75 lines
2.6 KiB
TypeScript
75 lines
2.6 KiB
TypeScript
|
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 {TokenRepository} from '../types'
|
||
|
import {ORMTokenRepository} from './ORMTokenRepository'
|
||
|
|
||
|
/**
|
||
|
* A dependency injection factory that matches the abstract TokenRepository class
|
||
|
* and produces an instance of the configured repository driver implementation.
|
||
|
*/
|
||
|
@FactoryProducer()
|
||
|
export class TokenRepositoryFactory extends AbstractFactory<TokenRepository> {
|
||
|
protected get config(): Config {
|
||
|
return Container.getContainer().make<Config>(Config)
|
||
|
}
|
||
|
|
||
|
produce(): TokenRepository {
|
||
|
return new (this.getTokenRepositoryClass())()
|
||
|
}
|
||
|
|
||
|
match(something: unknown): boolean {
|
||
|
return something === TokenRepository
|
||
|
}
|
||
|
|
||
|
getDependencyKeys(): Collection<DependencyRequirement> {
|
||
|
const meta = Reflect.getMetadata(DEPENDENCY_KEYS_METADATA_KEY, this.getTokenRepositoryClass())
|
||
|
if ( meta ) {
|
||
|
return meta
|
||
|
}
|
||
|
return new Collection<DependencyRequirement>()
|
||
|
}
|
||
|
|
||
|
getInjectedProperties(): Collection<PropertyDependency> {
|
||
|
const meta = new Collection<PropertyDependency>()
|
||
|
let currentToken = this.getTokenRepositoryClass()
|
||
|
|
||
|
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 token repository backend.
|
||
|
* @protected
|
||
|
* @return Instantiable<TokenRepository>
|
||
|
*/
|
||
|
protected getTokenRepositoryClass(): Instantiable<TokenRepository> {
|
||
|
const TokenRepositoryClass = this.config.get('oauth2.repository.token', ORMTokenRepository)
|
||
|
|
||
|
if ( !isInstantiable(TokenRepositoryClass) || !(TokenRepositoryClass.prototype instanceof TokenRepository) ) {
|
||
|
const e = new ErrorWithContext('Provided token repository class does not extend from @extollo/lib.TokenRepository')
|
||
|
e.context = {
|
||
|
configKey: 'oauth2.repository.client',
|
||
|
class: TokenRepositoryClass.toString(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TokenRepositoryClass
|
||
|
}
|
||
|
}
|