svelte-docinfo 0.1.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.
- package/LICENSE +21 -0
- package/README.md +349 -0
- package/dist/analyze-core.d.ts +1386 -0
- package/dist/analyze-core.d.ts.map +1 -0
- package/dist/analyze-core.js +324 -0
- package/dist/analyze.d.ts +137 -0
- package/dist/analyze.d.ts.map +1 -0
- package/dist/analyze.js +148 -0
- package/dist/cli.d.ts +102 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +206 -0
- package/dist/concurrency.d.ts +38 -0
- package/dist/concurrency.d.ts.map +1 -0
- package/dist/concurrency.js +57 -0
- package/dist/declaration-build.d.ts +164 -0
- package/dist/declaration-build.d.ts.map +1 -0
- package/dist/declaration-build.js +15 -0
- package/dist/declaration-helpers.d.ts +169 -0
- package/dist/declaration-helpers.d.ts.map +1 -0
- package/dist/declaration-helpers.js +239 -0
- package/dist/dep-resolver.d.ts +166 -0
- package/dist/dep-resolver.d.ts.map +1 -0
- package/dist/dep-resolver.js +144 -0
- package/dist/diagnostics.d.ts +650 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +377 -0
- package/dist/discovery.d.ts +115 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +126 -0
- package/dist/exports.d.ts +105 -0
- package/dist/exports.d.ts.map +1 -0
- package/dist/exports.js +274 -0
- package/dist/files.d.ts +77 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +95 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/log.d.ts +32 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +11 -0
- package/dist/logo.d.ts +8 -0
- package/dist/logo.d.ts.map +1 -0
- package/dist/logo.js +9 -0
- package/dist/main.d.ts +11 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +18 -0
- package/dist/paths.d.ts +35 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +34 -0
- package/dist/postprocess.d.ts +145 -0
- package/dist/postprocess.d.ts.map +1 -0
- package/dist/postprocess.js +305 -0
- package/dist/session.d.ts +248 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +496 -0
- package/dist/source-config.d.ts +330 -0
- package/dist/source-config.d.ts.map +1 -0
- package/dist/source-config.js +356 -0
- package/dist/source.d.ts +126 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +68 -0
- package/dist/svelte.d.ts +179 -0
- package/dist/svelte.d.ts.map +1 -0
- package/dist/svelte.js +898 -0
- package/dist/tsdoc.d.ts +145 -0
- package/dist/tsdoc.d.ts.map +1 -0
- package/dist/tsdoc.js +262 -0
- package/dist/types.d.ts +3381 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +588 -0
- package/dist/typescript-exports.d.ts +91 -0
- package/dist/typescript-exports.d.ts.map +1 -0
- package/dist/typescript-exports.js +656 -0
- package/dist/typescript-extract-class.d.ts +29 -0
- package/dist/typescript-extract-class.d.ts.map +1 -0
- package/dist/typescript-extract-class.js +251 -0
- package/dist/typescript-extract-function.d.ts +47 -0
- package/dist/typescript-extract-function.d.ts.map +1 -0
- package/dist/typescript-extract-function.js +108 -0
- package/dist/typescript-extract-shared.d.ts +166 -0
- package/dist/typescript-extract-shared.d.ts.map +1 -0
- package/dist/typescript-extract-shared.js +528 -0
- package/dist/typescript-extract-type-properties.d.ts +34 -0
- package/dist/typescript-extract-type-properties.d.ts.map +1 -0
- package/dist/typescript-extract-type-properties.js +241 -0
- package/dist/typescript-extract-type.d.ts +48 -0
- package/dist/typescript-extract-type.d.ts.map +1 -0
- package/dist/typescript-extract-type.js +238 -0
- package/dist/typescript-program.d.ts +211 -0
- package/dist/typescript-program.d.ts.map +1 -0
- package/dist/typescript-program.js +290 -0
- package/dist/vite.d.ts +116 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +418 -0
- package/package.json +131 -0
- package/virtual-svelte-docinfo.d.ts +49 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source configuration, path extraction, and file filtering.
|
|
3
|
+
*
|
|
4
|
+
* Provides `ModuleSourceOptions` configuration management and functions
|
|
5
|
+
* that operate on source files using those options: path extraction,
|
|
6
|
+
* source detection, dependency filtering, and file collection.
|
|
7
|
+
*
|
|
8
|
+
* @see `source.ts` for pure file type predicates (`isTypescript`, `isSvelte`, etc.)
|
|
9
|
+
* @see `analyze.ts` for consumers (`analyze`, `analyzeFromFiles`)
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { type AnalyzerType, type SourceFileInfo } from './source.js';
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for module source detection and path extraction.
|
|
16
|
+
*
|
|
17
|
+
* Uses proper path semantics with `projectRoot` as the base for all path operations.
|
|
18
|
+
* Paths are matched using `startsWith` rather than substring search, which correctly
|
|
19
|
+
* handles nested directories without special heuristics.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const options = createSourceOptions(process.cwd(), {
|
|
24
|
+
* sourcePaths: ['src/lib', 'src/routes'],
|
|
25
|
+
* sourceRoot: 'src',
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export interface ModuleSourceOptions {
|
|
30
|
+
/**
|
|
31
|
+
* Path to the project root directory.
|
|
32
|
+
*
|
|
33
|
+
* All `sourcePaths` are relative to this. Typically `process.cwd()`.
|
|
34
|
+
* Normalized (resolved to absolute, posixified to forward slashes,
|
|
35
|
+
* trailing slash stripped) by `normalizeSourceOptions`, which returns a
|
|
36
|
+
* new options object. Internal callers (`isSource`, `extractPath`) assume
|
|
37
|
+
* this is already POSIX form — construct via `createSourceOptions` /
|
|
38
|
+
* `normalizeSourceOptions` rather than building `ModuleSourceOptions`
|
|
39
|
+
* literals by hand on Windows.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* '/home/user/my-project'
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
projectRoot: string;
|
|
47
|
+
/**
|
|
48
|
+
* Source directory paths to include, relative to `projectRoot`.
|
|
49
|
+
*
|
|
50
|
+
* Normalized (leading/trailing slashes stripped) by `normalizeSourceOptions`,
|
|
51
|
+
* which returns a new options object.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* ['src/lib'] // single source directory
|
|
56
|
+
* ```
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* ['src/lib', 'src/routes'] // multiple directories
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
sourcePaths: Array<string>;
|
|
63
|
+
/**
|
|
64
|
+
* Source root for extracting relative module paths, relative to `projectRoot`.
|
|
65
|
+
*
|
|
66
|
+
* Normalized (leading/trailing slashes stripped; `'.'` collapsed to `''`)
|
|
67
|
+
* by `normalizeSourceOptions`, which returns a new options object.
|
|
68
|
+
*
|
|
69
|
+
* When omitted:
|
|
70
|
+
* - Single `sourcePath`: defaults to that path
|
|
71
|
+
* - Multiple `sourcePaths`: auto-derived as the longest common directory prefix
|
|
72
|
+
* (or `''` when paths share no common prefix — produces project-relative module paths)
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* 'src/lib' // module paths like 'foo.ts', 'utils/bar.ts'
|
|
77
|
+
* ```
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* 'src' // module paths like 'lib/foo.ts', 'routes/page.svelte'
|
|
81
|
+
* ```
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* '' // or '.': module paths stay project-relative, e.g. 'src/lib/foo.ts'
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
sourceRoot?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Glob patterns to exclude from analysis, relative to `projectRoot`.
|
|
90
|
+
*
|
|
91
|
+
* Applied at both stages of the pipeline:
|
|
92
|
+
* - **Discovery time** by `globFiles`/`discoverFromExports`, preventing matched files from being loaded.
|
|
93
|
+
* - **Analysis time** by `isSource()` against `relative(projectRoot, absolutePath)`,
|
|
94
|
+
* catching files that enter through TypeScript import resolution
|
|
95
|
+
* (e.g., a source file imports a test helper).
|
|
96
|
+
*
|
|
97
|
+
* `analyzeFromFiles` accepts a top-level `exclude` shortcut that merges into this field.
|
|
98
|
+
*
|
|
99
|
+
* Compiled to a matcher once per options object via picomatch and cached by reference;
|
|
100
|
+
* mutating this array post-`isSource`-call has no effect — pass through
|
|
101
|
+
* `normalizeSourceOptions` (which returns a fresh object) or otherwise build a
|
|
102
|
+
* new options object to apply changes.
|
|
103
|
+
*
|
|
104
|
+
* @default `['**\/*.test.ts', '**\/*.spec.ts']`
|
|
105
|
+
*/
|
|
106
|
+
exclude: Array<string>;
|
|
107
|
+
/**
|
|
108
|
+
* Determine which analyzer to use for a file path.
|
|
109
|
+
*
|
|
110
|
+
* Called for files in source directories. Return an `AnalyzerType` or `null` to skip:
|
|
111
|
+
* - `'typescript'` — TypeScript/JS files analyzed via TypeScript compiler API
|
|
112
|
+
* - `'svelte'` — Svelte components analyzed via svelte2tsx + TypeScript compiler API
|
|
113
|
+
* - `'css'` — CSS files included as modules with no declarations
|
|
114
|
+
* - `'json'` — JSON files included as modules with no declarations
|
|
115
|
+
* - `null` — skip the file
|
|
116
|
+
*
|
|
117
|
+
* @default Uses file extension: `.svelte` → svelte, `.ts`/`.js` → typescript, `.css` → css, `.json` → json
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* // Add MDsveX support
|
|
122
|
+
* getAnalyzerType: (path) => {
|
|
123
|
+
* if (path.endsWith('.svelte') || path.endsWith('.svx')) return 'svelte';
|
|
124
|
+
* if (path.endsWith('.ts') || path.endsWith('.js')) return 'typescript';
|
|
125
|
+
* if (path.endsWith('.css')) return 'css';
|
|
126
|
+
* if (path.endsWith('.json')) return 'json';
|
|
127
|
+
* return null;
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* // Include .d.ts files
|
|
134
|
+
* getAnalyzerType: (path) => {
|
|
135
|
+
* if (path.endsWith('.svelte')) return 'svelte';
|
|
136
|
+
* if (path.endsWith('.ts') || path.endsWith('.d.ts') || path.endsWith('.js')) return 'typescript';
|
|
137
|
+
* if (path.endsWith('.css')) return 'css';
|
|
138
|
+
* if (path.endsWith('.json')) return 'json';
|
|
139
|
+
* return null;
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
getAnalyzerType: (path: string) => AnalyzerType | null;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Default source options preset (without `projectRoot`).
|
|
147
|
+
*
|
|
148
|
+
* Use with `createSourceOptions` to build complete options.
|
|
149
|
+
* Contains all `ModuleSourceOptions` fields except `projectRoot`,
|
|
150
|
+
* which is provided separately as the first argument to `createSourceOptions`.
|
|
151
|
+
*/
|
|
152
|
+
export type SourceOptionsDefaults = Omit<ModuleSourceOptions, 'projectRoot'>;
|
|
153
|
+
/**
|
|
154
|
+
* Default partial options for standard SvelteKit library structure.
|
|
155
|
+
*
|
|
156
|
+
* Does not include `projectRoot` — use `createSourceOptions` to create
|
|
157
|
+
* complete options with your project root.
|
|
158
|
+
*
|
|
159
|
+
* `exclude` is the single source of truth for filtering: globs applied at both
|
|
160
|
+
* discovery time (by `globFiles`/`discoverFromExports`) and analysis time
|
|
161
|
+
* (by `isSource()` against project-root-relative paths).
|
|
162
|
+
*
|
|
163
|
+
* @see `createSourceOptions` for the typical way to build complete options
|
|
164
|
+
*/
|
|
165
|
+
export declare const DEFAULT_SOURCE_OPTIONS: SourceOptionsDefaults;
|
|
166
|
+
/**
|
|
167
|
+
* Create complete, normalized, validated source options from project root and optional overrides.
|
|
168
|
+
*
|
|
169
|
+
* Merges `overrides` with `DEFAULT_SOURCE_OPTIONS`, then normalizes via
|
|
170
|
+
* `normalizeSourceOptions` — so the returned object always has an absolute
|
|
171
|
+
* `projectRoot`, slash-stripped path entries, and an explicit `sourceRoot`
|
|
172
|
+
* (auto-derived for multi-path layouts). Throws on validation failure.
|
|
173
|
+
*
|
|
174
|
+
* @param projectRoot - path to project root (typically `process.cwd()`); resolved to absolute
|
|
175
|
+
* @param overrides - optional overrides for default options
|
|
176
|
+
* @throws Error if validation fails (empty `sourcePaths`, or `sourceRoot` not a prefix of all `sourcePaths`)
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```ts
|
|
180
|
+
* // Standard SvelteKit library
|
|
181
|
+
* const options = createSourceOptions(process.cwd());
|
|
182
|
+
* ```
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```ts
|
|
186
|
+
* // Multiple source directories
|
|
187
|
+
* const options = createSourceOptions(process.cwd(), {
|
|
188
|
+
* sourcePaths: ['src/lib', 'src/routes'],
|
|
189
|
+
* sourceRoot: 'src',
|
|
190
|
+
* });
|
|
191
|
+
* ```
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```ts
|
|
195
|
+
* // Custom exclusions
|
|
196
|
+
* const options = createSourceOptions(process.cwd(), {
|
|
197
|
+
* exclude: ['**\/*.test.ts', '**\/*.internal.ts'],
|
|
198
|
+
* });
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
export declare const createSourceOptions: (projectRoot: string, overrides?: Partial<SourceOptionsDefaults>) => ModuleSourceOptions;
|
|
202
|
+
/**
|
|
203
|
+
* Normalize and validate `ModuleSourceOptions`, returning a new options object.
|
|
204
|
+
*
|
|
205
|
+
* Normalization:
|
|
206
|
+
* - `projectRoot` resolved to absolute via `path.resolve` (relative paths resolve against cwd)
|
|
207
|
+
* - Trailing slash stripped from `projectRoot`
|
|
208
|
+
* - Leading/trailing slashes stripped from `sourcePaths` entries
|
|
209
|
+
* - Leading/trailing slashes stripped from `sourceRoot` (if provided)
|
|
210
|
+
* - `sourceRoot` of `'.'` is normalized to `''` (project root sentinel)
|
|
211
|
+
*
|
|
212
|
+
* Validation (after normalization):
|
|
213
|
+
* 1. `sourcePaths` has at least one entry
|
|
214
|
+
* 2. `sourceRoot` (if provided and non-empty) is a prefix of all `sourcePaths`
|
|
215
|
+
*
|
|
216
|
+
* When `sourceRoot` is omitted and multiple `sourcePaths` are provided,
|
|
217
|
+
* `sourceRoot` is auto-derived as their longest common path prefix. If the
|
|
218
|
+
* paths share no common prefix, the derived root is `''` and `extractPath`
|
|
219
|
+
* produces project-relative module paths.
|
|
220
|
+
*
|
|
221
|
+
* Returns a fresh object — the input is not mutated. Re-normalization produces
|
|
222
|
+
* a fresh identity, which naturally invalidates the `excludeMatcherCache`
|
|
223
|
+
* (keyed by options-object identity) without a separate "rebuild a fresh
|
|
224
|
+
* object" rule.
|
|
225
|
+
*
|
|
226
|
+
* @returns a new `ModuleSourceOptions` with normalized fields
|
|
227
|
+
* @throws Error if validation fails
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```ts
|
|
231
|
+
* // Normalization: slashes stripped, relative projectRoot resolved
|
|
232
|
+
* const normalized = normalizeSourceOptions({projectRoot: '.', sourcePaths: ['/src/lib/'], ...});
|
|
233
|
+
* // normalized.projectRoot is now absolute, normalized.sourcePaths is ['src/lib']
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
export declare const normalizeSourceOptions: (options: ModuleSourceOptions) => ModuleSourceOptions;
|
|
237
|
+
/**
|
|
238
|
+
* Get the effective `sourceRoot` from options.
|
|
239
|
+
*
|
|
240
|
+
* Returns `sourceRoot` if provided, otherwise:
|
|
241
|
+
* - Single `sourcePath`: returns that path
|
|
242
|
+
* - Multiple `sourcePaths`: derives the longest common directory prefix
|
|
243
|
+
*
|
|
244
|
+
* @returns the effective source root path
|
|
245
|
+
*/
|
|
246
|
+
export declare const getSourceRoot: (options: ModuleSourceOptions) => string;
|
|
247
|
+
/**
|
|
248
|
+
* Extract module path relative to source root from absolute source ID.
|
|
249
|
+
*
|
|
250
|
+
* Uses proper path semantics: strips `projectRoot/sourceRoot/` prefix.
|
|
251
|
+
*
|
|
252
|
+
* @param sourceId - absolute path to the source file
|
|
253
|
+
* @param options - module source options for path extraction
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```ts
|
|
257
|
+
* const options = createSourceOptions('/home/user/project');
|
|
258
|
+
* extractPath('/home/user/project/src/lib/foo.ts', options) // => 'foo.ts'
|
|
259
|
+
* extractPath('/home/user/project/src/lib/nested/bar.svelte', options) // => 'nested/bar.svelte'
|
|
260
|
+
* ```
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```ts
|
|
264
|
+
* const options = createSourceOptions('/home/user/project', {
|
|
265
|
+
* sourcePaths: ['src/lib', 'src/routes'],
|
|
266
|
+
* sourceRoot: 'src',
|
|
267
|
+
* });
|
|
268
|
+
* extractPath('/home/user/project/src/lib/foo.ts', options) // => 'lib/foo.ts'
|
|
269
|
+
* extractPath('/home/user/project/src/routes/page.svelte', options) // => 'routes/page.svelte'
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
export declare const extractPath: (sourceId: string, options: ModuleSourceOptions) => string;
|
|
273
|
+
/**
|
|
274
|
+
* Check if a path is an analyzable source file.
|
|
275
|
+
*
|
|
276
|
+
* Combines all filtering: source directory paths, exclude globs, and analyzer
|
|
277
|
+
* availability. This is the single check for whether a file should be
|
|
278
|
+
* included in library analysis.
|
|
279
|
+
*
|
|
280
|
+
* Uses proper path semantics with `startsWith` matching against
|
|
281
|
+
* `projectRoot/sourcePath/`. No heuristics needed — nested directories are
|
|
282
|
+
* correctly excluded by the prefix check.
|
|
283
|
+
*
|
|
284
|
+
* Order is sourceDir-then-exclude: the prefix check guarantees the path lives
|
|
285
|
+
* under `projectRoot` before relativization, so `relative()` always produces
|
|
286
|
+
* a clean glob-shaped string for the matcher. Files outside `projectRoot`
|
|
287
|
+
* (rare; would require monorepo path mapping) short-circuit at the prefix
|
|
288
|
+
* check before reaching the matcher.
|
|
289
|
+
*
|
|
290
|
+
* @param path - full absolute path to check
|
|
291
|
+
* @param options - module source options for filtering
|
|
292
|
+
* @returns true if the path is an analyzable source file
|
|
293
|
+
*
|
|
294
|
+
* @example
|
|
295
|
+
* ```ts
|
|
296
|
+
* const options = createSourceOptions('/home/user/project');
|
|
297
|
+
* isSource('/home/user/project/src/lib/foo.ts', options) // => true
|
|
298
|
+
* isSource('/home/user/project/src/lib/styles.css', options) // => true
|
|
299
|
+
* isSource('/home/user/project/src/lib/data.json', options) // => true
|
|
300
|
+
* isSource('/home/user/project/src/lib/foo.test.ts', options) // => false (excluded)
|
|
301
|
+
* isSource('/home/user/project/src/fixtures/mini/src/lib/bar.ts', options) // => false (wrong prefix)
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
export declare const isSource: (path: string, options: ModuleSourceOptions) => boolean;
|
|
305
|
+
/**
|
|
306
|
+
* Extract dependencies and dependents for a module from source file info.
|
|
307
|
+
*
|
|
308
|
+
* Filters to only include source modules (excludes external packages, node_modules, tests).
|
|
309
|
+
* Returns sorted arrays of module paths (relative to `sourceRoot`) for deterministic output.
|
|
310
|
+
*
|
|
311
|
+
* Native paths in `sourceFile.dependencies`/`dependents` are accepted —
|
|
312
|
+
* `isSource` and `extractPath` posixify their inputs, so direct callers with
|
|
313
|
+
* hand-built input need not pre-normalize.
|
|
314
|
+
*
|
|
315
|
+
* Accepts `SourceFileInfo` plus an optional `dependents` field — the public
|
|
316
|
+
* input type carries only `dependencies` (caller-supplied opt-in), while
|
|
317
|
+
* `dependents` is computed downstream by `computeDependents` and flows through
|
|
318
|
+
* as an enriched shape.
|
|
319
|
+
*
|
|
320
|
+
* @param sourceFile - the source file info to extract dependencies from
|
|
321
|
+
* @param options - module source options for filtering and path extraction
|
|
322
|
+
* @returns sorted arrays of module paths (relative to `sourceRoot`) for dependencies and dependents
|
|
323
|
+
*/
|
|
324
|
+
export declare const extractDependencies: (sourceFile: SourceFileInfo & {
|
|
325
|
+
dependents?: ReadonlyArray<string>;
|
|
326
|
+
}, options: ModuleSourceOptions) => {
|
|
327
|
+
dependencies: Array<string>;
|
|
328
|
+
dependents: Array<string>;
|
|
329
|
+
};
|
|
330
|
+
//# sourceMappingURL=source-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-config.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/source-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EAAC,KAAK,YAAY,EAAE,KAAK,cAAc,EAAqB,MAAM,aAAa,CAAC;AAGvF;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,mBAAmB;IACnC;;;;;;;;;;;;;;;OAeG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;OAcG;IACH,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,YAAY,GAAG,IAAI,CAAC;CACvD;AAED;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC;AAE7E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,EAAE,qBAIpC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,mBAAmB,GAC/B,aAAa,MAAM,EACnB,YAAY,OAAO,CAAC,qBAAqB,CAAC,KACxC,mBAKA,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,mBAAmB,KAAG,mBAmDrE,CAAC;AA+BF;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GAAI,SAAS,mBAAmB,KAAG,MAQ5D,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,WAAW,GAAI,UAAU,MAAM,EAAE,SAAS,mBAAmB,KAAG,MAgB5E,CAAC;AAwBF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,EAAE,SAAS,mBAAmB,KAAG,OAwBrE,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,mBAAmB,GAC/B,YAAY,cAAc,GAAG;IAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAC,EACjE,SAAS,mBAAmB,KAC1B;IAAC,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CA2BzD,CAAC"}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source configuration, path extraction, and file filtering.
|
|
3
|
+
*
|
|
4
|
+
* Provides `ModuleSourceOptions` configuration management and functions
|
|
5
|
+
* that operate on source files using those options: path extraction,
|
|
6
|
+
* source detection, dependency filtering, and file collection.
|
|
7
|
+
*
|
|
8
|
+
* @see `source.ts` for pure file type predicates (`isTypescript`, `isSvelte`, etc.)
|
|
9
|
+
* @see `analyze.ts` for consumers (`analyze`, `analyzeFromFiles`)
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { resolve, relative } from 'node:path';
|
|
14
|
+
import picomatch from 'picomatch';
|
|
15
|
+
import { getDefaultAnalyzer } from './source.js';
|
|
16
|
+
import { toPosixPath } from './paths.js';
|
|
17
|
+
/**
|
|
18
|
+
* Default partial options for standard SvelteKit library structure.
|
|
19
|
+
*
|
|
20
|
+
* Does not include `projectRoot` — use `createSourceOptions` to create
|
|
21
|
+
* complete options with your project root.
|
|
22
|
+
*
|
|
23
|
+
* `exclude` is the single source of truth for filtering: globs applied at both
|
|
24
|
+
* discovery time (by `globFiles`/`discoverFromExports`) and analysis time
|
|
25
|
+
* (by `isSource()` against project-root-relative paths).
|
|
26
|
+
*
|
|
27
|
+
* @see `createSourceOptions` for the typical way to build complete options
|
|
28
|
+
*/
|
|
29
|
+
export const DEFAULT_SOURCE_OPTIONS = {
|
|
30
|
+
sourcePaths: ['src/lib'],
|
|
31
|
+
exclude: ['**/*.test.ts', '**/*.spec.ts'],
|
|
32
|
+
getAnalyzerType: getDefaultAnalyzer,
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Create complete, normalized, validated source options from project root and optional overrides.
|
|
36
|
+
*
|
|
37
|
+
* Merges `overrides` with `DEFAULT_SOURCE_OPTIONS`, then normalizes via
|
|
38
|
+
* `normalizeSourceOptions` — so the returned object always has an absolute
|
|
39
|
+
* `projectRoot`, slash-stripped path entries, and an explicit `sourceRoot`
|
|
40
|
+
* (auto-derived for multi-path layouts). Throws on validation failure.
|
|
41
|
+
*
|
|
42
|
+
* @param projectRoot - path to project root (typically `process.cwd()`); resolved to absolute
|
|
43
|
+
* @param overrides - optional overrides for default options
|
|
44
|
+
* @throws Error if validation fails (empty `sourcePaths`, or `sourceRoot` not a prefix of all `sourcePaths`)
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* // Standard SvelteKit library
|
|
49
|
+
* const options = createSourceOptions(process.cwd());
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* // Multiple source directories
|
|
55
|
+
* const options = createSourceOptions(process.cwd(), {
|
|
56
|
+
* sourcePaths: ['src/lib', 'src/routes'],
|
|
57
|
+
* sourceRoot: 'src',
|
|
58
|
+
* });
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* // Custom exclusions
|
|
64
|
+
* const options = createSourceOptions(process.cwd(), {
|
|
65
|
+
* exclude: ['**\/*.test.ts', '**\/*.internal.ts'],
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export const createSourceOptions = (projectRoot, overrides) => normalizeSourceOptions({
|
|
70
|
+
projectRoot,
|
|
71
|
+
...DEFAULT_SOURCE_OPTIONS,
|
|
72
|
+
...overrides,
|
|
73
|
+
});
|
|
74
|
+
/**
|
|
75
|
+
* Normalize and validate `ModuleSourceOptions`, returning a new options object.
|
|
76
|
+
*
|
|
77
|
+
* Normalization:
|
|
78
|
+
* - `projectRoot` resolved to absolute via `path.resolve` (relative paths resolve against cwd)
|
|
79
|
+
* - Trailing slash stripped from `projectRoot`
|
|
80
|
+
* - Leading/trailing slashes stripped from `sourcePaths` entries
|
|
81
|
+
* - Leading/trailing slashes stripped from `sourceRoot` (if provided)
|
|
82
|
+
* - `sourceRoot` of `'.'` is normalized to `''` (project root sentinel)
|
|
83
|
+
*
|
|
84
|
+
* Validation (after normalization):
|
|
85
|
+
* 1. `sourcePaths` has at least one entry
|
|
86
|
+
* 2. `sourceRoot` (if provided and non-empty) is a prefix of all `sourcePaths`
|
|
87
|
+
*
|
|
88
|
+
* When `sourceRoot` is omitted and multiple `sourcePaths` are provided,
|
|
89
|
+
* `sourceRoot` is auto-derived as their longest common path prefix. If the
|
|
90
|
+
* paths share no common prefix, the derived root is `''` and `extractPath`
|
|
91
|
+
* produces project-relative module paths.
|
|
92
|
+
*
|
|
93
|
+
* Returns a fresh object — the input is not mutated. Re-normalization produces
|
|
94
|
+
* a fresh identity, which naturally invalidates the `excludeMatcherCache`
|
|
95
|
+
* (keyed by options-object identity) without a separate "rebuild a fresh
|
|
96
|
+
* object" rule.
|
|
97
|
+
*
|
|
98
|
+
* @returns a new `ModuleSourceOptions` with normalized fields
|
|
99
|
+
* @throws Error if validation fails
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* // Normalization: slashes stripped, relative projectRoot resolved
|
|
104
|
+
* const normalized = normalizeSourceOptions({projectRoot: '.', sourcePaths: ['/src/lib/'], ...});
|
|
105
|
+
* // normalized.projectRoot is now absolute, normalized.sourcePaths is ['src/lib']
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export const normalizeSourceOptions = (options) => {
|
|
109
|
+
// Normalize projectRoot: resolve to absolute, posixify, strip trailing slash.
|
|
110
|
+
// Posixify after `resolve` because `path.resolve` returns native separators
|
|
111
|
+
// on Windows; everything internal compares against forward-slash form.
|
|
112
|
+
let projectRoot = toPosixPath(resolve(options.projectRoot));
|
|
113
|
+
if (projectRoot.length > 1 && projectRoot.endsWith('/')) {
|
|
114
|
+
projectRoot = projectRoot.slice(0, -1);
|
|
115
|
+
}
|
|
116
|
+
// Normalize sourcePaths: posixify (in case a Windows user supplies
|
|
117
|
+
// `'src\\lib'`), then strip leading/trailing slashes.
|
|
118
|
+
const sourcePaths = options.sourcePaths.map((p) => stripSlashes(toPosixPath(p)));
|
|
119
|
+
// Validate sourcePaths non-empty
|
|
120
|
+
if (sourcePaths.length === 0) {
|
|
121
|
+
throw new Error('ModuleSourceOptions.sourcePaths must have at least one entry. ' +
|
|
122
|
+
"For SvelteKit projects, the default is ['src/lib']; for plain TS, try ['src'].");
|
|
123
|
+
}
|
|
124
|
+
// Normalize sourceRoot: posixify, strip leading/trailing slashes.
|
|
125
|
+
// `.` is treated as the project root sentinel — equivalent to an empty string,
|
|
126
|
+
// which `extractPath` interprets as "strip projectRoot only" (module paths
|
|
127
|
+
// stay project-relative). `.` is the ergonomic CLI form; `''` is the
|
|
128
|
+
// shell-quoting form. Both reach the same effective state.
|
|
129
|
+
let sourceRoot = options.sourceRoot === undefined ? undefined : stripSlashes(toPosixPath(options.sourceRoot));
|
|
130
|
+
if (sourceRoot === '.')
|
|
131
|
+
sourceRoot = '';
|
|
132
|
+
// Auto-derive sourceRoot for multiple sourcePaths when not explicitly provided.
|
|
133
|
+
// Empty common prefix is a valid result — `extractPath` will produce
|
|
134
|
+
// project-relative module paths (e.g., `lib/foo.ts`, `routes/page.svelte`)
|
|
135
|
+
// instead of stripping a common directory prefix.
|
|
136
|
+
if (sourceRoot === undefined && sourcePaths.length > 1) {
|
|
137
|
+
sourceRoot = deriveCommonPrefix(sourcePaths);
|
|
138
|
+
}
|
|
139
|
+
// Validate sourceRoot prefix constraint (if sourceRoot is set — either explicit or auto-derived)
|
|
140
|
+
if (sourceRoot !== undefined && sourceRoot !== '') {
|
|
141
|
+
for (const sourcePath of sourcePaths) {
|
|
142
|
+
if (sourcePath !== sourceRoot && !sourcePath.startsWith(sourceRoot + '/')) {
|
|
143
|
+
throw new Error(`sourcePaths entry "${sourcePath}" must start with sourceRoot "${sourceRoot}". ` +
|
|
144
|
+
`extractPath uses sourceRoot to compute module paths.`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return { ...options, projectRoot, sourcePaths, sourceRoot };
|
|
149
|
+
};
|
|
150
|
+
/** Strip all leading and trailing forward slashes from a path segment. */
|
|
151
|
+
const stripSlashes = (p) => {
|
|
152
|
+
let result = p;
|
|
153
|
+
while (result.startsWith('/'))
|
|
154
|
+
result = result.slice(1);
|
|
155
|
+
while (result.endsWith('/'))
|
|
156
|
+
result = result.slice(0, -1);
|
|
157
|
+
return result;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Derive the longest common directory prefix from an array of paths.
|
|
161
|
+
*
|
|
162
|
+
* @returns common prefix (e.g., `['src/lib', 'src/routes']` → `'src'`),
|
|
163
|
+
* or empty string if paths share no common prefix
|
|
164
|
+
*/
|
|
165
|
+
const deriveCommonPrefix = (paths) => {
|
|
166
|
+
if (paths.length === 0)
|
|
167
|
+
return '';
|
|
168
|
+
const segments = paths[0].split('/');
|
|
169
|
+
let common = '';
|
|
170
|
+
for (const segment of segments) {
|
|
171
|
+
const candidate = common ? common + '/' + segment : segment;
|
|
172
|
+
if (paths.every((p) => p === candidate || p.startsWith(candidate + '/'))) {
|
|
173
|
+
common = candidate;
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return common;
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Get the effective `sourceRoot` from options.
|
|
183
|
+
*
|
|
184
|
+
* Returns `sourceRoot` if provided, otherwise:
|
|
185
|
+
* - Single `sourcePath`: returns that path
|
|
186
|
+
* - Multiple `sourcePaths`: derives the longest common directory prefix
|
|
187
|
+
*
|
|
188
|
+
* @returns the effective source root path
|
|
189
|
+
*/
|
|
190
|
+
export const getSourceRoot = (options) => {
|
|
191
|
+
if (options.sourceRoot !== undefined) {
|
|
192
|
+
return options.sourceRoot;
|
|
193
|
+
}
|
|
194
|
+
if (options.sourcePaths.length === 1) {
|
|
195
|
+
return options.sourcePaths[0];
|
|
196
|
+
}
|
|
197
|
+
return deriveCommonPrefix(options.sourcePaths);
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Extract module path relative to source root from absolute source ID.
|
|
201
|
+
*
|
|
202
|
+
* Uses proper path semantics: strips `projectRoot/sourceRoot/` prefix.
|
|
203
|
+
*
|
|
204
|
+
* @param sourceId - absolute path to the source file
|
|
205
|
+
* @param options - module source options for path extraction
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* const options = createSourceOptions('/home/user/project');
|
|
210
|
+
* extractPath('/home/user/project/src/lib/foo.ts', options) // => 'foo.ts'
|
|
211
|
+
* extractPath('/home/user/project/src/lib/nested/bar.svelte', options) // => 'nested/bar.svelte'
|
|
212
|
+
* ```
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* const options = createSourceOptions('/home/user/project', {
|
|
217
|
+
* sourcePaths: ['src/lib', 'src/routes'],
|
|
218
|
+
* sourceRoot: 'src',
|
|
219
|
+
* });
|
|
220
|
+
* extractPath('/home/user/project/src/lib/foo.ts', options) // => 'lib/foo.ts'
|
|
221
|
+
* extractPath('/home/user/project/src/routes/page.svelte', options) // => 'routes/page.svelte'
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
export const extractPath = (sourceId, options) => {
|
|
225
|
+
// Posixify input so the prefix slice works regardless of which separator
|
|
226
|
+
// the caller's path system uses. `options.projectRoot` is already POSIX.
|
|
227
|
+
const posixId = toPosixPath(sourceId);
|
|
228
|
+
const effectiveRoot = getSourceRoot(options);
|
|
229
|
+
// Build the full prefix: projectRoot + '/' + sourceRoot + '/'
|
|
230
|
+
// When sourceRoot is empty, prefix is just projectRoot + '/'
|
|
231
|
+
const prefix = effectiveRoot
|
|
232
|
+
? options.projectRoot + '/' + effectiveRoot + '/'
|
|
233
|
+
: options.projectRoot + '/';
|
|
234
|
+
if (posixId.startsWith(prefix)) {
|
|
235
|
+
return posixId.slice(prefix.length);
|
|
236
|
+
}
|
|
237
|
+
// Fallback: return full path if prefix doesn't match (shouldn't happen with valid inputs)
|
|
238
|
+
return posixId;
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* Compiled glob-matcher cache for `options.exclude`, keyed by options object identity.
|
|
242
|
+
*
|
|
243
|
+
* Picomatch compilation is non-trivial; caching avoids re-parsing the same patterns
|
|
244
|
+
* on every `isSource()` call. Mutating `options.exclude` post-cache-population has
|
|
245
|
+
* no effect — callers that need to change the exclude list must build a fresh
|
|
246
|
+
* options object (different identity). `normalizeSourceOptions` returns a new
|
|
247
|
+
* object, so re-running it through normalize naturally produces a fresh identity
|
|
248
|
+
* and the cache populates fresh on first access.
|
|
249
|
+
*/
|
|
250
|
+
const excludeMatcherCache = new WeakMap();
|
|
251
|
+
const getExcludeMatcher = (options) => {
|
|
252
|
+
let matcher = excludeMatcherCache.get(options);
|
|
253
|
+
if (!matcher) {
|
|
254
|
+
matcher = options.exclude.length === 0 ? () => false : picomatch(options.exclude);
|
|
255
|
+
excludeMatcherCache.set(options, matcher);
|
|
256
|
+
}
|
|
257
|
+
return matcher;
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* Check if a path is an analyzable source file.
|
|
261
|
+
*
|
|
262
|
+
* Combines all filtering: source directory paths, exclude globs, and analyzer
|
|
263
|
+
* availability. This is the single check for whether a file should be
|
|
264
|
+
* included in library analysis.
|
|
265
|
+
*
|
|
266
|
+
* Uses proper path semantics with `startsWith` matching against
|
|
267
|
+
* `projectRoot/sourcePath/`. No heuristics needed — nested directories are
|
|
268
|
+
* correctly excluded by the prefix check.
|
|
269
|
+
*
|
|
270
|
+
* Order is sourceDir-then-exclude: the prefix check guarantees the path lives
|
|
271
|
+
* under `projectRoot` before relativization, so `relative()` always produces
|
|
272
|
+
* a clean glob-shaped string for the matcher. Files outside `projectRoot`
|
|
273
|
+
* (rare; would require monorepo path mapping) short-circuit at the prefix
|
|
274
|
+
* check before reaching the matcher.
|
|
275
|
+
*
|
|
276
|
+
* @param path - full absolute path to check
|
|
277
|
+
* @param options - module source options for filtering
|
|
278
|
+
* @returns true if the path is an analyzable source file
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* ```ts
|
|
282
|
+
* const options = createSourceOptions('/home/user/project');
|
|
283
|
+
* isSource('/home/user/project/src/lib/foo.ts', options) // => true
|
|
284
|
+
* isSource('/home/user/project/src/lib/styles.css', options) // => true
|
|
285
|
+
* isSource('/home/user/project/src/lib/data.json', options) // => true
|
|
286
|
+
* isSource('/home/user/project/src/lib/foo.test.ts', options) // => false (excluded)
|
|
287
|
+
* isSource('/home/user/project/src/fixtures/mini/src/lib/bar.ts', options) // => false (wrong prefix)
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
export const isSource = (path, options) => {
|
|
291
|
+
// Posixify input — callers may pass native paths (Windows backslashes).
|
|
292
|
+
// `options.projectRoot` and `sourcePaths` are already POSIX after
|
|
293
|
+
// `normalizeSourceOptions`.
|
|
294
|
+
const posixPath = toPosixPath(path);
|
|
295
|
+
// Source-dir prefix check first — guarantees the path lives under projectRoot
|
|
296
|
+
// before we relativize for glob matching. Out-of-root files (which can't be
|
|
297
|
+
// sources anyway) short-circuit here without reaching the matcher.
|
|
298
|
+
const inSourceDir = options.sourcePaths.some((sourcePath) => {
|
|
299
|
+
const fullPrefix = options.projectRoot + '/' + sourcePath + '/';
|
|
300
|
+
return posixPath.startsWith(fullPrefix);
|
|
301
|
+
});
|
|
302
|
+
if (!inSourceDir)
|
|
303
|
+
return false;
|
|
304
|
+
// Glob-match the project-root-relative path against `exclude`. `relative`
|
|
305
|
+
// returns native separators on Windows; posixify so the matcher sees the
|
|
306
|
+
// same forward-slash form the user wrote their globs in.
|
|
307
|
+
const relPath = toPosixPath(relative(options.projectRoot, posixPath));
|
|
308
|
+
if (getExcludeMatcher(options)(relPath))
|
|
309
|
+
return false;
|
|
310
|
+
// Check if file type is analyzable. Pass the posixified form so analyzer
|
|
311
|
+
// callbacks see the canonical id, not a native-separator variant.
|
|
312
|
+
return options.getAnalyzerType(posixPath) !== null;
|
|
313
|
+
};
|
|
314
|
+
/**
|
|
315
|
+
* Extract dependencies and dependents for a module from source file info.
|
|
316
|
+
*
|
|
317
|
+
* Filters to only include source modules (excludes external packages, node_modules, tests).
|
|
318
|
+
* Returns sorted arrays of module paths (relative to `sourceRoot`) for deterministic output.
|
|
319
|
+
*
|
|
320
|
+
* Native paths in `sourceFile.dependencies`/`dependents` are accepted —
|
|
321
|
+
* `isSource` and `extractPath` posixify their inputs, so direct callers with
|
|
322
|
+
* hand-built input need not pre-normalize.
|
|
323
|
+
*
|
|
324
|
+
* Accepts `SourceFileInfo` plus an optional `dependents` field — the public
|
|
325
|
+
* input type carries only `dependencies` (caller-supplied opt-in), while
|
|
326
|
+
* `dependents` is computed downstream by `computeDependents` and flows through
|
|
327
|
+
* as an enriched shape.
|
|
328
|
+
*
|
|
329
|
+
* @param sourceFile - the source file info to extract dependencies from
|
|
330
|
+
* @param options - module source options for filtering and path extraction
|
|
331
|
+
* @returns sorted arrays of module paths (relative to `sourceRoot`) for dependencies and dependents
|
|
332
|
+
*/
|
|
333
|
+
export const extractDependencies = (sourceFile, options) => {
|
|
334
|
+
const dependencies = [];
|
|
335
|
+
const dependents = [];
|
|
336
|
+
// Extract dependencies (files this module imports) if provided
|
|
337
|
+
if (sourceFile.dependencies) {
|
|
338
|
+
for (const depId of sourceFile.dependencies) {
|
|
339
|
+
if (isSource(depId, options)) {
|
|
340
|
+
dependencies.push(extractPath(depId, options));
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
// Extract dependents (files that import this module) if provided
|
|
345
|
+
if (sourceFile.dependents) {
|
|
346
|
+
for (const dependentId of sourceFile.dependents) {
|
|
347
|
+
if (isSource(dependentId, options)) {
|
|
348
|
+
dependents.push(extractPath(dependentId, options));
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// Sort for deterministic output
|
|
353
|
+
dependencies.sort();
|
|
354
|
+
dependents.sort();
|
|
355
|
+
return { dependencies, dependents };
|
|
356
|
+
};
|