depvitals 0.3.0 → 0.4.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 (77) hide show
  1. package/README.md +72 -3
  2. package/dist/cli/entry.js +8 -21
  3. package/dist/cli/entry.js.map +1 -1
  4. package/dist/cli/parseCliArgs.d.ts +5 -2
  5. package/dist/cli/parseCliArgs.d.ts.map +1 -1
  6. package/dist/cli/parseCliArgs.js +51 -36
  7. package/dist/cli/parseCliArgs.js.map +1 -1
  8. package/dist/cli/runCli.d.ts +4 -5
  9. package/dist/cli/runCli.d.ts.map +1 -1
  10. package/dist/cli/runCli.js +39 -49
  11. package/dist/cli/runCli.js.map +1 -1
  12. package/dist/config/ignoreDependencies.d.ts +2 -0
  13. package/dist/config/ignoreDependencies.d.ts.map +1 -1
  14. package/dist/config/ignoreDependencies.js +5 -1
  15. package/dist/config/ignoreDependencies.js.map +1 -1
  16. package/dist/config/readProjectConfig.d.ts +5 -0
  17. package/dist/config/readProjectConfig.d.ts.map +1 -1
  18. package/dist/config/readProjectConfig.js +24 -10
  19. package/dist/config/readProjectConfig.js.map +1 -1
  20. package/dist/core/analyzeProject.d.ts +35 -0
  21. package/dist/core/analyzeProject.d.ts.map +1 -1
  22. package/dist/core/analyzeProject.js +161 -25
  23. package/dist/core/analyzeProject.js.map +1 -1
  24. package/dist/core/evidence.d.ts +67 -0
  25. package/dist/core/evidence.d.ts.map +1 -0
  26. package/dist/core/evidence.js +115 -0
  27. package/dist/core/evidence.js.map +1 -0
  28. package/dist/core/scanContext.d.ts +20 -0
  29. package/dist/core/scanContext.d.ts.map +1 -0
  30. package/dist/core/scanContext.js +43 -0
  31. package/dist/core/scanContext.js.map +1 -0
  32. package/dist/detectors/eslintManifestConfig.d.ts +18 -0
  33. package/dist/detectors/eslintManifestConfig.d.ts.map +1 -1
  34. package/dist/detectors/eslintManifestConfig.js +55 -76
  35. package/dist/detectors/eslintManifestConfig.js.map +1 -1
  36. package/dist/detectors/eslintRcJsonConfig.d.ts +8 -2
  37. package/dist/detectors/eslintRcJsonConfig.d.ts.map +1 -1
  38. package/dist/detectors/eslintRcJsonConfig.js +25 -11
  39. package/dist/detectors/eslintRcJsonConfig.js.map +1 -1
  40. package/dist/detectors/jestManifestConfig.d.ts +15 -3
  41. package/dist/detectors/jestManifestConfig.d.ts.map +1 -1
  42. package/dist/detectors/jestManifestConfig.js +57 -79
  43. package/dist/detectors/jestManifestConfig.js.map +1 -1
  44. package/dist/reporters/jsonReporter.d.ts +39 -0
  45. package/dist/reporters/jsonReporter.d.ts.map +1 -0
  46. package/dist/reporters/jsonReporter.js +91 -0
  47. package/dist/reporters/jsonReporter.js.map +1 -0
  48. package/dist/reporters/terminalReporter.d.ts +15 -4
  49. package/dist/reporters/terminalReporter.d.ts.map +1 -1
  50. package/dist/reporters/terminalReporter.js +64 -4
  51. package/dist/reporters/terminalReporter.js.map +1 -1
  52. package/dist/scanner/moduleSpecifiers.d.ts +10 -0
  53. package/dist/scanner/moduleSpecifiers.d.ts.map +1 -1
  54. package/dist/scanner/moduleSpecifiers.js +46 -8
  55. package/dist/scanner/moduleSpecifiers.js.map +1 -1
  56. package/dist/scanner/projectManifest.d.ts +9 -0
  57. package/dist/scanner/projectManifest.d.ts.map +1 -1
  58. package/dist/scanner/projectManifest.js +7 -1
  59. package/dist/scanner/projectManifest.js.map +1 -1
  60. package/dist/scanner/scriptUsage.d.ts +13 -0
  61. package/dist/scanner/scriptUsage.d.ts.map +1 -1
  62. package/dist/scanner/scriptUsage.js +102 -32
  63. package/dist/scanner/scriptUsage.js.map +1 -1
  64. package/dist/scanner/sourceFiles.d.ts +5 -0
  65. package/dist/scanner/sourceFiles.d.ts.map +1 -1
  66. package/dist/scanner/sourceFiles.js +7 -0
  67. package/dist/scanner/sourceFiles.js.map +1 -1
  68. package/package.json +4 -2
  69. package/schemas/README.md +47 -0
  70. package/schemas/examples/README.md +27 -0
  71. package/schemas/examples/explain-excluded.json +53 -0
  72. package/schemas/examples/explain-missing.json +65 -0
  73. package/schemas/examples/explain-node-preload.json +70 -0
  74. package/schemas/examples/explain-unknown.json +53 -0
  75. package/schemas/examples/scan-clean.json +40 -0
  76. package/schemas/examples/scan-findings.json +80 -0
  77. package/schemas/report-v1.schema.json +376 -0
