@socketsecurity/cli-with-sentry 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +426 -0
  2. package/bin/cli.js +3 -1
  3. package/dist/cli.js +362 -400
  4. package/dist/cli.js.map +1 -1
  5. package/dist/constants.js +211 -19
  6. package/dist/constants.js.map +1 -1
  7. package/dist/flags.js +3 -3
  8. package/dist/flags.js.map +1 -1
  9. package/dist/instrument-with-sentry.js +8 -8
  10. package/dist/instrument-with-sentry.js.map +1 -1
  11. package/dist/shadow-npm-bin.js +14 -14
  12. package/dist/shadow-npm-bin.js.map +1 -1
  13. package/dist/shadow-npm-inject.js +16 -16
  14. package/dist/shadow-npm-inject.js.map +1 -1
  15. package/dist/tsconfig.dts.tsbuildinfo +1 -1
  16. package/dist/types/commands/ci/handle-ci.d.mts.map +1 -1
  17. package/dist/types/commands/fix/cmd-fix.d.mts.map +1 -1
  18. package/dist/types/commands/npm/cmd-npm.d.mts +1 -1
  19. package/dist/types/commands/npm/cmd-npm.d.mts.map +1 -1
  20. package/dist/types/commands/optimize/add-overrides.d.mts.map +1 -1
  21. package/dist/types/commands/patch/cmd-patch.d.mts.map +1 -1
  22. package/dist/types/commands/patch/handle-patch.d.mts +9 -2
  23. package/dist/types/commands/patch/handle-patch.d.mts.map +1 -1
  24. package/dist/types/commands/patch/output-patch-result.d.mts +1 -1
  25. package/dist/types/commands/patch/output-patch-result.d.mts.map +1 -1
  26. package/dist/types/commands/scan/cmd-scan-create.d.mts.map +1 -1
  27. package/dist/types/commands/scan/cmd-scan-github.d.mts.map +1 -1
  28. package/dist/types/commands/scan/cmd-scan-report.d.mts.map +1 -1
  29. package/dist/types/commands/scan/create-scan-from-github.d.mts.map +1 -1
  30. package/dist/types/commands/scan/generate-report.d.mts +9 -8
  31. package/dist/types/commands/scan/generate-report.d.mts.map +1 -1
  32. package/dist/types/commands/scan/handle-create-new-scan.d.mts +5 -2
  33. package/dist/types/commands/scan/handle-create-new-scan.d.mts.map +1 -1
  34. package/dist/types/commands/scan/handle-scan-report.d.mts +7 -5
  35. package/dist/types/commands/scan/handle-scan-report.d.mts.map +1 -1
  36. package/dist/types/commands/scan/output-scan-report.d.mts +10 -8
  37. package/dist/types/commands/scan/output-scan-report.d.mts.map +1 -1
  38. package/dist/types/commands/scan/perform-reachability-analysis.d.mts.map +1 -1
  39. package/dist/types/commands/scan/types.d.mts +3 -0
  40. package/dist/types/commands/scan/types.d.mts.map +1 -0
  41. package/dist/types/constants.d.mts +99 -46
  42. package/dist/types/constants.d.mts.map +1 -1
  43. package/dist/types/shadow/npm/arborist-helpers.d.mts +1 -17
  44. package/dist/types/shadow/npm/arborist-helpers.d.mts.map +1 -1
  45. package/dist/types/shadow/npm/bin.d.mts +4 -3
  46. package/dist/types/shadow/npm/bin.d.mts.map +1 -1
  47. package/dist/types/utils/coana.d.mts.map +1 -1
  48. package/dist/types/utils/ecosystem.d.mts.map +1 -1
  49. package/dist/types/utils/get-output-kind.d.mts.map +1 -1
  50. package/dist/types/utils/glob.d.mts.map +1 -1
  51. package/dist/types/utils/package-environment.d.mts.map +1 -1
  52. package/dist/types/utils/purl.d.mts +25 -9
  53. package/dist/types/utils/purl.d.mts.map +1 -1
  54. package/dist/types/utils/spec.d.mts.map +1 -1
  55. package/dist/utils.js +120 -102
  56. package/dist/utils.js.map +1 -1
  57. package/dist/vendor.js +222 -4598
  58. package/external/@socketsecurity/registry/lib/constants/env.js +0 -3
  59. package/external/@socketsecurity/registry/lib/constants/ext-cjs.js +3 -0
  60. package/external/@socketsecurity/registry/lib/constants/ext-cts.js +3 -0
  61. package/external/@socketsecurity/registry/lib/constants/ext-dts.js +3 -0
  62. package/external/@socketsecurity/registry/lib/constants/ext-js.js +3 -0
  63. package/external/@socketsecurity/registry/lib/constants/ext-json.js +3 -0
  64. package/external/@socketsecurity/registry/lib/constants/ext-lock.js +3 -0
  65. package/external/@socketsecurity/registry/lib/constants/ext-lockb.js +3 -0
  66. package/external/@socketsecurity/registry/lib/constants/ext-md.js +3 -0
  67. package/external/@socketsecurity/registry/lib/constants/ext-mjs.js +3 -0
  68. package/external/@socketsecurity/registry/lib/constants/ext-mts.js +3 -0
  69. package/external/@socketsecurity/registry/lib/constants/index.js +82 -83
  70. package/external/@socketsecurity/registry/lib/constants/ipc-promise.js +4 -5
  71. package/external/@socketsecurity/registry/lib/constants/node-debug-flags.js +9 -0
  72. package/external/@socketsecurity/registry/lib/constants/pnpm.js +3 -0
  73. package/external/@socketsecurity/registry/lib/constants/yarn-lock.js +3 -0
  74. package/external/@socketsecurity/registry/lib/json.js +11 -0
  75. package/external/@socketsecurity/registry/lib/strings.js +16 -0
  76. package/package.json +13 -12
  77. package/external/@socketsecurity/registry/lib/constants/socket-public-api-key.js +0 -3
  78. package/external/@socketsecurity/registry/lib/constants/tap.js +0 -3
  79. /package/external/@socketsecurity/registry/lib/constants/{ipc.js → ipc-object.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"instrument-with-sentry.js","sources":["../src/instrument-with-sentry.mts"],"sourcesContent":["// This should ONLY be included in the special Sentry build!\n// Otherwise the Sentry dependency won't even be present in the manifest.\n\nimport { createRequire } from 'node:module'\n\nimport { logger } from '@socketsecurity/registry/lib/logger'\n\nimport constants from './constants.mts'\n\nif (constants.ENV.INLINED_SOCKET_CLI_SENTRY_BUILD) {\n const require = createRequire(import.meta.url)\n const Sentry = /*@__PURE__*/ require('@sentry/node')\n Sentry.init({\n onFatalError(error: Error) {\n // Defer module loads until after Sentry.init is called.\n if (constants.ENV.SOCKET_CLI_DEBUG) {\n logger.fail('[DEBUG] [Sentry onFatalError]:', error)\n }\n },\n dsn: 'https://66736701db8e4ffac046bd09fa6aaced@o555220.ingest.us.sentry.io/4508846967619585',\n enabled: true,\n integrations: [],\n })\n Sentry.setTag(\n 'environment',\n constants.ENV.INLINED_SOCKET_CLI_PUBLISHED_BUILD\n ? 'pub'\n : constants.ENV.NODE_ENV,\n )\n Sentry.setTag('version', constants.ENV.INLINED_SOCKET_CLI_VERSION_HASH)\n if (constants.ENV.SOCKET_CLI_DEBUG) {\n Sentry.setTag('debugging', true)\n logger.info('[DEBUG] Set up Sentry.')\n } else {\n Sentry.setTag('debugging', false)\n }\n const {\n kInternalsSymbol,\n [kInternalsSymbol as unknown as 'Symbol(kInternalsSymbol)']: { setSentry },\n } = constants\n setSentry(Sentry)\n} else if (constants.ENV.SOCKET_CLI_DEBUG) {\n logger.info('[DEBUG] Sentry disabled explicitly.')\n}\n"],"names":["logger","dsn","enabled","integrations","Sentry","setSentry"],"mappings":";;;;;;;AAAA;AACA;;AAQA;;AAEE;;;AAGI;AACA;AACEA;AACF;;AAEFC;AACAC;AACAC;AACF;AACAC;;AAOA;AACEA;AACAJ;AACF;AACEI;AACF;;;AAGE;AAA+DC;AAAU;AAC3E;;AAEF;AACEL;AACF","debugId":"2a2ffd5a-4b19-474d-a10f-55917e9bbbf9"}
1
+ {"version":3,"file":"instrument-with-sentry.js","sources":["../src/instrument-with-sentry.mts"],"sourcesContent":["// This should ONLY be included in the special Sentry build!\n// Otherwise the Sentry dependency won't even be present in the manifest.\n\nimport { createRequire } from 'node:module'\n\nimport { logger } from '@socketsecurity/registry/lib/logger'\n\nimport constants from './constants.mts'\n\nif (constants.ENV.INLINED_SOCKET_CLI_SENTRY_BUILD) {\n const require = createRequire(import.meta.url)\n const Sentry = /*@__PURE__*/ require('@sentry/node')\n Sentry.init({\n onFatalError(error: Error) {\n // Defer module loads until after Sentry.init is called.\n if (constants.ENV.SOCKET_CLI_DEBUG) {\n logger.fail('[DEBUG] [Sentry onFatalError]:', error)\n }\n },\n dsn: 'https://66736701db8e4ffac046bd09fa6aaced@o555220.ingest.us.sentry.io/4508846967619585',\n enabled: true,\n integrations: [],\n })\n Sentry.setTag(\n 'environment',\n constants.ENV.INLINED_SOCKET_CLI_PUBLISHED_BUILD\n ? 'pub'\n : constants.ENV.NODE_ENV,\n )\n Sentry.setTag('version', constants.ENV.INLINED_SOCKET_CLI_VERSION_HASH)\n if (constants.ENV.SOCKET_CLI_DEBUG) {\n Sentry.setTag('debugging', true)\n logger.info('[DEBUG] Set up Sentry.')\n } else {\n Sentry.setTag('debugging', false)\n }\n const {\n kInternalsSymbol,\n [kInternalsSymbol as unknown as 'Symbol(kInternalsSymbol)']: { setSentry },\n } = constants\n setSentry(Sentry)\n} else if (constants.ENV.SOCKET_CLI_DEBUG) {\n logger.info('[DEBUG] Sentry disabled explicitly.')\n}\n"],"names":["logger","dsn","enabled","integrations","Sentry","setSentry"],"mappings":";;;;;;;AAAA;AACA;;AAQA;;AAEE;;;AAGI;AACA;AACEA;AACF;;AAEFC;AACAC;AACAC;AACF;AACAC;;AAOA;AACEA;AACAJ;AACF;AACEI;AACF;;;AAGE;AAA+DC;AAAU;AAC3E;;AAEF;AACEL;AACF","debugId":"b3c08eee-1888-4b54-a012-59984ad55732"}
@@ -15,7 +15,7 @@ async function installLinks(shadowBinPath, binName) {
15
15
  const binPath = isNpx ? utils.getNpxBinPath() : utils.getNpmBinPath();
16
16
  const {
17
17
  WIN32
18
- } = constants;
18
+ } = constants.default;
19
19
  // TODO: Is this early exit needed?
