@modern-js/prod-server 2.29.0 → 2.31.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @modern-js/prod-server
2
2
 
3
+ ## 2.31.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 56eaa0b: fix(prod-server): the app maybe undefined, when use renderHtml
8
+ fix(prod-server): 当使用 renderHtml 时,app 可能是个 undefined
9
+ - d9cc4d8: fix: the issue when set more than two cookie
10
+ fix: 修复设置多余两个 cookie 时的问题
11
+ - Updated dependencies [1882366]
12
+ - @modern-js/utils@2.31.0
13
+ - @modern-js/server-core@2.31.0
14
+ - @modern-js/plugin@2.31.0
15
+
16
+ ## 2.30.0
17
+
18
+ ### Minor Changes
19
+
20
+ - a5ee81a: feat(server): add new server hooks `beforeServerInit` & `afterServerInit`
21
+ feat(server): 添加新的服务端钩子 `beforeServerInit` & `afterServerInit`
22
+
23
+ ### Patch Changes
24
+
25
+ - 9f21f28: fix(server): add catch and imporve url parse logic in modern server
26
+ fix(server): 在 modern server 中优化 url 解析逻辑并添加错误捕获并
27
+ - 883692c: fix: can't proxy WebSocket without the initial http request
28
+ fix: WebSocket 代理只能在首次 http 请求后生效
29
+ - b6ab299: fix(prod-server): remove req bodyParser, let uesr parses body by themself.
30
+ fix(prod-server): 移除 req bodyParser, 让用户自行解析 body
31
+ - Updated dependencies [a5ee81a]
32
+ - @modern-js/server-core@2.30.0
33
+ - @modern-js/utils@2.30.0
34
+ - @modern-js/plugin@2.30.0
35
+
3
36
  ## 2.29.0
4
37
 
5
38
  ### Minor Changes
@@ -28,8 +28,12 @@ class ModernServerContext {
28
28
  return this.req.metrics;
29
29
  }
30
30
  get parsedURL() {
31
- const url = new _url.URL(this.req.url, MOCK_URL_BASE);
32
- 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
+ }
33
37
  }
