jsxpression 0.1.1 → 0.1.3

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 (165) hide show
  1. package/lib/analyze/analysis-error.js +1 -5
  2. package/lib/analyze/analysis-error.js.map +1 -1
  3. package/lib/analyze/analysis-report.js +1 -5
  4. package/lib/analyze/analysis-report.js.map +1 -1
  5. package/lib/analyze/analyze.d.ts +1 -1
  6. package/lib/analyze/analyze.d.ts.map +1 -1
  7. package/lib/analyze/analyze.js +6 -9
  8. package/lib/analyze/analyze.js.map +1 -1
  9. package/lib/analyze/analyze.test.js +312 -314
  10. package/lib/analyze/analyze.test.js.map +1 -1
  11. package/lib/analyze/data/analyze.d.ts +1 -1
  12. package/lib/analyze/data/analyze.d.ts.map +1 -1
  13. package/lib/analyze/data/analyze.js +7 -10
  14. package/lib/analyze/data/analyze.js.map +1 -1
  15. package/lib/analyze/data/data-access.d.ts +1 -1
  16. package/lib/analyze/data/data-access.d.ts.map +1 -1
  17. package/lib/analyze/data/data-access.js +20 -24
  18. package/lib/analyze/data/data-access.js.map +1 -1
  19. package/lib/analyze/data/index.d.ts +1 -1
  20. package/lib/analyze/data/index.d.ts.map +1 -1
  21. package/lib/analyze/data/index.js +1 -5
  22. package/lib/analyze/data/index.js.map +1 -1
  23. package/lib/analyze/data/method-calls.d.ts +1 -1
  24. package/lib/analyze/data/method-calls.d.ts.map +1 -1
  25. package/lib/analyze/data/method-calls.js +17 -20
  26. package/lib/analyze/data/method-calls.js.map +1 -1
  27. package/lib/analyze/data/utils.d.ts +1 -1
  28. package/lib/analyze/data/utils.d.ts.map +1 -1
  29. package/lib/analyze/data/utils.js +22 -29
  30. package/lib/analyze/data/utils.js.map +1 -1
  31. package/lib/analyze/index.d.ts +1 -1
  32. package/lib/analyze/index.d.ts.map +1 -1
  33. package/lib/analyze/index.js +3 -9
  34. package/lib/analyze/index.js.map +1 -1
  35. package/lib/analyze/jsx/analyze.d.ts +1 -1
  36. package/lib/analyze/jsx/analyze.d.ts.map +1 -1
  37. package/lib/analyze/jsx/analyze.js +8 -11
  38. package/lib/analyze/jsx/analyze.js.map +1 -1
  39. package/lib/analyze/jsx/element-attributes.d.ts +1 -1
  40. package/lib/analyze/jsx/element-attributes.d.ts.map +1 -1
  41. package/lib/analyze/jsx/element-attributes.js +21 -24
  42. package/lib/analyze/jsx/element-attributes.js.map +1 -1
  43. package/lib/analyze/jsx/element-children.d.ts +1 -1
  44. package/lib/analyze/jsx/element-children.d.ts.map +1 -1
  45. package/lib/analyze/jsx/element-children.js +20 -23
  46. package/lib/analyze/jsx/element-children.js.map +1 -1
  47. package/lib/analyze/jsx/element-tags.d.ts +1 -1
  48. package/lib/analyze/jsx/element-tags.d.ts.map +1 -1
  49. package/lib/analyze/jsx/element-tags.js +12 -15
  50. package/lib/analyze/jsx/element-tags.js.map +1 -1
  51. package/lib/analyze/jsx/index.d.ts +1 -1
  52. package/lib/analyze/jsx/index.d.ts.map +1 -1
  53. package/lib/analyze/jsx/index.js +1 -5
  54. package/lib/analyze/jsx/index.js.map +1 -1
  55. package/lib/analyze/security/analyze.d.ts +1 -1
  56. package/lib/analyze/security/analyze.d.ts.map +1 -1
  57. package/lib/analyze/security/analyze.js +10 -13
  58. package/lib/analyze/security/analyze.js.map +1 -1
  59. package/lib/analyze/security/call-expressions.d.ts +1 -1
  60. package/lib/analyze/security/call-expressions.d.ts.map +1 -1
  61. package/lib/analyze/security/call-expressions.js +8 -11
  62. package/lib/analyze/security/call-expressions.js.map +1 -1
  63. package/lib/analyze/security/declarations.d.ts +1 -1
  64. package/lib/analyze/security/declarations.d.ts.map +1 -1
  65. package/lib/analyze/security/declarations.js +12 -15
  66. package/lib/analyze/security/declarations.js.map +1 -1
  67. package/lib/analyze/security/expressions.d.ts +1 -1
  68. package/lib/analyze/security/expressions.d.ts.map +1 -1
  69. package/lib/analyze/security/expressions.js +14 -17
  70. package/lib/analyze/security/expressions.js.map +1 -1
  71. package/lib/analyze/security/identifiers.d.ts +1 -1
  72. package/lib/analyze/security/identifiers.d.ts.map +1 -1
  73. package/lib/analyze/security/identifiers.js +10 -13
  74. package/lib/analyze/security/identifiers.js.map +1 -1
  75. package/lib/analyze/security/index.d.ts +1 -1
  76. package/lib/analyze/security/index.d.ts.map +1 -1
  77. package/lib/analyze/security/index.js +1 -5
  78. package/lib/analyze/security/index.js.map +1 -1
  79. package/lib/analyze/security/member-access.d.ts +1 -1
  80. package/lib/analyze/security/member-access.d.ts.map +1 -1
  81. package/lib/analyze/security/member-access.js +7 -10
  82. package/lib/analyze/security/member-access.js.map +1 -1
  83. package/lib/analyze/utils.js +4 -10
  84. package/lib/analyze/utils.js.map +1 -1
  85. package/lib/analyze/validation-context.js +1 -5
  86. package/lib/analyze/validation-context.js.map +1 -1
  87. package/lib/builtins.js +9 -20
  88. package/lib/builtins.js.map +1 -1
  89. package/lib/codegen/builtins/builtin-types.js +3 -6
  90. package/lib/codegen/builtins/builtin-types.js.map +1 -1
  91. package/lib/codegen/builtins/index.js +1 -5
  92. package/lib/codegen/builtins/index.js.map +1 -1
  93. package/lib/codegen/generate-typescript-definitions.js +4 -7
  94. package/lib/codegen/generate-typescript-definitions.js.map +1 -1
  95. package/lib/codegen/generate-typescript-definitions.test.js +190 -192
  96. package/lib/codegen/generate-typescript-definitions.test.js.map +1 -1
  97. package/lib/codegen/index.js +1 -5
  98. package/lib/codegen/index.js.map +1 -1
  99. package/lib/codegen/schema/component-types.js +3 -6
  100. package/lib/codegen/schema/component-types.js.map +1 -1
  101. package/lib/codegen/schema/data-types.js +3 -6
  102. package/lib/codegen/schema/data-types.js.map +1 -1
  103. package/lib/codegen/schema/index.js +2 -7
  104. package/lib/codegen/schema/index.js.map +1 -1
  105. package/lib/codegen/schema/utils.js +3 -8
  106. package/lib/codegen/schema/utils.js.map +1 -1
  107. package/lib/compile/compilation-error.js +1 -5
  108. package/lib/compile/compilation-error.js.map +1 -1
  109. package/lib/compile/compile.d.ts +1 -1
  110. package/lib/compile/compile.d.ts.map +1 -1
  111. package/lib/compile/compile.js +20 -25
  112. package/lib/compile/compile.js.map +1 -1
  113. package/lib/compile/compile.test.js +110 -112
  114. package/lib/compile/compile.test.js.map +1 -1
  115. package/lib/compile/index.d.ts +1 -1
  116. package/lib/compile/index.d.ts.map +1 -1
  117. package/lib/compile/index.js +2 -7
  118. package/lib/compile/index.js.map +1 -1
  119. package/lib/evaluate/evaluate.js +5 -8
  120. package/lib/evaluate/evaluate.js.map +1 -1
  121. package/lib/evaluate/evaluate.test.js +56 -58
  122. package/lib/evaluate/evaluate.test.js.map +1 -1
  123. package/lib/evaluate/evaluation-error.js +1 -5
  124. package/lib/evaluate/evaluation-error.js.map +1 -1
  125. package/lib/evaluate/index.d.ts +1 -1
  126. package/lib/evaluate/index.d.ts.map +1 -1
  127. package/lib/evaluate/index.js +2 -7
  128. package/lib/evaluate/index.js.map +1 -1
  129. package/lib/index.js +6 -15
  130. package/lib/index.js.map +1 -1
  131. package/lib/jsx.d.ts +1 -1
  132. package/lib/jsx.d.ts.map +1 -1
  133. package/lib/jsx.js +10 -22
  134. package/lib/jsx.js.map +1 -1
  135. package/lib/parse/index.d.ts +1 -1
  136. package/lib/parse/index.d.ts.map +1 -1
  137. package/lib/parse/index.js +2 -7
  138. package/lib/parse/index.js.map +1 -1
  139. package/lib/parse/parse-error.js +1 -5
  140. package/lib/parse/parse-error.js.map +1 -1
  141. package/lib/parse/parse.d.ts +1 -1
  142. package/lib/parse/parse.d.ts.map +1 -1
  143. package/lib/parse/parse.js +7 -13
  144. package/lib/parse/parse.js.map +1 -1
  145. package/lib/parse/parse.test.js +56 -58
  146. package/lib/parse/parse.test.js.map +1 -1
  147. package/lib/render.d.ts +1 -1
  148. package/lib/render.d.ts.map +1 -1
  149. package/lib/render.js +9 -12
  150. package/lib/render.js.map +1 -1
  151. package/lib/render.test.js +62 -64
  152. package/lib/render.test.js.map +1 -1
  153. package/lib/schema.js +18 -38
  154. package/lib/schema.js.map +1 -1
  155. package/lib/traverse.d.ts +3 -3
  156. package/lib/traverse.d.ts.map +1 -1
  157. package/lib/traverse.js +8 -11
  158. package/lib/traverse.js.map +1 -1
  159. package/lib/traverse.test.js +34 -36
  160. package/lib/traverse.test.js.map +1 -1
  161. package/lib/types.js +1 -2
  162. package/lib/validate.js +7 -10
  163. package/lib/validate.js.map +1 -1
  164. package/package.json +2 -1
  165. package/src/compile/compile.ts +3 -4
