config(schema): export mergeConfigSchemas from config-loader for use by backstage-cli config:schema.

Signed-off-by: Andreas Stenius <git@astekk.se>
This commit is contained in:
Andreas Stenius
2021-02-19 14:43:25 +01:00
parent 4b01c7caaf
commit 0e0d0595ea
4 changed files with 46 additions and 26 deletions
+2 -1
View File
@@ -17,6 +17,7 @@
import { Command } from 'commander';
import { stringify as stringifyYaml } from 'yaml';
import { loadCliConfig } from '../../lib/config';
import { mergeConfigSchemas } from '@backstage/config-loader';
export default async (cmd: Command) => {
const { schema } = await loadCliConfig({
@@ -25,7 +26,7 @@ export default async (cmd: Command) => {
mockEnv: true,
});
const data = schema.serialize();
const { schema: data } = mergeConfigSchemas(schema.serialize().schemas);
if (cmd.format === 'json') {
process.stdout.write(`${JSON.stringify(data, null, 2)}\n`);
+1 -1
View File
@@ -14,7 +14,7 @@
* limitations under the License.
*/
export { readEnvConfig, loadConfigSchema } from './lib';
export { readEnvConfig, loadConfigSchema, mergeConfigSchemas } from './lib';
export type { ConfigSchema, ConfigVisibility } from './lib';
export { loadConfig } from './loader';
export type { LoadConfigOptions } from './loader';
@@ -35,6 +35,44 @@ 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 } {
// 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.
@@ -108,29 +146,9 @@ export function compileConfigSchemas(
},
);
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),
};
return {
schema: merged,
parser: ajv,
visibilityByPath,
};
}
@@ -14,5 +14,6 @@
* limitations under the License.
*/
export { mergeConfigSchemas } from './compile';
export { loadConfigSchema } from './load';
export type { ConfigSchema, ConfigVisibility } from './types';