sveld 0.29.1 → 0.30.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/README.md +19 -2
- package/lib/ComponentParser.d.ts +33 -1
- package/lib/index.js +690 -164
- package/lib/writer/Writer.d.ts +4 -2
- package/lib/writer/writer-ts-definitions.d.ts +1 -0
- package/package.json +2 -5
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ The purpose of this project is to make third party Svelte component libraries co
|
|
|
11
11
|
|
|
12
12
|
`sveld` uses the Svelte 5 compiler to parse `.svelte` files. That single parse path powers docgen and TypeScript output for Svelte 3, Svelte 4, Svelte 5 without runes (`export let`, `<slot>`, `$$restProps`, …), and Svelte 5 Runes (`$props()`, `$bindable()`, `{@render ...}`, callback props such as `onclick`, …).
|
|
13
13
|
|
|
14
|
+
For `lang="ts"` components, `sveld` preserves source-level prop type annotations when possible instead of requiring JSDoc as the primary source of truth. This includes legacy `export let` props, typed `$props()` destructuring, typed whole-object `$props()` captures, local `interface`/`type` declarations, and imported type references in emitted `.d.ts` files.
|
|
15
|
+
|
|
14
16
|
| Syntax mode | Supported |
|
|
15
17
|
| :------------------- | :-------: |
|
|
16
18
|
| Svelte 3 | ✓ |
|
|
@@ -156,6 +158,15 @@ Extracted metadata include:
|
|
|
156
158
|
|
|
157
159
|
This library adopts a progressively enhanced approach. Any property type that cannot be inferred (e.g., "hello" is a string) falls back to "any" to minimize incorrectly typed properties or signatures. To mitigate this, the library author can add JSDoc annotations to specify types that cannot be reliably inferred. This represents a progressively enhanced approach because JSDocs are comments that can be ignored by the compiler.
|
|
158
160
|
|
|
161
|
+
When both TypeScript syntax and JSDoc are present, `sveld` resolves prop types in this order:
|
|
162
|
+
|
|
163
|
+
1. explicit TypeScript annotation
|
|
164
|
+
2. explicit JSDoc annotation
|
|
165
|
+
3. initializer inference
|
|
166
|
+
4. `any`
|
|
167
|
+
|
|
168
|
+
`sveld` intentionally stays AST-only. It preserves imported and local type text in generated `.d.ts` output, but it does not perform project-wide semantic resolution with the TypeScript compiler. That means opaque imported whole-object `$props()` types can be preserved in declarations without being fully expanded into JSON metadata.
|
|
169
|
+
|
|
159
170
|
## Usage
|
|
160
171
|
|
|
161
172
|
### Installation
|
|
@@ -204,13 +215,15 @@ sveld({
|
|
|
204
215
|
When building the library, TypeScript definitions are emitted to the `types` folder by default.
|
|
205
216
|
|
|
206
217
|
Customize the output folder using the `typesOptions.outDir` option.
|
|
218
|
+
Use `typesOptions.printWidth` to control Prettier wrapping for generated `.d.ts` files. The default is `80`.
|
|
207
219
|
|
|
208
220
|
The following example emits the output to the `dist` folder:
|
|
209
221
|
|
|
210
222
|
```diff
|
|
211
223
|
sveld({
|
|
212
224
|
+ typesOptions: {
|
|
213
|
-
+ outDir: 'dist'
|
|
225
|
+
+ outDir: 'dist',
|
|
226
|
+
+ printWidth: 80
|
|
214
227
|
+ }
|
|
215
228
|
})
|
|
216
229
|
```
|
|
@@ -300,7 +313,7 @@ TypeScript definitions are outputted to the `types` folder by default. Don't for
|
|
|
300
313
|
- **`entry`** (string, optional): Specify the entry point to uncompiled Svelte source. If not provided, sveld will use the `"svelte"` field from `package.json`.
|
|
301
314
|
- **`glob`** (boolean, optional): Enable glob mode to analyze all `*.svelte` files.
|
|
302
315
|
- **`types`** (boolean, optional, default: `true`): Generate TypeScript definitions.
|
|
303
|
-
- **`typesOptions`** (object, optional): Options for TypeScript definition generation
|
|
316
|
+
- **`typesOptions`** (object, optional): Options for TypeScript definition generation, including `outDir`, `preamble`, and `printWidth`.
|
|
304
317
|
- **`json`** (boolean, optional): Generate component documentation in JSON format.
|
|
305
318
|
- **`jsonOptions`** (object, optional): Options for JSON output.
|
|
306
319
|
- **`markdown`** (boolean, optional): Generate component documentation in Markdown format.
|
|
@@ -354,6 +367,8 @@ export let id = `ccs-${Math.random().toString(36)}`;
|
|
|
354
367
|
|
|
355
368
|
Use the `@type` tag to explicitly document the type. In the following example, the `kind` property has an enumerated (enum) type.
|
|
356
369
|
|
|
370
|
+
For `lang="ts"` components, prefer native TypeScript annotations when they are already present. `@type` remains useful for JavaScript components, for overriding inferred types, and for cases where the AST cannot recover a more precise type.
|
|
371
|
+
|
|
357
372
|
**Signature:**
|
|
358
373
|
|
|
359
374
|
```js
|
|
@@ -761,6 +776,8 @@ For Svelte 5 compatibility, `sveld` automatically generates optional snippet pro
|
|
|
761
776
|
|
|
762
777
|
When parsing runes components, `sveld` maps `{@render ...}` calls back into the same slot metadata used for traditional `<slot>` declarations. Reserved snippet props such as `children`, along with named snippet props discovered from `{@render ...}`, are represented through `slots` metadata and generated snippet prop types rather than duplicated in the `props` output.
|
|
763
778
|
|
|
779
|
+
Positional snippet calls such as `{@render row?.(item, index)}` are preserved as typed props when the prop itself has an explicit type like `Snippet<[Item, number]>`. They are not converted into synthetic slot metadata.
|
|
780
|
+
|
|
764
781
|
For slots with props (e.g., `let:prop`), the generated type uses a Snippet-compatible signature:
|
|
765
782
|
|
|
766
783
|
```ts
|
package/lib/ComponentParser.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
export interface ParsedComponentTypeScriptMetadata {
|
|
2
|
+
canonicalPropsType?: string;
|
|
3
|
+
canonicalPropNames: string[];
|
|
4
|
+
localTypeDeclarations: string[];
|
|
5
|
+
typeImportStatements: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare const PARSED_COMPONENT_TYPE_SCRIPT_METADATA: unique symbol;
|
|
8
|
+
export declare function getParsedComponentTypeScriptMetadata(component: {
|
|
9
|
+
[PARSED_COMPONENT_TYPE_SCRIPT_METADATA]?: ParsedComponentTypeScriptMetadata;
|
|
10
|
+
}): ParsedComponentTypeScriptMetadata | undefined;
|
|
1
11
|
/**
|
|
2
12
|
* Diagnostic information for component parsing.
|
|
3
13
|
*
|
|
@@ -258,6 +268,8 @@ export interface ParsedComponent {
|
|
|
258
268
|
componentComment?: string;
|
|
259
269
|
/** Contexts created with `setContext` in the component */
|
|
260
270
|
contexts?: ComponentContext[];
|
|
271
|
+
/** Internal writer-only TypeScript metadata. Not serialized to JSON. */
|
|
272
|
+
[PARSED_COMPONENT_TYPE_SCRIPT_METADATA]?: ParsedComponentTypeScriptMetadata;
|
|
261
273
|
}
|
|
262
274
|
export default class ComponentParser {
|
|
263
275
|
/** Parser configuration options (e.g., verbose logging) */
|
|
@@ -306,10 +318,20 @@ export default class ComponentParser {
|
|
|
306
318
|
private readonly propLocalToPublicName;
|
|
307
319
|
/** Tracks `$props()` bindings that are used as spread/rest props */
|
|
308
320
|
private readonly restPropLocals;
|
|
321
|
+
/** Tracks identifier bindings that capture the entire `$props()` object */
|
|
322
|
+
private readonly wholePropsLocals;
|
|
309
323
|
/** Tracks prop locals that are used as snippet/render props */
|
|
310
324
|
private readonly snippetPropLocals;
|
|
311
325
|
/** Per-declarator type metadata extracted from modern AST `$props()` annotations */
|
|
312
|
-
private readonly
|
|
326
|
+
private readonly runesPropsDeclarationMetadataByDeclaratorStart;
|
|
327
|
+
/** Explicit TypeScript prop annotations for legacy `export let` declarations keyed by local name */
|
|
328
|
+
private readonly explicitPropTypesByName;
|
|
329
|
+
/** Type-only imports keyed by their local binding names */
|
|
330
|
+
private readonly typeImportBindingsByLocalName;
|
|
331
|
+
/** Local interface/type declarations keyed by type name */
|
|
332
|
+
private readonly localTypeDeclarationsByName;
|
|
333
|
+
/** Typed `$props()` declarations discovered in source order */
|
|
334
|
+
private readonly typedRunesPropsDeclarations;
|
|
313
335
|
/** Component-level lexical scope shared by instance script and template */
|
|
314
336
|
private readonly componentScope;
|
|
315
337
|
/** Precomputed lexical scopes for nested AST nodes */
|
|
@@ -325,7 +347,16 @@ export default class ComponentParser {
|
|
|
325
347
|
private trackPropLocalName;
|
|
326
348
|
private getPropByLocalOrPublic;
|
|
327
349
|
private getPropTypeByLocalOrPublic;
|
|
350
|
+
private getExplicitPropType;
|
|
351
|
+
private getRunesPropsDeclarationMetadata;
|
|
328
352
|
private getRunesPropTypeMetadata;
|
|
353
|
+
private getTypeReferenceName;
|
|
354
|
+
private getTypeDependencyName;
|
|
355
|
+
private getTypeAnnotationText;
|
|
356
|
+
private collectReferencedTypeDependencies;
|
|
357
|
+
private buildTypeImportStatements;
|
|
358
|
+
private buildTypeScriptMetadata;
|
|
359
|
+
private buildRunesPropTypeMetadataMap;
|
|
329
360
|
private declareScopeBinding;
|
|
330
361
|
private resolveIdentifierToReactiveProp;
|
|
331
362
|
private collectPatternIdentifiers;
|
|
@@ -499,6 +530,7 @@ export default class ComponentParser {
|
|
|
499
530
|
private parseRunesPropsDeclaration;
|
|
500
531
|
private inferSlotPropValueFromExpression;
|
|
501
532
|
private buildSlotPropsFromObjectExpression;
|
|
533
|
+
private resolveRenderTagPropReference;
|
|
502
534
|
private extractRenderTagInfo;
|
|
503
535
|
/**
|
|
504
536
|
* Adds or merges a component prop to the props map.
|