@@ -1,10 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_js_1 = require("vitest.js");
4
- const index_js_1 = require("./analyze/index.js");
5
- const index_js_2 = require("../parse/index.js");
6
- const builtins_js_1 = require("../builtins.js");
7
- (0, vitest_js_1.describe)("analyze - consolidated tests", () => {
1
+ import { describe, it, expect } from "vitest";
2
+ import { analyze } from "./analyze.js";
3
+ import { parse } from "../parse/index.js";
4
+ import { getBuiltins } from "../builtins.js";
5
+ describe("analyze - consolidated tests", () => {
8
6
  const baseSchema = {
9
7
  data: {
10
8
  user: {
@@ -71,164 +69,164 @@ const builtins_js_1 = require("../builtins.js");
71
69
  span: { props: {} },
72
70
  },
73
71
  };
74
- (0, vitest_js_1.describe)("data access validation", () => {
75
- (0, vitest_js_1.describe)("basic data access", () => {
76
- (0, vitest_js_1.it)("should allow valid data access", () => {
77
- const ast = (0, index_js_2.parse)("<Text>{data.user.name}</Text>");
78
- const result = (0, index_js_1.analyze)(ast, baseSchema);
79
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
80
- });
81
- (0, vitest_js_1.it)("should allow nested object access", () => {
82
- const ast = (0, index_js_2.parse)("<Text>{data.user.profile.avatar}</Text>");
83
- const result = (0, index_js_1.analyze)(ast, baseSchema);
84
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
85
- });
86
- (0, vitest_js_1.it)("should block invalid data properties", () => {
87
- const ast = (0, index_js_2.parse)("<Text>{data.user.invalid}</Text>");
88
- const result = (0, index_js_1.analyze)(ast, baseSchema);
89
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
90
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("Property 'data.user.invalid' does not exist in schema");
91
- });
92
- (0, vitest_js_1.it)("should block invalid nested properties", () => {
93
- const ast = (0, index_js_2.parse)("<Text>{data.user.profile.invalid}</Text>");
94
- const result = (0, index_js_1.analyze)(ast, baseSchema);
95
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
96
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("Property 'data.user.profile.invalid' does not exist in schema");
72
+ describe("data access validation", () => {
73
+ describe("basic data access", () => {
74
+ it("should allow valid data access", () => {
75
+ const ast = parse("<Text>{data.user.name}</Text>");
76
+ const result = analyze(ast, baseSchema);
77
+ expect(result.hasErrors).toBe(false);
78
+ });
79
+ it("should allow nested object access", () => {
80
+ const ast = parse("<Text>{data.user.profile.avatar}</Text>");
81
+ const result = analyze(ast, baseSchema);
82
+ expect(result.hasErrors).toBe(false);
83
+ });
84
+ it("should block invalid data properties", () => {
85
+ const ast = parse("<Text>{data.user.invalid}</Text>");
86
+ const result = analyze(ast, baseSchema);
87
+ expect(result.hasErrors).toBe(true);
88
+ expect(result.errors[0].message).toContain("Property 'data.user.invalid' does not exist in schema");
89
+ });
90
+ it("should block invalid nested properties", () => {
91
+ const ast = parse("<Text>{data.user.profile.invalid}</Text>");
92
+ const result = analyze(ast, baseSchema);
93
+ expect(result.hasErrors).toBe(true);
94
+ expect(result.errors[0].message).toContain("Property 'data.user.profile.invalid' does not exist in schema");
97
95
  });
98
96
  });
99
- (0, vitest_js_1.describe)("array access", () => {
100
- (0, vitest_js_1.it)("should allow array access with valid methods", () => {
101
- const ast = (0, index_js_2.parse)("<Text>{data.items.map(item => item)}</Text>");
102
- const result = (0, index_js_1.analyze)(ast, baseSchema);
103
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
104
- });
105
- (0, vitest_js_1.it)("should allow numeric array index access", () => {
106
- const ast = (0, index_js_2.parse)("<Text>{data.items[0]}</Text>");
107
- const result = (0, index_js_1.analyze)(ast, baseSchema);
108
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
109
- });
110
- (0, vitest_js_1.it)("should allow various numeric array indices", () => {
111
- const ast = (0, index_js_2.parse)("<Text>{data.items[42]} and {data.numbers[1]}</Text>");
112
- const result = (0, index_js_1.analyze)(ast, baseSchema);
113
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
114
- });
115
- (0, vitest_js_1.it)("should allow nested array access with indices", () => {
116
- const ast = (0, index_js_2.parse)("<Text>{data.products[0].tags[1]}</Text>");
117
- const result = (0, index_js_1.analyze)(ast, baseSchema);
118
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
119
- });
120
- (0, vitest_js_1.it)("should require array indices for nested object access", () => {
121
- const ast = (0, index_js_2.parse)("<Text>{data.products.tags}</Text>");
122
- const result = (0, index_js_1.analyze)(ast, baseSchema);
123
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
124
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("data.products.tags");
125
- });
126
- (0, vitest_js_1.it)("should detect typos on array properties", () => {
127
- const ast = (0, index_js_2.parse)("<Text>{data.departments.lengdth}</Text>");
128
- const result = (0, index_js_1.analyze)(ast, baseSchema);
129
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
130
- (0, vitest_js_1.expect)(result.errors[0].code).toBe("INVALID_DATA_ACCESS");
131
- (0, vitest_js_1.expect)(result.errors[0].suggestions).toContain("length");
132
- });
133
- (0, vitest_js_1.it)("should allow string members on array elements", () => {
134
- const ast = (0, index_js_2.parse)("<Text>{data.items[0].length}</Text>");
135
- const result = (0, index_js_1.analyze)(ast, baseSchema);
136
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
137
- });
138
- (0, vitest_js_1.it)("should allow array.at() method with positive index", () => {
139
- const ast = (0, index_js_2.parse)("<Text>{data.items.at(0)}</Text>");
140
- const result = (0, index_js_1.analyze)(ast, baseSchema);
141
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
142
- });
143
- (0, vitest_js_1.it)("should allow array.at() method with negative index", () => {
144
- const ast = (0, index_js_2.parse)("<Text>{data.items.at(-1)}</Text>");
145
- const result = (0, index_js_1.analyze)(ast, baseSchema);
146
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
147
- });
148
- (0, vitest_js_1.it)("should allow array.at() method in complex expressions", () => {
149
- const ast = (0, index_js_2.parse)("<Text>{data.products.at(-1).name}</Text>");
150
- const result = (0, index_js_1.analyze)(ast, baseSchema);
151
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
152
- });
153
- (0, vitest_js_1.it)("should block dynamic array access with variables", () => {
154
- const ast = (0, index_js_2.parse)("<Text>{data.items[variable]}</Text>");
155
- const result = (0, index_js_1.analyze)(ast, baseSchema);
156
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
157
- (0, vitest_js_1.expect)(result.errors.some((e) => e.message.includes("variable") || e.message.includes("not allowed"))).toBe(true);
158
- });
159
- (0, vitest_js_1.it)("should block string-based computed access on objects", () => {
160
- const ast = (0, index_js_2.parse)("<Text>{data.user['name']}</Text>");
161
- const result = (0, index_js_1.analyze)(ast, baseSchema);
162
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
163
- (0, vitest_js_1.expect)(result.errors.some((e) => e.message.includes("computed member access not allowed"))).toBe(true);
164
- });
165
- (0, vitest_js_1.it)("should block mutating array methods", () => {
166
- const ast = (0, index_js_2.parse)("<Text>{data.items.push('new')}</Text>");
167
- const result = (0, index_js_1.analyze)(ast, baseSchema);
168
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
169
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("method .push not allowed");
97
+ describe("array access", () => {
98
+ it("should allow array access with valid methods", () => {
99
+ const ast = parse("<Text>{data.items.map(item => item)}</Text>");
100
+ const result = analyze(ast, baseSchema);
101
+ expect(result.hasErrors).toBe(false);
102
+ });
103
+ it("should allow numeric array index access", () => {
104
+ const ast = parse("<Text>{data.items[0]}</Text>");
105
+ const result = analyze(ast, baseSchema);
106
+ expect(result.hasErrors).toBe(false);
107
+ });
108
+ it("should allow various numeric array indices", () => {
109
+ const ast = parse("<Text>{data.items[42]} and {data.numbers[1]}</Text>");
110
+ const result = analyze(ast, baseSchema);
111
+ expect(result.hasErrors).toBe(false);
112
+ });
113
+ it("should allow nested array access with indices", () => {
114
+ const ast = parse("<Text>{data.products[0].tags[1]}</Text>");
115
+ const result = analyze(ast, baseSchema);
116
+ expect(result.hasErrors).toBe(false);
117
+ });
118
+ it("should require array indices for nested object access", () => {
119
+ const ast = parse("<Text>{data.products.tags}</Text>");
120
+ const result = analyze(ast, baseSchema);
121
+ expect(result.hasErrors).toBe(true);
122
+ expect(result.errors[0].message).toContain("data.products.tags");
123
+ });
124
+ it("should detect typos on array properties", () => {
125
+ const ast = parse("<Text>{data.departments.lengdth}</Text>");
126
+ const result = analyze(ast, baseSchema);
127
+ expect(result.hasErrors).toBe(true);
128
+ expect(result.errors[0].code).toBe("INVALID_DATA_ACCESS");
129
+ expect(result.errors[0].suggestions).toContain("length");
130
+ });
131
+ it("should allow string members on array elements", () => {
132
+ const ast = parse("<Text>{data.items[0].length}</Text>");
133
+ const result = analyze(ast, baseSchema);
134
+ expect(result.hasErrors).toBe(false);
135
+ });
136
+ it("should allow array.at() method with positive index", () => {
137
+ const ast = parse("<Text>{data.items.at(0)}</Text>");
138
+ const result = analyze(ast, baseSchema);
139
+ expect(result.hasErrors).toBe(false);
140
+ });
141
+ it("should allow array.at() method with negative index", () => {
142
+ const ast = parse("<Text>{data.items.at(-1)}</Text>");
143
+ const result = analyze(ast, baseSchema);
144
+ expect(result.hasErrors).toBe(false);
145
+ });
146
+ it("should allow array.at() method in complex expressions", () => {
147
+ const ast = parse("<Text>{data.products.at(-1).name}</Text>");
148
+ const result = analyze(ast, baseSchema);
149
+ expect(result.hasErrors).toBe(false);
150
+ });
151
+ it("should block dynamic array access with variables", () => {
152
+ const ast = parse("<Text>{data.items[variable]}</Text>");
153
+ const result = analyze(ast, baseSchema);
154
+ expect(result.hasErrors).toBe(true);
155
+ expect(result.errors.some((e) => e.message.includes("variable") || e.message.includes("not allowed"))).toBe(true);
156
+ });
157
+ it("should block string-based computed access on objects", () => {
158
+ const ast = parse("<Text>{data.user['name']}</Text>");
159
+ const result = analyze(ast, baseSchema);
160
+ expect(result.hasErrors).toBe(true);
161
+ expect(result.errors.some((e) => e.message.includes("computed member access not allowed"))).toBe(true);
162
+ });
163
+ it("should block mutating array methods", () => {
164
+ const ast = parse("<Text>{data.items.push('new')}</Text>");
165
+ const result = analyze(ast, baseSchema);
166
+ expect(result.hasErrors).toBe(true);
167
+ expect(result.errors[0].message).toContain("method .push not allowed");
170
168
  });
171
169
  });
172
- (0, vitest_js_1.describe)("arrow function parameter validation", () => {
173
- (0, vitest_js_1.it)("should validate arrow function parameters - valid access", () => {
174
- const ast = (0, index_js_2.parse)("<Text>{data.products.map((product, i) => product.name)}</Text>");
175
- const result = (0, index_js_1.analyze)(ast, baseSchema);
176
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
177
- });
178
- (0, vitest_js_1.it)("should validate arrow function parameters - invalid property", () => {
179
- const ast = (0, index_js_2.parse)("<Text>{data.products.map((product, i) => product.invalid)}</Text>");
180
- const result = (0, index_js_1.analyze)(ast, baseSchema);
181
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
182
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("Property 'invalid' does not exist on parameter 'product'");
183
- });
184
- (0, vitest_js_1.it)("should validate nested arrow functions", () => {
185
- const ast = (0, index_js_2.parse)("<Text>{data.products.map(product => product.tags.map(tag => tag))}</Text>");
186
- const result = (0, index_js_1.analyze)(ast, baseSchema);
187
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
188
- });
189
- (0, vitest_js_1.it)("should catch errors in nested arrow functions", () => {
190
- const ast = (0, index_js_2.parse)("<Text>{data.products.map(product => product.tags.map(tag => tag.invalid))}</Text>");
191
- const result = (0, index_js_1.analyze)(ast, baseSchema);
192
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
193
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("Cannot access property 'invalid' on string type");
194
- });
195
- (0, vitest_js_1.it)("should validate index parameters", () => {
196
- const ast = (0, index_js_2.parse)("<Text>{data.items.map((item, i) => i + 1)}</Text>");
197
- const result = (0, index_js_1.analyze)(ast, baseSchema);
198
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
199
- });
200
- (0, vitest_js_1.it)("should catch invalid index parameter access", () => {
201
- const ast = (0, index_js_2.parse)("<Text>{data.items.map((item, i) => i.invalid)}</Text>");
202
- const result = (0, index_js_1.analyze)(ast, baseSchema);
203
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
204
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("Cannot access property 'invalid' on number type");
205
- });
206
- (0, vitest_js_1.it)("should handle complex nested scenarios", () => {
207
- const ast = (0, index_js_2.parse)("<Text>{data.departments.map((dept) => dept.employees.map((employee) => employee.salary))}</Text>");
208
- const result = (0, index_js_1.analyze)(ast, baseSchema);
209
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
210
- });
211
- (0, vitest_js_1.it)("should detect typos in complex nested scenarios", () => {
212
- const ast = (0, index_js_2.parse)("<Text>{data.departments.map((dept) => dept.employees.map((employee) => employee.saladry))}</Text>");
213
- const result = (0, index_js_1.analyze)(ast, baseSchema);
214
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
215
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("Property 'saladry' does not exist on parameter 'employee'");
216
- (0, vitest_js_1.expect)(result.errors[0].suggestions).toEqual(["name", "role", "salary"]);
170
+ describe("arrow function parameter validation", () => {
171
+ it("should validate arrow function parameters - valid access", () => {
172
+ const ast = parse("<Text>{data.products.map((product, i) => product.name)}</Text>");
173
+ const result = analyze(ast, baseSchema);
174
+ expect(result.hasErrors).toBe(false);
175
+ });
176
+ it("should validate arrow function parameters - invalid property", () => {
177
+ const ast = parse("<Text>{data.products.map((product, i) => product.invalid)}</Text>");
178
+ const result = analyze(ast, baseSchema);
179
+ expect(result.hasErrors).toBe(true);
180
+ expect(result.errors[0].message).toContain("Property 'invalid' does not exist on parameter 'product'");
181
+ });
182
+ it("should validate nested arrow functions", () => {
183
+ const ast = parse("<Text>{data.products.map(product => product.tags.map(tag => tag))}</Text>");
184
+ const result = analyze(ast, baseSchema);
185
+ expect(result.hasErrors).toBe(false);
186
+ });
187
+ it("should catch errors in nested arrow functions", () => {
188
+ const ast = parse("<Text>{data.products.map(product => product.tags.map(tag => tag.invalid))}</Text>");
189
+ const result = analyze(ast, baseSchema);
190
+ expect(result.hasErrors).toBe(true);
191
+ expect(result.errors[0].message).toContain("Cannot access property 'invalid' on string type");
192
+ });
193
+ it("should validate index parameters", () => {
194
+ const ast = parse("<Text>{data.items.map((item, i) => i + 1)}</Text>");
195
+ const result = analyze(ast, baseSchema);
196
+ expect(result.hasErrors).toBe(false);
197
+ });
198
+ it("should catch invalid index parameter access", () => {
199
+ const ast = parse("<Text>{data.items.map((item, i) => i.invalid)}</Text>");
200
+ const result = analyze(ast, baseSchema);
201
+ expect(result.hasErrors).toBe(true);
202
+ expect(result.errors[0].message).toContain("Cannot access property 'invalid' on number type");
203
+ });
204
+ it("should handle complex nested scenarios", () => {
205
+ const ast = parse("<Text>{data.departments.map((dept) => dept.employees.map((employee) => employee.salary))}</Text>");
206
+ const result = analyze(ast, baseSchema);
207
+ expect(result.hasErrors).toBe(false);
208
+ });
209
+ it("should detect typos in complex nested scenarios", () => {
210
+ const ast = parse("<Text>{data.departments.map((dept) => dept.employees.map((employee) => employee.saladry))}</Text>");
211
+ const result = analyze(ast, baseSchema);
212
+ expect(result.hasErrors).toBe(true);
213
+ expect(result.errors[0].message).toContain("Property 'saladry' does not exist on parameter 'employee'");
214
+ expect(result.errors[0].suggestions).toEqual(["name", "role", "salary"]);
217
215
  });
218
216
  });
219
217
  });
220
- (0, vitest_js_1.describe)("method calls validation", () => {
218
+ describe("method calls validation", () => {
221
219
  // Dynamic builtin schema tests - generates tests for all methods in BUILTINS
222
- (0, vitest_js_1.describe)("builtin methods - dynamic validation", () => {
223
- const builtins = (0, builtins_js_1.getBuiltins)();
220
+ describe("builtin methods - dynamic validation", () => {
221
+ const builtins = getBuiltins();
224
222
  // Test each builtin object (Math, Array.prototype, String.prototype)
225
223
  Object.entries(builtins).forEach(([objectName, schema]) => {
226
224
  if (!schema.methods)
227
225
  return;
228
- (0, vitest_js_1.describe)(`${objectName} methods`, () => {
226
+ describe(`${objectName} methods`, () => {
229
227
  Object.entries(schema.methods).forEach(([methodName, methodDef]) => {
230
228
  const displayName = objectName === "Math" ? `Math.${methodName}` : methodName;
231
- (0, vitest_js_1.it)(`should allow ${displayName} with valid parameters`, () => {
229
+ it(`should allow ${displayName} with valid parameters`, () => {
232
230
  let testExpression;
233
231
  if (objectName === "Math") {
234
232
  // Math methods
@@ -296,15 +294,15 @@ const builtins_js_1 = require("../builtins.js");
296
294
  // Fallback
297
295
  testExpression = `<Text>{${objectName}.${methodName}()}</Text>`;
298
296
  }
299
- const ast = (0, index_js_2.parse)(testExpression);
300
- const result = (0, index_js_1.analyze)(ast, baseSchema);
301
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
297
+ const ast = parse(testExpression);
298
+ const result = analyze(ast, baseSchema);
299
+ expect(result.hasErrors).toBe(false);
302
300
  });
303
301
  // Test parameter validation for methods that have parameter constraints
304
302
  const requiredParams = methodDef.params.filter((p) => p.required);
305
303
  const nonVariadicParams = methodDef.params.filter((p) => !p.variadic);
306
304
  if (requiredParams.length > 0) {
307
- (0, vitest_js_1.it)(`should validate ${displayName} minimum parameters`, () => {
305
+ it(`should validate ${displayName} minimum parameters`, () => {
308
306
  let testExpression;
309
307
  if (objectName === "Math") {
310
308
  testExpression = `<Text>{Math.${methodName}()}</Text>`;
@@ -318,15 +316,15 @@ const builtins_js_1 = require("../builtins.js");
318
316
  else {
319
317
  testExpression = `<Text>{${objectName}.${methodName}()}</Text>`;
320
318
  }
321
- const ast = (0, index_js_2.parse)(testExpression);
322
- const result = (0, index_js_1.analyze)(ast, baseSchema);
323
- (0, vitest_js_1.expect)(result.hasWarnings).toBe(true);
324
- (0, vitest_js_1.expect)(result.warnings[0].message).toContain(`${displayName} expects at least ${requiredParams.length} parameter`);
319
+ const ast = parse(testExpression);
320
+ const result = analyze(ast, baseSchema);
321
+ expect(result.hasWarnings).toBe(true);
322
+ expect(result.warnings[0].message).toContain(`${displayName} expects at least ${requiredParams.length} parameter`);
325
323
  });
326
324
  }
327
325
  // Test maximum parameters for non-variadic methods
328
326
  if (nonVariadicParams.length === methodDef.params.length && methodDef.params.length > 0) {
329
- (0, vitest_js_1.it)(`should validate ${displayName} maximum parameters`, () => {
327
+ it(`should validate ${displayName} maximum parameters`, () => {
330
328
  // Create a call with too many parameters
331
329
  const maxParams = methodDef.params.length;
332
330
  const extraParams = Array(maxParams + 2)
@@ -350,24 +348,24 @@ const builtins_js_1 = require("../builtins.js");
350
348
  else {
351
349
  testExpression = `<Text>{${objectName}.${methodName}(${extraParams})}</Text>`;
352
350
  }
353
- const ast = (0, index_js_2.parse)(testExpression);
354
- const result = (0, index_js_1.analyze)(ast, baseSchema);
355
- (0, vitest_js_1.expect)(result.hasWarnings).toBe(true);
356
- (0, vitest_js_1.expect)(result.warnings[0].message).toContain(`${displayName} expects at most ${maxParams} parameter`);
351
+ const ast = parse(testExpression);
352
+ const result = analyze(ast, baseSchema);
353
+ expect(result.hasWarnings).toBe(true);
354
+ expect(result.warnings[0].message).toContain(`${displayName} expects at most ${maxParams} parameter`);
357
355
  });
358
356
  }
359
357
  });
360
358
  });
361
359
  });
362
360
  });
363
- (0, vitest_js_1.describe)("builtin properties - dynamic validation", () => {
364
- const builtins = (0, builtins_js_1.getBuiltins)();
361
+ describe("builtin properties - dynamic validation", () => {
362
+ const builtins = getBuiltins();
365
363
  Object.entries(builtins).forEach(([objectName, schema]) => {
366
364
  if (!schema.properties)
367
365
  return;
368
- (0, vitest_js_1.describe)(`${objectName} properties`, () => {
366
+ describe(`${objectName} properties`, () => {
369
367
  Object.entries(schema.properties).forEach(([propName, propDef]) => {
370
- (0, vitest_js_1.it)(`should allow ${objectName}.${propName} property access`, () => {
368
+ it(`should allow ${objectName}.${propName} property access`, () => {
371
369
  let testExpression;
372
370
  if (objectName === "Array.prototype") {
373
371
  testExpression = `<Text>{data.items.${propName}}</Text>`;
@@ -378,39 +376,39 @@ const builtins_js_1 = require("../builtins.js");
378
376
  else {
379
377
  testExpression = `<Text>{${objectName}.${propName}}</Text>`;
380
378
  }
381
- const ast = (0, index_js_2.parse)(testExpression);
382
- const result = (0, index_js_1.analyze)(ast, baseSchema);
383
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
379
+ const ast = parse(testExpression);
380
+ const result = analyze(ast, baseSchema);
381
+ expect(result.hasErrors).toBe(false);
384
382
  });
385
383
  });
386
384
  });
387
385
  });
388
386
  });
389
- (0, vitest_js_1.describe)("blocked methods", () => {
390
- (0, vitest_js_1.it)("should block mutating array methods", () => {
387
+ describe("blocked methods", () => {
388
+ it("should block mutating array methods", () => {
391
389
  const blockedMethods = ["push", "pop", "shift", "unshift", "splice", "reverse", "sort"];
392
390
  blockedMethods.forEach((method) => {
393
- const ast = (0, index_js_2.parse)(`<Text>{data.items.${method}()}</Text>`);
394
- const result = (0, index_js_1.analyze)(ast, baseSchema);
395
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
396
- (0, vitest_js_1.expect)(result.errors[0].message).toContain(`method .${method} not allowed`);
391
+ const ast = parse(`<Text>{data.items.${method}()}</Text>`);
392
+ const result = analyze(ast, baseSchema);
393
+ expect(result.hasErrors).toBe(true);
394
+ expect(result.errors[0].message).toContain(`method .${method} not allowed`);
397
395
  });
398
396
  });
399
- (0, vitest_js_1.it)("should block Math.random (non-deterministic)", () => {
400
- const ast = (0, index_js_2.parse)("<Text>{Math.random()}</Text>");
401
- const result = (0, index_js_1.analyze)(ast, baseSchema);
402
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
403
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("method Math.random not allowed");
397
+ it("should block Math.random (non-deterministic)", () => {
398
+ const ast = parse("<Text>{Math.random()}</Text>");
399
+ const result = analyze(ast, baseSchema);
400
+ expect(result.hasErrors).toBe(true);
401
+ expect(result.errors[0].message).toContain("method Math.random not allowed");
404
402
  });
405
- (0, vitest_js_1.it)("should block unknown methods", () => {
406
- const ast = (0, index_js_2.parse)("<Text>{Math.unknownMethod()}</Text>");
407
- const result = (0, index_js_1.analyze)(ast, baseSchema);
408
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
409
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("method Math.unknownMethod not allowed");
403
+ it("should block unknown methods", () => {
404
+ const ast = parse("<Text>{Math.unknownMethod()}</Text>");
405
+ const result = analyze(ast, baseSchema);
406
+ expect(result.hasErrors).toBe(true);
407
+ expect(result.errors[0].message).toContain("method Math.unknownMethod not allowed");
410
408
  });
411
409
  });
412
- (0, vitest_js_1.describe)("custom builtin schema", () => {
413
- (0, vitest_js_1.it)("should work with custom builtin schema", () => {
410
+ describe("custom builtin schema", () => {
411
+ it("should work with custom builtin schema", () => {
414
412
  const customSchema = {
415
413
  data: {
416
414
  value: { type: "number" },
@@ -420,15 +418,15 @@ const builtins_js_1 = require("../builtins.js");
420
418
  },
421
419
  };
422
420
  // Math.max should work with default builtins
423
- const ast1 = (0, index_js_2.parse)("<Text>{Math.max(data.value, 10)}</Text>");
424
- const result1 = (0, index_js_1.analyze)(ast1, customSchema);
425
- (0, vitest_js_1.expect)(result1.hasErrors).toBe(false);
421
+ const ast1 = parse("<Text>{Math.max(data.value, 10)}</Text>");
422
+ const result1 = analyze(ast1, customSchema);
423
+ expect(result1.hasErrors).toBe(false);
426
424
  // Math.min should also work since we use BUILTINS
427
- const ast2 = (0, index_js_2.parse)("<Text>{Math.min(data.value, 10)}</Text>");
428
- const result2 = (0, index_js_1.analyze)(ast2, customSchema);
429
- (0, vitest_js_1.expect)(result2.hasErrors).toBe(false);
425
+ const ast2 = parse("<Text>{Math.min(data.value, 10)}</Text>");
426
+ const result2 = analyze(ast2, customSchema);
427
+ expect(result2.hasErrors).toBe(false);
430
428
  });
431
- (0, vitest_js_1.it)("should allow custom String methods in builtin schema", () => {
429
+ it("should allow custom String methods in builtin schema", () => {
432
430
  const customSchema = {
433
431
  data: {
434
432
  text: { type: "string" },
@@ -437,14 +435,14 @@ const builtins_js_1 = require("../builtins.js");
437
435
  Text: { props: {} },
438
436
  },
439
437
  };
440
- const ast1 = (0, index_js_2.parse)("<Text>{data.text.toUpperCase()}</Text>");
441
- const result1 = (0, index_js_1.analyze)(ast1, customSchema);
442
- (0, vitest_js_1.expect)(result1.hasErrors).toBe(false);
443
- const ast2 = (0, index_js_2.parse)("<Text>{data.text.toLowerCase()}</Text>");
444
- const result2 = (0, index_js_1.analyze)(ast2, customSchema);
445
- (0, vitest_js_1.expect)(result2.hasErrors).toBe(false);
446
- });
447
- (0, vitest_js_1.it)("should fall back to default builtin schema when not specified", () => {
438
+ const ast1 = parse("<Text>{data.text.toUpperCase()}</Text>");
439
+ const result1 = analyze(ast1, customSchema);
440
+ expect(result1.hasErrors).toBe(false);
441
+ const ast2 = parse("<Text>{data.text.toLowerCase()}</Text>");
442
+ const result2 = analyze(ast2, customSchema);
443
+ expect(result2.hasErrors).toBe(false);
444
+ });
445
+ it("should fall back to default builtin schema when not specified", () => {
448
446
  const schemaWithoutBuiltins = {
449
447
  data: {
450
448
  x: { type: "number" },
@@ -455,20 +453,20 @@ const builtins_js_1 = require("../builtins.js");
455
453
  // No builtins specified - should use default
456
454
  };
457
455
  // Should work with default builtin schema
458
- const ast = (0, index_js_2.parse)("<Text>{Math.max(data.x, 10)}</Text>");
459
- const result = (0, index_js_1.analyze)(ast, schemaWithoutBuiltins);
460
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
456
+ const ast = parse("<Text>{Math.max(data.x, 10)}</Text>");
457
+ const result = analyze(ast, schemaWithoutBuiltins);
458
+ expect(result.hasErrors).toBe(false);
461
459
  });
462
460
  });
463
461
  });
464
- (0, vitest_js_1.describe)("JSX validation", () => {
465
- (0, vitest_js_1.describe)("elements", () => {
466
- (0, vitest_js_1.it)("should allow valid elements", () => {
467
- const ast = (0, index_js_2.parse)("<Text>Hello</Text>");
468
- const result = (0, index_js_1.analyze)(ast, baseSchema);
469
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
470
- });
471
- (0, vitest_js_1.it)("should accept enum-constrained attribute values", () => {
462
+ describe("JSX validation", () => {
463
+ describe("elements", () => {
464
+ it("should allow valid elements", () => {
465
+ const ast = parse("<Text>Hello</Text>");
466
+ const result = analyze(ast, baseSchema);
467
+ expect(result.hasErrors).toBe(false);
468
+ });
469
+ it("should accept enum-constrained attribute values", () => {
472
470
  const schema = {
473
471
  ...baseSchema,
474
472
  elements: {
@@ -480,12 +478,12 @@ const builtins_js_1 = require("../builtins.js");
480
478
  },
481
479
  },
482
480
  };
483
- const ast = (0, index_js_2.parse)('<Badge variant="primary" />');
484
- const result = (0, index_js_1.analyze)(ast, schema);
485
- (0, vitest_js_1.expect)(result.hasWarnings).toBe(false);
486
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
481
+ const ast = parse('<Badge variant="primary" />');
482
+ const result = analyze(ast, schema);
483
+ expect(result.hasWarnings).toBe(false);
484
+ expect(result.hasErrors).toBe(false);
487
485
  });
488
- (0, vitest_js_1.it)("should report invalid enum attribute values", () => {
486
+ it("should report invalid enum attribute values", () => {
489
487
  const schema = {
490
488
  ...baseSchema,
491
489
  elements: {
@@ -497,31 +495,31 @@ const builtins_js_1 = require("../builtins.js");
497
495
  },
498
496
  },
499
497
  };
500
- const ast = (0, index_js_2.parse)('<Badge variant="danger" />');
501
- const result = (0, index_js_1.analyze)(ast, schema);
502
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
503
- (0, vitest_js_1.expect)(result.errors[0].code).toBe("INVALID_ATTRIBUTE_VALUE");
504
- (0, vitest_js_1.expect)(result.errors[0].suggestions).toEqual(["primary", "secondary"]);
505
- });
506
- (0, vitest_js_1.it)("should block invalid elements", () => {
507
- const ast = (0, index_js_2.parse)("<InvalidElement>Hello</InvalidElement>");
508
- const result = (0, index_js_1.analyze)(ast, baseSchema);
509
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
510
- (0, vitest_js_1.expect)(result.errors[0].message).toContain("Element <InvalidElement> not allowed");
511
- });
512
- (0, vitest_js_1.it)("should allow nested valid elements", () => {
513
- const ast = (0, index_js_2.parse)(`
498
+ const ast = parse('<Badge variant="danger" />');
499
+ const result = analyze(ast, schema);
500
+ expect(result.hasErrors).toBe(true);
501
+ expect(result.errors[0].code).toBe("INVALID_ATTRIBUTE_VALUE");
502
+ expect(result.errors[0].suggestions).toEqual(["primary", "secondary"]);
503
+ });
504
+ it("should block invalid elements", () => {
505
+ const ast = parse("<InvalidElement>Hello</InvalidElement>");
506
+ const result = analyze(ast, baseSchema);
507
+ expect(result.hasErrors).toBe(true);
508
+ expect(result.errors[0].message).toContain("Element <InvalidElement> not allowed");
509
+ });
510
+ it("should allow nested valid elements", () => {
511
+ const ast = parse(`
514
512
  <div>
515
513
  <Text>Hello</Text>
516
514
  <span>World</span>
517
515
  </div>
518
516
  `);
519
- const result = (0, index_js_1.analyze)(ast, baseSchema);
520
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
517
+ const result = analyze(ast, baseSchema);
518
+ expect(result.hasErrors).toBe(false);
521
519
  });
522
520
  });
523
- (0, vitest_js_1.describe)("spread attributes", () => {
524
- (0, vitest_js_1.it)("should allow spread with data object", () => {
521
+ describe("spread attributes", () => {
522
+ it("should allow spread with data object", () => {
525
523
  const schema = {
526
524
  data: {
527
525
  props: {
@@ -541,11 +539,11 @@ const builtins_js_1 = require("../builtins.js");
541
539
  },
542
540
  },
543
541
  };
544
- const ast = (0, index_js_2.parse)("<Card {...data.props} />");
545
- const result = (0, index_js_1.analyze)(ast, schema);
546
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
542
+ const ast = parse("<Card {...data.props} />");
543
+ const result = analyze(ast, schema);
544
+ expect(result.hasErrors).toBe(false);
547
545
  });
548
- (0, vitest_js_1.it)("should allow spread with nested data object", () => {
546
+ it("should allow spread with nested data object", () => {
549
547
  const schema = {
550
548
  data: {
551
549
  user: {
@@ -570,11 +568,11 @@ const builtins_js_1 = require("../builtins.js");
570
568
  },
571
569
  },
572
570
  };
573
- const ast = (0, index_js_2.parse)("<Text {...data.user.attributes} />");
574
- const result = (0, index_js_1.analyze)(ast, schema);
575
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
571
+ const ast = parse("<Text {...data.user.attributes} />");
572
+ const result = analyze(ast, schema);
573
+ expect(result.hasErrors).toBe(false);
576
574
  });
577
- (0, vitest_js_1.it)("should allow spread with arrow function parameter", () => {
575
+ it("should allow spread with arrow function parameter", () => {
578
576
  const schema = {
579
577
  data: {
580
578
  items: {
@@ -606,11 +604,11 @@ const builtins_js_1 = require("../builtins.js");
606
604
  },
607
605
  },
608
606
  };
609
- const ast = (0, index_js_2.parse)("<div>{data.items.map(item => <Item {...item.props} />)}</div>");
610
- const result = (0, index_js_1.analyze)(ast, schema);
611
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
607
+ const ast = parse("<div>{data.items.map(item => <Item {...item.props} />)}</div>");
608
+ const result = analyze(ast, schema);
609
+ expect(result.hasErrors).toBe(false);
612
610
  });
613
- (0, vitest_js_1.it)("should allow spread with the parameter itself", () => {
611
+ it("should allow spread with the parameter itself", () => {
614
612
  const schema = {
615
613
  data: {
616
614
  items: {
@@ -636,11 +634,11 @@ const builtins_js_1 = require("../builtins.js");
636
634
  },
637
635
  },
638
636
  };
639
- const ast = (0, index_js_2.parse)("<div>{data.items.map(item => <Item {...item} />)}</div>");
640
- const result = (0, index_js_1.analyze)(ast, schema);
641
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
637
+ const ast = parse("<div>{data.items.map(item => <Item {...item} />)}</div>");
638
+ const result = analyze(ast, schema);
639
+ expect(result.hasErrors).toBe(false);
642
640
  });
643
- (0, vitest_js_1.it)("should allow spread combined with regular attributes", () => {
641
+ it("should allow spread combined with regular attributes", () => {
644
642
  const schema = {
645
643
  data: {
646
644
  props: {
@@ -659,11 +657,11 @@ const builtins_js_1 = require("../builtins.js");
659
657
  },
660
658
  },
661
659
  };
662
- const ast = (0, index_js_2.parse)("<Card {...data.props} highlighted={true} />");
663
- const result = (0, index_js_1.analyze)(ast, schema);
664
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
660
+ const ast = parse("<Card {...data.props} highlighted={true} />");
661
+ const result = analyze(ast, schema);
662
+ expect(result.hasErrors).toBe(false);
665
663
  });
666
- (0, vitest_js_1.it)("should allow multiple spreads", () => {
664
+ it("should allow multiple spreads", () => {
667
665
  const schema = {
668
666
  data: {
669
667
  baseProps: {
@@ -688,77 +686,77 @@ const builtins_js_1 = require("../builtins.js");
688
686
  },
689
687
  },
690
688
  };
691
- const ast = (0, index_js_2.parse)("<Card {...data.baseProps} {...data.extraProps} />");
692
- const result = (0, index_js_1.analyze)(ast, schema);
693
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
689
+ const ast = parse("<Card {...data.baseProps} {...data.extraProps} />");
690
+ const result = analyze(ast, schema);
691
+ expect(result.hasErrors).toBe(false);
694
692
  });
695
693
  });
696
- (0, vitest_js_1.describe)("empty expressions", () => {
697
- (0, vitest_js_1.it)("should allow empty JSX expressions {} in children", () => {
698
- const ast = (0, index_js_2.parse)("<Text>{}</Text>");
699
- const result = (0, index_js_1.analyze)(ast, baseSchema);
700
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
701
- });
702
- (0, vitest_js_1.it)("should allow multiple empty expressions in children", () => {
703
- const ast = (0, index_js_2.parse)("<Text>{}{}{}</Text>");
704
- const result = (0, index_js_1.analyze)(ast, baseSchema);
705
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
706
- });
707
- (0, vitest_js_1.it)("should allow empty expressions mixed with content in children", () => {
708
- const ast = (0, index_js_2.parse)("<Text>Hello {}{data.user.name}{} World</Text>");
709
- const result = (0, index_js_1.analyze)(ast, baseSchema);
710
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
711
- });
712
- (0, vitest_js_1.it)("should handle empty expressions without compile errors", () => {
713
- const ast = (0, index_js_2.parse)("<Text>{}</Text>");
714
- const result = (0, index_js_1.analyze)(ast, baseSchema);
715
- (0, vitest_js_1.expect)(result.hasErrors).toBe(false);
716
- (0, vitest_js_1.expect)(ast).toBeDefined();
717
- (0, vitest_js_1.expect)(ast.body).toHaveLength(1);
694
+ describe("empty expressions", () => {
695
+ it("should allow empty JSX expressions {} in children", () => {
696
+ const ast = parse("<Text>{}</Text>");
697
+ const result = analyze(ast, baseSchema);
698
+ expect(result.hasErrors).toBe(false);
699
+ });
700
+ it("should allow multiple empty expressions in children", () => {
701
+ const ast = parse("<Text>{}{}{}</Text>");
702
+ const result = analyze(ast, baseSchema);
703
+ expect(result.hasErrors).toBe(false);
704
+ });
705
+ it("should allow empty expressions mixed with content in children", () => {
706
+ const ast = parse("<Text>Hello {}{data.user.name}{} World</Text>");
707
+ const result = analyze(ast, baseSchema);
708
+ expect(result.hasErrors).toBe(false);
709
+ });
710
+ it("should handle empty expressions without compile errors", () => {
711
+ const ast = parse("<Text>{}</Text>");
712
+ const result = analyze(ast, baseSchema);
713
+ expect(result.hasErrors).toBe(false);
714
+ expect(ast).toBeDefined();
715
+ expect(ast.body).toHaveLength(1);
718
716
  });
719
717
  });
720
718
  });
721
- (0, vitest_js_1.describe)("security validation", () => {
722
- (0, vitest_js_1.describe)("disallowed identifiers", () => {
723
- (0, vitest_js_1.it)("should block window access", () => {
724
- const ast = (0, index_js_2.parse)("<Text>{window.alert('hack')}</Text>");
725
- const result = (0, index_js_1.analyze)(ast, baseSchema);
726
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
727
- (0, vitest_js_1.expect)(result.errors[0].message).toContain('Identifier "window" not allowed');
728
- });
729
- (0, vitest_js_1.it)("should block document access", () => {
730
- const ast = (0, index_js_2.parse)("<Text>{document.body}</Text>");
731
- const result = (0, index_js_1.analyze)(ast, baseSchema);
732
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
733
- (0, vitest_js_1.expect)(result.errors[0].message).toContain('Identifier "document" not allowed');
719
+ describe("security validation", () => {
720
+ describe("disallowed identifiers", () => {
721
+ it("should block window access", () => {
722
+ const ast = parse("<Text>{window.alert('hack')}</Text>");
723
+ const result = analyze(ast, baseSchema);
724
+ expect(result.hasErrors).toBe(true);
725
+ expect(result.errors[0].message).toContain('Identifier "window" not allowed');
726
+ });
727
+ it("should block document access", () => {
728
+ const ast = parse("<Text>{document.body}</Text>");
729
+ const result = analyze(ast, baseSchema);
730
+ expect(result.hasErrors).toBe(true);
731
+ expect(result.errors[0].message).toContain('Identifier "document" not allowed');
734
732
  });
735
733
  });
736
- (0, vitest_js_1.describe)("dangerous expressions", () => {
737
- (0, vitest_js_1.it)("should block eval", () => {
738
- const ast = (0, index_js_2.parse)("<Text>{eval('alert(1)')}</Text>");
739
- const result = (0, index_js_1.analyze)(ast, baseSchema);
740
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
741
- (0, vitest_js_1.expect)(result.errors[0].message).toContain('Identifier "eval" not allowed');
742
- });
743
- (0, vitest_js_1.it)("should block Function constructor", () => {
744
- const ast = (0, index_js_2.parse)("<Text>{new Function('return 1')()}</Text>");
745
- const result = (0, index_js_1.analyze)(ast, baseSchema);
746
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
747
- (0, vitest_js_1.expect)(result.errors[0].message).toContain('Identifier "Function" not allowed');
734
+ describe("dangerous expressions", () => {
735
+ it("should block eval", () => {
736
+ const ast = parse("<Text>{eval('alert(1)')}</Text>");
737
+ const result = analyze(ast, baseSchema);
738
+ expect(result.hasErrors).toBe(true);
739
+ expect(result.errors[0].message).toContain('Identifier "eval" not allowed');
740
+ });
741
+ it("should block Function constructor", () => {
742
+ const ast = parse("<Text>{new Function('return 1')()}</Text>");
743
+ const result = analyze(ast, baseSchema);
744
+ expect(result.hasErrors).toBe(true);
745
+ expect(result.errors[0].message).toContain('Identifier "Function" not allowed');
748
746
  });
749
747
  });
750
748
  });
751
- (0, vitest_js_1.describe)("integration scenarios", () => {
752
- (0, vitest_js_1.it)("should catch multiple errors in complex expressions", () => {
753
- const ast = (0, index_js_2.parse)(`
749
+ describe("integration scenarios", () => {
750
+ it("should catch multiple errors in complex expressions", () => {
751
+ const ast = parse(`
754
752
  <InvalidElement>
755
753
  <Text>{data.user.invalid}</Text>
756
754
  <span>{window.location}</span>
757
755
  </InvalidElement>
758
756
  `);
759
- const result = (0, index_js_1.analyze)(ast, baseSchema);
760
- (0, vitest_js_1.expect)(result.hasErrors).toBe(true);
761
- (0, vitest_js_1.expect)(result.errors.length).toBeGreaterThan(1);
757
+ const result = analyze(ast, baseSchema);
758
+ expect(result.hasErrors).toBe(true);
759
+ expect(result.errors.length).toBeGreaterThan(1);
762
760
  });
763
761
  });
764
762
  });