jsxpression 0.1.41 → 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 (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 +14 -14
  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 +14 -18
  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 +76 -92
  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 +1 -1
  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
@@ -1,57 +1,28 @@
1
1
  import type { Program, Expression, Super } from "acorn";
2
- import { traverse } from "../../traverse.js";
3
2
  import type { Schema } from "../../schema.js";
4
- import type { ValidationContext } from "../validation-context.js";
5
- import { AnalysisReport } from "../analysis-report.js";
3
+ import { traverse } from "../../traverse.js";
4
+ import { createAnalysisReport, type AnalysisReport } from "../analysis-report.js";
6
5
  import { getNodeRange } from "../utils.js";
6
+ import type { ValidationContext } from "../validation-context.js";
7
7
 
8
- export function analyzeExpressions(
9
- ast: Program,
10
- _schema: Schema,
11
- validationContext: ValidationContext
12
- ): AnalysisReport {
13
- const analysisReport = new AnalysisReport();
8
+ export function analyzeExpressions(ast: Program, _schema: Schema, validationContext: ValidationContext): AnalysisReport {
9
+ const analysisReport = createAnalysisReport();
14
10
 
15
11
  traverse(ast, {
16
12
  NewExpression(node) {
17
- analysisReport.addIssue(
18
- "NEW_NOT_ALLOWED",
19
- "new not allowed",
20
- getNodeRange(node),
21
- validationContext.getSnapshot()
22
- );
13
+ analysisReport.addIssue("NEW_NOT_ALLOWED", "new not allowed", getNodeRange(node), validationContext.getSnapshot());
23
14
  },
24
15
  ThisExpression(node) {
25
- analysisReport.addIssue(
26
- "THIS_NOT_ALLOWED",
27
- "this not allowed",
28
- getNodeRange(node),
29
- validationContext.getSnapshot()
30
- );
16
+ analysisReport.addIssue("THIS_NOT_ALLOWED", "this not allowed", getNodeRange(node), validationContext.getSnapshot());
31
17
  },
32
18
  WithStatement(node) {
33
- analysisReport.addIssue(
34
- "WITH_NOT_ALLOWED",
35
- "with not allowed",
36
- getNodeRange(node),
37
- validationContext.getSnapshot()
38
- );
19
+ analysisReport.addIssue("WITH_NOT_ALLOWED", "with not allowed", getNodeRange(node), validationContext.getSnapshot());
39
20
  },
40
21
  AwaitExpression(node) {
41
- analysisReport.addIssue(
42
- "AWAIT_NOT_ALLOWED",
43
- "await not allowed",
44
- getNodeRange(node),
45
- validationContext.getSnapshot()
46
- );
22
+ analysisReport.addIssue("AWAIT_NOT_ALLOWED", "await not allowed", getNodeRange(node), validationContext.getSnapshot());
47
23
  },
48
24
  YieldExpression(node) {
49
- analysisReport.addIssue(
50
- "YIELD_NOT_ALLOWED",
51
- "yield not allowed",
52
- getNodeRange(node),
53
- validationContext.getSnapshot()
54
- );
25
+ analysisReport.addIssue("YIELD_NOT_ALLOWED", "yield not allowed", getNodeRange(node), validationContext.getSnapshot());
55
26
  },
56
27
  ArrowFunctionExpression(node) {
57
28
  if (node.body.type === "BlockStatement") {
@@ -83,12 +54,7 @@ export function analyzeExpressions(
83
54
  currentNode = currentNode.object;
84
55
  }
85
56
  if (depth > 5) {
86
- analysisReport.addIssue(
87
- "MEMBER_CHAIN_TOO_DEEP",
88
- "member chain too deep",
89
- getNodeRange(node),
90
- validationContext.getSnapshot()
91
- );
57
+ analysisReport.addIssue("MEMBER_CHAIN_TOO_DEEP", "member chain too deep", getNodeRange(node), validationContext.getSnapshot());
92
58
  }
93
59
 
94
60
  if (node.computed) {
@@ -101,10 +67,7 @@ export function analyzeExpressions(
101
67
  "computed member access not allowed",
102
68
  getNodeRange(node),
103
69
  validationContext.getSnapshot(),
104
- [
105
- "Use dot notation: obj.prop instead of obj[prop]",
106
- "For arrays, use numeric indices: array[0] instead of array[variable]",
107
- ]
70
+ ["Use dot notation: obj.prop instead of obj[prop]", "For arrays, use numeric indices: array[0] instead of array[variable]"]
108
71
  );
109
72
  }
110
73
  },
@@ -2,12 +2,12 @@ import type { AnyNode, ArrowFunctionExpression, FunctionDeclaration, Identifier,
2
2
  import { getBuiltinGlobals } from "../../builtins.js";
3
3
  import type { Schema } from "../../schema.js";
4
4
  import { traverse } from "../../traverse.js";
5
- import { AnalysisReport } from "../analysis-report.js";
5
+ import { createAnalysisReport, type AnalysisReport } from "../analysis-report.js";
6
6
  import { getNodeRange } from "../utils.js";
7
7
  import type { ValidationContext } from "../validation-context.js";
8
8
 
9
9
  export function analyzeIdentifiers(ast: Program, schema: Schema, validationContext: ValidationContext): AnalysisReport {
10
- const analysisReport = new AnalysisReport();
10
+ const analysisReport = createAnalysisReport();
11
11
  const arrowParamScopes = getArrowParamScopes(ast);
12
12
  const functionParamScopes = getFunctionParamScopes(ast);
13
13
  const functionLocalConsts = getFunctionLocalConsts(ast);
@@ -36,14 +36,7 @@ export function analyzeIdentifiers(ast: Program, schema: Schema, validationConte
36
36
  }
37
37
 
38
38
  const dataKeys = Object.keys(schema.data ?? {});
39
- const allowedRoots = [
40
- "props",
41
- ...dataKeys,
42
- ...getBuiltinGlobals(),
43
- ...constNames,
44
- ...functionNames,
45
- ...schemaFunctionNames,
46
- ];
39
+ const allowedRoots = ["props", ...dataKeys, ...getBuiltinGlobals(), ...constNames, ...functionNames, ...schemaFunctionNames];
47
40
 
48
41
  if (allowedRoots.includes(name)) {
49
42
  return;
@@ -52,10 +45,7 @@ export function analyzeIdentifiers(ast: Program, schema: Schema, validationConte
52
45
  const scopeParent = findScopeParent(node, ast);
53
46
 
54
47
  if (scopeParent) {
55
- const params =
56
- scopeParent.type === "ArrowFunctionExpression"
57
- ? arrowParamScopes.get(scopeParent)
58
- : functionParamScopes.get(scopeParent);
48
+ const params = scopeParent.type === "ArrowFunctionExpression" ? arrowParamScopes.get(scopeParent) : functionParamScopes.get(scopeParent);
59
49
  if (params?.has(name)) {
60
50
  return;
61
51
  }
@@ -141,7 +131,7 @@ function collectParamNames(param: AnyNode, names: Set<string>): void {
141
131
  names.add(param.name);
142
132
  break;
143
133
  case "ObjectPattern":
144
- for (const prop of (param as any).properties) {
134
+ for (const prop of param.properties) {
145
135
  if (prop.type === "RestElement") {
146
136
  collectParamNames(prop.argument, names);
147
137
  } else {
@@ -150,21 +140,25 @@ function collectParamNames(param: AnyNode, names: Set<string>): void {
150
140
  }
151
141
  break;
152
142
  case "ArrayPattern":
153
- for (const el of (param as any).elements) {
154
- if (el) collectParamNames(el, names);
143
+ for (const el of param.elements) {
144
+ if (el) {
145
+ collectParamNames(el, names);
146
+ }
155
147
  }
156
148
  break;
157
149
  case "AssignmentPattern":
158
- collectParamNames((param as any).left, names);
150
+ collectParamNames(param.left, names);
159
151
  break;
160
152
  case "RestElement":
161
- collectParamNames((param as any).argument, names);
153
+ collectParamNames(param.argument, names);
154
+ break;
155
+ default:
162
156
  break;
163
157
  }
164
158
  }
165
159
 
166
- function getTopLevelConstNames(ast: Program): string[] {
167
- const names: string[] = [];
160
+ function getTopLevelConstNames(ast: Program): Array<string> {
161
+ const names: Array<string> = [];
168
162
  for (const stmt of ast.body) {
169
163
  if (stmt.type === "VariableDeclaration" && stmt.kind === "const") {
170
164
  for (const decl of stmt.declarations) {
@@ -177,8 +171,8 @@ function getTopLevelConstNames(ast: Program): string[] {
177
171
  return names;
178
172
  }
179
173
 
180
- function getTopLevelFunctionNames(ast: Program): string[] {
181
- const names: string[] = [];
174
+ function getTopLevelFunctionNames(ast: Program): Array<string> {
175
+ const names: Array<string> = [];
182
176
  for (const stmt of ast.body) {
183
177
  if (stmt.type === "FunctionDeclaration" && stmt.id) {
184
178
  names.push(stmt.id.name);
@@ -201,17 +195,18 @@ function findScopeParent(targetNode: AnyNode, rootNode: AnyNode): ArrowFunctionE
201
195
  found = node as ArrowFunctionExpression | FunctionDeclaration;
202
196
  }
203
197
 
204
- for (const key of Object.keys(node)) {
205
- const value = (node as any)[key];
198
+ const record = node as unknown as Record<string, unknown>;
199
+ for (const key of Object.keys(record)) {
200
+ const value = record[key];
206
201
 
207
202
  if (value && typeof value === "object") {
208
203
  if (Array.isArray(value)) {
209
204
  for (const item of value) {
210
- if (item && typeof item === "object" && walk(item)) {
205
+ if (item && typeof item === "object" && walk(item as AnyNode)) {
211
206
  return true;
212
207
  }
213
208
  }
214
- } else if (walk(value)) {
209
+ } else if (walk(value as AnyNode)) {
215
210
  return true;
216
211
  }
217
212
  }
@@ -228,25 +223,28 @@ function findScopeParent(targetNode: AnyNode, rootNode: AnyNode): ArrowFunctionE
228
223
  return found;
229
224
  }
230
225
 
231
- function buildParentMap(ast: Program): Map<any, any> {
232
- const parentMap = new Map<any, any>();
226
+ function buildParentMap(ast: Program): Map<AnyNode, AnyNode | null> {
227
+ const parentMap = new Map<AnyNode, AnyNode | null>();
233
228
 
234
- function visit(node: any, parent: any): void {
235
- if (!node || typeof node !== "object") return;
236
- if (node.type) {
237
- parentMap.set(node, parent);
229
+ function visit(node: unknown, parent: AnyNode | null): void {
230
+ if (!node || typeof node !== "object") {
231
+ return;
232
+ }
233
+ const record = node as Record<string, unknown>;
234
+ if (record["type"]) {
235
+ parentMap.set(node as AnyNode, parent);
238
236
  }
239
- for (const key of Object.keys(node)) {
240
- const value = node[key];
237
+ for (const key of Object.keys(record)) {
238
+ const value = record[key];
241
239
  if (value && typeof value === "object") {
242
240
  if (Array.isArray(value)) {
243
241
  for (const child of value) {
244
- if (child && typeof child === "object" && child.type) {
245
- visit(child, node);
242
+ if (child && typeof child === "object" && (child as Record<string, unknown>)["type"]) {
243
+ visit(child, node as AnyNode);
246
244
  }
247
245
  }
248
- } else if (value.type) {
249
- visit(value, node);
246
+ } else if ((value as Record<string, unknown>)["type"]) {
247
+ visit(value, node as AnyNode);
250
248
  }
251
249
  }
252
250
  }
@@ -1,3 +1,5 @@
1
+ import type { Node } from "acorn";
2
+
1
3
  export interface RangePosition {
2
4
  line: number;
3
5
  column: number;
@@ -8,7 +10,8 @@ export interface Range {
8
10
  end: RangePosition;
9
11
  }
10
12
 
11
- export function getNodeRange(node: any): Range {
13
+ export function getNodeRange(nodeParam: unknown): Range {
14
+ const node = nodeParam as Node;
12
15
  if (node.loc) {
13
16
  return {
14
17
  start: {
@@ -34,15 +37,15 @@ export function getNodeRange(node: any): Range {
34
37
  };
35
38
  }
36
39
 
37
- export function getElementSimilarityMatchers(invalid: string, available: string[]): SimilarityMatcher[] {
40
+ export function getElementSimilarityMatchers(invalid: string, available: Array<string>): Array<SimilarityMatcher> {
38
41
  return getSimilarityMatchers(invalid, available, "element");
39
42
  }
40
43
 
41
- export function getAttributeSimilarityMatchers(invalid: string, available: string[]): SimilarityMatcher[] {
44
+ export function getAttributeSimilarityMatchers(invalid: string, available: Array<string>): Array<SimilarityMatcher> {
42
45
  return getSimilarityMatchers(invalid, available, "attribute");
43
46
  }
44
47
 
45
- export function getBestSimilarityMatcherSuggestion(invalid: string, available: string[]): string | null {
48
+ export function getBestSimilarityMatcherSuggestion(invalid: string, available: Array<string>): string | null {
46
49
  const similarityMatchers = getElementSimilarityMatchers(invalid, available);
47
50
 
48
51
  if (similarityMatchers.length === 0) {
@@ -66,24 +69,27 @@ interface SimilarityMatcher {
66
69
  type: SimilarityMatcherType;
67
70
  }
68
71
 
69
- function getSimilarityMatchers(invalid: string, available: string[], type: SimilarityMatcherType): SimilarityMatcher[] {
72
+ function getSimilarityMatchers(invalid: string, available: Array<string>, type: SimilarityMatcherType): Array<SimilarityMatcher> {
70
73
  if (available.length === 0) {
71
74
  return [];
72
75
  }
73
76
 
74
- return available
75
- .map((suggestion) => ({
76
- suggestion,
77
- distance: levenshteinDistance(invalid.toLowerCase(), suggestion.toLowerCase()),
78
- type,
79
- }))
80
- .filter((similarityMatcher) => similarityMatcher.distance <= Math.max(2, Math.floor(invalid.length * 0.4)))
81
- .sort((a, b) => a.distance - b.distance)
82
- .slice(0, 3)
83
- .map((similarityMatcher) => ({
84
- ...similarityMatcher,
85
- confidence: 1 - similarityMatcher.distance / Math.max(invalid.length, similarityMatcher.suggestion.length),
86
- }));
77
+ return (
78
+ available
79
+ .map((suggestion) => ({
80
+ suggestion,
81
+ distance: levenshteinDistance(invalid.toLowerCase(), suggestion.toLowerCase()),
82
+ type,
83
+ }))
84
+ .filter((similarityMatcher) => similarityMatcher.distance <= Math.max(2, Math.floor(invalid.length * 0.4)))
85
+ // oxlint-disable-next-line unicorn/no-array-sort
86
+ .sort((a, b) => a.distance - b.distance)
87
+ .slice(0, 3)
88
+ .map((similarityMatcher) => ({
89
+ ...similarityMatcher,
90
+ confidence: 1 - similarityMatcher.distance / Math.max(invalid.length, similarityMatcher.suggestion.length),
91
+ }))
92
+ );
87
93
  }
88
94
 
89
95
  function levenshteinDistance(x: string, y: string): number {
@@ -94,7 +100,7 @@ function levenshteinDistance(x: string, y: string): number {
94
100
  return x.length;
95
101
  }
96
102
 
97
- const matrix: number[][] = [];
103
+ const matrix: Array<Array<number>> = [];
98
104
 
99
105
  for (let i = 0; i <= y.length; i++) {
100
106
  matrix[i] = [i];
@@ -1,32 +1,41 @@
1
1
  export interface ValidationContextSnapshot {
2
- elements: string[];
2
+ elements: Array<string>;
3
3
  currentElement?: string;
4
- parentElements: string[];
4
+ parentElements: Array<string>;
5
5
  }
6
6
 
7
- export class ValidationContext {
8
- #elements: string[] = [];
7
+ export interface ValidationContext {
8
+ readonly currentPath: string;
9
+ enterElement: (element: string) => void;
10
+ exitElement: () => void;
11
+ getSnapshot: () => ValidationContextSnapshot;
12
+ }
13
+
14
+ export function createValidationContext(): ValidationContext {
15
+ const elements: Array<string> = [];
9
16
 
10
- get currentPath(): string {
11
- if (this.#elements.length > 0) {
12
- return this.#elements.join(" > ");
13
- }
14
- return "";
15
- }
17
+ return {
18
+ get currentPath(): string {
19
+ if (elements.length > 0) {
20
+ return elements.join(" > ");
21
+ }
22
+ return "";
23
+ },
16
24
 
17
- enterElement(element: string): void {
18
- this.#elements.push(element);
19
- }
25
+ enterElement(element: string): void {
26
+ elements.push(element);
27
+ },
20
28
 
21
- exitElement(): void {
22
- this.#elements.pop();
23
- }
29
+ exitElement(): void {
30
+ elements.pop();
31
+ },
24
32
 
25
- getSnapshot(): ValidationContextSnapshot {
26
- return {
27
- elements: this.#elements.slice(),
28
- currentElement: this.#elements[this.#elements.length - 1],
29
- parentElements: this.#elements.slice(0, -1),
30
- };
31
- }
33
+ getSnapshot(): ValidationContextSnapshot {
34
+ return {
35
+ elements: elements.slice(),
36
+ currentElement: elements[elements.length - 1],
37
+ parentElements: elements.slice(0, -1),
38
+ };
39
+ },
40
+ };
32
41
  }
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