expo-modules-autolinking 3.0.0 → 3.0.2
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/build/autolinking/findModules.d.ts +11 -5
- package/build/autolinking/findModules.js +8 -16
- package/build/autolinking/findModules.js.map +1 -1
- package/build/autolinking/generatePackageList.d.ts +16 -10
- package/build/autolinking/generatePackageList.js +13 -28
- package/build/autolinking/generatePackageList.js.map +1 -1
- package/build/autolinking/getConfiguration.d.ts +9 -2
- package/build/autolinking/getConfiguration.js +9 -4
- package/build/autolinking/getConfiguration.js.map +1 -1
- package/build/autolinking/index.d.ts +22 -17
- package/build/autolinking/index.js +23 -47
- package/build/autolinking/index.js.map +1 -1
- package/build/autolinking/resolveModules.d.ts +13 -9
- package/build/autolinking/resolveModules.js +21 -18
- package/build/autolinking/resolveModules.js.map +1 -1
- package/build/commands/autolinkingOptions.d.ts +50 -0
- package/build/commands/autolinkingOptions.js +168 -0
- package/build/commands/autolinkingOptions.js.map +1 -0
- package/build/commands/generateModulesProviderCommand.d.ts +3 -0
- package/build/commands/generateModulesProviderCommand.js +35 -0
- package/build/commands/generateModulesProviderCommand.js.map +1 -0
- package/build/commands/generatePackageListCommand.d.ts +6 -0
- package/build/commands/generatePackageListCommand.js +39 -0
- package/build/commands/generatePackageListCommand.js.map +1 -0
- package/build/commands/reactNativeConfigCommand.d.ts +3 -0
- package/build/commands/reactNativeConfigCommand.js +36 -0
- package/build/commands/reactNativeConfigCommand.js.map +1 -0
- package/build/commands/resolveCommand.d.ts +3 -0
- package/build/commands/resolveCommand.js +63 -0
- package/build/commands/resolveCommand.js.map +1 -0
- package/build/commands/searchCommand.d.ts +2 -0
- package/build/commands/searchCommand.js +27 -0
- package/build/commands/searchCommand.js.map +1 -0
- package/build/{autolinking/verifySearchResults.d.ts → commands/verifyCommand.d.ts} +4 -2
- package/build/{autolinking/verifySearchResults.js → commands/verifyCommand.js} +24 -3
- package/build/commands/verifyCommand.js.map +1 -0
- package/build/dependencies/CachedDependenciesLinker.d.ts +2 -1
- package/build/dependencies/CachedDependenciesLinker.js +23 -9
- package/build/dependencies/CachedDependenciesLinker.js.map +1 -1
- package/build/exports.d.ts +17 -1
- package/build/exports.js +48 -1
- package/build/exports.js.map +1 -1
- package/build/index.js +18 -162
- package/build/index.js.map +1 -1
- package/build/platforms/{android.d.ts → android/android.d.ts} +7 -2
- package/build/platforms/{android.js → android/android.js} +1 -5
- package/build/platforms/android/android.js.map +1 -0
- package/build/platforms/android/index.d.ts +1 -0
- package/build/platforms/android/index.js +9 -0
- package/build/platforms/android/index.js.map +1 -0
- package/build/platforms/{apple.d.ts → apple/apple.d.ts} +6 -6
- package/build/platforms/{apple.js → apple/apple.js} +5 -7
- package/build/platforms/apple/apple.js.map +1 -0
- package/build/platforms/apple/index.d.ts +1 -0
- package/build/platforms/apple/index.js +8 -0
- package/build/platforms/apple/index.js.map +1 -0
- package/build/platforms/index.d.ts +15 -0
- package/build/{autolinking/utils.js → platforms/index.js} +6 -1
- package/build/platforms/index.js.map +1 -0
- package/build/reactNativeConfig/reactNativeConfig.d.ts +11 -2
- package/build/reactNativeConfig/reactNativeConfig.js +13 -15
- package/build/reactNativeConfig/reactNativeConfig.js.map +1 -1
- package/build/reactNativeConfig/reactNativeConfig.types.d.ts +4 -33
- package/build/reactNativeConfig/reactNativeConfig.types.js.map +1 -1
- package/build/types.d.ts +1 -58
- package/build/types.js.map +1 -1
- package/package.json +3 -3
- package/src/autolinking/findModules.ts +18 -16
- package/src/autolinking/generatePackageList.ts +30 -31
- package/src/autolinking/getConfiguration.ts +16 -5
- package/src/autolinking/index.ts +48 -41
- package/src/autolinking/resolveModules.ts +47 -34
- package/src/commands/autolinkingOptions.ts +265 -0
- package/src/commands/generateModulesProviderCommand.ts +60 -0
- package/src/commands/generatePackageListCommand.ts +67 -0
- package/src/commands/reactNativeConfigCommand.ts +50 -0
- package/src/commands/resolveCommand.ts +101 -0
- package/src/commands/searchCommand.ts +35 -0
- package/src/{autolinking/verifySearchResults.ts → commands/verifyCommand.ts} +48 -6
- package/src/dependencies/CachedDependenciesLinker.ts +30 -12
- package/src/exports.ts +65 -0
- package/src/index.ts +18 -286
- package/src/platforms/{android.ts → android/android.ts} +10 -12
- package/src/platforms/android/index.ts +6 -0
- package/src/platforms/{apple.ts → apple/apple.ts} +10 -11
- package/src/platforms/apple/index.ts +5 -0
- package/src/platforms/index.ts +49 -0
- package/src/reactNativeConfig/reactNativeConfig.ts +25 -28
- package/src/reactNativeConfig/reactNativeConfig.types.ts +4 -35
- package/src/types.ts +10 -70
- package/build/autolinking/mergeLinkingOptions.d.ts +0 -27
- package/build/autolinking/mergeLinkingOptions.js +0 -112
- package/build/autolinking/mergeLinkingOptions.js.map +0 -1
- package/build/autolinking/utils.d.ts +0 -2
- package/build/autolinking/utils.js.map +0 -1
- package/build/autolinking/verifySearchResults.js.map +0 -1
- package/build/platforms/android.js.map +0 -1
- package/build/platforms/apple.js.map +0 -1
- package/src/autolinking/mergeLinkingOptions.ts +0 -146
- package/src/autolinking/utils.ts +0 -15
package/src/autolinking/index.ts
CHANGED
|
@@ -1,51 +1,58 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { AutolinkingOptions, createAutolinkingOptionsLoader } from '../commands/autolinkingOptions';
|
|
2
|
+
import { ExtraDependencies, ModuleDescriptor, SearchResults, SupportedPlatform } from '../types';
|
|
3
3
|
import { findModulesAsync } from './findModules';
|
|
4
|
-
import {
|
|
5
|
-
getProjectPackageJsonPathAsync,
|
|
6
|
-
getProjectPackageJsonPathSync,
|
|
7
|
-
mergeLinkingOptionsAsync,
|
|
8
|
-
resolveSearchPaths,
|
|
9
|
-
} from './mergeLinkingOptions';
|
|
10
4
|
import { resolveExtraBuildDependenciesAsync, resolveModulesAsync } from './resolveModules';
|
|
11
|
-
import type { ModuleDescriptor, SearchOptions } from '../types';
|
|
12
|
-
import { getConfiguration } from './getConfiguration';
|
|
13
5
|
|
|
14
|
-
export {
|
|
15
|
-
findModulesAsync,
|
|
16
|
-
getProjectPackageJsonPathAsync,
|
|
17
|
-
mergeLinkingOptionsAsync,
|
|
18
|
-
resolveExtraBuildDependenciesAsync,
|
|
19
|
-
resolveModulesAsync,
|
|
20
|
-
getConfiguration,
|
|
21
|
-
};
|
|
6
|
+
export { getConfiguration } from './getConfiguration';
|
|
22
7
|
export { generateModulesProviderAsync, generatePackageListAsync } from './generatePackageList';
|
|
23
|
-
export { verifySearchResults } from './verifySearchResults';
|
|
24
|
-
export * from '../types';
|
|
25
8
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
9
|
+
/** @deprecated */
|
|
10
|
+
export interface SearchOptions extends Partial<AutolinkingOptions> {
|
|
11
|
+
projectRoot: string;
|
|
12
|
+
platform: SupportedPlatform;
|
|
13
|
+
[extra: string]: unknown;
|
|
31
14
|
}
|
|
32
15
|
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
return
|
|
16
|
+
/** @deprecated */
|
|
17
|
+
export interface ResolveOptions {
|
|
18
|
+
projectRoot: string;
|
|
19
|
+
platform: SupportedPlatform;
|
|
20
|
+
[extra: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** @deprecated */
|
|
24
|
+
async function apiFindModulesAsync(providedOptions: SearchOptions): Promise<SearchResults> {
|
|
25
|
+
const autolinkingOptionsLoader = createAutolinkingOptionsLoader(providedOptions);
|
|
26
|
+
return findModulesAsync({
|
|
27
|
+
appRoot: await autolinkingOptionsLoader.getAppRoot(),
|
|
28
|
+
autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(providedOptions.platform),
|
|
29
|
+
});
|
|
44
30
|
}
|
|
45
31
|
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return
|
|
32
|
+
/** @deprecated */
|
|
33
|
+
async function apiResolveExtraBuildDependenciesAsync(
|
|
34
|
+
providedOptions: ResolveOptions
|
|
35
|
+
): Promise<ExtraDependencies> {
|
|
36
|
+
return resolveExtraBuildDependenciesAsync({
|
|
37
|
+
commandRoot: providedOptions.projectRoot,
|
|
38
|
+
platform: providedOptions.platform,
|
|
39
|
+
});
|
|
51
40
|
}
|
|
41
|
+
|
|
42
|
+
/** @deprecated */
|
|
43
|
+
async function apiResolveModulesAsync(
|
|
44
|
+
searchResults: SearchResults,
|
|
45
|
+
providedOptions: SearchOptions
|
|
46
|
+
): Promise<ModuleDescriptor[]> {
|
|
47
|
+
const autolinkingOptionsLoader = createAutolinkingOptionsLoader(providedOptions);
|
|
48
|
+
return resolveModulesAsync(
|
|
49
|
+
searchResults,
|
|
50
|
+
await autolinkingOptionsLoader.getPlatformOptions(providedOptions.platform)
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export {
|
|
55
|
+
apiFindModulesAsync as findModulesAsync,
|
|
56
|
+
apiResolveExtraBuildDependenciesAsync as resolveExtraBuildDependenciesAsync,
|
|
57
|
+
apiResolveModulesAsync as resolveModulesAsync,
|
|
58
|
+
};
|
|
@@ -1,46 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { AutolinkingOptions } from '../commands/autolinkingOptions';
|
|
2
|
+
import { getLinkingImplementationForPlatform } from '../platforms';
|
|
3
|
+
import type {
|
|
4
|
+
ExtraDependencies,
|
|
5
|
+
ModuleDescriptor,
|
|
6
|
+
SearchResults,
|
|
7
|
+
SupportedPlatform,
|
|
8
|
+
} from '../types';
|
|
3
9
|
|
|
4
|
-
/**
|
|
5
|
-
* Resolves search results to a list of platform-specific configuration.
|
|
6
|
-
*/
|
|
10
|
+
/** Resolves search results to a list of platform-specific configuration. */
|
|
7
11
|
export async function resolveModulesAsync(
|
|
8
12
|
searchResults: SearchResults,
|
|
9
|
-
|
|
13
|
+
autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform }
|
|
10
14
|
): Promise<ModuleDescriptor[]> {
|
|
11
|
-
const platformLinking = getLinkingImplementationForPlatform(
|
|
15
|
+
const platformLinking = getLinkingImplementationForPlatform(autolinkingOptions.platform);
|
|
16
|
+
// Additional output property for Cocoapods flags
|
|
17
|
+
const extraOutput = { flags: autolinkingOptions.flags };
|
|
12
18
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
.filter(
|
|
19
|
+
const moduleDescriptorList = await Promise.all(
|
|
20
|
+
Object.entries(searchResults).map(async ([packageName, revision]) => {
|
|
21
|
+
const resolvedModule = await platformLinking.resolveModuleAsync(
|
|
22
|
+
packageName,
|
|
23
|
+
revision,
|
|
24
|
+
extraOutput
|
|
25
|
+
);
|
|
26
|
+
return resolvedModule
|
|
27
|
+
? {
|
|
28
|
+
...resolvedModule,
|
|
29
|
+
packageVersion: revision.version,
|
|
30
|
+
packageName: resolvedModule.packageName ?? packageName,
|
|
31
|
+
}
|
|
32
|
+
: null;
|
|
33
|
+
})
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return moduleDescriptorList
|
|
37
|
+
.filter((moduleDescriptor) => moduleDescriptor != null)
|
|
32
38
|
.sort((a, b) => a.packageName.localeCompare(b.packageName));
|
|
33
39
|
}
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
interface ResolveExtraBuildDependenciesParams {
|
|
42
|
+
commandRoot: string;
|
|
43
|
+
platform: SupportedPlatform;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Resolves the extra build dependencies for the project, such as additional Maven repositories or CocoaPods pods. */
|
|
47
|
+
export async function resolveExtraBuildDependenciesAsync({
|
|
48
|
+
commandRoot,
|
|
49
|
+
platform,
|
|
50
|
+
}: ResolveExtraBuildDependenciesParams): Promise<ExtraDependencies> {
|
|
51
|
+
const platformLinking = getLinkingImplementationForPlatform(platform);
|
|
42
52
|
const extraDependencies = await platformLinking.resolveExtraBuildDependenciesAsync(
|
|
43
|
-
|
|
53
|
+
// NOTE: We assume we must be inside the native folder here
|
|
54
|
+
// The `resolve` command either is invoked in the CWD of `./{android,ios}` or has a `--project-root`
|
|
55
|
+
// that's in the native directory
|
|
56
|
+
commandRoot
|
|
44
57
|
);
|
|
45
58
|
return extraDependencies ?? [];
|
|
46
59
|
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import commander from 'commander';
|
|
2
|
+
import findUp from 'find-up';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
|
|
6
|
+
import { SupportedPlatform } from '../types';
|
|
7
|
+
|
|
8
|
+
export interface AutolinkingOptions {
|
|
9
|
+
/** Only scan direct "dependencies" of a project for React Native modules, rather than including transitive dependencies.
|
|
10
|
+
* @remarks
|
|
11
|
+
* Before SDK 54, React Native modules would only be linked if they were listed as dependencies
|
|
12
|
+
* of a project. However, in SDK 54+ transitive React Native modules dependencies are also
|
|
13
|
+
* auto-linked, unless this flag is enabled.
|
|
14
|
+
* @defaultValue `false`
|
|
15
|
+
*/
|
|
16
|
+
legacy_shallowReactNativeLinking: boolean;
|
|
17
|
+
/** Extra modules directories to search for native modules.
|
|
18
|
+
* @defaultValue `[]`
|
|
19
|
+
*/
|
|
20
|
+
searchPaths: string[];
|
|
21
|
+
/** Local native modules directory to add to autolinking.
|
|
22
|
+
* @defaultValue `"./modules"`
|
|
23
|
+
*/
|
|
24
|
+
nativeModulesDir: string | null;
|
|
25
|
+
/** Native modules to exclude from autolinking by name.
|
|
26
|
+
* @defaultValue `[]`
|
|
27
|
+
*/
|
|
28
|
+
exclude: string[];
|
|
29
|
+
/** A list of package names to opt out of prebuilt Expo modules (Android-only)
|
|
30
|
+
* @defaultValue `[]`
|
|
31
|
+
*/
|
|
32
|
+
buildFromSource?: string[];
|
|
33
|
+
/** CocoaPods flags to pass to each autolinked pod (Apple/iOS-only)
|
|
34
|
+
* @defaultValue `[]`
|
|
35
|
+
*/
|
|
36
|
+
flags?: Record<string, any>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const isJSONObject = (x: unknown): x is Record<string, unknown> =>
|
|
40
|
+
x != null && typeof x === 'object';
|
|
41
|
+
|
|
42
|
+
const resolvePathMaybe = (target: unknown, basePath: string): string | null => {
|
|
43
|
+
if (typeof target !== 'string') {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
let resolved = path.resolve(basePath, target);
|
|
47
|
+
if (fs.existsSync(resolved)) {
|
|
48
|
+
return resolved;
|
|
49
|
+
} else if ((resolved = path.resolve(target)) && fs.existsSync(target)) {
|
|
50
|
+
// TODO(@kitten): This is here for legacy support. However, this *will* be inconsistent
|
|
51
|
+
// This relies on the current working directory, and hence, can behave differently depending
|
|
52
|
+
// on where the command was invoked.
|
|
53
|
+
return target;
|
|
54
|
+
} else {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const filterMapSearchPaths = (
|
|
60
|
+
searchPaths: unknown,
|
|
61
|
+
basePath: string
|
|
62
|
+
): string[] | undefined => {
|
|
63
|
+
if (Array.isArray(searchPaths)) {
|
|
64
|
+
return searchPaths
|
|
65
|
+
.map((searchPath) => resolvePathMaybe(searchPath, basePath))
|
|
66
|
+
.filter((searchPath) => searchPath != null);
|
|
67
|
+
} else {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const parsePackageJsonOptions = (
|
|
73
|
+
packageJson: Record<string, unknown>,
|
|
74
|
+
appRoot: string,
|
|
75
|
+
platform: SupportedPlatform | null | undefined
|
|
76
|
+
): Partial<AutolinkingOptions> => {
|
|
77
|
+
const expo = isJSONObject(packageJson.expo) ? packageJson.expo : null;
|
|
78
|
+
const autolinkingOptions = expo && isJSONObject(expo.autolinking) ? expo.autolinking : null;
|
|
79
|
+
let platformOptions: Record<string, unknown> | null = null;
|
|
80
|
+
if (platform) {
|
|
81
|
+
autolinkingOptions && isJSONObject(autolinkingOptions[platform])
|
|
82
|
+
? autolinkingOptions[platform]
|
|
83
|
+
: null;
|
|
84
|
+
if (!platformOptions && platform === 'apple') {
|
|
85
|
+
// NOTE: `platform: 'apple'` has a fallback on `ios`. This doesn't make much sense, since apple should
|
|
86
|
+
// be the base option for other apple platforms, but changing this now is a breaking change
|
|
87
|
+
platformOptions =
|
|
88
|
+
autolinkingOptions && isJSONObject(autolinkingOptions.ios) ? autolinkingOptions.ios : null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const mergedOptions = { ...autolinkingOptions, ...platformOptions };
|
|
92
|
+
const outputOptions: Partial<AutolinkingOptions> = {};
|
|
93
|
+
// legacy_shallowReactNativeLinking
|
|
94
|
+
if (mergedOptions.legacy_shallowReactNativeLinking != null) {
|
|
95
|
+
outputOptions.legacy_shallowReactNativeLinking =
|
|
96
|
+
!!mergedOptions.legacy_shallowReactNativeLinking;
|
|
97
|
+
}
|
|
98
|
+
// searchPaths
|
|
99
|
+
if (typeof mergedOptions.searchPaths === 'string' || Array.isArray(mergedOptions.searchPaths)) {
|
|
100
|
+
const rawSearchPaths =
|
|
101
|
+
typeof mergedOptions.searchPaths === 'string'
|
|
102
|
+
? [mergedOptions.searchPaths]
|
|
103
|
+
: mergedOptions.searchPaths;
|
|
104
|
+
outputOptions.searchPaths = filterMapSearchPaths(rawSearchPaths, appRoot);
|
|
105
|
+
}
|
|
106
|
+
// nativeModulesDir
|
|
107
|
+
if (typeof mergedOptions.nativeModulesDir === 'string') {
|
|
108
|
+
outputOptions.nativeModulesDir = resolvePathMaybe(mergedOptions.nativeModulesDir, appRoot);
|
|
109
|
+
}
|
|
110
|
+
// exclude
|
|
111
|
+
if (Array.isArray(mergedOptions.exclude)) {
|
|
112
|
+
outputOptions.exclude = mergedOptions.exclude.filter((x) => typeof x === 'string');
|
|
113
|
+
}
|
|
114
|
+
// buildFromSource
|
|
115
|
+
if (Array.isArray(mergedOptions.buildFromSource)) {
|
|
116
|
+
outputOptions.buildFromSource = mergedOptions.buildFromSource.filter(
|
|
117
|
+
(x) => typeof x === 'string'
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
// flags
|
|
121
|
+
if (isJSONObject(mergedOptions.flags)) {
|
|
122
|
+
outputOptions.flags = { ...mergedOptions.flags };
|
|
123
|
+
}
|
|
124
|
+
return outputOptions;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/** Common commandline arguments for autolinking commands (Not to be confused with `AutolinkingOptions` */
|
|
128
|
+
export interface AutolinkingCommonArguments {
|
|
129
|
+
projectRoot?: string | null;
|
|
130
|
+
// NOTE(@kitten): These are added to other `searchPaths` entries
|
|
131
|
+
searchPaths?: string[] | null;
|
|
132
|
+
// NOTE(@kitten): These are added to other `exclude` entries
|
|
133
|
+
exclude?: string[] | null;
|
|
134
|
+
platform?: SupportedPlatform | null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function registerAutolinkingArguments(command: commander.Command): commander.Command {
|
|
138
|
+
return command
|
|
139
|
+
.option<string[] | null>(
|
|
140
|
+
'-e, --exclude <exclude...>',
|
|
141
|
+
'Package names to exclude when looking up for modules.',
|
|
142
|
+
(value, previous) => (previous ?? []).concat(value)
|
|
143
|
+
)
|
|
144
|
+
.option(
|
|
145
|
+
'-p, --platform [platform]',
|
|
146
|
+
'The platform that the resulting modules must support. Available options: "apple", "android"',
|
|
147
|
+
'apple'
|
|
148
|
+
)
|
|
149
|
+
.option(
|
|
150
|
+
// NOTE(@kitten): For backwards-compatibility, this is still called `project-root`, but it
|
|
151
|
+
// really is a replacement path for the current working directory. Henceforth called `commandRoot`
|
|
152
|
+
'--project-root <projectRoot>',
|
|
153
|
+
'The path to the root of the project. Defaults to current working directory',
|
|
154
|
+
process.cwd()
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
interface ArgumentsAutolinkingOptions {
|
|
159
|
+
/** The root directory that will be considered the base path for all other target paths */
|
|
160
|
+
commandRoot: string;
|
|
161
|
+
/** The platform to autolink against. If not passed or unknown, no specific autolinking search logic will be applied */
|
|
162
|
+
platform?: SupportedPlatform;
|
|
163
|
+
/** Added search paths to search for native modules (Usually passed as CLI rest argument. */
|
|
164
|
+
extraSearchPaths?: string[];
|
|
165
|
+
/** Added native module names to exclude from autolined native modules (Usually passed as CLI argument) */
|
|
166
|
+
extraExclude?: string[];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const parseExtraArgumentsOptions = (
|
|
170
|
+
args: AutolinkingCommonArguments
|
|
171
|
+
): ArgumentsAutolinkingOptions => {
|
|
172
|
+
const cwd = process.cwd();
|
|
173
|
+
const platform = args.platform || undefined;
|
|
174
|
+
const commandRoot = resolvePathMaybe(args.projectRoot, cwd) || cwd;
|
|
175
|
+
const extraSearchPaths = filterMapSearchPaths(args.searchPaths, commandRoot);
|
|
176
|
+
const extraExclude = args.exclude?.filter((name) => typeof name === 'string');
|
|
177
|
+
return {
|
|
178
|
+
platform,
|
|
179
|
+
commandRoot,
|
|
180
|
+
extraSearchPaths,
|
|
181
|
+
extraExclude,
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const findPackageJsonPathAsync = async (commandRoot: string | null): Promise<string> => {
|
|
186
|
+
const cwd = process.cwd();
|
|
187
|
+
const result = await findUp('package.json', { cwd: commandRoot || cwd });
|
|
188
|
+
if (!result) {
|
|
189
|
+
throw new Error(`Couldn't find "package.json" up from path "${commandRoot || cwd}"`);
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const loadPackageJSONAsync = async (packageJsonPath: string): Promise<Record<string, unknown>> => {
|
|
195
|
+
const packageJsonText = await fs.promises.readFile(packageJsonPath, 'utf8');
|
|
196
|
+
return JSON.parse(packageJsonText);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
export interface LinkingOptionsLoader {
|
|
200
|
+
getCommandRoot(): string;
|
|
201
|
+
getAppRoot(): Promise<string>;
|
|
202
|
+
getPlatformOptions<T extends SupportedPlatform | undefined>(
|
|
203
|
+
platform: T
|
|
204
|
+
): Promise<AutolinkingOptions & { platform: T }>;
|
|
205
|
+
getPlatformOptions(): Promise<AutolinkingOptions>;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function createAutolinkingOptionsLoader(
|
|
209
|
+
argumentsOptions?: AutolinkingCommonArguments
|
|
210
|
+
): LinkingOptionsLoader {
|
|
211
|
+
const extraArgumentsOptions = parseExtraArgumentsOptions(argumentsOptions ?? {});
|
|
212
|
+
const { commandRoot } = extraArgumentsOptions;
|
|
213
|
+
|
|
214
|
+
let _packageJsonPath$: Promise<string> | undefined;
|
|
215
|
+
const getPackageJsonPath = () => {
|
|
216
|
+
return _packageJsonPath$ || (_packageJsonPath$ = findPackageJsonPathAsync(commandRoot));
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
let _packageJson$: Promise<Record<string, unknown>> | undefined;
|
|
220
|
+
const getPackageJson = async () =>
|
|
221
|
+
_packageJson$ || (_packageJson$ = loadPackageJSONAsync(await getPackageJsonPath()));
|
|
222
|
+
|
|
223
|
+
const getAppRoot = async () => path.dirname(await getPackageJsonPath());
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
getCommandRoot: () => commandRoot,
|
|
227
|
+
getAppRoot,
|
|
228
|
+
async getPlatformOptions(platform = extraArgumentsOptions.platform) {
|
|
229
|
+
const packageJson = await getPackageJson();
|
|
230
|
+
const appRoot = await getAppRoot();
|
|
231
|
+
const options = parsePackageJsonOptions(packageJson, appRoot, platform);
|
|
232
|
+
|
|
233
|
+
if (extraArgumentsOptions.extraSearchPaths) {
|
|
234
|
+
options.searchPaths = [
|
|
235
|
+
...extraArgumentsOptions.extraSearchPaths,
|
|
236
|
+
...(options.searchPaths ?? []),
|
|
237
|
+
];
|
|
238
|
+
}
|
|
239
|
+
if (extraArgumentsOptions.extraExclude) {
|
|
240
|
+
options.exclude = [...(options.exclude ?? []), ...extraArgumentsOptions.extraExclude];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
...normalizeAutolinkingOptions(options, appRoot),
|
|
245
|
+
platform,
|
|
246
|
+
};
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const normalizeAutolinkingOptions = (
|
|
252
|
+
options: Partial<AutolinkingOptions>,
|
|
253
|
+
appRoot: string
|
|
254
|
+
): AutolinkingOptions => {
|
|
255
|
+
return {
|
|
256
|
+
legacy_shallowReactNativeLinking: options.legacy_shallowReactNativeLinking ?? false,
|
|
257
|
+
searchPaths: options.searchPaths ?? [],
|
|
258
|
+
nativeModulesDir: options.nativeModulesDir
|
|
259
|
+
? (resolvePathMaybe(options.nativeModulesDir, appRoot) ?? null)
|
|
260
|
+
: (resolvePathMaybe('./modules', appRoot) ?? null),
|
|
261
|
+
exclude: options.exclude ?? [],
|
|
262
|
+
buildFromSource: options.buildFromSource,
|
|
263
|
+
flags: options.flags,
|
|
264
|
+
};
|
|
265
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import commander from 'commander';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AutolinkingCommonArguments,
|
|
5
|
+
createAutolinkingOptionsLoader,
|
|
6
|
+
registerAutolinkingArguments,
|
|
7
|
+
} from './autolinkingOptions';
|
|
8
|
+
import { findModulesAsync } from '../autolinking/findModules';
|
|
9
|
+
import { generateModulesProviderAsync } from '../autolinking/generatePackageList';
|
|
10
|
+
import { resolveModulesAsync } from '../autolinking/resolveModules';
|
|
11
|
+
|
|
12
|
+
interface GenerateModulesProviderArguments extends AutolinkingCommonArguments {
|
|
13
|
+
target: string;
|
|
14
|
+
entitlement?: string;
|
|
15
|
+
packages?: string[] | null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Generates a source file listing all packages to link in the runtime */
|
|
19
|
+
export function generateModulesProviderCommand(cli: commander.CommanderStatic) {
|
|
20
|
+
return registerAutolinkingArguments(cli.command('generate-modules-provider [searchPaths...]'))
|
|
21
|
+
.option(
|
|
22
|
+
'-t, --target <path>',
|
|
23
|
+
'Path to the target file, where the package list should be written to.'
|
|
24
|
+
)
|
|
25
|
+
.option('--entitlement <path>', 'Path to the Apple code signing entitlements file.')
|
|
26
|
+
.option(
|
|
27
|
+
'-p, --packages <packages...>',
|
|
28
|
+
'Names of the packages to include in the generated modules provider.'
|
|
29
|
+
)
|
|
30
|
+
.action(
|
|
31
|
+
async (searchPaths: string[] | null, commandArguments: GenerateModulesProviderArguments) => {
|
|
32
|
+
const platform = commandArguments.platform ?? 'apple';
|
|
33
|
+
const autolinkingOptionsLoader = createAutolinkingOptionsLoader({
|
|
34
|
+
...commandArguments,
|
|
35
|
+
searchPaths,
|
|
36
|
+
});
|
|
37
|
+
const autolinkingOptions = await autolinkingOptionsLoader.getPlatformOptions(platform);
|
|
38
|
+
|
|
39
|
+
const expoModulesSearchResults = await findModulesAsync({
|
|
40
|
+
autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(platform),
|
|
41
|
+
appRoot: await autolinkingOptionsLoader.getAppRoot(),
|
|
42
|
+
});
|
|
43
|
+
const expoModulesResolveResults = await resolveModulesAsync(
|
|
44
|
+
expoModulesSearchResults,
|
|
45
|
+
autolinkingOptions
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const includeModules = new Set(commandArguments.packages ?? []);
|
|
49
|
+
const filteredModules = expoModulesResolveResults.filter((module) =>
|
|
50
|
+
includeModules.has(module.packageName)
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
await generateModulesProviderAsync(filteredModules, {
|
|
54
|
+
platform,
|
|
55
|
+
targetPath: commandArguments.target,
|
|
56
|
+
entitlementPath: commandArguments.entitlement ?? null,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import commander from 'commander';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AutolinkingCommonArguments,
|
|
5
|
+
createAutolinkingOptionsLoader,
|
|
6
|
+
registerAutolinkingArguments,
|
|
7
|
+
} from './autolinkingOptions';
|
|
8
|
+
import { findModulesAsync } from '../autolinking/findModules';
|
|
9
|
+
import { generatePackageListAsync } from '../autolinking/generatePackageList';
|
|
10
|
+
import { resolveModulesAsync } from '../autolinking/resolveModules';
|
|
11
|
+
import type { ModuleDescriptor } from '../types';
|
|
12
|
+
|
|
13
|
+
interface GeneratePackageListArguments extends AutolinkingCommonArguments {
|
|
14
|
+
target: string;
|
|
15
|
+
namespace: string;
|
|
16
|
+
empty: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Generates a source file listing all packages to link.
|
|
20
|
+
* @privateRemarks
|
|
21
|
+
* This command is deprecated for apple platforms, use `generate-modules-provider` instead.
|
|
22
|
+
*/
|
|
23
|
+
export function generatePackageListCommand(cli: commander.CommanderStatic) {
|
|
24
|
+
return registerAutolinkingArguments(cli.command('generate-package-list [searchPaths...]'))
|
|
25
|
+
.option(
|
|
26
|
+
'-t, --target <path>',
|
|
27
|
+
'Path to the target file, where the package list should be written to.'
|
|
28
|
+
)
|
|
29
|
+
.option(
|
|
30
|
+
'-n, --namespace <namespace>',
|
|
31
|
+
'Java package name under which the package list should be placed.'
|
|
32
|
+
)
|
|
33
|
+
.option(
|
|
34
|
+
'--empty',
|
|
35
|
+
'Whether to only generate an empty list. Might be used when the user opts-out of autolinking.',
|
|
36
|
+
false
|
|
37
|
+
)
|
|
38
|
+
.action(
|
|
39
|
+
async (searchPaths: string[] | null, commandArguments: GeneratePackageListArguments) => {
|
|
40
|
+
const platform = commandArguments.platform ?? 'android';
|
|
41
|
+
const autolinkingOptionsLoader = createAutolinkingOptionsLoader({
|
|
42
|
+
...commandArguments,
|
|
43
|
+
searchPaths,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
let expoModulesResolveResults: ModuleDescriptor[] = [];
|
|
47
|
+
if (!commandArguments.empty) {
|
|
48
|
+
const autolinkingOptions = await autolinkingOptionsLoader.getPlatformOptions(platform);
|
|
49
|
+
|
|
50
|
+
const expoModulesSearchResults = await findModulesAsync({
|
|
51
|
+
autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(platform),
|
|
52
|
+
appRoot: await autolinkingOptionsLoader.getAppRoot(),
|
|
53
|
+
});
|
|
54
|
+
expoModulesResolveResults = await resolveModulesAsync(
|
|
55
|
+
expoModulesSearchResults,
|
|
56
|
+
autolinkingOptions
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
await generatePackageListAsync(expoModulesResolveResults, {
|
|
61
|
+
platform,
|
|
62
|
+
targetPath: commandArguments.target,
|
|
63
|
+
namespace: commandArguments.namespace,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import commander from 'commander';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AutolinkingCommonArguments,
|
|
5
|
+
createAutolinkingOptionsLoader,
|
|
6
|
+
registerAutolinkingArguments,
|
|
7
|
+
} from './autolinkingOptions';
|
|
8
|
+
import { createReactNativeConfigAsync } from '../reactNativeConfig';
|
|
9
|
+
|
|
10
|
+
interface ReactNativeConfigArguments extends AutolinkingCommonArguments {
|
|
11
|
+
sourceDir?: string | null;
|
|
12
|
+
json?: boolean | null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** The react-native-config command (like RN CLI linking) */
|
|
16
|
+
export function reactNativeConfigCommand(cli: commander.CommanderStatic) {
|
|
17
|
+
return registerAutolinkingArguments(cli.command('react-native-config [searchPaths...]'))
|
|
18
|
+
.option(
|
|
19
|
+
'-p, --platform [platform]',
|
|
20
|
+
'The platform that the resulting modules must support. Available options: "android", "ios"',
|
|
21
|
+
'ios'
|
|
22
|
+
)
|
|
23
|
+
.option('--source-dir <sourceDir>', 'The path to the native source directory')
|
|
24
|
+
.option('-j, --json', 'Output results in the plain JSON format.', () => true, false)
|
|
25
|
+
.action(async (searchPaths: string[] | null, commandArguments: ReactNativeConfigArguments) => {
|
|
26
|
+
// TODO(@kitten): Do we need to restrict this?
|
|
27
|
+
const platform = commandArguments.platform ?? 'ios';
|
|
28
|
+
if (platform !== 'android' && platform !== 'ios') {
|
|
29
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const autolinkingOptionsLoader = createAutolinkingOptionsLoader({
|
|
33
|
+
...commandArguments,
|
|
34
|
+
searchPaths,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const reactNativeConfig = await createReactNativeConfigAsync({
|
|
38
|
+
autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(platform),
|
|
39
|
+
appRoot: await autolinkingOptionsLoader.getAppRoot(),
|
|
40
|
+
// NOTE(@kitten): This is currently not validated, and assumed to be validated later
|
|
41
|
+
sourceDir: commandArguments.sourceDir ?? undefined,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
if (commandArguments.json) {
|
|
45
|
+
console.log(JSON.stringify(reactNativeConfig));
|
|
46
|
+
} else {
|
|
47
|
+
console.log(require('util').inspect(reactNativeConfig, false, null, true));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|