app-builder-lib 26.4.0 → 26.5.0

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 (54) hide show
  1. package/out/asar/asarUtil.js +105 -73
  2. package/out/asar/asarUtil.js.map +1 -1
  3. package/out/macPackager.js +5 -0
  4. package/out/macPackager.js.map +1 -1
  5. package/out/node-module-collector/bunNodeModulesCollector.d.ts +4 -5
  6. package/out/node-module-collector/bunNodeModulesCollector.js +5 -9
  7. package/out/node-module-collector/bunNodeModulesCollector.js.map +1 -1
  8. package/out/node-module-collector/hoist.js +7 -4
  9. package/out/node-module-collector/hoist.js.map +1 -1
  10. package/out/node-module-collector/index.d.ts +5 -4
  11. package/out/node-module-collector/index.js +6 -3
  12. package/out/node-module-collector/index.js.map +1 -1
  13. package/out/node-module-collector/moduleManager.d.ts +52 -0
  14. package/out/node-module-collector/moduleManager.js +227 -0
  15. package/out/node-module-collector/moduleManager.js.map +1 -0
  16. package/out/node-module-collector/nodeModulesCollector.d.ts +97 -24
  17. package/out/node-module-collector/nodeModulesCollector.js +154 -183
  18. package/out/node-module-collector/nodeModulesCollector.js.map +1 -1
  19. package/out/node-module-collector/npmNodeModulesCollector.d.ts +3 -10
  20. package/out/node-module-collector/npmNodeModulesCollector.js +14 -88
  21. package/out/node-module-collector/npmNodeModulesCollector.js.map +1 -1
  22. package/out/node-module-collector/packageManager.d.ts +2 -1
  23. package/out/node-module-collector/packageManager.js +2 -0
  24. package/out/node-module-collector/packageManager.js.map +1 -1
  25. package/out/node-module-collector/pnpmNodeModulesCollector.d.ts +1 -1
  26. package/out/node-module-collector/pnpmNodeModulesCollector.js +14 -21
  27. package/out/node-module-collector/pnpmNodeModulesCollector.js.map +1 -1
  28. package/out/node-module-collector/traversalNodeModulesCollector.d.ts +18 -0
  29. package/out/node-module-collector/traversalNodeModulesCollector.js +119 -0
  30. package/out/node-module-collector/traversalNodeModulesCollector.js.map +1 -0
  31. package/out/node-module-collector/types.d.ts +5 -10
  32. package/out/node-module-collector/types.js.map +1 -1
  33. package/out/node-module-collector/yarnBerryNodeModulesCollector.js +3 -3
  34. package/out/node-module-collector/yarnBerryNodeModulesCollector.js.map +1 -1
  35. package/out/node-module-collector/yarnNodeModulesCollector.d.ts +1 -2
  36. package/out/node-module-collector/yarnNodeModulesCollector.js +4 -30
  37. package/out/node-module-collector/yarnNodeModulesCollector.js.map +1 -1
  38. package/out/options/macOptions.d.ts +5 -0
  39. package/out/options/macOptions.js.map +1 -1
  40. package/out/publish/PublishManager.js +3 -2
  41. package/out/publish/PublishManager.js.map +1 -1
  42. package/out/targets/archive.js.map +1 -1
  43. package/out/util/appFileCopier.js +16 -12
  44. package/out/util/appFileCopier.js.map +1 -1
  45. package/out/util/packageDependencies.js +2 -1
  46. package/out/util/packageDependencies.js.map +1 -1
  47. package/out/version.d.ts +1 -1
  48. package/out/version.js +1 -1
  49. package/out/version.js.map +1 -1
  50. package/package.json +9 -10
  51. package/scheme.json +7 -0
  52. package/out/node-module-collector/moduleCache.d.ts +0 -27
  53. package/out/node-module-collector/moduleCache.js +0 -65
  54. package/out/node-module-collector/moduleCache.js.map +0 -1
@@ -1,37 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NpmNodeModulesCollector = void 0;
4
- const builder_util_1 = require("builder-util");
5
- const path = require("path");
6
- const nodeModulesCollector_1 = require("./nodeModulesCollector");
7
- const packageManager_1 = require("./packageManager");
8
- class NpmNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollector {
4
+ const nodeModulesCollector_js_1 = require("./nodeModulesCollector.js");
5
+ const packageManager_js_1 = require("./packageManager.js");
6
+ class NpmNodeModulesCollector extends nodeModulesCollector_js_1.NodeModulesCollector {
9
7
  constructor() {
10
8
  super(...arguments);
11
9
  this.installOptions = {
12
- manager: packageManager_1.PM.NPM,
10
+ manager: packageManager_js_1.PM.NPM,
13
11
  lockfile: "package-lock.json",
14
12
  };
15
13
  }
16
14
  getArgs() {
17
15
  return ["list", "-a", "--include", "prod", "--include", "optional", "--omit", "dev", "--json", "--long", "--silent"];
18
16
  }
19
- async getDependenciesTree(pm) {
20
- try {
21
- return await super.getDependenciesTree(pm);
22
- }
23
- catch (error) {
24
- builder_util_1.log.info({ pm: this.installOptions.manager, parser: packageManager_1.PM.NPM, error: error.message }, "unable to process dependency tree, falling back to using manual node_modules traversal");
25
- }
26
- // node_modules linker fallback. (Slower due to system ops, so we only use it as a fallback) [such as when corepack env will not allow npm CLI to extract tree]
27
- return this.buildNodeModulesTreeManually(this.rootDir);
28
- }
29
17
  async collectAllDependencies(tree) {
30
- for (const [, value] of Object.entries(tree.dependencies || {})) {
18
+ for (const [key, value] of Object.entries(tree.dependencies || {})) {
31
19
  if (this.isDuplicatedNpmDependency(value)) {
32
20
  continue;
33
21
  }
34
- this.allDependencies.set(this.packageVersionString(value), value);
22
+ // Use the key (alias name) instead of value.name for npm aliased packages
23
+ // e.g., { "foo": { name: "@scope/bar", ... } } should be stored as "foo@version"
24
+ // This ensures aliased packages are copied to the correct location in node_modules
25
+ const normalizedDep = key !== value.name ? { ...value, name: key } : value;
26
+ this.allDependencies.set(this.packageVersionString(normalizedDep), normalizedDep);
35
27
  await this.collectAllDependencies(value);
36
28
  }
37
29
  }
@@ -53,7 +45,9 @@ class NpmNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollecto
53
45
  continue;
54
46
  }
55
47
  const dependency = resolvedDeps[packageName];
56
- const childDependencyId = this.packageVersionString(dependency);
48
+ // Use the key (alias name) for aliased packages to match how they're stored in allDependencies
49
+ const normalizedName = packageName !== dependency.name ? packageName : dependency.name;
50
+ const childDependencyId = `${normalizedName}@${dependency.version}`;
57
51
  await this.extractProductionDependencyGraph(dependency, childDependencyId);
58
52
  collectedDependencies.push(childDependencyId);
59
53
  }
@@ -67,79 +61,11 @@ class NpmNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollecto
67
61
  const isDuplicateDep = Object.keys(_dependencies).length > 0 && Object.keys(dependencies).length === 0;
68
62
  return isDuplicateDep;
69
63
  }
64
+ // `npm list` provides explicit list of deps in _dependencies
70
65
  isProdDependency(packageName, tree) {
71
66
  var _a;
72
67
  return ((_a = tree._dependencies) === null || _a === void 0 ? void 0 : _a[packageName]) != null;
73
68
  }
