{"version":3,"file":"pidTree.cjs","names":["os"],"sources":["../../../../src/utils/runParallel/pidTree.ts"],"sourcesContent":["import * as os from 'node:os';\nimport { ps } from './ps';\nimport { wmic } from './wmic';\n\ntype Platform =\n  | 'darwin'\n  | 'sunos'\n  | 'freebsd'\n  | 'netbsd'\n  | 'win'\n  | 'linux'\n  | 'aix';\ntype Method = 'ps' | 'wmic';\n\ntype ProcessList = [number, number][]; // [PPID, PID][]\n\ninterface ListOptions {\n  root?: boolean;\n  advanced?: boolean;\n}\n\ntype ProcessInfo = { pid: number; ppid?: number };\ntype ResultType<T extends ListOptions | undefined> = T extends {\n  advanced: true;\n}\n  ? ProcessInfo[]\n  : number[];\n\ntype ProcessListCallback = (err: Error | null, list?: ProcessList) => void;\ntype ListCallback<T extends ListOptions | undefined> = (\n  err: Error | null,\n  list?: ResultType<T>\n) => void;\n\ntype ProcessListFn = (callback: ProcessListCallback) => void;\n\nconst platformToMethod: Record<Platform, Method> = {\n  darwin: 'ps',\n  sunos: 'ps',\n  freebsd: 'ps',\n  netbsd: 'ps',\n  win: 'wmic',\n  linux: 'ps',\n  aix: 'ps',\n};\n\nconst methodToFn: Record<Method, ProcessListFn> = {\n  ps,\n  wmic,\n};\n\nlet platform: string = os.platform();\nif (platform.startsWith('win')) {\n  platform = 'win';\n}\n\nconst method: Method | undefined = platformToMethod[platform as Platform];\n\n/**\n * Gets the list of all the pids of the system.\n */\nconst getAll = (callback: ProcessListCallback): void => {\n  if (method === undefined) {\n    callback(\n      new Error(\n        os.platform() +\n          ' is not supported yet, please open an issue (https://github.com/simonepri/pidtree)'\n      ),\n      undefined\n    );\n    return;\n  }\n\n  const listFn = methodToFn[method];\n  listFn(callback);\n};\n\n/**\n * Get the list of children and grandchildren pids of the given PID.\n * @param PID A PID. If -1 will return all the pids.\n * @param options Optional options object.\n * @param callback Called when the list is ready.\n */\nconst pidtree = <T extends ListOptions | undefined>(\n  PID: number | string,\n  options: T | ListCallback<T> | undefined,\n  callback?: ListCallback<T>\n): void => {\n  let normalizedOptions: ListOptions;\n  let normalizedCallback: ListCallback<T>;\n\n  if (typeof options === 'function') {\n    normalizedCallback = options;\n    normalizedOptions = {};\n  } else {\n    normalizedCallback = callback!;\n    normalizedOptions = typeof options === 'object' ? options : {};\n  }\n\n  const parsedPID = parseInt(String(PID), 10);\n  if (Number.isNaN(parsedPID) || parsedPID < -1) {\n    normalizedCallback(\n      new TypeError('The pid provided is invalid') as Error,\n      undefined\n    );\n    return;\n  }\n\n  getAll((err, processList) => {\n    if (err) {\n      normalizedCallback(err, undefined);\n      return;\n    }\n\n    if (!processList) {\n      normalizedCallback(new Error('Failed to get process list'), undefined);\n      return;\n    }\n\n    // If the user wants the whole list just return it\n    if (parsedPID === -1) {\n      const result = processList.map(([ppid, pid]) =>\n        normalizedOptions.advanced ? { ppid, pid } : pid\n      ) as ResultType<T>;\n\n      normalizedCallback(null, result);\n      return;\n    }\n\n    let root: ProcessInfo | number | undefined;\n    for (let l = 0; l < processList.length; l++) {\n      if (processList[l][1] === parsedPID) {\n        root = normalizedOptions.advanced\n          ? { ppid: processList[l][0], pid: parsedPID }\n          : parsedPID;\n        break;\n      }\n\n      if (processList[l][0] === parsedPID) {\n        root = normalizedOptions.advanced ? { pid: parsedPID } : parsedPID; // Special pids like 0 on *nix\n      }\n    }\n\n    if (root === undefined) {\n      normalizedCallback(new Error('No matching pid found'), undefined);\n      return;\n    }\n\n    // Build the adjacency Hash Map (pid -> [children of pid])\n    const tree: Record<number, number[]> = {};\n    const listCopy = [...processList];\n    while (listCopy.length > 0) {\n      const element = listCopy.pop()!;\n      if (tree[element[0]]) {\n        tree[element[0]].push(element[1]);\n      } else {\n        tree[element[0]] = [element[1]];\n      }\n    }\n\n    // Starting by the PID provided by the user, traverse the tree using the\n    // adjacency Hash Map until the whole subtree is visited.\n    // Each pid encountered while visiting is added to the pids array.\n    let idx = 0;\n    const pids: (ProcessInfo | number)[] = [root];\n    while (idx < pids.length) {\n      const curpid = normalizedOptions.advanced\n        ? (pids[idx++] as ProcessInfo).pid\n        : (pids[idx++] as number);\n      if (!tree[curpid]) continue;\n      const length = tree[curpid].length;\n      for (let j = 0; j < length; j++) {\n        pids.push(\n          normalizedOptions.advanced\n            ? { ppid: curpid, pid: tree[curpid][j] }\n            : tree[curpid][j]\n        );\n      }\n\n      delete tree[curpid];\n    }\n\n    if (!normalizedOptions.root) {\n      pids.shift(); // Remove root\n    }\n\n    normalizedCallback(null, pids as ResultType<T>);\n  });\n};\n\nconst pify = <T extends ListOptions | undefined>(\n  fn: typeof pidtree,\n  arg1: number | string,\n  arg2: T | undefined\n): Promise<ResultType<T>> => {\n  return new Promise((resolve, reject) => {\n    fn(arg1, arg2, (err, data) => {\n      if (err) return reject(err);\n      if (data === undefined) {\n        return reject(new Error('No data returned'));\n      }\n      resolve(data);\n    });\n  });\n};\n\n// Node versions prior to 4.0.0 do not define have `startsWith`.\n/* istanbul ignore if */\nif (!String.prototype.startsWith) {\n  String.prototype.startsWith = function (suffix: string): boolean {\n    return this.substring(0, suffix.length) === suffix;\n  };\n}\n\n/**\n * Get the list of children pids of the given pid.\n * @param pid A PID. If -1 will return all the pids.\n * @param options Optional options object.\n * @param callback Called when the list is ready. If not provided a promise is returned instead.\n * @returns Only when the callback is not provided.\n */\nexport const list = <T extends ListOptions | undefined>(\n  pid: number | string,\n  options?: T | ListCallback<T>,\n  callback?: ListCallback<T>\n): Promise<ResultType<T>> | undefined => {\n  if (typeof options === 'function') {\n    pidtree(pid, undefined, options);\n    return;\n  }\n\n  if (typeof callback === 'function') {\n    pidtree(pid, options, callback);\n    return;\n  }\n\n  return pify(pidtree, pid, options);\n};\n"],"mappings":"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"}