@freemework/common
Version:
Common library of the Freemework Project.
124 lines • 4.7 kB
JavaScript
import { FConfiguration } from "./f_configuration.js";
import { FConfigurationException } from "./f_configuration_exception.js";
import { FConfigurationValue } from "./f_configuration_value.js";
import { FExceptionArgument } from "../exception/index.js";
export class FConfigurationChain extends FConfiguration {
get sourceURI() {
return this._sourceURI;
}
get namespaceFull() {
return this._configurations[0].namespaceFull;
}
get namespaceParent() {
return this._configurations[0].namespaceParent;
}
get keys() {
const union = new Set();
for (const item of this._configurations) {
for (const key of item.keys) {
union.add(key);
}
}
return Object.freeze([...union]);
}
constructor(...configurations) {
super();
if (configurations.length === 0) {
throw new FExceptionArgument("At least one configuration required for chain.", "configurations");
}
const innerCommaSeparatedSourceURIs = configurations
.map(s => s.sourceURI.toString())
.map(s => encodeURIComponent(s))
.join(",");
const sourceURI = `configuration:chain?sources=${innerCommaSeparatedSourceURIs}`;
this._sourceURI = new URL(sourceURI);
this._configurations = Object.freeze(configurations);
}
getArray(key, indexesName = FConfiguration.DEFAULT_INDEXES_KEY) {
const arrayNS = this.getNamespace(key);
const arrayIndexes = arrayNS.get(indexesName).asString
.split(" ")
.filter(s => s !== "");
const arrayNamespaces = arrayIndexes.map(s => {
return arrayNS.getNamespace(s);
});
return arrayNamespaces;
}
getNamespace(namespaceFull) {
const innerConfiguration = this.findNamespace(namespaceFull);
if (innerConfiguration !== null) {
return innerConfiguration;
}
// Force underlying config to raise error
for (const configuration of this._configurations) {
configuration.getNamespace(namespaceFull);
}
// just a guard, should not happens if underlying configuration is implemented correctly
throw new FConfigurationException(`Namespace was not found in the configuration.`, namespaceFull);
}
get(key, defaultData) {
const foundValue = this.find(key);
if (foundValue !== null) {
return foundValue;
}
const namespaceFull = this.namespaceFull;
const fullKey = namespaceFull !== null ? `${namespaceFull}.${key}` : key;
if (defaultData !== undefined) {
const value = FConfigurationValue.factory(fullKey, defaultData, null, null);
return value;
}
else {
throw new FConfigurationException("Current configuration does not have such key. Check your configuration.", fullKey);
}
}
findNamespace(namespaceFull) {
const innerConfigurations = [];
for (const configuration of this._configurations) {
if (configuration.hasNamespace(namespaceFull)) {
innerConfigurations.push(configuration.getNamespace(namespaceFull));
}
}
if (innerConfigurations.length === 0) {
return null;
}
return new FConfigurationChain(...innerConfigurations);
}
find(key) {
for (let itemIndex = 0; itemIndex < this._configurations.length; ++itemIndex) {
const configurationItem = this._configurations[itemIndex];
if (configurationItem.has(key)) {
return configurationItem.get(key);
}
}
return null;
}
hasNamespace(namespaceFull) {
for (const configuration of this._configurations) {
if (configuration.hasNamespace(namespaceFull)) {
return true;
}
else if (configuration.has(namespaceFull)) {
const isMaskedNamespace = configuration.get(namespaceFull).isNull;
if (isMaskedNamespace) {
// This is masked namespace
return false;
}
}
}
return false;
}
has(key) {
for (const configuration of this._configurations) {
if (configuration.has(key)) {
return true;
}
}
return false; // no one configurations contains key
}
_sourceURI;
/**
* List of inner configurations. Values from first more important!
*/
_configurations;
}
//# sourceMappingURL=f_configuration_chain.js.map