@callstack/brownfield-cli 3.13.1 → 3.14.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/packageAndroid.d.ts.map +1 -1
- package/dist/brownfield/commands/packageAndroid.js +3 -1
- 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 +37 -4
- package/dist/brownfield/commands/publishAndroid.d.ts.map +1 -1
- package/dist/brownfield/commands/publishAndroid.js +3 -1
- package/dist/brownfield/utils/createLocalSpmPackage.d.ts +2 -1
- package/dist/brownfield/utils/createLocalSpmPackage.d.ts.map +1 -1
- package/dist/brownfield/utils/createLocalSpmPackage.js +8 -2
- package/dist/brownfield/utils/emitExpoSupportXcframeworks.d.ts +9 -0
- package/dist/brownfield/utils/emitExpoSupportXcframeworks.d.ts.map +1 -0
- package/dist/brownfield/utils/emitExpoSupportXcframeworks.js +70 -0
- package/dist/brownfield/utils/normalizeCopiedXcframework.d.ts +3 -0
- package/dist/brownfield/utils/normalizeCopiedXcframework.d.ts.map +1 -0
- package/dist/brownfield/utils/normalizeCopiedXcframework.js +64 -0
- package/dist/brownfield/utils/prepareLocalSpmArtifacts.d.ts.map +1 -1
- package/dist/brownfield/utils/prepareLocalSpmArtifacts.js +2 -63
- package/dist/brownfield/utils/project.d.ts.map +1 -1
- package/dist/brownfield/utils/project.js +20 -9
- package/dist/brownfield/utils/supportsPrebuiltExpo.d.ts +14 -0
- package/dist/brownfield/utils/supportsPrebuiltExpo.d.ts.map +1 -0
- package/dist/brownfield/utils/supportsPrebuiltExpo.js +20 -0
- package/dist/brownie/config.js +1 -1
- package/dist/config.d.ts +4 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -7
- package/dist/expoPluginConfig.d.ts +74 -0
- package/dist/expoPluginConfig.d.ts.map +1 -0
- package/dist/expoPluginConfig.js +103 -0
- package/dist/types.d.ts +94 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -6
- package/schema.json +98 -9
- package/src/brownfield/commands/packageAndroid.ts +4 -1
- package/src/brownfield/commands/packageIos.ts +53 -4
- package/src/brownfield/commands/publishAndroid.ts +4 -1
- package/src/brownfield/utils/createLocalSpmPackage.ts +15 -1
- package/src/brownfield/utils/emitExpoSupportXcframeworks.ts +132 -0
- package/src/brownfield/utils/normalizeCopiedXcframework.ts +90 -0
- package/src/brownfield/utils/prepareLocalSpmArtifacts.ts +7 -90
- package/src/brownfield/utils/project.ts +33 -14
- package/src/brownfield/utils/supportsPrebuiltExpo.ts +34 -0
- package/src/brownie/config.ts +1 -1
- package/src/config.ts +12 -8
- package/src/expoPluginConfig.ts +195 -0
- package/src/types.ts +112 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @callstack/brownfield-cli
|
|
2
2
|
|
|
3
|
+
## 3.14.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#360](https://github.com/callstack/react-native-brownfield/pull/360) [`10ff597`](https://github.com/callstack/react-native-brownfield/commit/10ff597c057c04aa093b4e5ae8c5334b169d3d56) Thanks [@adamTrz](https://github.com/adamTrz)! - Expo SDK 56 support
|
|
8
|
+
|
|
9
|
+
## 3.13.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#398](https://github.com/callstack/react-native-brownfield/pull/398) [`8e90842`](https://github.com/callstack/react-native-brownfield/commit/8e90842291348dcb0542a6787f5cfbb1017532dd) Thanks [@artus9033](https://github.com/artus9033)! - feat: support brownfield unified config file in Expo
|
|
14
|
+
|
|
15
|
+
- [#402](https://github.com/callstack/react-native-brownfield/pull/402) [`3475c3d`](https://github.com/callstack/react-native-brownfield/commit/3475c3db375988ebd63ce01bfd93f4dbb1a55e8d) Thanks [@artus9033](https://github.com/artus9033)! - feat: support local BGP in Expo config plugin
|
|
16
|
+
|
|
17
|
+
- [#397](https://github.com/callstack/react-native-brownfield/pull/397) [`4088c01`](https://github.com/callstack/react-native-brownfield/commit/4088c01a069306565dd3e279d9132f5dbe861d0b) Thanks [@artus9033](https://github.com/artus9033)! - fix: generate config schema with descriptions, add more descriptions
|
|
18
|
+
|
|
3
19
|
## 3.13.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageAndroid.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/packageAndroid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,OAAO,EACL,YAAY,EAGb,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"packageAndroid.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/packageAndroid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,OAAO,EACL,YAAY,EAGb,MAAM,uBAAuB,CAAC;AAQ/B,eAAO,MAAM,qBAAqB,SAyBjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,cAGjC,CAAC"}
|
|
@@ -3,17 +3,19 @@ import { packageAarOptions, } from '@rock-js/platform-android';
|
|
|
3
3
|
import { packageAarAction } from '@rock-js/plugin-brownfield-android';
|
|
4
4
|
import { ExampleUsage, actionRunner, curryOptions, } from '../../shared/index.js';
|
|
5
5
|
import { runExpoPrebuildIfNeeded } from '../utils/expo.js';
|
|
6
|
+
import { findProjectRoot } from '../utils/paths.js';
|
|
6
7
|
import { getProjectInfo } from '../utils/project.js';
|
|
7
8
|
import { runBrownieCodegenIfApplicable } from '../../brownie/helpers/runBrownieCodegenIfApplicable.js';
|
|
8
9
|
import { runNavigationCodegenIfApplicable } from '../../navigation/helpers/runNavigationCodegenIfApplicable.js';
|
|
9
10
|
import { mergeBrownfieldConfigWithOptions } from '../../config.js';
|
|
10
11
|
export const packageAndroidCommand = curryOptions(new Command('package:android').description('Build Android AAR'), packageAarOptions).action(actionRunner(async (cliOptions) => {
|
|
11
12
|
const options = mergeBrownfieldConfigWithOptions(cliOptions, 'android');
|
|
12
|
-
const
|
|
13
|
+
const projectRoot = findProjectRoot();
|
|
13
14
|
await runExpoPrebuildIfNeeded({
|
|
14
15
|
projectRoot,
|
|
15
16
|
platform: 'android',
|
|
16
17
|
});
|
|
18
|
+
const { platformConfig } = getProjectInfo('android');
|
|
17
19
|
await runBrownieCodegenIfApplicable(projectRoot, 'kotlin');
|
|
18
20
|
await runNavigationCodegenIfApplicable(projectRoot);
|
|
19
21
|
await packageAarAction({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { ExampleUsage } from '../../shared/index.js';
|
|
3
3
|
export declare function parseUsePrebuiltRnCoreArgument(value: string | boolean): boolean;
|
|
4
|
+
export declare function parseUsePrebuiltExpoArgument(value: string | boolean): boolean;
|
|
4
5
|
export declare const packageIosCommand: Command;
|
|
5
6
|
export declare const packageIosExample: ExampleUsage;
|
|
6
7
|
//# sourceMappingURL=packageIos.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageIos.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/packageIos.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"packageIos.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/packageIos.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAO5C,OAAO,EAGL,YAAY,EACb,MAAM,uBAAuB,CAAC;AA4C/B,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,MAAM,GAAG,OAAO,GACtB,OAAO,CAET;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,GAAG,OAAO,GACtB,OAAO,CAET;AAcD,eAAO,MAAM,iBAAiB,SA8R3B,CAAC;AAEJ,eAAO,MAAM,iBAAiB,cAG7B,CAAC"}
|
|
@@ -5,7 +5,9 @@ import { packageIosAction } from '@rock-js/plugin-brownfield-ios';
|
|
|
5
5
|
import { RockError, colorLink, getReactNativeVersion, logger, relativeToCwd, } from '@rock-js/tools';
|
|
6
6
|
import { Command, Option } from 'commander';
|
|
7
7
|
import { runExpoPrebuildIfNeeded } from '../utils/expo.js';
|
|
8
|
+
import { findProjectRoot } from '../utils/paths.js';
|
|
8
9
|
import { getProjectInfo } from '../utils/project.js';
|
|
10
|
+
import { supportsPrebuiltExpo } from '../utils/supportsPrebuiltExpo.js';
|
|
9
11
|
import { supportsPrebuiltRNCore } from '../utils/supportsPrebuiltRNCore.js';
|
|
10
12
|
import { actionRunner, curryOptions, ExampleUsage, } from '../../shared/index.js';
|
|
11
13
|
import { runBrownieCodegenIfApplicable } from '../../brownie/helpers/runBrownieCodegenIfApplicable.js';
|
|
@@ -14,13 +16,19 @@ import { copyDebugBundleToSimulatorSlice } from '../utils/copyDebugBundleToSimul
|
|
|
14
16
|
import { resolvePackagedFrameworkName } from '../utils/resolvePackagedFrameworkName.js';
|
|
15
17
|
import { stripFrameworkBinary } from '../utils/stripFrameworkBinary.js';
|
|
16
18
|
import { createLocalSpmPackage } from '../utils/createLocalSpmPackage.js';
|
|
19
|
+
import { emitExpoSupportXcframeworks } from '../utils/emitExpoSupportXcframeworks.js';
|
|
17
20
|
import { mergeBrownfieldConfigWithOptions } from '../../config.js';
|
|
21
|
+
import { removeCodeSignatureArtifacts } from '../utils/normalizeCopiedXcframework.js';
|
|
18
22
|
/** Help text for `--use-prebuilt-rn-core` (keep in sync with docs/docs/docs/getting-started/ios.mdx, "React Native Prebuilts" section). */
|
|
19
23
|
const USE_PREBUILT_RN_CORE_HELP = 'Whether the Xcode build for packaging should use React Native Apple prebuilt binaries (via CocoaPods). ' +
|
|
20
24
|
'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. ' +
|
|
21
25
|
'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`). ' +
|
|
22
26
|
'See the Brownfield iOS guide for details: https://oss.callstack.com/react-native-brownfield/docs/getting-started/ios#react-native-prebuilts';
|
|
23
|
-
|
|
27
|
+
/** Help text for `--use-prebuilt-expo`. */
|
|
28
|
+
const USE_PREBUILT_EXPO_HELP = 'Whether the Xcode build for packaging should use prebuilt Expo support XCFrameworks. ' +
|
|
29
|
+
'If you omit this flag, Brownfield follows version-aware defaults for supported Expo projects. ' +
|
|
30
|
+
'Pass true or false to force either behavior. Use the flag without a value as shorthand for true (same as `--use-prebuilt-expo true`).';
|
|
31
|
+
function parseBooleanOptionArgument(flagName, value) {
|
|
24
32
|
if (typeof value === 'boolean') {
|
|
25
33
|
return value;
|
|
26
34
|
}
|
|
@@ -31,7 +39,13 @@ export function parseUsePrebuiltRnCoreArgument(value) {
|
|
|
31
39
|
if (normalized === 'false' || normalized === '0') {
|
|
32
40
|
return false;
|
|
33
41
|
}
|
|
34
|
-
throw new RockError(`Invalid value for
|
|
42
|
+
throw new RockError(`Invalid value for ${flagName}: expected true or false, received "${value}"`);
|
|
43
|
+
}
|
|
44
|
+
export function parseUsePrebuiltRnCoreArgument(value) {
|
|
45
|
+
return parseBooleanOptionArgument('--use-prebuilt-rn-core', value);
|
|
46
|
+
}
|
|
47
|
+
export function parseUsePrebuiltExpoArgument(value) {
|
|
48
|
+
return parseBooleanOptionArgument('--use-prebuilt-expo', value);
|
|
35
49
|
}
|
|
36
50
|
function getPackagedFrameworkResolutionFailureMessage({ resolution, candidates, }) {
|
|
37
51
|
return resolution === 'ambiguous'
|
|
@@ -48,15 +62,25 @@ export const packageIosCommand = curryOptions(new Command('package:ios').descrip
|
|
|
48
62
|
.addOption(new Option('--use-prebuilt-rn-core [bool]', USE_PREBUILT_RN_CORE_HELP)
|
|
49
63
|
.preset(true)
|
|
50
64
|
.argParser(parseUsePrebuiltRnCoreArgument))
|
|
65
|
+
.addOption(new Option('--use-prebuilt-expo [bool]', USE_PREBUILT_EXPO_HELP)
|
|
66
|
+
.preset(true)
|
|
67
|
+
.argParser(parseUsePrebuiltExpoArgument))
|
|
51
68
|
.addOption(new Option('--add-spm-package', 'Generate a local Swift Package Manager manifest next to the packaged XCFramework outputs'))
|
|
52
69
|
.action(actionRunner(async (cliOptions) => {
|
|
53
70
|
const options = mergeBrownfieldConfigWithOptions(cliOptions, 'ios');
|
|
54
|
-
const
|
|
71
|
+
const projectRoot = findProjectRoot();
|
|
72
|
+
await runExpoPrebuildIfNeeded({ projectRoot, platform: 'ios' });
|
|
73
|
+
const { platformConfig, userConfig } = getProjectInfo('ios');
|
|
55
74
|
const prebuiltRNCoreSupport = supportsPrebuiltRNCore({ projectRoot });
|
|
75
|
+
const prebuiltExpoSupport = supportsPrebuiltExpo({ projectRoot });
|
|
56
76
|
// version-aware default when the flag is omitted (see ios.mdx "React Native Prebuilts")
|
|
57
77
|
options.usePrebuiltRnCore ??= prebuiltRNCoreSupport.supported
|
|
58
78
|
? prebuiltRNCoreSupport.enabledByDefault
|
|
59
79
|
: false;
|
|
80
|
+
// version-aware default when the flag is omitted
|
|
81
|
+
options.usePrebuiltExpo ??= prebuiltExpoSupport.supported
|
|
82
|
+
? prebuiltExpoSupport.enabledByDefault
|
|
83
|
+
: false;
|
|
60
84
|
if (prebuiltRNCoreSupport) {
|
|
61
85
|
logger.info(`${options.usePrebuiltRnCore ? 'Using' : 'Not using'} prebuilt RN core`);
|
|
62
86
|
if (!prebuiltRNCoreSupport.enabledByDefault &&
|
|
@@ -67,7 +91,9 @@ export const packageIosCommand = curryOptions(new Command('package:ios').descrip
|
|
|
67
91
|
if (options.usePrebuiltRnCore && !prebuiltRNCoreSupport.supported) {
|
|
68
92
|
throw new RockError(prebuiltRNCoreSupport.reason);
|
|
69
93
|
}
|
|
70
|
-
|
|
94
|
+
if (options.usePrebuiltExpo && !prebuiltExpoSupport.supported) {
|
|
95
|
+
throw new RockError(prebuiltExpoSupport.reason);
|
|
96
|
+
}
|
|
71
97
|
if (!userConfig.project.ios) {
|
|
72
98
|
throw new Error('iOS project not found.');
|
|
73
99
|
}
|
|
@@ -104,6 +130,11 @@ export const packageIosCommand = curryOptions(new Command('package:ios').descrip
|
|
|
104
130
|
skipCache: true, // cache is dependent on existence of Rock config file
|
|
105
131
|
usePrebuiltRNCore: options.usePrebuiltRnCore,
|
|
106
132
|
}, platformConfig);
|
|
133
|
+
emitExpoSupportXcframeworks({
|
|
134
|
+
projectRoot,
|
|
135
|
+
packageDir,
|
|
136
|
+
usePrebuiltExpo: options.usePrebuiltExpo,
|
|
137
|
+
});
|
|
107
138
|
const productsPath = path.join(options.buildFolder, 'Build', 'Products');
|
|
108
139
|
const { frameworkName, resolution, candidates } = resolvePackagedFrameworkName({
|
|
109
140
|
explicitScheme: options.scheme,
|
|
@@ -176,10 +207,12 @@ export const packageIosCommand = curryOptions(new Command('package:ios').descrip
|
|
|
176
207
|
stripFrameworkBinary(brownfieldNavigationOutputPath);
|
|
177
208
|
logger.success(`BrownfieldNavigation.xcframework created at ${colorLink(relativeToCwd(brownfieldNavigationOutputPath))}`);
|
|
178
209
|
}
|
|
210
|
+
removeCodeSignatureArtifacts(packageDir);
|
|
179
211
|
if (options.addSpmPackage) {
|
|
180
212
|
const { packageManifestPath } = createLocalSpmPackage({
|
|
181
213
|
packageDir,
|
|
182
214
|
frameworkName: frameworkName ?? undefined,
|
|
215
|
+
usePrebuiltExpo: options.usePrebuiltExpo,
|
|
183
216
|
});
|
|
184
217
|
logger.success(`Local SPM package manifest created at ${colorLink(relativeToCwd(packageManifestPath))}`);
|
|
185
218
|
logger.info(`Add the local package folder in Xcode: ${colorLink(relativeToCwd(packageDir))}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publishAndroid.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/publishAndroid.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAGL,YAAY,EACb,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"publishAndroid.d.ts","sourceRoot":"","sources":["../../../src/brownfield/commands/publishAndroid.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAGL,YAAY,EACb,MAAM,uBAAuB,CAAC;AAQ/B,eAAO,MAAM,qBAAqB,SA0BjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,cAGjC,CAAC"}
|
|
@@ -3,17 +3,19 @@ import { publishLocalAarOptions, } from '@rock-js/platform-android';
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { actionRunner, curryOptions, ExampleUsage, } from '../../shared/index.js';
|
|
5
5
|
import { getProjectInfo } from '../utils/project.js';
|
|
6
|
+
import { findProjectRoot } from '../utils/paths.js';
|
|
6
7
|
import { runExpoPrebuildIfNeeded } from '../utils/expo.js';
|
|
7
8
|
import { runBrownieCodegenIfApplicable } from '../../brownie/helpers/runBrownieCodegenIfApplicable.js';
|
|
8
9
|
import { runNavigationCodegenIfApplicable } from '../../navigation/helpers/runNavigationCodegenIfApplicable.js';
|
|
9
10
|
import { mergeBrownfieldConfigWithOptions } from '../../config.js';
|
|
10
11
|
export const publishAndroidCommand = curryOptions(new Command('publish:android').description('Publish Android package to Maven local'), publishLocalAarOptions).action(actionRunner(async (cliOptions) => {
|
|
11
12
|
const options = mergeBrownfieldConfigWithOptions(cliOptions, 'android');
|
|
12
|
-
const
|
|
13
|
+
const projectRoot = findProjectRoot();
|
|
13
14
|
await runExpoPrebuildIfNeeded({
|
|
14
15
|
projectRoot,
|
|
15
16
|
platform: 'android',
|
|
16
17
|
});
|
|
18
|
+
const { platformConfig } = getProjectInfo('android');
|
|
17
19
|
await runBrownieCodegenIfApplicable(projectRoot, 'kotlin');
|
|
18
20
|
await runNavigationCodegenIfApplicable(projectRoot);
|
|
19
21
|
await publishLocalAarAction({
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
type CreateLocalSpmPackageOptions = {
|
|
2
2
|
packageDir: string;
|
|
3
3
|
frameworkName?: string;
|
|
4
|
+
usePrebuiltExpo?: boolean;
|
|
4
5
|
};
|
|
5
6
|
type CreateLocalSpmPackageResult = {
|
|
6
7
|
packageManifestPath: string;
|
|
7
8
|
};
|
|
8
|
-
export declare function createLocalSpmPackage({ packageDir, frameworkName, }: CreateLocalSpmPackageOptions): CreateLocalSpmPackageResult;
|
|
9
|
+
export declare function createLocalSpmPackage({ packageDir, frameworkName, usePrebuiltExpo, }: CreateLocalSpmPackageOptions): CreateLocalSpmPackageResult;
|
|
9
10
|
export {};
|
|
10
11
|
//# sourceMappingURL=createLocalSpmPackage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createLocalSpmPackage.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/createLocalSpmPackage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createLocalSpmPackage.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/createLocalSpmPackage.ts"],"names":[],"mappings":"AAYA,KAAK,4BAA4B,GAAG;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,KAAK,2BAA2B,GAAG;IACjC,mBAAmB,EAAE,MAAM,CAAC;CAC7B,CAAC;AA0JF,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,aAAa,EACb,eAAsB,GACvB,EAAE,4BAA4B,GAAG,2BAA2B,CA2C5D"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { prepareLocalSpmArtifacts, SPM_ARTIFACTS_DIR_NAME, } from './prepareLocalSpmArtifacts.js';
|
|
4
|
+
import { ALL_EXPO_SUPPORT_XCFRAMEWORK_NAMES, getExpoSupportXcframeworkNames, } from './emitExpoSupportXcframeworks.js';
|
|
4
5
|
const RESERVED_FRAMEWORK_NAMES = new Set([
|
|
5
6
|
'hermes',
|
|
6
7
|
'hermesvm',
|
|
@@ -9,6 +10,7 @@ const RESERVED_FRAMEWORK_NAMES = new Set([
|
|
|
9
10
|
'BrownfieldNavigation',
|
|
10
11
|
'React',
|
|
11
12
|
'ReactNativeDependencies',
|
|
13
|
+
...ALL_EXPO_SUPPORT_XCFRAMEWORK_NAMES,
|
|
12
14
|
]);
|
|
13
15
|
function requireXcframework(packageDir, name) {
|
|
14
16
|
const xcframeworkPath = path.join(packageDir, `${name}.xcframework`);
|
|
@@ -71,7 +73,9 @@ ${binaryTargets}
|
|
|
71
73
|
`;
|
|
72
74
|
}
|
|
73
75
|
function renderReadme({ packageName, libraryName, targetNames, }) {
|
|
74
|
-
const frameworks = targetNames
|
|
76
|
+
const frameworks = targetNames
|
|
77
|
+
.map((targetName) => `- \`${targetName}\``)
|
|
78
|
+
.join('\n');
|
|
75
79
|
return `# ${packageName}
|
|
76
80
|
|
|
77
81
|
This is a generated local Swift Package Manager package for the packaged React Native brownfield artifacts.
|
|
@@ -103,14 +107,16 @@ If Xcode builds your host app but the simulator installation fails, check the ho
|
|
|
103
107
|
This folder is generated by \`brownfield package:ios --add-spm-package\`. Re-run that command whenever the packaged XCFrameworks change so this package stays in sync.
|
|
104
108
|
`;
|
|
105
109
|
}
|
|
106
|
-
export function createLocalSpmPackage({ packageDir, frameworkName, }) {
|
|
110
|
+
export function createLocalSpmPackage({ packageDir, frameworkName, usePrebuiltExpo = true, }) {
|
|
107
111
|
const resolvedFrameworkName = resolveAppFrameworkName(packageDir, frameworkName);
|
|
112
|
+
const expoSupportXcframeworkNames = getExpoSupportXcframeworkNames(usePrebuiltExpo);
|
|
108
113
|
const targetNames = [
|
|
109
114
|
resolvedFrameworkName,
|
|
110
115
|
requireHermesXcframework(packageDir),
|
|
111
116
|
requireXcframework(packageDir, 'ReactBrownfield'),
|
|
112
117
|
optionalXcframework(packageDir, 'Brownie'),
|
|
113
118
|
optionalXcframework(packageDir, 'BrownfieldNavigation'),
|
|
119
|
+
...expoSupportXcframeworkNames.map((frameworkName) => optionalXcframework(packageDir, frameworkName)),
|
|
114
120
|
optionalXcframework(packageDir, 'React'),
|
|
115
121
|
optionalXcframework(packageDir, 'ReactNativeDependencies'),
|
|
116
122
|
].filter((targetName) => targetName !== null);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const EXPO_SUPPORT_XCFRAMEWORK_NAMES: readonly ["ExpoModulesJSI", "ExpoFileSystem", "ExpoFont", "ExpoModulesCore", "ExpoImage", "ExpoModulesWorklets"];
|
|
2
|
+
export declare const ALL_EXPO_SUPPORT_XCFRAMEWORK_NAMES: readonly ["ExpoModulesJSI", "ExpoFileSystem", "ExpoFont", "ExpoModulesCore", "ExpoImage", "ExpoModulesWorklets", "SDWebImage", "SDWebImageSVGCoder", "SDWebImageWebPCoder", "SDWebImageAVIFCoder", "libavif"];
|
|
3
|
+
export declare function getExpoSupportXcframeworkNames(usePrebuiltExpo: boolean): readonly ["ExpoModulesJSI", "ExpoFileSystem", "ExpoFont", "ExpoModulesCore", "ExpoImage", "ExpoModulesWorklets", "SDWebImage", "SDWebImageSVGCoder", "SDWebImageWebPCoder", "SDWebImageAVIFCoder", "libavif"] | readonly ["ExpoModulesJSI"];
|
|
4
|
+
export declare function emitExpoSupportXcframeworks({ projectRoot, packageDir, usePrebuiltExpo, }: {
|
|
5
|
+
projectRoot: string;
|
|
6
|
+
packageDir: string;
|
|
7
|
+
usePrebuiltExpo?: boolean;
|
|
8
|
+
}): boolean;
|
|
9
|
+
//# sourceMappingURL=emitExpoSupportXcframeworks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitExpoSupportXcframeworks.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/emitExpoSupportXcframeworks.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,8BAA8B,kHAOjC,CAAC;AAEX,eAAO,MAAM,kCAAkC,+MAGrC,CAAC;AAEX,wBAAgB,8BAA8B,CAAC,eAAe,EAAE,OAAO,+OAItE;AA8CD,wBAAgB,2BAA2B,CAAC,EAC1C,WAAW,EACX,UAAU,EACV,eAAsB,GACvB,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,WAkCA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { RockError } from '@rock-js/tools';
|
|
4
|
+
import { normalizeCopiedXcframework } from './normalizeCopiedXcframework.js';
|
|
5
|
+
import { getExpoSdkMajor, isExpoProject } from './project.js';
|
|
6
|
+
import { MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_EXPO } from './supportsPrebuiltExpo.js';
|
|
7
|
+
/**
|
|
8
|
+
* Swift support XCFrameworks
|
|
9
|
+
*
|
|
10
|
+
* These are required for the Expo Image module to work.
|
|
11
|
+
*
|
|
12
|
+
* TODO: This needs investigation and maybe a discussion with the Expo team.
|
|
13
|
+
*/
|
|
14
|
+
const SWIFT_SUPPORT_XCFRAMEWORK_NAMES = [
|
|
15
|
+
'SDWebImage',
|
|
16
|
+
'SDWebImageSVGCoder',
|
|
17
|
+
'SDWebImageWebPCoder',
|
|
18
|
+
'SDWebImageAVIFCoder',
|
|
19
|
+
'libavif',
|
|
20
|
+
];
|
|
21
|
+
export const EXPO_SUPPORT_XCFRAMEWORK_NAMES = [
|
|
22
|
+
'ExpoModulesJSI',
|
|
23
|
+
'ExpoFileSystem',
|
|
24
|
+
'ExpoFont',
|
|
25
|
+
'ExpoModulesCore',
|
|
26
|
+
'ExpoImage',
|
|
27
|
+
'ExpoModulesWorklets'
|
|
28
|
+
];
|
|
29
|
+
export const ALL_EXPO_SUPPORT_XCFRAMEWORK_NAMES = [
|
|
30
|
+
...EXPO_SUPPORT_XCFRAMEWORK_NAMES,
|
|
31
|
+
...SWIFT_SUPPORT_XCFRAMEWORK_NAMES,
|
|
32
|
+
];
|
|
33
|
+
export function getExpoSupportXcframeworkNames(usePrebuiltExpo) {
|
|
34
|
+
return usePrebuiltExpo
|
|
35
|
+
? ALL_EXPO_SUPPORT_XCFRAMEWORK_NAMES
|
|
36
|
+
: ['ExpoModulesJSI'];
|
|
37
|
+
}
|
|
38
|
+
function resolveExpoFrameworkSourcePath(projectRoot, frameworkName) {
|
|
39
|
+
if (frameworkName === 'ExpoModulesJSI') {
|
|
40
|
+
return path.join(projectRoot, 'node_modules', 'expo-modules-jsi', 'apple', 'Products', 'ExpoModulesJSI.xcframework');
|
|
41
|
+
}
|
|
42
|
+
if (SWIFT_SUPPORT_XCFRAMEWORK_NAMES.includes(frameworkName)) {
|
|
43
|
+
return path.join(projectRoot, 'ios', 'Pods', 'ExpoImage', `${frameworkName}.xcframework`);
|
|
44
|
+
}
|
|
45
|
+
if (EXPO_SUPPORT_XCFRAMEWORK_NAMES.includes(frameworkName)) {
|
|
46
|
+
return path.join(projectRoot, 'ios', 'Pods', frameworkName, `${frameworkName}.xcframework`);
|
|
47
|
+
}
|
|
48
|
+
throw new RockError(`Unsupported Expo XCFramework: ${frameworkName}`);
|
|
49
|
+
}
|
|
50
|
+
export function emitExpoSupportXcframeworks({ projectRoot, packageDir, usePrebuiltExpo = true, }) {
|
|
51
|
+
if (!isExpoProject(projectRoot)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const expoSdkMajor = getExpoSdkMajor(projectRoot);
|
|
55
|
+
if (expoSdkMajor === null ||
|
|
56
|
+
expoSdkMajor < MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_EXPO) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
for (const frameworkName of getExpoSupportXcframeworkNames(usePrebuiltExpo)) {
|
|
60
|
+
const sourcePath = resolveExpoFrameworkSourcePath(projectRoot, frameworkName);
|
|
61
|
+
if (!fs.existsSync(sourcePath)) {
|
|
62
|
+
throw new RockError(`Expected Expo SDK ${MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_EXPO}+ XCFramework not found: ${frameworkName}.xcframework at ${path.relative(projectRoot, sourcePath)}`);
|
|
63
|
+
}
|
|
64
|
+
const destinationPath = path.join(packageDir, `${frameworkName}.xcframework`);
|
|
65
|
+
fs.rmSync(destinationPath, { recursive: true, force: true });
|
|
66
|
+
fs.cpSync(sourcePath, destinationPath, { recursive: true });
|
|
67
|
+
normalizeCopiedXcframework(destinationPath);
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalizeCopiedXcframework.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/normalizeCopiedXcframework.ts"],"names":[],"mappings":"AAIA,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,QAkB3D;AAyCD,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,QA0BjE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { execFileSync } from 'node:child_process';
|
|
4
|
+
export function removeCodeSignatureArtifacts(dirPath) {
|
|
5
|
+
for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
|
|
6
|
+
const entryPath = path.join(dirPath, entry.name);
|
|
7
|
+
if (entry.isDirectory()) {
|
|
8
|
+
if (entry.name === '_CodeSignature') {
|
|
9
|
+
fs.rmSync(entryPath, { recursive: true, force: true });
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
removeCodeSignatureArtifacts(entryPath);
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (entry.name === 'CodeResources') {
|
|
16
|
+
fs.rmSync(entryPath, { force: true });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function resolveFrameworkExecutablePath(frameworkDir, frameworkName) {
|
|
21
|
+
const directExecutablePath = path.join(frameworkDir, frameworkName);
|
|
22
|
+
if (fs.existsSync(directExecutablePath)) {
|
|
23
|
+
return directExecutablePath;
|
|
24
|
+
}
|
|
25
|
+
const versionedExecutablePath = path.join(frameworkDir, 'Versions', 'Current', frameworkName);
|
|
26
|
+
if (fs.existsSync(versionedExecutablePath)) {
|
|
27
|
+
return versionedExecutablePath;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
function removeExecutableSignature(executablePath) {
|
|
32
|
+
try {
|
|
33
|
+
execFileSync('codesign', ['--remove-signature', executablePath], {
|
|
34
|
+
stdio: 'pipe',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error instanceof Error &&
|
|
39
|
+
error.message.includes('code object is not signed at all')) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function normalizeCopiedXcframework(xcframeworkPath) {
|
|
46
|
+
removeCodeSignatureArtifacts(xcframeworkPath);
|
|
47
|
+
for (const sliceName of fs.readdirSync(xcframeworkPath)) {
|
|
48
|
+
const slicePath = path.join(xcframeworkPath, sliceName);
|
|
49
|
+
if (!fs.statSync(slicePath).isDirectory()) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
for (const entry of fs.readdirSync(slicePath)) {
|
|
53
|
+
if (!entry.endsWith('.framework')) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const frameworkName = path.basename(entry, '.framework');
|
|
57
|
+
const frameworkDir = path.join(slicePath, entry);
|
|
58
|
+
const executablePath = resolveFrameworkExecutablePath(frameworkDir, frameworkName);
|
|
59
|
+
if (executablePath) {
|
|
60
|
+
removeExecutableSignature(executablePath);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepareLocalSpmArtifacts.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/prepareLocalSpmArtifacts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prepareLocalSpmArtifacts.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/prepareLocalSpmArtifacts.ts"],"names":[],"mappings":"AAKA,KAAK,+BAA+B,GAAG;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,sBAAsB,kBAAkB,CAAC;AAEtD,wBAAgB,wBAAwB,CAAC,EACvC,UAAU,EACV,WAAW,GACZ,EAAE,+BAA+B,UAkBjC"}
|
|
@@ -1,68 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { normalizeCopiedXcframework } from './normalizeCopiedXcframework.js';
|
|
4
4
|
export const SPM_ARTIFACTS_DIR_NAME = 'spm-artifacts';
|
|
5
|
-
function removeCodeSignatureArtifacts(dirPath) {
|
|
6
|
-
for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
|
|
7
|
-
const entryPath = path.join(dirPath, entry.name);
|
|
8
|
-
if (entry.isDirectory()) {
|
|
9
|
-
if (entry.name === '_CodeSignature') {
|
|
10
|
-
fs.rmSync(entryPath, { recursive: true, force: true });
|
|
11
|
-
continue;
|
|
12
|
-
}
|
|
13
|
-
removeCodeSignatureArtifacts(entryPath);
|
|
14
|
-
continue;
|
|
15
|
-
}
|
|
16
|
-
if (entry.name === 'CodeResources') {
|
|
17
|
-
fs.rmSync(entryPath, { force: true });
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
function resolveFrameworkExecutablePath(frameworkDir, frameworkName) {
|
|
22
|
-
const directExecutablePath = path.join(frameworkDir, frameworkName);
|
|
23
|
-
if (fs.existsSync(directExecutablePath)) {
|
|
24
|
-
return directExecutablePath;
|
|
25
|
-
}
|
|
26
|
-
const versionedExecutablePath = path.join(frameworkDir, 'Versions', 'Current', frameworkName);
|
|
27
|
-
if (fs.existsSync(versionedExecutablePath)) {
|
|
28
|
-
return versionedExecutablePath;
|
|
29
|
-
}
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
function removeExecutableSignature(executablePath) {
|
|
33
|
-
try {
|
|
34
|
-
execFileSync('codesign', ['--remove-signature', executablePath], {
|
|
35
|
-
stdio: 'pipe',
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
catch (error) {
|
|
39
|
-
if (error instanceof Error &&
|
|
40
|
-
error.message.includes('code object is not signed at all')) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
throw error;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
function normalizeCopiedXcframeworkSignature(xcframeworkPath) {
|
|
47
|
-
removeCodeSignatureArtifacts(xcframeworkPath);
|
|
48
|
-
for (const sliceName of fs.readdirSync(xcframeworkPath)) {
|
|
49
|
-
const slicePath = path.join(xcframeworkPath, sliceName);
|
|
50
|
-
if (!fs.statSync(slicePath).isDirectory()) {
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
for (const entry of fs.readdirSync(slicePath)) {
|
|
54
|
-
if (!entry.endsWith('.framework')) {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
const frameworkName = path.basename(entry, '.framework');
|
|
58
|
-
const frameworkDir = path.join(slicePath, entry);
|
|
59
|
-
const executablePath = resolveFrameworkExecutablePath(frameworkDir, frameworkName);
|
|
60
|
-
if (executablePath) {
|
|
61
|
-
removeExecutableSignature(executablePath);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
5
|
export function prepareLocalSpmArtifacts({ packageDir, targetNames, }) {
|
|
67
6
|
const spmArtifactsDir = path.join(packageDir, SPM_ARTIFACTS_DIR_NAME);
|
|
68
7
|
fs.rmSync(spmArtifactsDir, { recursive: true, force: true });
|
|
@@ -71,7 +10,7 @@ export function prepareLocalSpmArtifacts({ packageDir, targetNames, }) {
|
|
|
71
10
|
const sourcePath = path.join(packageDir, `${targetName}.xcframework`);
|
|
72
11
|
const destinationPath = path.join(spmArtifactsDir, `${targetName}.xcframework`);
|
|
73
12
|
fs.renameSync(sourcePath, destinationPath);
|
|
74
|
-
|
|
13
|
+
normalizeCopiedXcframework(destinationPath);
|
|
75
14
|
}
|
|
76
15
|
return spmArtifactsDir;
|
|
77
16
|
}
|
|
@@ -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;
|
|
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;AAiCtB;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,4BAYxD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE1D;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"}
|
|
@@ -7,16 +7,34 @@ const cliConfig = typeof cliConfigImport === 'function'
|
|
|
7
7
|
? cliConfigImport
|
|
8
8
|
: // @ts-expect-error: interop default
|
|
9
9
|
cliConfigImport.default;
|
|
10
|
+
function hasExpoAppConfig(projectRoot) {
|
|
11
|
+
return (fs.existsSync(path.join(projectRoot, 'app.json')) ||
|
|
12
|
+
fs.existsSync(path.join(projectRoot, 'app.config.js')) ||
|
|
13
|
+
fs.existsSync(path.join(projectRoot, 'app.config.ts')) ||
|
|
14
|
+
fs.existsSync(path.join(projectRoot, 'app.config.mjs')));
|
|
15
|
+
}
|
|
16
|
+
function projectDependsOnExpo(projectRoot) {
|
|
17
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
18
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
22
|
+
return ['dependencies', 'peerDependencies', 'devDependencies'].some((key) => packageJson[key]?.expo);
|
|
23
|
+
}
|
|
10
24
|
/**
|
|
11
25
|
* Gets the Expo config if the project is an Expo project
|
|
12
26
|
* @param projectRoot The project root path
|
|
13
27
|
* @returns The Expo config if the project is an Expo project, null otherwise
|
|
14
28
|
*/
|
|
15
29
|
export function getExpoConfigIfIsExpo(projectRoot) {
|
|
30
|
+
const hasAppConfig = hasExpoAppConfig(projectRoot);
|
|
16
31
|
try {
|
|
17
32
|
return getConfig(projectRoot, { skipSDKVersionRequirement: true });
|
|
18
33
|
}
|
|
19
|
-
catch {
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (hasAppConfig) {
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
20
38
|
return null;
|
|
21
39
|
}
|
|
22
40
|
}
|
|
@@ -27,14 +45,7 @@ export function getExpoConfigIfIsExpo(projectRoot) {
|
|
|
27
45
|
* @returns Whether the project is an Expo project
|
|
28
46
|
*/
|
|
29
47
|
export function isExpoProject(projectRoot) {
|
|
30
|
-
|
|
31
|
-
// additionally, it is needed to check if the project depends on Expo packages explicitly
|
|
32
|
-
// to prevent false positives in a monorepo setup
|
|
33
|
-
const rnProjectRoot = findProjectRoot();
|
|
34
|
-
const packageJsonPath = path.join(rnProjectRoot, 'package.json');
|
|
35
|
-
const dependsOnExpo = fs.existsSync(packageJsonPath) &&
|
|
36
|
-
['dependencies', 'peerDependencies', 'devDependencies'].some((key) => JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))[key]?.expo);
|
|
37
|
-
return hasExpoConfig && dependsOnExpo;
|
|
48
|
+
return hasExpoAppConfig(projectRoot) && projectDependsOnExpo(projectRoot);
|
|
38
49
|
}
|
|
39
50
|
export function getExpoSdkMajor(projectRoot) {
|
|
40
51
|
const rawExpoVersion = getExpoConfigIfIsExpo(projectRoot)?.exp.sdkVersion;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_EXPO = 56;
|
|
2
|
+
export type PrebuiltExpoSupportResult = {
|
|
3
|
+
supported: true;
|
|
4
|
+
enabledByDefault: boolean;
|
|
5
|
+
reason?: never;
|
|
6
|
+
} | {
|
|
7
|
+
supported: false;
|
|
8
|
+
enabledByDefault?: never;
|
|
9
|
+
reason: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function supportsPrebuiltExpo({ projectRoot, }: {
|
|
12
|
+
projectRoot: string;
|
|
13
|
+
}): PrebuiltExpoSupportResult;
|
|
14
|
+
//# sourceMappingURL=supportsPrebuiltExpo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supportsPrebuiltExpo.d.ts","sourceRoot":"","sources":["../../../src/brownfield/utils/supportsPrebuiltExpo.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oCAAoC,KAAK,CAAC;AAEvD,MAAM,MAAM,yBAAyB,GACjC;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,oBAAoB,CAAC,EACnC,WAAW,GACZ,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,yBAAyB,CAqB5B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getExpoSdkMajor, isExpoProject } from './project.js';
|
|
2
|
+
export const MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_EXPO = 56;
|
|
3
|
+
export function supportsPrebuiltExpo({ projectRoot, }) {
|
|
4
|
+
if (!isExpoProject(projectRoot)) {
|
|
5
|
+
return { supported: true, enabledByDefault: false };
|
|
6
|
+
}
|
|
7
|
+
const expoSdkMajor = getExpoSdkMajor(projectRoot);
|
|
8
|
+
if (expoSdkMajor === null ||
|
|
9
|
+
expoSdkMajor < MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_EXPO) {
|
|
10
|
+
const sdkLabel = expoSdkMajor === null ? 'unknown' : String(expoSdkMajor);
|
|
11
|
+
return {
|
|
12
|
+
supported: false,
|
|
13
|
+
reason: `--use-prebuilt-expo is unsupported in Expo SDK ${sdkLabel}: packaging brownfield with Expo prebuilts requires Expo SDK ${MIN_EXPO_SDK_MAJOR_FOR_PREBUILT_EXPO} or newer.`,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
supported: true,
|
|
18
|
+
enabledByDefault: true,
|
|
19
|
+
};
|
|
20
|
+
}
|
package/dist/brownie/config.js
CHANGED
|
@@ -66,7 +66,7 @@ export function resolveBrownieCodegenConfig({ brownie, projectRoot = findProject
|
|
|
66
66
|
const legacyConfig = hasLegacyConfig(projectRoot)
|
|
67
67
|
? loadConfig(projectRoot)
|
|
68
68
|
: undefined;
|
|
69
|
-
const brownfieldBrownie = loadBrownfieldConfig(projectRoot)
|
|
69
|
+
const brownfieldBrownie = loadBrownfieldConfig(projectRoot)?.brownie;
|
|
70
70
|
if (legacyConfig !== undefined && (brownie ?? brownfieldBrownie)) {
|
|
71
71
|
throw new Error(LEGACY_AND_NEW_BROWNIE_CONFIG_ERROR);
|
|
72
72
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { BrownfieldConfig } from './types.js';
|
|
2
|
+
export declare const CONFIG_BASE_NAME = "brownfield";
|
|
3
|
+
export declare const JS_CONFIG_FILE_NAME = "brownfield.config.js";
|
|
4
|
+
export declare const JSON_CONFIG_FILE_NAME = "brownfield.config.json";
|
|
2
5
|
export declare function validateBrownfieldCLIConfig(config: unknown): void;
|
|
3
|
-
export declare function loadBrownfieldConfig(projectRoot?: string): BrownfieldConfig;
|
|
6
|
+
export declare function loadBrownfieldConfig(projectRoot?: string): BrownfieldConfig | null;
|
|
4
7
|
type BrownfieldPlatform = 'android' | 'ios';
|
|
5
8
|
export declare function mergeBrownfieldConfigWithOptions<T extends object>(options: T, platform: BrownfieldPlatform): T;
|
|
6
9
|
export {};
|