diff --git a/.changeset/six-cooks-battle.md b/.changeset/six-cooks-battle.md new file mode 100644 index 0000000000..ecf856225e --- /dev/null +++ b/.changeset/six-cooks-battle.md @@ -0,0 +1,6 @@ +--- +'@backstage/config-loader': patch +'@backstage/config': patch +--- + +Allow colon to be used as config key. diff --git a/packages/config-loader/src/sources/EnvConfigSource.ts b/packages/config-loader/src/sources/EnvConfigSource.ts index d724f00c6d..988110b370 100644 --- a/packages/config-loader/src/sources/EnvConfigSource.ts +++ b/packages/config-loader/src/sources/EnvConfigSource.ts @@ -85,7 +85,7 @@ export class EnvConfigSource implements ConfigSource { const ENV_PREFIX = 'APP_CONFIG_'; // Update the same pattern in config package if this is changed -const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/i; +const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_:][a-z0-9]+)*$/i; /** * Read runtime configuration from the environment. diff --git a/packages/config/src/reader.test.ts b/packages/config/src/reader.test.ts index 3f6b9ac40a..bb16fbeaa1 100644 --- a/packages/config/src/reader.test.ts +++ b/packages/config/src/reader.test.ts @@ -43,6 +43,7 @@ const DATA = { null: null, string: 'string', strings: ['string1', 'string2'], + 'with:colon': 'yes', }, nestlings: [{ boolean: true }, { string: 'string' }, { number: 42 }] as {}[], }; @@ -57,6 +58,7 @@ function expectValidValues(config: ConfigReader) { expect(config.has('nested.one')).toBe(true); expect(config.has('nested.missing')).toBe(false); expect(config.has('nested.null')).toBe(false); + expect(config.has('nested.with:colon')).toBe(true); expect(config.getNumber('zero')).toBe(0); expect(config.getNumber('one')).toBe(1); expect(config.getNumber('zeroString')).toBe(0); @@ -84,8 +86,11 @@ function expectValidValues(config: ConfigReader) { null: undefined, string: 'string', strings: ['string1', 'string2'], + 'with:colon': 'yes', }); expect(config.getConfig('nested').getString('string')).toBe('string'); + expect(config.getString('nested.string')).toBe('string'); + expect(config.getString('nested.with:colon')).toBe('yes'); expect(config.getOptionalConfig('nested')!.getStringArray('strings')).toEqual( ['string1', 'string2'], ); diff --git a/packages/config/src/reader.ts b/packages/config/src/reader.ts index 2e83de9bf2..7ad0cf738d 100644 --- a/packages/config/src/reader.ts +++ b/packages/config/src/reader.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { JsonValue, JsonObject } from '@backstage/types'; +import { JsonObject, JsonValue } from '@backstage/types'; import { AppConfig, Config } from './types'; // Update the same pattern in config-loader package if this is changed -const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/i; +const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_:][a-z0-9]+)*$/i; function isObject(value: JsonValue | undefined): value is JsonObject { return typeof value === 'object' && value !== null && !Array.isArray(value);