jsxpression 0.1.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.
- package/LICENSE +21 -0
- package/README.md +368 -0
- package/lib/analyze/analysis-error.d.ts.map +1 -0
- package/lib/analyze/analysis-report.d.ts +33 -0
- package/lib/analyze/analysis-report.d.ts.map +1 -0
- package/lib/analyze/analysis-report.js +194 -0
- package/lib/analyze/analysis-report.js.map +1 -0
- package/lib/analyze/analyze.d.ts.map +1 -0
- package/lib/analyze/analyze.test.d.ts.map +1 -0
- package/lib/analyze/analyze.test.js +765 -0
- package/lib/analyze/analyze.test.js.map +1 -0
- package/lib/analyze/data/analyze.d.ts.map +1 -0
- package/lib/analyze/data/data-access.d.ts.map +1 -0
- package/lib/analyze/data/index.d.ts.map +1 -0
- package/lib/analyze/data/method-calls.d.ts.map +1 -0
- package/lib/analyze/data/utils.d.ts.map +1 -0
- package/lib/analyze/index.d.ts.map +1 -0
- package/lib/analyze/jsx/analyze.d.ts.map +1 -0
- package/lib/analyze/jsx/element-attributes.d.ts.map +1 -0
- package/lib/analyze/jsx/element-attributes.js +89 -0
- package/lib/analyze/jsx/element-attributes.js.map +1 -0
- package/lib/analyze/jsx/element-children.d.ts.map +1 -0
- package/lib/analyze/jsx/element-tags.d.ts.map +1 -0
- package/lib/analyze/jsx/index.d.ts.map +1 -0
- package/lib/analyze/security/analyze.d.ts.map +1 -0
- package/lib/analyze/security/call-expressions.d.ts.map +1 -0
- package/lib/analyze/security/declarations.d.ts.map +1 -0
- package/lib/analyze/security/expressions.d.ts.map +1 -0
- package/lib/analyze/security/identifiers.d.ts.map +1 -0
- package/lib/analyze/security/index.d.ts.map +1 -0
- package/lib/analyze/security/member-access.d.ts.map +1 -0
- package/lib/builtins.d.ts +50 -0
- package/lib/builtins.d.ts.map +1 -0
- package/lib/builtins.js +1065 -0
- package/lib/builtins.js.map +1 -0
- package/lib/codegen/builtin-types.d.ts +11 -0
- package/lib/codegen/builtin-types.d.ts.map +1 -0
- package/lib/codegen/builtin-types.js +151 -0
- package/lib/codegen/builtin-types.js.map +1 -0
- package/lib/codegen/builtins/builtin-types.d.ts +2 -0
- package/lib/codegen/builtins/builtin-types.d.ts.map +1 -0
- package/lib/codegen/builtins/builtin-types.js +143 -0
- package/lib/codegen/builtins/builtin-types.js.map +1 -0
- package/lib/codegen/builtins/index.d.ts +2 -0
- package/lib/codegen/builtins/index.d.ts.map +1 -0
- package/lib/codegen/builtins/index.js +6 -0
- package/lib/codegen/builtins/index.js.map +1 -0
- package/lib/codegen/declare-types.d.ts +20 -0
- package/lib/codegen/declare-types.d.ts.map +1 -0
- package/lib/codegen/declare-types.js +299 -0
- package/lib/codegen/declare-types.js.map +1 -0
- package/lib/codegen/generate-typescript-definitions.d.ts +31 -0
- package/lib/codegen/generate-typescript-definitions.d.ts.map +1 -0
- package/lib/codegen/generate-typescript-definitions.js +37 -0
- package/lib/codegen/generate-typescript-definitions.js.map +1 -0
- package/lib/codegen/generate-typescript-definitions.test.d.ts +2 -0
- package/lib/codegen/generate-typescript-definitions.test.d.ts.map +1 -0
- package/lib/codegen/generate-typescript-definitions.test.js +587 -0
- package/lib/codegen/generate-typescript-definitions.test.js.map +1 -0
- package/lib/codegen/index.d.ts +2 -0
- package/lib/codegen/index.d.ts.map +1 -0
- package/lib/codegen/index.js +6 -0
- package/lib/codegen/index.js.map +1 -0
- package/lib/codegen/schema/component-types.d.ts +3 -0
- package/lib/codegen/schema/component-types.d.ts.map +1 -0
- package/lib/codegen/schema/component-types.js +118 -0
- package/lib/codegen/schema/component-types.js.map +1 -0
- package/lib/codegen/schema/data-types.d.ts +3 -0
- package/lib/codegen/schema/data-types.d.ts.map +1 -0
- package/lib/codegen/schema/data-types.js +98 -0
- package/lib/codegen/schema/data-types.js.map +1 -0
- package/lib/codegen/schema/index.d.ts +3 -0
- package/lib/codegen/schema/index.d.ts.map +1 -0
- package/lib/codegen/schema/index.js +8 -0
- package/lib/codegen/schema/index.js.map +1 -0
- package/lib/codegen/schema/utils.d.ts +4 -0
- package/lib/codegen/schema/utils.d.ts.map +1 -0
- package/lib/codegen/schema/utils.js +103 -0
- package/lib/codegen/schema/utils.js.map +1 -0
- package/lib/codegen/schema-to-types.d.ts +14 -0
- package/lib/codegen/schema-to-types.d.ts.map +1 -0
- package/lib/codegen/schema-to-types.js +203 -0
- package/lib/codegen/schema-to-types.js.map +1 -0
- package/lib/compile/compile.d.ts.map +1 -0
- package/lib/compile/compile.js +245 -0
- package/lib/compile/compile.js.map +1 -0
- package/lib/compile/compile.test.d.ts.map +1 -0
- package/lib/compile/compile.test.js +148 -0
- package/lib/compile/compile.test.js.map +1 -0
- package/lib/evaluate/evaluate.d.ts +26 -0
- package/lib/evaluate/evaluate.d.ts.map +1 -0
- package/lib/evaluate/evaluate.js +40 -0
- package/lib/evaluate/evaluation-error.d.ts +4 -0
- package/lib/evaluate/evaluation-error.d.ts.map +1 -0
- package/lib/evaluate/evaluation-error.js +6 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +16 -0
- package/lib/index.js.map +1 -0
- package/lib/render.d.ts +58 -0
- package/lib/render.d.ts.map +1 -0
- package/lib/render.js +52 -0
- package/lib/render.test.d.ts.map +1 -0
- package/lib/schema.d.ts +68 -0
- package/lib/schema.d.ts.map +1 -0
- package/lib/schema.js +106 -0
- package/lib/validate.d.ts +41 -0
- package/lib/validate.d.ts.map +1 -0
- package/lib/validate.js +42 -0
- package/package.json +27 -0
- package/src/analyze/analysis-error.ts +26 -0
- package/src/analyze/analysis-report.ts +228 -0
- package/src/analyze/analyze.test.ts +829 -0
- package/src/analyze/analyze.ts +10 -0
- package/src/analyze/data/analyze.ts +15 -0
- package/src/analyze/data/data-access.ts +349 -0
- package/src/analyze/data/index.ts +1 -0
- package/src/analyze/data/method-calls.ts +96 -0
- package/src/analyze/data/utils.ts +329 -0
- package/src/analyze/index.ts +3 -0
- package/src/analyze/jsx/analyze.ts +17 -0
- package/src/analyze/jsx/element-attributes.ts +143 -0
- package/src/analyze/jsx/element-children.ts +97 -0
- package/src/analyze/jsx/element-tags.ts +55 -0
- package/src/analyze/jsx/index.ts +1 -0
- package/src/analyze/security/analyze.ts +21 -0
- package/src/analyze/security/call-expressions.ts +41 -0
- package/src/analyze/security/declarations.ts +67 -0
- package/src/analyze/security/expressions.ts +100 -0
- package/src/analyze/security/identifiers.ts +113 -0
- package/src/analyze/security/index.ts +1 -0
- package/src/analyze/security/member-access.ts +35 -0
- package/src/analyze/utils.ts +118 -0
- package/src/analyze/validation-context.ts +32 -0
- package/src/builtins.ts +1149 -0
- package/src/codegen/builtins/builtin-types.ts +174 -0
- package/src/codegen/builtins/index.ts +1 -0
- package/src/codegen/generate-typescript-definitions.test.ts +676 -0
- package/src/codegen/generate-typescript-definitions.ts +35 -0
- package/src/codegen/index.ts +1 -0
- package/src/codegen/schema/component-types.ts +140 -0
- package/src/codegen/schema/data-types.ts +109 -0
- package/src/codegen/schema/index.ts +2 -0
- package/src/codegen/schema/utils.ts +111 -0
- package/src/compile/compilation-error.ts +37 -0
- package/src/compile/compile.test.ts +180 -0
- package/src/compile/compile.ts +282 -0
- package/src/compile/index.ts +2 -0
- package/src/evaluate/evaluate.test.ts +316 -0
- package/src/evaluate/evaluate.ts +81 -0
- package/src/evaluate/evaluation-error.ts +6 -0
- package/src/evaluate/index.ts +2 -0
- package/src/index.ts +10 -0
- package/src/jsx.ts +161 -0
- package/src/parse/index.ts +2 -0
- package/src/parse/parse-error.ts +14 -0
- package/src/parse/parse.test.ts +99 -0
- package/src/parse/parse.ts +40 -0
- package/src/render.test.ts +425 -0
- package/src/render.ts +75 -0
- package/src/schema.ts +195 -0
- package/src/traverse.test.ts +104 -0
- package/src/traverse.ts +78 -0
- package/src/types.ts +17 -0
- package/src/validate.ts +59 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compile = compile;
|
|
4
|
+
const jsx_1 = require("../jsx");
|
|
5
|
+
const compilation_error_1 = require("./compilation-error");
|
|
6
|
+
function compile(ast) {
|
|
7
|
+
const root = getRoot(ast);
|
|
8
|
+
const code = emitJsxRoot(root);
|
|
9
|
+
return `"use strict";return ${code};`;
|
|
10
|
+
}
|
|
11
|
+
function getRoot(ast) {
|
|
12
|
+
for (const declaration of ast.body) {
|
|
13
|
+
if (declaration.type === "ExpressionStatement" && (0, jsx_1.isJsxRoot)(declaration.expression)) {
|
|
14
|
+
return declaration.expression;
|
|
15
|
+
}
|
|
16
|
+
if (declaration.type === "ReturnStatement" && declaration.argument && (0, jsx_1.isJsxRoot)(declaration.argument)) {
|
|
17
|
+
return declaration.argument;
|
|
18
|
+
}
|
|
19
|
+
// Handle bare expressions like {data.user.name} which parse as BlockStatement
|
|
20
|
+
if (declaration.type === "BlockStatement" && declaration.body.length === 1) {
|
|
21
|
+
const innerStatement = declaration.body[0];
|
|
22
|
+
if (innerStatement.type === "ExpressionStatement") {
|
|
23
|
+
// Create a synthetic JSXExpressionContainer for the bare expression
|
|
24
|
+
const syntheticContainer = {
|
|
25
|
+
type: "JSXExpressionContainer",
|
|
26
|
+
expression: innerStatement.expression,
|
|
27
|
+
};
|
|
28
|
+
return syntheticContainer;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
throw compilation_error_1.CompilationError.fromNode("No root JSX element/fragment/expression found", ast);
|
|
33
|
+
}
|
|
34
|
+
function emitJsxRoot(node) {
|
|
35
|
+
if ((0, jsx_1.isJsxElement)(node)) {
|
|
36
|
+
return emitJsxElement(node);
|
|
37
|
+
}
|
|
38
|
+
if ((0, jsx_1.isJsxFragment)(node)) {
|
|
39
|
+
return emitJsxFragment(node);
|
|
40
|
+
}
|
|
41
|
+
// Handle bare expression containers like {data.user.name}
|
|
42
|
+
return emitExpression(node.expression);
|
|
43
|
+
}
|
|
44
|
+
function emitJsxElement(node) {
|
|
45
|
+
const name = emitJsxName(node.openingElement.name);
|
|
46
|
+
const attributes = emitAttributes(node.openingElement.attributes);
|
|
47
|
+
const children = emitJsxChildren(node.children);
|
|
48
|
+
if (children.length > 0) {
|
|
49
|
+
return `h(${name}, ${attributes}, ${children.join(", ")})`;
|
|
50
|
+
}
|
|
51
|
+
return `h(${name}, ${attributes})`;
|
|
52
|
+
}
|
|
53
|
+
function emitJsxFragment(node) {
|
|
54
|
+
const children = emitJsxChildren(node.children);
|
|
55
|
+
return `[${children.join(", ")}]`;
|
|
56
|
+
}
|
|
57
|
+
function emitJsxName(nameNode) {
|
|
58
|
+
switch (nameNode.type) {
|
|
59
|
+
case "JSXIdentifier":
|
|
60
|
+
return JSON.stringify(nameNode.name);
|
|
61
|
+
case "JSXMemberExpression": {
|
|
62
|
+
const left = emitJsxName(nameNode.object);
|
|
63
|
+
const right = emitJsxName(nameNode.property);
|
|
64
|
+
return JSON.stringify(JSON.parse(left) + "." + JSON.parse(right));
|
|
65
|
+
}
|
|
66
|
+
default:
|
|
67
|
+
throw compilation_error_1.CompilationError.fromNode(`Unsupported JSX name: ${nameNode.type}`, nameNode);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function emitAttributes(attributes) {
|
|
71
|
+
const parts = [];
|
|
72
|
+
let currentObj = [];
|
|
73
|
+
const flushCurrent = () => {
|
|
74
|
+
if (currentObj.length) {
|
|
75
|
+
parts.push(`{ ${currentObj.join(", ")} }`);
|
|
76
|
+
currentObj = [];
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
for (const attribute of attributes) {
|
|
80
|
+
if (attribute.type === "JSXSpreadAttribute") {
|
|
81
|
+
flushCurrent();
|
|
82
|
+
parts.push(`(${emitExpression(attribute.argument)})`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (attribute.type !== "JSXAttribute") {
|
|
86
|
+
throw compilation_error_1.CompilationError.fromNode("Only simple JSX attributes allowed", attribute);
|
|
87
|
+
}
|
|
88
|
+
const key = attribute.name?.name;
|
|
89
|
+
let value;
|
|
90
|
+
if (!attribute.value) {
|
|
91
|
+
value = "true";
|
|
92
|
+
}
|
|
93
|
+
else if (attribute.value.type === "Literal") {
|
|
94
|
+
value = JSON.stringify(attribute.value.value);
|
|
95
|
+
}
|
|
96
|
+
else if (attribute.value.type === "JSXExpressionContainer") {
|
|
97
|
+
value = emitExpression(attribute.value.expression);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
throw compilation_error_1.CompilationError.fromNode("Unsupported attribute value", attribute.value);
|
|
101
|
+
}
|
|
102
|
+
currentObj.push(`${key}: ${value}`);
|
|
103
|
+
}
|
|
104
|
+
flushCurrent();
|
|
105
|
+
if (parts.length === 0) {
|
|
106
|
+
return "null";
|
|
107
|
+
}
|
|
108
|
+
if (parts.length === 1) {
|
|
109
|
+
return parts[0];
|
|
110
|
+
}
|
|
111
|
+
return `Object.assign({}, ${parts.join(", ")})`;
|
|
112
|
+
}
|
|
113
|
+
function emitJsxChildren(children) {
|
|
114
|
+
const result = [];
|
|
115
|
+
for (const child of children) {
|
|
116
|
+
if ((0, jsx_1.isJsxText)(child)) {
|
|
117
|
+
const text = normalizeJsxText(child.value);
|
|
118
|
+
if (text) {
|
|
119
|
+
result.push(JSON.stringify(text));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if ((0, jsx_1.isJsxExpressionContainer)(child)) {
|
|
123
|
+
// Skip empty expressions {} - they don't contribute any content
|
|
124
|
+
if (!(0, jsx_1.isJsxEmptyExpression)(child.expression)) {
|
|
125
|
+
result.push(emitExpression(child.expression));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else if ((0, jsx_1.isJsxElement)(child)) {
|
|
129
|
+
result.push(emitJsxElement(child));
|
|
130
|
+
}
|
|
131
|
+
else if ((0, jsx_1.isJsxFragment)(child)) {
|
|
132
|
+
result.push(emitJsxFragment(child));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
const TRAILING_PLUS_RX = /\+\s*\+\s*$/;
|
|
138
|
+
function emitExpression(node) {
|
|
139
|
+
switch (node.type) {
|
|
140
|
+
case "Literal":
|
|
141
|
+
return JSON.stringify(node.value);
|
|
142
|
+
case "Identifier":
|
|
143
|
+
return node.name;
|
|
144
|
+
case "TemplateLiteral": {
|
|
145
|
+
const bits = [];
|
|
146
|
+
node.quasis.forEach((quasi, index) => {
|
|
147
|
+
bits.push(JSON.stringify(quasi.value.cooked ?? ""));
|
|
148
|
+
if (node.expressions.length > index) {
|
|
149
|
+
bits.push(`+(${emitExpression(node.expressions[index])})+`);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
return bits.join("").replace(TRAILING_PLUS_RX, "") || '""';
|
|
153
|
+
}
|
|
154
|
+
case "ParenthesizedExpression":
|
|
155
|
+
return `(${emitExpression(node.expression)})`;
|
|
156
|
+
case "UnaryExpression":
|
|
157
|
+
return `${node.operator}${emitExpression(node.argument)}`;
|
|
158
|
+
case "BinaryExpression":
|
|
159
|
+
case "LogicalExpression":
|
|
160
|
+
return `(${emitExpression(node.left)} ${node.operator} ${emitExpression(node.right)})`;
|
|
161
|
+
case "ConditionalExpression":
|
|
162
|
+
return `(${emitExpression(node.test)}?${emitExpression(node.consequent)}:${emitExpression(node.alternate)})`;
|
|
163
|
+
case "ArrayExpression":
|
|
164
|
+
return `[${node.elements
|
|
165
|
+
.map((element) => {
|
|
166
|
+
if (!element) {
|
|
167
|
+
return "undefined";
|
|
168
|
+
}
|
|
169
|
+
if (element.type === "SpreadElement") {
|
|
170
|
+
return `...${emitExpression(element.argument)}`;
|
|
171
|
+
}
|
|
172
|
+
return emitExpression(element);
|
|
173
|
+
})
|
|
174
|
+
.join(", ")}]`;
|
|
175
|
+
case "ObjectExpression": {
|
|
176
|
+
const keyValuePairs = node.properties
|
|
177
|
+
.map((property) => {
|
|
178
|
+
if (property.type === "SpreadElement") {
|
|
179
|
+
return `...${emitExpression(property.argument)}`;
|
|
180
|
+
}
|
|
181
|
+
// analyze() ensures these are simple properties
|
|
182
|
+
const prop = property; // analyze() guarantees Property type
|
|
183
|
+
const key = getAstKeyString(prop.key);
|
|
184
|
+
return `${key}: ${emitExpression(prop.value)}`;
|
|
185
|
+
})
|
|
186
|
+
.join(", ");
|
|
187
|
+
return `{ ${keyValuePairs} }`;
|
|
188
|
+
}
|
|
189
|
+
case "MemberExpression": {
|
|
190
|
+
const obj = emitExpression(node.object);
|
|
191
|
+
let prop;
|
|
192
|
+
if (node.computed) {
|
|
193
|
+
prop = `[${emitExpression(node.property)}]`;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
prop = `.${getAstKeyString(node.property)}`;
|
|
197
|
+
}
|
|
198
|
+
return `${obj}${prop}`;
|
|
199
|
+
}
|
|
200
|
+
case "CallExpression": {
|
|
201
|
+
const callee = emitExpression(node.callee);
|
|
202
|
+
const args = node.arguments
|
|
203
|
+
.map((argument) => {
|
|
204
|
+
if (argument.type === "SpreadElement") {
|
|
205
|
+
return `...${emitExpression(argument.argument)}`;
|
|
206
|
+
}
|
|
207
|
+
return emitExpression(argument);
|
|
208
|
+
})
|
|
209
|
+
.join(", ");
|
|
210
|
+
return `${callee}(${args})`;
|
|
211
|
+
}
|
|
212
|
+
case "ArrowFunctionExpression": {
|
|
213
|
+
const params = node.params.map((param) => emitExpression(param)).join(", ");
|
|
214
|
+
// analyze() ensures this is not a BlockStatement
|
|
215
|
+
const body = emitExpression(node.body);
|
|
216
|
+
return `(${params}) => ${body}`;
|
|
217
|
+
}
|
|
218
|
+
case "JSXElement":
|
|
219
|
+
return emitJsxElement(node);
|
|
220
|
+
case "JSXFragment":
|
|
221
|
+
return emitJsxFragment(node);
|
|
222
|
+
case "JSXEmptyExpression":
|
|
223
|
+
return "null";
|
|
224
|
+
default:
|
|
225
|
+
throw compilation_error_1.CompilationError.fromNode(`Unsupported expression: ${node?.type}`, node);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function getAstKeyString(node) {
|
|
229
|
+
if (node.type === "Identifier") {
|
|
230
|
+
return node.name;
|
|
231
|
+
}
|
|
232
|
+
else if (node.type === "Literal") {
|
|
233
|
+
return JSON.stringify(node.value);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
// This should never happen due to type constraints but
|
|
237
|
+
// if JSX ever changes this could be possible!
|
|
238
|
+
throw compilation_error_1.CompilationError.fromNode("Unsupported key type", node);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const WHITESPACE_COLLAPSER_RX = /\s+/g;
|
|
242
|
+
function normalizeJsxText(value) {
|
|
243
|
+
return value.replace(WHITESPACE_COLLAPSER_RX, " ").trim();
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/compile/compile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.test.d.ts","sourceRoot":"","sources":["../../src/compile/compile.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const compile_1 = require("../compile");
|
|
5
|
+
const parse_1 = require("../parse");
|
|
6
|
+
(0, vitest_1.describe)("compile", () => {
|
|
7
|
+
(0, vitest_1.it)("should compile ternary expression", () => {
|
|
8
|
+
const ast = (0, parse_1.parse)("<div>{props.show ? 'Yes' : 'No'}</div>");
|
|
9
|
+
const result = (0, compile_1.compile)(ast);
|
|
10
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, (props.show?"Yes":"No"));');
|
|
11
|
+
});
|
|
12
|
+
(0, vitest_1.it)("should compile logical OR expression", () => {
|
|
13
|
+
const ast = (0, parse_1.parse)("<div>{props.value || 'default'}</div>");
|
|
14
|
+
const result = (0, compile_1.compile)(ast);
|
|
15
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, (props.value || "default"));');
|
|
16
|
+
});
|
|
17
|
+
(0, vitest_1.it)("should compile array operations", () => {
|
|
18
|
+
const ast = (0, parse_1.parse)("<div>{props.items.filter(x => x.length > 2).join(', ')}</div>");
|
|
19
|
+
const result = (0, compile_1.compile)(ast);
|
|
20
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, props.items.filter((x) => (x.length > 2)).join(", "));');
|
|
21
|
+
});
|
|
22
|
+
(0, vitest_1.it)("should compile object literals in props", () => {
|
|
23
|
+
const ast = (0, parse_1.parse)("<div style={{ color: 'red' }}>Text</div>");
|
|
24
|
+
const result = (0, compile_1.compile)(ast);
|
|
25
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", { style: { color: "red" } }, "Text");');
|
|
26
|
+
});
|
|
27
|
+
(0, vitest_1.it)("should compile nested ternary expressions", () => {
|
|
28
|
+
const ast = (0, parse_1.parse)("<div>{props.level > 2 ? 'high' : props.level > 1 ? 'medium' : 'low'}</div>");
|
|
29
|
+
const result = (0, compile_1.compile)(ast);
|
|
30
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, ((props.level > 2)?"high":((props.level > 1)?"medium":"low")));');
|
|
31
|
+
});
|
|
32
|
+
(0, vitest_1.it)("should compile nested JSX elements", () => {
|
|
33
|
+
const ast = (0, parse_1.parse)("<div><span><strong>Nested</strong></span></div>");
|
|
34
|
+
const result = (0, compile_1.compile)(ast);
|
|
35
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, h("span", null, h("strong", null, "Nested")));');
|
|
36
|
+
});
|
|
37
|
+
(0, vitest_1.it)("should compile nested array operations", () => {
|
|
38
|
+
const ast = (0, parse_1.parse)("<div>{props.items.map(x => x.split(',').map(y => y.trim()).join(' ')).join(' | ')}</div>");
|
|
39
|
+
const result = (0, compile_1.compile)(ast);
|
|
40
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, props.items.map((x) => x.split(",").map((y) => y.trim()).join(" ")).join(" | "));');
|
|
41
|
+
});
|
|
42
|
+
(0, vitest_1.it)("should compile bare expression containers", () => {
|
|
43
|
+
const ast = (0, parse_1.parse)("{data.user.name}");
|
|
44
|
+
const result = (0, compile_1.compile)(ast);
|
|
45
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return data.user.name;');
|
|
46
|
+
});
|
|
47
|
+
(0, vitest_1.it)("should compile bare mathematical expressions", () => {
|
|
48
|
+
const ast = (0, parse_1.parse)("{data.count * 2}");
|
|
49
|
+
const result = (0, compile_1.compile)(ast);
|
|
50
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return (data.count * 2);');
|
|
51
|
+
});
|
|
52
|
+
(0, vitest_1.it)("should compile bare method calls", () => {
|
|
53
|
+
const ast = (0, parse_1.parse)("{data.text.toUpperCase()}");
|
|
54
|
+
const result = (0, compile_1.compile)(ast);
|
|
55
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return data.text.toUpperCase();');
|
|
56
|
+
});
|
|
57
|
+
(0, vitest_1.it)("should compile bare complex expressions", () => {
|
|
58
|
+
const ast = (0, parse_1.parse)("{data.items.filter(x => x.length > 2).length}");
|
|
59
|
+
const result = (0, compile_1.compile)(ast);
|
|
60
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return data.items.filter((x) => (x.length > 2)).length;');
|
|
61
|
+
});
|
|
62
|
+
(0, vitest_1.describe)("JSX empty expressions", () => {
|
|
63
|
+
(0, vitest_1.it)("should handle empty expressions in children", () => {
|
|
64
|
+
const ast = (0, parse_1.parse)("<Text>{}</Text>");
|
|
65
|
+
const compiled = (0, compile_1.compile)(ast);
|
|
66
|
+
(0, vitest_1.expect)(compiled).toContain("return");
|
|
67
|
+
(0, vitest_1.expect)(compiled).toContain("Text");
|
|
68
|
+
// Empty expressions should be skipped, so no children array should be empty or minimal
|
|
69
|
+
(0, vitest_1.expect)(compiled).toBeDefined();
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.it)("should handle multiple empty expressions", () => {
|
|
72
|
+
const ast = (0, parse_1.parse)("<Text>{}{}{}</Text>");
|
|
73
|
+
const compiled = (0, compile_1.compile)(ast);
|
|
74
|
+
(0, vitest_1.expect)(compiled).toContain("return");
|
|
75
|
+
(0, vitest_1.expect)(compiled).toContain("Text");
|
|
76
|
+
(0, vitest_1.expect)(compiled).toBeDefined();
|
|
77
|
+
});
|
|
78
|
+
(0, vitest_1.it)("should handle mixed empty and real expressions", () => {
|
|
79
|
+
const ast = (0, parse_1.parse)("<Text>Hello {}{data.x}{} World</Text>");
|
|
80
|
+
const compiled = (0, compile_1.compile)(ast);
|
|
81
|
+
(0, vitest_1.expect)(compiled).toContain("return");
|
|
82
|
+
(0, vitest_1.expect)(compiled).toContain("Text");
|
|
83
|
+
(0, vitest_1.expect)(compiled).toContain("Hello");
|
|
84
|
+
(0, vitest_1.expect)(compiled).toContain("World");
|
|
85
|
+
(0, vitest_1.expect)(compiled).toContain("data.x");
|
|
86
|
+
});
|
|
87
|
+
(0, vitest_1.it)("should generate valid JavaScript code structure", () => {
|
|
88
|
+
const ast = (0, parse_1.parse)("<Text>{}</Text>");
|
|
89
|
+
const compiled = (0, compile_1.compile)(ast);
|
|
90
|
+
// The compiled code should have expected structure
|
|
91
|
+
(0, vitest_1.expect)(compiled).toMatch(/^"use strict";return .+;$/);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
(0, vitest_1.describe)("spread elements", () => {
|
|
95
|
+
(0, vitest_1.it)("should compile spread in arrays", () => {
|
|
96
|
+
const ast = (0, parse_1.parse)("<div>{[...data.items]}</div>");
|
|
97
|
+
const result = (0, compile_1.compile)(ast);
|
|
98
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, [...data.items]);');
|
|
99
|
+
});
|
|
100
|
+
(0, vitest_1.it)("should compile spread in objects", () => {
|
|
101
|
+
const ast = (0, parse_1.parse)("<div style={{ ...data.styles }}>Text</div>");
|
|
102
|
+
const result = (0, compile_1.compile)(ast);
|
|
103
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", { style: { ...data.styles } }, "Text");');
|
|
104
|
+
});
|
|
105
|
+
(0, vitest_1.it)("should compile mixed spread and regular elements in arrays", () => {
|
|
106
|
+
const ast = (0, parse_1.parse)("<div>{[1, ...data.items, 2]}</div>");
|
|
107
|
+
const result = (0, compile_1.compile)(ast);
|
|
108
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, [1, ...data.items, 2]);');
|
|
109
|
+
});
|
|
110
|
+
(0, vitest_1.it)("should compile mixed spread and regular properties in objects", () => {
|
|
111
|
+
const ast = (0, parse_1.parse)("<div style={{ color: 'red', ...data.styles, width: 100 }}>Text</div>");
|
|
112
|
+
const result = (0, compile_1.compile)(ast);
|
|
113
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", { style: { color: "red", ...data.styles, width: 100 } }, "Text");');
|
|
114
|
+
});
|
|
115
|
+
(0, vitest_1.it)("should compile multiple spreads in arrays", () => {
|
|
116
|
+
const ast = (0, parse_1.parse)("<div>{[...data.first, ...data.second]}</div>");
|
|
117
|
+
const result = (0, compile_1.compile)(ast);
|
|
118
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, [...data.first, ...data.second]);');
|
|
119
|
+
});
|
|
120
|
+
(0, vitest_1.it)("should compile multiple spreads in objects", () => {
|
|
121
|
+
const ast = (0, parse_1.parse)("<div style={{ ...data.base, ...data.override }}>Text</div>");
|
|
122
|
+
const result = (0, compile_1.compile)(ast);
|
|
123
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", { style: { ...data.base, ...data.override } }, "Text");');
|
|
124
|
+
});
|
|
125
|
+
(0, vitest_1.it)("should compile spread in function call arguments", () => {
|
|
126
|
+
const ast = (0, parse_1.parse)("<div>{Math.max(...data.numbers)}</div>");
|
|
127
|
+
const result = (0, compile_1.compile)(ast);
|
|
128
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, Math.max(...data.numbers));');
|
|
129
|
+
});
|
|
130
|
+
(0, vitest_1.it)("should compile spread with map in function call", () => {
|
|
131
|
+
const ast = (0, parse_1.parse)("<div>{Math.min(...data.items.map(x => x.price))}</div>");
|
|
132
|
+
const result = (0, compile_1.compile)(ast);
|
|
133
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, Math.min(...data.items.map((x) => x.price)));');
|
|
134
|
+
});
|
|
135
|
+
(0, vitest_1.it)("should compile mixed spread and regular arguments", () => {
|
|
136
|
+
const ast = (0, parse_1.parse)("<div>{Math.max(0, ...data.numbers, 100)}</div>");
|
|
137
|
+
const result = (0, compile_1.compile)(ast);
|
|
138
|
+
(0, vitest_1.expect)(result).toBe('"use strict";return h("div", null, Math.max(0, ...data.numbers, 100));');
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
// TODO: Add ChainExpression support for optional chaining (?.)
|
|
142
|
+
// it("should compile nested object access with conditionals", () => {
|
|
143
|
+
// const ast = parse("<div>{props.user?.profile?.name || 'Anonymous'}</div>");
|
|
144
|
+
// const result = compile(ast);
|
|
145
|
+
// expect(result).toBe('"use strict";return h("div", null, ((props.user?.profile?.name) || "Anonymous"));');
|
|
146
|
+
// });
|
|
147
|
+
});
|
|
148
|
+
//# sourceMappingURL=compile.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.test.js","sourceRoot":"","sources":["../../src/compile/compile.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type ComponentDict = Record<string, Component>;
|
|
2
|
+
export type CreateElement<T = any> = (type: Component, props?: PropsDict, ...children: any[]) => T;
|
|
3
|
+
export type PropsDict = Record<string, unknown>;
|
|
4
|
+
export type DataDict = Record<string, unknown>;
|
|
5
|
+
export type Node = {
|
|
6
|
+
type: string;
|
|
7
|
+
props: PropsDict;
|
|
8
|
+
children: Node[];
|
|
9
|
+
};
|
|
10
|
+
export type H = (type: string, props?: PropsDict, ...children: Node[]) => Node;
|
|
11
|
+
export type Component = (...args: any[]) => any;
|
|
12
|
+
/**
|
|
13
|
+
* Configuration options for evaluating JSX expressions.
|
|
14
|
+
*
|
|
15
|
+
* @template T - The return type of createElement function
|
|
16
|
+
*/
|
|
17
|
+
export interface EvaluateOptions<T = any> {
|
|
18
|
+
/** Data object available as `data.*` in JSX expressions */
|
|
19
|
+
data?: DataDict;
|
|
20
|
+
/** Map of component names to component functions used in JSX */
|
|
21
|
+
components?: ComponentDict;
|
|
22
|
+
/** Function to create JSX elements (e.g., React.createElement, h) */
|
|
23
|
+
createElement?: CreateElement<T>;
|
|
24
|
+
}
|
|
25
|
+
export declare function evaluate<T = any>(source: string, options: EvaluateOptions<T>): T;
|
|
26
|
+
//# sourceMappingURL=evaluate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/evaluate/evaluate.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAEtD,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAEnG,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,IAAI,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAE/E,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,GAAG;IACtC,2DAA2D;IAC3D,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,gEAAgE;IAChE,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,qEAAqE;IACrE,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CAClC;AAED,wBAAgB,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAgBhF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { EvaluationError } from "./evaluation-error";
|
|
2
|
+
export function evaluate(source, options) {
|
|
3
|
+
const { data = {}, components = {}, createElement } = options;
|
|
4
|
+
const h = createH(components, createElement || defaultCreateElement);
|
|
5
|
+
try {
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func
|
|
7
|
+
return new Function("h", "data", "Math", source)(h, deepFreezeData(data), Math);
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
// We may have thrown an EvaluationError from createH()
|
|
11
|
+
if (error instanceof EvaluationError) {
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
throw new EvaluationError(error instanceof Error ? error.message : "Evaluation failed");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function createH(components, createElement) {
|
|
18
|
+
return function h(type, props, ...children) {
|
|
19
|
+
const Component = components[type];
|
|
20
|
+
if (!Component) {
|
|
21
|
+
throw new EvaluationError(`component "${type}" is not allowed`);
|
|
22
|
+
}
|
|
23
|
+
return createElement(Component, props, ...children.flat().filter(Boolean));
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function deepFreezeData(obj) {
|
|
27
|
+
Object.freeze(obj);
|
|
28
|
+
Object.values(obj).filter(isDataDict).forEach(deepFreezeData);
|
|
29
|
+
return obj;
|
|
30
|
+
}
|
|
31
|
+
function isDataDict(value) {
|
|
32
|
+
return typeof value === "object" && value !== null;
|
|
33
|
+
}
|
|
34
|
+
function defaultCreateElement(Component, props = {}, ...children) {
|
|
35
|
+
return {
|
|
36
|
+
type: Component.name,
|
|
37
|
+
props,
|
|
38
|
+
children,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluation-error.d.ts","sourceRoot":"","sources":["../../src/evaluate/evaluation-error.ts"],"names":[],"mappings":"AAAA,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { Schema, PropertySchema } from "./schema";
|
|
2
|
+
export { ParseError } from "./parse";
|
|
3
|
+
export { CompilationError } from "./compile";
|
|
4
|
+
export { AnalysisError } from "./analyze";
|
|
5
|
+
export { render, type RenderOptions } from "./render";
|
|
6
|
+
export { validate, type ValidateOptions, type ValidateResult } from "./validate";
|
|
7
|
+
export { generateTypeScriptDefinitions } from "./codegen";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjF,OAAO,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateTypeScriptDefinitions = exports.validate = exports.render = exports.AnalysisError = exports.CompilationError = exports.ParseError = void 0;
|
|
4
|
+
var parse_1 = require("./parse");
|
|
5
|
+
Object.defineProperty(exports, "ParseError", { enumerable: true, get: function () { return parse_1.ParseError; } });
|
|
6
|
+
var compile_1 = require("./compile");
|
|
7
|
+
Object.defineProperty(exports, "CompilationError", { enumerable: true, get: function () { return compile_1.CompilationError; } });
|
|
8
|
+
var analyze_1 = require("./analyze");
|
|
9
|
+
Object.defineProperty(exports, "AnalysisError", { enumerable: true, get: function () { return analyze_1.AnalysisError; } });
|
|
10
|
+
var render_1 = require("./render");
|
|
11
|
+
Object.defineProperty(exports, "render", { enumerable: true, get: function () { return render_1.render; } });
|
|
12
|
+
var validate_1 = require("./validate");
|
|
13
|
+
Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return validate_1.validate; } });
|
|
14
|
+
var codegen_1 = require("./codegen");
|
|
15
|
+
Object.defineProperty(exports, "generateTypeScriptDefinitions", { enumerable: true, get: function () { return codegen_1.generateTypeScriptDefinitions; } });
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AACnB,qCAA6C;AAApC,2GAAA,gBAAgB,OAAA;AACzB,qCAA0C;AAAjC,wGAAA,aAAa,OAAA;AAEtB,mCAAsD;AAA7C,gGAAA,MAAM,OAAA;AACf,uCAAiF;AAAxE,oGAAA,QAAQ,OAAA;AAEjB,qCAA0D;AAAjD,wHAAA,6BAA6B,OAAA"}
|
package/lib/render.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { EvaluateOptions } from "./evaluate/evaluate";
|
|
2
|
+
import { Schema } from "./schema";
|
|
3
|
+
/**
|
|
4
|
+
* Configuration options for rendering JSX expressions.
|
|
5
|
+
*
|
|
6
|
+
* Extends EvaluateOptions with render-specific functionality, including control over
|
|
7
|
+
* the minimum severity threshold that stops rendering.
|
|
8
|
+
*
|
|
9
|
+
* @template T - The return type of createElement function
|
|
10
|
+
*/
|
|
11
|
+
export interface RenderOptions<T = any> extends EvaluateOptions<T> {
|
|
12
|
+
/**
|
|
13
|
+
* Minimum severity level that counts as a failure: 1=info, 2=warning, 3=error.
|
|
14
|
+
*/
|
|
15
|
+
minSeverity?: 1 | 2 | 3;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Renders a JSX expression with data validation and security constraints.
|
|
19
|
+
*
|
|
20
|
+
* Parses JSX source code, validates it against a schema for security and type safety,
|
|
21
|
+
* compiles it to executable code, and evaluates it with the provided data and components.
|
|
22
|
+
*
|
|
23
|
+
* @template T - The return type of the rendered JSX (e.g., ReactElement, VNode, string)
|
|
24
|
+
* @param source - JSX expression source code to render (e.g., `"<Text x={data.user.name}>Hello</Text>"`)
|
|
25
|
+
* @param schema - Schema defining allowed data properties, JSX elements, and hierarchy rules
|
|
26
|
+
* @param options - Rendering configuration
|
|
27
|
+
* @param options.data - Data object available as `data.*` in expressions
|
|
28
|
+
* @param options.components - Map of component names to component functions
|
|
29
|
+
* @param options.createElement - Function to create elements (e.g., React.createElement)
|
|
30
|
+
* @param options.minSeverity - Minimum severity (1=info, 2=warning, 3=error) required to abort rendering; defaults to `3`
|
|
31
|
+
* @returns The rendered JSX element of type T
|
|
32
|
+
*
|
|
33
|
+
* @throws {AnalysisError} When JSX contains security violations, invalid data access, or schema mismatches
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const schema: Schema = {
|
|
38
|
+
* data: {
|
|
39
|
+
* user: { type: "object", shape: { name: { type: "string" } } }
|
|
40
|
+
* },
|
|
41
|
+
* elements: {
|
|
42
|
+
* Text: { props: { children: { type: "string" } } }
|
|
43
|
+
* }
|
|
44
|
+
* };
|
|
45
|
+
*
|
|
46
|
+
* const result = render(
|
|
47
|
+
* "<Text>Hello {data.user.name}!</Text>",
|
|
48
|
+
* schema,
|
|
49
|
+
* {
|
|
50
|
+
* data: { user: { name: "World" } },
|
|
51
|
+
* components: { Text: ({ children }) => children },
|
|
52
|
+
* createElement: (type, props, ...children) => ({ type, props, children })
|
|
53
|
+
* }
|
|
54
|
+
* );
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function render<T = any>(source: string, schema: Schema, { minSeverity, ...options }?: RenderOptions<T>): T;
|
|
58
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,eAAe,CAAC,CAAC,CAAC;IAChE;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,MAAM,CAAC,CAAC,GAAG,GAAG,EAC5B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,EAAE,WAAe,EAAE,GAAG,OAAO,EAAE,GAAE,aAAa,CAAC,CAAC,CAAM,GACrD,CAAC,CASH"}
|