stack/packages/template/scripts/process-css.ts
BilalG1 609579abab
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
DB migration compat / Check if migrations changed (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests (Local Emulator) / E2E Tests (Local Emulator, Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Runs E2E Fallback Tests / E2E Fallback Tests (Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Lint & build / lint_and_build (24) (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
DB migration compat / No migration changes (skipped) (push) Has been cancelled
feat(hexclave): PR 3 — native @hexclave/* source rename + delete dual-publish wiring (#1482)
2026-05-29 15:21:59 -07:00

62 lines
2.0 KiB
TypeScript

import { HexclaveAssertionError } from '@hexclave/shared/dist/utils/errors';
import { writeFileSyncIfChanged } from '@hexclave/shared/dist/utils/fs';
import { replaceAll } from '@hexclave/shared/dist/utils/strings';
import autoprefixer from 'autoprefixer';
import * as fs from 'fs';
import * as path from 'path';
import postcss from 'postcss';
import postcssNested from 'postcss-nested';
const scopeSelector = ':where(.stack-scope)';
async function main() {
const args = process.argv.slice(2);
if (args.length !== 2) {
console.error('Please provide exactly three arguments: input file path and output file path');
process.exit(1);
}
const inputPath = path.resolve(args[0]);
const outputPath = path.resolve(args[1]);
let content = fs.readFileSync(inputPath, 'utf8');
// set the scope and sentinel, sentinel is used for same level selectors later
content = `${scopeSelector}, .--stack-sentinel-- {\n${content}\n}`;
// use postcss to nest the scope
content = await postcss([autoprefixer, postcssNested]).process(content, { from: undefined }).css;
// swap the case like .scope img to img.scope
content = content.replace(/(\.--stack-sentinel--\s)([*a-zA-Z0-9\-]+)([^,{\n]*)/g, `$2${scopeSelector}$3`)
// swap the case like .scope [data-foo="bar"] to [data-foo="bar"] .scope
content = content.replace(/(\.--stack-sentinel--\s)(\[.*?\])([^,{\n]*)/g, `$2 ${scopeSelector}$3`)
// replace the remaining sentinels
content = replaceAll(content, '.--stack-sentinel-- ', scopeSelector);
// remove all :root
content = replaceAll(content, ':root', '');
// double check that all sentinels were replaced
if (content.includes('--stack-sentinel--')) {
throw new HexclaveAssertionError('Sentinel not replaced', { content });
}
// output css file for debugging
writeFileSyncIfChanged(outputPath.replace(/\.ts$/, '.css'), content);
content = JSON.stringify(content);
content = `export const globalCSS = ${content};\n`;
writeFileSyncIfChanged(outputPath, content);
}
main().catch(err => {
console.error(err);
process.exit(1);
});