Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@backstage/config

Package Overview
Dependencies
Maintainers
3
Versions
327
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@backstage/config - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

dist/readDurationFromConfig.cjs.js

12

CHANGELOG.md
# @backstage/config
## 1.3.0
### Minor Changes
- d52d7f9: Make `readDurationFromConfig` support both ISO and ms formats as well, to make it easier to enter time as an end user
### Patch Changes
- Updated dependencies
- @backstage/types@1.2.0
- @backstage/errors@1.2.5
## 1.2.0

@@ -4,0 +16,0 @@

441

dist/index.cjs.js
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var readDurationFromConfig = require('./readDurationFromConfig.cjs.js');
var reader = require('./reader.cjs.js');
var errors$1 = require('@backstage/errors');
const propsOfHumanDuration = [
"years",
"months",
"weeks",
"days",
"hours",
"minutes",
"seconds",
"milliseconds"
];
function readDurationFromConfig(config, options) {
let root;
let found = false;
const result = {};
try {
root = (options == null ? void 0 : options.key) ? config.getConfig(options.key) : config;
for (const prop of propsOfHumanDuration) {
const value = root.getOptionalNumber(prop);
if (value !== void 0) {
result[prop] = value;
found = true;
}
}
} catch (error) {
throw new errors$1.InputError(`Failed to read duration from config, ${error}`);
}
try {
if (!found) {
const good = propsOfHumanDuration.map((p) => `'${p}'`).join(", ");
throw new Error(`Needs one or more of ${good}`);
}
const invalidProps = root.keys().filter((prop) => !propsOfHumanDuration.includes(prop));
if (invalidProps.length) {
const what = invalidProps.length === 1 ? "property" : "properties";
const bad = invalidProps.map((p) => `'${p}'`).join(", ");
const good = propsOfHumanDuration.map((p) => `'${p}'`).join(", ");
throw new Error(
`Unknown ${what} ${bad}; expected one or more of ${good}`
);
}
} catch (error) {
let prefix = "Failed to read duration from config";
if (options == null ? void 0 : options.key) {
prefix += ` at '${options.key}'`;
}
throw new errors$1.InputError(`${prefix}, ${error}`);
}
return result;
}
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_][a-z][a-z0-9]*)*$/i;
function isObject(value) {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function cloneDeep(value) {
if (typeof value !== "object" || value === null) {
return value;
}
if (Array.isArray(value)) {
return value.map(cloneDeep);
}
return Object.fromEntries(
Object.entries(value).map(([k, v]) => [k, cloneDeep(v)])
);
}
function merge(into, from) {
if (into === null) {
return void 0;
}
if (into === void 0) {
return from === void 0 ? void 0 : merge(from);
}
if (typeof into !== "object" || Array.isArray(into)) {
return into;
}
const fromObj = isObject(from) ? from : {};
const out = {};
for (const key of /* @__PURE__ */ new Set([...Object.keys(into), ...Object.keys(fromObj)])) {
const val = merge(into[key], fromObj[key]);
if (val !== void 0) {
out[key] = val;
}
}
return out;
}
function typeOf(value) {
if (value === null) {
return "null";
} else if (Array.isArray(value)) {
return "array";
}
const type = typeof value;
if (type === "number" && isNaN(value)) {
return "nan";
}
if (type === "string" && value === "") {
return "empty-string";
}
return type;
}
const errors = {
type(key, context, typeName, expected) {
return `Invalid type in config for key '${key}' in '${context}', got ${typeName}, wanted ${expected}`;
},
missing(key, context) {
return `Missing required config value at '${key}' in '${context}'`;
},
convert(key, context, expected) {
return `Unable to convert config value for key '${key}' in '${context}' to a ${expected}`;
}
};
class ConfigReader {
constructor(data, context = "mock-config", fallback, prefix = "") {
this.data = data;
this.context = context;
this.fallback = fallback;
this.prefix = prefix;
/**
* A set of key paths that where removed from the config due to not being visible.
*
* This was added as a mutable private member to avoid changes to the public API.
* Its only purpose of this is to warn users of missing visibility when running
* the frontend in development mode.
*/
__publicField(this, "filteredKeys");
__publicField(this, "notifiedFilteredKeys", /* @__PURE__ */ new Set());
}
/**
* Instantiates the config reader from a list of application config objects.
*/
static fromConfigs(configs) {
if (configs.length === 0) {
return new ConfigReader(void 0);
}
return configs.reduce(
(previousReader, { data, context, filteredKeys, deprecatedKeys }) => {
const reader = new ConfigReader(data, context, previousReader);
reader.filteredKeys = filteredKeys;
if (deprecatedKeys) {
for (const { key, description } of deprecatedKeys) {
console.warn(
`The configuration key '${key}' of ${context} is deprecated and may be removed soon. ${description || ""}`
);
}
}
return reader;
},
void 0
);
}
/** {@inheritdoc Config.has} */
has(key) {
var _a, _b;
const value = this.readValue(key);
if (value === null) {
return false;
}
if (value !== void 0) {
return true;
}
return (_b = (_a = this.fallback) == null ? void 0 : _a.has(key)) != null ? _b : false;
}
/** {@inheritdoc Config.keys} */
keys() {
var _a, _b;
const localKeys = this.data ? Object.keys(this.data) : [];
const fallbackKeys = (_b = (_a = this.fallback) == null ? void 0 : _a.keys()) != null ? _b : [];
return [.../* @__PURE__ */ new Set([...localKeys, ...fallbackKeys])].filter(
(k) => {
var _a2;
return ((_a2 = this.data) == null ? void 0 : _a2[k]) !== null;
}
);
}
/** {@inheritdoc Config.get} */
get(key) {
const value = this.getOptional(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key != null ? key : ""), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptional} */
getOptional(key) {
var _a, _b;
const value = cloneDeep(this.readValue(key));
const fallbackValue = (_a = this.fallback) == null ? void 0 : _a.getOptional(key);
if (value === null) {
return void 0;
}
if (value === void 0) {
if (process.env.NODE_ENV === "development") {
if (fallbackValue === void 0 && key) {
const fullKey = this.fullKey(key);
if (((_b = this.filteredKeys) == null ? void 0 : _b.includes(fullKey)) && !this.notifiedFilteredKeys.has(fullKey)) {
this.notifiedFilteredKeys.add(fullKey);
console.warn(
`Failed to read configuration value at '${fullKey}' as it is not visible. See https://backstage.io/docs/conf/defining#visibility for instructions on how to make it visible.`
);
}
}
}
return merge(fallbackValue);
} else if (fallbackValue === void 0) {
return merge(value);
}
return merge(value, fallbackValue);
}
/** {@inheritdoc Config.getConfig} */
getConfig(key) {
const value = this.getOptionalConfig(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalConfig} */
getOptionalConfig(key) {
var _a;
const value = this.readValue(key);
const fallbackConfig = (_a = this.fallback) == null ? void 0 : _a.getOptionalConfig(key);
if (isObject(value)) {
return this.copy(value, key, fallbackConfig);
}
if (value === null) {
return void 0;
}
if (value !== void 0) {
throw new TypeError(
errors.type(this.fullKey(key), this.context, typeOf(value), "object")
);
}
return fallbackConfig;
}
/** {@inheritdoc Config.getConfigArray} */
getConfigArray(key) {
const value = this.getOptionalConfigArray(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalConfigArray} */
getOptionalConfigArray(key) {
var _a;
const configs = this.readConfigValue(key, (values) => {
if (!Array.isArray(values)) {
return { expected: "object-array" };
}
for (const [index, value] of values.entries()) {
if (!isObject(value)) {
return { expected: "object-array", value, key: `${key}[${index}]` };
}
}
return true;
});
if (!configs) {
if (process.env.NODE_ENV === "development") {
const fullKey = this.fullKey(key);
if (((_a = this.filteredKeys) == null ? void 0 : _a.some((k) => k.startsWith(fullKey))) && !this.notifiedFilteredKeys.has(key)) {
this.notifiedFilteredKeys.add(key);
console.warn(
`Failed to read configuration array at '${key}' as it does not have any visible elements. See https://backstage.io/docs/conf/defining#visibility for instructions on how to make it visible.`
);
}
}
return void 0;
}
return configs.map((obj, index) => this.copy(obj, `${key}[${index}]`));
}
/** {@inheritdoc Config.getNumber} */
getNumber(key) {
const value = this.getOptionalNumber(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalNumber} */
getOptionalNumber(key) {
const value = this.readConfigValue(
key,
(val) => typeof val === "number" || typeof val === "string" || { expected: "number" }
);
if (typeof value === "number" || value === void 0) {
return value;
}
const number = Number(value);
if (!Number.isFinite(number)) {
throw new Error(
errors.convert(this.fullKey(key), this.context, "number")
);
}
return number;
}
/** {@inheritdoc Config.getBoolean} */
getBoolean(key) {
const value = this.getOptionalBoolean(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalBoolean} */
getOptionalBoolean(key) {
const value = this.readConfigValue(
key,
(val) => typeof val === "boolean" || typeof val === "number" || typeof val === "string" || { expected: "boolean" }
);
if (typeof value === "boolean" || value === void 0) {
return value;
}
const valueString = String(value).trim();
if (/^(?:y|yes|true|1|on)$/i.test(valueString)) {
return true;
}
if (/^(?:n|no|false|0|off)$/i.test(valueString)) {
return false;
}
throw new Error(errors.convert(this.fullKey(key), this.context, "boolean"));
}
/** {@inheritdoc Config.getString} */
getString(key) {
const value = this.getOptionalString(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalString} */
getOptionalString(key) {
return this.readConfigValue(
key,
(value) => typeof value === "string" && value !== "" || { expected: "string" }
);
}
/** {@inheritdoc Config.getStringArray} */
getStringArray(key) {
const value = this.getOptionalStringArray(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalStringArray} */
getOptionalStringArray(key) {
return this.readConfigValue(key, (values) => {
if (!Array.isArray(values)) {
return { expected: "string-array" };
}
for (const [index, value] of values.entries()) {
if (typeof value !== "string" || value === "") {
return { expected: "string-array", value, key: `${key}[${index}]` };
}
}
return true;
});
}
fullKey(key) {
return `${this.prefix}${this.prefix ? "." : ""}${key}`;
}
copy(data, key, fallback) {
const reader = new ConfigReader(
data,
this.context,
fallback,
this.fullKey(key)
);
reader.filteredKeys = this.filteredKeys;
return reader;
}
readConfigValue(key, validate) {
var _a, _b;
const value = this.readValue(key);
if (value === void 0) {
if (process.env.NODE_ENV === "development") {
const fullKey = this.fullKey(key);
if (((_a = this.filteredKeys) == null ? void 0 : _a.includes(fullKey)) && !this.notifiedFilteredKeys.has(fullKey)) {
this.notifiedFilteredKeys.add(fullKey);
console.warn(
`Failed to read configuration value at '${fullKey}' as it is not visible. See https://backstage.io/docs/conf/defining#visibility for instructions on how to make it visible.`
);
}
}
return (_b = this.fallback) == null ? void 0 : _b.readConfigValue(key, validate);
}
if (value === null) {
return void 0;
}
const result = validate(value);
if (result !== true) {
const { key: keyName = key, value: theValue = value, expected } = result;
throw new TypeError(
errors.type(
this.fullKey(keyName),
this.context,
typeOf(theValue),
expected
)
);
}
return value;
}
readValue(key) {
const parts = key ? key.split(".") : [];
for (const part of parts) {
if (!CONFIG_KEY_PART_PATTERN.test(part)) {
throw new TypeError(`Invalid config key '${key}'`);
}
}
if (this.data === void 0) {
return void 0;
}
let value = this.data;
for (const [index, part] of parts.entries()) {
if (isObject(value)) {
value = value[part];
} else if (value !== void 0 && value !== null) {
const badKey = this.fullKey(parts.slice(0, index).join("."));
throw new TypeError(
errors.type(badKey, this.context, typeOf(value), "object")
);
}
}
return value;
}
}
exports.ConfigReader = ConfigReader;
exports.readDurationFromConfig = readDurationFromConfig;
exports.readDurationFromConfig = readDurationFromConfig.readDurationFromConfig;
exports.ConfigReader = reader.ConfigReader;
//# sourceMappingURL=index.cjs.js.map

@@ -1,2 +0,2 @@

import { JsonPrimitive as JsonPrimitive$1, JsonObject as JsonObject$1, JsonArray as JsonArray$1, JsonValue as JsonValue$1, HumanDuration } from '@backstage/types';
import { JsonArray as JsonArray$1, JsonObject as JsonObject$1, JsonPrimitive as JsonPrimitive$1, JsonValue as JsonValue$1, HumanDuration } from '@backstage/types';
import { Config as Config$1 } from '@backstage/config';

@@ -34,3 +34,3 @@

/**
* Reads a duration from a config object.
* Reads a duration from config.
*

@@ -40,2 +40,13 @@ * @public

*
* The supported formats are:
*
* - A string in the format of '1d', '2 seconds' etc. as supported by the `ms`
* library.
* - A standard ISO formatted duration string, e.g. 'P2DT6H' or 'PT1M'.
* - An object with individual units (in plural) as keys, e.g. `{ days: 2, hours: 6 }`.
*
* The string forms are naturally only supported if the `options.key` argument
* is passed, since a `Config` argument always represents an object by its
* nature.
*
* This does not support optionality; if you want to support optional durations,

@@ -46,4 +57,4 @@ * you need to first check the presence of the target with `config.has(...)` and

* @param config - A configuration object
* @param key - If specified, read the duration from the given subkey
* under the config object
* @param key - If specified, read the duration from the given subkey under the
* config object
* @returns A duration object

@@ -237,2 +248,2 @@ */

export { AppConfig, Config, ConfigReader, JsonArray, JsonObject, JsonPrimitive, JsonValue, readDurationFromConfig };
export { type AppConfig, type Config, ConfigReader, type JsonArray, type JsonObject, type JsonPrimitive, type JsonValue, readDurationFromConfig };

@@ -1,438 +0,3 @@

import { InputError } from '@backstage/errors';
const propsOfHumanDuration = [
"years",
"months",
"weeks",
"days",
"hours",
"minutes",
"seconds",
"milliseconds"
];
function readDurationFromConfig(config, options) {
let root;
let found = false;
const result = {};
try {
root = (options == null ? void 0 : options.key) ? config.getConfig(options.key) : config;
for (const prop of propsOfHumanDuration) {
const value = root.getOptionalNumber(prop);
if (value !== void 0) {
result[prop] = value;
found = true;
}
}
} catch (error) {
throw new InputError(`Failed to read duration from config, ${error}`);
}
try {
if (!found) {
const good = propsOfHumanDuration.map((p) => `'${p}'`).join(", ");
throw new Error(`Needs one or more of ${good}`);
}
const invalidProps = root.keys().filter((prop) => !propsOfHumanDuration.includes(prop));
if (invalidProps.length) {
const what = invalidProps.length === 1 ? "property" : "properties";
const bad = invalidProps.map((p) => `'${p}'`).join(", ");
const good = propsOfHumanDuration.map((p) => `'${p}'`).join(", ");
throw new Error(
`Unknown ${what} ${bad}; expected one or more of ${good}`
);
}
} catch (error) {
let prefix = "Failed to read duration from config";
if (options == null ? void 0 : options.key) {
prefix += ` at '${options.key}'`;
}
throw new InputError(`${prefix}, ${error}`);
}
return result;
}
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_][a-z][a-z0-9]*)*$/i;
function isObject(value) {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function cloneDeep(value) {
if (typeof value !== "object" || value === null) {
return value;
}
if (Array.isArray(value)) {
return value.map(cloneDeep);
}
return Object.fromEntries(
Object.entries(value).map(([k, v]) => [k, cloneDeep(v)])
);
}
function merge(into, from) {
if (into === null) {
return void 0;
}
if (into === void 0) {
return from === void 0 ? void 0 : merge(from);
}
if (typeof into !== "object" || Array.isArray(into)) {
return into;
}
const fromObj = isObject(from) ? from : {};
const out = {};
for (const key of /* @__PURE__ */ new Set([...Object.keys(into), ...Object.keys(fromObj)])) {
const val = merge(into[key], fromObj[key]);
if (val !== void 0) {
out[key] = val;
}
}
return out;
}
function typeOf(value) {
if (value === null) {
return "null";
} else if (Array.isArray(value)) {
return "array";
}
const type = typeof value;
if (type === "number" && isNaN(value)) {
return "nan";
}
if (type === "string" && value === "") {
return "empty-string";
}
return type;
}
const errors = {
type(key, context, typeName, expected) {
return `Invalid type in config for key '${key}' in '${context}', got ${typeName}, wanted ${expected}`;
},
missing(key, context) {
return `Missing required config value at '${key}' in '${context}'`;
},
convert(key, context, expected) {
return `Unable to convert config value for key '${key}' in '${context}' to a ${expected}`;
}
};
class ConfigReader {
constructor(data, context = "mock-config", fallback, prefix = "") {
this.data = data;
this.context = context;
this.fallback = fallback;
this.prefix = prefix;
/**
* A set of key paths that where removed from the config due to not being visible.
*
* This was added as a mutable private member to avoid changes to the public API.
* Its only purpose of this is to warn users of missing visibility when running
* the frontend in development mode.
*/
__publicField(this, "filteredKeys");
__publicField(this, "notifiedFilteredKeys", /* @__PURE__ */ new Set());
}
/**
* Instantiates the config reader from a list of application config objects.
*/
static fromConfigs(configs) {
if (configs.length === 0) {
return new ConfigReader(void 0);
}
return configs.reduce(
(previousReader, { data, context, filteredKeys, deprecatedKeys }) => {
const reader = new ConfigReader(data, context, previousReader);
reader.filteredKeys = filteredKeys;
if (deprecatedKeys) {
for (const { key, description } of deprecatedKeys) {
console.warn(
`The configuration key '${key}' of ${context} is deprecated and may be removed soon. ${description || ""}`
);
}
}
return reader;
},
void 0
);
}
/** {@inheritdoc Config.has} */
has(key) {
var _a, _b;
const value = this.readValue(key);
if (value === null) {
return false;
}
if (value !== void 0) {
return true;
}
return (_b = (_a = this.fallback) == null ? void 0 : _a.has(key)) != null ? _b : false;
}
/** {@inheritdoc Config.keys} */
keys() {
var _a, _b;
const localKeys = this.data ? Object.keys(this.data) : [];
const fallbackKeys = (_b = (_a = this.fallback) == null ? void 0 : _a.keys()) != null ? _b : [];
return [.../* @__PURE__ */ new Set([...localKeys, ...fallbackKeys])].filter(
(k) => {
var _a2;
return ((_a2 = this.data) == null ? void 0 : _a2[k]) !== null;
}
);
}
/** {@inheritdoc Config.get} */
get(key) {
const value = this.getOptional(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key != null ? key : ""), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptional} */
getOptional(key) {
var _a, _b;
const value = cloneDeep(this.readValue(key));
const fallbackValue = (_a = this.fallback) == null ? void 0 : _a.getOptional(key);
if (value === null) {
return void 0;
}
if (value === void 0) {
if (process.env.NODE_ENV === "development") {
if (fallbackValue === void 0 && key) {
const fullKey = this.fullKey(key);
if (((_b = this.filteredKeys) == null ? void 0 : _b.includes(fullKey)) && !this.notifiedFilteredKeys.has(fullKey)) {
this.notifiedFilteredKeys.add(fullKey);
console.warn(
`Failed to read configuration value at '${fullKey}' as it is not visible. See https://backstage.io/docs/conf/defining#visibility for instructions on how to make it visible.`
);
}
}
}
return merge(fallbackValue);
} else if (fallbackValue === void 0) {
return merge(value);
}
return merge(value, fallbackValue);
}
/** {@inheritdoc Config.getConfig} */
getConfig(key) {
const value = this.getOptionalConfig(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalConfig} */
getOptionalConfig(key) {
var _a;
const value = this.readValue(key);
const fallbackConfig = (_a = this.fallback) == null ? void 0 : _a.getOptionalConfig(key);
if (isObject(value)) {
return this.copy(value, key, fallbackConfig);
}
if (value === null) {
return void 0;
}
if (value !== void 0) {
throw new TypeError(
errors.type(this.fullKey(key), this.context, typeOf(value), "object")
);
}
return fallbackConfig;
}
/** {@inheritdoc Config.getConfigArray} */
getConfigArray(key) {
const value = this.getOptionalConfigArray(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalConfigArray} */
getOptionalConfigArray(key) {
var _a;
const configs = this.readConfigValue(key, (values) => {
if (!Array.isArray(values)) {
return { expected: "object-array" };
}
for (const [index, value] of values.entries()) {
if (!isObject(value)) {
return { expected: "object-array", value, key: `${key}[${index}]` };
}
}
return true;
});
if (!configs) {
if (process.env.NODE_ENV === "development") {
const fullKey = this.fullKey(key);
if (((_a = this.filteredKeys) == null ? void 0 : _a.some((k) => k.startsWith(fullKey))) && !this.notifiedFilteredKeys.has(key)) {
this.notifiedFilteredKeys.add(key);
console.warn(
`Failed to read configuration array at '${key}' as it does not have any visible elements. See https://backstage.io/docs/conf/defining#visibility for instructions on how to make it visible.`
);
}
}
return void 0;
}
return configs.map((obj, index) => this.copy(obj, `${key}[${index}]`));
}
/** {@inheritdoc Config.getNumber} */
getNumber(key) {
const value = this.getOptionalNumber(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalNumber} */
getOptionalNumber(key) {
const value = this.readConfigValue(
key,
(val) => typeof val === "number" || typeof val === "string" || { expected: "number" }
);
if (typeof value === "number" || value === void 0) {
return value;
}
const number = Number(value);
if (!Number.isFinite(number)) {
throw new Error(
errors.convert(this.fullKey(key), this.context, "number")
);
}
return number;
}
/** {@inheritdoc Config.getBoolean} */
getBoolean(key) {
const value = this.getOptionalBoolean(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalBoolean} */
getOptionalBoolean(key) {
const value = this.readConfigValue(
key,
(val) => typeof val === "boolean" || typeof val === "number" || typeof val === "string" || { expected: "boolean" }
);
if (typeof value === "boolean" || value === void 0) {
return value;
}
const valueString = String(value).trim();
if (/^(?:y|yes|true|1|on)$/i.test(valueString)) {
return true;
}
if (/^(?:n|no|false|0|off)$/i.test(valueString)) {
return false;
}
throw new Error(errors.convert(this.fullKey(key), this.context, "boolean"));
}
/** {@inheritdoc Config.getString} */
getString(key) {
const value = this.getOptionalString(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalString} */
getOptionalString(key) {
return this.readConfigValue(
key,
(value) => typeof value === "string" && value !== "" || { expected: "string" }
);
}
/** {@inheritdoc Config.getStringArray} */
getStringArray(key) {
const value = this.getOptionalStringArray(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key), this.context));
}
return value;
}
/** {@inheritdoc Config.getOptionalStringArray} */
getOptionalStringArray(key) {
return this.readConfigValue(key, (values) => {
if (!Array.isArray(values)) {
return { expected: "string-array" };
}
for (const [index, value] of values.entries()) {
if (typeof value !== "string" || value === "") {
return { expected: "string-array", value, key: `${key}[${index}]` };
}
}
return true;
});
}
fullKey(key) {
return `${this.prefix}${this.prefix ? "." : ""}${key}`;
}
copy(data, key, fallback) {
const reader = new ConfigReader(
data,
this.context,
fallback,
this.fullKey(key)
);
reader.filteredKeys = this.filteredKeys;
return reader;
}
readConfigValue(key, validate) {
var _a, _b;
const value = this.readValue(key);
if (value === void 0) {
if (process.env.NODE_ENV === "development") {
const fullKey = this.fullKey(key);
if (((_a = this.filteredKeys) == null ? void 0 : _a.includes(fullKey)) && !this.notifiedFilteredKeys.has(fullKey)) {
this.notifiedFilteredKeys.add(fullKey);
console.warn(
`Failed to read configuration value at '${fullKey}' as it is not visible. See https://backstage.io/docs/conf/defining#visibility for instructions on how to make it visible.`
);
}
}
return (_b = this.fallback) == null ? void 0 : _b.readConfigValue(key, validate);
}
if (value === null) {
return void 0;
}
const result = validate(value);
if (result !== true) {
const { key: keyName = key, value: theValue = value, expected } = result;
throw new TypeError(
errors.type(
this.fullKey(keyName),
this.context,
typeOf(theValue),
expected
)
);
}
return value;
}
readValue(key) {
const parts = key ? key.split(".") : [];
for (const part of parts) {
if (!CONFIG_KEY_PART_PATTERN.test(part)) {
throw new TypeError(`Invalid config key '${key}'`);
}
}
if (this.data === void 0) {
return void 0;
}
let value = this.data;
for (const [index, part] of parts.entries()) {
if (isObject(value)) {
value = value[part];
} else if (value !== void 0 && value !== null) {
const badKey = this.fullKey(parts.slice(0, index).join("."));
throw new TypeError(
errors.type(badKey, this.context, typeOf(value), "object")
);
}
}
return value;
}
}
export { ConfigReader, readDurationFromConfig };
export { readDurationFromConfig } from './readDurationFromConfig.esm.js';
export { ConfigReader } from './reader.esm.js';
//# sourceMappingURL=index.esm.js.map
{
"name": "@backstage/config",
"version": "1.2.0",
"version": "1.3.0",
"description": "Config API used by Backstage core, backend, and CLI",

@@ -39,10 +39,18 @@ "backstage": {

"dependencies": {
"@backstage/errors": "^1.2.4",
"@backstage/types": "^1.1.1"
"@backstage/errors": "^1.2.5",
"@backstage/types": "^1.2.0",
"ms": "^2.1.3"
},
"devDependencies": {
"@backstage/cli": "^0.26.0",
"@backstage/test-utils": "^1.5.1"
"@backstage/cli": "^0.29.0",
"@backstage/test-utils": "^1.7.1"
},
"typesVersions": {
"*": {
"index": [
"dist/index.d.ts"
]
}
},
"module": "dist/index.esm.js"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc