@jbpark/live-editor 4.5.0 → 4.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.ko.md +4 -1
  2. package/README.md +5 -1
  3. package/dist/{boundary-DnjGgsK6.js → boundary-BLB80tyw.js} +2 -2
  4. package/dist/boundary-BLB80tyw.js.map +1 -0
  5. package/dist/cache-B0-XcIxJ.js.map +1 -1
  6. package/dist/{compile-DDfk5P25.js → compile-Dxas-D05.js} +3 -3
  7. package/dist/compile-Dxas-D05.js.map +1 -0
  8. package/dist/{constants-h1JAgOeW.js → constants-DU17Tdwo.js} +3 -3
  9. package/dist/constants-DU17Tdwo.js.map +1 -0
  10. package/dist/{context-DsEXJl4h.js → context-B8MzP7_p.js} +3 -3
  11. package/dist/context-B8MzP7_p.js.map +1 -0
  12. package/dist/{core-CRsAGpei.js → core-Bgfek364.js} +2 -2
  13. package/dist/core-Bgfek364.js.map +1 -0
  14. package/dist/{detect-typescript-CCj9ALXc.js → detect-typescript-Dr_oLniM.js} +2 -2
  15. package/dist/detect-typescript-Dr_oLniM.js.map +1 -0
  16. package/dist/dnd/index.d.ts +1 -1
  17. package/dist/dnd/index.js +1 -1
  18. package/dist/{dnd-DGNp20Nk.js → dnd-V8NAxd_R.js} +435 -413
  19. package/dist/dnd-V8NAxd_R.js.map +1 -0
  20. package/dist/document-CHO215iP.js +33992 -0
  21. package/dist/document-CHO215iP.js.map +1 -0
  22. package/dist/{document-Ct4jW78J.d.ts → document-DqRSCtsx.d.ts} +496 -435
  23. package/dist/editor/index.js +2 -2
  24. package/dist/{editor-DQ8Q--qR.js → editor-CMElfHer.js} +2 -2
  25. package/dist/editor-CMElfHer.js.map +1 -0
  26. package/dist/editor-caches-ClMvdcQF.js.map +1 -1
  27. package/dist/error/index.d.ts +1 -1
  28. package/dist/error/index.js +2 -2
  29. package/dist/{error-DwqwjJ2C.js → error-CN_GCnXB.js} +3 -3
  30. package/dist/{error-DwqwjJ2C.js.map → error-CN_GCnXB.js.map} +1 -1
  31. package/dist/{index-vtyggWy0.d.ts → index-CRwEhJ7w.d.ts} +2 -2
  32. package/dist/index-C_PfR4X9.d.ts +734 -0
  33. package/dist/{index-P9Aifaui.d.ts → index-CiWB0zFb.d.ts} +72 -70
  34. package/dist/{index-WQgFy510.d.ts → index-DrWtSKXu.d.ts} +2 -2
  35. package/dist/index.d.ts +5 -5
  36. package/dist/index.js +6 -6
  37. package/dist/{items-DdrwGxJw.js → items-BXXtMUNI.js} +307 -390
  38. package/dist/items-BXXtMUNI.js.map +1 -0
  39. package/dist/{messages-CzUPVnzH.js → messages-CSrMI4Rm.js} +2 -1
  40. package/dist/messages-CSrMI4Rm.js.map +1 -0
  41. package/dist/{messages-Cp3g1mn1.d.ts → messages-IBPs4TkZ.d.ts} +2 -1
  42. package/dist/preview/index.js +2 -2
  43. package/dist/{preview-BKFgq_5u.js → preview-CtyG5UbH.js} +4 -4
  44. package/dist/{preview-BKFgq_5u.js.map → preview-CtyG5UbH.js.map} +1 -1
  45. package/dist/provider/index.d.ts +2 -2
  46. package/dist/provider/index.js +2 -2
  47. package/dist/{sections-BRH3KHYc.js → sections-jYuqS4KB.js} +3 -3
  48. package/dist/sections-jYuqS4KB.js.map +1 -0
  49. package/dist/states-Ci1AvoQ9.js.map +1 -1
  50. package/dist/{use-dynamic-tailwind-T9r9ExbR.js → use-dynamic-tailwind-BP1toJkW.js} +59 -39
  51. package/dist/use-dynamic-tailwind-BP1toJkW.js.map +1 -0
  52. package/dist/utils/ast/index.d.ts +2 -2
  53. package/dist/utils/ast/index.js +84 -2
  54. package/dist/utils/ast/index.js.map +1 -1
  55. package/dist/utils/index.d.ts +1 -1
  56. package/dist/utils/index.js +4 -4
  57. package/dist/utils/index.js.map +1 -1
  58. package/dist/utils/tailwind/index.js.map +1 -1
  59. package/dist/validate-iLo8IONY.js.map +1 -1
  60. package/package.json +5 -7
  61. package/dist/boundary-DnjGgsK6.js.map +0 -1
  62. package/dist/compile-DDfk5P25.js.map +0 -1
  63. package/dist/constants-h1JAgOeW.js.map +0 -1
  64. package/dist/context-DsEXJl4h.js.map +0 -1
  65. package/dist/core-CRsAGpei.js.map +0 -1
  66. package/dist/detect-typescript-CCj9ALXc.js.map +0 -1
  67. package/dist/dnd-DGNp20Nk.js.map +0 -1
  68. package/dist/document-DGHTfrda.js +0 -38667
  69. package/dist/document-DGHTfrda.js.map +0 -1
  70. package/dist/editor-DQ8Q--qR.js.map +0 -1
  71. package/dist/index-CHknA6k1.d.ts +0 -221
  72. package/dist/items-DdrwGxJw.js.map +0 -1
  73. package/dist/messages-CzUPVnzH.js.map +0 -1
  74. package/dist/sections-BRH3KHYc.js.map +0 -1
  75. package/dist/use-dynamic-tailwind-T9r9ExbR.js.map +0 -1
@@ -1,11 +1,9 @@
1
- import { C as require_lib, S as require_lib$1, _ as generateCode, b as getJSXTagName, d as traverse, g as attrValue, v as unwrap, w as __toESM, x as nanoid, y as wrap } from "./document-DGHTfrda.js";
2
- import { c as RESERVED_BINDING_PROPERTIES, n as CONFIG, r as DATA_ATTR, s as REGEX, t as BINDING_PROP } from "./constants-h1JAgOeW.js";
1
+ import { $ as jsxClosingFragment, A as isJSXElement, B as isObjectExpression, C as booleanLiteral, D as isExpression, E as isBooleanLiteral, F as isJSXOpeningElement, G as isTSAsExpression, H as isParenthesizedExpression, I as isJSXSpreadAttribute, J as isTSTypeAssertion, K as isTSNonNullExpression, L as isJSXText, M as isJSXExpressionContainer, N as isJSXFragment, O as isIdentifier, P as isJSXIdentifier, Q as jsxClosingElement, R as isNullLiteral, S as arrayExpression, T as isArrayExpression, U as isSpreadElement, V as isObjectProperty, W as isStringLiteral, X as isUnaryExpression, Y as isTemplateLiteral, Z as jsxAttribute, _ as generateCode, _t as parse, at as jsxOpeningElement, b as getJSXTagName, ct as nullLiteral, d as traverse, dt as objectProperty, et as jsxElement, ft as stringLiteral, g as attrValue, gt as unaryExpression, ht as traverseFast, it as jsxMemberExpression, j as isJSXEmptyExpression, k as isJSXAttribute, lt as numericLiteral, mt as templateLiteral, nt as jsxFragment, ot as jsxOpeningFragment, pt as templateElement, q as isTSSatisfiesExpression, rt as jsxIdentifier, st as jsxText, tt as jsxExpressionContainer, ut as objectExpression, v as unwrap, vt as parseExpression, w as identifier, x as nanoid, y as wrap, z as isNumericLiteral } from "./document-CHO215iP.js";
2
+ import { c as RESERVED_BINDING_PROPERTIES, n as CONFIG, r as DATA_ATTR, s as REGEX, t as BINDING_PROP } from "./constants-DU17Tdwo.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 = require_lib();
8
- var import_lib$1 = /* @__PURE__ */ __toESM(require_lib$1(), 1);
9
7
  const BINDING_TYPES = [
10
8
  "array",
11
9
  "object",
@@ -31,44 +29,44 @@ const dedent = (str) => {
31
29
  };
32
30
  const unwrapExpression = (node) => {
33
31
  let current = node;
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;
32
+ while (isTSAsExpression(current) || isTSSatisfiesExpression(current) || isTSNonNullExpression(current) || isTSTypeAssertion(current) || isParenthesizedExpression(current)) current = current.expression;
35
33
  return current;
36
34
  };
37
35
  const isLosslesslyEvaluable = (node) => {
38
36
  const value = unwrapExpression(node);
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));
37
+ if (isStringLiteral(value) || isNumericLiteral(value) || isBooleanLiteral(value) || isNullLiteral(value)) return true;
38
+ if (isUnaryExpression(value) && value.operator === "-" && isNumericLiteral(value.argument)) return true;
39
+ if (isTemplateLiteral(value)) return value.expressions.length === 0;
40
+ if (isArrayExpression(value)) return value.elements.every((element) => element !== null && isLosslesslyEvaluable(element));
41
+ if (isObjectExpression(value)) return value.properties.every((property) => isObjectProperty(property) && !property.computed && (isIdentifier(property.key) || isStringLiteral(property.key) || isNumericLiteral(property.key)) && isLosslesslyEvaluable(property.value));
44
42
  return false;
