@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.
Files changed (51) hide show
  1. package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
  2. package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
  3. package/dist/components/client/Toast/UDSToastConfigProvider.d.cts +5 -5
  4. package/dist/components/client/Toast/UDSToastConfigProvider.d.ts +5 -5
  5. package/dist/styles/styler.d.cts +34 -34
  6. package/dist/styles/styler.d.ts +34 -34
  7. package/dist/tailwind/dist/commands/css.cjs +17 -3
  8. package/dist/tailwind/dist/commands/css.d.cts.map +1 -1
  9. package/dist/tailwind/dist/commands/css.d.ts.map +1 -1
  10. package/dist/tailwind/dist/commands/css.helpers.cjs +2 -1
  11. package/dist/tailwind/dist/commands/css.helpers.js +2 -1
  12. package/dist/tailwind/dist/commands/css.helpers.js.map +1 -1
  13. package/dist/tailwind/dist/commands/css.js +17 -3
  14. package/dist/tailwind/dist/commands/css.js.map +1 -1
  15. package/dist/tailwind/dist/css/generate.cjs +3 -0
  16. package/dist/tailwind/dist/css/generate.helpers.cjs +14 -6
  17. package/dist/tailwind/dist/css/generate.helpers.js +15 -7
  18. package/dist/tailwind/dist/css/generate.helpers.js.map +1 -1
  19. package/dist/tailwind/dist/css/generate.js +3 -0
  20. package/dist/tailwind/dist/css/generate.js.map +1 -1
  21. package/dist/tailwind/dist/css/nodeUtils.cjs +91 -20
  22. package/dist/tailwind/dist/css/nodeUtils.js +90 -21
  23. package/dist/tailwind/dist/css/nodeUtils.js.map +1 -1
  24. package/dist/tailwind/dist/css/postcss.cjs +22 -1
  25. package/dist/tailwind/dist/css/postcss.helpers.cjs +12 -1
  26. package/dist/tailwind/dist/css/postcss.helpers.js +11 -1
  27. package/dist/tailwind/dist/css/postcss.helpers.js.map +1 -1
  28. package/dist/tailwind/dist/css/postcss.js +22 -2
  29. package/dist/tailwind/dist/css/postcss.js.map +1 -1
  30. package/dist/tailwind/dist/css/runner.cjs +171 -20
  31. package/dist/tailwind/dist/css/runner.helpers.cjs +58 -6
  32. package/dist/tailwind/dist/css/runner.helpers.js +54 -7
  33. package/dist/tailwind/dist/css/runner.helpers.js.map +1 -1
  34. package/dist/tailwind/dist/css/runner.js +172 -20
  35. package/dist/tailwind/dist/css/runner.js.map +1 -1
  36. package/dist/tailwind/dist/css/theme.d.cts +11 -0
  37. package/dist/tailwind/dist/css/theme.d.cts.map +1 -1
  38. package/dist/tailwind/dist/css/theme.d.ts +11 -0
  39. package/dist/tailwind/dist/css/theme.d.ts.map +1 -1
  40. package/dist/tailwind/dist/css/theme.js.map +1 -1
  41. package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +26 -3
  42. package/dist/tailwind/dist/purger/optimized/ast/expressions.js +26 -3
  43. package/dist/tailwind/dist/purger/optimized/ast/expressions.js.map +1 -1
  44. package/dist/tailwind/dist/tailwind/utils/getFontStyles.d.cts +1 -1
  45. package/dist/tailwind/dist/tailwind/utils/getFontStyles.d.ts +1 -1
  46. package/dist/tailwind/dist/tailwind/utils/getShadowStyles.d.cts +4 -4
  47. package/dist/tailwind/dist/tailwind/utils/getShadowStyles.d.ts +4 -4
  48. package/dist/uds/generated/componentData.cjs +1152 -1152
  49. package/dist/uds/generated/componentData.js +1152 -1152
  50. package/generated/componentData.json +1738 -1738
  51. 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 getMainCssSummaryMessage = (options) => {
6
- const { optimizationStats, sizeGzipBytes, formatBytes } = options;
7
- if (!optimizationStats) return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip`;
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
- const savedBytesGzip = originalSizeGzip - sizeGzipBytes;
10
- if (savedBytesGzip <= 0) return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip`;
11
- return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip)(optimized: saved ${formatBytes(savedBytesGzip)} gzip, ${fontFacesRemoved} unused @font-face, ${emptyRulesRemoved} empty rules removed)`;
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 getMainCssSummaryMessage = (options: MainCssSummaryOptions): string => {\n const { optimizationStats, sizeGzipBytes, formatBytes } = options;\n\n if (!optimizationStats) {\n return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip`;\n }\n\n const { originalSizeGzip, fontFacesRemoved, emptyRulesRemoved } = optimizationStats;\n const savedBytesGzip = originalSizeGzip - sizeGzipBytes;\n\n if (savedBytesGzip <= 0) {\n return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip`;\n }\n\n return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip)(optimized: saved ${formatBytes(savedBytesGzip)} gzip, ${fontFacesRemoved} unused @font-face, ${emptyRulesRemoved} empty rules removed)`;\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 { getMainCssSummaryMessage, getWatchDirectoryGroups };\n"],"mappings":";;;;AAcA,MAAM,4BAA4B,YAA2C;CAC3E,MAAM,EAAE,mBAAmB,eAAe,gBAAgB;AAE1D,KAAI,CAAC,kBACH,QAAO,aAAa,YAAY,cAAc,CAAC;CAGjD,MAAM,EAAE,kBAAkB,kBAAkB,sBAAsB;CAClE,MAAM,iBAAiB,mBAAmB;AAE1C,KAAI,kBAAkB,EACpB,QAAO,aAAa,YAAY,cAAc,CAAC;AAGjD,QAAO,aAAa,YAAY,cAAc,CAAC,0BAA0B,YAAY,eAAe,CAAC,SAAS,iBAAiB,sBAAsB,kBAAkB;;AAGzK,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"}
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(path.sep).includes("node_modules")))];
20
- const isCoveredByRecursiveWatch = (watchPath, targetPath) => targetPath === watchPath || targetPath.startsWith(`${watchPath}${path.sep}`);
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(path.basename(String(filename)))) return;
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(path.join(options.workspaceDir, String(options.themeConfigPath)))) {
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 = path.isAbsolute(options.outFile) ? options.outFile : path.join(workspaceDir, String(options.outFile));
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("✅", `Scanned ${appScanResult.filesScanned} files`);
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("✅", `${packageName}: ${packageScanResult.filesScanned} files (inherit)`);
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
- const outputDir = path.dirname(outputPath);
245
- if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
339
+ ensureOutputDirectory(outputPath);
246
340
  fs.writeFileSync(outputPath, mainCssResult.css);
247
- genLog.spinStop("✅", getMainCssSummaryMessage({
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(green("CSS generation complete!"));
255
- genLog.newline();
256
- genLog.label("Output file:", outputPath);
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}ms`);
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
- log.print(`${gray(`[${updatedAt}]`)} ${green(`CSS updated (${result?.duration}ms)`)}`);
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;EAeW;EAbnB,MAAA;EAmBsB;EAjBtB,KAAA;EAkBE;EAhBF,MAAA;EAiB6B;;;;EAZ7B,OAAA;EAWE;EATF,UAAA;EAUI;EARJ,GAAA,GAAM,aAAA;AAAA;;;;KAMH,mBAAA,GACD,cAAA,KACE,GAAA,EAAK,eAAA,KAAoB,cAAA,GAAiB,OAAA,CAAQ,cAAA;;;;;cAMlD,WAAA,GAAe,MAAA,EAAQ,mBAAA,KAAsB,mBAAA"}
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;EAeW;EAbnB,MAAA;EAmBsB;EAjBtB,KAAA;EAkBE;EAhBF,MAAA;EAiB6B;;;;EAZ7B,OAAA;EAWE;EATF,UAAA;EAUI;EARJ,GAAA,GAAM,aAAA;AAAA;;;;KAMH,mBAAA,GACD,cAAA,KACE,GAAA,EAAK,eAAA,KAAoB,cAAA,GAAiB,OAAA,CAAQ,cAAA;;;;;cAMlD,WAAA,GAAe,MAAA,EAAQ,mBAAA,KAAsB,mBAAA"}
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":";;;;;;AA4EA,MAAM,eAAe,WAAqD"}
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"}