sveld 0.37.6 → 0.37.8
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 +122 -26
- package/lib/browser.d.ts +116 -7
- package/lib/browser.js +184 -156
- package/lib/{chunk-c2vdpk5t.js → chunk-0s0w60zm.js} +8 -8
- package/lib/chunk-1tbcz36r.js +1 -0
- package/lib/chunk-2vte7cyp.js +356 -0
- package/lib/chunk-dh2cbpn0.js +6 -0
- package/lib/chunk-p9hkwnfy.js +1 -0
- package/lib/chunk-sg7vsn8d.js +6 -0
- package/lib/cli-entry.js +1 -1
- package/lib/index.js +1 -1
- package/package.json +1 -1
- package/schema/component-api.schema.json +59 -3
- package/lib/chunk-9a8zmdck.js +0 -1
- package/lib/chunk-escdydzn.js +0 -6
- package/lib/chunk-jsp9b7b6.js +0 -331
- package/lib/chunk-v0hbw81y.js +0 -1
- package/lib/chunk-yqc5m8nm.js +0 -6
package/README.md
CHANGED
|
@@ -308,7 +308,7 @@ Parsed output is written to disk and reused when the source file has not changed
|
|
|
308
308
|
await sveld({ json: true });
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
-
By default this writes to `node_modules/.cache/sveld/parse-cache.json`. Pass a string to use a different location, e.g. `cache: ".cache/sveld.json"
|
|
311
|
+
By default this writes to `node_modules/.cache/sveld/parse-cache.json` in the project root, the nearest directory above the entry that has a `package.json`. Pass a string to use a different location, e.g. `cache: ".cache/sveld.json"` (relative paths resolve against the same project root), or `cache: false` to disable it. Also available as `--cache` / `--cache=<path>` / `--cache=false` on the CLI.
|
|
312
312
|
|
|
313
313
|
If a component [`@extendProps`](#extendprops) / [`@extends`](#extendprops) another file, it is re-parsed when that dependency changes, same as in [`watch`](#available-options) mode. Bumping the `sveld` or Svelte version clears the cache.
|
|
314
314
|
|
|
@@ -435,9 +435,10 @@ Every diagnostic carries a stable, namespaced `code` (`"sveld/<kind>"`) alongsid
|
|
|
435
435
|
| `sveld/syntax-skipped` | `error` | Rewrite the flagged syntax in a form sveld can model (see the diagnostic's `message` for what was skipped). |
|
|
436
436
|
| `sveld/rest-props-unresolved` | `warning` | Spread `$$restProps` onto a plain element (or `svelte:element`) instead of a component, or add an `@restProps` tag to type it manually. |
|
|
437
437
|
| `sveld/context-duplicate-key` | `warning` | Remove the duplicate `setContext` call, or give it a distinct key; only the first call's shape is used. |
|
|
438
|
-
| `sveld/context-key-unresolved` | `warning` | Use a string literal, a `const`-bound string, `Symbol()`, or a string `export const` imported from a relative module as the `setContext` key; otherwise the context is left out of every output. |
|
|
438
|
+
| `sveld/context-key-unresolved` | `warning` | Use a string literal, a `const`-bound string, `Symbol()`, or a string or `Symbol()` `export const` imported from a relative module as the `setContext` key; otherwise the context is left out of every output. |
|
|
439
|
+
| `sveld/context-value-unresolved` | `warning` | Pass an object literal or a typed variable as the `setContext` value (e.g. `const store = writable(0);` with a `@type` annotation, or `{ store }`); a call or other expression has no shape sveld can describe, so the context is left out of every output. |
|
|
439
440
|
| `sveld/spread-unresolved` | `warning` | Spread a local object literal or a variable with a resolvable type instead; otherwise the spread widens the generated type to `Record<string, any>`. |
|
|
440
|
-
| `sveld/export-unresolved` | `warning` | Export a local declaration directly. Instance-script exports are props, so move a re-export (`export { x } from "..."`, or `export { x }` of an import) into `<script context="module">`, where sveld writes it to the `.d.ts` as-is. |
|
|
441
|
+
| `sveld/export-unresolved` | `warning` | Export a local declaration directly. Instance-script exports are props, so move a re-export (`export { x } from "..."`, or `export { x }` of an import) into `<script context="module">`, where sveld writes it to the `.d.ts` as-is. A class can't be a prop either, so export it from `<script context="module">`, where sveld documents it. |
|
|
441
442
|
| `sveld/module-export-conflict` | `warning` | Rename the module-script export. `default` is always skipped (it collides with the component itself); a name matching the generated `<Name>Props`/`<Name>Exports` type breaks the `.d.ts` if the export carries a type. |
|
|
442
443
|
| `sveld/extend-props-target-missing` | `error` | Point `@extends`/`@extendProps` at a file that exists, and (for a bundled `.svelte` target) name its generated `<Name>Props` interface exactly. |
|
|
443
444
|
| `sveld/extend-props-duplicate` | `warning` | Remove the extra `@extends`/`@extendProps` tag; only the last one is used. |
|
|
@@ -450,10 +451,12 @@ Every diagnostic carries a stable, namespaced `code` (`"sveld/<kind>"`) alongsid
|
|
|
450
451
|
| `sveld/jsdoc-tag-dropped` | `warning` | Move the tag next to a `@slot`/`@snippet`/`@event`/`@typedef`/`@callback` tag in the same comment block so it has something to attach to. |
|
|
451
452
|
| `sveld/internal-typedef-referenced` | `error` | Remove `@internal`/`@ignore` from the referenced typedef, or stop referencing it from public type text (inline the shape, or make the referencing item `@internal` too). |
|
|
452
453
|
| `sveld/types-inline-unresolved` | `warning` | The import is kept as-is. Point it at a relative `.ts` file that exports a `type`/`interface`, or rename the colliding type. |
|
|
454
|
+
| `sveld/cross-file-unresolved` | `warning` | Only recorded by [`finalizeWithoutCrossFileResolution`](#browser) on a standalone parse: an imported `setContext` key, prop default, or dispatch helper needs the imported file read. Run `sveld` through the CLI or `generateBundle` to resolve it, or inline the value in the component. |
|
|
455
|
+
| `sveld/export-ambiguous` | `warning` | Two `export *` statements in the entry barrel bring in the same name from different modules, so (as in ES modules) the barrel doesn't export it and the [entry exports](#documenting-entry-exports) leave it out. Export it explicitly from the barrel (`export { format } from "./a.js"`) to pick one. Reported with the barrel file (e.g. `./index.js`) as its `component`, and only when `documentExports` is on. |
|
|
453
456
|
|
|
454
457
|
#### Severity and `--strict=errors`
|
|
455
458
|
|
|
456
|
-
Each diagnostic's `severity` is `"error"` (`example-compile-error`, `example-syntax-error`, `syntax-skipped`, `extend-props-target-missing`, `internal-typedef-referenced` — sveld emitted broken or unmodeled output) or `"warning"` (`prop-unknown-type`, `context-any-type`, `slot-missing-type`, `event-no-source`, `dispatch-escapes`, `rest-props-unresolved`, `context-duplicate-key`, `context-key-unresolved`, `spread-unresolved`, `export-unresolved`, `module-export-conflict`, `extend-props-duplicate`, `extend-props-override`, `jsdoc-unknown-tag`, `typedef-duplicate`, `property-duplicate`, `generics-conflict`, `event-description-ambiguous`, `jsdoc-tag-dropped`, `types-inline-unresolved` — a type fell back to `any
|
|
459
|
+
Each diagnostic's `severity` is `"error"` (`example-compile-error`, `example-syntax-error`, `syntax-skipped`, `extend-props-target-missing`, `internal-typedef-referenced` — sveld emitted broken or unmodeled output) or `"warning"` (`prop-unknown-type`, `context-any-type`, `slot-missing-type`, `event-no-source`, `dispatch-escapes`, `rest-props-unresolved`, `context-duplicate-key`, `context-key-unresolved`, `context-value-unresolved`, `spread-unresolved`, `export-unresolved`, `module-export-conflict`, `extend-props-duplicate`, `extend-props-override`, `jsdoc-unknown-tag`, `typedef-duplicate`, `property-duplicate`, `generics-conflict`, `event-description-ambiguous`, `jsdoc-tag-dropped`, `types-inline-unresolved`, `cross-file-unresolved`, `export-ambiguous` — a type fell back to `any`, or something was left out of the docs). Plain `strict: true` / `--strict` fails on both, unchanged from before. Pass `strict: "errors"` (or `--strict=errors`) to fail CI only on `error`-severity diagnostics, letting `any`-fallback warnings through:
|
|
457
460
|
|
|
458
461
|
```sh
|
|
459
462
|
npx sveld --json --strict=errors
|
|
@@ -808,6 +811,7 @@ It covers parsing one component's source and rendering that result to any output
|
|
|
808
811
|
import {
|
|
809
812
|
asNormalizedPath,
|
|
810
813
|
ComponentParser,
|
|
814
|
+
finalizeWithoutCrossFileResolution,
|
|
811
815
|
buildComponentApiDocument,
|
|
812
816
|
writeMarkdownCore,
|
|
813
817
|
writeTsDefinition,
|
|
@@ -817,7 +821,10 @@ import {
|
|
|
817
821
|
const parser = new ComponentParser();
|
|
818
822
|
const moduleName = "Button";
|
|
819
823
|
const filePath = "Button.svelte";
|
|
820
|
-
const parsed =
|
|
824
|
+
const parsed = finalizeWithoutCrossFileResolution(
|
|
825
|
+
parser.parseSvelteComponent(source, { moduleName, filePath }),
|
|
826
|
+
{ filePath },
|
|
827
|
+
);
|
|
821
828
|
|
|
822
829
|
// `parseSvelteComponent` returns component metadata only; add `moduleName`
|
|
823
830
|
// and `filePath` yourself to match the `ComponentDocApi` shape the writers expect.
|
|
@@ -839,6 +846,8 @@ const cem = buildCustomElementsManifest(components, {
|
|
|
839
846
|
});
|
|
840
847
|
```
|
|
841
848
|
|
|
849
|
+
A standalone parse can't read the files a component imports from, so some output the CLI and `generateBundle` produce is missing: a context whose `setContext` key is imported, the value of a prop default that names an imported `const`, the return type of a default that calls an imported function, and events dispatched by an imported helper (`wire(dispatch)`). `parseSvelteComponent` leaves these pending for the cross-file pass, which never runs here. Pass the result through `finalizeWithoutCrossFileResolution(parsed, { filePath })` to record a `sveld/cross-file-unresolved` warning for each one, naming the import (e.g. `` setContext key `keys.THEME` is imported from "./keys.js" ``), and to release the `sveld/event-no-source` warnings held back while a helper's events were unknown. It returns a new component and leaves the input unchanged.
|
|
850
|
+
|
|
842
851
|
`ComponentParser` is stateful but reusable across parses — call `parseSvelteComponent` again on the same instance for the next component instead of constructing a new one each time.
|
|
843
852
|
|
|
844
853
|
See [`playground/`](playground) in this repo for a working example: it parses Svelte source typed into an editor and renders JSON, Markdown, TypeScript, and Custom Elements Manifest tabs, all client-side. Deployed at [sveld.onrender.com](https://sveld.onrender.com).
|
|
@@ -1057,7 +1066,23 @@ typesOptions: {
|
|
|
1057
1066
|
|
|
1058
1067
|
Any key left out defaults to `true`.
|
|
1059
1068
|
|
|
1060
|
-
`<script context="module">` exports (`export declare const` / `export declare function`) are real runtime exports and are always emitted as exports, regardless of `exportTypes`.
|
|
1069
|
+
`<script context="module">` exports (`export declare const` / `export declare function` / `export declare class`) are real runtime exports and are always emitted as exports, regardless of `exportTypes`. So are the types a module script exports (`export interface Item`, `export type Mode`, `export type { Local }`), since they're part of the component module's API.
|
|
1070
|
+
|
|
1071
|
+
A module-script class (`export class Store {}`, or `class Store {}` then `export { Store }`) is emitted with its public surface: the constructor, methods (with their overload signatures, if any), fields, constructor parameter properties, getter/setter pairs, and `static`/`readonly`/`abstract`/optional modifiers. Types come from TypeScript annotations, then JSDoc (`@param`, `@returns`, `@type`, and `@template` on the class or a method), and are `any` otherwise. In a JS script, a `this.x = ...` assignment in the constructor declares property `x`. Private (`#x`, `private`), `protected`, computed-key, and `@internal` members are left out. `extends` and `implements` clauses are kept, and an imported base class or interface gets an `import type`. A class that extends something the `.d.ts` can't reference (a non-exported local class, or an expression like `mixin(Base)`) is declared without `extends`, with an `export-unresolved` warning, since its inherited members would be missing.
|
|
1072
|
+
|
|
1073
|
+
```ts
|
|
1074
|
+
export declare class Store<T> {
|
|
1075
|
+
constructor(initial: T);
|
|
1076
|
+
|
|
1077
|
+
value: T;
|
|
1078
|
+
|
|
1079
|
+
static create<U>(value: U): Store<U>;
|
|
1080
|
+
|
|
1081
|
+
subscribe(run: (value: T) => void): () => void;
|
|
1082
|
+
}
|
|
1083
|
+
```
|
|
1084
|
+
|
|
1085
|
+
In JSON the class is a `moduleExports` entry with `kind: "class"`, `type: "typeof Store"`, and its members under `members`; the Markdown and `llms-full.txt` output list them in a members table after the Module exports table.
|
|
1061
1086
|
|
|
1062
1087
|
One exception: when a bundled component uses [`@extendProps`](#extendprops) to extend another bundled component, sveld emits `import type { ButtonProps } from "./Button.svelte"` in the extending component's `.d.ts`. If `Button`'s props type stopped being exported, that import would break — so sveld always keeps a component's props type exported when another component in the same run extends it, even under `exportTypes: false`.
|
|
1063
1088
|
|
|
@@ -1086,7 +1111,7 @@ sveld({
|
|
|
1086
1111
|
+ export default class Button extends SvelteComponentTyped<IButtonProps, ...> {}
|
|
1087
1112
|
```
|
|
1088
1113
|
|
|
1089
|
-
Each template must contain `{name}` and produce a valid identifier once substituted; sveld throws otherwise. Any key left out of the object keeps its default (`"{name}Props"` / `"{name}Exports"`).
|
|
1114
|
+
Each template must contain `{name}` and produce a valid identifier once substituted, and the two must produce different names that aren't the component's own (`{name}`) or its generic-component interface's (`{name}Component`); sveld throws otherwise. Any key left out of the object keeps its default (`"{name}Props"` / `"{name}Exports"`).
|
|
1090
1115
|
|
|
1091
1116
|
If a bundled component then [`@extendProps`](#extendprops)/`@extends`-es another one, the tag must name the *templated* interface — `@extendProps {"./Button.svelte"} IButtonProps`, not `ButtonProps` — or sveld reports [`extend-props-target-missing`](#type-inference-diagnostics).
|
|
1092
1117
|
|
|
@@ -1147,6 +1172,8 @@ sveld({
|
|
|
1147
1172
|
});
|
|
1148
1173
|
```
|
|
1149
1174
|
|
|
1175
|
+
The same levels apply to the comments on slots, events, their snippet and `on<event>` callback props, `@restProps`, typedefs, contexts, module exports, and the component itself. A `@property` description inside a `@typedef` is part of the type's own text, so it stays at every level.
|
|
1176
|
+
|
|
1150
1177
|
`@internal`/`@ignore` members are removed from every output regardless of this option — see [`@ignore` / `@internal`](#ignore--internal). `comments` only controls how much JSDoc survives for members that *do* get emitted.
|
|
1151
1178
|
|
|
1152
1179
|
Also available as `--types-comments=<all|descriptions|none>` on the CLI.
|
|
@@ -1313,8 +1340,10 @@ It leaves alone:
|
|
|
1313
1340
|
- `enum`, `class`, and `function` exports, which can't be safely copied as a `type`/`interface`.
|
|
1314
1341
|
|
|
1315
1342
|
An import that can't be safely inlined (a missing file, a missing export, one of the unsupported
|
|
1316
|
-
export kinds above, or a name collision with something the component already declares
|
|
1317
|
-
typedef, a context type, a local `type`/`interface`,
|
|
1343
|
+
export kinds above, or a name collision with something the component's `.d.ts` already declares
|
|
1344
|
+
or imports — a typedef, a context type, a local `type`/`interface`, its `Props`/`Exports` type
|
|
1345
|
+
name, the component's own name, `$Props`/`$RestProps`, the svelte types the `.d.ts` imports, or a
|
|
1346
|
+
name bound by an import that stays) is left
|
|
1318
1347
|
as an import, with a [`types-inline-unresolved`](#diagnostic-codes) warning explaining why. If an
|
|
1319
1348
|
`import type { A, B } from "./x"` statement imports several names and even one of them can't be
|
|
1320
1349
|
inlined, the whole statement is kept and nothing from it is inlined — simpler, and always correct.
|
|
@@ -1461,7 +1490,7 @@ Nested barrels are followed too: `export { X } from "./dir"`, where `./dir/index
|
|
|
1461
1490
|
|
|
1462
1491
|
JSON adds `exports` and `totalExports`. Markdown adds an "Exports" section. Each item has `name`, `kind`, type text, optional JSDoc `description`, `source`, and — same as props — optional `@deprecated` and pass-through `tags`. A deprecated export's name is struck through in the Markdown table, same as a deprecated prop. See [`@deprecated`](#deprecated).
|
|
1463
1492
|
|
|
1464
|
-
An overloaded function (repeated `export function f(...)` signatures, or an import re-exported through a barrel) always documents the implementation signature, i.e. the last declaration. An `enum` export's `type` is the literal union of its members' values (`"A" | "B"` for a string enum, `0 | 1` for a numeric one), falling back to the bare enum name when a member's value can't be determined (e.g. a computed initializer). When two
|
|
1493
|
+
An overloaded function (repeated `export function f(...)` signatures, or an import re-exported through a barrel) always documents the implementation signature, i.e. the last declaration. An `enum` export's `type` is the literal union of its members' values (`"A" | "B"` for a string enum, `0 | 1` for a numeric one), falling back to the bare enum name when a member's value can't be determined (e.g. a computed initializer). A name the barrel exports itself (`export const X` or `export { X } from "./x"`) wins over the same name from an `export *`, as it does at runtime. When two `export *` statements bring in the same name from different modules (`export * from "./a"; export * from "./b"`), the name is ambiguous: the barrel doesn't export it at all, so `sveld` leaves it out and reports a [`sveld/export-ambiguous`](#diagnostic-codes) diagnostic naming both modules. Export it explicitly from the barrel (`export { format } from "./a"`) to pick one; that export wins silently. A namespace re-export (`export * as utils from "./utils"`, or an `import * as utils` the barrel re-exports) documents the one `const` export `utils`, with the wrapped module as its `source` and `typeof import("./utils.ts")` as its `type` (the module's path relative to the entry file, so the Markdown Type column names it); the names inside `./utils` aren't exports of the barrel, so they aren't listed. A re-exported default (`export { default as track } from "./track"`) is documented when that default export is a function, a class, or a named binding, with the JSDoc above `export default` as a named export would have; any other default (an object literal, say) is left out.
|
|
1465
1494
|
|
|
1466
1495
|
## JSON Output
|
|
1467
1496
|
|
|
@@ -1538,7 +1567,8 @@ interface ComponentDocApi {
|
|
|
1538
1567
|
interface ComponentProp {
|
|
1539
1568
|
name: string;
|
|
1540
1569
|
localName?: string;
|
|
1541
|
-
|
|
1570
|
+
// "re-export" and "class" are module exports only.
|
|
1571
|
+
kind: "let" | "const" | "function" | "re-export" | "class";
|
|
1542
1572
|
constant: boolean;
|
|
1543
1573
|
type?: string;
|
|
1544
1574
|
typeSource?: "typescript" | "jsdoc" | "default" | "inferred" | "unknown";
|
|
@@ -1557,6 +1587,23 @@ interface ComponentProp {
|
|
|
1557
1587
|
reactive: boolean;
|
|
1558
1588
|
binding?: "readonly" | "writable";
|
|
1559
1589
|
bindable?: true;
|
|
1590
|
+
// Set when `kind` is "class".
|
|
1591
|
+
members?: Array<{
|
|
1592
|
+
kind: "constructor" | "method" | "property";
|
|
1593
|
+
name: string;
|
|
1594
|
+
type?: string;
|
|
1595
|
+
params?: Array<{ name: string; type: string; description?: string; optional?: boolean }>;
|
|
1596
|
+
returnType?: string;
|
|
1597
|
+
typeParameters?: string;
|
|
1598
|
+
static?: true;
|
|
1599
|
+
readonly?: true;
|
|
1600
|
+
optional?: true;
|
|
1601
|
+
abstract?: true;
|
|
1602
|
+
description?: string;
|
|
1603
|
+
deprecated?: string | true;
|
|
1604
|
+
tags?: Array<{ name: string; body: string }>;
|
|
1605
|
+
}>;
|
|
1606
|
+
abstract?: true;
|
|
1560
1607
|
source?: SourceRange;
|
|
1561
1608
|
}
|
|
1562
1609
|
|
|
@@ -1689,7 +1736,7 @@ With that in place:
|
|
|
1689
1736
|
|
|
1690
1737
|
## llms.txt Output
|
|
1691
1738
|
|
|
1692
|
-
Set `llms: true` to emit an [`llms.txt`](https://llmstxt.org) / `llms-full.txt` pair: `llms.txt` is an index of every exported component (one link plus a one-line summary each), and `llms-full.txt` is the flattened full reference (every component's Props, Bindings, Events, Slots/Snippets, Typedefs, and Module exports, as terse Markdown tables). Props and Events Description columns include `@since`/`@example` tags, same as `COMPONENT_INDEX.md`.
|
|
1739
|
+
Set `llms: true` to emit an [`llms.txt`](https://llmstxt.org) / `llms-full.txt` pair: `llms.txt` is an index of every exported component (one link plus a one-line summary each), and `llms-full.txt` is the flattened full reference (every component's Props, Bindings, Events, Slots/Snippets, Typedefs, and Module exports, as terse Markdown tables). Props and Events Description columns include `@since`/`@example` tags, same as `COMPONENT_INDEX.md`. Fenced code in a Description cell is printed after its table as a regular fenced block, with `(code below)` left in the cell.
|
|
1693
1740
|
|
|
1694
1741
|
```diff
|
|
1695
1742
|
sveld({
|
|
@@ -1879,6 +1926,8 @@ listing one exported component name per line.
|
|
|
1879
1926
|
|
|
1880
1927
|
## API Reference
|
|
1881
1928
|
|
|
1929
|
+
A JSDoc block documents the declaration below it. Blank lines and ordinary comments may sit between the two, such as a `// biome-ignore ...` or `/* istanbul ignore next */` line.
|
|
1930
|
+
|
|
1882
1931
|
### `reactive`
|
|
1883
1932
|
|
|
1884
1933
|
The `reactive` field in generated JSON is a heuristic. It does not fully answer whether a parent can use `bind:prop` in Svelte.
|
|
@@ -2128,6 +2177,24 @@ By default, `sveld` infers the `@default` value from the prop's initializer and
|
|
|
2128
2177
|
open?: boolean;
|
|
2129
2178
|
```
|
|
2130
2179
|
|
|
2180
|
+
A fallback or conditional initializer (`??`, `||`, `&&`, `?:`) shows its source text, folded onto one line, in the `.d.ts`, the JSON `value`, and the Markdown "Default value" column:
|
|
2181
|
+
|
|
2182
|
+
```svelte
|
|
2183
|
+
<script>
|
|
2184
|
+
export let theme = undefined;
|
|
2185
|
+
const defaultSize = theme === "dense" ? "sm" : "md";
|
|
2186
|
+
|
|
2187
|
+
export let size = defaultSize ?? "md";
|
|
2188
|
+
</script>
|
|
2189
|
+
```
|
|
2190
|
+
|
|
2191
|
+
```ts
|
|
2192
|
+
/**
|
|
2193
|
+
* @default defaultSize ?? "md"
|
|
2194
|
+
*/
|
|
2195
|
+
size?: string;
|
|
2196
|
+
```
|
|
2197
|
+
|
|
2131
2198
|
Use `@default` to document the default value. When you supply `@default`, `sveld` uses it instead of the inferred value and avoids duplicate `@default` tags in the output.
|
|
2132
2199
|
|
|
2133
2200
|
Use `@default` when the initializer references a variable or expression that means nothing to consumers:
|
|
@@ -2191,7 +2258,7 @@ count?: number;
|
|
|
2191
2258
|
|
|
2192
2259
|
Resolution follows up to 5 levels of indirection. Beyond that, the last resolved identifier name is used as the default value.
|
|
2193
2260
|
|
|
2194
|
-
A named import resolves when the imported module (followed through re-exports) declares it as an `export const` with a string, number, boolean, or static template literal:
|
|
2261
|
+
A named import, or a member of a namespace import (`import * as timing from "./timing.js"` with `timing.TOOLTIP_LEAVE_DELAY_MS`, also through a namespace the module re-exports with `export * as`), resolves when the imported module (followed through re-exports) declares it as an `export const` with a string, number, boolean, or static template literal:
|
|
2195
2262
|
|
|
2196
2263
|
```svelte
|
|
2197
2264
|
<script>
|
|
@@ -2691,7 +2758,7 @@ function render(value: unknown, props: ComponentProps) {
|
|
|
2691
2758
|
|
|
2692
2759
|
Both forms support the same modifiers as typedef properties elsewhere in this doc: optional properties (`[name]`), default values (`[name=value]`), and nested/discriminated-union shapes. See the linked sections above for full signatures and worked examples with generated output.
|
|
2693
2760
|
|
|
2694
|
-
A description can wrap onto continuation lines, which run until the next tag. Indent them past the `*` gutter to keep them attached to the tag unambiguously; an unindented line right above an `@event`/`@typedef`/`@slot` with no description of its own is read as that tag's description instead, and an unindented line after an event's last `@property` describes the event.
|
|
2761
|
+
A description can wrap onto continuation lines, which run until the next tag. Indent them past the `*` gutter to keep them attached to the tag unambiguously; an unindented line right above an `@event`/`@typedef`/`@slot` with no description of its own is read as that tag's description instead, and an unindented line after an event's last `@property` describes the event. A blank line between indented paragraphs doesn't end the description; it's kept as a paragraph break. Lines inside a ```` ``` ```` code fence keep their indentation relative to the fence.
|
|
2695
2762
|
|
|
2696
2763
|
```js
|
|
2697
2764
|
/**
|
|
@@ -3013,7 +3080,7 @@ In Svelte 5 runes components, callback props like `onclick` are props, not event
|
|
|
3013
3080
|
|
|
3014
3081
|
Use `null` as the value if no event detail is provided.
|
|
3015
3082
|
|
|
3016
|
-
`sveld` infers events from `dispatch("name")` calls. When the dispatcher is passed to a function imported from a local module, as `helper(dispatch)` or `helper({ dispatch })
|
|
3083
|
+
`sveld` infers events from `dispatch("name")` calls. When the dispatcher is passed to a function imported from a local module, as `helper(dispatch)` or `helper({ dispatch })` (a named or default import) or `helpers.open(dispatch)` (a namespace import, or a namespace another module re-exports with `export * as helpers from "./helpers.js"`), it reads that function too and picks up the events it dispatches:
|
|
3017
3084
|
|
|
3018
3085
|
```js
|
|
3019
3086
|
// dispatch-open-close.js
|
|
@@ -3033,7 +3100,7 @@ export function createOpenCloseDispatcher(dispatch) {
|
|
|
3033
3100
|
</script>
|
|
3034
3101
|
```
|
|
3035
3102
|
|
|
3036
|
-
This happens when sveld builds the whole library (CLI, `sveld()`, or the Vite plugin), not when parsing a single component on its own. Each event name there must be a string literal, or a conditional between them. The detail is typed from a literal argument and is `
|
|
3103
|
+
This happens when sveld builds the whole library (CLI, `sveld()`, or the Vite plugin), not when parsing a single component on its own. Each event name there must be a string literal, or a conditional between them. The detail is typed from a literal argument, and an object or array literal is typed member by member as for a dispatch in the component (`{ id: "a" }` is `{ id: string; }`); a member or argument the helper computes, including one of its own variables, is `any`, so add an `@event` tag to type it more precisely. When sveld can't follow the dispatcher (a package import, a local function, a computed event name, or a helper that passes the dispatcher on), it reports `sveld/dispatch-escapes`, and you document those events with `@event` tags.
|
|
3037
3104
|
|
|
3038
3105
|
**Signature:**
|
|
3039
3106
|
|
|
@@ -3124,6 +3191,9 @@ Without an `@event` tag or a typed dispatcher, `sveld` infers a dispatched event
|
|
|
3124
3191
|
|
|
3125
3192
|
- A scalar literal argument narrows to its literal type: `dispatch("count", 5)` types the detail as `5`, not `number`. Use `@event` or a typed dispatcher (below) to widen it.
|
|
3126
3193
|
- An object or array literal argument infers a structural type per field/element: `dispatch("save", { id })` types the detail as `{ id: string }` (resolving the `id` variable's own type), and `dispatch("items", [1, 2])` types it as `number[]`. Fields or elements sveld can't resolve fall back to `any` individually, not for the whole detail.
|
|
3194
|
+
- A variable, as the whole detail (`dispatch("count", count)`) or as a field or element, takes its JSDoc `@type` or TS annotation. Without one, it's typed from its initializer the way a prop default is: `let count = 0` and `let count = $state(0)` are `number`, `$state<Item[]>([])` is `Item[]`, and `$derived(total * 2)` is `number`. A literal widens to its primitive, since a `let` can be reassigned. A variable initialized from a call (`let roll = Math.random()`), a destructured binding without an annotation, or a function parameter or nested variable is `any`.
|
|
3195
|
+
- `$host().dispatchEvent(new CustomEvent("name", { detail }))` in a custom element types `detail` the same way.
|
|
3196
|
+
- An empty object literal (`dispatch("reset", {})`) types the detail as `Record<string, never>`. A spread or computed key (`{ ...state }`, `{ [key]: 1 }`) adds fields sveld can't name, so the detail becomes `Record<string, any>`, or keeps the named fields next to a `[key: string]: any` index signature (`{ id: number; [key: string]: any }`).
|
|
3127
3197
|
|
|
3128
3198
|
#### Typed dispatchers
|
|
3129
3199
|
|
|
@@ -3585,7 +3655,7 @@ A width prop.<br />@see https://example.com/width-docs
|
|
|
3585
3655
|
|
|
3586
3656
|
`{@link target}` (optionally `{@link target|display text}`) is an inline JSDoc tag used inside prose, not a block-level tag like the others on this page. `sveld`'s comment parser only treats a *line* as starting a new tag when it begins with `@` — `{@link ...}` always starts with `{`, so it's never intercepted. It is always literal text.
|
|
3587
3657
|
|
|
3588
|
-
**Valid contexts:** anywhere free-form description text is read — prop and module export descriptions, event descriptions, slot descriptions, entry export descriptions, typedef descriptions, `@component` HTML comments, and `@example` bodies. `sveld` never resolves or validates the target. JSON `description` and `.d.ts` JSDoc always keep the tag verbatim. **Markdown is the one exception:** in a prop, event, slot, or entry export's Description table cell, `{@link target|text}` / `{@link target}` is rewritten to a Markdown link, `[text](target)` / `[target](target)
|
|
3658
|
+
**Valid contexts:** anywhere free-form description text is read — prop and module export descriptions, event descriptions, slot descriptions, entry export descriptions, typedef descriptions, `@component` HTML comments, and `@example` bodies. `sveld` never resolves or validates the target. JSON `description` and `.d.ts` JSDoc always keep the tag verbatim. **Markdown is the one exception:** in a prop, event, slot, or entry export's Description table cell, `{@link target|text}` / `{@link target}` is rewritten to a Markdown link, `[text](target)` / `[target](target)`, except inside a fenced code block. Typedef descriptions (rendered as a `.d.ts`-style code block) and `@component` comments keep the tag literal in Markdown too, since neither goes through the table-cell renderer.
|
|
3589
3659
|
|
|
3590
3660
|
**Example:**
|
|
3591
3661
|
|
|
@@ -3650,15 +3720,23 @@ Output (`.d.ts`):
|
|
|
3650
3720
|
/**
|
|
3651
3721
|
* Formats a value.
|
|
3652
3722
|
* @example
|
|
3653
|
-
*
|
|
3654
|
-
*
|
|
3655
|
-
*
|
|
3723
|
+
* ```js
|
|
3724
|
+
* formatValue("ok");
|
|
3725
|
+
* ```
|
|
3656
3726
|
*/
|
|
3657
3727
|
formatValue: (value: string) => string;
|
|
3658
3728
|
```
|
|
3659
3729
|
|
|
3660
3730
|
`@param`/`@returns` are consumed into the function's type signature rather than kept as separate JSDoc lines.
|
|
3661
3731
|
|
|
3732
|
+
In Markdown table cells, a fenced block (in an `@example` body or anywhere in a description) renders as `<pre><code>` with one `<br />` per line, since a table row can't span lines. `<pre>` keeps the indentation, and GitHub renders it as a monospaced block inside the cell. The example above shows up in the Description column as:
|
|
3733
|
+
|
|
3734
|
+
```
|
|
3735
|
+
Formats a value.<br />@example <pre><code>formatValue("ok");</code></pre>
|
|
3736
|
+
```
|
|
3737
|
+
|
|
3738
|
+
`llms-full.txt` instead puts `(code below)` in the cell and prints the code after the table as a regular multi-line fenced block, under a ``Code for `formatValue`:`` line.
|
|
3739
|
+
|
|
3662
3740
|
Output (Markdown props table Description column, newlines rendered as `<br />`):
|
|
3663
3741
|
|
|
3664
3742
|
````
|
|
@@ -3689,12 +3767,15 @@ The key becomes the `{PascalCase}Context` type name. `sveld` can resolve:
|
|
|
3689
3767
|
| `const`-bound string | `const KEY = "simple-modal";`<br>`setContext(KEY, …)` | `SimpleModalContext` |
|
|
3690
3768
|
| `Symbol()` / `Symbol.for()` | `setContext(Symbol("tabs"), …)` | `TabsContext` |
|
|
3691
3769
|
| Imported `export const` string | `import { KEY } from "./keys.js";`<br>`setContext(KEY, …)` | `SimpleModalContext` |
|
|
3770
|
+
| Namespace-imported `export const` string | `import * as keys from "./keys.js";`<br>`setContext(keys.KEY, …)` | `SimpleModalContext` |
|
|
3771
|
+
|
|
3772
|
+
Characters that can't appear in a TypeScript identifier are dropped and start a new PascalCase word, and a name starting with a digit gets a leading `_`: `"@scope/ctx"` becomes `ScopeCtxContext` and `"123"` becomes `_123Context`.
|
|
3692
3773
|
|
|
3693
3774
|
`const` identifiers are followed up to 5 levels deep (`const A = "x"; const B = A;`). Only `const` bindings count. `let`, `var`, and props are skipped because they can change at runtime.
|
|
3694
3775
|
|
|
3695
3776
|
Symbol keys take their name from the description: `Symbol("tabs")` and `Symbol.for("tabs")` both become `TabsContext`. For `const ModalKey = Symbol()` with no description, the binding name wins: `ModalKeyContext`.
|
|
3696
3777
|
|
|
3697
|
-
An imported key is read from its module, following re-exports, when that module is a relative `.js`/`.ts` file declaring it as `export const KEY = "simple-modal"` (or a static template literal). This works when sveld builds a whole library (CLI, `sveld()`, or the Vite plugin), not when parsing a single component on its own.
|
|
3778
|
+
An imported key (named, or read off a namespace import, including one another module re-exports with `export * as keys from "./keys.js"`) is read from its module, following re-exports, when that module is a relative `.js`/`.ts` file declaring it as `export const KEY = "simple-modal"` (or a static template literal). This works when sveld builds a whole library (CLI, `sveld()`, or the Vite plugin), not when parsing a single component on its own.
|
|
3698
3779
|
|
|
3699
3780
|
Anything else (dynamic identifiers, `let` exports, template interpolation, other function calls) records a `sveld/context-key-unresolved` diagnostic. No context type is generated.
|
|
3700
3781
|
|
|
@@ -3840,14 +3921,15 @@ There are several ways to type contexts:
|
|
|
3840
3921
|
</script>
|
|
3841
3922
|
```
|
|
3842
3923
|
|
|
3843
|
-
**Option 3:
|
|
3924
|
+
**Option 3: Passing a typed variable as the whole value**
|
|
3844
3925
|
|
|
3845
3926
|
```svelte
|
|
3846
3927
|
<script>
|
|
3847
3928
|
import { setContext } from 'svelte';
|
|
3848
3929
|
|
|
3849
3930
|
/**
|
|
3850
|
-
*
|
|
3931
|
+
* Modal controls
|
|
3932
|
+
* @type {import("./types").ModalAPI}
|
|
3851
3933
|
*/
|
|
3852
3934
|
const modalAPI = {
|
|
3853
3935
|
open: () => {},
|
|
@@ -3858,6 +3940,17 @@ There are several ways to type contexts:
|
|
|
3858
3940
|
</script>
|
|
3859
3941
|
```
|
|
3860
3942
|
|
|
3943
|
+
`getContext('modal')` returns `modalAPI` itself, so the context type is the variable's type, and the variable's description documents it:
|
|
3944
|
+
|
|
3945
|
+
```ts
|
|
3946
|
+
/**
|
|
3947
|
+
* Modal controls
|
|
3948
|
+
*/
|
|
3949
|
+
export type ModalContext = import("./types").ModalAPI;
|
|
3950
|
+
```
|
|
3951
|
+
|
|
3952
|
+
When the variable's type is an object type literal (`@type {{ open: () => void }}` or `const api: { open: () => void } = ...`), its members become the context type's members instead. An untyped `const` holding an object literal is described from that literal, as with `{ ...api }`. Any other untyped variable is typed from its initializer the way a prop default is (`let count = $state(0)` or `let count = 0` gives `number`, `$state<Item[]>([])` gives `Item[]`), and one sveld can't type gives `any` with a `sveld/context-any-type` diagnostic. In `COMPONENT_API.json`, a context typed this way has a `type` field holding the whole type and an empty `properties` array.
|
|
3953
|
+
|
|
3861
3954
|
**Option 4: Direct object literal with inline functions**
|
|
3862
3955
|
|
|
3863
3956
|
```svelte
|
|
@@ -3876,9 +3969,10 @@ There are several ways to type contexts:
|
|
|
3876
3969
|
|
|
3877
3970
|
#### Notes
|
|
3878
3971
|
|
|
3879
|
-
- Context keys must be statically resolvable: a string literal, a static template literal, a `const`-bound string
|
|
3880
|
-
- Variables passed to `setContext` should have JSDoc `@type` annotations for accurate types
|
|
3881
|
-
- The
|
|
3972
|
+
- Context keys must be statically resolvable: a string literal, a static template literal, a `const`-bound string, or a `Symbol()` / `Symbol.for()` call with a static description, either local or an imported `export const`. Dynamic expressions (runtime identifiers, template interpolation, other function calls) are skipped with a `sveld/context-key-unresolved` diagnostic.
|
|
3973
|
+
- Variables passed to `setContext` should have JSDoc `@type` annotations (or native TypeScript types) for accurate types. Without one, a variable is typed from its initializer the way a prop default is, unwrapping `$state`, `$state.raw`, and `$derived` (a rune's type argument, as in `$state<number>(0)`, wins). A variable passed as the whole value (`setContext("modal", modalAPI)`) types the context as that variable's type; one passed inside an object literal (`setContext("modal", { modalAPI })`) becomes a property
|
|
3974
|
+
- The value must be an object literal or a variable. Any other expression (such as `setContext("store", writable(0))`) is skipped with a `sveld/context-value-unresolved` diagnostic.
|
|
3975
|
+
- The generated type name follows the pattern: `{PascalCase}Context`. Separators (underscores and any character that can't appear in an identifier, such as hyphens, dots, colons, slashes, `@`, and spaces) are stripped and each segment is capitalized. A name starting with a digit gets a leading `_`:
|
|
3882
3976
|
| Context Key | Generated Type Name |
|
|
3883
3977
|
| --- | --- |
|
|
3884
3978
|
| `"simple-modal"` | `SimpleModalContext` |
|
|
@@ -3887,6 +3981,8 @@ There are several ways to type contexts:
|
|
|
3887
3981
|
| `"Carbon:Modal"` | `CarbonModalContext` |
|
|
3888
3982
|
| `"app/modal"` | `AppModalContext` |
|
|
3889
3983
|
| `"My Context"` | `MyContextContext` |
|
|
3984
|
+
| `"@scope/ctx"` | `ScopeCtxContext` |
|
|
3985
|
+
| `"123"` | `_123Context` |
|
|
3890
3986
|
| `"Tabs"` | `TabsContext` |
|
|
3891
3987
|
- If no type annotation is found, the type defaults to `any` with a warning
|
|
3892
3988
|
|
package/lib/browser.d.ts
CHANGED
|
@@ -42,13 +42,23 @@ interface PendingConstDefaultCandidate {
|
|
|
42
42
|
location: "props" | "moduleExports";
|
|
43
43
|
importSource: string;
|
|
44
44
|
importedName: string;
|
|
45
|
+
/** Members read off the import, through namespace exports: `["DELAY"]` for `C.timing.DELAY`. */
|
|
46
|
+
members?: string[];
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
interface PendingContextKeyCandidate {
|
|
48
50
|
importSource: string;
|
|
49
51
|
importedName: string;
|
|
52
|
+
/** Members read off the import, through namespace exports: `["THEME"]` for `ns.keys.THEME`. */
|
|
53
|
+
members?: string[];
|
|
54
|
+
/** See {@link ComponentContext.type}. */
|
|
55
|
+
type?: string;
|
|
50
56
|
properties: ComponentContextProp[];
|
|
51
57
|
description?: string;
|
|
58
|
+
/** See {@link ComponentContext.hasUnresolvedSpread}. */
|
|
59
|
+
hasUnresolvedSpread?: boolean;
|
|
60
|
+
/** See {@link ComponentContext.internal}. */
|
|
61
|
+
internal?: boolean;
|
|
52
62
|
/** Source range of the `setContext(...)` call, when available. */
|
|
53
63
|
source?: SourceRange;
|
|
54
64
|
}
|
|
@@ -56,6 +66,8 @@ interface PendingContextKeyCandidate {
|
|
|
56
66
|
interface PendingDispatchEscapeCandidate {
|
|
57
67
|
importSource: string;
|
|
58
68
|
importedName: string;
|
|
69
|
+
/** Members read off the import, through namespace exports: `["helper"]` for `ns.helper`. */
|
|
70
|
+
members?: string[];
|
|
59
71
|
/** Callee as written, for messages. */
|
|
60
72
|
calleeText: string;
|
|
61
73
|
/** Local name of the `createEventDispatcher()` result. */
|
|
@@ -74,6 +86,8 @@ interface ParsedComponentTypeScriptMetadata {
|
|
|
74
86
|
canonicalPropsType?: string;
|
|
75
87
|
canonicalPropNames: string[];
|
|
76
88
|
localTypeDeclarations: string[];
|
|
89
|
+
/** Types the module script exports (`export interface Item`), emitted with `export`. */
|
|
90
|
+
moduleTypeDeclarations?: string[];
|
|
77
91
|
typeImportStatements: string[];
|
|
78
92
|
/**
|
|
79
93
|
* Whether `canonicalPropsType` mentions one of the component's own
|
|
@@ -95,6 +109,11 @@ interface ParsedComponentTypeScriptMetadata {
|
|
|
95
109
|
* imported functions: `generateBundle` keeps those the functions don't dispatch.
|
|
96
110
|
*/
|
|
97
111
|
deferredEventNoSourceDiagnostics?: SveldDiagnostic[];
|
|
112
|
+
/**
|
|
113
|
+
* `@event` tags with no `{type}` or `@property`, whose `null` detail no
|
|
114
|
+
* same-file dispatch replaced; an escaped dispatcher's helper may still.
|
|
115
|
+
*/
|
|
116
|
+
untypedJsDocEventNames?: string[];
|
|
98
117
|
}
|
|
99
118
|
|
|
100
119
|
type SyntaxMode = "legacy" | "runes";
|
|
@@ -150,6 +169,29 @@ interface ComponentPropReExport {
|
|
|
150
169
|
imported: string;
|
|
151
170
|
}
|
|
152
171
|
|
|
172
|
+
interface ComponentClassMember {
|
|
173
|
+
/** `"property"` covers fields, constructor parameter properties, and getter/setter pairs. */
|
|
174
|
+
kind: "constructor" | "method" | "property";
|
|
175
|
+
/** Member name; `"constructor"` for the constructor. */
|
|
176
|
+
name: string;
|
|
177
|
+
/** Property type text; `"any"` when neither TypeScript nor JSDoc types it. */
|
|
178
|
+
type?: string;
|
|
179
|
+
/** Method or constructor parameters, typed from TypeScript or JSDoc `@param`, else `"any"`. A rest parameter's name starts with `...`. */
|
|
180
|
+
params?: ComponentPropParam[];
|
|
181
|
+
/** Method return type from TypeScript or JSDoc `@returns`; unset when neither gives one. */
|
|
182
|
+
returnType?: string;
|
|
183
|
+
/** A method's own type parameter list (`U extends object`), without the angle brackets. */
|
|
184
|
+
typeParameters?: string;
|
|
185
|
+
static?: true;
|
|
186
|
+
/** A `readonly` field, or a getter with no setter. */
|
|
187
|
+
readonly?: true;
|
|
188
|
+
optional?: true;
|
|
189
|
+
abstract?: true;
|
|
190
|
+
description?: string;
|
|
191
|
+
deprecated?: DeprecatedValue;
|
|
192
|
+
tags?: JsDocPassthroughTag[];
|
|
193
|
+
}
|
|
194
|
+
|
|
153
195
|
interface ComponentProp {
|
|
154
196
|
/** Public prop name; `"*"` for a bare `export * from "..."`. */
|
|
155
197
|
name: string;
|
|
@@ -157,8 +199,10 @@ interface ComponentProp {
|
|
|
157
199
|
* `"let"` (required), `"const"` (default), or `"function"`. `"re-export"`
|
|
158
200
|
* is module-export only: `export { x } from "..."`, `export * from "..."`,
|
|
159
201
|
* or `export { x }` of an imported binding, written to the `.d.ts` as-is.
|
|
202
|
+
* `"class"` is module-export only too: a class the module script declares,
|
|
203
|
+
* with its public surface in {@link ComponentProp.members}.
|
|
160
204
|
*/
|
|
161
|
-
kind: "let" | "const" | "function" | "re-export";
|
|
205
|
+
kind: "let" | "const" | "function" | "re-export" | "class";
|
|
162
206
|
/** True when declared with `const`. */
|
|
163
207
|
constant: boolean;
|
|
164
208
|
/** TypeScript type text. */
|
|
@@ -181,8 +225,17 @@ interface ComponentProp {
|
|
|
181
225
|
* A function's own type parameter list from its `@template` tags (e.g.
|
|
182
226
|
* `T extends { id: string }`), without the angle brackets. Also prefixed
|
|
183
227
|
* onto `type` when that signature is built from `@param`/`@returns`.
|
|
228
|
+
* For a `"class"`, the class's type parameters, from TypeScript or `@template`.
|
|
184
229
|
*/
|
|
185
230
|
typeParameters?: string;
|
|
231
|
+
/** Set when `kind` is `"class"`: its public constructor, methods, and properties, in source order. */
|
|
232
|
+
members?: ComponentClassMember[];
|
|
233
|
+
/** Set when `kind` is `"class"` and the class is `abstract`. */
|
|
234
|
+
abstract?: true;
|
|
235
|
+
/** Set when `kind` is `"class"` and it extends a base class: `Base<T>`. */
|
|
236
|
+
extends?: string;
|
|
237
|
+
/** Set when `kind` is `"class"` and it implements interfaces: `["Disposable"]`. */
|
|
238
|
+
implements?: string[];
|
|
186
239
|
/**
|
|
187
240
|
* True for arrow/function-expression initializers and bare `function`
|
|
188
241
|
* declarations in every mode; additionally true for a function-shaped
|
|
@@ -381,9 +434,15 @@ interface ComponentContext {
|
|
|
381
434
|
key: string;
|
|
382
435
|
/** Generated type name (e.g. `"ModalContext"`). */
|
|
383
436
|
typeName: string;
|
|
437
|
+
/**
|
|
438
|
+
* The context's whole type, when the `setContext` value is a variable whose
|
|
439
|
+
* type isn't an object type literal (`ModalAPI`, `Writable<number>`, or `any`
|
|
440
|
+
* when untyped). `properties` is empty then.
|
|
441
|
+
*/
|
|
442
|
+
type?: string;
|
|
384
443
|
/** From JSDoc. */
|
|
385
444
|
description?: string;
|
|
386
|
-
/** Context object properties. */
|
|
445
|
+
/** Context object properties. Empty when {@link ComponentContext.type} is set. */
|
|
387
446
|
properties: ComponentContextProp[];
|
|
388
447
|
/** True when a `{...spread}` in the context's object literal couldn't be resolved; the generated type intersects with `Record<string, any>`. */
|
|
389
448
|
hasUnresolvedSpread?: boolean;
|
|
@@ -476,13 +535,37 @@ export class ComponentParser {
|
|
|
476
535
|
} | undefined;
|
|
477
536
|
private addModuleExport;
|
|
478
537
|
/**
|
|
479
|
-
* Resolves one `export { local as exported }` specifier to the
|
|
480
|
-
*
|
|
538
|
+
* Resolves one `export { local as exported }` specifier to the top-level
|
|
539
|
+
* function, class, or variable declarator (including one destructured
|
|
540
|
+
* from a pattern) it names. Each specifier resolves on its own, so
|
|
481
541
|
* `export { a, b }` exports both, and `const a = 1, b = ""; export { b }`
|
|
482
542
|
* exports `b`'s declarator rather than the first one in the declaration.
|
|
543
|
+
*
|
|
544
|
+
* `program` is the script the export sits in: only its top-level
|
|
545
|
+
* declarations count, not a same-named variable inside a function. An
|
|
546
|
+
* instance-script export can also name a module-script declaration, or a
|
|
547
|
+
* variable that a `$: local = ...` reactive declaration declares implicitly.
|
|
483
548
|
*/
|
|
484
549
|
private resolveExportSpecifier;
|
|
485
550
|
private recordUnresolvedExportSpecifier;
|
|
551
|
+
/**
|
|
552
|
+
* Doc comment for a declaration exported by `node`. A specifier uses the
|
|
553
|
+
* comment on the declaration it names. An `export { ... }` list's own
|
|
554
|
+
* comment documents it too, but only when the list has a single specifier;
|
|
555
|
+
* its tags and description then override the declaration's.
|
|
556
|
+
*/
|
|
557
|
+
private exportJSDoc;
|
|
558
|
+
/** An instance-script `export class Foo {}` or `export { Foo }` of a class: neither a prop nor a documented accessor. */
|
|
559
|
+
private recordClassExport;
|
|
560
|
+
/**
|
|
561
|
+
* The `.d.ts` can only say `extends Base` when `Base` is in scope there:
|
|
562
|
+
* imported, or another exported class. A class extending anything else
|
|
563
|
+
* (a local class, a call like `mixin(Base)`) is declared without it, and
|
|
564
|
+
* flagged, since consumers won't see its inherited members.
|
|
565
|
+
*/
|
|
566
|
+
private dropUndeclaredClassBases;
|
|
567
|
+
/** A module-script `export class Foo {}` or `export { Foo }` of a class, with its public members. */
|
|
568
|
+
private addModuleClassExport;
|
|
486
569
|
/**
|
|
487
570
|
* @example
|
|
488
571
|
* ```ts
|
|
@@ -510,6 +593,17 @@ export class ComponentParser {
|
|
|
510
593
|
description?: string;
|
|
511
594
|
internal?: boolean;
|
|
512
595
|
} | null;
|
|
596
|
+
/**
|
|
597
|
+
* The description and `@internal` flag of the JSDoc above `varName`,
|
|
598
|
+
* whether or not it has a `@type`. For a variable typed some other way,
|
|
599
|
+
* such as from its initializer.
|
|
600
|
+
*/
|
|
601
|
+
findVariableJsDoc(varName: string): {
|
|
602
|
+
description?: string;
|
|
603
|
+
internal?: boolean;
|
|
604
|
+
};
|
|
605
|
+
/** The JSDoc table entry for `varName`, building the table on first use. */
|
|
606
|
+
private variableJsDocEntry;
|
|
513
607
|
accumulateGeneric(name: string, constraint: string): void;
|
|
514
608
|
/**
|
|
515
609
|
* Resets parser state for reuse between parses.
|
|
@@ -523,6 +617,7 @@ export class ComponentParser {
|
|
|
523
617
|
*/
|
|
524
618
|
cleanup(): void;
|
|
525
619
|
private static readonly SCRIPT_BLOCK_REGEX;
|
|
620
|
+
/** A `// @ts-...` comment, but not one on a `*` line of a JSDoc block (e.g. in an `@example`). */
|
|
526
621
|
private static readonly TS_DIRECTIVE_REGEX;
|
|
527
622
|
private static stripTypeScriptDirectivesFromScripts;
|
|
528
623
|
/**
|
|
@@ -539,12 +634,15 @@ export class ComponentParser {
|
|
|
539
634
|
parseSvelteComponent(source: string, diagnostics: ComponentParserDiagnostics): ParsedComponent;
|
|
540
635
|
}
|
|
541
636
|
|
|
542
|
-
export type SveldDiagnosticKind = "prop-unknown-type" | "context-any-type" | "slot-missing-type" | "event-no-source" | "dispatch-escapes" | "example-compile-error" | "example-syntax-error" | "syntax-skipped" | "rest-props-unresolved" | "context-duplicate-key" | "context-key-unresolved" | "spread-unresolved" | "export-unresolved" | "module-export-conflict" | "extend-props-target-missing" | "extend-props-duplicate" | "extend-props-override" | "jsdoc-unknown-tag" | "typedef-duplicate" | "property-duplicate" | "generics-conflict" | "event-description-ambiguous" | "jsdoc-tag-dropped" | "internal-typedef-referenced" | "types-inline-unresolved";
|
|
637
|
+
export type SveldDiagnosticKind = "prop-unknown-type" | "context-any-type" | "slot-missing-type" | "event-no-source" | "dispatch-escapes" | "example-compile-error" | "example-syntax-error" | "syntax-skipped" | "rest-props-unresolved" | "context-duplicate-key" | "context-key-unresolved" | "context-value-unresolved" | "spread-unresolved" | "export-unresolved" | "module-export-conflict" | "extend-props-target-missing" | "extend-props-duplicate" | "extend-props-override" | "jsdoc-unknown-tag" | "typedef-duplicate" | "property-duplicate" | "generics-conflict" | "event-description-ambiguous" | "jsdoc-tag-dropped" | "internal-typedef-referenced" | "types-inline-unresolved" | "cross-file-unresolved" | "export-ambiguous";
|
|
543
638
|
|
|
544
639
|
type SveldDiagnosticSeverity = "error" | "warning";
|
|
545
640
|
|
|
546
641
|
export interface SveldDiagnostic {
|
|
547
|
-
/**
|
|
642
|
+
/**
|
|
643
|
+
* File this came from, e.g. `"./Button.svelte"`, or the entry barrel
|
|
644
|
+
* (`"./index.js"`) for `export-ambiguous`.
|
|
645
|
+
*/
|
|
548
646
|
component: string;
|
|
549
647
|
kind: SveldDiagnosticKind;
|
|
550
648
|
/** Stable, namespaced identifier for `kind` (e.g. `"sveld/prop-unknown-type"`). */
|
|
@@ -566,6 +664,13 @@ export interface SveldDiagnostic {
|
|
|
566
664
|
|
|
567
665
|
declare const PARSED_COMPONENT_TYPE_SCRIPT_METADATA: unique symbol;
|
|
568
666
|
|
|
667
|
+
export interface FinalizeWithoutCrossFileResolutionOptions {
|
|
668
|
+
/** Path recorded on the new diagnostics. Defaults to the component's own `filePath`, if it has one. */
|
|
669
|
+
filePath?: string;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
export declare function finalizeWithoutCrossFileResolution<T extends ParsedComponent>(component: T, options?: FinalizeWithoutCrossFileResolutionOptions): T;
|
|
673
|
+
|
|
569
674
|
export interface ComponentDocApi extends ParsedComponent {
|
|
570
675
|
filePath: NormalizedPath;
|
|
571
676
|
moduleName: string;
|
|
@@ -665,7 +770,11 @@ export declare function writeTsDefinition(component: ComponentDocApi, options?:
|
|
|
665
770
|
interface EntryExport {
|
|
666
771
|
name: string;
|
|
667
772
|
kind: "const" | "let" | "var" | "function" | "class" | "type" | "interface" | "enum";
|
|
668
|
-
/**
|
|
773
|
+
/**
|
|
774
|
+
* Type text from the source, when present. A namespace export
|
|
775
|
+
* (`export * as ns from "./x"`) gets `typeof import("./x.ts")`, the
|
|
776
|
+
* wrapped module relative to the entry file.
|
|
777
|
+
*/
|
|
669
778
|
type?: string;
|
|
670
779
|
/** Initializer text for simple constants. */
|
|
671
780
|
value?: string;
|