@itwin/core-backend 4.0.0-dev.28 → 4.0.0-dev.32

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.
Files changed (244) hide show
  1. package/lib/cjs/AliCloudStorageService.d.ts +23 -23
  2. package/lib/cjs/AliCloudStorageService.js +71 -71
  3. package/lib/cjs/AliCloudStorageService.js.map +1 -1
  4. package/lib/cjs/BackendHubAccess.d.ts +224 -224
  5. package/lib/cjs/BackendHubAccess.js +41 -41
  6. package/lib/cjs/BackendHubAccess.js.map +1 -1
  7. package/lib/cjs/BackendLoggerCategory.d.ts +91 -91
  8. package/lib/cjs/BackendLoggerCategory.js +99 -99
  9. package/lib/cjs/BackendLoggerCategory.js.map +1 -1
  10. package/lib/cjs/BisCoreSchema.d.ts +21 -21
  11. package/lib/cjs/BisCoreSchema.js +60 -60
  12. package/lib/cjs/BisCoreSchema.js.map +1 -1
  13. package/lib/cjs/BriefcaseManager.d.ts +170 -170
  14. package/lib/cjs/BriefcaseManager.js +408 -408
  15. package/lib/cjs/BriefcaseManager.js.map +1 -1
  16. package/lib/cjs/Category.d.ts +153 -153
  17. package/lib/cjs/Category.js +243 -243
  18. package/lib/cjs/Category.js.map +1 -1
  19. package/lib/cjs/ChangeSummaryManager.d.ts +187 -187
  20. package/lib/cjs/ChangeSummaryManager.js +446 -446
  21. package/lib/cjs/ChangeSummaryManager.js.map +1 -1
  22. package/lib/cjs/ChangedElementsDb.d.ts +99 -99
  23. package/lib/cjs/ChangedElementsDb.js +165 -165
  24. package/lib/cjs/ChangedElementsDb.js.map +1 -1
  25. package/lib/cjs/ChangedElementsManager.d.ts +39 -39
  26. package/lib/cjs/ChangedElementsManager.js +88 -88
  27. package/lib/cjs/ChangedElementsManager.js.map +1 -1
  28. package/lib/cjs/CheckpointManager.d.ts +121 -121
  29. package/lib/cjs/CheckpointManager.js +348 -348
  30. package/lib/cjs/CheckpointManager.js.map +1 -1
  31. package/lib/cjs/ClassRegistry.d.ts +79 -79
  32. package/lib/cjs/ClassRegistry.js +249 -249
  33. package/lib/cjs/ClassRegistry.js.map +1 -1
  34. package/lib/cjs/CloudSqlite.d.ts +350 -350
  35. package/lib/cjs/CloudSqlite.js +153 -153
  36. package/lib/cjs/CloudSqlite.js.map +1 -1
  37. package/lib/cjs/CloudStorageBackend.d.ts +58 -58
  38. package/lib/cjs/CloudStorageBackend.js +170 -170
  39. package/lib/cjs/CloudStorageBackend.js.map +1 -1
  40. package/lib/cjs/CodeService.d.ts +396 -396
  41. package/lib/cjs/CodeService.js +63 -63
  42. package/lib/cjs/CodeService.js.map +1 -1
  43. package/lib/cjs/CodeSpecs.d.ts +55 -55
  44. package/lib/cjs/CodeSpecs.js +124 -124
  45. package/lib/cjs/CodeSpecs.js.map +1 -1
  46. package/lib/cjs/ConcurrentQuery.d.ts +13 -13
  47. package/lib/cjs/ConcurrentQuery.js +36 -36
  48. package/lib/cjs/ConcurrentQuery.js.map +1 -1
  49. package/lib/cjs/CustomViewState3dCreator.d.ts +21 -21
  50. package/lib/cjs/CustomViewState3dCreator.js +81 -81
  51. package/lib/cjs/CustomViewState3dCreator.js.map +1 -1
  52. package/lib/cjs/DevTools.d.ts +73 -73
  53. package/lib/cjs/DevTools.js +156 -156
  54. package/lib/cjs/DevTools.js.map +1 -1
  55. package/lib/cjs/DisplayStyle.d.ts +106 -106
  56. package/lib/cjs/DisplayStyle.js +253 -253
  57. package/lib/cjs/DisplayStyle.js.map +1 -1
  58. package/lib/cjs/ECDb.d.ts +191 -191
  59. package/lib/cjs/ECDb.js +348 -348
  60. package/lib/cjs/ECDb.js.map +1 -1
  61. package/lib/cjs/ECSchemaXmlContext.d.ts +18 -18
  62. package/lib/cjs/ECSchemaXmlContext.js +41 -41
  63. package/lib/cjs/ECSchemaXmlContext.js.map +1 -1
  64. package/lib/cjs/ECSqlStatement.d.ts +473 -473
  65. package/lib/cjs/ECSqlStatement.js +791 -791
  66. package/lib/cjs/ECSqlStatement.js.map +1 -1
  67. package/lib/cjs/Element.d.ts +1109 -1109
  68. package/lib/cjs/Element.js +1419 -1419
  69. package/lib/cjs/Element.js.map +1 -1
  70. package/lib/cjs/ElementAspect.d.ts +179 -179
  71. package/lib/cjs/ElementAspect.js +211 -211
  72. package/lib/cjs/ElementAspect.js.map +1 -1
  73. package/lib/cjs/ElementGraphics.d.ts +9 -9
  74. package/lib/cjs/ElementGraphics.js +41 -41
  75. package/lib/cjs/ElementGraphics.js.map +1 -1
  76. package/lib/cjs/ElementTreeWalker.d.ts +162 -162
  77. package/lib/cjs/ElementTreeWalker.js +409 -409
  78. package/lib/cjs/ElementTreeWalker.js.map +1 -1
  79. package/lib/cjs/Entity.d.ts +106 -106
  80. package/lib/cjs/Entity.js +134 -134
  81. package/lib/cjs/Entity.js.map +1 -1
  82. package/lib/cjs/EntityReferences.d.ts +49 -49
  83. package/lib/cjs/EntityReferences.js +95 -95
  84. package/lib/cjs/EntityReferences.js.map +1 -1
  85. package/lib/cjs/ExportGraphics.d.ts +317 -317
  86. package/lib/cjs/ExportGraphics.js +208 -208
  87. package/lib/cjs/ExportGraphics.js.map +1 -1
  88. package/lib/cjs/ExternalSource.d.ts +96 -96
  89. package/lib/cjs/ExternalSource.js +131 -131
  90. package/lib/cjs/ExternalSource.js.map +1 -1
  91. package/lib/cjs/GeoCoordConfig.d.ts +19 -19
  92. package/lib/cjs/GeoCoordConfig.js +85 -85
  93. package/lib/cjs/GeoCoordConfig.js.map +1 -1
  94. package/lib/cjs/GeometrySummary.d.ts +4 -4
  95. package/lib/cjs/GeometrySummary.js +380 -380
  96. package/lib/cjs/GeometrySummary.js.map +1 -1
  97. package/lib/cjs/HubMock.d.ts +94 -94
  98. package/lib/cjs/HubMock.js +220 -220
  99. package/lib/cjs/HubMock.js.map +1 -1
  100. package/lib/cjs/IModelCloneContext.d.ts +8 -8
  101. package/lib/cjs/IModelCloneContext.js +15 -15
  102. package/lib/cjs/IModelCloneContext.js.map +1 -1
  103. package/lib/cjs/IModelDb.d.ts +1210 -1210
  104. package/lib/cjs/IModelDb.js +2377 -2377
  105. package/lib/cjs/IModelDb.js.map +1 -1
  106. package/lib/cjs/IModelElementCloneContext.d.ts +89 -89
  107. package/lib/cjs/IModelElementCloneContext.js +159 -159
  108. package/lib/cjs/IModelElementCloneContext.js.map +1 -1
  109. package/lib/cjs/IModelHost.d.ts +369 -369
  110. package/lib/cjs/IModelHost.js +488 -488
  111. package/lib/cjs/IModelHost.js.map +1 -1
  112. package/lib/cjs/IModelJsFs.d.ts +62 -62
  113. package/lib/cjs/IModelJsFs.js +139 -139
  114. package/lib/cjs/IModelJsFs.js.map +1 -1
  115. package/lib/cjs/IpcHost.d.ts +104 -104
  116. package/lib/cjs/IpcHost.js +276 -276
  117. package/lib/cjs/IpcHost.js.map +1 -1
  118. package/lib/cjs/LineStyle.d.ts +311 -311
  119. package/lib/cjs/LineStyle.js +295 -295
  120. package/lib/cjs/LineStyle.js.map +1 -1
  121. package/lib/cjs/LocalHub.d.ts +162 -162
  122. package/lib/cjs/LocalHub.js +580 -580
  123. package/lib/cjs/LocalHub.js.map +1 -1
  124. package/lib/cjs/LocalhostIpcHost.d.ts +20 -20
  125. package/lib/cjs/LocalhostIpcHost.js +79 -79
  126. package/lib/cjs/LocalhostIpcHost.js.map +1 -1
  127. package/lib/cjs/Material.d.ts +131 -131
  128. package/lib/cjs/Material.js +180 -180
  129. package/lib/cjs/Material.js.map +1 -1
  130. package/lib/cjs/Model.d.ts +392 -392
  131. package/lib/cjs/Model.js +485 -485
  132. package/lib/cjs/Model.js.map +1 -1
  133. package/lib/cjs/NativeAppStorage.d.ts +51 -51
  134. package/lib/cjs/NativeAppStorage.js +202 -202
  135. package/lib/cjs/NativeAppStorage.js.map +1 -1
  136. package/lib/cjs/NativeHost.d.ts +52 -52
  137. package/lib/cjs/NativeHost.js +160 -160
  138. package/lib/cjs/NativeHost.js.map +1 -1
  139. package/lib/cjs/NavigationRelationship.d.ts +156 -156
  140. package/lib/cjs/NavigationRelationship.js +225 -225
  141. package/lib/cjs/NavigationRelationship.js.map +1 -1
  142. package/lib/cjs/PromiseMemoizer.d.ts +51 -51
  143. package/lib/cjs/PromiseMemoizer.js +101 -101
  144. package/lib/cjs/PromiseMemoizer.js.map +1 -1
  145. package/lib/cjs/PropertyStore.d.ts +132 -132
  146. package/lib/cjs/PropertyStore.js +11 -11
  147. package/lib/cjs/PropertyStore.js.map +1 -1
  148. package/lib/cjs/Relationship.d.ts +416 -416
  149. package/lib/cjs/Relationship.js +494 -494
  150. package/lib/cjs/Relationship.js.map +1 -1
  151. package/lib/cjs/RpcBackend.d.ts +5 -5
  152. package/lib/cjs/RpcBackend.js +32 -32
  153. package/lib/cjs/RpcBackend.js.map +1 -1
  154. package/lib/cjs/SQLiteDb.d.ts +219 -219
  155. package/lib/cjs/SQLiteDb.js +212 -212
  156. package/lib/cjs/SQLiteDb.js.map +1 -1
  157. package/lib/cjs/Schema.d.ts +55 -55
  158. package/lib/cjs/Schema.js +83 -83
  159. package/lib/cjs/Schema.js.map +1 -1
  160. package/lib/cjs/ServerBasedLocks.d.ts +57 -57
  161. package/lib/cjs/ServerBasedLocks.js +168 -168
  162. package/lib/cjs/ServerBasedLocks.js.map +1 -1
  163. package/lib/cjs/SqliteStatement.d.ts +360 -360
  164. package/lib/cjs/SqliteStatement.js +586 -586
  165. package/lib/cjs/SqliteStatement.js.map +1 -1
  166. package/lib/cjs/Texture.d.ts +58 -58
  167. package/lib/cjs/Texture.js +82 -82
  168. package/lib/cjs/Texture.js.map +1 -1
  169. package/lib/cjs/TileStorage.d.ts +18 -18
  170. package/lib/cjs/TileStorage.js +87 -87
  171. package/lib/cjs/TileStorage.js.map +1 -1
  172. package/lib/cjs/TxnManager.d.ts +202 -202
  173. package/lib/cjs/TxnManager.js +356 -356
  174. package/lib/cjs/TxnManager.js.map +1 -1
  175. package/lib/cjs/ViewDefinition.d.ts +435 -439
  176. package/lib/cjs/ViewDefinition.d.ts.map +1 -1
  177. package/lib/cjs/ViewDefinition.js +646 -646
  178. package/lib/cjs/ViewDefinition.js.map +1 -1
  179. package/lib/cjs/ViewStateHydrator.d.ts +13 -13
  180. package/lib/cjs/ViewStateHydrator.js +103 -103
  181. package/lib/cjs/ViewStateHydrator.js.map +1 -1
  182. package/lib/cjs/assets/IModelChange.02.00.00.ecschema.xml +90 -90
  183. package/lib/cjs/assets/Settings/Schemas/Cloud.Schema.json +67 -67
  184. package/lib/cjs/assets/Settings/Schemas/Gcs.schema.json +31 -31
  185. package/lib/cjs/assets/Settings/Schemas/Workspace.Schema.json +52 -52
  186. package/lib/cjs/assets/Settings/backend.setting.json5 +138 -138
  187. package/lib/cjs/core-backend.d.ts +184 -184
  188. package/lib/cjs/core-backend.js +204 -204
  189. package/lib/cjs/core-backend.js.map +1 -1
  190. package/lib/cjs/domains/FunctionalElements.d.ts +101 -101
  191. package/lib/cjs/domains/FunctionalElements.js +145 -145
  192. package/lib/cjs/domains/FunctionalElements.js.map +1 -1
  193. package/lib/cjs/domains/FunctionalSchema.d.ts +13 -13
  194. package/lib/cjs/domains/FunctionalSchema.js +40 -40
  195. package/lib/cjs/domains/FunctionalSchema.js.map +1 -1
  196. package/lib/cjs/domains/GenericElements.d.ts +177 -177
  197. package/lib/cjs/domains/GenericElements.js +263 -263
  198. package/lib/cjs/domains/GenericElements.js.map +1 -1
  199. package/lib/cjs/domains/GenericSchema.d.ts +10 -10
  200. package/lib/cjs/domains/GenericSchema.js +28 -28
  201. package/lib/cjs/domains/GenericSchema.js.map +1 -1
  202. package/lib/cjs/rpc/multipart.d.ts +11 -11
  203. package/lib/cjs/rpc/multipart.js +71 -71
  204. package/lib/cjs/rpc/multipart.js.map +1 -1
  205. package/lib/cjs/rpc/tracing.d.ts +28 -28
  206. package/lib/cjs/rpc/tracing.js +73 -73
  207. package/lib/cjs/rpc/tracing.js.map +1 -1
  208. package/lib/cjs/rpc/web/logging.d.ts +9 -9
  209. package/lib/cjs/rpc/web/logging.js +43 -43
  210. package/lib/cjs/rpc/web/logging.js.map +1 -1
  211. package/lib/cjs/rpc/web/request.d.ts +6 -6
  212. package/lib/cjs/rpc/web/request.js +73 -73
  213. package/lib/cjs/rpc/web/request.js.map +1 -1
  214. package/lib/cjs/rpc/web/response.d.ts +6 -6
  215. package/lib/cjs/rpc/web/response.js +105 -105
  216. package/lib/cjs/rpc/web/response.js.map +1 -1
  217. package/lib/cjs/rpc-impl/DevToolsRpcImpl.d.ts +15 -15
  218. package/lib/cjs/rpc-impl/DevToolsRpcImpl.js +32 -32
  219. package/lib/cjs/rpc-impl/DevToolsRpcImpl.js.map +1 -1
  220. package/lib/cjs/rpc-impl/IModelReadRpcImpl.d.ts +47 -47
  221. package/lib/cjs/rpc-impl/IModelReadRpcImpl.js +293 -293
  222. package/lib/cjs/rpc-impl/IModelReadRpcImpl.js.map +1 -1
  223. package/lib/cjs/rpc-impl/IModelTileRpcImpl.d.ts +22 -22
  224. package/lib/cjs/rpc-impl/IModelTileRpcImpl.js +202 -202
  225. package/lib/cjs/rpc-impl/IModelTileRpcImpl.js.map +1 -1
  226. package/lib/cjs/rpc-impl/RpcBriefcaseUtility.d.ts +36 -36
  227. package/lib/cjs/rpc-impl/RpcBriefcaseUtility.js +166 -166
  228. package/lib/cjs/rpc-impl/RpcBriefcaseUtility.js.map +1 -1
  229. package/lib/cjs/rpc-impl/SnapshotIModelRpcImpl.d.ts +16 -16
  230. package/lib/cjs/rpc-impl/SnapshotIModelRpcImpl.js +42 -42
  231. package/lib/cjs/rpc-impl/SnapshotIModelRpcImpl.js.map +1 -1
  232. package/lib/cjs/rpc-impl/WipRpcImpl.d.ts +15 -15
  233. package/lib/cjs/rpc-impl/WipRpcImpl.js +37 -37
  234. package/lib/cjs/rpc-impl/WipRpcImpl.js.map +1 -1
  235. package/lib/cjs/workspace/Settings.d.ts +186 -186
  236. package/lib/cjs/workspace/Settings.js +154 -154
  237. package/lib/cjs/workspace/Settings.js.map +1 -1
  238. package/lib/cjs/workspace/SettingsSchemas.d.ts +75 -75
  239. package/lib/cjs/workspace/SettingsSchemas.js +190 -190
  240. package/lib/cjs/workspace/SettingsSchemas.js.map +1 -1
  241. package/lib/cjs/workspace/Workspace.d.ts +414 -414
  242. package/lib/cjs/workspace/Workspace.js +537 -537
  243. package/lib/cjs/workspace/Workspace.js.map +1 -1
  244. package/package.json +11 -11
