@itwin/ecschema-editing 3.7.0-dev.6 → 3.7.0-dev.8

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 (147) hide show
  1. package/CHANGELOG.md +6 -1
  2. package/lib/cjs/Editing/Constants.d.ts +20 -20
  3. package/lib/cjs/Editing/Constants.js +60 -60
  4. package/lib/cjs/Editing/Constants.js.map +1 -1
  5. package/lib/cjs/Editing/CustomAttributes.d.ts +20 -20
  6. package/lib/cjs/Editing/CustomAttributes.js +59 -59
  7. package/lib/cjs/Editing/CustomAttributes.js.map +1 -1
  8. package/lib/cjs/Editing/ECClasses.d.ts +54 -54
  9. package/lib/cjs/Editing/ECClasses.js +269 -269
  10. package/lib/cjs/Editing/ECClasses.js.map +1 -1
  11. package/lib/cjs/Editing/Editor.d.ts +112 -112
  12. package/lib/cjs/Editing/Editor.js +166 -166
  13. package/lib/cjs/Editing/Editor.js.map +1 -1
  14. package/lib/cjs/Editing/Entities.d.ts +25 -25
  15. package/lib/cjs/Editing/Entities.js +116 -116
  16. package/lib/cjs/Editing/Entities.js.map +1 -1
  17. package/lib/cjs/Editing/Enumerations.d.ts +21 -21
  18. package/lib/cjs/Editing/Enumerations.js +66 -66
  19. package/lib/cjs/Editing/Enumerations.js.map +1 -1
  20. package/lib/cjs/Editing/Formats.d.ts +21 -21
  21. package/lib/cjs/Editing/Formats.js +61 -61
  22. package/lib/cjs/Editing/Formats.js.map +1 -1
  23. package/lib/cjs/Editing/InvertedUnits.d.ts +17 -17
  24. package/lib/cjs/Editing/InvertedUnits.js +82 -82
  25. package/lib/cjs/Editing/InvertedUnits.js.map +1 -1
  26. package/lib/cjs/Editing/KindOfQuantities.d.ts +28 -28
  27. package/lib/cjs/Editing/KindOfQuantities.js +78 -78
  28. package/lib/cjs/Editing/KindOfQuantities.js.map +1 -1
  29. package/lib/cjs/Editing/Mixins.d.ts +22 -22
  30. package/lib/cjs/Editing/Mixins.js +84 -84
  31. package/lib/cjs/Editing/Mixins.js.map +1 -1
  32. package/lib/cjs/Editing/Mutable/MutableCAClass.d.ts +9 -9
  33. package/lib/cjs/Editing/Mutable/MutableCAClass.js +15 -15
  34. package/lib/cjs/Editing/Mutable/MutableCAClass.js.map +1 -1
  35. package/lib/cjs/Editing/Mutable/MutableClass.d.ts +34 -34
  36. package/lib/cjs/Editing/Mutable/MutableClass.js +22 -22
  37. package/lib/cjs/Editing/Mutable/MutableClass.js.map +1 -1
  38. package/lib/cjs/Editing/Mutable/MutableConstant.d.ts +12 -12
  39. package/lib/cjs/Editing/Mutable/MutableConstant.js +15 -15
  40. package/lib/cjs/Editing/Mutable/MutableConstant.js.map +1 -1
  41. package/lib/cjs/Editing/Mutable/MutableEntityClass.d.ts +15 -15
  42. package/lib/cjs/Editing/Mutable/MutableEntityClass.js +59 -59
  43. package/lib/cjs/Editing/Mutable/MutableEntityClass.js.map +1 -1
  44. package/lib/cjs/Editing/Mutable/MutableEnumeration.d.ts +9 -9
  45. package/lib/cjs/Editing/Mutable/MutableEnumeration.js +14 -14
  46. package/lib/cjs/Editing/Mutable/MutableEnumeration.js.map +1 -1
  47. package/lib/cjs/Editing/Mutable/MutableFormat.d.ts +18 -18
  48. package/lib/cjs/Editing/Mutable/MutableFormat.js +15 -15
  49. package/lib/cjs/Editing/Mutable/MutableFormat.js.map +1 -1
  50. package/lib/cjs/Editing/Mutable/MutableInvertedUnit.d.ts +10 -10
  51. package/lib/cjs/Editing/Mutable/MutableInvertedUnit.js +15 -15
  52. package/lib/cjs/Editing/Mutable/MutableInvertedUnit.js.map +1 -1
  53. package/lib/cjs/Editing/Mutable/MutableKindOfQuantity.d.ts +10 -10
  54. package/lib/cjs/Editing/Mutable/MutableKindOfQuantity.js +15 -15
  55. package/lib/cjs/Editing/Mutable/MutableKindOfQuantity.js.map +1 -1
  56. package/lib/cjs/Editing/Mutable/MutableMixin.d.ts +11 -11
  57. package/lib/cjs/Editing/Mutable/MutableMixin.js +15 -15
  58. package/lib/cjs/Editing/Mutable/MutableMixin.js.map +1 -1
  59. package/lib/cjs/Editing/Mutable/MutablePhenomenon.d.ts +9 -9
  60. package/lib/cjs/Editing/Mutable/MutablePhenomenon.js +15 -15
  61. package/lib/cjs/Editing/Mutable/MutablePhenomenon.js.map +1 -1
  62. package/lib/cjs/Editing/Mutable/MutableProperty.d.ts +8 -8
  63. package/lib/cjs/Editing/Mutable/MutableProperty.js +15 -15
  64. package/lib/cjs/Editing/Mutable/MutableProperty.js.map +1 -1
  65. package/lib/cjs/Editing/Mutable/MutablePropertyCategory.d.ts +9 -9
  66. package/lib/cjs/Editing/Mutable/MutablePropertyCategory.js +15 -15
  67. package/lib/cjs/Editing/Mutable/MutablePropertyCategory.js.map +1 -1
  68. package/lib/cjs/Editing/Mutable/MutableRelationshipClass.d.ts +21 -21
  69. package/lib/cjs/Editing/Mutable/MutableRelationshipClass.js +24 -24
  70. package/lib/cjs/Editing/Mutable/MutableRelationshipClass.js.map +1 -1
  71. package/lib/cjs/Editing/Mutable/MutableSchema.d.ts +45 -45
  72. package/lib/cjs/Editing/Mutable/MutableSchema.js +17 -17
  73. package/lib/cjs/Editing/Mutable/MutableSchema.js.map +1 -1
  74. package/lib/cjs/Editing/Mutable/MutableUnit.d.ts +11 -11
  75. package/lib/cjs/Editing/Mutable/MutableUnit.js +15 -15
  76. package/lib/cjs/Editing/Mutable/MutableUnit.js.map +1 -1
  77. package/lib/cjs/Editing/Mutable/MutableUnitSystem.d.ts +8 -8
  78. package/lib/cjs/Editing/Mutable/MutableUnitSystem.js +15 -15
  79. package/lib/cjs/Editing/Mutable/MutableUnitSystem.js.map +1 -1
  80. package/lib/cjs/Editing/Phenomena.d.ts +15 -15
  81. package/lib/cjs/Editing/Phenomena.js +44 -44
  82. package/lib/cjs/Editing/Phenomena.js.map +1 -1
  83. package/lib/cjs/Editing/PropertyCategories.d.ts +16 -16
  84. package/lib/cjs/Editing/PropertyCategories.js +51 -51
  85. package/lib/cjs/Editing/PropertyCategories.js.map +1 -1
  86. package/lib/cjs/Editing/RelationshipClasses.d.ts +21 -21
  87. package/lib/cjs/Editing/RelationshipClasses.js +68 -68
  88. package/lib/cjs/Editing/RelationshipClasses.js.map +1 -1
  89. package/lib/cjs/Editing/Structs.d.ts +19 -19
  90. package/lib/cjs/Editing/Structs.js +57 -57
  91. package/lib/cjs/Editing/Structs.js.map +1 -1
  92. package/lib/cjs/Editing/UnitSystems.d.ts +15 -15
  93. package/lib/cjs/Editing/UnitSystems.js +41 -41
  94. package/lib/cjs/Editing/UnitSystems.js.map +1 -1
  95. package/lib/cjs/Editing/Units.d.ts +15 -15
  96. package/lib/cjs/Editing/Units.js +58 -58
  97. package/lib/cjs/Editing/Units.js.map +1 -1
  98. package/lib/cjs/Validation/Diagnostic.d.ts +321 -321
  99. package/lib/cjs/Validation/Diagnostic.js +310 -310
  100. package/lib/cjs/Validation/Diagnostic.js.map +1 -1
  101. package/lib/cjs/Validation/DiagnosticReporter.d.ts +96 -96
  102. package/lib/cjs/Validation/DiagnosticReporter.js +106 -106
  103. package/lib/cjs/Validation/DiagnosticReporter.js.map +1 -1
  104. package/lib/cjs/Validation/ECRules.d.ts +448 -448
  105. package/lib/cjs/Validation/ECRules.js +593 -593
  106. package/lib/cjs/Validation/ECRules.js.map +1 -1
  107. package/lib/cjs/Validation/LoggingDiagnosticReporter.d.ts +13 -13
  108. package/lib/cjs/Validation/LoggingDiagnosticReporter.js +40 -40
  109. package/lib/cjs/Validation/LoggingDiagnosticReporter.js.map +1 -1
  110. package/lib/cjs/Validation/RuleSuppressionSet.d.ts +59 -59
  111. package/lib/cjs/Validation/RuleSuppressionSet.js +9 -9
  112. package/lib/cjs/Validation/RuleSuppressionSet.js.map +1 -1
  113. package/lib/cjs/Validation/Rules.d.ts +64 -64
  114. package/lib/cjs/Validation/Rules.js +9 -9
  115. package/lib/cjs/Validation/Rules.js.map +1 -1
  116. package/lib/cjs/Validation/SchemaChanges.d.ts +607 -607
  117. package/lib/cjs/Validation/SchemaChanges.js +1135 -1135
  118. package/lib/cjs/Validation/SchemaChanges.js.map +1 -1
  119. package/lib/cjs/Validation/SchemaCompareDiagnostics.d.ts +422 -422
  120. package/lib/cjs/Validation/SchemaCompareDiagnostics.js +111 -111
  121. package/lib/cjs/Validation/SchemaCompareDiagnostics.js.map +1 -1
  122. package/lib/cjs/Validation/SchemaCompareReporter.d.ts +11 -11
  123. package/lib/cjs/Validation/SchemaCompareReporter.js +9 -9
  124. package/lib/cjs/Validation/SchemaCompareReporter.js.map +1 -1
  125. package/lib/cjs/Validation/SchemaCompareResultDelegate.d.ts +236 -236
  126. package/lib/cjs/Validation/SchemaCompareResultDelegate.js +348 -348
  127. package/lib/cjs/Validation/SchemaCompareResultDelegate.js.map +1 -1
  128. package/lib/cjs/Validation/SchemaCompareVisitor.d.ts +119 -119
  129. package/lib/cjs/Validation/SchemaCompareVisitor.js +206 -206
  130. package/lib/cjs/Validation/SchemaCompareVisitor.js.map +1 -1
  131. package/lib/cjs/Validation/SchemaComparer.d.ts +171 -171
  132. package/lib/cjs/Validation/SchemaComparer.js +666 -666
  133. package/lib/cjs/Validation/SchemaComparer.js.map +1 -1
  134. package/lib/cjs/Validation/SchemaValidater.d.ts +19 -19
  135. package/lib/cjs/Validation/SchemaValidater.js +61 -61
  136. package/lib/cjs/Validation/SchemaValidater.js.map +1 -1
  137. package/lib/cjs/Validation/SchemaValidationVisitor.d.ts +170 -170
  138. package/lib/cjs/Validation/SchemaValidationVisitor.js +492 -492
  139. package/lib/cjs/Validation/SchemaValidationVisitor.js.map +1 -1
  140. package/lib/cjs/Validation/SchemaWalker.d.ts +22 -22
  141. package/lib/cjs/Validation/SchemaWalker.js +51 -51
  142. package/lib/cjs/Validation/SchemaWalker.js.map +1 -1
  143. package/lib/cjs/ecschema-editing.d.ts +33 -33
  144. package/lib/cjs/ecschema-editing.js +54 -54
  145. package/lib/cjs/ecschema-editing.js.map +1 -1
  146. package/package.json +10 -10
  147. package/public/locales/en/ECSchemaEditing.json +26 -26
