@modern-js/server 1.1.2 → 1.1.3-beta.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 (45) hide show
  1. package/dist/js/modern/libs/hook-api/route.js +37 -0
  2. package/dist/js/modern/libs/{hook-api.js → hook-api/template.js} +0 -0
  3. package/dist/js/modern/libs/route/index.js +4 -0
  4. package/dist/js/modern/libs/route/matcher.js +4 -0
  5. package/dist/js/modern/server/{web-server.js → dev-server/dev-server-split.js} +9 -7
  6. package/dist/js/modern/server/{dev-server.js → dev-server/dev-server.js} +41 -22
  7. package/dist/js/modern/server/dev-server/index.js +2 -0
  8. package/dist/js/modern/server/index.js +61 -62
  9. package/dist/js/modern/server/{api-server.js → modern-server-split.js} +6 -10
  10. package/dist/js/modern/server/modern-server.js +48 -20
  11. package/dist/js/modern/utils.js +2 -2
  12. package/dist/js/node/libs/hook-api/route.js +46 -0
  13. package/dist/js/node/libs/{hook-api.js → hook-api/template.js} +0 -0
  14. package/dist/js/node/libs/route/index.js +4 -0
  15. package/dist/js/node/libs/route/matcher.js +4 -0
  16. package/dist/js/node/server/{api-server.js → dev-server/dev-server-split.js} +7 -12
  17. package/dist/js/node/server/{dev-server.js → dev-server/dev-server.js} +42 -21
  18. package/dist/js/node/server/dev-server/index.js +27 -0
  19. package/dist/js/node/server/index.js +67 -63
  20. package/dist/js/node/server/{web-server.js → modern-server-split.js} +10 -9
  21. package/dist/js/node/server/modern-server.js +50 -20
  22. package/dist/js/node/utils.js +2 -2
  23. package/dist/types/libs/hook-api/route.d.ts +13 -0
  24. package/dist/types/libs/{hook-api.d.ts → hook-api/template.d.ts} +0 -0
  25. package/dist/types/libs/route/index.d.ts +1 -0
  26. package/dist/types/libs/route/matcher.d.ts +1 -0
  27. package/dist/types/server/{api-server.d.ts → dev-server/dev-server-split.d.ts} +7 -8
  28. package/dist/types/server/{dev-server.d.ts → dev-server/dev-server.d.ts} +6 -5
  29. package/dist/types/server/dev-server/index.d.ts +2 -0
  30. package/dist/types/server/index.d.ts +3 -1
  31. package/dist/types/server/{web-server.d.ts → modern-server-split.d.ts} +5 -4
  32. package/dist/types/server/modern-server.d.ts +6 -5
  33. package/dist/types/utils.d.ts +1 -1
  34. package/package.json +19 -17
  35. package/src/libs/hook-api/route.ts +38 -0
  36. package/src/libs/{hook-api.ts → hook-api/template.ts} +0 -0
  37. package/src/libs/route/index.ts +4 -0
  38. package/src/libs/route/matcher.ts +4 -0
  39. package/src/server/{api-server.ts → dev-server/dev-server-split.ts} +9 -11
  40. package/src/server/{dev-server.ts → dev-server/dev-server.ts} +56 -23
  41. package/src/server/dev-server/index.ts +2 -0
  42. package/src/server/index.ts +69 -46
  43. package/src/server/{web-server.ts → modern-server-split.ts} +12 -10
  44. package/src/server/modern-server.ts +54 -34
  45. package/src/utils.ts +2 -2
@@ -0,0 +1,37 @@
1
+ class RouteAPI {
2
+ constructor(matched, router) {
3
+ this.router = void 0;
4
+ this.current = void 0;
5
+ this.current = matched;
6
+ this.router = router;
7
+ }
8
+
9
+ cur() {
10
+ return this.current.generate();
11
+ }
12
+
13
+ get(entryName) {
14
+ const {
15
+ router
16
+ } = this;
17
+ const matched = router.matchEntry(entryName);
18
+ return matched ? matched.generate() : null;
19
+ }
20
+
21
+ use(entryName) {
22
+ const {
23
+ router
24
+ } = this;
25
+ const matched = router.matchEntry(entryName);
26
+
27
+ if (matched) {
28
+ this.current = matched;
29
+ return true;
30
+ } else {
31
+ return false;
32
+ }
33
+ }
34
+
35
+ }
36
+
37
+ export const createRouteAPI = (matched, router) => new RouteAPI(matched, router);
@@ -56,6 +56,10 @@ export class RouteMatchManager {
56
56
  return best;
57
57
  }
