var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; import { readFileSync, writeFileSync, existsSync } from 'fs'; import { execFileSync } from 'child_process'; import { resolve, join } from 'path'; function findVersionFile(projectRoot, customPath) { // If custom path provided, use it if (customPath) { var resolved = resolve(projectRoot, customPath); if (existsSync(resolved)) return resolved; return null; } // Search order: project VERSION.txt -> project VERSION.json -> monorepo VERSION.txt -> monorepo VERSION.json var searchPaths = __spreadArray([ join(projectRoot, 'VERSION.txt'), join(projectRoot, 'VERSION.json') ], findMonorepoVersionPaths(projectRoot), true); for (var _i = 0, searchPaths_1 = searchPaths; _i < searchPaths_1.length; _i++) { var p = searchPaths_1[_i]; if (existsSync(p)) return p; } return null; } function findMonorepoVersionPaths(startDir) { var paths = []; var current = startDir; var depth = 0; var maxDepth = 10; while (depth < maxDepth) { var parent_1 = resolve(current, '..'); if (parent_1 === current) break; var workspaceFile = join(parent_1, 'pnpm-workspace.yaml'); if (existsSync(workspaceFile)) { paths.push(join(parent_1, 'VERSION.txt')); paths.push(join(parent_1, 'VERSION.json')); break; } current = parent_1; depth++; } return paths; } function readVersion(filePath) { var content = readFileSync(filePath, 'utf-8').trim(); // If JSON file, parse and extract version if (filePath.endsWith('.json')) { try { var json = JSON.parse(content); return json.version || '0.0.0'; } catch (_a) { return '0.0.0'; } } // Plain text VERSION.txt - just return the content (first line) return content.split('\n')[0].trim(); } function getGitInfo() { try { var commit = execFileSync('git', ['rev-parse', '--short', 'HEAD'], { encoding: 'utf-8', }).trim(); var branch = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { encoding: 'utf-8', }).trim(); return { commit: commit, branch: branch }; } catch (_a) { return { commit: 'unknown', branch: 'unknown' }; } } /** * Extract feature and frontend names from directory structure. * Expected pattern: codebase/features/{FEATURE}/frontend-{FRONTEND}/ * * @example * extractFeatureFrontendNames('/path/to/codebase/features/marketplace/frontend-public') * // Returns: { feature: 'marketplace', frontend: 'public' } */ function extractFeatureFrontendNames(projectRoot) { try { // Normalize path and look for pattern: features/{FEATURE}/frontend-{FRONTEND} var normalized = projectRoot.replace(/\\/g, '/'); var match = normalized.match(/features\/([^/]+)\/frontend-([^/]+)/); if (match) { return { feature: match[1], frontend: match[2], }; } // Fallback: unknown return { feature: 'unknown', frontend: 'unknown' }; } catch (_a) { return { feature: 'unknown', frontend: 'unknown' }; } } /** * Vite plugin that injects version info at build time * * Defines these globals: * - __APP_VERSION__: string - Version from VERSION.txt/VERSION.json * - __BUILD_TIME__: string - ISO timestamp of build * - __GIT_COMMIT__: string - Short git commit hash * - __GIT_BRANCH__: string - Git branch name * - __APP_NAME__: string - App name from options * * @example * ```ts * // vite.config.ts * import { versionPlugin } from '@lilith/vite-version-plugin'; * * export default defineConfig({ * plugins: [ * versionPlugin({ appName: 'my-dashboard' }) * ] * }); * ``` */ export function versionPlugin(options) { var appName = options.appName, versionFile = options.versionFile, _a = options.generateBuildInfo, generateBuildInfo = _a === void 0 ? true : _a, _b = options.fallbackVersion, fallbackVersion = _b === void 0 ? '0.0.0-dev' : _b, featureName = options.featureName, frontendName = options.frontendName; var resolvedConfig; var versionInfo; return { name: 'lilith-version-plugin', // config() runs first - calculate version here using cwd as fallback config: function (userConfig, _a) { var command = _a.command; var projectRoot = userConfig.root || process.cwd(); var versionPath = findVersionFile(projectRoot, versionFile); var version = versionPath ? readVersion(versionPath) : fallbackVersion; var gitInfo = getGitInfo(); var buildTime = new Date().toISOString(); // Extract feature/frontend names from directory structure (with overrides) var extracted = extractFeatureFrontendNames(projectRoot); var finalFeatureName = featureName || extracted.feature; var finalFrontendName = frontendName || extracted.frontend; versionInfo = { version: version, buildTime: buildTime, gitCommit: gitInfo.commit, gitBranch: gitInfo.branch, }; if (command === 'build') { console.log("\n\uD83D\uDCE6 ".concat(appName, " v").concat(version, " (").concat(gitInfo.commit, ")")); if (finalFeatureName !== 'unknown' && finalFrontendName !== 'unknown') { console.log(" Feature: ".concat(finalFeatureName, " / Frontend: ").concat(finalFrontendName)); } } // Return define config to be merged return { define: { __APP_VERSION__: JSON.stringify(version), __BUILD_TIME__: JSON.stringify(buildTime), __GIT_COMMIT__: JSON.stringify(gitInfo.commit), __GIT_BRANCH__: JSON.stringify(gitInfo.branch), __APP_NAME__: JSON.stringify(appName), __FEATURE_NAME__: JSON.stringify(finalFeatureName), __FRONTEND_NAME__: JSON.stringify(finalFrontendName), }, }; }, configResolved: function (config) { resolvedConfig = config; }, writeBundle: function (outputOptions) { if (!generateBuildInfo) return; var outDir = outputOptions.dir || resolvedConfig.build.outDir; var buildInfo = __assign({ app: appName }, versionInfo); var buildInfoPath = join(outDir, 'build-info.json'); writeFileSync(buildInfoPath, JSON.stringify(buildInfo, null, 2)); }, }; } export default versionPlugin;