74
- /**
75
- * Builds a dependency tree using only package.json dependencies and optionalDependencies.
76
- * This skips devDependencies and uses Node.js module resolution (require.resolve).
77
- */
78
- buildNodeModulesTreeManually(baseDir) {
79
- // Track visited packages by their resolved path to prevent infinite loops
80
- const visited = new Set();
81
- /**
82
- * Recursively builds dependency tree starting from a package directory.
83
- */
84
- const buildFromPackage = async (packageDir) => {
85
- const pkgPath = path.join(packageDir, "package.json");
86
- builder_util_1.log.debug({ pkgPath }, "building dependency node from package.json");
87
- if (!(await this.cache.exists[pkgPath])) {
88
- throw new Error(`package.json not found at ${pkgPath}`);
89
- }
90
- const pkg = await this.cache.packageJson[pkgPath];
91
- const resolvedPackageDir = await this.cache.realPath[packageDir];
92
- // Use resolved path as the unique identifier to prevent circular dependencies
93
- if (visited.has(resolvedPackageDir)) {
94
- builder_util_1.log.debug({ name: pkg.name, version: pkg.version, path: resolvedPackageDir }, "skipping already visited package");
95
- return {
96
- name: pkg.name,
97
- version: pkg.version,
98
- path: resolvedPackageDir,
99
- };
100
- }
101
- visited.add(resolvedPackageDir);
102
- const prodDeps = {};
103
- const allProdDepNames = {
104
- ...pkg.dependencies,
105
- ...pkg.optionalDependencies,
106
- };
107
- // Process all production and optional dependencies
108
- for (const [depName, depVersion] of Object.entries(allProdDepNames)) {
109
- try {
110
- const depPath = await this.locatePackageVersion(resolvedPackageDir, depName, depVersion);
111
- if (!depPath || depPath.packageDir.length === 0) {
112
- builder_util_1.log.warn({ package: pkg.name, dependency: depName, version: depVersion }, "dependency not found, skipping");
113
- continue;
114
- }
115
- const resolvedDepPath = await this.cache.realPath[depPath.packageDir];
116
- const logFields = { package: pkg.name, dependency: depName, resolvedPath: resolvedDepPath };
117
- // Skip if this dependency resolves to the base directory or any parent we're already processing
118
- if (resolvedDepPath === resolvedPackageDir || resolvedDepPath === (await this.cache.realPath[baseDir])) {
119
- builder_util_1.log.debug(logFields, "skipping self-referential dependency");
120
- continue;
121
- }
122
- builder_util_1.log.debug(logFields, "processing production dependency");
123
- // Recursively build the dependency tree for this dependency
124
- prodDeps[depName] = await buildFromPackage(resolvedDepPath);
125
- }
126
- catch (error) {
127
- builder_util_1.log.warn({ package: pkg.name, dependency: depName, error: error.message }, "failed to process dependency, skipping");
128
- }
129
- }
130
- return {
131
- name: pkg.name,
132
- version: pkg.version,
133
- path: resolvedPackageDir,
134
- dependencies: Object.keys(prodDeps).length > 0 ? prodDeps : undefined,
135
- optionalDependencies: pkg.optionalDependencies,
136
- };
137
- };
138
- return buildFromPackage(baseDir);
139
- }
140
- async parseDependenciesTree(jsonBlob) {
141
- return Promise.resolve(JSON.parse(jsonBlob));
142
- }
143
69
  }
144
70
  exports.NpmNodeModulesCollector = NpmNodeModulesCollector;
145
71
  //# sourceMappingURL=npmNodeModulesCollector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"npmNodeModulesCollector.js","sourceRoot":"","sources":["../../src/node-module-collector/npmNodeModulesCollector.ts"],"names":[],"mappings":"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","sourcesContent":["import { log } from \"builder-util\"\nimport * as path from \"path\"\nimport { NodeModulesCollector } from \"./nodeModulesCollector\"\nimport { PM } from \"./packageManager\"\nimport { NpmDependency, PackageJson } from \"./types\"\n\nexport class NpmNodeModulesCollector extends NodeModulesCollector<NpmDependency, string> {\n public readonly installOptions = {\n manager: PM.NPM,\n lockfile: \"package-lock.json\",\n }\n\n protected getArgs(): string[] {\n return [\"list\", \"-a\", \"--include\", \"prod\", \"--include\", \"optional\", \"--omit\", \"dev\", \"--json\", \"--long\", \"--silent\"]\n }\n\n protected async getDependenciesTree(pm: PM): Promise<NpmDependency> {\n try {\n return await super.getDependenciesTree(pm)\n } catch (error: any) {\n log.info({ pm: this.installOptions.manager, parser: PM.NPM, error: error.message }, \"unable to process dependency tree, falling back to using manual node_modules traversal\")\n }\n // node_modules linker fallback. (Slower due to system ops, so we only use it as a fallback) [such as when corepack env will not allow npm CLI to extract tree]\n return this.buildNodeModulesTreeManually(this.rootDir)\n }\n\n protected async collectAllDependencies(tree: NpmDependency) {\n for (const [, value] of Object.entries(tree.dependencies || {})) {\n if (this.isDuplicatedNpmDependency(value)) {\n continue\n }\n this.allDependencies.set(this.packageVersionString(value), value)\n await this.collectAllDependencies(value)\n }\n }\n\n protected async extractProductionDependencyGraph(tree: NpmDependency, dependencyId: string): Promise<void> {\n if (this.productionGraph[dependencyId]) {\n return\n }\n\n const isDuplicateDep = this.isDuplicatedNpmDependency(tree)\n const resolvedDeps = isDuplicateDep ? this.allDependencies.get(dependencyId)?.dependencies : tree.dependencies\n // Initialize with empty dependencies array first to mark this dependency as \"in progress\"\n // After initialization, if there are libraries with the same name+version later, they will not be searched recursively again\n // This will prevents infinite loops when circular dependencies are encountered.\n this.productionGraph[dependencyId] = { dependencies: [] }\n\n const collectedDependencies: string[] = []\n if (resolvedDeps && Object.keys(resolvedDeps).length > 0) {\n for (const packageName in resolvedDeps) {\n if (!this.isProdDependency(packageName, tree)) {\n continue\n }\n const dependency = resolvedDeps[packageName]\n const childDependencyId = this.packageVersionString(dependency)\n await this.extractProductionDependencyGraph(dependency, childDependencyId)\n collectedDependencies.push(childDependencyId)\n }\n }\n this.productionGraph[dependencyId] = { dependencies: collectedDependencies }\n }\n\n // Check: is package already included as a prod dependency due to another package?\n // We need to check this to prevent infinite loops in case of duplicated dependencies\n private isDuplicatedNpmDependency(tree: NpmDependency): boolean {\n const { _dependencies = {}, dependencies = {} } = tree\n const isDuplicateDep = Object.keys(_dependencies).length > 0 && Object.keys(dependencies).length === 0\n return isDuplicateDep\n }\n\n protected isProdDependency(packageName: string, tree: NpmDependency) {\n return tree._dependencies?.[packageName] != null\n }\n\n /**\n * Builds a dependency tree using only package.json dependencies and optionalDependencies.\n * This skips devDependencies and uses Node.js module resolution (require.resolve).\n */\n protected buildNodeModulesTreeManually(baseDir: string): Promise<NpmDependency> {\n // Track visited packages by their resolved path to prevent infinite loops\n const visited = new Set<string>()\n\n /**\n * Recursively builds dependency tree starting from a package directory.\n */\n const buildFromPackage = async (packageDir: string): Promise<NpmDependency> => {\n const pkgPath = path.join(packageDir, \"package.json\")\n\n log.debug({ pkgPath }, \"building dependency node from package.json\")\n\n if (!(await this.cache.exists[pkgPath])) {\n throw new Error(`package.json not found at ${pkgPath}`)\n }\n\n const pkg: PackageJson = await this.cache.packageJson[pkgPath]\n const resolvedPackageDir = await this.cache.realPath[packageDir]\n\n // Use resolved path as the unique identifier to prevent circular dependencies\n if (visited.has(resolvedPackageDir)) {\n log.debug({ name: pkg.name, version: pkg.version, path: resolvedPackageDir }, \"skipping already visited package\")\n return {\n name: pkg.name,\n version: pkg.version,\n path: resolvedPackageDir,\n }\n }\n\n visited.add(resolvedPackageDir)\n\n const prodDeps: Record<string, NpmDependency> = {}\n const allProdDepNames = {\n ...pkg.dependencies,\n ...pkg.optionalDependencies,\n }\n\n // Process all production and optional dependencies\n for (const [depName, depVersion] of Object.entries(allProdDepNames)) {\n try {\n const depPath = await this.locatePackageVersion(resolvedPackageDir, depName, depVersion)\n\n if (!depPath || depPath.packageDir.length === 0) {\n log.warn({ package: pkg.name, dependency: depName, version: depVersion }, \"dependency not found, skipping\")\n continue\n }\n\n const resolvedDepPath = await this.cache.realPath[depPath.packageDir]\n const logFields = { package: pkg.name, dependency: depName, resolvedPath: resolvedDepPath }\n\n // Skip if this dependency resolves to the base directory or any parent we're already processing\n if (resolvedDepPath === resolvedPackageDir || resolvedDepPath === (await this.cache.realPath[baseDir])) {\n log.debug(logFields, \"skipping self-referential dependency\")\n continue\n }\n\n log.debug(logFields, \"processing production dependency\")\n\n // Recursively build the dependency tree for this dependency\n prodDeps[depName] = await buildFromPackage(resolvedDepPath)\n } catch (error: any) {\n log.warn({ package: pkg.name, dependency: depName, error: error.message }, \"failed to process dependency, skipping\")\n }\n }\n\n return {\n name: pkg.name,\n version: pkg.version,\n path: resolvedPackageDir,\n dependencies: Object.keys(prodDeps).length > 0 ? prodDeps : undefined,\n optionalDependencies: pkg.optionalDependencies,\n }\n }\n\n return buildFromPackage(baseDir)\n }\n\n protected async parseDependenciesTree(jsonBlob: string): Promise<NpmDependency> {\n return Promise.resolve(JSON.parse(jsonBlob))\n }\n}\n"]}
