config-loader: add support for serializing and deserializing schema

This commit is contained in:
Patrik Oldsberg
2020-11-09 00:19:30 +01:00
parent 564f438edd
commit 3849e24112
6 changed files with 46 additions and 16 deletions
+1
View File
@@ -15,5 +15,6 @@
*/
export { readEnvConfig, loadConfigSchema } from './lib';
export type { ConfigSchema } from './lib';
export { loadConfig } from './loader';
export type { LoadConfigOptions } from './loader';
+1 -1
View File
@@ -17,4 +17,4 @@
export { readConfigFile } from './reader';
export { readEnvConfig } from './env';
export { readSecret } from './secrets';
export { loadConfigSchema } from './schema';
export * from './schema';
@@ -15,7 +15,11 @@
*/
import fs from 'fs-extra';
import { resolve as resolvePath, dirname } from 'path';
import {
resolve as resolvePath,
relative as relativePath,
dirname,
} from 'path';
import { ConfigSchemaPackageEntry } from './types';
type Item = {
@@ -36,8 +40,9 @@ export async function collectConfigSchemas(
): Promise<ConfigSchemaPackageEntry[]> {
const visitedPackages = new Set<string>();
const schemas = Array<ConfigSchemaPackageEntry>();
const currentDir = process.cwd();
async function process({ name, parentPath }: Item) {
async function processItem({ name, parentPath }: Item) {
// Ensures that we only process each package once. We don't bother with
// loading in schemas from duplicates of different versions, as that's not
// supported by Backstage right now anyway. We may want to change that in
@@ -81,22 +86,22 @@ export async function collectConfigSchemas(
);
schemas.push({
value,
path: pkgPath,
path: relativePath(currentDir, pkgPath),
});
} else {
schemas.push({
value: pkg.configSchema,
path: pkgPath,
path: relativePath(currentDir, pkgPath),
});
}
}
await Promise.all(
depNames.map(name => process({ name, parentPath: pkgPath })),
depNames.map(name => processItem({ name, parentPath: pkgPath })),
);
}
await Promise.all(packageNames.map(name => process({ name })));
await Promise.all(packageNames.map(name => processItem({ name })));
return schemas;
}
@@ -15,3 +15,4 @@
*/
export { loadConfigSchema } from './load';
export type { ConfigSchema } from './types';
+28 -6
View File
@@ -14,15 +14,19 @@
* limitations under the License.
*/
import { AppConfig } from '@backstage/config';
import { AppConfig, JsonObject } from '@backstage/config';
import { compileConfigSchemas } from './compile';
import { collectConfigSchemas } from './collect';
import { filterByVisibility } from './filtering';
import { ConfigSchema } from './types';
import { ConfigSchema, ConfigSchemaPackageEntry } from './types';
type Options = {
dependencies: string[];
};
type Options =
| {
dependencies: string[];
}
| {
serialized: JsonObject;
};
/**
* Loads config schema for a Backstage instance.
@@ -30,7 +34,19 @@ type Options = {
export async function loadConfigSchema(
options: Options,
): Promise<ConfigSchema> {
const schemas = await collectConfigSchemas(options.dependencies);
let schemas: ConfigSchemaPackageEntry[];
if ('dependencies' in options) {
schemas = await collectConfigSchemas(options.dependencies);
} else {
const { serialized } = options;
if (serialized?.backstageConfigSchemaVersion !== 1) {
throw new Error(
'Serialized configuration schema is invalid or has an invalid version number',
);
}
schemas = serialized.schemas as ConfigSchemaPackageEntry[];
}
const validate = compileConfigSchemas(schemas);
@@ -54,5 +70,11 @@ export async function loadConfigSchema(
return processedConfigs;
},
serialize(): JsonObject {
return {
schemas,
backstageConfigSchemaVersion: 1,
};
},
};
}
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import { AppConfig } from '@backstage/config';
import { JSONSchema7 as JSONSchema } from 'json-schema';
import { AppConfig, JsonObject } from '@backstage/config';
/**
* An sub-set of configuration schema.
@@ -24,7 +23,7 @@ export type ConfigSchemaPackageEntry = {
/**
* The configuration schema itself, as JSONSchema draft-07
*/
value: JSONSchema;
value: JsonObject;
/**
* The path that the configuration schema was discovered at.
*/
@@ -91,4 +90,6 @@ export type ConfigSchema = {
appConfigs: AppConfig[],
options?: ConfigProcessingOptions,
): AppConfig[];
serialize(): JsonObject;
};