sveld 0.25.11 → 0.25.12

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 CHANGED
@@ -8,11 +8,11 @@
8
8
 
9
9
  The purpose of this project is to make third party Svelte component libraries compatible with the Svelte Language Server and TypeScript with minimal effort required by the author. For example, TypeScript definitions may be used during development via intelligent code completion in Integrated Development Environments (IDE) like VSCode.
10
10
 
11
- [Carbon Components Svelte](https://github.com/IBM/carbon-components-svelte) uses this library to auto-generate component types and API metadata:
11
+ [Carbon Components Svelte](https://github.com/carbon-design-system/carbon-components-svelte) uses this library to auto-generate component types and API metadata:
12
12
 
13
- - [TypeScript definitions](https://github.com/IBM/carbon-components-svelte/blob/master/types): Component TypeScript definitions
14
- - [Component Index](https://github.com/IBM/carbon-components-svelte/blob/master/COMPONENT_INDEX.md): Markdown file documenting component props, slots, and events
15
- - [Component API](https://github.com/IBM/carbon-components-svelte/blob/master/docs/src/COMPONENT_API.json): Component API metadata in JSON format
13
+ - [TypeScript definitions](https://github.com/carbon-design-system/carbon-components-svelte/blob/master/types): Component TypeScript definitions
14
+ - [Component Index](https://github.com/carbon-design-system/carbon-components-svelte/blob/master/COMPONENT_INDEX.md): Markdown file documenting component props, slots, and events
15
+ - [Component API](https://github.com/carbon-design-system/carbon-components-svelte/blob/master/docs/src/COMPONENT_API.json): Component API metadata in JSON format
16
16
 
17
17
  **Note:** `sveld` supports Svelte 3, 4, and 5, but does not support Svelte 5-specific syntax or runes-only usage. Components must use traditional Svelte syntax (e.g., `export let` for props, not `$props()`).
18
18
 
@@ -430,9 +430,12 @@ Output:
430
430
 
431
431
  ```ts
432
432
  export type User = {
433
- /** The user's full name */ name: string;
434
- /** The user's email address */ email: string;
435
- /** The user's age in years */ age: number;
433
+ /** The user's full name */
434
+ name: string;
435
+ /** The user's email address */
436
+ email: string;
437
+ /** The user's age in years */
438
+ age: number;
436
439
  };
437
440
 
438
441
  export type ComponentProps = {
@@ -478,10 +481,14 @@ Output:
478
481
 
479
482
  ```ts
480
483
  export type ComponentConfig = {
481
- /** Whether the component is enabled */ enabled: boolean;
482
- /** The component theme */ theme: string;
483
- /** Optional timeout in milliseconds @default 5000 */ timeout?: number;
484
- /** Optional debug mode flag */ debug?: boolean;
484
+ /** Whether the component is enabled */
485
+ enabled: boolean;
486
+ /** The component theme */
487
+ theme: string;
488
+ /** Optional timeout in milliseconds @default 5000 */
489
+ timeout?: number;
490
+ /** Optional debug mode flag */
491
+ debug?: boolean;
485
492
  };
486
493
 
487
494
  export type ComponentProps = {
@@ -735,9 +742,12 @@ export default class Component extends SvelteComponentTyped<
735
742
  {
736
743
  /** Fired when the user submits the form */
737
744
  submit: CustomEvent<{
738
- /** The user's name */ name: string;
739
- /** The user's email address */ email: string;
740
- /** Whether the user opted into the newsletter */ newsletter: boolean;
745
+ /** The user's name */
746
+ name: string;
747
+ /** The user's email address */
748
+ email: string;
749
+ /** Whether the user opted into the newsletter */
750
+ newsletter: boolean;
741
751
  }>;
742
752
  },
743
753
  Record<string, never>
@@ -782,10 +792,14 @@ export default class Component extends SvelteComponentTyped<
782
792
  {
783
793
  /** Snowball event fired when throwing a snowball */
784
794
  snowball: CustomEvent<{
785
- /** Indicates whether the snowball is tightly packed */ isPacked: boolean;
786
- /** The speed of the snowball in mph */ speed: number;
787
- /** Optional color of the snowball */ color?: string;
788
- /** Optional density with default value @default 0.9 */ density?: number;
795
+ /** Indicates whether the snowball is tightly packed */
796
+ isPacked: boolean;
797
+ /** The speed of the snowball in mph */
798
+ speed: number;
799
+ /** Optional color of the snowball */
800
+ color?: string;
801
+ /** Optional density with default value @default 0.9 */
802
+ density?: number;
789
803
  }>;
790
804
  },
791
805
  Record<string, never>
@@ -1171,7 +1185,8 @@ Output:
1171
1185
 
1172
1186
  ```ts
1173
1187
  export type NotificationData = {
1174
- /** Optional id for deduplication */ id?: string;
1188
+ /** Optional id for deduplication */
1189
+ id?: string;
1175
1190
  kind?: "error" | "info" | "success";
1176
1191
  };
1177
1192
 
@@ -526,8 +526,72 @@ class ComponentParser {
526
526
  typeof unaryExpr.end === "number") {
527
527
  value = this.sourceAtPos(unaryExpr.start, unaryExpr.end);
528
528
  }
529
- if (unaryExpr.argument && typeof unaryExpr.argument === "object" && "value" in unaryExpr.argument) {
530
- type = typeof unaryExpr.argument.value;
529
+ if (unaryExpr.argument) {
530
+ // If the argument is another UnaryExpression, recursively resolve the type
531
+ if (typeof unaryExpr.argument === "object" &&
532
+ "type" in unaryExpr.argument &&
533
+ unaryExpr.argument.type === "UnaryExpression") {
534
+ const nestedResult = this.processInitializer(unaryExpr.argument);
535
+ type = nestedResult.type;
536
+ }
537
+ else if (typeof unaryExpr.argument === "object" && "value" in unaryExpr.argument) {
538
+ // Direct literal argument
539
+ type = typeof unaryExpr.argument.value;
540
+ }
541
+ }
542
+ }
543
+ else if (init.type === "NewExpression") {
544
+ const newExpr = init;
545
+ if ("start" in newExpr &&
546
+ "end" in newExpr &&
547
+ typeof newExpr.start === "number" &&
548
+ typeof newExpr.end === "number") {
549
+ value = this.sourceAtPos(newExpr.start, newExpr.end);
550
+ }
551
+ // Infer type from callee if it's an Identifier (e.g., new Date() -> Date)
552
+ if (newExpr.callee &&
553
+ typeof newExpr.callee === "object" &&
554
+ "type" in newExpr.callee &&
555
+ newExpr.callee.type === "Identifier") {
556
+ const calleeName = newExpr.callee.name;
557
+ // Common built-in constructors
558
+ if (calleeName === "Date") {
559
+ type = "Date";
560
+ }
561
+ else if (calleeName === "Map") {
562
+ type = "Map<any, any>";
563
+ }
564
+ else if (calleeName === "Set") {
565
+ type = "Set<any>";
566
+ }
567
+ else if (calleeName === "WeakMap") {
568
+ type = "WeakMap<object, any>";
569
+ }
570
+ else if (calleeName === "WeakSet") {
571
+ type = "WeakSet<object>";
572
+ }
573
+ else if (calleeName === "Array") {
574
+ type = "any[]";
575
+ }
576
+ else if (calleeName === "RegExp" || calleeName === "Regexp") {
577
+ type = "RegExp";
578
+ }
579
+ else if (calleeName === "Error") {
580
+ type = "Error";
581
+ }
582
+ else {
583
+ // For other constructors, use the constructor name as the type
584
+ type = calleeName;
585
+ }
586
+ }
587
+ }
588
+ else if (init.type === "CallExpression") {
589
+ const callExpr = init;
590
+ if ("start" in callExpr &&
591
+ "end" in callExpr &&
592
+ typeof callExpr.start === "number" &&
593
+ typeof callExpr.end === "number") {
594
+ value = this.sourceAtPos(callExpr.start, callExpr.end);
531
595
  }
532
596
  }
533
597
  else if (init.type === "Identifier") {
@@ -958,7 +1022,7 @@ class ComponentParser {
958
1022
  if (currentEventName !== undefined) {
959
1023
  let detailType;
960
1024
  if (eventProperties.length > 0) {
961
- detailType = this.buildEventDetailFromProperties(eventProperties, currentEventName);
1025
+ detailType = this.buildEventDetailFromProperties(eventProperties, currentEventName, true);
962
1026
  }
963
1027
  else {
964
1028
  detailType = currentEventType || "";
@@ -1008,8 +1072,9 @@ class ComponentParser {
1008
1072
  if (typedefProperties.length > 0) {
1009
1073
  /**
1010
1074
  * Build type alias with property descriptions from `@property` tags.
1075
+ * Use multiline formatting for better readability.
1011
1076
  */
1012
- typedefType = this.buildEventDetailFromProperties(typedefProperties);
1077
+ typedefType = this.buildEventDetailFromProperties(typedefProperties, undefined, true);
1013
1078
  typedefTs = `type ${currentTypedefName} = ${typedefType}`;
1014
1079
  }
1015
1080
  else if (currentTypedefType) {
@@ -1199,7 +1264,7 @@ class ComponentParser {
1199
1264
  * "{ /** The new value *\/ value: string; /** @default 0 *\/ count?: number; }"
1200
1265
  * ```
1201
1266
  */
1202
- buildEventDetailFromProperties(properties, _eventName) {
1267
+ buildEventDetailFromProperties(properties, _eventName, multiline = false) {
1203
1268
  if (properties.length === 0)
1204
1269
  return "null";
1205
1270
  /**
@@ -1221,12 +1286,15 @@ class ComponentParser {
1221
1286
  comment = `@default ${defaultValue}`;
1222
1287
  }
1223
1288
  if (comment) {
1289
+ if (multiline) {
1290
+ return `/** ${comment} */\n ${name}${optionalMarker}: ${type};`;
1291
+ }
1224
1292
  return `/** ${comment} */ ${name}${optionalMarker}: ${type};`;
1225
1293
  }
1226
1294
  return `${name}${optionalMarker}: ${type};`;
1227
1295
  })
1228
- .join(" ");
1229
- return `{ ${props} }`;
1296
+ .join(multiline ? "\n " : " ");
1297
+ return multiline ? `{\n ${props}\n}` : `{ ${props} }`;
1230
1298
  }
1231
1299
  /**
1232
1300
  * Generates a TypeScript type name for a context key.
@@ -1919,6 +1987,20 @@ class ComponentParser {
1919
1987
  description = jsdocInfo.description;
1920
1988
  }
1921
1989
  }
1990
+ // Merge returnType into type for function declarations if not overridden by @type
1991
+ if (isFunctionDeclaration && type === "() => any" && returnType) {
1992
+ if (params && params.length > 0) {
1993
+ const paramStrings = params.map((param) => {
1994
+ const optional = param.optional ? "?" : "";
1995
+ return `${param.name}${optional}: ${param.type}`;
1996
+ });
1997
+ const paramsString = paramStrings.join(", ");
1998
+ type = `(${paramsString}) => ${returnType}`;
1999
+ }
2000
+ else {
2001
+ type = `() => ${returnType}`;
2002
+ }
2003
+ }
1922
2004
  if (!description && type && this.typedefs.has(type)) {
1923
2005
  description = this.typedefs.get(type)?.description;
1924
2006
  }
@@ -2138,6 +2220,20 @@ class ComponentParser {
2138
2220
  description = jsdocInfo.description;
2139
2221
  }
2140
2222
  }
2223
+ // Merge returnType into type for function declarations if not overridden by @type
2224
+ if (isFunctionDeclaration && type === "() => any" && returnType) {
2225
+ if (params && params.length > 0) {
2226
+ const paramStrings = params.map((param) => {
2227
+ const optional = param.optional ? "?" : "";
2228
+ return `${param.name}${optional}: ${param.type}`;
2229
+ });
2230
+ const paramsString = paramStrings.join(", ");
2231
+ type = `(${paramsString}) => ${returnType}`;
2232
+ }
2233
+ else {
2234
+ type = `() => ${returnType}`;
2235
+ }
2236
+ }
2141
2237
  if (!description && type && this.typedefs.has(type)) {
2142
2238
  description = this.typedefs.get(type)?.description;
2143
2239
  }
@@ -3,8 +3,7 @@
3
3
  *
4
4
  * Maps HTML element tag names to their corresponding TypeScript element types.
5
5
  * Used for generating proper TypeScript types for element bindings and rest props.
6
- *
7
- * @see {@link https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts#L19263 | TypeScript lib.dom.d.ts}
6
+ * See the TypeScript lib.dom.d.ts for the original source.
8
7
  *
9
8
  * @example
10
9
  * ```ts
@@ -6,8 +6,7 @@ exports.getElementByTag = getElementByTag;
6
6
  *
7
7
  * Maps HTML element tag names to their corresponding TypeScript element types.
8
8
  * Used for generating proper TypeScript types for element bindings and rest props.
9
- *
10
- * @see {@link https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts#L19263 | TypeScript lib.dom.d.ts}
9
+ * See the TypeScript lib.dom.d.ts for the original source.
11
10
  *
12
11
  * @example
13
12
  * ```ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sveld",
3
- "version": "0.25.11",
3
+ "version": "0.25.12",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Generate TypeScript definitions for your Svelte components.",
6
6
  "main": "./lib/index.js",