sveld 0.34.1 → 0.35.1
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 +357 -89
- package/cli.js +6 -1
- package/lib/ComponentParser.d.ts +229 -568
- package/lib/ast-guards.d.ts +7 -1
- package/lib/browser.d.ts +39 -0
- package/lib/browser.js +290 -0
- package/lib/bundle.d.ts +23 -3
- package/lib/check.d.ts +6 -0
- package/lib/cli.d.ts +18 -18
- package/lib/diagnostics.d.ts +5 -1
- package/lib/example-check.d.ts +3 -1
- package/lib/index.js +306 -720
- package/lib/load-config.d.ts +20 -2
- package/lib/parse-exports.d.ts +5 -1
- package/lib/parser/bindings.d.ts +6 -0
- package/lib/parser/context.d.ts +114 -0
- package/lib/parser/contexts.d.ts +19 -0
- package/lib/parser/diagnostics.d.ts +8 -0
- package/lib/parser/events.d.ts +23 -0
- package/lib/parser/generics.d.ts +24 -0
- package/lib/parser/jsdoc.d.ts +59 -0
- package/lib/parser/props.d.ts +73 -0
- package/lib/parser/rest-props.d.ts +6 -0
- package/lib/parser/runes-detection.d.ts +16 -0
- package/lib/parser/runes-props.d.ts +18 -0
- package/lib/parser/scopes.d.ts +58 -0
- package/lib/parser/slots.d.ts +29 -0
- package/lib/parser/source-position.d.ts +30 -0
- package/lib/parser/type-resolution.d.ts +32 -0
- package/lib/parser/typescript-casts.d.ts +2 -0
- package/lib/plugin.d.ts +7 -3
- package/lib/resolve-types.d.ts +1 -1
- package/lib/sveld.d.ts +6 -19
- package/lib/writer/MarkdownWriterBase.d.ts +2 -1
- package/lib/writer/Writer.d.ts +13 -49
- package/lib/writer/WriterMarkdown.d.ts +1 -1
- package/lib/writer/format-generated-ts.d.ts +8 -0
- package/lib/writer/writer-custom-elements-core.d.ts +86 -0
- package/lib/writer/writer-custom-elements.d.ts +15 -0
- package/lib/writer/writer-ts-definitions-core.d.ts +12 -1
- package/lib/writer/writer-ts-definitions.d.ts +4 -3
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -3,24 +3,21 @@
|
|
|
3
3
|
[![NPM][npm]][npm-url]
|
|
4
4
|

