jsxpression 0.1.41 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/lib/analyze/analysis-error.d.ts.map +1 -1
  2. package/lib/analyze/analysis-error.js +2 -7
  3. package/lib/analyze/analysis-error.js.map +1 -1
  4. package/lib/analyze/analysis-report.d.ts +13 -13
  5. package/lib/analyze/analysis-report.d.ts.map +1 -1
  6. package/lib/analyze/analysis-report.js +48 -45
  7. package/lib/analyze/analysis-report.js.map +1 -1
  8. package/lib/analyze/analyze.d.ts +1 -1
  9. package/lib/analyze/analyze.d.ts.map +1 -1
  10. package/lib/analyze/analyze.js +4 -4
  11. package/lib/analyze/analyze.js.map +1 -1
  12. package/lib/analyze/data/analyze.d.ts +1 -1
  13. package/lib/analyze/data/analyze.d.ts.map +1 -1
  14. package/lib/analyze/data/analyze.js +5 -5
  15. package/lib/analyze/data/analyze.js.map +1 -1
  16. package/lib/analyze/data/data-access.d.ts +1 -1
  17. package/lib/analyze/data/data-access.d.ts.map +1 -1
  18. package/lib/analyze/data/data-access.js +19 -15
  19. package/lib/analyze/data/data-access.js.map +1 -1
  20. package/lib/analyze/data/method-calls.d.ts +1 -1
  21. package/lib/analyze/data/method-calls.d.ts.map +1 -1
  22. package/lib/analyze/data/method-calls.js +5 -5
  23. package/lib/analyze/data/method-calls.js.map +1 -1
  24. package/lib/analyze/data/utils.d.ts +3 -3
  25. package/lib/analyze/data/utils.d.ts.map +1 -1
  26. package/lib/analyze/data/utils.js +6 -5
  27. package/lib/analyze/data/utils.js.map +1 -1
  28. package/lib/analyze/index.d.ts +1 -1
  29. package/lib/analyze/index.d.ts.map +1 -1
  30. package/lib/analyze/index.js +1 -1
  31. package/lib/analyze/index.js.map +1 -1
  32. package/lib/analyze/jsx/analyze.d.ts +1 -1
  33. package/lib/analyze/jsx/analyze.d.ts.map +1 -1
  34. package/lib/analyze/jsx/analyze.js +4 -4
  35. package/lib/analyze/jsx/analyze.js.map +1 -1
  36. package/lib/analyze/jsx/element-attributes.d.ts +1 -1
  37. package/lib/analyze/jsx/element-attributes.d.ts.map +1 -1
  38. package/lib/analyze/jsx/element-attributes.js +3 -3
  39. package/lib/analyze/jsx/element-attributes.js.map +1 -1
  40. package/lib/analyze/jsx/element-children.d.ts +1 -1
  41. package/lib/analyze/jsx/element-children.d.ts.map +1 -1
  42. package/lib/analyze/jsx/element-children.js +3 -3
  43. package/lib/analyze/jsx/element-children.js.map +1 -1
  44. package/lib/analyze/jsx/element-tags.d.ts +1 -1
  45. package/lib/analyze/jsx/element-tags.d.ts.map +1 -1
  46. package/lib/analyze/jsx/element-tags.js +2 -2
  47. package/lib/analyze/jsx/element-tags.js.map +1 -1
  48. package/lib/analyze/security/analyze.d.ts +1 -1
  49. package/lib/analyze/security/analyze.d.ts.map +1 -1
  50. package/lib/analyze/security/analyze.js +4 -4
  51. package/lib/analyze/security/analyze.js.map +1 -1
  52. package/lib/analyze/security/call-expressions.d.ts +1 -1
  53. package/lib/analyze/security/call-expressions.d.ts.map +1 -1
  54. package/lib/analyze/security/call-expressions.js +3 -5
  55. package/lib/analyze/security/call-expressions.js.map +1 -1
  56. package/lib/analyze/security/declarations.d.ts +1 -1
  57. package/lib/analyze/security/declarations.d.ts.map +1 -1
  58. package/lib/analyze/security/declarations.js +6 -6
  59. package/lib/analyze/security/declarations.js.map +1 -1
  60. package/lib/analyze/security/expressions.d.ts +1 -1
  61. package/lib/analyze/security/expressions.d.ts.map +1 -1
  62. package/lib/analyze/security/expressions.js +3 -6
  63. package/lib/analyze/security/expressions.js.map +1 -1
  64. package/lib/analyze/security/identifiers.d.ts +1 -1
  65. package/lib/analyze/security/identifiers.d.ts.map +1 -1
  66. package/lib/analyze/security/identifiers.js +19 -22
  67. package/lib/analyze/security/identifiers.js.map +1 -1
  68. package/lib/analyze/utils.d.ts +4 -4
  69. package/lib/analyze/utils.d.ts.map +1 -1
  70. package/lib/analyze/utils.js +5 -3
  71. package/lib/analyze/utils.js.map +1 -1
  72. package/lib/analyze/validation-context.d.ts +8 -8
  73. package/lib/analyze/validation-context.d.ts.map +1 -1
  74. package/lib/analyze/validation-context.js +23 -21
  75. package/lib/analyze/validation-context.js.map +1 -1
  76. package/lib/builtins.d.ts +6 -6
  77. package/lib/builtins.d.ts.map +1 -1
  78. package/lib/builtins.js +9 -8
  79. package/lib/builtins.js.map +1 -1
  80. package/lib/codegen/builtins/builtin-types.d.ts.map +1 -1
  81. package/lib/codegen/builtins/builtin-types.js +9 -13
  82. package/lib/codegen/builtins/builtin-types.js.map +1 -1
  83. package/lib/codegen/generate-typescript-definitions.d.ts +18 -17
  84. package/lib/codegen/generate-typescript-definitions.d.ts.map +1 -1
  85. package/lib/codegen/generate-typescript-definitions.js +19 -23
  86. package/lib/codegen/generate-typescript-definitions.js.map +1 -1
  87. package/lib/codegen/schema/component-types.d.ts.map +1 -1
  88. package/lib/codegen/schema/component-types.js +7 -4
  89. package/lib/codegen/schema/component-types.js.map +1 -1
  90. package/lib/codegen/schema/data-types.d.ts.map +1 -1
  91. package/lib/codegen/schema/data-types.js +1 -1
  92. package/lib/codegen/schema/data-types.js.map +1 -1
  93. package/lib/codegen/schema/function-types.d.ts.map +1 -1
  94. package/lib/codegen/schema/function-types.js +1 -3
  95. package/lib/codegen/schema/function-types.js.map +1 -1
  96. package/lib/codegen/schema/utils.d.ts +4 -3
  97. package/lib/codegen/schema/utils.d.ts.map +1 -1
  98. package/lib/codegen/schema/utils.js +12 -8
  99. package/lib/codegen/schema/utils.js.map +1 -1
  100. package/lib/compile/compilation-error.d.ts +1 -1
  101. package/lib/compile/compilation-error.d.ts.map +1 -1
  102. package/lib/compile/compilation-error.js +3 -1
  103. package/lib/compile/compilation-error.js.map +1 -1
  104. package/lib/compile/compile.d.ts.map +1 -1
  105. package/lib/compile/compile.js +5 -11
  106. package/lib/compile/compile.js.map +1 -1
  107. package/lib/evaluate/evaluate.d.ts +6 -6
  108. package/lib/evaluate/evaluate.d.ts.map +1 -1
  109. package/lib/evaluate/evaluate.js +1 -1
  110. package/lib/evaluate/evaluate.js.map +1 -1
  111. package/lib/evaluate/evaluation-error.d.ts.map +1 -1
  112. package/lib/evaluate/evaluation-error.js +1 -0
  113. package/lib/evaluate/evaluation-error.js.map +1 -1
  114. package/lib/index.d.ts +1 -1
  115. package/lib/index.d.ts.map +1 -1
  116. package/lib/index.js +1 -1
  117. package/lib/index.js.map +1 -1
  118. package/lib/jsx.d.ts +3 -3
  119. package/lib/jsx.d.ts.map +1 -1
  120. package/lib/jsx.js.map +1 -1
  121. package/lib/parse/parse-error.d.ts.map +1 -1
  122. package/lib/parse/parse-error.js +1 -0
  123. package/lib/parse/parse-error.js.map +1 -1
  124. package/lib/render.d.ts +25 -33
  125. package/lib/render.d.ts.map +1 -1
  126. package/lib/render.js +21 -26
  127. package/lib/render.js.map +1 -1
  128. package/lib/schema.d.ts +9 -9
  129. package/lib/schema.d.ts.map +1 -1
  130. package/lib/schema.js +1 -1
  131. package/lib/schema.js.map +1 -1
  132. package/lib/traverse.d.ts.map +1 -1
  133. package/lib/traverse.js.map +1 -1
  134. package/lib/validate.d.ts +14 -17
  135. package/lib/validate.d.ts.map +1 -1
  136. package/lib/validate.js +13 -14
  137. package/lib/validate.js.map +1 -1
  138. package/package.json +12 -12
  139. package/src/analyze/analysis-error.ts +2 -6
  140. package/src/analyze/analysis-report.ts +73 -62
  141. package/src/analyze/analyze.test.ts +60 -60
  142. package/src/analyze/analyze.ts +4 -4
  143. package/src/analyze/data/analyze.ts +5 -8
  144. package/src/analyze/data/data-access.ts +49 -46
  145. package/src/analyze/data/method-calls.ts +9 -18
  146. package/src/analyze/data/utils.ts +15 -19
  147. package/src/analyze/index.ts +1 -1
  148. package/src/analyze/jsx/analyze.ts +4 -4
  149. package/src/analyze/jsx/element-attributes.ts +5 -18
  150. package/src/analyze/jsx/element-children.ts +4 -8
  151. package/src/analyze/jsx/element-tags.ts +2 -2
  152. package/src/analyze/security/analyze.ts +4 -4
  153. package/src/analyze/security/call-expressions.ts +5 -18
  154. package/src/analyze/security/declarations.ts +14 -43
  155. package/src/analyze/security/expressions.ts +12 -49
  156. package/src/analyze/security/identifiers.ts +37 -39
  157. package/src/analyze/utils.ts +25 -19
  158. package/src/analyze/validation-context.ts +32 -23
  159. package/src/builtins.ts +27 -38
  160. package/src/codegen/builtins/builtin-types.ts +13 -20
  161. package/src/codegen/generate-typescript-definitions.test.ts +6 -6
  162. package/src/codegen/generate-typescript-definitions.ts +19 -23
  163. package/src/codegen/schema/component-types.ts +22 -12
  164. package/src/codegen/schema/data-types.ts +6 -6
  165. package/src/codegen/schema/function-types.ts +1 -3
  166. package/src/codegen/schema/utils.ts +24 -23
  167. package/src/compile/compilation-error.ts +5 -1
  168. package/src/compile/compile.test.ts +7 -21
  169. package/src/compile/compile.ts +18 -30
  170. package/src/evaluate/evaluate.test.ts +78 -94
  171. package/src/evaluate/evaluate.ts +15 -20
  172. package/src/evaluate/evaluation-error.ts +1 -0
  173. package/src/index.ts +1 -7
  174. package/src/jsx.ts +4 -6
  175. package/src/parse/parse-error.ts +1 -0
  176. package/src/parse/parse.test.ts +16 -18
  177. package/src/render.test.ts +4 -4
  178. package/src/render.ts +26 -38
  179. package/src/schema.ts +11 -11
  180. package/src/traverse.test.ts +6 -6
  181. package/src/traverse.ts +3 -3
  182. package/src/validate.ts +14 -17
  183. package/CHANGELOG.md +0 -8
