@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.
- package/.claude/settings.local.json +2 -1
- package/package.json +1 -1
- package/src/dep-graph.js +37 -4
- package/tests/dep-graph.test.js +83 -0
- package/types/dep-graph.d.ts +19 -4
- package/types/dep-graph.d.ts.map +1 -1
package/package.json
CHANGED
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
|
-
* @
|
|
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
|
-
* @
|
|
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
|
|
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
|
-
|
|
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
|
|
package/tests/dep-graph.test.js
CHANGED
|
@@ -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()
|
package/types/dep-graph.d.ts
CHANGED
|
@@ -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
|
-
* @
|
|
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
|
-
|
|
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
|
-
* @
|
|
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?:
|
|
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
|
package/types/dep-graph.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dep-graph.d.ts","sourceRoot":"","sources":["../src/dep-graph.js"],"names":[],"mappings":"AAmQA
|
|
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"}
|