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

@backstage/config

Package Overview
Dependencies
Maintainers
4
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 0.1.1-alpha.9 to 0.1.1-alpha.10

122

dist/index.cjs.js

@@ -5,2 +5,7 @@ 'use strict';

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var cloneDeep2 = _interopDefault(require('lodash/cloneDeep'));
var mergeWith2 = _interopDefault(require('lodash/mergeWith'));
const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_][a-z][a-z0-9]*)*$/i;

@@ -25,28 +30,77 @@ function isObject(value) {

}
const errors = {
type(key, context, typeName, expected) {
return `Invalid type in config for key '${key}' in '${context}', got ${typeName}, wanted ${expected}`;
},
missing(key) {
return `Missing required config value at '${key}'`;
}
};
class ConfigReader {
constructor(data, fallback) {
constructor(data, context = "empty-config", fallback, prefix = "") {
this.data = data;
this.context = context;
this.fallback = fallback;
this.prefix = prefix;
}
static fromConfigs(configs) {
if (configs.length === 0) {
return new ConfigReader({});
return new ConfigReader(void 0);
}
return configs.reduceRight((previousReader, nextConfig) => {
return new ConfigReader(nextConfig, previousReader);
return configs.reduceRight((previousReader, {data, context}) => {
return new ConfigReader(data, context, previousReader);
}, void 0);
}
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 [...new Set([...localKeys, ...fallbackKeys])];
}
get(key) {
const value = this.getOptional(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptional(key) {
var _a;
const value = this.readValue(key);
const fallbackValue = (_a = this.fallback) == null ? void 0 : _a.getOptional(key);
if (value === void 0) {
return fallbackValue;
} else if (fallbackValue === void 0) {
return value;
}
return mergeWith2({}, {value: cloneDeep2(fallbackValue)}, {value}, (into, from) => !isObject(from) || !isObject(into) ? from : void 0).value;
}
getConfig(key) {
const value = this.getOptionalConfig(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalConfig(key) {
var _a;
const value = this.readValue(key);
const fallbackConfig = (_a = this.fallback) == null ? void 0 : _a.getConfig(key);
const fallbackConfig = (_a = this.fallback) == null ? void 0 : _a.getOptionalConfig(key);
const prefix = this.fullKey(key);
if (isObject(value)) {
return new ConfigReader(value, fallbackConfig);
return new ConfigReader(value, this.context, fallbackConfig, prefix);
}
if (value !== void 0) {
throw new TypeError(`Invalid type in config for key ${key}, got ${typeOf(value)}, wanted object`);
throw new TypeError(errors.type(this.fullKey(key), this.context, typeOf(value), "object"));
}
return fallbackConfig != null ? fallbackConfig : ConfigReader.nullReader;
return fallbackConfig;
}
getConfigArray(key) {
const value = this.getOptionalConfigArray(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalConfigArray(key) {
const configs = this.readConfigValue(key, (values) => {

@@ -63,14 +117,45 @@ if (!Array.isArray(values)) {

});
return (configs != null ? configs : []).map((obj) => new ConfigReader(obj));
if (!configs) {
return void 0;
}
return configs.map((obj, index) => new ConfigReader(obj, this.context, void 0, this.fullKey(`${key}[${index}]`)));
}
getNumber(key) {
const value = this.getOptionalNumber(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalNumber(key) {
return this.readConfigValue(key, (value) => typeof value === "number" || {expected: "number"});
}
getBoolean(key) {
const value = this.getOptionalBoolean(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalBoolean(key) {
return this.readConfigValue(key, (value) => typeof value === "boolean" || {expected: "boolean"});
}
getString(key) {
const value = this.getOptionalString(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalString(key) {
return this.readConfigValue(key, (value) => typeof value === "string" && value !== "" || {expected: "string"});
}
getStringArray(key) {
const value = this.getOptionalStringArray(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalStringArray(key) {
return this.readConfigValue(key, (values) => {

@@ -88,2 +173,5 @@ if (!Array.isArray(values)) {

}
fullKey(key) {
return `${this.prefix}${this.prefix ? "." : ""}${key}`;
}
readConfigValue(key, validate) {

@@ -99,4 +187,3 @@ var _a;

const {key: keyName = key, value: theValue = value, expected} = result;
const typeName = typeOf(theValue);
throw new TypeError(`Invalid type in config for key ${keyName}, got ${typeName}, wanted ${expected}`);
throw new TypeError(errors.type(this.fullKey(keyName), this.context, typeOf(theValue), expected));
}

@@ -108,3 +195,2 @@ }

const parts = key.split(".");
let value = this.data;
for (const part of parts) {

@@ -114,6 +200,13 @@ if (!CONFIG_KEY_PART_PATTERN.test(part)) {

}
}
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 {
value = void 0;
} else if (value !== void 0) {
const badKey = this.fullKey(parts.slice(0, index).join("."));
throw new TypeError(errors.type(badKey, this.context, typeOf(value), "object"));
}

@@ -124,4 +217,3 @@ }

}
ConfigReader.nullReader = new ConfigReader({});
exports.ConfigReader = ConfigReader;

47

dist/index.d.ts
declare type JsonObject = {
[key in string]: JsonValue;
[key in string]?: JsonValue;
};
declare type JsonArray = JsonValue[];
declare type JsonValue = JsonObject | JsonArray | number | string | boolean | null;
declare type AppConfig = JsonObject;
declare type AppConfig = {
context: string;
data: JsonObject;
};
declare type Config = {
keys(): string[];
get(key: string): JsonValue;
getOptional(key: string): JsonValue | undefined;
getConfig(key: string): Config;
getOptionalConfig(key: string): Config | undefined;
getConfigArray(key: string): Config[];
getNumber(key: string): number | undefined;
getBoolean(key: string): boolean | undefined;
getString(key: string): string | undefined;
getStringArray(key: string): string[] | undefined;
getOptionalConfigArray(key: string): Config[] | undefined;
getNumber(key: string): number;
getOptionalNumber(key: string): number | undefined;
getBoolean(key: string): boolean;
getOptionalBoolean(key: string): boolean | undefined;
getString(key: string): string;
getOptionalString(key: string): string | undefined;
getStringArray(key: string): string[];
getOptionalStringArray(key: string): string[] | undefined;
};

@@ -18,12 +30,23 @@

private readonly data;
private readonly context;
private readonly fallback?;
private static readonly nullReader;
private readonly prefix;
static fromConfigs(configs: AppConfig[]): ConfigReader;
constructor(data: JsonObject, fallback?: ConfigReader | undefined);
constructor(data: JsonObject | undefined, context?: string, fallback?: ConfigReader | undefined, prefix?: string);
keys(): string[];
get(key: string): JsonValue;
getOptional(key: string): JsonValue | undefined;
getConfig(key: string): ConfigReader;
getOptionalConfig(key: string): ConfigReader | undefined;
getConfigArray(key: string): ConfigReader[];
getNumber(key: string): number | undefined;
getBoolean(key: string): boolean | undefined;
getString(key: string): string | undefined;
getStringArray(key: string): string[] | undefined;
getOptionalConfigArray(key: string): ConfigReader[] | undefined;
getNumber(key: string): number;
getOptionalNumber(key: string): number | undefined;
getBoolean(key: string): boolean;
getOptionalBoolean(key: string): boolean | undefined;
getString(key: string): string;
getOptionalString(key: string): string | undefined;
getStringArray(key: string): string[];
getOptionalStringArray(key: string): string[] | undefined;
private fullKey;
private readConfigValue;

@@ -30,0 +53,0 @@ private readValue;

@@ -0,1 +1,4 @@

import cloneDeep2 from 'lodash/cloneDeep';
import mergeWith2 from 'lodash/mergeWith';
const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_][a-z][a-z0-9]*)*$/i;

@@ -20,28 +23,77 @@ function isObject(value) {

}
const errors = {
type(key, context, typeName, expected) {
return `Invalid type in config for key '${key}' in '${context}', got ${typeName}, wanted ${expected}`;
},
missing(key) {
return `Missing required config value at '${key}'`;
}
};
class ConfigReader {
constructor(data, fallback) {
constructor(data, context = "empty-config", fallback, prefix = "") {
this.data = data;
this.context = context;
this.fallback = fallback;
this.prefix = prefix;
}
static fromConfigs(configs) {
if (configs.length === 0) {
return new ConfigReader({});
return new ConfigReader(void 0);
}
return configs.reduceRight((previousReader, nextConfig) => {
return new ConfigReader(nextConfig, previousReader);
return configs.reduceRight((previousReader, {data, context}) => {
return new ConfigReader(data, context, previousReader);
}, void 0);
}
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 [...new Set([...localKeys, ...fallbackKeys])];
}
get(key) {
const value = this.getOptional(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptional(key) {
var _a;
const value = this.readValue(key);
const fallbackValue = (_a = this.fallback) == null ? void 0 : _a.getOptional(key);
if (value === void 0) {
return fallbackValue;
} else if (fallbackValue === void 0) {
return value;
}
return mergeWith2({}, {value: cloneDeep2(fallbackValue)}, {value}, (into, from) => !isObject(from) || !isObject(into) ? from : void 0).value;
}
getConfig(key) {
const value = this.getOptionalConfig(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalConfig(key) {
var _a;
const value = this.readValue(key);
const fallbackConfig = (_a = this.fallback) == null ? void 0 : _a.getConfig(key);
const fallbackConfig = (_a = this.fallback) == null ? void 0 : _a.getOptionalConfig(key);
const prefix = this.fullKey(key);
if (isObject(value)) {
return new ConfigReader(value, fallbackConfig);
return new ConfigReader(value, this.context, fallbackConfig, prefix);
}
if (value !== void 0) {
throw new TypeError(`Invalid type in config for key ${key}, got ${typeOf(value)}, wanted object`);
throw new TypeError(errors.type(this.fullKey(key), this.context, typeOf(value), "object"));
}
return fallbackConfig != null ? fallbackConfig : ConfigReader.nullReader;
return fallbackConfig;
}
getConfigArray(key) {
const value = this.getOptionalConfigArray(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalConfigArray(key) {
const configs = this.readConfigValue(key, (values) => {

@@ -58,14 +110,45 @@ if (!Array.isArray(values)) {

});
return (configs != null ? configs : []).map((obj) => new ConfigReader(obj));
if (!configs) {
return void 0;
}
return configs.map((obj, index) => new ConfigReader(obj, this.context, void 0, this.fullKey(`${key}[${index}]`)));
}
getNumber(key) {
const value = this.getOptionalNumber(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalNumber(key) {
return this.readConfigValue(key, (value) => typeof value === "number" || {expected: "number"});
}
getBoolean(key) {
const value = this.getOptionalBoolean(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalBoolean(key) {
return this.readConfigValue(key, (value) => typeof value === "boolean" || {expected: "boolean"});
}
getString(key) {
const value = this.getOptionalString(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalString(key) {
return this.readConfigValue(key, (value) => typeof value === "string" && value !== "" || {expected: "string"});
}
getStringArray(key) {
const value = this.getOptionalStringArray(key);
if (value === void 0) {
throw new Error(errors.missing(this.fullKey(key)));
}
return value;
}
getOptionalStringArray(key) {
return this.readConfigValue(key, (values) => {

@@ -83,2 +166,5 @@ if (!Array.isArray(values)) {

}
fullKey(key) {
return `${this.prefix}${this.prefix ? "." : ""}${key}`;
}
readConfigValue(key, validate) {

@@ -94,4 +180,3 @@ var _a;

const {key: keyName = key, value: theValue = value, expected} = result;
const typeName = typeOf(theValue);
throw new TypeError(`Invalid type in config for key ${keyName}, got ${typeName}, wanted ${expected}`);
throw new TypeError(errors.type(this.fullKey(keyName), this.context, typeOf(theValue), expected));
}

@@ -103,3 +188,2 @@ }

const parts = key.split(".");
let value = this.data;
for (const part of parts) {

@@ -109,6 +193,13 @@ if (!CONFIG_KEY_PART_PATTERN.test(part)) {

}
}
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 {
value = void 0;
} else if (value !== void 0) {
const badKey = this.fullKey(parts.slice(0, index).join("."));
throw new TypeError(errors.type(badKey, this.context, typeOf(value), "object"));
}

@@ -119,4 +210,3 @@ }

}
ConfigReader.nullReader = new ConfigReader({});
export { ConfigReader };
{
"name": "@backstage/config",
"description": "Config API used by Backstage core, backend, and CLI",
"version": "0.1.1-alpha.9",
"version": "0.1.1-alpha.10",
"private": false,

@@ -32,2 +32,5 @@ "publishConfig": {

},
"dependencies": {
"lodash": "^4.17.15"
},
"devDependencies": {

@@ -40,4 +43,4 @@ "@types/jest": "^25.2.2",

],
"gitHead": "73898f3084733d5c88c5a65d9989838a86a861e5",
"gitHead": "1253f82057eeb5f59b4e7c9a1f5a186a0b3c229f",
"module": "dist/index.esm.js"
}
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