metro 0.76.4 → 0.76.5

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.
@@ -65,6 +65,8 @@ const {codeFrameColumns} = require('@babel/code-frame');
65
65
  const MultipartResponse = require('./Server/MultipartResponse');
66
66
  const debug = require('debug')('Metro:Server');
67
67
  const fs = require('graceful-fs');
68
+ const invariant = require('invariant');
69
+ const jscSafeUrl = require('jsc-safe-url');
68
70
  const {
69
71
  Logger,
70
72
  Logger: {createActionStartEntry, createActionEndEntry, log},
@@ -489,14 +491,19 @@ class Server {
489
491
  return parseOptionsFromUrl(url, new Set(this._config.resolver.platforms));
490
492
  }
491
493
 
494
+ _rewriteAndNormalizeUrl(requestUrl: string): string {
495
+ return jscSafeUrl.toNormalUrl(
496
+ this._config.server.rewriteRequestUrl(jscSafeUrl.toNormalUrl(requestUrl)),
497
+ );
498
+ }
499
+
492
500
  async _processRequest(
493
501
  req: IncomingMessage,
494
502
  res: ServerResponse,
495
503
  next: (?Error) => mixed,
496
504
  ) {
497
505
  const originalUrl = req.url;
498
- req.url = this._config.server.rewriteRequestUrl(req.url);
499
-
506
+ req.url = this._rewriteAndNormalizeUrl(req.url);
500
507
  const urlObj = url.parse(req.url, true);
501
508
  const {host} = req.headers;
502
509
  debug(
@@ -899,7 +906,7 @@ class Server {
899
906
  bundle: bundleCode,
900
907
  };
901
908
  },
902
- finish({req, mres, result}) {
909
+ finish({req, mres, serializerOptions, result}) {
903
910
  if (
904
911
  // We avoid parsing the dates since the client should never send a more
905
912
  // recent date than the one returned by the Delta Bundler (if that's the
@@ -916,6 +923,9 @@ class Server {
916
923
  String(result.numModifiedFiles),
917
924
  );
918
925
  mres.setHeader(DELTA_ID_HEADER, String(result.nextRevId));
926
+ if (serializerOptions?.sourceUrl != null) {
927
+ mres.setHeader('Content-Location', serializerOptions.sourceUrl);
928
+ }
919
929
  mres.setHeader('Content-Type', 'application/javascript; charset=UTF-8');
920
930
  mres.setHeader('Last-Modified', result.lastModifiedDate.toUTCString());
921
931
  mres.setHeader(
@@ -1112,19 +1122,33 @@ class Server {
1112
1122
  /* $FlowFixMe: where is `rawBody` defined? Is it added by the `connect` framework? */
1113
1123
  const body = await req.rawBody;
1114
1124
  const parsedBody = JSON.parse(body);
1115
- const stack = parsedBody.stack.map(frame => {
1116
- if (frame.file && frame.file.includes('://')) {
1125
+
1126
+ const rewriteAndNormalizeStackFrame = <T>(
1127
+ frame: T,
1128
+ lineNumber: number,
1129
+ ): T => {
1130
+ invariant(
1131
+ frame != null && typeof frame === 'object',
1132
+ 'Bad stack frame at line %d, expected object, received: %s',
1133
+ lineNumber,
1134
+ typeof frame,
1135
+ );
1136
+ const frameFile = frame.file;
1137
+ if (typeof frameFile === 'string' && frameFile.includes('://')) {
1117
1138
  return {
1118
1139
  ...frame,
1119
- file: this._config.server.rewriteRequestUrl(frame.file),
1140
+ file: this._rewriteAndNormalizeUrl(frameFile),
1120
1141
  };
1121
1142
  }
1122
1143
  return frame;
1123
- });
1144
+ };
1145
+
1146
+ const stack = parsedBody.stack.map(rewriteAndNormalizeStackFrame);
1124
1147
  // In case of multiple bundles / HMR, some stack frames can have different URLs from others
1125
1148
  const urls = new Set<string>();
1126
1149
 
1127
1150
  stack.forEach(frame => {
1151
+ // These urls have been rewritten and normalized above.
1128
1152
  const sourceUrl = frame.file;
1129
1153
  // Skip `/debuggerWorker.js` which does not need symbolication.
1130
1154
  if (
@@ -1139,8 +1163,11 @@ class Server {
1139
1163
 
1140
1164
  debug('Getting source maps for symbolication');
1141
1165
  const sourceMaps = await Promise.all(
1142
- // $FlowFixMe[method-unbinding] added when improving typing for this parameters
1143
- Array.from(urls.values()).map(this._explodedSourceMapForURL, this),
1166
+ Array.from(urls.values()).map(normalizedUrl =>
1167
+ this._explodedSourceMapForBundleOptions(
1168
+ this._parseOptions(normalizedUrl),
1169
+ ),
1170
+ ),
1144
1171
  );
1145
1172
 
1146
1173
  debug('Performing fast symbolication');
@@ -1168,12 +1195,9 @@ class Server {
1168
1195
  }
1169
1196
  }
1170
1197
 
1171
- async _explodedSourceMapForURL(reqUrl: string): Promise<ExplodedSourceMap> {
1172
- const options = parseOptionsFromUrl(
1173
- reqUrl,
1174
- new Set(this._config.resolver.platforms),
1175
- );
1176
-
1198
+ async _explodedSourceMapForBundleOptions(
1199
+ bundleOptions: BundleOptions,
1200
+ ): Promise<ExplodedSourceMap> {
1177
1201
  const {
1178
1202
  entryFile,
1179
1203
  graphOptions,
@@ -1181,7 +1205,7 @@ class Server {
1181
1205
  resolverOptions,
1182
1206
  serializerOptions,
1183
1207
  transformOptions,
1184
- } = splitBundleOptions(options);
1208
+ } = splitBundleOptions(bundleOptions);
1185
1209
 
1186
1210
  /**
1187
1211
  * `entryFile` is relative to projectRoot, we need to use resolution function
@@ -14,6 +14,7 @@
14
14
  const parsePlatformFilePath = require("../node-haste/lib/parsePlatformFilePath");
15
15
  const parseCustomResolverOptions = require("./parseCustomResolverOptions");
16
16
  const parseCustomTransformOptions = require("./parseCustomTransformOptions");
17
+ const jscSafeUrl = require("jsc-safe-url");
17
18
  const nullthrows = require("nullthrows");
18
19
  const path = require("path");
19
20
  const url = require("url");
@@ -27,8 +28,8 @@ const getTransformProfile = (transformProfile) =>
27
28
  transformProfile === "hermes-stable" || transformProfile === "hermes-canary"
28
29
  ? transformProfile
29
30
  : "default";
30
- module.exports = function parseOptionsFromUrl(requestUrl, platforms) {
31
- const parsedURL = nullthrows(url.parse(requestUrl, true)); // `true` to parse the query param as an object.
31
+ module.exports = function parseOptionsFromUrl(normalizedRequestUrl, platforms) {
32
+ const parsedURL = nullthrows(url.parse(normalizedRequestUrl, true)); // `true` to parse the query param as an object.
32
33
  const query = nullthrows(parsedURL.query);
33
34
  const pathname =
34
35
  query.bundleEntry ||
@@ -62,7 +63,7 @@ module.exports = function parseOptionsFromUrl(requestUrl, platforms) {
62
63
  platform != null && platform.match(/^(android|ios)$/) ? "http" : "",
63
64
  pathname: pathname.replace(/\.(bundle|delta)$/, ".map"),
64
65
  }),
65
- sourceUrl: requestUrl,
66
+ sourceUrl: jscSafeUrl.toJscSafeUrl(normalizedRequestUrl),
66
67
  unstable_transformProfile: getTransformProfile(
67
68
  query.unstable_transformProfile
68
69
  ),
@@ -17,6 +17,7 @@ import type {TransformProfile} from 'metro-babel-transformer';
17
17
  const parsePlatformFilePath = require('../node-haste/lib/parsePlatformFilePath');
18
18
  const parseCustomResolverOptions = require('./parseCustomResolverOptions');
19
19
  const parseCustomTransformOptions = require('./parseCustomTransformOptions');
20
+ const jscSafeUrl = require('jsc-safe-url');
20
21
  const nullthrows = require('nullthrows');
21
22
  const path = require('path');
22
23
  const url = require('url');
@@ -39,10 +40,10 @@ const getTransformProfile = (transformProfile: string): TransformProfile =>
39
40
  : 'default';
40
41
 
41
42
  module.exports = function parseOptionsFromUrl(
42
- requestUrl: string,
43
+ normalizedRequestUrl: string,
43
44
  platforms: Set<string>,
44
45
  ): BundleOptions {
45
- const parsedURL = nullthrows(url.parse(requestUrl, true)); // `true` to parse the query param as an object.
46
+ const parsedURL = nullthrows(url.parse(normalizedRequestUrl, true)); // `true` to parse the query param as an object.
46
47
  const query = nullthrows(parsedURL.query);
47
48
  const pathname =
48
49
  query.bundleEntry ||
@@ -77,7 +78,7 @@ module.exports = function parseOptionsFromUrl(
77
78
  platform != null && platform.match(/^(android|ios)$/) ? 'http' : '',
78
79
  pathname: pathname.replace(/\.(bundle|delta)$/, '.map'),
79
80
  }),
80
- sourceUrl: requestUrl,
81
+ sourceUrl: jscSafeUrl.toJscSafeUrl(normalizedRequestUrl),
81
82
  unstable_transformProfile: getTransformProfile(
82
83
  query.unstable_transformProfile,
83
84
  ),