typespeed 2.4.11 → 2.5.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.
@@ -1,5 +1,7 @@
1
1
  import { ResultSetHeader } from 'mysql2';
2
2
  import { log, getBean } from './core.decorator';
3
+ import { isStd, getStdArgs } from './decorator-utils';
4
+ import { getBindMapping } from './bind.decorator';
3
5
  import CacheFactory from './factory/cache-factory.class';
4
6
  import DataSourceFactory from './factory/data-source-factory.class';
5
7
 
@@ -10,9 +12,24 @@ const tableVersionMap = new Map<string, number>();
10
12
  let cacheBean: CacheFactory;
11
13
 
12
14
  function insert(sql: string) {
13
- return (target, propertyKey: string, descriptor: PropertyDescriptor) => {
14
- descriptor.value = async (...args: any[]) => {
15
- const result: ResultSetHeader = await queryForExecute(sql, args, target, propertyKey);
15
+ return (...args: any[]): any => {
16
+ if (isStd(args)) {
17
+ const [, ctx] = getStdArgs(args);
18
+ const propertyKey = String(ctx.name);
19
+ return async function (this: any, ...callArgs: any[]) {
20
+ const result: ResultSetHeader = await queryForExecute(sql, callArgs, this, propertyKey);
21
+ if (cacheBean && result.affectedRows > 0) {
22
+ const [tableName, tableVersion] = getTableAndVersion("insert", sql);
23
+ tableVersionMap.set(tableName, tableVersion + 1);
24
+ }
25
+ return result.insertId;
26
+ };
27
+ }
28
+ const target = args[0];
29
+ const propertyKey = args[1] as string;
30
+ const descriptor = args[2] as PropertyDescriptor;
31
+ descriptor.value = async (...callArgs: any[]) => {
32
+ const result: ResultSetHeader = await queryForExecute(sql, callArgs, target, propertyKey);
16
33
  if (cacheBean && result.affectedRows > 0) {
17
34
  const [tableName, tableVersion] = getTableAndVersion("insert", sql);
18
35
  tableVersionMap.set(tableName, tableVersion + 1);
@@ -23,9 +40,24 @@ function insert(sql: string) {
23
40
  }
24
41
 
25
42
  function update(sql: string) {
26
- return (target, propertyKey: string, descriptor: PropertyDescriptor) => {
27
- descriptor.value = async (...args: any[]) => {
28
- const result: ResultSetHeader = await queryForExecute(sql, args, target, propertyKey);
43
+ return (...args: any[]): any => {
44
+ if (isStd(args)) {
45
+ const [, ctx] = getStdArgs(args);
46
+ const propertyKey = String(ctx.name);
47
+ return async function (this: any, ...callArgs: any[]) {
48
+ const result: ResultSetHeader = await queryForExecute(sql, callArgs, this, propertyKey);
49
+ if (cacheBean && result.affectedRows > 0) {
50
+ const [tableName, tableVersion] = getTableAndVersion("update", sql);
51
+ tableVersionMap.set(tableName, tableVersion + 1);
52
+ }
53
+ return result.affectedRows;
54
+ };
55
+ }
56
+ const target = args[0];
57
+ const propertyKey = args[1] as string;
58
+ const descriptor = args[2] as PropertyDescriptor;
59
+ descriptor.value = async (...callArgs: any[]) => {
60
+ const result: ResultSetHeader = await queryForExecute(sql, callArgs, target, propertyKey);
29
61
  if (cacheBean && result.affectedRows > 0) {
30
62
  const [tableName, tableVersion] = getTableAndVersion("update", sql);
31
63
  tableVersionMap.set(tableName, tableVersion + 1);
@@ -36,9 +68,24 @@ function update(sql: string) {
36
68
  }
37
69
 
38
70
  function remove(sql: string) {
39
- return (target, propertyKey: string, descriptor: PropertyDescriptor) => {
40
- descriptor.value = async (...args: any[]) => {
41
- const result: ResultSetHeader = await queryForExecute(sql, args, target, propertyKey);
71
+ return (...args: any[]): any => {
72
+ if (isStd(args)) {
73
+ const [, ctx] = getStdArgs(args);
74
+ const propertyKey = String(ctx.name);
75
+ return async function (this: any, ...callArgs: any[]) {
76
+ const result: ResultSetHeader = await queryForExecute(sql, callArgs, this, propertyKey);
77
+ if (cacheBean && result.affectedRows > 0) {
78
+ const [tableName, tableVersion] = getTableAndVersion("delete", sql);
79
+ tableVersionMap.set(tableName, tableVersion + 1);
80
+ }
81
+ return result.affectedRows;
82
+ };
83
+ }
84
+ const target = args[0];
85
+ const propertyKey = args[1] as string;
86
+ const descriptor = args[2] as PropertyDescriptor;
87
+ descriptor.value = async (...callArgs: any[]) => {
88
+ const result: ResultSetHeader = await queryForExecute(sql, callArgs, target, propertyKey);
42
89
  if (cacheBean && result.affectedRows > 0) {
43
90
  const [tableName, tableVersion] = getTableAndVersion("delete", sql);
44
91
  tableVersionMap.set(tableName, tableVersion + 1);
@@ -49,9 +96,33 @@ function remove(sql: string) {
49
96
  }
50
97
 
51
98
  function select(sql: string) {
52
- return (target, propertyKey: string, descriptor: PropertyDescriptor) => {
53
- descriptor.value = async (...args: any[]) => {
54
- const [newSql, sqlValues] = convertSQLParams(sql, target, propertyKey, args);
99
+ return (...args: any[]): any => {
100
+ if (isStd(args)) {
101
+ const [, ctx] = getStdArgs(args);
102
+ const propertyKey = String(ctx.name);
103
+ return async function (this: any, ...callArgs: any[]) {
104
+ const [newSql, sqlValues] = convertSQLParams(sql, this, propertyKey, callArgs);
105
+ const resultType = resultTypeMap.get([this.constructor.name, propertyKey].toString());
106
+ if (cacheBean && cacheDefindMap.has([this.constructor.name, propertyKey].toString())) {
107
+ const [tableName, tableVersion] = getTableAndVersion("select", newSql);
108
+ const cacheKey = JSON.stringify([tableName, tableVersion, newSql, sqlValues]);
109
+ if (cacheBean.get(cacheKey)) {
110
+ return cacheBean.get(cacheKey);
111
+ } else {
112
+ const rows = await actionQuery(newSql, sqlValues, resultType);
113
+ cacheBean.set(cacheKey, rows, cacheDefindMap.get([this.constructor.name, propertyKey].toString()));
114
+ return rows;
115
+ }
116
+ } else {
117
+ return await actionQuery(newSql, sqlValues, resultType);
118
+ }
119
+ };
120
+ }
121
+ const target = args[0];
122
+ const propertyKey = args[1] as string;
123
+ const descriptor = args[2] as PropertyDescriptor;
124
+ descriptor.value = async (...callArgs: any[]) => {
125
+ const [newSql, sqlValues] = convertSQLParams(sql, target, propertyKey, callArgs);
55
126
  const resultType = resultTypeMap.get([target.constructor.name, propertyKey].toString());
56
127
  if (cacheBean && cacheDefindMap.has([target.constructor.name, propertyKey].toString())) {
57
128
  const [tableName, tableVersion] = getTableAndVersion("select", newSql);
@@ -71,7 +142,16 @@ function select(sql: string) {
71
142
  }
72
143
 
73
144
  function resultType(dataClass) {
74
- return function (target, propertyKey: string) {
145
+ return function (...args: any[]): any {
146
+ if (isStd(args)) {
147
+ const [, ctx] = getStdArgs(args);
148
+ ctx.addInitializer(function (this: any) {
149
+ resultTypeMap.set([this.constructor.name, String(ctx.name)].toString(), dataClass);
150
+ });
151
+ return;
152
+ }
153
+ const target = args[0];
154
+ const propertyKey = args[1] as string;
75
155
  resultTypeMap.set([target.constructor.name, propertyKey].toString(), dataClass);
76
156
  //never return
77
157
  };
@@ -124,8 +204,17 @@ function convertSQLParams(decoratorSQL: string, target: any, propertyKey: string
124
204
  if (typeof args[0] === 'object') {
125
205
  argsVal = new Map(Object.getOwnPropertyNames(args[0]).map((valName) => [valName, args[0][valName]]));
126
206
  } else {
127
- const existingParameters: [string, number][] = Reflect.getOwnMetadata(paramMetadataKey, target, propertyKey,);
128
- argsVal = new Map(existingParameters.map(([argName, argIdx]) => [argName, args[argIdx]]));
207
+ // 优先 @param(legacy reflect-metadata),否则回退 @bind(方法级声明,标准模式)
208
+ let existingParameters: [string, number][] = Reflect.getOwnMetadata(paramMetadataKey, target, propertyKey);
209
+ if (!existingParameters) {
210
+ const bindMapping = getBindMapping(target.constructor.name, propertyKey);
211
+ if (bindMapping) {
212
+ existingParameters = Object.entries(bindMapping)
213
+ .filter(([, value]) => typeof value === "number")
214
+ .map(([name, value]) => [name, value as number]);
215
+ }
216
+ }
217
+ argsVal = new Map((existingParameters || []).map(([argName, argIdx]) => [argName, args[argIdx]]));
129
218
  }
130
219
  const regExp = /#{(\w+)}/;
131
220
  let match;
@@ -139,7 +228,22 @@ function convertSQLParams(decoratorSQL: string, target: any, propertyKey: string
139
228
  }
140
229
 
141
230
  function cache(ttl: number) {
142
- return function (target: any, propertyKey: string) {
231
+ return function (...args: any[]): any {
232
+ if (isStd(args)) {
233
+ const [, ctx] = getStdArgs(args);
234
+ ctx.addInitializer(function (this: any) {
235
+ cacheDefindMap.set([this.constructor.name, String(ctx.name)].toString(), ttl);
236
+ if (cacheBean == null) {
237
+ const cacheFactory = getBean(CacheFactory);
238
+ if (cacheFactory || cacheFactory["factory"]) {
239
+ cacheBean = cacheFactory["factory"];
240
+ }
241
+ }
242
+ });
243
+ return;
244
+ }
245
+ const target = args[0];
246
+ const propertyKey = args[1] as string;
143
247
  cacheDefindMap.set([target.constructor.name, propertyKey].toString(), ttl);
144
248
  if (cacheBean == null) {
145
249
  const cacheFactory = getBean(CacheFactory);
@@ -0,0 +1,53 @@
1
+ /**
2
+ * 装饰器双签名感知工具。
3
+ *
4
+ * typespeed 2.5.x 起,装饰器同时支持两套运行时签名:
5
+ * - legacy(experimentalDecorators: true,2.4.x 现状):
6
+ * 类装饰器 (ctor);方法/属性装饰器 (target, key);带 descriptor 的方法 (target, key, descriptor);参数 (target, key, index)
7
+ * - 标准(TC39 装饰器提案,当前 Stage 2.7,experimentalDecorators: false):
8
+ * 统一 (value, context),context 恒为带 kind 字段的对象
9
+ *
10
+ * 装饰器函数本质是普通函数,运行时收到什么签名由「调用方(用户代码)」的编译模式决定,
11
+ * 因此库可以单份源码、运行时按签名形态分流:legacy 分支逻辑与 2.4.x 逐字一致,标准分支为新增。
12
+ */
13
+
14
+ /** 标准装饰器 context 的 kind 取值(TS/Babel 2022-03 版语义) */
15
+ export type StdDecoratorKind = "class" | "method" | "getter" | "setter" | "field" | "accessor";
16
+
17
+ /** 标准装饰器 context 的宽松类型描述(不依赖 esnext.decorators lib,保持 ES2017 可编译) */
18
+ export interface StdDecoratorContext {
19
+ kind: StdDecoratorKind;
20
+ name?: string | symbol;
21
+ static?: boolean;
22
+ private?: boolean;
23
+ access?: { get?: boolean; set?: boolean };
24
+ metadata?: Record<PropertyKey, unknown>;
25
+ addInitializer(fn: (this: any) => void): void;
26
+ }
27
+
28
+ /**
29
+ * 判断装饰器收到的运行时参数是否为标准装饰器签名 (value, context)。
30
+ *
31
+ * 判据(与 `2.5.x-新版装饰器使用方案.md` 一致):
32
+ * 参数个数 === 2 且第二个参数是「带 string 类型 kind 字段」的对象。
33
+ *
34
+ * 为什么这个判据可靠:
35
+ * - legacy 类装饰器只有 1 参 → 不满足 length === 2
36
+ * - legacy 方法/属性装饰器第二参是 string 的 key → 不是对象
37
+ * - legacy 带 descriptor 的方法 / 参数装饰器是 3 参 → 不满足 length === 2
38
+ * - 标准模式第二参恒是带 kind 的对象 → 命中
39
+ */
40
+ export function isStd(args: unknown[]): boolean {
41
+ return args.length === 2
42
+ && typeof args[1] === "object"
43
+ && args[1] !== null
44
+ && typeof (args[1] as { kind?: unknown }).kind === "string";
45
+ }
46
+
47
+ /**
48
+ * 从标准装饰器参数中解出 (value, context)。
49
+ * 仅应在 isStd(args) 为 true 时调用。
50
+ */
51
+ export function getStdArgs(args: unknown[]): [any, StdDecoratorContext] {
52
+ return [args[0], args[1] as StdDecoratorContext];
53
+ }
@@ -2,6 +2,8 @@ import * as express from "express";
2
2
  import * as multiparty from "multiparty";
3
3
  import { expressjwt } from "express-jwt";
4
4
  import { getComponent } from "./core.decorator";
5
+ import { isStd, getStdArgs } from "./decorator-utils";
6
+ import { getBindMapping } from "./bind.decorator";
5
7
 
6
8
  const routerMapper = {
7
9
  "get": {},
@@ -26,7 +28,51 @@ function setRouter(app: express.Application) {
26
28
  }
27
29
 
28
30
  function mapperFunction(method: string, value: string) {
29
- return (target: any, propertyKey: string) => {
31
+ return (...args: any[]): any => {
32
+ if (isStd(args)) {
33
+ const [methodFn, ctx] = getStdArgs(args);
34
+ ctx.addInitializer(function (this: any) {
35
+ const className = this.constructor.name;
36
+ const propertyKey = String(ctx.name);
37
+ applyRouteBind(className, propertyKey, methodFn);
38
+ routerMapper[method][value] = {
39
+ "path": value,
40
+ "name": [className, propertyKey].toString(),
41
+ "target": this.constructor,
42
+ "propertyKey": propertyKey,
43
+ "invoker": async (req, res, next) => {
44
+ const routerBean = getComponent(this.constructor);
45
+ try {
46
+ let paramTotal = routerBean[propertyKey].length;
47
+ if (routerParamsTotal[[className, propertyKey].toString()]) {
48
+ paramTotal = Math.max(paramTotal, routerParamsTotal[[className, propertyKey].toString()]);
49
+ }
50
+ const callArgs = [req, res, next];
51
+ if (paramTotal > 0) {
52
+ for (let i = 0; i < paramTotal; i++) {
53
+ if (routerParams[[className, propertyKey, i].toString()]) {
54
+ callArgs[i] = routerParams[[className, propertyKey, i].toString()](req, res, next);
55
+ }
56
+ }
57
+ }
58
+ const testResult = await routerBean[propertyKey].apply(routerBean, callArgs);
59
+ if (typeof testResult === "object") {
60
+ res.json(testResult);
61
+ } else if (typeof testResult !== "undefined") {
62
+ res.send(testResult);
63
+ }
64
+ return testResult;
65
+ } catch (err) {
66
+ next(err);
67
+ }
68
+ }
69
+ };
70
+ });
71
+ return;
72
+ }
73
+ const target = args[0];
74
+ const propertyKey = args[1] as string;
75
+ applyRouteBind(target.constructor.name, propertyKey, target[propertyKey]);
30
76
  routerMapper[method][value] = {
31
77
  "path": value,
32
78
  "name": [target.constructor.name, propertyKey].toString(),
@@ -62,7 +108,21 @@ function mapperFunction(method: string, value: string) {
62
108
  }
63
109
  }
64
110
 
65
- function upload(target: any, propertyKey: string) {
111
+ function upload(...args: any[]): any {
112
+ if (isStd(args)) {
113
+ const [, ctx] = getStdArgs(args);
114
+ ctx.addInitializer(function (this: any) {
115
+ const key = [this.constructor.name, String(ctx.name)].toString();
116
+ if (routerMiddleware[key]) {
117
+ routerMiddleware[key].push(uploadMiddleware);
118
+ } else {
119
+ routerMiddleware[key] = [uploadMiddleware];
120
+ }
121
+ });
122
+ return;
123
+ }
124
+ const target = args[0];
125
+ const propertyKey = args[1] as string;
66
126
  const key = [target.constructor.name, propertyKey].toString();
67
127
  if (routerMiddleware[key]) {
68
128
  routerMiddleware[key].push(uploadMiddleware);
@@ -80,7 +140,21 @@ function uploadMiddleware(req, res, next) {
80
140
  }
81
141
 
82
142
  function jwt(jwtConfig) {
83
- return (target: any, propertyKey: string) => {
143
+ return (...args: any[]): any => {
144
+ if (isStd(args)) {
145
+ const [, ctx] = getStdArgs(args);
146
+ ctx.addInitializer(function (this: any) {
147
+ const key = [this.constructor.name, String(ctx.name)].toString();
148
+ if (routerMiddleware[key]) {
149
+ routerMiddleware[key].push(expressjwt(jwtConfig));
150
+ } else {
151
+ routerMiddleware[key] = [expressjwt(jwtConfig)];
152
+ }
153
+ });
154
+ return;
155
+ }
156
+ const target = args[0];
157
+ const propertyKey = args[1] as string;
84
158
  const key = [target.constructor.name, propertyKey].toString();
85
159
  if (routerMiddleware[key]) {
86
160
  routerMiddleware[key].push(expressjwt(jwtConfig));
@@ -92,15 +166,34 @@ function jwt(jwtConfig) {
92
166
 
93
167
  function before(constructorFunction, methodName: string) {
94
168
  const targetBean = getComponent(constructorFunction);
95
- return function (target, propertyKey: string) {
169
+ return function (...args: any[]) {
170
+ if (isStd(args)) {
171
+ const [, ctx] = getStdArgs(args);
172
+ const hookKey = String(ctx.name);
173
+ ctx.addInitializer(function (this: any) {
174
+ const currentMethod = this[methodName];
175
+ if (currentMethod && currentMethod.length > 0) {
176
+ routerParamsTotal[[constructorFunction.name, methodName].toString()] = currentMethod.length;
177
+ }
178
+ Object.assign(this, {
179
+ [methodName]: function (...innerArgs: any[]) {
180
+ this[hookKey](...innerArgs);
181
+ return currentMethod.apply(this, innerArgs);
182
+ }
183
+ })
184
+ });
185
+ return;
186
+ }
187
+ const target = args[0];
188
+ const propertyKey = args[1] as string;
96
189
  const currentMethod = targetBean[methodName];
97
190
  if(currentMethod.length > 0){
98
191
  routerParamsTotal[[constructorFunction.name, methodName].toString()] = currentMethod.length;
99
192
  }
100
193
  Object.assign(targetBean, {
101
- [methodName]: function (...args) {
102
- target[propertyKey](...args);
103
- return currentMethod.apply(targetBean, args);
194
+ [methodName]: function (...innerArgs) {
195
+ target[propertyKey](...innerArgs);
196
+ return currentMethod.apply(targetBean, innerArgs);
104
197
  }
105
198
  })
106
199
  };
@@ -108,14 +201,34 @@ function before(constructorFunction, methodName: string) {
108
201
 
109
202
  function after(constructorFunction, methodName: string) {
110
203
  const targetBean = getComponent(constructorFunction);
111
- return function (target, propertyKey: string) {
204
+ return function (...args: any[]) {
205
+ if (isStd(args)) {
206
+ const [, ctx] = getStdArgs(args);
207
+ const hookKey = String(ctx.name);
208
+ ctx.addInitializer(function (this: any) {
209
+ const currentMethod = this[methodName];
210
+ if (currentMethod && currentMethod.length > 0) {
211
+ routerParamsTotal[[constructorFunction.name, methodName].toString()] = currentMethod.length;
212
+ }
213
+ Object.assign(this, {
214
+ [methodName]: function (...innerArgs: any[]) {
215
+ const result = currentMethod.apply(this, innerArgs);
216
+ const afterResult = this[hookKey](result);
217
+ return afterResult ?? result;
218
+ }
219
+ })
220
+ });
221
+ return;
222
+ }
223
+ const target = args[0];
224
+ const propertyKey = args[1] as string;
112
225
  const currentMethod = targetBean[methodName];
113
226
  if(currentMethod.length > 0){
114
227
  routerParamsTotal[[constructorFunction.name, methodName].toString()] = currentMethod.length;
115
228
  }
116
229
  Object.assign(targetBean, {
117
- [methodName]: function (...args) {
118
- const result = currentMethod.apply(targetBean, args);
230
+ [methodName]: function (...innerArgs) {
231
+ const result = currentMethod.apply(targetBean, innerArgs);
119
232
  const afterResult = target[propertyKey](result);
120
233
  return afterResult ?? result;
121
234
  }
@@ -155,6 +268,52 @@ function getParamInFunction(fn: Function, index: number) {
155
268
  return result[index] || null;
156
269
  }
157
270
 
271
+ /** 解析函数参数名列表(供 route @bind 做「参数名 → 索引」映射) */
272
+ function getParamNames(fn: Function): string[] {
273
+ const code = fn.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '').replace(/=>.*$/mg, '').replace(/=[^,)]+/g, '');
274
+ const paramsStr = code.slice(code.indexOf('(') + 1, code.indexOf(')'));
275
+ if (!paramsStr.trim()) return [];
276
+ return paramsStr.split(',').map(p => {
277
+ const matched = p.trim().match(/([A-Za-z_$][\w$]*)/);
278
+ return matched ? matched[1] : p.trim();
279
+ }).filter(Boolean);
280
+ }
281
+
282
+ /** 把 route @bind 的「来源字符串」转成参数解析器 */
283
+ function getRouteSourceResolver(source: string, paramName: string) {
284
+ switch (source) {
285
+ case "req": return (req, res, next) => req;
286
+ case "res": return (req, res, next) => res;
287
+ case "next": return (req, res, next) => next;
288
+ case "reqBody": return (req, res, next) => req.body;
289
+ case "reqParam": return (req, res, next) => req.params[paramName];
290
+ case "reqQuery": return (req, res, next) => req.query[paramName];
291
+ case "reqForm": return (req, res, next) => req.body[paramName];
292
+ default: return null;
293
+ }
294
+ }
295
+
296
+ /** 读取 @bind 声明,把「参数名 → 来源」转成 routerParams 的「索引 → 解析器」 */
297
+ function applyRouteBind(className: string, propertyKey: string, method: Function) {
298
+ const bindMapping = getBindMapping(className, propertyKey);
299
+ if (!bindMapping) return;
300
+ const paramNames = getParamNames(method);
301
+ const nameToIndex: Record<string, number> = {};
302
+ paramNames.forEach((paramName, index) => {
303
+ if (paramName && nameToIndex[paramName] === undefined) nameToIndex[paramName] = index;
304
+ });
305
+ for (const bindName in bindMapping) {
306
+ const source = bindMapping[bindName];
307
+ if (typeof source !== "string") continue; // 跳过 database 的数值映射
308
+ const index = nameToIndex[bindName];
309
+ if (index === undefined) continue;
310
+ const resolver = getRouteSourceResolver(source, bindName);
311
+ if (resolver) {
312
+ routerParams[[className, propertyKey, index].toString()] = resolver;
313
+ }
314
+ }
315
+ }
316
+
158
317
  function reqQuery(target: any, propertyKey: string, parameterIndex: number) {
159
318
  const key = [target.constructor.name, propertyKey, parameterIndex].toString();
160
319
  const paramName = getParamInFunction(target[propertyKey], parameterIndex);
@@ -5,68 +5,74 @@ import "reflect-metadata";
5
5
 
6
6
  /**设置路由中间件 */
7
7
  declare function setRouter(app: express.Application): void;
8
- /**上传文件装饰器,装饰页面具备解析上传文件的能力 */
9
- declare function upload(target: any, propertyKey: string): void;
8
+ /**上传文件装饰器,装饰页面具备解析上传文件的能力(legacy 方法装饰器;2.5.x 起兼容标准 (value, context) 签名) */
9
+ declare function upload(...args: any[]): any;
10
10
  /**
11
11
  * 页面支持 JWT 鉴权能力
12
12
  * @param jwtConfig jwt 配置
13
13
  */
14
- declare function jwt(jwtConfig: any): (target: any, propertyKey: string) => void;
14
+ declare function jwt(jwtConfig: any): (...args: any[]) => any;
15
15
  /**
16
16
  * GET 请求装饰器
17
17
  * @param value 请求路径
18
18
  */
19
- declare const getMapping: (value: string) => (target: any, propertyKey: string) => void;
19
+ declare const getMapping: (value: string) => (...args: any[]) => any;
20
20
  /**
21
21
  * POST 请求装饰器
22
22
  * @param value 请求路径
23
23
  */
24
- declare const postMapping: (value: string) => (target: any, propertyKey: string) => void;
24
+ declare const postMapping: (value: string) => (...args: any[]) => any;
25
25
  /**
26
26
  * 请求装饰器,不区分请求类型
27
27
  * @param value 请求路径
28
28
  */
29
- declare const requestMapping: (value: string) => (target: any, propertyKey: string) => void;
29
+ declare const requestMapping: (value: string) => (...args: any[]) => any;
30
30
  /**
31
31
  * INSERT 装饰器
32
32
  * 将方法作为 INSERT SQL 使用
33
33
  * @param sql INSERT SQL 语句
34
34
  */
35
- declare function insert(sql: string): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
35
+ declare function insert(sql: string): (...args: any[]) => any;
36
36
  /**
37
37
  * UPDATE 装饰器
38
38
  * 将方法作为 UPDATE SQL 使用
39
39
  * @param sql UPDATE SQL 语句
40
40
  */
41
- declare function update(sql: string): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
41
+ declare function update(sql: string): (...args: any[]) => any;
42
42
  /**
43
43
  * DELETE 装饰器
44
44
  * 将方法作为 DELETE SQL 使用
45
45
  * @param sql DELETE SQL 语句
46
46
  */
47
- declare function remove(sql: string): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
47
+ declare function remove(sql: string): (...args: any[]) => any;
48
48
  /**
49
49
  * SELECT 装饰器
50
50
  * 将方法作为 SELECT SQL 使用
51
51
  * @param sql SELECT SQL 语句
52
52
  */
53
- declare function select(sql: string): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
53
+ declare function select(sql: string): (...args: any[]) => any;
54
54
  /**
55
55
  * SELECT 结果类型装饰器,和 @select 配合使用
56
56
  * @param dataClass 结果类型
57
57
  */
58
- declare function resultType(dataClass: any): (target: any, propertyKey: string) => void;
58
+ declare function resultType(dataClass: any): (...args: any[]) => any;
59
59
  /**
60
60
  * SQL 参数装饰器,标注 SQL 语句的绑定参数值,和 @select @insert @update @remove 配合使用
61
61
  * @param name 参数在 SQL 语句内的标记值
62
62
  */
63
63
  declare function param(name: string): (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
64
+ /**
65
+ * 方法级参数绑定装饰器(标准装饰器删除了参数装饰器后的替代,legacy 模式也可用)。
66
+ * database 场景映射 SQL 占位符 → 参数索引(值为 number);route 场景映射参数名 → 请求来源(值为 string)。
67
+ * @param mapping 绑定声明,如 { name: 0, id: 1 } 或 { id: "reqParam", body: "reqBody" }
68
+ */
69
+ declare function bind(mapping: Record<string, string | number>): (...args: any[]) => any;
64
70
  /**
65
71
  * SELECT 缓存装饰器,自动缓存 SELECT 查询结果,和 @select 配合使用
66
72
  * 当执行 @insert @update @remove 时,会自动清除缓存。
67
73
  * @param ttl 缓存时间,单位秒
68
74
  */
69
- declare function cache(ttl: number): (target: any, propertyKey: string) => void;
75
+ declare function cache(ttl: number): (...args: any[]) => any;
70
76
  /**模型数据操作类 */
71
77
  declare class Model {
72
78
  /**分页数据 */
@@ -139,23 +145,21 @@ declare class Model {
139
145
  *
140
146
  * 被装饰的类将作为应用程序入口,框架将启动该类的 main 方法
141
147
  */
142
- declare function app<T extends {
143
- new(...args: any[]): {};
144
- }>(constructor: T): void;
148
+ declare function app(...args: any[]): any;
145
149
  /**获取配置文件中的配置项 */
146
150
  declare function config(node: string): any;
147
- /**组件装饰器,被装饰的类可以通过 @autoware 取得实例 */
148
- declare function component(constructorFunction: any): void;
151
+ /**组件装饰器,被装饰的类可以通过 @autoware 取得实例(legacy 类装饰器;2.5.x 起兼容标准 (value, context) 签名) */
152
+ declare function component(...args: any[]): any;
149
153
  /**获取组件实例函数,返回结果同 @autoware */
150
154
  declare function getComponent(constructorFunction: any): any;
151
- /**提供对象装饰器,框架将使用 @bean 装饰的方法来获取对象实例 */
152
- declare function bean(target: any, propertyKey: string): void;
155
+ /**提供对象装饰器,框架将使用 @bean 装饰的方法来获取对象实例(legacy 方法装饰器;2.5.x 起兼容标准签名) */
156
+ declare function bean(...args: any[]): any;
153
157
  /**获取对象实例函数,返回结果由 @bean 装饰的方法提供 */
154
158
  declare function getBean(mappingClass: Function): any;
155
159
  /**配置装饰器,装饰类成员变量值,获取配置文件中的配置项 */
156
160
  declare function value(configPath: string): any;
157
161
  /**自动装配装饰器,无参数版本,被装饰的类成员变量将自动注入实例 */
158
- declare function autoware(target: any, propertyKey: string): void;
162
+ declare function autoware(...args: any[]): any;
159
163
  /**自动装配装饰器,带参数版本,可输入参数作为实例初始化参数,被装饰的类成员变量将自动注入实例 */
160
164
  declare function resource(...args: any[]): any;
161
165
  /**日志函数,输出打印日志 */
@@ -165,11 +169,11 @@ declare function logx(message: any): void;
165
169
  /**错误日志函数,输出打印错误日志 */
166
170
  declare function error(message?: any, ...optionalParams: any[]): void;
167
171
  /**路由页面前置执行装饰器,参数指向路由页面方法,被装饰的方法将在路由页面之前执行 */
168
- declare function before(constructorFunction: any, methodName: string): (target: any, propertyKey: string) => void;
172
+ declare function before(constructorFunction: any, methodName: string): (...args: any[]) => any;
169
173
  /**路由页面后置执行装饰器,参数指向路由页面方法,被装饰的方法将在路由页面之后执行 */
170
- declare function after(constructorFunction: any, methodName: string): (target: any, propertyKey: string) => void;
174
+ declare function after(constructorFunction: any, methodName: string): (...args: any[]) => any;
171
175
  /**定时程序装饰器,参数支持 crontab 格式字符串,可根据参数定时执行被装饰的方法 */
172
- declare function schedule(cronTime: string | Date): (target: any, propertyKey: string) => void;
176
+ declare function schedule(cronTime: string | Date): (...args: any[]) => any;
173
177
  /**RabbitMQ 监听装饰器,参数是监听的队列名称,当接受到消息时将执行被装饰方法 */
174
178
  declare function rabbitListener(queue: string): (target: any, propertyKey: string) => void;
175
179
  /**Redis 监听装饰器,参数是监听的队列名称,当接受到消息时将执行被装饰方法 */
@@ -396,4 +400,4 @@ declare class SocketIo {
396
400
  /**Socket IO 服务实现类 */
397
401
  declare const io: IoServer;
398
402
 
399
- export { ExpressServer, LogDefault, NodeCache, RabbitMQ, rabbitListener, redisSubscriber, ReadWriteDb, Redis, CacheFactory, DataSourceFactory, LogFactory, ServerFactory, AuthenticationFactory, next, reqBody, reqQuery, reqForm, reqParam, req, req as request, res, res as response, component, bean, resource, log, logx, app, before, after, value, error, config, autoware, getBean, getComponent, schedule, getMapping, postMapping, requestMapping, setRouter, upload, jwt, insert, update, remove, select, param, resultType, cache, Model, SocketIo, io };
403
+ export { ExpressServer, LogDefault, NodeCache, RabbitMQ, rabbitListener, redisSubscriber, ReadWriteDb, Redis, CacheFactory, DataSourceFactory, LogFactory, ServerFactory, AuthenticationFactory, next, reqBody, reqQuery, reqForm, reqParam, req, req as request, res, res as response, component, bean, resource, log, logx, app, before, after, value, error, config, autoware, getBean, getComponent, schedule, getMapping, postMapping, requestMapping, setRouter, upload, jwt, insert, update, remove, select, param, bind, resultType, cache, Model, SocketIo, io };