@vue-jsx/macros 3.3.0-beta.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/dist/api.d.ts +1546 -0
- package/dist/api.js +2 -0
- package/dist/astro.d.ts +11 -0
- package/dist/astro.js +11 -0
- package/dist/bun.d.ts +6 -0
- package/dist/bun.js +5 -0
- package/dist/core-BRE2gjfq.js +935 -0
- package/dist/esbuild.d.ts +7 -0
- package/dist/esbuild.js +5 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/nuxt.d.ts +8 -0
- package/dist/nuxt.js +17 -0
- package/dist/options-CtTcew0x.d.ts +42 -0
- package/dist/options.d.ts +2 -0
- package/dist/options.js +28 -0
- package/dist/raw-Qfl50r_v.js +92 -0
- package/dist/raw.d.ts +7 -0
- package/dist/raw.js +2 -0
- package/dist/rolldown.d.ts +7 -0
- package/dist/rolldown.js +5 -0
- package/dist/rollup.d.ts +7 -0
- package/dist/rollup.js +5 -0
- package/dist/rsbuild.d.ts +9 -0
- package/dist/rsbuild.js +12 -0
- package/dist/rspack.d.ts +6 -0
- package/dist/rspack.js +5 -0
- package/dist/vite.d.ts +7 -0
- package/dist/vite.js +5 -0
- package/dist/volar.d.ts +11 -0
- package/dist/volar.js +385 -0
- package/dist/webpack.d.ts +7 -0
- package/dist/webpack.js +5 -0
- package/package.json +100 -0
package/dist/volar.js
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { resolveOptions } from "./options.js";
|
|
2
|
+
import { allCodeFeatures, createPlugin, getText } from "ts-macro";
|
|
3
|
+
import { createFilter } from "unplugin-utils";
|
|
4
|
+
//#region src/volar/define-component.ts
|
|
5
|
+
function transformDefineComponent(node, parent, options) {
|
|
6
|
+
const { codes, ast, ts } = options;
|
|
7
|
+
const [comp, compOptions] = node.arguments;
|
|
8
|
+
codes.replaceRange(comp.end, node.end - 1);
|
|
9
|
+
const isFnComponent = (ts.isArrowFunction(comp) || ts.isFunctionExpression(comp)) && comp.typeParameters?.length;
|
|
10
|
+
const isVaporComponent = node.expression.getText(ast).includes("defineVapor");
|
|
11
|
+
codes.replaceRange(node.getStart(ast), node.expression.end, ts.isExpressionStatement(parent) ? ";" : "", isFnComponent ? "" : `(() => {
|
|
12
|
+
const __setup = `);
|
|
13
|
+
if (isFnComponent) {
|
|
14
|
+
codes.push("\n;[", [node.expression.getText(ast), node.expression.getStart(ast)], "]");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
codes.replaceRange(node.end, node.end, `
|
|
18
|
+
type __Setup = typeof __setup
|
|
19
|
+
type __Props = Parameters<__Setup>[0]
|
|
20
|
+
type __Slots = Parameters<__Setup>[1] extends { slots?: infer Slots } | undefined ? Slots : {}
|
|
21
|
+
type __Exposed = Parameters<__Setup>[1] extends { expose?: (exposed: infer Exposed) => any } | undefined ? Exposed : {}`, "\n return ", [node.expression.getText(ast), node.expression.getStart(ast)], `({\n ...{} as {
|
|
22
|
+
setup: (props: __Props) => __Exposed,
|
|
23
|
+
render: () => ReturnType<__Setup>,
|
|
24
|
+
slots: ${isVaporComponent ? "__Slots" : `import('vue').SlotsType<__Slots>`}
|
|
25
|
+
},`, ...compOptions ? ["...", [compOptions.getText(ast), compOptions.getStart(ast)]] : [], `})`, `\n})()`);
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/volar/global-types.ts
|
|
29
|
+
function getGlobalTypes(rootMap, options) {
|
|
30
|
+
let defineStyle = "";
|
|
31
|
+
if (options.defineSlots.alias) {
|
|
32
|
+
defineStyle = options.defineStyle.alias.map((alias) => `declare const ${alias}: { <T>(...args: __StyleArgs): T; scss: <T>(...args: __StyleArgs)=> T; sass: <T>(...args: __StyleArgs)=> T; stylus: <T>(...args: __StyleArgs)=> T; less: <T>(...args: __StyleArgs)=> T; postcss: <T>(...args: __StyleArgs)=> T };`).join("\n");
|
|
33
|
+
defineStyle += `\ntype __StyleArgs = [style: string, options?: { scoped?: boolean }];`;
|
|
34
|
+
}
|
|
35
|
+
if (!rootMap.size) return `\n${defineStyle}`;
|
|
36
|
+
const defineSlots = options.defineSlots.alias.flatMap((alias) => [`declare function ${alias}<T extends Record<string, any>>(): Partial<T>;`, `declare function ${alias}<T extends Record<string, any>>(slots: T): T;`]).join("\n");
|
|
37
|
+
const defineExpose = options.defineExpose.alias.map((alias) => `declare function ${alias}<Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed): Exposed;`).join("\n");
|
|
38
|
+
const defineModel = options.defineModel.alias.map((alias) => alias === "defineModel" ? "defineModel" : `defineModel: ${alias}`);
|
|
39
|
+
return `
|
|
40
|
+
${defineModel.length ? `declare const { ${defineModel.join(",")} }: typeof import('vue');` : ""}
|
|
41
|
+
${defineSlots}
|
|
42
|
+
${defineExpose}
|
|
43
|
+
${defineStyle}
|
|
44
|
+
type __ResolveSlots<T> = {
|
|
45
|
+
[K in keyof T]?: T[K] extends Record<string, any>
|
|
46
|
+
? (props: T[K]) => any
|
|
47
|
+
: T[K]
|
|
48
|
+
};
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/volar/define-style.ts
|
|
53
|
+
function transformDefineStyle({ expression, isCssModules }, index, root, options) {
|
|
54
|
+
const { ts, codes, ast } = options;
|
|
55
|
+
if (isCssModules && expression?.arguments[0] && !expression.typeArguments && ts.isTemplateLiteral(expression.arguments[0])) codes.replaceRange(expression.arguments.pos - 1, expression.arguments.pos - 1, `<{`, ...parseCssClassNames(expression.arguments[0].getText(ast).slice(1, -1)).flatMap(({ text, offset }) => [
|
|
56
|
+
`\n`,
|
|
57
|
+
[
|
|
58
|
+
`'${text.slice(1)}'`,
|
|
59
|
+
`style_${index}`,
|
|
60
|
+
expression.arguments.pos + offset + 1,
|
|
61
|
+
{ navigation: true }
|
|
62
|
+
],
|
|
63
|
+
`: string`
|
|
64
|
+
]), "\n}>");
|
|
65
|
+
else if (root?.body) {
|
|
66
|
+
const returnNode = root.body.forEachChild((node) => ts.isReturnStatement(node) ? node : void 0);
|
|
67
|
+
if (returnNode) {
|
|
68
|
+
codes.replaceRange(expression.getStart(ast), expression.getEnd());
|
|
69
|
+
codes.replaceRange(returnNode.pos, returnNode.pos, ";", [expression.getText(ast), expression.getStart(ast)]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
addEmbeddedCode(expression, index, options);
|
|
73
|
+
}
|
|
74
|
+
const commentReg = /(?<=\/\*)[\s\S]*?(?=\*\/)|(?<=\/\/)[\s\S]*?(?=\n)/g;
|
|
75
|
+
const cssClassNameReg = /(?=(\.[a-z_][-\w]*)[\s.,+~>:#)[{])/gi;
|
|
76
|
+
const fragmentReg = /(?<=\{)[^{]*(?=(?<!\\);)/g;
|
|
77
|
+
function parseCssClassNames(css) {
|
|
78
|
+
for (const reg of [commentReg, fragmentReg]) css = css.replace(reg, (match) => " ".repeat(match.length));
|
|
79
|
+
const matches = css.matchAll(cssClassNameReg);
|
|
80
|
+
const result = [];
|
|
81
|
+
for (const match of matches) {
|
|
82
|
+
const matchText = match[1];
|
|
83
|
+
if (matchText) result.push({
|
|
84
|
+
offset: match.index,
|
|
85
|
+
text: matchText
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
function addEmbeddedCode(expression, index, options) {
|
|
91
|
+
const { ts, ast } = options;
|
|
92
|
+
const languageId = ts.isPropertyAccessExpression(expression.expression) && ts.isIdentifier(expression.expression.name) ? expression.expression.name.text : "css";
|
|
93
|
+
const style = expression.arguments[0];
|
|
94
|
+
const styleText = style.getText(ast).slice(1, -1).replaceAll(/\$\{.*\}/g, (str) => "_".repeat(str.length));
|
|
95
|
+
options.embeddedCodes.push({
|
|
96
|
+
id: `style_${index}`,
|
|
97
|
+
languageId,
|
|
98
|
+
snapshot: {
|
|
99
|
+
getText: (start, end) => styleText.slice(start, end),
|
|
100
|
+
getLength: () => styleText.length,
|
|
101
|
+
getChangeRange: () => void 0
|
|
102
|
+
},
|
|
103
|
+
mappings: [{
|
|
104
|
+
sourceOffsets: [style.getStart(ast) + 1],
|
|
105
|
+
generatedOffsets: [0],
|
|
106
|
+
lengths: [styleText.length],
|
|
107
|
+
data: allCodeFeatures
|
|
108
|
+
}],
|
|
109
|
+
embeddedCodes: []
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
113
|
+
//#region src/volar/slot.ts
|
|
114
|
+
function transformSlot(slotNode, options) {
|
|
115
|
+
const { ts, codes, ast } = options;
|
|
116
|
+
if (slotNode.tagName.getText(ast) === "slot") {
|
|
117
|
+
let nameProp = ["default"];
|
|
118
|
+
const props = [];
|
|
119
|
+
let has_directive = false;
|
|
120
|
+
slotNode.attributes.forEachChild((node) => {
|
|
121
|
+
if (ts.isJsxAttribute(node)) {
|
|
122
|
+
const name = node.name.getText(ast);
|
|
123
|
+
if (name.startsWith("v-")) {
|
|
124
|
+
has_directive = true;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (name === "name" && node.initializer) nameProp = ts.isJsxExpression(node.initializer) && node.initializer.expression ? [
|
|
128
|
+
"[",
|
|
129
|
+
[node.initializer.expression.getText(ast), node.initializer.expression.getStart(ast)],
|
|
130
|
+
"]"
|
|
131
|
+
] : [[node.initializer.getText(ast), node.initializer.getStart(ast)]];
|
|
132
|
+
else {
|
|
133
|
+
const shouldResolve = name.includes("-") || ts.isJsxNamespacedName(node.name);
|
|
134
|
+
props.push(shouldResolve ? "\"" : "", [name, node.name.getStart(ast)], shouldResolve ? "\"" : "", ": ", node.initializer ? ts.isJsxExpression(node.initializer) && node.initializer.expression ? [node.initializer.expression.getText(ast), node.initializer.expression.getStart(ast)] : [node.initializer.getText(ast), node.initializer.getStart(ast)] : "true", ", ");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
if (has_directive) return;
|
|
139
|
+
codes.replaceRange(slotNode.attributes.pos, slotNode.attributes.end, " {...(__slots = { ...__slots || {}, ", ...nameProp, ": { ", ...props, "}})}");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region src/volar/transform.ts
|
|
144
|
+
function transformJsxMacros(rootMap, options) {
|
|
145
|
+
const { ts, codes, ast } = options;
|
|
146
|
+
let defineStyleIndex = 0;
|
|
147
|
+
for (const [root, macros] of rootMap) {
|
|
148
|
+
macros.defineStyle?.forEach((defaultStyle) => transformDefineStyle(defaultStyle, defineStyleIndex++, root, options));
|
|
149
|
+
if (!root?.body || ts.isExpression(root.body) || Object.keys(macros).length === 1 && macros.defineStyle) continue;
|
|
150
|
+
const asyncModifier = root.modifiers?.find((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword);
|
|
151
|
+
if (asyncModifier && macros.defineComponent) codes.replaceRange(asyncModifier.pos, asyncModifier.end);
|
|
152
|
+
const result = "({}) as typeof __ctx.render & { __ctx?: { props: typeof __ctx.props } & typeof __ctx.context }";
|
|
153
|
+
const propsType = root.parameters[0]?.type ? root.parameters[0].type.getText(ast) : "{}";
|
|
154
|
+
codes.replaceRange(root.parameters.pos, root.parameters.pos, ts.isArrowFunction(root) && root.parameters.pos === root.pos ? "(" : "", `__props: typeof __ctx.props & ${propsType}, `, `__context?: typeof __ctx.context, `, `__ctx = {} as Awaited<ReturnType<typeof __fn>>, `, `__fn = (${asyncModifier ? "async" : ""}(`);
|
|
155
|
+
if (ts.isArrowFunction(root)) codes.replaceRange(root.end, root.end, `))${root.pos === root.parameters.pos ? ")" : ""} => `, result);
|
|
156
|
+
else {
|
|
157
|
+
codes.replaceRange(root.body.getStart(ast), root.body.getStart(ast), "=>");
|
|
158
|
+
codes.replaceRange(root.end, root.end, `)){ return `, result, "}");
|
|
159
|
+
}
|
|
160
|
+
if (macros.slots && !macros.defineSlots) {
|
|
161
|
+
macros.defineSlots = "__ResolveSlots<typeof __slots>";
|
|
162
|
+
const start = root.body.getStart(ast);
|
|
163
|
+
codes.replaceRange(start + 1, start + 1, "let __slots;");
|
|
164
|
+
macros.slots.map((node) => transformSlot(node, options));
|
|
165
|
+
}
|
|
166
|
+
root.body.forEachChild((node) => {
|
|
167
|
+
if (ts.isReturnStatement(node) && node.expression) {
|
|
168
|
+
const props = [...macros.defineModel ?? []];
|
|
169
|
+
const elements = root.parameters[0] && !root.parameters[0].type && ts.isObjectBindingPattern(root.parameters[0].name) ? root.parameters[0].name.elements : [];
|
|
170
|
+
for (const element of elements) if (ts.isIdentifier(element.name)) {
|
|
171
|
+
const isRequired = element.initializer && ts.isNonNullExpression(element.initializer);
|
|
172
|
+
props.push(`${element.name.escapedText}${isRequired ? ":" : "?:"} typeof ${element.name.escapedText}`);
|
|
173
|
+
}
|
|
174
|
+
const isDefineComponent = macros.defineComponent && ["defineComponent", "defineCustomElement"].includes(macros.defineComponent.expression.getText(ast));
|
|
175
|
+
codes.replaceRange(node.getStart(ast), node.expression.getStart(ast), "const ", [
|
|
176
|
+
`__rndr`,
|
|
177
|
+
node.getStart(ast),
|
|
178
|
+
{ verification: true }
|
|
179
|
+
], isDefineComponent ? macros.slots ? " = (" : ": () => JSX.Element = " : " = ");
|
|
180
|
+
codes.replaceRange(node.expression.end, node.expression.end, isDefineComponent && macros.slots ? ")()" : "", `
|
|
181
|
+
return {} as {
|
|
182
|
+
props: {${props.join(", ")}},
|
|
183
|
+
context: ${root.parameters[1]?.type ? `${root.parameters[1].type.getText(ast)} & ` : ""}{
|
|
184
|
+
slots: ${macros.defineSlots ?? "{}"},
|
|
185
|
+
expose: (exposed: import('vue').ShallowUnwrapRef<${macros.defineExpose ?? "Record<string, any>"}>) => void,
|
|
186
|
+
attrs: Record<string, any>
|
|
187
|
+
},
|
|
188
|
+
render: ${isDefineComponent ? `ReturnType<` : ""}typeof __rndr${isDefineComponent ? ">" : ""}
|
|
189
|
+
}`);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/volar/index.ts
|
|
196
|
+
function getMacro(node, ts, options) {
|
|
197
|
+
if (!node) return;
|
|
198
|
+
if (ts.isVariableStatement(node)) return node.declarationList.forEachChild((decl) => getExpression(decl));
|
|
199
|
+
else return getExpression(node);
|
|
200
|
+
function getExpression(decl) {
|
|
201
|
+
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
202
|
+
const initializer = ts.isCallExpression(decl.initializer) && ts.isIdentifier(decl.initializer.expression) && decl.initializer.expression.escapedText === "$" && decl.initializer.arguments[0] ? decl.initializer.arguments[0] : decl.initializer;
|
|
203
|
+
const expression = getMacroExpression(initializer);
|
|
204
|
+
if (expression) return {
|
|
205
|
+
expression,
|
|
206
|
+
variableDeclaration: decl,
|
|
207
|
+
initializer: decl.initializer,
|
|
208
|
+
isRequired: ts.isNonNullExpression(initializer)
|
|
209
|
+
};
|
|
210
|
+
} else if (ts.isExpressionStatement(decl)) {
|
|
211
|
+
const expression = getMacroExpression(decl.expression);
|
|
212
|
+
if (expression) return {
|
|
213
|
+
expression,
|
|
214
|
+
initializer: decl.expression,
|
|
215
|
+
isRequired: ts.isNonNullExpression(decl.expression)
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function getMacroExpression(node) {
|
|
220
|
+
if (ts.isNonNullExpression(node)) node = node.expression;
|
|
221
|
+
if (!ts.isCallExpression(node)) return;
|
|
222
|
+
const expression = ts.isPropertyAccessExpression(node.expression) ? node.expression : node;
|
|
223
|
+
return ts.isIdentifier(expression.expression) && [
|
|
224
|
+
...options.defineModel.alias,
|
|
225
|
+
...options.defineSlots.alias,
|
|
226
|
+
...options.defineStyle.alias,
|
|
227
|
+
...options.defineExpose.alias,
|
|
228
|
+
...options.defineComponent.alias
|
|
229
|
+
].includes(expression.expression.escapedText) && node;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const getModifierPropName = (name) => {
|
|
233
|
+
return `${name === "modelValue" || name === "model-value" ? "model" : name}Modifiers${name === "model" ? "$" : ""}`;
|
|
234
|
+
};
|
|
235
|
+
function getRootMap(options) {
|
|
236
|
+
const { ts, ast, codes } = options;
|
|
237
|
+
const rootMap = /* @__PURE__ */ new Map();
|
|
238
|
+
function walk(node, parents, scopes) {
|
|
239
|
+
const root = parents[1] && (ts.isArrowFunction(parents[1]) || ts.isFunctionExpression(parents[1]) || ts.isFunctionDeclaration(parents[1])) ? parents[1] : void 0;
|
|
240
|
+
function getDefineComponentCaller(node) {
|
|
241
|
+
if (!node) return;
|
|
242
|
+
if (ts.isVariableDeclaration(node) && node.initializer) node = node.initializer;
|
|
243
|
+
if (ts.isCallExpression(node) && !node.typeArguments && options.defineComponent.alias.includes(node.expression.getText(ast))) return node;
|
|
244
|
+
}
|
|
245
|
+
if (root) {
|
|
246
|
+
const caller = getDefineComponentCaller(parents[2]);
|
|
247
|
+
if (caller) {
|
|
248
|
+
if (!rootMap.has(root)) rootMap.set(root, {});
|
|
249
|
+
if (!rootMap.get(root).defineComponent) {
|
|
250
|
+
rootMap.get(root).defineComponent = caller;
|
|
251
|
+
transformDefineComponent(caller, parents[3], options);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const macro = getMacro(node, ts, options);
|
|
256
|
+
if (macro) {
|
|
257
|
+
const { expression, initializer, variableDeclaration } = macro;
|
|
258
|
+
let isRequired = macro.isRequired;
|
|
259
|
+
if (!rootMap.has(root)) rootMap.set(root, {});
|
|
260
|
+
const macroName = expression.expression.getText(ast);
|
|
261
|
+
if (macroName.startsWith("defineStyle")) {
|
|
262
|
+
(rootMap.get(root).defineStyle ??= []).push({
|
|
263
|
+
expression,
|
|
264
|
+
isCssModules: ts.isVariableStatement(node)
|
|
265
|
+
});
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (root) {
|
|
269
|
+
if (options.defineModel.alias.includes(macroName)) {
|
|
270
|
+
const modelName = expression.arguments[0] && ts.isStringLiteralLike(expression.arguments[0]) ? expression.arguments[0].text : "modelValue";
|
|
271
|
+
const modelOptions = expression.arguments[0] && ts.isStringLiteralLike(expression.arguments[0]) ? expression.arguments[1] : expression.arguments[0];
|
|
272
|
+
if (modelOptions && ts.isObjectLiteralExpression(modelOptions)) {
|
|
273
|
+
let hasRequired = false;
|
|
274
|
+
for (const prop of modelOptions.properties) if (ts.isPropertyAssignment(prop) && prop.name.getText(ast) === "required") {
|
|
275
|
+
hasRequired = true;
|
|
276
|
+
isRequired = prop.initializer.kind === ts.SyntaxKind.TrueKeyword;
|
|
277
|
+
}
|
|
278
|
+
if (!hasRequired && isRequired) codes.replaceRange(modelOptions.end - 1, modelOptions.end - 1, `${!modelOptions.properties.hasTrailingComma && modelOptions.properties.length ? "," : ""} required: true`);
|
|
279
|
+
} else if (isRequired) codes.replaceRange(expression.arguments.end, expression.arguments.end, `${!expression.arguments.hasTrailingComma && expression.arguments.length ? "," : ""} { required: true }`);
|
|
280
|
+
const id = toValidAssetId(modelName, `_model`);
|
|
281
|
+
const typeString = `import('vue').UnwrapRef<typeof ${id}>`;
|
|
282
|
+
const defineModel = rootMap.get(root).defineModel ??= [];
|
|
283
|
+
defineModel.push(`${modelName.includes("-") ? `'${modelName}'` : modelName}${isRequired ? ":" : "?:"} ${typeString}`, `'onUpdate:${modelName}'?: ($event: ${typeString}) => any`);
|
|
284
|
+
if (expression.typeArguments?.[1]) defineModel.push(`${getModifierPropName(modelName)}?: Partial<Record<${getText(expression.typeArguments[1], ast, ts)}, boolean>>`);
|
|
285
|
+
codes.replaceRange(initializer.getStart(ast), initializer.getStart(ast), variableDeclaration ? `// @ts-ignore\n${id};\n` : "", `let ${id} = `);
|
|
286
|
+
} else if (options.defineSlots.alias.includes(macroName)) {
|
|
287
|
+
codes.replaceRange(expression.getStart(ast), expression.getStart(ast), variableDeclaration ? "// @ts-ignore\n__slots;\n" : "", `const __slots = `);
|
|
288
|
+
rootMap.get(root).defineSlots = `Partial<typeof __slots>`;
|
|
289
|
+
} else if (options.defineExpose.alias.includes(macroName)) {
|
|
290
|
+
codes.replaceRange(expression.getStart(ast), expression.getStart(ast), variableDeclaration ? "// @ts-ignore\n__exposed;\n" : "", `const __exposed = `);
|
|
291
|
+
rootMap.get(root).defineExpose = `typeof __exposed`;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
const slotNode = ts.isJsxElement(node) ? node.openingElement : ts.isJsxSelfClosingElement(node) ? node : null;
|
|
296
|
+
const scope = scopes[0];
|
|
297
|
+
if (scope && slotNode?.tagName.getText(ast) === "slot") {
|
|
298
|
+
if (!rootMap.has(scope)) rootMap.set(scope, {});
|
|
299
|
+
(rootMap.get(scope).slots ??= []).push(slotNode);
|
|
300
|
+
}
|
|
301
|
+
node.forEachChild((child) => {
|
|
302
|
+
parents.unshift(node);
|
|
303
|
+
const scopeNode = (ts.isArrowFunction(child) || ts.isFunctionExpression(child) || ts.isFunctionDeclaration(child)) && !ts.isReturnStatement(node);
|
|
304
|
+
if (scopeNode) scopes.unshift(child);
|
|
305
|
+
walk(child, parents, scopes);
|
|
306
|
+
parents.shift();
|
|
307
|
+
if (scopeNode) scopes.shift();
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
ast.forEachChild((node) => walk(node, [], []));
|
|
311
|
+
return rootMap;
|
|
312
|
+
}
|
|
313
|
+
function toValidAssetId(name, type) {
|
|
314
|
+
return `_${type}_${name.replaceAll(/\W/g, (searchValue, replaceValue) => {
|
|
315
|
+
return searchValue === "-" ? "_" : name.charCodeAt(replaceValue).toString();
|
|
316
|
+
})}`;
|
|
317
|
+
}
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region src/volar/jsx-element.ts
|
|
320
|
+
const isCompRex = /^[\W_]/;
|
|
321
|
+
var jsx_element_default = createPlugin(({ ts }) => {
|
|
322
|
+
return {
|
|
323
|
+
name: "@vue-jsx/jsx-element",
|
|
324
|
+
resolveVirtualCode({ ast, codes }) {
|
|
325
|
+
let transformed = false;
|
|
326
|
+
ast.forEachChild(function walk(node, parent = ast) {
|
|
327
|
+
if (!ts.isJsxElement(parent) && !ts.isJsxFragment(parent) && !ts.isJsxExpression(parent) && !(parent.parent ? isConditionalExpression(ts, parent) : false)) {
|
|
328
|
+
const openingElement = ts.isJsxElement(node) ? node.openingElement : ts.isJsxSelfClosingElement(node) ? node : null;
|
|
329
|
+
if (openingElement) {
|
|
330
|
+
const tagName = openingElement.tagName.getText(ast);
|
|
331
|
+
if (!tagName.includes("-") && tagName !== "slot") {
|
|
332
|
+
transformed = true;
|
|
333
|
+
codes.replaceRange(node.getStart(ast), node.getStart(ast) + 1, "(<");
|
|
334
|
+
codes.replaceRange(node.end, node.end, " as unknown as __InferJsxElement<", isCompRex.test(tagName) ? `typeof ${tagName}` : `'${tagName}'`, ">)");
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (!ts.isCallExpression(node) || node.expression.getText(ast) !== "defineSlots") node.forEachChild((child) => walk(child, node));
|
|
339
|
+
});
|
|
340
|
+
if (transformed) codes.push(`
|
|
341
|
+
type __InferJsxElement<T> = T extends keyof HTMLElementTagNameMap
|
|
342
|
+
? HTMLElementTagNameMap[T]
|
|
343
|
+
: T extends keyof SVGElementTagNameMap
|
|
344
|
+
? SVGElementTagNameMap[T]
|
|
345
|
+
: T extends (props: infer Props extends Record<string, any>, ctx: { slots: infer Slots extends Record<string, any>, expose: (exposed: infer Exposed extends Record<string, any>) => void, attrs: any, emit: any }) => infer TypeBlock
|
|
346
|
+
? TypeBlock extends import('vue').Block
|
|
347
|
+
? import('vue').VaporComponentInstance<Props, {}, Slots, Exposed, TypeBlock>
|
|
348
|
+
: TypeBlock
|
|
349
|
+
: T extends { new (...args: any[]): infer Instance }
|
|
350
|
+
? Instance extends { $: any }
|
|
351
|
+
? import('vue').VNode
|
|
352
|
+
: Instance
|
|
353
|
+
: JSX.Element
|
|
354
|
+
`);
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
});
|
|
358
|
+
function isConditionalExpression(ts, node) {
|
|
359
|
+
return !!(node && (ts.isBinaryExpression(node) || ts.isConditionalExpression(node)) && node.parent && (ts.isJsxExpression(node.parent) || isConditionalExpression(ts, node.parent)));
|
|
360
|
+
}
|
|
361
|
+
//#endregion
|
|
362
|
+
//#region src/volar.ts
|
|
363
|
+
const REGEX_VUE_SFC = /\.vue$/;
|
|
364
|
+
const plugin = createPlugin(({ ts }, userOptions = {}) => {
|
|
365
|
+
const resolvedOptions = resolveOptions(userOptions);
|
|
366
|
+
resolvedOptions.include.push(REGEX_VUE_SFC);
|
|
367
|
+
const filter = createFilter(resolvedOptions.include, resolvedOptions.exclude);
|
|
368
|
+
return {
|
|
369
|
+
name: "@vue-jsx/macros",
|
|
370
|
+
resolveVirtualCode(virtualCode) {
|
|
371
|
+
const { filePath, codes } = virtualCode;
|
|
372
|
+
if (!filter(filePath)) return;
|
|
373
|
+
const options = {
|
|
374
|
+
ts,
|
|
375
|
+
...virtualCode,
|
|
376
|
+
...resolvedOptions
|
|
377
|
+
};
|
|
378
|
+
const rootMap = getRootMap(options);
|
|
379
|
+
if (rootMap.size) transformJsxMacros(rootMap, options);
|
|
380
|
+
codes.push(getGlobalTypes(rootMap, options));
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
});
|
|
384
|
+
//#endregion
|
|
385
|
+
export { plugin as default, plugin as "module.exports", jsx_element_default as jsxElement };
|
package/dist/webpack.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vue-jsx/macros",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "3.3.0-beta.0",
|
|
5
|
+
"description": "Macros for Vue JSX",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://github.com/vuejs/vue-jsx-vapor#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/vuejs/vue-jsx-vapor.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/vuejs/vue-jsx-vapor/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"transform",
|
|
17
|
+
"vue-jsx",
|
|
18
|
+
"macros",
|
|
19
|
+
"volar",
|
|
20
|
+
"vapor"
|
|
21
|
+
],
|
|
22
|
+
"exports": {
|
|
23
|
+
".": "./dist/index.js",
|
|
24
|
+
"./astro": "./dist/astro.js",
|
|
25
|
+
"./rspack": "./dist/rspack.js",
|
|
26
|
+
"./rsbuild": "./dist/rsbuild.js",
|
|
27
|
+
"./vite": "./dist/vite.js",
|
|
28
|
+
"./webpack": "./dist/webpack.js",
|
|
29
|
+
"./rollup": "./dist/rollup.js",
|
|
30
|
+
"./esbuild": "./dist/esbuild.js",
|
|
31
|
+
"./nuxt": "./dist/nuxt.js",
|
|
32
|
+
"./bun": "./dist/bun.js",
|
|
33
|
+
"./api": "./dist/api.js",
|
|
34
|
+
"./raw": "./dist/raw.js",
|
|
35
|
+
"./volar": "./dist/volar.js",
|
|
36
|
+
"./*": "./*"
|
|
37
|
+
},
|
|
38
|
+
"main": "dist/index.js",
|
|
39
|
+
"types": "dist/index.d.ts",
|
|
40
|
+
"typesVersions": {
|
|
41
|
+
"*": {
|
|
42
|
+
"*": [
|
|
43
|
+
"./dist/*",
|
|
44
|
+
"./*"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
"dist"
|
|
50
|
+
],
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@nuxt/kit": "^3",
|
|
53
|
+
"@nuxt/schema": "^3",
|
|
54
|
+
"esbuild": "*",
|
|
55
|
+
"rollup": "^3",
|
|
56
|
+
"vite": ">=3",
|
|
57
|
+
"vue": ">=3",
|
|
58
|
+
"webpack": "^4 || ^5"
|
|
59
|
+
},
|
|
60
|
+
"peerDependenciesMeta": {
|
|
61
|
+
"@nuxt/kit": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"@nuxt/schema": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
67
|
+
"esbuild": {
|
|
68
|
+
"optional": true
|
|
69
|
+
},
|
|
70
|
+
"rollup": {
|
|
71
|
+
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"vite": {
|
|
74
|
+
"optional": true
|
|
75
|
+
},
|
|
76
|
+
"webpack": {
|
|
77
|
+
"optional": true
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"dependencies": {
|
|
81
|
+
"hash-sum": "^2.0.0",
|
|
82
|
+
"magic-string": "^0.30.21",
|
|
83
|
+
"ts-macro": "^0.3.7",
|
|
84
|
+
"unplugin": "^3.0.0",
|
|
85
|
+
"unplugin-utils": "^0.3.1"
|
|
86
|
+
},
|
|
87
|
+
"devDependencies": {
|
|
88
|
+
"@babel/parser": "^7.29.3",
|
|
89
|
+
"@babel/types": "^7.29.0",
|
|
90
|
+
"@nuxt/kit": "^3.21.4",
|
|
91
|
+
"@nuxt/schema": "^3.21.4",
|
|
92
|
+
"@types/hash-sum": "^1.0.2",
|
|
93
|
+
"ast-kit": "^2.2.0",
|
|
94
|
+
"vue": "3.6.0-rc.5"
|
|
95
|
+
},
|
|
96
|
+
"scripts": {
|
|
97
|
+
"build": "tsdown",
|
|
98
|
+
"dev": "DEV=true tsdown"
|
|
99
|
+
}
|
|
100
|
+
}
|