@tsed/adapters-redis 6.128.10 → 6.131.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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"]}
@@ -5,11 +5,28 @@ const tslib_1 = require("tslib");
5
5
  const adapters_1 = require("@tsed/adapters");
6
6
  const core_1 = require("@tsed/core");
7
7
  const di_1 = require("@tsed/di");
8
- const ioredis_1 = tslib_1.__importDefault(require("ioredis"));
8
+ const ioredis_1 = require("@tsed/ioredis");
9
9
  const uuid_1 = require("uuid");
10
- require("../services/RedisFactory");
11
- class RedisAdapter extends adapters_1.Adapter {
12
- 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
+ }
13
30
  key(id) {
14
31
  return `${this.collectionName}:${id}`;
15
32
  }
@@ -18,10 +35,10 @@ class RedisAdapter extends adapters_1.Adapter {
18
35
  return this.insert(payload, expiresAt);
19
36
  }
20
37
  async upsert(id, payload, expiresAt) {
21
- let item = await this.findById(id);
38
+ const item = await this.findById(id);
22
39
  if (!item) {
23
40
  payload = { ...payload, _id: id };
24
- return this.insert(payload, expiresAt);
41
+ return await this.insert(payload, expiresAt);
25
42
  }
26
43
  return (await this.update(id, payload, expiresAt));
27
44
  }
@@ -55,11 +72,19 @@ class RedisAdapter extends adapters_1.Adapter {
55
72
  return keys.length === foundKeys.length ? this.findById(id) : undefined;
56
73
  }
57
74
  async findById(_id) {
58
- 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);
59
77
  if (!item) {
60
78
  return undefined;
61
79
  }
62
- 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
+ };
63
88
  }
64
89
  async findAll(predicate = {}) {
65
90
  const { _id, ...props } = predicate;
@@ -76,7 +101,9 @@ class RedisAdapter extends adapters_1.Adapter {
76
101
  async deleteOne(predicate) {
77
102
  const item = await this.findOne(predicate);
78
103
  if (item) {
79
- 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]);
80
107
  return this.deserialize(item);
81
108
  }
82
109
  }
@@ -85,23 +112,29 @@ class RedisAdapter extends adapters_1.Adapter {
85
112
  }
86
113
  async deleteMany(predicate) {
87
114
  const items = await this.findAll(predicate);
88
- const promises = items.map(async (item) => {
89
- 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);
90
120
  return this.deserialize(item);
91
121
  });
92
- return Promise.all(promises);
122
+ const keys = await pipeline.exec();
123
+ this.db.del([...ids, ...flatKeys(keys)]);
124
+ return results;
93
125
  }
