@yahoo/uds 3.104.0 → 3.105.0
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/automated-config/dist/generated/autoVariants.cjs +57 -0
- package/dist/automated-config/dist/generated/autoVariants.d.cts +57 -57
- package/dist/automated-config/dist/generated/autoVariants.d.ts +57 -57
- package/dist/automated-config/dist/generated/autoVariants.js +57 -0
- package/dist/automated-config/dist/utils/generateDefaultClassName.cjs +18 -0
- package/dist/automated-config/dist/utils/generateDefaultClassName.d.cts +14 -0
- package/dist/automated-config/dist/utils/generateDefaultClassName.d.ts +14 -0
- package/dist/automated-config/dist/utils/generateDefaultClassName.js +17 -0
- package/dist/automated-config/dist/utils/index.cjs +3 -6
- package/dist/automated-config/dist/utils/index.d.cts +2 -2
- package/dist/automated-config/dist/utils/index.d.ts +2 -2
- package/dist/automated-config/dist/utils/index.js +3 -5
- package/dist/cli/runner.cjs +21 -5
- package/dist/cli/runner.js +21 -5
- package/dist/components/client/Button.cjs +9 -9
- package/dist/components/client/Button.js +2 -2
- package/dist/components/client/IconButton.cjs +8 -8
- package/dist/components/client/IconButton.js +2 -2
- package/dist/components/client/SpringMotionConfig.cjs +4 -4
- package/dist/components/client/SpringMotionConfig.js +5 -5
- package/dist/components/client/buttonConstants.cjs +10 -0
- package/dist/components/client/buttonConstants.d.cts +9 -0
- package/dist/components/client/buttonConstants.d.ts +9 -0
- package/dist/components/client/buttonConstants.js +8 -0
- package/dist/index.cjs +2 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/motion-tokens/dist/index.cjs +11 -0
- package/dist/motion-tokens/dist/index.d.cts +5 -1
- package/dist/motion-tokens/dist/index.d.ts +5 -1
- package/dist/motion-tokens/dist/index.js +11 -1
- package/dist/styles/styler.d.cts +67 -67
- package/dist/styles/styler.d.ts +67 -67
- package/dist/styles/variants.d.cts +57 -0
- package/dist/styles/variants.d.ts +57 -0
- package/dist/tailwind/dist/commands/generateComponentData.cjs +65 -0
- package/dist/tailwind/dist/commands/generateComponentData.d.ts +3 -0
- package/dist/tailwind/dist/commands/generateComponentData.js +64 -0
- package/dist/tailwind/dist/commands/generatePurgeCSSData.cjs +1 -1
- package/dist/tailwind/dist/commands/generatePurgeCSSData.js +1 -1
- package/dist/tailwind/dist/commands/purge.cjs +41 -11
- package/dist/tailwind/dist/commands/purge.d.ts +2 -1
- package/dist/tailwind/dist/commands/purge.js +41 -11
- package/dist/tailwind/dist/index.d.ts +1 -0
- package/dist/tailwind/dist/{utils → purger/legacy}/purgeCSS.cjs +7 -7
- package/dist/tailwind/dist/{utils → purger/legacy}/purgeCSS.js +6 -6
- package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +193 -0
- package/dist/tailwind/dist/purger/optimized/ast/expressions.js +192 -0
- package/dist/tailwind/dist/purger/optimized/ast/jsx.cjs +20 -0
- package/dist/tailwind/dist/purger/optimized/ast/jsx.js +19 -0
- package/dist/tailwind/dist/purger/optimized/purge.cjs +69 -0
- package/dist/tailwind/dist/purger/optimized/purge.js +66 -0
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +273 -0
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +272 -0
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +408 -0
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +405 -0
- package/dist/tailwind/dist/purger/optimized/utils/files.cjs +27 -0
- package/dist/tailwind/dist/purger/optimized/utils/files.js +24 -0
- package/dist/tailwind/dist/purger/optimized/utils/safelist.cjs +64 -0
- package/dist/tailwind/dist/purger/optimized/utils/safelist.js +60 -0
- package/dist/tailwind/dist/tailwind/utils/getColorModeStyles.cjs +1 -0
- package/dist/tailwind/dist/tailwind/utils/getColorModeStyles.js +1 -0
- package/dist/tailwind/dist/utils/tsMorph.cjs +1 -1
- package/dist/tokens/automation/index.cjs +2 -1
- package/dist/tokens/automation/index.d.cts +2 -1
- package/dist/tokens/automation/index.d.ts +2 -1
- package/dist/tokens/automation/index.js +2 -1
- package/dist/tokens/index.cjs +2 -1
- package/dist/tokens/index.d.cts +2 -1
- package/dist/tokens/index.d.ts +2 -1
- package/dist/tokens/index.js +2 -1
- package/dist/uds/generated/componentData.cjs +2110 -0
- package/dist/uds/generated/componentData.js +1720 -0
- package/dist/uds/generated/tailwindPurge.cjs +24 -24
- package/dist/uds/generated/tailwindPurge.js +24 -24
- package/package.json +1 -1
- /package/dist/tailwind/dist/{utils → purger/legacy}/purgeCSS.d.ts +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
2
|
import { trackEvent } from "../../../cli/dist/utils/analytics.js";
|
|
3
|
+
import { print } from "../../../cli/dist/lib/print.js";
|
|
3
4
|
import { spinStart, spinStop } from "../../../cli/dist/lib/spinner.js";
|
|
4
|
-
import { purge } from "../
|
|
5
|
+
import { purge } from "../purger/legacy/purgeCSS.js";
|
|
6
|
+
import { purgeOptimized } from "../purger/optimized/purge.js";
|
|
5
7
|
|
|
6
8
|
//#region ../tailwind/dist/commands/purge.js
|
|
7
9
|
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
@@ -9,16 +11,44 @@ const makePurgeCommand = (getContext) => ({
|
|
|
9
11
|
name: "purge",
|
|
10
12
|
description: `Purge unused CSS`,
|
|
11
13
|
run: async (props) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
const { entry, output, optimized, config } = props.options;
|
|
15
|
+
const useOptimized = optimized === "true" || optimized === true;
|
|
16
|
+
const { variants, autoVariants, packageJson, generatedPurgeCssData, componentData } = await getContext();
|
|
17
|
+
if (useOptimized) {
|
|
18
|
+
spinStart("Purging CSS with optimized purger...");
|
|
19
|
+
try {
|
|
20
|
+
const result = await purgeOptimized({
|
|
21
|
+
entry: typeof entry === "string" ? entry : void 0,
|
|
22
|
+
output: typeof output === "string" ? output : void 0,
|
|
23
|
+
variants,
|
|
24
|
+
autoVariants,
|
|
25
|
+
componentData
|
|
26
|
+
});
|
|
27
|
+
spinStop("✅", `Purging done (optimized)! Generated ${result.stats.classesGenerated} classes in ${result.stats.timeMs}ms`);
|
|
28
|
+
print(` Files scanned: ${result.stats.filesScanned}`);
|
|
29
|
+
print(` Spreads traced: ${result.stats.spreadsTraced}`);
|
|
30
|
+
print(` Expressions resolved: ${result.stats.expressionsResolved}`);
|
|
31
|
+
return await trackEvent("purge", { optimized: true });
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (error instanceof Error) spinStop("❌", error.message);
|
|
34
|
+
else spinStop("❌", "Purging css failed! Please reach out to #uds-ask channel for support.");
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
spinStart("Purging css started...");
|
|
39
|
+
try {
|
|
40
|
+
await purge(variants, packageJson, generatedPurgeCssData, {
|
|
41
|
+
config: typeof config === "string" ? config : void 0,
|
|
42
|
+
entry: typeof entry === "string" ? entry : void 0,
|
|
43
|
+
output: typeof output === "string" ? output : void 0
|
|
44
|
+
});
|
|
45
|
+
spinStop("✅", "Purging css done!");
|
|
46
|
+
return await trackEvent("purge");
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (error instanceof Error) spinStop("❌", error.message);
|
|
49
|
+
else spinStop("❌", "Purging css failed! Please reach out to #uds-ask channel for support.");
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
}
|
|
22
52
|
}
|
|
23
53
|
}
|
|
24
54
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
-
const require_runtime = require('
|
|
3
|
-
const require_index = require('
|
|
4
|
-
const require_print = require('
|
|
5
|
-
const require_spinner = require('
|
|
6
|
-
const require_tsMorph = require('
|
|
2
|
+
const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_index = require('../../../../css-tokens/dist/index.cjs');
|
|
4
|
+
const require_print = require('../../../../cli/dist/lib/print.cjs');
|
|
5
|
+
const require_spinner = require('../../../../cli/dist/lib/spinner.cjs');
|
|
6
|
+
const require_tsMorph = require('../../utils/tsMorph.cjs');
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
node_path = require_runtime.__toESM(node_path);
|
|
9
9
|
let node_fs = require("node:fs");
|
|
@@ -11,7 +11,7 @@ let ts_morph = require("ts-morph");
|
|
|
11
11
|
let fast_glob = require("fast-glob");
|
|
12
12
|
fast_glob = require_runtime.__toESM(fast_glob);
|
|
13
13
|
|
|
14
|
-
//#region ../tailwind/dist/
|
|
14
|
+
//#region ../tailwind/dist/purger/legacy/purgeCSS.js
|
|
15
15
|
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
16
16
|
const scaleModeToClass = {
|
|
17
17
|
large: require_index.LARGE_SCALE_MODE_CLASSNAME,
|
|
@@ -128,7 +128,7 @@ const isUDSComponent = (component, { componentToVariants }) => {
|
|
|
128
128
|
};
|
|
129
129
|
const saveToFile = (safeList, outputPath) => {
|
|
130
130
|
const fileContent = `
|
|
131
|
-
//! This file is generated by
|
|
131
|
+
//! This file is generated by \`uds purge\` from @yahoo/uds
|
|
132
132
|
//! Do not edit directly
|
|
133
133
|
//! If there is issue with this file please report to #ask-uds
|
|
134
134
|
export const safelist = ${JSON.stringify(safeList)};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
-
import { DARK_COLOR_MODE_CLASSNAME, LARGE_SCALE_MODE_CLASSNAME, LIGHT_COLOR_MODE_CLASSNAME, MEDIUM_SCALE_MODE_CLASSNAME, SMALL_SCALE_MODE_CLASSNAME, XLARGE_SCALE_MODE_CLASSNAME, XSMALL_SCALE_MODE_CLASSNAME, XXLARGE_SCALE_MODE_CLASSNAME, XXXLARGE_SCALE_MODE_CLASSNAME } from "
|
|
3
|
-
import { print } from "
|
|
4
|
-
import { spinStart, spinStop } from "
|
|
5
|
-
import { findReferencesAsJsxElements, getUsedPropsInReference } from "
|
|
2
|
+
import { DARK_COLOR_MODE_CLASSNAME, LARGE_SCALE_MODE_CLASSNAME, LIGHT_COLOR_MODE_CLASSNAME, MEDIUM_SCALE_MODE_CLASSNAME, SMALL_SCALE_MODE_CLASSNAME, XLARGE_SCALE_MODE_CLASSNAME, XSMALL_SCALE_MODE_CLASSNAME, XXLARGE_SCALE_MODE_CLASSNAME, XXXLARGE_SCALE_MODE_CLASSNAME } from "../../../../css-tokens/dist/index.js";
|
|
3
|
+
import { print } from "../../../../cli/dist/lib/print.js";
|
|
4
|
+
import { spinStart, spinStop } from "../../../../cli/dist/lib/spinner.js";
|
|
5
|
+
import { findReferencesAsJsxElements, getUsedPropsInReference } from "../../utils/tsMorph.js";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { Node, Project, SyntaxKind, ts } from "ts-morph";
|
|
9
9
|
import fg from "fast-glob";
|
|
10
10
|
|
|
11
|
-
//#region ../tailwind/dist/
|
|
11
|
+
//#region ../tailwind/dist/purger/legacy/purgeCSS.js
|
|
12
12
|
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
13
13
|
const scaleModeToClass = {
|
|
14
14
|
large: LARGE_SCALE_MODE_CLASSNAME,
|
|
@@ -125,7 +125,7 @@ const isUDSComponent = (component, { componentToVariants }) => {
|
|
|
125
125
|
};
|
|
126
126
|
const saveToFile = (safeList, outputPath) => {
|
|
127
127
|
const fileContent = `
|
|
128
|
-
//! This file is generated by
|
|
128
|
+
//! This file is generated by \`uds purge\` from @yahoo/uds
|
|
129
129
|
//! Do not edit directly
|
|
130
130
|
//! If there is issue with this file please report to #ask-uds
|
|
131
131
|
export const safelist = ${JSON.stringify(safeList)};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
const require_runtime = require('../../../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
let ts_morph = require("ts-morph");
|
|
4
|
+
|
|
5
|
+
//#region ../tailwind/dist/purger/optimized/ast/expressions.js
|
|
6
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
7
|
+
/**
|
|
8
|
+
* Extracts string literal values from an expression.
|
|
9
|
+
*
|
|
10
|
+
* Handles:
|
|
11
|
+
* - Direct string literals: 'value'
|
|
12
|
+
* - Ternary expressions: condition ? 'a' : 'b' -> ['a', 'b']
|
|
13
|
+
* - Variable references: traces back to initializer
|
|
14
|
+
* - Logical expressions: a || 'fallback', a ?? 'default'
|
|
15
|
+
* - Function calls: traces to return statements
|
|
16
|
+
* - Template literals: `value`
|
|
17
|
+
* - As expressions: value as Type
|
|
18
|
+
*
|
|
19
|
+
* @param node The expression node to extract values from
|
|
20
|
+
* @param visited Set of visited nodes to prevent infinite recursion
|
|
21
|
+
* @returns Array of extracted string literal values
|
|
22
|
+
*/
|
|
23
|
+
function extractStringLiterals(node, visited = /* @__PURE__ */ new Set()) {
|
|
24
|
+
if (visited.has(node)) return [];
|
|
25
|
+
visited.add(node);
|
|
26
|
+
const values = [];
|
|
27
|
+
if (ts_morph.Node.isStringLiteral(node)) {
|
|
28
|
+
values.push(node.getLiteralValue());
|
|
29
|
+
return values;
|
|
30
|
+
}
|
|
31
|
+
if (ts_morph.Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
32
|
+
values.push(node.getLiteralValue());
|
|
33
|
+
return values;
|
|
34
|
+
}
|
|
35
|
+
if (ts_morph.Node.isConditionalExpression(node)) {
|
|
36
|
+
values.push(...extractStringLiterals(node.getWhenTrue(), visited));
|
|
37
|
+
values.push(...extractStringLiterals(node.getWhenFalse(), visited));
|
|
38
|
+
return values;
|
|
39
|
+
}
|
|
40
|
+
if (ts_morph.Node.isBinaryExpression(node)) {
|
|
41
|
+
const op = node.getOperatorToken().getText();
|
|
42
|
+
if (op === "||" || op === "??") {
|
|
43
|
+
values.push(...extractStringLiterals(node.getLeft(), visited));
|
|
44
|
+
values.push(...extractStringLiterals(node.getRight(), visited));
|
|
45
|
+
return values;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (ts_morph.Node.isParenthesizedExpression(node)) {
|
|
49
|
+
values.push(...extractStringLiterals(node.getExpression(), visited));
|
|
50
|
+
return values;
|
|
51
|
+
}
|
|
52
|
+
if (ts_morph.Node.isAsExpression(node)) {
|
|
53
|
+
values.push(...extractStringLiterals(node.getExpression(), visited));
|
|
54
|
+
return values;
|
|
55
|
+
}
|
|
56
|
+
if (ts_morph.Node.isPropertyAccessExpression(node)) {
|
|
57
|
+
const typeValues = extractLiteralValuesFromType(node);
|
|
58
|
+
if (typeValues.length > 0) {
|
|
59
|
+
values.push(...typeValues);
|
|
60
|
+
return values;
|
|
61
|
+
}
|
|
62
|
+
const expression = node.getExpression();
|
|
63
|
+
const propertyName = node.getName();
|
|
64
|
+
const baseValues = extractObjectValues(expression, visited);
|
|
65
|
+
for (const objValue of baseValues) if (typeof objValue === "object" && objValue !== null && propertyName in objValue) {
|
|
66
|
+
const propValue = objValue[propertyName];
|
|
67
|
+
if (typeof propValue === "string") values.push(propValue);
|
|
68
|
+
}
|
|
69
|
+
return values;
|
|
70
|
+
}
|
|
71
|
+
if (ts_morph.Node.isElementAccessExpression(node)) {
|
|
72
|
+
const typeValues = extractLiteralValuesFromType(node);
|
|
73
|
+
if (typeValues.length > 0) {
|
|
74
|
+
values.push(...typeValues);
|
|
75
|
+
return values;
|
|
76
|
+
}
|
|
77
|
+
return values;
|
|
78
|
+
}
|
|
79
|
+
if (ts_morph.Node.isCallExpression(node)) {
|
|
80
|
+
const expression = node.getExpression();
|
|
81
|
+
if (ts_morph.Node.isIdentifier(expression)) for (const definition of expression.getDefinitionNodes()) {
|
|
82
|
+
if (ts_morph.Node.isFunctionDeclaration(definition)) for (const returnStmt of definition.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement)) {
|
|
83
|
+
const returnExpr = returnStmt.getExpression();
|
|
84
|
+
if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
|
|
85
|
+
}
|
|
86
|
+
if (ts_morph.Node.isVariableDeclaration(definition)) {
|
|
87
|
+
const initializer = definition.getInitializer();
|
|
88
|
+
if (initializer) values.push(...extractFromFunctionLike(initializer, visited));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return values;
|
|
92
|
+
}
|
|
93
|
+
if (ts_morph.Node.isIdentifier(node)) {
|
|
94
|
+
let foundInitializer = false;
|
|
95
|
+
for (const definition of node.getDefinitionNodes()) {
|
|
96
|
+
if (ts_morph.Node.isVariableDeclaration(definition)) {
|
|
97
|
+
const initializer = definition.getInitializer();
|
|
98
|
+
if (initializer) {
|
|
99
|
+
foundInitializer = true;
|
|
100
|
+
values.push(...extractStringLiterals(initializer, visited));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (ts_morph.Node.isParameterDeclaration(definition)) {
|
|
104
|
+
const initializer = definition.getInitializer();
|
|
105
|
+
if (initializer) {
|
|
106
|
+
foundInitializer = true;
|
|
107
|
+
values.push(...extractStringLiterals(initializer, visited));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (ts_morph.Node.isBindingElement(definition)) {
|
|
111
|
+
const initializer = definition.getInitializer();
|
|
112
|
+
if (initializer) {
|
|
113
|
+
foundInitializer = true;
|
|
114
|
+
values.push(...extractStringLiterals(initializer, visited));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (!foundInitializer && values.length === 0) values.push(...extractLiteralValuesFromType(node));
|
|
119
|
+
return values;
|
|
120
|
+
}
|
|
121
|
+
return values;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Extract string literals from arrow functions or function expressions
|
|
125
|
+
*/
|
|
126
|
+
function extractFromFunctionLike(node, visited) {
|
|
127
|
+
const values = [];
|
|
128
|
+
if (ts_morph.Node.isArrowFunction(node)) {
|
|
129
|
+
const body = node.getBody();
|
|
130
|
+
if (ts_morph.Node.isBlock(body)) for (const returnStmt of body.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement)) {
|
|
131
|
+
const returnExpr = returnStmt.getExpression();
|
|
132
|
+
if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
|
|
133
|
+
}
|
|
134
|
+
else values.push(...extractStringLiterals(body, visited));
|
|
135
|
+
} else if (ts_morph.Node.isFunctionExpression(node)) for (const returnStmt of node.getDescendantsOfKind(ts_morph.SyntaxKind.ReturnStatement)) {
|
|
136
|
+
const returnExpr = returnStmt.getExpression();
|
|
137
|
+
if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
|
|
138
|
+
}
|
|
139
|
+
return values;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Extract object literal values from an expression.
|
|
143
|
+
* Returns an array of all possible object values (for union types or indexed access).
|
|
144
|
+
*/
|
|
145
|
+
function extractObjectValues(node, visited) {
|
|
146
|
+
if (visited.has(node)) return [];
|
|
147
|
+
visited.add(node);
|
|
148
|
+
const values = [];
|
|
149
|
+
if (ts_morph.Node.isObjectLiteralExpression(node)) {
|
|
150
|
+
const obj = {};
|
|
151
|
+
for (const prop of node.getProperties()) if (ts_morph.Node.isPropertyAssignment(prop)) {
|
|
152
|
+
const name = prop.getName();
|
|
153
|
+
const init = prop.getInitializer();
|
|
154
|
+
if (init && ts_morph.Node.isStringLiteral(init)) obj[name] = init.getLiteralValue();
|
|
155
|
+
else if (init && ts_morph.Node.isObjectLiteralExpression(init)) {
|
|
156
|
+
const nestedValues = extractObjectValues(init, visited);
|
|
157
|
+
if (nestedValues.length > 0) obj[name] = nestedValues[0];
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
values.push(obj);
|
|
161
|
+
return values;
|
|
162
|
+
}
|
|
163
|
+
if (ts_morph.Node.isIdentifier(node)) {
|
|
164
|
+
for (const definition of node.getDefinitionNodes()) if (ts_morph.Node.isVariableDeclaration(definition)) {
|
|
165
|
+
const initializer = definition.getInitializer();
|
|
166
|
+
if (initializer) if (ts_morph.Node.isAsExpression(initializer)) {
|
|
167
|
+
const inner = initializer.getExpression();
|
|
168
|
+
values.push(...extractObjectValues(inner, visited));
|
|
169
|
+
} else values.push(...extractObjectValues(initializer, visited));
|
|
170
|
+
}
|
|
171
|
+
return values;
|
|
172
|
+
}
|
|
173
|
+
if (ts_morph.Node.isElementAccessExpression(node)) {
|
|
174
|
+
const baseObjects = extractObjectValues(node.getExpression(), visited);
|
|
175
|
+
for (const obj of baseObjects) if (typeof obj === "object" && obj !== null) for (const value of Object.values(obj)) values.push(value);
|
|
176
|
+
return values;
|
|
177
|
+
}
|
|
178
|
+
return values;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Extract literal values from a TypeScript type (for union types like 'brand' | 'secondary')
|
|
182
|
+
*/
|
|
183
|
+
function extractLiteralValuesFromType(node) {
|
|
184
|
+
const values = [];
|
|
185
|
+
const nodeType = node.getType();
|
|
186
|
+
if (nodeType.isUnion()) {
|
|
187
|
+
for (const unionMember of nodeType.getUnionTypes()) if (unionMember.isStringLiteral()) values.push(unionMember.getLiteralValue());
|
|
188
|
+
} else if (nodeType.isStringLiteral()) values.push(nodeType.getLiteralValue());
|
|
189
|
+
return values;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//#endregion
|
|
193
|
+
exports.extractStringLiterals = extractStringLiterals;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
import { Node, SyntaxKind } from "ts-morph";
|
|
3
|
+
|
|
4
|
+
//#region ../tailwind/dist/purger/optimized/ast/expressions.js
|
|
5
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
6
|
+
/**
|
|
7
|
+
* Extracts string literal values from an expression.
|
|
8
|
+
*
|
|
9
|
+
* Handles:
|
|
10
|
+
* - Direct string literals: 'value'
|
|
11
|
+
* - Ternary expressions: condition ? 'a' : 'b' -> ['a', 'b']
|
|
12
|
+
* - Variable references: traces back to initializer
|
|
13
|
+
* - Logical expressions: a || 'fallback', a ?? 'default'
|
|
14
|
+
* - Function calls: traces to return statements
|
|
15
|
+
* - Template literals: `value`
|
|
16
|
+
* - As expressions: value as Type
|
|
17
|
+
*
|
|
18
|
+
* @param node The expression node to extract values from
|
|
19
|
+
* @param visited Set of visited nodes to prevent infinite recursion
|
|
20
|
+
* @returns Array of extracted string literal values
|
|
21
|
+
*/
|
|
22
|
+
function extractStringLiterals(node, visited = /* @__PURE__ */ new Set()) {
|
|
23
|
+
if (visited.has(node)) return [];
|
|
24
|
+
visited.add(node);
|
|
25
|
+
const values = [];
|
|
26
|
+
if (Node.isStringLiteral(node)) {
|
|
27
|
+
values.push(node.getLiteralValue());
|
|
28
|
+
return values;
|
|
29
|
+
}
|
|
30
|
+
if (Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
31
|
+
values.push(node.getLiteralValue());
|
|
32
|
+
return values;
|
|
33
|
+
}
|
|
34
|
+
if (Node.isConditionalExpression(node)) {
|
|
35
|
+
values.push(...extractStringLiterals(node.getWhenTrue(), visited));
|
|
36
|
+
values.push(...extractStringLiterals(node.getWhenFalse(), visited));
|
|
37
|
+
return values;
|
|
38
|
+
}
|
|
39
|
+
if (Node.isBinaryExpression(node)) {
|
|
40
|
+
const op = node.getOperatorToken().getText();
|
|
41
|
+
if (op === "||" || op === "??") {
|
|
42
|
+
values.push(...extractStringLiterals(node.getLeft(), visited));
|
|
43
|
+
values.push(...extractStringLiterals(node.getRight(), visited));
|
|
44
|
+
return values;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (Node.isParenthesizedExpression(node)) {
|
|
48
|
+
values.push(...extractStringLiterals(node.getExpression(), visited));
|
|
49
|
+
return values;
|
|
50
|
+
}
|
|
51
|
+
if (Node.isAsExpression(node)) {
|
|
52
|
+
values.push(...extractStringLiterals(node.getExpression(), visited));
|
|
53
|
+
return values;
|
|
54
|
+
}
|
|
55
|
+
if (Node.isPropertyAccessExpression(node)) {
|
|
56
|
+
const typeValues = extractLiteralValuesFromType(node);
|
|
57
|
+
if (typeValues.length > 0) {
|
|
58
|
+
values.push(...typeValues);
|
|
59
|
+
return values;
|
|
60
|
+
}
|
|
61
|
+
const expression = node.getExpression();
|
|
62
|
+
const propertyName = node.getName();
|
|
63
|
+
const baseValues = extractObjectValues(expression, visited);
|
|
64
|
+
for (const objValue of baseValues) if (typeof objValue === "object" && objValue !== null && propertyName in objValue) {
|
|
65
|
+
const propValue = objValue[propertyName];
|
|
66
|
+
if (typeof propValue === "string") values.push(propValue);
|
|
67
|
+
}
|
|
68
|
+
return values;
|
|
69
|
+
}
|
|
70
|
+
if (Node.isElementAccessExpression(node)) {
|
|
71
|
+
const typeValues = extractLiteralValuesFromType(node);
|
|
72
|
+
if (typeValues.length > 0) {
|
|
73
|
+
values.push(...typeValues);
|
|
74
|
+
return values;
|
|
75
|
+
}
|
|
76
|
+
return values;
|
|
77
|
+
}
|
|
78
|
+
if (Node.isCallExpression(node)) {
|
|
79
|
+
const expression = node.getExpression();
|
|
80
|
+
if (Node.isIdentifier(expression)) for (const definition of expression.getDefinitionNodes()) {
|
|
81
|
+
if (Node.isFunctionDeclaration(definition)) for (const returnStmt of definition.getDescendantsOfKind(SyntaxKind.ReturnStatement)) {
|
|
82
|
+
const returnExpr = returnStmt.getExpression();
|
|
83
|
+
if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
|
|
84
|
+
}
|
|
85
|
+
if (Node.isVariableDeclaration(definition)) {
|
|
86
|
+
const initializer = definition.getInitializer();
|
|
87
|
+
if (initializer) values.push(...extractFromFunctionLike(initializer, visited));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return values;
|
|
91
|
+
}
|
|
92
|
+
if (Node.isIdentifier(node)) {
|
|
93
|
+
let foundInitializer = false;
|
|
94
|
+
for (const definition of node.getDefinitionNodes()) {
|
|
95
|
+
if (Node.isVariableDeclaration(definition)) {
|
|
96
|
+
const initializer = definition.getInitializer();
|
|
97
|
+
if (initializer) {
|
|
98
|
+
foundInitializer = true;
|
|
99
|
+
values.push(...extractStringLiterals(initializer, visited));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (Node.isParameterDeclaration(definition)) {
|
|
103
|
+
const initializer = definition.getInitializer();
|
|
104
|
+
if (initializer) {
|
|
105
|
+
foundInitializer = true;
|
|
106
|
+
values.push(...extractStringLiterals(initializer, visited));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (Node.isBindingElement(definition)) {
|
|
110
|
+
const initializer = definition.getInitializer();
|
|
111
|
+
if (initializer) {
|
|
112
|
+
foundInitializer = true;
|
|
113
|
+
values.push(...extractStringLiterals(initializer, visited));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (!foundInitializer && values.length === 0) values.push(...extractLiteralValuesFromType(node));
|
|
118
|
+
return values;
|
|
119
|
+
}
|
|
120
|
+
return values;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Extract string literals from arrow functions or function expressions
|
|
124
|
+
*/
|
|
125
|
+
function extractFromFunctionLike(node, visited) {
|
|
126
|
+
const values = [];
|
|
127
|
+
if (Node.isArrowFunction(node)) {
|
|
128
|
+
const body = node.getBody();
|
|
129
|
+
if (Node.isBlock(body)) for (const returnStmt of body.getDescendantsOfKind(SyntaxKind.ReturnStatement)) {
|
|
130
|
+
const returnExpr = returnStmt.getExpression();
|
|
131
|
+
if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
|
|
132
|
+
}
|
|
133
|
+
else values.push(...extractStringLiterals(body, visited));
|
|
134
|
+
} else if (Node.isFunctionExpression(node)) for (const returnStmt of node.getDescendantsOfKind(SyntaxKind.ReturnStatement)) {
|
|
135
|
+
const returnExpr = returnStmt.getExpression();
|
|
136
|
+
if (returnExpr) values.push(...extractStringLiterals(returnExpr, visited));
|
|
137
|
+
}
|
|
138
|
+
return values;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Extract object literal values from an expression.
|
|
142
|
+
* Returns an array of all possible object values (for union types or indexed access).
|
|
143
|
+
*/
|
|
144
|
+
function extractObjectValues(node, visited) {
|
|
145
|
+
if (visited.has(node)) return [];
|
|
146
|
+
visited.add(node);
|
|
147
|
+
const values = [];
|
|
148
|
+
if (Node.isObjectLiteralExpression(node)) {
|
|
149
|
+
const obj = {};
|
|
150
|
+
for (const prop of node.getProperties()) if (Node.isPropertyAssignment(prop)) {
|
|
151
|
+
const name = prop.getName();
|
|
152
|
+
const init = prop.getInitializer();
|
|
153
|
+
if (init && Node.isStringLiteral(init)) obj[name] = init.getLiteralValue();
|
|
154
|
+
else if (init && Node.isObjectLiteralExpression(init)) {
|
|
155
|
+
const nestedValues = extractObjectValues(init, visited);
|
|
156
|
+
if (nestedValues.length > 0) obj[name] = nestedValues[0];
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
values.push(obj);
|
|
160
|
+
return values;
|
|
161
|
+
}
|
|
162
|
+
if (Node.isIdentifier(node)) {
|
|
163
|
+
for (const definition of node.getDefinitionNodes()) if (Node.isVariableDeclaration(definition)) {
|
|
164
|
+
const initializer = definition.getInitializer();
|
|
165
|
+
if (initializer) if (Node.isAsExpression(initializer)) {
|
|
166
|
+
const inner = initializer.getExpression();
|
|
167
|
+
values.push(...extractObjectValues(inner, visited));
|
|
168
|
+
} else values.push(...extractObjectValues(initializer, visited));
|
|
169
|
+
}
|
|
170
|
+
return values;
|
|
171
|
+
}
|
|
172
|
+
if (Node.isElementAccessExpression(node)) {
|
|
173
|
+
const baseObjects = extractObjectValues(node.getExpression(), visited);
|
|
174
|
+
for (const obj of baseObjects) if (typeof obj === "object" && obj !== null) for (const value of Object.values(obj)) values.push(value);
|
|
175
|
+
return values;
|
|
176
|
+
}
|
|
177
|
+
return values;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Extract literal values from a TypeScript type (for union types like 'brand' | 'secondary')
|
|
181
|
+
*/
|
|
182
|
+
function extractLiteralValuesFromType(node) {
|
|
183
|
+
const values = [];
|
|
184
|
+
const nodeType = node.getType();
|
|
185
|
+
if (nodeType.isUnion()) {
|
|
186
|
+
for (const unionMember of nodeType.getUnionTypes()) if (unionMember.isStringLiteral()) values.push(unionMember.getLiteralValue());
|
|
187
|
+
} else if (nodeType.isStringLiteral()) values.push(nodeType.getLiteralValue());
|
|
188
|
+
return values;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
//#endregion
|
|
192
|
+
export { extractStringLiterals };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
const require_runtime = require('../../../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
let ts_morph = require("ts-morph");
|
|
4
|
+
|
|
5
|
+
//#region ../tailwind/dist/purger/optimized/ast/jsx.js
|
|
6
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
7
|
+
/**
|
|
8
|
+
* Find all JSX usages of a component from its identifier
|
|
9
|
+
*/
|
|
10
|
+
function findJsxReferences(identifier) {
|
|
11
|
+
const elements = [];
|
|
12
|
+
for (const reference of identifier.findReferencesAsNodes()) {
|
|
13
|
+
const node = reference.getFirstAncestor((n) => ts_morph.Node.isJsxOpeningElement(n) || ts_morph.Node.isJsxSelfClosingElement(n));
|
|
14
|
+
if (node && (ts_morph.Node.isJsxOpeningElement(node) || ts_morph.Node.isJsxSelfClosingElement(node))) elements.push(node);
|
|
15
|
+
}
|
|
16
|
+
return elements;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
exports.findJsxReferences = findJsxReferences;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
import { Node, SyntaxKind } from "ts-morph";
|
|
3
|
+
|
|
4
|
+
//#region ../tailwind/dist/purger/optimized/ast/jsx.js
|
|
5
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
6
|
+
/**
|
|
7
|
+
* Find all JSX usages of a component from its identifier
|
|
8
|
+
*/
|
|
9
|
+
function findJsxReferences(identifier) {
|
|
10
|
+
const elements = [];
|
|
11
|
+
for (const reference of identifier.findReferencesAsNodes()) {
|
|
12
|
+
const node = reference.getFirstAncestor((n) => Node.isJsxOpeningElement(n) || Node.isJsxSelfClosingElement(n));
|
|
13
|
+
if (node && (Node.isJsxOpeningElement(node) || Node.isJsxSelfClosingElement(node))) elements.push(node);
|
|
14
|
+
}
|
|
15
|
+
return elements;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { findJsxReferences };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_purgeFromCode = require('./purgeFromCode.cjs');
|
|
4
|
+
const require_files = require('./utils/files.cjs');
|
|
5
|
+
const require_safelist = require('./utils/safelist.cjs');
|
|
6
|
+
let node_path = require("node:path");
|
|
7
|
+
node_path = require_runtime.__toESM(node_path);
|
|
8
|
+
let node_fs = require("node:fs");
|
|
9
|
+
node_fs = require_runtime.__toESM(node_fs);
|
|
10
|
+
|
|
11
|
+
//#region ../tailwind/dist/purger/optimized/purge.js
|
|
12
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
13
|
+
const warnedLocations = /* @__PURE__ */ new Set();
|
|
14
|
+
/**
|
|
15
|
+
* Clear warned locations (call at start of new purge run)
|
|
16
|
+
*/
|
|
17
|
+
function clearWarnings() {
|
|
18
|
+
warnedLocations.clear();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Main purge function - optimized version
|
|
22
|
+
*
|
|
23
|
+
* Uses purgeFromCodeOptimized internally to ensure consistent behavior
|
|
24
|
+
* between CLI and playground.
|
|
25
|
+
*/
|
|
26
|
+
async function purgeOptimized(options) {
|
|
27
|
+
const { entry = "/src/", output = "dist/safelist.ts", colorModes = ["dark"], variants, autoVariants, componentData } = options;
|
|
28
|
+
const startTime = performance.now();
|
|
29
|
+
clearWarnings();
|
|
30
|
+
const workspaceDir = process.env.PWD ?? process.cwd();
|
|
31
|
+
const files = await require_files.scanForFiles(entry);
|
|
32
|
+
const allClasses = [];
|
|
33
|
+
const allImports = /* @__PURE__ */ new Set();
|
|
34
|
+
const allComponents = /* @__PURE__ */ new Set();
|
|
35
|
+
const stats = {
|
|
36
|
+
filesScanned: files.length,
|
|
37
|
+
timeMs: 0,
|
|
38
|
+
classesGenerated: 0,
|
|
39
|
+
spreadsTraced: 0,
|
|
40
|
+
expressionsResolved: 0
|
|
41
|
+
};
|
|
42
|
+
for (const filePath of files) {
|
|
43
|
+
const result = await require_purgeFromCode.purgeFromCodeOptimized(node_fs.default.readFileSync(filePath, "utf-8"), {
|
|
44
|
+
colorModes,
|
|
45
|
+
variants,
|
|
46
|
+
autoVariants,
|
|
47
|
+
componentData
|
|
48
|
+
});
|
|
49
|
+
allClasses.push(...result.safelist);
|
|
50
|
+
result.imports.forEach((imp) => allImports.add(imp));
|
|
51
|
+
result.components.forEach((comp) => allComponents.add(comp));
|
|
52
|
+
stats.spreadsTraced += result.stats.spreadsTraced;
|
|
53
|
+
stats.expressionsResolved += result.stats.expressionsResolved;
|
|
54
|
+
}
|
|
55
|
+
allClasses.push(...require_safelist.getThemeAndScaleClasses(colorModes));
|
|
56
|
+
const finalSafelist = require_safelist.deduplicateSafelist(allClasses);
|
|
57
|
+
await require_safelist.saveSafelistToFile(finalSafelist, node_path.default.join(workspaceDir, output));
|
|
58
|
+
stats.timeMs = Math.round(performance.now() - startTime);
|
|
59
|
+
stats.classesGenerated = finalSafelist.length;
|
|
60
|
+
return {
|
|
61
|
+
safelist: finalSafelist,
|
|
62
|
+
imports: [...allImports],
|
|
63
|
+
components: [...allComponents],
|
|
64
|
+
stats
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
69
|
+
exports.purgeOptimized = purgeOptimized;
|