{"version":3,"sources":["../../src/session/db.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport { PRINCIPAL_NAME_INDEX_NAME, resolveIndexesFor } from './common';\nimport { MapSession } from './map-session';\nimport type { SessionRepository } from './types';\n\ninterface SessionEntity {\n  primaryId: string;\n  sessionId: string;\n  creationTime: number;\n  lastAccessTime: number;\n  maxInactiveInterval: number;\n  expiryTime: number;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  attributes: Record<string, any>;\n  principalName?: string | null;\n}\n\nclass DBSession extends MapSession {\n  public isNew: boolean;\n  public primaryId: string;\n\n  constructor(cached: MapSession, isNew: boolean) {\n    super(cached);\n    this.isNew = isNew;\n    this.primaryId = randomUUID();\n  }\n}\n\nexport interface DBAdapter {\n  save(session: SessionEntity): Promise<void>;\n  deleteById(sessionId: string): Promise<void>;\n  findById(sessionId: string): Promise<SessionEntity | null>;\n  findByPrincipalName(principalName: string): Promise<SessionEntity[]>;\n  cleanupExpiredSessions(cleanupCount?: number): Promise<void>;\n}\n\nexport class DBIndexedSessionRepository implements SessionRepository<DBSession> {\n  private defaultMaxInactiveInterval = 1800;\n  private db: DBAdapter;\n\n  constructor(db: DBAdapter) {\n    this.db = db;\n  }\n\n  setDefaultMaxInactiveInterval(interval: number) {\n    this.defaultMaxInactiveInterval = interval;\n  }\n\n  private mapSessionToEntity(session: DBSession): SessionEntity {\n    const attributes: Record<string, string | number | null> = {};\n    for (const name of session.getAttributeNames()) {\n      attributes[name] = session.getAttribute(name);\n    }\n    const principalName = resolveIndexesFor(session);\n\n    return {\n      primaryId: session.primaryId,\n      sessionId: session.getId(),\n      creationTime: session.getCreationTime(),\n      lastAccessTime: session.getLastAccessedTime(),\n      maxInactiveInterval: session.getMaxInactiveInterval(),\n      expiryTime: session.getLastAccessedTime() + session.getMaxInactiveInterval() * 1000,\n      attributes,\n      principalName,\n    };\n  }\n\n  private mapEntityToSession(entity: SessionEntity, allowExpired: boolean): DBSession | null {\n    const loaded = new MapSession(entity.sessionId);\n    loaded.setCreationTime(entity.creationTime);\n    loaded.setLastAccessedTime(entity.lastAccessTime);\n    loaded.setMaxInactiveInterval(entity.maxInactiveInterval);\n    for (const [key, value] of Object.entries(entity.attributes)) {\n      loaded.setAttribute(key, value);\n    }\n\n    if (!allowExpired && loaded.isExpired()) return null;\n    const session = new DBSession(loaded, false);\n    session.primaryId = entity.primaryId;\n    return session;\n  }\n\n  private async getSession(id: string, allowExpired: boolean): Promise<DBSession | null> {\n    const entity = await this.db.findById(id);\n    if (!entity) return null;\n    return this.mapEntityToSession(entity, allowExpired);\n  }\n\n  // override\n  createSession() {\n    const cached = new MapSession();\n    cached.setMaxInactiveInterval(this.defaultMaxInactiveInterval);\n    return new DBSession(cached, true);\n  }\n\n  async save(session: DBSession) {\n    const entity = this.mapSessionToEntity(session);\n    await this.db.save(entity);\n    session.isNew = false;\n  }\n\n  async findById(sessionId: string): Promise<DBSession | null> {\n    return this.getSession(sessionId, false);\n  }\n\n  async deleteById(sessionId: string) {\n    await this.db.deleteById(sessionId);\n  }\n\n  async findByIndexNameAndIndexValue(\n    indexName: string,\n    indexValue: string\n  ): Promise<Map<string, DBSession>> {\n    if (indexName !== PRINCIPAL_NAME_INDEX_NAME) {\n      return new Map<string, DBSession>();\n    }\n    const entities = await this.db.findByPrincipalName(indexValue);\n    if (entities.length === 0) {\n      return new Map<string, DBSession>();\n    }\n    const sessions = new Map<string, DBSession>();\n    for (const entity of entities) {\n      const session = this.mapEntityToSession(entity, false);\n      if (session) {\n        sessions.set(session.getId(), session);\n      }\n    }\n    return sessions;\n  }\n\n  async findByPrincipalName(principalName: string): Promise<Map<string, DBSession>> {\n    return this.findByIndexNameAndIndexValue(PRINCIPAL_NAME_INDEX_NAME, principalName);\n  }\n\n  async cleanupExpiredSessions(cleanupCount?: number): Promise<void> {\n    return this.db.cleanupExpiredSessions(cleanupCount);\n  }\n}\n"],"mappings":"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","names":[]}