jsxpression 0.1.40 → 0.2.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.
Files changed (180) 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 +8 -9
  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.js.map +1 -1
  94. package/lib/codegen/schema/utils.d.ts +4 -3
  95. package/lib/codegen/schema/utils.d.ts.map +1 -1
  96. package/lib/codegen/schema/utils.js +12 -8
  97. package/lib/codegen/schema/utils.js.map +1 -1
  98. package/lib/compile/compilation-error.d.ts +1 -1
  99. package/lib/compile/compilation-error.d.ts.map +1 -1
  100. package/lib/compile/compilation-error.js +3 -1
  101. package/lib/compile/compilation-error.js.map +1 -1
  102. package/lib/compile/compile.d.ts.map +1 -1
  103. package/lib/compile/compile.js +5 -11
  104. package/lib/compile/compile.js.map +1 -1
  105. package/lib/evaluate/evaluate.d.ts +6 -6
  106. package/lib/evaluate/evaluate.d.ts.map +1 -1
  107. package/lib/evaluate/evaluate.js +2 -2
  108. package/lib/evaluate/evaluate.js.map +1 -1
  109. package/lib/evaluate/evaluation-error.d.ts.map +1 -1
  110. package/lib/evaluate/evaluation-error.js +1 -0
  111. package/lib/evaluate/evaluation-error.js.map +1 -1
  112. package/lib/index.d.ts.map +1 -1
  113. package/lib/index.js.map +1 -1
  114. package/lib/jsx.d.ts +3 -3
  115. package/lib/jsx.d.ts.map +1 -1
  116. package/lib/jsx.js.map +1 -1
  117. package/lib/parse/parse-error.d.ts.map +1 -1
  118. package/lib/parse/parse-error.js +1 -0
  119. package/lib/parse/parse-error.js.map +1 -1
  120. package/lib/render.d.ts +25 -33
  121. package/lib/render.d.ts.map +1 -1
  122. package/lib/render.js +21 -26
  123. package/lib/render.js.map +1 -1
  124. package/lib/schema.d.ts +9 -9
  125. package/lib/schema.d.ts.map +1 -1
  126. package/lib/schema.js +1 -1
  127. package/lib/schema.js.map +1 -1
  128. package/lib/traverse.d.ts.map +1 -1
  129. package/lib/traverse.js +0 -1
  130. package/lib/traverse.js.map +1 -1
  131. package/lib/validate.d.ts +14 -17
  132. package/lib/validate.d.ts.map +1 -1
  133. package/lib/validate.js +13 -14
  134. package/lib/validate.js.map +1 -1
  135. package/package.json +14 -14
  136. package/src/analyze/analysis-error.ts +2 -6
  137. package/src/analyze/analysis-report.ts +73 -62
  138. package/src/analyze/analyze.test.ts +14 -18
  139. package/src/analyze/analyze.ts +4 -4
  140. package/src/analyze/data/analyze.ts +5 -8
  141. package/src/analyze/data/data-access.ts +49 -46
  142. package/src/analyze/data/method-calls.ts +9 -18
  143. package/src/analyze/data/utils.ts +15 -19
  144. package/src/analyze/index.ts +1 -1
  145. package/src/analyze/jsx/analyze.ts +4 -4
  146. package/src/analyze/jsx/element-attributes.ts +6 -19
  147. package/src/analyze/jsx/element-children.ts +9 -13
  148. package/src/analyze/jsx/element-tags.ts +2 -2
  149. package/src/analyze/security/analyze.ts +4 -4
  150. package/src/analyze/security/call-expressions.ts +5 -18
  151. package/src/analyze/security/declarations.ts +14 -43
  152. package/src/analyze/security/expressions.ts +12 -49
  153. package/src/analyze/security/identifiers.ts +39 -41
  154. package/src/analyze/utils.ts +25 -19
  155. package/src/analyze/validation-context.ts +32 -23
  156. package/src/builtins.ts +28 -39
  157. package/src/codegen/builtins/builtin-types.ts +13 -20
  158. package/src/codegen/generate-typescript-definitions.test.ts +29 -29
  159. package/src/codegen/generate-typescript-definitions.ts +19 -23
  160. package/src/codegen/schema/component-types.ts +22 -12
  161. package/src/codegen/schema/data-types.ts +6 -6
  162. package/src/codegen/schema/function-types.ts +1 -1
  163. package/src/codegen/schema/utils.ts +24 -23
  164. package/src/compile/compilation-error.ts +5 -1
  165. package/src/compile/compile.test.ts +7 -21
  166. package/src/compile/compile.ts +33 -45
  167. package/src/evaluate/evaluate.test.ts +95 -111
  168. package/src/evaluate/evaluate.ts +16 -21
  169. package/src/evaluate/evaluation-error.ts +1 -0
  170. package/src/index.ts +1 -7
  171. package/src/jsx.ts +4 -6
  172. package/src/parse/parse-error.ts +1 -0
  173. package/src/parse/parse.test.ts +1 -1
  174. package/src/render.test.ts +4 -4
  175. package/src/render.ts +27 -39
  176. package/src/schema.ts +12 -12
  177. package/src/traverse.test.ts +6 -6
  178. package/src/traverse.ts +15 -16
  179. package/src/validate.ts +14 -17
  180. package/CHANGELOG.md +0 -8
