metro 0.83.0 → 0.83.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 (208) hide show
  1. package/package.json +16 -16
  2. package/src/Assets.js +68 -42
  3. package/src/Assets.js.flow +13 -24
  4. package/src/Bundler/util.js +40 -17
  5. package/src/Bundler/util.js.flow +6 -13
  6. package/src/Bundler.js +17 -6
  7. package/src/Bundler.js.flow +3 -7
  8. package/src/DeltaBundler/DeltaCalculator.js +15 -15
  9. package/src/DeltaBundler/DeltaCalculator.js.flow +4 -7
  10. package/src/DeltaBundler/Graph.js +45 -40
  11. package/src/DeltaBundler/Graph.js.flow +3 -4
  12. package/src/DeltaBundler/Serializers/baseJSBundle.js +24 -10
  13. package/src/DeltaBundler/Serializers/baseJSBundle.js.flow +6 -9
  14. package/src/DeltaBundler/Serializers/getAllFiles.js +9 -6
  15. package/src/DeltaBundler/Serializers/getAllFiles.js.flow +4 -8
  16. package/src/DeltaBundler/Serializers/getAssets.js +18 -11
  17. package/src/DeltaBundler/Serializers/getAssets.js.flow +5 -9
  18. package/src/DeltaBundler/Serializers/getExplodedSourceMap.d.ts +26 -0
  19. package/src/DeltaBundler/Serializers/getExplodedSourceMap.js +7 -6
  20. package/src/DeltaBundler/Serializers/getExplodedSourceMap.js.flow +3 -9
  21. package/src/DeltaBundler/Serializers/getRamBundleInfo.js +40 -23
  22. package/src/DeltaBundler/Serializers/getRamBundleInfo.js.flow +11 -18
  23. package/src/DeltaBundler/Serializers/helpers/getInlineSourceMappingURL.js +4 -1
  24. package/src/DeltaBundler/Serializers/helpers/getInlineSourceMappingURL.js.flow +1 -5
  25. package/src/DeltaBundler/Serializers/helpers/getSourceMapInfo.js +7 -4
  26. package/src/DeltaBundler/Serializers/helpers/getSourceMapInfo.js.flow +3 -7
  27. package/src/DeltaBundler/Serializers/helpers/getTransitiveDependencies.js +4 -1
  28. package/src/DeltaBundler/Serializers/helpers/getTransitiveDependencies.js.flow +2 -6
  29. package/src/DeltaBundler/Serializers/helpers/js.js +65 -31
  30. package/src/DeltaBundler/Serializers/helpers/js.js.flow +21 -21
  31. package/src/DeltaBundler/Serializers/helpers/processModules.js +8 -5
  32. package/src/DeltaBundler/Serializers/helpers/processModules.js.flow +3 -7
  33. package/src/DeltaBundler/Serializers/hmrJSBundle.js +70 -25
  34. package/src/DeltaBundler/Serializers/hmrJSBundle.js.flow +43 -33
  35. package/src/DeltaBundler/Serializers/sourceMapGenerator.js +19 -16
  36. package/src/DeltaBundler/Serializers/sourceMapGenerator.js.flow +6 -14
  37. package/src/DeltaBundler/Serializers/sourceMapObject.js +12 -10
  38. package/src/DeltaBundler/Serializers/sourceMapObject.js.flow +4 -9
  39. package/src/DeltaBundler/Serializers/sourceMapString.js +14 -12
  40. package/src/DeltaBundler/Serializers/sourceMapString.js.flow +4 -9
  41. package/src/DeltaBundler/Transformer.js +32 -27
  42. package/src/DeltaBundler/Transformer.js.flow +10 -17
  43. package/src/DeltaBundler/Worker.flow.js +25 -18
  44. package/src/DeltaBundler/Worker.flow.js.flow +12 -18
  45. package/src/DeltaBundler/Worker.js.flow +2 -0
  46. package/src/DeltaBundler/WorkerFarm.js +13 -11
  47. package/src/DeltaBundler/WorkerFarm.js.flow +7 -9
  48. package/src/DeltaBundler/buildSubgraph.js +13 -17
  49. package/src/DeltaBundler/buildSubgraph.js.flow +1 -1
  50. package/src/DeltaBundler/getTransformCacheKey.js +12 -6
  51. package/src/DeltaBundler/getTransformCacheKey.js.flow +5 -7
  52. package/src/DeltaBundler/mergeDeltas.js +4 -1
  53. package/src/DeltaBundler/mergeDeltas.js.flow +5 -6
  54. package/src/DeltaBundler/types.d.ts +4 -1
  55. package/src/DeltaBundler/{types.flow.js → types.js} +1 -5
  56. package/src/DeltaBundler/{types.flow.js.flow → types.js.flow} +5 -3
  57. package/src/DeltaBundler.js +15 -6
  58. package/src/DeltaBundler.js.flow +4 -8
  59. package/src/HmrServer.js +116 -68
  60. package/src/HmrServer.js.flow +41 -52
  61. package/src/IncrementalBundler/GraphNotFoundError.js +5 -1
  62. package/src/IncrementalBundler/GraphNotFoundError.js.flow +1 -5
  63. package/src/IncrementalBundler/ResourceNotFoundError.js +5 -1
  64. package/src/IncrementalBundler/ResourceNotFoundError.js.flow +1 -5
  65. package/src/IncrementalBundler/RevisionNotFoundError.js +5 -1
  66. package/src/IncrementalBundler/RevisionNotFoundError.js.flow +1 -5
  67. package/src/IncrementalBundler.js +71 -35
  68. package/src/IncrementalBundler.js.flow +12 -16
  69. package/src/ModuleGraph/test-helpers.js +19 -14
  70. package/src/ModuleGraph/worker/JsFileWrapping.js +22 -29
  71. package/src/ModuleGraph/worker/JsFileWrapping.js.flow +1 -10
  72. package/src/ModuleGraph/worker/collectDependencies.js +81 -52
  73. package/src/ModuleGraph/worker/collectDependencies.js.flow +15 -22
  74. package/src/ModuleGraph/worker/generateImportNames.js +12 -6
  75. package/src/ModuleGraph/worker/generateImportNames.js.flow +3 -7
  76. package/src/ModuleGraph/worker/importLocationsPlugin.js +5 -4
  77. package/src/ModuleGraph/worker/importLocationsPlugin.js.flow +2 -4
  78. package/src/Server/MultipartResponse.js +11 -4
  79. package/src/Server/MultipartResponse.js.flow +2 -5
  80. package/src/Server/symbolicate.d.ts +31 -0
  81. package/src/Server/symbolicate.js +15 -16
  82. package/src/Server/symbolicate.js.flow +6 -16
  83. package/src/Server.d.ts +0 -1
  84. package/src/Server.js +298 -191
  85. package/src/Server.js.flow +136 -99
  86. package/src/cli-utils.js +13 -4
  87. package/src/cli-utils.js.flow +3 -5
  88. package/src/cli.js.flow +2 -0
  89. package/src/commands/build.js +18 -15
  90. package/src/commands/build.js.flow +6 -6
  91. package/src/commands/dependencies.js +26 -16
  92. package/src/commands/dependencies.js.flow +7 -9
  93. package/src/commands/serve.js +16 -11
  94. package/src/commands/serve.js.flow +5 -6
  95. package/src/index.d.ts +26 -3
  96. package/src/index.flow.js +162 -72
  97. package/src/index.flow.js.flow +60 -47
  98. package/src/index.js.flow +2 -0
  99. package/src/integration_tests/basic_bundle/TestBundle.js.flow +2 -1
  100. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-import.js +1 -5
  101. package/src/integration_tests/basic_bundle/build-errors/inline-requires-cannot-resolve-import.js +1 -5
  102. package/src/integration_tests/basic_bundle/import-export/index.js +5 -13
  103. package/src/integration_tests/basic_bundle/require-context/mode-eager.js +2 -2
  104. package/src/integration_tests/basic_bundle/require-context/mode-lazy-once.js +2 -2
  105. package/src/integration_tests/basic_bundle/require-context/mode-lazy.js +2 -2
  106. package/src/integration_tests/basic_bundle/require-context/mode-sync.js +1 -1
  107. package/src/integration_tests/basic_bundle/require-context/utils.js +1 -1
  108. package/src/integration_tests/execBundle.js +7 -4
  109. package/src/integration_tests/execBundle.js.flow +1 -3
  110. package/src/integration_tests/metro.config.js +3 -3
  111. package/src/lib/BatchProcessor.js +15 -5
  112. package/src/lib/BatchProcessor.js.flow +2 -6
  113. package/src/lib/CountingSet.js.flow +2 -2
  114. package/src/lib/JsonReporter.js +6 -2
  115. package/src/lib/JsonReporter.js.flow +1 -5
  116. package/src/lib/RamBundleParser.js +12 -3
  117. package/src/lib/RamBundleParser.js.flow +2 -6
  118. package/src/lib/TerminalReporter.js +95 -56
  119. package/src/lib/TerminalReporter.js.flow +9 -12
  120. package/src/lib/bundleToString.js +4 -1
  121. package/src/lib/bundleToString.js.flow +2 -9
  122. package/src/lib/contextModule.js +3 -7
  123. package/src/lib/contextModuleTemplates.js +9 -19
  124. package/src/lib/countLines.js +5 -1
  125. package/src/lib/countLines.js.flow +1 -3
  126. package/src/lib/createWebsocketServer.js +7 -7
  127. package/src/lib/createWebsocketServer.js.flow +4 -4
  128. package/src/lib/debounceAsyncQueue.js +4 -1
  129. package/src/lib/debounceAsyncQueue.js.flow +1 -5
  130. package/src/lib/formatBundlingError.js +32 -22
  131. package/src/lib/formatBundlingError.js.flow +18 -20
  132. package/src/lib/getAppendScripts.js +20 -20
  133. package/src/lib/getAppendScripts.js.flow +9 -13
  134. package/src/lib/getGraphId.js +12 -6
  135. package/src/lib/getGraphId.js.flow +4 -10
  136. package/src/lib/getPreludeCode.js +7 -10
  137. package/src/lib/getPreludeCode.js.flow +2 -6
  138. package/src/lib/getPrependedScripts.js +40 -16
  139. package/src/lib/getPrependedScripts.js.flow +8 -13
  140. package/src/lib/isResolvedDependency.js.flow +1 -1
  141. package/src/lib/logToConsole.js +18 -12
  142. package/src/lib/logToConsole.js.flow +5 -14
  143. package/src/lib/parseBundleOptionsFromBundleRequestUrl.js +144 -0
  144. package/src/lib/parseBundleOptionsFromBundleRequestUrl.js.flow +146 -0
  145. package/src/lib/parseCustomResolverOptions.js +8 -6
  146. package/src/lib/parseCustomResolverOptions.js.flow +6 -12
  147. package/src/lib/parseCustomTransformOptions.js +8 -6
  148. package/src/lib/parseCustomTransformOptions.js.flow +11 -14
  149. package/src/lib/parseJsonBody.js +4 -1
  150. package/src/lib/parseJsonBody.js.flow +1 -3
  151. package/src/lib/pathUtils.js +34 -0
  152. package/src/lib/pathUtils.js.flow +16 -0
  153. package/src/lib/relativizeSourceMap.js +12 -3
  154. package/src/lib/relativizeSourceMap.js.flow +2 -6
  155. package/src/lib/reporting.js +25 -19
  156. package/src/lib/reporting.js.flow +6 -16
  157. package/src/lib/splitBundleOptions.js +4 -2
  158. package/src/lib/splitBundleOptions.js.flow +4 -7
  159. package/src/lib/transformHelpers.js +19 -25
  160. package/src/lib/transformHelpers.js.flow +5 -15
  161. package/src/node-haste/DependencyGraph/ModuleResolution.js +75 -57
  162. package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +28 -44
  163. package/src/node-haste/DependencyGraph/createFileMap.js +15 -13
  164. package/src/node-haste/DependencyGraph/createFileMap.js.flow +2 -5
  165. package/src/node-haste/DependencyGraph.js +61 -45
  166. package/src/node-haste/DependencyGraph.js.flow +34 -31
  167. package/src/node-haste/Package.js +13 -6
  168. package/src/node-haste/Package.js.flow +3 -7
  169. package/src/node-haste/{ModuleCache.js → PackageCache.js} +11 -19
  170. package/src/node-haste/{ModuleCache.js.flow → PackageCache.js.flow} +2 -30
  171. package/src/node-haste/lib/AssetPaths.js +14 -8
  172. package/src/node-haste/lib/AssetPaths.js.flow +7 -8
  173. package/src/node-haste/lib/parsePlatformFilePath.js +10 -4
  174. package/src/node-haste/lib/parsePlatformFilePath.js.flow +2 -6
  175. package/src/shared/output/RamBundle/as-assets.js +42 -22
  176. package/src/shared/output/RamBundle/as-assets.js.flow +12 -15
  177. package/src/shared/output/RamBundle/as-indexed-file.js +33 -23
  178. package/src/shared/output/RamBundle/as-indexed-file.js.flow +10 -16
  179. package/src/shared/output/RamBundle/buildSourcemapWithMetadata.js +11 -10
  180. package/src/shared/output/RamBundle/buildSourcemapWithMetadata.js.flow +4 -6
  181. package/src/shared/output/RamBundle/magic-number.js +5 -1
  182. package/src/shared/output/RamBundle/magic-number.js.flow +1 -3
  183. package/src/shared/output/RamBundle/util.js +21 -18
  184. package/src/shared/output/RamBundle/util.js.flow +4 -6
  185. package/src/shared/output/RamBundle/write-sourcemap.js +9 -3
  186. package/src/shared/output/RamBundle/write-sourcemap.js.flow +2 -6
  187. package/src/shared/output/RamBundle.js +16 -9
  188. package/src/shared/output/RamBundle.js.flow +8 -12
  189. package/src/shared/output/bundle.flow.js +37 -13
  190. package/src/shared/output/bundle.flow.js.flow +24 -12
  191. package/src/shared/output/bundle.js.flow +2 -0
  192. package/src/shared/output/meta.js +16 -9
  193. package/src/shared/output/meta.js.flow +3 -5
  194. package/src/shared/output/unbundle.js +14 -1
  195. package/src/shared/output/unbundle.js.flow +1 -3
  196. package/src/shared/output/writeFile.js +11 -4
  197. package/src/shared/output/writeFile.js.flow +3 -5
  198. package/src/shared/types.d.ts +0 -1
  199. package/src/shared/{types.flow.js.flow → types.js.flow} +16 -17
  200. package/src/lib/createModuleIdFactory.js +0 -15
  201. package/src/lib/createModuleIdFactory.js.flow +0 -27
  202. package/src/lib/getMaxWorkers.js +0 -9
  203. package/src/lib/getMaxWorkers.js.flow +0 -22
  204. package/src/lib/parseOptionsFromUrl.js +0 -62
  205. package/src/lib/parseOptionsFromUrl.js.flow +0 -97
  206. package/src/node-haste/Module.js +0 -24
  207. package/src/node-haste/Module.js.flow +0 -41
  208. /package/src/shared/{types.flow.js → types.js} +0 -0
