@davidwells/extract-deps 0.0.8 → 0.0.9

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.
@@ -7,7 +7,8 @@
7
7
  "Bash(npm pack:*)",
8
8
  "Bash(tar:*)",
9
9
  "Bash(npm install)",
10
- "Bash(npm test)"
10
+ "Bash(npm test)",
11
+ "Bash(npm test:*)"
11
12
  ],
12
13
  "deny": [],
13
14
  "ask": []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davidwells/extract-deps",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "Get imports and requires from a codebase without AST",
5
5
  "main": "src/index.js",
6
6
  "exports": {
package/src/dep-graph.js CHANGED
@@ -298,15 +298,27 @@ function depGraph(filePath, options = {}) {
298
298
  * Get all dependency file paths in build order (dependencies first), deduplicated
299
299
  * @param {string} filePath - Entry file path
300
300
  * @param {object} options - Options to pass to depGraph
301
- * @returns {string[]} - Array of unique dependency file paths in topological order
301
+ * @returns {{ files: string[], nodeModules: string[] }} - Object with files in topological order and unique node_modules
302
302
  */
303
303
  function resolveDepPaths(filePath, options = {}) {
304
- const graph = depGraph(filePath, options)
304
+ const graph = depGraph(filePath, { ...options, includeNodeModules: true })
305
+
306
+ // Collect node_modules (non-path strings in dependency arrays)
307
+ const nodeModulesSet = new Set()
308
+ for (const deps of graph.values()) {
309
+ for (const dep of deps) {
310
+ if (!dep.startsWith('/')) {
311
+ nodeModulesSet.add(dep)
312
+ }
313
+ }
314
+ }
305
315
 
306
- // Calculate in-degree (number of dependencies) for each file
316
+ // Calculate in-degree (number of file dependencies) for each file
307
317
  const inDegree = new Map()
308
318
  for (const [file, deps] of graph) {
309
- inDegree.set(file, deps.length)
319
+ // Only count file deps, not node_modules
320
+ const fileDeps = deps.filter(d => d.startsWith('/'))
321
+ inDegree.set(file, fileDeps.length)
310
322
  }
311
323
 
312
324
  // Queue of files with no dependencies (can be processed first)
@@ -335,7 +347,10 @@ function resolveDepPaths(filePath, options = {}) {
335
347
  }
336
348
  }
337
349
 
338
- return buildOrder
350
+ return {
351
+ files: buildOrder,
352
+ nodeModules: Array.from(nodeModulesSet)
353
+ }
339
354
  }
340
355
 
341
356
 
@@ -149,11 +149,12 @@ function verifyPackageEntries(packagePath, options = {}) {
149
149
 
150
150
  if (collectDeps) {
151
151
  // Collect dependencies using resolveDepPaths
152
- const relativeDeps = resolveDepPaths(entryPoint.resolvedPath, { verifyGraph, verifyNodeModules: true })
153
- result.sourceFiles = relativeDeps
152
+ const { files, nodeModules } = resolveDepPaths(entryPoint.resolvedPath, { verifyGraph, verifyNodeModules: true })
153
+ result.sourceFiles = files
154
+ result.nodeModules = nodeModules
154
155
 
155
156
  // Add to sourceFiles set
156
- relativeDeps.forEach(dep => sourceFilesSet.add(dep))
157
+ files.forEach(dep => sourceFilesSet.add(dep))
157
158
  } else if (verifyGraph) {
158
159
  // Just verify without collecting deps
159
160
  depGraph(entryPoint.resolvedPath, { buildGraph: false, verifyGraph: true })
@@ -117,38 +117,39 @@ test('should work with all options combined', () => {
117
117
  })
118
118
 
119
119
  // resolveDepPaths tests
120
- test('resolveDepPaths should return an array', () => {
121
- const deps = resolveDepPaths(CJS_FIXTURE_PATH)
122
- assert.ok(Array.isArray(deps), 'Should return an array')
120
+ test('resolveDepPaths should return object with files and nodeModules', () => {
121
+ const result = resolveDepPaths(CJS_FIXTURE_PATH)
122
+ assert.ok(Array.isArray(result.files), 'files should be an array')
123
+ assert.ok(Array.isArray(result.nodeModules), 'nodeModules should be an array')
123
124
  })
124
125
 
125
126
  test('resolveDepPaths should return deduplicated paths', () => {
126
- const deps = resolveDepPaths(CJS_DEEP_FIXTURE_PATH)
127
- const uniqueDeps = [...new Set(deps)]
127
+ const { files } = resolveDepPaths(CJS_DEEP_FIXTURE_PATH)
128
+ const uniqueDeps = [...new Set(files)]
128
129
 
129
- assert.is(deps.length, uniqueDeps.length, 'Should not have duplicate paths')
130
+ assert.is(files.length, uniqueDeps.length, 'Should not have duplicate paths')
130
131
  })
131
132
 
132
133
  test('resolveDepPaths should include all files from graph', () => {
133
134
  const graph = depGraph(CJS_FIXTURE_PATH)
134
- const deps = resolveDepPaths(CJS_FIXTURE_PATH)
135
+ const { files } = resolveDepPaths(CJS_FIXTURE_PATH)
135
136
 
136
- assert.is(deps.length, graph.size, 'Should have same number of files as graph')
137
+ assert.is(files.length, graph.size, 'Should have same number of files as graph')
137
138
 
138
- // All graph keys should be in deps
139
+ // All graph keys should be in files
139
140
  for (const key of graph.keys()) {
140
- assert.ok(deps.includes(key), `Should include ${path.basename(key)}`)
141
+ assert.ok(files.includes(key), `Should include ${path.basename(key)}`)
141
142
  }
142
143
  })
143
144
 
144
145
  test('resolveDepPaths should return paths in topological order (dependencies first)', () => {
145
- const deps = resolveDepPaths(CJS_FIXTURE_PATH)
146
+ const { files } = resolveDepPaths(CJS_FIXTURE_PATH)
146
147
 
147
148
  // Find indices
148
- const threeIdx = deps.findIndex(p => p.includes('three.js'))
149
- const twoIdx = deps.findIndex(p => p.includes('two.js'))
150
- const oneIdx = deps.findIndex(p => p.includes('one.js'))
151
- const indexIdx = deps.findIndex(p => p.includes('index.js'))
149
+ const threeIdx = files.findIndex(p => p.includes('three.js'))
150
+ const twoIdx = files.findIndex(p => p.includes('two.js'))
151
+ const oneIdx = files.findIndex(p => p.includes('one.js'))
152
+ const indexIdx = files.findIndex(p => p.includes('index.js'))
152
153
 
153
154
  // three.js has no dependencies, should come first
154
155
  assert.ok(threeIdx < twoIdx, 'three.js should come before two.js')
@@ -157,45 +158,45 @@ test('resolveDepPaths should return paths in topological order (dependencies fir
157
158
  })
158
159
 
159
160
  test('resolveDepPaths should work with ESM fixtures', () => {
160
- const deps = resolveDepPaths(ESM_FIXTURE_PATH)
161
+ const { files } = resolveDepPaths(ESM_FIXTURE_PATH)
161
162
 
162
- assert.ok(Array.isArray(deps), 'Should return an array')
163
- assert.ok(deps.length > 0, 'Should have dependencies')
163
+ assert.ok(Array.isArray(files), 'Should return an array')
164
+ assert.ok(files.length > 0, 'Should have dependencies')
164
165
 
165
166
  // Check files are included
166
- assert.ok(deps.some(p => p.includes('index.js')), 'Should include index.js')
167
- assert.ok(deps.some(p => p.includes('one.js')), 'Should include one.js')
168
- assert.ok(deps.some(p => p.includes('two.js')), 'Should include two.js')
169
- assert.ok(deps.some(p => p.includes('three.js')), 'Should include three.js')
167
+ assert.ok(files.some(p => p.includes('index.js')), 'Should include index.js')
168
+ assert.ok(files.some(p => p.includes('one.js')), 'Should include one.js')
169
+ assert.ok(files.some(p => p.includes('two.js')), 'Should include two.js')
170
+ assert.ok(files.some(p => p.includes('three.js')), 'Should include three.js')
170
171
  })
171
172
 
172
173
  test('resolveDepPaths should have entry point last', () => {
173
- const deps = resolveDepPaths(CJS_FIXTURE_PATH)
174
- const lastFile = deps[deps.length - 1]
174
+ const { files } = resolveDepPaths(CJS_FIXTURE_PATH)
175
+ const lastFile = files[files.length - 1]
175
176
 
176
177
  assert.ok(lastFile.includes('index.js'), 'Entry point (index.js) should be last')
177
178
  })
178
179
 
179
180
  test('resolveDepPaths should have leaf nodes first', () => {
180
- const deps = resolveDepPaths(CJS_FIXTURE_PATH)
181
- const firstFile = deps[0]
181
+ const { files } = resolveDepPaths(CJS_FIXTURE_PATH)
182
+ const firstFile = files[0]
182
183
 
183
184
  // three.js has no dependencies - it's a leaf node
184
185
  assert.ok(firstFile.includes('three.js'), 'Leaf node (three.js) should be first')
185
186
  })
186
187
 
187
188
  test('resolveDepPaths should handle complex graphs with shared dependencies', () => {
188
- const deps = resolveDepPaths(CJS_DEEP_FIXTURE_PATH)
189
+ const { files } = resolveDepPaths(CJS_DEEP_FIXTURE_PATH)
189
190
 
190
191
  // Should be deduplicated
191
- const uniqueDeps = [...new Set(deps)]
192
- assert.is(deps.length, uniqueDeps.length, 'Should deduplicate shared dependencies')
192
+ const uniqueDeps = [...new Set(files)]
193
+ assert.is(files.length, uniqueDeps.length, 'Should deduplicate shared dependencies')
193
194
 
194
195
  // Find d-three.js which is shared by d-two.js, d-two-a.js, d-two-b.js
195
- const threeIdx = deps.findIndex(p => p.includes('d-three.js'))
196
- const twoIdx = deps.findIndex(p => p.includes('d-two.js'))
197
- const twoAIdx = deps.findIndex(p => p.includes('d-two-a.js'))
198
- const twoBIdx = deps.findIndex(p => p.includes('d-two-b.js'))
196
+ const threeIdx = files.findIndex(p => p.includes('d-three.js'))
197
+ const twoIdx = files.findIndex(p => p.includes('d-two.js'))
198
+ const twoAIdx = files.findIndex(p => p.includes('d-two-a.js'))
199
+ const twoBIdx = files.findIndex(p => p.includes('d-two-b.js'))
199
200
 
200
201
  // d-three.js should come before all files that depend on it
201
202
  assert.ok(threeIdx < twoIdx, 'd-three.js should come before d-two.js')
@@ -204,10 +205,10 @@ test('resolveDepPaths should handle complex graphs with shared dependencies', ()
204
205
  })
205
206
 
206
207
  test('resolveDepPaths should pass options to depGraph', () => {
207
- const deps = resolveDepPaths(CJS_FIXTURE_PATH, { verifyGraph: false })
208
+ const { files } = resolveDepPaths(CJS_FIXTURE_PATH, { verifyGraph: false })
208
209
 
209
- assert.ok(Array.isArray(deps), 'Should work with options')
210
- assert.ok(deps.length > 0, 'Should return dependencies')
210
+ assert.ok(Array.isArray(files), 'Should work with options')
211
+ assert.ok(files.length > 0, 'Should return dependencies')
211
212
  })
212
213
 
213
214
  // verifyNodeModules tests
@@ -373,13 +374,68 @@ test('should resolve directory import to index.js', () => {
373
374
  })
374
375
 
375
376
  test('resolveDepPaths should work with directory imports', () => {
376
- const deps = resolveDepPaths(DIR_INDEX_FIXTURE_PATH)
377
+ const { files } = resolveDepPaths(DIR_INDEX_FIXTURE_PATH)
377
378
 
378
- assert.ok(Array.isArray(deps), 'Should return an array')
379
- assert.is(deps.length, 2, 'Should have 2 files')
379
+ assert.ok(Array.isArray(files), 'Should return an array')
380
+ assert.is(files.length, 2, 'Should have 2 files')
380
381
 
381
- assert.ok(deps.some(p => p.includes('shared-pkg/index.js')), 'Should include resolved index.js')
382
- assert.ok(deps.some(p => p.includes('entry.js')), 'Should include entry.js')
382
+ assert.ok(files.some(p => p.includes('shared-pkg/index.js')), 'Should include resolved index.js')
383
+ assert.ok(files.some(p => p.includes('entry.js')), 'Should include entry.js')
384
+ })
385
+
386
+ test('resolveDepPaths should return nodeModules', () => {
387
+ const { nodeModules } = resolveDepPaths(CJS_DEEP_FIXTURE_PATH)
388
+
389
+ assert.ok(Array.isArray(nodeModules), 'nodeModules should be an array')
390
+ assert.ok(nodeModules.includes('lodash'), 'Should include lodash')
391
+ })
392
+
393
+ // includeNodeModules tests
394
+ test('includeNodeModules should default to false', () => {
395
+ const graph = depGraph(CJS_DEEP_FIXTURE_PATH)
396
+
397
+ // Check that no dependency array contains 'lodash'
398
+ for (const deps of graph.values()) {
399
+ assert.ok(!deps.includes('lodash'), 'Should not include node_modules by default')
400
+ }
401
+ })
402
+
403
+ test('includeNodeModules: true should add package names to graph', () => {
404
+ const graph = depGraph(CJS_DEEP_FIXTURE_PATH, { includeNodeModules: true })
405
+
406
+ // Find index.js which requires lodash
407
+ const indexPath = Array.from(graph.keys()).find(key => key.includes('cjs-deep-example/index.js'))
408
+ assert.ok(indexPath, 'Should have index.js in graph')
409
+
410
+ const indexDeps = graph.get(indexPath)
411
+ assert.ok(indexDeps.includes('lodash'), 'Should include lodash in dependencies')
412
+ })
413
+
414
+ test('includeNodeModules: true should mix package names with file paths', () => {
415
+ const graph = depGraph(CJS_DEEP_FIXTURE_PATH, { includeNodeModules: true })
416
+
417
+ const indexPath = Array.from(graph.keys()).find(key => key.includes('cjs-deep-example/index.js'))
418
+ const indexDeps = graph.get(indexPath)
419
+
420
+ // Should have both relative dep (d-one.js) and node_module (lodash)
421
+ const hasRelativeDep = indexDeps.some(dep => dep.includes('d-one.js'))
422
+ const hasNodeModule = indexDeps.includes('lodash')
423
+
424
+ assert.ok(hasRelativeDep, 'Should have relative dependency')
425
+ assert.ok(hasNodeModule, 'Should have node_module dependency')
426
+ })
427
+
428
+ test('includeNodeModules works independently of verifyNodeModules', () => {
429
+ // Include but don't verify
430
+ const graph = depGraph(CJS_DEEP_FIXTURE_PATH, {
431
+ includeNodeModules: true,
432
+ verifyNodeModules: false
433
+ })
434
+
435
+ const indexPath = Array.from(graph.keys()).find(key => key.includes('cjs-deep-example/index.js'))
436
+ const indexDeps = graph.get(indexPath)
437
+
438
+ assert.ok(indexDeps.includes('lodash'), 'Should include lodash without verification')
383
439
  })
384
440
 
385
441
  test.run()
@@ -4,19 +4,26 @@
4
4
  * @param {object} options - Options
5
5
  * @param {boolean} [options.buildGraph] - If true, build and return dependency graph. Default: true
6
6
  * @param {boolean} [options.verifyGraph] - If true, verify imports/exports. Default: true
7
+ * @param {boolean} [options.verifyNodeModules] - If true, verify node_modules packages can be resolved. Default: false
8
+ * @param {boolean} [options.includeNodeModules] - If true, include node_modules package names in the graph. Default: false
7
9
  * @param {boolean} [options.throwOnFirstError] - If true, throw immediately on first error. Default: false
8
- * @returns {Map<string, string[]>|undefined} - Dependency graph where keys are file paths and values are arrays of dependency paths. Returns undefined if buildGraph is false.
10
+ * @returns {Map<string, string[]>|undefined} - Dependency graph where keys are file paths and values are arrays of dependency paths (or package names if includeNodeModules). Returns undefined if buildGraph is false.
9
11
  */
10
12
  export function depGraph(filePath: string, options?: {
11
13
  buildGraph?: boolean;
12
14
  verifyGraph?: boolean;
15
+ verifyNodeModules?: boolean;
16
+ includeNodeModules?: boolean;
13
17
  throwOnFirstError?: boolean;
14
18
  }): Map<string, string[]> | undefined;
15
19
  /**
16
20
  * Get all dependency file paths in build order (dependencies first), deduplicated
17
21
  * @param {string} filePath - Entry file path
18
22
  * @param {object} options - Options to pass to depGraph
19
- * @returns {string[]} - Array of unique dependency file paths in topological order
23
+ * @returns {{ files: string[], nodeModules: string[] }} - Object with files in topological order and unique node_modules
20
24
  */
21
- export function resolveDepPaths(filePath: string, options?: object): string[];
25
+ export function resolveDepPaths(filePath: string, options?: object): {
26
+ files: string[];
27
+ nodeModules: string[];
28
+ };
22
29
  //# sourceMappingURL=dep-graph.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dep-graph.d.ts","sourceRoot":"","sources":["../src/dep-graph.js"],"names":[],"mappings":"AA+LA;;;;;;;;GAQG;AACH,mCAPW,MAAM;IAEY,UAAU,GAA5B,OAAO;IACW,WAAW,GAA7B,OAAO;IACW,iBAAiB,GAAnC,OAAO;IACL,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC,GAAC,SAAS,CAiB3C;AAGD;;;;;GAKG;AACH,0CAJW,MAAM,YACN,MAAM,GACJ,MAAM,EAAE,CAsCpB"}
1
+ {"version":3,"file":"dep-graph.d.ts","sourceRoot":"","sources":["../src/dep-graph.js"],"names":[],"mappings":"AAmQA;;;;;;;;;;GAUG;AACH,mCATW,MAAM,YAEd;IAA0B,UAAU,GAA5B,OAAO;IACW,WAAW,GAA7B,OAAO;IACW,iBAAiB,GAAnC,OAAO;IACW,kBAAkB,GAApC,OAAO;IACW,iBAAiB,GAAnC,OAAO;CACf,GAAU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAC,SAAS,CAyB3C;AAGD;;;;;GAKG;AACH,0CAJW,MAAM,YACN,MAAM,GACJ;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAqDtD"}
@@ -32,4 +32,14 @@ export function getObjectAssignExports(originalText?: string, sanitizedText?: st
32
32
  index: number;
33
33
  isExport: boolean;
34
34
  }[];
35
+ export function getDefinePropertyExports(originalText?: string, sanitizedText?: string): {
36
+ line: string;
37
+ exportType: string;
38
+ exportName: string;
39
+ exportValue: string;
40
+ exportDefinitionName: string;
41
+ index: number;
42
+ isExport: boolean;
43
+ isDefineProperty: boolean;
44
+ }[];
35
45
  //# sourceMappingURL=get-cjs-exports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-cjs-exports.d.ts","sourceRoot":"","sources":["../src/get-cjs-exports.js"],"names":[],"mappings":"AA+BA,gDAuBC;AA+BD;;;;;;;;IAqGC;AAED;;;;;;;IAqBC;AAED;;;;;;;IAqBC;AAED;;;;;;;IAiDC"}
1
+ {"version":3,"file":"get-cjs-exports.d.ts","sourceRoot":"","sources":["../src/get-cjs-exports.js"],"names":[],"mappings":"AAoCA,gDAiCC;AA+BD;;;;;;;;IAqGC;AAED;;;;;;;IAqBC;AAED;;;;;;;IAqBC;AAED;;;;;;;IAiDC;AAED;;;;;;;;;IAwEC"}
@@ -24,6 +24,7 @@ export function getTypeImports(targetText?: string): {
24
24
  importName: string;
25
25
  index: number;
26
26
  isImport: boolean;
27
+ isTypeImport: boolean;
27
28
  isRelative: boolean;
28
29
  }[];
29
30
  export function getDynamicImports(targetText?: string): {
@@ -1 +1 @@
1
- {"version":3,"file":"get-imports.d.ts","sourceRoot":"","sources":["../src/get-imports.js"],"names":[],"mappings":"AAWA;;;;;;;;;IAQC;AAGD;;;;;;;;;IAkBC;AAED;;;;;;;IAgBC;AAED;;;;;;;;;;IAoBC;AAED;;;;;;;;;;;;IAwBC"}
1
+ {"version":3,"file":"get-imports.d.ts","sourceRoot":"","sources":["../src/get-imports.js"],"names":[],"mappings":"AAWA;;;;;;;;;IAQC;AAGD;;;;;;;;;IAkBC;AAED;;;;;;;;IAiBC;AAED;;;;;;;;;;IAoBC;AAED;;;;;;;;;;;;IAwBC"}
@@ -0,0 +1,4 @@
1
+ export function inspectParameters(source: any): any;
2
+ export function getParametersNames(source: any): any;
3
+ export function getParametersNamesFromInspection(inspectedParameters: any): any;
4
+ //# sourceMappingURL=inspect-parameters-declaration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect-parameters-declaration.d.ts","sourceRoot":"","sources":["../../src/vendor/inspect-parameters-declaration.js"],"names":[],"mappings":"AA0QA,oDAaC;AAtBD,qDAGC;AAED,gFAEC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Extract all entry points from package.json
3
+ * @param {string} packageJsonPath - Path to package.json
4
+ * @returns {Array<{field: string, path: string, resolvedPath: string}>} - Array of entry point objects
5
+ */
6
+ export function getPackageEntryPoints(packageJsonPath: string): Array<{
7
+ field: string;
8
+ path: string;
9
+ resolvedPath: string;
10
+ }>;
11
+ /**
12
+ * Verify all package.json entry points and collect dependencies
13
+ * @param {string} packagePath - Path to package.json
14
+ * @param {object} options - Options
15
+ * @param {boolean} [options.collectDeps] - If true, collect dependency paths for each entry point. Default: true
16
+ * @param {boolean} [options.verifyGraph] - If true, verify imports/exports. Default: true
17
+ * @param {boolean} [options.throwIfErrors] - If true, throw an error if there are any errors. Default: false
18
+ * @returns {{entryPoints: Array, sourceFiles: Set, errors: Array}} - Verification results
19
+ */
20
+ export function verifyPackageEntries(packagePath: string, options?: {
21
+ collectDeps?: boolean;
22
+ verifyGraph?: boolean;
23
+ throwIfErrors?: boolean;
24
+ }): {
25
+ entryPoints: any[];
26
+ sourceFiles: Set<any>;
27
+ errors: any[];
28
+ };
29
+ export function collectEntryPoints(packageJson: any, packageDir: any): any[];
30
+ //# sourceMappingURL=verify-package-entries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-package-entries.d.ts","sourceRoot":"","sources":["../src/verify-package-entries.js"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,uDAHW,MAAM,GACJ,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,CAAC,CAOtE;AAmGD;;;;;;;;GAQG;AACH,kDAPW,MAAM,YAEd;IAA0B,WAAW,GAA7B,OAAO;IACW,WAAW,GAA7B,OAAO;IACW,aAAa,GAA/B,OAAO;CACf,GAAU;IAAC,WAAW,QAAQ;IAAC,WAAW,WAAM;IAAC,MAAM,QAAO;CAAC,CAoEjE;AA5KD,6EA8DC"}