@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.
Files changed (63) hide show
  1. package/cli/README.md +57 -5
  2. package/cli/commands/expo/_setup.ts +59 -15
  3. package/cli/commands/expo/build.ts +2 -1
  4. package/cli/commands/expo/dev.ts +17 -8
  5. package/cli/commands/expo/expo.ts +6 -6
  6. package/cli/commands/expo/launch.ts +1 -0
  7. package/cli/commands/expo/update.ts +1 -0
  8. package/cli/commands/purge.ts +16 -0
  9. package/cli/commands/{config/sync.ts → sync.ts} +3 -2
  10. package/cli/commands/uds.ts +1 -0
  11. package/cli/env.d.ts +3 -0
  12. package/cli/utils/configWorker.ts +23 -1
  13. package/cli/utils/getCommandHelp.ts +3 -4
  14. package/cli/utils/purgeCSS.ts +138 -0
  15. package/cli/utils/setupConfigWorker.ts +15 -18
  16. package/dist/{chunk-P7GR6E3K.js → chunk-AHFH5E5L.js} +1 -1
  17. package/dist/{chunk-MBOOJIH7.js → chunk-FLBMVDKG.js} +1 -1
  18. package/dist/{chunk-AWTLI4D3.js → chunk-U3UPAQ7V.js} +1 -1
  19. package/dist/fixtures/index.cjs +1 -1
  20. package/dist/fixtures/index.d.cts +1 -3
  21. package/dist/fixtures/index.d.ts +1 -3
  22. package/dist/fixtures/index.js +1 -1
  23. package/dist/index.cjs +1 -1
  24. package/dist/index.d.cts +103 -32
  25. package/dist/index.d.ts +103 -32
  26. package/dist/index.js +1 -1
  27. package/dist/{index.native-9kYJrUPa.d.ts → index.native-fciGC1AQ.d.cts} +2 -2
  28. package/dist/{index.native-3ww4C4UV.d.cts → index.native-hIYZ_ma-.d.ts} +2 -2
  29. package/dist/index.native.cjs +1 -1
  30. package/dist/index.native.d.cts +10 -24
  31. package/dist/index.native.d.ts +10 -24
  32. package/dist/index.native.js +1 -1
  33. package/dist/tailwindPlugin.cjs +1 -1
  34. package/dist/tailwindPlugin.d.cts +1 -1
  35. package/dist/tailwindPlugin.d.ts +1 -1
  36. package/dist/tailwindPlugin.js +1 -1
  37. package/dist/tailwindPurge.cjs +4 -0
  38. package/dist/tailwindPurge.d.cts +16 -0
  39. package/dist/tailwindPurge.d.ts +16 -0
  40. package/dist/tailwindPurge.js +4 -0
  41. package/dist/tokens/index.cjs +1 -1
  42. package/dist/tokens/index.d.cts +3 -3
  43. package/dist/tokens/index.d.ts +3 -3
  44. package/dist/tokens/index.js +1 -1
  45. package/dist/tokens/index.native.cjs +1 -1
  46. package/dist/tokens/index.native.d.cts +2 -2
  47. package/dist/tokens/index.native.d.ts +2 -2
  48. package/dist/tokens/index.native.js +1 -1
  49. package/dist/tokens/parseTokens.cjs +1 -1
  50. package/dist/tokens/parseTokens.d.cts +12 -12
  51. package/dist/tokens/parseTokens.d.ts +12 -12
  52. package/dist/tokens/parseTokens.js +1 -1
  53. package/dist/tokens/parseTokens.native.d.cts +2 -2
  54. package/dist/tokens/parseTokens.native.d.ts +2 -2
  55. package/dist/{types-J4DLS6Xj.d.cts → types-3GXulqnG.d.cts} +1 -1
  56. package/dist/{types-J4DLS6Xj.d.ts → types-3GXulqnG.d.ts} +1 -1
  57. package/dist/{types-hirL9Qk5.d.cts → types-_E6o7OhU.d.cts} +47 -54
  58. package/dist/{types-hirL9Qk5.d.ts → types-_E6o7OhU.d.ts} +47 -54
  59. package/package.json +20 -4
  60. package/cli/commands/config/config.ts +0 -10
  61. package/cli/commands/nextjs/dev.ts +0 -17
  62. package/cli/commands/nextjs/nextjs.ts +0 -10
  63. package/cli/eslint.config.mjs +0 -8
