@modern-js/prod-server 1.21.2 → 2.0.0-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.
- package/CHANGELOG.md +47 -0
- package/dist/js/modern/libs/hook-api/index.js +156 -0
- package/dist/js/modern/libs/hook-api/route.js +14 -29
- package/dist/js/modern/libs/hook-api/template.js +43 -4
- package/dist/js/modern/libs/render/cache/index.js +33 -16
- package/dist/js/modern/libs/render/measure.js +8 -1
- package/dist/js/modern/libs/render/ssr.js +20 -7
- package/dist/js/modern/libs/serve-file.js +8 -0
- package/dist/js/modern/server/index.js +9 -3
- package/dist/js/modern/server/modern-server-split.js +5 -44
- package/dist/js/modern/server/modern-server.js +140 -130
- package/dist/js/node/libs/hook-api/index.js +178 -0
- package/dist/js/node/libs/hook-api/route.js +14 -29
- package/dist/js/node/libs/hook-api/template.js +48 -4
- package/dist/js/node/libs/render/cache/index.js +34 -16
- package/dist/js/node/libs/render/measure.js +7 -0
- package/dist/js/node/libs/render/ssr.js +20 -7
- package/dist/js/node/libs/serve-file.js +12 -1
- package/dist/js/node/server/index.js +8 -2
- package/dist/js/node/server/modern-server-split.js +5 -45
- package/dist/js/node/server/modern-server.js +140 -132
- package/dist/types/libs/hook-api/index.d.ts +5 -0
- package/dist/types/libs/hook-api/route.d.ts +9 -14
- package/dist/types/libs/hook-api/template.d.ts +19 -9
- package/dist/types/libs/render/cache/index.d.ts +4 -2
- package/dist/types/libs/render/type.d.ts +3 -1
- package/dist/types/libs/serve-file.d.ts +2 -1
- package/dist/types/server/index.d.ts +2 -0
- package/dist/types/server/modern-server.d.ts +11 -11
- package/dist/types/type.d.ts +8 -10
- package/package.json +9 -32
|
@@ -15,18 +15,16 @@ import { createServer } from 'http';
|
|
|
15
15
|
import util from 'util';
|
|
16
16
|
import path from 'path';
|
|
17
17
|
import { fs, mime, ROUTE_SPEC_FILE } from '@modern-js/utils';
|
|
18
|
-
import axios from 'axios';
|
|
19
|
-
import { clone } from '@modern-js/utils/lodash';
|
|
20
18
|
import { RouteMatchManager } from "../libs/route";
|
|
21
19
|
import { createRenderHandler } from "../libs/render";
|
|
22
|
-
import { createStaticFileHandler } from "../libs/serve-file";
|
|
20
|
+
import { createStaticFileHandler, faviconFallbackHandler } from "../libs/serve-file";
|
|
23
21
|
import { createErrorDocument, createMiddlewareCollecter, getStaticReg, mergeExtension, noop, debug, isRedirect } from "../utils";
|
|
24
22
|
import * as reader from "../libs/render/reader";
|
|
25
23
|
import { createProxyHandler } from "../libs/proxy";
|
|
26
24
|
import { createContext } from "../libs/context";
|
|
25
|
+
import { templateInjectableStream } from "../libs/hook-api/template";
|
|
27
26
|
import { AGGRED_DIR, ERROR_DIGEST, ERROR_PAGE_TEXT, RUN_MODE } from "../constants";
|
|
28
|
-
import {
|
|
29
|
-
import { createRouteAPI } from "../libs/hook-api/route";
|
|
27
|
+
import { createAfterMatchContext, createAfterRenderContext, createMiddlewareContext } from "../libs/hook-api";
|
|
30
28
|
const API_DIR = './api';
|
|
31
29
|
const SERVER_DIR = './server';
|
|
32
30
|
export class ModernServer {
|
|
@@ -75,6 +73,8 @@ export class ModernServer {
|
|
|
75
73
|
|
|
76
74
|
_defineProperty(this, "routeRenderHandler", void 0);
|
|
77
75
|
|
|
76
|
+
_defineProperty(this, "beforeRouteHandler", null);
|
|
77
|
+
|
|
78
78
|
_defineProperty(this, "frameWebHandler", null);
|
|
79
79
|
|
|
80
80
|
_defineProperty(this, "frameAPIHandler", null);
|
|
@@ -98,8 +98,7 @@ export class ModernServer {
|
|
|
98
98
|
this.presetRoutes = routes;
|
|
99
99
|
this.proxyTarget = proxyTarget;
|
|
100
100
|
this.staticGenerate = staticGenerate || false;
|
|
101
|
-
this.runMode = runMode || RUN_MODE.
|
|
102
|
-
process.env.BUILD_TYPE = `${this.staticGenerate ? 'ssg' : 'ssr'}`;
|
|
101
|
+
this.runMode = runMode || RUN_MODE.FULL; // process.env.BUILD_TYPE = `${this.staticGenerate ? 'ssg' : 'ssr'}`;
|
|
103
102
|
} // server prepare
|
|
104
103
|
|
|
105
104
|
|
|
@@ -132,7 +131,8 @@ export class ModernServer {
|
|
|
132
131
|
this.router.reset(usageRoutes); // warmup ssr bundle in production env
|
|
133
132
|
|
|
134
133
|
this.warmupSSRBundle();
|
|
135
|
-
await this.prepareFrameHandler();
|
|
134
|
+
await this.prepareFrameHandler();
|
|
135
|
+
await this.prepareBeforeRouteHandler(usageRoutes, distDir); // Only work when without setting `assetPrefix`.
|
|
136
136
|
// Setting `assetPrefix` means these resources should be uploaded to CDN.
|
|
137
137
|
|
|
138
138
|
const staticPathRegExp = getStaticReg(this.conf.output || {});
|
|
@@ -145,7 +145,10 @@ export class ModernServer {
|
|
|
145
145
|
staticGenerate
|
|
146
146
|
});
|
|
147
147
|
await this.setupBeforeProdMiddleware();
|
|
148
|
-
this.addHandler(this.staticFileHandler);
|
|
148
|
+
this.addHandler(this.staticFileHandler); // execute after staticFileHandler, can rename to staticFallbackHandler if needed.
|
|
149
|
+
|
|
150
|
+
this.addHandler(faviconFallbackHandler);
|
|
151
|
+
this.addBeforeRouteHandler();
|
|
149
152
|
this.addHandler(this.routeHandler.bind(this)); // compose middlewares to http handler
|
|
150
153
|
|
|
151
154
|
this.compose();
|
|
@@ -155,6 +158,21 @@ export class ModernServer {
|
|
|
155
158
|
onRepack(_) {// empty
|
|
156
159
|
}
|
|
157
160
|
|
|
161
|
+
addBeforeRouteHandler() {
|
|
162
|
+
this.addHandler(async (context, next) => {
|
|
163
|
+
if (this.beforeRouteHandler) {
|
|
164
|
+
await this.beforeRouteHandler(context);
|
|
165
|
+
|
|
166
|
+
if (this.isSend(context.res)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
} // eslint-disable-next-line consistent-return
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
return next();
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
158
176
|
onServerChange({
|
|
159
177
|
filepath
|
|
160
178
|
}) {
|
|
@@ -180,6 +198,26 @@ export class ModernServer {
|
|
|
180
198
|
return this.requestHandler.bind(this);
|
|
181
199
|
}
|
|
182
200
|
|
|
201
|
+
async render(req, res, url) {
|
|
202
|
+
req.logger = this.logger;
|
|
203
|
+
req.metrics = this.metrics;
|
|
204
|
+
const context = createContext(req, res);
|
|
205
|
+
const matched = this.router.match(url || context.path);
|
|
206
|
+
|
|
207
|
+
if (!matched) {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const route = matched.generate(context.url);
|
|
212
|
+
const result = await this.handleWeb(context, route);
|
|
213
|
+
|
|
214
|
+
if (!result) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return result.content.toString();
|
|
219
|
+
}
|
|
220
|
+
|
|
183
221
|
async createHTTPServer(handler) {
|
|
184
222
|
return createServer(handler);
|
|
185
223
|
}
|
|
@@ -218,6 +256,19 @@ export class ModernServer {
|
|
|
218
256
|
render404(context) {
|
|
219
257
|
context.error(ERROR_DIGEST.ENOTF, '404 Not Found');
|
|
220
258
|
this.renderErrorPage(context, 404);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async prepareBeforeRouteHandler(specs, distDir) {
|
|
262
|
+
const {
|
|
263
|
+
runner
|
|
264
|
+
} = this;
|
|
265
|
+
const handler = await runner.preparebeforeRouteHandler({
|
|
266
|
+
serverRoutes: specs,
|
|
267
|
+
distDir
|
|
268
|
+
}, {
|
|
269
|
+
onLast: () => null
|
|
270
|
+
});
|
|
271
|
+
this.beforeRouteHandler = handler;
|
|
221
272
|
} // gather frame extension and get framework handler
|
|
222
273
|
|
|
223
274
|
|
|
@@ -261,12 +312,13 @@ export class ModernServer {
|
|
|
261
312
|
workDir,
|
|
262
313
|
runner
|
|
263
314
|
} = this;
|
|
264
|
-
|
|
315
|
+
const handler = await runner.prepareWebServer({
|
|
265
316
|
pwd: workDir,
|
|
266
317
|
config: extension
|
|
267
318
|
}, {
|
|
268
319
|
onLast: () => null
|
|
269
320
|
});
|
|
321
|
+
return handler;
|
|
270
322
|
}
|
|
271
323
|
|
|
272
324
|
async prepareAPIHandler(extension) {
|
|
@@ -292,13 +344,6 @@ export class ModernServer {
|
|
|
292
344
|
return routes;
|
|
293
345
|
}
|
|
294
346
|
|
|
295
|
-
async emitRouteHook(eventName, input) {
|
|
296
|
-
input.context = clone(input.context);
|
|
297
|
-
return this.runner[eventName](input, {
|
|
298
|
-
onLast: noop
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
|
|
302
347
|
async setupBeforeProdMiddleware() {
|
|
303
348
|
const {
|
|
304
349
|
conf,
|
|
@@ -357,51 +402,70 @@ export class ModernServer {
|
|
|
357
402
|
|
|
358
403
|
async routeHandler(context) {
|
|
359
404
|
const {
|
|
360
|
-
req,
|
|
361
405
|
res
|
|
362
|
-
} = context;
|
|
363
|
-
await this.emitRouteHook('beforeMatch', {
|
|
364
|
-
context
|
|
365
|
-
}); // match routes in the route spec
|
|
406
|
+
} = context; // match routes in the route spec
|
|
366
407
|
|
|
367
408
|
const matched = this.router.match(context.path);
|
|
368
409
|
|
|
369
410
|
if (!matched) {
|
|
370
411
|
this.render404(context);
|
|
371
412
|
return;
|
|
372
|
-
}
|
|
413
|
+
} // route is api service
|
|
373
414
|
|
|
374
|
-
|
|
415
|
+
|
|
416
|
+
let route = matched.generate(context.url);
|
|
417
|
+
|
|
418
|
+
if (route.isApi) {
|
|
419
|
+
await this.handleAPI(context);
|
|
375
420
|
return;
|
|
376
421
|
}
|
|
377
422
|
|
|
378
|
-
const
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
423
|
+
const afterMatchContext = createAfterMatchContext(context, route.entryName); // only full mode run server hook
|
|
424
|
+
|
|
425
|
+
if (this.runMode === RUN_MODE.FULL) {
|
|
426
|
+
await this.runner.afterMatch(afterMatchContext, {
|
|
427
|
+
onLast: noop
|
|
428
|
+
});
|
|
429
|
+
}
|
|
383
430
|
|
|
384
431
|
if (this.isSend(res)) {
|
|
385
432
|
return;
|
|
386
433
|
}
|
|
387
434
|
|
|
388
435
|
const {
|
|
389
|
-
current
|
|
390
|
-
|
|
391
|
-
|
|
436
|
+
current,
|
|
437
|
+
url,
|
|
438
|
+
status
|
|
439
|
+
} = afterMatchContext.router; // redirect to another url
|
|
440
|
+
|
|
441
|
+
if (url) {
|
|
442
|
+
this.redirect(res, url, status);
|
|
443
|
+
return;
|
|
444
|
+
} // rewrite to another entry
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
if (route.entryName !== current) {
|
|
448
|
+
const matched = this.router.matchEntry(current);
|
|
449
|
+
|
|
450
|
+
if (!matched) {
|
|
451
|
+
this.render404(context);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
route = matched.generate(context.url);
|
|
456
|
+
}
|
|
457
|
+
|
|
392
458
|
context.setParams(route.params);
|
|
393
459
|
context.setServerData('router', {
|
|
394
460
|
baseUrl: route.urlPath,
|
|
395
461
|
params: route.params
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
if (route.isApi) {
|
|
399
|
-
await this.handleAPI(context);
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
462
|
+
});
|
|
402
463
|
|
|
403
464
|
if (this.frameWebHandler) {
|
|
404
|
-
|
|
465
|
+
res.locals = res.locals || {};
|
|
466
|
+
const middlewareContext = createMiddlewareContext(context);
|
|
467
|
+
await this.frameWebHandler(middlewareContext);
|
|
468
|
+
res.locals = _objectSpread(_objectSpread({}, res.locals), middlewareContext.response.locals);
|
|
405
469
|
} // frameWebHandler has process request
|
|
406
470
|
|
|
407
471
|
|
|
@@ -419,23 +483,16 @@ export class ModernServer {
|
|
|
419
483
|
});
|
|
420
484
|
}
|
|
421
485
|
|
|
422
|
-
|
|
423
|
-
await this.emitRouteHook('beforeRender', {
|
|
424
|
-
context
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
const file = await this.handleWeb(context, route);
|
|
486
|
+
const renderResult = await this.handleWeb(context, route);
|
|
429
487
|
|
|
430
|
-
if (!
|
|
488
|
+
if (!renderResult) {
|
|
431
489
|
this.render404(context);
|
|
432
490
|
return;
|
|
433
|
-
}
|
|
491
|
+
} // React Router navigation
|
|
434
492
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
res.end();
|
|
493
|
+
|
|
494
|
+
if (renderResult.redirect) {
|
|
495
|
+
this.redirect(res, renderResult.content, renderResult.statusCode);
|
|
439
496
|
return;
|
|
440
497
|
}
|
|
441
498
|
|
|
@@ -443,29 +500,42 @@ export class ModernServer {
|
|
|
443
500
|
return;
|
|
444
501
|
}
|
|
445
502
|
|
|
446
|
-
|
|
503
|
+
res.setHeader('content-type', renderResult.contentType);
|
|
504
|
+
const {
|
|
505
|
+
contentStream
|
|
506
|
+
} = renderResult;
|
|
507
|
+
|
|
508
|
+
if (contentStream) {
|
|
509
|
+
contentStream.pipe(templateInjectableStream({
|
|
510
|
+
prependHead: route.entryName ? `<script>window._SERVER_DATA=${JSON.stringify(context.serverData)}</script>` : undefined
|
|
511
|
+
})).pipe(res);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
let response = renderResult.content;
|
|
447
516
|
|
|
448
517
|
if (route.entryName) {
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
context,
|
|
452
|
-
templateAPI
|
|
453
|
-
});
|
|
518
|
+
const afterRenderContext = createAfterRenderContext(context, response.toString()); // only full mode run server hook
|
|
519
|
+
// FIXME: how to run server hook in streaming
|
|
454
520
|
|
|
455
|
-
if (this.
|
|
456
|
-
|
|
521
|
+
if (this.runMode === RUN_MODE.FULL) {
|
|
522
|
+
await this.runner.afterRender(afterRenderContext, {
|
|
523
|
+
onLast: noop
|
|
524
|
+
});
|
|
457
525
|
}
|
|
458
526
|
|
|
459
|
-
|
|
527
|
+
if (this.isSend(res)) {
|
|
528
|
+
return;
|
|
529
|
+
} // It will inject _SERVER_DATA twice, when SSG mode.
|
|
460
530
|
// The first time was in ssg html created, the seoncd time was in prod-server start.
|
|
461
531
|
// but the second wound causes route error.
|
|
462
532
|
// To ensure that the second injection fails, the _SERVER_DATA inject at the front of head,
|
|
463
533
|
|
|
464
|
-
|
|
465
|
-
|
|
534
|
+
|
|
535
|
+
afterRenderContext.template.prependHead(`<script>window._SERVER_DATA=${JSON.stringify(context.serverData)}</script>`);
|
|
536
|
+
response = afterRenderContext.template.get();
|
|
466
537
|
}
|
|
467
538
|
|
|
468
|
-
res.setHeader('content-type', file.contentType);
|
|
469
539
|
res.end(response);
|
|
470
540
|
}
|
|
471
541
|
|
|
@@ -480,72 +550,6 @@ export class ModernServer {
|
|
|
480
550
|
}
|
|
481
551
|
|
|
482
552
|
return false;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
async injectMicroFE(context, templateAPI) {
|
|
486
|
-
var _conf$runtime, _conf$server;
|
|
487
|
-
|
|
488
|
-
const {
|
|
489
|
-
conf
|
|
490
|
-
} = this;
|
|
491
|
-
const masterApp = (_conf$runtime = conf.runtime) === null || _conf$runtime === void 0 ? void 0 : _conf$runtime.masterApp; // no inject if not master App
|
|
492
|
-
|
|
493
|
-
if (!masterApp) {
|
|
494
|
-
return;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
const manifest = masterApp.manifest || {};
|
|
498
|
-
let modules = [];
|
|
499
|
-
const {
|
|
500
|
-
modules: configModules = []
|
|
501
|
-
} = manifest; // while config modules is an string, fetch data from remote
|
|
502
|
-
|
|
503
|
-
if (typeof configModules === 'string') {
|
|
504
|
-
const moduleRequestUrl = configModules;
|
|
505
|
-
|
|
506
|
-
try {
|
|
507
|
-
const {
|
|
508
|
-
data: remoteModules
|
|
509
|
-
} = await axios.get(moduleRequestUrl);
|
|
510
|
-
|
|
511
|
-
if (Array.isArray(remoteModules)) {
|
|
512
|
-
modules.push(...remoteModules);
|
|
513
|
-
}
|
|
514
|
-
} catch (e) {
|
|
515
|
-
context.error(ERROR_DIGEST.EMICROINJ, e);
|
|
516
|
-
}
|
|
517
|
-
} else if (Array.isArray(configModules)) {
|
|
518
|
-
modules.push(...configModules);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
const {
|
|
522
|
-
headers
|
|
523
|
-
} = context.req;
|
|
524
|
-
const debugName = headers['x-micro-frontend-module-name'] || context.query['__debug__micro-frontend-module-name'];
|
|
525
|
-
const debugEntry = headers['x-micro-frontend-module-entry'] || context.query['__debug__micro-frontend-module-entry']; // add debug micro App to first
|
|
526
|
-
|
|
527
|
-
if (debugName && debugEntry && (_conf$server = conf.server) !== null && _conf$server !== void 0 && _conf$server.enableMicroFrontendDebug) {
|
|
528
|
-
modules = modules.map(m => {
|
|
529
|
-
if (m.name === debugName) {
|
|
530
|
-
return {
|
|
531
|
-
name: debugName,
|
|
532
|
-
entry: debugEntry
|
|
533
|
-
};
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
return m;
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
try {
|
|
541
|
-
// Todo Safety xss
|
|
542
|
-
const injection = JSON.stringify(_objectSpread(_objectSpread({}, manifest), {}, {
|
|
543
|
-
modules
|
|
544
|
-
}));
|
|
545
|
-
templateAPI.appendHead(`<script>window.modern_manifest=${injection}</script>`);
|
|
546
|
-
} catch (e) {
|
|
547
|
-
context.error(ERROR_DIGEST.EMICROINJ, e);
|
|
548
|
-
}
|
|
549
553
|
} // compose handlers and create the final handler
|
|
550
554
|
|
|
551
555
|
|
|
@@ -612,6 +616,12 @@ export class ModernServer {
|
|
|
612
616
|
}
|
|
613
617
|
}
|
|
614
618
|
|
|
619
|
+
redirect(res, url, status = 302) {
|
|
620
|
+
res.setHeader('Location', url);
|
|
621
|
+
res.statusCode = status;
|
|
622
|
+
res.end();
|
|
623
|
+
}
|
|
624
|
+
|
|
615
625
|
onError(context, err) {
|
|
616
626
|
context.error(ERROR_DIGEST.EINTER, err);
|
|
617
627
|
this.renderErrorPage(context, 500);
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createMiddlewareContext = exports.createAfterRenderContext = exports.createAfterMatchContext = exports.base = void 0;
|
|
7
|
+
|
|
8
|
+
var _cookie = _interopRequireDefault(require("cookie"));
|
|
9
|
+
|
|
10
|
+
var _route = require("./route");
|
|
11
|
+
|
|
12
|
+
var _template = require("./template");
|
|
13
|
+
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
|
|
16
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
17
|
+
|
|
18
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
19
|
+
|
|
20
|
+
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; }
|
|
21
|
+
|
|
22
|
+
class Response {
|
|
23
|
+
constructor(res) {
|
|
24
|
+
_defineProperty(this, "cookies", void 0);
|
|
25
|
+
|
|
26
|
+
_defineProperty(this, "res", void 0);
|
|
27
|
+
|
|
28
|
+
_defineProperty(this, "_cookie", void 0);
|
|
29
|
+
|
|
30
|
+
this.res = res;
|
|
31
|
+
this._cookie = _cookie.default.parse(res.getHeader('set-cookie') || '');
|
|
32
|
+
this.cookies = {
|
|
33
|
+
get: this.getCookie.bind(this),
|
|
34
|
+
set: this.setCookie.bind(this),
|
|
35
|
+
delete: this.deleteCookie.bind(this),
|
|
36
|
+
clear: this.clearCookie.bind(this),
|
|
37
|
+
apply: this.applyCookie.bind(this)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get(key) {
|
|
42
|
+
return this.res.getHeader(key);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
set(key, value) {
|
|
46
|
+
return this.res.setHeader(key, value);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
status(code) {
|
|
50
|
+
this.res.statusCode = code;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getCookie(key) {
|
|
54
|
+
return this._cookie[key];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
setCookie(key, value) {
|
|
58
|
+
this._cookie[key] = value;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
deleteCookie(key) {
|
|
62
|
+
if (this._cookie[key]) {
|
|
63
|
+
delete this._cookie[key];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
clearCookie() {
|
|
68
|
+
this._cookie = {};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
applyCookie() {
|
|
72
|
+
const str = Object.entries(this._cookie).map(([key, value]) => {
|
|
73
|
+
return _cookie.default.serialize(key, value);
|
|
74
|
+
}).join('; ');
|
|
75
|
+
|
|
76
|
+
if (str) {
|
|
77
|
+
this.res.setHeader('set-cookie', str);
|
|
78
|
+
} else {
|
|
79
|
+
this.res.removeHeader('set-cookie');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
raw(body, {
|
|
84
|
+
status,
|
|
85
|
+
headers
|
|
86
|
+
}) {
|
|
87
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
88
|
+
this.res.setHeader(key, value);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (status) {
|
|
92
|
+
this.res.statusCode = status;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this.res.end(body);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
class Request {
|
|
101
|
+
constructor(ctx) {
|
|
102
|
+
_defineProperty(this, "host", void 0);
|
|
103
|
+
|
|
104
|
+
_defineProperty(this, "pathname", void 0);
|
|
105
|
+
|
|
106
|
+
_defineProperty(this, "query", void 0);
|
|
107
|
+
|
|
108
|
+
_defineProperty(this, "headers", void 0);
|
|
109
|
+
|
|
110
|
+
_defineProperty(this, "cookie", void 0);
|
|
111
|
+
|
|
112
|
+
_defineProperty(this, "cookies", void 0);
|
|
113
|
+
|
|
114
|
+
_defineProperty(this, "_cookie", void 0);
|
|
115
|
+
|
|
116
|
+
this.host = ctx.host;
|
|
117
|
+
this.pathname = ctx.path;
|
|
118
|
+
this.query = ctx.query;
|
|
119
|
+
this.headers = ctx.headers;
|
|
120
|
+
this.cookie = ctx.headers.cookie || '';
|
|
121
|
+
this._cookie = _cookie.default.parse(this.cookie);
|
|
122
|
+
this.cookies = {
|
|
123
|
+
get: this.getCookie.bind(this)
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
getCookie(key) {
|
|
128
|
+
return this._cookie[key];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const base = context => {
|
|
134
|
+
const {
|
|
135
|
+
res
|
|
136
|
+
} = context;
|
|
137
|
+
return {
|
|
138
|
+
response: new Response(res),
|
|
139
|
+
request: new Request(context),
|
|
140
|
+
logger: context.logger,
|
|
141
|
+
metrics: context.metrics
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
exports.base = base;
|
|
146
|
+
|
|
147
|
+
const createAfterMatchContext = (context, entryName) => {
|
|
148
|
+
const baseContext = base(context);
|
|
149
|
+
return _objectSpread(_objectSpread({}, baseContext), {}, {
|
|
150
|
+
router: new _route.RouteAPI(entryName)
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
exports.createAfterMatchContext = createAfterMatchContext;
|
|
155
|
+
|
|
156
|
+
const createAfterRenderContext = (context, content) => {
|
|
157
|
+
const baseContext = base(context);
|
|
158
|
+
return _objectSpread(_objectSpread({}, baseContext), {}, {
|
|
159
|
+
template: new _template.TemplateAPI(content)
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
exports.createAfterRenderContext = createAfterRenderContext;
|
|
164
|
+
|
|
165
|
+
const createMiddlewareContext = context => {
|
|
166
|
+
const baseContext = base(context);
|
|
167
|
+
return _objectSpread(_objectSpread({}, baseContext), {}, {
|
|
168
|
+
response: _objectSpread(_objectSpread({}, baseContext.response), {}, {
|
|
169
|
+
locals: context.res.locals || {}
|
|
170
|
+
}),
|
|
171
|
+
source: {
|
|
172
|
+
req: context.req,
|
|
173
|
+
res: context.res
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
exports.createMiddlewareContext = createMiddlewareContext;
|
|
@@ -3,51 +3,36 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.RouteAPI = void 0;
|
|
7
7
|
|
|
8
8
|
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; }
|
|
9
9
|
|
|
10
10
|
class RouteAPI {
|
|
11
|
-
constructor(
|
|
12
|
-
_defineProperty(this, "router", void 0);
|
|
13
|
-
|
|
11
|
+
constructor(entryName) {
|
|
14
12
|
_defineProperty(this, "current", void 0);
|
|
15
13
|
|
|
14
|
+
_defineProperty(this, "status", void 0);
|
|
15
|
+
|
|
16
16
|
_defineProperty(this, "url", void 0);
|
|
17
17
|
|
|
18
|
-
this.current =
|
|
19
|
-
this.
|
|
20
|
-
this.url =
|
|
18
|
+
this.current = entryName;
|
|
19
|
+
this.status = 200;
|
|
20
|
+
this.url = '';
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
redirect(url, status = 302) {
|
|
24
|
+
this.url = url;
|
|
25
|
+
this.status = status;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
router
|
|
30
|
-
} = this;
|
|
31
|
-
const matched = router.matchEntry(entryName);
|
|
32
|
-
return matched ? matched.generate(this.url) : null;
|
|
28
|
+
rewrite(entryName) {
|
|
29
|
+
this.current = entryName;
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
use(entryName) {
|
|
36
|
-
|
|
37
|
-
router
|
|
38
|
-
} = this;
|
|
39
|
-
const matched = router.matchEntry(entryName);
|
|
40
|
-
|
|
41
|
-
if (matched) {
|
|
42
|
-
this.current = matched;
|
|
43
|
-
return true;
|
|
44
|
-
} else {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
33
|
+
this.rewrite(entryName);
|
|
47
34
|
}
|
|
48
35
|
|
|
49
36
|
}
|
|
50
37
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
exports.createRouteAPI = createRouteAPI;
|
|
38
|
+
exports.RouteAPI = RouteAPI;
|