-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
107 lines (105 loc) · 3.02 KB
/
index.ts
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
97
98
99
100
101
102
103
104
105
106
107
import { init, injectable } from '@biorate/inversion';
import { ConfigLoader } from '@biorate/config-loader';
import { path } from '@biorate/tools';
import { promises as fs } from 'fs';
import { IConfigLoaderFsOption } from './interfaces';
import { ConfigLoaderFsFileNotLoadedError } from './errors';
export * from './errors';
/**
* @description File-based config loader
*
* ### Features
* - File config loader middleware
* - Basic configuration in config.json
* - Env-based configuration in config.{NODE_ENV}.json
*
* @example ./config.json
* ```
* {
* "hello": "world"
* }
* ```
*
* @example ./index.ts
* ```
* import { inject, container, Types, Core } from '@biorate/inversion';
* import { IConfig, Config } from '@biorate/config';
* import { ConfigLoader } from '@biorate/config-loader';
* import { ConfigLoaderFs } from '@biorate/config-loader-fs';
*
* class Root extends Core() {
* @inject(Types.Config) public config: IConfig;
* @inject(Types.ConfigLoaderFs) public configLoaderFs: ConfigLoader;
* }
*
* container.bind<IConfig>(Types.Config).to(Config).inSingletonScope();
* container.bind<ConfigLoader>(Types.ConfigLoaderFs).to(ConfigLoaderFs).inSingletonScope();
* container.bind<Root>(Root).toSelf().inSingletonScope();
*
* (async () => {
* const root = container.get<Root>(Root);
* await root.$run();
* root.config.get('hello'); // world
* })();
* ```
*
* ### See
*
* [@biorate/config-loader docs](https://biorate.github.io/core/modules/config_loader.html) for details
*/
@injectable()
export class ConfigLoaderFs extends ConfigLoader {
/**
* @description Root path
*/
private static directory = process.cwd();
/**
* @description Change application root method. Application root is equal ***process.cwd()*** by default
* @example
* ```ts
* FileConfig.root('/www/my-app/');
* ```
* @example
* ```ts
* container.bind<IConfig>(Types.Config)
* .to(FileConfig.root('/www/my-app/'))
* .inSingletonScope();
* ```
*/
public static root(path: string) {
ConfigLoaderFs.directory = path;
return this;
}
/**
* @description Load file
*/
protected async load(
file: string,
directory = ConfigLoaderFs.directory,
namespace?: string,
) {
try {
const data = JSON.parse(await fs.readFile(path.create(directory, file), 'utf-8'));
this.config.merge(namespace ? { [namespace]: data } : data);
console.info(`ConfigLoaderFs: file [${file}] - merged`);
} catch (e: unknown) {
console.warn(
new ConfigLoaderFsFileNotLoadedError(file, (<Error>e).message).message,
);
}
}
/**
* @description Initialize
*/
@init() protected async initialize() {
await this.load('package.json', undefined, 'package');
await this.load('config.json');
await this.load(`config.${process.env.NODE_ENV ?? 'debug'}.json`);
for (const option of this.config.get<IConfigLoaderFsOption[]>(
this.constructor.name,
[],
)) {
await this.load(option.file, option.directory, option.namespace);
}
}
}