@@ -9,8 +9,6 @@
9
9
  * @oncall react_native
10
10
  */
11
11
 
12
- 'use strict';
13
-
14
12
  import type {AssetData} from './Assets';
15
13
  import type {ExplodedSourceMap} from './DeltaBundler/Serializers/getExplodedSourceMap';
16
14
  import type {RamBundleInfo} from './DeltaBundler/Serializers/getRamBundleInfo';
@@ -21,7 +19,7 @@ import type {
21
19
  ReadOnlyGraph,
22
20
  TransformInputOptions,
23
21
  TransformResult,
24
- } from './DeltaBundler/types.flow';
22
+ } from './DeltaBundler/types';
25
23
  import type {RevisionId} from './IncrementalBundler';
26
24
  import type {GraphId} from './lib/getGraphId';
27
25
  import type {Reporter} from './lib/reporting';
@@ -32,7 +30,7 @@ import type {
32
30
  GraphOptions,
33
31
  ResolverInputOptions,
34
32
  SplitBundleOptions,
35
- } from './shared/types.flow';
33
+ } from './shared/types';
36
34
  import type {IncomingMessage} from 'connect';
37
35
  import type {ServerResponse} from 'http';
38
36
  import type {CacheStore} from 'metro-cache';
@@ -44,49 +42,42 @@ import type {
44
42
  import type {CustomResolverOptions} from 'metro-resolver/private/types';
45
43
  import type {CustomTransformOptions} from 'metro-transform-worker';
46
44
 
47
- import {SourcePathsMode} from './shared/types.flow';
48
-
49
- const {getAsset} = require('./Assets');
50
- const baseJSBundle = require('./DeltaBundler/Serializers/baseJSBundle');
51
- const getAllFiles = require('./DeltaBundler/Serializers/getAllFiles');
52
- const getAssets = require('./DeltaBundler/Serializers/getAssets');
53
- const {
54
- getExplodedSourceMap,
55
- } = require('./DeltaBundler/Serializers/getExplodedSourceMap');
56
- const getRamBundleInfo = require('./DeltaBundler/Serializers/getRamBundleInfo');
57
- const {
58
- sourceMapStringNonBlocking,
59
- } = require('./DeltaBundler/Serializers/sourceMapString');
60
- const IncrementalBundler = require('./IncrementalBundler');
61
- const ResourceNotFoundError = require('./IncrementalBundler/ResourceNotFoundError');
62
- const bundleToString = require('./lib/bundleToString');
63
- const formatBundlingError = require('./lib/formatBundlingError');
64
- const getGraphId = require('./lib/getGraphId');
65
- const parseJsonBody = require('./lib/parseJsonBody');
66
- const parseOptionsFromUrl = require('./lib/parseOptionsFromUrl');
67
- const splitBundleOptions = require('./lib/splitBundleOptions');
68
- const transformHelpers = require('./lib/transformHelpers');
69
- const {
70
- UnableToResolveError,
71
- } = require('./node-haste/DependencyGraph/ModuleResolution');
72
- const parsePlatformFilePath = require('./node-haste/lib/parsePlatformFilePath');
73
- const MultipartResponse = require('./Server/MultipartResponse');
74
- const symbolicate = require('./Server/symbolicate');
75
- const {codeFrameColumns} = require('@babel/code-frame');
45
+ import {getAsset} from './Assets';
46
+ import baseJSBundle from './DeltaBundler/Serializers/baseJSBundle';
47
+ import getAllFiles from './DeltaBundler/Serializers/getAllFiles';
48
+ import getAssets from './DeltaBundler/Serializers/getAssets';
49
+ import {getExplodedSourceMap} from './DeltaBundler/Serializers/getExplodedSourceMap';
50
+ import getRamBundleInfo from './DeltaBundler/Serializers/getRamBundleInfo';
51
+ import {sourceMapStringNonBlocking} from './DeltaBundler/Serializers/sourceMapString';
52
+ import IncrementalBundler from './IncrementalBundler';
53
+ import ResourceNotFoundError from './IncrementalBundler/ResourceNotFoundError';
54
+ import bundleToString from './lib/bundleToString';
55
+ import formatBundlingError from './lib/formatBundlingError';
56
+ import getGraphId from './lib/getGraphId';
57
+ import parseBundleOptionsFromBundleRequestUrl from './lib/parseBundleOptionsFromBundleRequestUrl';
58
+ import parseJsonBody from './lib/parseJsonBody';
59
+ import splitBundleOptions from './lib/splitBundleOptions';
60
+ import * as transformHelpers from './lib/transformHelpers';
61
+ import {UnableToResolveError} from './node-haste/DependencyGraph/ModuleResolution';
62
+ import parsePlatformFilePath from './node-haste/lib/parsePlatformFilePath';
63
+ import MultipartResponse from './Server/MultipartResponse';
64
+ import symbolicate from './Server/symbolicate';
65
+ import {SourcePathsMode} from './shared/types';
66
+ import {codeFrameColumns} from '@babel/code-frame';
67
+ import * as fs from 'graceful-fs';
68
+ import invariant from 'invariant';
69
+ import * as jscSafeUrl from 'jsc-safe-url';
70
+ import {Logger} from 'metro-core';
71
+ import mime from 'mime-types';
72
+ import nullthrows from 'nullthrows';
73
+ import path from 'path';
74
+ import {performance} from 'perf_hooks';
75
+ import querystring from 'querystring';
76
+
77
+ // eslint-disable-next-line import/no-commonjs
76
78
  const debug = require('debug')('Metro:Server');
77
- const fs = require('graceful-fs');
78
- const invariant = require('invariant');
79
- const jscSafeUrl = require('jsc-safe-url');
80
- const {
81
- Logger,
82
- Logger: {createActionStartEntry, createActionEndEntry, log},
83
- } = require('metro-core');
84
- const mime = require('mime-types');
85
- const nullthrows = require('nullthrows');
86
- const path = require('path');
87
- const {performance} = require('perf_hooks');
88
- const querystring = require('querystring');
89
- const url = require('url');
79
+
80
+ const {createActionStartEntry, createActionEndEntry, log} = Logger;
90
81
 
91
82
  const noopLogger: RootPerfLogger = {
92
83
  start: () => {},
@@ -139,7 +130,7 @@ export type ServerOptions = $ReadOnly<{
139
130
  const DELTA_ID_HEADER = 'X-Metro-Delta-ID';
140
131
  const FILES_CHANGED_COUNT_HEADER = 'X-Metro-Files-Changed-Count';
141
132
 
142
- class Server {
133
+ export default class Server {
143
134
  _bundler: IncrementalBundler;
144
135
  _config: ConfigT;
145
136
  _createModuleId: (path: string) => number;
@@ -244,6 +235,7 @@ class Server {
244
235
  processModuleFilter: this._config.serializer.processModuleFilter,
245
236
  createModuleId: this._createModuleId,
246
237
  getRunModuleStatement: this._config.serializer.getRunModuleStatement,
238
+ globalPrefix: this._config.transformer.globalPrefix,
247
239
  dev: transformOptions.dev,
248
240
  includeAsyncPaths: graphOptions.lazy,
249
241
  projectRoot: this._config.projectRoot,
@@ -389,6 +381,7 @@ class Server {
389
381
  excludeSource: serializerOptions.excludeSource,
390
382
  getRunModuleStatement: this._config.serializer.getRunModuleStatement,
391
383
  getTransformOptions: this._config.transformer.getTransformOptions,
384
+ globalPrefix: this._config.transformer.globalPrefix,
392
385
  includeAsyncPaths: graphOptions.lazy,
393
386
  platform: transformOptions.platform,
394
387
  projectRoot: this._config.projectRoot,
@@ -452,7 +445,7 @@ class Server {
452
445
  onProgress,
453
446
  resolverOptions,
454
447
  transformOptions,
455
- /* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an
448
+ /* $FlowFixMe[cannot-spread-inexact](>=0.122.0 site=react_native_fb) This comment suppresses an
456
449
  * error found when Flow v0.122.0 was deployed. To see the error, delete
457
450
  * this comment and run Flow. */
458
451
  } = splitBundleOptions({
@@ -471,7 +464,7 @@ class Server {
471
464
  transformOptions.platform ||
472
465
  parsePlatformFilePath(entryFile, this._platforms).platform;
473
466
 
474
- // $FlowFixMe[incompatible-return]
467
+ // $FlowFixMe[incompatible-type]
475
468
  return await getAllFiles(prepend, graph, {
476
469
  platform,
477
470
  processModuleFilter: this._config.serializer.processModuleFilter,
@@ -510,20 +503,36 @@ class Server {
510
503
  req: IncomingMessage,
511
504
  res: ServerResponse,
512
505
  ): Promise<void> {
513
- const urlObj = url.parse(decodeURI(req.url), true);
514
- let [, assetPath] =
515
- (urlObj &&
516
- urlObj.pathname &&
517
- urlObj.pathname.match(/^\/assets\/(.+)$/)) ||
518
- [];
506
+ debug('Processing single asset request: %s', req.url);
507
+ if (!URL.canParse(req.url, 'resolve://')) {
508
+ throw new Error('Could not parse URL', {cause: req.url});
509
+ }
519
510
 
520
- if (!assetPath && urlObj && urlObj.query && urlObj.query.unstable_path) {
511
+ const urlObj = new URL(req.url, 'resolve://');
512
+ const formattedUrl = urlObj.toString();
513
+ if (req.url !== formattedUrl) {
514
+ debug('Formatted as: %s', formattedUrl);
515
+ }
516
+
517
+ // using this Metro particular convention for decoding URL paths into file paths
518
+ let [, assetPath] =
519
+ urlObj.pathname
520
+ .split('/')
521
+ .map(segment => decodeURIComponent(segment))
522
+ .join('/')
523
+ .match(/^\/assets\/(.+)$/) || [];
524
+ if (!assetPath && urlObj.searchParams.get('unstable_path')) {
521
525
  const [, actualPath, secondaryQuery] = nullthrows(
522
- urlObj.query.unstable_path.match(/^([^?]*)\??(.*)$/),
526
+ (urlObj.searchParams.get('unstable_path') || '').match(
527
+ /^([^?]*)\??(.*)$/,
528
+ ),
523
529
  );
524
530
  if (secondaryQuery) {
525
- // $FlowFixMe[unsafe-object-assign]
526
- Object.assign(urlObj.query, querystring.parse(secondaryQuery));
531
+ Object.entries(querystring.parse(secondaryQuery)).forEach(
532
+ ([key, value]) => {
533
+ urlObj.searchParams.set(key, value);
534
+ },
535
+ );
527
536
  }
528
537
  assetPath = actualPath;
529
538
  }
@@ -544,12 +553,14 @@ class Server {
544
553
  assetPath,
545
554
  this._config.projectRoot,
546
555
  this._config.watchFolders,
547
- urlObj.query.platform,
556
+ urlObj.searchParams.get('platform'),
548
557
  this._config.resolver.assetExts,
549
558
  );
550
559
  // Tell clients to cache this for 1 year.
551
560
  // This is safe as the asset url contains a hash of the asset.
552
561
  // $FlowFixMe[incompatible-type]
562
+ /* $FlowFixMe[invalid-compare] Error discovered during Constant Condition
563
+ * roll out. See https://fburl.com/workplace/4oq3zi07. */
553
564
  if (process.env.REACT_NATIVE_ENABLE_ASSET_CACHING === true) {
554
565
  res.setHeader('Cache-Control', 'max-age=31536000');
555
566
  }
@@ -578,10 +589,11 @@ class Server {
578
589
  };
579
590
 
580
591
  _parseOptions(url: string): BundleOptions {
581
- const {bundleType: _bundleType, ...bundleOptions} = parseOptionsFromUrl(
582
- url,
583
- new Set(this._config.resolver.platforms),
584
- );
592
+ const {bundleType: _bundleType, ...bundleOptions} =
593
+ parseBundleOptionsFromBundleRequestUrl(
594
+ url,
595
+ new Set(this._config.resolver.platforms),
596
+ );
585
597
  return bundleOptions;
586
598
  }
587
599
 
@@ -595,21 +607,37 @@ class Server {
595
607
  req: IncomingMessage,
596
608
  res: ServerResponse,
597
609
  next: (?Error) => void,
598
- ) {
610
+ ): Promise<void> {
599
611
  const originalUrl = req.url;
612
+ debug('Handling request: %s', originalUrl);
600
613
  req.url = this._rewriteAndNormalizeUrl(req.url);
601
- const urlObj = url.parse(decodeURI(req.url), true);
602
- const {host} = req.headers;
603
- debug(
604
- `Handling request: ${host ? 'http://' + host : ''}${req.url}` +
605
- (originalUrl !== req.url ? ` (rewritten from ${originalUrl})` : ''),
606
- );
607
- const formattedUrl = url.format({
608
- ...urlObj,
609
- host,
610
- protocol: 'http',
611
- });
614
+ if (req.url !== originalUrl) {
615
+ debug('Rewritten to: %s', req.url);
616
+ }
617
+ const reqHost = req.headers['x-forwarded-host'] || req.headers['host'];
618
+ if (!reqHost) {
619
+ throw new Error('No host header was found.');
620
+ }
621
+
622
+ const reqProtocol =
623
+ req.headers['x-forwarded-proto'] ||
624
+ // $FlowFixMe[prop-missing] not missing for https requests
625
+ (req.socket?.encrypted === true ? 'https' : 'http');
626
+ const urlObj = new URL(req.url, reqProtocol + '://' + reqHost);
627
+
628
+ const formattedUrl = urlObj.toString();
629
+ if (req.url !== formattedUrl) {
630
+ debug('Formatted as: %s', formattedUrl);
631
+ }
632
+
612
633
  const pathname = urlObj.pathname || '';
634
+
635
+ // using this Metro particular convention for decoding URL paths into file paths
636
+ const filePathname = pathname
637
+ .split('/')
638
+ .map(segment => decodeURIComponent(segment))
639
+ .join('/');
640
+
613
641
  const buildNumber = this.getNewBuildNumber();
614
642
  if (pathname.endsWith('.bundle')) {
615
643
  const options = this._parseOptions(formattedUrl);
@@ -622,7 +650,7 @@ class Server {
622
650
  });
623
651
 
624
652
  if (this._serverOptions && this._serverOptions.onBundleBuilt) {
625
- this._serverOptions.onBundleBuilt(pathname);
653
+ this._serverOptions.onBundleBuilt(filePathname);
626
654
  }
627
655
  } else if (pathname.endsWith('.map')) {
628
656
  // Chrome dev tools may need to access the source maps.
@@ -654,10 +682,12 @@ class Server {
654
682
  let handled = false;
655
683
  for (const [pathnamePrefix, normalizedRootDir] of this
656
684
  ._sourceRequestRoutingMap) {
657
- if (pathname.startsWith(pathnamePrefix)) {
658
- const relativePathname = pathname.substr(pathnamePrefix.length);
685
+ if (filePathname.startsWith(pathnamePrefix)) {
686
+ const relativeFilePathname = filePathname.substr(
687
+ pathnamePrefix.length,
688
+ );
659
689
  await this._processSourceRequest(
660
- relativePathname,
690
+ relativeFilePathname,
661
691
  normalizedRootDir,
662
692
  res,
663
693
  );
@@ -672,13 +702,13 @@ class Server {
672
702
  }
673
703
 
674
704
  async _processSourceRequest(
675
- relativePathname: string,
705
+ relativeFilePathname: string,
676
706
  rootDir: string,
677
707
  res: ServerResponse,
678
708
  ): Promise<void> {
679
709
  if (
680
710
  !this._allowedSuffixesForSourceRequests.some(suffix =>
681
- relativePathname.endsWith(suffix),
711
+ relativeFilePathname.endsWith(suffix),
682
712
  )
683
713
  ) {
684
714
  res.writeHead(404);
@@ -686,7 +716,7 @@ class Server {
686
716
  return;
687
717
  }
688
718
  const depGraph = await this._bundler.getBundler().getDependencyGraph();
689
- const filePath = path.join(rootDir, relativePathname);
719
+ const filePath = path.join(rootDir, relativeFilePathname);
690
720
  try {
691
721
  await depGraph.getOrComputeSha1(filePath);
692
722
  } catch {
@@ -694,7 +724,7 @@ class Server {
694
724
  res.end();
695
725
  return;
696
726
  }
697
- const mimeType = mime.lookup(path.basename(relativePathname));
727
+ const mimeType = mime.lookup(path.basename(relativeFilePathname));
698
728
  res.setHeader('Content-Type', mimeType);
699
729
  const stream = fs.createReadStream(filePath);
700
730
  stream.pipe(res);
@@ -868,7 +898,7 @@ class Server {
868
898
  type: 'bundle_build_started',
869
899
  });
870
900
 
871
- const startContext = {
901
+ const startContext: ProcessStartContext = {
872
902
  buildNumber,
873
903
  bundleOptions,
874
904
  entryFile: resolvedEntryFilePath,
@@ -923,7 +953,7 @@ class Server {
923
953
  return;
924
954
  }
925
955
 
926
- const endContext = {
956
+ const endContext: ProcessEndContext<T> = {
927
957
  ...startContext,
928
958
  result,
929
959
  };
@@ -935,7 +965,7 @@ class Server {
935
965
  });
936
966
 
937
967
  log(
938
- /* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses
968
+ /* $FlowFixMe[cannot-spread-inexact](>=0.122.0 site=react_native_fb) This comment suppresses
939
969
  * an error found when Flow v0.122.0 was deployed. To see the error,
940
970
  * delete this comment and run Flow. */
941
971
  createActionEndEntry({
@@ -1050,6 +1080,7 @@ class Server {
1050
1080
  processModuleFilter: this._config.serializer.processModuleFilter,
1051
1081
  createModuleId: this._createModuleId,
1052
1082
  getRunModuleStatement: this._config.serializer.getRunModuleStatement,
1083
+ globalPrefix: this._config.transformer.globalPrefix,
1053
1084
  includeAsyncPaths: graphOptions.lazy,
1054
1085
  dev: transformOptions.dev,
1055
1086
  projectRoot: this._config.projectRoot,
@@ -1319,7 +1350,11 @@ class Server {
1319
1350
  fileName: file,
1320
1351
  };
1321
1352
  } catch (error) {
1322
- console.error(error);
1353
+ debug(
1354
+ 'Generating code frame failed on file read.',
1355
+ fileAbsolute,
1356
+ error,
1357
+ );
1323
1358
  }
1324
1359
  }
1325
1360
 
@@ -1412,7 +1447,7 @@ class Server {
1412
1447
  log(createActionEndEntry(symbolicatingLogEntry));
1413
1448
  });
1414
1449
  } catch (error) {
1415
- console.error(error.stack || error);
1450
+ debug('Symbolication failed', error.stack || error);
1416
1451
  res.statusCode = 500;
1417
1452
  res.end(JSON.stringify({error: error.message}));
1418
1453
  }
@@ -1520,14 +1555,12 @@ class Server {
1520
1555
  customResolverOptions: CustomResolverOptions,
1521
1556
  customTransformOptions: CustomTransformOptions,
1522
1557
  dev: boolean,
1523
- hot: boolean,
1524
1558
  minify: boolean,
1525
1559
  unstable_transformProfile: 'default',
1526
1560
  }> = {
1527
1561
  customResolverOptions: Object.create(null),
1528
1562
  customTransformOptions: Object.create(null),
1529
1563
  dev: true,
1530
- hot: false,
1531
1564
  minify: false,
1532
1565
  unstable_transformProfile: 'default',
1533
1566
  };
@@ -1594,17 +1627,23 @@ class Server {
1594
1627
  const relativePath = module.path.slice(
1595
1628
  normalizedRootDir.length + 1,
1596
1629
  );
1597
- const relativePathPosix = relativePath.split(path.sep).join('/');
1598
- return pathnamePrefix + encodeURI(relativePathPosix);
1630
+ const relativePathPosix = relativePath
1631
+ .split(path.sep)
1632
+ .map(segment => encodeURIComponent(segment))
1633
+ .join('/');
1634
+ return pathnamePrefix + relativePathPosix;
1599
1635
  }
1600
1636
  }
1601
1637
  // Ordinarily all files should match one of the roots above. If they
1602
1638
  // don't, try to preserve useful information, even if fetching the path
1603
1639
  // from Metro might fail.
1604
- const modulePathPosix = module.path.split(path.sep).join('/');
1640
+ const modulePathPosix = module.path
1641
+ .split(path.sep)
1642
+ .map(segment => encodeURIComponent(segment))
1643
+ .join('/');
1605
1644
  return modulePathPosix.startsWith('/')
1606
- ? encodeURI(modulePathPosix)
1607
- : '/' + encodeURI(modulePathPosix);
1645
+ ? modulePathPosix
1646
+ : '/' + modulePathPosix;
1608
1647
  case SourcePathsMode.Absolute:
1609
1648
  return module.path;
1610
1649
  }
@@ -1612,7 +1651,7 @@ class Server {
1612
1651
  }
1613
1652
 
1614
1653
  function* zip<X, Y>(xs: Iterable<X>, ys: Iterable<Y>): Iterable<[X, Y]> {
1615
- //$FlowIssue #9324959
1654
+ //$FlowFixMe[incompatible-type] #9324959
1616
1655
  const ysIter: Iterator<Y> = ys[Symbol.iterator]();
1617
1656
  for (const x of xs) {
1618
1657
  const y = ysIter.next();
@@ -1626,5 +1665,3 @@ function* zip<X, Y>(xs: Iterable<X>, ys: Iterable<Y>): Iterable<[X, Y]> {
1626
1665
  function getBuildID(buildNumber: number): string {
1627
1666
  return buildNumber.toString(36);
1628
1667
  }
1629
-
1630
- module.exports = Server;
package/src/cli-utils.js CHANGED
@@ -1,15 +1,24 @@
1
1
  "use strict";
2
2
 
3
- const fs = require("fs");
4
- exports.watchFile = async function (filename, callback) {
5
- fs.watchFile(filename, () => {
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true,
5
+ });
6
+ exports.watchFile = exports.makeAsyncCommand = void 0;
7
+ var _fs = _interopRequireDefault(require("fs"));
8
+ function _interopRequireDefault(e) {
9
+ return e && e.__esModule ? e : { default: e };
10
+ }
11
+ const watchFile = async function (filename, callback) {
12
+ _fs.default.watchFile(filename, () => {
6
13
  callback();
7
14
  });
8
15
  await callback();
9
16
  };
10
- exports.makeAsyncCommand = (command) => (argv) => {
17
+ exports.watchFile = watchFile;
18
+ const makeAsyncCommand = (command) => (argv) => {
11
19
  Promise.resolve(command(argv)).catch((error) => {
12
20
  console.error(error.stack);
13
21
  process.exitCode = 1;
14
22
  });
15
23
  };
24
+ exports.makeAsyncCommand = makeAsyncCommand;
@@ -9,11 +9,9 @@
9
9
  * @oncall react_native
10
10
  */
11
11
 
12
- 'use strict';
12
+ import fs from 'fs';
13
13
 
14
- const fs = require('fs');
15
-
16
- exports.watchFile = async function (
14
+ export const watchFile = async function (
17
15
  filename: string,
18
16
  callback: () => any,
19
17
  ): Promise<void> {
@@ -24,7 +22,7 @@ exports.watchFile = async function (
24
22
  await callback();
25
23
  };
26
24
 
27
- exports.makeAsyncCommand =
25
+ export const makeAsyncCommand =
28
26
  <T>(command: (argv: T) => Promise<void>): ((argv: T) => void) =>
29
27
  (argv: T) => {
30
28
  Promise.resolve(command(argv)).catch(error => {
package/src/cli.js.flow CHANGED
@@ -10,6 +10,8 @@
10
10
  * @oncall react_native
11
11
  */
12
12
 
13
+ /* eslint-disable import/no-commonjs */
14
+
13
15
  'use strict';
14
16
 
15
17
  try {
@@ -1,22 +1,24 @@
1
1
  "use strict";
2
2
 
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true,
5
+ });
6
+ exports.default = void 0;
7
+ var _cliUtils = require("../cli-utils");
3
8
  var _parseKeyValueParamArray = _interopRequireDefault(
4
- require("../cli/parseKeyValueParamArray")
9
+ require("../cli/parseKeyValueParamArray"),
10
+ );
11
+ var _TerminalReporter = _interopRequireDefault(
12
+ require("../lib/TerminalReporter"),
5
13
  );
14
+ var _metroConfig = require("metro-config");
15
+ var _metroCore = require("metro-core");
6
16
  function _interopRequireDefault(e) {
7
- return e && e.__esModule
8
- ? e
9
- : {
10
- default: e,
11
- };
17
+ return e && e.__esModule ? e : { default: e };
12
18
  }
13
- const { makeAsyncCommand } = require("../cli-utils");
14
- const TerminalReporter = require("../lib/TerminalReporter");
15
- const { loadConfig } = require("metro-config");
16
- const { Terminal } = require("metro-core");
17
- const term = new Terminal(process.stdout);
18
- const updateReporter = new TerminalReporter(term);
19
- module.exports = () => ({
19
+ const term = new _metroCore.Terminal(process.stdout);
20
+ const updateReporter = new _TerminalReporter.default(term);
21
+ var _default = () => ({
20
22
  command: "build <entry>",
21
23
  desc: "Generates a JavaScript bundle containing the specified entrypoint and its descendants",
22
24
  builder: (yargs) => {
@@ -82,8 +84,8 @@ module.exports = () => ({
82
84
  type: "boolean",
83
85
  });
84
86
  },
85
- handler: makeAsyncCommand(async (argv) => {
86
- const config = await loadConfig(argv);
87
+ handler: (0, _cliUtils.makeAsyncCommand)(async (argv) => {
88
+ const config = await (0, _metroConfig.loadConfig)(argv);
87
89
  const options = {
88
90
  entry: argv.entry,
89
91
  dev: argv.dev,
@@ -130,3 +132,4 @@ module.exports = () => ({
130
132
  });
131
133
  }),
132
134
  });
135
+ exports.default = _default;
@@ -15,12 +15,11 @@ import type {CustomResolverOptions} from 'metro-resolver';
15
15
  import type {ModuleObject} from 'yargs';
16
16
  import typeof Yargs from 'yargs';
17
17
 
18
+ import {makeAsyncCommand} from '../cli-utils';
18
19
  import parseKeyValueParamArray from '../cli/parseKeyValueParamArray';
19
-
20
- const {makeAsyncCommand} = require('../cli-utils');
21
- const TerminalReporter = require('../lib/TerminalReporter');
22
- const {loadConfig} = require('metro-config');
23
- const {Terminal} = require('metro-core');
20
+ import TerminalReporter from '../lib/TerminalReporter';
21
+ import {loadConfig} from 'metro-config';
22
+ import {Terminal} from 'metro-core';
24
23
 
25
24
  const term = new Terminal(process.stdout);
26
25
  const updateReporter = new TerminalReporter(term);
@@ -43,7 +42,7 @@ type Args = $ReadOnly<{
43
42
  resolverOption: CustomResolverOptions,
44
43
  }>;
45
44
 
46
- module.exports = (): {
45
+ export default (): {
47
46
  ...ModuleObject,
48
47
  handler: Function,
49
48
  } => ({
@@ -109,6 +108,7 @@ module.exports = (): {
109
108
  };
110
109
 
111
110
  // Inline require() to avoid circular dependency with ../index
111
+ // eslint-disable-next-line import/no-commonjs
112
112
  const MetroApi = require('../index');
113
113
 
114
114
  await MetroApi.runBuild(config, {