@fuzdev/fuz_ui 0.176.1 → 0.177.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/dist/LibraryDetail.svelte +1 -1
- package/dist/declaration.svelte.js +1 -1
- package/dist/library_gen.d.ts +19 -40
- package/dist/library_gen.d.ts.map +1 -1
- package/dist/library_gen.js +30 -128
- package/dist/library_generate.d.ts +94 -0
- package/dist/library_generate.d.ts.map +1 -0
- package/dist/library_generate.js +147 -0
- package/dist/library_helpers.d.ts +35 -33
- package/dist/library_helpers.d.ts.map +1 -1
- package/dist/library_helpers.js +36 -65
- package/dist/{library_gen_output.d.ts → library_output.d.ts} +7 -6
- package/dist/library_output.d.ts.map +1 -0
- package/dist/{library_gen_output.js → library_output.js} +4 -3
- package/dist/{library_gen_helpers.d.ts → library_pipeline.d.ts} +7 -8
- package/dist/library_pipeline.d.ts.map +1 -0
- package/dist/{library_gen_helpers.js → library_pipeline.js} +6 -7
- package/dist/module.svelte.js +1 -1
- package/dist/package_helpers.d.ts +141 -0
- package/dist/package_helpers.d.ts.map +1 -0
- package/dist/package_helpers.js +172 -0
- package/package.json +1 -1
- package/src/lib/declaration.svelte.ts +1 -1
- package/src/lib/library_gen.ts +33 -163
- package/src/lib/library_generate.ts +215 -0
- package/src/lib/library_helpers.ts +37 -72
- package/src/lib/{library_gen_output.ts → library_output.ts} +7 -6
- package/src/lib/{library_gen_helpers.ts → library_pipeline.ts} +6 -7
- package/src/lib/module.svelte.ts +1 -1
- package/src/lib/package_helpers.ts +180 -0
- package/dist/library_gen_helpers.d.ts.map +0 -1
- package/dist/library_gen_output.d.ts.map +0 -1
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import ImgOrSvg from './ImgOrSvg.svelte';
|
|
8
8
|
import DeclarationLink from './DeclarationLink.svelte';
|
|
9
9
|
import ModuleLink from './ModuleLink.svelte';
|
|
10
|
-
import {url_github_file, repo_url_parse, url_well_known} from './
|
|
10
|
+
import {url_github_file, repo_url_parse, url_well_known} from './package_helpers.js';
|
|
11
11
|
import {
|
|
12
12
|
module_is_typescript,
|
|
13
13
|
module_is_svelte,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { declaration_generate_import, declaration_get_display_name, } from '@fuzdev/fuz_util/source_json.js';
|
|
2
|
-
import { url_github_file } from './
|
|
2
|
+
import { url_github_file } from './package_helpers.js';
|
|
3
3
|
/**
|
|
4
4
|
* Rich runtime representation of an exported declaration.
|
|
5
5
|
*/
|
package/dist/library_gen.d.ts
CHANGED
|
@@ -1,33 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Gro-specific library metadata generation.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
* - Source code locations
|
|
8
|
-
* - Parameter information with descriptions and defaults
|
|
9
|
-
* - Return value documentation
|
|
10
|
-
* - Usage examples
|
|
11
|
-
* - Dependency graphs
|
|
12
|
-
* - Svelte component props
|
|
4
|
+
* This module provides Gro integration for library generation. It wraps the generic
|
|
5
|
+
* `library_generate` function with Gro's `Gen` interface and provides adapters for
|
|
6
|
+
* converting Gro's `Disknode` to the build-tool agnostic `SourceFileInfo`.
|
|
13
7
|
*
|
|
14
|
-
*
|
|
15
|
-
* build-tool agnostic helpers that work with `SourceFileInfo`.
|
|
8
|
+
* For build-tool agnostic usage, see `library_generate.ts`.
|
|
16
9
|
*
|
|
17
|
-
* @see
|
|
18
|
-
* @see
|
|
19
|
-
* @see
|
|
20
|
-
* @see `tsdoc_helpers.ts` for JSDoc/TSDoc parsing
|
|
21
|
-
* @see `ts_helpers.ts` for TypeScript analysis
|
|
22
|
-
* @see `svelte_helpers.ts` for Svelte component analysis
|
|
10
|
+
* @see library_generate.ts for the generic generation entry point
|
|
11
|
+
* @see library_pipeline.ts for pipeline helpers
|
|
12
|
+
* @see library_output.ts for output file generation
|
|
23
13
|
*
|
|
24
14
|
* @module
|
|
25
15
|
*/
|
|
26
16
|
import type { Gen } from '@ryanatkn/gro';
|
|
27
17
|
import type { Disknode } from '@ryanatkn/gro/disknode.js';
|
|
28
18
|
import { type SourceFileInfo, type ModuleSourceOptions, type ModuleSourcePartial } from './module_helpers.js';
|
|
29
|
-
import { type
|
|
30
|
-
/** Options for library generation. */
|
|
19
|
+
import { type OnDuplicatesCallback } from './library_generate.js';
|
|
20
|
+
/** Options for Gro library generation. */
|
|
31
21
|
export interface LibraryGenOptions {
|
|
32
22
|
/**
|
|
33
23
|
* Module source options for filtering and path extraction.
|
|
@@ -41,11 +31,11 @@ export interface LibraryGenOptions {
|
|
|
41
31
|
* Callback invoked when duplicate declaration names are found.
|
|
42
32
|
*
|
|
43
33
|
* Consumers decide how to handle duplicates: throw, warn, or ignore.
|
|
44
|
-
* Use `
|
|
34
|
+
* Use `library_throw_on_duplicates` for strict flat namespace enforcement.
|
|
45
35
|
*
|
|
46
36
|
* @example
|
|
47
37
|
* // Throw on duplicates (strict flat namespace)
|
|
48
|
-
* library_gen({ on_duplicates:
|
|
38
|
+
* library_gen({ on_duplicates: library_throw_on_duplicates });
|
|
49
39
|
*
|
|
50
40
|
* // Warn but continue
|
|
51
41
|
* library_gen({
|
|
@@ -58,24 +48,6 @@ export interface LibraryGenOptions {
|
|
|
58
48
|
*/
|
|
59
49
|
on_duplicates?: OnDuplicatesCallback;
|
|
60
50
|
}
|
|
61
|
-
/**
|
|
62
|
-
* Callback for handling duplicate declaration names.
|
|
63
|
-
*
|
|
64
|
-
* @param duplicates Map of declaration names to their occurrences across modules
|
|
65
|
-
* @param log Logger for reporting
|
|
66
|
-
*/
|
|
67
|
-
export type OnDuplicatesCallback = (duplicates: Map<string, Array<DuplicateInfo>>, log: {
|
|
68
|
-
error: (...args: Array<unknown>) => void;
|
|
69
|
-
}) => void;
|
|
70
|
-
/**
|
|
71
|
-
* Strict duplicate handler that throws on any duplicate declaration names.
|
|
72
|
-
*
|
|
73
|
-
* Use this callback with `library_gen({ on_duplicates: library_gen_throw_on_duplicates })`
|
|
74
|
-
* to enforce a flat namespace where all declaration names must be unique.
|
|
75
|
-
*
|
|
76
|
-
* @throws Error if any duplicate declaration names are found
|
|
77
|
-
*/
|
|
78
|
-
export declare const library_gen_throw_on_duplicates: OnDuplicatesCallback;
|
|
79
51
|
/**
|
|
80
52
|
* Convert Gro's Disknode to the build-tool agnostic SourceFileInfo interface.
|
|
81
53
|
*
|
|
@@ -102,6 +74,13 @@ export declare const library_collect_source_files_from_disknodes: (disknodes: It
|
|
|
102
74
|
/**
|
|
103
75
|
* Creates a Gen object for generating library metadata with full TypeScript analysis.
|
|
104
76
|
*
|
|
77
|
+
* This is the Gro-specific entry point. It handles:
|
|
78
|
+
* - Reading files from Gro's filer
|
|
79
|
+
* - Loading package.json via Gro utilities
|
|
80
|
+
* - Returning output in Gro's Gen format
|
|
81
|
+
*
|
|
82
|
+
* For build-tool agnostic usage, use `library_generate` directly.
|
|
83
|
+
*
|
|
105
84
|
* Usage in a `.gen.ts` file:
|
|
106
85
|
*
|
|
107
86
|
* ```ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"library_gen.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/library_gen.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"library_gen.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/library_gen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,eAAe,CAAC;AAEvC,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,2BAA2B,CAAC;AAExD,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EAKxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAmB,KAAK,oBAAoB,EAAC,MAAM,uBAAuB,CAAC;AAElF,0CAA0C;AAC1C,MAAM,WAAW,iBAAiB;IACjC;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC5D;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACrC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,GAAI,UAAU,QAAQ,KAAG,cAY9D,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,2CAA2C,GACvD,WAAW,QAAQ,CAAC,QAAQ,CAAC,EAC7B,SAAS,mBAAmB,EAC5B,MAAM;IAAC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;CAAC,KACtF,KAAK,CAAC,cAAc,CA6BtB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW,GAAI,UAAU,iBAAiB,KAAG,GA0CzD,CAAC"}
|
package/dist/library_gen.js
CHANGED
|
@@ -1,60 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Gro-specific library metadata generation.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
* - Source code locations
|
|
8
|
-
* - Parameter information with descriptions and defaults
|
|
9
|
-
* - Return value documentation
|
|
10
|
-
* - Usage examples
|
|
11
|
-
* - Dependency graphs
|
|
12
|
-
* - Svelte component props
|
|
4
|
+
* This module provides Gro integration for library generation. It wraps the generic
|
|
5
|
+
* `library_generate` function with Gro's `Gen` interface and provides adapters for
|
|
6
|
+
* converting Gro's `Disknode` to the build-tool agnostic `SourceFileInfo`.
|
|
13
7
|
*
|
|
14
|
-
*
|
|
15
|
-
* build-tool agnostic helpers that work with `SourceFileInfo`.
|
|
8
|
+
* For build-tool agnostic usage, see `library_generate.ts`.
|
|
16
9
|
*
|
|
17
|
-
* @see
|
|
18
|
-
* @see
|
|
19
|
-
* @see
|
|
20
|
-
* @see `tsdoc_helpers.ts` for JSDoc/TSDoc parsing
|
|
21
|
-
* @see `ts_helpers.ts` for TypeScript analysis
|
|
22
|
-
* @see `svelte_helpers.ts` for Svelte component analysis
|
|
10
|
+
* @see library_generate.ts for the generic generation entry point
|
|
11
|
+
* @see library_pipeline.ts for pipeline helpers
|
|
12
|
+
* @see library_output.ts for output file generation
|
|
23
13
|
*
|
|
24
14
|
* @module
|
|
25
15
|
*/
|
|
26
16
|
import { package_json_load } from '@ryanatkn/gro/package_json.js';
|
|
27
|
-
import { ts_create_program } from './ts_helpers.js';
|
|
28
17
|
import { module_create_source_options, module_validate_source_options, module_is_source, module_get_source_root, } from './module_helpers.js';
|
|
29
|
-
import {
|
|
30
|
-
import { library_sort_modules, library_find_duplicates, library_merge_re_exports, } from './library_gen_helpers.js';
|
|
31
|
-
import { library_generate_json } from './library_gen_output.js';
|
|
32
|
-
import { AnalysisContext, format_diagnostic } from './analysis_context.js';
|
|
33
|
-
/**
|
|
34
|
-
* Strict duplicate handler that throws on any duplicate declaration names.
|
|
35
|
-
*
|
|
36
|
-
* Use this callback with `library_gen({ on_duplicates: library_gen_throw_on_duplicates })`
|
|
37
|
-
* to enforce a flat namespace where all declaration names must be unique.
|
|
38
|
-
*
|
|
39
|
-
* @throws Error if any duplicate declaration names are found
|
|
40
|
-
*/
|
|
41
|
-
export const library_gen_throw_on_duplicates = (duplicates, log) => {
|
|
42
|
-
if (duplicates.size === 0)
|
|
43
|
-
return;
|
|
44
|
-
log.error('Duplicate declaration names detected in flat namespace:');
|
|
45
|
-
for (const [name, occurrences] of duplicates) {
|
|
46
|
-
log.error(` "${name}" found in:`);
|
|
47
|
-
for (const { declaration, module } of occurrences) {
|
|
48
|
-
const line_info = declaration.source_line !== undefined ? `:${declaration.source_line}` : '';
|
|
49
|
-
log.error(` - ${module}${line_info} (${declaration.kind})`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
throw new Error(`Found ${duplicates.size} duplicate declaration name${duplicates.size === 1 ? '' : 's'} across modules. ` +
|
|
53
|
-
'The flat namespace requires unique names. To resolve: ' +
|
|
54
|
-
'(1) rename one of the conflicting declarations, or ' +
|
|
55
|
-
'(2) add /** @nodocs */ to exclude from documentation. ' +
|
|
56
|
-
'See CLAUDE.md "Declaration namespacing" section for details.');
|
|
57
|
-
};
|
|
18
|
+
import { library_generate } from './library_generate.js';
|
|
58
19
|
/**
|
|
59
20
|
* Convert Gro's Disknode to the build-tool agnostic SourceFileInfo interface.
|
|
60
21
|
*
|
|
@@ -73,7 +34,6 @@ export const source_file_from_disknode = (disknode) => {
|
|
|
73
34
|
dependents: [...disknode.dependents.keys()],
|
|
74
35
|
};
|
|
75
36
|
};
|
|
76
|
-
// TODO more generic helpers
|
|
77
37
|
/**
|
|
78
38
|
* Collect source files from Gro disknodes, filtering BEFORE conversion to SourceFileInfo.
|
|
79
39
|
*
|
|
@@ -112,6 +72,13 @@ export const library_collect_source_files_from_disknodes = (disknodes, options,
|
|
|
112
72
|
/**
|
|
113
73
|
* Creates a Gen object for generating library metadata with full TypeScript analysis.
|
|
114
74
|
*
|
|
75
|
+
* This is the Gro-specific entry point. It handles:
|
|
76
|
+
* - Reading files from Gro's filer
|
|
77
|
+
* - Loading package.json via Gro utilities
|
|
78
|
+
* - Returning output in Gro's Gen format
|
|
79
|
+
*
|
|
80
|
+
* For build-tool agnostic usage, use `library_generate` directly.
|
|
81
|
+
*
|
|
115
82
|
* Usage in a `.gen.ts` file:
|
|
116
83
|
*
|
|
117
84
|
* ```ts
|
|
@@ -130,91 +97,26 @@ export const library_gen = (options) => {
|
|
|
130
97
|
const source_options = options?.source && 'project_root' in options.source
|
|
131
98
|
? options.source
|
|
132
99
|
: module_create_source_options(process.cwd(), options?.source);
|
|
133
|
-
// Validate options early to fail fast on misconfiguration
|
|
134
|
-
// (before expensive operations like program creation)
|
|
135
|
-
module_validate_source_options(source_options);
|
|
136
100
|
// Ensure filer is initialized
|
|
137
101
|
await filer.init();
|
|
138
102
|
// Read package.json
|
|
139
103
|
const package_json = await package_json_load();
|
|
140
|
-
//
|
|
141
|
-
const { program } = ts_create_program(undefined, log);
|
|
142
|
-
// Create analysis context for collecting diagnostics
|
|
143
|
-
const ctx = new AnalysisContext();
|
|
144
|
-
// Collect source files, filtering by source_options BEFORE converting to SourceFileInfo
|
|
145
|
-
// This avoids errors from files outside source directories (like test fixtures)
|
|
104
|
+
// Collect source files from Gro filer
|
|
146
105
|
const source_files = library_collect_source_files_from_disknodes(filer.files.values(), source_options, log);
|
|
147
|
-
//
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
};
|
|
156
|
-
// Collect re-exports for phase 2 merging
|
|
157
|
-
// See library_merge_re_exports for the two-phase resolution strategy
|
|
158
|
-
const collected_re_exports = [];
|
|
159
|
-
for (const source_file of source_files) {
|
|
160
|
-
// Use unified analyzer that dispatches based on file type
|
|
161
|
-
const result = library_analyze_module(source_file, program, source_options, ctx, log);
|
|
162
|
-
if (!result)
|
|
163
|
-
continue;
|
|
164
|
-
// Build ModuleJson, filtering out @nodocs declarations
|
|
165
|
-
const module = {
|
|
166
|
-
path: result.path,
|
|
167
|
-
declarations: result.declarations.filter((d) => !d.nodocs).map((d) => d.declaration),
|
|
168
|
-
};
|
|
169
|
-
if (result.module_comment)
|
|
170
|
-
module.module_comment = result.module_comment;
|
|
171
|
-
if (result.dependencies.length > 0)
|
|
172
|
-
module.dependencies = result.dependencies;
|
|
173
|
-
if (result.dependents.length > 0)
|
|
174
|
-
module.dependents = result.dependents;
|
|
175
|
-
if (result.star_exports.length > 0)
|
|
176
|
-
module.star_exports = result.star_exports;
|
|
177
|
-
modules.push(module);
|
|
178
|
-
// Collect re-exports for phase 2 merging
|
|
179
|
-
for (const re_export of result.re_exports) {
|
|
180
|
-
collected_re_exports.push({ re_exporting_module: result.path, re_export });
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
// Phase 2: Build also_exported_from arrays from re-export data
|
|
184
|
-
library_merge_re_exports(source_json, collected_re_exports);
|
|
185
|
-
// Sort modules alphabetically for deterministic output and cleaner diffs
|
|
186
|
-
source_json.modules = library_sort_modules(modules);
|
|
187
|
-
// Check for duplicate declaration names and invoke callback if provided
|
|
188
|
-
if (options?.on_duplicates) {
|
|
189
|
-
const duplicates = library_find_duplicates(source_json);
|
|
190
|
-
if (duplicates.size > 0) {
|
|
191
|
-
options.on_duplicates(duplicates, log);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
// Report any analysis diagnostics
|
|
195
|
-
if (ctx.diagnostics.length > 0) {
|
|
196
|
-
const errors = ctx.errors();
|
|
197
|
-
const warnings = ctx.warnings();
|
|
198
|
-
const format_options = { strip_base: process.cwd() };
|
|
199
|
-
if (errors.length > 0) {
|
|
200
|
-
log.error(`Analysis completed with ${errors.length} error(s):`);
|
|
201
|
-
for (const diagnostic of errors) {
|
|
202
|
-
log.error(` ${format_diagnostic(diagnostic, format_options)}`);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
if (warnings.length > 0) {
|
|
206
|
-
log.warn(`Analysis completed with ${warnings.length} warning(s):`);
|
|
207
|
-
for (const diagnostic of warnings) {
|
|
208
|
-
log.warn(` ${format_diagnostic(diagnostic, format_options)}`);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
106
|
+
// Use generic library_generate for the actual work
|
|
107
|
+
const result = library_generate({
|
|
108
|
+
source_files,
|
|
109
|
+
package_json,
|
|
110
|
+
source_options,
|
|
111
|
+
on_duplicates: options?.on_duplicates,
|
|
112
|
+
log,
|
|
113
|
+
});
|
|
212
114
|
log.info('library metadata generation complete');
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
115
|
+
// Return array of files in Gro's expected format
|
|
116
|
+
return [
|
|
117
|
+
{ content: result.ts_content },
|
|
118
|
+
{ content: result.json_content, filename: 'library.json' },
|
|
119
|
+
];
|
|
218
120
|
},
|
|
219
121
|
};
|
|
220
122
|
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic library metadata generation.
|
|
3
|
+
*
|
|
4
|
+
* This module provides build-tool agnostic library generation. It takes source files
|
|
5
|
+
* and package metadata, analyzes them, and produces structured metadata with:
|
|
6
|
+
* - JSDoc/TSDoc comments with full tag support
|
|
7
|
+
* - Full type signatures
|
|
8
|
+
* - Source code locations
|
|
9
|
+
* - Parameter information with descriptions and defaults
|
|
10
|
+
* - Return value documentation
|
|
11
|
+
* - Usage examples
|
|
12
|
+
* - Dependency graphs
|
|
13
|
+
* - Svelte component props
|
|
14
|
+
*
|
|
15
|
+
* For Gro integration, see `library_gen.ts` which wraps this with Gro's Gen interface.
|
|
16
|
+
*
|
|
17
|
+
* @see @fuzdev/fuz_util/source_json.js for type definitions
|
|
18
|
+
* @see `library_analysis.ts` for the unified analysis entry point
|
|
19
|
+
* @see `library_pipeline.ts` for pipeline helpers
|
|
20
|
+
* @see `library_output.ts` for JSON/TS file generation
|
|
21
|
+
*
|
|
22
|
+
* @module
|
|
23
|
+
*/
|
|
24
|
+
import type ts from 'typescript';
|
|
25
|
+
import type { SourceJson } from '@fuzdev/fuz_util/source_json.js';
|
|
26
|
+
import type { PackageJson } from '@fuzdev/fuz_util/package_json.js';
|
|
27
|
+
import type { Logger } from '@fuzdev/fuz_util/log.js';
|
|
28
|
+
import { type SourceFileInfo, type ModuleSourceOptions } from './module_helpers.js';
|
|
29
|
+
import { type DuplicateInfo } from './library_pipeline.js';
|
|
30
|
+
/**
|
|
31
|
+
* Callback for handling duplicate declaration names.
|
|
32
|
+
*
|
|
33
|
+
* @param duplicates Map of declaration names to their occurrences across modules
|
|
34
|
+
* @param log Logger for reporting
|
|
35
|
+
*/
|
|
36
|
+
export type OnDuplicatesCallback = (duplicates: Map<string, Array<DuplicateInfo>>, log: {
|
|
37
|
+
error: (...args: Array<unknown>) => void;
|
|
38
|
+
}) => void;
|
|
39
|
+
/**
|
|
40
|
+
* Strict duplicate handler that throws on any duplicate declaration names.
|
|
41
|
+
*
|
|
42
|
+
* Use this callback with `library_generate({ on_duplicates: library_throw_on_duplicates })`
|
|
43
|
+
* to enforce a flat namespace where all declaration names must be unique.
|
|
44
|
+
*
|
|
45
|
+
* @throws Error if any duplicate declaration names are found
|
|
46
|
+
*/
|
|
47
|
+
export declare const library_throw_on_duplicates: OnDuplicatesCallback;
|
|
48
|
+
/** Input for library metadata generation. */
|
|
49
|
+
export interface LibraryGenerateInput {
|
|
50
|
+
/** Source files to analyze (must have content loaded). */
|
|
51
|
+
source_files: Array<SourceFileInfo>;
|
|
52
|
+
/** Package metadata (name, version). */
|
|
53
|
+
package_json: PackageJson;
|
|
54
|
+
/** Module source options for path extraction. */
|
|
55
|
+
source_options: ModuleSourceOptions;
|
|
56
|
+
/**
|
|
57
|
+
* Optional TypeScript program. If not provided, one will be created.
|
|
58
|
+
* Pass an existing program to reuse across multiple calls.
|
|
59
|
+
*/
|
|
60
|
+
program?: ts.Program;
|
|
61
|
+
/** Optional callback for handling duplicate declaration names. */
|
|
62
|
+
on_duplicates?: OnDuplicatesCallback;
|
|
63
|
+
/** Optional logger for status and diagnostic messages. */
|
|
64
|
+
log?: Logger;
|
|
65
|
+
}
|
|
66
|
+
/** Result of library metadata generation. */
|
|
67
|
+
export interface LibraryGenerateResult {
|
|
68
|
+
/** The generated source metadata. */
|
|
69
|
+
source_json: SourceJson;
|
|
70
|
+
/** JSON file content string. */
|
|
71
|
+
json_content: string;
|
|
72
|
+
/** TypeScript wrapper file content string. */
|
|
73
|
+
ts_content: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Generate library metadata from source files.
|
|
77
|
+
*
|
|
78
|
+
* This is the main entry point for library generation. It analyzes source files,
|
|
79
|
+
* extracts metadata, and produces both structured data and file contents.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* const result = library_generate({
|
|
84
|
+
* source_files,
|
|
85
|
+
* package_json: {name: '@my/lib', version: '1.0.0'},
|
|
86
|
+
* source_options: module_create_source_options(process.cwd()),
|
|
87
|
+
* });
|
|
88
|
+
*
|
|
89
|
+
* await writeFile('library.json', result.json_content);
|
|
90
|
+
* await writeFile('library.ts', result.ts_content);
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare const library_generate: (input: LibraryGenerateInput) => LibraryGenerateResult;
|
|
94
|
+
//# sourceMappingURL=library_generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library_generate.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/library_generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,KAAK,EAAC,UAAU,EAAa,MAAM,iCAAiC,CAAC;AAC5E,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAGpD,OAAO,EAAC,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAC,MAAM,qBAAqB,CAAC;AAElF,OAAO,EAKN,KAAK,aAAa,EAClB,MAAM,uBAAuB,CAAC;AAI/B;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAClC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,EAC7C,GAAG,EAAE;IAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;CAAC,KAC3C,IAAI,CAAC;AAEV;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,EAAE,oBAiBzC,CAAC;AAEF,6CAA6C;AAC7C,MAAM,WAAW,oBAAoB;IACpC,0DAA0D;IAC1D,YAAY,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IACpC,wCAAwC;IACxC,YAAY,EAAE,WAAW,CAAC;IAC1B,iDAAiD;IACjD,cAAc,EAAE,mBAAmB,CAAC;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC;IACrB,kEAAkE;IAClE,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,6CAA6C;AAC7C,MAAM,WAAW,qBAAqB;IACrC,qCAAqC;IACrC,WAAW,EAAE,UAAU,CAAC;IACxB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,oBAAoB,KAAG,qBAuF9D,CAAC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic library metadata generation.
|
|
3
|
+
*
|
|
4
|
+
* This module provides build-tool agnostic library generation. It takes source files
|
|
5
|
+
* and package metadata, analyzes them, and produces structured metadata with:
|
|
6
|
+
* - JSDoc/TSDoc comments with full tag support
|
|
7
|
+
* - Full type signatures
|
|
8
|
+
* - Source code locations
|
|
9
|
+
* - Parameter information with descriptions and defaults
|
|
10
|
+
* - Return value documentation
|
|
11
|
+
* - Usage examples
|
|
12
|
+
* - Dependency graphs
|
|
13
|
+
* - Svelte component props
|
|
14
|
+
*
|
|
15
|
+
* For Gro integration, see `library_gen.ts` which wraps this with Gro's Gen interface.
|
|
16
|
+
*
|
|
17
|
+
* @see @fuzdev/fuz_util/source_json.js for type definitions
|
|
18
|
+
* @see `library_analysis.ts` for the unified analysis entry point
|
|
19
|
+
* @see `library_pipeline.ts` for pipeline helpers
|
|
20
|
+
* @see `library_output.ts` for JSON/TS file generation
|
|
21
|
+
*
|
|
22
|
+
* @module
|
|
23
|
+
*/
|
|
24
|
+
import { ts_create_program } from './ts_helpers.js';
|
|
25
|
+
import {} from './module_helpers.js';
|
|
26
|
+
import { library_analyze_module } from './library_analysis.js';
|
|
27
|
+
import { library_sort_modules, library_find_duplicates, library_merge_re_exports, } from './library_pipeline.js';
|
|
28
|
+
import { library_generate_output } from './library_output.js';
|
|
29
|
+
import { AnalysisContext, format_diagnostic } from './analysis_context.js';
|
|
30
|
+
/**
|
|
31
|
+
* Strict duplicate handler that throws on any duplicate declaration names.
|
|
32
|
+
*
|
|
33
|
+
* Use this callback with `library_generate({ on_duplicates: library_throw_on_duplicates })`
|
|
34
|
+
* to enforce a flat namespace where all declaration names must be unique.
|
|
35
|
+
*
|
|
36
|
+
* @throws Error if any duplicate declaration names are found
|
|
37
|
+
*/
|
|
38
|
+
export const library_throw_on_duplicates = (duplicates, log) => {
|
|
39
|
+
if (duplicates.size === 0)
|
|
40
|
+
return;
|
|
41
|
+
log.error('Duplicate declaration names detected in flat namespace:');
|
|
42
|
+
for (const [name, occurrences] of duplicates) {
|
|
43
|
+
log.error(` "${name}" found in:`);
|
|
44
|
+
for (const { declaration, module } of occurrences) {
|
|
45
|
+
const line_info = declaration.source_line !== undefined ? `:${declaration.source_line}` : '';
|
|
46
|
+
log.error(` - ${module}${line_info} (${declaration.kind})`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`Found ${duplicates.size} duplicate declaration name${duplicates.size === 1 ? '' : 's'} across modules. ` +
|
|
50
|
+
'The flat namespace requires unique names. To resolve: ' +
|
|
51
|
+
'(1) rename one of the conflicting declarations, or ' +
|
|
52
|
+
'(2) add /** @nodocs */ to exclude from documentation.');
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Generate library metadata from source files.
|
|
56
|
+
*
|
|
57
|
+
* This is the main entry point for library generation. It analyzes source files,
|
|
58
|
+
* extracts metadata, and produces both structured data and file contents.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* const result = library_generate({
|
|
63
|
+
* source_files,
|
|
64
|
+
* package_json: {name: '@my/lib', version: '1.0.0'},
|
|
65
|
+
* source_options: module_create_source_options(process.cwd()),
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* await writeFile('library.json', result.json_content);
|
|
69
|
+
* await writeFile('library.ts', result.ts_content);
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export const library_generate = (input) => {
|
|
73
|
+
const { source_files, package_json, source_options, on_duplicates, log } = input;
|
|
74
|
+
// Create or use provided TypeScript program
|
|
75
|
+
const program = input.program ?? ts_create_program(undefined, log).program;
|
|
76
|
+
// Create analysis context for collecting diagnostics
|
|
77
|
+
const ctx = new AnalysisContext();
|
|
78
|
+
// Collect modules
|
|
79
|
+
const modules = [];
|
|
80
|
+
// Build source_json with array-based modules
|
|
81
|
+
// Phase 1: Analyze all modules and collect re-exports
|
|
82
|
+
const source_json = {
|
|
83
|
+
name: package_json.name,
|
|
84
|
+
version: package_json.version,
|
|
85
|
+
modules,
|
|
86
|
+
};
|
|
87
|
+
// Collect re-exports for phase 2 merging
|
|
88
|
+
// See library_merge_re_exports for the two-phase resolution strategy
|
|
89
|
+
const collected_re_exports = [];
|
|
90
|
+
for (const source_file of source_files) {
|
|
91
|
+
// Use unified analyzer that dispatches based on file type
|
|
92
|
+
const result = library_analyze_module(source_file, program, source_options, ctx, log);
|
|
93
|
+
if (!result)
|
|
94
|
+
continue;
|
|
95
|
+
// Build ModuleJson, filtering out @nodocs declarations
|
|
96
|
+
const module = {
|
|
97
|
+
path: result.path,
|
|
98
|
+
declarations: result.declarations.filter((d) => !d.nodocs).map((d) => d.declaration),
|
|
99
|
+
};
|
|
100
|
+
if (result.module_comment)
|
|
101
|
+
module.module_comment = result.module_comment;
|
|
102
|
+
if (result.dependencies.length > 0)
|
|
103
|
+
module.dependencies = result.dependencies;
|
|
104
|
+
if (result.dependents.length > 0)
|
|
105
|
+
module.dependents = result.dependents;
|
|
106
|
+
if (result.star_exports.length > 0)
|
|
107
|
+
module.star_exports = result.star_exports;
|
|
108
|
+
modules.push(module);
|
|
109
|
+
// Collect re-exports for phase 2 merging
|
|
110
|
+
for (const re_export of result.re_exports) {
|
|
111
|
+
collected_re_exports.push({ re_exporting_module: result.path, re_export });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Phase 2: Build also_exported_from arrays from re-export data
|
|
115
|
+
library_merge_re_exports(source_json, collected_re_exports);
|
|
116
|
+
// Sort modules alphabetically for deterministic output and cleaner diffs
|
|
117
|
+
source_json.modules = library_sort_modules(modules);
|
|
118
|
+
// Check for duplicate declaration names and invoke callback if provided
|
|
119
|
+
if (on_duplicates) {
|
|
120
|
+
const duplicates = library_find_duplicates(source_json);
|
|
121
|
+
if (duplicates.size > 0) {
|
|
122
|
+
// Use provided logger or a minimal fallback
|
|
123
|
+
const error_log = log ?? { error: (...args) => console.error(...args) }; // eslint-disable-line no-console
|
|
124
|
+
on_duplicates(duplicates, error_log);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Report any analysis diagnostics
|
|
128
|
+
if (ctx.diagnostics.length > 0 && log) {
|
|
129
|
+
const errors = ctx.errors();
|
|
130
|
+
const warnings = ctx.warnings();
|
|
131
|
+
const format_options = { strip_base: source_options.project_root };
|
|
132
|
+
if (errors.length > 0) {
|
|
133
|
+
log.error(`Analysis completed with ${errors.length} error(s):`);
|
|
134
|
+
for (const diagnostic of errors) {
|
|
135
|
+
log.error(` ${format_diagnostic(diagnostic, format_options)}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (warnings.length > 0) {
|
|
139
|
+
log.warn(`Analysis completed with ${warnings.length} warning(s):`);
|
|
140
|
+
for (const diagnostic of warnings) {
|
|
141
|
+
log.warn(` ${format_diagnostic(diagnostic, format_options)}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const { json_content, ts_content } = library_generate_output(package_json, source_json);
|
|
146
|
+
return { source_json, json_content, ts_content };
|
|
147
|
+
};
|
|
@@ -1,54 +1,56 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Library documentation URL helpers.
|
|
3
|
+
*
|
|
4
|
+
* Runtime UI helpers for building URLs in the library documentation system.
|
|
5
|
+
* These depend on fuz_ui's documentation paths and SvelteKit's runtime state.
|
|
6
|
+
*
|
|
7
|
+
* For generic package/repository URL helpers, see `package_helpers.ts`.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
2
11
|
/**
|
|
3
12
|
* Build project-relative API documentation URL with hash anchor.
|
|
13
|
+
*
|
|
14
|
+
* @param declaration_name Name of the declaration to link to
|
|
15
|
+
* @returns URL path like '/docs/api#declaration_name'
|
|
4
16
|
*/
|
|
5
17
|
export declare const url_api_declaration: (declaration_name: string) => string;
|
|
6
18
|
/**
|
|
7
19
|
* Build full API documentation URL with domain and hash anchor.
|
|
20
|
+
*
|
|
21
|
+
* @param homepage Package homepage URL
|
|
22
|
+
* @param declaration_name Name of the declaration to link to
|
|
23
|
+
* @returns Full URL like 'https://example.com/docs/api#declaration_name'
|
|
8
24
|
*/
|
|
9
25
|
export declare const url_api_declaration_full: (homepage: string, declaration_name: string) => string;
|
|
10
26
|
/**
|
|
11
27
|
* Build project-relative module documentation URL.
|
|
28
|
+
*
|
|
29
|
+
* @param module_path Module path (e.g., 'helpers.ts')
|
|
30
|
+
* @returns URL path like '/docs/api/helpers.ts'
|
|
12
31
|
*/
|
|
13
32
|
export declare const url_api_module: (module_path: string) => string;
|
|
14
|
-
/**
|
|
15
|
-
* Build GitHub file URL for a repository.
|
|
16
|
-
*/
|
|
17
|
-
export declare const url_github_file: (repo_url: string, file_path: string, line?: number) => string;
|
|
18
|
-
/**
|
|
19
|
-
* Build GitHub organization URL from repo URL and repo name.
|
|
20
|
-
*/
|
|
21
|
-
export declare const url_github_org: (repo_url: string, repo_name: string) => string | null;
|
|
22
|
-
/**
|
|
23
|
-
* Parse GitHub owner/org name from repository URL.
|
|
24
|
-
*/
|
|
25
|
-
export declare const github_owner_parse: (repo_url: string) => string | null;
|
|
26
|
-
/**
|
|
27
|
-
* Build npm package URL.
|
|
28
|
-
*/
|
|
29
|
-
export declare const url_npm_package: (package_name: string) => string;
|
|
30
|
-
/**
|
|
31
|
-
* Check if a package is published to npm.
|
|
32
|
-
*/
|
|
33
|
-
export declare const package_is_published: (package_json: PackageJson) => boolean;
|
|
34
33
|
/**
|
|
35
34
|
* Build package logo URL with favicon.png fallback.
|
|
35
|
+
*
|
|
36
|
+
* @param homepage_url Package homepage URL, or null
|
|
37
|
+
* @param logo_path Optional custom logo path (defaults to 'favicon.png')
|
|
38
|
+
* @returns Full URL to the logo, or null if no homepage
|
|
36
39
|
*/
|
|
37
40
|
export declare const url_package_logo: (homepage_url: string | null, logo_path?: string) => string | null;
|
|
38
|
-
/**
|
|
39
|
-
* Extract repository name without scope from package name.
|
|
40
|
-
*/
|
|
41
|
-
export declare const repo_name_parse: (name: string) => string;
|
|
42
|
-
/**
|
|
43
|
-
* Parse repository URL from package.json format.
|
|
44
|
-
*/
|
|
45
|
-
export declare const repo_url_parse: (repository: PackageJson["repository"]) => string | null;
|
|
46
|
-
/**
|
|
47
|
-
* Build .well-known URL for package metadata files.
|
|
48
|
-
*/
|
|
49
|
-
export declare const url_well_known: (homepage_url: string, filename: string) => string;
|
|
50
41
|
/**
|
|
51
42
|
* Convert a full URL to root-relative format by removing the origin.
|
|
43
|
+
*
|
|
44
|
+
* Uses SvelteKit's page state for the current origin by default.
|
|
45
|
+
*
|
|
46
|
+
* @param url Full URL to convert
|
|
47
|
+
* @param origin Origin to strip (defaults to current page origin)
|
|
48
|
+
* @returns Root-relative URL starting with '/'
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // Assuming page.url.origin is 'https://example.com'
|
|
52
|
+
* url_to_root_relative('https://example.com/docs/api')
|
|
53
|
+
* // => '/docs/api'
|
|
52
54
|
*/
|
|
53
55
|
export declare const url_to_root_relative: (url: string, origin?: string) => string;
|
|
54
56
|
//# sourceMappingURL=library_helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"library_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/library_helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"library_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/library_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,kBAAkB,MAAM,KAAG,MACJ,CAAC;AAE5D;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,GAAI,UAAU,MAAM,EAAE,kBAAkB,MAAM,KAAG,MACR,CAAC;AAE/E;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,aAAa,MAAM,KAAG,MAA2C,CAAC;AAEjG;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC5B,cAAc,MAAM,GAAG,IAAI,EAC3B,YAAY,MAAM,KAChB,MAAM,GAAG,IAIX,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,MAAM,EAAE,SAAQ,MAAwB,KAAG,MAcpF,CAAC"}
|