@api-client/core 0.14.0 → 0.14.2

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 (169) hide show
  1. package/build/src/amf/AmfTypes.d.ts +1 -1
  2. package/build/src/amf/AmfTypes.js +1 -1
  3. package/build/src/amf/AmfTypes.js.map +1 -1
  4. package/build/src/amf/Utils.d.ts +0 -6
  5. package/build/src/amf/Utils.d.ts.map +1 -1
  6. package/build/src/amf/Utils.js +0 -14
  7. package/build/src/amf/Utils.js.map +1 -1
  8. package/build/src/browser.d.ts +2 -1
  9. package/build/src/browser.d.ts.map +1 -1
  10. package/build/src/browser.js +1 -0
  11. package/build/src/browser.js.map +1 -1
  12. package/build/src/index.d.ts +2 -1
  13. package/build/src/index.d.ts.map +1 -1
  14. package/build/src/index.js +1 -0
  15. package/build/src/index.js.map +1 -1
  16. package/build/src/legacy.d.ts +0 -8
  17. package/build/src/legacy.d.ts.map +1 -1
  18. package/build/src/legacy.js +0 -9
  19. package/build/src/legacy.js.map +1 -1
  20. package/build/src/modeling/Bindings.d.ts +1 -1
  21. package/build/src/modeling/Bindings.js.map +1 -1
  22. package/build/src/modeling/DataDomain.js +2 -2
  23. package/build/src/modeling/DataDomain.js.map +1 -1
  24. package/build/src/modeling/DataFormat.d.ts +0 -40
  25. package/build/src/modeling/DataFormat.d.ts.map +1 -1
  26. package/build/src/modeling/DataFormat.js +0 -27
  27. package/build/src/modeling/DataFormat.js.map +1 -1
  28. package/build/src/modeling/DomainAssociation.d.ts +63 -0
  29. package/build/src/modeling/DomainAssociation.d.ts.map +1 -1
  30. package/build/src/modeling/DomainAssociation.js +110 -4
  31. package/build/src/modeling/DomainAssociation.js.map +1 -1
  32. package/build/src/modeling/DomainEntity.d.ts +25 -9
  33. package/build/src/modeling/DomainEntity.d.ts.map +1 -1
  34. package/build/src/modeling/DomainEntity.js +65 -21
  35. package/build/src/modeling/DomainEntity.js.map +1 -1
  36. package/build/src/modeling/DomainFile.d.ts +1 -1
  37. package/build/src/modeling/DomainFile.js +1 -1
  38. package/build/src/modeling/DomainFile.js.map +1 -1
  39. package/build/src/modeling/DomainImpactAnalysis.d.ts +1 -1
  40. package/build/src/modeling/DomainImpactAnalysis.d.ts.map +1 -1
  41. package/build/src/modeling/DomainImpactAnalysis.js +3 -3
  42. package/build/src/modeling/DomainImpactAnalysis.js.map +1 -1
  43. package/build/src/modeling/DomainModel.d.ts +2 -2
  44. package/build/src/modeling/DomainModel.js +2 -2
  45. package/build/src/modeling/DomainModel.js.map +1 -1
  46. package/build/src/modeling/DomainProperty.d.ts +28 -12
  47. package/build/src/modeling/DomainProperty.d.ts.map +1 -1
  48. package/build/src/modeling/DomainProperty.js +61 -26
  49. package/build/src/modeling/DomainProperty.js.map +1 -1
  50. package/build/src/modeling/Semantics.d.ts +117 -0
  51. package/build/src/modeling/Semantics.d.ts.map +1 -0
  52. package/build/src/modeling/Semantics.js +112 -0
  53. package/build/src/modeling/Semantics.js.map +1 -0
  54. package/build/src/models/kinds.d.ts +0 -24
  55. package/build/src/models/kinds.d.ts.map +1 -1
  56. package/build/src/models/kinds.js +0 -24
  57. package/build/src/models/kinds.js.map +1 -1
  58. package/build/src/models/store/data_catalog.d.ts +1 -1
  59. package/build/src/models/store/data_catalog.js.map +1 -1
  60. package/build/tsconfig.tsbuildinfo +1 -1
  61. package/data/models/APIC-187.json +3 -3
  62. package/data/models/APIC-188.json +3 -3
  63. package/data/models/APIC-233.json +1 -1
  64. package/data/models/APIC-391.json +2 -2
  65. package/data/models/APIC-483.json +1 -1
  66. package/data/models/APIC-487.json +1 -1
  67. package/data/models/APIC-655.json +1 -1
  68. package/data/models/APIC-689.json +1 -1
  69. package/data/models/APIC-690.json +5 -5
  70. package/data/models/SE-10469.json +1 -1
  71. package/data/models/SE-13092.json +5 -5
  72. package/data/models/SE-22063.json +12 -2
  73. package/data/models/amf-helper-api.json +154 -14
  74. package/data/models/arc-demo-api.json +95 -15
  75. package/data/models/async-api.json +1 -1
  76. package/data/models/example-generator-api.json +369 -29
  77. package/data/models/expanded-api.json +1 -1
  78. package/data/models/flattened-api.json +1 -1
  79. package/data/models/multiple-servers.json +1 -1
  80. package/data/models/oas-3-api.json +1 -1
  81. package/data/models/oas-date.json +1 -1
  82. package/data/models/oas-types.json +1 -1
  83. package/data/models/oas-unions.json +1 -1
  84. package/data/models/petstore.json +1 -1
  85. package/data/models/raml-date.json +1 -1
  86. package/data/models/recursive.json +1 -1
  87. package/data/models/schema-api.json +62 -2
  88. package/data/models/secured-api.json +16 -16
  89. package/data/models/tracked-to-linked.json +4 -4
  90. package/package.json +2 -2
  91. package/src/amf/AmfTypes.ts +1 -1
  92. package/src/amf/Utils.ts +0 -15
  93. package/src/modeling/Bindings.ts +1 -1
  94. package/src/modeling/DataDomain.ts +2 -2
  95. package/src/modeling/DataFormat.ts +0 -48
  96. package/src/modeling/DomainAssociation.ts +122 -3
  97. package/src/modeling/DomainEntity.ts +56 -17
  98. package/src/modeling/DomainFile.ts +1 -1
  99. package/src/modeling/DomainImpactAnalysis.ts +3 -3
  100. package/src/modeling/DomainModel.ts +2 -2
  101. package/src/modeling/DomainProperty.ts +60 -21
  102. package/src/modeling/Semantics.ts +195 -0
  103. package/src/modeling/graph.md +14 -14
  104. package/src/modeling/readme.md +29 -29
  105. package/src/models/kinds.ts +0 -25
  106. package/src/models/store/data_catalog.ts +1 -1
  107. package/tests/unit/modeling/data_domain_change_observers.spec.ts +11 -10
  108. package/tests/unit/modeling/data_domain_entities.spec.ts +129 -1
  109. package/tests/unit/modeling/data_domain_property.spec.ts +1 -1
  110. package/tests/unit/modeling/domain_asociation.spec.ts +267 -0
  111. package/tests/unit/modeling/domain_entity.spec.ts +27 -26
  112. package/tests/unit/modeling/domain_entity_example_generator_json.spec.ts +11 -11
  113. package/tests/unit/modeling/domain_entity_example_generator_xml.spec.ts +10 -10
  114. package/tests/unit/modeling/{domain.property.spec.ts → domain_property.spec.ts} +139 -23
  115. package/tests/unit/modeling/semantics.spec.ts +149 -0
  116. package/build/src/amf/AmfShapeGenerator.d.ts +0 -103
  117. package/build/src/amf/AmfShapeGenerator.d.ts.map +0 -1
  118. package/build/src/amf/AmfShapeGenerator.js +0 -416
  119. package/build/src/amf/AmfShapeGenerator.js.map +0 -1
  120. package/build/src/modeling/legacy/DataAssociation.d.ts +0 -284
  121. package/build/src/modeling/legacy/DataAssociation.d.ts.map +0 -1
  122. package/build/src/modeling/legacy/DataAssociation.js +0 -443
  123. package/build/src/modeling/legacy/DataAssociation.js.map +0 -1
  124. package/build/src/modeling/legacy/DataEntity.d.ts +0 -358
  125. package/build/src/modeling/legacy/DataEntity.d.ts.map +0 -1
  126. package/build/src/modeling/legacy/DataEntity.js +0 -855
  127. package/build/src/modeling/legacy/DataEntity.js.map +0 -1
  128. package/build/src/modeling/legacy/DataEntityBuilder.d.ts +0 -162
  129. package/build/src/modeling/legacy/DataEntityBuilder.d.ts.map +0 -1
  130. package/build/src/modeling/legacy/DataEntityBuilder.js +0 -221
  131. package/build/src/modeling/legacy/DataEntityBuilder.js.map +0 -1
  132. package/build/src/modeling/legacy/DataImpactAnalysis.d.ts +0 -298
  133. package/build/src/modeling/legacy/DataImpactAnalysis.d.ts.map +0 -1
  134. package/build/src/modeling/legacy/DataImpactAnalysis.js +0 -441
  135. package/build/src/modeling/legacy/DataImpactAnalysis.js.map +0 -1
  136. package/build/src/modeling/legacy/DataModel.d.ts +0 -99
  137. package/build/src/modeling/legacy/DataModel.d.ts.map +0 -1
  138. package/build/src/modeling/legacy/DataModel.js +0 -237
  139. package/build/src/modeling/legacy/DataModel.js.map +0 -1
  140. package/build/src/modeling/legacy/DataNamespace.d.ts +0 -340
  141. package/build/src/modeling/legacy/DataNamespace.d.ts.map +0 -1
  142. package/build/src/modeling/legacy/DataNamespace.js +0 -784
  143. package/build/src/modeling/legacy/DataNamespace.js.map +0 -1
  144. package/build/src/modeling/legacy/DataProperty.d.ts +0 -332
  145. package/build/src/modeling/legacy/DataProperty.d.ts.map +0 -1
  146. package/build/src/modeling/legacy/DataProperty.js +0 -415
  147. package/build/src/modeling/legacy/DataProperty.js.map +0 -1
  148. package/build/src/models/store/DataFile.d.ts +0 -29
  149. package/build/src/models/store/DataFile.d.ts.map +0 -1
  150. package/build/src/models/store/DataFile.js +0 -87
  151. package/build/src/models/store/DataFile.js.map +0 -1
  152. package/src/amf/AmfShapeGenerator.ts +0 -477
  153. package/src/modeling/legacy/DataAssociation.ts +0 -554
  154. package/src/modeling/legacy/DataEntity.ts +0 -1019
  155. package/src/modeling/legacy/DataEntityBuilder.ts +0 -236
  156. package/src/modeling/legacy/DataImpactAnalysis.ts +0 -530
  157. package/src/modeling/legacy/DataModel.ts +0 -276
  158. package/src/modeling/legacy/DataNamespace.ts +0 -929
  159. package/src/modeling/legacy/DataProperty.ts +0 -630
  160. package/src/models/store/DataFile.ts +0 -95
  161. package/tests/unit/modeling/legacy/amf_shape_generator.spec.ts +0 -1041
  162. package/tests/unit/modeling/legacy/data_association.spec.ts +0 -710
  163. package/tests/unit/modeling/legacy/data_entity.spec.ts +0 -2061
  164. package/tests/unit/modeling/legacy/data_entity_generator_json.spec.ts +0 -987
  165. package/tests/unit/modeling/legacy/data_entity_generator_xml.spec.ts +0 -1451
  166. package/tests/unit/modeling/legacy/data_model.spec.ts +0 -395
  167. package/tests/unit/modeling/legacy/data_namespace.spec.ts +0 -1312
  168. package/tests/unit/modeling/legacy/data_property.spec.ts +0 -887
  169. package/tests/unit/modeling/legacy/impact_analysis.spec.ts +0 -373
