@axinom/mosaic-cli 0.14.2-rc.8 → 0.15.0-rc.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.
Files changed (76) hide show
  1. package/package.json +6 -5
  2. package/src/cli/README.md +60 -0
  3. package/src/cli/index.ts +47 -0
  4. package/src/commands/apply-templates/apply-templates.spec.ts +623 -0
  5. package/src/commands/apply-templates/apply-templates.ts +494 -0
  6. package/src/commands/apply-templates/bitwarden-vault.ts +130 -0
  7. package/src/commands/apply-templates/index.ts +1 -0
  8. package/src/commands/create-extension-config/create-extension-config.ts +92 -0
  9. package/src/commands/create-extension-config/index.ts +23 -0
  10. package/src/commands/get-access-token/get-access-token-options.ts +9 -0
  11. package/src/commands/get-access-token/get-dev-access-token.ts +32 -0
  12. package/src/commands/get-access-token/index.ts +66 -0
  13. package/src/commands/graphql-diff.ts +143 -0
  14. package/src/commands/msg-codegen/codegen.ts +891 -0
  15. package/src/commands/msg-codegen/index.ts +48 -0
  16. package/src/commands/msg-codegen/lint.ts +84 -0
  17. package/src/commands/msg-codegen/message-codegen-options.ts +7 -0
  18. package/src/commands/msg-diff/asyncapi-override.ts +31 -0
  19. package/src/commands/msg-diff/git-checkout-tmp.ts +73 -0
  20. package/src/commands/msg-diff/index.ts +53 -0
  21. package/src/commands/msg-diff/message-diff-options.ts +7 -0
  22. package/src/commands/msg-diff/msg-diff.spec.ts +412 -0
  23. package/src/commands/msg-diff/msg-diff.ts +364 -0
  24. package/src/commands/msg-diff/test-resources/0/1-asyncapi.yml +38 -0
  25. package/src/commands/msg-diff/test-resources/0/2-asyncapi.yml +36 -0
  26. package/src/commands/msg-diff/test-resources/0/command.json +74 -0
  27. package/src/commands/msg-diff/test-resources/0/event.json +25 -0
  28. package/src/commands/msg-diff/test-resources/1/1-asyncapi.yml +25 -0
  29. package/src/commands/msg-diff/test-resources/1/moved-event.json +25 -0
  30. package/src/commands/msg-diff/test-resources/common.json +20 -0
  31. package/src/commands/pg-dump/README.md +21 -0
  32. package/src/commands/pg-dump/generate.ts +146 -0
  33. package/src/commands/pg-dump/index.ts +39 -0
  34. package/src/commands/pg-dump/pg-dump-options.ts +6 -0
  35. package/src/commands/publish-schema-to-db/README.md +130 -0
  36. package/src/commands/publish-schema-to-db/abstractions/base-smart-tags.ts +6 -0
  37. package/src/commands/publish-schema-to-db/abstractions/index.ts +5 -0
  38. package/src/commands/publish-schema-to-db/abstractions/pg-column.ts +31 -0
  39. package/src/commands/publish-schema-to-db/abstractions/pg-fk-column.ts +6 -0
  40. package/src/commands/publish-schema-to-db/abstractions/pg-table.ts +55 -0
  41. package/src/commands/publish-schema-to-db/abstractions/pg-type.ts +8 -0
  42. package/src/commands/publish-schema-to-db/content-entity-model.ts +93 -0
  43. package/src/commands/publish-schema-to-db/generate.ts +82 -0
  44. package/src/commands/publish-schema-to-db/index.ts +49 -0
  45. package/src/commands/publish-schema-to-db/jest.config.js +9 -0
  46. package/src/commands/publish-schema-to-db/pg-models/columns/fk-column.spec.ts +42 -0
  47. package/src/commands/publish-schema-to-db/pg-models/columns/fk-column.ts +41 -0
  48. package/src/commands/publish-schema-to-db/pg-models/columns/index.ts +4 -0
  49. package/src/commands/publish-schema-to-db/pg-models/columns/pk-column.spec.ts +47 -0
  50. package/src/commands/publish-schema-to-db/pg-models/columns/pk-column.ts +34 -0
  51. package/src/commands/publish-schema-to-db/pg-models/columns/primitive-column.spec.ts +65 -0
  52. package/src/commands/publish-schema-to-db/pg-models/columns/primitive-column.ts +62 -0
  53. package/src/commands/publish-schema-to-db/pg-models/columns/virtual-fk-column.spec.ts +24 -0
  54. package/src/commands/publish-schema-to-db/pg-models/columns/virtual-fk-column.ts +34 -0
  55. package/src/commands/publish-schema-to-db/pg-models/json-schema-parse-utils.spec.ts +182 -0
  56. package/src/commands/publish-schema-to-db/pg-models/json-schema-parse-utils.ts +166 -0
  57. package/src/commands/publish-schema-to-db/pg-models/pg-sql-gen-utils.spec.ts +19 -0
  58. package/src/commands/publish-schema-to-db/pg-models/pg-sql-gen-utils.ts +237 -0
  59. package/src/commands/publish-schema-to-db/pg-models/pgl-utils.spec.ts +19 -0
  60. package/src/commands/publish-schema-to-db/pg-models/pgl-utils.ts +115 -0
  61. package/src/commands/publish-schema-to-db/pg-models/tables/content-entity-table.ts +104 -0
  62. package/src/commands/publish-schema-to-db/pg-models/tables/index.ts +3 -0
  63. package/src/commands/publish-schema-to-db/pg-models/tables/object-property-table.ts +113 -0
  64. package/src/commands/publish-schema-to-db/pg-models/tables/relations-table.ts +115 -0
  65. package/src/commands/publish-schema-to-db/postprocessors/collection-postprocessor.ts +33 -0
  66. package/src/commands/publish-schema-to-db/postprocessors/content-entity-model-postprocessor.ts +13 -0
  67. package/src/commands/publish-schema-to-db/postprocessors/episode-postprocessor.ts +37 -0
  68. package/src/commands/publish-schema-to-db/postprocessors/index.ts +6 -0
  69. package/src/commands/publish-schema-to-db/postprocessors/movie-postprocessor.ts +30 -0
  70. package/src/commands/publish-schema-to-db/postprocessors/postprocessing-utils.ts +21 -0
  71. package/src/commands/publish-schema-to-db/postprocessors/season-postprocessor.ts +37 -0
  72. package/src/commands/publish-schema-to-db/postprocessors/tvshow-postprocessor.ts +30 -0
  73. package/src/commands/publish-schema-to-db/publish-schema-to-db-options.ts +15 -0
  74. package/src/commands/publish-schema-to-db/types/sql-formatter.d.ts +10 -0
  75. package/src/exports.ts +2 -0
  76. package/src/index.ts +1 -0
