@shopify/shopify-app-session-storage-redis 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,26 +1,28 @@
1
1
  # Session Storage Adapter for Redis
2
2
 
3
- This package implements the `SessionStorage` interface that works with an instance of Redis.
3
+ This package implements the `SessionStorage` interface that works with an instance of [Redis](https://redis.io/).
4
4
 
5
5
  ```js
6
6
  import {shopifyApp} from '@shopify/shopify-app-express';
7
7
  import {RedisSessionStorage} from '@shopify/shopify-app-session-storage-redis';
8
8
 
9
9
  const shopify = shopifyApp({
10
- sessionStorage: new RedisSessionStorage("redis://username:password@host/database"),
11
- ...
10
+ sessionStorage: new RedisSessionStorage(
11
+ 'redis://username:password@host/database',
12
+ ),
13
+ // ...
12
14
  });
13
15
 
14
16
  // OR
15
17
 
16
18
  const shopify = shopifyApp({
17
19
  sessionStorage: RedisSessionStorage.withCredentials(
18
- "host.com",
19
- "thedatabase",
20
- "username",
21
- "password",
20
+ 'host.com',
21
+ 'thedatabase',
22
+ 'username',
23
+ 'password',
22
24
  ),
23
- ...
25
+ // ...
24
26
  });
25
27
  ```
26
28
 
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var shopifyApi = require('@shopify/shopify-api');
6
+
7
+ // need to add shop keys with list of associated session keys to support
8
+ // the new findSessionsByShop in v2.x.x
9
+ async function migrateToVersion1_0_1(client, sessionKeyPrefix, fullKey) {
10
+ const shopsAndSessions = {};
11
+ const keys = await client.keys('*');
12
+ for (const key of keys) {
13
+ if (key.startsWith(sessionKeyPrefix)) {
14
+ const session = shopifyApi.Session.fromPropertyArray(JSON.parse(await client.get(key)));
15
+ if (!shopsAndSessions[session.shop]) {
16
+ shopsAndSessions[session.shop] = [];
17
+ }
18
+ shopsAndSessions[session.shop].push(key);
19
+ }
20
+ }
21
+ // eslint-disable-next-line guard-for-in
22
+ for (const shop in shopsAndSessions) {
23
+ await client.set(fullKey(shop), JSON.stringify(shopsAndSessions[shop]));
24
+ }
25
+ }
26
+
27
+ exports.migrateToVersion1_0_1 = migrateToVersion1_0_1;
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var redis = require('redis');
6
6
  var shopifyApi = require('@shopify/shopify-api');
7
+ var migrations = require('./migrations.js');
7
8
 
8
9
  const defaultRedisSessionStorageOptions = {
9
10
  sessionKeyPrefix: 'shopify_sessions'
@@ -29,6 +30,7 @@ class RedisSessionStorage {
29
30
  async storeSession(session) {
30
31
  await this.ready;
31
32
  await this.client.set(this.fullKey(session.id), JSON.stringify(session.toPropertyArray()));
33
+ await this.addKeyToShopList(session);
32
34
  return true;
33
35
  }
34
36
  async loadSession(id) {
@@ -40,23 +42,29 @@ class RedisSessionStorage {
40
42
  }
41
43
  async deleteSession(id) {
42
44
  await this.ready;
43
- await this.client.del(this.fullKey(id));
45
+ const session = await this.loadSession(id);
46
+ if (session) {
47
+ await this.removeKeyFromShopList(session.shop, id);
48
+ await this.client.del(this.fullKey(id));
49
+ }
44
50
  return true;
45
51
  }
46
52
  async deleteSessions(ids) {
47
53
  await this.ready;
48
- await this.client.del(ids.map(id => this.fullKey(id)));
54
+ await Promise.all(ids.map(id => this.deleteSession(id)));
49
55
  return true;
50
56
  }
51
57
  async findSessionsByShop(shop) {
52
58
  await this.ready;
53
- const keys = await this.client.keys('*');
59
+ const idKeysArrayString = await this.client.get(this.fullKey(shop));
60
+ if (!idKeysArrayString) return [];
61
+ const idKeysArray = JSON.parse(idKeysArrayString);
54
62
  const results = [];
55
- for (const key of keys) {
56
- const rawResult = await this.client.get(key);
63
+ for (const idKey of idKeysArray) {
64
+ const rawResult = await this.client.get(idKey);
57
65
  if (!rawResult) continue;
58
66
  const session = shopifyApi.Session.fromPropertyArray(JSON.parse(rawResult));
59
- if (session.shop === shop) results.push(session);
67
+ results.push(session);
60
68
  }
61
69
  return results;
62
70
  }
@@ -66,6 +74,33 @@ class RedisSessionStorage {
66
74
  fullKey(name) {
67
75
  return `${this.options.sessionKeyPrefix}_${name}`;
68
76
  }
77
+ async addKeyToShopList(session) {
78
+ const shopKey = this.fullKey(session.shop);
79
+ const idKey = this.fullKey(session.id);
80
+ const idKeysArrayString = await this.client.get(shopKey);
81
+ if (idKeysArrayString) {
82
+ const idKeysArray = JSON.parse(idKeysArrayString);
83
+ if (!idKeysArray.includes(idKey)) {
84
+ idKeysArray.push(idKey);
85
+ await this.client.set(shopKey, JSON.stringify(idKeysArray));
86
+ }
87
+ } else {
88
+ await this.client.set(shopKey, JSON.stringify([idKey]));
89
+ }
90
+ }
91
+ async removeKeyFromShopList(shop, id) {
92
+ const shopKey = this.fullKey(shop);
93
+ const idKey = this.fullKey(id);
94
+ const idKeysArrayString = await this.client.get(shopKey);
95
+ if (idKeysArrayString) {
96
+ const idKeysArray = JSON.parse(idKeysArrayString);
97
+ const index = idKeysArray.indexOf(idKey);
98
+ if (index > -1) {
99
+ idKeysArray.splice(index, 1);
100
+ await this.client.set(shopKey, JSON.stringify(idKeysArray));
101
+ }
102
+ }
103
+ }
69
104
  async init() {
70
105
  this.client = redis.createClient({
71
106
  ...this.options,
@@ -75,6 +110,19 @@ class RedisSessionStorage {
75
110
  this.client.on('error', this.options.onError);
76
111
  }
77
112
  await this.client.connect();
113
+ await this.migrate();
114
+ }
115
+ async migrate() {
116
+ const migrationsRecord = await this.client.get(this.fullKey('migrations'));
117
+ let migrations$1 = {};
118
+ if (migrationsRecord) {
119
+ migrations$1 = JSON.parse(migrationsRecord);
120
+ }
121
+ if (!migrations$1.migrateToVersion1_0_1) {
122
+ await migrations.migrateToVersion1_0_1(this.client, this.options.sessionKeyPrefix, this.fullKey.bind(this));
123
+ migrations$1.migrateToVersion1_0_1 = true;
124
+ }
125
+ await this.client.set(this.fullKey('migrations'), JSON.stringify(migrations$1));
78
126
  }
79
127
  }
80
128
 
@@ -0,0 +1,5 @@
1
+ import { createClient } from 'redis';
2
+ type RedisClient = ReturnType<typeof createClient>;
3
+ export declare function migrateToVersion1_0_1(client: RedisClient, sessionKeyPrefix: string, fullKey: (name: string) => string): Promise<void>;
4
+ export {};
5
+ //# sourceMappingURL=migrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,OAAO,CAAC;AAGnC,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AAInD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,WAAW,EACnB,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,iBAmBlC"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrateToVersion1_0_1 = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var shopify_api_1 = require("@shopify/shopify-api");
6
+ // need to add shop keys with list of associated session keys to support
7
+ // the new findSessionsByShop in v2.x.x
8
+ function migrateToVersion1_0_1(client, sessionKeyPrefix, fullKey) {
9
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
10
+ var shopsAndSessions, keys, keys_1, keys_1_1, key, session, _a, _b, _c, _d, e_1_1, _e, _f, _g, _i, shop;
11
+ var e_1, _h;
12
+ return tslib_1.__generator(this, function (_j) {
13
+ switch (_j.label) {
14
+ case 0:
15
+ shopsAndSessions = {};
16
+ return [4 /*yield*/, client.keys('*')];
17
+ case 1:
18
+ keys = _j.sent();
19
+ _j.label = 2;
20
+ case 2:
21
+ _j.trys.push([2, 7, 8, 9]);
22
+ keys_1 = tslib_1.__values(keys), keys_1_1 = keys_1.next();
23
+ _j.label = 3;
24
+ case 3:
25
+ if (!!keys_1_1.done) return [3 /*break*/, 6];
26
+ key = keys_1_1.value;
27
+ if (!key.startsWith(sessionKeyPrefix)) return [3 /*break*/, 5];
28
+ _b = (_a = shopify_api_1.Session).fromPropertyArray;
29
+ _d = (_c = JSON).parse;
30
+ return [4 /*yield*/, client.get(key)];
31
+ case 4:
32
+ session = _b.apply(_a, [_d.apply(_c, [(_j.sent())])]);
33
+ if (!shopsAndSessions[session.shop]) {
34
+ shopsAndSessions[session.shop] = [];
35
+ }
36
+ shopsAndSessions[session.shop].push(key);
37
+ _j.label = 5;
38
+ case 5:
39
+ keys_1_1 = keys_1.next();
40
+ return [3 /*break*/, 3];
41
+ case 6: return [3 /*break*/, 9];
42
+ case 7:
43
+ e_1_1 = _j.sent();
44
+ e_1 = { error: e_1_1 };
45
+ return [3 /*break*/, 9];
46
+ case 8:
47
+ try {
48
+ if (keys_1_1 && !keys_1_1.done && (_h = keys_1.return)) _h.call(keys_1);
49
+ }
50
+ finally { if (e_1) throw e_1.error; }
51
+ return [7 /*endfinally*/];
52
+ case 9:
53
+ _e = shopsAndSessions;
54
+ _f = [];
55
+ for (_g in _e)
56
+ _f.push(_g);
57
+ _i = 0;
58
+ _j.label = 10;
59
+ case 10:
60
+ if (!(_i < _f.length)) return [3 /*break*/, 13];
61
+ _g = _f[_i];
62
+ if (!(_g in _e)) return [3 /*break*/, 12];
63
+ shop = _g;
64
+ return [4 /*yield*/, client.set(fullKey(shop), JSON.stringify(shopsAndSessions[shop]))];
65
+ case 11:
66
+ _j.sent();
67
+ _j.label = 12;
68
+ case 12:
69
+ _i++;
70
+ return [3 /*break*/, 10];
71
+ case 13: return [2 /*return*/];
72
+ }
73
+ });
74
+ });
75
+ }
76
+ exports.migrateToVersion1_0_1 = migrateToVersion1_0_1;
77
+ //# sourceMappingURL=migrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/migrations.ts"],"names":[],"mappings":";;;;AACA,oDAA6C;AAI7C,wEAAwE;AACxE,uCAAuC;AACvC,SAAsB,qBAAqB,CACzC,MAAmB,EACnB,gBAAwB,EACxB,OAAiC;;;;;;;oBAE3B,gBAAgB,GAA8B,EAAE,CAAC;oBAC1C,qBAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAA;;oBAA7B,IAAI,GAAG,SAAsB;;;;oBACjB,SAAA,iBAAA,IAAI,CAAA;;;;oBAAX,GAAG;yBACR,GAAG,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAhC,wBAAgC;oBAClB,KAAA,CAAA,KAAA,qBAAO,CAAA,CAAC,iBAAiB,CAAA;oBACvC,KAAA,CAAA,KAAA,IAAI,CAAA,CAAC,KAAK,CAAA;oBAAE,qBAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAA;;oBAD7B,OAAO,GAAG,cACd,cAAW,CAAC,SAAqB,CAAW,EAAC,EAC9C;oBACD,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;wBACnC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;qBACrC;oBACD,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;;;;;;;;;;;;;;;;yBAI1B,gBAAgB;;;;;;;;;;;oBACjC,qBAAM,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAA;;oBAAvE,SAAuE,CAAC;;;;;;;;;CAE3E;AAtBD,sDAsBC"}
@@ -19,6 +19,9 @@ export declare class RedisSessionStorage implements SessionStorage {
19
19
  findSessionsByShop(shop: string): Promise<Session[]>;
20
20
  disconnect(): Promise<void>;
21
21
  private fullKey;
22
+ private addKeyToShopList;
23
+ private removeKeyFromShopList;
22
24
  private init;
25
+ private migrate;
23
26
  }
24
27
  //# sourceMappingURL=redis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/redis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,kBAAkB,EAAC,MAAM,OAAO,CAAC;AACvD,OAAO,EAAC,OAAO,EAAC,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAC,cAAc,EAAC,MAAM,sCAAsC,CAAC;AAGpE,MAAM,WAAW,0BAA2B,SAAQ,kBAAkB;IACpE,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CACpC;AAKD,qBAAa,mBAAoB,YAAW,cAAc;IAuBtD,OAAO,CAAC,KAAK;IAtBf,MAAM,CAAC,eAAe,CACpB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,CAAC,0BAA0B,CAAC;IAY3C,SAAgB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,MAAM,CAAc;gBAGlB,KAAK,EAAE,GAAG,EAClB,IAAI,GAAE,OAAO,CAAC,0BAA0B,CAAM;IASnC,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAUhD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAWrD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM3C,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAM/C,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAgBpD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxC,OAAO,CAAC,OAAO;YAID,IAAI;CAUnB"}
1
+ {"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/redis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,kBAAkB,EAAC,MAAM,OAAO,CAAC;AACvD,OAAO,EAAC,OAAO,EAAC,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAC,cAAc,EAAC,MAAM,sCAAsC,CAAC;AAKpE,MAAM,WAAW,0BAA2B,SAAQ,kBAAkB;IACpE,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CACpC;AAKD,qBAAa,mBAAoB,YAAW,cAAc;IAuBtD,OAAO,CAAC,KAAK;IAtBf,MAAM,CAAC,eAAe,CACpB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,CAAC,0BAA0B,CAAC;IAY3C,SAAgB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,MAAM,CAAc;gBAGlB,KAAK,EAAE,GAAG,EAClB,IAAI,GAAE,OAAO,CAAC,0BAA0B,CAAM;IASnC,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAWhD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAWrD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU3C,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAM/C,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAmBpD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxC,OAAO,CAAC,OAAO;YAID,gBAAgB;YAiBhB,qBAAqB;YAgBrB,IAAI;YAYJ,OAAO;CAmBtB"}
package/build/ts/redis.js CHANGED
@@ -4,6 +4,7 @@ exports.RedisSessionStorage = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var redis_1 = require("redis");
6
6
  var shopify_api_1 = require("@shopify/shopify-api");
7
+ var migrations_1 = require("./migrations");
7
8
  var defaultRedisSessionStorageOptions = {
8
9
  sessionKeyPrefix: 'shopify_sessions',
9
10
  };
@@ -29,6 +30,9 @@ var RedisSessionStorage = /** @class */ (function () {
29
30
  _a.sent();
30
31
  return [4 /*yield*/, this.client.set(this.fullKey(session.id), JSON.stringify(session.toPropertyArray()))];
31
32
  case 2:
33
+ _a.sent();
34
+ return [4 /*yield*/, this.addKeyToShopList(session)];
35
+ case 3:
32
36
  _a.sent();
33
37
  return [2 /*return*/, true];
34
38
  }
@@ -56,15 +60,24 @@ var RedisSessionStorage = /** @class */ (function () {
56
60
  };
57
61
  RedisSessionStorage.prototype.deleteSession = function (id) {
58
62
  return tslib_1.__awaiter(this, void 0, void 0, function () {
63
+ var session;
59
64
  return tslib_1.__generator(this, function (_a) {
60
65
  switch (_a.label) {
61
66
  case 0: return [4 /*yield*/, this.ready];
62
67
  case 1:
63
68
  _a.sent();
64
- return [4 /*yield*/, this.client.del(this.fullKey(id))];
69
+ return [4 /*yield*/, this.loadSession(id)];
65
70
  case 2:
71
+ session = _a.sent();
72
+ if (!session) return [3 /*break*/, 5];
73
+ return [4 /*yield*/, this.removeKeyFromShopList(session.shop, id)];
74
+ case 3:
66
75
  _a.sent();
67
- return [2 /*return*/, true];
76
+ return [4 /*yield*/, this.client.del(this.fullKey(id))];
77
+ case 4:
78
+ _a.sent();
79
+ _a.label = 5;
80
+ case 5: return [2 /*return*/, true];
68
81
  }
69
82
  });
70
83
  });
@@ -77,7 +90,7 @@ var RedisSessionStorage = /** @class */ (function () {
77
90
  case 0: return [4 /*yield*/, this.ready];
78
91
  case 1:
79
92
  _a.sent();
80
- return [4 /*yield*/, this.client.del(ids.map(function (id) { return _this.fullKey(id); }))];
93
+ return [4 /*yield*/, Promise.all(ids.map(function (id) { return _this.deleteSession(id); }))];
81
94
  case 2:
82
95
  _a.sent();
83
96
  return [2 /*return*/, true];
@@ -87,36 +100,38 @@ var RedisSessionStorage = /** @class */ (function () {
87
100
  };
88
101
  RedisSessionStorage.prototype.findSessionsByShop = function (shop) {
89
102
  return tslib_1.__awaiter(this, void 0, void 0, function () {
90
- var keys, results, keys_1, keys_1_1, key, rawResult, session, e_1_1;
103
+ var idKeysArrayString, idKeysArray, results, idKeysArray_1, idKeysArray_1_1, idKey, rawResult, session, e_1_1;
91
104
  var e_1, _a;
92
105
  return tslib_1.__generator(this, function (_b) {
93
106
  switch (_b.label) {
94
107
  case 0: return [4 /*yield*/, this.ready];
95
108
  case 1:
96
109
  _b.sent();
97
- return [4 /*yield*/, this.client.keys('*')];
110
+ return [4 /*yield*/, this.client.get(this.fullKey(shop))];
98
111
  case 2:
99
- keys = _b.sent();
112
+ idKeysArrayString = _b.sent();
113
+ if (!idKeysArrayString)
114
+ return [2 /*return*/, []];
115
+ idKeysArray = JSON.parse(idKeysArrayString);
100
116
  results = [];
101
117
  _b.label = 3;
102
118
  case 3:
103
119
  _b.trys.push([3, 8, 9, 10]);
104
- keys_1 = tslib_1.__values(keys), keys_1_1 = keys_1.next();
120
+ idKeysArray_1 = tslib_1.__values(idKeysArray), idKeysArray_1_1 = idKeysArray_1.next();
105
121
  _b.label = 4;
106
122
  case 4:
107
- if (!!keys_1_1.done) return [3 /*break*/, 7];
108
- key = keys_1_1.value;
109
- return [4 /*yield*/, this.client.get(key)];
123
+ if (!!idKeysArray_1_1.done) return [3 /*break*/, 7];
124
+ idKey = idKeysArray_1_1.value;
125
+ return [4 /*yield*/, this.client.get(idKey)];
110
126
  case 5:
111
127
  rawResult = _b.sent();
112
128
  if (!rawResult)
113
129
  return [3 /*break*/, 6];
114
130
  session = shopify_api_1.Session.fromPropertyArray(JSON.parse(rawResult));
115
- if (session.shop === shop)
116
- results.push(session);
131
+ results.push(session);
117
132
  _b.label = 6;
118
133
  case 6:
119
- keys_1_1 = keys_1.next();
134
+ idKeysArray_1_1 = idKeysArray_1.next();
120
135
  return [3 /*break*/, 4];
121
136
  case 7: return [3 /*break*/, 10];
122
137
  case 8:
@@ -125,7 +140,7 @@ var RedisSessionStorage = /** @class */ (function () {
125
140
  return [3 /*break*/, 10];
126
141
  case 9:
127
142
  try {
128
- if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
143
+ if (idKeysArray_1_1 && !idKeysArray_1_1.done && (_a = idKeysArray_1.return)) _a.call(idKeysArray_1);
129
144
  }
130
145
  finally { if (e_1) throw e_1.error; }
131
146
  return [7 /*endfinally*/];
@@ -149,6 +164,60 @@ var RedisSessionStorage = /** @class */ (function () {
149
164
  RedisSessionStorage.prototype.fullKey = function (name) {
150
165
  return "".concat(this.options.sessionKeyPrefix, "_").concat(name);
151
166
  };
167
+ RedisSessionStorage.prototype.addKeyToShopList = function (session) {
168
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
169
+ var shopKey, idKey, idKeysArrayString, idKeysArray;
170
+ return tslib_1.__generator(this, function (_a) {
171
+ switch (_a.label) {
172
+ case 0:
173
+ shopKey = this.fullKey(session.shop);
174
+ idKey = this.fullKey(session.id);
175
+ return [4 /*yield*/, this.client.get(shopKey)];
176
+ case 1:
177
+ idKeysArrayString = _a.sent();
178
+ if (!idKeysArrayString) return [3 /*break*/, 4];
179
+ idKeysArray = JSON.parse(idKeysArrayString);
180
+ if (!!idKeysArray.includes(idKey)) return [3 /*break*/, 3];
181
+ idKeysArray.push(idKey);
182
+ return [4 /*yield*/, this.client.set(shopKey, JSON.stringify(idKeysArray))];
183
+ case 2:
184
+ _a.sent();
185
+ _a.label = 3;
186
+ case 3: return [3 /*break*/, 6];
187
+ case 4: return [4 /*yield*/, this.client.set(shopKey, JSON.stringify([idKey]))];
188
+ case 5:
189
+ _a.sent();
190
+ _a.label = 6;
191
+ case 6: return [2 /*return*/];
192
+ }
193
+ });
194
+ });
195
+ };
196
+ RedisSessionStorage.prototype.removeKeyFromShopList = function (shop, id) {
197
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
198
+ var shopKey, idKey, idKeysArrayString, idKeysArray, index;
199
+ return tslib_1.__generator(this, function (_a) {
200
+ switch (_a.label) {
201
+ case 0:
202
+ shopKey = this.fullKey(shop);
203
+ idKey = this.fullKey(id);
204
+ return [4 /*yield*/, this.client.get(shopKey)];
205
+ case 1:
206
+ idKeysArrayString = _a.sent();
207
+ if (!idKeysArrayString) return [3 /*break*/, 3];
208
+ idKeysArray = JSON.parse(idKeysArrayString);
209
+ index = idKeysArray.indexOf(idKey);
210
+ if (!(index > -1)) return [3 /*break*/, 3];
211
+ idKeysArray.splice(index, 1);
212
+ return [4 /*yield*/, this.client.set(shopKey, JSON.stringify(idKeysArray))];
213
+ case 2:
214
+ _a.sent();
215
+ _a.label = 3;
216
+ case 3: return [2 /*return*/];
217
+ }
218
+ });
219
+ });
220
+ };
152
221
  RedisSessionStorage.prototype.init = function () {
153
222
  return tslib_1.__awaiter(this, void 0, void 0, function () {
154
223
  return tslib_1.__generator(this, function (_a) {
@@ -160,6 +229,35 @@ var RedisSessionStorage = /** @class */ (function () {
160
229
  }
161
230
  return [4 /*yield*/, this.client.connect()];
162
231
  case 1:
232
+ _a.sent();
233
+ return [4 /*yield*/, this.migrate()];
234
+ case 2:
235
+ _a.sent();
236
+ return [2 /*return*/];
237
+ }
238
+ });
239
+ });
240
+ };
241
+ RedisSessionStorage.prototype.migrate = function () {
242
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
243
+ var migrationsRecord, migrations;
244
+ return tslib_1.__generator(this, function (_a) {
245
+ switch (_a.label) {
246
+ case 0: return [4 /*yield*/, this.client.get(this.fullKey('migrations'))];
247
+ case 1:
248
+ migrationsRecord = _a.sent();
249
+ migrations = {};
250
+ if (migrationsRecord) {
251
+ migrations = JSON.parse(migrationsRecord);
252
+ }
253
+ if (!!migrations.migrateToVersion1_0_1) return [3 /*break*/, 3];
254
+ return [4 /*yield*/, (0, migrations_1.migrateToVersion1_0_1)(this.client, this.options.sessionKeyPrefix, this.fullKey.bind(this))];
255
+ case 2:
256
+ _a.sent();
257
+ migrations.migrateToVersion1_0_1 = true;
258
+ _a.label = 3;
259
+ case 3: return [4 /*yield*/, this.client.set(this.fullKey('migrations'), JSON.stringify(migrations))];
260
+ case 4:
163
261
  _a.sent();
164
262
  return [2 /*return*/];
165
263
  }
@@ -1 +1 @@
1
- {"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/redis.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/redis.ts"],"names":[],"mappings":"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"}