@itwin/core-backend 3.0.0-dev.103 → 3.0.0-dev.107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Settings.d.ts","sourceRoot":"","sources":["../../../src/workspace/Settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module Workspace
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ITwinSettings = exports.SettingsPriority = void 0;
11
+ const fs = require("fs-extra");
12
+ const json5_1 = require("json5");
13
+ const core_bentley_1 = require("@itwin/core-bentley");
14
+ const SettingsSpecRegistry_1 = require("./SettingsSpecRegistry");
15
+ /**
16
+ * Values for SettingsPriority determine the sort order for Settings. Higher values take precedence over lower values.
17
+ * @beta
18
+ */
19
+ var SettingsPriority;
20
+ (function (SettingsPriority) {
21
+ /** values supplied default-settings files */
22
+ SettingsPriority[SettingsPriority["defaults"] = 100] = "defaults";
23
+ /** values supplied by applications at runtime */
24
+ SettingsPriority[SettingsPriority["application"] = 200] = "application";
25
+ /** values that apply to all iTwins for an organization. */
26
+ SettingsPriority[SettingsPriority["organization"] = 300] = "organization";
27
+ /** values that apply to all iModels in an iTwin. */
28
+ SettingsPriority[SettingsPriority["iTwin"] = 400] = "iTwin";
29
+ /** values that apply to a single iModel. */
30
+ SettingsPriority[SettingsPriority["iModel"] = 500] = "iModel";
31
+ })(SettingsPriority = exports.SettingsPriority || (exports.SettingsPriority = {}));
32
+ /** @internal */
33
+ function deepClone(obj) {
34
+ if (!obj || typeof obj !== "object")
35
+ return obj;
36
+ const result = Array.isArray(obj) ? [] : {};
37
+ Object.keys(obj).forEach((key) => {
38
+ const val = obj[key];
39
+ if (val && typeof val === "object") {
40
+ result[key] = deepClone(val);
41
+ }
42
+ else {
43
+ result[key] = val;
44
+ }
45
+ });
46
+ return result;
47
+ }
48
+ class SettingsDictionary {
49
+ constructor(name, priority, settings) {
50
+ this.name = name;
51
+ this.priority = priority;
52
+ this.settings = settings;
53
+ }
54
+ getSetting(settingName) {
55
+ return this.settings[settingName];
56
+ }
57
+ }
58
+ /**
59
+ * Internal implementation of Settings interface.
60
+ * @internal
61
+ */
62
+ class ITwinSettings {
63
+ constructor() {
64
+ this._dictionaries = [];
65
+ this.onSettingsChanged = new core_bentley_1.BeEvent();
66
+ SettingsSpecRegistry_1.SettingsSpecRegistry.onSpecsChanged.addListener(() => this.updateDefaults());
67
+ this._dictionaries = [];
68
+ this.updateDefaults();
69
+ }
70
+ updateDefaults() {
71
+ const defaults = {};
72
+ for (const [specName, val] of SettingsSpecRegistry_1.SettingsSpecRegistry.allSpecs)
73
+ defaults[specName] = val.default;
74
+ this.addDictionary("_default_", 0, defaults);
75
+ }
76
+ addFile(fileName, priority) {
77
+ this.addJson(fileName, priority, fs.readFileSync(fileName, "utf-8"));
78
+ }
79
+ addJson(dictionaryName, priority, settingsJson) {
80
+ this.addDictionary(dictionaryName, priority, (0, json5_1.parse)(settingsJson));
81
+ }
82
+ addDictionary(dictionaryName, priority, settings) {
83
+ this.dropDictionary(dictionaryName, false); // make sure we don't have the same dictionary twice
84
+ const file = new SettingsDictionary(dictionaryName, priority, settings);
85
+ for (let i = 0; i < this._dictionaries.length; ++i) {
86
+ if (this._dictionaries[i].priority <= file.priority) {
87
+ this._dictionaries.splice(i, 0, file);
88
+ return;
89
+ }
90
+ }
91
+ this._dictionaries.push(file);
92
+ this.onSettingsChanged.raiseEvent();
93
+ }
94
+ dropDictionary(dictionaryName, raiseEvent = true) {
95
+ for (let i = 0; i < this._dictionaries.length; ++i) {
96
+ if (this._dictionaries[i].name === dictionaryName) {
97
+ this._dictionaries.splice(i, 1);
98
+ if (raiseEvent)
99
+ this.onSettingsChanged.raiseEvent();
100
+ return true;
101
+ }
102
+ }
103
+ return false;
104
+ }
105
+ resolveSetting(name, resolver, defaultValue) {
106
+ for (const dict of this._dictionaries) {
107
+ const val = dict.getSetting(name);
108
+ const resolved = val && resolver(val, dict.name, dict.priority);
109
+ if (undefined !== resolved)
110
+ return resolved;
111
+ }
112
+ return defaultValue;
113
+ }
114
+ getSetting(name, defaultValue) {
115
+ var _a;
116
+ return (_a = this.resolveSetting(name, (val) => deepClone(val))) !== null && _a !== void 0 ? _a : defaultValue;
117
+ }
118
+ /** for debugging. Returns an array of all values for a setting, sorted by priority.
119
+ * @note values are not cloned. Do not modify objects or arrays.
120
+ */
121
+ inspectSetting(name) {
122
+ const all = [];
123
+ this.resolveSetting(name, (value, dictionary, priority) => { all.push({ value, dictionary, priority }); return undefined; });
124
+ return all;
125
+ }
126
+ getString(name, defaultValue) {
127
+ const out = this.getSetting(name);
128
+ return typeof out === "string" ? out : defaultValue;
129
+ }
130
+ getBoolean(name, defaultValue) {
131
+ const out = this.getSetting(name);
132
+ return typeof out === "boolean" ? out : defaultValue;
133
+ }
134
+ getNumber(name, defaultValue) {
135
+ const out = this.getSetting(name);
136
+ return typeof out === "number" ? out : defaultValue;
137
+ }
138
+ getObject(name, defaultValue) {
139
+ const out = this.getSetting(name);
140
+ return typeof out === "object" ? out : defaultValue;
141
+ }
142
+ getArray(name, defaultValue) {
143
+ const out = this.getSetting(name);
144
+ return Array.isArray(out) ? out : defaultValue;
145
+ }
146
+ }
147
+ exports.ITwinSettings = ITwinSettings;
148
+ //# sourceMappingURL=Settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Settings.js","sourceRoot":"","sources":["../../../src/workspace/Settings.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Workspace\r\n */\r\n\r\nimport * as fs from \"fs-extra\";\r\nimport { parse } from \"json5\";\r\nimport { BeEvent, JSONSchemaType } from \"@itwin/core-bentley\";\r\nimport { SettingsSpecRegistry } from \"./SettingsSpecRegistry\";\r\nimport { LocalFileName } from \"@itwin/core-common\";\r\n\r\n/** The type of a Setting, according to its schema\r\n * @beta\r\n */\r\nexport type SettingType = JSONSchemaType;\r\n\r\n/**\r\n * The name of a Setting. SettingNames must be valid JavaScript property names, defined in a [[SettingSpec]].\r\n * @see [SettingName]($docs/learning/backend/Workspace#settingnames)\r\n * @beta\r\n */\r\nexport type SettingName = string;\r\n\r\n/** The name of a [[SettingDictionary]]. `SettingDictionary`s are stored in [[Settings]] and may be removed by DictionaryName.\r\n * DictionaryNames must be valid JavaScript property names.\r\n * @beta\r\n */\r\nexport type DictionaryName = string;\r\n\r\n/**\r\n * A function called by [[Settings.resolveSetting]] for every SettingDictionary with a Setting that matches a name. The\r\n * SettingDictionaries are sorted by priority and this function is called in priority order with the highest priority first.\r\n * When this function returns a non-undefined value, the iteration is stopped and that value is returned. In this way,\r\n * applications can \"combine\" the prioritized Setting values as appropriate. The default implementation of this function\r\n * used by [[Settings.getSetting]] merely returns a clone of the value the first time it is called, so the highest priority\r\n * value is returned.\r\n * @beta\r\n */\r\nexport type SettingResolver<T> = (val: T, dict: DictionaryName, priority: SettingsPriority) => T | undefined;\r\n\r\n/** An entry in the array returned by [[Settings.inspectSetting]]\r\n * @beta\r\n *\r\n */\r\nexport interface SettingInspector<T> { value: T, dictionary: DictionaryName, priority: number }\r\n\r\n/** An object with string-named members (as opposed to an array object).\r\n * @beta\r\n */\r\nexport interface SettingObject {\r\n [name: string]: SettingType;\r\n}\r\n\r\n/**\r\n * An object with Settings as its members. A SettingDictionary also has a name and generally comes from a parsed JSON file, but\r\n * may also be created in memory by applications\r\n * @beta\r\n */\r\nexport type SettingDictionary = SettingObject;\r\n\r\n/**\r\n * Values for SettingsPriority determine the sort order for Settings. Higher values take precedence over lower values.\r\n * @beta\r\n*/\r\nexport enum SettingsPriority {\r\n /** values supplied default-settings files */\r\n defaults = 100,\r\n /** values supplied by applications at runtime */\r\n application = 200,\r\n /** values that apply to all iTwins for an organization. */\r\n organization = 300,\r\n /** values that apply to all iModels in an iTwin. */\r\n iTwin = 400,\r\n /** values that apply to a single iModel. */\r\n iModel = 500,\r\n}\r\n\r\n/** The current set of Settings for a Workspace.\r\n * @beta\r\n */\r\nexport interface Settings {\r\n /** Event raised whenever a SettingsDictionary is added or removed. */\r\n readonly onSettingsChanged: BeEvent<() => void>;\r\n\r\n /** Add a SettingDictionary from a local settings file. The file should be in [JSON5](https://json5.org/) format. It is read\r\n * and parsed and the fileName is used as the DictionaryName.\r\n * @param fileName the name of a local settings file of the SettingDictionary. This becomes the DictionaryName.\r\n * @param priority the SettingsPriority for the SettingDictionary\r\n * @note If the SettingDictionary was previously added, the new content overrides the old content.\r\n */\r\n addFile(fileName: LocalFileName, priority: SettingsPriority): void;\r\n\r\n /** Add a SettingDictionary from a JSON5 stringified string. The string is parsed and the resultant object is added as a SettingDictionary.\r\n * @param dictionaryName the name of the SettingDictionary\r\n * @param priority the SettingsPriority for the SettingDictionary\r\n * @param settingsJson the JSON5 stringified string to be parsed.\r\n * @note If the SettingDictionary was previously added, the new content overrides the old content.\r\n */\r\n addJson(dictionaryName: DictionaryName, priority: SettingsPriority, settingsJson: string): void;\r\n\r\n /** Add a SettingDictionary object.\r\n * @param dictionaryName the name of the SettingDictionary\r\n * @param priority the SettingsPriority for the SettingDictionary\r\n * @param settings the SettingDictionary object to be added.\r\n * @note If the SettingDictionary was previously added, the new content overrides the old content.\r\n */\r\n addDictionary(dictionaryName: DictionaryName, priority: SettingsPriority, settings: SettingDictionary): void;\r\n\r\n /** Remove a SettingDictionary by name. */\r\n dropDictionary(dictionaryName: DictionaryName): void;\r\n\r\n /**\r\n * Resolve a setting, by name, using a SettingResolver.\r\n * @param settingName The name of the setting to resolve\r\n * @param resolver function to be called for each SettingDictionary with a matching Setting. Iteration stops when it returns a non-undefined value.\r\n * @param defaultValue value returned if settingName is not present in any SettingDictionary or resolver never returned a value.\r\n * @returns the resolved setting value.\r\n */\r\n resolveSetting<T extends SettingType>(settingName: SettingName, resolver: SettingResolver<T>, defaultValue?: T): T | undefined;\r\n resolveSetting<T extends SettingType>(settingName: SettingName, resolver: SettingResolver<T>, defaultValue: T): T;\r\n\r\n /** Get the highest priority setting for a SettingName.\r\n * @param settingName The name of the setting\r\n * @param defaultValue value returned if settingName is not present in any SettingDictionary.\r\n * @note This method is generic on SettingType, but no type checking is actually performed at run time. So, if you\r\n * use this method to get a setting with an expected type, but its value is a different type, the return type of this method will be wrong.\r\n * You must always type check the result. Use the non-generic \"get\" methods (e.g. [[getString]]) if you only want the value\r\n * if its type is correct.\r\n */\r\n getSetting<T extends SettingType>(settingName: SettingName, defaultValue?: T): T | undefined;\r\n\r\n /** Get a string setting by SettingName.\r\n * @param settingName The name of the setting\r\n * @param defaultValue value returned if settingName is not present in any SettingDictionary, or if the highest priority setting is not a string.\r\n */\r\n getString(settingName: SettingName, defaultValue: string): string;\r\n getString(settingName: SettingName, defaultValue?: string): string | undefined;\r\n\r\n /** Get a boolean setting by SettingName.\r\n * @param settingName The name of the setting\r\n * @param defaultValue value returned if settingName is not present in any SettingDictionary, or if the highest priority setting is not a boolean.\r\n */\r\n getBoolean(settingName: SettingName, defaultValue: boolean): boolean;\r\n getBoolean(settingName: SettingName, defaultValue?: boolean): boolean | undefined;\r\n\r\n /** Get a number setting by SettingName.\r\n * @param settingName The name of the setting\r\n * @param defaultValue value returned if settingName is not present in any SettingDictionary, or if the highest priority setting is not a number.\r\n */\r\n getNumber(settingName: SettingName, defaultValue: number): number;\r\n getNumber(settingName: SettingName): number | undefined;\r\n\r\n /** Get an object setting by SettingName.\r\n * @param settingName The name of the setting\r\n * @param defaultValue value returned if settingName is not present in any SettingDictionary, or if the highest priority setting is not an object.\r\n */\r\n getObject(settingName: SettingName, defaultValue: SettingObject): SettingObject;\r\n getObject(settingName: SettingName): SettingObject | undefined;\r\n\r\n /** Get an array setting by SettingName.\r\n * @param settingName The name of the setting\r\n * @param defaultValue value returned if settingName is not present in any SettingDictionary, or if the highest priority setting is not an array.\r\n */\r\n getArray<T>(settingName: SettingName, defaultValue: Array<T>): Array<T>;\r\n getArray<T>(settingName: SettingName): Array<T> | undefined;\r\n\r\n /** Get an array of [[SettingInspector] objects, sorted in priority order, for all Settings that match a SettingName.\r\n * @note this method is mainly for debugging and diagnostics.\r\n */\r\n inspectSetting<T extends SettingType>(name: SettingName): SettingInspector<T>[];\r\n}\r\n\r\n/** @internal */\r\nfunction deepClone<T extends SettingType>(obj: any): T {\r\n if (!obj || typeof obj !== \"object\")\r\n return obj;\r\n\r\n const result = Array.isArray(obj) ? [] : {} as any;\r\n Object.keys(obj).forEach((key: string) => {\r\n const val = obj[key];\r\n if (val && typeof val === \"object\") {\r\n result[key] = deepClone(val);\r\n } else {\r\n result[key] = val;\r\n }\r\n });\r\n return result;\r\n}\r\n\r\nclass SettingsDictionary {\r\n public constructor(public readonly name: string, public readonly priority: SettingsPriority, public readonly settings: SettingDictionary) { }\r\n public getSetting<T extends SettingType>(settingName: string): SettingType | undefined {\r\n return this.settings[settingName] as T | undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Internal implementation of Settings interface.\r\n * @internal\r\n */\r\nexport class ITwinSettings implements Settings {\r\n private _dictionaries: SettingsDictionary[] = [];\r\n public readonly onSettingsChanged = new BeEvent<() => void>();\r\n\r\n private updateDefaults() {\r\n const defaults: SettingDictionary = {};\r\n for (const [specName, val] of SettingsSpecRegistry.allSpecs)\r\n defaults[specName] = val.default!;\r\n this.addDictionary(\"_default_\", 0, defaults);\r\n }\r\n\r\n public constructor() {\r\n SettingsSpecRegistry.onSpecsChanged.addListener(() => this.updateDefaults());\r\n this._dictionaries = [];\r\n this.updateDefaults();\r\n }\r\n\r\n public addFile(fileName: LocalFileName, priority: SettingsPriority) {\r\n this.addJson(fileName, priority, fs.readFileSync(fileName, \"utf-8\"));\r\n }\r\n\r\n public addJson(dictionaryName: string, priority: SettingsPriority, settingsJson: string) {\r\n this.addDictionary(dictionaryName, priority, parse(settingsJson));\r\n }\r\n\r\n public addDictionary(dictionaryName: string, priority: SettingsPriority, settings: SettingDictionary) {\r\n this.dropDictionary(dictionaryName, false); // make sure we don't have the same dictionary twice\r\n const file = new SettingsDictionary(dictionaryName, priority, settings);\r\n for (let i = 0; i < this._dictionaries.length; ++i) {\r\n if (this._dictionaries[i].priority <= file.priority) {\r\n this._dictionaries.splice(i, 0, file);\r\n return;\r\n }\r\n }\r\n this._dictionaries.push(file);\r\n this.onSettingsChanged.raiseEvent();\r\n }\r\n\r\n public dropDictionary(dictionaryName: DictionaryName, raiseEvent = true) {\r\n for (let i = 0; i < this._dictionaries.length; ++i) {\r\n if (this._dictionaries[i].name === dictionaryName) {\r\n this._dictionaries.splice(i, 1);\r\n if (raiseEvent)\r\n this.onSettingsChanged.raiseEvent();\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n public resolveSetting<T extends SettingType>(name: SettingName, resolver: SettingResolver<T>, defaultValue?: T): T | undefined {\r\n for (const dict of this._dictionaries) {\r\n const val = dict.getSetting(name) as T | undefined;\r\n const resolved = val && resolver(val, dict.name, dict.priority);\r\n if (undefined !== resolved)\r\n return resolved;\r\n }\r\n return defaultValue;\r\n }\r\n\r\n public getSetting<T extends SettingType>(name: SettingName, defaultValue?: T): T | undefined {\r\n return this.resolveSetting(name, (val) => deepClone<T>(val)) ?? defaultValue;\r\n }\r\n\r\n /** for debugging. Returns an array of all values for a setting, sorted by priority.\r\n * @note values are not cloned. Do not modify objects or arrays.\r\n */\r\n public inspectSetting<T extends SettingType>(name: SettingName): SettingInspector<T>[] {\r\n const all: SettingInspector<T>[] = [];\r\n this.resolveSetting<T>(name, (value, dictionary, priority) => { all.push({ value, dictionary, priority }); return undefined; });\r\n return all;\r\n }\r\n\r\n public getString(name: SettingName, defaultValue: string): string;\r\n public getString(name: SettingName): string | undefined;\r\n public getString(name: SettingName, defaultValue?: string): string | undefined {\r\n const out = this.getSetting<string>(name);\r\n return typeof out === \"string\" ? out : defaultValue;\r\n }\r\n public getBoolean(name: SettingName, defaultValue: boolean): boolean;\r\n public getBoolean(name: SettingName): boolean | undefined;\r\n public getBoolean(name: SettingName, defaultValue?: boolean): boolean | undefined {\r\n const out = this.getSetting<boolean>(name);\r\n return typeof out === \"boolean\" ? out : defaultValue;\r\n }\r\n public getNumber(name: SettingName, defaultValue: number): number;\r\n public getNumber(name: SettingName): number | undefined;\r\n public getNumber(name: SettingName, defaultValue?: number): number | undefined {\r\n const out = this.getSetting<number>(name);\r\n return typeof out === \"number\" ? out : defaultValue;\r\n }\r\n public getObject(name: SettingName, defaultValue: SettingObject): SettingObject;\r\n public getObject(name: SettingName): SettingObject | undefined;\r\n public getObject(name: SettingName, defaultValue?: SettingObject): SettingObject | undefined {\r\n const out = this.getSetting<SettingObject>(name);\r\n return typeof out === \"object\" ? out : defaultValue;\r\n }\r\n public getArray<T>(name: SettingName, defaultValue: Array<T>): Array<T>;\r\n public getArray<T>(name: SettingName): Array<T> | undefined;\r\n public getArray<T>(name: SettingName, defaultValue?: Array<T>): Array<T> | undefined {\r\n const out = this.getSetting<Array<T>>(name);\r\n return Array.isArray(out) ? out : defaultValue;\r\n }\r\n}\r\n"]}
@@ -0,0 +1,68 @@
1
+ /** @packageDocumentation
2
+ * @module Workspace
3
+ */
4
+ import { BeEvent, JSONSchema, JSONSchemaTypeName } from "@itwin/core-bentley";
5
+ /**
6
+ * The properties of a Setting, used by the settings editor. This interface also includes the
7
+ * default value if it is not specified in any Settings file.
8
+ * This interface includes all members of [JSONSchema]($bentley) with the extensions added by VSCode.
9
+ * @beta
10
+ */
11
+ export interface SettingSpec extends Readonly<JSONSchema> {
12
+ type: JSONSchemaTypeName | JSONSchemaTypeName[];
13
+ /** labels for items of an enum. */
14
+ readonly enumItemLabels?: string[];
15
+ /** whether the editor should show multiple lines. */
16
+ readonly multilineEdit?: true;
17
+ }
18
+ /**
19
+ * The properties of a group of [[SettingSpec]]s for an application. Groups can be added and removed from the registry
20
+ * and are identified by their (required) `groupName` member
21
+ * @beta
22
+ */
23
+ export interface SettingsGroupSpec {
24
+ readonly groupName: string;
25
+ readonly properties: {
26
+ [name: string]: SettingSpec;
27
+ };
28
+ readonly order?: number;
29
+ readonly title?: string;
30
+ readonly description?: string;
31
+ readonly extensionId?: string;
32
+ }
33
+ /**
34
+ * The registry of available [[SettingsGroupSpec]]s.
35
+ * The registry is used for editing Settings files and for finding default values for settings.
36
+ * @beta
37
+ */
38
+ export declare class SettingsSpecRegistry {
39
+ private constructor();
40
+ private static readonly _allGroups;
41
+ /** a map of all registered [[SettingSpec]]s */
42
+ static readonly allSpecs: Map<string, SettingSpec>;
43
+ /** event that signals that the values in [[allSpecs]] have changed in some way. */
44
+ static readonly onSpecsChanged: BeEvent<() => void>;
45
+ /** Clear the contents of the registry and remove all event listeners.
46
+ * @note This is really only necessary for tests of the Settings system.
47
+ * @internal
48
+ */
49
+ static reset(): void;
50
+ /**
51
+ * Add one or more [[SettingsGroupSpec]]s to the registry. `SettingsGroupSpec`s must include a `groupName` member that is used
52
+ * to identify the group. If a group with the same name is already registered, the old values are first removed and then the new group is added.
53
+ * @returns an array of problems found adding properties of the supplied group(s).
54
+ */
55
+ static addGroup(settingsGroup: SettingsGroupSpec | SettingsGroupSpec[]): string[];
56
+ /** Add a [[SettingsGroupSpec]] from stringified json5. */
57
+ static addJson(settingSpecJson: string): string[];
58
+ /** Add a [[SettingsGroupSpec]] from a json5 file. */
59
+ static addFile(fileName: string): string[];
60
+ /** Remove a previously added [[SettingsGroupSpec]] by groupName */
61
+ static removeGroup(groupName: string): void;
62
+ private static doAdd;
63
+ private static doRemove;
64
+ private static validateProperty;
65
+ private static validateAndAdd;
66
+ private static getDefaultValue;
67
+ }
68
+ //# sourceMappingURL=SettingsSpecRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsSpecRegistry.d.ts","sourceRoot":"","sources":["../../../src/workspace/SettingsSpecRegistry.ts"],"names":[],"mappings":"AAIA;;GAEG;AAIH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAkB,kBAAkB,EAAW,MAAM,qBAAqB,CAAC;AAEvG;;;;;GAKG;AACH,MAAM,WAAW,WAAY,SAAQ,QAAQ,CAAC,UAAU,CAAC;IACvD,IAAI,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,CAAC;IAChD,mCAAmC;IACnC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,qDAAqD;IACrD,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,CAAC;IACrD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,qBAAa,oBAAoB;IAC/B,OAAO;IACP,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAwC;IAC1E,+CAA+C;IAC/C,gBAAuB,QAAQ,2BAAkC;IACjE,mFAAmF;IACnF,gBAAuB,cAAc,gBAAqB,IAAI,EAAI;IAElE;;;OAGG;WACW,KAAK;IAMnB;;;;OAIG;WACW,QAAQ,CAAC,aAAa,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,GAAG,MAAM,EAAE;IAUxF,0DAA0D;WAC5C,OAAO,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE;IAIxD,qDAAqD;WACvC,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAIjD,mEAAmE;WACrD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKlD,OAAO,CAAC,MAAM,CAAC,KAAK;IAWpB,OAAO,CAAC,MAAM,CAAC,QAAQ;IASvB,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAS/B,OAAO,CAAC,MAAM,CAAC,cAAc;IAmB7B,OAAO,CAAC,MAAM,CAAC,eAAe;CAkB/B"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module Workspace
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.SettingsSpecRegistry = void 0;
11
+ const fs = require("fs-extra");
12
+ const json5_1 = require("json5");
13
+ const core_bentley_1 = require("@itwin/core-bentley");
14
+ /**
15
+ * The registry of available [[SettingsGroupSpec]]s.
16
+ * The registry is used for editing Settings files and for finding default values for settings.
17
+ * @beta
18
+ */
19
+ class SettingsSpecRegistry {
20
+ constructor() { } // singleton
21
+ /** Clear the contents of the registry and remove all event listeners.
22
+ * @note This is really only necessary for tests of the Settings system.
23
+ * @internal
24
+ */
25
+ static reset() {
26
+ this._allGroups.clear();
27
+ this.allSpecs.clear();
28
+ this.onSpecsChanged.clear();
29
+ }
30
+ /**
31
+ * Add one or more [[SettingsGroupSpec]]s to the registry. `SettingsGroupSpec`s must include a `groupName` member that is used
32
+ * to identify the group. If a group with the same name is already registered, the old values are first removed and then the new group is added.
33
+ * @returns an array of problems found adding properties of the supplied group(s).
34
+ */
35
+ static addGroup(settingsGroup) {
36
+ if (!Array.isArray(settingsGroup))
37
+ settingsGroup = [settingsGroup];
38
+ const problems = [];
39
+ this.doAdd(settingsGroup, problems);
40
+ this.onSpecsChanged.raiseEvent();
41
+ return problems;
42
+ }
43
+ /** Add a [[SettingsGroupSpec]] from stringified json5. */
44
+ static addJson(settingSpecJson) {
45
+ return this.addGroup((0, json5_1.parse)(settingSpecJson));
46
+ }
47
+ /** Add a [[SettingsGroupSpec]] from a json5 file. */
48
+ static addFile(fileName) {
49
+ return this.addJson(fs.readFileSync(fileName, "utf-8"));
50
+ }
51
+ /** Remove a previously added [[SettingsGroupSpec]] by groupName */
52
+ static removeGroup(groupName) {
53
+ this.doRemove(groupName);
54
+ this.onSpecsChanged.raiseEvent();
55
+ }
56
+ static doAdd(settingsGroup, problems) {
57
+ settingsGroup.forEach((group) => {
58
+ if (undefined === group.groupName)
59
+ throw new Error("settings group has no name");
60
+ this.doRemove(group.groupName);
61
+ this.validateAndAdd(group, problems);
62
+ this._allGroups.set(group.groupName, group);
63
+ });
64
+ }
65
+ static doRemove(groupName) {
66
+ const group = this._allGroups.get(groupName);
67
+ if (undefined !== (group === null || group === void 0 ? void 0 : group.properties)) {
68
+ for (const key of Object.keys(group.properties))
69
+ this.allSpecs.delete(key);
70
+ }
71
+ this._allGroups.delete(groupName);
72
+ }
73
+ static validateProperty(property) {
74
+ if (!property.trim())
75
+ return "empty property name";
76
+ if (this.allSpecs.has(property))
77
+ return `property "${property}" is already defined`;
78
+ return undefined;
79
+ }
80
+ static validateAndAdd(group, problems) {
81
+ var _a;
82
+ const properties = group.properties;
83
+ if (undefined === properties)
84
+ return;
85
+ for (const key of Object.keys(properties)) {
86
+ const problem = this.validateProperty(key);
87
+ if (problem) {
88
+ problems === null || problems === void 0 ? void 0 : problems.push(problem);
89
+ delete properties[key];
90
+ continue;
91
+ }
92
+ const property = properties[key];
93
+ property.default = (_a = property.default) !== null && _a !== void 0 ? _a : this.getDefaultValue(property.type);
94
+ this.allSpecs.set(key, property);
95
+ }
96
+ }
97
+ static getDefaultValue(type) {
98
+ type = Array.isArray(type) ? type[0] : type;
99
+ switch (type) {
100
+ case "boolean":
101
+ return false;
102
+ case "integer":
103
+ case "number":
104
+ return 0;
105
+ case "string":
106
+ return "";
107
+ case "array":
108
+ return [];
109
+ case "object":
110
+ return {};
111
+ default:
112
+ return undefined;
113
+ }
114
+ }
115
+ }
116
+ exports.SettingsSpecRegistry = SettingsSpecRegistry;
117
+ SettingsSpecRegistry._allGroups = new Map();
118
+ /** a map of all registered [[SettingSpec]]s */
119
+ SettingsSpecRegistry.allSpecs = new Map();
120
+ /** event that signals that the values in [[allSpecs]] have changed in some way. */
121
+ SettingsSpecRegistry.onSpecsChanged = new core_bentley_1.BeEvent();
122
+ //# sourceMappingURL=SettingsSpecRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsSpecRegistry.js","sourceRoot":"","sources":["../../../src/workspace/SettingsSpecRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Workspace\r\n */\r\n\r\nimport * as fs from \"fs-extra\";\r\nimport { parse } from \"json5\";\r\nimport { BeEvent, JSONSchema, JSONSchemaType, JSONSchemaTypeName, Mutable } from \"@itwin/core-bentley\";\r\n\r\n/**\r\n * The properties of a Setting, used by the settings editor. This interface also includes the\r\n * default value if it is not specified in any Settings file.\r\n * This interface includes all members of [JSONSchema]($bentley) with the extensions added by VSCode.\r\n * @beta\r\n */\r\nexport interface SettingSpec extends Readonly<JSONSchema> {\r\n type: JSONSchemaTypeName | JSONSchemaTypeName[];\r\n /** labels for items of an enum. */\r\n readonly enumItemLabels?: string[];\r\n /** whether the editor should show multiple lines. */\r\n readonly multilineEdit?: true;\r\n}\r\n\r\n/**\r\n * The properties of a group of [[SettingSpec]]s for an application. Groups can be added and removed from the registry\r\n * and are identified by their (required) `groupName` member\r\n * @beta\r\n */\r\nexport interface SettingsGroupSpec {\r\n readonly groupName: string;\r\n readonly properties: { [name: string]: SettingSpec };\r\n readonly order?: number;\r\n readonly title?: string;\r\n readonly description?: string;\r\n readonly extensionId?: string;\r\n}\r\n\r\n/**\r\n * The registry of available [[SettingsGroupSpec]]s.\r\n * The registry is used for editing Settings files and for finding default values for settings.\r\n * @beta\r\n */\r\nexport class SettingsSpecRegistry {\r\n private constructor() { } // singleton\r\n private static readonly _allGroups = new Map<string, SettingsGroupSpec>();\r\n /** a map of all registered [[SettingSpec]]s */\r\n public static readonly allSpecs = new Map<string, SettingSpec>();\r\n /** event that signals that the values in [[allSpecs]] have changed in some way. */\r\n public static readonly onSpecsChanged = new BeEvent<() => void>();\r\n\r\n /** Clear the contents of the registry and remove all event listeners.\r\n * @note This is really only necessary for tests of the Settings system.\r\n * @internal\r\n */\r\n public static reset() {\r\n this._allGroups.clear();\r\n this.allSpecs.clear();\r\n this.onSpecsChanged.clear();\r\n }\r\n\r\n /**\r\n * Add one or more [[SettingsGroupSpec]]s to the registry. `SettingsGroupSpec`s must include a `groupName` member that is used\r\n * to identify the group. If a group with the same name is already registered, the old values are first removed and then the new group is added.\r\n * @returns an array of problems found adding properties of the supplied group(s).\r\n */\r\n public static addGroup(settingsGroup: SettingsGroupSpec | SettingsGroupSpec[]): string[] {\r\n if (!Array.isArray(settingsGroup))\r\n settingsGroup = [settingsGroup];\r\n\r\n const problems: string[] = [];\r\n this.doAdd(settingsGroup, problems);\r\n this.onSpecsChanged.raiseEvent();\r\n return problems;\r\n }\r\n\r\n /** Add a [[SettingsGroupSpec]] from stringified json5. */\r\n public static addJson(settingSpecJson: string): string[] {\r\n return this.addGroup(parse(settingSpecJson));\r\n }\r\n\r\n /** Add a [[SettingsGroupSpec]] from a json5 file. */\r\n public static addFile(fileName: string): string[] {\r\n return this.addJson(fs.readFileSync(fileName, \"utf-8\"));\r\n }\r\n\r\n /** Remove a previously added [[SettingsGroupSpec]] by groupName */\r\n public static removeGroup(groupName: string): void {\r\n this.doRemove(groupName);\r\n this.onSpecsChanged.raiseEvent();\r\n }\r\n\r\n private static doAdd(settingsGroup: SettingsGroupSpec[], problems?: string[]) {\r\n settingsGroup.forEach((group) => {\r\n if (undefined === group.groupName)\r\n throw new Error(\"settings group has no name\");\r\n\r\n this.doRemove(group.groupName);\r\n this.validateAndAdd(group, problems);\r\n this._allGroups.set(group.groupName, group);\r\n });\r\n }\r\n\r\n private static doRemove(groupName: string) {\r\n const group = this._allGroups.get(groupName);\r\n if (undefined !== group?.properties) {\r\n for (const key of Object.keys(group.properties))\r\n this.allSpecs.delete(key);\r\n }\r\n this._allGroups.delete(groupName);\r\n }\r\n\r\n private static validateProperty(property: string): string | undefined {\r\n if (!property.trim())\r\n return \"empty property name\";\r\n if (this.allSpecs.has(property))\r\n return `property \"${property}\" is already defined`;\r\n\r\n return undefined;\r\n }\r\n\r\n private static validateAndAdd(group: SettingsGroupSpec, problems?: string[]) {\r\n const properties = group.properties;\r\n if (undefined === properties)\r\n return;\r\n\r\n for (const key of Object.keys(properties)) {\r\n const problem = this.validateProperty(key);\r\n if (problem) {\r\n problems?.push(problem);\r\n delete properties[key];\r\n continue;\r\n }\r\n\r\n const property: Mutable<SettingSpec> = properties[key];\r\n property.default = property.default ?? this.getDefaultValue(property.type);\r\n this.allSpecs.set(key, property);\r\n }\r\n }\r\n\r\n private static getDefaultValue(type: JSONSchemaTypeName | JSONSchemaTypeName[]): JSONSchemaType | undefined {\r\n type = Array.isArray(type) ? type[0] : type;\r\n switch (type) {\r\n case \"boolean\":\r\n return false;\r\n case \"integer\":\r\n case \"number\":\r\n return 0;\r\n case \"string\":\r\n return \"\";\r\n case \"array\":\r\n return [];\r\n case \"object\":\r\n return {};\r\n default:\r\n return undefined;\r\n }\r\n }\r\n}\r\n"]}