metro 0.76.0 → 0.76.1

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 (94) hide show
  1. package/package.json +24 -24
  2. package/src/Asset.d.ts +25 -0
  3. package/src/Bundler.d.ts +39 -0
  4. package/src/DeltaBundler/Graph.d.ts +40 -0
  5. package/src/DeltaBundler/Serializers/getRamBundleInfo.d.ts +18 -0
  6. package/src/DeltaBundler/Transformer.js +1 -2
  7. package/src/DeltaBundler/Transformer.js.flow +1 -2
  8. package/src/DeltaBundler/Worker.d.ts +47 -0
  9. package/src/DeltaBundler/types.d.ts +167 -0
  10. package/src/DeltaBundler.d.ts +58 -0
  11. package/src/HmrServer.js +1 -5
  12. package/src/HmrServer.js.flow +0 -5
  13. package/src/IncrementalBundler.d.ts +97 -0
  14. package/src/IncrementalBundler.js +1 -0
  15. package/src/IncrementalBundler.js.flow +1 -0
  16. package/src/ModuleGraph/worker/collectDependencies.d.ts +27 -0
  17. package/src/ModuleGraph/worker/collectDependencies.js +42 -25
  18. package/src/ModuleGraph/worker/collectDependencies.js.flow +41 -36
  19. package/src/Server/MultipartResponse.d.ts +31 -0
  20. package/src/Server.d.ts +113 -0
  21. package/src/Server.js +11 -133
  22. package/src/Server.js.flow +12 -154
  23. package/src/cli/parseKeyValueParamArray.js +34 -0
  24. package/src/cli/parseKeyValueParamArray.js.flow +31 -0
  25. package/src/cli-utils.js.flow +2 -6
  26. package/src/cli.js +2 -0
  27. package/src/cli.js.flow +1 -0
  28. package/src/commands/build.js +34 -7
  29. package/src/commands/build.js.flow +50 -8
  30. package/src/commands/dependencies.js +11 -9
  31. package/src/commands/dependencies.js.flow +128 -0
  32. package/src/commands/serve.js +11 -4
  33. package/src/commands/serve.js.flow +26 -6
  34. package/src/index.d.ts +151 -0
  35. package/src/index.flow.js +8 -2
  36. package/src/index.flow.js.flow +18 -6
  37. package/src/lib/CountingSet.d.ts +48 -0
  38. package/src/lib/TerminalReporter.d.ts +27 -0
  39. package/src/lib/TerminalReporter.js +1 -4
  40. package/src/lib/TerminalReporter.js.flow +1 -5
  41. package/src/lib/contextModule.d.ts +22 -0
  42. package/src/lib/getGraphId.d.ts +11 -0
  43. package/src/lib/getGraphId.js +0 -1
  44. package/src/lib/getGraphId.js.flow +0 -1
  45. package/src/lib/getPrependedScripts.js +0 -9
  46. package/src/lib/getPrependedScripts.js.flow +0 -9
  47. package/src/lib/parseOptionsFromUrl.js +1 -16
  48. package/src/lib/parseOptionsFromUrl.js.flow +0 -17
  49. package/src/lib/reporting.d.ts +140 -0
  50. package/src/lib/reporting.js.flow +0 -1
  51. package/src/lib/splitBundleOptions.js +0 -1
  52. package/src/lib/splitBundleOptions.js.flow +0 -1
  53. package/src/lib/transformHelpers.js +0 -1
  54. package/src/lib/transformHelpers.js.flow +0 -1
  55. package/src/node-haste/DependencyGraph/createHasteMap.js +0 -1
  56. package/src/node-haste/DependencyGraph/createHasteMap.js.flow +0 -1
  57. package/src/node-haste/DependencyGraph.d.ts +59 -0
  58. package/src/node-haste/DependencyGraph.js +1 -0
  59. package/src/node-haste/DependencyGraph.js.flow +1 -0
  60. package/src/shared/output/RamBundle/as-assets.js +1 -0
  61. package/src/shared/output/RamBundle/as-assets.js.flow +1 -0
  62. package/src/shared/output/RamBundle/write-sourcemap.js +1 -0
  63. package/src/shared/output/RamBundle/write-sourcemap.js.flow +1 -0
  64. package/src/shared/output/bundle.d.ts +31 -0
  65. package/src/shared/types.d.ts +138 -0
  66. package/src/shared/types.flow.js.flow +2 -1
  67. package/types/Asset.d.ts +25 -0
  68. package/types/Bundler.d.ts +39 -0
  69. package/types/DeltaBundler/Graph.d.ts +40 -0
  70. package/types/DeltaBundler/Serializers/getRamBundleInfo.d.ts +18 -0
  71. package/types/DeltaBundler/Worker.d.ts +47 -0
  72. package/types/DeltaBundler/types.d.ts +167 -0
  73. package/types/DeltaBundler.d.ts +58 -0
  74. package/types/IncrementalBundler.d.ts +97 -0
  75. package/types/ModuleGraph/worker/collectDependencies.d.ts +27 -0
  76. package/types/Server/MultipartResponse.d.ts +31 -0
  77. package/types/Server.d.ts +113 -0
  78. package/types/index.d.ts +151 -0
  79. package/types/lib/CountingSet.d.ts +48 -0
  80. package/types/lib/TerminalReporter.d.ts +27 -0
  81. package/types/lib/contextModule.d.ts +22 -0
  82. package/types/lib/getGraphId.d.ts +11 -0
  83. package/types/lib/reporting.d.ts +140 -0
  84. package/types/node-haste/DependencyGraph.d.ts +59 -0
  85. package/types/shared/output/bundle.d.ts +31 -0
  86. package/types/shared/types.d.ts +138 -0
  87. package/src/DeltaBundler/Serializers/baseBytecodeBundle.js +0 -81
  88. package/src/DeltaBundler/Serializers/baseBytecodeBundle.js.flow +0 -103
  89. package/src/DeltaBundler/Serializers/helpers/bytecode.js +0 -61
  90. package/src/DeltaBundler/Serializers/helpers/bytecode.js.flow +0 -75
  91. package/src/DeltaBundler/Serializers/helpers/processBytecodeModules.js +0 -40
  92. package/src/DeltaBundler/Serializers/helpers/processBytecodeModules.js.flow +0 -51
  93. package/src/lib/bundleToBytecode.js +0 -79
  94. package/src/lib/bundleToBytecode.js.flow +0 -97
