@rnx-kit/cli 0.16.28 → 0.16.30

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 (61) hide show
  1. package/lib/align-deps.d.ts +1 -1
  2. package/lib/align-deps.js +8 -9
  3. package/lib/bundle/cliOptions.d.ts +2 -2
  4. package/lib/bundle/cliOptions.js +27 -27
  5. package/lib/bundle/defaultPlugins.js +1 -2
  6. package/lib/bundle/hermes.d.ts +2 -1
  7. package/lib/bundle/hermes.js +5 -12
  8. package/lib/bundle/kit-config.js +2 -3
  9. package/lib/bundle/metro.js +6 -10
  10. package/lib/bundle/overrides.js +2 -2
  11. package/lib/bundle.d.ts +3 -3
  12. package/lib/bundle.js +6 -6
  13. package/lib/clean.d.ts +2 -2
  14. package/lib/clean.js +44 -64
  15. package/lib/copy-assets.js +6 -6
  16. package/lib/helpers/externals.d.ts +4 -0
  17. package/lib/{serve/external.js → helpers/externals.js} +11 -10
  18. package/lib/helpers/filesystem.d.ts +3 -0
  19. package/lib/helpers/filesystem.js +31 -0
  20. package/lib/{metro-config.js → helpers/metro-config.js} +2 -3
  21. package/lib/{parsers.d.ts → helpers/parsers.d.ts} +1 -1
  22. package/lib/{parsers.js → helpers/parsers.js} +20 -19
  23. package/lib/index.d.ts +15 -16
  24. package/lib/index.js +1 -5
  25. package/lib/ram-bundle.d.ts +4 -4
  26. package/lib/ram-bundle.js +4 -4
  27. package/lib/serve/help.js +1 -2
  28. package/lib/serve/keyboard.js +1 -2
  29. package/lib/serve/kit-config.js +1 -2
  30. package/lib/serve/types.d.ts +0 -2
  31. package/lib/start.d.ts +1 -1
  32. package/lib/start.js +35 -35
  33. package/lib/test.d.ts +2 -1
  34. package/lib/test.js +4 -4
  35. package/lib/write-third-party-notices.js +15 -15
  36. package/package.json +6 -8
  37. package/lib/serve/external.d.ts +0 -7
  38. package/src/align-deps.ts +0 -83
  39. package/src/bundle/cliOptions.ts +0 -82
  40. package/src/bundle/defaultPlugins.ts +0 -16
  41. package/src/bundle/hermes.ts +0 -114
  42. package/src/bundle/kit-config.ts +0 -81
  43. package/src/bundle/metro.ts +0 -66
  44. package/src/bundle/overrides.ts +0 -51
  45. package/src/bundle/types.ts +0 -41
  46. package/src/bundle.ts +0 -69
  47. package/src/clean.ts +0 -223
  48. package/src/copy-assets.ts +0 -545
  49. package/src/index.ts +0 -34
  50. package/src/metro-config.ts +0 -208
  51. package/src/parsers.ts +0 -44
  52. package/src/ram-bundle.ts +0 -78
  53. package/src/serve/external.ts +0 -62
  54. package/src/serve/help.ts +0 -59
  55. package/src/serve/keyboard.ts +0 -76
  56. package/src/serve/kit-config.ts +0 -47
  57. package/src/serve/types.ts +0 -87
  58. package/src/start.ts +0 -316
  59. package/src/test.ts +0 -137
  60. package/src/write-third-party-notices.ts +0 -85
  61. /package/lib/{metro-config.d.ts → helpers/metro-config.d.ts} +0 -0
