diff --git a/cli/__mocks__/pm2.ts b/cli/__mocks__/pm2.ts new file mode 100644 index 0000000000..1945d9dbd0 --- /dev/null +++ b/cli/__mocks__/pm2.ts @@ -0,0 +1,39 @@ +class API { + connect( callback: ( error: Error | null ) => void ) { + setTimeout( () => { + callback( null ); + }, 0 ); + } + disconnect( callback: ( error: Error | null ) => void ) { + setTimeout( () => { + callback( null ); + }, 0 ); + } + list( callback: ( error: Error | null, processes: any[] ) => void ) { + setTimeout( () => { + callback( null, [] ); + }, 0 ); + } + launchBus( callback: ( error: Error | null, bus: any ) => void ) { + setTimeout( () => { + callback( null, {} ); + }, 0 ); + } + sendDataToProcessId( id: string, data: any, callback: ( error: Error | null ) => void ) { + setTimeout( () => { + callback( null ); + }, 0 ); + } + start( config: any, callback: ( error: Error | null, apps: any[] ) => void ) { + setTimeout( () => { + callback( null, [] ); + }, 0 ); + } + delete( callback: ( error: Error | null ) => void ) { + setTimeout( () => { + callback( null ); + }, 0 ); + } +} + +exports.custom = API; diff --git a/cli/lib/pm2-manager.ts b/cli/lib/pm2-manager.ts index 7205577326..b8593446d7 100644 --- a/cli/lib/pm2-manager.ts +++ b/cli/lib/pm2-manager.ts @@ -1,8 +1,7 @@ -import fs from 'fs'; import os from 'os'; import path from 'path'; import { cacheFunctionTTL } from 'common/lib/cache-function-ttl'; -import { StartOptions } from 'pm2'; +import { custom as PM2, StartOptions } from 'pm2'; import { getAppdataPath } from 'cli/lib/appdata'; import { ProcessDescription } from 'cli/lib/types/pm2'; import { ManagerMessage } from './types/wordpress-server-ipc'; @@ -15,40 +14,7 @@ const DAEMON_TIMEOUT = 10000; // This ensures all Studio CLI commands use the same PM2 daemon const STUDIO_PM2_HOME = path.join( os.homedir(), '.studio', 'pm2' ); -process.env.PM2_HOME = STUDIO_PM2_HOME; - -function resolvePm2(): typeof import('pm2') { - try { - return require( 'pm2' ); - } catch ( error ) { - const possiblePaths: string[] = [ - path.join( __dirname, 'node_modules', 'pm2' ), - path.join( path.dirname( __dirname ), 'node_modules', 'pm2' ), - path.join( __dirname, '..', 'node_modules', 'pm2' ), - path.join( __dirname, '..', '..', 'node_modules', 'pm2' ), - path.join( __dirname, '..', '..', '..', 'node_modules', 'pm2' ), - path.resolve( process.cwd(), 'node_modules', 'pm2' ), - ]; - - for ( const pm2Path of possiblePaths ) { - if ( fs.existsSync( pm2Path ) ) { - try { - return require( pm2Path ); - } catch { - continue; - } - } - } - - throw new Error( - `pm2 module not found. Please ensure pm2 is installed in the CLI dependencies. Tried paths: ${ possiblePaths.join( - ', ' - ) }` - ); - } -} - -const pm2 = resolvePm2(); +const pm2 = new PM2( { pm2_home: STUDIO_PM2_HOME } ); let isConnected = false; @@ -101,7 +67,7 @@ const listProcesses = cacheFunctionTTL( () => { const processDescriptions = ( processes || [] ).map( ( p ) => ( { name: p.name || '', - pmId: p.pm_id || -1, + pmId: p.pm_id ?? -1, status: p.pm2_env?.status || 'unknown', pid: p.pid, } ) ); @@ -188,7 +154,7 @@ export async function isProcessRunning( export async function startProcess( processName: string, scriptPath: string, - env?: Record< string, string > + env: Record< string, string > = {} ): Promise< ProcessDescription > { return new Promise( ( resolve, reject ) => { const processConfig: StartOptions = { @@ -197,7 +163,7 @@ export async function startProcess( script: scriptPath, exec_mode: 'fork', autorestart: false, - env: env || {}, + env: env, }; pm2.start( processConfig, async ( error, apps ) => { @@ -206,7 +172,7 @@ export async function startProcess( return; } - if ( apps && apps.length > 0 ) { + if ( apps.length > 0 ) { const app = apps[ 0 ] as ( typeof apps )[ 0 ] & { pm2_env?: { pm_id?: number; status?: string }; pid?: number; diff --git a/cli/lib/tests/pm2-manager.test.ts b/cli/lib/tests/pm2-manager.test.ts index 8da4891af2..0eff6dd496 100644 --- a/cli/lib/tests/pm2-manager.test.ts +++ b/cli/lib/tests/pm2-manager.test.ts @@ -1,4 +1,8 @@ -// Mock dependencies before importing pm2-manager +import os from 'os'; +import { clearCache } from 'common/lib/cache-function-ttl'; +import { getAppdataPath } from 'cli/lib/appdata'; +import { ManagerMessage } from '../types/wordpress-server-ipc'; + jest.mock( 'fs' ); jest.mock( 'os', () => ( { homedir: jest.fn().mockReturnValue( '/home/user' ), @@ -6,90 +10,40 @@ jest.mock( 'os', () => ( { jest.mock( 'cli/lib/appdata', () => ( { getAppdataPath: jest.fn().mockReturnValue( '/home/user/.studio/appdata' ), } ) ); -// Create a mock pm2 module -const mockPm2 = { + +const mockPm2Instance = { connect: jest.fn(), disconnect: jest.fn(), list: jest.fn(), start: jest.fn(), delete: jest.fn(), + launchBus: jest.fn(), + sendDataToProcessId: jest.fn(), }; -// Mock the pm2 module at require time -jest.mock( - 'pm2', - () => { - return mockPm2; - }, - { virtual: true } -); - -import fs from 'fs'; -import os from 'os'; -import { clearCache } from 'common/lib/cache-function-ttl'; -import { getAppdataPath } from 'cli/lib/appdata'; -// Import the module after mocks are set up -import { - connect, - disconnect, - startProcess, - stopProcess, - isProcessRunning, - startProxyProcess, - isProxyProcessRunning, -} from '../pm2-manager'; +jest.mock( 'pm2', () => { + return { + custom: jest.fn().mockImplementation( () => mockPm2Instance ), + }; +} ); describe( 'PM2 Manager', () => { beforeEach( () => { jest.clearAllMocks(); - - // Clear cache to prevent test pollution clearCache(); - - // Reset connection state by calling disconnect - disconnect(); - - // Setup default mocks - ( fs.existsSync as jest.Mock ).mockReturnValue( true ); ( os.homedir as jest.Mock ).mockReturnValue( '/home/user' ); ( getAppdataPath as jest.Mock ).mockReturnValue( '/home/user/.studio/appdata' ); } ); - afterEach( () => { - jest.restoreAllMocks(); - } ); - - describe( 'connect', () => { - it( 'should connect to PM2 daemon successfully', async () => { - mockPm2.connect.mockImplementation( ( callback ) => { - callback( null ); - } ); - - await connect(); - - expect( mockPm2.connect ).toHaveBeenCalledTimes( 1 ); - expect( mockPm2.connect ).toHaveBeenCalledWith( expect.any( Function ) ); - } ); - - it( 'should handle connection errors', async () => { - const error = new Error( 'Connection failed' ); - mockPm2.connect.mockImplementation( ( callback ) => { - callback( error ); - } ); - - await expect( connect() ).rejects.toThrow( 'Connection failed' ); - } ); - - it( 'should timeout after 10 seconds', async () => { + describe( 'connect() - timeout handling and idempotency', () => { + it( 'should timeout after 10 seconds if PM2 does not respond', async () => { jest.useFakeTimers(); - - mockPm2.connect.mockImplementation( () => { - // Never call the callback - simulate hanging + mockPm2Instance.connect.mockImplementation( () => { + // Never call callback } ); + const { connect } = await import( '../pm2-manager' ); const connectPromise = connect(); - - // Fast-forward time by 10 seconds jest.advanceTimersByTime( 10000 ); await expect( connectPromise ).rejects.toThrow( 'PM2 connection timeout after 10 seconds' ); @@ -97,384 +51,261 @@ describe( 'PM2 Manager', () => { jest.useRealTimers(); } ); - it( 'should be idempotent (skip if already connected)', async () => { - mockPm2.connect.mockImplementation( ( callback ) => { + it( 'should not call pm2.connect again if already connected', async () => { + mockPm2Instance.connect.mockImplementation( ( callback ) => { callback( null ); } ); + const { connect } = await import( '../pm2-manager' ); await connect(); - await connect(); // Second call - - // Should only connect once - expect( mockPm2.connect ).toHaveBeenCalledTimes( 1 ); - } ); - - it( 'should clear timeout on successful connection', async () => { - jest.useFakeTimers(); - - mockPm2.connect.mockImplementation( ( callback ) => { - // Simulate immediate connection - callback( null ); - } ); - + await connect(); await connect(); - // Advance timers - timeout should be cleared, no error should occur - jest.advanceTimersByTime( 10000 ); - - jest.useRealTimers(); + expect( mockPm2Instance.connect ).toHaveBeenCalledTimes( 1 ); } ); } ); - describe( 'disconnect', () => { - it( 'should disconnect from PM2 daemon when connected', async () => { - mockPm2.connect.mockImplementation( ( callback ) => { - callback( null ); + describe( 'startProcess() - response validation and transformation', () => { + it( 'should validate PM2 response structure and reject incomplete responses', async () => { + mockPm2Instance.start.mockImplementation( ( config, callback ) => { + callback( null, [] ); } ); - await connect(); - - // Clear the disconnect call from beforeEach - jest.clearAllMocks(); + const { startProcess } = await import( '../pm2-manager' ); - disconnect(); - - expect( mockPm2.disconnect ).toHaveBeenCalledTimes( 1 ); - } ); - - it( 'should not call pm2.disconnect if not connected', () => { - disconnect(); - - expect( mockPm2.disconnect ).not.toHaveBeenCalled(); + await expect( startProcess( 'app', '/path/script.js' ) ).rejects.toThrow( + 'PM2 returned incomplete response' + ); } ); - it( 'should allow reconnection after disconnect', async () => { - mockPm2.connect.mockImplementation( ( callback ) => { - callback( null ); + it( 'should reject if PM2 response missing pm2_env', async () => { + mockPm2Instance.start.mockImplementation( ( config, callback ) => { + callback( null, [ { pid: 1234 } ] ); } ); - await connect(); - disconnect(); - await connect(); // Should connect again + const { startProcess } = await import( '../pm2-manager' ); - expect( mockPm2.connect ).toHaveBeenCalledTimes( 2 ); + await expect( startProcess( 'app', '/path/script.js' ) ).rejects.toThrow( + 'PM2 returned incomplete response' + ); } ); - } ); - describe( 'isProcessRunning', () => { - beforeEach( async () => { - mockPm2.connect.mockImplementation( ( callback ) => { - callback( null ); + it( 'should reject if pm2_env.pm_id is undefined', async () => { + mockPm2Instance.start.mockImplementation( ( config, callback ) => { + callback( null, [ + { pm2_env: { status: 'online' }, pid: 1234 }, // Missing pm_id + ] ); } ); - await connect(); - } ); - it( 'should return process description when process is running', async () => { - const mockProcess = { - name: 'test-process', - pm_id: 1, // Using 1 to avoid || -1 edge case with 0 - pid: 12345, - pm2_env: { status: 'online' }, - }; + const { startProcess } = await import( '../pm2-manager' ); - mockPm2.list.mockImplementation( ( callback ) => { - callback( null, [ mockProcess ] ); + await expect( startProcess( 'app', '/path/script.js' ) ).rejects.toThrow( + 'PM2 returned incomplete response' + ); + } ); + + it( 'should transform valid PM2 response to ProcessDescription', async () => { + mockPm2Instance.start.mockImplementation( ( config, callback ) => { + callback( null, [ + { + pm2_env: { pm_id: 5, status: 'online' }, + pid: 9999, + }, + ] ); } ); - const result = await isProcessRunning( 'test-process' ); + const { startProcess } = await import( '../pm2-manager' ); + const result = await startProcess( 'my-app', '/path/script.js' ); expect( result ).toEqual( { - name: 'test-process', - pmId: 1, + name: 'my-app', + pmId: 5, status: 'online', - pid: 12345, + pid: 9999, } ); } ); + } ); - it( 'should return undefined when process is not found', async () => { - mockPm2.list.mockImplementation( ( callback ) => { - callback( null, [] ); + describe( 'stopProcess() - graceful error handling', () => { + it( 'should swallow "process not found" error without rejecting', async () => { + mockPm2Instance.delete.mockImplementation( ( name, callback ) => { + callback( new Error( 'process name not found' ) ); } ); - const result = await isProcessRunning( 'non-existent-process' ); + const { stopProcess } = await import( '../pm2-manager' ); - expect( result ).toBeUndefined(); + await expect( stopProcess( 'non-existent' ) ).resolves.toBeUndefined(); } ); - it( 'should return undefined when process status is not online', async () => { - const mockProcess = { - name: 'test-process', - pm_id: 0, - pid: 12345, - pm2_env: { status: 'stopped' }, - }; - - mockPm2.list.mockImplementation( ( callback ) => { - callback( null, [ mockProcess ] ); + it( 'should reject on other delete errors', async () => { + mockPm2Instance.delete.mockImplementation( ( name, callback ) => { + callback( new Error( 'Permission denied' ) ); } ); - const result = await isProcessRunning( 'test-process' ); + const { stopProcess } = await import( '../pm2-manager' ); - expect( result ).toBeUndefined(); + await expect( stopProcess( 'app' ) ).rejects.toThrow( 'Permission denied' ); } ); + } ); + describe( 'isProcessRunning() - process discovery and filtering', () => { it( 'should return undefined when not connected', async () => { + const { isProcessRunning, disconnect } = await import( '../pm2-manager' ); disconnect(); - const result = await isProcessRunning( 'test-process' ); + const result = await isProcessRunning( 'app' ); expect( result ).toBeUndefined(); - expect( mockPm2.list ).not.toHaveBeenCalled(); + expect( mockPm2Instance.list ).not.toHaveBeenCalled(); } ); - it( 'should handle pm2.list errors gracefully', async () => { - const consoleErrorSpy = jest.spyOn( console, 'error' ).mockImplementation(); - mockPm2.list.mockImplementation( ( callback ) => { - callback( new Error( 'List error' ) ); + it( 'should filter for online status only', async () => { + mockPm2Instance.list.mockImplementation( ( callback ) => { + callback( null, [ + { + name: 'app', + pm_id: 1, + pid: 1000, + pm2_env: { status: 'stopped' }, + }, + ] ); } ); - const result = await isProcessRunning( 'test-process' ); + const { isProcessRunning, connect } = await import( '../pm2-manager' ); + await connect(); + + const result = await isProcessRunning( 'app' ); expect( result ).toBeUndefined(); - expect( consoleErrorSpy ).toHaveBeenCalledWith( - 'Error checking if process test-process is running:', - expect.any( Error ) - ); - - consoleErrorSpy.mockRestore(); } ); - } ); - describe( 'startProcess', () => { - it( 'should start a process successfully', async () => { - const mockApp = { - pm2_env: { - pm_id: 0, - status: 'online', - }, - pid: 12345, - }; - - mockPm2.start.mockImplementation( ( config, callback ) => { - callback( null, [ mockApp ] ); + it( 'should return process with online status and transform data', async () => { + mockPm2Instance.list.mockImplementation( ( callback ) => { + callback( null, [ + { + name: 'app', + pm_id: 2, + pid: 2000, + pm2_env: { status: 'online' }, + }, + ] ); } ); - const result = await startProcess( 'test-process', '/path/to/script.js' ); - - expect( mockPm2.start ).toHaveBeenCalledWith( - { - name: 'test-process', - interpreter: process.execPath, - script: '/path/to/script.js', - exec_mode: 'fork', - autorestart: false, - env: {}, - }, - expect.any( Function ) - ); + const { isProcessRunning, connect } = await import( '../pm2-manager' ); + await connect(); + + const result = await isProcessRunning( 'app' ); expect( result ).toEqual( { - name: 'test-process', - pmId: 0, + name: 'app', + pmId: 2, status: 'online', - pid: 12345, + pid: 2000, } ); } ); - it( 'should start a process with environment variables', async () => { - const mockApp = { - pm2_env: { - pm_id: 1, - status: 'online', - }, - pid: 54321, - }; - - mockPm2.start.mockImplementation( ( config, callback ) => { - callback( null, [ mockApp ] ); + it( 'should handle pm2.list errors gracefully', async () => { + const consoleErrorSpy = jest.spyOn( console, 'error' ).mockImplementation(); + mockPm2Instance.list.mockImplementation( ( callback ) => { + callback( new Error( 'List error' ) ); } ); - const env = { TEST_VAR: 'test-value' }; - await startProcess( 'test-process', '/path/to/script.js', env ); - - expect( mockPm2.start ).toHaveBeenCalledWith( - expect.objectContaining( { - env, - } ), - expect.any( Function ) - ); - } ); + const { isProcessRunning, connect } = await import( '../pm2-manager' ); + await connect(); - it( 'should handle pm2.start errors', async () => { - const error = new Error( 'Start failed' ); - mockPm2.start.mockImplementation( ( config, callback ) => { - callback( error ); - } ); + const result = await isProcessRunning( 'app' ); - await expect( startProcess( 'test-process', '/path/to/script.js' ) ).rejects.toThrow( - 'Start failed' - ); + expect( result ).toBeUndefined(); + expect( consoleErrorSpy ).toHaveBeenCalled(); + consoleErrorSpy.mockRestore(); } ); + } ); - it( 'should handle incomplete PM2 response', async () => { - mockPm2.start.mockImplementation( ( config, callback ) => { + describe( 'listProcesses caching', () => { + it( 'should cache results to avoid multiple pm2.list calls', async () => { + mockPm2Instance.list.mockImplementation( ( callback ) => { callback( null, [] ); } ); - await expect( startProcess( 'test-process', '/path/to/script.js' ) ).rejects.toThrow( - 'Failed to start process test-process: PM2 returned incomplete response' - ); - } ); - - it( 'should handle missing pm2_env in response', async () => { - const mockApp = { - pid: 12345, - }; + const { isProcessRunning, connect } = await import( '../pm2-manager' ); + await connect(); - mockPm2.start.mockImplementation( ( config, callback ) => { - callback( null, [ mockApp ] ); - } ); + await isProcessRunning( 'app1' ); + await isProcessRunning( 'app2' ); + await isProcessRunning( 'app3' ); - await expect( startProcess( 'test-process', '/path/to/script.js' ) ).rejects.toThrow( - 'Failed to start process test-process: PM2 returned incomplete response' - ); + expect( mockPm2Instance.list ).toHaveBeenCalledTimes( 1 ); } ); - } ); - describe( 'stopProcess', () => { - it( 'should stop a process successfully', async () => { - mockPm2.delete.mockImplementation( ( processName, callback ) => { - callback( null ); + it( 'should invalidate cache after clearCache is called', async () => { + mockPm2Instance.list.mockImplementation( ( callback ) => { + callback( null, [] ); } ); - await stopProcess( 'test-process' ); + const { isProcessRunning, connect } = await import( '../pm2-manager' ); + await connect(); + + await isProcessRunning( 'app1' ); + clearCache(); + await isProcessRunning( 'app2' ); - expect( mockPm2.delete ).toHaveBeenCalledWith( 'test-process', expect.any( Function ) ); + expect( mockPm2Instance.list ).toHaveBeenCalledTimes( 2 ); } ); + } ); - it( 'should handle "process name not found" error gracefully', async () => { - const error = new Error( 'process name not found' ); - mockPm2.delete.mockImplementation( ( processName, callback ) => { - callback( error ); + describe( 'getPm2Bus() - bus caching', () => { + it( 'should cache bus instance to avoid multiple launchBus calls', async () => { + const mockBus = { on: jest.fn() }; + mockPm2Instance.launchBus.mockImplementation( ( callback ) => { + callback( null, mockBus ); } ); - await expect( stopProcess( 'non-existent-process' ) ).resolves.toBeUndefined(); - } ); + const { getPm2Bus, connect } = await import( '../pm2-manager' ); + await connect(); - it( 'should reject on other errors', async () => { - const error = new Error( 'Delete failed' ); - mockPm2.delete.mockImplementation( ( processName, callback ) => { - callback( error ); - } ); + const bus1 = await getPm2Bus(); + const bus2 = await getPm2Bus(); - await expect( stopProcess( 'test-process' ) ).rejects.toThrow( 'Delete failed' ); + expect( bus1 ).toBe( bus2 ); + expect( mockPm2Instance.launchBus ).toHaveBeenCalledTimes( 1 ); } ); } ); - describe( 'startProxyProcess', () => { - it( 'should start the proxy process with correct configuration', async () => { - const mockApp = { - pm2_env: { - pm_id: 1, - status: 'online', - }, - pid: 99999, - }; - - mockPm2.start.mockImplementation( ( config, callback ) => { - callback( null, [ mockApp ] ); - } ); - - const result = await startProxyProcess(); - - expect( mockPm2.start ).toHaveBeenCalledWith( - expect.objectContaining( { - name: 'studio-proxy', - script: expect.stringContaining( 'proxy-daemon.js' ), - env: expect.objectContaining( { - STUDIO_USER_HOME: '/home/user', - STUDIO_APPDATA_PATH: '/home/user/.studio/appdata', - } ), - } ), - expect.any( Function ) - ); - - expect( result ).toEqual( { - name: 'studio-proxy', - pmId: 1, - status: 'online', - pid: 99999, + describe( 'sendMessageToProcess()', () => { + it( 'should send message with correct processId and data', async () => { + mockPm2Instance.sendDataToProcessId.mockImplementation( ( id, data, callback ) => { + callback( null ); } ); - } ); - it( 'should include ELECTRON_RUN_AS_NODE if set in process.env', async () => { - process.env.ELECTRON_RUN_AS_NODE = '1'; + const { sendMessageToProcess } = await import( '../pm2-manager' ); - const mockApp = { - pm2_env: { - pm_id: 1, - status: 'online', - }, - pid: 99999, + const message: ManagerMessage = { + topic: 'stop-server', + messageId: 1, }; - mockPm2.start.mockImplementation( ( config, callback ) => { - callback( null, [ mockApp ] ); - } ); - - await startProxyProcess(); + await sendMessageToProcess( 42, message ); - expect( mockPm2.start ).toHaveBeenCalledWith( - expect.objectContaining( { - env: expect.objectContaining( { - ELECTRON_RUN_AS_NODE: '1', - } ), - } ), + expect( mockPm2Instance.sendDataToProcessId ).toHaveBeenCalledWith( + 42, + message, expect.any( Function ) ); - - delete process.env.ELECTRON_RUN_AS_NODE; } ); - } ); - - describe( 'isProxyProcessRunning', () => { - beforeEach( async () => { - mockPm2.connect.mockImplementation( ( callback ) => { - callback( null ); - } ); - await connect(); - } ); - - it( 'should check for studio-proxy process', async () => { - const mockProcess = { - name: 'studio-proxy', - pm_id: 1, - pid: 99999, - pm2_env: { status: 'online' }, - }; - - mockPm2.list.mockImplementation( ( callback ) => { - callback( null, [ mockProcess ] ); - } ); - - const result = await isProxyProcessRunning(); - expect( result ).toEqual( { - name: 'studio-proxy', - pmId: 1, - status: 'online', - pid: 99999, + it( 'should reject on send error', async () => { + mockPm2Instance.sendDataToProcessId.mockImplementation( ( id, data, callback ) => { + callback( new Error( 'Send failed' ) ); } ); - } ); - it( 'should return undefined when proxy is not running', async () => { - mockPm2.list.mockImplementation( ( callback ) => { - callback( null, [] ); - } ); + const { sendMessageToProcess } = await import( '../pm2-manager' ); - const result = await isProxyProcessRunning(); + const message: ManagerMessage = { + topic: 'stop-server', + messageId: 1, + }; - expect( result ).toBeUndefined(); + await expect( sendMessageToProcess( 42, message ) ).rejects.toThrow( 'Send failed' ); } ); } ); } ); diff --git a/cli/patches/pm2+6.0.13.patch b/cli/patches/pm2+6.0.13.patch index ed4a867a6b..e2b92a3b1b 100644 --- a/cli/patches/pm2+6.0.13.patch +++ b/cli/patches/pm2+6.0.13.patch @@ -1,62 +1,727 @@ diff --git a/node_modules/pm2/types/index.d.ts b/node_modules/pm2/types/index.d.ts -index 77280f5..a9ef7e7 100644 +index 77280f5..887f710 100644 --- a/node_modules/pm2/types/index.d.ts +++ b/node_modules/pm2/types/index.d.ts -@@ -26,21 +26,21 @@ export function connect(noDaemonMode:boolean, errback: ErrCallback): void; - * @param errback - An errback called when the script has been started. - * The proc parameter will be a pm2 process object. - */ +@@ -3,316 +3,384 @@ + + // Exported Methods + +-/** +- * Either connects to a running pm2 daemon (“God”) or launches and daemonizes one. +- * Once launched, the pm2 process will keep running after the script exits. +- * @param errback - Called when finished connecting to or launching the pm2 daemon process. +- */ +-export function connect(errback: ErrCallback): void; +-/** +- * Either connects to a running pm2 daemon (“God”) or launches and daemonizes one. +- * Once launched, the pm2 process will keep running after the script exits. +- * @param noDaemonMode - (Default: false) If true is passed for the first argument +- * pm2 will not be run as a daemon and will die when the related script exits. +- * By default, pm2 stays alive after your script exits. +- * If pm2 is already running, your script will link to the existing daemon but will die once your process exits. +- * @param errback - Called when finished connecting to or launching the pm2 daemon process. +- */ +-export function connect(noDaemonMode:boolean, errback: ErrCallback): void; ++export class API { ++ constructor(opts?: PM2ConstructorOptions); + +-/** +- * Starts a script that will be managed by pm2. +- * @param options - Options +- * @param errback - An errback called when the script has been started. +- * The proc parameter will be a pm2 process object. +- */ -export function start(options: StartOptions, errback: ErrProcCallback): void; -+export function start(options: StartOptions, errback: ErrProcsCallback): void; - /** - * Starts a script that will be managed by pm2. - * @param jsonConfigFile - The path to a JSON file that can contain the same options as the options parameter. - * @param errback - An errback called when the script has been started. - * The proc parameter will be a pm2 process object. - */ +-/** +- * Starts a script that will be managed by pm2. +- * @param jsonConfigFile - The path to a JSON file that can contain the same options as the options parameter. +- * @param errback - An errback called when the script has been started. +- * The proc parameter will be a pm2 process object. +- */ -export function start(jsonConfigFile: string, errback: ErrProcCallback): void; -+export function start(jsonConfigFile: string, errback: ErrProcsCallback): void; - /** - * Starts a script that will be managed by pm2. - * @param script - The path of the script to run. - * @param errback - An errback called when the script has been started. - * The proc parameter will be a pm2 process object. - */ +-/** +- * Starts a script that will be managed by pm2. +- * @param script - The path of the script to run. +- * @param errback - An errback called when the script has been started. +- * The proc parameter will be a pm2 process object. +- */ -export function start(script: string , errback: ErrProcCallback): void; -+export function start(script: string , errback: ErrProcsCallback): void; - /** - * Starts a script that will be managed by pm2. - * @param script - The path of the script to run. -@@ -48,7 +48,7 @@ export function start(script: string , errback: ErrProcCallback): void; - * @param errback - An errback called when the script has been started. - * The proc parameter will be a pm2 process object. - */ +-/** +- * Starts a script that will be managed by pm2. +- * @param script - The path of the script to run. +- * @param options - Options +- * @param errback - An errback called when the script has been started. +- * The proc parameter will be a pm2 process object. +- */ -export function start(script: string, options: StartOptions, errback: ErrProcCallback): void; -+export function start(script: string, options: StartOptions, errback: ErrProcsCallback): void; - /** - * Starts a script that will be managed by pm2. - * @param script - The path of the script to run. -@@ -56,7 +56,7 @@ export function start(script: string, options: StartOptions, errback: ErrProcCal - * @param errback - An errback called when the script has been started. - * The proc parameter will be a pm2 process object. - */ +-/** +- * Starts a script that will be managed by pm2. +- * @param script - The path of the script to run. +- * @param jsonConfigFile - The path to a JSON file that can contain the same options as the options parameter. +- * @param errback - An errback called when the script has been started. +- * The proc parameter will be a pm2 process object. +- */ -export function start(script: string, jsonConfigFile: string, errback: ErrProcCallback): void; -+export function start(script: string, jsonConfigFile: string, errback: ErrProcsCallback): void; ++ /** ++ * Either connects to a running pm2 daemon (“God”) or launches and daemonizes one. ++ * Once launched, the pm2 process will keep running after the script exits. ++ * @param errback - Called when finished connecting to or launching the pm2 daemon process. ++ */ ++ connect(errback: ErrCallback): void; ++ /** ++ * Either connects to a running pm2 daemon (“God”) or launches and daemonizes one. ++ * Once launched, the pm2 process will keep running after the script exits. ++ * @param noDaemonMode - (Default: false) If true is passed for the first argument ++ * pm2 will not be run as a daemon and will die when the related script exits. ++ * By default, pm2 stays alive after your script exits. ++ * If pm2 is already running, your script will link to the existing daemon but will die once your process exits. ++ * @param errback - Called when finished connecting to or launching the pm2 daemon process. ++ */ ++ connect(noDaemonMode: boolean, errback: ErrCallback): void; + +-/** +- * Disconnects from the pm2 daemon. +- */ +-export function disconnect(): void; ++ /** ++ * Starts a script that will be managed by pm2. ++ * @param options - Options ++ * @param errback - An errback called when the script has been started. ++ * The proc parameter will be a pm2 process object. ++ */ ++ start(options: StartOptions, errback: ErrProcsCallback): void; ++ /** ++ * Starts a script that will be managed by pm2. ++ * @param jsonConfigFile - The path to a JSON file that can contain the same options as the options parameter. ++ * @param errback - An errback called when the script has been started. ++ * The proc parameter will be a pm2 process object. ++ */ ++ start(jsonConfigFile: string, errback: ErrProcsCallback): void; ++ /** ++ * Starts a script that will be managed by pm2. ++ * @param script - The path of the script to run. ++ * @param errback - An errback called when the script has been started. ++ * The proc parameter will be a pm2 process object. ++ */ ++ start(script: string, errback: ErrProcsCallback): void; ++ /** ++ * Starts a script that will be managed by pm2. ++ * @param script - The path of the script to run. ++ * @param options - Options ++ * @param errback - An errback called when the script has been started. ++ * The proc parameter will be a pm2 process object. ++ */ ++ start(script: string, options: StartOptions, errback: ErrProcsCallback): void; ++ /** ++ * Starts a script that will be managed by pm2. ++ * @param script - The path of the script to run. ++ * @param jsonConfigFile - The path to a JSON file that can contain the same options as the options parameter. ++ * @param errback - An errback called when the script has been started. ++ * The proc parameter will be a pm2 process object. ++ */ ++ start(script: string, jsonConfigFile: string, errback: ErrProcsCallback): void; + +-/** +- * Stops a process but leaves the process meta-data in pm2’s list +- * @param process - Can either be the name as given in the pm2.start options, +- * a process id, or the string “all” to indicate that all scripts should be restarted. +- * @param errback - called when the process is stopped +- */ +-export function stop(process: string|number, errback: ErrProcCallback): void; ++ /** ++ * Disconnects from the pm2 daemon. ++ */ ++ disconnect(): void; + +-/** +- * Stops and restarts the process. +- * @param process - Can either be the name as given in the pm2.start options, +- * a process id, or the string “all” to indicate that all scripts should be restarted. +- * @param errback - called when the process is restarted +- */ +-export function restart(process: string|number, errback: ErrProcCallback): void; ++ /** ++ * Stops a process but leaves the process meta-data in pm2’s list ++ * @param process - Can either be the name as given in the pm2.start options, ++ * a process id, or the string “all” to indicate that all scripts should be restarted. ++ * @param errback - called when the process is stopped ++ */ ++ stop(process: string | number, errback: ErrProcCallback): void; + +-/** +- * Stops the process and removes it from pm2’s list. +- * The process will no longer be accessible by its name +- * @param process - Can either be the name as given in the pm2.start options, +- * a process id, or the string “all” to indicate that all scripts should be restarted. +- * @param errback - called when the process is deleted +- */ +-declare function del(process: string|number, errback: ErrProcCallback): void; +-// have to use this construct because `delete` is a reserved word +-export {del as delete}; ++ /** ++ * Stops and restarts the process. ++ * @param process - Can either be the name as given in the pm2.start options, ++ * a process id, or the string “all” to indicate that all scripts should be restarted. ++ * @param errback - called when the process is restarted ++ */ ++ restart(process: string | number, errback: ErrProcCallback): void; + +-/** +- * Zero-downtime rolling restart. At least one process will be kept running at +- * all times as each instance is restarted individually. +- * Only works for scripts started in cluster mode. +- * @param process - Can either be the name as given in the pm2.start options, +- * a process id, or the string “all” to indicate that all scripts should be restarted. +- * @param errback - called when the process is reloaded +- */ +-export function reload(process: string|number, errback: ErrProcCallback): void; ++ /** ++ * Stops the process and removes it from pm2’s list. ++ * The process will no longer be accessible by its name ++ * @param process - Can either be the name as given in the pm2.start options, ++ * a process id, or the string “all” to indicate that all scripts should be restarted. ++ * @param errback - called when the process is deleted ++ */ ++ delete(process: string | number, errback: ErrProcCallback): void; + +-/** +- * Zero-downtime rolling restart. At least one process will be kept running at +- * all times as each instance is restarted individually. +- * Only works for scripts started in cluster mode. +- * @param process - Can either be the name as given in the pm2.start options, +- * a process id, or the string “all” to indicate that all scripts should be restarted. +- * @param options - An object containing configuration +- * @param options.updateEnv - (Default: false) If true is passed in, pm2 will reload it’s +- * environment from process.env before reloading your process. +- * @param errback - called when the process is reloaded +- */ +-export function reload(process: string|number, options: ReloadOptions, errback: ErrProcCallback): void; ++ /** ++ * Zero-downtime rolling restart. At least one process will be kept running at ++ * all times as each instance is restarted individually. ++ * Only works for scripts started in cluster mode. ++ * @param process - Can either be the name as given in the pm2.start options, ++ * a process id, or the string “all” to indicate that all scripts should be restarted. ++ * @param errback - called when the process is reloaded ++ */ ++ reload(process: string | number, errback: ErrProcCallback): void; + +-/** +- * Kills the pm2 daemon (same as pm2 kill). Note that when the daemon is killed, all its +- * processes are also killed. Also note that you still have to explicitly disconnect +- * from the daemon even after you kill it. +- * @param errback +- */ +-export function killDaemon(errback: ErrProcDescCallback): void; ++ /** ++ * Zero-downtime rolling restart. At least one process will be kept running at ++ * all times as each instance is restarted individually. ++ * Only works for scripts started in cluster mode. ++ * @param process - Can either be the name as given in the pm2.start options, ++ * a process id, or the string “all” to indicate that all scripts should be restarted. ++ * @param options - An object containing configuration ++ * @param options.updateEnv - (Default: false) If true is passed in, pm2 will reload it’s ++ * environment from process.env before reloading your process. ++ * @param errback - called when the process is reloaded ++ */ ++ reload( ++ process: string | number, ++ options: ReloadOptions, ++ errback: ErrProcCallback, ++ ): void; + +-/** +- * Returns various information about a process: eg what stdout/stderr and pid files are used. +- * @param process - Can either be the name as given in the pm2.start options, +- * a process id, or the string “all” to indicate that all scripts should be restarted. +- * @param errback +- */ +-export function describe(process: string|number, errback: ErrProcDescsCallback): void; ++ /** ++ * Kills the pm2 daemon (same as pm2 kill). Note that when the daemon is killed, all its ++ * processes are also killed. Also note that you still have to explicitly disconnect ++ * from the daemon even after you kill it. ++ * @param errback ++ */ ++ killDaemon(errback: ErrProcDescCallback): void; + +-/** +- * Gets the list of running processes being managed by pm2. +- * @param errback +- */ +-export function list(errback: ErrProcDescsCallback): void; ++ /** ++ * Returns various information about a process: eg what stdout/stderr and pid files are used. ++ * @param process - Can either be the name as given in the pm2.start options, ++ * a process id, or the string “all” to indicate that all scripts should be restarted. ++ * @param errback ++ */ ++ describe(process: string | number, errback: ErrProcDescsCallback): void; + +-/** +- * Writes the process list to a json file at the path in the DUMP_FILE_PATH environment variable +- * (“~/.pm2/dump.pm2” by default). +- * @param errback +- */ +-export function dump(errback: ErrResultCallback): void; ++ /** ++ * Gets the list of running processes being managed by pm2. ++ * @param errback ++ */ ++ list(errback: ErrProcDescsCallback): void; + +-/** +- * Flushes the logs. +- * @param process - Can either be the name as given in the pm2.start options, +- * a process id, or the string “all” to indicate that all scripts should be restarted. +- * @param errback +- */ +-export function flush(process: number|string, errback: ErrResultCallback): void; ++ /** ++ * Writes the process list to a json file at the path in the DUMP_FILE_PATH environment variable ++ * (“~/.pm2/dump.pm2” by default). ++ * @param errback ++ */ ++ dump(errback: ErrResultCallback): void; + +-/** +- * @param errback +- */ +-export function dump(errback: ErrResultCallback): void; ++ /** ++ * Flushes the logs. ++ * @param process - Can either be the name as given in the pm2.start options, ++ * a process id, or the string “all” to indicate that all scripts should be restarted. ++ * @param errback ++ */ ++ flush(process: number | string, errback: ErrResultCallback): void; + +-/** +- * Rotates the log files. The new log file will have a higher number +- * in it (the default format being ${process.name}-${out|err}-${number}.log). +- * @param errback +- */ +-export function reloadLogs(errback: ErrResultCallback): void; ++ /** ++ * @param errback ++ */ ++ dump(errback: ErrResultCallback): void; + +-/** +- * Opens a message bus. +- * @param errback The bus will be an Axon Sub Emitter object used to listen to and send events. +- */ +-export function launchBus(errback: ErrBusCallback): void; ++ /** ++ * Rotates the log files. The new log file will have a higher number ++ * in it (the default format being ${process.name}-${out|err}-${number}.log). ++ * @param errback ++ */ ++ reloadLogs(errback: ErrResultCallback): void; + +-/** +- * @param signal +- * @param process - Can either be the name as given in the pm2.start options, +- * a process id, or the string “all” to indicate that all scripts should be restarted. +- * @param errback +- */ +-export function sendSignalToProcessName(signal:string|number, process: number|string, errback: ErrResultCallback): void; ++ /** ++ * Opens a message bus. ++ * @param errback The bus will be an Axon Sub Emitter object used to listen to and send events. ++ */ ++ launchBus(errback: ErrBusCallback): void; + +-/** +- * - Registers the script as a process that will start on machine boot. The current process list will be dumped and saved for resurrection on reboot. +- * @param platform +- * @param errback +- */ +-export function startup(platform: Platform, errback: ErrResultCallback): void; ++ /** ++ * @param signal ++ * @param process - Can either be the name as given in the pm2.start options, ++ * a process id, or the string “all” to indicate that all scripts should be restarted. ++ * @param errback ++ */ ++ sendSignalToProcessName( ++ signal: string | number, ++ process: number | string, ++ errback: ErrResultCallback, ++ ): void; + +-/** +- * - Send an set of data as object to a specific process +- * @param proc_id +- * @param packet +- * @param cb +- */ +-export function sendDataToProcessId(proc_id: number, packet: object, cb: ErrResultCallback): void; ++ /** ++ * - Registers the script as a process that will start on machine boot. The current process list will be dumped and saved for resurrection on reboot. ++ * @param platform ++ * @param errback ++ */ ++ startup(platform: Platform, errback: ErrResultCallback): void; + +-/** +- * - Send an set of data as object to a specific process +- * @param packet {id: number, type: 'process:msg', topic: true, data: object} +- */ +-export function sendDataToProcessId(packet: {id: number, type: 'process:msg', topic: true, data: object}): void; ++ /** ++ * - Send an set of data as object to a specific process ++ * @param proc_id ++ * @param packet ++ * @param cb ++ */ ++ sendDataToProcessId( ++ proc_id: number, ++ packet: object, ++ cb: ErrResultCallback, ++ ): void; + +-/** +- * Launch system monitoring (CPU, Memory usage) +- * @param errback - Called when monitoring is launched +- */ +-export function launchSysMonitoring(errback?: ErrCallback): void; ++ /** ++ * - Send an set of data as object to a specific process ++ * @param packet {id: number, type: 'process:msg', topic: true, data: object} ++ */ ++ sendDataToProcessId(packet: { ++ id: number; ++ type: "process:msg"; ++ topic: true; ++ data: object; ++ }): void; + +-/** +- * Profile CPU or Memory usage +- * @param type - 'cpu' for CPU profiling, 'mem' for memory profiling +- * @param time - Duration in seconds (default: 10) +- * @param errback - Called when profiling is complete +- */ +-export function profile(type: 'cpu' | 'mem', time?: number, errback?: ErrCallback): void; ++ /** ++ * Launch system monitoring (CPU, Memory usage) ++ * @param errback - Called when monitoring is launched ++ */ ++ launchSysMonitoring(errback?: ErrCallback): void; + +-/** +- * Get process environment variables +- * @param app_id - Process name or id +- * @param errback - Called with environment variables +- */ +-export function env(app_id: string | number, errback?: ErrCallback): void; ++ /** ++ * Profile CPU or Memory usage ++ * @param type - 'cpu' for CPU profiling, 'mem' for memory profiling ++ * @param time - Duration in seconds (default: 10) ++ * @param errback - Called when profiling is complete ++ */ ++ profile(type: "cpu" | "mem", time?: number, errback?: ErrCallback): void; + +-/** +- * Get process PID +- * @param app_name - Process name (optional, returns all PIDs if not provided) +- * @param errback - Called with PID information +- */ +-export function getPID(app_name?: string, errback?: ErrProcCallback): void; ++ /** ++ * Get process environment variables ++ * @param app_id - Process name or id ++ * @param errback - Called with environment variables ++ */ ++ env(app_id: string | number, errback?: ErrCallback): void; + +-/** +- * Trigger a custom action on a process +- * @param pm_id - Process id +- * @param action_name - Name of the action to trigger +- * @param params - Parameters to pass to the action +- * @param errback - Called when action completes +- */ +-export function trigger(pm_id: string | number, action_name: string, params?: any, errback?: ErrCallback): void; ++ /** ++ * Get process PID ++ * @param app_name - Process name (optional, returns all PIDs if not provided) ++ * @param errback - Called with PID information ++ */ ++ getPID(app_name?: string, errback?: ErrProcCallback): void; + +-/** +- * Inspect a process (debugging) +- * @param app_name - Process name +- * @param errback - Called with inspect information +- */ +-export function inspect(app_name: string, errback?: ErrCallback): void; ++ /** ++ * Trigger a custom action on a process ++ * @param pm_id - Process id ++ * @param action_name - Name of the action to trigger ++ * @param params - Parameters to pass to the action ++ * @param errback - Called when action completes ++ */ ++ trigger( ++ pm_id: string | number, ++ action_name: string, ++ params?: any, ++ errback?: ErrCallback, ++ ): void; + +-/** +- * Serve static files +- * @param path - Path to serve files from +- * @param port - Port number (default: 8080) +- * @param options - Serve options +- * @param errback - Called when server starts +- */ +-export function serve(path?: string, port?: number, options?: ServeOptions, errback?: ErrCallback): void; ++ /** ++ * Inspect a process (debugging) ++ * @param app_name - Process name ++ * @param errback - Called with inspect information ++ */ ++ inspect(app_name: string, errback?: ErrCallback): void; + +-/** +- * Install a PM2 module +- * @param module_name - Name of the module to install +- * @param options - Installation options +- * @param errback - Called when installation completes +- */ +-export function install(module_name: string, options?: InstallOptions, errback?: ErrCallback): void; ++ /** ++ * Serve static files ++ * @param path - Path to serve files from ++ * @param port - Port number (default: 8080) ++ * @param options - Serve options ++ * @param errback - Called when server starts ++ */ ++ serve( ++ path?: string, ++ port?: number, ++ options?: ServeOptions, ++ errback?: ErrCallback, ++ ): void; + +-/** +- * Uninstall a PM2 module +- * @param module_name - Name of the module to uninstall +- * @param errback - Called when uninstallation completes +- */ +-export function uninstall(module_name: string, errback?: ErrCallback): void; ++ /** ++ * Install a PM2 module ++ * @param module_name - Name of the module to install ++ * @param options - Installation options ++ * @param errback - Called when installation completes ++ */ ++ install( ++ module_name: string, ++ options?: InstallOptions, ++ errback?: ErrCallback, ++ ): void; + +-/** +- * Send line to process stdin +- * @param pm_id - Process id +- * @param line - Line to send +- * @param separator - Line separator (default: '\n') +- * @param errback - Called when line is sent +- */ +-export function sendLineToStdin(pm_id: string | number, line: string, separator?: string, errback?: ErrCallback): void; ++ /** ++ * Uninstall a PM2 module ++ * @param module_name - Name of the module to uninstall ++ * @param errback - Called when uninstallation completes ++ */ ++ uninstall(module_name: string, errback?: ErrCallback): void; + +-/** +- * Attach to process logs +- * @param pm_id - Process id +- * @param separator - Log separator +- * @param errback - Called when attached +- */ +-export function attach(pm_id: string | number, separator?: string, errback?: ErrCallback): void; ++ /** ++ * Send line to process stdin ++ * @param pm_id - Process id ++ * @param line - Line to send ++ * @param separator - Line separator (default: '\n') ++ * @param errback - Called when line is sent ++ */ ++ sendLineToStdin( ++ pm_id: string | number, ++ line: string, ++ separator?: string, ++ errback?: ErrCallback, ++ ): void; + +-/** +- * Get PM2 configuration value +- * @param key - Configuration key (optional, returns all config if not provided) +- * @param errback - Called with configuration value +- */ +-export function get(key?: string, errback?: ErrCallback): void; ++ /** ++ * Attach to process logs ++ * @param pm_id - Process id ++ * @param separator - Log separator ++ * @param errback - Called when attached ++ */ ++ attach( ++ pm_id: string | number, ++ separator?: string, ++ errback?: ErrCallback, ++ ): void; + +-/** +- * Set PM2 configuration value +- * @param key - Configuration key +- * @param value - Configuration value +- * @param errback - Called when value is set +- */ +-export function set(key: string, value: any, errback?: ErrCallback): void; ++ /** ++ * Get PM2 configuration value ++ * @param key - Configuration key (optional, returns all config if not provided) ++ * @param errback - Called with configuration value ++ */ ++ get(key?: string, errback?: ErrCallback): void; + +-/** +- * Set multiple PM2 configuration values +- * @param values - Configuration values as string +- * @param errback - Called when values are set +- */ +-export function multiset(values: string, errback?: ErrCallback): void; ++ /** ++ * Set PM2 configuration value ++ * @param key - Configuration key ++ * @param value - Configuration value ++ * @param errback - Called when value is set ++ */ ++ set(key: string, value: any, errback?: ErrCallback): void; + +-/** +- * Unset PM2 configuration value +- * @param key - Configuration key to unset +- * @param errback - Called when value is unset +- */ +-export function unset(key: string, errback?: ErrCallback): void; ++ /** ++ * Set multiple PM2 configuration values ++ * @param values - Configuration values as string ++ * @param errback - Called when values are set ++ */ ++ multiset(values: string, errback?: ErrCallback): void; ++ ++ /** ++ * Unset PM2 configuration value ++ * @param key - Configuration key to unset ++ * @param errback - Called when value is unset ++ */ ++ unset(key: string, errback?: ErrCallback): void; ++} ++ ++declare const pm2: API; ++export default pm2; ++ ++export { API as custom }; + + // Interfaces + ++type BasePM2ConstructorOptions = { ++ cwd?: string; ++ daemon_mode?: boolean; ++ public_key?: string; ++ secret_key?: string; ++ machine_name?: string; ++} ++ ++type IndependentPM2ConstructorOptions = BasePM2ConstructorOptions & { ++ independent: true; ++ pm2_home?: never; ++}; ++ ++type PM2HomePM2ConstructorOptions = BasePM2ConstructorOptions & { ++ pm2_home: string; ++}; ++ ++type PM2ConstructorOptions = ++ | IndependentPM2ConstructorOptions ++ | PM2HomePM2ConstructorOptions; ++ + export interface Proc { + name?: string; + vizion?: boolean; +@@ -417,7 +485,7 @@ interface Pm2Env { + /** + * The number of running instances. + */ +- instances?: number | 'max'; ++ instances?: number | "max"; + /** + * The path of the script being run in this process. + */ +@@ -541,7 +609,7 @@ export interface StartOptions { + /** + * If set to true, the application will be restarted on change of the script file. + */ +- watch?: boolean|string[]; ++ watch?: boolean | string[]; + /** + * (Default: false) By default, pm2 will only start a script if that script isn’t + * already running (a script is a path to an application, not the name of an application +@@ -557,7 +625,7 @@ export interface StartOptions { + /** + * The environment variables to pass on to the process. + */ +- env?: { [key: string]: string; }; ++ env?: { [key: string]: string }; + /** + * NameSpace for the process + * @default 'default' +@@ -711,12 +779,33 @@ export interface InstallOptions { + + // Types - /** - * Disconnects from the pm2 daemon. -@@ -715,8 +715,9 @@ type ProcessStatus = 'online' | 'stopping' | 'stopped' | 'launching' | 'errored' - type Platform = 'ubuntu' | 'centos' | 'redhat' | 'gentoo' | 'systemd' | 'darwin' | 'amazon'; +-type ProcessStatus = 'online' | 'stopping' | 'stopped' | 'launching' | 'errored' | 'one-launch-status' | 'waiting_restart'; +-type Platform = 'ubuntu' | 'centos' | 'redhat' | 'gentoo' | 'systemd' | 'darwin' | 'amazon'; ++type ProcessStatus = ++ | "online" ++ | "stopping" ++ | "stopped" ++ | "launching" ++ | "errored" ++ | "one-launch-status" ++ | "waiting_restart"; ++type Platform = ++ | "ubuntu" ++ | "centos" ++ | "redhat" ++ | "gentoo" ++ | "systemd" ++ | "darwin" ++ | "amazon"; type ErrCallback = (err: Error) => void; --type ErrProcCallback = (err: Error, proc: Proc) => void; + type ErrProcCallback = (err: Error, proc: Proc) => void; -type ErrProcDescCallback = (err: Error, processDescription: ProcessDescription) => void; -type ErrProcDescsCallback = (err: Error, processDescriptionList: ProcessDescription[]) => void; --type ErrResultCallback = (err: Error, result: any) => void; --type ErrBusCallback = (err: Error, bus: any) => void; -+type ErrProcCallback = (err: Error | null, proc: Proc) => void; +type ErrProcsCallback = (err: Error | null, procs: Proc[]) => void; -+type ErrProcDescCallback = (err: Error | null, processDescription: ProcessDescription) => void; -+type ErrProcDescsCallback = (err: Error | null, processDescriptionList: ProcessDescription[]) => void; -+type ErrResultCallback = (err: Error | null, result: any) => void; -+type ErrBusCallback = (err: Error | null, bus: any) => void; ++type ErrProcDescCallback = ( ++ err: Error, ++ processDescription: ProcessDescription, ++) => void; ++type ErrProcDescsCallback = ( ++ err: Error, ++ processDescriptionList: ProcessDescription[], ++) => void; + type ErrResultCallback = (err: Error, result: any) => void; + type ErrBusCallback = (err: Error, bus: any) => void;