package/src/builtins.ts CHANGED
@@ -13,13 +13,13 @@ interface BuiltinParamBaseSchema {
13
13
 
14
14
  export interface BuiltinPrimitiveParamSchema extends BuiltinParamBaseSchema {
15
15
  kind: "primitive";
16
- types: string[];
16
+ types: Array<string>;
17
17
  }
18
18
 
19
19
  export interface BuiltinFunctionParamSchema extends BuiltinParamBaseSchema {
20
20
  kind: "function";
21
21
  signature: {
22
- params: BuiltinCallbackParamSchema[];
22
+ params: Array<BuiltinCallbackParamSchema>;
23
23
  returnType: string;
24
24
  };
25
25
  }
@@ -27,7 +27,7 @@ export interface BuiltinFunctionParamSchema extends BuiltinParamBaseSchema {
27
27
  export type BuiltinParamSchema = BuiltinPrimitiveParamSchema | BuiltinFunctionParamSchema;
28
28
 
29
29
  export interface BuiltinMethodSchema {
30
- params: BuiltinParamSchema[];
30
+ params: Array<BuiltinParamSchema>;
31
31
  returnType: string;
32
32
  description?: string;
33
33
  }
@@ -383,8 +383,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
383
383
  generic: "<T>",
384
384
  methods: {
385
385
  map: {
386
- description:
387
- "Calls a defined callback function on each element of an array, and returns an array that contains the results",
386
+ description: "Calls a defined callback function on each element of an array, and returns an array that contains the results",
388
387
  params: [
389
388
  {
390
389
  kind: "function" as const,
@@ -470,8 +469,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
470
469
  returnType: "U",
471
470
  },
472
471
  find: {
473
- description:
474
- "Returns the value of the first element in the array where predicate is true, and undefined otherwise",
472
+ description: "Returns the value of the first element in the array where predicate is true, and undefined otherwise",
475
473
  params: [
476
474
  {
477
475
  kind: "function" as const,
@@ -569,8 +567,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
569
567
  kind: "primitive" as const,
570
568
  name: "end",
571
569
  types: ["number"],
572
- description:
573
- "The end index of the specified portion of the array. This is exclusive of the element at the index 'end'",
570
+ description: "The end index of the specified portion of the array. This is exclusive of the element at the index 'end'",
574
571
  required: false,
575
572
  },
576
573
  ],
@@ -590,8 +587,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
590
587
  kind: "primitive" as const,
591
588
  name: "fromIndex",
592
589
  types: ["number"],
593
- description:
594
- "The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0",
590
+ description: "The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0",
595
591
  required: false,
596
592
  },
597
593
  ],
@@ -611,8 +607,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
611
607
  kind: "primitive" as const,
612
608
  name: "fromIndex",
613
609
  types: ["number"],
614
- description:
615
- "The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0",
610
+ description: "The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0",
616
611
  required: false,
617
612
  },
618
613
  ],
@@ -639,8 +634,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
639
634
  kind: "primitive" as const,
640
635
  name: "index",
641
636
  types: ["number"],
642
- description:
643
- "The zero-based index of the desired code unit. A negative index will count back from the last item",
637
+ description: "The zero-based index of the desired code unit. A negative index will count back from the last item",
644
638
  required: true,
645
639
  },
646
640
  ],
