|
|
|
import {
|
|
|
|
AbstractFactory,
|
|
|
|
Container,
|
|
|
|
DependencyRequirement,
|
|
|
|
PropertyDependency,
|
|
|
|
isInstantiable,
|
|
|
|
DEPENDENCY_KEYS_METADATA_KEY,
|
|
|
|
DEPENDENCY_KEYS_PROPERTY_METADATA_KEY, StaticClass, Instantiable,
|
|
|
|
} from '../di'
|
|
|
|
import {Collection, ErrorWithContext} from '../util'
|
|
|
|
import {Logging} from '../service/Logging'
|
|
|
|
import {Config} from '../service/Config'
|
|
|
|
import {ViewEngine} from './ViewEngine'
|
|
|
|
import {PugViewEngine} from './PugViewEngine'
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dependency factory whose token matches the abstract ViewEngine class, but produces
|
|
|
|
* a particular ViewEngine implementation based on the configuration.
|
|
|
|
*/
|
|
|
|
export class ViewEngineFactory extends AbstractFactory<ViewEngine> {
|
|
|
|
protected readonly logging: Logging
|
|
|
|
|
|
|
|
protected readonly config: Config
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
super({})
|
|
|
|
this.logging = Container.getContainer().make<Logging>(Logging)
|
|
|
|
this.config = Container.getContainer().make<Config>(Config)
|
|
|
|
}
|
|
|
|
|
|
|
|
produce(): ViewEngine {
|
|
|
|
return new (this.getViewEngineClass())()
|
|
|
|
}
|
|
|
|
|
|
|
|
match(something: unknown): boolean {
|
|
|
|
return something === ViewEngine
|
|
|
|
}
|
|
|
|
|
|
|
|
getDependencyKeys(): Collection<DependencyRequirement> {
|
|
|
|
const meta = Reflect.getMetadata(DEPENDENCY_KEYS_METADATA_KEY, this.getViewEngineClass())
|
|
|
|
if ( meta ) {
|
|
|
|
return meta
|
|
|
|
}
|
|
|
|
return new Collection<DependencyRequirement>()
|
|
|
|
}
|
|
|
|
|
|
|
|
getInjectedProperties(): Collection<PropertyDependency> {
|
|
|
|
const meta = new Collection<PropertyDependency>()
|
|
|
|
let currentToken = this.getViewEngineClass()
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Using the config, get the implementation of the ViewEngine that should be used in the application.
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
protected getViewEngineClass(): StaticClass<ViewEngine, Instantiable<ViewEngine>> {
|
|
|
|
const ViewEngineClass = this.config.get('server.view_engine.driver', PugViewEngine)
|
|
|
|
|
|
|
|
if ( !isInstantiable(ViewEngineClass) || !(ViewEngineClass.prototype instanceof ViewEngine) ) {
|
|
|
|
const e = new ErrorWithContext('Provided session class does not extend from @extollo/lib.ViewEngine')
|
|
|
|
e.context = {
|
|
|
|
configKey: 'server.view_engine.driver',
|
|
|
|
class: ViewEngineClass.toString(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ViewEngineClass
|
|
|
|
}
|
|
|
|
}
|