@modern-js/prod-server 2.28.0 → 2.30.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 (40) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/cjs/libs/context/context.js +16 -6
  3. package/dist/cjs/libs/hook-api/index.js +2 -1
  4. package/dist/cjs/libs/hook-api/index.worker.js +2 -1
  5. package/dist/cjs/libs/proxy.js +29 -11
  6. package/dist/cjs/libs/render/ssr.js +3 -20
  7. package/dist/cjs/libs/reporter.js +22 -0
  8. package/dist/cjs/libs/serverTiming.js +27 -0
  9. package/dist/cjs/server/index.js +14 -0
  10. package/dist/cjs/server/modernServer.js +27 -9
  11. package/dist/cjs/workerServer.js +12 -3
  12. package/dist/esm/libs/context/context.js +14 -4
  13. package/dist/esm/libs/hook-api/index.js +2 -1
  14. package/dist/esm/libs/hook-api/index.worker.js +2 -1
  15. package/dist/esm/libs/proxy.js +80 -32
  16. package/dist/esm/libs/render/ssr.js +6 -30
  17. package/dist/esm/libs/reporter.js +12 -0
  18. package/dist/esm/libs/serverTiming.js +27 -0
  19. package/dist/esm/server/index.js +22 -2
  20. package/dist/esm/server/modernServer.js +56 -33
  21. package/dist/esm/workerServer.js +13 -4
  22. package/dist/esm-node/libs/context/context.js +14 -4
  23. package/dist/esm-node/libs/hook-api/index.js +2 -1
  24. package/dist/esm-node/libs/hook-api/index.worker.js +2 -1
  25. package/dist/esm-node/libs/proxy.js +29 -11
  26. package/dist/esm-node/libs/render/ssr.js +3 -20
  27. package/dist/esm-node/libs/reporter.js +12 -0
  28. package/dist/esm-node/libs/serverTiming.js +17 -0
  29. package/dist/esm-node/server/index.js +14 -0
  30. package/dist/esm-node/server/modernServer.js +27 -9
  31. package/dist/esm-node/workerServer.js +12 -3
  32. package/dist/types/libs/context/context.d.ts +5 -2
  33. package/dist/types/libs/hook-api/index.worker.d.ts +2 -1
  34. package/dist/types/libs/proxy.d.ts +9 -2
  35. package/dist/types/libs/reporter.d.ts +2 -0
  36. package/dist/types/libs/serverTiming.d.ts +12 -0
  37. package/dist/types/server/modernServer.d.ts +1 -2
  38. package/dist/types/type.d.ts +1 -0
  39. package/dist/types/utils.d.ts +1 -1
  40. package/package.json +10 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # @modern-js/prod-server
2
2
 
3
+ ## 2.30.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a5ee81a: feat(server): add new server hooks `beforeServerInit` & `afterServerInit`
8
+ feat(server): 添加新的服务端钩子 `beforeServerInit` & `afterServerInit`
9
+
10
+ ### Patch Changes
11
+
12
+ - 9f21f28: fix(server): add catch and imporve url parse logic in modern server
13
+ fix(server): 在 modern server 中优化 url 解析逻辑并添加错误捕获并
14
+ - 883692c: fix: can't proxy WebSocket without the initial http request
15
+ fix: WebSocket 代理只能在首次 http 请求后生效
16
+ - b6ab299: fix(prod-server): remove req bodyParser, let uesr parses body by themself.
17
+ fix(prod-server): 移除 req bodyParser, 让用户自行解析 body
18
+ - Updated dependencies [a5ee81a]
19
+ - @modern-js/server-core@2.30.0
20
+ - @modern-js/utils@2.30.0
21
+ - @modern-js/plugin@2.30.0
22
+
23
+ ## 2.29.0
24
+
25
+ ### Minor Changes
26
+
27
+ - 16e5195: feat(prod-server): add body parser
28
+ feat(prod-server): 增加 body 解析器
29
+ - cba7675: feat: add a server reporter that report server cost, logger about error, info etc.
30
+ feat: 添加一个 server 端 reporter,来报告 server 端耗时,报错等
31
+
32
+ ### Patch Changes
33
+
34
+ - 76ace5d: fix(prod-server): bff may run bodyParser by themself, so we need't to run
35
+ fix(prod-server): bff 可能会在内部运行, 所以我们不需要运行
36
+ - Updated dependencies [e6b5355]
37
+ - Updated dependencies [93db783]
38
+ - Updated dependencies [cba7675]
39
+ - Updated dependencies [99052ea]
40
+ - Updated dependencies [1d71d2e]
41
+ - @modern-js/utils@2.29.0
42
+ - @modern-js/server-core@2.29.0
43
+ - @modern-js/plugin@2.29.0
44
+
3
45
  ## 2.28.0
