@fuzdev/fuz_ui 0.194.0 → 0.195.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 (61) hide show
  1. package/dist/DeclarationDetail.svelte +139 -64
  2. package/dist/DeclarationDetail.svelte.d.ts +9 -0
  3. package/dist/DeclarationDetail.svelte.d.ts.map +1 -1
  4. package/dist/LibraryDetail.svelte +14 -10
  5. package/dist/LibraryDetail.svelte.d.ts +7 -0
  6. package/dist/LibraryDetail.svelte.d.ts.map +1 -1
  7. package/dist/declaration.svelte.d.ts +233 -25
  8. package/dist/declaration.svelte.d.ts.map +1 -1
  9. package/dist/declaration.svelte.js +71 -23
  10. package/dist/library.svelte.js +1 -1
  11. package/dist/library_gen.d.ts +24 -17
  12. package/dist/library_gen.d.ts.map +1 -1
  13. package/dist/library_gen.js +52 -32
  14. package/dist/library_output.d.ts +5 -4
  15. package/dist/library_output.d.ts.map +1 -1
  16. package/dist/library_output.js +11 -8
  17. package/dist/module.svelte.d.ts +21 -7
  18. package/dist/module.svelte.d.ts.map +1 -1
  19. package/dist/module.svelte.js +26 -11
  20. package/dist/tsdoc_mdz.d.ts +6 -1
  21. package/dist/tsdoc_mdz.d.ts.map +1 -1
  22. package/dist/tsdoc_mdz.js +23 -2
  23. package/package.json +10 -8
  24. package/src/lib/declaration.svelte.ts +90 -35
  25. package/src/lib/library.svelte.ts +1 -1
  26. package/src/lib/library_gen.ts +65 -42
  27. package/src/lib/library_output.ts +11 -8
  28. package/src/lib/module.svelte.ts +29 -16
  29. package/src/lib/tsdoc_mdz.ts +25 -2
  30. package/dist/analysis_context.d.ts +0 -199
  31. package/dist/analysis_context.d.ts.map +0 -1
  32. package/dist/analysis_context.js +0 -138
  33. package/dist/library_analysis.d.ts +0 -112
  34. package/dist/library_analysis.d.ts.map +0 -1
  35. package/dist/library_analysis.js +0 -106
  36. package/dist/library_generate.d.ts +0 -94
  37. package/dist/library_generate.d.ts.map +0 -1
  38. package/dist/library_generate.js +0 -147
  39. package/dist/library_pipeline.d.ts +0 -113
  40. package/dist/library_pipeline.d.ts.map +0 -1
  41. package/dist/library_pipeline.js +0 -160
  42. package/dist/module_helpers.d.ts +0 -334
  43. package/dist/module_helpers.d.ts.map +0 -1
  44. package/dist/module_helpers.js +0 -317
  45. package/dist/svelte_helpers.d.ts +0 -92
  46. package/dist/svelte_helpers.d.ts.map +0 -1
  47. package/dist/svelte_helpers.js +0 -367
  48. package/dist/ts_helpers.d.ts +0 -181
  49. package/dist/ts_helpers.d.ts.map +0 -1
  50. package/dist/ts_helpers.js +0 -674
  51. package/dist/tsdoc_helpers.d.ts +0 -119
  52. package/dist/tsdoc_helpers.d.ts.map +0 -1
  53. package/dist/tsdoc_helpers.js +0 -207
  54. package/src/lib/analysis_context.ts +0 -254
  55. package/src/lib/library_analysis.ts +0 -168
  56. package/src/lib/library_generate.ts +0 -215
  57. package/src/lib/library_pipeline.ts +0 -221
  58. package/src/lib/module_helpers.ts +0 -501
  59. package/src/lib/svelte_helpers.ts +0 -539
  60. package/src/lib/ts_helpers.ts +0 -862
  61. package/src/lib/tsdoc_helpers.ts +0 -246