@@ -43,13 +43,47 @@ export class ModuleSpecifierError extends Error {
43
43
  * from which the scanner cannot safely continue.
44
44
  */
45
45
  export function extractModuleSpecifiers(source, options = {}) {
46
+ return collectModuleSpecifiers(source, options).map(({ specifier, kind }) => ({
47
+ specifier,
48
+ kind,
49
+ }));
50
+ }
51
+ /**
52
+ * Authoritative occurrence collector. The lexer must finish successfully before locations escape.
53
+ * Recognition is shared with the legacy projection above; no additional extraction is performed.
54
+ */
55
+ export function collectModuleSpecifiers(source, options = {}) {
46
56
  const jsx = options.jsx ?? false;
47
57
  // Ambiguous input gets one non-interpreting lexical probe and one definitive extraction. No
48
58
  // source reread, parser retry after an exception, or repeated per-statement suffix scans.
49
59
  const module = options.module === 'detect'
50
60
  ? tokenize(source, jsx, false, true).some((token) => token.moduleSignal === true)
51
61
  : (options.module ?? false);
52
- return interpret(tokenize(source, jsx, module));
62
+ const occurrences = interpret(tokenize(source, jsx, module));
63
+ let cursor = 0;
64
+ let line = 1;
65
+ let column = 1;
66
+ // Interpreter output is in literal encounter order. Each original UTF-16 unit is visited at
67
+ // most once, except a bounded CRLF lookahead; no per-occurrence prefix/suffix scan is needed.
68
+ return occurrences.map(({ specifier, kind, offset }) => {
69
+ while (cursor < offset) {
70
+ const character = source[cursor++];
71
+ if (character === '\r') {
72
+ if (source[cursor] === '\n')
73
+ cursor++;
74
+ line++;
75
+ column = 1;
76
+ }
77
+ else if (character === '\n' || character === '\u2028' || character === '\u2029') {
78
+ line++;
79
+ column = 1;
80
+ }
81
+ else {
82
+ column++;
83
+ }
84
+ }
85
+ return { specifier, kind, position: { offset, line, column } };
86
+ });
53
87
  }
54
88
  /**
55
89
  * Turn source into a stream of significant tokens, skipping whitespace, line/block comments, regex
@@ -3231,14 +3265,18 @@ function handleImport(tokens, i, occurrences, closingDelimiter) {
3231
3265
  }
3232
3266
  // `import 'pkg'`
3233
3267
  if (next?.kind === 'string') {
3234
- occurrences.push({ specifier: next.value, kind: 'import' });
3268
+ occurrences.push({ specifier: next.value, kind: 'import', offset: next.offset });
3235
3269
  return i + 2;
3236
3270
  }
3237
3271
  // Keep literal specifiers with sole-argument or bounded object-literal options forms.
3238
3272
  if (next?.kind === 'punct' && next.value === '(') {
3239
3273
  const specifier = dynamicImportSpecifier(tokens, i + 2, closingDelimiter);
3240
3274
  if (specifier !== undefined) {
3241
- occurrences.push({ specifier, kind: 'dynamic-import' });
3275
+ occurrences.push({
3276
+ specifier: specifier.value,
3277
+ kind: 'dynamic-import',
3278
+ offset: specifier.offset,
3279
+ });
3242
3280
  return i + 3;
3243
3281
  }
3244
3282
  return i + 1;
@@ -3261,7 +3299,7 @@ function scanImportSource(tokens, i, occurrences, kind) {
3261
3299
  const sourceIndex = kind === 'export-from' ? exportSourceIndex(tokens, i) : importSourceIndex(tokens, i);
3262
3300
  const source = sourceIndex === undefined ? undefined : tokens[sourceIndex];
3263
3301
  if (source?.kind === 'string' && sourceIndex !== undefined) {
3264
- occurrences.push({ specifier: source.value, kind });
3302
+ occurrences.push({ specifier: source.value, kind, offset: source.offset });
3265
3303
  return sourceIndex + 1;
3266
3304
  }
3267
3305
  return i + 1;
@@ -3395,7 +3433,7 @@ function handleRequire(tokens, i, occurrences) {
3395
3433
  if (next?.kind === 'punct' && next.value === '(') {
3396
3434
  const specifier = soleStringSpecifier(tokens, i + 2);
3397
3435
  if (specifier !== undefined) {
3398
- occurrences.push({ specifier, kind: 'require' });
3436
+ occurrences.push({ specifier: specifier.value, kind: 'require', offset: specifier.offset });
3399
3437
  return i + 3;
3400
3438
  }
3401
3439
  }
@@ -3543,10 +3581,10 @@ function dynamicImportSpecifier(tokens, argIndex, closingDelimiter) {
3543
3581
  return undefined;
3544
3582
  }
3545
3583
  const next = isPunct(tokens[optionsClose + 1], ',') ? optionsClose + 2 : optionsClose + 1;
3546
- return isPunct(tokens[next], ')') ? specifier.value : undefined;
3584
+ return isPunct(tokens[next], ')') ? specifier : undefined;
3547
3585
  }
3548
3586
  /**
3549
- * The decoded string at `argIndex` when it is the only argument of the surrounding call, that is
3587
+ * The string token at `argIndex` when it is the only argument of the surrounding call, that is
3550
3588
  * when it is a string followed by an optional trailing comma and `)`. Returns undefined otherwise,
3551
3589
  * so a dynamic argument (e.g. `'pkg-' + name`) or a call with extra arguments (e.g.
3552
3590
  * `require('pkg', ctx)`) never yields a static specifier.
@@ -3561,7 +3599,7 @@ function soleStringSpecifier(tokens, argIndex) {
3561
3599
  if (closing?.kind !== 'punct' || closing.value !== ')') {
3562
3600
  return undefined;
3563
3601
  }
3564
- return arg.value;
3602
+ return arg;
3565
3603
  }
3566
3604
  /* -------------------------------------------------------------------------- */
3567
3605
  /* Lexical constructs */