@@ -688,8 +682,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
688
682
  returnType: "number",
689
683
  },
690
684
  flat: {
691
- description:
692
- "Returns a new array with all sub-array elements concatenated into it recursively up to the specified depth",
685
+ description: "Returns a new array with all sub-array elements concatenated into it recursively up to the specified depth",
693
686
  params: [
694
687
  {
695
688
  kind: "primitive" as const,
@@ -702,8 +695,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
702
695
  returnType: "T[]",
703
696
  },
704
697
  flatMap: {
705
- description:
706
- "Calls a defined callback function on each element of an array, then flattens the result into a new array",
698
+ description: "Calls a defined callback function on each element of an array, then flattens the result into a new array",
707
699
  params: [
708
700
  {
709
701
  kind: "function" as const,
@@ -769,8 +761,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
769
761
  kind: "primitive" as const,
770
762
  name: "index",
771
763
  types: ["number"],
772
- description:
773
- "The zero-based index of the desired character. If there is no character at the specified index, NaN is returned",
764
+ description: "The zero-based index of the desired character. If there is no character at the specified index, NaN is returned",
774
765
  required: true,
775
766
  },
776
767
  ],
@@ -845,8 +836,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
845
836
  kind: "primitive" as const,
846
837
  name: "position",
847
838
  types: ["number"],
848
- description:
849
- "The index at which to begin searching the String object. If omitted, search starts at the beginning of the string",
839
+ description: "The index at which to begin searching the String object. If omitted, search starts at the beginning of the string",
850
840
  required: false,
851
841
  },
852
842
  ],
@@ -866,8 +856,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
866
856
  kind: "primitive" as const,
867
857
  name: "position",
868
858
  types: ["number"],
869
- description:
870
- "The index at which to begin searching. If omitted, the search begins at the end of the string",
859
+ description: "The index at which to begin searching. If omitted, the search begins at the end of the string",
871
860
  required: false,
872
861
  },
