sveld 0.37.4 → 0.37.6
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 +62 -5
- package/lib/browser.d.ts +34 -1
- package/lib/browser.js +148 -148
- package/lib/chunk-9a8zmdck.js +1 -0
- package/lib/{chunk-nxa0q3f3.js → chunk-c2vdpk5t.js} +6 -6
- package/lib/chunk-escdydzn.js +6 -0
- package/lib/chunk-jsp9b7b6.js +331 -0
- package/lib/chunk-v0hbw81y.js +1 -0
- package/lib/{chunk-yzb9k33r.js → chunk-yqc5m8nm.js} +1 -1
- package/lib/cli-entry.js +1 -1
- package/lib/index.js +1 -1
- package/package.json +1 -1
- package/lib/chunk-49hdrj4n.js +0 -6
- package/lib/chunk-7e36grhy.js +0 -1
- package/lib/chunk-rftengvg.js +0 -331
- package/lib/chunk-w37f2cq2.js +0 -1
package/README.md
CHANGED
|
@@ -429,11 +429,13 @@ Every diagnostic carries a stable, namespaced `code` (`"sveld/<kind>"`) alongsid
|
|
|
429
429
|
| `sveld/context-any-type` | `warning` | Annotate the `setContext` value's declaration with `@type` or a native TypeScript type. |
|
|
430
430
|
| `sveld/slot-missing-type` | `warning` | Add the required `{Type}` annotation to the `@slot`/`@snippet` tag (e.g. `@slot {{}} name`); until then it falls back to `Record<string, never>`. |
|
|
431
431
|
| `sveld/event-no-source` | `warning` | Dispatch the event (`createEventDispatcher`/`dispatch`), forward it (`on:name`), or add a matching `on<Name>` callback prop; otherwise remove the stale `@event` tag. |
|
|
432
|
+
| `sveld/dispatch-escapes` | `warning` | The `createEventDispatcher()` result is passed to a function sveld can't follow: one that isn't imported from a local module, names an event with something other than a string literal, or passes the dispatcher on. Document the events it dispatches with `@event` tags. Add `@sveld-ignore sveld/dispatch-escapes` to the dispatcher's JSDoc once they're covered. |
|
|
432
433
|
| `sveld/example-compile-error` | `error` | Fix the `@example` TS/JS code block so it type-checks, or remove the broken example. |
|
|
433
434
|
| `sveld/example-syntax-error` | `error` | Fix the `@example` `svelte`/`html` markup so it parses, or remove the broken example. |
|
|
434
435
|
| `sveld/syntax-skipped` | `error` | Rewrite the flagged syntax in a form sveld can model (see the diagnostic's `message` for what was skipped). |
|
|
435
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. |
|
|
436
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. |
|
|
437
439
|
| `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>`. |
|
|
438
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. |
|
|
439
441
|
| `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. |
|
|
@@ -451,7 +453,7 @@ Every diagnostic carries a stable, namespaced `code` (`"sveld/<kind>"`) alongsid
|
|
|
451
453
|
|
|
452
454
|
#### Severity and `--strict=errors`
|
|
453
455
|
|
|
454
|
-
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`, `rest-props-unresolved`, `context-duplicate-key`, `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`). 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:
|
|
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`). 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:
|
|
455
457
|
|
|
456
458
|
```sh
|
|
457
459
|
npx sveld --json --strict=errors
|
|
@@ -481,7 +483,7 @@ export default defineConfig({
|
|
|
481
483
|
});
|
|
482
484
|
```
|
|
483
485
|
|
|
484
|
-
**Inline `@sveld-ignore <code>`**, on the same JSDoc comment as the prop, `@event` tag,
|
|
486
|
+
**Inline `@sveld-ignore <code>`**, on the same JSDoc comment as the prop, `@event` tag, context variable, or event dispatcher it applies to:
|
|
485
487
|
|
|
486
488
|
```svelte
|
|
487
489
|
<script>
|
|
@@ -2187,7 +2189,27 @@ Chained references are also resolved:
|
|
|
2187
2189
|
count?: number;
|
|
2188
2190
|
```
|
|
2189
2191
|
|
|
2190
|
-
Resolution follows up to 5 levels of indirection. Beyond that, the last resolved identifier name is used as the default value.
|
|
2192
|
+
Resolution follows up to 5 levels of indirection. Beyond that, the last resolved identifier name is used as the default value.
|
|
2193
|
+
|
|
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:
|
|
2195
|
+
|
|
2196
|
+
```svelte
|
|
2197
|
+
<script>
|
|
2198
|
+
// timing.js: export const TOOLTIP_LEAVE_DELAY_MS = 300;
|
|
2199
|
+
import { TOOLTIP_LEAVE_DELAY_MS } from "./timing.js";
|
|
2200
|
+
|
|
2201
|
+
export let leaveDelayMs = TOOLTIP_LEAVE_DELAY_MS;
|
|
2202
|
+
</script>
|
|
2203
|
+
```
|
|
2204
|
+
|
|
2205
|
+
```ts
|
|
2206
|
+
/**
|
|
2207
|
+
* @default 300
|
|
2208
|
+
*/
|
|
2209
|
+
leaveDelayMs?: number;
|
|
2210
|
+
```
|
|
2211
|
+
|
|
2212
|
+
Any other identifier that cannot be resolved (an `export let`, a computed value, a package import) is used as-is, and its type falls back to `any`.
|
|
2191
2213
|
|
|
2192
2214
|
When an explicit `@default` annotation is provided, it always takes precedence over the resolved value.
|
|
2193
2215
|
|
|
@@ -2679,6 +2701,16 @@ A description can wrap onto continuation lines, which run until the next tag. In
|
|
|
2679
2701
|
*/
|
|
2680
2702
|
```
|
|
2681
2703
|
|
|
2704
|
+
A `{type}` can wrap too. The text after its closing `}` and the name is the tag's own description, exactly as if the type fit on one line:
|
|
2705
|
+
|
|
2706
|
+
```js
|
|
2707
|
+
/**
|
|
2708
|
+
* @property {"ascending"
|
|
2709
|
+
* | "descending"} [dir] - The next sort direction,
|
|
2710
|
+
* reported regardless.
|
|
2711
|
+
*/
|
|
2712
|
+
```
|
|
2713
|
+
|
|
2682
2714
|
### `@callback`
|
|
2683
2715
|
|
|
2684
2716
|
The `@callback` tag defines a function type with `@param` and `@returns`, following the [TypeScript JSDoc `@callback` spec](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#callback). Like `@typedef`, callbacks are exported from the generated `.d.ts`.
|
|
@@ -2981,6 +3013,28 @@ In Svelte 5 runes components, callback props like `onclick` are props, not event
|
|
|
2981
3013
|
|
|
2982
3014
|
Use `null` as the value if no event detail is provided.
|
|
2983
3015
|
|
|
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 })`, it reads that function too and picks up the events it dispatches:
|
|
3017
|
+
|
|
3018
|
+
```js
|
|
3019
|
+
// dispatch-open-close.js
|
|
3020
|
+
export function createOpenCloseDispatcher(dispatch) {
|
|
3021
|
+
return (open) => dispatch(open ? "open" : "close");
|
|
3022
|
+
}
|
|
3023
|
+
```
|
|
3024
|
+
|
|
3025
|
+
```svelte
|
|
3026
|
+
<script>
|
|
3027
|
+
import { createEventDispatcher } from "svelte";
|
|
3028
|
+
import { createOpenCloseDispatcher } from "./dispatch-open-close.js";
|
|
3029
|
+
|
|
3030
|
+
const dispatch = createEventDispatcher();
|
|
3031
|
+
// Types `open` and `close` as `CustomEvent<null>`
|
|
3032
|
+
const notifyOpenChange = createOpenCloseDispatcher(dispatch);
|
|
3033
|
+
</script>
|
|
3034
|
+
```
|
|
3035
|
+
|
|
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 `any` otherwise, 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
|
+
|
|
2984
3038
|
**Signature:**
|
|
2985
3039
|
|
|
2986
3040
|
```js
|
|
@@ -3634,12 +3688,15 @@ The key becomes the `{PascalCase}Context` type name. `sveld` can resolve:
|
|
|
3634
3688
|
| Static template literal | `` setContext(`simple-modal`, …) `` | `SimpleModalContext` |
|
|
3635
3689
|
| `const`-bound string | `const KEY = "simple-modal";`<br>`setContext(KEY, …)` | `SimpleModalContext` |
|
|
3636
3690
|
| `Symbol()` / `Symbol.for()` | `setContext(Symbol("tabs"), …)` | `TabsContext` |
|
|
3691
|
+
| Imported `export const` string | `import { KEY } from "./keys.js";`<br>`setContext(KEY, …)` | `SimpleModalContext` |
|
|
3637
3692
|
|
|
3638
3693
|
`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.
|
|
3639
3694
|
|
|
3640
3695
|
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`.
|
|
3641
3696
|
|
|
3642
|
-
|
|
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.
|
|
3698
|
+
|
|
3699
|
+
Anything else (dynamic identifiers, `let` exports, template interpolation, other function calls) records a `sveld/context-key-unresolved` diagnostic. No context type is generated.
|
|
3643
3700
|
|
|
3644
3701
|
#### Example
|
|
3645
3702
|
|
|
@@ -3819,7 +3876,7 @@ There are several ways to type contexts:
|
|
|
3819
3876
|
|
|
3820
3877
|
#### Notes
|
|
3821
3878
|
|
|
3822
|
-
- 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
|
|
3879
|
+
- Context keys must be statically resolvable: a string literal, a static template literal, a `const`-bound string (local or an imported `export const`), or a `Symbol()` / `Symbol.for()` call with a static description. Dynamic expressions (runtime identifiers, template interpolation, other function calls) are skipped with a `sveld/context-key-unresolved` diagnostic.
|
|
3823
3880
|
- Variables passed to `setContext` should have JSDoc `@type` annotations for accurate types
|
|
3824
3881
|
- The generated type name follows the pattern: `{PascalCase}Context`. Separators (hyphens, underscores, dots, colons, slashes, spaces) are stripped and each segment is capitalized:
|
|
3825
3882
|
| Context Key | Generated Type Name |
|
package/lib/browser.d.ts
CHANGED
|
@@ -37,6 +37,13 @@ interface PendingCallDefaultCandidate {
|
|
|
37
37
|
importedName?: string;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
interface PendingConstDefaultCandidate {
|
|
41
|
+
propName: string;
|
|
42
|
+
location: "props" | "moduleExports";
|
|
43
|
+
importSource: string;
|
|
44
|
+
importedName: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
40
47
|
interface PendingContextKeyCandidate {
|
|
41
48
|
importSource: string;
|
|
42
49
|
importedName: string;
|
|
@@ -46,6 +53,23 @@ interface PendingContextKeyCandidate {
|
|
|
46
53
|
source?: SourceRange;
|
|
47
54
|
}
|
|
48
55
|
|
|
56
|
+
interface PendingDispatchEscapeCandidate {
|
|
57
|
+
importSource: string;
|
|
58
|
+
importedName: string;
|
|
59
|
+
/** Callee as written, for messages. */
|
|
60
|
+
calleeText: string;
|
|
61
|
+
/** Local name of the `createEventDispatcher()` result. */
|
|
62
|
+
dispatcherName: string;
|
|
63
|
+
/** Argument position the dispatcher is passed at. */
|
|
64
|
+
argumentIndex: number;
|
|
65
|
+
/** Set when passed as an object literal property (`{ dispatch }`): that property's key. */
|
|
66
|
+
property?: string;
|
|
67
|
+
/** Source range of the call, when available. */
|
|
68
|
+
source?: SourceRange;
|
|
69
|
+
/** `@sveld-ignore sveld/dispatch-escapes` on the dispatcher's declaration. */
|
|
70
|
+
ignored?: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
49
73
|
interface ParsedComponentTypeScriptMetadata {
|
|
50
74
|
canonicalPropsType?: string;
|
|
51
75
|
canonicalPropNames: string[];
|
|
@@ -60,8 +84,17 @@ interface ParsedComponentTypeScriptMetadata {
|
|
|
60
84
|
referencesComponentGenerics?: boolean;
|
|
61
85
|
/** Unresolved CallExpression defaults for the cross-file pass in `generateBundle`. */
|
|
62
86
|
pendingCallDefaultCandidates?: PendingCallDefaultCandidate[];
|
|
87
|
+
/** Imported-identifier defaults for the cross-file pass in `generateBundle`. */
|
|
88
|
+
pendingConstDefaultCandidates?: PendingConstDefaultCandidate[];
|
|
63
89
|
/** Unresolved `setContext` import keys for the cross-file pass in `generateBundle`. */
|
|
64
90
|
pendingContextKeyCandidates?: PendingContextKeyCandidate[];
|
|
91
|
+
/** Dispatchers passed to imported functions, for the cross-file pass in `generateBundle`. */
|
|
92
|
+
pendingDispatchEscapeCandidates?: PendingDispatchEscapeCandidate[];
|
|
93
|
+
/**
|
|
94
|
+
* `event-no-source` diagnostics held back while the dispatcher escapes to
|
|
95
|
+
* imported functions: `generateBundle` keeps those the functions don't dispatch.
|
|
96
|
+
*/
|
|
97
|
+
deferredEventNoSourceDiagnostics?: SveldDiagnostic[];
|
|
65
98
|
}
|
|
66
99
|
|
|
67
100
|
type SyntaxMode = "legacy" | "runes";
|
|
@@ -506,7 +539,7 @@ export class ComponentParser {
|
|
|
506
539
|
parseSvelteComponent(source: string, diagnostics: ComponentParserDiagnostics): ParsedComponent;
|
|
507
540
|
}
|
|
508
541
|
|
|
509
|
-
export type SveldDiagnosticKind = "prop-unknown-type" | "context-any-type" | "slot-missing-type" | "event-no-source" | "example-compile-error" | "example-syntax-error" | "syntax-skipped" | "rest-props-unresolved" | "context-duplicate-key" | "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";
|
|
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";
|
|
510
543
|
|
|
511
544
|
type SveldDiagnosticSeverity = "error" | "warning";
|
|
512
545
|
|