@jbpark/live-editor 4.1.1 → 4.3.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-jab6hQrT.js → ast-BFbDWO-l.js} +288 -229
- package/dist/ast-BFbDWO-l.js.map +1 -0
- package/dist/{boundary-D2IFja-3.js → boundary-B17cepvm.js} +12 -9
- package/dist/boundary-B17cepvm.js.map +1 -0
- package/dist/{compile-CBOAtQMz.js → compile-0Dvp8zp5.js} +37 -5
- package/dist/compile-0Dvp8zp5.js.map +1 -0
- package/dist/{constants-BD3FZKWE.js → constants-CKvdqZtO.js} +11 -4
- package/dist/constants-CKvdqZtO.js.map +1 -0
- package/dist/{context-DQ-UtoyS.js → context-93X3gyfJ.js} +2 -2
- package/dist/{context-DQ-UtoyS.js.map → context-93X3gyfJ.js.map} +1 -1
- package/dist/{core-DaXVtvH5.js → core-B3ruccKb.js} +2 -2
- package/dist/{core-DaXVtvH5.js.map → core-B3ruccKb.js.map} +1 -1
- package/dist/{detect-typescript-b0A751v2.js → detect-typescript-5MV4mCM7.js} +2 -2
- package/dist/{detect-typescript-b0A751v2.js.map → detect-typescript-5MV4mCM7.js.map} +1 -1
- package/dist/dnd/index.d.ts +2 -2
- package/dist/dnd/index.js +2 -2
- package/dist/{dnd-CMrXfD8O.js → dnd-Z1KS16Fy.js} +969 -322
- package/dist/dnd-Z1KS16Fy.js.map +1 -0
- package/dist/{document-J9Lo9p81.d.ts → document-Ct4jW78J.d.ts} +42 -22
- package/dist/{document-C5Dypv4_.js → document-cEEdFERz.js} +138 -46
- package/dist/document-cEEdFERz.js.map +1 -0
- package/dist/editor/index.js +2 -2
- package/dist/{editor-C3tQaMlU.js → editor-DvMruljw.js} +2 -2
- package/dist/{editor-C3tQaMlU.js.map → editor-DvMruljw.js.map} +1 -1
- package/dist/error/index.d.ts +1 -1
- package/dist/error/index.js +2 -2
- package/dist/{error-KW8XCcjH.js → error-DWhxQEom.js} +2 -2
- package/dist/{error-KW8XCcjH.js.map → error-DWhxQEom.js.map} +1 -1
- package/dist/{index-DNNj_0ba.d.ts → index-C4SGQ3Ci.d.ts} +4 -3
- package/dist/{index-C4t0OawE.d.ts → index-CtlUYnWq.d.ts} +131 -34
- package/dist/{index-B_p74BRM.d.ts → index-w3kLcCXl.d.ts} +29 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/preview/index.js +2 -2
- package/dist/{preview-BwEfltgi.js → preview-C_UzpGWh.js} +3 -3
- package/dist/{preview-BwEfltgi.js.map → preview-C_UzpGWh.js.map} +1 -1
- package/dist/provider/index.js +1 -1
- package/dist/sections-GJQ63uEB.js +24 -0
- package/dist/sections-GJQ63uEB.js.map +1 -0
- package/dist/{use-dynamic-tailwind-DuGLeDR3.js → use-dynamic-tailwind-DpbjmATF.js} +20 -11
- package/dist/use-dynamic-tailwind-DpbjmATF.js.map +1 -0
- package/dist/utils/ast/index.d.ts +3 -3
- package/dist/utils/ast/index.js +3 -3
- package/dist/utils/index.d.ts +7 -6
- package/dist/utils/index.js +5 -5
- package/package.json +1 -1
- package/dist/ast-jab6hQrT.js.map +0 -1
- package/dist/boundary-D2IFja-3.js.map +0 -1
- package/dist/compile-CBOAtQMz.js.map +0 -1
- package/dist/constants-BD3FZKWE.js.map +0 -1
- package/dist/dnd-CMrXfD8O.js.map +0 -1
- package/dist/document-C5Dypv4_.js.map +0 -1
- package/dist/sections-B7dWoNVJ.js +0 -19
- package/dist/sections-B7dWoNVJ.js.map +0 -1
- package/dist/use-dynamic-tailwind-DuGLeDR3.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { C as require_lib, S as require_lib$1, _ as nanoid, b as unwrap, d as traverse, g as getJSXTagName, v as attrValue, w as __toESM, x as wrap, y as generateCode } from "./document-cEEdFERz.js";
|
|
2
|
+
import { c as RESERVED_BINDING_PROPERTIES, n as CONFIG, r as DATA_ATTR, s as REGEX, t as BINDING_PROP } from "./constants-CKvdqZtO.js";
|
|
3
3
|
import { n as registerEditorCache } from "./editor-caches-ClMvdcQF.js";
|
|
4
4
|
import { t as createBoundedCache } from "./cache-B0-XcIxJ.js";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
//#region src/utils/ast/types.ts
|
|
7
|
-
var import_lib
|
|
8
|
-
var import_lib$
|
|
7
|
+
var import_lib = require_lib();
|
|
8
|
+
var import_lib$1 = /* @__PURE__ */ __toESM(require_lib$1(), 1);
|
|
9
9
|
const BINDING_TYPES = [
|
|
10
10
|
"array",
|
|
11
11
|
"object",
|
|
@@ -19,35 +19,6 @@ const BINDING_TYPES = [
|
|
|
19
19
|
"url"
|
|
20
20
|
];
|
|
21
21
|
//#endregion
|
|
22
|
-
//#region src/utils/ast/helpers.ts
|
|
23
|
-
var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
|
|
24
|
-
const generate = typeof import_lib.default === "function" ? import_lib.default : import_lib.default.default;
|
|
25
|
-
const wrap = (code) => {
|
|
26
|
-
return `<>${code}</>`;
|
|
27
|
-
};
|
|
28
|
-
const unwrap = (generated) => {
|
|
29
|
-
return generated.replace(/^<>\s*/g, "").replace(/\s*<\/>\s*;?\s*$/g, "").trim();
|
|
30
|
-
};
|
|
31
|
-
const attrValue = ({ value, isStringLiteral }) => {
|
|
32
|
-
if (value === null) return null;
|
|
33
|
-
if (isStringLiteral) return import_lib$2.stringLiteral(value);
|
|
34
|
-
const trimmed = value.trim();
|
|
35
|
-
if (REGEX.NUMBER.test(trimmed)) return import_lib$2.jsxExpressionContainer(import_lib$2.numericLiteral(parseFloat(trimmed)));
|
|
36
|
-
if (REGEX.BOOLEAN_OR_NULL.test(trimmed)) {
|
|
37
|
-
const expr = (0, import_lib$1.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
|
|
38
|
-
return import_lib$2.jsxExpressionContainer(expr);
|
|
39
|
-
}
|
|
40
|
-
try {
|
|
41
|
-
const expr = (0, import_lib$1.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
|
|
42
|
-
return import_lib$2.jsxExpressionContainer(expr);
|
|
43
|
-
} catch {
|
|
44
|
-
return import_lib$2.stringLiteral(trimmed);
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
const generateCode = (node) => {
|
|
48
|
-
return generate(node, { jsescOption: { minimal: true } }).code;
|
|
49
|
-
};
|
|
50
|
-
//#endregion
|
|
51
22
|
//#region src/utils/ast/value.ts
|
|
52
23
|
const dedent = (str) => {
|
|
53
24
|
const lines = str.replace(/^\n/, "").replace(/\n\s*$/, "").split("\n");
|
|
@@ -60,44 +31,44 @@ const dedent = (str) => {
|
|
|
60
31
|
};
|
|
61
32
|
const unwrapExpression = (node) => {
|
|
62
33
|
let current = node;
|
|
63
|
-
while (import_lib$
|
|
34
|
+
while (import_lib$1.isTSAsExpression(current) || import_lib$1.isTSSatisfiesExpression(current) || import_lib$1.isTSNonNullExpression(current) || import_lib$1.isTSTypeAssertion(current) || import_lib$1.isParenthesizedExpression(current)) current = current.expression;
|
|
64
35
|
return current;
|
|
65
36
|
};
|
|
66
37
|
const isLosslesslyEvaluable = (node) => {
|
|
67
38
|
const value = unwrapExpression(node);
|
|
68
|
-
if (import_lib$
|
|
69
|
-
if (import_lib$
|
|
70
|
-
if (import_lib$
|
|
71
|
-
if (import_lib$
|
|
72
|
-
if (import_lib$
|
|
39
|
+
if (import_lib$1.isStringLiteral(value) || import_lib$1.isNumericLiteral(value) || import_lib$1.isBooleanLiteral(value) || import_lib$1.isNullLiteral(value)) return true;
|
|
40
|
+
if (import_lib$1.isUnaryExpression(value) && value.operator === "-" && import_lib$1.isNumericLiteral(value.argument)) return true;
|
|
41
|
+
if (import_lib$1.isTemplateLiteral(value)) return value.expressions.length === 0;
|
|
42
|
+
if (import_lib$1.isArrayExpression(value)) return value.elements.every((element) => element !== null && isLosslesslyEvaluable(element));
|
|
43
|
+
if (import_lib$1.isObjectExpression(value)) return value.properties.every((property) => import_lib$1.isObjectProperty(property) && !property.computed && (import_lib$1.isIdentifier(property.key) || import_lib$1.isStringLiteral(property.key) || import_lib$1.isNumericLiteral(property.key)) && isLosslesslyEvaluable(property.value));
|
|
73
44
|
return false;
|
|
74
45
|
};
|
|
75
46
|
const canLosslesslyEvaluateSource = (source) => {
|
|
76
47
|
try {
|
|
77
|
-
return isLosslesslyEvaluable((0, import_lib
|
|
48
|
+
return isLosslesslyEvaluable((0, import_lib.parseExpression)(source, { plugins: ["jsx", "typescript"] }));
|
|
78
49
|
} catch {
|
|
79
50
|
return false;
|
|
80
51
|
}
|
|
81
52
|
};
|
|
82
53
|
const evaluateLiteral = (rawNode) => {
|
|
83
54
|
const node = unwrapExpression(rawNode);
|
|
84
|
-
if (import_lib$
|
|
85
|
-
if (import_lib$
|
|
86
|
-
if (import_lib$
|
|
87
|
-
if (import_lib$
|
|
88
|
-
if (import_lib$
|
|
89
|
-
if (import_lib$
|
|
90
|
-
if (import_lib$
|
|
91
|
-
if (import_lib$
|
|
92
|
-
if (import_lib$
|
|
93
|
-
if (import_lib$
|
|
55
|
+
if (import_lib$1.isStringLiteral(node)) return node.value;
|
|
56
|
+
if (import_lib$1.isNumericLiteral(node)) return node.value;
|
|
57
|
+
if (import_lib$1.isBooleanLiteral(node)) return node.value;
|
|
58
|
+
if (import_lib$1.isNullLiteral(node)) return null;
|
|
59
|
+
if (import_lib$1.isIdentifier(node) && node.name === "undefined") return;
|
|
60
|
+
if (import_lib$1.isUnaryExpression(node) && node.operator === "-" && import_lib$1.isNumericLiteral(node.argument)) return -node.argument.value;
|
|
61
|
+
if (import_lib$1.isTemplateLiteral(node) && node.expressions.length === 0) return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw ?? "";
|
|
62
|
+
if (import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node)) return generateCode(node);
|
|
63
|
+
if (import_lib$1.isArrayExpression(node)) return node.elements.map((element) => element ? evaluateLiteral(element) : null);
|
|
64
|
+
if (import_lib$1.isObjectExpression(node)) {
|
|
94
65
|
const result = {};
|
|
95
66
|
for (const prop of node.properties) {
|
|
96
|
-
if (!import_lib$
|
|
67
|
+
if (!import_lib$1.isObjectProperty(prop)) continue;
|
|
97
68
|
let key = null;
|
|
98
|
-
if (import_lib$
|
|
99
|
-
else if (import_lib$
|
|
100
|
-
else if (import_lib$
|
|
69
|
+
if (import_lib$1.isIdentifier(prop.key)) key = prop.key.name;
|
|
70
|
+
else if (import_lib$1.isStringLiteral(prop.key)) key = prop.key.value;
|
|
71
|
+
else if (import_lib$1.isNumericLiteral(prop.key)) key = String(prop.key.value);
|
|
101
72
|
if (key === null) continue;
|
|
102
73
|
result[key] = evaluateLiteral(prop.value);
|
|
103
74
|
}
|
|
@@ -117,8 +88,8 @@ const parseValue = (value) => {
|
|
|
117
88
|
}
|
|
118
89
|
if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
119
90
|
try {
|
|
120
|
-
const ast = (0, import_lib
|
|
121
|
-
if (import_lib$
|
|
91
|
+
const ast = (0, import_lib.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
|
|
92
|
+
if (import_lib$1.isObjectExpression(ast) || import_lib$1.isArrayExpression(ast)) return evaluateLiteral(ast);
|
|
122
93
|
} catch {}
|
|
123
94
|
return value;
|
|
124
95
|
}
|
|
@@ -148,43 +119,80 @@ const flattenEditableValue = (value) => {
|
|
|
148
119
|
walk(parsed, [], 0);
|
|
149
120
|
return entries.length ? entries : null;
|
|
150
121
|
};
|
|
122
|
+
const findEditableLeaf = (root, path) => {
|
|
123
|
+
let node = unwrapExpression(root);
|
|
124
|
+
for (const segment of path) {
|
|
125
|
+
if (import_lib$1.isArrayExpression(node)) {
|
|
126
|
+
if (typeof segment !== "number") return null;
|
|
127
|
+
const elements = node.elements.slice(0, segment + 1);
|
|
128
|
+
const element = node.elements[segment];
|
|
129
|
+
if (!element || elements.some((item) => import_lib$1.isSpreadElement(item))) return null;
|
|
130
|
+
node = unwrapExpression(element);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (import_lib$1.isObjectExpression(node)) {
|
|
134
|
+
const key = String(segment);
|
|
135
|
+
const matches = (property) => import_lib$1.isObjectProperty(property) && !property.computed && (import_lib$1.isIdentifier(property.key) && property.key.name === key || import_lib$1.isStringLiteral(property.key) && property.key.value === key || import_lib$1.isNumericLiteral(property.key) && String(property.key.value) === key);
|
|
136
|
+
let index = node.properties.length - 1;
|
|
137
|
+
while (index >= 0 && !matches(node.properties[index])) index--;
|
|
138
|
+
const property = node.properties[index];
|
|
139
|
+
if (!property || !import_lib$1.isObjectProperty(property) || node.properties.slice(index + 1).some((item) => import_lib$1.isSpreadElement(item))) return null;
|
|
140
|
+
node = unwrapExpression(property.value);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
return node;
|
|
146
|
+
};
|
|
147
|
+
const isEditableLeaf = (node) => import_lib$1.isStringLiteral(node) || import_lib$1.isNumericLiteral(node) || import_lib$1.isBooleanLiteral(node) || import_lib$1.isUnaryExpression(node) && node.operator === "-" && import_lib$1.isNumericLiteral(node.argument) || import_lib$1.isTemplateLiteral(node) && node.expressions.length === 0 || import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node);
|
|
148
|
+
const quoteString = (text, quote) => {
|
|
149
|
+
if (quote === "`") return `\`${text.replace(/[\\`]|\$\{/g, (match) => `\\${match}`)}\``;
|
|
150
|
+
const escaped = JSON.stringify(text).slice(1, -1);
|
|
151
|
+
return quote === "\"" ? `"${escaped}"` : `'${escaped.replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
|
|
152
|
+
};
|
|
153
|
+
const isJSXSource = (text) => {
|
|
154
|
+
try {
|
|
155
|
+
const expression = (0, import_lib.parseExpression)(text, { plugins: ["jsx"] });
|
|
156
|
+
return import_lib$1.isJSXElement(expression) || import_lib$1.isJSXFragment(expression);
|
|
157
|
+
} catch {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const leafSource = (value, leaf, next) => {
|
|
162
|
+
if (typeof next !== "string") return String(next);
|
|
163
|
+
if ((import_lib$1.isJSXElement(leaf) || import_lib$1.isJSXFragment(leaf)) && isJSXSource(next)) return next.trim();
|
|
164
|
+
const quote = import_lib$1.isStringLiteral(leaf) || import_lib$1.isTemplateLiteral(leaf) ? value[leaf.start] : "'";
|
|
165
|
+
return quoteString(next, quote);
|
|
166
|
+
};
|
|
151
167
|
const setEditableValue = (value, path, next) => {
|
|
152
168
|
if (!path.length) return value;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const key = path[i];
|
|
159
|
-
const child = cursor[key];
|
|
160
|
-
if (typeof child !== "object" || child === null) return value;
|
|
161
|
-
const clonedChild = Array.isArray(child) ? [...child] : { ...child };
|
|
162
|
-
cursor[key] = clonedChild;
|
|
163
|
-
cursor = clonedChild;
|
|
169
|
+
let leaf;
|
|
170
|
+
try {
|
|
171
|
+
leaf = findEditableLeaf((0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] }), path);
|
|
172
|
+
} catch {
|
|
173
|
+
return value;
|
|
164
174
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
cursor[lastKey] = next;
|
|
168
|
-
return JSON.stringify(root);
|
|
175
|
+
if (!leaf || !isEditableLeaf(leaf) || leaf.start == null || leaf.end == null) return value;
|
|
176
|
+
return `${value.slice(0, leaf.start)}${leafSource(value, leaf, next)}${value.slice(leaf.end)}`;
|
|
169
177
|
};
|
|
170
178
|
const extractNodeValue = (node) => {
|
|
171
|
-
if (import_lib$
|
|
179
|
+
if (import_lib$1.isBooleanLiteral(node)) return {
|
|
172
180
|
type: "boolean",
|
|
173
181
|
value: node.value
|
|
174
182
|
};
|
|
175
|
-
if (import_lib$
|
|
183
|
+
if (import_lib$1.isNumericLiteral(node)) return {
|
|
176
184
|
type: "number",
|
|
177
185
|
value: node.value
|
|
178
186
|
};
|
|
179
|
-
if (import_lib$
|
|
187
|
+
if (import_lib$1.isUnaryExpression(node) && node.operator === "-" && import_lib$1.isNumericLiteral(node.argument)) return {
|
|
180
188
|
type: "number",
|
|
181
189
|
value: -node.argument.value
|
|
182
190
|
};
|
|
183
|
-
if (import_lib$
|
|
191
|
+
if (import_lib$1.isStringLiteral(node)) return {
|
|
184
192
|
type: "string",
|
|
185
193
|
value: node.value
|
|
186
194
|
};
|
|
187
|
-
if (import_lib$
|
|
195
|
+
if (import_lib$1.isTemplateLiteral(node)) {
|
|
188
196
|
if (node.expressions.length === 0 && node.quasis.length === 1) return {
|
|
189
197
|
type: "string",
|
|
190
198
|
value: dedent(node.quasis[0].value.cooked ?? node.quasis[0].value.raw)
|
|
@@ -194,19 +202,19 @@ const extractNodeValue = (node) => {
|
|
|
194
202
|
value: generateCode(node)
|
|
195
203
|
};
|
|
196
204
|
}
|
|
197
|
-
if (import_lib$
|
|
205
|
+
if (import_lib$1.isNullLiteral(node)) return {
|
|
198
206
|
type: "null",
|
|
199
207
|
value: null
|
|
200
208
|
};
|
|
201
|
-
if (import_lib$
|
|
209
|
+
if (import_lib$1.isArrayExpression(node)) return {
|
|
202
210
|
type: "array",
|
|
203
211
|
value: generateCode(node)
|
|
204
212
|
};
|
|
205
|
-
if (import_lib$
|
|
213
|
+
if (import_lib$1.isObjectExpression(node)) return {
|
|
206
214
|
type: "object",
|
|
207
215
|
value: generateCode(node)
|
|
208
216
|
};
|
|
209
|
-
if (import_lib$
|
|
217
|
+
if (import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node)) return {
|
|
210
218
|
type: "string",
|
|
211
219
|
value: generateCode(node)
|
|
212
220
|
};
|
|
@@ -217,10 +225,10 @@ const extractNodeValue = (node) => {
|
|
|
217
225
|
};
|
|
218
226
|
const createNodeFromValue = (type, value) => {
|
|
219
227
|
switch (type) {
|
|
220
|
-
case "boolean": return import_lib$
|
|
221
|
-
case "number": return import_lib$
|
|
222
|
-
case "string": return import_lib$
|
|
223
|
-
case "null": return import_lib$
|
|
228
|
+
case "boolean": return import_lib$1.booleanLiteral(value === true);
|
|
229
|
+
case "number": return import_lib$1.numericLiteral(Number(value));
|
|
230
|
+
case "string": return import_lib$1.stringLiteral(String(value));
|
|
231
|
+
case "null": return import_lib$1.nullLiteral();
|
|
224
232
|
case "array":
|
|
225
233
|
case "object":
|
|
226
234
|
case "unknown": return null;
|
|
@@ -228,26 +236,26 @@ const createNodeFromValue = (type, value) => {
|
|
|
228
236
|
}
|
|
229
237
|
};
|
|
230
238
|
const valueToExpression = (value) => {
|
|
231
|
-
if (typeof value === "string") return import_lib$
|
|
232
|
-
if (typeof value === "number") return value < 0 ? import_lib$
|
|
233
|
-
if (typeof value === "boolean") return import_lib$
|
|
234
|
-
if (value === null) return import_lib$
|
|
235
|
-
if (Array.isArray(value)) return import_lib$
|
|
239
|
+
if (typeof value === "string") return import_lib$1.stringLiteral(value);
|
|
240
|
+
if (typeof value === "number") return value < 0 ? import_lib$1.unaryExpression("-", import_lib$1.numericLiteral(-value)) : import_lib$1.numericLiteral(value);
|
|
241
|
+
if (typeof value === "boolean") return import_lib$1.booleanLiteral(value);
|
|
242
|
+
if (value === null) return import_lib$1.nullLiteral();
|
|
243
|
+
if (Array.isArray(value)) return import_lib$1.arrayExpression(value.map((item) => valueToExpression(item) ?? import_lib$1.nullLiteral()));
|
|
236
244
|
if (typeof value === "object") {
|
|
237
245
|
const properties = [];
|
|
238
246
|
for (const [key, item] of Object.entries(value)) {
|
|
239
247
|
const expr = valueToExpression(item);
|
|
240
248
|
if (expr === null) continue;
|
|
241
|
-
properties.push(import_lib$
|
|
249
|
+
properties.push(import_lib$1.objectProperty(import_lib$1.stringLiteral(key), expr));
|
|
242
250
|
}
|
|
243
|
-
return import_lib$
|
|
251
|
+
return import_lib$1.objectExpression(properties);
|
|
244
252
|
}
|
|
245
253
|
return null;
|
|
246
254
|
};
|
|
247
255
|
const parseArrayExpression = (value) => {
|
|
248
256
|
try {
|
|
249
|
-
const ast = unwrapExpression((0, import_lib
|
|
250
|
-
if (!import_lib$
|
|
257
|
+
const ast = unwrapExpression((0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] }));
|
|
258
|
+
if (!import_lib$1.isArrayExpression(ast)) return null;
|
|
251
259
|
return ast;
|
|
252
260
|
} catch (error) {
|
|
253
261
|
console.error("❌ Array parsing error:", error);
|
|
@@ -257,9 +265,9 @@ const parseArrayExpression = (value) => {
|
|
|
257
265
|
const extractObjectProperties = (element) => {
|
|
258
266
|
const properties = {};
|
|
259
267
|
element.properties.forEach((prop) => {
|
|
260
|
-
if (import_lib$
|
|
268
|
+
if (import_lib$1.isObjectProperty(prop) && import_lib$1.isIdentifier(prop.key)) {
|
|
261
269
|
const key = prop.key.name;
|
|
262
|
-
if (key === "children" || import_lib$
|
|
270
|
+
if (key === "children" || import_lib$1.isJSXElement(prop.value) || import_lib$1.isJSXFragment(prop.value)) return;
|
|
263
271
|
const extracted = extractNodeValue(prop.value);
|
|
264
272
|
properties[key] = {
|
|
265
273
|
...extracted,
|
|
@@ -270,7 +278,7 @@ const extractObjectProperties = (element) => {
|
|
|
270
278
|
return properties;
|
|
271
279
|
};
|
|
272
280
|
const arrayExpressionToCode = (elements) => {
|
|
273
|
-
const nextAst = import_lib$
|
|
281
|
+
const nextAst = import_lib$1.arrayExpression(elements);
|
|
274
282
|
return generateCode(nextAst);
|
|
275
283
|
};
|
|
276
284
|
//#endregion
|
|
@@ -377,12 +385,12 @@ const getCurrentValue = (node, property) => {
|
|
|
377
385
|
case BINDING_PROP.INNER_HTML: {
|
|
378
386
|
const dsiAttr = node.attributes.find((a) => a.name === "dangerouslySetInnerHTML");
|
|
379
387
|
if (dsiAttr?.value) try {
|
|
380
|
-
const expr = (0, import_lib
|
|
381
|
-
if (import_lib$
|
|
382
|
-
const htmlProp = expr.properties.find((p) => import_lib$
|
|
388
|
+
const expr = (0, import_lib.parseExpression)(dsiAttr.value, { plugins: ["jsx", "typescript"] });
|
|
389
|
+
if (import_lib$1.isObjectExpression(expr)) {
|
|
390
|
+
const htmlProp = expr.properties.find((p) => import_lib$1.isObjectProperty(p) && import_lib$1.isIdentifier(p.key) && p.key.name === "__html");
|
|
383
391
|
if (htmlProp) {
|
|
384
|
-
if (import_lib$
|
|
385
|
-
if (import_lib$
|
|
392
|
+
if (import_lib$1.isStringLiteral(htmlProp.value)) return htmlProp.value.value;
|
|
393
|
+
if (import_lib$1.isTemplateLiteral(htmlProp.value) && htmlProp.value.expressions.length === 0) return htmlProp.value.quasis[0]?.value.cooked ?? htmlProp.value.quasis[0]?.value.raw ?? "";
|
|
386
394
|
}
|
|
387
395
|
}
|
|
388
396
|
} catch {}
|
|
@@ -549,7 +557,7 @@ const commaIn = (source, start, end) => {
|
|
|
549
557
|
};
|
|
550
558
|
const denseArraySource = (source) => {
|
|
551
559
|
const array = parseArrayExpression(source);
|
|
552
|
-
if (!array || array.elements.some((node) => !import_lib$
|
|
560
|
+
if (!array || array.elements.some((node) => !import_lib$1.isExpression(node) || node.extra?.parenthesized)) return null;
|
|
553
561
|
const elements = array.elements;
|
|
554
562
|
const commas = elements.slice(0, -1).map((node, index) => commaIn(source, node.end, elements[index + 1].start));
|
|
555
563
|
if (commas.some((comma) => comma === null)) return null;
|
|
@@ -609,9 +617,9 @@ const appendArraySource = (source, data, copies) => {
|
|
|
609
617
|
//#endregion
|
|
610
618
|
//#region src/utils/ast/items.ts
|
|
611
619
|
const elementsOf = (code) => parseArrayExpression(code)?.elements ?? null;
|
|
612
|
-
const kindOf = (element) => import_lib$
|
|
620
|
+
const kindOf = (element) => import_lib$1.isObjectExpression(element) ? "object" : "primitive";
|
|
613
621
|
const parseItems = (code) => {
|
|
614
|
-
return elementsOf(code)?.flatMap((node, index) => import_lib$
|
|
622
|
+
return elementsOf(code)?.flatMap((node, index) => import_lib$1.isExpression(node) ? [{
|
|
615
623
|
index,
|
|
616
624
|
kind: kindOf(node),
|
|
617
625
|
node
|
|
@@ -627,23 +635,23 @@ const toTemplateRaw = (value) => {
|
|
|
627
635
|
const buildPropertyValue = (value, declaredType, renderLeaf, current) => {
|
|
628
636
|
if (renderLeaf?.property === BINDING_PROP.INNER_HTML) {
|
|
629
637
|
const raw = String(value);
|
|
630
|
-
return import_lib$
|
|
638
|
+
return import_lib$1.templateLiteral([import_lib$1.templateElement({
|
|
631
639
|
raw: toTemplateRaw(raw),
|
|
632
640
|
cooked: raw
|
|
633
641
|
}, true)], []);
|
|
634
642
|
}
|
|
635
|
-
if (renderLeaf?.type === "jsx" || import_lib$
|
|
643
|
+
if (renderLeaf?.type === "jsx" || import_lib$1.isJSXElement(current) || import_lib$1.isJSXFragment(current)) {
|
|
636
644
|
const trimmed = String(value).trim();
|
|
637
|
-
if (!trimmed.startsWith("<")) return import_lib$
|
|
645
|
+
if (!trimmed.startsWith("<")) return import_lib$1.stringLiteral(trimmed);
|
|
638
646
|
try {
|
|
639
|
-
return (0, import_lib
|
|
647
|
+
return (0, import_lib.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
|
|
640
648
|
} catch {
|
|
641
649
|
return;
|
|
642
650
|
}
|
|
643
651
|
}
|
|
644
652
|
if (declaredType === "array" || declaredType === "object") {
|
|
645
653
|
if (typeof value === "string") try {
|
|
646
|
-
return (0, import_lib
|
|
654
|
+
return (0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] });
|
|
647
655
|
} catch {
|
|
648
656
|
return;
|
|
649
657
|
}
|
|
@@ -655,13 +663,13 @@ const buildPropertyValue = (value, declaredType, renderLeaf, current) => {
|
|
|
655
663
|
const updateArrayItemProperty = (code, index, key, value, render) => {
|
|
656
664
|
const elements = elementsOf(code);
|
|
657
665
|
const element = elements?.[index];
|
|
658
|
-
if (!elements || !import_lib$
|
|
659
|
-
const target = element.properties.find((property) => import_lib$
|
|
666
|
+
if (!elements || !import_lib$1.isObjectExpression(element)) return null;
|
|
667
|
+
const target = element.properties.find((property) => import_lib$1.isObjectProperty(property) && import_lib$1.isIdentifier(property.key) && property.key.name === key);
|
|
660
668
|
if (!target) return null;
|
|
661
669
|
const declaredType = extractObjectProperties(element)[key]?.type ?? "string";
|
|
662
670
|
const nextValue = buildPropertyValue(value, declaredType, resolveRenderLeaf(render, key), target.value);
|
|
663
671
|
if (!nextValue) return null;
|
|
664
|
-
let serialized = typeof value === "string" && (declaredType === "array" || declaredType === "object" || import_lib$
|
|
672
|
+
let serialized = typeof value === "string" && (declaredType === "array" || declaredType === "object" || import_lib$1.isJSXElement(nextValue) || import_lib$1.isJSXFragment(nextValue)) ? value.trim() : generateCode(nextValue);
|
|
665
673
|
if (nextValue.trailingComments?.some((comment) => comment.type === "CommentLine")) serialized += "\n";
|
|
666
674
|
const content = target.shorthand ? `${key}: ${serialized}` : serialized;
|
|
667
675
|
return applyEdits(code, [{
|
|
@@ -673,7 +681,7 @@ const updateArrayItemProperty = (code, index, key, value, render) => {
|
|
|
673
681
|
const updateArrayItemValue = (code, index, value) => {
|
|
674
682
|
const elements = elementsOf(code);
|
|
675
683
|
const element = elements?.[index];
|
|
676
|
-
if (!elements || !import_lib$
|
|
684
|
+
if (!elements || !import_lib$1.isExpression(element)) return null;
|
|
677
685
|
const nextValue = createNodeFromValue(extractNodeValue(element).type, parseValue(value));
|
|
678
686
|
if (!nextValue) return null;
|
|
679
687
|
return applyEdits(code, [{
|
|
@@ -714,25 +722,25 @@ const copyItem = (code, element, generateId, usedIds) => {
|
|
|
714
722
|
usedIds.add(id);
|
|
715
723
|
return JSON.stringify(id);
|
|
716
724
|
};
|
|
717
|
-
import_lib$
|
|
718
|
-
if (!import_lib$
|
|
719
|
-
const ids = node.attributes.filter((attr) => import_lib$
|
|
725
|
+
import_lib$1.traverseFast(element, (node) => {
|
|
726
|
+
if (!import_lib$1.isJSXOpeningElement(node)) return;
|
|
727
|
+
const ids = node.attributes.filter((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name, { name: "data-id" }));
|
|
720
728
|
const attr = ids[0];
|
|
721
|
-
if (ids.length > 1 || attr && (!import_lib$
|
|
729
|
+
if (ids.length > 1 || attr && (!import_lib$1.isStringLiteral(attr.value) || node.attributes.slice(node.attributes.indexOf(attr) + 1).some((a) => import_lib$1.isJSXSpreadAttribute(a)))) {
|
|
722
730
|
unsupported = true;
|
|
723
731
|
return;
|
|
724
732
|
}
|
|
725
|
-
if (attr && import_lib$
|
|
733
|
+
if (attr && import_lib$1.isStringLiteral(attr.value)) edits.push({
|
|
726
734
|
start: attr.value.start,
|
|
727
735
|
end: attr.value.end,
|
|
728
736
|
content: reserveId(generateId())
|
|
729
737
|
});
|
|
730
738
|
});
|
|
731
|
-
if (import_lib$
|
|
732
|
-
const keys = element.properties.filter((prop) => import_lib$
|
|
739
|
+
if (import_lib$1.isObjectExpression(element)) {
|
|
740
|
+
const keys = element.properties.filter((prop) => import_lib$1.isObjectProperty(prop) && !prop.computed && (import_lib$1.isIdentifier(prop.key, { name: "key" }) || import_lib$1.isStringLiteral(prop.key, { value: "key" })));
|
|
733
741
|
const key = keys[0];
|
|
734
|
-
if (keys.length > 1 || key && (!import_lib$
|
|
735
|
-
if (key && import_lib$
|
|
742
|
+
if (keys.length > 1 || key && (!import_lib$1.isStringLiteral(key.value) || element.properties.slice(element.properties.indexOf(key) + 1).some((prop) => import_lib$1.isSpreadElement(prop) || "computed" in prop && prop.computed))) return null;
|
|
743
|
+
if (key && import_lib$1.isStringLiteral(key.value)) edits.push({
|
|
736
744
|
start: key.value.start,
|
|
737
745
|
end: key.value.end,
|
|
738
746
|
content: reserveId(`${key.value.value}-${generateId()}`)
|
|
@@ -749,9 +757,9 @@ const duplicateArrayItems = (code, indices, generateId = () => nanoid(6)) => {
|
|
|
749
757
|
const data = denseArraySource(code);
|
|
750
758
|
if (!data || !indices.size || !validArrayIndices(indices, data.elements.length)) return null;
|
|
751
759
|
const usedIds = /* @__PURE__ */ new Set();
|
|
752
|
-
import_lib$
|
|
753
|
-
if (import_lib$
|
|
754
|
-
else if (import_lib$
|
|
760
|
+
import_lib$1.traverseFast(data.array, (node) => {
|
|
761
|
+
if (import_lib$1.isJSXAttribute(node) && import_lib$1.isJSXIdentifier(node.name, { name: "data-id" }) && import_lib$1.isStringLiteral(node.value)) usedIds.add(node.value.value);
|
|
762
|
+
else if (import_lib$1.isObjectProperty(node) && !node.computed && (import_lib$1.isIdentifier(node.key, { name: "key" }) || import_lib$1.isStringLiteral(node.key, { value: "key" })) && import_lib$1.isStringLiteral(node.value)) usedIds.add(node.value.value);
|
|
755
763
|
});
|
|
756
764
|
const copies = [...indices].sort((a, b) => a - b).map((index) => copyItem(code, data.elements[index], generateId, usedIds));
|
|
757
765
|
return copies.every((copy) => copy !== null) ? appendArraySource(code, data, copies) : null;
|
|
@@ -763,31 +771,13 @@ const appendArrayItem = (code, kind, generateId = () => nanoid(6)) => {
|
|
|
763
771
|
//#endregion
|
|
764
772
|
//#region src/utils/ast/extract.ts
|
|
765
773
|
const collectText = (children) => {
|
|
766
|
-
return children.filter((c) => import_lib$
|
|
767
|
-
};
|
|
768
|
-
const getTagName = (opening) => {
|
|
769
|
-
if (import_lib$2.isJSXIdentifier(opening.name)) return opening.name.name;
|
|
770
|
-
if (import_lib$2.isJSXMemberExpression(opening.name)) return resolveMemberName(opening.name);
|
|
771
|
-
return "";
|
|
772
|
-
};
|
|
773
|
-
const resolveMemberName = (expr) => {
|
|
774
|
-
const parts = [];
|
|
775
|
-
const collectMemberParts = (node) => {
|
|
776
|
-
if (import_lib$2.isJSXIdentifier(node)) parts.push(node.name);
|
|
777
|
-
else if (import_lib$2.isJSXMemberExpression(node)) {
|
|
778
|
-
collectMemberParts(node.object);
|
|
779
|
-
if (import_lib$2.isJSXIdentifier(node.property)) parts.push(node.property.name);
|
|
780
|
-
}
|
|
781
|
-
};
|
|
782
|
-
collectMemberParts(expr.object);
|
|
783
|
-
if (import_lib$2.isJSXIdentifier(expr.property)) parts.push(expr.property.name);
|
|
784
|
-
return parts.join(".");
|
|
774
|
+
return children.filter((c) => import_lib$1.isJSXText(c)).map((c) => c.value.trim()).filter((v) => v.length).join(" ");
|
|
785
775
|
};
|
|
786
776
|
const parseJSXName = (tagName) => {
|
|
787
777
|
const parts = tagName.split(".");
|
|
788
|
-
if (parts.length === 1) return import_lib$
|
|
789
|
-
let expr = import_lib$
|
|
790
|
-
for (let i = 1; i < parts.length; i++) expr = import_lib$
|
|
778
|
+
if (parts.length === 1) return import_lib$1.jsxIdentifier(parts[0]);
|
|
779
|
+
let expr = import_lib$1.jsxIdentifier(parts[0]);
|
|
780
|
+
for (let i = 1; i < parts.length; i++) expr = import_lib$1.jsxMemberExpression(expr, import_lib$1.jsxIdentifier(parts[i]));
|
|
791
781
|
return expr;
|
|
792
782
|
};
|
|
793
783
|
const extractCache = createBoundedCache(CONFIG.CACHE_LIMIT);
|
|
@@ -795,17 +785,17 @@ const extractAttributes = (attributes, source) => {
|
|
|
795
785
|
const allAttrs = [];
|
|
796
786
|
const dataAttrs = [];
|
|
797
787
|
for (const attr of attributes) {
|
|
798
|
-
if (!import_lib$
|
|
788
|
+
if (!import_lib$1.isJSXAttribute(attr) || !import_lib$1.isJSXIdentifier(attr.name)) continue;
|
|
799
789
|
const name = attr.name.name;
|
|
800
790
|
let value = null;
|
|
801
791
|
let isStringLiteral = false;
|
|
802
792
|
if (attr.value) {
|
|
803
|
-
if (import_lib$
|
|
793
|
+
if (import_lib$1.isStringLiteral(attr.value)) {
|
|
804
794
|
value = attr.value.value;
|
|
805
795
|
isStringLiteral = true;
|
|
806
|
-
} else if (import_lib$
|
|
796
|
+
} else if (import_lib$1.isJSXExpressionContainer(attr.value)) try {
|
|
807
797
|
const expression = attr.value.expression;
|
|
808
|
-
const structural = import_lib$
|
|
798
|
+
const structural = import_lib$1.isArrayExpression(unwrapExpression(expression)) || import_lib$1.isObjectExpression(unwrapExpression(expression));
|
|
809
799
|
value = source && structural && expression.start != null && expression.end != null ? source.slice(expression.start, expression.end) : generateCode(expression);
|
|
810
800
|
isStringLiteral = false;
|
|
811
801
|
} catch {
|
|
@@ -827,7 +817,7 @@ const extractAttributes = (attributes, source) => {
|
|
|
827
817
|
};
|
|
828
818
|
const buildChildElements = (node) => {
|
|
829
819
|
const childElements = [];
|
|
830
|
-
if (node.textContent) childElements.push(import_lib$
|
|
820
|
+
if (node.textContent) childElements.push(import_lib$1.jsxText(node.textContent));
|
|
831
821
|
node.children?.forEach((child) => {
|
|
832
822
|
const childJSX = nodeToJSX(child);
|
|
833
823
|
if (childJSX) childElements.push(childJSX);
|
|
@@ -838,22 +828,22 @@ const nodeToJSX = (node) => {
|
|
|
838
828
|
try {
|
|
839
829
|
if (node.isFragment) {
|
|
840
830
|
const childElements = buildChildElements(node);
|
|
841
|
-
return import_lib$
|
|
831
|
+
return import_lib$1.jsxFragment(import_lib$1.jsxOpeningFragment(), import_lib$1.jsxClosingFragment(), childElements);
|
|
842
832
|
}
|
|
843
833
|
if (node.tagName === "div" && node.dataAttributes.some((attr) => attr.name === "data-item")) {
|
|
844
834
|
if (node.children) return nodeToJSX(node.children[0]);
|
|
845
835
|
return null;
|
|
846
836
|
}
|
|
847
837
|
const attributes = node.attributes.map((attr) => {
|
|
848
|
-
const attrName = import_lib$
|
|
849
|
-
if (!attr.value) return import_lib$
|
|
850
|
-
return import_lib$
|
|
838
|
+
const attrName = import_lib$1.jsxIdentifier(attr.name);
|
|
839
|
+
if (!attr.value) return import_lib$1.jsxAttribute(attrName, null);
|
|
840
|
+
return import_lib$1.jsxAttribute(attrName, attrValue(attr));
|
|
851
841
|
});
|
|
852
842
|
const elementName = parseJSXName(node.tagName);
|
|
853
|
-
const openingElement = import_lib$
|
|
854
|
-
const closingElement = import_lib$
|
|
843
|
+
const openingElement = import_lib$1.jsxOpeningElement(elementName, attributes);
|
|
844
|
+
const closingElement = import_lib$1.jsxClosingElement(elementName);
|
|
855
845
|
const children = buildChildElements(node);
|
|
856
|
-
return import_lib$
|
|
846
|
+
return import_lib$1.jsxElement(openingElement, closingElement, children, false);
|
|
857
847
|
} catch (error) {
|
|
858
848
|
console.error("❌ DataAttrNode to JSX conversion error:", error);
|
|
859
849
|
return null;
|
|
@@ -883,11 +873,11 @@ const createFragmentNode = (textContent, children) => ({
|
|
|
883
873
|
isFragment: true
|
|
884
874
|
});
|
|
885
875
|
const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, source) => {
|
|
886
|
-
const jsxChildren = jsxElement.children.filter((child) => import_lib$
|
|
876
|
+
const jsxChildren = jsxElement.children.filter((child) => import_lib$1.isJSXElement(child) || import_lib$1.isJSXFragment(child));
|
|
887
877
|
if (!jsxChildren.length) return;
|
|
888
878
|
const childrenNodes = [];
|
|
889
879
|
jsxChildren.forEach((child) => {
|
|
890
|
-
if (import_lib$
|
|
880
|
+
if (import_lib$1.isJSXElement(child)) {
|
|
891
881
|
const childResults = extractFromNode(child, processedNodes, source);
|
|
892
882
|
if (shouldWrap) {
|
|
893
883
|
const wrapperNode = createWrapperNode(collectText(child.children), childResults);
|
|
@@ -896,11 +886,11 @@ const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, s
|
|
|
896
886
|
if (dataId) wrapperNode.id = `child:${dataId}`;
|
|
897
887
|
childrenNodes.push(wrapperNode);
|
|
898
888
|
} else childrenNodes.push(...childResults);
|
|
899
|
-
} else if (import_lib$
|
|
889
|
+
} else if (import_lib$1.isJSXFragment(child)) {
|
|
900
890
|
processedNodes?.add(child);
|
|
901
891
|
const fragmentChildren = [];
|
|
902
892
|
child.children.forEach((fragmentChild) => {
|
|
903
|
-
if (import_lib$
|
|
893
|
+
if (import_lib$1.isJSXElement(fragmentChild)) {
|
|
904
894
|
const childResults = extractFromNode(fragmentChild, processedNodes, source);
|
|
905
895
|
fragmentChildren.push(...childResults);
|
|
906
896
|
}
|
|
@@ -915,32 +905,32 @@ const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, s
|
|
|
915
905
|
return childrenNodes.length ? childrenNodes : void 0;
|
|
916
906
|
};
|
|
917
907
|
const skipItemsChildren = (jsxElement, processedNodes, propertyName = "items") => {
|
|
918
|
-
const itemsAttr = jsxElement.openingElement.attributes.find((attr) => import_lib$
|
|
919
|
-
if (!itemsAttr || !import_lib$
|
|
920
|
-
if (itemsAttr.value && import_lib$
|
|
921
|
-
if (import_lib$
|
|
922
|
-
if (import_lib$
|
|
908
|
+
const itemsAttr = jsxElement.openingElement.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === propertyName);
|
|
909
|
+
if (!itemsAttr || !import_lib$1.isJSXAttribute(itemsAttr)) return;
|
|
910
|
+
if (itemsAttr.value && import_lib$1.isJSXExpressionContainer(itemsAttr.value) && import_lib$1.isArrayExpression(itemsAttr.value.expression)) itemsAttr.value.expression.elements.forEach((element) => {
|
|
911
|
+
if (import_lib$1.isObjectExpression(element)) element.properties.forEach((prop) => {
|
|
912
|
+
if (import_lib$1.isObjectProperty(prop) && import_lib$1.isIdentifier(prop.key) && import_lib$1.isJSXElement(prop.value)) markProcessedJSX(prop.value, processedNodes);
|
|
923
913
|
});
|
|
924
914
|
});
|
|
925
915
|
};
|
|
926
916
|
const markProcessedJSX = (node, processedNodes) => {
|
|
927
|
-
if (import_lib$
|
|
917
|
+
if (import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node)) {
|
|
928
918
|
processedNodes.add(node);
|
|
929
919
|
node.children.forEach((child) => markProcessedJSX(child, processedNodes));
|
|
930
920
|
return;
|
|
931
921
|
}
|
|
932
|
-
if (import_lib$
|
|
922
|
+
if (import_lib$1.isJSXExpressionContainer(node) || import_lib$1.isParenthesizedExpression(node)) markProcessedJSX(node.expression, processedNodes);
|
|
933
923
|
};
|
|
934
924
|
const getBindingExpression = (opening) => {
|
|
935
|
-
for (const attr of opening.attributes) if (import_lib$
|
|
925
|
+
for (const attr of opening.attributes) if (import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING && attr.value && import_lib$1.isJSXExpressionContainer(attr.value)) {
|
|
936
926
|
const expression = unwrapExpression(attr.value.expression);
|
|
937
|
-
if (import_lib$
|
|
927
|
+
if (import_lib$1.isArrayExpression(expression)) return expression;
|
|
938
928
|
}
|
|
939
929
|
return null;
|
|
940
930
|
};
|
|
941
931
|
const readNodeBindingInfo = (node, source) => {
|
|
942
932
|
const opening = node.openingElement;
|
|
943
|
-
const tagName =
|
|
933
|
+
const tagName = getJSXTagName(opening);
|
|
944
934
|
const { allAttrs, dataAttrs } = extractAttributes(opening.attributes, source);
|
|
945
935
|
const bindingAttr = dataAttrs.find((attr) => attr.name === DATA_ATTR.BINDING);
|
|
946
936
|
const bindingExpr = getBindingExpression(opening);
|
|
@@ -962,7 +952,7 @@ const readNodeBindingInfo = (node, source) => {
|
|
|
962
952
|
};
|
|
963
953
|
const parseToNodes = (raw) => {
|
|
964
954
|
const wrapped = wrap(raw);
|
|
965
|
-
const ast = (0, import_lib
|
|
955
|
+
const ast = (0, import_lib.parse)(wrapped, {
|
|
966
956
|
sourceType: "module",
|
|
967
957
|
plugins: ["jsx", "typescript"],
|
|
968
958
|
errorRecovery: true
|
|
@@ -1037,7 +1027,7 @@ const getChildrenSignatures = (nodes) => {
|
|
|
1037
1027
|
};
|
|
1038
1028
|
const indicesAreValid = (indices, count) => Array.isArray(indices) && new Set(indices).size === indices.length && indices.every((index) => Number.isInteger(index) && index >= 0 && index < count);
|
|
1039
1029
|
const copySource = (source, usedIds) => {
|
|
1040
|
-
const node = (0, import_lib
|
|
1030
|
+
const node = (0, import_lib.parseExpression)(source, { plugins: ["jsx", "typescript"] });
|
|
1041
1031
|
const edits = [];
|
|
1042
1032
|
const newId = () => {
|
|
1043
1033
|
let id = nanoid(12);
|
|
@@ -1045,15 +1035,15 @@ const copySource = (source, usedIds) => {
|
|
|
1045
1035
|
usedIds.add(id);
|
|
1046
1036
|
return id;
|
|
1047
1037
|
};
|
|
1048
|
-
import_lib$
|
|
1049
|
-
if (!import_lib$
|
|
1050
|
-
const ids = child.attributes.filter((attr) => import_lib$
|
|
1038
|
+
import_lib$1.traverseFast(node, (child) => {
|
|
1039
|
+
if (!import_lib$1.isJSXOpeningElement(child)) return;
|
|
1040
|
+
const ids = child.attributes.filter((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name, { name: "data-id" }));
|
|
1051
1041
|
if (ids.length > 1) throw new Error("Duplicate data-id attributes");
|
|
1052
1042
|
const attr = ids[0];
|
|
1053
|
-
if (attr && child.attributes.slice(child.attributes.indexOf(attr) + 1).some((attribute) => import_lib$
|
|
1043
|
+
if (attr && child.attributes.slice(child.attributes.indexOf(attr) + 1).some((attribute) => import_lib$1.isJSXSpreadAttribute(attribute))) throw new Error("A spread may override the copied data-id");
|
|
1054
1044
|
if (attr) {
|
|
1055
1045
|
const value = attr.value;
|
|
1056
|
-
if (!import_lib$
|
|
1046
|
+
if (!import_lib$1.isStringLiteral(value) || value.start == null || value.end == null) throw new Error("Cannot copy a dynamic data-id");
|
|
1057
1047
|
edits.push({
|
|
1058
1048
|
start: value.start,
|
|
1059
1049
|
end: value.end,
|
|
@@ -1075,7 +1065,7 @@ const editChildrenSource = (source, parent, input) => {
|
|
|
1075
1065
|
try {
|
|
1076
1066
|
if (!parent.closingElement || parent.start == null || parent.end == null) return null;
|
|
1077
1067
|
const value = typeof input === "string" ? JSON.parse(input) : input;
|
|
1078
|
-
const children = parent.children.filter((child) => import_lib$
|
|
1068
|
+
const children = parent.children.filter((child) => import_lib$1.isJSXElement(child) || import_lib$1.isJSXFragment(child));
|
|
1079
1069
|
const raw = children.map((child) => source.slice(child.start, child.end));
|
|
1080
1070
|
const models = extract(source.slice(parent.start, parent.end))[0]?.children ?? [];
|
|
1081
1071
|
if (models.length !== children.length) return null;
|
|
@@ -1098,7 +1088,7 @@ const editChildrenSource = (source, parent, input) => {
|
|
|
1098
1088
|
};
|
|
1099
1089
|
if (Array.isArray(value)) {
|
|
1100
1090
|
const desired = modeledSignatures(value);
|
|
1101
|
-
const lossless = raw.every((text, index) => generateCode((0, import_lib
|
|
1091
|
+
const lossless = raw.every((text, index) => generateCode((0, import_lib.parseExpression)(text, { plugins: ["jsx", "typescript"] })) === signatures[index]);
|
|
1102
1092
|
const consumed = /* @__PURE__ */ new Set();
|
|
1103
1093
|
const next = desired.map((signature, position) => {
|
|
1104
1094
|
const index = signatures.findIndex((candidate, i) => candidate === signature && !consumed.has(i) && (value[position].source === void 0 || value[position].source === raw[i]));
|
|
@@ -1111,8 +1101,8 @@ const editChildrenSource = (source, parent, input) => {
|
|
|
1111
1101
|
});
|
|
1112
1102
|
const countIds = (text) => {
|
|
1113
1103
|
const counts = /* @__PURE__ */ new Map();
|
|
1114
|
-
import_lib$
|
|
1115
|
-
if (import_lib$
|
|
1104
|
+
import_lib$1.traverseFast((0, import_lib.parseExpression)(text, { plugins: ["jsx", "typescript"] }), (node) => {
|
|
1105
|
+
if (import_lib$1.isJSXAttribute(node) && import_lib$1.isJSXIdentifier(node.name, { name: "data-id" }) && import_lib$1.isStringLiteral(node.value)) counts.set(node.value.value, (counts.get(node.value.value) ?? 0) + 1);
|
|
1116
1106
|
});
|
|
1117
1107
|
return counts;
|
|
1118
1108
|
};
|
|
@@ -1124,8 +1114,8 @@ const editChildrenSource = (source, parent, input) => {
|
|
|
1124
1114
|
if (request?.kind !== "children-edit" || !Array.isArray(request.expected) || request.expected.length !== signatures.length || !getChildrenSignatures(models).every((signature, index) => signature === request.expected[index]) || !request.action) return null;
|
|
1125
1115
|
const { action } = request;
|
|
1126
1116
|
const usedIds = /* @__PURE__ */ new Set();
|
|
1127
|
-
import_lib$
|
|
1128
|
-
if (import_lib$
|
|
1117
|
+
import_lib$1.traverseFast(parent, (node) => {
|
|
1118
|
+
if (import_lib$1.isJSXAttribute(node) && import_lib$1.isJSXIdentifier(node.name, { name: "data-id" }) && import_lib$1.isStringLiteral(node.value)) usedIds.add(node.value.value);
|
|
1129
1119
|
});
|
|
1130
1120
|
switch (action.type) {
|
|
1131
1121
|
case "move": {
|
|
@@ -1181,7 +1171,7 @@ const childrenRange = (element) => {
|
|
|
1181
1171
|
};
|
|
1182
1172
|
};
|
|
1183
1173
|
const findAttribute = (opening, propertyName) => {
|
|
1184
|
-
return opening.attributes.find((attr) => import_lib$
|
|
1174
|
+
return opening.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === propertyName);
|
|
1185
1175
|
};
|
|
1186
1176
|
const attributeInsertPoint = (opening) => {
|
|
1187
1177
|
return opening.attributes[opening.attributes.length - 1]?.end ?? opening.name.end ?? null;
|
|
@@ -1190,7 +1180,7 @@ const editInnerText = (source, element, value) => {
|
|
|
1190
1180
|
const range = childrenRange(element);
|
|
1191
1181
|
if (!range) return [];
|
|
1192
1182
|
const [only] = element.children;
|
|
1193
|
-
if (element.children.length === 1 && import_lib$
|
|
1183
|
+
if (element.children.length === 1 && import_lib$1.isJSXText(only) && only.start != null && only.end != null) {
|
|
1194
1184
|
const raw = source.slice(only.start, only.end);
|
|
1195
1185
|
if (raw.trim() !== "") {
|
|
1196
1186
|
const leading = raw.length - raw.trimStart().length;
|
|
@@ -1203,7 +1193,7 @@ const editInnerText = (source, element, value) => {
|
|
|
1203
1193
|
}
|
|
1204
1194
|
}
|
|
1205
1195
|
const edits = [];
|
|
1206
|
-
for (const child of element.children) if (import_lib$
|
|
1196
|
+
for (const child of element.children) if (import_lib$1.isJSXText(child) && child.start != null && child.end != null) edits.push({
|
|
1207
1197
|
start: child.start,
|
|
1208
1198
|
end: child.end,
|
|
1209
1199
|
content: ""
|
|
@@ -1233,7 +1223,7 @@ const editRichtext = (element, value) => {
|
|
|
1233
1223
|
content: ""
|
|
1234
1224
|
});
|
|
1235
1225
|
const opening = element.openingElement;
|
|
1236
|
-
const attribute = import_lib$
|
|
1226
|
+
const attribute = import_lib$1.jsxAttribute(import_lib$1.jsxIdentifier("dangerouslySetInnerHTML"), import_lib$1.jsxExpressionContainer(import_lib$1.objectExpression([import_lib$1.objectProperty(import_lib$1.identifier("__html"), import_lib$1.stringLiteral(value))])));
|
|
1237
1227
|
const content = generateCode(attribute);
|
|
1238
1228
|
const existing = findAttribute(opening, "dangerouslySetInnerHTML");
|
|
1239
1229
|
if (existing && existing.start != null && existing.end != null) {
|
|
@@ -1272,11 +1262,11 @@ const editJsxAttribute = (opening, propertyName, value) => {
|
|
|
1272
1262
|
content: `=${content}`
|
|
1273
1263
|
}];
|
|
1274
1264
|
};
|
|
1275
|
-
const holdsStructuralExpression = (value) => import_lib$
|
|
1265
|
+
const holdsStructuralExpression = (value) => import_lib$1.isJSXExpressionContainer(value) && (import_lib$1.isArrayExpression(unwrapExpression(value.expression)) || import_lib$1.isObjectExpression(unwrapExpression(value.expression)));
|
|
1276
1266
|
const structuralSource = (value) => {
|
|
1277
1267
|
try {
|
|
1278
|
-
const expression = (0, import_lib
|
|
1279
|
-
return import_lib$
|
|
1268
|
+
const expression = (0, import_lib.parseExpression)(value.trim(), { plugins: ["jsx", "typescript"] });
|
|
1269
|
+
return import_lib$1.isArrayExpression(unwrapExpression(expression)) || import_lib$1.isObjectExpression(unwrapExpression(expression)) ? expression : null;
|
|
1280
1270
|
} catch {
|
|
1281
1271
|
return null;
|
|
1282
1272
|
}
|
|
@@ -1284,29 +1274,29 @@ const structuralSource = (value) => {
|
|
|
1284
1274
|
const buildAttributeValue = (value, type, current) => {
|
|
1285
1275
|
if (type === "array" || type === "object") {
|
|
1286
1276
|
if (typeof value === "string") try {
|
|
1287
|
-
return import_lib$
|
|
1277
|
+
return import_lib$1.jsxExpressionContainer((0, import_lib.parseExpression)(value.trim(), { plugins: ["jsx", "typescript"] }));
|
|
1288
1278
|
} catch {
|
|
1289
|
-
return import_lib$
|
|
1279
|
+
return import_lib$1.stringLiteral(value);
|
|
1290
1280
|
}
|
|
1291
1281
|
const expr = valueToExpression(value);
|
|
1292
|
-
return expr ? import_lib$
|
|
1282
|
+
return expr ? import_lib$1.jsxExpressionContainer(expr) : import_lib$1.stringLiteral("");
|
|
1293
1283
|
}
|
|
1294
1284
|
if (typeof value === "string") {
|
|
1295
1285
|
if (holdsStructuralExpression(current) && !(type && STRING_VALUED_TYPES.has(type))) {
|
|
1296
1286
|
const structural = structuralSource(value);
|
|
1297
|
-
if (structural) return import_lib$
|
|
1287
|
+
if (structural) return import_lib$1.jsxExpressionContainer(structural);
|
|
1298
1288
|
}
|
|
1299
|
-
return import_lib$
|
|
1289
|
+
return import_lib$1.stringLiteral(value);
|
|
1300
1290
|
}
|
|
1301
1291
|
const expr = valueToExpression(value);
|
|
1302
|
-
return expr ? import_lib$
|
|
1292
|
+
return expr ? import_lib$1.jsxExpressionContainer(expr) : import_lib$1.stringLiteral(String(value));
|
|
1303
1293
|
};
|
|
1304
1294
|
const editAttribute = (opening, propertyName, value, type) => {
|
|
1305
1295
|
const attribute = findAttribute(opening, propertyName);
|
|
1306
1296
|
if (!attribute || attribute.start == null || attribute.end == null) return null;
|
|
1307
1297
|
if (typeof value === "string" && (type === "array" || type === "object" || holdsStructuralExpression(attribute.value) && !(type && STRING_VALUED_TYPES.has(type)))) {
|
|
1308
1298
|
const expression = structuralSource(value);
|
|
1309
|
-
if (expression && import_lib$
|
|
1299
|
+
if (expression && import_lib$1.isJSXExpressionContainer(attribute.value)) {
|
|
1310
1300
|
const text = value.trim();
|
|
1311
1301
|
const lineComment = expression.trailingComments?.some((comment) => comment.type === "CommentLine");
|
|
1312
1302
|
return [{
|
|
@@ -1316,7 +1306,7 @@ const editAttribute = (opening, propertyName, value, type) => {
|
|
|
1316
1306
|
}];
|
|
1317
1307
|
}
|
|
1318
1308
|
}
|
|
1319
|
-
const content = generateCode(import_lib$
|
|
1309
|
+
const content = generateCode(import_lib$1.jsxAttribute(attribute.name, buildAttributeValue(value, type, attribute.value)));
|
|
1320
1310
|
return [{
|
|
1321
1311
|
start: attribute.start,
|
|
1322
1312
|
end: attribute.end,
|
|
@@ -1324,14 +1314,36 @@ const editAttribute = (opening, propertyName, value, type) => {
|
|
|
1324
1314
|
indent: true
|
|
1325
1315
|
}];
|
|
1326
1316
|
};
|
|
1317
|
+
const removeAttribute = (source, attribute) => {
|
|
1318
|
+
if (attribute.start == null || attribute.end == null) return null;
|
|
1319
|
+
let start = attribute.start;
|
|
1320
|
+
while (start > 0 && /\s/.test(source[start - 1])) start -= 1;
|
|
1321
|
+
return [{
|
|
1322
|
+
start,
|
|
1323
|
+
end: attribute.end,
|
|
1324
|
+
content: ""
|
|
1325
|
+
}];
|
|
1326
|
+
};
|
|
1327
|
+
const addAttribute = (source, opening, propertyName, value, type) => {
|
|
1328
|
+
const insertAt = attributeInsertPoint(opening);
|
|
1329
|
+
if (insertAt == null) return null;
|
|
1330
|
+
const lastStart = opening.attributes[opening.attributes.length - 1]?.start;
|
|
1331
|
+
const lineStart = lastStart == null ? -1 : source.lastIndexOf("\n", lastStart - 1) + 1;
|
|
1332
|
+
return [{
|
|
1333
|
+
start: insertAt,
|
|
1334
|
+
end: insertAt,
|
|
1335
|
+
content: `${lastStart != null && lineStart > 0 && /^\s*$/.test(source.slice(lineStart, lastStart)) ? "\n" : " "}${type === "jsx" ? `${propertyName}={${String(value).trim()}}` : generateCode(import_lib$1.jsxAttribute(import_lib$1.jsxIdentifier(propertyName), buildAttributeValue(value, type)))}`,
|
|
1336
|
+
indent: true
|
|
1337
|
+
}];
|
|
1338
|
+
};
|
|
1327
1339
|
const canEditAttributeValue = (attribute, value, type) => {
|
|
1328
|
-
if (!import_lib$
|
|
1340
|
+
if (!import_lib$1.isJSXExpressionContainer(attribute.value) || import_lib$1.isJSXEmptyExpression(attribute.value.expression) || isLosslesslyEvaluable(attribute.value.expression)) return true;
|
|
1329
1341
|
return typeof value === "string" && holdsStructuralExpression(attribute.value) && !(type && STRING_VALUED_TYPES.has(type)) && structuralSource(value) !== null;
|
|
1330
1342
|
};
|
|
1331
1343
|
const update = (code, dataId, label, value, property) => {
|
|
1332
1344
|
try {
|
|
1333
1345
|
const wrapped = wrap(code);
|
|
1334
|
-
const ast = (0, import_lib
|
|
1346
|
+
const ast = (0, import_lib.parse)(wrapped, {
|
|
1335
1347
|
sourceType: "module",
|
|
1336
1348
|
plugins: ["jsx", "typescript"]
|
|
1337
1349
|
});
|
|
@@ -1349,9 +1361,9 @@ const update = (code, dataId, label, value, property) => {
|
|
|
1349
1361
|
traverse(ast, { JSXElement(path) {
|
|
1350
1362
|
const opening = path.node.openingElement;
|
|
1351
1363
|
if (!opening.attributes.find((attr) => {
|
|
1352
|
-
return import_lib$
|
|
1364
|
+
return import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.ID && attr.value && import_lib$1.isStringLiteral(attr.value) && attr.value.value === dataId;
|
|
1353
1365
|
})) return;
|
|
1354
|
-
const bindingAttr = opening.attributes.find((attr) => import_lib$
|
|
1366
|
+
const bindingAttr = opening.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING);
|
|
1355
1367
|
if (!bindingAttr?.value) {
|
|
1356
1368
|
failure = {
|
|
1357
1369
|
reason: "no-binding",
|
|
@@ -1360,8 +1372,8 @@ const update = (code, dataId, label, value, property) => {
|
|
|
1360
1372
|
return;
|
|
1361
1373
|
}
|
|
1362
1374
|
let bindingValue = "";
|
|
1363
|
-
if (import_lib$
|
|
1364
|
-
else if (import_lib$
|
|
1375
|
+
if (import_lib$1.isStringLiteral(bindingAttr.value)) bindingValue = bindingAttr.value.value;
|
|
1376
|
+
else if (import_lib$1.isJSXExpressionContainer(bindingAttr.value)) try {
|
|
1365
1377
|
bindingValue = generateCode(bindingAttr.value.expression);
|
|
1366
1378
|
} catch (error) {
|
|
1367
1379
|
failure = {
|
|
@@ -1392,20 +1404,45 @@ const update = (code, dataId, label, value, property) => {
|
|
|
1392
1404
|
}
|
|
1393
1405
|
const propertyBinding = matches[0];
|
|
1394
1406
|
const prop = propertyBinding.property;
|
|
1407
|
+
if (RESERVED_BINDING_PROPERTIES.includes(prop)) {
|
|
1408
|
+
failure = {
|
|
1409
|
+
reason: "reserved-property",
|
|
1410
|
+
dataId,
|
|
1411
|
+
property: prop
|
|
1412
|
+
};
|
|
1413
|
+
return;
|
|
1414
|
+
}
|
|
1415
|
+
const unset = value === void 0;
|
|
1416
|
+
if (unset && propertyBinding.required) {
|
|
1417
|
+
failure = {
|
|
1418
|
+
reason: "required-property",
|
|
1419
|
+
dataId,
|
|
1420
|
+
property: prop
|
|
1421
|
+
};
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1395
1424
|
switch (prop) {
|
|
1396
1425
|
case BINDING_PROP.INNER_TEXT:
|
|
1397
|
-
collect(editInnerText(wrapped, path.node, String(value)), () => ({
|
|
1426
|
+
collect(editInnerText(wrapped, path.node, unset ? "" : String(value)), () => ({
|
|
1398
1427
|
reason: "parse-error",
|
|
1399
1428
|
error: /* @__PURE__ */ new Error(`could not update "${prop}"`)
|
|
1400
1429
|
}));
|
|
1401
1430
|
break;
|
|
1402
1431
|
case BINDING_PROP.INNER_HTML:
|
|
1403
|
-
collect(propertyBinding.type === "richtext" ? editRichtext(path.node, String(value)) : editInnerHTML(path.node, String(value)), () => ({
|
|
1432
|
+
collect(propertyBinding.type === "richtext" ? editRichtext(path.node, unset ? "" : String(value)) : editInnerHTML(path.node, unset ? "" : String(value)), () => ({
|
|
1404
1433
|
reason: "parse-error",
|
|
1405
1434
|
error: /* @__PURE__ */ new Error(`could not update "${prop}"`)
|
|
1406
1435
|
}));
|
|
1407
1436
|
break;
|
|
1408
1437
|
case BINDING_PROP.CHILDREN:
|
|
1438
|
+
if (unset) {
|
|
1439
|
+
failure = {
|
|
1440
|
+
reason: "unsupported-syntax",
|
|
1441
|
+
dataId,
|
|
1442
|
+
property: prop
|
|
1443
|
+
};
|
|
1444
|
+
break;
|
|
1445
|
+
}
|
|
1409
1446
|
collect(editChildrenSource(wrapped, path.node, value), () => ({
|
|
1410
1447
|
reason: "parse-error",
|
|
1411
1448
|
error: /* @__PURE__ */ new Error("Unsupported or stale children edit; source was preserved")
|
|
@@ -1413,6 +1450,21 @@ const update = (code, dataId, label, value, property) => {
|
|
|
1413
1450
|
break;
|
|
1414
1451
|
default: {
|
|
1415
1452
|
const attribute = findAttribute(opening, prop);
|
|
1453
|
+
if (unset) {
|
|
1454
|
+
collect(attribute ? removeAttribute(wrapped, attribute) : [], () => ({
|
|
1455
|
+
reason: "parse-error",
|
|
1456
|
+
error: /* @__PURE__ */ new Error(`could not remove "${prop}"`)
|
|
1457
|
+
}));
|
|
1458
|
+
break;
|
|
1459
|
+
}
|
|
1460
|
+
if (!attribute) {
|
|
1461
|
+
collect(value === "" ? [] : addAttribute(wrapped, opening, prop, value, propertyBinding.type), () => ({
|
|
1462
|
+
reason: "attribute-not-found",
|
|
1463
|
+
dataId,
|
|
1464
|
+
property: prop
|
|
1465
|
+
}));
|
|
1466
|
+
break;
|
|
1467
|
+
}
|
|
1416
1468
|
if (attribute && propertyBinding.type !== "jsx" && !canEditAttributeValue(attribute, value, propertyBinding.type)) {
|
|
1417
1469
|
failure = {
|
|
1418
1470
|
reason: "unsupported-syntax",
|
|
@@ -1454,6 +1506,31 @@ const update = (code, dataId, label, value, property) => {
|
|
|
1454
1506
|
};
|
|
1455
1507
|
}
|
|
1456
1508
|
};
|
|
1509
|
+
const updateAll = (raw, entries) => {
|
|
1510
|
+
let current = raw;
|
|
1511
|
+
for (const [index, entry] of entries.entries()) {
|
|
1512
|
+
const result = update(current, entry.dataId, entry.label, entry.value, entry.property);
|
|
1513
|
+
if (!result.success) return {
|
|
1514
|
+
success: false,
|
|
1515
|
+
code: raw,
|
|
1516
|
+
failure: result.failure ?? {
|
|
1517
|
+
reason: "element-not-found",
|
|
1518
|
+
dataId: entry.dataId
|
|
1519
|
+
},
|
|
1520
|
+
index
|
|
1521
|
+
};
|
|
1522
|
+
current = result.code;
|
|
1523
|
+
}
|
|
1524
|
+
return {
|
|
1525
|
+
success: true,
|
|
1526
|
+
code: current
|
|
1527
|
+
};
|
|
1528
|
+
};
|
|
1529
|
+
/**
|
|
1530
|
+
* @deprecated Not atomic: when an entry fails, the ones before and after it
|
|
1531
|
+
* are still applied, and the returned `code` carries them. Use `updateAll`,
|
|
1532
|
+
* which applies every entry or none. Will be removed in the next major.
|
|
1533
|
+
*/
|
|
1457
1534
|
const bulkUpdate = (raw, entries) => {
|
|
1458
1535
|
let current = raw;
|
|
1459
1536
|
const failures = [];
|
|
@@ -1472,24 +1549,6 @@ const bulkUpdate = (raw, entries) => {
|
|
|
1472
1549
|
};
|
|
1473
1550
|
};
|
|
1474
1551
|
//#endregion
|
|
1475
|
-
//#region src/utils/ast/tree.ts
|
|
1476
|
-
const replaceIds = (code, generateId = () => nanoid(6)) => {
|
|
1477
|
-
return code.replace(new RegExp(`${DATA_ATTR.ID}="[^"]*"`, "g"), () => {
|
|
1478
|
-
return `${DATA_ATTR.ID}="${generateId()}"`;
|
|
1479
|
-
});
|
|
1480
|
-
};
|
|
1481
|
-
const fillIds = (code, generateId = () => nanoid(6)) => {
|
|
1482
|
-
return code.replace(new RegExp(`${DATA_ATTR.ID}=""`, "g"), () => {
|
|
1483
|
-
return `${DATA_ATTR.ID}="${generateId()}"`;
|
|
1484
|
-
});
|
|
1485
|
-
};
|
|
1486
|
-
const clone = (element, generateId = () => nanoid(6)) => {
|
|
1487
|
-
const cloned = import_lib$2.cloneNode(element, true);
|
|
1488
|
-
const generatedCode = generateCode(cloned);
|
|
1489
|
-
const code = replaceIds(generatedCode, generateId);
|
|
1490
|
-
return (0, import_lib$1.parseExpression)(code, { plugins: ["jsx", "typescript"] });
|
|
1491
|
-
};
|
|
1492
|
-
//#endregion
|
|
1493
1552
|
//#region src/utils/ast/validate.ts
|
|
1494
1553
|
const VALID = { valid: true };
|
|
1495
1554
|
const validateBindingValue = (binding, value) => {
|
|
@@ -1539,6 +1598,6 @@ const validateBindingValue = (binding, value) => {
|
|
|
1539
1598
|
return VALID;
|
|
1540
1599
|
};
|
|
1541
1600
|
//#endregion
|
|
1542
|
-
export {
|
|
1601
|
+
export { parseValue as A, arrayExpressionToCode as C, extractObjectProperties as D, extractNodeValue as E, flattenEditableValue as O, parseBindingExpression as S, createNodeFromValue as T, moveSelectedIndices as _, getChildrenSignatures as a, getStructuredValue as b, appendArrayItem as c, moveArrayItems as d, parseItems as f, canStructurallyEditArray as g, updateArrayItemValue as h, updateAll as i, setEditableValue as j, parseArrayExpression as k, duplicateArrayItems as l, updateArrayItemProperty as m, bulkUpdate as n, clearExtractCache as o, removeArrayItems as p, update as r, extract as s, validateBindingValue as t, moveArrayItem as u, findEditableChildren as v, canLosslesslyEvaluateSource as w, parseBinding as x, getCurrentValue as y };
|
|
1543
1602
|
|
|
1544
|
-
//# sourceMappingURL=ast-
|
|
1603
|
+
//# sourceMappingURL=ast-BFbDWO-l.js.map
|