45
43
  };
46
44
  const canLosslesslyEvaluateSource = (source) => {
47
45
  try {
48
- return isLosslesslyEvaluable((0, import_lib.parseExpression)(source, { plugins: ["jsx", "typescript"] }));
46
+ return isLosslesslyEvaluable(parseExpression(source, { plugins: ["jsx", "typescript"] }));
49
47
  } catch {
50
48
  return false;
51
49
  }
52
50
  };
53
51
  const evaluateLiteral = (rawNode) => {
54
52
  const node = unwrapExpression(rawNode);
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)) {
53
+ if (isStringLiteral(node)) return node.value;
54
+ if (isNumericLiteral(node)) return node.value;
55
+ if (isBooleanLiteral(node)) return node.value;
56
+ if (isNullLiteral(node)) return null;
57
+ if (isIdentifier(node) && node.name === "undefined") return;
58
+ if (isUnaryExpression(node) && node.operator === "-" && isNumericLiteral(node.argument)) return -node.argument.value;
59
+ if (isTemplateLiteral(node) && node.expressions.length === 0) return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw ?? "";
60
+ if (isJSXElement(node) || isJSXFragment(node)) return generateCode(node);
61
+ if (isArrayExpression(node)) return node.elements.map((element) => element ? evaluateLiteral(element) : null);
62
+ if (isObjectExpression(node)) {
65
63
  const result = {};
66
64
  for (const prop of node.properties) {
67
- if (!import_lib$1.isObjectProperty(prop)) continue;
65
+ if (!isObjectProperty(prop)) continue;
68
66
  let key = null;
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);
67
+ if (isIdentifier(prop.key)) key = prop.key.name;
68
+ else if (isStringLiteral(prop.key)) key = prop.key.value;
69
+ else if (isNumericLiteral(prop.key)) key = String(prop.key.value);
72
70
  if (key === null) continue;
73
71
  result[key] = evaluateLiteral(prop.value);
74
72
  }
@@ -88,111 +86,31 @@ const parseValue = (value) => {
88
86
  }
89
87
  if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
90
88
  try {
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);
89
+ const ast = parseExpression(trimmed, { plugins: ["jsx", "typescript"] });
90
+ if (isObjectExpression(ast) || isArrayExpression(ast)) return evaluateLiteral(ast);
93
91
  } catch {}
94
92
  return value;
95
93
  }
96
94
  return value;
97
95
  };