|
|
5
5
|
|
|
6
|
-
`sveld` generates TypeScript definitions and component documentation (Markdown/JSON) for Svelte components. It statically analyzes props, events, slots, and
|
|
6
|
+
`sveld` generates TypeScript definitions and component documentation (Markdown/JSON) for Svelte components. It statically analyzes props, events, slots, module exports, context, and `$$restProps`. Add types with [JSDoc](https://jsdoc.app/) when inference is not enough.
|
|
7
7
|
|
|
8
8
|
The goal is to get third-party Svelte libraries working with the Svelte Language Server and TypeScript with minimal effort from the author. Generated `.d.ts` files give you autocomplete in VS Code and other IDEs.
|
|
9
9
|
|
|
10
10
|
[Carbon Components Svelte](https://github.com/carbon-design-system/carbon-components-svelte) uses this library to auto-generate component types and API metadata.
|
|
11
11
|
|
|
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`, …)
|
|
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, and Svelte 5 without runes (`export let`, `<slot>`, `$$restProps`, …). It also covers Svelte 5 Runes (`$props()`, `$bindable()`, `{@render ...}`, callback props such as `onclick`, …).
|
|
13
13
|
|
|
14
14
|
For `lang="ts"` components, `sveld` keeps source-level prop type annotations when it can, instead of forcing JSDoc. That covers 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
15
|
|
|
16
|
-
|
|
17
|
-
| :------------------- | :-------: |
|
|
18
|
-
| Svelte 3 | ✓ |
|
|
19
|
-
| Svelte 4 | ✓ |
|
|
20
|
-
| Svelte 5 (non-Runes) | ✓ |
|
|
21
|
-
| Svelte 5 Runes | ✓ |
|
|
16
|
+
By default, generated `.d.ts` files extend `SvelteComponentTyped` from `svelte`, so TypeScript and the Svelte Language Server work whether consumers use Svelte 3, Svelte 4, or Svelte 5. Set `typesOptions.format: "component"` to instead emit the Svelte 5 `Component` type; see [`typesOptions.format`](#typesoptionsformat).
|
|
22
17
|
|
|
23
|
-
|
|
18
|
+
## When to use sveld
|
|
19
|
+
|
|
20
|
+
SvelteKit's library tooling (`svelte-package`) and `svelte2tsx` already emit `.d.ts` files for SvelteKit-based projects, so start there if that's your setup. `sveld` targets JS-first Svelte libraries: components authored in plain JavaScript with JSDoc rather than `lang="ts"`, where you still want full editor types without adopting TypeScript. It also covers cases `svelte-package` doesn't: generating JSON and Markdown component docs from the same source as the types, checking for API drift between releases (`--check`), and deriving richer types from JSDoc tags (`@typedef`, `@callback`, `@slot`, context types) than plain type inference produces.
|
|
24
21
|
|
|
25
22
|
---
|
|
26
23
|
|
|
@@ -72,6 +69,8 @@ export default class Button extends SvelteComponentTyped<
|
|
|
72
69
|
> {}
|
|
73
70
|
```
|
|
74
71
|
|
|
72
|
+
`sveld` adds the `[key: \`data-${string}\`]: unknown;` index signature whenever `$$restProps` is spread onto an element, so callers can pass arbitrary `data-*` attributes.
|
|
73
|
+
|
|
75
74
|
Inference only gets you so far. Use [JSDoc](https://jsdoc.app/) to document prop, event, and slot types when you need more precision.
|
|
76
75
|
|
|
77
76
|
```js
|
|
@@ -87,6 +86,7 @@ export let primary = false;
|
|
|
87
86
|
With JSDoc, the output looks like this:
|
|
88
87
|
|
|
89
88
|
```ts
|
|
89
|
+
import { SvelteComponentTyped } from "svelte";
|
|
90
90
|
import type { SvelteHTMLElements } from "svelte/elements";
|
|
91
91
|
|
|
92
92
|
type $RestProps = SvelteHTMLElements["button"];
|
|
@@ -117,19 +117,32 @@ export default class Button extends SvelteComponentTyped<
|
|
|
117
117
|
|
|
118
118
|
## Table of Contents
|
|
119
119
|
|
|
120
|
+
- [When to use sveld](#when-to-use-sveld)
|
|
120
121
|
- [Approach](#approach)
|
|
122
|
+
- [Features](#features)
|
|
123
|
+
- [`.d.ts` output format (`typesOptions.format`)](#dts-output-format-typesoptionsformat)
|
|
124
|
+
- [Opt-in semantic resolution (`resolveTypes`)](#opt-in-semantic-resolution-resolvetypes)
|
|
125
|
+
- [Persistent parse cache (`cache`)](#persistent-parse-cache-cache)
|
|
126
|
+
- [Compile-checked `@example` blocks (`checkExamples`)](#compile-checked-example-blocks-checkexamples)
|
|
127
|
+
- [Type inference diagnostics](#type-inference-diagnostics)
|
|
128
|
+
- [Requirements](#requirements)
|
|
121
129
|
- [Usage](#usage)
|
|
122
130
|
- [Installation](#installation)
|
|
123
131
|
- [Vite](#vite)
|
|
124
|
-
- [Node.js](#nodejs)
|
|
125
132
|
- [CLI](#cli)
|
|
126
133
|
- [CI: API-drift checks (`--check`)](#ci-api-drift-checks---check)
|
|
134
|
+
- [Node.js](#nodejs)
|
|
135
|
+
- [Browser](#browser)
|
|
127
136
|
- [Config File](#config-file)
|
|
128
137
|
- [Publishing to NPM](#publishing-to-npm)
|
|
129
138
|
- [Available Options](#available-options)
|
|
130
139
|
- [Documenting Entry Exports](#documenting-entry-exports)
|
|
131
140
|
- [JSON Output](#json-output)
|
|
141
|
+
- [Custom Elements Manifest](#custom-elements-manifest)
|
|
142
|
+
- [Consuming the manifest](#consuming-the-manifest)
|
|
132
143
|
- [API Reference](#api-reference)
|
|
144
|
+
- [reactive](#reactive)
|
|
145
|
+
- [binding](#binding)
|
|
133
146
|
- [@type](#type)
|
|
134
147
|
- [@default](#default)
|
|
135
148
|
- [@typedef](#typedef)
|
|
@@ -146,6 +159,7 @@ export default class Button extends SvelteComponentTyped<
|
|
|
146
159
|
- [@generics](#generics)
|
|
147
160
|
- [@component comments](#component-comments)
|
|
148
161
|
- [Accessor Props](#accessor-props)
|
|
162
|
+
- [Troubleshooting](#troubleshooting)
|
|
149
163
|
- [Contributing](#contributing)
|
|
150
164
|
- [License](#license)
|
|
151
165
|
|
|
@@ -173,7 +187,73 @@ When both TypeScript syntax and JSDoc are present, `sveld` resolves prop types i
|
|
|
173
187
|
|
|
174
188
|
`sveld` stays AST-only. It copies imported and local type text into generated `.d.ts` output but does not run project-wide semantic resolution with the TypeScript compiler. Opaque imported whole-object `$props()` types can therefore stay in declarations without being fully expanded into JSON metadata.
|
|
175
189
|
|
|
176
|
-
|
|
190
|
+
## Features
|
|
191
|
+
|
|
192
|
+
### `.d.ts` output format (`typesOptions.format`)
|
|
193
|
+
|
|
194
|
+
`typesOptions.format` controls the shape of generated `.d.ts` files: `"class"` (the default) or `"component"`.
|
|
195
|
+
|
|
196
|
+
`"class"` extends `SvelteComponentTyped`, deprecated in Svelte 5 and plausibly removed in Svelte 6:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
import { SvelteComponentTyped } from "svelte";
|
|
200
|
+
|
|
201
|
+
export type ButtonProps = { label?: string };
|
|
202
|
+
|
|
203
|
+
export default class Button extends SvelteComponentTyped<
|
|
204
|
+
ButtonProps,
|
|
205
|
+
{ click: WindowEventMap["click"] },
|
|
206
|
+
{ default: Record<string, never> }
|
|
207
|
+
> {}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`"component"` emits the Svelte 5 `Component` type instead:
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
import type { Component } from "svelte";
|
|
214
|
+
|
|
215
|
+
export type ButtonProps = { label?: string; onclick?: (event: WindowEventMap["click"]) => void };
|
|
216
|
+
export type ButtonExports = Record<string, never>;
|
|
217
|
+
|
|
218
|
+
declare const Button: Component<ButtonProps, ButtonExports, "">;
|
|
219
|
+
export default Button;
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Publish `"component"` if you target Svelte 5+ consumers. `"class"` remains compatible with Svelte 3, 4, and 5.
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
await sveld({ types: true, typesOptions: { format: "component" } });
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Also available as `--types-format=component` on the CLI.
|
|
229
|
+
|
|
230
|
+
`"component"`'s three type parameters:
|
|
231
|
+
|
|
232
|
+
- **Props**: the same `$Props`/`<Name>Props` type as `"class"`. Runes components already declare callback props (e.g. `onclick`) as regular props. Legacy (non-runes) components additionally get `on<name>?: (event: Type) => void` callback props for every dispatched and forwarded event, so Svelte 5 consumers can attach handlers as props instead of `on:event`.
|
|
233
|
+
- **Exports**: the component's accessor props (exported `function`/`const` members), the same members that render as class members under `"class"`.
|
|
234
|
+
- **Bindings**: a union of string literals for props declared with `$bindable(...)` (runes) or marked `@bindable writable` ([see `binding`](#binding)) (legacy) — e.g. `"value"`, or `"value" | "open"` for more than one. `""` when the component declares none, matching Svelte's own convention for "no bindings."
|
|
235
|
+
|
|
236
|
+
**Generic components.** A `declare const X: Component<...>` value can't itself carry a generic type parameter the way a class can, so generic components (`@template`/`generics`) get a per-component interface instead of `Component<...>` directly:
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
interface GenericListComponent {
|
|
240
|
+
new <Item extends { id: string | number } = { id: string }>(
|
|
241
|
+
options: ComponentConstructorOptions<GenericListProps<Item>>,
|
|
242
|
+
): SvelteComponent<GenericListProps<Item>> & GenericListExports;
|
|
243
|
+
<Item extends { id: string | number } = { id: string }>(
|
|
244
|
+
this: void,
|
|
245
|
+
internals: ComponentInternals,
|
|
246
|
+
props: GenericListProps<Item>,
|
|
247
|
+
): { $on?(...): () => void; $set?(...): void } & GenericListExports;
|
|
248
|
+
z_$$bindings?: "";
|
|
249
|
+
}
|
|
250
|
+
declare const GenericList: GenericListComponent;
|
|
251
|
+
export default GenericList;
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Both signatures carry their own generic parameter (not the `const` itself), so `Item` is inferred per usage site, e.g. `<GenericList items={numbers} />` infers `Item` from `numbers`. The `new` signature is the one place `"component"` format still touches a legacy type (`SvelteComponent`/`ComponentConstructorOptions`, not the deprecated `SvelteComponentTyped`): the Svelte language server resolves generic inference for `<Comp prop={...} />` template usage through `new`, not the plain call signature, confirmed by comparing against `@sveltejs/package`'s own generated output for the same component. Omitting it silently breaks inference instead of erroring, so it stays in even though it means one legacy import for generic components.
|
|
255
|
+
|
|
256
|
+
### Opt-in semantic resolution (`resolveTypes`)
|
|
177
257
|
|
|
178
258
|
Imported whole-object `$props()` types stay opaque in JSON by default (`"props": []`). Turn on `resolveTypes` when a docs site or prop table needs the individual fields.
|
|
179
259
|
|
|
@@ -203,19 +283,19 @@ Without `resolveTypes`, JSON lists no props. With it, each field shows up with `
|
|
|
203
283
|
|
|
204
284
|
**Performance.** Off by default. This is the only path that loads TypeScript. It needs `typescript` and a `tsconfig.json`, runs slower than the AST-only pipeline, and gets slower as your types grow. Use it only when you need expanded JSON. `.d.ts` output is unchanged.
|
|
205
285
|
|
|
206
|
-
|
|
286
|
+
### Persistent parse cache (`cache`)
|
|
207
287
|
|
|
208
|
-
|
|
288
|
+
Parsed output is written to disk and reused when the source file has not changed, on by default. That applies across runs, including CI on a fresh checkout.
|
|
209
289
|
|
|
210
290
|
```ts
|
|
211
|
-
await sveld({ json: true
|
|
291
|
+
await sveld({ json: true });
|
|
212
292
|
```
|
|
213
293
|
|
|
214
|
-
|
|
294
|
+
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"`, or `cache: false` to disable it. Also available as `--cache` / `--cache=<path>` / `--cache=false` on the CLI.
|
|
215
295
|
|
|
216
296
|
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.
|
|
217
297
|
|
|
218
|
-
|
|
298
|
+
### Compile-checked `@example` blocks (`checkExamples`)
|
|
219
299
|
|
|
220
300
|
`@example` blocks are just text. Rename a prop and the sample code can sit there broken for months. Set `checkExamples: true` to run plain TS/JS `@example` blocks through the TypeScript program. Broken examples show up as `example-compile-error` diagnostics.
|
|
221
301
|
|
|
@@ -254,30 +334,34 @@ The check is narrow on purpose. It catches renamed or removed symbols and wrong
|
|
|
254
334
|
|
|
255
335
|
Needs `typescript` and a `tsconfig.json`, same as `resolveTypes`. Use `--strict` (or the `strict` option) to fail CI when an example breaks.
|
|
256
336
|
|
|
257
|
-
|
|
337
|
+
### Type inference diagnostics
|
|
258
338
|
|
|
259
|
-
`sveld` collects unresolved-type diagnostics on every run: props that fall back to `any`, context values typed as `any`, `@event` tags with no dispatch or callback, and (when `checkExamples` is enabled) `example-compile-error`. They are always returned from the programmatic `sveld()` API in `SveldResult.diagnostics`.
|
|
339
|
+
`sveld` collects unresolved-type diagnostics on every run: props that fall back to `any`, context values typed as `any`, `@event` tags with no dispatch or callback, `$props()`/`{@render}` syntax sveld can't model, and (when `checkExamples` is enabled) `example-compile-error`. They are always returned from the programmatic `sveld()` API in `SveldResult.diagnostics`. Each diagnostic carries an optional `source` range (the same `{ start: { line, column }, end: { line, column } }` shape as JSON output source ranges) whenever the parser holds a stable position for it.
|
|
260
340
|
|
|
261
341
|
With `reportDiagnostics` or `strict`, the grouped summary looks like this:
|
|
262
342
|
|
|
263
343
|
```
|
|
264
|
-
sveld:
|
|
344
|
+
sveld: 5 unresolved types found.
|
|
265
345
|
|
|
266
346
|
Props without inferred types (1):
|
|
267
347
|
./icons/Add.svelte
|
|
268
|
-
- Prop "title" type could not be inferred; falling back to "any".
|
|
348
|
+
- Prop "title" type could not be inferred; falling back to "any". (./icons/Add.svelte:4:2)
|
|
269
349
|
|
|
270
350
|
Context values typed as `any` (1):
|
|
271
351
|
./ThemeProvider.svelte
|
|
272
|
-
- Context "theme" variable "themeStore" has no type annotation; defaulted to "any".
|
|
352
|
+
- Context "theme" variable "themeStore" has no type annotation; defaulted to "any". (./ThemeProvider.svelte:8:6)
|
|
273
353
|
|
|
274
354
|
@event tags with no dispatch or callback (2):
|
|
275
355
|
./Modal.svelte
|
|
276
|
-
- @event "open" has no matching dispatch or callback prop.
|
|
277
|
-
- @event "close" has no matching dispatch or callback prop.
|
|
356
|
+
- @event "open" has no matching dispatch or callback prop. (./Modal.svelte:3:5)
|
|
357
|
+
- @event "close" has no matching dispatch or callback prop. (./Modal.svelte:4:5)
|
|
358
|
+
|
|
359
|
+
Component syntax sveld skipped (1):
|
|
360
|
+
./Tabs.svelte
|
|
361
|
+
- {@render tabs(getTabProps())} argument is not a plain object literal; the render call was not mapped to slot metadata. (./Tabs.svelte:6:4)
|
|
278
362
|
```
|
|
279
363
|
|
|
280
|
-
When `checkExamples` is also enabled, `@example` compile failures appear as a
|
|
364
|
+
When `checkExamples` is also enabled, `@example` compile failures appear as a fifth group:
|
|
281
365
|
|
|
282
366
|
```
|
|
283
367
|
@example blocks that failed to compile (1):
|
|
@@ -306,6 +390,12 @@ npx sveld --json --strict
|
|
|
306
390
|
|
|
307
391
|
`--check` is separate: it diffs `COMPONENT_API.json` for API drift and semver classification, not inference warnings.
|
|
308
392
|
|
|
393
|
+
## Requirements
|
|
394
|
+
|
|
395
|
+
- Node 22+. CI tests against Node 22 on Linux, Windows, and macOS; earlier LTS versions are not verified.
|
|
396
|
+
- `sveld` is ESM-only. `require("sveld")` does not work — use `import` or dynamic `import()`.
|
|
397
|
+
- `sveld` bundles its own Svelte 5 compiler to parse `.svelte` files. Parsing does not depend on the Svelte version installed in your project, so Svelte 3 and Svelte 4 codebases parse the same way Svelte 5 codebases do — there is no compiler version to match up.
|
|
398
|
+
|
|
309
399
|
## Usage
|
|
310
400
|
|
|
311
401
|
### Installation
|
|
@@ -328,7 +418,7 @@ yarn add -D sveld
|
|
|
328
418
|
|
|
329
419
|
### Vite
|
|
330
420
|
|
|
331
|
-
Import and add `sveld` as a plugin to your `vite.config.ts`. The plugin only runs during `vite build`
|
|
421
|
+
Import and add `sveld` as a plugin to your `vite.config.ts`. The plugin only runs during `vite build`, unless `watch: true` is set, in which case it also regenerates output during `vite dev`.
|
|
332
422
|
|
|
333
423
|
```ts
|
|
334
424
|
// vite.config.ts
|
|
@@ -343,7 +433,7 @@ export default defineConfig({
|
|
|
343
433
|
|
|
344
434
|
Since Vite uses Rollup for production builds, the same plugin works in Rollup configs.
|
|
345
435
|
|
|
346
|
-
By default, `sveld`
|
|
436
|
+
By default, `sveld` uses the `"svelte"` field from your `package.json` to determine the entry point. You can override this by specifying an explicit `entry` option:
|
|
347
437
|
|
|
348
438
|
```js
|
|
349
439
|
sveld({
|
|
@@ -354,7 +444,6 @@ sveld({
|
|
|
354
444
|
When building the library, TypeScript definitions are emitted to the `types` folder by default.
|
|
355
445
|
|
|
356
446
|
Customize the output folder using the `typesOptions.outDir` option.
|
|
357
|
-
Use `typesOptions.printWidth` to control Prettier wrapping for generated `.d.ts` files. The default is `80`.
|
|
358
447
|
|
|
359
448
|
The following example emits the output to the `dist` folder:
|
|
360
449
|
|
|
@@ -362,7 +451,6 @@ The following example emits the output to the `dist` folder:
|
|
|
362
451
|
sveld({
|
|
363
452
|
+ typesOptions: {
|
|
364
453
|
+ outDir: 'dist',
|
|
365
|
-
+ printWidth: 80
|
|
366
454
|
+ }
|
|
367
455
|
})
|
|
368
456
|
```
|
|
@@ -381,6 +469,12 @@ Generate documentation in JSON and/or Markdown formats using the following flags
|
|
|
381
469
|
npx sveld --json --markdown
|
|
382
470
|
```
|
|
383
471
|
|
|
472
|
+
If no entry point can be resolved (no `package.json#svelte` field and no `--entry`), the CLI exits `1` and prints the reason to `stderr`. If `src/index.js` happens to exist relative to your working directory, sveld falls back to it and prints a one-line note asking you to set `package.json#svelte` (or `--entry`) instead of relying on the fallback.
|
|
473
|
+
|
|
474
|
+
Flags are kebab-case: `--entry`, `--glob`, `--types`, `--json`, `--markdown`, `--fail-fast`, `--cache`, `--resolve-types`, `--check-examples`, `--report-diagnostics`, `--strict`, `--check`, `--types-format`. The camelCase spellings `--resolveTypes` and `--checkExamples` still work as deprecated aliases for compatibility with existing scripts. An unrecognized flag (e.g. `--markdwon`) prints `Unknown flag: --markdwon` to `stderr`, exits `1`, and skips generation; sveld takes no positional arguments, so any non-flag argument errors the same way.
|
|
475
|
+
|
|
476
|
+
Run `npx sveld --help` for the full flag list with descriptions, or `npx sveld --version` to print the installed version.
|
|
477
|
+
|
|
384
478
|
### CI: API-drift checks (`--check`)
|
|
385
479
|
|
|
386
480
|
`--check` diffs the parsed component API against a committed `COMPONENT_API.json` snapshot, assigns a semver bump to each change, and exits `1` when it finds a breaking change.
|
|
@@ -407,18 +501,22 @@ Removed props, events, or slots, and props that become required, are breaking (`
|
|
|
407
501
|
|
|
408
502
|
Use `--check=<path>` to diff against a snapshot at a custom location (defaults to `jsonOptions.outFile`, or `COMPONENT_API.json`).
|
|
409
503
|
|
|
504
|
+
The CLI exits non-zero on any fatal error (an unreadable entry, a config file that throws, etc.), not just on `--strict`/`--check` findings, so it's safe to use either flag as a CI gate.
|
|
505
|
+
|
|
410
506
|
### Node.js
|
|
411
507
|
|
|
412
|
-
You can also call `sveld` from Node.js.
|
|
508
|
+
You can also call `sveld` from Node.js. See [Requirements](#requirements) for supported Node versions and the ESM-only constraint.
|
|
509
|
+
|
|
510
|
+
If no `entry` is specified, `sveld` infers the entry point based on the `package.json#svelte` field. If no entry point can be resolved, `sveld()` throws with an actionable message (previously it resolved to `{ diagnostics: [] }` and generated nothing).
|
|
413
511
|
|
|
414
|
-
|
|
512
|
+
> `input` was renamed to `entry` to match the CLI, plugin, and config. Calls passing `input` throw with a message pointing at `entry`.
|
|
415
513
|
|
|
416
514
|
```js
|
|
417
515
|
import { sveld } from "sveld";
|
|
418
516
|
import pkg from "./package.json" with { type: "json" };
|
|
419
517
|
|
|
420
518
|
const { diagnostics } = await sveld({
|
|
421
|
-
|
|
519
|
+
entry: "./src/index.js",
|
|
422
520
|
glob: true,
|
|
423
521
|
markdown: true,
|
|
424
522
|
markdownOptions: {
|
|
@@ -439,6 +537,21 @@ const { diagnostics } = await sveld({
|
|
|
439
537
|
|
|
440
538
|
`diagnostics` is always populated; printing is opt-in via `reportDiagnostics` or `strict` (see [Type inference diagnostics](#type-inference-diagnostics)).
|
|
441
539
|
|
|
540
|
+
Pass `check: true` (or `check: "<path>"` for a custom snapshot location) to diff against a committed `COMPONENT_API.json`, the same way `--check` does on the CLI. The result lands on `SveldResult.check`; sveld does not print it or touch `process.exitCode` for you, so inspect and act on it yourself:
|
|
541
|
+
|
|
542
|
+
```js
|
|
543
|
+
import { formatCheckReport } from "sveld";
|
|
544
|
+
|
|
545
|
+
const { check } = await sveld({ json: true, check: true });
|
|
546
|
+
|
|
547
|
+
if (check) {
|
|
548
|
+
console.log(formatCheckReport(check));
|
|
549
|
+
if (check.bump === "major") process.exitCode = 1;
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
See [CI: API-drift checks (`--check`)](#ci-api-drift-checks---check) for how changes are classified.
|
|
554
|
+
|
|
442
555
|
#### `jsonOptions.outDir`
|
|
443
556
|
|
|
444
557
|
With `json: true`, `sveld` writes `COMPONENT_API.json` at the project root. The file documents all components.
|
|
@@ -456,6 +569,51 @@ sveld({
|
|
|
456
569
|
});
|
|
457
570
|
```
|
|
458
571
|
|
|
572
|
+
### Browser
|
|
573
|
+
|
|
574
|
+
`sveld/browser` is a Node-free subpath export for running `sveld` client-side — e.g. an in-browser Svelte playground or REPL that parses whatever `.svelte` source the user typed and renders docs for it live. It bundles with Vite, esbuild, webpack, or Rollup without a `node:fs`/`node:path` polyfill.
|
|
575
|
+
|
|
576
|
+
It covers parsing one component's source and rendering that result to any output format `sveld` supports (JSON, Markdown, `.d.ts`, Custom Elements Manifest). It does not cover project-wide glob scanning, the config file, or the CLI/Vite plugin (`sveld()`/`pluginSveld()`) — those walk the filesystem and only make sense in Node. Use the main `sveld` entry point for those.
|
|
577
|
+
|
|
578
|
+
```ts
|
|
579
|
+
import {
|
|
580
|
+
asNormalizedPath,
|
|
581
|
+
ComponentParser,
|
|
582
|
+
buildComponentApiDocument,
|
|
583
|
+
writeMarkdownCore,
|
|
584
|
+
writeTsDefinition,
|
|
585
|
+
buildCustomElementsManifest,
|
|
586
|
+
} from "sveld/browser";
|
|
587
|
+
|
|
588
|
+
const parser = new ComponentParser();
|
|
589
|
+
const moduleName = "Button";
|
|
590
|
+
const filePath = "Button.svelte";
|
|
591
|
+
const parsed = parser.parseSvelteComponent(source, { moduleName, filePath });
|
|
592
|
+
|
|
593
|
+
// `parseSvelteComponent` returns component metadata only; add `moduleName`
|
|
594
|
+
// and `filePath` yourself to match the `ComponentDocApi` shape the writers expect.
|
|
595
|
+
const component = { ...parsed, moduleName, filePath: asNormalizedPath(filePath) };
|
|
596
|
+
const components = new Map([[moduleName, component]]);
|
|
597
|
+
|
|
598
|
+
// JSON
|
|
599
|
+
const jsonDoc = buildComponentApiDocument(components);
|
|
600
|
+
|
|
601
|
+
// Markdown
|
|
602
|
+
const markdown = writeMarkdownCore(components);
|
|
603
|
+
|
|
604
|
+
// TypeScript definitions (per component)
|
|
605
|
+
const dts = writeTsDefinition(jsonDoc.components[0]);
|
|
606
|
+
|
|
607
|
+
// Custom Elements Manifest
|
|
608
|
+
const cem = buildCustomElementsManifest(components, {
|
|
609
|
+
resolveModulePath: (component) => component.filePath,
|
|
610
|
+
});
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
`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.
|
|
614
|
+
|
|
615
|
+
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.
|
|
616
|
+
|
|
459
617
|
### Config File
|
|
460
618
|
|
|
461
619
|
Put a `sveld.config.js`, `sveld.config.mjs`, or `sveld.config.ts` at your project root to set defaults for the CLI and the programmatic `sveld()` API.
|
|
@@ -479,17 +637,34 @@ CLI flags > config file > `package.json#svelte` inference / defaults
|
|
|
479
637
|
|
|
480
638
|
With the config above, `npx sveld --json` keeps `glob` and `markdown` from the file. A CLI flag overrides the same key in the config.
|
|
481
639
|
|
|
640
|
+
`strict`, `reportDiagnostics`, and `check` are valid config keys too — not just CLI flags or `sveld()` options — and follow the same precedence: a CLI flag (or an option passed to `sveld()`) overrides the same key set in the config file.
|
|
641
|
+
|
|
642
|
+
```js
|
|
643
|
+
// sveld.config.js
|
|
644
|
+
export default {
|
|
645
|
+
json: true,
|
|
646
|
+
strict: true,
|
|
647
|
+
check: "snapshots/COMPONENT_API.json",
|
|
648
|
+
};
|
|
649
|
+
```
|
|
650
|
+
|
|
482
651
|
A bad config (syntax error, throws at load time, or no default-export object) fails with an error that names the file.
|
|
483
652
|
|
|
484
653
|
### Publishing to NPM
|
|
485
654
|
|
|
486
|
-
TypeScript definitions land in the `types` folder by default.
|
|
655
|
+
TypeScript definitions land in the `types` folder by default. Point consumers at them with an `exports` map, and include that folder in `package.json` when you publish to npm.
|
|
487
656
|
|
|
488
657
|
```diff
|
|
489
658
|
{
|
|
490
659
|
"svelte": "./src/index.js",
|
|
660
|
+
+ "exports": {
|
|
661
|
+
+ ".": {
|
|
662
|
+
+ "types": "./types/index.d.ts",
|
|
663
|
+
+ "svelte": "./src/index.js",
|
|
664
|
+
+ "default": "./lib/index.mjs"
|
|
665
|
+
+ }
|
|
666
|
+
+ },
|
|
491
667
|
"main": "./lib/index.mjs",
|
|
492
|
-
+ "types": "./types/index.d.ts",
|
|
493
668
|
"files": [
|
|
494
669
|
"src",
|
|
495
670
|
"lib",
|
|
@@ -498,26 +673,36 @@ TypeScript definitions land in the `types` folder by default. Include that folde
|
|
|
498
673
|
}
|
|
499
674
|
```
|
|
500
675
|
|
|
676
|
+
The `svelte` condition lets bundlers that understand it (Vite, Rollup, webpack via `svelte-loader`) resolve straight to source; `types` and `default` cover TypeScript and everything else. Keep the top-level `"svelte"` field too — older tooling that predates conditional exports still reads it directly.
|
|
677
|
+
|
|
501
678
|
## Available Options
|
|
502
679
|
|
|
503
680
|
### Plugin Options
|
|
504
681
|
|
|
505
|
-
- **`entry`** (string, optional): Specify the entry point to uncompiled Svelte source. If not provided, sveld
|
|
682
|
+
- **`entry`** (string, optional): Specify the entry point to uncompiled Svelte source. If not provided, sveld uses the `"svelte"` field from `package.json`.
|
|
506
683
|
- **`glob`** (boolean, optional): Enable glob mode to analyze all `*.svelte` files.
|
|
507
684
|
- **`documentExports`** (boolean, optional): Include consts, functions, and types from the entry barrel in JSON (`exports`) and Markdown ("Exports"). Off by default. See [Documenting Entry Exports](#documenting-entry-exports).
|
|
508
685
|
- **`types`** (boolean, optional, default: `true`): Generate TypeScript definitions.
|
|
509
|
-
|
|
686
|
+
<<<<<<< HEAD
|
|
687
|
+
- **`typesOptions`** (object, optional): Options for TypeScript definition generation, including `outDir`, `preamble`, and `format`.
|
|
688
|
+
- **`format`** (`"class"` | `"component"`, optional, default: `"class"`): `.d.ts` output shape. `"class"` extends `SvelteComponentTyped`; `"component"` emits the Svelte 5 `Component` type. Also available as `--types-format`. See [`.d.ts` output format](#dts-output-format-typesoptionsformat).
|
|
689
|
+
=======
|
|
690
|
+
- **`typesOptions`** (object, optional): Options for TypeScript definition generation, including `outDir` and `preamble`.
|
|
691
|
+
>>>>>>> 0724225 (feat(writer)!: remove prettier entirely)
|
|
510
692
|
- **`json`** (boolean, optional): Generate component documentation in JSON format.
|
|
511
693
|
- **`jsonOptions`** (object, optional): Options for JSON output.
|
|
512
694
|
- **`markdown`** (boolean, optional): Generate component documentation in Markdown format.
|
|
513
695
|
- **`markdownOptions`** (object, optional): Options for Markdown output.
|
|
696
|
+
- **`customElements`** (boolean, optional): Generate a [Custom Elements Manifest](#custom-elements-manifest) (`custom-elements.json`). Also available as the `--custom-elements` CLI flag.
|
|
697
|
+
- **`customElementsOptions`** (object, optional): Options for Custom Elements Manifest output, including `outFile`.
|
|
514
698
|
- **`watch`** (boolean, optional, default: `false`): Regenerate output incrementally when `.svelte` source changes during `vite dev` / `vite build --watch`. Only the changed component and the components that depend on it via [`@extendProps`](#extendprops) / `@extends` are re-parsed, rather than rebuilding every component. Without this option, the plugin only runs during `vite build`.
|
|
515
699
|
- **`failFast`** (boolean, optional, default: `false`): Abort the entire run when a single component fails to parse. By default, parse failures are collected as diagnostics (and reported to `stderr`) so the remaining components still emit their output. Also available as the `--fail-fast` CLI flag.
|
|
516
|
-
- **`resolveTypes`** (boolean, optional, default: `false`): Load the TypeScript program to expand opaque imported whole-object `$props()` types into JSON. See [Opt-in semantic resolution](#opt-in-semantic-resolution-resolvetypes).
|
|
517
|
-
- **`cache`** (boolean | string, optional, default: `
|
|
518
|
-
- **`checkExamples`** (boolean, optional, default: `false`): Run plain TS/JS `@example` blocks through the TypeScript program. Broken ones get an `example-compile-error` diagnostic. See [Compile-checked `@example` blocks](#compile-checked-example-blocks-checkexamples).
|
|
700
|
+
- **`resolveTypes`** (boolean, optional, default: `false`): Load the TypeScript program to expand opaque imported whole-object `$props()` types into JSON. Also available as `--resolve-types` (`--resolveTypes` remains as a deprecated alias). See [Opt-in semantic resolution](#opt-in-semantic-resolution-resolvetypes).
|
|
701
|
+
- **`cache`** (boolean | string, optional, default: `true`): Write parsed component output to disk and skip re-parsing unchanged files on later runs. On by default, writing to `node_modules/.cache/sveld/parse-cache.json`; a string sets a custom path; pass `false` to disable. Also available as `--cache` / `--cache=<path>` / `--cache=false`. See [Persistent parse cache](#persistent-parse-cache-cache).
|
|
702
|
+
- **`checkExamples`** (boolean, optional, default: `false`): Run plain TS/JS `@example` blocks through the TypeScript program. Broken ones get an `example-compile-error` diagnostic. Also available as `--check-examples` (`--checkExamples` remains as a deprecated alias). See [Compile-checked `@example` blocks](#compile-checked-example-blocks-checkexamples).
|
|
519
703
|
- **`reportDiagnostics`** (boolean, optional, default: `false`): Print unresolved-type diagnostics to stderr (CLI) or `console.warn` (programmatic API). Also available as `--report-diagnostics`. See [Type inference diagnostics](#type-inference-diagnostics).
|
|
520
704
|
- **`strict`** (boolean, optional, default: `false`): Exit with code `1` when diagnostics exist. Implies `reportDiagnostics`. Also available as `--strict`. See [Type inference diagnostics](#type-inference-diagnostics).
|
|
705
|
+
- **`check`** (boolean | string, optional, default: `false`): Diff the parsed component API against a committed snapshot and assign a semver bump to each change. `true` uses the `json` writer's `outFile` (or `COMPONENT_API.json`); a string sets a custom snapshot path. Also available as `--check` / `--check=<path>`. On the CLI this exits `1` on a breaking change; from `sveld()` it's returned on `SveldResult.check` for you to act on. See [CI: API-drift checks (`--check`)](#ci-api-drift-checks---check).
|
|
521
706
|
|
|
522
707
|
By default, only TypeScript definitions are generated.
|
|
523
708
|
|
|
@@ -559,7 +744,7 @@ JSON adds `exports` and `totalExports`. Markdown adds an "Exports" section. Each
|
|
|
559
744
|
## JSON Output
|
|
560
745
|
|
|
561
746
|
When `json: true` is enabled, `sveld` emits a `COMPONENT_API.json` file with schema and generator metadata plus the parsed
|
|
562
|
-
component API.
|
|
747
|
+
component API. For stable output, generated `events` arrays are emitted in deterministic sorted order.
|
|
563
748
|
|
|
564
749
|
The JSON Schema lives on GitHub ([path to file](https://github.com/carbon-design-system/sveld/blob/main/schema/component-api.schema.json), [raw URL](https://raw.githubusercontent.com/carbon-design-system/sveld/main/schema/component-api.schema.json)). Use it to validate generated `COMPONENT_API.json` files. Optional fields may be missing when the parser has no stable source for that metadata.
|
|
565
750
|
|
|
@@ -615,6 +800,7 @@ interface ComponentDocApi {
|
|
|
615
800
|
componentComment?: string;
|
|
616
801
|
componentCommentSource?: SourceRange;
|
|
617
802
|
contexts?: ComponentContext[];
|
|
803
|
+
customElementTag?: string;
|
|
618
804
|
}
|
|
619
805
|
|
|
620
806
|
interface ComponentProp {
|
|
@@ -681,6 +867,47 @@ Prop metadata is additive and keeps the older public fields:
|
|
|
681
867
|
- `value` remains the raw default expression string. `defaultValue` adds structured metadata with the same raw expression, a coarse `kind`, and a parsed `value` only for JSON-safe literals, arrays, and plain objects. `sveld` does not evaluate arbitrary code.
|
|
682
868
|
- `bindable: true` is emitted only for props explicitly declared with Svelte 5 `$bindable(...)`. Missing `bindable` should be treated as false.
|
|
683
869
|
|
|
870
|
+
## Custom Elements Manifest
|
|
871
|
+
|
|
872
|
+
Set `customElements: true` to emit a [Custom Elements Manifest](https://github.com/webcomponents/custom-elements-manifest) (`custom-elements.json`, `schemaVersion: "1.0.0"`). This is the interchange format the web-components ecosystem standardized on: Storybook autodocs, VS Code/JetBrains HTML data, and other CEM-aware tooling can all read it directly.
|
|
873
|
+
|
|
874
|
+
```diff
|
|
875
|
+
sveld({
|
|
876
|
+
+ customElements: true,
|
|
877
|
+
})
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
- **`customElements`** (boolean, optional): Generate `custom-elements.json`.
|
|
881
|
+
- **`customElementsOptions.outFile`** (string, optional, default: `"custom-elements.json"`): Override the output path.
|
|
882
|
+
- Also available as the `--custom-elements` CLI flag.
|
|
883
|
+
|
|
884
|
+
Each exported component becomes one `javascript-module` with a class declaration:
|
|
885
|
+
|
|
886
|
+
- **Members** — every prop becomes a `ClassField` (`name`, `type.text`, `default`, `description`, `deprecated`).
|
|
887
|
+
- **Attributes** — derived conservatively from props: only props with a bare primitive type (`string`, `number`, or `boolean`) become attributes, using the same default name Svelte's custom-element runtime uses (`prop.toLowerCase()`, unless the tool's own `attribute` override applies). Props whose lowercased name collides with another prop are dropped from `attributes` on both sides, since which one wins at runtime is ambiguous. Complex types (arrays, objects, unions, custom types) never become attributes.
|
|
888
|
+
- **Events** — dispatched events (`createEventDispatcher()`, and `$host().dispatchEvent(...)` from inside a custom element) become `{ name, type: { text: "CustomEvent<...>" } }`. Forwarded (`on:click`) events are left out, since they aren't dispatched by the component's own class.
|
|
889
|
+
- **Slots** — named and default slots, with descriptions. The default slot's `name` is `""`, matching the CEM convention.
|
|
890
|
+
|
|
891
|
+
When a component sets `<svelte:options customElement="x-foo" />` (or the object form, `<svelte:options customElement={{ tag: "x-foo" }} />`), its declaration gets `tagName: "x-foo"` and `customElement: true`, and the module's `exports` include a `custom-element-definition` export alongside the plain `js` export.
|
|
892
|
+
|
|
893
|
+
Components without `customElement` still emit a plain class declaration (no `tagName`/`customElement`) — useful for documenting the class shape even before it's compiled as a custom element, but the manifest is most useful for `customElement`-compiled builds, where downstream tooling can resolve `tagName`, `attributes`, and `events` for actual custom-element usage.
|
|
894
|
+
|
|
895
|
+
### Consuming the manifest
|
|
896
|
+
|
|
897
|
+
Most tools discover `custom-elements.json` through a `customElements` field in `package.json`, pointing at the generated file:
|
|
898
|
+
|
|
899
|
+
```json
|
|
900
|
+
{
|
|
901
|
+
"customElements": "custom-elements.json"
|
|
902
|
+
}
|
|
903
|
+
```
|
|
904
|
+
|
|
905
|
+
With that in place:
|
|
906
|
+
|
|
907
|
+
- The [VS Code custom elements extension](https://marketplace.visualstudio.com/items?itemName=BendingSpoons.vscode-custom-elements) and JetBrains IDEs pick it up automatically, giving tag name, attribute, and slot completion/hover in HTML and Svelte templates.
|
|
908
|
+
- [Storybook](https://storybook.js.org/docs/api/doc-blocks/doc-block-argtypes#extracting-argtypes) for web components reads the manifest to auto-generate `argTypes` (controls, docs tables) for `customElement`-compiled components, once you point it at the file (e.g. `setCustomElementsManifest` from `@storybook/web-components`, or `customElements: "custom-elements.json"` in `.storybook/main.js`).
|
|
909
|
+
- Any other tool built against the [Custom Elements Manifest spec](https://github.com/webcomponents/custom-elements-manifest) (API viewers, doc generators, linters) can read the file directly without sveld-specific integration.
|
|
910
|
+
|
|
684
911
|
## API Reference
|
|
685
912
|
|
|
686
913
|
### `reactive`
|
|
@@ -730,11 +957,9 @@ Generated JSON includes `"binding": "readonly"` or `"binding": "writable"` for a
|
|
|
730
957
|
|
|
731
958
|
This is documentation only. Generated `.svelte.d.ts` prop types do not change. TypeScript cannot express Svelte binding direction reliably.
|
|
732
959
|
|
|
733
|
-
For stable output, generated `events` arrays are emitted in deterministic sorted order.
|
|
734
|
-
|
|
735
960
|
### `@type`
|
|
736
961
|
|
|
737
|
-
Without a `@type` annotation, `sveld`
|
|
962
|
+
Without a `@type` annotation, `sveld` infers the primitive type for a prop:
|
|
738
963
|
|
|
739
964
|
```js
|
|
740
965
|
export let kind = "primary";
|
|
@@ -763,8 +988,6 @@ For `lang="ts"` components, prefer native TypeScript annotations when you alread
|
|
|
763
988
|
|
|
764
989
|
**Example:**
|
|
765
990
|
|
|
766
|
-
**Svelte 5 Runes:**
|
|
767
|
-
|
|
768
991
|
```svelte
|
|
769
992
|
<script>
|
|
770
993
|
let {
|
|
@@ -784,7 +1007,8 @@ For `lang="ts"` components, prefer native TypeScript annotations when you alread
|
|
|
784
1007
|
|
|
785
1008
|
For runes components with multiple destructured props, put JSDoc on the property you want to document. A declaration-level block is a fallback when the destructure exposes a single public prop.
|
|
786
1009
|
|
|
787
|
-
|
|
1010
|
+
<details>
|
|
1011
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
788
1012
|
|
|
789
1013
|
```svelte
|
|
790
1014
|
<script>
|
|
@@ -802,6 +1026,8 @@ For runes components with multiple destructured props, put JSDoc on the property
|
|
|
802
1026
|
</script>
|
|
803
1027
|
```
|
|
804
1028
|
|
|
1029
|
+
</details>
|
|
1030
|
+
|
|
805
1031
|
#### Importing types
|
|
806
1032
|
|
|
807
1033
|
`sveld` supports TypeScript's [`import(...)` type syntax](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#import-types), so a `@type` or `@typedef` can reference a type from another module without a top-level `import`. The expression is copied verbatim into the generated `.d.ts` and resolves the same way as hand-written TypeScript:
|
|
@@ -1012,8 +1238,6 @@ The `@typedef` tag defines a shared type used multiple times in a component. All
|
|
|
1012
1238
|
|
|
1013
1239
|
**Example:**
|
|
1014
1240
|
|
|
1015
|
-
**Svelte 5 Runes:**
|
|
1016
|
-
|
|
1017
1241
|
```svelte
|
|
1018
1242
|
<script>
|
|
1019
1243
|
/**
|
|
@@ -1030,7 +1254,8 @@ The `@typedef` tag defines a shared type used multiple times in a component. All
|
|
|
1030
1254
|
</script>
|
|
1031
1255
|
```
|
|
1032
1256
|
|
|
1033
|
-
|
|
1257
|
+
<details>
|
|
1258
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1034
1259
|
|
|
1035
1260
|
```svelte
|
|
1036
1261
|
<script>
|
|
@@ -1047,6 +1272,8 @@ The `@typedef` tag defines a shared type used multiple times in a component. All
|
|
|
1047
1272
|
</script>
|
|
1048
1273
|
```
|
|
1049
1274
|
|
|
1275
|
+
</details>
|
|
1276
|
+
|
|
1050
1277
|
#### Using `@property` for complex typedefs
|
|
1051
1278
|
|
|
1052
1279
|
For complex object types, use `@property` to document individual fields. That gives per-property tooltips in the IDE.
|
|
@@ -1063,8 +1290,6 @@ For complex object types, use `@property` to document individual fields. That gi
|
|
|
1063
1290
|
|
|
1064
1291
|
**Example:**
|
|
1065
1292
|
|
|
1066
|
-
**Svelte 5 Runes:**
|
|
1067
|
-
|
|
1068
1293
|
```svelte
|
|
1069
1294
|
<script>
|
|
1070
1295
|
/**
|
|
@@ -1080,7 +1305,8 @@ For complex object types, use `@property` to document individual fields. That gi
|
|
|
1080
1305
|
</script>
|
|
1081
1306
|
```
|
|
1082
1307
|
|
|
1083
|
-
|
|
1308
|
+
<details>
|
|
1309
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1084
1310
|
|
|
1085
1311
|
```svelte
|
|
1086
1312
|
<script>
|
|
@@ -1097,6 +1323,10 @@ For complex object types, use `@property` to document individual fields. That gi
|
|
|
1097
1323
|
</script>
|
|
1098
1324
|
```
|
|
1099
1325
|
|
|
1326
|
+
</details>
|
|
1327
|
+
|
|
1328
|
+
Output is identical for both syntax modes.
|
|
1329
|
+
|
|
1100
1330
|
Output:
|
|
1101
1331
|
|
|
1102
1332
|
```ts
|
|
@@ -1134,8 +1364,6 @@ Use square brackets for optional properties, per JSDoc. Default values use `[pro
|
|
|
1134
1364
|
|
|
1135
1365
|
**Example:**
|
|
1136
1366
|
|
|
1137
|
-
**Svelte 5 Runes:**
|
|
1138
|
-
|
|
1139
1367
|
```svelte
|
|
1140
1368
|
<script>
|
|
1141
1369
|
/**
|
|
@@ -1152,7 +1380,8 @@ Use square brackets for optional properties, per JSDoc. Default values use `[pro
|
|
|
1152
1380
|
</script>
|
|
1153
1381
|
```
|
|
1154
1382
|
|
|
1155
|
-
|
|
1383
|
+
<details>
|
|
1384
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1156
1385
|
|
|
1157
1386
|
```svelte
|
|
1158
1387
|
<script>
|
|
@@ -1170,6 +1399,10 @@ Use square brackets for optional properties, per JSDoc. Default values use `[pro
|
|
|
1170
1399
|
</script>
|
|
1171
1400
|
```
|
|
1172
1401
|
|
|
1402
|
+
</details>
|
|
1403
|
+
|
|
1404
|
+
Output is identical for both syntax modes.
|
|
1405
|
+
|
|
1173
1406
|
Output:
|
|
1174
1407
|
|
|
1175
1408
|
```ts
|
|
@@ -1459,8 +1692,6 @@ Use it for callback props when you do not want inline function type syntax.
|
|
|
1459
1692
|
|
|
1460
1693
|
**Example:**
|
|
1461
1694
|
|
|
1462
|
-
**Svelte 5 Runes:**
|
|
1463
|
-
|
|
1464
1695
|
```svelte
|
|
1465
1696
|
<script>
|
|
1466
1697
|
/**
|
|
@@ -1476,7 +1707,8 @@ Use it for callback props when you do not want inline function type syntax.
|
|
|
1476
1707
|
</script>
|
|
1477
1708
|
```
|
|
1478
1709
|
|
|
1479
|
-
|
|
1710
|
+
<details>
|
|
1711
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1480
1712
|
|
|
1481
1713
|
```svelte
|
|
1482
1714
|
<script>
|
|
@@ -1493,6 +1725,10 @@ Use it for callback props when you do not want inline function type syntax.
|
|
|
1493
1725
|
</script>
|
|
1494
1726
|
```
|
|
1495
1727
|
|
|
1728
|
+
</details>
|
|
1729
|
+
|
|
1730
|
+
Output is identical for both syntax modes.
|
|
1731
|
+
|
|
1496
1732
|
Output:
|
|
1497
1733
|
|
|
1498
1734
|
```ts
|
|
@@ -1550,8 +1786,6 @@ Omit the `slot-name` to type the default slot.
|
|
|
1550
1786
|
|
|
1551
1787
|
**Example:**
|
|
1552
1788
|
|
|
1553
|
-
**Svelte 5 Runes:**
|
|
1554
|
-
|
|
1555
1789
|
```svelte
|
|
1556
1790
|
<script>
|
|
1557
1791
|
/**
|
|
@@ -1573,7 +1807,8 @@ Omit the `slot-name` to type the default slot.
|
|
|
1573
1807
|
</p>
|
|
1574
1808
|
```
|
|
1575
1809
|
|
|
1576
|
-
|
|
1810
|
+
<details>
|
|
1811
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1577
1812
|
|
|
1578
1813
|
```svelte
|
|
1579
1814
|
<script>
|
|
@@ -1596,6 +1831,8 @@ Omit the `slot-name` to type the default slot.
|
|
|
1596
1831
|
</p>
|
|
1597
1832
|
```
|
|
1598
1833
|
|
|
1834
|
+
</details>
|
|
1835
|
+
|
|
1599
1836
|
#### Extra JSDoc tags before `@slot`
|
|
1600
1837
|
|
|
1601
1838
|
Tags such as `@example`, `@see`, or `@since` that appear after the prose description and before the `@slot` / `@snippet` line are copied into generated `.d.ts` files. The emitted JSDoc above each slot's snippet prop (and the traditional `SlotDefs` shape) lists the description, then those tags in source order. The same entries appear in JSON as `tags: [{ "name", "body" }, ...]`.
|
|
@@ -1749,8 +1986,6 @@ Use `null` as the value if no event detail is provided.
|
|
|
1749
1986
|
|
|
1750
1987
|
**Example:**
|
|
1751
1988
|
|
|
1752
|
-
**Svelte 5 Runes:**
|
|
1753
|
-
|
|
1754
1989
|
```svelte
|
|
1755
1990
|
<script>
|
|
1756
1991
|
/**
|
|
@@ -1785,7 +2020,8 @@ Use `null` as the value if no event detail is provided.
|
|
|
1785
2020
|
</script>
|
|
1786
2021
|
```
|
|
1787
2022
|
|
|
1788
|
-
|
|
2023
|
+
<details>
|
|
2024
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1789
2025
|
|
|
1790
2026
|
```svelte
|
|
1791
2027
|
<script>
|
|
@@ -1805,6 +2041,10 @@ Use `null` as the value if no event detail is provided.
|
|
|
1805
2041
|
</script>
|
|
1806
2042
|
```
|
|
1807
2043
|
|
|
2044
|
+
</details>
|
|
2045
|
+
|
|
2046
|
+
Output is identical for both syntax modes.
|
|
2047
|
+
|
|
1808
2048
|
Output:
|
|
1809
2049
|
|
|
1810
2050
|
```ts
|
|
@@ -1837,8 +2077,6 @@ This is the idiomatic way to describe each field of an event detail. An inline o
|
|
|
1837
2077
|
|
|
1838
2078
|
**Example:**
|
|
1839
2079
|
|
|
1840
|
-
**Svelte 5 Runes:**
|
|
1841
|
-
|
|
1842
2080
|
```svelte
|
|
1843
2081
|
<script>
|
|
1844
2082
|
/**
|
|
@@ -1865,7 +2103,8 @@ This is the idiomatic way to describe each field of an event detail. An inline o
|
|
|
1865
2103
|
<button type="button" onclick={handleSubmit}>Submit</button>
|
|
1866
2104
|
```
|
|
1867
2105
|
|
|
1868
|
-
|
|
2106
|
+
<details>
|
|
2107
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1869
2108
|
|
|
1870
2109
|
```svelte
|
|
1871
2110
|
<script>
|
|
@@ -1895,6 +2134,10 @@ This is the idiomatic way to describe each field of an event detail. An inline o
|
|
|
1895
2134
|
<button type="button" on:click={handleSubmit}>Submit</button>
|
|
1896
2135
|
```
|
|
1897
2136
|
|
|
2137
|
+
</details>
|
|
2138
|
+
|
|
2139
|
+
Output is identical for both syntax modes.
|
|
2140
|
+
|
|
1898
2141
|
Output:
|
|
1899
2142
|
|
|
1900
2143
|
```ts
|
|
@@ -1921,8 +2164,6 @@ Like typedefs, you can mark event detail properties as optional with square brac
|
|
|
1921
2164
|
|
|
1922
2165
|
**Example:**
|
|
1923
2166
|
|
|
1924
|
-
**Svelte 5 Runes:**
|
|
1925
|
-
|
|
1926
2167
|
```svelte
|
|
1927
2168
|
<script>
|
|
1928
2169
|
/**
|
|
@@ -1953,7 +2194,8 @@ Like typedefs, you can mark event detail properties as optional with square brac
|
|
|
1953
2194
|
<button type="button" onclick={throwSnowball}>Throw</button>
|
|
1954
2195
|
```
|
|
1955
2196
|
|
|
1956
|
-
|
|
2197
|
+
<details>
|
|
2198
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
1957
2199
|
|
|
1958
2200
|
```svelte
|
|
1959
2201
|
<script>
|
|
@@ -1985,6 +2227,10 @@ Like typedefs, you can mark event detail properties as optional with square brac
|
|
|
1985
2227
|
<button type="button" on:click={throwSnowball}>Throw</button>
|
|
1986
2228
|
```
|
|
1987
2229
|
|
|
2230
|
+
</details>
|
|
2231
|
+
|
|
2232
|
+
Output is identical for both syntax modes.
|
|
2233
|
+
|
|
1988
2234
|
Output:
|
|
1989
2235
|
|
|
1990
2236
|
```ts
|
|
@@ -2123,8 +2369,6 @@ Anything else (dynamic identifiers, template interpolation, other function calls
|
|
|
2123
2369
|
|
|
2124
2370
|
**Modal.svelte**
|
|
2125
2371
|
|
|
2126
|
-
**Svelte 5 Runes:**
|
|
2127
|
-
|
|
2128
2372
|
```svelte
|
|
2129
2373
|
<script>
|
|
2130
2374
|
import { setContext } from "svelte";
|
|
@@ -2155,7 +2399,8 @@ Anything else (dynamic identifiers, template interpolation, other function calls
|
|
|
2155
2399
|
</div>
|
|
2156
2400
|
```
|
|
2157
2401
|
|
|
2158
|
-
|
|
2402
|
+
<details>
|
|
2403
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
2159
2404
|
|
|
2160
2405
|
```svelte
|
|
2161
2406
|
<script>
|
|
@@ -2185,6 +2430,10 @@ Anything else (dynamic identifiers, template interpolation, other function calls
|
|
|
2185
2430
|
</div>
|
|
2186
2431
|
```
|
|
2187
2432
|
|
|
2433
|
+
</details>
|
|
2434
|
+
|
|
2435
|
+
Output is identical for both syntax modes.
|
|
2436
|
+
|
|
2188
2437
|
**Generated TypeScript definition:**
|
|
2189
2438
|
|
|
2190
2439
|
```ts
|
|
@@ -2294,7 +2543,7 @@ There are several ways to type contexts:
|
|
|
2294
2543
|
|
|
2295
2544
|
#### Notes
|
|
2296
2545
|
|
|
2297
|
-
- Context keys must be string
|
|
2546
|
+
- 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. Dynamic expressions (runtime identifiers, template interpolation, other function calls) are skipped with a warning.
|
|
2298
2547
|
- Variables passed to `setContext` should have JSDoc `@type` annotations for accurate types
|
|
2299
2548
|
- The generated type name follows the pattern: `{PascalCase}Context`. Separators (hyphens, underscores, dots, colons, slashes, spaces) are stripped and each segment is capitalized:
|
|
2300
2549
|
| Context Key | Generated Type Name |
|
|
@@ -2328,8 +2577,6 @@ Use `@restProps` to name the element tags `$$restProps` is forwarded to.
|
|
|
2328
2577
|
|
|
2329
2578
|
**Example:**
|
|
2330
2579
|
|
|
2331
|
-
**Svelte 5 Runes:**
|
|
2332
|
-
|
|
2333
2580
|
```svelte
|
|
2334
2581
|
<script>
|
|
2335
2582
|
import Button from "./Button.svelte";
|
|
@@ -2347,7 +2594,8 @@ Use `@restProps` to name the element tags `$$restProps` is forwarded to.
|
|
|
2347
2594
|
{/if}
|
|
2348
2595
|
```
|
|
2349
2596
|
|
|
2350
|
-
|
|
2597
|
+
<details>
|
|
2598
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
2351
2599
|
|
|
2352
2600
|
```svelte
|
|
2353
2601
|
<script>
|
|
@@ -2364,6 +2612,8 @@ Use `@restProps` to name the element tags `$$restProps` is forwarded to.
|
|
|
2364
2612
|
{/if}
|
|
2365
2613
|
```
|
|
2366
2614
|
|
|
2615
|
+
</details>
|
|
2616
|
+
|
|
2367
2617
|
### `@extendProps`
|
|
2368
2618
|
|
|
2369
2619
|
When a component wraps another, use `@extendProps` to extend generated props.
|
|
@@ -2390,14 +2640,15 @@ import Button from "./Button.svelte";
|
|
|
2390
2640
|
|
|
2391
2641
|
### `@template`
|
|
2392
2642
|
|
|
2393
|
-
Svelte supports defining generics via the [`generics` attribute](https://svelte.dev/docs/svelte/typescript) on the script tag, but this requires `lang="ts"
|
|
2643
|
+
Svelte supports defining generics via the [`generics` attribute](https://svelte.dev/docs/svelte/typescript) on the script tag, but this requires `lang="ts"`:
|
|
2394
2644
|
|
|
2395
2645
|
```svelte
|
|
2396
|
-
<!-- Requires lang="ts" -->
|
|
2397
2646
|
<script lang="ts" generics="Row extends DataTableRow = any"></script>
|
|
2398
2647
|
```
|
|
2399
2648
|
|
|
2400
|
-
Because `sveld` targets JavaScript-only usage as a baseline,
|
|
2649
|
+
`sveld` reads the `generics` attribute directly, and it's the recommended way to declare generics for `lang="ts"` components. Because `sveld` also targets JavaScript-only usage as a baseline, plain JS (or JS-with-JSDoc) components instead use the standard JSDoc `@template` tag; `@generics` is also supported as an alias.
|
|
2650
|
+
|
|
2651
|
+
**Precedence:** if a component declares generics both ways, the `generics` attribute wins — it's the compiler-checked source of truth — and the `@generics`/`@template` tag is reported as a `syntax-skipped` diagnostic rather than silently dropped. The attribute is invalid without `lang="ts"`; if present on a plain-JS script, sveld reports `syntax-skipped` and ignores it rather than guessing.
|
|
2401
2652
|
|
|
2402
2653
|
**Signature:** Uses standard [JSDoc `@template` syntax](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#template):
|
|
2403
2654
|
|
|
@@ -2417,8 +2668,6 @@ Because `sveld` targets JavaScript-only usage as a baseline, generics use the st
|
|
|
2417
2668
|
|
|
2418
2669
|
**Component example:**
|
|
2419
2670
|
|
|
2420
|
-
**Svelte 5 Runes:**
|
|
2421
|
-
|
|
2422
2671
|
```svelte
|
|
2423
2672
|
<script>
|
|
2424
2673
|
/**
|
|
@@ -2440,7 +2689,8 @@ Because `sveld` targets JavaScript-only usage as a baseline, generics use the st
|
|
|
2440
2689
|
{@render children?.({ headers, rows })}
|
|
2441
2690
|
```
|
|
2442
2691
|
|
|
2443
|
-
|
|
2692
|
+
<details>
|
|
2693
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
2444
2694
|
|
|
2445
2695
|
```svelte
|
|
2446
2696
|
<script>
|
|
@@ -2461,6 +2711,10 @@ Because `sveld` targets JavaScript-only usage as a baseline, generics use the st
|
|
|
2461
2711
|
<slot {headers} {rows} />
|
|
2462
2712
|
```
|
|
2463
2713
|
|
|
2714
|
+
</details>
|
|
2715
|
+
|
|
2716
|
+
Output is identical for both syntax modes.
|
|
2717
|
+
|
|
2464
2718
|
Generated output looks like this:
|
|
2465
2719
|
|
|
2466
2720
|
```ts
|
|
@@ -2533,12 +2787,10 @@ For multiple generics, use a single `@generics` tag with comma-separated names:
|
|
|
2533
2787
|
|
|
2534
2788
|
The Svelte Language Server supports component-level comments through the following syntax: `<!-- @component [comment] -->`.
|
|
2535
2789
|
|
|
2536
|
-
`sveld`
|
|
2790
|
+
`sveld` copies these over to the exported default component in the TypeScript definition.
|
|
2537
2791
|
|
|
2538
2792
|
**Example:**
|
|
2539
2793
|
|
|
2540
|
-
**Svelte 5 Runes:**
|
|
2541
|
-
|
|
2542
2794
|
```svelte
|
|
2543
2795
|
<!-- @component
|
|
2544
2796
|
@example
|
|
@@ -2555,7 +2807,8 @@ The Svelte Language Server supports component-level comments through the followi
|
|
|
2555
2807
|
</button>
|
|
2556
2808
|
```
|
|
2557
2809
|
|
|
2558
|
-
|
|
2810
|
+
<details>
|
|
2811
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
2559
2812
|
|
|
2560
2813
|
```svelte
|
|
2561
2814
|
<!-- @component
|
|
@@ -2569,6 +2822,10 @@ The Svelte Language Server supports component-level comments through the followi
|
|
|
2569
2822
|
</button>
|
|
2570
2823
|
```
|
|
2571
2824
|
|
|
2825
|
+
</details>
|
|
2826
|
+
|
|
2827
|
+
Output is identical for both syntax modes.
|
|
2828
|
+
|
|
2572
2829
|
Output:
|
|
2573
2830
|
|
|
2574
2831
|
```ts
|
|
@@ -2604,8 +2861,6 @@ Exported functions and consts become accessor props in generated TypeScript defi
|
|
|
2604
2861
|
|
|
2605
2862
|
**Example:**
|
|
2606
2863
|
|
|
2607
|
-
**Svelte 5 Runes:**
|
|
2608
|
-
|
|
2609
2864
|
```svelte
|
|
2610
2865
|
<script>
|
|
2611
2866
|
/**
|
|
@@ -2649,7 +2904,8 @@ Exported functions and consts become accessor props in generated TypeScript defi
|
|
|
2649
2904
|
</div>
|
|
2650
2905
|
```
|
|
2651
2906
|
|
|
2652
|
-
|
|
2907
|
+
<details>
|
|
2908
|
+
<summary>Svelte 3/4 (legacy) syntax</summary>
|
|
2653
2909
|
|
|
2654
2910
|
```svelte
|
|
2655
2911
|
<script>
|
|
@@ -2688,6 +2944,10 @@ Exported functions and consts become accessor props in generated TypeScript defi
|
|
|
2688
2944
|
</script>
|
|
2689
2945
|
```
|
|
2690
2946
|
|
|
2947
|
+
</details>
|
|
2948
|
+
|
|
2949
|
+
Output is identical for both syntax modes.
|
|
2950
|
+
|
|
2691
2951
|
Output:
|
|
2692
2952
|
|
|
2693
2953
|
```ts
|
|
@@ -2723,6 +2983,14 @@ export default class Component extends SvelteComponentTyped<
|
|
|
2723
2983
|
|
|
2724
2984
|
When only `@param` tags are present without `@returns`, the return type defaults to `any`. When only `@returns` is present without `@param`, the function signature is `() => returnType`.
|
|
2725
2985
|
|
|
2986
|
+
## Troubleshooting
|
|
2987
|
+
|
|
2988
|
+
**A prop came out `any`.** Enable [`reportDiagnostics`](#type-inference-diagnostics) (or `strict` to fail CI) to see which props sveld couldn't infer, then tighten them with `@type` or a native TypeScript annotation.
|
|
2989
|
+
|
|
2990
|
+
**Generated types don't appear for consumers.** Check that the `types` folder is listed in `exports` and `files` in `package.json`. See [Publishing to NPM](#publishing-to-npm).
|
|
2991
|
+
|
|
2992
|
+
**Output differs in CI.** Commit `COMPONENT_API.json` and run [`--check`](#ci-api-drift-checks---check) in CI so API drift fails the build instead of silently diverging.
|
|
2993
|
+
|
|
2726
2994
|
## Contributing
|
|
2727
2995
|
|
|
2728
2996
|
See [contributing guidelines](CONTRIBUTING.md).
|