@jbpark/live-editor 4.2.0 → 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/dist/{ast-CMD20ykx.js → ast-BFbDWO-l.js} +198 -208
- 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/dnd/index.d.ts +2 -2
- package/dist/dnd/index.js +2 -2
- package/dist/{dnd-DBaH2L8N.js → dnd-Z1KS16Fy.js} +462 -222
- package/dist/dnd-Z1KS16Fy.js.map +1 -0
- package/dist/{document-C3eCRQlj.js → document-cEEdFERz.js} +79 -20
- package/dist/document-cEEdFERz.js.map +1 -0
- 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-DVgwXnPa.d.ts → index-CtlUYnWq.d.ts} +25 -3
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/preview/index.js +2 -2
- package/dist/{preview-B9Jhv1Up.js → preview-C_UzpGWh.js} +3 -3
- package/dist/{preview-B9Jhv1Up.js.map → preview-C_UzpGWh.js.map} +1 -1
- package/dist/{sections-A4TAXUP8.js → sections-GJQ63uEB.js} +2 -2
- package/dist/{sections-A4TAXUP8.js.map → sections-GJQ63uEB.js.map} +1 -1
- package/dist/{use-dynamic-tailwind-BDfytfYC.js → use-dynamic-tailwind-DpbjmATF.js} +5 -5
- package/dist/use-dynamic-tailwind-DpbjmATF.js.map +1 -0
- package/dist/utils/ast/index.js +2 -2
- package/dist/utils/index.js +2 -2
- package/package.json +1 -1
- package/dist/ast-CMD20ykx.js.map +0 -1
- package/dist/boundary-D2IFja-3.js.map +0 -1
- package/dist/dnd-DBaH2L8N.js.map +0 -1
- package/dist/document-C3eCRQlj.js.map +0 -1
- package/dist/use-dynamic-tailwind-BDfytfYC.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { _ as
|
|
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
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,13 +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$
|
|
774
|
+
return children.filter((c) => import_lib$1.isJSXText(c)).map((c) => c.value.trim()).filter((v) => v.length).join(" ");
|
|
767
775
|
};
|
|
768
776
|
const parseJSXName = (tagName) => {
|
|
769
777
|
const parts = tagName.split(".");
|
|
770
|
-
if (parts.length === 1) return import_lib$
|
|
771
|
-
let expr = import_lib$
|
|
772
|
-
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]));
|
|
773
781
|
return expr;
|
|
774
782
|
};
|
|
775
783
|
const extractCache = createBoundedCache(CONFIG.CACHE_LIMIT);
|
|
@@ -777,17 +785,17 @@ const extractAttributes = (attributes, source) => {
|
|
|
777
785
|
const allAttrs = [];
|
|
778
786
|
const dataAttrs = [];
|
|
779
787
|
for (const attr of attributes) {
|
|
780
|
-
if (!import_lib$
|
|
788
|
+
if (!import_lib$1.isJSXAttribute(attr) || !import_lib$1.isJSXIdentifier(attr.name)) continue;
|
|
781
789
|
const name = attr.name.name;
|
|
782
790
|
let value = null;
|
|
783
791
|
let isStringLiteral = false;
|
|
784
792
|
if (attr.value) {
|
|
785
|
-
if (import_lib$
|
|
793
|
+
if (import_lib$1.isStringLiteral(attr.value)) {
|
|
786
794
|
value = attr.value.value;
|
|
787
795
|
isStringLiteral = true;
|
|
788
|
-
} else if (import_lib$
|
|
796
|
+
} else if (import_lib$1.isJSXExpressionContainer(attr.value)) try {
|
|
789
797
|
const expression = attr.value.expression;
|
|
790
|
-
const structural = import_lib$
|
|
798
|
+
const structural = import_lib$1.isArrayExpression(unwrapExpression(expression)) || import_lib$1.isObjectExpression(unwrapExpression(expression));
|
|
791
799
|
value = source && structural && expression.start != null && expression.end != null ? source.slice(expression.start, expression.end) : generateCode(expression);
|
|
792
800
|
isStringLiteral = false;
|
|
793
801
|
} catch {
|
|
@@ -809,7 +817,7 @@ const extractAttributes = (attributes, source) => {
|
|
|
809
817
|
};
|
|
810
818
|
const buildChildElements = (node) => {
|
|
811
819
|
const childElements = [];
|
|
812
|
-
if (node.textContent) childElements.push(import_lib$
|
|
820
|
+
if (node.textContent) childElements.push(import_lib$1.jsxText(node.textContent));
|
|
813
821
|
node.children?.forEach((child) => {
|
|
814
822
|
const childJSX = nodeToJSX(child);
|
|
815
823
|
if (childJSX) childElements.push(childJSX);
|
|
@@ -820,22 +828,22 @@ const nodeToJSX = (node) => {
|
|
|
820
828
|
try {
|
|
821
829
|
if (node.isFragment) {
|
|
822
830
|
const childElements = buildChildElements(node);
|
|
823
|
-
return import_lib$
|
|
831
|
+
return import_lib$1.jsxFragment(import_lib$1.jsxOpeningFragment(), import_lib$1.jsxClosingFragment(), childElements);
|
|
824
832
|
}
|
|
825
833
|
if (node.tagName === "div" && node.dataAttributes.some((attr) => attr.name === "data-item")) {
|
|
826
834
|
if (node.children) return nodeToJSX(node.children[0]);
|
|
827
835
|
return null;
|
|
828
836
|
}
|
|
829
837
|
const attributes = node.attributes.map((attr) => {
|
|
830
|
-
const attrName = import_lib$
|
|
831
|
-
if (!attr.value) return import_lib$
|
|
832
|
-
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));
|
|
833
841
|
});
|
|
834
842
|
const elementName = parseJSXName(node.tagName);
|
|
835
|
-
const openingElement = import_lib$
|
|
836
|
-
const closingElement = import_lib$
|
|
843
|
+
const openingElement = import_lib$1.jsxOpeningElement(elementName, attributes);
|
|
844
|
+
const closingElement = import_lib$1.jsxClosingElement(elementName);
|
|
837
845
|
const children = buildChildElements(node);
|
|
838
|
-
return import_lib$
|
|
846
|
+
return import_lib$1.jsxElement(openingElement, closingElement, children, false);
|
|
839
847
|
} catch (error) {
|
|
840
848
|
console.error("❌ DataAttrNode to JSX conversion error:", error);
|
|
841
849
|
return null;
|
|
@@ -865,11 +873,11 @@ const createFragmentNode = (textContent, children) => ({
|
|
|
865
873
|
isFragment: true
|
|
866
874
|
});
|
|
867
875
|
const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, source) => {
|
|
868
|
-
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));
|
|
869
877
|
if (!jsxChildren.length) return;
|
|
870
878
|
const childrenNodes = [];
|
|
871
879
|
jsxChildren.forEach((child) => {
|
|
872
|
-
if (import_lib$
|
|
880
|
+
if (import_lib$1.isJSXElement(child)) {
|
|
873
881
|
const childResults = extractFromNode(child, processedNodes, source);
|
|
874
882
|
if (shouldWrap) {
|
|
875
883
|
const wrapperNode = createWrapperNode(collectText(child.children), childResults);
|
|
@@ -878,11 +886,11 @@ const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, s
|
|
|
878
886
|
if (dataId) wrapperNode.id = `child:${dataId}`;
|
|
879
887
|
childrenNodes.push(wrapperNode);
|
|
880
888
|
} else childrenNodes.push(...childResults);
|
|
881
|
-
} else if (import_lib$
|
|
889
|
+
} else if (import_lib$1.isJSXFragment(child)) {
|
|
882
890
|
processedNodes?.add(child);
|
|
883
891
|
const fragmentChildren = [];
|
|
884
892
|
child.children.forEach((fragmentChild) => {
|
|
885
|
-
if (import_lib$
|
|
893
|
+
if (import_lib$1.isJSXElement(fragmentChild)) {
|
|
886
894
|
const childResults = extractFromNode(fragmentChild, processedNodes, source);
|
|
887
895
|
fragmentChildren.push(...childResults);
|
|
888
896
|
}
|
|
@@ -897,26 +905,26 @@ const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, s
|
|
|
897
905
|
return childrenNodes.length ? childrenNodes : void 0;
|
|
898
906
|
};
|
|
899
907
|
const skipItemsChildren = (jsxElement, processedNodes, propertyName = "items") => {
|
|
900
|
-
const itemsAttr = jsxElement.openingElement.attributes.find((attr) => import_lib$
|
|
901
|
-
if (!itemsAttr || !import_lib$
|
|
902
|
-
if (itemsAttr.value && import_lib$
|
|
903
|
-
if (import_lib$
|
|
904
|
-
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);
|
|
905
913
|
});
|
|
906
914
|
});
|
|
907
915
|
};
|
|
908
916
|
const markProcessedJSX = (node, processedNodes) => {
|
|
909
|
-
if (import_lib$
|
|
917
|
+
if (import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node)) {
|
|
910
918
|
processedNodes.add(node);
|
|
911
919
|
node.children.forEach((child) => markProcessedJSX(child, processedNodes));
|
|
912
920
|
return;
|
|
913
921
|
}
|
|
914
|
-
if (import_lib$
|
|
922
|
+
if (import_lib$1.isJSXExpressionContainer(node) || import_lib$1.isParenthesizedExpression(node)) markProcessedJSX(node.expression, processedNodes);
|
|
915
923
|
};
|
|
916
924
|
const getBindingExpression = (opening) => {
|
|
917
|
-
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)) {
|
|
918
926
|
const expression = unwrapExpression(attr.value.expression);
|
|
919
|
-
if (import_lib$
|
|
927
|
+
if (import_lib$1.isArrayExpression(expression)) return expression;
|
|
920
928
|
}
|
|
921
929
|
return null;
|
|
922
930
|
};
|
|
@@ -944,7 +952,7 @@ const readNodeBindingInfo = (node, source) => {
|
|
|
944
952
|
};
|
|
945
953
|
const parseToNodes = (raw) => {
|
|
946
954
|
const wrapped = wrap(raw);
|
|
947
|
-
const ast = (0, import_lib
|
|
955
|
+
const ast = (0, import_lib.parse)(wrapped, {
|
|
948
956
|
sourceType: "module",
|
|
949
957
|
plugins: ["jsx", "typescript"],
|
|
950
958
|
errorRecovery: true
|
|
@@ -1019,7 +1027,7 @@ const getChildrenSignatures = (nodes) => {
|
|
|
1019
1027
|
};
|
|
1020
1028
|
const indicesAreValid = (indices, count) => Array.isArray(indices) && new Set(indices).size === indices.length && indices.every((index) => Number.isInteger(index) && index >= 0 && index < count);
|
|
1021
1029
|
const copySource = (source, usedIds) => {
|
|
1022
|
-
const node = (0, import_lib
|
|
1030
|
+
const node = (0, import_lib.parseExpression)(source, { plugins: ["jsx", "typescript"] });
|
|
1023
1031
|
const edits = [];
|
|
1024
1032
|
const newId = () => {
|
|
1025
1033
|
let id = nanoid(12);
|
|
@@ -1027,15 +1035,15 @@ const copySource = (source, usedIds) => {
|
|
|
1027
1035
|
usedIds.add(id);
|
|
1028
1036
|
return id;
|
|
1029
1037
|
};
|
|
1030
|
-
import_lib$
|
|
1031
|
-
if (!import_lib$
|
|
1032
|
-
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" }));
|
|
1033
1041
|
if (ids.length > 1) throw new Error("Duplicate data-id attributes");
|
|
1034
1042
|
const attr = ids[0];
|
|
1035
|
-
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");
|
|
1036
1044
|
if (attr) {
|
|
1037
1045
|
const value = attr.value;
|
|
1038
|
-
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");
|
|
1039
1047
|
edits.push({
|
|
1040
1048
|
start: value.start,
|
|
1041
1049
|
end: value.end,
|
|
@@ -1057,7 +1065,7 @@ const editChildrenSource = (source, parent, input) => {
|
|
|
1057
1065
|
try {
|
|
1058
1066
|
if (!parent.closingElement || parent.start == null || parent.end == null) return null;
|
|
1059
1067
|
const value = typeof input === "string" ? JSON.parse(input) : input;
|
|
1060
|
-
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));
|
|
1061
1069
|
const raw = children.map((child) => source.slice(child.start, child.end));
|
|
1062
1070
|
const models = extract(source.slice(parent.start, parent.end))[0]?.children ?? [];
|
|
1063
1071
|
if (models.length !== children.length) return null;
|
|
@@ -1080,7 +1088,7 @@ const editChildrenSource = (source, parent, input) => {
|
|
|
1080
1088
|
};
|
|
1081
1089
|
if (Array.isArray(value)) {
|
|
1082
1090
|
const desired = modeledSignatures(value);
|
|
1083
|
-
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]);
|
|
1084
1092
|
const consumed = /* @__PURE__ */ new Set();
|
|
1085
1093
|
const next = desired.map((signature, position) => {
|
|
1086
1094
|
const index = signatures.findIndex((candidate, i) => candidate === signature && !consumed.has(i) && (value[position].source === void 0 || value[position].source === raw[i]));
|
|
@@ -1093,8 +1101,8 @@ const editChildrenSource = (source, parent, input) => {
|
|
|
1093
1101
|
});
|
|
1094
1102
|
const countIds = (text) => {
|
|
1095
1103
|
const counts = /* @__PURE__ */ new Map();
|
|
1096
|
-
import_lib$
|
|
1097
|
-
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);
|
|
1098
1106
|
});
|
|
1099
1107
|
return counts;
|
|
1100
1108
|
};
|
|
@@ -1106,8 +1114,8 @@ const editChildrenSource = (source, parent, input) => {
|
|
|
1106
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;
|
|
1107
1115
|
const { action } = request;
|
|
1108
1116
|
const usedIds = /* @__PURE__ */ new Set();
|
|
1109
|
-
import_lib$
|
|
1110
|
-
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);
|
|
1111
1119
|
});
|
|
1112
1120
|
switch (action.type) {
|
|
1113
1121
|
case "move": {
|
|
@@ -1163,7 +1171,7 @@ const childrenRange = (element) => {
|
|
|
1163
1171
|
};
|
|
1164
1172
|
};
|
|
1165
1173
|
const findAttribute = (opening, propertyName) => {
|
|
1166
|
-
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);
|
|
1167
1175
|
};
|
|
1168
1176
|
const attributeInsertPoint = (opening) => {
|
|
1169
1177
|
return opening.attributes[opening.attributes.length - 1]?.end ?? opening.name.end ?? null;
|
|
@@ -1172,7 +1180,7 @@ const editInnerText = (source, element, value) => {
|
|
|
1172
1180
|
const range = childrenRange(element);
|
|
1173
1181
|
if (!range) return [];
|
|
1174
1182
|
const [only] = element.children;
|
|
1175
|
-
if (element.children.length === 1 && import_lib$
|
|
1183
|
+
if (element.children.length === 1 && import_lib$1.isJSXText(only) && only.start != null && only.end != null) {
|
|
1176
1184
|
const raw = source.slice(only.start, only.end);
|
|
1177
1185
|
if (raw.trim() !== "") {
|
|
1178
1186
|
const leading = raw.length - raw.trimStart().length;
|
|
@@ -1185,7 +1193,7 @@ const editInnerText = (source, element, value) => {
|
|
|
1185
1193
|
}
|
|
1186
1194
|
}
|
|
1187
1195
|
const edits = [];
|
|
1188
|
-
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({
|
|
1189
1197
|
start: child.start,
|
|
1190
1198
|
end: child.end,
|
|
1191
1199
|
content: ""
|
|
@@ -1215,7 +1223,7 @@ const editRichtext = (element, value) => {
|
|
|
1215
1223
|
content: ""
|
|
1216
1224
|
});
|
|
1217
1225
|
const opening = element.openingElement;
|
|
1218
|
-
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))])));
|
|
1219
1227
|
const content = generateCode(attribute);
|
|
1220
1228
|
const existing = findAttribute(opening, "dangerouslySetInnerHTML");
|
|
1221
1229
|
if (existing && existing.start != null && existing.end != null) {
|
|
@@ -1254,11 +1262,11 @@ const editJsxAttribute = (opening, propertyName, value) => {
|
|
|
1254
1262
|
content: `=${content}`
|
|
1255
1263
|
}];
|
|
1256
1264
|
};
|
|
1257
|
-
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)));
|
|
1258
1266
|
const structuralSource = (value) => {
|
|
1259
1267
|
try {
|
|
1260
|
-
const expression = (0, import_lib
|
|
1261
|
-
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;
|
|
1262
1270
|
} catch {
|
|
1263
1271
|
return null;
|
|
1264
1272
|
}
|
|
@@ -1266,29 +1274,29 @@ const structuralSource = (value) => {
|
|
|
1266
1274
|
const buildAttributeValue = (value, type, current) => {
|
|
1267
1275
|
if (type === "array" || type === "object") {
|
|
1268
1276
|
if (typeof value === "string") try {
|
|
1269
|
-
return import_lib$
|
|
1277
|
+
return import_lib$1.jsxExpressionContainer((0, import_lib.parseExpression)(value.trim(), { plugins: ["jsx", "typescript"] }));
|
|
1270
1278
|
} catch {
|
|
1271
|
-
return import_lib$
|
|
1279
|
+
return import_lib$1.stringLiteral(value);
|
|
1272
1280
|
}
|
|
1273
1281
|
const expr = valueToExpression(value);
|
|
1274
|
-
return expr ? import_lib$
|
|
1282
|
+
return expr ? import_lib$1.jsxExpressionContainer(expr) : import_lib$1.stringLiteral("");
|
|
1275
1283
|
}
|
|
1276
1284
|
if (typeof value === "string") {
|
|
1277
1285
|
if (holdsStructuralExpression(current) && !(type && STRING_VALUED_TYPES.has(type))) {
|
|
1278
1286
|
const structural = structuralSource(value);
|
|
1279
|
-
if (structural) return import_lib$
|
|
1287
|
+
if (structural) return import_lib$1.jsxExpressionContainer(structural);
|
|
1280
1288
|
}
|
|
1281
|
-
return import_lib$
|
|
1289
|
+
return import_lib$1.stringLiteral(value);
|
|
1282
1290
|
}
|
|
1283
1291
|
const expr = valueToExpression(value);
|
|
1284
|
-
return expr ? import_lib$
|
|
1292
|
+
return expr ? import_lib$1.jsxExpressionContainer(expr) : import_lib$1.stringLiteral(String(value));
|
|
1285
1293
|
};
|
|
1286
1294
|
const editAttribute = (opening, propertyName, value, type) => {
|
|
1287
1295
|
const attribute = findAttribute(opening, propertyName);
|
|
1288
1296
|
if (!attribute || attribute.start == null || attribute.end == null) return null;
|
|
1289
1297
|
if (typeof value === "string" && (type === "array" || type === "object" || holdsStructuralExpression(attribute.value) && !(type && STRING_VALUED_TYPES.has(type)))) {
|
|
1290
1298
|
const expression = structuralSource(value);
|
|
1291
|
-
if (expression && import_lib$
|
|
1299
|
+
if (expression && import_lib$1.isJSXExpressionContainer(attribute.value)) {
|
|
1292
1300
|
const text = value.trim();
|
|
1293
1301
|
const lineComment = expression.trailingComments?.some((comment) => comment.type === "CommentLine");
|
|
1294
1302
|
return [{
|
|
@@ -1298,7 +1306,7 @@ const editAttribute = (opening, propertyName, value, type) => {
|
|
|
1298
1306
|
}];
|
|
1299
1307
|
}
|
|
1300
1308
|
}
|
|
1301
|
-
const content = generateCode(import_lib$
|
|
1309
|
+
const content = generateCode(import_lib$1.jsxAttribute(attribute.name, buildAttributeValue(value, type, attribute.value)));
|
|
1302
1310
|
return [{
|
|
1303
1311
|
start: attribute.start,
|
|
1304
1312
|
end: attribute.end,
|
|
@@ -1324,18 +1332,18 @@ const addAttribute = (source, opening, propertyName, value, type) => {
|
|
|
1324
1332
|
return [{
|
|
1325
1333
|
start: insertAt,
|
|
1326
1334
|
end: insertAt,
|
|
1327
|
-
content: `${lastStart != null && lineStart > 0 && /^\s*$/.test(source.slice(lineStart, lastStart)) ? "\n" : " "}${type === "jsx" ? `${propertyName}={${String(value).trim()}}` : generateCode(import_lib$
|
|
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)))}`,
|
|
1328
1336
|
indent: true
|
|
1329
1337
|
}];
|
|
1330
1338
|
};
|
|
1331
1339
|
const canEditAttributeValue = (attribute, value, type) => {
|
|
1332
|
-
if (!import_lib$
|
|
1340
|
+
if (!import_lib$1.isJSXExpressionContainer(attribute.value) || import_lib$1.isJSXEmptyExpression(attribute.value.expression) || isLosslesslyEvaluable(attribute.value.expression)) return true;
|
|
1333
1341
|
return typeof value === "string" && holdsStructuralExpression(attribute.value) && !(type && STRING_VALUED_TYPES.has(type)) && structuralSource(value) !== null;
|
|
1334
1342
|
};
|
|
1335
1343
|
const update = (code, dataId, label, value, property) => {
|
|
1336
1344
|
try {
|
|
1337
1345
|
const wrapped = wrap(code);
|
|
1338
|
-
const ast = (0, import_lib
|
|
1346
|
+
const ast = (0, import_lib.parse)(wrapped, {
|
|
1339
1347
|
sourceType: "module",
|
|
1340
1348
|
plugins: ["jsx", "typescript"]
|
|
1341
1349
|
});
|
|
@@ -1353,9 +1361,9 @@ const update = (code, dataId, label, value, property) => {
|
|
|
1353
1361
|
traverse(ast, { JSXElement(path) {
|
|
1354
1362
|
const opening = path.node.openingElement;
|
|
1355
1363
|
if (!opening.attributes.find((attr) => {
|
|
1356
|
-
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;
|
|
1357
1365
|
})) return;
|
|
1358
|
-
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);
|
|
1359
1367
|
if (!bindingAttr?.value) {
|
|
1360
1368
|
failure = {
|
|
1361
1369
|
reason: "no-binding",
|
|
@@ -1364,8 +1372,8 @@ const update = (code, dataId, label, value, property) => {
|
|
|
1364
1372
|
return;
|
|
1365
1373
|
}
|
|
1366
1374
|
let bindingValue = "";
|
|
1367
|
-
if (import_lib$
|
|
1368
|
-
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 {
|
|
1369
1377
|
bindingValue = generateCode(bindingAttr.value.expression);
|
|
1370
1378
|
} catch (error) {
|
|
1371
1379
|
failure = {
|
|
@@ -1541,24 +1549,6 @@ const bulkUpdate = (raw, entries) => {
|
|
|
1541
1549
|
};
|
|
1542
1550
|
};
|
|
1543
1551
|
//#endregion
|
|
1544
|
-
//#region src/utils/ast/tree.ts
|
|
1545
|
-
const replaceIds = (code, generateId = () => nanoid(6)) => {
|
|
1546
|
-
return code.replace(new RegExp(`${DATA_ATTR.ID}="[^"]*"`, "g"), () => {
|
|
1547
|
-
return `${DATA_ATTR.ID}="${generateId()}"`;
|
|
1548
|
-
});
|
|
1549
|
-
};
|
|
1550
|
-
const fillIds = (code, generateId = () => nanoid(6)) => {
|
|
1551
|
-
return code.replace(new RegExp(`${DATA_ATTR.ID}=""`, "g"), () => {
|
|
1552
|
-
return `${DATA_ATTR.ID}="${generateId()}"`;
|
|
1553
|
-
});
|
|
1554
|
-
};
|
|
1555
|
-
const clone = (element, generateId = () => nanoid(6)) => {
|
|
1556
|
-
const cloned = import_lib$2.cloneNode(element, true);
|
|
1557
|
-
const generatedCode = generateCode(cloned);
|
|
1558
|
-
const code = replaceIds(generatedCode, generateId);
|
|
1559
|
-
return (0, import_lib$1.parseExpression)(code, { plugins: ["jsx", "typescript"] });
|
|
1560
|
-
};
|
|
1561
|
-
//#endregion
|
|
1562
1552
|
//#region src/utils/ast/validate.ts
|
|
1563
1553
|
const VALID = { valid: true };
|
|
1564
1554
|
const validateBindingValue = (binding, value) => {
|
|
@@ -1608,6 +1598,6 @@ const validateBindingValue = (binding, value) => {
|
|
|
1608
1598
|
return VALID;
|
|
1609
1599
|
};
|
|
1610
1600
|
//#endregion
|
|
1611
|
-
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 };
|
|
1612
1602
|
|
|
1613
|
-
//# sourceMappingURL=ast-
|
|
1603
|
+
//# sourceMappingURL=ast-BFbDWO-l.js.map
|