98
- const MAX_FLATTEN_DEPTH = 20;
99
- const isEditablePrimitive = (value) => typeof value === "string" || typeof value === "number" || typeof value === "boolean";
100
- const flattenEditableValue = (value) => {
101
- const parsed = parseValue(value);
102
- if (typeof parsed !== "object" || parsed === null || Object.keys(parsed).length === 0) return null;
103
- const entries = [];
104
- const walk = (node, path, depth) => {
105
- if (depth > MAX_FLATTEN_DEPTH) return;
106
- if (isEditablePrimitive(node)) {
107
- entries.push({
108
- path,
109
- value: node
110
- });
111
- return;
112
- }
113
- if (Array.isArray(node)) {
114
- node.forEach((item, index) => walk(item, [...path, index], depth + 1));
115
- return;
116
- }
117
- if (typeof node === "object" && node !== null) Object.entries(node).forEach(([key, item]) => walk(item, [...path, key], depth + 1));
118
- };
119
- walk(parsed, [], 0);
120
- return entries.length ? entries : null;
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
- };
167
- const setEditableValue = (value, path, next) => {
168
- if (!path.length) return value;
169
- let leaf;
170
- try {
171
- leaf = findEditableLeaf((0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] }), path);
172
- } catch {
173
- return value;
174
- }
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)}`;
177
- };
178
96
  const extractNodeValue = (node) => {
179
- if (import_lib$1.isBooleanLiteral(node)) return {
97
+ if (isBooleanLiteral(node)) return {
180
98
  type: "boolean",
181
99
  value: node.value
182
100
  };
183
- if (import_lib$1.isNumericLiteral(node)) return {
101
+ if (isNumericLiteral(node)) return {
184
102
  type: "number",
185
103
  value: node.value
186
104
  };
187
- if (import_lib$1.isUnaryExpression(node) && node.operator === "-" && import_lib$1.isNumericLiteral(node.argument)) return {
105
+ if (isUnaryExpression(node) && node.operator === "-" && isNumericLiteral(node.argument)) return {
188
106
  type: "number",
189
107
  value: -node.argument.value
190
108
  };
191
- if (import_lib$1.isStringLiteral(node)) return {
109
+ if (isStringLiteral(node)) return {
192
110
  type: "string",
193
111
  value: node.value
194
112
  };
195
- if (import_lib$1.isTemplateLiteral(node)) {
113
+ if (isTemplateLiteral(node)) {
196
114
  if (node.expressions.length === 0 && node.quasis.length === 1) return {
197
115
  type: "string",
198
116
  value: dedent(node.quasis[0].value.cooked ?? node.quasis[0].value.raw)
@@ -202,19 +120,19 @@ const extractNodeValue = (node) => {
202
120
  value: generateCode(node)
203
121
  };
204
122
  }
205
- if (import_lib$1.isNullLiteral(node)) return {
123
+ if (isNullLiteral(node)) return {
206
124
  type: "null",
207
125
  value: null
208
126
  };
209
- if (import_lib$1.isArrayExpression(node)) return {
127
+ if (isArrayExpression(node)) return {
210
128
  type: "array",
211
129
  value: generateCode(node)
212
130
  };
213
- if (import_lib$1.isObjectExpression(node)) return {
131
+ if (isObjectExpression(node)) return {
214
132
  type: "object",
215
133
  value: generateCode(node)
216
134
  };
217
- if (import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node)) return {
135
+ if (isJSXElement(node) || isJSXFragment(node)) return {
218
136
  type: "string",
219
137
  value: generateCode(node)
220
138
  };
@@ -223,39 +141,10 @@ const extractNodeValue = (node) => {
223
141
  value: null
224
142
  };
225
143
  };
226
- const createNodeFromValue = (type, value) => {
227
- switch (type) {
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();
232
- case "array":
233
- case "object":
234
- case "unknown": return null;
235
- default: return null;
236
- }
237
- };
238
- const valueToExpression = (value) => {
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()));
244
- if (typeof value === "object") {
245
- const properties = [];
246
- for (const [key, item] of Object.entries(value)) {
247
- const expr = valueToExpression(item);
248
- if (expr === null) continue;
249
- properties.push(import_lib$1.objectProperty(import_lib$1.stringLiteral(key), expr));
250
- }
251
- return import_lib$1.objectExpression(properties);
252
- }
253
- return null;
254
- };
255
144
  const parseArrayExpression = (value) => {
256
145
  try {
257
- const ast = unwrapExpression((0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] }));
258
- if (!import_lib$1.isArrayExpression(ast)) return null;
146
+ const ast = unwrapExpression(parseExpression(value, { plugins: ["jsx", "typescript"] }));
147
+ if (!isArrayExpression(ast)) return null;
259
148
  return ast;
260
149
  } catch (error) {
261
150
  console.error("❌ Array parsing error:", error);
@@ -265,9 +154,9 @@ const parseArrayExpression = (value) => {
265
154
  const extractObjectProperties = (element) => {
266
155
  const properties = {};
267
156
  element.properties.forEach((prop) => {
268
- if (import_lib$1.isObjectProperty(prop) && import_lib$1.isIdentifier(prop.key)) {
157
+ if (isObjectProperty(prop) && isIdentifier(prop.key)) {
269
158
  const key = prop.key.name;
270
- if (key === "children" || import_lib$1.isJSXElement(prop.value) || import_lib$1.isJSXFragment(prop.value)) return;
159
+ if (key === "children" || isJSXElement(prop.value) || isJSXFragment(prop.value)) return;
271
160
  const extracted = extractNodeValue(prop.value);
272
161
  properties[key] = {
273
162
  ...extracted,
@@ -277,10 +166,6 @@ const extractObjectProperties = (element) => {
277
166
  });
278
167
  return properties;
279
168
  };
280
- const arrayExpressionToCode = (elements) => {
281
- const nextAst = import_lib$1.arrayExpression(elements);
282
- return generateCode(nextAst);
283
- };
284
169
  //#endregion
285
170
  //#region src/utils/ast/binding.ts
286
171
  const bindingTypeSchema = z.enum(BINDING_TYPES);
@@ -442,12 +327,12 @@ const getCurrentValue = (node, property) => {
442
327
  case BINDING_PROP.INNER_HTML: {
443
328
  const dsiAttr = node.attributes.find((a) => a.name === "dangerouslySetInnerHTML");
444
329
  if (dsiAttr?.value) try {
445
- const expr = (0, import_lib.parseExpression)(dsiAttr.value, { plugins: ["jsx", "typescript"] });
446
- if (import_lib$1.isObjectExpression(expr)) {
447
- const htmlProp = expr.properties.find((p) => import_lib$1.isObjectProperty(p) && import_lib$1.isIdentifier(p.key) && p.key.name === "__html");
330
+ const expr = parseExpression(dsiAttr.value, { plugins: ["jsx", "typescript"] });
331
+ if (isObjectExpression(expr)) {
332
+ const htmlProp = expr.properties.find((p) => isObjectProperty(p) && isIdentifier(p.key) && p.key.name === "__html");
448
333
  if (htmlProp) {
449
- if (import_lib$1.isStringLiteral(htmlProp.value)) return htmlProp.value.value;
450
- 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 ?? "";
334
+ if (isStringLiteral(htmlProp.value)) return htmlProp.value.value;
335
+ if (isTemplateLiteral(htmlProp.value) && htmlProp.value.expressions.length === 0) return htmlProp.value.quasis[0]?.value.cooked ?? htmlProp.value.quasis[0]?.value.raw ?? "";
451
336
  }
452
337
  }
453
338
  } catch {}
@@ -498,13 +383,13 @@ const findEditableChildren = (node) => {
498
383
  //#endregion
499
384
  //#region src/utils/ast/extract.ts
500
385
  const collectText = (children) => {
501
- return children.filter((c) => import_lib$1.isJSXText(c)).map((c) => c.value.trim()).filter((v) => v.length).join(" ");
386
+ return children.filter((c) => isJSXText(c)).map((c) => c.value.trim()).filter((v) => v.length).join(" ");
502
387
  };
503
388
  const parseJSXName = (tagName) => {
504
389
  const parts = tagName.split(".");
505
- if (parts.length === 1) return import_lib$1.jsxIdentifier(parts[0]);
506
- let expr = import_lib$1.jsxIdentifier(parts[0]);
507
- for (let i = 1; i < parts.length; i++) expr = import_lib$1.jsxMemberExpression(expr, import_lib$1.jsxIdentifier(parts[i]));
390
+ if (parts.length === 1) return jsxIdentifier(parts[0]);
391
+ let expr = jsxIdentifier(parts[0]);
392
+ for (let i = 1; i < parts.length; i++) expr = jsxMemberExpression(expr, jsxIdentifier(parts[i]));
508
393
  return expr;
509
394
  };
510
395
  const extractCache = createBoundedCache(CONFIG.CACHE_LIMIT);
@@ -528,19 +413,19 @@ const extractAttributes = (attributes, source) => {
528
413
  const allAttrs = [];
529
414
  const dataAttrs = [];
530
415
  for (const attr of attributes) {
531
- if (!import_lib$1.isJSXAttribute(attr) || !import_lib$1.isJSXIdentifier(attr.name)) continue;
416
+ if (!isJSXAttribute(attr) || !isJSXIdentifier(attr.name)) continue;
532
417
  const name = attr.name.name;
533
418
  let value = null;
534
- let isStringLiteral = false;
419
+ let isStringLiteral$1 = false;
535
420
  if (attr.value) {
536
- if (import_lib$1.isStringLiteral(attr.value)) {
421
+ if (isStringLiteral(attr.value)) {
537
422
  value = attr.value.value;
538
- isStringLiteral = true;
539
- } else if (import_lib$1.isJSXExpressionContainer(attr.value)) try {
423
+ isStringLiteral$1 = true;
424
+ } else if (isJSXExpressionContainer(attr.value)) try {
540
425
  const expression = attr.value.expression;
541
- const structural = import_lib$1.isArrayExpression(unwrapExpression(expression)) || import_lib$1.isObjectExpression(unwrapExpression(expression));
426
+ const structural = isArrayExpression(unwrapExpression(expression)) || isObjectExpression(unwrapExpression(expression));
542
427
  value = source && structural && expression.start != null && expression.end != null ? source.slice(expression.start, expression.end) : generateCode(expression);
543
- isStringLiteral = false;
428
+ isStringLiteral$1 = false;
544
429
  } catch {
545
430
  value = null;
546
431
  }
@@ -548,7 +433,7 @@ const extractAttributes = (attributes, source) => {
548
433
  const entry = {
549
434
  name,
550
435
  value,
551
- isStringLiteral
436
+ isStringLiteral: isStringLiteral$1
552
437
  };
553
438
  allAttrs.push(entry);
554
439
  if (name.startsWith("data-")) dataAttrs.push(entry);
@@ -560,7 +445,7 @@ const extractAttributes = (attributes, source) => {
560
445
  };
561
446
  const buildChildElements = (node) => {
562
447
  const childElements = [];
563
- if (node.textContent) childElements.push(import_lib$1.jsxText(node.textContent));
448
+ if (node.textContent) childElements.push(jsxText(node.textContent));
564
449
  node.children?.forEach((child) => {
565
450
  const childJSX = nodeToJSX(child);
566
451
  if (childJSX) childElements.push(childJSX);
@@ -571,22 +456,22 @@ const nodeToJSX = (node) => {
571
456
  try {
572
457
  if (node.isFragment) {
573
458
  const childElements = buildChildElements(node);
574
- return import_lib$1.jsxFragment(import_lib$1.jsxOpeningFragment(), import_lib$1.jsxClosingFragment(), childElements);
459
+ return jsxFragment(jsxOpeningFragment(), jsxClosingFragment(), childElements);
575
460
  }
576
461
  if (node.tagName === "div" && node.dataAttributes.some((attr) => attr.name === "data-item")) {
577
462
  if (node.children) return nodeToJSX(node.children[0]);
578
463
  return null;
579
464
  }
580
465
  const attributes = node.attributes.map((attr) => {
581
- const attrName = import_lib$1.jsxIdentifier(attr.name);
582
- if (!attr.value) return import_lib$1.jsxAttribute(attrName, null);
583
- return import_lib$1.jsxAttribute(attrName, attrValue(attr));
466
+ const attrName = jsxIdentifier(attr.name);
467
+ if (!attr.value) return jsxAttribute(attrName, null);
468
+ return jsxAttribute(attrName, attrValue(attr));
584
469
  });
585
470
  const elementName = parseJSXName(node.tagName);
586
- const openingElement = import_lib$1.jsxOpeningElement(elementName, attributes);
587
- const closingElement = import_lib$1.jsxClosingElement(elementName);
471
+ const openingElement = jsxOpeningElement(elementName, attributes);
472
+ const closingElement = jsxClosingElement(elementName);
588
473
  const children = buildChildElements(node);
589
- return import_lib$1.jsxElement(openingElement, closingElement, children, false);
474
+ return jsxElement(openingElement, closingElement, children);
590
475
  } catch (error) {
591
476
  console.error("❌ DataAttrNode to JSX conversion error:", error);
592
477
  return null;
@@ -616,11 +501,11 @@ const createFragmentNode = (textContent, children) => ({
616
501
  isFragment: true
617
502
  });
618
503
  const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, source, options) => {
619
- const jsxChildren = jsxElement.children.filter((child) => import_lib$1.isJSXElement(child) || import_lib$1.isJSXFragment(child));
504
+ const jsxChildren = jsxElement.children.filter((child) => isJSXElement(child) || isJSXFragment(child));
620
505
  if (!jsxChildren.length) return;
621
506
  const childrenNodes = [];
622
507
  jsxChildren.forEach((child) => {
623
- if (import_lib$1.isJSXElement(child)) {
508
+ if (isJSXElement(child)) {
624
509
  const childResults = extractFromNode(child, processedNodes, source, options);
625
510
  if (shouldWrap) {
626
511
  const wrapperNode = createWrapperNode(collectText(child.children), childResults);
@@ -629,11 +514,11 @@ const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, s
629
514
  if (dataId) wrapperNode.id = `child:${dataId}`;
630
515
  childrenNodes.push(wrapperNode);
631
516
  } else childrenNodes.push(...childResults);
632
- } else if (import_lib$1.isJSXFragment(child)) {
517
+ } else if (isJSXFragment(child)) {
633
518
  processedNodes?.add(child);
634
519
  const fragmentChildren = [];
635
520
  child.children.forEach((fragmentChild) => {
636
- if (import_lib$1.isJSXElement(fragmentChild)) {
521
+ if (isJSXElement(fragmentChild)) {
637
522
  const childResults = extractFromNode(fragmentChild, processedNodes, source, options);
638
523
  fragmentChildren.push(...childResults);
639
524
  }
@@ -648,26 +533,26 @@ const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, s
648
533
  return childrenNodes.length ? childrenNodes : void 0;
649
534
  };
650
535
  const skipItemsChildren = (jsxElement, processedNodes, propertyName = "items") => {
651
- const itemsAttr = jsxElement.openingElement.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === propertyName);
652
- if (!itemsAttr || !import_lib$1.isJSXAttribute(itemsAttr)) return;
653
- if (itemsAttr.value && import_lib$1.isJSXExpressionContainer(itemsAttr.value) && import_lib$1.isArrayExpression(itemsAttr.value.expression)) itemsAttr.value.expression.elements.forEach((element) => {
654
- if (import_lib$1.isObjectExpression(element)) element.properties.forEach((prop) => {
655
- if (import_lib$1.isObjectProperty(prop) && import_lib$1.isIdentifier(prop.key) && import_lib$1.isJSXElement(prop.value)) markProcessedJSX(prop.value, processedNodes);
536
+ const itemsAttr = jsxElement.openingElement.attributes.find((attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === propertyName);
537
+ if (!itemsAttr || !isJSXAttribute(itemsAttr)) return;
538
+ if (itemsAttr.value && isJSXExpressionContainer(itemsAttr.value) && isArrayExpression(itemsAttr.value.expression)) itemsAttr.value.expression.elements.forEach((element) => {
539
+ if (isObjectExpression(element)) element.properties.forEach((prop) => {
540
+ if (isObjectProperty(prop) && isIdentifier(prop.key) && isJSXElement(prop.value)) markProcessedJSX(prop.value, processedNodes);
656
541
  });
657
542
  });
658
543
  };
659
544
  const markProcessedJSX = (node, processedNodes) => {
660
- if (import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node)) {
545
+ if (isJSXElement(node) || isJSXFragment(node)) {
661
546
  processedNodes.add(node);
662
547
  node.children.forEach((child) => markProcessedJSX(child, processedNodes));
663
548
  return;
664
549
  }
665
- if (import_lib$1.isJSXExpressionContainer(node) || import_lib$1.isParenthesizedExpression(node)) markProcessedJSX(node.expression, processedNodes);
550
+ if (isJSXExpressionContainer(node) || isParenthesizedExpression(node)) markProcessedJSX(node.expression, processedNodes);
666
551
  };
667
552
  const getBindingExpression = (opening) => {
668
- 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)) {
553
+ for (const attr of opening.attributes) if (isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING && attr.value && isJSXExpressionContainer(attr.value)) {
669
554
  const expression = unwrapExpression(attr.value.expression);
670
- if (import_lib$1.isArrayExpression(expression)) return expression;
555
+ if (isArrayExpression(expression)) return expression;
671
556
  }
672
557
  return null;
673
558
  };
@@ -696,7 +581,7 @@ const readNodeBindingInfo = (node, source, options) => {
696
581
  };
697
582
  const parseToNodes = (raw, options) => {
698
583
  const wrapped = wrap(raw);
699
- const ast = (0, import_lib.parse)(wrapped, {
584
+ const ast = parse(wrapped, {
700
585
  sourceType: "module",
701
586
  plugins: ["jsx", "typescript"],
702
587
  errorRecovery: true
@@ -873,7 +758,7 @@ const getChildrenSignatures = (nodes) => {
873
758
  };
874
759
  const indicesAreValid = (indices, count) => Array.isArray(indices) && new Set(indices).size === indices.length && indices.every((index) => Number.isInteger(index) && index >= 0 && index < count);
875
760
  const copySource = (source, usedIds) => {
876
- const node = (0, import_lib.parseExpression)(source, { plugins: ["jsx", "typescript"] });
761
+ const node = parseExpression(source, { plugins: ["jsx", "typescript"] });
877
762
  const edits = [];
878
763
  const newId = () => {
879
764
  let id = nanoid(12);
@@ -881,15 +766,15 @@ const copySource = (source, usedIds) => {
881
766
  usedIds.add(id);
882
767
  return id;
883
768
  };
884
- import_lib$1.traverseFast(node, (child) => {
885
- if (!import_lib$1.isJSXOpeningElement(child)) return;
886
- const ids = child.attributes.filter((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name, { name: "data-id" }));
769
+ traverseFast(node, (child) => {
770
+ if (!isJSXOpeningElement(child)) return;
771
+ const ids = child.attributes.filter((attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name, { name: "data-id" }));
887
772
  if (ids.length > 1) throw new Error("Duplicate data-id attributes");
888
773
  const attr = ids[0];
889
- 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");
774
+ if (attr && child.attributes.slice(child.attributes.indexOf(attr) + 1).some((attribute) => isJSXSpreadAttribute(attribute))) throw new Error("A spread may override the copied data-id");
890
775
  if (attr) {
891
776
  const value = attr.value;
892
- if (!import_lib$1.isStringLiteral(value) || value.start == null || value.end == null) throw new Error("Cannot copy a dynamic data-id");
777
+ if (!isStringLiteral(value) || value.start == null || value.end == null) throw new Error("Cannot copy a dynamic data-id");
893
778
  edits.push({
894
779
  start: value.start,
895
780
  end: value.end,
@@ -911,7 +796,7 @@ const editChildrenSource = (source, parent, input, options) => {
911
796
  try {
912
797
  if (!parent.closingElement || parent.start == null || parent.end == null) return null;
913
798
  const value = typeof input === "string" ? JSON.parse(input) : input;
914
- const children = parent.children.filter((child) => import_lib$1.isJSXElement(child) || import_lib$1.isJSXFragment(child));
799
+ const children = parent.children.filter((child) => isJSXElement(child) || isJSXFragment(child));
915
800
  const raw = children.map((child) => source.slice(child.start, child.end));
916
801
  const models = extract(source.slice(parent.start, parent.end), options)[0]?.children ?? [];
917
802
  if (models.length !== children.length) return null;
@@ -934,7 +819,7 @@ const editChildrenSource = (source, parent, input, options) => {
934
819
  };
935
820
  if (Array.isArray(value)) {
936
821
  const desired = modeledSignatures(value);
937
- const lossless = raw.every((text, index) => generateCode((0, import_lib.parseExpression)(text, { plugins: ["jsx", "typescript"] })) === signatures[index]);
822
+ const lossless = raw.every((text, index) => generateCode(parseExpression(text, { plugins: ["jsx", "typescript"] })) === signatures[index]);
938
823
  const consumed = /* @__PURE__ */ new Set();
939
824
  const next = desired.map((signature, position) => {
940
825
  const index = signatures.findIndex((candidate, i) => candidate === signature && !consumed.has(i) && (value[position].source === void 0 || value[position].source === raw[i]));
@@ -947,8 +832,8 @@ const editChildrenSource = (source, parent, input, options) => {
947
832
  });
948
833
  const countIds = (text) => {
949
834
  const counts = /* @__PURE__ */ new Map();
950
- import_lib$1.traverseFast((0, import_lib.parseExpression)(text, { plugins: ["jsx", "typescript"] }), (node) => {
951
- 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);
835
+ traverseFast(parseExpression(text, { plugins: ["jsx", "typescript"] }), (node) => {
836
+ if (isJSXAttribute(node) && isJSXIdentifier(node.name, { name: "data-id" }) && isStringLiteral(node.value)) counts.set(node.value.value, (counts.get(node.value.value) ?? 0) + 1);
952
837
  });
953
838
  return counts;
954
839
  };
@@ -960,8 +845,8 @@ const editChildrenSource = (source, parent, input, options) => {
960
845
  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;
961
846
  const { action } = request;
962
847
  const usedIds = /* @__PURE__ */ new Set();
963
- import_lib$1.traverseFast(parent, (node) => {
964
- 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);
848
+ traverseFast(parent, (node) => {
849
+ if (isJSXAttribute(node) && isJSXIdentifier(node.name, { name: "data-id" }) && isStringLiteral(node.value)) usedIds.add(node.value.value);
965
850
  });
966
851
  switch (action.type) {
967
852
  case "move": {
@@ -1007,7 +892,42 @@ const editChildrenSource = (source, parent, input, options) => {
1007
892
  }
1008
893
  };
1009
894
  //#endregion
1010
- //#region src/utils/ast/update.ts
895
+ //#region src/utils/ast/value-expression.ts
896
+ const createNodeFromValue = (type, value) => {
897
+ switch (type) {
898
+ case "boolean": return booleanLiteral(value === true);
899
+ case "number": return numericLiteral(Number(value));
900
+ case "string": return stringLiteral(String(value));
901
+ case "null": return nullLiteral();
902
+ case "array":
903
+ case "object":
904
+ case "unknown": return null;
905
+ default: return null;
906
+ }
907
+ };
908
+ const valueToExpression = (value) => {
909
+ if (typeof value === "string") return stringLiteral(value);
910
+ if (typeof value === "number") return value < 0 ? unaryExpression("-", numericLiteral(-value)) : numericLiteral(value);
911
+ if (typeof value === "boolean") return booleanLiteral(value);
912
+ if (value === null) return nullLiteral();
913
+ if (Array.isArray(value)) return arrayExpression(value.map((item) => valueToExpression(item) ?? nullLiteral()));
914
+ if (typeof value === "object") {
915
+ const properties = [];
916
+ for (const [key, item] of Object.entries(value)) {
917
+ const expr = valueToExpression(item);
918
+ if (expr === null) continue;
919
+ properties.push(objectProperty(stringLiteral(key), expr));
920
+ }
921
+ return objectExpression(properties);
922
+ }
923
+ return null;
924
+ };
925
+ const arrayExpressionToCode = (elements) => {
926
+ const nextAst = arrayExpression(elements);
927
+ return generateCode(nextAst);
928
+ };
929
+ //#endregion
930
+ //#region src/utils/ast/edit-source.ts
1011
931
  const childrenRange = (element) => {
1012
932
  const { openingElement, closingElement } = element;
1013
933
  if (!closingElement || openingElement.end == null || closingElement.start == null) return null;
@@ -1017,7 +937,7 @@ const childrenRange = (element) => {
1017
937
  };
1018
938
  };
1019
939
  const findAttribute = (opening, propertyName) => {
1020
- return opening.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === propertyName);
940
+ return opening.attributes.find((attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === propertyName);
1021
941
  };
1022
942
  const attributeInsertPoint = (opening) => {
1023
943
  return opening.attributes[opening.attributes.length - 1]?.end ?? opening.name.end ?? null;
@@ -1026,7 +946,7 @@ const editInnerText = (source, element, value) => {
1026
946
  const range = childrenRange(element);
1027
947
  if (!range) return [];
1028
948
  const [only] = element.children;
1029
- if (element.children.length === 1 && import_lib$1.isJSXText(only) && only.start != null && only.end != null) {
949
+ if (element.children.length === 1 && isJSXText(only) && only.start != null && only.end != null) {
1030
950
  const raw = source.slice(only.start, only.end);
1031
951
  if (raw.trim() !== "") {
1032
952
  const leading = raw.length - raw.trimStart().length;
@@ -1039,7 +959,7 @@ const editInnerText = (source, element, value) => {
1039
959
  }
1040
960
  }
1041
961
  const edits = [];
1042
- for (const child of element.children) if (import_lib$1.isJSXText(child) && child.start != null && child.end != null) edits.push({
962
+ for (const child of element.children) if (isJSXText(child) && child.start != null && child.end != null) edits.push({
1043
963
  start: child.start,
1044
964
  end: child.end,
1045
965
  content: ""
@@ -1069,7 +989,7 @@ const editRichtext = (element, value) => {
1069
989
  content: ""
1070
990
  });
1071
991
  const opening = element.openingElement;
1072
- 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))])));
992
+ const attribute = jsxAttribute(jsxIdentifier("dangerouslySetInnerHTML"), jsxExpressionContainer(objectExpression([objectProperty(identifier("__html"), stringLiteral(value))])));
1073
993
  const content = generateCode(attribute);
1074
994
  const existing = findAttribute(opening, "dangerouslySetInnerHTML");
1075
995
  if (existing && existing.start != null && existing.end != null) {
@@ -1108,11 +1028,11 @@ const editJsxAttribute = (opening, propertyName, value) => {
1108
1028
  content: `=${content}`
1109
1029
  }];
1110
1030
  };
1111
- const holdsStructuralExpression = (value) => import_lib$1.isJSXExpressionContainer(value) && (import_lib$1.isArrayExpression(unwrapExpression(value.expression)) || import_lib$1.isObjectExpression(unwrapExpression(value.expression)));
1031
+ const holdsStructuralExpression = (value) => isJSXExpressionContainer(value) && (isArrayExpression(unwrapExpression(value.expression)) || isObjectExpression(unwrapExpression(value.expression)));
1112
1032
  const structuralSource = (value) => {
1113
1033
  try {
1114
- const expression = (0, import_lib.parseExpression)(value.trim(), { plugins: ["jsx", "typescript"] });
1115
- return import_lib$1.isArrayExpression(unwrapExpression(expression)) || import_lib$1.isObjectExpression(unwrapExpression(expression)) ? expression : null;
1034
+ const expression = parseExpression(value.trim(), { plugins: ["jsx", "typescript"] });
1035
+ return isArrayExpression(unwrapExpression(expression)) || isObjectExpression(unwrapExpression(expression)) ? expression : null;
1116
1036
  } catch {
1117
1037
  return null;
1118
1038
  }
@@ -1120,29 +1040,29 @@ const structuralSource = (value) => {
1120
1040
  const buildAttributeValue = (value, type, current) => {
1121
1041
  if (type === "array" || type === "object") {
1122
1042
  if (typeof value === "string") try {
1123
- return import_lib$1.jsxExpressionContainer((0, import_lib.parseExpression)(value.trim(), { plugins: ["jsx", "typescript"] }));
1043
+ return jsxExpressionContainer(parseExpression(value.trim(), { plugins: ["jsx", "typescript"] }));
1124
1044
  } catch {
1125
- return import_lib$1.stringLiteral(value);
1045
+ return stringLiteral(value);
1126
1046
  }
1127
1047
  const expr = valueToExpression(value);
1128
- return expr ? import_lib$1.jsxExpressionContainer(expr) : import_lib$1.stringLiteral("");
1048
+ return expr ? jsxExpressionContainer(expr) : stringLiteral("");
1129
1049
  }
1130
1050
  if (typeof value === "string") {
1131
1051
  if (holdsStructuralExpression(current) && !(type && STRING_VALUED_TYPES.has(type))) {
1132
1052
  const structural = structuralSource(value);
1133
- if (structural) return import_lib$1.jsxExpressionContainer(structural);
1053
+ if (structural) return jsxExpressionContainer(structural);
1134
1054
  }
1135
- return import_lib$1.stringLiteral(value);
1055
+ return stringLiteral(value);
1136
1056
  }
1137
1057
  const expr = valueToExpression(value);
1138
- return expr ? import_lib$1.jsxExpressionContainer(expr) : import_lib$1.stringLiteral(String(value));
1058
+ return expr ? jsxExpressionContainer(expr) : stringLiteral(String(value));
1139
1059
  };
1140
1060
  const editAttribute = (opening, propertyName, value, type) => {
1141
1061
  const attribute = findAttribute(opening, propertyName);
1142
1062
  if (!attribute || attribute.start == null || attribute.end == null) return null;
1143
1063
  if (typeof value === "string" && (type === "array" || type === "object" || holdsStructuralExpression(attribute.value) && !(type && STRING_VALUED_TYPES.has(type)))) {
1144
1064
  const expression = structuralSource(value);
1145
- if (expression && import_lib$1.isJSXExpressionContainer(attribute.value)) {
1065
+ if (expression && isJSXExpressionContainer(attribute.value)) {
1146
1066
  const text = value.trim();
1147
1067
  const lineComment = expression.trailingComments?.some((comment) => comment.type === "CommentLine");
1148
1068
  return [{
@@ -1152,7 +1072,7 @@ const editAttribute = (opening, propertyName, value, type) => {
1152
1072
  }];
1153
1073
  }
1154
1074
  }
1155
- const content = generateCode(import_lib$1.jsxAttribute(attribute.name, buildAttributeValue(value, type, attribute.value)));
1075
+ const content = generateCode(jsxAttribute(attribute.name, buildAttributeValue(value, type, attribute.value)));
1156
1076
  return [{
1157
1077
  start: attribute.start,
1158
1078
  end: attribute.end,
@@ -1178,168 +1098,165 @@ const addAttribute = (source, opening, propertyName, value, type) => {
1178
1098
  return [{
1179
1099
  start: insertAt,
1180
1100
  end: insertAt,
1181
- 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)))}`,
1101
+ content: `${lastStart != null && lineStart > 0 && /^\s*$/.test(source.slice(lineStart, lastStart)) ? "\n" : " "}${type === "jsx" ? `${propertyName}={${String(value).trim()}}` : generateCode(jsxAttribute(jsxIdentifier(propertyName), buildAttributeValue(value, type)))}`,
1182
1102
  indent: true
