@loopback/core
Version:
Define and implement core constructs such as Application and Component
168 lines (147 loc) • 3.59 kB
text/typescript
// Copyright IBM Corp. and LoopBack contributors 2017,2019. All Rights Reserved.
// Node module: @loopback/core
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
import {
Binding,
BoundValue,
Constructor,
createBindingFromClass,
Provider,
} from '@loopback/context';
import {
Application,
ControllerClass,
ServiceOrProviderClass,
} from './application';
import {LifeCycleObserver} from './lifecycle';
import {Server} from './server';
/**
* A map of provider classes to be bound to a context
*/
export interface ProviderMap {
[key: string]: Constructor<Provider<BoundValue>>;
}
/**
* A map of classes to be bound to a context
*/
export interface ClassMap {
[key: string]: Constructor<BoundValue>;
}
/**
* A component declares a set of artifacts so that they can be contributed to
* an application as a group
*/
export interface Component {
/**
* An array of controller classes
*/
controllers?: ControllerClass[];
/**
* A map of providers to be bound to the application context
*
* @example
* ```ts
* {
* 'authentication.strategies.ldap': LdapStrategyProvider
* }
* ```
*/
providers?: ProviderMap;
/**
* A map of classes to be bound to the application context.
*
* @example
* ```ts
* {
* 'rest.body-parsers.xml': XmlBodyParser
* }
* ```
*/
classes?: ClassMap;
/**
* A map of name/class pairs for servers
*/
servers?: {
[name: string]: Constructor<Server>;
};
lifeCycleObservers?: Constructor<LifeCycleObserver>[];
/**
* An array of service or provider classes
*/
services?: ServiceOrProviderClass[];
/**
* An array of bindings to be aded to the application context.
*
* @example
* ```ts
* const bindingX = Binding.bind('x').to('Value X');
* this.bindings = [bindingX]
* ```
*/
bindings?: Binding[];
/**
* An array of component classes
*/
components?: Constructor<Component>[];
/**
* Other properties
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[prop: string]: any;
}
/**
* Mount a component to an Application.
*
* @param app - Application
* @param component - Component instance
*/
export function mountComponent(app: Application, component: Component) {
if (component.classes) {
for (const classKey in component.classes) {
const binding = createBindingFromClass(component.classes[classKey], {
key: classKey,
});
app.add(binding);
}
}
if (component.providers) {
for (const providerKey in component.providers) {
const binding = createBindingFromClass(component.providers[providerKey], {
key: providerKey,
});
app.add(binding);
}
}
if (component.bindings) {
for (const binding of component.bindings) {
app.add(binding);
}
}
if (component.controllers) {
for (const controllerCtor of component.controllers) {
app.controller(controllerCtor);
}
}
if (component.servers) {
for (const serverKey in component.servers) {
app.server(component.servers[serverKey], serverKey);
}
}
if (component.lifeCycleObservers) {
for (const observer of component.lifeCycleObservers) {
app.lifeCycleObserver(observer);
}
}
if (component.services) {
for (const service of component.services) {
app.service(service);
}
}
if (component.components) {
for (const c of component.components) {
if (c === component) continue;
app.component(c);
}
}
}