1
+ {"version":3,"file":"npmNodeModulesCollector.js","sourceRoot":"","sources":["../../src/node-module-collector/npmNodeModulesCollector.ts"],"names":[],"mappings":"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","sourcesContent":["import { NodeModulesCollector } from \"./nodeModulesCollector.js\"\nimport { PM } from \"./packageManager.js\"\nimport { NpmDependency } from \"./types.js\"\n\nexport class NpmNodeModulesCollector extends NodeModulesCollector<NpmDependency, string> {\n public readonly installOptions = {\n manager: PM.NPM,\n lockfile: \"package-lock.json\",\n }\n\n protected getArgs(): string[] {\n return [\"list\", \"-a\", \"--include\", \"prod\", \"--include\", \"optional\", \"--omit\", \"dev\", \"--json\", \"--long\", \"--silent\"]\n }\n\n protected async collectAllDependencies(tree: NpmDependency) {\n for (const [key, value] of Object.entries(tree.dependencies || {})) {\n if (this.isDuplicatedNpmDependency(value)) {\n continue\n }\n // Use the key (alias name) instead of value.name for npm aliased packages\n // e.g., { \"foo\": { name: \"@scope/bar\", ... } } should be stored as \"foo@version\"\n // This ensures aliased packages are copied to the correct location in node_modules\n const normalizedDep: NpmDependency = key !== value.name ? { ...value, name: key } : value\n this.allDependencies.set(this.packageVersionString(normalizedDep), normalizedDep)\n await this.collectAllDependencies(value)\n }\n }\n\n protected async extractProductionDependencyGraph(tree: NpmDependency, dependencyId: string): Promise<void> {\n if (this.productionGraph[dependencyId]) {\n return\n }\n\n const isDuplicateDep = this.isDuplicatedNpmDependency(tree)\n const resolvedDeps = isDuplicateDep ? this.allDependencies.get(dependencyId)?.dependencies : tree.dependencies\n // Initialize with empty dependencies array first to mark this dependency as \"in progress\"\n // After initialization, if there are libraries with the same name+version later, they will not be searched recursively again\n // This will prevents infinite loops when circular dependencies are encountered.\n this.productionGraph[dependencyId] = { dependencies: [] }\n\n const collectedDependencies: string[] = []\n if (resolvedDeps && Object.keys(resolvedDeps).length > 0) {\n for (const packageName in resolvedDeps) {\n if (!this.isProdDependency(packageName, tree)) {\n continue\n }\n const dependency = resolvedDeps[packageName]\n // Use the key (alias name) for aliased packages to match how they're stored in allDependencies\n const normalizedName = packageName !== dependency.name ? packageName : dependency.name\n const childDependencyId = `${normalizedName}@${dependency.version}`\n await this.extractProductionDependencyGraph(dependency, childDependencyId)\n collectedDependencies.push(childDependencyId)\n }\n }\n this.productionGraph[dependencyId] = { dependencies: collectedDependencies }\n }\n\n // Check: is package already included as a prod dependency due to another package?\n // We need to check this to prevent infinite loops in case of duplicated dependencies\n private isDuplicatedNpmDependency(tree: NpmDependency): boolean {\n const { _dependencies = {}, dependencies = {} } = tree\n const isDuplicateDep = Object.keys(_dependencies).length > 0 && Object.keys(dependencies).length === 0\n return isDuplicateDep\n }\n\n // `npm list` provides explicit list of deps in _dependencies\n protected isProdDependency(packageName: string, tree: NpmDependency) {\n return tree._dependencies?.[packageName] != null\n }\n}\n"]}
@@ -3,7 +3,8 @@ export declare enum PM {
3
3
  YARN = "yarn",
4
4
  YARN_BERRY = "yarn-berry",
5
5
  BUN = "bun",
6
- NPM = "npm"
6
+ NPM = "npm",
7
+ TRAVERSAL = "traversal"
7
8
  }
8
9
  export declare function getPackageManagerCommand(pm: PM): string;
9
10
  type PackageManagerSetup = {
@@ -14,6 +14,7 @@ var PM;
14
14
  PM["YARN_BERRY"] = "yarn-berry";
15
15
  PM["BUN"] = "bun";
16
16
  PM["NPM"] = "npm";
17
+ PM["TRAVERSAL"] = "traversal";
17
18
  })(PM || (exports.PM = PM = {}));
18
19
  // Cache for resolved paths
