kb-server 0.0.1-beta.20 → 0.0.1-beta.22
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/create-errors.d.ts +3 -0
- package/dist/common/create-errors.js +1 -0
- package/dist/common/create-server.d.ts +12 -2
- package/dist/common/create-sse.d.ts +27 -0
- package/dist/common/create-sse.js +31 -0
- package/dist/common/sse-middleware.d.ts +2 -16
- package/dist/common/sse-middleware.js +15 -9
- package/package.json +2 -2
|
@@ -21,6 +21,7 @@ declare const CommonErrorsMap: {
|
|
|
21
21
|
readonly EmptyParameter: "请求参数不能为空";
|
|
22
22
|
readonly EmptyAPIRequest: "未指定API的请求";
|
|
23
23
|
readonly ValidationError: "参数校验失败";
|
|
24
|
+
readonly RouteError: "路由错误";
|
|
24
25
|
};
|
|
25
26
|
readonly ResourceNotFound: {
|
|
26
27
|
readonly APINotFound: "不存在的API";
|
|
@@ -77,6 +78,7 @@ declare function createErrorsClasses<T extends MessageMap = MessageMap>(messageM
|
|
|
77
78
|
readonly EmptyParameter: "请求参数不能为空";
|
|
78
79
|
readonly EmptyAPIRequest: "未指定API的请求";
|
|
79
80
|
readonly ValidationError: "参数校验失败";
|
|
81
|
+
readonly RouteError: "路由错误";
|
|
80
82
|
};
|
|
81
83
|
readonly ResourceNotFound: {
|
|
82
84
|
readonly APINotFound: "不存在的API";
|
|
@@ -102,6 +104,7 @@ export declare const CommonErrors: ErrorClasses<MergeMessageMap<{
|
|
|
102
104
|
readonly EmptyParameter: "请求参数不能为空";
|
|
103
105
|
readonly EmptyAPIRequest: "未指定API的请求";
|
|
104
106
|
readonly ValidationError: "参数校验失败";
|
|
107
|
+
readonly RouteError: "路由错误";
|
|
105
108
|
};
|
|
106
109
|
readonly ResourceNotFound: {
|
|
107
110
|
readonly APINotFound: "不存在的API";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import express from "express";
|
|
2
2
|
import { AuthFunction } from "./api-middleware";
|
|
3
3
|
import { APIs } from "./create-api";
|
|
4
|
-
import {
|
|
4
|
+
import { SseHandlers } from "./create-sse";
|
|
5
5
|
export interface ICreateServerParams {
|
|
6
6
|
/**
|
|
7
7
|
* API列表
|
|
@@ -11,7 +11,17 @@ export interface ICreateServerParams {
|
|
|
11
11
|
* SSE配置
|
|
12
12
|
*/
|
|
13
13
|
sse?: {
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* SSE API列表
|
|
16
|
+
*/
|
|
17
|
+
handlers: SseHandlers;
|
|
18
|
+
/**
|
|
19
|
+
* SSE 监听的路由,例如:`/sse/generate`
|
|
20
|
+
*
|
|
21
|
+
* 注意:路由要以 `/` 开头
|
|
22
|
+
*
|
|
23
|
+
* 默认为:`/sse`
|
|
24
|
+
*/
|
|
15
25
|
route?: string;
|
|
16
26
|
};
|
|
17
27
|
/**
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Class } from "utility-types";
|
|
2
|
+
import { ServerContext } from "./create-api";
|
|
3
|
+
export type API<P, R> = (param: P) => Promise<R>;
|
|
4
|
+
export type SseExecution<P, R, A> = (
|
|
5
|
+
/** 请求入参 */
|
|
6
|
+
params: P,
|
|
7
|
+
/** 请求上下文 */
|
|
8
|
+
ctx: ServerContext<A>,
|
|
9
|
+
/**
|
|
10
|
+
* 操作函数
|
|
11
|
+
*/
|
|
12
|
+
operations: {
|
|
13
|
+
/**
|
|
14
|
+
* 向客户端推送消息
|
|
15
|
+
*/
|
|
16
|
+
send: (event: string, message: string) => void;
|
|
17
|
+
/**
|
|
18
|
+
* 推送完毕回调
|
|
19
|
+
*/
|
|
20
|
+
done: () => void;
|
|
21
|
+
}) => Promise<R>;
|
|
22
|
+
export type AnySseExecution = SseExecution<any, any, any>;
|
|
23
|
+
export type SseHandlers = Record<string, AnySseExecution>;
|
|
24
|
+
export declare function createSseAPI<P, R, A>(ParamsClass: Class<P>, execution: SseExecution<P, R, A>): API<P, R>;
|
|
25
|
+
type StubParam<T> = T extends (params: infer P) => any ? P : never;
|
|
26
|
+
export declare function implementSseAPI<F extends (params: any) => any, A = Record<string, any>>(_actionStub: F, ParamsClass: Class<StubParam<F>>, execution: SseExecution<StubParam<F>, ReturnType<F>, A>): API<StubParam<F>, ReturnType<F>>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.implementSseAPI = exports.createSseAPI = void 0;
|
|
4
|
+
const class_transformer_1 = require("class-transformer");
|
|
5
|
+
const class_validator_1 = require("class-validator");
|
|
6
|
+
const create_errors_1 = require("./create-errors");
|
|
7
|
+
const create_api_1 = require("./create-api");
|
|
8
|
+
function createSseAPI(ParamsClass, execution) {
|
|
9
|
+
const runtime = async (params, ctx, operations) => {
|
|
10
|
+
if (!params) {
|
|
11
|
+
throw new create_errors_1.CommonErrors.InvalidParameter.EmptyParameter();
|
|
12
|
+
}
|
|
13
|
+
// 校验参数
|
|
14
|
+
const paramsToCheck = params instanceof ParamsClass
|
|
15
|
+
? params
|
|
16
|
+
: (0, class_transformer_1.plainToClass)(ParamsClass, params);
|
|
17
|
+
const errors = await (0, class_validator_1.validate)(paramsToCheck || {});
|
|
18
|
+
if (errors?.length) {
|
|
19
|
+
const errorMessages = errors.flatMap((error) => (0, create_api_1.getMessage)(error));
|
|
20
|
+
throw new create_errors_1.CommonErrors.InvalidParameter.ValidationError(errorMessages.join("\n"));
|
|
21
|
+
}
|
|
22
|
+
// 执行函数
|
|
23
|
+
return await execution(params, ctx, operations);
|
|
24
|
+
};
|
|
25
|
+
return runtime;
|
|
26
|
+
}
|
|
27
|
+
exports.createSseAPI = createSseAPI;
|
|
28
|
+
function implementSseAPI(_actionStub, ParamsClass, execution) {
|
|
29
|
+
return createSseAPI(ParamsClass, execution);
|
|
30
|
+
}
|
|
31
|
+
exports.implementSseAPI = implementSseAPI;
|
|
@@ -1,25 +1,11 @@
|
|
|
1
1
|
import express from "express";
|
|
2
|
-
import { ServerContext } from "./create-api";
|
|
3
2
|
import { AuthFunction } from "./api-middleware";
|
|
4
|
-
|
|
5
|
-
/** 请求入参 */
|
|
6
|
-
params: P,
|
|
7
|
-
/** 请求上下文 */
|
|
8
|
-
ctx: ServerContext<A>,
|
|
9
|
-
/**
|
|
10
|
-
* 允许执行的操作
|
|
11
|
-
*/
|
|
12
|
-
operations: {
|
|
13
|
-
/** 发送消息 */
|
|
14
|
-
send: (event: string, message: string) => void;
|
|
15
|
-
}) => Promise<R>;
|
|
16
|
-
export type AnySseExecution = SseExecution<any, any, any>;
|
|
17
|
-
export type SSEHandlers = Record<string, AnySseExecution>;
|
|
3
|
+
import { SseHandlers } from "./create-sse";
|
|
18
4
|
interface IPackSSEOptions {
|
|
19
5
|
authFn?: AuthFunction;
|
|
20
6
|
route?: string;
|
|
21
7
|
log?: boolean;
|
|
22
8
|
}
|
|
23
|
-
export declare const packSSE: (sseHandlers:
|
|
9
|
+
export declare const packSSE: (sseHandlers: SseHandlers, options?: IPackSSEOptions) => express.RequestHandler;
|
|
24
10
|
export declare const createSSEMessage: (event: string, message: string) => string;
|
|
25
11
|
export {};
|
|
@@ -12,8 +12,12 @@ const packSSE = (sseHandlers, options) => {
|
|
|
12
12
|
]));
|
|
13
13
|
const { authFn, log = true, route = "/sse" } = options || {};
|
|
14
14
|
return async (req, res, next) => {
|
|
15
|
+
const isValidRoute = route.startsWith("/");
|
|
16
|
+
if (!isValidRoute) {
|
|
17
|
+
throw new create_errors_1.CommonErrors.InvalidParameter.RouteError();
|
|
18
|
+
}
|
|
15
19
|
const { path } = req;
|
|
16
|
-
//
|
|
20
|
+
// SSE的路径直接往后走
|
|
17
21
|
if (path !== route) {
|
|
18
22
|
next();
|
|
19
23
|
return;
|
|
@@ -66,18 +70,20 @@ const packSSE = (sseHandlers, options) => {
|
|
|
66
70
|
* 统一管理请求头
|
|
67
71
|
*
|
|
68
72
|
*/
|
|
69
|
-
// 处理SSE
|
|
70
73
|
res.writeHead(200, {
|
|
71
74
|
"Content-Type": "text/event-stream",
|
|
72
75
|
"Cache-Control": "no-cache",
|
|
73
76
|
Connection: "keep-alive",
|
|
74
77
|
});
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
await new Promise((resolve) => {
|
|
79
|
+
const send = (event, message) => {
|
|
80
|
+
const response = (0, exports.createSSEMessage)(event, message);
|
|
81
|
+
res.write(response);
|
|
82
|
+
logger_1.logger.log("info", `发送消息:\n${response}`);
|
|
83
|
+
};
|
|
84
|
+
const done = () => resolve(true);
|
|
85
|
+
execution(params, ctx, { send, done });
|
|
86
|
+
});
|
|
81
87
|
// 完成响应
|
|
82
88
|
took = Date.now() - start;
|
|
83
89
|
logger_1.logger.log("info", `耗时:${took} ms - RequestId: ${requestId}`);
|
|
@@ -106,7 +112,7 @@ const packSSE = (sseHandlers, options) => {
|
|
|
106
112
|
}));
|
|
107
113
|
// 完成响应
|
|
108
114
|
took = Date.now() - start;
|
|
109
|
-
logger_1.logger.log("info",
|
|
115
|
+
logger_1.logger.log("info", `发送消息:\n${response}`);
|
|
110
116
|
logger_1.logger.log("info", `耗时:${took} ms - RequestId: ${requestId}`);
|
|
111
117
|
res.write(response);
|
|
112
118
|
return res.end();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kb-server",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.22",
|
|
4
4
|
"description": "A fast server for Node.JS,made by express.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"express": "^4.21.1",
|
|
25
25
|
"is-plain-object": "^5.0.0",
|
|
26
26
|
"moment": "^2.30.1",
|
|
27
|
-
"nanoid": "^
|
|
27
|
+
"nanoid": "^3.3.9",
|
|
28
28
|
"node-fetch": "^2.7.0",
|
|
29
29
|
"utility-types": "^3.11.0",
|
|
30
30
|
"uuid": "^11.0.3"
|