@@ -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: {
@@ -30,9 +30,7 @@ describe("compile", () => {
30
30
  it("should compile nested ternary expressions", () => {
31
31
  const ast = parse("<div>{props.level > 2 ? 'high' : props.level > 1 ? 'medium' : 'low'}</div>");
32
32
  const result = compile(ast);
33
- expect(result).toBe(
34
- '"use strict";return h("div", null, ((props.level > 2)?"high":((props.level > 1)?"medium":"low")));'
35
- );
33
+ expect(result).toBe('"use strict";return h("div", null, ((props.level > 2)?"high":((props.level > 1)?"medium":"low")));');
36
34
  });
37
35
 
38
36
  it("should compile nested JSX elements", () => {
@@ -44,9 +42,7 @@ describe("compile", () => {
44
42
  it("should compile nested array operations", () => {
45
43
  const ast = parse("<div>{props.items.map(x => x.split(',').map(y => y.trim()).join(' ')).join(' | ')}</div>");
46
44
  const result = compile(ast);
47
- expect(result).toBe(
48
- '"use strict";return h("div", null, props.items.map((x) => x.split(",").map((y) => y.trim()).join(" ")).join(" | "));'
49
- );
45
+ expect(result).toBe('"use strict";return h("div", null, props.items.map((x) => x.split(",").map((y) => y.trim()).join(" ")).join(" | "));');
50
46
  });
51
47
 
52
48
  it("should compile bare expression containers", () => {
@@ -217,23 +213,17 @@ describe("compile", () => {
217
213
  it("should compile function with props parameter", () => {
218
214
  const ast = parse('function Badge({ label }) {\n return <span>{label}</span>\n}\nreturn <Badge label="hi" />');
219
215
  const result = compile(ast);
220
- expect(result).toBe(
221
- '"use strict";function Badge({ label }) { return h("span", null, label); }return h(Badge, { label: "hi" });'
222
- );
216
+ expect(result).toBe('"use strict";function Badge({ label }) { return h("span", null, label); }return h(Badge, { label: "hi" });');
223
217
  });
224
218
 
225
219
  it("should compile function with default parameter", () => {
226
220
  const ast = parse("function Badge({ label = 'default' }) {\n return <span>{label}</span>\n}\nreturn <Badge />");
227
221
  const result = compile(ast);
228
- expect(result).toBe(
229
- '"use strict";function Badge({ label = "default" }) { return h("span", null, label); }return h(Badge, null);'
230
- );
222
+ expect(result).toBe('"use strict";function Badge({ label = "default" }) { return h("span", null, label); }return h(Badge, null);');
231
223
  });
232
224
 
233
225
  it("should compile function with const inside body", () => {
234
- const ast = parse(
235
- "function Badge({ value }) {\n const doubled = value * 2;\n return <span>{doubled}</span>\n}\nreturn <Badge value={5} />"
236
- );
226
+ const ast = parse("function Badge({ value }) {\n const doubled = value * 2;\n return <span>{doubled}</span>\n}\nreturn <Badge value={5} />");
237
227
  const result = compile(ast);
238
228
  expect(result).toContain("const doubled = (value * 2);");
239
229
  expect(result).toContain('return h("span", null, doubled);');
@@ -248,9 +238,7 @@ describe("compile", () => {
248
238
  });
249
239
 
250
240
  it("should compile multiple function declarations", () => {
251
- const ast = parse(
252
- "function A() {\n return <span>a</span>\n}\nfunction B() {\n return <span>b</span>\n}\nreturn <div><A /><B /></div>"
253
- );
241
+ const ast = parse("function A() {\n return <span>a</span>\n}\nfunction B() {\n return <span>b</span>\n}\nreturn <div><A /><B /></div>");
254
242
  const result = compile(ast);
255
243
  expect(result).toContain("function A()");
256
244
  expect(result).toContain("function B()");
@@ -259,9 +247,7 @@ describe("compile", () => {
259
247
  });
260
248
 
261
249
  it("should compile function calling another function", () => {
262
- const ast = parse(
263
- "function Inner() {\n return <span>inner</span>\n}\nfunction Outer() {\n return <div><Inner /></div>\n}\nreturn <Outer />"
264
- );
250
+ const ast = parse("function Inner() {\n return <span>inner</span>\n}\nfunction Outer() {\n return <div><Inner /></div>\n}\nreturn <Outer />");
265
251
  const result = compile(ast);
266
252
  expect(result).toContain("function Inner()");
267
253
  expect(result).toContain("function Outer()");
@@ -11,7 +11,6 @@ import type {
11
11
  Super,
12
12
  VariableDeclaration,
13
13
  } from "acorn";
14
-
15
14
  import {
16
15
  isJsxElement,
17
16
  isJsxEmptyExpression,
@@ -40,7 +39,7 @@ export function compile(ast: Program): string {
40
39
  }
41
40
  }
42
41
 
43
- const parts: string[] = ['"use strict";'];
42
+ const parts: Array<string> = ['"use strict";'];
44
43
 
45
44
  const hasDeclarations = ast.body.some((s) => s.type === "VariableDeclaration" || s.type === "FunctionDeclaration");
46
45
 
@@ -48,7 +47,7 @@ export function compile(ast: Program): string {
48
47
  if (statement.type === "VariableDeclaration") {
49
48
  parts.push(emitVariableDeclaration(statement, localFunctions));
50
49
  } else if (statement.type === "FunctionDeclaration") {
51
- parts.push(emitFunctionDeclaration(statement as FunctionDeclaration, localFunctions));
50
+ parts.push(emitFunctionDeclaration(statement, localFunctions));
52
51
  } else if (statement.type === "ReturnStatement" && statement.argument && isJsxRoot(statement.argument)) {
53
52
  parts.push(`return ${emitJsxRoot(statement.argument, localFunctions)};`);
54
53
  } else if (!hasDeclarations && statement.type === "ExpressionStatement" && isJsxRoot(statement.expression)) {
@@ -108,13 +107,13 @@ function emitJsxName(nameNode: JSXNameNode, localFunctions: Set<string>): string
108
107
  return JSON.stringify(JSON.parse(left) + "." + JSON.parse(right));
109
108
  }
110
109
  default:
111
- throw CompilationError.fromNode(`Unsupported JSX name: ${(nameNode as any).type}`, nameNode);
110
+ throw CompilationError.fromNode(`Unsupported JSX name: ${(nameNode as { type: string }).type}`, nameNode);
112
111
  }
113
112
  }
114
113
 
115
- function emitAttributes(attributes: (JSXAttribute | JSXSpreadAttribute)[], localFunctions: Set<string>): string {
116
- const parts: string[] = [];
117
- let currentObj: string[] = [];
114
+ function emitAttributes(attributes: Array<JSXAttribute | JSXSpreadAttribute>, localFunctions: Set<string>): string {
115
+ const parts: Array<string> = [];
116
+ let currentObj: Array<string> = [];
118
117
 
119
118
  const flushCurrent = (): void => {
120
119
  if (currentObj.length) {
@@ -134,15 +133,15 @@ function emitAttributes(attributes: (JSXAttribute | JSXSpreadAttribute)[], local
134
133
  throw CompilationError.fromNode("Only simple JSX attributes allowed", attribute);
135
134
  }
136
135
 
137
- const key = attribute.name?.name as string;
136
+ const key = attribute.name?.name;
138
137
 
139
- let value: string;
138
+ let value: string = "";
140
139
  if (!attribute.value) {
141
140
  value = "true";
142
141
  } else if (attribute.value.type === "Literal") {
143
142
  value = JSON.stringify(attribute.value.value);
144
143
  } else if (attribute.value.type === "JSXExpressionContainer") {
145
- value = emitExpression(attribute.value.expression as CompilableExpression, localFunctions);
144
+ value = emitExpression(attribute.value.expression, localFunctions);
146
145
  } else {
147
146
  throw CompilationError.fromNode("Unsupported attribute value", attribute.value);
148
147
  }
@@ -163,8 +162,8 @@ function emitAttributes(attributes: (JSXAttribute | JSXSpreadAttribute)[], local
163
162
  return `Object.assign({}, ${parts.join(", ")})`;
164
163
  }
165
164
 
166
- function emitJsxChildren(children: JSXNode[], localFunctions: Set<string>): string[] {
167
- const result: string[] = [];
165
+ function emitJsxChildren(children: Array<JSXNode>, localFunctions: Set<string>): Array<string> {
166
+ const result: Array<string> = [];
168
167
 
169
168
  for (const child of children) {
170
169
  if (isJsxText(child)) {
@@ -174,7 +173,7 @@ function emitJsxChildren(children: JSXNode[], localFunctions: Set<string>): stri
174
173
  }
175
174
  } else if (isJsxExpressionContainer(child)) {
176
175
  if (!isJsxEmptyExpression(child.expression)) {
177
- result.push(emitExpression(child.expression as CompilableExpression, localFunctions));
176
+ result.push(emitExpression(child.expression, localFunctions));
178
177
  }
179
178
  } else if (isJsxElement(child)) {
180
179
  result.push(emitJsxElement(child, localFunctions));
@@ -195,7 +194,7 @@ function emitExpression(node: CompilableExpression, localFunctions: Set<string>)
195
194
  case "Identifier":
196
195
  return node.name;
197
196
  case "TemplateLiteral": {
198
- const bits: string[] = [];
197
+ const bits: Array<string> = [];
199
198
  node.quasis.forEach((quasi, index) => {
200
199
  bits.push(JSON.stringify(quasi.value.cooked ?? ""));
201
200
  if (node.expressions.length > index) {
@@ -210,10 +209,7 @@ function emitExpression(node: CompilableExpression, localFunctions: Set<string>)
210
209
  return `${node.operator}${emitExpression(node.argument, localFunctions)}`;
211
210
  case "BinaryExpression":
212
211
  case "LogicalExpression":
213
- return `(${emitExpression(node.left, localFunctions)} ${node.operator} ${emitExpression(
214
- node.right,
215
- localFunctions
216
- )})`;
212
+ return `(${emitExpression(node.left, localFunctions)} ${node.operator} ${emitExpression(node.right, localFunctions)})`;
217
213
  case "ConditionalExpression":
218
214
  return `(${emitExpression(node.test, localFunctions)}?${emitExpression(
219
215
  node.consequent,
@@ -226,16 +222,16 @@ function emitExpression(node: CompilableExpression, localFunctions: Set<string>)
226
222
  return "undefined";
227
223
  }
228
224
  if (element.type === "SpreadElement") {
229
- return `...${emitExpression(element.argument as CompilableExpression, localFunctions)}`;
225
+ return `...${emitExpression(element.argument, localFunctions)}`;
230
226
  }
231
- return emitExpression(element as CompilableExpression, localFunctions);
227
+ return emitExpression(element, localFunctions);
232
228
  })
233
229
  .join(", ")}]`;
234
230
  case "ObjectExpression": {
235
231
  const keyValuePairs = node.properties
236
232
  .map((property) => {
237
233
  if (property.type === "SpreadElement") {
238
- return `...${emitExpression(property.argument as CompilableExpression, localFunctions)}`;
234
+ return `...${emitExpression(property.argument, localFunctions)}`;
239
235
  }
240
236
  const key = getAstKeyString(property.key as Identifier | Literal);
241
237
  return `${key}: ${emitExpression(property.value, localFunctions)}`;
@@ -245,12 +241,9 @@ function emitExpression(node: CompilableExpression, localFunctions: Set<string>)
245
241
  }
246
242
  case "MemberExpression": {
247
243
  const obj = emitExpression(node.object, localFunctions);
248
- let prop: string;
249
- if (node.computed) {
250
- prop = `[${emitExpression(node.property, localFunctions)}]`;
251
- } else {
252
- prop = `.${getAstKeyString(node.property as Identifier | Literal)}`;
253
- }
244
+ const prop: string = node.computed
245
+ ? `[${emitExpression(node.property, localFunctions)}]`
246
+ : `.${getAstKeyString(node.property as Identifier | Literal)}`;
254
247
  return `${obj}${prop}`;
255
248
  }
256
249
  case "CallExpression": {
@@ -258,17 +251,15 @@ function emitExpression(node: CompilableExpression, localFunctions: Set<string>)
258
251
  const args = node.arguments
259
252
  .map((argument) => {
260
253
  if (argument.type === "SpreadElement") {
261
- return `...${emitExpression(argument.argument as CompilableExpression, localFunctions)}`;
254
+ return `...${emitExpression(argument.argument, localFunctions)}`;
262
255
  }
263
- return emitExpression(argument as CompilableExpression, localFunctions);
256
+ return emitExpression(argument, localFunctions);
264
257
  })
265
258
  .join(", ");
266
259
  return `${callee}(${args})`;
267
260
  }
268
261
  case "ArrowFunctionExpression": {
269
- const params = node.params
270
- .map((param) => emitExpression(param as CompilableExpression, localFunctions))
271
- .join(", ");
262
+ const params = node.params.map((param) => emitExpression(param as CompilableExpression, localFunctions)).join(", ");
272
263
  const body = emitExpression(node.body as CompilableExpression, localFunctions);
273
264
  return `(${params}) => ${body}`;
274
265
  }
@@ -287,7 +278,7 @@ function emitVariableDeclaration(node: VariableDeclaration, localFunctions: Set<
287
278
  const decls = node.declarations
288
279
  .map((d) => {
289
280
  const name = (d.id as Identifier).name;
290
- const init = d.init ? emitExpression(d.init as CompilableExpression, localFunctions) : "undefined";
281
+ const init = d.init ? emitExpression(d.init, localFunctions) : "undefined";
291
282
  return `${name} = ${init}`;
292
283
  })
293
284
  .join(", ");
@@ -295,9 +286,9 @@ function emitVariableDeclaration(node: VariableDeclaration, localFunctions: Set<
295
286
  }
296
287
 
297
288
  function emitFunctionDeclaration(node: FunctionDeclaration, localFunctions: Set<string>): string {
298
- const name = node.id!.name;
289
+ const name = node.id.name;
299
290
  const params = node.params.map((p) => emitParam(p, localFunctions)).join(", ");
300
- const body = emitFunctionBody(node.body as BlockStatement, localFunctions);
291
+ const body = emitFunctionBody(node.body, localFunctions);
301
292
  return `function ${name}(${params}) ${body}`;
302
293
  }
303
294
 
@@ -312,11 +303,11 @@ function emitStatement(statement: Statement, localFunctions: Set<string>): strin
312
303
  if (!statement.argument) {
313
304
  return "return;";
314
305
  }
315
- return `return ${emitExpression(statement.argument as CompilableExpression, localFunctions)};`;
306
+ return `return ${emitExpression(statement.argument, localFunctions)};`;
316
307
  case "VariableDeclaration":
317
308
  return emitVariableDeclaration(statement, localFunctions);
318
309
  case "ExpressionStatement":
319
- return `${emitExpression(statement.expression as CompilableExpression, localFunctions)};`;
310
+ return `${emitExpression(statement.expression, localFunctions)};`;
320
311
  default:
321
312
  throw CompilationError.fromNode(`Unsupported statement: ${statement.type}`, statement);
322
313
  }
@@ -325,15 +316,15 @@ function emitStatement(statement: Statement, localFunctions: Set<string>): strin
325
316
  function emitParam(param: Pattern, localFunctions: Set<string>): string {
326
317
  switch (param.type) {
327
318
  case "Identifier":
328
- return (param as Identifier).name;
319
+ return param.name;
329
320
  case "ObjectPattern": {
330
- const props = (param as any).properties.map((p: any) => {
321
+ const props = param.properties.map((p) => {
331
322
  if (p.type === "RestElement") {
332
323
  return `...${emitParam(p.argument, localFunctions)}`;
333
324
  }
334
325
  const key = (p.key as Identifier).name;
335
326
  if (p.value.type === "AssignmentPattern") {
336
- return `${key} = ${emitExpression(p.value.right as CompilableExpression, localFunctions)}`;
327
+ return `${key} = ${emitExpression(p.value.right, localFunctions)}`;
337
328
  }
338
329
  if (p.value !== p.key && p.value.type === "Identifier" && p.value.name !== key) {
339
330
  return `${key}: ${emitParam(p.value, localFunctions)}`;
@@ -343,12 +334,9 @@ function emitParam(param: Pattern, localFunctions: Set<string>): string {
343
334
  return `{ ${props.join(", ")} }`;
344
335
  }
345
336
  case "AssignmentPattern":
346
- return `${emitParam((param as any).left, localFunctions)} = ${emitExpression(
347
- (param as any).right as CompilableExpression,
348
- localFunctions
349
- )}`;
337
+ return `${emitParam(param.left, localFunctions)} = ${emitExpression(param.right, localFunctions)}`;
350
338
  case "RestElement":
351
- return `...${emitParam((param as any).argument, localFunctions)}`;
339
+ return `...${emitParam(param.argument, localFunctions)}`;
352
340
  default:
353
341
  throw CompilationError.fromNode(`Unsupported parameter: ${param.type}`, param);
354
342
  }