{"version":3,"file":"index.mjs","sources":["../src/logger.ts","../src/analyze-project.ts","../src/exports.ts","../src/vite-plugin-library.ts"],"sourcesContent":["import * as colors from 'picocolors';\n\nconst { bgRed, bold, red, yellow } = colors;\nexport const logger = {\n  fatal(name: string, ...messages: unknown[]) {\n    console.error(bgRed(bold(' FATAL ')), red(bold(name)), ...messages);\n  },\n  warn(name: string, ...messages: unknown[]) {\n    console.debug(yellow(bold(` ⚠️ ${name}${messages.length > 0 ? ': ' : ''}`)), ...messages);\n  }\n};\n","import { exists } from '@neodx/fs';\nimport { asyncReduce, keys } from '@neodx/std';\nimport { relative, resolve } from 'node:path';\n// @ts-expect-error Outdated types\nimport { readPackageJSON, readTSConfig } from 'pkg-types';\nimport { logger } from './logger';\n\nexport async function analyzeProject(cwd: string) {\n  const pkg = await readPackageJSON(resolve(cwd, 'package.json'));\n  const prodDeps = { ...pkg.dependencies, ...pkg.peerDependencies, ...pkg.optionalDependencies };\n  const deps = {\n    prod: keys(prodDeps),\n    dev: keys(pkg.devDependencies ?? {}),\n    all: keys({ ...pkg.devDependencies, ...prodDeps })\n  };\n\n  const haveTypescript = deps.all.includes('typescript');\n  const tsConfig = haveTypescript ? await loadTsConfig(cwd) : null;\n\n  const defaultEntryAbs = await findDefaultEntry(cwd);\n\n  if (haveTypescript && !pkg.vitePluginDts) {\n    logger.warn(\n      `Install \"vite-plugin-dts\" for automatic .dts generation:\\n`,\n      `npm i -D vite-plugin-dts\nyarn add -D vite-plugin-dts\npnpm i -D vite-plugin-dts`\n    );\n  }\n\n  return {\n    pkg,\n    deps,\n    tsConfig,\n    defaultEntry: defaultEntryAbs ? relative(cwd, defaultEntryAbs) : null\n  };\n}\n\nasync function loadTsConfig(cwd: string) {\n  try {\n    return readTSConfig(resolve(cwd, 'tsconfig.json'));\n  } catch {\n    logger.fatal(`tsconfig.json not found`);\n    return null;\n  }\n}\n\nconst findDefaultEntry = async (cwd: string) =>\n  asyncReduce(\n    extensionsPriority,\n    async (acc: string | null, ext) => {\n      if (acc) return acc;\n      const rootFile = resolve(cwd, `index.${ext}`);\n      const srcFile = resolve(cwd, `src/index.${ext}`);\n\n      if (await exists(rootFile)) return rootFile;\n      if (await exists(srcFile)) return srcFile;\n      return null;\n    },\n    null\n  );\nconst extensionsPriority = ['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs'];\n","import { compactObject } from '@neodx/std';\nimport { join, relative } from 'node:path';\nimport type { NormalizedOutputOptions, OutputAsset, OutputBundle, OutputChunk } from 'rollup';\nimport { normalizePath } from 'vite';\n\nexport type ExportsKey = 'types' | 'require' | 'default' | 'import' | 'browser' | 'node';\nexport type ExportsRecord = Partial<Record<ExportsKey, string>>;\nexport type ExportsGenerator = ReturnType<typeof createExportsGenerator>;\nexport interface ExportsGeneratorParams {\n  addTypes?: boolean;\n  outDir?: string;\n  root?: string;\n}\n\nexport function createExportsGenerator({\n  addTypes,\n  root = '',\n  outDir = 'dist'\n}: ExportsGeneratorParams) {\n  const exportsMap = new Map<string, ExportsRecord>();\n  const relativeOutDir = outDir.startsWith(root) ? relative(root, outDir) : outDir;\n\n  return {\n    addBundle({ format }: NormalizedOutputOptions, bundle: OutputBundle) {\n      if (!supportedFormats.includes(format)) {\n        return;\n      }\n      const entryChunks = Object.values(bundle).filter(isChunk).filter(isEntryChunk);\n\n      for (const chunk of entryChunks) {\n        const exportFile = `./${normalizePath(join(relativeOutDir, chunk.fileName))}`;\n        const exportName = getExportName(chunk.name);\n        const haveDefaultExport = chunk.exports.includes('default');\n        const haveNamedExports = chunk.exports.some(name => name !== 'default');\n\n        exportsMap.set(exportName, {\n          ...exportsMap.get(exportName),\n          ...compactObject({\n            require: format === 'cjs' && exportFile,\n            default: format === 'es' && haveDefaultExport && exportFile,\n            import: format === 'es' && haveNamedExports && exportFile,\n            types: addTypes && exportFile.replace(/\\.[a-z]*$/, '.d.ts')\n          })\n        });\n      }\n    },\n    getExports() {\n      return Object.fromEntries(exportsMap);\n    },\n    getFields() {\n      const main = exportsMap.get('.') ?? {};\n\n      return compactObject({\n        main: main.require,\n        types: main.types,\n        module: main.import ?? main.default\n      });\n    }\n  };\n}\n\nconst supportedFormats = ['cjs', 'es'];\nconst isChunk = (entry: OutputAsset | OutputChunk): entry is OutputChunk => entry.type === 'chunk';\nconst isEntryChunk = ({ isEntry }: OutputChunk) => isEntry;\n\n/**\n * @example index -> .\n * @example foo/bar -> ./foo/bar\n * @example foo/baz/index -> ./foo/baz\n */\nconst getExportName = (name: string) =>\n  name === 'index' ? '.' : `./${name.replace(/\\/index/, '')}`;\n","import { scan } from '@neodx/fs';\nimport { compact, toArray } from '@neodx/std';\nimport { createVfs, type VFS } from '@neodx/vfs';\nimport { builtinModules } from 'node:module';\n// @ts-expect-error Outdated types\nimport type { PackageJson } from 'pkg-types';\nimport type { Plugin } from 'vite';\nimport { analyzeProject } from './analyze-project';\nimport { createExportsGenerator, type ExportsGenerator } from './exports';\n\nexport interface VitePluginLibraryParams {\n  entry?: string | string[];\n  addTypes?: boolean;\n  updatePackageExports?: boolean;\n  updatePackageMainFields?: boolean;\n}\n\nexport function vitePluginLibrary({\n  entry: userEntry,\n  addTypes,\n  updatePackageExports,\n  updatePackageMainFields = updatePackageExports\n}: VitePluginLibraryParams = {}): Plugin {\n  let vfs: VFS;\n  let exportsGenerator: ExportsGenerator | null = null;\n\n  return {\n    name: 'vite-plugin-library',\n    async closeBundle() {\n      if (exportsGenerator) {\n        await vfs.updateJson<PackageJson>('package.json', prev => ({\n          ...prev,\n          ...exportsGenerator?.getFields(),\n          exports: {\n            ...(typeof prev.exports !== 'string' && prev.exports),\n            ...exportsGenerator?.getExports()\n          }\n        }));\n        console.log(await vfs.readJson('package.json'));\n      }\n    },\n    generateBundle(options, files) {\n      exportsGenerator?.addBundle(options, files);\n    },\n    async config({ root = process.cwd(), build }) {\n      const { pkg, defaultEntry, deps, tsConfig } = await analyzeProject(root);\n      const entryPatterns = compact(toArray(userEntry ?? defaultEntry));\n      const entryFiles = await scan(root, entryPatterns);\n      const entry = Object.fromEntries(\n        entryFiles.map(file => [file.replace('src/', '').replace(/\\.[tj]sx?$/, ''), file])\n      );\n\n      if (entryFiles.length === 0) {\n        throw new Error(`Not found any entry file`);\n      }\n      vfs = createVfs(root, { dryRun: true });\n      if (updatePackageExports || updatePackageMainFields) {\n        exportsGenerator = createExportsGenerator({\n          addTypes: addTypes ?? Boolean(tsConfig),\n          outDir: build?.outDir,\n          root\n        });\n      }\n      return {\n        build: {\n          lib: {\n            name: pkg.name,\n            entry,\n            formats: ['cjs', 'es']\n          },\n          rollupOptions: {\n            external: [\n              /node:.*/,\n              // eslint-disable-next-line @typescript-eslint/require-array-sort-compare\n              ...builtinModules.filter(x => !/^_|^(internal|v8|node-inspect)\\/|\\//.test(x)).sort(),\n              ...deps.prod\n            ]\n          }\n        }\n      };\n    }\n  };\n}\n"],"names":["bgRed","bold","red","yellow","colors","logger","fatal","name","messages","console","error","warn","debug","length","analyzeProject","cwd","pkg","readPackageJSON","resolve","prodDeps","dependencies","peerDependencies","optionalDependencies","deps","prod","keys","dev","devDependencies","all","haveTypescript","includes","tsConfig","loadTsConfig","defaultEntryAbs","findDefaultEntry","vitePluginDts","defaultEntry","relative","readTSConfig","asyncReduce","extensionsPriority","acc","ext","rootFile","srcFile","exists","supportedFormats","isChunk","entry","type","isEntryChunk","isEntry","getExportName","replace","vitePluginLibrary","userEntry","addTypes","updatePackageExports","updatePackageMainFields","vfs","exportsGenerator","closeBundle","updateJson","prev","getFields","exports","getExports","log","readJson","generateBundle","options","files","addBundle","config","root","process","build","entryPatterns","compact","toArray","entryFiles","scan","Object","fromEntries","map","file","Error","createVfs","dryRun","createExportsGenerator","outDir","exportsMap","Map","relativeOutDir","startsWith","format","bundle","entryChunks","values","filter","chunk","exportFile","normalizePath","join","fileName","exportName","haveDefaultExport","haveNamedExports","some","set","get","compactObject","require","default","import","types","main","module","Boolean","lib","formats","rollupOptions","external","builtinModules","x","test","sort"],"mappings":"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"}