depvitals 0.0.1 → 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.
Files changed (40) hide show
  1. package/README.md +67 -10
  2. package/dist/cli/index.js +13 -7
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/cli/parseCliArgs.d.ts +37 -0
  5. package/dist/cli/parseCliArgs.d.ts.map +1 -0
  6. package/dist/cli/parseCliArgs.js +85 -0
  7. package/dist/cli/parseCliArgs.js.map +1 -0
  8. package/dist/cli/runCli.d.ts +31 -13
  9. package/dist/cli/runCli.d.ts.map +1 -1
  10. package/dist/cli/runCli.js +76 -84
  11. package/dist/cli/runCli.js.map +1 -1
  12. package/dist/core/analyzeProject.d.ts +92 -0
  13. package/dist/core/analyzeProject.d.ts.map +1 -0
  14. package/dist/core/analyzeProject.js +175 -0
  15. package/dist/core/analyzeProject.js.map +1 -0
  16. package/dist/reporters/terminalReporter.d.ts +49 -0
  17. package/dist/reporters/terminalReporter.d.ts.map +1 -0
  18. package/dist/reporters/terminalReporter.js +98 -0
  19. package/dist/reporters/terminalReporter.js.map +1 -0
  20. package/dist/scanner/moduleSpecifiers.d.ts +60 -0
  21. package/dist/scanner/moduleSpecifiers.d.ts.map +1 -0
  22. package/dist/scanner/moduleSpecifiers.js +824 -0
  23. package/dist/scanner/moduleSpecifiers.js.map +1 -0
  24. package/dist/scanner/packageSpecifier.d.ts +45 -0
  25. package/dist/scanner/packageSpecifier.d.ts.map +1 -0
  26. package/dist/scanner/packageSpecifier.js +98 -0
  27. package/dist/scanner/packageSpecifier.js.map +1 -0
  28. package/dist/scanner/projectManifest.d.ts +72 -0
  29. package/dist/scanner/projectManifest.d.ts.map +1 -0
  30. package/dist/scanner/projectManifest.js +176 -0
  31. package/dist/scanner/projectManifest.js.map +1 -0
  32. package/dist/scanner/scriptUsage.d.ts +54 -0
  33. package/dist/scanner/scriptUsage.d.ts.map +1 -0
  34. package/dist/scanner/scriptUsage.js +490 -0
  35. package/dist/scanner/scriptUsage.js.map +1 -0
  36. package/dist/scanner/sourceFiles.d.ts +52 -0
  37. package/dist/scanner/sourceFiles.d.ts.map +1 -0
  38. package/dist/scanner/sourceFiles.js +190 -0
  39. package/dist/scanner/sourceFiles.js.map +1 -0
  40. package/package.json +3 -1
