config-loader: throw error rather than silently ignore invalid config

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-07-28 15:53:27 +02:00
parent 425b386e13
commit 2f18595859
2 changed files with 31 additions and 5 deletions
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/config-loader': minor
---
Loading invalid TypeScript configuration schemas will now throw an error rather than silently being ignored.
In particular this includes defining any additional types other than `Config` in the schema file, or use of unsupported types such as `Record` or `Partial`.
+24 -5
View File
@@ -15,6 +15,7 @@
*/
import fs from 'fs-extra';
import { EOL } from 'os';
import {
resolve as resolvePath,
relative as relativePath,
@@ -163,7 +164,7 @@ async function compileTsSchemas(paths: string[]) {
// Lazy loaded, because this brings up all of TypeScript and we don't
// want that eagerly loaded in tests
const { getProgramFromFiles, generateSchema } = await import(
const { getProgramFromFiles, buildGenerator } = await import(
'typescript-json-schema'
);
@@ -183,17 +184,35 @@ async function compileTsSchemas(paths: string[]) {
const tsSchemas = paths.map(path => {
let value;
try {
value = generateSchema(
const generator = buildGenerator(
program,
// All schemas should export a `Config` symbol
'Config',
// This enables the use of these tags in TSDoc comments
{
required: true,
validationKeywords: ['visibility', 'deepVisibility', 'deprecated'],
},
[path.split(sep).join('/')], // Unix paths are expected for all OSes here
) as JsonObject | null;
);
const userSymbols = new Set(generator?.getUserSymbols());
userSymbols.delete('Config');
if (userSymbols.size !== 0) {
const names = Array.from(userSymbols).join("', '");
throw new Error(
`Invalid configuration schema in ${path}, additional symbol definitions are not allowed, found '${names}'`,
);
}
// All schemas should export a `Config` symbol
value = generator?.getSchemaForSymbol('Config') as JsonObject | null;
const reffedDefs = Object.keys(generator?.ReffedDefinitions ?? {});
if (reffedDefs.length !== 0) {
const lines = reffedDefs.join(`${EOL} `);
throw new Error(
`Invalid configuration schema in ${path}, the following definitions are not supported:${EOL}${EOL} ${lines}`,
);
}
} catch (error) {
assertError(error);
if (error.message !== 'type Config not found') {