94
126
  async findKeys(props) {
95
127
  const keys = Object.keys(props);
96
- const promises = this.indexes
128
+ const pipeline = this.db.pipeline();
129
+ this.indexes
97
130
  .filter(({ propertyKey }) => keys.includes(propertyKey))
98
- .map(({ propertyKey }) => {
131
+ .forEach(({ propertyKey }) => {
99
132
  const value = props[propertyKey];
100
133
  const patterns = this.getIndexedKey("*", propertyKey, value);
101
- return this.db.keys(patterns);
134
+ pipeline.keys(patterns);
102
135
  });
103
- const result = await Promise.all(promises);
104
- return result.reduce((keys, input) => keys.concat(input), []).filter(Boolean);
136
+ const results = await pipeline.exec();
137
+ return flatKeys(results);
105
138
  }
106
139
  async insert(payload, expiresAt) {
107
140
  const id = (payload._id = payload._id || (0, uuid_1.v4)());
@@ -109,7 +142,8 @@ class RedisAdapter extends adapters_1.Adapter {
109
142
  await this.validate(payload);
110
143
  const multi = this.db.multi();
111
144
  const key = this.key(id);
112
- 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);
113
147
  if (expiresIn) {
114
148
  multi.expire(key, expiresIn);
115
149
  }
@@ -119,13 +153,15 @@ class RedisAdapter extends adapters_1.Adapter {
119
153
  multi.set(indexedKey, id);
120
154
  expiresIn && multi.expire(indexedKey, expiresIn);
121
155
  });
156
+ await this.hooks.asyncAlter("insert", multi, [payload, expiresIn]);
122
157
  await multi.exec();
123
- return this.deserialize(payload);
158
+ const result = this.deserialize(payload, { useAlias: false });
159
+ await this.hooks.asyncEmit("afterInsert", [result]);
160
+ return result;
124
161
  }
125
- async cleanIndexes(id) {
162
+ getAllIndex(id, pipeline) {
126
163
  const key = ["$idx", this.key(id), "*"].join(":");
127
- const keys = await this.db.keys(key);
128
- return this.db.del(...keys);
164
+ return (pipeline || this.db).keys(key);
129
165
  }
130
166
  getIndexedKey(id, propertyKey, value) {
131
167
  const key = this.key(id);
@@ -133,16 +169,19 @@ class RedisAdapter extends adapters_1.Adapter {
133
169
  }
134
170
  async getAll() {
135
171
  const keys = await this.db.keys(`${this.collectionName}:*`);
136
- const items = await Promise.all(keys.map((key) => this.findById(key.split(":")[1])));
137
- 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);
138
178
  }
139
179
  async findAllBy(props) {
140
180
  const keys = Object.keys(props);
141
- let foundKeys = await this.findKeys(props);
181
+ const foundKeys = await this.findKeys(props);
142
182
  if (foundKeys.length < keys.length) {
143
183
  return [];
144
184
  }
145
- const getId = (key) => key.split(":")[2];
146
185
  const map = foundKeys.reduce((map, key) => {
147
186
  const id = getId(key);
148
187
  const value = map.get(id) || 0;
@@ -152,10 +191,12 @@ class RedisAdapter extends adapters_1.Adapter {
152
191
  const result = await Promise.all(promises);
153
192
  return result.filter(Boolean);
154
193
  }
155
- }
156
- tslib_1.__decorate([
157
- (0, di_1.Inject)(ioredis_1.default),
158
- tslib_1.__metadata("design:type", Object)
159
- ], 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);
160
201
  exports.RedisAdapter = RedisAdapter;
161
202
  //# sourceMappingURL=RedisAdapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RedisAdapter.js","sourceRoot":"","sources":["../../../src/adapters/RedisAdapter.ts"],"names":[],"mappings":";;;;AAAA,6CAAqD;AACrD,qCAAuC;AACvC,iCAAgC;AAChC,8DAA8B;AAE9B,+BAAgC;AAChC,oCAAkC;AAElC,MAAa,YAAqC,SAAQ,kBAAU;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,OAAO,CAAC,GAAG,CAAC;QAEnB,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;YACP,GAAG,IAAA,kBAAW,EAAC,OAAO,CAAC;YACvB,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,IAAA,SAAI,GAAE,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;AAlNC;IADC,IAAA,WAAM,EAAC,iBAAO,CAAC;;wCACG;AAFrB,oCAoNC","sourcesContent":["import {Adapter, AdapterModel} from \"@tsed/adapters\";\nimport {cleanObject} from \"@tsed/core\";\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 delete payload._id;\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 ...item,\n ...cleanObject(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":";;;;AAAA,6CAAgF;AAChF,qCAAwD;AACxD,iCAAqD;AACrD,2CAA2D;AAE3D,+BAAgC;AAEhC,MAAM,KAAK,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,MAAM,QAAQ,GAAG,CAAC,IAAgC,EAAY,EAAE;IAC9D,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC9D,CAAC,CAAC;AAOF,IAAa,YAAY,GAAzB,MAAa,YAAyC,SAAQ,kBAAc;IAS7C;IARpB,KAAK,GAAG,IAAI,YAAK,EAAE,CAAC;IACpB,cAAc,CAAS;IACvB,UAAU,CAAU;IACnB,OAAO,GAAY,KAAK,CAAC;IAEnC,YACQ,OAAuC,EAChB,WAAsB,EACxB,aAA4B;QAEvD,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QAFH,kBAAa,GAAb,aAAa,CAAe;QAIvD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,SAAS,CAAC;QAC1D,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,cAAc,CAAE,CAAC,CAAC,qBAAqB;IACrH,CAAC;IAED,IAAI,EAAE;QACJ,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,GAAG,IAAI,CAAC,cAAc,IAAI,EAAE,EAAE,CAAC;IACxC,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,OAAuB,EAAE,SAAgB;QAC3D,OAAO,OAAO,CAAC,GAAG,CAAC;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,OAAc,EAAE,SAAgB;QAC9D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAErC,IAAI,CAAC,IAAI,EAAE;YACT,OAAO,GAAG,EAAC,GAAG,OAAO,EAAE,GAAG,EAAE,EAAE,EAAC,CAAC;YAEhC,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;SAC9C;QAED,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,CAAU,CAAC;IAC9D,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,OAAc,EAAE,SAAgB;QAC9D,OAAO,IAAI,CAAC,SAAS,CAAC,EAAC,GAAG,EAAE,EAAE,EAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACvD,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,SAA+B,EAAE,OAAc,EAAE,SAAgB;QACtF,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;YACP,GAAG,IAAA,kBAAW,EAAC,OAAO,CAAC;YACvB,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,EACD,SAAS,CACV,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAA+B;QAC3C,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;QACjD,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,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEhF,IAAI,CAAC,IAAI,EAAE;YACT,OAAO,SAAS,CAAC;SAClB;QAED,IAAI,IAAA,eAAQ,EAAC,IAAI,CAAC,EAAE;YAClB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;SAC3C;QAED,MAAM,EAAC,OAAO,EAAE,GAAG,IAAI,EAAC,GAAG,IAAI,CAAC;QAEhC,OAAO;YACL,GAAG,IAAI;YACP,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,YAAkC,EAAE;QACvD,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,SAA+B;QACpD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,IAAI,EAAE;YACR,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAElD,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;YAErC,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,SAAyB;QAC/C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,GAAG,GAAa,EAAE,CAAC;QAEzB,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACjC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAE7B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YAErC,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,QAAQ,CAAC,IAAW,CAAC,CAAC,CAAC,CAAC;QAEhD,OAAO,OAAO,CAAC;IACjB,CAAC;IAES,KAAK,CAAC,QAAQ,CAAC,KAAU;QACjC,MAAM,IAAI,GAAU,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;QAEpC,IAAI,CAAC,OAAO;aACT,MAAM,CAAC,CAAC,EAAC,WAAW,EAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;aACrD,OAAO,CAAC,CAAC,EAAC,WAAW,EAAC,EAAE,EAAE;YACzB,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;YACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;YAE7D,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEL,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEtC,OAAO,QAAQ,CAAC,OAAgB,CAAC,CAAC;IACpC,CAAC;IAES,KAAK,CAAC,MAAM,CAAC,OAAuB,EAAE,SAAgB;QAC9D,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAA,SAAI,GAAE,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,OAAgB,CAAC,CAAC;QAEtC,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEzB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QAE3D,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,EAAC,OAAO,EAAE,UAAU,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAE/F,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,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;QAEnE,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAEnB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,EAAC,QAAQ,EAAE,KAAK,EAAC,CAAC,CAAC;QAE5D,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAEpD,OAAO,MAAM,CAAC;IAChB,CAAC;IAIS,WAAW,CAAC,EAAU,EAAE,QAA6B;QAC7D,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAElD,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,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,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;QAEpC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACnB,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAgB,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7G,CAAC;IAES,KAAK,CAAC,SAAS,CAAC,KAA2B;QACnD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE7C,IAAI,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YAClC,OAAO,EAAE,CAAC;SACX;QAED,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,CAAY,CAAC;IAC3C,CAAC;CACF,CAAA;AAvQY,YAAY;IAOpB,mBAAA,SAAI,CAAA;IACJ,mBAAA,IAAA,WAAM,EAAC,6BAAmB,CAAC,CAAA;IAC3B,mBAAA,IAAA,kBAAa,GAAE,CAAA;;GATP,YAAY,CAuQxB;AAvQY,oCAAY","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,12 +1,29 @@
1
- import { __decorate, __metadata } from "tslib";
1
+ import { __decorate, __metadata, __param } from "tslib";
2
2
  import { Adapter } from "@tsed/adapters";
3
- import { cleanObject } from "@tsed/core";
4
- import { Inject } from "@tsed/di";
5
- 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";
6
6
  import { v4 as uuid } from "uuid";
7
- import "../services/RedisFactory.js";
8
- export class RedisAdapter extends Adapter {
9
- 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
+ }
10
27
  key(id) {
11
28
  return `${this.collectionName}:${id}`;
12
29
  }
@@ -15,10 +32,10 @@ export class RedisAdapter extends Adapter {
15
32
  return this.insert(payload, expiresAt);
16
33
  }
17
34
  async upsert(id, payload, expiresAt) {
18
- let item = await this.findById(id);
35
+ const item = await this.findById(id);
19
36
  if (!item) {
20
37
  payload = { ...payload, _id: id };
21
- return this.insert(payload, expiresAt);
38
+ return await this.insert(payload, expiresAt);
22
39
  }
23
40
  return (await this.update(id, payload, expiresAt));
24
41
  }
@@ -52,11 +69,19 @@ export class RedisAdapter extends Adapter {
52
69
  return keys.length === foundKeys.length ? this.findById(id) : undefined;
53
70
  }
54
71
  async findById(_id) {
55
- 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);
56
74
  if (!item) {
57
75
  return undefined;
58
76
  }
59
- 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
+ };
60
85
  }
61
86
  async findAll(predicate = {}) {
62
87
  const { _id, ...props } = predicate;
@@ -73,7 +98,9 @@ export class RedisAdapter extends Adapter {
73
98
  async deleteOne(predicate) {
74
99
  const item = await this.findOne(predicate);
75
100
  if (item) {
76
- 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]);
77
104
  return this.deserialize(item);
78
105
  }
79
106
  }
@@ -82,23 +109,29 @@ export class RedisAdapter extends Adapter {
82
109
  }
83
110
  async deleteMany(predicate) {
84
111
  const items = await this.findAll(predicate);
85
- const promises = items.map(async (item) => {
86
- 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);
87
117
  return this.deserialize(item);
88
118
  });
89
- return Promise.all(promises);
119
+ const keys = await pipeline.exec();
120
+ this.db.del([...ids, ...flatKeys(keys)]);
121
+ return results;
90
122
  }
91
123
  async findKeys(props) {
92
124
  const keys = Object.keys(props);
93
- const promises = this.indexes
125
+ const pipeline = this.db.pipeline();
126
+ this.indexes
94
127
  .filter(({ propertyKey }) => keys.includes(propertyKey))
95
- .map(({ propertyKey }) => {
128
+ .forEach(({ propertyKey }) => {
96
129
  const value = props[propertyKey];
97
130
  const patterns = this.getIndexedKey("*", propertyKey, value);
98
- return this.db.keys(patterns);
131
+ pipeline.keys(patterns);
99
132
  });
100
- const result = await Promise.all(promises);
101
- return result.reduce((keys, input) => keys.concat(input), []).filter(Boolean);
133
+ const results = await pipeline.exec();
134
+ return flatKeys(results);
102
135
  }
103
136
  async insert(payload, expiresAt) {
104
137
  const id = (payload._id = payload._id || uuid());
@@ -106,7 +139,8 @@ export class RedisAdapter extends Adapter {
106
139
  await this.validate(payload);
107
140
  const multi = this.db.multi();
108
141
  const key = this.key(id);
109
- 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);
110
144
  if (expiresIn) {
111
145
  multi.expire(key, expiresIn);
112
146
  }
@@ -116,13 +150,15 @@ export class RedisAdapter extends Adapter {
116
150
  multi.set(indexedKey, id);
117
151
  expiresIn && multi.expire(indexedKey, expiresIn);
118
152
  });
153
+ await this.hooks.asyncAlter("insert", multi, [payload, expiresIn]);
119
154
  await multi.exec();
120
- return this.deserialize(payload);
155
+ const result = this.deserialize(payload, { useAlias: false });
156
+ await this.hooks.asyncEmit("afterInsert", [result]);
157
+ return result;
121
158
  }
122
- async cleanIndexes(id) {
159
+ getAllIndex(id, pipeline) {
123
160
  const key = ["$idx", this.key(id), "*"].join(":");
124
- const keys = await this.db.keys(key);
125
- return this.db.del(...keys);
161
+ return (pipeline || this.db).keys(key);
126
162
  }
127
163
  getIndexedKey(id, propertyKey, value) {
128
164
  const key = this.key(id);
@@ -130,16 +166,19 @@ export class RedisAdapter extends Adapter {
130
166
  }
131
167
  async getAll() {
132
168
  const keys = await this.db.keys(`${this.collectionName}:*`);
133
- const items = await Promise.all(keys.map((key) => this.findById(key.split(":")[1])));
134
- 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);
135
175
  }
136
176
  async findAllBy(props) {
137
177
  const keys = Object.keys(props);
138
- let foundKeys = await this.findKeys(props);
178
+ const foundKeys = await this.findKeys(props);
139
179
  if (foundKeys.length < keys.length) {
140
180
  return [];
141
181
  }
142
- const getId = (key) => key.split(":")[2];
143
182
  const map = foundKeys.reduce((map, key) => {
144
183
  const id = getId(key);
145
184
  const value = map.get(id) || 0;
@@ -149,9 +188,12 @@ export class RedisAdapter extends Adapter {
149
188
  const result = await Promise.all(promises);
150
189
  return result.filter(Boolean);
151
190
  }
152
- }
153
- __decorate([
154
- Inject(IoRedis),
155
- __metadata("design:type", Object)
156
- ], 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 };
157
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,WAAW,EAAC,MAAM,YAAY,CAAC;AACvC,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,OAAO,CAAC,GAAG,CAAC;QAEnB,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;YACP,GAAG,WAAW,CAAC,OAAO,CAAC;YACvB,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;AAlNC;IADC,MAAM,CAAC,OAAO,CAAC;;wCACG","sourcesContent":["import {Adapter, AdapterModel} from \"@tsed/adapters\";\nimport {cleanObject} from \"@tsed/core\";\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 delete payload._id;\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 ...item,\n ...cleanObject(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": "6.128.10",
3
+ "version": "6.131.0",
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": "6.128.10",
24
+ "@tsed/adapters": "6.131.0",
25
+ "@tsed/ioredis": "6.131.0",
25
26
  "tslib": "2.4.0"
26
27
  },
27
28
  "devDependencies": {
28
- "@tsed/core": "6.128.10",
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": "6.131.0"
33
30
  },
34
31
  "peerDependencies": {
35
- "@tsed/adapters": "^6.128.10",
36
- "@tsed/common": "^6.128.10",
37
- "@tsed/core": "^6.128.10",
38
- "@tsed/di": "^6.128.10",
39
- "ioredis": "^4.19.4",
40
- "ioredis-mock": "^5.2.0",
32
+ "@tsed/adapters": "^6.131.0",
33
+ "@tsed/common": "^6.131.0",
34
+ "@tsed/core": "^6.131.0",
35
+ "@tsed/di": "^6.131.0",
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",
@@ -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 {};