@davidwells/extract-deps 0.1.0 → 0.1.1

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.
@@ -8,7 +8,8 @@
8
8
  "Bash(tar:*)",
9
9
  "Bash(npm install)",
10
10
  "Bash(npm test)",
11
- "Bash(npm test:*)"
11
+ "Bash(npm test:*)",
12
+ "Bash(npm run types:*)"
12
13
  ],
13
14
  "deny": [],
14
15
  "ask": []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davidwells/extract-deps",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
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
@@ -266,7 +266,8 @@ function buildGraphRecursively(
266
266
  * @param {boolean} [options.verifyNodeModules] - If true, verify node_modules packages can be resolved. Default: false
267
267
  * @param {boolean} [options.includeNodeModules] - If true, include node_modules package names in the graph. Default: false
268
268
  * @param {boolean} [options.throwOnFirstError] - If true, throw immediately on first error. Default: false
269
- * @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.
269
+ * @param {boolean} [options.returnErrors] - If true, return { graph, errors } instead of throwing. Default: false
270
+ * @returns {Map<string, string[]>|{graph: Map, errors: Error[]}|undefined} - Dependency graph, or { graph, errors } if returnErrors is true. Returns undefined if buildGraph is false.
270
271
  */
271
272
  function depGraph(filePath, options = {}) {
272
273
  const {
@@ -275,12 +276,17 @@ function depGraph(filePath, options = {}) {
275
276
  verifyNodeModules = false,
276
277
  includeNodeModules = false,
277
278
  throwOnFirstError = false,
279
+ returnErrors = false,
278
280
  } = options
279
281
  const errors = []
280
282
  const graph = buildGraph ? new Map() : null
281
283
 
282
284
  buildGraphRecursively(filePath, errors, throwOnFirstError, verifyGraph, verifyNodeModules, includeNodeModules, graph)
283
285
 
286
+ if (returnErrors) {
287
+ return { graph, errors }
288
+ }
289
+
284
290
  if (errors.length > 0) {
285
291
  const errorMessage = errors.map((err, idx) => `Dep graph error:\n ${err.message}`).join('\n')
286
292
  throw new Error(
@@ -298,10 +304,31 @@ function depGraph(filePath, options = {}) {
298
304
  * Get all dependency file paths in build order (dependencies first), deduplicated
299
305
  * @param {string} filePath - Entry file path
300
306
  * @param {object} options - Options to pass to depGraph
301
- * @returns {{ files: string[], nodeModules: string[] }} - Object with files in topological order and unique node_modules
307
+ * @param {boolean} [options.verifyGraph] - If true, verify imports/exports. Default: true
308
+ * @param {boolean} [options.verifyNodeModules] - If true, verify node_modules packages can be resolved. Default: false
309
+ * @param {boolean} [options.throwOnFirstError] - If true, throw immediately on first error. Default: false
310
+ * @param {boolean} [options.returnErrors] - If true, include errors array in result instead of throwing
311
+ * @returns {{ files: string[], nodeModules: string[], errors?: Error[] }} - Object with files in topological order and unique node_modules
302
312
  */
303
313
  function resolveDepPaths(filePath, options = {}) {
304
- const graph = depGraph(filePath, { ...options, includeNodeModules: true })
314
+ const { returnErrors = false, ...restOptions } = options
315
+
316
+ /** @type {Map<string, string[]>} */
317
+ let graph
318
+ /** @type {Error[]} */
319
+ let errors = []
320
+
321
+ if (returnErrors) {
322
+ const result = /** @type {{ graph: Map<string, string[]>, errors: Error[] }} */ (
323
+ depGraph(filePath, { ...restOptions, includeNodeModules: true, returnErrors: true })
324
+ )
325
+ graph = result.graph
326
+ errors = result.errors
327
+ } else {
328
+ graph = /** @type {Map<string, string[]>} */ (
329
+ depGraph(filePath, { ...restOptions, includeNodeModules: true })
330
+ )
331
+ }
305
332
 
306
333
  // Collect node_modules (non-path strings in dependency arrays)
307
334
  const nodeModulesSet = new Set()
@@ -347,10 +374,16 @@ function resolveDepPaths(filePath, options = {}) {
347
374
  }
348
375
  }
349
376
 
350
- return {
377
+ const result = {
351
378
  files: buildOrder,
352
379
  nodeModules: Array.from(nodeModulesSet)
353
380
  }
381
+
382
+ if (returnErrors) {
383
+ result.errors = errors
384
+ }
385
+
386
+ return result
354
387
  }
355
388
 
356
389
 
@@ -438,4 +438,87 @@ test('includeNodeModules works independently of verifyNodeModules', () => {
438
438
  assert.ok(indexDeps.includes('lodash'), 'Should include lodash without verification')
439
439
  })
440
440
 
441
+ // returnErrors tests
442
+ test('returnErrors: true should return { graph, errors } instead of throwing', () => {
443
+ const fs = require('fs')
444
+ const testFile = path.resolve(__dirname, 'fixtures/test-return-errors.js')
445
+
446
+ fs.writeFileSync(testFile, `
447
+ const missing = require('missing-package-xyz')
448
+ module.exports = { missing }
449
+ `)
450
+
451
+ try {
452
+ const result = depGraph(testFile, { verifyNodeModules: true, returnErrors: true })
453
+
454
+ assert.ok(result.graph instanceof Map, 'Should return graph in result')
455
+ assert.ok(Array.isArray(result.errors), 'Should return errors array')
456
+ assert.ok(result.errors.length > 0, 'Should have errors for missing package')
457
+ assert.ok(result.errors[0].message.includes('missing-package-xyz'), 'Error should mention package')
458
+ } finally {
459
+ fs.unlinkSync(testFile)
460
+ }
461
+ })
462
+
463
+ test('returnErrors: true with no errors returns empty errors array', () => {
464
+ const result = depGraph(CJS_FIXTURE_PATH, { returnErrors: true })
465
+
466
+ assert.ok(result.graph instanceof Map, 'Should return graph')
467
+ assert.ok(Array.isArray(result.errors), 'Should return errors array')
468
+ assert.is(result.errors.length, 0, 'Should have no errors')
469
+ })
470
+
471
+ test('returnErrors: true collects all errors without throwing', () => {
472
+ const fs = require('fs')
473
+ const testFile = path.resolve(__dirname, 'fixtures/test-return-multi-errors.js')
474
+
475
+ fs.writeFileSync(testFile, `
476
+ const missing1 = require('missing-pkg-1-xyz')
477
+ const missing2 = require('missing-pkg-2-xyz')
478
+ module.exports = { missing1, missing2 }
479
+ `)
480
+
481
+ try {
482
+ const result = depGraph(testFile, { verifyNodeModules: true, returnErrors: true })
483
+
484
+ assert.is(result.errors.length, 2, 'Should collect both errors')
485
+ assert.ok(result.errors.some(e => e.message.includes('missing-pkg-1-xyz')), 'Should have first error')
486
+ assert.ok(result.errors.some(e => e.message.includes('missing-pkg-2-xyz')), 'Should have second error')
487
+ } finally {
488
+ fs.unlinkSync(testFile)
489
+ }
490
+ })
491
+
492
+ // resolveDepPaths with returnErrors
493
+ test('resolveDepPaths with returnErrors: true returns { files, nodeModules, errors }', () => {
494
+ const fs = require('fs')
495
+ const testFile = path.resolve(__dirname, 'fixtures/test-resolve-return-errors.js')
496
+
497
+ fs.writeFileSync(testFile, `
498
+ const missing = require('missing-resolve-pkg-xyz')
499
+ module.exports = { missing }
500
+ `)
501
+
502
+ try {
503
+ const result = resolveDepPaths(testFile, { verifyNodeModules: true, returnErrors: true })
504
+
505
+ assert.ok(Array.isArray(result.files), 'Should have files array')
506
+ assert.ok(Array.isArray(result.nodeModules), 'Should have nodeModules array')
507
+ assert.ok(Array.isArray(result.errors), 'Should have errors array')
508
+ assert.ok(result.errors.length > 0, 'Should have errors')
509
+ assert.ok(result.errors[0].message.includes('missing-resolve-pkg-xyz'), 'Error should mention package')
510
+ } finally {
511
+ fs.unlinkSync(testFile)
512
+ }
513
+ })
514
+
515
+ test('resolveDepPaths with returnErrors: true and no errors', () => {
516
+ const result = resolveDepPaths(CJS_FIXTURE_PATH, { returnErrors: true })
517
+
518
+ assert.ok(Array.isArray(result.files), 'Should have files')
519
+ assert.ok(Array.isArray(result.nodeModules), 'Should have nodeModules')
520
+ assert.ok(Array.isArray(result.errors), 'Should have errors array')
521
+ assert.is(result.errors.length, 0, 'Should have no errors')
522
+ })
523
+
441
524
  test.run()
@@ -7,7 +7,8 @@
7
7
  * @param {boolean} [options.verifyNodeModules] - If true, verify node_modules packages can be resolved. Default: false
8
8
  * @param {boolean} [options.includeNodeModules] - If true, include node_modules package names in the graph. Default: false
9
9
  * @param {boolean} [options.throwOnFirstError] - If true, throw immediately on first error. Default: 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.
10
+ * @param {boolean} [options.returnErrors] - If true, return { graph, errors } instead of throwing. Default: false
11
+ * @returns {Map<string, string[]>|{graph: Map, errors: Error[]}|undefined} - Dependency graph, or { graph, errors } if returnErrors is true. Returns undefined if buildGraph is false.
11
12
  */
12
13
  export function depGraph(filePath: string, options?: {
13
14
  buildGraph?: boolean;
@@ -15,15 +16,29 @@ export function depGraph(filePath: string, options?: {
15
16
  verifyNodeModules?: boolean;
16
17
  includeNodeModules?: boolean;
17
18
  throwOnFirstError?: boolean;
18
- }): Map<string, string[]> | undefined;
19
+ returnErrors?: boolean;
20
+ }): Map<string, string[]> | {
21
+ graph: Map<any, any>;
22
+ errors: Error[];
23
+ } | undefined;
19
24
  /**
20
25
  * Get all dependency file paths in build order (dependencies first), deduplicated
21
26
  * @param {string} filePath - Entry file path
22
27
  * @param {object} options - Options to pass to depGraph
23
- * @returns {{ files: string[], nodeModules: string[] }} - Object with files in topological order and unique node_modules
28
+ * @param {boolean} [options.verifyGraph] - If true, verify imports/exports. Default: true
29
+ * @param {boolean} [options.verifyNodeModules] - If true, verify node_modules packages can be resolved. Default: false
30
+ * @param {boolean} [options.throwOnFirstError] - If true, throw immediately on first error. Default: false
31
+ * @param {boolean} [options.returnErrors] - If true, include errors array in result instead of throwing
32
+ * @returns {{ files: string[], nodeModules: string[], errors?: Error[] }} - Object with files in topological order and unique node_modules
24
33
  */
25
- export function resolveDepPaths(filePath: string, options?: object): {
34
+ export function resolveDepPaths(filePath: string, options?: {
35
+ verifyGraph?: boolean;
36
+ verifyNodeModules?: boolean;
37
+ throwOnFirstError?: boolean;
38
+ returnErrors?: boolean;
39
+ }): {
26
40
  files: string[];
27
41
  nodeModules: string[];
42
+ errors?: Error[];
28
43
  };
29
44
  //# sourceMappingURL=dep-graph.d.ts.map
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"dep-graph.d.ts","sourceRoot":"","sources":["../src/dep-graph.js"],"names":[],"mappings":"AAmQA;;;;;;;;;;;GAWG;AACH,mCAVW,MAAM,YAEd;IAA0B,UAAU,GAA5B,OAAO;IACW,WAAW,GAA7B,OAAO;IACW,iBAAiB,GAAnC,OAAO;IACW,kBAAkB,GAApC,OAAO;IACW,iBAAiB,GAAnC,OAAO;IACW,YAAY,GAA9B,OAAO;CACf,GAAU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAC;IAAC,KAAK,gBAAM;IAAC,MAAM,EAAE,KAAK,EAAE,CAAA;CAAC,GAAC,SAAS,CA8BzE;AAGD;;;;;;;;;GASG;AACH,0CARW,MAAM,YAEd;IAA0B,WAAW,GAA7B,OAAO;IACW,iBAAiB,GAAnC,OAAO;IACW,iBAAiB,GAAnC,OAAO;IACW,YAAY,GAA9B,OAAO;CACf,GAAU;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;CAAE,CA4ExE"}