UNPKG

@shopify/shopify-app-session-storage-redis

Version:
125 lines (122 loc) 4.85 kB
import { Session } from '@shopify/shopify-api'; import { migrationList } from './migrations.mjs'; import { RedisConnection } from './redis-connection.mjs'; import { RedisSessionStorageMigrator } from './redis-migrator.mjs'; /* eslint-disable @shopify/typescript/prefer-pascal-case-enums */ var ShopifyStorageOption; (function (ShopifyStorageOption) { ShopifyStorageOption["sessionKeyPrefix"] = "sessionKeyPrefix"; ShopifyStorageOption["migratorOptions"] = "migratorOptions"; ShopifyStorageOption["onError"] = "onError"; })(ShopifyStorageOption || (ShopifyStorageOption = {})); const defaultRedisSessionStorageOptions = { sessionKeyPrefix: 'shopify_sessions', migratorOptions: { migrationDBIdentifier: 'migrations', }, }; class RedisSessionStorage { static withCredentials(host, db, username, password, opts) { return new RedisSessionStorage(new URL(`redis://${encodeURIComponent(username)}:${encodeURIComponent(password)}@${host}/${db}`), opts); } ready; internalInit; options; client; migrator; constructor(urlOrClient, opts = {}) { const allowedClientKeys = Object.keys(ShopifyStorageOption); const disallowedClientKeys = Object.keys(opts).filter((key) => !allowedClientKeys.includes(key)); if (typeof urlOrClient !== 'string' && !(urlOrClient instanceof URL) && disallowedClientKeys.length > 0) { throw new Error('Passing a RedisClient instance is not supported with options. Set the options when creating the client ' + 'instead.'); } this.options = { ...defaultRedisSessionStorageOptions, ...opts }; this.internalInit = this.init(urlOrClient); this.migrator = new RedisSessionStorageMigrator(this.client, this.options.migratorOptions, migrationList); this.ready = this.migrator.applyMigrations(this.internalInit); } async storeSession(session) { await this.ready; await this.client.set(session.id, JSON.stringify(session.toPropertyArray(true))); await this.addKeyToShopList(session); return true; } async loadSession(id) { await this.ready; let rawResult = await this.client.get(id); if (!rawResult) return undefined; rawResult = JSON.parse(rawResult); return Session.fromPropertyArray(rawResult, true); } async deleteSession(id) { await this.ready; const session = await this.loadSession(id); if (session) { await this.removeKeyFromShopList(session.shop, id); await this.client.del(id); } return true; } async deleteSessions(ids) { await this.ready; await Promise.all(ids.map((id) => this.deleteSession(id))); return true; } async findSessionsByShop(shop) { await this.ready; const idKeysArrayString = await this.client.get(shop); if (!idKeysArrayString) return []; const idKeysArray = JSON.parse(idKeysArrayString); const results = []; for (const idKey of idKeysArray) { const rawResult = await this.client.get(idKey, false); if (!rawResult) continue; const session = Session.fromPropertyArray(JSON.parse(rawResult), true); results.push(session); } return results; } async disconnect() { await this.client.disconnect(); } async addKeyToShopList(session) { const shopKey = session.shop; const idKey = this.client.generateFullKey(session.id); const idKeysArrayString = await this.client.get(shopKey); if (idKeysArrayString) { const idKeysArray = JSON.parse(idKeysArrayString); if (!idKeysArray.includes(idKey)) { idKeysArray.push(idKey); await this.client.set(shopKey, JSON.stringify(idKeysArray)); } } else { await this.client.set(shopKey, JSON.stringify([idKey])); } } async removeKeyFromShopList(shop, id) { const shopKey = shop; const idKey = this.client.generateFullKey(id); const idKeysArrayString = await this.client.get(shopKey); if (idKeysArrayString) { const idKeysArray = JSON.parse(idKeysArrayString); const index = idKeysArray.indexOf(idKey); if (index > -1) { idKeysArray.splice(index, 1); await this.client.set(shopKey, JSON.stringify(idKeysArray)); } } } async init(urlOrClient) { this.client = new RedisConnection(urlOrClient, this.options, this.options.sessionKeyPrefix); await this.client.connect(); } } export { RedisSessionStorage }; //# sourceMappingURL=redis.mjs.map