1183
1103
  }];
1184
1104
  };
1185
1105
  const canEditAttributeValue = (attribute, value, type) => {
1186
- if (!import_lib$1.isJSXExpressionContainer(attribute.value) || import_lib$1.isJSXEmptyExpression(attribute.value.expression) || isLosslesslyEvaluable(attribute.value.expression)) return true;
1106
+ if (!isJSXExpressionContainer(attribute.value) || isJSXEmptyExpression(attribute.value.expression) || isLosslesslyEvaluable(attribute.value.expression)) return true;
1187
1107
  return typeof value === "string" && holdsStructuralExpression(attribute.value) && !(type && STRING_VALUED_TYPES.has(type)) && structuralSource(value) !== null;
1188
1108
  };
1109
+ //#endregion
1110
+ //#region src/utils/ast/update.ts
1111
+ const hasDataId = (opening, dataId) => opening.attributes.some((attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.ID && attr.value && isStringLiteral(attr.value) && attr.value.value === dataId);
1112
+ const findJSXAttribute = (opening, name) => opening.attributes.find((attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === name);
1113
+ const findBinding = (opening, { dataId, label, property, options }) => {
1114
+ const bindingAttr = findJSXAttribute(opening, DATA_ATTR.BINDING);
1115
+ if (bindingAttr && !bindingAttr.value) return { failure: {
1116
+ reason: "no-binding",
1117
+ dataId
1118
+ } };
1119
+ let own;
1120
+ if (bindingAttr?.value) {
1121
+ let bindingValue = "";
1122
+ if (isStringLiteral(bindingAttr.value)) bindingValue = bindingAttr.value.value;
1123
+ else if (isJSXExpressionContainer(bindingAttr.value)) try {
1124
+ bindingValue = generateCode(bindingAttr.value.expression);
1125
+ } catch (error) {
1126
+ return { failure: {
1127
+ reason: "parse-error",
1128
+ error
1129
+ } };
1130
+ }
1131
+ own = parseBinding(bindingValue);
1132
+ }
1133
+ const keyAttr = findJSXAttribute(opening, DATA_ATTR.BINDING_KEY);
1134
+ const bindings = resolveBindings(own, keyAttr && (keyAttr.value && isStringLiteral(keyAttr.value) ? keyAttr.value.value : null), getJSXTagName(opening), options);
1135
+ if (!own && bindings.length === 0) return { failure: {
1136
+ reason: "no-binding",
1137
+ dataId
1138
+ } };
1139
+ const matches = bindings.filter((binding) => property !== void 0 ? binding.property === property : binding.label === label);
1140
+ if (matches.length === 0) return { failure: {
1141
+ reason: "binding-not-declared",
1142
+ dataId,
1143
+ label,
1144
+ property
1145
+ } };
1146
+ if (matches.length > 1) return { failure: {
1147
+ reason: "duplicate-binding",
1148
+ dataId,
1149
+ label,
1150
+ property,
1151
+ count: matches.length
1152
+ } };
1153
+ return { binding: matches[0] };
1154
+ };
1155
+ const checkEdit = (binding, { dataId, value }) => {
1156
+ const property = binding.property;
1157
+ if (RESERVED_BINDING_PROPERTIES.includes(property)) return {
1158
+ reason: "reserved-property",
1159
+ dataId,
1160
+ property
1161
+ };
1162
+ if (value === void 0 && binding.required) return {
1163
+ reason: "required-property",
1164
+ dataId,
1165
+ property
1166
+ };
1167
+ };
1168
+ const toElementEdit = (result, onNull) => result ? { edits: result } : { failure: onNull() };
1169
+ const editProperty = (source, element, binding, { dataId, value, options }) => {
1170
+ const opening = element.openingElement;
1171
+ const prop = binding.property;
1172
+ const unset = value === void 0;
1173
+ const couldNotUpdate = () => ({
1174
+ reason: "parse-error",
1175
+ error: /* @__PURE__ */ new Error(`could not update "${prop}"`)
1176
+ });
1177
+ const contentWithoutSlot = !unset && String(value) !== "" && !childrenRange(element);
1178
+ switch (prop) {
1179
+ case BINDING_PROP.INNER_TEXT:
1180
+ if (contentWithoutSlot) return { failure: {
1181
+ reason: "self-closing",
1182
+ dataId,
1183
+ property: prop
1184
+ } };
1185
+ return toElementEdit(editInnerText(source, element, unset ? "" : String(value)), couldNotUpdate);
1186
+ case BINDING_PROP.INNER_HTML:
1187
+ if (contentWithoutSlot && binding.type !== "richtext") return { failure: {
1188
+ reason: "self-closing",
1189
+ dataId,
1190
+ property: prop
1191
+ } };
1192
+ return toElementEdit(binding.type === "richtext" ? editRichtext(element, unset ? "" : String(value)) : editInnerHTML(element, unset ? "" : String(value)), couldNotUpdate);
1193
+ case BINDING_PROP.CHILDREN:
1194
+ if (unset) return { failure: {
1195
+ reason: "unsupported-syntax",
1196
+ dataId,
1197
+ property: prop
1198
+ } };
1199
+ return toElementEdit(editChildrenSource(source, element, value, options), () => ({
1200
+ reason: "parse-error",
1201
+ error: /* @__PURE__ */ new Error("Unsupported or stale children edit; source was preserved")
1202
+ }));
1203
+ default: {
1204
+ const attribute = findAttribute(opening, prop);
1205
+ if (unset) return toElementEdit(attribute ? removeAttribute(source, attribute) : [], () => ({
1206
+ reason: "parse-error",
1207
+ error: /* @__PURE__ */ new Error(`could not remove "${prop}"`)
1208
+ }));
1209
+ if (!attribute) return toElementEdit(value === "" ? [] : addAttribute(source, opening, prop, value, binding.type), () => ({
1210
+ reason: "attribute-not-found",
1211
+ dataId,
1212
+ property: prop
1213
+ }));
1214
+ if (binding.type !== "jsx" && !canEditAttributeValue(attribute, value, binding.type)) return { failure: {
1215
+ reason: "unsupported-syntax",
1216
+ dataId,
1217
+ property: prop
1218
+ } };
1219
+ return toElementEdit(binding.type === "jsx" ? editJsxAttribute(opening, prop, value) : editAttribute(opening, prop, value, binding.type), () => ({
1220
+ reason: "attribute-not-found",
1221
+ dataId,
1222
+ property: prop
1223
+ }));
1224
+ }
1225
+ }
1226
+ };
1227
+ const editElement = (source, element, request) => {
1228
+ const found = findBinding(element.openingElement, request);
1229
+ if ("failure" in found) return found;
1230
+ const refused = checkEdit(found.binding, request);
1231
+ if (refused) return { failure: refused };
1232
+ return editProperty(source, element, found.binding, request);
1233
+ };
1189
1234
  const update = (code, dataId, label, value, property, options = {}) => {
1235
+ const request = {
1236
+ dataId,
1237
+ label,
1238
+ value,
1239
+ property,
1240
+ options
1241
+ };
1190
1242
  try {
1191
1243
  const wrapped = wrap(code);
1192
- const ast = (0, import_lib.parse)(wrapped, {
1244
+ const ast = parse(wrapped, {
1193
1245
  sourceType: "module",
1194
1246
  plugins: ["jsx", "typescript"]
1195
1247
  });
1196
1248
  let changed = false;
1197
1249
  let failure;
1198
1250
  const edits = [];
1199
- const collect = (result, onNull) => {
1200
- if (!result) {
1201
- failure = onNull();
1202
- return;
1203
- }
1204
- edits.push(...result);
1205
- changed = true;
1206
- };
1207
1251
  traverse(ast, { JSXElement(path) {
1208
- const opening = path.node.openingElement;
1209
- if (!opening.attributes.find((attr) => {
1210
- 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;
1211
- })) return;
1212
- const bindingAttr = opening.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING);
1213
- if (bindingAttr && !bindingAttr.value) {
1214
- failure = {
1215
- reason: "no-binding",
1216
- dataId
1217
- };
1252
+ if (!hasDataId(path.node.openingElement, dataId)) return;
1253
+ const result = editElement(wrapped, path.node, request);
1254
+ if ("failure" in result) {
1255
+ failure = result.failure;
1218
1256
  return;
1219
1257
  }
1220
- let own;
1221
- if (bindingAttr?.value) {
1222
- let bindingValue = "";
1223
- if (import_lib$1.isStringLiteral(bindingAttr.value)) bindingValue = bindingAttr.value.value;
1224
- else if (import_lib$1.isJSXExpressionContainer(bindingAttr.value)) try {
1225
- bindingValue = generateCode(bindingAttr.value.expression);
1226
- } catch (error) {
1227
- failure = {
1228
- reason: "parse-error",
1229
- error
1230
- };
1231
- return;
1232
- }
1233
- own = parseBinding(bindingValue);
1234
- }
1235
- const keyAttr = opening.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING_KEY);
1236
- const bindings = resolveBindings(own, keyAttr && (keyAttr.value && import_lib$1.isStringLiteral(keyAttr.value) ? keyAttr.value.value : null), getJSXTagName(opening), options);
1237
- if (!own && bindings.length === 0) {
1238
- failure = {
1239
- reason: "no-binding",
1240
- dataId
1241
- };
1242
- return;
1243
- }
1244
- const matches = bindings.filter((binding) => property !== void 0 ? binding.property === property : binding.label === label);
1245
- if (matches.length === 0) {
1246
- failure = {
1247
- reason: "binding-not-declared",
1248
- dataId,
1249
- label,
1250
- property
1251
- };
1252
- return;
1253
- }
1254
- if (matches.length > 1) {
1255
- failure = {
1256
- reason: "duplicate-binding",
1257
- dataId,
1258
- label,
1259
- property,
1260
- count: matches.length
1261
- };
1262
- return;
1263
- }
1264
- const propertyBinding = matches[0];
1265
- const prop = propertyBinding.property;
1266
- if (RESERVED_BINDING_PROPERTIES.includes(prop)) {
1267
- failure = {
1268
- reason: "reserved-property",
1269
- dataId,
1270
- property: prop
1271
- };
1272
- return;
1273
- }
1274
- const unset = value === void 0;
1275
- if (unset && propertyBinding.required) {
1276
- failure = {
1277
- reason: "required-property",
1278
- dataId,
1279
- property: prop
1280
- };
1281
- return;
1282
- }
1283
- switch (prop) {
1284
- case BINDING_PROP.INNER_TEXT:
1285
- collect(editInnerText(wrapped, path.node, unset ? "" : String(value)), () => ({
1286
- reason: "parse-error",
1287
- error: /* @__PURE__ */ new Error(`could not update "${prop}"`)
1288
- }));
1289
- break;
1290
- case BINDING_PROP.INNER_HTML:
1291
- collect(propertyBinding.type === "richtext" ? editRichtext(path.node, unset ? "" : String(value)) : editInnerHTML(path.node, unset ? "" : String(value)), () => ({
1292
- reason: "parse-error",
1293
- error: /* @__PURE__ */ new Error(`could not update "${prop}"`)
1294
- }));
1295
- break;
1296
- case BINDING_PROP.CHILDREN:
1297
- if (unset) {
1298
- failure = {
1299
- reason: "unsupported-syntax",
1300
- dataId,
1301
- property: prop
1302
- };
1303
- break;
1304
- }
1305
- collect(editChildrenSource(wrapped, path.node, value, options), () => ({
1306
- reason: "parse-error",
1307
- error: /* @__PURE__ */ new Error("Unsupported or stale children edit; source was preserved")
1308
- }));
1309
- break;
1310
- default: {
1311
- const attribute = findAttribute(opening, prop);
1312
- if (unset) {
1313
- collect(attribute ? removeAttribute(wrapped, attribute) : [], () => ({
1314
- reason: "parse-error",
1315
- error: /* @__PURE__ */ new Error(`could not remove "${prop}"`)
1316
- }));
1317
- break;
1318
- }
1319
- if (!attribute) {
1320
- collect(value === "" ? [] : addAttribute(wrapped, opening, prop, value, propertyBinding.type), () => ({
1321
- reason: "attribute-not-found",
1322
- dataId,
1323
- property: prop
1324
- }));
1325
- break;
1326
- }
1327
- if (attribute && propertyBinding.type !== "jsx" && !canEditAttributeValue(attribute, value, propertyBinding.type)) {
1328
- failure = {
1329
- reason: "unsupported-syntax",
1330
- dataId,
1331
- property: prop
1332
- };
1333
- break;
1334
- }
1335
- collect(propertyBinding.type === "jsx" ? editJsxAttribute(opening, prop, value) : editAttribute(opening, prop, value, propertyBinding.type), () => ({
1336
- reason: "attribute-not-found",
1337
- dataId,
1338
- property: prop
1339
- }));
1340
- break;
1341
- }
1342
- }
1258
+ edits.push(...result.edits);
1259
+ changed = true;
1343
1260
  } });
1344
1261
  if (!changed) return {
1345
1262
  code,
@@ -1427,7 +1344,7 @@ const commaIn = (source, start, end) => {
1427
1344
  };
1428
1345
  const denseArraySource = (source) => {
1429
1346
  const array = parseArrayExpression(source);
1430
- if (!array || array.elements.some((node) => !import_lib$1.isExpression(node) || node.extra?.parenthesized)) return null;
1347
+ if (!array || array.elements.some((node) => !isExpression(node) || node.extra?.parenthesized)) return null;
1431
1348
  const elements = array.elements;
1432
1349
  const commas = elements.slice(0, -1).map((node, index) => commaIn(source, node.end, elements[index + 1].start));
1433
1350
  if (commas.some((comma) => comma === null)) return null;
@@ -1487,9 +1404,9 @@ const appendArraySource = (source, data, copies) => {
1487
1404
  //#endregion
1488
1405
  //#region src/utils/ast/items.ts
1489
1406
  const elementsOf = (code) => parseArrayExpression(code)?.elements ?? null;
1490
- const kindOf = (element) => import_lib$1.isObjectExpression(element) ? "object" : "primitive";
1407
+ const kindOf = (element) => isObjectExpression(element) ? "object" : "primitive";
1491
1408
  const parseItems = (code) => {
1492
- return elementsOf(code)?.flatMap((node, index) => import_lib$1.isExpression(node) ? [{
1409
+ return elementsOf(code)?.flatMap((node, index) => isExpression(node) ? [{
1493
1410
  index,
1494
1411
  kind: kindOf(node),
1495
1412
  node
@@ -1505,23 +1422,23 @@ const toTemplateRaw = (value) => {
1505
1422
  const buildPropertyValue = (value, declaredType, renderLeaf, current) => {
1506
1423
  if (renderLeaf?.property === BINDING_PROP.INNER_HTML) {
1507
1424
  const raw = String(value);
1508
- return import_lib$1.templateLiteral([import_lib$1.templateElement({
1425
+ return templateLiteral([templateElement({
1509
1426
  raw: toTemplateRaw(raw),
1510
1427
  cooked: raw
1511
1428
  }, true)], []);
1512
1429
  }
1513
- if (renderLeaf?.type === "jsx" || import_lib$1.isJSXElement(current) || import_lib$1.isJSXFragment(current)) {
1430
+ if (renderLeaf?.type === "jsx" || isJSXElement(current) || isJSXFragment(current)) {
1514
1431
  const trimmed = String(value).trim();
1515
- if (!trimmed.startsWith("<")) return import_lib$1.stringLiteral(trimmed);
1432
+ if (!trimmed.startsWith("<")) return stringLiteral(trimmed);
1516
1433
  try {
1517
- return (0, import_lib.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
1434
+ return parseExpression(trimmed, { plugins: ["jsx", "typescript"] });
1518
1435
  } catch {
1519
1436
  return;
1520
1437
  }
1521
1438
  }
1522
1439
  if (declaredType === "array" || declaredType === "object") {
1523
1440
  if (typeof value === "string") try {
1524
- return (0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] });
1441
+ return parseExpression(value, { plugins: ["jsx", "typescript"] });
1525
1442
  } catch {
1526
1443
  return;
1527
1444
  }
@@ -1533,13 +1450,13 @@ const buildPropertyValue = (value, declaredType, renderLeaf, current) => {
1533
1450
  const updateArrayItemProperty = (code, index, key, value, render) => {
1534
1451
  const elements = elementsOf(code);
1535
1452
  const element = elements?.[index];
1536
- if (!elements || !import_lib$1.isObjectExpression(element)) return null;
1537
- const target = element.properties.find((property) => import_lib$1.isObjectProperty(property) && import_lib$1.isIdentifier(property.key) && property.key.name === key);
1453
+ if (!elements || !isObjectExpression(element)) return null;
1454
+ const target = element.properties.find((property) => isObjectProperty(property) && isIdentifier(property.key) && property.key.name === key);
1538
1455
  if (!target) return null;
1539
1456
  const declaredType = extractObjectProperties(element)[key]?.type ?? "string";
1540
1457
  const nextValue = buildPropertyValue(value, declaredType, resolveRenderLeaf(render, key), target.value);
1541
1458
  if (!nextValue) return null;
1542
- let serialized = typeof value === "string" && (declaredType === "array" || declaredType === "object" || import_lib$1.isJSXElement(nextValue) || import_lib$1.isJSXFragment(nextValue)) ? value.trim() : generateCode(nextValue);
1459
+ let serialized = typeof value === "string" && (declaredType === "array" || declaredType === "object" || isJSXElement(nextValue) || isJSXFragment(nextValue)) ? value.trim() : generateCode(nextValue);
1543
1460
  if (nextValue.trailingComments?.some((comment) => comment.type === "CommentLine")) serialized += "\n";
1544
1461
  const content = target.shorthand ? `${key}: ${serialized}` : serialized;
1545
1462
  return applyEdits(code, [{
@@ -1551,7 +1468,7 @@ const updateArrayItemProperty = (code, index, key, value, render) => {
1551
1468
  const updateArrayItemValue = (code, index, value) => {
1552
1469
  const elements = elementsOf(code);
1553
1470
  const element = elements?.[index];
1554
- if (!elements || !import_lib$1.isExpression(element)) return null;
1471
+ if (!elements || !isExpression(element)) return null;
1555
1472
  const nextValue = createNodeFromValue(extractNodeValue(element).type, parseValue(value));
1556
1473
  if (!nextValue) return null;
1557
1474
  return applyEdits(code, [{
@@ -1592,25 +1509,25 @@ const copyItem = (code, element, generateId, usedIds) => {
1592
1509
  usedIds.add(id);
1593
1510
  return JSON.stringify(id);
1594
1511
  };
1595
- import_lib$1.traverseFast(element, (node) => {
1596
- if (!import_lib$1.isJSXOpeningElement(node)) return;
1597
- const ids = node.attributes.filter((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name, { name: "data-id" }));
1512
+ traverseFast(element, (node) => {
1513
+ if (!isJSXOpeningElement(node)) return;
1514
+ const ids = node.attributes.filter((attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name, { name: "data-id" }));
1598
1515
  const attr = ids[0];
1599
- 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)))) {
1516
+ if (ids.length > 1 || attr && (!isStringLiteral(attr.value) || node.attributes.slice(node.attributes.indexOf(attr) + 1).some((a) => isJSXSpreadAttribute(a)))) {
1600
1517
  unsupported = true;
1601
1518
  return;
1602
1519
  }
1603
- if (attr && import_lib$1.isStringLiteral(attr.value)) edits.push({
1520
+ if (attr && isStringLiteral(attr.value)) edits.push({
1604
1521
  start: attr.value.start,
1605
1522
  end: attr.value.end,
1606
1523
  content: reserveId(generateId())
1607
1524
  });
1608
1525
  });
1609
- if (import_lib$1.isObjectExpression(element)) {
1610
- 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" })));
1526
+ if (isObjectExpression(element)) {
1527
+ const keys = element.properties.filter((prop) => isObjectProperty(prop) && !prop.computed && (isIdentifier(prop.key, { name: "key" }) || isStringLiteral(prop.key, { value: "key" })));
1611
1528
  const key = keys[0];
1612
- 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;
1613
- if (key && import_lib$1.isStringLiteral(key.value)) edits.push({
1529
+ if (keys.length > 1 || key && (!isStringLiteral(key.value) || element.properties.slice(element.properties.indexOf(key) + 1).some((prop) => isSpreadElement(prop) || "computed" in prop && prop.computed))) return null;
1530
+ if (key && isStringLiteral(key.value)) edits.push({
1614
1531
  start: key.value.start,
1615
1532
  end: key.value.end,
1616
1533
  content: reserveId(`${key.value.value}-${generateId()}`)
@@ -1627,9 +1544,9 @@ const duplicateArrayItems = (code, indices, generateId = () => nanoid(6)) => {
1627
1544
  const data = denseArraySource(code);
1628
1545
  if (!data || !indices.size || !validArrayIndices(indices, data.elements.length)) return null;
1629
1546
  const usedIds = /* @__PURE__ */ new Set();
1630
- import_lib$1.traverseFast(data.array, (node) => {
1631
- 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);
1632
- 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);
1547
+ traverseFast(data.array, (node) => {
1548
+ if (isJSXAttribute(node) && isJSXIdentifier(node.name, { name: "data-id" }) && isStringLiteral(node.value)) usedIds.add(node.value.value);
1549
+ else if (isObjectProperty(node) && !node.computed && (isIdentifier(node.key, { name: "key" }) || isStringLiteral(node.key, { value: "key" })) && isStringLiteral(node.value)) usedIds.add(node.value.value);
1633
1550
  });
1634
1551
  const copies = [...indices].sort((a, b) => a - b).map((index) => copyItem(code, data.elements[index], generateId, usedIds));
1635
1552
  return copies.every((copy) => copy !== null) ? appendArraySource(code, data, copies) : null;
@@ -1639,6 +1556,6 @@ const appendArrayItem = (code, kind, generateId = () => nanoid(6)) => {
1639
1556
  return index < 0 ? null : duplicateArrayItems(code, /* @__PURE__ */ new Set([index]), generateId);
1640
1557
  };
1641
1558
  //#endregion
1642
- export { extractNodeValue as A, parseBinding as C, arrayExpressionToCode as D, resolveBindings as E, setEditableValue as F, flattenEditableValue as M, parseArrayExpression as N, canLosslesslyEvaluateSource as O, parseValue as P, isComponentTagName as S, readNodeBindings as T, findEditableChildren as _, parseItems as a, getRegistryBindings as b, updateArrayItemValue as c, update as d, updateAll as f, extract as g, clearExtractCache as h, moveArrayItems as i, extractObjectProperties as j, createNodeFromValue as k, canStructurallyEditArray as l, moveSelectedIndices as m, duplicateArrayItems as n, removeArrayItems as o, getChildrenSignatures as p, moveArrayItem as r, updateArrayItemProperty as s, appendArrayItem as t, bulkUpdate as u, getCurrentValue as v, parseBindingExpression as w, getStructuredValue as x, getKeyBindings as y };
1559
+ export { extractNodeValue as A, getStructuredValue as C, readNodeBindings as D, parseBindingExpression as E, parseArrayExpression as M, parseValue as N, resolveBindings as O, unwrapExpression as P, getRegistryBindings as S, parseBinding as T, clearExtractCache as _, parseItems as a, getCurrentValue as b, updateArrayItemValue as c, update as d, updateAll as f, moveSelectedIndices as g, getChildrenSignatures as h, moveArrayItems as i, extractObjectProperties as j, canLosslesslyEvaluateSource as k, canStructurallyEditArray as l, createNodeFromValue as m, duplicateArrayItems as n, removeArrayItems as o, arrayExpressionToCode as p, moveArrayItem as r, updateArrayItemProperty as s, appendArrayItem as t, bulkUpdate as u, extract as v, isComponentTagName as w, getKeyBindings as x, findEditableChildren as y };
1643
1560
 
1644
- //# sourceMappingURL=items-DdrwGxJw.js.map
1561
+ //# sourceMappingURL=items-BXXtMUNI.js.map