@@ -43,7 +43,6 @@ import type {CustomResolverOptions} from 'metro-resolver/src/types';
43
43
  import type {CustomTransformOptions} from 'metro-transform-worker';
44
44
 
45
45
  const {getAsset} = require('./Assets');
46
- const baseBytecodeBundle = require('./DeltaBundler/Serializers/baseBytecodeBundle');
47
46
  const baseJSBundle = require('./DeltaBundler/Serializers/baseJSBundle');
48
47
  const getAllFiles = require('./DeltaBundler/Serializers/getAllFiles');
49
48
  const getAssets = require('./DeltaBundler/Serializers/getAssets');
@@ -54,7 +53,6 @@ const getRamBundleInfo = require('./DeltaBundler/Serializers/getRamBundleInfo');
54
53
  const sourceMapString = require('./DeltaBundler/Serializers/sourceMapString');
55
54
  const IncrementalBundler = require('./IncrementalBundler');
56
55
  const ResourceNotFoundError = require('./IncrementalBundler/ResourceNotFoundError');
57
- const bundleToBytecode = require('./lib/bundleToBytecode');
58
56
  const bundleToString = require('./lib/bundleToString');
59
57
  const formatBundlingError = require('./lib/formatBundlingError');
60
58
  const getGraphId = require('./lib/getGraphId');
@@ -128,10 +126,6 @@ export type ServerOptions = $ReadOnly<{
128
126
  const DELTA_ID_HEADER = 'X-Metro-Delta-ID';
129
127
  const FILES_CHANGED_COUNT_HEADER = 'X-Metro-Files-Changed-Count';
130
128
 
131
- function getBytecodeVersion() {
132
- return require('metro-hermes-compiler').VERSION;
133
- }
134
-
135
129
  class Server {
136
130
  _bundler: IncrementalBundler;
137
131
  _config: ConfigT;
@@ -349,7 +343,7 @@ class Server {
349
343
  +dev: boolean,
350
344
  +entryFile: string,
351
345
  +minify: boolean,
352
- +platform: string,
346
+ +platform: ?string,
353
347
  ...
354
348
  }): Promise<Array<string>> {
355
349
  const {
@@ -402,12 +396,13 @@ class Server {
402
396
  'Accept-Ranges': 'bytes',
403
397
  'Content-Length': chunksize.toString(),
404
398
  'Content-Range': `bytes ${dataStart}-${dataEnd}/${data.length}`,
405
- 'Content-Type': mime.lookup(path.basename(assetPath)),
406
399
  });
407
400
 
408
401
  return data.slice(dataStart, dataEnd + 1);
409
402
  }
410
403
 
404
+ res.setHeader('Content-Length', String(Buffer.byteLength(data)));
405
+
411
406
  return data;
412
407
  }
