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.
Files changed (101) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/build/autolinking/findModules.d.ts +11 -5
  3. package/build/autolinking/findModules.js +8 -16
  4. package/build/autolinking/findModules.js.map +1 -1
  5. package/build/autolinking/generatePackageList.d.ts +16 -10
  6. package/build/autolinking/generatePackageList.js +13 -28
  7. package/build/autolinking/generatePackageList.js.map +1 -1
  8. package/build/autolinking/getConfiguration.d.ts +9 -2
  9. package/build/autolinking/getConfiguration.js +9 -4
  10. package/build/autolinking/getConfiguration.js.map +1 -1
  11. package/build/autolinking/index.d.ts +22 -17
  12. package/build/autolinking/index.js +23 -47
  13. package/build/autolinking/index.js.map +1 -1
  14. package/build/autolinking/resolveModules.d.ts +13 -9
  15. package/build/autolinking/resolveModules.js +21 -18
  16. package/build/autolinking/resolveModules.js.map +1 -1
  17. package/build/commands/autolinkingOptions.d.ts +50 -0
  18. package/build/commands/autolinkingOptions.js +168 -0
  19. package/build/commands/autolinkingOptions.js.map +1 -0
  20. package/build/commands/generateModulesProviderCommand.d.ts +3 -0
  21. package/build/commands/generateModulesProviderCommand.js +35 -0
  22. package/build/commands/generateModulesProviderCommand.js.map +1 -0
  23. package/build/commands/generatePackageListCommand.d.ts +6 -0
  24. package/build/commands/generatePackageListCommand.js +39 -0
  25. package/build/commands/generatePackageListCommand.js.map +1 -0
  26. package/build/commands/reactNativeConfigCommand.d.ts +3 -0
  27. package/build/commands/reactNativeConfigCommand.js +36 -0
  28. package/build/commands/reactNativeConfigCommand.js.map +1 -0
  29. package/build/commands/resolveCommand.d.ts +3 -0
  30. package/build/commands/resolveCommand.js +63 -0
  31. package/build/commands/resolveCommand.js.map +1 -0
  32. package/build/commands/searchCommand.d.ts +2 -0
  33. package/build/commands/searchCommand.js +27 -0
  34. package/build/commands/searchCommand.js.map +1 -0
  35. package/build/{autolinking/verifySearchResults.d.ts → commands/verifyCommand.d.ts} +4 -2
  36. package/build/{autolinking/verifySearchResults.js → commands/verifyCommand.js} +24 -3
  37. package/build/commands/verifyCommand.js.map +1 -0
  38. package/build/dependencies/CachedDependenciesLinker.d.ts +2 -1
  39. package/build/dependencies/CachedDependenciesLinker.js +23 -9
  40. package/build/dependencies/CachedDependenciesLinker.js.map +1 -1
  41. package/build/exports.d.ts +17 -1
  42. package/build/exports.js +48 -1
  43. package/build/exports.js.map +1 -1
  44. package/build/index.js +18 -162
  45. package/build/index.js.map +1 -1
  46. package/build/platforms/{android.d.ts → android/android.d.ts} +7 -2
  47. package/build/platforms/{android.js → android/android.js} +1 -5
  48. package/build/platforms/android/android.js.map +1 -0
  49. package/build/platforms/android/index.d.ts +1 -0
  50. package/build/platforms/android/index.js +9 -0
  51. package/build/platforms/android/index.js.map +1 -0
  52. package/build/platforms/{apple.d.ts → apple/apple.d.ts} +6 -6
  53. package/build/platforms/{apple.js → apple/apple.js} +5 -7
  54. package/build/platforms/apple/apple.js.map +1 -0
  55. package/build/platforms/apple/index.d.ts +1 -0
  56. package/build/platforms/apple/index.js +8 -0
  57. package/build/platforms/apple/index.js.map +1 -0
  58. package/build/platforms/index.d.ts +15 -0
  59. package/build/{autolinking/utils.js → platforms/index.js} +6 -1
  60. package/build/platforms/index.js.map +1 -0
  61. package/build/reactNativeConfig/reactNativeConfig.d.ts +11 -2
  62. package/build/reactNativeConfig/reactNativeConfig.js +13 -15
  63. package/build/reactNativeConfig/reactNativeConfig.js.map +1 -1
  64. package/build/reactNativeConfig/reactNativeConfig.types.d.ts +4 -33
  65. package/build/reactNativeConfig/reactNativeConfig.types.js.map +1 -1
  66. package/build/types.d.ts +1 -58
  67. package/build/types.js.map +1 -1
  68. package/package.json +3 -3
  69. package/src/autolinking/findModules.ts +18 -16
  70. package/src/autolinking/generatePackageList.ts +30 -31
  71. package/src/autolinking/getConfiguration.ts +16 -5
  72. package/src/autolinking/index.ts +48 -41
  73. package/src/autolinking/resolveModules.ts +47 -34
  74. package/src/commands/autolinkingOptions.ts +265 -0
  75. package/src/commands/generateModulesProviderCommand.ts +60 -0
  76. package/src/commands/generatePackageListCommand.ts +67 -0
  77. package/src/commands/reactNativeConfigCommand.ts +50 -0
  78. package/src/commands/resolveCommand.ts +101 -0
  79. package/src/commands/searchCommand.ts +35 -0
  80. package/src/{autolinking/verifySearchResults.ts → commands/verifyCommand.ts} +48 -6
  81. package/src/dependencies/CachedDependenciesLinker.ts +30 -12
  82. package/src/exports.ts +65 -0
  83. package/src/index.ts +18 -286
  84. package/src/platforms/{android.ts → android/android.ts} +10 -12
  85. package/src/platforms/android/index.ts +6 -0
  86. package/src/platforms/{apple.ts → apple/apple.ts} +10 -11
  87. package/src/platforms/apple/index.ts +5 -0
  88. package/src/platforms/index.ts +49 -0
  89. package/src/reactNativeConfig/reactNativeConfig.ts +25 -28
  90. package/src/reactNativeConfig/reactNativeConfig.types.ts +4 -35
  91. package/src/types.ts +10 -70
  92. package/build/autolinking/mergeLinkingOptions.d.ts +0 -27
  93. package/build/autolinking/mergeLinkingOptions.js +0 -112
  94. package/build/autolinking/mergeLinkingOptions.js.map +0 -1
  95. package/build/autolinking/utils.d.ts +0 -2
  96. package/build/autolinking/utils.js.map +0 -1
  97. package/build/autolinking/verifySearchResults.js.map +0 -1
  98. package/build/platforms/android.js.map +0 -1
  99. package/build/platforms/apple.js.map +0 -1
  100. package/src/autolinking/mergeLinkingOptions.ts +0 -146
  101. package/src/autolinking/utils.ts +0 -15