@@ -1,594 +1,594 @@
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 Validation
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.validateCustomAttributeInstance = exports.mixinAppliedToClassMustDeriveFromConstraint = exports.enumerationTypeUnsupported = exports.abstractConstraintMustExistWithMultipleConstraints = exports.atLeastOneConstraintClassDefined = exports.constraintClassesDeriveFromAbstractContraint = exports.derivedConstraintsMustNarrowBaseConstraints = exports.abstractConstraintMustNarrowBaseConstraints = exports.validateNavigationProperty = exports.incompatibleUnitPropertyOverride = exports.incompatibleTypePropertyOverride = exports.incompatibleValueTypePropertyOverride = exports.abstractClassWithNonAbstractBase = exports.baseClassIsOfDifferentType = exports.baseClassIsSealed = exports.validateSchemaReferencesSync = exports.validateSchemaReferences = exports.ECRuleSet = exports.Diagnostics = exports.DiagnosticCodes = void 0;
11
- const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
12
- const Diagnostic_1 = require("./Diagnostic");
13
- const ruleSetName = "ECObjects";
14
- function getCode(code) {
15
- return `${ruleSetName}-${code}`;
16
- }
17
- /**
18
- * The unique diagnostic codes for ECObjects rules.
19
- *
20
- * To provide meaning to code values, with anticipation
21
- * of future rules for all current EC Types, the following
22
- * value ranges should be used:
23
- *
24
- * - Schema: 000-099
25
- * - Class: 100-199
26
- * - Constant: 200-299
27
- * - CustomAttribute 300-399
28
- * - CustomAttributeClass: 400-499
29
- * - CustomAttributeContainer: 500-599
30
- * - EntityClass: 600-699
31
- * - Enumeration: 700-799
32
- * - Format: 800-899
33
- * - InvertedUnit: 900-999
34
- * - KindOfQuantity: 1000-1099
35
- * - Mixin: 1100-1199
36
- * - Phenomenon: 1200-1299
37
- * - Property: 1300-1399
38
- * - PropertyCategory: 1400-1499
39
- * - RelationshipClass: 1500-1599
40
- * - RelationshipConstraint: 1600-1699
41
- * - StructClass: 1700-1799
42
- * - Unit: 1800-1899
43
- * - UnitSystem: 1900-1999
44
- * @beta
45
- */
46
- /* eslint-disable @typescript-eslint/naming-convention */
47
- exports.DiagnosticCodes = {
48
- // Class Rule Codes (100-199)
49
- BaseClassIsSealed: getCode(100),
50
- BaseClassOfDifferentType: getCode(101),
51
- AbstractClassWithNonAbstractBase: getCode(102),
52
- // CA Container Rule Codes (500-599)
53
- CustomAttributeNotOfConcreteClass: getCode(500),
54
- CustomAttributeSchemaMustBeReferenced: getCode(501),
55
- CustomAttributeClassNotFound: getCode(502),
56
- // Enumeration Rule Codes (700-799)
57
- EnumerationTypeUnsupported: getCode(700),
58
- // Mixin Rule Codes (1100-1199)
59
- MixinAppliedToClassMustDeriveFromConstraint: getCode(1100),
60
- // Property Rule Codes (1300-1399)
61
- IncompatibleValueTypePropertyOverride: getCode(1300),
62
- IncompatibleTypePropertyOverride: getCode(1301),
63
- IncompatibleUnitPropertyOverride: getCode(1302),
64
- // Relationship Rule Codes (1500-1599)
65
- AbstractConstraintMustNarrowBaseConstraints: getCode(1500),
66
- DerivedConstraintsMustNarrowBaseConstraints: getCode(1501),
67
- ConstraintClassesDeriveFromAbstractContraint: getCode(1502),
68
- // Relationship Constraint Rule Codes (1600-1699)
69
- AtLeastOneConstraintClassDefined: getCode(1600),
70
- AbstractConstraintMustExistWithMultipleConstraints: getCode(1601),
71
- };
72
- /**
73
- * The list of [[IDiagnostic]] implementation classes used by the EC rule implementations.
74
- * @beta
75
- */
76
- exports.Diagnostics = {
77
- /** EC-001: Required message parameters: schema name, referenced schema name */
78
- SupplementalSchemasCannotBeReferenced: (0, Diagnostic_1.createSchemaDiagnosticClass)(getCode(1), "Referenced schema '{1}' of schema '{0}' is a supplemental schema. Supplemental schemas are not allowed to be referenced."),
79
- /** EC-002: Required message parameters: schema name, reference schema alias, first schema reference name, second schema reference name. */
80
- SchemaRefAliasMustBeUnique: (0, Diagnostic_1.createSchemaDiagnosticClass)(getCode(2), "Schema '{0}' has multiple schema references ({2}, {3}) with the same alias '{1}', which is not allowed."),
81
- /** EC-003: Required message parameters: schema name, cycle text */
82
- ReferenceCyclesNotAllowed: (0, Diagnostic_1.createSchemaDiagnosticClass)(getCode(3), "Schema '{0}' has reference cycles: {1}"),
83
- /** EC-100: Required message parameters: childClass.FullName, baseClass.FullName */
84
- BaseClassIsSealed: (0, Diagnostic_1.createClassDiagnosticClass)(exports.DiagnosticCodes.BaseClassIsSealed, "Class '{0}' cannot derive from sealed base class '{1}'."),
85
- /** EC-101: Required message parameters: childClass.FullName, baseClass.FullName, baseClass.schemaItemType */
86
- BaseClassIsOfDifferentType: (0, Diagnostic_1.createClassDiagnosticClass)(exports.DiagnosticCodes.BaseClassOfDifferentType, "Class '{0}' cannot derive from base class '{1}' of type '{2}'."),
87
- /** EC-102: Required message parameters: childClass.FullName, baseClass.FullName */
88
- AbstractClassWithNonAbstractBase: (0, Diagnostic_1.createClassDiagnosticClass)(exports.DiagnosticCodes.AbstractClassWithNonAbstractBase, "Abstract Class '{0}' cannot derive from base class '{1}' because it is not an abstract class."),
89
- /** EC-500: Required message parameters: CustomAttribute container name and CustomAttributeClass name. */
90
- CustomAttributeNotOfConcreteClass: (0, Diagnostic_1.createCustomAttributeContainerDiagnosticClass)(exports.DiagnosticCodes.CustomAttributeNotOfConcreteClass, "The CustomAttribute container '{0}' has a CustomAttribute with the class '{1}' which is not a concrete class."),
91
- /** EC-501: Required message parameters: CustomAttribute container name, CustomAttributeClass name, CustomAttributeClass Schema name. */
92
- CustomAttributeSchemaMustBeReferenced: (0, Diagnostic_1.createCustomAttributeContainerDiagnosticClass)(exports.DiagnosticCodes.CustomAttributeSchemaMustBeReferenced, "The CustomAttribute container '{0}' has a CustomAttribute with the class '{1}' whose schema is not referenced by the container's Schema."),
93
- /** EC-502: Required message parameters: CustomAttribute container name and CustomAttributeClass name. */
94
- CustomAttributeClassNotFound: (0, Diagnostic_1.createCustomAttributeContainerDiagnosticClass)(exports.DiagnosticCodes.CustomAttributeClassNotFound, "The CustomAttribute container '{0}' has a CustomAttribute with the class '{1}' which cannot be found."),
95
- /** EC-700: Required message parameters: Enumeration name */
96
- EnumerationTypeUnsupported: (0, Diagnostic_1.createSchemaItemDiagnosticClass)(exports.DiagnosticCodes.EnumerationTypeUnsupported, "Enumeration '{0}' has invalid primitive type."),
97
- /** EC-1100: Required message parameters: mixin class fullName, class fullName, applies to constraint class fullName */
98
- MixinAppliedToClassMustDeriveFromConstraint: (0, Diagnostic_1.createSchemaItemDiagnosticClass)(exports.DiagnosticCodes.MixinAppliedToClassMustDeriveFromConstraint, "Mixin '{0}' cannot be applied to the class '{1}' because it does not satisfy the applies to constraint '{2}'."),
99
- /** EC-1300: Required message parameters: childClass.FullName, property name, baseClass.FullName, base value type, child value type */
100
- IncompatibleValueTypePropertyOverride: (0, Diagnostic_1.createPropertyDiagnosticClass)(exports.DiagnosticCodes.IncompatibleValueTypePropertyOverride, "The ECProperty '{0}.{1}' has a base property '{2}.{1}' with a value type of {3} which is incompatible with the value type of {4}."),
101
- /** EC-1301: Required message parameters: childClass.FullName, property name, baseClass.FullName, base property type, child property type */
102
- IncompatibleTypePropertyOverride: (0, Diagnostic_1.createPropertyDiagnosticClass)(exports.DiagnosticCodes.IncompatibleTypePropertyOverride, "The ECProperty '{0}.{1}' has a base property '{2}.{1}' with a type of {3} which is incompatible with the type of {4}."),
103
- /** EC-1302: Required message parameters: childClass.Name, property name, baseClass.Name, baseClass Koq name, baseClass Koq persistence unit name, child class Koq persistence unit name, child class Koq name */
104
- IncompatibleUnitPropertyOverride: (0, Diagnostic_1.createPropertyDiagnosticClass)(exports.DiagnosticCodes.IncompatibleUnitPropertyOverride, "The ECProperty '{0}.{1}' has a base property '{2}.{1}' with KindOfQuantity '{3}' with persistence unit '{4}' which is not the same as the persistence unit '{5}' of the provided KindOfQuantity '{6}'."),
105
- /** EC-1303: Required message parameters: property.fullName, navigation relationship.fullName */
106
- NavigationRelationshipMustBeRoot: (0, Diagnostic_1.createPropertyDiagnosticClass)(getCode(1303), "The referenced relationship '{1}', used in NavigationProperty '{0}' is not the root relationship."),
107
- /** EC-1304: Required message parameters: property.fullName, navigation relationship.fullName */
108
- NavigationTargetMustHaveSingularMultiplicity: (0, Diagnostic_1.createPropertyDiagnosticClass)(getCode(1304), "NavigationProperty '{0}' uses the relationship '{1}' that cannot be traversed in the '{2}' direction due to a max multiplicity greater than 1."),
109
- /** EC-1305: Required message parameters: property.fullName, navigation relationship.fullName */
110
- NavigationRelationshipAbstractConstraintEntityOrMixin: (0, Diagnostic_1.createPropertyDiagnosticClass)(getCode(1305), "The NavigationProperty '{0}', using the relationship '{1}', points to a RelationshipClass, which is not allowed. NavigationProperties must point to an EntityClass or Mixin."),
111
- /** EC-1306: Required message parameters: class name, property name, navigation relationship.fullName */
112
- NavigationClassMustBeAConstraintClassOfRelationship: (0, Diagnostic_1.createPropertyDiagnosticClass)(getCode(1306), "The class '{0}' of NavigationProperty '{1}' is not supported by the {3} constraint of the referenced relationship '{2}'."),
113
- /** EC-1500: Required message parameters: abstract constraint class name, relationship end (source/target), relationship name, base relationship name */
114
- AbstractConstraintMustNarrowBaseConstraints: (0, Diagnostic_1.createSchemaItemDiagnosticClass)(exports.DiagnosticCodes.AbstractConstraintMustNarrowBaseConstraints, "The abstract constraint class '{0}' on the {1}-Constraint of '{2}' is not supported by the base class constraint in '{3}'."),
115
- /** EC-1501: Required message parameters: constraint class name, relationship end (source/target), relationship name, base relationship name */
116
- DerivedConstraintsMustNarrowBaseConstraints: (0, Diagnostic_1.createSchemaItemDiagnosticClass)(exports.DiagnosticCodes.DerivedConstraintsMustNarrowBaseConstraints, "The constraint class '{0}' on the {1}-Constraint of '{2}' is not supported by the base class constraint in '{3}'."),
117
- /** EC-1502: Required message parameters: constraint class name, relationship end (source/target), relationship name, abstract constraint class name */
118
- ConstraintClassesDeriveFromAbstractContraint: (0, Diagnostic_1.createSchemaItemDiagnosticClass)(exports.DiagnosticCodes.ConstraintClassesDeriveFromAbstractContraint, "The constraint class '{0}' on the {1}-Constraint of '{2}' is not derived from the abstract constraint class '{3}'."),
119
- /** EC-1600: Required message parameters: relationship end (source/target), relationship name */
120
- AtLeastOneConstraintClassDefined: (0, Diagnostic_1.createRelationshipConstraintDiagnosticClass)(exports.DiagnosticCodes.AtLeastOneConstraintClassDefined, "The {0}-Constraint of '{1}' does not contain any constraint classes."),
121
- /** EC-1601: Required message parameters: relationship end (source/target), relationship name */
122
- AbstractConstraintMustExistWithMultipleConstraints: (0, Diagnostic_1.createRelationshipConstraintDiagnosticClass)(exports.DiagnosticCodes.AbstractConstraintMustExistWithMultipleConstraints, "The {0}-Constraint of '{1}' has multiple constraint classes which requires an abstract constraint to be defined."),
123
- };
124
- /**
125
- * All schema validation rules that fall under the category of ECObjects.
126
- * @beta
127
- */
128
- exports.ECRuleSet = {
129
- name: ruleSetName,
130
- schemaRules: [
131
- validateSchemaReferences,
132
- ],
133
- classRules: [
134
- baseClassIsSealed,
135
- baseClassIsOfDifferentType,
136
- abstractClassWithNonAbstractBase,
137
- ],
138
- propertyRules: [
139
- incompatibleValueTypePropertyOverride,
140
- incompatibleTypePropertyOverride,
141
- incompatibleUnitPropertyOverride,
142
- validateNavigationProperty,
143
- ],
144
- relationshipRules: [
145
- abstractConstraintMustNarrowBaseConstraints,
146
- constraintClassesDeriveFromAbstractContraint,
147
- derivedConstraintsMustNarrowBaseConstraints,
148
- ],
149
- relationshipConstraintRules: [
150
- atLeastOneConstraintClassDefined,
151
- abstractConstraintMustExistWithMultipleConstraints,
152
- ],
153
- enumerationRules: [
154
- enumerationTypeUnsupported,
155
- ],
156
- entityClassRules: [
157
- mixinAppliedToClassMustDeriveFromConstraint,
158
- ],
159
- customAttributeInstanceRules: [
160
- validateCustomAttributeInstance,
161
- ],
162
- };
163
- /* eslint-enable @typescript-eslint/naming-convention */
164
- /**
165
- * Validates schema references against multiple EC rules.
166
- * @param schema The schema to validate.
167
- * @internal
168
- */
169
- async function* validateSchemaReferences(schema) {
170
- yield* validateSchemaReferencesSync(schema);
171
- }
172
- exports.validateSchemaReferences = validateSchemaReferences;
173
- /**
174
- * Validates schema references against multiple EC rules.
175
- * @param schema The schema to validate.
176
- * @internal
177
- */
178
- function* validateSchemaReferencesSync(schema) {
179
- const aliases = new Map();
180
- for (const schemaRef of schema.references) {
181
- if (schemaRef.customAttributes && schemaRef.customAttributes.has("CoreCustomAttributes.SupplementalSchema"))
182
- yield new exports.Diagnostics.SupplementalSchemasCannotBeReferenced(schema, [schema.name, schemaRef.name]);
183
- if (schema.schemaKey.matches(schemaRef.schemaKey))
184
- yield new exports.Diagnostics.ReferenceCyclesNotAllowed(schema, [schema.name, `${schema.name} --> ${schemaRef.name}`]);
185
- if (aliases.has(schemaRef.alias)) {
186
- const currentRef = aliases.get(schemaRef.alias);
187
- yield new exports.Diagnostics.SchemaRefAliasMustBeUnique(schema, [schema.name, schemaRef.alias, currentRef.name, schemaRef.name]);
188
- }
189
- else {
190
- aliases.set(schemaRef.alias, schemaRef);
191
- }
192
- }
193
- const graph = new ecschema_metadata_1.SchemaGraph(schema);
194
- const cycles = graph.detectCycles();
195
- if (cycles) {
196
- const result = cycles.map((cycle) => `${cycle.schema.name} --> ${cycle.refSchema.name}`).join(", ");
197
- yield new exports.Diagnostics.ReferenceCyclesNotAllowed(schema, [schema.name, result]);
198
- }
199
- }
200
- exports.validateSchemaReferencesSync = validateSchemaReferencesSync;
201
- /**
202
- * EC Rule: Sealed classes cannot be a base class.
203
- * @internal
204
- */
205
- async function* baseClassIsSealed(ecClass) {
206
- if (!ecClass.baseClass)
207
- return;
208
- const baseClass = await ecClass.baseClass;
209
- // return if rule passed
210
- if (baseClass.modifier !== ecschema_metadata_1.ECClassModifier.Sealed)
211
- return;
212
- yield new exports.Diagnostics.BaseClassIsSealed(ecClass, [ecClass.fullName, baseClass.fullName]);
213
- }
214
- exports.baseClassIsSealed = baseClassIsSealed;
215
- /**
216
- * EC Rule: Base and child class must be of the same type (i.e. Entity, Mixin, Relationship, etc.)
217
- * @internal
218
- */
219
- async function* baseClassIsOfDifferentType(ecClass) {
220
- if (!ecClass.baseClass)
221
- return;
222
- const baseClass = await ecClass.baseClass;
223
- // return if rule passed
224
- if (baseClass.schemaItemType === ecClass.schemaItemType)
225
- return;
226
- const itemType = (0, ecschema_metadata_1.schemaItemTypeToString)(baseClass.schemaItemType);
227
- yield new exports.Diagnostics.BaseClassIsOfDifferentType(ecClass, [ecClass.fullName, baseClass.fullName, itemType]);
228
- }
229
- exports.baseClassIsOfDifferentType = baseClassIsOfDifferentType;
230
- /**
231
- * EC Rule: Abstract class cannot derive from a non-abstract base class.
232
- * @internal
233
- */
234
- async function* abstractClassWithNonAbstractBase(ecClass) {
235
- if (ecClass.modifier !== ecschema_metadata_1.ECClassModifier.Abstract || !ecClass.baseClass)
236
- return;
237
- const baseClass = await ecClass.baseClass;
238
- // return if rule passed
239
- if (baseClass.modifier === ecschema_metadata_1.ECClassModifier.Abstract)
240
- return;
241
- yield new exports.Diagnostics.AbstractClassWithNonAbstractBase(ecClass, [ecClass.fullName, baseClass.fullName]);
242
- }
243
- exports.abstractClassWithNonAbstractBase = abstractClassWithNonAbstractBase;
244
- /**
245
- * EC Rule: When overriding a class primitive property, the child and base property must be of the same type (string, number, etc...).
246
- * @internal
247
- */
248
- async function* incompatibleValueTypePropertyOverride(property) {
249
- if (!property.class.baseClass)
250
- return;
251
- const primitiveType = getPrimitiveType(property);
252
- if (!primitiveType)
253
- return;
254
- async function callback(baseClass) {
255
- const baseProperty = await baseClass.getProperty(property.name);
256
- if (!baseProperty)
257
- return;
258
- // Other rules will catch this if false, but we need to make sure
259
- // types match for this rule to be valid.
260
- if (!propertyTypesMatch(property, baseProperty))
261
- return;
262
- const baseType = getPrimitiveType(baseProperty);
263
- // Return if rule passed
264
- if (!baseType || primitiveType === baseType)
265
- return;
266
- return new exports.Diagnostics.IncompatibleValueTypePropertyOverride(property, [property.class.fullName, property.name, baseClass.fullName, (0, ecschema_metadata_1.primitiveTypeToString)(baseType), (0, ecschema_metadata_1.primitiveTypeToString)(primitiveType)]);
267
- }
268
- for await (const baseClass of property.class.getAllBaseClasses()) {
269
- const result = await callback(baseClass);
270
- if (result)
271
- yield result;
272
- }
273
- }
274
- exports.incompatibleValueTypePropertyOverride = incompatibleValueTypePropertyOverride;
275
- /**
276
- * EC Rule: When overriding a class property, the child and base property must be of the same property type (primitive, struct, enumeration, etc...).
277
- * @internal
278
- */
279
- async function* incompatibleTypePropertyOverride(property) {
280
- if (!property.class.baseClass)
281
- return;
282
- async function callback(baseClass) {
283
- const baseProperty = await baseClass.getProperty(property.name);
284
- if (!baseProperty)
285
- return;
286
- // Return if rule passed
287
- if (propertyTypesMatch(property, baseProperty))
288
- return;
289
- return new exports.Diagnostics.IncompatibleTypePropertyOverride(property, [property.class.fullName, property.name, baseClass.fullName, baseProperty.constructor.name, property.constructor.name]);
290
- }
291
- for await (const baseClass of property.class.getAllBaseClasses()) {
292
- const result = await callback(baseClass);
293
- if (result)
294
- yield result;
295
- }
296
- }
297
- exports.incompatibleTypePropertyOverride = incompatibleTypePropertyOverride;
298
- /**
299
- * EC Rule: When overriding a kindOfQuantity property, the child and base property units must be the same.
300
- * @internal
301
- */
302
- async function* incompatibleUnitPropertyOverride(property) {
303
- if (!property.kindOfQuantity || !property.class.baseClass)
304
- return;
305
- async function callback(baseClass) {
306
- const baseProperty = await baseClass.getProperty(property.name);
307
- if (!baseProperty || !baseProperty.kindOfQuantity)
308
- return;
309
- // Other rules will catch this if false, but we need to make sure
310
- // types match for this rule to be valid.
311
- if (!propertyTypesMatch(property, baseProperty))
312
- return;
313
- const koq = await property.kindOfQuantity;
314
- const baseKoq = await baseProperty.kindOfQuantity;
315
- if (!koq || !baseKoq)
316
- return;
317
- const unit = await koq.persistenceUnit;
318
- const baseUnit = await baseKoq.persistenceUnit;
319
- if (!unit || !baseUnit)
320
- return;
321
- // return if rule passed
322
- if (unit.key.matches(baseUnit.key))
323
- return;
324
- return new exports.Diagnostics.IncompatibleUnitPropertyOverride(property, [
325
- property.class.fullName,
326
- property.name,
327
- baseClass.fullName,
328
- baseKoq.fullName,
329
- baseUnit.fullName,
330
- unit.fullName,
331
- koq.fullName,
332
- ]);
333
- }
334
- for await (const baseClass of property.class.getAllBaseClasses()) {
335
- const result = await callback(baseClass);
336
- if (result)
337
- yield result;
338
- }
339
- }
340
- exports.incompatibleUnitPropertyOverride = incompatibleUnitPropertyOverride;
341
- /**
342
- * Validates Navigation Properties. EC Rules: 1303, 1304
343
- * @internal
344
- */
345
- async function* validateNavigationProperty(property) {
346
- if (!property.isNavigation())
347
- return;
348
- const navProp = property;
349
- const relationship = await navProp.relationshipClass;
350
- if (relationship.baseClass)
351
- yield new exports.Diagnostics.NavigationRelationshipMustBeRoot(property, [property.fullName, relationship.fullName]);
352
- let thisConstraint;
353
- let thatConstraint;
354
- let navigationClassSide;
355
- if (navProp.direction === ecschema_metadata_1.StrengthDirection.Forward) {
356
- thisConstraint = relationship.source;
357
- thatConstraint = relationship.target;
358
- navigationClassSide = "source";
359
- }
360
- else {
361
- thisConstraint = relationship.target;
362
- thatConstraint = relationship.source;
363
- navigationClassSide = "target";
364
- }
365
- const thatAbstractConstraint = await thatConstraint.abstractConstraint;
366
- if (thatAbstractConstraint && thatAbstractConstraint.schemaItemType === ecschema_metadata_1.SchemaItemType.RelationshipClass) {
367
- yield new exports.Diagnostics.NavigationRelationshipAbstractConstraintEntityOrMixin(property, [property.fullName, relationship.fullName]);
368
- }
369
- const isClassSupported = async (ecClass, propertyName, constraintName) => {
370
- if (constraintName === ecClass.fullName && undefined !== await ecClass.getProperty(propertyName))
371
- return true;
372
- const inheritedProp = await ecClass.getInheritedProperty(propertyName);
373
- if (inheritedProp && constraintName === inheritedProp.class.fullName)
374
- return true;
375
- const baseClass = await ecClass.baseClass;
376
- if (!baseClass)
377
- return false;
378
- return isClassSupported(baseClass, propertyName, constraintName);
379
- };
380
- let classSupported = false;
381
- if (thisConstraint.constraintClasses) {
382
- for (const constraintClass of thisConstraint.constraintClasses) {
383
- classSupported = await isClassSupported(property.class, property.name, constraintClass.fullName);
384
- if (classSupported)
385
- break;
386
- }
387
- }
388
- if (!classSupported)
389
- yield new exports.Diagnostics.NavigationClassMustBeAConstraintClassOfRelationship(property, [property.class.name, property.name, relationship.fullName, navigationClassSide]);
390
- if (thatConstraint.multiplicity === ecschema_metadata_1.RelationshipMultiplicity.oneMany || thatConstraint.multiplicity === ecschema_metadata_1.RelationshipMultiplicity.zeroMany) {
391
- const direction = (0, ecschema_metadata_1.strengthDirectionToString)(navProp.direction);
392
- yield new exports.Diagnostics.NavigationTargetMustHaveSingularMultiplicity(property, [property.fullName, relationship.fullName, direction]);
393
- }
394
- return;
395
- }
396
- exports.validateNavigationProperty = validateNavigationProperty;
397
- /**
398
- * EC Rule: When overriding a RelationshipClass, the derived abstract constraint must narrow the base constraint classes.
399
- * @internal
400
- */
401
- async function* abstractConstraintMustNarrowBaseConstraints(ecClass) {
402
- if (!ecClass.baseClass)
403
- return;
404
- const baseRelationship = await ecClass.baseClass;
405
- const sourceResult = await applyAbstractConstraintMustNarrowBaseConstraints(ecClass, ecClass.source, baseRelationship);
406
- if (sourceResult)
407
- yield sourceResult;
408
- const targetResult = await applyAbstractConstraintMustNarrowBaseConstraints(ecClass, ecClass.target, baseRelationship);
409
- if (targetResult)
410
- yield targetResult;
411
- }
412
- exports.abstractConstraintMustNarrowBaseConstraints = abstractConstraintMustNarrowBaseConstraints;
413
- /**
414
- * EC Rule: When overriding a RelationshipClass, derived constraint classes must narrow base constraint classes.
415
- * @internal
416
- */
417
- async function* derivedConstraintsMustNarrowBaseConstraints(ecClass) {
418
- if (!ecClass.baseClass)
419
- return;
420
- const baseRelationship = await ecClass.baseClass;
421
- const sourceResult = await applyDerivedConstraintsMustNarrowBaseConstraints(ecClass, ecClass.source, baseRelationship);
422
- if (sourceResult)
423
- yield sourceResult;
424
- const targetResult = await applyDerivedConstraintsMustNarrowBaseConstraints(ecClass, ecClass.target, baseRelationship);
425
- if (targetResult)
426
- yield targetResult;
427
- }
428
- exports.derivedConstraintsMustNarrowBaseConstraints = derivedConstraintsMustNarrowBaseConstraints;
429
- /**
430
- * EC Rule: All constraint classes must have a common base class specified in the abstract constraint.
431
- * @internal
432
- */
433
- async function* constraintClassesDeriveFromAbstractContraint(ecClass) {
434
- const sourceResult = await applyConstraintClassesDeriveFromAbstractContraint(ecClass, ecClass.source);
435
- if (sourceResult)
436
- yield sourceResult;
437
- const targetResult = await applyConstraintClassesDeriveFromAbstractContraint(ecClass, ecClass.target);
438
- if (targetResult)
439
- yield targetResult;
440
- }
441
- exports.constraintClassesDeriveFromAbstractContraint = constraintClassesDeriveFromAbstractContraint;
442
- /**
443
- * EC Rule: At least on concrete constraint class must be defined in the list of constraint classes.
444
- * @internal
445
- */
446
- async function* atLeastOneConstraintClassDefined(constraint) {
447
- if (!constraint.constraintClasses || constraint.constraintClasses.length === 0) {
448
- const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
449
- yield new exports.Diagnostics.AtLeastOneConstraintClassDefined(constraint, [constraintType, constraint.relationshipClass.fullName]);
450
- }
451
- }
452
- exports.atLeastOneConstraintClassDefined = atLeastOneConstraintClassDefined;
453
- /**
454
- * EC Rule: If multiple constraints exist, an abstract constraint must be defined.
455
- * @internal
456
- */
457
- async function* abstractConstraintMustExistWithMultipleConstraints(constraint) {
458
- if (!constraint.constraintClasses || constraint.constraintClasses.length <= 1) {
459
- return;
460
- }
461
- const abstractConstraint = await getAbstractConstraint(constraint);
462
- if (abstractConstraint)
463
- return;
464
- const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
465
- yield new exports.Diagnostics.AbstractConstraintMustExistWithMultipleConstraints(constraint, [constraintType, constraint.relationshipClass.fullName]);
466
- }
467
- exports.abstractConstraintMustExistWithMultipleConstraints = abstractConstraintMustExistWithMultipleConstraints;
468
- function propertyTypesMatch(propertyA, propertyB) {
469
- return propertyA.constructor.name === propertyB.constructor.name;
470
- }
471
- function getPrimitiveType(property) {
472
- if (property.isPrimitive())
473
- return property.primitiveType;
474
- return undefined;
475
- }
476
- /**
477
- * EC Rule: Enumeration type must be a string or integer
478
- * @internal
479
- */
480
- async function* enumerationTypeUnsupported(enumeration) {
481
- const type = enumeration.type;
482
- if (type === ecschema_metadata_1.PrimitiveType.Integer || type === ecschema_metadata_1.PrimitiveType.String)
483
- return;
484
- yield new exports.Diagnostics.EnumerationTypeUnsupported(enumeration, [enumeration.fullName]);
485
- }
486
- exports.enumerationTypeUnsupported = enumerationTypeUnsupported;
487
- /**
488
- * EC Rule: Mixin applied to class must derived from the Mixin appliesTo constraint.
489
- * @internal
490
- */
491
- async function* mixinAppliedToClassMustDeriveFromConstraint(entityClass) {
492
- for (const lazyMixin of entityClass.mixins) {
493
- const mixin = await lazyMixin;
494
- if (!mixin.appliesTo)
495
- continue;
496
- if (!await entityClass.is(await mixin.appliesTo))
497
- yield new exports.Diagnostics.MixinAppliedToClassMustDeriveFromConstraint(entityClass, [mixin.fullName, entityClass.fullName, mixin.appliesTo.fullName]);
498
- }
499
- return;
500
- }
501
- exports.mixinAppliedToClassMustDeriveFromConstraint = mixinAppliedToClassMustDeriveFromConstraint;
502
- /**
503
- * Validates a custom attribute instance and yields EC-500, EC-501, and EC-502 rule violations.
504
- * @internal
505
- */
506
- async function* validateCustomAttributeInstance(container, customAttribute) {
507
- yield* customAttributeNotOfConcreteClass(container, customAttribute);
508
- yield* customAttributeSchemaMustBeReferenced(container, customAttribute);
509
- yield* customAttributeClassMustExist(container, customAttribute);
510
- }
511
- exports.validateCustomAttributeInstance = validateCustomAttributeInstance;
512
- /** EC Rule: CustomAttribute instance must be of a concrete CustomAttributeClass. */
513
- async function* customAttributeNotOfConcreteClass(container, customAttribute) {
514
- const schema = container.schema;
515
- const caClass = await schema.lookupItem(customAttribute.className);
516
- if (!caClass)
517
- return;
518
- if (caClass.modifier !== ecschema_metadata_1.ECClassModifier.Abstract)
519
- return;
520
- yield new exports.Diagnostics.CustomAttributeNotOfConcreteClass(container, [container.fullName, caClass.fullName]);
521
- }
522
- /** EC Rule: CustomAttribute Schema must be referenced by the container's Schema. */
523
- async function* customAttributeSchemaMustBeReferenced(container, customAttribute) {
524
- const schema = container.schema;
525
- const nameParts = customAttribute.className.split(".");
526
- if (nameParts.length === 1 || nameParts[0] === schema.name)
527
- return;
528
- if (schema.references.some((s) => s.name === nameParts[0]))
529
- return;
530
- yield new exports.Diagnostics.CustomAttributeSchemaMustBeReferenced(container, [container.fullName, customAttribute.className]);
531
- }
532
- /** EC Rule: CustomAttribute instance class must exist. */
533
- async function* customAttributeClassMustExist(container, customAttribute) {
534
- const schema = container.schema;
535
- const caClass = await schema.lookupItem(customAttribute.className);
536
- if (!caClass)
537
- yield new exports.Diagnostics.CustomAttributeClassNotFound(container, [container.fullName, customAttribute.className]);
538
- }
539
- async function applyAbstractConstraintMustNarrowBaseConstraints(ecClass, constraint, baseRelationship) {
540
- const baseConstraint = constraint.isSource ? baseRelationship.source : baseRelationship.target;
541
- const abstractConstraint = await constraint.abstractConstraint;
542
- if (!abstractConstraint)
543
- return;
544
- if (await baseConstraint.supportsClass(abstractConstraint))
545
- return;
546
- const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
547
- return new exports.Diagnostics.AbstractConstraintMustNarrowBaseConstraints(ecClass, [abstractConstraint.fullName, constraintType, constraint.relationshipClass.fullName, baseRelationship.fullName]);
548
- }
549
- async function applyDerivedConstraintsMustNarrowBaseConstraints(ecClass, constraint, baseRelationship) {
550
- const baseConstraint = constraint.isSource ? baseRelationship.source : baseRelationship.target;
551
- if (!constraint.constraintClasses)
552
- return;
553
- for (const classPromise of constraint.constraintClasses) {
554
- const constraintClass = await classPromise;
555
- if (await baseConstraint.supportsClass(constraintClass))
556
- continue;
557
- const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
558
- return new exports.Diagnostics.DerivedConstraintsMustNarrowBaseConstraints(ecClass, [constraintClass.fullName, constraintType, constraint.relationshipClass.fullName, baseRelationship.fullName]);
559
- }
560
- return;
561
- }
562
- async function applyConstraintClassesDeriveFromAbstractContraint(ecClass, constraint) {
563
- const abstractConstraint = await getAbstractConstraint(constraint);
564
- if (!abstractConstraint)
565
- return;
566
- if (!constraint.constraintClasses)
567
- return;
568
- for (const classPromise of constraint.constraintClasses) {
569
- const constraintClass = await classPromise;
570
- if (constraintClass.schemaItemType === ecschema_metadata_1.SchemaItemType.Mixin && abstractConstraint.schemaItemType === ecschema_metadata_1.SchemaItemType.EntityClass) {
571
- if (!await (constraintClass).applicableTo(abstractConstraint)) {
572
- const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
573
- return new exports.Diagnostics.ConstraintClassesDeriveFromAbstractContraint(ecClass, [constraintClass.fullName, constraintType, constraint.relationshipClass.fullName, abstractConstraint.fullName]);
574
- }
575
- continue;
576
- }
577
- if (!await constraintClass.is(abstractConstraint)) {
578
- const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
579
- return new exports.Diagnostics.ConstraintClassesDeriveFromAbstractContraint(ecClass, [constraintClass.fullName, constraintType, constraint.relationshipClass.fullName, abstractConstraint.fullName]);
580
- }
581
- }
582
- return;
583
- }
584
- async function getAbstractConstraint(constraint) {
585
- const abstractConstraint = await constraint.abstractConstraint;
586
- if (abstractConstraint)
587
- return abstractConstraint;
588
- const baseRelationship = await constraint.relationshipClass.baseClass;
589
- if (!baseRelationship)
590
- return;
591
- const baseConstraint = constraint.isSource ? baseRelationship.source : baseRelationship.target;
592
- return getAbstractConstraint(baseConstraint);
593
- }
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 Validation
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.validateCustomAttributeInstance = exports.mixinAppliedToClassMustDeriveFromConstraint = exports.enumerationTypeUnsupported = exports.abstractConstraintMustExistWithMultipleConstraints = exports.atLeastOneConstraintClassDefined = exports.constraintClassesDeriveFromAbstractContraint = exports.derivedConstraintsMustNarrowBaseConstraints = exports.abstractConstraintMustNarrowBaseConstraints = exports.validateNavigationProperty = exports.incompatibleUnitPropertyOverride = exports.incompatibleTypePropertyOverride = exports.incompatibleValueTypePropertyOverride = exports.abstractClassWithNonAbstractBase = exports.baseClassIsOfDifferentType = exports.baseClassIsSealed = exports.validateSchemaReferencesSync = exports.validateSchemaReferences = exports.ECRuleSet = exports.Diagnostics = exports.DiagnosticCodes = void 0;
11
+ const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
12
+ const Diagnostic_1 = require("./Diagnostic");
13
+ const ruleSetName = "ECObjects";
14
+ function getCode(code) {
15
+ return `${ruleSetName}-${code}`;
16
+ }
17
+ /**
18
+ * The unique diagnostic codes for ECObjects rules.
19
+ *
20
+ * To provide meaning to code values, with anticipation
21
+ * of future rules for all current EC Types, the following
22
+ * value ranges should be used:
23
+ *
24
+ * - Schema: 000-099
25
+ * - Class: 100-199
26
+ * - Constant: 200-299
27
+ * - CustomAttribute 300-399
28
+ * - CustomAttributeClass: 400-499
29
+ * - CustomAttributeContainer: 500-599
30
+ * - EntityClass: 600-699
31
+ * - Enumeration: 700-799
32
+ * - Format: 800-899
33
+ * - InvertedUnit: 900-999
34
+ * - KindOfQuantity: 1000-1099
35
+ * - Mixin: 1100-1199
36
+ * - Phenomenon: 1200-1299
37
+ * - Property: 1300-1399
38
+ * - PropertyCategory: 1400-1499
39
+ * - RelationshipClass: 1500-1599
40
+ * - RelationshipConstraint: 1600-1699
41
+ * - StructClass: 1700-1799
42
+ * - Unit: 1800-1899
43
+ * - UnitSystem: 1900-1999
44
+ * @beta
45
+ */
46
+ /* eslint-disable @typescript-eslint/naming-convention */
47
+ exports.DiagnosticCodes = {
48
+ // Class Rule Codes (100-199)
49
+ BaseClassIsSealed: getCode(100),
50
+ BaseClassOfDifferentType: getCode(101),
51
+ AbstractClassWithNonAbstractBase: getCode(102),
52
+ // CA Container Rule Codes (500-599)
53
+ CustomAttributeNotOfConcreteClass: getCode(500),
54
+ CustomAttributeSchemaMustBeReferenced: getCode(501),
55
+ CustomAttributeClassNotFound: getCode(502),
56
+ // Enumeration Rule Codes (700-799)
57
+ EnumerationTypeUnsupported: getCode(700),
58
+ // Mixin Rule Codes (1100-1199)
59
+ MixinAppliedToClassMustDeriveFromConstraint: getCode(1100),
60
+ // Property Rule Codes (1300-1399)
61
+ IncompatibleValueTypePropertyOverride: getCode(1300),
62
+ IncompatibleTypePropertyOverride: getCode(1301),
63
+ IncompatibleUnitPropertyOverride: getCode(1302),
64
+ // Relationship Rule Codes (1500-1599)
65
+ AbstractConstraintMustNarrowBaseConstraints: getCode(1500),
66
+ DerivedConstraintsMustNarrowBaseConstraints: getCode(1501),
67
+ ConstraintClassesDeriveFromAbstractContraint: getCode(1502),
68
+ // Relationship Constraint Rule Codes (1600-1699)
69
+ AtLeastOneConstraintClassDefined: getCode(1600),
70
+ AbstractConstraintMustExistWithMultipleConstraints: getCode(1601),
71
+ };
72
+ /**
73
+ * The list of [[IDiagnostic]] implementation classes used by the EC rule implementations.
74
+ * @beta
75
+ */
76
+ exports.Diagnostics = {
77
+ /** EC-001: Required message parameters: schema name, referenced schema name */
78
+ SupplementalSchemasCannotBeReferenced: (0, Diagnostic_1.createSchemaDiagnosticClass)(getCode(1), "Referenced schema '{1}' of schema '{0}' is a supplemental schema. Supplemental schemas are not allowed to be referenced."),
79
+ /** EC-002: Required message parameters: schema name, reference schema alias, first schema reference name, second schema reference name. */
80
+ SchemaRefAliasMustBeUnique: (0, Diagnostic_1.createSchemaDiagnosticClass)(getCode(2), "Schema '{0}' has multiple schema references ({2}, {3}) with the same alias '{1}', which is not allowed."),
81
+ /** EC-003: Required message parameters: schema name, cycle text */
82
+ ReferenceCyclesNotAllowed: (0, Diagnostic_1.createSchemaDiagnosticClass)(getCode(3), "Schema '{0}' has reference cycles: {1}"),
83
+ /** EC-100: Required message parameters: childClass.FullName, baseClass.FullName */
84
+ BaseClassIsSealed: (0, Diagnostic_1.createClassDiagnosticClass)(exports.DiagnosticCodes.BaseClassIsSealed, "Class '{0}' cannot derive from sealed base class '{1}'."),
85
+ /** EC-101: Required message parameters: childClass.FullName, baseClass.FullName, baseClass.schemaItemType */
86
+ BaseClassIsOfDifferentType: (0, Diagnostic_1.createClassDiagnosticClass)(exports.DiagnosticCodes.BaseClassOfDifferentType, "Class '{0}' cannot derive from base class '{1}' of type '{2}'."),
87
+ /** EC-102: Required message parameters: childClass.FullName, baseClass.FullName */
88
+ AbstractClassWithNonAbstractBase: (0, Diagnostic_1.createClassDiagnosticClass)(exports.DiagnosticCodes.AbstractClassWithNonAbstractBase, "Abstract Class '{0}' cannot derive from base class '{1}' because it is not an abstract class."),
89
+ /** EC-500: Required message parameters: CustomAttribute container name and CustomAttributeClass name. */
90
+ CustomAttributeNotOfConcreteClass: (0, Diagnostic_1.createCustomAttributeContainerDiagnosticClass)(exports.DiagnosticCodes.CustomAttributeNotOfConcreteClass, "The CustomAttribute container '{0}' has a CustomAttribute with the class '{1}' which is not a concrete class."),
91
+ /** EC-501: Required message parameters: CustomAttribute container name, CustomAttributeClass name, CustomAttributeClass Schema name. */
92
+ CustomAttributeSchemaMustBeReferenced: (0, Diagnostic_1.createCustomAttributeContainerDiagnosticClass)(exports.DiagnosticCodes.CustomAttributeSchemaMustBeReferenced, "The CustomAttribute container '{0}' has a CustomAttribute with the class '{1}' whose schema is not referenced by the container's Schema."),
93
+ /** EC-502: Required message parameters: CustomAttribute container name and CustomAttributeClass name. */
94
+ CustomAttributeClassNotFound: (0, Diagnostic_1.createCustomAttributeContainerDiagnosticClass)(exports.DiagnosticCodes.CustomAttributeClassNotFound, "The CustomAttribute container '{0}' has a CustomAttribute with the class '{1}' which cannot be found."),
95
+ /** EC-700: Required message parameters: Enumeration name */
96
+ EnumerationTypeUnsupported: (0, Diagnostic_1.createSchemaItemDiagnosticClass)(exports.DiagnosticCodes.EnumerationTypeUnsupported, "Enumeration '{0}' has invalid primitive type."),
97
+ /** EC-1100: Required message parameters: mixin class fullName, class fullName, applies to constraint class fullName */
98
+ MixinAppliedToClassMustDeriveFromConstraint: (0, Diagnostic_1.createSchemaItemDiagnosticClass)(exports.DiagnosticCodes.MixinAppliedToClassMustDeriveFromConstraint, "Mixin '{0}' cannot be applied to the class '{1}' because it does not satisfy the applies to constraint '{2}'."),
99
+ /** EC-1300: Required message parameters: childClass.FullName, property name, baseClass.FullName, base value type, child value type */
100
+ IncompatibleValueTypePropertyOverride: (0, Diagnostic_1.createPropertyDiagnosticClass)(exports.DiagnosticCodes.IncompatibleValueTypePropertyOverride, "The ECProperty '{0}.{1}' has a base property '{2}.{1}' with a value type of {3} which is incompatible with the value type of {4}."),
101
+ /** EC-1301: Required message parameters: childClass.FullName, property name, baseClass.FullName, base property type, child property type */
102
+ IncompatibleTypePropertyOverride: (0, Diagnostic_1.createPropertyDiagnosticClass)(exports.DiagnosticCodes.IncompatibleTypePropertyOverride, "The ECProperty '{0}.{1}' has a base property '{2}.{1}' with a type of {3} which is incompatible with the type of {4}."),
103
+ /** EC-1302: Required message parameters: childClass.Name, property name, baseClass.Name, baseClass Koq name, baseClass Koq persistence unit name, child class Koq persistence unit name, child class Koq name */
104
+ IncompatibleUnitPropertyOverride: (0, Diagnostic_1.createPropertyDiagnosticClass)(exports.DiagnosticCodes.IncompatibleUnitPropertyOverride, "The ECProperty '{0}.{1}' has a base property '{2}.{1}' with KindOfQuantity '{3}' with persistence unit '{4}' which is not the same as the persistence unit '{5}' of the provided KindOfQuantity '{6}'."),
105
+ /** EC-1303: Required message parameters: property.fullName, navigation relationship.fullName */
106
+ NavigationRelationshipMustBeRoot: (0, Diagnostic_1.createPropertyDiagnosticClass)(getCode(1303), "The referenced relationship '{1}', used in NavigationProperty '{0}' is not the root relationship."),
107
+ /** EC-1304: Required message parameters: property.fullName, navigation relationship.fullName */
108
+ NavigationTargetMustHaveSingularMultiplicity: (0, Diagnostic_1.createPropertyDiagnosticClass)(getCode(1304), "NavigationProperty '{0}' uses the relationship '{1}' that cannot be traversed in the '{2}' direction due to a max multiplicity greater than 1."),
109
+ /** EC-1305: Required message parameters: property.fullName, navigation relationship.fullName */
110
+ NavigationRelationshipAbstractConstraintEntityOrMixin: (0, Diagnostic_1.createPropertyDiagnosticClass)(getCode(1305), "The NavigationProperty '{0}', using the relationship '{1}', points to a RelationshipClass, which is not allowed. NavigationProperties must point to an EntityClass or Mixin."),
111
+ /** EC-1306: Required message parameters: class name, property name, navigation relationship.fullName */
112
+ NavigationClassMustBeAConstraintClassOfRelationship: (0, Diagnostic_1.createPropertyDiagnosticClass)(getCode(1306), "The class '{0}' of NavigationProperty '{1}' is not supported by the {3} constraint of the referenced relationship '{2}'."),
113
+ /** EC-1500: Required message parameters: abstract constraint class name, relationship end (source/target), relationship name, base relationship name */
114
+ AbstractConstraintMustNarrowBaseConstraints: (0, Diagnostic_1.createSchemaItemDiagnosticClass)(exports.DiagnosticCodes.AbstractConstraintMustNarrowBaseConstraints, "The abstract constraint class '{0}' on the {1}-Constraint of '{2}' is not supported by the base class constraint in '{3}'."),
115
+ /** EC-1501: Required message parameters: constraint class name, relationship end (source/target), relationship name, base relationship name */
116
+ DerivedConstraintsMustNarrowBaseConstraints: (0, Diagnostic_1.createSchemaItemDiagnosticClass)(exports.DiagnosticCodes.DerivedConstraintsMustNarrowBaseConstraints, "The constraint class '{0}' on the {1}-Constraint of '{2}' is not supported by the base class constraint in '{3}'."),
117
+ /** EC-1502: Required message parameters: constraint class name, relationship end (source/target), relationship name, abstract constraint class name */
118
+ ConstraintClassesDeriveFromAbstractContraint: (0, Diagnostic_1.createSchemaItemDiagnosticClass)(exports.DiagnosticCodes.ConstraintClassesDeriveFromAbstractContraint, "The constraint class '{0}' on the {1}-Constraint of '{2}' is not derived from the abstract constraint class '{3}'."),
119
+ /** EC-1600: Required message parameters: relationship end (source/target), relationship name */
120
+ AtLeastOneConstraintClassDefined: (0, Diagnostic_1.createRelationshipConstraintDiagnosticClass)(exports.DiagnosticCodes.AtLeastOneConstraintClassDefined, "The {0}-Constraint of '{1}' does not contain any constraint classes."),
121
+ /** EC-1601: Required message parameters: relationship end (source/target), relationship name */
122
+ AbstractConstraintMustExistWithMultipleConstraints: (0, Diagnostic_1.createRelationshipConstraintDiagnosticClass)(exports.DiagnosticCodes.AbstractConstraintMustExistWithMultipleConstraints, "The {0}-Constraint of '{1}' has multiple constraint classes which requires an abstract constraint to be defined."),
123
+ };
124
+ /**
125
+ * All schema validation rules that fall under the category of ECObjects.
126
+ * @beta
127
+ */
128
+ exports.ECRuleSet = {
129
+ name: ruleSetName,
130
+ schemaRules: [
131
+ validateSchemaReferences,
132
+ ],
133
+ classRules: [
134
+ baseClassIsSealed,
135
+ baseClassIsOfDifferentType,
136
+ abstractClassWithNonAbstractBase,
137
+ ],
138
+ propertyRules: [
139
+ incompatibleValueTypePropertyOverride,
140
+ incompatibleTypePropertyOverride,
141
+ incompatibleUnitPropertyOverride,
142
+ validateNavigationProperty,
143
+ ],
144
+ relationshipRules: [
145
+ abstractConstraintMustNarrowBaseConstraints,
146
+ constraintClassesDeriveFromAbstractContraint,
147
+ derivedConstraintsMustNarrowBaseConstraints,
148
+ ],
149
+ relationshipConstraintRules: [
150
+ atLeastOneConstraintClassDefined,
151
+ abstractConstraintMustExistWithMultipleConstraints,
152
+ ],
153
+ enumerationRules: [
154
+ enumerationTypeUnsupported,
155
+ ],
156
+ entityClassRules: [
157
+ mixinAppliedToClassMustDeriveFromConstraint,
158
+ ],
159
+ customAttributeInstanceRules: [
160
+ validateCustomAttributeInstance,
161
+ ],
162
+ };
163
+ /* eslint-enable @typescript-eslint/naming-convention */
164
+ /**
165
+ * Validates schema references against multiple EC rules.
166
+ * @param schema The schema to validate.
167
+ * @internal
168
+ */
169
+ async function* validateSchemaReferences(schema) {
170
+ yield* validateSchemaReferencesSync(schema);
171
+ }
172
+ exports.validateSchemaReferences = validateSchemaReferences;
173
+ /**
174
+ * Validates schema references against multiple EC rules.
175
+ * @param schema The schema to validate.
176
+ * @internal
177
+ */
178
+ function* validateSchemaReferencesSync(schema) {
179
+ const aliases = new Map();
180
+ for (const schemaRef of schema.references) {
181
+ if (schemaRef.customAttributes && schemaRef.customAttributes.has("CoreCustomAttributes.SupplementalSchema"))
182
+ yield new exports.Diagnostics.SupplementalSchemasCannotBeReferenced(schema, [schema.name, schemaRef.name]);
183
+ if (schema.schemaKey.matches(schemaRef.schemaKey))
184
+ yield new exports.Diagnostics.ReferenceCyclesNotAllowed(schema, [schema.name, `${schema.name} --> ${schemaRef.name}`]);
185
+ if (aliases.has(schemaRef.alias)) {
186
+ const currentRef = aliases.get(schemaRef.alias);
187
+ yield new exports.Diagnostics.SchemaRefAliasMustBeUnique(schema, [schema.name, schemaRef.alias, currentRef.name, schemaRef.name]);
188
+ }
189
+ else {
190
+ aliases.set(schemaRef.alias, schemaRef);
191
+ }
192
+ }
193
+ const graph = new ecschema_metadata_1.SchemaGraph(schema);
194
+ const cycles = graph.detectCycles();
195
+ if (cycles) {
196
+ const result = cycles.map((cycle) => `${cycle.schema.name} --> ${cycle.refSchema.name}`).join(", ");
197
+ yield new exports.Diagnostics.ReferenceCyclesNotAllowed(schema, [schema.name, result]);
198
+ }
199
+ }
200
+ exports.validateSchemaReferencesSync = validateSchemaReferencesSync;
201
+ /**
202
+ * EC Rule: Sealed classes cannot be a base class.
203
+ * @internal
204
+ */
205
+ async function* baseClassIsSealed(ecClass) {
206
+ if (!ecClass.baseClass)
207
+ return;
208
+ const baseClass = await ecClass.baseClass;
209
+ // return if rule passed
210
+ if (baseClass.modifier !== ecschema_metadata_1.ECClassModifier.Sealed)
211
+ return;
212
+ yield new exports.Diagnostics.BaseClassIsSealed(ecClass, [ecClass.fullName, baseClass.fullName]);
213
+ }
214
+ exports.baseClassIsSealed = baseClassIsSealed;
215
+ /**
216
+ * EC Rule: Base and child class must be of the same type (i.e. Entity, Mixin, Relationship, etc.)
217
+ * @internal
218
+ */
219
+ async function* baseClassIsOfDifferentType(ecClass) {
220
+ if (!ecClass.baseClass)
221
+ return;
222
+ const baseClass = await ecClass.baseClass;
223
+ // return if rule passed
224
+ if (baseClass.schemaItemType === ecClass.schemaItemType)
225
+ return;
226
+ const itemType = (0, ecschema_metadata_1.schemaItemTypeToString)(baseClass.schemaItemType);
227
+ yield new exports.Diagnostics.BaseClassIsOfDifferentType(ecClass, [ecClass.fullName, baseClass.fullName, itemType]);
228
+ }
229
+ exports.baseClassIsOfDifferentType = baseClassIsOfDifferentType;
230
+ /**
231
+ * EC Rule: Abstract class cannot derive from a non-abstract base class.
232
+ * @internal
233
+ */
234
+ async function* abstractClassWithNonAbstractBase(ecClass) {
235
+ if (ecClass.modifier !== ecschema_metadata_1.ECClassModifier.Abstract || !ecClass.baseClass)
236
+ return;
237
+ const baseClass = await ecClass.baseClass;
238
+ // return if rule passed
239
+ if (baseClass.modifier === ecschema_metadata_1.ECClassModifier.Abstract)
240
+ return;
241
+ yield new exports.Diagnostics.AbstractClassWithNonAbstractBase(ecClass, [ecClass.fullName, baseClass.fullName]);
242
+ }
243
+ exports.abstractClassWithNonAbstractBase = abstractClassWithNonAbstractBase;
244
+ /**
245
+ * EC Rule: When overriding a class primitive property, the child and base property must be of the same type (string, number, etc...).
246
+ * @internal
247
+ */
248
+ async function* incompatibleValueTypePropertyOverride(property) {
249
+ if (!property.class.baseClass)
250
+ return;
251
+ const primitiveType = getPrimitiveType(property);
252
+ if (!primitiveType)
253
+ return;
254
+ async function callback(baseClass) {
255
+ const baseProperty = await baseClass.getProperty(property.name);
256
+ if (!baseProperty)
257
+ return;
258
+ // Other rules will catch this if false, but we need to make sure
259
+ // types match for this rule to be valid.
260
+ if (!propertyTypesMatch(property, baseProperty))
261
+ return;
262
+ const baseType = getPrimitiveType(baseProperty);
263
+ // Return if rule passed
264
+ if (!baseType || primitiveType === baseType)
265
+ return;
266
+ return new exports.Diagnostics.IncompatibleValueTypePropertyOverride(property, [property.class.fullName, property.name, baseClass.fullName, (0, ecschema_metadata_1.primitiveTypeToString)(baseType), (0, ecschema_metadata_1.primitiveTypeToString)(primitiveType)]);
267
+ }
268
+ for await (const baseClass of property.class.getAllBaseClasses()) {
269
+ const result = await callback(baseClass);
270
+ if (result)
271
+ yield result;
272
+ }
273
+ }
274
+ exports.incompatibleValueTypePropertyOverride = incompatibleValueTypePropertyOverride;
275
+ /**
276
+ * EC Rule: When overriding a class property, the child and base property must be of the same property type (primitive, struct, enumeration, etc...).
277
+ * @internal
278
+ */
279
+ async function* incompatibleTypePropertyOverride(property) {
280
+ if (!property.class.baseClass)
281
+ return;
282
+ async function callback(baseClass) {
283
+ const baseProperty = await baseClass.getProperty(property.name);
284
+ if (!baseProperty)
285
+ return;
286
+ // Return if rule passed
287
+ if (propertyTypesMatch(property, baseProperty))
288
+ return;
289
+ return new exports.Diagnostics.IncompatibleTypePropertyOverride(property, [property.class.fullName, property.name, baseClass.fullName, baseProperty.constructor.name, property.constructor.name]);
290
+ }
291
+ for await (const baseClass of property.class.getAllBaseClasses()) {
292
+ const result = await callback(baseClass);
293
+ if (result)
294
+ yield result;
295
+ }
296
+ }
297
+ exports.incompatibleTypePropertyOverride = incompatibleTypePropertyOverride;
298
+ /**
299
+ * EC Rule: When overriding a kindOfQuantity property, the child and base property units must be the same.
300
+ * @internal
301
+ */
302
+ async function* incompatibleUnitPropertyOverride(property) {
303
+ if (!property.kindOfQuantity || !property.class.baseClass)
304
+ return;
305
+ async function callback(baseClass) {
306
+ const baseProperty = await baseClass.getProperty(property.name);
307
+ if (!baseProperty || !baseProperty.kindOfQuantity)
308
+ return;
309
+ // Other rules will catch this if false, but we need to make sure
310
+ // types match for this rule to be valid.
311
+ if (!propertyTypesMatch(property, baseProperty))
312
+ return;
313
+ const koq = await property.kindOfQuantity;
314
+ const baseKoq = await baseProperty.kindOfQuantity;
315
+ if (!koq || !baseKoq)
316
+ return;
317
+ const unit = await koq.persistenceUnit;
318
+ const baseUnit = await baseKoq.persistenceUnit;
319
+ if (!unit || !baseUnit)
320
+ return;
321
+ // return if rule passed
322
+ if (unit.key.matches(baseUnit.key))
323
+ return;
324
+ return new exports.Diagnostics.IncompatibleUnitPropertyOverride(property, [
325
+ property.class.fullName,
326
+ property.name,
327
+ baseClass.fullName,
328
+ baseKoq.fullName,
329
+ baseUnit.fullName,
330
+ unit.fullName,
331
+ koq.fullName,
332
+ ]);
333
+ }
334
+ for await (const baseClass of property.class.getAllBaseClasses()) {
335
+ const result = await callback(baseClass);
336
+ if (result)
337
+ yield result;
338
+ }
339
+ }
340
+ exports.incompatibleUnitPropertyOverride = incompatibleUnitPropertyOverride;
341
+ /**
342
+ * Validates Navigation Properties. EC Rules: 1303, 1304
343
+ * @internal
344
+ */
345
+ async function* validateNavigationProperty(property) {
346
+ if (!property.isNavigation())
347
+ return;
348
+ const navProp = property;
349
+ const relationship = await navProp.relationshipClass;
350
+ if (relationship.baseClass)
351
+ yield new exports.Diagnostics.NavigationRelationshipMustBeRoot(property, [property.fullName, relationship.fullName]);
352
+ let thisConstraint;
353
+ let thatConstraint;
354
+ let navigationClassSide;
355
+ if (navProp.direction === ecschema_metadata_1.StrengthDirection.Forward) {
356
+ thisConstraint = relationship.source;
357
+ thatConstraint = relationship.target;
358
+ navigationClassSide = "source";
359
+ }
360
+ else {
361
+ thisConstraint = relationship.target;
362
+ thatConstraint = relationship.source;
363
+ navigationClassSide = "target";
364
+ }
365
+ const thatAbstractConstraint = await thatConstraint.abstractConstraint;
366
+ if (thatAbstractConstraint && thatAbstractConstraint.schemaItemType === ecschema_metadata_1.SchemaItemType.RelationshipClass) {
367
+ yield new exports.Diagnostics.NavigationRelationshipAbstractConstraintEntityOrMixin(property, [property.fullName, relationship.fullName]);
368
+ }
369
+ const isClassSupported = async (ecClass, propertyName, constraintName) => {
370
+ if (constraintName === ecClass.fullName && undefined !== await ecClass.getProperty(propertyName))
371
+ return true;
372
+ const inheritedProp = await ecClass.getInheritedProperty(propertyName);
373
+ if (inheritedProp && constraintName === inheritedProp.class.fullName)
374
+ return true;
375
+ const baseClass = await ecClass.baseClass;
376
+ if (!baseClass)
377
+ return false;
378
+ return isClassSupported(baseClass, propertyName, constraintName);
379
+ };
380
+ let classSupported = false;
381
+ if (thisConstraint.constraintClasses) {
382
+ for (const constraintClass of thisConstraint.constraintClasses) {
383
+ classSupported = await isClassSupported(property.class, property.name, constraintClass.fullName);
384
+ if (classSupported)
385
+ break;
386
+ }
387
+ }
388
+ if (!classSupported)
389
+ yield new exports.Diagnostics.NavigationClassMustBeAConstraintClassOfRelationship(property, [property.class.name, property.name, relationship.fullName, navigationClassSide]);
390
+ if (thatConstraint.multiplicity === ecschema_metadata_1.RelationshipMultiplicity.oneMany || thatConstraint.multiplicity === ecschema_metadata_1.RelationshipMultiplicity.zeroMany) {
391
+ const direction = (0, ecschema_metadata_1.strengthDirectionToString)(navProp.direction);
392
+ yield new exports.Diagnostics.NavigationTargetMustHaveSingularMultiplicity(property, [property.fullName, relationship.fullName, direction]);
393
+ }
394
+ return;
395
+ }
396
+ exports.validateNavigationProperty = validateNavigationProperty;
397
+ /**
398
+ * EC Rule: When overriding a RelationshipClass, the derived abstract constraint must narrow the base constraint classes.
399
+ * @internal
400
+ */
401
+ async function* abstractConstraintMustNarrowBaseConstraints(ecClass) {
402
+ if (!ecClass.baseClass)
403
+ return;
404
+ const baseRelationship = await ecClass.baseClass;
405
+ const sourceResult = await applyAbstractConstraintMustNarrowBaseConstraints(ecClass, ecClass.source, baseRelationship);
406
+ if (sourceResult)
407
+ yield sourceResult;
408
+ const targetResult = await applyAbstractConstraintMustNarrowBaseConstraints(ecClass, ecClass.target, baseRelationship);
409
+ if (targetResult)
410
+ yield targetResult;
411
+ }
412
+ exports.abstractConstraintMustNarrowBaseConstraints = abstractConstraintMustNarrowBaseConstraints;
413
+ /**
414
+ * EC Rule: When overriding a RelationshipClass, derived constraint classes must narrow base constraint classes.
415
+ * @internal
416
+ */
417
+ async function* derivedConstraintsMustNarrowBaseConstraints(ecClass) {
418
+ if (!ecClass.baseClass)
419
+ return;
420
+ const baseRelationship = await ecClass.baseClass;
421
+ const sourceResult = await applyDerivedConstraintsMustNarrowBaseConstraints(ecClass, ecClass.source, baseRelationship);
422
+ if (sourceResult)
423
+ yield sourceResult;
424
+ const targetResult = await applyDerivedConstraintsMustNarrowBaseConstraints(ecClass, ecClass.target, baseRelationship);
425
+ if (targetResult)
426
+ yield targetResult;
427
+ }
428
+ exports.derivedConstraintsMustNarrowBaseConstraints = derivedConstraintsMustNarrowBaseConstraints;
429
+ /**
430
+ * EC Rule: All constraint classes must have a common base class specified in the abstract constraint.
431
+ * @internal
432
+ */
433
+ async function* constraintClassesDeriveFromAbstractContraint(ecClass) {
434
+ const sourceResult = await applyConstraintClassesDeriveFromAbstractContraint(ecClass, ecClass.source);
435
+ if (sourceResult)
436
+ yield sourceResult;
437
+ const targetResult = await applyConstraintClassesDeriveFromAbstractContraint(ecClass, ecClass.target);
438
+ if (targetResult)
439
+ yield targetResult;
440
+ }
441
+ exports.constraintClassesDeriveFromAbstractContraint = constraintClassesDeriveFromAbstractContraint;
442
+ /**
443
+ * EC Rule: At least on concrete constraint class must be defined in the list of constraint classes.
444
+ * @internal
445
+ */
446
+ async function* atLeastOneConstraintClassDefined(constraint) {
447
+ if (!constraint.constraintClasses || constraint.constraintClasses.length === 0) {
448
+ const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
449
+ yield new exports.Diagnostics.AtLeastOneConstraintClassDefined(constraint, [constraintType, constraint.relationshipClass.fullName]);
450
+ }
451
+ }
452
+ exports.atLeastOneConstraintClassDefined = atLeastOneConstraintClassDefined;
453
+ /**
454
+ * EC Rule: If multiple constraints exist, an abstract constraint must be defined.
455
+ * @internal
456
+ */
457
+ async function* abstractConstraintMustExistWithMultipleConstraints(constraint) {
458
+ if (!constraint.constraintClasses || constraint.constraintClasses.length <= 1) {
459
+ return;
460
+ }
461
+ const abstractConstraint = await getAbstractConstraint(constraint);
462
+ if (abstractConstraint)
463
+ return;
464
+ const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
465
+ yield new exports.Diagnostics.AbstractConstraintMustExistWithMultipleConstraints(constraint, [constraintType, constraint.relationshipClass.fullName]);
466
+ }
467
+ exports.abstractConstraintMustExistWithMultipleConstraints = abstractConstraintMustExistWithMultipleConstraints;
468
+ function propertyTypesMatch(propertyA, propertyB) {
469
+ return propertyA.constructor.name === propertyB.constructor.name;
470
+ }
471
+ function getPrimitiveType(property) {
472
+ if (property.isPrimitive())
473
+ return property.primitiveType;
474
+ return undefined;
475
+ }
476
+ /**
477
+ * EC Rule: Enumeration type must be a string or integer
478
+ * @internal
479
+ */
480
+ async function* enumerationTypeUnsupported(enumeration) {
481
+ const type = enumeration.type;
482
+ if (type === ecschema_metadata_1.PrimitiveType.Integer || type === ecschema_metadata_1.PrimitiveType.String)
483
+ return;
484
+ yield new exports.Diagnostics.EnumerationTypeUnsupported(enumeration, [enumeration.fullName]);
485
+ }
486
+ exports.enumerationTypeUnsupported = enumerationTypeUnsupported;
487
+ /**
488
+ * EC Rule: Mixin applied to class must derived from the Mixin appliesTo constraint.
489
+ * @internal
490
+ */
491
+ async function* mixinAppliedToClassMustDeriveFromConstraint(entityClass) {
492
+ for (const lazyMixin of entityClass.mixins) {
493
+ const mixin = await lazyMixin;
494
+ if (!mixin.appliesTo)
495
+ continue;
496
+ if (!await entityClass.is(await mixin.appliesTo))
497
+ yield new exports.Diagnostics.MixinAppliedToClassMustDeriveFromConstraint(entityClass, [mixin.fullName, entityClass.fullName, mixin.appliesTo.fullName]);
498
+ }
499
+ return;
500
+ }
501
+ exports.mixinAppliedToClassMustDeriveFromConstraint = mixinAppliedToClassMustDeriveFromConstraint;
502
+ /**
503
+ * Validates a custom attribute instance and yields EC-500, EC-501, and EC-502 rule violations.
504
+ * @internal
505
+ */
506
+ async function* validateCustomAttributeInstance(container, customAttribute) {
507
+ yield* customAttributeNotOfConcreteClass(container, customAttribute);
508
+ yield* customAttributeSchemaMustBeReferenced(container, customAttribute);
509
+ yield* customAttributeClassMustExist(container, customAttribute);
510
+ }
511
+ exports.validateCustomAttributeInstance = validateCustomAttributeInstance;
512
+ /** EC Rule: CustomAttribute instance must be of a concrete CustomAttributeClass. */
513
+ async function* customAttributeNotOfConcreteClass(container, customAttribute) {
514
+ const schema = container.schema;
515
+ const caClass = await schema.lookupItem(customAttribute.className);
516
+ if (!caClass)
517
+ return;
518
+ if (caClass.modifier !== ecschema_metadata_1.ECClassModifier.Abstract)
519
+ return;
520
+ yield new exports.Diagnostics.CustomAttributeNotOfConcreteClass(container, [container.fullName, caClass.fullName]);
521
+ }
522
+ /** EC Rule: CustomAttribute Schema must be referenced by the container's Schema. */
523
+ async function* customAttributeSchemaMustBeReferenced(container, customAttribute) {
524
+ const schema = container.schema;
525
+ const nameParts = customAttribute.className.split(".");
526
+ if (nameParts.length === 1 || nameParts[0] === schema.name)
527
+ return;
528
+ if (schema.references.some((s) => s.name === nameParts[0]))
529
+ return;
530
+ yield new exports.Diagnostics.CustomAttributeSchemaMustBeReferenced(container, [container.fullName, customAttribute.className]);
531
+ }
532
+ /** EC Rule: CustomAttribute instance class must exist. */
533
+ async function* customAttributeClassMustExist(container, customAttribute) {
534
+ const schema = container.schema;
535
+ const caClass = await schema.lookupItem(customAttribute.className);
536
+ if (!caClass)
537
+ yield new exports.Diagnostics.CustomAttributeClassNotFound(container, [container.fullName, customAttribute.className]);
538
+ }
539
+ async function applyAbstractConstraintMustNarrowBaseConstraints(ecClass, constraint, baseRelationship) {
540
+ const baseConstraint = constraint.isSource ? baseRelationship.source : baseRelationship.target;
541
+ const abstractConstraint = await constraint.abstractConstraint;
542
+ if (!abstractConstraint)
543
+ return;
544
+ if (await baseConstraint.supportsClass(abstractConstraint))
545
+ return;
546
+ const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
547
+ return new exports.Diagnostics.AbstractConstraintMustNarrowBaseConstraints(ecClass, [abstractConstraint.fullName, constraintType, constraint.relationshipClass.fullName, baseRelationship.fullName]);
548
+ }
549
+ async function applyDerivedConstraintsMustNarrowBaseConstraints(ecClass, constraint, baseRelationship) {
550
+ const baseConstraint = constraint.isSource ? baseRelationship.source : baseRelationship.target;
551
+ if (!constraint.constraintClasses)
552
+ return;
553
+ for (const classPromise of constraint.constraintClasses) {
554
+ const constraintClass = await classPromise;
555
+ if (await baseConstraint.supportsClass(constraintClass))
556
+ continue;
557
+ const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
558
+ return new exports.Diagnostics.DerivedConstraintsMustNarrowBaseConstraints(ecClass, [constraintClass.fullName, constraintType, constraint.relationshipClass.fullName, baseRelationship.fullName]);
559
+ }
560
+ return;
561
+ }
562
+ async function applyConstraintClassesDeriveFromAbstractContraint(ecClass, constraint) {
563
+ const abstractConstraint = await getAbstractConstraint(constraint);
564
+ if (!abstractConstraint)
565
+ return;
566
+ if (!constraint.constraintClasses)
567
+ return;
568
+ for (const classPromise of constraint.constraintClasses) {
569
+ const constraintClass = await classPromise;
570
+ if (constraintClass.schemaItemType === ecschema_metadata_1.SchemaItemType.Mixin && abstractConstraint.schemaItemType === ecschema_metadata_1.SchemaItemType.EntityClass) {
571
+ if (!await (constraintClass).applicableTo(abstractConstraint)) {
572
+ const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
573
+ return new exports.Diagnostics.ConstraintClassesDeriveFromAbstractContraint(ecClass, [constraintClass.fullName, constraintType, constraint.relationshipClass.fullName, abstractConstraint.fullName]);
574
+ }
575
+ continue;
576
+ }
577
+ if (!await constraintClass.is(abstractConstraint)) {
578
+ const constraintType = constraint.isSource ? ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_SOURCE : ecschema_metadata_1.ECStringConstants.RELATIONSHIP_END_TARGET;
579
+ return new exports.Diagnostics.ConstraintClassesDeriveFromAbstractContraint(ecClass, [constraintClass.fullName, constraintType, constraint.relationshipClass.fullName, abstractConstraint.fullName]);
580
+ }
581
+ }
582
+ return;
583
+ }
584
+ async function getAbstractConstraint(constraint) {
585
+ const abstractConstraint = await constraint.abstractConstraint;
586
+ if (abstractConstraint)
587
+ return abstractConstraint;
588
+ const baseRelationship = await constraint.relationshipClass.baseClass;
589
+ if (!baseRelationship)
590
+ return;
591
+ const baseConstraint = constraint.isSource ? baseRelationship.source : baseRelationship.target;
592
+ return getAbstractConstraint(baseConstraint);
593
+ }
594
594
  //# sourceMappingURL=ECRules.js.map