index.mjs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import { createRequire } from 'node:module';
  2. import path from 'upath';
  3. import { capitalize, camelize } from 'vue';
  4. function parseTemplate(source) {
  5. const components = createSet(source.matchAll(/(?:var|const) (\w+) = _resolveComponent\("([\w-.]+)"\);?/gm));
  6. const directives = createSet(source.matchAll(/(?:var|const) (\w+) = _resolveDirective\("([\w-.]+)"\);?/gm));
  7. return { components, directives };
  8. }
  9. function createSet(matches) {
  10. return new Set(Array.from(matches, (i) => ({
  11. symbol: i[1],
  12. name: capitalize(camelize(i[2])),
  13. index: i.index,
  14. length: i[0].length
  15. })));
  16. }
  17. const require$1 = createRequire(import.meta.url);
  18. const importMap = require$1("vuetify/dist/json/importMap.json");
  19. const importMapLabs = require$1("vuetify/dist/json/importMap-labs.json");
  20. function getImports(source, options) {
  21. const { components, directives } = parseTemplate(source);
  22. const resolvedComponents = [];
  23. const resolvedDirectives = [];
  24. const imports = /* @__PURE__ */ new Map();
  25. const ignore = isObject(options.autoImport) && options.autoImport.ignore || null;
  26. const includeLabs = isObject(options.autoImport) && options.autoImport.labs;
  27. const map = includeLabs ? {
  28. components: { ...importMap.components, ...importMapLabs.components },
  29. directives: importMap.directives
  30. } : importMap;
  31. if (components.size || directives.size) {
  32. components.forEach((component) => {
  33. if (ignore?.includes(component.name))
  34. return;
  35. if (component.name in importMap.components) {
  36. resolvedComponents.push(component);
  37. } else if (includeLabs && component.name in importMapLabs.components) {
  38. resolvedComponents.push(component);
  39. }
  40. });
  41. directives.forEach((directive) => {
  42. if (importMap.directives.includes(directive.name) && !ignore?.includes(directive.name)) {
  43. resolvedDirectives.push(directive);
  44. }
  45. });
  46. }
  47. resolvedComponents.forEach((component) => {
  48. addImport(imports, component.name, component.symbol, "vuetify/lib/" + map.components[component.name].from);
  49. });
  50. resolvedDirectives.forEach((directive) => {
  51. addImport(imports, directive.name, directive.symbol, "vuetify/lib/directives/index.mjs");
  52. });
  53. return {
  54. imports,
  55. components: resolvedComponents,
  56. directives: resolvedDirectives
  57. };
  58. }
  59. function addImport(imports, name, as, from) {
  60. if (!imports.has(from)) {
  61. imports.set(from, []);
  62. }
  63. imports.get(from).push(`${name} as ${as}`);
  64. }
  65. function generateImports(source, options) {
  66. const { imports, components, directives } = getImports(source, options);
  67. let code = "";
  68. if (components.length || directives.length) {
  69. code += "\n\n/* Vuetify */\n";
  70. Array.from(imports).sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0).forEach(([from, names]) => {
  71. code += `import { ${names.join(", ")} } from "${from}"
  72. `;
  73. });
  74. code += "\n";
  75. source = [...components, ...directives].reduce((acc, v) => {
  76. return acc.slice(0, v.index) + " ".repeat(v.length) + acc.slice(v.index + v.length);
  77. }, source);
  78. if (!source.includes("_resolveComponent(")) {
  79. source = source.replace("resolveComponent as _resolveComponent, ", "");
  80. }
  81. if (!source.includes("_resolveDirective(")) {
  82. source = source.replace("resolveDirective as _resolveDirective, ", "");
  83. }
  84. }
  85. return { code, source };
  86. }
  87. const require = createRequire(import.meta.url);
  88. function resolveVuetifyBase() {
  89. return path.dirname(require.resolve("vuetify/package.json", { paths: [process.cwd()] }));
  90. }
  91. function isObject(value) {
  92. return value !== null && typeof value === "object";
  93. }
  94. function includes(arr, val) {
  95. return arr.includes(val);
  96. }
  97. function normalizePath(p) {
  98. p = path.normalize(p);
  99. return /^[a-z]:\//i.test(p) ? "/" + p : p;
  100. }
  101. function toKebabCase(str = "") {
  102. return str.replace(/[^a-z]/gi, "-").replace(/\B([A-Z])/g, "-$1").toLowerCase();
  103. }
  104. const defaultTags = {
  105. video: ["src", "poster"],
  106. source: ["src"],
  107. img: ["src"],
  108. image: ["xlink:href", "href"],
  109. use: ["xlink:href", "href"]
  110. };
  111. const transformAssetUrls = {
  112. VAppBar: ["image"],
  113. VAvatar: ["image"],
  114. VBanner: ["avatar"],
  115. VCard: ["image", "prependAvatar", "appendAvatar"],
  116. VCardItem: ["prependAvatar", "appendAvatar"],
  117. VCarouselItem: ["src", "lazySrc", "srcset"],
  118. VChip: ["prependAvatar", "appendAvatar"],
  119. VImg: ["src", "lazySrc", "srcset"],
  120. VListItem: ["prependAvatar", "appendAvatar"],
  121. VNavigationDrawer: ["image"],
  122. VParallax: ["src", "lazySrc", "srcset"],
  123. VToolbar: ["image"]
  124. };
  125. for (const [tag, attrs] of Object.entries(transformAssetUrls)) {
  126. attrs.forEach((attr) => {
  127. if (/[A-Z]/.test(attr)) {
  128. attrs.push(toKebabCase(attr));
  129. }
  130. });
  131. transformAssetUrls[toKebabCase(tag)] = attrs;
  132. }
  133. Object.assign(transformAssetUrls, defaultTags);
  134. export { generateImports, includes, isObject, normalizePath, resolveVuetifyBase, toKebabCase, transformAssetUrls };