@nest-yalc-2/app 2.2.1 → 2.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/package.json +10 -2
  2. package/src/__tests__/app-bootstrap-base.helper.spec.ts +86 -38
  3. package/src/__tests__/app-bootstrap-standalone.helper.spec.ts +35 -35
  4. package/src/__tests__/app-bootstrap.helper.spec.ts +162 -98
  5. package/src/__tests__/app-config.service.spec.ts +55 -55
  6. package/src/__tests__/app-context.service.spec.ts +28 -28
  7. package/src/__tests__/app.events.spec.ts +12 -12
  8. package/src/__tests__/app.helper.spec.ts +71 -204
  9. package/src/__tests__/base-app-module.helper.spec.ts +295 -231
  10. package/src/__tests__/base-app.controller.spec.ts +90 -90
  11. package/src/__tests__/base-app.service.spec.ts +39 -39
  12. package/src/__tests__/cls.module.spec.ts +33 -33
  13. package/src/__tests__/life-cycle-handler.service.spec.ts +57 -48
  14. package/src/__tests__/unwrap-result.interceptor.spec.ts +52 -52
  15. package/src/app-bootstrap-base.helper.ts +206 -206
  16. package/src/app-bootstrap-standalone.helper.ts +67 -67
  17. package/src/app-bootstrap.helper.js +9 -9
  18. package/src/app-bootstrap.helper.ts +279 -279
  19. package/src/app-config.service.ts +61 -61
  20. package/src/app-context.module.ts +6 -6
  21. package/src/app-context.service.ts +16 -16
  22. package/src/app-imports.factory.js +2 -2
  23. package/src/app-imports.factory.js.map +1 -1
  24. package/src/app-imports.factory.ts +321 -321
  25. package/src/app.events.ts +8 -8
  26. package/src/app.helper.ts +73 -73
  27. package/src/base-app-module.helper.d.ts +2 -2
  28. package/src/base-app-module.helper.js +8 -5
  29. package/src/base-app-module.helper.js.map +1 -1
  30. package/src/base-app-module.helper.ts +457 -453
  31. package/src/base-app.controller.ts +51 -51
  32. package/src/base-app.interface.ts +55 -55
  33. package/src/base-app.service.ts +33 -33
  34. package/src/cls.module.d.ts +2 -1
  35. package/src/cls.module.js.map +1 -1
  36. package/src/cls.module.ts +76 -75
  37. package/src/conf.type.ts +22 -22
  38. package/src/def.const.ts +33 -33
  39. package/src/global.enum.ts +6 -6
  40. package/src/life-cycle-handler.service.ts +66 -66
  41. package/src/unwrap-result.interceptor.ts +32 -32
  42. package/src/yalc-controller.interface.ts +6 -6
