svelte-docinfo 0.12.0 → 0.13.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 +1 -2
- package/dist/analyze-core.d.ts +2 -2
- package/dist/diagnostics.d.ts +5 -29
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +4 -21
- package/dist/svelte-legacy.d.ts +145 -0
- package/dist/svelte-legacy.d.ts.map +1 -0
- package/dist/svelte-legacy.js +210 -0
- package/dist/svelte-scripts.d.ts +144 -0
- package/dist/svelte-scripts.d.ts.map +1 -0
- package/dist/svelte-scripts.js +242 -0
- package/dist/svelte.d.ts +33 -11
- package/dist/svelte.d.ts.map +1 -1
- package/dist/svelte.js +284 -213
- package/dist/types.d.ts +16 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +16 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -372,8 +372,7 @@ Known gaps:
|
|
|
372
372
|
|
|
373
373
|
- context tracking (transitive detection of common patterns seems tractable)
|
|
374
374
|
- standalone `namespace Foo {}` declarations and decorators are not yet supported
|
|
375
|
-
-
|
|
376
|
-
- legacy `export let` props aren't extracted (the component gets zero props), but a `legacy_props` warning names them
|
|
375
|
+
- legacy `export let` components document their props (all `bindable`), and a legacy component's default `<slot />` sets `acceptsChildren`, but named slots, slot props, events, and `$$restProps` aren't modeled — Svelte 5 snippets and callback props replace most of them
|
|
377
376
|
- `@nodocs` applies to declarations and export statements only; on a member or component prop it's ignored without a warning
|
|
378
377
|
|
|
379
378
|
[Issues](https://github.com/fuzdev/svelte-docinfo/issues) for bugs and
|
package/dist/analyze-core.d.ts
CHANGED
|
@@ -65,14 +65,14 @@ import { type IsEmittedFile } from './typescript-extract-shared.js';
|
|
|
65
65
|
export type OnDuplicates = 'diagnostic' | 'warn' | 'throw';
|
|
66
66
|
declare const AnalyzeResultJsonEntries: v.StrictObjectSchema<{
|
|
67
67
|
readonly modules: v.OptionalSchema<v.ArraySchema<import("./types.js").ModuleJsonSchema, undefined>, () => never[]>;
|
|
68
|
-
readonly diagnostics: v.OptionalSchema<v.ArraySchema<v.VariantSchema<"kind", [import("./diagnostics.js").TypeExtractionDiagnosticSchema, import("./diagnostics.js").SignatureAnalysisDiagnosticSchema, import("./diagnostics.js").ClassMemberDiagnosticSchema, import("./diagnostics.js").SveltePropDiagnosticSchema, import("./diagnostics.js").
|
|
68
|
+
readonly diagnostics: v.OptionalSchema<v.ArraySchema<v.VariantSchema<"kind", [import("./diagnostics.js").TypeExtractionDiagnosticSchema, import("./diagnostics.js").SignatureAnalysisDiagnosticSchema, import("./diagnostics.js").ClassMemberDiagnosticSchema, import("./diagnostics.js").SveltePropDiagnosticSchema, import("./diagnostics.js").ModuleSkippedDiagnosticSchema, import("./diagnostics.js").ModuleUnreadableDiagnosticSchema, import("./diagnostics.js").ImportParseDiagnosticSchema, import("./diagnostics.js").DuplicateCommentDiagnosticSchema, import("./diagnostics.js").MisplacedTagDiagnosticSchema, import("./diagnostics.js").UnknownParamDiagnosticSchema, import("./diagnostics.js").SourceMapFailedDiagnosticSchema, import("./diagnostics.js").DuplicateDeclarationDiagnosticSchema, import("./diagnostics.js").TransformFailedDiagnosticSchema, import("./diagnostics.js").ResolverFailedDiagnosticSchema, import("./diagnostics.js").AliasLostDiagnosticSchema], undefined>, undefined>, () => never[]>;
|
|
69
69
|
}, undefined>;
|
|
70
70
|
/** @nodocs */
|
|
71
71
|
export interface AnalyzeResultJsonEntriesInput extends Named<v.InferInput<typeof AnalyzeResultJsonEntries>> {
|
|
72
72
|
}
|
|
73
73
|
declare const AnalyzeResultJsonImpl: v.SchemaWithPipe<readonly [v.CustomSchema<AnalyzeResultJsonEntriesInput, v.ErrorMessage<v.CustomIssue> | undefined>, v.StrictObjectSchema<{
|
|
74
74
|
readonly modules: v.OptionalSchema<v.ArraySchema<import("./types.js").ModuleJsonSchema, undefined>, () => never[]>;
|
|
75
|
-
readonly diagnostics: v.OptionalSchema<v.ArraySchema<v.VariantSchema<"kind", [import("./diagnostics.js").TypeExtractionDiagnosticSchema, import("./diagnostics.js").SignatureAnalysisDiagnosticSchema, import("./diagnostics.js").ClassMemberDiagnosticSchema, import("./diagnostics.js").SveltePropDiagnosticSchema, import("./diagnostics.js").
|
|
75
|
+
readonly diagnostics: v.OptionalSchema<v.ArraySchema<v.VariantSchema<"kind", [import("./diagnostics.js").TypeExtractionDiagnosticSchema, import("./diagnostics.js").SignatureAnalysisDiagnosticSchema, import("./diagnostics.js").ClassMemberDiagnosticSchema, import("./diagnostics.js").SveltePropDiagnosticSchema, import("./diagnostics.js").ModuleSkippedDiagnosticSchema, import("./diagnostics.js").ModuleUnreadableDiagnosticSchema, import("./diagnostics.js").ImportParseDiagnosticSchema, import("./diagnostics.js").DuplicateCommentDiagnosticSchema, import("./diagnostics.js").MisplacedTagDiagnosticSchema, import("./diagnostics.js").UnknownParamDiagnosticSchema, import("./diagnostics.js").SourceMapFailedDiagnosticSchema, import("./diagnostics.js").DuplicateDeclarationDiagnosticSchema, import("./diagnostics.js").TransformFailedDiagnosticSchema, import("./diagnostics.js").ResolverFailedDiagnosticSchema, import("./diagnostics.js").AliasLostDiagnosticSchema], undefined>, undefined>, () => never[]>;
|
|
76
76
|
}, undefined>]>;
|
|
77
77
|
/** @nodocs */
|
|
78
78
|
export interface AnalyzeResultJsonSchema extends Named<typeof AnalyzeResultJsonImpl> {
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -80,7 +80,7 @@ export type DiagnosticSeverity = v.InferOutput<typeof DiagnosticSeverity>;
|
|
|
80
80
|
* Severity is a stable per-kind property: `transform_failed` and
|
|
81
81
|
* `module_unreadable` are always `error`, every other kind always `warning`.
|
|
82
82
|
*/
|
|
83
|
-
export declare const DiagnosticKind: v.PicklistSchema<["type_extraction_failed", "signature_analysis_failed", "class_member_failed", "svelte_prop_failed", "
|
|
83
|
+
export declare const DiagnosticKind: v.PicklistSchema<["type_extraction_failed", "signature_analysis_failed", "class_member_failed", "svelte_prop_failed", "module_skipped", "module_unreadable", "import_parse_failed", "duplicate_comment", "misplaced_tag", "unknown_param", "source_map_failed", "duplicate_declaration", "transform_failed", "resolver_failed", "alias_lost"], undefined>;
|
|
84
84
|
export type DiagnosticKind = v.InferOutput<typeof DiagnosticKind>;
|
|
85
85
|
declare const TypeExtractionDiagnosticImpl: v.StrictObjectSchema<{
|
|
86
86
|
/** Name of the symbol whose type couldn't be extracted. */
|
|
@@ -156,6 +156,10 @@ export interface SveltePropDiagnosticSchema extends Named<typeof SveltePropDiagn
|
|
|
156
156
|
/**
|
|
157
157
|
* Svelte prop type resolution failed.
|
|
158
158
|
*
|
|
159
|
+
* Also emitted once per `export let` prop of a legacy component whose
|
|
160
|
+
* svelte2tsx output has no recognized props type: those props aren't
|
|
161
|
+
* extracted, and each failure carries its export's line.
|
|
162
|
+
*
|
|
159
163
|
* `file` is the original `.svelte` path, so `line`/`column` are present only
|
|
160
164
|
* when the prop's declaration lives in the component's own virtual *and* maps
|
|
161
165
|
* back to the original source — an imported props type or a node svelte2tsx
|
|
@@ -165,33 +169,6 @@ export interface SveltePropDiagnosticSchema extends Named<typeof SveltePropDiagn
|
|
|
165
169
|
*/
|
|
166
170
|
export declare const SveltePropDiagnostic: SveltePropDiagnosticSchema;
|
|
167
171
|
export type SveltePropDiagnostic = v.InferOutput<typeof SveltePropDiagnostic>;
|
|
168
|
-
declare const LegacyPropsDiagnosticImpl: v.StrictObjectSchema<{
|
|
169
|
-
/** Name of the component. */
|
|
170
|
-
readonly componentName: v.StringSchema<undefined>;
|
|
171
|
-
/** Exported prop names, in source order. */
|
|
172
|
-
readonly propNames: v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.MinLengthAction<string[], 1, undefined>]>;
|
|
173
|
-
readonly file: v.StringSchema<undefined>;
|
|
174
|
-
readonly line: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.SafeIntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
|
|
175
|
-
readonly column: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.SafeIntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
|
|
176
|
-
readonly message: v.StringSchema<undefined>;
|
|
177
|
-
readonly severity: v.PicklistSchema<["error", "warning"], undefined>;
|
|
178
|
-
readonly kind: v.LiteralSchema<"legacy_props", undefined>;
|
|
179
|
-
}, undefined>;
|
|
180
|
-
/** @nodocs */
|
|
181
|
-
export interface LegacyPropsDiagnosticSchema extends Named<typeof LegacyPropsDiagnosticImpl> {
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Legacy (runes-less) component props detected — not extracted.
|
|
185
|
-
*
|
|
186
|
-
* `export let` components are still-legal Svelte 5 syntax, but prop extraction
|
|
187
|
-
* anchors on the `$props()` declaration, so their props yield no
|
|
188
|
-
* `ComponentPropJson` entries. Emitted once per component, listing the
|
|
189
|
-
* detected prop names — exported `let`/`var` statements plus export-clause
|
|
190
|
-
* renames of mutable bindings (`export {a as b}`) — with `line` pointing at
|
|
191
|
-
* the first legacy prop export in the original `.svelte` source.
|
|
192
|
-
*/
|
|
193
|
-
export declare const LegacyPropsDiagnostic: LegacyPropsDiagnosticSchema;
|
|
194
|
-
export type LegacyPropsDiagnostic = v.InferOutput<typeof LegacyPropsDiagnostic>;
|
|
195
172
|
declare const ModuleSkippedDiagnosticImpl: v.StrictObjectSchema<{
|
|
196
173
|
/** Reason the module was skipped. */
|
|
197
174
|
readonly reason: v.PicklistSchema<["not_in_program", "no_analyzer", "requires_program"], undefined>;
|
|
@@ -497,7 +474,6 @@ export declare const Diagnostic: v.VariantSchema<'kind', [
|
|
|
497
474
|
typeof SignatureAnalysisDiagnostic,
|
|
498
475
|
typeof ClassMemberDiagnostic,
|
|
499
476
|
typeof SveltePropDiagnostic,
|
|
500
|
-
typeof LegacyPropsDiagnostic,
|
|
501
477
|
typeof ModuleSkippedDiagnostic,
|
|
502
478
|
typeof ModuleUnreadableDiagnostic,
|
|
503
479
|
typeof ImportParseDiagnostic,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AAEH,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,OAAO,EAAoB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAI3D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,mDAAmC,CAAC;AACnE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI1E;;;;;GAKG;AACH,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/diagnostics.ts"],"names":[],"mappings":"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"}
|
package/dist/diagnostics.js
CHANGED
|
@@ -86,7 +86,6 @@ export const DiagnosticKind = v.picklist([
|
|
|
86
86
|
'signature_analysis_failed',
|
|
87
87
|
'class_member_failed',
|
|
88
88
|
'svelte_prop_failed',
|
|
89
|
-
'legacy_props',
|
|
90
89
|
'module_skipped',
|
|
91
90
|
'module_unreadable',
|
|
92
91
|
'import_parse_failed',
|
|
@@ -187,6 +186,10 @@ const SveltePropDiagnosticImpl = v.strictObject({
|
|
|
187
186
|
/**
|
|
188
187
|
* Svelte prop type resolution failed.
|
|
189
188
|
*
|
|
189
|
+
* Also emitted once per `export let` prop of a legacy component whose
|
|
190
|
+
* svelte2tsx output has no recognized props type: those props aren't
|
|
191
|
+
* extracted, and each failure carries its export's line.
|
|
192
|
+
*
|
|
190
193
|
* `file` is the original `.svelte` path, so `line`/`column` are present only
|
|
191
194
|
* when the prop's declaration lives in the component's own virtual *and* maps
|
|
192
195
|
* back to the original source — an imported props type or a node svelte2tsx
|
|
@@ -195,25 +198,6 @@ const SveltePropDiagnosticImpl = v.strictObject({
|
|
|
195
198
|
* diagnostics.
|
|
196
199
|
*/
|
|
197
200
|
export const SveltePropDiagnostic = SveltePropDiagnosticImpl;
|
|
198
|
-
const LegacyPropsDiagnosticImpl = v.strictObject({
|
|
199
|
-
kind: v.literal('legacy_props'),
|
|
200
|
-
...baseDiagnosticFields,
|
|
201
|
-
/** Name of the component. */
|
|
202
|
-
componentName: v.string(),
|
|
203
|
-
/** Exported prop names, in source order. */
|
|
204
|
-
propNames: v.pipe(v.array(v.string()), v.minLength(1))
|
|
205
|
-
});
|
|
206
|
-
/**
|
|
207
|
-
* Legacy (runes-less) component props detected — not extracted.
|
|
208
|
-
*
|
|
209
|
-
* `export let` components are still-legal Svelte 5 syntax, but prop extraction
|
|
210
|
-
* anchors on the `$props()` declaration, so their props yield no
|
|
211
|
-
* `ComponentPropJson` entries. Emitted once per component, listing the
|
|
212
|
-
* detected prop names — exported `let`/`var` statements plus export-clause
|
|
213
|
-
* renames of mutable bindings (`export {a as b}`) — with `line` pointing at
|
|
214
|
-
* the first legacy prop export in the original `.svelte` source.
|
|
215
|
-
*/
|
|
216
|
-
export const LegacyPropsDiagnostic = LegacyPropsDiagnosticImpl;
|
|
217
201
|
const ModuleSkippedDiagnosticImpl = v.strictObject({
|
|
218
202
|
kind: v.literal('module_skipped'),
|
|
219
203
|
...baseDiagnosticFields,
|
|
@@ -444,7 +428,6 @@ export const Diagnostic = v.variant('kind', [
|
|
|
444
428
|
SignatureAnalysisDiagnostic,
|
|
445
429
|
ClassMemberDiagnostic,
|
|
446
430
|
SveltePropDiagnostic,
|
|
447
|
-
LegacyPropsDiagnostic,
|
|
448
431
|
ModuleSkippedDiagnostic,
|
|
449
432
|
ModuleUnreadableDiagnostic,
|
|
450
433
|
ImportParseDiagnostic,
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy (runes-less) Svelte component support: props declared with
|
|
3
|
+
* `export let` instead of `$props()`.
|
|
4
|
+
*
|
|
5
|
+
* Still-legal syntax under Svelte 5, with no `$props()` declaration for prop
|
|
6
|
+
* extraction to anchor on. This module supplies the two things that replace
|
|
7
|
+
* it, and nothing else: a syntactic scan of the original instance script
|
|
8
|
+
* (`scanLegacyExports`) and the checker anchor in the svelte2tsx virtual
|
|
9
|
+
* (`resolveLegacyPropsAnchor`). `analyzeSvelteModule` hands the result to the
|
|
10
|
+
* same prop extraction the runes path uses, so filtering, types, callbacks,
|
|
11
|
+
* and JSDoc are shared.
|
|
12
|
+
*
|
|
13
|
+
* What a legacy component documents: its props, all of them bindable (any
|
|
14
|
+
* `export let` can be bound). Slots and events aren't modeled here; a default
|
|
15
|
+
* slot sets `acceptsChildren` in `svelte.ts`, which covers legacy components
|
|
16
|
+
* with no props too.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
import ts from 'typescript';
|
|
23
|
+
/** A prop found by `scanLegacyExports`. */
|
|
24
|
+
export interface LegacyProp {
|
|
25
|
+
/** Exported prop name (the rename in the `export {a as b}` form). */
|
|
26
|
+
name: string;
|
|
27
|
+
/** Offset of the export within the script content; the caller owns line mapping. */
|
|
28
|
+
pos: number;
|
|
29
|
+
/** Whether the binding has an initializer, which makes the prop optional. */
|
|
30
|
+
hasInitializer: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Verbatim source text of the initializer. Absent without one, and for an
|
|
33
|
+
* explicit `undefined`, which says the same as no default.
|
|
34
|
+
*/
|
|
35
|
+
defaultValue?: string;
|
|
36
|
+
}
|
|
37
|
+
/** What `scanLegacyExports` reads from an instance script. */
|
|
38
|
+
export interface LegacyExports {
|
|
39
|
+
/** Props, in source order of their exports. */
|
|
40
|
+
props: Array<LegacyProp>;
|
|
41
|
+
/**
|
|
42
|
+
* Exported names of accessors: `export const`, `export function`,
|
|
43
|
+
* `export class`, and export clauses over those bindings. svelte2tsx lists
|
|
44
|
+
* them in the props type as optional properties, but they're read from the
|
|
45
|
+
* component instance, never passed in.
|
|
46
|
+
*/
|
|
47
|
+
accessors: Set<string>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Scan an instance script for legacy props and accessors.
|
|
51
|
+
*
|
|
52
|
+
* Runes-less components declare props by exporting mutable bindings —
|
|
53
|
+
* `export let a` / `export var a` directly, or `let a; export {a as b}` for
|
|
54
|
+
* renames (the reserved-word workaround). `export const` / `export function` /
|
|
55
|
+
* `export class` are accessors, not props, and type-only exports aren't
|
|
56
|
+
* runtime bindings.
|
|
57
|
+
*
|
|
58
|
+
* The scan says what the script exports, not what mode the component is in:
|
|
59
|
+
* a runes component can export a mutable binding too, as an instance export.
|
|
60
|
+
* The caller scans only a component svelte2tsx didn't read as runes
|
|
61
|
+
* (`classifyRenderMode` in `svelte.ts`).
|
|
62
|
+
*
|
|
63
|
+
* The scan reads the *original* instance script because svelte2tsx rewrites
|
|
64
|
+
* the `export` modifier away inside `$$render`; a purely syntactic walk over
|
|
65
|
+
* top-level statements is all it needs. It's also where defaults come from:
|
|
66
|
+
* `defaultValue` is the initializer's source text as the author wrote it.
|
|
67
|
+
*
|
|
68
|
+
* @param scriptSource - parsed instance `<script>` content from the original source
|
|
69
|
+
* @returns props in source order (empty when the script exports no mutable binding) and accessor names
|
|
70
|
+
*/
|
|
71
|
+
export declare const scanLegacyExports: (scriptSource: ts.SourceFile) => LegacyExports;
|
|
72
|
+
/** The checker anchor for a legacy component's props, resolved by `resolveLegacyPropsAnchor`. */
|
|
73
|
+
export interface LegacyPropsAnchor {
|
|
74
|
+
/** The props type. */
|
|
75
|
+
type: ts.Type;
|
|
76
|
+
/**
|
|
77
|
+
* The node the type was read from, in the component's own virtual: the
|
|
78
|
+
* written type (a TS component) or the props object literal (a JS one,
|
|
79
|
+
* which has no type node).
|
|
80
|
+
*/
|
|
81
|
+
node: ts.Node;
|
|
82
|
+
/**
|
|
83
|
+
* Which props value shape `node` was read from:
|
|
84
|
+
*
|
|
85
|
+
* - `'untyped'` — a bare object literal (a JS component, and a TS one whose
|
|
86
|
+
* exports are all untyped and uninitialized). Every property reads as
|
|
87
|
+
* required, so optionality comes from the script instead
|
|
88
|
+
* (`LegacyProp.hasInitializer`). Only the scanned prop names are props.
|
|
89
|
+
* - `'generated'` — a type svelte2tsx wrote from the exports, whose
|
|
90
|
+
* properties carry their own optionality. It lists every export,
|
|
91
|
+
* accessors and type-only exports included, so only the scanned prop
|
|
92
|
+
* names are props.
|
|
93
|
+
* - `'authored'` — the author's own `$$Props`, whose properties carry their
|
|
94
|
+
* own optionality. It can declare props the script never exports, so all
|
|
95
|
+
* of its properties are props except the accessors, which svelte2tsx
|
|
96
|
+
* intersects in beside it.
|
|
97
|
+
*/
|
|
98
|
+
kind: 'untyped' | 'generated' | 'authored';
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Resolve the props anchor of a legacy component from its svelte2tsx virtual.
|
|
102
|
+
*
|
|
103
|
+
* svelte2tsx ends `$$render` with `return {props: …, slots: …, …}`, and the
|
|
104
|
+
* `props` value is the anchor. The shapes recognized:
|
|
105
|
+
*
|
|
106
|
+
* - **Typed** — `<object> as <Type>`. The type is a literal svelte2tsx writes
|
|
107
|
+
* from the exports, carrying each prop's JSDoc and optionality
|
|
108
|
+
* (`{a?: typeof a, b: number}`: `'generated'`), or the author's reserved
|
|
109
|
+
* `$$Props`, bare or intersected with a literal of the accessors
|
|
110
|
+
* (`'authored'`).
|
|
111
|
+
* - **Untyped** — a bare object literal (`{a: a, b: b}`: `'untyped'`), what a
|
|
112
|
+
* JS component gets, and a TS one whose exports are all untyped and
|
|
113
|
+
* uninitialized, with each binding's JSDoc copied onto its property, so a
|
|
114
|
+
* `@type` there types the prop.
|
|
115
|
+
*
|
|
116
|
+
* Anything else is `undefined`: an unknown virtual yields no props rather
|
|
117
|
+
* than guessed ones, and the caller reports it.
|
|
118
|
+
*
|
|
119
|
+
* A props value svelte2tsx built from no exports is unrecognized here too:
|
|
120
|
+
* an empty object under a cast (`{} as Record<string, never>`, or in JS a
|
|
121
|
+
* JSDoc cast on `({})`). The caller asks only when the scan found exports,
|
|
122
|
+
* so an empty value means svelte2tsx didn't read the script the scan read,
|
|
123
|
+
* and the exports are reported, not dropped in silence.
|
|
124
|
+
*
|
|
125
|
+
* Whether the component is legacy at all isn't decided here. The caller asks
|
|
126
|
+
* only for a component svelte2tsx read as legacy (`classifyRenderMode` in
|
|
127
|
+
* `svelte.ts`); one it read as runes has an empty props type that would be
|
|
128
|
+
* unrecognized here, and its exported bindings are instance exports.
|
|
129
|
+
*
|
|
130
|
+
* The props are what the type declares, so an `export let` name an authored
|
|
131
|
+
* `$$Props` leaves out is no prop: a typed consumer can't pass it.
|
|
132
|
+
*
|
|
133
|
+
* Where svelte2tsx's props value departs from Svelte, the output follows it:
|
|
134
|
+
*
|
|
135
|
+
* - A binding exported both directly and through a renaming clause
|
|
136
|
+
* (`export let a; export {a as b}`) keeps only the renamed prop, without the
|
|
137
|
+
* binding's JSDoc. In TS it reads as optional.
|
|
138
|
+
* - An export clause written above its binding loses the binding's JSDoc too,
|
|
139
|
+
* and in TS reads as optional.
|
|
140
|
+
*
|
|
141
|
+
* @param propsValue - the `props` value of the object `$$render` returns, when the virtual has one
|
|
142
|
+
* @returns the anchor, or `undefined` when the value's shape isn't recognized or the checker throws
|
|
143
|
+
*/
|
|
144
|
+
export declare const resolveLegacyPropsAnchor: (propsValue: ts.Expression | undefined, checker: ts.TypeChecker) => LegacyPropsAnchor | undefined;
|
|
145
|
+
//# sourceMappingURL=svelte-legacy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svelte-legacy.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/svelte-legacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IAC1B,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,cAAc,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC7B,+CAA+C;IAC/C,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACzB;;;;;OAKG;IACH,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;AAMD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,iBAAiB,GAAI,cAAc,EAAE,CAAC,UAAU,KAAG,aA4E/D,CAAC;AAEF,iGAAiG;AACjG,MAAM,WAAW,iBAAiB;IACjC,sBAAsB;IACtB,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd;;;;OAIG;IACH,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd;;;;;;;;;;;;;;;OAeG;IACH,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;CAC3C;AA8BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,wBAAwB,GACpC,YAAY,EAAE,CAAC,UAAU,GAAG,SAAS,EACrC,SAAS,EAAE,CAAC,WAAW,KACrB,iBAAiB,GAAG,SAsBtB,CAAC"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy (runes-less) Svelte component support: props declared with
|
|
3
|
+
* `export let` instead of `$props()`.
|
|
4
|
+
*
|
|
5
|
+
* Still-legal syntax under Svelte 5, with no `$props()` declaration for prop
|
|
6
|
+
* extraction to anchor on. This module supplies the two things that replace
|
|
7
|
+
* it, and nothing else: a syntactic scan of the original instance script
|
|
8
|
+
* (`scanLegacyExports`) and the checker anchor in the svelte2tsx virtual
|
|
9
|
+
* (`resolveLegacyPropsAnchor`). `analyzeSvelteModule` hands the result to the
|
|
10
|
+
* same prop extraction the runes path uses, so filtering, types, callbacks,
|
|
11
|
+
* and JSDoc are shared.
|
|
12
|
+
*
|
|
13
|
+
* What a legacy component documents: its props, all of them bindable (any
|
|
14
|
+
* `export let` can be bound). Slots and events aren't modeled here; a default
|
|
15
|
+
* slot sets `acceptsChildren` in `svelte.ts`, which covers legacy components
|
|
16
|
+
* with no props too.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
import ts from 'typescript';
|
|
23
|
+
/**
|
|
24
|
+
* Scan an instance script for legacy props and accessors.
|
|
25
|
+
*
|
|
26
|
+
* Runes-less components declare props by exporting mutable bindings —
|
|
27
|
+
* `export let a` / `export var a` directly, or `let a; export {a as b}` for
|
|
28
|
+
* renames (the reserved-word workaround). `export const` / `export function` /
|
|
29
|
+
* `export class` are accessors, not props, and type-only exports aren't
|
|
30
|
+
* runtime bindings.
|
|
31
|
+
*
|
|
32
|
+
* The scan says what the script exports, not what mode the component is in:
|
|
33
|
+
* a runes component can export a mutable binding too, as an instance export.
|
|
34
|
+
* The caller scans only a component svelte2tsx didn't read as runes
|
|
35
|
+
* (`classifyRenderMode` in `svelte.ts`).
|
|
36
|
+
*
|
|
37
|
+
* The scan reads the *original* instance script because svelte2tsx rewrites
|
|
38
|
+
* the `export` modifier away inside `$$render`; a purely syntactic walk over
|
|
39
|
+
* top-level statements is all it needs. It's also where defaults come from:
|
|
40
|
+
* `defaultValue` is the initializer's source text as the author wrote it.
|
|
41
|
+
*
|
|
42
|
+
* @param scriptSource - parsed instance `<script>` content from the original source
|
|
43
|
+
* @returns props in source order (empty when the script exports no mutable binding) and accessor names
|
|
44
|
+
*/
|
|
45
|
+
export const scanLegacyExports = (scriptSource) => {
|
|
46
|
+
// top-level bindings by local name, for the export-clause forms
|
|
47
|
+
const bindings = new Map();
|
|
48
|
+
const props = [];
|
|
49
|
+
const accessors = new Set();
|
|
50
|
+
const toProp = (name, pos, initializer) => {
|
|
51
|
+
const prop = { name, pos, hasInitializer: initializer !== undefined };
|
|
52
|
+
if (initializer && !(ts.isIdentifier(initializer) && initializer.text === 'undefined')) {
|
|
53
|
+
prop.defaultValue = initializer.getText(scriptSource);
|
|
54
|
+
}
|
|
55
|
+
return prop;
|
|
56
|
+
};
|
|
57
|
+
for (const statement of scriptSource.statements) {
|
|
58
|
+
const exported = ts.canHaveModifiers(statement) &&
|
|
59
|
+
(ts.getModifiers(statement)?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false);
|
|
60
|
+
if (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) {
|
|
61
|
+
if (!statement.name)
|
|
62
|
+
continue;
|
|
63
|
+
bindings.set(statement.name.text, { kind: 'accessor' });
|
|
64
|
+
if (exported)
|
|
65
|
+
accessors.add(statement.name.text);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (!ts.isVariableStatement(statement))
|
|
69
|
+
continue;
|
|
70
|
+
// const/using/await-using bindings aren't reassignable — accessors, not props
|
|
71
|
+
const mutable = !(statement.declarationList.flags & (ts.NodeFlags.Const | ts.NodeFlags.Using));
|
|
72
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
73
|
+
// legacy props are simple identifiers; skip destructuring defensively
|
|
74
|
+
if (!ts.isIdentifier(declaration.name))
|
|
75
|
+
continue;
|
|
76
|
+
const name = declaration.name.text;
|
|
77
|
+
// a directly-exported binding can still be renamed by a clause, so
|
|
78
|
+
// record it either way — `export let a; export {a as b}` scans as
|
|
79
|
+
// `a` and `b`, and svelte2tsx's props value then keeps only `b`
|
|
80
|
+
bindings.set(name, mutable ? { kind: 'mutable', initializer: declaration.initializer } : { kind: 'accessor' });
|
|
81
|
+
if (!exported)
|
|
82
|
+
continue;
|
|
83
|
+
if (mutable) {
|
|
84
|
+
props.push(toProp(name, declaration.name.getStart(scriptSource), declaration.initializer));
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
accessors.add(name);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// separate pass — an export clause may precede the binding it re-exports
|
|
92
|
+
for (const statement of scriptSource.statements) {
|
|
93
|
+
if (!ts.isExportDeclaration(statement) ||
|
|
94
|
+
statement.isTypeOnly ||
|
|
95
|
+
statement.moduleSpecifier !== undefined ||
|
|
96
|
+
statement.exportClause === undefined ||
|
|
97
|
+
!ts.isNamedExports(statement.exportClause)) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
for (const spec of statement.exportClause.elements) {
|
|
101
|
+
if (spec.isTypeOnly)
|
|
102
|
+
continue;
|
|
103
|
+
const binding = bindings.get((spec.propertyName ?? spec.name).text);
|
|
104
|
+
if (!binding)
|
|
105
|
+
continue;
|
|
106
|
+
if (binding.kind === 'mutable') {
|
|
107
|
+
props.push(toProp(spec.name.text, spec.getStart(scriptSource), binding.initializer));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
accessors.add(spec.name.text);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
props.sort((a, b) => a.pos - b.pos);
|
|
115
|
+
return { props, accessors };
|
|
116
|
+
};
|
|
117
|
+
/** The reserved alias svelte2tsx reads a legacy component's authored props type from. */
|
|
118
|
+
const PROPS_ALIAS = '$$Props';
|
|
119
|
+
/** Whether a type node is a reference to the reserved `$$Props`. */
|
|
120
|
+
const isPropsAliasReference = (node) => ts.isTypeReferenceNode(node) &&
|
|
121
|
+
ts.isIdentifier(node.typeName) &&
|
|
122
|
+
node.typeName.text === PROPS_ALIAS;
|
|
123
|
+
/**
|
|
124
|
+
* Classify the written props type of a legacy component: `'generated'` for the
|
|
125
|
+
* literal svelte2tsx writes from the exports, `'authored'` for a `$$Props`
|
|
126
|
+
* (bare, or intersected with the literal that carries the accessors:
|
|
127
|
+
* `{fn?: typeof fn} & $$Props`), `undefined` for a type that is neither.
|
|
128
|
+
*/
|
|
129
|
+
const classifyWrittenPropsType = (node) => {
|
|
130
|
+
if (ts.isTypeLiteralNode(node))
|
|
131
|
+
return 'generated';
|
|
132
|
+
if (isPropsAliasReference(node))
|
|
133
|
+
return 'authored';
|
|
134
|
+
if (ts.isIntersectionTypeNode(node) &&
|
|
135
|
+
node.types.some(isPropsAliasReference) &&
|
|
136
|
+
node.types.every((member) => ts.isTypeLiteralNode(member) || isPropsAliasReference(member))) {
|
|
137
|
+
return 'authored';
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Resolve the props anchor of a legacy component from its svelte2tsx virtual.
|
|
143
|
+
*
|
|
144
|
+
* svelte2tsx ends `$$render` with `return {props: …, slots: …, …}`, and the
|
|
145
|
+
* `props` value is the anchor. The shapes recognized:
|
|
146
|
+
*
|
|
147
|
+
* - **Typed** — `<object> as <Type>`. The type is a literal svelte2tsx writes
|
|
148
|
+
* from the exports, carrying each prop's JSDoc and optionality
|
|
149
|
+
* (`{a?: typeof a, b: number}`: `'generated'`), or the author's reserved
|
|
150
|
+
* `$$Props`, bare or intersected with a literal of the accessors
|
|
151
|
+
* (`'authored'`).
|
|
152
|
+
* - **Untyped** — a bare object literal (`{a: a, b: b}`: `'untyped'`), what a
|
|
153
|
+
* JS component gets, and a TS one whose exports are all untyped and
|
|
154
|
+
* uninitialized, with each binding's JSDoc copied onto its property, so a
|
|
155
|
+
* `@type` there types the prop.
|
|
156
|
+
*
|
|
157
|
+
* Anything else is `undefined`: an unknown virtual yields no props rather
|
|
158
|
+
* than guessed ones, and the caller reports it.
|
|
159
|
+
*
|
|
160
|
+
* A props value svelte2tsx built from no exports is unrecognized here too:
|
|
161
|
+
* an empty object under a cast (`{} as Record<string, never>`, or in JS a
|
|
162
|
+
* JSDoc cast on `({})`). The caller asks only when the scan found exports,
|
|
163
|
+
* so an empty value means svelte2tsx didn't read the script the scan read,
|
|
164
|
+
* and the exports are reported, not dropped in silence.
|
|
165
|
+
*
|
|
166
|
+
* Whether the component is legacy at all isn't decided here. The caller asks
|
|
167
|
+
* only for a component svelte2tsx read as legacy (`classifyRenderMode` in
|
|
168
|
+
* `svelte.ts`); one it read as runes has an empty props type that would be
|
|
169
|
+
* unrecognized here, and its exported bindings are instance exports.
|
|
170
|
+
*
|
|
171
|
+
* The props are what the type declares, so an `export let` name an authored
|
|
172
|
+
* `$$Props` leaves out is no prop: a typed consumer can't pass it.
|
|
173
|
+
*
|
|
174
|
+
* Where svelte2tsx's props value departs from Svelte, the output follows it:
|
|
175
|
+
*
|
|
176
|
+
* - A binding exported both directly and through a renaming clause
|
|
177
|
+
* (`export let a; export {a as b}`) keeps only the renamed prop, without the
|
|
178
|
+
* binding's JSDoc. In TS it reads as optional.
|
|
179
|
+
* - An export clause written above its binding loses the binding's JSDoc too,
|
|
180
|
+
* and in TS reads as optional.
|
|
181
|
+
*
|
|
182
|
+
* @param propsValue - the `props` value of the object `$$render` returns, when the virtual has one
|
|
183
|
+
* @returns the anchor, or `undefined` when the value's shape isn't recognized or the checker throws
|
|
184
|
+
*/
|
|
185
|
+
export const resolveLegacyPropsAnchor = (propsValue, checker) => {
|
|
186
|
+
if (!propsValue)
|
|
187
|
+
return undefined;
|
|
188
|
+
let node;
|
|
189
|
+
let kind;
|
|
190
|
+
if (ts.isObjectLiteralExpression(propsValue)) {
|
|
191
|
+
node = propsValue;
|
|
192
|
+
kind = 'untyped';
|
|
193
|
+
}
|
|
194
|
+
else if (ts.isAsExpression(propsValue)) {
|
|
195
|
+
const written = classifyWrittenPropsType(propsValue.type);
|
|
196
|
+
if (!written)
|
|
197
|
+
return undefined;
|
|
198
|
+
node = propsValue.type;
|
|
199
|
+
kind = written;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
return { type: checker.getTypeAtLocation(node), node, kind };
|
|
206
|
+
}
|
|
207
|
+
catch (_) {
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
210
|
+
};
|