34
38
  bind() {
35
39
  const { req, res } = this;
@@ -31,7 +31,7 @@ class BaseResponse {
31
31
  this.res.statusCode = code;
32
32
  }
33
33
  setCookie(key, value, options) {
34
- const cookieValue = String(this.res.getHeader("set-cookie") || "");
34
+ const cookieValue = this.res.getHeader("set-cookie") || "";
35
35
  const fmt = Array.isArray(cookieValue) ? cookieValue : [
36
36
  cookieValue
37
37
  ].filter(Boolean);
@@ -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
  };
@@ -30,8 +30,7 @@ const render = async (ctx, renderOptions, runner) => {
30
30
  host: ctx.host,
31
31
  query: ctx.query,
32
32
  url: ctx.href,
33
- headers: ctx.headers,
34
- body: ctx.req.body
33
+ headers: ctx.headers
35
34
  },
36
35
  response: {
37
36
  setHeader: (key, value) => {
@@ -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
  /**
@@ -28,18 +28,17 @@ const SERVER_DIR = "./server";
28
28
  class ModernServer {
29
29
  // server prepare
30
30
  async onInit(runner, app) {
31
- var _conf_bff, _app, _this_conf_output;
31
+ var _conf_bff, _app, _app1, _this_conf_output;
32
32
  this.runner = runner;
33
33
  const { distDir, conf } = this;
34
34
  this.initReader();
35
35
  (0, _utils1.debug)("final server conf", this.conf);
36
- this.proxyHandler = (0, _proxy.createProxyHandler)((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy);
37
- if (this.proxyHandler) {
38
- this.proxyHandler.forEach((handler) => {
39
- this.addHandler(handler);
40
- });
41
- }
42
- (_app = app) === null || _app === void 0 ? void 0 : _app.on("close", () => {
36
+ const proxyHandlers = (0, _proxy.createProxyHandler)((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy);
37
+ (_app = app) === null || _app === void 0 ? void 0 : _app.on("upgrade", proxyHandlers.handleUpgrade);
38
+ proxyHandlers.handlers.forEach((handler) => {
39
+ this.addHandler(handler);
40
+ });
41
+ (_app1 = app) === null || _app1 === void 0 ? void 0 : _app1.on("close", () => {
43
42
  this.reader.close();
44
43
  });
45
44
  const usageRoutes = this.filterRoutes(this.getRoutes());
@@ -280,7 +279,7 @@ class ModernServer {
280
279
  /* —————————————————————— private function —————————————————————— */
281
280
  // handler route.json, include api / csr / ssr
282
281
  async routeHandler(context) {
283
- const { res, req, reporter } = context;
282
+ const { res, reporter } = context;
284
283
  const matched = this.router.match(context.path);
285
284
  if (!matched) {
286
285
  this.render404(context);
@@ -299,7 +298,6 @@ class ModernServer {
299
298
  await this.handleAPI(context);
300
299
  return;
301
300
  }
302
- await (0, _utils1.bodyParser)(req);
303
301
  if (route.entryName) {
304
302
  const afterMatchContext = (0, _hookapi.createAfterMatchContext)(context, route.entryName);
305
303
  if (this.runMode === _constants.RUN_MODE.FULL) {
@@ -493,7 +491,6 @@ class ModernServer {
493
491
  _define_property._(this, "loaderHandler", null);
494
492
  _define_property._(this, "frameWebHandler", null);
495
493
  _define_property._(this, "frameAPIHandler", null);
496
- _define_property._(this, "proxyHandler", null);
497
494
  _define_property._(this, "_handler", void 0);
498
495
  require("ignore-styles");
499
496
  this.pwd = pwd;
package/dist/cjs/utils.js CHANGED
@@ -36,9 +36,6 @@ _export(exports, {
36
36
  },
37
37
  isRedirect: function() {
38
38
  return isRedirect;
39
- },
40
- bodyParser: function() {
41
- return bodyParser;
42
39
  }
43
40
  });
44
41
  const _utils = require("@modern-js/utils");
@@ -162,33 +159,3 @@ const isRedirect = (code) => {
162
159
  308
163
160
  ].includes(code);
164
161
  };
165
- function parseBodyTypes(headers, body) {
166
- switch (headers["content-type"]) {
167
- case "application/json":
168
- return JSON.parse(body);
169
- default:
170
- return body;
171
- }
172
- }
173
- const getRequestBody = (req) => new Promise((resolve, reject) => {
174
- var _req;
175
- if (((_req = req) === null || _req === void 0 ? void 0 : _req.method) && req.method.toLowerCase() !== "get") {
176
- let body = "";
177
- req.on("data", (chunk) => {
178
- body += chunk.toString();
179
- });
180
- req.on("end", () => {
181
- resolve(parseBodyTypes(req.headers, body));
182
- });
183
- req.on("error", (err) => {
184
- reject(err);
185
- });
186
- } else {
187
- resolve(void 0);
188
- }
189
- });
190
- const bodyParser = async (req) => {
191
- if (!req.body) {
192
- req.body = await getRequestBody(req);
193
- }
194
- };
@@ -46,8 +46,12 @@ export var ModernServerContext = /* @__PURE__ */ function() {
46
46
  {
47
47
  key: "parsedURL",
48
48
  get: function get() {
49
- var url = new URL(this.req.url, MOCK_URL_BASE);
50
- 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
+ }
51
55
  }
52
56
  },
53
57
  {
@@ -37,7 +37,7 @@ export var BaseResponse = /* @__PURE__ */ function() {
37
37
  {
38
38
  key: "setCookie",
39
39
  value: function setCookie(key, value, options) {
40
- var cookieValue = String(this.res.getHeader("set-cookie") || "");
40
+ var cookieValue = this.res.getHeader("set-cookie") || "";
41
41
  var fmt = Array.isArray(cookieValue) ? cookieValue : [
42
42
  cookieValue
43
43
  ].filter(Boolean);
@@ -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
  };
@@ -25,8 +25,7 @@ export var render = function() {
25
25
  host: ctx.host,
26
26
  query: ctx.query,
27
27
  url: ctx.href,
28
- headers: ctx.headers,
29
- body: ctx.req.body
28
+ headers: ctx.headers
30
29
  },
31
30
  response: {
32
31
  setHeader: function(key, value) {
@@ -54,7 +54,7 @@ export var Server = /* @__PURE__ */ function() {
54
54
  }, _ref_disableHttpServer = _ref.disableHttpServer, disableHttpServer = _ref_disableHttpServer === void 0 ? false : _ref_disableHttpServer;
55
55
  var _this = this;
56
56
  return _async_to_generator(function() {
57
- var options;
57
+ var options, result, ref, ref1, result1, ref2, ref3;
58
58
  return _ts_generator(this, function(_state) {
59
59
  switch (_state.label) {
60
60
  case 0:
@@ -112,10 +112,30 @@ export var Server = /* @__PURE__ */ function() {
112
112
  case 8:
113
113
  return [
114
114
  4,
115
- _this.server.onInit(_this.runner, _this.app)
115
+ _this.runner.beforeServerInit({
116
+ app: _this.app,
117
+ server: _this.server
118
+ })
116
119
  ];
117
120
  case 9:
121
+ result = _state.sent();
122
+ ref = result, ref1 = ref.app, _this.app = ref1 === void 0 ? _this.app : ref1, _this.server = ref.server, ref;
123
+ return [
124
+ 4,
125
+ _this.server.onInit(_this.runner, _this.app)
126
+ ];
127
+ case 10:
118
128
  _state.sent();
129
+ return [
130
+ 4,
131
+ _this.runner.afterServerInit({
132
+ app: _this.app,
133
+ server: _this.server
134
+ })
135
+ ];
136
+ case 11:
137
+ result1 = _state.sent();
138
+ ref2 = result1, ref3 = ref2.app, _this.app = ref3 === void 0 ? _this.app : ref3, _this.server = ref2.server, ref2;
119
139
  return [
120
140
  2,
121
141
  _this
@@ -12,7 +12,7 @@ import { time } from "@modern-js/utils/universal/time";
12
12
  import { RouteMatchManager } from "../libs/route";
13
13
  import { createRenderHandler } from "../libs/render";
14
14
  import { createStaticFileHandler, faviconFallbackHandler } from "../libs/serveFile";
15
- import { createErrorDocument, createMiddlewareCollecter, getStaticReg, mergeExtension, noop, debug, isRedirect, bodyParser } from "../utils";
15
+ import { createErrorDocument, createMiddlewareCollecter, getStaticReg, mergeExtension, noop, debug, isRedirect } from "../utils";
16
16
  import * as reader from "../libs/render/reader";
17
17
  import { createProxyHandler } from "../libs/proxy";
18
18
  import { createContext } from "../libs/context";
@@ -44,7 +44,6 @@ export var ModernServer = /* @__PURE__ */ function() {
44
44
  _define_property(this, "loaderHandler", null);
45
45
  _define_property(this, "frameWebHandler", null);
46
46
  _define_property(this, "frameAPIHandler", null);
47
- _define_property(this, "proxyHandler", null);
48
47
  _define_property(this, "_handler", void 0);
49
48
  require("ignore-styles");
50
49
  this.pwd = pwd;
@@ -69,7 +68,7 @@ export var ModernServer = /* @__PURE__ */ function() {
69
68
  function onInit(runner, app) {
70
69
  var _this = this;
71
70
  return _async_to_generator(function() {
72
- var _conf_bff, _app, _this_conf_output, distDir, conf, usageRoutes;
71
+ var _conf_bff, _app, _app1, _this_conf_output, distDir, conf, proxyHandlers, usageRoutes;
73
72
  return _ts_generator(this, function(_state) {
74
73
  switch (_state.label) {
75
74
  case 0:
@@ -77,13 +76,12 @@ export var ModernServer = /* @__PURE__ */ function() {
77
76
  distDir = _this.distDir, conf = _this.conf;
78
77
  _this.initReader();
79
78
  debug("final server conf", _this.conf);
80
- _this.proxyHandler = createProxyHandler((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy);
81
- if (_this.proxyHandler) {
82
- _this.proxyHandler.forEach(function(handler) {
83
- _this.addHandler(handler);
84
- });
85
- }
86
- (_app = app) === null || _app === void 0 ? void 0 : _app.on("close", function() {
79
+ proxyHandlers = createProxyHandler((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy);
80
+ (_app = app) === null || _app === void 0 ? void 0 : _app.on("upgrade", proxyHandlers.handleUpgrade);
81
+ proxyHandlers.handlers.forEach(function(handler) {
82
+ _this.addHandler(handler);
83
+ });
84
+ (_app1 = app) === null || _app1 === void 0 ? void 0 : _app1.on("close", function() {
87
85
  _this.reader.close();
88
86
  });
89
87
  usageRoutes = _this.filterRoutes(_this.getRoutes());
@@ -669,11 +667,11 @@ export var ModernServer = /* @__PURE__ */ function() {
669
667
  function routeHandler(context) {
670
668
  var _this = this;
671
669
  return _async_to_generator(function() {
672
- var res, req, reporter, matched, end, route, afterMatchContext, end1, cost, _afterMatchContext_router, current, url, status, matched1, middlewareContext, end2, cost1, renderResult, responseStream, response, afterRenderContext, end3, cost2;
670
+ var res, reporter, matched, end, route, afterMatchContext, end1, cost, _afterMatchContext_router, current, url, status, matched1, middlewareContext, end2, cost1, renderResult, responseStream, response, afterRenderContext, end3, cost2;
673
671
  return _ts_generator(this, function(_state) {
674
672
  switch (_state.label) {
675
673
  case 0:
676
- res = context.res, req = context.req, reporter = context.reporter;
674
+ res = context.res, reporter = context.reporter;
677
675
  matched = _this.router.match(context.path);
678
676
  if (!matched) {
679
677
  _this.render404(context);
@@ -710,22 +708,16 @@ export var ModernServer = /* @__PURE__ */ function() {
710
708
  2
711
709
  ];
712
710
  case 3:
713
- return [
714
- 4,
715
- bodyParser(req)
716
- ];
717
- case 4:
718
- _state.sent();
719
711
  if (!route.entryName)
720
712
  return [
721
713
  3,
722
- 7
714
+ 6
723
715
  ];
724
716
  afterMatchContext = createAfterMatchContext(context, route.entryName);
725
717
  if (!(_this.runMode === RUN_MODE.FULL))
726
718
  return [
727
719
  3,
728
- 6
720
+ 5
729
721
  ];
730
722
  end1 = time();
731
723
  return [
@@ -734,12 +726,12 @@ export var ModernServer = /* @__PURE__ */ function() {
734
726
  onLast: noop
735
727
  })
736
728
  ];
737
- case 5:
729
+ case 4:
738
730
  _state.sent();
739
731
  cost = end1();
740
732
  reporter.reportTiming("server_hook_after_render", cost);
741
- _state.label = 6;
742
- case 6:
733
+ _state.label = 5;
734
+ case 5:
743
735
  if (_this.isSend(res)) {
744
736
  return [
745
737
  2
@@ -762,12 +754,12 @@ export var ModernServer = /* @__PURE__ */ function() {
762
754
  }
763
755
  route = matched1.generate(context.url);
764
756
  }
765
- _state.label = 7;
766
- case 7:
757
+ _state.label = 6;
758
+ case 6:
767
759
  if (!_this.frameWebHandler)
768
760
  return [
769
761
  3,
770
- 9
762
+ 8
771
763
  ];
772
764
  res.locals = res.locals || {};
773
765
  middlewareContext = createMiddlewareContext(context);
@@ -776,7 +768,7 @@ export var ModernServer = /* @__PURE__ */ function() {
776
768
  4,
777
769
  _this.frameWebHandler(middlewareContext)
778
770
  ];
779
- case 8:
771
+ case 7:
780
772
  _state.sent();
781
773
  cost1 = end2();
782
774
  reporter.reportTiming("server_middleware", cost1);
@@ -786,13 +778,13 @@ export var ModernServer = /* @__PURE__ */ function() {
786
778
  2
787
779
  ];
788
780
  }
789
- _state.label = 9;
790
- case 9:
781
+ _state.label = 8;
782
+ case 8:
791
783
  return [
792
784
  4,
793
785
  _this.handleWeb(context, route)
794
786
  ];
795
- case 10:
787
+ case 9:
796
788
  renderResult = _state.sent();
797
789
  if (!renderResult) {
798
790
  return [
@@ -810,13 +802,13 @@ export var ModernServer = /* @__PURE__ */ function() {
810
802
  if (!route.entryName)
811
803
  return [
812
804
  3,
813
- 13
805
+ 12
814
806
  ];
815
807
  afterRenderContext = createAfterRenderContext(context, response.toString());
816
808
  if (!(_this.runMode === RUN_MODE.FULL))
817
809
  return [
818
810
  3,
819
- 12
811
+ 11
820
812
  ];
821
813
  end3 = time();
822
814
  return [
@@ -825,20 +817,20 @@ export var ModernServer = /* @__PURE__ */ function() {
825
817
  onLast: noop
826
818
  })
827
819
  ];
828
- case 11:
820
+ case 10:
829
821
  _state.sent();
830
822
  cost2 = end3();
831
823
  reporter.reportTiming("server_hook_after_render", cost2);
832
- _state.label = 12;
833
- case 12:
824
+ _state.label = 11;
825
+ case 11:
834
826
  if (_this.isSend(res)) {
835
827
  return [
836
828
  2
837
829
  ];
838
830
  }
839
831
  response = afterRenderContext.template.get();
840
- _state.label = 13;
841
- case 13:
832
+ _state.label = 12;
833
+ case 12:
842
834
  res.end(response);
843
835
  return [
844
836
  2
package/dist/esm/utils.js CHANGED
@@ -1,7 +1,5 @@
1
- import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
1
  import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
3
2
  import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
4
- import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
5
3
  import { createDebugger } from "@modern-js/utils";
6
4
  export var debug = createDebugger("prod-server");
7
5
  export var mergeExtension = function(users) {
@@ -92,58 +90,3 @@ export var isRedirect = function(code) {
92
90
  308
93
91
  ].includes(code);
94
92
  };
95
- function parseBodyTypes(headers, body) {
96
- switch (headers["content-type"]) {
97
- case "application/json":
98
- return JSON.parse(body);
99
- default:
100
- return body;
101
- }
102
- }
103
- var getRequestBody = function(req) {
104
- return new Promise(function(resolve, reject) {
105
- var _req;
106
- if (((_req = req) === null || _req === void 0 ? void 0 : _req.method) && req.method.toLowerCase() !== "get") {
107
- var body = "";
108
- req.on("data", function(chunk) {
109
- body += chunk.toString();
110
- });
111
- req.on("end", function() {
112
- resolve(parseBodyTypes(req.headers, body));
113
- });
114
- req.on("error", function(err) {
115
- reject(err);
116
- });
117
- } else {
118
- resolve(void 0);
119
- }
120
- });
121
- };
122
- export var bodyParser = function() {
123
- var _ref = _async_to_generator(function(req) {
124
- return _ts_generator(this, function(_state) {
125
- switch (_state.label) {
126
- case 0:
127
- if (!!req.body)
128
- return [
129
- 3,
130
- 2
131
- ];
132
- return [
133
- 4,
134
- getRequestBody(req)
135
- ];
136
- case 1:
137
- req.body = _state.sent();
138
- _state.label = 2;
139
- case 2:
140
- return [
141
- 2
142
- ];
143
- }
144
- });
145
- });
146
- return function bodyParser2(req) {
147
- return _ref.apply(this, arguments);
148
- };
149
- }();
@@ -17,8 +17,12 @@ export class ModernServerContext {
17
17
  return this.req.metrics;
18
18
  }
19
19
  get parsedURL() {
20
- const url = new URL(this.req.url, MOCK_URL_BASE);
21
- return url;
20
+ try {
21
+ return new URL(this.req.url, MOCK_URL_BASE);
22
+ } catch (e) {
23
+ this.logger.error("Parse URL error", e.stack || e.message);
24
+ return new URL("/_modern_mock_path", MOCK_URL_BASE);
25
+ }
22
26
  }
23
27
  bind() {
24
28
  const { req, res } = this;
@@ -11,7 +11,7 @@ export class BaseResponse {
11
11
  this.res.statusCode = code;
12
12
  }
13
13
  setCookie(key, value, options) {
14
- const cookieValue = String(this.res.getHeader("set-cookie") || "");
14
+ const cookieValue = this.res.getHeader("set-cookie") || "";
15
15
  const fmt = Array.isArray(cookieValue) ? cookieValue : [
16
16
  cookieValue
17
17
  ].filter(Boolean);
@@ -26,24 +26,42 @@ export function formatProxyOptions(proxyOptions) {
26
26
  }
27
27
  export const createProxyHandler = (proxyOptions) => {
28
28
  debug("createProxyHandler", proxyOptions);
29
+ const middlewares = [];
30
+ const handlers = [];
31
+ const handleUpgrade = (req, socket, head) => {
32
+ for (const middleware of middlewares) {
33
+ if (typeof middleware.upgrade === "function") {
34
+ middleware.upgrade(req, socket, head);
35
+ }
36
+ }
37
+ };
29
38
  if (!proxyOptions) {
30
- return null;
39
+ return {
40
+ handlers,
41
+ handleUpgrade
42
+ };
31
43
  }
32
- const formattedProxy = formatProxyOptions(proxyOptions);
33
- const middlewares = formattedProxy.map((option) => {
34
- const middleware = createProxyMiddleware(option.context, option);
35
- return async (ctx, next) => {
44
+ const formattedOptionsList = formatProxyOptions(proxyOptions);
45
+ for (const options of formattedOptionsList) {
46
+ const middleware = createProxyMiddleware(options.context, options);
47
+ const handler = async (ctx, next) => {
36
48
  const { req, res } = ctx;
37
- const bypassUrl = typeof option.bypass === "function" ? option.bypass(req, res, option) : null;
49
+ const bypassUrl = typeof options.bypass === "function" ? options.bypass(req, res, options) : null;
38
50
  if (typeof bypassUrl === "boolean") {
39
51
  ctx.status = 404;
40
- return next();
52
+ next();
41
53
  } else if (typeof bypassUrl === "string") {
42
54
  ctx.url = bypassUrl;
43
- return next();
55
+ next();
56
+ } else {
57
+ middleware(req, res, next);
44
58
  }
45
- middleware(req, res, next);
46
59
  };
47
- });
48
- return middlewares;
60
+ middlewares.push(middleware);
61
+ handlers.push(handler);
62
+ }
63
+ return {
64
+ handlers,
65
+ handleUpgrade
66
+ };
49
67
  };
@@ -19,8 +19,7 @@ export const render = async (ctx, renderOptions, runner) => {
19
19
  host: ctx.host,
20
20
  query: ctx.query,
21
21
  url: ctx.href,
22
- headers: ctx.headers,
23
- body: ctx.req.body
22
+ headers: ctx.headers
24
23
  },
25
24
  response: {
26
25
  setHeader: (key, value) => {
@@ -36,7 +36,21 @@ export class Server {
36
36
  if (!disableHttpServer) {
37
37
  this.app = await this.server.createHTTPServer(this.getRequestHandler());
38
38
  }
39
+ {
40
+ const result = await this.runner.beforeServerInit({
41
+ app: this.app,
42
+ server: this.server
43
+ });
44
+ ({ app: this.app = this.app, server: this.server } = result);
45
+ }
39
46
  await this.server.onInit(this.runner, this.app);
47
+ {
48
+ const result = await this.runner.afterServerInit({
49
+ app: this.app,
50
+ server: this.server
51
+ });
52
+ ({ app: this.app = this.app, server: this.server } = result);
53
+ }
40
54
  return this;
41
55
  }
42
56
  /**
@@ -6,7 +6,7 @@ import { time } from "@modern-js/utils/universal/time";
6
6
  import { RouteMatchManager } from "../libs/route";
7
7
  import { createRenderHandler } from "../libs/render";
8
8
  import { createStaticFileHandler, faviconFallbackHandler } from "../libs/serveFile";
9
- import { createErrorDocument, createMiddlewareCollecter, getStaticReg, mergeExtension, noop, debug, isRedirect, bodyParser } from "../utils";
9
+ import { createErrorDocument, createMiddlewareCollecter, getStaticReg, mergeExtension, noop, debug, isRedirect } from "../utils";
10
10
  import * as reader from "../libs/render/reader";
11
11
  import { createProxyHandler } from "../libs/proxy";
12
12
  import { createContext } from "../libs/context";
@@ -16,18 +16,17 @@ const SERVER_DIR = "./server";
16
16
  export class ModernServer {
17
17
  // server prepare
18
18
  async onInit(runner, app) {
19
- var _conf_bff, _app, _this_conf_output;
19
+ var _conf_bff, _app, _app1, _this_conf_output;
20
20
  this.runner = runner;
21
21
  const { distDir, conf } = this;
22
22
  this.initReader();
23
23
  debug("final server conf", this.conf);
24
- this.proxyHandler = createProxyHandler((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy);
25
- if (this.proxyHandler) {
26
- this.proxyHandler.forEach((handler) => {
27
- this.addHandler(handler);
28
- });
29
- }
30
- (_app = app) === null || _app === void 0 ? void 0 : _app.on("close", () => {
24
+ const proxyHandlers = createProxyHandler((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy);
25
+ (_app = app) === null || _app === void 0 ? void 0 : _app.on("upgrade", proxyHandlers.handleUpgrade);
26
+ proxyHandlers.handlers.forEach((handler) => {
27
+ this.addHandler(handler);
28
+ });
29
+ (_app1 = app) === null || _app1 === void 0 ? void 0 : _app1.on("close", () => {
31
30
  this.reader.close();
32
31
  });
33
32
  const usageRoutes = this.filterRoutes(this.getRoutes());
@@ -268,7 +267,7 @@ export class ModernServer {
268
267
  /* —————————————————————— private function —————————————————————— */
269
268
  // handler route.json, include api / csr / ssr
270
269
  async routeHandler(context) {
271
- const { res, req, reporter } = context;
270
+ const { res, reporter } = context;
272
271
  const matched = this.router.match(context.path);
273
272
  if (!matched) {
274
273
  this.render404(context);
@@ -287,7 +286,6 @@ export class ModernServer {
287
286
  await this.handleAPI(context);
288
287
  return;
289
288
  }
290
- await bodyParser(req);
291
289
  if (route.entryName) {
292
290
  const afterMatchContext = createAfterMatchContext(context, route.entryName);
293
291
  if (this.runMode === RUN_MODE.FULL) {
@@ -481,7 +479,6 @@ export class ModernServer {
481
479
  _define_property(this, "loaderHandler", null);
482
480
  _define_property(this, "frameWebHandler", null);
483
481
  _define_property(this, "frameAPIHandler", null);
484
- _define_property(this, "proxyHandler", null);
485
482
  _define_property(this, "_handler", void 0);
486
483
  require("ignore-styles");
487
484
  this.pwd = pwd;
@@ -119,33 +119,3 @@ export const isRedirect = (code) => {
119
119
  308
120
120
  ].includes(code);
121
121
  };
122
- function parseBodyTypes(headers, body) {
123
- switch (headers["content-type"]) {
124
- case "application/json":
125
- return JSON.parse(body);
126
- default:
127
- return body;
128
- }
129
- }
130
- const getRequestBody = (req) => new Promise((resolve, reject) => {
131
- var _req;
132
- if (((_req = req) === null || _req === void 0 ? void 0 : _req.method) && req.method.toLowerCase() !== "get") {
133
- let body = "";
134
- req.on("data", (chunk) => {
135
- body += chunk.toString();
136
- });
137
- req.on("end", () => {
138
- resolve(parseBodyTypes(req.headers, body));
139
- });
140
- req.on("error", (err) => {
141
- reject(err);
142
- });
143
- } else {
144
- resolve(void 0);
145
- }
146
- });
147
- export const bodyParser = async (req) => {
148
- if (!req.body) {
149
- req.body = await getRequestBody(req);
150
- }
151
- };
@@ -2,7 +2,7 @@
2
2
  /// <reference types="node" />
3
3
  /// <reference types="node" />
4
4
  /// <reference types="node/http" />
5
- /// <reference types=".dts-temp/rFczrZA4GO714tUiIeLuz/src/type" />
5
+ /// <reference types=".dts-temp/GWYELZ4kWR3lwdimqb5Eh/src/type" />
6
6
  import { IncomingMessage, ServerResponse } from 'http';
7
7
  import qs from 'querystring';
8
8
  import type { ModernServerContext as ModernServerContextInterface, Reporter as ModernServerReporter, ServerTiming as ModernServerTiming } from '@modern-js/types';
@@ -1,4 +1,11 @@
1
- import { ProxyDetail, NextFunction, BffProxyOptions, ModernServerContext } from '@modern-js/types';
1
+ /// <reference types="node" />
2
+ import { RequestHandler } from 'http-proxy-middleware';
3
+ import { ProxyDetail, BffProxyOptions } from '@modern-js/types';
4
+ import type { ModernServerHandler } from '../type';
2
5
  export type { BffProxyOptions };
3
6
  export declare function formatProxyOptions(proxyOptions: BffProxyOptions): ProxyDetail[];
4
- export declare const createProxyHandler: (proxyOptions?: BffProxyOptions) => ((ctx: ModernServerContext, next: NextFunction) => Promise<void>)[] | null;
7
+ export type HttpUpgradeHandler = NonNullable<RequestHandler['upgrade']>;
8
+ export declare const createProxyHandler: (proxyOptions?: BffProxyOptions) => {
9
+ handlers: ModernServerHandler[];
10
+ handleUpgrade: (req: import("http-proxy-middleware/dist/types").Request, socket: import("net").Socket, head: any) => void;
11
+ };
@@ -30,7 +30,6 @@ export declare class ModernServer implements ModernServerInterface {
30
30
  private loaderHandler;
31
31
  private frameWebHandler;
32
32
  private frameAPIHandler;
33
- private proxyHandler;
34
33
  private _handler;
35
34
  constructor({
36
35
  pwd,
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node/http" />
3
- /// <reference types=".dts-temp/rFczrZA4GO714tUiIeLuz/src/type" />
3
+ /// <reference types=".dts-temp/GWYELZ4kWR3lwdimqb5Eh/src/type" />
4
4
  import { IncomingMessage } from 'http';
5
5
  import type { OutputNormalizedConfig, HtmlNormalizedConfig } from '@modern-js/server-core';
6
6
  export declare const debug: any;
@@ -21,5 +21,4 @@ export declare const createMiddlewareCollecter: () => {
21
21
  export declare const getStaticReg: (output?: OutputNormalizedConfig, html?: HtmlNormalizedConfig, prefix?: string) => RegExp;
22
22
  export declare const prepareFavicons: (favicon: string | undefined, faviconByEntries?: Record<string, string | undefined>) => string[];
23
23
  export declare const headersWithoutCookie: (headers: IncomingMessage['headers']) => import("http").IncomingHttpHeaders;
24
- export declare const isRedirect: (code: number) => boolean;
25
- export declare const bodyParser: (req: IncomingMessage) => Promise<void>;
24
+ export declare const isRedirect: (code: number) => boolean;
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.29.0",
18
+ "version": "2.31.0",
19
19
  "jsnext:source": "./src/index.ts",
20
20
  "types": "./dist/types/index.d.ts",
21
21
  "main": "./dist/cjs/index.js",
@@ -73,9 +73,9 @@
73
73
  "path-to-regexp": "^6.2.0",
74
74
  "serve-static": "^1.14.1",
75
75
  "@swc/helpers": "0.5.1",
76
- "@modern-js/utils": "2.29.0",
77
- "@modern-js/server-core": "2.29.0",
78
- "@modern-js/plugin": "2.29.0"
76
+ "@modern-js/server-core": "2.31.0",
77
+ "@modern-js/plugin": "2.31.0",
78
+ "@modern-js/utils": "2.31.0"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@types/cookie": "^0.4.1",
@@ -92,10 +92,12 @@
92
92
  "portfinder": "^1.0.28",
93
93
  "typescript": "^5",
94
94
  "memfs": "^3.5.1",
95
- "@modern-js/types": "2.29.0",
96
- "@modern-js/server-core": "2.29.0",
97
- "@scripts/jest-config": "2.29.0",
98
- "@scripts/build": "2.29.0"
95
+ "ws": "^8.13.0",
96
+ "@types/ws": "^8.5.5",
97
+ "@modern-js/types": "2.31.0",
98
+ "@modern-js/server-core": "2.31.0",
99
+ "@scripts/jest-config": "2.31.0",
100
+ "@scripts/build": "2.31.0"
99
101
  },
100
102
  "sideEffects": false,
101
103
  "publishConfig": {