@yahoo/uds 3.96.0 → 3.97.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/cli/commands/purge.cjs +26 -0
- package/dist/cli/commands/purge.d.cts +15 -0
- package/dist/cli/commands/purge.d.ts +15 -0
- package/dist/cli/commands/purge.js +25 -0
- package/dist/cli/commands/sync.cjs +96 -0
- package/dist/cli/commands/sync.d.cts +16 -0
- package/dist/cli/commands/sync.d.ts +16 -0
- package/dist/cli/commands/sync.js +93 -0
- package/dist/cli/commands/utils/purgeCSS.cjs +258 -0
- package/dist/cli/commands/utils/purgeCSS.d.cts +59 -0
- package/dist/cli/commands/utils/purgeCSS.d.ts +59 -0
- package/dist/cli/commands/utils/purgeCSS.js +244 -0
- package/dist/cli/commands/utils/sortKeys.cjs +23 -0
- package/dist/cli/commands/utils/sortKeys.d.cts +5 -0
- package/dist/cli/commands/utils/sortKeys.d.ts +5 -0
- package/dist/cli/commands/utils/sortKeys.js +21 -0
- package/dist/cli/commands/version.cjs +21 -0
- package/dist/cli/commands/version.d.cts +7 -0
- package/dist/cli/commands/version.d.ts +7 -0
- package/dist/cli/commands/version.js +18 -0
- package/dist/cli/dist/cli.cjs +78 -0
- package/dist/cli/dist/cli.js +78 -0
- package/dist/cli/dist/commands/codemod/codemod.cjs +81 -0
- package/dist/cli/dist/commands/codemod/codemod.js +79 -0
- package/dist/cli/dist/commands/editor-rules.cjs +107 -0
- package/dist/cli/dist/commands/editor-rules.js +106 -0
- package/dist/cli/dist/lib/args.cjs +32 -0
- package/dist/cli/dist/lib/args.js +31 -0
- package/dist/cli/dist/lib/colors.cjs +26 -0
- package/dist/cli/dist/lib/colors.js +18 -0
- package/dist/cli/dist/lib/print.cjs +13 -0
- package/dist/cli/dist/lib/print.js +12 -0
- package/dist/cli/dist/lib/spinner.cjs +59 -0
- package/dist/cli/dist/lib/spinner.js +57 -0
- package/dist/cli/dist/utils/analytics.cjs +33 -0
- package/dist/cli/dist/utils/analytics.js +32 -0
- package/dist/cli/dist/utils/getCommandHelp.cjs +58 -0
- package/dist/cli/dist/utils/getCommandHelp.js +56 -0
- package/dist/cli/dist/utils/getDirChoices.cjs +27 -0
- package/dist/cli/dist/utils/getDirChoices.js +25 -0
- package/dist/cli/dist/utils/rules/config.cjs +56 -0
- package/dist/cli/dist/utils/rules/config.js +53 -0
- package/dist/cli/runner.cjs +14 -0
- package/dist/cli/runner.d.cts +2 -0
- package/dist/cli/runner.d.ts +2 -0
- package/dist/cli/runner.js +14 -0
- package/dist/styles/styler.d.cts +32 -32
- package/dist/styles/styler.d.ts +32 -32
- package/dist/tailwind/tailwindPlugin.d.cts +1 -1
- package/dist/tailwind/tailwindPlugin.d.ts +1 -1
- package/dist/tailwind/utils/getShadowStyles.d.cts +4 -4
- package/dist/tailwind/utils/getShadowStyles.d.ts +4 -4
- package/dist/uds/scripts/utils/tsMorph.cjs +1 -1
- package/dist/uds/scripts/utils/tsMorph.d.cts +1 -1
- package/dist/uds/scripts/utils/tsMorph.d.ts +1 -1
- package/package.json +5 -8
- package/uds.js +11 -1
- package/dist/cli.mjs +0 -897
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
|
|
2
|
+
import { JsxOpeningElement, JsxSelfClosingElement, Project } from "ts-morph";
|
|
3
|
+
|
|
4
|
+
//#region src/cli/commands/utils/purgeCSS.d.ts
|
|
5
|
+
type SafeList = string[];
|
|
6
|
+
type ImportsList = string[];
|
|
7
|
+
type Files = string[];
|
|
8
|
+
declare const getFiles: (entry: string) => Promise<Files>;
|
|
9
|
+
/**
|
|
10
|
+
* Find all JSX references for a named import.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const references = findNamedImportReferences(project, '@yahoo/uds', 'HStack')
|
|
14
|
+
*/
|
|
15
|
+
declare function findNamedImportReferences(project: Project, moduleSpecifierValue: string, namedImportName: string): (JsxOpeningElement | JsxSelfClosingElement)[];
|
|
16
|
+
/**
|
|
17
|
+
* Given a file it returns the list of imports from @yahoo/uds
|
|
18
|
+
*/
|
|
19
|
+
declare const parseFiles: (project: Project, files: Files) => ImportsList;
|
|
20
|
+
declare const getTailwindSafelist: (project: Project, componentList: string[]) => SafeList;
|
|
21
|
+
/**
|
|
22
|
+
* Get the used props for a given component.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const usedProps = getUsedProps(project, 'HStack');
|
|
26
|
+
*/
|
|
27
|
+
declare const getUsedProps: (project: Project, component: string) => Array<[string, string[]]>;
|
|
28
|
+
declare const isUDSComponent: (component: string) => boolean;
|
|
29
|
+
declare const getComponentsToConvertToTW: (udsImport: ImportsList) => string[];
|
|
30
|
+
/**
|
|
31
|
+
* Get the classes that corresponds to the used modes
|
|
32
|
+
*/
|
|
33
|
+
declare const getClassesForEnabledThemesAndScales: () => string[];
|
|
34
|
+
/**
|
|
35
|
+
* Scan the source code for all `getStyles` references
|
|
36
|
+
*
|
|
37
|
+
* Note: This currently only works if we are passing a literal object to getStyles.
|
|
38
|
+
*
|
|
39
|
+
* Explanation: They we are able to enfer what css to include is by looking at the properties of the object passed.
|
|
40
|
+
* If something other than an object is passed, we can fallback on the Type, but that would require handling
|
|
41
|
+
* a lot of edge cases (function return type, spread operator, ternary, ...) and each one of these cases will
|
|
42
|
+
* most likely have a sub case. Falling back to the Type will complicate the code a lot is error prone as there
|
|
43
|
+
* is only so much info we can get out of the types as the Users are free to use `any` on their project which will
|
|
44
|
+
* provide no value for us. Hence why having a literal object passed is the best and probably the only sane way
|
|
45
|
+
* to go about this.
|
|
46
|
+
*/
|
|
47
|
+
declare const scanGetStylesReferences: (project: Project) => Map<string, Set<string>>;
|
|
48
|
+
type PurgeOptions = {
|
|
49
|
+
config?: string;
|
|
50
|
+
output?: string;
|
|
51
|
+
entry?: string;
|
|
52
|
+
};
|
|
53
|
+
declare function purge({
|
|
54
|
+
config: configPath,
|
|
55
|
+
output: output,
|
|
56
|
+
entry: entry
|
|
57
|
+
}: PurgeOptions): Promise<void>;
|
|
58
|
+
//#endregion
|
|
59
|
+
export { type PurgeOptions, findNamedImportReferences, getClassesForEnabledThemesAndScales, getComponentsToConvertToTW, getFiles, getTailwindSafelist, getUsedProps, isUDSComponent, parseFiles, purge, scanGetStylesReferences };
|
|
@@ -0,0 +1,244 @@
|
|
|
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 "../../../css-tokens/dist/index.js";
|
|
3
|
+
import { variants } from "../../../styles/variants.js";
|
|
4
|
+
import { print } from "../../dist/lib/print.js";
|
|
5
|
+
import { spinStart, spinStop } from "../../dist/lib/spinner.js";
|
|
6
|
+
import { componentToTwClasses, componentToVariants, componentsDependencies, variantsList } from "../../../uds/generated/tailwindPurge.js";
|
|
7
|
+
import { findReferencesAsJsxElements, getUsedPropsInReference } from "../../../uds/scripts/utils/tsMorph.js";
|
|
8
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import pkg from "@yahoo/uds/package.json" with { type: "json" };
|
|
11
|
+
import fg from "fast-glob";
|
|
12
|
+
import { Node, Project, SyntaxKind, ts } from "ts-morph";
|
|
13
|
+
|
|
14
|
+
//#region src/cli/commands/utils/purgeCSS.ts
|
|
15
|
+
const scaleModeToClass = {
|
|
16
|
+
large: LARGE_SCALE_MODE_CLASSNAME,
|
|
17
|
+
medium: MEDIUM_SCALE_MODE_CLASSNAME,
|
|
18
|
+
small: SMALL_SCALE_MODE_CLASSNAME,
|
|
19
|
+
xLarge: XLARGE_SCALE_MODE_CLASSNAME,
|
|
20
|
+
xSmall: XSMALL_SCALE_MODE_CLASSNAME,
|
|
21
|
+
xxLarge: XXLARGE_SCALE_MODE_CLASSNAME,
|
|
22
|
+
xxxLarge: XXXLARGE_SCALE_MODE_CLASSNAME
|
|
23
|
+
};
|
|
24
|
+
const colorModeToClass = {
|
|
25
|
+
dark: DARK_COLOR_MODE_CLASSNAME,
|
|
26
|
+
light: LIGHT_COLOR_MODE_CLASSNAME
|
|
27
|
+
};
|
|
28
|
+
const getFiles = async (entry) => {
|
|
29
|
+
try {
|
|
30
|
+
const workspaceDir = process.env.PWD || process.cwd();
|
|
31
|
+
if (!workspaceDir) throw new Error("Workspace directory not found.");
|
|
32
|
+
return await fg(["**/*.jsx", "**/*.tsx"], {
|
|
33
|
+
cwd: path.join(workspaceDir, entry),
|
|
34
|
+
absolute: true
|
|
35
|
+
});
|
|
36
|
+
} catch {
|
|
37
|
+
throw new Error(`Couldn't find the entry directory: ${entry}. Please make sure it exists.`);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Find all JSX references for a named import.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* const references = findNamedImportReferences(project, '@yahoo/uds', 'HStack')
|
|
45
|
+
*/
|
|
46
|
+
function findNamedImportReferences(project, moduleSpecifierValue, namedImportName) {
|
|
47
|
+
const references = [];
|
|
48
|
+
for (const sourceFile of project.getSourceFiles()) for (const importDeclaration of sourceFile.getImportDeclarations()) if (importDeclaration.getModuleSpecifierValue() === moduleSpecifierValue) {
|
|
49
|
+
for (const namedImport of importDeclaration.getNamedImports()) if (namedImport.getName() === namedImportName) {
|
|
50
|
+
const identifier = namedImport.getFirstDescendantByKindOrThrow(ts.SyntaxKind.Identifier);
|
|
51
|
+
references.push(...findReferencesAsJsxElements(identifier));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return references;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Given a file it returns the list of imports from @yahoo/uds
|
|
58
|
+
*/
|
|
59
|
+
const parseFiles = (project, files) => {
|
|
60
|
+
const importsSet = /* @__PURE__ */ new Set();
|
|
61
|
+
files.map((file) => {
|
|
62
|
+
return project.getSourceFile(file)?.getImportDeclarations().filter((declaration) => {
|
|
63
|
+
return declaration.getModuleSpecifier().getText().includes("@yahoo/uds") || declaration.getModuleSpecifier().getText().includes("@yahoo/uds/experimental");
|
|
64
|
+
}).map((declaration) => {
|
|
65
|
+
return declaration.getNamedImports().map((namedImport) => namedImport.getName());
|
|
66
|
+
}).flat() ?? [];
|
|
67
|
+
}).flat().forEach((item) => {
|
|
68
|
+
if (!importsSet.has(item)) importsSet.add(item);
|
|
69
|
+
});
|
|
70
|
+
return Array.from(importsSet);
|
|
71
|
+
};
|
|
72
|
+
const getTailwindSafelist = (project, componentList) => {
|
|
73
|
+
const safeList = [];
|
|
74
|
+
const validVariants = new Set(variantsList);
|
|
75
|
+
const usedProps = /* @__PURE__ */ new Map();
|
|
76
|
+
componentList.forEach((component) => {
|
|
77
|
+
if (isUDSComponent(component)) {
|
|
78
|
+
componentToVariants[component].forEach(([propName, usedValues]) => {
|
|
79
|
+
if (validVariants.has(propName)) {
|
|
80
|
+
const options = usedProps.get(propName) ?? /* @__PURE__ */ new Set();
|
|
81
|
+
usedValues.forEach((val) => options.add(val));
|
|
82
|
+
usedProps.set(propName, options);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
getUsedProps(project, component).forEach(([propName, usedValues]) => {
|
|
86
|
+
if (validVariants.has(propName)) {
|
|
87
|
+
if (usedValues.length === 0) usedValues = Object.keys(variants[propName]);
|
|
88
|
+
const options = usedProps.get(propName) ?? /* @__PURE__ */ new Set();
|
|
89
|
+
usedValues.forEach((val) => options.add(val));
|
|
90
|
+
usedProps.set(propName, options);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
safeList.push(...componentToTwClasses[component].replaceAll("\\", "").split(" "));
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
for (const [propName, usedValues] of usedProps) {
|
|
97
|
+
const variantGroup = variants[propName];
|
|
98
|
+
if (variantGroup) usedValues.forEach((option) => {
|
|
99
|
+
const variantClass = variantGroup[option];
|
|
100
|
+
if (variantClass) safeList.push(variantClass.replaceAll("\\", ""));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
for (const [variant, variantOptions] of scanGetStylesReferences(project)) {
|
|
104
|
+
const variantGroup = variants[variant];
|
|
105
|
+
if (variantGroup) variantOptions.forEach((option) => {
|
|
106
|
+
const variantClass = variantGroup[option];
|
|
107
|
+
if (variantClass) safeList.push(variantClass.replaceAll("\\", ""));
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return Array.from(new Set(safeList)).filter(Boolean);
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Get the used props for a given component.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* const usedProps = getUsedProps(project, 'HStack');
|
|
117
|
+
*/
|
|
118
|
+
const getUsedProps = (project, component) => {
|
|
119
|
+
const references = [];
|
|
120
|
+
references.push(...findNamedImportReferences(project, pkg.name, component));
|
|
121
|
+
references.push(...findNamedImportReferences(project, `${pkg.name}/experimental`, component));
|
|
122
|
+
return references.map((reference) => getUsedPropsInReference(reference)).flat();
|
|
123
|
+
};
|
|
124
|
+
const isUDSComponent = (component) => {
|
|
125
|
+
return !!componentToVariants[component];
|
|
126
|
+
};
|
|
127
|
+
const saveToFile = (safeList, outputPath) => {
|
|
128
|
+
const fileContent = `
|
|
129
|
+
//! This file is generated by purgeCSS.ts from @yahoo/uds
|
|
130
|
+
//! Do not edit directly
|
|
131
|
+
//! If there is issue with this file please report to #ask-uds
|
|
132
|
+
export const safelist = ${JSON.stringify(safeList)};
|
|
133
|
+
`;
|
|
134
|
+
mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
135
|
+
writeFileSync(outputPath, fileContent);
|
|
136
|
+
};
|
|
137
|
+
const getComponentsToConvertToTW = (udsImport) => {
|
|
138
|
+
const components = udsImport.filter((importedItem) => !!componentToVariants[importedItem]);
|
|
139
|
+
const set = /* @__PURE__ */ new Set();
|
|
140
|
+
components.forEach((component) => {
|
|
141
|
+
if (!set.has(component)) set.add(component);
|
|
142
|
+
if (componentsDependencies[component]) componentsDependencies[component].forEach((dependent) => {
|
|
143
|
+
if (!set.has(dependent)) set.add(dependent);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
return Array.from(set);
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Get the classes that corresponds to the used modes
|
|
150
|
+
*/
|
|
151
|
+
const getClassesForEnabledThemesAndScales = () => {
|
|
152
|
+
const classes = [];
|
|
153
|
+
if (process.env.ENABLED_SCALE_AND_COLOR_MODES) process.env.ENABLED_SCALE_AND_COLOR_MODES.split(",").map((mode) => {
|
|
154
|
+
mode = mode.trim();
|
|
155
|
+
if (colorModeToClass[mode]) classes.push(colorModeToClass[mode]);
|
|
156
|
+
else if (scaleModeToClass[mode]) classes.push(scaleModeToClass[mode]);
|
|
157
|
+
});
|
|
158
|
+
else {
|
|
159
|
+
classes.push(colorModeToClass.dark);
|
|
160
|
+
classes.push(colorModeToClass.light);
|
|
161
|
+
classes.push(scaleModeToClass.large);
|
|
162
|
+
}
|
|
163
|
+
return classes;
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Scan the source code for all `getStyles` references
|
|
167
|
+
*
|
|
168
|
+
* Note: This currently only works if we are passing a literal object to getStyles.
|
|
169
|
+
*
|
|
170
|
+
* Explanation: They we are able to enfer what css to include is by looking at the properties of the object passed.
|
|
171
|
+
* If something other than an object is passed, we can fallback on the Type, but that would require handling
|
|
172
|
+
* a lot of edge cases (function return type, spread operator, ternary, ...) and each one of these cases will
|
|
173
|
+
* most likely have a sub case. Falling back to the Type will complicate the code a lot is error prone as there
|
|
174
|
+
* is only so much info we can get out of the types as the Users are free to use `any` on their project which will
|
|
175
|
+
* provide no value for us. Hence why having a literal object passed is the best and probably the only sane way
|
|
176
|
+
* to go about this.
|
|
177
|
+
*/
|
|
178
|
+
const scanGetStylesReferences = (project) => {
|
|
179
|
+
const references = [];
|
|
180
|
+
for (const sourceFile of project.getSourceFiles()) for (const importDeclaration of sourceFile.getImportDeclarations()) if (importDeclaration.getModuleSpecifierValue() === pkg.name) {
|
|
181
|
+
for (const namedImport of importDeclaration.getNamedImports()) if (namedImport.getName() === "getStyles") {
|
|
182
|
+
const identifier = namedImport.getFirstDescendantByKindOrThrow(ts.SyntaxKind.Identifier);
|
|
183
|
+
for (const reference of identifier.findReferencesAsNodes()) {
|
|
184
|
+
const node = reference.getFirstAncestor((node) => {
|
|
185
|
+
return Node.isCallExpression(node);
|
|
186
|
+
});
|
|
187
|
+
if (node) references.push(node);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const usedProps = /* @__PURE__ */ new Map();
|
|
192
|
+
for (const reference of references) {
|
|
193
|
+
const objectLiteralExpression = reference.getFirstChildByKindOrThrow(SyntaxKind.ObjectLiteralExpression);
|
|
194
|
+
const propertyAssignments = objectLiteralExpression.getDescendantsOfKind(SyntaxKind.PropertyAssignment);
|
|
195
|
+
const shorthandPropertyAssignments = objectLiteralExpression.getDescendantsOfKind(SyntaxKind.ShorthandPropertyAssignment);
|
|
196
|
+
propertyAssignments.forEach((propertyAssigment) => {
|
|
197
|
+
const identifier = propertyAssigment.getFirstChildByKind(SyntaxKind.Identifier)?.getText();
|
|
198
|
+
const stringLiteral = propertyAssigment.getFirstChildByKind(SyntaxKind.StringLiteral)?.getLiteralText();
|
|
199
|
+
if (identifier && !stringLiteral) {
|
|
200
|
+
const fallback = !!variants[identifier] ? Object.keys(variants[identifier]) : [];
|
|
201
|
+
usedProps.set(identifier, new Set(fallback));
|
|
202
|
+
}
|
|
203
|
+
if (identifier && stringLiteral) {
|
|
204
|
+
let options;
|
|
205
|
+
if (usedProps.has(identifier)) options = usedProps.get(identifier);
|
|
206
|
+
else options = /* @__PURE__ */ new Set();
|
|
207
|
+
options.add(stringLiteral);
|
|
208
|
+
usedProps.set(identifier, options);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
shorthandPropertyAssignments.forEach((propertyAssigment) => {
|
|
212
|
+
const identifier = propertyAssigment.getFirstChildByKind(SyntaxKind.Identifier)?.getText();
|
|
213
|
+
if (identifier) usedProps.set(identifier, /* @__PURE__ */ new Set());
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return usedProps;
|
|
217
|
+
};
|
|
218
|
+
async function purge({ config: configPath = process.env.UDS_OUT_FILE ?? "./uds.config.ts", output = "dist/safelist.ts", entry = "/src/" }) {
|
|
219
|
+
const workspaceDir = process.env.PWD || process.cwd();
|
|
220
|
+
if (!workspaceDir) throw new Error("Workspace directory not found.");
|
|
221
|
+
const project = new Project({ tsConfigFilePath: path.join(workspaceDir, "/tsconfig.json") });
|
|
222
|
+
const outputFilePath = path.join(workspaceDir, output);
|
|
223
|
+
const configAbsolutePath = path.join(workspaceDir, configPath);
|
|
224
|
+
try {
|
|
225
|
+
await import(configAbsolutePath);
|
|
226
|
+
} catch {
|
|
227
|
+
throw new Error("Couldn't load the UDS config. Make sure you have uds.config.ts in the root of your project.");
|
|
228
|
+
}
|
|
229
|
+
spinStart("Getting used UDS components...");
|
|
230
|
+
print("Loading the project...");
|
|
231
|
+
const files = await getFiles(entry);
|
|
232
|
+
print("Going through the imports...");
|
|
233
|
+
const udsImports = parseFiles(project, files);
|
|
234
|
+
print("Finding all the components imported from UDS...");
|
|
235
|
+
const udsComponents = getComponentsToConvertToTW(udsImports);
|
|
236
|
+
print("🧑🍳 Cooking...");
|
|
237
|
+
const safeList = getTailwindSafelist(project, udsComponents);
|
|
238
|
+
const themesAndScalesClasses = getClassesForEnabledThemesAndScales();
|
|
239
|
+
saveToFile(safeList.concat(themesAndScalesClasses), outputFilePath);
|
|
240
|
+
spinStop("Generated your safelist!");
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
//#endregion
|
|
244
|
+
export { findNamedImportReferences, getClassesForEnabledThemesAndScales, getComponentsToConvertToTW, getFiles, getTailwindSafelist, getUsedProps, isUDSComponent, parseFiles, purge, scanGetStylesReferences };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
3
|
+
|
|
4
|
+
//#region src/cli/commands/utils/sortKeys.ts
|
|
5
|
+
function sortKeys(unsortedObj) {
|
|
6
|
+
const sortedObj = {};
|
|
7
|
+
if (!unsortedObj || typeof unsortedObj !== "object") return unsortedObj;
|
|
8
|
+
const keys = Object.keys(unsortedObj).sort();
|
|
9
|
+
for (var index in keys) {
|
|
10
|
+
const key = keys[index];
|
|
11
|
+
const value = unsortedObj[key];
|
|
12
|
+
if (typeof value === "object") if (Array.isArray(value)) sortedObj[key] = value.map((item) => {
|
|
13
|
+
if (typeof item === "object") return sortKeys(item);
|
|
14
|
+
return item;
|
|
15
|
+
});
|
|
16
|
+
else sortedObj[key] = sortKeys(value);
|
|
17
|
+
else sortedObj[key] = value;
|
|
18
|
+
}
|
|
19
|
+
return sortedObj;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
exports.sortKeys = sortKeys;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
//#region src/cli/commands/utils/sortKeys.ts
|
|
3
|
+
function sortKeys(unsortedObj) {
|
|
4
|
+
const sortedObj = {};
|
|
5
|
+
if (!unsortedObj || typeof unsortedObj !== "object") return unsortedObj;
|
|
6
|
+
const keys = Object.keys(unsortedObj).sort();
|
|
7
|
+
for (var index in keys) {
|
|
8
|
+
const key = keys[index];
|
|
9
|
+
const value = unsortedObj[key];
|
|
10
|
+
if (typeof value === "object") if (Array.isArray(value)) sortedObj[key] = value.map((item) => {
|
|
11
|
+
if (typeof item === "object") return sortKeys(item);
|
|
12
|
+
return item;
|
|
13
|
+
});
|
|
14
|
+
else sortedObj[key] = sortKeys(value);
|
|
15
|
+
else sortedObj[key] = value;
|
|
16
|
+
}
|
|
17
|
+
return sortedObj;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { sortKeys };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
3
|
+
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
4
|
+
const require_analytics = require('../dist/utils/analytics.cjs');
|
|
5
|
+
const require_print = require('../dist/lib/print.cjs');
|
|
6
|
+
let _yahoo_uds_package_json = require("@yahoo/uds/package.json");
|
|
7
|
+
_yahoo_uds_package_json = require_runtime.__toESM(_yahoo_uds_package_json);
|
|
8
|
+
|
|
9
|
+
//#region src/cli/commands/version.ts
|
|
10
|
+
const version = _yahoo_uds_package_json.default.version;
|
|
11
|
+
const versionCommand = {
|
|
12
|
+
name: "version",
|
|
13
|
+
description: `Display CLI version (${version})`,
|
|
14
|
+
run: async () => {
|
|
15
|
+
require_print.print(version);
|
|
16
|
+
await require_analytics.trackEvent("version", { version });
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
exports.versionCommand = versionCommand;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
import { trackEvent } from "../dist/utils/analytics.js";
|
|
3
|
+
import { print } from "../dist/lib/print.js";
|
|
4
|
+
import pkg from "@yahoo/uds/package.json" with { type: "json" };
|
|
5
|
+
|
|
6
|
+
//#region src/cli/commands/version.ts
|
|
7
|
+
const version = pkg.version;
|
|
8
|
+
const versionCommand = {
|
|
9
|
+
name: "version",
|
|
10
|
+
description: `Display CLI version (${version})`,
|
|
11
|
+
run: async () => {
|
|
12
|
+
print(version);
|
|
13
|
+
await trackEvent("version", { version });
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { versionCommand };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
const require_analytics = require('./utils/analytics.cjs');
|
|
3
|
+
const require_args = require('./lib/args.cjs');
|
|
4
|
+
const require_colors = require('./lib/colors.cjs');
|
|
5
|
+
const require_print = require('./lib/print.cjs');
|
|
6
|
+
const require_getCommandHelp = require('./utils/getCommandHelp.cjs');
|
|
7
|
+
const require_codemod = require('./commands/codemod/codemod.cjs');
|
|
8
|
+
const require_editor_rules = require('./commands/editor-rules.cjs');
|
|
9
|
+
|
|
10
|
+
//#region ../cli/dist/cli.mjs
|
|
11
|
+
/*! © 2026 Yahoo, Inc. UDS CLI v0.0.0-development */
|
|
12
|
+
/**
|
|
13
|
+
* UDS CLI - Universal Design System Command Line Interface
|
|
14
|
+
*
|
|
15
|
+
* This is the main entry point for the CLI. It uses manual argument parsing
|
|
16
|
+
* (no external framework) following the packages/mobile pattern.
|
|
17
|
+
*/
|
|
18
|
+
const { positional, options } = require_args.parseArgs(process.argv.slice(2));
|
|
19
|
+
const command = positional[0];
|
|
20
|
+
const banner = `
|
|
21
|
+
█ █ █▀▄ ▄▀▀ ▄▀▀ █ █
|
|
22
|
+
▀▄█ █▄▀ ▄██ ▀▄▄ █▄▄ █
|
|
23
|
+
Universal Design System
|
|
24
|
+
`.trim();
|
|
25
|
+
const LOCAL_COMMANDS = [{
|
|
26
|
+
name: "codemod",
|
|
27
|
+
description: "Apply a codemod",
|
|
28
|
+
run: (props) => require_codemod.codemod_default.run({
|
|
29
|
+
...props,
|
|
30
|
+
first: positional[1]
|
|
31
|
+
})
|
|
32
|
+
}, {
|
|
33
|
+
name: "editor-rules",
|
|
34
|
+
description: "🎯 Generate editor rules for various code editors and AI tools",
|
|
35
|
+
aliases: ["rules", "editor"],
|
|
36
|
+
run: require_editor_rules.editor_rules_default.run
|
|
37
|
+
}];
|
|
38
|
+
function showHelp(commands) {
|
|
39
|
+
const widest = Math.max(...commands.map((c) => c.name.length)) + 4;
|
|
40
|
+
const subcommandWidest = Math.max(...require_getCommandHelp.CODEMOD_SUBCOMMANDS.map((c) => c.name.length)) + 4;
|
|
41
|
+
require_print.print(`\n${require_colors.green(banner)}\n`);
|
|
42
|
+
require_print.print(`${require_colors.magenta("Usage:")} ${require_colors.white("uds <command> [options]")}\n`);
|
|
43
|
+
require_print.print(`${require_colors.magenta("Commands:")}`);
|
|
44
|
+
for (const cmd of commands) {
|
|
45
|
+
require_print.print(` ${require_colors.cyan(cmd.name.padEnd(widest))} ${require_colors.gray(cmd.description)}`);
|
|
46
|
+
if (cmd.name === "codemod") for (const sub of require_getCommandHelp.CODEMOD_SUBCOMMANDS) require_print.print(` ${require_colors.cyan(sub.name.padEnd(subcommandWidest))} ${require_colors.gray(sub.description)}`);
|
|
47
|
+
}
|
|
48
|
+
require_print.print("");
|
|
49
|
+
}
|
|
50
|
+
async function run(externalCommands) {
|
|
51
|
+
const commands = [...LOCAL_COMMANDS, ...externalCommands];
|
|
52
|
+
const helpCommands = commands.filter((c) => c.tag !== "hidden");
|
|
53
|
+
const showHelpForCommands = () => showHelp(helpCommands);
|
|
54
|
+
const props = {
|
|
55
|
+
name: "uds",
|
|
56
|
+
commandPath: positional.slice(0, 1),
|
|
57
|
+
first: positional[1],
|
|
58
|
+
second: positional[2],
|
|
59
|
+
third: positional[3],
|
|
60
|
+
options
|
|
61
|
+
};
|
|
62
|
+
if (command === "help" || command === "--help" || command === "-h" || !command) {
|
|
63
|
+
showHelpForCommands();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const commandDefinition = commands.find((c) => c.name === command || c.aliases?.includes(command));
|
|
67
|
+
if (!commandDefinition) {
|
|
68
|
+
require_print.print(require_colors.red(`Unknown command: ${command}`));
|
|
69
|
+
await require_analytics.trackEvent("unknown_cmd", { cmd: command });
|
|
70
|
+
showHelpForCommands();
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
await commandDefinition.run(props);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
exports.run = run;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
import { trackEvent } from "./utils/analytics.js";
|
|
3
|
+
import { parseArgs } from "./lib/args.js";
|
|
4
|
+
import { cyan, gray, green, magenta, red, white } from "./lib/colors.js";
|
|
5
|
+
import { print } from "./lib/print.js";
|
|
6
|
+
import { CODEMOD_SUBCOMMANDS } from "./utils/getCommandHelp.js";
|
|
7
|
+
import { codemod_default } from "./commands/codemod/codemod.js";
|
|
8
|
+
import { editor_rules_default } from "./commands/editor-rules.js";
|
|
9
|
+
|
|
10
|
+
//#region ../cli/dist/cli.mjs
|
|
11
|
+
/*! © 2026 Yahoo, Inc. UDS CLI v0.0.0-development */
|
|
12
|
+
/**
|
|
13
|
+
* UDS CLI - Universal Design System Command Line Interface
|
|
14
|
+
*
|
|
15
|
+
* This is the main entry point for the CLI. It uses manual argument parsing
|
|
16
|
+
* (no external framework) following the packages/mobile pattern.
|
|
17
|
+
*/
|
|
18
|
+
const { positional, options } = parseArgs(process.argv.slice(2));
|
|
19
|
+
const command = positional[0];
|
|
20
|
+
const banner = `
|
|
21
|
+
█ █ █▀▄ ▄▀▀ ▄▀▀ █ █
|
|
22
|
+
▀▄█ █▄▀ ▄██ ▀▄▄ █▄▄ █
|
|
23
|
+
Universal Design System
|
|
24
|
+
`.trim();
|
|
25
|
+
const LOCAL_COMMANDS = [{
|
|
26
|
+
name: "codemod",
|
|
27
|
+
description: "Apply a codemod",
|
|
28
|
+
run: (props) => codemod_default.run({
|
|
29
|
+
...props,
|
|
30
|
+
first: positional[1]
|
|
31
|
+
})
|
|
32
|
+
}, {
|
|
33
|
+
name: "editor-rules",
|
|
34
|
+
description: "🎯 Generate editor rules for various code editors and AI tools",
|
|
35
|
+
aliases: ["rules", "editor"],
|
|
36
|
+
run: editor_rules_default.run
|
|
37
|
+
}];
|
|
38
|
+
function showHelp(commands) {
|
|
39
|
+
const widest = Math.max(...commands.map((c) => c.name.length)) + 4;
|
|
40
|
+
const subcommandWidest = Math.max(...CODEMOD_SUBCOMMANDS.map((c) => c.name.length)) + 4;
|
|
41
|
+
print(`\n${green(banner)}\n`);
|
|
42
|
+
print(`${magenta("Usage:")} ${white("uds <command> [options]")}\n`);
|
|
43
|
+
print(`${magenta("Commands:")}`);
|
|
44
|
+
for (const cmd of commands) {
|
|
45
|
+
print(` ${cyan(cmd.name.padEnd(widest))} ${gray(cmd.description)}`);
|
|
46
|
+
if (cmd.name === "codemod") for (const sub of CODEMOD_SUBCOMMANDS) print(` ${cyan(sub.name.padEnd(subcommandWidest))} ${gray(sub.description)}`);
|
|
47
|
+
}
|
|
48
|
+
print("");
|
|
49
|
+
}
|
|
50
|
+
async function run(externalCommands) {
|
|
51
|
+
const commands = [...LOCAL_COMMANDS, ...externalCommands];
|
|
52
|
+
const helpCommands = commands.filter((c) => c.tag !== "hidden");
|
|
53
|
+
const showHelpForCommands = () => showHelp(helpCommands);
|
|
54
|
+
const props = {
|
|
55
|
+
name: "uds",
|
|
56
|
+
commandPath: positional.slice(0, 1),
|
|
57
|
+
first: positional[1],
|
|
58
|
+
second: positional[2],
|
|
59
|
+
third: positional[3],
|
|
60
|
+
options
|
|
61
|
+
};
|
|
62
|
+
if (command === "help" || command === "--help" || command === "-h" || !command) {
|
|
63
|
+
showHelpForCommands();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const commandDefinition = commands.find((c) => c.name === command || c.aliases?.includes(command));
|
|
67
|
+
if (!commandDefinition) {
|
|
68
|
+
print(red(`Unknown command: ${command}`));
|
|
69
|
+
await trackEvent("unknown_cmd", { cmd: command });
|
|
70
|
+
showHelpForCommands();
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
await commandDefinition.run(props);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { run };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_analytics = require('../../utils/analytics.cjs');
|
|
4
|
+
const require_getCommandHelp = require('../../utils/getCommandHelp.cjs');
|
|
5
|
+
const require_getDirChoices = require('../../utils/getDirChoices.cjs');
|
|
6
|
+
let prompts = require("prompts");
|
|
7
|
+
prompts = require_runtime.__toESM(prompts);
|
|
8
|
+
|
|
9
|
+
//#region ../cli/dist/commands/codemod/codemod.mjs
|
|
10
|
+
/*! © 2026 Yahoo, Inc. UDS CLI v0.0.0-development */
|
|
11
|
+
var codemod_default = {
|
|
12
|
+
name: "codemod",
|
|
13
|
+
description: `Apply a codemod`,
|
|
14
|
+
run: async (props) => {
|
|
15
|
+
const subCommands = await require_getCommandHelp.getSubCommandsChoices(props);
|
|
16
|
+
const subCommandIsValid = subCommands.some(({ value }) => props?.first === value);
|
|
17
|
+
const wantsHelp = props.options.help || props.options.h;
|
|
18
|
+
const isRootCommand = Boolean(!props?.first);
|
|
19
|
+
const dirChoices = require_getDirChoices.getDirChoices();
|
|
20
|
+
if (wantsHelp) return require_getCommandHelp.getCommandHelp(props);
|
|
21
|
+
const runCodeMod = async (codemod, selectedDirs) => {
|
|
22
|
+
return (await import(`./${codemod}`)).default.run({
|
|
23
|
+
...props,
|
|
24
|
+
selectedDirs
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
if (isRootCommand) {
|
|
28
|
+
const { selectedDirs, selectedCodemods, didConfirm } = await (0, prompts.default)([
|
|
29
|
+
{
|
|
30
|
+
type: "multiselect",
|
|
31
|
+
name: "selectedDirs",
|
|
32
|
+
instructions: false,
|
|
33
|
+
message: "Where are your sourcefiles?",
|
|
34
|
+
hint: "(Space to select. Return to submit)",
|
|
35
|
+
choices: dirChoices
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: "multiselect",
|
|
39
|
+
name: "selectedCodemods",
|
|
40
|
+
instructions: false,
|
|
41
|
+
message: "Select the codemods you want to run",
|
|
42
|
+
hint: "(Space to select. Return to submit)",
|
|
43
|
+
choices: subCommands
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: "toggle",
|
|
47
|
+
name: "didConfirm",
|
|
48
|
+
message: "Are you ready?",
|
|
49
|
+
initial: true,
|
|
50
|
+
active: "yes",
|
|
51
|
+
inactive: "no"
|
|
52
|
+
}
|
|
53
|
+
]);
|
|
54
|
+
if (!selectedDirs?.length || !selectedCodemods?.length || !didConfirm) process.exit(1);
|
|
55
|
+
await Promise.all(selectedCodemods.map(async (codemod) => {
|
|
56
|
+
await runCodeMod(codemod, selectedDirs);
|
|
57
|
+
return require_analytics.trackEvent("codemod", { codemod });
|
|
58
|
+
}));
|
|
59
|
+
return;
|
|
60
|
+
} else if (subCommandIsValid) {
|
|
61
|
+
const { selectedDirs } = await (0, prompts.default)({
|
|
62
|
+
type: "multiselect",
|
|
63
|
+
name: "selectedDirs",
|
|
64
|
+
instructions: false,
|
|
65
|
+
message: "Where are your sourcefiles?",
|
|
66
|
+
hint: "(Space to select. Return to submit)",
|
|
67
|
+
choices: dirChoices
|
|
68
|
+
});
|
|
69
|
+
if (!selectedDirs?.length) process.exit(1);
|
|
70
|
+
const codemod = props.first;
|
|
71
|
+
await runCodeMod(codemod, selectedDirs);
|
|
72
|
+
return require_analytics.trackEvent("codemod", { codemod });
|
|
73
|
+
} else await require_getCommandHelp.getCommandHelp({
|
|
74
|
+
...props,
|
|
75
|
+
notes: `That codemod does not exist. Try one of the codemods listed above!`
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
exports.codemod_default = codemod_default;
|