sveld 0.35.0 → 0.35.2

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.
Files changed (54) hide show
  1. package/README.md +46 -4
  2. package/cli.js +1 -1
  3. package/lib/ComponentParser.d.ts +164 -398
  4. package/lib/ast-guards.d.ts +2 -0
  5. package/lib/browser.d.ts +39 -0
  6. package/lib/browser.js +268 -0
  7. package/lib/bundle.d.ts +9 -4
  8. package/lib/chunk-1p4ka68s.js +2 -0
  9. package/lib/chunk-72hx9e9w.js +20 -0
  10. package/lib/chunk-7qz0hzgw.js +217 -0
  11. package/lib/chunk-8xw75w8t.js +10 -0
  12. package/lib/chunk-cxrw7gzr.js +2 -0
  13. package/lib/chunk-jdnsv86e.js +1 -0
  14. package/lib/chunk-pmj8c3yv.js +6 -0
  15. package/lib/chunk-s9mzxa4y.js +1 -0
  16. package/lib/chunk-v4q9vw0y.js +62 -0
  17. package/lib/chunk-xkrgedm4.js +4 -0
  18. package/lib/chunk-zva3xjwa.js +13 -0
  19. package/lib/cli-entry.d.ts +12 -0
  20. package/lib/cli-entry.js +1 -0
  21. package/lib/get-svelte-entry.d.ts +0 -1
  22. package/lib/index.js +1 -484
  23. package/lib/parse-cache.d.ts +1 -1
  24. package/lib/parse-entry-exports.d.ts +2 -2
  25. package/lib/parse-exports.d.ts +5 -1
  26. package/lib/parsed-component-metadata.d.ts +13 -0
  27. package/lib/parser/bindings.d.ts +0 -2
  28. package/lib/parser/context.d.ts +13 -51
  29. package/lib/parser/events.d.ts +0 -2
  30. package/lib/parser/jsdoc.d.ts +0 -4
  31. package/lib/parser/prop-shared.d.ts +84 -0
  32. package/lib/parser/props.d.ts +6 -2
  33. package/lib/parser/rest-props.d.ts +0 -2
  34. package/lib/parser/runes-detection.d.ts +13 -0
  35. package/lib/parser/scopes.d.ts +23 -7
  36. package/lib/parser/slots.d.ts +1 -6
  37. package/lib/parser/source-position.d.ts +0 -4
  38. package/lib/parser/type-resolution.d.ts +4 -14
  39. package/lib/parser/typescript-casts.d.ts +1 -0
  40. package/lib/parser/utils.d.ts +1 -0
  41. package/lib/parser/variable-jsdoc.d.ts +12 -0
  42. package/lib/parser-stack.d.ts +20 -0
  43. package/lib/path.d.ts +0 -1
  44. package/lib/resolve-types.d.ts +1 -1
  45. package/lib/svelte-parse.d.ts +4 -0
  46. package/lib/svelte-version.d.ts +1 -0
  47. package/lib/writer/Writer.d.ts +7 -29
  48. package/lib/writer/WriterMarkdown.d.ts +0 -2
  49. package/lib/writer/markdown-format-utils.d.ts +0 -84
  50. package/lib/writer/writer-json.d.ts +2 -12
  51. package/lib/writer/writer-markdown.d.ts +0 -2
  52. package/lib/writer/writer-ts-definitions-core.d.ts +1 -9
  53. package/lib/writer/writer-ts-definitions.d.ts +1 -28
  54. package/package.json +6 -1
@@ -1,8 +1,9 @@
1
1
  import type { Property } from "estree";
2
2
  import type { Node } from "estree-walker";
3
3
  import type { SveldDiagnostic } from "./diagnostics";
4
- /** Returns `value`, or `undefined` when it's `undefined` or the empty string. */
5
- export declare function assignValue(value?: "" | string): string | undefined;
4
+ import { PARSED_COMPONENT_TYPE_SCRIPT_METADATA } from "./parsed-component-metadata";
5
+ import { assignValueOrUndefined } from "./parser/utils";
6
+ export { assignValueOrUndefined as assignValue };
6
7
  /** Structured JSDoc tag (e.g. `{ name: "since", body: "1.2.0" }`). */
