@itwin/core-backend 5.15.0-dev.17 → 5.15.0-dev.19
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/lib/cjs/BlobContainerService.d.ts +2 -0
- package/lib/cjs/BlobContainerService.d.ts.map +1 -1
- package/lib/cjs/BlobContainerService.js.map +1 -1
- package/lib/cjs/workspace/SettingsEditor.d.ts +4 -3
- package/lib/cjs/workspace/SettingsEditor.d.ts.map +1 -1
- package/lib/cjs/workspace/SettingsEditor.js +7 -5
- package/lib/cjs/workspace/SettingsEditor.js.map +1 -1
- package/lib/esm/BlobContainerService.d.ts +2 -0
- package/lib/esm/BlobContainerService.d.ts.map +1 -1
- package/lib/esm/BlobContainerService.js.map +1 -1
- package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.d.ts +2 -0
- package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.d.ts.map +1 -0
- package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.js +240 -0
- package/lib/esm/test/schema/SchemaViewPropertyOverrides.test.js.map +1 -0
- package/lib/esm/test/schema/SchemaViewValidation.test.js +2 -8
- package/lib/esm/test/schema/SchemaViewValidation.test.js.map +1 -1
- package/lib/esm/test/workspace/SettingsContainers.test.d.ts +2 -0
- package/lib/esm/test/workspace/SettingsContainers.test.d.ts.map +1 -0
- package/lib/esm/test/workspace/SettingsContainers.test.js +95 -0
- package/lib/esm/test/workspace/SettingsContainers.test.js.map +1 -0
- package/lib/esm/workspace/SettingsEditor.d.ts +4 -3
- package/lib/esm/workspace/SettingsEditor.d.ts.map +1 -1
- package/lib/esm/workspace/SettingsEditor.js +7 -5
- package/lib/esm/workspace/SettingsEditor.js.map +1 -1
- package/package.json +16 -16
|
@@ -60,6 +60,8 @@ export declare namespace BlobContainer {
|
|
|
60
60
|
containerId: string;
|
|
61
61
|
/** The iTwinId that owns this container. */
|
|
62
62
|
iTwinId?: GuidString;
|
|
63
|
+
/** The iModelId that owns this container. */
|
|
64
|
+
iModelId?: GuidString;
|
|
63
65
|
/** The account iTwinId of the owning iTwin. */
|
|
64
66
|
accountITwinId?: GuidString;
|
|
65
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlobContainerService.d.ts","sourceRoot":"","sources":["../../src/BlobContainerService.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BlobContainerService.d.ts","sourceRoot":"","sources":["../../src/BlobContainerService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlobContainerService.js","sourceRoot":"","sources":["../../src/BlobContainerService.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAOH;;;GAGG;AACH,IAAiB,aAAa,
|
|
1
|
+
{"version":3,"file":"BlobContainerService.js","sourceRoot":"","sources":["../../src/BlobContainerService.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAOH;;;GAGG;AACH,IAAiB,aAAa,CAwL7B;AAxLD,WAAiB,aAAa;AAwL9B,CAAC,EAxLgB,aAAa,6BAAb,aAAa,QAwL7B","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 BlobContainers\r\n */\r\n\r\n// spell:ignore datacenter\r\n\r\nimport { AccessToken, GuidString, Id64String } from \"@itwin/core-bentley\";\r\nimport { SettingsContainer } from \"./workspace/Settings\";\r\n\r\n/**\r\n * Types and functions for creating, deleting and authorizing access to cloud-based blob containers for an iTwin.\r\n * @beta\r\n */\r\nexport namespace BlobContainer {\r\n\r\n /** Object that implements the methods to create, delete, and request access to a container. */\r\n export let service: BlobContainer.ContainerService | undefined;\r\n\r\n /** name of cloud provider for a container. */\r\n export type Provider = \"azure\" | \"google\";\r\n\r\n /** the name of the container within its `Scope` */\r\n export type ContainerId = string;\r\n\r\n /** token that authenticates a user. This token is required to obtain a `ContainerToken`. */\r\n export type UserToken = AccessToken;\r\n\r\n /** token that authenticates access to a container for either read or write. */\r\n export type ContainerToken = AccessToken;\r\n\r\n /**\r\n * The scope for a container. This determines:\r\n * - the \"owner\" organization, including the contract that governs its legal and commercial terms and obligations\r\n * - the administrators who may configure RBAC permissions\r\n * - the datacenter for the container. Every container resides in a datacenter as determined by the iTwinId. This\r\n * determines the region for data residency requirements.\r\n * - the lifecycle constraints for the container. No container can outlive its iTwin or its iModel (if defined). That is,\r\n * when the iTwin/iModel is deleted (either explicitly or due to contract expiration), the container is also deleted.\r\n */\r\n export interface Scope {\r\n /** iTwinId of the owner of this container. */\r\n iTwinId: Id64String;\r\n /** optionally, an iModelId within the iTwin. If present, container is deleted when the iModel is deleted. */\r\n iModelId?: Id64String;\r\n /** the user GUID an individual, if this container is private. */\r\n ownerGuid?: GuidString;\r\n }\r\n\r\n /**\r\n * Metadata about the use of a container so that:\r\n * - administrators can understand why a container exists for assigning RBAC permissions appropriately\r\n * - usage reports can aggregate types of containers\r\n * - applications can identify their containers\r\n * - applications can store properties about their containers\r\n */\r\n export interface Metadata {\r\n /** The machine-readable string that describes what the container is being used for (e.g. \"workspace\"). Always lowercase and singular. */\r\n containerType: string;\r\n /** Human-readable name for the container. This will be displayed in the administrator RBAC panel, and on usage reports. Not required to be unique.*/\r\n label: string;\r\n /** Optional human-readable explanation of the information held in the container. This will be displayed in the administrator RBAC panel, and on usage reports. */\r\n description?: string;\r\n /** optional properties for the container */\r\n json?: SettingsContainer;\r\n }\r\n\r\n /**\r\n * Properties returned by queryContainersMetadata\r\n */\r\n export interface MetadataResponse extends Metadata {\r\n /** The id of the container. */\r\n containerId: string;\r\n /** The iTwinId that owns this container. */\r\n iTwinId?: GuidString;\r\n /** The iModelId that owns this container. */\r\n iModelId?: GuidString;\r\n /** The account iTwinId of the owning iTwin. */\r\n accountITwinId?: GuidString;\r\n }\r\n\r\n /** Properties returned by `Service.requestToken` */\r\n export interface TokenProps {\r\n /**\r\n * Expiring token that provides the requested access to the container. Should be used in all subsequent requests for blobs within the container,\r\n * and must be refreshed before it expires\r\n */\r\n token: ContainerToken;\r\n /** Scope of the container. */\r\n scope: Scope;\r\n /** Name of the blob storage provider. */\r\n provider: Provider;\r\n /** Time at which the token will expire. The token should be refreshed (that is, a new token should be requested) before this time. */\r\n expiration: Date;\r\n /** Metadata of the container. */\r\n metadata: Metadata;\r\n /** Base URI of the storage account that hosts the container */\r\n baseUri: string;\r\n }\r\n\r\n /** The URI and Id of the container. */\r\n export interface UriAndId {\r\n baseUri: string;\r\n containerId: ContainerId;\r\n }\r\n\r\n /** Information required to access an existing container. */\r\n export interface AccessContainerProps extends UriAndId {\r\n userToken: UserToken;\r\n }\r\n\r\n /** Information about a newly created container. */\r\n export interface CreatedContainerProps extends UriAndId {\r\n /** name of the blob storage provider. */\r\n provider: Provider;\r\n }\r\n\r\n /**\r\n * Access level to request for token.\r\n * - `\"write\"`: request a writeable AccessToken.\r\n * - `\"read\"`: request a read-only AccessToken.\r\n * - `\"admin\"`: request a admin AccessToken.\r\n * - `\"writeIfPossible\"`: first request a writeable AccessToken. If the user is not authorized for write, request a read-only AccessToken.\r\n * If the user is not authorized for the level requested, an exception is thrown.\r\n */\r\n export type RequestAccessLevel = \"write\" | \"read\" | \"admin\" | \"writeIfPossible\";\r\n\r\n /** Information required to request an access token for a container. */\r\n export interface RequestTokenProps extends Omit<AccessContainerProps, \"baseUri\"> {\r\n /** the level of access requested. If not specified, defaults to `\"writeIfPossible\"`. */\r\n accessLevel?: RequestAccessLevel;\r\n /** the number of seconds before the token should expire.\r\n * @note A maximum duration is determined by the service. If no value is supplied, or the value is larger than the maximum, the maximum duration is used.\r\n */\r\n durationSeconds?: number;\r\n }\r\n\r\n /** Information required to create a new container. */\r\n export interface CreateNewContainerProps {\r\n /** the scope of the new container */\r\n scope: Scope;\r\n /** metadata to be stored on the new container */\r\n metadata: Metadata;\r\n /** The user's access token. The user must be authorized with \"create container\" RBAC role for the iTwin. */\r\n userToken: UserToken;\r\n /**\r\n * the id for the container. Useful for tests.\r\n * @internal\r\n */\r\n containerId?: ContainerId;\r\n }\r\n\r\n /**\r\n * Query Parameters for querying containers\r\n */\r\n export interface QueryContainerProps {\r\n /** the iTwinId of the containers to query */\r\n iTwinId: GuidString;\r\n /** optional iModelId of the containers to query */\r\n iModelId?: GuidString;\r\n /** optional containerType of the containers to query */\r\n containerType?: GuidString;\r\n /** optional label of the containers to query */\r\n label?: GuidString;\r\n /** Whether to include parent iTwins in the query. Pass `true` to traverse the full parent chain, or `{ filter: \"accountOnly\" }` to include only the account iTwin. Defaults to `false`. */\r\n includeParentITwins?: boolean | { filter: \"accountOnly\" };\r\n }\r\n\r\n /** Methods to create, delete, and access blob containers. */\r\n export interface ContainerService {\r\n /** Create a new blob container. Throws on failure (e.g. access denied or container already exists.) */\r\n create(props: CreateNewContainerProps): Promise<CreatedContainerProps>;\r\n\r\n /**\r\n * Delete an existing blob container.\r\n * @note This method requires that the user be authorized with \"delete container\" RBAC role for the iTwin.\r\n */\r\n delete(container: AccessContainerProps): Promise<void>;\r\n\r\n /** query the Scope for a container */\r\n queryScope(container: AccessContainerProps): Promise<Scope>;\r\n\r\n /** query the Metadata for a specific container */\r\n queryMetadata(container: AccessContainerProps): Promise<Metadata>;\r\n\r\n /** Returns all containers and their metadata associated with a given iTwinId.\r\n * Pass `includeParentITwins: { filter: \"accountOnly\" }` to also include the account iTwin container,\r\n * without traversing any higher parent chain.\r\n * Results can be further queried by label and containerType.\r\n */\r\n queryContainersMetadata(userToken: UserToken, args: QueryContainerProps): Promise<MetadataResponse[]>;\r\n\r\n /** update the json properties of this container */\r\n updateJson(container: AccessContainerProps, json: SettingsContainer): Promise<void>;\r\n\r\n /** Request a `ContainerToken` for a container. Throws on failure. */\r\n requestToken(props: RequestTokenProps): Promise<TokenProps>;\r\n }\r\n}\r\n"]}
|
|
@@ -41,9 +41,10 @@ export declare namespace SettingsEditor {
|
|
|
41
41
|
*/
|
|
42
42
|
export declare namespace SettingsContainers {
|
|
43
43
|
/**
|
|
44
|
-
* Query the [[BlobContainer]] service for the
|
|
45
|
-
*
|
|
46
|
-
* @
|
|
44
|
+
* Query the [[BlobContainer]] service for the iTwin-root settings container associated with a given iTwin.
|
|
45
|
+
* Only containers without an iModelId in their query metadata are considered.
|
|
46
|
+
* @returns The containerId, or `undefined` if no matching container is found.
|
|
47
|
+
* @throws if more than one matching container is found.
|
|
47
48
|
*/
|
|
48
49
|
function getITwinContainerId(iTwinId: GuidString): Promise<WorkspaceContainerId | undefined>;
|
|
49
50
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsEditor.d.ts","sourceRoot":"","sources":["../../../src/workspace/SettingsEditor.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAI7E,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIhF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD,gBAAgB;AAChB,yBAAiB,cAAc,CAAC;IAC9B,8DAA8D;IACvD,MAAM,aAAa,aAAa,CAAC;IAExC;;;;OAIG;IACH,SAAsB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,0BAA0B,CAAA;KAAE,CAAC,CAExI;IAED;;;;;OAKG;IACH,SAAsB,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,0BAA0B,CAAA;KAAE,GAAG,SAAS,CAAC,CAE9I;CACF;AAED;;;GAGG;AACH,yBAAiB,kBAAkB,CAAC;IAclC
|
|
1
|
+
{"version":3,"file":"SettingsEditor.d.ts","sourceRoot":"","sources":["../../../src/workspace/SettingsEditor.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAI7E,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIhF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD,gBAAgB;AAChB,yBAAiB,cAAc,CAAC;IAC9B,8DAA8D;IACvD,MAAM,aAAa,aAAa,CAAC;IAExC;;;;OAIG;IACH,SAAsB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,0BAA0B,CAAA;KAAE,CAAC,CAExI;IAED;;;;;OAKG;IACH,SAAsB,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,0BAA0B,CAAA;KAAE,GAAG,SAAS,CAAC,CAE9I;CACF;AAED;;;GAGG;AACH,yBAAiB,kBAAkB,CAAC;IAclC;;;;;OAKG;IACH,SAAsB,mBAAmB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CASxG;IAED;;;;;;;OAOG;IACH,SAAsB,uBAAuB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,wBAAwB,EAAE,GAAG,SAAS,CAAC,CAyClH;CACF"}
|
|
@@ -64,12 +64,13 @@ var SettingsContainers;
|
|
|
64
64
|
return BlobContainerService_1.BlobContainer.service.queryContainersMetadata(userToken, { ...args, containerType: SettingsEditor.containerType });
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
67
|
-
* Query the [[BlobContainer]] service for the
|
|
68
|
-
*
|
|
69
|
-
* @
|
|
67
|
+
* Query the [[BlobContainer]] service for the iTwin-root settings container associated with a given iTwin.
|
|
68
|
+
* Only containers without an iModelId in their query metadata are considered.
|
|
69
|
+
* @returns The containerId, or `undefined` if no matching container is found.
|
|
70
|
+
* @throws if more than one matching container is found.
|
|
70
71
|
*/
|
|
71
72
|
async function getITwinContainerId(iTwinId) {
|
|
72
|
-
const containers = await queryContainers({ iTwinId });
|
|
73
|
+
const containers = (await queryContainers({ iTwinId })).filter((container) => undefined === container.iModelId);
|
|
73
74
|
if (containers.length > 1) {
|
|
74
75
|
core_common_1.ITwinSettingsError.throwError("multiple-itwin-settings-containers", {
|
|
75
76
|
message: `Multiple iTwin settings containers were found for '${iTwinId}', so a container cannot be automatically selected.`,
|
|
@@ -91,7 +92,8 @@ var SettingsContainers;
|
|
|
91
92
|
if (undefined === BlobContainerService_1.BlobContainer.service)
|
|
92
93
|
core_common_1.ITwinSettingsError.throwError("blob-service-unavailable", { message: "BlobContainer.service is not available." });
|
|
93
94
|
const userToken = await IModelHost_1.IModelHost.getAccessToken();
|
|
94
|
-
const containers = await queryContainers({ iTwinId, includeParentITwins: { filter: "accountOnly" } })
|
|
95
|
+
const containers = (await queryContainers({ iTwinId, includeParentITwins: { filter: "accountOnly" } }))
|
|
96
|
+
.filter((container) => undefined === container.iModelId);
|
|
95
97
|
if (containers.length === 0)
|
|
96
98
|
return undefined;
|
|
97
99
|
const seenITwins = new Set();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsEditor.js","sourceRoot":"","sources":["../../../src/workspace/SettingsEditor.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 { ITwinSettingsError } from \"@itwin/core-common\";\r\nimport { GuidString } from \"@itwin/core-bentley\";\r\nimport { WorkspaceContainerId, WorkspaceDbSettingsProps } from \"./Workspace\";\r\nimport { BlobContainer } from \"../BlobContainerService\";\r\nimport { IModelHost } from \"../IModelHost\";\r\nimport { constructSettingsEditorForITwin, getSettingsEditorForITwin } from \"../internal/workspace/SettingsEditorImpl\";\r\nimport { EditableWorkspaceContainer, WorkspaceEditor } from \"./WorkspaceEditor\";\r\nimport { SettingsPriority } from \"./Settings\";\r\nimport { settingsWorkspaceDbName } from \"./SettingsDb\";\r\n\r\n/** The default resource name used to store settings in a [[WorkspaceDb]].\r\n * This is the key under which all settings are stored in the SQLite `strings` table.\r\n * When loading settings at runtime via [[Workspace.loadSettingsDictionary]], the `resourceName` defaults\r\n * to this value, ensuring the read and write paths always agree on which key to use.\r\n * @internal\r\n */\r\nexport const settingsResourceName = \"settingsDictionary\";\r\n\r\n/** @internal */\r\nexport namespace SettingsEditor {\r\n /** The type of workspace container used to store settings. */\r\n export const containerType = \"settings\";\r\n\r\n /**\r\n * Create a new [[SettingsEditor]] for creating new versions of [[SettingsDb]]s.\r\n * @note The caller becomes the owner of the SettingsEditor and is responsible for calling [[SettingsEditor.close]] on it when finished.\r\n * @note It is illegal to have more than one SettingsEditor active in a single session.\r\n */\r\n export async function constructForITwin(iTwinId: GuidString): Promise<{ editor: WorkspaceEditor; container: EditableWorkspaceContainer }> {\r\n return constructSettingsEditorForITwin(iTwinId);\r\n }\r\n\r\n /**\r\n * Obtain a [[SettingsEditor]] for the existing settings container associated with an iTwin.\r\n * @returns The editor and container, or `undefined` if no settings container exists for the iTwin.\r\n * @note The caller becomes the owner of the SettingsEditor and is responsible for calling [[SettingsEditor.close]] on it when finished.\r\n * @note It is illegal to have more than one SettingsEditor active in a single session.\r\n */\r\n export async function getForITwin(iTwinId: GuidString): Promise<{ editor: WorkspaceEditor; container: EditableWorkspaceContainer } | undefined> {\r\n return getSettingsEditorForITwin(iTwinId);\r\n }\r\n}\r\n\r\n/**\r\n * Help locate and obtain access to known containers with type \"settings\".\r\n * @internal\r\n */\r\nexport namespace SettingsContainers {\r\n /**\r\n * Query the [[BlobContainer]] service for all settings containers associated with a given iTwin.\r\n * Automatically filters by `containerType: \"settings\"`.\r\n * @note Requires [[IModelHost.authorizationClient]] to be configured.\r\n */\r\n async function queryContainers(args: BlobContainer.QueryContainerProps): Promise<BlobContainer.MetadataResponse[]> {\r\n if (undefined === BlobContainer.service)\r\n ITwinSettingsError.throwError(\"blob-service-unavailable\", { message: \"BlobContainer.service is not available.\" });\r\n\r\n const userToken = await IModelHost.getAccessToken();\r\n return BlobContainer.service.queryContainersMetadata(userToken, { ...args, containerType: SettingsEditor.containerType });\r\n }\r\n\r\n /**\r\n * Query the [[BlobContainer]] service for the single settings container associated with a given iTwin.\r\n * @returns The containerId, or `undefined` if no container exists.\r\n * @throws if more than one settings container is found.\r\n */\r\n export async function getITwinContainerId(iTwinId: GuidString): Promise<WorkspaceContainerId | undefined> {\r\n const containers = await queryContainers({ iTwinId });\r\n if (containers.length > 1) {\r\n ITwinSettingsError.throwError(\"multiple-itwin-settings-containers\", {\r\n message: `Multiple iTwin settings containers were found for '${iTwinId}', so a container cannot be automatically selected.`,\r\n iTwinId,\r\n });\r\n }\r\n return containers[0]?.containerId;\r\n }\r\n\r\n /**\r\n * Look up settings containers for an iTwin and its account iTwin and obtain read-only access tokens.\r\n * @returns Container props needed by [[IModelHost.getITwinWorkspace]]. The requested iTwin's settings\r\n * container is returned at [[SettingsPriority.iTwin]]; the account iTwin container is returned at\r\n * [[SettingsPriority.organization]].\r\n * @note Requires [[IModelHost.authorizationClient]] to be configured.\r\n * @note Requires [[BlobContainer.service]] to be configured.\r\n */\r\n export async function getITwinSettingsSources(iTwinId: GuidString): Promise<WorkspaceDbSettingsProps[] | undefined> {\r\n if (undefined === BlobContainer.service)\r\n ITwinSettingsError.throwError(\"blob-service-unavailable\", { message: \"BlobContainer.service is not available.\" });\r\n\r\n const userToken = await IModelHost.getAccessToken();\r\n const containers = await queryContainers({ iTwinId, includeParentITwins: { filter: \"accountOnly\" } });\r\n if (containers.length === 0) return undefined;\r\n\r\n const seenITwins = new Set<string>();\r\n const results: WorkspaceDbSettingsProps[] = [];\r\n for (const container of containers) {\r\n const ownerITwinId = container.iTwinId;\r\n if (undefined === ownerITwinId) {\r\n ITwinSettingsError.throwError(\"missing-container-itwinid\", {\r\n message: `Settings container '${container.containerId}' has no iTwinId. Please upgrade to a newer version of the BlobContainer service that populates iTwinId in query results.`,\r\n iTwinId,\r\n });\r\n }\r\n if (seenITwins.has(ownerITwinId)) {\r\n ITwinSettingsError.throwError(\"multiple-itwin-settings-containers\", {\r\n message: `Multiple iTwin settings containers were found for '${ownerITwinId}', so a container cannot be automatically selected.`,\r\n iTwinId: ownerITwinId,\r\n });\r\n }\r\n seenITwins.add(ownerITwinId);\r\n\r\n const priority = container.accountITwinId === ownerITwinId ? SettingsPriority.organization : SettingsPriority.iTwin;\r\n const tokenProps = await BlobContainer.service.requestToken({ containerId: container.containerId, accessLevel: \"read\", userToken });\r\n results.push({\r\n baseUri: tokenProps.baseUri,\r\n containerId: container.containerId,\r\n storageType: tokenProps.provider,\r\n accessToken: tokenProps.token,\r\n priority,\r\n dbName: settingsWorkspaceDbName,\r\n includePrerelease: true,\r\n });\r\n }\r\n\r\n return results;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"SettingsEditor.js","sourceRoot":"","sources":["../../../src/workspace/SettingsEditor.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 { ITwinSettingsError } from \"@itwin/core-common\";\r\nimport { GuidString } from \"@itwin/core-bentley\";\r\nimport { WorkspaceContainerId, WorkspaceDbSettingsProps } from \"./Workspace\";\r\nimport { BlobContainer } from \"../BlobContainerService\";\r\nimport { IModelHost } from \"../IModelHost\";\r\nimport { constructSettingsEditorForITwin, getSettingsEditorForITwin } from \"../internal/workspace/SettingsEditorImpl\";\r\nimport { EditableWorkspaceContainer, WorkspaceEditor } from \"./WorkspaceEditor\";\r\nimport { SettingsPriority } from \"./Settings\";\r\nimport { settingsWorkspaceDbName } from \"./SettingsDb\";\r\n\r\n/** The default resource name used to store settings in a [[WorkspaceDb]].\r\n * This is the key under which all settings are stored in the SQLite `strings` table.\r\n * When loading settings at runtime via [[Workspace.loadSettingsDictionary]], the `resourceName` defaults\r\n * to this value, ensuring the read and write paths always agree on which key to use.\r\n * @internal\r\n */\r\nexport const settingsResourceName = \"settingsDictionary\";\r\n\r\n/** @internal */\r\nexport namespace SettingsEditor {\r\n /** The type of workspace container used to store settings. */\r\n export const containerType = \"settings\";\r\n\r\n /**\r\n * Create a new [[SettingsEditor]] for creating new versions of [[SettingsDb]]s.\r\n * @note The caller becomes the owner of the SettingsEditor and is responsible for calling [[SettingsEditor.close]] on it when finished.\r\n * @note It is illegal to have more than one SettingsEditor active in a single session.\r\n */\r\n export async function constructForITwin(iTwinId: GuidString): Promise<{ editor: WorkspaceEditor; container: EditableWorkspaceContainer }> {\r\n return constructSettingsEditorForITwin(iTwinId);\r\n }\r\n\r\n /**\r\n * Obtain a [[SettingsEditor]] for the existing settings container associated with an iTwin.\r\n * @returns The editor and container, or `undefined` if no settings container exists for the iTwin.\r\n * @note The caller becomes the owner of the SettingsEditor and is responsible for calling [[SettingsEditor.close]] on it when finished.\r\n * @note It is illegal to have more than one SettingsEditor active in a single session.\r\n */\r\n export async function getForITwin(iTwinId: GuidString): Promise<{ editor: WorkspaceEditor; container: EditableWorkspaceContainer } | undefined> {\r\n return getSettingsEditorForITwin(iTwinId);\r\n }\r\n}\r\n\r\n/**\r\n * Help locate and obtain access to known containers with type \"settings\".\r\n * @internal\r\n */\r\nexport namespace SettingsContainers {\r\n /**\r\n * Query the [[BlobContainer]] service for all settings containers associated with a given iTwin.\r\n * Automatically filters by `containerType: \"settings\"`.\r\n * @note Requires [[IModelHost.authorizationClient]] to be configured.\r\n */\r\n async function queryContainers(args: BlobContainer.QueryContainerProps): Promise<BlobContainer.MetadataResponse[]> {\r\n if (undefined === BlobContainer.service)\r\n ITwinSettingsError.throwError(\"blob-service-unavailable\", { message: \"BlobContainer.service is not available.\" });\r\n\r\n const userToken = await IModelHost.getAccessToken();\r\n return BlobContainer.service.queryContainersMetadata(userToken, { ...args, containerType: SettingsEditor.containerType });\r\n }\r\n\r\n /**\r\n * Query the [[BlobContainer]] service for the iTwin-root settings container associated with a given iTwin.\r\n * Only containers without an iModelId in their query metadata are considered.\r\n * @returns The containerId, or `undefined` if no matching container is found.\r\n * @throws if more than one matching container is found.\r\n */\r\n export async function getITwinContainerId(iTwinId: GuidString): Promise<WorkspaceContainerId | undefined> {\r\n const containers = (await queryContainers({ iTwinId })).filter((container) => undefined === container.iModelId);\r\n if (containers.length > 1) {\r\n ITwinSettingsError.throwError(\"multiple-itwin-settings-containers\", {\r\n message: `Multiple iTwin settings containers were found for '${iTwinId}', so a container cannot be automatically selected.`,\r\n iTwinId,\r\n });\r\n }\r\n return containers[0]?.containerId;\r\n }\r\n\r\n /**\r\n * Look up settings containers for an iTwin and its account iTwin and obtain read-only access tokens.\r\n * @returns Container props needed by [[IModelHost.getITwinWorkspace]]. The requested iTwin's settings\r\n * container is returned at [[SettingsPriority.iTwin]]; the account iTwin container is returned at\r\n * [[SettingsPriority.organization]].\r\n * @note Requires [[IModelHost.authorizationClient]] to be configured.\r\n * @note Requires [[BlobContainer.service]] to be configured.\r\n */\r\n export async function getITwinSettingsSources(iTwinId: GuidString): Promise<WorkspaceDbSettingsProps[] | undefined> {\r\n if (undefined === BlobContainer.service)\r\n ITwinSettingsError.throwError(\"blob-service-unavailable\", { message: \"BlobContainer.service is not available.\" });\r\n\r\n const userToken = await IModelHost.getAccessToken();\r\n const containers = (await queryContainers({ iTwinId, includeParentITwins: { filter: \"accountOnly\" } }))\r\n .filter((container) => undefined === container.iModelId);\r\n if (containers.length === 0) return undefined;\r\n\r\n const seenITwins = new Set<string>();\r\n const results: WorkspaceDbSettingsProps[] = [];\r\n for (const container of containers) {\r\n const ownerITwinId = container.iTwinId;\r\n if (undefined === ownerITwinId) {\r\n ITwinSettingsError.throwError(\"missing-container-itwinid\", {\r\n message: `Settings container '${container.containerId}' has no iTwinId. Please upgrade to a newer version of the BlobContainer service that populates iTwinId in query results.`,\r\n iTwinId,\r\n });\r\n }\r\n if (seenITwins.has(ownerITwinId)) {\r\n ITwinSettingsError.throwError(\"multiple-itwin-settings-containers\", {\r\n message: `Multiple iTwin settings containers were found for '${ownerITwinId}', so a container cannot be automatically selected.`,\r\n iTwinId: ownerITwinId,\r\n });\r\n }\r\n seenITwins.add(ownerITwinId);\r\n\r\n const priority = container.accountITwinId === ownerITwinId ? SettingsPriority.organization : SettingsPriority.iTwin;\r\n const tokenProps = await BlobContainer.service.requestToken({ containerId: container.containerId, accessLevel: \"read\", userToken });\r\n results.push({\r\n baseUri: tokenProps.baseUri,\r\n containerId: container.containerId,\r\n storageType: tokenProps.provider,\r\n accessToken: tokenProps.token,\r\n priority,\r\n dbName: settingsWorkspaceDbName,\r\n includePrerelease: true,\r\n });\r\n }\r\n\r\n return results;\r\n }\r\n}\r\n"]}
|
|
@@ -60,6 +60,8 @@ export declare namespace BlobContainer {
|
|
|
60
60
|
containerId: string;
|
|
61
61
|
/** The iTwinId that owns this container. */
|
|
62
62
|
iTwinId?: GuidString;
|
|
63
|
+
/** The iModelId that owns this container. */
|
|
64
|
+
iModelId?: GuidString;
|
|
63
65
|
/** The account iTwinId of the owning iTwin. */
|
|
64
66
|
accountITwinId?: GuidString;
|
|
65
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlobContainerService.d.ts","sourceRoot":"","sources":["../../src/BlobContainerService.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BlobContainerService.d.ts","sourceRoot":"","sources":["../../src/BlobContainerService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlobContainerService.js","sourceRoot":"","sources":["../../src/BlobContainerService.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAOH;;;GAGG;AACH,MAAM,KAAW,aAAa,
|
|
1
|
+
{"version":3,"file":"BlobContainerService.js","sourceRoot":"","sources":["../../src/BlobContainerService.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAOH;;;GAGG;AACH,MAAM,KAAW,aAAa,CAwL7B;AAxLD,WAAiB,aAAa;AAwL9B,CAAC,EAxLgB,aAAa,KAAb,aAAa,QAwL7B","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 BlobContainers\r\n */\r\n\r\n// spell:ignore datacenter\r\n\r\nimport { AccessToken, GuidString, Id64String } from \"@itwin/core-bentley\";\r\nimport { SettingsContainer } from \"./workspace/Settings\";\r\n\r\n/**\r\n * Types and functions for creating, deleting and authorizing access to cloud-based blob containers for an iTwin.\r\n * @beta\r\n */\r\nexport namespace BlobContainer {\r\n\r\n /** Object that implements the methods to create, delete, and request access to a container. */\r\n export let service: BlobContainer.ContainerService | undefined;\r\n\r\n /** name of cloud provider for a container. */\r\n export type Provider = \"azure\" | \"google\";\r\n\r\n /** the name of the container within its `Scope` */\r\n export type ContainerId = string;\r\n\r\n /** token that authenticates a user. This token is required to obtain a `ContainerToken`. */\r\n export type UserToken = AccessToken;\r\n\r\n /** token that authenticates access to a container for either read or write. */\r\n export type ContainerToken = AccessToken;\r\n\r\n /**\r\n * The scope for a container. This determines:\r\n * - the \"owner\" organization, including the contract that governs its legal and commercial terms and obligations\r\n * - the administrators who may configure RBAC permissions\r\n * - the datacenter for the container. Every container resides in a datacenter as determined by the iTwinId. This\r\n * determines the region for data residency requirements.\r\n * - the lifecycle constraints for the container. No container can outlive its iTwin or its iModel (if defined). That is,\r\n * when the iTwin/iModel is deleted (either explicitly or due to contract expiration), the container is also deleted.\r\n */\r\n export interface Scope {\r\n /** iTwinId of the owner of this container. */\r\n iTwinId: Id64String;\r\n /** optionally, an iModelId within the iTwin. If present, container is deleted when the iModel is deleted. */\r\n iModelId?: Id64String;\r\n /** the user GUID an individual, if this container is private. */\r\n ownerGuid?: GuidString;\r\n }\r\n\r\n /**\r\n * Metadata about the use of a container so that:\r\n * - administrators can understand why a container exists for assigning RBAC permissions appropriately\r\n * - usage reports can aggregate types of containers\r\n * - applications can identify their containers\r\n * - applications can store properties about their containers\r\n */\r\n export interface Metadata {\r\n /** The machine-readable string that describes what the container is being used for (e.g. \"workspace\"). Always lowercase and singular. */\r\n containerType: string;\r\n /** Human-readable name for the container. This will be displayed in the administrator RBAC panel, and on usage reports. Not required to be unique.*/\r\n label: string;\r\n /** Optional human-readable explanation of the information held in the container. This will be displayed in the administrator RBAC panel, and on usage reports. */\r\n description?: string;\r\n /** optional properties for the container */\r\n json?: SettingsContainer;\r\n }\r\n\r\n /**\r\n * Properties returned by queryContainersMetadata\r\n */\r\n export interface MetadataResponse extends Metadata {\r\n /** The id of the container. */\r\n containerId: string;\r\n /** The iTwinId that owns this container. */\r\n iTwinId?: GuidString;\r\n /** The iModelId that owns this container. */\r\n iModelId?: GuidString;\r\n /** The account iTwinId of the owning iTwin. */\r\n accountITwinId?: GuidString;\r\n }\r\n\r\n /** Properties returned by `Service.requestToken` */\r\n export interface TokenProps {\r\n /**\r\n * Expiring token that provides the requested access to the container. Should be used in all subsequent requests for blobs within the container,\r\n * and must be refreshed before it expires\r\n */\r\n token: ContainerToken;\r\n /** Scope of the container. */\r\n scope: Scope;\r\n /** Name of the blob storage provider. */\r\n provider: Provider;\r\n /** Time at which the token will expire. The token should be refreshed (that is, a new token should be requested) before this time. */\r\n expiration: Date;\r\n /** Metadata of the container. */\r\n metadata: Metadata;\r\n /** Base URI of the storage account that hosts the container */\r\n baseUri: string;\r\n }\r\n\r\n /** The URI and Id of the container. */\r\n export interface UriAndId {\r\n baseUri: string;\r\n containerId: ContainerId;\r\n }\r\n\r\n /** Information required to access an existing container. */\r\n export interface AccessContainerProps extends UriAndId {\r\n userToken: UserToken;\r\n }\r\n\r\n /** Information about a newly created container. */\r\n export interface CreatedContainerProps extends UriAndId {\r\n /** name of the blob storage provider. */\r\n provider: Provider;\r\n }\r\n\r\n /**\r\n * Access level to request for token.\r\n * - `\"write\"`: request a writeable AccessToken.\r\n * - `\"read\"`: request a read-only AccessToken.\r\n * - `\"admin\"`: request a admin AccessToken.\r\n * - `\"writeIfPossible\"`: first request a writeable AccessToken. If the user is not authorized for write, request a read-only AccessToken.\r\n * If the user is not authorized for the level requested, an exception is thrown.\r\n */\r\n export type RequestAccessLevel = \"write\" | \"read\" | \"admin\" | \"writeIfPossible\";\r\n\r\n /** Information required to request an access token for a container. */\r\n export interface RequestTokenProps extends Omit<AccessContainerProps, \"baseUri\"> {\r\n /** the level of access requested. If not specified, defaults to `\"writeIfPossible\"`. */\r\n accessLevel?: RequestAccessLevel;\r\n /** the number of seconds before the token should expire.\r\n * @note A maximum duration is determined by the service. If no value is supplied, or the value is larger than the maximum, the maximum duration is used.\r\n */\r\n durationSeconds?: number;\r\n }\r\n\r\n /** Information required to create a new container. */\r\n export interface CreateNewContainerProps {\r\n /** the scope of the new container */\r\n scope: Scope;\r\n /** metadata to be stored on the new container */\r\n metadata: Metadata;\r\n /** The user's access token. The user must be authorized with \"create container\" RBAC role for the iTwin. */\r\n userToken: UserToken;\r\n /**\r\n * the id for the container. Useful for tests.\r\n * @internal\r\n */\r\n containerId?: ContainerId;\r\n }\r\n\r\n /**\r\n * Query Parameters for querying containers\r\n */\r\n export interface QueryContainerProps {\r\n /** the iTwinId of the containers to query */\r\n iTwinId: GuidString;\r\n /** optional iModelId of the containers to query */\r\n iModelId?: GuidString;\r\n /** optional containerType of the containers to query */\r\n containerType?: GuidString;\r\n /** optional label of the containers to query */\r\n label?: GuidString;\r\n /** Whether to include parent iTwins in the query. Pass `true` to traverse the full parent chain, or `{ filter: \"accountOnly\" }` to include only the account iTwin. Defaults to `false`. */\r\n includeParentITwins?: boolean | { filter: \"accountOnly\" };\r\n }\r\n\r\n /** Methods to create, delete, and access blob containers. */\r\n export interface ContainerService {\r\n /** Create a new blob container. Throws on failure (e.g. access denied or container already exists.) */\r\n create(props: CreateNewContainerProps): Promise<CreatedContainerProps>;\r\n\r\n /**\r\n * Delete an existing blob container.\r\n * @note This method requires that the user be authorized with \"delete container\" RBAC role for the iTwin.\r\n */\r\n delete(container: AccessContainerProps): Promise<void>;\r\n\r\n /** query the Scope for a container */\r\n queryScope(container: AccessContainerProps): Promise<Scope>;\r\n\r\n /** query the Metadata for a specific container */\r\n queryMetadata(container: AccessContainerProps): Promise<Metadata>;\r\n\r\n /** Returns all containers and their metadata associated with a given iTwinId.\r\n * Pass `includeParentITwins: { filter: \"accountOnly\" }` to also include the account iTwin container,\r\n * without traversing any higher parent chain.\r\n * Results can be further queried by label and containerType.\r\n */\r\n queryContainersMetadata(userToken: UserToken, args: QueryContainerProps): Promise<MetadataResponse[]>;\r\n\r\n /** update the json properties of this container */\r\n updateJson(container: AccessContainerProps, json: SettingsContainer): Promise<void>;\r\n\r\n /** Request a `ContainerToken` for a container. Throws on failure. */\r\n requestToken(props: RequestTokenProps): Promise<TokenProps>;\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaViewPropertyOverrides.test.d.ts","sourceRoot":"","sources":["../../../../src/test/schema/SchemaViewPropertyOverrides.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { IModelHost, SnapshotDb } from "../../core-backend";
|
|
6
|
+
import { expect } from "chai";
|
|
7
|
+
import { IModelTestUtils } from "../IModelTestUtils";
|
|
8
|
+
import { TestUtils } from "../TestUtils";
|
|
9
|
+
/**
|
|
10
|
+
* Tests how SchemaView resolves metadata of property overrides: category, KindOfQuantity and hidden flags
|
|
11
|
+
* come from the overridden property when the override does not define them, priority stays local.
|
|
12
|
+
* Also covers which declaration a class gets when mixins override properties of other mixins.
|
|
13
|
+
*/
|
|
14
|
+
describe("SchemaView property overrides", () => {
|
|
15
|
+
const zooSchema = `<?xml version="1.0" encoding="UTF-8"?>
|
|
16
|
+
<ECSchema schemaName="Zoo" alias="zoo" version="01.00.00" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.3.2">
|
|
17
|
+
<ECSchemaReference name="BisCore" version="01.00.00" alias="bis"/>
|
|
18
|
+
<ECSchemaReference name="CoreCustomAttributes" version="01.00.03" alias="CoreCA"/>
|
|
19
|
+
<ECSchemaReference name="Units" version="01.00.09" alias="u"/>
|
|
20
|
+
<ECSchemaReference name="Formats" version="01.00.00" alias="f"/>
|
|
21
|
+
|
|
22
|
+
<PropertyCategory typeName="Identity" priority="100"/>
|
|
23
|
+
<PropertyCategory typeName="Nicknames" priority="50"/>
|
|
24
|
+
<PropertyCategory typeName="Skills" priority="40"/>
|
|
25
|
+
<PropertyCategory typeName="Anatomy" priority="30"/>
|
|
26
|
+
<PropertyCategory typeName="Flight" priority="20"/>
|
|
27
|
+
|
|
28
|
+
<KindOfQuantity typeName="BodyMass" persistenceUnit="u:KG" relativeError="0.01" presentationUnits="f:DefaultRealU(2)[u:KG]"/>
|
|
29
|
+
<KindOfQuantity typeName="PreciseBodyMass" persistenceUnit="u:KG" relativeError="0.0001" presentationUnits="f:DefaultRealU(4)[u:KG]"/>
|
|
30
|
+
|
|
31
|
+
<ECEntityClass typeName="Animal" modifier="Abstract">
|
|
32
|
+
<BaseClass>bis:PhysicalElement</BaseClass>
|
|
33
|
+
<ECProperty propertyName="Nickname" typeName="string" category="Identity" priority="5"/>
|
|
34
|
+
<ECProperty propertyName="Weight" typeName="double" kindOfQuantity="BodyMass"/>
|
|
35
|
+
<ECArrayProperty propertyName="DailyWeights" typeName="double" kindOfQuantity="BodyMass" minOccurs="0" maxOccurs="unbounded"/>
|
|
36
|
+
<ECProperty propertyName="FavoriteSnack" typeName="string"/>
|
|
37
|
+
<ECProperty propertyName="Secret" typeName="string">
|
|
38
|
+
<ECCustomAttributes>
|
|
39
|
+
<HiddenProperty xmlns="CoreCustomAttributes.01.00.03"/>
|
|
40
|
+
</ECCustomAttributes>
|
|
41
|
+
</ECProperty>
|
|
42
|
+
<ECProperty propertyName="Mood" typeName="string">
|
|
43
|
+
<ECCustomAttributes>
|
|
44
|
+
<HiddenProperty xmlns="CoreCustomAttributes.01.00.03"/>
|
|
45
|
+
</ECCustomAttributes>
|
|
46
|
+
</ECProperty>
|
|
47
|
+
</ECEntityClass>
|
|
48
|
+
|
|
49
|
+
<ECEntityClass typeName="Mammal" modifier="Abstract">
|
|
50
|
+
<BaseClass>Animal</BaseClass>
|
|
51
|
+
<ECProperty propertyName="Nickname" typeName="string" displayLabel="Mammal Nickname"/>
|
|
52
|
+
<ECProperty propertyName="Weight" typeName="double" displayLabel="Mammal Weight"/>
|
|
53
|
+
<ECArrayProperty propertyName="DailyWeights" typeName="double" displayLabel="Mammal Daily Weights" minOccurs="0" maxOccurs="unbounded"/>
|
|
54
|
+
<ECProperty propertyName="FavoriteSnack" typeName="string" displayLabel="Mammal Snack"/>
|
|
55
|
+
<ECProperty propertyName="Secret" typeName="string" displayLabel="Mammal Secret"/>
|
|
56
|
+
<ECProperty propertyName="Mood" typeName="string">
|
|
57
|
+
<ECCustomAttributes>
|
|
58
|
+
<HiddenProperty xmlns="CoreCustomAttributes.01.00.03">
|
|
59
|
+
<Show>true</Show>
|
|
60
|
+
</HiddenProperty>
|
|
61
|
+
</ECCustomAttributes>
|
|
62
|
+
</ECProperty>
|
|
63
|
+
</ECEntityClass>
|
|
64
|
+
|
|
65
|
+
<ECEntityClass typeName="Cat" modifier="Sealed">
|
|
66
|
+
<BaseClass>Mammal</BaseClass>
|
|
67
|
+
<ECProperty propertyName="Nickname" typeName="string" displayLabel="Cat Nickname"/>
|
|
68
|
+
</ECEntityClass>
|
|
69
|
+
|
|
70
|
+
<ECEntityClass typeName="Dog" modifier="Sealed">
|
|
71
|
+
<BaseClass>Mammal</BaseClass>
|
|
72
|
+
<ECProperty propertyName="Nickname" typeName="string" category="Nicknames" priority="0"/>
|
|
73
|
+
<ECProperty propertyName="Weight" typeName="double" kindOfQuantity="PreciseBodyMass"/>
|
|
74
|
+
</ECEntityClass>
|
|
75
|
+
|
|
76
|
+
<ECEntityClass typeName="ITalker" modifier="Abstract">
|
|
77
|
+
<ECCustomAttributes>
|
|
78
|
+
<IsMixin xmlns="CoreCustomAttributes.01.00.03">
|
|
79
|
+
<AppliesToEntityClass>bis:PhysicalElement</AppliesToEntityClass>
|
|
80
|
+
</IsMixin>
|
|
81
|
+
</ECCustomAttributes>
|
|
82
|
+
<ECProperty propertyName="Vocabulary" typeName="string" category="Skills"/>
|
|
83
|
+
</ECEntityClass>
|
|
84
|
+
|
|
85
|
+
<ECEntityClass typeName="Parrot" modifier="Sealed">
|
|
86
|
+
<BaseClass>Animal</BaseClass>
|
|
87
|
+
<BaseClass>ITalker</BaseClass>
|
|
88
|
+
<ECProperty propertyName="Vocabulary" typeName="string" displayLabel="Parrot Vocabulary"/>
|
|
89
|
+
</ECEntityClass>
|
|
90
|
+
|
|
91
|
+
<ECEntityClass typeName="IFlyer" modifier="Abstract">
|
|
92
|
+
<ECCustomAttributes>
|
|
93
|
+
<IsMixin xmlns="CoreCustomAttributes.01.00.03">
|
|
94
|
+
<AppliesToEntityClass>bis:PhysicalElement</AppliesToEntityClass>
|
|
95
|
+
</IsMixin>
|
|
96
|
+
</ECCustomAttributes>
|
|
97
|
+
<ECProperty propertyName="WingSpan" typeName="double" category="Anatomy"/>
|
|
98
|
+
<ECProperty propertyName="FlightSpeed" typeName="double" category="Flight"/>
|
|
99
|
+
</ECEntityClass>
|
|
100
|
+
|
|
101
|
+
<ECEntityClass typeName="ISoarer" modifier="Abstract">
|
|
102
|
+
<BaseClass>IFlyer</BaseClass>
|
|
103
|
+
<ECCustomAttributes>
|
|
104
|
+
<IsMixin xmlns="CoreCustomAttributes.01.00.03">
|
|
105
|
+
<AppliesToEntityClass>bis:PhysicalElement</AppliesToEntityClass>
|
|
106
|
+
</IsMixin>
|
|
107
|
+
</ECCustomAttributes>
|
|
108
|
+
<ECProperty propertyName="WingSpan" typeName="double" displayLabel="Soaring Wing Span" category="Flight"/>
|
|
109
|
+
<ECProperty propertyName="FlightSpeed" typeName="double" displayLabel="Soaring Speed"/>
|
|
110
|
+
</ECEntityClass>
|
|
111
|
+
|
|
112
|
+
<ECEntityClass typeName="Eagle" modifier="Sealed">
|
|
113
|
+
<BaseClass>Animal</BaseClass>
|
|
114
|
+
<BaseClass>ISoarer</BaseClass>
|
|
115
|
+
</ECEntityClass>
|
|
116
|
+
</ECSchema>`;
|
|
117
|
+
let iModel;
|
|
118
|
+
let view;
|
|
119
|
+
before(async () => {
|
|
120
|
+
if (!IModelHost.isValid)
|
|
121
|
+
await TestUtils.startBackend();
|
|
122
|
+
const testFileName = IModelTestUtils.prepareOutputFile("SchemaViewPropertyOverrides", "Zoo.bim");
|
|
123
|
+
iModel = SnapshotDb.createEmpty(testFileName, { rootSubject: { name: "SchemaViewPropertyOverrides" } });
|
|
124
|
+
await iModel.importSchemaStrings([zooSchema]);
|
|
125
|
+
view = await iModel.getSchemaView();
|
|
126
|
+
});
|
|
127
|
+
after(() => {
|
|
128
|
+
if (iModel?.isOpen)
|
|
129
|
+
iModel.close();
|
|
130
|
+
});
|
|
131
|
+
function getProperty(className, propertyName) {
|
|
132
|
+
const ecClass = view.findClass(`Zoo:${className}`);
|
|
133
|
+
expect(ecClass, `class ${className}`).to.not.be.undefined;
|
|
134
|
+
const property = ecClass.getProperty(propertyName);
|
|
135
|
+
expect(property, `property ${className}.${propertyName}`).to.not.be.undefined;
|
|
136
|
+
return property;
|
|
137
|
+
}
|
|
138
|
+
function getKindOfQuantityName(className, propertyName) {
|
|
139
|
+
const property = getProperty(className, propertyName);
|
|
140
|
+
if (!property.isPrimitive())
|
|
141
|
+
throw new Error(`${className}.${propertyName} is not primitive`);
|
|
142
|
+
return property.kindOfQuantity?.name;
|
|
143
|
+
}
|
|
144
|
+
describe("category", () => {
|
|
145
|
+
it("returns the local category", () => {
|
|
146
|
+
expect(getProperty("Animal", "Nickname").category?.name).to.equal("Identity");
|
|
147
|
+
});
|
|
148
|
+
it("takes the category from the overridden property", () => {
|
|
149
|
+
const property = getProperty("Mammal", "Nickname");
|
|
150
|
+
expect(property.declaringClass?.name).to.equal("Mammal");
|
|
151
|
+
expect(property.label).to.equal("Mammal Nickname");
|
|
152
|
+
expect(property.category?.name).to.equal("Identity");
|
|
153
|
+
});
|
|
154
|
+
it("takes the category through multiple overrides", () => {
|
|
155
|
+
const property = getProperty("Cat", "Nickname");
|
|
156
|
+
expect(property.declaringClass?.name).to.equal("Cat");
|
|
157
|
+
expect(property.label).to.equal("Cat Nickname");
|
|
158
|
+
expect(property.category?.name).to.equal("Identity");
|
|
159
|
+
});
|
|
160
|
+
it("prefers the local category over the overridden one", () => {
|
|
161
|
+
expect(getProperty("Dog", "Nickname").category?.name).to.equal("Nicknames");
|
|
162
|
+
});
|
|
163
|
+
it("returns undefined if no declaration has a category", () => {
|
|
164
|
+
expect(getProperty("Cat", "FavoriteSnack").category).to.be.undefined;
|
|
165
|
+
});
|
|
166
|
+
it("returns the category of an inherited property that is not overridden", () => {
|
|
167
|
+
const property = getProperty("Eagle", "Nickname");
|
|
168
|
+
expect(property.declaringClass?.name).to.equal("Animal");
|
|
169
|
+
expect(property.category?.name).to.equal("Identity");
|
|
170
|
+
});
|
|
171
|
+
it("takes the category from an overridden mixin property", () => {
|
|
172
|
+
const property = getProperty("Parrot", "Vocabulary");
|
|
173
|
+
expect(property.declaringClass?.name).to.equal("Parrot");
|
|
174
|
+
expect(property.label).to.equal("Parrot Vocabulary");
|
|
175
|
+
expect(property.category?.name).to.equal("Skills");
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
describe("kindOfQuantity", () => {
|
|
179
|
+
it("returns the local KindOfQuantity", () => {
|
|
180
|
+
expect(getKindOfQuantityName("Animal", "Weight")).to.equal("BodyMass");
|
|
181
|
+
expect(getKindOfQuantityName("Dog", "Weight")).to.equal("PreciseBodyMass");
|
|
182
|
+
});
|
|
183
|
+
it("takes the KindOfQuantity from the overridden property", () => {
|
|
184
|
+
expect(getKindOfQuantityName("Mammal", "Weight")).to.equal("BodyMass");
|
|
185
|
+
expect(getKindOfQuantityName("Cat", "Weight")).to.equal("BodyMass");
|
|
186
|
+
});
|
|
187
|
+
it("takes the KindOfQuantity from the overridden primitive array property", () => {
|
|
188
|
+
const property = getProperty("Mammal", "DailyWeights");
|
|
189
|
+
expect(property.isArray()).to.be.true;
|
|
190
|
+
expect(getKindOfQuantityName("Mammal", "DailyWeights")).to.equal("BodyMass");
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
describe("hidden", () => {
|
|
194
|
+
it("hidden declaration is hidden", () => {
|
|
195
|
+
const property = getProperty("Animal", "Secret");
|
|
196
|
+
expect(property.isHidden).to.be.true;
|
|
197
|
+
expect(property.isEffectivelyHidden).to.be.true;
|
|
198
|
+
});
|
|
199
|
+
it("override without HiddenProperty is effectively hidden if the overridden property is hidden", () => {
|
|
200
|
+
const property = getProperty("Mammal", "Secret");
|
|
201
|
+
expect(property.isHidden).to.be.false;
|
|
202
|
+
expect(property.isEffectivelyHidden).to.be.true;
|
|
203
|
+
});
|
|
204
|
+
it("HiddenProperty(Show=true) on an override does not unhide a hidden overridden property", () => {
|
|
205
|
+
// Documented limitation: SchemaView cannot tell Show=true apart from no HiddenProperty.
|
|
206
|
+
const property = getProperty("Mammal", "Mood");
|
|
207
|
+
expect(property.isHidden).to.be.false;
|
|
208
|
+
expect(property.isEffectivelyHidden).to.be.true;
|
|
209
|
+
});
|
|
210
|
+
it("property without any HiddenProperty is not effectively hidden", () => {
|
|
211
|
+
expect(getProperty("Cat", "FavoriteSnack").isEffectivelyHidden).to.be.false;
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
describe("priority", () => {
|
|
215
|
+
it("is local to the declaration", () => {
|
|
216
|
+
expect(getProperty("Animal", "Nickname").priority).to.equal(5);
|
|
217
|
+
expect(getProperty("Mammal", "Nickname").priority).to.equal(0);
|
|
218
|
+
expect(getProperty("Dog", "Nickname").priority).to.equal(0);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
describe("mixin overriding a mixin", () => {
|
|
222
|
+
it("class gets the declaration of the derived mixin", () => {
|
|
223
|
+
const property = getProperty("Eagle", "WingSpan");
|
|
224
|
+
expect(property.declaringClass?.name).to.equal("ISoarer");
|
|
225
|
+
expect(property.label).to.equal("Soaring Wing Span");
|
|
226
|
+
expect(property.category?.name).to.equal("Flight");
|
|
227
|
+
});
|
|
228
|
+
it("derived mixin declaration takes the category from the base mixin", () => {
|
|
229
|
+
const property = getProperty("Eagle", "FlightSpeed");
|
|
230
|
+
expect(property.declaringClass?.name).to.equal("ISoarer");
|
|
231
|
+
expect(property.label).to.equal("Soaring Speed");
|
|
232
|
+
expect(property.category?.name).to.equal("Flight");
|
|
233
|
+
});
|
|
234
|
+
it("lists each property once", () => {
|
|
235
|
+
const names = view.findClass("Zoo:Eagle").getProperties().map((property) => property.name.toLowerCase());
|
|
236
|
+
expect(new Set(names).size).to.equal(names.length);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
//# sourceMappingURL=SchemaViewPropertyOverrides.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaViewPropertyOverrides.test.js","sourceRoot":"","sources":["../../../../src/test/schema/SchemaViewPropertyOverrides.test.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\r\nimport { IModelHost, SnapshotDb } from \"../../core-backend\";\r\nimport type { SchemaView } from \"@itwin/ecschema-metadata\";\r\nimport { expect } from \"chai\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\nimport { TestUtils } from \"../TestUtils\";\r\n\r\n/**\r\n * Tests how SchemaView resolves metadata of property overrides: category, KindOfQuantity and hidden flags\r\n * come from the overridden property when the override does not define them, priority stays local.\r\n * Also covers which declaration a class gets when mixins override properties of other mixins.\r\n */\r\ndescribe(\"SchemaView property overrides\", () => {\r\n const zooSchema = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n <ECSchema schemaName=\"Zoo\" alias=\"zoo\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECSchemaReference name=\"BisCore\" version=\"01.00.00\" alias=\"bis\"/>\r\n <ECSchemaReference name=\"CoreCustomAttributes\" version=\"01.00.03\" alias=\"CoreCA\"/>\r\n <ECSchemaReference name=\"Units\" version=\"01.00.09\" alias=\"u\"/>\r\n <ECSchemaReference name=\"Formats\" version=\"01.00.00\" alias=\"f\"/>\r\n\r\n <PropertyCategory typeName=\"Identity\" priority=\"100\"/>\r\n <PropertyCategory typeName=\"Nicknames\" priority=\"50\"/>\r\n <PropertyCategory typeName=\"Skills\" priority=\"40\"/>\r\n <PropertyCategory typeName=\"Anatomy\" priority=\"30\"/>\r\n <PropertyCategory typeName=\"Flight\" priority=\"20\"/>\r\n\r\n <KindOfQuantity typeName=\"BodyMass\" persistenceUnit=\"u:KG\" relativeError=\"0.01\" presentationUnits=\"f:DefaultRealU(2)[u:KG]\"/>\r\n <KindOfQuantity typeName=\"PreciseBodyMass\" persistenceUnit=\"u:KG\" relativeError=\"0.0001\" presentationUnits=\"f:DefaultRealU(4)[u:KG]\"/>\r\n\r\n <ECEntityClass typeName=\"Animal\" modifier=\"Abstract\">\r\n <BaseClass>bis:PhysicalElement</BaseClass>\r\n <ECProperty propertyName=\"Nickname\" typeName=\"string\" category=\"Identity\" priority=\"5\"/>\r\n <ECProperty propertyName=\"Weight\" typeName=\"double\" kindOfQuantity=\"BodyMass\"/>\r\n <ECArrayProperty propertyName=\"DailyWeights\" typeName=\"double\" kindOfQuantity=\"BodyMass\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\r\n <ECProperty propertyName=\"FavoriteSnack\" typeName=\"string\"/>\r\n <ECProperty propertyName=\"Secret\" typeName=\"string\">\r\n <ECCustomAttributes>\r\n <HiddenProperty xmlns=\"CoreCustomAttributes.01.00.03\"/>\r\n </ECCustomAttributes>\r\n </ECProperty>\r\n <ECProperty propertyName=\"Mood\" typeName=\"string\">\r\n <ECCustomAttributes>\r\n <HiddenProperty xmlns=\"CoreCustomAttributes.01.00.03\"/>\r\n </ECCustomAttributes>\r\n </ECProperty>\r\n </ECEntityClass>\r\n\r\n <ECEntityClass typeName=\"Mammal\" modifier=\"Abstract\">\r\n <BaseClass>Animal</BaseClass>\r\n <ECProperty propertyName=\"Nickname\" typeName=\"string\" displayLabel=\"Mammal Nickname\"/>\r\n <ECProperty propertyName=\"Weight\" typeName=\"double\" displayLabel=\"Mammal Weight\"/>\r\n <ECArrayProperty propertyName=\"DailyWeights\" typeName=\"double\" displayLabel=\"Mammal Daily Weights\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\r\n <ECProperty propertyName=\"FavoriteSnack\" typeName=\"string\" displayLabel=\"Mammal Snack\"/>\r\n <ECProperty propertyName=\"Secret\" typeName=\"string\" displayLabel=\"Mammal Secret\"/>\r\n <ECProperty propertyName=\"Mood\" typeName=\"string\">\r\n <ECCustomAttributes>\r\n <HiddenProperty xmlns=\"CoreCustomAttributes.01.00.03\">\r\n <Show>true</Show>\r\n </HiddenProperty>\r\n </ECCustomAttributes>\r\n </ECProperty>\r\n </ECEntityClass>\r\n\r\n <ECEntityClass typeName=\"Cat\" modifier=\"Sealed\">\r\n <BaseClass>Mammal</BaseClass>\r\n <ECProperty propertyName=\"Nickname\" typeName=\"string\" displayLabel=\"Cat Nickname\"/>\r\n </ECEntityClass>\r\n\r\n <ECEntityClass typeName=\"Dog\" modifier=\"Sealed\">\r\n <BaseClass>Mammal</BaseClass>\r\n <ECProperty propertyName=\"Nickname\" typeName=\"string\" category=\"Nicknames\" priority=\"0\"/>\r\n <ECProperty propertyName=\"Weight\" typeName=\"double\" kindOfQuantity=\"PreciseBodyMass\"/>\r\n </ECEntityClass>\r\n\r\n <ECEntityClass typeName=\"ITalker\" modifier=\"Abstract\">\r\n <ECCustomAttributes>\r\n <IsMixin xmlns=\"CoreCustomAttributes.01.00.03\">\r\n <AppliesToEntityClass>bis:PhysicalElement</AppliesToEntityClass>\r\n </IsMixin>\r\n </ECCustomAttributes>\r\n <ECProperty propertyName=\"Vocabulary\" typeName=\"string\" category=\"Skills\"/>\r\n </ECEntityClass>\r\n\r\n <ECEntityClass typeName=\"Parrot\" modifier=\"Sealed\">\r\n <BaseClass>Animal</BaseClass>\r\n <BaseClass>ITalker</BaseClass>\r\n <ECProperty propertyName=\"Vocabulary\" typeName=\"string\" displayLabel=\"Parrot Vocabulary\"/>\r\n </ECEntityClass>\r\n\r\n <ECEntityClass typeName=\"IFlyer\" modifier=\"Abstract\">\r\n <ECCustomAttributes>\r\n <IsMixin xmlns=\"CoreCustomAttributes.01.00.03\">\r\n <AppliesToEntityClass>bis:PhysicalElement</AppliesToEntityClass>\r\n </IsMixin>\r\n </ECCustomAttributes>\r\n <ECProperty propertyName=\"WingSpan\" typeName=\"double\" category=\"Anatomy\"/>\r\n <ECProperty propertyName=\"FlightSpeed\" typeName=\"double\" category=\"Flight\"/>\r\n </ECEntityClass>\r\n\r\n <ECEntityClass typeName=\"ISoarer\" modifier=\"Abstract\">\r\n <BaseClass>IFlyer</BaseClass>\r\n <ECCustomAttributes>\r\n <IsMixin xmlns=\"CoreCustomAttributes.01.00.03\">\r\n <AppliesToEntityClass>bis:PhysicalElement</AppliesToEntityClass>\r\n </IsMixin>\r\n </ECCustomAttributes>\r\n <ECProperty propertyName=\"WingSpan\" typeName=\"double\" displayLabel=\"Soaring Wing Span\" category=\"Flight\"/>\r\n <ECProperty propertyName=\"FlightSpeed\" typeName=\"double\" displayLabel=\"Soaring Speed\"/>\r\n </ECEntityClass>\r\n\r\n <ECEntityClass typeName=\"Eagle\" modifier=\"Sealed\">\r\n <BaseClass>Animal</BaseClass>\r\n <BaseClass>ISoarer</BaseClass>\r\n </ECEntityClass>\r\n </ECSchema>`;\r\n\r\n let iModel: SnapshotDb;\r\n let view: SchemaView;\r\n\r\n before(async () => {\r\n if (!IModelHost.isValid)\r\n await TestUtils.startBackend();\r\n\r\n const testFileName = IModelTestUtils.prepareOutputFile(\"SchemaViewPropertyOverrides\", \"Zoo.bim\");\r\n iModel = SnapshotDb.createEmpty(testFileName, { rootSubject: { name: \"SchemaViewPropertyOverrides\" } });\r\n await iModel.importSchemaStrings([zooSchema]);\r\n view = await iModel.getSchemaView();\r\n });\r\n\r\n after(() => {\r\n if (iModel?.isOpen)\r\n iModel.close();\r\n });\r\n\r\n function getProperty(className: string, propertyName: string): SchemaView.Property {\r\n const ecClass = view.findClass(`Zoo:${className}`);\r\n expect(ecClass, `class ${className}`).to.not.be.undefined;\r\n const property = ecClass!.getProperty(propertyName);\r\n expect(property, `property ${className}.${propertyName}`).to.not.be.undefined;\r\n return property!;\r\n }\r\n\r\n function getKindOfQuantityName(className: string, propertyName: string): string | undefined {\r\n const property = getProperty(className, propertyName);\r\n if (!property.isPrimitive())\r\n throw new Error(`${className}.${propertyName} is not primitive`);\r\n return property.kindOfQuantity?.name;\r\n }\r\n\r\n describe(\"category\", () => {\r\n it(\"returns the local category\", () => {\r\n expect(getProperty(\"Animal\", \"Nickname\").category?.name).to.equal(\"Identity\");\r\n });\r\n\r\n it(\"takes the category from the overridden property\", () => {\r\n const property = getProperty(\"Mammal\", \"Nickname\");\r\n expect(property.declaringClass?.name).to.equal(\"Mammal\");\r\n expect(property.label).to.equal(\"Mammal Nickname\");\r\n expect(property.category?.name).to.equal(\"Identity\");\r\n });\r\n\r\n it(\"takes the category through multiple overrides\", () => {\r\n const property = getProperty(\"Cat\", \"Nickname\");\r\n expect(property.declaringClass?.name).to.equal(\"Cat\");\r\n expect(property.label).to.equal(\"Cat Nickname\");\r\n expect(property.category?.name).to.equal(\"Identity\");\r\n });\r\n\r\n it(\"prefers the local category over the overridden one\", () => {\r\n expect(getProperty(\"Dog\", \"Nickname\").category?.name).to.equal(\"Nicknames\");\r\n });\r\n\r\n it(\"returns undefined if no declaration has a category\", () => {\r\n expect(getProperty(\"Cat\", \"FavoriteSnack\").category).to.be.undefined;\r\n });\r\n\r\n it(\"returns the category of an inherited property that is not overridden\", () => {\r\n const property = getProperty(\"Eagle\", \"Nickname\");\r\n expect(property.declaringClass?.name).to.equal(\"Animal\");\r\n expect(property.category?.name).to.equal(\"Identity\");\r\n });\r\n\r\n it(\"takes the category from an overridden mixin property\", () => {\r\n const property = getProperty(\"Parrot\", \"Vocabulary\");\r\n expect(property.declaringClass?.name).to.equal(\"Parrot\");\r\n expect(property.label).to.equal(\"Parrot Vocabulary\");\r\n expect(property.category?.name).to.equal(\"Skills\");\r\n });\r\n });\r\n\r\n describe(\"kindOfQuantity\", () => {\r\n it(\"returns the local KindOfQuantity\", () => {\r\n expect(getKindOfQuantityName(\"Animal\", \"Weight\")).to.equal(\"BodyMass\");\r\n expect(getKindOfQuantityName(\"Dog\", \"Weight\")).to.equal(\"PreciseBodyMass\");\r\n });\r\n\r\n it(\"takes the KindOfQuantity from the overridden property\", () => {\r\n expect(getKindOfQuantityName(\"Mammal\", \"Weight\")).to.equal(\"BodyMass\");\r\n expect(getKindOfQuantityName(\"Cat\", \"Weight\")).to.equal(\"BodyMass\");\r\n });\r\n\r\n it(\"takes the KindOfQuantity from the overridden primitive array property\", () => {\r\n const property = getProperty(\"Mammal\", \"DailyWeights\");\r\n expect(property.isArray()).to.be.true;\r\n expect(getKindOfQuantityName(\"Mammal\", \"DailyWeights\")).to.equal(\"BodyMass\");\r\n });\r\n });\r\n\r\n describe(\"hidden\", () => {\r\n it(\"hidden declaration is hidden\", () => {\r\n const property = getProperty(\"Animal\", \"Secret\");\r\n expect(property.isHidden).to.be.true;\r\n expect(property.isEffectivelyHidden).to.be.true;\r\n });\r\n\r\n it(\"override without HiddenProperty is effectively hidden if the overridden property is hidden\", () => {\r\n const property = getProperty(\"Mammal\", \"Secret\");\r\n expect(property.isHidden).to.be.false;\r\n expect(property.isEffectivelyHidden).to.be.true;\r\n });\r\n\r\n it(\"HiddenProperty(Show=true) on an override does not unhide a hidden overridden property\", () => {\r\n // Documented limitation: SchemaView cannot tell Show=true apart from no HiddenProperty.\r\n const property = getProperty(\"Mammal\", \"Mood\");\r\n expect(property.isHidden).to.be.false;\r\n expect(property.isEffectivelyHidden).to.be.true;\r\n });\r\n\r\n it(\"property without any HiddenProperty is not effectively hidden\", () => {\r\n expect(getProperty(\"Cat\", \"FavoriteSnack\").isEffectivelyHidden).to.be.false;\r\n });\r\n });\r\n\r\n describe(\"priority\", () => {\r\n it(\"is local to the declaration\", () => {\r\n expect(getProperty(\"Animal\", \"Nickname\").priority).to.equal(5);\r\n expect(getProperty(\"Mammal\", \"Nickname\").priority).to.equal(0);\r\n expect(getProperty(\"Dog\", \"Nickname\").priority).to.equal(0);\r\n });\r\n });\r\n\r\n describe(\"mixin overriding a mixin\", () => {\r\n it(\"class gets the declaration of the derived mixin\", () => {\r\n const property = getProperty(\"Eagle\", \"WingSpan\");\r\n expect(property.declaringClass?.name).to.equal(\"ISoarer\");\r\n expect(property.label).to.equal(\"Soaring Wing Span\");\r\n expect(property.category?.name).to.equal(\"Flight\");\r\n });\r\n\r\n it(\"derived mixin declaration takes the category from the base mixin\", () => {\r\n const property = getProperty(\"Eagle\", \"FlightSpeed\");\r\n expect(property.declaringClass?.name).to.equal(\"ISoarer\");\r\n expect(property.label).to.equal(\"Soaring Speed\");\r\n expect(property.category?.name).to.equal(\"Flight\");\r\n });\r\n\r\n it(\"lists each property once\", () => {\r\n const names = view.findClass(\"Zoo:Eagle\")!.getProperties().map((property) => property.name.toLowerCase());\r\n expect(new Set(names).size).to.equal(names.length);\r\n });\r\n });\r\n});\r\n"]}
|
|
@@ -445,10 +445,7 @@ function compareProperty(rProp, metaProp, rClass) {
|
|
|
445
445
|
expect(rProp.extendedTypeName?.toLowerCase()).to.equal(metaPrimProp.extendedTypeName.toLowerCase(), `extendedTypeName mismatch for ${ctx}`);
|
|
446
446
|
}
|
|
447
447
|
// KindOfQuantity reference (only on primitive properties)
|
|
448
|
-
|
|
449
|
-
if (metaKoq !== undefined && rProp.kindOfQuantity !== undefined) {
|
|
450
|
-
expect(rProp.kindOfQuantity.name).to.equal(metaKoq.name, `KoQ mismatch for ${ctx}`);
|
|
451
|
-
}
|
|
448
|
+
expect(rProp.kindOfQuantity?.name).to.equal(metaProp.getKindOfQuantitySync()?.name, `KoQ mismatch for ${ctx}`);
|
|
452
449
|
}
|
|
453
450
|
// isReadOnly
|
|
454
451
|
expect(rProp.isReadOnly).to.equal(metaProp.isReadOnly, `isReadOnly mismatch for ${ctx}`);
|
|
@@ -467,9 +464,6 @@ function compareProperty(rProp, metaProp, rClass) {
|
|
|
467
464
|
}
|
|
468
465
|
}
|
|
469
466
|
// Category reference (available on all property kinds)
|
|
470
|
-
|
|
471
|
-
if (metaCat !== undefined && rProp.category !== undefined) {
|
|
472
|
-
expect(rProp.category.name).to.equal(metaCat.name, `category mismatch for ${ctx}`);
|
|
473
|
-
}
|
|
467
|
+
expect(rProp.category?.name).to.equal(metaProp.getCategorySync()?.name, `category mismatch for ${ctx}`);
|
|
474
468
|
}
|
|
475
469
|
//# sourceMappingURL=SchemaViewValidation.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaViewValidation.test.js","sourceRoot":"","sources":["../../../../src/test/schema/SchemaViewValidation.test.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\r\nimport { DbResult } from \"@itwin/core-bentley\";\r\nimport { IModelHost, SnapshotDb } from \"../../core-backend\";\r\nimport { ClassModifier, ClassType, ECClass, ECClassModifier, Enumeration, KindOfQuantity, Mixin, NavigationProperty, PrimitiveProperty, Property, PropertyCategory, RelationshipClass, SchemaItemType, type SchemaView, StructProperty } from \"@itwin/ecschema-metadata\";\r\nimport { assert, expect } from \"chai\";\r\nimport * as path from \"path\";\r\nimport { KnownTestLocations } from \"../KnownTestLocations\";\r\nimport { TestUtils } from \"../TestUtils\";\r\n\r\n/** Schemas excluded from the SchemaView binary blob by the C++ writer.\r\n * Must stay in sync with `IsExcludedSchema()` in `SchemaViewWriter.cpp`.\r\n */\r\nconst excludedSchemaViewSchemas: ReadonlySet<string> = new Set([\r\n \"BisCustomAttributes\",\r\n \"CoreCustomAttributes\",\r\n \"ECDbFileInfo\",\r\n \"ECDbMap\",\r\n \"ECDbSchemaPolicies\",\r\n \"ECDbSystem\",\r\n \"ECv3ConversionAttributes\",\r\n \"EditorCustomAttributes\",\r\n \"Formats\",\r\n \"SchemaLocalizationCustomAttributes\",\r\n \"SchemaUpgradeCustomAttributes\",\r\n \"Units\",\r\n]);\r\n\r\n/**\r\n * Cross-validation test: walks ecschema-metadata and SchemaView in parallel,\r\n * asserting that every schema, class, property, enumeration, KoQ, and category returns\r\n * identical information from both layers.\r\n *\r\n * This test is iModel-agnostic - it works for any test bim. No hard-coded expected values.\r\n * To validate against a larger real iModel, just add its path to the `iModelPaths` array.\r\n */\r\ndescribe(\"SchemaView cross-validation\", () => {\r\n before(async () => {\r\n if (!IModelHost.isValid)\r\n await TestUtils.startBackend();\r\n });\r\n\r\n /** All test iModels to validate. Add paths here to test against larger/real iModels. */\r\n const iModelPaths = [\r\n path.join(KnownTestLocations.assetsDir, \"test.bim\"),\r\n // To temporarily test with a larger iModel:\r\n // \"/path/to/real/imodel.bim\",\r\n ];\r\n\r\n for (const iModelPath of iModelPaths) {\r\n const iModelName = path.basename(iModelPath);\r\n\r\n describe(iModelName, () => {\r\n let iModel: SnapshotDb;\r\n let schemaView: SchemaView;\r\n\r\n before(async () => {\r\n iModel = SnapshotDb.openFile(iModelPath);\r\n schemaView = await iModel.getSchemaView();\r\n });\r\n\r\n after(() => {\r\n iModel.close();\r\n });\r\n\r\n it(\"should have matching schema count and names\", () => {\r\n // Force all schemas to load via the schemaContext by looking up a class from each SchemaView schema.\r\n // ecschema-metadata loads schemas lazily - getKnownSchemas() only returns already-loaded ones.\r\n for (const rSchema of schemaView.getSchemas()) {\r\n // Looking up any item from this schema forces it to load in ecschema-metadata\r\n const firstClass = rSchema.getClasses().next();\r\n if (!firstClass.done) {\r\n const metaClass = iModel.schemaContext.getSchemaItemSync(rSchema.name, firstClass.value.name);\r\n assert.isDefined(metaClass, `Schema '${rSchema.name}' could not be loaded in ecschema-metadata`);\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching classes for every schema\", () => {\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n const metaClass = iModel.schemaContext.getSchemaItemSync(rSchema.name, rClass.name) as ECClass | undefined;\r\n assert.isDefined(metaClass, `Class '${rClass.fullName}' not found in ecschema-metadata`);\r\n\r\n // Name and fullName\r\n expect(rClass.name).to.equal(metaClass!.name, `name mismatch for ${rClass.fullName}`);\r\n\r\n // Type\r\n const expectedType = schemaItemTypeToClassType(metaClass!.schemaItemType, metaClass!);\r\n expect(rClass.type).to.equal(expectedType, `type mismatch for ${rClass.fullName}: schemaView=${ClassType[rClass.type]}, expected=${ClassType[expectedType]}`);\r\n\r\n // Modifier\r\n const expectedModifier = ecModifierToClassModifier(metaClass!.modifier);\r\n expect(rClass.modifier).to.equal(expectedModifier, `modifier mismatch for ${rClass.fullName}`);\r\n\r\n // Label (ecschema-metadata returns undefined when no label, SchemaView returns the name)\r\n if (metaClass!.label !== undefined) {\r\n expect(rClass.label).to.equal(metaClass!.label, `label mismatch for ${rClass.fullName}`);\r\n }\r\n\r\n // Base class\r\n const metaBase = metaClass!.getBaseClassSync();\r\n if (metaBase !== undefined) {\r\n assert.isDefined(rClass.baseClass, `${rClass.fullName} should have a base class`);\r\n expect(rClass.baseClass!.name).to.equal(metaBase.name, `base class name mismatch for ${rClass.fullName}`);\r\n }\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching properties for every class\", () => {\r\n let totalChecked = 0;\r\n\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n const metaClass = iModel.schemaContext.getSchemaItemSync(rSchema.name, rClass.name) as ECClass | undefined;\r\n if (metaClass === undefined)\r\n continue;\r\n\r\n // Compare own properties (exclude inherited to avoid ordering issues across layers)\r\n const rOwnProps = rClass.getOwnProperties();\r\n const metaOwnProps = [...metaClass.getPropertiesSync(true)]; // excludeInherited=true\r\n\r\n expect(rOwnProps.length).to.equal(metaOwnProps.length,\r\n `own property count mismatch for ${rClass.fullName}: schemaView=${rOwnProps.length}, meta=${metaOwnProps.length}`);\r\n\r\n for (const rProp of rOwnProps) {\r\n const metaProp = metaOwnProps.find((p) => p.name.toLowerCase() === rProp.name.toLowerCase());\r\n assert.isDefined(metaProp, `Property '${rProp.name}' on ${rClass.fullName} not found in ecschema-metadata`);\r\n\r\n compareProperty(rProp, metaProp!, rClass);\r\n totalChecked++;\r\n }\r\n }\r\n }\r\n\r\n // Sanity: we actually compared something\r\n assert.isAbove(totalChecked, 0, \"No properties were compared - something is wrong with the test setup\");\r\n });\r\n\r\n it(\"should have matching inherited properties for every class\", () => {\r\n let classesChecked = 0;\r\n\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n const metaClass = iModel.schemaContext.getSchemaItemSync(rSchema.name, rClass.name) as ECClass | undefined;\r\n if (metaClass === undefined)\r\n continue;\r\n\r\n // Compare all properties (including inherited)\r\n const rAllProps = rClass.getProperties();\r\n const metaAllProps = [...metaClass.getPropertiesSync(false)]; // includeInherited\r\n\r\n // Check that every ecschema-metadata property exists in the SchemaView\r\n for (const metaProp of metaAllProps) {\r\n const rProp = rAllProps.find((p) => p.name.toLowerCase() === metaProp.name.toLowerCase());\r\n assert.isDefined(rProp, `Inherited property '${metaProp.name}' on ${rClass.fullName} missing from SchemaView`);\r\n }\r\n\r\n // Check that every SchemaView property exists in ecschema-metadata\r\n for (const rProp of rAllProps) {\r\n const metaProp = metaAllProps.find((p) => p.name.toLowerCase() === rProp.name.toLowerCase());\r\n assert.isDefined(metaProp, `SchemaView property '${rProp.name}' on ${rClass.fullName} has no ecschema-metadata counterpart`);\r\n }\r\n\r\n expect(rAllProps.length).to.equal(metaAllProps.length,\r\n `total property count mismatch for ${rClass.fullName}`);\r\n\r\n classesChecked++;\r\n }\r\n }\r\n\r\n assert.isAbove(classesChecked, 0);\r\n });\r\n\r\n it(\"should have correct ecInstanceId values\", () => {\r\n // Validate that ecInstanceId on SchemaView objects matches ec_ table row IDs.\r\n // This is the bridge that lets consumers fall back to ECDbMeta ECSQL queries.\r\n\r\n // Schemas\r\n const ecSchemaIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\"SELECT Id, Name FROM ec_Schema\", (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecSchemaIds.set(stmt.getValueString(1).toLowerCase(), stmt.getValueInteger(0));\r\n });\r\n for (const rSchema of schemaView.getSchemas()) {\r\n const ecId = ecSchemaIds.get(rSchema.name.toLowerCase());\r\n assert.isDefined(ecId, `ec_Schema row not found for ${rSchema.name}`);\r\n expect(rSchema.ecInstanceId).to.equal(ecId, `ecInstanceId mismatch for schema ${rSchema.name}`);\r\n }\r\n\r\n // Classes\r\n const ecClassIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\r\n \"SELECT c.Id, s.Name, c.Name FROM ec_Class c JOIN ec_Schema s ON c.SchemaId=s.Id\",\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecClassIds.set(`${stmt.getValueString(1).toLowerCase()}:${stmt.getValueString(2).toLowerCase()}`, stmt.getValueInteger(0));\r\n },\r\n );\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n const key = `${rSchema.name.toLowerCase()}:${rClass.name.toLowerCase()}`;\r\n const ecId = ecClassIds.get(key);\r\n assert.isDefined(ecId, `ec_Class row not found for ${rClass.fullName}`);\r\n expect(rClass.ecInstanceId).to.equal(ecId, `ecInstanceId mismatch for class ${rClass.fullName}`);\r\n }\r\n }\r\n\r\n // Own properties\r\n const ecPropIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\r\n \"SELECT p.Id, s.Name, c.Name, p.Name FROM ec_Property p JOIN ec_Class c ON p.ClassId=c.Id JOIN ec_Schema s ON c.SchemaId=s.Id\",\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecPropIds.set(`${stmt.getValueString(1).toLowerCase()}:${stmt.getValueString(2).toLowerCase()}.${stmt.getValueString(3).toLowerCase()}`, stmt.getValueInteger(0));\r\n },\r\n );\r\n let propsChecked = 0;\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n for (const rProp of rClass.getOwnProperties()) {\r\n const key = `${rSchema.name.toLowerCase()}:${rClass.name.toLowerCase()}.${rProp.name.toLowerCase()}`;\r\n const ecId = ecPropIds.get(key);\r\n if (ecId === undefined) continue; // dropped properties (broken refs)\r\n expect(rProp.ecInstanceId).to.equal(ecId, `ecInstanceId mismatch for property ${rClass.fullName}.${rProp.name}`);\r\n propsChecked++;\r\n }\r\n }\r\n }\r\n assert.isAbove(propsChecked, 0, \"No property ecInstanceIds were checked\");\r\n\r\n // Enumerations\r\n const ecEnumIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\r\n \"SELECT e.Id, s.Name, e.Name FROM ec_Enumeration e JOIN ec_Schema s ON e.SchemaId=s.Id\",\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecEnumIds.set(`${stmt.getValueString(1).toLowerCase()}:${stmt.getValueString(2).toLowerCase()}`, stmt.getValueInteger(0));\r\n },\r\n );\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rEnum of rSchema.getEnumerations()) {\r\n const key = `${rSchema.name.toLowerCase()}:${rEnum.name.toLowerCase()}`;\r\n const ecId = ecEnumIds.get(key);\r\n assert.isDefined(ecId, `ec_Enumeration row not found for ${rEnum.fullName}`);\r\n expect(rEnum.ecInstanceId).to.equal(ecId!, `ecInstanceId mismatch for enum ${rEnum.fullName}`);\r\n }\r\n }\r\n\r\n // KindOfQuantity\r\n const ecKoqIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\r\n \"SELECT k.Id, s.Name, k.Name FROM ec_KindOfQuantity k JOIN ec_Schema s ON k.SchemaId=s.Id\",\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecKoqIds.set(`${stmt.getValueString(1).toLowerCase()}:${stmt.getValueString(2).toLowerCase()}`, stmt.getValueInteger(0));\r\n },\r\n );\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rKoq of rSchema.getKindOfQuantities()) {\r\n const key = `${rSchema.name.toLowerCase()}:${rKoq.name.toLowerCase()}`;\r\n const ecId = ecKoqIds.get(key);\r\n assert.isDefined(ecId, `ec_KindOfQuantity row not found for ${rKoq.fullName}`);\r\n expect(rKoq.ecInstanceId).to.equal(ecId!, `ecInstanceId mismatch for KoQ ${rKoq.fullName}`);\r\n }\r\n }\r\n\r\n // PropertyCategory\r\n const ecCatIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\r\n \"SELECT pc.Id, s.Name, pc.Name FROM ec_PropertyCategory pc JOIN ec_Schema s ON pc.SchemaId=s.Id\",\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecCatIds.set(`${stmt.getValueString(1).toLowerCase()}:${stmt.getValueString(2).toLowerCase()}`, stmt.getValueInteger(0));\r\n },\r\n );\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rCat of rSchema.getPropertyCategories()) {\r\n const key = `${rSchema.name.toLowerCase()}:${rCat.name.toLowerCase()}`;\r\n const ecId = ecCatIds.get(key);\r\n assert.isDefined(ecId, `ec_PropertyCategory row not found for ${rCat.fullName}`);\r\n expect(rCat.ecInstanceId).to.equal(ecId!, `ecInstanceId mismatch for category ${rCat.fullName}`);\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching enumerations\", () => {\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rEnum of rSchema.getEnumerations()) {\r\n const metaEnum = iModel.schemaContext.getSchemaItemSync(rSchema.name, rEnum.name) as Enumeration | undefined;\r\n assert.isDefined(metaEnum, `Enumeration '${rEnum.fullName}' not found in ecschema-metadata`);\r\n\r\n expect(rEnum.isStrict).to.equal(metaEnum!.isStrict, `isStrict mismatch for ${rEnum.fullName}`);\r\n\r\n // Compare enumerators\r\n const rEnumerators = [...rEnum.getEnumerators()];\r\n const metaEnumerators = metaEnum!.enumerators;\r\n expect(rEnumerators.length).to.equal(metaEnumerators.length,\r\n `enumerator count mismatch for ${rEnum.fullName}`);\r\n\r\n for (let i = 0; i < rEnumerators.length; i++) {\r\n expect(rEnumerators[i].name).to.equal(metaEnumerators[i].name,\r\n `enumerator name mismatch at index ${i} in ${rEnum.fullName}`);\r\n expect(rEnumerators[i].value).to.equal(metaEnumerators[i].value,\r\n `enumerator value mismatch for ${rEnumerators[i].name} in ${rEnum.fullName}`);\r\n }\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching KindOfQuantity items\", () => {\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rKoq of rSchema.getKindOfQuantities()) {\r\n const metaKoq = iModel.schemaContext.getSchemaItemSync(rSchema.name, rKoq.name) as KindOfQuantity | undefined;\r\n assert.isDefined(metaKoq, `KoQ '${rKoq.fullName}' not found in ecschema-metadata`);\r\n\r\n expect(rKoq.relativeError).to.equal(metaKoq!.relativeError,\r\n `relativeError mismatch for ${rKoq.fullName}`);\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching PropertyCategory items\", () => {\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rCat of rSchema.getPropertyCategories()) {\r\n const metaCat = iModel.schemaContext.getSchemaItemSync(rSchema.name, rCat.name) as PropertyCategory | undefined;\r\n assert.isDefined(metaCat, `PropertyCategory '${rCat.fullName}' not found in ecschema-metadata`);\r\n\r\n expect(rCat.priority).to.equal(metaCat!.priority,\r\n `priority mismatch for ${rCat.fullName}`);\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching relationship constraints\", () => {\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n if (!rClass.isRelationship())\r\n continue;\r\n\r\n const metaRel = iModel.schemaContext.getSchemaItemSync(rSchema.name, rClass.name) as RelationshipClass | undefined;\r\n assert.isDefined(metaRel, `Relationship '${rClass.fullName}' not in ecschema-metadata`);\r\n\r\n // Source constraint\r\n if (rClass.source !== undefined) {\r\n const metaSrc = metaRel!.source;\r\n if (metaSrc.abstractConstraint !== undefined && rClass.source.abstractConstraint !== undefined) {\r\n expect(rClass.source.abstractConstraint.name).to.equal(\r\n metaSrc.abstractConstraint.fullName.split(\".\").pop(),\r\n `source abstractConstraint mismatch for ${rClass.fullName}`,\r\n );\r\n }\r\n }\r\n\r\n // Target constraint\r\n if (rClass.target !== undefined) {\r\n const metaTgt = metaRel!.target;\r\n if (metaTgt.abstractConstraint !== undefined && rClass.target.abstractConstraint !== undefined) {\r\n expect(rClass.target.abstractConstraint.name).to.equal(\r\n metaTgt.abstractConstraint.fullName.split(\".\").pop(),\r\n `target abstractConstraint mismatch for ${rClass.fullName}`,\r\n );\r\n }\r\n }\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching IS-A relationships\", () => {\r\n // Pick a few well-known hierarchies and verify IS-A checks match\r\n const testPairs: Array<[string, string, boolean]> = [\r\n [\"BisCore:GeometricElement3d\", \"BisCore:Element\", true],\r\n [\"BisCore:Element\", \"BisCore:GeometricElement3d\", false],\r\n [\"BisCore:PhysicalElement\", \"BisCore:GeometricElement\", true],\r\n [\"BisCore:ModelContainsElements\", \"BisCore:ElementRefersToElements\", false],\r\n ];\r\n\r\n for (const [className, baseName, expected] of testPairs) {\r\n const rClass = schemaView.findClass(className);\r\n if (rClass === undefined)\r\n continue; // Class may not exist in minimal test iModels\r\n\r\n const result = rClass.is(baseName);\r\n expect(result).to.equal(expected, `IS-A check: ${className} -> ${baseName}`);\r\n }\r\n });\r\n\r\n it(\"should have matching isHidden flags against ec_CustomAttribute\", () => {\r\n // Build a set of property IDs that have CoreCustomAttributes:HiddenProperty CA\r\n // (without Show=True override), mirroring the C++ writer's CollectHiddenPropertyIds.\r\n const hiddenPropertyIds = new Set<number>();\r\n iModel.withSqliteStatement(\r\n `SELECT ca.ContainerId, ca.Instance\r\n FROM ec_CustomAttribute ca\r\n JOIN ec_Class cac ON ca.ClassId=cac.Id\r\n JOIN ec_Schema cas ON cac.SchemaId=cas.Id\r\n WHERE ca.ContainerType & 992 <> 0\r\n AND cas.Name='CoreCustomAttributes' AND cac.Name='HiddenProperty'`,\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW) {\r\n const instance: string = stmt.getValueString(1) ?? \"\";\r\n if (instance) {\r\n const lower = instance.toLowerCase();\r\n if (lower.includes(\">true</\"))\r\n continue; // Show=True means NOT hidden\r\n }\r\n hiddenPropertyIds.add(stmt.getValueInteger(0));\r\n }\r\n },\r\n );\r\n\r\n // Build a map of property ID -> (schemaName, className, propertyName) from ec_ tables\r\n // so we can correlate ec_ property IDs to SchemaView properties.\r\n const propIdMap = new Map<number, { schema: string; cls: string; prop: string }>();\r\n iModel.withSqliteStatement(\r\n `SELECT p.Id, s.Name, c.Name, p.Name\r\n FROM ec_Property p\r\n JOIN ec_Class c ON p.ClassId=c.Id\r\n JOIN ec_Schema s ON c.SchemaId=s.Id`,\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW) {\r\n propIdMap.set(stmt.getValueInteger(0), {\r\n schema: stmt.getValueString(1),\r\n cls: stmt.getValueString(2),\r\n prop: stmt.getValueString(3),\r\n });\r\n }\r\n },\r\n );\r\n\r\n // Cross-validate: for every hidden property in ec_ tables that belongs to a\r\n // non-excluded schema, the SchemaView must also mark it as hidden.\r\n let hiddenChecked = 0;\r\n for (const propId of hiddenPropertyIds) {\r\n const info = propIdMap.get(propId);\r\n if (info === undefined) continue;\r\n if (excludedSchemaViewSchemas.has(info.schema)) continue;\r\n\r\n const rClass = schemaView.findClass(`${info.schema}:${info.cls}`);\r\n if (rClass === undefined) continue;\r\n\r\n // Check own properties only (the property lives on this class)\r\n const rProp = rClass.getOwnProperties().find(\r\n (p) => p.name.toLowerCase() === info.prop.toLowerCase(),\r\n );\r\n if (rProp === undefined) continue; // property may have been dropped (broken struct ref)\r\n\r\n expect(rProp.isHidden).to.equal(true,\r\n `${info.schema}:${info.cls}.${info.prop} should be hidden (has HiddenProperty CA)`);\r\n hiddenChecked++;\r\n }\r\n\r\n // Also spot-check that explicitly visible properties are NOT hidden.\r\n // Walk a subset of SchemaView classes and verify that properties not in the hidden set\r\n // are marked as not hidden.\r\n let visibleChecked = 0;\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n for (const rProp of rClass.getOwnProperties()) {\r\n // Find the ec_ property ID for this prop\r\n const matchingEntry = [...propIdMap.entries()].find(([_, info]) =>\r\n info.schema.toLowerCase() === rSchema.name.toLowerCase()\r\n && info.cls.toLowerCase() === rClass.name.toLowerCase()\r\n && info.prop.toLowerCase() === rProp.name.toLowerCase(),\r\n );\r\n if (matchingEntry === undefined) continue;\r\n const [propId] = matchingEntry;\r\n\r\n if (!hiddenPropertyIds.has(propId)) {\r\n expect(rProp.isHidden).to.equal(false,\r\n `${rClass.fullName}.${rProp.name} should NOT be hidden (no HiddenProperty CA)`);\r\n visibleChecked++;\r\n }\r\n }\r\n if (visibleChecked >= 200) break; // cap to keep test fast\r\n }\r\n if (visibleChecked >= 200) break;\r\n }\r\n\r\n // The test.bim likely has at least some non-hidden properties\r\n assert.isAbove(visibleChecked, 0, \"No visible properties checked - test setup issue\");\r\n assert.isAbove(hiddenChecked, 0, \"No hidden properties checked - test setup issue\");\r\n });\r\n });\r\n }\r\n});\r\n\r\n// --- Helper functions ---\r\n\r\n/** Map ecschema-metadata SchemaItemType to SchemaView ClassType. */\r\nfunction schemaItemTypeToClassType(itemType: SchemaItemType, ecClass: ECClass): ClassType {\r\n switch (itemType) {\r\n case SchemaItemType.EntityClass:\r\n // ecschema-metadata distinguishes Mixin via instanceof, not SchemaItemType\r\n return (ecClass instanceof Mixin) ? ClassType.Mixin : ClassType.Entity;\r\n case SchemaItemType.Mixin:\r\n return ClassType.Mixin;\r\n case SchemaItemType.RelationshipClass:\r\n return ClassType.Relationship;\r\n case SchemaItemType.StructClass:\r\n return ClassType.Struct;\r\n case SchemaItemType.CustomAttributeClass:\r\n return ClassType.CustomAttribute;\r\n default:\r\n assert.fail(`Unexpected SchemaItemType '${itemType}' for class '${ecClass.fullName}'`);\r\n }\r\n}\r\n\r\n/** Map ecschema-metadata ECClassModifier to SchemaView ClassModifier. */\r\nfunction ecModifierToClassModifier(modifier: ECClassModifier): ClassModifier {\r\n switch (modifier) {\r\n case ECClassModifier.None: return ClassModifier.None;\r\n case ECClassModifier.Abstract: return ClassModifier.Abstract;\r\n case ECClassModifier.Sealed: return ClassModifier.Sealed;\r\n default: return ClassModifier.None;\r\n }\r\n}\r\n\r\n/** Compare a single property across both layers. */\r\nfunction compareProperty(rProp: ReturnType<SchemaView.Class[\"getProperties\"]>[number], metaProp: Property, rClass: SchemaView.Class): void {\r\n const ctx = `${rClass.fullName}.${rProp.name}`;\r\n\r\n // Name\r\n expect(rProp.name.toLowerCase()).to.equal(metaProp.name.toLowerCase(), `name mismatch for ${ctx}`);\r\n\r\n // Kind discriminators (methods, not getters - they are real type predicates)\r\n expect(rProp.isPrimitive()).to.equal(metaProp.isPrimitive(), `isPrimitive mismatch for ${ctx}`);\r\n expect(rProp.isNavigation()).to.equal(metaProp.isNavigation(), `isNavigation mismatch for ${ctx}`);\r\n expect(rProp.isArray()).to.equal(metaProp.isArray(), `isArray mismatch for ${ctx}`);\r\n\r\n // For primitives and enums: check primitiveType and extendedTypeName\r\n if (rProp.isPrimitive()) {\r\n // Cast to PrimitiveProperty for field access - ecschema-metadata's type hierarchy\r\n // doesn't model enum-as-primitive correctly (see itwinjs-core#8448), but the fields exist at runtime.\r\n const metaPrimProp = metaProp as unknown as PrimitiveProperty;\r\n if (metaPrimProp.primitiveType !== undefined) {\r\n // SchemaViewPrimitiveType values match PrimitiveType values\r\n expect(rProp.primitiveType).to.equal(metaPrimProp.primitiveType,\r\n `primitiveType mismatch for ${ctx}: schemaView=0x${rProp.primitiveType.toString(16)}, meta=0x${metaPrimProp.primitiveType.toString(16)}`);\r\n }\r\n if (metaPrimProp.extendedTypeName !== undefined) {\r\n expect(rProp.extendedTypeName?.toLowerCase()).to.equal(metaPrimProp.extendedTypeName.toLowerCase(),\r\n `extendedTypeName mismatch for ${ctx}`);\r\n }\r\n\r\n // KindOfQuantity reference (only on primitive properties)\r\n const metaKoq = metaProp.getKindOfQuantitySync();\r\n if (metaKoq !== undefined && rProp.kindOfQuantity !== undefined) {\r\n expect(rProp.kindOfQuantity.name).to.equal(metaKoq.name, `KoQ mismatch for ${ctx}`);\r\n }\r\n }\r\n\r\n // isReadOnly\r\n expect(rProp.isReadOnly).to.equal(metaProp.isReadOnly, `isReadOnly mismatch for ${ctx}`);\r\n\r\n // Struct class reference - structClass is non-nullable on struct subclasses\r\n if (rProp.isStruct()) {\r\n const metaStruct = metaProp as StructProperty;\r\n expect(rProp.structClass.name).to.equal(metaStruct.structClass.name, `structClass mismatch for ${ctx}`);\r\n }\r\n\r\n // Navigation property: direction and relationship class\r\n if (rProp.isNavigation()) {\r\n const metaNav = metaProp as NavigationProperty;\r\n expect(rProp.direction).to.equal(metaNav.direction, `direction mismatch for ${ctx}`);\r\n\r\n const metaRelClass = metaNav.getRelationshipClassSync();\r\n if (metaRelClass !== undefined) {\r\n expect(rProp.relationshipClass.name).to.equal(metaRelClass.name,\r\n `nav relationshipClass mismatch for ${ctx}`);\r\n }\r\n }\r\n\r\n // Category reference (available on all property kinds)\r\n const metaCat = metaProp.getCategorySync();\r\n if (metaCat !== undefined && rProp.category !== undefined) {\r\n expect(rProp.category.name).to.equal(metaCat.name, `category mismatch for ${ctx}`);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"SchemaViewValidation.test.js","sourceRoot":"","sources":["../../../../src/test/schema/SchemaViewValidation.test.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\r\nimport { DbResult } from \"@itwin/core-bentley\";\r\nimport { IModelHost, SnapshotDb } from \"../../core-backend\";\r\nimport { ClassModifier, ClassType, ECClass, ECClassModifier, Enumeration, KindOfQuantity, Mixin, NavigationProperty, PrimitiveProperty, Property, PropertyCategory, RelationshipClass, SchemaItemType, type SchemaView, StructProperty } from \"@itwin/ecschema-metadata\";\r\nimport { assert, expect } from \"chai\";\r\nimport * as path from \"path\";\r\nimport { KnownTestLocations } from \"../KnownTestLocations\";\r\nimport { TestUtils } from \"../TestUtils\";\r\n\r\n/** Schemas excluded from the SchemaView binary blob by the C++ writer.\r\n * Must stay in sync with `IsExcludedSchema()` in `SchemaViewWriter.cpp`.\r\n */\r\nconst excludedSchemaViewSchemas: ReadonlySet<string> = new Set([\r\n \"BisCustomAttributes\",\r\n \"CoreCustomAttributes\",\r\n \"ECDbFileInfo\",\r\n \"ECDbMap\",\r\n \"ECDbSchemaPolicies\",\r\n \"ECDbSystem\",\r\n \"ECv3ConversionAttributes\",\r\n \"EditorCustomAttributes\",\r\n \"Formats\",\r\n \"SchemaLocalizationCustomAttributes\",\r\n \"SchemaUpgradeCustomAttributes\",\r\n \"Units\",\r\n]);\r\n\r\n/**\r\n * Cross-validation test: walks ecschema-metadata and SchemaView in parallel,\r\n * asserting that every schema, class, property, enumeration, KoQ, and category returns\r\n * identical information from both layers.\r\n *\r\n * This test is iModel-agnostic - it works for any test bim. No hard-coded expected values.\r\n * To validate against a larger real iModel, just add its path to the `iModelPaths` array.\r\n */\r\ndescribe(\"SchemaView cross-validation\", () => {\r\n before(async () => {\r\n if (!IModelHost.isValid)\r\n await TestUtils.startBackend();\r\n });\r\n\r\n /** All test iModels to validate. Add paths here to test against larger/real iModels. */\r\n const iModelPaths = [\r\n path.join(KnownTestLocations.assetsDir, \"test.bim\"),\r\n // To temporarily test with a larger iModel:\r\n // \"/path/to/real/imodel.bim\",\r\n ];\r\n\r\n for (const iModelPath of iModelPaths) {\r\n const iModelName = path.basename(iModelPath);\r\n\r\n describe(iModelName, () => {\r\n let iModel: SnapshotDb;\r\n let schemaView: SchemaView;\r\n\r\n before(async () => {\r\n iModel = SnapshotDb.openFile(iModelPath);\r\n schemaView = await iModel.getSchemaView();\r\n });\r\n\r\n after(() => {\r\n iModel.close();\r\n });\r\n\r\n it(\"should have matching schema count and names\", () => {\r\n // Force all schemas to load via the schemaContext by looking up a class from each SchemaView schema.\r\n // ecschema-metadata loads schemas lazily - getKnownSchemas() only returns already-loaded ones.\r\n for (const rSchema of schemaView.getSchemas()) {\r\n // Looking up any item from this schema forces it to load in ecschema-metadata\r\n const firstClass = rSchema.getClasses().next();\r\n if (!firstClass.done) {\r\n const metaClass = iModel.schemaContext.getSchemaItemSync(rSchema.name, firstClass.value.name);\r\n assert.isDefined(metaClass, `Schema '${rSchema.name}' could not be loaded in ecschema-metadata`);\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching classes for every schema\", () => {\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n const metaClass = iModel.schemaContext.getSchemaItemSync(rSchema.name, rClass.name) as ECClass | undefined;\r\n assert.isDefined(metaClass, `Class '${rClass.fullName}' not found in ecschema-metadata`);\r\n\r\n // Name and fullName\r\n expect(rClass.name).to.equal(metaClass!.name, `name mismatch for ${rClass.fullName}`);\r\n\r\n // Type\r\n const expectedType = schemaItemTypeToClassType(metaClass!.schemaItemType, metaClass!);\r\n expect(rClass.type).to.equal(expectedType, `type mismatch for ${rClass.fullName}: schemaView=${ClassType[rClass.type]}, expected=${ClassType[expectedType]}`);\r\n\r\n // Modifier\r\n const expectedModifier = ecModifierToClassModifier(metaClass!.modifier);\r\n expect(rClass.modifier).to.equal(expectedModifier, `modifier mismatch for ${rClass.fullName}`);\r\n\r\n // Label (ecschema-metadata returns undefined when no label, SchemaView returns the name)\r\n if (metaClass!.label !== undefined) {\r\n expect(rClass.label).to.equal(metaClass!.label, `label mismatch for ${rClass.fullName}`);\r\n }\r\n\r\n // Base class\r\n const metaBase = metaClass!.getBaseClassSync();\r\n if (metaBase !== undefined) {\r\n assert.isDefined(rClass.baseClass, `${rClass.fullName} should have a base class`);\r\n expect(rClass.baseClass!.name).to.equal(metaBase.name, `base class name mismatch for ${rClass.fullName}`);\r\n }\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching properties for every class\", () => {\r\n let totalChecked = 0;\r\n\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n const metaClass = iModel.schemaContext.getSchemaItemSync(rSchema.name, rClass.name) as ECClass | undefined;\r\n if (metaClass === undefined)\r\n continue;\r\n\r\n // Compare own properties (exclude inherited to avoid ordering issues across layers)\r\n const rOwnProps = rClass.getOwnProperties();\r\n const metaOwnProps = [...metaClass.getPropertiesSync(true)]; // excludeInherited=true\r\n\r\n expect(rOwnProps.length).to.equal(metaOwnProps.length,\r\n `own property count mismatch for ${rClass.fullName}: schemaView=${rOwnProps.length}, meta=${metaOwnProps.length}`);\r\n\r\n for (const rProp of rOwnProps) {\r\n const metaProp = metaOwnProps.find((p) => p.name.toLowerCase() === rProp.name.toLowerCase());\r\n assert.isDefined(metaProp, `Property '${rProp.name}' on ${rClass.fullName} not found in ecschema-metadata`);\r\n\r\n compareProperty(rProp, metaProp!, rClass);\r\n totalChecked++;\r\n }\r\n }\r\n }\r\n\r\n // Sanity: we actually compared something\r\n assert.isAbove(totalChecked, 0, \"No properties were compared - something is wrong with the test setup\");\r\n });\r\n\r\n it(\"should have matching inherited properties for every class\", () => {\r\n let classesChecked = 0;\r\n\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n const metaClass = iModel.schemaContext.getSchemaItemSync(rSchema.name, rClass.name) as ECClass | undefined;\r\n if (metaClass === undefined)\r\n continue;\r\n\r\n // Compare all properties (including inherited)\r\n const rAllProps = rClass.getProperties();\r\n const metaAllProps = [...metaClass.getPropertiesSync(false)]; // includeInherited\r\n\r\n // Check that every ecschema-metadata property exists in the SchemaView\r\n for (const metaProp of metaAllProps) {\r\n const rProp = rAllProps.find((p) => p.name.toLowerCase() === metaProp.name.toLowerCase());\r\n assert.isDefined(rProp, `Inherited property '${metaProp.name}' on ${rClass.fullName} missing from SchemaView`);\r\n }\r\n\r\n // Check that every SchemaView property exists in ecschema-metadata\r\n for (const rProp of rAllProps) {\r\n const metaProp = metaAllProps.find((p) => p.name.toLowerCase() === rProp.name.toLowerCase());\r\n assert.isDefined(metaProp, `SchemaView property '${rProp.name}' on ${rClass.fullName} has no ecschema-metadata counterpart`);\r\n }\r\n\r\n expect(rAllProps.length).to.equal(metaAllProps.length,\r\n `total property count mismatch for ${rClass.fullName}`);\r\n\r\n classesChecked++;\r\n }\r\n }\r\n\r\n assert.isAbove(classesChecked, 0);\r\n });\r\n\r\n it(\"should have correct ecInstanceId values\", () => {\r\n // Validate that ecInstanceId on SchemaView objects matches ec_ table row IDs.\r\n // This is the bridge that lets consumers fall back to ECDbMeta ECSQL queries.\r\n\r\n // Schemas\r\n const ecSchemaIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\"SELECT Id, Name FROM ec_Schema\", (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecSchemaIds.set(stmt.getValueString(1).toLowerCase(), stmt.getValueInteger(0));\r\n });\r\n for (const rSchema of schemaView.getSchemas()) {\r\n const ecId = ecSchemaIds.get(rSchema.name.toLowerCase());\r\n assert.isDefined(ecId, `ec_Schema row not found for ${rSchema.name}`);\r\n expect(rSchema.ecInstanceId).to.equal(ecId, `ecInstanceId mismatch for schema ${rSchema.name}`);\r\n }\r\n\r\n // Classes\r\n const ecClassIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\r\n \"SELECT c.Id, s.Name, c.Name FROM ec_Class c JOIN ec_Schema s ON c.SchemaId=s.Id\",\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecClassIds.set(`${stmt.getValueString(1).toLowerCase()}:${stmt.getValueString(2).toLowerCase()}`, stmt.getValueInteger(0));\r\n },\r\n );\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n const key = `${rSchema.name.toLowerCase()}:${rClass.name.toLowerCase()}`;\r\n const ecId = ecClassIds.get(key);\r\n assert.isDefined(ecId, `ec_Class row not found for ${rClass.fullName}`);\r\n expect(rClass.ecInstanceId).to.equal(ecId, `ecInstanceId mismatch for class ${rClass.fullName}`);\r\n }\r\n }\r\n\r\n // Own properties\r\n const ecPropIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\r\n \"SELECT p.Id, s.Name, c.Name, p.Name FROM ec_Property p JOIN ec_Class c ON p.ClassId=c.Id JOIN ec_Schema s ON c.SchemaId=s.Id\",\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecPropIds.set(`${stmt.getValueString(1).toLowerCase()}:${stmt.getValueString(2).toLowerCase()}.${stmt.getValueString(3).toLowerCase()}`, stmt.getValueInteger(0));\r\n },\r\n );\r\n let propsChecked = 0;\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n for (const rProp of rClass.getOwnProperties()) {\r\n const key = `${rSchema.name.toLowerCase()}:${rClass.name.toLowerCase()}.${rProp.name.toLowerCase()}`;\r\n const ecId = ecPropIds.get(key);\r\n if (ecId === undefined) continue; // dropped properties (broken refs)\r\n expect(rProp.ecInstanceId).to.equal(ecId, `ecInstanceId mismatch for property ${rClass.fullName}.${rProp.name}`);\r\n propsChecked++;\r\n }\r\n }\r\n }\r\n assert.isAbove(propsChecked, 0, \"No property ecInstanceIds were checked\");\r\n\r\n // Enumerations\r\n const ecEnumIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\r\n \"SELECT e.Id, s.Name, e.Name FROM ec_Enumeration e JOIN ec_Schema s ON e.SchemaId=s.Id\",\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecEnumIds.set(`${stmt.getValueString(1).toLowerCase()}:${stmt.getValueString(2).toLowerCase()}`, stmt.getValueInteger(0));\r\n },\r\n );\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rEnum of rSchema.getEnumerations()) {\r\n const key = `${rSchema.name.toLowerCase()}:${rEnum.name.toLowerCase()}`;\r\n const ecId = ecEnumIds.get(key);\r\n assert.isDefined(ecId, `ec_Enumeration row not found for ${rEnum.fullName}`);\r\n expect(rEnum.ecInstanceId).to.equal(ecId!, `ecInstanceId mismatch for enum ${rEnum.fullName}`);\r\n }\r\n }\r\n\r\n // KindOfQuantity\r\n const ecKoqIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\r\n \"SELECT k.Id, s.Name, k.Name FROM ec_KindOfQuantity k JOIN ec_Schema s ON k.SchemaId=s.Id\",\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecKoqIds.set(`${stmt.getValueString(1).toLowerCase()}:${stmt.getValueString(2).toLowerCase()}`, stmt.getValueInteger(0));\r\n },\r\n );\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rKoq of rSchema.getKindOfQuantities()) {\r\n const key = `${rSchema.name.toLowerCase()}:${rKoq.name.toLowerCase()}`;\r\n const ecId = ecKoqIds.get(key);\r\n assert.isDefined(ecId, `ec_KindOfQuantity row not found for ${rKoq.fullName}`);\r\n expect(rKoq.ecInstanceId).to.equal(ecId!, `ecInstanceId mismatch for KoQ ${rKoq.fullName}`);\r\n }\r\n }\r\n\r\n // PropertyCategory\r\n const ecCatIds = new Map<string, number>();\r\n iModel.withSqliteStatement(\r\n \"SELECT pc.Id, s.Name, pc.Name FROM ec_PropertyCategory pc JOIN ec_Schema s ON pc.SchemaId=s.Id\",\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW)\r\n ecCatIds.set(`${stmt.getValueString(1).toLowerCase()}:${stmt.getValueString(2).toLowerCase()}`, stmt.getValueInteger(0));\r\n },\r\n );\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rCat of rSchema.getPropertyCategories()) {\r\n const key = `${rSchema.name.toLowerCase()}:${rCat.name.toLowerCase()}`;\r\n const ecId = ecCatIds.get(key);\r\n assert.isDefined(ecId, `ec_PropertyCategory row not found for ${rCat.fullName}`);\r\n expect(rCat.ecInstanceId).to.equal(ecId!, `ecInstanceId mismatch for category ${rCat.fullName}`);\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching enumerations\", () => {\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rEnum of rSchema.getEnumerations()) {\r\n const metaEnum = iModel.schemaContext.getSchemaItemSync(rSchema.name, rEnum.name) as Enumeration | undefined;\r\n assert.isDefined(metaEnum, `Enumeration '${rEnum.fullName}' not found in ecschema-metadata`);\r\n\r\n expect(rEnum.isStrict).to.equal(metaEnum!.isStrict, `isStrict mismatch for ${rEnum.fullName}`);\r\n\r\n // Compare enumerators\r\n const rEnumerators = [...rEnum.getEnumerators()];\r\n const metaEnumerators = metaEnum!.enumerators;\r\n expect(rEnumerators.length).to.equal(metaEnumerators.length,\r\n `enumerator count mismatch for ${rEnum.fullName}`);\r\n\r\n for (let i = 0; i < rEnumerators.length; i++) {\r\n expect(rEnumerators[i].name).to.equal(metaEnumerators[i].name,\r\n `enumerator name mismatch at index ${i} in ${rEnum.fullName}`);\r\n expect(rEnumerators[i].value).to.equal(metaEnumerators[i].value,\r\n `enumerator value mismatch for ${rEnumerators[i].name} in ${rEnum.fullName}`);\r\n }\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching KindOfQuantity items\", () => {\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rKoq of rSchema.getKindOfQuantities()) {\r\n const metaKoq = iModel.schemaContext.getSchemaItemSync(rSchema.name, rKoq.name) as KindOfQuantity | undefined;\r\n assert.isDefined(metaKoq, `KoQ '${rKoq.fullName}' not found in ecschema-metadata`);\r\n\r\n expect(rKoq.relativeError).to.equal(metaKoq!.relativeError,\r\n `relativeError mismatch for ${rKoq.fullName}`);\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching PropertyCategory items\", () => {\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rCat of rSchema.getPropertyCategories()) {\r\n const metaCat = iModel.schemaContext.getSchemaItemSync(rSchema.name, rCat.name) as PropertyCategory | undefined;\r\n assert.isDefined(metaCat, `PropertyCategory '${rCat.fullName}' not found in ecschema-metadata`);\r\n\r\n expect(rCat.priority).to.equal(metaCat!.priority,\r\n `priority mismatch for ${rCat.fullName}`);\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching relationship constraints\", () => {\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n if (!rClass.isRelationship())\r\n continue;\r\n\r\n const metaRel = iModel.schemaContext.getSchemaItemSync(rSchema.name, rClass.name) as RelationshipClass | undefined;\r\n assert.isDefined(metaRel, `Relationship '${rClass.fullName}' not in ecschema-metadata`);\r\n\r\n // Source constraint\r\n if (rClass.source !== undefined) {\r\n const metaSrc = metaRel!.source;\r\n if (metaSrc.abstractConstraint !== undefined && rClass.source.abstractConstraint !== undefined) {\r\n expect(rClass.source.abstractConstraint.name).to.equal(\r\n metaSrc.abstractConstraint.fullName.split(\".\").pop(),\r\n `source abstractConstraint mismatch for ${rClass.fullName}`,\r\n );\r\n }\r\n }\r\n\r\n // Target constraint\r\n if (rClass.target !== undefined) {\r\n const metaTgt = metaRel!.target;\r\n if (metaTgt.abstractConstraint !== undefined && rClass.target.abstractConstraint !== undefined) {\r\n expect(rClass.target.abstractConstraint.name).to.equal(\r\n metaTgt.abstractConstraint.fullName.split(\".\").pop(),\r\n `target abstractConstraint mismatch for ${rClass.fullName}`,\r\n );\r\n }\r\n }\r\n }\r\n }\r\n });\r\n\r\n it(\"should have matching IS-A relationships\", () => {\r\n // Pick a few well-known hierarchies and verify IS-A checks match\r\n const testPairs: Array<[string, string, boolean]> = [\r\n [\"BisCore:GeometricElement3d\", \"BisCore:Element\", true],\r\n [\"BisCore:Element\", \"BisCore:GeometricElement3d\", false],\r\n [\"BisCore:PhysicalElement\", \"BisCore:GeometricElement\", true],\r\n [\"BisCore:ModelContainsElements\", \"BisCore:ElementRefersToElements\", false],\r\n ];\r\n\r\n for (const [className, baseName, expected] of testPairs) {\r\n const rClass = schemaView.findClass(className);\r\n if (rClass === undefined)\r\n continue; // Class may not exist in minimal test iModels\r\n\r\n const result = rClass.is(baseName);\r\n expect(result).to.equal(expected, `IS-A check: ${className} -> ${baseName}`);\r\n }\r\n });\r\n\r\n it(\"should have matching isHidden flags against ec_CustomAttribute\", () => {\r\n // Build a set of property IDs that have CoreCustomAttributes:HiddenProperty CA\r\n // (without Show=True override), mirroring the C++ writer's CollectHiddenPropertyIds.\r\n const hiddenPropertyIds = new Set<number>();\r\n iModel.withSqliteStatement(\r\n `SELECT ca.ContainerId, ca.Instance\r\n FROM ec_CustomAttribute ca\r\n JOIN ec_Class cac ON ca.ClassId=cac.Id\r\n JOIN ec_Schema cas ON cac.SchemaId=cas.Id\r\n WHERE ca.ContainerType & 992 <> 0\r\n AND cas.Name='CoreCustomAttributes' AND cac.Name='HiddenProperty'`,\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW) {\r\n const instance: string = stmt.getValueString(1) ?? \"\";\r\n if (instance) {\r\n const lower = instance.toLowerCase();\r\n if (lower.includes(\">true</\"))\r\n continue; // Show=True means NOT hidden\r\n }\r\n hiddenPropertyIds.add(stmt.getValueInteger(0));\r\n }\r\n },\r\n );\r\n\r\n // Build a map of property ID -> (schemaName, className, propertyName) from ec_ tables\r\n // so we can correlate ec_ property IDs to SchemaView properties.\r\n const propIdMap = new Map<number, { schema: string; cls: string; prop: string }>();\r\n iModel.withSqliteStatement(\r\n `SELECT p.Id, s.Name, c.Name, p.Name\r\n FROM ec_Property p\r\n JOIN ec_Class c ON p.ClassId=c.Id\r\n JOIN ec_Schema s ON c.SchemaId=s.Id`,\r\n (stmt) => {\r\n while (stmt.step() === DbResult.BE_SQLITE_ROW) {\r\n propIdMap.set(stmt.getValueInteger(0), {\r\n schema: stmt.getValueString(1),\r\n cls: stmt.getValueString(2),\r\n prop: stmt.getValueString(3),\r\n });\r\n }\r\n },\r\n );\r\n\r\n // Cross-validate: for every hidden property in ec_ tables that belongs to a\r\n // non-excluded schema, the SchemaView must also mark it as hidden.\r\n let hiddenChecked = 0;\r\n for (const propId of hiddenPropertyIds) {\r\n const info = propIdMap.get(propId);\r\n if (info === undefined) continue;\r\n if (excludedSchemaViewSchemas.has(info.schema)) continue;\r\n\r\n const rClass = schemaView.findClass(`${info.schema}:${info.cls}`);\r\n if (rClass === undefined) continue;\r\n\r\n // Check own properties only (the property lives on this class)\r\n const rProp = rClass.getOwnProperties().find(\r\n (p) => p.name.toLowerCase() === info.prop.toLowerCase(),\r\n );\r\n if (rProp === undefined) continue; // property may have been dropped (broken struct ref)\r\n\r\n expect(rProp.isHidden).to.equal(true,\r\n `${info.schema}:${info.cls}.${info.prop} should be hidden (has HiddenProperty CA)`);\r\n hiddenChecked++;\r\n }\r\n\r\n // Also spot-check that explicitly visible properties are NOT hidden.\r\n // Walk a subset of SchemaView classes and verify that properties not in the hidden set\r\n // are marked as not hidden.\r\n let visibleChecked = 0;\r\n for (const rSchema of schemaView.getSchemas()) {\r\n for (const rClass of rSchema.getClasses()) {\r\n for (const rProp of rClass.getOwnProperties()) {\r\n // Find the ec_ property ID for this prop\r\n const matchingEntry = [...propIdMap.entries()].find(([_, info]) =>\r\n info.schema.toLowerCase() === rSchema.name.toLowerCase()\r\n && info.cls.toLowerCase() === rClass.name.toLowerCase()\r\n && info.prop.toLowerCase() === rProp.name.toLowerCase(),\r\n );\r\n if (matchingEntry === undefined) continue;\r\n const [propId] = matchingEntry;\r\n\r\n if (!hiddenPropertyIds.has(propId)) {\r\n expect(rProp.isHidden).to.equal(false,\r\n `${rClass.fullName}.${rProp.name} should NOT be hidden (no HiddenProperty CA)`);\r\n visibleChecked++;\r\n }\r\n }\r\n if (visibleChecked >= 200) break; // cap to keep test fast\r\n }\r\n if (visibleChecked >= 200) break;\r\n }\r\n\r\n // The test.bim likely has at least some non-hidden properties\r\n assert.isAbove(visibleChecked, 0, \"No visible properties checked - test setup issue\");\r\n assert.isAbove(hiddenChecked, 0, \"No hidden properties checked - test setup issue\");\r\n });\r\n });\r\n }\r\n});\r\n\r\n// --- Helper functions ---\r\n\r\n/** Map ecschema-metadata SchemaItemType to SchemaView ClassType. */\r\nfunction schemaItemTypeToClassType(itemType: SchemaItemType, ecClass: ECClass): ClassType {\r\n switch (itemType) {\r\n case SchemaItemType.EntityClass:\r\n // ecschema-metadata distinguishes Mixin via instanceof, not SchemaItemType\r\n return (ecClass instanceof Mixin) ? ClassType.Mixin : ClassType.Entity;\r\n case SchemaItemType.Mixin:\r\n return ClassType.Mixin;\r\n case SchemaItemType.RelationshipClass:\r\n return ClassType.Relationship;\r\n case SchemaItemType.StructClass:\r\n return ClassType.Struct;\r\n case SchemaItemType.CustomAttributeClass:\r\n return ClassType.CustomAttribute;\r\n default:\r\n assert.fail(`Unexpected SchemaItemType '${itemType}' for class '${ecClass.fullName}'`);\r\n }\r\n}\r\n\r\n/** Map ecschema-metadata ECClassModifier to SchemaView ClassModifier. */\r\nfunction ecModifierToClassModifier(modifier: ECClassModifier): ClassModifier {\r\n switch (modifier) {\r\n case ECClassModifier.None: return ClassModifier.None;\r\n case ECClassModifier.Abstract: return ClassModifier.Abstract;\r\n case ECClassModifier.Sealed: return ClassModifier.Sealed;\r\n default: return ClassModifier.None;\r\n }\r\n}\r\n\r\n/** Compare a single property across both layers. */\r\nfunction compareProperty(rProp: ReturnType<SchemaView.Class[\"getProperties\"]>[number], metaProp: Property, rClass: SchemaView.Class): void {\r\n const ctx = `${rClass.fullName}.${rProp.name}`;\r\n\r\n // Name\r\n expect(rProp.name.toLowerCase()).to.equal(metaProp.name.toLowerCase(), `name mismatch for ${ctx}`);\r\n\r\n // Kind discriminators (methods, not getters - they are real type predicates)\r\n expect(rProp.isPrimitive()).to.equal(metaProp.isPrimitive(), `isPrimitive mismatch for ${ctx}`);\r\n expect(rProp.isNavigation()).to.equal(metaProp.isNavigation(), `isNavigation mismatch for ${ctx}`);\r\n expect(rProp.isArray()).to.equal(metaProp.isArray(), `isArray mismatch for ${ctx}`);\r\n\r\n // For primitives and enums: check primitiveType and extendedTypeName\r\n if (rProp.isPrimitive()) {\r\n // Cast to PrimitiveProperty for field access - ecschema-metadata's type hierarchy\r\n // doesn't model enum-as-primitive correctly (see itwinjs-core#8448), but the fields exist at runtime.\r\n const metaPrimProp = metaProp as unknown as PrimitiveProperty;\r\n if (metaPrimProp.primitiveType !== undefined) {\r\n // SchemaViewPrimitiveType values match PrimitiveType values\r\n expect(rProp.primitiveType).to.equal(metaPrimProp.primitiveType,\r\n `primitiveType mismatch for ${ctx}: schemaView=0x${rProp.primitiveType.toString(16)}, meta=0x${metaPrimProp.primitiveType.toString(16)}`);\r\n }\r\n if (metaPrimProp.extendedTypeName !== undefined) {\r\n expect(rProp.extendedTypeName?.toLowerCase()).to.equal(metaPrimProp.extendedTypeName.toLowerCase(),\r\n `extendedTypeName mismatch for ${ctx}`);\r\n }\r\n\r\n // KindOfQuantity reference (only on primitive properties)\r\n expect(rProp.kindOfQuantity?.name).to.equal(metaProp.getKindOfQuantitySync()?.name, `KoQ mismatch for ${ctx}`);\r\n }\r\n\r\n // isReadOnly\r\n expect(rProp.isReadOnly).to.equal(metaProp.isReadOnly, `isReadOnly mismatch for ${ctx}`);\r\n\r\n // Struct class reference - structClass is non-nullable on struct subclasses\r\n if (rProp.isStruct()) {\r\n const metaStruct = metaProp as StructProperty;\r\n expect(rProp.structClass.name).to.equal(metaStruct.structClass.name, `structClass mismatch for ${ctx}`);\r\n }\r\n\r\n // Navigation property: direction and relationship class\r\n if (rProp.isNavigation()) {\r\n const metaNav = metaProp as NavigationProperty;\r\n expect(rProp.direction).to.equal(metaNav.direction, `direction mismatch for ${ctx}`);\r\n\r\n const metaRelClass = metaNav.getRelationshipClassSync();\r\n if (metaRelClass !== undefined) {\r\n expect(rProp.relationshipClass.name).to.equal(metaRelClass.name,\r\n `nav relationshipClass mismatch for ${ctx}`);\r\n }\r\n }\r\n\r\n // Category reference (available on all property kinds)\r\n expect(rProp.category?.name).to.equal(metaProp.getCategorySync()?.name, `category mismatch for ${ctx}`);\r\n}\r\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SettingsContainers.test.d.ts","sourceRoot":"","sources":["../../../../src/test/workspace/SettingsContainers.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { expect } from "chai";
|
|
6
|
+
import * as sinon from "sinon";
|
|
7
|
+
import { BlobContainer } from "../../BlobContainerService";
|
|
8
|
+
import { IModelHost } from "../../IModelHost";
|
|
9
|
+
import { SettingsPriority } from "../../workspace/Settings";
|
|
10
|
+
import { SettingsContainers } from "../../workspace/SettingsEditor";
|
|
11
|
+
const projectId = "11111111-1111-4111-8111-111111111111";
|
|
12
|
+
const accountId = "22222222-2222-4222-8222-222222222222";
|
|
13
|
+
const metadata = (containerId, iTwinId = projectId, iModelId) => ({
|
|
14
|
+
containerId, iTwinId, iModelId, accountITwinId: accountId, containerType: "settings", label: containerId,
|
|
15
|
+
});
|
|
16
|
+
const projectRoot = metadata("project-root");
|
|
17
|
+
const accountRoot = metadata("account-root", accountId);
|
|
18
|
+
const iModels = [metadata("iModel-a", projectId, "iModel-a-id"), metadata("iModel-b", projectId, "iModel-b-id")];
|
|
19
|
+
describe("SettingsContainers root discovery", () => {
|
|
20
|
+
let savedService;
|
|
21
|
+
let query;
|
|
22
|
+
let requestToken;
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
savedService = BlobContainer.service;
|
|
25
|
+
sinon.stub(IModelHost, "getAccessToken").resolves("test-token");
|
|
26
|
+
query = sinon.stub();
|
|
27
|
+
requestToken = sinon.stub().callsFake(async ({ containerId }) => ({
|
|
28
|
+
token: "read-token", baseUri: "https://example.test", provider: "azure", containerId,
|
|
29
|
+
}));
|
|
30
|
+
BlobContainer.service = {
|
|
31
|
+
create: sinon.stub(), delete: sinon.stub(), queryScope: sinon.stub(), queryMetadata: sinon.stub(),
|
|
32
|
+
queryContainersMetadata: query, updateJson: sinon.stub(), requestToken,
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
BlobContainer.service = savedService;
|
|
37
|
+
sinon.restore();
|
|
38
|
+
});
|
|
39
|
+
for (const { name, containers, expected } of [
|
|
40
|
+
{ name: "project root and iModel containers", containers: [projectRoot, ...iModels], expected: "project-root" },
|
|
41
|
+
{ name: "a sole iModel container without a project root", containers: iModels.slice(0, 1), expected: undefined },
|
|
42
|
+
{ name: "iModel containers without a project root", containers: iModels, expected: undefined },
|
|
43
|
+
]) {
|
|
44
|
+
it(`selects only the project root for write lookup with ${name}`, async () => {
|
|
45
|
+
query.resolves(containers);
|
|
46
|
+
expect(await SettingsContainers.getITwinContainerId(projectId)).to.equal(expected);
|
|
47
|
+
expect(query.calledOnceWithExactly("test-token", { iTwinId: projectId, containerType: "settings" })).to.be.true;
|
|
48
|
+
expect(requestToken.called).to.be.false;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
for (const { name, containers, expected } of [
|
|
52
|
+
{ name: "project root and iModel containers", containers: [projectRoot, ...iModels], expected: ["project-root"] },
|
|
53
|
+
{ name: "a sole iModel container without a project root", containers: iModels.slice(0, 1), expected: [] },
|
|
54
|
+
{ name: "iModel containers without a project root", containers: iModels, expected: [] },
|
|
55
|
+
{
|
|
56
|
+
name: "organization root, project root and iModel containers",
|
|
57
|
+
containers: [projectRoot, ...iModels, accountRoot, metadata("account-iModel", accountId, "account-iModel-id")],
|
|
58
|
+
expected: ["project-root", "account-root"],
|
|
59
|
+
},
|
|
60
|
+
]) {
|
|
61
|
+
it(`selects only roots for read discovery with ${name}`, async () => {
|
|
62
|
+
query.resolves(containers);
|
|
63
|
+
const sources = await SettingsContainers.getITwinSettingsSources(projectId);
|
|
64
|
+
expect(sources?.map((source) => source.containerId) ?? []).to.deep.equal(expected);
|
|
65
|
+
expect(requestToken.getCalls().map((call) => call.args[0].containerId)).to.deep.equal(expected);
|
|
66
|
+
if (expected.length === 0)
|
|
67
|
+
expect(sources).to.be.undefined;
|
|
68
|
+
else
|
|
69
|
+
expect(sources?.map((source) => source.priority)).to.deep.equal(expected.map((id) => id === "account-root" ? SettingsPriority.organization : SettingsPriority.iTwin));
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
it("still rejects duplicate project roots for write lookup and read discovery", async () => {
|
|
73
|
+
query.resolves([projectRoot, ...iModels, metadata("duplicate-root")]);
|
|
74
|
+
for (const discover of [SettingsContainers.getITwinContainerId, SettingsContainers.getITwinSettingsSources]) {
|
|
75
|
+
try {
|
|
76
|
+
await discover(projectId);
|
|
77
|
+
expect.fail("Duplicate roots must be rejected");
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
expect(error.message).to.include("Multiple iTwin settings containers");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
it("still rejects duplicate organization roots for read discovery", async () => {
|
|
85
|
+
query.resolves([accountRoot, metadata("duplicate-account-root", accountId), ...iModels]);
|
|
86
|
+
try {
|
|
87
|
+
await SettingsContainers.getITwinSettingsSources(projectId);
|
|
88
|
+
expect.fail("Duplicate organization roots must be rejected");
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
expect(error.message).to.include("Multiple iTwin settings containers");
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=SettingsContainers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SettingsContainers.test.js","sourceRoot":"","sources":["../../../../src/test/workspace/SettingsContainers.test.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\r\nimport { expect } from \"chai\";\r\nimport * as sinon from \"sinon\";\r\nimport { BlobContainer } from \"../../BlobContainerService\";\r\nimport { IModelHost } from \"../../IModelHost\";\r\nimport { SettingsPriority } from \"../../workspace/Settings\";\r\nimport { SettingsContainers } from \"../../workspace/SettingsEditor\";\r\n\r\nconst projectId = \"11111111-1111-4111-8111-111111111111\";\r\nconst accountId = \"22222222-2222-4222-8222-222222222222\";\r\nconst metadata = (containerId: string, iTwinId = projectId, iModelId?: string) => ({\r\n containerId, iTwinId, iModelId, accountITwinId: accountId, containerType: \"settings\", label: containerId,\r\n});\r\nconst projectRoot = metadata(\"project-root\");\r\nconst accountRoot = metadata(\"account-root\", accountId);\r\nconst iModels = [metadata(\"iModel-a\", projectId, \"iModel-a-id\"), metadata(\"iModel-b\", projectId, \"iModel-b-id\")];\r\n\r\ndescribe(\"SettingsContainers root discovery\", () => {\r\n let savedService: BlobContainer.ContainerService | undefined;\r\n let query: sinon.SinonStub;\r\n let requestToken: sinon.SinonStub;\r\n\r\n beforeEach(() => {\r\n savedService = BlobContainer.service;\r\n sinon.stub(IModelHost, \"getAccessToken\").resolves(\"test-token\");\r\n query = sinon.stub();\r\n requestToken = sinon.stub().callsFake(async ({ containerId }) => ({\r\n token: \"read-token\", baseUri: \"https://example.test\", provider: \"azure\", containerId,\r\n }));\r\n BlobContainer.service = {\r\n create: sinon.stub(), delete: sinon.stub(), queryScope: sinon.stub(), queryMetadata: sinon.stub(),\r\n queryContainersMetadata: query, updateJson: sinon.stub(), requestToken,\r\n };\r\n });\r\n\r\n afterEach(() => {\r\n BlobContainer.service = savedService;\r\n sinon.restore();\r\n });\r\n\r\n for (const { name, containers, expected } of [\r\n { name: \"project root and iModel containers\", containers: [projectRoot, ...iModels], expected: \"project-root\" },\r\n { name: \"a sole iModel container without a project root\", containers: iModels.slice(0, 1), expected: undefined },\r\n { name: \"iModel containers without a project root\", containers: iModels, expected: undefined },\r\n ]) {\r\n it(`selects only the project root for write lookup with ${name}`, async () => {\r\n query.resolves(containers);\r\n expect(await SettingsContainers.getITwinContainerId(projectId)).to.equal(expected);\r\n expect(query.calledOnceWithExactly(\"test-token\", { iTwinId: projectId, containerType: \"settings\" })).to.be.true;\r\n expect(requestToken.called).to.be.false;\r\n });\r\n }\r\n\r\n for (const { name, containers, expected } of [\r\n { name: \"project root and iModel containers\", containers: [projectRoot, ...iModels], expected: [\"project-root\"] },\r\n { name: \"a sole iModel container without a project root\", containers: iModels.slice(0, 1), expected: [] },\r\n { name: \"iModel containers without a project root\", containers: iModels, expected: [] },\r\n {\r\n name: \"organization root, project root and iModel containers\",\r\n containers: [projectRoot, ...iModels, accountRoot, metadata(\"account-iModel\", accountId, \"account-iModel-id\")],\r\n expected: [\"project-root\", \"account-root\"],\r\n },\r\n ]) {\r\n it(`selects only roots for read discovery with ${name}`, async () => {\r\n query.resolves(containers);\r\n const sources = await SettingsContainers.getITwinSettingsSources(projectId);\r\n expect(sources?.map((source) => source.containerId) ?? []).to.deep.equal(expected);\r\n expect(requestToken.getCalls().map((call) => call.args[0].containerId)).to.deep.equal(expected);\r\n if (expected.length === 0)\r\n expect(sources).to.be.undefined;\r\n else\r\n expect(sources?.map((source) => source.priority)).to.deep.equal(expected.map((id) => id === \"account-root\" ? SettingsPriority.organization : SettingsPriority.iTwin));\r\n });\r\n }\r\n\r\n it(\"still rejects duplicate project roots for write lookup and read discovery\", async () => {\r\n query.resolves([projectRoot, ...iModels, metadata(\"duplicate-root\")]);\r\n for (const discover of [SettingsContainers.getITwinContainerId, SettingsContainers.getITwinSettingsSources]) {\r\n try {\r\n await discover(projectId);\r\n expect.fail(\"Duplicate roots must be rejected\");\r\n } catch (error) {\r\n expect((error as Error).message).to.include(\"Multiple iTwin settings containers\");\r\n }\r\n }\r\n });\r\n\r\n it(\"still rejects duplicate organization roots for read discovery\", async () => {\r\n query.resolves([accountRoot, metadata(\"duplicate-account-root\", accountId), ...iModels]);\r\n try {\r\n await SettingsContainers.getITwinSettingsSources(projectId);\r\n expect.fail(\"Duplicate organization roots must be rejected\");\r\n } catch (error) {\r\n expect((error as Error).message).to.include(\"Multiple iTwin settings containers\");\r\n }\r\n });\r\n});\r\n"]}
|
|
@@ -41,9 +41,10 @@ export declare namespace SettingsEditor {
|
|
|
41
41
|
*/
|
|
42
42
|
export declare namespace SettingsContainers {
|
|
43
43
|
/**
|
|
44
|
-
* Query the [[BlobContainer]] service for the
|
|
45
|
-
*
|
|
46
|
-
* @
|
|
44
|
+
* Query the [[BlobContainer]] service for the iTwin-root settings container associated with a given iTwin.
|
|
45
|
+
* Only containers without an iModelId in their query metadata are considered.
|
|
46
|
+
* @returns The containerId, or `undefined` if no matching container is found.
|
|
47
|
+
* @throws if more than one matching container is found.
|
|
47
48
|
*/
|
|
48
49
|
function getITwinContainerId(iTwinId: GuidString): Promise<WorkspaceContainerId | undefined>;
|
|
49
50
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsEditor.d.ts","sourceRoot":"","sources":["../../../src/workspace/SettingsEditor.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAI7E,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIhF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD,gBAAgB;AAChB,yBAAiB,cAAc,CAAC;IAC9B,8DAA8D;IACvD,MAAM,aAAa,aAAa,CAAC;IAExC;;;;OAIG;IACH,SAAsB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,0BAA0B,CAAA;KAAE,CAAC,CAExI;IAED;;;;;OAKG;IACH,SAAsB,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,0BAA0B,CAAA;KAAE,GAAG,SAAS,CAAC,CAE9I;CACF;AAED;;;GAGG;AACH,yBAAiB,kBAAkB,CAAC;IAclC
|
|
1
|
+
{"version":3,"file":"SettingsEditor.d.ts","sourceRoot":"","sources":["../../../src/workspace/SettingsEditor.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAI7E,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIhF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD,gBAAgB;AAChB,yBAAiB,cAAc,CAAC;IAC9B,8DAA8D;IACvD,MAAM,aAAa,aAAa,CAAC;IAExC;;;;OAIG;IACH,SAAsB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,0BAA0B,CAAA;KAAE,CAAC,CAExI;IAED;;;;;OAKG;IACH,SAAsB,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,0BAA0B,CAAA;KAAE,GAAG,SAAS,CAAC,CAE9I;CACF;AAED;;;GAGG;AACH,yBAAiB,kBAAkB,CAAC;IAclC;;;;;OAKG;IACH,SAAsB,mBAAmB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CASxG;IAED;;;;;;;OAOG;IACH,SAAsB,uBAAuB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,wBAAwB,EAAE,GAAG,SAAS,CAAC,CAyClH;CACF"}
|
|
@@ -61,12 +61,13 @@ export var SettingsContainers;
|
|
|
61
61
|
return BlobContainer.service.queryContainersMetadata(userToken, { ...args, containerType: SettingsEditor.containerType });
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
64
|
-
* Query the [[BlobContainer]] service for the
|
|
65
|
-
*
|
|
66
|
-
* @
|
|
64
|
+
* Query the [[BlobContainer]] service for the iTwin-root settings container associated with a given iTwin.
|
|
65
|
+
* Only containers without an iModelId in their query metadata are considered.
|
|
66
|
+
* @returns The containerId, or `undefined` if no matching container is found.
|
|
67
|
+
* @throws if more than one matching container is found.
|
|
67
68
|
*/
|
|
68
69
|
async function getITwinContainerId(iTwinId) {
|
|
69
|
-
const containers = await queryContainers({ iTwinId });
|
|
70
|
+
const containers = (await queryContainers({ iTwinId })).filter((container) => undefined === container.iModelId);
|
|
70
71
|
if (containers.length > 1) {
|
|
71
72
|
ITwinSettingsError.throwError("multiple-itwin-settings-containers", {
|
|
72
73
|
message: `Multiple iTwin settings containers were found for '${iTwinId}', so a container cannot be automatically selected.`,
|
|
@@ -88,7 +89,8 @@ export var SettingsContainers;
|
|
|
88
89
|
if (undefined === BlobContainer.service)
|
|
89
90
|
ITwinSettingsError.throwError("blob-service-unavailable", { message: "BlobContainer.service is not available." });
|
|
90
91
|
const userToken = await IModelHost.getAccessToken();
|
|
91
|
-
const containers = await queryContainers({ iTwinId, includeParentITwins: { filter: "accountOnly" } })
|
|
92
|
+
const containers = (await queryContainers({ iTwinId, includeParentITwins: { filter: "accountOnly" } }))
|
|
93
|
+
.filter((container) => undefined === container.iModelId);
|
|
92
94
|
if (containers.length === 0)
|
|
93
95
|
return undefined;
|
|
94
96
|
const seenITwins = new Set();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsEditor.js","sourceRoot":"","sources":["../../../src/workspace/SettingsEditor.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 { ITwinSettingsError } from \"@itwin/core-common\";\r\nimport { GuidString } from \"@itwin/core-bentley\";\r\nimport { WorkspaceContainerId, WorkspaceDbSettingsProps } from \"./Workspace\";\r\nimport { BlobContainer } from \"../BlobContainerService\";\r\nimport { IModelHost } from \"../IModelHost\";\r\nimport { constructSettingsEditorForITwin, getSettingsEditorForITwin } from \"../internal/workspace/SettingsEditorImpl\";\r\nimport { EditableWorkspaceContainer, WorkspaceEditor } from \"./WorkspaceEditor\";\r\nimport { SettingsPriority } from \"./Settings\";\r\nimport { settingsWorkspaceDbName } from \"./SettingsDb\";\r\n\r\n/** The default resource name used to store settings in a [[WorkspaceDb]].\r\n * This is the key under which all settings are stored in the SQLite `strings` table.\r\n * When loading settings at runtime via [[Workspace.loadSettingsDictionary]], the `resourceName` defaults\r\n * to this value, ensuring the read and write paths always agree on which key to use.\r\n * @internal\r\n */\r\nexport const settingsResourceName = \"settingsDictionary\";\r\n\r\n/** @internal */\r\nexport namespace SettingsEditor {\r\n /** The type of workspace container used to store settings. */\r\n export const containerType = \"settings\";\r\n\r\n /**\r\n * Create a new [[SettingsEditor]] for creating new versions of [[SettingsDb]]s.\r\n * @note The caller becomes the owner of the SettingsEditor and is responsible for calling [[SettingsEditor.close]] on it when finished.\r\n * @note It is illegal to have more than one SettingsEditor active in a single session.\r\n */\r\n export async function constructForITwin(iTwinId: GuidString): Promise<{ editor: WorkspaceEditor; container: EditableWorkspaceContainer }> {\r\n return constructSettingsEditorForITwin(iTwinId);\r\n }\r\n\r\n /**\r\n * Obtain a [[SettingsEditor]] for the existing settings container associated with an iTwin.\r\n * @returns The editor and container, or `undefined` if no settings container exists for the iTwin.\r\n * @note The caller becomes the owner of the SettingsEditor and is responsible for calling [[SettingsEditor.close]] on it when finished.\r\n * @note It is illegal to have more than one SettingsEditor active in a single session.\r\n */\r\n export async function getForITwin(iTwinId: GuidString): Promise<{ editor: WorkspaceEditor; container: EditableWorkspaceContainer } | undefined> {\r\n return getSettingsEditorForITwin(iTwinId);\r\n }\r\n}\r\n\r\n/**\r\n * Help locate and obtain access to known containers with type \"settings\".\r\n * @internal\r\n */\r\nexport namespace SettingsContainers {\r\n /**\r\n * Query the [[BlobContainer]] service for all settings containers associated with a given iTwin.\r\n * Automatically filters by `containerType: \"settings\"`.\r\n * @note Requires [[IModelHost.authorizationClient]] to be configured.\r\n */\r\n async function queryContainers(args: BlobContainer.QueryContainerProps): Promise<BlobContainer.MetadataResponse[]> {\r\n if (undefined === BlobContainer.service)\r\n ITwinSettingsError.throwError(\"blob-service-unavailable\", { message: \"BlobContainer.service is not available.\" });\r\n\r\n const userToken = await IModelHost.getAccessToken();\r\n return BlobContainer.service.queryContainersMetadata(userToken, { ...args, containerType: SettingsEditor.containerType });\r\n }\r\n\r\n /**\r\n * Query the [[BlobContainer]] service for the single settings container associated with a given iTwin.\r\n * @returns The containerId, or `undefined` if no container exists.\r\n * @throws if more than one settings container is found.\r\n */\r\n export async function getITwinContainerId(iTwinId: GuidString): Promise<WorkspaceContainerId | undefined> {\r\n const containers = await queryContainers({ iTwinId });\r\n if (containers.length > 1) {\r\n ITwinSettingsError.throwError(\"multiple-itwin-settings-containers\", {\r\n message: `Multiple iTwin settings containers were found for '${iTwinId}', so a container cannot be automatically selected.`,\r\n iTwinId,\r\n });\r\n }\r\n return containers[0]?.containerId;\r\n }\r\n\r\n /**\r\n * Look up settings containers for an iTwin and its account iTwin and obtain read-only access tokens.\r\n * @returns Container props needed by [[IModelHost.getITwinWorkspace]]. The requested iTwin's settings\r\n * container is returned at [[SettingsPriority.iTwin]]; the account iTwin container is returned at\r\n * [[SettingsPriority.organization]].\r\n * @note Requires [[IModelHost.authorizationClient]] to be configured.\r\n * @note Requires [[BlobContainer.service]] to be configured.\r\n */\r\n export async function getITwinSettingsSources(iTwinId: GuidString): Promise<WorkspaceDbSettingsProps[] | undefined> {\r\n if (undefined === BlobContainer.service)\r\n ITwinSettingsError.throwError(\"blob-service-unavailable\", { message: \"BlobContainer.service is not available.\" });\r\n\r\n const userToken = await IModelHost.getAccessToken();\r\n const containers = await queryContainers({ iTwinId, includeParentITwins: { filter: \"accountOnly\" } });\r\n if (containers.length === 0) return undefined;\r\n\r\n const seenITwins = new Set<string>();\r\n const results: WorkspaceDbSettingsProps[] = [];\r\n for (const container of containers) {\r\n const ownerITwinId = container.iTwinId;\r\n if (undefined === ownerITwinId) {\r\n ITwinSettingsError.throwError(\"missing-container-itwinid\", {\r\n message: `Settings container '${container.containerId}' has no iTwinId. Please upgrade to a newer version of the BlobContainer service that populates iTwinId in query results.`,\r\n iTwinId,\r\n });\r\n }\r\n if (seenITwins.has(ownerITwinId)) {\r\n ITwinSettingsError.throwError(\"multiple-itwin-settings-containers\", {\r\n message: `Multiple iTwin settings containers were found for '${ownerITwinId}', so a container cannot be automatically selected.`,\r\n iTwinId: ownerITwinId,\r\n });\r\n }\r\n seenITwins.add(ownerITwinId);\r\n\r\n const priority = container.accountITwinId === ownerITwinId ? SettingsPriority.organization : SettingsPriority.iTwin;\r\n const tokenProps = await BlobContainer.service.requestToken({ containerId: container.containerId, accessLevel: \"read\", userToken });\r\n results.push({\r\n baseUri: tokenProps.baseUri,\r\n containerId: container.containerId,\r\n storageType: tokenProps.provider,\r\n accessToken: tokenProps.token,\r\n priority,\r\n dbName: settingsWorkspaceDbName,\r\n includePrerelease: true,\r\n });\r\n }\r\n\r\n return results;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"SettingsEditor.js","sourceRoot":"","sources":["../../../src/workspace/SettingsEditor.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 { ITwinSettingsError } from \"@itwin/core-common\";\r\nimport { GuidString } from \"@itwin/core-bentley\";\r\nimport { WorkspaceContainerId, WorkspaceDbSettingsProps } from \"./Workspace\";\r\nimport { BlobContainer } from \"../BlobContainerService\";\r\nimport { IModelHost } from \"../IModelHost\";\r\nimport { constructSettingsEditorForITwin, getSettingsEditorForITwin } from \"../internal/workspace/SettingsEditorImpl\";\r\nimport { EditableWorkspaceContainer, WorkspaceEditor } from \"./WorkspaceEditor\";\r\nimport { SettingsPriority } from \"./Settings\";\r\nimport { settingsWorkspaceDbName } from \"./SettingsDb\";\r\n\r\n/** The default resource name used to store settings in a [[WorkspaceDb]].\r\n * This is the key under which all settings are stored in the SQLite `strings` table.\r\n * When loading settings at runtime via [[Workspace.loadSettingsDictionary]], the `resourceName` defaults\r\n * to this value, ensuring the read and write paths always agree on which key to use.\r\n * @internal\r\n */\r\nexport const settingsResourceName = \"settingsDictionary\";\r\n\r\n/** @internal */\r\nexport namespace SettingsEditor {\r\n /** The type of workspace container used to store settings. */\r\n export const containerType = \"settings\";\r\n\r\n /**\r\n * Create a new [[SettingsEditor]] for creating new versions of [[SettingsDb]]s.\r\n * @note The caller becomes the owner of the SettingsEditor and is responsible for calling [[SettingsEditor.close]] on it when finished.\r\n * @note It is illegal to have more than one SettingsEditor active in a single session.\r\n */\r\n export async function constructForITwin(iTwinId: GuidString): Promise<{ editor: WorkspaceEditor; container: EditableWorkspaceContainer }> {\r\n return constructSettingsEditorForITwin(iTwinId);\r\n }\r\n\r\n /**\r\n * Obtain a [[SettingsEditor]] for the existing settings container associated with an iTwin.\r\n * @returns The editor and container, or `undefined` if no settings container exists for the iTwin.\r\n * @note The caller becomes the owner of the SettingsEditor and is responsible for calling [[SettingsEditor.close]] on it when finished.\r\n * @note It is illegal to have more than one SettingsEditor active in a single session.\r\n */\r\n export async function getForITwin(iTwinId: GuidString): Promise<{ editor: WorkspaceEditor; container: EditableWorkspaceContainer } | undefined> {\r\n return getSettingsEditorForITwin(iTwinId);\r\n }\r\n}\r\n\r\n/**\r\n * Help locate and obtain access to known containers with type \"settings\".\r\n * @internal\r\n */\r\nexport namespace SettingsContainers {\r\n /**\r\n * Query the [[BlobContainer]] service for all settings containers associated with a given iTwin.\r\n * Automatically filters by `containerType: \"settings\"`.\r\n * @note Requires [[IModelHost.authorizationClient]] to be configured.\r\n */\r\n async function queryContainers(args: BlobContainer.QueryContainerProps): Promise<BlobContainer.MetadataResponse[]> {\r\n if (undefined === BlobContainer.service)\r\n ITwinSettingsError.throwError(\"blob-service-unavailable\", { message: \"BlobContainer.service is not available.\" });\r\n\r\n const userToken = await IModelHost.getAccessToken();\r\n return BlobContainer.service.queryContainersMetadata(userToken, { ...args, containerType: SettingsEditor.containerType });\r\n }\r\n\r\n /**\r\n * Query the [[BlobContainer]] service for the iTwin-root settings container associated with a given iTwin.\r\n * Only containers without an iModelId in their query metadata are considered.\r\n * @returns The containerId, or `undefined` if no matching container is found.\r\n * @throws if more than one matching container is found.\r\n */\r\n export async function getITwinContainerId(iTwinId: GuidString): Promise<WorkspaceContainerId | undefined> {\r\n const containers = (await queryContainers({ iTwinId })).filter((container) => undefined === container.iModelId);\r\n if (containers.length > 1) {\r\n ITwinSettingsError.throwError(\"multiple-itwin-settings-containers\", {\r\n message: `Multiple iTwin settings containers were found for '${iTwinId}', so a container cannot be automatically selected.`,\r\n iTwinId,\r\n });\r\n }\r\n return containers[0]?.containerId;\r\n }\r\n\r\n /**\r\n * Look up settings containers for an iTwin and its account iTwin and obtain read-only access tokens.\r\n * @returns Container props needed by [[IModelHost.getITwinWorkspace]]. The requested iTwin's settings\r\n * container is returned at [[SettingsPriority.iTwin]]; the account iTwin container is returned at\r\n * [[SettingsPriority.organization]].\r\n * @note Requires [[IModelHost.authorizationClient]] to be configured.\r\n * @note Requires [[BlobContainer.service]] to be configured.\r\n */\r\n export async function getITwinSettingsSources(iTwinId: GuidString): Promise<WorkspaceDbSettingsProps[] | undefined> {\r\n if (undefined === BlobContainer.service)\r\n ITwinSettingsError.throwError(\"blob-service-unavailable\", { message: \"BlobContainer.service is not available.\" });\r\n\r\n const userToken = await IModelHost.getAccessToken();\r\n const containers = (await queryContainers({ iTwinId, includeParentITwins: { filter: \"accountOnly\" } }))\r\n .filter((container) => undefined === container.iModelId);\r\n if (containers.length === 0) return undefined;\r\n\r\n const seenITwins = new Set<string>();\r\n const results: WorkspaceDbSettingsProps[] = [];\r\n for (const container of containers) {\r\n const ownerITwinId = container.iTwinId;\r\n if (undefined === ownerITwinId) {\r\n ITwinSettingsError.throwError(\"missing-container-itwinid\", {\r\n message: `Settings container '${container.containerId}' has no iTwinId. Please upgrade to a newer version of the BlobContainer service that populates iTwinId in query results.`,\r\n iTwinId,\r\n });\r\n }\r\n if (seenITwins.has(ownerITwinId)) {\r\n ITwinSettingsError.throwError(\"multiple-itwin-settings-containers\", {\r\n message: `Multiple iTwin settings containers were found for '${ownerITwinId}', so a container cannot be automatically selected.`,\r\n iTwinId: ownerITwinId,\r\n });\r\n }\r\n seenITwins.add(ownerITwinId);\r\n\r\n const priority = container.accountITwinId === ownerITwinId ? SettingsPriority.organization : SettingsPriority.iTwin;\r\n const tokenProps = await BlobContainer.service.requestToken({ containerId: container.containerId, accessLevel: \"read\", userToken });\r\n results.push({\r\n baseUri: tokenProps.baseUri,\r\n containerId: container.containerId,\r\n storageType: tokenProps.provider,\r\n accessToken: tokenProps.token,\r\n priority,\r\n dbName: settingsWorkspaceDbName,\r\n includePrerelease: true,\r\n });\r\n }\r\n\r\n return results;\r\n }\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/core-backend",
|
|
3
|
-
"version": "5.15.0-dev.
|
|
3
|
+
"version": "5.15.0-dev.19",
|
|
4
4
|
"description": "iTwin.js backend components",
|
|
5
5
|
"main": "lib/cjs/core-backend.js",
|
|
6
6
|
"module": "lib/esm/core-backend.js",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"@opentelemetry/api": "^1.0.4",
|
|
30
|
-
"@itwin/core-
|
|
31
|
-
"@itwin/core-
|
|
32
|
-
"@itwin/core-
|
|
33
|
-
"@itwin/
|
|
34
|
-
"@itwin/
|
|
30
|
+
"@itwin/core-quantity": "5.15.0-dev.19",
|
|
31
|
+
"@itwin/core-bentley": "5.15.0-dev.19",
|
|
32
|
+
"@itwin/core-common": "5.15.0-dev.19",
|
|
33
|
+
"@itwin/ecschema-metadata": "5.15.0-dev.19",
|
|
34
|
+
"@itwin/core-geometry": "5.15.0-dev.19"
|
|
35
35
|
},
|
|
36
36
|
"peerDependenciesMeta": {
|
|
37
37
|
"@opentelemetry/api": {
|
|
@@ -72,18 +72,18 @@
|
|
|
72
72
|
"marked": "^14.1.3",
|
|
73
73
|
"sql-formatter": "^15.4.6",
|
|
74
74
|
"vite": "^6.4.4",
|
|
75
|
-
"@itwin/build-tools": "5.15.0-dev.
|
|
76
|
-
"@itwin/core-bentley": "5.15.0-dev.
|
|
77
|
-
"@itwin/core-geometry": "5.15.0-dev.
|
|
78
|
-
"@itwin/
|
|
79
|
-
"@itwin/ecschema-locaters": "5.15.0-dev.
|
|
80
|
-
"@itwin/core-
|
|
81
|
-
"@itwin/
|
|
82
|
-
"
|
|
83
|
-
"
|
|
75
|
+
"@itwin/build-tools": "5.15.0-dev.19",
|
|
76
|
+
"@itwin/core-bentley": "5.15.0-dev.19",
|
|
77
|
+
"@itwin/core-geometry": "5.15.0-dev.19",
|
|
78
|
+
"@itwin/core-common": "5.15.0-dev.19",
|
|
79
|
+
"@itwin/ecschema-locaters": "5.15.0-dev.19",
|
|
80
|
+
"@itwin/core-quantity": "5.15.0-dev.19",
|
|
81
|
+
"@itwin/ecschema-metadata": "5.15.0-dev.19",
|
|
82
|
+
"@itwin/ecsql-common": "5.15.0-dev.19",
|
|
83
|
+
"internal-tools": "3.0.0-dev.69"
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@bentley/imodeljs-native": "5.15.
|
|
86
|
+
"@bentley/imodeljs-native": "5.15.37",
|
|
87
87
|
"@itwin/object-storage-azure": "^3.0.4",
|
|
88
88
|
"@azure/storage-blob": "^12.28.0",
|
|
89
89
|
"form-data": "^4.0.6",
|