index.mjs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. import * as t from "@babel/types";
  2. import _template from "@babel/template";
  3. import _syntaxJsx from "@babel/plugin-syntax-jsx";
  4. import { addDefault, addNamed, addNamespace, isModule } from "@babel/helper-module-imports";
  5. import ResolveType from "@vue/babel-plugin-resolve-type";
  6. import { declare } from "@babel/helper-plugin-utils";
  7. import { isHTMLTag, isSVGTag } from "@vue/shared";
  8. //#region src/slotFlags.ts
  9. var SlotFlags = /* @__PURE__ */ function(SlotFlags$1) {
  10. /**
  11. * Stable slots that only reference slot props or context state. The slot
  12. * can fully capture its own dependencies so when passed down the parent won't
  13. * need to force the child to update.
  14. */
  15. SlotFlags$1[SlotFlags$1["STABLE"] = 1] = "STABLE";
  16. /**
  17. * Slots that reference scope variables (v-for or an outer slot prop), or
  18. * has conditional structure (v-if, v-for). The parent will need to force
  19. * the child to update because the slot does not fully capture its dependencies.
  20. */
  21. SlotFlags$1[SlotFlags$1["DYNAMIC"] = 2] = "DYNAMIC";
  22. /**
  23. * `<slot/>` being forwarded into a child component. Whether the parent needs
  24. * to update the child is dependent on what kind of slots the parent itself
  25. * received. This has to be refined at runtime, when the child's vnode
  26. * is being created (in `normalizeChildren`)
  27. */
  28. SlotFlags$1[SlotFlags$1["FORWARDED"] = 3] = "FORWARDED";
  29. return SlotFlags$1;
  30. }(SlotFlags || {});
  31. var slotFlags_default = SlotFlags;
  32. //#endregion
  33. //#region src/utils.ts
  34. const FRAGMENT = "Fragment";
  35. const KEEP_ALIVE = "KeepAlive";
  36. /**
  37. * create Identifier
  38. * @param path NodePath
  39. * @param state
  40. * @param name string
  41. * @returns MemberExpression
  42. */
  43. const createIdentifier = (state, name) => state.get(name)();
  44. /**
  45. * Checks if string is describing a directive
  46. * @param src string
  47. */
  48. const isDirective = (src) => src.startsWith("v-") || src.startsWith("v") && src.length >= 2 && src[1] >= "A" && src[1] <= "Z";
  49. /**
  50. * Should transformed to slots
  51. * @param tag string
  52. * @returns boolean
  53. */
  54. const shouldTransformedToSlots = (tag) => !(tag.match(RegExp(`^_?${FRAGMENT}\\d*$`)) || tag === KEEP_ALIVE);
  55. /**
  56. * Check if a Node is a component
  57. *
  58. * @param t
  59. * @param path JSXOpeningElement
  60. * @returns boolean
  61. */
  62. const checkIsComponent = (path, state) => {
  63. var _state$opts$isCustomE, _state$opts;
  64. const namePath = path.get("name");
  65. if (namePath.isJSXMemberExpression()) return shouldTransformedToSlots(namePath.node.property.name);
  66. const tag = namePath.node.name;
  67. return !((_state$opts$isCustomE = (_state$opts = state.opts).isCustomElement) === null || _state$opts$isCustomE === void 0 ? void 0 : _state$opts$isCustomE.call(_state$opts, tag)) && shouldTransformedToSlots(tag) && !isHTMLTag(tag) && !isSVGTag(tag);
  68. };
  69. /**
  70. * Transform JSXMemberExpression to MemberExpression
  71. * @param path JSXMemberExpression
  72. * @returns MemberExpression
  73. */
  74. const transformJSXMemberExpression = (path) => {
  75. const objectPath = path.node.object;
  76. const propertyPath = path.node.property;
  77. const transformedObject = t.isJSXMemberExpression(objectPath) ? transformJSXMemberExpression(path.get("object")) : t.isJSXIdentifier(objectPath) ? t.identifier(objectPath.name) : t.nullLiteral();
  78. const transformedProperty = t.identifier(propertyPath.name);
  79. return t.memberExpression(transformedObject, transformedProperty);
  80. };
  81. /**
  82. * Get tag (first attribute for h) from JSXOpeningElement
  83. * @param path JSXElement
  84. * @param state State
  85. * @returns Identifier | StringLiteral | MemberExpression | CallExpression
  86. */
  87. const getTag = (path, state) => {
  88. const namePath = path.get("openingElement").get("name");
  89. if (namePath.isJSXIdentifier()) {
  90. const { name } = namePath.node;
  91. if (!isHTMLTag(name) && !isSVGTag(name)) {
  92. var _state$opts$isCustomE2, _state$opts2;
  93. return name === FRAGMENT ? createIdentifier(state, FRAGMENT) : path.scope.hasBinding(name) ? t.identifier(name) : ((_state$opts$isCustomE2 = (_state$opts2 = state.opts).isCustomElement) === null || _state$opts$isCustomE2 === void 0 ? void 0 : _state$opts$isCustomE2.call(_state$opts2, name)) ? t.stringLiteral(name) : t.callExpression(createIdentifier(state, "resolveComponent"), [t.stringLiteral(name)]);
  94. }
  95. return t.stringLiteral(name);
  96. }
  97. if (namePath.isJSXMemberExpression()) return transformJSXMemberExpression(namePath);
  98. throw new Error(`getTag: ${namePath.type} is not supported`);
  99. };
  100. const getJSXAttributeName = (path) => {
  101. const nameNode = path.node.name;
  102. if (t.isJSXIdentifier(nameNode)) return nameNode.name;
  103. return `${nameNode.namespace.name}:${nameNode.name.name}`;
  104. };
  105. /**
  106. * Transform JSXText to StringLiteral
  107. * @param path JSXText
  108. * @returns StringLiteral | null
  109. */
  110. const transformJSXText = (path) => {
  111. const str = transformText(path.node.value);
  112. return str !== "" ? t.stringLiteral(str) : null;
  113. };
  114. const transformText = (text) => {
  115. const lines = text.split(/\r\n|\n|\r/);
  116. let lastNonEmptyLine = 0;
  117. for (let i = 0; i < lines.length; i++) if (lines[i].match(/[^ \t]/)) lastNonEmptyLine = i;
  118. let str = "";
  119. for (let i = 0; i < lines.length; i++) {
  120. const line = lines[i];
  121. const isFirstLine = i === 0;
  122. const isLastLine = i === lines.length - 1;
  123. const isLastNonEmptyLine = i === lastNonEmptyLine;
  124. let trimmedLine = line.replace(/\t/g, " ");
  125. if (!isFirstLine) trimmedLine = trimmedLine.replace(/^[ ]+/, "");
  126. if (!isLastLine) trimmedLine = trimmedLine.replace(/[ ]+$/, "");
  127. if (trimmedLine) {
  128. if (!isLastNonEmptyLine) trimmedLine += " ";
  129. str += trimmedLine;
  130. }
  131. }
  132. return str;
  133. };
  134. /**
  135. * Transform JSXExpressionContainer to Expression
  136. * @param path JSXExpressionContainer
  137. * @returns Expression
  138. */
  139. const transformJSXExpressionContainer = (path) => path.get("expression").node;
  140. /**
  141. * Transform JSXSpreadChild
  142. * @param path JSXSpreadChild
  143. * @returns SpreadElement
  144. */
  145. const transformJSXSpreadChild = (path) => t.spreadElement(path.get("expression").node);
  146. const walksScope = (path, name, slotFlag) => {
  147. if (path.scope.hasBinding(name) && path.parentPath) {
  148. if (t.isJSXElement(path.parentPath.node)) path.parentPath.setData("slotFlag", slotFlag);
  149. walksScope(path.parentPath, name, slotFlag);
  150. }
  151. };
  152. const buildIIFE = (path, children) => {
  153. const { parentPath } = path;
  154. if (parentPath.isAssignmentExpression()) {
  155. const { left } = parentPath.node;
  156. if (t.isIdentifier(left)) return children.map((child) => {
  157. if (t.isIdentifier(child) && child.name === left.name) {
  158. const insertName = path.scope.generateUidIdentifier(child.name);
  159. parentPath.insertBefore(t.variableDeclaration("const", [t.variableDeclarator(insertName, t.callExpression(t.functionExpression(null, [], t.blockStatement([t.returnStatement(child)])), []))]));
  160. return insertName;
  161. }
  162. return child;
  163. });
  164. }
  165. return children;
  166. };
  167. const onRE = /^on[^a-z]/;
  168. const isOn = (key) => onRE.test(key);
  169. const mergeAsArray = (existing, incoming) => {
  170. if (t.isArrayExpression(existing.value)) existing.value.elements.push(incoming.value);
  171. else existing.value = t.arrayExpression([existing.value, incoming.value]);
  172. };
  173. const dedupeProperties = (properties = [], mergeProps) => {
  174. if (!mergeProps) return properties;
  175. const knownProps = /* @__PURE__ */ new Map();
  176. const deduped = [];
  177. properties.forEach((prop) => {
  178. if (t.isStringLiteral(prop.key)) {
  179. const { value: name } = prop.key;
  180. const existing = knownProps.get(name);
  181. if (existing) {
  182. if (name === "style" || name === "class" || name.startsWith("on")) mergeAsArray(existing, prop);
  183. } else {
  184. knownProps.set(name, prop);
  185. deduped.push(prop);
  186. }
  187. } else deduped.push(prop);
  188. });
  189. return deduped;
  190. };
  191. /**
  192. * Check if an attribute value is constant
  193. * @param node
  194. * @returns boolean
  195. */
  196. const isConstant = (node) => {
  197. if (t.isIdentifier(node)) return node.name === "undefined";
  198. if (t.isArrayExpression(node)) {
  199. const { elements } = node;
  200. return elements.every((element) => element && isConstant(element));
  201. }
  202. if (t.isObjectExpression(node)) return node.properties.every((property) => isConstant(property.value));
  203. if (t.isTemplateLiteral(node) ? !node.expressions.length : t.isLiteral(node)) return true;
  204. return false;
  205. };
  206. const transformJSXSpreadAttribute = (nodePath, path, mergeProps, args) => {
  207. const argument = path.get("argument");
  208. const properties = t.isObjectExpression(argument.node) ? argument.node.properties : void 0;
  209. if (!properties) {
  210. if (argument.isIdentifier()) walksScope(nodePath, argument.node.name, slotFlags_default.DYNAMIC);
  211. args.push(mergeProps ? argument.node : t.spreadElement(argument.node));
  212. } else if (mergeProps) args.push(t.objectExpression(properties));
  213. else args.push(...properties);
  214. };
  215. //#endregion
  216. //#region src/patchFlags.ts
  217. let PatchFlags = /* @__PURE__ */ function(PatchFlags$1) {
  218. PatchFlags$1[PatchFlags$1["TEXT"] = 1] = "TEXT";
  219. PatchFlags$1[PatchFlags$1["CLASS"] = 2] = "CLASS";
  220. PatchFlags$1[PatchFlags$1["STYLE"] = 4] = "STYLE";
  221. PatchFlags$1[PatchFlags$1["PROPS"] = 8] = "PROPS";
  222. PatchFlags$1[PatchFlags$1["FULL_PROPS"] = 16] = "FULL_PROPS";
  223. PatchFlags$1[PatchFlags$1["HYDRATE_EVENTS"] = 32] = "HYDRATE_EVENTS";
  224. PatchFlags$1[PatchFlags$1["STABLE_FRAGMENT"] = 64] = "STABLE_FRAGMENT";
  225. PatchFlags$1[PatchFlags$1["KEYED_FRAGMENT"] = 128] = "KEYED_FRAGMENT";
  226. PatchFlags$1[PatchFlags$1["UNKEYED_FRAGMENT"] = 256] = "UNKEYED_FRAGMENT";
  227. PatchFlags$1[PatchFlags$1["NEED_PATCH"] = 512] = "NEED_PATCH";
  228. PatchFlags$1[PatchFlags$1["DYNAMIC_SLOTS"] = 1024] = "DYNAMIC_SLOTS";
  229. PatchFlags$1[PatchFlags$1["HOISTED"] = -1] = "HOISTED";
  230. PatchFlags$1[PatchFlags$1["BAIL"] = -2] = "BAIL";
  231. return PatchFlags$1;
  232. }({});
  233. const PatchFlagNames = {
  234. [PatchFlags.TEXT]: "TEXT",
  235. [PatchFlags.CLASS]: "CLASS",
  236. [PatchFlags.STYLE]: "STYLE",
  237. [PatchFlags.PROPS]: "PROPS",
  238. [PatchFlags.FULL_PROPS]: "FULL_PROPS",
  239. [PatchFlags.HYDRATE_EVENTS]: "HYDRATE_EVENTS",
  240. [PatchFlags.STABLE_FRAGMENT]: "STABLE_FRAGMENT",
  241. [PatchFlags.KEYED_FRAGMENT]: "KEYED_FRAGMENT",
  242. [PatchFlags.UNKEYED_FRAGMENT]: "UNKEYED_FRAGMENT",
  243. [PatchFlags.DYNAMIC_SLOTS]: "DYNAMIC_SLOTS",
  244. [PatchFlags.NEED_PATCH]: "NEED_PATCH",
  245. [PatchFlags.HOISTED]: "HOISTED",
  246. [PatchFlags.BAIL]: "BAIL"
  247. };
  248. //#endregion
  249. //#region src/parseDirectives.ts
  250. /**
  251. * Get JSX element type
  252. *
  253. * @param path Path<JSXOpeningElement>
  254. */
  255. const getType = (path) => {
  256. const typePath = path.get("attributes").find((attribute) => {
  257. if (!attribute.isJSXAttribute()) return false;
  258. return attribute.get("name").isJSXIdentifier() && attribute.get("name").node.name === "type";
  259. });
  260. return typePath ? typePath.get("value").node : null;
  261. };
  262. const parseModifiers = (value) => t.isArrayExpression(value) ? value.elements.map((el) => t.isStringLiteral(el) ? el.value : "").filter(Boolean) : [];
  263. const parseDirectives = (params) => {
  264. var _modifiersSet$, _modifiersSet$2;
  265. const { path, value, state, tag, isComponent } = params;
  266. const args = [];
  267. const vals = [];
  268. const modifiersSet = [];
  269. let directiveName;
  270. let directiveArgument;
  271. let directiveModifiers;
  272. if ("namespace" in path.node.name) {
  273. [directiveName, directiveArgument] = params.name.split(":");
  274. directiveName = path.node.name.namespace.name;
  275. directiveArgument = path.node.name.name.name;
  276. directiveModifiers = directiveArgument.split("_").slice(1);
  277. } else {
  278. const underscoreModifiers = params.name.split("_");
  279. directiveName = underscoreModifiers.shift() || "";
  280. directiveModifiers = underscoreModifiers;
  281. }
  282. directiveName = directiveName.replace(/^v/, "").replace(/^-/, "").replace(/^\S/, (s) => s.toLowerCase());
  283. if (directiveArgument) args.push(t.stringLiteral(directiveArgument.split("_")[0]));
  284. const isVModels = directiveName === "models";
  285. const isVModel = directiveName === "model";
  286. if (isVModel && !path.get("value").isJSXExpressionContainer()) throw new Error("You have to use JSX Expression inside your v-model");
  287. if (isVModels && !isComponent) throw new Error("v-models can only use in custom components");
  288. const shouldResolve = ![
  289. "html",
  290. "text",
  291. "model",
  292. "slots",
  293. "models"
  294. ].includes(directiveName) || isVModel && !isComponent;
  295. let modifiers = directiveModifiers;
  296. if (t.isArrayExpression(value)) {
  297. const elementsList = isVModels ? value.elements : [value];
  298. elementsList.forEach((element) => {
  299. if (isVModels && !t.isArrayExpression(element)) throw new Error("You should pass a Two-dimensional Arrays to v-models");
  300. const { elements } = element;
  301. const [first, second, third] = elements;
  302. if (second && !t.isArrayExpression(second) && !t.isSpreadElement(second)) {
  303. args.push(second);
  304. modifiers = parseModifiers(third);
  305. } else if (t.isArrayExpression(second)) {
  306. if (!shouldResolve) args.push(t.nullLiteral());
  307. modifiers = parseModifiers(second);
  308. } else if (!shouldResolve) args.push(t.nullLiteral());
  309. modifiersSet.push(new Set(modifiers));
  310. vals.push(first);
  311. });
  312. } else if (isVModel && !shouldResolve) {
  313. args.push(t.nullLiteral());
  314. modifiersSet.push(new Set(directiveModifiers));
  315. } else modifiersSet.push(new Set(directiveModifiers));
  316. return {
  317. directiveName,
  318. modifiers: modifiersSet,
  319. values: vals.length ? vals : [value],
  320. args,
  321. directive: shouldResolve ? [
  322. resolveDirective(path, state, tag, directiveName),
  323. vals[0] || value,
  324. ((_modifiersSet$ = modifiersSet[0]) === null || _modifiersSet$ === void 0 ? void 0 : _modifiersSet$.size) ? args[0] || t.unaryExpression("void", t.numericLiteral(0), true) : args[0],
  325. !!((_modifiersSet$2 = modifiersSet[0]) === null || _modifiersSet$2 === void 0 ? void 0 : _modifiersSet$2.size) && t.objectExpression([...modifiersSet[0]].map((modifier) => t.objectProperty(t.identifier(modifier), t.booleanLiteral(true))))
  326. ].filter(Boolean) : void 0
  327. };
  328. };
  329. const resolveDirective = (path, state, tag, directiveName) => {
  330. if (directiveName === "show") return createIdentifier(state, "vShow");
  331. if (directiveName === "model") {
  332. let modelToUse;
  333. const type = getType(path.parentPath);
  334. switch (tag.value) {
  335. case "select":
  336. modelToUse = createIdentifier(state, "vModelSelect");
  337. break;
  338. case "textarea":
  339. modelToUse = createIdentifier(state, "vModelText");
  340. break;
  341. default: if (t.isStringLiteral(type) || !type) switch (type === null || type === void 0 ? void 0 : type.value) {
  342. case "checkbox":
  343. modelToUse = createIdentifier(state, "vModelCheckbox");
  344. break;
  345. case "radio":
  346. modelToUse = createIdentifier(state, "vModelRadio");
  347. break;
  348. default: modelToUse = createIdentifier(state, "vModelText");
  349. }
  350. else modelToUse = createIdentifier(state, "vModelDynamic");
  351. }
  352. return modelToUse;
  353. }
  354. const referenceName = "v" + directiveName[0].toUpperCase() + directiveName.slice(1);
  355. if (path.scope.references[referenceName]) return t.identifier(referenceName);
  356. return t.callExpression(createIdentifier(state, "resolveDirective"), [t.stringLiteral(directiveName)]);
  357. };
  358. var parseDirectives_default = parseDirectives;
  359. //#endregion
  360. //#region src/transform-vue-jsx.ts
  361. const xlinkRE = new RegExp("^xlink([A-Z])", "");
  362. const getJSXAttributeValue = (path, state) => {
  363. const valuePath = path.get("value");
  364. if (valuePath.isJSXElement()) return transformJSXElement(valuePath, state);
  365. if (valuePath.isStringLiteral()) return t.stringLiteral(transformText(valuePath.node.value));
  366. if (valuePath.isJSXExpressionContainer()) return transformJSXExpressionContainer(valuePath);
  367. return null;
  368. };
  369. const buildProps = (path, state) => {
  370. const tag = getTag(path, state);
  371. const isComponent = checkIsComponent(path.get("openingElement"), state);
  372. const props = path.get("openingElement").get("attributes");
  373. const directives = [];
  374. const dynamicPropNames = /* @__PURE__ */ new Set();
  375. let slots = null;
  376. let patchFlag = 0;
  377. if (props.length === 0) return {
  378. tag,
  379. isComponent,
  380. slots,
  381. props: t.nullLiteral(),
  382. directives,
  383. patchFlag,
  384. dynamicPropNames
  385. };
  386. let properties = [];
  387. let hasRef = false;
  388. let hasClassBinding = false;
  389. let hasStyleBinding = false;
  390. let hasHydrationEventBinding = false;
  391. let hasDynamicKeys = false;
  392. const mergeArgs = [];
  393. const { mergeProps = true } = state.opts;
  394. props.forEach((prop) => {
  395. if (prop.isJSXAttribute()) {
  396. let name = getJSXAttributeName(prop);
  397. const attributeValue = getJSXAttributeValue(prop, state);
  398. if (!isConstant(attributeValue) || name === "ref") {
  399. if (!isComponent && isOn(name) && name.toLowerCase() !== "onclick" && name !== "onUpdate:modelValue") hasHydrationEventBinding = true;
  400. if (name === "ref") hasRef = true;
  401. else if (name === "class" && !isComponent) hasClassBinding = true;
  402. else if (name === "style" && !isComponent) hasStyleBinding = true;
  403. else if (name !== "key" && !isDirective(name) && name !== "on") dynamicPropNames.add(name);
  404. }
  405. if (state.opts.transformOn && (name === "on" || name === "nativeOn")) {
  406. if (!state.get("transformOn")) state.set("transformOn", addDefault(path, "@vue/babel-helper-vue-transform-on", { nameHint: "_transformOn" }));
  407. mergeArgs.push(t.callExpression(state.get("transformOn"), [attributeValue || t.booleanLiteral(true)]));
  408. return;
  409. }
  410. if (isDirective(name)) {
  411. const { directive, modifiers, values, args, directiveName } = parseDirectives_default({
  412. tag,
  413. isComponent,
  414. name,
  415. path: prop,
  416. state,
  417. value: attributeValue
  418. });
  419. if (directiveName === "slots") {
  420. slots = attributeValue;
  421. return;
  422. }
  423. if (directive) directives.push(t.arrayExpression(directive));
  424. else if (directiveName === "html") {
  425. properties.push(t.objectProperty(t.stringLiteral("innerHTML"), values[0]));
  426. dynamicPropNames.add("innerHTML");
  427. } else if (directiveName === "text") {
  428. properties.push(t.objectProperty(t.stringLiteral("textContent"), values[0]));
  429. dynamicPropNames.add("textContent");
  430. }
  431. if (["models", "model"].includes(directiveName)) values.forEach((value, index) => {
  432. const propName = args[index];
  433. const isDynamic = propName && !t.isStringLiteral(propName) && !t.isNullLiteral(propName);
  434. if (!directive) {
  435. var _modifiers$index;
  436. properties.push(t.objectProperty(t.isNullLiteral(propName) ? t.stringLiteral("modelValue") : propName, value, isDynamic));
  437. if (!isDynamic) dynamicPropNames.add((propName === null || propName === void 0 ? void 0 : propName.value) || "modelValue");
  438. if ((_modifiers$index = modifiers[index]) === null || _modifiers$index === void 0 ? void 0 : _modifiers$index.size) properties.push(t.objectProperty(isDynamic ? t.binaryExpression("+", propName, t.stringLiteral("Modifiers")) : t.stringLiteral(`${(propName === null || propName === void 0 ? void 0 : propName.value) || "model"}Modifiers`), t.objectExpression([...modifiers[index]].map((modifier) => t.objectProperty(t.stringLiteral(modifier), t.booleanLiteral(true)))), isDynamic));
  439. }
  440. const updateName = isDynamic ? t.binaryExpression("+", t.stringLiteral("onUpdate:"), propName) : t.stringLiteral(`onUpdate:${(propName === null || propName === void 0 ? void 0 : propName.value) || "modelValue"}`);
  441. properties.push(t.objectProperty(updateName, t.arrowFunctionExpression([t.identifier("$event")], t.assignmentExpression("=", value, t.identifier("$event"))), isDynamic));
  442. if (!isDynamic) dynamicPropNames.add(updateName.value);
  443. else hasDynamicKeys = true;
  444. });
  445. } else {
  446. if (name.match(xlinkRE)) name = name.replace(xlinkRE, (_, firstCharacter) => `xlink:${firstCharacter.toLowerCase()}`);
  447. properties.push(t.objectProperty(t.stringLiteral(name), attributeValue || t.booleanLiteral(true)));
  448. }
  449. } else {
  450. if (properties.length && mergeProps) {
  451. mergeArgs.push(t.objectExpression(dedupeProperties(properties, mergeProps)));
  452. properties = [];
  453. }
  454. hasDynamicKeys = true;
  455. transformJSXSpreadAttribute(path, prop, mergeProps, mergeProps ? mergeArgs : properties);
  456. }
  457. });
  458. if (hasDynamicKeys) patchFlag |= PatchFlags.FULL_PROPS;
  459. else {
  460. if (hasClassBinding) patchFlag |= PatchFlags.CLASS;
  461. if (hasStyleBinding) patchFlag |= PatchFlags.STYLE;
  462. if (dynamicPropNames.size) patchFlag |= PatchFlags.PROPS;
  463. if (hasHydrationEventBinding) patchFlag |= PatchFlags.HYDRATE_EVENTS;
  464. }
  465. if ((patchFlag === 0 || patchFlag === PatchFlags.HYDRATE_EVENTS) && (hasRef || directives.length > 0)) patchFlag |= PatchFlags.NEED_PATCH;
  466. let propsExpression = t.nullLiteral();
  467. if (mergeArgs.length) {
  468. if (properties.length) mergeArgs.push(t.objectExpression(dedupeProperties(properties, mergeProps)));
  469. if (mergeArgs.length > 1) propsExpression = t.callExpression(createIdentifier(state, "mergeProps"), mergeArgs);
  470. else propsExpression = mergeArgs[0];
  471. } else if (properties.length) if (properties.length === 1 && t.isSpreadElement(properties[0])) propsExpression = properties[0].argument;
  472. else propsExpression = t.objectExpression(dedupeProperties(properties, mergeProps));
  473. return {
  474. tag,
  475. props: propsExpression,
  476. isComponent,
  477. slots,
  478. directives,
  479. patchFlag,
  480. dynamicPropNames
  481. };
  482. };
  483. /**
  484. * Get children from Array of JSX children
  485. * @param paths Array<JSXText | JSXExpressionContainer | JSXElement | JSXFragment>
  486. * @returns Array<Expression | SpreadElement>
  487. */
  488. const getChildren = (paths, state) => paths.map((path) => {
  489. if (path.isJSXText()) {
  490. const transformedText = transformJSXText(path);
  491. if (transformedText) return t.callExpression(createIdentifier(state, "createTextVNode"), [transformedText]);
  492. return transformedText;
  493. }
  494. if (path.isJSXExpressionContainer()) {
  495. const expression = transformJSXExpressionContainer(path);
  496. if (t.isIdentifier(expression)) {
  497. const { name } = expression;
  498. const { referencePaths = [] } = path.scope.getBinding(name) || {};
  499. referencePaths.forEach((referencePath) => {
  500. walksScope(referencePath, name, slotFlags_default.DYNAMIC);
  501. });
  502. }
  503. return expression;
  504. }
  505. if (path.isJSXSpreadChild()) return transformJSXSpreadChild(path);
  506. if (path.isCallExpression()) return path.node;
  507. if (path.isJSXElement()) return transformJSXElement(path, state);
  508. throw new Error(`getChildren: ${path.type} is not supported`);
  509. }).filter(((value) => value != null && !t.isJSXEmptyExpression(value)));
  510. const transformJSXElement = (path, state) => {
  511. var _path$getData;
  512. const children = getChildren(path.get("children"), state);
  513. const { tag, props, isComponent, directives, patchFlag, dynamicPropNames, slots } = buildProps(path, state);
  514. const { optimize = false } = state.opts;
  515. if (directives.length && directives.some((d) => {
  516. var _d$elements;
  517. return ((_d$elements = d.elements) === null || _d$elements === void 0 || (_d$elements = _d$elements[0]) === null || _d$elements === void 0 ? void 0 : _d$elements.type) === "CallExpression" && d.elements[0].callee.type === "Identifier" && d.elements[0].callee.name === "_resolveDirective";
  518. })) {
  519. var _currentPath$parentPa;
  520. let currentPath = path;
  521. while ((_currentPath$parentPa = currentPath.parentPath) === null || _currentPath$parentPa === void 0 ? void 0 : _currentPath$parentPa.isJSXElement()) {
  522. currentPath = currentPath.parentPath;
  523. currentPath.setData("slotFlag", 0);
  524. }
  525. }
  526. const slotFlag = (_path$getData = path.getData("slotFlag")) !== null && _path$getData !== void 0 ? _path$getData : slotFlags_default.STABLE;
  527. const optimizeSlots = optimize && slotFlag !== 0;
  528. let VNodeChild;
  529. if (children.length > 1 || slots) VNodeChild = isComponent ? children.length ? t.objectExpression([
  530. !!children.length && t.objectProperty(t.identifier("default"), t.arrowFunctionExpression([], t.arrayExpression(buildIIFE(path, children)))),
  531. ...slots ? t.isObjectExpression(slots) ? slots.properties : [t.spreadElement(slots)] : [],
  532. optimizeSlots && t.objectProperty(t.identifier("_"), t.numericLiteral(slotFlag))
  533. ].filter(Boolean)) : slots : t.arrayExpression(children);
  534. else if (children.length === 1) {
  535. const { enableObjectSlots = true } = state.opts;
  536. const child = children[0];
  537. const objectExpression = t.objectExpression([t.objectProperty(t.identifier("default"), t.arrowFunctionExpression([], t.arrayExpression(buildIIFE(path, [child])))), optimizeSlots && t.objectProperty(t.identifier("_"), t.numericLiteral(slotFlag))].filter(Boolean));
  538. if (t.isIdentifier(child) && isComponent) VNodeChild = enableObjectSlots ? t.conditionalExpression(t.callExpression(state.get("@vue/babel-plugin-jsx/runtimeIsSlot")(), [child]), child, objectExpression) : objectExpression;
  539. else if (t.isCallExpression(child) && child.loc && isComponent) if (enableObjectSlots) {
  540. const { scope } = path;
  541. const slotId = scope.generateUidIdentifier("slot");
  542. if (scope) scope.push({
  543. id: slotId,
  544. kind: "let"
  545. });
  546. const alternate = t.objectExpression([t.objectProperty(t.identifier("default"), t.arrowFunctionExpression([], t.arrayExpression(buildIIFE(path, [slotId])))), optimizeSlots && t.objectProperty(t.identifier("_"), t.numericLiteral(slotFlag))].filter(Boolean));
  547. const assignment = t.assignmentExpression("=", slotId, child);
  548. const condition = t.callExpression(state.get("@vue/babel-plugin-jsx/runtimeIsSlot")(), [assignment]);
  549. VNodeChild = t.conditionalExpression(condition, slotId, alternate);
  550. } else VNodeChild = objectExpression;
  551. else if (t.isFunctionExpression(child) || t.isArrowFunctionExpression(child)) VNodeChild = t.objectExpression([t.objectProperty(t.identifier("default"), child)]);
  552. else if (t.isObjectExpression(child)) VNodeChild = t.objectExpression([...child.properties, optimizeSlots && t.objectProperty(t.identifier("_"), t.numericLiteral(slotFlag))].filter(Boolean));
  553. else VNodeChild = isComponent ? t.objectExpression([t.objectProperty(t.identifier("default"), t.arrowFunctionExpression([], t.arrayExpression([child])))]) : t.arrayExpression([child]);
  554. }
  555. const createVNode = t.callExpression(createIdentifier(state, "createVNode"), [
  556. tag,
  557. props,
  558. VNodeChild || t.nullLiteral(),
  559. !!patchFlag && optimize && t.numericLiteral(patchFlag),
  560. !!dynamicPropNames.size && optimize && t.arrayExpression([...dynamicPropNames.keys()].map((name) => t.stringLiteral(name)))
  561. ].filter(Boolean));
  562. if (!directives.length) return createVNode;
  563. return t.callExpression(createIdentifier(state, "withDirectives"), [createVNode, t.arrayExpression(directives)]);
  564. };
  565. const visitor$1 = { JSXElement: { exit(path, state) {
  566. path.replaceWith(transformJSXElement(path, state));
  567. } } };
  568. var transform_vue_jsx_default = visitor$1;
  569. //#endregion
  570. //#region src/sugar-fragment.ts
  571. const transformFragment = (path, Fragment) => {
  572. const children = path.get("children") || [];
  573. return t.jsxElement(t.jsxOpeningElement(Fragment, []), t.jsxClosingElement(Fragment), children.map(({ node }) => node), false);
  574. };
  575. const visitor = { JSXFragment: { enter(path, state) {
  576. const fragmentCallee = createIdentifier(state, FRAGMENT);
  577. path.replaceWith(transformFragment(path, t.isIdentifier(fragmentCallee) ? t.jsxIdentifier(fragmentCallee.name) : t.jsxMemberExpression(t.jsxIdentifier(fragmentCallee.object.name), t.jsxIdentifier(fragmentCallee.property.name))));
  578. } } };
  579. var sugar_fragment_default = visitor;
  580. //#endregion
  581. //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/typeof.js
  582. function _typeof(o) {
  583. "@babel/helpers - typeof";
  584. return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
  585. return typeof o$1;
  586. } : function(o$1) {
  587. return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
  588. }, _typeof(o);
  589. }
  590. //#endregion
  591. //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/toPrimitive.js
  592. function toPrimitive(t$1, r) {
  593. if ("object" != _typeof(t$1) || !t$1) return t$1;
  594. var e = t$1[Symbol.toPrimitive];
  595. if (void 0 !== e) {
  596. var i = e.call(t$1, r || "default");
  597. if ("object" != _typeof(i)) return i;
  598. throw new TypeError("@@toPrimitive must return a primitive value.");
  599. }
  600. return ("string" === r ? String : Number)(t$1);
  601. }
  602. //#endregion
  603. //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/toPropertyKey.js
  604. function toPropertyKey(t$1) {
  605. var i = toPrimitive(t$1, "string");
  606. return "symbol" == _typeof(i) ? i : i + "";
  607. }
  608. //#endregion
  609. //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/defineProperty.js
  610. function _defineProperty(e, r, t$1) {
  611. return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
  612. value: t$1,
  613. enumerable: !0,
  614. configurable: !0,
  615. writable: !0
  616. }) : e[r] = t$1, e;
  617. }
  618. //#endregion
  619. //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/objectSpread2.js
  620. function ownKeys(e, r) {
  621. var t$1 = Object.keys(e);
  622. if (Object.getOwnPropertySymbols) {
  623. var o = Object.getOwnPropertySymbols(e);
  624. r && (o = o.filter(function(r$1) {
  625. return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
  626. })), t$1.push.apply(t$1, o);
  627. }
  628. return t$1;
  629. }
  630. function _objectSpread2(e) {
  631. for (var r = 1; r < arguments.length; r++) {
  632. var t$1 = null != arguments[r] ? arguments[r] : {};
  633. r % 2 ? ownKeys(Object(t$1), !0).forEach(function(r$1) {
  634. _defineProperty(e, r$1, t$1[r$1]);
  635. }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t$1)) : ownKeys(Object(t$1)).forEach(function(r$1) {
  636. Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t$1, r$1));
  637. });
  638. }
  639. return e;
  640. }
  641. //#endregion
  642. //#region src/index.ts
  643. const hasJSX = (parentPath) => {
  644. let fileHasJSX = false;
  645. parentPath.traverse({
  646. JSXElement(path) {
  647. fileHasJSX = true;
  648. path.stop();
  649. },
  650. JSXFragment(path) {
  651. fileHasJSX = true;
  652. path.stop();
  653. }
  654. });
  655. return fileHasJSX;
  656. };
  657. const JSX_ANNOTATION_REGEX = new RegExp("\\*?\\s*@jsx\\s+([^\\s]+)", "");
  658. /* @__NO_SIDE_EFFECTS__ */
  659. function interopDefault(m) {
  660. return m.default || m;
  661. }
  662. const syntaxJsx = /* @__PURE__ */ interopDefault(_syntaxJsx);
  663. const template = /* @__PURE__ */ interopDefault(_template);
  664. const plugin = declare((api, opt, dirname) => {
  665. const { types } = api;
  666. let resolveType;
  667. if (opt.resolveType) {
  668. if (typeof opt.resolveType === "boolean") opt.resolveType = {};
  669. resolveType = ResolveType(api, opt.resolveType, dirname);
  670. }
  671. return _objectSpread2(_objectSpread2({}, resolveType || {}), {}, {
  672. name: "babel-plugin-jsx",
  673. inherits: /* @__PURE__ */ interopDefault(syntaxJsx),
  674. visitor: _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, resolveType === null || resolveType === void 0 ? void 0 : resolveType.visitor), transform_vue_jsx_default), sugar_fragment_default), {}, { Program: { enter(path, state) {
  675. if (hasJSX(path)) {
  676. const importNames = [
  677. "createVNode",
  678. "Fragment",
  679. "resolveComponent",
  680. "withDirectives",
  681. "vShow",
  682. "vModelSelect",
  683. "vModelText",
  684. "vModelCheckbox",
  685. "vModelRadio",
  686. "vModelText",
  687. "vModelDynamic",
  688. "resolveDirective",
  689. "mergeProps",
  690. "createTextVNode",
  691. "isVNode"
  692. ];
  693. if (isModule(path)) {
  694. const importMap = {};
  695. importNames.forEach((name) => {
  696. state.set(name, () => {
  697. if (importMap[name]) return types.cloneNode(importMap[name]);
  698. const identifier = addNamed(path, name, "vue", { ensureLiveReference: true });
  699. importMap[name] = identifier;
  700. return identifier;
  701. });
  702. });
  703. const { enableObjectSlots = true } = state.opts;
  704. if (enableObjectSlots) state.set("@vue/babel-plugin-jsx/runtimeIsSlot", () => {
  705. if (importMap.runtimeIsSlot) return importMap.runtimeIsSlot;
  706. const { name: isVNodeName } = state.get("isVNode")();
  707. const isSlot = path.scope.generateUidIdentifier("isSlot");
  708. const ast = template.ast`
  709. function ${isSlot.name}(s) {
  710. return typeof s === 'function' || (Object.prototype.toString.call(s) === '[object Object]' && !${isVNodeName}(s));
  711. }
  712. `;
  713. const lastImport = path.get("body").filter((p) => p.isImportDeclaration()).pop();
  714. if (lastImport) lastImport.insertAfter(ast);
  715. importMap.runtimeIsSlot = isSlot;
  716. return isSlot;
  717. });
  718. } else {
  719. let sourceName;
  720. importNames.forEach((name) => {
  721. state.set(name, () => {
  722. if (!sourceName) sourceName = addNamespace(path, "vue", { ensureLiveReference: true });
  723. return t.memberExpression(sourceName, t.identifier(name));
  724. });
  725. });
  726. const helpers = {};
  727. const { enableObjectSlots = true } = state.opts;
  728. if (enableObjectSlots) state.set("@vue/babel-plugin-jsx/runtimeIsSlot", () => {
  729. if (helpers.runtimeIsSlot) return helpers.runtimeIsSlot;
  730. const isSlot = path.scope.generateUidIdentifier("isSlot");
  731. const { object: objectName } = state.get("isVNode")();
  732. const ast = template.ast`
  733. function ${isSlot.name}(s) {
  734. return typeof s === 'function' || (Object.prototype.toString.call(s) === '[object Object]' && !${objectName.name}.isVNode(s));
  735. }
  736. `;
  737. const nodePaths = path.get("body");
  738. const lastImport = nodePaths.filter((p) => p.isVariableDeclaration() && p.node.declarations.some((d) => {
  739. var _d$id;
  740. return ((_d$id = d.id) === null || _d$id === void 0 ? void 0 : _d$id.name) === sourceName.name;
  741. })).pop();
  742. if (lastImport) lastImport.insertAfter(ast);
  743. return isSlot;
  744. });
  745. }
  746. const { opts: { pragma = "" }, file } = state;
  747. if (pragma) state.set("createVNode", () => t.identifier(pragma));
  748. if (file.ast.comments) for (const comment of file.ast.comments) {
  749. const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
  750. if (jsxMatches) state.set("createVNode", () => t.identifier(jsxMatches[1]));
  751. }
  752. }
  753. } } })
  754. });
  755. });
  756. var src_default = plugin;
  757. //#endregion
  758. export { src_default as default };