19
20
  const pmPathCache = {
@@ -22,6 +23,7 @@ const pmPathCache = {
22
23
  [PM.PNPM]: undefined,
23
24
  [PM.YARN_BERRY]: undefined,
24
25
  [PM.BUN]: undefined,
26
+ [PM.TRAVERSAL]: undefined,
25
27
  };
26
28
  function resolveCommand(pm) {
27
29
  const fallback = pm === PM.YARN_BERRY ? "yarn" : pm;
@@ -1 +1 @@
1
- {"version":3,"file":"packageManager.js","sourceRoot":"","sources":["../../src/node-module-collector/packageManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { exists, log } from \"builder-util\"\nimport * as fs from \"fs-extra\"\nimport * as path from \"path\"\nimport * as which from \"which\"\n\nexport enum PM {\n PNPM = \"pnpm\",\n YARN = \"yarn\",\n YARN_BERRY = \"yarn-berry\",\n BUN = \"bun\",\n NPM = \"npm\",\n}\n\n// Cache for resolved paths\nconst pmPathCache: Record<PM, string | null | undefined> = {\n [PM.NPM]: undefined,\n [PM.YARN]: undefined,\n [PM.PNPM]: undefined,\n [PM.YARN_BERRY]: undefined,\n [PM.BUN]: undefined,\n}\n\nfunction resolveCommand(pm: PM): string {\n const fallback = pm === PM.YARN_BERRY ? \"yarn\" : pm\n\n if (process.platform !== \"win32\") {\n return fallback\n }\n\n try {\n return which.sync(fallback)\n } catch {\n // If `which` fails (not found), still return the fallback string\n return fallback\n }\n}\n\nexport function getPackageManagerCommand(pm: PM) {\n if (pmPathCache[pm] !== undefined) {\n return pmPathCache[pm]!\n }\n\n const resolved = resolveCommand(pm)\n pmPathCache[pm] = resolved\n return resolved\n}\n\ntype PackageManagerSetup = {\n pm: PM\n corepackConfig: string | undefined\n resolvedDirectory: string | undefined\n detectionMethod: string\n}\n\nexport async function detectPackageManager(searchPaths: string[]): Promise<PackageManagerSetup> {\n let pm: PM | null = null\n const dedupedPaths = Array.from(new Set(searchPaths)) // reduce file operations, dedupe paths since primary use case has projectDir === appDir\n\n const resolveIfYarn = (pm: PM, version: string, cwd: string) => (pm === PM.YARN ? detectYarnBerry(cwd, version) : pm)\n\n for (const dir of dedupedPaths) {\n const packageJsonPath = path.join(dir, \"package.json\")\n const packageManager = (await exists(packageJsonPath)) ? (await fs.readJson(packageJsonPath, \"utf8\"))?.packageManager : undefined\n if (packageManager) {\n const [pm, version] = packageManager.split(\"@\")\n if (Object.values(PM).includes(pm as PM)) {\n const resolvedPackageManager = await resolveIfYarn(pm as PM, version, dir)\n return { pm: resolvedPackageManager, corepackConfig: packageManager, resolvedDirectory: dir, detectionMethod: \"packageManager field\" }\n }\n }\n\n pm = await detectPackageManagerByFile(dir)\n if (pm) {\n const resolvedPackageManager = await resolveIfYarn(pm, \"\", dir)\n return { pm: resolvedPackageManager, resolvedDirectory: dir, corepackConfig: undefined, detectionMethod: \"lock file\" }\n }\n }\n\n pm = detectPackageManagerByEnv() || PM.NPM\n const cwd = process.env.npm_package_json ? path.dirname(process.env.npm_package_json) : (process.env.INIT_CWD ?? process.cwd())\n const resolvedPackageManager = await resolveIfYarn(pm, \"\", cwd)\n log.info({ resolvedPackageManager, detected: cwd }, \"packageManager not detected by file, falling back to environment detection\")\n return { pm: resolvedPackageManager, resolvedDirectory: undefined, corepackConfig: undefined, detectionMethod: \"process environment\" }\n}\n\nfunction detectPackageManagerByEnv(): PM | null {\n const priorityChecklist = [(key: string) => process.env.npm_config_user_agent?.includes(key), (key: string) => process.env.npm_execpath?.includes(key)]\n\n const pms = Object.values(PM).filter(pm => pm !== PM.YARN_BERRY)\n for (const checker of priorityChecklist) {\n for (const pm of pms) {\n if (checker(pm)) {\n return pm\n }\n }\n }\n return null\n}\n\nasync function detectPackageManagerByFile(dir: string): Promise<PM | null> {\n const has = (file: string) => exists(path.join(dir, file))\n\n const detected: PM[] = []\n if (await has(\"yarn.lock\")) {\n detected.push(PM.YARN)\n }\n if (await has(\"pnpm-lock.yaml\")) {\n detected.push(PM.PNPM)\n }\n if (await has(\"package-lock.json\")) {\n detected.push(PM.NPM)\n }\n if ((await has(\"bun.lock\")) || (await has(\"bun.lockb\"))) {\n detected.push(PM.BUN)\n }\n\n if (detected.length === 1) {\n return detected[0]\n }\n\n return null\n}\n\nasync function detectYarnBerry(cwd: string, version: string): Promise<PM.YARN | PM.YARN_BERRY> {\n const checkBerry = () => {\n try {\n if (parseInt(version.split(\".\")[0]) > 1) {\n return PM.YARN_BERRY\n }\n } catch (_error) {\n log.debug({ error: _error }, \"cannot determine yarn version, assuming yarn v1\")\n // If `yarn` is not found or another error occurs, fall back to the regular Yarn since we're already determined in a Yarn project\n }\n return undefined\n }\n\n if (version === \"latest\" || version === \"berry\") {\n return PM.YARN_BERRY\n }\n\n if (version.length > 0) {\n return checkBerry() ?? PM.YARN\n }\n\n const lockPath = path.join(cwd, \"yarn.lock\")\n if (!(await exists(lockPath))) {\n return checkBerry() ?? PM.YARN\n }\n // Read the first few lines of yarn.lock to determine the version\n const firstBytes = (await fs.readFile(lockPath, \"utf8\")).split(\"\\n\").slice(0, 10).join(\"\\n\")\n\n // Yarn v2+ (Berry) has a \"__metadata:\" block near the top\n if (firstBytes.includes(\"__metadata:\")) {\n return PM.YARN_BERRY\n }\n\n // Yarn v1 format is classic semi-YAML with comment header\n if (firstBytes.includes(\"DO NOT EDIT THIS FILE DIRECTLY.\")) {\n return PM.YARN\n }\n\n return checkBerry() ?? PM.YARN\n}\n"]}
1
+ {"version":3,"file":"packageManager.js","sourceRoot":"","sources":["../../src/node-module-collector/packageManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { exists, log } from \"builder-util\"\nimport * as fs from \"fs-extra\"\nimport * as path from \"path\"\nimport * as which from \"which\"\n\nexport enum PM {\n PNPM = \"pnpm\",\n YARN = \"yarn\",\n YARN_BERRY = \"yarn-berry\",\n BUN = \"bun\",\n NPM = \"npm\",\n TRAVERSAL = \"traversal\",\n}\n\n// Cache for resolved paths\nconst pmPathCache: Record<PM, string | null | undefined> = {\n [PM.NPM]: undefined,\n [PM.YARN]: undefined,\n [PM.PNPM]: undefined,\n [PM.YARN_BERRY]: undefined,\n [PM.BUN]: undefined,\n [PM.TRAVERSAL]: undefined,\n}\n\nfunction resolveCommand(pm: PM): string {\n const fallback = pm === PM.YARN_BERRY ? \"yarn\" : pm\n\n if (process.platform !== \"win32\") {\n return fallback\n }\n\n try {\n return which.sync(fallback)\n } catch {\n // If `which` fails (not found), still return the fallback string\n return fallback\n }\n}\n\nexport function getPackageManagerCommand(pm: PM) {\n if (pmPathCache[pm] !== undefined) {\n return pmPathCache[pm]!\n }\n\n const resolved = resolveCommand(pm)\n pmPathCache[pm] = resolved\n return resolved\n}\n\ntype PackageManagerSetup = {\n pm: PM\n corepackConfig: string | undefined\n resolvedDirectory: string | undefined\n detectionMethod: string\n}\n\nexport async function detectPackageManager(searchPaths: string[]): Promise<PackageManagerSetup> {\n let pm: PM | null = null\n const dedupedPaths = Array.from(new Set(searchPaths)) // reduce file operations, dedupe paths since primary use case has projectDir === appDir\n\n const resolveIfYarn = (pm: PM, version: string, cwd: string) => (pm === PM.YARN ? detectYarnBerry(cwd, version) : pm)\n\n for (const dir of dedupedPaths) {\n const packageJsonPath = path.join(dir, \"package.json\")\n const packageManager = (await exists(packageJsonPath)) ? (await fs.readJson(packageJsonPath, \"utf8\"))?.packageManager : undefined\n if (packageManager) {\n const [pm, version] = packageManager.split(\"@\")\n if (Object.values(PM).includes(pm as PM)) {\n const resolvedPackageManager = await resolveIfYarn(pm as PM, version, dir)\n return { pm: resolvedPackageManager, corepackConfig: packageManager, resolvedDirectory: dir, detectionMethod: \"packageManager field\" }\n }\n }\n\n pm = await detectPackageManagerByFile(dir)\n if (pm) {\n const resolvedPackageManager = await resolveIfYarn(pm, \"\", dir)\n return { pm: resolvedPackageManager, resolvedDirectory: dir, corepackConfig: undefined, detectionMethod: \"lock file\" }\n }\n }\n\n pm = detectPackageManagerByEnv() || PM.NPM\n const cwd = process.env.npm_package_json ? path.dirname(process.env.npm_package_json) : (process.env.INIT_CWD ?? process.cwd())\n const resolvedPackageManager = await resolveIfYarn(pm, \"\", cwd)\n log.info({ resolvedPackageManager, detected: cwd }, \"packageManager not detected by file, falling back to environment detection\")\n return { pm: resolvedPackageManager, resolvedDirectory: undefined, corepackConfig: undefined, detectionMethod: \"process environment\" }\n}\n\nfunction detectPackageManagerByEnv(): PM | null {\n const priorityChecklist = [(key: string) => process.env.npm_config_user_agent?.includes(key), (key: string) => process.env.npm_execpath?.includes(key)]\n\n const pms = Object.values(PM).filter(pm => pm !== PM.YARN_BERRY)\n for (const checker of priorityChecklist) {\n for (const pm of pms) {\n if (checker(pm)) {\n return pm\n }\n }\n }\n return null\n}\n\nasync function detectPackageManagerByFile(dir: string): Promise<PM | null> {\n const has = (file: string) => exists(path.join(dir, file))\n\n const detected: PM[] = []\n if (await has(\"yarn.lock\")) {\n detected.push(PM.YARN)\n }\n if (await has(\"pnpm-lock.yaml\")) {\n detected.push(PM.PNPM)\n }\n if (await has(\"package-lock.json\")) {\n detected.push(PM.NPM)\n }\n if ((await has(\"bun.lock\")) || (await has(\"bun.lockb\"))) {\n detected.push(PM.BUN)\n }\n\n if (detected.length === 1) {\n return detected[0]\n }\n\n return null\n}\n\nasync function detectYarnBerry(cwd: string, version: string): Promise<PM.YARN | PM.YARN_BERRY> {\n const checkBerry = () => {\n try {\n if (parseInt(version.split(\".\")[0]) > 1) {\n return PM.YARN_BERRY\n }\n } catch (_error) {\n log.debug({ error: _error }, \"cannot determine yarn version, assuming yarn v1\")\n // If `yarn` is not found or another error occurs, fall back to the regular Yarn since we're already determined in a Yarn project\n }\n return undefined\n }\n\n if (version === \"latest\" || version === \"berry\") {\n return PM.YARN_BERRY\n }\n\n if (version.length > 0) {\n return checkBerry() ?? PM.YARN\n }\n\n const lockPath = path.join(cwd, \"yarn.lock\")\n if (!(await exists(lockPath))) {\n return checkBerry() ?? PM.YARN\n }\n // Read the first few lines of yarn.lock to determine the version\n const firstBytes = (await fs.readFile(lockPath, \"utf8\")).split(\"\\n\").slice(0, 10).join(\"\\n\")\n\n // Yarn v2+ (Berry) has a \"__metadata:\" block near the top\n if (firstBytes.includes(\"__metadata:\")) {\n return PM.YARN_BERRY\n }\n\n // Yarn v1 format is classic semi-YAML with comment header\n if (firstBytes.includes(\"DO NOT EDIT THIS FILE DIRECTLY.\")) {\n return PM.YARN\n }\n\n return checkBerry() ?? PM.YARN\n}\n"]}
@@ -11,5 +11,5 @@ export declare class PnpmNodeModulesCollector extends NodeModulesCollector<PnpmD
11
11
  protected extractProductionDependencyGraph(tree: PnpmDependency, dependencyId: string): Promise<void>;
12
12
  protected collectAllDependencies(tree: PnpmDependency): Promise<void>;
13
13
  protected packageVersionString(pkg: PnpmDependency): string;
14
- protected parseDependenciesTree(jsonBlob: string): Promise<PnpmDependency>;
14
+ protected parseDependenciesTree(jsonBlob: string): PnpmDependency;
15
15
  }
@@ -14,7 +14,7 @@ class PnpmNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollect
14
14
  };
15
15
  }
16
16
  getArgs() {
17
- return ["list", "--prod", "--json", "--depth", "Infinity", "--long"];
17
+ return ["list", "--prod", "--json", "--depth", "Infinity"];
18
18
  }
19
19
  async getProductionDependencies(depTree) {
20
20
  const packageName = depTree.name || depTree.from;
@@ -22,19 +22,12 @@ class PnpmNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollect
22
22
  builder_util_1.log.error(depTree, `Cannot determine production dependencies for package with empty name`);
23
23
  throw new Error(`Cannot compute production dependencies for package with empty name: ${packageName}`);
24
24
  }