@@ -1,545 +0,0 @@
1
- import type { Config as CLIConfig } from "@react-native-community/cli-types";
2
- import { error, info, warn } from "@rnx-kit/console";
3
- import { keysOf } from "@rnx-kit/tools-language/properties";
4
- import type { PackageManifest } from "@rnx-kit/tools-node/package";
5
- import {
6
- findPackageDependencyDir,
7
- findPackageDir,
8
- readPackage,
9
- } from "@rnx-kit/tools-node/package";
10
- import { findUp } from "@rnx-kit/tools-node/path";
11
- import type { AllPlatforms } from "@rnx-kit/tools-react-native";
12
- import { parsePlatform } from "@rnx-kit/tools-react-native";
13
- import type { SpawnSyncOptions } from "child_process";
14
- import { spawnSync } from "child_process";
15
- import * as fs from "fs-extra";
16
- import * as os from "os";
17
- import * as path from "path";
18
-
19
- export type AndroidArchive = {
20
- targetName?: string;
21
- version?: string;
22
- output?: string;
23
- android?: {
24
- androidPluginVersion?: string;
25
- compileSdkVersion?: number;
26
- defaultConfig?: {
27
- minSdkVersion?: number;
28
- targetSdkVersion?: number;
29
- };
30
- kotlinVersion?: string;
31
- };
32
- };
33
-
34
- export type NativeAssets = {
35
- assets?: string[];
36
- strings?: string[];
37
- aar?: AndroidArchive & {
38
- env?: Record<string, string | number>;
39
- dependencies?: Record<string, AndroidArchive>;
40
- };
41
- xcassets?: string[];
42
- };
43
-
44
- export type Options = {
45
- platform: AllPlatforms;
46
- assetsDest: string;
47
- bundleAar: boolean;
48
- xcassetsDest?: string;
49
- [key: string]: unknown;
50
- };
51
-
52
- export type Context = {
53
- projectRoot: string;
54
- manifest: PackageManifest;
55
- options: Options;
56
- };
57
-
58
- export type AssetsConfig = {
59
- getAssets?: (context: Context) => Promise<NativeAssets>;
60
- };
61
-
62
- const defaultAndroidConfig: Required<Required<AndroidArchive>["android"]> = {
63
- androidPluginVersion: "7.2.2",
64
- compileSdkVersion: 33,
65
- defaultConfig: {
66
- minSdkVersion: 23,
67
- targetSdkVersion: 29,
68
- },
69
- kotlinVersion: "1.7.22",
70
- };
71
-
72
- function ensureOption(options: Options, opt: string, flag = opt) {
73
- if (options[opt] == null) {
74
- error(`Missing required option: --${flag}`);
75
- process.exit(1);
76
- }
77
- }
78
-
79
- function findGradleProject(projectRoot: string): string | undefined {
80
- if (fs.existsSync(path.join(projectRoot, "android", "build.gradle"))) {
81
- return path.join(projectRoot, "android");
82
- }
83
- if (fs.existsSync(path.join(projectRoot, "build.gradle"))) {
84
- return projectRoot;
85
- }
86
- return undefined;
87
- }
88
-
89
- function gradleTargetName(packageName: string): string {
90
- return (
91
- packageName.startsWith("@") ? packageName.slice(1) : packageName
92
- ).replace(/[^\w\-.]+/g, "_");
93
- }
94
-
95
- function isAssetsConfig(config: unknown): config is AssetsConfig {
96
- return typeof config === "object" && config !== null && "getAssets" in config;
97
- }
98
-
99
- export function versionOf(pkgName: string): string {
100
- const packageDir = findPackageDependencyDir(pkgName);
101
- if (!packageDir) {
102
- throw new Error(`Could not find module '${pkgName}'`);
103
- }
104
-
105
- const { version } = readPackage(packageDir);
106
- return version;
107
- }
108
-
109
- function getAndroidPaths(
110
- context: Context,
111
- packageName: string,
112
- { targetName, version, output }: AndroidArchive
113
- ) {
114
- const projectRoot = findPackageDependencyDir(packageName);
115
- if (!projectRoot) {
116
- throw new Error(`Could not find module '${packageName}'`);
117
- }
118
-
119
- const gradleFriendlyName = targetName || gradleTargetName(packageName);
120
- const aarVersion = version || versionOf(packageName);
121
-
122
- switch (packageName) {
123
- case "hermes-engine":
124
- return {
125
- targetName: gradleFriendlyName,
126
- version: aarVersion,
127
- projectRoot,
128
- output: path.join(projectRoot, "android", "hermes-release.aar"),
129
- destination: path.join(
130
- context.options.assetsDest,
131
- "aar",
132
- `hermes-release-${versionOf(packageName)}.aar`
133
- ),
134
- };
135
-
136
- case "react-native":
137
- return {
138
- targetName: gradleFriendlyName,
139
- version: aarVersion,
140
- projectRoot,
141
- output: path.join(projectRoot, "android"),
142
- destination: path.join(
143
- context.options.assetsDest,
144
- "aar",
145
- "react-native"
146
- ),
147
- };
148
-
149
- default: {
150
- const androidProject = findGradleProject(projectRoot);
151
- return {
152
- targetName: gradleFriendlyName,
153
- version: aarVersion,
154
- projectRoot,
155
- androidProject,
156
- output:
157
- output ||
158
- (androidProject &&
159
- path.join(
160
- androidProject,
161
- "build",
162
- "outputs",
163
- "aar",
164
- `${gradleFriendlyName}-release.aar`
165
- )),
166
- destination: path.join(
167
- context.options.assetsDest,
168
- "aar",
169
- `${gradleFriendlyName}-${aarVersion}.aar`
170
- ),
171
- };
172
- }
173
- }
174
- }
175
-
176
- function run(command: string, args: string[], options: SpawnSyncOptions) {
177
- const { status } = spawnSync(command, args, options);
178
- if (status !== 0) {
179
- process.exit(status || 1);
180
- }
181
- }
182
-
183
- export async function assembleAarBundle(
184
- context: Context,
185
- packageName: string,
186
- { aar }: NativeAssets
187
- ): Promise<void> {
188
- if (!aar) {
189
- return;
190
- }
191
-
192
- const wrapper = os.platform() === "win32" ? "gradlew.bat" : "gradlew";
193
- const gradlew = findUp(wrapper);
194
- if (!gradlew) {
195
- warn(`Skipped \`${packageName}\`: cannot find \`${wrapper}\``);
196
- return;
197
- }
198
-
199
- const { targetName, version, androidProject, output } = getAndroidPaths(
200
- context,
201
- packageName,
202
- aar
203
- );
204
- if (!androidProject || !output) {
205
- warn(`Skipped \`${packageName}\`: cannot find \`build.gradle\``);
206
- return;
207
- }
208
-
209
- const { env: customEnv, dependencies, android } = aar;
210
- const env = {
211
- NODE_MODULES_PATH: path.join(process.cwd(), "node_modules"),
212
- REACT_NATIVE_VERSION: versionOf("react-native"),
213
- ...process.env,
214
- ...customEnv,
215
- };
216
-
217
- const outputDir = path.join(context.options.assetsDest, "aar");
218
- fs.ensureDirSync(outputDir);
219
-
220
- const dest = path.join(outputDir, `${targetName}-${version}.aar`);
221
-
222
- const targets = [`:${targetName}:assembleRelease`];
223
- const targetsToCopy: [string, string][] = [[output, dest]];
224
-
225
- const settings = path.join(androidProject, "settings.gradle");
226
- if (fs.existsSync(settings)) {
227
- if (dependencies) {
228
- for (const [dependencyName, aar] of Object.entries(dependencies)) {
229
- const { targetName, output, destination } = getAndroidPaths(
230
- context,
231
- dependencyName,
232
- aar
233
- );
234
- if (output) {
235
- if (!fs.existsSync(output)) {
236
- targets.push(`:${targetName}:assembleRelease`);
237
- targetsToCopy.push([output, destination]);
238
- } else if (!fs.existsSync(destination)) {
239
- targetsToCopy.push([output, destination]);
240
- }
241
- }
242
- }
243
- }
244
-
245
- // Run only one Gradle task at a time
246
- run(gradlew, targets, { cwd: androidProject, stdio: "inherit", env });
247
- } else {
248
- const reactNativePath = findPackageDependencyDir("react-native");
249
- if (!reactNativePath) {
250
- throw new Error("Could not find 'react-native'");
251
- }
252
-
253
- const buildDir = path.join(
254
- process.cwd(),
255
- "node_modules",
256
- ".rnx-gradle-build",
257
- targetName
258
- );
259
-
260
- const compileSdkVersion =
261
- android?.compileSdkVersion ?? defaultAndroidConfig.compileSdkVersion;
262
- const minSdkVersion =
263
- android?.defaultConfig?.minSdkVersion ??
264
- defaultAndroidConfig.defaultConfig.minSdkVersion;
265
- const targetSdkVersion =
266
- android?.defaultConfig?.targetSdkVersion ??
267
- defaultAndroidConfig.defaultConfig.targetSdkVersion;
268
- const androidPluginVersion =
269
- android?.androidPluginVersion ??
270
- defaultAndroidConfig.androidPluginVersion;
271
- const kotlinVersion =
272
- android?.kotlinVersion ?? defaultAndroidConfig.kotlinVersion;
273
- const buildRelativeReactNativePath = path.relative(
274
- buildDir,
275
- reactNativePath
276
- );
277
-
278
- const buildGradle = [
279
- "buildscript {",
280
- " ext {",
281
- ` compileSdkVersion = ${compileSdkVersion}`,
282
- ` minSdkVersion = ${minSdkVersion}`,
283
- ` targetSdkVersion = ${targetSdkVersion}`,
284
- ` androidPluginVersion = "${androidPluginVersion}"`,
285
- ` kotlinVersion = "${kotlinVersion}"`,
286
- " }",
287
- "",
288
- " repositories {",
289
- " mavenCentral()",
290
- " google()",
291
- " }",
292
- "",
293
- " dependencies {",
294
- ' classpath("com.android.tools.build:gradle:${project.ext.androidPluginVersion}")',
295
- ' classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.ext.kotlinVersion}")',
296
- " }",
297
- "}",
298
- "",
299
- "allprojects {",
300
- " repositories {",
301
- " maven {",
302
- " // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm",
303
- ` url("\${rootDir}/${buildRelativeReactNativePath}/android")`,
304
- " }",
305
- " mavenCentral()",
306
- " google()",
307
- " }",
308
- "}",
309
- "",
310
- ].join("\n");
311
-
312
- const gradleProperties = "android.useAndroidX=true\n";
313
-
314
- const settingsGradle = [
315
- `include(":${targetName}")`,
316
- `project(":${targetName}").projectDir = file(${JSON.stringify(
317
- androidProject
318
- )})`,
319
- "",
320
- ].join("\n");
321
-
322
- fs.ensureDirSync(buildDir);
323
- fs.writeFileSync(path.join(buildDir, "build.gradle"), buildGradle);
324
- fs.writeFileSync(
325
- path.join(buildDir, "gradle.properties"),
326
- gradleProperties
327
- );
328
- fs.writeFileSync(path.join(buildDir, "settings.gradle"), settingsGradle);
329
-
330
- // Run only one Gradle task at a time
331
- run(gradlew, targets, { cwd: buildDir, stdio: "inherit", env });
332
- }
333
-
334
- await Promise.all(targetsToCopy.map(([src, dest]) => fs.copy(src, dest)));
335
- }
336
-
337
- function copyFiles(files: unknown, destination: string): Promise<void>[] {
338
- if (!Array.isArray(files) || files.length === 0) {
339
- return [];
340
- }
341
-
342
- fs.ensureDirSync(destination);
343
- return files.map((file) => {
344
- return fs.copy(file, `${destination}/${path.basename(file)}`);
345
- });
346
- }
347
-
348
- export async function copyAssets(
349
- { options: { assetsDest, xcassetsDest } }: Context,
350
- packageName: string,
351
- { assets, strings, xcassets }: NativeAssets
352
- ): Promise<void> {
353
- const tasks = [
354
- ...copyFiles(assets, `${assetsDest}/assets/${packageName}`),
355
- ...copyFiles(strings, `${assetsDest}/strings/${packageName}`),
356
- ];
357
-
358
- if (typeof xcassetsDest === "string") {
359
- tasks.push(...copyFiles(xcassets, xcassetsDest));
360
- }
361
-
362
- await Promise.all(tasks);
363
- }
364
-
365
- export async function gatherConfigs({
366
- projectRoot,
367
- manifest,
368
- }: Context): Promise<Record<string, AssetsConfig | null> | undefined> {
369
- const { dependencies, devDependencies } = manifest;
370
- const packages = [...keysOf(dependencies), ...keysOf(devDependencies)];
371
- if (packages.length === 0) {
372
- return;
373
- }
374
-
375
- const resolveOptions = { paths: [projectRoot] };
376
- const assetsConfigs: Record<string, AssetsConfig | null> = {};
377
-
378
- for (const pkg of packages) {
379
- try {
380
- const pkgPath = path.dirname(
381
- require.resolve(`${pkg}/package.json`, resolveOptions)
382
- );
383
- const reactNativeConfig = `${pkgPath}/react-native.config.js`;
384
- if (fs.existsSync(reactNativeConfig)) {
385
- const { nativeAssets } = require(reactNativeConfig);
386
- if (nativeAssets) {
387
- assetsConfigs[pkg] = nativeAssets;
388
- }
389
- }
390
- } catch (err) {
391
- warn(err);
392
- }
393
- }
394
-
395
- // Overrides from project config
396
- const reactNativeConfig = `${projectRoot}/react-native.config.js`;
397
- if (fs.existsSync(reactNativeConfig)) {
398
- const { nativeAssets } = require(reactNativeConfig);
399
- const overrides = Object.entries(nativeAssets);
400
- for (const [pkgName, config] of overrides) {
401
- if (config === null || isAssetsConfig(config)) {
402
- assetsConfigs[pkgName] = config;
403
- }
404
- }
405
- }
406
-
407
- return assetsConfigs;
408
- }
409
-
410
- /**
411
- * Copies additional assets not picked by bundlers into desired directory.
412
- *
413
- * The way this works is by scanning all direct dependencies of the current
414
- * project for a file, `react-native.config.js`, whose contents include a
415
- * field, `nativeAssets`, and a function that returns assets to copy:
416
- *
417
- * ```js
418
- * // react-native.config.js
419
- * module.exports = {
420
- * nativeAssets: {
421
- * getAssets: (context) => {
422
- * return {
423
- * assets: [],
424
- * strings: [],
425
- * xcassets: [],
426
- * };
427
- * }
428
- * }
429
- * };
430
- * ```
431
- *
432
- * We also allow the project itself to override this where applicable. The
433
- * format is similar and looks like this:
434
- *
435
- * ```js
436
- * // react-native.config.js
437
- * module.exports = {
438
- * nativeAssets: {
439
- * "some-library": {
440
- * getAssets: (context) => {
441
- * return {
442
- * assets: [],
443
- * strings: [],
444
- * xcassets: [],
445
- * };
446
- * }
447
- * },
448
- * "another-library": {
449
- * getAssets: (context) => {
450
- * return {
451
- * assets: [],
452
- * strings: [],
453
- * xcassets: [],
454
- * };
455
- * }
456
- * }
457
- * }
458
- * };
459
- * ```
460
- *
461
- * @param options Options dictate what gets copied where
462
- */
463
- export async function copyProjectAssets(options: Options): Promise<void> {
464
- const projectRoot = findPackageDir() || process.cwd();
465
- const manifest = readPackage(projectRoot);
466
- const context = { projectRoot, manifest, options };
467
- const assetConfigs = await gatherConfigs(context);
468
- if (!assetConfigs) {
469
- return;
470
- }
471
-
472
- const dependencies = Object.entries(assetConfigs);
473
- for (const [packageName, config] of dependencies) {
474
- if (!isAssetsConfig(config)) {
475
- continue;
476
- }
477
-
478
- const { getAssets } = config;
479
- if (typeof getAssets !== "function") {
480
- warn(`Skipped \`${packageName}\`: getAssets is not a function`);
481
- continue;
482
- }
483
-
484
- const assets = await getAssets(context);
485
- if (options.bundleAar && assets.aar) {
486
- info(`Assembling "${packageName}"`);
487
- await assembleAarBundle(context, packageName, assets);
488
- } else {
489
- info(`Copying assets for "${packageName}"`);
490
- await copyAssets(context, packageName, assets);
491
- }
492
- }
493
-
494
- if (options.bundleAar) {
495
- const dummyAar = { targetName: "dummy" };
496
- const copyTasks = [];
497
- for (const dependencyName of ["hermes-engine", "react-native"]) {
498
- const { output, destination } = getAndroidPaths(
499
- context,
500
- dependencyName,
501
- dummyAar
502
- );
503
- if (
504
- output &&
505
- (!fs.existsSync(destination) || fs.statSync(destination).isDirectory())
506
- ) {
507
- info(`Copying Android Archive of "${dependencyName}"`);
508
- copyTasks.push(fs.copy(output, destination));
509
- }
510
- }
511
- await Promise.all(copyTasks);
512
- }
513
- }
514
-
515
- export const rnxCopyAssetsCommand = {
516
- name: "rnx-copy-assets",
517
- description:
518
- "Copies additional assets not picked by bundlers into desired directory.",
519
- func: (_argv: string[], _config: CLIConfig, options: Options) => {
520
- ensureOption(options, "platform");
521
- ensureOption(options, "assetsDest", "assets-dest");
522
- return copyProjectAssets(options);
523
- },
524
- options: [
525
- {
526
- name: "--platform <string>",
527
- description: "platform to target",
528
- parse: parsePlatform,
529
- },
530
- {
531
- name: "--assets-dest <string>",
532
- description: "path of the directory to copy assets into",
533
- },
534
- {
535
- name: "--bundle-aar <boolean>",
536
- description: "whether to bundle AARs of dependencies",
537
- default: false,
538
- },
539
- {
540
- name: "--xcassets-dest <string>",
541
- description:
542
- "path of the directory to copy Xcode asset catalogs into. Asset catalogs will only be copied if a destination path is specified.",
543
- },
544
- ],
545
- };
package/src/index.ts DELETED
@@ -1,34 +0,0 @@
1
- import { rnxAlignDepsCommand } from "./align-deps";
2
- import { rnxBundleCommand } from "./bundle";
3
- import { rnxCleanCommand } from "./clean";
4
- import { rnxCopyAssetsCommand } from "./copy-assets";
5
- import { rnxRamBundleCommand } from "./ram-bundle";
6
- import { rnxStartCommand } from "./start";
7
- import { rnxTestCommand } from "./test";
8
- import { rnxWriteThirdPartyNoticesCommand } from "./write-third-party-notices";
9
-
10
- export const reactNativeConfig = {
11
- commands: [
12
- rnxBundleCommand,
13
- rnxRamBundleCommand,
14
- rnxStartCommand,
15
- rnxCopyAssetsCommand,
16
- rnxAlignDepsCommand,
17
- rnxTestCommand,
18
- rnxWriteThirdPartyNoticesCommand,
19
- rnxCleanCommand,
20
- ],
21
- };
22
-
23
- export { rnxAlignDeps, rnxAlignDepsCommand } from "./align-deps";
24
- export { rnxBundle, rnxBundleCommand } from "./bundle";
25
- export { rnxClean, rnxCleanCommand } from "./clean";
26
- export { copyProjectAssets, rnxCopyAssetsCommand } from "./copy-assets";
27
- export { asBoolean, asNumber, parseTransformProfile } from "./parsers";
28
- export { rnxRamBundle, rnxRamBundleCommand } from "./ram-bundle";
29
- export { rnxStart, rnxStartCommand } from "./start";
30
- export { rnxTest, rnxTestCommand } from "./test";
31
- export {
32
- rnxWriteThirdPartyNotices,
33
- rnxWriteThirdPartyNoticesCommand,
34
- } from "./write-third-party-notices";