@itwin/core-backend
Version:
iTwin.js backend components
154 lines • 5.85 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Workspace
*/
import * as fs from "fs-extra";
import { parse } from "json5";
import { extname, join } from "path";
import { BeEvent } from "@itwin/core-bentley";
import { IModelJsFs } from "../../IModelJsFs";
import { Setting } from "../../workspace/Settings";
import { IModelHost } from "../../IModelHost";
import { _implementationProhibited } from "../Symbols";
const dictionaryMatches = (d1, d2) => {
return (d1.workspaceDb === d2.workspaceDb) && (d1.name === d2.name);
};
class SettingsDictionaryImpl {
[_implementationProhibited] = undefined;
props;
settings;
constructor(props, settings) {
this.props = { ...props }; // make a copy so it can't be changed by caller
this.settings = settings;
}
getSetting(settingName) {
const value = this.settings[settingName];
return undefined !== value ? Setting.clone(value) : undefined;
}
}
/**
* Internal implementation of Settings interface.
* @internal
*/
export class SettingsImpl {
[_implementationProhibited] = undefined;
dictionaries = [];
verifyPriority(_priority) { }
close() { }
onSettingsChanged = new BeEvent();
addFile(fileName, priority) {
this.addJson({ name: fileName, priority }, fs.readFileSync(fileName, "utf-8"));
}
addDirectory(dirName, priority) {
for (const fileName of IModelJsFs.readdirSync(dirName)) {
const ext = extname(fileName);
if (ext === ".json5" || ext === ".json")
this.addFile(join(dirName, fileName), priority);
}
}
addJson(props, settingsJson) {
this.addDictionary(props, parse(settingsJson));
}
addDictionary(props, settings) {
this.verifyPriority(props.priority);
this.dropDictionary(props, false); // make sure we don't have the same dictionary twice
const dict = new SettingsDictionaryImpl(props, settings);
const doAdd = () => {
for (let i = 0; i < this.dictionaries.length; ++i) {
if (this.dictionaries[i].props.priority <= dict.props.priority) {
this.dictionaries.splice(i, 0, dict);
return;
}
}
this.dictionaries.push(dict);
};
doAdd();
this.onSettingsChanged.raiseEvent();
}
getDictionary(source) {
for (const dictionary of this.dictionaries) {
if (dictionaryMatches(dictionary.props, source))
return dictionary;
}
return undefined;
}
dropDictionary(source, raiseEvent = true) {
for (let i = 0; i < this.dictionaries.length; ++i) {
if (dictionaryMatches(this.dictionaries[i].props, source)) {
this.dictionaries.splice(i, 1);
if (raiseEvent)
this.onSettingsChanged.raiseEvent();
return true;
}
}
return false;
}
*getSettingEntries(settingName) {
for (const dictionary of this.dictionaries) {
const value = dictionary.getSetting(settingName);
if (undefined !== value) {
yield { value, dictionary };
}
}
}
*getSettingValues(settingName) {
for (const entry of this.getSettingEntries(settingName)) {
yield entry.value;
}
}
getSetting(settingName, defaultValue) {
for (const value of this.getSettingValues(settingName)) {
return value;
}
return defaultValue;
}
// get the setting and verify the result is either undefined or the correct type. If so, return it. Otherwise throw an exception.
getResult(name, expectedType) {
const out = this.getSetting(name);
if (out === undefined || typeof out === expectedType)
return out;
throw new Error(`setting "${name}" is not a ${expectedType}: ${typeof out}`);
}
getString(name, defaultValue) {
return this.getResult(name, "string") ?? defaultValue;
}
getBoolean(name, defaultValue) {
return this.getResult(name, "boolean") ?? defaultValue;
}
getNumber(name, defaultValue) {
return this.getResult(name, "number") ?? defaultValue;
}
getObject(name, defaultValue) {
const out = this.getResult(name, "object");
return out ? IModelHost.settingsSchemas.validateSetting(out, name) : defaultValue;
}
getArray(name, defaultValue) {
if (IModelHost.settingsSchemas.settingDefs.get(name)?.combineArray) {
return this.getCombinedArray(name, defaultValue);
}
const out = this.getSetting(name);
if (out === undefined)
return defaultValue;
if (!Array.isArray(out))
throw new Error(`setting ${name} is not an array: ${out}`);
return IModelHost.settingsSchemas.validateSetting(out, name);
}
getCombinedArray(name, defaultValue) {
let foundSetting = false;
const out = [];
for (const array of this.getSettingValues(name)) {
foundSetting = true;
IModelHost.settingsSchemas.validateSetting(array, name);
for (const value of array) {
if (undefined === out.find((x) => Setting.areEqual(x, value))) {
out.push(value);
}
}
}
return foundSetting ? out : defaultValue;
}
}
//# sourceMappingURL=SettingsImpl.js.map