typespeed 2.3.4 → 2.3.5
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/.github/workflows/test.yml +5 -2
- package/README.md +4 -3
- package/app/src/custom-log.class.ts +2 -1
- package/app/src/test-orm.class.ts +0 -11
- package/app/src/test-redis.class.ts +45 -0
- package/dist/default/express-server.class.js +1 -1
- package/dist/default/redis.class.js +55 -6
- package/dist/typespeed.d.ts +28 -11
- package/dist/typespeed.js +3 -2
- package/package.json +1 -1
- package/src/default/express-server.class.ts +1 -1
- package/src/default/redis.class.ts +59 -7
- package/src/typespeed.d.ts +28 -11
- package/src/typespeed.ts +1 -1
- package/test/hooks.ts +1 -0
- package/test/redis.test.ts +48 -0
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
name: Tests
|
|
2
|
-
'on':
|
|
2
|
+
'on':
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- main
|
|
3
6
|
|
|
4
7
|
jobs:
|
|
5
8
|
test:
|
|
@@ -20,7 +23,7 @@ jobs:
|
|
|
20
23
|
steps:
|
|
21
24
|
- uses: actions/setup-node@v1
|
|
22
25
|
with:
|
|
23
|
-
node-version:
|
|
26
|
+
node-version: 16
|
|
24
27
|
- uses: actions/checkout@v2
|
|
25
28
|
- name: Setup MySQL
|
|
26
29
|
run: |
|
package/README.md
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/typespeed)
|
|
4
4
|
[](https://www.npmjs.com/package/typespeed)
|
|
5
|
-
[](https://github.com/SpeedPHP/typespeed/commits/main)
|
|
6
5
|
[](https://www.npmjs.com/package/typespeed)
|
|
7
6
|
[](https://github.com/SpeedPHP/typespeed/blob/main/LICENSE)
|
|
8
|
-
[](https://github.com/SpeedPHP/typespeed/commits/main)
|
|
8
|
+
[
|
|
9
|
+
](https://codecov.io/gh/SpeedPHP/typespeed)
|
|
9
10
|
|
|
10
11
|
### 特点
|
|
11
12
|
|
|
12
13
|
- 遵循 MIT 许可的开源项目。
|
|
13
|
-
- 提供
|
|
14
|
+
- 提供 31 个 TypeScript 装饰器,这些装饰器构成了完整的 Web 框架功能,包括对象管理、Web 路由、数据库操作等。
|
|
14
15
|
- 通过命令行脚手架,可以快速创建项目,零配置启动。
|
|
15
16
|
- 基于依赖注入、AOP、中间件和启动扫描等编程理念开发实现。
|
|
16
17
|
- 底层采用 ExpressJS 实现,提供稳定、快速的 Web 服务。
|
|
@@ -17,7 +17,8 @@ export default class CustomLog extends LogFactory {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
public log(message?: any, ...optionalParams: any[]) : void{
|
|
20
|
-
|
|
20
|
+
if(process.env.LOG === "CLOSE") return;
|
|
21
|
+
this.logger.log(message, ...optionalParams);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
public error(message?: any, ...optionalParams: any[]) : void {
|
|
@@ -7,17 +7,6 @@ export default class TestOrm {
|
|
|
7
7
|
@resource("user")
|
|
8
8
|
private userModel: UserModel;
|
|
9
9
|
|
|
10
|
-
@autoware
|
|
11
|
-
private redisObj: Redis;
|
|
12
|
-
|
|
13
|
-
@getMapping("/redis")
|
|
14
|
-
async redisTest() {
|
|
15
|
-
await this.redisObj.set("redisKey", "Hello World");
|
|
16
|
-
const value = await this.redisObj.get("redisKey");
|
|
17
|
-
log(value)
|
|
18
|
-
return "get from redis: " + value;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
10
|
@getMapping("/orm/first")
|
|
22
11
|
async firstTest(req, res) {
|
|
23
12
|
const results = await this.userModel.getUsers();
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Redis, component, redisSubscriber, autoware, getMapping, log, reqQuery } from "../../src/typespeed";
|
|
2
|
+
|
|
3
|
+
@component
|
|
4
|
+
export default class TestRedis {
|
|
5
|
+
@autoware
|
|
6
|
+
private redisObj: Redis;
|
|
7
|
+
|
|
8
|
+
@redisSubscriber("mychannel")
|
|
9
|
+
public listen(message) {
|
|
10
|
+
log("Received by Decorator '%s'", message);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@getMapping("/redis/publish")
|
|
14
|
+
async redisPublish() {
|
|
15
|
+
await this.redisObj.publish("mychannel", "Hello World");
|
|
16
|
+
return "Published!";
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@getMapping("/redis")
|
|
20
|
+
async redisString() {
|
|
21
|
+
await this.redisObj.set("redisKey", "Hello World");
|
|
22
|
+
const value = await this.redisObj.get("redisKey");
|
|
23
|
+
return "get from redis: " + value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@getMapping("/redis/add")
|
|
27
|
+
async addZset(@reqQuery name: string, @reqQuery score: number) {
|
|
28
|
+
log("add zset: %s, %s", name, score)
|
|
29
|
+
await this.redisObj.zadd("scoreSet", score, name);
|
|
30
|
+
return "add zset success";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@getMapping("/redis/ranking")
|
|
34
|
+
async listRanking() {
|
|
35
|
+
const list = await this.redisObj.zrevranking("scoreSet", 0, -1);
|
|
36
|
+
return Object.fromEntries(list);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@getMapping("/redis/list")
|
|
40
|
+
async listZset() {
|
|
41
|
+
const list = await this.redisObj.zranking("scoreSet", 0, -1);
|
|
42
|
+
log("list zset: %s", JSON.stringify(Object.fromEntries(list)));
|
|
43
|
+
return Object.fromEntries(list);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -138,7 +138,7 @@ __decorate([
|
|
|
138
138
|
], ExpressServer.prototype, "redisConfig", void 0);
|
|
139
139
|
__decorate([
|
|
140
140
|
core_decorator_1.autoware,
|
|
141
|
-
__metadata("design:type", redis_class_1.
|
|
141
|
+
__metadata("design:type", redis_class_1.Redis)
|
|
142
142
|
], ExpressServer.prototype, "redisClient", void 0);
|
|
143
143
|
__decorate([
|
|
144
144
|
core_decorator_1.autoware,
|
|
@@ -9,24 +9,73 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.redisSubscriber = exports.Redis = void 0;
|
|
12
13
|
const core_decorator_1 = require("../core.decorator");
|
|
13
14
|
const ioredis_1 = require("ioredis");
|
|
14
15
|
const typespeed_1 = require("../typespeed");
|
|
15
|
-
|
|
16
|
+
const redisSubscribers = {};
|
|
17
|
+
class Redis extends ioredis_1.Redis {
|
|
16
18
|
getRedis() {
|
|
19
|
+
return Redis.getInstanceOfRedis("pub");
|
|
20
|
+
}
|
|
21
|
+
async zrevranking(key, start, stop) {
|
|
22
|
+
const list = await this.zrevrange(key, start, stop, "WITHSCORES");
|
|
23
|
+
const map = new Map();
|
|
24
|
+
for (let i = 0; i < list.length; i = i + 2) {
|
|
25
|
+
map.set(list[i], Number(list[i + 1]));
|
|
26
|
+
}
|
|
27
|
+
return map;
|
|
28
|
+
}
|
|
29
|
+
async zranking(key, start, stop) {
|
|
30
|
+
const list = await this.zrange(key, start, stop, "WITHSCORES");
|
|
31
|
+
const map = new Map();
|
|
32
|
+
for (let i = 0; i < list.length; i = i + 2) {
|
|
33
|
+
map.set(list[i], Number(list[i + 1]));
|
|
34
|
+
}
|
|
35
|
+
return map;
|
|
36
|
+
}
|
|
37
|
+
static getInstanceOfRedis(mode) {
|
|
17
38
|
if (!(0, typespeed_1.config)("redis")) {
|
|
18
39
|
return null;
|
|
19
40
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
41
|
+
if (mode === "sub") {
|
|
42
|
+
this.pubObj = this.pubObj || new Redis((0, typespeed_1.config)("redis"));
|
|
43
|
+
return this.pubObj;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.subObj = this.subObj || new Redis((0, typespeed_1.config)("redis"));
|
|
47
|
+
return this.subObj;
|
|
48
|
+
}
|
|
24
49
|
}
|
|
25
50
|
}
|
|
51
|
+
Redis.pubObj = null;
|
|
52
|
+
Redis.subObj = null;
|
|
26
53
|
__decorate([
|
|
27
54
|
core_decorator_1.bean,
|
|
28
55
|
__metadata("design:type", Function),
|
|
29
56
|
__metadata("design:paramtypes", []),
|
|
30
57
|
__metadata("design:returntype", Redis)
|
|
31
58
|
], Redis.prototype, "getRedis", null);
|
|
32
|
-
exports.
|
|
59
|
+
exports.Redis = Redis;
|
|
60
|
+
function redisSubscriber(channel) {
|
|
61
|
+
if (!(0, typespeed_1.config)("redis"))
|
|
62
|
+
return;
|
|
63
|
+
Redis.getInstanceOfRedis("sub").subscribe(channel, function (err, count) {
|
|
64
|
+
if (err) {
|
|
65
|
+
console.error(err);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
return function (target, propertyKey) {
|
|
69
|
+
redisSubscribers[channel] = target[propertyKey];
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
exports.redisSubscriber = redisSubscriber;
|
|
73
|
+
if ((0, typespeed_1.config)("redis")) {
|
|
74
|
+
Redis.getInstanceOfRedis("sub").on("message", function (channel, message) {
|
|
75
|
+
redisSubscribers[channel](message);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
process.once('SIGINT', () => {
|
|
79
|
+
Redis.getInstanceOfRedis("sub") || Redis.getInstanceOfRedis("sub").disconnect();
|
|
80
|
+
Redis.getInstanceOfRedis("pub") || Redis.getInstanceOfRedis("pub").disconnect();
|
|
81
|
+
});
|
package/dist/typespeed.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as express from "express";
|
|
2
|
-
import IoRedis from "ioredis";
|
|
2
|
+
import { Redis as IoRedis, RedisKey } from "ioredis";
|
|
3
3
|
import "reflect-metadata";
|
|
4
4
|
|
|
5
5
|
/**设置路由中间件 */
|
|
@@ -139,7 +139,7 @@ declare class Model {
|
|
|
139
139
|
* 被装饰的类将作为应用程序入口,框架将启动该类的 main 方法
|
|
140
140
|
*/
|
|
141
141
|
declare function app<T extends {
|
|
142
|
-
new
|
|
142
|
+
new(...args: any[]): {};
|
|
143
143
|
}>(constructor: T): void;
|
|
144
144
|
/**获取配置文件中的配置项 */
|
|
145
145
|
declare function config(node: string): any;
|
|
@@ -169,20 +169,22 @@ declare function after(constructorFunction: any, methodName: string): (target: a
|
|
|
169
169
|
declare function schedule(cronTime: string | Date): (target: any, propertyKey: string) => void;
|
|
170
170
|
/**RabbitMQ 监听装饰器,参数是监听的队列名称,当接受到消息时将执行被装饰方法 */
|
|
171
171
|
declare function rabbitListener(queue: string): (target: any, propertyKey: string) => void;
|
|
172
|
+
/**Redis 监听装饰器,参数是监听的队列名称,当接受到消息时将执行被装饰方法 */
|
|
173
|
+
declare function redisSubscriber(target: any, propertyKey: string): void;
|
|
172
174
|
/** request 对象装饰器,作为路由页面方法参数,获取 request 对象 */
|
|
173
|
-
declare function req(target: any, propertyKey: string, parameterIndex: number)
|
|
175
|
+
declare function req(target: any, propertyKey: string, parameterIndex: number): void;
|
|
174
176
|
/** response 对象装饰器,作为路由页面方法参数,获取 response 对象 */
|
|
175
|
-
declare function res(target: any, propertyKey: string, parameterIndex: number)
|
|
177
|
+
declare function res(target: any, propertyKey: string, parameterIndex: number): void;
|
|
176
178
|
/** next 函数装饰器,作为路由页面方法参数,获取 next 函数 */
|
|
177
|
-
declare function next(target: any, propertyKey: string, parameterIndex: number)
|
|
179
|
+
declare function next(target: any, propertyKey: string, parameterIndex: number): void;
|
|
178
180
|
/** request.body 对象装饰器,作为路由页面方法参数,获取 request.body 对象 */
|
|
179
|
-
declare function reqBody(target: any, propertyKey: string, parameterIndex: number)
|
|
181
|
+
declare function reqBody(target: any, propertyKey: string, parameterIndex: number): void;
|
|
180
182
|
/** request.param 值装饰器,作为路由页面方法参数,获取 request.params 内容 */
|
|
181
|
-
declare function reqParam(target: any, propertyKey: string, parameterIndex: number)
|
|
183
|
+
declare function reqParam(target: any, propertyKey: string, parameterIndex: number): void;
|
|
182
184
|
/** request.query 值装饰器,作为路由页面方法参数,获取 request.query 内容 */
|
|
183
|
-
declare function reqQuery(target: any, propertyKey: string, parameterIndex: number)
|
|
185
|
+
declare function reqQuery(target: any, propertyKey: string, parameterIndex: number): void;
|
|
184
186
|
/** request 表单值装饰器,作为路由页面方法参数,获取 request.body 表单内容 */
|
|
185
|
-
declare function reqForm(paramName: string)
|
|
187
|
+
declare function reqForm(paramName: string): (target: any, propertyKey: string, parameterIndex: number) => void;
|
|
186
188
|
|
|
187
189
|
/**框架 Web 服务工厂类 */
|
|
188
190
|
declare abstract class ServerFactory {
|
|
@@ -275,7 +277,22 @@ declare abstract class AuthenticationFactory {
|
|
|
275
277
|
declare class Redis extends IoRedis {
|
|
276
278
|
/**获取 Redis 实例 */
|
|
277
279
|
getRedis(): Redis;
|
|
278
|
-
|
|
280
|
+
/**
|
|
281
|
+
* 获取有序集合(sorted set),按照分数从大到小排序,返回 Map 对象
|
|
282
|
+
* @param key 键
|
|
283
|
+
* @param start 开始位置,0 表示第一个元素,-1 表示最后一个元素
|
|
284
|
+
* @param stop 结束位置,0 表示第一个元素,-1 表示最后一个元素
|
|
285
|
+
* @returns Map 对象,key 为有序集合的成员,value 为成员的分数
|
|
286
|
+
*/
|
|
287
|
+
zrevranking(key: RedisKey, start: number | string, stop: number | string): Promise<Map<string, number>>;
|
|
288
|
+
/**
|
|
289
|
+
* 获取有序集合(sorted set),按照分数从小到大排序,返回 Map 对象
|
|
290
|
+
* @param key 键
|
|
291
|
+
* @param start 开始位置,0 表示第一个元素,-1 表示最后一个元素
|
|
292
|
+
* @param stop 结束位置,0 表示第一个元素,-1 表示最后一个元素
|
|
293
|
+
* @returns Map 对象,key 为有序集合的成员,value 为成员的分数
|
|
294
|
+
*/
|
|
295
|
+
zranking(key: RedisKey, start: number | string, stop: number | string): Promise<Map<string, number>>;
|
|
279
296
|
}
|
|
280
297
|
/**读写数据源实现类 */
|
|
281
298
|
declare class ReadWriteDb extends DataSourceFactory {
|
|
@@ -359,4 +376,4 @@ declare class ExpressServer extends ServerFactory {
|
|
|
359
376
|
private setDefaultMiddleware;
|
|
360
377
|
}
|
|
361
378
|
|
|
362
|
-
export { ExpressServer, LogDefault, NodeCache, RabbitMQ, rabbitListener, ReadWriteDb, Redis, CacheFactory, DataSourceFactory, LogFactory, ServerFactory, AuthenticationFactory, next, reqBody, reqQuery, reqForm, reqParam, req, req as request, res, res as response, component, bean, resource, log, app, before, after, value, error, config, autoware, getBean, getComponent, schedule, getMapping, postMapping, requestMapping, setRouter, upload, jwt, insert, update, remove, select, param, resultType, cache, Model};
|
|
379
|
+
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, app, before, after, value, error, config, autoware, getBean, getComponent, schedule, getMapping, postMapping, requestMapping, setRouter, upload, jwt, insert, update, remove, select, param, resultType, cache, Model };
|
package/dist/typespeed.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.ReadWriteDb = exports.Redis = exports.NodeCache = exports.LogDefault = exports.ExpressServer = exports.AuthenticationFactory = exports.ServerFactory = exports.DataSourceFactory = exports.CacheFactory = exports.LogFactory = exports.config = exports.value = exports.app = void 0;
|
|
17
|
+
exports.ReadWriteDb = exports.redisSubscriber = exports.Redis = exports.NodeCache = exports.LogDefault = exports.ExpressServer = exports.AuthenticationFactory = exports.ServerFactory = exports.DataSourceFactory = exports.CacheFactory = exports.LogFactory = exports.config = exports.value = exports.app = void 0;
|
|
18
18
|
require("reflect-metadata");
|
|
19
19
|
const fs = require("fs");
|
|
20
20
|
const path = require("path");
|
|
@@ -119,7 +119,8 @@ Object.defineProperty(exports, "LogDefault", { enumerable: true, get: function (
|
|
|
119
119
|
var node_cache_class_1 = require("./default/node-cache.class");
|
|
120
120
|
Object.defineProperty(exports, "NodeCache", { enumerable: true, get: function () { return node_cache_class_1.default; } });
|
|
121
121
|
var redis_class_1 = require("./default/redis.class");
|
|
122
|
-
Object.defineProperty(exports, "Redis", { enumerable: true, get: function () { return redis_class_1.
|
|
122
|
+
Object.defineProperty(exports, "Redis", { enumerable: true, get: function () { return redis_class_1.Redis; } });
|
|
123
|
+
Object.defineProperty(exports, "redisSubscriber", { enumerable: true, get: function () { return redis_class_1.redisSubscriber; } });
|
|
123
124
|
var read_write_db_class_1 = require("./default/read-write-db.class");
|
|
124
125
|
Object.defineProperty(exports, "ReadWriteDb", { enumerable: true, get: function () { return read_write_db_class_1.default; } });
|
|
125
126
|
__exportStar(require("./default/rabbitmq.class"), exports);
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@ import ServerFactory from "../factory/server-factory.class";
|
|
|
10
10
|
import { setRouter } from "../route.decorator";
|
|
11
11
|
import { value } from "../typespeed";
|
|
12
12
|
import { bean, log, error, autoware } from "../core.decorator";
|
|
13
|
-
import Redis from "./redis.class";
|
|
13
|
+
import { Redis } from "./redis.class";
|
|
14
14
|
import AuthenticationFactory from "../factory/authentication-factory.class";
|
|
15
15
|
|
|
16
16
|
export default class ExpressServer extends ServerFactory {
|
|
@@ -1,18 +1,70 @@
|
|
|
1
1
|
import { bean } from "../core.decorator";
|
|
2
|
-
import IoRedis from "ioredis";
|
|
2
|
+
import { Redis as IoRedis, RedisKey} from "ioredis";
|
|
3
3
|
import { config } from "../typespeed";
|
|
4
|
-
|
|
4
|
+
const redisSubscribers = {};
|
|
5
|
+
|
|
6
|
+
class Redis extends IoRedis {
|
|
7
|
+
private static pubObj: Redis = null;
|
|
8
|
+
private static subObj: Redis = null;
|
|
5
9
|
|
|
6
10
|
@bean
|
|
7
11
|
public getRedis(): Redis {
|
|
12
|
+
return Redis.getInstanceOfRedis("pub");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public async zrevranking(key: RedisKey, start: number | string, stop: number | string): Promise<Map<string, number>> {
|
|
16
|
+
const list = await this.zrevrange(key, start, stop, "WITHSCORES");
|
|
17
|
+
const map = new Map<string, number>();
|
|
18
|
+
for (let i = 0; i < list.length; i = i + 2) {
|
|
19
|
+
map.set(list[i], Number(list[i + 1]));
|
|
20
|
+
}
|
|
21
|
+
return map;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public async zranking(key: RedisKey, start: number | string, stop: number | string): Promise<Map<string, number>> {
|
|
25
|
+
const list = await this.zrange(key, start, stop, "WITHSCORES");
|
|
26
|
+
const map = new Map<string, number>();
|
|
27
|
+
for (let i = 0; i < list.length; i = i + 2) {
|
|
28
|
+
map.set(list[i], Number(list[i + 1]));
|
|
29
|
+
}
|
|
30
|
+
return map;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static getInstanceOfRedis(mode: "sub" | "pub") {
|
|
8
34
|
if (!config("redis")) {
|
|
9
35
|
return null;
|
|
10
36
|
}
|
|
11
|
-
|
|
37
|
+
if (mode === "sub") {
|
|
38
|
+
this.pubObj = this.pubObj || new Redis(config("redis"));
|
|
39
|
+
return this.pubObj;
|
|
40
|
+
} else {
|
|
41
|
+
this.subObj = this.subObj || new Redis(config("redis"));
|
|
42
|
+
return this.subObj;
|
|
43
|
+
}
|
|
12
44
|
}
|
|
45
|
+
}
|
|
13
46
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
47
|
+
function redisSubscriber(channel: string) {
|
|
48
|
+
if (!config("redis")) return;
|
|
49
|
+
Redis.getInstanceOfRedis("sub").subscribe(channel, function (err, count) {
|
|
50
|
+
if (err) {
|
|
51
|
+
console.error(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
return function (target: any, propertyKey: string) {
|
|
55
|
+
redisSubscribers[channel] = target[propertyKey];
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (config("redis")) {
|
|
60
|
+
Redis.getInstanceOfRedis("sub").on("message", function (channel, message) {
|
|
61
|
+
redisSubscribers[channel](message);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
process.once('SIGINT', () => {
|
|
66
|
+
Redis.getInstanceOfRedis("sub") || Redis.getInstanceOfRedis("sub").disconnect();
|
|
67
|
+
Redis.getInstanceOfRedis("pub") || Redis.getInstanceOfRedis("pub").disconnect();
|
|
68
|
+
});
|
|
17
69
|
|
|
18
|
-
}
|
|
70
|
+
export { Redis, redisSubscriber };
|
package/src/typespeed.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as express from "express";
|
|
2
|
-
import IoRedis from "ioredis";
|
|
2
|
+
import { Redis as IoRedis, RedisKey } from "ioredis";
|
|
3
3
|
import "reflect-metadata";
|
|
4
4
|
|
|
5
5
|
/**设置路由中间件 */
|
|
@@ -139,7 +139,7 @@ declare class Model {
|
|
|
139
139
|
* 被装饰的类将作为应用程序入口,框架将启动该类的 main 方法
|
|
140
140
|
*/
|
|
141
141
|
declare function app<T extends {
|
|
142
|
-
new
|
|
142
|
+
new(...args: any[]): {};
|
|
143
143
|
}>(constructor: T): void;
|
|
144
144
|
/**获取配置文件中的配置项 */
|
|
145
145
|
declare function config(node: string): any;
|
|
@@ -169,20 +169,22 @@ declare function after(constructorFunction: any, methodName: string): (target: a
|
|
|
169
169
|
declare function schedule(cronTime: string | Date): (target: any, propertyKey: string) => void;
|
|
170
170
|
/**RabbitMQ 监听装饰器,参数是监听的队列名称,当接受到消息时将执行被装饰方法 */
|
|
171
171
|
declare function rabbitListener(queue: string): (target: any, propertyKey: string) => void;
|
|
172
|
+
/**Redis 监听装饰器,参数是监听的队列名称,当接受到消息时将执行被装饰方法 */
|
|
173
|
+
declare function redisSubscriber(target: any, propertyKey: string): void;
|
|
172
174
|
/** request 对象装饰器,作为路由页面方法参数,获取 request 对象 */
|
|
173
|
-
declare function req(target: any, propertyKey: string, parameterIndex: number)
|
|
175
|
+
declare function req(target: any, propertyKey: string, parameterIndex: number): void;
|
|
174
176
|
/** response 对象装饰器,作为路由页面方法参数,获取 response 对象 */
|
|
175
|
-
declare function res(target: any, propertyKey: string, parameterIndex: number)
|
|
177
|
+
declare function res(target: any, propertyKey: string, parameterIndex: number): void;
|
|
176
178
|
/** next 函数装饰器,作为路由页面方法参数,获取 next 函数 */
|
|
177
|
-
declare function next(target: any, propertyKey: string, parameterIndex: number)
|
|
179
|
+
declare function next(target: any, propertyKey: string, parameterIndex: number): void;
|
|
178
180
|
/** request.body 对象装饰器,作为路由页面方法参数,获取 request.body 对象 */
|
|
179
|
-
declare function reqBody(target: any, propertyKey: string, parameterIndex: number)
|
|
181
|
+
declare function reqBody(target: any, propertyKey: string, parameterIndex: number): void;
|
|
180
182
|
/** request.param 值装饰器,作为路由页面方法参数,获取 request.params 内容 */
|
|
181
|
-
declare function reqParam(target: any, propertyKey: string, parameterIndex: number)
|
|
183
|
+
declare function reqParam(target: any, propertyKey: string, parameterIndex: number): void;
|
|
182
184
|
/** request.query 值装饰器,作为路由页面方法参数,获取 request.query 内容 */
|
|
183
|
-
declare function reqQuery(target: any, propertyKey: string, parameterIndex: number)
|
|
185
|
+
declare function reqQuery(target: any, propertyKey: string, parameterIndex: number): void;
|
|
184
186
|
/** request 表单值装饰器,作为路由页面方法参数,获取 request.body 表单内容 */
|
|
185
|
-
declare function reqForm(paramName: string)
|
|
187
|
+
declare function reqForm(paramName: string): (target: any, propertyKey: string, parameterIndex: number) => void;
|
|
186
188
|
|
|
187
189
|
/**框架 Web 服务工厂类 */
|
|
188
190
|
declare abstract class ServerFactory {
|
|
@@ -275,7 +277,22 @@ declare abstract class AuthenticationFactory {
|
|
|
275
277
|
declare class Redis extends IoRedis {
|
|
276
278
|
/**获取 Redis 实例 */
|
|
277
279
|
getRedis(): Redis;
|
|
278
|
-
|
|
280
|
+
/**
|
|
281
|
+
* 获取有序集合(sorted set),按照分数从大到小排序,返回 Map 对象
|
|
282
|
+
* @param key 键
|
|
283
|
+
* @param start 开始位置,0 表示第一个元素,-1 表示最后一个元素
|
|
284
|
+
* @param stop 结束位置,0 表示第一个元素,-1 表示最后一个元素
|
|
285
|
+
* @returns Map 对象,key 为有序集合的成员,value 为成员的分数
|
|
286
|
+
*/
|
|
287
|
+
zrevranking(key: RedisKey, start: number | string, stop: number | string): Promise<Map<string, number>>;
|
|
288
|
+
/**
|
|
289
|
+
* 获取有序集合(sorted set),按照分数从小到大排序,返回 Map 对象
|
|
290
|
+
* @param key 键
|
|
291
|
+
* @param start 开始位置,0 表示第一个元素,-1 表示最后一个元素
|
|
292
|
+
* @param stop 结束位置,0 表示第一个元素,-1 表示最后一个元素
|
|
293
|
+
* @returns Map 对象,key 为有序集合的成员,value 为成员的分数
|
|
294
|
+
*/
|
|
295
|
+
zranking(key: RedisKey, start: number | string, stop: number | string): Promise<Map<string, number>>;
|
|
279
296
|
}
|
|
280
297
|
/**读写数据源实现类 */
|
|
281
298
|
declare class ReadWriteDb extends DataSourceFactory {
|
|
@@ -359,4 +376,4 @@ declare class ExpressServer extends ServerFactory {
|
|
|
359
376
|
private setDefaultMiddleware;
|
|
360
377
|
}
|
|
361
378
|
|
|
362
|
-
export { ExpressServer, LogDefault, NodeCache, RabbitMQ, rabbitListener, ReadWriteDb, Redis, CacheFactory, DataSourceFactory, LogFactory, ServerFactory, AuthenticationFactory, next, reqBody, reqQuery, reqForm, reqParam, req, req as request, res, res as response, component, bean, resource, log, app, before, after, value, error, config, autoware, getBean, getComponent, schedule, getMapping, postMapping, requestMapping, setRouter, upload, jwt, insert, update, remove, select, param, resultType, cache, Model};
|
|
379
|
+
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, app, before, after, value, error, config, autoware, getBean, getComponent, schedule, getMapping, postMapping, requestMapping, setRouter, upload, jwt, insert, update, remove, select, param, resultType, cache, Model };
|
package/src/typespeed.ts
CHANGED
|
@@ -97,6 +97,6 @@ export { default as AuthenticationFactory} from "./factory/authentication-factor
|
|
|
97
97
|
export { default as ExpressServer} from "./default/express-server.class";
|
|
98
98
|
export { default as LogDefault} from "./default/log-default.class";
|
|
99
99
|
export { default as NodeCache} from "./default/node-cache.class";
|
|
100
|
-
export {
|
|
100
|
+
export { Redis, redisSubscriber } from "./default/redis.class";
|
|
101
101
|
export { default as ReadWriteDb} from "./default/read-write-db.class";
|
|
102
102
|
export * from "./default/rabbitmq.class";
|
package/test/hooks.ts
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const chaiObj = require('chai');
|
|
2
|
+
chaiObj.use(require("chai-http"));
|
|
3
|
+
const expect = chaiObj.expect;
|
|
4
|
+
|
|
5
|
+
describe("Test Redis", () => {
|
|
6
|
+
const testAddr = `http://${process.env.LOCAL_HOST || "localhost"}:8081`;
|
|
7
|
+
const ranking = {
|
|
8
|
+
"zhangsan": 93, "lisi": 99, "wangwu": 96, "zhaoliu": 97, "qianqi": 98, "sunba": 92, "zhoujiu": 94, "wushi": 95
|
|
9
|
+
};
|
|
10
|
+
it("/redis", (done) => {
|
|
11
|
+
chaiObj.request(testAddr).get("/redis").end((err, res) => {
|
|
12
|
+
expect(res.text).to.be.equal("get from redis: " + "Hello World");
|
|
13
|
+
done();
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
it("/redis/publish", (done) => {
|
|
17
|
+
chaiObj.request(testAddr).get("/redis/publish").end((err, res) => {
|
|
18
|
+
expect(res.text).to.be.equal("Published!");
|
|
19
|
+
done();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
Object.keys(ranking).forEach((item) => {
|
|
23
|
+
it("/redis/add " + item, (done) => {
|
|
24
|
+
chaiObj.request(testAddr).get(`/redis/add?name=${item}&score=${ranking[item]}`).end((err, res) => {
|
|
25
|
+
expect(res.text).to.be.equal("add zset success");
|
|
26
|
+
done();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
it("/redis/list", (done) => {
|
|
31
|
+
chaiObj.request(testAddr).get("/redis/list").end((err, res) => {
|
|
32
|
+
const dataList = JSON.parse(res.text);
|
|
33
|
+
const rankingAsc = Object.fromEntries(Object.entries(ranking).sort((a, b) => a[1] - b[1]));
|
|
34
|
+
expect(JSON.stringify(dataList)).to.be.equal(JSON.stringify(rankingAsc));
|
|
35
|
+
done();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
it("/redis/ranking", (done) => {
|
|
39
|
+
chaiObj.request(testAddr).get("/redis/ranking").end((err, res) => {
|
|
40
|
+
const dataList = JSON.parse(res.text);
|
|
41
|
+
const rankingDesc = Object.fromEntries(Object.entries(ranking).sort((a, b) => b[1] - a[1]));
|
|
42
|
+
expect(JSON.stringify(dataList)).to.be.equal(JSON.stringify(rankingDesc));
|
|
43
|
+
done();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
export { };
|