UNPKG

@vue-jsx-vapor/macros

Version:
1,053 lines (1,036 loc) 43.5 kB
//#region rolldown:runtime var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) { __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } } } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion require("@babel/parser"); let magic_string = require("magic-string"); magic_string = __toESM(magic_string); let hash_sum = require("hash-sum"); hash_sum = __toESM(hash_sum); //#region ../../node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; function normalizeWindowsPath(input = "") { if (!input) return input; return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); } const _EXTNAME_RE = /.(\.[^./]+|\.)$/; const extname = function(p) { if (p === "..") return ""; const match = _EXTNAME_RE.exec(normalizeWindowsPath(p)); return match && match[1] || ""; }; //#endregion //#region ../../node_modules/.pnpm/ast-kit@2.2.0/node_modules/ast-kit/dist/index.js /** * Checks if the given node is a function type. * * @param node - The node to check. * @returns True if the node is a function type, false otherwise. */ function isFunctionType(node) { return !!node && !node.type.startsWith("TS") && /Function(?:Expression|Declaration)$|Method$/.test(node.type); } /* v8 ignore next -- @preserve */ /** * Checks if the input `node` is a reference to a bound variable. * * Copied from https://github.com/babel/babel/blob/main/packages/babel-types/src/validators/isReferenced.ts * * To avoid runtime dependency on `@babel/types` (which includes process references) * This file should not change very often in babel but we may need to keep it * up-to-date from time to time. * * @param node - The node to check. * @param parent - The parent node of the input `node`. * @param grandparent - The grandparent node of the input `node`. * @returns True if the input `node` is a reference to a bound variable, false otherwise. */ function isReferenced(node, parent, grandparent) { switch (parent.type) { case "MemberExpression": case "OptionalMemberExpression": if (parent.property === node) return !!parent.computed; return parent.object === node; case "JSXMemberExpression": return parent.object === node; case "VariableDeclarator": return parent.init === node; case "ArrowFunctionExpression": return parent.body === node; case "PrivateName": return false; case "ClassMethod": case "ClassPrivateMethod": case "ObjectMethod": if (parent.key === node) return !!parent.computed; return false; case "ObjectProperty": if (parent.key === node) return !!parent.computed; return !grandparent || grandparent.type !== "ObjectPattern"; case "ClassProperty": case "ClassAccessorProperty": if (parent.key === node) return !!parent.computed; return true; case "ClassPrivateProperty": return parent.key !== node; case "ClassDeclaration": case "ClassExpression": return parent.superClass === node; case "AssignmentExpression": return parent.right === node; case "AssignmentPattern": return parent.right === node; case "LabeledStatement": return false; case "CatchClause": return false; case "RestElement": return false; case "BreakStatement": case "ContinueStatement": return false; case "FunctionDeclaration": case "FunctionExpression": return false; case "ExportNamespaceSpecifier": case "ExportDefaultSpecifier": return false; case "ExportSpecifier": if (grandparent?.source) return false; return parent.local === node; case "ImportDefaultSpecifier": case "ImportNamespaceSpecifier": case "ImportSpecifier": return false; case "ImportAttribute": return false; case "JSXAttribute": case "JSXNamespacedName": return false; case "ObjectPattern": case "ArrayPattern": return false; case "MetaProperty": return false; case "ObjectTypeProperty": return parent.key !== node; case "TSEnumMember": return parent.id !== node; case "TSPropertySignature": if (parent.key === node) return !!parent.computed; return true; } return true; } function isIdentifier(node) { return !!node && (node.type === "Identifier" || node.type === "JSXIdentifier"); } function isForStatement(stmt) { return stmt.type === "ForOfStatement" || stmt.type === "ForInStatement" || stmt.type === "ForStatement"; } function isReferencedIdentifier(id, parent, parentStack) { if (!parent) return true; if (id.name === "arguments") return false; if (isReferenced(id, parent, parentStack.at(-2))) return true; switch (parent.type) { case "AssignmentExpression": case "AssignmentPattern": return true; case "ObjectProperty": return parent.key !== id && isInDestructureAssignment(parent, parentStack); case "ArrayPattern": return isInDestructureAssignment(parent, parentStack); } return false; } function isInDestructureAssignment(parent, parentStack) { if (parent && (parent.type === "ObjectProperty" || parent.type === "ArrayPattern")) { let i = parentStack.length; while (i--) { const p = parentStack[i]; if (p.type === "AssignmentExpression") return true; else if (p.type !== "ObjectProperty" && !p.type.endsWith("Pattern")) break; } } return false; } /** * Extract identifiers of the given node. * @param node The node to extract. * @param identifiers The array to store the extracted identifiers. * @see https://github.com/vuejs/core/blob/1f6a1102aa09960f76a9af2872ef01e7da8538e3/packages/compiler-core/src/babelUtils.ts#L208 */ function extractIdentifiers(node, identifiers = []) { switch (node.type) { case "Identifier": case "JSXIdentifier": identifiers.push(node); break; case "MemberExpression": case "JSXMemberExpression": { let object = node; while (object.type === "MemberExpression") object = object.object; identifiers.push(object); break; } case "ObjectPattern": for (const prop of node.properties) if (prop.type === "RestElement") extractIdentifiers(prop.argument, identifiers); else extractIdentifiers(prop.value, identifiers); break; case "ArrayPattern": node.elements.forEach((element) => { element && extractIdentifiers(element, identifiers); }); break; case "RestElement": extractIdentifiers(node.argument, identifiers); break; case "AssignmentPattern": extractIdentifiers(node.left, identifiers); break; } return identifiers; } const REGEX_DTS = /\.d\.[cm]?ts(\?.*)?$/; /** * Returns the language (extension name) of a given filename. * @param filename - The name of the file. * @returns The language of the file. */ function getLang(filename) { if (isDts(filename)) return "dts"; return extname(filename).replace(/^\./, "").replace(/\?.*$/, ""); } /** * Checks if a filename represents a TypeScript declaration file (.d.ts). * @param filename - The name of the file to check. * @returns A boolean value indicating whether the filename is a TypeScript declaration file. */ function isDts(filename) { return REGEX_DTS.test(filename); } /** * @typedef { import('estree').Node} Node * @typedef {{ * skip: () => void; * remove: () => void; * replace: (node: Node) => void; * }} WalkerContext */ var WalkerBase = class { constructor() { /** @type {boolean} */ this.should_skip = false; /** @type {boolean} */ this.should_remove = false; /** @type {Node | null} */ this.replacement = null; /** @type {WalkerContext} */ this.context = { skip: () => this.should_skip = true, remove: () => this.should_remove = true, replace: (node) => this.replacement = node }; } /** * @template {Node} Parent * @param {Parent | null | undefined} parent * @param {keyof Parent | null | undefined} prop * @param {number | null | undefined} index * @param {Node} node */ replace(parent, prop, index, node) { if (parent && prop) if (index != null) /** @type {Array<Node>} */ parent[prop][index] = node; else /** @type {Node} */ parent[prop] = node; } /** * @template {Node} Parent * @param {Parent | null | undefined} parent * @param {keyof Parent | null | undefined} prop * @param {number | null | undefined} index */ remove(parent, prop, index) { if (parent && prop) if (index !== null && index !== void 0) /** @type {Array<Node>} */ parent[prop].splice(index, 1); else delete parent[prop]; } }; /** * @typedef { import('estree').Node} Node * @typedef { import('./walker.js').WalkerContext} WalkerContext * @typedef {( * this: WalkerContext, * node: Node, * parent: Node | null, * key: string | number | symbol | null | undefined, * index: number | null | undefined * ) => void} SyncHandler */ var SyncWalker = class extends WalkerBase { /** * * @param {SyncHandler} [enter] * @param {SyncHandler} [leave] */ constructor(enter, leave) { super(); /** @type {boolean} */ this.should_skip = false; /** @type {boolean} */ this.should_remove = false; /** @type {Node | null} */ this.replacement = null; /** @type {WalkerContext} */ this.context = { skip: () => this.should_skip = true, remove: () => this.should_remove = true, replace: (node) => this.replacement = node }; /** @type {SyncHandler | undefined} */ this.enter = enter; /** @type {SyncHandler | undefined} */ this.leave = leave; } /** * @template {Node} Parent * @param {Node} node * @param {Parent | null} parent * @param {keyof Parent} [prop] * @param {number | null} [index] * @returns {Node | null} */ visit(node, parent, prop, index) { if (node) { if (this.enter) { const _should_skip = this.should_skip; const _should_remove = this.should_remove; const _replacement = this.replacement; this.should_skip = false; this.should_remove = false; this.replacement = null; this.enter.call(this.context, node, parent, prop, index); if (this.replacement) { node = this.replacement; this.replace(parent, prop, index, node); } if (this.should_remove) this.remove(parent, prop, index); const skipped = this.should_skip; const removed = this.should_remove; this.should_skip = _should_skip; this.should_remove = _should_remove; this.replacement = _replacement; if (skipped) return node; if (removed) return null; } /** @type {keyof Node} */ let key; for (key in node) { /** @type {unknown} */ const value = node[key]; if (value && typeof value === "object") { if (Array.isArray(value)) { const nodes = value; for (let i = 0; i < nodes.length; i += 1) { const item = nodes[i]; if (isNode$1(item)) { if (!this.visit(item, node, key, i)) i--; } } } else if (isNode$1(value)) this.visit(value, node, key, null); } } if (this.leave) { const _replacement = this.replacement; const _should_remove = this.should_remove; this.replacement = null; this.should_remove = false; this.leave.call(this.context, node, parent, prop, index); if (this.replacement) { node = this.replacement; this.replace(parent, prop, index, node); } if (this.should_remove) this.remove(parent, prop, index); const removed = this.should_remove; this.replacement = _replacement; this.should_remove = _should_remove; if (removed) return null; } } return node; } }; /** * Ducktype a node. * * @param {unknown} value * @returns {value is Node} */ function isNode$1(value) { return value !== null && typeof value === "object" && "type" in value && typeof value.type === "string"; } /** * @typedef {import('estree').Node} Node * @typedef {import('./sync.js').SyncHandler} SyncHandler * @typedef {import('./async.js').AsyncHandler} AsyncHandler */ /** * @param {Node} ast * @param {{ * enter?: SyncHandler * leave?: SyncHandler * }} walker * @returns {Node | null} */ function walk(ast, { enter, leave }) { return new SyncWalker(enter, leave).visit(ast, null); } const TS_NODE_TYPES = [ "TSAsExpression", "TSTypeAssertion", "TSNonNullExpression", "TSInstantiationExpression", "TSSatisfiesExpression" ]; /** * Walks the AST and applies the provided handlers. * * @template T - The type of the AST node. * @param {T} node - The root node of the AST. * @param {WalkHandlers<T, void>} hooks - The handlers to be applied during the walk. * @returns {T | null} - The modified AST node or null if the node is removed. */ const walkAST = walk; /** * Modified from https://github.com/vuejs/core/blob/main/packages/compiler-core/src/babelUtils.ts * To support browser environments and JSX. * * https://github.com/vuejs/core/blob/main/LICENSE */ /** * Return value indicates whether the AST walked can be a constant */ function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) { const rootExp = root.type === "Program" ? root.body[0].type === "ExpressionStatement" && root.body[0].expression : root; walkAST(root, { enter(node, parent) { parent && parentStack.push(parent); if (parent && parent.type.startsWith("TS") && !TS_NODE_TYPES.includes(parent.type)) return this.skip(); if (isIdentifier(node)) { const isLocal = !!knownIds[node.name]; const isRefed = isReferencedIdentifier(node, parent, parentStack); if (includeAll || isRefed && !isLocal) onIdentifier(node, parent, parentStack, isRefed, isLocal); } else if (node.type === "ObjectProperty" && parent?.type === "ObjectPattern") node.inPattern = true; else if (isFunctionType(node)) /* v8 ignore if -- @preserve */ if (node.scopeIds) node.scopeIds.forEach((id) => markKnownIds(id, knownIds)); else walkFunctionParams(node, (id) => markScopeIdentifier(node, id, knownIds)); else if (node.type === "BlockStatement") /* v8 ignore if -- @preserve */ if (node.scopeIds) node.scopeIds.forEach((id) => markKnownIds(id, knownIds)); else walkBlockDeclarations(node, (id) => markScopeIdentifier(node, id, knownIds)); else if (node.type === "CatchClause" && node.param) for (const id of extractIdentifiers(node.param)) markScopeIdentifier(node, id, knownIds); else if (isForStatement(node)) walkForStatement(node, false, (id) => markScopeIdentifier(node, id, knownIds)); }, leave(node, parent) { parent && parentStack.pop(); if (node !== rootExp && node.scopeIds) for (const id of node.scopeIds) { knownIds[id]--; if (knownIds[id] === 0) delete knownIds[id]; } } }); } function walkFunctionParams(node, onIdent) { for (const p of node.params) for (const id of extractIdentifiers(p)) onIdent(id); } function walkBlockDeclarations(block, onIdent) { for (const stmt of block.body) if (stmt.type === "VariableDeclaration") { if (stmt.declare) continue; for (const decl of stmt.declarations) for (const id of extractIdentifiers(decl.id)) onIdent(id); } else if (stmt.type === "FunctionDeclaration" || stmt.type === "ClassDeclaration") { /* v8 ignore if -- @preserve */ if (stmt.declare || !stmt.id) continue; onIdent(stmt.id); } else if (isForStatement(stmt)) walkForStatement(stmt, true, onIdent); } function walkForStatement(stmt, isVar, onIdent) { const variable = stmt.type === "ForStatement" ? stmt.init : stmt.left; if (variable && variable.type === "VariableDeclaration" && (variable.kind === "var" ? isVar : !isVar)) for (const decl of variable.declarations) for (const id of extractIdentifiers(decl.id)) onIdent(id); } function markKnownIds(name, knownIds) { if (name in knownIds) knownIds[name]++; else knownIds[name] = 1; } function markScopeIdentifier(node, child, knownIds) { const { name } = child; /* v8 ignore if -- @preserve */ if (node.scopeIds && node.scopeIds.has(name)) return; markKnownIds(name, knownIds); (node.scopeIds || (node.scopeIds = /* @__PURE__ */ new Set())).add(name); } //#endregion //#region src/core/helper/use-model.ts?raw var use_model_default = "import { customRef, watchSyncEffect } from \"vue\";\nconst EMPTY_OBJ = {};\nexport function useModel(props, name, options = {}) {\n const res = customRef((track, trigger) => {\n let localValue = options && options.default;\n let prevSetValue = EMPTY_OBJ;\n watchSyncEffect(() => {\n let propValue = props[name];\n if (propValue === void 0) {\n propValue = options && options.default;\n }\n if (!Object.is(localValue, propValue)) {\n localValue = propValue;\n trigger();\n }\n });\n return {\n get() {\n track();\n return options.get ? options.get(localValue) : localValue;\n },\n set(value) {\n const emittedValue = options.set ? options.set(value) : value;\n if (Object.is(emittedValue, localValue) && (prevSetValue === EMPTY_OBJ || Object.is(value, prevSetValue)))\n return;\n localValue = emittedValue;\n trigger();\n for (const emit of [props[`onUpdate:${name}`]].flat()) {\n if (typeof emit === \"function\") emit(emittedValue);\n }\n prevSetValue = value;\n }\n };\n });\n res[Symbol.iterator] = () => {\n let i = 0;\n return {\n next() {\n if (i < 2) {\n return {\n value: i++ ? props[`${name}Modifiers`] || {} : res,\n done: false\n };\n } else {\n return { done: true };\n }\n }\n };\n };\n return res;\n}\n"; //#endregion //#region src/core/helper/with-defaults.ts?raw var with_defaults_default = "function resolveDefaultProps(paths) {\n const result = {};\n for (const path of Object.keys(paths)) {\n const segments = path.split(/[.?[\\]]/).filter(Boolean);\n let current = result;\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (i === segments.length - 1) {\n current[segment] = paths[path];\n } else {\n if (!current[segment]) {\n current[segment] = Number.isNaN(Number(segments[i + 1])) ? {} : [];\n }\n current = current[segment];\n }\n }\n }\n return result;\n}\nexport function createPropsDefaultProxy(props, defaults) {\n const defaultProps = resolveDefaultProps(defaults);\n const result = {};\n for (const key of /* @__PURE__ */ new Set([\n ...Object.keys(props),\n ...Object.keys(defaultProps)\n ])) {\n Object.defineProperty(result, key, {\n enumerable: true,\n get: () => props[key] === void 0 ? defaultProps[key] : props[key]\n });\n }\n return result;\n}\n"; //#endregion //#region src/core/helper/index.ts const helperPrefix = "/vue-jsx-vapor/macros"; const useModelHelperId = `${helperPrefix}/use-model`; const withDefaultsHelperId = `${helperPrefix}/with-defaults`; //#endregion //#region src/core/utils.ts function prependFunctionalNode(node, s, result) { const isBlockStatement = node.body.type === "BlockStatement"; const start = node.body.extra?.parenthesized ? node.body.extra.parenStart : node.body.start; s.appendRight(start + (isBlockStatement ? 1 : 0), `${result};${isBlockStatement ? "" : "return "}`); if (!isBlockStatement) { s.appendLeft(start, "{"); s.appendRight(node.end, "}"); } } function isFunctionalNode(node) { return !!(node && (node.type === "ArrowFunctionExpression" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression")); } function getParamsStart(node, code) { return node.params[0] ? node.params[0].start : node.start + (code.slice(node.start, node.body.start).match(/\(\s*\)/)?.index || 0) + 1; } function getDefaultValue(node) { if (node.type === "TSNonNullExpression") return getDefaultValue(node.expression); if (node.type === "TSAsExpression") return getDefaultValue(node.expression); return node; } let require$1; function getRequire() { if (require$1) return require$1; try { if (globalThis.process?.getBuiltinModule) { const module$1 = process.getBuiltinModule("node:module"); if (module$1?.createRequire) return require$1 = module$1.createRequire(require("url").pathToFileURL(__filename).href); } } catch {} } const importedMap = /* @__PURE__ */ new WeakMap(); const HELPER_PREFIX = "__"; function importHelperFn(s, imported, local = imported, from = "vue") { const cacheKey = `${from}@${imported}`; if (!importedMap.get(s)?.has(cacheKey)) { s.appendLeft(0, `\nimport ${imported === "default" ? HELPER_PREFIX + local : `{ ${imported} as ${HELPER_PREFIX + local} }`} from ${JSON.stringify(from)};`); if (importedMap.has(s)) importedMap.get(s).add(cacheKey); else importedMap.set(s, new Set([cacheKey])); } return `${HELPER_PREFIX}${local}`; } //#endregion //#region src/core/restructure.ts function restructure(s, node, options = {}) { let index = 0; const propList = []; for (const param of node.params) { const path = `${HELPER_PREFIX}props${index++ || ""}`; const props = getProps(s, options, param, path); if (props) { s.overwrite(param.start, param.end, path); propList.push(...props); } } if (propList.length) { const defaultValues = {}; const rests = []; for (const prop of propList) { if (prop.isRest) rests.push(prop); if (prop.defaultValue) { const paths = prop.path.split(/\.|\[/); if (!options.skipDefaultProps || paths.length !== 1) (defaultValues[paths[0]] ??= []).push(prop); } } for (const [index$1, rest] of rests.entries()) prependFunctionalNode(node, s, options.generateRestProps?.(rest.name, index$1, rests) ?? `\nconst ${rest.name} = ${importHelperFn(s, "createPropsRestProxy")}(${rest.path}, [${rest.value}])`); for (const [path, values] of Object.entries(defaultValues)) prependFunctionalNode(node, s, `\n${path} = ${importHelperFn(s, "createPropsDefaultProxy", void 0, options.withDefaultsFrom ?? withDefaultsHelperId)}(${path}, {${values.map((i) => `'${i.path.replace(path, "")}${i.value}': ${i.defaultValue}`).join(", ")}})`); walkIdentifiers(node.body, (id, parent) => { const prop = propList.find((i) => i.name === id.name); if (prop && !prop.isRest) s.overwrite(id.start, id.end, `${parent?.type === "ObjectProperty" && parent.shorthand ? `${id.name}: ` : ""}${prop.path}${prop.value}`); }, false); } return propList; } function getProps(s, options, node, path = "", props = []) { const properties = node.type === "ObjectPattern" ? node.properties : node.type === "ArrayPattern" ? node.elements : []; if (!properties.length) return; const propNames = []; properties.forEach((prop, index) => { if (prop?.type === "Identifier") { props.push({ name: prop.name, path, value: `[${index}]` }); propNames.push(`'${prop.name}'`); } else if (prop?.type === "AssignmentPattern" && prop.left.type === "Identifier") { const defaultValue = getDefaultValue(prop.right); props.push({ path, name: prop.left.name, value: `[${index}]`, defaultValue: s.slice(defaultValue.start, defaultValue.end) }); propNames.push(`'${prop.left.name}'`); } else if (prop?.type === "ObjectProperty" && prop.key.type === "Identifier") { if (prop.value.type === "AssignmentPattern") if (prop.value.left.type === "Identifier") { const defaultValue = getDefaultValue(prop.value.right); props.push({ path, name: prop.value.left.name, value: `.${prop.key.name}`, defaultValue: s.slice(defaultValue.start, defaultValue.end) }); } else getProps(s, options, prop.value.left, `${path}.${prop.key.name}`, props); else if (!getProps(s, options, prop.value, `${path}.${prop.key.name}`, props)) { const name = prop.value.type === "Identifier" ? prop.value.name : prop.key.name; props.push({ path, name, value: `.${prop.key.name}` }); } propNames.push(`'${prop.key.name}'`); } else if (prop?.type === "RestElement" && prop.argument.type === "Identifier" && !prop.argument.name.startsWith(`${HELPER_PREFIX}props`)) props.push({ path, name: prop.argument.name, value: propNames.join(", "), isRest: true }); else if (prop) getProps(s, options, prop, `${path}[${index}]`, props); }); return props.length ? props : void 0; } //#endregion //#region src/core/define-component/await.ts function transformAwait(root, s) { if (root.body.type !== "BlockStatement") return; let hasAwait = false; for (const node of root.body.body) if (node.type === "VariableDeclaration" && !node.declare || node.type.endsWith("Statement")) { const scope = [root.body.body]; walkAST(node, { enter(child, parent) { if (isFunctionType(child)) this.skip(); if (child.type === "BlockStatement") scope.push(child.body); if (child.type === "AwaitExpression") { hasAwait = true; processAwait(s, child, !!scope.at(-1)?.some((n, i) => { return (scope.length === 1 || i > 0) && n.type === "ExpressionStatement" && n.start === child.start; }), parent.type === "ExpressionStatement"); } }, leave(node$1) { if (node$1.type === "BlockStatement") scope.pop(); } }); } if (hasAwait) s.prependLeft(root.body.start + 1, `\nlet __temp, __restore\n`); } function processAwait(s, node, needSemi, isStatement) { const argumentStart = node.argument.extra && node.argument.extra.parenthesized ? node.argument.extra.parenStart : node.argument.start; const argumentStr = s.slice(argumentStart, node.argument.end); const containsNestedAwait = /\bawait\b/.test(argumentStr); s.overwrite(node.start, argumentStart, `${needSemi ? `;` : ``}(\n ([__temp,__restore] = ${importHelperFn(s, `withAsyncContext`)}(${containsNestedAwait ? `async ` : ``}() => `); s.appendLeft(node.end, `)),\n ${isStatement ? `` : `__temp = `}await __temp,\n __restore()${isStatement ? `` : `,\n __temp`}\n)`); } //#endregion //#region src/core/define-component/return.ts function transformReturn(root, s) { const node = root.body.type === "BlockStatement" ? root.body.body.find((node$1) => node$1.type === "ReturnStatement")?.argument : root.body; if (!node || isFunctionalNode(node)) return; s.appendRight(node.extra?.parenthesized ? node.extra.parenStart : node.start, "() => "); } //#endregion //#region src/core/define-component/index.ts function transformDefineComponent(root, propsName, macros, s, autoReturnFunction = false) { if (!macros.defineComponent) return; const defineComponentName = s.slice(macros.defineComponent.callee.start, macros.defineComponent.callee.end); if (defineComponentName && !["defineComponent", "defineVaporComponent"].includes(defineComponentName)) importHelperFn(s, "defineComponent", defineComponentName); let hasRestProp = false; const props = {}; if (root.params[0]) { if (root.params[0].type === "Identifier") { getWalkedIds(root, propsName).forEach((id) => props[id] = null); prependFunctionalNode(root, s, `const ${propsName} = ${importHelperFn(s, "useFullProps", void 0, "/vue-jsx-vapor/props")}()`); s.overwrite(root.params[0].start, root.params[0].end, root.params.length > 1 ? `${HELPER_PREFIX}props` : root.start === root.params[0].start ? "()" : ""); } else if (root.params[0].type === "ObjectPattern") { const restructuredProps = root.params[0]; for (const prop of restructuredProps.properties) { if (prop.type !== "ObjectProperty" || prop.key.type !== "Identifier") continue; const propName = prop.key.name; if (prop.value.type !== "AssignmentPattern") { props[propName] = null; continue; } const defaultValue = getDefaultValue(prop.value.right); let isRequired = false; walkAST(prop.value.right, { enter(node) { if (node.type === "TSNonNullExpression") { isRequired = true; this.skip(); } } }); const propOptions = []; if (isRequired) propOptions.push("required: true"); if (defaultValue) { const { value, type, skipFactory } = getTypeAndValue(s, defaultValue); if (type) propOptions.push(`type: ${type}`); if (value) propOptions.push(`default: ${value}`); if (skipFactory) propOptions.push("skipFactory: true"); } if (propOptions.length) props[propName] = `{ ${propOptions.join(", ")} }`; else props[propName] = null; } restructure(s, root, { skipDefaultProps: true, generateRestProps: (restPropsName, index, list) => { if (index === list.length - 1) { hasRestProp = true; return `const ${restPropsName} = ${importHelperFn(s, "useAttrs")}()`; } } }); } } transformDefineModel$1(s, macros.defineModel, props); const propsString = Object.entries(props).map(([key, value]) => `'${key}': ${value}`).join(", \n"); if (propsString) { const resolvedPropsString = `${hasRestProp ? "inheritAttrs: false, " : ""}props: {\n${propsString}\n}`; const compOptions = macros.defineComponent.arguments[1]; if (!compOptions) s.appendRight(root.end, `, { ${resolvedPropsString} }`); else if (compOptions.type === "ObjectExpression") { s.appendLeft(compOptions.start, `{ ${resolvedPropsString}, ...`); s.appendRight(compOptions.end, " }"); } } transformAwait(root, s); if (autoReturnFunction) transformReturn(root, s); } function getWalkedIds(root, propsName) { const walkedIds = /* @__PURE__ */ new Set(); walkIdentifiers(root.body, (id, parent) => { if (id.name === propsName && (parent?.type === "MemberExpression" || parent?.type === "JSXMemberExpression" || parent?.type === "OptionalMemberExpression")) { const prop = parent.property.type === "Identifier" || parent.property.type === "JSXIdentifier" ? parent.property.name : parent.property.type === "StringLiteral" ? parent.property.value : ""; if (prop) walkedIds.add(prop); } }); return walkedIds; } function transformDefineModel$1(s, defineModel, props) { for (const { expression, isRequired } of defineModel || []) { const modelOptions = expression.arguments[0]?.type === "ObjectExpression" ? expression.arguments[0] : expression.arguments[1]?.type === "ObjectExpression" ? expression.arguments[1] : void 0; const options = {}; if (isRequired) options.required = true; let defaultValueNode; for (const prop of modelOptions?.properties || []) if (prop.type === "ObjectProperty" && prop.key.type === "Identifier" && [ "validator", "type", "required", "default" ].includes(prop.key.name)) { if (prop.key.name === "default") defaultValueNode = prop.value; options[prop.key.name] = s.slice(prop.value.start, prop.value.end); } if (defaultValueNode && !options.type) { const { value, type, skipFactory } = getTypeAndValue(s, defaultValueNode); if (type) options.type = type; if (value) options.default = value; if (skipFactory) options.skipFactory = "true"; } const propName = expression.arguments[0]?.type === "StringLiteral" ? expression.arguments[0].value : "modelValue"; props[propName] = Object.keys(options).length ? `{ ${Object.entries(options).map(([key, value]) => `${key}: ${value}`).join(", ")} }` : null; props[`onUpdate:${propName}`] = null; props[`${propName === "modelValue" ? "model" : propName}Modifiers`] = null; } } function getTypeAndValue(s, node) { let value = ""; let type = ""; let skipFactory = false; switch (node.type) { case "StringLiteral": type = "String"; value = `'${node.value}'`; break; case "BooleanLiteral": type = "Boolean"; value = String(node.value); break; case "NumericLiteral": type = "Number"; value = String(node.value); break; case "ObjectExpression": type = "Object"; value = `() => (${s.slice(node.start, node.end)})`; break; case "ArrayExpression": type = "Array"; value = `() => (${s.slice(node.start, node.end)})`; break; default: if (isFunctionalNode(node)) { type = "Function"; value = s.slice(node.start, node.end); } else if (node.type === "Identifier") if (node.name === "undefined") value = "undefined"; else { skipFactory = true; value = s.slice(node.start, node.end); } else if (node.type === "NullLiteral") value = "null"; } return { value, type, skipFactory }; } //#endregion //#region src/core/define-expose.ts function transformDefineExpose(node, s) { s.overwrite(node.callee.start, node.callee.end, ";"); s.appendRight(node.arguments[0]?.start || node.end - 1, `${importHelperFn(s, "getCurrentInstance", void 0, "/vue-jsx-vapor/props")}().exposed = `); } //#endregion //#region src/core/define-model.ts function transformDefineModel(node, propsName, s) { s.overwrite(node.callee.start, node.callee.end, importHelperFn(s, "useModel", void 0, useModelHelperId)); s.appendRight(node.arguments[0]?.start || node.end - 1, `${propsName}, ${node.arguments[0]?.type === "StringLiteral" ? "" : `'modelValue',`}`); } //#endregion //#region src/core/define-slots.ts function transformDefineSlots(node, s) { s.overwrite(node.start, node.arguments[0]?.start && node.arguments[0].start - 1 || node.typeArguments?.end || node.callee.end, `Object.assign`); const slots = `${importHelperFn(s, "useSlots")}()`; s.appendLeft(node.end - 1, `${node.arguments[0] ? "," : "{}, "}${slots}`); } //#endregion //#region src/core/define-style.ts function transformDefineStyle(defineStyle, index, root, s, importMap, { defineSlots }) { const { expression, lang, isCssModules } = defineStyle; if (expression.arguments[0]?.type !== "TemplateLiteral") return; let css = s.slice(expression.arguments[0].start, expression.arguments[0].end).slice(1, -1); const scopeId = (0, hash_sum.default)(css); const vars = /* @__PURE__ */ new Map(); expression.arguments[0].expressions.forEach((exp) => { const cssVar = s.slice(exp.start, exp.end); const cssVarId = toCssVarId(cssVar, `--${scopeId}-`); s.overwrite(exp.start - 2, exp.end + 1, `var(${cssVarId})`); vars.set(cssVarId, cssVar); }); let returnExpression = root && getReturnStatement(root); if (isFunctionalNode(returnExpression)) returnExpression = getReturnStatement(returnExpression); if (vars.size && returnExpression) { const children = returnExpression.type === "JSXElement" ? [returnExpression] : returnExpression.type === "JSXFragment" ? returnExpression.children : []; const varString = Array.from(vars.entries()).map(([key, value]) => `'${key}': ${value}`).join(", "); for (const child of children) if (child.type === "JSXElement") s.appendRight(child.openingElement.name.end, ` {...{style:{${varString}}}}`); } let scoped = !!root; if (expression.arguments[1]?.type === "ObjectExpression") { for (const prop of expression.arguments[1].properties) if (prop.type === "ObjectProperty" && prop.key.type === "Identifier" && prop.key.name === "scoped" && prop.value.type === "BooleanLiteral") scoped = prop.value.value; } if (scoped && root) { const slotNames = defineSlots?.id ? defineSlots.id.type === "Identifier" ? defineSlots.id.name : defineSlots.id.type === "ObjectPattern" ? defineSlots.id.properties.map((prop) => { const value = prop.type === "RestElement" ? prop.argument : prop.value; return s.slice(value.start, value.end); }) : [] : []; walkAST(root, { enter(node) { if (node.type === "JSXElement" && s.slice(node.openingElement.name.start, node.openingElement.name.end) !== "template") { let subfix = ""; if (slotNames.length) { const tagName = node.openingElement.name.type === "JSXMemberExpression" ? node.openingElement.name.object : node.openingElement.name; const name = s.slice(tagName.start, tagName.end); subfix = slotNames.includes(name) ? "-s" : ""; } s.appendRight(node.openingElement.name.end, ` data-v-${scopeId}${subfix}=""`); } } }); } css = s.slice(expression.arguments[0].start, expression.arguments[0].end).slice(1, -1).replaceAll(/\/\/(.*)(?=\n)/g, "/*$1*/"); const importId = `${helperPrefix}/define-style/${index}?scopeId=${scopeId}&scoped=${scoped}&lang.${isCssModules ? "module." : ""}${lang}`; importMap.set(importId, css); s.appendLeft(0, isCssModules ? `import style${index} from "${importId}";` : `import "${importId}";`); s.overwrite(expression.start, expression.end, isCssModules ? `style${index}` : ""); } function getReturnStatement(root) { if (root.body.type === "BlockStatement") { const returnStatement = root.body.body.find((node) => node.type === "ReturnStatement"); if (returnStatement) return returnStatement.argument; } else return root.body; } function toCssVarId(name, prefix = "") { return prefix + name.replaceAll(/\W/g, (searchValue, replaceValue) => { return searchValue === "." ? "-" : name.charCodeAt(replaceValue).toString(); }); } //#endregion //#region src/core/index.ts let babelParse; async function getBabelParse() { if (babelParse) return babelParse; const require$2 = getRequire(); try { return babelParse = require$2 ? require$2("vue/compiler-sfc").babelParse : (await import("https://esm.sh/@vue/compiler-sfc")).babelParse; } catch {} } async function transformJsxMacros(code, id, importMap, options) { const s = new magic_string.default(code); const lang = getLang(id); if (lang === "dts") return; const ast = (await getBabelParse())(s.original, { sourceType: "module", plugins: lang === "tsx" ? ["typescript", "jsx"] : lang === "jsx" ? ["jsx"] : lang === "ts" ? ["typescript"] : [] }).program; const rootMap = getRootMap(ast, s, options); let defineStyleIndex = 0; for (const [root, macros] of rootMap) { macros.defineStyle?.forEach((defineStyle) => { transformDefineStyle(defineStyle, defineStyleIndex++, root, s, importMap, macros); }); if (root === void 0) continue; let propsName = `${HELPER_PREFIX}props`; if (root.params[0]) { if (root.params[0].type === "Identifier") propsName = root.params[0].name; else if (root.params[0].type === "ObjectPattern") { const lastProp = root.params[0].properties.at(-1); if (!macros.defineComponent && lastProp?.type === "RestElement" && lastProp.argument.type === "Identifier") propsName = lastProp.argument.name; else s.appendRight(root.params[0].extra?.trailingComma ? root.params[0].extra?.trailingComma + 1 : lastProp?.end || root.params[0].end - 1, `${!root.params[0].extra?.trailingComma && root.params[0].properties.length ? "," : ""} ...${HELPER_PREFIX}props`); } } else if (macros.defineModel?.length) s.appendRight(getParamsStart(root, s.original), propsName); if (macros.defineComponent) transformDefineComponent(root, propsName, macros, s, options.defineComponent?.autoReturnFunction); if (macros.defineModel?.length) macros.defineModel.forEach(({ expression }) => { transformDefineModel(expression, propsName, s); }); if (macros.defineSlots) transformDefineSlots(macros.defineSlots.expression, s); if (macros.defineExpose) transformDefineExpose(macros.defineExpose, s); } if (s.hasChanged()) return { code: s.toString(), get map() { return s.generateMap({ source: id, includeContent: true, hires: "boundary" }); } }; } function getRootMap(ast, s, options) { const parents = []; const rootMap = /* @__PURE__ */ new Map(); walkAST(ast, { enter(node, parent) { parents.unshift(parent); const root = isFunctionalNode(parents[1]) ? parents[1] : void 0; if (root && parents[2]?.type === "CallExpression" && options.defineComponent.alias.includes(s.slice(parents[2].callee.start, parents[2].callee.end))) { if (!rootMap.has(root)) rootMap.set(root, {}); if (!rootMap.get(root).defineComponent) rootMap.get(root).defineComponent = parents[2]; } const expression = node.type === "VariableDeclaration" ? node.declarations[0].init?.type === "CallExpression" && s.slice(node.declarations[0].init.callee.start, node.declarations[0].init.callee.end) === "$" ? node.declarations[0].init.arguments[0] : node.declarations[0].init : node.type === "ExpressionStatement" ? node.expression : void 0; if (!expression) return; const macroExpression = getMacroExpression(expression, options); if (!macroExpression) return; if (!rootMap.has(root)) rootMap.set(root, {}); const macro = macroExpression.callee.type === "MemberExpression" ? macroExpression.callee.object : macroExpression.callee; const macroName = s.slice(macro.start, macro.end); if (macroName) { if (options.defineModel.alias.includes(macroName)) (rootMap.get(root).defineModel ??= []).push({ expression: macroExpression, isRequired: expression.type === "TSNonNullExpression" }); else if (options.defineStyle.alias.includes(macroName)) { const lang = macroExpression.callee.type === "MemberExpression" && macroExpression.callee.property.type === "Identifier" ? macroExpression.callee.property.name : "css"; (rootMap.get(root).defineStyle ??= []).push({ expression: macroExpression, isCssModules: node.type === "VariableDeclaration", lang }); } else if (options.defineSlots.alias.includes(macroName)) rootMap.get(root).defineSlots = { expression: macroExpression, id: node.type === "VariableDeclaration" ? node.declarations[0].id : void 0 }; else if (options.defineExpose.alias.includes(macroName)) rootMap.get(root).defineExpose = macroExpression; } }, leave() { parents.shift(); } }); return rootMap; } function getMacroExpression(node, options) { if (node.type === "TSNonNullExpression") node = node.expression; if (node.type === "CallExpression") { if (node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && node.callee.object.name === "defineStyle") return node; else if (node.callee.type === "Identifier" && [ ...options.defineComponent.alias, ...options.defineSlots.alias, ...options.defineModel.alias, ...options.defineExpose.alias, ...options.defineStyle.alias ].includes(node.callee.name)) return node; } } //#endregion Object.defineProperty(exports, '__toESM', { enumerable: true, get: function () { return __toESM; } }); Object.defineProperty(exports, 'getMacroExpression', { enumerable: true, get: function () { return getMacroExpression; } }); Object.defineProperty(exports, 'getRequire', { enumerable: true, get: function () { return getRequire; } }); Object.defineProperty(exports, 'isFunctionalNode', { enumerable: true, get: function () { return isFunctionalNode; } }); Object.defineProperty(exports, 'restructure', { enumerable: true, get: function () { return restructure; } }); Object.defineProperty(exports, 'transformJsxMacros', { enumerable: true, get: function () { return transformJsxMacros; } }); Object.defineProperty(exports, 'useModelHelperId', { enumerable: true, get: function () { return useModelHelperId; } }); Object.defineProperty(exports, 'use_model_default', { enumerable: true, get: function () { return use_model_default; } }); Object.defineProperty(exports, 'withDefaultsHelperId', { enumerable: true, get: function () { return withDefaultsHelperId; } }); Object.defineProperty(exports, 'with_defaults_default', { enumerable: true, get: function () { return with_defaults_default; } });