7
8
  export interface JsDocPassthroughTag {
8
9
  name: string;
@@ -52,6 +53,16 @@ export type ModernRunesTypeNode = {
52
53
  typeName?: unknown;
53
54
  types?: ModernRunesTypeNode[];
54
55
  members?: ModernRunesTypeMember[];
56
+ /** Declaration-side `<T, U = Default>` (interfaces/type aliases). */
57
+ typeParameters?: {
58
+ params?: Array<{
59
+ name?: string;
60
+ }>;
61
+ };
62
+ /** Reference-side `<string, number>` concrete arguments (`TSTypeReference`). */
63
+ typeArguments?: {
64
+ params?: ModernRunesTypeNode[];
65
+ };
55
66
  };
56
67
  export type ModernRunesTypeMember = {
57
68
  type?: string;
@@ -82,11 +93,15 @@ export interface ParsedComponentTypeScriptMetadata {
82
93
  canonicalPropNames: string[];
83
94
  localTypeDeclarations: string[];
84
95
  typeImportStatements: string[];
96
+ /**
97
+ * Whether `canonicalPropsType` mentions one of the component's own
98
+ * `<script generics="...">` parameters (e.g. `Props<T>`). The semantic
99
+ * resolver has no binding for `T`, so `resolveTypes` must leave this
100
+ * component's props as their AST-derived text rather than expand them.
101
+ */
102
+ referencesComponentGenerics?: boolean;
85
103
  }
86
- export declare const PARSED_COMPONENT_TYPE_SCRIPT_METADATA: unique symbol;
87
- export declare function getParsedComponentTypeScriptMetadata(component: {
88
- [PARSED_COMPONENT_TYPE_SCRIPT_METADATA]?: ParsedComponentTypeScriptMetadata;
89
- }): ParsedComponentTypeScriptMetadata | undefined;
104
+ export { applyResolvedProps, getParsedComponentTypeScriptMetadata, PARSED_COMPONENT_TYPE_SCRIPT_METADATA, } from "./parsed-component-metadata";
90
105
  /** One prop returned by the TypeScript checker during `resolveTypes`. */
91
106
  export interface ResolvedComponentProp {
92
107
  name: string;
@@ -94,8 +109,6 @@ export interface ResolvedComponentProp {
94
109
  isRequired: boolean;
95
110
  description?: string;
96
111
  }
97
- /** Append checker-resolved props. Names the AST walker already found are left alone. */
98
- export declare function applyResolvedProps(component: ParsedComponent, resolved: ResolvedComponentProp[]): void;
99
112
  export type SyntaxMode = "legacy" | "runes";
100
113
  export type ScriptLanguage = "js" | "ts";
101
114
  export type ScopeBindingKind = "prop" | "local";
@@ -134,177 +147,172 @@ type ModernScriptAttribute = {
134
147
  export type ModernScriptNode = {
135
148
  attributes?: ModernScriptAttribute[];
136
149
  };
137
- /**
138
- * Diagnostic information for component parsing.
139
- *
140
- * Used to provide context about the component being parsed for error
141
- * messages and logging.
142
- */
143
150
  interface ComponentParserDiagnostics {
144
- /** The module/component name (e.g., "Button", "App") */
145
151
  moduleName: string;
146
- /** The file path to the component (e.g., "./Button.svelte") */
147
152
  filePath: string;
148
153
  }
149
154
  export type ComponentPropBinding = "readonly" | "writable";
150
- /**
151
- * Parameter information for function props.
152
- *
153
- * Extracted from JSDoc `@param` tags to provide detailed function signatures.
154
- */
155
+ /** Function prop parameter from JSDoc `@param` tags. */
155
156
  export interface ComponentPropParam {
156
- /** The parameter name */
157
+ /** Parameter name. */
157
158
  name: string;
158
- /** The parameter type (e.g., "string", "number", "CustomType") */
159
+ /** Parameter type (e.g. `"string"`, `"CustomType"`). */
159
160
  type: string;
160
- /** Optional description from JSDoc */
161
+ /** From JSDoc `@param`. */
161
162
  description?: string;
162
- /** Whether the parameter is optional */
163
+ /** True when optional. */
163
164
  optional?: boolean;
164
165
  }
165
166
  /**
166
- * Component prop definition extracted from Svelte component.
167
+ * A parsed component prop: the shared internal IR that every prop front-end
168
+ * (legacy `<script context="module">` exports, legacy instance
169
+ * `export let`/`export function`, and runes `$props()` destructuring)
170
+ * produces via {@link resolvePropTypeAndDocs}, then hands to `addProp`. The
171
+ * three front-ends differ only in how they extract the raw signals (type
172
+ * text, JSDoc, initializer shape) from their respective AST shapes; the
173
+ * decisions below are shared and, outside the two documented mode
174
+ * differences, identical across modes.
167
175
  *
168
- * Represents a single prop that can be passed to the component, including
169
- * its type, default value, description, and metadata about whether it's
170
- * required, reactive, or a function.
176
+ * - `typeSource` precedence: an explicit TypeScript annotation always wins,
177
+ * then JSDoc (`@type`/`@param`/`@returns`), then a type resolved from an
178
+ * identifier default's own JSDoc, and only then a bare inferred/initializer
179
+ * type. See {@link resolveTypeSource}.
180
+ * - JSDoc-vs-TS merge: `type`/`params`/`returnType`/`description` each
181
+ * independently prefer their JSDoc-sourced value over the identifier
182
+ * default's resolved value; an explicit TypeScript type additionally beats
183
+ * JSDoc for `type` only.
184
+ * - Mode difference (preserved, not converged): legacy `export let`/
185
+ * `export function` never infers `isFunction` from a function-shaped type
186
+ * text; runes `$props()` does (`inferIsFunctionFromTypeSignature`).
187
+ * - Mode difference (preserved, not converged): legacy falls back to a
188
+ * matching `@typedef`'s own description when the prop has none; runes does
189
+ * not pass `typedefs` to {@link resolvePropTypeAndDocs} today.
171
190
  */
172
191
  export interface ComponentProp {
173
- /** The prop name as declared in the component */
192
+ /** Public prop name. */
174
193
  name: string;
175
- /** The declaration kind: "let" (required), "const" (optional with default), or "function" */
194
+ /** `"let"` (required), `"const"` (default), or `"function"`. */
176
195
  kind: "let" | "const" | "function";
177
- /** Whether this prop is declared as `const` (has a default value) */
196
+ /** True when declared with `const`. */
178
197
  constant: boolean;
179
- /** The TypeScript type of the prop (e.g., "string", "number | string") */
198
+ /** TypeScript type text. */
180
199
  type?: string;
181
- /** Conservative provenance for the prop type */
200
+ /** Conservative provenance for the prop type. See the precedence rule on {@link ComponentProp}. */
182
201
  typeSource?: ComponentPropTypeSource;
183
- /** Local variable name, emitted when it differs from the public prop name */
202
+ /** Local binding when it differs from the public name. */
184
203
  localName?: string;
185
- /** The default value as a string representation of the source code */
204
+ /** Default value as source text; unset when the prop has no initializer/default. */
186
205
  value?: string;
187
- /** Structured default value metadata for docs UIs */
206
+ /** Structured default value metadata for docs UIs; set alongside `value` from the same initializer. */
188
207
  defaultValue?: ComponentPropDefaultValue;
189
- /** Description extracted from JSDoc comments */
208
+ /** From JSDoc, or a matching `@typedef`'s own description (legacy only; see {@link ComponentProp}). */
190
209
  description?: string;
191
- /** Function parameters (for function props) extracted from `@param` tags */
210
+ /** From JSDoc `@param` on function props. */
192
211
  params?: ComponentPropParam[];
193
- /** Return type (for function props) extracted from `@returns` tag */
212
+ /** From JSDoc `@returns` on function props. */
194
213
  returnType?: string;
195
- /** Whether this prop is a function (arrow function or function expression) */
214
+ /**
215
+ * True for arrow/function-expression initializers and bare `function`
216
+ * declarations in every mode; additionally true for a function-shaped
217
+ * type/JSDoc signature in runes only (see {@link ComponentProp}).
218
+ */
196
219
  isFunction: boolean;
197
- /** Whether this prop is a function declaration (not an expression) */
220
+ /** True for `function` declarations. */
198
221
  isFunctionDeclaration: boolean;
199
- /** Whether this prop is required (no default value, declared with `let`) */
222
+ /** True when declared with `let` and no default. */
200
223
  isRequired: boolean;
201
- /** Whether this prop is reactive (can change and trigger reactivity) */
224
+ /**
225
+ * True when the prop is mutated locally (legacy, inferred from assignment/
226
+ * binding targets) or declared with `$bindable()` (runes).
227
+ */
202
228
  reactive: boolean;
203
- /** Explicit author-documented binding direction from `@bindable` JSDoc */
229
+ /** Binding direction from `@bindable` JSDoc. */
204
230
  binding?: ComponentPropBinding;
205
- /** True when the prop is explicitly declared with Svelte 5 `$bindable()` */
231
+ /** True when declared with Svelte 5 `$bindable()` (runes only). */
206
232
  bindable?: true;
207
233
  /** From `@deprecated` JSDoc. */
208
234
  deprecated?: DeprecatedValue;
209
- /** Structured `@since` / `@example` tags, in source order. */
235
+ /** `@since` / `@example` tags in source order. */
210
236
  tags?: JsDocPassthroughTag[];
211
- /** Source range for the prop declaration, when available */
237
+ /** Source range when available. */
212
238
  source?: SourceRange;
213
239
  }
214
- /**
215
- * Component slot definition.
216
- *
217
- * Represents a slot that can be used to pass content into the component.
218
- * Includes information about slot props, fallback content, and descriptions.
219
- */
220
240
  export interface ComponentSlot {
221
- /** The slot name (null or undefined for default slot) */
241
+ /** Slot name (`null` for the default slot). */
222
242
  name?: string | null;
223
- /** Whether this is the default slot */
243
+ /** True for the default slot. */
224
244
  default: boolean;
225
- /** Fallback content to display when slot is not provided */
245
+ /** Fallback content when the slot is empty. */
226
246
  fallback?: string;
227
- /** TypeScript type definition for slot props (e.g., "{ title: string }") */
247
+ /** Slot props as TypeScript type text. */
228
248
  slot_props?: string;
229
- /** Description extracted from JSDoc `@slot` or `@snippet` tags */
249
+ /** From JSDoc `@slot` or `@snippet`. */
230
250
  description?: string;
231
251
  /** From `@deprecated` JSDoc. */
232
252
  deprecated?: DeprecatedValue;
233
- /**
234
- * JSDoc tags that appeared after the prose description and before `@slot` / `@snippet`
235
- * (e.g. `@example`), in source order.
236
- */
253
+ /** Tags between the description and `@slot`/`@snippet` (e.g. `@example`), in source order. */
237
254
  tags?: JsDocPassthroughTag[];
238
- /** Source range for the slot/snippet declaration or documentation tag, when available */
255
+ /** Source range when available. */
239
256
  source?: SourceRange;
240
257
  }
241
- /**
242
- * Slot prop value definition.
243
- *
244
- * Used internally to track slot prop types and whether they should be
245
- * replaced with prop type references.
246
- */
258
+ /** Slot prop type text or a reference to resolve at finalize time. */
247
259
  export interface SlotPropValue {
248
- /** The prop type value or reference */
260
+ /** Type text or reference. */
249
261
  value?: string;
250
- /** Whether this value should be replaced with a prop type reference */
262
+ /** True to replace with a prop type reference. */
251
263
  replace: boolean;
252
264
  }
253
265
  export type SlotProps = Record<string, SlotPropValue>;
254
266
  /**
255
- * Event that is forwarded from a child component or element.
267
+ * Internal representation of {@link ComponentSlot} used while parsing.
256
268
  *
257
- * Forwarded events are those that use `on:eventname` syntax without
258
- * a handler, passing the event through to the parent.
269
+ * `slot_props` is either raw TS type text (from a JSDoc `@slot`/`@snippet` tag,
270
+ * used as-is) or a structured {@link SlotProps} map (from template parsing,
271
+ * formatted into TS type text once at the end of the parse). Keeping it
272
+ * structured until then avoids a JSON.stringify/JSON.parse round-trip per slot.
259
273
  */
274
+ export type InternalComponentSlot = Omit<ComponentSlot, "slot_props"> & {
275
+ slot_props?: string | SlotProps;
276
+ };
277
+ /** Event forwarded with `on:eventname` and no handler. */
260
278
  export interface ForwardedEvent {
261
- /** Always "forwarded" for forwarded events */
279
+ /** Discriminator: `"forwarded"`. */
262
280
  type: "forwarded";
263
- /** The event name (e.g., "click", "change") */
281
+ /** Event name. */
264
282
  name: string;
265
- /** The element or component that forwards this event */
283
+ /** Element or component that forwards the event. */
266
284
  element: ComponentInlineElement | ComponentElement;
267
- /** Description extracted from JSDoc `@event` tags */
285
+ /** From JSDoc `@event`. */
268
286
  description?: string;
269
287
  /** From `@deprecated` JSDoc. */
270
288
  deprecated?: DeprecatedValue;
271
- /** The detail type if explicitly specified in `@event` tag */
289
+ /** Detail type from `@event`. */
272
290
  detail?: string;
273
- /** Structured `@since` / `@example` tags, in source order. */
291
+ /** `@since` / `@example` tags in source order. */
274
292
  tags?: JsDocPassthroughTag[];
275
- /** Source range for the forwarded event declaration or documentation tag, when available */
293
+ /** Source range when available. */
276
294
  source?: SourceRange;
277
295
  }
278
- /**
279
- * Event that is dispatched by the component.
280
- *
281
- * Dispatched events are those created with `createEventDispatcher()` and
282
- * dispatched via `dispatch("eventname", detail)`, or dispatched from a custom
283
- * element via `$host().dispatchEvent(new CustomEvent("eventname", { detail }))`.
284
- */
296
+ /** Event from `createEventDispatcher()`, `dispatch()`, or `$host().dispatchEvent()`. */
285
297
  export interface DispatchedEvent {
286
- /** Always "dispatched" for dispatched events */
298
+ /** Discriminator: `"dispatched"`. */
287
299
  type: "dispatched";
288
- /** The event name (e.g., "click", "change") */
300
+ /** Event name. */
289
301
  name: string;
290
- /** The detail type (e.g., "{ value: string }", "null", "CustomEvent<...>") */
302
+ /** Detail type text. */
291
303
  detail?: string;
292
- /** Description extracted from JSDoc `@event` tags */
304
+ /** From JSDoc `@event`. */
293
305
  description?: string;
294
306
  /** From `@deprecated` JSDoc. */
295
307
  deprecated?: DeprecatedValue;
296
- /** Structured `@since` / `@example` tags, in source order. */
308
+ /** `@since` / `@example` tags in source order. */
297
309
  tags?: JsDocPassthroughTag[];
298
- /** Source range for the dispatched event call or documentation tag, when available */
310
+ /** Source range when available. */
299
311
  source?: SourceRange;
300
312
  }
301
313
  export type ComponentEvent = ForwardedEvent | DispatchedEvent;
302
314
  /**
303
- * Serialized version of {@link ForwardedEvent} for JSON output.
304
- *
305
- * This interface maintains backward compatibility by serializing the `element`
306
- * property as a string instead of an object. The element name is extracted
307
- * from the {@link ComponentInlineElement} or {@link ComponentElement} object.
315
+ * Serialized {@link ForwardedEvent} for JSON output. `element` is a string, not an object.
308
316
  *
309
317
  * @example
310
318
  * ```ts
@@ -316,63 +324,47 @@ export type ComponentEvent = ForwardedEvent | DispatchedEvent;
316
324
  * ```
317
325
  */
318
326
  export interface SerializedForwardedEvent {
319
- /** Always "forwarded" for forwarded events */
327
+ /** Discriminator: `"forwarded"`. */
320
328
  type: "forwarded";
321
- /** The event name (e.g., "click", "change") */
329
+ /** Event name. */
322
330
  name: string;
323
- /**
324
- * Serialized as string for JSON backward compatibility.
325
- * In the internal API, this is an object, but for JSON output it's a string.
326
- */
331
+ /** Element name as a string for JSON output. */
327
332
  element: string;
328
- /** Description extracted from JSDoc `@event` tags */
333
+ /** From JSDoc `@event`. */
329
334
  description?: string;
330
335
  /** From `@deprecated` JSDoc. */
331
336
  deprecated?: DeprecatedValue;
332
- /** The detail type if explicitly specified in `@event` tag */
337
+ /** Detail type from `@event`. */
333
338
  detail?: string;
334
- /** Structured `@since` / `@example` tags, in source order. */
339
+ /** `@since` / `@example` tags in source order. */
335
340
  tags?: JsDocPassthroughTag[];
336
- /** Source range for the forwarded event declaration or documentation tag, when available */
341
+ /** Source range when available. */
337
342
  source?: SourceRange;
338
343
  }
339
344
  export type SerializedComponentEvent = SerializedForwardedEvent | DispatchedEvent;
340
- /**
341
- * Type definition extracted from JSDoc `@typedef` tags.
342
- *
343
- * Represents custom types defined in component comments that can be
344
- * referenced by props, events, and other type annotations.
345
- */
345
+ /** JSDoc `@typedef` extracted as a named type. */
346
346
  export interface TypeDef {
347
- /** The type string representation (e.g., "{ x: number; y: number }") */
347
+ /** Type text (e.g. `"{ x: number; y: number }"`). */
348
348
  type: string;
349
- /** The type name (e.g., "Point", "User") */
349
+ /** Type name. */
350
350
  name: string;
351
- /** Description extracted from JSDoc comments */
351
+ /** From JSDoc. */
352
352
  description?: string;
353
- /** The full TypeScript type definition string (e.g., "type Point = { x: number; y: number }") */
353
+ /** Full `type` alias declaration text. */
354
354
  ts: string;
355
355
  }
356
356
  export type ComponentGenerics = [name: string, type: string] | null;
357
- /**
358
- * Represents an inline Svelte component element.
359
- *
360
- * Used to identify which component forwards an event or accepts rest props.
361
- */
362
357
  export interface ComponentInlineElement {
363
- /** Always "InlineComponent" for component elements */
358
+ /** Discriminator: `"InlineComponent"`. */
364
359
  type: "InlineComponent";
365
- /** The component name (e.g., "Button", "Modal") */
360
+ /** Component name. */
366
361
  name: string;
367
362
  }
368
363
  export interface ComponentElement {
369
364
  type: "Element";
370
365
  name: string;
371
366
  /**
372
- * For `svelte:element`, stores the hardcoded element tag if `this` is a literal string.
373
- *
374
- * When `svelte:element` is used with a static tag (e.g., `svelte:element this="div"`),
375
- * this property contains the tag name. If the tag is dynamic, this property is undefined.
367
+ * Static tag for `svelte:element this="div"`. Undefined when `this` is dynamic.
376
368
  *
377
369
  * @example
378
370
  * ```svelte
@@ -386,62 +378,43 @@ export interface ComponentElement {
386
378
  * ```
387
379
  */
388
380
  thisValue?: string;
389
- /** Inline or block description from the `@restProps` JSDoc tag */
381
+ /** From `@restProps` JSDoc. */
390
382
  description?: string;
391
383
  }
392
384
  export type RestProps = undefined | ComponentInlineElement | ComponentElement;
393
- /**
394
- * Interface extension information from JSDoc `@extends` tag.
395
- *
396
- * Allows components to extend external TypeScript interfaces for
397
- * better type safety and code reuse.
398
- */
385
+ /** JSDoc `@extends` target. */
399
386
  export interface Extends {
400
- /** The interface name to extend (e.g., "ButtonProps") */
387
+ /** Interface name (e.g. `"ButtonProps"`). */
401
388
  interface: string;
402
- /** The import path for the interface (e.g., "./types" or "carbon-components-svelte") */
389
+ /** Import path (e.g. `"./types"`). */
403
390
  import: string;
404
391
  }
405
392
  export interface ComponentPropBindings {
406
393
  elements: string[];
407
394
  }
408
- /**
409
- * Property definition for a component context.
410
- *
411
- * Represents a single property in a context object created with `setContext`.
412
- */
413
395
  export interface ComponentContextProp {
414
- /** The property name */
396
+ /** Property name. */
415
397
  name: string;
416
- /** The property type (inferred from JSDoc or variable types) */
398
+ /** Property type text. */
417
399
  type: string;
418
- /** Description extracted from JSDoc comments on the variable */
400
+ /** From JSDoc. */
419
401
  description?: string;
420
- /** Whether the property is optional */
402
+ /** True when optional. */
421
403
  optional: boolean;
422
404
  }
423
- /**
424
- * Component context definition.
425
- *
426
- * Represents a context created with `setContext(key, value)` that can be
427
- * accessed by child components via `getContext(key)`.
428
- */
405
+ /** Context from `setContext(key, value)`. */
429
406
  export interface ComponentContext {
430
- /** The context key (e.g., "modal", "tabs") */
407
+ /** Context key from `setContext`. */
431
408
  key: string;
432
- /** The generated TypeScript type name (e.g., "ModalContext", "TabsContext") */
409
+ /** Generated type name (e.g. `"ModalContext"`). */
433
410
  typeName: string;
434
- /** Description extracted from JSDoc comments */
411
+ /** From JSDoc. */
435
412
  description?: string;
436
- /** Properties available in this context */
413
+ /** Context object properties. */
437
414
  properties: ComponentContextProp[];
438
415
  }
439
416
  /**
440
- * Complete parsed component metadata.
441
- *
442
- * This is the main return type from {@link ComponentParser.parseSvelteComponent}.
443
- * Contains all extracted information about a Svelte component including props,
444
- * slots, events, types, and more.
417
+ * Complete parsed component metadata from {@link ComponentParser.parseSvelteComponent}.
445
418
  *
446
419
  * @example
447
420
  * ```ts
@@ -451,51 +424,39 @@ export interface ComponentContext {
451
424
  * filePath: "./Button.svelte"
452
425
  * });
453
426
  *
454
- * // Access component metadata:
455
- * parsed.props // Array of component props
456
- * parsed.slots // Array of component slots
457
- * parsed.events // Array of component events
458
- * parsed.typedefs // Array of custom type definitions
459
- * parsed.contexts // Array of context definitions
427
+ * parsed.props;
428
+ * parsed.slots;
429
+ * parsed.events;
430
+ * parsed.typedefs;
431
+ * parsed.contexts;
460
432
  * ```
461
433
  */
462
434
  export interface ParsedComponent {
463
- /** Source range for the component source that was parsed */
435
+ /** Source range of the parsed file. */
464
436
  source?: SourceRange;
465
- /** Whether the component uses legacy or runes syntax according to compiler metadata */
466
437
  syntaxMode: SyntaxMode;
467
- /** Language used by the instance or module script when it can be determined */
468
438
  scriptLanguage?: ScriptLanguage;
469
- /** Component props that can be passed to the component */
439
+ /** Instance-level props (`export let`/`export function`, or runes `$props()`). See {@link ComponentProp} for the shared IR these are built from. */
470
440
  props: ComponentProp[];
471
- /** Exports from `<script context="module">` block */
441
+ /** Exports from `<script context="module">`. Same {@link ComponentProp} shape as `props`, resolved through the same shared decisions. */
472
442
  moduleExports: ComponentProp[];
473
- /** Slots available in the component template */
474
443
  slots: ComponentSlot[];
475
- /** Events that the component can dispatch or forward (serialized for JSON/API output) */
444
+ /** Serialized events for JSON/API output. */
476
445
  events: SerializedComponentEvent[];
477
- /** Custom type definitions from JSDoc `@typedef` tags */
478
446
  typedefs: TypeDef[];
479
- /** Generic type parameters (e.g., `[name: "T", type: "string"]`) or null */
480
447
  generics: null | ComponentGenerics;
481
- /** Rest props configuration (which elements/components accept rest props) */
482
448
  rest_props: RestProps;
483
- /** Interface extension from JSDoc `@extends` tag */
484
449
  extends?: Extends;
485
- /** Component-level description from `@component` HTML comment */
450
+ /** From `@component` HTML comment. */
486
451
  componentComment?: string;
487
- /** Source range for the `@component` HTML comment, when available */
488
452
  componentCommentSource?: SourceRange;
489
- /** Contexts created with `setContext` in the component */
490
453
  contexts?: ComponentContext[];
491
- /** Custom-element tag name from `<svelte:options customElement="x-foo" />` (or the object form's `tag`), when present */
492
454
  customElementTag?: string;
493
455
  /**
494
456
  * Type guesses from this parse (unknown props, `any` contexts, orphan `@event` tags).
495
- * Set on every {@link ComponentParser.parseSvelteComponent} call.
496
457
  */
497
458
  diagnostics?: SveldDiagnostic[];
498
- /** Internal writer-only TypeScript metadata. Not serialized to JSON. */
459
+ /** Writer-only TypeScript metadata. Not serialized to JSON. */
499
460
  [PARSED_COMPONENT_TYPE_SCRIPT_METADATA]?: ParsedComponentTypeScriptMetadata;
500
461
  }
501
462
  export default class ComponentParser {
@@ -532,38 +493,7 @@ export default class ComponentParser {
532
493
  getPropTypeByLocalOrPublic(name: string): string | undefined;
533
494
  getExplicitPropType(name: string): string | undefined;
534
495
  getPropertyName(node: Property["key"]): string | undefined;
535
- /**
536
- * Checks if a MemberExpression represents a well-known numeric constant.
537
- *
538
- * Identifies constants from the Number and Math objects that should be
539
- * typed as `number` rather than their literal values.
540
- *
541
- * @param memberExpr - The AST node to check
542
- * @returns True if the expression is a recognized numeric constant
543
- *
544
- * @example
545
- * ```ts
546
- * // Recognized constants:
547
- * Number.POSITIVE_INFINITY // true
548
- * Number.MAX_VALUE // true
549
- * Math.PI // true
550
- * Math.E // true
551
- *
552
- * // Not recognized:
553
- * Custom.CONSTANT // false
554
- * Number.UNKNOWN // false
555
- * ```
556
- */
557
496
  isNumericConstant(memberExpr: unknown): boolean;
558
- resolveTypeSource({ hasTypeScriptType, hasJSDocType, inferredType, finalType, }: {
559
- hasTypeScriptType?: boolean;
560
- hasJSDocType?: boolean;
561
- inferredType?: string;
562
- finalType?: string;
563
- }): ComponentPropTypeSource;
564
- /**
565
- * Look up JSDoc on a local variable declaration by name.
566
- */
567
497
  resolveLocalVarJSDoc(name: string): {
568
498
  type?: string;
569
499
  params?: ComponentPropParam[];
@@ -573,212 +503,49 @@ export default class ComponentParser {
573
503
  deprecated?: DeprecatedValue;
574
504
  tags?: JsDocPassthroughTag[];
575
505
  } | undefined;
576
- /**
577
- * Adds or merges a module export to the moduleExports map.
578
- *
579
- * Similar to {@link addProp}, but for exported values from the module script.
580
- * If an export with the same name already exists, the new data is merged
581
- * with the existing export.
582
- *
583
- * @param prop_name - The name of the exported value
584
- * @param data - The export data to add or merge
585
- *
586
- * @example
587
- * ```ts
588
- * // For: export const API_URL = "https://api.example.com"
589
- * addModuleExport("API_URL", {
590
- * name: "API_URL",
591
- * kind: "const",
592
- * type: "string",
593
- * value: '"https://api.example.com"'
594
- * })
595
- * ```
596
- */
597
506
  private addModuleExport;
598
507
  /**
599
- * Normalizes type strings by aliasing common patterns.
600
- *
601
- * Converts `*` to `any` (common JSDoc wildcard) and trims whitespace
602
- * from type annotations.
603
- *
604
- * @param type - The type string to normalize
605
- * @returns The normalized type string
606
- *
607
508
  * @example
608
509
  * ```ts
609
- * aliasType("*") // Returns: "any"
610
- * aliasType(" string ") // Returns: "string"
611
- * aliasType("number") // Returns: "number"
510
+ * aliasType("*"); // "any"
511
+ * aliasType(" string "); // "string"
612
512
  * ```
613
513
  */
614
514
  aliasType(type: string): string;
615
515
  /**
616
- * Builds a cache of variable type information from JSDoc comments.
617
- *
618
- * Scans the source code for variable declarations and extracts type information
619
- * from preceding JSDoc comments. This cache is used to infer types for context
620
- * properties and other variable references.
621
- *
622
- * @example
623
- * ```ts
624
- * // Source code:
625
- * /**
626
- * * @type {string}
627
- * * The user's name
628
- * *\/
629
- * const userName = "John";
630
- *
631
- * // Cache entry:
632
- * // { "userName": { type: "string", description: "The user's name" } }
633
- * ```
634
- */
635
- private buildVariableInfoCache;
636
- /**
637
- * Cache for compiled regex patterns for variable name matching.
638
- *
639
- * Stores three regex patterns (const, let, function) per variable name
640
- * to avoid recreating them on each lookup. Improves performance when
641
- * searching for the same variable multiple times.
642
- */
643
- private static readonly VAR_NAME_REGEX_CACHE;
644
- /**
645
- * Gets or creates cached regex patterns for matching variable declarations.
646
- *
647
- * Creates three regex patterns for matching const, let, and function declarations
648
- * of a specific variable name. The patterns are cached to avoid recreating them
649
- * for the same variable name.
650
- *
651
- * @param varName - The variable name to create regex patterns for
652
- * @returns A tuple of three RegExp objects for const, let, and function patterns
653
- *
654
- * @example
655
- * ```ts
656
- * getVarNameRegexes("count")
657
- * // Returns:
658
- * // [
659
- * // /\bconst\s+count\s*=/,
660
- * // /\blet\s+count\s*=/,
661
- * // /\bfunction\s+count\s*\(/
662
- * // ]
663
- * ```
664
- */
665
- private static getVarNameRegexes;
666
- /**
667
- * Finds the type and description for a variable by searching for its JSDoc comment.
668
- *
669
- * First checks the cache built by {@link buildVariableInfoCache}. If not found,
670
- * searches the source code directly for the variable declaration and its
671
- * preceding JSDoc comment.
672
- *
673
- * @param varName - The variable name to look up
674
- * @returns The type and description if found, null otherwise
675
- *
676
516
  * @example
677
517
  * ```ts
678
- * // Source:
679
- * /**
680
- * * @type {number}
681
- * * The count value
682
- * *\/
683
- * const count = 0;
684
- *
685
- * findVariableTypeAndDescription("count")
686
- * // Returns: { type: "number", description: "The count value" }
518
+ * // Given:
519
+ * // /**
520
+ * // * @type {number}
521
+ * // * The count value
522
+ * // *\/
523
+ * // const count = 0;
524
+ *
525
+ * findVariableTypeAndDescription("count");
526
+ * // { type: "number", description: "The count value" }
687
527
  * ```
688
528
  */
689
529
  findVariableTypeAndDescription(varName: string): {
690
530
  type: string;
691
531
  description?: string;
692
532
  } | null;
533
+ accumulateGeneric(name: string, constraint: string): void;
693
534
  /**
694
- * Cleans up all parser state, resetting the instance for reuse.
695
- *
696
- * Clears all maps, caches, and resets all state variables to their initial
697
- * values. Should be called before parsing a new component or when the
698
- * parser instance needs to be reset.
535
+ * Resets parser state for reuse between parses.
699
536
  *
700
537
  * @example
701
538
  * ```ts
702
539
  * parser.parseSvelteComponent(source1, diagnostics1);
703
- * parser.cleanup(); // Reset state
704
- * parser.parseSvelteComponent(source2, diagnostics2); // Fresh parse
540
+ * parser.cleanup();
541
+ * parser.parseSvelteComponent(source2, diagnostics2);
705
542
  * ```
706
543
  */
707
- accumulateGeneric(name: string, constraint: string): void;
708
544
  cleanup(): void;
709
- /**
710
- * Pre-compiled regex for matching script blocks in Svelte components.
711
- *
712
- * Matches `<script>` tags and their content, capturing the opening tag,
713
- * script content, and closing tag. Global and case-insensitive flags
714
- * allow matching multiple script blocks.
715
- *
716
- * @example
717
- * ```ts
718
- * // Matches:
719
- * // "<script>const x = 1;</script>"
720
- * // "<script lang='ts'>...</script>"
721
- * ```
722
- */
723
545
  private static readonly SCRIPT_BLOCK_REGEX;
724
- /**
725
- * Pre-compiled regex for matching TypeScript directive comments.
726
- *
727
- * Matches TypeScript directive comments like ts-ignore, ts-expect-error,
728
- * etc. Used to remove these directives from script blocks before JSDoc parsing.
729
- *
730
- * @example
731
- * ```ts
732
- * // Matches:
733
- * // "// ts-ignore"
734
- * // "// ts-expect-error: reason"
735
- * // "// ts-nocheck"
736
- * ```
737
- */
738
546
  private static readonly TS_DIRECTIVE_REGEX;
739
- /**
740
- * Strips TypeScript directive comments from script blocks only.
741
- *
742
- * Removes TypeScript directive comments (e.g., ts-ignore, ts-expect-error directives)
743
- * from within `<script>` blocks to prevent them from interfering with JSDoc parsing.
744
- * Directives outside script blocks are left untouched.
745
- *
746
- * @param source - The Svelte component source code
747
- * @returns The source code with TypeScript directives removed from script blocks
748
- *
749
- * @example
750
- * ```ts
751
- * // Input (with TypeScript directive):
752
- * <script>
753
- * const x: string = 123; // directive removed
754
- * </script>
755
- *
756
- * // Output (directive stripped):
757
- * <script>
758
- * const x: string = 123;
759
- * </script>
760
- * ```
761
- */
762
547
  private static stripTypeScriptDirectivesFromScripts;
763
548
  /**
764
- * Parses a Svelte component and extracts all component metadata.
765
- *
766
- * This is the main entry point that orchestrates the entire parsing process:
767
- * 1. Cleans up previous state
768
- * 2. Strips TypeScript directives that might interfere with JSDoc
769
- * 3. Compiles the component to get the AST
770
- * 4. Collects reactive variables
771
- * 5. Builds variable type cache
772
- * 6. Parses custom types from JSDoc comments
773
- * 7. Walks the AST to extract props, slots, events, bindings, and contexts
774
- * 8. Post-processes events to distinguish dispatched vs forwarded
775
- * 9. Processes props with bindings and slots with prop references
776
- * 10. Returns the complete parsed component structure
777
- *
778
- * @param source - The Svelte component source code
779
- * @param diagnostics - Diagnostic information (module name and file path)
780
- * @returns A ParsedComponent object containing all extracted metadata
781
- *
782
549
  * @example
783
550
  * ```ts
784
551
  * const parser = new ComponentParser();
@@ -786,9 +553,8 @@ export default class ComponentParser {
786
553
  * moduleName: "Button",
787
554
  * filePath: "./Button.svelte"
788
555
  * });
789
- * // Returns: { props: [...], slots: [...], events: [...], ... }
556
+ * // { props, slots, events, typedefs, ... }
790
557
  * ```
791
558
  */
792
559
  parseSvelteComponent(source: string, diagnostics: ComponentParserDiagnostics): ParsedComponent;
793
560
  }
794
- export {};