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.
Files changed (97) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +349 -0
  3. package/dist/analyze-core.d.ts +1386 -0
  4. package/dist/analyze-core.d.ts.map +1 -0
  5. package/dist/analyze-core.js +324 -0
  6. package/dist/analyze.d.ts +137 -0
  7. package/dist/analyze.d.ts.map +1 -0
  8. package/dist/analyze.js +148 -0
  9. package/dist/cli.d.ts +102 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +206 -0
  12. package/dist/concurrency.d.ts +38 -0
  13. package/dist/concurrency.d.ts.map +1 -0
  14. package/dist/concurrency.js +57 -0
  15. package/dist/declaration-build.d.ts +164 -0
  16. package/dist/declaration-build.d.ts.map +1 -0
  17. package/dist/declaration-build.js +15 -0
  18. package/dist/declaration-helpers.d.ts +169 -0
  19. package/dist/declaration-helpers.d.ts.map +1 -0
  20. package/dist/declaration-helpers.js +239 -0
  21. package/dist/dep-resolver.d.ts +166 -0
  22. package/dist/dep-resolver.d.ts.map +1 -0
  23. package/dist/dep-resolver.js +144 -0
  24. package/dist/diagnostics.d.ts +650 -0
  25. package/dist/diagnostics.d.ts.map +1 -0
  26. package/dist/diagnostics.js +377 -0
  27. package/dist/discovery.d.ts +115 -0
  28. package/dist/discovery.d.ts.map +1 -0
  29. package/dist/discovery.js +126 -0
  30. package/dist/exports.d.ts +105 -0
  31. package/dist/exports.d.ts.map +1 -0
  32. package/dist/exports.js +274 -0
  33. package/dist/files.d.ts +77 -0
  34. package/dist/files.d.ts.map +1 -0
  35. package/dist/files.js +95 -0
  36. package/dist/index.d.ts +32 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +30 -0
  39. package/dist/log.d.ts +32 -0
  40. package/dist/log.d.ts.map +1 -0
  41. package/dist/log.js +11 -0
  42. package/dist/logo.d.ts +8 -0
  43. package/dist/logo.d.ts.map +1 -0
  44. package/dist/logo.js +9 -0
  45. package/dist/main.d.ts +11 -0
  46. package/dist/main.d.ts.map +1 -0
  47. package/dist/main.js +18 -0
  48. package/dist/paths.d.ts +35 -0
  49. package/dist/paths.d.ts.map +1 -0
  50. package/dist/paths.js +34 -0
  51. package/dist/postprocess.d.ts +145 -0
  52. package/dist/postprocess.d.ts.map +1 -0
  53. package/dist/postprocess.js +305 -0
  54. package/dist/session.d.ts +248 -0
  55. package/dist/session.d.ts.map +1 -0
  56. package/dist/session.js +496 -0
  57. package/dist/source-config.d.ts +330 -0
  58. package/dist/source-config.d.ts.map +1 -0
  59. package/dist/source-config.js +356 -0
  60. package/dist/source.d.ts +126 -0
  61. package/dist/source.d.ts.map +1 -0
  62. package/dist/source.js +68 -0
  63. package/dist/svelte.d.ts +179 -0
  64. package/dist/svelte.d.ts.map +1 -0
  65. package/dist/svelte.js +898 -0
  66. package/dist/tsdoc.d.ts +145 -0
  67. package/dist/tsdoc.d.ts.map +1 -0
  68. package/dist/tsdoc.js +262 -0
  69. package/dist/types.d.ts +3381 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +588 -0
  72. package/dist/typescript-exports.d.ts +91 -0
  73. package/dist/typescript-exports.d.ts.map +1 -0
  74. package/dist/typescript-exports.js +656 -0
  75. package/dist/typescript-extract-class.d.ts +29 -0
  76. package/dist/typescript-extract-class.d.ts.map +1 -0
  77. package/dist/typescript-extract-class.js +251 -0
  78. package/dist/typescript-extract-function.d.ts +47 -0
  79. package/dist/typescript-extract-function.d.ts.map +1 -0
  80. package/dist/typescript-extract-function.js +108 -0
  81. package/dist/typescript-extract-shared.d.ts +166 -0
  82. package/dist/typescript-extract-shared.d.ts.map +1 -0
  83. package/dist/typescript-extract-shared.js +528 -0
  84. package/dist/typescript-extract-type-properties.d.ts +34 -0
  85. package/dist/typescript-extract-type-properties.d.ts.map +1 -0
  86. package/dist/typescript-extract-type-properties.js +241 -0
  87. package/dist/typescript-extract-type.d.ts +48 -0
  88. package/dist/typescript-extract-type.d.ts.map +1 -0
  89. package/dist/typescript-extract-type.js +238 -0
  90. package/dist/typescript-program.d.ts +211 -0
  91. package/dist/typescript-program.d.ts.map +1 -0
  92. package/dist/typescript-program.js +290 -0
  93. package/dist/vite.d.ts +116 -0
  94. package/dist/vite.d.ts.map +1 -0
  95. package/dist/vite.js +418 -0
  96. package/package.json +131 -0
  97. package/virtual-svelte-docinfo.d.ts +49 -0
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Utility functions for working with declaration and member types.
3
+ *
4
+ * Display formatting, code generation, serialization, type narrowing,
5
+ * and type reference discovery for `DeclarationJson` and `MemberJson`.
6
+ *
7
+ * @see `types.ts` for `DeclarationJson`, `MemberJson` Zod schemas
8
+ *
9
+ * @module
10
+ */
11
+ import type { DeclarationJson, MemberJson, DeclarationKind, MemberKind } from './types.js';
12
+ /**
13
+ * JSON replacer that strips Zod default values for compact serialization.
14
+ *
15
+ * Strips empty arrays and `false` booleans — both are Zod `.default()` values
16
+ * restored on `.parse()`, so the round-trip is lossless for svelte-docinfo types.
17
+ * Assumes all boolean fields in the schema default to `false` — a `true`-defaulted
18
+ * boolean would need its `false` values preserved, breaking the round-trip.
19
+ *
20
+ * **Root-value caveat**: `JSON.stringify([], compactReplacer)` returns the JS
21
+ * `undefined` (not the string `'[]'`), and `JSON.stringify(false, compactReplacer)`
22
+ * returns the JS `undefined` too. Object-rooted callers (`AnalyzeResultJson`
23
+ * envelope, CLI output) don't hit this — empty inner arrays strip and
24
+ * `AnalyzeResultJson.parse` restores them on the consumer side. Array-rooted
25
+ * callers (Vite plugin, anyone splicing the JSON into a source template)
26
+ * must handle the empty case themselves before calling this; see
27
+ * `vite.ts:updateOutputFromQuery` for the pattern.
28
+ *
29
+ * Two guard tests in `declaration-helpers.test.ts` lock this in:
30
+ * - `every z.boolean().default in types.ts uses false` — source-regex check
31
+ * that fails on a new `z.boolean().default(true)`.
32
+ * - `parse → stringify(compactReplacer) → parse is a faithful round-trip
33
+ * across every variant` — exercises every variant and member through a
34
+ * full round-trip, catching regressions where a `.default(false)` or
35
+ * `.default([])` is removed (or a new field is added that the replacer
36
+ * drops but Zod doesn't restore).
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * const result = await analyze({sourceFiles, sourceOptions});
41
+ * const json = JSON.stringify(result, compactReplacer);
42
+ * // On the consumer side, restore Zod defaults:
43
+ * const restored = AnalyzeResultJson.parse(JSON.parse(json));
44
+ * ```
45
+ */
46
+ export declare const compactReplacer: (_key: string, value: unknown) => unknown;
47
+ /**
48
+ * Format declaration or member name with generic parameters for display.
49
+ *
50
+ * Default-slot entries return the literal `'default'` (the symbol's actual
51
+ * name in JS). Renderers that want a richer label (PascalCased module path,
52
+ * an explicit "default export" header) should branch on `name === 'default'`
53
+ * themselves before calling this.
54
+ *
55
+ * @see `generateImport` for the divergent default-slot fallback used in
56
+ * import-statement generation (PascalCased module path, since an import
57
+ * needs a JS identifier binding, not a label).
58
+ *
59
+ * @param declaration - the `DeclarationJson` or `MemberJson` to format
60
+ * @returns name with generic parameters appended (e.g., `Map<K, V>`)
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * getDisplayName({name: 'Map', kind: 'type', genericParams: [{name: 'K'}, {name: 'V'}]})
65
+ * // => 'Map<K, V>'
66
+ * ```
67
+ */
68
+ export declare const getDisplayName: (declaration: DeclarationJson | MemberJson) => string;
69
+ /**
70
+ * Generate TypeScript import statement for a declaration.
71
+ *
72
+ * Produces `import type` for type/interface declarations, `import` for values.
73
+ *
74
+ * **Default export handling**: when `declaration.name === 'default'`, emits
75
+ * `import X from '...'` with the binding derived by PascalCasing the module
76
+ * path. (`'default'` is the symbol's actual name in JS — `import X from 'mod'`
77
+ * is sugar for `import {default as X} from 'mod'`.)
78
+ *
79
+ * @see `getDisplayName` for the divergent default-slot fallback used as a
80
+ * display label (the literal `'default'`, since a label has no use for a
81
+ * synthesized JS binding).
82
+ *
83
+ * @param declaration - the `DeclarationJson` to generate an import for
84
+ * @param modulePath - module path relative to source root (e.g., `foo.ts`)
85
+ * @param libraryName - package name for the import specifier (e.g., `@pkg/lib`)
86
+ * @returns formatted import statement string
87
+ *
88
+ * @example
89
+ * ```ts
90
+ * generateImport({name: 'Foo', kind: 'type'}, 'foo.ts', '@pkg/lib')
91
+ * // => "import type {Foo} from '@pkg/lib/foo.js';"
92
+ *
93
+ * generateImport({name: 'default', kind: 'function'}, 'foo-bar.ts', '@pkg/lib')
94
+ * // => "import FooBar from '@pkg/lib/foo-bar.js';"
95
+ * ```
96
+ */
97
+ export declare const generateImport: (declaration: DeclarationJson, modulePath: string, libraryName: string) => string;
98
+ /**
99
+ * Pre-compile identifier-boundary patterns for a set of declaration names.
100
+ *
101
+ * When scanning many type strings against the same declaration set,
102
+ * call this once and pass the result to `findTypeReferences`
103
+ * to avoid recompiling regexes on every call.
104
+ *
105
+ * @param declarationNames - set of known in-project declaration names
106
+ * @returns array of `[name, pattern]` pairs for use with `findTypeReferences`
107
+ *
108
+ * @example
109
+ * ```ts
110
+ * const names = new Set(modules.flatMap(m => m.declarations.map(d => d.name)));
111
+ * const patterns = buildTypeReferencePatterns(names);
112
+ * for (const decl of declarations) {
113
+ * const refs = findTypeReferences(decl.typeSignature, patterns);
114
+ * }
115
+ * ```
116
+ */
117
+ export declare const buildTypeReferencePatterns: (declarationNames: ReadonlySet<string>) => Array<[string, RegExp]>;
118
+ /**
119
+ * Find in-project declaration names referenced in a type string.
120
+ *
121
+ * Uses identifier-boundary matching to find which known declaration names appear
122
+ * in an opaque type string (e.g., `typeSignature`, `returnType`, parameter `type`).
123
+ * Enables consumers to render clickable type links without needing access to
124
+ * the TypeScript type checker.
125
+ *
126
+ * Handles identifiers starting with `$` (e.g., `$state`) which `\b` does not
127
+ * recognize as word boundaries.
128
+ *
129
+ * Accepts either a `ReadonlySet<string>` (convenience) or pre-compiled patterns
130
+ * from `buildTypeReferencePatterns` (performance). Use pre-compiled patterns
131
+ * when scanning many type strings against the same declaration set.
132
+ *
133
+ * **Known limitations**: Identifier-boundary matching can produce false positives
134
+ * when a declaration name appears as a property key in an object literal type
135
+ * (e.g., `{ Foo: string }` when `Foo` is a declaration). This is rare in practice.
136
+ *
137
+ * @param typeString - opaque type string from analysis output
138
+ * @param declarationNames - set of names or pre-compiled patterns from `buildTypeReferencePatterns`
139
+ * @returns array of declaration names found in the type string
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const names = new Set(modules.flatMap(m => m.declarations.map(d => d.name)));
144
+ * findTypeReferences('Map<string, ModuleJson[]>', names)
145
+ * // => ['ModuleJson']
146
+ * ```
147
+ */
148
+ export declare const findTypeReferences: (typeString: string, declarationNames: ReadonlySet<string> | Array<[string, RegExp]>) => Array<string>;
149
+ /**
150
+ * Narrow a declaration by kind for type-safe field access.
151
+ *
152
+ * Works with both `DeclarationJson` (top-level) and `MemberJson` (nested).
153
+ * Accepts `DeclarationKind | MemberKind` so `isKind(member, 'constructor')` compiles.
154
+ *
155
+ * @example
156
+ * ```ts
157
+ * if (isKind(declaration, 'function')) {
158
+ * declaration.parameters; // FunctionDeclarationJson — has parameters
159
+ * declaration.returnType; // has returnType
160
+ * }
161
+ * if (isKind(member, 'constructor')) {
162
+ * member.parameters; // ConstructorMemberJson — has parameters
163
+ * }
164
+ * ```
165
+ */
166
+ export declare const isKind: <K extends DeclarationKind | MemberKind>(declaration: DeclarationJson | MemberJson, kind: K) => declaration is Extract<DeclarationJson | MemberJson, {
167
+ kind: K;
168
+ }>;
169
+ //# sourceMappingURL=declaration-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declaration-helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/declaration-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAC,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAC,MAAM,YAAY,CAAC;AAIzF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,OAAO,OAAO,KAAG,OACqB,CAAC;AAIrF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,cAAc,GAAI,aAAa,eAAe,GAAG,UAAU,KAAG,MAS1E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,cAAc,GAC1B,aAAa,eAAe,EAC5B,YAAY,MAAM,EAClB,aAAa,MAAM,KACjB,MAuBF,CAAC;AA6BF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,0BAA0B,GACtC,kBAAkB,WAAW,CAAC,MAAM,CAAC,KACnC,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAMxB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,kBAAkB,GAC9B,YAAY,MAAM,EAClB,kBAAkB,WAAW,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAC7D,KAAK,CAAC,MAAM,CAYd,CAAC;AAIF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,eAAe,GAAG,UAAU,EAC5D,aAAa,eAAe,GAAG,UAAU,EACzC,MAAM,CAAC,KACL,WAAW,IAAI,OAAO,CAAC,eAAe,GAAG,UAAU,EAAE;IAAC,IAAI,EAAE,CAAC,CAAA;CAAC,CAA8B,CAAC"}
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Utility functions for working with declaration and member types.
3
+ *
4
+ * Display formatting, code generation, serialization, type narrowing,
5
+ * and type reference discovery for `DeclarationJson` and `MemberJson`.
6
+ *
7
+ * @see `types.ts` for `DeclarationJson`, `MemberJson` Zod schemas
8
+ *
9
+ * @module
10
+ */
11
+ // ── Serialization ───────────────────────────────────────────────────────────
12
+ /**
13
+ * JSON replacer that strips Zod default values for compact serialization.
14
+ *
15
+ * Strips empty arrays and `false` booleans — both are Zod `.default()` values
16
+ * restored on `.parse()`, so the round-trip is lossless for svelte-docinfo types.
17
+ * Assumes all boolean fields in the schema default to `false` — a `true`-defaulted
18
+ * boolean would need its `false` values preserved, breaking the round-trip.
19
+ *
20
+ * **Root-value caveat**: `JSON.stringify([], compactReplacer)` returns the JS
21
+ * `undefined` (not the string `'[]'`), and `JSON.stringify(false, compactReplacer)`
22
+ * returns the JS `undefined` too. Object-rooted callers (`AnalyzeResultJson`
23
+ * envelope, CLI output) don't hit this — empty inner arrays strip and
24
+ * `AnalyzeResultJson.parse` restores them on the consumer side. Array-rooted
25
+ * callers (Vite plugin, anyone splicing the JSON into a source template)
26
+ * must handle the empty case themselves before calling this; see
27
+ * `vite.ts:updateOutputFromQuery` for the pattern.
28
+ *
29
+ * Two guard tests in `declaration-helpers.test.ts` lock this in:
30
+ * - `every z.boolean().default in types.ts uses false` — source-regex check
31
+ * that fails on a new `z.boolean().default(true)`.
32
+ * - `parse → stringify(compactReplacer) → parse is a faithful round-trip
33
+ * across every variant` — exercises every variant and member through a
34
+ * full round-trip, catching regressions where a `.default(false)` or
35
+ * `.default([])` is removed (or a new field is added that the replacer
36
+ * drops but Zod doesn't restore).
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * const result = await analyze({sourceFiles, sourceOptions});
41
+ * const json = JSON.stringify(result, compactReplacer);
42
+ * // On the consumer side, restore Zod defaults:
43
+ * const restored = AnalyzeResultJson.parse(JSON.parse(json));
44
+ * ```
45
+ */
46
+ export const compactReplacer = (_key, value) => (Array.isArray(value) && value.length === 0) || value === false ? undefined : value;
47
+ // ── Display Helpers ─────────────────────────────────────────────────────────
48
+ /**
49
+ * Format declaration or member name with generic parameters for display.
50
+ *
51
+ * Default-slot entries return the literal `'default'` (the symbol's actual
52
+ * name in JS). Renderers that want a richer label (PascalCased module path,
53
+ * an explicit "default export" header) should branch on `name === 'default'`
54
+ * themselves before calling this.
55
+ *
56
+ * @see `generateImport` for the divergent default-slot fallback used in
57
+ * import-statement generation (PascalCased module path, since an import
58
+ * needs a JS identifier binding, not a label).
59
+ *
60
+ * @param declaration - the `DeclarationJson` or `MemberJson` to format
61
+ * @returns name with generic parameters appended (e.g., `Map<K, V>`)
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * getDisplayName({name: 'Map', kind: 'type', genericParams: [{name: 'K'}, {name: 'V'}]})
66
+ * // => 'Map<K, V>'
67
+ * ```
68
+ */
69
+ export const getDisplayName = (declaration) => {
70
+ if (!declaration.genericParams.length)
71
+ return declaration.name;
72
+ const params = declaration.genericParams.map((p) => {
73
+ let param = p.name;
74
+ if (p.constraint)
75
+ param += ` extends ${p.constraint}`;
76
+ if (p.defaultType)
77
+ param += ` = ${p.defaultType}`;
78
+ return param;
79
+ });
80
+ return `${declaration.name}<${params.join(', ')}>`;
81
+ };
82
+ /**
83
+ * Generate TypeScript import statement for a declaration.
84
+ *
85
+ * Produces `import type` for type/interface declarations, `import` for values.
86
+ *
87
+ * **Default export handling**: when `declaration.name === 'default'`, emits
88
+ * `import X from '...'` with the binding derived by PascalCasing the module
89
+ * path. (`'default'` is the symbol's actual name in JS — `import X from 'mod'`
90
+ * is sugar for `import {default as X} from 'mod'`.)
91
+ *
92
+ * @see `getDisplayName` for the divergent default-slot fallback used as a
93
+ * display label (the literal `'default'`, since a label has no use for a
94
+ * synthesized JS binding).
95
+ *
96
+ * @param declaration - the `DeclarationJson` to generate an import for
97
+ * @param modulePath - module path relative to source root (e.g., `foo.ts`)
98
+ * @param libraryName - package name for the import specifier (e.g., `@pkg/lib`)
99
+ * @returns formatted import statement string
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * generateImport({name: 'Foo', kind: 'type'}, 'foo.ts', '@pkg/lib')
104
+ * // => "import type {Foo} from '@pkg/lib/foo.js';"
105
+ *
106
+ * generateImport({name: 'default', kind: 'function'}, 'foo-bar.ts', '@pkg/lib')
107
+ * // => "import FooBar from '@pkg/lib/foo-bar.js';"
108
+ * ```
109
+ */
110
+ export const generateImport = (declaration, modulePath, libraryName) => {
111
+ const jsPath = modulePath.replace(/\.ts$/, '.js');
112
+ const specifier = `${libraryName}/${jsPath}`;
113
+ // Default-slot entries — derive the import binding from the module path.
114
+ if (declaration.name === 'default') {
115
+ return `import ${pascalCaseFromModulePath(modulePath)} from '${specifier}';`;
116
+ }
117
+ // Components are default exports in Svelte
118
+ if (declaration.kind === 'component') {
119
+ return `import ${declaration.name} from '${specifier}';`;
120
+ }
121
+ // Namespace re-export: `export * as ns from './x'` in the source becomes
122
+ // `import * as ns from '<package>/<re-exporter>.js'` for consumers.
123
+ if (declaration.kind === 'namespace') {
124
+ return `import * as ${declaration.name} from '${specifier}';`;
125
+ }
126
+ const importKeyword = declaration.kind === 'type' || declaration.kind === 'interface' ? 'import type' : 'import';
127
+ return `${importKeyword} {${declaration.name}} from '${specifier}';`;
128
+ };
129
+ const pascalCaseFromModulePath = (modulePath) => {
130
+ const moduleName = modulePath.replace(/\.(js|ts|svelte)$/, '');
131
+ return moduleName
132
+ .split(/[-_/]/)
133
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
134
+ .join('');
135
+ };
136
+ // ── Type Reference Helpers ─────────────────────────────────────────────────
137
+ /**
138
+ * Escape special regex characters in a string.
139
+ */
140
+ const escapeRegex = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
141
+ /** Matches TypeScript identifier characters (letters, digits, `_`, `$`). */
142
+ const ID_CHAR = '[a-zA-Z0-9_$]';
143
+ /**
144
+ * Build a regex that matches `name` only at identifier boundaries.
145
+ *
146
+ * Uses lookaround for `[a-zA-Z0-9_$]` instead of `\b` so that
147
+ * `$`-prefixed identifiers like `$state` are matched correctly.
148
+ */
149
+ const buildIdentifierPattern = (name) => new RegExp('(?<!' + ID_CHAR + ')' + escapeRegex(name) + '(?!' + ID_CHAR + ')');
150
+ /**
151
+ * Pre-compile identifier-boundary patterns for a set of declaration names.
152
+ *
153
+ * When scanning many type strings against the same declaration set,
154
+ * call this once and pass the result to `findTypeReferences`
155
+ * to avoid recompiling regexes on every call.
156
+ *
157
+ * @param declarationNames - set of known in-project declaration names
158
+ * @returns array of `[name, pattern]` pairs for use with `findTypeReferences`
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * const names = new Set(modules.flatMap(m => m.declarations.map(d => d.name)));
163
+ * const patterns = buildTypeReferencePatterns(names);
164
+ * for (const decl of declarations) {
165
+ * const refs = findTypeReferences(decl.typeSignature, patterns);
166
+ * }
167
+ * ```
168
+ */
169
+ export const buildTypeReferencePatterns = (declarationNames) => {
170
+ const patterns = [];
171
+ for (const name of declarationNames) {
172
+ if (name)
173
+ patterns.push([name, buildIdentifierPattern(name)]);
174
+ }
175
+ return patterns;
176
+ };
177
+ /**
178
+ * Find in-project declaration names referenced in a type string.
179
+ *
180
+ * Uses identifier-boundary matching to find which known declaration names appear
181
+ * in an opaque type string (e.g., `typeSignature`, `returnType`, parameter `type`).
182
+ * Enables consumers to render clickable type links without needing access to
183
+ * the TypeScript type checker.
184
+ *
185
+ * Handles identifiers starting with `$` (e.g., `$state`) which `\b` does not
186
+ * recognize as word boundaries.
187
+ *
188
+ * Accepts either a `ReadonlySet<string>` (convenience) or pre-compiled patterns
189
+ * from `buildTypeReferencePatterns` (performance). Use pre-compiled patterns
190
+ * when scanning many type strings against the same declaration set.
191
+ *
192
+ * **Known limitations**: Identifier-boundary matching can produce false positives
193
+ * when a declaration name appears as a property key in an object literal type
194
+ * (e.g., `{ Foo: string }` when `Foo` is a declaration). This is rare in practice.
195
+ *
196
+ * @param typeString - opaque type string from analysis output
197
+ * @param declarationNames - set of names or pre-compiled patterns from `buildTypeReferencePatterns`
198
+ * @returns array of declaration names found in the type string
199
+ *
200
+ * @example
201
+ * ```ts
202
+ * const names = new Set(modules.flatMap(m => m.declarations.map(d => d.name)));
203
+ * findTypeReferences('Map<string, ModuleJson[]>', names)
204
+ * // => ['ModuleJson']
205
+ * ```
206
+ */
207
+ export const findTypeReferences = (typeString, declarationNames) => {
208
+ if (!typeString)
209
+ return [];
210
+ const patterns = Array.isArray(declarationNames)
211
+ ? declarationNames
212
+ : buildTypeReferencePatterns(declarationNames);
213
+ const refs = [];
214
+ for (const [name, pattern] of patterns) {
215
+ if (pattern.test(typeString)) {
216
+ refs.push(name);
217
+ }
218
+ }
219
+ return refs;
220
+ };
221
+ // ── Narrowed Declaration Types ──────────────────────────────────────────────
222
+ /**
223
+ * Narrow a declaration by kind for type-safe field access.
224
+ *
225
+ * Works with both `DeclarationJson` (top-level) and `MemberJson` (nested).
226
+ * Accepts `DeclarationKind | MemberKind` so `isKind(member, 'constructor')` compiles.
227
+ *
228
+ * @example
229
+ * ```ts
230
+ * if (isKind(declaration, 'function')) {
231
+ * declaration.parameters; // FunctionDeclarationJson — has parameters
232
+ * declaration.returnType; // has returnType
233
+ * }
234
+ * if (isKind(member, 'constructor')) {
235
+ * member.parameters; // ConstructorMemberJson — has parameters
236
+ * }
237
+ * ```
238
+ */
239
+ export const isKind = (declaration, kind) => declaration.kind === kind;
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Import resolver primitives for the analysis session.
3
+ *
4
+ * Exposes the `ImportResolver` token contract (`{resolve, identity}`) plus
5
+ * building blocks the session uses inside its three-phase setFiles pipeline:
6
+ *
7
+ * - `ensureLexerReady` — one-time wasm init for `es-module-lexer`. Phase 1 is
8
+ * sync per-file; the session awaits this once before the loop starts.
9
+ * - `lexImports` — sync specifier extraction from already-prepared content
10
+ * (raw TS/JS, or svelte2tsx virtual content for `.svelte` files).
11
+ * - `createDefaultResolver` — the TS + tsconfig fallback used when neither
12
+ * `AnalysisSessionOptions.resolveImport` nor a per-call override is provided.
13
+ * Carries a fresh symbol identity per session (cache-key-safe).
14
+ * - `normalizeResolveImport` — coerces the public `ResolveImport` union (bare
15
+ * function or token-paired resolver) to an `ImportResolver` at each boundary.
16
+ * - `wrapResolveImport` — the fn→token primitive behind `normalizeResolveImport`:
17
+ * wraps a bare function in an `ImportResolver`, synthesizing a throwaway
18
+ * identity unless a stable one is passed.
19
+ *
20
+ * @internal — subpath-importable for power users who want to drive resolution
21
+ * outside the session, but not part of the stable barrel surface.
22
+ *
23
+ * @see `session.ts` for the three-phase ingestion pipeline that consumes these
24
+ * @see `loadTsconfig` in `typescript-program.ts` for the TS module-resolution
25
+ * compiler-options shortcut used by the default resolver
26
+ *
27
+ * @module
28
+ */
29
+ import ts from 'typescript';
30
+ /**
31
+ * Bare import-resolver function — the convenience form.
32
+ *
33
+ * Resolve an import specifier to an absolute file path, or `null` if the
34
+ * specifier is unresolvable (external package, missing file, etc.). May return
35
+ * synchronously or asynchronously; sync returns are awaited harmlessly in the
36
+ * session's parallel resolve phase.
37
+ *
38
+ * @param specifier - import specifier from source code
39
+ * @param fromFile - absolute path of the importing file
40
+ */
41
+ export type ResolveImportFn = (specifier: string, fromFile: string) => string | null | Promise<string | null>;
42
+ /**
43
+ * Token-paired import resolver.
44
+ *
45
+ * `identity` is a stable opaque token that keys the session's resolve cache
46
+ * alongside content. Cache hits require both (a) byte-for-byte identical
47
+ * source content and (b) identity equality. Naive function-reference keys
48
+ * would silently destroy cache reuse when callers wrap the resolver in fresh
49
+ * closures (a very common pattern in Vite/Rollup plugins) — opaque tokens
50
+ * lift the responsibility to the caller, where it can be done correctly.
51
+ */
52
+ export interface ImportResolver {
53
+ /** Resolve an import specifier to an absolute file path, or `null`. */
54
+ resolve: ResolveImportFn;
55
+ /**
56
+ * Stable opaque token identifying this resolver's cache scope.
57
+ *
58
+ * Two `ImportResolver`s with `identity` `===` to each other are treated
59
+ * as cache-equivalent. `string` for human-readable identities (e.g.,
60
+ * `'vite-plugin-container'`); `symbol` for generated sentinels.
61
+ */
62
+ identity: string | symbol;
63
+ }
64
+ /**
65
+ * Public resolver shape accepted across the API — a bare `ResolveImportFn` or
66
+ * the token-paired `ImportResolver`.
67
+ *
68
+ * Every entry point that accepts `resolveImport` (`analyze`, `analyzeFromFiles`,
69
+ * `createAnalysisSession`, and the session's `setFile`/`setFiles` per-call
70
+ * override) takes this union, so the same value copy-pastes between them. Pass:
71
+ *
72
+ * - a **bare function** for the common case — a fresh cache identity is
73
+ * synthesized at the boundary. Correct for one-shot use (`analyze`,
74
+ * `analyzeFromFiles`) and for a session default (wrapped once at
75
+ * construction, so identity is stable for the session's lifetime).
76
+ * - an **`ImportResolver`** with a stable `identity` when you need the session
77
+ * to reuse its resolve cache across calls where the same logical resolver is
78
+ * rebuilt as a fresh closure (Vite/Rollup plugins). A bare function handed to
79
+ * a *per-call* `setFile`/`setFiles` override is treated as a distinct
80
+ * resolver each call (fresh identity → touched files re-resolve), which is
81
+ * the expected behavior for a deliberate one-off override.
82
+ */
83
+ export type ResolveImport = ResolveImportFn | ImportResolver;
84
+ /**
85
+ * Normalize the public `ResolveImport` union to an `ImportResolver`.
86
+ *
87
+ * Wraps a bare function via `wrapResolveImport` (fresh synthesized identity);
88
+ * passes a token-paired resolver through unchanged. `undefined` in, `undefined`
89
+ * out — callers fall back to the session default. Call once per logical
90
+ * resolver scope: at session construction for the default, per call for an
91
+ * override.
92
+ */
93
+ export declare const normalizeResolveImport: (value: ResolveImport | undefined) => ImportResolver | undefined;
94
+ /**
95
+ * Ensure `es-module-lexer`'s wasm runtime is initialized.
96
+ *
97
+ * Idempotent and cheap after the first call. The session awaits this once at
98
+ * the top of `setFiles` so phase 1's per-file lex is purely synchronous.
99
+ */
100
+ export declare const ensureLexerReady: () => Promise<void>;
101
+ /**
102
+ * Lex import specifiers from prepared content.
103
+ *
104
+ * Sync — caller must have awaited `ensureLexerReady` at least once before
105
+ * invoking. For `.svelte` files, pass the svelte2tsx-transformed virtual
106
+ * content, not the raw `.svelte` source (which isn't lex-able as JS/TS).
107
+ *
108
+ * Dynamic imports (`import(specifier)` with non-literal arg) are omitted.
109
+ *
110
+ * @throws Error if lexing fails (malformed source). Callers should catch and
111
+ * emit `import_parse_failed`.
112
+ *
113
+ * @param content - prepared file content (TS/JS, or svelte2tsx virtual)
114
+ * @param fileId - absolute file path (used for error messages)
115
+ * @returns specifiers in declaration order
116
+ */
117
+ export declare const lexImports: (content: string, fileId: string) => Array<string>;
118
+ /**
119
+ * Create the default `ImportResolver` (TypeScript + tsconfig).
120
+ *
121
+ * Uses `ts.resolveModuleName` against `ts.sys` directly — no `ts.Program` is
122
+ * built. Identity is a fresh symbol per call, so each session that constructs
123
+ * its own default gets a unique cache scope. Multiple sessions sharing one
124
+ * resolver instance share the cache scope (correct, since resolver state is
125
+ * shared too).
126
+ *
127
+ * Falls back to appending `.svelte` when the bare specifier doesn't resolve —
128
+ * lets `.svelte` imports work without polluting the consumer's tsconfig.
129
+ *
130
+ * @param compilerOptions - parsed tsconfig (from `loadTsconfig`)
131
+ * @param projectRoot - absolute project root for the module-resolution cache
132
+ */
133
+ export declare const createDefaultResolver: (compilerOptions: ts.CompilerOptions, projectRoot: string) => ImportResolver;
134
+ /**
135
+ * Wrap a bare `resolveImport` function into an `ImportResolver` token.
136
+ *
137
+ * `identity` is optional; when omitted, a fresh `Symbol('wrapped')` is
138
+ * synthesized per call. The synthesized default suits single-use scopes —
139
+ * `normalizeResolveImport` relies on it to wrap a bare function for a one-shot
140
+ * `analyze` call or for a session default (wrapped once at construction, so the
141
+ * identity stays stable for the session's lifetime).
142
+ *
143
+ * For a long-lived session that re-wraps the *same* logical resolver across
144
+ * calls (Vite plugin, LSP), a throwaway identity cache-misses every time — the
145
+ * fresh `Symbol('wrapped')` never compares equal. Pass a stable `identity`
146
+ * here, or — simpler — construct an `ImportResolver` (`{resolve, identity}`)
147
+ * directly and pass it through the `ResolveImport` union.
148
+ */
149
+ export declare const wrapResolveImport: (resolveImport: ResolveImportFn, identity?: string | symbol) => ImportResolver;
150
+ /**
151
+ * Shared no-op `ImportResolver` for the "dependency resolution disabled" case.
152
+ *
153
+ * Stable string identity (`'no-deps'`) instead of a per-call symbol so that
154
+ * repeated ingests within a long-lived session cache-hit on identity. Each
155
+ * session still owns its own cache (entries live on the per-session `owned`
156
+ * map; sessions don't share state), but within one session every reference
157
+ * to `noDepsResolver` is `===` to every other — so a Vite re-save of
158
+ * byte-identical content with `resolveDependencies: false` exercises the
159
+ * cache-hit branch. The resolver always returns `null`, so any two calls
160
+ * with identical content under this identity produce identical resolution
161
+ * results — `string` identity correctly captures that. Used by both the
162
+ * one-shot `analyzeFromFiles` path and the long-lived Vite plugin
163
+ * (`resolveDependencies: false`).
164
+ */
165
+ export declare const noDepsResolver: ImportResolver;
166
+ //# sourceMappingURL=dep-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dep-resolver.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/dep-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B;;;;;;;;;;GAUG;AACH,MAAM,MAAM,eAAe,GAAG,CAC7B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,KACZ,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAE5C;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC9B,uEAAuE;IACvE,OAAO,EAAE,eAAe,CAAC;IACzB;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,cAAc,CAAC;AAE7D;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GAClC,OAAO,aAAa,GAAG,SAAS,KAC9B,cAAc,GAAG,SAC6E,CAAC;AAElG;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,IAAI,CAErD,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,KAAK,CAAC,MAAM,CAOxE,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,GACjC,iBAAiB,EAAE,CAAC,eAAe,EACnC,aAAa,MAAM,KACjB,cAwBF,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,GAC7B,eAAe,eAAe,EAC9B,WAAU,MAAM,GAAG,MAA0B,KAC3C,cAGD,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,cAAc,EAAE,cAG5B,CAAC"}