'use strict'; const path = require('node:path'); const process = require('node:process'); const unplugin = require('unplugin'); const ci = require('ci-info'); const simpleGit = require('simple-git'); const parseGitUrl = require('git-url-parse'); const fs = require('node:fs'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } const path__default = /*#__PURE__*/_interopDefaultCompat(path); const process__default = /*#__PURE__*/_interopDefaultCompat(process); const ci__default = /*#__PURE__*/_interopDefaultCompat(ci); const parseGitUrl__default = /*#__PURE__*/_interopDefaultCompat(parseGitUrl); const fs__default = /*#__PURE__*/_interopDefaultCompat(fs); var __defProp$1 = Object.defineProperty; var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$1 = (obj, key, value) => { __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class BuildInfoModule { constructor(name, root, options) { __publicField$1(this, "name"); __publicField$1(this, "root"); __publicField$1(this, "options"); this.name = `${options?.prefix ?? "~build"}/${name}`; this.root = root; this.options = options; } buildStart(ctx) { } buildEnd(ctx) { } } var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class BuildTimeModule extends BuildInfoModule { constructor(root, options) { super("time", root, options); __publicField(this, "now"); } buildStart() { this.now = /* @__PURE__ */ new Date(); } load() { return `const time = new Date(${this.now.getTime()}) export default time`; } } async function getRepoInfo(root, extra = {}) { const git = simpleGit.simpleGit(root); if (!await git.checkIsRepo()) { return void 0; } const [branch, currentCommit, committer, tags, github, result] = await Promise.all([ getBranch(git), getCommit(git), getCommitter(git), getTags(git), getGitHubUrl(git), Promise.all( Object.entries(extra).map(async ([key, fn]) => { return [key, await fn(git)]; }) ) ]); return { ...branch, ...currentCommit, ...committer, ...tags, ...github, ...Object.fromEntries(result) }; } async function getBranch(git) { try { const branch = (await git.branch([])).current; return { branch }; } catch (error) { return { branch: void 0 }; } } async function getCommit(git) { try { const log = await git.log(["-1"]); const sha = log.latest?.hash; const commitMessage = log.latest?.message; const author = log.latest?.author_name; const authorEmail = log.latest?.author_email; const authorDate = log.latest?.date; return { sha, abbreviatedSha: sha?.slice(0, 10), commitMessage, author, authorEmail, authorDate }; } catch (error) { return { sha: void 0, abbreviatedSha: void 0, commitMessage: void 0, author: void 0, authorEmail: void 0, authorDate: void 0 }; } } function removeLineBreak(str) { return str.replace(/[\s\r\n]+$/, ""); } async function getCommitter(git) { try { const [committer, committerEmail, committerDate] = await Promise.all([ git.show(["-s", "--format=%cn"]), git.show(["-s", "--format=%ce"]), git.show(["-s", "--format=%cd"]) ]); return { committer: removeLineBreak(committer), committerEmail: removeLineBreak(committerEmail), committerDate: removeLineBreak(committerDate) }; } catch (error) { return { committer: void 0, committerEmail: void 0, committerDate: void 0 }; } } async function getTags(git) { try { const hash = await git.revparse(["HEAD"]); const tags = await git.tags(["--points-at", hash]); const all = await git.tags(); return { tag: tags.all[tags.all.length - 1], tags: tags.all, lastTag: all.latest }; } catch (error) { return { tags: void 0, lastTag: void 0 }; } } async function getGitHubUrl(git) { const remotes = await git.getRemotes(true); const origin = remotes.find((remote) => remote.name === "origin"); const url = origin?.refs.fetch; if (url) { const parsed = parseGitUrl__default(url); if (parsed.resource === "github.com" && parsed.full_name) { return { github: `https://github.com/${parsed.full_name}` }; } } return { github: void 0 }; } class BuildGitModule extends BuildInfoModule { constructor(root, options) { super("git", root, options); } async load(ctx, id) { const { root, options } = this; const info = await getRepoInfo(root, options?.git); if (info && options?.github) { info.github = options.github; } if (!info) { ctx.warn("This may not be a git repo"); } const keys = [ .../* @__PURE__ */ new Set([ "github", "sha", "abbreviatedSha", "branch", "tag", "tags", "lastTag", "author", "authorEmail", "authorDate", "committer", "committerEmail", "committerDate", "commitMessage", ...Object.keys(options?.git ?? {}) ]) ]; const gen = (key) => { return `export const ${key} = ${info ? JSON.stringify(info[key]) : "null"}`; }; return [ // Support legacy ~build/info module id.endsWith("info") ? `export const CI = ${ci__default.isCI ? `"${ci__default.name}"` : "null"}` : ``, ...keys.map((key) => gen(key)) ].join("\n"); } } class LegacyInfoModule extends BuildGitModule { constructor(root, options) { super(root, options); this.name = `${options.prefix ?? "~build"}/info`; } } class BuildConsoleModule extends BuildInfoModule { constructor(root, options) { super("console", root, options); } load() { const { environment = ["development", "production"] } = this.options.console ?? {}; return [ `import time from '~build/time';`, `import { isCI } from '~build/ci';`, `import { github } from '~build/git';`, `import { name, version } from '~build/package';`, ``, `export const print = () => {`, ` if (!${JSON.stringify(environment)}.includes(process.env.NODE_ENV)) return;`, ` if (import.meta.env.SSR) return;`, ` console.groupCollapsed('~build/console');`, ` console.log('Project:', name);`, ` console.log('Build-at:', time ? time.toLocaleString() : 'Unknown');`, ` console.log('Environment:', \`\${process.env.NODE_ENV}\${isCI ? '(ci)' : ''}\`);`, ` console.log('Version:', version);`, ` console.log('GitHub:', github);`, ` console.groupEnd();`, `};`, ``, `print();` ].join("\n"); } } class BuildCIModule extends BuildInfoModule { constructor(root, options) { super("ci", root, options); } load() { return [ `export const isCI = ${ci__default.isCI !== null ? ci__default.isCI ? "true" : "false" : "null"}`, `export const isPR = ${ci__default.isPR !== null ? ci__default.isPR ? "true" : "false" : "null"}`, `export const name = ${ci__default.name !== null ? `\`${ci__default.name}\`` : "null"}` ].join("\n"); } } class BuildMetaModule extends BuildInfoModule { constructor(root, options) { super("meta", root, options); } async load() { const { options } = this; const get = () => { if (!options?.meta) return {}; if (typeof options.meta === "function") { return options.meta(); } return options.meta; }; const meta = await get(); const body = Object.entries(meta).map( ([key, value]) => `export const ${key} = ${JSON.stringify(value, null, 2)};` ); return body.length > 0 ? body.join("\n") : "export {};"; } } class BuildEnvModule extends BuildInfoModule { constructor(root, options) { super("env", root, options); } async load() { const { options } = this; const get = () => { if (!options?.env) return {}; if (typeof options.env === "function") { return options.env(); } return options.env; }; const cloudflare = options.cloudflare === true; const meta = await get(); const body = Object.entries(meta).map( ([key, value]) => !cloudflare ? `export const ${key} = (import.meta.env.SSR ? process?.env?.['${key.replace(/'/g, "\\")}'] : undefined) ?? ${JSON.stringify(value, null, 2)};` : `export const ${key} = ${JSON.stringify(value, null, 2)};` ); return body.length > 0 ? body.join("\n") : "export {};"; } } class BuildPackageModule extends BuildInfoModule { constructor(root, options) { super("package", root, options); } load() { const { root, options } = this; const pkg = JSON.parse(fs__default.readFileSync(path__default.join(root, "package.json"), "utf-8")); const defaults = ["name", "version", "description", "keywords", "license", "author"]; const keys = new Set( Array.isArray(options?.package) ? [...defaults, ...options.package] : typeof options?.package === "object" ? Object.entries( Object.fromEntries([ ...defaults.map((d) => [d, true]), ...Object.entries(options.package) ]) ).filter(([k, v]) => !!v).map(([k, v]) => k) : defaults ); const resolved = { name: "", version: "0.0.0", description: "", keywords: [], license: "", author: "", ...pkg }; const entries = [...keys].map((key) => [key, resolved[key]]); return entries.map(([key, value]) => `export const ${key} = ${JSON.stringify(value, null, 2)};`).join("\n"); } } const UnpluginInfo = /* @__PURE__ */ unplugin.createUnplugin( (options = {}, meta) => { const root = path__default.resolve(options?.root ?? process__default.cwd()); const modules = { Time: new BuildTimeModule(root, options), Git: new BuildGitModule(root, options), CI: new BuildCIModule(root, options), Info: new LegacyInfoModule(root, options), Console: new BuildConsoleModule(root, options), Meta: new BuildMetaModule(root, options), Env: new BuildEnvModule(root, options), Package: new BuildPackageModule(root, options) }; return { name: "unplugin-info", async buildStart() { await Promise.all(Object.values(modules).map((mod) => mod.buildStart(this))); }, async buildEnd() { await Promise.all(Object.values(modules).map((mod) => mod.buildEnd(this))); }, resolveId(id) { if (Object.values(modules).map((m) => m.name).includes(id)) { return `\0${id}`; } }, loadInclude(id) { if (!id.startsWith("\0")) return false; id = id.slice(1); return Object.values(modules).map((m) => m.name).includes(id); }, async load(id) { if (!id.startsWith("\0")) return; id = id.slice(1); for (const mod of Object.values(modules)) { if (id === mod.name) { if (id === modules.Info.name) { this.warn( `${modules.Info.name} is deprecated, please migrate to ${modules.Git.name} and ${modules.CI.name}.` ); } if (id === modules.Env.name && meta.framework !== "vite") { this.warn(`${modules.Env.name} is only supported in Vite.`); return; } return mod.load(this, id); } } }, vite: { handleHotUpdate({ file, server }) { if (file === normalizePath(path__default.resolve(root, "package.json"))) { const module = server.moduleGraph.getModuleById("\0" + modules.Package.name); if (module) { server.moduleGraph.invalidateModule(module); server.ws.send({ type: "full-reload" }); } } } } }; } ); function normalizePath(filename) { return filename.split(path__default.win32.sep).join(path__default.posix.sep); } exports.BuildInfoModule = BuildInfoModule; exports.UnpluginInfo = UnpluginInfo;