expo-brownfield 56.0.13 → 56.0.15

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/CHANGELOG.md CHANGED
@@ -10,6 +10,20 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 56.0.15 — 2026-05-26
14
+
15
+ ### 🎉 New features
16
+
17
+ - [iOS] Make `ReactNativeHostManager` accessible directly to Objective-C. ([#46227](https://github.com/expo/expo/pull/46227) by [@gabrieldonadel](https://github.com/gabrieldonadel))
18
+
19
+ ### 🐛 Bug fixes
20
+
21
+ - [iOS] `build:ios` now detects a missing iOS workspace and prompts to run `pod install` instead of failing with a vague "Could not find brownfield iOS workspace". ([#46247](https://github.com/expo/expo/pull/46247) by [@gabrieldonadel](https://github.com/gabrieldonadel))
22
+
23
+ ## 56.0.14 — 2026-05-23
24
+
25
+ _This version does not introduce any user-facing changes._
26
+
13
27
  ## 56.0.13 — 2026-05-21
14
28
 
15
29
  _This version does not introduce any user-facing changes._
@@ -4,7 +4,7 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'expo.modules.brownfield'
7
- version = '56.0.13'
7
+ version = '56.0.15'
8
8
 
9
9
  expoModule {
10
10
  canBePublished false
@@ -14,7 +14,7 @@ android {
14
14
  namespace "expo.modules.brownfield"
15
15
  defaultConfig {
16
16
  versionCode 1
17
- versionName '56.0.13'
17
+ versionName '56.0.15'
18
18
  }
19
19
  }
20
20
 
@@ -2,8 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("../utils");
4
4
  const buildIos = async (command) => {
5
- await (0, utils_1.validatePrebuild)('ios');
6
- const config = (0, utils_1.resolveBuildConfigIos)(command.opts());
5
+ const opts = command.opts();
6
+ await (0, utils_1.validatePrebuild)('ios', { dryRun: !!opts.dryRun });
7
+ const config = (0, utils_1.resolveBuildConfigIos)(opts);
7
8
  (0, utils_1.printIosConfig)(config);
8
9
  await (0, utils_1.buildFramework)(config);
9
10
  if (config.output !== 'frameworks') {
@@ -1 +1 @@
1
- {"version":3,"file":"build-ios.js","sourceRoot":"","sources":["../../src/commands/build-ios.ts"],"names":[],"mappings":";;AAEA,oCAOkB;AAElB,MAAM,QAAQ,GAAG,KAAK,EAAE,OAAgB,EAAE,EAAE;IAC1C,MAAM,IAAA,wBAAgB,EAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAA,6BAAqB,EAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACrD,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAC;IAEvB,MAAM,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAC;IAE7B,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACnC,mCAAmC;QACnC,IAAA,wBAAgB,EAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,6CAA6C;QAC7C,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAC;IACzB,CAAC;AACH,CAAC,CAAC;AAEF,kBAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"build-ios.js","sourceRoot":"","sources":["../../src/commands/build-ios.ts"],"names":[],"mappings":";;AAEA,oCAOkB;AAElB,MAAM,QAAQ,GAAG,KAAK,EAAE,OAAgB,EAAE,EAAE;IAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,IAAA,wBAAgB,EAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,IAAA,6BAAqB,EAAC,IAAI,CAAC,CAAC;IAC3C,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAC;IAEvB,MAAM,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAC;IAE7B,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACnC,mCAAmC;QACnC,IAAA,wBAAgB,EAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,6CAA6C;QAC7C,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAC;IACzB,CAAC;AACH,CAAC,CAAC;AAEF,kBAAe,QAAQ,CAAC"}
@@ -1,4 +1,4 @@
1
- type ErrorType = 'android-task-repo' | 'android-directory-not-found' | 'android-library-unknown-error' | 'android-library-not-found' | 'ios-artifacts-directory-unknown-error' | 'ios-directory-not-found' | 'ios-directory-unknown-error' | 'ios-hermes-framework-not-found' | 'ios-prebuilds-spm-dep-missing' | 'ios-scheme-not-found' | 'ios-workspace-not-found' | 'ios-workspace-unknown-error' | 'package-not-installed' | 'plugin-not-configured' | 'prebuild-cancelled';
1
+ type ErrorType = 'android-task-repo' | 'android-directory-not-found' | 'android-library-unknown-error' | 'android-library-not-found' | 'ios-artifacts-directory-unknown-error' | 'ios-directory-not-found' | 'ios-directory-unknown-error' | 'ios-hermes-framework-not-found' | 'ios-pod-install-cancelled' | 'ios-prebuilds-spm-dep-missing' | 'ios-scheme-not-found' | 'ios-workspace-not-found' | 'ios-workspace-unknown-error' | 'package-not-installed' | 'plugin-not-configured' | 'prebuild-cancelled';
2
2
  declare class CLIError {
3
3
  private static readonly errorSymbol;
4
4
  private static readonly errorMessages;
@@ -11,9 +11,10 @@ class CLIError {
11
11
  'ios-directory-not-found': 'Cannot find `ios` directory in the project',
12
12
  'ios-directory-unknown-error': 'Unknown error occurred while finding brownfield iOS scheme',
13
13
  'ios-hermes-framework-not-found': 'Could not find hermes framework in the project at path',
14
+ 'ios-pod-install-cancelled': 'Brownfield cannot be built without installing CocoaPods. Run `pod install` in the `ios/` and try again.',
14
15
  'ios-prebuilds-spm-dep-missing': "Could not find a prebuilt xcframework for an SPM dependency declared by an Expo module. The brownfield Swift Package would ship without it, causing `Library not loaded: @rpath/...` at runtime in the host app. Either re-install the affected Expo module from a release published with bundled SPM deps (`bundleSharedDeps: true`), populate the monorepo's `packages/precompile/.build/.spm-deps/` cache, or set `EXPO_PRECOMPILED_MODULES_PATH` to a directory that contains `.spm-deps/<dep>/<flavor>/<dep>.xcframework`.",
15
16
  'ios-scheme-not-found': 'Could not find brownfield iOS scheme',
16
- 'ios-workspace-not-found': 'Could not find brownfield iOS workspace',
17
+ 'ios-workspace-not-found': 'Could not find a brownfield iOS workspace (`.xcworkspace`) in the `ios/` directory. This usually means `pod install` has not been run yet. Run `pod install` and try again.',
17
18
  'ios-workspace-unknown-error': 'Unknown error occurred while finding brownfield iOS workspace',
18
19
  'package-not-installed': 'expo-brownfield is not installed in the project. Install it with `npx expo install expo-brownfield`',
19
20
  'plugin-not-configured': 'expo-brownfield is not configured as a plugin. Add it to the `plugins` array in your app config',
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":";;AAiBA,MAAM,QAAQ;IACJ,MAAM,CAAU,WAAW,GAAW,GAAG,CAAC;IAC1C,MAAM,CAAU,aAAa,GAA8B;QACjE,mBAAmB,EAAE,mDAAmD;QACxE,6BAA6B,EAAE,gDAAgD;QAC/E,+BAA+B,EAAE,yDAAyD;QAC1F,2BAA2B,EAAE,kDAAkD;QAC/E,uCAAuC,EACrC,2DAA2D;QAC7D,yBAAyB,EAAE,4CAA4C;QACvE,6BAA6B,EAAE,4DAA4D;QAC3F,gCAAgC,EAAE,wDAAwD;QAC1F,+BAA+B,EAC7B,igBAAigB;QACngB,sBAAsB,EAAE,sCAAsC;QAC9D,yBAAyB,EAAE,yCAAyC;QACpE,6BAA6B,EAAE,+DAA+D;QAC9F,uBAAuB,EACrB,qGAAqG;QACvG,uBAAuB,EACrB,iGAAiG;QACnG,oBAAoB,EAAE,mEAAmE;KAC1F,CAAC;IAEK,MAAM,CAAC,MAAM,CAAC,KAAgB,EAAE,eAAuB,EAAE,EAAE,QAAiB,IAAI;QACrF,MAAM,OAAO,GAAG,YAAY;YAC1B,CAAC,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,YAAY,EAAE;YACjD,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAEO,MAAM,CAAC,cAAc,CAAC,OAAe,EAAE,QAAiB,IAAI;QAClE,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,WAAW,WAAW,OAAO,EAAE,CAAC,CAAC;QACvD,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;;AAGH,kBAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":";;AAkBA,MAAM,QAAQ;IACJ,MAAM,CAAU,WAAW,GAAW,GAAG,CAAC;IAC1C,MAAM,CAAU,aAAa,GAA8B;QACjE,mBAAmB,EAAE,mDAAmD;QACxE,6BAA6B,EAAE,gDAAgD;QAC/E,+BAA+B,EAAE,yDAAyD;QAC1F,2BAA2B,EAAE,kDAAkD;QAC/E,uCAAuC,EACrC,2DAA2D;QAC7D,yBAAyB,EAAE,4CAA4C;QACvE,6BAA6B,EAAE,4DAA4D;QAC3F,gCAAgC,EAAE,wDAAwD;QAC1F,2BAA2B,EACzB,yGAAyG;QAC3G,+BAA+B,EAC7B,igBAAigB;QACngB,sBAAsB,EAAE,sCAAsC;QAC9D,yBAAyB,EACvB,6KAA6K;QAC/K,6BAA6B,EAAE,+DAA+D;QAC9F,uBAAuB,EACrB,qGAAqG;QACvG,uBAAuB,EACrB,iGAAiG;QACnG,oBAAoB,EAAE,mEAAmE;KAC1F,CAAC;IAEK,MAAM,CAAC,MAAM,CAAC,KAAgB,EAAE,eAAuB,EAAE,EAAE,QAAiB,IAAI;QACrF,MAAM,OAAO,GAAG,YAAY;YAC1B,CAAC,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,YAAY,EAAE;YACjD,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAEO,MAAM,CAAC,cAAc,CAAC,OAAe,EAAE,QAAiB,IAAI;QAClE,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,WAAW,WAAW,OAAO,EAAE,CAAC,CAAC;QACvD,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;;AAGH,kBAAe,QAAQ,CAAC"}
@@ -1,3 +1,5 @@
1
1
  import type { Platform } from './types';
2
- export declare const validatePrebuild: (platform: Platform) => Promise<void>;
2
+ export declare const validatePrebuild: (platform: Platform, options?: {
3
+ dryRun?: boolean;
4
+ }) => Promise<void>;
3
5
  export declare const validatePackageInstalled: () => void;
@@ -12,7 +12,7 @@ const node_path_1 = __importDefault(require("node:path"));
12
12
  const prompts_1 = __importDefault(require("prompts"));
13
13
  const error_1 = __importDefault(require("./error"));
14
14
  const spinner_1 = require("./spinner");
15
- const validatePrebuild = async (platform) => {
15
+ const validatePrebuild = async (platform, options = {}) => {
16
16
  (0, exports.validatePackageInstalled)();
17
17
  if (!checkPrebuild(platform)) {
18
18
  console.info(`${chalk_1.default.yellow(`⚠ Prebuild for platform: ${platform} is missing`)}`);
@@ -35,8 +35,49 @@ const validatePrebuild = async (platform) => {
35
35
  error_1.default.handle('prebuild-cancelled');
36
36
  }
37
37
  }
38
+ if (platform === 'ios' && !options.dryRun) {
39
+ await validateIosPodsInstalled();
40
+ }
38
41
  };
39
42
  exports.validatePrebuild = validatePrebuild;
43
+ const validateIosPodsInstalled = async () => {
44
+ if (checkIosWorkspace()) {
45
+ return;
46
+ }
47
+ console.info(`${chalk_1.default.yellow('⚠ iOS workspace not found. CocoaPods has not been installed in the `ios/` directory yet.')}`);
48
+ const response = await (0, prompts_1.default)({
49
+ type: 'confirm',
50
+ name: 'shouldRunPodInstall',
51
+ message: 'Do you want to run `pod install` now?',
52
+ initial: true,
53
+ });
54
+ if (!response.shouldRunPodInstall) {
55
+ error_1.default.handle('ios-pod-install-cancelled');
56
+ return;
57
+ }
58
+ await (0, spinner_1.withSpinner)({
59
+ operation: () => (0, spawn_async_1.default)('pod', ['install'], { cwd: node_path_1.default.join(process.cwd(), 'ios') }),
60
+ loaderMessage: 'Running `pod install` in the `ios` directory...',
61
+ successMessage: 'Pod install completed\n',
62
+ errorMessage: 'Pod install failed',
63
+ verbose: false,
64
+ });
65
+ if (!checkIosWorkspace()) {
66
+ error_1.default.handle('ios-workspace-not-found');
67
+ }
68
+ };
69
+ const checkIosWorkspace = () => {
70
+ const iosPath = node_path_1.default.join(process.cwd(), 'ios');
71
+ if (!node_fs_1.default.existsSync(iosPath)) {
72
+ return false;
73
+ }
74
+ try {
75
+ return node_fs_1.default.readdirSync(iosPath).some((name) => name.endsWith('.xcworkspace'));
76
+ }
77
+ catch {
78
+ return false;
79
+ }
80
+ };
40
81
  const validatePackageInstalled = () => {
41
82
  const PACKAGE_NAME = 'expo-brownfield';
42
83
  const packageJson = (0, config_1.getPackageJson)(process.cwd());
@@ -1 +1 @@
1
- {"version":3,"file":"prebuild.js","sourceRoot":"","sources":["../../src/utils/prebuild.ts"],"names":[],"mappings":";;;;;;AAAA,oEAA2C;AAC3C,kDAA0B;AAC1B,wCAAwD;AACxD,sDAAyB;AACzB,0DAA6B;AAC7B,sDAA8B;AAE9B,oDAA+B;AAC/B,uCAAwC;AAGjC,MAAM,gBAAgB,GAAG,KAAK,EAAE,QAAkB,EAAiB,EAAE;IAC1E,IAAA,gCAAwB,GAAE,CAAC;IAE3B,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,GAAG,eAAK,CAAC,MAAM,CAAC,4BAA4B,QAAQ,aAAa,CAAC,EAAE,CAAC,CAAC;QACnF,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAO,EAAC;YAC7B,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,sCAAsC;YAC/C,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,iBAAiB,EAAE,CAAC;YAC/B,MAAM,IAAA,qBAAW,EAAC;gBAChB,SAAS,EAAE,GAAG,EAAE,CAAC,IAAA,qBAAU,EAAC,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;gBAChF,aAAa,EAAE,6CAA6C,QAAQ,KAAK;gBACzE,cAAc,EAAE,gBAAgB,QAAQ,cAAc;gBACtD,YAAY,EAAE,gBAAgB,QAAQ,SAAS;gBAC/C,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,eAAQ,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAxBW,QAAA,gBAAgB,oBAwB3B;AAEK,MAAM,wBAAwB,GAAG,GAAS,EAAE;IACjD,MAAM,YAAY,GAAG,iBAAiB,CAAC;IACvC,MAAM,WAAW,GAAG,IAAA,uBAAc,EAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9F,eAAQ,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IACD,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAS,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,yBAAyB,EAAE,IAAI,EAAE,CAAC,CAAC;IACtF,MAAM,4BAA4B,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CACnE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,CAC7E,CAAC;IACF,IAAI,CAAC,4BAA4B,EAAE,CAAC;QAClC,eAAQ,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC;AAdW,QAAA,wBAAwB,4BAcnC;AAEF,MAAM,aAAa,GAAG,CAAC,QAAkB,EAAW,EAAE;IACpD,MAAM,eAAe,GAAG,mBAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC3D,OAAO,iBAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AACxC,CAAC,CAAC"}
1
+ {"version":3,"file":"prebuild.js","sourceRoot":"","sources":["../../src/utils/prebuild.ts"],"names":[],"mappings":"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"}
@@ -10,8 +10,9 @@ import {
10
10
  } from '../utils';
11
11
 
12
12
  const buildIos = async (command: Command) => {
13
- await validatePrebuild('ios');
14
- const config = resolveBuildConfigIos(command.opts());
13
+ const opts = command.opts();
14
+ await validatePrebuild('ios', { dryRun: !!opts.dryRun });
15
+ const config = resolveBuildConfigIos(opts);
15
16
  printIosConfig(config);
16
17
 
17
18
  await buildFramework(config);
@@ -7,6 +7,7 @@ type ErrorType =
7
7
  | 'ios-directory-not-found'
8
8
  | 'ios-directory-unknown-error'
9
9
  | 'ios-hermes-framework-not-found'
10
+ | 'ios-pod-install-cancelled'
10
11
  | 'ios-prebuilds-spm-dep-missing'
11
12
  | 'ios-scheme-not-found'
12
13
  | 'ios-workspace-not-found'
@@ -27,10 +28,13 @@ class CLIError {
27
28
  'ios-directory-not-found': 'Cannot find `ios` directory in the project',
28
29
  'ios-directory-unknown-error': 'Unknown error occurred while finding brownfield iOS scheme',
29
30
  'ios-hermes-framework-not-found': 'Could not find hermes framework in the project at path',
31
+ 'ios-pod-install-cancelled':
32
+ 'Brownfield cannot be built without installing CocoaPods. Run `pod install` in the `ios/` and try again.',
30
33
  'ios-prebuilds-spm-dep-missing':
31
34
  "Could not find a prebuilt xcframework for an SPM dependency declared by an Expo module. The brownfield Swift Package would ship without it, causing `Library not loaded: @rpath/...` at runtime in the host app. Either re-install the affected Expo module from a release published with bundled SPM deps (`bundleSharedDeps: true`), populate the monorepo's `packages/precompile/.build/.spm-deps/` cache, or set `EXPO_PRECOMPILED_MODULES_PATH` to a directory that contains `.spm-deps/<dep>/<flavor>/<dep>.xcframework`.",
32
35
  'ios-scheme-not-found': 'Could not find brownfield iOS scheme',
33
- 'ios-workspace-not-found': 'Could not find brownfield iOS workspace',
36
+ 'ios-workspace-not-found':
37
+ 'Could not find a brownfield iOS workspace (`.xcworkspace`) in the `ios/` directory. This usually means `pod install` has not been run yet. Run `pod install` and try again.',
34
38
  'ios-workspace-unknown-error': 'Unknown error occurred while finding brownfield iOS workspace',
35
39
  'package-not-installed':
36
40
  'expo-brownfield is not installed in the project. Install it with `npx expo install expo-brownfield`',
@@ -9,7 +9,10 @@ import CLIError from './error';
9
9
  import { withSpinner } from './spinner';
10
10
  import type { Platform } from './types';
11
11
 
12
- export const validatePrebuild = async (platform: Platform): Promise<void> => {
12
+ export const validatePrebuild = async (
13
+ platform: Platform,
14
+ options: { dryRun?: boolean } = {}
15
+ ): Promise<void> => {
13
16
  validatePackageInstalled();
14
17
 
15
18
  if (!checkPrebuild(platform)) {
@@ -33,6 +36,57 @@ export const validatePrebuild = async (platform: Platform): Promise<void> => {
33
36
  CLIError.handle('prebuild-cancelled');
34
37
  }
35
38
  }
39
+
40
+ if (platform === 'ios' && !options.dryRun) {
41
+ await validateIosPodsInstalled();
42
+ }
43
+ };
44
+
45
+ const validateIosPodsInstalled = async (): Promise<void> => {
46
+ if (checkIosWorkspace()) {
47
+ return;
48
+ }
49
+
50
+ console.info(
51
+ `${chalk.yellow(
52
+ '⚠ iOS workspace not found. CocoaPods has not been installed in the `ios/` directory yet.'
53
+ )}`
54
+ );
55
+ const response = await prompts({
56
+ type: 'confirm',
57
+ name: 'shouldRunPodInstall',
58
+ message: 'Do you want to run `pod install` now?',
59
+ initial: true,
60
+ });
61
+
62
+ if (!response.shouldRunPodInstall) {
63
+ CLIError.handle('ios-pod-install-cancelled');
64
+ return;
65
+ }
66
+
67
+ await withSpinner({
68
+ operation: () => spawnAsync('pod', ['install'], { cwd: path.join(process.cwd(), 'ios') }),
69
+ loaderMessage: 'Running `pod install` in the `ios` directory...',
70
+ successMessage: 'Pod install completed\n',
71
+ errorMessage: 'Pod install failed',
72
+ verbose: false,
73
+ });
74
+
75
+ if (!checkIosWorkspace()) {
76
+ CLIError.handle('ios-workspace-not-found');
77
+ }
78
+ };
79
+
80
+ const checkIosWorkspace = (): boolean => {
81
+ const iosPath = path.join(process.cwd(), 'ios');
82
+ if (!fs.existsSync(iosPath)) {
83
+ return false;
84
+ }
85
+ try {
86
+ return fs.readdirSync(iosPath).some((name) => name.endsWith('.xcworkspace'));
87
+ } catch {
88
+ return false;
89
+ }
36
90
  };
37
91
 
38
92
  export const validatePackageInstalled = (): void => {
@@ -0,0 +1 @@
1
+ {"root":["./src/index.ts","./src/commands/build-android.ts","./src/commands/build-ios.ts","./src/commands/index.ts","./src/commands/mangle.ts","./src/commands/tasks-android.ts","./src/utils/android.ts","./src/utils/config.ts","./src/utils/constants.ts","./src/utils/error.ts","./src/utils/index.ts","./src/utils/ios.ts","./src/utils/mangle.ts","./src/utils/prebuild.ts","./src/utils/precompiled.ts","./src/utils/spinner.ts","./src/utils/types.ts"],"version":"6.0.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-brownfield",
3
- "version": "56.0.13",
3
+ "version": "56.0.15",
4
4
  "description": "Toolkit and APIs for adding brownfield setup to Expo projects",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -41,7 +41,7 @@
41
41
  "chalk": "^4.1.2",
42
42
  "commander": "^14.0.3",
43
43
  "diff": "^5.2.0",
44
- "expo-build-properties": "~56.0.13",
44
+ "expo-build-properties": "~56.0.15",
45
45
  "expo-manifests": "~56.0.4",
46
46
  "ora": "^5.4.1",
47
47
  "prompts": "^2.4.2"
@@ -53,7 +53,7 @@
53
53
  "@types/prompts": "^2.0.6",
54
54
  "@types/react": "~19.2.0",
55
55
  "glob": "^13.0.6",
56
- "expo": "56.0.3",
56
+ "expo": "56.0.5",
57
57
  "create-expo": "4.0.2",
58
58
  "expo-module-scripts": "56.0.2"
59
59
  },
@@ -61,7 +61,7 @@
61
61
  "expo": "*",
62
62
  "react": "*"
63
63
  },
64
- "gitHead": "125e8225bf36a4b9b2a159441d9ea724bcf1110f",
64
+ "gitHead": "f67a101bcbe56114e982184834b93da7bbed00af",
65
65
  "scripts": {
66
66
  "build": "expo-module build",
67
67
  "clean": "expo-module clean",
@@ -10,8 +10,9 @@ import UIKit
10
10
  internal import EXDevMenu
11
11
  #endif
12
12
 
13
- public class ReactNativeHostManager {
14
- public static let shared = ReactNativeHostManager()
13
+ @objc
14
+ public class ReactNativeHostManager: NSObject {
15
+ @objc public static let shared = ReactNativeHostManager()
15
16
 
16
17
  private var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
17
18
  private var reactNativeFactory: RCTReactNativeFactory?
@@ -19,11 +20,14 @@ public class ReactNativeHostManager {
19
20
  private var devMenuInitialized: Bool = false
20
21
  private var turboModuleClasses: [String: AnyClass] = [:]
21
22
 
23
+ private override init() {
24
+ super.init()
25
+ }
22
26
  /**
23
27
  * Initializes ReactNativeHostManager instance
24
28
  * Instance can be initialized only once
25
29
  */
26
- public func initialize(turboModuleClasses: [String: AnyClass] = [:]) {
30
+ @objc public func initialize(turboModuleClasses: [String: AnyClass] = [:]) {
27
31
  if firstLoadInitialized {
28
32
  return
29
33
  }
@@ -38,7 +42,7 @@ public class ReactNativeHostManager {
38
42
  /**
39
43
  * Creates the React Native view using RCTReactNativeFactory
40
44
  */
41
- public func loadView(
45
+ @objc public func loadView(
42
46
  moduleName: String = "main",
43
47
  initialProps: [AnyHashable: Any]?,
44
48
  launchOptions: [AnyHashable: Any]?
@@ -61,7 +65,7 @@ public class ReactNativeHostManager {
61
65
  /**
62
66
  * Initializes a React Native instance
63
67
  */
64
- public func initializeInstance() {
68
+ @objc public func initializeInstance() {
65
69
  let delegate = ReactNativeDelegate(turboModuleClasses: turboModuleClasses)
66
70
  reactNativeFactory = ExpoReactNativeFactory(delegate: delegate)
67
71
  delegate.dependencyProvider = RCTAppDependencyProvider()
@@ -72,7 +76,7 @@ public class ReactNativeHostManager {
72
76
  * Cleans up the previous instance of React Native
73
77
  * to prevent memory leaks
74
78
  */
75
- public func cleanupPreviousInstance() {
79
+ @objc public func cleanupPreviousInstance() {
76
80
  if let rootViewFactory = reactNativeFactory?.rootViewFactory {
77
81
  rootViewFactory.setValue(nil, forKey: "_reactHost")
78
82
  reactNativeDelegate = nil
@@ -0,0 +1 @@
1
+ {"root":["./src/index.ts","./src/types.ts","./src/withbrownfield.ts","./src/android/index.ts","./src/android/types.ts","./src/android/withandroidplugin.ts","./src/android/plugins/index.ts","./src/android/plugins/withgradlepropertiesplugin.ts","./src/android/plugins/withprojectbuildgradleplugin.ts","./src/android/plugins/withprojectfilesplugin.ts","./src/android/plugins/withsettingsgradleplugin.ts","./src/android/utils/filesystem.ts","./src/android/utils/index.ts","./src/android/utils/props.ts","./src/android/utils/repositories.ts","./src/android/utils/validation.ts","./src/common/filesystem.ts","./src/common/index.ts","./src/common/types.ts","./src/common/utils.ts","./src/common/plugins/index.ts","./src/common/plugins/withdevlauncherwarning.ts","./src/ios/index.ts","./src/ios/types.ts","./src/ios/withiosplugin.ts","./src/ios/plugins/index.ts","./src/ios/plugins/withbuildpropertiesplugin.ts","./src/ios/plugins/withpodfileplugin.ts","./src/ios/plugins/withpodfilepropertiesplugin.ts","./src/ios/plugins/withxcodeprojectplugin.ts","./src/ios/utils/constants.ts","./src/ios/utils/filesystem.ts","./src/ios/utils/index.ts","./src/ios/utils/podfile.ts","./src/ios/utils/project.ts","./src/ios/utils/props.ts"],"version":"6.0.3"}