@jbpark/live-editor 1.4.0 → 1.6.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/README.ko.md +1 -1
- package/README.md +1 -1
- package/dist/ast-CXRFs1hO.mjs +788 -0
- package/dist/ast-CXRFs1hO.mjs.map +1 -0
- package/dist/{ast-fX6Whrjc.mjs → document-BkOqiV4R.mjs} +9940 -9340
- package/dist/document-BkOqiV4R.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +112 -60
- package/dist/index.mjs.map +1 -1
- package/dist/utils/ast/index.d.mts +23 -3
- package/dist/utils/ast/index.mjs +3 -2
- package/dist/utils/index.d.mts +2 -1
- package/dist/utils/index.mjs +3 -2
- package/dist/{utils-INSWI9h0.mjs → utils-YMe7_mya.mjs} +14 -40
- package/dist/{utils-INSWI9h0.mjs.map → utils-YMe7_mya.mjs.map} +1 -1
- package/package.json +8 -2
- package/dist/ast-fX6Whrjc.mjs.map +0 -1
- package/dist/enums-3yleLgqV.mjs +0 -1237
- package/dist/enums-3yleLgqV.mjs.map +0 -1
|
@@ -0,0 +1,788 @@
|
|
|
1
|
+
import { b as __toESM, c as createBoundedCache, d as require_lib$2, f as require_lib$1, h as DATA_ATTR, l as require_lib$3, m as CONFIG, p as BINDING_PROP, u as require_lib, v as REGEX } from "./document-BkOqiV4R.mjs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import crypto from "crypto";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/ast/types.ts
|
|
6
|
+
const BINDING_TYPES = [
|
|
7
|
+
"array",
|
|
8
|
+
"object",
|
|
9
|
+
"string",
|
|
10
|
+
"number",
|
|
11
|
+
"boolean",
|
|
12
|
+
"color",
|
|
13
|
+
"jsx",
|
|
14
|
+
"richtext",
|
|
15
|
+
"date",
|
|
16
|
+
"url",
|
|
17
|
+
"icon-picker",
|
|
18
|
+
"asset-picker"
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/utils/ast/helpers.ts
|
|
23
|
+
var import_lib$1 = /* @__PURE__ */ __toESM(require_lib(), 1);
|
|
24
|
+
var import_lib$2 = require_lib$1();
|
|
25
|
+
var import_lib$3 = /* @__PURE__ */ __toESM(require_lib$2(), 1);
|
|
26
|
+
const wrap = (code) => {
|
|
27
|
+
return `<>${code}</>`;
|
|
28
|
+
};
|
|
29
|
+
const unwrap = (generated) => {
|
|
30
|
+
return generated.replace(/^<>\s*/g, "").replace(/\s*<\/>\s*;?\s*$/g, "").trim();
|
|
31
|
+
};
|
|
32
|
+
const attrValue = ({ value, isStringLiteral }) => {
|
|
33
|
+
if (value === null) return null;
|
|
34
|
+
if (isStringLiteral) return import_lib$3.stringLiteral(value);
|
|
35
|
+
const trimmed = value.trim();
|
|
36
|
+
if (REGEX.NUMBER.test(trimmed)) return import_lib$3.jsxExpressionContainer(import_lib$3.numericLiteral(parseFloat(trimmed)));
|
|
37
|
+
if (REGEX.BOOLEAN_OR_NULL.test(trimmed)) {
|
|
38
|
+
const expr = (0, import_lib$2.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
|
|
39
|
+
return import_lib$3.jsxExpressionContainer(expr);
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const expr = (0, import_lib$2.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
|
|
43
|
+
return import_lib$3.jsxExpressionContainer(expr);
|
|
44
|
+
} catch {
|
|
45
|
+
return import_lib$3.stringLiteral(trimmed);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const generateCode = (node) => {
|
|
49
|
+
return (0, import_lib$1.default)(node, { jsescOption: { minimal: true } }).code;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/utils/ast/value.ts
|
|
54
|
+
const dedent = (str) => {
|
|
55
|
+
const lines = str.replace(/^\n/, "").replace(/\n\s*$/, "").split("\n");
|
|
56
|
+
const indent = lines.reduce((min, line) => {
|
|
57
|
+
if (!line.trim()) return min;
|
|
58
|
+
const match = line.match(/^(\s*)/);
|
|
59
|
+
return Math.min(min, match?.[1]?.length ?? 0);
|
|
60
|
+
}, Infinity);
|
|
61
|
+
return indent === Infinity ? str.trim() : lines.map((line) => line.slice(indent)).join("\n");
|
|
62
|
+
};
|
|
63
|
+
const evaluateLiteral = (node) => {
|
|
64
|
+
if (import_lib$3.isStringLiteral(node)) return node.value;
|
|
65
|
+
if (import_lib$3.isNumericLiteral(node)) return node.value;
|
|
66
|
+
if (import_lib$3.isBooleanLiteral(node)) return node.value;
|
|
67
|
+
if (import_lib$3.isNullLiteral(node)) return null;
|
|
68
|
+
if (import_lib$3.isIdentifier(node) && node.name === "undefined") return;
|
|
69
|
+
if (import_lib$3.isUnaryExpression(node) && node.operator === "-" && import_lib$3.isNumericLiteral(node.argument)) return -node.argument.value;
|
|
70
|
+
if (import_lib$3.isTemplateLiteral(node) && node.expressions.length === 0) return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw ?? "";
|
|
71
|
+
if (import_lib$3.isJSXElement(node) || import_lib$3.isJSXFragment(node)) return generateCode(node);
|
|
72
|
+
if (import_lib$3.isArrayExpression(node)) return node.elements.map((element) => element ? evaluateLiteral(element) : null);
|
|
73
|
+
if (import_lib$3.isObjectExpression(node)) {
|
|
74
|
+
const result = {};
|
|
75
|
+
for (const prop of node.properties) {
|
|
76
|
+
if (!import_lib$3.isObjectProperty(prop)) continue;
|
|
77
|
+
let key = null;
|
|
78
|
+
if (import_lib$3.isIdentifier(prop.key)) key = prop.key.name;
|
|
79
|
+
else if (import_lib$3.isStringLiteral(prop.key)) key = prop.key.value;
|
|
80
|
+
else if (import_lib$3.isNumericLiteral(prop.key)) key = String(prop.key.value);
|
|
81
|
+
if (key === null) continue;
|
|
82
|
+
result[key] = evaluateLiteral(prop.value);
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const parseValue = (value) => {
|
|
88
|
+
if (typeof value !== "string") return value;
|
|
89
|
+
const trimmed = value.trim();
|
|
90
|
+
if (!trimmed) return value;
|
|
91
|
+
if (REGEX.NUMBER.test(trimmed)) return parseFloat(trimmed);
|
|
92
|
+
if (REGEX.BOOLEAN_OR_NULL.test(trimmed)) {
|
|
93
|
+
if (trimmed === "true") return true;
|
|
94
|
+
if (trimmed === "false") return false;
|
|
95
|
+
if (trimmed === "null") return null;
|
|
96
|
+
if (trimmed === "undefined") return;
|
|
97
|
+
}
|
|
98
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
99
|
+
try {
|
|
100
|
+
const ast = (0, import_lib$2.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
|
|
101
|
+
if (import_lib$3.isObjectExpression(ast) || import_lib$3.isArrayExpression(ast)) return evaluateLiteral(ast);
|
|
102
|
+
} catch {}
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
return value;
|
|
106
|
+
};
|
|
107
|
+
const extractNodeValue = (node) => {
|
|
108
|
+
if (import_lib$3.isBooleanLiteral(node)) return {
|
|
109
|
+
type: "boolean",
|
|
110
|
+
value: node.value
|
|
111
|
+
};
|
|
112
|
+
if (import_lib$3.isNumericLiteral(node)) return {
|
|
113
|
+
type: "number",
|
|
114
|
+
value: node.value
|
|
115
|
+
};
|
|
116
|
+
if (import_lib$3.isStringLiteral(node)) return {
|
|
117
|
+
type: "string",
|
|
118
|
+
value: node.value
|
|
119
|
+
};
|
|
120
|
+
if (import_lib$3.isTemplateLiteral(node)) {
|
|
121
|
+
if (node.expressions.length === 0 && node.quasis.length === 1) return {
|
|
122
|
+
type: "string",
|
|
123
|
+
value: dedent(node.quasis[0].value.cooked ?? node.quasis[0].value.raw)
|
|
124
|
+
};
|
|
125
|
+
return {
|
|
126
|
+
type: "string",
|
|
127
|
+
value: generateCode(node)
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (import_lib$3.isNullLiteral(node)) return {
|
|
131
|
+
type: "null",
|
|
132
|
+
value: null
|
|
133
|
+
};
|
|
134
|
+
if (import_lib$3.isArrayExpression(node)) return {
|
|
135
|
+
type: "array",
|
|
136
|
+
value: generateCode(node)
|
|
137
|
+
};
|
|
138
|
+
if (import_lib$3.isObjectExpression(node)) return {
|
|
139
|
+
type: "object",
|
|
140
|
+
value: generateCode(node)
|
|
141
|
+
};
|
|
142
|
+
if (import_lib$3.isJSXElement(node) || import_lib$3.isJSXFragment(node)) return {
|
|
143
|
+
type: "string",
|
|
144
|
+
value: generateCode(node)
|
|
145
|
+
};
|
|
146
|
+
return {
|
|
147
|
+
type: "unknown",
|
|
148
|
+
value: null
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
const createNodeFromValue = (type, value) => {
|
|
152
|
+
switch (type) {
|
|
153
|
+
case "boolean": return import_lib$3.booleanLiteral(value === true);
|
|
154
|
+
case "number": return import_lib$3.numericLiteral(Number(value));
|
|
155
|
+
case "string": return import_lib$3.stringLiteral(String(value));
|
|
156
|
+
case "null": return import_lib$3.nullLiteral();
|
|
157
|
+
case "array":
|
|
158
|
+
case "object":
|
|
159
|
+
case "unknown": return null;
|
|
160
|
+
default: return null;
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
const parseArrayExpression = (value) => {
|
|
164
|
+
try {
|
|
165
|
+
const ast = (0, import_lib$2.parseExpression)(value, { plugins: ["jsx", "typescript"] });
|
|
166
|
+
if (!import_lib$3.isArrayExpression(ast)) return null;
|
|
167
|
+
return ast;
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.error("❌ Array parsing error:", error);
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
const extractObjectProperties = (element) => {
|
|
174
|
+
const properties = {};
|
|
175
|
+
element.properties.forEach((prop) => {
|
|
176
|
+
if (import_lib$3.isObjectProperty(prop) && import_lib$3.isIdentifier(prop.key)) {
|
|
177
|
+
const key = prop.key.name;
|
|
178
|
+
if (key === "children") return;
|
|
179
|
+
properties[key] = {
|
|
180
|
+
...extractNodeValue(prop.value),
|
|
181
|
+
astNode: prop.value
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
return properties;
|
|
186
|
+
};
|
|
187
|
+
const arrayExpressionToCode = (elements) => {
|
|
188
|
+
return generateCode(import_lib$3.arrayExpression(elements));
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/utils/ast/binding.ts
|
|
193
|
+
const bindingTypeSchema = z.enum(BINDING_TYPES);
|
|
194
|
+
const bindingOptionSchema = z.object({
|
|
195
|
+
label: z.string(),
|
|
196
|
+
value: z.string()
|
|
197
|
+
});
|
|
198
|
+
const bindingRenderLeafSchema = z.object({
|
|
199
|
+
type: bindingTypeSchema,
|
|
200
|
+
property: z.string().optional()
|
|
201
|
+
});
|
|
202
|
+
const rawBindingItemSchema = z.object({
|
|
203
|
+
label: z.string(),
|
|
204
|
+
property: z.string().optional(),
|
|
205
|
+
type: bindingTypeSchema.optional(),
|
|
206
|
+
options: z.array(bindingOptionSchema).optional(),
|
|
207
|
+
min: z.number().optional(),
|
|
208
|
+
max: z.number().optional(),
|
|
209
|
+
pattern: z.string().optional(),
|
|
210
|
+
required: z.boolean().optional()
|
|
211
|
+
});
|
|
212
|
+
const isPlainObject = (value) => {
|
|
213
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
214
|
+
};
|
|
215
|
+
const sanitizeRenderMap = (value) => {
|
|
216
|
+
if (!isPlainObject(value)) return;
|
|
217
|
+
const map = {};
|
|
218
|
+
for (const [key, raw] of Object.entries(value)) {
|
|
219
|
+
if (!isPlainObject(raw)) continue;
|
|
220
|
+
if ("type" in raw) {
|
|
221
|
+
const leaf = bindingRenderLeafSchema.safeParse(raw);
|
|
222
|
+
if (leaf.success) {
|
|
223
|
+
const render = sanitizeRenderMap(raw.render);
|
|
224
|
+
map[key] = render ? {
|
|
225
|
+
...leaf.data,
|
|
226
|
+
render
|
|
227
|
+
} : leaf.data;
|
|
228
|
+
}
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
const nested = sanitizeRenderMap(raw);
|
|
232
|
+
if (nested) map[key] = nested;
|
|
233
|
+
}
|
|
234
|
+
return Object.keys(map).length > 0 ? map : void 0;
|
|
235
|
+
};
|
|
236
|
+
const parseBinding = (bindingValue) => {
|
|
237
|
+
if (!bindingValue) return [];
|
|
238
|
+
const ast = parseArrayExpression(bindingValue);
|
|
239
|
+
if (!ast) return [];
|
|
240
|
+
const raw = evaluateLiteral(ast);
|
|
241
|
+
if (!Array.isArray(raw)) return [];
|
|
242
|
+
const items = [];
|
|
243
|
+
for (const rawItem of raw) {
|
|
244
|
+
if (!isPlainObject(rawItem)) continue;
|
|
245
|
+
const sanitizedType = bindingTypeSchema.safeParse(rawItem.type);
|
|
246
|
+
const sanitizedOptions = Array.isArray(rawItem.options) ? rawItem.options.map((option) => {
|
|
247
|
+
const parsed = bindingOptionSchema.safeParse(option);
|
|
248
|
+
return parsed.success ? parsed.data : null;
|
|
249
|
+
}).filter((option) => option !== null) : void 0;
|
|
250
|
+
const parsed = rawBindingItemSchema.safeParse({
|
|
251
|
+
...rawItem,
|
|
252
|
+
type: sanitizedType.success ? sanitizedType.data : void 0,
|
|
253
|
+
options: sanitizedOptions?.length ? sanitizedOptions : void 0
|
|
254
|
+
});
|
|
255
|
+
if (!parsed.success) continue;
|
|
256
|
+
const { label, property, type, options, min, max, pattern, required } = parsed.data;
|
|
257
|
+
if (property === void 0 && type !== "richtext") continue;
|
|
258
|
+
const render = sanitizeRenderMap(rawItem.render);
|
|
259
|
+
items.push({
|
|
260
|
+
label,
|
|
261
|
+
property: property ?? BINDING_PROP.INNER_HTML,
|
|
262
|
+
...type !== void 0 && { type },
|
|
263
|
+
...options?.length && { options },
|
|
264
|
+
...render && { render },
|
|
265
|
+
...min !== void 0 && { min },
|
|
266
|
+
...max !== void 0 && { max },
|
|
267
|
+
...pattern !== void 0 && { pattern },
|
|
268
|
+
...required !== void 0 && { required }
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
return items;
|
|
272
|
+
};
|
|
273
|
+
const getCurrentValue = (node, property) => {
|
|
274
|
+
switch (property) {
|
|
275
|
+
case BINDING_PROP.INNER_TEXT: return node.textContent || "";
|
|
276
|
+
case BINDING_PROP.INNER_HTML: {
|
|
277
|
+
const dsiAttr = node.attributes.find((a) => a.name === "dangerouslySetInnerHTML");
|
|
278
|
+
if (dsiAttr?.value) try {
|
|
279
|
+
const expr = (0, import_lib$2.parseExpression)(dsiAttr.value, { plugins: ["jsx", "typescript"] });
|
|
280
|
+
if (import_lib$3.isObjectExpression(expr)) {
|
|
281
|
+
const htmlProp = expr.properties.find((p) => import_lib$3.isObjectProperty(p) && import_lib$3.isIdentifier(p.key) && p.key.name === "__html");
|
|
282
|
+
if (htmlProp) {
|
|
283
|
+
if (import_lib$3.isStringLiteral(htmlProp.value)) return htmlProp.value.value;
|
|
284
|
+
if (import_lib$3.isTemplateLiteral(htmlProp.value) && htmlProp.value.expressions.length === 0) return htmlProp.value.quasis[0]?.value.cooked ?? htmlProp.value.quasis[0]?.value.raw ?? "";
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
} catch {}
|
|
288
|
+
return node.rawChildren || node.textContent || "";
|
|
289
|
+
}
|
|
290
|
+
case BINDING_PROP.CHILDREN: return JSON.stringify(node?.children || []);
|
|
291
|
+
default: return node.attributes.find((attr) => attr.name === property)?.value || "";
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
const hasEditableBindings = (node) => {
|
|
295
|
+
const bindingAttr = node.dataAttributes.find((attr) => attr.name === DATA_ATTR.BINDING);
|
|
296
|
+
if (!bindingAttr?.value) return false;
|
|
297
|
+
return (node.bindings || parseBinding(bindingAttr.value)).length > 0;
|
|
298
|
+
};
|
|
299
|
+
const findEditableChildren = (node) => {
|
|
300
|
+
const editableChildren = [];
|
|
301
|
+
const traverse = (children) => {
|
|
302
|
+
if (!children) return;
|
|
303
|
+
for (const child of children) {
|
|
304
|
+
if (hasEditableBindings(child)) editableChildren.push(child);
|
|
305
|
+
traverse(child.children);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
traverse(node.children);
|
|
309
|
+
return editableChildren;
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
//#endregion
|
|
313
|
+
//#region node_modules/.pnpm/nanoid@3.3.11/node_modules/nanoid/url-alphabet/index.js
|
|
314
|
+
let urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
315
|
+
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region node_modules/.pnpm/nanoid@3.3.11/node_modules/nanoid/index.js
|
|
318
|
+
const POOL_SIZE_MULTIPLIER = 128;
|
|
319
|
+
let pool, poolOffset;
|
|
320
|
+
let fillPool = (bytes) => {
|
|
321
|
+
if (!pool || pool.length < bytes) {
|
|
322
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
323
|
+
crypto.randomFillSync(pool);
|
|
324
|
+
poolOffset = 0;
|
|
325
|
+
} else if (poolOffset + bytes > pool.length) {
|
|
326
|
+
crypto.randomFillSync(pool);
|
|
327
|
+
poolOffset = 0;
|
|
328
|
+
}
|
|
329
|
+
poolOffset += bytes;
|
|
330
|
+
};
|
|
331
|
+
let nanoid = (size = 21) => {
|
|
332
|
+
fillPool(size |= 0);
|
|
333
|
+
let id = "";
|
|
334
|
+
for (let i = poolOffset - size; i < poolOffset; i++) id += urlAlphabet[pool[i] & 63];
|
|
335
|
+
return id;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
//#endregion
|
|
339
|
+
//#region src/utils/ast/extract.ts
|
|
340
|
+
var import_lib = /* @__PURE__ */ __toESM(require_lib$3(), 1);
|
|
341
|
+
const collectText = (children) => {
|
|
342
|
+
return children.filter((c) => import_lib$3.isJSXText(c)).map((c) => c.value.trim()).filter((v) => v.length).join(" ");
|
|
343
|
+
};
|
|
344
|
+
const getTagName = (opening) => {
|
|
345
|
+
if (import_lib$3.isJSXIdentifier(opening.name)) return opening.name.name;
|
|
346
|
+
if (import_lib$3.isJSXMemberExpression(opening.name)) return resolveMemberName(opening.name);
|
|
347
|
+
return "";
|
|
348
|
+
};
|
|
349
|
+
const resolveMemberName = (expr) => {
|
|
350
|
+
const parts = [];
|
|
351
|
+
const collectMemberParts = (node) => {
|
|
352
|
+
if (import_lib$3.isJSXIdentifier(node)) parts.push(node.name);
|
|
353
|
+
else if (import_lib$3.isJSXMemberExpression(node)) {
|
|
354
|
+
collectMemberParts(node.object);
|
|
355
|
+
if (import_lib$3.isJSXIdentifier(node.property)) parts.push(node.property.name);
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
collectMemberParts(expr.object);
|
|
359
|
+
if (import_lib$3.isJSXIdentifier(expr.property)) parts.push(expr.property.name);
|
|
360
|
+
return parts.join(".");
|
|
361
|
+
};
|
|
362
|
+
const parseJSXName = (tagName) => {
|
|
363
|
+
const parts = tagName.split(".");
|
|
364
|
+
if (parts.length === 1) return import_lib$3.jsxIdentifier(parts[0]);
|
|
365
|
+
let expr = import_lib$3.jsxIdentifier(parts[0]);
|
|
366
|
+
for (let i = 1; i < parts.length; i++) expr = import_lib$3.jsxMemberExpression(expr, import_lib$3.jsxIdentifier(parts[i]));
|
|
367
|
+
return expr;
|
|
368
|
+
};
|
|
369
|
+
const extractCache = createBoundedCache(CONFIG.CACHE_LIMIT);
|
|
370
|
+
const extractAttributes = (attributes) => {
|
|
371
|
+
const allAttrs = [];
|
|
372
|
+
const dataAttrs = [];
|
|
373
|
+
for (const attr of attributes) {
|
|
374
|
+
if (!import_lib$3.isJSXAttribute(attr) || !import_lib$3.isJSXIdentifier(attr.name)) continue;
|
|
375
|
+
const name = attr.name.name;
|
|
376
|
+
let value = null;
|
|
377
|
+
let isStringLiteral = false;
|
|
378
|
+
if (attr.value) {
|
|
379
|
+
if (import_lib$3.isStringLiteral(attr.value)) {
|
|
380
|
+
value = attr.value.value;
|
|
381
|
+
isStringLiteral = true;
|
|
382
|
+
} else if (import_lib$3.isJSXExpressionContainer(attr.value)) try {
|
|
383
|
+
value = generateCode(attr.value.expression);
|
|
384
|
+
isStringLiteral = false;
|
|
385
|
+
} catch {
|
|
386
|
+
value = null;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const entry = {
|
|
390
|
+
name,
|
|
391
|
+
value,
|
|
392
|
+
isStringLiteral
|
|
393
|
+
};
|
|
394
|
+
allAttrs.push(entry);
|
|
395
|
+
if (name.startsWith("data-")) dataAttrs.push(entry);
|
|
396
|
+
}
|
|
397
|
+
return {
|
|
398
|
+
allAttrs,
|
|
399
|
+
dataAttrs
|
|
400
|
+
};
|
|
401
|
+
};
|
|
402
|
+
const buildChildElements = (node) => {
|
|
403
|
+
const childElements = [];
|
|
404
|
+
if (node.textContent) childElements.push(import_lib$3.jsxText(node.textContent));
|
|
405
|
+
node.children?.forEach((child) => {
|
|
406
|
+
const childJSX = nodeToJSX(child);
|
|
407
|
+
if (childJSX) childElements.push(childJSX);
|
|
408
|
+
});
|
|
409
|
+
return childElements;
|
|
410
|
+
};
|
|
411
|
+
const nodeToJSX = (node) => {
|
|
412
|
+
try {
|
|
413
|
+
if (node.isFragment) {
|
|
414
|
+
const childElements = buildChildElements(node);
|
|
415
|
+
return import_lib$3.jsxFragment(import_lib$3.jsxOpeningFragment(), import_lib$3.jsxClosingFragment(), childElements);
|
|
416
|
+
}
|
|
417
|
+
if (node.tagName === "div" && node.dataAttributes.some((attr) => attr.name === "data-item")) {
|
|
418
|
+
if (node.children) return nodeToJSX(node.children[0]);
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
const attributes = node.attributes.map((attr) => {
|
|
422
|
+
const attrName = import_lib$3.jsxIdentifier(attr.name);
|
|
423
|
+
if (!attr.value) return import_lib$3.jsxAttribute(attrName, null);
|
|
424
|
+
return import_lib$3.jsxAttribute(attrName, attrValue(attr));
|
|
425
|
+
});
|
|
426
|
+
const elementName = parseJSXName(node.tagName);
|
|
427
|
+
const openingElement = import_lib$3.jsxOpeningElement(elementName, attributes);
|
|
428
|
+
const closingElement = import_lib$3.jsxClosingElement(elementName);
|
|
429
|
+
const children = buildChildElements(node);
|
|
430
|
+
return import_lib$3.jsxElement(openingElement, closingElement, children, false);
|
|
431
|
+
} catch (error) {
|
|
432
|
+
console.error("❌ DataAttrNode to JSX conversion error:", error);
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
const createWrapperNode = (textContent, children) => ({
|
|
437
|
+
tagName: "div",
|
|
438
|
+
id: nanoid(6),
|
|
439
|
+
attributes: [{
|
|
440
|
+
name: DATA_ATTR.ITEM,
|
|
441
|
+
value: "true"
|
|
442
|
+
}],
|
|
443
|
+
dataAttributes: [{
|
|
444
|
+
name: DATA_ATTR.ITEM,
|
|
445
|
+
value: "true"
|
|
446
|
+
}],
|
|
447
|
+
textContent,
|
|
448
|
+
children
|
|
449
|
+
});
|
|
450
|
+
const createFragmentNode = (textContent, children) => ({
|
|
451
|
+
tagName: "",
|
|
452
|
+
id: nanoid(6),
|
|
453
|
+
attributes: [],
|
|
454
|
+
dataAttributes: [],
|
|
455
|
+
textContent,
|
|
456
|
+
children,
|
|
457
|
+
isFragment: true
|
|
458
|
+
});
|
|
459
|
+
const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true) => {
|
|
460
|
+
const jsxChildren = jsxElement.children.filter((child) => import_lib$3.isJSXElement(child) || import_lib$3.isJSXFragment(child));
|
|
461
|
+
if (!jsxChildren.length) return;
|
|
462
|
+
const childrenNodes = [];
|
|
463
|
+
jsxChildren.forEach((child) => {
|
|
464
|
+
if (import_lib$3.isJSXElement(child)) {
|
|
465
|
+
const childResults = extractFromNode(child, processedNodes);
|
|
466
|
+
if (shouldWrap) {
|
|
467
|
+
const wrapperNode = createWrapperNode(collectText(child.children), childResults);
|
|
468
|
+
childrenNodes.push(wrapperNode);
|
|
469
|
+
} else childrenNodes.push(...childResults);
|
|
470
|
+
} else if (import_lib$3.isJSXFragment(child)) {
|
|
471
|
+
processedNodes?.add(child);
|
|
472
|
+
const fragmentChildren = [];
|
|
473
|
+
child.children.forEach((fragmentChild) => {
|
|
474
|
+
if (import_lib$3.isJSXElement(fragmentChild)) {
|
|
475
|
+
const childResults = extractFromNode(fragmentChild, processedNodes);
|
|
476
|
+
fragmentChildren.push(...childResults);
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
if (fragmentChildren.length) {
|
|
480
|
+
const fragmentNode = createFragmentNode(collectText(child.children), fragmentChildren);
|
|
481
|
+
childrenNodes.push(fragmentNode);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
return childrenNodes.length ? childrenNodes : void 0;
|
|
486
|
+
};
|
|
487
|
+
const skipItemsChildren = (jsxElement, processedNodes, propertyName = "items") => {
|
|
488
|
+
const itemsAttr = jsxElement.openingElement.attributes.find((attr) => import_lib$3.isJSXAttribute(attr) && import_lib$3.isJSXIdentifier(attr.name) && attr.name.name === propertyName);
|
|
489
|
+
if (!itemsAttr || !import_lib$3.isJSXAttribute(itemsAttr)) return;
|
|
490
|
+
if (itemsAttr.value && import_lib$3.isJSXExpressionContainer(itemsAttr.value) && import_lib$3.isArrayExpression(itemsAttr.value.expression)) itemsAttr.value.expression.elements.forEach((element) => {
|
|
491
|
+
if (import_lib$3.isObjectExpression(element)) element.properties.forEach((prop) => {
|
|
492
|
+
if (import_lib$3.isObjectProperty(prop) && import_lib$3.isIdentifier(prop.key) && import_lib$3.isJSXElement(prop.value)) markProcessedJSX(prop.value, processedNodes);
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
};
|
|
496
|
+
const markProcessedJSX = (node, processedNodes) => {
|
|
497
|
+
if (import_lib$3.isJSXElement(node) || import_lib$3.isJSXFragment(node)) {
|
|
498
|
+
processedNodes.add(node);
|
|
499
|
+
node.children.forEach((child) => markProcessedJSX(child, processedNodes));
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
if (import_lib$3.isJSXExpressionContainer(node) || import_lib$3.isParenthesizedExpression(node)) markProcessedJSX(node.expression, processedNodes);
|
|
503
|
+
};
|
|
504
|
+
const readNodeBindingInfo = (node) => {
|
|
505
|
+
const opening = node.openingElement;
|
|
506
|
+
const tagName = getTagName(opening);
|
|
507
|
+
const { allAttrs, dataAttrs } = extractAttributes(opening.attributes);
|
|
508
|
+
const bindingAttr = dataAttrs.find((attr) => attr.name === DATA_ATTR.BINDING);
|
|
509
|
+
const bindings = bindingAttr?.value ? parseBinding(bindingAttr.value) : [];
|
|
510
|
+
const childrenBinding = bindings.find((b) => b.property === BINDING_PROP.CHILDREN);
|
|
511
|
+
const arrayBindings = bindings.filter((b) => b.property === BINDING_PROP.ITEMS || b.type === "array");
|
|
512
|
+
const innerHtmlBinding = bindings.find((b) => b.property === BINDING_PROP.INNER_HTML);
|
|
513
|
+
let rawChildren;
|
|
514
|
+
if (innerHtmlBinding && node.children.length > 0) rawChildren = node.children.map((child) => generateCode(child)).join("").trim();
|
|
515
|
+
return {
|
|
516
|
+
tagName,
|
|
517
|
+
allAttrs,
|
|
518
|
+
dataAttrs,
|
|
519
|
+
bindings,
|
|
520
|
+
childrenBinding,
|
|
521
|
+
arrayBindings,
|
|
522
|
+
rawChildren
|
|
523
|
+
};
|
|
524
|
+
};
|
|
525
|
+
const parseToNodes = (raw) => {
|
|
526
|
+
const ast = (0, import_lib$2.parse)(wrap(raw), {
|
|
527
|
+
sourceType: "module",
|
|
528
|
+
plugins: ["jsx", "typescript"],
|
|
529
|
+
errorRecovery: true
|
|
530
|
+
});
|
|
531
|
+
const results = [];
|
|
532
|
+
const processedNodes = /* @__PURE__ */ new WeakSet();
|
|
533
|
+
(0, import_lib.default)(ast, { JSXElement(path) {
|
|
534
|
+
if (processedNodes.has(path.node)) return;
|
|
535
|
+
const { tagName, allAttrs, dataAttrs, bindings, childrenBinding, arrayBindings, rawChildren } = readNodeBindingInfo(path.node);
|
|
536
|
+
if (!tagName || !dataAttrs.length) return;
|
|
537
|
+
let childrenNodes;
|
|
538
|
+
if (childrenBinding) childrenNodes = processChildrenBinding(path.node, processedNodes);
|
|
539
|
+
for (const arrayBinding of arrayBindings) skipItemsChildren(path.node, processedNodes, arrayBinding.property);
|
|
540
|
+
results.push({
|
|
541
|
+
tagName,
|
|
542
|
+
attributes: allAttrs,
|
|
543
|
+
dataAttributes: dataAttrs,
|
|
544
|
+
textContent: collectText(path.node.children),
|
|
545
|
+
rawChildren,
|
|
546
|
+
children: childrenNodes,
|
|
547
|
+
bindings,
|
|
548
|
+
loc: path.node.loc ? {
|
|
549
|
+
start: {
|
|
550
|
+
line: path.node.loc.start.line,
|
|
551
|
+
column: path.node.loc.start.column
|
|
552
|
+
},
|
|
553
|
+
end: {
|
|
554
|
+
line: path.node.loc.end.line,
|
|
555
|
+
column: path.node.loc.end.column
|
|
556
|
+
}
|
|
557
|
+
} : void 0
|
|
558
|
+
});
|
|
559
|
+
} });
|
|
560
|
+
return results;
|
|
561
|
+
};
|
|
562
|
+
function extract(raw) {
|
|
563
|
+
if (extractCache.has(raw)) return extractCache.get(raw);
|
|
564
|
+
const results = parseToNodes(raw);
|
|
565
|
+
extractCache.set(raw, results);
|
|
566
|
+
return results;
|
|
567
|
+
}
|
|
568
|
+
function extractFromNode(node, processedNodes) {
|
|
569
|
+
processedNodes?.add(node);
|
|
570
|
+
const { tagName, allAttrs, dataAttrs, bindings, childrenBinding, rawChildren } = readNodeBindingInfo(node);
|
|
571
|
+
let childrenNodes;
|
|
572
|
+
if (childrenBinding) childrenNodes = processChildrenBinding(node, processedNodes);
|
|
573
|
+
if (!childrenNodes) childrenNodes = processChildrenBinding(node, processedNodes, false);
|
|
574
|
+
return [{
|
|
575
|
+
tagName,
|
|
576
|
+
attributes: allAttrs,
|
|
577
|
+
dataAttributes: dataAttrs,
|
|
578
|
+
textContent: collectText(node.children),
|
|
579
|
+
rawChildren,
|
|
580
|
+
children: childrenNodes,
|
|
581
|
+
bindings
|
|
582
|
+
}];
|
|
583
|
+
}
|
|
584
|
+
function clearExtractCache() {
|
|
585
|
+
extractCache.clear();
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
//#endregion
|
|
589
|
+
//#region src/utils/ast/update.ts
|
|
590
|
+
const updateInnerText = (path, value) => {
|
|
591
|
+
const jsxChildren = path.node.children;
|
|
592
|
+
for (let i = jsxChildren.length - 1; i >= 0; i--) if (import_lib$3.isJSXText(jsxChildren[i])) jsxChildren.splice(i, 1);
|
|
593
|
+
jsxChildren.push(import_lib$3.jsxText(value));
|
|
594
|
+
return true;
|
|
595
|
+
};
|
|
596
|
+
const injectPlaceholder = (prefix, value, placeholders, { asRawContent = false } = {}) => {
|
|
597
|
+
const name = `__${prefix}_${nanoid(6)}__`;
|
|
598
|
+
const container = import_lib$3.jsxExpressionContainer(import_lib$3.identifier(name));
|
|
599
|
+
placeholders.set(asRawContent ? `{${name}}` : name, value);
|
|
600
|
+
return container;
|
|
601
|
+
};
|
|
602
|
+
const updateInnerHTML = (path, value, placeholders) => {
|
|
603
|
+
path.node.children = [injectPlaceholder("HTML", value, placeholders, { asRawContent: true })];
|
|
604
|
+
return true;
|
|
605
|
+
};
|
|
606
|
+
const updateChildren = (path, value) => {
|
|
607
|
+
try {
|
|
608
|
+
const childrenData = JSON.parse(value);
|
|
609
|
+
path.node.children.length = 0;
|
|
610
|
+
childrenData.forEach((childData) => {
|
|
611
|
+
const jsxElement = nodeToJSX(childData);
|
|
612
|
+
if (jsxElement) path.node.children.push(jsxElement);
|
|
613
|
+
});
|
|
614
|
+
return true;
|
|
615
|
+
} catch (error) {
|
|
616
|
+
console.error("❌ Children update error:", error);
|
|
617
|
+
return false;
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
const updateRichtext = (path, value) => {
|
|
621
|
+
path.node.children = [];
|
|
622
|
+
const opening = path.node.openingElement;
|
|
623
|
+
const htmlObject = import_lib$3.objectExpression([import_lib$3.objectProperty(import_lib$3.identifier("__html"), import_lib$3.stringLiteral(value))]);
|
|
624
|
+
const existingAttr = opening.attributes.find((a) => import_lib$3.isJSXAttribute(a) && import_lib$3.isJSXIdentifier(a.name) && a.name.name === "dangerouslySetInnerHTML");
|
|
625
|
+
if (existingAttr && import_lib$3.isJSXAttribute(existingAttr)) existingAttr.value = import_lib$3.jsxExpressionContainer(htmlObject);
|
|
626
|
+
else opening.attributes.push(import_lib$3.jsxAttribute(import_lib$3.jsxIdentifier("dangerouslySetInnerHTML"), import_lib$3.jsxExpressionContainer(htmlObject)));
|
|
627
|
+
return true;
|
|
628
|
+
};
|
|
629
|
+
const updateAttribute = (opening, propertyName, value) => {
|
|
630
|
+
const customAttr = opening.attributes.find((attr) => import_lib$3.isJSXAttribute(attr) && import_lib$3.isJSXIdentifier(attr.name) && attr.name.name === propertyName);
|
|
631
|
+
if (customAttr && import_lib$3.isJSXAttribute(customAttr)) {
|
|
632
|
+
const trimmed = value.trim();
|
|
633
|
+
customAttr.value = attrValue({
|
|
634
|
+
name: propertyName,
|
|
635
|
+
value,
|
|
636
|
+
isStringLiteral: !(trimmed.startsWith("[") || trimmed.startsWith("{") || REGEX.NUMBER.test(trimmed) || REGEX.BOOLEAN_OR_NULL.test(trimmed))
|
|
637
|
+
});
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
return false;
|
|
641
|
+
};
|
|
642
|
+
const update = (code, dataId, label, value) => {
|
|
643
|
+
try {
|
|
644
|
+
const ast = (0, import_lib$2.parse)(wrap(code), {
|
|
645
|
+
sourceType: "module",
|
|
646
|
+
plugins: ["jsx", "typescript"]
|
|
647
|
+
});
|
|
648
|
+
let changed = false;
|
|
649
|
+
const jsxPlaceholders = /* @__PURE__ */ new Map();
|
|
650
|
+
(0, import_lib.default)(ast, { JSXElement(path) {
|
|
651
|
+
const opening = path.node.openingElement;
|
|
652
|
+
if (!opening.attributes.find((attr) => {
|
|
653
|
+
return import_lib$3.isJSXAttribute(attr) && import_lib$3.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.ID && attr.value && import_lib$3.isStringLiteral(attr.value) && attr.value.value === dataId;
|
|
654
|
+
})) return;
|
|
655
|
+
const bindingAttr = opening.attributes.find((attr) => import_lib$3.isJSXAttribute(attr) && import_lib$3.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING);
|
|
656
|
+
if (!bindingAttr?.value) return;
|
|
657
|
+
let bindingValue = "";
|
|
658
|
+
if (import_lib$3.isStringLiteral(bindingAttr.value)) bindingValue = bindingAttr.value.value;
|
|
659
|
+
else if (import_lib$3.isJSXExpressionContainer(bindingAttr.value)) try {
|
|
660
|
+
bindingValue = generateCode(bindingAttr.value.expression);
|
|
661
|
+
} catch {
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
const propertyBinding = parseBinding(bindingValue).find((binding) => binding.label === label);
|
|
665
|
+
if (!propertyBinding) return;
|
|
666
|
+
switch (propertyBinding.property) {
|
|
667
|
+
case BINDING_PROP.INNER_TEXT:
|
|
668
|
+
changed = updateInnerText(path, value);
|
|
669
|
+
break;
|
|
670
|
+
case BINDING_PROP.INNER_HTML:
|
|
671
|
+
if (propertyBinding.type === "richtext") changed = updateRichtext(path, value);
|
|
672
|
+
else changed = updateInnerHTML(path, value, jsxPlaceholders);
|
|
673
|
+
break;
|
|
674
|
+
case BINDING_PROP.CHILDREN:
|
|
675
|
+
changed = updateChildren(path, value);
|
|
676
|
+
break;
|
|
677
|
+
default:
|
|
678
|
+
if (propertyBinding.type === "jsx") {
|
|
679
|
+
const attr = opening.attributes.find((a) => import_lib$3.isJSXAttribute(a) && import_lib$3.isJSXIdentifier(a.name) && a.name.name === propertyBinding.property);
|
|
680
|
+
if (attr && import_lib$3.isJSXAttribute(attr)) {
|
|
681
|
+
attr.value = injectPlaceholder("JSX", value.trim(), jsxPlaceholders);
|
|
682
|
+
changed = true;
|
|
683
|
+
}
|
|
684
|
+
} else changed = updateAttribute(opening, propertyBinding.property, value);
|
|
685
|
+
break;
|
|
686
|
+
}
|
|
687
|
+
} });
|
|
688
|
+
if (!changed) return {
|
|
689
|
+
code,
|
|
690
|
+
success: false
|
|
691
|
+
};
|
|
692
|
+
let result = unwrap(generateCode(ast));
|
|
693
|
+
for (const [placeholder, original] of jsxPlaceholders) result = result.replace(placeholder, () => original);
|
|
694
|
+
return {
|
|
695
|
+
code: result,
|
|
696
|
+
success: true
|
|
697
|
+
};
|
|
698
|
+
} catch (error) {
|
|
699
|
+
console.error("❌ Code update error:", error);
|
|
700
|
+
return {
|
|
701
|
+
code,
|
|
702
|
+
success: false
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
const bulkUpdate = (raw, entries) => {
|
|
707
|
+
let current = raw;
|
|
708
|
+
let allSucceeded = true;
|
|
709
|
+
for (const entry of entries) {
|
|
710
|
+
const result = update(current, entry.dataId, entry.label, entry.value);
|
|
711
|
+
current = result.code;
|
|
712
|
+
allSucceeded = allSucceeded && result.success;
|
|
713
|
+
}
|
|
714
|
+
return {
|
|
715
|
+
code: current,
|
|
716
|
+
success: allSucceeded
|
|
717
|
+
};
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
//#endregion
|
|
721
|
+
//#region src/utils/ast/tree.ts
|
|
722
|
+
const replaceIds = (code, generateId = () => nanoid(6)) => {
|
|
723
|
+
return code.replace(new RegExp(`${DATA_ATTR.ID}="[^"]*"`, "g"), () => {
|
|
724
|
+
return `${DATA_ATTR.ID}="${generateId()}"`;
|
|
725
|
+
});
|
|
726
|
+
};
|
|
727
|
+
const fillIds = (code, generateId = () => nanoid(6)) => {
|
|
728
|
+
return code.replace(new RegExp(`${DATA_ATTR.ID}=""`, "g"), () => {
|
|
729
|
+
return `${DATA_ATTR.ID}="${generateId()}"`;
|
|
730
|
+
});
|
|
731
|
+
};
|
|
732
|
+
const clone = (element, generateId = () => nanoid(6)) => {
|
|
733
|
+
return (0, import_lib$2.parseExpression)(replaceIds(generateCode(import_lib$3.cloneNode(element, true)), generateId), { plugins: ["jsx", "typescript"] });
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
//#endregion
|
|
737
|
+
//#region src/utils/ast/validate.ts
|
|
738
|
+
const VALID = { valid: true };
|
|
739
|
+
const validateBindingValue = (binding, value) => {
|
|
740
|
+
if (value === "" || value === null || value === void 0) {
|
|
741
|
+
if (binding.required) return {
|
|
742
|
+
valid: false,
|
|
743
|
+
message: "This field is required."
|
|
744
|
+
};
|
|
745
|
+
return VALID;
|
|
746
|
+
}
|
|
747
|
+
if (typeof value === "number") {
|
|
748
|
+
if (binding.min !== void 0 && value < binding.min) return {
|
|
749
|
+
valid: false,
|
|
750
|
+
message: `Must be at least ${binding.min}.`
|
|
751
|
+
};
|
|
752
|
+
if (binding.max !== void 0 && value > binding.max) return {
|
|
753
|
+
valid: false,
|
|
754
|
+
message: `Must be at most ${binding.max}.`
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
if (typeof value === "string" && binding.pattern) {
|
|
758
|
+
let regex;
|
|
759
|
+
try {
|
|
760
|
+
regex = new RegExp(binding.pattern);
|
|
761
|
+
} catch {
|
|
762
|
+
return VALID;
|
|
763
|
+
}
|
|
764
|
+
if (!regex.test(value)) return {
|
|
765
|
+
valid: false,
|
|
766
|
+
message: "Value does not match the required format."
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
if (typeof value === "string" && binding.type === "url") try {
|
|
770
|
+
new URL(value);
|
|
771
|
+
} catch {
|
|
772
|
+
return {
|
|
773
|
+
valid: false,
|
|
774
|
+
message: "Must be a valid URL."
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
if (typeof value === "string" && binding.type === "date") {
|
|
778
|
+
if (Number.isNaN(Date.parse(value))) return {
|
|
779
|
+
valid: false,
|
|
780
|
+
message: "Must be a valid date."
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
return VALID;
|
|
784
|
+
};
|
|
785
|
+
|
|
786
|
+
//#endregion
|
|
787
|
+
export { parseArrayExpression as _, bulkUpdate as a, extract as c, getCurrentValue as d, parseBinding as f, extractObjectProperties as g, extractNodeValue as h, replaceIds as i, nanoid as l, createNodeFromValue as m, clone as n, update as o, arrayExpressionToCode as p, fillIds as r, clearExtractCache as s, validateBindingValue as t, findEditableChildren as u, parseValue as v, generateCode as y };
|
|
788
|
+
//# sourceMappingURL=ast-CXRFs1hO.mjs.map
|