sveld 0.37.8 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -1,3 +1,962 @@
1
- /// <reference types="node" />
1
+ import type { Property } from "estree";
2
2
 
3
- export declare function parse(source: string): unknown;
3
+ import type { Dirent } from "node:fs";
4
+
5
+ import { type Program } from "acorn";
6
+
7
+ interface ComponentParserDiagnostics {
8
+ moduleName: string;
9
+ filePath: string;
10
+ }
11
+
12
+ export class ComponentParser {
13
+ /**
14
+ * All per-parse mutable state (props, slots, events, scopes, source, etc.).
15
+ * See {@link ParserContext} for field-by-field documentation. Replaced
16
+ * wholesale by `cleanup()` between parses.
17
+ */
18
+ private ctx;
19
+ /**
20
+ * Resets parser state for reuse between parses.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * parser.parseSvelteComponent(source1, diagnostics1);
25
+ * parser.cleanup();
26
+ * parser.parseSvelteComponent(source2, diagnostics2);
27
+ * ```
28
+ */
29
+ cleanup(): void;
30
+ /**
31
+ * @example
32
+ * ```ts
33
+ * const parser = new ComponentParser();
34
+ * const result = parser.parseSvelteComponent(source, {
35
+ * moduleName: "Button",
36
+ * filePath: "./Button.svelte"
37
+ * });
38
+ * // { props, slots, events, typedefs, ... }
39
+ * ```
40
+ */
41
+ parseSvelteComponent(source: string, diagnostics: ComponentParserDiagnostics): ParsedComponent;
42
+ /**
43
+ * Like {@link parseSvelteComponent}, but returns the candidates only a
44
+ * pass with file access can resolve beside the component rather than
45
+ * inside its metadata.
46
+ */
47
+ parse(source: string, diagnostics: ComponentParserDiagnostics): ComponentParseResult;
48
+ }
49
+
50
+ interface JsDocPassthroughTag {
51
+ name: string;
52
+ body: string;
53
+ }
54
+
55
+ type DeprecatedValue = string | true;
56
+
57
+ interface SourcePosition {
58
+ /** 1-based source line number */
59
+ line: number;
60
+ /** 0-based source column number */
61
+ column: number;
62
+ }
63
+
64
+ interface SourceRange {
65
+ start: SourcePosition;
66
+ end: SourcePosition;
67
+ }
68
+
69
+ interface PendingCallDefaultCandidate {
70
+ propName: string;
71
+ location: "props" | "moduleExports";
72
+ calleeName: string;
73
+ importSource?: string;
74
+ importedName?: string;
75
+ }
76
+
77
+ interface PendingConstDefaultCandidate {
78
+ propName: string;
79
+ location: "props" | "moduleExports";
80
+ importSource: string;
81
+ importedName: string;
82
+ /** Members read off the import, through namespace exports: `["DELAY"]` for `C.timing.DELAY`. */
83
+ members?: string[];
84
+ }
85
+
86
+ interface PendingContextKeyCandidate {
87
+ importSource: string;
88
+ importedName: string;
89
+ /** Members read off the import, through namespace exports: `["THEME"]` for `ns.keys.THEME`. */
90
+ members?: string[];
91
+ /** See {@link ComponentContext.type}. */
92
+ type?: string;
93
+ properties: ComponentContextProp[];
94
+ description?: string;
95
+ /** See {@link ComponentContext.hasUnresolvedSpread}. */
96
+ hasUnresolvedSpread?: boolean;
97
+ /** See {@link ComponentContext.internal}. */
98
+ internal?: boolean;
99
+ /** Source range of the `setContext(...)` call, when available. */
100
+ source?: SourceRange;
101
+ }
102
+
103
+ interface PendingDispatchEscapeCandidate {
104
+ importSource: string;
105
+ importedName: string;
106
+ /** Members read off the import, through namespace exports: `["helper"]` for `ns.helper`. */
107
+ members?: string[];
108
+ /** Callee as written, for messages. */
109
+ calleeText: string;
110
+ /** Local name of the `createEventDispatcher()` result. */
111
+ dispatcherName: string;
112
+ /** Argument position the dispatcher is passed at. */
113
+ argumentIndex: number;
114
+ /** Set when passed as an object literal property (`{ dispatch }`): that property's key. */
115
+ property?: string;
116
+ /** Source range of the call, when available. */
117
+ source?: SourceRange;
118
+ /** `@sveld-ignore sveld/dispatch-escapes` on the dispatcher's declaration. */
119
+ ignored?: boolean;
120
+ }
121
+
122
+ interface PendingCrossFileCandidates {
123
+ /** Unresolved CallExpression defaults. */
124
+ pendingCallDefaultCandidates?: PendingCallDefaultCandidate[];
125
+ /** Imported-identifier defaults. */
126
+ pendingConstDefaultCandidates?: PendingConstDefaultCandidate[];
127
+ /** Unresolved `setContext` import keys. */
128
+ pendingContextKeyCandidates?: PendingContextKeyCandidate[];
129
+ /** Dispatchers passed to imported functions. */
130
+ pendingDispatchEscapeCandidates?: PendingDispatchEscapeCandidate[];
131
+ /**
132
+ * `event-no-source` diagnostics held back while the dispatcher escapes to
133
+ * imported functions: the cross-file pass keeps those the functions don't dispatch.
134
+ */
135
+ deferredEventNoSourceDiagnostics?: SveldDiagnostic[];
136
+ /**
137
+ * `@event` tags with no `{type}` or `@property`, whose `null` detail no
138
+ * same-file dispatch replaced; an escaped dispatcher's helper may still.
139
+ */
140
+ untypedJsDocEventNames?: string[];
141
+ }
142
+
143
+ interface ParsedComponentTypeScriptMetadata extends PendingCrossFileCandidates {
144
+ canonicalPropsType?: string;
145
+ canonicalPropNames: string[];
146
+ localTypeDeclarations: string[];
147
+ /** Types the module script exports (`export interface Item`), emitted with `export`. */
148
+ moduleTypeDeclarations?: string[];
149
+ typeImportStatements: string[];
150
+ }
151
+
152
+ interface ComponentParseResult {
153
+ component: ParsedComponent;
154
+ /** Undefined when the component depends on no other file's contents. */
155
+ pending?: PendingCrossFileCandidates;
156
+ }
157
+
158
+ type SyntaxMode = "legacy" | "runes";
159
+
160
+ type ScriptLanguage = "js" | "ts";
161
+
162
+ type ComponentPropTypeSource = "typescript" | "jsdoc" | "default" | "inferred" | "unknown";
163
+
164
+ type ComponentPropDefaultValueKind = "literal" | "array" | "object" | "expression" | "function" | "unknown";
165
+
166
+ interface ComponentPropDefaultValue {
167
+ raw: string;
168
+ kind: ComponentPropDefaultValueKind;
169
+ value?: unknown;
170
+ }
171
+
172
+ type ComponentPropBinding = "readonly" | "writable";
173
+
174
+ interface ComponentPropParam {
175
+ /** Parameter name. */
176
+ name: string;
177
+ /** Parameter type (e.g. `"string"`, `"CustomType"`). */
178
+ type: string;
179
+ /** From JSDoc `@param`. */
180
+ description?: string;
181
+ /** True when optional. */
182
+ optional?: boolean;
183
+ }
184
+
185
+ interface ComponentPropReExport {
186
+ /** Module specifier as written in the source (e.g. `"./utils.js"`). */
187
+ from: string;
188
+ /** Name `from` exports: `"default"` for a default import, `"*"` for `export *` or a namespace import. */
189
+ imported: string;
190
+ }
191
+
192
+ interface ComponentClassMember {
193
+ /** `"property"` covers fields, constructor parameter properties, and getter/setter pairs. */
194
+ kind: "constructor" | "method" | "property";
195
+ /** Member name; `"constructor"` for the constructor. */
196
+ name: string;
197
+ /** Property type text; `"any"` when neither TypeScript nor JSDoc types it. */
198
+ type?: string;
199
+ /** Method or constructor parameters, typed from TypeScript or JSDoc `@param`, else `"any"`. A rest parameter's name starts with `...`. */
200
+ params?: ComponentPropParam[];
201
+ /** Method return type from TypeScript or JSDoc `@returns`; unset when neither gives one. */
202
+ returnType?: string;
203
+ /** A method's own type parameter list (`U extends object`), without the angle brackets. */
204
+ typeParameters?: string;
205
+ static?: true;
206
+ /** A `readonly` field, or a getter with no setter. */
207
+ readonly?: true;
208
+ optional?: true;
209
+ abstract?: true;
210
+ description?: string;
211
+ deprecated?: DeprecatedValue;
212
+ tags?: JsDocPassthroughTag[];
213
+ }
214
+
215
+ interface ComponentProp {
216
+ /** Public prop name; `"*"` for a bare `export * from "..."`. */
217
+ name: string;
218
+ /**
219
+ * `"let"` (required), `"const"` (default), or `"function"`. `"re-export"`
220
+ * is module-export only: `export { x } from "..."`, `export * from "..."`,
221
+ * or `export { x }` of an imported binding, written to the `.d.ts` as-is.
222
+ * `"class"` is module-export only too: a class the module script declares,
223
+ * with its public surface in {@link ComponentProp.members}.
224
+ */
225
+ kind: "let" | "const" | "function" | "re-export" | "class";
226
+ /** True when declared with `const`. */
227
+ constant: boolean;
228
+ /** TypeScript type text. */
229
+ type?: string;
230
+ /** Conservative provenance for the prop type. See the precedence rule on {@link ComponentProp}. */
231
+ typeSource?: ComponentPropTypeSource;
232
+ /** Local binding when it differs from the public name. */
233
+ localName?: string;
234
+ /** Default value as source text; unset when the prop has no initializer/default. */
235
+ value?: string;
236
+ /** Structured default value metadata for docs UIs; set alongside `value` from the same initializer. */
237
+ defaultValue?: ComponentPropDefaultValue;
238
+ /** From JSDoc, or a matching `@typedef`'s own description (legacy only; see {@link ComponentProp}). */
239
+ description?: string;
240
+ /** From JSDoc `@param` on function props. */
241
+ params?: ComponentPropParam[];
242
+ /** From JSDoc `@returns` on function props. */
243
+ returnType?: string;
244
+ /**
245
+ * A function's own type parameter list from its `@template` tags (e.g.
246
+ * `T extends { id: string }`), without the angle brackets. Also prefixed
247
+ * onto `type` when that signature is built from `@param`/`@returns`.
248
+ * For a `"class"`, the class's type parameters, from TypeScript or `@template`.
249
+ */
250
+ typeParameters?: string;
251
+ /** Set when `kind` is `"class"`: its public constructor, methods, and properties, in source order. */
252
+ members?: ComponentClassMember[];
253
+ /** Set when `kind` is `"class"` and the class is `abstract`. */
254
+ abstract?: true;
255
+ /** Set when `kind` is `"class"` and it extends a base class: `Base<T>`. */
256
+ extends?: string;
257
+ /** Set when `kind` is `"class"` and it implements interfaces: `["Disposable"]`. */
258
+ implements?: string[];
259
+ /**
260
+ * True for arrow/function-expression initializers and bare `function`
261
+ * declarations in every mode; additionally true for a function-shaped
262
+ * type/JSDoc signature in runes only (see {@link ComponentProp}).
263
+ */
264
+ isFunction: boolean;
265
+ /** True for `function` declarations. */
266
+ isFunctionDeclaration: boolean;
267
+ /** True when declared with `let` and no default. */
268
+ isRequired: boolean;
269
+ /**
270
+ * True when the prop is mutated locally (legacy, inferred from assignment/
271
+ * binding targets) or declared with `$bindable()` (runes).
272
+ */
273
+ reactive: boolean;
274
+ /** Binding direction from `@bindable` JSDoc. */
275
+ binding?: ComponentPropBinding;
276
+ /** True when declared with Svelte 5 `$bindable()` (runes only). */
277
+ bindable?: true;
278
+ /** From `@deprecated` JSDoc. */
279
+ deprecated?: DeprecatedValue;
280
+ /** `@since` / `@example` tags in source order. */
281
+ tags?: JsDocPassthroughTag[];
282
+ /** True from `@ignore`/`@internal` JSDoc; excluded from every output by `buildComponentApiDocument`. */
283
+ internal?: boolean;
284
+ /** Set when `kind` is `"re-export"`. */
285
+ reExport?: ComponentPropReExport;
286
+ /** Source range when available. */
287
+ source?: SourceRange;
288
+ }
289
+
290
+ interface ComponentSlot {
291
+ /** Slot name (`null` for the default slot). */
292
+ name?: string | null;
293
+ /** True for the default slot. */
294
+ default: boolean;
295
+ /** Fallback content when the slot is empty. */
296
+ fallback?: string;
297
+ /** Slot props as TypeScript type text. */
298
+ slot_props?: string;
299
+ /** From JSDoc `@slot` or `@snippet`. */
300
+ description?: string;
301
+ /** From `@deprecated` JSDoc. */
302
+ deprecated?: DeprecatedValue;
303
+ /** Tags between the description and `@slot`/`@snippet` (e.g. `@example`), in source order. */
304
+ tags?: JsDocPassthroughTag[];
305
+ /** True from `@ignore`/`@internal` JSDoc; excluded from every output by `buildComponentApiDocument`. */
306
+ internal?: boolean;
307
+ /** Source range when available. */
308
+ source?: SourceRange;
309
+ }
310
+
311
+ interface DispatchedEvent {
312
+ /** Discriminator: `"dispatched"`. */
313
+ type: "dispatched";
314
+ /** Event name. */
315
+ name: string;
316
+ /** Detail type text. */
317
+ detail?: string;
318
+ /** From JSDoc `@event`. */
319
+ description?: string;
320
+ /** From `@deprecated` JSDoc. */
321
+ deprecated?: DeprecatedValue;
322
+ /** `@since` / `@example` tags in source order. */
323
+ tags?: JsDocPassthroughTag[];
324
+ /** True from `@ignore`/`@internal` JSDoc; excluded from every output by `buildComponentApiDocument`. */
325
+ internal?: boolean;
326
+ /** Source range when available. */
327
+ source?: SourceRange;
328
+ }
329
+
330
+ interface SerializedForwardedEvent {
331
+ /** Discriminator: `"forwarded"`. */
332
+ type: "forwarded";
333
+ /** Event name. */
334
+ name: string;
335
+ /** Element name as a string for JSON output. */
336
+ element: string;
337
+ /** From JSDoc `@event`. */
338
+ description?: string;
339
+ /** From `@deprecated` JSDoc. */
340
+ deprecated?: DeprecatedValue;
341
+ /** Detail type from `@event`. */
342
+ detail?: string;
343
+ /** `@since` / `@example` tags in source order. */
344
+ tags?: JsDocPassthroughTag[];
345
+ /** True from `@ignore`/`@internal` JSDoc; excluded from every output by `buildComponentApiDocument`. */
346
+ internal?: boolean;
347
+ /** Source range when available. */
348
+ source?: SourceRange;
349
+ }
350
+
351
+ export type SerializedComponentEvent = SerializedForwardedEvent | DispatchedEvent;
352
+
353
+ interface TypeDef {
354
+ /** Type text (e.g. `"{ x: number; y: number }"`). */
355
+ type: string;
356
+ /** Type name. */
357
+ name: string;
358
+ /** From JSDoc. */
359
+ description?: string;
360
+ /** Full `type` alias declaration text. */
361
+ ts: string;
362
+ /** Tags in the same block (e.g. `@since`, `@example`, `@see`), in source order. */
363
+ tags?: JsDocPassthroughTag[];
364
+ /** True from `@ignore`/`@internal` JSDoc; excluded from every output by `buildComponentApiDocument`. */
365
+ internal?: boolean;
366
+ /** Source range of the `@typedef`/`@callback` tag, when available. */
367
+ source?: SourceRange;
368
+ }
369
+
370
+ type ComponentGenerics = [name: string, type: string] | null;
371
+
372
+ interface ComponentInlineElement {
373
+ /** Discriminator: `"InlineComponent"`. */
374
+ type: "InlineComponent";
375
+ /** Component name. */
376
+ name: string;
377
+ }
378
+
379
+ interface ComponentElement {
380
+ type: "Element";
381
+ name: string;
382
+ /**
383
+ * Static tag for `svelte:element this="div"`. Undefined when `this` is dynamic.
384
+ *
385
+ * @example
386
+ * ```svelte
387
+ * <!-- Static tag -->
388
+ * <svelte:element this="div" bind:this={elementRef} />
389
+ * // thisValue: "div"
390
+ *
391
+ * <!-- Dynamic tag -->
392
+ * <svelte:element this={tagName} bind:this={elementRef} />
393
+ * // thisValue: undefined
394
+ * ```
395
+ */
396
+ thisValue?: string;
397
+ /** From `@restProps` JSDoc. */
398
+ description?: string;
399
+ }
400
+
401
+ type RestProps = undefined | ComponentInlineElement | ComponentElement;
402
+
403
+ interface Extends {
404
+ /** Interface name (e.g. `"ButtonProps"`). */
405
+ interface: string;
406
+ /** Import path (e.g. `"./types"`). */
407
+ import: string;
408
+ }
409
+
410
+ type CustomElementPropType = "String" | "Boolean" | "Number" | "Array" | "Object";
411
+
412
+ interface CustomElementPropConfig {
413
+ /** Explicit attribute name. Svelte itself always observes every prop as an attribute; sveld's own output omits the attribute entirely when this is `false`. */
414
+ attribute?: string | false;
415
+ reflect?: boolean;
416
+ type?: CustomElementPropType;
417
+ }
418
+
419
+ interface CustomElementOptions {
420
+ tag?: string;
421
+ shadow?: "open" | "none";
422
+ props?: Record<string, CustomElementPropConfig>;
423
+ extend?: true;
424
+ }
425
+
426
+ interface ComponentCssPart {
427
+ name: string;
428
+ description?: string;
429
+ }
430
+
431
+ interface ComponentCssProperty {
432
+ /** Includes the leading `--`. */
433
+ name: string;
434
+ type?: string;
435
+ default?: string;
436
+ description?: string;
437
+ }
438
+
439
+ interface ComponentContextProp {
440
+ /** Property name. */
441
+ name: string;
442
+ /** Property type text. */
443
+ type: string;
444
+ /** From JSDoc. */
445
+ description?: string;
446
+ /** True when optional. */
447
+ optional: boolean;
448
+ /** True from `@ignore`/`@internal` JSDoc; excluded from every output by `buildComponentApiDocument`. */
449
+ internal?: boolean;
450
+ }
451
+
452
+ interface ComponentContext {
453
+ /** Context key from `setContext`. */
454
+ key: string;
455
+ /** Generated type name (e.g. `"ModalContext"`). */
456
+ typeName: string;
457
+ /**
458
+ * The context's whole type, when the `setContext` value is a variable whose
459
+ * type isn't an object type literal (`ModalAPI`, `Writable<number>`, or `any`
460
+ * when untyped). `properties` is empty then.
461
+ */
462
+ type?: string;
463
+ /** From JSDoc. */
464
+ description?: string;
465
+ /** Context object properties. Empty when {@link ComponentContext.type} is set. */
466
+ properties: ComponentContextProp[];
467
+ /** True when a `{...spread}` in the context's object literal couldn't be resolved; the generated type intersects with `Record<string, any>`. */
468
+ hasUnresolvedSpread?: boolean;
469
+ /** True from `@ignore`/`@internal` JSDoc on the `setContext` call; excluded from every output by `buildComponentApiDocument`. */
470
+ internal?: boolean;
471
+ /** Source range of the `setContext(...)` call, when available. */
472
+ source?: SourceRange;
473
+ }
474
+
475
+ interface ParsedComponent {
476
+ /** Source range of the parsed file. */
477
+ source?: SourceRange;
478
+ syntaxMode: SyntaxMode;
479
+ scriptLanguage?: ScriptLanguage;
480
+ /** Instance-level props (`export let`/`export function`, or runes `$props()`). See {@link ComponentProp} for the shared IR these are built from. */
481
+ props: ComponentProp[];
482
+ /** Exports from `<script context="module">`. Same {@link ComponentProp} shape as `props`, resolved through the same shared decisions. */
483
+ moduleExports: ComponentProp[];
484
+ slots: ComponentSlot[];
485
+ /** Serialized events for JSON/API output. */
486
+ events: SerializedComponentEvent[];
487
+ typedefs: TypeDef[];
488
+ generics: null | ComponentGenerics;
489
+ rest_props: RestProps;
490
+ extends?: Extends;
491
+ /** From `@component` HTML comment. */
492
+ componentComment?: string;
493
+ componentCommentSource?: SourceRange;
494
+ contexts?: ComponentContext[];
495
+ customElementTag?: string;
496
+ /** Full `<svelte:options customElement=... />` config (shorthand or object form), when present. */
497
+ customElement?: CustomElementOptions;
498
+ /** From component-level `@csspart` JSDoc tags. */
499
+ cssParts?: ComponentCssPart[];
500
+ /** From component-level `@cssprop`/`@cssproperty` JSDoc tags. */
501
+ cssProperties?: ComponentCssProperty[];
502
+ /**
503
+ * Type guesses from this parse (unknown props, `any` contexts, orphan `@event` tags).
504
+ */
505
+ diagnostics?: SveldDiagnostic[];
506
+ /** Writer-only TypeScript metadata. Not serialized to JSON. */
507
+ [PARSED_COMPONENT_TYPE_SCRIPT_METADATA]?: ParsedComponentTypeScriptMetadata;
508
+ }
509
+
510
+ 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" | "type-syntax-error" | "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" | "cross-file-unresolved" | "export-ambiguous";
511
+
512
+ export type SveldDiagnosticSeverity = "error" | "warning";
513
+
514
+ export declare const DIAGNOSTIC_CODES: Record<SveldDiagnosticKind, string>;
515
+
516
+ export interface SveldDiagnostic {
517
+ /**
518
+ * File this came from, e.g. `"./Button.svelte"`, or the entry barrel
519
+ * (`"./index.js"`) for `export-ambiguous`.
520
+ */
521
+ component: string;
522
+ kind: SveldDiagnosticKind;
523
+ /** Stable, namespaced identifier for `kind` (e.g. `"sveld/prop-unknown-type"`). */
524
+ code: string;
525
+ severity: SveldDiagnosticSeverity;
526
+ /** Prop, context field, or event name. */
527
+ name: string;
528
+ /** What went wrong and what type sveld used. */
529
+ message: string;
530
+ /** Where in the component source this diagnostic points, when the parser holds a stable position. */
531
+ source?: SourceRange;
532
+ /**
533
+ * True when suppressed by an inline `@sveld-ignore` tag or a `diagnostics.ignore`
534
+ * config matcher. Still present here (and counted in the summary) but never
535
+ * fails `--strict` / `--strict=errors`.
536
+ */
537
+ ignored?: boolean;
538
+ }
539
+
540
+ export interface DiagnosticIgnoreMatcher {
541
+ code?: string;
542
+ component?: string;
543
+ name?: string;
544
+ }
545
+
546
+ export declare const DIAGNOSTICS_SCHEMA_VERSION = 1;
547
+
548
+ export interface DiagnosticsJson {
549
+ kind: "diagnostics";
550
+ schemaVersion: typeof DIAGNOSTICS_SCHEMA_VERSION;
551
+ diagnostics: SveldDiagnostic[];
552
+ }
553
+
554
+ declare const PARSED_COMPONENT_TYPE_SCRIPT_METADATA: unique symbol;
555
+
556
+ export type SemverBump = "major" | "minor" | "patch" | "none";
557
+
558
+ export interface ApiChange {
559
+ /** Component `moduleName` this change belongs to, or `"*"` for document-wide notices. */
560
+ component: string;
561
+ kind: "component" | "prop" | "moduleExport" | "event" | "slot" | "shape" | "schema";
562
+ /** Prop, event, slot, or shape-field name, when applicable. */
563
+ name?: string;
564
+ bump: SemverBump;
565
+ message: string;
566
+ }
567
+
568
+ export interface CheckResult {
569
+ /** `false` when there was nothing on disk to diff against (e.g. first run). */
570
+ snapshotExists: boolean;
571
+ snapshotFile: string;
572
+ changes: ApiChange[];
573
+ /** Highest bump across all changes. */
574
+ bump: SemverBump;
575
+ }
576
+
577
+ export declare function diffApiDocuments(previous: ComponentApiDocument, next: ComponentApiDocument): ApiChange[];
578
+
579
+ interface RunCheckOptions {
580
+ /** Entry-barrel exports when `documentExports` is on. */
581
+ entryExports?: EntryExports;
582
+ }
583
+
584
+ export declare function runCheck(components: ComponentDocs, snapshotFile: string, options?: RunCheckOptions): Promise<CheckResult>;
585
+
586
+ export declare function formatCheckReport(result: CheckResult): string;
587
+
588
+ export declare const CHECK_REPORT_SCHEMA_VERSION = 1;
589
+
590
+ export type CheckReportJson = CheckResult & {
591
+ kind: "check-report";
592
+ schemaVersion: typeof CHECK_REPORT_SCHEMA_VERSION;
593
+ };
594
+
595
+ export declare function formatCheckReportJson(result: CheckResult): string;
596
+
597
+ interface ComponentDocApi extends ParsedComponent {
598
+ filePath: NormalizedPath;
599
+ moduleName: string;
600
+ }
601
+
602
+ type ComponentDocs = Map<string, ComponentDocApi>;
603
+
604
+ interface ComponentParseError {
605
+ filePath: string;
606
+ moduleName: string;
607
+ message: string;
608
+ stack?: string;
609
+ }
610
+
611
+ interface GenerateBundleOptions {
612
+ /**
613
+ * Throw on the first component that fails to parse instead of collecting
614
+ * the failure and continuing with the remaining components.
615
+ */
616
+ failFast?: boolean;
617
+ /** Record consts, functions, and types from the entry barrel. Off by default. */
618
+ documentExports?: boolean;
619
+ /**
620
+ * Cache parsed component output to disk. Unchanged files skip re-parsing on
621
+ * later runs. On by default, writing to
622
+ * `node_modules/.cache/sveld/parse-cache.json`; a string sets a custom path.
623
+ * Pass `false` to disable.
624
+ */
625
+ cache?: boolean | string;
626
+ /**
627
+ * Check `@example` blocks on props, module exports, slots, and events.
628
+ * `true` runs plain TS/JS examples through the TypeScript program
629
+ * (`example-compile-error` diagnostics; requires `typescript`) and
630
+ * Svelte/HTML examples through sveld's own template parser
631
+ * (`example-syntax-error` diagnostics; no `typescript` needed). Pass
632
+ * `"syntax"` to run only the markup path, so `typescript` is never loaded
633
+ * even when TS/JS examples exist. Off by default.
634
+ */
635
+ checkExamples?: boolean | "syntax";
636
+ /**
637
+ * `ignore`: diagnostics matching at least one `{ code?, component?, name? }`
638
+ * matcher are marked `ignored` (an omitted field matches anything;
639
+ * `component` is a glob). Ignored diagnostics still appear in
640
+ * `SveldResult.diagnostics` and are counted in the text summary, but never
641
+ * fail `--strict` / `--strict=errors`.
642
+ */
643
+ diagnostics?: {
644
+ ignore?: DiagnosticIgnoreMatcher[];
645
+ };
646
+ }
647
+
648
+ declare const brand: unique symbol;
649
+
650
+ type Brand<TBase extends string, TBrand extends string> = TBase & {
651
+ readonly [brand]: TBrand;
652
+ };
653
+
654
+ export type SvelteEntryPoint = Brand<string, "SvelteEntryPoint">;
655
+
656
+ type NormalizedPath = Brand<string, "NormalizedPath">;
657
+
658
+ interface EntryExport {
659
+ name: string;
660
+ kind: "const" | "let" | "var" | "function" | "class" | "type" | "interface" | "enum";
661
+ /**
662
+ * Type text from the source, when present. A namespace export
663
+ * (`export * as ns from "./x"`) gets `typeof import("./x.ts")`, the
664
+ * wrapped module relative to the entry file.
665
+ */
666
+ type?: string;
667
+ /** Initializer text for simple constants. */
668
+ value?: string;
669
+ description?: string;
670
+ /** From `@deprecated` JSDoc. */
671
+ deprecated?: DeprecatedValue;
672
+ /** `@since` / `@example` / `@see` tags in source order. */
673
+ tags?: JsDocPassthroughTag[];
674
+ /** True from `@ignore`/`@internal` JSDoc; excluded from every output by `buildComponentApiDocument`. */
675
+ internal?: boolean;
676
+ /** Declaring module, relative to the entry file. */
677
+ source?: string;
678
+ isTypeOnly: boolean;
679
+ }
680
+
681
+ type EntryExports = EntryExport[];
682
+
683
+ export interface SveldRuntimeOptions extends PluginSveldOptions {
684
+ /** Print unresolved-type diagnostics to stderr. */
685
+ reportDiagnostics?: boolean;
686
+ /**
687
+ * Exit code 4 when diagnostics exist. Implies `reportDiagnostics`. Pass
688
+ * `"errors"` to fail only on `severity: "error"` diagnostics
689
+ * (`example-compile-error`, `syntax-skipped`), letting warnings
690
+ * (`prop-unknown-type`, `context-any-type`, `event-no-source`) through.
691
+ */
692
+ strict?: boolean | "errors";
693
+ /**
694
+ * Diff the parsed component API against a committed snapshot (default:
695
+ * the `json` writer's `outFile`, or `COMPONENT_API.json`) and assign a
696
+ * semver bump to each change. Exits `3` on a breaking change. Pass a
697
+ * string for a custom snapshot path.
698
+ */
699
+ check?: boolean | string;
700
+ /**
701
+ * Minimum bump `--check` fails the run (exit `3`) on: `"major"` (default,
702
+ * preserves prior behavior), `"minor"`, or `"patch"`.
703
+ */
704
+ checkLevel?: "major" | "minor" | "patch";
705
+ /** Suppress writer progress logs (`created "..."` / `unchanged "..."`). */
706
+ quiet?: boolean;
707
+ /**
708
+ * Print the single selected `json` / `markdown` document to stdout
709
+ * instead of writing it to disk. Requires exactly one of those two
710
+ * outputs; CLI-only (the Vite plugin ignores it).
711
+ */
712
+ stdout?: boolean;
713
+ /**
714
+ * Output format for the `--check` report and the `--report-diagnostics` /
715
+ * `--strict` diagnostics summary: `"text"` (default) or `"json"`.
716
+ * Channels are unchanged, the check report on stdout and diagnostics on
717
+ * stderr. CLI-only; `sveld()` ignores `format` for its own console output.
718
+ */
719
+ format?: "text" | "json";
720
+ }
721
+
722
+ export type SveldConfig = SveldRuntimeOptions;
723
+
724
+ export declare function defineConfig(config: SveldConfig): SveldConfig;
725
+
726
+ interface PluginSveldOptions extends Pick<GenerateBundleOptions, "cache" | "checkExamples" | "diagnostics"> {
727
+ /**
728
+ * Specify the entry point to uncompiled Svelte source.
729
+ * If not provided, sveld will use the "svelte" field from package.json.
730
+ */
731
+ entry?: string;
732
+ /**
733
+ * Load `sveld.config.{js,mjs,ts}` and merge it with these options; these
734
+ * options win when a key is set in both. `true` resolves the config from
735
+ * the Vite project root (or `process.cwd()` if the plugin isn't running
736
+ * under Vite); a string is an explicit path to the config file itself.
737
+ * @default false
738
+ */
739
+ config?: boolean | string;
740
+ glob?: boolean;
741
+ /** Suppress writer progress logs (`created "..."` / `unchanged "..."`). */
742
+ quiet?: boolean;
743
+ /** Record consts, functions, and types from the entry barrel. Off by default. */
744
+ documentExports?: boolean;
745
+ types?: boolean;
746
+ typesOptions?: TypesOptions;
747
+ json?: boolean;
748
+ jsonOptions?: JsonOptions;
749
+ markdown?: boolean;
750
+ markdownOptions?: MarkdownOptions;
751
+ /**
752
+ * Abort the entire run when a single component fails to parse.
753
+ * When `false` (the default), parse failures are collected as diagnostics
754
+ * and the remaining components still emit their output.
755
+ */
756
+ failFast?: boolean;
757
+ /**
758
+ * Regenerate output incrementally when relevant source changes during
759
+ * `vite dev` / `vite build --watch`: a component, the entry barrel itself
760
+ * (adding/removing an export), a module a component reads a value from,
761
+ * or a non-`.svelte` file a component names via `@extendProps` /
762
+ * `@extends`. Only the edited components and those that read an edited
763
+ * module are re-parsed.
764
+ * @default false
765
+ */
766
+ watch?: boolean;
767
+ }
768
+
769
+ interface HotUpdateContext {
770
+ file: string;
771
+ }
772
+
773
+ interface RollupPluginContext {
774
+ error(message: string): never;
775
+ }
776
+
777
+ interface ResolvedViteConfig {
778
+ root: string;
779
+ }
780
+
781
+ interface SveldPlugin {
782
+ name: string;
783
+ apply?: "build" | "serve";
784
+ enforce?: "pre" | "post";
785
+ /** Vite-only hook: captures the project root before `buildStart` runs. */
786
+ configResolved?(config: ResolvedViteConfig): void;
787
+ buildStart(): void | Promise<void>;
788
+ generateBundle(this: RollupPluginContext): Promise<void>;
789
+ writeBundle(this: RollupPluginContext): Promise<void>;
790
+ /** Vite dev-server HMR hook (serve mode). */
791
+ handleHotUpdate?(ctx: HotUpdateContext): void;
792
+ /** Rollup/Vite watch hook (build `--watch`). */
793
+ watchChange?(id: string): void;
794
+ }
795
+
796
+ export default function pluginSveld(opts?: PluginSveldOptions): SveldPlugin;
797
+
798
+ export interface JsonOptions {
799
+ /**
800
+ * Path (relative to the project root) for the single combined JSON
801
+ * document. Ignored when `outDir` is set.
802
+ * @default "COMPONENT_API.json"
803
+ */
804
+ outFile?: string;
805
+ /**
806
+ * Emit one `<ComponentName>.api.json` file per component into this
807
+ * directory instead of the single combined `outFile`.
808
+ */
809
+ outDir?: string;
810
+ /**
811
+ * Include `source`/`componentCommentSource` position ranges in the
812
+ * output. These are the bulk of a large component library's
813
+ * `COMPONENT_API.json` (roughly a quarter of the file for a 150+
814
+ * component library); set to `false` to omit them and shrink the file
815
+ * when consumers don't need exact source positions.
816
+ * @default true
817
+ */
818
+ source?: boolean;
819
+ }
820
+
821
+ export interface ComponentApiDocument {
822
+ schemaVersion: 1;
823
+ generator: {
824
+ name: string;
825
+ version: string;
826
+ svelteVersion: string;
827
+ };
828
+ total: number;
829
+ components: ComponentDocApi[];
830
+ /** Only when `documentExports` is on. */
831
+ totalExports?: number;
832
+ exports?: EntryExports;
833
+ }
834
+
835
+ interface BuildComponentApiDocumentOptions {
836
+ /** Entry-barrel exports when `documentExports` is on. */
837
+ entryExports?: EntryExports;
838
+ }
839
+
840
+ export declare function buildComponentApiDocument(components: ComponentDocs, options?: BuildComponentApiDocumentOptions): ComponentApiDocument;
841
+
842
+ export interface MarkdownOptions {
843
+ /**
844
+ * Path (relative to the project root) for the single combined Markdown
845
+ * document. Ignored when `outDir` is set.
846
+ * @default "COMPONENT_INDEX.md"
847
+ */
848
+ outFile?: string;
849
+ /**
850
+ * Emit one `<ModuleName>.md` file per component into this directory,
851
+ * plus an index `README.md` linking to each, instead of the single
852
+ * combined `outFile`. See `jsonOptions.outDir` for the equivalent JSON
853
+ * option.
854
+ */
855
+ outDir?: string;
856
+ /**
857
+ * Called every time a heading, quote, paragraph, divider, or raw block is
858
+ * appended to the document, to inject extra content.
859
+ */
860
+ onAppend?: (type: AppendType, document: MarkdownDocument, components: ComponentDocs) => void;
861
+ }
862
+
863
+ type AppendType = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "quote" | "p" | "divider" | "raw";
864
+
865
+ interface TocLine {
866
+ /** Leading space count; 0 for the top-level (`h2`) entries the TOC currently lists. */
867
+ indent: number;
868
+ raw: string;
869
+ }
870
+
871
+ type MarkdownAppendCallback = (type: AppendType, document: MarkdownDocument) => void;
872
+
873
+ interface MarkdownDocumentOptions {
874
+ onAppend?: MarkdownAppendCallback;
875
+ }
876
+
877
+ declare class MarkdownDocument {
878
+ sourceParts: string[];
879
+ hasToC: boolean;
880
+ toc: TocLine[];
881
+ onAppend?: MarkdownAppendCallback;
882
+ constructor(options?: MarkdownDocumentOptions);
883
+ get source(): string;
884
+ appendLineBreaks(): this;
885
+ append(type: AppendType, raw?: string): this;
886
+ tableOfContents(): this;
887
+ end(): string;
888
+ }
889
+
890
+ type TransformContext = {
891
+ kind: "component";
892
+ component: ComponentDocApi;
893
+ filePath: string;
894
+ } | {
895
+ kind: "index";
896
+ filePath: string;
897
+ };
898
+
899
+ export interface TypesOptions extends WriteTsDefinitionOptions {
900
+ /**
901
+ * Output directory for generated `.d.ts` files, relative to the project
902
+ * root.
903
+ * @default "types"
904
+ */
905
+ outDir?: string;
906
+ /**
907
+ * Raw text prepended to the generated `index.d.ts` barrel, e.g. a license
908
+ * header.
909
+ * @default ""
910
+ */
911
+ preamble?: string;
912
+ /**
913
+ * Post-processes each generated file's text before it is written. Runs
914
+ * after the generated-text cache, so it applies on every run. Config file
915
+ * or `sveld()` only.
916
+ */
917
+ transform?: (text: string, context: TransformContext) => string | Promise<string>;
918
+ /**
919
+ * Also re-export generated types from `index.d.ts`: each component's
920
+ * `Props` type, and its `Exports` type under `format: "component"`.
921
+ */
922
+ indexTypes?: boolean;
923
+ }
924
+
925
+ interface WriteTsDefinitionOptions {
926
+ /**
927
+ * `"class"` (default) extends the deprecated `SvelteComponentTyped`.
928
+ * `"component"` emits `declare const X: Component<Props, Exports, Bindings>`
929
+ * instead, for Svelte 5+ consumers. Generic components get a per-component
930
+ * interface with a generic call signature instead of `Component<...>`
931
+ * directly, since a `declare const` can't itself carry a generic type
932
+ * parameter (see `genGenericComponentDeclaration`).
933
+ */
934
+ format?: "class" | "component";
935
+ }
936
+
937
+ type SveldOptions = SveldRuntimeOptions;
938
+
939
+ export interface SveldResult {
940
+ /** Diagnostics from this run. */
941
+ diagnostics: SveldDiagnostic[];
942
+ /** Populated when `check` is enabled: the API diff against the committed snapshot. */
943
+ check?: CheckResult;
944
+ /** Parse errors for components that failed to parse (empty unless `failFast` is disabled and a component errors). */
945
+ errors: ComponentParseError[];
946
+ /**
947
+ * The component API document for the exported components, exactly as the
948
+ * `json` writer writes `COMPONENT_API.json`. Populated whether or not
949
+ * `json` is enabled, so custom output can be rendered from it directly.
950
+ */
951
+ document: ComponentApiDocument;
952
+ /**
953
+ * Suggested process exit code for this run, using the same mapping as the
954
+ * CLI (see {@link resolveExitCode}). `sveld()` never mutates `process.exitCode` itself; assign this
955
+ * value yourself if you want the process to exit non-zero.
956
+ */
957
+ exitCode: ExitCode;
958
+ }
959
+
960
+ type ExitCode = 0 | 1 | 2 | 3 | 4;
961
+
962
+ export declare function sveld(opts?: SveldOptions): Promise<SveldResult>;