@@ -10,6 +10,27 @@ import type { AssociationBinding, AssociationBindings, AssociationWebBindings }
10
10
  import { DomainAttributeAttribute, DomainAttributeAttributes } from './DataFormat.js'
11
11
  import type { AssociationTarget, DomainGraphEdge } from './types.js'
12
12
  import { ShapeGenerator } from './amf/ShapeGenerator.js'
13
+ import { DataSemantics, isAssociationSemantic, type SemanticType, type AppliedDataSemantic } from './Semantics.js'
14
+
15
+ /**
16
+ * Defines the behavior when a parent entity in an association is deleted.
17
+ *
18
+ * - `restrict`: Prevents the deletion of a parent entity if it has any associated child entities.
19
+ * The generated API should return a clear and specific error message (e.g., 409 Conflict).
20
+ * - _Example_: Do not allow a Department to be deleted if it still has Employees.
21
+ * - `cascade`: Automatically deletes all associated child entities when the parent entity is deleted.
22
+ * - _Example_: Deleting a User will also delete all their associated Posts and Comments.
23
+ * - `setNull`: Sets the foreign key of the associated child entities to NULL. This is only valid if the
24
+ * association property on the child entity is nullable.
25
+ * - _Example_: When a `Project` is deleted, the `project_id` on associated `Tasks` is set to NULL,
26
+ * making them unassigned but not deleting them.
27
+ * - `doNothing`: No action is taken on the associated child entities when the parent entity is deleted.
28
+ * - _Example_: Deleting a `Category` does not affect associated `Products`, which remain in the database
29
+ * but may become orphaned.
30
+ * This is useful when the association is optional or when child entities should not be deleted
31
+ * or modified upon the deletion of a parent entity.
32
+ */
33
+ export type OnDeleteRule = 'restrict' | 'cascade' | 'setNull' | 'doNothing'
13
34
 
