@fuzdev/fuz_ui 0.175.0 → 0.176.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/Alert.svelte +2 -0
- package/dist/Alert.svelte.d.ts.map +1 -1
- package/dist/ApiModule.svelte +5 -6
- package/dist/ApiModule.svelte.d.ts.map +1 -1
- package/dist/DeclarationDetail.svelte +2 -1
- package/dist/DeclarationDetail.svelte.d.ts.map +1 -1
- package/dist/Details.svelte +2 -0
- package/dist/Details.svelte.d.ts.map +1 -1
- package/dist/Themed.svelte +2 -0
- package/dist/Themed.svelte.d.ts.map +1 -1
- package/dist/analysis_context.d.ts +195 -0
- package/dist/analysis_context.d.ts.map +1 -0
- package/dist/analysis_context.js +134 -0
- package/dist/library_analysis.d.ts +112 -0
- package/dist/library_analysis.d.ts.map +1 -0
- package/dist/library_analysis.js +106 -0
- package/dist/library_gen.d.ts +88 -5
- package/dist/library_gen.d.ts.map +1 -1
- package/dist/library_gen.js +163 -69
- package/dist/library_gen_helpers.d.ts +81 -72
- package/dist/library_gen_helpers.d.ts.map +1 -1
- package/dist/library_gen_helpers.js +115 -156
- package/dist/library_gen_output.d.ts +34 -0
- package/dist/library_gen_output.d.ts.map +1 -0
- package/dist/library_gen_output.js +40 -0
- package/dist/mdz.d.ts +3 -0
- package/dist/mdz.d.ts.map +1 -1
- package/dist/mdz.js +12 -3
- package/dist/module_helpers.d.ts +246 -24
- package/dist/module_helpers.d.ts.map +1 -1
- package/dist/module_helpers.js +250 -42
- package/dist/svelte_helpers.d.ts +65 -10
- package/dist/svelte_helpers.d.ts.map +1 -1
- package/dist/svelte_helpers.js +171 -49
- package/dist/ts_helpers.d.ts +132 -61
- package/dist/ts_helpers.d.ts.map +1 -1
- package/dist/ts_helpers.js +423 -282
- package/dist/tsdoc_helpers.d.ts +11 -0
- package/dist/tsdoc_helpers.d.ts.map +1 -1
- package/dist/tsdoc_helpers.js +22 -47
- package/dist/tsdoc_mdz.d.ts +36 -0
- package/dist/tsdoc_mdz.d.ts.map +1 -0
- package/dist/tsdoc_mdz.js +56 -0
- package/dist/vite_plugin_library_well_known.js +5 -5
- package/package.json +11 -6
- package/src/lib/analysis_context.ts +250 -0
- package/src/lib/library_analysis.ts +168 -0
- package/src/lib/library_gen.ts +247 -84
- package/src/lib/library_gen_helpers.ts +148 -215
- package/src/lib/library_gen_output.ts +63 -0
- package/src/lib/mdz.ts +13 -4
- package/src/lib/module_helpers.ts +392 -47
- package/src/lib/svelte_helpers.ts +291 -55
- package/src/lib/ts_helpers.ts +538 -338
- package/src/lib/tsdoc_helpers.ts +24 -49
- package/src/lib/tsdoc_mdz.ts +62 -0
- package/src/lib/vite_plugin_library_well_known.ts +5 -5
package/dist/svelte_helpers.d.ts
CHANGED
|
@@ -10,28 +10,83 @@
|
|
|
10
10
|
* Workflow: Transform Svelte to TypeScript via svelte2tsx, parse the transformed
|
|
11
11
|
* TypeScript with the TS Compiler API, extract component-level JSDoc from original source.
|
|
12
12
|
*
|
|
13
|
+
* **Svelte 5 only**: The svelte2tsx output format changed significantly between versions.
|
|
14
|
+
* This module requires Svelte 5+ and will throw a clear error if an older version is detected.
|
|
15
|
+
* There is no Svelte 4 compatibility layer.
|
|
16
|
+
*
|
|
13
17
|
* All functions are prefixed with `svelte_` for clarity.
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
14
20
|
*/
|
|
15
21
|
import ts from 'typescript';
|
|
22
|
+
import { TraceMap } from '@jridgewell/trace-mapping';
|
|
16
23
|
import type { DeclarationJson } from '@fuzdev/fuz_util/source_json.js';
|
|
24
|
+
import { type SourceFileInfo, type ModuleSourceOptions } from './module_helpers.js';
|
|
25
|
+
import type { AnalysisContext } from './analysis_context.js';
|
|
26
|
+
import type { ModuleAnalysis } from './library_analysis.js';
|
|
27
|
+
/** Result of analyzing a Svelte file. */
|
|
28
|
+
export interface SvelteFileAnalysis {
|
|
29
|
+
/** The component declaration metadata. */
|
|
30
|
+
declaration: DeclarationJson;
|
|
31
|
+
/** Module-level documentation comment, if present. */
|
|
32
|
+
module_comment?: string;
|
|
33
|
+
}
|
|
17
34
|
/**
|
|
18
|
-
* Analyze a Svelte component
|
|
35
|
+
* Analyze a Svelte component file and extract module metadata.
|
|
36
|
+
*
|
|
37
|
+
* Wraps `svelte_analyze_file` and adds dependency information
|
|
38
|
+
* from the source file info if available.
|
|
39
|
+
*
|
|
40
|
+
* This is a high-level function suitable for building documentation or library metadata.
|
|
41
|
+
* For lower-level analysis, use `svelte_analyze_file` directly.
|
|
42
|
+
*
|
|
43
|
+
* Returns raw analysis data matching `ModuleAnalysis` structure.
|
|
44
|
+
* Consumer decides filtering policy (Svelte components are never nodocs).
|
|
45
|
+
*
|
|
46
|
+
* @param source_file The source file info (from Gro filer, file system, or other source)
|
|
47
|
+
* @param module_path The module path (relative to source root)
|
|
48
|
+
* @param checker TypeScript type checker
|
|
49
|
+
* @param options Module source options for path extraction
|
|
50
|
+
* @param ctx Analysis context for collecting diagnostics
|
|
51
|
+
* @returns Module analysis matching ModuleAnalysis structure
|
|
19
52
|
*/
|
|
20
|
-
export declare const
|
|
53
|
+
export declare const svelte_analyze_module: (source_file: SourceFileInfo, module_path: string, checker: ts.TypeChecker, options: ModuleSourceOptions, ctx: AnalysisContext) => ModuleAnalysis;
|
|
21
54
|
/**
|
|
22
|
-
* Analyze a Svelte component file
|
|
55
|
+
* Analyze a Svelte component file.
|
|
23
56
|
*
|
|
24
57
|
* This is a high-level function that handles the complete workflow:
|
|
25
|
-
* 1.
|
|
26
|
-
* 2.
|
|
27
|
-
* 3. Extract
|
|
58
|
+
* 1. Transform Svelte source to TypeScript via svelte2tsx
|
|
59
|
+
* 2. Extract component metadata (props, documentation)
|
|
60
|
+
* 3. Extract module-level documentation
|
|
28
61
|
*
|
|
29
62
|
* Suitable for use in documentation generators, build tools, and analysis.
|
|
30
63
|
*
|
|
31
|
-
* @param
|
|
32
|
-
* @param module_path Module path relative to
|
|
64
|
+
* @param source_file Source file info with path and content
|
|
65
|
+
* @param module_path Module path relative to source root (e.g., 'Alert.svelte')
|
|
33
66
|
* @param checker TypeScript type checker for type resolution
|
|
34
|
-
* @
|
|
67
|
+
* @param ctx Analysis context for collecting diagnostics
|
|
68
|
+
* @returns Component declaration and optional module-level comment
|
|
69
|
+
*/
|
|
70
|
+
export declare const svelte_analyze_file: (source_file: SourceFileInfo, module_path: string, checker: ts.TypeChecker, ctx: AnalysisContext) => SvelteFileAnalysis;
|
|
71
|
+
/**
|
|
72
|
+
* Analyze a Svelte component from its svelte2tsx transformation.
|
|
73
|
+
*/
|
|
74
|
+
export declare const svelte_analyze_component: (ts_code: string, source_file: ts.SourceFile, checker: ts.TypeChecker, component_name: string, file_path: string, source_map: TraceMap | null, ctx: AnalysisContext) => DeclarationJson;
|
|
75
|
+
/**
|
|
76
|
+
* Extract the content of the main `<script>` tag from Svelte source.
|
|
77
|
+
*
|
|
78
|
+
* Matches `<script>` or `<script lang="ts">` but not `<script module>`.
|
|
79
|
+
* Returns undefined if no matching script tag is found.
|
|
80
|
+
*/
|
|
81
|
+
export declare const svelte_extract_script_content: (svelte_source: string) => string | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Extract module-level comment from Svelte script content.
|
|
84
|
+
*
|
|
85
|
+
* Requires `@module` tag to identify module comments. The tag line is stripped
|
|
86
|
+
* from the output.
|
|
87
|
+
*
|
|
88
|
+
* @param script_content - The content of the `<script>` tag.
|
|
89
|
+
* @returns The cleaned module comment text, or undefined if none found.
|
|
35
90
|
*/
|
|
36
|
-
export declare const
|
|
91
|
+
export declare const svelte_extract_module_comment: (script_content: string) => string | undefined;
|
|
37
92
|
//# sourceMappingURL=svelte_helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svelte_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/svelte_helpers.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"svelte_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/svelte_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAC,QAAQ,EAAsB,MAAM,2BAA2B,CAAC;AAExE,OAAO,KAAK,EAAC,eAAe,EAAoB,MAAM,iCAAiC,CAAC;AAIxF,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,mBAAmB,EAGxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAE3D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAqB1D,yCAAyC;AACzC,MAAM,WAAW,kBAAkB;IAClC,0CAA0C;IAC1C,WAAW,EAAE,eAAe,CAAC;IAC7B,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,GACjC,aAAa,cAAc,EAC3B,aAAa,MAAM,EACnB,SAAS,EAAE,CAAC,WAAW,EACvB,SAAS,mBAAmB,EAC5B,KAAK,eAAe,KAClB,cAiBF,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mBAAmB,GAC/B,aAAa,cAAc,EAC3B,aAAa,MAAM,EACnB,SAAS,EAAE,CAAC,WAAW,EACvB,KAAK,eAAe,KAClB,kBAqDF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,wBAAwB,GACpC,SAAS,MAAM,EACf,aAAa,EAAE,CAAC,UAAU,EAC1B,SAAS,EAAE,CAAC,WAAW,EACvB,gBAAgB,MAAM,EACtB,WAAW,MAAM,EACjB,YAAY,QAAQ,GAAG,IAAI,EAC3B,KAAK,eAAe,KAClB,eA0CF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,GAAI,eAAe,MAAM,KAAG,MAAM,GAAG,SAM9E,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,GAAI,gBAAgB,MAAM,KAAG,MAAM,GAAG,SAU/E,CAAC"}
|
package/dist/svelte_helpers.js
CHANGED
|
@@ -10,17 +10,124 @@
|
|
|
10
10
|
* Workflow: Transform Svelte to TypeScript via svelte2tsx, parse the transformed
|
|
11
11
|
* TypeScript with the TS Compiler API, extract component-level JSDoc from original source.
|
|
12
12
|
*
|
|
13
|
+
* **Svelte 5 only**: The svelte2tsx output format changed significantly between versions.
|
|
14
|
+
* This module requires Svelte 5+ and will throw a clear error if an older version is detected.
|
|
15
|
+
* There is no Svelte 4 compatibility layer.
|
|
16
|
+
*
|
|
13
17
|
* All functions are prefixed with `svelte_` for clarity.
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
14
20
|
*/
|
|
15
21
|
import ts from 'typescript';
|
|
16
|
-
import { readFileSync } from 'node:fs';
|
|
17
22
|
import { svelte2tsx } from 'svelte2tsx';
|
|
23
|
+
import { TraceMap, originalPositionFor } from '@jridgewell/trace-mapping';
|
|
24
|
+
import { VERSION } from 'svelte/compiler';
|
|
18
25
|
import { tsdoc_parse, tsdoc_apply_to_declaration } from './tsdoc_helpers.js';
|
|
19
|
-
import {
|
|
26
|
+
import { ts_extract_module_comment } from './ts_helpers.js';
|
|
27
|
+
import { module_get_component_name, module_extract_dependencies, } from './module_helpers.js';
|
|
28
|
+
/** Guard to ensure version check runs only once. */
|
|
29
|
+
let svelte_version_checked = false;
|
|
30
|
+
/**
|
|
31
|
+
* Assert Svelte 5+ is installed (lazy, runs once on first use).
|
|
32
|
+
* Throws a clear error message if an older version is detected.
|
|
33
|
+
*/
|
|
34
|
+
const svelte_assert_version = () => {
|
|
35
|
+
if (svelte_version_checked)
|
|
36
|
+
return;
|
|
37
|
+
svelte_version_checked = true;
|
|
38
|
+
const [major] = VERSION.split('.');
|
|
39
|
+
if (parseInt(major, 10) < 5) {
|
|
40
|
+
throw new Error(`Svelte ${VERSION} detected but Svelte 5+ is required for source analysis. ` +
|
|
41
|
+
`The svelte2tsx output format changed significantly between versions.`);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Analyze a Svelte component file and extract module metadata.
|
|
46
|
+
*
|
|
47
|
+
* Wraps `svelte_analyze_file` and adds dependency information
|
|
48
|
+
* from the source file info if available.
|
|
49
|
+
*
|
|
50
|
+
* This is a high-level function suitable for building documentation or library metadata.
|
|
51
|
+
* For lower-level analysis, use `svelte_analyze_file` directly.
|
|
52
|
+
*
|
|
53
|
+
* Returns raw analysis data matching `ModuleAnalysis` structure.
|
|
54
|
+
* Consumer decides filtering policy (Svelte components are never nodocs).
|
|
55
|
+
*
|
|
56
|
+
* @param source_file The source file info (from Gro filer, file system, or other source)
|
|
57
|
+
* @param module_path The module path (relative to source root)
|
|
58
|
+
* @param checker TypeScript type checker
|
|
59
|
+
* @param options Module source options for path extraction
|
|
60
|
+
* @param ctx Analysis context for collecting diagnostics
|
|
61
|
+
* @returns Module analysis matching ModuleAnalysis structure
|
|
62
|
+
*/
|
|
63
|
+
export const svelte_analyze_module = (source_file, module_path, checker, options, ctx) => {
|
|
64
|
+
// Use the existing helper for core analysis
|
|
65
|
+
const { declaration, module_comment } = svelte_analyze_file(source_file, module_path, checker, ctx);
|
|
66
|
+
// Extract dependencies and dependents if provided
|
|
67
|
+
const { dependencies, dependents } = module_extract_dependencies(source_file, options);
|
|
68
|
+
return {
|
|
69
|
+
path: module_path,
|
|
70
|
+
module_comment,
|
|
71
|
+
// Wrap declaration in DeclarationAnalysis format (Svelte components are never nodocs)
|
|
72
|
+
declarations: [{ declaration, nodocs: false }],
|
|
73
|
+
dependencies,
|
|
74
|
+
dependents,
|
|
75
|
+
star_exports: [],
|
|
76
|
+
re_exports: [],
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Analyze a Svelte component file.
|
|
81
|
+
*
|
|
82
|
+
* This is a high-level function that handles the complete workflow:
|
|
83
|
+
* 1. Transform Svelte source to TypeScript via svelte2tsx
|
|
84
|
+
* 2. Extract component metadata (props, documentation)
|
|
85
|
+
* 3. Extract module-level documentation
|
|
86
|
+
*
|
|
87
|
+
* Suitable for use in documentation generators, build tools, and analysis.
|
|
88
|
+
*
|
|
89
|
+
* @param source_file Source file info with path and content
|
|
90
|
+
* @param module_path Module path relative to source root (e.g., 'Alert.svelte')
|
|
91
|
+
* @param checker TypeScript type checker for type resolution
|
|
92
|
+
* @param ctx Analysis context for collecting diagnostics
|
|
93
|
+
* @returns Component declaration and optional module-level comment
|
|
94
|
+
*/
|
|
95
|
+
export const svelte_analyze_file = (source_file, module_path, checker, ctx) => {
|
|
96
|
+
svelte_assert_version();
|
|
97
|
+
const svelte_source = source_file.content;
|
|
98
|
+
// Check if component uses TypeScript
|
|
99
|
+
const is_ts_file = svelte_source.includes('lang="ts"');
|
|
100
|
+
// Transform Svelte to TS
|
|
101
|
+
const ts_result = svelte2tsx(svelte_source, {
|
|
102
|
+
filename: source_file.id,
|
|
103
|
+
isTsFile: is_ts_file,
|
|
104
|
+
emitOnTemplateError: true, // Handle malformed templates gracefully
|
|
105
|
+
});
|
|
106
|
+
// Create source map for position mapping back to original .svelte file
|
|
107
|
+
let source_map = null;
|
|
108
|
+
try {
|
|
109
|
+
// svelte2tsx returns a magic-string SourceMap which is compatible with TraceMap
|
|
110
|
+
// Cast to unknown first since the types don't perfectly align but are compatible
|
|
111
|
+
source_map = new TraceMap(ts_result.map);
|
|
112
|
+
}
|
|
113
|
+
catch (_error) {
|
|
114
|
+
// If source map parsing fails, diagnostics will use virtual file positions
|
|
115
|
+
}
|
|
116
|
+
// Get component name from filename
|
|
117
|
+
const component_name = module_get_component_name(module_path);
|
|
118
|
+
// Create a temporary source file from the original Svelte content for JSDoc extraction
|
|
119
|
+
const temp_source = ts.createSourceFile(source_file.id, svelte_source, ts.ScriptTarget.Latest, true);
|
|
120
|
+
// Analyze the component using the existing lower-level function
|
|
121
|
+
const declaration = svelte_analyze_component(ts_result.code, temp_source, checker, component_name, module_path, source_map, ctx);
|
|
122
|
+
// Extract module-level comment from the script content
|
|
123
|
+
const script_content = svelte_extract_script_content(svelte_source);
|
|
124
|
+
const module_comment = script_content ? svelte_extract_module_comment(script_content) : undefined;
|
|
125
|
+
return { declaration, module_comment };
|
|
126
|
+
};
|
|
20
127
|
/**
|
|
21
128
|
* Analyze a Svelte component from its svelte2tsx transformation.
|
|
22
129
|
*/
|
|
23
|
-
export const svelte_analyze_component = (ts_code, source_file, checker, component_name) => {
|
|
130
|
+
export const svelte_analyze_component = (ts_code, source_file, checker, component_name, file_path, source_map, ctx) => {
|
|
24
131
|
const result = {
|
|
25
132
|
name: component_name,
|
|
26
133
|
kind: 'component',
|
|
@@ -33,7 +140,7 @@ export const svelte_analyze_component = (ts_code, source_file, checker, componen
|
|
|
33
140
|
const component_tsdoc = svelte_extract_component_tsdoc(virtual_source);
|
|
34
141
|
tsdoc_apply_to_declaration(result, component_tsdoc);
|
|
35
142
|
// Extract props from svelte2tsx transformed output
|
|
36
|
-
const props = svelte_extract_props(virtual_source, checker);
|
|
143
|
+
const props = svelte_extract_props(virtual_source, checker, component_name, file_path, source_map, ctx);
|
|
37
144
|
if (props.length > 0) {
|
|
38
145
|
result.props = props;
|
|
39
146
|
}
|
|
@@ -42,12 +149,37 @@ export const svelte_analyze_component = (ts_code, source_file, checker, componen
|
|
|
42
149
|
result.source_line = start_pos.line + 1;
|
|
43
150
|
}
|
|
44
151
|
catch (error) {
|
|
45
|
-
|
|
46
|
-
// eslint-disable-next-line no-console
|
|
47
|
-
console.error(`Error analyzing Svelte component ${component_name}:`, error);
|
|
152
|
+
throw new Error(`Failed to analyze Svelte component ${component_name}`, { cause: error });
|
|
48
153
|
}
|
|
49
154
|
return result;
|
|
50
155
|
};
|
|
156
|
+
/**
|
|
157
|
+
* Extract the content of the main `<script>` tag from Svelte source.
|
|
158
|
+
*
|
|
159
|
+
* Matches `<script>` or `<script lang="ts">` but not `<script module>`.
|
|
160
|
+
* Returns undefined if no matching script tag is found.
|
|
161
|
+
*/
|
|
162
|
+
export const svelte_extract_script_content = (svelte_source) => {
|
|
163
|
+
// Match <script> or <script lang="ts"> but not <script module>
|
|
164
|
+
// Captures the content between opening and closing tags
|
|
165
|
+
const script_regex = /<script(?:\s+lang=["']ts["'])?(?:\s*)>([^]*?)<\/script>/i;
|
|
166
|
+
const match = script_regex.exec(svelte_source);
|
|
167
|
+
return match?.[1];
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Extract module-level comment from Svelte script content.
|
|
171
|
+
*
|
|
172
|
+
* Requires `@module` tag to identify module comments. The tag line is stripped
|
|
173
|
+
* from the output.
|
|
174
|
+
*
|
|
175
|
+
* @param script_content - The content of the `<script>` tag.
|
|
176
|
+
* @returns The cleaned module comment text, or undefined if none found.
|
|
177
|
+
*/
|
|
178
|
+
export const svelte_extract_module_comment = (script_content) => {
|
|
179
|
+
// Parse the script content as TypeScript and reuse the shared extraction logic
|
|
180
|
+
const source_file = ts.createSourceFile('script.ts', script_content, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
181
|
+
return ts_extract_module_comment(source_file);
|
|
182
|
+
};
|
|
51
183
|
/**
|
|
52
184
|
* Extract component-level TSDoc comment from svelte2tsx transformed output.
|
|
53
185
|
*
|
|
@@ -81,9 +213,9 @@ const svelte_extract_component_tsdoc = (source_file) => {
|
|
|
81
213
|
return found_tsdoc;
|
|
82
214
|
};
|
|
83
215
|
/**
|
|
84
|
-
*
|
|
216
|
+
* Extract prop info from a property signature member.
|
|
85
217
|
*/
|
|
86
|
-
const svelte_extract_prop_from_member = (member, source_file, checker) => {
|
|
218
|
+
const svelte_extract_prop_from_member = (member, source_file, checker, component_name, file_path, source_map, ctx) => {
|
|
87
219
|
if (!ts.isIdentifier(member.name))
|
|
88
220
|
return undefined;
|
|
89
221
|
const prop_name = member.name.text;
|
|
@@ -99,8 +231,30 @@ const svelte_extract_prop_from_member = (member, source_file, checker) => {
|
|
|
99
231
|
const prop_type = checker.getTypeAtLocation(member);
|
|
100
232
|
type_string = checker.typeToString(prop_type);
|
|
101
233
|
}
|
|
102
|
-
catch {
|
|
103
|
-
// Fallback to 'any'
|
|
234
|
+
catch (err) {
|
|
235
|
+
// Fallback to 'any' but report diagnostic with mapped position
|
|
236
|
+
const { line, character } = source_file.getLineAndCharacterOfPosition(member.getStart());
|
|
237
|
+
// Map virtual position back to original .svelte file if source map available
|
|
238
|
+
let final_line = line + 1;
|
|
239
|
+
let final_column = character + 1;
|
|
240
|
+
if (source_map) {
|
|
241
|
+
const original = originalPositionFor(source_map, { line: line + 1, column: character });
|
|
242
|
+
// When line is found, column is guaranteed to be present (same mapping entry)
|
|
243
|
+
if (original.line !== null) {
|
|
244
|
+
final_line = original.line;
|
|
245
|
+
final_column = original.column + 1;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
ctx.add({
|
|
249
|
+
kind: 'svelte_prop_failed',
|
|
250
|
+
file: file_path,
|
|
251
|
+
line: final_line,
|
|
252
|
+
column: final_column,
|
|
253
|
+
message: `Failed to resolve type for prop "${prop_name}" in ${component_name}, falling back to 'any': ${err instanceof Error ? err.message : String(err)}`,
|
|
254
|
+
severity: 'warning',
|
|
255
|
+
component_name,
|
|
256
|
+
prop_name,
|
|
257
|
+
});
|
|
104
258
|
}
|
|
105
259
|
}
|
|
106
260
|
// Extract TSDoc description
|
|
@@ -154,12 +308,12 @@ const svelte_extract_bindable_props = (virtual_source) => {
|
|
|
154
308
|
*
|
|
155
309
|
* @mutates props - adds extracted prop info to the array
|
|
156
310
|
*/
|
|
157
|
-
const svelte_extract_props_from_type = (type_node, virtual_source, checker, bindable_props, props) => {
|
|
311
|
+
const svelte_extract_props_from_type = (type_node, virtual_source, checker, bindable_props, props, component_name, file_path, source_map, ctx) => {
|
|
158
312
|
if (ts.isTypeLiteralNode(type_node)) {
|
|
159
313
|
// Handle direct type literal: { prop1: type1, prop2: type2 }
|
|
160
314
|
for (const member of type_node.members) {
|
|
161
315
|
if (ts.isPropertySignature(member)) {
|
|
162
|
-
const prop_info = svelte_extract_prop_from_member(member, virtual_source, checker);
|
|
316
|
+
const prop_info = svelte_extract_prop_from_member(member, virtual_source, checker, component_name, file_path, source_map, ctx);
|
|
163
317
|
if (prop_info) {
|
|
164
318
|
// Mark as bindable if found in bindings
|
|
165
319
|
if (bindable_props.has(prop_info.name)) {
|
|
@@ -173,7 +327,7 @@ const svelte_extract_props_from_type = (type_node, virtual_source, checker, bind
|
|
|
173
327
|
else if (ts.isIntersectionTypeNode(type_node)) {
|
|
174
328
|
// Handle intersection type: TypeA & TypeB & { prop: type }
|
|
175
329
|
for (const type_part of type_node.types) {
|
|
176
|
-
svelte_extract_props_from_type(type_part, virtual_source, checker, bindable_props, props);
|
|
330
|
+
svelte_extract_props_from_type(type_part, virtual_source, checker, bindable_props, props, component_name, file_path, source_map, ctx);
|
|
177
331
|
}
|
|
178
332
|
}
|
|
179
333
|
// Skip other type references like SvelteHTMLElements['details'] since we can't easily resolve them
|
|
@@ -184,20 +338,20 @@ const svelte_extract_props_from_type = (type_node, virtual_source, checker, bind
|
|
|
184
338
|
* svelte2tsx generates a `$$ComponentProps` type alias containing the component props.
|
|
185
339
|
* This function extracts prop metadata from that type.
|
|
186
340
|
*/
|
|
187
|
-
const svelte_extract_props = (virtual_source, checker) => {
|
|
341
|
+
const svelte_extract_props = (virtual_source, checker, component_name, file_path, source_map, ctx) => {
|
|
188
342
|
const props = [];
|
|
189
343
|
const bindable_props = svelte_extract_bindable_props(virtual_source);
|
|
190
344
|
// Look for $$ComponentProps type alias or Props interface
|
|
191
345
|
ts.forEachChild(virtual_source, (node) => {
|
|
192
346
|
// Check for type alias ($$ComponentProps)
|
|
193
347
|
if (ts.isTypeAliasDeclaration(node) && node.name.text === '$$ComponentProps') {
|
|
194
|
-
svelte_extract_props_from_type(node.type, virtual_source, checker, bindable_props, props);
|
|
348
|
+
svelte_extract_props_from_type(node.type, virtual_source, checker, bindable_props, props, component_name, file_path, source_map, ctx);
|
|
195
349
|
}
|
|
196
350
|
// Also check for Props interface (fallback/older format)
|
|
197
351
|
else if (ts.isInterfaceDeclaration(node) && node.name.text === 'Props') {
|
|
198
352
|
for (const member of node.members) {
|
|
199
353
|
if (ts.isPropertySignature(member)) {
|
|
200
|
-
const prop_info = svelte_extract_prop_from_member(member, virtual_source, checker);
|
|
354
|
+
const prop_info = svelte_extract_prop_from_member(member, virtual_source, checker, component_name, file_path, source_map, ctx);
|
|
201
355
|
if (prop_info) {
|
|
202
356
|
// Mark as bindable if found in bindings
|
|
203
357
|
if (bindable_props.has(prop_info.name)) {
|
|
@@ -211,35 +365,3 @@ const svelte_extract_props = (virtual_source, checker) => {
|
|
|
211
365
|
});
|
|
212
366
|
return props;
|
|
213
367
|
};
|
|
214
|
-
/**
|
|
215
|
-
* Analyze a Svelte component file from disk.
|
|
216
|
-
*
|
|
217
|
-
* This is a high-level function that handles the complete workflow:
|
|
218
|
-
* 1. Read the Svelte source from disk
|
|
219
|
-
* 2. Transform to TypeScript via svelte2tsx
|
|
220
|
-
* 3. Extract component metadata (props, documentation)
|
|
221
|
-
*
|
|
222
|
-
* Suitable for use in documentation generators, build tools, and analysis.
|
|
223
|
-
*
|
|
224
|
-
* @param file_path Absolute path to the .svelte file
|
|
225
|
-
* @param module_path Module path relative to src/lib (e.g., 'Alert.svelte')
|
|
226
|
-
* @param checker TypeScript type checker for type resolution
|
|
227
|
-
* @returns Complete declaration metadata for the component
|
|
228
|
-
*/
|
|
229
|
-
export const svelte_analyze_file = (file_path, module_path, checker) => {
|
|
230
|
-
const svelte_source = readFileSync(file_path, 'utf-8');
|
|
231
|
-
// Check if component uses TypeScript
|
|
232
|
-
const is_ts_file = svelte_source.includes('lang="ts"');
|
|
233
|
-
// Transform Svelte to TS
|
|
234
|
-
const ts_result = svelte2tsx(svelte_source, {
|
|
235
|
-
filename: file_path,
|
|
236
|
-
isTsFile: is_ts_file,
|
|
237
|
-
emitOnTemplateError: true, // Handle malformed templates gracefully
|
|
238
|
-
});
|
|
239
|
-
// Get component name from filename
|
|
240
|
-
const component_name = module_get_component_name(module_path);
|
|
241
|
-
// Create a temporary source file from the original Svelte content for JSDoc extraction
|
|
242
|
-
const temp_source = ts.createSourceFile(file_path, svelte_source, ts.ScriptTarget.Latest, true);
|
|
243
|
-
// Analyze the component using the existing lower-level function
|
|
244
|
-
return svelte_analyze_component(ts_result.code, temp_source, checker, component_name);
|
|
245
|
-
};
|
package/dist/ts_helpers.d.ts
CHANGED
|
@@ -2,48 +2,94 @@
|
|
|
2
2
|
* TypeScript compiler API helpers for extracting metadata from source code.
|
|
3
3
|
*
|
|
4
4
|
* All functions are prefixed with `ts_` for clarity.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
5
7
|
*/
|
|
6
8
|
import ts from 'typescript';
|
|
7
9
|
import type { DeclarationJson, DeclarationKind } from '@fuzdev/fuz_util/source_json.js';
|
|
10
|
+
import type { Logger } from '@fuzdev/fuz_util/log.js';
|
|
8
11
|
import { tsdoc_parse } from './tsdoc_helpers.js';
|
|
12
|
+
import { type ModuleSourceOptions, type SourceFileInfo } from './module_helpers.js';
|
|
13
|
+
import type { AnalysisContext } from './analysis_context.js';
|
|
14
|
+
import type { DeclarationAnalysis, ReExportInfo, ModuleAnalysis } from './library_analysis.js';
|
|
9
15
|
/**
|
|
10
|
-
*
|
|
16
|
+
* Options for creating a TypeScript program.
|
|
11
17
|
*/
|
|
12
|
-
export
|
|
18
|
+
export interface TsProgramOptions {
|
|
19
|
+
/** Project root directory. @default './' */
|
|
20
|
+
root?: string;
|
|
21
|
+
/** Path to tsconfig.json (relative to root). @default 'tsconfig.json' */
|
|
22
|
+
tsconfig?: string;
|
|
23
|
+
/** Override compiler options. */
|
|
24
|
+
compiler_options?: ts.CompilerOptions;
|
|
25
|
+
}
|
|
13
26
|
/**
|
|
14
|
-
*
|
|
15
|
-
* with descriptions and default values.
|
|
16
|
-
*
|
|
17
|
-
* @mutates declaration - adds type_signature, return_type, return_description, throws, since, parameters, generic_params
|
|
27
|
+
* Result of creating a TypeScript program.
|
|
18
28
|
*/
|
|
19
|
-
export
|
|
29
|
+
export interface TsProgram {
|
|
30
|
+
program: ts.Program;
|
|
31
|
+
checker: ts.TypeChecker;
|
|
32
|
+
}
|
|
20
33
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @mutates declaration - adds type_signature, generic_params, extends, properties
|
|
34
|
+
* Result of analyzing a module's exports.
|
|
24
35
|
*/
|
|
25
|
-
export
|
|
36
|
+
export interface ModuleExportsAnalysis {
|
|
37
|
+
/** Module-level documentation comment. */
|
|
38
|
+
module_comment?: string;
|
|
39
|
+
/** All exported declarations with nodocs flags - consumer filters based on policy. */
|
|
40
|
+
declarations: Array<DeclarationAnalysis>;
|
|
41
|
+
/** Same-name re-exports (for building also_exported_from in post-processing). */
|
|
42
|
+
re_exports: Array<ReExportInfo>;
|
|
43
|
+
/** Star exports (`export * from './module'`) - module paths that are fully re-exported. */
|
|
44
|
+
star_exports: Array<string>;
|
|
45
|
+
}
|
|
26
46
|
/**
|
|
27
|
-
*
|
|
47
|
+
* Create TypeScript program for analysis.
|
|
28
48
|
*
|
|
29
|
-
* @
|
|
49
|
+
* @param options Configuration options for program creation
|
|
50
|
+
* @param log Optional logger for info messages
|
|
51
|
+
* @returns The program and type checker
|
|
52
|
+
* @throws Error if tsconfig.json is not found
|
|
30
53
|
*/
|
|
31
|
-
export declare const
|
|
54
|
+
export declare const ts_create_program: (options?: TsProgramOptions, log?: Logger) => TsProgram;
|
|
32
55
|
/**
|
|
33
|
-
*
|
|
56
|
+
* Analyze a TypeScript file and extract module metadata.
|
|
34
57
|
*
|
|
35
|
-
*
|
|
58
|
+
* Wraps `ts_analyze_module_exports` and adds dependency information
|
|
59
|
+
* from the source file info if available.
|
|
60
|
+
*
|
|
61
|
+
* This is a high-level function suitable for building documentation or library metadata.
|
|
62
|
+
* For lower-level analysis, use `ts_analyze_module_exports` directly.
|
|
63
|
+
*
|
|
64
|
+
* @param source_file_info The source file info (from Gro filer, file system, or other source)
|
|
65
|
+
* @param ts_source_file TypeScript source file from the program
|
|
66
|
+
* @param module_path The module path (relative to source root)
|
|
67
|
+
* @param checker TypeScript type checker
|
|
68
|
+
* @param options Module source options for path extraction
|
|
69
|
+
* @param ctx Analysis context for collecting diagnostics
|
|
70
|
+
* @returns Module metadata and re-export information
|
|
36
71
|
*/
|
|
37
|
-
export declare const
|
|
72
|
+
export declare const ts_analyze_module: (source_file_info: SourceFileInfo, ts_source_file: ts.SourceFile, module_path: string, checker: ts.TypeChecker, options: ModuleSourceOptions, ctx: AnalysisContext) => ModuleAnalysis;
|
|
38
73
|
/**
|
|
39
|
-
*
|
|
74
|
+
* Analyze all exports from a TypeScript source file.
|
|
75
|
+
*
|
|
76
|
+
* Extracts the module-level comment and all exported declarations with
|
|
77
|
+
* complete metadata. Handles re-exports by:
|
|
78
|
+
* - Same-name re-exports: tracked in `re_exports` for `also_exported_from` building
|
|
79
|
+
* - Renamed re-exports: included as new declarations with `alias_of` metadata
|
|
80
|
+
* - Star exports (`export * from`): tracked in `star_exports` for namespace-level info
|
|
81
|
+
*
|
|
82
|
+
* This is a mid-level function (above `ts_extract_*`, below `library_gen`)
|
|
83
|
+
* suitable for building documentation, API explorers, or analysis tools.
|
|
84
|
+
* For standard SvelteKit library layouts, use `module_create_source_options(process.cwd())`.
|
|
85
|
+
*
|
|
86
|
+
* @param source_file The TypeScript source file to analyze
|
|
87
|
+
* @param checker The TypeScript type checker
|
|
88
|
+
* @param options Module source options for path extraction in re-exports
|
|
89
|
+
* @param ctx Analysis context for collecting diagnostics
|
|
90
|
+
* @returns Module comment, declarations, re-exports, and star exports
|
|
40
91
|
*/
|
|
41
|
-
export
|
|
42
|
-
/** The analyzed declaration metadata. */
|
|
43
|
-
declaration: DeclarationJson;
|
|
44
|
-
/** Whether the declaration is marked @nodocs (should be excluded from documentation). */
|
|
45
|
-
nodocs: boolean;
|
|
46
|
-
}
|
|
92
|
+
export declare const ts_analyze_module_exports: (source_file: ts.SourceFile, checker: ts.TypeChecker, options: ModuleSourceOptions, ctx: AnalysisContext) => ModuleExportsAnalysis;
|
|
47
93
|
/**
|
|
48
94
|
* Analyze a TypeScript symbol and extract rich metadata.
|
|
49
95
|
*
|
|
@@ -54,57 +100,82 @@ export interface TsDeclarationAnalysis {
|
|
|
54
100
|
* @param symbol The TypeScript symbol to analyze
|
|
55
101
|
* @param source_file The source file containing the symbol
|
|
56
102
|
* @param checker The TypeScript type checker
|
|
103
|
+
* @param ctx Optional analysis context for collecting diagnostics
|
|
57
104
|
* @returns Complete declaration metadata including docs, types, and parameters, plus nodocs flag
|
|
58
105
|
*/
|
|
59
|
-
export declare const ts_analyze_declaration: (symbol: ts.Symbol, source_file: ts.SourceFile, checker: ts.TypeChecker) =>
|
|
106
|
+
export declare const ts_analyze_declaration: (symbol: ts.Symbol, source_file: ts.SourceFile, checker: ts.TypeChecker, ctx: AnalysisContext) => DeclarationAnalysis;
|
|
60
107
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
108
|
+
* Extract module-level comment.
|
|
109
|
+
*
|
|
110
|
+
* Requires `@module` tag to identify module comments. The tag line is stripped
|
|
111
|
+
* from the output. Supports optional module renaming: `@module custom-name`.
|
|
112
|
+
*
|
|
113
|
+
* @see https://typedoc.org/documents/Tags._module.html
|
|
63
114
|
*/
|
|
64
|
-
export
|
|
65
|
-
/** Name of the re-exported declaration. */
|
|
66
|
-
name: string;
|
|
67
|
-
/** Module path (relative to src/lib) where the declaration is originally declared. */
|
|
68
|
-
original_module: string;
|
|
69
|
-
}
|
|
115
|
+
export declare const ts_extract_module_comment: (source_file: ts.SourceFile) => string | undefined;
|
|
70
116
|
/**
|
|
71
|
-
*
|
|
117
|
+
* Infer declaration kind from symbol and node.
|
|
118
|
+
*
|
|
119
|
+
* Maps TypeScript constructs to `DeclarationKind`:
|
|
120
|
+
* - Classes → `'class'`
|
|
121
|
+
* - Functions (declarations, expressions, arrows) → `'function'`
|
|
122
|
+
* - Interfaces, type aliases → `'type'`
|
|
123
|
+
* - Enums (regular and const) → `'type'`
|
|
124
|
+
* - Variables → `'variable'` (unless function-valued → `'function'`)
|
|
72
125
|
*/
|
|
73
|
-
export
|
|
74
|
-
/** Module-level documentation comment. */
|
|
75
|
-
module_comment?: string;
|
|
76
|
-
/** All exported declarations with their metadata (excludes same-name re-exports). */
|
|
77
|
-
declarations: Array<DeclarationJson>;
|
|
78
|
-
/** Same-name re-exports (for building also_exported_from in post-processing). */
|
|
79
|
-
re_exports: Array<ReExportInfo>;
|
|
80
|
-
}
|
|
126
|
+
export declare const ts_infer_declaration_kind: (symbol: ts.Symbol, node: ts.Node) => DeclarationKind;
|
|
81
127
|
/**
|
|
82
|
-
*
|
|
128
|
+
* Extract parameters from a TypeScript signature with TSDoc descriptions and default values.
|
|
83
129
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* - Same-name re-exports: tracked in `re_exports` for `also_exported_from` building
|
|
87
|
-
* - Renamed re-exports: included as new declarations with `alias_of` metadata
|
|
130
|
+
* Shared helper for extracting parameter information from both standalone functions
|
|
131
|
+
* and class methods/constructors.
|
|
88
132
|
*
|
|
89
|
-
*
|
|
133
|
+
* @param sig The TypeScript signature to extract parameters from
|
|
134
|
+
* @param checker TypeScript type checker for type resolution
|
|
135
|
+
* @param tsdoc_params Map of parameter names to TSDoc descriptions (from tsdoc.params)
|
|
136
|
+
* @returns Array of parameter info objects
|
|
137
|
+
*/
|
|
138
|
+
export declare const ts_extract_signature_parameters: (sig: ts.Signature, checker: ts.TypeChecker, tsdoc_params: Map<string, string> | undefined) => Array<{
|
|
139
|
+
name: string;
|
|
140
|
+
type: string;
|
|
141
|
+
optional?: boolean;
|
|
142
|
+
description?: string;
|
|
143
|
+
default_value?: string;
|
|
144
|
+
}>;
|
|
145
|
+
/**
|
|
146
|
+
* Extract function/method information including parameters
|
|
147
|
+
* with descriptions and default values.
|
|
90
148
|
*
|
|
91
|
-
* @
|
|
92
|
-
* @
|
|
93
|
-
* @returns Module comment, array of analyzed declarations, and re-export information
|
|
149
|
+
* @internal Use `ts_analyze_declaration` for high-level analysis.
|
|
150
|
+
* @mutates declaration - adds type_signature, return_type, return_description, throws, since, parameters, generic_params
|
|
94
151
|
*/
|
|
95
|
-
export declare const
|
|
152
|
+
export declare const ts_extract_function_info: (node: ts.Node, symbol: ts.Symbol, checker: ts.TypeChecker, declaration: DeclarationJson, tsdoc: ReturnType<typeof tsdoc_parse>, ctx: AnalysisContext) => void;
|
|
96
153
|
/**
|
|
97
|
-
* Extract
|
|
154
|
+
* Extract type/interface information with rich property metadata.
|
|
98
155
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* comments as module comments. Module comments can appear after imports.
|
|
156
|
+
* @internal Use `ts_analyze_declaration` for high-level analysis.
|
|
157
|
+
* @mutates declaration - adds type_signature, generic_params, extends, properties
|
|
102
158
|
*/
|
|
103
|
-
export declare const
|
|
159
|
+
export declare const ts_extract_type_info: (node: ts.Node, _symbol: ts.Symbol, checker: ts.TypeChecker, declaration: DeclarationJson, ctx: AnalysisContext) => void;
|
|
104
160
|
/**
|
|
105
|
-
*
|
|
161
|
+
* Extract class information with rich member metadata.
|
|
162
|
+
*
|
|
163
|
+
* @internal Use `ts_analyze_declaration` for high-level analysis.
|
|
164
|
+
* @mutates declaration - adds extends, implements, generic_params, members
|
|
165
|
+
*/
|
|
166
|
+
export declare const ts_extract_class_info: (node: ts.Node, _symbol: ts.Symbol, checker: ts.TypeChecker, declaration: DeclarationJson, ctx: AnalysisContext) => void;
|
|
167
|
+
/**
|
|
168
|
+
* Extract variable information.
|
|
169
|
+
*
|
|
170
|
+
* @internal Use `ts_analyze_declaration` for high-level analysis.
|
|
171
|
+
* @mutates declaration - adds type_signature
|
|
172
|
+
*/
|
|
173
|
+
export declare const ts_extract_variable_info: (node: ts.Node, symbol: ts.Symbol, checker: ts.TypeChecker, declaration: DeclarationJson, ctx: AnalysisContext) => void;
|
|
174
|
+
/**
|
|
175
|
+
* TypeScript modifier keywords extracted from declarations.
|
|
176
|
+
*
|
|
177
|
+
* These are the access modifiers and other keywords that can appear
|
|
178
|
+
* on class members, interface properties, etc.
|
|
106
179
|
*/
|
|
107
|
-
export
|
|
108
|
-
warn: (message: string) => void;
|
|
109
|
-
}) => ts.Program | null;
|
|
180
|
+
export type TsModifier = 'public' | 'private' | 'protected' | 'readonly' | 'static' | 'abstract';
|
|
110
181
|
//# sourceMappingURL=ts_helpers.d.ts.map
|