config-loader: Change loadConfig return type to object
Signed-off-by: Johan Haals <johan.haals@gmail.com>
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
---
|
||||
'@backstage/config-loader': minor
|
||||
---
|
||||
|
||||
Update `loadConfig` to return `LoadConfigResult` instead of an array of `AppConfig`.
|
||||
|
||||
This function is primarily used internally by other config loaders like `loadBackendConfig` which means no changes are required for most users.
|
||||
|
||||
If you use `loadConfig` directly you will need to update your usage from:
|
||||
|
||||
```diff
|
||||
- const appConfigs = await loadConfig(options)
|
||||
+ const { appConfigs } = await loadConfig(options)
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Update internal usage of `configLoader.loadConfig` that now returns an object instead of an array of configs.
|
||||
@@ -200,7 +200,7 @@ export async function loadBackendConfig(options: {
|
||||
});
|
||||
|
||||
const config = new ObservableConfigProxy(options.logger);
|
||||
const configs = await loadConfig({
|
||||
const { appConfigs } = await loadConfig({
|
||||
configRoot: paths.targetRoot,
|
||||
configPaths: [],
|
||||
configTargets: configTargets,
|
||||
@@ -227,14 +227,16 @@ export async function loadBackendConfig(options: {
|
||||
});
|
||||
|
||||
options.logger.info(
|
||||
`Loaded config from ${configs.map(c => c.context).join(', ')}`,
|
||||
`Loaded config from ${appConfigs.map(c => c.context).join(', ')}`,
|
||||
);
|
||||
|
||||
config.setConfig(ConfigReader.fromConfigs(configs));
|
||||
config.setConfig(ConfigReader.fromConfigs(appConfigs));
|
||||
|
||||
// Subscribe to config changes and update the redaction list for logging
|
||||
updateRedactionList(schema, configs, options.logger);
|
||||
config.subscribe(() => updateRedactionList(schema, configs, options.logger));
|
||||
updateRedactionList(schema, appConfigs, options.logger);
|
||||
config.subscribe(() =>
|
||||
updateRedactionList(schema, appConfigs, options.logger),
|
||||
);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ export async function loadCliConfig(options: Options) {
|
||||
packagePaths: [paths.resolveTargetRoot('package.json')],
|
||||
});
|
||||
|
||||
const appConfigs = await loadConfig({
|
||||
const { appConfigs } = await loadConfig({
|
||||
experimentalEnvFunc: options.mockEnv
|
||||
? async name => process.env[name] || 'x'
|
||||
: undefined,
|
||||
|
||||
@@ -38,7 +38,9 @@ export type ConfigTarget =
|
||||
export type ConfigVisibility = 'frontend' | 'backend' | 'secret';
|
||||
|
||||
// @public
|
||||
export function loadConfig(options: LoadConfigOptions): Promise<AppConfig[]>;
|
||||
export function loadConfig(
|
||||
options: LoadConfigOptions,
|
||||
): Promise<LoadConfigResult>;
|
||||
|
||||
// @public
|
||||
export type LoadConfigOptions = {
|
||||
@@ -66,6 +68,11 @@ export type LoadConfigOptionsWatch = {
|
||||
stopSignal?: Promise<void>;
|
||||
};
|
||||
|
||||
// @public
|
||||
export type LoadConfigResult = {
|
||||
appConfigs: AppConfig[];
|
||||
};
|
||||
|
||||
// @public
|
||||
export function loadConfigSchema(
|
||||
options: LoadConfigSchemaOptions,
|
||||
|
||||
@@ -34,4 +34,5 @@ export type {
|
||||
LoadConfigOptions,
|
||||
LoadConfigOptionsWatch,
|
||||
LoadConfigOptionsRemote,
|
||||
LoadConfigResult,
|
||||
} from './loader';
|
||||
|
||||
@@ -122,18 +122,20 @@ describe('loadConfig', () => {
|
||||
configTargets: [],
|
||||
env: 'production',
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
).resolves.toEqual({
|
||||
appConfigs: [
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('load config from remote path', async () => {
|
||||
@@ -151,18 +153,20 @@ describe('loadConfig', () => {
|
||||
reloadIntervalSeconds: 30,
|
||||
},
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
context: configUrl,
|
||||
data: {
|
||||
app: {
|
||||
title: 'Remote Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
).resolves.toEqual({
|
||||
appConfigs: [
|
||||
{
|
||||
context: configUrl,
|
||||
data: {
|
||||
app: {
|
||||
title: 'Remote Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('loads config with secrets from two different files', async () => {
|
||||
@@ -173,28 +177,30 @@ describe('loadConfig', () => {
|
||||
configTargets: [{ path: '/root/app-config.yaml' }],
|
||||
env: 'production',
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
).resolves.toEqual({
|
||||
appConfigs: [
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
context: 'app-config2.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App 2',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
{
|
||||
context: 'app-config2.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App 2',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('loads config with secrets from single file', async () => {
|
||||
@@ -205,18 +211,20 @@ describe('loadConfig', () => {
|
||||
configTargets: [{ path: '/root/app-config.yaml' }],
|
||||
env: 'production',
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
).resolves.toEqual({
|
||||
appConfigs: [
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('loads development config with secrets', async () => {
|
||||
@@ -230,34 +238,36 @@ describe('loadConfig', () => {
|
||||
],
|
||||
env: 'development',
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
context: 'app-config.development.yaml',
|
||||
data: {
|
||||
app: {
|
||||
sessionKey: 'development-key',
|
||||
},
|
||||
backend: {
|
||||
foo: {
|
||||
bar: 'token is-secret',
|
||||
).resolves.toEqual({
|
||||
appConfigs: [
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
},
|
||||
},
|
||||
other: {
|
||||
secret: 'abc123',
|
||||
},
|
||||
{
|
||||
context: 'app-config.development.yaml',
|
||||
data: {
|
||||
app: {
|
||||
sessionKey: 'development-key',
|
||||
},
|
||||
backend: {
|
||||
foo: {
|
||||
bar: 'token is-secret',
|
||||
},
|
||||
},
|
||||
other: {
|
||||
secret: 'abc123',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('loads deep substituted config', async () => {
|
||||
@@ -268,19 +278,21 @@ describe('loadConfig', () => {
|
||||
configTargets: [{ path: '/root/app-config.substitute.yaml' }],
|
||||
env: 'development',
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
context: 'app-config.substitute.yaml',
|
||||
data: {
|
||||
app: {
|
||||
someConfig: {
|
||||
secret: '123abc',
|
||||
).resolves.toEqual({
|
||||
appConfigs: [
|
||||
{
|
||||
context: 'app-config.substitute.yaml',
|
||||
data: {
|
||||
app: {
|
||||
someConfig: {
|
||||
secret: '123abc',
|
||||
},
|
||||
noSubstitute: 'notSubstituted',
|
||||
},
|
||||
noSubstitute: 'notSubstituted',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('watches config files', async () => {
|
||||
@@ -297,18 +309,20 @@ describe('loadConfig', () => {
|
||||
stopSignal: stopSignal.promise,
|
||||
},
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
).resolves.toEqual({
|
||||
appConfigs: [
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
],
|
||||
});
|
||||
|
||||
await fs.writeJson('/root/app-config.yaml', {
|
||||
app: {
|
||||
@@ -349,18 +363,20 @@ describe('loadConfig', () => {
|
||||
reloadIntervalSeconds: 1,
|
||||
},
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
context: configUrl,
|
||||
data: {
|
||||
app: {
|
||||
title: 'Remote Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
).resolves.toEqual({
|
||||
appConfigs: [
|
||||
{
|
||||
context: configUrl,
|
||||
data: {
|
||||
app: {
|
||||
title: 'Remote Example App',
|
||||
sessionKey: 'abc123',
|
||||
escaped: '${Escaped}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
],
|
||||
});
|
||||
|
||||
server.use(reloadHandler);
|
||||
|
||||
|
||||
@@ -88,6 +88,17 @@ export type LoadConfigOptions = {
|
||||
watch?: LoadConfigOptionsWatch;
|
||||
};
|
||||
|
||||
/**
|
||||
* Results of loading configuration files.
|
||||
* @public
|
||||
*/
|
||||
export type LoadConfigResult = {
|
||||
/**
|
||||
* Array of all loaded configs.
|
||||
*/
|
||||
appConfigs: AppConfig[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Load configuration data.
|
||||
*
|
||||
@@ -95,7 +106,7 @@ export type LoadConfigOptions = {
|
||||
*/
|
||||
export async function loadConfig(
|
||||
options: LoadConfigOptions,
|
||||
): Promise<AppConfig[]> {
|
||||
): Promise<LoadConfigResult> {
|
||||
const { configRoot, experimentalEnvFunc: envFunc, watch, remote } = options;
|
||||
|
||||
const configPaths: string[] = options.configTargets
|
||||
@@ -290,7 +301,9 @@ export async function loadConfig(
|
||||
watchRemoteConfig(watch, remote);
|
||||
}
|
||||
|
||||
return remote
|
||||
? [...remoteConfigs, ...fileConfigs, ...envConfigs]
|
||||
: [...fileConfigs, ...envConfigs];
|
||||
return {
|
||||
appConfigs: remote
|
||||
? [...remoteConfigs, ...fileConfigs, ...envConfigs]
|
||||
: [...fileConfigs, ...envConfigs],
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user