forked from tools/josh
1
0
Fork 0
josh/src/main/js/Environment.ts

157 lines
5.1 KiB
TypeScript

import {IllegalArgumentError} from "./Shared";
/**
* A set of environment variables.
*
* Variables can be marked as read-only. This ensures that the methods prefixed with `safe` cannot set or delete these
* variables. All other methods can still affect read-only variables.
*/
export class Environment {
/**
* The environment variables and associated values.
*/
private readonly _variables: { [key: string]: string } = {};
/**
* The keys of the environment variables that are read-only.
*/
private readonly readonlyKeys: string[];
/**
* Constructs a new set of environment variables where the given keys are read-only.
*
* @param readonlyKeys the keys of the environment variables that are read-only
* @param variables the variables to load by default
*/
constructor(readonlyKeys: string[] = [], variables: { [key: string]: any } = {}) {
this.readonlyKeys = readonlyKeys;
this.load(variables);
}
/**
* Returns a copy of the variables contained within this environment.
*/
get variables(): { [key: string]: string } {
return Object.assign({}, this._variables);
}
/**
* Deletes all environment variables, including the read-only variables.
*/
clear(): void {
for (const key of Object.getOwnPropertyNames(this._variables))
this.delete(key);
}
/**
* Deletes the environment variable with the given key, even if it is read-only.
*
* @param key the key of the environment variable to delete
* @throws if the key is invalid
*/
delete(key: string): void {
if (!Environment.isKeyValid(key))
throw new IllegalArgumentError("Environment variable keys can only contain alphanumerical characters and underscores.");
delete this._variables[key];
}
/**
* Deletes the environment variable with the given key, unless it is read-only.
*
* @param key the key of the environment variable to delete
* @throws if the key is invalid or the environment variable to delete is read-only
*/
safeDelete(key: string): void {
if (this.readonlyKeys.indexOf(key) >= 0)
throw new IllegalArgumentError("Cannot set read-only environment variable.");
this.delete(key);
}
/**
* Returns the value of the environment variable with the given key, or throws an exception if there is no such
* environment variable.
*
* @param key the key of the environment variable to return
* @throws if there is no such environment variable
*/
get(key: string): string {
if (!this.has(key))
throw new IllegalArgumentError(`Cannot read non-existing environment variable '${key}'.`);
return this._variables[key];
}
/**
* Returns the value of the environment variable with the given key, or the given default value if there is no such
* environment variable.
*
* @param key the key of the environment variable to return
* @param def the default value to return in case there is no environment variable with the given key
*/
getOrDefault(key: string, def: string): string {
return this._variables[key] ?? def;
}
/**
* Returns `true` if and only if there is an environment variable with the given key.
*
* @param key the key of the environment variable to check
*/
has(key: string): boolean {
return this._variables.hasOwnProperty(key);
}
/**
* Loads all variables in the given object into this environment.
*
* @param variables the variables to load
*/
load(variables: { [key: string]: any }): void {
for (const key of Object.getOwnPropertyNames(variables))
this.set(key, variables[key]);
}
/**
* Sets the value of the environment variable with the given key, even if it is read-only.
*
* @param key the key of the environment variable to set
* @param value the value to set the environment variable to
* @throws if the key is invalid
*/
set(key: string, value: string): void {
if (!Environment.isKeyValid(key))
throw new IllegalArgumentError("Environment variable keys can only contain alphanumerical characters and underscores.");
this._variables[key] = value;
}
/**
* Sets the value of the environment variable with the given key, unless it is read-only.
*
* @param key the key of the environment variable to set
* @param value the value to set the environment variable to
* @throws if the key is invalid or the environment variable to set is read-only
*/
safeSet(key: string, value: string): void {
if (this.readonlyKeys.indexOf(key) >= 0)
throw new IllegalArgumentError("Cannot set read-only environment variable.");
this.set(key, value);
}
/**
* Returns `true` if and only if the given key has a valid format.
*
* @param key the key to validate
*/
private static isKeyValid(key: string): boolean {
return !!key.match(/^[0-9a-z_]+$/i);
}
}