packages/config: flip around must* and get* to get* and getOptional*

This commit is contained in:
Patrik Oldsberg
2020-06-17 20:10:44 +02:00
parent 31585800a4
commit 3dcef70e3c
7 changed files with 47 additions and 51 deletions
-6
View File
@@ -33,9 +33,6 @@ import { BundlingOptions, BackendBundlingOptions } from './types';
export function resolveBaseUrl(config: Config): URL {
const baseUrl = config.getString('app.baseUrl');
if (!baseUrl) {
throw new Error('app.baseUrl must be set in config');
}
try {
return new URL(baseUrl, 'http://localhost:3000');
} catch (error) {
@@ -52,9 +49,6 @@ export function createConfig(
const { plugins, loaders } = transforms(options);
const baseUrl = options.config.getString('app.baseUrl');
if (!baseUrl) {
throw new Error('app.baseUrl must be set in config');
}
const validBaseUrl = new URL(baseUrl, 'https://backstage-app.dev');
if (checksEnabled) {
+23 -22
View File
@@ -49,10 +49,10 @@ function expectValidValues(config: ConfigReader) {
'string1',
'string2',
]);
expect(config.mustNumber('zero')).toBe(0);
expect(config.mustBoolean('true')).toBe(true);
expect(config.mustString('string')).toBe('string');
expect(config.mustStringArray('strings')).toEqual(['string1', 'string2']);
expect(config.getNumber('zero')).toBe(0);
expect(config.getBoolean('true')).toBe(true);
expect(config.getString('string')).toBe('string');
expect(config.getStringArray('strings')).toEqual(['string1', 'string2']);
const [config1, config2, config3] = config.getConfigArray('nestlings');
expect(config1.getBoolean('boolean')).toBe(true);
@@ -94,16 +94,16 @@ function expectInvalidValues(config: ConfigReader) {
expect(() => config.getConfigArray('one')).toThrow(
'Invalid type in config for key one, got number, wanted object-array',
);
expect(() => config.mustBoolean('missing')).toThrow(
expect(() => config.getBoolean('missing')).toThrow(
"Missing required config value at 'missing'",
);
expect(() => config.mustNumber('missing')).toThrow(
expect(() => config.getNumber('missing')).toThrow(
"Missing required config value at 'missing'",
);
expect(() => config.mustString('missing')).toThrow(
expect(() => config.getString('missing')).toThrow(
"Missing required config value at 'missing'",
);
expect(() => config.mustStringArray('missing')).toThrow(
expect(() => config.getStringArray('missing')).toThrow(
"Missing required config value at 'missing'",
);
}
@@ -111,13 +111,13 @@ function expectInvalidValues(config: ConfigReader) {
describe('ConfigReader', () => {
it('should read empty config with valid keys', () => {
const config = new ConfigReader({});
expect(config.getString('x')).toBeUndefined();
expect(config.getString('x_x')).toBeUndefined();
expect(config.getString('x-X')).toBeUndefined();
expect(config.getString('x0')).toBeUndefined();
expect(config.getString('X-x2')).toBeUndefined();
expect(config.getString('x0_x0')).toBeUndefined();
expect(config.getString('x_x-x_x')).toBeUndefined();
expect(config.getOptionalString('x')).toBeUndefined();
expect(config.getOptionalString('x_x')).toBeUndefined();
expect(config.getOptionalString('x-X')).toBeUndefined();
expect(config.getOptionalString('x0')).toBeUndefined();
expect(config.getOptionalString('X-x2')).toBeUndefined();
expect(config.getOptionalString('x0_x0')).toBeUndefined();
expect(config.getOptionalString('x_x-x_x')).toBeUndefined();
});
it('should throw on invalid keys', () => {
@@ -154,7 +154,7 @@ describe('ConfigReader', () => {
describe('ConfigReader with fallback', () => {
it('should behave as if without fallback', () => {
const config = new ConfigReader({}, new ConfigReader(DATA));
expect(config.getString('x')).toBeUndefined();
expect(config.getOptionalString('x')).toBeUndefined();
expect(() => config.getString('.')).toThrow(/^Invalid config key/);
expect(() => config.getString('a.')).toThrow(/^Invalid config key/);
});
@@ -229,14 +229,12 @@ describe('ConfigReader with fallback', () => {
// Config arrays aren't merged either
expect(config.getConfigArray('merged.configs').length).toBe(1);
expect(config.getConfigArray('merged.configs')[0].getString('a')).toBe('a');
expect(config.getConfigArray('merged.configs')[0].mustString('a')).toBe(
'a',
);
expect(config.getConfigArray('merged.configs')[0].getString('a')).toBe('a');
expect(() =>
config.getConfigArray('merged.configs')[0].mustString('missing'),
config.getConfigArray('merged.configs')[0].getString('missing'),
).toThrow("Missing required config value at 'missing'");
expect(
config.getConfigArray('merged.configs')[0].getString('b'),
config.getConfigArray('merged.configs')[0].getOptionalString('b'),
).toBeUndefined();
// Config arrays aren't merged either
@@ -245,7 +243,10 @@ describe('ConfigReader with fallback', () => {
config.getConfig('merged').getConfigArray('configs')[0].getString('a'),
).toBe('a');
expect(
config.getConfig('merged').getConfigArray('configs')[0].getString('b'),
config
.getConfig('merged')
.getConfigArray('configs')[0]
.getOptionalString('b'),
).toBeUndefined();
});
});
+12 -12
View File
@@ -92,45 +92,45 @@ export class ConfigReader implements Config {
return (configs ?? []).map(obj => new ConfigReader(obj));
}
mustNumber(key: string): number {
const value = this.getNumber(key);
getNumber(key: string): number {
const value = this.getOptionalNumber(key);
if (value === undefined) {
throw new Error(`Missing required config value at '${key}'`);
}
return value;
}
getNumber(key: string): number | undefined {
getOptionalNumber(key: string): number | undefined {
return this.readConfigValue(
key,
value => typeof value === 'number' || { expected: 'number' },
);
}
mustBoolean(key: string): boolean {
const value = this.getBoolean(key);
getBoolean(key: string): boolean {
const value = this.getOptionalBoolean(key);
if (value === undefined) {
throw new Error(`Missing required config value at '${key}'`);
}
return value;
}
getBoolean(key: string): boolean | undefined {
getOptionalBoolean(key: string): boolean | undefined {
return this.readConfigValue(
key,
value => typeof value === 'boolean' || { expected: 'boolean' },
);
}
mustString(key: string): string {
const value = this.getString(key);
getString(key: string): string {
const value = this.getOptionalString(key);
if (value === undefined) {
throw new Error(`Missing required config value at '${key}'`);
}
return value;
}
getString(key: string): string | undefined {
getOptionalString(key: string): string | undefined {
return this.readConfigValue(
key,
value =>
@@ -138,15 +138,15 @@ export class ConfigReader implements Config {
);
}
mustStringArray(key: string): string[] {
const value = this.getStringArray(key);
getStringArray(key: string): string[] {
const value = this.getOptionalStringArray(key);
if (value === undefined) {
throw new Error(`Missing required config value at '${key}'`);
}
return value;
}
getStringArray(key: string): string[] | undefined {
getOptionalStringArray(key: string): string[] | undefined {
return this.readConfigValue(key, values => {
if (!Array.isArray(values)) {
return { expected: 'string-array' };
+8 -8
View File
@@ -31,15 +31,15 @@ export type Config = {
getConfigArray(key: string): Config[];
getNumber(key: string): number | undefined;
mustNumber(key: string): number;
getNumber(key: string): number;
getOptionalNumber(key: string): number | undefined;
getBoolean(key: string): boolean | undefined;
mustBoolean(key: string): boolean;
getBoolean(key: string): boolean;
getOptionalBoolean(key: string): boolean | undefined;
getString(key: string): string | undefined;
mustString(key: string): string;
getString(key: string): string;
getOptionalString(key: string): string | undefined;
getStringArray(key: string): string[] | undefined;
mustStringArray(key: string): string[];
getStringArray(key: string): string[];
getOptionalStringArray(key: string): string[] | undefined;
};
+1 -1
View File
@@ -282,7 +282,7 @@ export class PrivateAppImpl implements BackstageApp {
const configApi = useApi(configApiRef);
let { pathname } = new URL(
configApi.getString('app.baseUrl') ?? '/',
configApi.getOptionalString('app.baseUrl') ?? '/',
'http://dummy.dev', // baseUrl can be specified as just a path
);
if (pathname.endsWith('/')) {
@@ -39,7 +39,7 @@ export const SignInPage: FC<Props> = ({ onResult, providers }) => {
return (
<Page>
<Header title={configApi.getString('app.title') ?? 'Backstage'} />
<Header title={configApi.getString('app.title')} />
<Content>
<ContentHeader title="Select a sign-in method" />
<Grid container>{providerElements}</Grid>
@@ -39,7 +39,8 @@ import {
} from '@backstage/core';
const WelcomePage: FC<{}> = () => {
const appTitle = useApi(configApiRef).getString('app.title') ?? 'Backstage';
const appTitle =
useApi(configApiRef).getOptionalString('app.title') ?? 'Backstage';
const profile = { givenName: '' };
return (