58
58
 
59
+ matchEntry(entryname) {
60
+ return this.matchers.find(matcher => matcher.matchEntry(entryname));
61
+ }
62
+
59
63
  getBundles() {
60
64
  const bundles = this.specs.filter(route => route.isSSR).map(route => route.bundle);
61
65
  return bundles;
@@ -57,6 +57,10 @@ export class RouteMatcher {
57
57
 
58
58
  return false;
59
59
  }
60
+ }
61
+
62
+ matchEntry(entryName) {
63
+ return this.spec.entryName === entryName;
60
64
  } // compiler urlPath to regexp if necessary
61
65
 
62
66
 
@@ -1,6 +1,5 @@
1
1
  import { ModernDevServer } from "./dev-server";
2
- import { ModernServer } from "./modern-server";
3
- export class WebModernServer extends ModernServer {
2
+ export class WebModernDevServer extends ModernDevServer {
4
3
  prepareAPIHandler(_m, _) {
5
4
  return null;
6
5
  }
@@ -14,17 +13,20 @@ export class WebModernServer extends ModernServer {
14
13
  }
15
14
 
16
15
  }
17
- export class WebModernDevServer extends ModernDevServer {
18
- prepareAPIHandler(_m, _) {
16
+ export class APIModernDevServer extends ModernDevServer {
17
+ prepareWebHandler(_) {
19
18
  return null;
20
19
  }
21
20
 
22
- async prepareWebHandler(extension) {
23
- return super.prepareWebHandler(extension);
21
+ async prepareAPIHandler(mode, extension) {
22
+ return super.prepareAPIHandler(mode, extension);
24
23
  }
25
24
 
26
25
  filterRoutes(routes) {
27
- return routes.filter(route => route.entryName);
26
+ return routes.filter(route => route.isApi);
27
+ }
28
+
29
+ async preServerInit() {// noop
28
30
  }
29
31
 
30
32
  }
@@ -1,16 +1,18 @@
1
+ import { createServer } from 'http';
1
2
  import path from 'path';
2
- import { HMR_SOCK_PATH } from '@modern-js/utils';
3
+ import { createServer as createHttpsServer } from 'https';
4
+ import { API_DIR, HMR_SOCK_PATH, SERVER_DIR, SHARED_DIR } from '@modern-js/utils';
3
5
  import webpackDevMiddleware from 'webpack-dev-middleware';
4
- import { createMockHandler } from "../dev-tools/mock";
5
- import { createProxyHandler } from "../libs/proxy";
6
- import SocketServer from "../dev-tools/socket-server";
7
- import DevServerPlugin from "../dev-tools/dev-server-plugin";
8
- import { createLaunchEditorHandler } from "../dev-tools/launch-editor";
9
- import { enableRegister } from "../dev-tools/babel/register";
10
- import * as reader from "../libs/render/reader";
11
- import Watcher from "../dev-tools/watcher";
12
- import { ModernServer } from "./modern-server";
13
- import { AGGRED_DIR } from "../constants";
6
+ import { ModernServer } from "../modern-server";
7
+ import { createMockHandler } from "../../dev-tools/mock";
8
+ import { createProxyHandler } from "../../libs/proxy";
9
+ import SocketServer from "../../dev-tools/socket-server";
10
+ import DevServerPlugin from "../../dev-tools/dev-server-plugin";
11
+ import { createLaunchEditorHandler } from "../../dev-tools/launch-editor";
12
+ import { enableRegister } from "../../dev-tools/babel/register";
13
+ import * as reader from "../../libs/render/reader";
14
+ import Watcher from "../../dev-tools/watcher";
15
+ import { AGGRED_DIR } from "../../constants";
14
16
  const DEFAULT_DEV_OPTIONS = {
15
17
  client: {
16
18
  port: '8080',
@@ -27,8 +29,8 @@ const DEFAULT_DEV_OPTIONS = {
27
29
  liveReload: true
28
30
  };
29
31
  export class ModernDevServer extends ModernServer {
30
- constructor(options, runner) {
31
- super(options, runner); // set webpack compiler
32
+ constructor(options) {
33
+ super(options); // set webpack compiler
32
34
 
33
35
  this.devProxyHandler = null;
34
36
  this.mockHandler = null;
@@ -40,18 +42,18 @@ export class ModernDevServer extends ModernServer {
40
42
  this.compiler = options.compiler; // set dev server options, like webpack-dev-server
41
43
 
42
44
  this.dev = typeof options.dev === 'boolean' ? DEFAULT_DEV_OPTIONS : options.dev;
45
+ enableRegister(this.pwd, this.conf);
43
46
  } // Complete the preparation of services
44
47
 
45
48
 
46
- async init() {
49
+ async init(runner) {
47
50
  var _conf$tools, _conf$tools$devServer;
48
51
 
49
52
  const {
50
53
  conf,
51
54
  pwd,
52
55
  compiler
53
- } = this;
54
- enableRegister(pwd, conf); // mock handler
56
+ } = this; // mock handler
55
57
 
56
58
  this.mockHandler = createMockHandler({
57
59
  pwd
@@ -86,7 +88,7 @@ export class ModernDevServer extends ModernServer {
86
88
  this.addHandler(devMiddlewareHandler);
87
89
  }
88
90
 
89
- await super.init(); // watch mock/ server/ api/ dir file change
91
+ await super.init(runner); // watch mock/ server/ api/ dir file change
90
92
 
91
93
  this.startWatcher();
92
94
  }
@@ -97,6 +99,7 @@ export class ModernDevServer extends ModernServer {
97
99
  this.cleanSSRCache(); // reset static file
98
100
 
99
101
  reader.updateFile();
102
+ this.runner.reset();
100
103
  }
101
104
 
102
105
  onListening(app) {
@@ -113,6 +116,24 @@ export class ModernDevServer extends ModernServer {
113
116
  resolve();
114
117
  });
115
118
  });
119
+ }
120
+
121
+ async createHTTPServer(handler) {
122
+ const {
123
+ dev
124
+ } = this;
125
+ const devHttpsOption = typeof dev === 'object' && dev.https;
126
+
127
+ if (devHttpsOption) {
128
+ const {
129
+ genHttpsOptions
130
+ } = require("../../dev-tools/https");
131
+
132
+ const httpsOptions = await genHttpsOptions(devHttpsOption);
133
+ return createHttpsServer(httpsOptions, handler);
134
+ } else {
135
+ return createServer(handler);
136
+ }
116
137
  } // set up plugin to each compiler
117
138
  // register hooks for each compilation, update socket stats if recompiled
118
139
  // start dev middleware
@@ -207,18 +228,16 @@ export class ModernDevServer extends ModernServer {
207
228
  pwd
208
229
  } = this;
209
230
  const {
210
- mock,
211
- server,
212
- api,
213
- shared
231
+ mock
214
232
  } = AGGRED_DIR;
215
- const defaultWatched = [`${pwd}/${mock}/**/*`, `${pwd}/${server}/**/*`, `${pwd}/${api}/**/*`, `${pwd}/${shared}/**/*`];
233
+ const defaultWatched = [`${pwd}/${mock}/**/*`, `${pwd}/${SERVER_DIR}/**/*`, `${pwd}/${API_DIR}/**/*`, `${pwd}/${SHARED_DIR}/**/*`];
216
234
  const watcher = new Watcher();
217
235
  watcher.createDepTree(); // 监听文件变动,如果有变动则给 client,也就是 start 启动的插件发消息
218
236
 
219
237
  watcher.listen(defaultWatched, filepath => {
220
238
  watcher.updateDepTree();
221
239
  watcher.cleanDepCache(filepath);
240
+ this.runner.reset();
222
241
 
223
242
  if (filepath.startsWith(`${pwd}/${mock}`)) {
224
243
  this.mockHandler = createMockHandler({
@@ -0,0 +1,2 @@
1
+ export { APIModernDevServer, WebModernDevServer } from "./dev-server-split";
2
+ export { ModernDevServer } from "./dev-server";
@@ -1,21 +1,23 @@
1
- import { createServer } from 'http';
2
- import { createServer as createHttpsServer } from 'https';
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
2
+
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
4
+
5
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+
7
+ import path from 'path';
3
8
  import { serverManager } from '@modern-js/server-plugin';
4
9
  import { logger as defaultLogger } from '@modern-js/utils';
10
+ import { AppContext, initAppContext, initAppDir, loadUserConfig } from '@modern-js/core';
5
11
  import { ModernServer } from "./modern-server";
12
+ import { APIModernServer, WebModernServer } from "./modern-server-split";
6
13
  import { measure as defaultMeasure } from "../libs/measure";
7
14
  export class Server {
8
15
  constructor(options) {
9
- var _options$plugins;
10
-
11
16
  this.options = void 0;
12
17
  this.server = void 0;
13
18
  this.app = void 0;
14
19
  this.runner = void 0;
15
20
  this.options = options;
16
- (_options$plugins = options.plugins) === null || _options$plugins === void 0 ? void 0 : _options$plugins.forEach(p => {
17
- serverManager.usePlugin(p);
18
- });
19
21
  }
20
22
 
21
23
  getRequestHandler() {
@@ -33,40 +35,20 @@ export class Server {
33
35
  const {
34
36
  options
35
37
  } = this;
36
- this.runner = await serverManager.init({});
37
- const {
38
- logger,
39
- measure
40
- } = await this.runner.create({
41
- loggerOptions: options.logger,
42
- measureOptions: options.measure
43
- }, {
44
- onLast: () => ({})
45
- });
46
- options.logger = options.logger || logger || defaultLogger;
47
- options.measure = options.measure || measure || defaultMeasure;
38
+ options.logger = options.logger || defaultLogger;
39
+ options.measure = options.measure || defaultMeasure; // initialize server
48
40
 
49
41
  if (options.dev) {
50
- this.server = this.createDevServer(); // check if https is configured when start dev server
51
-
52
- const devHttpsOption = typeof options.dev === 'object' && options.dev.https;
53
-
54
- if (devHttpsOption) {
55
- const {
56
- genHttpsOptions
57
- } = require("../dev-tools/https");
58
-
59
- const httpsOptions = await genHttpsOptions(devHttpsOption);
60
- this.app = createHttpsServer(httpsOptions, this.getRequestHandler());
61
- } else {
62
- this.app = createServer(this.getRequestHandler());
63
- }
42
+ this.server = this.createDevServer();
64
43
  } else {
65
44
  this.server = this.createProdServer();
66
- this.app = createServer(this.getRequestHandler());
67
- }
45
+ } // check if https is configured when start dev server
68
46
 
69
- await this.server.init();
47
+
48
+ this.app = await this.server.createHTTPServer(this.getRequestHandler());
49
+ this.runner = await this.createHookRunner(); // runner can only be used after server init
50
+
51
+ await this.server.init(this.runner);
70
52
  return this;
71
53
  }
72
54
 
@@ -97,19 +79,11 @@ export class Server {
97
79
  } = this;
98
80
 
99
81
  if (options.apiOnly) {
100
- const {
101
- APIModernServer
102
- } = require("./api-server");
103
-
104
- return new APIModernServer(options, this.runner);
82
+ return new APIModernServer(options);
105
83
  } else if (options.webOnly) {
106
- const {
107
- WebModernServer
108
- } = require("./web-server");
109
-
110
- return new WebModernServer(options, this.runner);
84
+ return new WebModernServer(options);
111
85
  } else {
112
- return new ModernServer(options, this.runner);
86
+ return new ModernServer(options);
113
87
  }
114
88
  }
115
89
 
@@ -118,25 +92,50 @@ export class Server {
118
92
  options
119
93
  } = this;
120
94
 
121
- if (options.apiOnly) {
122
- const {
123
- APIModernDevServer
124
- } = require("./api-server");
95
+ const {
96
+ APIModernDevServer,
97
+ WebModernDevServer,
98
+ ModernDevServer
99
+ } = require("./dev-server");
125
100
 
126
- return new APIModernDevServer(options, this.runner);
101
+ if (options.apiOnly) {
102
+ return new APIModernDevServer(options);
127
103
  } else if (options.webOnly) {
128
- const {
129
- WebModernDevServer
130
- } = require("./web-server");
131
-
132
- return new WebModernDevServer(options, this.runner);
104
+ return new WebModernDevServer(options);
133
105
  } else {
134
- const {
135
- ModernDevServer
136
- } = require("./dev-server");
137
-
138
- return new ModernDevServer(options, this.runner);
106
+ return new ModernDevServer(options);
139
107
  }
140
108
  }
141
109
 
110
+ async createHookRunner() {
111
+ var _options$plugins;
112
+
113
+ const {
114
+ options
115
+ } = this;
116
+ const appContext = await this.initAppContext();
117
+ serverManager.run(() => {
118
+ AppContext.set(_objectSpread(_objectSpread({}, appContext), {}, {
119
+ distDirectory: path.join(options.pwd, options.config.output.path || 'dist')
120
+ }));
121
+ });
122
+ (_options$plugins = options.plugins) === null || _options$plugins === void 0 ? void 0 : _options$plugins.forEach(p => {
123
+ serverManager.usePlugin(p);
124
+ });
125
+ return serverManager.init({});
126
+ }
127
+
128
+ async initAppContext() {
129
+ var _this$options$plugins;
130
+
131
+ const appDirectory = await initAppDir();
132
+ const loaded = await loadUserConfig(appDirectory);
133
+ const plugins = (_this$options$plugins = this.options.plugins) === null || _this$options$plugins === void 0 ? void 0 : _this$options$plugins.map(p => ({
134
+ server: p,
135
+ cli: undefined
136
+ }));
137
+ const appContext = initAppContext(appDirectory, plugins || [], loaded.filePath);
138
+ return appContext;
139
+ }
140
+
142
141
  }
@@ -1,23 +1,19 @@
1
- import { ModernDevServer } from "./dev-server";
2
1
  import { ModernServer } from "./modern-server";
3
- export class APIModernServer extends ModernServer {
4
- prepareWebHandler(_) {
2
+ export class WebModernServer extends ModernServer {
3
+ prepareAPIHandler(_m, _) {
5
4
  return null;
6
5
  }
7
6
 
8
- async prepareAPIHandler(mode, extension) {
9
- return super.prepareAPIHandler(mode, extension);
7
+ async prepareWebHandler(extension) {
8
+ return super.prepareWebHandler(extension);
10
9
  }
11
10
 
12
11
  filterRoutes(routes) {
13
- return routes.filter(route => route.isApi);
14
- }
15
-
16
- async preServerInit() {// noop
12
+ return routes.filter(route => route.entryName);
17
13
  }
18
14
 
19
15
  }
20
- export class APIModernDevServer extends ModernDevServer {
16
+ export class APIModernServer extends ModernServer {
21
17
  prepareWebHandler(_) {
22
18
  return null;
23
19
  }
@@ -11,10 +11,11 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
11
11
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
12
12
 
13
13
  /* eslint-disable max-lines */
14
+ import { createServer } from 'http';
14
15
  import util from 'util';
15
16
  import path from 'path';
16
17
  import { fs, ROUTE_SPEC_FILE } from '@modern-js/utils';
17
- import { gather, createMiddlewareCollecter } from '@modern-js/server-utils';
18
+ import { createMiddlewareCollecter } from '@modern-js/server-utils';
18
19
  import mime from 'mime-types';
19
20
  import axios from 'axios';
20
21
  import { RouteMatchManager } from "../libs/route";
@@ -25,7 +26,8 @@ import * as reader from "../libs/render/reader";
25
26
  import { createProxyHandler } from "../libs/proxy";
26
27
  import { createContext } from "../libs/context";
27
28
  import { AGGRED_DIR, ApiServerMode, ERROR_DIGEST, ERROR_PAGE_TEXT } from "../constants";
28
- import { createTemplateAPI } from "../libs/hook-api";
29
+ import { createTemplateAPI } from "../libs/hook-api/template";
30
+ import { createRouteAPI } from "../libs/hook-api/route";
29
31
  const API_DIR = './api';
30
32
  const SERVER_DIR = './server';
31
33
  export class ModernServer {
@@ -40,7 +42,7 @@ export class ModernServer {
40
42
  staticGenerate,
41
43
  logger,
42
44
  measure
43
- }, runner) {
45
+ }) {
44
46
  this.pwd = void 0;
45
47
  this.distDir = void 0;
46
48
  this.workDir = void 0;
@@ -48,9 +50,9 @@ export class ModernServer {
48
50
  this.conf = void 0;
49
51
  this.handlers = [];
50
52
  this.presetRoutes = void 0;
53
+ this.runner = void 0;
51
54
  this.logger = void 0;
52
55
  this.measure = void 0;
53
- this.runner = void 0;
54
56
  this.isDev = false;
55
57
  this.staticFileHandler = void 0;
56
58
  this.routeRenderHandler = void 0;
@@ -67,7 +69,6 @@ export class ModernServer {
67
69
  this.distDir = path.join(pwd, config.output.path || '');
68
70
  this.workDir = this.isDev ? pwd : this.distDir;
69
71
  this.conf = config;
70
- this.runner = runner;
71
72
  this.logger = logger;
72
73
  this.measure = measure;
73
74
  this.router = new RouteMatchManager();
@@ -86,9 +87,10 @@ export class ModernServer {
86
87
  } // server prepare
87
88
 
88
89
 
89
- async init() {
90
+ async init(runner) {
90
91
  var _conf$bff;
91
92
 
93
+ this.runner = runner;
92
94
  const {
93
95
  distDir,
94
96
  isDev,
@@ -153,6 +155,10 @@ export class ModernServer {
153
155
 
154
156
  close() {
155
157
  reader.close();
158
+ }
159
+
160
+ async createHTTPServer(handler) {
161
+ return createServer(handler);
156
162
  } // warmup ssr function
157
163
 
158
164
 
@@ -200,12 +206,7 @@ export class ModernServer {
200
206
  const {
201
207
  workDir,
202
208
  runner
203
- } = this; // inner tool, gather user inject
204
-
205
- const {
206
- api: userAPIExt,
207
- web: userWebExt
208
- } = gather(workDir); // server hook, gather plugin inject
209
+ } = this; // server hook, gather plugin inject
209
210
 
210
211
  const _createMiddlewareColl = createMiddlewareCollecter(),
211
212
  {
@@ -222,15 +223,17 @@ export class ModernServer {
222
223
  const serverDir = path.join(workDir, SERVER_DIR); // get api or web server handler from server-framework plugin
223
224
 
224
225
  if (await fs.pathExists(path.join(serverDir))) {
225
- const webExtension = mergeExtension(pluginWebExt, userWebExt);
226
+ const webExtension = mergeExtension(pluginWebExt);
226
227
  this.frameWebHandler = await this.prepareWebHandler(webExtension);
227
228
  }
228
229
 
229
230
  if (fs.existsSync(apiDir)) {
230
231
  const mode = fs.existsSync(path.join(apiDir, AGGRED_DIR.lambda)) ? ApiServerMode.frame : ApiServerMode.func; // if use lambda/, mean framework style of writing, then discard user extension
231
232
 
232
- const apiExtension = mergeExtension(pluginAPIExt, mode === ApiServerMode.frame ? [] : userAPIExt);
233
- this.frameAPIHandler = await this.prepareAPIHandler(mode, apiExtension);
233
+ const apiExtension = mergeExtension(pluginAPIExt);
234
+ this.frameAPIHandler = await this.prepareAPIHandler(mode, _objectSpread(_objectSpread({}, apiExtension), {}, {
235
+ modernJsConfig: this.conf
236
+ }));
234
237
  }
235
238
  }
236
239
  /* —————————————————————— function will be overwrite —————————————————————— */
@@ -263,7 +266,7 @@ export class ModernServer {
263
266
  pwd: workDir,
264
267
  mode,
265
268
  config: extension,
266
- prefix
269
+ prefix: Array.isArray(prefix) ? prefix[0] : prefix
267
270
  }, {
268
271
  onLast: () => null
269
272
  });
@@ -278,7 +281,7 @@ export class ModernServer {
278
281
  conf
279
282
  } = this;
280
283
  const preMiddleware = await this.runner.preServerInit(conf);
281
- preMiddleware.forEach(mid => {
284
+ preMiddleware.flat().forEach(mid => {
282
285
  this.addHandler(mid);
283
286
  });
284
287
  }
@@ -311,7 +314,12 @@ export class ModernServer {
311
314
  const {
312
315
  req,
313
316
  res
314
- } = context; // match routes in the route spec
317
+ } = context;
318
+ await this.runner.beforeMatch({
319
+ context
320
+ }, {
321
+ onLast: noop
322
+ }); // match routes in the route spec
315
323
 
316
324
  const matched = this.router.match(context.url);
317
325
 
@@ -320,8 +328,23 @@ export class ModernServer {
320
328
  return;
321
329
  }
322
330
 
323
- const route = matched.generate();
324
- const params = matched.parseURLParams(context.url);
331
+ const routeAPI = createRouteAPI(matched, this.router);
332
+ await this.runner.afterMatch({
333
+ context,
334
+ routeAPI
335
+ }, {
336
+ onLast: noop
337
+ });
338
+
339
+ if (res.headersSent) {
340
+ return;
341
+ }
342
+
343
+ const {
344
+ current
345
+ } = routeAPI;
346
+ const route = current.generate();
347
+ const params = current.parseURLParams(context.url);
325
348
  context.setParams(params); // route is api service
326
349
 
327
350
  if (route.isApi) {
@@ -342,6 +365,11 @@ export class ModernServer {
342
365
  return;
343
366
  }
344
367
 
368
+ await this.runner.beforeRender({
369
+ context
370
+ }, {
371
+ onLast: noop
372
+ });
345
373
  const file = await this.routeRenderHandler(context, route);
346
374
 
347
375
  if (!file) {
@@ -1,7 +1,7 @@
1
- export const mergeExtension = (users, plugins) => {
1
+ export const mergeExtension = users => {
2
2
  const output = [];
3
3
  return {
4
- middleware: output.concat(users).concat(plugins)
4
+ middleware: output.concat(users)
5
5
  };
6
6
  };
7
7
  export const toMessage = (dig, e) => {
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createRouteAPI = void 0;
7
+
8
+ class RouteAPI {
9
+ constructor(matched, router) {
10
+ this.router = void 0;
11
+ this.current = void 0;
12
+ this.current = matched;
13
+ this.router = router;
14
+ }
15
+
16
+ cur() {
17
+ return this.current.generate();
18
+ }
19
+
20
+ get(entryName) {
21
+ const {
22
+ router
23
+ } = this;
24
+ const matched = router.matchEntry(entryName);
25
+ return matched ? matched.generate() : null;
26
+ }
27
+
28
+ use(entryName) {
29
+ const {
30
+ router
31
+ } = this;
32
+ const matched = router.matchEntry(entryName);
33
+
34
+ if (matched) {
35
+ this.current = matched;
36
+ return true;
37
+ } else {
38
+ return false;
39
+ }
40
+ }
41
+
42
+ }
43
+
44
+ const createRouteAPI = (matched, router) => new RouteAPI(matched, router);
45
+
46
+ exports.createRouteAPI = createRouteAPI;
@@ -64,6 +64,10 @@ class RouteMatchManager {
64
64
  return best;
65
65
  }
66
66
 
67
+ matchEntry(entryname) {
68
+ return this.matchers.find(matcher => matcher.matchEntry(entryname));
69
+ }
70
+
67
71
  getBundles() {
68
72
  const bundles = this.specs.filter(route => route.isSSR).map(route => route.bundle);
69
73
  return bundles;