873
862
  ],
@@ -996,8 +985,7 @@ const BUILTINS: Record<string, BuiltinSchema> = {
996
985
  kind: "primitive" as const,
997
986
  name: "replaceValue",
998
987
  types: ["string"],
999
- description:
1000
- "A string containing the text to replace for every successful match of searchValue in this string",
988
+ description: "A string containing the text to replace for every successful match of searchValue in this string",
1001
989
  required: true,
1002
990
  },
1003
991
  ],
@@ -1093,19 +1081,20 @@ export function getBuiltins(): Record<string, BuiltinSchema> {
1093
1081
  return structuredClone(BUILTINS);
1094
1082
  }
1095
1083
 
1096
- export function getBuiltinGlobals(): string[] {
1084
+ export function getBuiltinGlobals(): Array<string> {
1085
+ // oxlint-disable-next-line typescript/no-unnecessary-boolean-literal-compare
1097
1086
  return Object.keys(BUILTINS).filter((name) => BUILTINS[name].global === true);
1098
1087
  }
1099
1088
 
1100
1089
  export function isAllowedOnArray(prop: string): boolean {
1101
- const arrayMethods = BUILTINS[ARRAY_PROTOTYPE]?.methods || {};
1102
- const arrayProperties = BUILTINS[ARRAY_PROTOTYPE]?.properties || {};
1090
+ const arrayMethods = BUILTINS[ARRAY_PROTOTYPE]?.methods ?? {};
1091
+ const arrayProperties = BUILTINS[ARRAY_PROTOTYPE]?.properties ?? {};
1103
1092
  return prop in arrayMethods || prop in arrayProperties;
1104
1093
  }
1105
1094
 
1106
1095
  export function isAllowedOnString(prop: string): boolean {
1107
- const stringMethods = BUILTINS[STRING_PROTOTYPE]?.methods || {};
1108
- const stringProperties = BUILTINS[STRING_PROTOTYPE]?.properties || {};
1096
+ const stringMethods = BUILTINS[STRING_PROTOTYPE]?.methods ?? {};
1097
+ const stringProperties = BUILTINS[STRING_PROTOTYPE]?.properties ?? {};
1109
1098
  return prop in stringMethods || prop in stringProperties;
1110
1099
  }
1111
1100
 
@@ -1127,17 +1116,17 @@ export function getMethodDefinition(methodName: string): BuiltinMethodSchema | n
1127
1116
  return null;
1128
1117
  }
1129
1118
 
