@rnx-kit/cli 0.12.5 → 0.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.
Files changed (88) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/README.md +90 -65
  3. package/coverage/clover.xml +216 -225
  4. package/coverage/coverage-final.json +7 -6
  5. package/coverage/lcov-report/index.html +29 -29
  6. package/coverage/lcov-report/src/bundle/index.html +29 -29
  7. package/coverage/lcov-report/src/bundle/kit-config.ts.html +63 -117
  8. package/coverage/lcov-report/src/bundle/metro.ts.html +40 -163
  9. package/coverage/lcov-report/src/bundle/overrides.ts.html +28 -58
  10. package/coverage/lcov-report/src/bundler-plugin-defaults.ts.html +115 -0
  11. package/coverage/lcov-report/src/copy-assets.ts.html +36 -12
  12. package/coverage/lcov-report/src/index.html +35 -20
  13. package/coverage/lcov-report/src/metro-config.ts.html +49 -31
  14. package/coverage/lcov-report/src/typescript/index.html +1 -1
  15. package/coverage/lcov-report/src/typescript/project-cache.ts.html +5 -5
  16. package/coverage/lcov.info +408 -419
  17. package/lib/bundle/kit-config.d.ts +9 -15
  18. package/lib/bundle/kit-config.d.ts.map +1 -1
  19. package/lib/bundle/kit-config.js +29 -43
  20. package/lib/bundle/kit-config.js.map +1 -1
  21. package/lib/bundle/metro.d.ts +7 -11
  22. package/lib/bundle/metro.d.ts.map +1 -1
  23. package/lib/bundle/metro.js +10 -40
  24. package/lib/bundle/metro.js.map +1 -1
  25. package/lib/bundle/overrides.d.ts +11 -9
  26. package/lib/bundle/overrides.d.ts.map +1 -1
  27. package/lib/bundle/overrides.js +10 -18
  28. package/lib/bundle/overrides.js.map +1 -1
  29. package/lib/bundle/types.d.ts +4 -17
  30. package/lib/bundle/types.d.ts.map +1 -1
  31. package/lib/bundle.d.ts +8 -7
  32. package/lib/bundle.d.ts.map +1 -1
  33. package/lib/bundle.js +3 -19
  34. package/lib/bundle.js.map +1 -1
  35. package/lib/bundler-plugin-defaults.d.ts +3 -0
  36. package/lib/bundler-plugin-defaults.d.ts.map +1 -0
  37. package/lib/bundler-plugin-defaults.js +13 -0
  38. package/lib/bundler-plugin-defaults.js.map +1 -0
  39. package/lib/copy-assets.d.ts.map +1 -1
  40. package/lib/copy-assets.js +8 -2
  41. package/lib/copy-assets.js.map +1 -1
  42. package/lib/index.d.ts +1 -1
  43. package/lib/index.d.ts.map +1 -1
  44. package/lib/index.js +2 -1
  45. package/lib/index.js.map +1 -1
  46. package/lib/metro-config.d.ts +3 -2
  47. package/lib/metro-config.d.ts.map +1 -1
  48. package/lib/metro-config.js +7 -5
  49. package/lib/metro-config.js.map +1 -1
  50. package/lib/parsers.d.ts +2 -0
  51. package/lib/parsers.d.ts.map +1 -1
  52. package/lib/parsers.js +16 -1
  53. package/lib/parsers.js.map +1 -1
  54. package/lib/serve/kit-config.d.ts +6 -5
  55. package/lib/serve/kit-config.d.ts.map +1 -1
  56. package/lib/serve/kit-config.js +16 -6
  57. package/lib/serve/kit-config.js.map +1 -1
  58. package/lib/start.d.ts +2 -2
  59. package/lib/start.d.ts.map +1 -1
  60. package/lib/start.js +3 -9
  61. package/lib/start.js.map +1 -1
  62. package/package.json +9 -7
  63. package/react-native.config.js +66 -59
  64. package/src/bundle/kit-config.ts +42 -60
  65. package/src/bundle/metro.ts +15 -56
  66. package/src/bundle/overrides.ts +24 -34
  67. package/src/bundle/types.ts +17 -23
  68. package/src/bundle.ts +18 -36
  69. package/src/bundler-plugin-defaults.ts +10 -0
  70. package/src/copy-assets.ts +10 -2
  71. package/src/index.ts +1 -1
  72. package/src/metro-config.ts +12 -6
  73. package/src/parsers.ts +19 -0
  74. package/src/serve/kit-config.ts +23 -11
  75. package/src/start.ts +7 -13
  76. package/test/__mocks__/child_process.js +1 -1
  77. package/test/bundle/__mocks__/@rnx-kit/config.js +2 -3
  78. package/test/bundle/__mocks__/@rnx-kit/console.js +1 -0
  79. package/test/bundle/__mocks__/@rnx-kit/metro-service.js +1 -0
  80. package/test/bundle/kit-config.test.ts +102 -100
  81. package/test/bundle/metro.test.ts +58 -98
  82. package/test/bundle/overrides.test.ts +29 -25
  83. package/test/copy-assets/assembleAarBundle.test.ts +7 -6
  84. package/lib/types.d.ts +0 -5
  85. package/lib/types.d.ts.map +0 -1
  86. package/lib/types.js +0 -3
  87. package/lib/types.js.map +0 -1
  88. package/src/types.ts +0 -4
