config-loader: add support for serializing and deserializing schema
This commit is contained in:
@@ -15,5 +15,6 @@
|
||||
*/
|
||||
|
||||
export { readEnvConfig, loadConfigSchema } from './lib';
|
||||
export type { ConfigSchema } from './lib';
|
||||
export { loadConfig } from './loader';
|
||||
export type { LoadConfigOptions } from './loader';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user