@@ -1,279 +1,279 @@
1
- import { SystemExceptionFilter } from '@nest-yalc-2/errors/filters/index.js';
2
- import {
3
- BadRequestException,
4
- ExceptionFilter,
5
- NestApplicationOptions,
6
- ValidationPipe,
7
- ValidationPipeOptions,
8
- } from '@nestjs/common';
9
- import { NestFactory } from '@nestjs/core';
10
- // import { GqlExceptionFilter } from '@nestjs/graphql';
11
- import {
12
- FastifyAdapter,
13
- NestFastifyApplication,
14
- } from '@nestjs/platform-fastify';
15
- import fastifyCookie from '@fastify/cookie';
16
- import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
17
- import { fastify, FastifyInstance } from 'fastify';
18
- import { envIsTrue } from '@node-yalc/utils/env.helper.js';
19
- import { useContainer } from 'class-validator';
20
- import clc from 'cli-color';
21
- import {
22
- BaseAppBootstrap,
23
- IGlobalOptions,
24
- } from './app-bootstrap-base.helper.js';
25
- import { getEnvLoggerLevels } from '@node-yalc/logger/logger.helper.js';
26
- import { UnwrapResultInterceptor } from './unwrap-result.interceptor.js';
27
-
28
- export interface ICreateOptions {
29
- enableSwagger?: boolean;
30
- /**
31
- * Path segment (without leading slash) where Swagger UI/JSON is exposed.
32
- * Defaults to "api".
33
- */
34
- swaggerPath?: string;
35
- filters?: ExceptionFilter[];
36
- validationPipeOptions?: ValidationPipeOptions;
37
- /**
38
- * On some cases we do want to manually override the apiPrefix of the service conf
39
- */
40
- apiPrefix?: string;
41
- }
42
-
43
- export interface INestCreateOptions
44
- extends ICreateOptions, NestApplicationOptions {}
45
-
46
- export class AppBootstrap<
47
- TGlobalOptions extends IGlobalOptions = IGlobalOptions,
48
- > extends BaseAppBootstrap<NestFastifyApplication> {
49
- private fastifyInstance?: FastifyInstance;
50
- protected isSwaggerEnabled: boolean = false;
51
- protected swaggerPath = 'api';
52
-
53
- constructor(appAlias: string, module: any, options?: TGlobalOptions) {
54
- super(appAlias, module, { globalsOptions: options });
55
- }
56
-
57
- /* istanbul ignore next */
58
- async startServer(options?: {
59
- createOptions?: INestCreateOptions;
60
- fastifyInstance?: FastifyInstance;
61
- }) {
62
- await this.initApp(options);
63
-
64
- if (envIsTrue(process.env.APP_DRY_RUN) === true) {
65
- await this.closeApp();
66
- process.exit(0);
67
- }
68
-
69
- // no need to wait here
70
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
71
- this.listen();
72
-
73
- return this;
74
- }
75
-
76
- async initApp(options?: {
77
- createOptions?: INestCreateOptions;
78
- fastifyInstance?: FastifyInstance;
79
- }) {
80
- await this.createApp({
81
- fastifyInstance: this.fastifyInstance,
82
- createOptions: options?.createOptions,
83
- });
84
-
85
- return this.initSetup({
86
- fastifyInstance: this.fastifyInstance,
87
- createOptions: options?.createOptions,
88
- });
89
- }
90
-
91
- async initSetup(options?: {
92
- createOptions?: ICreateOptions;
93
- fastifyInstance?: FastifyInstance;
94
- }) {
95
- try {
96
- await this.applyBootstrapGlobals(options?.createOptions);
97
-
98
- await this.getApp().init();
99
- } catch (err) {
100
- /* istanbul ignore next */
101
- console.error('App init failed:', err);
102
- /* istanbul ignore next */
103
- this.closeCleanup();
104
- /* istanbul ignore next */
105
- throw new Error('Process aborted');
106
- }
107
-
108
- /* istanbul ignore next */
109
- if (envIsTrue(process.env.APP_DRY_RUN) === true) {
110
- /* istanbul ignore next */
111
- this.loggerService?.log('Dry run, exiting...');
112
- /* istanbul ignore next */
113
- await this.closeApp();
114
- /* istanbul ignore next */
115
- process.exit(0);
116
- }
117
-
118
- return this;
119
- }
120
-
121
- async createApp(options?: {
122
- createOptions?: INestCreateOptions;
123
- fastifyInstance?: FastifyInstance;
124
- }) {
125
- this.fastifyInstance = options?.fastifyInstance ?? fastify();
126
-
127
- let app;
128
- try {
129
- app = await NestFactory.create<NestFastifyApplication>(
130
- this.module,
131
- new FastifyAdapter(this.fastifyInstance as any),
132
- {
133
- bufferLogs: false,
134
- abortOnError: options?.createOptions?.abortOnError ?? false,
135
- logger: getEnvLoggerLevels(),
136
- ...(options?.createOptions ?? {}),
137
- },
138
- );
139
- } catch (err) {
140
- this.closeCleanup();
141
- // eslint-disable-next-line no-console
142
- console.error(clc.red('Failed to create app'), clc.red(err));
143
- throw new Error('Process aborted');
144
- }
145
-
146
- return this.setApp(app);
147
- }
148
-
149
- /* istanbul ignore next */
150
- /* istanbul ignore next */
151
- getFastifyInstance() {
152
- return this.fastifyInstance;
153
- }
154
-
155
- /* istanbul ignore next */
156
- setSwaggerEnabled(enabled: boolean) {
157
- this.isSwaggerEnabled = enabled;
158
- }
159
-
160
- async applyBootstrapGlobals(options?: ICreateOptions) {
161
- await super.applyBootstrapGlobals(options);
162
-
163
- this.getApp().useGlobalPipes(
164
- new ValidationPipe({
165
- transform: true,
166
- transformOptions: { enableImplicitConversion: false },
167
- validateCustomDecorators: true,
168
- exceptionFactory: /* istanbul ignore next */ (errors) => {
169
- /* istanbul ignore next */
170
- const errorMessages: { [key: string]: any } = {};
171
- /* istanbul ignore next */
172
- errors.forEach((error) => {
173
- errorMessages[error.property] = error;
174
- });
175
- /* istanbul ignore next */
176
- return new BadRequestException(errorMessages);
177
- },
178
- ...(options?.validationPipeOptions ?? {}),
179
- }),
180
- );
181
-
182
- this.getApp().setGlobalPrefix(
183
- options?.apiPrefix ?? (this.getConf()?.apiPrefix || ''),
184
- );
185
-
186
- await this.getApp().register(fastifyCookie as any, {});
187
-
188
- this.getApp().useGlobalInterceptors(new UnwrapResultInterceptor());
189
-
190
- /**
191
- * @todo refactor using a factory function to share with all services
192
- */
193
- const filters = [
194
- new SystemExceptionFilter(this.loggerService),
195
- ...(options?.filters ?? []),
196
- ];
197
- this.getApp().useGlobalFilters(...filters);
198
-
199
- if (options?.enableSwagger) {
200
- const swaggerPath = sanitizeSwaggerPath(options.swaggerPath);
201
- this.swaggerPath = swaggerPath;
202
- this.setSwaggerEnabled(true);
203
- const document = SwaggerModule.createDocument(
204
- this.getApp(),
205
- this.buildSwaggerConfig().build(),
206
- );
207
- SwaggerModule.setup(swaggerPath, this.getApp(), document, {
208
- jsonDocumentUrl: `/${swaggerPath}/json`,
209
- useGlobalPrefix: true,
210
- });
211
- }
212
-
213
- useContainer(this.getApp().select(this.getModule()), {
214
- fallbackOnErrors: true,
215
- });
216
-
217
- return this;
218
- }
219
-
220
- buildSwaggerConfig() {
221
- return new DocumentBuilder()
222
- .setTitle(this.appAlias)
223
- .setDescription(`${this.appAlias} rest api`);
224
- }
225
-
226
- /* istanbul ignore next */
227
- async listen(callback?: {
228
- (port: number, host: string, domain: string): void;
229
- }) {
230
- const port = this.getConf()?.port || 0;
231
- const host = this.getConf()?.host || '0.0.0.0';
232
- let apiPrefix = this.getConf()?.apiPrefix;
233
- apiPrefix = apiPrefix ? `/${apiPrefix}` : '';
234
- const domain = this.getConf()?.domain || 'localhost';
235
- await this.getApp().listen(port, host, async (_err, address) => {
236
- // eslint-disable-next-line no-console
237
- console.debug(`Server ${this.appAlias} listening on
238
- http://localhost:${port}${apiPrefix}/
239
- http://127.0.0.1:${port}${apiPrefix}/
240
- http://${domain}:${port}${apiPrefix}/
241
- ${address}`);
242
-
243
- // // eslint-disable-next-line no-console
244
- // console.debug(`GraphQL ${this.appAlias} listening on
245
- // http://localhost:${port}${apiPrefix}/graphql
246
- // http://127.0.0.1:${port}${apiPrefix}/graphql
247
- // http://${domain}:${port}${apiPrefix}/graphql`);
248
-
249
- if (this.isSwaggerEnabled) {
250
- // eslint-disable-next-line no-console
251
- console.debug(`Swagger ${this.appAlias} listening on
252
- http://localhost:${port}${apiPrefix}/${this.swaggerPath}
253
- http://127.0.0.1:${port}${apiPrefix}/${this.swaggerPath}
254
- http://${domain}:${port}${apiPrefix}/${this.swaggerPath}
255
- ${address}/${this.swaggerPath}
256
- JSON: http://localhost:${port}${apiPrefix}/${this.swaggerPath}/json`);
257
- }
258
-
259
- callback?.(port, host, domain);
260
- });
261
-
262
- /**
263
- * Hot reload @see https://docs.nestjs.com/recipes/hot-reload#hot-module-replacement-1
264
- */
265
- const hmr = typeof module !== 'undefined' ? (module as any).hot : undefined;
266
- if (hmr) {
267
- // eslint-disable-next-line no-console
268
- console.debug('Hot reload enabled. Reloading...');
269
- hmr.accept();
270
- hmr.dispose(() => this.closeApp());
271
- }
272
- }
273
- }
274
-
275
- /* istanbul ignore next */
276
- function sanitizeSwaggerPath(path?: string): string {
277
- const normalized = (path ?? 'api').replace(/^\/+/, '').replace(/\/+$/, '');
278
- return normalized || 'api';
279
- }
1
+ import { SystemExceptionFilter } from '@nest-yalc-2/errors/filters/index.js';
2
+ import {
3
+ BadRequestException,
4
+ ExceptionFilter,
5
+ NestApplicationOptions,
6
+ ValidationPipe,
7
+ ValidationPipeOptions,
8
+ } from '@nestjs/common';
9
+ import { NestFactory } from '@nestjs/core';
10
+ // import { GqlExceptionFilter } from '@nestjs/graphql';
11
+ import {
12
+ FastifyAdapter,
13
+ NestFastifyApplication,
14
+ } from '@nestjs/platform-fastify';
15
+ import fastifyCookie from '@fastify/cookie';
16
+ import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
17
+ import { fastify, FastifyInstance } from 'fastify';
18
+ import { envIsTrue } from '@node-yalc/utils/env.helper.js';
19
+ import { useContainer } from 'class-validator';
20
+ import clc from 'cli-color';
21
+ import {
22
+ BaseAppBootstrap,
23
+ IGlobalOptions,
24
+ } from './app-bootstrap-base.helper.js';
25
+ import { getEnvLoggerLevels } from '@node-yalc/logger/logger.helper.js';
26
+ import { UnwrapResultInterceptor } from './unwrap-result.interceptor.js';
27
+
28
+ export interface ICreateOptions {
29
+ enableSwagger?: boolean;
30
+ /**
31
+ * Path segment (without leading slash) where Swagger UI/JSON is exposed.
32
+ * Defaults to "api".
33
+ */
34
+ swaggerPath?: string;
35
+ filters?: ExceptionFilter[];
36
+ validationPipeOptions?: ValidationPipeOptions;
37
+ /**
38
+ * On some cases we do want to manually override the apiPrefix of the service conf
39
+ */
40
+ apiPrefix?: string;
41
+ }
42
+
43
+ export interface INestCreateOptions
44
+ extends ICreateOptions, NestApplicationOptions {}
45
+
46
+ export class AppBootstrap<
47
+ TGlobalOptions extends IGlobalOptions = IGlobalOptions,
48
+ > extends BaseAppBootstrap<NestFastifyApplication> {
49
+ private fastifyInstance?: FastifyInstance;
50
+ protected isSwaggerEnabled: boolean = false;
51
+ protected swaggerPath = 'api';
52
+
53
+ constructor(appAlias: string, module: any, options?: TGlobalOptions) {
54
+ super(appAlias, module, { globalsOptions: options });
55
+ }
56
+
57
+ /* istanbul ignore next */
58
+ async startServer(options?: {
59
+ createOptions?: INestCreateOptions;
60
+ fastifyInstance?: FastifyInstance;
61
+ }) {
62
+ await this.initApp(options);
63
+
64
+ if (envIsTrue(process.env.APP_DRY_RUN) === true) {
65
+ await this.closeApp();
66
+ process.exit(0);
67
+ }
68
+
69
+ // no need to wait here
70
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
71
+ this.listen();
72
+
73
+ return this;
74
+ }
75
+
76
+ async initApp(options?: {
77
+ createOptions?: INestCreateOptions;
78
+ fastifyInstance?: FastifyInstance;
79
+ }) {
80
+ await this.createApp({
81
+ fastifyInstance: this.fastifyInstance,
82
+ createOptions: options?.createOptions,
83
+ });
84
+
85
+ return this.initSetup({
86
+ fastifyInstance: this.fastifyInstance,
87
+ createOptions: options?.createOptions,
88
+ });
89
+ }
90
+
91
+ async initSetup(options?: {
92
+ createOptions?: ICreateOptions;
93
+ fastifyInstance?: FastifyInstance;
94
+ }) {
95
+ try {
96
+ await this.applyBootstrapGlobals(options?.createOptions);
97
+
98
+ await this.getApp().init();
99
+ } catch (err) {
100
+ /* istanbul ignore next */
101
+ console.error('App init failed:', err);
102
+ /* istanbul ignore next */
103
+ this.closeCleanup();
104
+ /* istanbul ignore next */
105
+ throw new Error('Process aborted');
106
+ }
107
+
108
+ /* istanbul ignore next */
109
+ if (envIsTrue(process.env.APP_DRY_RUN) === true) {
110
+ /* istanbul ignore next */
111
+ this.loggerService?.log('Dry run, exiting...');
112
+ /* istanbul ignore next */
113
+ await this.closeApp();
114
+ /* istanbul ignore next */
115
+ process.exit(0);
116
+ }
117
+
118
+ return this;
119
+ }
120
+
121
+ async createApp(options?: {
122
+ createOptions?: INestCreateOptions;
123
+ fastifyInstance?: FastifyInstance;
124
+ }) {
125
+ this.fastifyInstance = options?.fastifyInstance ?? fastify();
126
+
127
+ let app;
128
+ try {
129
+ app = await NestFactory.create<NestFastifyApplication>(
130
+ this.module,
131
+ new FastifyAdapter(this.fastifyInstance as any),
132
+ {
133
+ bufferLogs: false,
134
+ abortOnError: options?.createOptions?.abortOnError ?? false,
135
+ logger: getEnvLoggerLevels(),
136
+ ...(options?.createOptions ?? {}),
137
+ },
138
+ );
139
+ } catch (err) {
140
+ this.closeCleanup();
141
+ // eslint-disable-next-line no-console
142
+ console.error(clc.red('Failed to create app'), clc.red(err));
143
+ throw new Error('Process aborted');
144
+ }
145
+
146
+ return this.setApp(app);
147
+ }
148
+
149
+ /* istanbul ignore next */
150
+ /* istanbul ignore next */
151
+ getFastifyInstance() {
152
+ return this.fastifyInstance;
153
+ }
154
+
155
+ /* istanbul ignore next */
156
+ setSwaggerEnabled(enabled: boolean) {
157
+ this.isSwaggerEnabled = enabled;
158
+ }
159
+
160
+ async applyBootstrapGlobals(options?: ICreateOptions) {
161
+ await super.applyBootstrapGlobals(options);
162
+
163
+ this.getApp().useGlobalPipes(
164
+ new ValidationPipe({
165
+ transform: true,
166
+ transformOptions: { enableImplicitConversion: false },
167
+ validateCustomDecorators: true,
168
+ exceptionFactory: /* istanbul ignore next */ (errors) => {
169
+ /* istanbul ignore next */
170
+ const errorMessages: { [key: string]: any } = {};
171
+ /* istanbul ignore next */
172
+ errors.forEach((error) => {
173
+ errorMessages[error.property] = error;
174
+ });
175
+ /* istanbul ignore next */
176
+ return new BadRequestException(errorMessages);
177
+ },
178
+ ...(options?.validationPipeOptions ?? {}),
179
+ }),
180
+ );
181
+
182
+ this.getApp().setGlobalPrefix(
183
+ options?.apiPrefix ?? (this.getConf()?.apiPrefix || ''),
184
+ );
185
+
186
+ await this.getApp().register(fastifyCookie as any, {});
187
+
188
+ this.getApp().useGlobalInterceptors(new UnwrapResultInterceptor());
189
+
190
+ /**
191
+ * @todo refactor using a factory function to share with all services
192
+ */
193
+ const filters = [
194
+ new SystemExceptionFilter(this.loggerService),
195
+ ...(options?.filters ?? []),
196
+ ];
197
+ this.getApp().useGlobalFilters(...filters);
198
+
199
+ if (options?.enableSwagger) {
200
+ const swaggerPath = sanitizeSwaggerPath(options.swaggerPath);
201
+ this.swaggerPath = swaggerPath;
202
+ this.setSwaggerEnabled(true);
203
+ const document = SwaggerModule.createDocument(
204
+ this.getApp(),
205
+ this.buildSwaggerConfig().build(),
206
+ );
207
+ SwaggerModule.setup(swaggerPath, this.getApp(), document, {
208
+ jsonDocumentUrl: `/${swaggerPath}/json`,
209
+ useGlobalPrefix: true,
210
+ });
211
+ }
212
+
213
+ useContainer(this.getApp().select(this.getModule()), {
214
+ fallbackOnErrors: true,
215
+ });
216
+
217
+ return this;
218
+ }
219
+
220
+ buildSwaggerConfig() {
221
+ return new DocumentBuilder()
222
+ .setTitle(this.appAlias)
223
+ .setDescription(`${this.appAlias} rest api`);
224
+ }
225
+
226
+ /* istanbul ignore next */
227
+ async listen(callback?: {
228
+ (port: number, host: string, domain: string): void;
229
+ }) {
230
+ const port = this.getConf()?.port || 0;
231
+ const host = this.getConf()?.host || '0.0.0.0';
232
+ let apiPrefix = this.getConf()?.apiPrefix;
233
+ apiPrefix = apiPrefix ? `/${apiPrefix}` : '';
234
+ const domain = this.getConf()?.domain || 'localhost';
235
+ await this.getApp().listen(port, host, async (_err, address) => {
236
+ // eslint-disable-next-line no-console
237
+ console.debug(`Server ${this.appAlias} listening on
238
+ http://localhost:${port}${apiPrefix}/
239
+ http://127.0.0.1:${port}${apiPrefix}/
240
+ http://${domain}:${port}${apiPrefix}/
241
+ ${address}`);
242
+
243
+ // // eslint-disable-next-line no-console
244
+ // console.debug(`GraphQL ${this.appAlias} listening on
245
+ // http://localhost:${port}${apiPrefix}/graphql
246
+ // http://127.0.0.1:${port}${apiPrefix}/graphql
247
+ // http://${domain}:${port}${apiPrefix}/graphql`);
248
+
249
+ if (this.isSwaggerEnabled) {
250
+ // eslint-disable-next-line no-console
251
+ console.debug(`Swagger ${this.appAlias} listening on
252
+ http://localhost:${port}${apiPrefix}/${this.swaggerPath}
253
+ http://127.0.0.1:${port}${apiPrefix}/${this.swaggerPath}
254
+ http://${domain}:${port}${apiPrefix}/${this.swaggerPath}
255
+ ${address}/${this.swaggerPath}
256
+ JSON: http://localhost:${port}${apiPrefix}/${this.swaggerPath}/json`);
257
+ }
258
+
259
+ callback?.(port, host, domain);
260
+ });
261
+
262
+ /**
263
+ * Hot reload @see https://docs.nestjs.com/recipes/hot-reload#hot-module-replacement-1
264
+ */
265
+ const hmr = typeof module !== 'undefined' ? (module as any).hot : undefined;
266
+ if (hmr) {
267
+ // eslint-disable-next-line no-console
268
+ console.debug('Hot reload enabled. Reloading...');
269
+ hmr.accept();
270
+ hmr.dispose(() => this.closeApp());
271
+ }
272
+ }
273
+ }
274
+
275
+ /* istanbul ignore next */
276
+ function sanitizeSwaggerPath(path?: string): string {
277
+ const normalized = (path ?? 'api').replace(/^\/+/, '').replace(/\/+$/, '');
278
+ return normalized || 'api';
279
+ }
@@ -1,61 +1,61 @@
1
- import { Provider } from '@nestjs/common';
2
- import { ConfigService } from '@nestjs/config';
3
-
4
- /**
5
- * This service is used to access the app config registered with a specific app alias.
6
- * This is useful when you want to access the config of the current app with the dependency injection and
7
- * without specifying the app alias.
8
- */
9
- export class AppConfigService<T = any> {
10
- protected _config: T;
11
-
12
- constructor(
13
- public readonly service: ConfigService,
14
- protected readonly appAlias: string,
15
- ) {
16
- const config = this.service.get<T>(this.appAlias);
17
- if (!config) {
18
- throw new Error(
19
- `AppConfigService: No config found for app alias '${this.appAlias}'`,
20
- );
21
- }
22
-
23
- this._config = config;
24
- }
25
-
26
- /**
27
- * Type-safe access to the app config values of the current app.
28
- */
29
- get values(): T {
30
- return this._config;
31
- }
32
-
33
- /**
34
- * @deprecated - use .values instead
35
- */
36
- get(): T {
37
- return this.values;
38
- }
39
- }
40
-
41
- export function createAppConfigProvider(appAlias: string): Provider {
42
- return {
43
- provide: getAppConfigToken(appAlias),
44
- useFactory: (config: ConfigService): AppConfigService => {
45
- return new AppConfigService(config, appAlias);
46
- },
47
- inject: [ConfigService],
48
- };
49
- }
50
-
51
- export function getAppConfigToken(appAlias: string): string {
52
- return `${appAlias}Config`;
53
- }
54
-
55
- export function getAppEventToken(appAlias: string): string {
56
- return `${appAlias}Event`;
57
- }
58
-
59
- export function getAppLoggerToken(appAlias: string): string {
60
- return `${appAlias}Logger`;
61
- }
1
+ import { Provider } from '@nestjs/common';
2
+ import { ConfigService } from '@nestjs/config';
3
+
4
+ /**
5
+ * This service is used to access the app config registered with a specific app alias.
6
+ * This is useful when you want to access the config of the current app with the dependency injection and
7
+ * without specifying the app alias.
8
+ */
9
+ export class AppConfigService<T = any> {
10
+ protected _config: T;
11
+
12
+ constructor(
13
+ public readonly service: ConfigService,
14
+ protected readonly appAlias: string,
15
+ ) {
16
+ const config = this.service.get<T>(this.appAlias);
17
+ if (!config) {
18
+ throw new Error(
19
+ `AppConfigService: No config found for app alias '${this.appAlias}'`,
20
+ );
21
+ }
22
+
23
+ this._config = config;
24
+ }
25
+
26
+ /**
27
+ * Type-safe access to the app config values of the current app.
28
+ */
29
+ get values(): T {
30
+ return this._config;
31
+ }
32
+
33
+ /**
34
+ * @deprecated - use .values instead
35
+ */
36
+ get(): T {
37
+ return this.values;
38
+ }
39
+ }
40
+
41
+ export function createAppConfigProvider(appAlias: string): Provider {
42
+ return {
43
+ provide: getAppConfigToken(appAlias),
44
+ useFactory: (config: ConfigService): AppConfigService => {
45
+ return new AppConfigService(config, appAlias);
46
+ },
47
+ inject: [ConfigService],
48
+ };
49
+ }
50
+
51
+ export function getAppConfigToken(appAlias: string): string {
52
+ return `${appAlias}Config`;
53
+ }
54
+
55
+ export function getAppEventToken(appAlias: string): string {
56
+ return `${appAlias}Event`;
57
+ }
58
+
59
+ export function getAppLoggerToken(appAlias: string): string {
60
+ return `${appAlias}Logger`;
61
+ }