import path from 'path'; import { transformAsync } from '@babel/core'; import vanillaBabelPlugin from '@vanilla-extract/babel-plugin-debug-ids'; import typescriptSyntax from '@babel/plugin-syntax-typescript'; const CSS_TS_FILTER = /\.css\.(js|cjs|mjs|jsx|ts|tsx)(\?.*)?$/; /** Slug for vanilla-extract class names (letters, digits, _, -). */ function sanitizeIdentifierPart(value) { return String(value) .replace(/\s/g, '_') .replace(/[^a-zA-Z0-9_-]/g, '_') .replace(/_+/g, '_') .replace(/^_+|_+$/g, ''); } function fileScopeSlug(filePath, projectRoot, packageName) { const absolute = path.isAbsolute(filePath) ? filePath : path.join(projectRoot, filePath); const normalized = absolute.replace(/\\/g, '/'); const srcRoot = path.join(projectRoot, 'src').replace(/\\/g, '/'); let rel; if (normalized.startsWith(srcRoot)) { rel = path.relative(path.join(projectRoot, 'src'), absolute); } else if (normalized.includes('/src/')) { rel = normalized.split('/src/').pop(); } else if (packageName) { rel = path.join(packageName, path.basename(absolute)); } else { rel = path.relative(projectRoot, absolute); } return sanitizeIdentifierPart( String(rel) .replace(/\\/g, '/') .replace(/\.css\.(ts|tsx|js|cjs|mjs|jsx)$/i, '') .replace(/\//g, '_') ); } function finalizeIdentifier(parts) { let name = parts.filter(Boolean).join('_'); if (!name) { name = 've_style'; } if (/^[0-9]/.test(name)) { name = `_${name}`; } if (!/^[A-Z_][0-9A-Z_-]+$/i.test(name)) { name = `ve_${name}`; } return name; } /** * Human-readable vanilla-extract class names without hash suffixes. * Example: app_components_updates_dialog_UpdatesDialog_Root */ export function createReadableVanillaExtractIdentifiers(projectRoot) { return function readableVanillaExtractIdentifier({ debugId, filePath, packageName, hash }) { const scope = fileScopeSlug(filePath, projectRoot, packageName); const exportName = debugId ? sanitizeIdentifierPart(debugId) : ''; if (exportName) { return finalizeIdentifier([scope, exportName]); } // Unnamed styles (rare): keep a short disambiguator from the scoped hash. const suffix = sanitizeIdentifierPart(String(hash).replace(/^_/, '')); return finalizeIdentifier([scope, suffix]); }; } /** * Injects export names into style() calls so readable identifiers can use them. * Required when identifiers is a function — vanilla-extract only runs this for identOption === 'debug'. */ export function vanillaExtractDebugIdsPlugin() { return { name: 'vanilla-extract-debug-ids', enforce: 'pre', async transform(code, id) { if (!CSS_TS_FILTER.test(id)) { return null; } const result = await transformAsync(code, { filename: id, plugins: [vanillaBabelPlugin, typescriptSyntax], configFile: false, babelrc: false, }); if (!result?.code) { return null; } return { code: result.code, map: result.map }; }, }; }