package/cli/README.md CHANGED
@@ -1,16 +1,68 @@
1
- # UDS ClI
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
- # Standalone executable
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
- ## Command structure
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, print } from 'bluebun';
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 (needsXcode) {
42
- console.write(
43
- 'You must have XCode installed before continuing... Visit https://apps.apple.com/us/app/xcode/id497799835?mt=12 to download.',
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
- if (needsXcrun) {
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: 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',
@@ -1,5 +1,6 @@
1
1
  import { $, semver } from 'bun';
2
- import { setup, needsBinary, needsBrewFormula, type MobileProps } from './_setup';
2
+
3
+ import { type MobileProps, needsBinary, needsBrewFormula, setup } from './_setup';
3
4
 
4
5
  export default {
5
6
  name: 'build',
@@ -1,6 +1,7 @@
1
1
  import { Props } from 'bluebun';
2
2
  import { $, sleep } from 'bun';
3
- import { setup, type MobileProps } from './_setup';
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: Props) => {
7
+ run: async (props: MobileProps) => {
8
8
  switch (props?.first) {
9
9
  case 'build':
10
- return require('./build').default.run(props);
10
+ return (await import('./build')).default.run(props);
11
11
  case 'dev':
12
- return require('./dev').default.run(props);
12
+ return (await import('./dev')).default.run(props);
13
13
  case 'launch':
14
- return require('./launch').default.run(props);
14
+ return (await import('./launch')).default.run(props);
15
15
  case 'update':
16
- return require('./update').default.run(props);
16
+ return (await import('./update')).default.run(props);
17
17
  default: {
18
18
  await getCommandHelp(props);
19
19
  break;
@@ -1,4 +1,5 @@
1
1
  import { $ } from 'bun';
2
+
2
3
  import type { MobileProps } from './_setup';
3
4
  import { setup } from './_setup';
4
5
 
@@ -1,4 +1,5 @@
1
1
  import { $ } from 'bun';
2
+
2
3
  import type { MobileProps } from './_setup';
3
4
  import { setup } from './_setup';
4
5
 
@@ -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
- import { setupConfigWorker } from '../../utils/setupConfigWorker';
3
- import { SyncOptions } from '../../utils/types';
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;
@@ -1,4 +1,5 @@
1
1
  import { type Props } from 'bluebun';
2
+
2
3
  import { getCommandHelp } from '../utils/getCommandHelp';
3
4
 
4
5
  export default {
package/cli/env.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ // See https://github.com/oven-sh/bun/issues/8736
2
+ /// <reference types="bun-types/overrides.d.ts" />
3
+
1
4
  declare module 'bun' {
2
5
  interface Env {
3
6
  PWD: string;
@@ -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
- console.log('setup websocket endpoint to watch for config updates');
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
- let lines: string[] = [];
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
- import { ConfigWorkerMainThreadMessage, SyncOptions } from './types';
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({ id, outFile, onUpdate }: ConfigWorkerOptions = {}) {
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}/${outFile}`;
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 ${id}`);
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"],l=["Georgia","Times","Times New Roman","serif"],b={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:l,name:"yahoo-serif-text"},"serif-display":{fallbacks:l,name:"yahoo-serif-display"}},d={display1:"sans",title1:"sans",title2:"sans",title3:"sans",title4:"sans",headline1:"sans",body1:"sans",label1:"sans",label2:"sans",caption1:"sans",caption2:"sans",legal1:"sans"},p={thin:"100",extralight:"200",light:"300",regular:"400",medium:"500",semibold:"600",bold:"700",extrabold:"800",black:"900"},c={display1:"black",title1:"bold",title2:"bold",title3:"bold",title4:"bold",headline1:"semibold",body1:"regular",label1:"semibold",label2:"regular",caption1:"semibold",caption2:"regular",legal1:"semibold"},g={display1:"uppercase",title1:"none",title2:"none",title3:"none",title4:"none",headline1:"none",body1:"none",label1:"none",label2:"none",caption1:"none",caption2:"none",legal1:"none"},i={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:{...i.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}},r={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{b as a,d as b,p as c,c as d,g as e,i as f,a as g,t as h,n as i,o as j,s as k,r as l};
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{c as d}from"./chunk-P7GR6E3K.js";import{a as y}from"./chunk-WYDHNV42.js";import{a as c}from"./chunk-74YHFBTD.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};
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};