import hoek from "hoek" ; import CatboxRedis from "@hapi/catbox-redis" ; import CatboxMemory from "@hapi/catbox-memory" ; import Redis from "ioredis" ; import config from "../config" ; import { HapiRequest , HapiServer } from "../types" ; import { FormSubmissionState } from "../plugins/engine/types" ; const { redisHost , redisPort , redisPassword , redisTls , isSandbox , sessionTimeout , } = config ; const partition = "cache" ; enum ADDITIONAL_IDENTIFIER { Confirmation = ":confirmation" } export class CacheService { /**
     * This service is responsible for getting, storing or deleting a user's session data in the cache. This service has been registered by  createServer cache : any ; logger : HapiServer [ "logger" ] ; constructor ( server ) { this . cache = server . cache ( { segment : "cache" } ) ; this . logger = server . logger ; } async getState ( request ) { const cached = await this . cache . get ( this . Key ( request ) ) ; return cached || { } ; } async mergeState ( request , value , nullOverride = true , arrayMerge = false ) { const key = this . Key ( request ) ; const state = await this . getState ( request ) ; hoek . merge ( state , value , nullOverride , arrayMerge ) ; await this . cache . set ( key , state , sessionTimeout ) ; return this . cache . get ( key ) ; } async getConfirmationState ( request ) { const key = this . Key ( request , ADDITIONAL_IDENTIFIER . Confirmation ) ; return await this . cache . get ( key ) ; } async setConfirmationState ( request , viewModel ) { const key = this . Key ( request , ADDITIONAL_IDENTIFIER . Confirmation ) ; return this . cache . set ( key , viewModel , sessionTimeout ) ; } async clearState ( request ) { if ( request . yar ?. id ) { this . cache . drop ( this . Key ( request ) ) ; } } param request param additionalIdentifier Key ( request , additionalIdentifier ? ) { if ( ! request ?. yar ?. id ) { throw Error ( "No session ID found" ) ; } return { segment : partition , id : `${ request . yar . id }:${ request . params . id }${ additionalIdentifier }` , } ; } } export const catboxProvider = ( ) => { /**
     * If redisHost doesn't exist, CatboxMemory will be used instead.
     * More information at  https const provider = { constructor : redisHost ? CatboxRedis : CatboxMemory , options : { } , } ; if ( redisHost ) { const redisOptions = { } ; if ( redisPassword ) { redisOptions . password = redisPassword ; } if ( redisTls ) { redisOptions . tls = { } ; } const client = isSandbox ? new Redis ( { host : redisHost , port : redisPort , password : redisPassword } ) : new Redis . Cluster ( [ { host : redisHost , port : redisPort , } , ] , { dnsLookup : ( address , callback ) => callback ( null , address , 4 ) , redisOptions , } ) ; provider . options = { client , partition } ; } else { provider . options = { partition } ; } return provider ; } ;