14
35
  export interface DomainAssociationSchema extends DomainElementSchema {
15
36
  kind: typeof DomainAssociationKind
@@ -47,6 +68,20 @@ export interface DomainAssociationSchema extends DomainElementSchema {
47
68
  * When multiple associations are set then we are dealing with an union.
48
69
  */
49
70
  targets?: AssociationTarget[]
71
+ /**
72
+ * The semantics applied to this association.
73
+ * This is a list of applied semantics that can be used to
74
+ * describe the association in more detail.
75
+ */
76
+ semantics?: AppliedDataSemantic[]
77
+ /**
78
+ * Defines the behavior when a parent entity in an association is deleted.
79
+ */
80
+ onDelete?: OnDeleteRule
81
+ /**
82
+ * Whether the association is read-only.
83
+ */
84
+ readOnly?: boolean
50
85
  }
51
86
 
52
87
  /**
@@ -141,6 +176,21 @@ export class DomainAssociation extends DomainElement {
141
176
  */
142
177
  @observed({ deep: true }) accessor targets: AssociationTarget[]
143
178
 
179
+ /**
180
+ * Semantics applied to this association.
181
+ */
182
+ @observed({ deep: true }) accessor semantics: AppliedDataSemantic[] = []
183
+
184
+ /**
185
+ * Defines the behavior when a parent entity in an association is deleted.
186
+ */
187
+ @observed() accessor onDelete: OnDeleteRule | undefined
188
+
189
+ /**
190
+ * Whether the association is read-only.
191
+ */
192
+ @observed() accessor readOnly: boolean | undefined
193
+
144
194
  /**
145
195
  * Creates a full data association schema with defaults.
146
196
  *
@@ -148,13 +198,22 @@ export class DomainAssociation extends DomainElement {
148
198
  * @returns The data association schema.
149
199
  */
150
200
  static createSchema(input: Partial<DomainAssociationSchema> = {}): DomainAssociationSchema {
151
- const { key = nanoid() } = input
201
+ const { key = nanoid(), semantics = [] } = input
152
202
  const info = Thing.fromJSON(input.info, { name: 'new_association' }).toJSON()
153
203
  const result: DomainAssociationSchema = {
154
204
  kind: DomainAssociationKind,
155
205
  key,
156
206
  info,
157
207
  }
208
+ if (Array.isArray(semantics)) {
209
+ result.semantics = [...semantics]
210
+ }
211
+ if (input.onDelete) {
212
+ result.onDelete = input.onDelete
213
+ }
214
+ if (typeof input.readOnly === 'boolean') {
215
+ result.readOnly = input.readOnly
216
+ }
158
217
  if (input.schema) {
159
218
  result.schema = structuredClone(input.schema)
160
219
  }
@@ -207,6 +266,17 @@ export class DomainAssociation extends DomainElement {
207
266
  } else {
208
267
  this.targets = []
209
268
  }
269
+ if (Array.isArray(init.semantics)) {
270
+ this.semantics = init.semantics.map((item) => structuredClone(item))
271
+ } else {
272
+ this.semantics = []
273
+ }
274
+ if (init.onDelete) {
275
+ this.onDelete = init.onDelete
276
+ }
277
+ if (typeof init.readOnly === 'boolean') {
278
+ this.readOnly = init.readOnly
279
+ }
210
280
  }
211
281
 
212
282
  /**
@@ -230,10 +300,19 @@ export class DomainAssociation extends DomainElement {
230
300
  result.required = this.required
231
301
  }
232
302
  if (Array.isArray(this.bindings) && this.bindings.length) {
233
- result.bindings = (toRaw(this, this.bindings) as AssociationBinding[]).map((i) => structuredClone(i))
303
+ result.bindings = toRaw(this, this.bindings)?.map((i) => structuredClone(i))
234
304
  }
235
305
  if (Array.isArray(this.targets) && this.targets.length) {
236
- result.targets = (toRaw(this, this.targets) as AssociationTarget[]).map((i) => ({ ...i }))
306
+ result.targets = toRaw(this, this.targets)?.map((i) => ({ ...i }))
307
+ }
308
+ if (Array.isArray(this.semantics) && this.semantics.length) {
309
+ result.semantics = toRaw(this, this.semantics)?.map((i) => structuredClone(i))
310
+ }
311
+ if (this.onDelete) {
312
+ result.onDelete = this.onDelete
313
+ }
314
+ if (typeof this.readOnly === 'boolean' && this.readOnly) {
315
+ result.readOnly = this.readOnly
237
316
  }
238
317
  return result
239
318
  }
@@ -472,4 +551,44 @@ export class DomainAssociation extends DomainElement {
472
551
  const serializer = new ShapeGenerator()
473
552
  return serializer.associationProperty(this)
474
553
  }
554
+
555
+ /**
556
+ * Adds or updates a semantic to the association.
557
+ * @param semantic The semantic to add to the association.
558
+ * @throws Error if the semantic is not an association semantic.
559
+ */
560
+ addSemantic(semantic: AppliedDataSemantic): void {
561
+ const sem = DataSemantics[semantic.id]
562
+ if (!isAssociationSemantic(sem)) {
563
+ throw new Error(`Invalid semantic type: ${semantic.id}. Expected an association semantic.`)
564
+ }
565
+ const index = this.semantics.findIndex((s) => s.id === semantic.id)
566
+ if (index >= 0) {
567
+ this.semantics[index] = semantic
568
+ } else {
569
+ this.semantics.push(semantic)
570
+ }
571
+ this.domain.notifyChange()
572
+ }
573
+
574
+ /**
575
+ * Removes a semantic from the association.
576
+ * @param semanticId The ID of the semantic to remove.
577
+ */
578
+ removeSemantic(semanticId: SemanticType): void {
579
+ const index = this.semantics.findIndex((s) => s.id === semanticId)
580
+ if (index >= 0) {
581
+ this.semantics.splice(index, 1)
582
+ this.domain.notifyChange()
583
+ }
584
+ }
585
+
586
+ /**
587
+ * Checks if the association has a specific semantic.
588
+ * @param semanticId The ID of the semantic to check.
589
+ * @returns True if the semantic is present, false otherwise.
590
+ */
591
+ hasSemantic(semanticId: SemanticType): boolean {
592
+ return this.semantics.some((s) => s.id === semanticId)
593
+ }
475
594
  }
