@itwin/core-backend 5.15.0-dev.6 → 5.15.0-dev.7

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ElementSubModelInsert.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementSubModelInsert.test.d.ts","sourceRoot":"","sources":["../../../../src/test/element/ElementSubModelInsert.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,183 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the repository root for full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { expect } from "chai";
6
+ import { spy as sinonSpy } from "sinon";
7
+ import { Id64, IModelStatus } from "@itwin/core-bentley";
8
+ import { Code, IModel, IModelError } from "@itwin/core-common";
9
+ import { ClassRegistry } from "../../ClassRegistry";
10
+ import { withEditTxn } from "../../EditTxn";
11
+ import { Document, Drawing, SectionDrawing, Sheet, TemplateRecipe2d } from "../../Element";
12
+ import { GenericSchema } from "../../domains/GenericSchema";
13
+ import { SnapshotDb } from "../../IModelDb";
14
+ import { DefinitionModel, DocumentListModel, DrawingModel, SectionDrawingModel, SheetModel } from "../../Model";
15
+ import { Schema, Schemas } from "../../Schema";
16
+ import { IModelTestUtils } from "../IModelTestUtils";
17
+ class TestSubModelSchema extends Schema {
18
+ static get schemaName() { return "TestSubModel"; }
19
+ }
20
+ /** A Sheet subclass that overrides the hook and defers to the inherited validation via `super`. */
21
+ class TestSheetSpy extends Sheet {
22
+ static get className() { return "TestSheetSpy"; }
23
+ static onSubModelInsert(arg) {
24
+ super.onSubModelInsert(arg);
25
+ }
26
+ }
27
+ /** A Sheet subclass that widens the inherited rule to also permit a DrawingModel. */
28
+ class TestSheetWidened extends Sheet {
29
+ static get className() { return "TestSheetWidened"; }
30
+ static get allowedSubModelClasses() { return [SheetModel, DrawingModel]; }
31
+ }
32
+ /** A Sheet subclass that replaces the hook without calling `super`, opting out of validation. */
33
+ class TestSheetUnvalidated extends Sheet {
34
+ static get className() { return "TestSheetUnvalidated"; }
35
+ static onSubModelInsert(_arg) { }
36
+ }
37
+ /** A domain ISubModeledElement unrelated to Sheet/Drawing that opts in by overriding only the getter. */
38
+ class TestRestrictedDocument extends Document {
39
+ static get className() { return "TestRestrictedDocument"; }
40
+ static get allowedSubModelClasses() { return [DrawingModel]; }
41
+ }
42
+ const testSchemaXml = `<?xml version="1.0" encoding="UTF-8"?>
43
+ <ECSchema schemaName="TestSubModel" alias="tsm" version="01.00.00" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.3.2">
44
+ <ECSchemaReference name="BisCore" version="01.00.04" alias="bis"/>
45
+ <ECCustomAttributes>
46
+ <SchemaHasBehavior xmlns="BisCore.01.00.00"/>
47
+ </ECCustomAttributes>
48
+ <ECEntityClass typeName="TestSheetModel">
49
+ <BaseClass>bis:SheetModel</BaseClass>
50
+ </ECEntityClass>
51
+ <ECEntityClass typeName="TestSheetGenerated">
52
+ <BaseClass>bis:Sheet</BaseClass>
53
+ </ECEntityClass>
54
+ <ECEntityClass typeName="TestSheetSpy">
55
+ <BaseClass>bis:Sheet</BaseClass>
56
+ </ECEntityClass>
57
+ <ECEntityClass typeName="TestSheetWidened">
58
+ <BaseClass>bis:Sheet</BaseClass>
59
+ </ECEntityClass>
60
+ <ECEntityClass typeName="TestSheetUnvalidated">
61
+ <BaseClass>bis:Sheet</BaseClass>
62
+ </ECEntityClass>
63
+ <ECEntityClass typeName="TestHostDocument">
64
+ <BaseClass>bis:Document</BaseClass>
65
+ <BaseClass>bis:ISubModeledElement</BaseClass>
66
+ </ECEntityClass>
67
+ <ECEntityClass typeName="TestRestrictedDocument">
68
+ <BaseClass>bis:Document</BaseClass>
69
+ <BaseClass>bis:ISubModeledElement</BaseClass>
70
+ </ECEntityClass>
71
+ </ECSchema>`;
72
+ describe("Sub-model insert validation", () => {
73
+ let imodel;
74
+ let documentListModelId;
75
+ before(async () => {
76
+ GenericSchema.registerSchema();
77
+ Schemas.registerSchema(TestSubModelSchema);
78
+ ClassRegistry.register(TestSheetSpy, TestSubModelSchema);
79
+ ClassRegistry.register(TestSheetWidened, TestSubModelSchema);
80
+ ClassRegistry.register(TestSheetUnvalidated, TestSubModelSchema);
81
+ ClassRegistry.register(TestRestrictedDocument, TestSubModelSchema);
82
+ const iModelPath = IModelTestUtils.prepareOutputFile("SubModelInsert", "SubModelInsert.bim");
83
+ imodel = SnapshotDb.createEmpty(iModelPath, { rootSubject: { name: "SubModelInsertTest" } });
84
+ await imodel.importSchemaStrings([testSchemaXml]);
85
+ documentListModelId = withEditTxn(imodel, (txn) => DocumentListModel.insert(txn, SnapshotDb.rootSubjectId, "DocumentList"));
86
+ });
87
+ after(() => {
88
+ imodel.close();
89
+ Schemas.unregisterSchema(TestSubModelSchema.schemaName);
90
+ });
91
+ function insertHost(classFullName, modelId = documentListModelId) {
92
+ const id = withEditTxn(imodel, (txn) => txn.insertElement({ classFullName, model: modelId, code: Code.createEmpty() }));
93
+ expect(Id64.isValidId64(id)).to.be.true;
94
+ return id;
95
+ }
96
+ function insertSubModel(modelClassFullName, modeledElementId) {
97
+ return withEditTxn(imodel, (txn) => txn.insertModel({ classFullName: modelClassFullName, modeledElement: { id: modeledElementId } }));
98
+ }
99
+ function expectAccepted(hostClassFullName, modelClassFullName, hostModelId) {
100
+ const hostId = insertHost(hostClassFullName, hostModelId);
101
+ const modelId = insertSubModel(modelClassFullName, hostId);
102
+ expect(modelId).to.equal(hostId);
103
+ expect(imodel.models.getModel(modelId).classFullName).to.equal(modelClassFullName);
104
+ }
105
+ function expectRejected(hostClassFullName, modelClassFullName, hostModelId) {
106
+ const hostId = insertHost(hostClassFullName, hostModelId);
107
+ let error;
108
+ try {
109
+ insertSubModel(modelClassFullName, hostId);
110
+ }
111
+ catch (err) {
112
+ error = err;
113
+ }
114
+ expect(error).to.be.instanceOf(IModelError);
115
+ expect(error.errorNumber).to.equal(IModelStatus.WrongModel);
116
+ expect(error.message).to.contain("must be sub-modeled by");
117
+ expect(imodel.models.tryGetModel(hostId)).to.be.undefined;
118
+ }
119
+ describe("accepts", () => {
120
+ it("Sheet + SheetModel", () => expectAccepted(Sheet.classFullName, SheetModel.classFullName));
121
+ it("Drawing + DrawingModel", () => expectAccepted(Drawing.classFullName, DrawingModel.classFullName));
122
+ it("SectionDrawing + DrawingModel", () => expectAccepted(SectionDrawing.classFullName, DrawingModel.classFullName));
123
+ it("SectionDrawing + SectionDrawingModel", () => expectAccepted(SectionDrawing.classFullName, SectionDrawingModel.classFullName));
124
+ it("SectionDrawing + Generic:GraphicalModel3d", () => expectAccepted(SectionDrawing.classFullName, "Generic:GraphicalModel3d"));
125
+ it("TemplateRecipe2d + DrawingModel", () => expectAccepted(TemplateRecipe2d.classFullName, DrawingModel.classFullName, IModel.dictionaryId));
126
+ it("Sheet + SheetModel subclass without a JS class", () => expectAccepted(Sheet.classFullName, "TestSubModel:TestSheetModel"));
127
+ it("no allowedSubModelClasses → any model accepted", () => {
128
+ expectAccepted("TestSubModel:TestHostDocument", SheetModel.classFullName);
129
+ expectAccepted("TestSubModel:TestHostDocument", DrawingModel.classFullName);
130
+ });
131
+ it("Sheet subclass that widens allowedSubModelClasses + DrawingModel", () => expectAccepted(TestSheetWidened.classFullName, DrawingModel.classFullName));
132
+ it("Sheet subclass that overrides onSubModelInsert without super + DrawingModel", () => expectAccepted(TestSheetUnvalidated.classFullName, DrawingModel.classFullName));
133
+ it("Document subclass with allowedSubModelClasses + DrawingModel", () => expectAccepted(TestRestrictedDocument.classFullName, DrawingModel.classFullName));
134
+ });
135
+ describe("rejects with IModelStatus.WrongModel", () => {
136
+ it("Sheet + DrawingModel", () => expectRejected(Sheet.classFullName, DrawingModel.classFullName));
137
+ it("Drawing + SheetModel", () => expectRejected(Drawing.classFullName, SheetModel.classFullName));
138
+ it("SectionDrawing + SheetModel", () => expectRejected(SectionDrawing.classFullName, SheetModel.classFullName));
139
+ it("TemplateRecipe2d + SheetModel", () => expectRejected(TemplateRecipe2d.classFullName, SheetModel.classFullName, IModel.dictionaryId));
140
+ it("Sheet subclass without a JS class + DrawingModel", () => expectRejected("TestSubModel:TestSheetGenerated", DrawingModel.classFullName));
141
+ it("Document subclass with allowedSubModelClasses + SheetModel", () => expectRejected(TestRestrictedDocument.classFullName, SheetModel.classFullName));
142
+ });
143
+ it("invokes an overriding subclass hook that defers to the inherited validation", () => {
144
+ const spy = sinonSpy(TestSheetSpy, "onSubModelInsert");
145
+ try {
146
+ expectAccepted(TestSheetSpy.classFullName, SheetModel.classFullName);
147
+ expect(spy.calledOnce).to.be.true;
148
+ expect(spy.getCall(0).args[0].subModelProps.classFullName).to.equal(SheetModel.classFullName);
149
+ expectRejected(TestSheetSpy.classFullName, DrawingModel.classFullName);
150
+ expect(spy.calledTwice).to.be.true;
151
+ expect(spy.getCall(1).threw()).to.be.true;
152
+ }
153
+ finally {
154
+ spy.restore();
155
+ }
156
+ });
157
+ describe("missing required behavior", () => {
158
+ it("rejects sub-model insertion", () => {
159
+ const hostId = insertHost(TestRestrictedDocument.classFullName);
160
+ Schemas.unregisterSchema(TestSubModelSchema.schemaName);
161
+ try {
162
+ let error;
163
+ try {
164
+ insertSubModel(DefinitionModel.classFullName, hostId);
165
+ }
166
+ catch (err) {
167
+ error = err;
168
+ }
169
+ expect(error).to.be.instanceOf(IModelError);
170
+ expect(error.errorNumber).to.equal(IModelStatus.WrongHandler);
171
+ expect(imodel.models.tryGetModel(hostId)).to.be.undefined;
172
+ }
173
+ finally {
174
+ Schemas.registerSchema(TestSubModelSchema);
175
+ ClassRegistry.register(TestSheetSpy, TestSubModelSchema);
176
+ ClassRegistry.register(TestSheetWidened, TestSubModelSchema);
177
+ ClassRegistry.register(TestSheetUnvalidated, TestSubModelSchema);
178
+ ClassRegistry.register(TestRestrictedDocument, TestSubModelSchema);
179
+ }
180
+ });
181
+ });
182
+ });
183
+ //# sourceMappingURL=ElementSubModelInsert.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementSubModelInsert.test.js","sourceRoot":"","sources":["../../../../src/test/element/ElementSubModelInsert.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the repository root for full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { expect } from \"chai\";\r\nimport { spy as sinonSpy } from \"sinon\";\r\nimport { Id64, Id64String, IModelStatus } from \"@itwin/core-bentley\";\r\nimport { Code, IModel, IModelError } from \"@itwin/core-common\";\r\nimport { ClassRegistry } from \"../../ClassRegistry\";\r\nimport { withEditTxn } from \"../../EditTxn\";\r\nimport { Document, Drawing, OnSubModelPropsArg, SectionDrawing, Sheet, TemplateRecipe2d } from \"../../Element\";\r\nimport { EntityClassType } from \"../../Entity\";\r\nimport { GenericSchema } from \"../../domains/GenericSchema\";\r\nimport { SnapshotDb } from \"../../IModelDb\";\r\nimport { DefinitionModel, DocumentListModel, DrawingModel, Model, SectionDrawingModel, SheetModel } from \"../../Model\";\r\nimport { Schema, Schemas } from \"../../Schema\";\r\nimport { IModelTestUtils } from \"../IModelTestUtils\";\r\n\r\nclass TestSubModelSchema extends Schema {\r\n public static override get schemaName(): string { return \"TestSubModel\"; }\r\n}\r\n\r\n/** A Sheet subclass that overrides the hook and defers to the inherited validation via `super`. */\r\nclass TestSheetSpy extends Sheet {\r\n public static override get className(): string { return \"TestSheetSpy\"; }\r\n public static override onSubModelInsert(arg: OnSubModelPropsArg): void {\r\n super.onSubModelInsert(arg);\r\n }\r\n}\r\n\r\n/** A Sheet subclass that widens the inherited rule to also permit a DrawingModel. */\r\nclass TestSheetWidened extends Sheet {\r\n public static override get className(): string { return \"TestSheetWidened\"; }\r\n protected static override get allowedSubModelClasses(): Array<EntityClassType<Model>> { return [SheetModel, DrawingModel]; }\r\n}\r\n\r\n/** A Sheet subclass that replaces the hook without calling `super`, opting out of validation. */\r\nclass TestSheetUnvalidated extends Sheet {\r\n public static override get className(): string { return \"TestSheetUnvalidated\"; }\r\n public static override onSubModelInsert(_arg: OnSubModelPropsArg): void { }\r\n}\r\n\r\n/** A domain ISubModeledElement unrelated to Sheet/Drawing that opts in by overriding only the getter. */\r\nclass TestRestrictedDocument extends Document {\r\n public static override get className(): string { return \"TestRestrictedDocument\"; }\r\n protected static override get allowedSubModelClasses(): Array<EntityClassType<Model>> { return [DrawingModel]; }\r\n}\r\n\r\nconst testSchemaXml = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<ECSchema schemaName=\"TestSubModel\" alias=\"tsm\" version=\"01.00.00\" xmlns=\"http://www.bentley.com/schemas/Bentley.ECXML.3.2\">\r\n <ECSchemaReference name=\"BisCore\" version=\"01.00.04\" alias=\"bis\"/>\r\n <ECCustomAttributes>\r\n <SchemaHasBehavior xmlns=\"BisCore.01.00.00\"/>\r\n </ECCustomAttributes>\r\n <ECEntityClass typeName=\"TestSheetModel\">\r\n <BaseClass>bis:SheetModel</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestSheetGenerated\">\r\n <BaseClass>bis:Sheet</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestSheetSpy\">\r\n <BaseClass>bis:Sheet</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestSheetWidened\">\r\n <BaseClass>bis:Sheet</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestSheetUnvalidated\">\r\n <BaseClass>bis:Sheet</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestHostDocument\">\r\n <BaseClass>bis:Document</BaseClass>\r\n <BaseClass>bis:ISubModeledElement</BaseClass>\r\n </ECEntityClass>\r\n <ECEntityClass typeName=\"TestRestrictedDocument\">\r\n <BaseClass>bis:Document</BaseClass>\r\n <BaseClass>bis:ISubModeledElement</BaseClass>\r\n </ECEntityClass>\r\n</ECSchema>`;\r\n\r\ndescribe(\"Sub-model insert validation\", () => {\r\n let imodel: SnapshotDb;\r\n let documentListModelId: Id64String;\r\n\r\n before(async () => {\r\n GenericSchema.registerSchema();\r\n Schemas.registerSchema(TestSubModelSchema);\r\n ClassRegistry.register(TestSheetSpy, TestSubModelSchema);\r\n ClassRegistry.register(TestSheetWidened, TestSubModelSchema);\r\n ClassRegistry.register(TestSheetUnvalidated, TestSubModelSchema);\r\n ClassRegistry.register(TestRestrictedDocument, TestSubModelSchema);\r\n\r\n const iModelPath = IModelTestUtils.prepareOutputFile(\"SubModelInsert\", \"SubModelInsert.bim\");\r\n imodel = SnapshotDb.createEmpty(iModelPath, { rootSubject: { name: \"SubModelInsertTest\" } });\r\n await imodel.importSchemaStrings([testSchemaXml]);\r\n documentListModelId = withEditTxn(imodel, (txn) => DocumentListModel.insert(txn, SnapshotDb.rootSubjectId, \"DocumentList\"));\r\n });\r\n\r\n after(() => {\r\n imodel.close();\r\n Schemas.unregisterSchema(TestSubModelSchema.schemaName);\r\n });\r\n\r\n function insertHost(classFullName: string, modelId: Id64String = documentListModelId): Id64String {\r\n const id = withEditTxn(imodel, (txn) => txn.insertElement({ classFullName, model: modelId, code: Code.createEmpty() }));\r\n expect(Id64.isValidId64(id)).to.be.true;\r\n return id;\r\n }\r\n\r\n function insertSubModel(modelClassFullName: string, modeledElementId: Id64String): Id64String {\r\n return withEditTxn(imodel, (txn) => txn.insertModel({ classFullName: modelClassFullName, modeledElement: { id: modeledElementId } }));\r\n }\r\n\r\n function expectAccepted(hostClassFullName: string, modelClassFullName: string, hostModelId?: Id64String): void {\r\n const hostId = insertHost(hostClassFullName, hostModelId);\r\n const modelId = insertSubModel(modelClassFullName, hostId);\r\n expect(modelId).to.equal(hostId);\r\n expect(imodel.models.getModel(modelId).classFullName).to.equal(modelClassFullName);\r\n }\r\n\r\n function expectRejected(hostClassFullName: string, modelClassFullName: string, hostModelId?: Id64String): void {\r\n const hostId = insertHost(hostClassFullName, hostModelId);\r\n let error: unknown;\r\n try {\r\n insertSubModel(modelClassFullName, hostId);\r\n } catch (err) {\r\n error = err;\r\n }\r\n\r\n expect(error).to.be.instanceOf(IModelError);\r\n expect((error as IModelError).errorNumber).to.equal(IModelStatus.WrongModel);\r\n expect((error as IModelError).message).to.contain(\"must be sub-modeled by\");\r\n expect(imodel.models.tryGetModel(hostId)).to.be.undefined;\r\n }\r\n\r\n describe(\"accepts\", () => {\r\n it(\"Sheet + SheetModel\", () => expectAccepted(Sheet.classFullName, SheetModel.classFullName));\r\n it(\"Drawing + DrawingModel\", () => expectAccepted(Drawing.classFullName, DrawingModel.classFullName));\r\n it(\"SectionDrawing + DrawingModel\", () => expectAccepted(SectionDrawing.classFullName, DrawingModel.classFullName));\r\n it(\"SectionDrawing + SectionDrawingModel\", () => expectAccepted(SectionDrawing.classFullName, SectionDrawingModel.classFullName));\r\n it(\"SectionDrawing + Generic:GraphicalModel3d\", () => expectAccepted(SectionDrawing.classFullName, \"Generic:GraphicalModel3d\"));\r\n it(\"TemplateRecipe2d + DrawingModel\", () => expectAccepted(TemplateRecipe2d.classFullName, DrawingModel.classFullName, IModel.dictionaryId));\r\n it(\"Sheet + SheetModel subclass without a JS class\", () => expectAccepted(Sheet.classFullName, \"TestSubModel:TestSheetModel\"));\r\n it(\"no allowedSubModelClasses → any model accepted\", () => {\r\n expectAccepted(\"TestSubModel:TestHostDocument\", SheetModel.classFullName);\r\n expectAccepted(\"TestSubModel:TestHostDocument\", DrawingModel.classFullName);\r\n });\r\n it(\"Sheet subclass that widens allowedSubModelClasses + DrawingModel\", () => expectAccepted(TestSheetWidened.classFullName, DrawingModel.classFullName));\r\n it(\"Sheet subclass that overrides onSubModelInsert without super + DrawingModel\", () => expectAccepted(TestSheetUnvalidated.classFullName, DrawingModel.classFullName));\r\n it(\"Document subclass with allowedSubModelClasses + DrawingModel\", () => expectAccepted(TestRestrictedDocument.classFullName, DrawingModel.classFullName));\r\n });\r\n\r\n describe(\"rejects with IModelStatus.WrongModel\", () => {\r\n it(\"Sheet + DrawingModel\", () => expectRejected(Sheet.classFullName, DrawingModel.classFullName));\r\n it(\"Drawing + SheetModel\", () => expectRejected(Drawing.classFullName, SheetModel.classFullName));\r\n it(\"SectionDrawing + SheetModel\", () => expectRejected(SectionDrawing.classFullName, SheetModel.classFullName));\r\n it(\"TemplateRecipe2d + SheetModel\", () => expectRejected(TemplateRecipe2d.classFullName, SheetModel.classFullName, IModel.dictionaryId));\r\n it(\"Sheet subclass without a JS class + DrawingModel\", () => expectRejected(\"TestSubModel:TestSheetGenerated\", DrawingModel.classFullName));\r\n it(\"Document subclass with allowedSubModelClasses + SheetModel\", () => expectRejected(TestRestrictedDocument.classFullName, SheetModel.classFullName));\r\n });\r\n\r\n it(\"invokes an overriding subclass hook that defers to the inherited validation\", () => {\r\n const spy = sinonSpy(TestSheetSpy, \"onSubModelInsert\");\r\n try {\r\n expectAccepted(TestSheetSpy.classFullName, SheetModel.classFullName);\r\n expect(spy.calledOnce).to.be.true;\r\n expect(spy.getCall(0).args[0].subModelProps.classFullName).to.equal(SheetModel.classFullName);\r\n\r\n expectRejected(TestSheetSpy.classFullName, DrawingModel.classFullName);\r\n expect(spy.calledTwice).to.be.true;\r\n expect(spy.getCall(1).threw()).to.be.true;\r\n } finally {\r\n spy.restore();\r\n }\r\n });\r\n\r\n describe(\"missing required behavior\", () => {\r\n it(\"rejects sub-model insertion\", () => {\r\n const hostId = insertHost(TestRestrictedDocument.classFullName);\r\n Schemas.unregisterSchema(TestSubModelSchema.schemaName);\r\n\r\n try {\r\n let error: unknown;\r\n try {\r\n insertSubModel(DefinitionModel.classFullName, hostId);\r\n } catch (err) {\r\n error = err;\r\n }\r\n\r\n expect(error).to.be.instanceOf(IModelError);\r\n expect((error as IModelError).errorNumber).to.equal(IModelStatus.WrongHandler);\r\n expect(imodel.models.tryGetModel(hostId)).to.be.undefined;\r\n } finally {\r\n Schemas.registerSchema(TestSubModelSchema);\r\n ClassRegistry.register(TestSheetSpy, TestSubModelSchema);\r\n ClassRegistry.register(TestSheetWidened, TestSubModelSchema);\r\n ClassRegistry.register(TestSheetUnvalidated, TestSubModelSchema);\r\n ClassRegistry.register(TestRestrictedDocument, TestSubModelSchema);\r\n }\r\n });\r\n });\r\n});\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/core-backend",
3
- "version": "5.15.0-dev.6",
3
+ "version": "5.15.0-dev.7",
4
4
  "description": "iTwin.js backend components",