@@ -1,115 +1,75 @@
1
- import type { AllPlatforms } from "@rnx-kit/tools-react-native/platform";
2
- import path from "path";
3
- import { createMetroBundleArgs } from "../../src/bundle/metro";
4
- import type { BundleConfig } from "../../src/bundle/types";
1
+ import "jest-extended";
2
+ import { metroBundle } from "../../src/bundle/metro";
3
+ import type { CliPlatformBundleConfig } from "../../src/bundle/types";
5
4
 
6
- describe("CLI > Bundle > Metro > createMetroBundleArgs", () => {
7
- const bundleConfig: BundleConfig = {
8
- detectCyclicDependencies: true,
9
- detectDuplicateDependencies: true,
10
- typescriptValidation: true,
11
- treeShake: true,
12
- entryPath: "out/entry.js",
13
- distPath: "out",
14
- assetsPath: "out/assets",
15
- bundlePrefix: "my-app",
16
- platform: "ios",
17
- dev: true,
18
- minify: true,
19
- sourceMapPath: "abc.map",
20
- sourceMapSourceRootPath: "root-path-for-source-maps",
21
- };
22
-
23
- test("sets assetsDest", () => {
24
- expect(createMetroBundleArgs(bundleConfig).assetsDest).toEqual(
25
- bundleConfig.assetsPath
26
- );
27
- });
28
-
29
- test("sets entryFile", () => {
30
- expect(createMetroBundleArgs(bundleConfig).entryFile).toEqual(
31
- bundleConfig.entryPath
32
- );
33
- });
34
-
35
- test("sets minify", () => {
36
- expect(createMetroBundleArgs(bundleConfig).minify).toEqual(
37
- bundleConfig.minify
38
- );
39
- });
40
-
41
- test("sets platform", () => {
42
- expect(createMetroBundleArgs(bundleConfig).platform).toEqual(
43
- bundleConfig.platform
44
- );
45
- });
46
-
47
- test("sets dev", () => {
48
- expect(createMetroBundleArgs(bundleConfig).dev).toEqual(bundleConfig.dev);
49
- });
50
-
51
- function testBundleFileExtension(
52
- platform: AllPlatforms,
53
- expectedExtension: string
54
- ): void {
55
- const copy: BundleConfig = { ...bundleConfig, platform };
56
- const args = createMetroBundleArgs(copy);
57
- expect(path.extname(args.bundleOutput).toLowerCase()).toEqual(
58
- expectedExtension
59
- );
60
- }
5
+ const { getDefaultConfig } = require("metro-config");
61
6
 
62
- test("sets bundle file extension to .bundle for android", () => {
63
- testBundleFileExtension("android", ".bundle");
64
- });
7
+ const mockCreateDirectory = jest.fn();
8
+ const toolsNodeFS = require("@rnx-kit/tools-node/fs");
9
+ toolsNodeFS.createDirectory = mockCreateDirectory;
65
10
 
66
- test("sets bundle file extension to .jsbundle for ios", () => {
67
- testBundleFileExtension("ios", ".jsbundle");
68
- });
11
+ const metroService = require("@rnx-kit/metro-service");
12
+ const mockBundle = metroService.bundle;
69
13
 
70
- test("sets bundle file extension to .jsbundle for macos", () => {
71
- testBundleFileExtension("macos", ".jsbundle");
14
+ describe("CLI > Bundle > Metro > metroBundle", () => {
15
+ afterEach(() => {
16
+ jest.resetAllMocks();
72
17
  });
73
18
 
74
- test("sets bundle file extension to .bundle for windows", () => {
75
- testBundleFileExtension("windows", ".bundle");
76
- });
19
+ const bundleConfigNoPlugins: CliPlatformBundleConfig = {
20
+ entryFile: "out/entry.js",
21
+ bundleOutput: "src/main.jsbundle",
22
+ detectCyclicDependencies: false,
23
+ detectDuplicateDependencies: false,
24
+ typescriptValidation: false,
25
+ treeShake: false,
26
+ platform: "ios",
27
+ sourcemapOutput: "map/main.map",
28
+ sourcemapSourcesRoot: "root-path-for-source-maps",
29
+ sourcemapUseAbsolutePath: false,
30
+ assetsDest: "dist",
31
+ };
77
32
 
78
- test("sets bundle file extension to .bundle for win32", () => {
79
- testBundleFileExtension("win32", ".bundle");
80
- });
33
+ const bundleConfig: CliPlatformBundleConfig = {
34
+ ...bundleConfigNoPlugins,
35
+ detectCyclicDependencies: true,
36
+ detectDuplicateDependencies: true,
37
+ typescriptValidation: true,
38
+ treeShake: true,
39
+ };
81
40
 
82
- test("sets bundleOutput to prefix + platform + extension under distPath", () => {
83
- expect(createMetroBundleArgs(bundleConfig).bundleOutput).toEqual(
84
- path.join(bundleConfig.distPath, "my-app.ios.jsbundle")
85
- );
86
- });
41
+ const dev = true;
42
+ const minify = true;
87
43
 
88
- test("sets bundleEncoding", () => {
89
- expect(createMetroBundleArgs(bundleConfig).bundleEncoding).toEqual(
90
- bundleConfig.bundleEncoding
91
- );
44
+ it("does not use a custom serializer when all plugins are disabled", async () => {
45
+ const metroConfig = await getDefaultConfig();
46
+ expect(metroConfig.serializer.customSerializer).toBeNil();
47
+ await metroBundle(metroConfig, bundleConfigNoPlugins, dev, minify);
48
+ expect(metroConfig.serializer.customSerializer).toBeNil();
92
49
  });
93
50
 
94
- test("always sets sourcemapOutput in dev mode", () => {
95
- const copy: BundleConfig = { ...bundleConfig, dev: true };
96
- delete copy.sourceMapPath;
97
-
98
- const args = createMetroBundleArgs(copy);
99
- expect(args.sourcemapOutput).toEqual(args.bundleOutput + ".map");
51
+ it("uses a custom serializer when at least one plugin is enabled", async () => {
52
+ const metroConfig = await getDefaultConfig();
53
+ expect(metroConfig.serializer.customSerializer).toBeNil();
54
+ await metroBundle(metroConfig, bundleConfig, dev, minify);
55
+ expect(metroConfig.serializer.customSerializer).not.toBeNil();
100
56
  });
101
57
 
102
- test("sets sourcemapOutput in production mode", () => {
103
- const copy: BundleConfig = { ...bundleConfig, dev: false };
104
- const args = createMetroBundleArgs(copy);
105
- expect(args.sourcemapOutput).toEqual(
106
- path.join(bundleConfig.distPath, bundleConfig.sourceMapPath)
107
- );
58
+ it("creates directories for the bundle, the source map, and assets", async () => {
59
+ await metroBundle(await getDefaultConfig(), bundleConfig, dev, minify);
60
+ expect(mockCreateDirectory).toHaveBeenCalledTimes(3);
61
+ expect(mockCreateDirectory).toHaveBeenNthCalledWith(1, "src");
62
+ expect(mockCreateDirectory).toHaveBeenNthCalledWith(2, "map");
63
+ expect(mockCreateDirectory).toHaveBeenNthCalledWith(3, "dist");
108
64
  });
109
65
 
110
- test("sets sourcemapSourcesRoot", () => {
111
- expect(createMetroBundleArgs(bundleConfig).sourcemapSourcesRoot).toEqual(
112
- bundleConfig.sourceMapSourceRootPath
113
- );
66
+ it("invokes the Metro bundler using all input parameters", async () => {
67
+ await metroBundle(await getDefaultConfig(), bundleConfig, dev, minify);
68
+ expect(mockBundle).toHaveBeenCalledTimes(1);
69
+ expect(mockBundle.mock.calls[0][0]).toEqual({
70
+ ...bundleConfig,
71
+ dev,
72
+ minify,
73
+ });
114
74
  });
115
75
  });
@@ -1,29 +1,33 @@
1
1
  import "jest-extended";
2
- import { applyKitBundleConfigOverrides } from "../../src/bundle/overrides";
3
- import type { KitBundleConfig } from "../../src/bundle/types";
2
+ import { applyBundleConfigOverrides } from "../../src/bundle/overrides";
3
+ import type { CliPlatformBundleConfig } from "../../src/bundle/types";
4
4
 
5
- describe("CLI > Bundle > Overrides > applyKitBundleConfigOverrides", () => {
6
- const config: KitBundleConfig = {
5
+ describe("CLI > Bundle > Overrides > applyBundleConfigOverrides", () => {
6
+ const config: CliPlatformBundleConfig = {
7
+ entryFile: "src/index.js",
8
+ bundleOutput: "main.jsbundle",
9
+ sourcemapUseAbsolutePath: false,
7
10
  detectCyclicDependencies: true,
8
11
  detectDuplicateDependencies: true,
9
12
  typescriptValidation: true,
10
13
  treeShake: true,
11
- entryPath: "dist/index.js",
12
- distPath: "dist",
13
- assetsPath: "dist",
14
- bundlePrefix: "main",
15
14
  platform: "ios",
16
15
  };
17
16
 
18
17
  test("has no effect when no overrides are given", () => {
19
18
  const copy = { ...config };
20
- applyKitBundleConfigOverrides({}, [copy]);
19
+ applyBundleConfigOverrides({}, [copy]);
21
20
  expect(copy).toEqual(config);
22
21
  });
23
22
 
24
23
  function testOverride(name: string, value: unknown) {
25
24
  const copy = { ...config };
26
- applyKitBundleConfigOverrides(
25
+ if (name in copy) {
26
+ if (name !== undefined && name !== null) {
27
+ expect(copy[name]).not.toEqual(value);
28
+ }
29
+ }
30
+ applyBundleConfigOverrides(
27
31
  {
28
32
  [name]: value,
29
33
  },
@@ -35,35 +39,35 @@ describe("CLI > Bundle > Overrides > applyKitBundleConfigOverrides", () => {
35
39
  });
36
40
  }
37
41
 
38
- test("changes entryPath using an override", () => {
39
- testOverride("entryPath", "out/entry.js");
42
+ test("changes entryFile using an override", () => {
43
+ testOverride("entryFile", "foo.js");
40
44
  });
41
45
 
42
- test("changes distPath using an override", () => {
43
- testOverride("distPath", "out");
46
+ test("changes bundleOutput using an override", () => {
47
+ testOverride("bundleOutput", "foo.bundle");
44
48
  });
45
49
 
46
- test("changes assetsPath using an override", () => {
47
- testOverride("assetsPath", "out/assets");
50
+ test("sets bundleEncoding using an override", () => {
51
+ testOverride("bundleEncoding", "utf8");
48
52
  });
49
53
 
50
- test("changes bundlePrefix using an override", () => {
51
- testOverride("bundlePrefix", "main");
54
+ test("sets sourcemapOutput using an override", () => {
55
+ testOverride("sourcemapOutput", "out/foo.map");
52
56
  });
53
57
 
54
- test("changes bundleEncoding using an override", () => {
55
- testOverride("bundleEncoding", "utf8");
58
+ test("sets sourcemapSourcesRoot using an override", () => {
59
+ testOverride("sourcemapSourcesRoot", "/myrepo/packags/foo");
56
60
  });
57
61
 
58
- test("changes sourcemapOutput using an override", () => {
59
- testOverride("sourcemapOutput", "out/entry.map");
62
+ test("changes sourcemapUseAbsolutePath using an override", () => {
63
+ testOverride("sourcemapUseAbsolutePath", true);
60
64
  });
61
65
 
62
- test("changes sourcemapSourcesRoot using an override", () => {
63
- testOverride("sourcemapSourcesRoot", "out");
66
+ test("sets assetsDest using an override", () => {
67
+ testOverride("assetsDest", "dist");
64
68
  });
65
69
 
66
70
  test("changes treeShake using an override", () => {
67
- testOverride("treeShake", true);
71
+ testOverride("treeShake", false);
68
72
  });
69
73
  });
@@ -5,6 +5,7 @@ import { assembleAarBundle } from "../../src/copy-assets";
5
5
 
6
6
  jest.mock("child_process");
7
7
  jest.mock("fs");
8
+ jest.unmock("@rnx-kit/console");
8
9
 
9
10
  export const options = {
10
11
  platform: "android" as const,
@@ -23,11 +24,11 @@ export const context = {
23
24
 
24
25
  describe("assembleAarBundle", () => {
25
26
  const consoleWarnSpy = jest.spyOn(global.console, "warn");
27
+ const spawnSyncSpy = jest.spyOn(require("child_process"), "spawnSync");
26
28
 
27
29
  afterEach(() => {
28
30
  mockFiles();
29
31
  consoleWarnSpy.mockReset();
30
- spawnSync.mockReset();
31
32
  });
32
33
 
33
34
  afterAll(() => {
@@ -48,7 +49,7 @@ describe("assembleAarBundle", () => {
48
49
  expect.anything(),
49
50
  expect.stringMatching(/cannot find `gradlew`$/)
50
51
  );
51
- expect(spawnSync).not.toHaveBeenCalled();
52
+ expect(spawnSyncSpy).not.toHaveBeenCalled();
52
53
  expect(findFiles()).toEqual([]);
53
54
  });
54
55
 
@@ -82,7 +83,7 @@ describe("assembleAarBundle", () => {
82
83
  expect.anything(),
83
84
  expect.stringMatching(/cannot find `build.gradle`/)
84
85
  );
85
- expect(spawnSync).not.toHaveBeenCalled();
86
+ expect(spawnSyncSpy).not.toHaveBeenCalled();
86
87
  expect(findFiles()).toEqual([
87
88
  [expect.stringMatching(/[/\\]gradlew$/), ""],
88
89
  [expect.stringMatching(/[/\\]gradlew.bat$/), ""],
@@ -114,7 +115,7 @@ describe("assembleAarBundle", () => {
114
115
  await assembleAarBundle(context, "@rnx-kit/react-native-auth", { aar: {} });
115
116
 
116
117
  expect(consoleWarnSpy).not.toHaveBeenCalled();
117
- expect(spawnSync).toHaveBeenCalledWith(
118
+ expect(spawnSyncSpy).toHaveBeenCalledWith(
118
119
  expect.stringMatching(/[/\\]gradlew(?:\.bat)?$/),
119
120
  [":rnx-kit_react-native-auth:assembleRelease"],
120
121
  expect.objectContaining({
@@ -200,7 +201,7 @@ describe("assembleAarBundle", () => {
200
201
  await assembleAarBundle(context, "@rnx-kit/react-native-auth", { aar: {} });
201
202
 
202
203
  expect(consoleWarnSpy).not.toHaveBeenCalled();
203
- expect(spawnSync).toHaveBeenCalledWith(
204
+ expect(spawnSyncSpy).toHaveBeenCalledWith(
204
205
  expect.stringMatching(/[/\\]gradlew(?:\.bat)?$/),
205
206
  [":rnx-kit_react-native-auth:assembleRelease"],
206
207
  expect.objectContaining({
@@ -281,7 +282,7 @@ describe("assembleAarBundle", () => {
281
282
  });
282
283
 
283
284
  expect(consoleWarnSpy).not.toHaveBeenCalled();
284
- expect(spawnSync).toHaveBeenCalledWith(
285
+ expect(spawnSyncSpy).toHaveBeenCalledWith(
285
286
  expect.stringMatching(/[/\\]gradlew(?:\.bat)?$/),
286
287
  [":rnx-kit_react-native-auth:assembleRelease"],
287
288
  expect.objectContaining({
package/lib/types.d.ts DELETED
@@ -1,5 +0,0 @@
1
- export declare type TypeScriptValidationOptions = {
2
- print?: (message: string) => void;
3
- throwOnError?: boolean;
4
- };
5
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,oBAAY,2BAA2B,GAAG;IACxC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC"}
package/lib/types.js DELETED
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=types.js.map
package/lib/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/src/types.ts DELETED
@@ -1,4 +0,0 @@
1
- export type TypeScriptValidationOptions = {
2
- print?: (message: string) => void;
3
- throwOnError?: boolean;
4
- };