20
20
  if (WIN32 && binPath) {
21
21
  return binPath;
@@ -24,7 +24,7 @@ async function installLinks(shadowBinPath, binName) {
24
24
  // Move our bin directory to front of PATH so its found first.
25
25
  if (!shadowed) {
26
26
  if (WIN32) {
27
- await vendor.libExports(path.join(constants.distPath, `${binName}-cli.js`), path.join(shadowBinPath, binName));
27
+ await vendor.libExports(path.join(constants.default.distPath, `${binName}-cli.js`), path.join(shadowBinPath, binName));
28
28
  }
29
29
  const {
30
30
  env
@@ -44,18 +44,18 @@ async function shadowBin(binName, args = process.argv.slice(2), options, extra)
44
44
  ...options
45
45
  };
46
46
  const cwd = require$$11.getOwn(spawnOpts, 'cwd') ?? process.cwd();
47
- const isShadowNpm = binName === 'npm';
47
+ const isShadowNpm = binName === constants.NPM;
48
48
  const terminatorPos = args.indexOf('--');
49
49
  const rawBinArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos);
50
50
  const nodeOptionsArg = rawBinArgs.findLast(npm.isNpmNodeOptionsFlag);
51
51
  const progressArg = rawBinArgs.findLast(npm.isNpmProgressFlag) !== '--no-progress';
52
52
  const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos);
53
- const permArgs = isShadowNpm && constants.SUPPORTS_NODE_PERMISSION_FLAG ? ['--permission', '--allow-child-process',
53
+ const permArgs = isShadowNpm && constants.default.SUPPORTS_NODE_PERMISSION_FLAG ? ['--permission', '--allow-child-process',
54
54
  // '--allow-addons',
55
55
  // '--allow-wasi',
56
56
  // Allow all reads because npm walks up directories looking for config
57
57
  // and package.json files.
58
- '--allow-fs-read=*', `--allow-fs-write=${cwd}/*`, `--allow-fs-write=${constants.npmGlobalPrefix}/*`, `--allow-fs-write=${constants.npmCachePath}/*`] : [];
58
+ '--allow-fs-read=*', `--allow-fs-write=${cwd}/*`, `--allow-fs-write=${constants.default.npmGlobalPrefix}/*`, `--allow-fs-write=${constants.default.npmCachePath}/*`] : [];
59
59
  const useAudit = rawBinArgs.includes('--audit');
60
60
  const useDebug = require$$9.isDebug('stdio');
61
61
  const useNodeOptions = nodeOptionsArg || permArgs.length;
@@ -64,7 +64,7 @@ async function shadowBin(binName, args = process.argv.slice(2), options, extra)
64
64
  // The default value of loglevel is "notice". We default to "error" which is
65
65
  // two levels quieter.
66
66
  const logLevelArgs = isSilent ? ['--loglevel', 'error'] : [];
67
- const noAuditArgs = useAudit || !(await utils.findUp('node_modules', {
67
+ const noAuditArgs = useAudit || !(await utils.findUp(constants.NODE_MODULES, {
68
68
  cwd,
69
69
  onlyDirectories: true
70
70
  })) ? [] : ['--no-audit'];
@@ -78,8 +78,8 @@ async function shadowBin(binName, args = process.argv.slice(2), options, extra)
78
78
  } else {
79
79
  stdio = ['pipe', 'pipe', 'pipe', 'ipc'];
80
80
  }
81
- const realBinPath = await installLinks(constants.shadowBinPath, binName);
82
- const spawnPromise = spawn.spawn(constants.execPath, [...constants.nodeNoWarningsFlags, ...constants.nodeDebugFlags, ...constants.nodeHardenFlags, ...constants.nodeMemoryFlags, ...(constants.ENV.INLINED_SOCKET_CLI_SENTRY_BUILD ? ['--require', constants.instrumentWithSentryPath] : []), '--require', constants.shadowNpmInjectPath, realBinPath, ...noAuditArgs, ...(useNodeOptions ? [`--node-options='${nodeOptionsArg ? nodeOptionsArg.slice(15) : ''}${utils.cmdFlagsToString(permArgs)}'`] : []), '--no-fund',
81
+ const realBinPath = await installLinks(constants.default.shadowBinPath, binName);
82
+ const spawnPromise = spawn.spawn(constants.default.execPath, [...constants.default.nodeNoWarningsFlags, ...constants.default.nodeDebugFlags, ...constants.default.nodeHardenFlags, ...constants.default.nodeMemoryFlags, ...(constants.default.ENV.INLINED_SOCKET_CLI_SENTRY_BUILD ? ['--require', constants.default.instrumentWithSentryPath] : []), '--require', constants.default.shadowNpmInjectPath, realBinPath, ...noAuditArgs, ...(useNodeOptions ? [`--node-options='${nodeOptionsArg ? nodeOptionsArg.slice(15) : ''}${utils.cmdFlagsToString(permArgs)}'`] : []), '--no-fund',
83
83
  // Add '--no-progress' to fix input being swallowed by the npm spinner.
84
84
  '--no-progress',
85
85
  // Add '--loglevel=error' if a loglevel flag is not provided and the
@@ -88,16 +88,16 @@ async function shadowBin(binName, args = process.argv.slice(2), options, extra)
88
88
  ...spawnOpts,
89
89
  env: {
90
90
  ...process.env,
91
- ...constants.processEnv,
91
+ ...constants.default.processEnv,
92
92
  ...spawnEnv
93
93
  },
94
94
  stdio
95
95
  }, extra);
96
96
  spawnPromise.process.send({
97
- [constants.SOCKET_IPC_HANDSHAKE]: {
98
- [constants.SOCKET_CLI_SHADOW_API_TOKEN]: utils.getPublicApiToken(),
99
- [constants.SOCKET_CLI_SHADOW_BIN]: binName,
100
- [constants.SOCKET_CLI_SHADOW_PROGRESS]: progressArg,
97
+ [constants.default.SOCKET_IPC_HANDSHAKE]: {
98
+ [constants.default.SOCKET_CLI_SHADOW_API_TOKEN]: utils.getPublicApiToken(),
99
+ [constants.default.SOCKET_CLI_SHADOW_BIN]: binName,
100
+ [constants.default.SOCKET_CLI_SHADOW_PROGRESS]: progressArg,
101
101
  ...ipc
102
102
  }
103
103
  });
@@ -107,5 +107,5 @@ async function shadowBin(binName, args = process.argv.slice(2), options, extra)
107
107
  }
108
108
 
109
109
  module.exports = shadowBin;
110
- //# debugId=3db6aa47-ab77-4ba0-8e8b-08bbbbf027ee
110
+ //# debugId=9a370935-692f-4b6a-aa5d-62d09bae0929
111
111
  //# sourceMappingURL=shadow-npm-bin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-npm-bin.js","sources":["../src/shadow/npm/link.mts","../src/shadow/npm/bin.mts"],"sourcesContent":["import path from 'node:path'\n\nimport cmdShim from 'cmd-shim'\n\nimport constants from '../../constants.mts'\nimport {\n getNpmBinPath,\n getNpxBinPath,\n isNpmBinPathShadowed,\n isNpxBinPathShadowed,\n} from '../../utils/npm-paths.mts'\n\nexport async function installLinks(\n shadowBinPath: string,\n binName: 'npm' | 'npx',\n): Promise<string> {\n const isNpx = binName === 'npx'\n // Find package manager being shadowed by this process.\n const binPath = isNpx ? getNpxBinPath() : getNpmBinPath()\n const { WIN32 } = constants\n // TODO: Is this early exit needed?\n if (WIN32 && binPath) {\n return binPath\n }\n const shadowed = isNpx ? isNpxBinPathShadowed() : isNpmBinPathShadowed()\n // Move our bin directory to front of PATH so its found first.\n if (!shadowed) {\n if (WIN32) {\n await cmdShim(\n path.join(constants.distPath, `${binName}-cli.js`),\n path.join(shadowBinPath, binName),\n )\n }\n const { env } = process\n env['PATH'] = `${shadowBinPath}${path.delimiter}${env['PATH']}`\n }\n return binPath\n}\n","import { isDebug } from '@socketsecurity/registry/lib/debug'\nimport {\n isNpmAuditFlag,\n isNpmLoglevelFlag,\n isNpmNodeOptionsFlag,\n isNpmProgressFlag,\n} from '@socketsecurity/registry/lib/npm'\nimport { getOwn } from '@socketsecurity/registry/lib/objects'\nimport { spawn } from '@socketsecurity/registry/lib/spawn'\n\nimport { installLinks } from './link.mts'\nimport constants from '../../constants.mts'\nimport { cmdFlagsToString } from '../../utils/cmd.mts'\nimport { findUp } from '../../utils/fs.mts'\nimport { getPublicApiToken } from '../../utils/sdk.mts'\n\nimport type { IPC } from '../../constants.mts'\nimport type {\n SpawnExtra,\n SpawnOptions,\n SpawnResult,\n} from '@socketsecurity/registry/lib/spawn'\n\nexport type ShadowBinOptions = SpawnOptions & {\n ipc?: IPC | undefined\n}\n\nexport type ShadowBinResult = {\n spawnPromise: SpawnResult<string, SpawnExtra | undefined>\n}\n\nexport default async function shadowBin(\n binName: 'npm' | 'npx',\n args: string[] | readonly string[] = process.argv.slice(2),\n options?: ShadowBinOptions | undefined,\n extra?: SpawnExtra | undefined,\n): Promise<ShadowBinResult> {\n const {\n env: spawnEnv,\n ipc,\n ...spawnOpts\n } = { __proto__: null, ...options } as ShadowBinOptions\n const cwd = getOwn(spawnOpts, 'cwd') ?? process.cwd()\n const isShadowNpm = binName === 'npm'\n const terminatorPos = args.indexOf('--')\n const rawBinArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos)\n const nodeOptionsArg = rawBinArgs.findLast(isNpmNodeOptionsFlag)\n const progressArg = rawBinArgs.findLast(isNpmProgressFlag) !== '--no-progress'\n const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos)\n const permArgs =\n isShadowNpm && constants.SUPPORTS_NODE_PERMISSION_FLAG\n ? [\n '--permission',\n '--allow-child-process',\n // '--allow-addons',\n // '--allow-wasi',\n // Allow all reads because npm walks up directories looking for config\n // and package.json files.\n '--allow-fs-read=*',\n `--allow-fs-write=${cwd}/*`,\n `--allow-fs-write=${constants.npmGlobalPrefix}/*`,\n `--allow-fs-write=${constants.npmCachePath}/*`,\n ]\n : []\n\n const useAudit = rawBinArgs.includes('--audit')\n const useDebug = isDebug('stdio')\n const useNodeOptions = nodeOptionsArg || permArgs.length\n const binArgs = rawBinArgs.filter(\n a => !isNpmAuditFlag(a) && !isNpmProgressFlag(a),\n )\n const isSilent = !useDebug && !binArgs.some(isNpmLoglevelFlag)\n // The default value of loglevel is \"notice\". We default to \"error\" which is\n // two levels quieter.\n const logLevelArgs = isSilent ? ['--loglevel', 'error'] : []\n const noAuditArgs =\n useAudit || !(await findUp('node_modules', { cwd, onlyDirectories: true }))\n ? []\n : ['--no-audit']\n\n let stdio = getOwn(spawnOpts, 'stdio')\n if (typeof stdio === 'string') {\n stdio = [stdio, stdio, stdio, 'ipc']\n } else if (Array.isArray(stdio)) {\n if (!stdio.includes('ipc')) {\n stdio = stdio.concat('ipc')\n }\n } else {\n stdio = ['pipe', 'pipe', 'pipe', 'ipc']\n }\n\n const realBinPath = await installLinks(constants.shadowBinPath, binName)\n\n const spawnPromise = spawn(\n constants.execPath,\n [\n ...constants.nodeNoWarningsFlags,\n ...constants.nodeDebugFlags,\n ...constants.nodeHardenFlags,\n ...constants.nodeMemoryFlags,\n ...(constants.ENV.INLINED_SOCKET_CLI_SENTRY_BUILD\n ? ['--require', constants.instrumentWithSentryPath]\n : []),\n '--require',\n constants.shadowNpmInjectPath,\n realBinPath,\n ...noAuditArgs,\n ...(useNodeOptions\n ? [\n `--node-options='${nodeOptionsArg ? nodeOptionsArg.slice(15) : ''}${cmdFlagsToString(permArgs)}'`,\n ]\n : []),\n '--no-fund',\n // Add '--no-progress' to fix input being swallowed by the npm spinner.\n '--no-progress',\n // Add '--loglevel=error' if a loglevel flag is not provided and the\n // SOCKET_CLI_DEBUG environment variable is not truthy.\n ...logLevelArgs,\n ...binArgs,\n ...otherArgs,\n ],\n {\n ...spawnOpts,\n env: {\n ...process.env,\n ...constants.processEnv,\n ...spawnEnv,\n },\n stdio,\n },\n extra,\n )\n\n spawnPromise.process.send({\n [constants.SOCKET_IPC_HANDSHAKE]: {\n [constants.SOCKET_CLI_SHADOW_API_TOKEN]: getPublicApiToken(),\n [constants.SOCKET_CLI_SHADOW_BIN]: binName,\n [constants.SOCKET_CLI_SHADOW_PROGRESS]: progressArg,\n ...ipc,\n },\n })\n\n return { spawnPromise }\n}\n"],"names":["WIN32","env","__proto__","onlyDirectories","stdio","spawnPromise"],"mappings":";;;;;;;;;;;AAYO;AAIL;AACA;;;AAEQA;AAAM;AACd;;AAEE;AACF;;AAEA;;AAEE;;AAKA;;AACQC;AAAI;AACZA;AACF;AACA;AACF;;ACNe;;AAOXA;;;AAGF;AAAMC;;;AACN;AACA;AACA;AACA;AACA;;AAEA;;AAMQ;AACA;AACA;AACA;AACA;AAOR;AACA;AACA;AACA;;AAIA;AACA;;;;AAGoDC;AAAsB;AAI1E;AACA;;;AAGE;AACEC;AACF;AACF;;AAEA;;AAIA;AAoBI;;AAEA;AACA;;AAMA;AACAH;;;;;AAKAG;;AAKJC;;AAEI;AACA;AACA;;AAEF;AACF;;AAESA;;AACX;;","debugId":"3db6aa47-ab77-4ba0-8e8b-08bbbbf027ee"}
1
+ {"version":3,"file":"shadow-npm-bin.js","sources":["../src/shadow/npm/link.mts","../src/shadow/npm/bin.mts"],"sourcesContent":["import path from 'node:path'\n\nimport cmdShim from 'cmd-shim'\n\nimport constants from '../../constants.mts'\nimport {\n getNpmBinPath,\n getNpxBinPath,\n isNpmBinPathShadowed,\n isNpxBinPathShadowed,\n} from '../../utils/npm-paths.mts'\n\nexport async function installLinks(\n shadowBinPath: string,\n binName: 'npm' | 'npx',\n): Promise<string> {\n const isNpx = binName === 'npx'\n // Find package manager being shadowed by this process.\n const binPath = isNpx ? getNpxBinPath() : getNpmBinPath()\n const { WIN32 } = constants\n // TODO: Is this early exit needed?\n if (WIN32 && binPath) {\n return binPath\n }\n const shadowed = isNpx ? isNpxBinPathShadowed() : isNpmBinPathShadowed()\n // Move our bin directory to front of PATH so its found first.\n if (!shadowed) {\n if (WIN32) {\n await cmdShim(\n path.join(constants.distPath, `${binName}-cli.js`),\n path.join(shadowBinPath, binName),\n )\n }\n const { env } = process\n env['PATH'] = `${shadowBinPath}${path.delimiter}${env['PATH']}`\n }\n return binPath\n}\n","import { isDebug } from '@socketsecurity/registry/lib/debug'\nimport {\n isNpmAuditFlag,\n isNpmLoglevelFlag,\n isNpmNodeOptionsFlag,\n isNpmProgressFlag,\n} from '@socketsecurity/registry/lib/npm'\nimport { getOwn } from '@socketsecurity/registry/lib/objects'\nimport { spawn } from '@socketsecurity/registry/lib/spawn'\n\nimport { installLinks } from './link.mts'\nimport constants, { NODE_MODULES, NPM, NPX } from '../../constants.mts'\nimport { cmdFlagsToString } from '../../utils/cmd.mts'\nimport { findUp } from '../../utils/fs.mts'\nimport { getPublicApiToken } from '../../utils/sdk.mts'\n\nimport type { IpcObject } from '../../constants.mts'\nimport type {\n SpawnExtra,\n SpawnOptions,\n SpawnResult,\n} from '@socketsecurity/registry/lib/spawn'\n\nexport type ShadowBinOptions = SpawnOptions & {\n ipc?: IpcObject | undefined\n}\n\nexport type ShadowBinResult = {\n spawnPromise: SpawnResult<string, SpawnExtra | undefined>\n}\n\nexport default async function shadowBin(\n binName: typeof NPM | typeof NPX,\n args: string[] | readonly string[] = process.argv.slice(2),\n options?: ShadowBinOptions | undefined,\n extra?: SpawnExtra | undefined,\n): Promise<ShadowBinResult> {\n const {\n env: spawnEnv,\n ipc,\n ...spawnOpts\n } = { __proto__: null, ...options } as ShadowBinOptions\n const cwd = getOwn(spawnOpts, 'cwd') ?? process.cwd()\n const isShadowNpm = binName === NPM\n const terminatorPos = args.indexOf('--')\n const rawBinArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos)\n const nodeOptionsArg = rawBinArgs.findLast(isNpmNodeOptionsFlag)\n const progressArg = rawBinArgs.findLast(isNpmProgressFlag) !== '--no-progress'\n const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos)\n const permArgs =\n isShadowNpm && constants.SUPPORTS_NODE_PERMISSION_FLAG\n ? [\n '--permission',\n '--allow-child-process',\n // '--allow-addons',\n // '--allow-wasi',\n // Allow all reads because npm walks up directories looking for config\n // and package.json files.\n '--allow-fs-read=*',\n `--allow-fs-write=${cwd}/*`,\n `--allow-fs-write=${constants.npmGlobalPrefix}/*`,\n `--allow-fs-write=${constants.npmCachePath}/*`,\n ]\n : []\n\n const useAudit = rawBinArgs.includes('--audit')\n const useDebug = isDebug('stdio')\n const useNodeOptions = nodeOptionsArg || permArgs.length\n const binArgs = rawBinArgs.filter(\n a => !isNpmAuditFlag(a) && !isNpmProgressFlag(a),\n )\n const isSilent = !useDebug && !binArgs.some(isNpmLoglevelFlag)\n // The default value of loglevel is \"notice\". We default to \"error\" which is\n // two levels quieter.\n const logLevelArgs = isSilent ? ['--loglevel', 'error'] : []\n const noAuditArgs =\n useAudit || !(await findUp(NODE_MODULES, { cwd, onlyDirectories: true }))\n ? []\n : ['--no-audit']\n\n let stdio = getOwn(spawnOpts, 'stdio')\n if (typeof stdio === 'string') {\n stdio = [stdio, stdio, stdio, 'ipc']\n } else if (Array.isArray(stdio)) {\n if (!stdio.includes('ipc')) {\n stdio = stdio.concat('ipc')\n }\n } else {\n stdio = ['pipe', 'pipe', 'pipe', 'ipc']\n }\n\n const realBinPath = await installLinks(constants.shadowBinPath, binName)\n\n const spawnPromise = spawn(\n constants.execPath,\n [\n ...constants.nodeNoWarningsFlags,\n ...constants.nodeDebugFlags,\n ...constants.nodeHardenFlags,\n ...constants.nodeMemoryFlags,\n ...(constants.ENV.INLINED_SOCKET_CLI_SENTRY_BUILD\n ? ['--require', constants.instrumentWithSentryPath]\n : []),\n '--require',\n constants.shadowNpmInjectPath,\n realBinPath,\n ...noAuditArgs,\n ...(useNodeOptions\n ? [\n `--node-options='${nodeOptionsArg ? nodeOptionsArg.slice(15) : ''}${cmdFlagsToString(permArgs)}'`,\n ]\n : []),\n '--no-fund',\n // Add '--no-progress' to fix input being swallowed by the npm spinner.\n '--no-progress',\n // Add '--loglevel=error' if a loglevel flag is not provided and the\n // SOCKET_CLI_DEBUG environment variable is not truthy.\n ...logLevelArgs,\n ...binArgs,\n ...otherArgs,\n ],\n {\n ...spawnOpts,\n env: {\n ...process.env,\n ...constants.processEnv,\n ...spawnEnv,\n },\n stdio,\n },\n extra,\n )\n\n spawnPromise.process.send({\n [constants.SOCKET_IPC_HANDSHAKE]: {\n [constants.SOCKET_CLI_SHADOW_API_TOKEN]: getPublicApiToken(),\n [constants.SOCKET_CLI_SHADOW_BIN]: binName,\n [constants.SOCKET_CLI_SHADOW_PROGRESS]: progressArg,\n ...ipc,\n },\n })\n\n return { spawnPromise }\n}\n"],"names":["WIN32","env","__proto__","onlyDirectories","stdio","spawnPromise"],"mappings":";;;;;;;;;;;AAYO;AAIL;AACA;;;AAEQA;AAAM;AACd;;AAEE;AACF;;AAEA;;AAEE;;AAKA;;AACQC;AAAI;AACZA;AACF;AACA;AACF;;ACNe;;AAOXA;;;AAGF;AAAMC;;;AACN;AACA;AACA;AACA;AACA;;AAEA;;AAMQ;AACA;AACA;AACA;AACA;AAOR;AACA;AACA;AACA;;AAIA;AACA;;;;AAGkDC;AAAsB;AAIxE;AACA;;;AAGE;AACEC;AACF;AACF;;AAEA;;AAIA;AAoBI;;AAEA;AACA;;AAMA;AACAH;;;;;AAKAG;;AAKJC;;AAEI;AACA;AACA;;AAEF;AACF;;AAESA;;AACX;;","debugId":"9a370935-692f-4b6a-aa5d-62d09bae0929"}
@@ -17,7 +17,7 @@ function getArboristPackagePath() {
17
17
  const pkgName = '@npmcli/arborist';
18
18
  const mainPathWithForwardSlashes = path$1.normalizePath(utils.getNpmRequire().resolve(pkgName));
19
19
  const arboristPkgPathWithForwardSlashes = mainPathWithForwardSlashes.slice(0, mainPathWithForwardSlashes.lastIndexOf(pkgName) + pkgName.length);
20
- _arboristPkgPath = constants.WIN32 ? path.normalize(arboristPkgPathWithForwardSlashes) : arboristPkgPathWithForwardSlashes;
20
+ _arboristPkgPath = constants.default.WIN32 ? path.normalize(arboristPkgPathWithForwardSlashes) : arboristPkgPathWithForwardSlashes;
21
21
  }
22
22
  return _arboristPkgPath;
23
23
  }
@@ -95,7 +95,7 @@ function getDetailsFromDiff(diff, options) {
95
95
  }
96
96
  const {
97
97
  NPM_REGISTRY_URL
98
- } = constants;
98
+ } = constants.default;
99
99
  const filterConfig = utils.toFilterConfig({
100
100
  existing: false,
101
101
  unknownOrigin: true,
@@ -107,7 +107,7 @@ function getDetailsFromDiff(diff, options) {
107
107
  length: queueLength
108
108
  } = queue;
109
109
  while (pos < queueLength) {
110
- if (pos === constants.LOOP_SENTINEL) {
110
+ if (pos === constants.default.LOOP_SENTINEL) {
111
111
  throw new Error('Detected infinite loop while walking Arborist diff');
112
112
  }
113
113
  const currDiff = queue[pos++];
@@ -173,7 +173,7 @@ const {
173
173
  [kInternalsSymbol]: {
174
174
  getIpc
175
175
  }
176
- } = constants;
176
+ } = constants.default;
177
177
  const SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES = {
178
178
  __proto__: null,
179
179
  audit: false,
@@ -221,7 +221,7 @@ class SafeArborist extends Arborist {
221
221
  ...(args.length ? args[0] : undefined)
222
222
  };
223
223
  const ipc = await getIpc();
224
- const binName = ipc[constants.SOCKET_CLI_SHADOW_BIN];
224
+ const binName = ipc[constants.default.SOCKET_CLI_SHADOW_BIN];
225
225
  if (!binName) {
226
226
  return await this[kRiskyReify](...args);
227
227
  }
@@ -232,15 +232,15 @@ class SafeArborist extends Arborist {
232
232
  },
233
233
  // @ts-ignore: TypeScript gets grumpy about rest parameters.
234
234
  ...args.slice(1));
235
- const shadowAcceptRisks = !!ipc[constants.SOCKET_CLI_SHADOW_ACCEPT_RISKS];
236
- const shadowProgress = !!ipc[constants.SOCKET_CLI_SHADOW_PROGRESS];
237
- const shadowSilent = !!ipc[constants.SOCKET_CLI_SHADOW_SILENT];
238
- const acceptRisks = shadowAcceptRisks || constants.ENV.SOCKET_CLI_ACCEPT_RISKS;
235
+ const shadowAcceptRisks = !!ipc[constants.default.SOCKET_CLI_SHADOW_ACCEPT_RISKS];
236
+ const shadowProgress = !!ipc[constants.default.SOCKET_CLI_SHADOW_PROGRESS];
237
+ const shadowSilent = !!ipc[constants.default.SOCKET_CLI_SHADOW_SILENT];
238
+ const acceptRisks = shadowAcceptRisks || constants.default.ENV.SOCKET_CLI_ACCEPT_RISKS;
239
239
  const reportOnlyBlocking = acceptRisks || options.dryRun || options['yes'];
240
240
  const silent = !!options['silent'];
241
- const spinner = silent || !shadowProgress ? undefined : constants.spinner;
242
- const isShadowNpx = binName === 'npx';
243
- const hasExisting = await utils.findUp('node_modules', {
241
+ const spinner = silent || !shadowProgress ? undefined : constants.default.spinner;
242
+ const isShadowNpx = binName === constants.NPX;
243
+ const hasExisting = await utils.findUp(constants.NODE_MODULES, {
244
244
  cwd: process.cwd(),
245
245
  onlyDirectories: true
246
246
  });
@@ -251,7 +251,7 @@ class SafeArborist extends Arborist {
251
251
  }
252
252
  });
253
253
  const alertsMap = await getAlertsMapFromArborist(this, needInfoOn, {
254
- apiToken: ipc[constants.SOCKET_CLI_SHADOW_API_TOKEN],
254
+ apiToken: ipc[constants.default.SOCKET_CLI_SHADOW_API_TOKEN],
255
255
  spinner,
256
256
  filter: reportOnlyBlocking ? {
257
257
  actions: ['error'],
@@ -264,13 +264,13 @@ class SafeArborist extends Arborist {
264
264
  });
265
265
  if (alertsMap.size) {
266
266
  process.exitCode = 1;
267
- const viewAllRisks = constants.ENV.SOCKET_CLI_VIEW_ALL_RISKS;
267
+ const viewAllRisks = constants.default.ENV.SOCKET_CLI_VIEW_ALL_RISKS;
268
268
  utils.logAlertsMap(alertsMap, {
269
269
  hideAt: viewAllRisks ? 'none' : 'middle',
270
270
  output: process.stderr
271
271
  });
272
272
  throw new Error(`
273
- Socket ${binName} exiting due to risks.${viewAllRisks ? '' : `\nView all risks - Rerun with environment variable ${constants.SOCKET_CLI_VIEW_ALL_RISKS}=1.`}${acceptRisks ? '' : `\nAccept risks - Rerun with environment variable ${constants.SOCKET_CLI_ACCEPT_RISKS}=1.`}
273
+ Socket ${binName} exiting due to risks.${viewAllRisks ? '' : `\nView all risks - Rerun with environment variable ${constants.default.SOCKET_CLI_VIEW_ALL_RISKS}=1.`}${acceptRisks ? '' : `\nAccept risks - Rerun with environment variable ${constants.default.SOCKET_CLI_ACCEPT_RISKS}=1.`}
274
274
  `.trim());
275
275
  } else if (!silent && !shadowSilent) {
276
276
  logger.logger.success(`Socket ${binName} ${acceptRisks ? 'accepted' : 'found no'}${hasExisting ? ' new' : ''} risks`);
@@ -305,5 +305,5 @@ function installSafeArborist() {
305
305
  }
306
306
 
307
307
  installSafeArborist();
308
- //# debugId=cb5f5a9e-09b4-4668-be84-c67c918a6432
308
+ //# debugId=b33002f6-cafc-4095-a7ed-0703c935057c
309
309
  //# sourceMappingURL=shadow-npm-inject.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-npm-inject.js","sources":["../src/shadow/npm/paths.mts","../src/shadow/npm/arborist/types.mts","../src/shadow/npm/arborist-helpers.mts","../src/shadow/npm/arborist/lib/arborist/index.mts","../src/shadow/npm/arborist/index.mts","../src/shadow/npm/inject.mts"],"sourcesContent":["import path from 'node:path'\n\nimport { normalizePath } from '@socketsecurity/registry/lib/path'\n\nimport constants from '../../constants.mts'\nimport { getNpmRequire } from '../../utils/npm-paths.mts'\n\nlet _arboristPkgPath: string | undefined\nexport function getArboristPackagePath() {\n if (_arboristPkgPath === undefined) {\n const pkgName = '@npmcli/arborist'\n const mainPathWithForwardSlashes = normalizePath(\n getNpmRequire().resolve(pkgName),\n )\n const arboristPkgPathWithForwardSlashes = mainPathWithForwardSlashes.slice(\n 0,\n mainPathWithForwardSlashes.lastIndexOf(pkgName) + pkgName.length,\n )\n _arboristPkgPath = constants.WIN32\n ? path.normalize(arboristPkgPathWithForwardSlashes)\n : arboristPkgPathWithForwardSlashes\n }\n return _arboristPkgPath\n}\n\nlet _arboristClassPath: string | undefined\nexport function getArboristClassPath() {\n if (_arboristClassPath === undefined) {\n _arboristClassPath = path.join(\n getArboristPackagePath(),\n 'lib/arborist/index.js',\n )\n }\n return _arboristClassPath\n}\n\nlet _arboristEdgeClassPath: string | undefined\nexport function getArboristEdgeClassPath() {\n if (_arboristEdgeClassPath === undefined) {\n _arboristEdgeClassPath = path.join(getArboristPackagePath(), 'lib/edge.js')\n }\n return _arboristEdgeClassPath\n}\n\nlet _arboristNodeClassPath: string | undefined\nexport function getArboristNodeClassPath() {\n if (_arboristNodeClassPath === undefined) {\n _arboristNodeClassPath = path.join(getArboristPackagePath(), 'lib/node.js')\n }\n return _arboristNodeClassPath\n}\n\nlet _arboristOverrideSetClassPath: string | undefined\nexport function getArboristOverrideSetClassPath() {\n if (_arboristOverrideSetClassPath === undefined) {\n _arboristOverrideSetClassPath = path.join(\n getArboristPackagePath(),\n 'lib/override-set.js',\n )\n }\n return _arboristOverrideSetClassPath\n}\n","import { createEnum } from '../../../utils/objects.mts'\n\nimport type {\n Advisory as BaseAdvisory,\n Arborist as BaseArborist,\n Options as BaseArboristOptions,\n AuditReport as BaseAuditReport,\n Diff as BaseDiff,\n Edge as BaseEdge,\n Node as BaseNode,\n BaseOverrideSet,\n BuildIdealTreeOptions,\n ReifyOptions,\n} from '@npmcli/arborist'\n\nexport type ArboristOptions = BaseArboristOptions & {\n npmCommand?: string\n npmVersion?: string\n}\n\nexport type ArboristClass = ArboristInstance & {\n new (...args: any): ArboristInstance\n}\n\nexport type ArboristInstance = Omit<\n typeof BaseArborist,\n | 'actualTree'\n | 'auditReport'\n | 'buildIdealTree'\n | 'diff'\n | 'idealTree'\n | 'loadActual'\n | 'loadVirtual'\n | 'reify'\n> & {\n auditReport?: AuditReportInstance | null | undefined\n actualTree?: NodeClass | null | undefined\n diff: Diff | null\n idealTree?: NodeClass | null | undefined\n buildIdealTree(options?: BuildIdealTreeOptions): Promise<NodeClass>\n loadActual(options?: ArboristOptions): Promise<NodeClass>\n loadVirtual(options?: ArboristOptions): Promise<NodeClass>\n reify(options?: ArboristReifyOptions): Promise<NodeClass>\n}\n\nexport type ArboristReifyOptions = ReifyOptions & ArboristOptions\n\nexport type AuditAdvisory = Omit<BaseAdvisory, 'id'> & {\n id: number\n cwe: string[]\n cvss: {\n score: number\n vectorString: string\n }\n vulnerable_versions: string\n}\n\nexport type AuditReportInstance = Omit<BaseAuditReport, 'report'> & {\n report: { [dependency: string]: AuditAdvisory[] }\n}\n\nexport const DiffAction = createEnum({\n add: 'ADD',\n change: 'CHANGE',\n remove: 'REMOVE',\n})\n\nexport type Diff = Omit<\n BaseDiff,\n | 'actual'\n | 'children'\n | 'filterSet'\n | 'ideal'\n | 'leaves'\n | 'removed'\n | 'shrinkwrapInflated'\n | 'unchanged'\n> & {\n actual: NodeClass\n children: Diff[]\n filterSet: Set<NodeClass>\n ideal: NodeClass\n leaves: NodeClass[]\n parent: Diff | null\n removed: NodeClass[]\n shrinkwrapInflated: Set<NodeClass>\n unchanged: NodeClass[]\n}\n\nexport type EdgeClass = Omit<\n BaseEdge,\n | 'accept'\n | 'detach'\n | 'optional'\n | 'overrides'\n | 'peer'\n | 'peerConflicted'\n | 'rawSpec'\n | 'reload'\n | 'satisfiedBy'\n | 'spec'\n | 'to'\n> & {\n optional: boolean\n overrides: OverrideSetClass | undefined\n peer: boolean\n peerConflicted: boolean\n rawSpec: string\n get accept(): string | undefined\n get spec(): string\n get to(): NodeClass | null\n new (...args: any): EdgeClass\n detach(): void\n reload(hard?: boolean): void\n satisfiedBy(node: NodeClass): boolean\n}\n\nexport type LinkClass = Omit<NodeClass, 'isLink'> & {\n readonly isLink: true\n}\n\nexport type NodeClass = Omit<\n BaseNode,\n | 'addEdgeIn'\n | 'addEdgeOut'\n | 'canDedupe'\n | 'canReplace'\n | 'canReplaceWith'\n | 'children'\n | 'deleteEdgeIn'\n | 'edgesIn'\n | 'edgesOut'\n | 'from'\n | 'hasShrinkwrap'\n | 'inDepBundle'\n | 'inShrinkwrap'\n | 'integrity'\n | 'isTop'\n | 'matches'\n | 'meta'\n | 'name'\n | 'overrides'\n | 'packageName'\n | 'parent'\n | 'recalculateOutEdgesOverrides'\n | 'resolve'\n | 'resolveParent'\n | 'root'\n | 'target'\n | 'updateOverridesEdgeInAdded'\n | 'updateOverridesEdgeInRemoved'\n | 'version'\n | 'versions'\n> & {\n name: string\n version: string\n children: Map<string, NodeClass | LinkClass>\n edgesIn: Set<EdgeClass>\n edgesOut: Map<string, EdgeClass>\n from: NodeClass | null\n hasShrinkwrap: boolean\n inShrinkwrap: boolean | undefined\n integrity?: string | null\n isTop: boolean | undefined\n meta: BaseNode['meta'] & {\n addEdge(edge: EdgeClass): void\n }\n overrides: OverrideSetClass | undefined\n target: NodeClass\n versions: string[]\n get inDepBundle(): boolean\n get packageName(): string | null\n get parent(): NodeClass | null\n set parent(value: NodeClass | null)\n get resolveParent(): NodeClass | null\n get root(): NodeClass | null\n set root(value: NodeClass | null)\n new (...args: any): NodeClass\n addEdgeIn(edge: EdgeClass): void\n addEdgeOut(edge: EdgeClass): void\n canDedupe(preferDedupe?: boolean): boolean\n canReplace(node: NodeClass, ignorePeers?: string[]): boolean\n canReplaceWith(node: NodeClass, ignorePeers?: string[]): boolean\n deleteEdgeIn(edge: EdgeClass): void\n matches(node: NodeClass): boolean\n recalculateOutEdgesOverrides(): void\n resolve(name: string): NodeClass\n updateOverridesEdgeInAdded(\n otherOverrideSet: OverrideSetClass | undefined,\n ): boolean\n updateOverridesEdgeInRemoved(otherOverrideSet: OverrideSetClass): boolean\n}\n\nexport interface OverrideSetClass\n extends Omit<\n BaseOverrideSet,\n | 'ancestry'\n | 'children'\n | 'getEdgeRule'\n | 'getMatchingRule'\n | 'getNodeRule'\n | 'parent'\n | 'ruleset'\n > {\n children: Map<string, OverrideSetClass>\n key: string | undefined\n keySpec: string | undefined\n name: string | undefined\n parent: OverrideSetClass | undefined\n value: string | undefined\n version: string | undefined\n // eslint-disable-next-line @typescript-eslint/no-misused-new\n new (...args: any[]): OverrideSetClass\n get isRoot(): boolean\n get ruleset(): Map<string, OverrideSetClass>\n ancestry(): Generator<OverrideSetClass>\n childrenAreEqual(otherOverrideSet: OverrideSetClass | undefined): boolean\n getEdgeRule(edge: EdgeClass): OverrideSetClass\n getMatchingRule(node: NodeClass): OverrideSetClass | null\n getNodeRule(node: NodeClass): OverrideSetClass\n isEqual(otherOverrideSet: OverrideSetClass | undefined): boolean\n}\n","import semver from 'semver'\n\nimport { PackageURL } from '@socketregistry/packageurl-js'\nimport { getManifestData } from '@socketsecurity/registry'\nimport { debugFn } from '@socketsecurity/registry/lib/debug'\nimport { getOwn, hasOwn } from '@socketsecurity/registry/lib/objects'\nimport { fetchPackagePackument } from '@socketsecurity/registry/lib/packages'\n\nimport constants from '../../constants.mts'\nimport { Edge } from './arborist/index.mts'\nimport { DiffAction } from './arborist/types.mts'\nimport { getAlertsMapFromPurls } from '../../utils/alerts-map.mts'\nimport { toFilterConfig } from '../../utils/filter-config.mts'\nimport { npa } from '../../utils/npm-package-arg.mts'\nimport { applyRange, getMajor, getMinVersion } from '../../utils/semver.mts'\nimport { idToNpmPurl } from '../../utils/spec.mts'\n\nimport type {\n ArboristInstance,\n Diff,\n EdgeClass,\n LinkClass,\n NodeClass,\n} from './arborist/types.mts'\nimport type { AliasResult } from '../../utils/npm-package-arg.mts'\nimport type { RangeStyle } from '../../utils/semver.mts'\nimport type {\n AlertFilter,\n AlertsByPurl,\n} from '../../utils/socket-package-alert.mts'\nimport type { EditablePackageJson } from '@socketsecurity/registry/lib/packages'\nimport type { Spinner } from '@socketsecurity/registry/lib/spinner'\n\nfunction getUrlOrigin(input: string): string {\n try {\n // TODO: URL.parse is available in Node 22.1.0. We can use it when we drop Node 18.\n // https://nodejs.org/docs/latest-v22.x/api/url.html#urlparseinput-base\n // return URL.parse(input)?.origin ?? ''\n return new URL(input).origin ?? ''\n } catch {}\n return ''\n}\n\nexport type BestPatchVersionOptions = {\n minSatisfying?: boolean | undefined\n vulnerableVersionRange?: string | undefined\n}\n\nexport function findBestPatchVersion(\n node: NodeClass,\n availableVersions: string[],\n options?: BestPatchVersionOptions | undefined,\n): string | null {\n const { minSatisfying = false, vulnerableVersionRange } = {\n __proto__: null,\n ...options,\n } as BestPatchVersionOptions\n const manifestData = getManifestData('npm', node.name)\n let eligibleVersions\n if (manifestData && manifestData.name === manifestData.package) {\n const major = getMajor(manifestData.version)\n if (typeof major !== 'number') {\n return null\n }\n eligibleVersions = availableVersions.filter(v => getMajor(v) === major)\n } else {\n const major = getMajor(node.version)\n if (typeof major !== 'number') {\n return null\n }\n eligibleVersions = availableVersions.filter(\n v =>\n // Filter for versions that are within the current major version and\n // are NOT in the vulnerable range.\n getMajor(v) === major &&\n (!vulnerableVersionRange ||\n !semver.satisfies(v, vulnerableVersionRange)),\n )\n }\n if (eligibleVersions) {\n const satisfying = minSatisfying\n ? semver.minSatisfying\n : semver.maxSatisfying\n return satisfying(eligibleVersions, '*')\n }\n return null\n}\n\nexport function findPackageNode(\n tree: NodeClass,\n name: string,\n version?: string | undefined,\n): NodeClass | undefined {\n const queue: Array<NodeClass | LinkClass> = [tree]\n const visited = new Set<NodeClass>()\n let sentinel = 0\n while (queue.length) {\n if (sentinel++ === constants.LOOP_SENTINEL) {\n throw new Error('Detected infinite loop in findPackageNode')\n }\n const nodeOrLink = queue.pop()!\n const node = getTargetNode(nodeOrLink)\n if (visited.has(node)) {\n continue\n }\n visited.add(node)\n if (\n node.name === name &&\n (typeof version !== 'string' || node.version === version)\n ) {\n return node\n }\n for (const child of node.children.values()) {\n queue.push(child)\n }\n for (const edge of node.edgesOut.values()) {\n const { to } = edge\n if (to) {\n queue.push(to)\n }\n }\n }\n return undefined\n}\n\nexport function findPackageNodes(\n tree: NodeClass,\n name: string,\n version?: string | undefined,\n): NodeClass[] {\n const matches: NodeClass[] = []\n const queue: Array<NodeClass | LinkClass> = [tree]\n const visited = new Set<NodeClass>()\n let sentinel = 0\n while (queue.length) {\n if (sentinel++ === constants.LOOP_SENTINEL) {\n throw new Error('Detected infinite loop in findPackageNodes')\n }\n const nodeOrLink = queue.pop()!\n const node = getTargetNode(nodeOrLink)\n if (visited.has(node)) {\n continue\n }\n visited.add(node)\n\n const { version: targetVersion } = node\n if (!targetVersion && Array.isArray(node.errors) && node.errors.length) {\n debugFn(\n 'notice',\n `miss: version for ${node.name} due to errors:\\n`,\n node.errors,\n )\n }\n if (\n node.name === name &&\n (typeof version !== 'string' || node.version === version)\n ) {\n matches.push(node)\n }\n for (const child of node.children.values()) {\n queue.push(child)\n }\n for (const edge of node.edgesOut.values()) {\n const { to } = edge\n if (to) {\n queue.push(to)\n }\n }\n }\n return matches\n}\n\nexport type GetAlertsMapFromArboristOptions = {\n apiToken?: string | undefined\n consolidate?: boolean | undefined\n filter?: AlertFilter | undefined\n nothrow?: boolean | undefined\n spinner?: Spinner | undefined\n}\n\nexport async function getAlertsMapFromArborist(\n arb: ArboristInstance,\n needInfoOn: PackageDetail[],\n options?: GetAlertsMapFromArboristOptions | undefined,\n): Promise<AlertsByPurl> {\n const opts = {\n __proto__: null,\n consolidate: false,\n nothrow: false,\n ...options,\n filter: toFilterConfig(getOwn(options, 'filter')),\n } as GetAlertsMapFromArboristOptions & { filter: AlertFilter }\n\n const purls = needInfoOn.map(d => idToNpmPurl(d.node.pkgid))\n\n let overrides: { [key: string]: string } | undefined\n const overridesMap = (\n arb.actualTree ??\n arb.idealTree ??\n (await arb.loadActual())\n )?.overrides?.children\n if (overridesMap) {\n overrides = Object.fromEntries(\n Array.from(overridesMap.entries()).map(([key, overrideSet]) => {\n return [key, overrideSet.value!]\n }),\n )\n }\n\n return await getAlertsMapFromPurls(purls, {\n overrides,\n ...opts,\n })\n}\n\nexport type DiffQueryFilter = {\n existing?: boolean | undefined\n unknownOrigin?: boolean | undefined\n}\n\nexport type DiffQueryOptions = {\n filter?: DiffQueryFilter | undefined\n}\n\nexport type PackageDetail = {\n node: NodeClass\n existing?: NodeClass | undefined\n}\n\nexport function getDetailsFromDiff(\n diff: Diff | null,\n options?: DiffQueryOptions | undefined,\n): PackageDetail[] {\n const details: PackageDetail[] = []\n // `diff` is `null` when `npm install --package-lock-only` is passed.\n if (!diff) {\n debugFn('notice', `miss: diff is ${diff}`)\n return details\n }\n\n const { NPM_REGISTRY_URL } = constants\n\n const filterConfig = toFilterConfig({\n existing: false,\n unknownOrigin: true,\n ...getOwn(options, 'filter'),\n }) as DiffQueryFilter\n\n const queue: Diff[] = [...diff.children]\n let pos = 0\n let { length: queueLength } = queue\n while (pos < queueLength) {\n if (pos === constants.LOOP_SENTINEL) {\n throw new Error('Detected infinite loop while walking Arborist diff')\n }\n const currDiff = queue[pos++]!\n const { action } = currDiff\n if (action) {\n // The `pkgNode`, i.e. the `ideal` node, will be `undefined` if the diff\n // action is 'REMOVE'\n // The `oldNode`, i.e. the `actual` node, will be `undefined` if the diff\n // action is 'ADD'.\n const { actual: oldNode, ideal: pkgNode } = currDiff\n let existing: NodeClass | undefined\n let keep = false\n if (action === DiffAction.change) {\n if (pkgNode?.package.version !== oldNode?.package.version) {\n keep = true\n if (\n oldNode?.package.name &&\n oldNode.package.name === pkgNode?.package.name\n ) {\n existing = oldNode\n }\n }\n } else {\n keep = action !== DiffAction.remove\n }\n if (keep && pkgNode?.resolved && (!oldNode || oldNode.resolved)) {\n if (\n filterConfig.unknownOrigin ||\n getUrlOrigin(pkgNode.resolved) === NPM_REGISTRY_URL\n ) {\n details.push({\n node: pkgNode,\n existing,\n })\n }\n }\n }\n for (const child of currDiff.children) {\n queue[queueLength++] = child\n }\n }\n if (filterConfig.existing) {\n const { unchanged } = diff\n for (let i = 0, { length } = unchanged; i < length; i += 1) {\n const pkgNode = unchanged[i]!\n if (\n filterConfig.unknownOrigin ||\n getUrlOrigin(pkgNode.resolved!) === NPM_REGISTRY_URL\n ) {\n details.push({\n node: pkgNode,\n existing: pkgNode,\n })\n }\n }\n }\n return details\n}\n\nexport function getTargetNode(nodeOrLink: NodeClass | LinkClass): NodeClass\nexport function getTargetNode<T>(nodeOrLink: T): NodeClass | null\nexport function getTargetNode(nodeOrLink: any): NodeClass | null {\n return nodeOrLink?.isLink ? nodeOrLink.target : (nodeOrLink ?? null)\n}\n\nexport function isTopLevel(tree: NodeClass, node: NodeClass): boolean {\n return getTargetNode(tree.children.get(node.name)) === node\n}\n\nexport type Packument = Exclude<\n Awaited<ReturnType<typeof fetchPackagePackument>>,\n null\n>\n\nexport function updateNode(\n node: NodeClass,\n newVersion: string,\n newVersionPackument: Packument['versions'][number],\n): void {\n // Object.defineProperty is needed to set the version property and replace\n // the old value with newVersion.\n Object.defineProperty(node, 'version', {\n configurable: true,\n enumerable: true,\n get: () => newVersion,\n })\n // Update package.version associated with the node.\n node.package.version = newVersion\n // Update node.resolved.\n const purlObj = PackageURL.fromString(idToNpmPurl(node.name))\n node.resolved = `${constants.NPM_REGISTRY_URL}/${node.name}/-/${purlObj.name}-${newVersion}.tgz`\n // Update node.integrity with the targetPackument.dist.integrity value if available\n // else delete node.integrity so a new value is resolved for the target version.\n const { integrity } = newVersionPackument.dist\n if (integrity) {\n node.integrity = integrity\n } else {\n delete node.integrity\n }\n // Update node.package.deprecated based on targetPackument.deprecated.\n if (hasOwn(newVersionPackument, 'deprecated')) {\n node.package['deprecated'] = newVersionPackument.deprecated as string\n } else {\n delete node.package['deprecated']\n }\n // Update node.package.dependencies.\n const newDeps = { ...newVersionPackument.dependencies }\n const { dependencies: oldDeps } = node.package\n node.package.dependencies = newDeps\n if (oldDeps) {\n for (const oldDepName of Object.keys(oldDeps)) {\n if (!hasOwn(newDeps, oldDepName)) {\n // Detach old edges for dependencies that don't exist on the updated\n // node.package.dependencies.\n node.edgesOut.get(oldDepName)?.detach()\n }\n }\n }\n for (const newDepName of Object.keys(newDeps)) {\n if (!hasOwn(oldDeps, newDepName)) {\n // Add new edges for dependencies that don't exist on the old\n // node.package.dependencies.\n node.addEdgeOut(\n new Edge({\n from: node,\n name: newDepName,\n spec: newDeps[newDepName],\n type: 'prod',\n }) as unknown as EdgeClass,\n )\n }\n }\n}\n\nexport function updatePackageJsonFromNode(\n editablePkgJson: EditablePackageJson,\n tree: NodeClass,\n node: NodeClass,\n newVersion: string,\n rangeStyle?: RangeStyle | undefined,\n): boolean {\n let result = false\n if (!isTopLevel(tree, node)) {\n return result\n }\n const { name } = node\n for (const depField of [\n 'dependencies',\n 'optionalDependencies',\n 'peerDependencies',\n ]) {\n const depObject = editablePkgJson.content[depField] as\n | { [key: string]: string }\n | undefined\n const depValue = hasOwn(depObject, name) ? depObject[name] : undefined\n if (typeof depValue !== 'string' || depValue.startsWith('catalog:')) {\n continue\n }\n let oldRange = depValue\n // Use npa if depValue looks like more than just a semver range.\n if (depValue.includes(':')) {\n const npaResult = npa(depValue)\n if (!npaResult || (npaResult as AliasResult).subSpec) {\n continue\n }\n oldRange = npaResult.rawSpec\n }\n const oldMin = getMinVersion(oldRange)\n const newRange =\n oldMin &&\n // Ensure we're on the same major version...\n getMajor(newVersion) === oldMin.major &&\n // and not a downgrade.\n semver.gte(newVersion, oldMin.version)\n ? applyRange(oldRange, newVersion, rangeStyle)\n : oldRange\n if (oldRange !== newRange) {\n result = true\n editablePkgJson.update({\n [depField]: {\n ...depObject,\n [name]: newRange,\n },\n })\n }\n }\n return result\n}\n","// @ts-ignore\nimport UntypedArborist from '@npmcli/arborist/lib/arborist/index.js'\n\nimport { logger } from '@socketsecurity/registry/lib/logger'\n\nimport constants from '../../../../../constants.mts'\nimport { findUp } from '../../../../../utils/fs.mts'\nimport { logAlertsMap } from '../../../../../utils/socket-package-alert.mts'\nimport {\n getAlertsMapFromArborist,\n getDetailsFromDiff,\n} from '../../../arborist-helpers.mts'\n\nimport type {\n ArboristClass,\n ArboristReifyOptions,\n NodeClass,\n} from '../../types.mts'\n\nconst {\n kInternalsSymbol,\n [kInternalsSymbol as unknown as 'Symbol(kInternalsSymbol)']: { getIpc },\n} = constants\n\nexport const SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES = {\n __proto__: null,\n audit: false,\n dryRun: true,\n fund: false,\n ignoreScripts: true,\n progress: false,\n save: false,\n saveBundle: false,\n silent: true,\n}\n\nexport const SAFE_WITH_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES = {\n // @ts-ignore\n __proto__: null,\n ...SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES,\n dryRun: false,\n save: true,\n}\n\nexport const kCtorArgs = Symbol('ctorArgs')\n\nexport const kRiskyReify = Symbol('riskyReify')\n\nexport const Arborist: ArboristClass = UntypedArborist\n\n// Implementation code not related to our custom behavior is based on\n// https://github.com/npm/cli/blob/v11.0.0/workspaces/arborist/lib/arborist/index.js:\nexport class SafeArborist extends Arborist {\n constructor(...ctorArgs: ConstructorParameters<ArboristClass>) {\n super(\n {\n path:\n (ctorArgs.length ? ctorArgs[0]?.path : undefined) ?? process.cwd(),\n ...(ctorArgs.length ? ctorArgs[0] : undefined),\n ...SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES,\n },\n ...ctorArgs.slice(1),\n )\n ;(this as any)[kCtorArgs] = ctorArgs\n }\n\n async [kRiskyReify](\n ...args: Parameters<InstanceType<ArboristClass>['reify']>\n ): Promise<NodeClass> {\n const ctorArgs = (this as any)[kCtorArgs]\n const arb = new Arborist(\n {\n ...(ctorArgs.length ? ctorArgs[0] : undefined),\n progress: false,\n },\n ...ctorArgs.slice(1),\n )\n const ret = await (arb.reify as (...args: any[]) => Promise<NodeClass>)(\n {\n ...(args.length ? args[0] : undefined),\n progress: false,\n },\n ...args.slice(1),\n )\n Object.assign(this, arb)\n return ret\n }\n\n // @ts-ignore Incorrectly typed.\n override async reify(\n this: SafeArborist,\n ...args: Parameters<InstanceType<ArboristClass>['reify']>\n ): Promise<NodeClass> {\n const options = {\n __proto__: null,\n ...(args.length ? args[0] : undefined),\n } as ArboristReifyOptions\n\n const ipc = await getIpc()\n\n const binName = ipc[constants.SOCKET_CLI_SHADOW_BIN]\n if (!binName) {\n return await this[kRiskyReify](...args)\n }\n\n await super.reify(\n {\n ...options,\n ...SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES,\n progress: false,\n },\n // @ts-ignore: TypeScript gets grumpy about rest parameters.\n ...args.slice(1),\n )\n\n const shadowAcceptRisks = !!ipc[constants.SOCKET_CLI_SHADOW_ACCEPT_RISKS]\n const shadowProgress = !!ipc[constants.SOCKET_CLI_SHADOW_PROGRESS]\n const shadowSilent = !!ipc[constants.SOCKET_CLI_SHADOW_SILENT]\n\n const acceptRisks =\n shadowAcceptRisks || constants.ENV.SOCKET_CLI_ACCEPT_RISKS\n const reportOnlyBlocking = acceptRisks || options.dryRun || options['yes']\n const silent = !!options['silent']\n const spinner = silent || !shadowProgress ? undefined : constants.spinner\n\n const isShadowNpx = binName === 'npx'\n const hasExisting = await findUp('node_modules', {\n cwd: process.cwd(),\n onlyDirectories: true,\n })\n const shouldCheckExisting = reportOnlyBlocking ? true : isShadowNpx\n\n const needInfoOn = getDetailsFromDiff(this.diff, {\n filter: {\n existing: shouldCheckExisting,\n },\n })\n\n const alertsMap = await getAlertsMapFromArborist(this, needInfoOn, {\n apiToken: ipc[constants.SOCKET_CLI_SHADOW_API_TOKEN],\n spinner,\n filter: reportOnlyBlocking\n ? {\n actions: ['error'],\n blocked: true,\n existing: shouldCheckExisting,\n }\n : {\n actions: ['error', 'monitor', 'warn'],\n existing: shouldCheckExisting,\n },\n })\n\n if (alertsMap.size) {\n process.exitCode = 1\n const viewAllRisks = constants.ENV.SOCKET_CLI_VIEW_ALL_RISKS\n logAlertsMap(alertsMap, {\n hideAt: viewAllRisks ? 'none' : 'middle',\n output: process.stderr,\n })\n throw new Error(\n `\n Socket ${binName} exiting due to risks.${\n viewAllRisks\n ? ''\n : `\\nView all risks - Rerun with environment variable ${constants.SOCKET_CLI_VIEW_ALL_RISKS}=1.`\n }${\n acceptRisks\n ? ''\n : `\\nAccept risks - Rerun with environment variable ${constants.SOCKET_CLI_ACCEPT_RISKS}=1.`\n }\n `.trim(),\n )\n } else if (!silent && !shadowSilent) {\n logger.success(\n `Socket ${binName} ${acceptRisks ? 'accepted' : 'found no'}${hasExisting ? ' new' : ''} risks`,\n )\n if (isShadowNpx) {\n logger.log(`Running ${options.add![0]}`)\n }\n }\n\n return await this[kRiskyReify](...args)\n }\n}\n","import { createRequire } from 'node:module'\n\n// @ts-ignore\nimport UntypedEdge from '@npmcli/arborist/lib/edge.js'\n// @ts-ignore\nimport UntypedNode from '@npmcli/arborist/lib/node.js'\n// @ts-ignore\nimport UntypedOverrideSet from '@npmcli/arborist/lib/override-set.js'\n\nimport {\n getArboristClassPath,\n getArboristEdgeClassPath,\n getArboristNodeClassPath,\n getArboristOverrideSetClassPath,\n} from '../paths.mts'\nimport { Arborist, SafeArborist } from './lib/arborist/index.mts'\n\nimport type { EdgeClass, NodeClass, OverrideSetClass } from './types.mts'\n\nconst require = createRequire(import.meta.url)\n\nexport { Arborist, SafeArborist }\n\nexport const Edge: EdgeClass = UntypedEdge\n\nexport const Node: NodeClass = UntypedNode\n\nexport const OverrideSet: OverrideSetClass = UntypedOverrideSet\n\nexport function installSafeArborist() {\n // Override '@npmcli/arborist' module exports with patched variants based on\n // https://github.com/npm/cli/pull/8089.\n const cache: { [key: string]: any } = require.cache\n cache[getArboristClassPath()] = { exports: SafeArborist }\n cache[getArboristEdgeClassPath()] = { exports: Edge }\n cache[getArboristNodeClassPath()] = { exports: Node }\n cache[getArboristOverrideSetClassPath()] = { exports: OverrideSet }\n}\n","import { installSafeArborist } from './arborist/index.mts'\n\ninstallSafeArborist()\n"],"names":["_arboristPkgPath","add","change","remove","__proto__","consolidate","nothrow","debugFn","NPM_REGISTRY_URL","existing","unknownOrigin","length","action","actual","ideal","keep","node","queue","unchanged","getIpc","audit","dryRun","fund","ignoreScripts","progress","save","saveBundle","silent","path","Object","cwd","onlyDirectories","filter","apiToken","blocked","actions","hideAt","logger","cache","exports","installSafeArborist"],"mappings":";;;;;;;;;;;;;AAOA;AACO;;;AAGH;AAGA;AAIAA;AAGF;AACA;AACF;AAEA;AACO;;;AAML;AACA;AACF;AAEA;AACO;;;AAGL;AACA;AACF;AAEA;AACO;;;AAGL;AACA;AACF;AAEA;AACO;;;AAML;AACA;AACF;;ACAO;AACLC;AACAC;AACAC;AACF;;AChCA;;AAEI;AACA;AACA;;;AAGF;AACF;AA2IO;AAKL;AACEC;AACAC;AACAC;AACA;;;AAIF;AAEA;;AAMA;;AAGM;AACF;AAEJ;AAEA;;;AAGA;AACF;AAgBO;;AAKL;;AAEEC;AACA;AACF;;AAEQC;AAAiB;;AAGvBC;AACAC;AACA;AACF;AAEA;;;AAEMC;AAAoB;;AAExB;AACE;AACF;AACA;;AACQC;AAAO;AACf;AACE;AACA;AACA;AACA;;AACQC;AAAiBC;AAAe;AACxC;;AAEA;;AAEIC;AACA;AAIEN;AACF;AACF;AACF;AACEM;AACF;AACA;AACE;;AAKIC;AACAP;AACF;AACF;AACF;AACF;AACA;AACEQ;AACF;AACF;;;AAEUC;AAAU;AAClB;AAAkBP;;AAChB;AACA;;AAKIK;AACAP;AACF;AACF;AACF;AACF;AACA;AACF;;ACtTA;AAmBA;;AAEE;AAA+DU;AAAO;AACxE;AAEO;AACLf;AACAgB;AACAC;AACAC;AACAC;AACAC;AACAC;AACAC;AACAC;AACF;AAUO;AAEA;AAEA;;AAEP;AACA;AACO;;AAEH;AAEIC;;;;AAOF;AACJ;AAEA;AAGE;AACA;;AAGIJ;;AAIJ;;AAGIA;;AAIJK;AACA;AACF;;AAEA;AACA;AAIE;AACEzB;;;AAIF;AAEA;;;AAGA;;AAII;AACA;AACAoB;;AAEF;AACA;;;;;;AAUF;;AAGA;AACA;AACEM;AACAC;AACF;AACA;AAEA;AACEC;AACEvB;AACF;AACF;;AAGEwB;;;;AAKMC;AACAzB;AACF;AAEE0B;AACA1B;AACF;AACN;;;AAIE;;AAEE2B;;AAEF;;AAGN;AAQA;AAGI;AACEC;AAGA;;AAEA;AACF;;AAGF;AACF;;ACrKA;AAIO;AAEA;AAEA;AAEA;AACL;AACA;AACA;AACAC;AAAkCC;;AAClCD;AAAsCC;;AACtCD;AAAsCC;;AACtCD;AAA6CC;;AAC/C;;ACnCAC","debugId":"cb5f5a9e-09b4-4668-be84-c67c918a6432"}
1
+ {"version":3,"file":"shadow-npm-inject.js","sources":["../src/shadow/npm/paths.mts","../src/shadow/npm/arborist/types.mts","../src/shadow/npm/arborist-helpers.mts","../src/shadow/npm/arborist/lib/arborist/index.mts","../src/shadow/npm/arborist/index.mts","../src/shadow/npm/inject.mts"],"sourcesContent":["import path from 'node:path'\n\nimport { normalizePath } from '@socketsecurity/registry/lib/path'\n\nimport constants from '../../constants.mts'\nimport { getNpmRequire } from '../../utils/npm-paths.mts'\n\nlet _arboristPkgPath: string | undefined\nexport function getArboristPackagePath() {\n if (_arboristPkgPath === undefined) {\n const pkgName = '@npmcli/arborist'\n const mainPathWithForwardSlashes = normalizePath(\n getNpmRequire().resolve(pkgName),\n )\n const arboristPkgPathWithForwardSlashes = mainPathWithForwardSlashes.slice(\n 0,\n mainPathWithForwardSlashes.lastIndexOf(pkgName) + pkgName.length,\n )\n _arboristPkgPath = constants.WIN32\n ? path.normalize(arboristPkgPathWithForwardSlashes)\n : arboristPkgPathWithForwardSlashes\n }\n return _arboristPkgPath\n}\n\nlet _arboristClassPath: string | undefined\nexport function getArboristClassPath() {\n if (_arboristClassPath === undefined) {\n _arboristClassPath = path.join(\n getArboristPackagePath(),\n 'lib/arborist/index.js',\n )\n }\n return _arboristClassPath\n}\n\nlet _arboristEdgeClassPath: string | undefined\nexport function getArboristEdgeClassPath() {\n if (_arboristEdgeClassPath === undefined) {\n _arboristEdgeClassPath = path.join(getArboristPackagePath(), 'lib/edge.js')\n }\n return _arboristEdgeClassPath\n}\n\nlet _arboristNodeClassPath: string | undefined\nexport function getArboristNodeClassPath() {\n if (_arboristNodeClassPath === undefined) {\n _arboristNodeClassPath = path.join(getArboristPackagePath(), 'lib/node.js')\n }\n return _arboristNodeClassPath\n}\n\nlet _arboristOverrideSetClassPath: string | undefined\nexport function getArboristOverrideSetClassPath() {\n if (_arboristOverrideSetClassPath === undefined) {\n _arboristOverrideSetClassPath = path.join(\n getArboristPackagePath(),\n 'lib/override-set.js',\n )\n }\n return _arboristOverrideSetClassPath\n}\n","import { createEnum } from '../../../utils/objects.mts'\n\nimport type {\n Advisory as BaseAdvisory,\n Arborist as BaseArborist,\n Options as BaseArboristOptions,\n AuditReport as BaseAuditReport,\n Diff as BaseDiff,\n Edge as BaseEdge,\n Node as BaseNode,\n BaseOverrideSet,\n BuildIdealTreeOptions,\n ReifyOptions,\n} from '@npmcli/arborist'\n\nexport type ArboristOptions = BaseArboristOptions & {\n npmCommand?: string\n npmVersion?: string\n}\n\nexport type ArboristClass = ArboristInstance & {\n new (...args: any): ArboristInstance\n}\n\nexport type ArboristInstance = Omit<\n typeof BaseArborist,\n | 'actualTree'\n | 'auditReport'\n | 'buildIdealTree'\n | 'diff'\n | 'idealTree'\n | 'loadActual'\n | 'loadVirtual'\n | 'reify'\n> & {\n auditReport?: AuditReportInstance | null | undefined\n actualTree?: NodeClass | null | undefined\n diff: Diff | null\n idealTree?: NodeClass | null | undefined\n buildIdealTree(options?: BuildIdealTreeOptions): Promise<NodeClass>\n loadActual(options?: ArboristOptions): Promise<NodeClass>\n loadVirtual(options?: ArboristOptions): Promise<NodeClass>\n reify(options?: ArboristReifyOptions): Promise<NodeClass>\n}\n\nexport type ArboristReifyOptions = ReifyOptions & ArboristOptions\n\nexport type AuditAdvisory = Omit<BaseAdvisory, 'id'> & {\n id: number\n cwe: string[]\n cvss: {\n score: number\n vectorString: string\n }\n vulnerable_versions: string\n}\n\nexport type AuditReportInstance = Omit<BaseAuditReport, 'report'> & {\n report: { [dependency: string]: AuditAdvisory[] }\n}\n\nexport const DiffAction = createEnum({\n add: 'ADD',\n change: 'CHANGE',\n remove: 'REMOVE',\n})\n\nexport type Diff = Omit<\n BaseDiff,\n | 'actual'\n | 'children'\n | 'filterSet'\n | 'ideal'\n | 'leaves'\n | 'removed'\n | 'shrinkwrapInflated'\n | 'unchanged'\n> & {\n actual: NodeClass\n children: Diff[]\n filterSet: Set<NodeClass>\n ideal: NodeClass\n leaves: NodeClass[]\n parent: Diff | null\n removed: NodeClass[]\n shrinkwrapInflated: Set<NodeClass>\n unchanged: NodeClass[]\n}\n\nexport type EdgeClass = Omit<\n BaseEdge,\n | 'accept'\n | 'detach'\n | 'optional'\n | 'overrides'\n | 'peer'\n | 'peerConflicted'\n | 'rawSpec'\n | 'reload'\n | 'satisfiedBy'\n | 'spec'\n | 'to'\n> & {\n optional: boolean\n overrides: OverrideSetClass | undefined\n peer: boolean\n peerConflicted: boolean\n rawSpec: string\n get accept(): string | undefined\n get spec(): string\n get to(): NodeClass | null\n new (...args: any): EdgeClass\n detach(): void\n reload(hard?: boolean): void\n satisfiedBy(node: NodeClass): boolean\n}\n\nexport type LinkClass = Omit<NodeClass, 'isLink'> & {\n readonly isLink: true\n}\n\nexport type NodeClass = Omit<\n BaseNode,\n | 'addEdgeIn'\n | 'addEdgeOut'\n | 'canDedupe'\n | 'canReplace'\n | 'canReplaceWith'\n | 'children'\n | 'deleteEdgeIn'\n | 'edgesIn'\n | 'edgesOut'\n | 'from'\n | 'hasShrinkwrap'\n | 'inDepBundle'\n | 'inShrinkwrap'\n | 'integrity'\n | 'isTop'\n | 'matches'\n | 'meta'\n | 'name'\n | 'overrides'\n | 'packageName'\n | 'parent'\n | 'recalculateOutEdgesOverrides'\n | 'resolve'\n | 'resolveParent'\n | 'root'\n | 'target'\n | 'updateOverridesEdgeInAdded'\n | 'updateOverridesEdgeInRemoved'\n | 'version'\n | 'versions'\n> & {\n name: string\n version: string\n children: Map<string, NodeClass | LinkClass>\n edgesIn: Set<EdgeClass>\n edgesOut: Map<string, EdgeClass>\n from: NodeClass | null\n hasShrinkwrap: boolean\n inShrinkwrap: boolean | undefined\n integrity?: string | null\n isTop: boolean | undefined\n meta: BaseNode['meta'] & {\n addEdge(edge: EdgeClass): void\n }\n overrides: OverrideSetClass | undefined\n target: NodeClass\n versions: string[]\n get inDepBundle(): boolean\n get packageName(): string | null\n get parent(): NodeClass | null\n set parent(value: NodeClass | null)\n get resolveParent(): NodeClass | null\n get root(): NodeClass | null\n set root(value: NodeClass | null)\n new (...args: any): NodeClass\n addEdgeIn(edge: EdgeClass): void\n addEdgeOut(edge: EdgeClass): void\n canDedupe(preferDedupe?: boolean): boolean\n canReplace(node: NodeClass, ignorePeers?: string[]): boolean\n canReplaceWith(node: NodeClass, ignorePeers?: string[]): boolean\n deleteEdgeIn(edge: EdgeClass): void\n matches(node: NodeClass): boolean\n recalculateOutEdgesOverrides(): void\n resolve(name: string): NodeClass\n updateOverridesEdgeInAdded(\n otherOverrideSet: OverrideSetClass | undefined,\n ): boolean\n updateOverridesEdgeInRemoved(otherOverrideSet: OverrideSetClass): boolean\n}\n\nexport interface OverrideSetClass\n extends Omit<\n BaseOverrideSet,\n | 'ancestry'\n | 'children'\n | 'getEdgeRule'\n | 'getMatchingRule'\n | 'getNodeRule'\n | 'parent'\n | 'ruleset'\n > {\n children: Map<string, OverrideSetClass>\n key: string | undefined\n keySpec: string | undefined\n name: string | undefined\n parent: OverrideSetClass | undefined\n value: string | undefined\n version: string | undefined\n // eslint-disable-next-line @typescript-eslint/no-misused-new\n new (...args: any[]): OverrideSetClass\n get isRoot(): boolean\n get ruleset(): Map<string, OverrideSetClass>\n ancestry(): Generator<OverrideSetClass>\n childrenAreEqual(otherOverrideSet: OverrideSetClass | undefined): boolean\n getEdgeRule(edge: EdgeClass): OverrideSetClass\n getMatchingRule(node: NodeClass): OverrideSetClass | null\n getNodeRule(node: NodeClass): OverrideSetClass\n isEqual(otherOverrideSet: OverrideSetClass | undefined): boolean\n}\n","import { debugFn } from '@socketsecurity/registry/lib/debug'\nimport { getOwn } from '@socketsecurity/registry/lib/objects'\n\nimport constants from '../../constants.mts'\nimport { DiffAction } from './arborist/types.mts'\nimport { getAlertsMapFromPurls } from '../../utils/alerts-map.mts'\nimport { toFilterConfig } from '../../utils/filter-config.mts'\nimport { idToNpmPurl } from '../../utils/spec.mts'\n\nimport type { ArboristInstance, Diff, NodeClass } from './arborist/types.mts'\nimport type {\n AlertFilter,\n AlertsByPurl,\n} from '../../utils/socket-package-alert.mts'\nimport type { Spinner } from '@socketsecurity/registry/lib/spinner'\n\nfunction getUrlOrigin(input: string): string {\n try {\n // TODO: URL.parse is available in Node 22.1.0. We can use it when we drop Node 18.\n // https://nodejs.org/docs/latest-v22.x/api/url.html#urlparseinput-base\n // return URL.parse(input)?.origin ?? ''\n return new URL(input).origin ?? ''\n } catch {}\n return ''\n}\n\nexport type GetAlertsMapFromArboristOptions = {\n apiToken?: string | undefined\n consolidate?: boolean | undefined\n filter?: AlertFilter | undefined\n nothrow?: boolean | undefined\n spinner?: Spinner | undefined\n}\n\nexport async function getAlertsMapFromArborist(\n arb: ArboristInstance,\n needInfoOn: PackageDetail[],\n options?: GetAlertsMapFromArboristOptions | undefined,\n): Promise<AlertsByPurl> {\n const opts = {\n __proto__: null,\n consolidate: false,\n nothrow: false,\n ...options,\n filter: toFilterConfig(getOwn(options, 'filter')),\n } as GetAlertsMapFromArboristOptions & { filter: AlertFilter }\n\n const purls = needInfoOn.map(d => idToNpmPurl(d.node.pkgid))\n\n let overrides: { [key: string]: string } | undefined\n const overridesMap = (\n arb.actualTree ??\n arb.idealTree ??\n (await arb.loadActual())\n )?.overrides?.children\n if (overridesMap) {\n overrides = Object.fromEntries(\n Array.from(overridesMap.entries()).map(([key, overrideSet]) => {\n return [key, overrideSet.value!]\n }),\n )\n }\n\n return await getAlertsMapFromPurls(purls, {\n overrides,\n ...opts,\n })\n}\n\nexport type DiffQueryFilter = {\n existing?: boolean | undefined\n unknownOrigin?: boolean | undefined\n}\n\nexport type DiffQueryOptions = {\n filter?: DiffQueryFilter | undefined\n}\n\nexport type PackageDetail = {\n node: NodeClass\n existing?: NodeClass | undefined\n}\n\nexport function getDetailsFromDiff(\n diff: Diff | null,\n options?: DiffQueryOptions | undefined,\n): PackageDetail[] {\n const details: PackageDetail[] = []\n // `diff` is `null` when `npm install --package-lock-only` is passed.\n if (!diff) {\n debugFn('notice', `miss: diff is ${diff}`)\n return details\n }\n\n const { NPM_REGISTRY_URL } = constants\n\n const filterConfig = toFilterConfig({\n existing: false,\n unknownOrigin: true,\n ...getOwn(options, 'filter'),\n }) as DiffQueryFilter\n\n const queue: Diff[] = [...diff.children]\n let pos = 0\n let { length: queueLength } = queue\n while (pos < queueLength) {\n if (pos === constants.LOOP_SENTINEL) {\n throw new Error('Detected infinite loop while walking Arborist diff')\n }\n const currDiff = queue[pos++]!\n const { action } = currDiff\n if (action) {\n // The `pkgNode`, i.e. the `ideal` node, will be `undefined` if the diff\n // action is 'REMOVE'\n // The `oldNode`, i.e. the `actual` node, will be `undefined` if the diff\n // action is 'ADD'.\n const { actual: oldNode, ideal: pkgNode } = currDiff\n let existing: NodeClass | undefined\n let keep = false\n if (action === DiffAction.change) {\n if (pkgNode?.package.version !== oldNode?.package.version) {\n keep = true\n if (\n oldNode?.package.name &&\n oldNode.package.name === pkgNode?.package.name\n ) {\n existing = oldNode\n }\n }\n } else {\n keep = action !== DiffAction.remove\n }\n if (keep && pkgNode?.resolved && (!oldNode || oldNode.resolved)) {\n if (\n filterConfig.unknownOrigin ||\n getUrlOrigin(pkgNode.resolved) === NPM_REGISTRY_URL\n ) {\n details.push({\n node: pkgNode,\n existing,\n })\n }\n }\n }\n for (const child of currDiff.children) {\n queue[queueLength++] = child\n }\n }\n if (filterConfig.existing) {\n const { unchanged } = diff\n for (let i = 0, { length } = unchanged; i < length; i += 1) {\n const pkgNode = unchanged[i]!\n if (\n filterConfig.unknownOrigin ||\n getUrlOrigin(pkgNode.resolved!) === NPM_REGISTRY_URL\n ) {\n details.push({\n node: pkgNode,\n existing: pkgNode,\n })\n }\n }\n }\n return details\n}\n","// @ts-ignore\nimport UntypedArborist from '@npmcli/arborist/lib/arborist/index.js'\n\nimport { logger } from '@socketsecurity/registry/lib/logger'\n\nimport constants, { NODE_MODULES, NPX } from '../../../../../constants.mts'\nimport { findUp } from '../../../../../utils/fs.mts'\nimport { logAlertsMap } from '../../../../../utils/socket-package-alert.mts'\nimport {\n getAlertsMapFromArborist,\n getDetailsFromDiff,\n} from '../../../arborist-helpers.mts'\n\nimport type {\n ArboristClass,\n ArboristReifyOptions,\n NodeClass,\n} from '../../types.mts'\n\nconst {\n kInternalsSymbol,\n [kInternalsSymbol as unknown as 'Symbol(kInternalsSymbol)']: { getIpc },\n} = constants\n\nexport const SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES = {\n __proto__: null,\n audit: false,\n dryRun: true,\n fund: false,\n ignoreScripts: true,\n progress: false,\n save: false,\n saveBundle: false,\n silent: true,\n}\n\nexport const SAFE_WITH_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES = {\n // @ts-ignore\n __proto__: null,\n ...SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES,\n dryRun: false,\n save: true,\n}\n\nexport const kCtorArgs = Symbol('ctorArgs')\n\nexport const kRiskyReify = Symbol('riskyReify')\n\nexport const Arborist: ArboristClass = UntypedArborist\n\n// Implementation code not related to our custom behavior is based on\n// https://github.com/npm/cli/blob/v11.0.0/workspaces/arborist/lib/arborist/index.js:\nexport class SafeArborist extends Arborist {\n constructor(...ctorArgs: ConstructorParameters<ArboristClass>) {\n super(\n {\n path:\n (ctorArgs.length ? ctorArgs[0]?.path : undefined) ?? process.cwd(),\n ...(ctorArgs.length ? ctorArgs[0] : undefined),\n ...SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES,\n },\n ...ctorArgs.slice(1),\n )\n ;(this as any)[kCtorArgs] = ctorArgs\n }\n\n async [kRiskyReify](\n ...args: Parameters<InstanceType<ArboristClass>['reify']>\n ): Promise<NodeClass> {\n const ctorArgs = (this as any)[kCtorArgs]\n const arb = new Arborist(\n {\n ...(ctorArgs.length ? ctorArgs[0] : undefined),\n progress: false,\n },\n ...ctorArgs.slice(1),\n )\n const ret = await (arb.reify as (...args: any[]) => Promise<NodeClass>)(\n {\n ...(args.length ? args[0] : undefined),\n progress: false,\n },\n ...args.slice(1),\n )\n Object.assign(this, arb)\n return ret\n }\n\n // @ts-ignore Incorrectly typed.\n override async reify(\n this: SafeArborist,\n ...args: Parameters<InstanceType<ArboristClass>['reify']>\n ): Promise<NodeClass> {\n const options = {\n __proto__: null,\n ...(args.length ? args[0] : undefined),\n } as ArboristReifyOptions\n\n const ipc = await getIpc()\n\n const binName = ipc[constants.SOCKET_CLI_SHADOW_BIN]\n if (!binName) {\n return await this[kRiskyReify](...args)\n }\n\n await super.reify(\n {\n ...options,\n ...SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES,\n progress: false,\n },\n // @ts-ignore: TypeScript gets grumpy about rest parameters.\n ...args.slice(1),\n )\n\n const shadowAcceptRisks = !!ipc[constants.SOCKET_CLI_SHADOW_ACCEPT_RISKS]\n const shadowProgress = !!ipc[constants.SOCKET_CLI_SHADOW_PROGRESS]\n const shadowSilent = !!ipc[constants.SOCKET_CLI_SHADOW_SILENT]\n\n const acceptRisks =\n shadowAcceptRisks || constants.ENV.SOCKET_CLI_ACCEPT_RISKS\n const reportOnlyBlocking = acceptRisks || options.dryRun || options['yes']\n const silent = !!options['silent']\n const spinner = silent || !shadowProgress ? undefined : constants.spinner\n\n const isShadowNpx = binName === NPX\n const hasExisting = await findUp(NODE_MODULES, {\n cwd: process.cwd(),\n onlyDirectories: true,\n })\n const shouldCheckExisting = reportOnlyBlocking ? true : isShadowNpx\n\n const needInfoOn = getDetailsFromDiff(this.diff, {\n filter: {\n existing: shouldCheckExisting,\n },\n })\n\n const alertsMap = await getAlertsMapFromArborist(this, needInfoOn, {\n apiToken: ipc[constants.SOCKET_CLI_SHADOW_API_TOKEN],\n spinner,\n filter: reportOnlyBlocking\n ? {\n actions: ['error'],\n blocked: true,\n existing: shouldCheckExisting,\n }\n : {\n actions: ['error', 'monitor', 'warn'],\n existing: shouldCheckExisting,\n },\n })\n\n if (alertsMap.size) {\n process.exitCode = 1\n const viewAllRisks = constants.ENV.SOCKET_CLI_VIEW_ALL_RISKS\n logAlertsMap(alertsMap, {\n hideAt: viewAllRisks ? 'none' : 'middle',\n output: process.stderr,\n })\n throw new Error(\n `\n Socket ${binName} exiting due to risks.${\n viewAllRisks\n ? ''\n : `\\nView all risks - Rerun with environment variable ${constants.SOCKET_CLI_VIEW_ALL_RISKS}=1.`\n }${\n acceptRisks\n ? ''\n : `\\nAccept risks - Rerun with environment variable ${constants.SOCKET_CLI_ACCEPT_RISKS}=1.`\n }\n `.trim(),\n )\n } else if (!silent && !shadowSilent) {\n logger.success(\n `Socket ${binName} ${acceptRisks ? 'accepted' : 'found no'}${hasExisting ? ' new' : ''} risks`,\n )\n if (isShadowNpx) {\n logger.log(`Running ${options.add![0]}`)\n }\n }\n\n return await this[kRiskyReify](...args)\n }\n}\n","import { createRequire } from 'node:module'\n\n// @ts-ignore\nimport UntypedEdge from '@npmcli/arborist/lib/edge.js'\n// @ts-ignore\nimport UntypedNode from '@npmcli/arborist/lib/node.js'\n// @ts-ignore\nimport UntypedOverrideSet from '@npmcli/arborist/lib/override-set.js'\n\nimport {\n getArboristClassPath,\n getArboristEdgeClassPath,\n getArboristNodeClassPath,\n getArboristOverrideSetClassPath,\n} from '../paths.mts'\nimport { Arborist, SafeArborist } from './lib/arborist/index.mts'\n\nimport type { EdgeClass, NodeClass, OverrideSetClass } from './types.mts'\n\nconst require = createRequire(import.meta.url)\n\nexport { Arborist, SafeArborist }\n\nexport const Edge: EdgeClass = UntypedEdge\n\nexport const Node: NodeClass = UntypedNode\n\nexport const OverrideSet: OverrideSetClass = UntypedOverrideSet\n\nexport function installSafeArborist() {\n // Override '@npmcli/arborist' module exports with patched variants based on\n // https://github.com/npm/cli/pull/8089.\n const cache: { [key: string]: any } = require.cache\n cache[getArboristClassPath()] = { exports: SafeArborist }\n cache[getArboristEdgeClassPath()] = { exports: Edge }\n cache[getArboristNodeClassPath()] = { exports: Node }\n cache[getArboristOverrideSetClassPath()] = { exports: OverrideSet }\n}\n","import { installSafeArborist } from './arborist/index.mts'\n\ninstallSafeArborist()\n"],"names":["_arboristPkgPath","add","change","remove","__proto__","consolidate","nothrow","debugFn","NPM_REGISTRY_URL","existing","unknownOrigin","length","action","actual","ideal","keep","node","queue","unchanged","getIpc","audit","dryRun","fund","ignoreScripts","progress","save","saveBundle","silent","path","Object","cwd","onlyDirectories","filter","apiToken","blocked","actions","hideAt","logger","cache","exports","installSafeArborist"],"mappings":";;;;;;;;;;;;;AAOA;AACO;;;AAGH;AAGA;AAIAA;AAGF;AACA;AACF;AAEA;AACO;;;AAML;AACA;AACF;AAEA;AACO;;;AAGL;AACA;AACF;AAEA;AACO;;;AAGL;AACA;AACF;AAEA;AACO;;;AAML;AACA;AACF;;ACAO;AACLC;AACAC;AACAC;AACF;;ACjDA;;AAEI;AACA;AACA;;;AAGF;AACF;AAUO;AAKL;AACEC;AACAC;AACAC;AACA;;;AAIF;AAEA;;AAMA;;AAGM;AACF;AAEJ;AAEA;;;AAGA;AACF;AAgBO;;AAKL;;AAEEC;AACA;AACF;;AAEQC;AAAiB;;AAGvBC;AACAC;AACA;AACF;AAEA;;;AAEMC;AAAoB;;AAExB;AACE;AACF;AACA;;AACQC;AAAO;AACf;AACE;AACA;AACA;AACA;;AACQC;AAAiBC;AAAe;AACxC;;AAEA;;AAEIC;AACA;AAIEN;AACF;AACF;AACF;AACEM;AACF;AACA;AACE;;AAKIC;AACAP;AACF;AACF;AACF;AACF;AACA;AACEQ;AACF;AACF;;;AAEUC;AAAU;AAClB;AAAkBP;;AAChB;AACA;;AAKIK;AACAP;AACF;AACF;AACF;AACF;AACA;AACF;;ACpKA;AAmBA;;AAEE;AAA+DU;AAAO;AACxE;AAEO;AACLf;AACAgB;AACAC;AACAC;AACAC;AACAC;AACAC;AACAC;AACAC;AACF;AAUO;AAEA;AAEA;;AAEP;AACA;AACO;;AAEH;AAEIC;;;;AAOF;AACJ;AAEA;AAGE;AACA;;AAGIJ;;AAIJ;;AAGIA;;AAIJK;AACA;AACF;;AAEA;AACA;AAIE;AACEzB;;;AAIF;AAEA;;;AAGA;;AAII;AACA;AACAoB;;AAEF;AACA;;;;;;AAUF;;AAGA;AACA;AACEM;AACAC;AACF;AACA;AAEA;AACEC;AACEvB;AACF;AACF;;AAGEwB;;;;AAKMC;AACAzB;AACF;AAEE0B;AACA1B;AACF;AACN;;;AAIE;;AAEE2B;;AAEF;;AAGN;AAQA;AAGI;AACEC;AAGA;;AAEA;AACF;;AAGF;AACF;;ACrKA;AAIO;AAEA;AAEA;AAEA;AACL;AACA;AACA;AACAC;AAAkCC;;AAClCD;AAAsCC;;AACtCD;AAAsCC;;AACtCD;AAA6CC;;AAC/C;;ACnCAC","debugId":"b33002f6-cafc-4095-a7ed-0703c935057c"}