@@ -0,0 +1,490 @@
1
+ /**
2
+ * Basic package.json script usage detection.
3
+ *
4
+ * This module answers exactly one narrow question: which declared dependencies are referenced by
5
+ * the static strings found in a project's `package.json` `scripts`? It turns those strings into a
6
+ * conservative set of package names that have clear static usage evidence, so later steps can avoid
7
+ * reporting them as unused.
8
+ *
9
+ * It deliberately does not:
10
+ * - execute, expand, substitute, resolve, spawn, source or evaluate anything;
11
+ * - shell-out, read the filesystem or consult `node_modules`;
12
+ * - map arbitrary shell binaries to packages; only the small, explicit `BINARY_TO_PACKAGE` list
13
+ * (currently `tsc` -> `typescript`) is ever translated, and only against declared packages;
14
+ * - report missing dependencies (undeclared command tokens are ignored);
15
+ * - inspect installed `bin` metadata, config, workspaces or framework detectors.
16
+ *
17
+ * The strings are treated as inert text. This module performs no I/O and has no side effects.
18
+ *
19
+ * Recognition is intentionally conservative:
20
+ * - a shell segment's first effective command token counts only when that token is exactly a package
21
+ * name, so paths and package subpaths (`scripts/build.js`, `eslint/bin/cli`) are never usage
22
+ * evidence for the package they point into;
23
+ * - the small explicit `BINARY_TO_PACKAGE` list translates a recognized direct executable (currently
24
+ * `tsc` -> `typescript`) to its declared package; every other command keeps exact-name matching.
25
+ * - the five documented package-runner forms count (`npx`, `npm exec`, `pnpm exec`, `pnpm dlx`,
26
+ * `yarn dlx`) with the package in its immediate position;
27
+ * - leading POSIX environment assignments (`NODE_ENV=test`, `FOO=1 BAR=2`) are skipped;
28
+ * - quoted tokens keep their content, so separators and text inside quotes are not misread.
29
+ *
30
+ * Shell syntax this scanner does not understand invalidates the segment that contains it: single `&`
31
+ * (background execution), redirection (`<`, `>`), command and parameter expansion (`$(...)`,
32
+ * `${...}`), legacy backtick substitution and backslash escapes outside single quotes, plus a quote
33
+ * that is still open at the end of the script. Each such region is consumed as an opaque block, so a
34
+ * separator inside it never delimits the surrounding script. An invalidated segment yields no
35
+ * evidence at all, while the neighbouring segments delimited by real supported separators are still
36
+ * analyzed normally.
37
+ */
38
+ import { classifyPackageSpecifier } from './packageSpecifier.js';
39
+ /**
40
+ * Package-manager command words that are never evidence that the manager itself is a used dependency.
41
+ *
42
+ * Invoked without a supported runner form (for example `npm run build`, `pnpm test`, `yarn lint`),
43
+ * they do not prove usage of a declared dependency. The package they actually run (if any) is what
44
+ * may count, and only through the supported runner forms above.
45
+ */
46
+ const PACKAGE_MANAGER_COMMANDS = new Set(['npm', 'pnpm', 'yarn', 'npx']);
47
+ /**
48
+ * Leading POSIX-style environment assignment prefix, e.g. `NODE_ENV=`, `FOO=`.
49
+ *
50
+ * Only the name part is matched; the value (quoted or not) is consumed by the tokenizer.
51
+ */
52
+ const ASSIGNMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*=/;
53
+ /**
54
+ * Explicit static executable -> declared-package mappings for supported direct command positions.
55
+ *
56
+ * A shell command position carries binaries and file paths, not package names, so this list is
57
+ * strictly opt-in: each executable here is known to provide exactly the mapped package.
58
+ * - `tsc` is the compiler front-end of the `typescript` package; the deprecated standalone `tsc`
59
+ * npm package is intentionally NOT treated as providing the TypeScript compiler.
60
+ * - `docsify` is the executable provided by the `docsify-cli` package.
61
+ * Only lowercase `tsc` and `docsify` map; runner forms such as `npx tsc` or `npx docsify` keep their
62
+ * own (unmapped) semantics for now.
63
+ *
64
+ * The mapping is applied after safe command extraction and can only match a package that is actually
65
+ * declared, so it can never create a missing-dependency finding. When both a bare package name and
66
+ * its mapped package are declared (for example `docsify` and `docsify-cli`), only the declared
67
+ * mapped package (`docsify-cli`) receives this evidence; the bare `docsify` package is unaffected
68
+ * unless independent source or script evidence supports it.
69
+ */
70
+ const BINARY_TO_PACKAGE = new Map([
71
+ ['tsc', 'typescript'],
72
+ ['docsify', 'docsify-cli'],
73
+ ]);
74
+ /**
75
+ * Recognize the declared dependencies that `package.json` scripts clearly reference.
76
+ *
77
+ * For every script command the module collects the package names that have clear static usage
78
+ * evidence (a command token, a recognized executable mapped through `BINARY_TO_PACKAGE`, or a
79
+ * supported runner package position) and keeps only those that are present in
80
+ * {@link declaredPackageNames}. Undeclared command tokens and undeclared mapped packages are ignored:
81
+ * this module never creates missing-dependency findings.
82
+ *
83
+ * The result is built in alphabetical package-name order so iteration is deterministic. Neither
84
+ * {@link scripts} nor {@link declaredPackageNames} is mutated.
85
+ *
86
+ * @param scripts - `package.json` `scripts` entries as static strings (never executed).
87
+ * @param declaredPackageNames - the declared dependency names that may be suppressed as used.
88
+ */
89
+ export function findPackageScriptUsage(scripts, declaredPackageNames) {
90
+ const used = new Set();
91
+ for (const command of Object.values(scripts)) {
92
+ for (const candidate of collectScriptCandidates(command)) {
93
+ if (declaredPackageNames.has(candidate)) {
94
+ used.add(candidate);
95
+ }
96
+ }
97
+ }
98
+ return new Set([...used].sort(compareNames));
99
+ }
100
+ /**
101
+ * Collect the package-name candidates referenced by a single script command.
102
+ *
103
+ * Each shell segment contributes at most one candidate: the package supplied to a supported runner
104
+ * form, or the segment's first effective command token when that token is exactly a package name.
105
+ * Segments containing unsupported shell syntax contribute nothing.
106
+ */
107
+ function collectScriptCandidates(command) {
108
+ const candidates = [];
109
+ for (const segment of splitSegments(command)) {
110
+ // An unsupported segment is never partially trusted, not even its leading command.
111
+ if (segment.unsupported) {
112
+ continue;
113
+ }
114
+ const significant = skipLeadingAssignments(segment.tokens);
115
+ if (significant.length === 0) {
116
+ continue;
117
+ }
118
+ const runnerPackage = matchRunnerPackage(significant);
119
+ if (runnerPackage !== undefined) {
120
+ candidates.push(runnerPackage);
121
+ continue;
122
+ }
123
+ // A package manager invoked without a supported runner form is never evidence that the manager
124
+ // itself is a used dependency.
125
+ const commandName = significant[0]?.value;
126
+ if (commandName === undefined) {
127
+ continue;
128
+ }
129
+ if (PACKAGE_MANAGER_COMMANDS.has(commandName)) {
130
+ continue;
131
+ }
132
+ // Only the first effective command token is inspected, and it must be exactly the package root.
133
+ // Shell command position carries binaries and file paths, so a package subpath such as
134
+ // `eslint/bin/cli` or a script path such as `scripts/build.js` is never usage evidence.
135
+ const classification = classifyPackageSpecifier(commandName);
136
+ if (classification.kind === 'external' && commandName === classification.packageName) {
137
+ // An explicit executable mapping takes precedence over same-name matching: `tsc` resolves to
138
+ // the declared `typescript` package only, never to a hypothetical `tsc` package, so a single
139
+ // executable yields at most one piece of usage evidence.
140
+ const mapped = BINARY_TO_PACKAGE.get(commandName);
141
+ candidates.push(mapped ?? commandName);
142
+ }
143
+ }
144
+ return candidates;
145
+ }
146
+ /**
147
+ * Drop leading `VAR=value` assignments so the first real command token can be inspected.
148
+ */
149
+ function skipLeadingAssignments(segment) {
150
+ let index = 0;
151
+ while (index < segment.length) {
152
+ const token = segment[index];
153
+ if (token === undefined || !ASSIGNMENT_PATTERN.test(token.value)) {
154
+ break;
155
+ }
156
+ index += 1;
157
+ }
158
+ return segment.slice(index);
159
+ }
160
+ /**
161
+ * Recognize the package position of the five supported runner forms.
162
+ *
163
+ * Returns the package token only when it appears in the expected immediate position. Forms that add
164
+ * flags, `--package` options or version/tags (for example `npx --no-install eslint`) return
165
+ * `undefined` and fall back to command-token handling.
166
+ */
167
+ function matchRunnerPackage(significant) {
168
+ const command = significant[0]?.value;
169
+ if (command === 'npx') {
170
+ return significant[1]?.value;
171
+ }
172
+ if (command === 'npm') {
173
+ return significant[1]?.value === 'exec' ? significant[2]?.value : undefined;
174
+ }
175
+ if (command === 'pnpm') {
176
+ const subcommand = significant[1]?.value;
177
+ return subcommand === 'exec' || subcommand === 'dlx' ? significant[2]?.value : undefined;
178
+ }
179
+ if (command === 'yarn') {
180
+ return significant[1]?.value === 'dlx' ? significant[2]?.value : undefined;
181
+ }
182
+ return undefined;
183
+ }
184
+ /**
185
+ * Split a script string into segments on the supported separators (`&&`, `||`, `;`, `|`, newline
186
+ * outside quotes).
187
+ *
188
+ * The scanner only needs enough shell awareness to preserve quoted tokens, to keep separators and
189
+ * text inside quotes from being misread, and to detect the syntax it refuses to interpret. It never
190
+ * executes, expands or substitutes anything.
191
+ *
192
+ * Unsupported constructs (single `&`, redirection, `$(...)`, `${...}`, quotes left open at the end of
193
+ * the script) mark the current segment as unsupported instead of guessing tokens from inside it. The
194
+ * marker is reset by the next real separator, so invalidation stays local to the affected segment.
195
+ */
196
+ function splitSegments(script) {
197
+ const segments = [];
198
+ let tokens = [];
199
+ let unsupported = false;
200
+ let i = 0;
201
+ const length = script.length;
202
+ // A real separator ends the current segment and clears its unsupported marker.
203
+ const flush = () => {
204
+ segments.push({ tokens, unsupported });
205
+ tokens = [];
206
+ unsupported = false;
207
+ };
208
+ while (i < length) {
209
+ const ch = script[i];
210
+ if (ch === undefined) {
211
+ break;
212
+ }
213
+ // Whitespace separates tokens within a segment.
214
+ if (isWhitespace(ch)) {
215
+ i += 1;
216
+ continue;
217
+ }
218
+ // Supported separators. `&&`/`||` are two-character; `;`, `|` and newline are single-character.
219
+ if (ch === ';' || ch === '\n') {
220
+ i += 1;
221
+ flush();
222
+ continue;
223
+ }
224
+ if (ch === '|') {
225
+ i += script[i + 1] === '|' ? 2 : 1;
226
+ flush();
227
+ continue;
228
+ }
229
+ // A single `&` is background execution, which is unsupported in v0.1.0. It deliberately does not
230
+ // behave like `&&`: it never splits the segment, it only invalidates it, so `eslint & prettier`
231
+ // yields no evidence instead of two independently trusted commands.
232
+ if (ch === '&') {
233
+ if (script[i + 1] === '&') {
234
+ i += 2;
235
+ flush();
236
+ }
237
+ else {
238
+ i += 1;
239
+ unsupported = true;
240
+ }
241
+ continue;
242
+ }
243
+ // Every other character starts an unquoted token. The token scan consumes exactly the characters
244
+ // of one token, so it always advances at least one position here.
245
+ const scanned = scanToken(script, i);
246
+ if (scanned.unsupported) {
247
+ unsupported = true;
248
+ }
249
+ if (scanned.text.length > 0) {
250
+ tokens = [...tokens, { value: scanned.text }];
251
+ }
252
+ i = scanned.next;
253
+ }
254
+ segments.push({ tokens, unsupported });
255
+ return segments;
256
+ }
257
+ /**
258
+ * Scan a single unquoted token starting at `start`.
259
+ *
260
+ * Quoted runs inside the token are consumed with their content kept verbatim, so `"eslint"`,
261
+ * `FOO="a;b"` and `echo "a && b"` tokenize safely. Redirection and shell expansion are reported as
262
+ * unsupported rather than interpreted, and a quote left open at the end of the script drops the
263
+ * partially accumulated token entirely.
264
+ */
265
+ function scanToken(script, start) {
266
+ let value = '';
267
+ let unsupported = false;
268
+ let i = start;
269
+ while (i < script.length) {
270
+ const ch = script[i];
271
+ if (ch === undefined) {
272
+ break;
273
+ }
274
+ if (isWhitespace(ch) || ch === ';' || ch === '\n' || ch === '|' || ch === '&') {
275
+ break;
276
+ }
277
+ // Redirection is not parsed in v0.1.0; its presence alone invalidates the segment.
278
+ if (ch === '<' || ch === '>') {
279
+ unsupported = true;
280
+ i += 1;
281
+ continue;
282
+ }
283
+ // `$(...)`, `${...}` and backticks are never parsed or expanded here. The whole region is
284
+ // consumed as an opaque block so that separators (`;`, `|`, `&&`, newline) found inside it can
285
+ // never reach the outer segment logic and flush the current segment.
286
+ if (isUnsupportedRegionStart(script, i)) {
287
+ unsupported = true;
288
+ i = skipUnsupportedRegion(script, i);
289
+ continue;
290
+ }
291
+ // Outside single quotes a backslash escapes the following character, so that character can never
292
+ // act as a separator. The pair is consumed together; its exact meaning is irrelevant here.
293
+ if (ch === '\\') {
294
+ unsupported = true;
295
+ value += ch + (script[i + 1] ?? '');
296
+ i += 2;
297
+ continue;
298
+ }
299
+ if (ch === '"' || ch === "'") {
300
+ const run = scanQuoted(script, i + 1, ch);
301
+ if (run.open) {
302
+ // EOF before the quote closes: the segment is invalid and the partial token is dropped.
303
+ return { text: '', next: run.next, unsupported: true };
304
+ }
305
+ if (run.expands) {
306
+ unsupported = true;
307
+ }
308
+ value += run.text;
309
+ i = run.next;
310
+ continue;
311
+ }
312
+ value += ch;
313
+ i += 1;
314
+ }
315
+ return { text: value, next: i, unsupported };
316
+ }
317
+ /**
318
+ * Consume a quoted run, keeping its content verbatim.
319
+ *
320
+ * Separators and redirection characters inside quotes stay literal text. Single quotes are fully
321
+ * literal. Inside double quotes `$(...)`, `${...}`, backticks and a backslash count as expansion or
322
+ * escape and invalidate the segment; each such region is still consumed as an opaque block. Newlines
323
+ * are literal in both quote forms, so a quoted string may span several lines; only an unclosed quote
324
+ * at the end of the script is malformed.
325
+ */
326
+ function scanQuoted(script, start, quote) {
327
+ const doubleQuoted = quote === '"';
328
+ let text = '';
329
+ let expands = false;
330
+ let i = start;
331
+ while (i < script.length) {
332
+ const ch = script[i];
333
+ if (ch === undefined) {
334
+ break;
335
+ }
336
+ if (ch === quote) {
337
+ return { text, next: i + 1, open: false, expands };
338
+ }
339
+ if (doubleQuoted && isUnsupportedRegionStart(script, i)) {
340
+ // Inside double quotes, `$(...)`, `${...}` and backticks are real expansion. The region is
341
+ // consumed as an opaque block so its inner separators never reach the outer segment, while the
342
+ // expansion itself still invalidates the segment.
343
+ expands = true;
344
+ i = skipUnsupportedRegion(script, i);
345
+ continue;
346
+ }
347
+ // Inside double quotes a backslash escapes the following character, so that character can never
348
+ // close the quoted run. The pair is consumed together and invalidates the segment.
349
+ if (doubleQuoted && ch === '\\') {
350
+ expands = true;
351
+ text += ch + (script[i + 1] ?? '');
352
+ i += 2;
353
+ continue;
354
+ }
355
+ text += ch;
356
+ i += 1;
357
+ }
358
+ return { text, next: i, open: true, expands };
359
+ }
360
+ /**
361
+ * Whether the character right after `$` opens a shell expansion (`$(` or `${`).
362
+ */
363
+ function opensExpansion(next) {
364
+ return next === '(' || next === '{';
365
+ }
366
+ /**
367
+ * Whether an unsupported opaque region starts at `index`: `$(`, `${` or a legacy backtick.
368
+ */
369
+ function isUnsupportedRegionStart(script, index) {
370
+ const ch = script[index];
371
+ if (ch === '`') {
372
+ return true;
373
+ }
374
+ return ch === '$' && opensExpansion(script[index + 1]);
375
+ }
376
+ /**
377
+ * Skip one unsupported shell region starting at `start`, which must point at `$(`, `${` or a
378
+ * backtick, and return the index just past its matching closing delimiter.
379
+ *
380
+ * The region is consumed opaquely: its contents are never interpreted, so separators found inside it
381
+ * can never flush the outer segment. Every open region is pushed onto a stack, which keeps mixed
382
+ * nesting balanced (`${A:-$(...)}`, `$(echo ${X})`, ``${X:-`cmd`}``) no matter which delimiter type
383
+ * opened it. Quoted runs are stack entries too, so a closing delimiter inside a quote never ends a
384
+ * region early, and a backslash consumes the character after it so an escaped `\)`, `\}` or backtick
385
+ * cannot close a region either. A single quote is literal text inside a double-quoted run, which is
386
+ * the one quote form that does not nest.
387
+ *
388
+ * If EOF is reached first the region is unterminated and `script.length` is returned, leaving the
389
+ * current outer segment unsupported. This never interprets shell semantics; it only locates opaque
390
+ * region boundaries safely.
391
+ */
392
+ function skipUnsupportedRegion(script, start) {
393
+ const length = script.length;
394
+ const stack = [];
395
+ const first = script[start];
396
+ const second = script[start + 1];
397
+ let i;
398
+ if (first === '`') {
399
+ stack.push('`');
400
+ i = start + 1;
401
+ }
402
+ else if (first === '$' && (second === '(' || second === '{')) {
403
+ stack.push(second === '(' ? ')' : '}');
404
+ i = start + 2;
405
+ }
406
+ else {
407
+ // Not a region opener; advance by one so a caller can never loop forever.
408
+ return start + 1;
409
+ }
410
+ while (i < length && stack.length > 0) {
411
+ const ch = script[i];
412
+ if (ch === undefined) {
413
+ break;
414
+ }
415
+ const top = stack.at(-1);
416
+ // Inside single quotes everything is literal, so only the closing single quote is special.
417
+ if (top === "'") {
418
+ if (ch === "'") {
419
+ stack.pop();
420
+ }
421
+ i += 1;
422
+ continue;
423
+ }
424
+ // A backslash consumes the next character in `$()`, `${}`, backticks and double quotes.
425
+ if (ch === '\\') {
426
+ i += 2;
427
+ continue;
428
+ }
429
+ if (ch === "'" || ch === '"') {
430
+ // A single quote is literal text inside a double-quoted run, so it must never open a region of
431
+ // its own. Doing so would keep the outer double quote open until EOF and hide the separators
432
+ // that follow it.
433
+ if (ch === "'" && top === '"') {
434
+ i += 1;
435
+ continue;
436
+ }
437
+ // A double quote closes only the quoted run it opened; any other quote opens a literal run.
438
+ if (ch === '"' && top === '"') {
439
+ stack.pop();
440
+ }
441
+ else {
442
+ stack.push(ch);
443
+ }
444
+ i += 1;
445
+ continue;
446
+ }
447
+ const next = script[i + 1];
448
+ if (ch === '$' && opensExpansion(next)) {
449
+ stack.push(next === '(' ? ')' : '}');
450
+ i += 2;
451
+ continue;
452
+ }
453
+ if (ch === '`') {
454
+ if (top === '`') {
455
+ stack.pop();
456
+ }
457
+ else {
458
+ stack.push('`');
459
+ }
460
+ i += 1;
461
+ continue;
462
+ }
463
+ // `)` and `}` close only a matching region; otherwise they are inert region content.
464
+ if ((ch === ')' || ch === '}') && ch === top) {
465
+ stack.pop();
466
+ }
467
+ i += 1;
468
+ }
469
+ // An empty stack means the outermost region closed just before `i`; otherwise EOF arrived first.
470
+ return stack.length === 0 ? i : length;
471
+ }
472
+ /**
473
+ * Whether a character is whitespace (spaces, tabs, CR, FF, VT).
474
+ */
475
+ function isWhitespace(ch) {
476
+ return ch === ' ' || ch === '\t' || ch === '\r' || ch === '\f' || ch === '\v';
477
+ }
478
+ /**
479
+ * Locale-independent lexicographic ordering, so the same scripts always yield the same order.
480
+ */
481
+ function compareNames(a, b) {
482
+ if (a < b) {
483
+ return -1;
484
+ }
485
+ if (a > b) {
486
+ return 1;
487
+ }
488
+ return 0;
489
+ }
490
+ //# sourceMappingURL=scriptUsage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scriptUsage.js","sourceRoot":"","sources":["../../src/scanner/scriptUsage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Source file discovery.
3
+ *
4
+ * This module answers exactly one question: "which source files should DepVitals inspect?". It
5
+ * walks a single Node.js project tree and returns the supported JavaScript/TypeScript files without
6
+ * parsing them.
7
+ *
8
+ * It deliberately does not:
9
+ * - read, parse or execute any discovered file (that belongs to the analyzers / specifier extractor);
10
+ * - decide whether anything is used, unused or missing;
11
+ * - parse `.gitignore` or honor custom ignore configuration (`v0.1.0` uses a fixed built-in set);
12
+ * - follow symlinks, which avoids cycles and scanning content outside the intended project tree;
13
+ * - mutate the analyzed project.
14
+ *
15
+ * Traversal uses `fs.readdir` with `withFileTypes` so ignored directories are pruned before descent
16
+ * instead of walking every subtree and filtering afterwards. The result is sorted deterministically
17
+ * so the same tree always yields the same order.
18
+ */
19
+ /**
20
+ * A discovered source file as an absolute, platform-separated path, sorted lexicographically.
21
+ */
22
+ export type DiscoveredSourceFile = string;
23
+ /**
24
+ * Why source discovery could not run.
25
+ *
26
+ * - `missing`: the project root does not exist.
27
+ * - `not-a-directory`: the project root exists but is a regular file.
28
+ * - `unreadable`: the root exists, or a nested directory, could not be read (permissions, I/O
29
+ * error, ...).
30
+ */
31
+ export type SourceFilesErrorCode = 'missing' | 'not-a-directory' | 'unreadable';
32
+ /**
33
+ * Operational error for source discovery. The `code` lets callers (the CLI in a later step) render
34
+ * a clean message without matching on error strings.
35
+ */
36
+ export declare class SourceFilesError extends Error {
37
+ readonly code: SourceFilesErrorCode;
38
+ constructor(message: string, code: SourceFilesErrorCode, cause?: unknown);
39
+ }
40
+ /**
41
+ * Discover the supported JavaScript/TypeScript source files of the project rooted at `projectRoot`.
42
+ *
43
+ * The supplied root is resolved to an absolute path; `process.cwd()` is never changed and the
44
+ * target project is never read as code or written to.
45
+ *
46
+ * The returned paths are absolute and sorted lexicographically so the same tree always yields the
47
+ * same order.
48
+ *
49
+ * @throws {SourceFilesError} when the root is missing, is not a directory, or cannot be read.
50
+ */
51
+ export declare function discoverSourceFiles(projectRoot: string): Promise<readonly DiscoveredSourceFile[]>;
52
+ //# sourceMappingURL=sourceFiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceFiles.d.ts","sourceRoot":"","sources":["../../src/scanner/sourceFiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AA2CH;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,iBAAiB,GAAG,YAAY,CAAC;AAEhF;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;gBAExB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,OAAO;CAKzE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAY1C"}