attaform 0.0.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +142 -2
- package/dist/chunks/devtools.cjs +179 -0
- package/dist/chunks/devtools.cjs.map +1 -0
- package/dist/chunks/devtools.mjs +177 -0
- package/dist/chunks/devtools.mjs.map +1 -0
- package/dist/chunks/indexeddb.cjs +119 -0
- package/dist/chunks/indexeddb.cjs.map +1 -0
- package/dist/chunks/indexeddb.mjs +117 -0
- package/dist/chunks/indexeddb.mjs.map +1 -0
- package/dist/chunks/local-storage.cjs +58 -0
- package/dist/chunks/local-storage.cjs.map +1 -0
- package/dist/chunks/local-storage.mjs +56 -0
- package/dist/chunks/local-storage.mjs.map +1 -0
- package/dist/chunks/session-storage.cjs +58 -0
- package/dist/chunks/session-storage.cjs.map +1 -0
- package/dist/chunks/session-storage.mjs +56 -0
- package/dist/chunks/session-storage.mjs.map +1 -0
- package/dist/index.cjs +173 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +493 -0
- package/dist/index.d.mts +493 -0
- package/dist/index.d.ts +493 -0
- package/dist/index.mjs +141 -0
- package/dist/index.mjs.map +1 -0
- package/dist/nuxt.cjs +97 -0
- package/dist/nuxt.cjs.map +1 -0
- package/dist/nuxt.d.cts +38 -0
- package/dist/nuxt.d.mts +38 -0
- package/dist/nuxt.d.ts +38 -0
- package/dist/nuxt.mjs +94 -0
- package/dist/nuxt.mjs.map +1 -0
- package/dist/runtime/plugins/attaform.cjs +32 -0
- package/dist/runtime/plugins/attaform.cjs.map +1 -0
- package/dist/runtime/plugins/attaform.d.cts +5 -0
- package/dist/runtime/plugins/attaform.d.mts +5 -0
- package/dist/runtime/plugins/attaform.d.ts +5 -0
- package/dist/runtime/plugins/attaform.mjs +30 -0
- package/dist/runtime/plugins/attaform.mjs.map +1 -0
- package/dist/shared/attaform.B5GWYl76.cjs +386 -0
- package/dist/shared/attaform.B5GWYl76.cjs.map +1 -0
- package/dist/shared/attaform.BRTxpA3q.mjs +3283 -0
- package/dist/shared/attaform.BRTxpA3q.mjs.map +1 -0
- package/dist/shared/attaform.BYc9kugA.d.ts +124 -0
- package/dist/shared/attaform.Bubm_slq.cjs +622 -0
- package/dist/shared/attaform.Bubm_slq.cjs.map +1 -0
- package/dist/shared/attaform.BwaYWtMs.d.cts +126 -0
- package/dist/shared/attaform.BwaYWtMs.d.mts +126 -0
- package/dist/shared/attaform.BwaYWtMs.d.ts +126 -0
- package/dist/shared/attaform.CNJO3mME.cjs +3295 -0
- package/dist/shared/attaform.CNJO3mME.cjs.map +1 -0
- package/dist/shared/attaform.CRgix6_n.cjs +796 -0
- package/dist/shared/attaform.CRgix6_n.cjs.map +1 -0
- package/dist/shared/attaform.CXZgUECn.d.cts +124 -0
- package/dist/shared/attaform.CXpzmj38.mjs +617 -0
- package/dist/shared/attaform.CXpzmj38.mjs.map +1 -0
- package/dist/shared/attaform.Cc93zNzD.mjs +83 -0
- package/dist/shared/attaform.Cc93zNzD.mjs.map +1 -0
- package/dist/shared/attaform.DDXrY-1Q.d.cts +2568 -0
- package/dist/shared/attaform.DDXrY-1Q.d.mts +2568 -0
- package/dist/shared/attaform.DDXrY-1Q.d.ts +2568 -0
- package/dist/shared/attaform.DOKOyb3Y.d.mts +124 -0
- package/dist/shared/attaform.DlgKK10S.mjs +789 -0
- package/dist/shared/attaform.DlgKK10S.mjs.map +1 -0
- package/dist/shared/attaform.al_rpt7_.mjs +361 -0
- package/dist/shared/attaform.al_rpt7_.mjs.map +1 -0
- package/dist/shared/attaform.xKWYHMdq.cjs +89 -0
- package/dist/shared/attaform.xKWYHMdq.cjs.map +1 -0
- package/dist/transforms.cjs +11 -0
- package/dist/transforms.cjs.map +1 -0
- package/dist/transforms.d.cts +49 -0
- package/dist/transforms.d.mts +49 -0
- package/dist/transforms.d.ts +49 -0
- package/dist/transforms.mjs +2 -0
- package/dist/transforms.mjs.map +1 -0
- package/dist/vite.cjs +39 -0
- package/dist/vite.cjs.map +1 -0
- package/dist/vite.d.cts +53 -0
- package/dist/vite.d.mts +53 -0
- package/dist/vite.d.ts +53 -0
- package/dist/vite.mjs +37 -0
- package/dist/vite.mjs.map +1 -0
- package/dist/zod-v3.cjs +1511 -0
- package/dist/zod-v3.cjs.map +1 -0
- package/dist/zod-v3.d.cts +164 -0
- package/dist/zod-v3.d.mts +164 -0
- package/dist/zod-v3.d.ts +164 -0
- package/dist/zod-v3.mjs +1504 -0
- package/dist/zod-v3.mjs.map +1 -0
- package/dist/zod.cjs +1548 -0
- package/dist/zod.cjs.map +1 -0
- package/dist/zod.d.cts +67 -0
- package/dist/zod.d.mts +67 -0
- package/dist/zod.d.ts +67 -0
- package/dist/zod.mjs +1541 -0
- package/dist/zod.mjs.map +1 -0
- package/package.json +182 -6
|
@@ -0,0 +1,617 @@
|
|
|
1
|
+
import { createCompoundExpression, NodeTypes, createSimpleExpression, ElementTypes, processExpression } from '@vue/compiler-core';
|
|
2
|
+
|
|
3
|
+
function getSummarizedProps$1(node) {
|
|
4
|
+
if (!("props" in node)) return [];
|
|
5
|
+
const props = node.props;
|
|
6
|
+
const summarizedProps = props.reduce((acc, currProp) => {
|
|
7
|
+
if (currProp.type === NodeTypes.ATTRIBUTE) {
|
|
8
|
+
const key2 = currProp.name;
|
|
9
|
+
const value2 = currProp.value?.content ?? "";
|
|
10
|
+
return [...acc, { key: key2, value: renderAsStatic$1(value2, true) }];
|
|
11
|
+
}
|
|
12
|
+
if (currProp.exp === void 0) return acc;
|
|
13
|
+
const key = currProp.arg ? getSummarizedPropValue$1(currProp.arg) : renderAsStatic$1(currProp.name, true);
|
|
14
|
+
if (typeof key !== "string") return acc;
|
|
15
|
+
const value = getSummarizedPropValue$1(currProp.exp);
|
|
16
|
+
return [...acc, { key, value }];
|
|
17
|
+
}, []);
|
|
18
|
+
return summarizedProps;
|
|
19
|
+
}
|
|
20
|
+
function renderAsStatic$1(val, isStatic) {
|
|
21
|
+
return isStatic ? `"${val}"` : val;
|
|
22
|
+
}
|
|
23
|
+
function getSummarizedPropValue$1(exp) {
|
|
24
|
+
if (exp.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
25
|
+
return renderAsStatic$1(exp.content, exp.isStatic);
|
|
26
|
+
}
|
|
27
|
+
return exp.children;
|
|
28
|
+
}
|
|
29
|
+
function generateEqualityExpression$1(registerValue, optionValue, scalarTarget) {
|
|
30
|
+
const registerValueArr = Array.isArray(registerValue) ? registerValue : [registerValue];
|
|
31
|
+
const optionValueArr = Array.isArray(optionValue) ? optionValue : [optionValue];
|
|
32
|
+
const scalarTargetArr = Array.isArray(scalarTarget) ? scalarTarget : [scalarTarget];
|
|
33
|
+
return [
|
|
34
|
+
"Array.isArray((",
|
|
35
|
+
...registerValueArr,
|
|
36
|
+
")?.innerRef?.value) ? ",
|
|
37
|
+
"(",
|
|
38
|
+
...registerValueArr,
|
|
39
|
+
")?.innerRef?.value?.includes(",
|
|
40
|
+
...optionValueArr,
|
|
41
|
+
") : ",
|
|
42
|
+
"(",
|
|
43
|
+
...registerValueArr,
|
|
44
|
+
")?.innerRef?.value instanceof Set ? (",
|
|
45
|
+
...registerValueArr,
|
|
46
|
+
")?.innerRef?.value?.has(",
|
|
47
|
+
...optionValueArr,
|
|
48
|
+
") : ",
|
|
49
|
+
"((",
|
|
50
|
+
...registerValueArr,
|
|
51
|
+
")?.innerRef?.value === (",
|
|
52
|
+
...scalarTargetArr,
|
|
53
|
+
"))"
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
function removePropsByName$1(props, propNames) {
|
|
57
|
+
const removePropIndices = [];
|
|
58
|
+
for (let index = 0; index < props.length; index++) {
|
|
59
|
+
const prop = props[index];
|
|
60
|
+
if (!prop) continue;
|
|
61
|
+
if (propNames.includes(prop.name) || "arg" in prop && prop.arg && "content" in prop.arg && propNames.includes(prop.arg.content)) {
|
|
62
|
+
removePropIndices.push(index);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const index of removePropIndices.sort((a, z) => z - a)) {
|
|
66
|
+
props.splice(index, 1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function isExactKey$1(summarizedKey, name) {
|
|
70
|
+
return summarizedKey === name || summarizedKey === `"${name}"`;
|
|
71
|
+
}
|
|
72
|
+
function isStaticTypeOneOf(value, names) {
|
|
73
|
+
if (Array.isArray(value)) return false;
|
|
74
|
+
const trimmed = value.trim();
|
|
75
|
+
const literalMatch = /^(["'`])(.*)\1$/.exec(trimmed);
|
|
76
|
+
if (literalMatch === null) return false;
|
|
77
|
+
const inner = literalMatch[2].toLowerCase();
|
|
78
|
+
return names.includes(inner);
|
|
79
|
+
}
|
|
80
|
+
function couldResolveToFileType(value) {
|
|
81
|
+
if (Array.isArray(value)) return true;
|
|
82
|
+
const trimmed = value.trim();
|
|
83
|
+
const literalMatch = /^(["'`])(.*)\1$/.exec(trimmed);
|
|
84
|
+
if (literalMatch === null) return true;
|
|
85
|
+
const quote = literalMatch[1];
|
|
86
|
+
const inner = literalMatch[2];
|
|
87
|
+
if (quote === "`" && inner.includes("${")) return true;
|
|
88
|
+
return inner.toLowerCase() === "file";
|
|
89
|
+
}
|
|
90
|
+
const inputTextAreaNodeTransform = (node) => {
|
|
91
|
+
try {
|
|
92
|
+
let computeProps = function(_node, registerSummarizedProp2, elementValueSummarizedProp2) {
|
|
93
|
+
const injectedLoc = _node.loc;
|
|
94
|
+
const props = _node.props;
|
|
95
|
+
const isStaticCheckbox = typeProp !== void 0 && isStaticTypeOneOf(typeProp.value, ["checkbox"]);
|
|
96
|
+
const isStaticRadio = typeProp !== void 0 && isStaticTypeOneOf(typeProp.value, ["radio"]);
|
|
97
|
+
const keepStaticValue = isStaticCheckbox || isStaticRadio;
|
|
98
|
+
removePropsByName$1(props, keepStaticValue ? ["checked"] : ["checked", "value"]);
|
|
99
|
+
const registerValueArr = Array.isArray(registerSummarizedProp2.value) ? registerSummarizedProp2.value : [registerSummarizedProp2.value];
|
|
100
|
+
const valueExpression = createCompoundExpression([
|
|
101
|
+
"(",
|
|
102
|
+
...registerValueArr,
|
|
103
|
+
")?.displayValue?.value"
|
|
104
|
+
]);
|
|
105
|
+
const trueValueIndex = elementProps.findIndex((p) => isExactKey$1(p.key, "true-value"));
|
|
106
|
+
const trueValueProp = elementProps[trueValueIndex];
|
|
107
|
+
const scalarTarget = isStaticCheckbox ? trueValueProp !== void 0 ? trueValueProp.value : "true" : elementValueSummarizedProp2.value;
|
|
108
|
+
const valueOrCheckedProp = {
|
|
109
|
+
// reconstruct the `value` attribute based on the provided v-registerer, now that the computation is complete
|
|
110
|
+
arg: elementSelectionLabelExpression,
|
|
111
|
+
exp: createCompoundExpression([
|
|
112
|
+
"(",
|
|
113
|
+
...elementSelectionLabelExpression.children,
|
|
114
|
+
") === 'checked' ? (",
|
|
115
|
+
// resolves to a boolean
|
|
116
|
+
...generateEqualityExpression$1(
|
|
117
|
+
registerSummarizedProp2.value,
|
|
118
|
+
elementValueSummarizedProp2.value,
|
|
119
|
+
scalarTarget
|
|
120
|
+
),
|
|
121
|
+
") : (",
|
|
122
|
+
// resolves to the provided register value
|
|
123
|
+
...valueExpression.children,
|
|
124
|
+
")"
|
|
125
|
+
]),
|
|
126
|
+
name: "bind",
|
|
127
|
+
modifiers: [],
|
|
128
|
+
type: NodeTypes.DIRECTIVE,
|
|
129
|
+
loc: injectedLoc
|
|
130
|
+
};
|
|
131
|
+
props.push(valueOrCheckedProp);
|
|
132
|
+
};
|
|
133
|
+
if (node.type !== NodeTypes.ELEMENT) return;
|
|
134
|
+
const isInput = node.tag === "input";
|
|
135
|
+
const isTextArea = node.tag === "textarea";
|
|
136
|
+
if (!isInput && !isTextArea) return;
|
|
137
|
+
const elementProps = getSummarizedProps$1(node);
|
|
138
|
+
const registerIndex = elementProps.findIndex((p) => isExactKey$1(p.key, "register"));
|
|
139
|
+
const registerSummarizedProp = elementProps[registerIndex];
|
|
140
|
+
if (!registerSummarizedProp) return;
|
|
141
|
+
const typeIndex = elementProps.findIndex((p) => isExactKey$1(p.key, "type"));
|
|
142
|
+
const typeProp = elementProps[typeIndex];
|
|
143
|
+
if (typeProp !== void 0 && couldResolveToFileType(typeProp.value)) return;
|
|
144
|
+
const valueIndex = elementProps.findIndex((p) => isExactKey$1(p.key, "value"));
|
|
145
|
+
const elementValueSummarizedProp = elementProps?.[valueIndex] ?? {
|
|
146
|
+
key: "value",
|
|
147
|
+
value: "''"
|
|
148
|
+
};
|
|
149
|
+
const inputTypeIndex = typeIndex;
|
|
150
|
+
const defaultSummarizedTextProp = { key: "type", value: "'text'" };
|
|
151
|
+
const inputTypeSummarizedProp = inputTypeIndex === -1 ? defaultSummarizedTextProp : elementProps[inputTypeIndex] ?? defaultSummarizedTextProp;
|
|
152
|
+
const inputTypeExpressionArray = typeof inputTypeSummarizedProp.value === "string" ? [inputTypeSummarizedProp.value] : inputTypeSummarizedProp.value;
|
|
153
|
+
const elementSelectionLabelExpression = createCompoundExpression([
|
|
154
|
+
"(",
|
|
155
|
+
"String((",
|
|
156
|
+
...inputTypeExpressionArray,
|
|
157
|
+
")).toLowerCase()",
|
|
158
|
+
" === 'checkbox' || ",
|
|
159
|
+
"String((",
|
|
160
|
+
...inputTypeExpressionArray,
|
|
161
|
+
")).toLowerCase() === 'radio'",
|
|
162
|
+
") ? 'checked' : 'value'"
|
|
163
|
+
]);
|
|
164
|
+
computeProps(node, registerSummarizedProp, elementValueSummarizedProp);
|
|
165
|
+
} catch (err) {
|
|
166
|
+
console.error("[attaform] input/textarea transform failed, skipping:", err);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
function getSummarizedProps(node) {
|
|
171
|
+
if (!("props" in node)) return [];
|
|
172
|
+
const props = node.props;
|
|
173
|
+
const summarizedProps = props.reduce((acc, currProp) => {
|
|
174
|
+
if (currProp.type === NodeTypes.ATTRIBUTE) {
|
|
175
|
+
const key2 = currProp.name;
|
|
176
|
+
const value2 = currProp.value?.content ?? "";
|
|
177
|
+
return [...acc, { key: key2, value: renderAsStatic(value2, true) }];
|
|
178
|
+
}
|
|
179
|
+
if (currProp.exp === void 0) return acc;
|
|
180
|
+
const key = currProp.arg ? getSummarizedPropValue(currProp.arg) : renderAsStatic(currProp.name, true);
|
|
181
|
+
if (typeof key !== "string") return acc;
|
|
182
|
+
const value = getSummarizedPropValue(currProp.exp);
|
|
183
|
+
return [...acc, { key, value }];
|
|
184
|
+
}, []);
|
|
185
|
+
return summarizedProps;
|
|
186
|
+
}
|
|
187
|
+
function renderAsStatic(val, isStatic) {
|
|
188
|
+
return isStatic ? `"${val}"` : val;
|
|
189
|
+
}
|
|
190
|
+
function getSummarizedPropValue(exp) {
|
|
191
|
+
if (exp.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
192
|
+
return renderAsStatic(exp.content, exp.isStatic);
|
|
193
|
+
}
|
|
194
|
+
return exp.children;
|
|
195
|
+
}
|
|
196
|
+
function generateEqualityExpression(selectValue, optionValue, previousOptionExpressions) {
|
|
197
|
+
function getExpressionNodeChildren(_selectValue, _optionValue, _previousOptionExpressions) {
|
|
198
|
+
const multipleExpression = _previousOptionExpressions?.[0];
|
|
199
|
+
if (multipleExpression === void 0) {
|
|
200
|
+
throw new Error(
|
|
201
|
+
"Programming error: `multiple` expression for `select` node not generated while transforming AST"
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
const optExpressions = _previousOptionExpressions.slice(1);
|
|
205
|
+
const noMultipleOptExpressions = optExpressions.reduce(
|
|
206
|
+
(acc, curr, index) => {
|
|
207
|
+
if (index === 0) {
|
|
208
|
+
acc.push("(");
|
|
209
|
+
}
|
|
210
|
+
acc.push(...curr);
|
|
211
|
+
if (index < optExpressions.length - 1) {
|
|
212
|
+
acc.push(" || ");
|
|
213
|
+
}
|
|
214
|
+
if (index === optExpressions.length - 1) {
|
|
215
|
+
acc.push(")");
|
|
216
|
+
}
|
|
217
|
+
return acc;
|
|
218
|
+
},
|
|
219
|
+
[]
|
|
220
|
+
);
|
|
221
|
+
const selectValueArr = Array.isArray(_selectValue) ? _selectValue : [_selectValue];
|
|
222
|
+
const optionValueArr = Array.isArray(_optionValue) ? _optionValue : [_optionValue];
|
|
223
|
+
function getImplicitTrueMultipleExpression(expression) {
|
|
224
|
+
if (expression.length === 1 && expression[0] === "") return [`true`];
|
|
225
|
+
return expression;
|
|
226
|
+
}
|
|
227
|
+
_previousOptionExpressions.push(["(", ...selectValueArr, ") === (", ...optionValueArr, ")"]);
|
|
228
|
+
if (!noMultipleOptExpressions.length) {
|
|
229
|
+
return [
|
|
230
|
+
"(",
|
|
231
|
+
...getImplicitTrueMultipleExpression(multipleExpression),
|
|
232
|
+
`) ? ((`,
|
|
233
|
+
...selectValueArr,
|
|
234
|
+
`)?.innerRef?.value?.findIndex?.(el => el === (`,
|
|
235
|
+
...optionValueArr,
|
|
236
|
+
`)) > -1) : (typeof (`,
|
|
237
|
+
...selectValueArr,
|
|
238
|
+
`)?.innerRef?.value !== 'object' && String((`,
|
|
239
|
+
...selectValueArr,
|
|
240
|
+
`)?.innerRef?.value) === String((`,
|
|
241
|
+
...optionValueArr,
|
|
242
|
+
`)))`
|
|
243
|
+
];
|
|
244
|
+
}
|
|
245
|
+
return [
|
|
246
|
+
"(",
|
|
247
|
+
...getImplicitTrueMultipleExpression(multipleExpression),
|
|
248
|
+
`) ? ((`,
|
|
249
|
+
...selectValueArr,
|
|
250
|
+
`)?.innerRef?.value?.findIndex?.(el => el === (`,
|
|
251
|
+
...optionValueArr,
|
|
252
|
+
`)) > -1) : ((`,
|
|
253
|
+
...noMultipleOptExpressions,
|
|
254
|
+
// if true, we already found the relevant option
|
|
255
|
+
`) ? false : (typeof (`,
|
|
256
|
+
...selectValueArr,
|
|
257
|
+
`)?.innerRef?.value !== 'object' && String((`,
|
|
258
|
+
...selectValueArr,
|
|
259
|
+
`)?.innerRef?.value) === String((`,
|
|
260
|
+
...optionValueArr,
|
|
261
|
+
`))))`
|
|
262
|
+
];
|
|
263
|
+
}
|
|
264
|
+
return getExpressionNodeChildren(selectValue, optionValue, previousOptionExpressions);
|
|
265
|
+
}
|
|
266
|
+
function extractMultipleFromSelectSummarizedProps(props) {
|
|
267
|
+
const multipleDirectiveIndex = props.findIndex(
|
|
268
|
+
(prop) => prop.key.replace(/"/g, `'`) === "'multiple'"
|
|
269
|
+
);
|
|
270
|
+
const multipleAttributeIndex = props.findIndex((prop) => prop.key === "multiple");
|
|
271
|
+
if (multipleDirectiveIndex === -1 && multipleAttributeIndex === -1) {
|
|
272
|
+
return "false";
|
|
273
|
+
}
|
|
274
|
+
const priorityIndex = multipleDirectiveIndex >= 0 ? multipleDirectiveIndex : multipleAttributeIndex;
|
|
275
|
+
const value = props[priorityIndex]?.value;
|
|
276
|
+
return typeof value === "string" ? value.replace(/'|"/g, "") : value ?? "true";
|
|
277
|
+
}
|
|
278
|
+
function removePropsByName(props, propNames) {
|
|
279
|
+
const removePropIndices = [];
|
|
280
|
+
for (let index = 0; index < props.length; index++) {
|
|
281
|
+
const prop = props[index];
|
|
282
|
+
if (!prop) continue;
|
|
283
|
+
if (propNames.includes(prop.name) || "arg" in prop && prop.arg && "content" in prop.arg && propNames.includes(prop.arg.content)) {
|
|
284
|
+
removePropIndices.push(index);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
for (const index of removePropIndices.sort((a, z) => z - a)) {
|
|
288
|
+
props.splice(index, 1);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function flattenCompoundExpression(node) {
|
|
292
|
+
let result = "";
|
|
293
|
+
for (const child of node.children) {
|
|
294
|
+
if (typeof child === "string") {
|
|
295
|
+
result += child;
|
|
296
|
+
} else if (typeof child === "symbol") {
|
|
297
|
+
continue;
|
|
298
|
+
} else if (child.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
299
|
+
result += child.content;
|
|
300
|
+
} else if (child.type === NodeTypes.COMPOUND_EXPRESSION) {
|
|
301
|
+
result += flattenCompoundExpression(child);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
function isExactKey(summarizedKey, name) {
|
|
307
|
+
return summarizedKey === name || summarizedKey === `"${name}"`;
|
|
308
|
+
}
|
|
309
|
+
const RECURSABLE_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
310
|
+
NodeTypes.ELEMENT,
|
|
311
|
+
NodeTypes.FOR,
|
|
312
|
+
NodeTypes.IF,
|
|
313
|
+
NodeTypes.IF_BRANCH
|
|
314
|
+
]);
|
|
315
|
+
const NATIVE_FORM_TAGS = /* @__PURE__ */ new Set([
|
|
316
|
+
"input",
|
|
317
|
+
"textarea",
|
|
318
|
+
"select",
|
|
319
|
+
"option",
|
|
320
|
+
"form",
|
|
321
|
+
"fieldset",
|
|
322
|
+
"label",
|
|
323
|
+
"button"
|
|
324
|
+
]);
|
|
325
|
+
function inferOptionValueFromChildren(node) {
|
|
326
|
+
if (!("children" in node)) return null;
|
|
327
|
+
const children = node.children;
|
|
328
|
+
if (children.length !== 1) return null;
|
|
329
|
+
const only = children[0];
|
|
330
|
+
if (only === void 0) return null;
|
|
331
|
+
if (typeof only === "string" || typeof only === "symbol") return null;
|
|
332
|
+
if (only.type !== NodeTypes.TEXT) return null;
|
|
333
|
+
const text = only.content.trim();
|
|
334
|
+
return JSON.stringify(text);
|
|
335
|
+
}
|
|
336
|
+
const selectNodeTransform = (node, context) => {
|
|
337
|
+
const snapshots = [];
|
|
338
|
+
const snapshotProps = (target) => {
|
|
339
|
+
if (snapshots.some((entry) => entry.target === target)) return;
|
|
340
|
+
snapshots.push({ target, snapshot: [...target] });
|
|
341
|
+
};
|
|
342
|
+
try {
|
|
343
|
+
let traverseSelectNode = function(_node, previousOptionExpressions2) {
|
|
344
|
+
const isOption = _node.type === NodeTypes.ELEMENT && _node.tag === "option";
|
|
345
|
+
if (!isOption) {
|
|
346
|
+
if (!RECURSABLE_NODE_TYPES.has(_node.type)) return;
|
|
347
|
+
const hasChildren = "children" in _node;
|
|
348
|
+
if (!hasChildren) return;
|
|
349
|
+
for (const child of _node.children) {
|
|
350
|
+
if (typeof child === "symbol" || typeof child === "string") continue;
|
|
351
|
+
if (child.type === NodeTypes.SIMPLE_EXPRESSION) continue;
|
|
352
|
+
traverseSelectNode(child, previousOptionExpressions2);
|
|
353
|
+
}
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
const optionProps = getSummarizedProps(_node);
|
|
357
|
+
const valueIndex = optionProps.findIndex((p) => isExactKey(p.key, "value"));
|
|
358
|
+
let optionValueSummarizedProp;
|
|
359
|
+
if (valueIndex >= 0 && valueIndex < optionProps.length) {
|
|
360
|
+
optionValueSummarizedProp = optionProps[valueIndex];
|
|
361
|
+
} else {
|
|
362
|
+
const fallback = inferOptionValueFromChildren(_node);
|
|
363
|
+
if (fallback === null) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
optionValueSummarizedProp = { key: "value", value: fallback };
|
|
367
|
+
}
|
|
368
|
+
const props = _node.props;
|
|
369
|
+
snapshotProps(props);
|
|
370
|
+
removePropsByName(props, ["selected"]);
|
|
371
|
+
const newProp = {
|
|
372
|
+
arg: createSimpleExpression("selected", true),
|
|
373
|
+
exp: createCompoundExpression(
|
|
374
|
+
generateEqualityExpression(
|
|
375
|
+
registerSummarizedProp?.value ?? "undefined",
|
|
376
|
+
optionValueSummarizedProp?.value ?? "undefined",
|
|
377
|
+
previousOptionExpressions2
|
|
378
|
+
)
|
|
379
|
+
),
|
|
380
|
+
name: "bind",
|
|
381
|
+
modifiers: [],
|
|
382
|
+
type: NodeTypes.DIRECTIVE,
|
|
383
|
+
loc: _node.loc
|
|
384
|
+
};
|
|
385
|
+
props.push(newProp);
|
|
386
|
+
};
|
|
387
|
+
const isSelect = node.type === NodeTypes.ELEMENT && node.tag === "select";
|
|
388
|
+
const isCustomComponent = node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.COMPONENT;
|
|
389
|
+
const isKebabCustomElement = node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.ELEMENT && node.tag.includes("-") && !NATIVE_FORM_TAGS.has(node.tag);
|
|
390
|
+
if (!(isSelect || isCustomComponent || isKebabCustomElement)) return;
|
|
391
|
+
const selectSummarizedProps = getSummarizedProps(node);
|
|
392
|
+
const registerIndex = selectSummarizedProps.findIndex((p) => isExactKey(p.key, "register"));
|
|
393
|
+
if (selectSummarizedProps.length === 0 || registerIndex < 0 || registerIndex >= selectSummarizedProps.length)
|
|
394
|
+
return;
|
|
395
|
+
const registerSummarizedProp = selectSummarizedProps[registerIndex];
|
|
396
|
+
const selectLoc = node.loc;
|
|
397
|
+
const multipleExpression = extractMultipleFromSelectSummarizedProps(selectSummarizedProps);
|
|
398
|
+
const previousOptionExpressions = typeof multipleExpression === "string" ? [[multipleExpression]] : [multipleExpression];
|
|
399
|
+
const isStaticallyNonMultiple = multipleExpression === "false";
|
|
400
|
+
const selectProps = node.props;
|
|
401
|
+
snapshotProps(selectProps);
|
|
402
|
+
removePropsByName(selectProps, ["value"]);
|
|
403
|
+
if (isStaticallyNonMultiple) {
|
|
404
|
+
const valuePropExpArray = Array.isArray(registerSummarizedProp?.value) ? registerSummarizedProp.value : [registerSummarizedProp?.value ?? "undefined"];
|
|
405
|
+
const initExpression = createCompoundExpression([
|
|
406
|
+
"(",
|
|
407
|
+
...valuePropExpArray,
|
|
408
|
+
")?.displayValue.value"
|
|
409
|
+
]);
|
|
410
|
+
const simpleExpression = createSimpleExpression(
|
|
411
|
+
flattenCompoundExpression(initExpression),
|
|
412
|
+
false
|
|
413
|
+
);
|
|
414
|
+
let outputExp;
|
|
415
|
+
try {
|
|
416
|
+
outputExp = processExpression(simpleExpression, { ...context, prefixIdentifiers: false });
|
|
417
|
+
} catch (err) {
|
|
418
|
+
console.error(
|
|
419
|
+
"[attaform] select transform: processExpression failed; falling back to the unprocessed expression.",
|
|
420
|
+
err
|
|
421
|
+
);
|
|
422
|
+
outputExp = simpleExpression;
|
|
423
|
+
}
|
|
424
|
+
const valueProp = {
|
|
425
|
+
rawName: ":value",
|
|
426
|
+
arg: createSimpleExpression("value", true),
|
|
427
|
+
exp: outputExp,
|
|
428
|
+
name: "bind",
|
|
429
|
+
modifiers: [],
|
|
430
|
+
type: NodeTypes.DIRECTIVE,
|
|
431
|
+
loc: selectLoc
|
|
432
|
+
};
|
|
433
|
+
node.props.push(valueProp);
|
|
434
|
+
}
|
|
435
|
+
if (isSelect) {
|
|
436
|
+
for (const child of node.children) {
|
|
437
|
+
traverseSelectNode(child, previousOptionExpressions);
|
|
438
|
+
}
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
const registerProps = node.props.filter(
|
|
442
|
+
(x) => x.type === NodeTypes.DIRECTIVE && x.name === "register"
|
|
443
|
+
);
|
|
444
|
+
const registerProp = registerProps[0];
|
|
445
|
+
if (!registerProp) return;
|
|
446
|
+
const alreadyInjected = node.props.some(
|
|
447
|
+
(p) => p.type === NodeTypes.DIRECTIVE && p.name === "bind" && p.arg !== void 0 && "content" in p.arg && p.arg.content === "registerValue"
|
|
448
|
+
);
|
|
449
|
+
if (alreadyInjected) return;
|
|
450
|
+
const customElementProp = {
|
|
451
|
+
arg: createSimpleExpression("registerValue", true),
|
|
452
|
+
exp: "exp" in registerProp ? registerProp.exp : createSimpleExpression("undefined", false),
|
|
453
|
+
name: "bind",
|
|
454
|
+
modifiers: [],
|
|
455
|
+
type: NodeTypes.DIRECTIVE,
|
|
456
|
+
loc: selectLoc
|
|
457
|
+
};
|
|
458
|
+
node.props.push(customElementProp);
|
|
459
|
+
} catch (err) {
|
|
460
|
+
for (const { target, snapshot } of snapshots.slice().reverse()) {
|
|
461
|
+
target.splice(0, target.length, ...snapshot);
|
|
462
|
+
}
|
|
463
|
+
console.error("[attaform] select transform failed, skipping:", err);
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
const HINT_MARKER = "__attaRv";
|
|
468
|
+
const HINT_PREFIX = `((${HINT_MARKER}) => (${HINT_MARKER}?.markConnectedOptimistically?.(), ${HINT_MARKER}))(`;
|
|
469
|
+
const HINT_SUFFIX = `)`;
|
|
470
|
+
const vRegisterHintTransform = (node) => {
|
|
471
|
+
try {
|
|
472
|
+
if (node.type !== NodeTypes.ELEMENT) return;
|
|
473
|
+
for (const prop of node.props) {
|
|
474
|
+
if (prop.type !== NodeTypes.DIRECTIVE) continue;
|
|
475
|
+
if (prop.name !== "register") continue;
|
|
476
|
+
if (prop.exp === void 0) continue;
|
|
477
|
+
if (isAlreadyWrapped(prop.exp)) continue;
|
|
478
|
+
prop.exp = wrapWithOptimisticHint(prop.exp);
|
|
479
|
+
}
|
|
480
|
+
} catch (err) {
|
|
481
|
+
console.error("[attaform] v-register hint transform failed, skipping:", err);
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
function isAlreadyWrapped(exp) {
|
|
485
|
+
if (exp.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
486
|
+
return exp.content.includes(HINT_MARKER);
|
|
487
|
+
}
|
|
488
|
+
for (const child of exp.children) {
|
|
489
|
+
if (typeof child === "string" && child.includes(HINT_MARKER)) return true;
|
|
490
|
+
}
|
|
491
|
+
return false;
|
|
492
|
+
}
|
|
493
|
+
function wrapWithOptimisticHint(exp) {
|
|
494
|
+
const innerChildren = exp.type === NodeTypes.SIMPLE_EXPRESSION ? [exp] : [...exp.children];
|
|
495
|
+
return createCompoundExpression([HINT_PREFIX, ...innerChildren, HINT_SUFFIX], exp.loc);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
const stateByRoot = /* @__PURE__ */ new WeakMap();
|
|
499
|
+
const PREAMBLE_ATTR = "data-atta-pre-mark";
|
|
500
|
+
const vRegisterPreambleTransform = (node, context) => {
|
|
501
|
+
try {
|
|
502
|
+
if (node.type === NodeTypes.ROOT) {
|
|
503
|
+
if (stateByRoot.has(node)) return;
|
|
504
|
+
stateByRoot.set(node, {
|
|
505
|
+
captured: [],
|
|
506
|
+
capturedElements: /* @__PURE__ */ new WeakSet(),
|
|
507
|
+
vForDepth: 0,
|
|
508
|
+
firstRootElementVisited: false
|
|
509
|
+
});
|
|
510
|
+
return () => {
|
|
511
|
+
stateByRoot.delete(node);
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
const state = stateByRoot.get(context.root);
|
|
515
|
+
if (state === void 0) return;
|
|
516
|
+
if (node.type === NodeTypes.FOR) {
|
|
517
|
+
state.vForDepth += 1;
|
|
518
|
+
return () => {
|
|
519
|
+
state.vForDepth -= 1;
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
if (node.type !== NodeTypes.ELEMENT) return;
|
|
523
|
+
captureVRegisterIfStatic(node, state);
|
|
524
|
+
if (!state.firstRootElementVisited && context.parent?.type === NodeTypes.ROOT) {
|
|
525
|
+
state.firstRootElementVisited = true;
|
|
526
|
+
return () => {
|
|
527
|
+
const finalState = stateByRoot.get(context.root);
|
|
528
|
+
if (finalState === void 0 || finalState.captured.length === 0) return;
|
|
529
|
+
injectPreamble(node, finalState.captured);
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
return;
|
|
533
|
+
} catch (err) {
|
|
534
|
+
console.error("[attaform] v-register preamble transform failed, skipping:", err);
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
function captureVRegisterIfStatic(node, state) {
|
|
539
|
+
if (state.vForDepth > 0) return;
|
|
540
|
+
if (hasVForDirective(node)) return;
|
|
541
|
+
if (state.capturedElements.has(node)) return;
|
|
542
|
+
const exp = findVRegisterExpression(node);
|
|
543
|
+
if (exp === null) return;
|
|
544
|
+
state.capturedElements.add(node);
|
|
545
|
+
state.captured.push(flattenExpression(exp));
|
|
546
|
+
}
|
|
547
|
+
function findVRegisterExpression(node) {
|
|
548
|
+
for (const prop of node.props) {
|
|
549
|
+
if (prop.type !== NodeTypes.DIRECTIVE) continue;
|
|
550
|
+
if (prop.name !== "register") continue;
|
|
551
|
+
if (prop.exp === void 0) continue;
|
|
552
|
+
return prop.exp;
|
|
553
|
+
}
|
|
554
|
+
return null;
|
|
555
|
+
}
|
|
556
|
+
function hasVForDirective(node) {
|
|
557
|
+
for (const prop of node.props) {
|
|
558
|
+
if (prop.type === NodeTypes.DIRECTIVE && prop.name === "for") return true;
|
|
559
|
+
}
|
|
560
|
+
return false;
|
|
561
|
+
}
|
|
562
|
+
function flattenExpression(exp) {
|
|
563
|
+
if (exp.type === NodeTypes.SIMPLE_EXPRESSION) return exp.content;
|
|
564
|
+
let out = "";
|
|
565
|
+
for (const child of exp.children) {
|
|
566
|
+
if (typeof child === "string") {
|
|
567
|
+
out += child;
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
if (typeof child === "symbol") continue;
|
|
571
|
+
if ("content" in child) {
|
|
572
|
+
out += child.content;
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
out += flattenExpression(child);
|
|
576
|
+
}
|
|
577
|
+
return out;
|
|
578
|
+
}
|
|
579
|
+
function injectPreamble(element, captured) {
|
|
580
|
+
if (hasPreamble(element)) return;
|
|
581
|
+
const callList = captured.map((source) => `(()=>{try{(${source})?.markConnectedOptimistically?.()}catch{}})()`).join(", ");
|
|
582
|
+
const expressionText = `(${callList}, undefined)`;
|
|
583
|
+
const exp = createSimpleExpression(
|
|
584
|
+
expressionText,
|
|
585
|
+
false
|
|
586
|
+
/* not static */
|
|
587
|
+
);
|
|
588
|
+
const directive = {
|
|
589
|
+
type: NodeTypes.DIRECTIVE,
|
|
590
|
+
name: "bind",
|
|
591
|
+
arg: createSimpleExpression(
|
|
592
|
+
PREAMBLE_ATTR,
|
|
593
|
+
true
|
|
594
|
+
/* static arg */
|
|
595
|
+
),
|
|
596
|
+
exp,
|
|
597
|
+
modifiers: [],
|
|
598
|
+
// Reuse the host element's source location so any runtime error
|
|
599
|
+
// in the synthesized expression points at the consumer's template
|
|
600
|
+
// line, not at the dummyLoc that pre-fix was line 0.
|
|
601
|
+
loc: element.loc
|
|
602
|
+
};
|
|
603
|
+
element.props.unshift(directive);
|
|
604
|
+
}
|
|
605
|
+
function hasPreamble(element) {
|
|
606
|
+
for (const prop of element.props) {
|
|
607
|
+
if (prop.type !== NodeTypes.DIRECTIVE) continue;
|
|
608
|
+
if (prop.name !== "bind") continue;
|
|
609
|
+
if (prop.arg === void 0) continue;
|
|
610
|
+
if (prop.arg.type !== NodeTypes.SIMPLE_EXPRESSION) continue;
|
|
611
|
+
if (prop.arg.content === PREAMBLE_ATTR) return true;
|
|
612
|
+
}
|
|
613
|
+
return false;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
export { vRegisterPreambleTransform as a, inputTextAreaNodeTransform as i, selectNodeTransform as s, vRegisterHintTransform as v };
|
|
617
|
+
//# sourceMappingURL=attaform.CXpzmj38.mjs.map
|