cli(config:schema): cleanups.

Signed-off-by: Andreas Stenius <git@astekk.se>
This commit is contained in:
Andreas Stenius
2021-02-24 09:27:54 +01:00
parent 4548ed4e91
commit fb30fc103b
5 changed files with 46 additions and 64 deletions
+1 -5
View File
@@ -15,10 +15,6 @@
*/
export { readEnvConfig, loadConfigSchema, mergeConfigSchemas } from './lib';
export type {
ConfigSchema,
ConfigSchemaPackageEntry,
ConfigVisibility,
} from './lib';
export type { ConfigSchema, ConfigVisibility } from './lib';
export { loadConfig } from './loader';
export type { LoadConfigOptions } from './loader';
@@ -35,48 +35,6 @@ import {
export function compileConfigSchemas(
schemas: ConfigSchemaPackageEntry[],
): ValidationFunc {
const { schema: merged, parser: ajv, visibilityByPath } = mergeConfigSchemas(
schemas,
);
const validate = ajv.compile(merged);
return configs => {
const config = ConfigReader.fromConfigs(configs).get();
visibilityByPath.clear();
const valid = validate(config);
if (!valid) {
const errors = validate.errors ?? [];
return {
errors: errors.map(({ dataPath, message, params }) => {
const paramStr = Object.entries(params)
.map(([name, value]) => `${name}=${value}`)
.join(' ');
return `Config ${message || ''} { ${paramStr} } at ${dataPath}`;
}),
visibilityByPath: new Map(),
};
}
return {
visibilityByPath: new Map(visibilityByPath),
};
};
}
/**
* Given a list of configuration schemas from packages, merge them
* into a single json schema.
*/
export function mergeConfigSchemas(
schemas: ConfigSchemaPackageEntry[],
): {
schema: JSONSchema;
parser: Ajv;
visibilityByPath: Map<string, ConfigVisibility>;
} {
// The ajv instance below is stateful and doesn't really allow for additional
// output during validation. We work around this by having this extra piece
// of state that we reset before each validation.
@@ -119,8 +77,41 @@ export function mergeConfigSchemas(
}
}
const merged = mergeConfigSchemas(schemas.map(_ => _.value));
const validate = ajv.compile(merged);
return configs => {
const config = ConfigReader.fromConfigs(configs).get();
visibilityByPath.clear();
const valid = validate(config);
if (!valid) {
const errors = validate.errors ?? [];
return {
errors: errors.map(({ dataPath, message, params }) => {
const paramStr = Object.entries(params)
.map(([name, value]) => `${name}=${value}`)
.join(' ');
return `Config ${message || ''} { ${paramStr} } at ${dataPath}`;
}),
visibilityByPath: new Map(),
};
}
return {
visibilityByPath: new Map(visibilityByPath),
};
};
}
/**
* Given a list of configuration schemas from packages, merge them
* into a single json schema.
*/
export function mergeConfigSchemas(schemas: JSONSchema[]): JSONSchema {
const merged = mergeAllOf(
{ allOf: schemas.map(_ => _.value) },
{ allOf: schemas },
{
// JSONSchema is typically subtractive, as in it always reduces the set of allowed
// inputs through constraints. This changes the object property merging to be additive
@@ -149,10 +140,5 @@ export function mergeConfigSchemas(
} as Partial<Resolvers<JSONSchema>>,
},
);
return {
schema: merged,
parser: ajv,
visibilityByPath,
};
return merged;
}
@@ -16,8 +16,4 @@
export { mergeConfigSchemas } from './compile';
export { loadConfigSchema } from './load';
export type {
ConfigSchema,
ConfigSchemaPackageEntry,
ConfigVisibility,
} from './types';
export type { ConfigSchema, ConfigVisibility } from './types';