25
- const actualPath = await this.locatePackageVersion(depTree.path, packageName, depTree.version).then(it => it === null || it === void 0 ? void 0 : it.packageDir);
26
- const resolvedLocalPath = await this.cache.realPath[actualPath !== null && actualPath !== void 0 ? actualPath : depTree.path];
27
- const p = path.normalize(resolvedLocalPath);
28
- const pkgJsonPath = path.join(p, "package.json");
29
- let packageJson;
30
- try {
31
- packageJson = await this.cache.packageJson[pkgJsonPath];
25
+ const result = await this.cache.locatePackageVersion({ parentDir: depTree.path, pkgName: packageName, requiredRange: depTree.version });
26
+ if (result == null) {
27
+ return { path: path.resolve(depTree.path), dependencies: {}, optionalDependencies: {} };
32
28
  }
33
- catch (error) {
34
- builder_util_1.log.warn(null, `Failed to read package.json for ${p}: ${error.message}`);
35
- return { path: p, dependencies: {}, optionalDependencies: {} };
36
- }
37
- return { path: p, dependencies: { ...packageJson.dependencies }, optionalDependencies: { ...packageJson.optionalDependencies } };
29
+ const { dependencies, optionalDependencies } = result.packageJson;
30
+ return { path: result.packageDir, dependencies: { ...dependencies }, optionalDependencies: { ...optionalDependencies } };
38
31
  }
39
32
  async extractProductionDependencyGraph(tree, dependencyId) {
40
33
  var _a, _b, _c, _d;
@@ -52,10 +45,10 @@ class PnpmNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollect
52
45
  continue;
53
46
  }
54
47
  // Then check if optional dependency path exists (using actual resolved path)