4
46
 
5
47
  ### Minor Changes
@@ -15,7 +15,10 @@ const _querystring = /* @__PURE__ */ _interop_require_default._(require("queryst
15
15
  const _buffer = require("buffer");
16
16
  const _etag = /* @__PURE__ */ _interop_require_default._(require("etag"));
17
17
  const _fresh = /* @__PURE__ */ _interop_require_default._(require("fresh"));
18
- const _utils = require("../../utils");
18
+ const _utils = require("@modern-js/utils");
19
+ const _serverTiming = require("../serverTiming");
20
+ const _reporter = require("../reporter");
21
+ const _utils1 = require("../../utils");
19
22
  const MOCK_URL_BASE = "https://modernjs.dev/";
20
23
  class ModernServerContext {
21
24
  get logger() {
@@ -25,8 +28,12 @@ class ModernServerContext {
25
28
  return this.req.metrics;
26
29
  }
27
30
  get parsedURL() {
28
- const url = new _url.URL(this.req.url, MOCK_URL_BASE);
29
- return url;
31
+ try {
32
+ return new _url.URL(this.req.url, MOCK_URL_BASE);
33
+ } catch (e) {
34
+ this.logger.error("Parse URL error", e.stack || e.message);
35
+ return new _url.URL("/_modern_mock_path", MOCK_URL_BASE);
36
+ }
30
37
  }
31
38
  bind() {
32
39
  const { req, res } = this;
@@ -157,18 +164,21 @@ class ModernServerContext {
157
164
  return this.res.writableEnded;
158
165
  }
159
166
  error(dig, e = "") {
160
- this.logger.error(`Web Server Error - ${dig}, error = %s, req.url = %s, req.headers = %o`, e instanceof Error ? e.stack || e.message : e, this.path, (0, _utils.headersWithoutCookie)(this.headers));
167
+ this.logger.error(`Web Server Error - ${dig}, error = %s, req.url = %s, req.headers = %o`, e instanceof Error ? e.stack || e.message : e, this.path, (0, _utils1.headersWithoutCookie)(this.headers));
161
168
  }
162
169
  constructor(req, res, options) {
170
+ var _options;
163
171
  _define_property._(this, "req", void 0);
164
172
  _define_property._(this, "res", void 0);
165
173
  _define_property._(this, "params", {});
166
- _define_property._(this, "serverData", void 0);
174
+ _define_property._(this, "reporter", _reporter.defaultReporter);
175
+ _define_property._(this, "serverTiming", void 0);
176
+ _define_property._(this, "serverData", {});
167
177
  _define_property._(this, "options", {});
168
178
  this.req = req;
169
179
  this.res = res;
170
180
  this.options = options || {};
171
- this.serverData = {};
181
+ this.serverTiming = new _serverTiming.ServerTiming(res, (0, _utils.cutNameByHyphen)(((_options = options) === null || _options === void 0 ? void 0 : _options.metaName) || "modern-js"));
172
182
  this.bind();
173
183
  }
174
184
  }
@@ -27,10 +27,11 @@ const _route = require("./route");
27
27
  const _template = require("./template");
28
28
  const _base = require("./base");
29
29
  const base = (context) => {
30
- const { res } = context;
30
+ const { res, reporter } = context;
31
31
  return {
32
32
  response: new _base.BaseResponse(res),
33
33
  request: new _base.BaseRequest(context),
34
+ reporter,
34
35
  logger: context.logger,
35
36
  metrics: context.metrics
36
37
  };
@@ -56,7 +56,7 @@ class ServerResponse {
56
56
  }
57
57
  }
58
58
  const base = (context) => {
59
- const { req, res, logger, metrics } = context;
59
+ const { req, res, logger, metrics, reporter } = context;
60
60
  const serverResponse = new ServerResponse(res);
61
61
  const { host, pathname, searchParams } = new URL(req.url);
62
62
  const headers = {};
@@ -65,6 +65,7 @@ const base = (context) => {
65
65
  });
66
66
  return {
67
67
  response: new _base.BaseResponse(serverResponse),
68
+ reporter,
68
69
  request: new _base.BaseRequest({
69
70
  url: req.url,
70
71
  host,
@@ -45,24 +45,42 @@ function formatProxyOptions(proxyOptions) {
45
45
  }
46
46
  const createProxyHandler = (proxyOptions) => {
47
47
  (0, _utils.debug)("createProxyHandler", proxyOptions);
48
+ const middlewares = [];
49
+ const handlers = [];
50
+ const handleUpgrade = (req, socket, head) => {
51
+ for (const middleware of middlewares) {
52
+ if (typeof middleware.upgrade === "function") {
53
+ middleware.upgrade(req, socket, head);
54
+ }
55
+ }
56
+ };
48
57
  if (!proxyOptions) {
49
- return null;
58
+ return {
59
+ handlers,
60
+ handleUpgrade
61
+ };
50
62
  }
51
- const formattedProxy = formatProxyOptions(proxyOptions);
52
- const middlewares = formattedProxy.map((option) => {
53
- const middleware = (0, _httpproxymiddleware.createProxyMiddleware)(option.context, option);
54
- return async (ctx, next) => {
63
+ const formattedOptionsList = formatProxyOptions(proxyOptions);
64
+ for (const options of formattedOptionsList) {
65
+ const middleware = (0, _httpproxymiddleware.createProxyMiddleware)(options.context, options);
66
+ const handler = async (ctx, next) => {
55
67
  const { req, res } = ctx;
56
- const bypassUrl = typeof option.bypass === "function" ? option.bypass(req, res, option) : null;
68
+ const bypassUrl = typeof options.bypass === "function" ? options.bypass(req, res, options) : null;
57
69
  if (typeof bypassUrl === "boolean") {
58
70
  ctx.status = 404;
59
- return next();
71
+ next();
60
72
  } else if (typeof bypassUrl === "string") {
61
73
  ctx.url = bypassUrl;
62
- return next();
74
+ next();
75
+ } else {
76
+ middleware(req, res, next);
63
77
  }
64
- middleware(req, res, next);
65
78
  };
66
- });
67
- return middlewares;
79
+ middlewares.push(middleware);
80
+ handlers.push(handler);
81
+ }
82
+ return {
83
+ handlers,
84
+ handleUpgrade
85
+ };
68
86
  };
@@ -22,7 +22,6 @@ const render = async (ctx, renderOptions, runner) => {
22
22
  const loadableStats = _utils.fs.existsSync(loadableUri) ? require(loadableUri) : "";
23
23
  const routesManifestUri = _path.default.join(distDir, _utils.ROUTE_MANIFEST_FILE);
24
24
  const routeManifest = _utils.fs.existsSync(routesManifestUri) ? require(routesManifestUri) : void 0;
25
- const body = await getRequestBody(ctx.req);
26
25
  const context = {
27
26
  request: {
28
27
  baseUrl: urlPath,
@@ -31,8 +30,7 @@ const render = async (ctx, renderOptions, runner) => {
31
30
  host: ctx.host,
32
31
  query: ctx.query,
33
32
  url: ctx.href,
34
- headers: ctx.headers,
35
- body
33
+ headers: ctx.headers
36
34
  },
37
35
  response: {
38
36
  setHeader: (key, value) => {
@@ -51,6 +49,8 @@ const render = async (ctx, renderOptions, runner) => {
51
49
  staticGenerate,
52
50
  logger: void 0,
53
51
  metrics: void 0,
52
+ reporter: ctx.reporter,
53
+ serverTiming: ctx.serverTiming,
54
54
  req: ctx.req,
55
55
  res: ctx.res,
56
56
  enableUnsafeCtx,
@@ -84,20 +84,3 @@ const render = async (ctx, renderOptions, runner) => {
84
84
  };
85
85
  }
86
86
  };
87
- const getRequestBody = (req) => new Promise((resolve, reject) => {
88
- var _req;
89
- if (((_req = req) === null || _req === void 0 ? void 0 : _req.method) && req.method.toLowerCase() !== "get") {
90
- let body = "";
91
- req.on("data", (chunk) => {
92
- body += chunk.toString();
93
- });
94
- req.on("end", () => {
95
- resolve(body);
96
- });
97
- req.on("error", (err) => {
98
- reject(err);
99
- });
100
- } else {
101
- resolve(void 0);
102
- }
103
- });
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "defaultReporter", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return defaultReporter;
9
+ }
10
+ });
11
+ const defaultReporter = {
12
+ init() {
13
+ },
14
+ reportError() {
15
+ },
16
+ reportTiming() {
17
+ },
18
+ reportInfo() {
19
+ },
20
+ reportWarn() {
21
+ }
22
+ };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "ServerTiming", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ServerTiming;
9
+ }
10
+ });
11
+ const _define_property = require("@swc/helpers/_/_define_property");
12
+ const SERVER_TIMING = "Server-Timing";
13
+ class ServerTiming {
14
+ addServeTiming(name, dur, desc) {
15
+ const _name = `bd-${this.meta}-${name}`;
16
+ const serverTiming = this.res.getHeader(SERVER_TIMING) || this.res.getHeader(SERVER_TIMING.toLocaleLowerCase());
17
+ const value = `${_name};${desc ? `decs="${desc}";` : ""} dur=${dur}`;
18
+ this.res.setHeader(SERVER_TIMING, serverTiming ? `${serverTiming}, ${value}` : value);
19
+ return this;
20
+ }
21
+ constructor(res, meta) {
22
+ _define_property._(this, "meta", void 0);
23
+ _define_property._(this, "res", void 0);
24
+ this.meta = meta;
25
+ this.res = res;
26
+ }
27
+ }
@@ -47,7 +47,21 @@ class Server {
47
47
  if (!disableHttpServer) {
48
48
  this.app = await this.server.createHTTPServer(this.getRequestHandler());
49
49
  }
50
+ {
51
+ const result = await this.runner.beforeServerInit({
52
+ app: this.app,
53
+ server: this.server
54
+ });
55
+ ({ app: this.app = this.app, server: this.server } = result);
56
+ }
50
57
  await this.server.onInit(this.runner, this.app);
58
+ {
59
+ const result = await this.runner.afterServerInit({
60
+ app: this.app,
61
+ server: this.server
62
+ });
63
+ ({ app: this.app = this.app, server: this.server } = result);
64
+ }
51
65
  return this;
52
66
  }
53
67
  /**
@@ -14,6 +14,7 @@ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildc
14
14
  const _http = require("http");
15
15
  const _path = /* @__PURE__ */ _interop_require_default._(require("path"));
16
16
  const _utils = require("@modern-js/utils");
17
+ const _time = require("@modern-js/utils/universal/time");
17
18
  const _route = require("../libs/route");
18
19
  const _render = require("../libs/render");
19
20
  const _serveFile = require("../libs/serveFile");
@@ -32,12 +33,11 @@ class ModernServer {
32
33
  const { distDir, conf } = this;
33
34
  this.initReader();
34
35
  (0, _utils1.debug)("final server conf", this.conf);
35
- this.proxyHandler = (0, _proxy.createProxyHandler)((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy);
36
- if (this.proxyHandler) {
37
- this.proxyHandler.forEach((handler) => {
38
- this.addHandler(handler);
39
- });
40
- }
36
+ const proxyHandlers = (0, _proxy.createProxyHandler)((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy);
37
+ app.on("upgrade", proxyHandlers.handleUpgrade);
38
+ proxyHandlers.handlers.forEach((handler) => {
39
+ this.addHandler(handler);
40
+ });
41
41
  (_app = app) === null || _app === void 0 ? void 0 : _app.on("close", () => {
42
42
  this.reader.close();
43
43
  });
@@ -76,7 +76,9 @@ class ModernServer {
76
76
  async render(req, res, url) {
77
77
  req.logger = req.logger || this.logger;
78
78
  req.metrics = req.metrics || this.metrics;
79
- const context = (0, _context.createContext)(req, res);
79
+ const context = (0, _context.createContext)(req, res, {
80
+ metaName: this.metaName
81
+ });
80
82
  const matched = this.router.match(url || context.path);
81
83
  if (!matched) {
82
84
  return null;
@@ -277,12 +279,20 @@ class ModernServer {
277
279
  /* —————————————————————— private function —————————————————————— */
278
280
  // handler route.json, include api / csr / ssr
279
281
  async routeHandler(context) {
280
- const { res } = context;
282
+ const { res, reporter } = context;
281
283
  const matched = this.router.match(context.path);
282
284
  if (!matched) {
283
285
  this.render404(context);
284
286
  return;
285
287
  }
288
+ await reporter.init({
289
+ match: matched
290
+ });
291
+ const end = (0, _time.time)();
292
+ res.on("finish", () => {
293
+ const cost = end();
294
+ reporter.reportTiming("server_handle_request", cost);
295
+ });
286
296
  let route = matched.generate(context.url);
287
297
  if (route.isApi) {
288
298
  await this.handleAPI(context);
@@ -291,9 +301,12 @@ class ModernServer {
291
301
  if (route.entryName) {
292
302
  const afterMatchContext = (0, _hookapi.createAfterMatchContext)(context, route.entryName);
293
303
  if (this.runMode === _constants.RUN_MODE.FULL) {
304
+ const end2 = (0, _time.time)();
294
305
  await this.runner.afterMatch(afterMatchContext, {
295
306
  onLast: _utils1.noop
296
307
  });
308
+ const cost = end2();
309
+ reporter.reportTiming("server_hook_after_render", cost);
297
310
  }
298
311
  if (this.isSend(res)) {
299
312
  return;
@@ -315,7 +328,10 @@ class ModernServer {
315
328
  if (this.frameWebHandler) {
316
329
  res.locals = res.locals || {};
317
330
  const middlewareContext = (0, _hookapi.createMiddlewareContext)(context);
331
+ const end2 = (0, _time.time)();
318
332
  await this.frameWebHandler(middlewareContext);
333
+ const cost = end2();
334
+ reporter.reportTiming("server_middleware", cost);
319
335
  res.locals = {
320
336
  ...res.locals,
321
337
  ...middlewareContext.response.locals
@@ -337,9 +353,12 @@ class ModernServer {
337
353
  if (route.entryName) {
338
354
  const afterRenderContext = (0, _hookapi.createAfterRenderContext)(context, response.toString());
339
355
  if (this.runMode === _constants.RUN_MODE.FULL) {
356
+ const end2 = (0, _time.time)();
340
357
  await this.runner.afterRender(afterRenderContext, {
341
358
  onLast: _utils1.noop
342
359
  });
360
+ const cost = end2();
361
+ reporter.reportTiming("server_hook_after_render", cost);
343
362
  }
344
363
  if (this.isSend(res)) {
345
364
  return;
@@ -472,7 +491,6 @@ class ModernServer {
472
491
  _define_property._(this, "loaderHandler", null);
473
492
  _define_property._(this, "frameWebHandler", null);
474
493
  _define_property._(this, "frameAPIHandler", null);
475
- _define_property._(this, "proxyHandler", null);
476
494
  _define_property._(this, "_handler", void 0);
477
495
  require("ignore-styles");
478
496
  this.pwd = pwd;
@@ -23,6 +23,7 @@ const _indexworker = require("./libs/hook-api/index.worker");
23
23
  const _logger = require("./libs/logger");
24
24
  const _route = require("./libs/route");
25
25
  const _metrics = require("./libs/metrics");
26
+ const _reporter = require("./libs/reporter");
26
27
  class ReturnResponse {
27
28
  /**
28
29
  * Iterate a Object
@@ -101,7 +102,8 @@ const createHandler = (manifest) => {
101
102
  level: "warn"
102
103
  });
103
104
  const metrics = _metrics.metrics;
104
- const hookContext = createWorkerHookContext(request.url, logger, metrics);
105
+ const reporter = _reporter.defaultReporter;
106
+ const hookContext = createWorkerHookContext(request.url, logger, metrics, reporter);
105
107
  const afterMatchHookContext = (0, _indexworker.createAfterMatchContext)(hookContext, entryName);
106
108
  (_page = page) === null || _page === void 0 ? void 0 : (_page_serverHooks = _page.serverHooks) === null || _page_serverHooks === void 0 ? void 0 : (_page_serverHooks_afterMatch = _page_serverHooks.afterMatch) === null || _page_serverHooks_afterMatch === void 0 ? void 0 : _page_serverHooks_afterMatch.call(_page_serverHooks, afterMatchHookContext, () => void 0);
107
109
  if (checkIsSent(hookContext)) {
@@ -137,9 +139,15 @@ const createHandler = (manifest) => {
137
139
  template: page.template,
138
140
  entryName: page.entryName,
139
141
  logger,
142
+ reporter: _reporter.defaultReporter,
140
143
  metrics,
141
144
  // FIXME: pass correctly req & res
142
145
  req: request,
146
+ serverTiming: {
147
+ addServeTiming() {
148
+ return this;
149
+ }
150
+ },
143
151
  res: responseLike
144
152
  };
145
153
  const body = await page.serverRender(serverRenderContext);
@@ -184,7 +192,7 @@ function createResponse(template) {
184
192
  return RESPONSE_NOTFOUND;
185
193
  }
186
194
  }
187
- function createWorkerHookContext(url, logger, metrics) {
195
+ function createWorkerHookContext(url, logger, metrics, reporter) {
188
196
  const [res, req] = [
189
197
  {
190
198
  headers: new Headers(),
@@ -198,7 +206,8 @@ function createWorkerHookContext(url, logger, metrics) {
198
206
  res,
199
207
  req,
200
208
  logger,
201
- metrics
209
+ metrics,
210
+ reporter
202
211
  };
203
212
  }
204
213
  function applyMiddlewares(ctx, middleware) {
@@ -7,21 +7,27 @@ import qs from "querystring";
7
7
  import { Buffer } from "buffer";
8
8
  import createEtag from "etag";
9
9
  import fresh from "fresh";
10
+ import { cutNameByHyphen } from "@modern-js/utils";
11
+ import { ServerTiming } from "../serverTiming";
12
+ import { defaultReporter } from "../reporter";
10
13
  import { headersWithoutCookie } from "../../utils";
11
14
  var MOCK_URL_BASE = "https://modernjs.dev/";
12
15
  export var ModernServerContext = /* @__PURE__ */ function() {
13
16
  "use strict";
14
17
  function ModernServerContext2(req, res, options) {
15
18
  _class_call_check(this, ModernServerContext2);
19
+ var _options;
16
20
  _define_property(this, "req", void 0);
17
21
  _define_property(this, "res", void 0);
18
22
  _define_property(this, "params", {});
19
- _define_property(this, "serverData", void 0);
23
+ _define_property(this, "reporter", defaultReporter);
24
+ _define_property(this, "serverTiming", void 0);
25
+ _define_property(this, "serverData", {});
20
26
  _define_property(this, "options", {});
21
27
  this.req = req;
22
28
  this.res = res;
23
29
  this.options = options || {};
24
- this.serverData = {};
30
+ this.serverTiming = new ServerTiming(res, cutNameByHyphen(((_options = options) === null || _options === void 0 ? void 0 : _options.metaName) || "modern-js"));
25
31
  this.bind();
26
32
  }
27
33
  _create_class(ModernServerContext2, [
@@ -40,8 +46,12 @@ export var ModernServerContext = /* @__PURE__ */ function() {
40
46
  {
41
47
  key: "parsedURL",
42
48
  get: function get() {
43
- var url = new URL(this.req.url, MOCK_URL_BASE);
44
- return url;
49
+ try {
50
+ return new URL(this.req.url, MOCK_URL_BASE);
51
+ } catch (e) {
52
+ this.logger.error("Parse URL error", e.stack || e.message);
53
+ return new URL("/_modern_mock_path", MOCK_URL_BASE);
54
+ }
45
55
  }
46
56
  },
47
57
  {
@@ -4,10 +4,11 @@ import { RouteAPI } from "./route";
4
4
  import { TemplateAPI } from "./template";
5
5
  import { BaseRequest, BaseResponse } from "./base";
6
6
  export var base = function(context) {
7
- var res = context.res;
7
+ var res = context.res, reporter = context.reporter;
8
8
  return {
9
9
  response: new BaseResponse(res),
10
10
  request: new BaseRequest(context),
11
+ reporter: reporter,
11
12
  logger: context.logger,
12
13
  metrics: context.metrics
13
14
  };
@@ -55,7 +55,7 @@ var ServerResponse = /* @__PURE__ */ function() {
55
55
  return ServerResponse2;
56
56
  }();
57
57
  export var base = function(context) {
58
- var req = context.req, res = context.res, logger = context.logger, metrics = context.metrics;
58
+ var req = context.req, res = context.res, logger = context.logger, metrics = context.metrics, reporter = context.reporter;
59
59
  var serverResponse = new ServerResponse(res);
60
60
  var _ref = new URL(req.url), host = _ref.host, pathname = _ref.pathname, searchParams = _ref.searchParams;
61
61
  var headers = {};
@@ -64,6 +64,7 @@ export var base = function(context) {
64
64
  });
65
65
  return {
66
66
  response: new BaseResponse(serverResponse),
67
+ reporter: reporter,
67
68
  request: new BaseRequest({
68
69
  url: req.url,
69
70
  host: host,
@@ -30,41 +30,89 @@ export function formatProxyOptions(proxyOptions) {
30
30
  }
31
31
  export var createProxyHandler = function(proxyOptions) {
32
32
  debug("createProxyHandler", proxyOptions);
33
+ var middlewares = [];
34
+ var handlers = [];
35
+ var handleUpgrade = function(req, socket, head) {
36
+ var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = void 0;
37
+ try {
38
+ for (var _iterator2 = middlewares[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
39
+ var middleware = _step2.value;
40
+ if (typeof middleware.upgrade === "function") {
41
+ middleware.upgrade(req, socket, head);
42
+ }
43
+ }
44
+ } catch (err) {
45
+ _didIteratorError2 = true;
46
+ _iteratorError2 = err;
47
+ } finally {
48
+ try {
49
+ if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
50
+ _iterator2.return();
51
+ }
52
+ } finally {
53
+ if (_didIteratorError2) {
54
+ throw _iteratorError2;
55
+ }
56
+ }
57
+ }
58
+ };
33
59
  if (!proxyOptions) {
34
- return null;
60
+ return {
61
+ handlers: handlers,
62
+ handleUpgrade: handleUpgrade
63
+ };
35
64
  }
36
- var formattedProxy = formatProxyOptions(proxyOptions);
37
- var middlewares = formattedProxy.map(function(option) {
38
- var middleware = createProxyMiddleware(option.context, option);
39
- return function() {
40
- var _ref = _async_to_generator(function(ctx, next) {
41
- var req, res, bypassUrl;
42
- return _ts_generator(this, function(_state) {
43
- req = ctx.req, res = ctx.res;
44
- bypassUrl = typeof option.bypass === "function" ? option.bypass(req, res, option) : null;
45
- if (typeof bypassUrl === "boolean") {
46
- ctx.status = 404;
47
- return [
48
- 2,
49
- next()
50
- ];
51
- } else if (typeof bypassUrl === "string") {
52
- ctx.url = bypassUrl;
65
+ var formattedOptionsList = formatProxyOptions(proxyOptions);
66
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
67
+ try {
68
+ var _loop = function() {
69
+ var options = _step.value;
70
+ var middleware = createProxyMiddleware(options.context, options);
71
+ var handler = function() {
72
+ var _ref = _async_to_generator(function(ctx, next) {
73
+ var req, res, bypassUrl;
74
+ return _ts_generator(this, function(_state) {
75
+ req = ctx.req, res = ctx.res;
76
+ bypassUrl = typeof options.bypass === "function" ? options.bypass(req, res, options) : null;
77
+ if (typeof bypassUrl === "boolean") {
78
+ ctx.status = 404;
79
+ next();
80
+ } else if (typeof bypassUrl === "string") {
81
+ ctx.url = bypassUrl;
82
+ next();
83
+ } else {
84
+ middleware(req, res, next);
85
+ }
53
86
  return [
54
- 2,
55
- next()
87
+ 2
56
88
  ];
57
- }
58
- middleware(req, res, next);
59
- return [
60
- 2
61
- ];
89
+ });
62
90
  });
63
- });
64
- return function(ctx, next) {
65
- return _ref.apply(this, arguments);
66
- };
67
- }();
68
- });
69
- return middlewares;
91
+ return function handler2(ctx, next) {
92
+ return _ref.apply(this, arguments);
93
+ };
94
+ }();
95
+ middlewares.push(middleware);
96
+ handlers.push(handler);
97
+ };
98
+ for (var _iterator = formattedOptionsList[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)
99
+ _loop();
100
+ } catch (err) {
101
+ _didIteratorError = true;
102
+ _iteratorError = err;
103
+ } finally {
104
+ try {
105
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
106
+ _iterator.return();
107
+ }
108
+ } finally {
109
+ if (_didIteratorError) {
110
+ throw _iteratorError;
111
+ }
112
+ }
113
+ }
114
+ return {
115
+ handlers: handlers,
116
+ handleUpgrade: handleUpgrade
117
+ };
70
118
  };