-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.ts
115 lines (111 loc) · 2.86 KB
/
config.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
108
109
110
111
112
113
114
115
import { controller } from '../../utils';
import type { ResponsesBuilder } from '../../services';
import type {
Config,
Response,
AsyncExpressMiddleware,
ExpressMiddleware,
} from '../../types';
/**
* The options to contruct a {@link ConfigController}.
*
* @group Controllers/Config
*/
export type ConfigControllerOptions = {
/**
* A dictionary with the dependencies to inject.
*/
inject: {
responsesBuilder: ResponsesBuilder;
config: Config;
};
};
/**
* The controller class that allows to show and switch the application configuration.
*
* @group Controller Classes
* @group Controllers/Config
* @prettierignore
*/
export class ConfigController {
/**
* The service in charge or building the responses.
*/
protected readonly _responsesBuilder: ResponsesBuilder;
/**
* The service in charge of the configuration.
*/
protected readonly _config: Config;
/**
* @param options The options to construct the controller.
*/
constructor({ inject }: ConfigControllerOptions) {
this._responsesBuilder = inject.responsesBuilder;
this._config = inject.config;
}
/**
* Creates the middleware the shows the current configuration.
*/
showConfig(): ExpressMiddleware {
return (_, res) => {
this.respondWithConfig(res);
};
}
/**
* Creates the middleware the allows to switch the configuration.
*/
switchConfig(): AsyncExpressMiddleware {
return async (req, res, next) => {
const { name } = req.params;
if (!name || !this._config.canSwitchConfigs()) {
next();
return;
}
try {
await this._config.switch(name);
this.respondWithConfig(res);
} catch (error) {
next(error);
}
};
}
/**
* Utility to respond with the current configuration.
*/
protected respondWithConfig(res: Response): void {
const name = this._config.get<string>('name');
const data = {
name,
...this._config.getConfig<Record<string, unknown>>(),
};
this._responsesBuilder.json({
res,
data,
});
}
}
/**
* This controller is kind of special as it will only mount the routes if the
* `debug.configController` setting of the app configuration is set to `true`.
*
* It provides routes for:
* - `/`: Showing the current configuration.
* - `/switch/:name`: Switching the configuration, but only if the service allows it.
*
* @group Controllers
* @group Controllers/Config
*/
export const configController = controller((app) => {
const config = app.getConfig();
const router = app.getRouter();
if (config.get<boolean | undefined>('debug.configController') !== true) {
return router;
}
const ctrl = new ConfigController({
inject: {
config,
responsesBuilder: app.get('responsesBuilder'),
},
});
return router.get('/', ctrl.showConfig()).get('/switch/:name', ctrl.switchConfig());
});