1130
- export function getAvailableArrayMembers(): string[] {
1119
+ export function getAvailableArrayMembers(): Array<string> {
1131
1120
  const arrayNamespace = BUILTINS[ARRAY_PROTOTYPE];
1132
- const methods = Object.keys(arrayNamespace?.methods || {});
1133
- const properties = Object.keys(arrayNamespace?.properties || {});
1121
+ const methods = Object.keys(arrayNamespace?.methods ?? {});
1122
+ const properties = Object.keys(arrayNamespace?.properties ?? {});
1134
1123
  return [...methods, ...properties];
1135
1124
  }
1136
1125
 
1137
- export function getAvailableStringMembers(): string[] {
1126
+ export function getAvailableStringMembers(): Array<string> {
1138
1127
  const stringNamespace = BUILTINS[STRING_PROTOTYPE];
1139
- const methods = Object.keys(stringNamespace?.methods || {});
1140
- const properties = Object.keys(stringNamespace?.properties || {});
1128
+ const methods = Object.keys(stringNamespace?.methods ?? {});
1129
+ const properties = Object.keys(stringNamespace?.properties ?? {});
1141
1130
  return [...methods, ...properties];
1142
1131
  }
1143
1132
 
@@ -1,18 +1,14 @@
1
1
  import { getBuiltins } from "../../builtins.js";
2
- import type {
3
- BuiltinSchema,
4
- BuiltinMethodSchema,
5
- BuiltinParamSchema,
6
- BuiltinPropertySchema,
7
- BuiltinCallbackParamSchema,
8
- } from "../../builtins.js";
2
+ import type { BuiltinSchema, BuiltinMethodSchema, BuiltinParamSchema, BuiltinPropertySchema, BuiltinCallbackParamSchema } from "../../builtins.js";
9
3
 
10
4
  function generateJSDoc(description?: string, indent: string = ""): string {
11
- if (!description) return "";
5
+ if (!description) {
6
+ return "";
7
+ }
12
8
  return `${indent}/**\n${indent} * ${description}\n${indent} */\n`;
13
9
  }
14
10
 
15
- function generateCallbackSignature(signature: { params: BuiltinCallbackParamSchema[]; returnType: string }): string {
11
+ function generateCallbackSignature(signature: { params: Array<BuiltinCallbackParamSchema>; returnType: string }): string {
16
12
  const params = signature.params.map((p) => `${p.name}: ${p.type}`).join(", ");
17
13
  return `(${params}) => ${signature.returnType}`;
18
14
  }
@@ -21,23 +17,20 @@ function extractGenerics(method: BuiltinMethodSchema): string {
21
17
  for (const param of method.params) {
22
18
  if (param.kind === "function") {
23
19
  const usesU = param.signature.returnType === "U" || param.signature.params.some((p) => p.type === "U");
24
- if (usesU) return "<U>";
20
+ if (usesU) {
21
+ return "<U>";
22
+ }
25
23
  }
26
24
  }
27
25
  return "";
28
26
  }
29
27
 
30
28
  function generateParam(param: BuiltinParamSchema): string {
31
- let typeStr: string;
29
+ let typeStr: string = param.kind === "function" ? generateCallbackSignature(param.signature) : param.types.join(" | ");
32
30
 
33
- if (param.kind === "function") {
34
- typeStr = generateCallbackSignature(param.signature);
35
- } else {
36
- typeStr = param.types.join(" | ");
37
- // The type should be an array for variadic parameters
38
- if (param.variadic) {
39
- typeStr = `${typeStr}[]`;
40
- }
31
+ // The type should be an array for variadic parameters
32
+ if (param.kind !== "function" && param.variadic) {
33
+ typeStr = `${typeStr}[]`;
41
34
  }
42
35
 
43
36
  const optional = param.required || param.variadic ? "" : "?";
@@ -93,7 +86,7 @@ function generateNamespaceDeclaration(namespace: string, schema: BuiltinSchema):
93
86
 
94
87
  if (schema.intrinsic) {
95
88
  const interfaceName = namespace.replace(".prototype", "");
96
- const genericParam = schema.generic || "";
89
+ const genericParam = schema.generic ?? "";
97
90
 
98
91
  result += `interface ${interfaceName}${genericParam} {\n`;
99
92
 
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect } from "vitest";
2
+ import type { ElementSchema, Schema } from "../schema.js";
2
3
  import { generateTypeScriptDefinitions } from "./generate-typescript-definitions.js";
3
- import type { Schema } from "../schema.js";
4
4
 
5
5
  describe("generateTypeScriptDefinitions", () => {
6
6
  describe("basic structure", () => {
@@ -230,10 +230,11 @@ describe("generateTypeScriptDefinitions", () => {
230
230
  const schema: Schema = {
231
231
  data: {},
232
232
  elements: {
233
+ // `content` isn't part of ElementSchema; this intersection type documents that it's a legacy/unmodeled field being tested here.
233
234
  Input: {
234
235
  props: {},
235
236
  content: false,
236
- } as any,
237
+ } as ElementSchema & { content: boolean },
237
238
  },
238
239
  };
239
240
 
@@ -525,9 +526,7 @@ describe("generateTypeScriptDefinitions", () => {
525
526
  };
526
527
 
527
528
  const result = generateTypeScriptDefinitions(schema);
528
- expect(result).toContain(
529
- `id: "TypeA";\n valueA: string;\n } | {\n id: "TypeB";\n valueB: number;\n };`
530
- );
529
+ expect(result).toContain(`id: "TypeA";\n valueA: string;\n } | {\n id: "TypeB";\n valueB: number;\n };`);
531
530
  });
532
531
 
533
532
  it("should generate functions", () => {
@@ -608,8 +607,9 @@ describe("generateTypeScriptDefinitions", () => {
608
607
  shape: { type: "string" },
609
608
  },
610
609
  },
610
+ // `content` isn't part of ElementSchema; this intersection type documents that it's a legacy/unmodeled field being tested here.
611
611
  content: false,
612
- } as any,
612
+ } as ElementSchema & { content: boolean },
613
613
  },
614
614
  };
615
615
 
@@ -6,35 +6,31 @@ import { declareComponentTypes, declareDataTypes, declareFunctionTypes } from ".
6
6
  * Generates TypeScript definitions from a JSXExpression schema.
7
7
  *
8
8
  * The generated definitions enable code editors to provide:
9
+ *
9
10
  * - IntelliSense autocomplete for components and data properties
10
11
  * - Type checking for JSX expressions
11
12
  * - Hover documentation from schema descriptions
12
13
  *
13
- * @param schema - Schema defining allowed data properties, JSX elements, and their types
14
- * @returns Complete TypeScript definition file as a string
15
- *
16
14
  * @example
17
- * ```typescript
18
- * const schema = {
19
- * elements: {
20
- * Button: {
21
- * props: { size: { type: "string", enum: ["sm", "md", "lg"] } }
22
- * }
23
- * },
24
- * data: {
25
- * user: { type: "object", shape: { name: { type: "string" } } }
26
- * }
27
- * };
15
+ * ```typescript
16
+ * const schema = {
17
+ * elements: {
18
+ * Button: {
19
+ * props: { size: { type: "string", enum: ["sm", "md", "lg"] } },
20
+ * },
21
+ * },
22
+ * data: {
23
+ * user: { type: "object", shape: { name: { type: "string" } } },
24
+ * },
25
+ * };
28
26
  *
29
- * const definitions = generateTypeScriptDefinitions(schema);
30
- * // Use with Monaco, VS Code, or any TypeScript-enabled editor
31
- * ```
27
+ * const definitions = generateTypeScriptDefinitions(schema);
28
+ * // Use with Monaco, VS Code, or any TypeScript-enabled editor
29
+ * ```;
30
+ *
31
+ * @param schema - Schema defining allowed data properties, JSX elements, and their types
32
+ * @returns Complete TypeScript definition file as a string
32
33
  */
33
34
  export function generateTypeScriptDefinitions(schema: Schema): string {
34
- return [
35
- declareBuiltinTypes(),
36
- declareComponentTypes(schema),
37
- declareDataTypes(schema),
38
- declareFunctionTypes(schema),
39
- ].join("\n");
35
+ return [declareBuiltinTypes(), declareComponentTypes(schema), declareDataTypes(schema), declareFunctionTypes(schema)].join("\n");
40
36
  }
@@ -1,6 +1,13 @@
1
- import type { Schema } from "../../schema.js";
1
+ import type { ElementSchema, PropertySchema, Schema } from "../../schema.js";
2
2
  import { mapSchemaTypeToTypeScript } from "./utils.js";
3
3
 
4
+ // ElementSchema fields the generator supports that aren't (yet) part of the shared schema type.
5
+ type ElementSchemaExtras = ElementSchema & {
6
+ content?: boolean;
7
+ doc?: string;
8
+ examples?: ReadonlyArray<string>;
9
+ };
10
+
4
11
  export function declareComponentTypes(schema: Schema): string {
5
12
  let output = `declare global {\n`;
6
13
 
@@ -29,10 +36,10 @@ export function declareComponentTypes(schema: Schema): string {
29
36
  return output;
30
37
  }
31
38
 
32
- function generatePropsInterface(interfaceName: string, element: any, indent: string = ""): string {
39
+ function generatePropsInterface(interfaceName: string, element: ElementSchemaExtras, indent: string = ""): string {
33
40
  let output = `${indent}interface ${interfaceName} {\n`;
34
41
 
35
- Object.entries(element.props || {}).forEach(([propName, prop]: [string, any]) => {
42
+ Object.entries(element.props ?? {}).forEach(([propName, prop]) => {
36
43
  const optional = prop.required ? "" : "?";
37
44
  const type = mapSchemaTypeToTypeScript(prop);
38
45
  const comment = generatePropComment(prop, `${indent} `);
@@ -51,8 +58,8 @@ function generatePropsInterface(interfaceName: string, element: any, indent: str
51
58
  return output;
52
59
  }
53
60
 
54
- function generateComponentComment(elementName: string, element: any, indent: string = ""): string {
55
- const comments: string[] = [];
61
+ function generateComponentComment(elementName: string, element: ElementSchemaExtras, indent: string = ""): string {
62
+ const comments: Array<string> = [];
56
63
 
57
64
  if (element.description) {
58
65
  comments.push(element.description);
@@ -66,7 +73,7 @@ function generateComponentComment(elementName: string, element: any, indent: str
66
73
  comments.push("");
67
74
  comments.push(`@param props Component props`);
68
75
 
69
- Object.entries(element.props).forEach(([propName, prop]: [string, any]) => {
76
+ Object.entries(element.props).forEach(([propName, prop]) => {
70
77
  if (prop.description) {
71
78
  comments.push(`@param props.${propName} ${prop.description}`);
72
79
  }
@@ -79,7 +86,7 @@ function generateComponentComment(elementName: string, element: any, indent: str
79
86
  if (element.examples && element.examples.length > 0) {
80
87
  comments.push("");
81
88
  comments.push("@example");
82
- element.examples.forEach((example: string) => {
89
+ element.examples.forEach((example) => {
83
90
  comments.push(example);
84
91
  });
85
92
  }
@@ -107,19 +114,22 @@ function generateComponentComment(elementName: string, element: any, indent: str
107
114
  return output;
108
115
  }
109
116
 
110
- function generatePropComment(prop: any, indent: string): string {
111
- const comments: string[] = [];
117
+ function generatePropComment(prop: PropertySchema, indent: string): string {
118
+ const comments: Array<string> = [];
112
119
 
113
120
  if (prop.description) {
114
121
  comments.push(prop.description);
115
122
  }
116
123
 
117
- if (prop.default !== undefined) {
124
+ if ((prop.type === "string" || prop.type === "number" || prop.type === "boolean") && prop.default !== undefined) {
118
125
  comments.push(`@default ${JSON.stringify(prop.default)}`);
119
126
  }
120
127
 
121
- if (prop.type === "enum" && prop.values) {
122
- comments.push(`@values ${prop.values.map((v: any) => `"${v}"`).join(", ")}`);
128
+ // oxlint-disable-next-line typescript/no-explicit-any -- "enum" isn't a PropertySchema.type variant; kept as-is rather than deleted by this type-only lint pass
129
+ const propAsAny = prop as any;
130
+ if (propAsAny.type === "enum" && propAsAny.values) {
131
+ // oxlint-disable-next-line typescript/no-explicit-any -- propAsAny.values is untyped ("enum" isn't a PropertySchema.type variant)
132
+ comments.push(`@values ${propAsAny.values.map((v: any) => `"${v}"`).join(", ")}`);
123
133
  }
124
134
 
125
135
  if (comments.length === 0) {
@@ -1,4 +1,4 @@
1
- import type { Schema } from "../../schema.js";
1
+ import type { PropertySchema, Schema } from "../../schema.js";
2
2
  import { mapSchemaTypeToTypeScript } from "./utils.js";
3
3
 
4
4
  export function declareDataTypes(schema: Schema): string {
@@ -21,8 +21,8 @@ export function declareDataTypes(schema: Schema): string {
21
21
  return output;
22
22
  }
23
23
 
24
- function generateNestedPropertyJSDoc(propertyName: string, propertySchema: any, indent: string = ""): string {
25
- const comments: string[] = [];
24
+ function generateNestedPropertyJSDoc(propertyName: string, propertySchema: PropertySchema, indent: string = ""): string {
25
+ const comments: Array<string> = [];
26
26
 
27
27
  if (propertySchema.description) {
28
28
  comments.push(propertySchema.description);
@@ -39,15 +39,15 @@ function generateNestedPropertyJSDoc(propertyName: string, propertySchema: any,
39
39
  let hasNestedProperties = false;
40
40
  if (propertySchema.type === "object" && propertySchema.shape) {
41
41
  comments.push("");
42
- Object.entries(propertySchema.shape).forEach(([key, value]: [string, any]) => {
42
+ Object.entries(propertySchema.shape).forEach(([key, value]) => {
43
43
  if (value.description) {
44
44
  comments.push(`@property ${key} ${value.description}`);
45
45
  hasNestedProperties = true;
46
46
  }
47
47
  });
48
- } else if (propertySchema.type === "array" && propertySchema.shape?.type === "object" && propertySchema.shape.shape) {
48
+ } else if (propertySchema.type === "array" && propertySchema.shape.type === "object" && propertySchema.shape.shape) {
49
49
  comments.push("");
50
- Object.entries(propertySchema.shape.shape).forEach(([key, value]: [string, any]) => {
50
+ Object.entries(propertySchema.shape.shape).forEach(([key, value]) => {
51
51
  if (value.description) {
52
52
  comments.push(`@property ${key} ${value.description}`);
53
53
  hasNestedProperties = true;
@@ -6,9 +6,7 @@ export function declareFunctionTypes(schema: Schema): string {
6
6
 
7
7
  if (schema.functions) {
8
8
  Object.entries(schema.functions).forEach(([funcName, funcSchema]) => {
9
- const args = funcSchema.args
10
- ? funcSchema.args.map((arg) => `${arg.name}: ${mapSchemaTypeToTypeScript(arg.property)}`).join(", ")
11
- : "";
9
+ const args = funcSchema.args ? funcSchema.args.map((arg) => `${arg.name}: ${mapSchemaTypeToTypeScript(arg.property)}`).join(", ") : "";
12
10
  const ret = funcSchema.ret ? mapSchemaTypeToTypeScript(funcSchema.ret) : "void";
13
11
  output += `function ${funcName}(${args}): ${ret};\n`;
14
12
  });
@@ -1,50 +1,56 @@
1
- export function mapSchemaTypeToTypeScript(prop: any, depth: number = 0): string {
1
+ import type { PropertySchema } from "../../schema.js";
2
+
3
+ export function mapSchemaTypeToTypeScript(prop: PropertySchema, depth: number = 0): string {
2
4
  switch (prop.type) {
3
5
  case "string":
4
6
  if (prop.enum && Array.isArray(prop.enum)) {
5
- return prop.enum.map((value: any) => `"${value}"`).join(" | ");
7
+ return prop.enum.map((value) => `"${value}"`).join(" | ");
6
8
  }
7
9
  return "string";
8
10
  case "number":
9
11
  if (prop.enum && Array.isArray(prop.enum)) {
10
- return prop.enum.map((value: any) => String(value)).join(" | ");
12
+ return prop.enum.map((value) => String(value)).join(" | ");
11
13
  }
12
14
  return "number";
13
15
  case "boolean":
14
16
  if (prop.enum && Array.isArray(prop.enum)) {
15
- return prop.enum.map((value: any) => String(value)).join(" | ");
17
+ return prop.enum.map((value) => String(value)).join(" | ");
16
18
  }
17
19
  return "boolean";
18
- case "array":
20
+ case "array": {
19
21
  const itemType = prop.shape ? mapSchemaTypeToTypeScript(prop.shape, depth) : "any";
20
22
  return `${itemType}[]`;
21
- case "object":
23
+ }
24
+ case "object": {
22
25
  if (prop.shape && typeof prop.shape === "object") {
23
26
  return generateObjectTypeWithJSDoc(prop.shape, depth);
24
27
  }
25
- if (prop.properties && typeof prop.properties === "object") {
26
- return generateObjectTypeWithJSDoc(prop.properties, depth);
28
+ // oxlint-disable-next-line typescript/no-explicit-any -- "properties" isn't an ObjectPropertySchema field; kept as a legacy fallback rather than removed by this type-only pass
29
+ const propAsAny = prop as any;
30
+ if (propAsAny.properties && typeof propAsAny.properties === "object") {
31
+ return generateObjectTypeWithJSDoc(propAsAny.properties, depth);
27
32
  }
28
33
  return "object";
29
- case "record":
34
+ }
35
+ case "record": {
30
36
  const valueType = prop.shape ? mapSchemaTypeToTypeScript(prop.shape) : "any";
31
37
  return `Record<string, ${valueType}>`;
38
+ }
32
39
  case "function":
33
40
  return "(...args: any[]) => any";
34
41
  case "union": {
35
- return `${prop.shape.map((p: any) => mapSchemaTypeToTypeScript(p)).join(" | ")}`;
42
+ return prop.shape.map((p) => mapSchemaTypeToTypeScript(p)).join(" | ");
36
43
  }
37
44
  default:
38
- console.warn(`Unknown schema type: ${prop.type}`);
39
45
  return "any";
40
46
  }
41
47
  }
42
48
 
43
- export function generateObjectTypeWithJSDoc(properties: any, depth: number = 0): string {
49
+ export function generateObjectTypeWithJSDoc(properties: Record<string, PropertySchema>, depth: number = 0): string {
44
50
  let result = "{\n";
45
51
 
46
52
  // Generate each property with inline JSDoc
47
- Object.entries(properties).forEach(([key, value]: [string, any]) => {
53
+ Object.entries(properties).forEach(([key, value]) => {
48
54
  // Generate comprehensive JSDoc for this property
49
55
  const propertyJSDoc = generatePropertyJSDoc(key, value, " ", depth);
50
56
  result += propertyJSDoc;
@@ -59,13 +65,8 @@ export function generateObjectTypeWithJSDoc(properties: any, depth: number = 0):
59
65
  return result;
60
66
  }
61
67
 
62
- export function generatePropertyJSDoc(
63
- _propertyName: string,
64
- propertySchema: any,
65
- indent: string = "",
66
- _depth: number = 0
67
- ): string {
68
- const comments: string[] = [];
68
+ export function generatePropertyJSDoc(_propertyName: string, propertySchema: PropertySchema, indent: string = "", _depth: number = 0): string {
69
+ const comments: Array<string> = [];
69
70
 
70
71
  // Main description
71
72
  if (propertySchema.description) {
@@ -76,16 +77,16 @@ export function generatePropertyJSDoc(
76
77
  let hasNestedProperties = false;
77
78
  if (propertySchema.type === "object" && propertySchema.shape) {
78
79
  comments.push("");
79
- Object.entries(propertySchema.shape).forEach(([key, value]: [string, any]) => {
80
+ Object.entries(propertySchema.shape).forEach(([key, value]) => {
80
81
  if (value.description) {
81
82
  comments.push(`@property ${key} ${value.description}`);
82
83
  hasNestedProperties = true;
83
84
  }
84
85
  });
85
- } else if (propertySchema.type === "array" && propertySchema.shape?.type === "object" && propertySchema.shape.shape) {
86
+ } else if (propertySchema.type === "array" && propertySchema.shape.type === "object" && propertySchema.shape.shape) {
86
87
  // For arrays of objects, document the object structure
87
88
  comments.push("");
88
- Object.entries(propertySchema.shape.shape).forEach(([key, value]: [string, any]) => {
89
+ Object.entries(propertySchema.shape.shape).forEach(([key, value]) => {
89
90
  if (value.description) {
90
91
  comments.push(`@property ${key} ${value.description}`);
91
92
  hasNestedProperties = true;
@@ -1,3 +1,5 @@
1
+ import type { Node } from "acorn";
2
+
1
3
  type Loc = {
2
4
  start: {
3
5
  line: number;
@@ -9,8 +11,10 @@ type Loc = {
9
11
  };
10
12
  };
11
13
 
14
+ // oxlint-disable-next-line functional/no-classes -- extends Error, which requires a class
12
15
  export class CompilationError extends Error {
13
- static fromNode(message: string, node: any): CompilationError {
16
+ static fromNode(message: string, nodeParam: unknown): CompilationError {
17
+ const node = nodeParam as Node;
14
18
  const loc = node.loc
15
19
  ? {
16
20
  start: {