Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 8x 1x 1x 1x 7x 2x 2x 2x 5x 5x 1x 4x 1x 3x 1x 2x 1x 1x 1x | /**
* CLI boundary and dispatcher for the CSS build.
*
* runBuild reads the CLI flags and dispatches to the builders:
* - buildStandard.ts: standard CSS, base structure plus themes
* - buildThemeLayer.ts: theme-layer CSS, base plus per-theme plus LBC
*
* Build modes:
* --dev-standard: modular standard CSS for Storybook
* --dev-theme-layer: modular theme-layer CSS for Storybook
* --production: every consumer-facing output to dist/css/
* --watch: incremental rebuilds (see watcher.ts)
*
* runBuild is exported and runs nothing on import; the entry point at the bottom
* runs only when this file is executed as a script, so tests import runBuild
* without side effects.
*
* Usage. See package.json scripts for the canonical invocations:
* tsx scripts/buildCss/index.ts --system=slds2 --dev-standard (dev standard CSS)
* tsx scripts/buildCss/index.ts --system=slds2 --dev-theme-layer (dev theme-layer CSS)
* tsx scripts/buildCss/index.ts --system=slds2 --production (all dist outputs)
* tsx scripts/buildCss/index.ts --system=slds2 --watch (incremental watch)
*/
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { writeReleaseArtifactReceiptIfRequested } from '../../../design-system/scripts/scs/artifact-provenance.js';
import { args } from './args.ts';
import { designTokensDist } from './config.ts';
import { addFiles, buildDevStandard, buildProductionStandard } from './buildStandard.ts';
import { buildThemeLayerBase, buildThemeLayerDist } from './buildThemeLayer.ts';
import { buildThemeData } from './buildThemeData.ts';
import { buildPearl } from './buildPearl.ts';
import { startWatch } from './watcher.ts';
/** Parsed CLI flags. Passed explicitly so callers (and tests) drive the build. */
type Args = typeof args;
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const packageRoot = path.resolve(__dirname, '../..');
const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
// ─── Production build ────────────────────────────────────────────────────────
// Build the production CSS outputs.
//
// Consumer-facing outputs into dist/css/:
// modular/slds2.base.css Structure only
// modular/slds2.scoped.base.css Scoped structure only
// modular/slds2.theme.{theme}.css Theme tokens per theme
// bundled/slds2.{theme}.css Structure and theme, baked
// bundled/slds2.scoped.{theme}.css Scoped structure and theme, baked
//
// Internal pipeline outputs into build/css/. The SCS release consumes these. They are not published:
// theme-layer/modular/slds2.theme-layer.base.css Theme-layer base building block
// theme-layer/modular/slds2[.lbc].theme.{theme}.css Theme-layer per-theme building blocks
// theme-layer/bundled/slds2[.lbc].theme-layer.{theme}.css Theme-layer monolith, baked
const buildProduction = async () => {
await Promise.all([
buildProductionStandard(),
buildPearl({ production: true }),
buildThemeLayerBase({ forDist: true }),
buildThemeLayerBase({ forDist: true, lbc: true }),
buildThemeLayerDist(),
buildThemeLayerDist({ lbc: true }),
]);
await buildThemeData();
writeReleaseArtifactReceiptIfRequested({
packageName: packageJson.name,
packageVersion: packageJson.version,
packageRoot,
trustedRoot: path.resolve(packageRoot, '..'),
receiptPath: path.join(packageRoot, '.scs-slds2-artifact-provenance.json'),
files: [
path.join(packageRoot, 'dist/css/bundled/slds2.cosmos.css'),
path.join(packageRoot, 'dist/css/bundled/slds2.scoped.cosmos.css'),
path.join(packageRoot, 'build/css/theme-layer/bundled/slds2.theme-layer.cosmos.css'),
],
});
// Pearl is released independently (pearl-only mode), so it gets its own receipt.
writeReleaseArtifactReceiptIfRequested({
packageName: packageJson.name,
packageVersion: packageJson.version,
packageRoot,
trustedRoot: path.resolve(packageRoot, '..'),
receiptPath: path.join(packageRoot, '.scs-pearl-artifact-provenance.json'),
files: [path.join(packageRoot, 'build/pearl-theme/modular/slds2.pearl.core.css')],
});
};
// ─── Dev builds ──────────────────────────────────────────────────────────────
// Dev build. Writes modular theme-layer CSS: base plus per-theme, including LBC variants.
const buildDevThemeLayer = async () => {
await Promise.all([buildThemeLayerBase(), buildThemeLayerBase({ lbc: true })]);
await buildThemeData();
};
// ─── Dispatch ────────────────────────────────────────────────────────────────
/**
* Read the CLI flags and run the matching build.
* @param args - Parsed CLI flags that select the build mode.
*/
export const runBuild = async (args: Args) => {
if (!args['--system']) {
console.error('Error: --system is required.');
process.exitCode = 1;
return;
}
// Ensure design-tokens/dist exists to prevent silently emiting CSS without token definitions.
if (!fs.existsSync(designTokensDist)) {
console.error(`Error: ${designTokensDist} not found. Build design-tokens first.`);
process.exitCode = 1;
return;
}
try {
if (args['--production']) {
await buildProduction();
} else if (args['--dev-standard']) {
await buildDevStandard();
} else if (args['--dev-theme-layer']) {
await buildDevThemeLayer();
} else {
await addFiles();
}
} catch (err) {
console.error(err);
process.exitCode = 1;
}
};
// ─── Entry point ─────────────────────────────────────────────────────────────
// The tests load this file to reuse runBuild, and loading it should not start a
// build. Only build when this file is the one being run.
Iif (fileURLToPath(import.meta.url) === process.argv[1]) {
await runBuild(args);
// Skip the watcher if the build failed.
if (args['--watch'] && !process.exitCode) {
startWatch();
}
}
|