unplugin-export-collector
Version:
Recursively get all named export from a file and out-of-the-box support unplugin-auto-import
81 lines (72 loc) • 6.43 kB
JavaScript
;const i$1=require("node:process"),node_fs=require("node:fs"),pathe=require("pathe"),core=require("@swc/core"),utils=require("@s3xysteak/utils");function _interopDefaultCompat(e){return e&&typeof e=="object"&&"default"in e?e.default:e}const i__default=_interopDefaultCompat(i$1);async function isDirectory(e){return(await node_fs.promises.stat(e)).isDirectory()}async function findPath(e,t){const n=pathe.resolve(t??i__default.cwd(),e),r=node_fs.existsSync(n)&&await isDirectory(n)?pathe.resolve(n,"index"):n,p=findExtension(r,t);if(utils.isUndefined(p))throw new Error(`File not found: ${r}`);return r+p}async function getPkg(e){const t=e?pathe.normalize(e):pathe.resolve(i__default.cwd(),"./package.json"),n=await node_fs.promises.readFile(t,"utf-8").then(p=>JSON.parse(p)),r=!!(n?.devDependencies?.typescript||n?.dependencies?.typescript);return{raw:n,isTs:r}}function findExtension(e,t=i__default.cwd()){const n=pathe.resolve(t,e);return["",".mjs",".js",".mts",".ts",".jsx",".tsx",".json"].find(r=>node_fs.existsSync(n+r))}function addExtension(e,t=i__default.cwd()){return e+findExtension(e,t)}function toValue(e){return utils.isFunction(e)?e():e}const f=new Set(["/","\\",void 0]),i=Symbol.for("pathe:normalizedAlias");function normalizeAliases(e){if(e[i])return e;const t=Object.fromEntries(Object.entries(e).sort(([n],[r])=>u$1(n,r)));for(const n in t)for(const r in t)r===n||n.startsWith(r)||t[n].startsWith(r)&&f.has(t[n][r.length])&&(t[n]=t[r]+t[n].slice(r.length));return Object.defineProperty(t,i,{value:!0,enumerable:!1}),t}function resolveAlias(e,t){const n=pathe.toNamespacedPath(e);t=normalizeAliases(t);for(const[r,p]of Object.entries(t)){if(!n.startsWith(r))continue;const c=s(r)?r.slice(0,-1):r;if(s(n[c.length]))return pathe.join(p,n.slice(r.length))}return n}function u$1(e,t){return t.split("/").length-e.split("/").length}function s(e="/"){const t=e[e.length-1];return t==="/"||t==="\\"}async function expCollector(e,t){const{base:n,alias:r={}}=t??{},p=new Set,c=async(a,o)=>{const l=await findPath(a,o),x=await node_fs.promises.readFile(l,"utf-8"),{exp:y,refer:d}=await parser(x);y.forEach(m=>p.add(m)),await utils.p(d,{concurrency:Number.POSITIVE_INFINITY}).forEach(async m=>await c(resolveAlias(m,r),pathe.dirname(l)))};return await c(e,n??i__default.cwd()),Array.from(p)}async function parser(e){const t=[],n=[],{raw:r,isTs:p}=await getPkg();(await core.parse(e,{syntax:p?"typescript":"ecmascript",target:"es2020"})).body.forEach(a=>{a.type==="ExportAllDeclaration"&&n.push(a.source.value),a.type==="ExportNamedDeclaration"&&a.specifiers.forEach(o=>{o.type==="ExportSpecifier"&&t.push(o?.exported?.value??o.orig.value),o.type==="ExportNamespaceSpecifier"&&n.push(o.name.value)}),a.type==="ExportDeclaration"&&(a.declaration.type==="VariableDeclaration"&&a.declaration.declarations.forEach(o=>o.id.type==="Identifier"&&t.push(o.id.value)),a.declaration.type==="FunctionDeclaration"&&t.push(a.declaration.identifier.value),a.declaration.type==="ClassDeclaration"&&t.push(a.declaration.identifier.value))});const c=[...Object.keys(r.dependencies??{}),...Object.keys(r.devDependencies??{})];return{exp:t,refer:n.filter(a=>!c.includes(a))}}const COMMENT="// --- Auto-Generated By Unplugin-Export-Collector ---";function importsTemplate(e,t,n,r){return{ts:`
const __UnExportList = ${JSON.stringify(e)} as const
/**
* @returns Call in \`imports\` option of \`unplugin-auto-import\`.
*/
${r?"export default":"export"} function ${n}(map?: Partial<{ [K in typeof __UnExportList[number]]: string }>): Record<string, (string | [string, string])[]> {
return {
'${t}': __UnExportList.map(v => map && map[v] ? [v, map[v]] as [string, string] : v),
}
}
`,js:`
const __UnExportList = /** @type {const} */ (${JSON.stringify(e)})
/**
* @param {Partial<{ [K in typeof __UnExportList[number]]: string }>} [map]
* @returns {Record<string, (string | [string, string])[]>} Call in \`imports\` option of \`unplugin-auto-import\`.
*/
${r?"export default":"export"} function ${n}(map) {
return {
'${t}': __UnExportList.map(v => map && map[v] ? [v, map[v]] : v),
}
}
`}}function resolversTemplate(e,t,n,r){return{ts:`
const __UnExportList = ${JSON.stringify(e)} as const
/**
* @returns Call in \`resolvers\` option of \`unplugin-auto-import\`.
*/
${r?"export default":"export"} function ${n}(map?: Partial<{ [K in typeof __UnExportList[number]]: string }>) {
return (name: string) => {
if (!__UnExportList.includes(name as any))
return
return map && (map as any)[name]
? {
name,
as: (map as any)[name],
from: '${t}',
}
: {
name,
from: '${t}',
}
}
}
`,js:`
const __UnExportList = /** @type {const} */ (${JSON.stringify(e)})
/**
* @param {Partial<{ [K in typeof __UnExportList[number]]: string }>} [map]
* @returns Call in \`resolvers\` option of \`unplugin-auto-import\`.
*/
${r?"export default":"export"} function ${n}(map) {
/** @param {string} name */
const func = (name) => {
if (!__UnExportList.includes(name))
return
return map && map[name]
? {
name,
as: map[name],
from: '${t}',
}
: {
name,
from: '${t}',
}
}
return func
}
`}}async function expGenerator(e,t={}){const{data:n,pkgContext:{isTs:r}}=await expGeneratorData(e,t),{type:p,base:c,typescript:a=r,writeTo:o=`./src/${p}.${a?"ts":"js"}`}=u(t);return await node_fs.promises.writeFile(pathe.resolve(c,pathe.extname(o)?o:`${o}.${a?"ts":"js"}`),n)}async function expGeneratorData(e,t={}){const{raw:n,isTs:r}=await getPkg(),{base:p,include:c,exclude:a,rename:o,exportDefault:l,alias:x,type:y,typescript:d=r,pkgName:m=n.name}=u(t);a.push(o);const g=[...await expCollector(e,{base:p,alias:x}),...c].filter(h=>!a.includes(h)).sort(),w=y==="imports"?importsTemplate(g,m,o,l)[d?"ts":"js"]:resolversTemplate(g,m,o,l)[d?"ts":"js"];return{data:`${`
${COMMENT}
${w.trim()}
${COMMENT}
`.trim()}
`,pkgContext:{pkg:n,isTs:r}}}function u(e={}){const{type:t="imports",base:n=i__default.cwd(),include:r=[],exclude:p=[],rename:c="autoImport",exportDefault:a=!0,alias:o,...l}=e;return{type:t,base:n,include:r,exclude:p,rename:c,exportDefault:a,alias:o,...l}}exports.addExtension=addExtension,exports.expCollector=expCollector,exports.expGenerator=expGenerator,exports.expGeneratorData=expGeneratorData,exports.parser=parser,exports.toValue=toValue;