@yahoo/uds 0.1.14 → 0.1.16
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/cli/README.md +57 -5
- package/cli/commands/expo/_setup.ts +59 -15
- package/cli/commands/expo/build.ts +2 -1
- package/cli/commands/expo/dev.ts +17 -8
- package/cli/commands/expo/expo.ts +6 -6
- package/cli/commands/expo/launch.ts +1 -0
- package/cli/commands/expo/update.ts +1 -0
- package/cli/commands/purge.ts +16 -0
- package/cli/commands/{config/sync.ts → sync.ts} +3 -2
- package/cli/commands/uds.ts +1 -0
- package/cli/env.d.ts +3 -0
- package/cli/utils/configWorker.ts +23 -1
- package/cli/utils/getCommandHelp.ts +3 -4
- package/cli/utils/purgeCSS.ts +138 -0
- package/cli/utils/setupConfigWorker.ts +15 -18
- package/dist/{chunk-P7GR6E3K.js → chunk-AHFH5E5L.js} +1 -1
- package/dist/{chunk-MBOOJIH7.js → chunk-FLBMVDKG.js} +1 -1
- package/dist/{chunk-AWTLI4D3.js → chunk-U3UPAQ7V.js} +1 -1
- package/dist/fixtures/index.cjs +1 -1
- package/dist/fixtures/index.d.cts +1 -3
- package/dist/fixtures/index.d.ts +1 -3
- package/dist/fixtures/index.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +103 -32
- package/dist/index.d.ts +103 -32
- package/dist/index.js +1 -1
- package/dist/{index.native-9kYJrUPa.d.ts → index.native-fciGC1AQ.d.cts} +2 -2
- package/dist/{index.native-3ww4C4UV.d.cts → index.native-hIYZ_ma-.d.ts} +2 -2
- package/dist/index.native.cjs +1 -1
- package/dist/index.native.d.cts +10 -24
- package/dist/index.native.d.ts +10 -24
- package/dist/index.native.js +1 -1
- package/dist/tailwindPlugin.cjs +1 -1
- package/dist/tailwindPlugin.d.cts +1 -1
- package/dist/tailwindPlugin.d.ts +1 -1
- package/dist/tailwindPlugin.js +1 -1
- package/dist/tailwindPurge.cjs +4 -0
- package/dist/tailwindPurge.d.cts +16 -0
- package/dist/tailwindPurge.d.ts +16 -0
- package/dist/tailwindPurge.js +4 -0
- package/dist/tokens/index.cjs +1 -1
- package/dist/tokens/index.d.cts +3 -3
- package/dist/tokens/index.d.ts +3 -3
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/index.native.cjs +1 -1
- package/dist/tokens/index.native.d.cts +2 -2
- package/dist/tokens/index.native.d.ts +2 -2
- package/dist/tokens/index.native.js +1 -1
- package/dist/tokens/parseTokens.cjs +1 -1
- package/dist/tokens/parseTokens.d.cts +12 -12
- package/dist/tokens/parseTokens.d.ts +12 -12
- package/dist/tokens/parseTokens.js +1 -1
- package/dist/tokens/parseTokens.native.d.cts +2 -2
- package/dist/tokens/parseTokens.native.d.ts +2 -2
- package/dist/{types-J4DLS6Xj.d.cts → types-3GXulqnG.d.cts} +1 -1
- package/dist/{types-J4DLS6Xj.d.ts → types-3GXulqnG.d.ts} +1 -1
- package/dist/{types-hirL9Qk5.d.cts → types-_E6o7OhU.d.cts} +47 -54
- package/dist/{types-hirL9Qk5.d.ts → types-_E6o7OhU.d.ts} +47 -54
- package/package.json +20 -4
- package/cli/commands/config/config.ts +0 -10
- package/cli/commands/nextjs/dev.ts +0 -17
- package/cli/commands/nextjs/nextjs.ts +0 -10
- package/cli/eslint.config.mjs +0 -8
package/cli/README.md
CHANGED
@@ -1,16 +1,68 @@
|
|
1
|
-
# UDS
|
1
|
+
# UDS Cli
|
2
2
|
|
3
3
|
We leverage Bluebun, which is a CLI framework inspired by [Gluegun](https://github.com/infinitered/gluegun), but specifically designed to be used with [Bun](https://bun.sh), the new JS runtime.
|
4
4
|
|
5
5
|
Bluebun relies on Bun APIs and is designed to be extremely fast, with no-dependencies.
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
We use Bun to build our standalone executable. See [Bun build docs](https://bun.sh/docs/bundler/executables) for more details. The uds package.json's `build:cli` script handles building the CLI. The bin is output to the `dist/uds` binary file and this path is defined in the package.json's bin field.
|
7
|
+
> Trying to add a new command? Please see the "Adding a Command" section below
|
10
8
|
|
11
9
|
# Commands
|
12
10
|
|
13
|
-
|
11
|
+
In any consumer of `@yahoo/uds` the following commands are available:
|
12
|
+
|
13
|
+
> Please note: If you are _not_ running the CLI from a package.json script you will need to add `bun` before the binary in order to run it directly. i.e. `bun uds purge`
|
14
|
+
|
15
|
+
## Config
|
16
|
+
|
17
|
+
### Using args
|
18
|
+
|
19
|
+
| Arg | Required | Default |
|
20
|
+
| ------- | -------- | --------------- |
|
21
|
+
| id | true | |
|
22
|
+
| outFile | false | ./uds.config.ts |
|
23
|
+
|
24
|
+
```shell
|
25
|
+
uds sync --id [id] --outFile [path]
|
26
|
+
```
|
27
|
+
|
28
|
+
```shell
|
29
|
+
uds sync --id [id]
|
30
|
+
```
|
31
|
+
|
32
|
+
### Using ENV vars
|
33
|
+
|
34
|
+
| Env Var | Required | Default |
|
35
|
+
| ------------ | -------- | --------------- |
|
36
|
+
| UDS_ID | true | |
|
37
|
+
| UDS_OUT_FILE | false | ./uds.config.ts |
|
38
|
+
|
39
|
+
```shell
|
40
|
+
UDS_ID=[id] uds sync --outFile [path]
|
41
|
+
```
|
42
|
+
|
43
|
+
```shell
|
44
|
+
UDS_ID=[id] UDS_OUT_FILE=[path] uds sync
|
45
|
+
```
|
46
|
+
|
47
|
+
## Expo
|
48
|
+
|
49
|
+
```shell
|
50
|
+
uds expo build --profile [profile] --platform [ios|android]
|
51
|
+
uds expo dev --profile [profile] --platform [ios|android]
|
52
|
+
uds expo launch --profile [profile] --platform [ios|android]
|
53
|
+
uds expo update --profile [profile] --platform [ios|android]
|
54
|
+
uds expo --help
|
55
|
+
```
|
56
|
+
|
57
|
+
## Purge CSS
|
58
|
+
|
59
|
+
```shell
|
60
|
+
uds purge
|
61
|
+
```
|
62
|
+
|
63
|
+
## Adding a command
|
64
|
+
|
65
|
+
> Please note: Adding nested commands, i.e. uds expo dev, appears to not work correctly when UDS is consumed from npm. As a workaround, please see code for expo/expo.ts for re-routing sub-commands from the root command file. To verify your CLI command works correctly you should run `npm pack` within the packages/uds directory. Once you have your generated tarball you should copy that tarball to a test application such as https://github.com/yahoo-design/uds-nextjs-demo, then add `"@yahoo/uds": "file:./tarball-generated-from-npm-pack.tgz` to it's dependencies and run an install. Now you should be able to run `bun uds [your command name]` to test your functionality.
|
14
66
|
|
15
67
|
Commands are organized in a tree structure. The root command is the name of the CLI (uds), and then we can have subcommands under that, and subcommands under those, and so on.
|
16
68
|
|
@@ -1,5 +1,8 @@
|
|
1
|
+
import fs from 'node:fs';
|
2
|
+
import os from 'node:os';
|
3
|
+
|
1
4
|
import { EasJsonAccessor, EasJsonUtils, Platform } from '@expo/eas-json';
|
2
|
-
import { type Props
|
5
|
+
import { print, type Props } from 'bluebun';
|
3
6
|
import { $, semver, which } from 'bun';
|
4
7
|
|
5
8
|
export interface MobileProps extends Props {
|
@@ -29,19 +32,60 @@ export async function setup({
|
|
29
32
|
const { profile, platform, jsEngine = 'hermes', debug = false } = props.options;
|
30
33
|
const isIOS = platform === Platform.IOS;
|
31
34
|
const isAndroid = platform === Platform.ANDROID;
|
35
|
+
const pathAsString = await $`echo $PATH`.text();
|
36
|
+
const needsBunInPath = !pathAsString.includes('.bun');
|
37
|
+
|
38
|
+
/* -------------------------------------------------------------------------- */
|
39
|
+
/* VERIFY BUN IS IN PATH */
|
40
|
+
/* -------------------------------------------------------------------------- */
|
41
|
+
if (needsBunInPath) {
|
42
|
+
/**
|
43
|
+
* If BUN_INSTALL is not in the path, we need to add it.
|
44
|
+
* https://bun.sh/docs/installation#checking-installation:~:text=shell%27s%20configuration%20file.
|
45
|
+
*/
|
46
|
+
console.write(
|
47
|
+
'BUN is not installed globally or is not available in your $PATH. Adding to your $PATH...',
|
48
|
+
);
|
49
|
+
const whichShell = await $`echo $SHELL`.text();
|
50
|
+
const homeDirectory = os.homedir();
|
51
|
+
const shellRcFile = whichShell.includes('zsh') ? '.zshrc' : '.bashrc';
|
52
|
+
fs.appendFileSync(
|
53
|
+
`${homeDirectory}/${shellRcFile}`,
|
54
|
+
'\n# bun\nexport BUN_INSTALL="$HOME/.bun"\nexport PATH="$BUN_INSTALL/bin:$PATH"',
|
55
|
+
);
|
56
|
+
await $`source $HOME/${shellRcFile}`;
|
57
|
+
}
|
32
58
|
|
33
59
|
/* -------------------------------------------------------------------------- */
|
34
60
|
/* XCODE SETUP */
|
35
61
|
/* -------------------------------------------------------------------------- */
|
36
62
|
if (isIOS) {
|
37
63
|
const xcodePath = await $`xcode-select -p`.text();
|
38
|
-
const needsXcode = !xcodePath.startsWith('/Applications');
|
39
|
-
const needsXcrun = await needsBinary('xcrun');
|
40
64
|
|
41
|
-
if (
|
42
|
-
|
43
|
-
|
44
|
-
)
|
65
|
+
if (xcodePath) {
|
66
|
+
const isInvalidXcodePath = !xcodePath.startsWith('/Applications');
|
67
|
+
|
68
|
+
if (isInvalidXcodePath) {
|
69
|
+
console.write(`
|
70
|
+
/* -------------------------------------------------------------------------- */
|
71
|
+
/* XCODDE PATH IS INVALID */
|
72
|
+
/* -------------------------------------------------------------------------- */
|
73
|
+
|
74
|
+
Run the following command to set the correct path to XCode:
|
75
|
+
|
76
|
+
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
|
77
|
+
`);
|
78
|
+
}
|
79
|
+
} else {
|
80
|
+
console.write(`
|
81
|
+
/* -------------------------------------------------------------------------- */
|
82
|
+
/* XCODE NOT INSTALLED */
|
83
|
+
/* -------------------------------------------------------------------------- */
|
84
|
+
|
85
|
+
You must have XCode installed before continuing...
|
86
|
+
|
87
|
+
Visit https://apps.apple.com/us/app/xcode/id497799835?mt=12 to download.
|
88
|
+
`);
|
45
89
|
throw new Error('XCode not installed');
|
46
90
|
}
|
47
91
|
|
@@ -49,14 +93,14 @@ export async function setup({
|
|
49
93
|
* Installing the XCode command line tools & simulators normally
|
50
94
|
* requires opening up XCode to install.
|
51
95
|
* This conditional is to avoid having to do that.
|
96
|
+
*
|
97
|
+
* If xcode command line tools and simulators have already been installed, that's
|
98
|
+
* fine. This command is really fast and will continue running if already available.
|
99
|
+
*
|
100
|
+
* https://developer.apple.com/documentation/xcode/installing-additional-simulator-runtimes#Install-and-manage-Simulator-runtimes-from-the-command-line
|
52
101
|
*/
|
53
|
-
|
54
|
-
|
55
|
-
* https://developer.apple.com/documentation/xcode/installing-additional-simulator-runtimes#Install-and-manage-Simulator-runtimes-from-the-command-line
|
56
|
-
*/
|
57
|
-
await $`xcodebuild -runFirstLaunch`;
|
58
|
-
await $`xcodebuild -downloadPlatform iOS`;
|
59
|
-
}
|
102
|
+
await $`xcodebuild -runFirstLaunch`;
|
103
|
+
await $`xcodebuild -downloadPlatform iOS`;
|
60
104
|
}
|
61
105
|
|
62
106
|
/* -------------------------------------------------------------------------- */
|
@@ -215,7 +259,7 @@ export async function setup({
|
|
215
259
|
const output = {
|
216
260
|
name: outputName,
|
217
261
|
dir: outputDir,
|
218
|
-
prebuildsDir
|
262
|
+
prebuildsDir,
|
219
263
|
fileBase: outputFileBase,
|
220
264
|
artifact: isIOS ? `${outputFileBase}.tar.gz` : `${outputFileBase}.zip`,
|
221
265
|
app: isIOS ? `${outputFileBase}.app` : 'todo fix android',
|
package/cli/commands/expo/dev.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import { Props } from 'bluebun';
|
2
2
|
import { $, sleep } from 'bun';
|
3
|
-
|
3
|
+
|
4
|
+
import { type MobileProps, setup } from './_setup';
|
4
5
|
|
5
6
|
interface MobileStartProps extends Props {
|
6
7
|
options: MobileProps['options'] & {
|
@@ -56,15 +57,22 @@ export default {
|
|
56
57
|
const iphone15Udid = iphone15ProMax?.udid;
|
57
58
|
await $`open -a Simulator --args -CurrentDeviceUDID ${iphone15Udid}`;
|
58
59
|
}
|
60
|
+
const appContainerPath =
|
61
|
+
await $`xcrun simctl get_app_container booted ${scheme} data`.text();
|
62
|
+
|
63
|
+
if (!appContainerPath) {
|
64
|
+
console.write('App not installed on booted device. Installing...');
|
65
|
+
await $`eas build:run --platform ${platform} --path ${output.launchFile}`;
|
66
|
+
}
|
67
|
+
/**
|
68
|
+
* In dev mode we use a debug build, which requires a metro server to serve
|
69
|
+
* the Javascript bundle.
|
70
|
+
*
|
71
|
+
* To avoid the, "Could not find metro server" error screen on launch,
|
72
|
+
* we delay the launch of the app until after the metro server has started.
|
73
|
+
*/
|
59
74
|
}
|
60
75
|
|
61
|
-
/**
|
62
|
-
* In dev mode we use a debug build, which requires a metro server to serve
|
63
|
-
* the Javascript bundle.
|
64
|
-
*
|
65
|
-
* To avoid the, "Could not find metro server" error screen on launch,
|
66
|
-
* we delay the launch of the app until after the metro server has started.
|
67
|
-
*/
|
68
76
|
sleep(3000).then(async () => {
|
69
77
|
/**
|
70
78
|
* Launch the app on the booted device
|
@@ -76,6 +84,7 @@ export default {
|
|
76
84
|
console.write('Starting Metro server...');
|
77
85
|
await $`expo start --${platform} --dev-client --localhost --scheme ${scheme} ${extrArgsString}`;
|
78
86
|
} catch (err) {
|
87
|
+
console.error(err);
|
79
88
|
throw err;
|
80
89
|
}
|
81
90
|
},
|
@@ -1,19 +1,19 @@
|
|
1
|
-
import { type Props } from 'bluebun';
|
2
1
|
import { getCommandHelp } from '../../utils/getCommandHelp';
|
2
|
+
import { type MobileProps } from './_setup';
|
3
3
|
|
4
4
|
export default {
|
5
5
|
name: 'expo',
|
6
6
|
description: '',
|
7
|
-
run: async (props:
|
7
|
+
run: async (props: MobileProps) => {
|
8
8
|
switch (props?.first) {
|
9
9
|
case 'build':
|
10
|
-
return
|
10
|
+
return (await import('./build')).default.run(props);
|
11
11
|
case 'dev':
|
12
|
-
return
|
12
|
+
return (await import('./dev')).default.run(props);
|
13
13
|
case 'launch':
|
14
|
-
return
|
14
|
+
return (await import('./launch')).default.run(props);
|
15
15
|
case 'update':
|
16
|
-
return
|
16
|
+
return (await import('./update')).default.run(props);
|
17
17
|
default: {
|
18
18
|
await getCommandHelp(props);
|
19
19
|
break;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { Props, spinStart, spinStop } from 'bluebun';
|
2
|
+
|
3
|
+
import { purge } from '../utils/purgeCSS';
|
4
|
+
|
5
|
+
export default {
|
6
|
+
name: 'purge',
|
7
|
+
description: `Purge unused CSS`,
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
9
|
+
run: async (props: Props) => {
|
10
|
+
spinStart('Purging css...');
|
11
|
+
|
12
|
+
await purge();
|
13
|
+
|
14
|
+
spinStop('✅ Purging css done!');
|
15
|
+
},
|
16
|
+
};
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import { Props } from 'bluebun';
|
2
|
-
|
3
|
-
import {
|
2
|
+
|
3
|
+
import { setupConfigWorker } from '../utils/setupConfigWorker';
|
4
|
+
import { SyncOptions } from '../utils/types';
|
4
5
|
|
5
6
|
interface SyncProps extends Props {
|
6
7
|
options: SyncOptions;
|
package/cli/commands/uds.ts
CHANGED
package/cli/env.d.ts
CHANGED
@@ -1,9 +1,31 @@
|
|
1
1
|
// prevents TS errors
|
2
2
|
declare var self: Worker;
|
3
|
+
|
4
|
+
import { $ } from 'bun';
|
5
|
+
|
3
6
|
import { ConfigWorkerThreadMessage } from './types';
|
4
7
|
|
5
8
|
self.onmessage = async ({ data }: ConfigWorkerThreadMessage) => {
|
6
9
|
if (data.type === 'init') {
|
7
|
-
|
10
|
+
try {
|
11
|
+
// Only listen for updates if firebase is available. This will only be available in UDS monorepo atm
|
12
|
+
const firebase = await import('database/firebase');
|
13
|
+
console.write('Fetching from local database package...\n');
|
14
|
+
firebase.onBranchSnapshot(data.resp.id, ({ config, status }) => {
|
15
|
+
postMessage({ type: 'update', resp: { config, status } });
|
16
|
+
});
|
17
|
+
} catch (err) {
|
18
|
+
try {
|
19
|
+
const res =
|
20
|
+
await $`curl https://syncconfig-j57v6zmjrq-uc.a.run.app?id=${data.resp.id}`.json();
|
21
|
+
if (res?.config) {
|
22
|
+
postMessage({ type: 'update', resp: { config: res.config, status: 'error' } });
|
23
|
+
} else {
|
24
|
+
throw Error;
|
25
|
+
}
|
26
|
+
} catch (err) {
|
27
|
+
throw new Error('Error fetching config');
|
28
|
+
}
|
29
|
+
}
|
8
30
|
}
|
9
31
|
};
|
@@ -1,13 +1,12 @@
|
|
1
1
|
import {
|
2
|
-
CommandTree,
|
3
|
-
InitialProps,
|
4
|
-
Props,
|
5
2
|
bold,
|
6
3
|
calcWidestCommandName,
|
4
|
+
CommandTree,
|
7
5
|
commandTree,
|
8
6
|
cyan,
|
9
7
|
gray,
|
10
8
|
print,
|
9
|
+
Props,
|
11
10
|
white,
|
12
11
|
} from 'bluebun';
|
13
12
|
|
@@ -35,7 +34,7 @@ async function formatHelp(initialProps: Props) {
|
|
35
34
|
function generateHelp(cmdTree: CommandTree, prefix: string): string[] {
|
36
35
|
return Object.keys(cmdTree).flatMap((key) => {
|
37
36
|
const command = cmdTree[key];
|
38
|
-
|
37
|
+
const lines: string[] = [];
|
39
38
|
|
40
39
|
const fullName = `${prefix} ${command.name === name ? '' : command.name}`.trim();
|
41
40
|
lines.push(`${cyan(fullName).padEnd(widest)} ${gray(command.description)}`);
|
@@ -0,0 +1,138 @@
|
|
1
|
+
import path from 'node:path';
|
2
|
+
|
3
|
+
import {
|
4
|
+
componentsDependencies,
|
5
|
+
componentToVariants,
|
6
|
+
variantsList,
|
7
|
+
variantToTailwindClass,
|
8
|
+
} from '@yahoo/uds/tailwindPurge';
|
9
|
+
import { spinStart } from 'bluebun';
|
10
|
+
import FastGlob from 'fast-glob';
|
11
|
+
import { Project } from 'ts-morph';
|
12
|
+
|
13
|
+
type SafeList = string;
|
14
|
+
type ImportsList = string[];
|
15
|
+
type Files = string[];
|
16
|
+
|
17
|
+
// TODO: use CLI args to power the output file path
|
18
|
+
const OUTPUT_FILE_PATH = Bun.file(`${Bun.env.PWD}/dist/safelist.js`);
|
19
|
+
|
20
|
+
const getFiles = async (): Promise<Files> => {
|
21
|
+
const workspaceDir = Bun.env.PWD;
|
22
|
+
const srcDir = path.join(workspaceDir, '/src/');
|
23
|
+
const files = await FastGlob(`${srcDir}/**/*.{jsx,tsx}`);
|
24
|
+
|
25
|
+
return files;
|
26
|
+
};
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Given a file it returns the list of imports from @yahoo/uds
|
30
|
+
*/
|
31
|
+
const parseFiles = (project: Project, files: Files): ImportsList => {
|
32
|
+
const importsSet = new Set();
|
33
|
+
|
34
|
+
const importsPerFile: string[] = files
|
35
|
+
.map((file: string) => {
|
36
|
+
const sourceFile = project.getSourceFile(file);
|
37
|
+
|
38
|
+
const udsImports =
|
39
|
+
sourceFile
|
40
|
+
?.getImportDeclarations()
|
41
|
+
.filter((declaration) => {
|
42
|
+
return declaration.getModuleSpecifier().getText().includes('@yahoo/uds');
|
43
|
+
})
|
44
|
+
.map((declaration) => {
|
45
|
+
return declaration.getNamedImports().map((namedImport) => namedImport.getName());
|
46
|
+
})
|
47
|
+
.flat() ?? [];
|
48
|
+
|
49
|
+
return udsImports;
|
50
|
+
})
|
51
|
+
.flat();
|
52
|
+
|
53
|
+
importsPerFile.forEach((item: string) => {
|
54
|
+
if (!importsSet.has(item)) {
|
55
|
+
importsSet.add(item);
|
56
|
+
}
|
57
|
+
});
|
58
|
+
|
59
|
+
return Array.from(importsSet) as string[];
|
60
|
+
};
|
61
|
+
|
62
|
+
const getTailwindSafelist = (componentList: string[]): SafeList => {
|
63
|
+
const validVariants = new Set<string>(variantsList);
|
64
|
+
const usedProps = new Set<string>();
|
65
|
+
componentList.forEach((component: string) => {
|
66
|
+
if (isUDSComponent(component)) {
|
67
|
+
// go through the list of props of that particular component
|
68
|
+
// and get the related tailwind classes
|
69
|
+
componentToVariants[component].forEach((prop: string) => {
|
70
|
+
if (validVariants.has(prop) && !usedProps.has(prop)) {
|
71
|
+
usedProps.add(prop);
|
72
|
+
}
|
73
|
+
});
|
74
|
+
}
|
75
|
+
});
|
76
|
+
|
77
|
+
let safeList = '';
|
78
|
+
for (const prop of usedProps) {
|
79
|
+
safeList += `${variantToTailwindClass[prop]} `;
|
80
|
+
}
|
81
|
+
return safeList;
|
82
|
+
};
|
83
|
+
|
84
|
+
const isUDSComponent = (component: string): boolean => {
|
85
|
+
return !!componentToVariants[component];
|
86
|
+
};
|
87
|
+
|
88
|
+
const saveToFile = async (safeList: SafeList) => {
|
89
|
+
const fileContent = `
|
90
|
+
//! This file is generated by purgeCSS.ts from @yahoo/uds
|
91
|
+
//! Do not edit directly
|
92
|
+
//! If there is issue with this file please report to #ask-uds
|
93
|
+
const safeList = "${safeList}";
|
94
|
+
`;
|
95
|
+
|
96
|
+
await Bun.write(OUTPUT_FILE_PATH, fileContent);
|
97
|
+
};
|
98
|
+
|
99
|
+
const getComponentsToConvertToTW = (udsImport: ImportsList): string[] => {
|
100
|
+
// filter out just the components
|
101
|
+
const components = udsImport.filter((importedItem) => !!componentToVariants[importedItem]);
|
102
|
+
const set = new Set();
|
103
|
+
components.forEach((component) => {
|
104
|
+
if (!set.has(component)) {
|
105
|
+
set.add(component);
|
106
|
+
}
|
107
|
+
if (componentsDependencies[component]) {
|
108
|
+
componentsDependencies[component].forEach((dependent: string) => {
|
109
|
+
if (!set.has(dependent)) {
|
110
|
+
set.add(dependent);
|
111
|
+
}
|
112
|
+
});
|
113
|
+
}
|
114
|
+
});
|
115
|
+
return Array.from(set) as string[];
|
116
|
+
};
|
117
|
+
|
118
|
+
async function purge() {
|
119
|
+
const workspaceDir = Bun.env.PWD;
|
120
|
+
const srcDir = path.join(workspaceDir, '/tsconfig.json');
|
121
|
+
const project = new Project({
|
122
|
+
tsConfigFilePath: srcDir,
|
123
|
+
});
|
124
|
+
|
125
|
+
spinStart('Getting used UDS components...');
|
126
|
+
/// 1. Get all files from the current dir
|
127
|
+
const files = await getFiles();
|
128
|
+
// 2. For each file get the imports;
|
129
|
+
const udsImports = parseFiles(project, files);
|
130
|
+
// 3. Now that we have the importer components
|
131
|
+
const udsComponents = getComponentsToConvertToTW(udsImports);
|
132
|
+
// 4. Generate the CSS we need
|
133
|
+
const safeList = getTailwindSafelist(udsComponents);
|
134
|
+
// 5. Write the allowlist to a file
|
135
|
+
await saveToFile(safeList);
|
136
|
+
}
|
137
|
+
|
138
|
+
export { purge };
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import path from 'node:path';
|
2
|
-
|
2
|
+
|
3
3
|
import { sortKeys } from './sortKeys';
|
4
|
+
import { ConfigWorkerMainThreadMessage, SyncOptions } from './types';
|
4
5
|
|
5
6
|
const workerPath = path.resolve(import.meta.dir, './configWorker');
|
6
7
|
const workerURL = new URL(Bun.pathToFileURL(workerPath)).href;
|
@@ -9,45 +10,41 @@ interface ConfigWorkerOptions extends SyncOptions {
|
|
9
10
|
onUpdate?: (params: { worker: Worker }) => void;
|
10
11
|
}
|
11
12
|
|
12
|
-
export async function setupConfigWorker({
|
13
|
+
export async function setupConfigWorker({
|
14
|
+
id = Bun.env.UDS_ID,
|
15
|
+
outFile = Bun.env.UDS_OUT_FILE,
|
16
|
+
onUpdate,
|
17
|
+
}: ConfigWorkerOptions = {}) {
|
13
18
|
const workspaceDir = Bun.env.PWD;
|
14
19
|
let configID = id;
|
15
|
-
let configOutFile = outFile;
|
20
|
+
let configOutFile = outFile ?? './uds.config.ts';
|
16
21
|
|
22
|
+
// If we didn't get the config ID from the command line or env vars, check for a uds.json file
|
17
23
|
if (!configID) {
|
18
24
|
const udsConfigFile = Bun.file(`${workspaceDir}/uds.json`);
|
19
25
|
const udsConfigFileExists = await udsConfigFile.exists();
|
20
26
|
if (udsConfigFileExists) {
|
21
|
-
const configJsonFile = await udsConfigFile.json
|
22
|
-
id: string;
|
23
|
-
outFile: string;
|
24
|
-
}>();
|
27
|
+
const configJsonFile = (await udsConfigFile.json()) as { id: string; outFile: string };
|
25
28
|
|
26
29
|
configID = configJsonFile.id;
|
27
30
|
configOutFile = configJsonFile.outFile;
|
28
31
|
}
|
29
32
|
}
|
30
33
|
|
34
|
+
// have _nothing_, warn the eng to do something
|
31
35
|
if (!configID) {
|
32
36
|
console.error(
|
33
|
-
'\nMissing config ID. Please pass in --id or create a uds.json file with { "id": "your-config-id" } defined.\n',
|
34
|
-
);
|
35
|
-
process.exit(1);
|
36
|
-
}
|
37
|
-
|
38
|
-
if (!configOutFile) {
|
39
|
-
console.error(
|
40
|
-
'\nMissing outFile details. Please pass in --outFile ./some-path.ts or create a uds.json file with { "outFile": "./some-path.ts" } defined.\n',
|
37
|
+
'\nMissing config ID. Please pass in --id, set UDS_ID in your .env, or create a uds.json file with { "id": "your-config-id" } defined.\n',
|
41
38
|
);
|
42
39
|
process.exit(1);
|
43
40
|
}
|
44
41
|
|
45
|
-
const outFilePath = `${workspaceDir}/${
|
42
|
+
const outFilePath = `${workspaceDir}/${configOutFile}`;
|
46
43
|
|
47
44
|
const worker = new Worker(workerURL);
|
48
45
|
|
49
46
|
worker.addEventListener('open', () => {
|
50
|
-
worker.postMessage({ type: 'init', resp: { id } });
|
47
|
+
worker.postMessage({ type: 'init', resp: { id: configID } });
|
51
48
|
});
|
52
49
|
|
53
50
|
worker.onmessage = async ({ data }: ConfigWorkerMainThreadMessage) => {
|
@@ -62,7 +59,7 @@ import { type UniversalTokensConfig } from '@yahoo/uds';
|
|
62
59
|
export const config: UniversalTokensConfig = ${JSON.stringify(sortedConfig, null, 2)};
|
63
60
|
`.trimStart();
|
64
61
|
|
65
|
-
console.log(`✅ Synced UDS config ${
|
62
|
+
console.log(`✅ Synced UDS config ${configID} to ${outFilePath}`);
|
66
63
|
await Bun.write(outFilePath, configContent);
|
67
64
|
onUpdate?.({ worker });
|
68
65
|
}
|
@@ -1 +1 @@
|
|
1
|
-
var e=["Helvetica Neue","Helvetica","Arial","sans-serif"],
|
1
|
+
var e=["Helvetica Neue","Helvetica","Arial","sans-serif"],i=["Georgia","Times","Times New Roman","serif"],g={icons:{fallbacks:e,name:"yahoo-icons"},sans:{fallbacks:e,name:"yahoo-sans"},"sans-beta":{fallbacks:e,name:"yahoo-sans-beta"},"sans-condensed":{fallbacks:e,name:"yahoo-sans-condensed"},"serif-text":{fallbacks:i,name:"yahoo-serif-text"},"serif-display":{fallbacks:i,name:"yahoo-serif-display"}},b={display1:"sans",title1:"sans",title2:"sans",title3:"sans",title4:"sans",headline1:"sans",body1:"sans",label1:"sans",label2:"sans",caption1:"sans",caption2:"sans",legal1:"sans"},f={thin:"100",extralight:"200",light:"300",regular:"400",medium:"500",semibold:"600",bold:"700",extrabold:"800",black:"900"},p={display1:"black",title1:"bold",title2:"bold",title3:"bold",title4:"bold",headline1:"semibold",body1:"regular",label1:"semibold",label2:"regular",caption1:"semibold",caption2:"regular",legal1:"semibold"},d={display1:"uppercase",title1:"none",title2:"none",title3:"none",title4:"none",headline1:"none",body1:"none",label1:"none",label2:"none",caption1:"none",caption2:"none",legal1:"none"},l={fontSize:{display1:46,title1:29,title2:25,title3:21,title4:17,headline1:13,body1:13,label1:12,label2:12,caption1:11,caption2:11,legal1:10},lineHeight:{display1:44,title1:36,title2:32,title3:28,title4:24,headline1:16,body1:16,label1:16,label2:16,caption1:16,caption2:16,legal1:12}},a={fontSize:{display1:46,title1:30,title2:26,title3:22,title4:18,headline1:14,body1:14,label1:13,label2:13,caption1:12,caption2:12,legal1:11},lineHeight:{...l.lineHeight,title1:40,headline1:20,body1:20,legal1:16}},t={fontSize:{display1:47,title1:31,title2:27,title3:23,title4:19,headline1:15,body1:15,label1:13,label2:13,caption1:12,caption2:12,legal1:11},lineHeight:{...a.lineHeight,title2:36,title3:32}},n={fontSize:{...t.fontSize,display1:48,title1:32,title2:28,title3:24,title4:20,headline1:16,body1:16,label1:14,label2:14},lineHeight:{...t.lineHeight,title2:36,title3:32,headline1:20,body1:20,label1:20,label2:20}},o={fontSize:{display1:50,title1:34,title2:30,title3:26,title4:22,headline1:18,body1:16,label1:16,label2:16,caption1:14,caption2:14,legal1:13},lineHeight:{...n.lineHeight,title1:44,headline1:24,body1:24,caption1:20,caption2:20}},s={fontSize:{display1:52,title1:36,title2:32,title3:28,title4:26,headline1:20,body1:20,label1:18,label2:18,caption1:16,caption2:16,legal1:15},lineHeight:{...o.lineHeight,title2:40,title3:36,headline1:28,body1:28,label1:24,label2:24,legal1:20}},c={fontSize:{display1:54,title1:38,title2:34,title3:30,title4:28,headline1:22,body1:22,label1:20,label2:20,caption1:18,caption2:18,legal1:17},lineHeight:{...s.lineHeight,title1:48,title2:44,title4:32,label1:28,label2:28,caption1:24,caption2:24}};export{g as a,b,f as c,p as d,d as e,l as f,a as g,t as h,n as i,o as j,s as k,c as l};
|
@@ -1 +1 @@
|
|
1
|
-
import{a as v,b as R,c as m,d as T,e as F,f as $,g as C,h as _,i as E,j as h,k as S}from"./chunk-3I3D5S54.js";import{
|
1
|
+
import{a as y}from"./chunk-WYDHNV42.js";import{a as v,b as R,c as m,d as T,e as F,f as $,g as C,h as _,i as E,j as h,k as S}from"./chunk-3I3D5S54.js";import{a as c}from"./chunk-74YHFBTD.js";import{c as d}from"./chunk-AHFH5E5L.js";function I(o){let{palette:e,spectrum:a}=o,n={},r={spectrum:{},palette:{}};for(let[t,i]of c(a))for(let[s,f]of c(i)){let l=`${t}-${s}`,p=`--${R}-${l}`;r.spectrum[t]||(r.spectrum[t]={}),r.spectrum[t][s]=`rgb(var(${p}))`,n[p]=f}return c(e).forEach(([t,i])=>{for(let[s,{hue:f,step:l,opacity:p}]of Object.entries(i)){t in r.palette||(r.palette[t]={});let g=`--${v}-${t}-color-${s}`;n[g]=`var(--${R}-${f}-${l})`,r.palette[t][s]=p?`rgb(var(${g}) / ${p})`:`rgb(var(${g}))`}}),{_vars:n,_raw:o,tailwindConfig:r}}function k(o){let e={},a={};for(let[n,r="regular"]of c(o)){let t=`--${h}-${n}`,i=d[r];e[t]=i,a[n]=`var(${t})`}return{_vars:e,_raw:o,tailwindConfig:{...d,...a}}}function P(o,e,a){let n={},r={};for(let[t,i]of c(e)){let s=`--${o}-${t}`,f=a?a(i):i;n[s]=f,r[t]=`var(${s})`}return{_vars:n,_raw:e,tailwindConfig:r}}function u(o,e){let a={},n={};for(let[r,t]of c(e)){let i=`--${o}-${r}`,s=`${t}px`;a[i]=s,n[r]=`var(${i})`}return{_vars:a,_raw:e,tailwindConfig:n}}function x(o){let e={};for(let[a,n]of c(o)){let r=n.map(({color:t,offsetX:i,offsetY:s,blurRadius:f,spreadRadius:l})=>`${i}px ${s}px ${f}px ${l}px ${t}`).join(", ");e[a]=r}return e}function N(o){return y(o,(e,a)=>{let{fallbacks:n=[]}=e??{};return[`var(--${m}-${a})`,...n]})}function X(o){return`${o}px`}function w(o){return y(o,X)}var H=w;function U(o){let{colorMode:e,scaleMode:a,elevation:n,fontFamily:r,borderWidth:t}=o;return{...o,colorMode:{light:I(e.light),dark:I(e.dark)},scaleMode:y(a,({shapes:i,spacing:s,fontSize:f,lineHeight:l,fontFamily:p,fontWeight:g,textTransform:b,avatarSizes:V,iconSizes:W})=>({fontFamily:P(m,p,M=>`var(--${m}-${M})`),fontSize:u(_,f),fontWeight:k(g),lineHeight:u(E,l),textTransform:P(S,b),shapes:u($,i),spacing:u(C,s),avatarSizes:u(F,V),iconSizes:u(T,W)})),borderWidth:H(t),elevation:x(n),fontFamily:N(r)}}export{U as a};
|