@@ -0,0 +1,623 @@
1
+ import * as envfile from 'envfile';
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
3
+ import 'jest-extended';
4
+ import {
5
+ ConfigTransform,
6
+ EnvConfigTransform,
7
+ getEnvConfigTransforms,
8
+ transformComparison,
9
+ } from './apply-templates';
10
+ import { Vault } from './bitwarden-vault';
11
+
12
+ // mock file system functions
13
+ let mockFiles: Record<string, string> = {};
14
+ jest.mock('fs', () => ({
15
+ existsSync: jest.fn((f) => f.toString() in mockFiles),
16
+ readFileSync: jest.fn((f, _) => mockFiles[f.toString()]),
17
+ copyFileSync: jest.fn((f1, f2) => (mockFiles[f2] = mockFiles[f1])),
18
+ writeFileSync: jest.fn((f, c) => (mockFiles[f.toString()] = c)),
19
+ readdirSync: jest.fn((_) => Object.keys(mockFiles)),
20
+ }));
21
+
22
+ class MockVault implements Vault {
23
+ constructor(
24
+ private values: Record<string, string> = {
25
+ 'item1::username': 'Username from vault',
26
+ 'item1::password': 'Password from vault',
27
+ },
28
+ ) {}
29
+ error = undefined;
30
+ getValue(name: string, fieldName: string): string | undefined {
31
+ const key = `${name}::${fieldName}`;
32
+ return key in this.values ? this.values[key] : undefined;
33
+ }
34
+ }
35
+
36
+ // .env file helpers
37
+ const loadEnv = (name: string): Record<string, string> =>
38
+ envfile.parse(readFileSync(name, name).toString());
39
+ const saveEnv = (
40
+ name: string,
41
+ vars: Record<string, string>,
42
+ prefix = '',
43
+ ): void => writeFileSync(name, prefix + envfile.stringify(vars));
44
+
45
+ describe('applyTemplates', () => {
46
+ beforeEach(() => {
47
+ mockFiles = {};
48
+ });
49
+
50
+ describe('sanity', () => {
51
+ it('mock file system sanity', () => {
52
+ // blank filename is invalid for real files but is accepted by the mock
53
+ writeFileSync('', 'test-content');
54
+
55
+ // Assert
56
+ expect(existsSync('')).toBeTrue();
57
+ expect(readFileSync('').toString()).toBe('test-content');
58
+ });
59
+ });
60
+
61
+ describe('compareTemplate (.env)', () => {
62
+ it('target exists -> same', () => {
63
+ // Arrange
64
+ const template = {
65
+ VAR1: '1',
66
+ VAR2: '2',
67
+ };
68
+ const prefix = '#@TEMPLATE = 1.env.template\n';
69
+ saveEnv('1.env.template', template);
70
+ saveEnv('1.env', template, prefix);
71
+
72
+ // Act
73
+ const result = transformComparison(
74
+ new EnvConfigTransform('1.env.template', '1.env'),
75
+ false,
76
+ false,
77
+ );
78
+
79
+ // Assert
80
+ expect(result).toBe('same');
81
+ expect(loadEnv('1.env.template')).toEqual(template);
82
+ expect(loadEnv('1.env')).toEqual(template);
83
+ });
84
+
85
+ it('no target -> created', () => {
86
+ // Arrange
87
+ const template = {
88
+ VAR1: '1',
89
+ VAR2: '2',
90
+ };
91
+ saveEnv('1.env.template', template);
92
+
93
+ // Act
94
+ const result = transformComparison(
95
+ new EnvConfigTransform('1.env.template', '1.env'),
96
+ false,
97
+ false,
98
+ );
99
+
100
+ // Assert
101
+ expect(result).toBe('created');
102
+ expect(loadEnv('1.env.template')).toEqual(template);
103
+ expect(loadEnv('1.env')).toEqual(template);
104
+ });
105
+
106
+ it('target with differences -> different', () => {
107
+ // Arrange
108
+ const template =
109
+ 'VAR1=1\n' +
110
+ 'VAR2=2\n' +
111
+ 'VAR3=3\n' +
112
+ 'VAR4=<BITWARDEN_{placeholder}>\n' +
113
+ 'VAR5=<BITWARDEN_{placeholder}>\n' +
114
+ 'VAR6=\n' +
115
+ 'VAR7=\n';
116
+ const target =
117
+ 'VAR1=1\n' +
118
+ 'VAR2=Old value\n' +
119
+ '#VAR3=3\n' +
120
+ 'VAR3=Custom value\n' +
121
+ 'VAR4=Placeholder replaced\n' +
122
+ 'VAR6=Blank value replaced\n' +
123
+ 'VAR8=My new value\n';
124
+ const prefix = '#@TEMPLATE = 1.env.template\n';
125
+ writeFileSync('1.env.template', template);
126
+ writeFileSync('1.env', target, prefix);
127
+
128
+ // Act
129
+ const transform = new EnvConfigTransform('1.env.template', '1.env');
130
+ const result = transformComparison(transform, false, false);
131
+ transform.writeTarget();
132
+
133
+ // Assert
134
+ expect(result).toBe('different');
135
+ expect(readFileSync('1.env').toString()).toEqual(
136
+ prefix +
137
+ 'VAR1=1\n' +
138
+ 'VAR2=2\n' +
139
+ '#VAR3=3\n' +
140
+ 'VAR3=Custom value\n' +
141
+ 'VAR4=Placeholder replaced\n' +
142
+ 'VAR5=<BITWARDEN_{placeholder}>\n' +
143
+ 'VAR6=Blank value replaced\n' +
144
+ 'VAR7=\n' +
145
+ '\n' +
146
+ '\n' +
147
+ '# Additional keys (not in template)\n' +
148
+ 'VAR8=My new value\n',
149
+ );
150
+ });
151
+
152
+ it('replace option used -> different', () => {
153
+ // Arrange
154
+ const template =
155
+ 'VAR1=1\n' +
156
+ 'VAR2=2\n' +
157
+ 'VAR3=3\n' +
158
+ 'VAR4=<BITWARDEN_{placeholder}>\n' +
159
+ 'VAR5=<BITWARDEN_{placeholder}>\n' +
160
+ 'VAR6=\n' +
161
+ 'VAR7=\n';
162
+ const prefix = '#@TEMPLATE = 1.env.template\n';
163
+ const target =
164
+ prefix +
165
+ 'VAR1=1\n' +
166
+ 'VAR2=Old value\n' +
167
+ '#VAR3=3\n' +
168
+ 'VAR3=Custom value\n' +
169
+ 'VAR4=Placeholder replaced\n' +
170
+ 'VAR6=Blank value replaced\n' +
171
+ 'VAR8=My new value\n';
172
+ writeFileSync('1.env.template', template);
173
+ writeFileSync('1.env', target);
174
+
175
+ // Act
176
+ const transform = new EnvConfigTransform('1.env.template', '1.env');
177
+ const result = transformComparison(transform, true, false);
178
+ transform.writeTarget();
179
+
180
+ // Assert
181
+ expect(result).toBe('different');
182
+ expect(readFileSync('1.env').toString()).toEqual(prefix + template);
183
+ });
184
+
185
+ it('comment changes -> different-layout', () => {
186
+ // Arrange
187
+ const template =
188
+ '# some comment\n' +
189
+ 'BLAH=1\n' +
190
+ '# a new comment\n' +
191
+ 'BAR=2\n' +
192
+ 'FOO=3';
193
+ const target0 =
194
+ '#@TEMPLATE = 1.env.template\n' +
195
+ '# some slightly different comment\n' +
196
+ 'BLAH=1\n' +
197
+ 'BAR=2\n' +
198
+ 'FOO=3\n';
199
+ writeFileSync('1.env.template', template);
200
+ writeFileSync('1.env', target0);
201
+
202
+ // Act
203
+ const result = transformComparison(
204
+ new EnvConfigTransform('1.env.template', '1.env'),
205
+ false,
206
+ false,
207
+ );
208
+
209
+ // Assert
210
+ expect(result).toBe('differentLayout');
211
+ expect(readFileSync('1.env.template').toString()).toEqual(template);
212
+ expect(readFileSync('1.env').toString()).toEqual(target0);
213
+ });
214
+
215
+ it('whitespace changes -> different-layout', () => {
216
+ // Arrange
217
+ const template =
218
+ '# a really really interesting comment\n' +
219
+ 'BLAH=1\n' +
220
+ 'FOO=2\n' +
221
+ 'BAR=3\n';
222
+ const target0 =
223
+ '#@TEMPLATE = 1.env.template\n' +
224
+ '# a really really interesting comment\n' +
225
+ 'BLAH=1\n' +
226
+ '\n' +
227
+ 'FOO=2\n' +
228
+ '\n' +
229
+ 'BAR=3\n';
230
+ writeFileSync('1.env.template', template);
231
+ writeFileSync('1.env', target0);
232
+
233
+ // Act
234
+ const result = transformComparison(
235
+ new EnvConfigTransform('1.env.template', '1.env'),
236
+ false,
237
+ false,
238
+ );
239
+
240
+ // Assert
241
+ expect(result).toBe('differentLayout');
242
+ expect(readFileSync('1.env.template').toString()).toEqual(template);
243
+ expect(readFileSync('1.env').toString()).toEqual(target0);
244
+ });
245
+
246
+ it('ordering changes -> different-layout', () => {
247
+ // Arrange
248
+ const template =
249
+ '# a really really interesting comment\n' +
250
+ 'BLAH=1\n' +
251
+ 'FOO=2\n' +
252
+ 'BAR=3\n';
253
+ const target0 =
254
+ '#@TEMPLATE = 1.env.template\n' +
255
+ 'FOO=2\n' +
256
+ 'BLAH=1\n' +
257
+ 'BAR=3\n' +
258
+ '# a really really interesting comment\n';
259
+ writeFileSync('1.env.template', template);
260
+ writeFileSync('1.env', target0);
261
+
262
+ // Act
263
+ const result = transformComparison(
264
+ new EnvConfigTransform('1.env.template', '1.env'),
265
+ false,
266
+ false,
267
+ );
268
+
269
+ // Assert
270
+ expect(result).toBe('differentLayout');
271
+ expect(readFileSync('1.env.template').toString()).toEqual(template);
272
+ expect(readFileSync('1.env').toString()).toEqual(target0);
273
+ });
274
+
275
+ it('new target created -> created (with added template directive)', () => {
276
+ // Arrange
277
+ const template = 'BLAH=1\n' + 'FOO=2\n' + 'BAR=3\n';
278
+ writeFileSync('1.env.template', template);
279
+
280
+ // Act
281
+ const transform = new EnvConfigTransform('1.env.template', '1.env');
282
+ const result = transformComparison(transform, false, false);
283
+ transform.writeTarget();
284
+
285
+ const expectedTarget = '#@TEMPLATE = 1.env.template\n' + template;
286
+
287
+ // Assert
288
+ expect(result).toBe('created');
289
+ expect(readFileSync('1.env.template').toString()).toEqual(template);
290
+ expect(readFileSync('1.env').toString()).toEqual(expectedTarget);
291
+ });
292
+
293
+ it('target without template directive -> different-layout', () => {
294
+ // Arrange
295
+ const template = 'BLAH=1\n' + 'FOO=2\n' + 'BAR=3\n';
296
+ writeFileSync('1.env.template', template);
297
+ writeFileSync('1.env', template);
298
+
299
+ // Act
300
+ const transform = new EnvConfigTransform('1.env.template', '1.env');
301
+ const result = transformComparison(transform, false, false);
302
+ transform.writeTarget();
303
+
304
+ const expectedTarget = '#@TEMPLATE = 1.env.template\n' + template;
305
+
306
+ // Assert
307
+ expect(result).toBe('differentLayout');
308
+ expect(readFileSync('1.env.template').toString()).toEqual(template);
309
+ expect(readFileSync('1.env').toString()).toEqual(expectedTarget);
310
+ });
311
+
312
+ it('target with template directive -> same', () => {
313
+ // Arrange
314
+ const template = 'BLAH=1\n' + 'FOO=2\n' + 'BAR=3\n';
315
+ const target = '#@TEMPLATE = 1.env.template\n' + template;
316
+ writeFileSync('1.env.template', template);
317
+ writeFileSync('1.env', target);
318
+
319
+ // Act
320
+ const transform = new EnvConfigTransform('1.env.template', '1.env');
321
+ const result = transformComparison(transform, false, false);
322
+ transform.writeTarget();
323
+
324
+ // Assert
325
+ expect(result).toBe('same');
326
+ expect(readFileSync('1.env.template').toString()).toEqual(template);
327
+ expect(readFileSync('1.env').toString()).toEqual(target);
328
+ });
329
+ });
330
+
331
+ describe('compareTemplate (.env, bitwarden)', () => {
332
+ it('no target -> created with placeholders resolved', () => {
333
+ // Arrange
334
+ const template = {
335
+ VAR1: '1',
336
+ VAR2: '<BITWARDEN_{item1::username}>',
337
+ };
338
+ const target = {
339
+ VAR1: '1',
340
+ VAR2: 'Username from vault',
341
+ };
342
+ saveEnv('1.env.template', template);
343
+
344
+ // Act
345
+ const result = transformComparison(
346
+ new EnvConfigTransform('1.env.template', '1.env', new MockVault()),
347
+ false,
348
+ false,
349
+ );
350
+
351
+ // Assert
352
+ expect(result).toBe('created');
353
+ expect(loadEnv('1.env.template')).toEqual(template);
354
+ expect(loadEnv('1.env')).toEqual(target);
355
+ });
356
+
357
+ it('placeholder not resolved in target -> different', () => {
358
+ // Arrange
359
+ const template = {
360
+ VAR1: '1',
361
+ VAR2: '<BITWARDEN_{item1::username}>',
362
+ };
363
+ saveEnv('1.env.template', template);
364
+ saveEnv('1.env', template);
365
+
366
+ // Act
367
+ const transform = new EnvConfigTransform(
368
+ '1.env.template',
369
+ '1.env',
370
+ new MockVault(),
371
+ );
372
+ const result = transformComparison(transform, false, false);
373
+ transform.writeTarget();
374
+
375
+ // Assert
376
+ expect(result).toBe('different');
377
+ expect(loadEnv('1.env.template')).toEqual(template);
378
+ expect(loadEnv('1.env')).toEqual({
379
+ VAR1: '1',
380
+ VAR2: 'Username from vault',
381
+ });
382
+ });
383
+
384
+ it('target exists with placeholders resolved -> same', () => {
385
+ // Arrange
386
+ const template = {
387
+ VAR1: '1',
388
+ VAR2: '<BITWARDEN_{item1::username}>',
389
+ };
390
+ const target = {
391
+ VAR1: '1',
392
+ VAR2: 'Username from vault',
393
+ };
394
+ saveEnv('1.env.template', template);
395
+ saveEnv('1.env', target, '#@TEMPLATE = 1.env.template\n');
396
+
397
+ // Act
398
+ const result = transformComparison(
399
+ new EnvConfigTransform('1.env.template', '1.env', new MockVault()),
400
+ false,
401
+ false,
402
+ );
403
+
404
+ // Assert
405
+ expect(result).toBe('same');
406
+ expect(loadEnv('1.env.template')).toEqual(template);
407
+ expect(loadEnv('1.env')).toEqual(target);
408
+ });
409
+
410
+ it('vault value changed -> different', () => {
411
+ // Arrange
412
+ const template = {
413
+ VAR1: '1',
414
+ VAR2: '<BITWARDEN_{item1::username}>',
415
+ };
416
+ const target = {
417
+ VAR1: '1',
418
+ VAR2: 'Old value from vault',
419
+ };
420
+ saveEnv('1.env.template', template);
421
+ saveEnv('1.env', target);
422
+
423
+ // Act
424
+ const transform = new EnvConfigTransform(
425
+ '1.env.template',
426
+ '1.env',
427
+ new MockVault(),
428
+ );
429
+ const result = transformComparison(transform, false, false);
430
+ transform.writeTarget();
431
+
432
+ // Assert
433
+ expect(result).toBe('different');
434
+ expect(loadEnv('1.env.template')).toEqual(template);
435
+ expect(loadEnv('1.env')).toEqual({
436
+ VAR1: '1',
437
+ VAR2: 'Username from vault',
438
+ });
439
+ });
440
+ });
441
+
442
+ describe('getEnvConfigTargets (.env)', () => {
443
+ it('no template directive -> default target updated', () => {
444
+ // Arrange
445
+ writeFileSync('1.env', 'x');
446
+ writeFileSync('2.env', 'x');
447
+
448
+ // Act
449
+ const targets = getEnvConfigTransforms('2.env.template');
450
+
451
+ // Assert
452
+ expect(targets).toIncludeAllMembers(['2.env']);
453
+ });
454
+
455
+ it('no template directive -> missing default target is created', () => {
456
+ // Arrange
457
+ writeFileSync('2.env', 'x');
458
+
459
+ // Act
460
+ const targets = getEnvConfigTransforms('1.env.template');
461
+
462
+ // Assert
463
+ expect(targets).toIncludeAllMembers(['1.env']);
464
+ });
465
+
466
+ it('template directive defined -> defined target used', () => {
467
+ // Arrange
468
+ writeFileSync('1.env', '#@TEMPLATE = 2.env.template\n');
469
+ writeFileSync('2.env', '#@TEMPLATE = 1.env.template\n');
470
+
471
+ // Act
472
+ const targets = getEnvConfigTransforms('1.env.template');
473
+
474
+ // Assert
475
+ expect(targets).toIncludeAllMembers(['2.env']);
476
+ });
477
+
478
+ it('template directive defined -> default and defined target updated', () => {
479
+ // Arrange
480
+ writeFileSync('1.env', 'x');
481
+ writeFileSync('2.env', '#@TEMPLATE = 1.env.template\n');
482
+
483
+ // Act
484
+ const targets = getEnvConfigTransforms('1.env.template');
485
+
486
+ // Assert
487
+ expect(targets).toIncludeAllMembers(['1.env', '2.env']);
488
+ });
489
+
490
+ it('template directive defined -> missing default target is not created', () => {
491
+ // Arrange
492
+ writeFileSync('2.env', '#@TEMPLATE = 1.env.template\n');
493
+
494
+ // Act
495
+ const targets = getEnvConfigTransforms('1.env.template');
496
+
497
+ // Assert
498
+ expect(targets).toIncludeAllMembers(['2.env']);
499
+ });
500
+
501
+ it('template directive defined on default target -> target not updated', () => {
502
+ // Arrange
503
+ writeFileSync('1.env', '#@TEMPLATE = 2.env.template\n');
504
+
505
+ // Act
506
+ const targets = getEnvConfigTransforms('1.env.template');
507
+
508
+ // Assert
509
+ expect(targets).toIncludeAllMembers([]);
510
+ });
511
+
512
+ it('multiple targets with directive defined -> all targets updated', () => {
513
+ // Arrange
514
+ writeFileSync('2.env', '#@TEMPLATE = 1.env.template\n');
515
+ writeFileSync('3.env', '#@TEMPLATE = 1.env.template\n');
516
+
517
+ // Act
518
+ const targets = getEnvConfigTransforms('1.env.template');
519
+
520
+ // Assert
521
+ expect(targets).toIncludeAllMembers(['2.env', '3.env']);
522
+ });
523
+
524
+ it('template directive malformed -> directive ignored', () => {
525
+ // Arrange
526
+ writeFileSync('1.env', '#@@TEMPLATE = 2.env.template\n');
527
+ writeFileSync('2.env', '#@@TEMPLATE = 1.env.template\n');
528
+
529
+ // Act
530
+ const targets = getEnvConfigTransforms('1.env.template');
531
+
532
+ // Assert
533
+ expect(targets).toIncludeAllMembers(['1.env']);
534
+ });
535
+
536
+ it('template directive bad filename -> target ignored', () => {
537
+ // Arrange
538
+ writeFileSync('1.env', '#@TEMPLATE = 3.env.template\n');
539
+ writeFileSync('2.env', '#@TEMPLATE = 3.env.template\n');
540
+
541
+ // Act
542
+ const targets = getEnvConfigTransforms('1.env.template');
543
+
544
+ // Assert
545
+ expect(targets).toIncludeAllMembers([]);
546
+ });
547
+ });
548
+
549
+ describe('compareTemplate (not .env)', () => {
550
+ it('target exists -> same', () => {
551
+ // Arrange
552
+ const template = `
553
+ BLAH
554
+ FOO
555
+ BAR
556
+ `;
557
+ writeFileSync('1.template', template);
558
+ writeFileSync('1', template);
559
+
560
+ // Act
561
+ const result = transformComparison(
562
+ new ConfigTransform('1.template', '1'),
563
+ false,
564
+ false,
565
+ );
566
+
567
+ // Assert
568
+ expect(result).toBe('same');
569
+ expect(readFileSync('1.template').toString()).toEqual(template);
570
+ expect(readFileSync('1').toString()).toEqual(template);
571
+ });
572
+
573
+ it('no target -> created', () => {
574
+ // Arrange
575
+ const template = `
576
+ BLAH
577
+ FOO
578
+ BAR
579
+ `;
580
+ writeFileSync('1.template', template);
581
+
582
+ // Act
583
+ const result = transformComparison(
584
+ new ConfigTransform('1.template', '1'),
585
+ false,
586
+ false,
587
+ );
588
+
589
+ // Assert
590
+ expect(result).toBe('created');
591
+ expect(readFileSync('1.template').toString()).toEqual(template);
592
+ expect(readFileSync('1').toString()).toEqual(template);
593
+ });
594
+
595
+ it('target with differences -> different', () => {
596
+ // Arrange
597
+ const template = `
598
+ BLAH
599
+ FOO
600
+ BAR
601
+ `;
602
+ const target0 = `
603
+ BLAH
604
+ BAR
605
+ FOO
606
+ `;
607
+ writeFileSync('1.template', template);
608
+ writeFileSync('1', target0);
609
+
610
+ // Act
611
+ const result = transformComparison(
612
+ new ConfigTransform('1.template', '1'),
613
+ false,
614
+ false,
615
+ );
616
+
617
+ // Assert
618
+ expect(result).toBe('different');
619
+ expect(readFileSync('1.template').toString()).toEqual(template);
620
+ expect(readFileSync('1').toString()).toEqual(target0);
621
+ });
622
+ });
623
+ });