{"version":3,"file":"redis.mjs","sources":["../../../src/redis.ts"],"sourcesContent":["import {RedisClientOptions, createClient} from 'redis';\nimport {Session} from '@shopify/shopify-api';\nimport {\n  SessionStorage,\n  SessionStorageMigratorOptions,\n  SessionStorageMigrator,\n} from '@shopify/shopify-app-session-storage';\n\nimport {migrationList} from './migrations';\nimport {RedisConnection} from './redis-connection';\nimport {RedisSessionStorageMigrator} from './redis-migrator';\n\ntype RedisClient = ReturnType<typeof createClient>;\n\n/* eslint-disable @shopify/typescript-prefer-pascal-case-enums */\nenum ShopifyStorageOption {\n  sessionKeyPrefix = 'sessionKeyPrefix',\n  migratorOptions = 'migratorOptions',\n  onError = 'onError',\n}\n/* eslint-enable @shopify/typescript-prefer-pascal-case-enums */\n\nexport interface RedisSessionStorageOptions extends RedisClientOptions {\n  [ShopifyStorageOption.sessionKeyPrefix]: string;\n  [ShopifyStorageOption.migratorOptions]?: SessionStorageMigratorOptions;\n  [ShopifyStorageOption.onError]?: (...args: any[]) => void;\n}\n\nconst defaultRedisSessionStorageOptions: RedisSessionStorageOptions = {\n  sessionKeyPrefix: 'shopify_sessions',\n  migratorOptions: {\n    migrationDBIdentifier: 'migrations',\n  },\n};\n\nexport class RedisSessionStorage implements SessionStorage {\n  static withCredentials(\n    host: string,\n    db: number,\n    username: string,\n    password: string,\n    opts: Partial<RedisSessionStorageOptions>,\n  ) {\n    return new RedisSessionStorage(\n      new URL(\n        `redis://${encodeURIComponent(username)}:${encodeURIComponent(\n          password,\n        )}@${host}/${db}`,\n      ),\n      opts,\n    );\n  }\n\n  public readonly ready: Promise<void>;\n  private internalInit: Promise<void>;\n  private options: RedisSessionStorageOptions;\n  private client: RedisConnection;\n  private migrator: SessionStorageMigrator;\n\n  constructor(\n    urlOrClient: URL | string | RedisClient,\n    opts: Partial<RedisSessionStorageOptions> = {},\n  ) {\n    const allowedClientKeys = Object.keys(ShopifyStorageOption);\n    const disallowedClientKeys = Object.keys(opts).filter(\n      (key) => !allowedClientKeys.includes(key),\n    );\n\n    if (\n      typeof urlOrClient !== 'string' &&\n      !(urlOrClient instanceof URL) &&\n      disallowedClientKeys.length > 0\n    ) {\n      throw new Error(\n        'Passing a RedisClient instance is not supported with options. Set the options when creating the client ' +\n          'instead.',\n      );\n    }\n\n    this.options = {...defaultRedisSessionStorageOptions, ...opts};\n    this.internalInit = this.init(urlOrClient);\n    this.migrator = new RedisSessionStorageMigrator(\n      this.client,\n      this.options.migratorOptions,\n      migrationList,\n    );\n    this.ready = this.migrator.applyMigrations(this.internalInit);\n  }\n\n  public async storeSession(session: Session): Promise<boolean> {\n    await this.ready;\n\n    await this.client.set(\n      session.id,\n      JSON.stringify(session.toPropertyArray(true)),\n    );\n    await this.addKeyToShopList(session);\n    return true;\n  }\n\n  public async loadSession(id: string): Promise<Session | undefined> {\n    await this.ready;\n\n    let rawResult: any = await this.client.get(id);\n\n    if (!rawResult) return undefined;\n    rawResult = JSON.parse(rawResult);\n\n    return Session.fromPropertyArray(rawResult, true);\n  }\n\n  public async deleteSession(id: string): Promise<boolean> {\n    await this.ready;\n    const session = await this.loadSession(id);\n    if (session) {\n      await this.removeKeyFromShopList(session.shop, id);\n      await this.client.del(id);\n    }\n    return true;\n  }\n\n  public async deleteSessions(ids: string[]): Promise<boolean> {\n    await this.ready;\n    await Promise.all(ids.map((id) => this.deleteSession(id)));\n    return true;\n  }\n\n  public async findSessionsByShop(shop: string): Promise<Session[]> {\n    await this.ready;\n\n    const idKeysArrayString = await this.client.get(shop);\n    if (!idKeysArrayString) return [];\n\n    const idKeysArray = JSON.parse(idKeysArrayString);\n    const results: Session[] = [];\n    for (const idKey of idKeysArray) {\n      const rawResult = await this.client.get(idKey, false);\n      if (!rawResult) continue;\n\n      const session = Session.fromPropertyArray(JSON.parse(rawResult), true);\n      results.push(session);\n    }\n\n    return results;\n  }\n\n  public async disconnect(): Promise<void> {\n    await this.client.disconnect();\n  }\n\n  private async addKeyToShopList(session: Session) {\n    const shopKey = session.shop;\n    const idKey = this.client.generateFullKey(session.id);\n    const idKeysArrayString = await this.client.get(shopKey);\n\n    if (idKeysArrayString) {\n      const idKeysArray = JSON.parse(idKeysArrayString);\n\n      if (!idKeysArray.includes(idKey)) {\n        idKeysArray.push(idKey);\n        await this.client.set(shopKey, JSON.stringify(idKeysArray));\n      }\n    } else {\n      await this.client.set(shopKey, JSON.stringify([idKey]));\n    }\n  }\n\n  private async removeKeyFromShopList(shop: string, id: string) {\n    const shopKey = shop;\n    const idKey = this.client.generateFullKey(id);\n    const idKeysArrayString = await this.client.get(shopKey);\n\n    if (idKeysArrayString) {\n      const idKeysArray = JSON.parse(idKeysArrayString);\n      const index = idKeysArray.indexOf(idKey);\n\n      if (index > -1) {\n        idKeysArray.splice(index, 1);\n        await this.client.set(shopKey, JSON.stringify(idKeysArray));\n      }\n    }\n  }\n\n  private async init(urlOrClient: URL | string | RedisClient) {\n    this.client = new RedisConnection(\n      urlOrClient,\n      this.options,\n      this.options.sessionKeyPrefix,\n    );\n    await this.client.connect();\n  }\n}\n"],"names":[],"mappings":"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"}