@kibibit/configit 2.3.0 → 2.6.0
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.
- package/README.md +6 -2
- package/lib/config.model.d.ts +2 -2
- package/lib/config.model.d.ts.map +1 -1
- package/lib/config.model.js +7 -9
- package/lib/config.model.js.map +1 -1
- package/lib/config.service.d.ts +10 -3
- package/lib/config.service.d.ts.map +1 -1
- package/lib/config.service.js +53 -14
- package/lib/config.service.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -2
- package/src/__snapshots__/config.service.spec.ts.snap +174 -1
- package/src/config.model.ts +7 -8
- package/src/config.service.spec.ts +247 -13
- package/src/config.service.ts +46 -18
- package/src/pizza.config.model.mock.ts +8 -3
|
@@ -2,22 +2,36 @@
|
|
|
2
2
|
import fsExtra from 'fs-extra';
|
|
3
3
|
import { mockProcessExit } from 'jest-mock-process';
|
|
4
4
|
|
|
5
|
-
import { ConfigService } from './config.service';
|
|
6
|
-
import { PizzaConfig, ToppingEnum } from './pizza.config.model.mock';
|
|
5
|
+
import { ConfigService, EFileFormats, IConfigServiceOptions } from './config.service';
|
|
6
|
+
import { PizzaConfig, ToppingEnum, ToppingsConfig } from './pizza.config.model.mock';
|
|
7
7
|
|
|
8
8
|
class PizzaConfigService extends ConfigService<PizzaConfig> {
|
|
9
|
-
constructor(passedConfig?: Partial<PizzaConfig
|
|
10
|
-
super(PizzaConfig, passedConfig);
|
|
9
|
+
constructor(passedConfig?: Partial<PizzaConfig>, options?: IConfigServiceOptions) {
|
|
10
|
+
super(PizzaConfig, passedConfig, options);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
describe('Config Service', () => {
|
|
15
15
|
let configService: PizzaConfigService;
|
|
16
|
+
let mockExit;
|
|
16
17
|
beforeAll(() => {
|
|
17
18
|
configService = new PizzaConfigService({
|
|
18
19
|
NODE_ENV: 'test'
|
|
19
20
|
});
|
|
20
21
|
});
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
jest.clearAllMocks();
|
|
25
|
+
mockExit = mockProcessExit();
|
|
26
|
+
|
|
27
|
+
(fsExtra.writeJSONSync as jest.Mock).mockReturnValue(false);
|
|
28
|
+
(fsExtra.writeFileSync as jest.Mock).mockReturnValue(false);
|
|
29
|
+
(fsExtra.pathExistsSync as jest.Mock).mockReturnValue(true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
mockExit.mockRestore();
|
|
34
|
+
});
|
|
21
35
|
test('Service creation', () => {
|
|
22
36
|
expect(configService).toBeDefined();
|
|
23
37
|
});
|
|
@@ -38,10 +52,7 @@ describe('Config Service', () => {
|
|
|
38
52
|
});
|
|
39
53
|
|
|
40
54
|
test('Service can initialize the config files with saveToFile or init param', () => {
|
|
41
|
-
(fsExtra.writeJSONSync as jest.Mock).mockReturnValue(false);
|
|
42
55
|
(fsExtra.pathExistsSync as jest.Mock).mockReturnValue(false);
|
|
43
|
-
const mockExit = mockProcessExit();
|
|
44
|
-
jest.clearAllMocks();
|
|
45
56
|
new PizzaConfigService({
|
|
46
57
|
saveToFile: true,
|
|
47
58
|
NODE_ENV: 'test'
|
|
@@ -51,14 +62,9 @@ describe('Config Service', () => {
|
|
|
51
62
|
expect((fsExtra.writeJSONSync as jest.Mock).mock.calls[0]).toMatchSnapshot();
|
|
52
63
|
expect((fsExtra.writeJSONSync as jest.Mock).mock.calls[1]).toMatchSnapshot();
|
|
53
64
|
expect(mockExit).toHaveBeenCalledWith(0);
|
|
54
|
-
mockExit.mockRestore();
|
|
55
65
|
});
|
|
56
66
|
|
|
57
67
|
test('Service can SAVE the config files with saveToFile or init param', () => {
|
|
58
|
-
(fsExtra.writeJSONSync as jest.Mock).mockReturnValue(false);
|
|
59
|
-
(fsExtra.pathExistsSync as jest.Mock).mockReturnValue(true);
|
|
60
|
-
jest.clearAllMocks();
|
|
61
|
-
const mockExit = mockProcessExit();
|
|
62
68
|
new PizzaConfigService({
|
|
63
69
|
saveToFile: true,
|
|
64
70
|
NODE_ENV: 'test',
|
|
@@ -68,6 +74,234 @@ describe('Config Service', () => {
|
|
|
68
74
|
expect(fsExtra.writeJSONSync).toHaveBeenCalledTimes(1);
|
|
69
75
|
expect((fsExtra.writeJSONSync as jest.Mock).mock.calls[0]).toMatchSnapshot();
|
|
70
76
|
expect(mockExit).toHaveBeenCalledWith(0);
|
|
71
|
-
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('Service can Save and CONVERT the config files with saveToFile or init param', () => {
|
|
80
|
+
new PizzaConfigService({
|
|
81
|
+
saveToFile: true,
|
|
82
|
+
convert: EFileFormats.yaml,
|
|
83
|
+
NODE_ENV: 'test',
|
|
84
|
+
toppings: [ ToppingEnum.Cheese ]
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
expect(fsExtra.writeFileSync).toHaveBeenCalledTimes(1);
|
|
88
|
+
|
|
89
|
+
const [ filePath, fileContent ] = (fsExtra.writeFileSync as jest.Mock).mock.calls[0];
|
|
90
|
+
|
|
91
|
+
expect(filePath).toMatchSnapshot();
|
|
92
|
+
expect(`\n${ fileContent }\n`).toMatchSnapshot();
|
|
93
|
+
expect(mockExit).toHaveBeenCalledWith(0);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('wrap variables in attribute', () => {
|
|
97
|
+
test('YAML', () => {
|
|
98
|
+
new PizzaConfigService({
|
|
99
|
+
saveToFile: true,
|
|
100
|
+
convert: EFileFormats.yaml,
|
|
101
|
+
wrapper: 'env_variables',
|
|
102
|
+
NODE_ENV: 'test',
|
|
103
|
+
toppings: [ ToppingEnum.Cheese ]
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
expect(fsExtra.writeFileSync).toHaveBeenCalledTimes(1);
|
|
107
|
+
|
|
108
|
+
const [ filePath, fileContent ] = (fsExtra.writeFileSync as jest.Mock).mock.calls[0];
|
|
109
|
+
|
|
110
|
+
expect(filePath).toMatchSnapshot();
|
|
111
|
+
expect(`\n${ fileContent }\n`).toMatchSnapshot();
|
|
112
|
+
expect(mockExit).toHaveBeenCalledWith(0);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test('JSONC', () => {
|
|
116
|
+
new PizzaConfigService({
|
|
117
|
+
saveToFile: true,
|
|
118
|
+
wrapper: 'env_variables',
|
|
119
|
+
NODE_ENV: 'test',
|
|
120
|
+
toppings: [ ToppingEnum.Cheese ]
|
|
121
|
+
}, { fileFormat: EFileFormats.jsonc });
|
|
122
|
+
|
|
123
|
+
expect(fsExtra.writeJSONSync).toHaveBeenCalledTimes(1);
|
|
124
|
+
|
|
125
|
+
const [ filePath, fileContent ] = (fsExtra.writeJSONSync as jest.Mock).mock.calls[0];
|
|
126
|
+
|
|
127
|
+
expect(filePath).toMatchSnapshot();
|
|
128
|
+
expect(fileContent).toMatchSnapshot();
|
|
129
|
+
expect(mockExit).toHaveBeenCalledWith(0);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test('JSON', () => {
|
|
133
|
+
new PizzaConfigService({
|
|
134
|
+
saveToFile: true,
|
|
135
|
+
wrapper: 'env_variables',
|
|
136
|
+
NODE_ENV: 'test',
|
|
137
|
+
toppings: [ ToppingEnum.Cheese ]
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
expect(fsExtra.writeJSONSync).toHaveBeenCalledTimes(1);
|
|
141
|
+
|
|
142
|
+
const [ filePath, fileContent ] = (fsExtra.writeJSONSync as jest.Mock).mock.calls[0];
|
|
143
|
+
|
|
144
|
+
expect(filePath).toMatchSnapshot();
|
|
145
|
+
expect(fileContent).toMatchSnapshot();
|
|
146
|
+
expect(mockExit).toHaveBeenCalledWith(0);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test('Service returns correct empty yaml when config is empty', () => {
|
|
151
|
+
new PizzaConfigService({
|
|
152
|
+
saveToFile: true,
|
|
153
|
+
convert: EFileFormats.yaml
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
expect(fsExtra.writeFileSync).toHaveBeenCalledTimes(1);
|
|
157
|
+
|
|
158
|
+
const [ filePath, fileContent ] = (fsExtra.writeFileSync as jest.Mock).mock.calls[0];
|
|
159
|
+
|
|
160
|
+
expect(filePath).toMatchSnapshot();
|
|
161
|
+
expect(fileContent.trim()).toMatchSnapshot();
|
|
162
|
+
expect(mockExit).toHaveBeenCalledWith(0);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test('Service can return a plain object', () => {
|
|
166
|
+
const pizzaConfigInstance = new PizzaConfigService({
|
|
167
|
+
NODE_ENV: 'test',
|
|
168
|
+
toppings: [ ToppingEnum.Cheese ]
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const plainObjectConfig = pizzaConfigInstance.toPlainObject();
|
|
172
|
+
expect(plainObjectConfig).toMatchSnapshot();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test('Service can save yaml without schema', async () => {
|
|
176
|
+
const pizzaConfigInstance = new PizzaConfigService({
|
|
177
|
+
NODE_ENV: 'test',
|
|
178
|
+
toppings: [ ToppingEnum.Cheese ]
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
await pizzaConfigInstance.writeConfigToFile({
|
|
182
|
+
fileFormat: EFileFormats.yaml,
|
|
183
|
+
excludeSchema: true
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
expect(fsExtra.writeFileSync).toHaveBeenCalledTimes(1);
|
|
187
|
+
|
|
188
|
+
const [ filePath, fileContent ] = (fsExtra.writeFileSync as jest.Mock).mock.calls[0];
|
|
189
|
+
|
|
190
|
+
expect(filePath).toMatchSnapshot();
|
|
191
|
+
expect(fileContent).not.toContain('# yaml-language-server: $schema=');
|
|
192
|
+
expect(fileContent).toMatchSnapshot();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test('writeConfigToFile YAML', () => {
|
|
196
|
+
const config = new PizzaConfigService({
|
|
197
|
+
toppings: [ ToppingEnum.Cheese ]
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
config.writeConfigToFile({
|
|
201
|
+
fileFormat: EFileFormats.yaml,
|
|
202
|
+
excludeSchema: true,
|
|
203
|
+
objectWrapper: 'env_variables'
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
expect(fsExtra.writeFileSync).toHaveBeenCalledTimes(1);
|
|
207
|
+
|
|
208
|
+
const [ filePath, fileContent ] = (fsExtra.writeFileSync as jest.Mock).mock.calls[0];
|
|
209
|
+
|
|
210
|
+
expect(filePath).toMatchSnapshot();
|
|
211
|
+
expect(fileContent.trim()).toMatchSnapshot();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test('writeConfigToFile HJSON', () => {
|
|
215
|
+
const config = new PizzaConfigService({
|
|
216
|
+
toppings: [ ToppingEnum.Cheese ]
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
config.writeConfigToFile({
|
|
220
|
+
fileFormat: EFileFormats.hjson,
|
|
221
|
+
excludeSchema: true,
|
|
222
|
+
objectWrapper: 'env_variables'
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
expect(fsExtra.writeFileSync).toHaveBeenCalledTimes(1);
|
|
226
|
+
|
|
227
|
+
const [ filePath, fileContent ] = (fsExtra.writeFileSync as jest.Mock).mock.calls[0];
|
|
228
|
+
|
|
229
|
+
expect(filePath).toMatchSnapshot();
|
|
230
|
+
expect(fileContent.trim()).toMatchSnapshot();
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
test('writeConfigToFile JSONC', () => {
|
|
234
|
+
const config = new PizzaConfigService({
|
|
235
|
+
toppings: [ ToppingEnum.Cheese ]
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
jest.clearAllMocks();
|
|
239
|
+
|
|
240
|
+
config.writeConfigToFile({
|
|
241
|
+
fileFormat: EFileFormats.jsonc,
|
|
242
|
+
excludeSchema: true,
|
|
243
|
+
objectWrapper: 'env_variables'
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
expect(fsExtra.writeJSONSync).toHaveBeenCalledTimes(1);
|
|
247
|
+
|
|
248
|
+
const [ filePath, fileContent ] = (fsExtra.writeJSONSync as jest.Mock).mock.calls[0];
|
|
249
|
+
|
|
250
|
+
expect(filePath).toMatchSnapshot();
|
|
251
|
+
expect(fileContent).toMatchSnapshot();
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test('writeConfigToFile JSON', () => {
|
|
255
|
+
const config = new PizzaConfigService({
|
|
256
|
+
toppings: [ ToppingEnum.Cheese ]
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
jest.clearAllMocks();
|
|
260
|
+
|
|
261
|
+
config.writeConfigToFile({
|
|
262
|
+
fileFormat: EFileFormats.json,
|
|
263
|
+
excludeSchema: true,
|
|
264
|
+
objectWrapper: 'env_variables'
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
expect(fsExtra.writeJSONSync).toHaveBeenCalledTimes(1);
|
|
268
|
+
|
|
269
|
+
const [ filePath, fileContent ] = (fsExtra.writeJSONSync as jest.Mock).mock.calls[0];
|
|
270
|
+
|
|
271
|
+
expect(filePath).toMatchSnapshot();
|
|
272
|
+
expect(fileContent).toMatchSnapshot();
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
describe('Shared Configurations', () => {
|
|
276
|
+
test('Can define shared config', () => {
|
|
277
|
+
const pizzaConfigInstance = new PizzaConfigService({
|
|
278
|
+
NODE_ENV: 'test',
|
|
279
|
+
toppings: [ ToppingEnum.Cheese ],
|
|
280
|
+
INCLUDE_MEAT: true
|
|
281
|
+
} as any, {
|
|
282
|
+
sharedConfig: [ ToppingsConfig ]
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
pizzaConfigInstance.writeConfigToFile({
|
|
286
|
+
fileFormat: EFileFormats.json
|
|
287
|
+
// excludeSchema: false
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
expect(fsExtra.writeJSONSync).toHaveBeenCalledTimes(4);
|
|
291
|
+
|
|
292
|
+
const [ filePath0, fileContent0 ] = (fsExtra.writeJSONSync as jest.Mock).mock.calls[0];
|
|
293
|
+
const [ filePath1, fileContent1 ] = (fsExtra.writeJSONSync as jest.Mock).mock.calls[1];
|
|
294
|
+
const [ filePath2, fileContent2 ] = (fsExtra.writeJSONSync as jest.Mock).mock.calls[2];
|
|
295
|
+
const [ filePath3, fileContent3 ] = (fsExtra.writeJSONSync as jest.Mock).mock.calls[3];
|
|
296
|
+
|
|
297
|
+
expect(filePath0).toMatchSnapshot();
|
|
298
|
+
expect(fileContent0).toMatchSnapshot();
|
|
299
|
+
expect(filePath1).toMatchSnapshot();
|
|
300
|
+
expect(fileContent1).toMatchSnapshot();
|
|
301
|
+
expect(filePath2).toMatchSnapshot();
|
|
302
|
+
expect(fileContent2).toMatchSnapshot();
|
|
303
|
+
expect(filePath3).toMatchSnapshot();
|
|
304
|
+
expect(fileContent3).toMatchSnapshot();
|
|
305
|
+
});
|
|
72
306
|
});
|
|
73
307
|
});
|
package/src/config.service.ts
CHANGED
|
@@ -11,23 +11,32 @@ import {
|
|
|
11
11
|
readJSONSync,
|
|
12
12
|
writeFileSync,
|
|
13
13
|
writeJSONSync } from 'fs-extra';
|
|
14
|
+
import { stringify as hjsonStringify } from 'hjson';
|
|
14
15
|
import { camelCase, chain, keys, mapValues, startCase, times } from 'lodash';
|
|
15
|
-
import nconf, { IFormats } from 'nconf';
|
|
16
|
+
import nconf, { IFormat, IFormats } from 'nconf';
|
|
16
17
|
import nconfYamlFormat from 'nconf-yaml';
|
|
17
18
|
import YAML from 'yaml';
|
|
18
19
|
|
|
20
|
+
import * as nconfJsoncFormat from '@kibibit/nconf-jsonc';
|
|
21
|
+
|
|
19
22
|
import { ConfigValidationError } from './config.errors';
|
|
20
23
|
import { BaseConfig } from './config.model';
|
|
21
24
|
import { getEnvironment, setEnvironment } from './environment.service';
|
|
22
25
|
|
|
23
|
-
type
|
|
26
|
+
type INconfKibibitFormats = IFormats & {
|
|
27
|
+
yaml: nconfYamlFormat;
|
|
28
|
+
jsonc: IFormat;
|
|
29
|
+
};
|
|
24
30
|
|
|
25
|
-
const
|
|
31
|
+
const nconfFormats = nconf.formats as INconfKibibitFormats;
|
|
32
|
+
nconfFormats.yaml = nconfYamlFormat;
|
|
33
|
+
nconfFormats.jsonc = nconfJsoncFormat;
|
|
26
34
|
|
|
27
35
|
export interface IConfigServiceOptions {
|
|
28
36
|
convertToCamelCase?: boolean;
|
|
29
|
-
|
|
37
|
+
fileFormat?: EFileFormats;
|
|
30
38
|
sharedConfig?: TClass<BaseConfig>[];
|
|
39
|
+
skipSchema?: boolean;
|
|
31
40
|
schemaFolderName?: string;
|
|
32
41
|
showOverrides?: boolean;
|
|
33
42
|
configFolderRelativePath?: string;
|
|
@@ -37,8 +46,15 @@ export interface IConfigServiceOptions {
|
|
|
37
46
|
};
|
|
38
47
|
}
|
|
39
48
|
|
|
49
|
+
export enum EFileFormats {
|
|
50
|
+
json = 'json',
|
|
51
|
+
yaml = 'yaml',
|
|
52
|
+
jsonc = 'jsonc',
|
|
53
|
+
hjson = 'hjson'
|
|
54
|
+
}
|
|
55
|
+
|
|
40
56
|
export interface IWriteConfigToFileOptions {
|
|
41
|
-
|
|
57
|
+
fileFormat: EFileFormats;
|
|
42
58
|
excludeSchema?: boolean;
|
|
43
59
|
objectWrapper?: string;
|
|
44
60
|
outputFolder?: string;
|
|
@@ -56,7 +72,7 @@ type TClass<T> = (new (partial: Partial<T>) => T);
|
|
|
56
72
|
* first one.
|
|
57
73
|
*/
|
|
58
74
|
export class ConfigService<T extends BaseConfig> {
|
|
59
|
-
private fileExtension:
|
|
75
|
+
private fileExtension: EFileFormats;
|
|
60
76
|
readonly mode: string = getEnvironment();
|
|
61
77
|
readonly options: IConfigServiceOptions;
|
|
62
78
|
readonly config?: T;
|
|
@@ -79,15 +95,16 @@ export class ConfigService<T extends BaseConfig> {
|
|
|
79
95
|
|
|
80
96
|
this.options = {
|
|
81
97
|
sharedConfig: [],
|
|
82
|
-
|
|
98
|
+
fileFormat: EFileFormats.json,
|
|
83
99
|
convertToCamelCase: false,
|
|
84
100
|
schemaFolderName: '.schemas',
|
|
101
|
+
skipSchema: false,
|
|
85
102
|
showOverrides: false,
|
|
86
103
|
...options
|
|
87
104
|
};
|
|
88
105
|
this.appRoot = this.findRoot();
|
|
89
106
|
this.genericClass = givenClass;
|
|
90
|
-
this.fileExtension = this.options.
|
|
107
|
+
this.fileExtension = this.options.fileFormat || EFileFormats.json;
|
|
91
108
|
this.config = this.createConfigInstance(this.genericClass, {}) as T;
|
|
92
109
|
this.configFileName = this.config.getFileName(this.fileExtension);
|
|
93
110
|
this.configFileRoot = this.findConfigRoot();
|
|
@@ -120,15 +137,17 @@ export class ConfigService<T extends BaseConfig> {
|
|
|
120
137
|
if (config.convert) {
|
|
121
138
|
console.log(cyan('Converting Configuration File'));
|
|
122
139
|
}
|
|
123
|
-
const
|
|
140
|
+
const fileFormat = config.convert ? config.convert : this.fileExtension;
|
|
124
141
|
const objectWrapper = config.wrapper;
|
|
125
|
-
this.writeConfigToFile({
|
|
142
|
+
this.writeConfigToFile({ fileFormat, objectWrapper });
|
|
126
143
|
console.log(cyan('EXITING'));
|
|
127
144
|
process.exit(0);
|
|
128
145
|
return;
|
|
129
146
|
}
|
|
130
147
|
|
|
131
|
-
this.
|
|
148
|
+
if (!this.options.skipSchema) {
|
|
149
|
+
this.writeSchema();
|
|
150
|
+
}
|
|
132
151
|
|
|
133
152
|
configService = this;
|
|
134
153
|
}
|
|
@@ -140,15 +159,15 @@ export class ConfigService<T extends BaseConfig> {
|
|
|
140
159
|
|
|
141
160
|
writeConfigToFile(
|
|
142
161
|
{
|
|
143
|
-
|
|
162
|
+
fileFormat,
|
|
144
163
|
excludeSchema,
|
|
145
164
|
objectWrapper,
|
|
146
165
|
outputFolder
|
|
147
166
|
}: IWriteConfigToFileOptions = {
|
|
148
|
-
|
|
167
|
+
fileFormat: this.options.fileFormat,
|
|
149
168
|
excludeSchema: false
|
|
150
169
|
}) {
|
|
151
|
-
const fileExtension =
|
|
170
|
+
const fileExtension = fileFormat;
|
|
152
171
|
const configFileName = this.config.getFileName(fileExtension);
|
|
153
172
|
const configFileFullPath = join(
|
|
154
173
|
outputFolder || this.configFileRoot,
|
|
@@ -164,7 +183,7 @@ export class ConfigService<T extends BaseConfig> {
|
|
|
164
183
|
}
|
|
165
184
|
const orderedKeys = this.orderObjectKeys(plainConfig);
|
|
166
185
|
|
|
167
|
-
if (
|
|
186
|
+
if (fileFormat === 'yaml') {
|
|
168
187
|
const yamlValues = chain(orderedKeys)
|
|
169
188
|
.omit([ '$schema' ])
|
|
170
189
|
// eslint-disable-next-line no-undefined
|
|
@@ -193,7 +212,16 @@ export class ConfigService<T extends BaseConfig> {
|
|
|
193
212
|
{ [objectWrapper]: orderedKeys } :
|
|
194
213
|
orderedKeys;
|
|
195
214
|
|
|
196
|
-
|
|
215
|
+
if (fileFormat === 'hjson') {
|
|
216
|
+
writeFileSync(configFileFullPath, hjsonStringify(output, {
|
|
217
|
+
quotes: 'min',
|
|
218
|
+
space: 2
|
|
219
|
+
}));
|
|
220
|
+
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
writeJSONSync(configFileFullPath, output, { spaces: 2 });
|
|
197
225
|
|
|
198
226
|
for (const sharedConfig of this.options.sharedConfig) {
|
|
199
227
|
this.writeSharedConfigToFile(sharedConfig);
|
|
@@ -221,7 +249,7 @@ export class ConfigService<T extends BaseConfig> {
|
|
|
221
249
|
});
|
|
222
250
|
|
|
223
251
|
const nconfFileOptions: nconf.IFileOptions = {
|
|
224
|
-
format: this.options.
|
|
252
|
+
format: nconfFormats[this.options.fileFormat]
|
|
225
253
|
};
|
|
226
254
|
|
|
227
255
|
if (this.options.encryptConfig) {
|
|
@@ -340,7 +368,7 @@ export class ConfigService<T extends BaseConfig> {
|
|
|
340
368
|
|
|
341
369
|
const orderedKeys = this.orderObjectKeys(plainConfig);
|
|
342
370
|
|
|
343
|
-
if (this.options.
|
|
371
|
+
if (this.options.fileFormat === 'yaml') {
|
|
344
372
|
const yamlValues = chain(orderedKeys)
|
|
345
373
|
.omit([ '$schema' ])
|
|
346
374
|
// eslint-disable-next-line no-undefined
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IsEnum, IsOptional } from 'class-validator';
|
|
1
|
+
import { IsBoolean, IsEnum, IsOptional } from 'class-validator';
|
|
2
2
|
import { values } from 'lodash';
|
|
3
3
|
|
|
4
4
|
import { BaseConfig, Configuration, ConfigVariable } from './';
|
|
@@ -24,5 +24,10 @@ export class PizzaConfig extends BaseConfig {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
@Configuration()
|
|
28
|
+
export class ToppingsConfig extends BaseConfig {
|
|
29
|
+
@IsOptional()
|
|
30
|
+
@IsBoolean()
|
|
31
|
+
@ConfigVariable('Should meat be included in the toppings options')
|
|
32
|
+
INCLUDE_MEAT;
|
|
33
|
+
}
|