@@ -17,6 +17,7 @@ import { ShapeGenerator } from './amf/ShapeGenerator.js'
17
17
  import type { IShapeRenderOptions } from '../amf/shape/ShapeBase.js'
18
18
  import { ApiSchemaGenerator } from '../amf/ApiSchemaGenerator.js'
19
19
  import { removeGraphNode } from './GraphUtils.js'
20
+ import { DataSemantics, isEntitySemantic, type SemanticType, type AppliedDataSemantic } from './Semantics.js'
20
21
 
21
22
  export interface EntityOrderedItem {
22
23
  /**
@@ -43,11 +44,11 @@ export interface DomainEntitySchema extends DomainElementSchema {
43
44
  tags?: string[]
44
45
 
45
46
  /**
46
- * For future use.
47
- *
48
- * The keys of the taxonomy items associated with the entity.
47
+ * The semantics applied to this entity.
48
+ * This is a list of applied semantics that can be used to
49
+ * describe the entity in more detail.
49
50
  */
50
- taxonomy?: string[]
51
+ semantics?: AppliedDataSemantic[]
51
52
 
52
53
  /**
53
54
  * The ordered list of fields (properties and associations) in the schema.
@@ -76,7 +77,7 @@ export interface DomainEntitySchema extends DomainElementSchema {
76
77
  * - **Properties:** Defines the data elements (fields) within the entity.
77
78
  * - **Associations:** Defines relationships to other entities.
78
79
  * - **Inheritance:** Supports inheriting properties and associations from parent entities.
79
- * - **Metadata:** Supports tags, taxonomy, and deprecation status.
80
+ * - **Metadata:** Supports tags, semantics, and deprecation status.
80
81
  * - **AMF Shape Generation:** Can be serialized to an AMF (API Modeling Framework) shape.
81
82
  * - **Example Generation:** Can generate example databased on its schema.
82
83
  *
@@ -139,11 +140,9 @@ export class DomainEntity extends DomainElement {
139
140
  @observed({ deep: true }) accessor tags: string[]
140
141
 
141
142
  /**
142
- * Reserved for future use.
143
- *
144
- * The keys of the taxonomy items associated with the entity.
143
+ * Semantics applied to this property.
145
144
  */
146
- @observed({ deep: true }) accessor taxonomy: string[]
145
+ @observed({ deep: true }) accessor semantics: AppliedDataSemantic[] = []
147
146
 
148
147
  /**
149
148
  * The ordered list of fields (properties and associations) in the schema.
@@ -165,7 +164,7 @@ export class DomainEntity extends DomainElement {
165
164
  * @returns The data entity schema.
166
165
  */
167
166
  static createSchema(input: Partial<DomainEntitySchema> = {}): DomainEntitySchema {
168
- const { key = nanoid(), tags, taxonomy, fields, deprecated } = input
167
+ const { key = nanoid(), tags, semantics, fields, deprecated } = input
169
168
  const info = Thing.fromJSON(input.info, { name: 'New entity' }).toJSON()
170
169
  const result: DomainEntitySchema = {
171
170
  kind: DomainEntityKind,
@@ -175,8 +174,8 @@ export class DomainEntity extends DomainElement {
175
174
  if (Array.isArray(tags)) {
176
175
  result.tags = [...tags]
177
176
  }
178
- if (Array.isArray(taxonomy)) {
179
- result.taxonomy = [...taxonomy]
177
+ if (Array.isArray(semantics)) {
178
+ result.semantics = [...semantics]
180
179
  }
181
180
  if (Array.isArray(fields)) {
182
181
  result.fields = [...fields]
@@ -206,10 +205,10 @@ export class DomainEntity extends DomainElement {
206
205
  } else {
207
206
  this.tags = []
208
207
  }
209
- if (Array.isArray(init.taxonomy)) {
210
- this.taxonomy = [...init.taxonomy]
208
+ if (Array.isArray(init.semantics)) {
209
+ this.semantics = init.semantics.map((item) => structuredClone(item))
211
210
  } else {
212
- this.taxonomy = []
211
+ this.semantics = []
213
212
  }
214
213
  if (Array.isArray(init.fields)) {
215
214
  this.fields = [...init.fields]
@@ -235,8 +234,8 @@ export class DomainEntity extends DomainElement {
235
234
  if (Array.isArray(this.fields) && this.fields.length) {
236
235
  result.fields = [...this.fields]
237
236
  }
238
- if (Array.isArray(this.taxonomy) && this.taxonomy.length) {
239
- result.taxonomy = [...(toRaw(this, this.taxonomy) as string[])]
237
+ if (Array.isArray(this.semantics) && this.semantics.length) {
238
+ result.semantics = toRaw(this, this.semantics)?.map((i) => structuredClone(i))
240
239
  }
241
240
  if (Array.isArray(this.tags) && this.tags.length) {
242
241
  result.tags = [...(toRaw(this, this.tags) as string[])]
@@ -841,4 +840,44 @@ export class DomainEntity extends DomainElement {
841
840
  }
842
841
  return property
843
842
  }
843
+
844
+ /**
845
+ * Adds or updates a semantic to the entity.
846
+ * @param semantic The semantic to add to the entity.
847
+ * @throws Error if the semantic is not an entity semantic.
848
+ */
849
+ addSemantic(semantic: AppliedDataSemantic): void {
850
+ const sem = DataSemantics[semantic.id]
851
+ if (!isEntitySemantic(sem)) {
852
+ throw new Error(`Invalid semantic type: ${semantic.id}. Expected an entity semantic.`)
853
+ }
854
+ const index = this.semantics.findIndex((s) => s.id === semantic.id)
855
+ if (index >= 0) {
856
+ this.semantics[index] = semantic
857
+ } else {
858
+ this.semantics.push(semantic)
859
+ }
860
+ this.domain.notifyChange()
861
+ }
862
+
863
+ /**
864
+ * Removes a semantic from the entity.
865
+ * @param semanticId The ID of the semantic to remove.
866
+ */
867
+ removeSemantic(semanticId: SemanticType): void {
868
+ const index = this.semantics.findIndex((s) => s.id === semanticId)
869
+ if (index >= 0) {
870
+ this.semantics.splice(index, 1)
871
+ this.domain.notifyChange()
872
+ }
873
+ }
874
+
875
+ /**
876
+ * Checks if the entity has a specific semantic.
877
+ * @param semanticId The ID of the semantic to check.
878
+ * @returns True if the semantic is present, false otherwise.
879
+ */
880
+ hasSemantic(semanticId: SemanticType): boolean {
881
+ return this.semantics.some((s) => s.id === semanticId)
882
+ }
844
883
  }
@@ -19,7 +19,7 @@ export class DomainFile extends File {
19
19
  }
20
20
 
21
21
  /**
22
- * Creates the file definition for a DataNamespace contents.
22
+ * Creates the file definition for a DomainNamespace contents.
23
23
  *
24
24
  * @param input The data namespace instance or schema.
25
25
  */
@@ -436,7 +436,7 @@ export class DomainImpactAnalysis {
436
436
  this.deleteNamespaceAnalysis(key, rootKey)
437
437
  break
438
438
  case DomainModelKind:
439
- this.deleteDataModelAnalysis(key, rootKey)
439
+ this.deleteModelAnalysis(key, rootKey)
440
440
  break
441
441
  case DomainEntityKind:
442
442
  this.deleteEntityAnalysis(key, rootKey)
@@ -469,11 +469,11 @@ export class DomainImpactAnalysis {
469
469
  this.deleteNamespaceAnalysis(child.key, rootKey)
470
470
  }
471
471
  for (const child of ns.listModels()) {
472
- this.deleteDataModelAnalysis(child.key, rootKey)
472
+ this.deleteModelAnalysis(child.key, rootKey)
473
473
  }
474
474
  }
475
475
 
476
- protected deleteDataModelAnalysis(key: string, rootKey: string): void {
476
+ protected deleteModelAnalysis(key: string, rootKey: string): void {
477
477
  const model = this.root.findModel(key)
478
478
  if (!model) {
479
479
  return
@@ -64,10 +64,10 @@ export interface DomainModelSchema extends DomainElementSchema {
64
64
  *
65
65
  * ```typescript
66
66
  * const dataDomain = new DataDomain();
67
- * const dataNamespace = dataDomain.addNamespace({
67
+ * const ns = dataDomain.addNamespace({
68
68
  * key: 'myNamespace',
69
69
  * });
70
- * const userModel = dataNamespace.addModel({
70
+ * const userModel = ns.addModel({
71
71
  * key: 'userModel',
72
72
  * info: { name: 'User Model' },
73
73
  * });
@@ -16,12 +16,13 @@ import {
16
16
  type NumberFormat,
17
17
  NumberFormats,
18
18
  } from './DataFormat.js'
19
+ import { ShapeGenerator } from './amf/ShapeGenerator.js'
19
20
  import type { PropertyBinding, PropertyBindings, PropertyWebBindings } from './Bindings.js'
20
21
  import type { ModelValidationOptions } from '../models/types.js'
21
22
  import type { DomainEntity } from './DomainEntity.js'
22
23
  import type { IApiPropertyShape } from '../amf/definitions/Shapes.js'
23
- import { ShapeGenerator } from './amf/ShapeGenerator.js'
24
- import { PropertySchema } from './types.js'
24
+ import type { PropertySchema } from './types.js'
25
+ import { DataSemantics, isPropertySemantic, type SemanticType, type AppliedDataSemantic } from './Semantics.js'
25
26
 
26
27
  export interface DomainPropertySchema extends DomainElementSchema {
27
28
  kind: typeof DomainPropertyKind
@@ -62,11 +63,11 @@ export interface DomainPropertySchema extends DomainElementSchema {
62
63
  */
63
64
  tags?: string[]
64
65
  /**
65
- * For future use.
66
- *
67
- * The keys of the taxonomy items associated with the property.
66
+ * The semantics applied to this property.
67
+ * This is a list of applied semantics that can be used to
68
+ * describe the property in more detail.
68
69
  */
69
- taxonomy?: string[]
70
+ semantics?: AppliedDataSemantic[]
70
71
  /**
71
72
  * The data type for this property.
72
73
  * Note, not all schemas support the same type. For example, defining `sint32`
@@ -106,21 +107,21 @@ export interface DomainPropertySchema extends DomainElementSchema {
106
107
  * - **Bindings:** Allows defining how the property is
107
108
  * represented in different formats (e.g., web APIs,
108
109
  * protocol buffers).
109
- * - **Metadata:** Supports metadata such as tags, taxonomy,
110
+ * - **Metadata:** Supports metadata such as tags, semantics,
110
111
  * read-only/write-only status, and deprecation.
111
112
  * - **Schema:** Allows defining a general schema for the
112
113
  * property, which is propagated to all bindings.
113
114
  *
114
115
  * **Usage:**
115
116
  *
116
- * Use the `DataEntity.addProperty` method to add a new property to an
117
+ * Use the `DomainEntity.addProperty` method to add a new property to an
117
118
  * entity. The property can be created using the constructor, but it
118
119
  * won't be added to the graph until you call the `addProperty` method.
119
120
  *
120
121
  * **Example:**
121
122
  *
122
123
  * ```typescript
123
- * const entity = dataModel.addEntity({ key: 'user' });
124
+ * const entity = domainModel.addEntity({ key: 'user' });
124
125
  * const property = entity.addProperty({
125
126
  * key: 'name',
126
127
  * type: 'string',
@@ -185,11 +186,9 @@ export class DomainProperty extends DomainElement {
185
186
  @observed({ deep: true }) accessor tags: string[] = []
186
187
 
187
188
  /**
188
- * Reserved for future use.
189
- *
190
- * The keys of the taxonomy items associated with the property.
189
+ * Semantics applied to this property.
191
190
  */
192
- @observed({ deep: true }) accessor taxonomy: string[] = []
191
+ @observed({ deep: true }) accessor semantics: AppliedDataSemantic[] = []
193
192
 
194
193
  /**
195
194
  * The data type for this property.
@@ -232,7 +231,7 @@ export class DomainProperty extends DomainElement {
232
231
  readOnly,
233
232
  writeOnly,
234
233
  tags,
235
- taxonomy,
234
+ semantics,
236
235
  deprecated,
237
236
  schema,
238
237
  bindings,
@@ -273,8 +272,8 @@ export class DomainProperty extends DomainElement {
273
272
  if (Array.isArray(tags)) {
274
273
  result.tags = [...tags]
275
274
  }
276
- if (Array.isArray(taxonomy)) {
277
- result.taxonomy = [...taxonomy]
275
+ if (Array.isArray(semantics)) {
276
+ result.semantics = [...semantics]
278
277
  }
279
278
  if (schema) {
280
279
  result.schema = structuredClone(schema)
@@ -353,10 +352,10 @@ export class DomainProperty extends DomainElement {
353
352
  } else {
354
353
  this.tags = []
355
354
  }
356
- if (Array.isArray(init.taxonomy)) {
357
- this.taxonomy = [...init.taxonomy]
355
+ if (Array.isArray(init.semantics)) {
356
+ this.semantics = [...init.semantics]
358
357
  } else {
359
- this.taxonomy = []
358
+ this.semantics = []
360
359
  }
361
360
  if (init.schema) {
362
361
  this.schema = structuredClone(init.schema)
@@ -419,8 +418,8 @@ export class DomainProperty extends DomainElement {
419
418
  if (Array.isArray(this.tags) && this.tags.length) {
420
419
  result.tags = [...this.tags]
421
420
  }
422
- if (Array.isArray(this.taxonomy) && this.taxonomy.length) {
423
- result.taxonomy = [...this.taxonomy]
421
+ if (Array.isArray(this.semantics) && this.semantics.length) {
422
+ result.semantics = toRaw(this, this.semantics)?.map((i) => structuredClone(i))
424
423
  }
425
424
  if (this.schema) {
426
425
  result.schema = structuredClone(toRaw(this, this.schema))
@@ -545,4 +544,44 @@ export class DomainProperty extends DomainElement {
545
544
  const serializer = new ShapeGenerator()
546
545
  return serializer.property(this)
547
546
  }
547
+
548
+ /**
549
+ * Adds or updates a semantic to the property.
550
+ * @param semantic The semantic to add to the property.
551
+ * @throws Error if the semantic is not an property semantic.
552
+ */
553
+ addSemantic(semantic: AppliedDataSemantic): void {
554
+ const sem = DataSemantics[semantic.id]
555
+ if (!isPropertySemantic(sem)) {
556
+ throw new Error(`Invalid semantic type: ${semantic.id}. Expected a property semantic.`)
557
+ }
558
+ const index = this.semantics.findIndex((s) => s.id === semantic.id)
559
+ if (index >= 0) {
560
+ this.semantics[index] = semantic
561
+ } else {
562
+ this.semantics.push(semantic)
563
+ }
564
+ this.domain.notifyChange()
565
+ }
566
+
567
+ /**
568
+ * Removes a semantic from the property.
569
+ * @param semanticId The ID of the semantic to remove.
570
+ */
571
+ removeSemantic(semanticId: SemanticType): void {
572
+ const index = this.semantics.findIndex((s) => s.id === semanticId)
573
+ if (index >= 0) {
574
+ this.semantics.splice(index, 1)
575
+ this.domain.notifyChange()
576
+ }
577
+ }
578
+
579
+ /**
580
+ * Checks if the property has a specific semantic.
581
+ * @param semanticId The ID of the semantic to check.
582
+ * @returns True if the semantic is present, false otherwise.
583
+ */
584
+ hasSemantic(semanticId: SemanticType): boolean {
585
+ return this.semantics.some((s) => s.id === semanticId)
586
+ }
548
587
  }