@midwayjs/core 3.16.2 → 3.17.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/dist/common/middlewareManager.d.ts +12 -1
- package/dist/common/middlewareManager.js +17 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -1
- package/dist/interface.d.ts +28 -4
- package/dist/response/base.d.ts +16 -0
- package/dist/response/base.js +48 -0
- package/dist/response/http.d.ts +23 -0
- package/dist/response/http.js +72 -0
- package/dist/response/index.d.ts +3 -0
- package/dist/response/index.js +8 -0
- package/dist/response/sse.d.ts +23 -0
- package/dist/response/sse.js +105 -0
- package/dist/response/stream.d.ts +14 -0
- package/dist/response/stream.js +57 -0
- package/dist/service/middlewareService.js +16 -12
- package/package.json +3 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CommonMiddleware, CommonMiddlewareUnion, IMiddlewareManager, IMidwayContext } from '../interface';
|
|
1
|
+
import { ClassMiddleware, CommonMiddleware, CommonMiddlewareUnion, CompositionMiddleware, IMiddlewareManager, IMidwayContext } from '../interface';
|
|
2
2
|
export declare class ContextMiddlewareManager<CTX extends IMidwayContext, R, N> extends Array<CommonMiddleware<CTX, R, N>> implements IMiddlewareManager<CTX, R, N> {
|
|
3
3
|
/**
|
|
4
4
|
* insert a middleware or middleware array to first
|
|
@@ -67,4 +67,15 @@ export declare class ContextMiddlewareManager<CTX extends IMidwayContext, R, N>
|
|
|
67
67
|
*/
|
|
68
68
|
getNames(): string[];
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Get middleware resolve options
|
|
72
|
+
*/
|
|
73
|
+
type MiddlewareResolveOptions<T, CTX, R, N> = T extends ClassMiddleware<CTX, R, N> ? InstanceType<T> extends {
|
|
74
|
+
resolve: (...args: infer P) => any;
|
|
75
|
+
} ? P[1] : any : never;
|
|
76
|
+
/**
|
|
77
|
+
* wrap a middleware with options and composition a new middleware
|
|
78
|
+
*/
|
|
79
|
+
export declare function createMiddleware<CTX extends IMidwayContext, R, N, M extends ClassMiddleware<CTX, R, N>>(middleware: M, options: MiddlewareResolveOptions<M, CTX, R, N>, name?: string): CompositionMiddleware<CTX, R, N>;
|
|
80
|
+
export {};
|
|
70
81
|
//# sourceMappingURL=middlewareManager.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ContextMiddlewareManager = void 0;
|
|
3
|
+
exports.createMiddleware = exports.ContextMiddlewareManager = void 0;
|
|
4
4
|
class ContextMiddlewareManager extends Array {
|
|
5
5
|
/**
|
|
6
6
|
* insert a middleware or middleware array to first
|
|
@@ -151,8 +151,11 @@ class ContextMiddlewareManager extends Array {
|
|
|
151
151
|
* @param middleware
|
|
152
152
|
*/
|
|
153
153
|
getMiddlewareName(middleware) {
|
|
154
|
-
var _a, _b;
|
|
155
|
-
|
|
154
|
+
var _a, _b, _c;
|
|
155
|
+
if (middleware['middleware']) {
|
|
156
|
+
return ((_a = middleware.name) !== null && _a !== void 0 ? _a : this.getMiddlewareName(middleware['middleware']));
|
|
157
|
+
}
|
|
158
|
+
return ((_c = (_b = (middleware.getName && middleware.getName())) !== null && _b !== void 0 ? _b : middleware._name) !== null && _c !== void 0 ? _c : middleware.name);
|
|
156
159
|
}
|
|
157
160
|
/**
|
|
158
161
|
* remove a middleware
|
|
@@ -196,4 +199,15 @@ class ContextMiddlewareManager extends Array {
|
|
|
196
199
|
}
|
|
197
200
|
}
|
|
198
201
|
exports.ContextMiddlewareManager = ContextMiddlewareManager;
|
|
202
|
+
/**
|
|
203
|
+
* wrap a middleware with options and composition a new middleware
|
|
204
|
+
*/
|
|
205
|
+
function createMiddleware(middleware, options, name) {
|
|
206
|
+
return {
|
|
207
|
+
middleware,
|
|
208
|
+
options,
|
|
209
|
+
name,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
exports.createMiddleware = createMiddleware;
|
|
199
213
|
//# sourceMappingURL=middlewareManager.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -46,4 +46,5 @@ export { Types } from './util/types';
|
|
|
46
46
|
export { PathFileUtil } from './util/pathFileUtil';
|
|
47
47
|
export { FileUtils } from './util/fs';
|
|
48
48
|
export { FORMAT } from './util/format';
|
|
49
|
+
export { ServerResponse, HttpServerResponse } from './response/index';
|
|
49
50
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.FORMAT = exports.FileUtils = exports.PathFileUtil = exports.Types = exports.retryWith = exports.retryWithAsync = exports.extend = exports.Utils = exports.sleep = exports.isTypeScriptEnvironment = exports.wrapAsync = exports.wrapMiddleware = exports.pathMatching = exports.transformRequestObjectByType = exports.deprecatedOutput = exports.delegateTargetAllPrototypeMethod = exports.delegateTargetProperties = exports.delegateTargetMethod = exports.delegateTargetPrototypeMethod = exports.loadModule = exports.safeRequire = exports.safelyGet = exports.ASYNC_ROOT_CONTEXT = exports.MidwayPriorityManager = exports.DEFAULT_PRIORITY = exports.DataSourceManager = exports.WebRouterCollector = exports.MidwayServerlessFunctionService = exports.MidwayWebRouterService = exports.MidwayHealthService = exports.MidwayMockService = exports.MidwayDecoratorService = exports.MidwayMiddlewareService = exports.MidwayLifeCycleService = exports.MidwayAspectService = exports.MidwayFrameworkService = exports.MidwayLoggerService = exports.MidwayInformationService = exports.MidwayEnvironmentService = exports.MidwayConfigService = exports.FunctionalConfiguration = exports.createConfiguration = exports.BaseFramework = exports.MidwayRequestContainer = void 0;
|
|
17
|
+
exports.HttpServerResponse = exports.ServerResponse = exports.FORMAT = exports.FileUtils = exports.PathFileUtil = exports.Types = exports.retryWith = exports.retryWithAsync = exports.extend = exports.Utils = exports.sleep = exports.isTypeScriptEnvironment = exports.wrapAsync = exports.wrapMiddleware = exports.pathMatching = exports.transformRequestObjectByType = exports.deprecatedOutput = exports.delegateTargetAllPrototypeMethod = exports.delegateTargetProperties = exports.delegateTargetMethod = exports.delegateTargetPrototypeMethod = exports.loadModule = exports.safeRequire = exports.safelyGet = exports.ASYNC_ROOT_CONTEXT = exports.MidwayPriorityManager = exports.DEFAULT_PRIORITY = exports.DataSourceManager = exports.WebRouterCollector = exports.MidwayServerlessFunctionService = exports.MidwayWebRouterService = exports.MidwayHealthService = exports.MidwayMockService = exports.MidwayDecoratorService = exports.MidwayMiddlewareService = exports.MidwayLifeCycleService = exports.MidwayAspectService = exports.MidwayFrameworkService = exports.MidwayLoggerService = exports.MidwayInformationService = exports.MidwayEnvironmentService = exports.MidwayConfigService = exports.FunctionalConfiguration = exports.createConfiguration = exports.BaseFramework = exports.MidwayRequestContainer = void 0;
|
|
18
18
|
__exportStar(require("./interface"), exports);
|
|
19
19
|
__exportStar(require("./context/container"), exports);
|
|
20
20
|
var requestContainer_1 = require("./context/requestContainer");
|
|
@@ -109,4 +109,7 @@ var fs_1 = require("./util/fs");
|
|
|
109
109
|
Object.defineProperty(exports, "FileUtils", { enumerable: true, get: function () { return fs_1.FileUtils; } });
|
|
110
110
|
var format_1 = require("./util/format");
|
|
111
111
|
Object.defineProperty(exports, "FORMAT", { enumerable: true, get: function () { return format_1.FORMAT; } });
|
|
112
|
+
var index_1 = require("./response/index");
|
|
113
|
+
Object.defineProperty(exports, "ServerResponse", { enumerable: true, get: function () { return index_1.ServerResponse; } });
|
|
114
|
+
Object.defineProperty(exports, "HttpServerResponse", { enumerable: true, get: function () { return index_1.HttpServerResponse; } });
|
|
112
115
|
//# sourceMappingURL=index.js.map
|
package/dist/interface.d.ts
CHANGED
|
@@ -421,12 +421,12 @@ export type CreateDataSourceInstanceOptions = {
|
|
|
421
421
|
cacheInstance?: boolean | undefined;
|
|
422
422
|
};
|
|
423
423
|
export type DataSourceManagerConfigOption<OPTIONS, ENTITY_CONFIG_KEY extends string = 'entities'> = {
|
|
424
|
-
default?:
|
|
424
|
+
default?: OPTIONS;
|
|
425
425
|
defaultDataSourceName?: string;
|
|
426
426
|
dataSource?: {
|
|
427
427
|
[key: string]: PowerPartial<{
|
|
428
428
|
[keyName in ENTITY_CONFIG_KEY]: any[];
|
|
429
|
-
} & OPTIONS
|
|
429
|
+
}> & OPTIONS;
|
|
430
430
|
};
|
|
431
431
|
} & CreateDataSourceInstanceOptions;
|
|
432
432
|
type ConfigType<T> = T extends (...args: any[]) => any ? Writable<PowerPartial<ReturnType<T>>> : Writable<PowerPartial<T>>;
|
|
@@ -715,13 +715,24 @@ export type IgnoreMatcher<CTX> = string | RegExp | ((ctx: CTX) => boolean);
|
|
|
715
715
|
* Common middleware definition
|
|
716
716
|
*/
|
|
717
717
|
export interface IMiddleware<CTX, R, N = unknown> {
|
|
718
|
-
resolve: (app: IMidwayApplication) => FunctionMiddleware<CTX, R, N> | Promise<FunctionMiddleware<CTX, R, N>>;
|
|
718
|
+
resolve: (app: IMidwayApplication, options?: any) => FunctionMiddleware<CTX, R, N> | Promise<FunctionMiddleware<CTX, R, N>>;
|
|
719
|
+
/**
|
|
720
|
+
* Which paths to ignore
|
|
721
|
+
*/
|
|
719
722
|
match?: IgnoreMatcher<CTX> | IgnoreMatcher<CTX>[];
|
|
723
|
+
/**
|
|
724
|
+
* Match those paths with higher priority than ignore
|
|
725
|
+
*/
|
|
720
726
|
ignore?: IgnoreMatcher<CTX> | IgnoreMatcher<CTX>[];
|
|
721
727
|
}
|
|
722
728
|
export type FunctionMiddleware<CTX, R, N = unknown> = N extends true ? (req: CTX, res: R, next: N) => any : (context: CTX, next: R, options?: any) => any;
|
|
723
729
|
export type ClassMiddleware<CTX, R, N> = new (...args: any[]) => IMiddleware<CTX, R, N>;
|
|
724
|
-
export type
|
|
730
|
+
export type CompositionMiddleware<CTX, R, N> = {
|
|
731
|
+
middleware: ClassMiddleware<CTX, R, N>;
|
|
732
|
+
options: any;
|
|
733
|
+
name?: string;
|
|
734
|
+
};
|
|
735
|
+
export type CommonMiddleware<CTX, R, N> = ClassMiddleware<CTX, R, N> | FunctionMiddleware<CTX, R, N> | CompositionMiddleware<CTX, R, N>;
|
|
725
736
|
export type CommonMiddlewareUnion<CTX, R, N> = CommonMiddleware<CTX, R, N> | Array<CommonMiddleware<CTX, R, N>>;
|
|
726
737
|
export type MiddlewareRespond<CTX, R, N> = (context: CTX, nextOrRes?: N extends true ? R : NextFunction, next?: N) => Promise<any>;
|
|
727
738
|
/**
|
|
@@ -987,5 +998,18 @@ export interface HealthResults {
|
|
|
987
998
|
reason?: string;
|
|
988
999
|
}>;
|
|
989
1000
|
}
|
|
1001
|
+
export interface ServerSendEventMessage {
|
|
1002
|
+
data?: string | object;
|
|
1003
|
+
event?: string;
|
|
1004
|
+
id?: string;
|
|
1005
|
+
retry?: number;
|
|
1006
|
+
}
|
|
1007
|
+
export interface ServerStreamOptions {
|
|
1008
|
+
tpl?: (data: unknown) => unknown;
|
|
1009
|
+
}
|
|
1010
|
+
export interface ServerSendEventStreamOptions {
|
|
1011
|
+
closeEvent?: string;
|
|
1012
|
+
tpl?: (data: ServerSendEventMessage) => ServerSendEventMessage;
|
|
1013
|
+
}
|
|
990
1014
|
export {};
|
|
991
1015
|
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { IMidwayContext } from '../interface';
|
|
3
|
+
export declare class ServerResponse<CTX extends IMidwayContext = IMidwayContext> {
|
|
4
|
+
protected readonly ctx: any;
|
|
5
|
+
protected isSuccess: boolean;
|
|
6
|
+
constructor(ctx: CTX);
|
|
7
|
+
static TEXT_TPL: (data: string, isSuccess: boolean) => unknown;
|
|
8
|
+
static JSON_TPL: (data: Record<any, any>, isSuccess: boolean) => unknown;
|
|
9
|
+
static BLOB_TPL: (data: Buffer, isSuccess: boolean) => unknown;
|
|
10
|
+
json(data: Record<any, any>): any;
|
|
11
|
+
text(data: string): any;
|
|
12
|
+
blob(data: Buffer): any;
|
|
13
|
+
success(): this;
|
|
14
|
+
fail(): this;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ServerResponse = void 0;
|
|
4
|
+
class ServerResponse {
|
|
5
|
+
constructor(ctx) {
|
|
6
|
+
this.isSuccess = true;
|
|
7
|
+
this.ctx = ctx;
|
|
8
|
+
}
|
|
9
|
+
json(data) {
|
|
10
|
+
return Object.getPrototypeOf(this).constructor.JSON_TPL(data, this.isSuccess);
|
|
11
|
+
}
|
|
12
|
+
text(data) {
|
|
13
|
+
return Object.getPrototypeOf(this).constructor.TEXT_TPL(data, this.isSuccess);
|
|
14
|
+
}
|
|
15
|
+
blob(data) {
|
|
16
|
+
return Object.getPrototypeOf(this).constructor.BLOB_TPL(data, this.isSuccess);
|
|
17
|
+
}
|
|
18
|
+
success() {
|
|
19
|
+
this.isSuccess = true;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
fail() {
|
|
23
|
+
this.isSuccess = false;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.ServerResponse = ServerResponse;
|
|
28
|
+
ServerResponse.TEXT_TPL = (data, isSuccess) => {
|
|
29
|
+
return data;
|
|
30
|
+
};
|
|
31
|
+
ServerResponse.JSON_TPL = (data, isSuccess) => {
|
|
32
|
+
if (isSuccess) {
|
|
33
|
+
return {
|
|
34
|
+
success: 'true',
|
|
35
|
+
data,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
return {
|
|
40
|
+
success: 'false',
|
|
41
|
+
message: data || 'fail',
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
ServerResponse.BLOB_TPL = (data, isSuccess) => {
|
|
46
|
+
return data;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { IMidwayContext, ServerSendEventMessage, ServerSendEventStreamOptions, ServerStreamOptions } from '../interface';
|
|
4
|
+
import { ServerResponse } from './base';
|
|
5
|
+
import { ServerSendEventStream } from './sse';
|
|
6
|
+
import { Readable } from 'stream';
|
|
7
|
+
import { HttpStreamResponse } from './stream';
|
|
8
|
+
export declare class HttpServerResponse<CTX extends IMidwayContext> extends ServerResponse<CTX> {
|
|
9
|
+
constructor(ctx: CTX);
|
|
10
|
+
static FILE_TPL: (data: Readable, isSuccess: boolean) => Readable;
|
|
11
|
+
static SSE_TPL: (data: ServerSendEventMessage) => ServerSendEventMessage;
|
|
12
|
+
static STREAM_TPL: (data: unknown) => unknown;
|
|
13
|
+
status(code: number): this;
|
|
14
|
+
header(key: string, value: string): this;
|
|
15
|
+
headers(headers: Record<string, string>): this;
|
|
16
|
+
json(data: Record<any, any>): any;
|
|
17
|
+
text(data: string): any;
|
|
18
|
+
file(filePath: string, mimeType?: string): any;
|
|
19
|
+
blob(data: Buffer, mimeType?: string): any;
|
|
20
|
+
sse(options?: ServerSendEventStreamOptions): ServerSendEventStream;
|
|
21
|
+
stream(options?: ServerStreamOptions): HttpStreamResponse;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpServerResponse = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const base_1 = require("./base");
|
|
6
|
+
const sse_1 = require("./sse");
|
|
7
|
+
const stream_1 = require("./stream");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
class HttpServerResponse extends base_1.ServerResponse {
|
|
10
|
+
constructor(ctx) {
|
|
11
|
+
super(ctx);
|
|
12
|
+
}
|
|
13
|
+
status(code) {
|
|
14
|
+
this.ctx.res.statusCode = code;
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
header(key, value) {
|
|
18
|
+
this.ctx.res.setHeader(key, value);
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
headers(headers) {
|
|
22
|
+
if (this.ctx.res.setHeaders) {
|
|
23
|
+
this.ctx.res.setHeaders(new Map(Object.entries(headers)));
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
for (const key in headers) {
|
|
27
|
+
this.header(key, headers[key]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
json(data) {
|
|
33
|
+
this.header('Content-Type', 'application/json');
|
|
34
|
+
return Object.getPrototypeOf(this).constructor.JSON_TPL(data, this.isSuccess);
|
|
35
|
+
}
|
|
36
|
+
text(data) {
|
|
37
|
+
this.header('Content-Type', 'text/plain');
|
|
38
|
+
return Object.getPrototypeOf(this).constructor.TEXT_TPL(data, this.isSuccess);
|
|
39
|
+
}
|
|
40
|
+
file(filePath, mimeType) {
|
|
41
|
+
this.header('Content-Type', mimeType || 'application/octet-stream');
|
|
42
|
+
this.header('Content-Disposition', `attachment; filename=${(0, path_1.basename)(filePath)}`);
|
|
43
|
+
return Object.getPrototypeOf(this).constructor.FILE_TPL(typeof filePath === 'string' ? (0, fs_1.createReadStream)(filePath) : filePath, this.isSuccess);
|
|
44
|
+
}
|
|
45
|
+
blob(data, mimeType) {
|
|
46
|
+
this.header('Content-Type', mimeType || 'application/octet-stream');
|
|
47
|
+
return Object.getPrototypeOf(this).constructor.BLOB_TPL(data, this.isSuccess);
|
|
48
|
+
}
|
|
49
|
+
sse(options = {}) {
|
|
50
|
+
return new sse_1.ServerSendEventStream(this.ctx, {
|
|
51
|
+
tpl: Object.getPrototypeOf(this).constructor.SSE_TPL,
|
|
52
|
+
...options,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
stream(options = {}) {
|
|
56
|
+
return new stream_1.HttpStreamResponse(this.ctx, {
|
|
57
|
+
tpl: Object.getPrototypeOf(this).constructor.STREAM_TPL,
|
|
58
|
+
...options,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.HttpServerResponse = HttpServerResponse;
|
|
63
|
+
HttpServerResponse.FILE_TPL = (data, isSuccess) => {
|
|
64
|
+
return data;
|
|
65
|
+
};
|
|
66
|
+
HttpServerResponse.SSE_TPL = (data) => {
|
|
67
|
+
return data;
|
|
68
|
+
};
|
|
69
|
+
HttpServerResponse.STREAM_TPL = (data) => {
|
|
70
|
+
return data;
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpServerResponse = exports.ServerResponse = void 0;
|
|
4
|
+
var base_1 = require("./base");
|
|
5
|
+
Object.defineProperty(exports, "ServerResponse", { enumerable: true, get: function () { return base_1.ServerResponse; } });
|
|
6
|
+
var http_1 = require("./http");
|
|
7
|
+
Object.defineProperty(exports, "HttpServerResponse", { enumerable: true, get: function () { return http_1.HttpServerResponse; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Transform } from 'stream';
|
|
3
|
+
import { ServerSendEventStreamOptions } from '../interface';
|
|
4
|
+
interface MessageEvent {
|
|
5
|
+
data?: string | object;
|
|
6
|
+
event?: string;
|
|
7
|
+
id?: string;
|
|
8
|
+
retry?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class ServerSendEventStream extends Transform {
|
|
11
|
+
private readonly ctx;
|
|
12
|
+
private isActive;
|
|
13
|
+
private readonly closeEvent;
|
|
14
|
+
private options;
|
|
15
|
+
constructor(ctx: any, options?: ServerSendEventStreamOptions);
|
|
16
|
+
_transform(chunk: any, encoding: any, callback: any): void;
|
|
17
|
+
sendError(error: Error): void;
|
|
18
|
+
sendEnd(message?: MessageEvent): void;
|
|
19
|
+
send(message: MessageEvent): void;
|
|
20
|
+
private handleClose;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=sse.d.ts.map
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ServerSendEventStream = void 0;
|
|
4
|
+
const stream_1 = require("stream");
|
|
5
|
+
class ServerSendEventStream extends stream_1.Transform {
|
|
6
|
+
constructor(ctx, options = {}) {
|
|
7
|
+
super({
|
|
8
|
+
objectMode: true,
|
|
9
|
+
...options,
|
|
10
|
+
});
|
|
11
|
+
this.isActive = false;
|
|
12
|
+
this.ctx = ctx;
|
|
13
|
+
this.closeEvent = options.closeEvent || 'close';
|
|
14
|
+
this.options = options;
|
|
15
|
+
// 监听客户端关闭连接
|
|
16
|
+
this.ctx.req.on('close', this.handleClose.bind(this));
|
|
17
|
+
}
|
|
18
|
+
_transform(chunk, encoding, callback) {
|
|
19
|
+
try {
|
|
20
|
+
let dataLines, prefix = 'data: ';
|
|
21
|
+
const commentReg = /^\s*:\s*/;
|
|
22
|
+
const res = [];
|
|
23
|
+
if (!this.isActive) {
|
|
24
|
+
this.isActive = true;
|
|
25
|
+
const defaultHeader = {
|
|
26
|
+
'Content-Type': 'text/event-stream',
|
|
27
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
28
|
+
Connection: 'keep-alive',
|
|
29
|
+
'X-Accel-Buffering': 'no',
|
|
30
|
+
};
|
|
31
|
+
for (const key in defaultHeader) {
|
|
32
|
+
this.ctx.res.setHeader(key, defaultHeader[key]);
|
|
33
|
+
}
|
|
34
|
+
this.ctx.req.socket.setTimeout(0);
|
|
35
|
+
this.ctx.req.socket.setNoDelay(true);
|
|
36
|
+
this.ctx.req.socket.setKeepAlive(true);
|
|
37
|
+
res.push({
|
|
38
|
+
data: ':ok',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const senderObject = chunk;
|
|
42
|
+
if (senderObject.event)
|
|
43
|
+
res.push('event: ' + senderObject.event);
|
|
44
|
+
if (senderObject.retry)
|
|
45
|
+
res.push('retry: ' + senderObject.retry);
|
|
46
|
+
if (senderObject.id)
|
|
47
|
+
res.push('id: ' + senderObject.id);
|
|
48
|
+
if (typeof senderObject.data === 'object') {
|
|
49
|
+
dataLines = JSON.stringify(senderObject.data);
|
|
50
|
+
res.push(prefix + dataLines);
|
|
51
|
+
}
|
|
52
|
+
else if (typeof senderObject.data === 'undefined') {
|
|
53
|
+
// Send an empty string even without data
|
|
54
|
+
res.push(prefix);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
senderObject.data = String(senderObject.data);
|
|
58
|
+
if (senderObject.data.search(commentReg) !== -1) {
|
|
59
|
+
senderObject.data = senderObject.data.replace(commentReg, '');
|
|
60
|
+
prefix = ': ';
|
|
61
|
+
}
|
|
62
|
+
senderObject.data = senderObject.data.replace(/(\r\n|\r|\n)/g, '\n');
|
|
63
|
+
dataLines = senderObject.data.split(/\n/);
|
|
64
|
+
for (let i = 0, l = dataLines.length; i < l; ++i) {
|
|
65
|
+
const line = dataLines[i];
|
|
66
|
+
if (i + 1 === l) {
|
|
67
|
+
res.push(prefix + line);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
res.push(prefix + line);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
this.push(res.join('\n') + '\n\n');
|
|
75
|
+
callback();
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
this.ctx.logger.error(err);
|
|
79
|
+
// send error to client
|
|
80
|
+
this.sendError(err);
|
|
81
|
+
// close stream
|
|
82
|
+
this.end();
|
|
83
|
+
// callback error
|
|
84
|
+
callback(err);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
sendError(error) {
|
|
88
|
+
this.send({
|
|
89
|
+
event: 'error',
|
|
90
|
+
data: error.message || 'An error occurred',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
sendEnd(message) {
|
|
94
|
+
message.event = this.closeEvent;
|
|
95
|
+
this.send(message);
|
|
96
|
+
}
|
|
97
|
+
send(message) {
|
|
98
|
+
super.write(this.options.tpl(message));
|
|
99
|
+
}
|
|
100
|
+
handleClose() {
|
|
101
|
+
this.end();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.ServerSendEventStream = ServerSendEventStream;
|
|
105
|
+
//# sourceMappingURL=sse.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Transform } from 'stream';
|
|
3
|
+
import { ServerStreamOptions } from '../interface';
|
|
4
|
+
export declare class HttpStreamResponse extends Transform {
|
|
5
|
+
private ctx;
|
|
6
|
+
private isActive;
|
|
7
|
+
private options;
|
|
8
|
+
constructor(ctx: any, options?: ServerStreamOptions);
|
|
9
|
+
_transform(chunk: any, encoding: any, callback: any): void;
|
|
10
|
+
send(data: unknown): void;
|
|
11
|
+
sendError(error: any): void;
|
|
12
|
+
_flush(callback: any): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpStreamResponse = void 0;
|
|
4
|
+
const stream_1 = require("stream");
|
|
5
|
+
class HttpStreamResponse extends stream_1.Transform {
|
|
6
|
+
constructor(ctx, options = {}) {
|
|
7
|
+
super({
|
|
8
|
+
objectMode: true,
|
|
9
|
+
...options,
|
|
10
|
+
});
|
|
11
|
+
this.isActive = false;
|
|
12
|
+
this.ctx = ctx;
|
|
13
|
+
this.options = options;
|
|
14
|
+
}
|
|
15
|
+
_transform(chunk, encoding, callback) {
|
|
16
|
+
try {
|
|
17
|
+
if (!this.isActive) {
|
|
18
|
+
this.isActive = true;
|
|
19
|
+
this.ctx.res.statusCode = 200;
|
|
20
|
+
this.ctx.res.setHeader('Transfer-Encoding', 'chunked');
|
|
21
|
+
this.ctx.res.setHeader('Cache-Control', 'no-cache');
|
|
22
|
+
this.ctx.req.socket.setTimeout(0);
|
|
23
|
+
}
|
|
24
|
+
if (typeof chunk === 'string') {
|
|
25
|
+
this.ctx.res.write(chunk);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
this.ctx.res.write(JSON.stringify(chunk));
|
|
29
|
+
}
|
|
30
|
+
callback();
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
this.ctx.logger.error(err);
|
|
34
|
+
// close stream
|
|
35
|
+
this.end();
|
|
36
|
+
this.ctx.res.end();
|
|
37
|
+
callback(err);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
send(data) {
|
|
41
|
+
if (!this.writable) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.write(this.options.tpl(data));
|
|
45
|
+
}
|
|
46
|
+
sendError(error) {
|
|
47
|
+
this.ctx.logger.error(error);
|
|
48
|
+
this.end();
|
|
49
|
+
this.ctx.res.end();
|
|
50
|
+
}
|
|
51
|
+
_flush(callback) {
|
|
52
|
+
this.ctx.res.end();
|
|
53
|
+
callback();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.HttpStreamResponse = HttpStreamResponse;
|
|
57
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -22,33 +22,37 @@ let MidwayMiddlewareService = class MidwayMiddlewareService {
|
|
|
22
22
|
this.applicationContext = applicationContext;
|
|
23
23
|
}
|
|
24
24
|
async compose(middleware, app, name) {
|
|
25
|
+
var _a;
|
|
25
26
|
if (!Array.isArray(middleware)) {
|
|
26
27
|
throw new error_1.MidwayParameterError('Middleware stack must be an array');
|
|
27
28
|
}
|
|
28
29
|
const newMiddlewareArr = [];
|
|
29
30
|
for (let fn of middleware) {
|
|
30
|
-
if (types_1.Types.isClass(fn) || typeof fn === 'string') {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
if (types_1.Types.isClass(fn) || typeof fn === 'string' || (fn === null || fn === void 0 ? void 0 : fn['middleware'])) {
|
|
32
|
+
let mw = (_a = fn === null || fn === void 0 ? void 0 : fn['middleware']) !== null && _a !== void 0 ? _a : fn;
|
|
33
|
+
const mwConfig = fn === null || fn === void 0 ? void 0 : fn['options'];
|
|
34
|
+
let mwName = fn === null || fn === void 0 ? void 0 : fn['name'];
|
|
35
|
+
if (typeof mw === 'string' &&
|
|
36
|
+
!this.applicationContext.hasDefinition(mw)) {
|
|
37
|
+
throw new error_1.MidwayCommonError(`Middleware definition of "${mw}" not found in midway container`);
|
|
34
38
|
}
|
|
35
|
-
const classMiddleware = await this.applicationContext.getAsync(
|
|
39
|
+
const classMiddleware = await this.applicationContext.getAsync(mw);
|
|
36
40
|
if (classMiddleware) {
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
mwName = mwName !== null && mwName !== void 0 ? mwName : classMiddleware.constructor.name;
|
|
42
|
+
mw = await classMiddleware.resolve(app, mwConfig);
|
|
43
|
+
if (!mw) {
|
|
39
44
|
// for middleware enabled
|
|
40
45
|
continue;
|
|
41
46
|
}
|
|
42
47
|
if (!classMiddleware.match && !classMiddleware.ignore) {
|
|
43
|
-
if (!
|
|
44
|
-
|
|
48
|
+
if (!mw.name) {
|
|
49
|
+
mw._name = mwName;
|
|
45
50
|
}
|
|
46
51
|
// just got fn
|
|
47
|
-
newMiddlewareArr.push(
|
|
52
|
+
newMiddlewareArr.push(mw);
|
|
48
53
|
}
|
|
49
54
|
else {
|
|
50
55
|
// wrap ignore and match
|
|
51
|
-
const mw = fn;
|
|
52
56
|
const match = (0, util_1.pathMatching)({
|
|
53
57
|
match: classMiddleware.match,
|
|
54
58
|
ignore: classMiddleware.ignore,
|
|
@@ -59,7 +63,7 @@ let MidwayMiddlewareService = class MidwayMiddlewareService {
|
|
|
59
63
|
return next();
|
|
60
64
|
return mw(ctx, next, options);
|
|
61
65
|
};
|
|
62
|
-
fn._name =
|
|
66
|
+
fn._name = mwName;
|
|
63
67
|
newMiddlewareArr.push(fn);
|
|
64
68
|
}
|
|
65
69
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midwayjs/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.17.0",
|
|
4
4
|
"description": "midway core",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@midwayjs/logger": "^3.0.0",
|
|
26
|
+
"eventsource": "2.0.2",
|
|
26
27
|
"koa": "2.15.3",
|
|
27
28
|
"mm": "3.4.0",
|
|
28
29
|
"raw-body": "2.5.2",
|
|
@@ -42,5 +43,5 @@
|
|
|
42
43
|
"engines": {
|
|
43
44
|
"node": ">=12"
|
|
44
45
|
},
|
|
45
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "21faf25ae7277f28d61f8416d1acd5a786a2c353"
|
|
46
47
|
}
|