@rdyl/node-koa-controller 0.5.6 → 0.5.8

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 CHANGED
@@ -1,4 +1,4 @@
1
- ## 0.5.5 (2025-12-31)
1
+ ## 0.5.7 (2026-01-07)
2
2
 
3
3
 
4
4
 
package/dist/cache.js CHANGED
@@ -107,9 +107,9 @@ var ASTCache = /** @class */ (function () {
107
107
  }); });
108
108
  var hasLogs = Boolean(ASTCache.logs);
109
109
  ASTCache.routes.forEach(function (route) {
110
- var handlers = route.handlers, prefix = route.prefix, Instance = route.Instance;
110
+ var handlers = route.handlers, prefix = route.prefix, Instance = route.Instance, cAuth = route.auth;
111
111
  handlers.forEach(function (handler) {
112
- var method = handler.method, url = handler.url, name = handler.name;
112
+ var method = handler.method, url = handler.url, name = handler.name, hAuth = handler.auth;
113
113
  var path = (0, path_1.join)("/" + ASTCache.prefix, prefix, url);
114
114
  var isPublic = route.isPublic || handler.isPublic;
115
115
  if (isPublic) {
@@ -125,61 +125,68 @@ var ASTCache = /** @class */ (function () {
125
125
  }
126
126
  });
127
127
  }); };
128
- var execWithJwt = !!useJwt
129
- ? isPublic
130
- ? function (instance) { return __awaiter(_this, void 0, void 0, function () {
128
+ var enabledAuth = (0, utils_1.ParsedAuthControl)(hAuth, cAuth);
129
+ var execWithJwt = (function () {
130
+ if (useJwt) {
131
+ if (isPublic) {
132
+ // 非权限控制接口
133
+ return function (instance) { return __awaiter(_this, void 0, void 0, function () {
134
+ var jwt;
135
+ return __generator(this, function (_a) {
136
+ switch (_a.label) {
137
+ case 0: return [4 /*yield*/, useJwt(instance._ctx)];
138
+ case 1:
139
+ jwt = _a.sent();
140
+ if (jwt) {
141
+ instance.jwt = jwt;
142
+ }
143
+ return [4 /*yield*/, next(instance)];
144
+ case 2:
145
+ _a.sent();
146
+ return [2 /*return*/];
147
+ }
148
+ });
149
+ }); };
150
+ }
151
+ return function (instance) { return __awaiter(_this, void 0, void 0, function () {
131
152
  var jwt;
132
153
  return __generator(this, function (_a) {
133
154
  switch (_a.label) {
134
155
  case 0: return [4 /*yield*/, useJwt(instance._ctx)];
135
156
  case 1:
136
157
  jwt = _a.sent();
137
- if (jwt) {
138
- instance.jwt = jwt;
139
- }
158
+ if (!jwt)
159
+ return [2 /*return*/, instance.status.unauthorized()];
160
+ if (!enabledAuth(jwt.permissions))
161
+ return [2 /*return*/, instance.status.inaccessible()];
162
+ instance.jwt = jwt;
140
163
  return [4 /*yield*/, next(instance)];
141
164
  case 2:
142
165
  _a.sent();
143
166
  return [2 /*return*/];
144
167
  }
145
168
  });
146
- }); }
147
- : function (instance) { return __awaiter(_this, void 0, void 0, function () {
148
- var jwt;
169
+ }); };
170
+ }
171
+ return next;
172
+ })();
173
+ var routerHandler = (function () {
174
+ if (hasLogs) {
175
+ return function (ctx) { return __awaiter(_this, void 0, void 0, function () {
176
+ var instance;
149
177
  return __generator(this, function (_a) {
150
178
  switch (_a.label) {
151
- case 0: return [4 /*yield*/, useJwt(instance._ctx)];
179
+ case 0:
180
+ instance = new Instance(ctx);
181
+ return [4 /*yield*/, (0, utils_1.LogsHandler)(ctx, function () { return execWithJwt(instance); })];
152
182
  case 1:
153
- jwt = _a.sent();
154
- if (!jwt) {
155
- return [2 /*return*/, instance.status.unauthorized()];
156
- }
157
- if (jwt) {
158
- instance.jwt = jwt;
159
- }
160
- return [4 /*yield*/, next(instance)];
161
- case 2:
162
183
  _a.sent();
163
184
  return [2 /*return*/];
164
185
  }
165
186
  });
166
- }); }
167
- : next;
168
- var finalHandler = hasLogs
169
- ? function (ctx) { return __awaiter(_this, void 0, void 0, function () {
170
- var instance;
171
- return __generator(this, function (_a) {
172
- switch (_a.label) {
173
- case 0:
174
- instance = new Instance(ctx);
175
- return [4 /*yield*/, (0, utils_1.LogsHandler)(ctx, function () { return execWithJwt(instance); })];
176
- case 1:
177
- _a.sent();
178
- return [2 /*return*/];
179
- }
180
- });
181
- }); }
182
- : function (ctx) { return __awaiter(_this, void 0, void 0, function () {
187
+ }); };
188
+ }
189
+ return function (ctx) { return __awaiter(_this, void 0, void 0, function () {
183
190
  var instance;
184
191
  return __generator(this, function (_a) {
185
192
  switch (_a.label) {
@@ -192,8 +199,9 @@ var ASTCache = /** @class */ (function () {
192
199
  }
193
200
  });
194
201
  }); };
202
+ })();
195
203
  // @ts-ignore
196
- router[method.toLowerCase()](path, finalHandler);
204
+ router[method.toLowerCase()](path, routerHandler);
197
205
  });
198
206
  });
199
207
  };
@@ -6,6 +6,7 @@ function parseASTRoutes(routes) {
6
6
  return routes.map(function (ele) {
7
7
  return {
8
8
  name: ele.prefix,
9
+ tag: ele.auth.isPublic ? "public" : "",
9
10
  handlers: ele.handlers.map(function (item) {
10
11
  var url = utils_1.Uri.join([ele.prefix, item.url]);
11
12
  return {
@@ -14,6 +15,7 @@ function parseASTRoutes(routes) {
14
15
  url: url,
15
16
  jsUrl: "`" + url.replace(new RegExp("{", "g"), "${") + "`",
16
17
  methodColor: "red",
18
+ tag: item.auth.isPublic ? "public" : "",
17
19
  };
18
20
  }),
19
21
  };
package/dist/meta.js CHANGED
@@ -41,6 +41,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
42
  exports.Patch = exports.Put = exports.Delete = exports.Post = exports.Get = exports.BaseController = exports.HttpMethod = void 0;
43
43
  exports.Controller = Controller;
44
+ exports.AuthControl = AuthControl;
44
45
  var cache_1 = __importDefault(require("./cache"));
45
46
  var HttpMethod;
46
47
  (function (HttpMethod) {
@@ -54,8 +55,9 @@ var BaseController = /** @class */ (function () {
54
55
  function BaseController(_ctx) {
55
56
  this._ctx = _ctx;
56
57
  this.jwt = {
57
- token: "",
58
- value: {},
58
+ token: '',
59
+ current: {},
60
+ permissions: [],
59
61
  };
60
62
  }
61
63
  Object.defineProperty(BaseController.prototype, "pathname", {
@@ -70,16 +72,6 @@ var BaseController = /** @class */ (function () {
70
72
  var values = this._ctx.query;
71
73
  return {
72
74
  values: values,
73
- getPaged: function (def) {
74
- if (def === void 0) { def = {}; }
75
- var p = Number(values.page);
76
- var s = Number(values.pageSize);
77
- var _a = def.page, dPage = _a === void 0 ? 1 : _a, _b = def.pageSize, dPageSize = _b === void 0 ? 20 : _b;
78
- return {
79
- page: isNaN(p) ? dPage : p,
80
- pageSize: isNaN(s) ? dPageSize : s,
81
- };
82
- },
83
75
  getNumber: function (k) {
84
76
  var n = values[k];
85
77
  if (!n)
@@ -93,7 +85,7 @@ var BaseController = /** @class */ (function () {
93
85
  var b = values[k];
94
86
  if (!b)
95
87
  return null;
96
- if (b === "1" || b === "true" || b === "TRUE") {
88
+ if (b === '1' || b === 'true' || b === 'TRUE') {
97
89
  return true;
98
90
  }
99
91
  return false;
@@ -105,7 +97,28 @@ var BaseController = /** @class */ (function () {
105
97
  });
106
98
  Object.defineProperty(BaseController.prototype, "params", {
107
99
  get: function () {
108
- return this._ctx.params || {};
100
+ var values = this._ctx.params || {};
101
+ return {
102
+ values: values,
103
+ getNumber: function (k) {
104
+ var n = values[k];
105
+ if (!n)
106
+ return null;
107
+ var value = Number(n);
108
+ if (isNaN(value))
109
+ return null;
110
+ return value;
111
+ },
112
+ getBool: function (k) {
113
+ var b = values[k];
114
+ if (!b)
115
+ return null;
116
+ if (b === '1' || b === 'true' || b === 'TRUE') {
117
+ return true;
118
+ }
119
+ return false;
120
+ },
121
+ };
109
122
  },
110
123
  enumerable: false,
111
124
  configurable: true
@@ -130,7 +143,7 @@ var BaseController = /** @class */ (function () {
130
143
  get: function () {
131
144
  var _this = this;
132
145
  var sendJson = function (body) {
133
- _this._ctx.response.set("Content-Type", "application/json;charset=utf-8");
146
+ _this._ctx.response.set('Content-Type', 'application/json;charset=utf-8');
134
147
  _this._ctx.status = body.code;
135
148
  _this._ctx.body = body;
136
149
  };
@@ -138,39 +151,39 @@ var BaseController = /** @class */ (function () {
138
151
  raw: function (body, headers) {
139
152
  var _a;
140
153
  if (headers === void 0) { headers = {}; }
141
- _this._ctx.response.set("Content-Type", (_a = headers["Content-Type"]) !== null && _a !== void 0 ? _a : "application/json;charset=utf-8");
154
+ _this._ctx.response.set('Content-Type', (_a = headers['Content-Type']) !== null && _a !== void 0 ? _a : 'application/json;charset=utf-8');
142
155
  _this._ctx.status = 200;
143
156
  _this._ctx.body = body;
144
157
  },
145
158
  ok: function (data) {
146
- sendJson({ data: data, code: 200, msg: "ok" });
159
+ sendJson({ data: data, code: 200, msg: 'ok' });
147
160
  },
148
161
  okCreated: function (data, msg) {
149
- if (msg === void 0) { msg = "ok created"; }
162
+ if (msg === void 0) { msg = 'ok created'; }
150
163
  sendJson({ code: 201, data: data, msg: msg });
151
164
  },
152
165
  okAccept: function (data, msg) {
153
- if (msg === void 0) { msg = "ok accept"; }
166
+ if (msg === void 0) { msg = 'ok accept'; }
154
167
  sendJson({ code: 203, data: data, msg: msg });
155
168
  },
156
169
  parameterError: function (msg) {
157
- if (msg === void 0) { msg = "Parameter Error"; }
170
+ if (msg === void 0) { msg = 'Parameter Error'; }
158
171
  sendJson({ msg: msg, code: 400 });
159
172
  },
160
173
  unauthorized: function (msg) {
161
- if (msg === void 0) { msg = "User Unauthorized"; }
174
+ if (msg === void 0) { msg = 'User Unauthorized'; }
162
175
  sendJson({ msg: msg, code: 401 });
163
176
  },
164
177
  inaccessible: function (msg) {
165
- if (msg === void 0) { msg = "User Inaccessible"; }
178
+ if (msg === void 0) { msg = 'User Inaccessible'; }
166
179
  sendJson({ msg: msg, code: 403 });
167
180
  },
168
181
  exception: function (msg) {
169
- if (msg === void 0) { msg = "Service Exception"; }
182
+ if (msg === void 0) { msg = 'Service Exception'; }
170
183
  sendJson({ msg: msg, code: 500 });
171
184
  },
172
185
  unavailable: function (msg) {
173
- if (msg === void 0) { msg = "Service Unavailable"; }
186
+ if (msg === void 0) { msg = 'Service Unavailable'; }
174
187
  sendJson({ msg: msg, code: 503 });
175
188
  },
176
189
  };
@@ -182,14 +195,17 @@ var BaseController = /** @class */ (function () {
182
195
  }());
183
196
  exports.BaseController = BaseController;
184
197
  function MethodFactory(method) {
185
- return function (url, isPublic) {
186
- if (isPublic === void 0) { isPublic = false; }
198
+ return function (url) {
187
199
  return function (target, name) {
200
+ console.log('method', name);
188
201
  var item = {
189
202
  url: url,
190
203
  method: method,
191
204
  name: name,
192
- isPublic: isPublic,
205
+ isPublic: false,
206
+ auth: {
207
+ isPublic: false,
208
+ },
193
209
  };
194
210
  if (target.routes) {
195
211
  target.routes.push(item);
@@ -200,19 +216,47 @@ function MethodFactory(method) {
200
216
  };
201
217
  };
202
218
  }
203
- function Controller(prefix, isPublic) {
204
- if (isPublic === void 0) { isPublic = false; }
219
+ function Controller(prefix) {
205
220
  return function (target) {
206
221
  var _a;
207
222
  var route = {
208
223
  Instance: target,
209
224
  prefix: prefix,
210
225
  handlers: ((_a = target.prototype) === null || _a === void 0 ? void 0 : _a.routes) || [],
211
- isPublic: isPublic,
226
+ isPublic: false,
227
+ auth: {
228
+ isPublic: false,
229
+ },
212
230
  };
213
231
  cache_1.default.routes.push(route);
214
232
  };
215
233
  }
234
+ function AuthControl(name, mode) {
235
+ return function (target, method) {
236
+ if (method) {
237
+ target.routes.forEach(function (ele) {
238
+ if (ele.name === method) {
239
+ ele.auth = {
240
+ isPublic: name === null,
241
+ name: name || [],
242
+ mode: mode,
243
+ };
244
+ }
245
+ });
246
+ }
247
+ else {
248
+ cache_1.default.routes.forEach(function (ele) {
249
+ if (ele.Instance === target) {
250
+ ele.auth = {
251
+ isPublic: name === null,
252
+ name: name || [],
253
+ mode: mode,
254
+ };
255
+ }
256
+ });
257
+ }
258
+ };
259
+ }
216
260
  exports.Get = MethodFactory(HttpMethod.GET);
217
261
  exports.Post = MethodFactory(HttpMethod.POST);
218
262
  exports.Delete = MethodFactory(HttpMethod.DELETE);
package/dist/utils.js CHANGED
@@ -43,6 +43,7 @@ exports.Uri = void 0;
43
43
  exports.formatDateTime = formatDateTime;
44
44
  exports.getIPAdress = getIPAdress;
45
45
  exports.LogsHandler = LogsHandler;
46
+ exports.ParsedAuthControl = ParsedAuthControl;
46
47
  var os_1 = __importDefault(require("os"));
47
48
  var chalk_1 = __importDefault(require("chalk"));
48
49
  exports.Uri = {
@@ -139,3 +140,55 @@ function LogsHandler(ctx, next) {
139
140
  });
140
141
  });
141
142
  }
143
+ function ParsedAuthControl() {
144
+ var auths = [];
145
+ for (var _i = 0; _i < arguments.length; _i++) {
146
+ auths[_i] = arguments[_i];
147
+ }
148
+ if (!auths.length)
149
+ return function (_perms) { return true; };
150
+ // 预处理规则(只执行一次)
151
+ var required = [];
152
+ var any = [];
153
+ for (var _a = 0, auths_1 = auths; _a < auths_1.length; _a++) {
154
+ var auth = auths_1[_a];
155
+ var _b = auth.mode, mode = _b === void 0 ? "AND" : _b, _c = auth.name, name_1 = _c === void 0 ? [] : _c, isPublic = auth.isPublic;
156
+ if (isPublic)
157
+ continue;
158
+ var keys = typeof name_1 === "string" ? [name_1] : name_1;
159
+ if (!keys.length)
160
+ continue;
161
+ if (mode === "OR") {
162
+ any.push(keys);
163
+ }
164
+ else {
165
+ required.push.apply(required, keys);
166
+ }
167
+ }
168
+ // 返回真正的校验函数(高频调用)
169
+ return function (perms) {
170
+ if (perms === void 0) { perms = []; }
171
+ var permSet = new Set(perms);
172
+ // AND:必须全部存在
173
+ for (var _i = 0, required_1 = required; _i < required_1.length; _i++) {
174
+ var key = required_1[_i];
175
+ if (!permSet.has(key))
176
+ return false;
177
+ }
178
+ // OR:每一组至少命中一个
179
+ for (var _a = 0, any_1 = any; _a < any_1.length; _a++) {
180
+ var group = any_1[_a];
181
+ var hit = false;
182
+ for (var _b = 0, group_1 = group; _b < group_1.length; _b++) {
183
+ var key = group_1[_b];
184
+ if (permSet.has(key)) {
185
+ hit = true;
186
+ break;
187
+ }
188
+ }
189
+ if (!hit)
190
+ return false;
191
+ }
192
+ return true;
193
+ };
194
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rdyl/node-koa-controller",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "types/index.d.ts",
@@ -1,11 +1,13 @@
1
1
  import { ASTCacheRoute } from "../meta";
2
2
  export declare function parseASTRoutes(routes: ASTCacheRoute[]): {
3
3
  name: string;
4
+ tag: string;
4
5
  handlers: {
5
6
  method: string;
6
7
  name: string;
7
8
  url: string;
8
9
  jsUrl: string;
9
10
  methodColor: string;
11
+ tag: string;
10
12
  }[];
11
13
  }[];
package/types/meta.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { ParameterizedContext } from "koa";
2
- import { ExtendedFormidableOptions } from "koa-body";
1
+ import { ParameterizedContext } from 'koa';
2
+ import { ExtendedFormidableOptions } from 'koa-body';
3
3
  export type KoaCtx = ParameterizedContext<any, any, any>;
4
4
  export declare enum HttpMethod {
5
5
  GET = "GET",
@@ -15,17 +15,14 @@ export declare class BaseController {
15
15
  get pathname(): any;
16
16
  get query(): {
17
17
  values: any;
18
- getPaged(def?: Partial<{
19
- page: number;
20
- pageSize: number;
21
- }>): {
22
- page: number;
23
- pageSize: number;
24
- };
25
18
  getNumber(k: string): number | null;
26
19
  getBool(k: string): boolean | null;
27
20
  };
28
- get params(): any;
21
+ get params(): {
22
+ values: any;
23
+ getNumber(k: string): number | null;
24
+ getBool(k: string): boolean | null;
25
+ };
29
26
  get body(): any;
30
27
  files(): Promise<any>;
31
28
  get status(): {
@@ -40,12 +37,13 @@ export declare class BaseController {
40
37
  unavailable(msg?: string): void;
41
38
  };
42
39
  }
43
- export declare function Controller(prefix: string, isPublic?: boolean): (target: any) => void;
44
- export declare const Get: (url: string, isPublic?: boolean) => (target: any, name: string) => void;
45
- export declare const Post: (url: string, isPublic?: boolean) => (target: any, name: string) => void;
46
- export declare const Delete: (url: string, isPublic?: boolean) => (target: any, name: string) => void;
47
- export declare const Put: (url: string, isPublic?: boolean) => (target: any, name: string) => void;
48
- export declare const Patch: (url: string, isPublic?: boolean) => (target: any, name: string) => void;
40
+ export declare function Controller(prefix: string): (target: any) => void;
41
+ export declare function AuthControl(name: string | string[] | null, mode?: 'AND' | 'OR'): (target: any, method?: string) => void;
42
+ export declare const Get: (url: string) => (target: any, name: string) => void;
43
+ export declare const Post: (url: string) => (target: any, name: string) => void;
44
+ export declare const Delete: (url: string) => (target: any, name: string) => void;
45
+ export declare const Put: (url: string) => (target: any, name: string) => void;
46
+ export declare const Patch: (url: string) => (target: any, name: string) => void;
49
47
  export interface ResData<T> {
50
48
  code: number;
51
49
  msg: string;
@@ -61,7 +59,7 @@ export interface UseProps {
61
59
  useJwt?: UseJwtHandler;
62
60
  }
63
61
  export interface SyncUseValue {
64
- context: import("koa").DefaultContext;
62
+ context: import('koa').DefaultContext;
65
63
  port: number;
66
64
  prefix: string;
67
65
  whitelist: (string | RegExp)[];
@@ -72,18 +70,26 @@ export interface ASTCacheHandler {
72
70
  method: string;
73
71
  isPublic: boolean;
74
72
  name: string;
73
+ auth: AuthControlProps;
75
74
  }
76
75
  export interface ASTCacheRoute {
77
76
  Instance: any;
78
77
  isPublic: boolean;
79
78
  prefix: string;
80
79
  handlers: ASTCacheHandler[];
80
+ auth: AuthControlProps;
81
81
  }
82
82
  export type UseJwtRes = {
83
83
  token: string;
84
- value: unknown;
84
+ current: unknown;
85
+ permissions?: string[];
85
86
  };
86
87
  export type HandlerStatusBody = {
87
- "Content-Type"?: string;
88
+ 'Content-Type'?: string;
88
89
  };
89
90
  export type UseJwtHandler = (_ctx: KoaCtx) => Promise<UseJwtRes | null>;
91
+ export type AuthControlProps = {
92
+ isPublic: boolean;
93
+ mode?: 'AND' | 'OR';
94
+ name?: string | string[];
95
+ };
package/types/utils.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { KoaCtx } from "./meta";
1
+ import { AuthControlProps, KoaCtx } from "./meta";
2
2
  export declare const Uri: {
3
3
  join(paths: string[]): string;
4
4
  };
5
5
  export declare function formatDateTime(date?: Date, format?: string): string;
6
6
  export declare function getIPAdress(): string;
7
7
  export declare function LogsHandler(ctx: KoaCtx, next: () => Promise<any>): Promise<void>;
8
+ export declare function ParsedAuthControl(...auths: AuthControlProps[]): (_perms?: string[]) => boolean;