@itwin/core-backend
Version:
iTwin.js backend components
216 lines • 14.1 kB
TypeScript
/** @packageDocumentation
* @module Workspace
*/
import { BeEvent, JSONSchemaType } from "@itwin/core-bentley";
import { LocalDirName, LocalFileName } from "@itwin/core-common";
import { WorkspaceDb } from "./Workspace";
import { _implementationProhibited } from "../internal/Symbols";
/** The value of a single named parameter within a [[Workspace.settings]] that configures some aspect of the applications run-time behavior.
* Settings are stored in a [[SettingsDictionary]]. A setting is described by its [[SettingSchema]].
* @beta
*/
export type Setting = JSONSchemaType;
/** @beta */
export declare namespace Setting {
/** Create a deep copy of a [[Setting]]. */
function clone<T extends Setting>(setting: T): T;
/** Returns true if `a` and `b` are considered equivalent [[Setting]] values.
* Settings of primitive types like `number` and `string` are compared using `===`.
* Settings of type "object" are compared by comparing each property using `areEqual`; the objects are considered
* equal if they have the exact same set of property names with equivalent values.
* Settings of type "array" are compared by comparing each element of the arrays use `areEqual`; the arrays are considered
* equal if they have the same number of elements with equivalent values in the same exact order.
*/
function areEqual(a: Setting | undefined, b: Setting | undefined): boolean;
}
/**
* The name of a [[Setting]].
* Setting names must be [valid JavaScript property names](https://developer.mozilla.org/en-US/docs/Glossary/property/JavaScript) containing no spaces or periods.
* The name of a setting begins with the schema prefix of the [[SettingGroupSchema]] in which its [[SettingSchema]] is defined.
* A setting name therefore forms a path like file names in a file system.
* For example, the following are setting names defined in the `energyAnalysis`, `iot-scan-visualization`, and `vibration-map` schemas.
*
* ```ts
* "energyAnalysis/formats/totalWork"
* "energyAnalysis/formats/totalHours"
* "energyAnalysis/units/power"
* "energyAnalysis/units/temperature"
* "energyAnalysis/startupMode"
* "iot-scan-visualization/ports/cameras"
* "vibration-map/filters/scope"
* "vibration-map/filters/prefabricated"
* ```
*
* @beta
*/
export type SettingName = string;
/** An object that defines the values for any number of [[Setting]]s. Each of its properties' names must conform to the semantics of a [[SettingName]].
* @beta
*/
export interface SettingsContainer {
/** Accesses settings by their names. */
[name: SettingName]: Setting | undefined;
}
/** Defines the precedence of a [[SettingsDictionary]].
* [[Settings]] may contain multiple dictionaries containing different values for the same [[SettingName]].
* When resolving the value of a [[Setting]], the value from the highest-priority dictionary is used.
* Priorities are grouped into coarse categories like [[SettingsPriority.application]] and [[SettingsPriority.iModel]].
* Settings with priorities less than or equal to [[SettingsPriority.application]] are stored in [[IModelHost.appWorkspace]], while
* those with priorities higher than [[SettingsPriority.application]] are stored inside [[IModelDb.workspace]].
* @beta
*/
export type SettingsPriority = number;
/** @beta */
export declare namespace SettingsPriority {
/** Settings that originate from default setting files loaded automatically at the start of a session. */
const defaults = 100;
/** Settings supplied by an application at runtime. */
const application = 200;
/** Settings that apply to all iTwins for an organization. */
const organization = 300;
/** Settings that apply to all iModels in an iTwin. */
const iTwin = 400;
/** Settings that apply to all branches of an iModel. */
const branch = 500;
/** Settings that apply to a specific iModel. */
const iModel = 600;
}
/** A named container that supplies values for [[Setting]]s.
* @see [[Settings.addDictionary]] to register a new settings dictionary.
* @beta
*/
export interface SettingsDictionary {
/** @internal */
[_implementationProhibited]: unknown;
/** Metadata describing the dictionary. */
readonly props: SettingsDictionaryProps;
/** Obtain a copy of the value of the setting named `settingName` stored in this dictionary, or `undefined` if no such setting exists.
* The returned value is always cloned using [[Setting.clone]].
* @note Generally, applications use methods like [[Settings.getString]] and [[Setting.getArray]] to resolve a setting value from multiple
* dictionaries. Those methods - unlike this one - also validate that `settingName` is of type `T` as defined by its [[SettingSchema]].
*/
getSetting<T extends Setting>(settingName: SettingName): T | undefined;
}
/** Uniquely identifies a [[SettingsDictionary]].
* @beta
*/
export interface SettingsDictionarySource {
/** The name of the dictionary, which must be unique within its [[workspaceDb]], or - if [[workspaceDb]] is undefined - unique among all dictionaries not associated with any [[WorkspaceDb]]. */
readonly name: string;
/** The [[WorkspaceDb]] from which the dictionary originated. */
readonly workspaceDb?: WorkspaceDb;
}
/** Properties of a [[SettingsDictionary]], defining its name, the [[WorkspaceDb]] (if any) from which it originated, and its [[priority]] relative to other dictionaries.
* @beta
*/
export interface SettingsDictionaryProps extends SettingsDictionarySource {
/** Precedence value determining which setting value to use when multiple dictionaries supply values for the same [[SettingName]]. */
readonly priority: SettingsPriority;
}
/**
* The collection of [[Setting]]s that supply the run-time configuration of a [[Workspace]].
* The `Settings` object comprises a collection of named [[SettingsDictionary]] objects.
* Methods like [[getSetting]], [[getString]], and [[getArray]] provide access to the value of an individual [[Setting]] by searching
* the [[dictionaries]] in order by their [[SettingsPriority]] to find the highest-priority setting with the requested [[SettingName]].
* Most methods that retrieve [[Setting]] values validate them against their [[SettingSchema]]s to ensure that they are of the correct type.
* A [[SettingsDictionary]] can be added or removed using [[addDictionary]] and [[dropDictionary]].
* Because [[Setting]]s can change at any time during the session, you should avoid caching their values wherever possible.
* If you must cache them (for example, to display in a user interface), you should listen for the [[onSettingsChanged]] event to be
* notified of potential changes.
*
* Settings are accessed via [[Workspace.settings]]. They are defined at the application level by [[IModelHost.appWorkspace]], but individual iModels may supply
* additional iModel-specific settings or overrides for application-level settings. When working in the context of a specific iModel, use [[IModelDb.workspace]]'s `settings`
* property. Any settings not overridden by the iModel will fall back to the settings defined in [[IModelHost.appWorkspace]].
*
* Application settings are loaded into [[IModelHost.appWorkspace]] when the session begins (i.e., when [[IModelHost.startup]] is invoked), and unloaded when it ends (in [[IModelHost.shutdown]]).
* They are read from [JSON5](https://json5.org/) files delivered with the application. The application should register any additional [[SettingsDictionary]]'s '(and their corresponding
* [[SettingGroupSchema]]s) at this time.
*
* iModel-specific settings are stored in the iModel's property table and loaded into [[IModelDb.workspace]] when the iModel is first opened.
* You can add and remove a [[SettingsDictionary]] from the property table using [[IModelDb.saveSettingDictionary]] and [[IModelDb.deleteSettingDictionary]].
*
* See the [learning article]($docs/learning/backend/Workspace) for a detailed overiew and examples.
*
* @see [[IModelHost.appWorkspace]] application-wide settings, and [[IModelDb.workspace]] for settings specific to a given iModel.
* @beta
*/
export interface Settings {
/** @internal */
[_implementationProhibited]: unknown;
/** @internal */
close(): void;
/** The set of settings dictionaries from which [[Setting]] values are obtained, sorted by [[SettingsPriority]].
* The set can contain at most one dictionary for each unique combination of name and [[WorkspaceDb]].
* @see [[addDictionary]], [[addFile]], [[addJson]], and [[addDirectory]] to add a new dictionary.
* @see [[dropDictionary]] to remove a dictionary.
* @see [[getDictionary]] to look up a dictionary.
*/
readonly dictionaries: readonly SettingsDictionary[];
/** Event raised whenever a [[SettingsDictionary]] is added or removed. */
readonly onSettingsChanged: BeEvent<() => void>;
/** Parses the contents of a local [JSON5](https://json5.org/) file as a [[SettingsContainer]] and invokes [[addDictionary]] to
* add a [[SettingsDictionary]] named `fileName` with the specified priority.
* @param fileName the name of a local settings file containing the dictionary.
* @param priority the priority for the dictionary.
*/
addFile(fileName: LocalFileName, priority: SettingsPriority): void;
/** Invokes [[addFile]] for all files in `directory` with the extension ".json" or ".json5". */
addDirectory(directory: LocalDirName, priority: SettingsPriority): void;
/** Parses `settingsJson` as a [[SettingsContainer]] and invokes [[addDictionary]] to add a [[SettingsDictionary]] with the specified `props`.
* This is typically used when reading dictionaries out of a [[WorkspaceDb]], where they are stored as stringified JSON.
*/
addJson(props: SettingsDictionaryProps, settingsJson: string): void;
/** Find a [[SettingsDictionary]] with the same name and [[WorkspaceDb]] as `source`. */
getDictionary(source: SettingsDictionarySource): SettingsDictionary | undefined;
/** Add a new [[SettingsDictionary]] with the priority, name, and [[WorkspaceDb]] specified by `props` and setting values supplied by `settings`.
* @note If a dictionary with the same name and [[WorkspaceDb]] already exists, it will be replaced.
* @see [[addFile]], [[addJson]], and [[addDirectory]] for convenient ways to add dictionaries from various sources.
*/
addDictionary(props: SettingsDictionaryProps, settings: SettingsContainer): void;
/** Removes a previously-added [[SettingsDictionary]]. */
dropDictionary(props: SettingsDictionarySource): void;
/** Looks up the highest priority setting value for a SettingName, falling back to a default value if no value for the setting is found.
* The [[dictionaries]] are searched in order by [[SettingsPriority]]; the first one that provides a value for `settingName` wins.
* @param settingName The name of the setting.
* @param defaultValue value returned if settingName is not present in any [[SettingsDictionary]].
* @note This method is generic on [[Setting]] type, but no type checking is actually performed at run time. So, if you
* 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.
* You must always type check the result. Use the non-generic "get" methods like [[getString]] and [[getArray]] if you only want the value
* if its type is correct.
* @note Unlike [[getArray]], this method does not combine arrays - it ignores [[SettingsSchema.combineArrays]].
*/
getSetting<T extends Setting>(settingName: SettingName, defaultValue?: T): T | undefined;
/** Obtain an iterator over all of the values in the [[dictionaries]] for the [[Setting]] identified by `settingName`, ordered by [[SettingsPriority]]. */
getSettingEntries<T extends Setting>(settingName: SettingName): Iterable<{
value: T;
dictionary: SettingsDictionary;
}>;
/** Obtain an iterator over all of the values in the [[dictionaries]] for the [[Setting]] identified by `settingName`, ordered by [[SettingsPriority]]. */
getSettingValues<T extends Setting>(settingName: SettingName): Iterable<T>;
/** Look up the value of a string [[Setting]] named `settingName`, returning `defaultValue` if no such value is defined.
* @throws Error if the setting exists but is not a string.
*/
getString(settingName: SettingName, defaultValue: string): string;
getString(settingName: SettingName, defaultValue?: string): string | undefined;
/** Look up the value of a boolean [[Setting]] named `settingName`, returning `defaultValue` if no such value is defined.
* @throws Error if the setting exists but is not a boolean.
*/
getBoolean(settingName: SettingName, defaultValue: boolean): boolean;
getBoolean(settingName: SettingName, defaultValue?: boolean): boolean | undefined;
/** Look up the value of a numeric [[Setting]] named `settingName`, returning `defaultValue` if no such value is defined.
* @throws Error if the setting exists but is not a number.
*/
getNumber(settingName: SettingName, defaultValue: number): number;
getNumber(settingName: SettingName): number | undefined;
/** Look up the value of an object [[Setting]] named `settingName`, returning `defaultValue` if no such value is defined.
* @throws Error if the setting exists but is not an object.
*/
getObject<T extends object>(settingName: SettingName, defaultValue: T): T;
getObject<T extends object>(settingName: SettingName): T | undefined;
/** Look up the value of an array [[Setting]] named `settingName`, returning `defaultValue` if no such value is defined.
* @throws Error if the setting exists but is not an array.
*/
getArray<T extends Setting>(settingName: SettingName, defaultValue: Array<T>): Array<T>;
getArray<T extends Setting>(settingName: SettingName): Array<T> | undefined;
}
//# sourceMappingURL=Settings.d.ts.map