@@ -1,501 +0,0 @@
1
- /**
2
- * Module path and metadata helpers.
3
- *
4
- * Provides utilities for working with source module paths, file types,
5
- * and import relationships in the package generation system.
6
- *
7
- * All functions are prefixed with `module_` for clarity.
8
- *
9
- * @module
10
- */
11
-
12
- /**
13
- * Analyzer type for source files.
14
- *
15
- * - `'typescript'` - TypeScript/JS files analyzed via TypeScript Compiler API
16
- * - `'svelte'` - Svelte components analyzed via svelte2tsx + TypeScript Compiler API
17
- */
18
- export type AnalyzerType = 'typescript' | 'svelte';
19
-
20
- /**
21
- * File information for source analysis.
22
- *
23
- * Can be constructed from Gro's `Disknode` or from plain file system access.
24
- * This abstraction enables non-Gro usage while keeping Gro support via adapter.
25
- *
26
- * Note: `content` is required to keep analysis functions pure (no hidden I/O).
27
- * Callers are responsible for reading file content before analysis.
28
- */
29
- export interface SourceFileInfo {
30
- /** Absolute path to the file. */
31
- id: string;
32
- /** File content (required - analysis functions don't read from disk). */
33
- content: string;
34
- /**
35
- * Absolute file paths of modules this file imports (optional).
36
- * Only include resolved local imports, not node_modules.
37
- * Order should be declaration order in source for deterministic output.
38
- */
39
- dependencies?: ReadonlyArray<string>;
40
- /**
41
- * Absolute file paths of modules that import this file (optional).
42
- * Only include resolved local imports, not node_modules.
43
- */
44
- dependents?: ReadonlyArray<string>;
45
- }
46
-
47
- /**
48
- * Configuration for module source detection and path extraction.
49
- *
50
- * Uses proper path semantics with `project_root` as the base for all path operations.
51
- * Paths are matched using `startsWith` rather than substring search, which correctly
52
- * handles nested directories without special heuristics.
53
- *
54
- * @example
55
- * ```ts
56
- * const options = module_create_source_options(process.cwd(), {
57
- * source_paths: ['src/lib', 'src/routes'],
58
- * source_root: 'src',
59
- * });
60
- * ```
61
- */
62
- export interface ModuleSourceOptions {
63
- /**
64
- * Absolute path to the project root directory.
65
- *
66
- * All `source_paths` are relative to this. Typically `process.cwd()` when
67
- * running from the project root via Gro, Vite, or other build tools.
68
- *
69
- * @example
70
- * ```ts
71
- * '/home/user/my-project'
72
- * ```
73
- */
74
- project_root: string;
75
- /**
76
- * Source directory paths to include, relative to `project_root`.
77
- *
78
- * Paths should not have leading or trailing slashes - they are added
79
- * internally for correct matching.
80
- *
81
- * @example
82
- * ```ts
83
- * ['src/lib'] // single source directory
84
- * ```
85
- * @example
86
- * ```ts
87
- * ['src/lib', 'src/routes'] // multiple directories
88
- * ```
89
- */
90
- source_paths: Array<string>;
91
- /**
92
- * Source root for extracting relative module paths, relative to `project_root`.
93
- *
94
- * When omitted:
95
- * - Single `source_path`: defaults to that path
96
- * - Multiple `source_paths`: required (no auto-derivation)
97
- *
98
- * @example
99
- * ```ts
100
- * 'src/lib' // module paths like 'foo.ts', 'utils/bar.ts'
101
- * ```
102
- * @example
103
- * ```ts
104
- * 'src' // module paths like 'lib/foo.ts', 'routes/page.svelte'
105
- * ```
106
- */
107
- source_root?: string;
108
- /** Patterns to exclude (matched against full path). */
109
- exclude_patterns: Array<RegExp>;
110
- /**
111
- * Determine which analyzer to use for a file path.
112
- *
113
- * Called for files in source directories. Return `'typescript'`, `'svelte'`,
114
- * or `null` to skip the file. This is the single source of truth for which
115
- * files are analyzable and how to analyze them.
116
- *
117
- * @default Uses file extension: `.svelte` → svelte, `.ts`/`.js` → typescript
118
- *
119
- * @example
120
- * ```ts
121
- * // Add MDsveX support
122
- * get_analyzer: (path) => {
123
- * if (path.endsWith('.svelte') || path.endsWith('.svx')) return 'svelte';
124
- * if (path.endsWith('.ts') || path.endsWith('.js')) return 'typescript';
125
- * return null;
126
- * }
127
- * ```
128
- *
129
- * @example
130
- * ```ts
131
- * // Include .d.ts files
132
- * get_analyzer: (path) => {
133
- * if (path.endsWith('.svelte')) return 'svelte';
134
- * if (path.endsWith('.ts') || path.endsWith('.d.ts') || path.endsWith('.js')) return 'typescript';
135
- * return null;
136
- * }
137
- * ```
138
- */
139
- get_analyzer: (path: string) => AnalyzerType | null;
140
- }
141
-
142
- /**
143
- * Default analyzer resolver based on file extension.
144
- *
145
- * - `.svelte` → `'svelte'`
146
- * - `.ts`, `.js` → `'typescript'`
147
- * - Other extensions → `null` (skip)
148
- */
149
- export const module_get_analyzer_default = (path: string): AnalyzerType | null => {
150
- if (module_is_svelte(path)) return 'svelte';
151
- if (module_is_typescript(path)) return 'typescript';
152
- return null;
153
- };
154
-
155
- /**
156
- * Partial source options without `project_root`.
157
- *
158
- * Use with `module_create_source_options` to build complete options.
159
- */
160
- export type ModuleSourcePartial = Omit<ModuleSourceOptions, 'project_root'>;
161
-
162
- /**
163
- * Default partial options for standard SvelteKit library structure.
164
- *
165
- * Does not include `project_root` - use `module_create_source_options()` to create
166
- * complete options with your project root.
167
- */
168
- export const MODULE_SOURCE_PARTIAL: ModuleSourcePartial = {
169
- source_paths: ['src/lib'],
170
- exclude_patterns: [/\.test\.ts$/],
171
- get_analyzer: module_get_analyzer_default,
172
- };
173
-
174
- /**
175
- * Create complete source options from project root and optional overrides.
176
- *
177
- * @param project_root - absolute path to project root (typically `process.cwd()`)
178
- * @param overrides - optional overrides for default options
179
- *
180
- * @example
181
- * ```ts
182
- * // Standard SvelteKit library
183
- * const options = module_create_source_options(process.cwd());
184
- * ```
185
- *
186
- * @example
187
- * ```ts
188
- * // Multiple source directories
189
- * const options = module_create_source_options(process.cwd(), {
190
- * source_paths: ['src/lib', 'src/routes'],
191
- * source_root: 'src',
192
- * });
193
- * ```
194
- *
195
- * @example
196
- * ```ts
197
- * // Custom exclusions
198
- * const options = module_create_source_options(process.cwd(), {
199
- * exclude_patterns: [/\.test\.ts$/, /\.internal\.ts$/],
200
- * });
201
- * ```
202
- */
203
- export const module_create_source_options = (
204
- project_root: string,
205
- overrides?: Partial<ModuleSourcePartial>,
206
- ): ModuleSourceOptions => ({
207
- project_root,
208
- ...MODULE_SOURCE_PARTIAL,
209
- ...overrides,
210
- });
211
-
212
- /**
213
- * Validate `ModuleSourceOptions` format and consistency.
214
- *
215
- * Checks:
216
- * 1. `project_root` is an absolute path (starts with `/`)
217
- * 2. `source_paths` entries don't have leading/trailing slashes
218
- * 3. `source_root` (if provided) doesn't have leading/trailing slashes
219
- * 4. Multiple `source_paths` require explicit `source_root`
220
- * 5. `source_root` is a prefix of all `source_paths`
221
- *
222
- * @throws Error if validation fails
223
- *
224
- * @example
225
- * ```ts
226
- * // Valid - single source path (source_root auto-derived)
227
- * module_validate_source_options({
228
- * project_root: '/home/user/project',
229
- * source_paths: ['src/lib'],
230
- * ...
231
- * });
232
- * ```
233
- *
234
- * @example
235
- * ```ts
236
- * // Valid - multiple source paths with explicit source_root
237
- * module_validate_source_options({
238
- * project_root: '/home/user/project',
239
- * source_paths: ['src/lib', 'src/routes'],
240
- * source_root: 'src',
241
- * ...
242
- * });
243
- * ```
244
- *
245
- * @example
246
- * ```ts
247
- * // Invalid - multiple source paths without source_root
248
- * module_validate_source_options({
249
- * project_root: '/home/user/project',
250
- * source_paths: ['src/lib', 'src/routes'], // throws
251
- * ...
252
- * });
253
- * ```
254
- */
255
- export const module_validate_source_options = (options: ModuleSourceOptions): void => {
256
- const {project_root, source_paths, source_root} = options;
257
-
258
- // Validate project_root is absolute
259
- if (!project_root.startsWith('/')) {
260
- throw new Error(`project_root must be an absolute path (start with "/"): "${project_root}"`);
261
- }
262
-
263
- // Validate project_root doesn't have trailing slash (we add it internally)
264
- if (project_root.endsWith('/')) {
265
- throw new Error(
266
- `project_root should not have trailing slash: "${project_root}". ` +
267
- `Trailing slashes are added internally for correct matching.`,
268
- );
269
- }
270
-
271
- // Validate source_paths
272
- if (source_paths.length === 0) {
273
- throw new Error('source_paths must have at least one entry');
274
- }
275
-
276
- for (const source_path of source_paths) {
277
- if (source_path.startsWith('/')) {
278
- throw new Error(
279
- `source_paths entry should not start with "/": "${source_path}". ` +
280
- `Paths are relative to project_root.`,
281
- );
282
- }
283
- if (source_path.endsWith('/')) {
284
- throw new Error(
285
- `source_paths entry should not end with "/": "${source_path}". ` +
286
- `Trailing slashes are added internally for correct matching.`,
287
- );
288
- }
289
- }
290
-
291
- // Validate source_root if provided
292
- if (source_root !== undefined) {
293
- if (source_root.startsWith('/')) {
294
- throw new Error(
295
- `source_root should not start with "/": "${source_root}". ` +
296
- `Paths are relative to project_root.`,
297
- );
298
- }
299
- if (source_root.endsWith('/')) {
300
- throw new Error(
301
- `source_root should not end with "/": "${source_root}". ` +
302
- `Trailing slashes are added internally for correct matching.`,
303
- );
304
- }
305
-
306
- // Validate each source_path starts with source_root
307
- for (const source_path of source_paths) {
308
- // source_path should equal source_root or start with source_root/
309
- if (source_path !== source_root && !source_path.startsWith(source_root + '/')) {
310
- throw new Error(
311
- `source_paths entry "${source_path}" must start with source_root "${source_root}". ` +
312
- `module_extract_path uses source_root to compute module paths.`,
313
- );
314
- }
315
- }
316
- } else if (source_paths.length > 1) {
317
- // Multiple source_paths without source_root - error
318
- throw new Error(
319
- `source_root is required when source_paths has multiple entries. ` +
320
- `Got source_paths: [${source_paths.map((p) => `"${p}"`).join(', ')}]. ` +
321
- `Provide source_root to specify the common prefix for module path extraction.`,
322
- );
323
- }
324
- };
325
-
326
- /**
327
- * Get the effective source_root from options.
328
- *
329
- * Returns `source_root` if provided, otherwise returns `source_paths[0]` for single-path configs.
330
- *
331
- * @throws Error if `source_root` is required but not provided (multiple `source_paths`)
332
- */
333
- export const module_get_source_root = (options: ModuleSourceOptions): string => {
334
- if (options.source_root !== undefined) {
335
- return options.source_root;
336
- }
337
- if (options.source_paths.length === 1) {
338
- return options.source_paths[0]!;
339
- }
340
- throw new Error(
341
- `source_root is required when source_paths has multiple entries. ` +
342
- `Got source_paths: [${options.source_paths.map((p) => `"${p}"`).join(', ')}].`,
343
- );
344
- };
345
-
346
- /**
347
- * Extract module path relative to source root from absolute source ID.
348
- *
349
- * Uses proper path semantics: strips `project_root/source_root/` prefix.
350
- *
351
- * @param source_id - absolute path to the source file
352
- * @param options - module source options for path extraction
353
- *
354
- * @example
355
- * ```ts
356
- * const options = module_create_source_options('/home/user/project');
357
- * module_extract_path('/home/user/project/src/lib/foo.ts', options) // => 'foo.ts'
358
- * module_extract_path('/home/user/project/src/lib/nested/bar.svelte', options) // => 'nested/bar.svelte'
359
- * ```
360
- *
361
- * @example
362
- * ```ts
363
- * const options = module_create_source_options('/home/user/project', {
364
- * source_paths: ['src/lib', 'src/routes'],
365
- * source_root: 'src',
366
- * });
367
- * module_extract_path('/home/user/project/src/lib/foo.ts', options) // => 'lib/foo.ts'
368
- * module_extract_path('/home/user/project/src/routes/page.svelte', options) // => 'routes/page.svelte'
369
- * ```
370
- */
371
- export const module_extract_path = (source_id: string, options: ModuleSourceOptions): string => {
372
- const effective_root = module_get_source_root(options);
373
- // Build the full prefix: project_root + '/' + source_root + '/'
374
- const prefix = options.project_root + '/' + effective_root + '/';
375
-
376
- if (source_id.startsWith(prefix)) {
377
- return source_id.slice(prefix.length);
378
- }
379
- // Fallback: return full path if prefix doesn't match (shouldn't happen with valid inputs)
380
- return source_id;
381
- };
382
-
383
- /**
384
- * Extract component name from a Svelte module path.
385
- *
386
- * @example
387
- * ```ts
388
- * module_get_component_name('Alert.svelte') // => 'Alert'
389
- * module_get_component_name('components/Button.svelte') // => 'Button'
390
- * ```
391
- */
392
- export const module_get_component_name = (module_path: string): string =>
393
- module_path.replace(/^.*\//, '').replace(/\.svelte$/, '');
394
-
395
- /**
396
- * Convert module path to module key format (with ./ prefix).
397
- *
398
- * @example
399
- * ```ts
400
- * module_get_key('foo.ts') // => './foo.ts'
401
- * ```
402
- */
403
- export const module_get_key = (module_path: string): string => `./${module_path}`;
404
-
405
- /**
406
- * Check if a path is a TypeScript or JS file.
407
- *
408
- * Includes both `.ts` and `.js` files since JS files are valid in TS projects.
409
- * Excludes `.d.ts` declaration files - use a custom `get_analyzer` to include them.
410
- */
411
- export const module_is_typescript = (path: string): boolean =>
412
- (path.endsWith('.ts') && !path.endsWith('.d.ts')) || path.endsWith('.js');
413
-
414
- export const module_is_svelte = (path: string): boolean => path.endsWith('.svelte');
415
-
416
- export const module_is_css = (path: string): boolean => path.endsWith('.css');
417
-
418
- export const module_is_json = (path: string): boolean => path.endsWith('.json');
419
-
420
- export const module_is_test = (path: string): boolean => path.endsWith('.test.ts');
421
-
422
- /**
423
- * Check if a path is an analyzable source file.
424
- *
425
- * Combines all filtering: exclusion patterns, source directory paths,
426
- * and analyzer availability. This is the single check for whether a
427
- * file should be included in library analysis.
428
- *
429
- * Uses proper path semantics with `startsWith` matching against
430
- * `project_root/source_path/`. No heuristics needed - nested directories
431
- * are correctly excluded by the prefix check.
432
- *
433
- * @param path - full absolute path to check
434
- * @param options - module source options for filtering
435
- * @returns true if the path is an analyzable source file
436
- *
437
- * @example
438
- * ```ts
439
- * const options = module_create_source_options('/home/user/project');
440
- * module_is_source('/home/user/project/src/lib/foo.ts', options) // => true
441
- * module_is_source('/home/user/project/src/lib/foo.test.ts', options) // => false (excluded)
442
- * module_is_source('/home/user/project/src/fixtures/mini/src/lib/bar.ts', options) // => false (wrong prefix)
443
- * ```
444
- */
445
- export const module_is_source = (path: string, options: ModuleSourceOptions): boolean => {
446
- // Check exclusion patterns first (fast regex check)
447
- const is_excluded = options.exclude_patterns.some((pattern) => pattern.test(path));
448
- if (is_excluded) return false;
449
-
450
- // Check if path starts with project_root/source_path/
451
- // Using startsWith with trailing slash ensures correct directory matching
452
- const in_source_dir = options.source_paths.some((source_path) => {
453
- const full_prefix = options.project_root + '/' + source_path + '/';
454
- return path.startsWith(full_prefix);
455
- });
456
- if (!in_source_dir) return false;
457
-
458
- // Check if file type is analyzable
459
- return options.get_analyzer(path) !== null;
460
- };
461
-
462
- /**
463
- * Extract dependencies and dependents for a module from source file info.
464
- *
465
- * Filters to only include source modules (excludes external packages, node_modules, tests).
466
- * Returns sorted arrays of module paths (relative to source_root) for deterministic output.
467
- *
468
- * @param source_file - the source file info to extract dependencies from
469
- * @param options - module source options for filtering and path extraction
470
- */
471
- export const module_extract_dependencies = (
472
- source_file: SourceFileInfo,
473
- options: ModuleSourceOptions,
474
- ): {dependencies: Array<string>; dependents: Array<string>} => {
475
- const dependencies: Array<string> = [];
476
- const dependents: Array<string> = [];
477
-
478
- // Extract dependencies (files this module imports) if provided
479
- if (source_file.dependencies) {
480
- for (const dep_id of source_file.dependencies) {
481
- if (module_is_source(dep_id, options)) {
482
- dependencies.push(module_extract_path(dep_id, options));
483
- }
484
- }
485
- }
486
-
487
- // Extract dependents (files that import this module) if provided
488
- if (source_file.dependents) {
489
- for (const dependent_id of source_file.dependents) {
490
- if (module_is_source(dependent_id, options)) {
491
- dependents.push(module_extract_path(dependent_id, options));
492
- }
493
- }
494
- }
495
-
496
- // Sort for deterministic output
497
- dependencies.sort();
498
- dependents.sort();
499
-
500
- return {dependencies, dependents};
501
- };