@tsed/adapters-redis 7.0.0-rc.2 → 7.0.0-rc.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.
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OIDCRedisAdapter = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const di_1 = require("@tsed/di");
6
+ const ioredis_1 = require("@tsed/ioredis");
7
+ const RedisAdapter_1 = require("./RedisAdapter");
8
+ const GRANTABLE = new Set(["AccessToken", "AuthorizationCode", "RefreshToken", "DeviceCode", "BackchannelAuthenticationRequest"]);
9
+ const CONSUMABLE = new Set(["AuthorizationCode", "RefreshToken", "DeviceCode", "BackchannelAuthenticationRequest"]);
10
+ function grantKeyFor(id) {
11
+ return `$oidc:grant:${id}`;
12
+ }
13
+ function userCodeKeyFor(userCode) {
14
+ return `$oidc:userCode:${userCode}`;
15
+ }
16
+ function uidKeyFor(uid) {
17
+ return `$oidc:uid:${uid}`;
18
+ }
19
+ let OIDCRedisAdapter = class OIDCRedisAdapter extends RedisAdapter_1.RedisAdapter {
20
+ configuration;
21
+ isGrantable;
22
+ constructor(options, connections, configuration) {
23
+ super(options, connections, configuration);
24
+ this.configuration = configuration;
25
+ this.useHash = CONSUMABLE.has(this.collectionName);
26
+ this.isGrantable = GRANTABLE.has(this.collectionName);
27
+ this.hooks.on("insert", this.onInsert.bind(this));
28
+ }
29
+ async onInsert(multi, payload, expiresIn) {
30
+ const id = payload._id;
31
+ const key = this.key(id);
32
+ if (this.isGrantable && payload.grantId) {
33
+ const grantKey = grantKeyFor(payload.grantId);
34
+ multi.rpush(grantKey, key);
35
+ // if you're seeing grant key lists growing out of acceptable proportions consider using LTRIM
36
+ // here to trim the list to an appropriate length
37
+ const ttl = await this.db.ttl(grantKey);
38
+ if (expiresIn && expiresIn > ttl) {
39
+ multi.expire(grantKey, expiresIn);
40
+ }
41
+ }
42
+ if (payload.userCode) {
43
+ const userCodeKey = userCodeKeyFor(payload.userCode);
44
+ multi.set(userCodeKey, id);
45
+ expiresIn && multi.expire(userCodeKey, expiresIn);
46
+ }
47
+ if (payload.uid) {
48
+ const uidKey = uidKeyFor(payload.uid);
49
+ multi.set(uidKey, id);
50
+ expiresIn && multi.expire(uidKey, expiresIn);
51
+ }
52
+ return multi;
53
+ }
54
+ async findByUid(uid) {
55
+ const id = await this.db.get(uidKeyFor(uid));
56
+ return id && this.findById(id);
57
+ }
58
+ async findByUserCode(userCode) {
59
+ const id = await this.db.get(userCodeKeyFor(userCode));
60
+ return id && this.findById(id);
61
+ }
62
+ async destroy(id) {
63
+ const key = this.key(id);
64
+ await this.db.del(key);
65
+ }
66
+ async revokeByGrantId(grantId) {
67
+ // eslint-disable-line class-methods-use-this
68
+ const multi = this.db.multi();
69
+ const key = grantKeyFor(grantId);
70
+ const tokens = await this.db.lrange(key, 0, -1);
71
+ tokens.forEach((token) => multi.del(token));
72
+ multi.del(grantKeyFor(grantId));
73
+ await multi.exec();
74
+ }
75
+ async consume(id) {
76
+ await this.db.hset(this.key(id), "consumed", Math.floor(Date.now() / 1000));
77
+ }
78
+ };
79
+ OIDCRedisAdapter = tslib_1.__decorate([
80
+ tslib_1.__param(0, di_1.Opts),
81
+ tslib_1.__param(1, (0, di_1.Inject)(ioredis_1.IOREDIS_CONNECTIONS)),
82
+ tslib_1.__param(2, (0, di_1.Configuration)()),
83
+ tslib_1.__metadata("design:paramtypes", [Object, Array, Object])
84
+ ], OIDCRedisAdapter);
85
+ exports.OIDCRedisAdapter = OIDCRedisAdapter;
86
+ //# sourceMappingURL=OIDCRedisAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OIDCRedisAdapter.js","sourceRoot":"","sources":["../../../src/adapters/OIDCRedisAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import {AdapterModel} from \"@tsed/adapters\";\nimport {Configuration, Inject, Opts} from \"@tsed/di\";\nimport {ChainableCommander} from \"ioredis\";\nimport {IOREDIS_CONNECTIONS, IORedis} from \"@tsed/ioredis\";\n\nimport {RedisAdapter, RedisAdapterConstructorOptions} from \"./RedisAdapter\";\n\nconst GRANTABLE = new Set([\"AccessToken\", \"AuthorizationCode\", \"RefreshToken\", \"DeviceCode\", \"BackchannelAuthenticationRequest\"]);\nconst CONSUMABLE = new Set([\"AuthorizationCode\", \"RefreshToken\", \"DeviceCode\", \"BackchannelAuthenticationRequest\"]);\n\nfunction grantKeyFor(id: string) {\n return `$oidc:grant:${id}`;\n}\n\nfunction userCodeKeyFor(userCode: string) {\n return `$oidc:userCode:${userCode}`;\n}\n\nfunction uidKeyFor(uid: string) {\n return `$oidc:uid:${uid}`;\n}\n\nexport class OIDCRedisAdapter<T extends AdapterModel> extends RedisAdapter<T> {\n protected isGrantable: boolean;\n\n constructor(\n @Opts options: RedisAdapterConstructorOptions,\n @Inject(IOREDIS_CONNECTIONS) connections: IORedis[],\n @Configuration() protected configuration: Configuration\n ) {\n super(options, connections, configuration);\n\n this.useHash = CONSUMABLE.has(this.collectionName);\n this.isGrantable = GRANTABLE.has(this.collectionName);\n this.hooks.on(\"insert\", this.onInsert.bind(this));\n }\n\n async onInsert(multi: ChainableCommander, payload: T, expiresIn: number) {\n const id = payload._id;\n\n const key = this.key(id);\n\n if (this.isGrantable && payload.grantId) {\n const grantKey = grantKeyFor(payload.grantId);\n\n multi.rpush(grantKey, key);\n // if you're seeing grant key lists growing out of acceptable proportions consider using LTRIM\n // here to trim the list to an appropriate length\n const ttl = await this.db.ttl(grantKey);\n\n if (expiresIn && expiresIn > ttl) {\n multi.expire(grantKey, expiresIn);\n }\n }\n\n if (payload.userCode) {\n const userCodeKey = userCodeKeyFor(payload.userCode);\n\n multi.set(userCodeKey, id);\n expiresIn && multi.expire(userCodeKey, expiresIn);\n }\n\n if (payload.uid) {\n const uidKey = uidKeyFor(payload.uid);\n\n multi.set(uidKey, id);\n expiresIn && multi.expire(uidKey, expiresIn);\n }\n\n return multi;\n }\n\n async findByUid(uid: string) {\n const id = await this.db.get(uidKeyFor(uid));\n\n return id && this.findById(id);\n }\n\n async findByUserCode(userCode: string) {\n const id = await this.db.get(userCodeKeyFor(userCode));\n return id && this.findById(id);\n }\n\n async destroy(id: string) {\n const key = this.key(id);\n await this.db.del(key);\n }\n\n async revokeByGrantId(grantId: string) {\n // eslint-disable-line class-methods-use-this\n const multi = this.db.multi();\n const key = grantKeyFor(grantId);\n const tokens = await this.db.lrange(key, 0, -1);\n\n tokens.forEach((token) => multi.del(token));\n multi.del(grantKeyFor(grantId));\n\n await multi.exec();\n }\n\n async consume(id: string) {\n await this.db.hset(this.key(id), \"consumed\", Math.floor(Date.now() / 1000));\n }\n}\n"]}
@@ -3,24 +3,42 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RedisAdapter = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const adapters_1 = require("@tsed/adapters");
6
+ const core_1 = require("@tsed/core");
6
7
  const di_1 = require("@tsed/di");
7
- const ioredis_1 = tslib_1.__importDefault(require("ioredis"));
8
+ const ioredis_1 = require("@tsed/ioredis");
8
9
  const uuid_1 = require("uuid");
