@modern-js/server 1.1.3 → 1.1.5-beta.1
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 +19 -0
- package/dist/js/modern/dev-tools/babel/register.js +2 -2
- package/dist/js/modern/dev-tools/mock/getMockData.js +2 -2
- package/dist/js/modern/libs/context/context.js +15 -7
- package/dist/js/modern/libs/context/index.js +2 -2
- package/dist/js/modern/libs/{measure.js → metrics.js} +2 -2
- package/dist/js/modern/libs/proxy.js +2 -2
- package/dist/js/modern/libs/render/cache/__tests__/cache.test.js +2 -2
- package/dist/js/modern/libs/render/cache/index.js +2 -2
- package/dist/js/modern/libs/render/index.js +6 -2
- package/dist/js/modern/libs/render/ssr.js +3 -2
- package/dist/js/modern/libs/route/route.js +1 -1
- package/dist/js/modern/server/dev-server/dev-server-split.js +2 -6
- package/dist/js/modern/server/dev-server/dev-server.js +11 -2
- package/dist/js/modern/server/dev-server/index.js +1 -1
- package/dist/js/modern/server/index.js +17 -15
- package/dist/js/modern/server/modern-server-split.js +55 -6
- package/dist/js/modern/server/modern-server.js +96 -56
- package/dist/js/modern/utils.js +9 -1
- package/dist/js/node/dev-tools/babel/register.js +2 -2
- package/dist/js/node/dev-tools/mock/getMockData.js +2 -2
- package/dist/js/node/libs/context/context.js +15 -7
- package/dist/js/node/libs/context/index.js +2 -2
- package/dist/js/node/libs/{measure.js → metrics.js} +3 -3
- package/dist/js/node/libs/proxy.js +2 -2
- package/dist/js/node/libs/render/cache/__tests__/cache.test.js +2 -2
- package/dist/js/node/libs/render/cache/index.js +2 -2
- package/dist/js/node/libs/render/index.js +6 -2
- package/dist/js/node/libs/render/ssr.js +3 -2
- package/dist/js/node/libs/route/route.js +1 -1
- package/dist/js/node/server/dev-server/dev-server-split.js +5 -9
- package/dist/js/node/server/dev-server/dev-server.js +11 -2
- package/dist/js/node/server/dev-server/index.js +4 -4
- package/dist/js/node/server/index.js +16 -14
- package/dist/js/node/server/modern-server-split.js +61 -9
- package/dist/js/node/server/modern-server.js +97 -57
- package/dist/js/node/utils.js +12 -2
- package/dist/types/libs/context/context.d.ts +5 -5
- package/dist/types/libs/context/index.d.ts +3 -3
- package/dist/types/libs/metrics.d.ts +3 -0
- package/dist/types/libs/render/index.d.ts +10 -1
- package/dist/types/libs/render/ssr.d.ts +2 -1
- package/dist/types/libs/render/type.d.ts +2 -21
- package/dist/types/libs/route/route.d.ts +2 -10
- package/dist/types/server/dev-server/dev-server-split.d.ts +3 -4
- package/dist/types/server/dev-server/index.d.ts +1 -1
- package/dist/types/server/modern-server-split.d.ts +15 -5
- package/dist/types/server/modern-server.d.ts +14 -7
- package/dist/types/type.d.ts +11 -5
- package/dist/types/utils.d.ts +2 -1
- package/package.json +5 -5
- package/src/libs/context/context.ts +12 -8
- package/src/libs/context/index.ts +3 -3
- package/src/libs/{measure.ts → metrics.ts} +3 -3
- package/src/libs/render/index.ts +21 -11
- package/src/libs/render/ssr.ts +5 -1
- package/src/libs/render/type.ts +3 -16
- package/src/libs/route/route.ts +4 -20
- package/src/server/dev-server/dev-server-split.ts +3 -7
- package/src/server/dev-server/dev-server.ts +14 -12
- package/src/server/dev-server/index.ts +1 -1
- package/src/server/index.ts +21 -14
- package/src/server/modern-server-split.ts +59 -7
- package/src/server/modern-server.ts +109 -64
- package/src/type.ts +12 -5
- package/src/utils.ts +14 -0
- package/dist/types/libs/measure.d.ts +0 -3
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import { APIServerStartInput } from '@modern-js/server-plugin';
|
|
2
2
|
import { ModernServer } from './modern-server';
|
|
3
3
|
import { mergeExtension } from '@/utils';
|
|
4
|
-
import { ModernRouteInterface } from '@/libs/route';
|
|
4
|
+
import { ModernRoute, ModernRouteInterface, RouteMatcher } from '@/libs/route';
|
|
5
5
|
import { ApiServerMode } from '@/constants';
|
|
6
|
+
import { ModernServerContext } from '@/libs/context';
|
|
7
|
+
|
|
8
|
+
export class ModernSSRServer extends ModernServer {
|
|
9
|
+
// Todo should not invoke any route hook in modernSSRServer
|
|
10
|
+
|
|
11
|
+
protected async warmupSSRBundle() {
|
|
12
|
+
// empty
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
protected verifyMatch(context: ModernServerContext, matched: RouteMatcher) {
|
|
16
|
+
if (matched.generate().isApi) {
|
|
17
|
+
this.render404(context);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
6
20
|
|
|
7
|
-
export class WebModernServer extends ModernServer {
|
|
8
21
|
protected prepareAPIHandler(
|
|
9
22
|
_m: ApiServerMode,
|
|
10
|
-
_:
|
|
23
|
+
_: APIServerStartInput['config'],
|
|
11
24
|
) {
|
|
12
25
|
return null as any;
|
|
13
26
|
}
|
|
@@ -18,12 +31,24 @@ export class WebModernServer extends ModernServer {
|
|
|
18
31
|
return super.prepareWebHandler(extension);
|
|
19
32
|
}
|
|
20
33
|
|
|
21
|
-
protected filterRoutes(routes: ModernRouteInterface[]) {
|
|
22
|
-
|
|
34
|
+
// protected filterRoutes(routes: ModernRouteInterface[]) {
|
|
35
|
+
// return routes.filter(route => route.entryName);
|
|
36
|
+
// }
|
|
37
|
+
|
|
38
|
+
protected async preServerInit() {
|
|
39
|
+
// empty
|
|
23
40
|
}
|
|
24
41
|
}
|
|
25
42
|
|
|
26
|
-
export class
|
|
43
|
+
export class ModernAPIServer extends ModernServer {
|
|
44
|
+
protected async emitRouteHook(_: string, _input: any) {
|
|
45
|
+
// empty
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
protected async warmupSSRBundle() {
|
|
49
|
+
// empty
|
|
50
|
+
}
|
|
51
|
+
|
|
27
52
|
protected prepareWebHandler(_: ReturnType<typeof mergeExtension>) {
|
|
28
53
|
return null as any;
|
|
29
54
|
}
|
|
@@ -40,6 +65,33 @@ export class APIModernServer extends ModernServer {
|
|
|
40
65
|
}
|
|
41
66
|
|
|
42
67
|
protected async preServerInit() {
|
|
43
|
-
//
|
|
68
|
+
// empty
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export class ModernWebServer extends ModernServer {
|
|
73
|
+
protected async warmupSSRBundle() {
|
|
74
|
+
// empty
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
protected async handleAPI(context: ModernServerContext) {
|
|
78
|
+
const { proxyTarget } = this;
|
|
79
|
+
if (!proxyTarget?.api) {
|
|
80
|
+
this.proxy();
|
|
81
|
+
} else {
|
|
82
|
+
this.render404(context);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
protected async handleWeb(context: ModernServerContext, route: ModernRoute) {
|
|
87
|
+
const { proxyTarget } = this;
|
|
88
|
+
|
|
89
|
+
if (route.isSSR && proxyTarget?.ssr) {
|
|
90
|
+
return this.proxy();
|
|
91
|
+
} else {
|
|
92
|
+
// if no proxyTarget but access web server, degradation to csr
|
|
93
|
+
route.isSSR = false;
|
|
94
|
+
return super.handleWeb(context, route);
|
|
95
|
+
}
|
|
44
96
|
}
|
|
45
97
|
}
|
|
@@ -12,17 +12,22 @@ import {
|
|
|
12
12
|
ModernServerOptions,
|
|
13
13
|
NextFunction,
|
|
14
14
|
ServerHookRunner,
|
|
15
|
-
|
|
15
|
+
Metrics,
|
|
16
16
|
Logger,
|
|
17
17
|
ReadyOptions,
|
|
18
18
|
ConfWithBFF,
|
|
19
|
-
} from '
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
} from '@/type';
|
|
20
|
+
import {
|
|
21
|
+
RouteMatchManager,
|
|
22
|
+
ModernRouteInterface,
|
|
23
|
+
ModernRoute,
|
|
24
|
+
RouteMatcher,
|
|
25
|
+
} from '@/libs/route';
|
|
26
|
+
import { createRenderHandler } from '@/libs/render';
|
|
27
|
+
import { createStaticFileHandler } from '@/libs/serve-file';
|
|
28
|
+
import { createErrorDocument, mergeExtension, noop } from '@/utils';
|
|
29
|
+
import * as reader from '@/libs/render/reader';
|
|
30
|
+
import { createProxyHandler, ProxyOptions } from '@/libs/proxy';
|
|
26
31
|
import { createContext, ModernServerContext } from '@/libs/context';
|
|
27
32
|
import {
|
|
28
33
|
AGGRED_DIR,
|
|
@@ -68,7 +73,9 @@ export class ModernServer {
|
|
|
68
73
|
|
|
69
74
|
protected readonly logger: Logger;
|
|
70
75
|
|
|
71
|
-
protected readonly
|
|
76
|
+
protected readonly metrics: Metrics;
|
|
77
|
+
|
|
78
|
+
protected readonly proxyTarget: ModernServerOptions['proxyTarget'];
|
|
72
79
|
|
|
73
80
|
private readonly isDev: boolean = false;
|
|
74
81
|
|
|
@@ -93,19 +100,21 @@ export class ModernServer {
|
|
|
93
100
|
routes,
|
|
94
101
|
staticGenerate,
|
|
95
102
|
logger,
|
|
96
|
-
|
|
103
|
+
metrics,
|
|
104
|
+
proxyTarget,
|
|
97
105
|
}: ModernServerOptions) {
|
|
98
106
|
require('ignore-styles');
|
|
99
107
|
this.isDev = Boolean(dev);
|
|
100
108
|
|
|
101
109
|
this.pwd = pwd;
|
|
102
|
-
this.distDir = path.join(pwd, config.output.path || '');
|
|
110
|
+
this.distDir = path.join(pwd, config.output.path || 'dist');
|
|
103
111
|
this.workDir = this.isDev ? pwd : this.distDir;
|
|
104
112
|
this.conf = config;
|
|
105
113
|
this.logger = logger!;
|
|
106
|
-
this.
|
|
114
|
+
this.metrics = metrics!;
|
|
107
115
|
this.router = new RouteMatchManager();
|
|
108
116
|
this.presetRoutes = routes;
|
|
117
|
+
this.proxyTarget = proxyTarget;
|
|
109
118
|
|
|
110
119
|
if (staticGenerate) {
|
|
111
120
|
this.staticGenerate = staticGenerate;
|
|
@@ -207,18 +216,6 @@ export class ModernServer {
|
|
|
207
216
|
return createServer(handler);
|
|
208
217
|
}
|
|
209
218
|
|
|
210
|
-
// warmup ssr function
|
|
211
|
-
protected warmupSSRBundle() {
|
|
212
|
-
const { distDir } = this;
|
|
213
|
-
const bundles = this.router.getBundles();
|
|
214
|
-
|
|
215
|
-
bundles.forEach(bundle => {
|
|
216
|
-
const filepath = path.join(distDir, bundle!);
|
|
217
|
-
// if error, just throw and let process die
|
|
218
|
-
require(filepath);
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
|
|
222
219
|
// read route spec from route.json
|
|
223
220
|
protected readRouteSpec() {
|
|
224
221
|
const file = path.join(this.distDir, ROUTE_SPEC_FILE);
|
|
@@ -276,6 +273,11 @@ export class ModernServer {
|
|
|
276
273
|
}
|
|
277
274
|
}
|
|
278
275
|
|
|
276
|
+
// Todo
|
|
277
|
+
protected async proxy() {
|
|
278
|
+
return null as any;
|
|
279
|
+
}
|
|
280
|
+
|
|
279
281
|
/* —————————————————————— function will be overwrite —————————————————————— */
|
|
280
282
|
protected async prepareWebHandler(
|
|
281
283
|
extension: ReturnType<typeof mergeExtension>,
|
|
@@ -314,75 +316,93 @@ export class ModernServer {
|
|
|
314
316
|
return routes;
|
|
315
317
|
}
|
|
316
318
|
|
|
319
|
+
protected async emitRouteHook(
|
|
320
|
+
eventName: 'beforeMatch' | 'afterMatch' | 'beforeRender' | 'afterRender',
|
|
321
|
+
input: any,
|
|
322
|
+
) {
|
|
323
|
+
return this.runner[eventName](input, { onLast: noop as any });
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// warmup ssr function
|
|
327
|
+
protected warmupSSRBundle() {
|
|
328
|
+
const { distDir } = this;
|
|
329
|
+
const bundles = this.router.getBundles();
|
|
330
|
+
|
|
331
|
+
bundles.forEach(bundle => {
|
|
332
|
+
const filepath = path.join(distDir, bundle as string);
|
|
333
|
+
// if error, just throw and let process die
|
|
334
|
+
require(filepath);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
317
338
|
protected async preServerInit() {
|
|
318
|
-
const { conf } = this;
|
|
339
|
+
const { conf, runner } = this;
|
|
319
340
|
const preMiddleware: ModernServerAsyncHandler[] =
|
|
320
|
-
await
|
|
341
|
+
await runner.preServerInit(conf);
|
|
321
342
|
|
|
322
343
|
preMiddleware.flat().forEach(mid => {
|
|
323
344
|
this.addHandler(mid);
|
|
324
345
|
});
|
|
325
346
|
}
|
|
326
347
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
if (favicon) {
|
|
333
|
-
faviconNames.push(favicon.substring(favicon.lastIndexOf('/') + 1));
|
|
334
|
-
}
|
|
335
|
-
if (faviconByEntries) {
|
|
336
|
-
Object.keys(faviconByEntries).forEach(f => {
|
|
337
|
-
const curFavicon = faviconByEntries[f];
|
|
338
|
-
if (curFavicon) {
|
|
339
|
-
faviconNames.push(
|
|
340
|
-
curFavicon.substring(curFavicon.lastIndexOf('/') + 1),
|
|
341
|
-
);
|
|
342
|
-
}
|
|
343
|
-
});
|
|
348
|
+
protected async handleAPI(context: ModernServerContext) {
|
|
349
|
+
const { req, res } = context;
|
|
350
|
+
|
|
351
|
+
if (!this.frameAPIHandler) {
|
|
352
|
+
throw new Error('can not found api hanlder');
|
|
344
353
|
}
|
|
345
|
-
|
|
354
|
+
|
|
355
|
+
await this.frameAPIHandler(req, res);
|
|
346
356
|
}
|
|
347
357
|
|
|
348
|
-
|
|
358
|
+
protected async handleWeb(context: ModernServerContext, route: ModernRoute) {
|
|
359
|
+
return this.routeRenderHandler({
|
|
360
|
+
ctx: context,
|
|
361
|
+
route,
|
|
362
|
+
runner: this.runner,
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
protected verifyMatch(_c: ModernServerContext, _m: RouteMatcher) {
|
|
367
|
+
// empty
|
|
368
|
+
}
|
|
349
369
|
|
|
370
|
+
/* —————————————————————— private function —————————————————————— */
|
|
350
371
|
// handler route.json, include api / csr / ssr
|
|
351
372
|
// eslint-disable-next-line max-statements
|
|
352
373
|
private async routeHandler(context: ModernServerContext) {
|
|
353
374
|
const { req, res } = context;
|
|
354
375
|
|
|
355
|
-
await this.
|
|
376
|
+
await this.emitRouteHook('beforeMatch', { context });
|
|
356
377
|
|
|
357
378
|
// match routes in the route spec
|
|
358
379
|
const matched = this.router.match(context.url);
|
|
359
380
|
if (!matched) {
|
|
360
381
|
this.render404(context);
|
|
361
382
|
return;
|
|
383
|
+
} else {
|
|
384
|
+
this.verifyMatch(context, matched);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (res.headersSent) {
|
|
388
|
+
return;
|
|
362
389
|
}
|
|
363
390
|
|
|
364
391
|
const routeAPI = createRouteAPI(matched, this.router);
|
|
365
|
-
await this.
|
|
366
|
-
{ context, routeAPI },
|
|
367
|
-
{ onLast: noop as any },
|
|
368
|
-
);
|
|
392
|
+
await this.emitRouteHook('afterMatch', { context, routeAPI });
|
|
369
393
|
|
|
370
394
|
if (res.headersSent) {
|
|
371
395
|
return;
|
|
372
396
|
}
|
|
373
397
|
|
|
374
398
|
const { current } = routeAPI as any;
|
|
375
|
-
const route = current.generate();
|
|
399
|
+
const route: ModernRoute = current.generate();
|
|
376
400
|
const params = current.parseURLParams(context.url);
|
|
377
401
|
context.setParams(params);
|
|
378
402
|
|
|
379
403
|
// route is api service
|
|
380
404
|
if (route.isApi) {
|
|
381
|
-
|
|
382
|
-
throw new Error('can not found api hanlder');
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
await this.frameAPIHandler(req, res);
|
|
405
|
+
this.handleAPI(context);
|
|
386
406
|
return;
|
|
387
407
|
}
|
|
388
408
|
|
|
@@ -395,8 +415,11 @@ export class ModernServer {
|
|
|
395
415
|
return;
|
|
396
416
|
}
|
|
397
417
|
|
|
398
|
-
|
|
399
|
-
|
|
418
|
+
if (route.entryName) {
|
|
419
|
+
await this.emitRouteHook('beforeRender', { context });
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const file = await this.handleWeb(context, route);
|
|
400
423
|
if (!file) {
|
|
401
424
|
this.render404(context);
|
|
402
425
|
return;
|
|
@@ -412,10 +435,7 @@ export class ModernServer {
|
|
|
412
435
|
let response = file.content;
|
|
413
436
|
if (route.entryName) {
|
|
414
437
|
const templateAPI = createTemplateAPI(file.content.toString());
|
|
415
|
-
await this.
|
|
416
|
-
{ context, templateAPI },
|
|
417
|
-
{ onLast: noop as any },
|
|
418
|
-
);
|
|
438
|
+
await this.emitRouteHook('afterRender', { context, templateAPI });
|
|
419
439
|
await this.injectMicroFE(context, templateAPI);
|
|
420
440
|
response = templateAPI.get();
|
|
421
441
|
}
|
|
@@ -532,7 +552,7 @@ export class ModernServer {
|
|
|
532
552
|
res.statusCode = 200;
|
|
533
553
|
const context: ModernServerContext = createContext(req, res, {
|
|
534
554
|
logger: this.logger,
|
|
535
|
-
|
|
555
|
+
metrics: this.metrics,
|
|
536
556
|
});
|
|
537
557
|
|
|
538
558
|
try {
|
|
@@ -564,7 +584,11 @@ export class ModernServer {
|
|
|
564
584
|
// check entryName, aviod matched '/' route
|
|
565
585
|
if (entryName === status.toString() || entryName === '_error') {
|
|
566
586
|
try {
|
|
567
|
-
const file = await this.routeRenderHandler(
|
|
587
|
+
const file = await this.routeRenderHandler({
|
|
588
|
+
route,
|
|
589
|
+
ctx: context,
|
|
590
|
+
runner: this.runner,
|
|
591
|
+
});
|
|
568
592
|
if (file) {
|
|
569
593
|
context.res.end(file.content);
|
|
570
594
|
return;
|
|
@@ -578,5 +602,26 @@ export class ModernServer {
|
|
|
578
602
|
const text = ERROR_PAGE_TEXT[status] || ERROR_PAGE_TEXT[500];
|
|
579
603
|
res.end(createErrorDocument(status, text));
|
|
580
604
|
}
|
|
605
|
+
|
|
606
|
+
private prepareFavicons(
|
|
607
|
+
favicon: string | undefined,
|
|
608
|
+
faviconByEntries?: Record<string, string | undefined>,
|
|
609
|
+
) {
|
|
610
|
+
const faviconNames = [];
|
|
611
|
+
if (favicon) {
|
|
612
|
+
faviconNames.push(favicon.substring(favicon.lastIndexOf('/') + 1));
|
|
613
|
+
}
|
|
614
|
+
if (faviconByEntries) {
|
|
615
|
+
Object.keys(faviconByEntries).forEach(f => {
|
|
616
|
+
const curFavicon = faviconByEntries[f];
|
|
617
|
+
if (curFavicon) {
|
|
618
|
+
faviconNames.push(
|
|
619
|
+
curFavicon.substring(curFavicon.lastIndexOf('/') + 1),
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
return faviconNames;
|
|
625
|
+
}
|
|
581
626
|
}
|
|
582
627
|
/* eslint-enable max-lines */
|
package/src/type.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Buffer } from 'buffer';
|
|
|
2
2
|
import type Webpack from 'webpack';
|
|
3
3
|
import { serverManager } from '@modern-js/server-plugin';
|
|
4
4
|
import type { NormalizedConfig } from '@modern-js/core';
|
|
5
|
-
import type {
|
|
5
|
+
import type { Metrics, Logger, NextFunction } from '@modern-js/types/server';
|
|
6
6
|
import { ModernRouteInterface } from './libs/route';
|
|
7
7
|
|
|
8
8
|
declare module '@modern-js/core' {
|
|
@@ -26,6 +26,8 @@ export type DevServerOptions = {
|
|
|
26
26
|
dev: {
|
|
27
27
|
writeToDisk: boolean | ((filename: string) => boolean);
|
|
28
28
|
};
|
|
29
|
+
// 是否监听文件变化
|
|
30
|
+
watch: boolean;
|
|
29
31
|
// 是否开启 hot reload
|
|
30
32
|
hot: boolean | string;
|
|
31
33
|
// 是否开启 page reload
|
|
@@ -39,17 +41,22 @@ export type ModernServerOptions = {
|
|
|
39
41
|
pwd: string;
|
|
40
42
|
config: NormalizedConfig;
|
|
41
43
|
plugins?: any[];
|
|
42
|
-
dev?: boolean | DevServerOptions
|
|
44
|
+
dev?: boolean | Partial<DevServerOptions>;
|
|
43
45
|
compiler?: Webpack.MultiCompiler | Webpack.Compiler;
|
|
44
46
|
routes?: ModernRouteInterface[];
|
|
45
47
|
staticGenerate?: boolean;
|
|
46
48
|
customServer?: boolean;
|
|
47
49
|
loggerOptions?: Record<string, string>;
|
|
48
|
-
|
|
50
|
+
metricsOptions?: Record<string, string>;
|
|
49
51
|
logger?: Logger;
|
|
50
|
-
|
|
52
|
+
metrics?: Metrics;
|
|
51
53
|
apiOnly?: boolean;
|
|
54
|
+
ssrOnly?: boolean;
|
|
52
55
|
webOnly?: boolean;
|
|
56
|
+
proxyTarget?: {
|
|
57
|
+
ssr?: string;
|
|
58
|
+
api?: string;
|
|
59
|
+
};
|
|
53
60
|
};
|
|
54
61
|
|
|
55
62
|
export type RenderResult = {
|
|
@@ -71,4 +78,4 @@ export type ServerHookRunner = Then<ReturnType<typeof serverManager.init>>;
|
|
|
71
78
|
|
|
72
79
|
export type ReadyOptions = { routes?: ModernRouteInterface[] };
|
|
73
80
|
|
|
74
|
-
export type {
|
|
81
|
+
export type { Metrics, Logger, NextFunction };
|
package/src/utils.ts
CHANGED
|
@@ -49,3 +49,17 @@ export const createErrorDocument = (status: number, text: string) => {
|
|
|
49
49
|
</html>
|
|
50
50
|
`;
|
|
51
51
|
};
|
|
52
|
+
|
|
53
|
+
// This can live anywhere in your codebase:
|
|
54
|
+
export function applyMixins(derivedCtor: any, constructors: any[]) {
|
|
55
|
+
constructors.forEach(baseCtor => {
|
|
56
|
+
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
|
|
57
|
+
Object.defineProperty(
|
|
58
|
+
derivedCtor.prototype,
|
|
59
|
+
name,
|
|
60
|
+
Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
|
|
61
|
+
Object.create(null),
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|