55
- const version = ((_a = json === null || json === void 0 ? void 0 : json.optionalDependencies) === null || _a === void 0 ? void 0 : _a[packageName]) || ((_c = (_b = tree.optionalDependencies) === null || _b === void 0 ? void 0 : _b[packageName]) === null || _c === void 0 ? void 0 : _c.version);
56
- const actualPath = await this.locatePackageVersion((_d = json === null || json === void 0 ? void 0 : json.path) !== null && _d !== void 0 ? _d : tree.path, packageName, version).then(it => it === null || it === void 0 ? void 0 : it.packageDir);
57
- if (actualPath == null || !(await this.cache.exists[actualPath])) {
58
- builder_util_1.log.debug({ packageName, version: version, searchPath: actualPath }, `optional dependency not installed, skipping`);
48
+ const version = ((_a = json === null || json === void 0 ? void 0 : json.optionalDependencies) === null || _a === void 0 ? void 0 : _a[packageName]) || ((_c = (_b = tree.optionalDependencies) === null || _b === void 0 ? void 0 : _b[packageName]) === null || _c === void 0 ? void 0 : _c.version) || "";
49
+ const result = await this.locatePackageWithVersion({ name: packageName, version, path: (_d = json === null || json === void 0 ? void 0 : json.path) !== null && _d !== void 0 ? _d : tree.path });
50
+ if (result == null || !(await this.cache.exists[result.packageDir])) {
51
+ builder_util_1.log.debug({ packageName, version: version, searchPath: result === null || result === void 0 ? void 0 : result.packageDir }, `optional dependency not installed, skipping`);
59
52
  continue;
60
53
  }
61
54
  const dependency = treeDep[packageName];
@@ -68,7 +61,7 @@ class PnpmNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollect
68
61
  async collectAllDependencies(tree) {
69
62
  // Collect regular dependencies
70
63
  for (const [key, value] of Object.entries(tree.dependencies || {})) {
71
- const json = await this.getProductionDependencies(value);
64
+ const json = await this.getProductionDependencies({ ...value, name: key });
72
65
  this.allDependencies.set(`${key}@${value.version}`, { ...value, path: json.path });
73
66
  await this.collectAllDependencies(value);
74
67
  }
@@ -83,10 +76,10 @@ class PnpmNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollect
83
76
  // we use 'from' field because 'name' may be different in case of aliases
84
77
  return `${pkg.from}@${pkg.version}`;
85
78
  }
86
- async parseDependenciesTree(jsonBlob) {
87
- const dependencyTree = JSON.parse(jsonBlob);
79
+ parseDependenciesTree(jsonBlob) {
88
80
  // pnpm returns an array of dependency trees
89
- return Promise.resolve(dependencyTree[0]);
81
+ const dependencyTree = this.extractJsonFromPollutedOutput(jsonBlob);
82
+ return dependencyTree[0];
90
83
  }
91
84
  }
92
85
  exports.PnpmNodeModulesCollector = PnpmNodeModulesCollector;
@@ -1 +1 @@
1
- {"version":3,"file":"pnpmNodeModulesCollector.js","sourceRoot":"","sources":["../../src/node-module-collector/pnpmNodeModulesCollector.ts"],"names":[],"mappings":";;;AAAA,+CAAmD;AACnD,6BAA4B;AAC5B,iEAA6D;AAC7D,qDAAqC;AAGrC,MAAa,wBAAyB,SAAQ,2CAAoD;IAAlG;;QACkB,mBAAc,GAAG;YAC/B,OAAO,EAAE,mBAAE,CAAC,IAAI;YAChB,QAAQ,EAAE,gBAAgB;SAC3B,CAAA;IAuFH,CAAC;IArFW,OAAO;QACf,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;IACtE,CAAC;IAEO,KAAK,CAAC,yBAAyB,CAAC,OAAuB;QAC7D,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAA;QAChD,IAAI,IAAA,8BAAe,EAAC,WAAW,CAAC,EAAE,CAAC;YACjC,kBAAG,CAAC,KAAK,CAAC,OAAO,EAAE,sEAAsE,CAAC,CAAA;YAC1F,MAAM,IAAI,KAAK,CAAC,uEAAuE,WAAW,EAAE,CAAC,CAAA;QACvG,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,aAAF,EAAE,uBAAF,EAAE,CAAE,UAAU,CAAC,CAAA;QACzH,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,OAAO,CAAC,IAAI,CAAC,CAAA;QAC/E,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;QAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,cAAc,CAAC,CAAA;QAEhD,IAAI,WAAwB,CAAA;QAC5B,IAAI,CAAC;YACH,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAA;QACzD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,kBAAG,CAAC,IAAI,CAAC,IAAI,EAAE,mCAAmC,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;YACxE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAE,CAAA;QAChE,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,GAAG,WAAW,CAAC,YAAY,EAAE,EAAE,oBAAoB,EAAE,EAAE,GAAG,WAAW,CAAC,oBAAoB,EAAE,EAAE,CAAA;IAClI,CAAC;IAES,KAAK,CAAC,gCAAgC,CAAC,IAAoB,EAAE,YAAoB;;QACzF,IAAI,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,CAAC;YACvC,OAAM;QACR,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,CAAA;QAEzD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAA;QAE1C,MAAM,OAAO,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,oBAAoB,IAAI,EAAE,CAAC,EAAE,CAAA;QACtF,MAAM,IAAI,GAAG,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAA;QAC7F,MAAM,gBAAgB,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;QAEhG,MAAM,qBAAqB,GAAa,EAAE,CAAA;QAC1C,KAAK,MAAM,WAAW,IAAI,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;gBACnC,SAAQ;YACV,CAAC;YAED,6EAA6E;YAC7E,MAAM,OAAO,GAAG,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,oBAAoB,0CAAG,WAAW,CAAC,MAAI,MAAA,MAAA,IAAI,CAAC,oBAAoB,0CAAG,WAAW,CAAC,0CAAE,OAAO,CAAA,CAAA;YAC9G,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,mCAAI,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,aAAF,EAAE,uBAAF,EAAE,CAAE,UAAU,CAAC,CAAA;YAC5H,IAAI,UAAU,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;gBACjE,kBAAG,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,6CAA6C,CAAC,CAAA;gBACnH,SAAQ;YACV,CAAC;YACD,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;YACvC,MAAM,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAA;YAC/D,MAAM,IAAI,CAAC,gCAAgC,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA;YAC1E,qBAAqB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAC/C,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,GAAG,EAAE,YAAY,EAAE,qBAAqB,EAAE,CAAA;IAC9E,CAAC;IAES,KAAK,CAAC,sBAAsB,CAAC,IAAoB;QACzD,+BAA+B;QAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAA;YACxD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;YAClF,MAAM,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAA;QAC1C,CAAC;QAED,8CAA8C;QAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,oBAAoB,IAAI,EAAE,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAA;YACxD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;YAClF,MAAM,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAES,oBAAoB,CAAC,GAAmB;QAChD,yEAAyE;QACzE,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAA;IACrC,CAAC;IAES,KAAK,CAAC,qBAAqB,CAAC,QAAgB;QACpD,MAAM,cAAc,GAAqB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAC7D,4CAA4C;QAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;IAC3C,CAAC;CACF;AA3FD,4DA2FC","sourcesContent":["import { isEmptyOrSpaces, log } from \"builder-util\"\nimport * as path from \"path\"\nimport { NodeModulesCollector } from \"./nodeModulesCollector\"\nimport { PM } from \"./packageManager\"\nimport { PackageJson, PnpmDependency } from \"./types\"\n\nexport class PnpmNodeModulesCollector extends NodeModulesCollector<PnpmDependency, PnpmDependency> {\n public readonly installOptions = {\n manager: PM.PNPM,\n lockfile: \"pnpm-lock.yaml\",\n }\n\n protected getArgs(): string[] {\n return [\"list\", \"--prod\", \"--json\", \"--depth\", \"Infinity\", \"--long\"]\n }\n\n private async getProductionDependencies(depTree: PnpmDependency): Promise<{ path: string; dependencies: Record<string, string>; optionalDependencies: Record<string, string> }> {\n const packageName = depTree.name || depTree.from\n if (isEmptyOrSpaces(packageName)) {\n log.error(depTree, `Cannot determine production dependencies for package with empty name`)\n throw new Error(`Cannot compute production dependencies for package with empty name: ${packageName}`)\n }\n\n const actualPath = await this.locatePackageVersion(depTree.path, packageName, depTree.version).then(it => it?.packageDir)\n const resolvedLocalPath = await this.cache.realPath[actualPath ?? depTree.path]\n const p = path.normalize(resolvedLocalPath)\n const pkgJsonPath = path.join(p, \"package.json\")\n\n let packageJson: PackageJson\n try {\n packageJson = await this.cache.packageJson[pkgJsonPath]\n } catch (error: any) {\n log.warn(null, `Failed to read package.json for ${p}: ${error.message}`)\n return { path: p, dependencies: {}, optionalDependencies: {} }\n }\n return { path: p, dependencies: { ...packageJson.dependencies }, optionalDependencies: { ...packageJson.optionalDependencies } }\n }\n\n protected async extractProductionDependencyGraph(tree: PnpmDependency, dependencyId: string) {\n if (this.productionGraph[dependencyId]) {\n return\n }\n this.productionGraph[dependencyId] = { dependencies: [] }\n\n const packageName = tree.name || tree.from\n\n const treeDep = { ...(tree.dependencies || {}), ...(tree.optionalDependencies || {}) }\n const json = packageName === dependencyId ? null : await this.getProductionDependencies(tree)\n const prodDependencies = json ? { ...json.dependencies, ...json.optionalDependencies } : treeDep\n\n const collectedDependencies: string[] = []\n for (const packageName in treeDep) {\n if (!prodDependencies[packageName]) {\n continue\n }\n\n // Then check if optional dependency path exists (using actual resolved path)\n const version = json?.optionalDependencies?.[packageName] || tree.optionalDependencies?.[packageName]?.version\n const actualPath = await this.locatePackageVersion(json?.path ?? tree.path, packageName, version).then(it => it?.packageDir)\n if (actualPath == null || !(await this.cache.exists[actualPath])) {\n log.debug({ packageName, version: version, searchPath: actualPath }, `optional dependency not installed, skipping`)\n continue\n }\n const dependency = treeDep[packageName]\n const childDependencyId = this.packageVersionString(dependency)\n await this.extractProductionDependencyGraph(dependency, childDependencyId)\n collectedDependencies.push(childDependencyId)\n }\n this.productionGraph[dependencyId] = { dependencies: collectedDependencies }\n }\n\n protected async collectAllDependencies(tree: PnpmDependency) {\n // Collect regular dependencies\n for (const [key, value] of Object.entries(tree.dependencies || {})) {\n const json = await this.getProductionDependencies(value)\n this.allDependencies.set(`${key}@${value.version}`, { ...value, path: json.path })\n await this.collectAllDependencies(value)\n }\n\n // Collect optional dependencies if they exist\n for (const [key, value] of Object.entries(tree.optionalDependencies || {})) {\n const json = await this.getProductionDependencies(value)\n this.allDependencies.set(`${key}@${value.version}`, { ...value, path: json.path })\n await this.collectAllDependencies(value)\n }\n }\n\n protected packageVersionString(pkg: PnpmDependency): string {\n // we use 'from' field because 'name' may be different in case of aliases\n return `${pkg.from}@${pkg.version}`\n }\n\n protected async parseDependenciesTree(jsonBlob: string): Promise<PnpmDependency> {\n const dependencyTree: PnpmDependency[] = JSON.parse(jsonBlob)\n // pnpm returns an array of dependency trees\n return Promise.resolve(dependencyTree[0])\n }\n}\n"]}
1
+ {"version":3,"file":"pnpmNodeModulesCollector.js","sourceRoot":"","sources":["../../src/node-module-collector/pnpmNodeModulesCollector.ts"],"names":[],"mappings":"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","sourcesContent":["import { isEmptyOrSpaces, log } from \"builder-util\"\nimport * as path from \"path\"\nimport { NodeModulesCollector } from \"./nodeModulesCollector\"\nimport { PM } from \"./packageManager\"\nimport { PnpmDependency } from \"./types\"\n\nexport class PnpmNodeModulesCollector extends NodeModulesCollector<PnpmDependency, PnpmDependency> {\n public readonly installOptions = {\n manager: PM.PNPM,\n lockfile: \"pnpm-lock.yaml\",\n }\n\n protected getArgs(): string[] {\n return [\"list\", \"--prod\", \"--json\", \"--depth\", \"Infinity\"]\n }\n\n private async getProductionDependencies(depTree: PnpmDependency): Promise<{ path: string; dependencies: Record<string, string>; optionalDependencies: Record<string, string> }> {\n const packageName = depTree.name || depTree.from\n if (isEmptyOrSpaces(packageName)) {\n log.error(depTree, `Cannot determine production dependencies for package with empty name`)\n throw new Error(`Cannot compute production dependencies for package with empty name: ${packageName}`)\n }\n\n const result = await this.cache.locatePackageVersion({ parentDir: depTree.path, pkgName: packageName, requiredRange: depTree.version })\n if (result == null) {\n return { path: path.resolve(depTree.path), dependencies: {}, optionalDependencies: {} }\n }\n\n const { dependencies, optionalDependencies } = result.packageJson\n return { path: result.packageDir, dependencies: { ...dependencies }, optionalDependencies: { ...optionalDependencies } }\n }\n\n protected async extractProductionDependencyGraph(tree: PnpmDependency, dependencyId: string) {\n if (this.productionGraph[dependencyId]) {\n return\n }\n this.productionGraph[dependencyId] = { dependencies: [] }\n\n const packageName = tree.name || tree.from\n\n const treeDep = { ...(tree.dependencies || {}), ...(tree.optionalDependencies || {}) }\n const json = packageName === dependencyId ? null : await this.getProductionDependencies(tree)\n const prodDependencies = json ? { ...json.dependencies, ...json.optionalDependencies } : treeDep\n\n const collectedDependencies: string[] = []\n for (const packageName in treeDep) {\n if (!prodDependencies[packageName]) {\n continue\n }\n\n // Then check if optional dependency path exists (using actual resolved path)\n const version = json?.optionalDependencies?.[packageName] || tree.optionalDependencies?.[packageName]?.version || \"\"\n const result = await this.locatePackageWithVersion({ name: packageName, version, path: json?.path ?? tree.path })\n if (result == null || !(await this.cache.exists[result.packageDir])) {\n log.debug({ packageName, version: version, searchPath: result?.packageDir }, `optional dependency not installed, skipping`)\n continue\n }\n const dependency = treeDep[packageName]\n const childDependencyId = this.packageVersionString(dependency)\n await this.extractProductionDependencyGraph(dependency, childDependencyId)\n collectedDependencies.push(childDependencyId)\n }\n this.productionGraph[dependencyId] = { dependencies: collectedDependencies }\n }\n\n protected async collectAllDependencies(tree: PnpmDependency) {\n // Collect regular dependencies\n for (const [key, value] of Object.entries(tree.dependencies || {})) {\n const json = await this.getProductionDependencies({ ...value, name: key })\n this.allDependencies.set(`${key}@${value.version}`, { ...value, path: json.path })\n await this.collectAllDependencies(value)\n }\n\n // Collect optional dependencies if they exist\n for (const [key, value] of Object.entries(tree.optionalDependencies || {})) {\n const json = await this.getProductionDependencies(value)\n this.allDependencies.set(`${key}@${value.version}`, { ...value, path: json.path })\n await this.collectAllDependencies(value)\n }\n }\n\n protected packageVersionString(pkg: PnpmDependency): string {\n // we use 'from' field because 'name' may be different in case of aliases\n return `${pkg.from}@${pkg.version}`\n }\n\n protected parseDependenciesTree(jsonBlob: string): PnpmDependency {\n // pnpm returns an array of dependency trees\n const dependencyTree: PnpmDependency[] = this.extractJsonFromPollutedOutput<PnpmDependency[]>(jsonBlob)\n return dependencyTree[0]\n }\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { NodeModulesCollector } from "./nodeModulesCollector";
2
+ import { PM } from "./packageManager.js";
3
+ import { TraversedDependency } from "./types.js";
4
+ export declare class TraversalNodeModulesCollector extends NodeModulesCollector<TraversedDependency, TraversedDependency> {
5
+ installOptions: {
6
+ manager: PM;
7
+ lockfile: string;
8
+ };
9
+ protected getArgs(): string[];
10
+ protected getDependenciesTree(_pm: PM): Promise<TraversedDependency>;
11
+ protected collectAllDependencies(tree: TraversedDependency, appPackageName: string): Promise<void>;
12
+ protected extractProductionDependencyGraph(tree: TraversedDependency, dependencyId: string): Promise<void>;
13
+ /**
14
+ * Builds a dependency tree using only package.json dependencies and optionalDependencies.
15
+ * This skips devDependencies and uses Node.js module resolution (require.resolve).
16
+ */
17
+ private buildNodeModulesTreeManually;
18
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TraversalNodeModulesCollector = void 0;
4
+ const builder_util_1 = require("builder-util");
5
+ const nodeModulesCollector_1 = require("./nodeModulesCollector");
6
+ const packageManager_js_1 = require("./packageManager.js");
7
+ const path = require("path");
8
+ // manual traversal of node_modules for package managers without CLI support for dependency tree extraction (e.g., bun) OR as a fallback (e.g. corepack enabled w/ strict mode)
9
+ class TraversalNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollector {
10
+ constructor() {
11
+ super(...arguments);
12
+ this.installOptions = {
13
+ manager: packageManager_js_1.PM.TRAVERSAL,
14
+ lockfile: "none",
15
+ };
16
+ }
17
+ getArgs() {
18
+ return [];
19
+ }
20
+ getDependenciesTree(_pm) {
21
+ builder_util_1.log.info(null, "using manual traversal of node_modules to build dependency tree");
22
+ return this.buildNodeModulesTreeManually(this.rootDir, undefined);
23
+ }
24
+ async collectAllDependencies(tree, appPackageName) {
25
+ for (const [, value] of Object.entries({ ...tree.dependencies, ...tree.optionalDependencies })) {
26
+ this.allDependencies.set(this.packageVersionString(value), value);
27
+ await this.collectAllDependencies(value, appPackageName);
28
+ }
29
+ }
30
+ // we don't need to check optional dependencies here because they're pre-processed in `buildNodeModulesTreeManually`
31
+ async extractProductionDependencyGraph(tree, dependencyId) {
32
+ if (this.productionGraph[dependencyId]) {
33
+ return;
34
+ }
35
+ this.productionGraph[dependencyId] = { dependencies: [] };
36
+ const prodDependencies = { ...(tree.dependencies || {}), ...(tree.optionalDependencies || {}) };
37
+ const collectedDependencies = [];
38
+ for (const packageName in prodDependencies) {
39
+ const dependency = prodDependencies[packageName];
40
+ const childDependencyId = this.packageVersionString(dependency);
41
+ await this.extractProductionDependencyGraph(dependency, childDependencyId);
42
+ collectedDependencies.push(childDependencyId);
43
+ }
44
+ this.productionGraph[dependencyId] = { dependencies: collectedDependencies };
45
+ }
46
+ /**
47
+ * Builds a dependency tree using only package.json dependencies and optionalDependencies.
48
+ * This skips devDependencies and uses Node.js module resolution (require.resolve).
49
+ */
50
+ async buildNodeModulesTreeManually(baseDir, aliasName) {
51
+ // Track visited packages by their resolved path to prevent infinite loops
52
+ const visited = new Set();
53
+ const resolvedBaseDir = await this.cache.realPath[baseDir];
54
+ /**
55
+ * Recursively builds dependency tree starting from a package directory.
56
+ * @param packageDir - The directory of the package to process
57
+ * @param aliasName - Optional alias name for npm aliased dependencies (e.g., "foo": "npm:@scope/bar@1.0.0")
58
+ * When provided, this name is used instead of the package.json name for the module name,
59
+ * ensuring the package is copied to the correct location in node_modules.
60
+ */
61
+ const buildFromPackage = async (packageDir, aliasName) => {
62
+ const pkgPath = path.join(packageDir, "package.json");
63
+ if (!(await this.cache.exists[pkgPath])) {
64
+ throw new Error(`package.json not found at ${pkgPath}`);
65
+ }
66
+ const pkg = (await this.cache.json[pkgPath]);
67
+ const resolvedPackageDir = await this.cache.realPath[packageDir];
68
+ // Use the alias name if provided, otherwise fall back to the package.json name
69
+ // This ensures npm aliased packages are copied to the correct location
70
+ const moduleName = aliasName !== null && aliasName !== void 0 ? aliasName : pkg.name;
71
+ // Use resolved path as the unique identifier to prevent circular dependencies
72
+ if (visited.has(resolvedPackageDir)) {
73
+ builder_util_1.log.debug({ name: moduleName, version: pkg.version, path: resolvedPackageDir }, "skipping already visited package");
74
+ return {
75
+ name: moduleName,
76
+ version: pkg.version,
77
+ path: resolvedPackageDir,
78
+ };
79
+ }
80
+ visited.add(resolvedPackageDir);
81
+ const buildPackage = async (dependencies, nullHandler) => {
82
+ const builtPackages = {};
83
+ for (const [depName, depVersion] of Object.entries(dependencies || {})) {
84
+ const pkg = await this.locatePackageWithVersion({ name: depName, version: depVersion, path: resolvedPackageDir });
85
+ const logFields = { parent: moduleName, dependency: depName, version: depVersion };
86
+ if (pkg == null) {
87
+ nullHandler(depName, depVersion);
88
+ continue;
89
+ }
90
+ // Skip if this dependency resolves to the base directory or any parent we're already processing
91
+ if (pkg.packageDir === resolvedPackageDir || pkg.packageDir === resolvedBaseDir) {
92
+ builder_util_1.log.debug({ ...logFields, resolvedPath: pkg.packageDir }, "skipping self-referential dependency");
93
+ continue;
94
+ }
95
+ builder_util_1.log.debug(logFields, "processing production dependency");
96
+ builtPackages[depName] = await buildFromPackage(pkg.packageDir, depName);
97
+ }
98
+ return builtPackages;
99
+ };
100
+ const prodDeps = await buildPackage(pkg.dependencies, (depName, version) => {
101
+ builder_util_1.log.error({ parent: moduleName, dependency: depName, version }, "production dependency not found");
102
+ throw new Error(`Production dependency ${depName} not found for package ${moduleName}`);
103
+ });
104
+ const optionalDeps = await buildPackage(pkg.optionalDependencies, (depName) => {
105
+ builder_util_1.log.debug({ parent: moduleName, dependency: depName }, "optional dependency not installed, skipping");
106
+ });
107
+ return {
108
+ name: moduleName,
109
+ version: pkg.version,
110
+ path: resolvedPackageDir,
111
+ dependencies: Object.keys(prodDeps).length > 0 ? prodDeps : undefined,
112
+ optionalDependencies: Object.keys(optionalDeps).length > 0 ? optionalDeps : undefined,
113
+ };
114
+ };
115
+ return buildFromPackage(baseDir, aliasName);
116
+ }
117
+ }
118
+ exports.TraversalNodeModulesCollector = TraversalNodeModulesCollector;
119
+ //# sourceMappingURL=traversalNodeModulesCollector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traversalNodeModulesCollector.js","sourceRoot":"","sources":["../../src/node-module-collector/traversalNodeModulesCollector.ts"],"names":[],"mappings":"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","sourcesContent":["import { log } from \"builder-util\"\nimport { NodeModulesCollector } from \"./nodeModulesCollector\"\nimport { PM } from \"./packageManager.js\"\nimport { TraversedDependency } from \"./types.js\"\nimport * as path from \"path\"\n\n// manual traversal of node_modules for package managers without CLI support for dependency tree extraction (e.g., bun) OR as a fallback (e.g. corepack enabled w/ strict mode)\nexport class TraversalNodeModulesCollector extends NodeModulesCollector<TraversedDependency, TraversedDependency> {\n public installOptions = {\n manager: PM.TRAVERSAL,\n lockfile: \"none\",\n }\n\n protected getArgs(): string[] {\n return []\n }\n\n protected getDependenciesTree(_pm: PM): Promise<TraversedDependency> {\n log.info(null, \"using manual traversal of node_modules to build dependency tree\")\n return this.buildNodeModulesTreeManually(this.rootDir, undefined)\n }\n\n protected async collectAllDependencies(tree: TraversedDependency, appPackageName: string) {\n for (const [, value] of Object.entries({ ...tree.dependencies, ...tree.optionalDependencies })) {\n this.allDependencies.set(this.packageVersionString(value), value)\n await this.collectAllDependencies(value, appPackageName)\n }\n }\n\n // we don't need to check optional dependencies here because they're pre-processed in `buildNodeModulesTreeManually`\n protected async extractProductionDependencyGraph(tree: TraversedDependency, dependencyId: string): Promise<void> {\n if (this.productionGraph[dependencyId]) {\n return\n }\n this.productionGraph[dependencyId] = { dependencies: [] }\n\n const prodDependencies = { ...(tree.dependencies || {}), ...(tree.optionalDependencies || {}) }\n\n const collectedDependencies: string[] = []\n for (const packageName in prodDependencies) {\n const dependency = prodDependencies[packageName]\n const childDependencyId = this.packageVersionString(dependency)\n await this.extractProductionDependencyGraph(dependency, childDependencyId)\n collectedDependencies.push(childDependencyId)\n }\n this.productionGraph[dependencyId] = { dependencies: collectedDependencies }\n }\n\n /**\n * Builds a dependency tree using only package.json dependencies and optionalDependencies.\n * This skips devDependencies and uses Node.js module resolution (require.resolve).\n */\n private async buildNodeModulesTreeManually(baseDir: string, aliasName: string | undefined): Promise<TraversedDependency> {\n // Track visited packages by their resolved path to prevent infinite loops\n const visited = new Set<string>()\n const resolvedBaseDir = await this.cache.realPath[baseDir]\n\n /**\n * Recursively builds dependency tree starting from a package directory.\n * @param packageDir - The directory of the package to process\n * @param aliasName - Optional alias name for npm aliased dependencies (e.g., \"foo\": \"npm:@scope/bar@1.0.0\")\n * When provided, this name is used instead of the package.json name for the module name,\n * ensuring the package is copied to the correct location in node_modules.\n */\n const buildFromPackage = async (packageDir: string, aliasName: string | undefined): Promise<TraversedDependency> => {\n const pkgPath = path.join(packageDir, \"package.json\")\n\n if (!(await this.cache.exists[pkgPath])) {\n throw new Error(`package.json not found at ${pkgPath}`)\n }\n\n const pkg = (await this.cache.json[pkgPath])!\n const resolvedPackageDir = await this.cache.realPath[packageDir]\n\n // Use the alias name if provided, otherwise fall back to the package.json name\n // This ensures npm aliased packages are copied to the correct location\n const moduleName = aliasName ?? pkg.name\n\n // Use resolved path as the unique identifier to prevent circular dependencies\n if (visited.has(resolvedPackageDir)) {\n log.debug({ name: moduleName, version: pkg.version, path: resolvedPackageDir }, \"skipping already visited package\")\n\n return {\n name: moduleName,\n version: pkg.version,\n path: resolvedPackageDir,\n }\n }\n\n visited.add(resolvedPackageDir)\n\n const buildPackage = async (dependencies: Record<string, string> | undefined, nullHandler: (depName: string, version: string) => void) => {\n const builtPackages: Record<string, TraversedDependency> = {}\n for (const [depName, depVersion] of Object.entries(dependencies || {})) {\n const pkg = await this.locatePackageWithVersion({ name: depName, version: depVersion, path: resolvedPackageDir })\n\n const logFields = { parent: moduleName, dependency: depName, version: depVersion }\n if (pkg == null) {\n nullHandler(depName, depVersion)\n continue\n }\n\n // Skip if this dependency resolves to the base directory or any parent we're already processing\n if (pkg.packageDir === resolvedPackageDir || pkg.packageDir === resolvedBaseDir) {\n log.debug({ ...logFields, resolvedPath: pkg.packageDir }, \"skipping self-referential dependency\")\n continue\n }\n\n log.debug(logFields, \"processing production dependency\")\n builtPackages[depName] = await buildFromPackage(pkg.packageDir, depName)\n }\n return builtPackages\n }\n\n const prodDeps = await buildPackage(pkg.dependencies, (depName: string, version: string) => {\n log.error({ parent: moduleName, dependency: depName, version }, \"production dependency not found\")\n throw new Error(`Production dependency ${depName} not found for package ${moduleName}`)\n })\n\n const optionalDeps = await buildPackage(pkg.optionalDependencies, (depName: string) => {\n log.debug({ parent: moduleName, dependency: depName }, \"optional dependency not installed, skipping\")\n })\n\n return {\n name: moduleName,\n version: pkg.version,\n path: resolvedPackageDir,\n dependencies: Object.keys(prodDeps).length > 0 ? prodDeps : undefined,\n optionalDependencies: Object.keys(optionalDeps).length > 0 ? optionalDeps : undefined,\n }\n }\n\n return buildFromPackage(baseDir, aliasName)\n }\n}\n"]}
@@ -9,11 +9,6 @@ export type PackageJson = {
9
9
  packages: string[];
10
10
  };
11
11
  };
12
- export type ResolveModuleOptions<T> = {
13
- dependency: T;
14
- virtualPath?: string;
15
- isOptionalDependency?: boolean;
16
- };
17
12
  export interface NodeModuleInfo {
18
13
  name: string;
19
14
  version: string;
@@ -42,6 +37,8 @@ export interface YarnBerryDependency extends Dependency<YarnBerryDependency, str
42
37
  }
43
38
  export interface YarnDependency extends Dependency<YarnDependency, YarnDependency> {
44
39
  }
40
+ export interface TraversedDependency extends Dependency<TraversedDependency, TraversedDependency> {
41
+ }
45
42
  export type Dependency<T, V> = Dependencies<T, V> & ParsedDependencyTree;
46
43
  export type Dependencies<T, V> = {
47
44
  readonly dependencies?: {
@@ -52,9 +49,7 @@ export type Dependencies<T, V> = {
52
49
  };
53
50
  };
54
51
  export interface DependencyGraph {
55
- [packageNameAndVersion: string]: PackageDependencies;
56
- }
57
- interface PackageDependencies {
58
- readonly dependencies: string[];
52
+ [packageNameAndVersion: string]: {
53
+ readonly dependencies: string[];
54
+ };
59
55
  }
60
- export {};
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/node-module-collector/types.ts"],"names":[],"mappings":"","sourcesContent":["export type PackageJson = {\n name: string\n version: string\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n optionalDependencies?: Record<string, string>\n workspaces?: string[] | { packages: string[] }\n}\n\nexport type ResolveModuleOptions<T> = {\n dependency: T\n virtualPath?: string // e.g. for file: dependencies or symlinked dependencies\n isOptionalDependency?: boolean\n}\n\nexport interface NodeModuleInfo {\n name: string\n version: string\n dir: string\n dependencies?: Array<NodeModuleInfo>\n}\n\nexport type ParsedDependencyTree = {\n readonly name: string\n readonly version: string\n readonly path: string\n readonly workspaces?: string[] | { packages: string[] } // we only use this at root level\n}\n\n// Note: `PnpmDependency` and `NpmDependency` include the output of `JSON.parse(...)` of `pnpm list` and `npm list` respectively\n// This object has a TON of info - a majority, if not all, of each dependency's package.json\n// We extract only what we need when constructing DependencyTree in `extractProductionDependencyTree`\nexport interface PnpmDependency extends Dependency<PnpmDependency, PnpmDependency> {\n readonly from: string\n readonly resolved: string\n}\n\nexport interface NpmDependency extends Dependency<NpmDependency, string> {\n readonly resolved?: string\n // implicit dependencies\n readonly _dependencies?: {\n [packageName: string]: string\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface YarnBerryDependency extends Dependency<YarnBerryDependency, string> {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface YarnDependency extends Dependency<YarnDependency, YarnDependency> {}\n\nexport type Dependency<T, V> = Dependencies<T, V> & ParsedDependencyTree\n\nexport type Dependencies<T, V> = {\n readonly dependencies?: {\n [packageName: string]: T\n }\n readonly optionalDependencies?: {\n [packageName: string]: V\n }\n}\n\nexport interface DependencyGraph {\n [packageNameAndVersion: string]: PackageDependencies\n}\n\ninterface PackageDependencies {\n readonly dependencies: string[]\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/node-module-collector/types.ts"],"names":[],"mappings":"","sourcesContent":["export type PackageJson = {\n name: string\n version: string\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n optionalDependencies?: Record<string, string>\n workspaces?: string[] | { packages: string[] }\n}\n\nexport interface NodeModuleInfo {\n name: string\n version: string\n dir: string\n dependencies?: Array<NodeModuleInfo>\n}\n\nexport type ParsedDependencyTree = {\n readonly name: string\n readonly version: string\n readonly path: string\n readonly workspaces?: string[] | { packages: string[] } // we only use this at root level\n}\n\n// Note: `PnpmDependency` and `NpmDependency` include the output of `JSON.parse(...)` of `pnpm list` and `npm list` respectively\n// This object has a TON of info - a majority, if not all, of each dependency's package.json\n// We extract only what we need when constructing DependencyTree in `extractProductionDependencyTree`\nexport interface PnpmDependency extends Dependency<PnpmDependency, PnpmDependency> {\n readonly from: string\n readonly resolved: string\n}\n\nexport interface NpmDependency extends Dependency<NpmDependency, string> {\n readonly resolved?: string\n // implicit dependencies, returned only through `npm list`\n readonly _dependencies?: {\n [packageName: string]: string\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface YarnBerryDependency extends Dependency<YarnBerryDependency, string> {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface YarnDependency extends Dependency<YarnDependency, YarnDependency> {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface TraversedDependency extends Dependency<TraversedDependency, TraversedDependency> {}\n\nexport type Dependency<T, V> = Dependencies<T, V> & ParsedDependencyTree\n\nexport type Dependencies<T, V> = {\n readonly dependencies?: {\n [packageName: string]: T\n }\n readonly optionalDependencies?: {\n [packageName: string]: V\n }\n}\n\nexport interface DependencyGraph {\n [packageNameAndVersion: string]: {\n readonly dependencies: string[]\n }\n}\n"]}