@modern-js/server 1.1.3-beta.1 → 1.1.5-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 +42 -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/cache/type.js +0 -1
- 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 +12 -3
- package/dist/js/modern/server/dev-server/index.js +1 -1
- package/dist/js/modern/server/index.js +19 -16
- package/dist/js/modern/server/modern-server-split.js +55 -6
- package/dist/js/modern/server/modern-server.js +92 -58
- package/dist/js/modern/type.js +0 -1
- 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 +12 -3
- package/dist/js/node/server/dev-server/index.js +4 -4
- package/dist/js/node/server/index.js +18 -14
- package/dist/js/node/server/modern-server-split.js +61 -9
- package/dist/js/node/server/modern-server.js +93 -59
- 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 +7 -7
- 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 +15 -13
- package/src/server/dev-server/index.ts +1 -1
- package/src/server/index.ts +24 -14
- package/src/server/modern-server-split.ts +59 -7
- package/src/server/modern-server.ts +105 -67
- 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);
|
|
@@ -272,13 +269,15 @@ export class ModernServer {
|
|
|
272
269
|
|
|
273
270
|
// if use lambda/, mean framework style of writing, then discard user extension
|
|
274
271
|
const apiExtension = mergeExtension(pluginAPIExt);
|
|
275
|
-
this.frameAPIHandler = await this.prepareAPIHandler(mode,
|
|
276
|
-
...apiExtension,
|
|
277
|
-
modernJsConfig: this.conf,
|
|
278
|
-
});
|
|
272
|
+
this.frameAPIHandler = await this.prepareAPIHandler(mode, apiExtension);
|
|
279
273
|
}
|
|
280
274
|
}
|
|
281
275
|
|
|
276
|
+
// Todo
|
|
277
|
+
protected async proxy() {
|
|
278
|
+
return null as any;
|
|
279
|
+
}
|
|
280
|
+
|
|
282
281
|
/* —————————————————————— function will be overwrite —————————————————————— */
|
|
283
282
|
protected async prepareWebHandler(
|
|
284
283
|
extension: ReturnType<typeof mergeExtension>,
|
|
@@ -317,75 +316,93 @@ export class ModernServer {
|
|
|
317
316
|
return routes;
|
|
318
317
|
}
|
|
319
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
|
+
|
|
320
338
|
protected async preServerInit() {
|
|
321
|
-
const { conf } = this;
|
|
339
|
+
const { conf, runner } = this;
|
|
322
340
|
const preMiddleware: ModernServerAsyncHandler[] =
|
|
323
|
-
await
|
|
341
|
+
await runner.preServerInit(conf);
|
|
324
342
|
|
|
325
343
|
preMiddleware.flat().forEach(mid => {
|
|
326
344
|
this.addHandler(mid);
|
|
327
345
|
});
|
|
328
346
|
}
|
|
329
347
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
if (favicon) {
|
|
336
|
-
faviconNames.push(favicon.substring(favicon.lastIndexOf('/') + 1));
|
|
337
|
-
}
|
|
338
|
-
if (faviconByEntries) {
|
|
339
|
-
Object.keys(faviconByEntries).forEach(f => {
|
|
340
|
-
const curFavicon = faviconByEntries[f];
|
|
341
|
-
if (curFavicon) {
|
|
342
|
-
faviconNames.push(
|
|
343
|
-
curFavicon.substring(curFavicon.lastIndexOf('/') + 1),
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
});
|
|
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');
|
|
347
353
|
}
|
|
348
|
-
|
|
354
|
+
|
|
355
|
+
await this.frameAPIHandler(req, res);
|
|
349
356
|
}
|
|
350
357
|
|
|
351
|
-
|
|
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
|
+
}
|
|
352
369
|
|
|
370
|
+
/* —————————————————————— private function —————————————————————— */
|
|
353
371
|
// handler route.json, include api / csr / ssr
|
|
354
372
|
// eslint-disable-next-line max-statements
|
|
355
373
|
private async routeHandler(context: ModernServerContext) {
|
|
356
374
|
const { req, res } = context;
|
|
357
375
|
|
|
358
|
-
await this.
|
|
376
|
+
await this.emitRouteHook('beforeMatch', { context });
|
|
359
377
|
|
|
360
378
|
// match routes in the route spec
|
|
361
379
|
const matched = this.router.match(context.url);
|
|
362
380
|
if (!matched) {
|
|
363
381
|
this.render404(context);
|
|
364
382
|
return;
|
|
383
|
+
} else {
|
|
384
|
+
this.verifyMatch(context, matched);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (res.headersSent) {
|
|
388
|
+
return;
|
|
365
389
|
}
|
|
366
390
|
|
|
367
391
|
const routeAPI = createRouteAPI(matched, this.router);
|
|
368
|
-
await this.
|
|
369
|
-
{ context, routeAPI },
|
|
370
|
-
{ onLast: noop as any },
|
|
371
|
-
);
|
|
392
|
+
await this.emitRouteHook('afterMatch', { context, routeAPI });
|
|
372
393
|
|
|
373
394
|
if (res.headersSent) {
|
|
374
395
|
return;
|
|
375
396
|
}
|
|
376
397
|
|
|
377
398
|
const { current } = routeAPI as any;
|
|
378
|
-
const route = current.generate();
|
|
399
|
+
const route: ModernRoute = current.generate();
|
|
379
400
|
const params = current.parseURLParams(context.url);
|
|
380
401
|
context.setParams(params);
|
|
381
402
|
|
|
382
403
|
// route is api service
|
|
383
404
|
if (route.isApi) {
|
|
384
|
-
|
|
385
|
-
throw new Error('can not found api hanlder');
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
await this.frameAPIHandler(req, res);
|
|
405
|
+
this.handleAPI(context);
|
|
389
406
|
return;
|
|
390
407
|
}
|
|
391
408
|
|
|
@@ -398,8 +415,11 @@ export class ModernServer {
|
|
|
398
415
|
return;
|
|
399
416
|
}
|
|
400
417
|
|
|
401
|
-
|
|
402
|
-
|
|
418
|
+
if (route.entryName) {
|
|
419
|
+
await this.emitRouteHook('beforeRender', { context });
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const file = await this.handleWeb(context, route);
|
|
403
423
|
if (!file) {
|
|
404
424
|
this.render404(context);
|
|
405
425
|
return;
|
|
@@ -415,10 +435,7 @@ export class ModernServer {
|
|
|
415
435
|
let response = file.content;
|
|
416
436
|
if (route.entryName) {
|
|
417
437
|
const templateAPI = createTemplateAPI(file.content.toString());
|
|
418
|
-
await this.
|
|
419
|
-
{ context, templateAPI },
|
|
420
|
-
{ onLast: noop as any },
|
|
421
|
-
);
|
|
438
|
+
await this.emitRouteHook('afterRender', { context, templateAPI });
|
|
422
439
|
await this.injectMicroFE(context, templateAPI);
|
|
423
440
|
response = templateAPI.get();
|
|
424
441
|
}
|
|
@@ -535,7 +552,7 @@ export class ModernServer {
|
|
|
535
552
|
res.statusCode = 200;
|
|
536
553
|
const context: ModernServerContext = createContext(req, res, {
|
|
537
554
|
logger: this.logger,
|
|
538
|
-
|
|
555
|
+
metrics: this.metrics,
|
|
539
556
|
});
|
|
540
557
|
|
|
541
558
|
try {
|
|
@@ -581,5 +598,26 @@ export class ModernServer {
|
|
|
581
598
|
const text = ERROR_PAGE_TEXT[status] || ERROR_PAGE_TEXT[500];
|
|
582
599
|
res.end(createErrorDocument(status, text));
|
|
583
600
|
}
|
|
601
|
+
|
|
602
|
+
private prepareFavicons(
|
|
603
|
+
favicon: string | undefined,
|
|
604
|
+
faviconByEntries?: Record<string, string | undefined>,
|
|
605
|
+
) {
|
|
606
|
+
const faviconNames = [];
|
|
607
|
+
if (favicon) {
|
|
608
|
+
faviconNames.push(favicon.substring(favicon.lastIndexOf('/') + 1));
|
|
609
|
+
}
|
|
610
|
+
if (faviconByEntries) {
|
|
611
|
+
Object.keys(faviconByEntries).forEach(f => {
|
|
612
|
+
const curFavicon = faviconByEntries[f];
|
|
613
|
+
if (curFavicon) {
|
|
614
|
+
faviconNames.push(
|
|
615
|
+
curFavicon.substring(curFavicon.lastIndexOf('/') + 1),
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
return faviconNames;
|
|
621
|
+
}
|
|
584
622
|
}
|
|
585
623
|
/* 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
|
+
}
|