@@ -1,51 +1,58 @@
1
- import path from 'path';
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
- export async function resolveSearchPathsAsync(
27
- searchPaths: string[] | null,
28
- cwd: string
29
- ): Promise<string[]> {
30
- return resolveSearchPaths(searchPaths, cwd);
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
- * Programmatic API to query autolinked modules for a project.
35
- */
36
- export async function queryAutolinkingModulesFromProjectAsync(
37
- projectRoot: string,
38
- options: Pick<SearchOptions, 'platform' | 'exclude' | 'onlyProjectDeps'>
39
- ): Promise<ModuleDescriptor[]> {
40
- const searchPaths = await resolveSearchPathsAsync(null, projectRoot);
41
- const linkOptions = await mergeLinkingOptionsAsync({ ...options, projectRoot, searchPaths });
42
- const searchResults = await findModulesAsync(linkOptions);
43
- return await resolveModulesAsync(searchResults, linkOptions);
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
- * Get the project root directory from the current working directory.
48
- */
49
- export function findProjectRootSync(cwd: string = process.cwd()): string {
50
- return path.dirname(getProjectPackageJsonPathSync(cwd));
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 { getLinkingImplementationForPlatform } from './utils';
2
- import type { ExtraDependencies, ModuleDescriptor, ResolveOptions, SearchResults } from '../types';
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
- options: ResolveOptions
13
+ autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform }
10
14
  ): Promise<ModuleDescriptor[]> {
11
- const platformLinking = getLinkingImplementationForPlatform(options.platform);
15
+ const platformLinking = getLinkingImplementationForPlatform(autolinkingOptions.platform);
16
+ // Additional output property for Cocoapods flags
17
+ const extraOutput = { flags: autolinkingOptions.flags };
12
18
 
13
- return (
14
- await Promise.all(
15
- Object.entries(searchResults).map(async ([packageName, revision]) => {
16
- const resolvedModule = await platformLinking.resolveModuleAsync(
17
- packageName,
18
- revision,
19
- options
20
- );
21
- return resolvedModule
22
- ? {
23
- packageName,
24
- packageVersion: revision.version,
25
- ...resolvedModule,
26
- }
27
- : null;
28
- })
29
- )
30
- )
31
- .filter(Boolean)
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
- * Resolves the extra build dependencies for the project, such as additional Maven repositories or CocoaPods pods.
37
- */
38
- export async function resolveExtraBuildDependenciesAsync(
39
- options: ResolveOptions
40
- ): Promise<ExtraDependencies> {
41
- const platformLinking = getLinkingImplementationForPlatform(options.platform);
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
- options.projectRoot
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
+ }