UNPKG

4.51 kBPlain TextView Raw
1// Copyright IBM Corp. and LoopBack contributors 2019,2020. All Rights Reserved.
2// Node module: @loopback/boot
3// This file is licensed under the MIT License.
4// License text available at https://opensource.org/licenses/MIT
5
6import {
7 Binding,
8 BindingSpec,
9 Constructor,
10 ContextTags,
11 injectable,
12} from '@loopback/core';
13import {BootBindings, BootTags} from './keys';
14
15/**
16 * Type definition for ArtifactOptions. These are the options supported by
17 * this Booter.
18 */
19export type ArtifactOptions = {
20 /**
21 * Array of directories to check for artifacts.
22 * Paths must be relative. Defaults to ['controllers']
23 */
24 dirs?: string | string[];
25 /**
26 * Array of file extensions to match artifact
27 * files in dirs. Defaults to ['.controller.js']
28 */
29 extensions?: string | string[];
30 /**
31 * A flag to control if artifact discovery should check nested
32 * folders or not. Default to true
33 */
34 nested?: boolean;
35 /**
36 * A `glob` string to use when searching for files. This takes
37 * precedence over other options.
38 */
39 glob?: string;
40};
41
42/**
43 * Defines the requirements to implement a Booter for LoopBack applications:
44 * - configure()
45 * - discover()
46 * - load()
47 *
48 * A Booter will run through the above methods in order.
49 */
50export interface Booter {
51 /**
52 * Configure phase of the Booter. It should set options / defaults in this phase.
53 */
54 configure?(): Promise<void>;
55 /**
56 * Discover phase of the Booter. It should search for artifacts in this phase.
57 */
58 discover?(): Promise<void>;
59 /**
60 * Load phase of the Booter. It should bind the artifacts in this phase.
61 */
62 load?(): Promise<void>;
63}
64
65/**
66 * Export of an array of all the Booter phases supported by the interface
67 * above, in the order they should be run.
68 */
69export const BOOTER_PHASES = ['configure', 'discover', 'load'];
70
71/**
72 * Options to configure `Bootstrapper`
73 */
74export type BootOptions = {
75 controllers?: ArtifactOptions;
76 repositories?: ArtifactOptions;
77 /**
78 * Additional Properties
79 */
80 // eslint-disable-next-line @typescript-eslint/no-explicit-any
81 [prop: string]: any;
82};
83
84/**
85 * Options for boot() execution
86 */
87export type BootExecutionOptions = {
88 /**
89 * Optional array of Booter Classes to bind to the application before running bootstrapper.
90 */
91 booters?: Constructor<Booter>[];
92 /**
93 * Filter Object for Bootstrapper
94 */
95 filter?: {
96 /**
97 * Names of booters that should be run by Bootstrapper
98 */
99 booters?: string[];
100 /**
101 * Names of phases that should be run by Bootstrapper
102 */
103 phases?: string[];
104 };
105 /**
106 * Additional Properties
107 */
108 // eslint-disable-next-line @typescript-eslint/no-explicit-any
109 [prop: string]: any;
110};
111
112/**
113 * Interface to describe the additions made available to an Application
114 * that uses BootMixin.
115 */
116export interface Bootable {
117 /**
118 * Root directory for the project to be booted
119 */
120 projectRoot: string;
121 /**
122 * Options for boot
123 */
124 bootOptions?: BootOptions;
125 /**
126 * Boot up the project
127 */
128 boot(): Promise<void>;
129 /**
130 * Register booters
131 * @param booterClasses - A list of booter classes
132 */
133 booters(...booterClasses: Constructor<Booter>[]): Binding[];
134}
135
136/**
137 * `@booter` decorator to mark a class as a `Booter` and specify the artifact
138 * namespace for the configuration of the booter
139 *
140 * @example
141 * ```ts
142 * @booter('controllers')
143 * export class ControllerBooter extends BaseArtifactBooter {
144 * constructor(
145 * @inject(CoreBindings.APPLICATION_INSTANCE) public app: Application,
146 * @inject(BootBindings.PROJECT_ROOT) projectRoot: string,
147 * @config()
148 * public controllerConfig: ArtifactOptions = {},
149 * ) {
150 * // ...
151 * }
152 * }
153 * ```
154 *
155 * @param artifactNamespace - Namespace for the artifact. It will be used to
156 * inject configuration from boot options. For example, the Booter class
157 * decorated with `@booter('controllers')` can receive its configuration via
158 * `@config()` from the `controllers` property of boot options.
159 *
160 * @param specs - Extra specs for the binding
161 */
162export function booter(artifactNamespace: string, ...specs: BindingSpec[]) {
163 return injectable(
164 {
165 tags: {
166 artifactNamespace,
167 [BootTags.BOOTER]: BootTags.BOOTER,
168 [ContextTags.NAMESPACE]: BootBindings.BOOTERS,
169 },
170 },
171 ...specs,
172 );
173}
174
175/**
176 * Interface to describe an object that may have an array of `booters`.
177 */
178export interface InstanceWithBooters {
179 booters?: Constructor<Booter>[];
180}