@callstack/brownfield-cli 3.8.1 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/brownfield/commands/packageIos.d.ts +1 -0
- package/dist/brownfield/commands/packageIos.d.ts.map +1 -1
- package/dist/brownfield/commands/packageIos.js +43 -4
- package/dist/brownfield/utils/project.d.ts +1 -0
- package/dist/brownfield/utils/project.d.ts.map +1 -1
- package/dist/brownfield/utils/project.js +8 -0
- package/dist/brownfield/utils/supportsPrebuiltRNCore.d.ts +18 -0
- package/dist/brownfield/utils/supportsPrebuiltRNCore.d.ts.map +1 -0
- package/dist/brownfield/utils/supportsPrebuiltRNCore.js +36 -0
- package/package.json +6 -6
- package/src/brownfield/commands/packageIos.ts +208 -131
- package/src/brownfield/utils/project.ts +9 -0
- package/src/brownfield/utils/supportsPrebuiltRNCore.ts +67 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @callstack/brownfield-cli
|
|
2
2
|
|
|
3
|
+
## 3.10.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#323](https://github.com/callstack/react-native-brownfield/pull/323) [`3456d3a`](https://github.com/callstack/react-native-brownfield/commit/3456d3aded18002475def4b79889979e76e1db5e) Thanks [@artus9033](https://github.com/artus9033)! - Support RN prebuilts in Brownfield, by default enabled in RN >= 0.84, opt-in in RN 0.83; or in Expo 55+ (Expo 54 is not supported).
|
|
8
|
+
|
|
9
|
+
Add `--use-prebuilt-rn-core` to `brownfield package:ios` so callers can opt into or out of React Native Apple prebuilt binaries; omitting the flag defers to version-aware defaults handled by Rock. The CLI rejects `--use-prebuilt-rn-core` when React Native is older than 0.81 or when the project is Expo SDK older than 55.
|
|
10
|
+
|
|
11
|
+
Fix brownfield framework dylib install names to use @rpath instead of hardcoded paths.
|
|
12
|
+
|
|
13
|
+
## 3.9.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- [#326](https://github.com/callstack/react-native-brownfield/pull/326) [`80e6364`](https://github.com/callstack/react-native-brownfield/commit/80e6364d405d216b3e84a6297dfe346d2f01444b) Thanks [@artus9033](https://github.com/artus9033)! - feat: strip SO files by default, deprecate experimental option in favor of useStrippedSoFiles
|
|
18
|
+
|
|
3
19
|
## 3.8.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { ExampleUsage } from '../../shared/index.js';
|
|
3
|
+
export declare function parseUsePrebuiltRnCoreArgument(value: string | boolean): boolean;
|
|
3
4
|
export declare const packageIosCommand: Command;
|
|
4
5
|
export declare const packageIosExample: ExampleUsage;
|
|
5
6
|
//# sourceMappingURL=packageIos.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageIos.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/packageIos.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"packageIos.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/packageIos.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAK5C,OAAO,EAGL,YAAY,EACb,MAAM,uBAAuB,CAAC;AAY/B,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,MAAM,GAAG,OAAO,GACtB,OAAO,CAcT;AAOD,eAAO,MAAM,iBAAiB,SA6L3B,CAAC;AAEJ,eAAO,MAAM,iBAAiB,cAG7B,CAAC"}
|
|
@@ -2,22 +2,60 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { getBuildOptions, mergeFrameworks, } from '@rock-js/platform-apple-helpers';
|
|
4
4
|
import { packageIosAction } from '@rock-js/plugin-brownfield-ios';
|
|
5
|
-
import { colorLink, getReactNativeVersion, logger, relativeToCwd, } from '@rock-js/tools';
|
|
6
|
-
import { Command } from 'commander';
|
|
5
|
+
import { RockError, colorLink, getReactNativeVersion, logger, relativeToCwd, } from '@rock-js/tools';
|
|
6
|
+
import { Command, Option } from 'commander';
|
|
7
7
|
import { runExpoPrebuildIfNeeded } from '../utils/expo.js';
|
|
8
8
|
import { getProjectInfo } from '../utils/project.js';
|
|
9
|
+
import { supportsPrebuiltRNCore } from '../utils/supportsPrebuiltRNCore.js';
|
|
9
10
|
import { actionRunner, curryOptions, ExampleUsage, } from '../../shared/index.js';
|
|
10
11
|
import { runBrownieCodegenIfApplicable } from '../../brownie/helpers/runBrownieCodegenIfApplicable.js';
|
|
11
12
|
import { runNavigationCodegenIfApplicable } from '../../navigation/helpers/runNavigationCodegenIfApplicable.js';
|
|
12
13
|
import { stripFrameworkBinary } from '../utils/stripFrameworkBinary.js';
|
|
14
|
+
/** Help text for `--use-prebuilt-rn-core` (keep in sync with docs/docs/docs/getting-started/ios.mdx, "React Native Prebuilts" section). */
|
|
15
|
+
const USE_PREBUILT_RN_CORE_HELP = 'Whether the Xcode build for packaging should use React Native Apple prebuilt binaries (via CocoaPods). ' +
|
|
16
|
+
'If you omit this flag, Brownfield follows version-aware defaults: for React Native 0.84 and newer, prebuilts are enabled by default; for RN 0.83, they are disabled unless you opt in. ' +
|
|
17
|
+
'Pass true or false to force either behavior. Use the flag without a value as shorthand for true (same as `--use-prebuilt-rn-core true`). ' +
|
|
18
|
+
'See the Brownfield iOS guide for details: https://oss.callstack.com/react-native-brownfield/docs/getting-started/ios#react-native-prebuilts';
|
|
19
|
+
export function parseUsePrebuiltRnCoreArgument(value) {
|
|
20
|
+
if (typeof value === 'boolean') {
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
const normalized = value.trim().toLowerCase();
|
|
24
|
+
if (normalized === 'true' || normalized === '1') {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
if (normalized === 'false' || normalized === '0') {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
throw new RockError(`Invalid value for --use-prebuilt-rn-core: expected true or false, received "${value}"`);
|
|
31
|
+
}
|
|
13
32
|
export const packageIosCommand = curryOptions(new Command('package:ios').description('Build iOS XCFramework'), getBuildOptions({ platformName: 'ios' }).map((option) => option.name.startsWith('--build-folder')
|
|
14
33
|
? {
|
|
15
34
|
...option,
|
|
16
35
|
description: option.description +
|
|
17
36
|
" By default, the '.brownfield/build' path will be used.",
|
|
18
37
|
}
|
|
19
|
-
: option))
|
|
38
|
+
: option))
|
|
39
|
+
.addOption(new Option('--use-prebuilt-rn-core [bool]', USE_PREBUILT_RN_CORE_HELP)
|
|
40
|
+
.preset(true)
|
|
41
|
+
.argParser(parseUsePrebuiltRnCoreArgument))
|
|
42
|
+
.action(actionRunner(async (options) => {
|
|
20
43
|
const { projectRoot, platformConfig, userConfig } = getProjectInfo('ios');
|
|
44
|
+
const prebuiltRNCoreSupport = supportsPrebuiltRNCore({ projectRoot });
|
|
45
|
+
// version-aware default when the flag is omitted (see ios.mdx "React Native Prebuilts")
|
|
46
|
+
options.usePrebuiltRnCore ??= prebuiltRNCoreSupport.supported
|
|
47
|
+
? prebuiltRNCoreSupport.enabledByDefault
|
|
48
|
+
: false;
|
|
49
|
+
if (prebuiltRNCoreSupport) {
|
|
50
|
+
logger.info(`${options.usePrebuiltRnCore ? 'Using' : 'Not using'} prebuilt RN core`);
|
|
51
|
+
if (!prebuiltRNCoreSupport.enabledByDefault &&
|
|
52
|
+
!options.usePrebuiltRnCore) {
|
|
53
|
+
logger.info('Your environment supports prebuilt RN Core as an opt-in feature, but it is disabled by default. Pass --use-prebuilt-rn-core to enable it.');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (options.usePrebuiltRnCore && !prebuiltRNCoreSupport.supported) {
|
|
57
|
+
throw new RockError(prebuiltRNCoreSupport.reason);
|
|
58
|
+
}
|
|
21
59
|
await runExpoPrebuildIfNeeded({ projectRoot, platform: 'ios' });
|
|
22
60
|
if (!userConfig.project.ios) {
|
|
23
61
|
throw new Error('iOS project not found.');
|
|
@@ -35,6 +73,7 @@ export const packageIosCommand = curryOptions(new Command('package:ios').descrip
|
|
|
35
73
|
dotBrownfieldDir = path.join(projectRoot, dotBrownfieldDir);
|
|
36
74
|
}
|
|
37
75
|
options.buildFolder ??= path.join(dotBrownfieldDir, 'build');
|
|
76
|
+
options.verbose ??= logger.isVerbose();
|
|
38
77
|
// The new_architecture.rb script scans Info.plist and fails on binary plist files,
|
|
39
78
|
// which is the case for our XCFrameworks.
|
|
40
79
|
// We're reusing the "build" directory which is excluded from the scan.
|
|
@@ -50,9 +89,9 @@ export const packageIosCommand = curryOptions(new Command('package:ios').descrip
|
|
|
50
89
|
// e.g. '0.82' (note the missing patch component),
|
|
51
90
|
// therefore we resolve it manually from RN's package.json using Rock's utils
|
|
52
91
|
reactNativeVersion: getReactNativeVersion(projectRoot),
|
|
53
|
-
usePrebuiltRNCore: false, // for brownfield, it is required to build RN from source
|
|
54
92
|
packageDir, // the output directory for artifacts
|
|
55
93
|
skipCache: true, // cache is dependent on existence of Rock config file
|
|
94
|
+
usePrebuiltRNCore: options.usePrebuiltRnCore,
|
|
56
95
|
}, platformConfig);
|
|
57
96
|
const reactBrownfieldXcframeworkPath = path.join(packageDir, 'ReactBrownfield.xcframework');
|
|
58
97
|
if (fs.existsSync(reactBrownfieldXcframeworkPath)) {
|
|
@@ -14,6 +14,7 @@ export declare function getExpoConfigIfIsExpo(projectRoot: string): ExpoProjectC
|
|
|
14
14
|
* @returns Whether the project is an Expo project
|
|
15
15
|
*/
|
|
16
16
|
export declare function isExpoProject(projectRoot: string): boolean;
|
|
17
|
+
export declare function getExpoSdkMajor(projectRoot: string): number | null;
|
|
17
18
|
/**
|
|
18
19
|
* Fills the RNC CLI project config from the Expo config by mutating the passed in `options.projectConfig` object in place
|
|
19
20
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/project.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,UAAU,EACX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAKjE,OAAO,EAEL,KAAK,aAAa,IAAI,iBAAiB,EACxC,MAAM,cAAc,CAAC;AAQtB;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,4BAMxD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAc1D;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,aAAa,EACb,UAAU,EAAE,EAAE,GAAG,EAAE,EACnB,WAAW,GACZ,EAAE;IACD,8CAA8C;IAC9C,aAAa,EAAE,aAAa,CAAC;IAE7B,8BAA8B;IAC9B,UAAU,EAAE,iBAAiB,CAAC;IAE9B,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB,QAuBA;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,SAAS,KAAK,GAAG,SAAS,EAC/D,QAAQ,EAAE,QAAQ,GACjB;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,cAAc,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;CACzC,CAeA;AAED,wBAAgB,aAAa,CAAC,EAC5B,WAAW,EACX,QAAQ,GACT,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;CAC7B,GAAG,UAAU,CAuBb;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,eAAe,EACrB,aAAa,EAAE,oBAAoB;;;EAQpC"}
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/project.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,UAAU,EACX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAKjE,OAAO,EAEL,KAAK,aAAa,IAAI,iBAAiB,EACxC,MAAM,cAAc,CAAC;AAQtB;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,4BAMxD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAc1D;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOlE;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,aAAa,EACb,UAAU,EAAE,EAAE,GAAG,EAAE,EACnB,WAAW,GACZ,EAAE;IACD,8CAA8C;IAC9C,aAAa,EAAE,aAAa,CAAC;IAE7B,8BAA8B;IAC9B,UAAU,EAAE,iBAAiB,CAAC;IAE9B,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB,QAuBA;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,SAAS,KAAK,GAAG,SAAS,EAC/D,QAAQ,EAAE,QAAQ,GACjB;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,cAAc,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;CACzC,CAeA;AAED,wBAAgB,aAAa,CAAC,EAC5B,WAAW,EACX,QAAQ,GACT,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;CAC7B,GAAG,UAAU,CAuBb;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,eAAe,EACrB,aAAa,EAAE,oBAAoB;;;EAQpC"}
|
|
@@ -36,6 +36,14 @@ export function isExpoProject(projectRoot) {
|
|
|
36
36
|
['dependencies', 'peerDependencies', 'devDependencies'].some((key) => JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))[key]?.expo);
|
|
37
37
|
return hasExpoConfig && dependsOnExpo;
|
|
38
38
|
}
|
|
39
|
+
export function getExpoSdkMajor(projectRoot) {
|
|
40
|
+
const rawExpoVersion = getExpoConfigIfIsExpo(projectRoot)?.exp.sdkVersion;
|
|
41
|
+
if (!rawExpoVersion) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const expoSdkMajor = parseInt(rawExpoVersion.split('.')[0], 10);
|
|
45
|
+
return Number.isFinite(expoSdkMajor) ? expoSdkMajor : null;
|
|
46
|
+
}
|
|
39
47
|
/**
|
|
40
48
|
* Fills the RNC CLI project config from the Expo config by mutating the passed in `options.projectConfig` object in place
|
|
41
49
|
*/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Minimum RN version that can opt in to prebuilts via `--use-prebuilt-rn-core`. */
|
|
2
|
+
export declare const MIN_REACT_NATIVE_VERSION_FOR_OPT_IN_PREBUILT_RN_CORE = "0.81.0";
|
|
3
|
+
/** Minimum RN version where Brownfield enables prebuilts by default (vanilla projects). */
|
|
4
|
+
export declare const MIN_REACT_NATIVE_VERSION_FOR_PREBUILT_RN_CORE_BY_DEFAULT = "0.84.0";
|
|
5
|
+
export declare const MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_RN_CORE_BY_DEFAULT = 55;
|
|
6
|
+
export type PrebuiltRNCoreSupportResult = {
|
|
7
|
+
supported: true;
|
|
8
|
+
enabledByDefault: boolean;
|
|
9
|
+
reason?: never;
|
|
10
|
+
} | {
|
|
11
|
+
supported: false;
|
|
12
|
+
enabledByDefault?: never;
|
|
13
|
+
reason: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function supportsPrebuiltRNCore({ projectRoot, }: {
|
|
16
|
+
projectRoot: string;
|
|
17
|
+
}): PrebuiltRNCoreSupportResult;
|
|
18
|
+
//# sourceMappingURL=supportsPrebuiltRNCore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supportsPrebuiltRNCore.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/supportsPrebuiltRNCore.ts"],"names":[],"mappings":"AAIA,oFAAoF;AACpF,eAAO,MAAM,oDAAoD,WAAW,CAAC;AAC7E,2FAA2F;AAC3F,eAAO,MAAM,wDAAwD,WAC3D,CAAC;AACX,eAAO,MAAM,kDAAkD,KAAK,CAAC;AAErE,MAAM,MAAM,2BAA2B,GACnC;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,gBAAgB,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAA;CAAE,GAC9D;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,gBAAgB,CAAC,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,wBAAgB,sBAAsB,CAAC,EACrC,WAAW,GACZ,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,2BAA2B,CA+C9B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getReactNativeVersion, versionCompare } from '@rock-js/tools';
|
|
2
|
+
import { getExpoSdkMajor, isExpoProject } from './project.js';
|
|
3
|
+
/** Minimum RN version that can opt in to prebuilts via `--use-prebuilt-rn-core`. */
|
|
4
|
+
export const MIN_REACT_NATIVE_VERSION_FOR_OPT_IN_PREBUILT_RN_CORE = '0.81.0';
|
|
5
|
+
/** Minimum RN version where Brownfield enables prebuilts by default (vanilla projects). */
|
|
6
|
+
export const MIN_REACT_NATIVE_VERSION_FOR_PREBUILT_RN_CORE_BY_DEFAULT = '0.84.0';
|
|
7
|
+
export const MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_RN_CORE_BY_DEFAULT = 55;
|
|
8
|
+
export function supportsPrebuiltRNCore({ projectRoot, }) {
|
|
9
|
+
const reactNativeVersion = getReactNativeVersion(projectRoot);
|
|
10
|
+
if (reactNativeVersion === 'unknown') {
|
|
11
|
+
return {
|
|
12
|
+
supported: false,
|
|
13
|
+
reason: 'Cannot use --use-prebuilt-rn-core: unable to resolve the installed react-native version.',
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (versionCompare(reactNativeVersion, MIN_REACT_NATIVE_VERSION_FOR_OPT_IN_PREBUILT_RN_CORE) < 0) {
|
|
17
|
+
return {
|
|
18
|
+
supported: false,
|
|
19
|
+
reason: `--use-prebuilt-rn-core requires React Native ${MIN_REACT_NATIVE_VERSION_FOR_OPT_IN_PREBUILT_RN_CORE} or newer (found ${reactNativeVersion}).`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (isExpoProject(projectRoot)) {
|
|
23
|
+
const expoSdkMajor = getExpoSdkMajor(projectRoot);
|
|
24
|
+
if (expoSdkMajor === null ||
|
|
25
|
+
expoSdkMajor < MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_RN_CORE_BY_DEFAULT) {
|
|
26
|
+
const sdkLabel = expoSdkMajor === null ? 'unknown' : String(expoSdkMajor);
|
|
27
|
+
return {
|
|
28
|
+
supported: false,
|
|
29
|
+
reason: `--use-prebuilt-rn-core is unsupported in Expo SDK ${sdkLabel}: packaging brownfield with prebuilts requires Expo SDK ${MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_RN_CORE_BY_DEFAULT} or newer.`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return { supported: true, enabledByDefault: true };
|
|
33
|
+
}
|
|
34
|
+
const enabledByDefault = versionCompare(reactNativeVersion, MIN_REACT_NATIVE_VERSION_FOR_PREBUILT_RN_CORE_BY_DEFAULT) >= 0;
|
|
35
|
+
return { supported: true, enabledByDefault };
|
|
36
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@callstack/brownfield-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Artur Morys-Magiera <artus9033@gmail.com>",
|
|
6
6
|
"bin": {
|
|
@@ -76,11 +76,11 @@
|
|
|
76
76
|
"@expo/config": "^12.0.13",
|
|
77
77
|
"@react-native-community/cli-config": "^20.0.0",
|
|
78
78
|
"@react-native-community/cli-config-android": "^20.0.0",
|
|
79
|
-
"@rock-js/platform-android": "^0.
|
|
80
|
-
"@rock-js/platform-apple-helpers": "^0.
|
|
81
|
-
"@rock-js/plugin-brownfield-android": "^0.
|
|
82
|
-
"@rock-js/plugin-brownfield-ios": "^0.
|
|
83
|
-
"@rock-js/tools": "^0.
|
|
79
|
+
"@rock-js/platform-android": "^0.13.3",
|
|
80
|
+
"@rock-js/platform-apple-helpers": "^0.13.3",
|
|
81
|
+
"@rock-js/plugin-brownfield-android": "^0.13.3",
|
|
82
|
+
"@rock-js/plugin-brownfield-ios": "^0.13.3",
|
|
83
|
+
"@rock-js/tools": "^0.13.3",
|
|
84
84
|
"commander": "^14.0.3",
|
|
85
85
|
"quicktype-core": "^23.2.6",
|
|
86
86
|
"quicktype-typescript-input": "^23.2.6",
|
|
@@ -8,16 +8,18 @@ import {
|
|
|
8
8
|
} from '@rock-js/platform-apple-helpers';
|
|
9
9
|
import { packageIosAction } from '@rock-js/plugin-brownfield-ios';
|
|
10
10
|
import {
|
|
11
|
+
RockError,
|
|
11
12
|
colorLink,
|
|
12
13
|
getReactNativeVersion,
|
|
13
14
|
logger,
|
|
14
15
|
relativeToCwd,
|
|
15
16
|
} from '@rock-js/tools';
|
|
16
17
|
|
|
17
|
-
import { Command } from 'commander';
|
|
18
|
+
import { Command, Option } from 'commander';
|
|
18
19
|
|
|
19
20
|
import { runExpoPrebuildIfNeeded } from '../utils/expo.js';
|
|
20
21
|
import { getProjectInfo } from '../utils/project.js';
|
|
22
|
+
import { supportsPrebuiltRNCore } from '../utils/supportsPrebuiltRNCore.js';
|
|
21
23
|
import {
|
|
22
24
|
actionRunner,
|
|
23
25
|
curryOptions,
|
|
@@ -27,6 +29,36 @@ import { runBrownieCodegenIfApplicable } from '../../brownie/helpers/runBrownieC
|
|
|
27
29
|
import { runNavigationCodegenIfApplicable } from '../../navigation/helpers/runNavigationCodegenIfApplicable.js';
|
|
28
30
|
import { stripFrameworkBinary } from '../utils/stripFrameworkBinary.js';
|
|
29
31
|
|
|
32
|
+
/** Help text for `--use-prebuilt-rn-core` (keep in sync with docs/docs/docs/getting-started/ios.mdx, "React Native Prebuilts" section). */
|
|
33
|
+
const USE_PREBUILT_RN_CORE_HELP =
|
|
34
|
+
'Whether the Xcode build for packaging should use React Native Apple prebuilt binaries (via CocoaPods). ' +
|
|
35
|
+
'If you omit this flag, Brownfield follows version-aware defaults: for React Native 0.84 and newer, prebuilts are enabled by default; for RN 0.83, they are disabled unless you opt in. ' +
|
|
36
|
+
'Pass true or false to force either behavior. Use the flag without a value as shorthand for true (same as `--use-prebuilt-rn-core true`). ' +
|
|
37
|
+
'See the Brownfield iOS guide for details: https://oss.callstack.com/react-native-brownfield/docs/getting-started/ios#react-native-prebuilts';
|
|
38
|
+
|
|
39
|
+
export function parseUsePrebuiltRnCoreArgument(
|
|
40
|
+
value: string | boolean
|
|
41
|
+
): boolean {
|
|
42
|
+
if (typeof value === 'boolean') {
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
const normalized = value.trim().toLowerCase();
|
|
46
|
+
if (normalized === 'true' || normalized === '1') {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
if (normalized === 'false' || normalized === '0') {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
throw new RockError(
|
|
53
|
+
`Invalid value for --use-prebuilt-rn-core: expected true or false, received "${value}"`
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
type PackageIosCliFlags = AppleBuildFlags & {
|
|
58
|
+
/** Set when `--use-prebuilt-rn-core` is passed; omitted when the flag is absent (Rock applies RN version defaults). */
|
|
59
|
+
usePrebuiltRnCore?: boolean;
|
|
60
|
+
};
|
|
61
|
+
|
|
30
62
|
export const packageIosCommand = curryOptions(
|
|
31
63
|
new Command('package:ios').description('Build iOS XCFramework'),
|
|
32
64
|
getBuildOptions({ platformName: 'ios' }).map((option) =>
|
|
@@ -39,139 +71,184 @@ export const packageIosCommand = curryOptions(
|
|
|
39
71
|
}
|
|
40
72
|
: option
|
|
41
73
|
)
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
projectRoot,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
74
|
+
)
|
|
75
|
+
.addOption(
|
|
76
|
+
new Option('--use-prebuilt-rn-core [bool]', USE_PREBUILT_RN_CORE_HELP)
|
|
77
|
+
.preset(true)
|
|
78
|
+
.argParser(parseUsePrebuiltRnCoreArgument)
|
|
79
|
+
)
|
|
80
|
+
.action(
|
|
81
|
+
actionRunner(async (options: PackageIosCliFlags) => {
|
|
82
|
+
const { projectRoot, platformConfig, userConfig } = getProjectInfo('ios');
|
|
83
|
+
|
|
84
|
+
const prebuiltRNCoreSupport = supportsPrebuiltRNCore({ projectRoot });
|
|
85
|
+
|
|
86
|
+
// version-aware default when the flag is omitted (see ios.mdx "React Native Prebuilts")
|
|
87
|
+
options.usePrebuiltRnCore ??= prebuiltRNCoreSupport.supported
|
|
88
|
+
? prebuiltRNCoreSupport.enabledByDefault
|
|
89
|
+
: false;
|
|
90
|
+
|
|
91
|
+
if (prebuiltRNCoreSupport) {
|
|
92
|
+
logger.info(
|
|
93
|
+
`${options.usePrebuiltRnCore ? 'Using' : 'Not using'} prebuilt RN core`
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
if (
|
|
97
|
+
!prebuiltRNCoreSupport.enabledByDefault &&
|
|
98
|
+
!options.usePrebuiltRnCore
|
|
99
|
+
) {
|
|
100
|
+
logger.info(
|
|
101
|
+
'Your environment supports prebuilt RN Core as an opt-in feature, but it is disabled by default. Pass --use-prebuilt-rn-core to enable it.'
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (options.usePrebuiltRnCore && !prebuiltRNCoreSupport.supported) {
|
|
107
|
+
throw new RockError(prebuiltRNCoreSupport.reason);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
await runExpoPrebuildIfNeeded({ projectRoot, platform: 'ios' });
|
|
111
|
+
|
|
112
|
+
if (!userConfig.project.ios) {
|
|
113
|
+
throw new Error('iOS project not found.');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!userConfig.project.ios.xcodeProject) {
|
|
117
|
+
throw new Error('iOS Xcode project not found in the configuration.');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
let dotBrownfieldDir = path.join(
|
|
121
|
+
// for Expo projects, platformConfig?.sourceDir == "", but for non-Expo projects, it's "ios"
|
|
122
|
+
...(userConfig.project.ios.sourceDir.trim().length > 0
|
|
123
|
+
? [userConfig.project.ios.sourceDir]
|
|
124
|
+
: [projectRoot, 'ios']),
|
|
125
|
+
'.brownfield'
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// non-Expo projects have a relative sourceDir path, so we need to make it absolute
|
|
129
|
+
if (!path.isAbsolute(dotBrownfieldDir)) {
|
|
130
|
+
dotBrownfieldDir = path.join(projectRoot, dotBrownfieldDir);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
options.buildFolder ??= path.join(dotBrownfieldDir, 'build');
|
|
134
|
+
options.verbose ??= logger.isVerbose();
|
|
135
|
+
|
|
136
|
+
// The new_architecture.rb script scans Info.plist and fails on binary plist files,
|
|
137
|
+
// which is the case for our XCFrameworks.
|
|
138
|
+
// We're reusing the "build" directory which is excluded from the scan.
|
|
139
|
+
// Reference: https://github.com/facebook/react-native/blob/490c5e8dcc6cdb19c334cc39e93a39a48ba71e96/packages/react-native/scripts/cocoapods/new_architecture.rb#L171
|
|
140
|
+
const packageDir = path.join(dotBrownfieldDir, 'package', 'build');
|
|
141
|
+
const configuration = options.configuration ?? 'Debug';
|
|
142
|
+
|
|
143
|
+
const { hasBrownie } = await runBrownieCodegenIfApplicable(
|
|
86
144
|
projectRoot,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// (which contains ReactBrownfield symbols) and ReactBrownfield.xcframework.
|
|
107
|
-
stripFrameworkBinary(reactBrownfieldXcframeworkPath);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (hasBrownie) {
|
|
111
|
-
const productsPath = path.join(options.buildFolder, 'Build', 'Products');
|
|
112
|
-
const brownieOutputPath = path.join(packageDir, 'Brownie.xcframework');
|
|
113
|
-
|
|
114
|
-
await mergeFrameworks({
|
|
115
|
-
sourceDir: userConfig.project.ios.sourceDir,
|
|
116
|
-
frameworkPaths: [
|
|
117
|
-
path.join(
|
|
118
|
-
productsPath,
|
|
119
|
-
`${configuration}-iphoneos`,
|
|
120
|
-
'Brownie',
|
|
121
|
-
'Brownie.framework'
|
|
122
|
-
),
|
|
123
|
-
path.join(
|
|
124
|
-
productsPath,
|
|
125
|
-
`${configuration}-iphonesimulator`,
|
|
126
|
-
'Brownie',
|
|
127
|
-
'Brownie.framework'
|
|
128
|
-
),
|
|
129
|
-
],
|
|
130
|
-
outputPath: brownieOutputPath,
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// Strip the binary from Brownie.xcframework to make it interface-only.
|
|
134
|
-
// This avoids duplicate symbols when consumer apps embed both BrownfieldLib
|
|
135
|
-
// (which contains Brownie symbols) and Brownie.xcframework.
|
|
136
|
-
stripFrameworkBinary(brownieOutputPath);
|
|
137
|
-
|
|
138
|
-
logger.success(
|
|
139
|
-
`Brownie.xcframework created at ${colorLink(relativeToCwd(brownieOutputPath))}`
|
|
145
|
+
'swift'
|
|
146
|
+
);
|
|
147
|
+
const { hasNavigation } =
|
|
148
|
+
await runNavigationCodegenIfApplicable(projectRoot);
|
|
149
|
+
|
|
150
|
+
await packageIosAction(
|
|
151
|
+
options,
|
|
152
|
+
{
|
|
153
|
+
projectRoot,
|
|
154
|
+
reactNativePath: userConfig.reactNativePath,
|
|
155
|
+
// below: the userConfig.reactNativeVersion may be a non-semver-format string,
|
|
156
|
+
// e.g. '0.82' (note the missing patch component),
|
|
157
|
+
// therefore we resolve it manually from RN's package.json using Rock's utils
|
|
158
|
+
reactNativeVersion: getReactNativeVersion(projectRoot),
|
|
159
|
+
packageDir, // the output directory for artifacts
|
|
160
|
+
skipCache: true, // cache is dependent on existence of Rock config file
|
|
161
|
+
usePrebuiltRNCore: options.usePrebuiltRnCore,
|
|
162
|
+
},
|
|
163
|
+
platformConfig
|
|
140
164
|
);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const brownfieldNavigationOutputPath = path.join(packageDir, 'BrownfieldNavigation.xcframework');
|
|
146
|
-
|
|
147
|
-
await mergeFrameworks({
|
|
148
|
-
sourceDir: userConfig.project.ios.sourceDir,
|
|
149
|
-
frameworkPaths: [
|
|
150
|
-
path.join(
|
|
151
|
-
productsPath,
|
|
152
|
-
`${configuration}-iphoneos`,
|
|
153
|
-
'BrownfieldNavigation',
|
|
154
|
-
'BrownfieldNavigation.framework'
|
|
155
|
-
),
|
|
156
|
-
path.join(
|
|
157
|
-
productsPath,
|
|
158
|
-
`${configuration}-iphonesimulator`,
|
|
159
|
-
'BrownfieldNavigation',
|
|
160
|
-
'BrownfieldNavigation.framework'
|
|
161
|
-
),
|
|
162
|
-
],
|
|
163
|
-
outputPath: brownfieldNavigationOutputPath,
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
stripFrameworkBinary(brownfieldNavigationOutputPath);
|
|
168
|
-
|
|
169
|
-
logger.success(
|
|
170
|
-
`BrownfieldNavigation.xcframework created at ${colorLink(relativeToCwd(brownfieldNavigationOutputPath))}`
|
|
165
|
+
|
|
166
|
+
const reactBrownfieldXcframeworkPath = path.join(
|
|
167
|
+
packageDir,
|
|
168
|
+
'ReactBrownfield.xcframework'
|
|
171
169
|
);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
170
|
+
if (fs.existsSync(reactBrownfieldXcframeworkPath)) {
|
|
171
|
+
// Strip the binary from ReactBrownfield.xcframework to make it interface-only.
|
|
172
|
+
// This avoids duplicate symbols when consumer apps embed both BrownfieldLib
|
|
173
|
+
// (which contains ReactBrownfield symbols) and ReactBrownfield.xcframework.
|
|
174
|
+
stripFrameworkBinary(reactBrownfieldXcframeworkPath);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (hasBrownie) {
|
|
178
|
+
const productsPath = path.join(
|
|
179
|
+
options.buildFolder,
|
|
180
|
+
'Build',
|
|
181
|
+
'Products'
|
|
182
|
+
);
|
|
183
|
+
const brownieOutputPath = path.join(packageDir, 'Brownie.xcframework');
|
|
184
|
+
|
|
185
|
+
await mergeFrameworks({
|
|
186
|
+
sourceDir: userConfig.project.ios.sourceDir,
|
|
187
|
+
frameworkPaths: [
|
|
188
|
+
path.join(
|
|
189
|
+
productsPath,
|
|
190
|
+
`${configuration}-iphoneos`,
|
|
191
|
+
'Brownie',
|
|
192
|
+
'Brownie.framework'
|
|
193
|
+
),
|
|
194
|
+
path.join(
|
|
195
|
+
productsPath,
|
|
196
|
+
`${configuration}-iphonesimulator`,
|
|
197
|
+
'Brownie',
|
|
198
|
+
'Brownie.framework'
|
|
199
|
+
),
|
|
200
|
+
],
|
|
201
|
+
outputPath: brownieOutputPath,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Strip the binary from Brownie.xcframework to make it interface-only.
|
|
205
|
+
// This avoids duplicate symbols when consumer apps embed both BrownfieldLib
|
|
206
|
+
// (which contains Brownie symbols) and Brownie.xcframework.
|
|
207
|
+
stripFrameworkBinary(brownieOutputPath);
|
|
208
|
+
|
|
209
|
+
logger.success(
|
|
210
|
+
`Brownie.xcframework created at ${colorLink(relativeToCwd(brownieOutputPath))}`
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (hasNavigation) {
|
|
215
|
+
const productsPath = path.join(
|
|
216
|
+
options.buildFolder,
|
|
217
|
+
'Build',
|
|
218
|
+
'Products'
|
|
219
|
+
);
|
|
220
|
+
const brownfieldNavigationOutputPath = path.join(
|
|
221
|
+
packageDir,
|
|
222
|
+
'BrownfieldNavigation.xcframework'
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
await mergeFrameworks({
|
|
226
|
+
sourceDir: userConfig.project.ios.sourceDir,
|
|
227
|
+
frameworkPaths: [
|
|
228
|
+
path.join(
|
|
229
|
+
productsPath,
|
|
230
|
+
`${configuration}-iphoneos`,
|
|
231
|
+
'BrownfieldNavigation',
|
|
232
|
+
'BrownfieldNavigation.framework'
|
|
233
|
+
),
|
|
234
|
+
path.join(
|
|
235
|
+
productsPath,
|
|
236
|
+
`${configuration}-iphonesimulator`,
|
|
237
|
+
'BrownfieldNavigation',
|
|
238
|
+
'BrownfieldNavigation.framework'
|
|
239
|
+
),
|
|
240
|
+
],
|
|
241
|
+
outputPath: brownfieldNavigationOutputPath,
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
stripFrameworkBinary(brownfieldNavigationOutputPath);
|
|
245
|
+
|
|
246
|
+
logger.success(
|
|
247
|
+
`BrownfieldNavigation.xcframework created at ${colorLink(relativeToCwd(brownfieldNavigationOutputPath))}`
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
})
|
|
251
|
+
);
|
|
175
252
|
|
|
176
253
|
export const packageIosExample = new ExampleUsage(
|
|
177
254
|
'package:ios --scheme BrownfieldLib --configuration Release',
|
|
@@ -56,6 +56,15 @@ export function isExpoProject(projectRoot: string): boolean {
|
|
|
56
56
|
return hasExpoConfig && dependsOnExpo;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
export function getExpoSdkMajor(projectRoot: string): number | null {
|
|
60
|
+
const rawExpoVersion = getExpoConfigIfIsExpo(projectRoot)?.exp.sdkVersion;
|
|
61
|
+
if (!rawExpoVersion) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const expoSdkMajor = parseInt(rawExpoVersion.split('.')[0], 10);
|
|
65
|
+
return Number.isFinite(expoSdkMajor) ? expoSdkMajor : null;
|
|
66
|
+
}
|
|
67
|
+
|
|
59
68
|
/**
|
|
60
69
|
* Fills the RNC CLI project config from the Expo config by mutating the passed in `options.projectConfig` object in place
|
|
61
70
|
*/
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { getReactNativeVersion, versionCompare } from '@rock-js/tools';
|
|
2
|
+
|
|
3
|
+
import { getExpoSdkMajor, isExpoProject } from './project.js';
|
|
4
|
+
|
|
5
|
+
/** Minimum RN version that can opt in to prebuilts via `--use-prebuilt-rn-core`. */
|
|
6
|
+
export const MIN_REACT_NATIVE_VERSION_FOR_OPT_IN_PREBUILT_RN_CORE = '0.81.0';
|
|
7
|
+
/** Minimum RN version where Brownfield enables prebuilts by default (vanilla projects). */
|
|
8
|
+
export const MIN_REACT_NATIVE_VERSION_FOR_PREBUILT_RN_CORE_BY_DEFAULT =
|
|
9
|
+
'0.84.0';
|
|
10
|
+
export const MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_RN_CORE_BY_DEFAULT = 55;
|
|
11
|
+
|
|
12
|
+
export type PrebuiltRNCoreSupportResult =
|
|
13
|
+
| { supported: true; enabledByDefault: boolean; reason?: never }
|
|
14
|
+
| { supported: false; enabledByDefault?: never; reason: string };
|
|
15
|
+
|
|
16
|
+
export function supportsPrebuiltRNCore({
|
|
17
|
+
projectRoot,
|
|
18
|
+
}: {
|
|
19
|
+
projectRoot: string;
|
|
20
|
+
}): PrebuiltRNCoreSupportResult {
|
|
21
|
+
const reactNativeVersion = getReactNativeVersion(projectRoot);
|
|
22
|
+
|
|
23
|
+
if (reactNativeVersion === 'unknown') {
|
|
24
|
+
return {
|
|
25
|
+
supported: false,
|
|
26
|
+
reason:
|
|
27
|
+
'Cannot use --use-prebuilt-rn-core: unable to resolve the installed react-native version.',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (
|
|
32
|
+
versionCompare(
|
|
33
|
+
reactNativeVersion,
|
|
34
|
+
MIN_REACT_NATIVE_VERSION_FOR_OPT_IN_PREBUILT_RN_CORE
|
|
35
|
+
) < 0
|
|
36
|
+
) {
|
|
37
|
+
return {
|
|
38
|
+
supported: false,
|
|
39
|
+
reason: `--use-prebuilt-rn-core requires React Native ${MIN_REACT_NATIVE_VERSION_FOR_OPT_IN_PREBUILT_RN_CORE} or newer (found ${reactNativeVersion}).`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (isExpoProject(projectRoot)) {
|
|
44
|
+
const expoSdkMajor = getExpoSdkMajor(projectRoot);
|
|
45
|
+
|
|
46
|
+
if (
|
|
47
|
+
expoSdkMajor === null ||
|
|
48
|
+
expoSdkMajor < MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_RN_CORE_BY_DEFAULT
|
|
49
|
+
) {
|
|
50
|
+
const sdkLabel = expoSdkMajor === null ? 'unknown' : String(expoSdkMajor);
|
|
51
|
+
return {
|
|
52
|
+
supported: false,
|
|
53
|
+
reason: `--use-prebuilt-rn-core is unsupported in Expo SDK ${sdkLabel}: packaging brownfield with prebuilts requires Expo SDK ${MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_RN_CORE_BY_DEFAULT} or newer.`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return { supported: true, enabledByDefault: true };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const enabledByDefault =
|
|
61
|
+
versionCompare(
|
|
62
|
+
reactNativeVersion,
|
|
63
|
+
MIN_REACT_NATIVE_VERSION_FOR_PREBUILT_RN_CORE_BY_DEFAULT
|
|
64
|
+
) >= 0;
|
|
65
|
+
|
|
66
|
+
return { supported: true, enabledByDefault };
|
|
67
|
+
}
|