-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathvalidation.ts
More file actions
90 lines (76 loc) · 2.99 KB
/
validation.ts
File metadata and controls
90 lines (76 loc) · 2.99 KB
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
import { readdir } from 'fs-extra';
import { logger } from '@app-config/logging';
import { FileSource, EnvironmentAliases, defaultAliases } from '@app-config/node';
import { loadValidatedConfig } from '@app-config/config';
export interface Options {
/** Where app-config files are */
directory?: string;
/** Override for aliasing of environments */
environmentAliases?: EnvironmentAliases;
/** If app-config should be validating in a "no current environment" state */
includeNoEnvironment?: boolean;
}
/**
* Loads and validations app-config values in every environment detectable.
*
* Uses a hueristic to find which environments are available, because these are arbitrary.
*/
export async function validateAllConfigVariants({
directory = '.',
environmentAliases = defaultAliases,
includeNoEnvironment = false,
}: Options = {}) {
// first, we have to find any applicable app-config files
// this is less trivial than config loading, because we can't "assume" the current environment (it could be anything)
const filesInDirectory = await readdir(directory);
const appConfigFiles = filesInDirectory.filter((filename) =>
/^\.app-config\.(?:secrets\.)?(?:.*\.)?(?:yml|yaml|json|json5|toml)$/.exec(filename),
);
const appConfigEnvironments = new Set<string>();
for (const filename of appConfigFiles) {
// extract the environment out, which is the first capture group
const regex = /^\.app-config\.(?:secrets\.)?(.*)\.(?:yml|yaml|json|json5|toml)$/;
const environment = regex.exec(filename)?.[1];
if (environment && environment !== 'meta' && environment !== 'schema') {
appConfigEnvironments.add(environmentAliases[environment] ?? environment);
}
}
await Promise.all(
appConfigFiles.map(async (filename) => {
const parsed = await new FileSource(filename).read(undefined, { environmentAliases });
parsed.visitAll((value) => {
const obj = value.asObject();
if (obj?.$env) {
for (const key of Object.keys(obj.$env.asObject() ?? {})) {
appConfigEnvironments.add(environmentAliases[key] ?? key);
}
}
});
}),
);
// remove special-cased names
appConfigEnvironments.delete('default');
appConfigEnvironments.delete('secrets');
appConfigEnvironments.delete('schema');
appConfigEnvironments.delete('meta');
logger.info(
`Found ${appConfigEnvironments.size} environments to validate: [${Array.from(
appConfigEnvironments,
).join(', ')}]`,
);
for (const environment of appConfigEnvironments) {
logger.info(`Validating configuration for environment: ${environment}`);
await loadValidatedConfig({
directory,
environmentOverride: environment,
environmentVariableName: '', // do not load APP_CONFIG
});
}
if (includeNoEnvironment || appConfigEnvironments.size === 0) {
logger.info(`Validating configuration for no environment`);
await loadValidatedConfig({
directory,
environmentVariableName: '', // do not load APP_CONFIG
});
}
}