import { AbstractFactory, Container, DependencyRequirement, PropertyDependency, isInstantiable, DEPENDENCY_KEYS_METADATA_KEY, DEPENDENCY_KEYS_PROPERTY_METADATA_KEY, Instantiable, FactoryProducer, } from '../../../di' import {Collection, ErrorWithContext} from '../../../util' import {Config} from '../../../service/Config' import {RedemptionCodeRepository} from '../types' import {CacheRedemptionCodeRepository} from './CacheRedemptionCodeRepository' /** * A dependency injection factory that matches the abstract RedemptionCodeRepository class * and produces an instance of the configured repository driver implementation. */ @FactoryProducer() export class RedemptionCodeRepositoryFactory extends AbstractFactory { protected get config(): Config { return Container.getContainer().make(Config) } produce(): RedemptionCodeRepository { return new (this.getRedemptionCodeRepositoryClass())() } match(something: unknown): boolean { return something === RedemptionCodeRepository } getDependencyKeys(): Collection { const meta = Reflect.getMetadata(DEPENDENCY_KEYS_METADATA_KEY, this.getRedemptionCodeRepositoryClass()) if ( meta ) { return meta } return new Collection() } getInjectedProperties(): Collection { const meta = new Collection() let currentToken = this.getRedemptionCodeRepositoryClass() do { const loadedMeta = Reflect.getMetadata(DEPENDENCY_KEYS_PROPERTY_METADATA_KEY, currentToken) if ( loadedMeta ) { meta.concat(loadedMeta) } currentToken = Object.getPrototypeOf(currentToken) } while (Object.getPrototypeOf(currentToken) !== Function.prototype && Object.getPrototypeOf(currentToken) !== Object.prototype) return meta } /** * Return the instantiable class of the configured client repository backend. * @protected * @return Instantiable */ protected getRedemptionCodeRepositoryClass(): Instantiable { const RedemptionCodeRepositoryClass = this.config.get('oauth2.repository.client', CacheRedemptionCodeRepository) if ( !isInstantiable(RedemptionCodeRepositoryClass) || !(RedemptionCodeRepositoryClass.prototype instanceof RedemptionCodeRepository) ) { const e = new ErrorWithContext('Provided client repository class does not extend from @extollo/lib.RedemptionCodeRepository') e.context = { configKey: 'oauth2.repository.client', class: RedemptionCodeRepositoryClass.toString(), } } return RedemptionCodeRepositoryClass } }