{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n  ChildProcessByStdio,\n  SendHandle,\n  Serializable,\n  spawn as nodeSpawn,\n  SpawnOptions,\n} from 'child_process'\nimport crossSpawn from 'cross-spawn'\nimport { onExit } from 'signal-exit'\nimport { proxySignals } from './proxy-signals.js'\nimport { watchdog } from './watchdog.js'\n\n/* c8 ignore start */\nconst spawn = process?.platform === 'win32' ? crossSpawn : nodeSpawn\n/* c8 ignore stop */\n\n/**\n * The signature for the cleanup method.\n *\n * Arguments indicate the exit status of the child process.\n *\n * If a Promise is returned, then the process is not terminated\n * until it resolves, and the resolution value is treated as the\n * exit status (if a number) or signal exit (if a signal string).\n *\n * If `undefined` is returned, then no change is made, and the parent\n * exits in the same way that the child exited.\n *\n * If boolean `false` is returned, then the parent's exit is canceled.\n *\n * If a number is returned, then the parent process exits with the number\n * as its exitCode.\n *\n * If a signal string is returned, then the parent process is killed with\n * the same signal that caused the child to exit.\n */\nexport type Cleanup = (\n  code: number | null,\n  signal: null | NodeJS.Signals,\n) =>\n  | void\n  | undefined\n  | number\n  | NodeJS.Signals\n  | false\n  | Promise<void | undefined | number | NodeJS.Signals | false>\n\nexport type FgArgs =\n  | [program: string | [cmd: string, ...args: string[]], cleanup?: Cleanup]\n  | [\n      program: [cmd: string, ...args: string[]],\n      opts?: SpawnOptions,\n      cleanup?: Cleanup,\n    ]\n  | [program: string, cleanup?: Cleanup]\n  | [program: string, opts?: SpawnOptions, cleanup?: Cleanup]\n  | [program: string, args?: string[], cleanup?: Cleanup]\n  | [\n      program: string,\n      args?: string[],\n      opts?: SpawnOptions,\n      cleanup?: Cleanup,\n    ]\n\n/**\n * Normalizes the arguments passed to `foregroundChild`.\n *\n * Exposed for testing.\n *\n * @internal\n */\nexport const normalizeFgArgs = (\n  fgArgs: FgArgs,\n): [\n  program: string,\n  args: string[],\n  spawnOpts: SpawnOptions,\n  cleanup: Cleanup,\n] => {\n  let [program, args = [], spawnOpts = {}, cleanup = () => {}] = fgArgs\n  if (typeof args === 'function') {\n    cleanup = args\n    spawnOpts = {}\n    args = []\n  } else if (!!args && typeof args === 'object' && !Array.isArray(args)) {\n    if (typeof spawnOpts === 'function') cleanup = spawnOpts\n    spawnOpts = args\n    args = []\n  } else if (typeof spawnOpts === 'function') {\n    cleanup = spawnOpts\n    spawnOpts = {}\n  }\n  if (Array.isArray(program)) {\n    const [pp, ...pa] = program\n    program = pp\n    args = pa\n  }\n  return [program, args, { ...spawnOpts }, cleanup]\n}\n\n/**\n * Spawn the specified program as a \"foreground\" process, or at least as\n * close as is possible given node's lack of exec-without-fork.\n *\n * Cleanup method may be used to modify or ignore the result of the child's\n * exit code or signal. If cleanup returns undefined (or a Promise that\n * resolves to undefined), then the parent will exit in the same way that\n * the child did.\n *\n * Return boolean `false` to prevent the parent's exit entirely.\n */\nexport function foregroundChild(\n  cmd: string | [cmd: string, ...args: string[]],\n  cleanup?: Cleanup,\n): ChildProcessByStdio<null, null, null>\nexport function foregroundChild(\n  program: string,\n  args?: string[],\n  cleanup?: Cleanup,\n): ChildProcessByStdio<null, null, null>\nexport function foregroundChild(\n  program: string,\n  spawnOpts?: SpawnOptions,\n  cleanup?: Cleanup,\n): ChildProcessByStdio<null, null, null>\nexport function foregroundChild(\n  program: string,\n  args?: string[],\n  spawnOpts?: SpawnOptions,\n  cleanup?: Cleanup,\n): ChildProcessByStdio<null, null, null>\nexport function foregroundChild(\n  ...fgArgs: FgArgs\n): ChildProcessByStdio<null, null, null> {\n  const [program, args, spawnOpts, cleanup] = normalizeFgArgs(fgArgs)\n\n  spawnOpts.stdio = [0, 1, 2]\n  if (process.send) {\n    spawnOpts.stdio.push('ipc')\n  }\n\n  const child = spawn(program, args, spawnOpts) as ChildProcessByStdio<\n    null,\n    null,\n    null\n  >\n\n  const childHangup = () => {\n    try {\n      child.kill('SIGHUP')\n\n      /* c8 ignore start */\n    } catch (_) {\n      // SIGHUP is weird on windows\n      child.kill('SIGTERM')\n    }\n    /* c8 ignore stop */\n  }\n  const removeOnExit = onExit(childHangup)\n\n  proxySignals(child)\n  watchdog(child)\n\n  let done = false\n  child.on('close', async (code, signal) => {\n    /* c8 ignore start */\n    if (done) return\n    /* c8 ignore stop */\n    done = true\n    const result = cleanup(code, signal)\n    const res = isPromise(result) ? await result : result\n    removeOnExit()\n\n    if (res === false) return\n    else if (typeof res === 'string') {\n      signal = res\n      code = null\n    } else if (typeof res === 'number') {\n      code = res\n      signal = null\n    }\n\n    if (signal) {\n      // If there is nothing else keeping the event loop alive,\n      // then there's a race between a graceful exit and getting\n      // the signal to this process.  Put this timeout here to\n      // make sure we're still alive to get the signal, and thus\n      // exit with the intended signal code.\n      /* istanbul ignore next */\n      setTimeout(() => {}, 2000)\n      try {\n        process.kill(process.pid, signal)\n        /* c8 ignore start */\n      } catch (_) {\n        process.kill(process.pid, 'SIGTERM')\n      }\n      /* c8 ignore stop */\n    } else {\n      process.exit(code || 0)\n    }\n  })\n\n  if (process.send) {\n    process.removeAllListeners('message')\n\n    child.on('message', (message, sendHandle) => {\n      process.send?.(message, sendHandle)\n    })\n\n    process.on('message', (message, sendHandle) => {\n      child.send(\n        message as Serializable,\n        sendHandle as SendHandle | undefined,\n      )\n    })\n  }\n\n  return child\n}\n\nconst isPromise = (o: any): o is Promise<any> =>\n  !!o && typeof o === 'object' && typeof o.then === 'function'\n"]}