| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 |
- 'use strict';
- const node_path = require('node:path');
- const process = require('node:process');
- const pathe = require('pathe');
- const scule = require('scule');
- const MagicString = require('magic-string');
- const mlly = require('mlly');
- const stripLiteral = require('strip-literal');
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
- const process__default = /*#__PURE__*/_interopDefaultCompat(process);
- const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
- const excludeRE = [
- // imported/exported from other module
- /\b(import|export)\b([\w$*{},\s]+?)\bfrom\s*["']/g,
- // defined as function
- /\bfunction\s*([\w$]+)\s*\(/g,
- // defined as class
- /\bclass\s*([\w$]+)\s*\{/g,
- // defined as local variable
- // eslint-disable-next-line regexp/no-super-linear-backtracking
- /\b(?:const|let|var)\s+?(\[.*?\]|\{.*?\}|.+?)\s*?[=;\n]/gs
- ];
- const importAsRE = /^.*\sas\s+/;
- const separatorRE = /[,[\]{}\n]|\b(?:import|export)\b/g;
- const matchRE = /(^|\.\.\.|(?:\bcase|\?)\s+|[^\w$/)]|\bextends\s+)([\w$]+)\s*(?=[.()[\]}:;?+\-*&|`<>,\n]|\b(?:instanceof|in)\b|$|(?<=extends\s+\w+)\s+\{)/g;
- const regexRE = /\/\S*?(?<!\\)(?<!\[[^\]]*)\/[gimsuy]*/g;
- function stripCommentsAndStrings(code, options) {
- return stripLiteral.stripLiteral(code, options).replace(regexRE, 'new RegExp("")');
- }
- function defineUnimportPreset(preset) {
- return preset;
- }
- const safePropertyName = /^[a-z$_][\w$]*$/i;
- function stringifyWith(withValues) {
- let withDefs = "";
- for (let entries = Object.entries(withValues), l = entries.length, i = 0; i < l; i++) {
- const [prop, value] = entries[i];
- withDefs += safePropertyName.test(prop) ? prop : JSON.stringify(prop);
- withDefs += `: ${JSON.stringify(String(value))}`;
- if (i + 1 !== l)
- withDefs += ", ";
- }
- return `{ ${withDefs} }`;
- }
- function stringifyImports(imports, isCJS = false) {
- const map = toImportModuleMap(imports);
- return Object.entries(map).flatMap(([name, importSet]) => {
- const entries = [];
- const imports2 = Array.from(importSet).filter((i) => {
- if (!i.name || i.as === "") {
- let importStr;
- if (isCJS) {
- importStr = `require('${name}');`;
- } else {
- importStr = `import '${name}'`;
- if (i.with)
- importStr += ` with ${stringifyWith(i.with)}`;
- importStr += ";";
- }
- entries.push(importStr);
- return false;
- } else if (i.name === "default" || i.name === "=") {
- let importStr;
- if (isCJS) {
- importStr = i.name === "=" ? `const ${i.as} = require('${name}');` : `const { default: ${i.as} } = require('${name}');`;
- } else {
- importStr = `import ${i.as} from '${name}'`;
- if (i.with)
- importStr += ` with ${stringifyWith(i.with)}`;
- importStr += ";";
- }
- entries.push(importStr);
- return false;
- } else if (i.name === "*") {
- let importStr;
- if (isCJS) {
- importStr = `const ${i.as} = require('${name}');`;
- } else {
- importStr = `import * as ${i.as} from '${name}'`;
- if (i.with)
- importStr += ` with ${stringifyWith(i.with)}`;
- importStr += ";";
- }
- entries.push(importStr);
- return false;
- } else if (!isCJS && i.with) {
- entries.push(`import { ${stringifyImportAlias(i)} } from '${name}' with ${stringifyWith(i.with)};`);
- return false;
- }
- return true;
- });
- if (imports2.length) {
- const importsAs = imports2.map((i) => stringifyImportAlias(i, isCJS));
- entries.push(
- isCJS ? `const { ${importsAs.join(", ")} } = require('${name}');` : `import { ${importsAs.join(", ")} } from '${name}';`
- );
- }
- return entries;
- }).join("\n");
- }
- function dedupeImports(imports, warn) {
- const map = /* @__PURE__ */ new Map();
- const indexToRemove = /* @__PURE__ */ new Set();
- imports.filter((i) => !i.disabled).forEach((i, idx) => {
- if (i.declarationType === "enum" || i.declarationType === "class")
- return;
- const name = i.as ?? i.name;
- if (!map.has(name)) {
- map.set(name, idx);
- return;
- }
- const other = imports[map.get(name)];
- if (other.from === i.from) {
- indexToRemove.add(idx);
- return;
- }
- const diff = (other.priority || 1) - (i.priority || 1);
- if (diff === 0)
- warn(`Duplicated imports "${name}", the one from "${other.from}" has been ignored and "${i.from}" is used`);
- if (diff <= 0) {
- indexToRemove.add(map.get(name));
- map.set(name, idx);
- } else {
- indexToRemove.add(idx);
- }
- });
- return imports.filter((_, idx) => !indexToRemove.has(idx));
- }
- function toExports(imports, fileDir, includeType = false) {
- const map = toImportModuleMap(imports, includeType);
- return Object.entries(map).flatMap(([name, imports2]) => {
- if (isFilePath(name))
- name = name.replace(/\.[a-z]+$/i, "");
- if (fileDir && pathe.isAbsolute(name)) {
- name = pathe.relative(fileDir, name);
- if (!name.match(/^[./]/))
- name = `./${name}`;
- }
- const entries = [];
- const filtered = Array.from(imports2).filter((i) => {
- if (i.name === "*") {
- entries.push(`export * as ${i.as} from '${name}';`);
- return false;
- }
- return true;
- });
- if (filtered.length)
- entries.push(`export { ${filtered.map((i) => stringifyImportAlias(i, false)).join(", ")} } from '${name}';`);
- return entries;
- }).join("\n");
- }
- function stripFileExtension(path) {
- return path.replace(/\.[a-z]+$/i, "");
- }
- function toTypeDeclarationItems(imports, options) {
- return imports.map((i) => {
- const from = options?.resolvePath?.(i) || stripFileExtension(i.typeFrom || i.from);
- let typeDef = "";
- if (i.with)
- typeDef += `import('${from}', { with: ${stringifyWith(i.with)} })`;
- else
- typeDef += `import('${from}')`;
- if (i.name !== "*" && i.name !== "=")
- typeDef += `['${i.name}']`;
- return `const ${i.as}: typeof ${typeDef}`;
- }).sort();
- }
- function toTypeDeclarationFile(imports, options) {
- const items = toTypeDeclarationItems(imports, options);
- const {
- exportHelper = true
- } = options || {};
- let declaration = "";
- if (exportHelper)
- declaration += "export {}\n";
- declaration += `declare global {
- ${items.map((i) => ` ${i}`).join("\n")}
- }`;
- return declaration;
- }
- function makeTypeModulesMap(imports, resolvePath) {
- const modulesMap = /* @__PURE__ */ new Map();
- const resolveImportFrom = typeof resolvePath === "function" ? (i) => {
- return resolvePath(i) || stripFileExtension(i.typeFrom || i.from);
- } : (i) => stripFileExtension(i.typeFrom || i.from);
- for (const import_ of imports) {
- const from = resolveImportFrom(import_);
- let module = modulesMap.get(from);
- if (!module) {
- module = { typeImports: /* @__PURE__ */ new Set(), starTypeImport: void 0 };
- modulesMap.set(from, module);
- }
- if (import_.name === "*") {
- if (import_.as)
- module.starTypeImport = import_;
- } else {
- module.typeImports.add(import_);
- }
- }
- return modulesMap;
- }
- function toTypeReExports(imports, options) {
- const importsMap = makeTypeModulesMap(imports, options?.resolvePath);
- const code = Array.from(importsMap).flatMap(([from, module]) => {
- from = from.replace(/\.d\.([cm]?)ts$/i, ".$1js");
- const { starTypeImport, typeImports } = module;
- const strings = [];
- if (typeImports.size) {
- const typeImportNames = Array.from(typeImports).map(({ name, as }) => {
- if (as && as !== name)
- return `${name} as ${as}`;
- return name;
- });
- strings.push(
- "// @ts-ignore",
- `export type { ${typeImportNames.join(", ")} } from '${from}'`
- );
- }
- if (starTypeImport) {
- strings.push(
- "// @ts-ignore",
- `export type * as ${starTypeImport.as} from '${from}'`
- );
- }
- if (strings.length) {
- strings.push(
- // This is a workaround for a TypeScript issue where type-only re-exports are not properly initialized.
- `import('${from}')`
- );
- }
- return strings;
- });
- return `// for type re-export
- declare global {
- ${code.map((i) => ` ${i}`).join("\n")}
- }`;
- }
- function stringifyImportAlias(item, isCJS = false) {
- return item.as === void 0 || item.name === item.as ? item.name : isCJS ? `${item.name}: ${item.as}` : `${item.name} as ${item.as}`;
- }
- function toImportModuleMap(imports, includeType = false) {
- const map = {};
- for (const _import of imports) {
- if (_import.type && !includeType)
- continue;
- if (!map[_import.from])
- map[_import.from] = /* @__PURE__ */ new Set();
- map[_import.from].add(_import);
- }
- return map;
- }
- function getString(code) {
- if (typeof code === "string")
- return code;
- return code.toString();
- }
- function getMagicString(code) {
- if (typeof code === "string")
- return new MagicString__default(code);
- return code;
- }
- function addImportToCode(code, imports, isCJS = false, mergeExisting = false, injectAtLast = false, firstOccurrence = Number.POSITIVE_INFINITY, onResolved, onStringified) {
- let newImports = [];
- const s = getMagicString(code);
- let _staticImports;
- const strippedCode = stripCommentsAndStrings(s.original);
- function findStaticImportsLazy() {
- if (!_staticImports) {
- _staticImports = mlly.findStaticImports(s.original).filter((i) => Boolean(strippedCode.slice(i.start, i.end).trim())).map((i) => mlly.parseStaticImport(i));
- }
- return _staticImports;
- }
- function hasShebang() {
- const shebangRegex = /^#!.+/;
- return shebangRegex.test(s.original);
- }
- if (mergeExisting && !isCJS) {
- const existingImports = findStaticImportsLazy();
- const map = /* @__PURE__ */ new Map();
- imports.forEach((i) => {
- const target = existingImports.find((e) => e.specifier === i.from && e.imports.startsWith("{"));
- if (!target)
- return newImports.push(i);
- if (!map.has(target))
- map.set(target, []);
- map.get(target).push(i);
- });
- for (const [target, items] of map.entries()) {
- const strings = items.map((i) => `${stringifyImportAlias(i)}, `);
- const importLength = target.code.match(/^\s*import\s*\{/)?.[0]?.length;
- if (importLength)
- s.appendLeft(target.start + importLength, ` ${strings.join("").trim()}`);
- }
- } else {
- newImports = imports;
- }
- newImports = onResolved?.(newImports) ?? newImports;
- let newEntries = stringifyImports(newImports, isCJS);
- newEntries = onStringified?.(newEntries, newImports) ?? newEntries;
- if (newEntries) {
- const insertionIndex = injectAtLast ? findStaticImportsLazy().reverse().find((i) => i.end <= firstOccurrence)?.end ?? 0 : 0;
- if (insertionIndex > 0)
- s.appendRight(insertionIndex, `
- ${newEntries}
- `);
- else if (hasShebang())
- s.appendLeft(s.original.indexOf("\n") + 1, `
- ${newEntries}
- `);
- else
- s.prepend(`${newEntries}
- `);
- }
- return {
- s,
- get code() {
- return s.toString();
- }
- };
- }
- function normalizeImports(imports) {
- for (const _import of imports)
- _import.as = _import.as ?? _import.name;
- return imports;
- }
- function resolveIdAbsolute(id, parentId) {
- return mlly.resolvePathSync(id, {
- url: parentId
- });
- }
- function isFilePath(path) {
- return path.startsWith(".") || pathe.isAbsolute(path) || path.includes("://");
- }
- const toImports = stringifyImports;
- const contextRE$1 = /\b_ctx\.([$\w]+)\b/g;
- const UNREF_KEY = "__unimport_unref_";
- const VUE_TEMPLATE_NAME = "unimport:vue-template";
- function vueTemplateAddon() {
- const self = {
- name: VUE_TEMPLATE_NAME,
- async transform(s, id) {
- if (!s.original.includes("_ctx.") || s.original.includes(UNREF_KEY))
- return s;
- const matches = Array.from(s.original.matchAll(contextRE$1));
- const imports = await this.getImports();
- let targets = [];
- for (const match of matches) {
- const name = match[1];
- const item = imports.find((i) => i.as === name);
- if (!item)
- continue;
- const start = match.index;
- const end = start + match[0].length;
- const tempName = `__unimport_${name}`;
- s.overwrite(start, end, `(${JSON.stringify(name)} in _ctx ? _ctx.${name} : ${UNREF_KEY}(${tempName}))`);
- if (!targets.find((i) => i.as === tempName)) {
- targets.push({
- ...item,
- as: tempName
- });
- }
- }
- if (targets.length) {
- targets.push({
- name: "unref",
- from: "vue",
- as: UNREF_KEY
- });
- for (const addon of this.addons) {
- if (addon === self)
- continue;
- targets = await addon.injectImportsResolved?.call(this, targets, s, id) ?? targets;
- }
- let injection = stringifyImports(targets);
- for (const addon of this.addons) {
- if (addon === self)
- continue;
- injection = await addon.injectImportsStringified?.call(this, injection, targets, s, id) ?? injection;
- }
- s.prepend(injection);
- }
- return s;
- },
- async declaration(dts, options) {
- const imports = await this.getImports();
- const items = imports.map((i) => {
- if (i.type || i.dtsDisabled)
- return "";
- const from = options?.resolvePath?.(i) || i.from;
- return `readonly ${i.as}: UnwrapRef<typeof import('${from}')${i.name !== "*" ? `['${i.name}']` : ""}>`;
- }).filter(Boolean).sort();
- const extendItems = items.map((i) => ` ${i}`).join("\n");
- return `${dts}
- // for vue template auto import
- import { UnwrapRef } from 'vue'
- declare module 'vue' {
- interface ComponentCustomProperties {
- ${extendItems}
- }
- }`;
- }
- };
- return self;
- }
- const contextRE = /resolveDirective as _resolveDirective/;
- const contextText = `${contextRE.source}, `;
- const directiveRE = /(?:var|const) (\w+) = _resolveDirective\("([\w.-]+)"\);?\s*/g;
- const VUE_DIRECTIVES_NAME = "unimport:vue-directives";
- function vueDirectivesAddon(options = {}) {
- function isDirective(importEntry) {
- let isDirective2 = importEntry.meta?.vueDirective === true;
- if (isDirective2) {
- return true;
- }
- isDirective2 = options.isDirective?.(normalizePath(process__default.cwd(), importEntry.from), importEntry) ?? false;
- if (isDirective2) {
- importEntry.meta ?? (importEntry.meta = {});
- importEntry.meta.vueDirective = true;
- }
- return isDirective2;
- }
- const self = {
- name: VUE_DIRECTIVES_NAME,
- async transform(s, id) {
- if (!s.original.match(contextRE))
- return s;
- const matches = Array.from(s.original.matchAll(directiveRE)).sort((a, b) => b.index - a.index);
- if (!matches.length)
- return s;
- let targets = [];
- for await (const [
- begin,
- end,
- importEntry
- ] of findDirectives(
- isDirective,
- matches,
- this.getImports()
- )) {
- s.overwrite(begin, end, "");
- targets.push(importEntry);
- }
- if (!targets.length)
- return s;
- s.replace(contextText, "");
- for (const addon of this.addons) {
- if (addon === self)
- continue;
- targets = await addon.injectImportsResolved?.call(this, targets, s, id) ?? targets;
- }
- let injection = stringifyImports(targets);
- for (const addon of this.addons) {
- if (addon === self)
- continue;
- injection = await addon.injectImportsStringified?.call(this, injection, targets, s, id) ?? injection;
- }
- s.prepend(injection);
- return s;
- },
- async declaration(dts, options2) {
- const directivesMap = await this.getImports().then((imports) => {
- return imports.filter(isDirective).reduce((acc, i) => {
- if (i.type || i.dtsDisabled)
- return acc;
- let name;
- if (i.name === "default" && (i.as === "default" || !i.as)) {
- const file = node_path.basename(i.from);
- const idx = file.indexOf(".");
- name = idx > -1 ? file.slice(0, idx) : file;
- } else {
- name = i.as ?? i.name;
- }
- name = name[0] === "v" ? scule.camelCase(name) : scule.camelCase(`v-${name}`);
- if (!acc.has(name)) {
- acc.set(name, i);
- }
- return acc;
- }, /* @__PURE__ */ new Map());
- });
- if (!directivesMap.size)
- return dts;
- const directives = Array.from(directivesMap.entries()).map(([name, i]) => ` ${name}: typeof import('${options2?.resolvePath?.(i) || i.from}')['${i.name}']`).sort().join("\n");
- return `${dts}
- // for vue directives auto import
- declare module 'vue' {
- interface ComponentCustomProperties {
- ${directives}
- }
- interface GlobalDirectives {
- ${directives}
- }
- }`;
- }
- };
- return self;
- }
- function resolvePath(cwd, path) {
- return path[0] === "." ? pathe.resolve(cwd, path) : path;
- }
- function normalizePath(cwd, path) {
- return resolvePath(cwd, path).replace(/\\/g, "/");
- }
- async function* findDirectives(isDirective, regexArray, importsPromise) {
- const imports = (await importsPromise).filter(isDirective);
- if (!imports.length)
- return;
- const symbols = regexArray.reduce((acc, regex) => {
- const [all, symbol, resolveDirectiveName] = regex;
- if (acc.has(symbol))
- return acc;
- acc.set(symbol, [
- regex.index,
- regex.index + all.length,
- scule.kebabCase(resolveDirectiveName)
- ]);
- return acc;
- }, /* @__PURE__ */ new Map());
- for (const [symbol, data] of symbols.entries()) {
- yield* findDirective(imports, symbol, data);
- }
- }
- function* findDirective(imports, symbol, [begin, end, importName]) {
- let resolvedName;
- for (const i of imports) {
- if (i.name === "default" && (i.as === "default" || !i.as)) {
- const file = node_path.basename(i.from);
- const idx = file.indexOf(".");
- resolvedName = scule.kebabCase(idx > -1 ? file.slice(0, idx) : file);
- } else {
- resolvedName = scule.kebabCase(i.as ?? i.name);
- }
- if (resolvedName[0] === "v") {
- resolvedName = resolvedName.slice(resolvedName[1] === "-" ? 2 : 1);
- }
- if (resolvedName === importName) {
- yield [
- begin,
- end,
- { ...i, name: i.name, as: symbol }
- ];
- return;
- }
- }
- }
- exports.VUE_DIRECTIVES_NAME = VUE_DIRECTIVES_NAME;
- exports.VUE_TEMPLATE_NAME = VUE_TEMPLATE_NAME;
- exports.addImportToCode = addImportToCode;
- exports.dedupeImports = dedupeImports;
- exports.defineUnimportPreset = defineUnimportPreset;
- exports.excludeRE = excludeRE;
- exports.getMagicString = getMagicString;
- exports.getString = getString;
- exports.importAsRE = importAsRE;
- exports.matchRE = matchRE;
- exports.normalizeImports = normalizeImports;
- exports.resolveIdAbsolute = resolveIdAbsolute;
- exports.separatorRE = separatorRE;
- exports.stringifyImports = stringifyImports;
- exports.stripCommentsAndStrings = stripCommentsAndStrings;
- exports.stripFileExtension = stripFileExtension;
- exports.toExports = toExports;
- exports.toImports = toImports;
- exports.toTypeDeclarationFile = toTypeDeclarationFile;
- exports.toTypeDeclarationItems = toTypeDeclarationItems;
- exports.toTypeReExports = toTypeReExports;
- exports.vueDirectivesAddon = vueDirectivesAddon;
- exports.vueTemplateAddon = vueTemplateAddon;
|