-
Notifications
You must be signed in to change notification settings - Fork 79
Expand file tree
/
Copy pathbase.booter.ts
More file actions
96 lines (86 loc) · 2.61 KB
/
base.booter.ts
File metadata and controls
96 lines (86 loc) · 2.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import {
ArtifactOptions,
Booter,
discoverFiles,
loadClassesFromFiles,
} from '@loopback/boot';
import {Constructor} from 'loopback4-soft-delete';
export class BaseBooter implements Booter {
/**
* Options being used by the Booter.
*/
options: ArtifactOptions;
/**
* Project root relative to which all other paths are resolved
*/
projectRoot: string;
/**
* Relative paths of directories to be searched
*/
dirs: string[];
/**
* File extensions to be searched
*/
extensions: string[];
/**
* `glob` pattern to match artifact paths
*/
glob: string;
/**
* List of files discovered by the Booter that matched artifact requirements
*/
discovered: string[];
/**
* List of exported classes discovered in the files
*/
classes: Constructor<{}>[];
/**
* Get the name of the artifact loaded by this booter, e.g. "Controller".
* Subclasses can override the default logic based on the class name.
*/
get artifactName(): string {
return this.constructor.name.replace(/Booter$/, '');
}
/**
* Configure the Booter by initializing the 'dirs', 'extensions' and 'glob'
* properties.
*
* NOTE: All properties are configured even if all aren't used.
*/
async configure() {
this.dirs = this.normalizeToArray(this.options.dirs);
this.extensions = this.normalizeToArray(this.options.extensions);
const joinedDirs = this.formatDirs(this.dirs);
const joinedExts = `@(${this.extensions.join('|')})`;
this.glob =
this.options.glob ??
`/${joinedDirs}/${this.options.nested ? '**/*' : '*'}${joinedExts}`;
}
private normalizeToArray<T>(value: T | T[] | undefined): T[] {
if (!value) return [];
return Array.isArray(value) ? value : [value];
}
private formatDirs(dirs: string[]): string {
if (dirs.length > 1) return `{${dirs.join(',')}}`;
return dirs.join(',');
}
/**
* Discover files based on the 'glob' property relative to the 'projectRoot'.
* Discovered artifact files matching the pattern are saved to the
* 'discovered' property.
*/
async discover() {
this.discovered = await discoverFiles(this.glob, this.projectRoot);
}
/**
* Filters the exports of 'discovered' files to only be Classes (in case
* function / types are exported) as an artifact is a Class. The filtered
* artifact Classes are saved in the 'classes' property.
*
* NOTE: Booters extending this class should call this method (await super.load())
* and then process the artifact classes as appropriate.
*/
async load() {
this.classes = loadClassesFromFiles(this.discovered, this.projectRoot);
}
}