kb-server 0.0.1-beta.1 → 0.0.1-beta.10

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/README.md CHANGED
@@ -2,4 +2,13 @@
2
2
 
3
3
  快速创建一个 Node 服务
4
4
 
5
- 快速创建API、标准错误码、Server
5
+ 快速创建 API、标准错误码、Server、支持统一鉴权函数(API 级别)
6
+
7
+ ```javascript
8
+ import { createServer } from "kb-server";
9
+ import * as apis from "./apis";
10
+
11
+ (async () => {
12
+ return createServer({ apis });
13
+ })().then((app) => app.listen(3000));
14
+ ```
@@ -1,5 +1,8 @@
1
1
  import express from "express";
2
- import { AnyAPIExecution } from "./create-api";
2
+ import { APIs } from "./create-api";
3
+ /**
4
+ * 正确响应
5
+ */
3
6
  export interface APIResponse {
4
7
  Response: {
5
8
  Data: {
@@ -8,6 +11,9 @@ export interface APIResponse {
8
11
  RequestId: string;
9
12
  };
10
13
  }
14
+ /**
15
+ * 错误响应
16
+ */
11
17
  export interface APIErrorResponse {
12
18
  Response: {
13
19
  Error: {
@@ -17,9 +23,15 @@ export interface APIErrorResponse {
17
23
  RequestId: string;
18
24
  };
19
25
  }
26
+ export type AuthFunction = (action: string, req: express.Request) => Promise<Record<string, any> | boolean> | boolean | Record<string, any>;
27
+ interface IPackAPIOptions {
28
+ authFn?: AuthFunction;
29
+ log?: boolean;
30
+ }
20
31
  /**
21
32
  * API包装函数
22
33
  * @param apis API列表
23
34
  * @returns
24
35
  */
25
- export declare const packAPI: (apis: Record<string, AnyAPIExecution>) => (req: express.Request, res: express.Response) => Promise<express.Response<any, Record<string, any>>>;
36
+ export declare const packAPI: (apis: APIs, options?: IPackAPIOptions) => (req: express.Request, res: express.Response) => Promise<express.Response<any, Record<string, any>>>;
37
+ export {};
@@ -3,12 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.packAPI = void 0;
4
4
  const create_errors_1 = require("./create-errors");
5
5
  const uuid_1 = require("uuid");
6
+ const logger_1 = require("../helper/logger");
6
7
  /**
7
8
  * API包装函数
8
9
  * @param apis API列表
9
10
  * @returns
10
11
  */
11
- const packAPI = (apis) => {
12
+ const packAPI = (apis, options) => {
13
+ const { authFn, log = true } = options || {};
12
14
  return async (req, res) => {
13
15
  // 生成API映射
14
16
  const apiMap = new Map(Object.entries(apis).map(([action, execution]) => [action, execution]));
@@ -22,13 +24,29 @@ const packAPI = (apis) => {
22
24
  RequestId: requestId,
23
25
  };
24
26
  try {
25
- console.log(req.body);
26
27
  // API 解析
27
28
  const { Action, ...params } = req.body || {};
29
+ if (log) {
30
+ logger_1.logger.log("info", `请求入参:${JSON.stringify(req.body)} - RequestId: ${requestId}`);
31
+ }
28
32
  // 接口未定义
29
33
  if (!Action) {
30
34
  throw new create_errors_1.CommonErrors.InvalidParameter.EmptyAPIRequest();
31
35
  }
36
+ // 处理鉴权函数
37
+ if (authFn !== null && authFn !== undefined) {
38
+ if (typeof authFn !== "function") {
39
+ throw new create_errors_1.CommonErrors.ResourceNotFound.AuthFunctionNotFound();
40
+ }
41
+ const authResult = await authFn(Action, req);
42
+ if (!authResult) {
43
+ throw new create_errors_1.CommonErrors.FailOperation.NoPermission();
44
+ }
45
+ if (typeof authResult !== "boolean") {
46
+ // 把权限信息写入上下文
47
+ ctx.AuthInfo = authResult || {};
48
+ }
49
+ }
32
50
  // API 处理
33
51
  const execution = apiMap.get(Action);
34
52
  if (typeof execution !== "function") {
@@ -45,11 +63,12 @@ const packAPI = (apis) => {
45
63
  };
46
64
  // 完成响应
47
65
  took = Date.now() - start;
48
- console.log("响应:", took, JSON.stringify(response));
66
+ logger_1.logger.log("info", response);
67
+ logger_1.logger.log("info", `耗时:${took} ms - RequestId: ${requestId}`);
49
68
  return res.send(response);
50
69
  }
51
70
  catch (rawError) {
52
- console.log("原始错误:", rawError);
71
+ logger_1.logger.log("error", rawError);
53
72
  // 未知错误
54
73
  let error = new create_errors_1.CommonErrors.InternalError.UnknownError();
55
74
  // 可控错误
@@ -71,7 +90,8 @@ const packAPI = (apis) => {
71
90
  };
72
91
  // 完成响应
73
92
  took = Date.now() - start;
74
- console.log("响应:", took, JSON.stringify(response));
93
+ logger_1.logger.log("info", response);
94
+ logger_1.logger.log("info", `耗时:${took} ms - RequestId: ${requestId}`);
75
95
  return res.send(response);
76
96
  }
77
97
  };
@@ -0,0 +1 @@
1
+ export declare const callService: <P = Record<string, any>, R = any>(endpoint: string, body: P) => Promise<R>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.callService = void 0;
7
+ const node_fetch_1 = __importDefault(require("node-fetch"));
8
+ const create_errors_1 = require("./create-errors");
9
+ const callService = async (endpoint, body) => {
10
+ const response = await (0, node_fetch_1.default)(endpoint, {
11
+ headers: {
12
+ "Content-Type": "application/json",
13
+ },
14
+ method: "POST",
15
+ body: JSON.stringify(body),
16
+ });
17
+ const result = await response.json();
18
+ if (result?.Response?.Error) {
19
+ const errMsg = result.Response.Error?.Message;
20
+ if (errMsg) {
21
+ throw new create_errors_1.CommonErrors.InternalError.ServiceError(errMsg);
22
+ }
23
+ throw new create_errors_1.CommonErrors.InternalError.ServiceError();
24
+ }
25
+ return result?.Response?.Data;
26
+ };
27
+ exports.callService = callService;
@@ -2,12 +2,17 @@ import { Class } from "utility-types";
2
2
  export interface ServerContext {
3
3
  /** 被调用方的 RequestId */
4
4
  RequestId: string;
5
- /** 用户ID */
6
- UserId?: number;
5
+ /** 权限信息 */
6
+ AuthInfo?: Record<string, any>;
7
7
  }
8
8
  export type API<P, R> = (param: P) => Promise<R>;
9
- export type APIExecution<P, R> = (params: P, ctx: ServerContext) => Promise<R>;
9
+ export type APIExecution<P, R> = (
10
+ /** 请求入参 */
11
+ params: P,
12
+ /** 请求上下文 */
13
+ ctx: ServerContext) => Promise<R>;
10
14
  export type AnyAPIExecution = APIExecution<any, any>;
15
+ export type APIs = Record<string, AnyAPIExecution>;
11
16
  export declare function createAPI<P, R>(ParamsClass: Class<P>, execution: APIExecution<P, R>): API<P, R>;
12
17
  type StubParam<T> = T extends (params: infer P) => any ? P : never;
13
18
  export declare function implementAPI<A extends (params: any) => any>(_actionStub: A, ParamsClass: Class<StubParam<A>>, execution: APIExecution<StubParam<A>, ReturnType<A>>): API<StubParam<A>, ReturnType<A>>;
@@ -24,6 +24,7 @@ declare const CommonErrorsMap: {
24
24
  };
25
25
  readonly ResourceNotFound: {
26
26
  readonly APINotFound: "不存在的API";
27
+ readonly AuthFunctionNotFound: "鉴权函数不存在";
27
28
  };
28
29
  readonly FailOperation: {
29
30
  readonly NoPermission: "无权操作";
@@ -79,6 +80,7 @@ declare function createErrorsClasses<T extends MessageMap = MessageMap>(messageM
79
80
  };
80
81
  readonly ResourceNotFound: {
81
82
  readonly APINotFound: "不存在的API";
83
+ readonly AuthFunctionNotFound: "鉴权函数不存在";
82
84
  };
83
85
  readonly FailOperation: {
84
86
  readonly NoPermission: "无权操作";
@@ -103,6 +105,7 @@ export declare const CommonErrors: ErrorClasses<MergeMessageMap<{
103
105
  };
104
106
  readonly ResourceNotFound: {
105
107
  readonly APINotFound: "不存在的API";
108
+ readonly AuthFunctionNotFound: "鉴权函数不存在";
106
109
  };
107
110
  readonly FailOperation: {
108
111
  readonly NoPermission: "无权操作";
@@ -26,6 +26,7 @@ const CommonErrorsMap = {
26
26
  },
27
27
  ResourceNotFound: {
28
28
  APINotFound: "不存在的API",
29
+ AuthFunctionNotFound: "鉴权函数不存在",
29
30
  },
30
31
  FailOperation: {
31
32
  NoPermission: "无权操作",
@@ -1,6 +1,20 @@
1
- import { AnyAPIExecution } from "./create-api";
1
+ import { AuthFunction } from "./api-middleware";
2
+ import { APIs } from "./create-api";
2
3
  export interface ICreateServerParams {
3
- apis: Record<string, AnyAPIExecution>;
4
+ /**
5
+ * API列表
6
+ */
7
+ apis: APIs;
8
+ /**
9
+ * 鉴权函数
10
+ *
11
+ * 可以通过返回布尔值来定义权限,也可以直接返回数据对象,数据对象会被传递到上下文 ctx 中(AuthInfo)
12
+ */
13
+ authFn?: AuthFunction;
14
+ /**
15
+ * 默认请求日志,true开启,false关闭
16
+ */
17
+ log?: boolean;
4
18
  }
5
19
  export interface ICreateServerOptions {
6
20
  limit?: string | number | undefined;
@@ -30,14 +30,14 @@ const api_middleware_1 = require("./api-middleware");
30
30
  * 创建 Server
31
31
  */
32
32
  function createServer(params, options) {
33
- const { apis } = params || {};
33
+ const { apis, authFn, log } = params || {};
34
34
  const { limit = "10mb" } = options || {};
35
35
  const app = (0, express_1.default)();
36
36
  // POST 参数获取
37
37
  app.use((0, express_1.urlencoded)({ extended: true, limit }));
38
38
  app.use((0, express_1.json)({ limit }));
39
39
  // 注入API
40
- app.use((0, api_middleware_1.packAPI)(apis));
40
+ app.use((0, api_middleware_1.packAPI)(apis, { authFn, log }));
41
41
  return app;
42
42
  }
43
43
  exports.createServer = createServer;
@@ -0,0 +1,6 @@
1
+ export declare const logger: {
2
+ log: typeof log;
3
+ };
4
+ type LogLevel = "info" | "error" | "warning";
5
+ declare function log(level: LogLevel, message: unknown): void;
6
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.logger = void 0;
7
+ const moment_1 = __importDefault(require("moment"));
8
+ exports.logger = { log };
9
+ function log(level, message) {
10
+ const logTime = (0, moment_1.default)().format(`YYYY-MM-DD HH:ss:mm`);
11
+ if (typeof message === "object") {
12
+ console.log(`[${level}] - [${logTime}] - ${JSON.stringify(message)}`);
13
+ }
14
+ else {
15
+ console.log(`[${level}] - [${logTime}] - ${message}`);
16
+ }
17
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { createServer } from "./common/create-server";
2
- export { createErrors, CommonErrors } from "./common/create-errors";
2
+ export { createErrors } from "./common/create-errors";
3
3
  export { implementAPI } from "./common/create-api";
package/dist/index.js CHANGED
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.implementAPI = exports.CommonErrors = exports.createErrors = exports.createServer = void 0;
3
+ exports.implementAPI = exports.createErrors = exports.createServer = void 0;
4
4
  var create_server_1 = require("./common/create-server");
5
5
  Object.defineProperty(exports, "createServer", { enumerable: true, get: function () { return create_server_1.createServer; } });
6
6
  var create_errors_1 = require("./common/create-errors");
7
7
  Object.defineProperty(exports, "createErrors", { enumerable: true, get: function () { return create_errors_1.createErrors; } });
8
- Object.defineProperty(exports, "CommonErrors", { enumerable: true, get: function () { return create_errors_1.CommonErrors; } });
9
8
  var create_api_1 = require("./common/create-api");
10
9
  Object.defineProperty(exports, "implementAPI", { enumerable: true, get: function () { return create_api_1.implementAPI; } });
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "kb-server",
3
- "version": "0.0.1-beta.1",
3
+ "version": "0.0.1-beta.10",
4
4
  "description": "A fast server for Node.JS,made by express.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
- "build": "tsc",
7
+ "build": "rm -rf ./dist && tsc",
8
8
  "test": "echo \"Error: no test specified\" && exit 1"
9
9
  },
10
10
  "keywords": [
@@ -23,10 +23,13 @@
23
23
  "class-validator": "^0.14.1",
24
24
  "express": "^4.21.1",
25
25
  "is-plain-object": "^5.0.0",
26
+ "moment": "^2.30.1",
27
+ "node-fetch": "^2.7.0",
26
28
  "utility-types": "^3.11.0",
27
29
  "uuid": "^11.0.3"
28
30
  },
29
31
  "devDependencies": {
30
- "@types/express": "^4.17.21"
32
+ "@types/express": "^4.17.21",
33
+ "@types/node-fetch": "^2.6.12"
31
34
  }
32
35
  }