5
5
  "main": "lib/cjs/core-backend.js",
6
6
  "module": "lib/esm/core-backend.js",
@@ -27,11 +27,11 @@
27
27
  },
28
28
  "peerDependencies": {
29
29
  "@opentelemetry/api": "^1.0.4",
30
- "@itwin/core-bentley": "5.15.0-dev.6",
31
- "@itwin/ecschema-metadata": "5.15.0-dev.6",
32
- "@itwin/core-geometry": "5.15.0-dev.6",
33
- "@itwin/core-common": "5.15.0-dev.6",
34
- "@itwin/core-quantity": "5.15.0-dev.6"
30
+ "@itwin/core-bentley": "5.15.0-dev.7",
31
+ "@itwin/ecschema-metadata": "5.15.0-dev.7",
32
+ "@itwin/core-common": "5.15.0-dev.7",
33
+ "@itwin/core-geometry": "5.15.0-dev.7",
34
+ "@itwin/core-quantity": "5.15.0-dev.7"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@opentelemetry/api": {
@@ -72,18 +72,18 @@
72
72
  "marked": "^14.1.3",
73
73
  "sql-formatter": "^15.4.6",
74
74
  "vite": "^6.4.3",
75
- "@itwin/build-tools": "5.15.0-dev.6",
76
- "@itwin/core-quantity": "5.15.0-dev.6",
77
- "@itwin/core-bentley": "5.15.0-dev.6",
78
- "@itwin/ecschema-locaters": "5.15.0-dev.6",
79
- "@itwin/core-common": "5.15.0-dev.6",
80
- "@itwin/ecsql-common": "5.15.0-dev.6",
81
- "@itwin/ecschema-metadata": "5.15.0-dev.6",
75
+ "@itwin/build-tools": "5.15.0-dev.7",
76
+ "@itwin/core-bentley": "5.15.0-dev.7",
77
+ "@itwin/core-quantity": "5.15.0-dev.7",
78
+ "@itwin/core-common": "5.15.0-dev.7",
79
+ "@itwin/core-geometry": "5.15.0-dev.7",
80
+ "@itwin/ecschema-metadata": "5.15.0-dev.7",
81
+ "@itwin/ecsql-common": "5.15.0-dev.7",
82
82
  "internal-tools": "3.0.0-dev.69",
83
- "@itwin/core-geometry": "5.15.0-dev.6"
83
+ "@itwin/ecschema-locaters": "5.15.0-dev.7"
84
84
  },
85
85
  "dependencies": {
86
- "@bentley/imodeljs-native": "5.15.10",
86
+ "@bentley/imodeljs-native": "5.15.11",
87
87
  "@itwin/object-storage-azure": "^3.0.4",
88
88
  "@azure/storage-blob": "^12.28.0",
89
89
  "form-data": "^4.0.6",