@@ -1,250 +1,250 @@
1
- "use strict";
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
- * See LICENSE.md in the project root for license terms and full copyright notice.
5
- *--------------------------------------------------------------------------------------------*/
6
- /** @packageDocumentation
7
- * @module Schema
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.MetaDataRegistry = exports.ClassRegistry = void 0;
11
- const core_bentley_1 = require("@itwin/core-bentley");
12
- const core_common_1 = require("@itwin/core-common");
13
- const Entity_1 = require("./Entity");
14
- const Schema_1 = require("./Schema");
15
- const EntityReferences_1 = require("./EntityReferences");
16
- const assert = require("assert");
17
- const isGeneratedClassTag = Symbol("isGeneratedClassTag");
18
- /** The mapping between a BIS class name (in the form "schema:class") and its JavaScript constructor function
19
- * @public
20
- */
21
- class ClassRegistry {
22
- /** @internal */
23
- static isNotFoundError(err) { return (err instanceof core_common_1.IModelError) && (err.errorNumber === core_bentley_1.IModelStatus.NotFound); }
24
- /** @internal */
25
- static makeMetaDataNotFoundError(className) { return new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, `metadata not found for ${className}`); }
26
- /** @internal */
27
- static register(entityClass, schema) {
28
- entityClass.schema = schema;
29
- const key = (`${schema.schemaName}:${entityClass.className}`).toLowerCase();
30
- if (this._classMap.has(key)) {
31
- const errMsg = `Class ${key} is already registered. Make sure static className member is correct on JavaScript class ${entityClass.name}`;
32
- core_bentley_1.Logger.logError("core-frontend.classRegistry", errMsg);
33
- throw new Error(errMsg);
34
- }
35
- this._classMap.set(key, entityClass);
36
- }
37
- /** Generate a proxy Schema for a domain that has not been registered. */
38
- static generateProxySchema(domain, iModel) {
39
- const hasBehavior = iModel.withPreparedSqliteStatement(`
40
- SELECT NULL FROM [ec_CustomAttribute] [c]
41
- JOIN [ec_schema] [s] ON [s].[Id] = [c].[ContainerId]
42
- JOIN [ec_class] [e] ON [e].[Id] = [c].[ClassId]
43
- JOIN [ec_schema] [b] ON [e].[SchemaId] = [b].[Id]
44
- WHERE [c].[ContainerType] = 1 AND [s].[Name] = ? AND [b].[Name] || '.' || [e].[name] = ?`, (stmt) => {
45
- stmt.bindString(1, domain);
46
- stmt.bindString(2, "BisCore.SchemaHasBehavior");
47
- return stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW;
48
- });
49
- const schemaClass = class extends Schema_1.Schema {
50
- static get schemaName() { return domain; }
51
- static get missingRequiredBehavior() { return hasBehavior; }
52
- };
53
- Schema_1.Schemas.registerSchema(schemaClass); // register the class before we return it.
54
- return schemaClass;
55
- }
56
- /** First, finds the root BisCore entity class for an entity, by traversing base classes and mixin targets (AppliesTo).
57
- * Then, gets its metadata and returns that.
58
- * @param iModel - iModel containing the metadata for this type
59
- * @param ecTypeQualifier - a full name of an ECEntityClass to find the root of
60
- * @returns the qualified full name of an ECEntityClass
61
- * @internal public for testing only
62
- */
63
- static getRootEntity(iModel, ecTypeQualifier) {
64
- const [classSchema, className] = ecTypeQualifier.split(".");
65
- const schemaItemJson = iModel.nativeDb.getSchemaItem(classSchema, className);
66
- if (schemaItemJson.error)
67
- throw new core_common_1.IModelError(schemaItemJson.error.status, `failed to get schema item '${ecTypeQualifier}'`);
68
- assert(undefined !== schemaItemJson.result);
69
- const schemaItem = JSON.parse(schemaItemJson.result);
70
- if (!("appliesTo" in schemaItem) && schemaItem.baseClass === undefined) {
71
- return ecTypeQualifier;
72
- }
73
- // typescript doesn't understand that the inverse of the above condition is
74
- // ("appliesTo" in rootclassMetaData || rootClassMetaData.baseClass !== undefined)
75
- const parentItemQualifier = schemaItem.appliesTo ?? schemaItem.baseClass;
76
- return this.getRootEntity(iModel, parentItemQualifier);
77
- }
78
- /** Generate a JavaScript class from Entity metadata.
79
- * @param entityMetaData The Entity metadata that defines the class
80
- */
81
- static generateClassForEntity(entityMetaData, iModel) {
82
- var _a, _b;
83
- const name = entityMetaData.ecclass.split(":");
84
- const domainName = name[0];
85
- const className = name[1];
86
- if (0 === entityMetaData.baseClasses.length) // metadata must contain a superclass
87
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadArg, `class ${name} has no superclass`);
88
- // make sure schema exists
89
- let schema = Schema_1.Schemas.getRegisteredSchema(domainName);
90
- if (undefined === schema)
91
- schema = this.generateProxySchema(domainName, iModel); // no schema found, create it too
92
- const superclass = this._classMap.get(entityMetaData.baseClasses[0].toLowerCase());
93
- if (undefined === superclass)
94
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, `cannot find superclass for class ${name}`);
95
- // user defined class hierarchies may skip a class in the hierarchy, and therefore their JS base class cannot
96
- // be used to tell if there are any generated classes in the hierarchy
97
- let generatedClassHasNonGeneratedNonCoreAncestor = false;
98
- let currentSuperclass = superclass;
99
- const MAX_ITERS = 1000;
100
- for (let i = 0; i < MAX_ITERS; ++i) {
101
- if (currentSuperclass.schema.schemaName === "BisCore")
102
- break;
103
- if (!currentSuperclass.isGeneratedClass) {
104
- generatedClassHasNonGeneratedNonCoreAncestor = true;
105
- break;
106
- }
107
- const superclassMetaData = iModel.classMetaDataRegistry.find(currentSuperclass.classFullName);
108
- if (superclassMetaData === undefined)
109
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadSchema, `could not find the metadata for class '${currentSuperclass.name}', class metadata should be loaded by now`);
110
- const maybeNextSuperclass = this.getClass(superclassMetaData.baseClasses[0], iModel);
111
- if (maybeNextSuperclass === undefined)
112
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadSchema, `could not find the base class of '${currentSuperclass.name}', all generated classes must have a base class`);
113
- currentSuperclass = maybeNextSuperclass;
114
- }
115
- const generatedClass = (_b = class extends superclass {
116
- static get className() { return className; }
117
- static get isGeneratedClass() { return this.hasOwnProperty(isGeneratedClassTag); }
118
- },
119
- _a = isGeneratedClassTag,
120
- _b[_a] = true,
121
- _b);
122
- // the above creates an anonymous class. For help debugging, set the "constructor.name" property to be the same as the bisClassName.
123
- Object.defineProperty(generatedClass, "name", { get: () => className }); // this is the (only) way to change that readonly property.
124
- // a class only gets an automatic `collectReferenceConcreteIds` implementation if:
125
- // - it is not in the `BisCore` schema
126
- // - there are no ancestors with manually registered JS implementations, (excluding BisCore base classes)
127
- if (!generatedClassHasNonGeneratedNonCoreAncestor) {
128
- const navigationProps = Object.entries(entityMetaData.properties)
129
- .filter(([_name, prop]) => prop.isNavigation)
130
- // eslint-disable-next-line @typescript-eslint/no-shadow
131
- .map(([name, prop]) => {
132
- assert(prop.relationshipClass);
133
- const maybeMetaData = iModel.nativeDb.getSchemaItem(...prop.relationshipClass.split(":"));
134
- assert(maybeMetaData.result !== undefined, "The nav props relationship metadata was not found");
135
- const relMetaData = JSON.parse(maybeMetaData.result);
136
- const rootClassMetaData = ClassRegistry.getRootEntity(iModel, relMetaData.target.constraintClasses[0]);
137
- // root class must be in BisCore so should be loaded since biscore classes will never get this
138
- // generated implementation
139
- const normalizeClassName = (clsName) => clsName.replace(".", ":");
140
- const rootClass = ClassRegistry.findRegisteredClass(normalizeClassName(rootClassMetaData));
141
- assert(rootClass, `The root class for ${prop.relationshipClass} was not in BisCore.`);
142
- return { name, concreteEntityType: EntityReferences_1.EntityReferences.typeFromClass(rootClass) };
143
- });
144
- Object.defineProperty(generatedClass.prototype, "collectReferenceConcreteIds", {
145
- value(referenceIds) {
146
- // eslint-disable-next-line @typescript-eslint/dot-notation
147
- const superImpl = superclass.prototype["collectReferenceConcreteIds"];
148
- superImpl.call(this, referenceIds);
149
- for (const navProp of navigationProps) {
150
- const relatedElem = this[navProp.name]; // cast to any since subclass can have any extensions
151
- if (!relatedElem || !core_bentley_1.Id64.isValid(relatedElem.id))
152
- continue;
153
- const referenceId = EntityReferences_1.EntityReferences.fromEntityType(relatedElem.id, navProp.concreteEntityType);
154
- referenceIds.add(referenceId);
155
- }
156
- },
157
- // defaults for methods on a prototype (required for sinon to stub out methods on tests)
158
- writable: true,
159
- configurable: true,
160
- });
161
- }
162
- // if the schema is a proxy for a domain with behavior, throw exceptions for all protected operations
163
- if (schema.missingRequiredBehavior) {
164
- const throwError = () => {
165
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.WrongHandler, `Schema [${domainName}] not registered, but is marked with SchemaHasBehavior`);
166
- };
167
- superclass.protectedOperations.forEach((operation) => generatedClass[operation] = throwError);
168
- }
169
- this.register(generatedClass, schema); // register it before returning
170
- return generatedClass;
171
- }
172
- /** Register all of the classes found in the given module that derive from Entity. See the example in [[Schema]]
173
- * @param moduleObj The module to search for subclasses of Entity
174
- * @param schema The schema for all found classes
175
- */
176
- static registerModule(moduleObj, schema) {
177
- for (const thisMember in moduleObj) { // eslint-disable-line guard-for-in
178
- const thisClass = moduleObj[thisMember];
179
- if (thisClass.prototype instanceof Entity_1.Entity)
180
- this.register(thisClass, schema);
181
- }
182
- }
183
- /**
184
- * This function fetches the specified Entity from the imodel, generates a JavaScript class for it, and registers the generated
185
- * class. This function also ensures that all of the base classes of the Entity exist and are registered.
186
- */
187
- static generateClass(classFullName, iModel) {
188
- const metadata = iModel.classMetaDataRegistry.find(classFullName);
189
- if (metadata === undefined || metadata.ecclass === undefined)
190
- throw this.makeMetaDataNotFoundError(classFullName);
191
- // Make sure we have all base classes registered.
192
- if (metadata.baseClasses && (0 !== metadata.baseClasses.length))
193
- this.getClass(metadata.baseClasses[0], iModel);
194
- // Now we can generate the class from the classDef.
195
- return this.generateClassForEntity(metadata, iModel);
196
- }
197
- /** Find a registered class by classFullName.
198
- * @param classFullName class to find
199
- * @param iModel The IModel that contains the class definitions
200
- * @returns The Entity class or undefined
201
- */
202
- static findRegisteredClass(classFullName) {
203
- return this._classMap.get(classFullName.toLowerCase());
204
- }
205
- /** Get the Entity class for the specified Entity className.
206
- * @param classFullName The full BIS class name of the Entity
207
- * @param iModel The IModel that contains the class definitions
208
- * @returns The Entity class
209
- */
210
- static getClass(classFullName, iModel) {
211
- const key = classFullName.toLowerCase();
212
- const ctor = this._classMap.get(key);
213
- return ctor ? ctor : this.generateClass(key, iModel);
214
- }
215
- /** Unregister a class, by name, if one is already registered.
216
- * This function is not normally needed, but is useful for cases where a generated *proxy* class needs to be replaced by the *real* class.
217
- * @param classFullName Name of the class to unregister
218
- * @return true if the class was unregistered
219
- * @internal
220
- */
221
- static unregisterCLass(classFullName) { return this._classMap.delete(classFullName.toLowerCase()); }
222
- /** Unregister all classes from a schema.
223
- * This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema.
224
- * @param schema Name of the schema to unregister
225
- * @internal
226
- */
227
- static unregisterClassesFrom(schema) {
228
- for (const entry of Array.from(this._classMap)) {
229
- if (entry[1].schema === schema)
230
- this.unregisterCLass(entry[0]);
231
- }
232
- }
233
- }
234
- exports.ClassRegistry = ClassRegistry;
235
- ClassRegistry._classMap = new Map();
236
- /**
237
- * A cache that records the mapping between class names and class metadata
238
- * @internal
239
- */
240
- class MetaDataRegistry {
241
- constructor() {
242
- this._registry = new Map();
243
- }
244
- /** Get the specified Entity metadata */
245
- find(classFullName) { return this._registry.get(classFullName.toLowerCase()); }
246
- /** Add metadata to the cache */
247
- add(classFullName, metaData) { this._registry.set(classFullName.toLowerCase(), metaData); }
248
- }
249
- exports.MetaDataRegistry = MetaDataRegistry;
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module Schema
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.MetaDataRegistry = exports.ClassRegistry = void 0;
11
+ const core_bentley_1 = require("@itwin/core-bentley");
12
+ const core_common_1 = require("@itwin/core-common");
13
+ const Entity_1 = require("./Entity");
14
+ const Schema_1 = require("./Schema");
15
+ const EntityReferences_1 = require("./EntityReferences");
16
+ const assert = require("assert");
17
+ const isGeneratedClassTag = Symbol("isGeneratedClassTag");
18
+ /** The mapping between a BIS class name (in the form "schema:class") and its JavaScript constructor function
19
+ * @public
20
+ */
21
+ class ClassRegistry {
22
+ /** @internal */
23
+ static isNotFoundError(err) { return (err instanceof core_common_1.IModelError) && (err.errorNumber === core_bentley_1.IModelStatus.NotFound); }
24
+ /** @internal */
25
+ static makeMetaDataNotFoundError(className) { return new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, `metadata not found for ${className}`); }
26
+ /** @internal */
27
+ static register(entityClass, schema) {
28
+ entityClass.schema = schema;
29
+ const key = (`${schema.schemaName}:${entityClass.className}`).toLowerCase();
30
+ if (this._classMap.has(key)) {
31
+ const errMsg = `Class ${key} is already registered. Make sure static className member is correct on JavaScript class ${entityClass.name}`;
32
+ core_bentley_1.Logger.logError("core-frontend.classRegistry", errMsg);
33
+ throw new Error(errMsg);
34
+ }
35
+ this._classMap.set(key, entityClass);
36
+ }
37
+ /** Generate a proxy Schema for a domain that has not been registered. */
38
+ static generateProxySchema(domain, iModel) {
39
+ const hasBehavior = iModel.withPreparedSqliteStatement(`
40
+ SELECT NULL FROM [ec_CustomAttribute] [c]
41
+ JOIN [ec_schema] [s] ON [s].[Id] = [c].[ContainerId]
42
+ JOIN [ec_class] [e] ON [e].[Id] = [c].[ClassId]
43
+ JOIN [ec_schema] [b] ON [e].[SchemaId] = [b].[Id]
44
+ WHERE [c].[ContainerType] = 1 AND [s].[Name] = ? AND [b].[Name] || '.' || [e].[name] = ?`, (stmt) => {
45
+ stmt.bindString(1, domain);
46
+ stmt.bindString(2, "BisCore.SchemaHasBehavior");
47
+ return stmt.step() === core_bentley_1.DbResult.BE_SQLITE_ROW;
48
+ });
49
+ const schemaClass = class extends Schema_1.Schema {
50
+ static get schemaName() { return domain; }
51
+ static get missingRequiredBehavior() { return hasBehavior; }
52
+ };
53
+ Schema_1.Schemas.registerSchema(schemaClass); // register the class before we return it.
54
+ return schemaClass;
55
+ }
56
+ /** First, finds the root BisCore entity class for an entity, by traversing base classes and mixin targets (AppliesTo).
57
+ * Then, gets its metadata and returns that.
58
+ * @param iModel - iModel containing the metadata for this type
59
+ * @param ecTypeQualifier - a full name of an ECEntityClass to find the root of
60
+ * @returns the qualified full name of an ECEntityClass
61
+ * @internal public for testing only
62
+ */
63
+ static getRootEntity(iModel, ecTypeQualifier) {
64
+ const [classSchema, className] = ecTypeQualifier.split(".");
65
+ const schemaItemJson = iModel.nativeDb.getSchemaItem(classSchema, className);
66
+ if (schemaItemJson.error)
67
+ throw new core_common_1.IModelError(schemaItemJson.error.status, `failed to get schema item '${ecTypeQualifier}'`);
68
+ assert(undefined !== schemaItemJson.result);
69
+ const schemaItem = JSON.parse(schemaItemJson.result);
70
+ if (!("appliesTo" in schemaItem) && schemaItem.baseClass === undefined) {
71
+ return ecTypeQualifier;
72
+ }
73
+ // typescript doesn't understand that the inverse of the above condition is
74
+ // ("appliesTo" in rootclassMetaData || rootClassMetaData.baseClass !== undefined)
75
+ const parentItemQualifier = schemaItem.appliesTo ?? schemaItem.baseClass;
76
+ return this.getRootEntity(iModel, parentItemQualifier);
77
+ }
78
+ /** Generate a JavaScript class from Entity metadata.
79
+ * @param entityMetaData The Entity metadata that defines the class
80
+ */
81
+ static generateClassForEntity(entityMetaData, iModel) {
82
+ var _a, _b;
83
+ const name = entityMetaData.ecclass.split(":");
84
+ const domainName = name[0];
85
+ const className = name[1];
86
+ if (0 === entityMetaData.baseClasses.length) // metadata must contain a superclass
87
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadArg, `class ${name} has no superclass`);
88
+ // make sure schema exists
89
+ let schema = Schema_1.Schemas.getRegisteredSchema(domainName);
90
+ if (undefined === schema)
91
+ schema = this.generateProxySchema(domainName, iModel); // no schema found, create it too
92
+ const superclass = this._classMap.get(entityMetaData.baseClasses[0].toLowerCase());
93
+ if (undefined === superclass)
94
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, `cannot find superclass for class ${name}`);
95
+ // user defined class hierarchies may skip a class in the hierarchy, and therefore their JS base class cannot
96
+ // be used to tell if there are any generated classes in the hierarchy
97
+ let generatedClassHasNonGeneratedNonCoreAncestor = false;
98
+ let currentSuperclass = superclass;
99
+ const MAX_ITERS = 1000;
100
+ for (let i = 0; i < MAX_ITERS; ++i) {
101
+ if (currentSuperclass.schema.schemaName === "BisCore")
102
+ break;
103
+ if (!currentSuperclass.isGeneratedClass) {
104
+ generatedClassHasNonGeneratedNonCoreAncestor = true;
105
+ break;
106
+ }
107
+ const superclassMetaData = iModel.classMetaDataRegistry.find(currentSuperclass.classFullName);
108
+ if (superclassMetaData === undefined)
109
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadSchema, `could not find the metadata for class '${currentSuperclass.name}', class metadata should be loaded by now`);
110
+ const maybeNextSuperclass = this.getClass(superclassMetaData.baseClasses[0], iModel);
111
+ if (maybeNextSuperclass === undefined)
112
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadSchema, `could not find the base class of '${currentSuperclass.name}', all generated classes must have a base class`);
113
+ currentSuperclass = maybeNextSuperclass;
114
+ }
115
+ const generatedClass = (_b = class extends superclass {
116
+ static get className() { return className; }
117
+ static get isGeneratedClass() { return this.hasOwnProperty(isGeneratedClassTag); }
118
+ },
119
+ _a = isGeneratedClassTag,
120
+ _b[_a] = true,
121
+ _b);
122
+ // the above creates an anonymous class. For help debugging, set the "constructor.name" property to be the same as the bisClassName.
123
+ Object.defineProperty(generatedClass, "name", { get: () => className }); // this is the (only) way to change that readonly property.
124
+ // a class only gets an automatic `collectReferenceConcreteIds` implementation if:
125
+ // - it is not in the `BisCore` schema
126
+ // - there are no ancestors with manually registered JS implementations, (excluding BisCore base classes)
127
+ if (!generatedClassHasNonGeneratedNonCoreAncestor) {
128
+ const navigationProps = Object.entries(entityMetaData.properties)
129
+ .filter(([_name, prop]) => prop.isNavigation)
130
+ // eslint-disable-next-line @typescript-eslint/no-shadow
131
+ .map(([name, prop]) => {
132
+ assert(prop.relationshipClass);
133
+ const maybeMetaData = iModel.nativeDb.getSchemaItem(...prop.relationshipClass.split(":"));
134
+ assert(maybeMetaData.result !== undefined, "The nav props relationship metadata was not found");
135
+ const relMetaData = JSON.parse(maybeMetaData.result);
136
+ const rootClassMetaData = ClassRegistry.getRootEntity(iModel, relMetaData.target.constraintClasses[0]);
137
+ // root class must be in BisCore so should be loaded since biscore classes will never get this
138
+ // generated implementation
139
+ const normalizeClassName = (clsName) => clsName.replace(".", ":");
140
+ const rootClass = ClassRegistry.findRegisteredClass(normalizeClassName(rootClassMetaData));
141
+ assert(rootClass, `The root class for ${prop.relationshipClass} was not in BisCore.`);
142
+ return { name, concreteEntityType: EntityReferences_1.EntityReferences.typeFromClass(rootClass) };
143
+ });
144
+ Object.defineProperty(generatedClass.prototype, "collectReferenceConcreteIds", {
145
+ value(referenceIds) {
146
+ // eslint-disable-next-line @typescript-eslint/dot-notation
147
+ const superImpl = superclass.prototype["collectReferenceConcreteIds"];
148
+ superImpl.call(this, referenceIds);
149
+ for (const navProp of navigationProps) {
150
+ const relatedElem = this[navProp.name]; // cast to any since subclass can have any extensions
151
+ if (!relatedElem || !core_bentley_1.Id64.isValid(relatedElem.id))
152
+ continue;
153
+ const referenceId = EntityReferences_1.EntityReferences.fromEntityType(relatedElem.id, navProp.concreteEntityType);
154
+ referenceIds.add(referenceId);
155
+ }
156
+ },
157
+ // defaults for methods on a prototype (required for sinon to stub out methods on tests)
158
+ writable: true,
159
+ configurable: true,
160
+ });
161
+ }
162
+ // if the schema is a proxy for a domain with behavior, throw exceptions for all protected operations
163
+ if (schema.missingRequiredBehavior) {
164
+ const throwError = () => {
165
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.WrongHandler, `Schema [${domainName}] not registered, but is marked with SchemaHasBehavior`);
166
+ };
167
+ superclass.protectedOperations.forEach((operation) => generatedClass[operation] = throwError);
168
+ }
169
+ this.register(generatedClass, schema); // register it before returning
170
+ return generatedClass;
171
+ }
172
+ /** Register all of the classes found in the given module that derive from Entity. See the example in [[Schema]]
173
+ * @param moduleObj The module to search for subclasses of Entity
174
+ * @param schema The schema for all found classes
175
+ */
176
+ static registerModule(moduleObj, schema) {
177
+ for (const thisMember in moduleObj) { // eslint-disable-line guard-for-in
178
+ const thisClass = moduleObj[thisMember];
179
+ if (thisClass.prototype instanceof Entity_1.Entity)
180
+ this.register(thisClass, schema);
181
+ }
182
+ }
183
+ /**
184
+ * This function fetches the specified Entity from the imodel, generates a JavaScript class for it, and registers the generated
185
+ * class. This function also ensures that all of the base classes of the Entity exist and are registered.
186
+ */
187
+ static generateClass(classFullName, iModel) {
188
+ const metadata = iModel.classMetaDataRegistry.find(classFullName);
189
+ if (metadata === undefined || metadata.ecclass === undefined)
190
+ throw this.makeMetaDataNotFoundError(classFullName);
191
+ // Make sure we have all base classes registered.
192
+ if (metadata.baseClasses && (0 !== metadata.baseClasses.length))
193
+ this.getClass(metadata.baseClasses[0], iModel);
194
+ // Now we can generate the class from the classDef.
195
+ return this.generateClassForEntity(metadata, iModel);
196
+ }
197
+ /** Find a registered class by classFullName.
198
+ * @param classFullName class to find
199
+ * @param iModel The IModel that contains the class definitions
200
+ * @returns The Entity class or undefined
201
+ */
202
+ static findRegisteredClass(classFullName) {
203
+ return this._classMap.get(classFullName.toLowerCase());
204
+ }
205
+ /** Get the Entity class for the specified Entity className.
206
+ * @param classFullName The full BIS class name of the Entity
207
+ * @param iModel The IModel that contains the class definitions
208
+ * @returns The Entity class
209
+ */
210
+ static getClass(classFullName, iModel) {
211
+ const key = classFullName.toLowerCase();
212
+ const ctor = this._classMap.get(key);
213
+ return ctor ? ctor : this.generateClass(key, iModel);
214
+ }
215
+ /** Unregister a class, by name, if one is already registered.
216
+ * This function is not normally needed, but is useful for cases where a generated *proxy* class needs to be replaced by the *real* class.
217
+ * @param classFullName Name of the class to unregister
218
+ * @return true if the class was unregistered
219
+ * @internal
220
+ */
221
+ static unregisterCLass(classFullName) { return this._classMap.delete(classFullName.toLowerCase()); }
222
+ /** Unregister all classes from a schema.
223
+ * This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema.
224
+ * @param schema Name of the schema to unregister
225
+ * @internal
226
+ */
227
+ static unregisterClassesFrom(schema) {
228
+ for (const entry of Array.from(this._classMap)) {
229
+ if (entry[1].schema === schema)
230
+ this.unregisterCLass(entry[0]);
231
+ }
232
+ }
233
+ }
234
+ exports.ClassRegistry = ClassRegistry;
235
+ ClassRegistry._classMap = new Map();
236
+ /**
237
+ * A cache that records the mapping between class names and class metadata
238
+ * @internal
239
+ */
240
+ class MetaDataRegistry {
241
+ constructor() {
242
+ this._registry = new Map();
243
+ }
244
+ /** Get the specified Entity metadata */
245
+ find(classFullName) { return this._registry.get(classFullName.toLowerCase()); }
246
+ /** Add metadata to the cache */
247
+ add(classFullName, metaData) { this._registry.set(classFullName.toLowerCase(), metaData); }
248
+ }
249
+ exports.MetaDataRegistry = MetaDataRegistry;
250
250
  //# sourceMappingURL=ClassRegistry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ClassRegistry.js","sourceRoot":"","sources":["../../src/ClassRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Schema\n */\n\nimport { DbResult, Id64, IModelStatus, Logger } from \"@itwin/core-bentley\";\nimport { EntityMetaData, EntityReferenceSet, IModelError, RelatedElement } from \"@itwin/core-common\";\nimport { Entity } from \"./Entity\";\nimport { IModelDb } from \"./IModelDb\";\nimport { Schema, Schemas } from \"./Schema\";\nimport { EntityReferences } from \"./EntityReferences\";\nimport * as assert from \"assert\";\n\nconst isGeneratedClassTag = Symbol(\"isGeneratedClassTag\");\n\n/** The mapping between a BIS class name (in the form \"schema:class\") and its JavaScript constructor function\n * @public\n */\nexport class ClassRegistry {\n private static readonly _classMap = new Map<string, typeof Entity>();\n /** @internal */\n public static isNotFoundError(err: any) { return (err instanceof IModelError) && (err.errorNumber === IModelStatus.NotFound); }\n /** @internal */\n public static makeMetaDataNotFoundError(className: string): IModelError { return new IModelError(IModelStatus.NotFound, `metadata not found for ${className}`); }\n /** @internal */\n public static register(entityClass: typeof Entity, schema: typeof Schema) {\n entityClass.schema = schema;\n const key = (`${schema.schemaName}:${entityClass.className}`).toLowerCase();\n if (this._classMap.has(key)) {\n const errMsg = `Class ${key} is already registered. Make sure static className member is correct on JavaScript class ${entityClass.name}`;\n Logger.logError(\"core-frontend.classRegistry\", errMsg);\n throw new Error(errMsg);\n }\n\n this._classMap.set(key, entityClass);\n }\n\n /** Generate a proxy Schema for a domain that has not been registered. */\n private static generateProxySchema(domain: string, iModel: IModelDb): typeof Schema {\n const hasBehavior = iModel.withPreparedSqliteStatement(`\n SELECT NULL FROM [ec_CustomAttribute] [c]\n JOIN [ec_schema] [s] ON [s].[Id] = [c].[ContainerId]\n JOIN [ec_class] [e] ON [e].[Id] = [c].[ClassId]\n JOIN [ec_schema] [b] ON [e].[SchemaId] = [b].[Id]\n WHERE [c].[ContainerType] = 1 AND [s].[Name] = ? AND [b].[Name] || '.' || [e].[name] = ?`, (stmt) => {\n stmt.bindString(1, domain);\n stmt.bindString(2, \"BisCore.SchemaHasBehavior\");\n return stmt.step() === DbResult.BE_SQLITE_ROW;\n });\n\n const schemaClass = class extends Schema {\n public static override get schemaName() { return domain; }\n public static override get missingRequiredBehavior() { return hasBehavior; }\n };\n\n Schemas.registerSchema(schemaClass); // register the class before we return it.\n return schemaClass;\n }\n\n /** First, finds the root BisCore entity class for an entity, by traversing base classes and mixin targets (AppliesTo).\n * Then, gets its metadata and returns that.\n * @param iModel - iModel containing the metadata for this type\n * @param ecTypeQualifier - a full name of an ECEntityClass to find the root of\n * @returns the qualified full name of an ECEntityClass\n * @internal public for testing only\n */\n public static getRootEntity(iModel: IModelDb, ecTypeQualifier: string): string {\n const [classSchema, className] = ecTypeQualifier.split(\".\");\n const schemaItemJson = iModel.nativeDb.getSchemaItem(classSchema, className);\n if (schemaItemJson.error)\n throw new IModelError(schemaItemJson.error.status, `failed to get schema item '${ecTypeQualifier}'`);\n\n assert(undefined !== schemaItemJson.result);\n const schemaItem = JSON.parse(schemaItemJson.result);\n if (!(\"appliesTo\" in schemaItem) && schemaItem.baseClass === undefined) {\n return ecTypeQualifier;\n }\n\n // typescript doesn't understand that the inverse of the above condition is\n // (\"appliesTo\" in rootclassMetaData || rootClassMetaData.baseClass !== undefined)\n const parentItemQualifier = schemaItem.appliesTo ?? schemaItem.baseClass as string;\n return this.getRootEntity(iModel, parentItemQualifier);\n }\n\n /** Generate a JavaScript class from Entity metadata.\n * @param entityMetaData The Entity metadata that defines the class\n */\n private static generateClassForEntity(entityMetaData: EntityMetaData, iModel: IModelDb): typeof Entity {\n const name = entityMetaData.ecclass.split(\":\");\n const domainName = name[0];\n const className = name[1];\n\n if (0 === entityMetaData.baseClasses.length) // metadata must contain a superclass\n throw new IModelError(IModelStatus.BadArg, `class ${name} has no superclass`);\n\n // make sure schema exists\n let schema = Schemas.getRegisteredSchema(domainName);\n if (undefined === schema)\n schema = this.generateProxySchema(domainName, iModel); // no schema found, create it too\n\n const superclass = this._classMap.get(entityMetaData.baseClasses[0].toLowerCase());\n if (undefined === superclass)\n throw new IModelError(IModelStatus.NotFound, `cannot find superclass for class ${name}`);\n\n // user defined class hierarchies may skip a class in the hierarchy, and therefore their JS base class cannot\n // be used to tell if there are any generated classes in the hierarchy\n let generatedClassHasNonGeneratedNonCoreAncestor = false;\n let currentSuperclass = superclass;\n const MAX_ITERS = 1000;\n for (let i = 0; i < MAX_ITERS; ++i) {\n if (currentSuperclass.schema.schemaName === \"BisCore\")\n break;\n\n if (!currentSuperclass.isGeneratedClass) {\n generatedClassHasNonGeneratedNonCoreAncestor = true;\n break;\n }\n const superclassMetaData = iModel.classMetaDataRegistry.find(currentSuperclass.classFullName);\n if (superclassMetaData === undefined)\n throw new IModelError(IModelStatus.BadSchema, `could not find the metadata for class '${currentSuperclass.name}', class metadata should be loaded by now`);\n const maybeNextSuperclass = this.getClass(superclassMetaData.baseClasses[0], iModel);\n if (maybeNextSuperclass === undefined)\n throw new IModelError(IModelStatus.BadSchema, `could not find the base class of '${currentSuperclass.name}', all generated classes must have a base class`);\n currentSuperclass = maybeNextSuperclass;\n }\n\n const generatedClass = class extends superclass {\n public static override get className() { return className; }\n private static [isGeneratedClassTag] = true;\n public static override get isGeneratedClass() { return this.hasOwnProperty(isGeneratedClassTag); }\n };\n\n // the above creates an anonymous class. For help debugging, set the \"constructor.name\" property to be the same as the bisClassName.\n Object.defineProperty(generatedClass, \"name\", { get: () => className }); // this is the (only) way to change that readonly property.\n\n // a class only gets an automatic `collectReferenceConcreteIds` implementation if:\n // - it is not in the `BisCore` schema\n // - there are no ancestors with manually registered JS implementations, (excluding BisCore base classes)\n if (!generatedClassHasNonGeneratedNonCoreAncestor) {\n const navigationProps = Object.entries(entityMetaData.properties)\n .filter(([_name, prop]) => prop.isNavigation)\n // eslint-disable-next-line @typescript-eslint/no-shadow\n .map(([name, prop]) => {\n assert(prop.relationshipClass);\n const maybeMetaData = iModel.nativeDb.getSchemaItem(...prop.relationshipClass.split(\":\") as [string, string]);\n assert(maybeMetaData.result !== undefined, \"The nav props relationship metadata was not found\");\n const relMetaData = JSON.parse(maybeMetaData.result);\n const rootClassMetaData = ClassRegistry.getRootEntity(iModel, relMetaData.target.constraintClasses[0]);\n // root class must be in BisCore so should be loaded since biscore classes will never get this\n // generated implementation\n const normalizeClassName = (clsName: string) => clsName.replace(\".\", \":\");\n const rootClass = ClassRegistry.findRegisteredClass(normalizeClassName(rootClassMetaData));\n assert(rootClass, `The root class for ${prop.relationshipClass} was not in BisCore.`);\n return { name, concreteEntityType: EntityReferences.typeFromClass(rootClass) };\n });\n\n Object.defineProperty(\n generatedClass.prototype,\n \"collectReferenceConcreteIds\",\n {\n value(this: typeof generatedClass, referenceIds: EntityReferenceSet) {\n // eslint-disable-next-line @typescript-eslint/dot-notation\n const superImpl = superclass.prototype[\"collectReferenceConcreteIds\"];\n superImpl.call(this, referenceIds);\n for (const navProp of navigationProps) {\n const relatedElem: RelatedElement | undefined = (this as any)[navProp.name]; // cast to any since subclass can have any extensions\n if (!relatedElem || !Id64.isValid(relatedElem.id))\n continue;\n const referenceId = EntityReferences.fromEntityType(relatedElem.id, navProp.concreteEntityType);\n referenceIds.add(referenceId);\n }\n },\n // defaults for methods on a prototype (required for sinon to stub out methods on tests)\n writable: true,\n configurable: true,\n }\n );\n }\n\n // if the schema is a proxy for a domain with behavior, throw exceptions for all protected operations\n if (schema.missingRequiredBehavior) {\n const throwError = () => {\n throw new IModelError(IModelStatus.WrongHandler, `Schema [${domainName}] not registered, but is marked with SchemaHasBehavior`);\n };\n\n superclass.protectedOperations.forEach((operation) => (generatedClass as any)[operation] = throwError);\n }\n\n this.register(generatedClass, schema); // register it before returning\n return generatedClass;\n }\n\n /** Register all of the classes found in the given module that derive from Entity. See the example in [[Schema]]\n * @param moduleObj The module to search for subclasses of Entity\n * @param schema The schema for all found classes\n */\n public static registerModule(moduleObj: any, schema: typeof Schema) {\n for (const thisMember in moduleObj) { // eslint-disable-line guard-for-in\n const thisClass = moduleObj[thisMember];\n if (thisClass.prototype instanceof Entity)\n this.register(thisClass, schema);\n }\n }\n\n /**\n * This function fetches the specified Entity from the imodel, generates a JavaScript class for it, and registers the generated\n * class. This function also ensures that all of the base classes of the Entity exist and are registered.\n */\n private static generateClass(classFullName: string, iModel: IModelDb): typeof Entity {\n const metadata: EntityMetaData | undefined = iModel.classMetaDataRegistry.find(classFullName);\n if (metadata === undefined || metadata.ecclass === undefined)\n throw this.makeMetaDataNotFoundError(classFullName);\n\n // Make sure we have all base classes registered.\n if (metadata.baseClasses && (0 !== metadata.baseClasses.length))\n this.getClass(metadata.baseClasses[0], iModel);\n\n // Now we can generate the class from the classDef.\n return this.generateClassForEntity(metadata, iModel);\n }\n\n /** Find a registered class by classFullName.\n * @param classFullName class to find\n * @param iModel The IModel that contains the class definitions\n * @returns The Entity class or undefined\n */\n public static findRegisteredClass(classFullName: string): typeof Entity | undefined {\n return this._classMap.get(classFullName.toLowerCase());\n }\n\n /** Get the Entity class for the specified Entity className.\n * @param classFullName The full BIS class name of the Entity\n * @param iModel The IModel that contains the class definitions\n * @returns The Entity class\n */\n public static getClass(classFullName: string, iModel: IModelDb): typeof Entity {\n const key = classFullName.toLowerCase();\n const ctor = this._classMap.get(key);\n return ctor ? ctor : this.generateClass(key, iModel);\n }\n\n /** Unregister a class, by name, if one is already registered.\n * This function is not normally needed, but is useful for cases where a generated *proxy* class needs to be replaced by the *real* class.\n * @param classFullName Name of the class to unregister\n * @return true if the class was unregistered\n * @internal\n */\n public static unregisterCLass(classFullName: string) { return this._classMap.delete(classFullName.toLowerCase()); }\n /** Unregister all classes from a schema.\n * This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema.\n * @param schema Name of the schema to unregister\n * @internal\n */\n public static unregisterClassesFrom(schema: typeof Schema) {\n for (const entry of Array.from(this._classMap)) {\n if (entry[1].schema === schema)\n this.unregisterCLass(entry[0]);\n }\n }\n}\n\n/**\n * A cache that records the mapping between class names and class metadata\n * @internal\n */\nexport class MetaDataRegistry {\n private _registry: Map<string, EntityMetaData> = new Map<string, EntityMetaData>();\n\n /** Get the specified Entity metadata */\n public find(classFullName: string): EntityMetaData | undefined { return this._registry.get(classFullName.toLowerCase()); }\n\n /** Add metadata to the cache */\n public add(classFullName: string, metaData: EntityMetaData): void { this._registry.set(classFullName.toLowerCase(), metaData); }\n}\n"]}