9
- require("../services/RedisFactory");
10
- class RedisAdapter extends adapters_1.Adapter {
11
- db;
10
+ const getId = (key) => key.split(":")[2];
11
+ const flatKeys = (keys) => {
12
+ return keys.flatMap(([, result]) => result).filter(Boolean);
13
+ };
14
+ let RedisAdapter = class RedisAdapter extends adapters_1.Adapter {
15
+ configuration;
16
+ hooks = new core_1.Hooks();
17
+ connectionName;
18
+ connection;
19
+ useHash = false;
20
+ constructor(options, connections, configuration) {
21
+ super(options, configuration);
22
+ this.configuration = configuration;
23
+ this.useHash = Boolean(options.useHash);
24
+ this.connectionName = options.connectionName || "default";
25
+ this.connection = connections.find((connection) => connection.name === this.connectionName); // || connections[0];
26
+ }
27
+ get db() {
28
+ return this.connection;
29
+ }
12
30
  key(id) {
13
31
  return `${this.collectionName}:${id}`;
14
32
  }
15
33
  async create(payload, expiresAt) {
16
- payload._id = (0, uuid_1.v4)();
34
+ delete payload._id;
17
35
  return this.insert(payload, expiresAt);
18
36
  }
19
37
  async upsert(id, payload, expiresAt) {
20
- let item = await this.findById(id);
38
+ const item = await this.findById(id);
21
39
  if (!item) {
22
40
  payload = { ...payload, _id: id };
23
- return this.insert(payload, expiresAt);
41
+ return await this.insert(payload, expiresAt);
24
42
  }
25
43
  return (await this.update(id, payload, expiresAt));
26
44
  }
@@ -33,7 +51,8 @@ class RedisAdapter extends adapters_1.Adapter {
33
51
  return undefined;
34
52
  }
35
53
  return this.insert({
36
- ...this.updateInstance(item, payload),
54
+ ...item,
55
+ ...(0, core_1.cleanObject)(payload),
37
56
  _id: item._id
38
57
  }, expiresAt);
39
58
  }
@@ -53,11 +72,19 @@ class RedisAdapter extends adapters_1.Adapter {
53
72
  return keys.length === foundKeys.length ? this.findById(id) : undefined;
54
73
  }
55
74
  async findById(_id) {
56
- const item = await this.db.get(this.key(_id));
75
+ const key = this.key(_id);
76
+ const item = this.useHash ? await this.db.hgetall(key) : await this.db.get(key);
57
77
  if (!item) {
58
78
  return undefined;
59
79
  }
60
- return this.deserialize(JSON.parse(item));
80
+ if ((0, core_1.isString)(item)) {
81
+ return this.deserialize(JSON.parse(item));
82
+ }
83
+ const { payload, ...rest } = item;
84
+ return {
85
+ ...rest,
86
+ ...(payload ? JSON.parse(payload) : {})
87
+ };
61
88
  }
62
89
  async findAll(predicate = {}) {
63
90
  const { _id, ...props } = predicate;
@@ -74,7 +101,9 @@ class RedisAdapter extends adapters_1.Adapter {
74
101
  async deleteOne(predicate) {
75
102
  const item = await this.findOne(predicate);
76
103
  if (item) {
77
- await Promise.all([this.db.del(this.key(item._id)), this.cleanIndexes(item._id)]);
104
+ const id = this.key(item._id);
105
+ const indexIds = await this.getAllIndex(item._id);
106
+ await this.db.del([id, ...indexIds]);
78
107
  return this.deserialize(item);
79
108
  }
80
109
  }
@@ -83,23 +112,29 @@ class RedisAdapter extends adapters_1.Adapter {
83
112
  }
84
113
  async deleteMany(predicate) {
85
114
  const items = await this.findAll(predicate);
86
- const promises = items.map(async (item) => {
87
- await Promise.all([this.db.del(this.key(item._id)), this.cleanIndexes(item._id)]);
115
+ const pipeline = this.db.pipeline();
116
+ const ids = [];
117
+ const results = items.map((item) => {
118
+ ids.push(this.key(item._id));
119
+ this.getAllIndex(item._id, pipeline);
88
120
  return this.deserialize(item);
89
121
  });
90
- return Promise.all(promises);
122
+ const keys = await pipeline.exec();
123
+ this.db.del([...ids, ...flatKeys(keys)]);
124
+ return results;
91
125
  }
92
126
  async findKeys(props) {
93
127
  const keys = Object.keys(props);
94
- const promises = this.indexes
128
+ const pipeline = this.db.pipeline();
129
+ this.indexes
95
130
  .filter(({ propertyKey }) => keys.includes(propertyKey))
96
- .map(({ propertyKey }) => {
131
+ .forEach(({ propertyKey }) => {
97
132
  const value = props[propertyKey];
98
133
  const patterns = this.getIndexedKey("*", propertyKey, value);
99
- return this.db.keys(patterns);
134
+ pipeline.keys(patterns);
100
135
  });
101
- const result = await Promise.all(promises);
102
- return result.reduce((keys, input) => keys.concat(input), []).filter(Boolean);
136
+ const results = await pipeline.exec();
137
+ return flatKeys(results);
103
138
  }
104
139
  async insert(payload, expiresAt) {
105
140
  const id = (payload._id = payload._id || (0, uuid_1.v4)());
@@ -107,7 +142,8 @@ class RedisAdapter extends adapters_1.Adapter {
107
142
  await this.validate(payload);
108
143
  const multi = this.db.multi();
109
144
  const key = this.key(id);
110
- await multi.set(key, JSON.stringify(this.serialize(payload)));
145
+ const strPayload = JSON.stringify(this.serialize(payload));
146
+ this.useHash ? await multi.hset(key, { payload: strPayload }) : await multi.set(key, strPayload);
111
147
  if (expiresIn) {
112
148
  multi.expire(key, expiresIn);
113
149
  }
@@ -117,13 +153,15 @@ class RedisAdapter extends adapters_1.Adapter {
117
153
  multi.set(indexedKey, id);
118
154
  expiresIn && multi.expire(indexedKey, expiresIn);
119
155
  });
156
+ await this.hooks.asyncAlter("insert", multi, [payload, expiresIn]);
120
157
  await multi.exec();
121
- return this.deserialize(payload);
158
+ const result = this.deserialize(payload, { useAlias: false });
159
+ await this.hooks.asyncEmit("afterInsert", [result]);
160
+ return result;
122
161
  }
123
- async cleanIndexes(id) {
162
+ getAllIndex(id, pipeline) {
124
163
  const key = ["$idx", this.key(id), "*"].join(":");
125
- const keys = await this.db.keys(key);
126
- return this.db.del(...keys);
164
+ return (pipeline || this.db).keys(key);
127
165
  }
128
166
  getIndexedKey(id, propertyKey, value) {
129
167
  const key = this.key(id);
@@ -131,16 +169,19 @@ class RedisAdapter extends adapters_1.Adapter {
131
169
  }
132
170
  async getAll() {
133
171
  const keys = await this.db.keys(`${this.collectionName}:*`);
134
- const items = await Promise.all(keys.map((key) => this.findById(key.split(":")[1])));
135
- return items.filter(Boolean);
172
+ const pipeline = this.db.pipeline();
173
+ keys.forEach((key) => {
174
+ pipeline.get(key);
175
+ });
176
+ const result = await pipeline.exec();
177
+ return (result || []).map(([, data]) => this.deserialize(JSON.parse(data))).filter(Boolean);
136
178
  }
137
179
  async findAllBy(props) {
138
180
  const keys = Object.keys(props);
139
- let foundKeys = await this.findKeys(props);
181
+ const foundKeys = await this.findKeys(props);
140
182
  if (foundKeys.length < keys.length) {
141
183
  return [];
142
184
  }
143
- const getId = (key) => key.split(":")[2];
144
185
  const map = foundKeys.reduce((map, key) => {
145
186
  const id = getId(key);
146
187
  const value = map.get(id) || 0;
@@ -150,10 +191,12 @@ class RedisAdapter extends adapters_1.Adapter {
150
191
  const result = await Promise.all(promises);
151
192
  return result.filter(Boolean);
152
193
  }
153
- }
154
- tslib_1.__decorate([
155
- (0, di_1.Inject)(ioredis_1.default),
156
- tslib_1.__metadata("design:type", Object)
157
- ], RedisAdapter.prototype, "db", void 0);
194
+ };
195
+ RedisAdapter = tslib_1.__decorate([
196
+ tslib_1.__param(0, di_1.Opts),
197
+ tslib_1.__param(1, (0, di_1.Inject)(ioredis_1.IOREDIS_CONNECTIONS)),
198
+ tslib_1.__param(2, (0, di_1.Configuration)()),
199
+ tslib_1.__metadata("design:paramtypes", [Object, Array, Object])
200
+ ], RedisAdapter);
158
201
  exports.RedisAdapter = RedisAdapter;
159
202
  //# sourceMappingURL=RedisAdapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RedisAdapter.js","sourceRoot":"","sources":["../../../src/adapters/RedisAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import {Adapter, AdapterModel} from \"@tsed/adapters\";\nimport {Inject} from \"@tsed/di\";\nimport IoRedis from \"ioredis\";\nimport type {Redis} from \"ioredis\";\nimport {v4 as uuid} from \"uuid\";\nimport \"../services/RedisFactory\";\n\nexport class RedisAdapter<T extends AdapterModel> extends Adapter<T> {\n @Inject(IoRedis)\n readonly db: Redis;\n\n key(id: string) {\n return `${this.collectionName}:${id}`;\n }\n\n public async create(payload: Partial<T>, expiresAt?: Date): Promise<T> {\n payload._id = uuid();\n\n return this.insert(payload, expiresAt);\n }\n\n public async upsert(id: string, payload: T, expiresAt?: Date): Promise<T> {\n let item = await this.findById(id);\n\n if (!item) {\n payload = {...payload, _id: id};\n\n return this.insert(payload, expiresAt);\n }\n\n return (await this.update(id, payload, expiresAt)) as T;\n }\n\n public async update(id: string, payload: T, expiresAt?: Date): Promise<T | undefined> {\n return this.updateOne({_id: id}, payload, expiresAt);\n }\n\n public async updateOne(predicate: Partial<T & any>, payload: T, expiresAt?: Date): Promise<T | undefined> {\n const item = await this.findOne(predicate);\n\n if (!item) {\n return undefined;\n }\n\n return this.insert(\n {\n ...this.updateInstance(item, payload),\n _id: item._id\n },\n expiresAt\n );\n }\n\n async findOne(predicate: Partial<T & any>): Promise<T | undefined> {\n const {_id, ...props} = predicate;\n\n if (_id) {\n return this.findById(_id);\n }\n\n const keys = Object.keys(props);\n let foundKeys = await this.findKeys(props);\n\n if (foundKeys.length < keys.length) {\n return undefined;\n }\n\n const getId = (key: string) => key.split(\":\")[2];\n\n const id = getId(foundKeys[0]);\n\n foundKeys = foundKeys.filter((key) => id === getId(key));\n\n return keys.length === foundKeys.length ? this.findById(id) : undefined;\n }\n\n async findById(_id: string): Promise<T | undefined> {\n const item = await this.db.get(this.key(_id));\n\n if (!item) {\n return undefined;\n }\n\n return this.deserialize(JSON.parse(item));\n }\n\n public async findAll(predicate: Partial<T & any> = {}): Promise<T[]> {\n const {_id, ...props} = predicate;\n\n if (_id) {\n const item = await this.findById(_id);\n return item ? [item] : [];\n }\n\n const keys = Object.keys(props);\n\n if (keys.length === 0) {\n return this.getAll();\n }\n\n return this.findAllBy(props);\n }\n\n public async deleteOne(predicate: Partial<T & any>): Promise<T | undefined> {\n const item = await this.findOne(predicate);\n\n if (item) {\n await Promise.all([this.db.del(this.key(item._id)), this.cleanIndexes(item._id)]);\n\n return this.deserialize(item);\n }\n }\n\n public async deleteById(_id: string): Promise<T | undefined> {\n return this.deleteOne({_id} as any);\n }\n\n public async deleteMany(predicate: Partial<T>): Promise<T[]> {\n const items = await this.findAll(predicate);\n\n const promises = items.map(async (item) => {\n await Promise.all([this.db.del(this.key(item._id)), this.cleanIndexes(item._id)]);\n\n return this.deserialize(item);\n });\n\n return Promise.all(promises);\n }\n\n protected async findKeys(props: any): Promise<string[]> {\n const keys: any[] = Object.keys(props);\n\n const promises = this.indexes\n .filter(({propertyKey}) => keys.includes(propertyKey))\n .map(({propertyKey}) => {\n const value = props[propertyKey];\n const patterns = this.getIndexedKey(\"*\", propertyKey, value);\n\n return this.db.keys(patterns);\n });\n\n const result = await Promise.all(promises);\n\n return result.reduce((keys: string[], input: string[]) => keys.concat(input), []).filter(Boolean);\n }\n\n protected async insert(payload: Partial<T>, expiresAt?: Date) {\n const id = (payload._id = payload._id || uuid());\n\n const expiresIn = expiresAt ? expiresAt.getTime() - Date.now() : null;\n\n await this.validate(payload as T);\n\n const multi = this.db.multi();\n const key = this.key(id);\n\n await multi.set(key, JSON.stringify(this.serialize(payload)));\n\n if (expiresIn) {\n multi.expire(key, expiresIn);\n }\n\n this.indexes.forEach(({propertyKey}) => {\n const value = payload[propertyKey];\n const indexedKey = this.getIndexedKey(id, propertyKey, value);\n\n multi.set(indexedKey, id);\n expiresIn && multi.expire(indexedKey, expiresIn);\n });\n\n await multi.exec();\n\n return this.deserialize(payload);\n }\n\n protected async cleanIndexes(id: string) {\n const key = [\"$idx\", this.key(id), \"*\"].join(\":\");\n\n const keys = await this.db.keys(key);\n\n return this.db.del(...keys);\n }\n\n protected getIndexedKey(id: string, propertyKey: string, value: any): string {\n const key = this.key(id);\n return [\"$idx\", key, `${propertyKey}(${value})`].map(String).join(\":\");\n }\n\n protected async getAll(): Promise<T[]> {\n const keys = await this.db.keys(`${this.collectionName}:*`);\n const items = await Promise.all(keys.map((key) => this.findById(key.split(\":\")[1])));\n\n return items.filter(Boolean) as T[];\n }\n\n protected async findAllBy(props: Partial<T & any>): Promise<T[]> {\n const keys = Object.keys(props);\n let foundKeys = await this.findKeys(props);\n\n if (foundKeys.length < keys.length) {\n return [];\n }\n\n const getId = (key: string) => key.split(\":\")[2];\n\n const map = foundKeys.reduce((map: Map<string, number>, key) => {\n const id = getId(key);\n const value = map.get(id) || 0;\n\n return map.set(id, value + 1);\n }, new Map());\n\n const promises = [...map.entries()].filter(([, num]) => num === keys.length).map(([id]) => this.findById(id));\n\n const result = await Promise.all(promises);\n\n return result.filter(Boolean) as T[];\n }\n}\n"]}
1
+ {"version":3,"file":"RedisAdapter.js","sourceRoot":"","sources":["../../../src/adapters/RedisAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import {Adapter, AdapterConstructorOptions, AdapterModel} from \"@tsed/adapters\";\nimport {cleanObject, Hooks, isString} from \"@tsed/core\";\nimport {Configuration, Inject, Opts} from \"@tsed/di\";\nimport {IORedis, IOREDIS_CONNECTIONS} from \"@tsed/ioredis\";\nimport type {ChainableCommander, Redis} from \"ioredis\";\nimport {v4 as uuid} from \"uuid\";\n\nconst getId = (key: string) => key.split(\":\")[2];\nconst flatKeys = (keys: [Error | null, string[]][]): string[] => {\n return keys.flatMap(([, result]) => result).filter(Boolean);\n};\n\nexport interface RedisAdapterConstructorOptions extends AdapterConstructorOptions {\n connectionName?: string;\n useHash?: boolean;\n}\n\nexport class RedisAdapter<Model extends AdapterModel> extends Adapter<Model> {\n readonly hooks = new Hooks();\n readonly connectionName: string;\n readonly connection: IORedis;\n protected useHash: boolean = false;\n\n constructor(\n @Opts options: RedisAdapterConstructorOptions,\n @Inject(IOREDIS_CONNECTIONS) connections: IORedis[],\n @Configuration() protected configuration: Configuration\n ) {\n super(options, configuration);\n\n this.useHash = Boolean(options.useHash);\n this.connectionName = options.connectionName || \"default\";\n this.connection = connections.find((connection) => connection.name === this.connectionName)!; // || connections[0];\n }\n\n get db(): Redis {\n return this.connection;\n }\n\n key(id: string) {\n return `${this.collectionName}:${id}`;\n }\n\n public async create(payload: Partial<Model>, expiresAt?: Date): Promise<Model> {\n delete payload._id;\n return this.insert(payload, expiresAt);\n }\n\n public async upsert(id: string, payload: Model, expiresAt?: Date): Promise<Model> {\n const item = await this.findById(id);\n\n if (!item) {\n payload = {...payload, _id: id};\n\n return await this.insert(payload, expiresAt);\n }\n\n return (await this.update(id, payload, expiresAt)) as Model;\n }\n\n public async update(id: string, payload: Model, expiresAt?: Date): Promise<Model | undefined> {\n return this.updateOne({_id: id}, payload, expiresAt);\n }\n\n public async updateOne(predicate: Partial<Model & any>, payload: Model, expiresAt?: Date): Promise<Model | undefined> {\n const item = await this.findOne(predicate);\n\n if (!item) {\n return undefined;\n }\n\n return this.insert(\n {\n ...item,\n ...cleanObject(payload),\n _id: item._id\n },\n expiresAt\n );\n }\n\n async findOne(predicate: Partial<Model & any>): Promise<Model | undefined> {\n const {_id, ...props} = predicate;\n\n if (_id) {\n return this.findById(_id);\n }\n\n const keys = Object.keys(props);\n let foundKeys = await this.findKeys(props);\n\n if (foundKeys.length < keys.length) {\n return undefined;\n }\n\n const getId = (key: string) => key.split(\":\")[2];\n const id = getId(foundKeys[0]);\n\n foundKeys = foundKeys.filter((key) => id === getId(key));\n\n return keys.length === foundKeys.length ? this.findById(id) : undefined;\n }\n\n async findById(_id: string): Promise<Model | undefined> {\n const key = this.key(_id);\n\n const item = this.useHash ? await this.db.hgetall(key) : await this.db.get(key);\n\n if (!item) {\n return undefined;\n }\n\n if (isString(item)) {\n return this.deserialize(JSON.parse(item));\n }\n\n const {payload, ...rest} = item;\n\n return {\n ...rest,\n ...(payload ? JSON.parse(payload) : {})\n };\n }\n\n public async findAll(predicate: Partial<Model & any> = {}): Promise<Model[]> {\n const {_id, ...props} = predicate;\n\n if (_id) {\n const item = await this.findById(_id);\n return item ? [item] : [];\n }\n\n const keys = Object.keys(props);\n\n if (keys.length === 0) {\n return this.getAll();\n }\n\n return this.findAllBy(props);\n }\n\n public async deleteOne(predicate: Partial<Model & any>): Promise<Model | undefined> {\n const item = await this.findOne(predicate);\n\n if (item) {\n const id = this.key(item._id);\n const indexIds = await this.getAllIndex(item._id);\n\n await this.db.del([id, ...indexIds]);\n\n return this.deserialize(item);\n }\n }\n\n public async deleteById(_id: string): Promise<Model | undefined> {\n return this.deleteOne({_id} as any);\n }\n\n public async deleteMany(predicate: Partial<Model>): Promise<Model[]> {\n const items = await this.findAll(predicate);\n\n const pipeline = this.db.pipeline();\n const ids: string[] = [];\n\n const results = items.map((item) => {\n ids.push(this.key(item._id));\n\n this.getAllIndex(item._id, pipeline);\n\n return this.deserialize(item);\n });\n\n const keys = await pipeline.exec();\n\n this.db.del([...ids, ...flatKeys(keys as any)]);\n\n return results;\n }\n\n protected async findKeys(props: any): Promise<string[]> {\n const keys: any[] = Object.keys(props);\n const pipeline = this.db.pipeline();\n\n this.indexes\n .filter(({propertyKey}) => keys.includes(propertyKey))\n .forEach(({propertyKey}) => {\n const value = props[propertyKey];\n const patterns = this.getIndexedKey(\"*\", propertyKey, value);\n\n pipeline.keys(patterns);\n });\n\n const results = await pipeline.exec();\n\n return flatKeys(results as any[]);\n }\n\n protected async insert(payload: Partial<Model>, expiresAt?: Date) {\n const id = (payload._id = payload._id || uuid());\n\n const expiresIn = expiresAt ? expiresAt.getTime() - Date.now() : null;\n\n await this.validate(payload as Model);\n\n const multi = this.db.multi();\n const key = this.key(id);\n\n const strPayload = JSON.stringify(this.serialize(payload));\n\n this.useHash ? await multi.hset(key, {payload: strPayload}) : await multi.set(key, strPayload);\n\n if (expiresIn) {\n multi.expire(key, expiresIn);\n }\n\n this.indexes.forEach(({propertyKey}) => {\n const value = payload[propertyKey];\n const indexedKey = this.getIndexedKey(id, propertyKey, value);\n\n multi.set(indexedKey, id);\n expiresIn && multi.expire(indexedKey, expiresIn);\n });\n\n await this.hooks.asyncAlter(\"insert\", multi, [payload, expiresIn]);\n\n await multi.exec();\n\n const result = this.deserialize(payload, {useAlias: false});\n\n await this.hooks.asyncEmit(\"afterInsert\", [result]);\n\n return result;\n }\n\n protected getAllIndex(id: string): Promise<string[]>;\n protected getAllIndex(id: string, pipeline: ChainableCommander): ChainableCommander;\n protected getAllIndex(id: string, pipeline?: ChainableCommander) {\n const key = [\"$idx\", this.key(id), \"*\"].join(\":\");\n\n return (pipeline || this.db).keys(key);\n }\n\n protected getIndexedKey(id: string, propertyKey: string, value: any): string {\n const key = this.key(id);\n return [\"$idx\", key, `${propertyKey}(${value})`].map(String).join(\":\");\n }\n\n protected async getAll(): Promise<Model[]> {\n const keys = await this.db.keys(`${this.collectionName}:*`);\n const pipeline = this.db.pipeline();\n\n keys.forEach((key) => {\n pipeline.get(key);\n });\n\n const result = await pipeline.exec();\n return (result || []).map(([, data]: [any, string]) => this.deserialize(JSON.parse(data))).filter(Boolean);\n }\n\n protected async findAllBy(props: Partial<Model & any>): Promise<Model[]> {\n const keys = Object.keys(props);\n const foundKeys = await this.findKeys(props);\n\n if (foundKeys.length < keys.length) {\n return [];\n }\n\n const map = foundKeys.reduce((map: Map<string, number>, key) => {\n const id = getId(key);\n const value = map.get(id) || 0;\n\n return map.set(id, value + 1);\n }, new Map());\n\n const promises = [...map.entries()].filter(([, num]) => num === keys.length).map(([id]) => this.findById(id));\n\n const result = await Promise.all(promises);\n\n return result.filter(Boolean) as Model[];\n }\n}\n"]}
package/lib/cjs/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const tslib_1 = require("tslib");
7
+ tslib_1.__exportStar(require("./adapters/OIDCRedisAdapter"), exports);
7
8
  tslib_1.__exportStar(require("./adapters/RedisAdapter"), exports);
8
9
  tslib_1.__exportStar(require("./domain/RedisAdaptersSettings"), exports);
9
- tslib_1.__exportStar(require("./services/RedisFactory"), exports);
10
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,kEAAwC;AACxC,yEAA+C;AAC/C,kEAAwC","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./adapters/RedisAdapter\";\nexport * from \"./domain/RedisAdaptersSettings\";\nexport * from \"./services/RedisFactory\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,sEAA4C;AAC5C,kEAAwC;AACxC,yEAA+C","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./adapters/OIDCRedisAdapter\";\nexport * from \"./adapters/RedisAdapter\";\nexport * from \"./domain/RedisAdaptersSettings\";\n"]}
@@ -0,0 +1,83 @@
1
+ import { __decorate, __metadata, __param } from "tslib";
2
+ import { Configuration, Inject, Opts } from "@tsed/di";
3
+ import { IOREDIS_CONNECTIONS } from "@tsed/ioredis";
4
+ import { RedisAdapter } from "./RedisAdapter.js";
5
+ const GRANTABLE = new Set(["AccessToken", "AuthorizationCode", "RefreshToken", "DeviceCode", "BackchannelAuthenticationRequest"]);
6
+ const CONSUMABLE = new Set(["AuthorizationCode", "RefreshToken", "DeviceCode", "BackchannelAuthenticationRequest"]);
7
+ function grantKeyFor(id) {
8
+ return `$oidc:grant:${id}`;
9
+ }
10
+ function userCodeKeyFor(userCode) {
11
+ return `$oidc:userCode:${userCode}`;
12
+ }
13
+ function uidKeyFor(uid) {
14
+ return `$oidc:uid:${uid}`;
15
+ }
16
+ let OIDCRedisAdapter = class OIDCRedisAdapter extends RedisAdapter {
17
+ configuration;
18
+ isGrantable;
19
+ constructor(options, connections, configuration) {
20
+ super(options, connections, configuration);
21
+ this.configuration = configuration;
22
+ this.useHash = CONSUMABLE.has(this.collectionName);
23
+ this.isGrantable = GRANTABLE.has(this.collectionName);
24
+ this.hooks.on("insert", this.onInsert.bind(this));
25
+ }
26
+ async onInsert(multi, payload, expiresIn) {
27
+ const id = payload._id;
28
+ const key = this.key(id);
29
+ if (this.isGrantable && payload.grantId) {
30
+ const grantKey = grantKeyFor(payload.grantId);
31
+ multi.rpush(grantKey, key);
32
+ // if you're seeing grant key lists growing out of acceptable proportions consider using LTRIM
33
+ // here to trim the list to an appropriate length
34
+ const ttl = await this.db.ttl(grantKey);
35
+ if (expiresIn && expiresIn > ttl) {
36
+ multi.expire(grantKey, expiresIn);
37
+ }
38
+ }
39
+ if (payload.userCode) {
40
+ const userCodeKey = userCodeKeyFor(payload.userCode);
41
+ multi.set(userCodeKey, id);
42
+ expiresIn && multi.expire(userCodeKey, expiresIn);
43
+ }
44
+ if (payload.uid) {
45
+ const uidKey = uidKeyFor(payload.uid);
46
+ multi.set(uidKey, id);
47
+ expiresIn && multi.expire(uidKey, expiresIn);
48
+ }
49
+ return multi;
50
+ }
51
+ async findByUid(uid) {
52
+ const id = await this.db.get(uidKeyFor(uid));
53
+ return id && this.findById(id);
54
+ }
55
+ async findByUserCode(userCode) {
56
+ const id = await this.db.get(userCodeKeyFor(userCode));
57
+ return id && this.findById(id);
58
+ }
59
+ async destroy(id) {
60
+ const key = this.key(id);
61
+ await this.db.del(key);
62
+ }
63
+ async revokeByGrantId(grantId) {
64
+ // eslint-disable-line class-methods-use-this
65
+ const multi = this.db.multi();
66
+ const key = grantKeyFor(grantId);
67
+ const tokens = await this.db.lrange(key, 0, -1);
68
+ tokens.forEach((token) => multi.del(token));
69
+ multi.del(grantKeyFor(grantId));
70
+ await multi.exec();
71
+ }
72
+ async consume(id) {
73
+ await this.db.hset(this.key(id), "consumed", Math.floor(Date.now() / 1000));
74
+ }
75
+ };
76
+ OIDCRedisAdapter = __decorate([
77
+ __param(0, Opts),
78
+ __param(1, Inject(IOREDIS_CONNECTIONS)),
79
+ __param(2, Configuration()),
80
+ __metadata("design:paramtypes", [Object, Array, Object])
81
+ ], OIDCRedisAdapter);
82
+ export { OIDCRedisAdapter };
83
+ //# sourceMappingURL=OIDCRedisAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OIDCRedisAdapter.js","sourceRoot":"","sources":["../../../src/adapters/OIDCRedisAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import {AdapterModel} from \"@tsed/adapters\";\nimport {Configuration, Inject, Opts} from \"@tsed/di\";\nimport {ChainableCommander} from \"ioredis\";\nimport {IOREDIS_CONNECTIONS, IORedis} from \"@tsed/ioredis\";\n\nimport {RedisAdapter, RedisAdapterConstructorOptions} from \"./RedisAdapter\";\n\nconst GRANTABLE = new Set([\"AccessToken\", \"AuthorizationCode\", \"RefreshToken\", \"DeviceCode\", \"BackchannelAuthenticationRequest\"]);\nconst CONSUMABLE = new Set([\"AuthorizationCode\", \"RefreshToken\", \"DeviceCode\", \"BackchannelAuthenticationRequest\"]);\n\nfunction grantKeyFor(id: string) {\n return `$oidc:grant:${id}`;\n}\n\nfunction userCodeKeyFor(userCode: string) {\n return `$oidc:userCode:${userCode}`;\n}\n\nfunction uidKeyFor(uid: string) {\n return `$oidc:uid:${uid}`;\n}\n\nexport class OIDCRedisAdapter<T extends AdapterModel> extends RedisAdapter<T> {\n protected isGrantable: boolean;\n\n constructor(\n @Opts options: RedisAdapterConstructorOptions,\n @Inject(IOREDIS_CONNECTIONS) connections: IORedis[],\n @Configuration() protected configuration: Configuration\n ) {\n super(options, connections, configuration);\n\n this.useHash = CONSUMABLE.has(this.collectionName);\n this.isGrantable = GRANTABLE.has(this.collectionName);\n this.hooks.on(\"insert\", this.onInsert.bind(this));\n }\n\n async onInsert(multi: ChainableCommander, payload: T, expiresIn: number) {\n const id = payload._id;\n\n const key = this.key(id);\n\n if (this.isGrantable && payload.grantId) {\n const grantKey = grantKeyFor(payload.grantId);\n\n multi.rpush(grantKey, key);\n // if you're seeing grant key lists growing out of acceptable proportions consider using LTRIM\n // here to trim the list to an appropriate length\n const ttl = await this.db.ttl(grantKey);\n\n if (expiresIn && expiresIn > ttl) {\n multi.expire(grantKey, expiresIn);\n }\n }\n\n if (payload.userCode) {\n const userCodeKey = userCodeKeyFor(payload.userCode);\n\n multi.set(userCodeKey, id);\n expiresIn && multi.expire(userCodeKey, expiresIn);\n }\n\n if (payload.uid) {\n const uidKey = uidKeyFor(payload.uid);\n\n multi.set(uidKey, id);\n expiresIn && multi.expire(uidKey, expiresIn);\n }\n\n return multi;\n }\n\n async findByUid(uid: string) {\n const id = await this.db.get(uidKeyFor(uid));\n\n return id && this.findById(id);\n }\n\n async findByUserCode(userCode: string) {\n const id = await this.db.get(userCodeKeyFor(userCode));\n return id && this.findById(id);\n }\n\n async destroy(id: string) {\n const key = this.key(id);\n await this.db.del(key);\n }\n\n async revokeByGrantId(grantId: string) {\n // eslint-disable-line class-methods-use-this\n const multi = this.db.multi();\n const key = grantKeyFor(grantId);\n const tokens = await this.db.lrange(key, 0, -1);\n\n tokens.forEach((token) => multi.del(token));\n multi.del(grantKeyFor(grantId));\n\n await multi.exec();\n }\n\n async consume(id: string) {\n await this.db.hset(this.key(id), \"consumed\", Math.floor(Date.now() / 1000));\n }\n}\n"]}
@@ -1,23 +1,41 @@
1
- import { __decorate, __metadata } from "tslib";
1
+ import { __decorate, __metadata, __param } from "tslib";
2
2
  import { Adapter } from "@tsed/adapters";
3
- import { Inject } from "@tsed/di";
4
- import IoRedis from "ioredis";
3
+ import { cleanObject, Hooks, isString } from "@tsed/core";
4
+ import { Configuration, Inject, Opts } from "@tsed/di";
5
+ import { IOREDIS_CONNECTIONS } from "@tsed/ioredis";
5
6
  import { v4 as uuid } from "uuid";
6
- import "../services/RedisFactory.js";
7
- export class RedisAdapter extends Adapter {
8
- db;
7
+ const getId = (key) => key.split(":")[2];
8
+ const flatKeys = (keys) => {
9
+ return keys.flatMap(([, result]) => result).filter(Boolean);
10
+ };
11
+ let RedisAdapter = class RedisAdapter extends Adapter {
12
+ configuration;
13
+ hooks = new Hooks();
14
+ connectionName;
15
+ connection;
16
+ useHash = false;
17
+ constructor(options, connections, configuration) {
18
+ super(options, configuration);
19
+ this.configuration = configuration;
20
+ this.useHash = Boolean(options.useHash);
21
+ this.connectionName = options.connectionName || "default";
22
+ this.connection = connections.find((connection) => connection.name === this.connectionName); // || connections[0];
23
+ }
24
+ get db() {
25
+ return this.connection;
26
+ }
9
27
  key(id) {
10
28
  return `${this.collectionName}:${id}`;
11
29
  }
12
30
  async create(payload, expiresAt) {
13
- payload._id = uuid();
31
+ delete payload._id;
14
32
  return this.insert(payload, expiresAt);
15
33
  }
16
34
  async upsert(id, payload, expiresAt) {
17
- let item = await this.findById(id);
35
+ const item = await this.findById(id);
18
36
  if (!item) {
19
37
  payload = { ...payload, _id: id };
20
- return this.insert(payload, expiresAt);
38
+ return await this.insert(payload, expiresAt);
21
39
  }
22
40
  return (await this.update(id, payload, expiresAt));
23
41
  }
@@ -30,7 +48,8 @@ export class RedisAdapter extends Adapter {
30
48
  return undefined;
31
49
  }
32
50
  return this.insert({
33
- ...this.updateInstance(item, payload),
51
+ ...item,
52
+ ...cleanObject(payload),
34
53
  _id: item._id
35
54
  }, expiresAt);
36
55
  }
@@ -50,11 +69,19 @@ export class RedisAdapter extends Adapter {
50
69
  return keys.length === foundKeys.length ? this.findById(id) : undefined;
51
70
  }
52
71
  async findById(_id) {
53
- const item = await this.db.get(this.key(_id));
72
+ const key = this.key(_id);
73
+ const item = this.useHash ? await this.db.hgetall(key) : await this.db.get(key);
54
74
  if (!item) {
55
75
  return undefined;
56
76
  }
57
- return this.deserialize(JSON.parse(item));
77
+ if (isString(item)) {
78
+ return this.deserialize(JSON.parse(item));
79
+ }
80
+ const { payload, ...rest } = item;
81
+ return {
82
+ ...rest,
83
+ ...(payload ? JSON.parse(payload) : {})
84
+ };
58
85
  }
59
86
  async findAll(predicate = {}) {
60
87
  const { _id, ...props } = predicate;
@@ -71,7 +98,9 @@ export class RedisAdapter extends Adapter {
71
98
  async deleteOne(predicate) {
72
99
  const item = await this.findOne(predicate);
73
100
  if (item) {
74
- await Promise.all([this.db.del(this.key(item._id)), this.cleanIndexes(item._id)]);
101
+ const id = this.key(item._id);
102
+ const indexIds = await this.getAllIndex(item._id);
103
+ await this.db.del([id, ...indexIds]);
75
104
  return this.deserialize(item);
76
105
  }
77
106
  }
@@ -80,23 +109,29 @@ export class RedisAdapter extends Adapter {
80
109
  }
81
110
  async deleteMany(predicate) {
82
111
  const items = await this.findAll(predicate);
83
- const promises = items.map(async (item) => {
84
- await Promise.all([this.db.del(this.key(item._id)), this.cleanIndexes(item._id)]);
112
+ const pipeline = this.db.pipeline();
113
+ const ids = [];
114
+ const results = items.map((item) => {
115
+ ids.push(this.key(item._id));
116
+ this.getAllIndex(item._id, pipeline);
85
117
  return this.deserialize(item);
86
118
  });
87
- return Promise.all(promises);
119
+ const keys = await pipeline.exec();
120
+ this.db.del([...ids, ...flatKeys(keys)]);
121
+ return results;
88
122
  }
89
123
  async findKeys(props) {
90
124
  const keys = Object.keys(props);
91
- const promises = this.indexes
125
+ const pipeline = this.db.pipeline();
126
+ this.indexes
92
127
  .filter(({ propertyKey }) => keys.includes(propertyKey))
93
- .map(({ propertyKey }) => {
128
+ .forEach(({ propertyKey }) => {
94
129
  const value = props[propertyKey];
95
130
  const patterns = this.getIndexedKey("*", propertyKey, value);
96
- return this.db.keys(patterns);
131
+ pipeline.keys(patterns);
97
132
  });
98
- const result = await Promise.all(promises);
99
- return result.reduce((keys, input) => keys.concat(input), []).filter(Boolean);
133
+ const results = await pipeline.exec();
134
+ return flatKeys(results);
100
135
  }
101
136
  async insert(payload, expiresAt) {
102
137
  const id = (payload._id = payload._id || uuid());
@@ -104,7 +139,8 @@ export class RedisAdapter extends Adapter {
104
139
  await this.validate(payload);
105
140
  const multi = this.db.multi();
106
141
  const key = this.key(id);
107
- await multi.set(key, JSON.stringify(this.serialize(payload)));
142
+ const strPayload = JSON.stringify(this.serialize(payload));
143
+ this.useHash ? await multi.hset(key, { payload: strPayload }) : await multi.set(key, strPayload);
108
144
  if (expiresIn) {
109
145
  multi.expire(key, expiresIn);
110
146
  }
@@ -114,13 +150,15 @@ export class RedisAdapter extends Adapter {
114
150
  multi.set(indexedKey, id);
115
151
  expiresIn && multi.expire(indexedKey, expiresIn);
116
152
  });
153
+ await this.hooks.asyncAlter("insert", multi, [payload, expiresIn]);
117
154
  await multi.exec();
118
- return this.deserialize(payload);
155
+ const result = this.deserialize(payload, { useAlias: false });
156
+ await this.hooks.asyncEmit("afterInsert", [result]);
157
+ return result;
119
158
  }
120
- async cleanIndexes(id) {
159
+ getAllIndex(id, pipeline) {
121
160
  const key = ["$idx", this.key(id), "*"].join(":");
122
- const keys = await this.db.keys(key);
123
- return this.db.del(...keys);
161
+ return (pipeline || this.db).keys(key);
124
162
  }
125
163
  getIndexedKey(id, propertyKey, value) {
126
164
  const key = this.key(id);
@@ -128,16 +166,19 @@ export class RedisAdapter extends Adapter {
128
166
  }
129
167
  async getAll() {
130
168
  const keys = await this.db.keys(`${this.collectionName}:*`);
131
- const items = await Promise.all(keys.map((key) => this.findById(key.split(":")[1])));
132
- return items.filter(Boolean);
169
+ const pipeline = this.db.pipeline();
170
+ keys.forEach((key) => {
171
+ pipeline.get(key);
172
+ });
173
+ const result = await pipeline.exec();
174
+ return (result || []).map(([, data]) => this.deserialize(JSON.parse(data))).filter(Boolean);
133
175
  }
134
176
  async findAllBy(props) {
135
177
  const keys = Object.keys(props);
136
- let foundKeys = await this.findKeys(props);
178
+ const foundKeys = await this.findKeys(props);
137
179
  if (foundKeys.length < keys.length) {
138
180
  return [];
139
181
  }
140
- const getId = (key) => key.split(":")[2];
141
182
  const map = foundKeys.reduce((map, key) => {
142
183
  const id = getId(key);
143
184
  const value = map.get(id) || 0;
@@ -147,9 +188,12 @@ export class RedisAdapter extends Adapter {
147
188
  const result = await Promise.all(promises);
148
189
  return result.filter(Boolean);
149
190
  }
150
- }
151
- __decorate([
152
- Inject(IoRedis),
153
- __metadata("design:type", Object)
154
- ], RedisAdapter.prototype, "db", void 0);
191
+ };
192
+ RedisAdapter = __decorate([
193
+ __param(0, Opts),
194
+ __param(1, Inject(IOREDIS_CONNECTIONS)),
195
+ __param(2, Configuration()),
196
+ __metadata("design:paramtypes", [Object, Array, Object])
197
+ ], RedisAdapter);
198
+ export { RedisAdapter };
155
199
  //# sourceMappingURL=RedisAdapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RedisAdapter.js","sourceRoot":"","sources":["../../../src/adapters/RedisAdapter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,OAAO,EAAe,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAC;AAChC,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAC,EAAE,IAAI,IAAI,EAAC,MAAM,MAAM,CAAC;AAChC,OAAO,0BAA0B,CAAC;AAElC,MAAM,OAAO,YAAqC,SAAQ,OAAU;IAEzD,EAAE,CAAQ;IAEnB,GAAG,CAAC,EAAU;QACZ,OAAO,GAAG,IAAI,CAAC,cAAc,IAAI,EAAE,EAAE,CAAC;IACxC,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,OAAmB,EAAE,SAAgB;QACvD,OAAO,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC;QAErB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,OAAU,EAAE,SAAgB;QAC1D,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAEnC,IAAI,CAAC,IAAI,EAAE;YACT,OAAO,GAAG,EAAC,GAAG,OAAO,EAAE,GAAG,EAAE,EAAE,EAAC,CAAC;YAEhC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;SACxC;QAED,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,CAAM,CAAC;IAC1D,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,OAAU,EAAE,SAAgB;QAC1D,OAAO,IAAI,CAAC,SAAS,CAAC,EAAC,GAAG,EAAE,EAAE,EAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACvD,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,SAA2B,EAAE,OAAU,EAAE,SAAgB;QAC9E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC,IAAI,EAAE;YACT,OAAO,SAAS,CAAC;SAClB;QAED,OAAO,IAAI,CAAC,MAAM,CAChB;YACE,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC;YACrC,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,EACD,SAAS,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAA2B;QACvC,MAAM,EAAC,GAAG,EAAE,GAAG,KAAK,EAAC,GAAG,SAAS,CAAC;QAElC,IAAI,GAAG,EAAE;YACP,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;SAC3B;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE3C,IAAI,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YAClC,OAAO,SAAS,CAAC;SAClB;QAED,MAAM,KAAK,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjD,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/B,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAEzD,OAAO,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAW;QACxB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAE9C,IAAI,CAAC,IAAI,EAAE;YACT,OAAO,SAAS,CAAC;SAClB;QAED,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5C,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,YAA8B,EAAE;QACnD,MAAM,EAAC,GAAG,EAAE,GAAG,KAAK,EAAC,GAAG,SAAS,CAAC;QAElC,IAAI,GAAG,EAAE;YACP,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3B;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEhC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;YACrB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;SACtB;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,SAA2B;QAChD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,IAAI,EAAE;YACR,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAElF,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SAC/B;IACH,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,GAAW;QACjC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAC,GAAG,EAAQ,CAAC,CAAC;IACtC,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,SAAqB;QAC3C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACxC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAElF,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAES,KAAK,CAAC,QAAQ,CAAC,KAAU;QACjC,MAAM,IAAI,GAAU,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO;aAC1B,MAAM,CAAC,CAAC,EAAC,WAAW,EAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;aACrD,GAAG,CAAC,CAAC,EAAC,WAAW,EAAC,EAAE,EAAE;YACrB,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;YACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;YAE7D,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEL,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE3C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,IAAc,EAAE,KAAe,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpG,CAAC;IAES,KAAK,CAAC,MAAM,CAAC,OAAmB,EAAE,SAAgB;QAC1D,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;QAEjD,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAEtE,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAY,CAAC,CAAC;QAElC,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEzB,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAE9D,IAAI,SAAS,EAAE;YACb,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;SAC9B;QAED,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAC,WAAW,EAAC,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;YACnC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;YAE9D,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAC1B,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAEnB,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAES,KAAK,CAAC,YAAY,CAAC,EAAU;QACrC,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAElD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAErC,OAAO,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9B,CAAC;IAES,aAAa,CAAC,EAAU,EAAE,WAAmB,EAAE,KAAU;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,WAAW,IAAI,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzE,CAAC;IAES,KAAK,CAAC,MAAM;QACpB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAErF,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAQ,CAAC;IACtC,CAAC;IAES,KAAK,CAAC,SAAS,CAAC,KAAuB;QAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE3C,IAAI,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YAClC,OAAO,EAAE,CAAC;SACX;QAED,MAAM,KAAK,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjD,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAwB,EAAE,GAAG,EAAE,EAAE;YAC7D,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YAE/B,OAAO,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAChC,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAEd,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;QAE9G,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE3C,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAQ,CAAC;IACvC,CAAC;CACF;AAjNC;IADC,MAAM,CAAC,OAAO,CAAC;;wCACG","sourcesContent":["import {Adapter, AdapterModel} from \"@tsed/adapters\";\nimport {Inject} from \"@tsed/di\";\nimport IoRedis from \"ioredis\";\nimport type {Redis} from \"ioredis\";\nimport {v4 as uuid} from \"uuid\";\nimport \"../services/RedisFactory\";\n\nexport class RedisAdapter<T extends AdapterModel> extends Adapter<T> {\n @Inject(IoRedis)\n readonly db: Redis;\n\n key(id: string) {\n return `${this.collectionName}:${id}`;\n }\n\n public async create(payload: Partial<T>, expiresAt?: Date): Promise<T> {\n payload._id = uuid();\n\n return this.insert(payload, expiresAt);\n }\n\n public async upsert(id: string, payload: T, expiresAt?: Date): Promise<T> {\n let item = await this.findById(id);\n\n if (!item) {\n payload = {...payload, _id: id};\n\n return this.insert(payload, expiresAt);\n }\n\n return (await this.update(id, payload, expiresAt)) as T;\n }\n\n public async update(id: string, payload: T, expiresAt?: Date): Promise<T | undefined> {\n return this.updateOne({_id: id}, payload, expiresAt);\n }\n\n public async updateOne(predicate: Partial<T & any>, payload: T, expiresAt?: Date): Promise<T | undefined> {\n const item = await this.findOne(predicate);\n\n if (!item) {\n return undefined;\n }\n\n return this.insert(\n {\n ...this.updateInstance(item, payload),\n _id: item._id\n },\n expiresAt\n );\n }\n\n async findOne(predicate: Partial<T & any>): Promise<T | undefined> {\n const {_id, ...props} = predicate;\n\n if (_id) {\n return this.findById(_id);\n }\n\n const keys = Object.keys(props);\n let foundKeys = await this.findKeys(props);\n\n if (foundKeys.length < keys.length) {\n return undefined;\n }\n\n const getId = (key: string) => key.split(\":\")[2];\n\n const id = getId(foundKeys[0]);\n\n foundKeys = foundKeys.filter((key) => id === getId(key));\n\n return keys.length === foundKeys.length ? this.findById(id) : undefined;\n }\n\n async findById(_id: string): Promise<T | undefined> {\n const item = await this.db.get(this.key(_id));\n\n if (!item) {\n return undefined;\n }\n\n return this.deserialize(JSON.parse(item));\n }\n\n public async findAll(predicate: Partial<T & any> = {}): Promise<T[]> {\n const {_id, ...props} = predicate;\n\n if (_id) {\n const item = await this.findById(_id);\n return item ? [item] : [];\n }\n\n const keys = Object.keys(props);\n\n if (keys.length === 0) {\n return this.getAll();\n }\n\n return this.findAllBy(props);\n }\n\n public async deleteOne(predicate: Partial<T & any>): Promise<T | undefined> {\n const item = await this.findOne(predicate);\n\n if (item) {\n await Promise.all([this.db.del(this.key(item._id)), this.cleanIndexes(item._id)]);\n\n return this.deserialize(item);\n }\n }\n\n public async deleteById(_id: string): Promise<T | undefined> {\n return this.deleteOne({_id} as any);\n }\n\n public async deleteMany(predicate: Partial<T>): Promise<T[]> {\n const items = await this.findAll(predicate);\n\n const promises = items.map(async (item) => {\n await Promise.all([this.db.del(this.key(item._id)), this.cleanIndexes(item._id)]);\n\n return this.deserialize(item);\n });\n\n return Promise.all(promises);\n }\n\n protected async findKeys(props: any): Promise<string[]> {\n const keys: any[] = Object.keys(props);\n\n const promises = this.indexes\n .filter(({propertyKey}) => keys.includes(propertyKey))\n .map(({propertyKey}) => {\n const value = props[propertyKey];\n const patterns = this.getIndexedKey(\"*\", propertyKey, value);\n\n return this.db.keys(patterns);\n });\n\n const result = await Promise.all(promises);\n\n return result.reduce((keys: string[], input: string[]) => keys.concat(input), []).filter(Boolean);\n }\n\n protected async insert(payload: Partial<T>, expiresAt?: Date) {\n const id = (payload._id = payload._id || uuid());\n\n const expiresIn = expiresAt ? expiresAt.getTime() - Date.now() : null;\n\n await this.validate(payload as T);\n\n const multi = this.db.multi();\n const key = this.key(id);\n\n await multi.set(key, JSON.stringify(this.serialize(payload)));\n\n if (expiresIn) {\n multi.expire(key, expiresIn);\n }\n\n this.indexes.forEach(({propertyKey}) => {\n const value = payload[propertyKey];\n const indexedKey = this.getIndexedKey(id, propertyKey, value);\n\n multi.set(indexedKey, id);\n expiresIn && multi.expire(indexedKey, expiresIn);\n });\n\n await multi.exec();\n\n return this.deserialize(payload);\n }\n\n protected async cleanIndexes(id: string) {\n const key = [\"$idx\", this.key(id), \"*\"].join(\":\");\n\n const keys = await this.db.keys(key);\n\n return this.db.del(...keys);\n }\n\n protected getIndexedKey(id: string, propertyKey: string, value: any): string {\n const key = this.key(id);\n return [\"$idx\", key, `${propertyKey}(${value})`].map(String).join(\":\");\n }\n\n protected async getAll(): Promise<T[]> {\n const keys = await this.db.keys(`${this.collectionName}:*`);\n const items = await Promise.all(keys.map((key) => this.findById(key.split(\":\")[1])));\n\n return items.filter(Boolean) as T[];\n }\n\n protected async findAllBy(props: Partial<T & any>): Promise<T[]> {\n const keys = Object.keys(props);\n let foundKeys = await this.findKeys(props);\n\n if (foundKeys.length < keys.length) {\n return [];\n }\n\n const getId = (key: string) => key.split(\":\")[2];\n\n const map = foundKeys.reduce((map: Map<string, number>, key) => {\n const id = getId(key);\n const value = map.get(id) || 0;\n\n return map.set(id, value + 1);\n }, new Map());\n\n const promises = [...map.entries()].filter(([, num]) => num === keys.length).map(([id]) => this.findById(id));\n\n const result = await Promise.all(promises);\n\n return result.filter(Boolean) as T[];\n }\n}\n"]}
1
+ {"version":3,"file":"RedisAdapter.js","sourceRoot":"","sources":["../../../src/adapters/RedisAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import {Adapter, AdapterConstructorOptions, AdapterModel} from \"@tsed/adapters\";\nimport {cleanObject, Hooks, isString} from \"@tsed/core\";\nimport {Configuration, Inject, Opts} from \"@tsed/di\";\nimport {IORedis, IOREDIS_CONNECTIONS} from \"@tsed/ioredis\";\nimport type {ChainableCommander, Redis} from \"ioredis\";\nimport {v4 as uuid} from \"uuid\";\n\nconst getId = (key: string) => key.split(\":\")[2];\nconst flatKeys = (keys: [Error | null, string[]][]): string[] => {\n return keys.flatMap(([, result]) => result).filter(Boolean);\n};\n\nexport interface RedisAdapterConstructorOptions extends AdapterConstructorOptions {\n connectionName?: string;\n useHash?: boolean;\n}\n\nexport class RedisAdapter<Model extends AdapterModel> extends Adapter<Model> {\n readonly hooks = new Hooks();\n readonly connectionName: string;\n readonly connection: IORedis;\n protected useHash: boolean = false;\n\n constructor(\n @Opts options: RedisAdapterConstructorOptions,\n @Inject(IOREDIS_CONNECTIONS) connections: IORedis[],\n @Configuration() protected configuration: Configuration\n ) {\n super(options, configuration);\n\n this.useHash = Boolean(options.useHash);\n this.connectionName = options.connectionName || \"default\";\n this.connection = connections.find((connection) => connection.name === this.connectionName)!; // || connections[0];\n }\n\n get db(): Redis {\n return this.connection;\n }\n\n key(id: string) {\n return `${this.collectionName}:${id}`;\n }\n\n public async create(payload: Partial<Model>, expiresAt?: Date): Promise<Model> {\n delete payload._id;\n return this.insert(payload, expiresAt);\n }\n\n public async upsert(id: string, payload: Model, expiresAt?: Date): Promise<Model> {\n const item = await this.findById(id);\n\n if (!item) {\n payload = {...payload, _id: id};\n\n return await this.insert(payload, expiresAt);\n }\n\n return (await this.update(id, payload, expiresAt)) as Model;\n }\n\n public async update(id: string, payload: Model, expiresAt?: Date): Promise<Model | undefined> {\n return this.updateOne({_id: id}, payload, expiresAt);\n }\n\n public async updateOne(predicate: Partial<Model & any>, payload: Model, expiresAt?: Date): Promise<Model | undefined> {\n const item = await this.findOne(predicate);\n\n if (!item) {\n return undefined;\n }\n\n return this.insert(\n {\n ...item,\n ...cleanObject(payload),\n _id: item._id\n },\n expiresAt\n );\n }\n\n async findOne(predicate: Partial<Model & any>): Promise<Model | undefined> {\n const {_id, ...props} = predicate;\n\n if (_id) {\n return this.findById(_id);\n }\n\n const keys = Object.keys(props);\n let foundKeys = await this.findKeys(props);\n\n if (foundKeys.length < keys.length) {\n return undefined;\n }\n\n const getId = (key: string) => key.split(\":\")[2];\n const id = getId(foundKeys[0]);\n\n foundKeys = foundKeys.filter((key) => id === getId(key));\n\n return keys.length === foundKeys.length ? this.findById(id) : undefined;\n }\n\n async findById(_id: string): Promise<Model | undefined> {\n const key = this.key(_id);\n\n const item = this.useHash ? await this.db.hgetall(key) : await this.db.get(key);\n\n if (!item) {\n return undefined;\n }\n\n if (isString(item)) {\n return this.deserialize(JSON.parse(item));\n }\n\n const {payload, ...rest} = item;\n\n return {\n ...rest,\n ...(payload ? JSON.parse(payload) : {})\n };\n }\n\n public async findAll(predicate: Partial<Model & any> = {}): Promise<Model[]> {\n const {_id, ...props} = predicate;\n\n if (_id) {\n const item = await this.findById(_id);\n return item ? [item] : [];\n }\n\n const keys = Object.keys(props);\n\n if (keys.length === 0) {\n return this.getAll();\n }\n\n return this.findAllBy(props);\n }\n\n public async deleteOne(predicate: Partial<Model & any>): Promise<Model | undefined> {\n const item = await this.findOne(predicate);\n\n if (item) {\n const id = this.key(item._id);\n const indexIds = await this.getAllIndex(item._id);\n\n await this.db.del([id, ...indexIds]);\n\n return this.deserialize(item);\n }\n }\n\n public async deleteById(_id: string): Promise<Model | undefined> {\n return this.deleteOne({_id} as any);\n }\n\n public async deleteMany(predicate: Partial<Model>): Promise<Model[]> {\n const items = await this.findAll(predicate);\n\n const pipeline = this.db.pipeline();\n const ids: string[] = [];\n\n const results = items.map((item) => {\n ids.push(this.key(item._id));\n\n this.getAllIndex(item._id, pipeline);\n\n return this.deserialize(item);\n });\n\n const keys = await pipeline.exec();\n\n this.db.del([...ids, ...flatKeys(keys as any)]);\n\n return results;\n }\n\n protected async findKeys(props: any): Promise<string[]> {\n const keys: any[] = Object.keys(props);\n const pipeline = this.db.pipeline();\n\n this.indexes\n .filter(({propertyKey}) => keys.includes(propertyKey))\n .forEach(({propertyKey}) => {\n const value = props[propertyKey];\n const patterns = this.getIndexedKey(\"*\", propertyKey, value);\n\n pipeline.keys(patterns);\n });\n\n const results = await pipeline.exec();\n\n return flatKeys(results as any[]);\n }\n\n protected async insert(payload: Partial<Model>, expiresAt?: Date) {\n const id = (payload._id = payload._id || uuid());\n\n const expiresIn = expiresAt ? expiresAt.getTime() - Date.now() : null;\n\n await this.validate(payload as Model);\n\n const multi = this.db.multi();\n const key = this.key(id);\n\n const strPayload = JSON.stringify(this.serialize(payload));\n\n this.useHash ? await multi.hset(key, {payload: strPayload}) : await multi.set(key, strPayload);\n\n if (expiresIn) {\n multi.expire(key, expiresIn);\n }\n\n this.indexes.forEach(({propertyKey}) => {\n const value = payload[propertyKey];\n const indexedKey = this.getIndexedKey(id, propertyKey, value);\n\n multi.set(indexedKey, id);\n expiresIn && multi.expire(indexedKey, expiresIn);\n });\n\n await this.hooks.asyncAlter(\"insert\", multi, [payload, expiresIn]);\n\n await multi.exec();\n\n const result = this.deserialize(payload, {useAlias: false});\n\n await this.hooks.asyncEmit(\"afterInsert\", [result]);\n\n return result;\n }\n\n protected getAllIndex(id: string): Promise<string[]>;\n protected getAllIndex(id: string, pipeline: ChainableCommander): ChainableCommander;\n protected getAllIndex(id: string, pipeline?: ChainableCommander) {\n const key = [\"$idx\", this.key(id), \"*\"].join(\":\");\n\n return (pipeline || this.db).keys(key);\n }\n\n protected getIndexedKey(id: string, propertyKey: string, value: any): string {\n const key = this.key(id);\n return [\"$idx\", key, `${propertyKey}(${value})`].map(String).join(\":\");\n }\n\n protected async getAll(): Promise<Model[]> {\n const keys = await this.db.keys(`${this.collectionName}:*`);\n const pipeline = this.db.pipeline();\n\n keys.forEach((key) => {\n pipeline.get(key);\n });\n\n const result = await pipeline.exec();\n return (result || []).map(([, data]: [any, string]) => this.deserialize(JSON.parse(data))).filter(Boolean);\n }\n\n protected async findAllBy(props: Partial<Model & any>): Promise<Model[]> {\n const keys = Object.keys(props);\n const foundKeys = await this.findKeys(props);\n\n if (foundKeys.length < keys.length) {\n return [];\n }\n\n const map = foundKeys.reduce((map: Map<string, number>, key) => {\n const id = getId(key);\n const value = map.get(id) || 0;\n\n return map.set(id, value + 1);\n }, new Map());\n\n const promises = [...map.entries()].filter(([, num]) => num === keys.length).map(([id]) => this.findById(id));\n\n const result = await Promise.all(promises);\n\n return result.filter(Boolean) as Model[];\n }\n}\n"]}
package/lib/esm/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file Automatically generated by barrelsby.
3
3
  */
4
+ export * from "./adapters/OIDCRedisAdapter.js";
4
5
  export * from "./adapters/RedisAdapter.js";
5
6
  export * from "./domain/RedisAdaptersSettings.js";
6
- export * from "./services/RedisFactory.js";
7
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./adapters/RedisAdapter\";\nexport * from \"./domain/RedisAdaptersSettings\";\nexport * from \"./services/RedisFactory\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./adapters/OIDCRedisAdapter\";\nexport * from \"./adapters/RedisAdapter\";\nexport * from \"./domain/RedisAdaptersSettings\";\n"]}
@@ -0,0 +1,16 @@
1
+ import { AdapterModel } from "@tsed/adapters";
2
+ import { Configuration } from "@tsed/di";
3
+ import { ChainableCommander } from "ioredis";
4
+ import { IORedis } from "@tsed/ioredis";
5
+ import { RedisAdapter, RedisAdapterConstructorOptions } from "./RedisAdapter";
6
+ export declare class OIDCRedisAdapter<T extends AdapterModel> extends RedisAdapter<T> {
7
+ protected configuration: Configuration;
8
+ protected isGrantable: boolean;
9
+ constructor(options: RedisAdapterConstructorOptions, connections: IORedis[], configuration: Configuration);
10
+ onInsert(multi: ChainableCommander, payload: T, expiresIn: number): Promise<ChainableCommander>;
11
+ findByUid(uid: string): Promise<"" | T | null | undefined>;
12
+ findByUserCode(userCode: string): Promise<"" | T | null | undefined>;
13
+ destroy(id: string): Promise<void>;
14
+ revokeByGrantId(grantId: string): Promise<void>;
15
+ consume(id: string): Promise<void>;
16
+ }
@@ -1,23 +1,36 @@
1
- import { Adapter, AdapterModel } from "@tsed/adapters";
2
- import type { Redis } from "ioredis";
3
- import "../services/RedisFactory";
4
- export declare class RedisAdapter<T extends AdapterModel> extends Adapter<T> {
5
- readonly db: Redis;
1
+ import { Adapter, AdapterConstructorOptions, AdapterModel } from "@tsed/adapters";
2
+ import { Hooks } from "@tsed/core";
3
+ import { Configuration } from "@tsed/di";
4
+ import { IORedis } from "@tsed/ioredis";
5
+ import type { ChainableCommander, Redis } from "ioredis";
6
+ export interface RedisAdapterConstructorOptions extends AdapterConstructorOptions {
7
+ connectionName?: string;
8
+ useHash?: boolean;
9
+ }
10
+ export declare class RedisAdapter<Model extends AdapterModel> extends Adapter<Model> {
11
+ protected configuration: Configuration;
12
+ readonly hooks: Hooks;
13
+ readonly connectionName: string;
14
+ readonly connection: IORedis;
15
+ protected useHash: boolean;
16
+ constructor(options: RedisAdapterConstructorOptions, connections: IORedis[], configuration: Configuration);
17
+ get db(): Redis;
6
18
  key(id: string): string;
7
- create(payload: Partial<T>, expiresAt?: Date): Promise<T>;
8
- upsert(id: string, payload: T, expiresAt?: Date): Promise<T>;
9
- update(id: string, payload: T, expiresAt?: Date): Promise<T | undefined>;
10
- updateOne(predicate: Partial<T & any>, payload: T, expiresAt?: Date): Promise<T | undefined>;
11
- findOne(predicate: Partial<T & any>): Promise<T | undefined>;
12
- findById(_id: string): Promise<T | undefined>;
13
- findAll(predicate?: Partial<T & any>): Promise<T[]>;
14
- deleteOne(predicate: Partial<T & any>): Promise<T | undefined>;
15
- deleteById(_id: string): Promise<T | undefined>;
16
- deleteMany(predicate: Partial<T>): Promise<T[]>;
19
+ create(payload: Partial<Model>, expiresAt?: Date): Promise<Model>;
20
+ upsert(id: string, payload: Model, expiresAt?: Date): Promise<Model>;
21
+ update(id: string, payload: Model, expiresAt?: Date): Promise<Model | undefined>;
22
+ updateOne(predicate: Partial<Model & any>, payload: Model, expiresAt?: Date): Promise<Model | undefined>;
23
+ findOne(predicate: Partial<Model & any>): Promise<Model | undefined>;
24
+ findById(_id: string): Promise<Model | undefined>;
25
+ findAll(predicate?: Partial<Model & any>): Promise<Model[]>;
26
+ deleteOne(predicate: Partial<Model & any>): Promise<Model | undefined>;
27
+ deleteById(_id: string): Promise<Model | undefined>;
28
+ deleteMany(predicate: Partial<Model>): Promise<Model[]>;
17
29
  protected findKeys(props: any): Promise<string[]>;
18
- protected insert(payload: Partial<T>, expiresAt?: Date): Promise<any>;
19
- protected cleanIndexes(id: string): Promise<number>;
30
+ protected insert(payload: Partial<Model>, expiresAt?: Date): Promise<any>;
31
+ protected getAllIndex(id: string): Promise<string[]>;
32
+ protected getAllIndex(id: string, pipeline: ChainableCommander): ChainableCommander;
20
33
  protected getIndexedKey(id: string, propertyKey: string, value: any): string;
21
- protected getAll(): Promise<T[]>;
22
- protected findAllBy(props: Partial<T & any>): Promise<T[]>;
34
+ protected getAll(): Promise<Model[]>;
35
+ protected findAllBy(props: Partial<Model & any>): Promise<Model[]>;
23
36
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file Automatically generated by barrelsby.
3
3
  */
4
+ export * from "./adapters/OIDCRedisAdapter";
4
5
  export * from "./adapters/RedisAdapter";
5
6
  export * from "./domain/RedisAdaptersSettings";
6
- export * from "./services/RedisFactory";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsed/adapters-redis",
3
- "version": "7.0.0-rc.2",
3
+ "version": "7.0.0-rc.5",
4
4
  "description": "Redis adapter for Ts.ED",
5
5
  "private": false,
6
6
  "source": "./src/index.ts",
@@ -21,23 +21,20 @@
21
21
  "test": "cross-env NODE_ENV=test yarn jest"
22
22
  },
23
23
  "dependencies": {
24
- "@tsed/adapters": "7.0.0-rc.2",
24
+ "@tsed/adapters": "7.0.0-rc.5",
25
+ "@tsed/ioredis": "7.0.0-rc.5",
25
26
  "tslib": "2.4.0"
26
27
  },
27
28
  "devDependencies": {
28
- "@tsed/core": "7.0.0-rc.2",
29
- "@types/ioredis": "4.28.10",
30
- "@types/ioredis-mock": "5.6.0",
31
- "ioredis": "4.28.5",
32
- "ioredis-mock": "7.2.0"
29
+ "@tsed/core": "7.0.0-rc.5"
33
30
  },
34
31
  "peerDependencies": {
35
- "@tsed/adapters": "^7.0.0-rc.2",
36
- "@tsed/common": "^7.0.0-rc.2",
37
- "@tsed/core": "^7.0.0-rc.2",
38
- "@tsed/di": "^7.0.0-rc.2",
39
- "ioredis": "^4.19.4",
40
- "ioredis-mock": "^5.2.0",
32
+ "@tsed/adapters": "^7.0.0-rc.5",
33
+ "@tsed/common": "^7.0.0-rc.5",
34
+ "@tsed/core": "^7.0.0-rc.5",
35
+ "@tsed/di": "^7.0.0-rc.5",
36
+ "ioredis": ">=5.2.3",
37
+ "ioredis-mock": ">=8.2.2",
41
38
  "uuid": "8.3.2"
42
39
  },
43
40
  "repository": "https://github.com/tsedio/tsed",
package/readme.md CHANGED
@@ -32,9 +32,9 @@ A package of Ts.ED framework. See website: https://tsed.io/tutorials/adapters
32
32
 
33
33
  ## Contributors
34
34
 
35
- Please read [contributing guidelines here](https://tsed.io/CONTRIBUTING.html)
35
+ Please read [contributing guidelines here](https://tsed.io/contributing.html)
36
36
 
37
- <a href="https://github.com/tsedio/ts-express-decorators/graphs/contributors"><img src="https://opencollective.com/tsed/contributors.svg?width=890" /></a>
37
+ <a href="https://github.com/tsedio/tsed/graphs/contributors"><img src="https://opencollective.com/tsed/contributors.svg?width=890" /></a>
38
38
 
39
39
  ## Backers
40
40
 
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const di_1 = require("@tsed/di");
5
- const ioredis_1 = tslib_1.__importDefault(require("ioredis"));
6
- (0, di_1.registerProvider)({
7
- provide: ioredis_1.default,
8
- deps: [di_1.Configuration],
9
- useFactory(configuration) {
10
- const options = configuration.get("adapters.redis");
11
- // istanbul ignore next
12
- if (options) {
13
- return new ioredis_1.default(options);
14
- }
15
- return {};
16
- }
17
- });
18
- //# sourceMappingURL=RedisFactory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RedisFactory.js","sourceRoot":"","sources":["../../../src/services/RedisFactory.ts"],"names":[],"mappings":";;;AAAA,iCAAyD;AACzD,8DAA8C;AAE9C,IAAA,qBAAgB,EAAC;IACf,OAAO,EAAE,iBAAO;IAChB,IAAI,EAAE,CAAC,kBAAa,CAAC;IACrB,UAAU,CAAC,aAA4B;QACrC,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAe,gBAAgB,CAAC,CAAC;QAElE,uBAAuB;QACvB,IAAI,OAAO,EAAE;YACX,OAAO,IAAI,iBAAO,CAAC,OAAO,CAAC,CAAC;SAC7B;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import {Configuration, registerProvider} from \"@tsed/di\";\nimport IoRedis, {RedisOptions} from \"ioredis\";\n\nregisterProvider({\n provide: IoRedis,\n deps: [Configuration],\n useFactory(configuration: Configuration) {\n const options = configuration.get<RedisOptions>(\"adapters.redis\");\n\n // istanbul ignore next\n if (options) {\n return new IoRedis(options);\n }\n\n return {};\n }\n});\n"]}
@@ -1,15 +0,0 @@
1
- import { Configuration, registerProvider } from "@tsed/di";
2
- import IoRedis from "ioredis";
3
- registerProvider({
4
- provide: IoRedis,
5
- deps: [Configuration],
6
- useFactory(configuration) {
7
- const options = configuration.get("adapters.redis");
8
- // istanbul ignore next
9
- if (options) {
10
- return new IoRedis(options);
11
- }
12
- return {};
13
- }
14
- });
15
- //# sourceMappingURL=RedisFactory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RedisFactory.js","sourceRoot":"","sources":["../../../src/services/RedisFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,gBAAgB,EAAC,MAAM,UAAU,CAAC;AACzD,OAAO,OAAuB,MAAM,SAAS,CAAC;AAE9C,gBAAgB,CAAC;IACf,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE,CAAC,aAAa,CAAC;IACrB,UAAU,CAAC,aAA4B;QACrC,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAe,gBAAgB,CAAC,CAAC;QAElE,uBAAuB;QACvB,IAAI,OAAO,EAAE;YACX,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;SAC7B;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import {Configuration, registerProvider} from \"@tsed/di\";\nimport IoRedis, {RedisOptions} from \"ioredis\";\n\nregisterProvider({\n provide: IoRedis,\n deps: [Configuration],\n useFactory(configuration: Configuration) {\n const options = configuration.get<RedisOptions>(\"adapters.redis\");\n\n // istanbul ignore next\n if (options) {\n return new IoRedis(options);\n }\n\n return {};\n }\n});\n"]}
@@ -1 +0,0 @@
1
- export {};