wj-config
Version:
Javascript configuration module for NodeJS and browser frameworks such as React that works like ASP.net configuration where data sources are specified (usually JSON files) and environment variables can contribute/overwrite values by following a naming con
90 lines (89 loc) • 3.35 kB
JavaScript
import { InvalidEnvNameError } from "./EnvConfigError.js";
import { EnvironmentDefinition } from "./EnvironmentDefinition.js";
import { isArray } from "./helpers.js";
function ensureEnvDefinition(env) {
if (typeof env === 'string') {
return new EnvironmentDefinition(env);
}
else if (env === null || env === undefined) {
throw new TypeError('Environment cannot be null or undefined.');
}
return env;
}
function capitalize(text) {
return text[0].toLocaleUpperCase() + text.slice(1);
}
/**
* Builds an environment object with the provided environment information.
* @param currentEnvironment The application's current environment.
* @param possibleEnvironments The complete list of all possible environments.
* @returns The newly created `IEnvironment<TEnvironments>` object.
*/
export function buildEnvironment(possibleEnvironments, currentEnvironment) {
const envDef = ensureEnvDefinition(currentEnvironment);
const env = {
get all() {
return possibleEnvironments;
},
get current() {
return envDef;
}
};
env.hasAnyTrait = hasAnyTrait.bind(env);
env.hasTraits = hasTraits.bind(env);
let validCurrentEnvironment = false;
env.all.forEach((envName) => {
env[`is${capitalize(envName)}`] = function () {
return env.current.name === envName;
};
validCurrentEnvironment = validCurrentEnvironment || env.current.name === envName;
});
// Throw if the current environment name was not found among the possible environment names..
if (!validCurrentEnvironment) {
throw new InvalidEnvNameError(env.current.name);
}
return env;
function normalizeTestTraits(traits) {
if (typeof traits === 'number' && typeof this.current.traits !== 'number') {
throw new TypeError('Cannot test a numeric trait against string traits.');
}
if ((typeof traits === 'string' || (isArray(traits) && typeof traits[0] === 'string')) && typeof this.current.traits === 'number') {
throw new TypeError('Cannot test string traits against a numeric trait.');
}
if (typeof traits === 'string') {
traits = [traits];
}
return traits;
}
function hasTraits(traits) {
traits = normalizeTestTraits.call(this, traits);
const hasBitwiseTraits = (t) => (this.current.traits & t) === t && t > 0;
const hasStringTraits = (t) => {
let has = true;
t.forEach(it => {
has = has && this.current.traits.includes(it);
});
return has;
};
if (typeof traits === "number") {
return hasBitwiseTraits(traits);
}
return hasStringTraits(traits);
}
function hasAnyTrait(traits) {
traits = normalizeTestTraits.call(this, traits);
const hasAnyBitwiseTrait = (t) => (this.current.traits & t) > 0;
const hasAnyStringTrait = (t) => {
for (let x of t) {
if (this.current.traits.includes(x)) {
return true;
}
}
return false;
};
if (typeof traits === "number") {
return hasAnyBitwiseTrait(traits);
}
return hasAnyStringTrait(traits);
}
}