1
+ {"version":3,"file":"ClassRegistry.js","sourceRoot":"","sources":["../../src/ClassRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Schema\r\n */\r\n\r\nimport { DbResult, Id64, IModelStatus, Logger } from \"@itwin/core-bentley\";\r\nimport { EntityMetaData, EntityReferenceSet, IModelError, RelatedElement } from \"@itwin/core-common\";\r\nimport { Entity } from \"./Entity\";\r\nimport { IModelDb } from \"./IModelDb\";\r\nimport { Schema, Schemas } from \"./Schema\";\r\nimport { EntityReferences } from \"./EntityReferences\";\r\nimport * as assert from \"assert\";\r\n\r\nconst isGeneratedClassTag = Symbol(\"isGeneratedClassTag\");\r\n\r\n/** The mapping between a BIS class name (in the form \"schema:class\") and its JavaScript constructor function\r\n * @public\r\n */\r\nexport class ClassRegistry {\r\n private static readonly _classMap = new Map<string, typeof Entity>();\r\n /** @internal */\r\n public static isNotFoundError(err: any) { return (err instanceof IModelError) && (err.errorNumber === IModelStatus.NotFound); }\r\n /** @internal */\r\n public static makeMetaDataNotFoundError(className: string): IModelError { return new IModelError(IModelStatus.NotFound, `metadata not found for ${className}`); }\r\n /** @internal */\r\n public static register(entityClass: typeof Entity, schema: typeof Schema) {\r\n entityClass.schema = schema;\r\n const key = (`${schema.schemaName}:${entityClass.className}`).toLowerCase();\r\n if (this._classMap.has(key)) {\r\n const errMsg = `Class ${key} is already registered. Make sure static className member is correct on JavaScript class ${entityClass.name}`;\r\n Logger.logError(\"core-frontend.classRegistry\", errMsg);\r\n throw new Error(errMsg);\r\n }\r\n\r\n this._classMap.set(key, entityClass);\r\n }\r\n\r\n /** Generate a proxy Schema for a domain that has not been registered. */\r\n private static generateProxySchema(domain: string, iModel: IModelDb): typeof Schema {\r\n const hasBehavior = iModel.withPreparedSqliteStatement(`\r\n SELECT NULL FROM [ec_CustomAttribute] [c]\r\n JOIN [ec_schema] [s] ON [s].[Id] = [c].[ContainerId]\r\n JOIN [ec_class] [e] ON [e].[Id] = [c].[ClassId]\r\n JOIN [ec_schema] [b] ON [e].[SchemaId] = [b].[Id]\r\n WHERE [c].[ContainerType] = 1 AND [s].[Name] = ? AND [b].[Name] || '.' || [e].[name] = ?`, (stmt) => {\r\n stmt.bindString(1, domain);\r\n stmt.bindString(2, \"BisCore.SchemaHasBehavior\");\r\n return stmt.step() === DbResult.BE_SQLITE_ROW;\r\n });\r\n\r\n const schemaClass = class extends Schema {\r\n public static override get schemaName() { return domain; }\r\n public static override get missingRequiredBehavior() { return hasBehavior; }\r\n };\r\n\r\n Schemas.registerSchema(schemaClass); // register the class before we return it.\r\n return schemaClass;\r\n }\r\n\r\n /** First, finds the root BisCore entity class for an entity, by traversing base classes and mixin targets (AppliesTo).\r\n * Then, gets its metadata and returns that.\r\n * @param iModel - iModel containing the metadata for this type\r\n * @param ecTypeQualifier - a full name of an ECEntityClass to find the root of\r\n * @returns the qualified full name of an ECEntityClass\r\n * @internal public for testing only\r\n */\r\n public static getRootEntity(iModel: IModelDb, ecTypeQualifier: string): string {\r\n const [classSchema, className] = ecTypeQualifier.split(\".\");\r\n const schemaItemJson = iModel.nativeDb.getSchemaItem(classSchema, className);\r\n if (schemaItemJson.error)\r\n throw new IModelError(schemaItemJson.error.status, `failed to get schema item '${ecTypeQualifier}'`);\r\n\r\n assert(undefined !== schemaItemJson.result);\r\n const schemaItem = JSON.parse(schemaItemJson.result);\r\n if (!(\"appliesTo\" in schemaItem) && schemaItem.baseClass === undefined) {\r\n return ecTypeQualifier;\r\n }\r\n\r\n // typescript doesn't understand that the inverse of the above condition is\r\n // (\"appliesTo\" in rootclassMetaData || rootClassMetaData.baseClass !== undefined)\r\n const parentItemQualifier = schemaItem.appliesTo ?? schemaItem.baseClass as string;\r\n return this.getRootEntity(iModel, parentItemQualifier);\r\n }\r\n\r\n /** Generate a JavaScript class from Entity metadata.\r\n * @param entityMetaData The Entity metadata that defines the class\r\n */\r\n private static generateClassForEntity(entityMetaData: EntityMetaData, iModel: IModelDb): typeof Entity {\r\n const name = entityMetaData.ecclass.split(\":\");\r\n const domainName = name[0];\r\n const className = name[1];\r\n\r\n if (0 === entityMetaData.baseClasses.length) // metadata must contain a superclass\r\n throw new IModelError(IModelStatus.BadArg, `class ${name} has no superclass`);\r\n\r\n // make sure schema exists\r\n let schema = Schemas.getRegisteredSchema(domainName);\r\n if (undefined === schema)\r\n schema = this.generateProxySchema(domainName, iModel); // no schema found, create it too\r\n\r\n const superclass = this._classMap.get(entityMetaData.baseClasses[0].toLowerCase());\r\n if (undefined === superclass)\r\n throw new IModelError(IModelStatus.NotFound, `cannot find superclass for class ${name}`);\r\n\r\n // user defined class hierarchies may skip a class in the hierarchy, and therefore their JS base class cannot\r\n // be used to tell if there are any generated classes in the hierarchy\r\n let generatedClassHasNonGeneratedNonCoreAncestor = false;\r\n let currentSuperclass = superclass;\r\n const MAX_ITERS = 1000;\r\n for (let i = 0; i < MAX_ITERS; ++i) {\r\n if (currentSuperclass.schema.schemaName === \"BisCore\")\r\n break;\r\n\r\n if (!currentSuperclass.isGeneratedClass) {\r\n generatedClassHasNonGeneratedNonCoreAncestor = true;\r\n break;\r\n }\r\n const superclassMetaData = iModel.classMetaDataRegistry.find(currentSuperclass.classFullName);\r\n if (superclassMetaData === undefined)\r\n throw new IModelError(IModelStatus.BadSchema, `could not find the metadata for class '${currentSuperclass.name}', class metadata should be loaded by now`);\r\n const maybeNextSuperclass = this.getClass(superclassMetaData.baseClasses[0], iModel);\r\n if (maybeNextSuperclass === undefined)\r\n throw new IModelError(IModelStatus.BadSchema, `could not find the base class of '${currentSuperclass.name}', all generated classes must have a base class`);\r\n currentSuperclass = maybeNextSuperclass;\r\n }\r\n\r\n const generatedClass = class extends superclass {\r\n public static override get className() { return className; }\r\n private static [isGeneratedClassTag] = true;\r\n public static override get isGeneratedClass() { return this.hasOwnProperty(isGeneratedClassTag); }\r\n };\r\n\r\n // the above creates an anonymous class. For help debugging, set the \"constructor.name\" property to be the same as the bisClassName.\r\n Object.defineProperty(generatedClass, \"name\", { get: () => className }); // this is the (only) way to change that readonly property.\r\n\r\n // a class only gets an automatic `collectReferenceConcreteIds` implementation if:\r\n // - it is not in the `BisCore` schema\r\n // - there are no ancestors with manually registered JS implementations, (excluding BisCore base classes)\r\n if (!generatedClassHasNonGeneratedNonCoreAncestor) {\r\n const navigationProps = Object.entries(entityMetaData.properties)\r\n .filter(([_name, prop]) => prop.isNavigation)\r\n // eslint-disable-next-line @typescript-eslint/no-shadow\r\n .map(([name, prop]) => {\r\n assert(prop.relationshipClass);\r\n const maybeMetaData = iModel.nativeDb.getSchemaItem(...prop.relationshipClass.split(\":\") as [string, string]);\r\n assert(maybeMetaData.result !== undefined, \"The nav props relationship metadata was not found\");\r\n const relMetaData = JSON.parse(maybeMetaData.result);\r\n const rootClassMetaData = ClassRegistry.getRootEntity(iModel, relMetaData.target.constraintClasses[0]);\r\n // root class must be in BisCore so should be loaded since biscore classes will never get this\r\n // generated implementation\r\n const normalizeClassName = (clsName: string) => clsName.replace(\".\", \":\");\r\n const rootClass = ClassRegistry.findRegisteredClass(normalizeClassName(rootClassMetaData));\r\n assert(rootClass, `The root class for ${prop.relationshipClass} was not in BisCore.`);\r\n return { name, concreteEntityType: EntityReferences.typeFromClass(rootClass) };\r\n });\r\n\r\n Object.defineProperty(\r\n generatedClass.prototype,\r\n \"collectReferenceConcreteIds\",\r\n {\r\n value(this: typeof generatedClass, referenceIds: EntityReferenceSet) {\r\n // eslint-disable-next-line @typescript-eslint/dot-notation\r\n const superImpl = superclass.prototype[\"collectReferenceConcreteIds\"];\r\n superImpl.call(this, referenceIds);\r\n for (const navProp of navigationProps) {\r\n const relatedElem: RelatedElement | undefined = (this as any)[navProp.name]; // cast to any since subclass can have any extensions\r\n if (!relatedElem || !Id64.isValid(relatedElem.id))\r\n continue;\r\n const referenceId = EntityReferences.fromEntityType(relatedElem.id, navProp.concreteEntityType);\r\n referenceIds.add(referenceId);\r\n }\r\n },\r\n // defaults for methods on a prototype (required for sinon to stub out methods on tests)\r\n writable: true,\r\n configurable: true,\r\n }\r\n );\r\n }\r\n\r\n // if the schema is a proxy for a domain with behavior, throw exceptions for all protected operations\r\n if (schema.missingRequiredBehavior) {\r\n const throwError = () => {\r\n throw new IModelError(IModelStatus.WrongHandler, `Schema [${domainName}] not registered, but is marked with SchemaHasBehavior`);\r\n };\r\n\r\n superclass.protectedOperations.forEach((operation) => (generatedClass as any)[operation] = throwError);\r\n }\r\n\r\n this.register(generatedClass, schema); // register it before returning\r\n return generatedClass;\r\n }\r\n\r\n /** Register all of the classes found in the given module that derive from Entity. See the example in [[Schema]]\r\n * @param moduleObj The module to search for subclasses of Entity\r\n * @param schema The schema for all found classes\r\n */\r\n public static registerModule(moduleObj: any, schema: typeof Schema) {\r\n for (const thisMember in moduleObj) { // eslint-disable-line guard-for-in\r\n const thisClass = moduleObj[thisMember];\r\n if (thisClass.prototype instanceof Entity)\r\n this.register(thisClass, schema);\r\n }\r\n }\r\n\r\n /**\r\n * This function fetches the specified Entity from the imodel, generates a JavaScript class for it, and registers the generated\r\n * class. This function also ensures that all of the base classes of the Entity exist and are registered.\r\n */\r\n private static generateClass(classFullName: string, iModel: IModelDb): typeof Entity {\r\n const metadata: EntityMetaData | undefined = iModel.classMetaDataRegistry.find(classFullName);\r\n if (metadata === undefined || metadata.ecclass === undefined)\r\n throw this.makeMetaDataNotFoundError(classFullName);\r\n\r\n // Make sure we have all base classes registered.\r\n if (metadata.baseClasses && (0 !== metadata.baseClasses.length))\r\n this.getClass(metadata.baseClasses[0], iModel);\r\n\r\n // Now we can generate the class from the classDef.\r\n return this.generateClassForEntity(metadata, iModel);\r\n }\r\n\r\n /** Find a registered class by classFullName.\r\n * @param classFullName class to find\r\n * @param iModel The IModel that contains the class definitions\r\n * @returns The Entity class or undefined\r\n */\r\n public static findRegisteredClass(classFullName: string): typeof Entity | undefined {\r\n return this._classMap.get(classFullName.toLowerCase());\r\n }\r\n\r\n /** Get the Entity class for the specified Entity className.\r\n * @param classFullName The full BIS class name of the Entity\r\n * @param iModel The IModel that contains the class definitions\r\n * @returns The Entity class\r\n */\r\n public static getClass(classFullName: string, iModel: IModelDb): typeof Entity {\r\n const key = classFullName.toLowerCase();\r\n const ctor = this._classMap.get(key);\r\n return ctor ? ctor : this.generateClass(key, iModel);\r\n }\r\n\r\n /** Unregister a class, by name, if one is already registered.\r\n * This function is not normally needed, but is useful for cases where a generated *proxy* class needs to be replaced by the *real* class.\r\n * @param classFullName Name of the class to unregister\r\n * @return true if the class was unregistered\r\n * @internal\r\n */\r\n public static unregisterCLass(classFullName: string) { return this._classMap.delete(classFullName.toLowerCase()); }\r\n /** Unregister all classes from a schema.\r\n * This function is not normally needed, but is useful for cases where a generated *proxy* schema needs to be replaced by the *real* schema.\r\n * @param schema Name of the schema to unregister\r\n * @internal\r\n */\r\n public static unregisterClassesFrom(schema: typeof Schema) {\r\n for (const entry of Array.from(this._classMap)) {\r\n if (entry[1].schema === schema)\r\n this.unregisterCLass(entry[0]);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * A cache that records the mapping between class names and class metadata\r\n * @internal\r\n */\r\nexport class MetaDataRegistry {\r\n private _registry: Map<string, EntityMetaData> = new Map<string, EntityMetaData>();\r\n\r\n /** Get the specified Entity metadata */\r\n public find(classFullName: string): EntityMetaData | undefined { return this._registry.get(classFullName.toLowerCase()); }\r\n\r\n /** Add metadata to the cache */\r\n public add(classFullName: string, metaData: EntityMetaData): void { this._registry.set(classFullName.toLowerCase(), metaData); }\r\n}\r\n"]}