413
408
 
@@ -456,6 +451,7 @@ class Server {
456
451
  if (process.env.REACT_NATIVE_ENABLE_ASSET_CACHING === true) {
457
452
  res.setHeader('Cache-Control', 'max-age=31536000');
458
453
  }
454
+ res.setHeader('Content-Type', mime.lookup(path.basename(assetPath)));
459
455
  res.end(this._rangeRequestMiddleware(req, res, data, assetPath));
460
456
  process.nextTick(() => {
461
457
  log(createActionEndEntry(processingAssetRequestLogEntry));
@@ -480,11 +476,7 @@ class Server {
480
476
  };
481
477
 
482
478
  _parseOptions(url: string): BundleOptions {
483
- return parseOptionsFromUrl(
484
- url,
485
- new Set(this._config.resolver.platforms),
486
- getBytecodeVersion(),
487
- );
479
+ return parseOptionsFromUrl(url, new Set(this._config.resolver.platforms));
488
480
  }
489
481
 
490
482
  async _processRequest(
@@ -510,20 +502,13 @@ class Server {
510
502
  const buildNumber = this.getNewBuildNumber();
511
503
  if (pathname.endsWith('.bundle')) {
512
504
  const options = this._parseOptions(formattedUrl);
513
- if (options.runtimeBytecodeVersion) {
514
- await this._processBytecodeBundleRequest(req, res, options, {
515
- buildNumber,
516
- bundlePerfLogger: noopLogger,
517
- });
518
- } else {
519
- await this._processBundleRequest(req, res, options, {
520
- buildNumber,
521
- bundlePerfLogger:
522
- this._config.unstable_perfLoggerFactory?.('BUNDLING_REQUEST', {
523
- key: buildNumber,
524
- }) ?? noopLogger,
525
- });
526
- }
505
+ await this._processBundleRequest(req, res, options, {
506
+ buildNumber,
507
+ bundlePerfLogger:
508
+ this._config.unstable_perfLoggerFactory?.('BUNDLING_REQUEST', {
509
+ key: buildNumber,
510
+ }) ?? noopLogger,
511
+ });
527
512
 
528
513
  if (this._serverOptions && this._serverOptions.onBundleBuilt) {
529
514
  this._serverOptions.onBundleBuilt(pathname);
@@ -697,7 +682,6 @@ class Server {
697
682
  entryFile: resolvedEntryFilePath,
698
683
  minify: transformOptions.minify,
699
684
  platform: transformOptions.platform,
700
- runtimeBytecodeVersion: transformOptions.runtimeBytecodeVersion,
701
685
  },
702
686
  isPrefetch: req.method === 'HEAD',
703
687
  type: 'bundle_build_started',
@@ -937,129 +921,6 @@ class Server {
937
921
  },
938
922
  });
939
923
 
940
- _processBytecodeBundleRequest: (
941
- req: IncomingMessage,
942
- res: ServerResponse,
943
- bundleOptions: BundleOptions,
944
- buildContext: $ReadOnly<{
945
- buildNumber: number,
946
- bundlePerfLogger: RootPerfLogger,
947
- }>,
948
- ) => Promise<void> = this._createRequestProcessor({
949
- createStartEntry(context: ProcessStartContext) {
950
- return {
951
- action_name: 'Requesting bundle',
952
- bundle_url: context.req.url,
953
- entry_point: context.entryFile,
954
- bundler: 'delta',
955
- build_id: getBuildID(context.buildNumber),
956
- bundle_options: context.bundleOptions,
957
- bundle_hash: context.graphId,
958
- };
959
- },
960
- createEndEntry(
961
- context: ProcessEndContext<{
962
- bytecode: Buffer,
963
- lastModifiedDate: Date,
964
- nextRevId: RevisionId,
965
- numModifiedFiles: number,
966
- }>,
967
- ) {
968
- return {
969
- outdated_modules: context.result.numModifiedFiles,
970
- };
971
- },
972
- build: async ({
973
- entryFile,
974
- graphId,
975
- graphOptions,
976
- onProgress,
977
- resolverOptions,
978
- serializerOptions,
979
- transformOptions,
980
- }) => {
981
- const revPromise = this._bundler.getRevisionByGraphId(graphId);
982
-
983
- const {delta, revision} = await (revPromise != null
984
- ? this._bundler.updateGraph(await revPromise, false)
985
- : this._bundler.initializeGraph(
986
- entryFile,
987
- transformOptions,
988
- resolverOptions,
989
- {
990
- onProgress,
991
- shallow: graphOptions.shallow,
992
- },
993
- ));
994
-
995
- const bundle = bundleToBytecode(
996
- baseBytecodeBundle(entryFile, revision.prepend, revision.graph, {
997
- asyncRequireModulePath: await this._resolveRelativePath(
998
- this._config.transformer.asyncRequireModulePath,
999
- {
1000
- relativeTo: 'project',
1001
- resolverOptions,
1002
- transformOptions,
1003
- },
1004
- ),
1005
- processModuleFilter: this._config.serializer.processModuleFilter,
1006
- createModuleId: this._createModuleId,
1007
- getRunModuleStatement: this._config.serializer.getRunModuleStatement,
1008
- includeAsyncPaths:
1009
- this._config.server.experimentalImportBundleSupport,
1010
- dev: transformOptions.dev,
1011
- projectRoot: this._config.projectRoot,
1012
- modulesOnly: serializerOptions.modulesOnly,
1013
- runBeforeMainModule:
1014
- this._config.serializer.getModulesRunBeforeMainModule(
1015
- path.relative(this._config.projectRoot, entryFile),
1016
- ),
1017
- runModule: serializerOptions.runModule,
1018
- sourceMapUrl: serializerOptions.sourceMapUrl,
1019
- sourceUrl: serializerOptions.sourceUrl,
1020
- inlineSourceMap: serializerOptions.inlineSourceMap,
1021
- serverRoot:
1022
- this._config.server.unstable_serverRoot ?? this._config.projectRoot,
1023
- }),
1024
- );
1025
-
1026
- return {
1027
- numModifiedFiles: delta.reset
1028
- ? delta.added.size + revision.prepend.length
1029
- : delta.added.size + delta.modified.size + delta.deleted.size,
1030
- lastModifiedDate: revision.date,
1031
- nextRevId: revision.id,
1032
- bytecode: bundle.bytecode,
1033
- };
1034
- },
1035
- finish({req, mres, result}) {
1036
- if (
1037
- // We avoid parsing the dates since the client should never send a more
1038
- // recent date than the one returned by the Delta Bundler (if that's the
1039
- // case it's fine to return the whole bundle).
1040
- req.headers['if-modified-since'] ===
1041
- result.lastModifiedDate.toUTCString()
1042
- ) {
1043
- debug('Responding with 304');
1044
- mres.writeHead(304);
1045
- mres.end();
1046
- } else {
1047
- mres.setHeader(
1048
- FILES_CHANGED_COUNT_HEADER,
1049
- String(result.numModifiedFiles),
1050
- );
1051
- mres.setHeader(DELTA_ID_HEADER, String(result.nextRevId));
1052
- mres.setHeader('Content-Type', 'application/x-metro-bytecode-bundle');
1053
- mres.setHeader('Last-Modified', result.lastModifiedDate.toUTCString());
1054
- mres.setHeader(
1055
- 'Content-Length',
1056
- String(Buffer.byteLength(result.bytecode)),
1057
- );
1058
- mres.end(result.bytecode);
1059
- }
1060
- },
1061
- });
1062
-
1063
924
  // This function ensures that modules in source maps are sorted in the same
1064
925
  // order as in a plain JS bundle.
1065
926
  _getSortedModules(graph: ReadOnlyGraph<>): $ReadOnlyArray<Module<>> {
@@ -1292,7 +1153,6 @@ class Server {
1292
1153
  const options = parseOptionsFromUrl(
1293
1154
  reqUrl,
1294
1155
  new Set(this._config.resolver.platforms),
1295
- getBytecodeVersion(),
1296
1156
  );
1297
1157
 
1298
1158
  const {
@@ -1390,7 +1250,6 @@ class Server {
1390
1250
  dev: boolean,
1391
1251
  hot: boolean,
1392
1252
  minify: boolean,
1393
- runtimeBytecodeVersion: ?number,
1394
1253
  unstable_transformProfile: 'default',
1395
1254
  }> = {
1396
1255
  customResolverOptions: Object.create(null),
@@ -1398,7 +1257,6 @@ class Server {
1398
1257
  dev: true,
1399
1258
  hot: false,
1400
1259
  minify: false,
1401
- runtimeBytecodeVersion: null,
1402
1260
  unstable_transformProfile: 'default',
1403
1261
  };
1404
1262
 
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true,
5
+ });
6
+ exports.default = coerceKeyValueArray;
7
+ var _querystring = _interopRequireDefault(require("querystring"));
8
+ function _interopRequireDefault(obj) {
9
+ return obj && obj.__esModule ? obj : { default: obj };
10
+ }
11
+ /**
12
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
13
+ *
14
+ * This source code is licensed under the MIT license found in the
15
+ * LICENSE file in the root directory of this source tree.
16
+ *
17
+ *
18
+ * @format
19
+ * @oncall react_native
20
+ */
21
+
22
+ function coerceKeyValueArray(keyValueArray) {
23
+ const result = Object.create(null);
24
+ for (const item of keyValueArray) {
25
+ if (item.indexOf("=") === -1) {
26
+ throw new Error('Expected parameter to include "=" but found: ' + item);
27
+ }
28
+ if (item.indexOf("&") !== -1) {
29
+ throw new Error('Parameter cannot include "&" but found: ' + item);
30
+ }
31
+ Object.assign(result, _querystring.default.parse(item));
32
+ }
33
+ return result;
34
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict-local
8
+ * @format
9
+ * @oncall react_native
10
+ */
11
+
12
+ import querystring from 'querystring';
13
+
14
+ export default function coerceKeyValueArray(
15
+ keyValueArray: $ReadOnlyArray<string>,
16
+ ): {
17
+ [key: string]: string,
18
+ __proto__: null,
19
+ } {
20
+ const result: {[key: string]: string, __proto__: null} = Object.create(null);
21
+ for (const item of keyValueArray) {
22
+ if (item.indexOf('=') === -1) {
23
+ throw new Error('Expected parameter to include "=" but found: ' + item);
24
+ }
25
+ if (item.indexOf('&') !== -1) {
26
+ throw new Error('Parameter cannot include "&" but found: ' + item);
27
+ }
28
+ Object.assign(result, querystring.parse(item));
29
+ }
30
+ return result;
31
+ }
@@ -11,8 +11,6 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- import type {YargArguments} from 'metro-config/src/configTypes.flow';
15
-
16
14
  const fs = require('fs');
17
15
 
18
16
  exports.watchFile = async function (
@@ -27,10 +25,8 @@ exports.watchFile = async function (
27
25
  };
28
26
 
29
27
  exports.makeAsyncCommand =
30
- (
31
- command: (argv: YargArguments) => Promise<void>,
32
- ): ((argv: YargArguments) => void) =>
33
- (argv: YargArguments) => {
28
+ <T>(command: (argv: T) => Promise<void>): ((argv: T) => void) =>
29
+ (argv: T) => {
34
30
  Promise.resolve(command(argv)).catch(error => {
35
31
  console.error(error.stack);
36
32
  process.exitCode = 1;
package/src/cli.js CHANGED
@@ -17,4 +17,6 @@ try {
17
17
  } catch {}
18
18
  const { attachMetroCli } = require("./index");
19
19
  const yargs = require("yargs");
20
+
21
+ // $FlowFixMe[unused-promise]
20
22
  attachMetroCli(yargs.demandCommand(1)).argv;
package/src/cli.js.flow CHANGED
@@ -20,4 +20,5 @@ try {
20
20
  const {attachMetroCli} = require('./index');
21
21
  const yargs = require('yargs');
22
22
 
23
+ // $FlowFixMe[unused-promise]
23
24
  attachMetroCli(yargs.demandCommand(1)).argv;
@@ -1,3 +1,11 @@
1
+ "use strict";
2
+
3
+ var _parseKeyValueParamArray = _interopRequireDefault(
4
+ require("../cli/parseKeyValueParamArray")
5
+ );
6
+ function _interopRequireDefault(obj) {
7
+ return obj && obj.__esModule ? obj : { default: obj };
8
+ }
1
9
  /**
2
10
  * Copyright (c) Meta Platforms, Inc. and affiliates.
3
11
  *
@@ -9,8 +17,6 @@
9
17
  * @oncall react_native
10
18
  */
11
19
 
12
- "use strict";
13
-
14
20
  const { makeAsyncCommand } = require("../cli-utils");
15
21
  const TerminalReporter = require("../lib/TerminalReporter");
16
22
  const { loadConfig } = require("metro-config");
@@ -64,6 +70,21 @@ module.exports = () => ({
64
70
  alias: "c",
65
71
  type: "string",
66
72
  });
73
+ yargs.option("transform-option", {
74
+ type: "string",
75
+ array: true,
76
+ alias: "transformer-option",
77
+ coerce: _parseKeyValueParamArray.default,
78
+ describe:
79
+ "Custom transform options of the form key=value. URL-encoded. May be specified multiple times.",
80
+ });
81
+ yargs.option("resolver-option", {
82
+ type: "string",
83
+ array: true,
84
+ coerce: _parseKeyValueParamArray.default,
85
+ describe:
86
+ "Custom resolver options of the form key=value. URL-encoded. May be specified multiple times.",
87
+ });
67
88
 
68
89
  // Deprecated
69
90
  yargs.option("reset-cache", {
@@ -72,8 +93,17 @@ module.exports = () => ({
72
93
  },
73
94
  handler: makeAsyncCommand(async (argv) => {
74
95
  const config = await loadConfig(argv);
75
- // $FlowExpectedError YargArguments and RunBuildOptions are used interchangeable but their types are not yet compatible
76
- const options = argv;
96
+ const options = {
97
+ entry: argv.entry,
98
+ dev: argv.dev,
99
+ out: argv.out,
100
+ minify: argv.minify,
101
+ platform: argv.platform,
102
+ sourceMap: argv.sourceMap,
103
+ sourceMapUrl: argv.sourceMapUrl,
104
+ customResolverOptions: argv.resolverOption,
105
+ customTransformOptions: argv.transformOption,
106
+ };
77
107
 
78
108
  // Inline require() to avoid circular dependency with ../index
79
109
  const MetroApi = require("../index");
@@ -89,9 +119,6 @@ module.exports = () => ({
89
119
  entryFile: options.entry,
90
120
  minify: !!options.minify,
91
121
  platform: options.platform,
92
- // Bytecode bundles in Metro are not meant for production use. Instead,
93
- // the Hermes Bytecode Compiler should be invoked on the resulting JS bundle from Metro.
94
- runtimeBytecodeVersion: null,
95
122
  },
96
123
  });
97
124
  },
@@ -9,10 +9,11 @@
9
9
  * @oncall react_native
10
10
  */
11
11
 
12
- 'use strict';
12
+ import parseKeyValueParamArray from '../cli/parseKeyValueParamArray';
13
13
 
14
+ import type {CustomTransformOptions} from 'metro-babel-transformer';
15
+ import type {CustomResolverOptions} from 'metro-resolver';
14
16
  import type {RunBuildOptions} from '../index';
15
- import type {YargArguments} from 'metro-config/src/configTypes.flow';
16
17
  import typeof Yargs from 'yargs';
17
18
  import type {ModuleObject} from 'yargs';
18
19
 
@@ -24,6 +25,24 @@ const {Terminal} = require('metro-core');
24
25
  const term = new Terminal(process.stdout);
25
26
  const updateReporter = new TerminalReporter(term);
26
27
 
28
+ type Args = $ReadOnly<{
29
+ config?: string,
30
+ dev?: boolean,
31
+ entry: string,
32
+ legacyBundler?: boolean,
33
+ maxWorkers?: number,
34
+ minify?: boolean,
35
+ out: string,
36
+ outputType?: string,
37
+ platform?: string,
38
+ projectRoots?: $ReadOnlyArray<string>,
39
+ resetCache?: boolean,
40
+ sourceMap?: boolean,
41
+ sourceMapUrl?: string,
42
+ transformOption: CustomTransformOptions,
43
+ resolverOption: CustomResolverOptions,
44
+ }>;
45
+
27
46
  module.exports = (): {
28
47
  ...ModuleObject,
29
48
  handler: Function,
@@ -54,14 +73,40 @@ module.exports = (): {
54
73
 
55
74
  yargs.option('config', {alias: 'c', type: 'string'});
56
75
 
76
+ yargs.option('transform-option', {
77
+ type: 'string',
78
+ array: true,
79
+ alias: 'transformer-option',
80
+ coerce: (parseKeyValueParamArray: $FlowFixMe),
81
+ describe:
82
+ 'Custom transform options of the form key=value. URL-encoded. May be specified multiple times.',
83
+ });
84
+
85
+ yargs.option('resolver-option', {
86
+ type: 'string',
87
+ array: true,
88
+ coerce: (parseKeyValueParamArray: $FlowFixMe),
89
+ describe:
90
+ 'Custom resolver options of the form key=value. URL-encoded. May be specified multiple times.',
91
+ });
92
+
57
93
  // Deprecated
58
94
  yargs.option('reset-cache', {type: 'boolean'});
59
95
  },
60
96
 
61
- handler: makeAsyncCommand(async (argv: YargArguments) => {
97
+ handler: makeAsyncCommand(async (argv: Args) => {
62
98
  const config = await loadConfig(argv);
63
- // $FlowExpectedError YargArguments and RunBuildOptions are used interchangeable but their types are not yet compatible
64
- const options = (argv: RunBuildOptions);
99
+ const options: RunBuildOptions = {
100
+ entry: argv.entry,
101
+ dev: argv.dev,
102
+ out: argv.out,
103
+ minify: argv.minify,
104
+ platform: argv.platform,
105
+ sourceMap: argv.sourceMap,
106
+ sourceMapUrl: argv.sourceMapUrl,
107
+ customResolverOptions: argv.resolverOption,
108
+ customTransformOptions: argv.transformOption,
109
+ };
65
110
 
66
111
  // Inline require() to avoid circular dependency with ../index
67
112
  const MetroApi = require('../index');
@@ -78,9 +123,6 @@ module.exports = (): {
78
123
  entryFile: options.entry,
79
124
  minify: !!options.minify,
80
125
  platform: options.platform,
81
- // Bytecode bundles in Metro are not meant for production use. Instead,
82
- // the Hermes Bytecode Compiler should be invoked on the resulting JS bundle from Metro.
83
- runtimeBytecodeVersion: null,
84
126
  },
85
127
  });
86
128
  },
@@ -4,6 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
+ *
7
8
  * @format
8
9
  * @oncall react_native
9
10
  */
@@ -12,10 +13,10 @@
12
13
 
13
14
  const { makeAsyncCommand } = require("../cli-utils");
14
15
  const Server = require("../Server");
15
- const denodeify = require("denodeify");
16
16
  const fs = require("fs");
17
17
  const { loadConfig } = require("metro-config");
18
18
  const path = require("path");
19
+ const { promisify } = require("util");
19
20
  async function dependencies(args, config) {
20
21
  const rootModuleAbsolutePath = args.entryFile;
21
22
  if (!fs.existsSync(rootModuleAbsolutePath)) {
@@ -23,6 +24,8 @@ async function dependencies(args, config) {
23
24
  new Error(`File ${rootModuleAbsolutePath} does not exist`)
24
25
  );
25
26
  }
27
+
28
+ // $FlowFixMe[cannot-write]
26
29
  config.cacheStores = [];
27
30
  const relativePath = path.relative(
28
31
  config.server.unstable_serverRoot ?? config.projectRoot,
@@ -35,10 +38,8 @@ async function dependencies(args, config) {
35
38
  minify: false,
36
39
  generateSourceMaps: !args.dev,
37
40
  };
38
- const writeToFile = args.output;
39
- const outStream = writeToFile
40
- ? fs.createWriteStream(args.output)
41
- : process.stdout;
41
+ const outStream =
42
+ args.output != null ? fs.createWriteStream(args.output) : process.stdout;
42
43
  const server = new Server(config);
43
44
  const deps = await server.getOrderedDependencyPaths(options);
44
45
  deps.forEach((modulePath) => {
@@ -54,13 +55,14 @@ async function dependencies(args, config) {
54
55
  }
55
56
  });
56
57
  server.end();
57
- return writeToFile
58
- ? denodeify(outStream.end).bind(outStream)()
58
+ return args.output != null
59
+ ? // $FlowFixMe[method-unbinding]
60
+ promisify(outStream.end).bind(outStream)()
59
61
  : Promise.resolve();
60
62
  }
61
63
  module.exports = () => ({
62
- command: "get-dependencies",
63
- desc: "List dependencies",
64
+ command: "get-dependencies [entryFile]",
65
+ desc: "List all dependencies that will be bundled for a given entry point",
64
66
  builder: (yargs) => {
65
67
  yargs.option("entry-file", {
66
68
  type: "string",