@yahoo/uds 0.1.13 → 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,22 +1,21 @@
1
1
  import { EasJsonAccessor, EasJsonUtils, Platform } from '@expo/eas-json';
2
2
  import { type Props, print } from 'bluebun';
3
- import { $ } from 'bun';
3
+ import { $, semver, which } from 'bun';
4
4
 
5
5
  export interface MobileProps extends Props {
6
6
  options: {
7
7
  profile: string;
8
- platform: Platform.IOS | Platform.ANDROID;
8
+ platform: Platform;
9
9
  jsEngine?: 'hermes' | 'jsc';
10
10
  debug?: boolean;
11
11
  };
12
12
  }
13
13
 
14
- async function needsBinary(lib: string) {
15
- const whichLib = await $`which ${lib}`.text();
16
- return whichLib.includes('not found');
14
+ export async function needsBinary(lib: string) {
15
+ return which(lib) === null;
17
16
  }
18
17
 
19
- async function needsBrewFormula(formula: string) {
18
+ export async function needsBrewFormula(formula: string) {
20
19
  return (await $`brew list --formula | grep ${formula} | wc -l`.text()).trim() === '0';
21
20
  }
22
21
 
@@ -28,87 +27,67 @@ export async function setup({
28
27
  env?: Partial<typeof Bun.env>;
29
28
  }) {
30
29
  const { profile, platform, jsEngine = 'hermes', debug = false } = props.options;
30
+ const isIOS = platform === Platform.IOS;
31
+ const isAndroid = platform === Platform.ANDROID;
31
32
 
32
33
  /* -------------------------------------------------------------------------- */
33
- /* HOMEBREW SETUP */
34
+ /* XCODE SETUP */
34
35
  /* -------------------------------------------------------------------------- */
35
- const needsBrew = await needsBinary('brew');
36
- if (needsBrew) {
37
- console.log('Installing brew...');
38
- await $`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`;
39
- console.log('Installing brew...Complete');
36
+ if (isIOS) {
37
+ const xcodePath = await $`xcode-select -p`.text();
38
+ const needsXcode = !xcodePath.startsWith('/Applications');
39
+ const needsXcrun = await needsBinary('xcrun');
40
+
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
+ );
45
+ throw new Error('XCode not installed');
46
+ }
40
47
 
41
48
  /**
42
- * This portion of logic was ported from the homebrew installer script
43
- * https://github.com/Homebrew/install/blob/master/install.sh#L153C5-L153C63.
44
- * However, their script just alerts users to the fact that they need to add
45
- * brew to their path, but doesn't do it for them. This logic attempts to do that
46
- * so we can automatically proceed to the next steps of auto-installing
47
- * the necessary dependencies for local development.
49
+ * Installing the XCode command line tools & simulators normally
50
+ * requires opening up XCode to install.
51
+ * This conditional is to avoid having to do that.
48
52
  */
49
- const machineArch = await $`uname -m`.text();
50
- const isLinux = (await $`uname`.text()) === 'Linux';
51
- const shellType = await $`echo $SHELL`.text();
52
- const homebrewPrefix = machineArch.includes('arm64') ? '/opt/homebrew' : '/usr/local';
53
- let shellRcFile;
54
-
55
- if (isLinux) {
56
- shellRcFile = shellType.includes('zsh') ? '.zshrc' : '.bashrc';
57
- } else {
58
- shellRcFile = shellType.includes('zsh') ? '.zprofile' : '.bash_profile';
59
- }
60
-
61
- const shellRcPath = `${Bun.env.HOME}/${shellRcFile}`;
62
- let shellRcContents = '';
63
- try {
64
- shellRcContents = await Bun.file(shellRcPath).text();
65
- } catch (err) {
66
- // Ignore if it doesn't exist. We create it below.
67
- }
68
-
69
- if (!shellRcContents.includes('homebrew')) {
70
- console.log('Adding brew to $PATH...');
71
- const newShellRcContents = `${shellRcContents}\neval "$(${homebrewPrefix}/bin/brew shellenv)"`;
72
- await Bun.write(shellRcPath, newShellRcContents);
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`;
73
59
  }
74
60
  }
75
61
 
76
- /* -------------------------------------------------------------------------- */
77
- /* FASTLANE SETUP */
78
- /* -------------------------------------------------------------------------- */
79
- const needsFastlane = await needsBrewFormula('fastlane');
80
- if (needsFastlane) {
81
- console.log('Installing fastlane...');
82
- await $`brew install fastlane`;
83
- }
84
-
85
- /* -------------------------------------------------------------------------- */
86
- /* COCOAPODS SETUP */
87
- /* -------------------------------------------------------------------------- */
88
- const needsCocoapods = await needsBrewFormula('cocoapods');
89
- if (needsCocoapods) {
90
- console.log('Installing cocoapods...');
91
- await $`brew install cocoapods`;
92
- }
93
-
94
62
  /* -------------------------------------------------------------------------- */
95
63
  /* JAVA DEVELOPMENT KIT */
96
64
  /* -------------------------------------------------------------------------- */
97
- if (platform === 'android') {
65
+ if (isAndroid) {
98
66
  const jdkPath = await $`brew info --cask zulu17`.text();
99
67
  const needsJdk = jdkPath.includes('unavailable');
100
68
  if (needsJdk) {
101
- console.log('Installing Java Development Kit for Android...');
69
+ console.write('Installing Java Development Kit for Android...');
102
70
  await $`brew install --cask zulu17`;
103
71
  }
104
72
  }
105
73
 
106
74
  /* -------------------------------------------------------------------------- */
107
- /* EXPO SETUP */
75
+ /* EAS CONFIG SETUP */
108
76
  /* -------------------------------------------------------------------------- */
77
+ /**
78
+ * eas.json is used to define build profiles for different environments.
79
+ * For example, you may have a profile for development, staging, and production.
80
+ *
81
+ * The EAS CLI is used to build and run an app locally based on the eas.json,
82
+ * but it isn't opinionated about how you define your profiles.
83
+ *
84
+ * We however want to enforce some conventions to make it easier to get started.
85
+ * We also want to store our builds outside of EAS ecosystem since they auto
86
+ * delete after 30 days & our builds infrequently.
87
+ *
88
+ */
109
89
  const appDirectory = Bun.env.PWD;
110
90
  const easJsonAccessor = EasJsonAccessor.fromProjectPath(appDirectory);
111
-
112
91
  const easProfiles = await EasJsonUtils.getBuildProfileNamesAsync(easJsonAccessor);
113
92
 
114
93
  if (!easProfiles.includes(profile)) {
@@ -126,20 +105,22 @@ export async function setup({
126
105
  }
127
106
 
128
107
  const easJsonConfig = await EasJsonUtils.getBuildProfileAsync(easJsonAccessor, platform, profile);
129
-
130
108
  const easCliConfig = await EasJsonUtils.getCliConfigAsync(easJsonAccessor);
131
109
  const easCliVersion = easCliConfig?.version ?? 'latest';
132
110
 
133
111
  /* -------------------------------------------------------------------------- */
134
112
  /* EAS CLI SETUP */
135
113
  /* -------------------------------------------------------------------------- */
114
+ /**
115
+ * EAS CLI is used to build and run an app locally.
116
+ */
136
117
  const needsEasCli = await needsBinary('eas');
137
118
  if (needsEasCli) {
138
- await $`bun install eas-cli@${easCliVersion} -g`;
119
+ await $`bun install eas-cli@${easCliVersion} -g`.quiet();
139
120
  } else {
140
121
  const currentEasCliVersion = await $`eas --version`.text();
141
- if (currentEasCliVersion !== easCliVersion) {
142
- await $`bun install eas-cli@${easCliVersion} -g`;
122
+ if (!semver.satisfies(currentEasCliVersion, easCliVersion)) {
123
+ await $`bun install eas-cli@${easCliVersion} -g`.quiet();
143
124
  }
144
125
  }
145
126
 
@@ -150,7 +131,7 @@ export async function setup({
150
131
  } = easJsonConfig.env ?? {};
151
132
 
152
133
  // TODO: Add additional checks for ensuring this value adheres to Android formatting specs
153
- if (platform === Platform.ANDROID && !androidId) {
134
+ if (isAndroid && !androidId) {
154
135
  throw new Error(`
155
136
  APP_ANDROID_BUNDLE_IDENTIFIER must be defined in eas.json within the ${profile} > env config.
156
137
  See https://docs.expo.dev/build-reference/variables/#setting-plaintext-environment-variables-in-easjson for information about env variables in eas.json
@@ -174,7 +155,7 @@ export async function setup({
174
155
  }
175
156
 
176
157
  // TODO: Add additional checks for ensuring this value adheres to Uniform Type Identifier
177
- if (platform === Platform.IOS && !appleId) {
158
+ if (isIOS && !appleId) {
178
159
  throw new Error(`
179
160
  APP_APPLE_BUNDLE_IDENTIFIER must be defined in eas.json within the ${profile} > env config.
180
161
  See https://docs.expo.dev/build-reference/variables/#setting-plaintext-environment-variables-in-easjson for information about env variables in eas.json
@@ -197,11 +178,13 @@ export async function setup({
197
178
  }
198
179
 
199
180
  const outputName = `${platform}-${profile}-${jsEngine}`;
200
- // TODO: make this configurable
201
- const prebuildsDir = `${appDirectory}/prebuilds`;
181
+ const prebuildsDir = `${appDirectory}/prebuilds`; // TODO: make this configurable
202
182
  const outputDir = `${prebuildsDir}/${outputName}`;
203
183
  const outputFileBase = `${outputDir}/${outputName}`;
204
184
 
185
+ /* -------------------------------------------------------------------------- */
186
+ /* ENVIRONMENT VARIABLES */
187
+ /* -------------------------------------------------------------------------- */
205
188
  let envVars = Bun.env;
206
189
 
207
190
  envVars = {
@@ -226,6 +209,7 @@ export async function setup({
226
209
  envVars = { ...envVars, ...envOpts };
227
210
  }
228
211
 
212
+ /** Change the default environment variables for shells created by this instance. */
229
213
  $.env(envVars);
230
214
 
231
215
  const output = {
@@ -233,10 +217,10 @@ export async function setup({
233
217
  dir: outputDir,
234
218
  prebuildsDir: prebuildsDir,
235
219
  fileBase: outputFileBase,
236
- artifact: platform === 'ios' ? `${outputFileBase}.tar.gz` : `${outputFileBase}.zip`,
237
- app: platform === 'ios' ? `${outputFileBase}.app` : 'todo fix android',
220
+ artifact: isIOS ? `${outputFileBase}.tar.gz` : `${outputFileBase}.zip`,
221
+ app: isIOS ? `${outputFileBase}.app` : 'todo fix android',
238
222
  get launchFile() {
239
- return platform === 'ios' ? this.artifact : this.apk.signed;
223
+ return isIOS ? this.artifact : this.apk.signed;
240
224
  },
241
225
  apk: {
242
226
  contents: `${outputFileBase}/build`,
@@ -248,7 +232,7 @@ export async function setup({
248
232
  };
249
233
 
250
234
  return {
251
- scheme: platform === 'ios' ? appleId : androidId,
235
+ scheme: isIOS ? appleId : androidId,
252
236
  channel: easJsonConfig.channel,
253
237
  debug,
254
238
  profile,
@@ -1,6 +1,5 @@
1
- import { $ } from 'bun';
2
- import type { MobileProps } from './_setup';
3
- import { setup } from './_setup';
1
+ import { $, semver } from 'bun';
2
+ import { setup, needsBinary, needsBrewFormula, type MobileProps } from './_setup';
4
3
 
5
4
  export default {
6
5
  name: 'build',
@@ -10,6 +9,88 @@ export default {
10
9
  props,
11
10
  });
12
11
 
12
+ /* ----- Homebrew, Fastlane, and Cocoapods are only required for builds. ---- */
13
+ /* -------------------------------------------------------------------------- */
14
+ /* HOMEBREW SETUP */
15
+ /* -------------------------------------------------------------------------- */
16
+ const needsBrew = await needsBinary('brew');
17
+ if (needsBrew) {
18
+ console.write('Installing brew...');
19
+ await $`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`;
20
+ console.write('Installing brew...Complete');
21
+
22
+ /**
23
+ * This logic was ported from the homebrew installer script
24
+ * https://github.com/Homebrew/install/blob/master/install.sh#L153C5-L153C63.
25
+ * However, their script just alerts users to the fact that they need to add
26
+ * brew to their path, but doesn't do it for them. This logic attempts to do that
27
+ * so we can automatically proceed to the next steps of auto-installing
28
+ * the necessary dependencies for local development.
29
+ */
30
+ const machineArch = await $`uname -m`.text();
31
+ const isLinux = (await $`uname`.text()) === 'Linux';
32
+ const shellType = await $`echo $SHELL`.text();
33
+ const homebrewPrefix = machineArch.includes('arm64') ? '/opt/homebrew' : '/usr/local';
34
+ let shellRcFile;
35
+
36
+ if (isLinux) {
37
+ shellRcFile = shellType.includes('zsh') ? '.zshrc' : '.bashrc';
38
+ } else {
39
+ shellRcFile = shellType.includes('zsh') ? '.zprofile' : '.bash_profile';
40
+ }
41
+
42
+ const shellRcPath = `${Bun.env.HOME}/${shellRcFile}`;
43
+ let shellRcContents = '';
44
+ try {
45
+ shellRcContents = await Bun.file(shellRcPath).text();
46
+ } catch (err) {
47
+ // Ignore if it doesn't exist. We create it below.
48
+ }
49
+
50
+ if (!shellRcContents.includes('homebrew')) {
51
+ console.write('Adding brew to $PATH...');
52
+ const newShellRcContents = `${shellRcContents}\neval "$(${homebrewPrefix}/bin/brew shellenv)"`;
53
+ await Bun.write(shellRcPath, newShellRcContents);
54
+ }
55
+ }
56
+
57
+ /* -------------------------------------------------------------------------- */
58
+ /* FASTLANE SETUP */
59
+ /* -------------------------------------------------------------------------- */
60
+ const needsFastlane = await needsBrewFormula('fastlane');
61
+ if (needsFastlane) {
62
+ console.write('Installing fastlane...');
63
+ await $`brew install fastlane`;
64
+ }
65
+
66
+ /* -------------------------------------------------------------------------- */
67
+ /* COCOAPODS SETUP */
68
+ /* -------------------------------------------------------------------------- */
69
+ const needsCocoapods = await needsBrewFormula('cocoapods');
70
+ /** https://github.com/facebook/react-native/issues/42698#issuecomment-1915670708 */
71
+ const validCocoapodsVersion = '1.14.3';
72
+
73
+ const installCocoapods = async () =>
74
+ await $`brew install ${import.meta.dirname}/install/cocoapods.rb`;
75
+
76
+ if (needsCocoapods) {
77
+ console.write('Installing cocoapods...');
78
+ await installCocoapods();
79
+ } else {
80
+ const cocoapodsVersion = await $`pod --version`.text();
81
+ const needsDowngrade = semver.satisfies(cocoapodsVersion, `>${validCocoapodsVersion}`);
82
+ if (needsDowngrade) {
83
+ await $`brew unlink cocoapods`;
84
+ await $`brew uninstall cocoapods`;
85
+ console.write(
86
+ `Downgrading cocoapods from ${cocoapodsVersion} to ${validCocoapodsVersion}...`,
87
+ );
88
+ await installCocoapods();
89
+ await $`brew link cocoapods`;
90
+ }
91
+ }
92
+
13
93
  await $`eas build --local --non-interactive --json --clear-cache --platform ${platform} --profile ${profile} --output ${output.artifact}`;
94
+ console.write('You can now run your dev command to start the app!');
14
95
  },
15
96
  };
@@ -1,5 +1,5 @@
1
1
  import { Props } from 'bluebun';
2
- import { $ } from 'bun';
2
+ import { $, sleep } from 'bun';
3
3
  import { setup, type MobileProps } from './_setup';
4
4
 
5
5
  interface MobileStartProps extends Props {
@@ -12,7 +12,7 @@ interface MobileStartProps extends Props {
12
12
  type SimDevice = { udid: string; name: string; state: 'Booted' | 'Shutdown' };
13
13
  type SimList = {
14
14
  devices: {
15
- ['com.apple.CoreSimulator.SimRuntime.iOS-17-2']: SimDevice[];
15
+ [key: string]: SimDevice[];
16
16
  };
17
17
  };
18
18
 
@@ -20,7 +20,6 @@ export default {
20
20
  name: 'dev',
21
21
  description: '🚧 Dev',
22
22
  run: async (props: MobileStartProps) => {
23
- console.log('running dev');
24
23
  const { platform, scheme, output } = await setup({
25
24
  props,
26
25
  env: {
@@ -28,52 +27,56 @@ export default {
28
27
  },
29
28
  });
30
29
 
31
- if (platform === 'ios') {
32
- const xcodePath = await $`xcode-select -p`.text();
33
- const xcodeExists = xcodePath.startsWith('/Applications');
34
-
35
- if (xcodeExists) {
36
- await $`open -a simulator`;
37
- const deviceList = (await $`xcrun simctl list devices available -j -e`.json()) as SimList;
38
-
39
- const devices = Object.values(deviceList?.devices).flatMap((item) => item);
40
-
41
- if (devices.length === 0) {
42
- throw new Error('No devices found');
43
- } else {
44
- const isBooted = devices.find((device: SimDevice) => device.state === 'Booted');
45
- if (!isBooted) {
46
- const iphone15Max = devices.find(
47
- (device: SimDevice) => device.name === 'iPhone 15 Pro Max',
48
- );
49
- if (!iphone15Max) {
50
- throw new Error('iPhone 15 Pro Max not found');
51
- } else {
52
- const udid = iphone15Max.udid;
53
- await $`xcrun simctl boot ${udid}`;
54
- }
55
- }
56
- }
57
- } else {
58
- console.log(
59
- 'You must have XCode installed before continuing... Visit https://apps.apple.com/us/app/xcode/id497799835?mt=12 to download.',
60
- );
61
- throw new Error('XCode not installed');
62
- }
63
- }
64
-
65
- await $`eas build:run --platform ${platform} --path ${output.launchFile}`;
66
-
67
30
  const extraArgs = [];
68
31
 
69
32
  if (props.options.clear) {
70
33
  extraArgs.push('--clear');
71
34
  }
72
-
73
35
  const extrArgsString = extraArgs.join(' ');
74
36
 
75
- console.log(`Starting metro server...`);
37
+ try {
38
+ /**
39
+ * Get list of devices.
40
+ * If there is a booted device, open the simulator on that device.
41
+ * If no booted device is found, open the simulator on iPhone 15 Pro Max.
42
+ * * https://github.com/expo/orbit/blob/main/packages/eas-shared/src/run/ios/simulator.ts#L98
43
+ *
44
+ * TODO:
45
+ * Should we open app on all booted devices if there are multiple open?
46
+ * Should we prompt user to pick from one of the booted devices?
47
+ * Should we prompt user to pick a device if there are no booted devices?
48
+ */
49
+ if (platform === 'ios') {
50
+ const deviceList =
51
+ (await $`xcrun simctl list devices available --json -e`.json()) as SimList;
52
+ const devices = Object.values(deviceList?.devices).flatMap((item) => item);
53
+ const bootedDevice = devices.find((device: SimDevice) => device.state === 'Booted');
54
+ if (!bootedDevice) {
55
+ const iphone15ProMax = devices.find((device) => device.name === 'iPhone 15 Pro Max');
56
+ const iphone15Udid = iphone15ProMax?.udid;
57
+ await $`open -a Simulator --args -CurrentDeviceUDID ${iphone15Udid}`;
58
+ }
59
+ }
60
+
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
+ sleep(3000).then(async () => {
69
+ /**
70
+ * Launch the app on the booted device
71
+ * https://github.com/expo/eas-cli?tab=readme-ov-file#eas-buildrun
72
+ */
73
+ await $`eas build:run --platform ${platform} --path ${output.launchFile}`;
74
+ });
76
75
 
77
- await $`expo start --${platform} --dev-client --localhost --scheme ${scheme} ${extrArgsString}`;
76
+ console.write('Starting Metro server...');
77
+ await $`expo start --${platform} --dev-client --localhost --scheme ${scheme} ${extrArgsString}`;
78
+ } catch (err) {
79
+ throw err;
80
+ }
78
81
  },
79
82
  };
@@ -0,0 +1,35 @@
1
+ class Cocoapods < Formula
2
+ desc "Dependency manager for Cocoa projects"
3
+ homepage "https://cocoapods.org/"
4
+ url "https://github.com/CocoaPods/CocoaPods/archive/refs/tags/1.14.3.tar.gz"
5
+ sha256 "de05766e5771e0cef7af89f73b0e42a1f1c52a76ce1288592cd9511bcd688a9e"
6
+ license "MIT"
7
+ revision 1
8
+
9
+ bottle do
10
+ sha256 cellar: :any, arm64_sonoma: "0fb8e638fb4901b6c578c44ae1af0098a0b3530e7a339bf43f2fb67f2819d412"
11
+ sha256 cellar: :any, arm64_ventura: "e3d0c8624df429cb30c5cf818f3a358d4f678b374410e9fbc8fde090889f9b61"
12
+ sha256 cellar: :any, arm64_monterey: "a6df519bae3f51b1609cfcd017b4d47cb688200780ffb9b27d57a5dc05ea93de"
13
+ sha256 cellar: :any, sonoma: "5c2ee41824fcb154b46f9fa967f203fbf9009d2051f8c898375d69d333052988"
14
+ sha256 cellar: :any, ventura: "91459cb108161201a81fdd0e96a126e9843be8213112c208051e8e72ce9736f9"
15
+ sha256 cellar: :any, monterey: "316b0954e21f76c013d8c581c589e4f884231687eb2253a9f9a38a77a87728a6"
16
+ sha256 cellar: :any_skip_relocation, x86_64_linux: "2d5be1290e8161d9a49b3fd191fc8423aac29f61fbc84148c8ba08cdc03d8d84"
17
+ end
18
+
19
+ depends_on "pkg-config" => :build
20
+ depends_on "ruby"
21
+ uses_from_macos "libffi", since: :catalina
22
+
23
+ def install
24
+ ENV["GEM_HOME"] = libexec
25
+ system "gem", "build", "cocoapods.gemspec"
26
+ system "gem", "install", "cocoapods-#{version}.gem"
27
+ # Other executables don't work currently.
28
+ bin.install libexec/"bin/pod", libexec/"bin/xcodeproj"
29
+ bin.env_script_all_files(libexec/"bin", GEM_HOME: ENV["GEM_HOME"])
30
+ end
31
+
32
+ test do
33
+ system "#{bin}/pod", "list"
34
+ end
35
+ end
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yahoo/uds",
3
3
  "description": "Yahoo Universal System",
4
- "version": "0.1.13",
4
+ "version": "0.1.14",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "uds": "./cli/uds-cli"
@@ -88,10 +88,10 @@
88
88
  "build": "bun run build:fontcss && bun run build:fixtures && tsup",
89
89
  "build:css": "tailwindcss --input ./src/tailwind/uds.css --output ./generated/uds.css --config ./src/tailwind/tailwind.config.ts",
90
90
  "build:fixtures": "bun run ./scripts/buildFixtures.ts",
91
- "build:fontcss": "tsx ./scripts/generateFontCSS.ts --output ./generated/fonts.css",
91
+ "build:fontcss": "bun run ./scripts/generateFontCSS.ts --output ./generated/fonts.css",
92
92
  "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
93
93
  "dev": "concurrently bun:dev:*",
94
- "dev:fontcss": "tsx watch --clear-screen=false ./scripts/generateFontCSS.ts --output ./generated/fonts.css",
94
+ "dev:fontcss": "bun run --watch --clear-screen=false ./scripts/generateFontCSS.ts --output ./generated/fonts.css",
95
95
  "dev:ts": "tsup --watch",
96
96
  "lint": "ESLINT_USE_FLAT_CONFIG=true eslint -c eslint.config.mjs .",
97
97
  "lint:pkg": "bun publint",
@@ -113,18 +113,9 @@
113
113
  "tailwind-merge": "^2.2.1"
114
114
  },
115
115
  "devDependencies": {
116
- "@gorhom/bottom-sheet": "^4.6.0",
117
- "@react-navigation/native": "^6.0.2",
118
116
  "@types/react": "^18.2.48",
119
117
  "@types/react-dom": "^18.2.18",
120
118
  "concurrently": "^8.2.2",
121
- "expo-constants": "^15.4.5",
122
- "expo-image": "^1.10.4",
123
- "expo-status-bar": "^1.11.1",
124
- "react": "^18.2.0",
125
- "react-dom": "^18.2.0",
126
- "react-native": "^0.73.2",
127
- "react-native-safe-area-context": "^4.8.2",
128
119
  "shared": "workspace:*",
129
120
  "tsconfig": "workspace:*",
130
121
  "tsup": "^8.0.1",
@@ -143,9 +134,6 @@
143
134
  "tailwindcss": "^3.4.1"
144
135
  },
145
136
  "peerDependenciesMeta": {
146
- "@expo/eas-json": {
147
- "optional": true
148
- },
149
137
  "@gorhom/bottom-sheet": {
150
138
  "optional": true
151
139
  },