@itwin/ecschema-metadata 5.14.0-dev.8 → 5.14.0
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.
- package/CHANGELOG.md +44 -1
- package/lib/cjs/ECName.d.ts +4 -0
- package/lib/cjs/ECName.d.ts.map +1 -1
- package/lib/cjs/ECName.js +9 -1
- package/lib/cjs/ECName.js.map +1 -1
- package/lib/cjs/Formatting/FormatSetFormatsProvider.d.ts +13 -5
- package/lib/cjs/Formatting/FormatSetFormatsProvider.d.ts.map +1 -1
- package/lib/cjs/Formatting/FormatSetFormatsProvider.js +65 -22
- package/lib/cjs/Formatting/FormatSetFormatsProvider.js.map +1 -1
- package/lib/cjs/Formatting/SchemaFormatsProvider.d.ts +15 -6
- package/lib/cjs/Formatting/SchemaFormatsProvider.d.ts.map +1 -1
- package/lib/cjs/Formatting/SchemaFormatsProvider.js +163 -44
- package/lib/cjs/Formatting/SchemaFormatsProvider.js.map +1 -1
- package/lib/cjs/SchemaView/SchemaManifest.d.ts +11 -14
- package/lib/cjs/SchemaView/SchemaManifest.d.ts.map +1 -1
- package/lib/cjs/SchemaView/SchemaManifest.js +8 -11
- package/lib/cjs/SchemaView/SchemaManifest.js.map +1 -1
- package/lib/cjs/SchemaView/SchemaView.d.ts +14 -5
- package/lib/cjs/SchemaView/SchemaView.d.ts.map +1 -1
- package/lib/cjs/SchemaView/SchemaView.js +22 -12
- package/lib/cjs/SchemaView/SchemaView.js.map +1 -1
- package/lib/cjs/SchemaView/SchemaViewManager.d.ts +22 -17
- package/lib/cjs/SchemaView/SchemaViewManager.d.ts.map +1 -1
- package/lib/cjs/SchemaView/SchemaViewManager.js +11 -11
- package/lib/cjs/SchemaView/SchemaViewManager.js.map +1 -1
- package/lib/esm/ECName.d.ts +4 -0
- package/lib/esm/ECName.d.ts.map +1 -1
- package/lib/esm/ECName.js +9 -1
- package/lib/esm/ECName.js.map +1 -1
- package/lib/esm/Formatting/FormatSetFormatsProvider.d.ts +13 -5
- package/lib/esm/Formatting/FormatSetFormatsProvider.d.ts.map +1 -1
- package/lib/esm/Formatting/FormatSetFormatsProvider.js +65 -22
- package/lib/esm/Formatting/FormatSetFormatsProvider.js.map +1 -1
- package/lib/esm/Formatting/SchemaFormatsProvider.d.ts +15 -6
- package/lib/esm/Formatting/SchemaFormatsProvider.d.ts.map +1 -1
- package/lib/esm/Formatting/SchemaFormatsProvider.js +163 -44
- package/lib/esm/Formatting/SchemaFormatsProvider.js.map +1 -1
- package/lib/esm/SchemaView/SchemaManifest.d.ts +11 -14
- package/lib/esm/SchemaView/SchemaManifest.d.ts.map +1 -1
- package/lib/esm/SchemaView/SchemaManifest.js +8 -11
- package/lib/esm/SchemaView/SchemaManifest.js.map +1 -1
- package/lib/esm/SchemaView/SchemaView.d.ts +14 -5
- package/lib/esm/SchemaView/SchemaView.d.ts.map +1 -1
- package/lib/esm/SchemaView/SchemaView.js +22 -12
- package/lib/esm/SchemaView/SchemaView.js.map +1 -1
- package/lib/esm/SchemaView/SchemaViewManager.d.ts +22 -17
- package/lib/esm/SchemaView/SchemaViewManager.d.ts.map +1 -1
- package/lib/esm/SchemaView/SchemaViewManager.js +11 -11
- package/lib/esm/SchemaView/SchemaViewManager.js.map +1 -1
- package/package.json +6 -6
|
@@ -10,11 +10,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.SchemaFormatsProvider = void 0;
|
|
11
11
|
const Context_1 = require("../Context");
|
|
12
12
|
const SchemaKey_1 = require("../SchemaKey");
|
|
13
|
+
const ECObjects_1 = require("../ECObjects");
|
|
14
|
+
const Exception_1 = require("../Exception");
|
|
13
15
|
const SchemaItem_1 = require("../Metadata/SchemaItem");
|
|
14
16
|
const Format_1 = require("../Metadata/Format");
|
|
17
|
+
const OverrideFormat_1 = require("../Metadata/OverrideFormat");
|
|
15
18
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
16
19
|
const KindOfQuantity_1 = require("../Metadata/KindOfQuantity");
|
|
17
|
-
const
|
|
20
|
+
const Unit_1 = require("../Metadata/Unit");
|
|
21
|
+
const InvertedUnit_1 = require("../Metadata/InvertedUnit");
|
|
22
|
+
const UnitSystem_1 = require("../Metadata/UnitSystem");
|
|
18
23
|
const loggerCategory = "SchemaFormatsProvider";
|
|
19
24
|
/**
|
|
20
25
|
* Provides default formats and kind of quantities from a given SchemaContext or SchemaLocater.
|
|
@@ -77,55 +82,42 @@ class SchemaFormatsProvider {
|
|
|
77
82
|
core_bentley_1.Logger.logError(loggerCategory, `Failed to find KindOfQuantity ${itemKey.fullName}`);
|
|
78
83
|
return undefined;
|
|
79
84
|
}
|
|
80
|
-
if (!kindOfQuantity)
|
|
85
|
+
if (!kindOfQuantity)
|
|
81
86
|
return undefined;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const props = (0, OverrideFormat_1.getFormatProps)(format);
|
|
99
|
-
return this.convertToFormatDefinition(props, kindOfQuantity);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
// If no matching presentation format was found, fall back to persistence unit format
|
|
104
|
-
// only if it matches the requested unit system.
|
|
105
|
-
const persistenceUnit = await kindOfQuantity.persistenceUnit;
|
|
106
|
-
const persistenceUnitSystem = await persistenceUnit?.unitSystem;
|
|
107
|
-
if (persistenceUnit && persistenceUnitSystem && unitSystemMatchers.some((matcher) => matcher(persistenceUnitSystem))) {
|
|
108
|
-
this._formatsRetrieved.add(itemKey.fullName);
|
|
109
|
-
const props = getPersistenceUnitFormatProps(persistenceUnit);
|
|
110
|
-
return this.convertToFormatDefinition(props, kindOfQuantity);
|
|
87
|
+
const props = await this.getKindOfQuantityFormatProps(kindOfQuantity, systemOverride);
|
|
88
|
+
if (!props)
|
|
89
|
+
return undefined;
|
|
90
|
+
this._formatsRetrieved.add(itemKey.fullName);
|
|
91
|
+
return this.convertToFormatDefinition(props, kindOfQuantity);
|
|
92
|
+
}
|
|
93
|
+
async getKindOfQuantityFormatProps(kindOfQuantity, systemOverride) {
|
|
94
|
+
// Cache each unit once per lookup because matchers may revisit it. Lazy formats already resolve only once.
|
|
95
|
+
const unitCache = new Map();
|
|
96
|
+
const getUnit = (unit) => {
|
|
97
|
+
if (!unit)
|
|
98
|
+
return undefined;
|
|
99
|
+
let resolved = unitCache.get(unit);
|
|
100
|
+
if (!resolved) {
|
|
101
|
+
resolved = resolveUnitAsync(unit);
|
|
102
|
+
unitCache.set(unit, resolved);
|
|
111
103
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
104
|
+
return resolved;
|
|
105
|
+
};
|
|
106
|
+
for (const candidate of getFormatSelectionCandidates(kindOfQuantity, systemOverride ?? this._unitSystem)) {
|
|
107
|
+
const format = candidate.type === "persistence" ? undefined : await candidate.format;
|
|
108
|
+
const unit = candidate.type === "default" ? undefined : await getUnit(candidate.type === "persistence" ? candidate.unit : format?.units?.[0]?.[0]);
|
|
109
|
+
const props = getFormatPropsForCandidate(candidate, format, unit);
|
|
110
|
+
if (props)
|
|
111
|
+
return props;
|
|
120
112
|
}
|
|
121
113
|
return undefined;
|
|
122
114
|
}
|
|
123
115
|
/**
|
|
124
|
-
* Retrieves a
|
|
125
|
-
*
|
|
126
|
-
*
|
|
116
|
+
* Retrieves a format definition from the schema context.
|
|
117
|
+
*
|
|
118
|
+
* For a KindOfQuantity with a unit system, matching presentation formats are checked first, followed by the persistence unit and then the default presentation format. Without a unit system, the default presentation format is used.
|
|
127
119
|
* @param name The full name of the Format or KindOfQuantity.
|
|
128
|
-
* @
|
|
120
|
+
* @param system Optional unit system used to select a KindOfQuantity format.
|
|
129
121
|
*/
|
|
130
122
|
async getFormat(name, system) {
|
|
131
123
|
const [schemaName, schemaItemName] = SchemaItem_1.SchemaItem.parseFullName(name);
|
|
@@ -158,12 +150,139 @@ class SchemaFormatsProvider {
|
|
|
158
150
|
}
|
|
159
151
|
return this.getKindOfQuantityFormatFromSchema(itemKey, system);
|
|
160
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Retrieves a format definition using only schema metadata already loaded in the context.
|
|
155
|
+
* It follows the same selection order as `getFormat` but never asks a locater to load a schema. Returns `undefined` when required metadata is not cached.
|
|
156
|
+
* Unlike `getFormat`, which logs lookup errors and returns `undefined`, this method treats only a schema that is still loading as a cache miss and rethrows other errors.
|
|
157
|
+
*/
|
|
158
|
+
getFormatSync(name, system) {
|
|
159
|
+
const [schemaName, schemaItemName] = SchemaItem_1.SchemaItem.parseFullName(name);
|
|
160
|
+
const schemaKey = new SchemaKey_1.SchemaKey(schemaName);
|
|
161
|
+
const schema = getCachedSchemaSync(this._context, schemaKey, ECObjects_1.SchemaMatchType.Latest);
|
|
162
|
+
if (!schema)
|
|
163
|
+
return undefined;
|
|
164
|
+
const itemKey = new SchemaKey_1.SchemaItemKey(schemaItemName, schema.schemaKey);
|
|
165
|
+
if (schema.name === "Formats") {
|
|
166
|
+
const format = schema.getItemSync(itemKey.name, Format_1.Format);
|
|
167
|
+
return format?.toJSON(true);
|
|
168
|
+
}
|
|
169
|
+
return this.getKindOfQuantityFormatFromSchemaSync(itemKey, system);
|
|
170
|
+
}
|
|
171
|
+
getKindOfQuantityFormatFromSchemaSync(itemKey, systemOverride) {
|
|
172
|
+
const schema = getCachedSchemaSync(this._context, itemKey.schemaKey, ECObjects_1.SchemaMatchType.Latest);
|
|
173
|
+
const kindOfQuantity = schema?.getItemSync(itemKey.name, KindOfQuantity_1.KindOfQuantity);
|
|
174
|
+
if (!kindOfQuantity)
|
|
175
|
+
return undefined;
|
|
176
|
+
const props = this.getKindOfQuantityFormatPropsSync(kindOfQuantity, systemOverride);
|
|
177
|
+
if (!props)
|
|
178
|
+
return undefined;
|
|
179
|
+
this._formatsRetrieved.add(itemKey.fullName);
|
|
180
|
+
return this.convertToFormatDefinition(props, kindOfQuantity);
|
|
181
|
+
}
|
|
182
|
+
getKindOfQuantityFormatPropsSync(kindOfQuantity, systemOverride) {
|
|
183
|
+
const formatCache = new Map();
|
|
184
|
+
const unitCache = new Map();
|
|
185
|
+
const getFormat = (format) => {
|
|
186
|
+
if (!formatCache.has(format))
|
|
187
|
+
formatCache.set(format, resolveFormatSync(this._context, format));
|
|
188
|
+
return formatCache.get(format);
|
|
189
|
+
};
|
|
190
|
+
const getUnit = (unit) => {
|
|
191
|
+
if (!unit)
|
|
192
|
+
return undefined;
|
|
193
|
+
if (!unitCache.has(unit))
|
|
194
|
+
unitCache.set(unit, resolveUnitSync(this._context, unit));
|
|
195
|
+
return unitCache.get(unit);
|
|
196
|
+
};
|
|
197
|
+
// A reference that cannot be resolved means metadata is not cached. Stop there: async lookup would resolve it and never reach a later candidate.
|
|
198
|
+
for (const candidate of getFormatSelectionCandidates(kindOfQuantity, systemOverride ?? this._unitSystem)) {
|
|
199
|
+
const format = candidate.type === "persistence" ? undefined : getFormat(candidate.format);
|
|
200
|
+
if (candidate.type !== "persistence" && !format)
|
|
201
|
+
return undefined;
|
|
202
|
+
const unitReference = candidate.type === "presentation" ? format?.units?.[0]?.[0] : candidate.type === "persistence" ? candidate.unit : undefined;
|
|
203
|
+
const unit = getUnit(unitReference);
|
|
204
|
+
if (unitReference && !unit)
|
|
205
|
+
return undefined;
|
|
206
|
+
const props = getFormatPropsForCandidate(candidate, format, unit);
|
|
207
|
+
if (props)
|
|
208
|
+
return props;
|
|
209
|
+
}
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
161
212
|
}
|
|
162
213
|
exports.SchemaFormatsProvider = SchemaFormatsProvider;
|
|
214
|
+
/**
|
|
215
|
+
* Produces candidates in lookup order: presentation formats by unit-system priority, then the persistence unit,
|
|
216
|
+
* then the default presentation format. The generator defers each candidate until the lookup reaches it.
|
|
217
|
+
*/
|
|
218
|
+
function* getFormatSelectionCandidates(kindOfQuantity, effectiveSystem) {
|
|
219
|
+
if (effectiveSystem) {
|
|
220
|
+
const matchers = getUnitSystemGroupMatchers(effectiveSystem);
|
|
221
|
+
for (const matcher of matchers) {
|
|
222
|
+
for (const format of kindOfQuantity.presentationFormats)
|
|
223
|
+
yield { type: "presentation", format, matcher };
|
|
224
|
+
}
|
|
225
|
+
yield { type: "persistence", unit: kindOfQuantity.persistenceUnit, matchers };
|
|
226
|
+
}
|
|
227
|
+
const defaultFormat = kindOfQuantity.defaultPresentationFormat;
|
|
228
|
+
if (defaultFormat)
|
|
229
|
+
yield { type: "default", format: defaultFormat };
|
|
230
|
+
}
|
|
231
|
+
function getFormatPropsForCandidate(candidate, format, unit) {
|
|
232
|
+
const unitSystemName = unit?.unitSystemName;
|
|
233
|
+
switch (candidate.type) {
|
|
234
|
+
case "presentation":
|
|
235
|
+
return format && unitSystemName && candidate.matcher(unitSystemName) ? (0, OverrideFormat_1.getFormatProps)(format) : undefined;
|
|
236
|
+
case "persistence":
|
|
237
|
+
return unit && unitSystemName && candidate.matchers.some((matcher) => matcher(unitSystemName)) ? getPersistenceUnitFormatProps(unit.unit) : undefined;
|
|
238
|
+
case "default":
|
|
239
|
+
return format ? (0, OverrideFormat_1.getFormatProps)(format) : undefined;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function resolveFormatSync(context, format) {
|
|
243
|
+
if (OverrideFormat_1.OverrideFormat.isOverrideFormat(format))
|
|
244
|
+
return format;
|
|
245
|
+
const schema = getCachedSchemaSync(context, format.schemaKey, ECObjects_1.SchemaMatchType.Exact);
|
|
246
|
+
return schema?.getItemSync(format.name, Format_1.Format);
|
|
247
|
+
}
|
|
248
|
+
async function resolveUnitAsync(unit) {
|
|
249
|
+
const resolvedUnit = await unit;
|
|
250
|
+
const unitSystem = await resolvedUnit.unitSystem;
|
|
251
|
+
return { unit: resolvedUnit, unitSystemName: unitSystem?.name };
|
|
252
|
+
}
|
|
253
|
+
function resolveUnitSync(context, unit) {
|
|
254
|
+
const resolvedUnit = getLoadedUnitSync(context, unit);
|
|
255
|
+
if (!resolvedUnit)
|
|
256
|
+
return undefined;
|
|
257
|
+
const unitSystem = resolvedUnit.unitSystem;
|
|
258
|
+
if (!unitSystem)
|
|
259
|
+
return { unit: resolvedUnit };
|
|
260
|
+
const unitSystemName = getCachedSchemaSync(context, unitSystem.schemaKey, ECObjects_1.SchemaMatchType.Exact)?.getItemSync(unitSystem.name, UnitSystem_1.UnitSystem)?.name;
|
|
261
|
+
return unitSystemName ? { unit: resolvedUnit, unitSystemName } : undefined;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Name-only lookups use `SchemaMatchType.Latest`. References use `SchemaMatchType.Exact` because they carry the version
|
|
265
|
+
* the loaded item resolved; matching by name alone could return an item from a different cached version.
|
|
266
|
+
*/
|
|
267
|
+
function getCachedSchemaSync(context, schemaKey, matchType) {
|
|
268
|
+
try {
|
|
269
|
+
return context.getCachedSchemaSync(schemaKey, matchType);
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
if (error instanceof Exception_1.ECSchemaError && error.errorNumber === Exception_1.ECSchemaStatus.UnableToLoadSchema)
|
|
273
|
+
return undefined;
|
|
274
|
+
throw error;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function getLoadedUnitSync(context, unit) {
|
|
278
|
+
const schema = getCachedSchemaSync(context, unit.schemaKey, ECObjects_1.SchemaMatchType.Exact);
|
|
279
|
+
const item = schema?.getItemSync(unit.name);
|
|
280
|
+
return Unit_1.Unit.isUnit(item) || InvertedUnit_1.InvertedUnit.isInvertedUnit(item) ? item : undefined;
|
|
281
|
+
}
|
|
163
282
|
function getUnitSystemGroupMatchers(groupKey) {
|
|
164
283
|
function createMatcher(name) {
|
|
165
284
|
const names = Array.isArray(name) ? name : [name];
|
|
166
|
-
return (
|
|
285
|
+
return (unitSystemName) => names.some((n) => n === unitSystemName.toUpperCase());
|
|
167
286
|
}
|
|
168
287
|
switch (groupKey) {
|
|
169
288
|
case "imperial":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaFormatsProvider.js","sourceRoot":"","sources":["../../../src/Formatting/SchemaFormatsProvider.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 Metadata\r\n */\r\n\r\nimport { ISchemaLocater, SchemaContext } from \"../Context\";\r\nimport { SchemaItemKey, SchemaKey } from \"../SchemaKey\";\r\nimport { SchemaItem } from \"../Metadata/SchemaItem\";\r\nimport { Format } from \"../Metadata/Format\";\r\nimport { SchemaItemFormatProps } from \"../Deserialization/JsonProps\";\r\nimport { BeEvent, Logger } from \"@itwin/core-bentley\";\r\nimport { KindOfQuantity } from \"../Metadata/KindOfQuantity\";\r\nimport { getFormatProps } from \"../Metadata/OverrideFormat\";\r\nimport { FormatDefinition, FormatProps, FormatsChangedArgs, FormatsProvider, UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport { Unit } from \"../Metadata/Unit\";\r\nimport { InvertedUnit } from \"../Metadata/InvertedUnit\";\r\nimport { Schema } from \"../Metadata/Schema\";\r\nimport { UnitSystem } from \"../Metadata/UnitSystem\";\r\nconst loggerCategory = \"SchemaFormatsProvider\";\r\n/**\r\n * Provides default formats and kind of quantities from a given SchemaContext or SchemaLocater.\r\n * @beta\r\n */\r\nexport class SchemaFormatsProvider implements FormatsProvider {\r\n private _context: SchemaContext;\r\n private _unitSystem?: UnitSystemKey;\r\n private _formatsRetrieved: Set<string> = new Set();\r\n public onFormatsChanged = new BeEvent<(args: FormatsChangedArgs) => void>();\r\n /**\r\n *\r\n * @param contextOrLocater The SchemaContext or a different ISchemaLocater implementation used to retrieve the schema. The SchemaContext\r\n * class implements the ISchemaLocater interface. If the provided locater is not a SchemaContext instance a new SchemaContext will be\r\n * created and the locater will be added.\r\n * @param unitSystem Optional unit system used to lookup a default format through a schema specific algorithm, when the format retrieved is associated with a KindOfQuantity.\r\n * If not provided, the default presentation format will be used directly without matching unit systems.\r\n */\r\n constructor(contextOrLocater: ISchemaLocater, unitSystem?: UnitSystemKey) {\r\n if (contextOrLocater instanceof SchemaContext) {\r\n this._context = contextOrLocater;\r\n } else {\r\n this._context = new SchemaContext();\r\n this._context.addLocater(contextOrLocater);\r\n }\r\n this._unitSystem = unitSystem;\r\n }\r\n\r\n public get context() { return this._context; }\r\n public get unitSystem() { return this._unitSystem; }\r\n\r\n public set unitSystem(unitSystem: UnitSystemKey | undefined) {\r\n this._unitSystem = unitSystem;\r\n this.clear();\r\n }\r\n\r\n private clear(): void {\r\n const formatsChanged = Array.from(this._formatsRetrieved);\r\n this._formatsRetrieved.clear();\r\n this.onFormatsChanged.raiseEvent({ formatsChanged });\r\n }\r\n\r\n /** When using a presentation unit from a KindOfQuantity, the label and description should come from the KindOfQuantity */\r\n private convertToFormatDefinition(format: SchemaItemFormatProps, kindOfQuantity: KindOfQuantity): FormatDefinition {\r\n // Destructure all properties except 'rest'\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n const { name, label, description, $schema, schema, schemaVersion, schemaItemType,\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n customAttributes, originalECSpecMajorVersion, originalECSpecMinorVersion, ...rest } = format;\r\n\r\n return {\r\n ...rest,\r\n name: kindOfQuantity.fullName,\r\n label: kindOfQuantity.label ?? format.label,\r\n description: kindOfQuantity.description ?? format.description,\r\n }\r\n }\r\n\r\n private async getKindOfQuantityFormatFromSchema(itemKey: SchemaItemKey, systemOverride?: UnitSystemKey): Promise<FormatDefinition | undefined> {\r\n let kindOfQuantity: KindOfQuantity | undefined;\r\n try {\r\n kindOfQuantity = await this._context.getSchemaItem(itemKey, KindOfQuantity);\r\n } catch {\r\n Logger.logError(loggerCategory, `Failed to find KindOfQuantity ${itemKey.fullName}`);\r\n return undefined;\r\n }\r\n\r\n if (!kindOfQuantity) {\r\n return undefined;\r\n }\r\n\r\n // If a unit system is provided, find the first presentation format that matches it.\r\n const effectiveSystem = systemOverride ?? this._unitSystem;\r\n if (effectiveSystem) {\r\n const unitSystemMatchers = getUnitSystemGroupMatchers(effectiveSystem);\r\n const presentationFormats = kindOfQuantity.presentationFormats;\r\n for (const matcher of unitSystemMatchers) {\r\n for (const lazyFormat of presentationFormats) {\r\n const format = await lazyFormat;\r\n const unit = await (format.units && format.units[0][0]);\r\n if (!unit) {\r\n continue;\r\n }\r\n const currentUnitSystem = await unit.unitSystem;\r\n if (currentUnitSystem && matcher(currentUnitSystem)) {\r\n this._formatsRetrieved.add(itemKey.fullName);\r\n const props = getFormatProps(format);\r\n return this.convertToFormatDefinition(props, kindOfQuantity);\r\n }\r\n }\r\n }\r\n\r\n // If no matching presentation format was found, fall back to persistence unit format\r\n // only if it matches the requested unit system.\r\n const persistenceUnit = await kindOfQuantity.persistenceUnit;\r\n const persistenceUnitSystem = await persistenceUnit?.unitSystem;\r\n if (persistenceUnit && persistenceUnitSystem && unitSystemMatchers.some((matcher) => matcher(persistenceUnitSystem))) {\r\n this._formatsRetrieved.add(itemKey.fullName);\r\n const props = getPersistenceUnitFormatProps(persistenceUnit);\r\n return this.convertToFormatDefinition(props, kindOfQuantity);\r\n }\r\n }\r\n\r\n // If no unit system was provided, or no matching format was found, use the default presentation format.\r\n // Unit conversion from persistence unit to presentation unit will be handled by FormatterSpec.\r\n const defaultFormat = kindOfQuantity.defaultPresentationFormat;\r\n if (defaultFormat) {\r\n this._formatsRetrieved.add(itemKey.fullName);\r\n const defaultProps = getFormatProps(await defaultFormat);\r\n return this.convertToFormatDefinition(defaultProps, kindOfQuantity);\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n\r\n /**\r\n * Retrieves a Format from a SchemaContext. If the format is part of a KindOfQuantity, the first presentation format in the KindOfQuantity that matches the current unit system will be retrieved.\r\n * If no presentation format matches the current unit system, the persistence unit format will be retrieved if it matches the current unit system.\r\n * Else, the default presentation format will be retrieved.\r\n * @param name The full name of the Format or KindOfQuantity.\r\n * @returns\r\n */\r\n public async getFormat(name: string, system?: UnitSystemKey): Promise<FormatDefinition | undefined> {\r\n const [schemaName, schemaItemName] = SchemaItem.parseFullName(name);\r\n const schemaKey = new SchemaKey(schemaName);\r\n let schema: Schema | undefined;\r\n try {\r\n schema = await this._context.getSchema(schemaKey);\r\n } catch {\r\n Logger.logError(loggerCategory, `Failed to find schema ${schemaName}`);\r\n return undefined;\r\n }\r\n if (!schema) {\r\n return undefined;\r\n }\r\n const itemKey = new SchemaItemKey(schemaItemName, schema.schemaKey);\r\n\r\n if (schema.name === \"Formats\") {\r\n let format: Format | undefined;\r\n try {\r\n format = await this._context.getSchemaItem(itemKey, Format);\r\n } catch {\r\n Logger.logError(loggerCategory, `Failed to find Format ${itemKey.fullName}`);\r\n return undefined;\r\n }\r\n if (!format) {\r\n return undefined;\r\n }\r\n return format.toJSON(true);\r\n }\r\n return this.getKindOfQuantityFormatFromSchema(itemKey, system);\r\n }\r\n}\r\n\r\nfunction getUnitSystemGroupMatchers(groupKey?: UnitSystemKey) {\r\n function createMatcher(name: string | string[]) {\r\n const names = Array.isArray(name) ? name : [name];\r\n return (unitSystem: UnitSystem) => names.some((n) => n === unitSystem.name.toUpperCase());\r\n }\r\n switch (groupKey) {\r\n case \"imperial\":\r\n return [\"IMPERIAL\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"metric\":\r\n return [[\"SI\", \"METRIC\"], \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"usCustomary\":\r\n return [\"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"usSurvey\":\r\n return [\"USSURVEY\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n }\r\n return [];\r\n}\r\n\r\nfunction getPersistenceUnitFormatProps(persistenceUnit: Unit | InvertedUnit): FormatProps {\r\n // Same as Format \"DefaultRealU\" in Formats ecschema\r\n return {\r\n formatTraits: [\"keepSingleZero\", \"keepDecimalPoint\", \"showUnitLabel\"],\r\n precision: 6,\r\n type: \"Decimal\",\r\n composite: {\r\n units: [\r\n {\r\n name: persistenceUnit.fullName,\r\n label: persistenceUnit.label,\r\n },\r\n ],\r\n },\r\n };\r\n}"]}
|
|
1
|
+
{"version":3,"file":"SchemaFormatsProvider.js","sourceRoot":"","sources":["../../../src/Formatting/SchemaFormatsProvider.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 Metadata\r\n */\r\n\r\nimport { ISchemaLocater, SchemaContext } from \"../Context\";\r\nimport { SchemaItemKey, SchemaKey } from \"../SchemaKey\";\r\nimport { SchemaMatchType } from \"../ECObjects\";\r\nimport { ECSchemaError, ECSchemaStatus } from \"../Exception\";\r\nimport { SchemaItem } from \"../Metadata/SchemaItem\";\r\nimport { Format } from \"../Metadata/Format\";\r\nimport { getFormatProps, OverrideFormat } from \"../Metadata/OverrideFormat\";\r\nimport { SchemaItemFormatProps } from \"../Deserialization/JsonProps\";\r\nimport { BeEvent, Logger } from \"@itwin/core-bentley\";\r\nimport { KindOfQuantity } from \"../Metadata/KindOfQuantity\";\r\nimport { FormatDefinition, FormatProps, FormatsChangedArgs, FormatsProvider, SyncFormatsProvider, UnitSystemKey } from \"@itwin/core-quantity\";\r\nimport { type LazyLoadedFormat, type LazyLoadedInvertedUnit, type LazyLoadedUnit } from \"../Interfaces\";\r\nimport { Unit } from \"../Metadata/Unit\";\r\nimport { InvertedUnit } from \"../Metadata/InvertedUnit\";\r\nimport { Schema } from \"../Metadata/Schema\";\r\nimport { UnitSystem } from \"../Metadata/UnitSystem\";\r\nconst loggerCategory = \"SchemaFormatsProvider\";\r\n/**\r\n * Provides default formats and kind of quantities from a given SchemaContext or SchemaLocater.\r\n * @beta\r\n */\r\nexport class SchemaFormatsProvider implements FormatsProvider, SyncFormatsProvider {\r\n private _context: SchemaContext;\r\n private _unitSystem?: UnitSystemKey;\r\n private _formatsRetrieved: Set<string> = new Set();\r\n public onFormatsChanged = new BeEvent<(args: FormatsChangedArgs) => void>();\r\n /**\r\n *\r\n * @param contextOrLocater The SchemaContext or a different ISchemaLocater implementation used to retrieve the schema. The SchemaContext\r\n * class implements the ISchemaLocater interface. If the provided locater is not a SchemaContext instance a new SchemaContext will be\r\n * created and the locater will be added.\r\n * @param unitSystem Optional unit system used to lookup a default format through a schema specific algorithm, when the format retrieved is associated with a KindOfQuantity.\r\n * If not provided, the default presentation format will be used directly without matching unit systems.\r\n */\r\n constructor(contextOrLocater: ISchemaLocater, unitSystem?: UnitSystemKey) {\r\n if (contextOrLocater instanceof SchemaContext) {\r\n this._context = contextOrLocater;\r\n } else {\r\n this._context = new SchemaContext();\r\n this._context.addLocater(contextOrLocater);\r\n }\r\n this._unitSystem = unitSystem;\r\n }\r\n\r\n public get context() { return this._context; }\r\n public get unitSystem() { return this._unitSystem; }\r\n\r\n public set unitSystem(unitSystem: UnitSystemKey | undefined) {\r\n this._unitSystem = unitSystem;\r\n this.clear();\r\n }\r\n\r\n private clear(): void {\r\n const formatsChanged = Array.from(this._formatsRetrieved);\r\n this._formatsRetrieved.clear();\r\n this.onFormatsChanged.raiseEvent({ formatsChanged });\r\n }\r\n\r\n /** When using a presentation unit from a KindOfQuantity, the label and description should come from the KindOfQuantity */\r\n private convertToFormatDefinition(format: SchemaItemFormatProps, kindOfQuantity: KindOfQuantity): FormatDefinition {\r\n // Destructure all properties except 'rest'\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n const { name, label, description, $schema, schema, schemaVersion, schemaItemType,\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n customAttributes, originalECSpecMajorVersion, originalECSpecMinorVersion, ...rest } = format;\r\n\r\n return {\r\n ...rest,\r\n name: kindOfQuantity.fullName,\r\n label: kindOfQuantity.label ?? format.label,\r\n description: kindOfQuantity.description ?? format.description,\r\n }\r\n }\r\n\r\n private async getKindOfQuantityFormatFromSchema(itemKey: SchemaItemKey, systemOverride?: UnitSystemKey): Promise<FormatDefinition | undefined> {\r\n let kindOfQuantity: KindOfQuantity | undefined;\r\n try {\r\n kindOfQuantity = await this._context.getSchemaItem(itemKey, KindOfQuantity);\r\n } catch {\r\n Logger.logError(loggerCategory, `Failed to find KindOfQuantity ${itemKey.fullName}`);\r\n return undefined;\r\n }\r\n\r\n if (!kindOfQuantity)\r\n return undefined;\r\n\r\n const props = await this.getKindOfQuantityFormatProps(kindOfQuantity, systemOverride);\r\n if (!props)\r\n return undefined;\r\n\r\n this._formatsRetrieved.add(itemKey.fullName);\r\n return this.convertToFormatDefinition(props, kindOfQuantity);\r\n }\r\n\r\n private async getKindOfQuantityFormatProps(kindOfQuantity: KindOfQuantity, systemOverride?: UnitSystemKey): Promise<FormatProps | undefined> {\r\n // Cache each unit once per lookup because matchers may revisit it. Lazy formats already resolve only once.\r\n const unitCache = new Map<UnitReference, Promise<ResolvedUnit>>();\r\n const getUnit = (unit: UnitReference | undefined): Promise<ResolvedUnit> | undefined => {\r\n if (!unit)\r\n return undefined;\r\n\r\n let resolved = unitCache.get(unit);\r\n if (!resolved) {\r\n resolved = resolveUnitAsync(unit);\r\n unitCache.set(unit, resolved);\r\n }\r\n return resolved;\r\n };\r\n\r\n for (const candidate of getFormatSelectionCandidates(kindOfQuantity, systemOverride ?? this._unitSystem)) {\r\n const format = candidate.type === \"persistence\" ? undefined : await candidate.format;\r\n const unit = candidate.type === \"default\" ? undefined : await getUnit(candidate.type === \"persistence\" ? candidate.unit : format?.units?.[0]?.[0]);\r\n const props = getFormatPropsForCandidate(candidate, format, unit);\r\n if (props)\r\n return props;\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Retrieves a format definition from the schema context.\r\n *\r\n * For a KindOfQuantity with a unit system, matching presentation formats are checked first, followed by the persistence unit and then the default presentation format. Without a unit system, the default presentation format is used.\r\n * @param name The full name of the Format or KindOfQuantity.\r\n * @param system Optional unit system used to select a KindOfQuantity format.\r\n */\r\n public async getFormat(name: string, system?: UnitSystemKey): Promise<FormatDefinition | undefined> {\r\n const [schemaName, schemaItemName] = SchemaItem.parseFullName(name);\r\n const schemaKey = new SchemaKey(schemaName);\r\n let schema: Schema | undefined;\r\n try {\r\n schema = await this._context.getSchema(schemaKey);\r\n } catch {\r\n Logger.logError(loggerCategory, `Failed to find schema ${schemaName}`);\r\n return undefined;\r\n }\r\n if (!schema) {\r\n return undefined;\r\n }\r\n const itemKey = new SchemaItemKey(schemaItemName, schema.schemaKey);\r\n\r\n if (schema.name === \"Formats\") {\r\n let format: Format | undefined;\r\n try {\r\n format = await this._context.getSchemaItem(itemKey, Format);\r\n } catch {\r\n Logger.logError(loggerCategory, `Failed to find Format ${itemKey.fullName}`);\r\n return undefined;\r\n }\r\n if (!format) {\r\n return undefined;\r\n }\r\n return format.toJSON(true);\r\n }\r\n return this.getKindOfQuantityFormatFromSchema(itemKey, system);\r\n }\r\n\r\n /**\r\n * Retrieves a format definition using only schema metadata already loaded in the context.\r\n * It follows the same selection order as `getFormat` but never asks a locater to load a schema. Returns `undefined` when required metadata is not cached.\r\n * Unlike `getFormat`, which logs lookup errors and returns `undefined`, this method treats only a schema that is still loading as a cache miss and rethrows other errors.\r\n */\r\n public getFormatSync(name: string, system?: UnitSystemKey): FormatDefinition | undefined {\r\n const [schemaName, schemaItemName] = SchemaItem.parseFullName(name);\r\n const schemaKey = new SchemaKey(schemaName);\r\n const schema = getCachedSchemaSync(this._context, schemaKey, SchemaMatchType.Latest);\r\n if (!schema)\r\n return undefined;\r\n\r\n const itemKey = new SchemaItemKey(schemaItemName, schema.schemaKey);\r\n if (schema.name === \"Formats\") {\r\n const format = schema.getItemSync(itemKey.name, Format);\r\n return format?.toJSON(true);\r\n }\r\n\r\n return this.getKindOfQuantityFormatFromSchemaSync(itemKey, system);\r\n }\r\n\r\n private getKindOfQuantityFormatFromSchemaSync(itemKey: SchemaItemKey, systemOverride?: UnitSystemKey): FormatDefinition | undefined {\r\n const schema = getCachedSchemaSync(this._context, itemKey.schemaKey, SchemaMatchType.Latest);\r\n const kindOfQuantity = schema?.getItemSync(itemKey.name, KindOfQuantity);\r\n if (!kindOfQuantity)\r\n return undefined;\r\n\r\n const props = this.getKindOfQuantityFormatPropsSync(kindOfQuantity, systemOverride);\r\n if (!props)\r\n return undefined;\r\n\r\n this._formatsRetrieved.add(itemKey.fullName);\r\n return this.convertToFormatDefinition(props, kindOfQuantity);\r\n }\r\n\r\n private getKindOfQuantityFormatPropsSync(kindOfQuantity: KindOfQuantity, systemOverride?: UnitSystemKey): FormatProps | undefined {\r\n const formatCache = new Map<FormatReference, ResolvedFormat | undefined>();\r\n const unitCache = new Map<UnitReference, ResolvedUnit | undefined>();\r\n const getFormat = (format: FormatReference): ResolvedFormat | undefined => {\r\n if (!formatCache.has(format))\r\n formatCache.set(format, resolveFormatSync(this._context, format));\r\n return formatCache.get(format);\r\n };\r\n const getUnit = (unit: UnitReference | undefined): ResolvedUnit | undefined => {\r\n if (!unit)\r\n return undefined;\r\n if (!unitCache.has(unit))\r\n unitCache.set(unit, resolveUnitSync(this._context, unit));\r\n return unitCache.get(unit);\r\n };\r\n\r\n // A reference that cannot be resolved means metadata is not cached. Stop there: async lookup would resolve it and never reach a later candidate.\r\n for (const candidate of getFormatSelectionCandidates(kindOfQuantity, systemOverride ?? this._unitSystem)) {\r\n const format = candidate.type === \"persistence\" ? undefined : getFormat(candidate.format);\r\n if (candidate.type !== \"persistence\" && !format)\r\n return undefined;\r\n\r\n const unitReference = candidate.type === \"presentation\" ? format?.units?.[0]?.[0] : candidate.type === \"persistence\" ? candidate.unit : undefined;\r\n const unit = getUnit(unitReference);\r\n if (unitReference && !unit)\r\n return undefined;\r\n\r\n const props = getFormatPropsForCandidate(candidate, format, unit);\r\n if (props)\r\n return props;\r\n }\r\n\r\n return undefined;\r\n }\r\n}\r\n\r\ntype FormatReference = LazyLoadedFormat | OverrideFormat;\r\ntype UnitReference = LazyLoadedUnit | LazyLoadedInvertedUnit;\r\ntype ResolvedFormat = Format | OverrideFormat;\r\ntype UnitSystemMatcher = (unitSystemName: string) => boolean;\r\n\r\ninterface ResolvedUnit {\r\n unit: Unit | InvertedUnit;\r\n unitSystemName?: string;\r\n}\r\n\r\ntype FormatSelectionCandidate =\r\n | { type: \"presentation\", format: FormatReference, matcher: UnitSystemMatcher }\r\n | { type: \"persistence\", unit: UnitReference | undefined, matchers: UnitSystemMatcher[] }\r\n | { type: \"default\", format: FormatReference };\r\n\r\n/**\r\n * Produces candidates in lookup order: presentation formats by unit-system priority, then the persistence unit,\r\n * then the default presentation format. The generator defers each candidate until the lookup reaches it.\r\n */\r\nfunction* getFormatSelectionCandidates(kindOfQuantity: KindOfQuantity, effectiveSystem?: UnitSystemKey): Iterable<FormatSelectionCandidate> {\r\n if (effectiveSystem) {\r\n const matchers = getUnitSystemGroupMatchers(effectiveSystem);\r\n for (const matcher of matchers) {\r\n for (const format of kindOfQuantity.presentationFormats)\r\n yield { type: \"presentation\", format, matcher };\r\n }\r\n yield { type: \"persistence\", unit: kindOfQuantity.persistenceUnit, matchers };\r\n }\r\n\r\n const defaultFormat = kindOfQuantity.defaultPresentationFormat;\r\n if (defaultFormat)\r\n yield { type: \"default\", format: defaultFormat };\r\n}\r\n\r\nfunction getFormatPropsForCandidate(candidate: FormatSelectionCandidate, format: ResolvedFormat | undefined, unit: ResolvedUnit | undefined): FormatProps | undefined {\r\n const unitSystemName = unit?.unitSystemName;\r\n switch (candidate.type) {\r\n case \"presentation\":\r\n return format && unitSystemName && candidate.matcher(unitSystemName) ? getFormatProps(format) : undefined;\r\n case \"persistence\":\r\n return unit && unitSystemName && candidate.matchers.some((matcher) => matcher(unitSystemName)) ? getPersistenceUnitFormatProps(unit.unit) : undefined;\r\n case \"default\":\r\n return format ? getFormatProps(format) : undefined;\r\n }\r\n}\r\n\r\nfunction resolveFormatSync(context: SchemaContext, format: FormatReference): ResolvedFormat | undefined {\r\n if (OverrideFormat.isOverrideFormat(format))\r\n return format;\r\n\r\n const schema = getCachedSchemaSync(context, format.schemaKey, SchemaMatchType.Exact);\r\n return schema?.getItemSync(format.name, Format);\r\n}\r\n\r\nasync function resolveUnitAsync(unit: UnitReference): Promise<ResolvedUnit> {\r\n const resolvedUnit = await unit;\r\n const unitSystem = await resolvedUnit.unitSystem;\r\n return { unit: resolvedUnit, unitSystemName: unitSystem?.name };\r\n}\r\n\r\nfunction resolveUnitSync(context: SchemaContext, unit: UnitReference): ResolvedUnit | undefined {\r\n const resolvedUnit = getLoadedUnitSync(context, unit);\r\n if (!resolvedUnit)\r\n return undefined;\r\n\r\n const unitSystem = resolvedUnit.unitSystem;\r\n if (!unitSystem)\r\n return { unit: resolvedUnit };\r\n\r\n const unitSystemName = getCachedSchemaSync(context, unitSystem.schemaKey, SchemaMatchType.Exact)?.getItemSync(unitSystem.name, UnitSystem)?.name;\r\n return unitSystemName ? { unit: resolvedUnit, unitSystemName } : undefined;\r\n}\r\n\r\n/**\r\n * Name-only lookups use `SchemaMatchType.Latest`. References use `SchemaMatchType.Exact` because they carry the version\r\n * the loaded item resolved; matching by name alone could return an item from a different cached version.\r\n */\r\nfunction getCachedSchemaSync(context: SchemaContext, schemaKey: SchemaKey, matchType: SchemaMatchType): Schema | undefined {\r\n try {\r\n return context.getCachedSchemaSync(schemaKey, matchType);\r\n } catch (error) {\r\n if (error instanceof ECSchemaError && error.errorNumber === ECSchemaStatus.UnableToLoadSchema)\r\n return undefined;\r\n throw error;\r\n }\r\n}\r\n\r\nfunction getLoadedUnitSync(context: SchemaContext, unit: UnitReference): Unit | InvertedUnit | undefined {\r\n const schema = getCachedSchemaSync(context, unit.schemaKey, SchemaMatchType.Exact);\r\n const item = schema?.getItemSync(unit.name);\r\n return Unit.isUnit(item) || InvertedUnit.isInvertedUnit(item) ? item : undefined;\r\n}\r\n\r\nfunction getUnitSystemGroupMatchers(groupKey?: UnitSystemKey): UnitSystemMatcher[] {\r\n function createMatcher(name: string | string[]): UnitSystemMatcher {\r\n const names = Array.isArray(name) ? name : [name];\r\n return (unitSystemName: string) => names.some((n) => n === unitSystemName.toUpperCase());\r\n }\r\n switch (groupKey) {\r\n case \"imperial\":\r\n return [\"IMPERIAL\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"metric\":\r\n return [[\"SI\", \"METRIC\"], \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"usCustomary\":\r\n return [\"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n case \"usSurvey\":\r\n return [\"USSURVEY\", \"USCUSTOM\", \"INTERNATIONAL\", \"FINANCE\"].map(createMatcher);\r\n }\r\n return [];\r\n}\r\n\r\nfunction getPersistenceUnitFormatProps(persistenceUnit: Unit | InvertedUnit): FormatProps {\r\n // Same as Format \"DefaultRealU\" in Formats ecschema\r\n return {\r\n formatTraits: [\"keepSingleZero\", \"keepDecimalPoint\", \"showUnitLabel\"],\r\n precision: 6,\r\n type: \"Decimal\",\r\n composite: {\r\n units: [\r\n {\r\n name: persistenceUnit.fullName,\r\n label: persistenceUnit.label,\r\n },\r\n ],\r\n },\r\n };\r\n}"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @module Schema
|
|
3
3
|
*/
|
|
4
4
|
/** One schema in a {@link SchemaManifest}: its name, version, and the entries it directly references.
|
|
5
|
-
* @
|
|
5
|
+
* @beta
|
|
6
6
|
*/
|
|
7
7
|
export interface SchemaManifestEntry {
|
|
8
8
|
readonly name: string;
|
|
@@ -17,7 +17,7 @@ export interface SchemaManifestEntry {
|
|
|
17
17
|
* @note `ecInstanceId` is a plain number, matching SchemaView's convention for schema-related rows:
|
|
18
18
|
* `ec_` metadata rowids carry no briefcase prefix, so they are exactly representable. It is used
|
|
19
19
|
* only to wire reference edges and is not retained in the manifest.
|
|
20
|
-
* @
|
|
20
|
+
* @beta
|
|
21
21
|
*/
|
|
22
22
|
export interface SchemaManifestSchemaRow {
|
|
23
23
|
readonly ecInstanceId: number;
|
|
@@ -28,22 +28,20 @@ export interface SchemaManifestSchemaRow {
|
|
|
28
28
|
}
|
|
29
29
|
/** One row of `SELECT SourceECInstanceId, TargetECInstanceId FROM meta.SchemaHasSchemaReferences`,
|
|
30
30
|
* as passed to {@link SchemaManifest.fromRows}.
|
|
31
|
-
* @
|
|
31
|
+
* @beta
|
|
32
32
|
*/
|
|
33
33
|
export interface SchemaManifestReferenceRow {
|
|
34
34
|
readonly sourceECInstanceId: number;
|
|
35
35
|
readonly targetECInstanceId: number;
|
|
36
36
|
}
|
|
37
37
|
/** The reference graph of every schema in one iModel - names, versions and reference edges, without
|
|
38
|
-
*
|
|
39
|
-
*
|
|
38
|
+
* schema items. A {@link SchemaViewDataProvider} builds it from ECDbMeta rows via
|
|
39
|
+
* {@link SchemaManifest.fromRows}. It includes schemas excluded from SchemaView's binary data.
|
|
40
40
|
*
|
|
41
|
-
*
|
|
42
|
-
* The
|
|
43
|
-
*
|
|
44
|
-
* @
|
|
45
|
-
* and filters the result of {@link SchemaManifest.getSchemaClosure} itself.
|
|
46
|
-
* @internal
|
|
41
|
+
* {@link SchemaViewManager} uses this graph to determine which schemas a filtered request needs.
|
|
42
|
+
* The manifest does not track which schemas are already loaded; the manager filters the result of
|
|
43
|
+
* {@link SchemaManifest.getSchemaClosure} itself.
|
|
44
|
+
* @beta
|
|
47
45
|
*/
|
|
48
46
|
export declare class SchemaManifest {
|
|
49
47
|
private readonly _entries;
|
|
@@ -53,7 +51,7 @@ export declare class SchemaManifest {
|
|
|
53
51
|
/** Build a manifest from raw ECDbMeta query rows, so a `SchemaViewDataProvider` only has to run
|
|
54
52
|
* the two queries and hand the rows over. Reference rows whose endpoints are unknown or
|
|
55
53
|
* self-referential are skipped; that cannot happen for a well-formed iModel.
|
|
56
|
-
* @
|
|
54
|
+
* @beta
|
|
57
55
|
*/
|
|
58
56
|
static fromRows(schemaRows: readonly SchemaManifestSchemaRow[], referenceRows: readonly SchemaManifestReferenceRow[]): SchemaManifest;
|
|
59
57
|
/** The number of schemas in the iModel. */
|
|
@@ -64,8 +62,7 @@ export declare class SchemaManifest {
|
|
|
64
62
|
/** The entry for a schema by name (case-insensitive), or `undefined` if the iModel has no such schema. */
|
|
65
63
|
findByName(name: string): SchemaManifestEntry | undefined;
|
|
66
64
|
/** The transitive reference closure of the requested schemas, as a flat, duplicate-free list of
|
|
67
|
-
* names: the full set
|
|
68
|
-
* {@link SchemaManifest.sortInDependencyOrder} on the result when a load order is needed.
|
|
65
|
+
* names: the full set to request in a standalone fragment. The order is unspecified.
|
|
69
66
|
* @note Requested names the iModel does not contain are ignored; check
|
|
70
67
|
* {@link SchemaManifest.findByName} first to detect them.
|
|
71
68
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaManifest.d.ts","sourceRoot":"","sources":["../../../src/SchemaView/SchemaManifest.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,UAAU,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACrD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED
|
|
1
|
+
{"version":3,"file":"SchemaManifest.d.ts","sourceRoot":"","sources":["../../../src/SchemaView/SchemaManifest.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,UAAU,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACrD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA2C;IAExE,gFAAgF;gBAC7D,OAAO,EAAE,SAAS,mBAAmB,EAAE;IAQ1D;;;;OAIG;WACW,QAAQ,CAAC,UAAU,EAAE,SAAS,uBAAuB,EAAE,EAAE,aAAa,EAAE,SAAS,0BAA0B,EAAE,GAAG,cAAc;IA6B5I,2CAA2C;IAC3C,IAAW,WAAW,IAAI,MAAM,CAAiC;IAEjE,kEAAkE;IAC3D,uBAAuB,IAAI,MAAM,EAAE;IAI1C,IAAW,OAAO,IAAI,SAAS,mBAAmB,EAAE,CAEnD;IAED,0GAA0G;IACnG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAIhE;;;;OAIG;IACI,gBAAgB,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;IAqBnE;;;;;OAKG;IACI,qBAAqB,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;CA4BtE"}
|
|
@@ -9,15 +9,13 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.SchemaManifest = void 0;
|
|
11
11
|
/** The reference graph of every schema in one iModel - names, versions and reference edges, without
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* schema items. A {@link SchemaViewDataProvider} builds it from ECDbMeta rows via
|
|
13
|
+
* {@link SchemaManifest.fromRows}. It includes schemas excluded from SchemaView's binary data.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
* The
|
|
17
|
-
*
|
|
18
|
-
* @
|
|
19
|
-
* and filters the result of {@link SchemaManifest.getSchemaClosure} itself.
|
|
20
|
-
* @internal
|
|
15
|
+
* {@link SchemaViewManager} uses this graph to determine which schemas a filtered request needs.
|
|
16
|
+
* The manifest does not track which schemas are already loaded; the manager filters the result of
|
|
17
|
+
* {@link SchemaManifest.getSchemaClosure} itself.
|
|
18
|
+
* @beta
|
|
21
19
|
*/
|
|
22
20
|
class SchemaManifest {
|
|
23
21
|
_entries;
|
|
@@ -33,7 +31,7 @@ class SchemaManifest {
|
|
|
33
31
|
/** Build a manifest from raw ECDbMeta query rows, so a `SchemaViewDataProvider` only has to run
|
|
34
32
|
* the two queries and hand the rows over. Reference rows whose endpoints are unknown or
|
|
35
33
|
* self-referential are skipped; that cannot happen for a well-formed iModel.
|
|
36
|
-
* @
|
|
34
|
+
* @beta
|
|
37
35
|
*/
|
|
38
36
|
static fromRows(schemaRows, referenceRows) {
|
|
39
37
|
const entries = [];
|
|
@@ -72,8 +70,7 @@ class SchemaManifest {
|
|
|
72
70
|
return this._byLowerName.get(name.toLowerCase());
|
|
73
71
|
}
|
|
74
72
|
/** The transitive reference closure of the requested schemas, as a flat, duplicate-free list of
|
|
75
|
-
* names: the full set
|
|
76
|
-
* {@link SchemaManifest.sortInDependencyOrder} on the result when a load order is needed.
|
|
73
|
+
* names: the full set to request in a standalone fragment. The order is unspecified.
|
|
77
74
|
* @note Requested names the iModel does not contain are ignored; check
|
|
78
75
|
* {@link SchemaManifest.findByName} first to detect them.
|
|
79
76
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaManifest.js","sourceRoot":"","sources":["../../../src/SchemaView/SchemaManifest.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 Schema\r\n */\r\n\r\n/** One schema in a {@link SchemaManifest}: its name, version, and the entries it directly references.\r\n * @internal\r\n */\r\nexport interface SchemaManifestEntry {\r\n readonly name: string;\r\n readonly readVersion: number;\r\n readonly writeVersion: number;\r\n readonly minorVersion: number;\r\n /** The schemas this schema directly references. */\r\n readonly references: readonly SchemaManifestEntry[];\r\n}\r\n\r\n/** One row of `SELECT ECInstanceId, Name, VersionMajor, VersionWrite, VersionMinor FROM\r\n * meta.ECSchemaDef`, as passed to {@link SchemaManifest.fromRows}.\r\n * @note `ecInstanceId` is a plain number, matching SchemaView's convention for schema-related rows:\r\n * `ec_` metadata rowids carry no briefcase prefix, so they are exactly representable. It is used\r\n * only to wire reference edges and is not retained in the manifest.\r\n * @internal\r\n */\r\nexport interface SchemaManifestSchemaRow {\r\n readonly ecInstanceId: number;\r\n readonly name: string;\r\n readonly versionMajor: number;\r\n readonly versionWrite: number;\r\n readonly versionMinor: number;\r\n}\r\n\r\n/** One row of `SELECT SourceECInstanceId, TargetECInstanceId FROM meta.SchemaHasSchemaReferences`,\r\n * as passed to {@link SchemaManifest.fromRows}.\r\n * @internal\r\n */\r\nexport interface SchemaManifestReferenceRow {\r\n readonly sourceECInstanceId: number;\r\n readonly targetECInstanceId: number;\r\n}\r\n\r\n/** The reference graph of every schema in one iModel - names, versions and reference edges, without\r\n * any schema data. A {@link (SchemaView:class)} husk loads it up front to answer which schemas exist\r\n * and which dependency-ordered set it must load to satisfy a request.\r\n *\r\n * A `SchemaViewDataProvider` builds the manifest from ECDbMeta rows via {@link SchemaManifest.fromRows}.\r\n * The entries are a flat array with no iModel or platform dependency; even the largest iModels hold\r\n * on the order of a hundred schemas, so the closure and topological walks are plain recursion.\r\n * @note The manifest does not track which schemas are already loaded. `SchemaViewManager` does that\r\n * and filters the result of {@link SchemaManifest.getSchemaClosure} itself.\r\n * @internal\r\n */\r\nexport class SchemaManifest {\r\n private readonly _entries: readonly SchemaManifestEntry[];\r\n private readonly _byLowerName: ReadonlyMap<string, SchemaManifestEntry>;\r\n\r\n /** Wraps a set of entries whose references are already wired to one another. */\r\n public constructor(entries: readonly SchemaManifestEntry[]) {\r\n this._entries = entries;\r\n const byLowerName = new Map<string, SchemaManifestEntry>();\r\n for (const entry of entries)\r\n byLowerName.set(entry.name.toLowerCase(), entry);\r\n this._byLowerName = byLowerName;\r\n }\r\n\r\n /** Build a manifest from raw ECDbMeta query rows, so a `SchemaViewDataProvider` only has to run\r\n * the two queries and hand the rows over. Reference rows whose endpoints are unknown or\r\n * self-referential are skipped; that cannot happen for a well-formed iModel.\r\n * @internal\r\n */\r\n public static fromRows(schemaRows: readonly SchemaManifestSchemaRow[], referenceRows: readonly SchemaManifestReferenceRow[]): SchemaManifest {\r\n // Mutable during the wiring walk below; entries are read-only once handed to the manifest.\r\n type MutableEntry = Omit<SchemaManifestEntry, \"references\"> & { references: SchemaManifestEntry[] };\r\n\r\n const entries: MutableEntry[] = [];\r\n const entryByECInstanceId = new Map<number, MutableEntry>();\r\n for (const row of schemaRows) {\r\n const entry: MutableEntry = {\r\n name: row.name,\r\n readVersion: row.versionMajor,\r\n writeVersion: row.versionWrite,\r\n minorVersion: row.versionMinor,\r\n references: [],\r\n };\r\n entries.push(entry);\r\n entryByECInstanceId.set(row.ecInstanceId, entry);\r\n }\r\n\r\n for (const row of referenceRows) {\r\n const source = entryByECInstanceId.get(row.sourceECInstanceId);\r\n const target = entryByECInstanceId.get(row.targetECInstanceId);\r\n if (source === undefined || target === undefined || source === target || source.references.includes(target))\r\n continue;\r\n source.references.push(target);\r\n }\r\n\r\n return new SchemaManifest(entries);\r\n }\r\n\r\n /** The number of schemas in the iModel. */\r\n public get schemaCount(): number { return this._entries.length; }\r\n\r\n /** The names of every schema in the iModel, in manifest order. */\r\n public getAvailableSchemaNames(): string[] {\r\n return this._entries.map((entry) => entry.name);\r\n }\r\n\r\n public get entries(): readonly SchemaManifestEntry[] {\r\n return this._entries;\r\n }\r\n\r\n /** The entry for a schema by name (case-insensitive), or `undefined` if the iModel has no such schema. */\r\n public findByName(name: string): SchemaManifestEntry | undefined {\r\n return this._byLowerName.get(name.toLowerCase());\r\n }\r\n\r\n /** The transitive reference closure of the requested schemas, as a flat, duplicate-free list of\r\n * names: the full set that must be present to use them. The order is unspecified - run\r\n * {@link SchemaManifest.sortInDependencyOrder} on the result when a load order is needed.\r\n * @note Requested names the iModel does not contain are ignored; check\r\n * {@link SchemaManifest.findByName} first to detect them.\r\n */\r\n public getSchemaClosure(requestedNames: Iterable<string>): string[] {\r\n const result: string[] = [];\r\n const visited = new Set<SchemaManifestEntry>();\r\n\r\n const visit = (entry: SchemaManifestEntry): void => {\r\n if (visited.has(entry))\r\n return;\r\n visited.add(entry);\r\n result.push(entry.name);\r\n for (const reference of entry.references)\r\n visit(reference);\r\n };\r\n\r\n for (const name of requestedNames) {\r\n const entry = this._byLowerName.get(name.toLowerCase());\r\n if (entry !== undefined)\r\n visit(entry);\r\n }\r\n return result;\r\n }\r\n\r\n /** Orders the given schema names so each appears after every schema it references, directly or\r\n * transitively. References through schemas not in `schemaNames` are still honored, so the order is\r\n * correct even when an intermediate schema is left out. Names the iModel does not contain are\r\n * ignored, and reference cycles - which EC forbids - are broken arbitrarily rather than looping.\r\n * @internal\r\n */\r\n public sortInDependencyOrder(schemaNames: Iterable<string>): string[] {\r\n const requested = new Set<SchemaManifestEntry>();\r\n for (const name of schemaNames) {\r\n const entry = this._byLowerName.get(name.toLowerCase());\r\n if (entry !== undefined)\r\n requested.add(entry);\r\n }\r\n\r\n const result: string[] = [];\r\n const visited = new Set<SchemaManifestEntry>();\r\n const visiting = new Set<SchemaManifestEntry>();\r\n\r\n const visit = (entry: SchemaManifestEntry): void => {\r\n if (visited.has(entry) || visiting.has(entry))\r\n return;\r\n visiting.add(entry);\r\n for (const reference of entry.references)\r\n visit(reference);\r\n visiting.delete(entry);\r\n visited.add(entry);\r\n if (requested.has(entry))\r\n result.push(entry.name);\r\n };\r\n\r\n for (const entry of requested)\r\n visit(entry);\r\n return result;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"SchemaManifest.js","sourceRoot":"","sources":["../../../src/SchemaView/SchemaManifest.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 Schema\r\n */\r\n\r\n/** One schema in a {@link SchemaManifest}: its name, version, and the entries it directly references.\r\n * @beta\r\n */\r\nexport interface SchemaManifestEntry {\r\n readonly name: string;\r\n readonly readVersion: number;\r\n readonly writeVersion: number;\r\n readonly minorVersion: number;\r\n /** The schemas this schema directly references. */\r\n readonly references: readonly SchemaManifestEntry[];\r\n}\r\n\r\n/** One row of `SELECT ECInstanceId, Name, VersionMajor, VersionWrite, VersionMinor FROM\r\n * meta.ECSchemaDef`, as passed to {@link SchemaManifest.fromRows}.\r\n * @note `ecInstanceId` is a plain number, matching SchemaView's convention for schema-related rows:\r\n * `ec_` metadata rowids carry no briefcase prefix, so they are exactly representable. It is used\r\n * only to wire reference edges and is not retained in the manifest.\r\n * @beta\r\n */\r\nexport interface SchemaManifestSchemaRow {\r\n readonly ecInstanceId: number;\r\n readonly name: string;\r\n readonly versionMajor: number;\r\n readonly versionWrite: number;\r\n readonly versionMinor: number;\r\n}\r\n\r\n/** One row of `SELECT SourceECInstanceId, TargetECInstanceId FROM meta.SchemaHasSchemaReferences`,\r\n * as passed to {@link SchemaManifest.fromRows}.\r\n * @beta\r\n */\r\nexport interface SchemaManifestReferenceRow {\r\n readonly sourceECInstanceId: number;\r\n readonly targetECInstanceId: number;\r\n}\r\n\r\n/** The reference graph of every schema in one iModel - names, versions and reference edges, without\r\n * schema items. A {@link SchemaViewDataProvider} builds it from ECDbMeta rows via\r\n * {@link SchemaManifest.fromRows}. It includes schemas excluded from SchemaView's binary data.\r\n *\r\n * {@link SchemaViewManager} uses this graph to determine which schemas a filtered request needs.\r\n * The manifest does not track which schemas are already loaded; the manager filters the result of\r\n * {@link SchemaManifest.getSchemaClosure} itself.\r\n * @beta\r\n */\r\nexport class SchemaManifest {\r\n private readonly _entries: readonly SchemaManifestEntry[];\r\n private readonly _byLowerName: ReadonlyMap<string, SchemaManifestEntry>;\r\n\r\n /** Wraps a set of entries whose references are already wired to one another. */\r\n public constructor(entries: readonly SchemaManifestEntry[]) {\r\n this._entries = entries;\r\n const byLowerName = new Map<string, SchemaManifestEntry>();\r\n for (const entry of entries)\r\n byLowerName.set(entry.name.toLowerCase(), entry);\r\n this._byLowerName = byLowerName;\r\n }\r\n\r\n /** Build a manifest from raw ECDbMeta query rows, so a `SchemaViewDataProvider` only has to run\r\n * the two queries and hand the rows over. Reference rows whose endpoints are unknown or\r\n * self-referential are skipped; that cannot happen for a well-formed iModel.\r\n * @beta\r\n */\r\n public static fromRows(schemaRows: readonly SchemaManifestSchemaRow[], referenceRows: readonly SchemaManifestReferenceRow[]): SchemaManifest {\r\n // Mutable during the wiring walk below; entries are read-only once handed to the manifest.\r\n type MutableEntry = Omit<SchemaManifestEntry, \"references\"> & { references: SchemaManifestEntry[] };\r\n\r\n const entries: MutableEntry[] = [];\r\n const entryByECInstanceId = new Map<number, MutableEntry>();\r\n for (const row of schemaRows) {\r\n const entry: MutableEntry = {\r\n name: row.name,\r\n readVersion: row.versionMajor,\r\n writeVersion: row.versionWrite,\r\n minorVersion: row.versionMinor,\r\n references: [],\r\n };\r\n entries.push(entry);\r\n entryByECInstanceId.set(row.ecInstanceId, entry);\r\n }\r\n\r\n for (const row of referenceRows) {\r\n const source = entryByECInstanceId.get(row.sourceECInstanceId);\r\n const target = entryByECInstanceId.get(row.targetECInstanceId);\r\n if (source === undefined || target === undefined || source === target || source.references.includes(target))\r\n continue;\r\n source.references.push(target);\r\n }\r\n\r\n return new SchemaManifest(entries);\r\n }\r\n\r\n /** The number of schemas in the iModel. */\r\n public get schemaCount(): number { return this._entries.length; }\r\n\r\n /** The names of every schema in the iModel, in manifest order. */\r\n public getAvailableSchemaNames(): string[] {\r\n return this._entries.map((entry) => entry.name);\r\n }\r\n\r\n public get entries(): readonly SchemaManifestEntry[] {\r\n return this._entries;\r\n }\r\n\r\n /** The entry for a schema by name (case-insensitive), or `undefined` if the iModel has no such schema. */\r\n public findByName(name: string): SchemaManifestEntry | undefined {\r\n return this._byLowerName.get(name.toLowerCase());\r\n }\r\n\r\n /** The transitive reference closure of the requested schemas, as a flat, duplicate-free list of\r\n * names: the full set to request in a standalone fragment. The order is unspecified.\r\n * @note Requested names the iModel does not contain are ignored; check\r\n * {@link SchemaManifest.findByName} first to detect them.\r\n */\r\n public getSchemaClosure(requestedNames: Iterable<string>): string[] {\r\n const result: string[] = [];\r\n const visited = new Set<SchemaManifestEntry>();\r\n\r\n const visit = (entry: SchemaManifestEntry): void => {\r\n if (visited.has(entry))\r\n return;\r\n visited.add(entry);\r\n result.push(entry.name);\r\n for (const reference of entry.references)\r\n visit(reference);\r\n };\r\n\r\n for (const name of requestedNames) {\r\n const entry = this._byLowerName.get(name.toLowerCase());\r\n if (entry !== undefined)\r\n visit(entry);\r\n }\r\n return result;\r\n }\r\n\r\n /** Orders the given schema names so each appears after every schema it references, directly or\r\n * transitively. References through schemas not in `schemaNames` are still honored, so the order is\r\n * correct even when an intermediate schema is left out. Names the iModel does not contain are\r\n * ignored, and reference cycles - which EC forbids - are broken arbitrarily rather than looping.\r\n * @internal\r\n */\r\n public sortInDependencyOrder(schemaNames: Iterable<string>): string[] {\r\n const requested = new Set<SchemaManifestEntry>();\r\n for (const name of schemaNames) {\r\n const entry = this._byLowerName.get(name.toLowerCase());\r\n if (entry !== undefined)\r\n requested.add(entry);\r\n }\r\n\r\n const result: string[] = [];\r\n const visited = new Set<SchemaManifestEntry>();\r\n const visiting = new Set<SchemaManifestEntry>();\r\n\r\n const visit = (entry: SchemaManifestEntry): void => {\r\n if (visited.has(entry) || visiting.has(entry))\r\n return;\r\n visiting.add(entry);\r\n for (const reference of entry.references)\r\n visit(reference);\r\n visiting.delete(entry);\r\n visited.add(entry);\r\n if (requested.has(entry))\r\n result.push(entry.name);\r\n };\r\n\r\n for (const entry of requested)\r\n visit(entry);\r\n return result;\r\n }\r\n}\r\n"]}
|
|
@@ -52,8 +52,9 @@ export interface SchemaViewData {
|
|
|
52
52
|
* stateless wrappers that hold a reference to this view plus an index. They allocate nothing
|
|
53
53
|
* and cache nothing.
|
|
54
54
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
55
|
+
* Use {@link SchemaViewManager} to load schemas incrementally into one view, or parse a standalone
|
|
56
|
+
* binary blob via {@link (SchemaView:class).fromBinary}. Consumers cannot modify the metadata; a manager
|
|
57
|
+
* can extend its view with additional schemas while previously obtained view objects remain valid.
|
|
57
58
|
* @beta
|
|
58
59
|
*/
|
|
59
60
|
export declare class SchemaView {
|
|
@@ -109,7 +110,8 @@ export declare class SchemaView {
|
|
|
109
110
|
*/
|
|
110
111
|
findPropertyCategory(qualifiedName: string): SchemaView.PropertyCategory | undefined;
|
|
111
112
|
/** Parse a binary blob into a SchemaView. Synchronous.
|
|
112
|
-
* @param blob - The binary blob from `PRAGMA schema_view
|
|
113
|
+
* @param blob - The binary blob from `PRAGMA schema_view`, or a standalone `PRAGMA schema_view_fragment`
|
|
114
|
+
* containing the requested schemas and their references.
|
|
113
115
|
* @param schemaToken - Optional cache-invalidation token (schema name+version hash; see `PRAGMA checksum(schema_token)`).
|
|
114
116
|
* @beta
|
|
115
117
|
*/
|
|
@@ -167,6 +169,7 @@ export declare namespace SchemaView {
|
|
|
167
169
|
get ecInstanceId(): number;
|
|
168
170
|
get name(): string;
|
|
169
171
|
get alias(): string;
|
|
172
|
+
/** Display label, or the decoded name when the label is absent or empty. */
|
|
170
173
|
get label(): string;
|
|
171
174
|
get description(): string;
|
|
172
175
|
get readVersion(): number;
|
|
@@ -215,6 +218,7 @@ export declare namespace SchemaView {
|
|
|
215
218
|
*/
|
|
216
219
|
get ecInstanceId(): number;
|
|
217
220
|
get name(): string;
|
|
221
|
+
/** Display label, or the decoded name when the label is absent or empty. */
|
|
218
222
|
get label(): string;
|
|
219
223
|
get description(): string;
|
|
220
224
|
/** "SchemaName:ClassName" - colon-separated, matching the EC class full name convention.
|
|
@@ -261,7 +265,8 @@ export declare namespace SchemaView {
|
|
|
261
265
|
* Accepts a `SchemaView.Class` or a qualified name string ("SchemaName:ClassName").
|
|
262
266
|
*/
|
|
263
267
|
is(classOrName: Class | string): boolean;
|
|
264
|
-
/** Direct derived classes
|
|
268
|
+
/** Direct derived classes among the currently loaded schemas. A partial view may omit derived
|
|
269
|
+
* classes from other schemas. Expensive on first call (builds reverse map across all loaded classes). */
|
|
265
270
|
get derivedClasses(): readonly Class[];
|
|
266
271
|
/** Find a property by name (case-insensitive). Searches own + inherited.
|
|
267
272
|
*
|
|
@@ -316,7 +321,7 @@ export declare namespace SchemaView {
|
|
|
316
321
|
*/
|
|
317
322
|
get ecInstanceId(): number;
|
|
318
323
|
get name(): string;
|
|
319
|
-
/** Display label
|
|
324
|
+
/** Display label, or the decoded property name when the label is absent or empty.
|
|
320
325
|
* Labels are stored per-reference (not per-definition) because EC allows class overrides. */
|
|
321
326
|
get label(): string;
|
|
322
327
|
get description(): string;
|
|
@@ -438,6 +443,7 @@ export declare namespace SchemaView {
|
|
|
438
443
|
*/
|
|
439
444
|
get ecInstanceId(): number;
|
|
440
445
|
get name(): string;
|
|
446
|
+
/** Display label, or the decoded name when the label is absent or empty. */
|
|
441
447
|
get label(): string;
|
|
442
448
|
get description(): string;
|
|
443
449
|
/** "SchemaName:EnumName" - colon-separated. */
|
|
@@ -463,6 +469,7 @@ export declare namespace SchemaView {
|
|
|
463
469
|
/** @internal */ idx: number);
|
|
464
470
|
private get _data();
|
|
465
471
|
get name(): string;
|
|
472
|
+
/** Display label, or the decoded name when the label is absent or empty. */
|
|
466
473
|
get label(): string;
|
|
467
474
|
get description(): string;
|
|
468
475
|
get value(): number | string;
|
|
@@ -504,6 +511,7 @@ export declare namespace SchemaView {
|
|
|
504
511
|
*/
|
|
505
512
|
get ecInstanceId(): number;
|
|
506
513
|
get name(): string;
|
|
514
|
+
/** Display label, or the decoded name when the label is absent or empty. */
|
|
507
515
|
get label(): string;
|
|
508
516
|
get description(): string;
|
|
509
517
|
/** "SchemaName:KoqName" - colon-separated. */
|
|
@@ -555,6 +563,7 @@ export declare namespace SchemaView {
|
|
|
555
563
|
*/
|
|
556
564
|
get ecInstanceId(): number;
|
|
557
565
|
get name(): string;
|
|
566
|
+
/** Display label, or the decoded name when the label is absent or empty. */
|
|
558
567
|
get label(): string;
|
|
559
568
|
get description(): string;
|
|
560
569
|
/** "SchemaName:CategoryName" - colon-separated. */
|