@yahoo/uds 3.123.0 → 3.124.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
- package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
- package/dist/components/client/Toast/UDSToastConfigProvider.d.cts +5 -5
- package/dist/components/client/Toast/UDSToastConfigProvider.d.ts +5 -5
- package/dist/styles/styler.d.cts +34 -34
- package/dist/styles/styler.d.ts +34 -34
- package/dist/tailwind/dist/commands/css.cjs +17 -3
- package/dist/tailwind/dist/commands/css.d.cts.map +1 -1
- package/dist/tailwind/dist/commands/css.d.ts.map +1 -1
- package/dist/tailwind/dist/commands/css.helpers.cjs +2 -1
- package/dist/tailwind/dist/commands/css.helpers.js +2 -1
- package/dist/tailwind/dist/commands/css.helpers.js.map +1 -1
- package/dist/tailwind/dist/commands/css.js +17 -3
- package/dist/tailwind/dist/commands/css.js.map +1 -1
- package/dist/tailwind/dist/css/generate.cjs +3 -0
- package/dist/tailwind/dist/css/generate.helpers.cjs +14 -6
- package/dist/tailwind/dist/css/generate.helpers.js +15 -7
- package/dist/tailwind/dist/css/generate.helpers.js.map +1 -1
- package/dist/tailwind/dist/css/generate.js +3 -0
- package/dist/tailwind/dist/css/generate.js.map +1 -1
- package/dist/tailwind/dist/css/nodeUtils.cjs +91 -20
- package/dist/tailwind/dist/css/nodeUtils.js +90 -21
- package/dist/tailwind/dist/css/nodeUtils.js.map +1 -1
- package/dist/tailwind/dist/css/postcss.cjs +22 -1
- package/dist/tailwind/dist/css/postcss.helpers.cjs +12 -1
- package/dist/tailwind/dist/css/postcss.helpers.js +11 -1
- package/dist/tailwind/dist/css/postcss.helpers.js.map +1 -1
- package/dist/tailwind/dist/css/postcss.js +22 -2
- package/dist/tailwind/dist/css/postcss.js.map +1 -1
- package/dist/tailwind/dist/css/runner.cjs +171 -20
- package/dist/tailwind/dist/css/runner.helpers.cjs +58 -6
- package/dist/tailwind/dist/css/runner.helpers.js +54 -7
- package/dist/tailwind/dist/css/runner.helpers.js.map +1 -1
- package/dist/tailwind/dist/css/runner.js +172 -20
- package/dist/tailwind/dist/css/runner.js.map +1 -1
- package/dist/tailwind/dist/css/theme.d.cts +11 -0
- package/dist/tailwind/dist/css/theme.d.cts.map +1 -1
- package/dist/tailwind/dist/css/theme.d.ts +11 -0
- package/dist/tailwind/dist/css/theme.d.ts.map +1 -1
- package/dist/tailwind/dist/css/theme.js.map +1 -1
- package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +26 -3
- package/dist/tailwind/dist/purger/optimized/ast/expressions.js +26 -3
- package/dist/tailwind/dist/purger/optimized/ast/expressions.js.map +1 -1
- package/dist/tailwind/dist/tailwind/utils/getFontStyles.d.cts +1 -1
- package/dist/tailwind/dist/tailwind/utils/getFontStyles.d.ts +1 -1
- package/dist/tailwind/dist/tailwind/utils/getShadowStyles.d.cts +4 -4
- package/dist/tailwind/dist/tailwind/utils/getShadowStyles.d.ts +4 -4
- package/dist/uds/generated/componentData.cjs +1152 -1152
- package/dist/uds/generated/componentData.js +1152 -1152
- package/generated/componentData.json +1738 -1738
- package/package.json +1 -1
|
@@ -2,13 +2,60 @@
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
4
|
//#region src/css/runner.helpers.ts
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
5
|
+
const getDisplayPath = (cwd, targetPath) => {
|
|
6
|
+
const relativePath = path.relative(cwd, targetPath);
|
|
7
|
+
return relativePath.length === 0 ? "." : relativePath;
|
|
8
|
+
};
|
|
9
|
+
const getVerboseScanFileList = (cwd, filePaths) => [...new Set(filePaths.map((filePath) => getDisplayPath(cwd, filePath)))].sort((left, right) => left.localeCompare(right));
|
|
10
|
+
const getOptimizationDetailLines = (optimizationStats) => {
|
|
11
|
+
const detailLines = [];
|
|
12
|
+
if (optimizationStats.fontFacesRemoved > 0) detailLines.push(` • removed ${optimizationStats.fontFacesRemoved} unused @font-face`);
|
|
13
|
+
if (optimizationStats.emptyRulesRemoved > 0) detailLines.push(` • removed ${optimizationStats.emptyRulesRemoved} empty rules`);
|
|
14
|
+
return detailLines;
|
|
15
|
+
};
|
|
16
|
+
const formatCssDuration = (durationMs) => {
|
|
17
|
+
return `${(Math.floor(durationMs / 100) / 10).toFixed(1)}s`;
|
|
18
|
+
};
|
|
19
|
+
const getCssSummaryMessage = (options) => {
|
|
20
|
+
const { label, optimizationStats, sizeGzipBytes, formatBytes } = options;
|
|
21
|
+
const summaryLine = `${label}: ${formatBytes(sizeGzipBytes)} gzip`;
|
|
22
|
+
if (!optimizationStats) return {
|
|
23
|
+
summaryLine,
|
|
24
|
+
detailLines: []
|
|
25
|
+
};
|
|
8
26
|
const { originalSizeGzip, fontFacesRemoved, emptyRulesRemoved } = optimizationStats;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
27
|
+
if (originalSizeGzip - sizeGzipBytes <= 0) return {
|
|
28
|
+
summaryLine,
|
|
29
|
+
detailLines: []
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
summaryLine,
|
|
33
|
+
detailLines: getOptimizationDetailLines({
|
|
34
|
+
originalSizeGzip,
|
|
35
|
+
fontFacesRemoved,
|
|
36
|
+
emptyRulesRemoved
|
|
37
|
+
})
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
const getMainCssSummaryMessage = (options) => {
|
|
41
|
+
return getCssSummaryMessage({
|
|
42
|
+
label: "Main CSS",
|
|
43
|
+
...options
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const getScopedCssSummaryMessage = (packageName, options) => getCssSummaryMessage({
|
|
47
|
+
label: `${packageName} CSS`,
|
|
48
|
+
...options
|
|
49
|
+
});
|
|
50
|
+
const getOutputFileSection = (cwd, outputPaths) => ({
|
|
51
|
+
label: "Output files:",
|
|
52
|
+
paths: outputPaths.map((outputPath) => getDisplayPath(cwd, outputPath))
|
|
53
|
+
});
|
|
54
|
+
const getScanSummaryMessage = (options) => {
|
|
55
|
+
const nonComponentFileCount = Math.max(options.filesScanned - options.filesWithComponents, 0);
|
|
56
|
+
const fileLabel = nonComponentFileCount === 1 ? "file" : "files";
|
|
57
|
+
const componentLabel = options.componentCount === 1 ? "component" : "components";
|
|
58
|
+
return `${options.label}: ${nonComponentFileCount} ${fileLabel}, ${options.componentCount} ${componentLabel} (${options.mode})`;
|
|
12
59
|
};
|
|
13
60
|
const getWatchDirectoryGroups = (entryDirs, dirs) => {
|
|
14
61
|
const watchDirs = [...new Set(dirs.filter((dir) => !dir.split(path.sep).includes("node_modules")))];
|
|
@@ -19,5 +66,5 @@ const getWatchDirectoryGroups = (entryDirs, dirs) => {
|
|
|
19
66
|
};
|
|
20
67
|
|
|
21
68
|
//#endregion
|
|
22
|
-
export { getMainCssSummaryMessage, getWatchDirectoryGroups };
|
|
69
|
+
export { formatCssDuration, getMainCssSummaryMessage, getOutputFileSection, getScanSummaryMessage, getScopedCssSummaryMessage, getVerboseScanFileList, getWatchDirectoryGroups };
|
|
23
70
|
//# sourceMappingURL=runner.helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.helpers.js","names":[],"sources":["../../src/css/runner.helpers.ts"],"sourcesContent":["import path from 'node:path';\n\ntype OptimizationStats = {\n originalSizeGzip: number;\n fontFacesRemoved: number;\n emptyRulesRemoved: number;\n};\n\ntype MainCssSummaryOptions = {\n sizeGzipBytes: number;\n optimizationStats?: OptimizationStats;\n formatBytes: (bytes: number) => string;\n};\n\nconst
|
|
1
|
+
{"version":3,"file":"runner.helpers.js","names":[],"sources":["../../src/css/runner.helpers.ts"],"sourcesContent":["import path from 'node:path';\n\ntype OptimizationStats = {\n originalSizeGzip: number;\n fontFacesRemoved: number;\n emptyRulesRemoved: number;\n};\n\ntype MainCssSummaryOptions = {\n sizeGzipBytes: number;\n optimizationStats?: OptimizationStats;\n formatBytes: (bytes: number) => string;\n};\n\ntype CssSummaryOptions = MainCssSummaryOptions & {\n label: string;\n};\n\ntype CssSummaryMessage = {\n summaryLine: string;\n detailLines: string[];\n};\n\ntype OutputFileSection = {\n label: string;\n paths: string[];\n};\n\ntype ScanSummaryOptions = {\n label: string;\n filesScanned: number;\n filesWithComponents: number;\n componentCount: number;\n mode: 'app' | 'inherit' | 'scoped';\n};\n\nconst getDisplayPath = (cwd: string, targetPath: string): string => {\n const relativePath = path.relative(cwd, targetPath);\n return relativePath.length === 0 ? '.' : relativePath;\n};\n\nconst getVerboseScanFileList = (cwd: string, filePaths: string[]): string[] =>\n [...new Set(filePaths.map((filePath) => getDisplayPath(cwd, filePath)))].sort((left, right) =>\n left.localeCompare(right),\n );\n\nconst getOptimizationDetailLines = (optimizationStats: OptimizationStats): string[] => {\n const detailLines: string[] = [];\n\n if (optimizationStats.fontFacesRemoved > 0) {\n detailLines.push(` • removed ${optimizationStats.fontFacesRemoved} unused @font-face`);\n }\n\n if (optimizationStats.emptyRulesRemoved > 0) {\n detailLines.push(` • removed ${optimizationStats.emptyRulesRemoved} empty rules`);\n }\n\n return detailLines;\n};\n\nconst formatCssDuration = (durationMs: number): string => {\n const seconds = Math.floor(durationMs / 100) / 10;\n return `${seconds.toFixed(1)}s`;\n};\n\nconst getCssSummaryMessage = (options: CssSummaryOptions): CssSummaryMessage => {\n const { label, optimizationStats, sizeGzipBytes, formatBytes } = options;\n const summaryLine = `${label}: ${formatBytes(sizeGzipBytes)} gzip`;\n\n if (!optimizationStats) {\n return {\n summaryLine,\n detailLines: [],\n };\n }\n\n const { originalSizeGzip, fontFacesRemoved, emptyRulesRemoved } = optimizationStats;\n const savedBytesGzip = originalSizeGzip - sizeGzipBytes;\n\n if (savedBytesGzip <= 0) {\n return {\n summaryLine,\n detailLines: [],\n };\n }\n\n return {\n summaryLine,\n detailLines: getOptimizationDetailLines({\n originalSizeGzip,\n fontFacesRemoved,\n emptyRulesRemoved,\n }),\n };\n};\n\nconst getMainCssSummaryMessage = (options: MainCssSummaryOptions): CssSummaryMessage => {\n return getCssSummaryMessage({\n label: 'Main CSS',\n ...options,\n });\n};\n\nconst getScopedCssSummaryMessage = (\n packageName: string,\n options: MainCssSummaryOptions,\n): CssSummaryMessage =>\n getCssSummaryMessage({\n label: `${packageName} CSS`,\n ...options,\n });\n\nconst getOutputFileSection = (cwd: string, outputPaths: string[]): OutputFileSection => ({\n label: 'Output files:',\n paths: outputPaths.map((outputPath) => getDisplayPath(cwd, outputPath)),\n});\n\nconst getScanSummaryMessage = (options: ScanSummaryOptions): string => {\n const nonComponentFileCount = Math.max(options.filesScanned - options.filesWithComponents, 0);\n const fileLabel = nonComponentFileCount === 1 ? 'file' : 'files';\n const componentLabel = options.componentCount === 1 ? 'component' : 'components';\n return `${options.label}: ${nonComponentFileCount} ${fileLabel}, ${options.componentCount} ${componentLabel} (${options.mode})`;\n};\n\nconst getWatchDirectoryGroups = (entryDirs: string[], dirs: string[]) => {\n const watchDirs = [\n ...new Set(dirs.filter((dir) => !dir.split(path.sep).includes('node_modules'))),\n ];\n const filteredPackageDirs = watchDirs.filter((dir) => !entryDirs.includes(dir));\n\n return {\n watchDirs,\n filteredPackageDirs,\n };\n};\n\nexport {\n formatCssDuration,\n getDisplayPath,\n getMainCssSummaryMessage,\n getOutputFileSection,\n getScanSummaryMessage,\n getScopedCssSummaryMessage,\n getVerboseScanFileList,\n getWatchDirectoryGroups,\n};\n"],"mappings":";;;;AAoCA,MAAM,kBAAkB,KAAa,eAA+B;CAClE,MAAM,eAAe,KAAK,SAAS,KAAK,WAAW;AACnD,QAAO,aAAa,WAAW,IAAI,MAAM;;AAG3C,MAAM,0BAA0B,KAAa,cAC3C,CAAC,GAAG,IAAI,IAAI,UAAU,KAAK,aAAa,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,UACnF,KAAK,cAAc,MAAM,CAC1B;AAEH,MAAM,8BAA8B,sBAAmD;CACrF,MAAM,cAAwB,EAAE;AAEhC,KAAI,kBAAkB,mBAAmB,EACvC,aAAY,KAAK,mBAAmB,kBAAkB,iBAAiB,oBAAoB;AAG7F,KAAI,kBAAkB,oBAAoB,EACxC,aAAY,KAAK,mBAAmB,kBAAkB,kBAAkB,cAAc;AAGxF,QAAO;;AAGT,MAAM,qBAAqB,eAA+B;AAExD,QAAO,IADS,KAAK,MAAM,aAAa,IAAI,GAAG,IAC7B,QAAQ,EAAE,CAAC;;AAG/B,MAAM,wBAAwB,YAAkD;CAC9E,MAAM,EAAE,OAAO,mBAAmB,eAAe,gBAAgB;CACjE,MAAM,cAAc,GAAG,MAAM,IAAI,YAAY,cAAc,CAAC;AAE5D,KAAI,CAAC,kBACH,QAAO;EACL;EACA,aAAa,EAAE;EAChB;CAGH,MAAM,EAAE,kBAAkB,kBAAkB,sBAAsB;AAGlE,KAFuB,mBAAmB,iBAEpB,EACpB,QAAO;EACL;EACA,aAAa,EAAE;EAChB;AAGH,QAAO;EACL;EACA,aAAa,2BAA2B;GACtC;GACA;GACA;GACD,CAAC;EACH;;AAGH,MAAM,4BAA4B,YAAsD;AACtF,QAAO,qBAAqB;EAC1B,OAAO;EACP,GAAG;EACJ,CAAC;;AAGJ,MAAM,8BACJ,aACA,YAEA,qBAAqB;CACnB,OAAO,GAAG,YAAY;CACtB,GAAG;CACJ,CAAC;AAEJ,MAAM,wBAAwB,KAAa,iBAA8C;CACvF,OAAO;CACP,OAAO,YAAY,KAAK,eAAe,eAAe,KAAK,WAAW,CAAC;CACxE;AAED,MAAM,yBAAyB,YAAwC;CACrE,MAAM,wBAAwB,KAAK,IAAI,QAAQ,eAAe,QAAQ,qBAAqB,EAAE;CAC7F,MAAM,YAAY,0BAA0B,IAAI,SAAS;CACzD,MAAM,iBAAiB,QAAQ,mBAAmB,IAAI,cAAc;AACpE,QAAO,GAAG,QAAQ,MAAM,IAAI,sBAAsB,GAAG,UAAU,IAAI,QAAQ,eAAe,GAAG,eAAe,IAAI,QAAQ,KAAK;;AAG/H,MAAM,2BAA2B,WAAqB,SAAmB;CACvE,MAAM,YAAY,CAChB,GAAG,IAAI,IAAI,KAAK,QAAQ,QAAQ,CAAC,IAAI,MAAM,KAAK,IAAI,CAAC,SAAS,eAAe,CAAC,CAAC,CAChF;AAGD,QAAO;EACL;EACA,qBAJ0B,UAAU,QAAQ,QAAQ,CAAC,UAAU,SAAS,IAAI,CAAC;EAK9E"}
|
|
@@ -4,20 +4,62 @@ import { print } from "../cli/dist/lib/print.js";
|
|
|
4
4
|
import { spinStart, spinStop } from "../cli/dist/lib/spinner.js";
|
|
5
5
|
import { createLogger } from "../cli/dist/lib/logger.js";
|
|
6
6
|
import { DEFAULT_ENTRY, resolveEntryPaths } from "../utils/entryPoints.js";
|
|
7
|
-
import { findPackageSourceDir, loadConfigFile, scanDirectoriesForSafelist, scanDirectoryForSafelist } from "./nodeUtils.js";
|
|
7
|
+
import { findPackageRoot, findPackageSourceDir, getPackageUdsScope, loadConfigFile, scanDirectoriesForSafelist, scanDirectoryForSafelist } from "./nodeUtils.js";
|
|
8
8
|
import { defaultTokensConfig } from "../config/dist/index.js";
|
|
9
9
|
import { deduplicateSafelist, getInternalSafelistClasses, getThemeAndScaleClasses } from "../purger/optimized/utils/safelist.js";
|
|
10
|
+
import { formatCssDuration, getMainCssSummaryMessage, getOutputFileSection, getScanSummaryMessage, getScopedCssSummaryMessage, getVerboseScanFileList, getWatchDirectoryGroups } from "./runner.helpers.js";
|
|
10
11
|
import { extractRuntimeConfigValues, extractVariantDefaults, formatBytes, getConfigurableCssVariables, getMotionVarPrefixes } from "./utils.js";
|
|
11
12
|
import { getPruneVarSafelist } from "./generate.helpers.js";
|
|
12
13
|
import { generateCSS, generateSimpleModeCSS } from "./generate.js";
|
|
13
|
-
import { getMainCssSummaryMessage, getWatchDirectoryGroups } from "./runner.helpers.js";
|
|
14
14
|
import fs from "node:fs";
|
|
15
|
-
import path from "node:path";
|
|
16
15
|
|
|
17
16
|
//#region src/css/runner.ts
|
|
17
|
+
const getScopedPackageOutputPath = (packageName, outFile) => {
|
|
18
|
+
if (typeof outFile === "string" && outFile.trim().length > 0) return outFile;
|
|
19
|
+
return `dist/${packageName.split("/").pop() ?? packageName}.css`;
|
|
20
|
+
};
|
|
21
|
+
const normalizeScopedPackageConfig = (scopedPackageValue) => {
|
|
22
|
+
if (typeof scopedPackageValue === "string") return { config: scopedPackageValue };
|
|
23
|
+
return scopedPackageValue;
|
|
24
|
+
};
|
|
25
|
+
const resolveScopedEntryDirs = (packageRoot, packageDir, entry) => {
|
|
26
|
+
if (entry === void 0) return [packageDir];
|
|
27
|
+
return resolveEntryPaths(entry, packageRoot).map((resolvedEntry) => resolvedEntry.absolutePath);
|
|
28
|
+
};
|
|
29
|
+
const PATH_SEPARATOR = "/";
|
|
30
|
+
const normalizePath = (value) => value.replace(/\\/g, PATH_SEPARATOR);
|
|
31
|
+
const isAbsolutePath = (value) => {
|
|
32
|
+
const normalizedValue = normalizePath(value);
|
|
33
|
+
return normalizedValue.startsWith(PATH_SEPARATOR) || /^[A-Za-z]:\//.test(normalizedValue);
|
|
34
|
+
};
|
|
35
|
+
const joinPath = (...parts) => {
|
|
36
|
+
const filteredParts = parts.filter((part) => part.length > 0);
|
|
37
|
+
if (filteredParts.length === 0) return "";
|
|
38
|
+
return filteredParts.map((part, index) => {
|
|
39
|
+
const normalizedPart = normalizePath(part);
|
|
40
|
+
if (index === 0) return normalizedPart.replace(/\/+$/g, "");
|
|
41
|
+
return normalizedPart.replace(/^\/+|\/+$/g, "");
|
|
42
|
+
}).join(PATH_SEPARATOR).replace(/\/+/g, PATH_SEPARATOR).replace(/\/\.\//g, PATH_SEPARATOR);
|
|
43
|
+
};
|
|
44
|
+
const dirnamePath = (value) => {
|
|
45
|
+
const normalizedValue = normalizePath(value).replace(/\/+$/g, "");
|
|
46
|
+
const lastSeparatorIndex = normalizedValue.lastIndexOf(PATH_SEPARATOR);
|
|
47
|
+
if (lastSeparatorIndex <= 0) return lastSeparatorIndex === 0 ? PATH_SEPARATOR : ".";
|
|
48
|
+
return normalizedValue.slice(0, lastSeparatorIndex);
|
|
49
|
+
};
|
|
50
|
+
const basenamePath = (value) => {
|
|
51
|
+
const normalizedValue = normalizePath(value).replace(/\/+$/g, "");
|
|
52
|
+
const lastSeparatorIndex = normalizedValue.lastIndexOf(PATH_SEPARATOR);
|
|
53
|
+
return lastSeparatorIndex >= 0 ? normalizedValue.slice(lastSeparatorIndex + 1) : normalizedValue;
|
|
54
|
+
};
|
|
55
|
+
const resolveOutputPath = (workspaceDir, outFile) => isAbsolutePath(outFile) ? outFile : joinPath(workspaceDir, outFile);
|
|
56
|
+
const ensureOutputDirectory = (outputPath) => {
|
|
57
|
+
const outputDir = dirnamePath(outputPath);
|
|
58
|
+
if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
|
|
59
|
+
};
|
|
18
60
|
const SOURCE_FILE_PATTERN = /\.(jsx?|tsx?)$/i;
|
|
19
|
-
const getWatchDirs = (dirs) => [...new Set(dirs.filter((dir) => !dir.split(
|
|
20
|
-
const isCoveredByRecursiveWatch = (watchPath, targetPath) => targetPath === watchPath || targetPath.startsWith(`${watchPath}${
|
|
61
|
+
const getWatchDirs = (dirs) => [...new Set(dirs.filter((dir) => !normalizePath(dir).split(PATH_SEPARATOR).includes("node_modules")))];
|
|
62
|
+
const isCoveredByRecursiveWatch = (watchPath, targetPath) => targetPath === watchPath || targetPath.startsWith(`${watchPath}${PATH_SEPARATOR}`);
|
|
21
63
|
const getEntryWatchTargets = (entries) => {
|
|
22
64
|
const directoryTargets = getWatchDirs(entries.filter((entry) => entry.kind === "directory").map((entry) => entry.absolutePath)).map((watchPath) => ({
|
|
23
65
|
watchPath,
|
|
@@ -41,7 +83,7 @@ const watchSourceFiles = (targets, onFileChange) => {
|
|
|
41
83
|
targets.forEach((target) => {
|
|
42
84
|
fs.watch(target.watchPath, { recursive: target.recursive }, (_eventType, filename) => {
|
|
43
85
|
if (!filename || !SOURCE_FILE_PATTERN.test(filename)) return;
|
|
44
|
-
if (target.fileNames && !target.fileNames.includes(
|
|
86
|
+
if (target.fileNames && !target.fileNames.includes(basenamePath(String(filename)))) return;
|
|
45
87
|
onFileChange();
|
|
46
88
|
});
|
|
47
89
|
});
|
|
@@ -79,8 +121,13 @@ const createQueuedRegenerator = (options) => {
|
|
|
79
121
|
};
|
|
80
122
|
return regenerate;
|
|
81
123
|
};
|
|
124
|
+
const printVerboseScanFiles = (log, workspaceDir, filePaths) => {
|
|
125
|
+
getVerboseScanFileList(workspaceDir, filePaths).forEach((filePath) => {
|
|
126
|
+
log.listItem(filePath);
|
|
127
|
+
});
|
|
128
|
+
};
|
|
82
129
|
const runCssCommand = async (options, context) => {
|
|
83
|
-
if (!fs.existsSync(
|
|
130
|
+
if (!fs.existsSync(joinPath(options.workspaceDir, String(options.themeConfigPath)))) {
|
|
84
131
|
await runSimpleMode(options, context);
|
|
85
132
|
return;
|
|
86
133
|
}
|
|
@@ -101,7 +148,8 @@ const runSimpleMode = async (options, context) => {
|
|
|
101
148
|
scope: options.scope,
|
|
102
149
|
configPath,
|
|
103
150
|
isWatch: options.watch,
|
|
104
|
-
silent: options.silent
|
|
151
|
+
silent: options.silent,
|
|
152
|
+
verbose: options.verbose
|
|
105
153
|
});
|
|
106
154
|
if (options.watch) await runSimpleModeWatch(options, context, entry, configPath, result.packageDirs ?? []);
|
|
107
155
|
} catch (error) {
|
|
@@ -181,7 +229,7 @@ const loadThemeModeSetup = async (options) => {
|
|
|
181
229
|
};
|
|
182
230
|
const runThemeMode = async (options, context) => {
|
|
183
231
|
const workspaceDir = options.workspaceDir;
|
|
184
|
-
const outputPath =
|
|
232
|
+
const outputPath = resolveOutputPath(workspaceDir, String(options.outFile));
|
|
185
233
|
let effectiveSilent = options.silent;
|
|
186
234
|
let log = createLogger({ silent: effectiveSilent });
|
|
187
235
|
log.spinStart("Loading theme configuration...");
|
|
@@ -202,12 +250,21 @@ const runThemeMode = async (options, context) => {
|
|
|
202
250
|
const generateThemeModeCSS = async (opts) => {
|
|
203
251
|
const genStartTime = performance.now();
|
|
204
252
|
const genLog = opts?.isWatch ? createLogger({ silent: true }) : log;
|
|
253
|
+
const scopedCssOutputs = [];
|
|
205
254
|
genLog.spinStart("Scanning app code...");
|
|
206
255
|
const appScanResult = await scanDirectoriesForSafelist(entryDirs, colorModes, context.variants, context.autoVariants, context.componentData, appVariantDefaults, runtimeConfigValues);
|
|
207
|
-
genLog.spinStop("✅",
|
|
256
|
+
genLog.spinStop("✅", getScanSummaryMessage({
|
|
257
|
+
label: "app",
|
|
258
|
+
filesScanned: appScanResult.filesScanned,
|
|
259
|
+
filesWithComponents: appScanResult.filesWithComponents,
|
|
260
|
+
componentCount: appScanResult.components.length,
|
|
261
|
+
mode: "app"
|
|
262
|
+
}));
|
|
263
|
+
if (options.verbose) printVerboseScanFiles(genLog, workspaceDir, appScanResult.filePaths);
|
|
208
264
|
genLog.spinStart("Generating main CSS...");
|
|
209
265
|
const inheritedClasses = [...appScanResult.safelist];
|
|
210
266
|
const inheritedComponents = new Set(appScanResult.components);
|
|
267
|
+
const scopedPackageTargets = [];
|
|
211
268
|
const processInheritedPackage = async (packageName) => {
|
|
212
269
|
genLog.spinStart(`Processing package: ${packageName}...`);
|
|
213
270
|
const packageDir = findPackageSourceDir(packageName);
|
|
@@ -219,12 +276,50 @@ const runThemeMode = async (options, context) => {
|
|
|
219
276
|
const packageScanResult = await scanDirectoryForSafelist(packageDir, colorModes, context.variants, context.autoVariants, context.componentData, appVariantDefaults, runtimeConfigValues, true);
|
|
220
277
|
inheritedClasses.push(...packageScanResult.safelist);
|
|
221
278
|
packageScanResult.components.forEach((comp) => inheritedComponents.add(comp));
|
|
222
|
-
genLog.spinStop("✅",
|
|
279
|
+
genLog.spinStop("✅", getScanSummaryMessage({
|
|
280
|
+
label: packageName,
|
|
281
|
+
filesScanned: packageScanResult.filesScanned,
|
|
282
|
+
filesWithComponents: packageScanResult.filesWithComponents,
|
|
283
|
+
componentCount: packageScanResult.components.length,
|
|
284
|
+
mode: "inherit"
|
|
285
|
+
}));
|
|
286
|
+
if (options.verbose) printVerboseScanFiles(genLog, workspaceDir, packageScanResult.filePaths);
|
|
287
|
+
};
|
|
288
|
+
const processScopedPackage = async (packageName, scopedPackageValue) => {
|
|
289
|
+
genLog.spinStart(`Processing scoped package: ${packageName}...`);
|
|
290
|
+
const scopedPackageConfig = normalizeScopedPackageConfig(scopedPackageValue);
|
|
291
|
+
const packageRoot = findPackageRoot(packageName);
|
|
292
|
+
const packageDir = findPackageSourceDir(packageName);
|
|
293
|
+
if (!packageRoot || !packageDir) {
|
|
294
|
+
genLog.spinStop("⚠️", `Scoped package not found: ${packageName}`);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const scopeClass = getPackageUdsScope(packageName);
|
|
298
|
+
if (!scopeClass) {
|
|
299
|
+
genLog.spinStop("⚠️", `Scoped package missing package.json uds.scope: ${packageName}`);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
const entryDirs = resolveScopedEntryDirs(packageRoot, packageDir, scopedPackageConfig.entry);
|
|
303
|
+
entryDirs.forEach((entryDir) => {
|
|
304
|
+
if (!packageDirs.includes(entryDir)) packageDirs.push(entryDir);
|
|
305
|
+
});
|
|
306
|
+
scopedPackageTargets.push({
|
|
307
|
+
packageName,
|
|
308
|
+
packageRoot,
|
|
309
|
+
packageDir,
|
|
310
|
+
entryDirs,
|
|
311
|
+
scopeClass,
|
|
312
|
+
config: scopedPackageConfig
|
|
313
|
+
});
|
|
223
314
|
};
|
|
224
315
|
await (themeConfig.inherit ?? []).reduce(async (promise, packageName) => {
|
|
225
316
|
await promise;
|
|
226
317
|
await processInheritedPackage(packageName);
|
|
227
318
|
}, Promise.resolve());
|
|
319
|
+
await Object.entries(themeConfig.scoped ?? {}).reduce(async (promise, [packageName, scopedPackageConfig]) => {
|
|
320
|
+
await promise;
|
|
321
|
+
await processScopedPackage(packageName, scopedPackageConfig);
|
|
322
|
+
}, Promise.resolve());
|
|
228
323
|
const mainSafelist = deduplicateSafelist([
|
|
229
324
|
...inheritedClasses,
|
|
230
325
|
...getThemeAndScaleClasses(colorModes),
|
|
@@ -241,24 +336,80 @@ const runThemeMode = async (options, context) => {
|
|
|
241
336
|
...getPruneVarSafelist(themeConfig.css)
|
|
242
337
|
]
|
|
243
338
|
});
|
|
244
|
-
|
|
245
|
-
if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
|
|
339
|
+
ensureOutputDirectory(outputPath);
|
|
246
340
|
fs.writeFileSync(outputPath, mainCssResult.css);
|
|
247
|
-
|
|
341
|
+
for (const scopedPackageTarget of scopedPackageTargets) {
|
|
342
|
+
const packageConfig = await loadConfigFile(isAbsolutePath(scopedPackageTarget.config.config) ? scopedPackageTarget.config.config : joinPath(scopedPackageTarget.packageRoot, scopedPackageTarget.config.config)) ?? defaultTokensConfig;
|
|
343
|
+
const packageVariantDefaults = extractVariantDefaults(packageConfig);
|
|
344
|
+
const packageRuntimeConfigValues = extractRuntimeConfigValues(packageConfig);
|
|
345
|
+
const packageScanResult = await scanDirectoriesForSafelist(scopedPackageTarget.entryDirs, colorModes, context.variants, context.autoVariants, context.componentData, packageVariantDefaults, packageRuntimeConfigValues, true);
|
|
346
|
+
genLog.spinStop("✅", getScanSummaryMessage({
|
|
347
|
+
label: scopedPackageTarget.packageName,
|
|
348
|
+
filesScanned: packageScanResult.filesScanned,
|
|
349
|
+
filesWithComponents: packageScanResult.filesWithComponents,
|
|
350
|
+
componentCount: packageScanResult.components.length,
|
|
351
|
+
mode: "scoped"
|
|
352
|
+
}));
|
|
353
|
+
if (options.verbose) printVerboseScanFiles(genLog, workspaceDir, packageScanResult.filePaths);
|
|
354
|
+
const packageSafelist = deduplicateSafelist([
|
|
355
|
+
...packageScanResult.safelist,
|
|
356
|
+
...getThemeAndScaleClasses(colorModes),
|
|
357
|
+
...getInternalSafelistClasses()
|
|
358
|
+
]);
|
|
359
|
+
const scopedCssResult = await generateCSS([...themeConfig.css?.safelist ?? [], ...packageSafelist], packageConfig, {
|
|
360
|
+
scope: scopedPackageTarget.scopeClass,
|
|
361
|
+
contentDir: scopedPackageTarget.entryDirs,
|
|
362
|
+
cssOptions: themeConfig.css,
|
|
363
|
+
referenceCss: themeConfig.css?.optimization?.deduplicateScopedCss === false ? void 0 : mainCssResult.css,
|
|
364
|
+
safeVarPrefixes: [
|
|
365
|
+
...getMotionVarPrefixes(context.componentData, [...packageScanResult.components]),
|
|
366
|
+
...getConfigurableCssVariables(),
|
|
367
|
+
...getPruneVarSafelist(themeConfig.css)
|
|
368
|
+
]
|
|
369
|
+
});
|
|
370
|
+
const scopedOutputPath = resolveOutputPath(workspaceDir, getScopedPackageOutputPath(scopedPackageTarget.packageName, scopedPackageTarget.config.outFile));
|
|
371
|
+
ensureOutputDirectory(scopedOutputPath);
|
|
372
|
+
fs.writeFileSync(scopedOutputPath, scopedCssResult.css);
|
|
373
|
+
scopedCssOutputs.push({
|
|
374
|
+
label: scopedPackageTarget.packageName,
|
|
375
|
+
outputPath: scopedOutputPath,
|
|
376
|
+
sizeGzipBytes: scopedCssResult.sizeGzipBytes,
|
|
377
|
+
optimizationStats: scopedCssResult.optimizationStats
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
const mainCssSummary = getMainCssSummaryMessage({
|
|
248
381
|
sizeGzipBytes: mainCssResult.sizeGzipBytes,
|
|
249
382
|
optimizationStats: mainCssResult.optimizationStats,
|
|
250
383
|
formatBytes
|
|
251
|
-
})
|
|
384
|
+
});
|
|
385
|
+
genLog.spinStop("✅", mainCssSummary.summaryLine);
|
|
386
|
+
mainCssSummary.detailLines.forEach((detailLine) => {
|
|
387
|
+
genLog.print(detailLine);
|
|
388
|
+
});
|
|
389
|
+
scopedCssOutputs.forEach((scopedCssOutput) => {
|
|
390
|
+
const scopedCssSummary = getScopedCssSummaryMessage(scopedCssOutput.label, {
|
|
391
|
+
sizeGzipBytes: scopedCssOutput.sizeGzipBytes,
|
|
392
|
+
optimizationStats: scopedCssOutput.optimizationStats,
|
|
393
|
+
formatBytes
|
|
394
|
+
});
|
|
395
|
+
genLog.spinStop("✅", scopedCssSummary.summaryLine);
|
|
396
|
+
scopedCssSummary.detailLines.forEach((detailLine) => {
|
|
397
|
+
genLog.print(detailLine);
|
|
398
|
+
});
|
|
399
|
+
});
|
|
252
400
|
const duration = Math.round(performance.now() - genStartTime);
|
|
401
|
+
const outputFileSection = getOutputFileSection(workspaceDir, [outputPath, ...scopedCssOutputs.map((scopedCssOutput) => scopedCssOutput.outputPath)]);
|
|
253
402
|
genLog.newline();
|
|
254
|
-
genLog.print(
|
|
255
|
-
|
|
256
|
-
|
|
403
|
+
genLog.print(outputFileSection.label);
|
|
404
|
+
outputFileSection.paths.forEach((filePath) => {
|
|
405
|
+
genLog.listItem(filePath);
|
|
406
|
+
});
|
|
257
407
|
genLog.newline();
|
|
258
|
-
genLog.print(`${magenta("Total time:")} ${duration}
|
|
408
|
+
genLog.print(`${magenta("Total time:")} ${formatCssDuration(duration)}`);
|
|
259
409
|
return {
|
|
260
410
|
duration,
|
|
261
411
|
outputPath,
|
|
412
|
+
outputPaths: outputFileSection.paths,
|
|
262
413
|
packageDirs
|
|
263
414
|
};
|
|
264
415
|
};
|
|
@@ -289,7 +440,8 @@ const runThemeMode = async (options, context) => {
|
|
|
289
440
|
onSuccess: (result) => {
|
|
290
441
|
if (!effectiveSilent) {
|
|
291
442
|
const updatedAt = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
292
|
-
|
|
443
|
+
const updatedMessage = result?.duration == null ? "CSS updated" : `CSS updated (${formatCssDuration(result.duration)})`;
|
|
444
|
+
log.print(`${gray(`[${updatedAt}]`)} ${green(updatedMessage)}`);
|
|
293
445
|
log.newline();
|
|
294
446
|
}
|
|
295
447
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","names":[],"sources":["../../src/css/runner.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { createLogger, gray, green, magenta, print, spinStart, spinStop } from '@yahoo/uds-cli/lib';\nimport type { UniversalTokensConfig } from '@yahoo/uds-config';\nimport { defaultTokensConfig } from '@yahoo/uds-config';\n\nimport type { SerializedComponentInfo } from '../commands/generateComponentData';\nimport {\n deduplicateSafelist,\n getInternalSafelistClasses,\n getThemeAndScaleClasses,\n} from '../purger/optimized/utils/safelist';\nimport type { EntryValue, ResolvedEntryPath } from '../utils/entryPoints';\nimport { DEFAULT_ENTRY, resolveEntryPaths } from '../utils/entryPoints';\nimport { generateCSS, generateSimpleModeCSS } from './generate';\nimport { getPruneVarSafelist } from './generate.helpers';\nimport {\n findPackageSourceDir,\n loadConfigFile,\n scanDirectoriesForSafelist,\n scanDirectoryForSafelist,\n} from './nodeUtils';\nimport { getMainCssSummaryMessage, getWatchDirectoryGroups } from './runner.helpers';\nimport type { UDSThemeConfig, UDSThemeConfigInput, UDSThemeContext } from './theme';\nimport {\n extractRuntimeConfigValues,\n extractVariantDefaults,\n formatBytes,\n getConfigurableCssVariables,\n getMotionVarPrefixes,\n} from './utils';\n\ntype CssCommandContext = {\n variants: Record<string, Record<string, string>>;\n autoVariants: Record<string, Record<string, string>>;\n componentData: Record<string, SerializedComponentInfo>;\n};\n\ntype CssCommandOptions = {\n workspaceDir: string;\n outFile: string;\n themeConfigPath: string;\n scope?: string;\n entryOption?: EntryValue;\n configOption?: string;\n watch: boolean;\n silent: boolean;\n};\n\ntype ThemeModeSetup = {\n themeConfig: UDSThemeConfig;\n colorModes: ('dark' | 'light')[];\n entries: ResolvedEntryPath[];\n appConfig: UniversalTokensConfig;\n appVariantDefaults: ReturnType<typeof extractVariantDefaults>;\n runtimeConfigValues: ReturnType<typeof extractRuntimeConfigValues>;\n effectiveSilent: boolean;\n};\n\nconst SOURCE_FILE_PATTERN = /\\.(jsx?|tsx?)$/i;\n\ntype WatchTarget = {\n watchPath: string;\n recursive: boolean;\n fileNames?: string[];\n};\n\nconst getWatchDirs = (dirs: string[]): string[] => [\n ...new Set(dirs.filter((dir) => !dir.split(path.sep).includes('node_modules'))),\n];\n\nconst isCoveredByRecursiveWatch = (watchPath: string, targetPath: string): boolean =>\n targetPath === watchPath || targetPath.startsWith(`${watchPath}${path.sep}`);\n\nconst getEntryWatchTargets = (entries: ResolvedEntryPath[]): WatchTarget[] => {\n const directoryTargets = getWatchDirs(\n entries.filter((entry) => entry.kind === 'directory').map((entry) => entry.absolutePath),\n ).map((watchPath) => ({ watchPath, recursive: true }));\n\n const fileNamesByDirectory = new Map<string, Set<string>>();\n\n entries\n .filter(\n (entry): entry is ResolvedEntryPath & { kind: 'file'; fileName: string } =>\n entry.kind === 'file' && typeof entry.fileName === 'string',\n )\n .forEach((entry) => {\n if (\n directoryTargets.some((target) =>\n isCoveredByRecursiveWatch(target.watchPath, entry.absolutePath),\n )\n ) {\n return;\n }\n\n const fileNames = fileNamesByDirectory.get(entry.watchDirectory) ?? new Set<string>();\n fileNames.add(entry.fileName);\n fileNamesByDirectory.set(entry.watchDirectory, fileNames);\n });\n\n const fileTargets = [...fileNamesByDirectory.entries()].map(([watchPath, fileNames]) => ({\n watchPath,\n recursive: false,\n fileNames: [...fileNames],\n }));\n\n return [...directoryTargets, ...fileTargets];\n};\n\nconst watchSourceFiles = (targets: WatchTarget[], onFileChange: () => void): void => {\n targets.forEach((target) => {\n fs.watch(target.watchPath, { recursive: target.recursive }, (_eventType, filename) => {\n if (!filename || !SOURCE_FILE_PATTERN.test(filename)) {\n return;\n }\n\n if (target.fileNames && !target.fileNames.includes(path.basename(String(filename)))) {\n return;\n }\n\n onFileChange();\n });\n });\n};\n\nconst createDebouncedAction = (action: () => void, delayMs: number): (() => void) => {\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n return () => {\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(action, delayMs);\n };\n};\n\nconst createQueuedRegenerator = <T>(options: {\n onStart?: () => void;\n onSuccess?: (result: T) => void;\n onError: (message: string) => void;\n regenerateOnce: () => Promise<T>;\n}): (() => Promise<void>) => {\n let isGenerating = false;\n let pendingRegenerate = false;\n\n const regenerate = async (): Promise<void> => {\n if (isGenerating) {\n pendingRegenerate = true;\n return;\n }\n\n isGenerating = true;\n try {\n options.onStart?.();\n const result = await options.regenerateOnce();\n options.onSuccess?.(result);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'CSS generation failed';\n options.onError(message);\n } finally {\n isGenerating = false;\n\n if (pendingRegenerate) {\n pendingRegenerate = false;\n await regenerate();\n }\n }\n };\n\n return regenerate;\n};\n\nconst runCssCommand = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const themeConfigExists = fs.existsSync(\n path.join(options.workspaceDir, String(options.themeConfigPath)),\n );\n\n if (!themeConfigExists) {\n await runSimpleMode(options, context);\n return;\n }\n\n await runThemeMode(options, context);\n};\n\nconst runSimpleMode = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const entry = options.entryOption ?? DEFAULT_ENTRY;\n const configPath = typeof options.configOption === 'string' ? options.configOption : undefined;\n\n if (!options.watch && !options.silent) {\n spinStart('Generating CSS...');\n }\n\n try {\n const result = await generateSimpleModeCSS({\n workspaceDir: options.workspaceDir,\n entry,\n outFile: String(options.outFile),\n variants: context.variants,\n autoVariants: context.autoVariants,\n componentData: context.componentData,\n scope: options.scope,\n configPath,\n isWatch: options.watch,\n silent: options.silent,\n });\n\n if (options.watch) {\n await runSimpleModeWatch(options, context, entry, configPath, result.packageDirs ?? []);\n }\n } catch (error) {\n spinStop('❌', error instanceof Error ? error.message : 'CSS generation failed');\n process.exitCode = 1;\n }\n};\n\nconst runSimpleModeWatch = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n entry: EntryValue,\n configPath: string | undefined,\n packageDirs: string[],\n): Promise<void> => {\n const resolvedEntries = resolveEntryPaths(entry, options.workspaceDir);\n const entryWatchTargets = getEntryWatchTargets(resolvedEntries);\n const fallbackTargets = getWatchDirs(packageDirs).map((watchPath) => ({\n watchPath,\n recursive: true,\n }));\n const watchTargets = packageDirs.length > 0 ? fallbackTargets : entryWatchTargets;\n\n if (!options.silent) {\n print('');\n print(`${magenta('Watching for changes...')}`);\n watchTargets.forEach((target) => print(` ${gray('•')} ${target.watchPath}`));\n print(`${gray('Press Ctrl+C to stop')}`);\n print('');\n }\n\n const regenerate = createQueuedRegenerator({\n onStart: () => {\n if (!options.silent) {\n const timestamp = new Date().toLocaleTimeString();\n print(`${gray(`[${timestamp}]`)} Change detected, regenerating...`);\n }\n },\n regenerateOnce: async () => {\n await generateSimpleModeCSS({\n workspaceDir: options.workspaceDir,\n entry,\n outFile: String(options.outFile),\n variants: context.variants,\n autoVariants: context.autoVariants,\n componentData: context.componentData,\n scope: options.scope,\n configPath,\n isWatch: true,\n silent: true,\n });\n },\n onSuccess: () => {\n if (!options.silent) {\n const updatedAt = new Date().toLocaleTimeString();\n print(`${gray(`[${updatedAt}]`)} ${green('CSS updated')}`);\n print('');\n }\n },\n onError: (message) => {\n print(`Error: ${message}`);\n },\n });\n\n watchSourceFiles(\n watchTargets,\n createDebouncedAction(() => {\n void regenerate();\n }, 100),\n );\n\n await new Promise(() => {});\n};\n\nconst loadThemeModeSetup = async (options: CssCommandOptions): Promise<ThemeModeSetup | null> => {\n const themeConfigInput = await loadConfigFile<UDSThemeConfigInput>(\n String(options.themeConfigPath),\n );\n if (!themeConfigInput) {\n return null;\n }\n\n const themeContext: UDSThemeContext = {\n cwd: options.workspaceDir,\n watch: options.watch,\n };\n const themeConfig: UDSThemeConfig =\n typeof themeConfigInput === 'function'\n ? await themeConfigInput(themeContext)\n : themeConfigInput;\n\n let appConfig: UniversalTokensConfig = defaultTokensConfig;\n if (themeConfig.config) {\n const loadedConfig = await loadConfigFile<UniversalTokensConfig>(themeConfig.config);\n if (loadedConfig) {\n appConfig = loadedConfig;\n }\n }\n\n return {\n themeConfig,\n colorModes: themeConfig.colorModes ?? ['dark'],\n entries: resolveEntryPaths(themeConfig.entry, options.workspaceDir),\n appConfig,\n appVariantDefaults: extractVariantDefaults(appConfig),\n runtimeConfigValues: extractRuntimeConfigValues(appConfig),\n effectiveSilent: options.silent || themeConfig.silent === true,\n };\n};\n\nconst runThemeMode = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const workspaceDir = options.workspaceDir;\n const outputPath = path.isAbsolute(options.outFile)\n ? options.outFile\n : path.join(workspaceDir, String(options.outFile));\n let effectiveSilent = options.silent;\n let log = createLogger({ silent: effectiveSilent });\n\n log.spinStart('Loading theme configuration...');\n\n try {\n const setup = await loadThemeModeSetup(options);\n if (!setup) {\n log.spinStop('❌', `Theme config not found: ${options.themeConfigPath}`);\n process.exitCode = 1;\n return;\n }\n\n const { themeConfig, colorModes, entries, appConfig, appVariantDefaults, runtimeConfigValues } =\n setup;\n effectiveSilent = setup.effectiveSilent;\n log = createLogger({ silent: effectiveSilent });\n const entryDirs = entries.map((entry) => entry.absolutePath);\n\n if (!effectiveSilent) {\n log.spinStop('✅', 'Theme configuration loaded');\n }\n\n if (themeConfig.config && appConfig === defaultTokensConfig) {\n log.warn(`App config not found: ${themeConfig.config}, using defaults`);\n }\n const packageDirs: string[] = [];\n\n const generateThemeModeCSS = async (opts?: { isWatch?: boolean }) => {\n const genStartTime = performance.now();\n const genLog = opts?.isWatch ? createLogger({ silent: true }) : log;\n\n genLog.spinStart('Scanning app code...');\n const appScanResult = await scanDirectoriesForSafelist(\n entryDirs,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n appVariantDefaults,\n runtimeConfigValues,\n );\n genLog.spinStop('✅', `Scanned ${appScanResult.filesScanned} files`);\n\n genLog.spinStart('Generating main CSS...');\n\n const inheritedClasses: string[] = [...appScanResult.safelist];\n const inheritedComponents = new Set<string>(appScanResult.components);\n\n const processInheritedPackage = async (packageName: string) => {\n genLog.spinStart(`Processing package: ${packageName}...`);\n\n const packageDir = findPackageSourceDir(packageName);\n if (!packageDir) {\n genLog.spinStop('⚠️', `Package not found: ${packageName}`);\n return;\n }\n\n if (!packageDirs.includes(packageDir)) {\n packageDirs.push(packageDir);\n }\n\n const packageScanResult = await scanDirectoryForSafelist(\n packageDir,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n appVariantDefaults,\n runtimeConfigValues,\n true,\n );\n inheritedClasses.push(...packageScanResult.safelist);\n packageScanResult.components.forEach((comp) => inheritedComponents.add(comp));\n genLog.spinStop('✅', `${packageName}: ${packageScanResult.filesScanned} files (inherit)`);\n };\n\n await (themeConfig.inherit ?? []).reduce(async (promise, packageName) => {\n await promise;\n await processInheritedPackage(packageName);\n }, Promise.resolve());\n\n const mainSafelist = deduplicateSafelist([\n ...inheritedClasses,\n ...getThemeAndScaleClasses(colorModes),\n ...getInternalSafelistClasses(),\n ]);\n\n const allMotionComponents: string[] = [...inheritedComponents];\n\n const mainCssResult = await generateCSS(\n [...(themeConfig.css?.safelist ?? []), ...mainSafelist],\n appConfig,\n {\n scope: options.scope,\n contentDir: entryDirs,\n cssOptions: themeConfig.css,\n safeVarPrefixes: [\n ...getMotionVarPrefixes(context.componentData, allMotionComponents),\n ...getConfigurableCssVariables(),\n ...getPruneVarSafelist(themeConfig.css),\n ],\n },\n );\n\n const outputDir = path.dirname(outputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n fs.writeFileSync(outputPath, mainCssResult.css);\n\n genLog.spinStop(\n '✅',\n getMainCssSummaryMessage({\n sizeGzipBytes: mainCssResult.sizeGzipBytes,\n optimizationStats: mainCssResult.optimizationStats,\n formatBytes,\n }),\n );\n\n const duration = Math.round(performance.now() - genStartTime);\n\n genLog.newline();\n genLog.print(green('CSS generation complete!'));\n genLog.newline();\n genLog.label('Output file:', outputPath);\n genLog.newline();\n genLog.print(`${magenta('Total time:')} ${duration}ms`);\n\n return { duration, outputPath, packageDirs };\n };\n\n await generateThemeModeCSS();\n\n if (options.watch) {\n const entryWatchTargets = getEntryWatchTargets(entries);\n const entryWatchDirs = getWatchDirs(entryWatchTargets.map((target) => target.watchPath));\n const { filteredPackageDirs } = getWatchDirectoryGroups(entryWatchDirs, [\n ...entryDirs,\n ...packageDirs,\n ]);\n\n if (!effectiveSilent) {\n log.newline();\n log.print(`${magenta('Watching for changes...')}`);\n entryDirs.forEach((entryDir) => {\n log.listItem(`App: ${entryDir}`);\n });\n filteredPackageDirs.forEach((dir) => {\n log.listItem(`Package: ${dir}`);\n });\n log.print(`${gray('Press Ctrl+C to stop')}`);\n log.newline();\n }\n\n const regenerate = createQueuedRegenerator({\n onStart: () => {\n if (!effectiveSilent) {\n const timestamp = new Date().toLocaleTimeString();\n log.print(`${gray(`[${timestamp}]`)} Change detected, regenerating...`);\n }\n },\n regenerateOnce: async () => generateThemeModeCSS({ isWatch: true }),\n onSuccess: (result) => {\n if (!effectiveSilent) {\n const updatedAt = new Date().toLocaleTimeString();\n log.print(`${gray(`[${updatedAt}]`)} ${green(`CSS updated (${result?.duration}ms)`)}`);\n log.newline();\n }\n },\n onError: (message) => {\n log.print(message);\n },\n });\n\n const watchDebounce = themeConfig.css?.watchDebounce ?? 100;\n\n watchSourceFiles(\n [\n ...entryWatchTargets,\n ...filteredPackageDirs\n .filter(\n (packageDir) =>\n !entryWatchTargets.some((target) =>\n isCoveredByRecursiveWatch(target.watchPath, packageDir),\n ),\n )\n .map((watchPath) => ({ watchPath, recursive: true })),\n ],\n createDebouncedAction(() => {\n void regenerate();\n }, watchDebounce),\n );\n\n await new Promise(() => {});\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'CSS generation failed';\n if (effectiveSilent) {\n spinStop('❌', message);\n } else {\n log.spinStop('❌', message);\n }\n process.exitCode = 1;\n }\n};\n\nexport { runCssCommand };\nexport type { CssCommandContext, CssCommandOptions };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runner.js","names":[],"sources":["../../src/css/runner.ts"],"sourcesContent":["import fs from 'node:fs';\n\nimport { createLogger, gray, green, magenta, print, spinStart, spinStop } from '@yahoo/uds-cli/lib';\nimport type { UniversalTokensConfig } from '@yahoo/uds-config';\nimport { defaultTokensConfig } from '@yahoo/uds-config';\n\nimport type { SerializedComponentInfo } from '../commands/generateComponentData';\nimport {\n deduplicateSafelist,\n getInternalSafelistClasses,\n getThemeAndScaleClasses,\n} from '../purger/optimized/utils/safelist';\nimport type { EntryValue, ResolvedEntryPath } from '../utils/entryPoints';\nimport { DEFAULT_ENTRY, resolveEntryPaths } from '../utils/entryPoints';\nimport { generateCSS, generateSimpleModeCSS } from './generate';\nimport { getPruneVarSafelist } from './generate.helpers';\nimport {\n findPackageRoot,\n findPackageSourceDir,\n getPackageUdsScope,\n loadConfigFile,\n scanDirectoriesForSafelist,\n scanDirectoryForSafelist,\n} from './nodeUtils';\nimport {\n formatCssDuration,\n getMainCssSummaryMessage,\n getOutputFileSection,\n getScanSummaryMessage,\n getScopedCssSummaryMessage,\n getVerboseScanFileList,\n getWatchDirectoryGroups,\n} from './runner.helpers';\nimport type {\n UDSScopedPackageConfig,\n UDSScopedPackageValue,\n UDSThemeConfig,\n UDSThemeConfigInput,\n UDSThemeContext,\n} from './theme';\nimport {\n extractRuntimeConfigValues,\n extractVariantDefaults,\n formatBytes,\n getConfigurableCssVariables,\n getMotionVarPrefixes,\n} from './utils';\n\ntype CssCommandContext = {\n variants: Record<string, Record<string, string>>;\n autoVariants: Record<string, Record<string, string>>;\n componentData: Record<string, SerializedComponentInfo>;\n};\n\ntype CssCommandOptions = {\n workspaceDir: string;\n outFile: string;\n themeConfigPath: string;\n scope?: string;\n entryOption?: EntryValue;\n configOption?: string;\n watch: boolean;\n silent: boolean;\n verbose?: boolean;\n};\n\ntype ThemeModeSetup = {\n themeConfig: UDSThemeConfig;\n colorModes: ('dark' | 'light')[];\n entries: ResolvedEntryPath[];\n appConfig: UniversalTokensConfig;\n appVariantDefaults: ReturnType<typeof extractVariantDefaults>;\n runtimeConfigValues: ReturnType<typeof extractRuntimeConfigValues>;\n effectiveSilent: boolean;\n};\n\ntype ScopedPackageBuildTarget = {\n packageName: string;\n packageRoot: string;\n packageDir: string;\n entryDirs: string[];\n scopeClass: string;\n config: UDSScopedPackageConfig;\n};\n\ntype GeneratedCssOutput = {\n label: string;\n outputPath: string;\n sizeGzipBytes: number;\n optimizationStats?: {\n originalSizeGzip: number;\n fontFacesRemoved: number;\n emptyRulesRemoved: number;\n };\n};\n\nconst getScopedPackageOutputPath = (packageName: string, outFile?: string): string => {\n if (typeof outFile === 'string' && outFile.trim().length > 0) {\n return outFile;\n }\n\n const packageLeafName = packageName.split('/').pop() ?? packageName;\n return `dist/${packageLeafName}.css`;\n};\n\nconst normalizeScopedPackageConfig = (\n scopedPackageValue: UDSScopedPackageValue,\n): UDSScopedPackageConfig => {\n if (typeof scopedPackageValue === 'string') {\n return { config: scopedPackageValue };\n }\n\n return scopedPackageValue;\n};\n\nconst resolveScopedEntryDirs = (\n packageRoot: string,\n packageDir: string,\n entry: string | string[] | undefined,\n): string[] => {\n if (entry === undefined) {\n return [packageDir];\n }\n\n return resolveEntryPaths(entry, packageRoot).map((resolvedEntry) => resolvedEntry.absolutePath);\n};\n\nconst PATH_SEPARATOR = '/';\n\nconst normalizePath = (value: string): string => value.replace(/\\\\/g, PATH_SEPARATOR);\n\nconst isAbsolutePath = (value: string): boolean => {\n const normalizedValue = normalizePath(value);\n return normalizedValue.startsWith(PATH_SEPARATOR) || /^[A-Za-z]:\\//.test(normalizedValue);\n};\n\nconst joinPath = (...parts: string[]): string => {\n const filteredParts = parts.filter((part) => part.length > 0);\n if (filteredParts.length === 0) {\n return '';\n }\n\n const normalizedParts = filteredParts.map((part, index) => {\n const normalizedPart = normalizePath(part);\n if (index === 0) {\n return normalizedPart.replace(/\\/+$/g, '');\n }\n return normalizedPart.replace(/^\\/+|\\/+$/g, '');\n });\n\n return normalizedParts\n .join(PATH_SEPARATOR)\n .replace(/\\/+/g, PATH_SEPARATOR)\n .replace(/\\/\\.\\//g, PATH_SEPARATOR);\n};\n\nconst dirnamePath = (value: string): string => {\n const normalizedValue = normalizePath(value).replace(/\\/+$/g, '');\n const lastSeparatorIndex = normalizedValue.lastIndexOf(PATH_SEPARATOR);\n if (lastSeparatorIndex <= 0) {\n return lastSeparatorIndex === 0 ? PATH_SEPARATOR : '.';\n }\n\n return normalizedValue.slice(0, lastSeparatorIndex);\n};\n\nconst basenamePath = (value: string): string => {\n const normalizedValue = normalizePath(value).replace(/\\/+$/g, '');\n const lastSeparatorIndex = normalizedValue.lastIndexOf(PATH_SEPARATOR);\n return lastSeparatorIndex >= 0 ? normalizedValue.slice(lastSeparatorIndex + 1) : normalizedValue;\n};\n\nconst resolveOutputPath = (workspaceDir: string, outFile: string): string =>\n isAbsolutePath(outFile) ? outFile : joinPath(workspaceDir, outFile);\n\nconst ensureOutputDirectory = (outputPath: string): void => {\n const outputDir = dirnamePath(outputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n};\n\nconst SOURCE_FILE_PATTERN = /\\.(jsx?|tsx?)$/i;\n\ntype WatchTarget = {\n watchPath: string;\n recursive: boolean;\n fileNames?: string[];\n};\n\nconst getWatchDirs = (dirs: string[]): string[] => [\n ...new Set(\n dirs.filter((dir) => !normalizePath(dir).split(PATH_SEPARATOR).includes('node_modules')),\n ),\n];\n\nconst isCoveredByRecursiveWatch = (watchPath: string, targetPath: string): boolean =>\n targetPath === watchPath || targetPath.startsWith(`${watchPath}${PATH_SEPARATOR}`);\n\nconst getEntryWatchTargets = (entries: ResolvedEntryPath[]): WatchTarget[] => {\n const directoryTargets = getWatchDirs(\n entries.filter((entry) => entry.kind === 'directory').map((entry) => entry.absolutePath),\n ).map((watchPath) => ({ watchPath, recursive: true }));\n\n const fileNamesByDirectory = new Map<string, Set<string>>();\n\n entries\n .filter(\n (entry): entry is ResolvedEntryPath & { kind: 'file'; fileName: string } =>\n entry.kind === 'file' && typeof entry.fileName === 'string',\n )\n .forEach((entry) => {\n if (\n directoryTargets.some((target) =>\n isCoveredByRecursiveWatch(target.watchPath, entry.absolutePath),\n )\n ) {\n return;\n }\n\n const fileNames = fileNamesByDirectory.get(entry.watchDirectory) ?? new Set<string>();\n fileNames.add(entry.fileName);\n fileNamesByDirectory.set(entry.watchDirectory, fileNames);\n });\n\n const fileTargets = [...fileNamesByDirectory.entries()].map(([watchPath, fileNames]) => ({\n watchPath,\n recursive: false,\n fileNames: [...fileNames],\n }));\n\n return [...directoryTargets, ...fileTargets];\n};\n\nconst watchSourceFiles = (targets: WatchTarget[], onFileChange: () => void): void => {\n targets.forEach((target) => {\n fs.watch(target.watchPath, { recursive: target.recursive }, (_eventType, filename) => {\n if (!filename || !SOURCE_FILE_PATTERN.test(filename)) {\n return;\n }\n\n if (target.fileNames && !target.fileNames.includes(basenamePath(String(filename)))) {\n return;\n }\n\n onFileChange();\n });\n });\n};\n\nconst createDebouncedAction = (action: () => void, delayMs: number): (() => void) => {\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n return () => {\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(action, delayMs);\n };\n};\n\nconst createQueuedRegenerator = <T>(options: {\n onStart?: () => void;\n onSuccess?: (result: T) => void;\n onError: (message: string) => void;\n regenerateOnce: () => Promise<T>;\n}): (() => Promise<void>) => {\n let isGenerating = false;\n let pendingRegenerate = false;\n\n const regenerate = async (): Promise<void> => {\n if (isGenerating) {\n pendingRegenerate = true;\n return;\n }\n\n isGenerating = true;\n try {\n options.onStart?.();\n const result = await options.regenerateOnce();\n options.onSuccess?.(result);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'CSS generation failed';\n options.onError(message);\n } finally {\n isGenerating = false;\n\n if (pendingRegenerate) {\n pendingRegenerate = false;\n await regenerate();\n }\n }\n };\n\n return regenerate;\n};\n\nconst printVerboseScanFiles = (\n log: ReturnType<typeof createLogger>,\n workspaceDir: string,\n filePaths: string[],\n): void => {\n getVerboseScanFileList(workspaceDir, filePaths).forEach((filePath) => {\n log.listItem(filePath);\n });\n};\n\nconst runCssCommand = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const themeConfigExists = fs.existsSync(\n joinPath(options.workspaceDir, String(options.themeConfigPath)),\n );\n\n if (!themeConfigExists) {\n await runSimpleMode(options, context);\n return;\n }\n\n await runThemeMode(options, context);\n};\n\nconst runSimpleMode = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const entry = options.entryOption ?? DEFAULT_ENTRY;\n const configPath = typeof options.configOption === 'string' ? options.configOption : undefined;\n\n if (!options.watch && !options.silent) {\n spinStart('Generating CSS...');\n }\n\n try {\n const result = await generateSimpleModeCSS({\n workspaceDir: options.workspaceDir,\n entry,\n outFile: String(options.outFile),\n variants: context.variants,\n autoVariants: context.autoVariants,\n componentData: context.componentData,\n scope: options.scope,\n configPath,\n isWatch: options.watch,\n silent: options.silent,\n verbose: options.verbose,\n });\n\n if (options.watch) {\n await runSimpleModeWatch(options, context, entry, configPath, result.packageDirs ?? []);\n }\n } catch (error) {\n spinStop('❌', error instanceof Error ? error.message : 'CSS generation failed');\n process.exitCode = 1;\n }\n};\n\nconst runSimpleModeWatch = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n entry: EntryValue,\n configPath: string | undefined,\n packageDirs: string[],\n): Promise<void> => {\n const resolvedEntries = resolveEntryPaths(entry, options.workspaceDir);\n const entryWatchTargets = getEntryWatchTargets(resolvedEntries);\n const fallbackTargets = getWatchDirs(packageDirs).map((watchPath) => ({\n watchPath,\n recursive: true,\n }));\n const watchTargets = packageDirs.length > 0 ? fallbackTargets : entryWatchTargets;\n\n if (!options.silent) {\n print('');\n print(`${magenta('Watching for changes...')}`);\n watchTargets.forEach((target) => print(` ${gray('•')} ${target.watchPath}`));\n print(`${gray('Press Ctrl+C to stop')}`);\n print('');\n }\n\n const regenerate = createQueuedRegenerator({\n onStart: () => {\n if (!options.silent) {\n const timestamp = new Date().toLocaleTimeString();\n print(`${gray(`[${timestamp}]`)} Change detected, regenerating...`);\n }\n },\n regenerateOnce: async () => {\n await generateSimpleModeCSS({\n workspaceDir: options.workspaceDir,\n entry,\n outFile: String(options.outFile),\n variants: context.variants,\n autoVariants: context.autoVariants,\n componentData: context.componentData,\n scope: options.scope,\n configPath,\n isWatch: true,\n silent: true,\n });\n },\n onSuccess: () => {\n if (!options.silent) {\n const updatedAt = new Date().toLocaleTimeString();\n print(`${gray(`[${updatedAt}]`)} ${green('CSS updated')}`);\n print('');\n }\n },\n onError: (message) => {\n print(`Error: ${message}`);\n },\n });\n\n watchSourceFiles(\n watchTargets,\n createDebouncedAction(() => {\n void regenerate();\n }, 100),\n );\n\n await new Promise(() => {});\n};\n\nconst loadThemeModeSetup = async (options: CssCommandOptions): Promise<ThemeModeSetup | null> => {\n const themeConfigInput = await loadConfigFile<UDSThemeConfigInput>(\n String(options.themeConfigPath),\n );\n if (!themeConfigInput) {\n return null;\n }\n\n const themeContext: UDSThemeContext = {\n cwd: options.workspaceDir,\n watch: options.watch,\n };\n const themeConfig: UDSThemeConfig =\n typeof themeConfigInput === 'function'\n ? await themeConfigInput(themeContext)\n : themeConfigInput;\n\n let appConfig: UniversalTokensConfig = defaultTokensConfig;\n if (themeConfig.config) {\n const loadedConfig = await loadConfigFile<UniversalTokensConfig>(themeConfig.config);\n if (loadedConfig) {\n appConfig = loadedConfig;\n }\n }\n\n return {\n themeConfig,\n colorModes: themeConfig.colorModes ?? ['dark'],\n entries: resolveEntryPaths(themeConfig.entry, options.workspaceDir),\n appConfig,\n appVariantDefaults: extractVariantDefaults(appConfig),\n runtimeConfigValues: extractRuntimeConfigValues(appConfig),\n effectiveSilent: options.silent || themeConfig.silent === true,\n };\n};\n\nconst runThemeMode = async (\n options: CssCommandOptions,\n context: CssCommandContext,\n): Promise<void> => {\n const workspaceDir = options.workspaceDir;\n const outputPath = resolveOutputPath(workspaceDir, String(options.outFile));\n let effectiveSilent = options.silent;\n let log = createLogger({ silent: effectiveSilent });\n\n log.spinStart('Loading theme configuration...');\n\n try {\n const setup = await loadThemeModeSetup(options);\n if (!setup) {\n log.spinStop('❌', `Theme config not found: ${options.themeConfigPath}`);\n process.exitCode = 1;\n return;\n }\n\n const { themeConfig, colorModes, entries, appConfig, appVariantDefaults, runtimeConfigValues } =\n setup;\n effectiveSilent = setup.effectiveSilent;\n log = createLogger({ silent: effectiveSilent });\n const entryDirs = entries.map((entry) => entry.absolutePath);\n\n if (!effectiveSilent) {\n log.spinStop('✅', 'Theme configuration loaded');\n }\n\n if (themeConfig.config && appConfig === defaultTokensConfig) {\n log.warn(`App config not found: ${themeConfig.config}, using defaults`);\n }\n const packageDirs: string[] = [];\n\n const generateThemeModeCSS = async (opts?: { isWatch?: boolean }) => {\n const genStartTime = performance.now();\n const genLog = opts?.isWatch ? createLogger({ silent: true }) : log;\n const scopedCssOutputs: GeneratedCssOutput[] = [];\n\n genLog.spinStart('Scanning app code...');\n const appScanResult = await scanDirectoriesForSafelist(\n entryDirs,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n appVariantDefaults,\n runtimeConfigValues,\n );\n genLog.spinStop(\n '✅',\n getScanSummaryMessage({\n label: 'app',\n filesScanned: appScanResult.filesScanned,\n filesWithComponents: appScanResult.filesWithComponents,\n componentCount: appScanResult.components.length,\n mode: 'app',\n }),\n );\n if (options.verbose) {\n printVerboseScanFiles(genLog, workspaceDir, appScanResult.filePaths);\n }\n\n genLog.spinStart('Generating main CSS...');\n\n const inheritedClasses: string[] = [...appScanResult.safelist];\n const inheritedComponents = new Set<string>(appScanResult.components);\n const scopedPackageTargets: ScopedPackageBuildTarget[] = [];\n\n const processInheritedPackage = async (packageName: string) => {\n genLog.spinStart(`Processing package: ${packageName}...`);\n\n const packageDir = findPackageSourceDir(packageName);\n if (!packageDir) {\n genLog.spinStop('⚠️', `Package not found: ${packageName}`);\n return;\n }\n\n if (!packageDirs.includes(packageDir)) {\n packageDirs.push(packageDir);\n }\n\n const packageScanResult = await scanDirectoryForSafelist(\n packageDir,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n appVariantDefaults,\n runtimeConfigValues,\n true,\n );\n inheritedClasses.push(...packageScanResult.safelist);\n packageScanResult.components.forEach((comp) => inheritedComponents.add(comp));\n genLog.spinStop(\n '✅',\n getScanSummaryMessage({\n label: packageName,\n filesScanned: packageScanResult.filesScanned,\n filesWithComponents: packageScanResult.filesWithComponents,\n componentCount: packageScanResult.components.length,\n mode: 'inherit',\n }),\n );\n if (options.verbose) {\n printVerboseScanFiles(genLog, workspaceDir, packageScanResult.filePaths);\n }\n };\n\n const processScopedPackage = async (\n packageName: string,\n scopedPackageValue: UDSScopedPackageValue,\n ) => {\n genLog.spinStart(`Processing scoped package: ${packageName}...`);\n const scopedPackageConfig = normalizeScopedPackageConfig(scopedPackageValue);\n\n const packageRoot = findPackageRoot(packageName);\n const packageDir = findPackageSourceDir(packageName);\n if (!packageRoot || !packageDir) {\n genLog.spinStop('⚠️', `Scoped package not found: ${packageName}`);\n return;\n }\n\n const scopeClass = getPackageUdsScope(packageName);\n if (!scopeClass) {\n genLog.spinStop('⚠️', `Scoped package missing package.json uds.scope: ${packageName}`);\n return;\n }\n\n const entryDirs = resolveScopedEntryDirs(\n packageRoot,\n packageDir,\n scopedPackageConfig.entry,\n );\n entryDirs.forEach((entryDir) => {\n if (!packageDirs.includes(entryDir)) {\n packageDirs.push(entryDir);\n }\n });\n\n scopedPackageTargets.push({\n packageName,\n packageRoot,\n packageDir,\n entryDirs,\n scopeClass,\n config: scopedPackageConfig,\n });\n };\n\n await (themeConfig.inherit ?? []).reduce(async (promise, packageName) => {\n await promise;\n await processInheritedPackage(packageName);\n }, Promise.resolve());\n\n await Object.entries(themeConfig.scoped ?? {}).reduce(\n async (promise, [packageName, scopedPackageConfig]) => {\n await promise;\n await processScopedPackage(packageName, scopedPackageConfig);\n },\n Promise.resolve(),\n );\n\n const mainSafelist = deduplicateSafelist([\n ...inheritedClasses,\n ...getThemeAndScaleClasses(colorModes),\n ...getInternalSafelistClasses(),\n ]);\n\n const allMotionComponents: string[] = [...inheritedComponents];\n\n const mainCssResult = await generateCSS(\n [...(themeConfig.css?.safelist ?? []), ...mainSafelist],\n appConfig,\n {\n scope: options.scope,\n contentDir: entryDirs,\n cssOptions: themeConfig.css,\n safeVarPrefixes: [\n ...getMotionVarPrefixes(context.componentData, allMotionComponents),\n ...getConfigurableCssVariables(),\n ...getPruneVarSafelist(themeConfig.css),\n ],\n },\n );\n\n ensureOutputDirectory(outputPath);\n fs.writeFileSync(outputPath, mainCssResult.css);\n\n for (const scopedPackageTarget of scopedPackageTargets) {\n const packageConfigPath = isAbsolutePath(scopedPackageTarget.config.config)\n ? scopedPackageTarget.config.config\n : joinPath(scopedPackageTarget.packageRoot, scopedPackageTarget.config.config);\n const packageConfig =\n (await loadConfigFile<UniversalTokensConfig>(packageConfigPath)) ?? defaultTokensConfig;\n const packageVariantDefaults = extractVariantDefaults(packageConfig);\n const packageRuntimeConfigValues = extractRuntimeConfigValues(packageConfig);\n const packageScanResult = await scanDirectoriesForSafelist(\n scopedPackageTarget.entryDirs,\n colorModes,\n context.variants,\n context.autoVariants,\n context.componentData,\n packageVariantDefaults,\n packageRuntimeConfigValues,\n true,\n );\n genLog.spinStop(\n '✅',\n getScanSummaryMessage({\n label: scopedPackageTarget.packageName,\n filesScanned: packageScanResult.filesScanned,\n filesWithComponents: packageScanResult.filesWithComponents,\n componentCount: packageScanResult.components.length,\n mode: 'scoped',\n }),\n );\n if (options.verbose) {\n printVerboseScanFiles(genLog, workspaceDir, packageScanResult.filePaths);\n }\n const packageSafelist = deduplicateSafelist([\n ...packageScanResult.safelist,\n ...getThemeAndScaleClasses(colorModes),\n ...getInternalSafelistClasses(),\n ]);\n const scopedCssResult = await generateCSS(\n [...(themeConfig.css?.safelist ?? []), ...packageSafelist],\n packageConfig,\n {\n scope: scopedPackageTarget.scopeClass,\n contentDir: scopedPackageTarget.entryDirs,\n cssOptions: themeConfig.css,\n referenceCss:\n themeConfig.css?.optimization?.deduplicateScopedCss === false\n ? undefined\n : mainCssResult.css,\n safeVarPrefixes: [\n ...getMotionVarPrefixes(context.componentData, [...packageScanResult.components]),\n ...getConfigurableCssVariables(),\n ...getPruneVarSafelist(themeConfig.css),\n ],\n },\n );\n\n const scopedOutputPath = resolveOutputPath(\n workspaceDir,\n getScopedPackageOutputPath(\n scopedPackageTarget.packageName,\n scopedPackageTarget.config.outFile,\n ),\n );\n ensureOutputDirectory(scopedOutputPath);\n fs.writeFileSync(scopedOutputPath, scopedCssResult.css);\n scopedCssOutputs.push({\n label: scopedPackageTarget.packageName,\n outputPath: scopedOutputPath,\n sizeGzipBytes: scopedCssResult.sizeGzipBytes,\n optimizationStats: scopedCssResult.optimizationStats,\n });\n }\n\n const mainCssSummary = getMainCssSummaryMessage({\n sizeGzipBytes: mainCssResult.sizeGzipBytes,\n optimizationStats: mainCssResult.optimizationStats,\n formatBytes,\n });\n genLog.spinStop('✅', mainCssSummary.summaryLine);\n mainCssSummary.detailLines.forEach((detailLine) => {\n genLog.print(detailLine);\n });\n\n scopedCssOutputs.forEach((scopedCssOutput) => {\n const scopedCssSummary = getScopedCssSummaryMessage(scopedCssOutput.label, {\n sizeGzipBytes: scopedCssOutput.sizeGzipBytes,\n optimizationStats: scopedCssOutput.optimizationStats,\n formatBytes,\n });\n genLog.spinStop('✅', scopedCssSummary.summaryLine);\n scopedCssSummary.detailLines.forEach((detailLine) => {\n genLog.print(detailLine);\n });\n });\n\n const duration = Math.round(performance.now() - genStartTime);\n const outputFileSection = getOutputFileSection(workspaceDir, [\n outputPath,\n ...scopedCssOutputs.map((scopedCssOutput) => scopedCssOutput.outputPath),\n ]);\n\n genLog.newline();\n genLog.print(outputFileSection.label);\n outputFileSection.paths.forEach((filePath) => {\n genLog.listItem(filePath);\n });\n genLog.newline();\n genLog.print(`${magenta('Total time:')} ${formatCssDuration(duration)}`);\n\n return {\n duration,\n outputPath,\n outputPaths: outputFileSection.paths,\n packageDirs,\n };\n };\n\n await generateThemeModeCSS();\n\n if (options.watch) {\n const entryWatchTargets = getEntryWatchTargets(entries);\n const entryWatchDirs = getWatchDirs(entryWatchTargets.map((target) => target.watchPath));\n const { filteredPackageDirs } = getWatchDirectoryGroups(entryWatchDirs, [\n ...entryDirs,\n ...packageDirs,\n ]);\n\n if (!effectiveSilent) {\n log.newline();\n log.print(`${magenta('Watching for changes...')}`);\n entryDirs.forEach((entryDir) => {\n log.listItem(`App: ${entryDir}`);\n });\n filteredPackageDirs.forEach((dir) => {\n log.listItem(`Package: ${dir}`);\n });\n log.print(`${gray('Press Ctrl+C to stop')}`);\n log.newline();\n }\n\n const regenerate = createQueuedRegenerator({\n onStart: () => {\n if (!effectiveSilent) {\n const timestamp = new Date().toLocaleTimeString();\n log.print(`${gray(`[${timestamp}]`)} Change detected, regenerating...`);\n }\n },\n regenerateOnce: async () => generateThemeModeCSS({ isWatch: true }),\n onSuccess: (result) => {\n if (!effectiveSilent) {\n const updatedAt = new Date().toLocaleTimeString();\n const updatedMessage =\n result?.duration == null\n ? 'CSS updated'\n : `CSS updated (${formatCssDuration(result.duration)})`;\n log.print(`${gray(`[${updatedAt}]`)} ${green(updatedMessage)}`);\n log.newline();\n }\n },\n onError: (message) => {\n log.print(message);\n },\n });\n\n const watchDebounce = themeConfig.css?.watchDebounce ?? 100;\n\n watchSourceFiles(\n [\n ...entryWatchTargets,\n ...filteredPackageDirs\n .filter(\n (packageDir) =>\n !entryWatchTargets.some((target) =>\n isCoveredByRecursiveWatch(target.watchPath, packageDir),\n ),\n )\n .map((watchPath) => ({ watchPath, recursive: true })),\n ],\n createDebouncedAction(() => {\n void regenerate();\n }, watchDebounce),\n );\n\n await new Promise(() => {});\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'CSS generation failed';\n if (effectiveSilent) {\n spinStop('❌', message);\n } else {\n log.spinStop('❌', message);\n }\n process.exitCode = 1;\n }\n};\n\nexport { runCssCommand };\nexport type { CssCommandContext, CssCommandOptions };\n"],"mappings":"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"}
|
|
@@ -59,7 +59,18 @@ interface UDSThemeConfig {
|
|
|
59
59
|
colorModes?: ('dark' | 'light')[];
|
|
60
60
|
/** CSS generation options */
|
|
61
61
|
css?: UDSCSSOptions;
|
|
62
|
+
/** Packages that generate their own scoped CSS output files */
|
|
63
|
+
scoped?: Record<string, UDSScopedPackageValue>;
|
|
62
64
|
}
|
|
65
|
+
interface UDSScopedPackageConfig {
|
|
66
|
+
/** Entry path, file path, or list of paths relative to the package root */
|
|
67
|
+
entry?: string | string[];
|
|
68
|
+
/** Output file path for the generated package CSS (default: dist/<package-name>.css) */
|
|
69
|
+
outFile?: string;
|
|
70
|
+
/** Path to the package-specific uds.config.ts file */
|
|
71
|
+
config: string;
|
|
72
|
+
}
|
|
73
|
+
type UDSScopedPackageValue = string | UDSScopedPackageConfig;
|
|
63
74
|
/**
|
|
64
75
|
* Theme config can be an object or a function that receives context
|
|
65
76
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.cts","names":[],"sources":["../../src/css/theme.ts"],"mappings":";;;;KAEK,wBAAA,YAAoC,MAAA;AAAA,UAE/B,sBAAA;EAFL;EAIH,QAAA,GAAW,wBAAA;AAAA;;;AAJkC;UAUrC,eAAA;;EAER,GAAA;EARmC;EAUnC,KAAA;AAAA;;;;UAMQ,yBAAA;EAAyB;EAEjC,OAAA;EAiB4C;EAf5C,iBAAA;EAAA;EAEA,gBAAA;EAEA;EAAA,2BAAA;EAWA;;;;AAA4C;EAL5C,oBAAA;;;;;EAKA,SAAA,aAAsB,sBAAA;AAAA;;;;UAMd,cAAA;
|
|
1
|
+
{"version":3,"file":"theme.d.cts","names":[],"sources":["../../src/css/theme.ts"],"mappings":";;;;KAEK,wBAAA,YAAoC,MAAA;AAAA,UAE/B,sBAAA;EAFL;EAIH,QAAA,GAAW,wBAAA;AAAA;;;AAJkC;UAUrC,eAAA;;EAER,GAAA;EARmC;EAUnC,KAAA;AAAA;;;;UAMQ,yBAAA;EAAyB;EAEjC,OAAA;EAiB4C;EAf5C,iBAAA;EAAA;EAEA,gBAAA;EAEA;EAAA,2BAAA;EAWA;;;;AAA4C;EAL5C,oBAAA;;;;;EAKA,SAAA,aAAsB,sBAAA;AAAA;;;;UAMd,cAAA;EAaR;EAXA,MAAA;EAaM;EAXN,KAAA;EAaS;EAXT,MAAA;EAW6C;;AAAA;;EAN7C,OAAA;EAS8B;EAP9B,UAAA;EAWA;EATA,GAAA,GAAM,aAAA;EAWA;EATN,MAAA,GAAS,MAAA,SAAe,qBAAA;AAAA;AAAA,UAGhB,sBAAA;;EAER,KAAA;EAO0D;EAL1D,OAAA;EAUsB;EARtB,MAAA;AAAA;AAAA,KAGG,qBAAA,YAAiC,sBAAA;;;;KAKjC,mBAAA,GACD,cAAA,KACE,GAAA,EAAK,eAAA,KAAoB,cAAA,GAAiB,OAAA,CAAQ,cAAA;;;;;cAMlD,WAAA,GAAe,MAAA,EAAQ,mBAAA,KAAsB,mBAAA"}
|
|
@@ -59,7 +59,18 @@ interface UDSThemeConfig {
|
|
|
59
59
|
colorModes?: ('dark' | 'light')[];
|
|
60
60
|
/** CSS generation options */
|
|
61
61
|
css?: UDSCSSOptions;
|
|
62
|
+
/** Packages that generate their own scoped CSS output files */
|
|
63
|
+
scoped?: Record<string, UDSScopedPackageValue>;
|
|
62
64
|
}
|
|
65
|
+
interface UDSScopedPackageConfig {
|
|
66
|
+
/** Entry path, file path, or list of paths relative to the package root */
|
|
67
|
+
entry?: string | string[];
|
|
68
|
+
/** Output file path for the generated package CSS (default: dist/<package-name>.css) */
|
|
69
|
+
outFile?: string;
|
|
70
|
+
/** Path to the package-specific uds.config.ts file */
|
|
71
|
+
config: string;
|
|
72
|
+
}
|
|
73
|
+
type UDSScopedPackageValue = string | UDSScopedPackageConfig;
|
|
63
74
|
/**
|
|
64
75
|
* Theme config can be an object or a function that receives context
|
|
65
76
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.ts","names":[],"sources":["../../src/css/theme.ts"],"mappings":";;;;KAEK,wBAAA,YAAoC,MAAA;AAAA,UAE/B,sBAAA;EAFL;EAIH,QAAA,GAAW,wBAAA;AAAA;;;AAJkC;UAUrC,eAAA;;EAER,GAAA;EARmC;EAUnC,KAAA;AAAA;;;;UAMQ,yBAAA;EAAyB;EAEjC,OAAA;EAiB4C;EAf5C,iBAAA;EAAA;EAEA,gBAAA;EAEA;EAAA,2BAAA;EAWA;;;;AAA4C;EAL5C,oBAAA;;;;;EAKA,SAAA,aAAsB,sBAAA;AAAA;;;;UAMd,cAAA;
|
|
1
|
+
{"version":3,"file":"theme.d.ts","names":[],"sources":["../../src/css/theme.ts"],"mappings":";;;;KAEK,wBAAA,YAAoC,MAAA;AAAA,UAE/B,sBAAA;EAFL;EAIH,QAAA,GAAW,wBAAA;AAAA;;;AAJkC;UAUrC,eAAA;;EAER,GAAA;EARmC;EAUnC,KAAA;AAAA;;;;UAMQ,yBAAA;EAAyB;EAEjC,OAAA;EAiB4C;EAf5C,iBAAA;EAAA;EAEA,gBAAA;EAEA;EAAA,2BAAA;EAWA;;;;AAA4C;EAL5C,oBAAA;;;;;EAKA,SAAA,aAAsB,sBAAA;AAAA;;;;UAMd,cAAA;EAaR;EAXA,MAAA;EAaM;EAXN,KAAA;EAaS;EAXT,MAAA;EAW6C;;AAAA;;EAN7C,OAAA;EAS8B;EAP9B,UAAA;EAWA;EATA,GAAA,GAAM,aAAA;EAWA;EATN,MAAA,GAAS,MAAA,SAAe,qBAAA;AAAA;AAAA,UAGhB,sBAAA;;EAER,KAAA;EAO0D;EAL1D,OAAA;EAUsB;EARtB,MAAA;AAAA;AAAA,KAGG,qBAAA,YAAiC,sBAAA;;;;KAKjC,mBAAA,GACD,cAAA,KACE,GAAA,EAAK,eAAA,KAAoB,cAAA,GAAiB,OAAA,CAAQ,cAAA;;;;;cAMlD,WAAA,GAAe,MAAA,EAAQ,mBAAA,KAAsB,mBAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.js","names":[],"sources":["../../src/css/theme.ts"],"sourcesContent":["import type { UDSCSSOptions } from './generate';\n\ntype UDSCSSVarSafelistPattern = string | RegExp;\n\ninterface UDSCSSPruneVarsOptions {\n /** CSS variable prefixes or patterns to preserve when pruning is enabled */\n safelist?: UDSCSSVarSafelistPattern[];\n}\n\n/**\n * Context passed to theme config function\n */\ninterface UDSThemeContext {\n /** Current working directory */\n cwd: string;\n /** Whether the CLI is running in watch mode */\n watch?: boolean;\n}\n\n/**\n * CSS optimization options for uds.theme.ts\n */\ninterface UDSCSSOptimizationOptions {\n /** Enable all CSS optimizations (default: true) */\n enabled?: boolean;\n /** Remove @font-face declarations for fonts not used in the CSS (default: false) */\n removeUnusedFonts?: boolean;\n /** Remove empty CSS rules (default: true) */\n removeEmptyRules?: boolean;\n /** Aggregate duplicate selectors (default: true) */\n aggregateDuplicateSelectors?: boolean;\n /**\n * Remove duplicate content from scoped CSS that already exists in main CSS (default: true)\n * Currently deduplicates @font-face declarations. Reduces bundle size when scoped packages\n * share fonts with the main app.\n */\n deduplicateScopedCss?: boolean;\n /**\n * Prune unused CSS variables (default: true).\n * Provide an object to keep pruning enabled while safelisting variable prefixes or patterns.\n */\n pruneVars?: boolean | UDSCSSPruneVarsOptions;\n}\n\n/**\n * Theme configuration structure for uds.theme.ts\n */\ninterface UDSThemeConfig {\n /** Path to app's uds.config (relative to project root) */\n config?: string;\n /** Entry directory path or .tsx file path, or a list of those paths (default: './src') */\n entry?: string | string[];\n /** Suppress log output during generation (default: false) */\n silent?: boolean;\n /**\n * Packages that inherit the app's theme configuration.\n * These packages' styles are merged into the main uds.css file.\n */\n inherit?: string[];\n /** Color modes to include (default: ['dark']) - light mode is always in :root */\n colorModes?: ('dark' | 'light')[];\n /** CSS generation options */\n css?: UDSCSSOptions;\n}\n\n/**\n * Theme config can be an object or a function that receives context\n */\ntype UDSThemeConfigInput =\n | UDSThemeConfig\n | ((ctx: UDSThemeContext) => UDSThemeConfig | Promise<UDSThemeConfig>);\n\n/**\n * Helper function to define theme configuration with full type support.\n * Supports both static config objects and dynamic functions.\n */\nconst defineTheme = (config: UDSThemeConfigInput): UDSThemeConfigInput => config;\n\nexport { defineTheme };\nexport type {\n UDSCSSOptimizationOptions,\n UDSCSSPruneVarsOptions,\n UDSCSSVarSafelistPattern,\n UDSThemeConfig,\n UDSThemeConfigInput,\n UDSThemeContext,\n};\n"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"theme.js","names":[],"sources":["../../src/css/theme.ts"],"sourcesContent":["import type { UDSCSSOptions } from './generate';\n\ntype UDSCSSVarSafelistPattern = string | RegExp;\n\ninterface UDSCSSPruneVarsOptions {\n /** CSS variable prefixes or patterns to preserve when pruning is enabled */\n safelist?: UDSCSSVarSafelistPattern[];\n}\n\n/**\n * Context passed to theme config function\n */\ninterface UDSThemeContext {\n /** Current working directory */\n cwd: string;\n /** Whether the CLI is running in watch mode */\n watch?: boolean;\n}\n\n/**\n * CSS optimization options for uds.theme.ts\n */\ninterface UDSCSSOptimizationOptions {\n /** Enable all CSS optimizations (default: true) */\n enabled?: boolean;\n /** Remove @font-face declarations for fonts not used in the CSS (default: false) */\n removeUnusedFonts?: boolean;\n /** Remove empty CSS rules (default: true) */\n removeEmptyRules?: boolean;\n /** Aggregate duplicate selectors (default: true) */\n aggregateDuplicateSelectors?: boolean;\n /**\n * Remove duplicate content from scoped CSS that already exists in main CSS (default: true)\n * Currently deduplicates @font-face declarations. Reduces bundle size when scoped packages\n * share fonts with the main app.\n */\n deduplicateScopedCss?: boolean;\n /**\n * Prune unused CSS variables (default: true).\n * Provide an object to keep pruning enabled while safelisting variable prefixes or patterns.\n */\n pruneVars?: boolean | UDSCSSPruneVarsOptions;\n}\n\n/**\n * Theme configuration structure for uds.theme.ts\n */\ninterface UDSThemeConfig {\n /** Path to app's uds.config (relative to project root) */\n config?: string;\n /** Entry directory path or .tsx file path, or a list of those paths (default: './src') */\n entry?: string | string[];\n /** Suppress log output during generation (default: false) */\n silent?: boolean;\n /**\n * Packages that inherit the app's theme configuration.\n * These packages' styles are merged into the main uds.css file.\n */\n inherit?: string[];\n /** Color modes to include (default: ['dark']) - light mode is always in :root */\n colorModes?: ('dark' | 'light')[];\n /** CSS generation options */\n css?: UDSCSSOptions;\n /** Packages that generate their own scoped CSS output files */\n scoped?: Record<string, UDSScopedPackageValue>;\n}\n\ninterface UDSScopedPackageConfig {\n /** Entry path, file path, or list of paths relative to the package root */\n entry?: string | string[];\n /** Output file path for the generated package CSS (default: dist/<package-name>.css) */\n outFile?: string;\n /** Path to the package-specific uds.config.ts file */\n config: string;\n}\n\ntype UDSScopedPackageValue = string | UDSScopedPackageConfig;\n\n/**\n * Theme config can be an object or a function that receives context\n */\ntype UDSThemeConfigInput =\n | UDSThemeConfig\n | ((ctx: UDSThemeContext) => UDSThemeConfig | Promise<UDSThemeConfig>);\n\n/**\n * Helper function to define theme configuration with full type support.\n * Supports both static config objects and dynamic functions.\n */\nconst defineTheme = (config: UDSThemeConfigInput): UDSThemeConfigInput => config;\n\nexport { defineTheme };\nexport type {\n UDSCSSOptimizationOptions,\n UDSCSSPruneVarsOptions,\n UDSCSSVarSafelistPattern,\n UDSScopedPackageConfig,\n UDSScopedPackageValue,\n UDSThemeConfig,\n UDSThemeConfigInput,\n UDSThemeContext,\n};\n"],"mappings":";;;;;;AAyFA,MAAM,eAAe,WAAqD"}
|