@itwin/core-backend 3.5.0-dev.18 → 3.5.0-dev.20

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