@api-client/core 0.14.0 → 0.14.1
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.
- package/build/src/amf/AmfTypes.d.ts +1 -1
- package/build/src/amf/AmfTypes.js +1 -1
- package/build/src/amf/AmfTypes.js.map +1 -1
- package/build/src/amf/Utils.d.ts +0 -6
- package/build/src/amf/Utils.d.ts.map +1 -1
- package/build/src/amf/Utils.js +0 -14
- package/build/src/amf/Utils.js.map +1 -1
- package/build/src/browser.d.ts +1 -0
- package/build/src/browser.d.ts.map +1 -1
- package/build/src/browser.js +1 -0
- package/build/src/browser.js.map +1 -1
- package/build/src/index.d.ts +1 -0
- package/build/src/index.d.ts.map +1 -1
- package/build/src/index.js +1 -0
- package/build/src/index.js.map +1 -1
- package/build/src/legacy.d.ts +0 -8
- package/build/src/legacy.d.ts.map +1 -1
- package/build/src/legacy.js +0 -9
- package/build/src/legacy.js.map +1 -1
- package/build/src/modeling/Bindings.d.ts +1 -1
- package/build/src/modeling/Bindings.js.map +1 -1
- package/build/src/modeling/DataDomain.js +2 -2
- package/build/src/modeling/DataDomain.js.map +1 -1
- package/build/src/modeling/DataFormat.d.ts +0 -40
- package/build/src/modeling/DataFormat.d.ts.map +1 -1
- package/build/src/modeling/DataFormat.js +0 -27
- package/build/src/modeling/DataFormat.js.map +1 -1
- package/build/src/modeling/DomainAssociation.d.ts +28 -0
- package/build/src/modeling/DomainAssociation.d.ts.map +1 -1
- package/build/src/modeling/DomainAssociation.js +73 -4
- package/build/src/modeling/DomainAssociation.js.map +1 -1
- package/build/src/modeling/DomainEntity.d.ts +25 -9
- package/build/src/modeling/DomainEntity.d.ts.map +1 -1
- package/build/src/modeling/DomainEntity.js +65 -21
- package/build/src/modeling/DomainEntity.js.map +1 -1
- package/build/src/modeling/DomainFile.d.ts +1 -1
- package/build/src/modeling/DomainFile.js +1 -1
- package/build/src/modeling/DomainFile.js.map +1 -1
- package/build/src/modeling/DomainImpactAnalysis.d.ts +1 -1
- package/build/src/modeling/DomainImpactAnalysis.d.ts.map +1 -1
- package/build/src/modeling/DomainImpactAnalysis.js +3 -3
- package/build/src/modeling/DomainImpactAnalysis.js.map +1 -1
- package/build/src/modeling/DomainModel.d.ts +2 -2
- package/build/src/modeling/DomainModel.js +2 -2
- package/build/src/modeling/DomainModel.js.map +1 -1
- package/build/src/modeling/DomainProperty.d.ts +28 -12
- package/build/src/modeling/DomainProperty.d.ts.map +1 -1
- package/build/src/modeling/DomainProperty.js +61 -26
- package/build/src/modeling/DomainProperty.js.map +1 -1
- package/build/src/modeling/Semantics.d.ts +109 -0
- package/build/src/modeling/Semantics.d.ts.map +1 -0
- package/build/src/modeling/Semantics.js +97 -0
- package/build/src/modeling/Semantics.js.map +1 -0
- package/build/src/models/kinds.d.ts +0 -24
- package/build/src/models/kinds.d.ts.map +1 -1
- package/build/src/models/kinds.js +0 -24
- package/build/src/models/kinds.js.map +1 -1
- package/build/src/models/store/data_catalog.d.ts +1 -1
- package/build/src/models/store/data_catalog.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +11 -11
- package/package.json +1 -1
- package/src/amf/AmfTypes.ts +1 -1
- package/src/amf/Utils.ts +0 -15
- package/src/modeling/Bindings.ts +1 -1
- package/src/modeling/DataDomain.ts +2 -2
- package/src/modeling/DataFormat.ts +0 -48
- package/src/modeling/DomainAssociation.ts +66 -3
- package/src/modeling/DomainEntity.ts +56 -17
- package/src/modeling/DomainFile.ts +1 -1
- package/src/modeling/DomainImpactAnalysis.ts +3 -3
- package/src/modeling/DomainModel.ts +2 -2
- package/src/modeling/DomainProperty.ts +60 -21
- package/src/modeling/Semantics.ts +178 -0
- package/src/modeling/graph.md +14 -14
- package/src/modeling/readme.md +29 -29
- package/src/models/kinds.ts +0 -25
- package/src/models/store/data_catalog.ts +1 -1
- package/tests/unit/modeling/data_domain_change_observers.spec.ts +11 -10
- package/tests/unit/modeling/data_domain_entities.spec.ts +129 -1
- package/tests/unit/modeling/data_domain_property.spec.ts +1 -1
- package/tests/unit/modeling/domain_asociation.spec.ts +177 -0
- package/tests/unit/modeling/domain_entity.spec.ts +27 -26
- package/tests/unit/modeling/domain_entity_example_generator_json.spec.ts +11 -11
- package/tests/unit/modeling/domain_entity_example_generator_xml.spec.ts +10 -10
- package/tests/unit/modeling/{domain.property.spec.ts → domain_property.spec.ts} +139 -23
- package/build/src/amf/AmfShapeGenerator.d.ts +0 -103
- package/build/src/amf/AmfShapeGenerator.d.ts.map +0 -1
- package/build/src/amf/AmfShapeGenerator.js +0 -416
- package/build/src/amf/AmfShapeGenerator.js.map +0 -1
- package/build/src/modeling/legacy/DataAssociation.d.ts +0 -284
- package/build/src/modeling/legacy/DataAssociation.d.ts.map +0 -1
- package/build/src/modeling/legacy/DataAssociation.js +0 -443
- package/build/src/modeling/legacy/DataAssociation.js.map +0 -1
- package/build/src/modeling/legacy/DataEntity.d.ts +0 -358
- package/build/src/modeling/legacy/DataEntity.d.ts.map +0 -1
- package/build/src/modeling/legacy/DataEntity.js +0 -855
- package/build/src/modeling/legacy/DataEntity.js.map +0 -1
- package/build/src/modeling/legacy/DataEntityBuilder.d.ts +0 -162
- package/build/src/modeling/legacy/DataEntityBuilder.d.ts.map +0 -1
- package/build/src/modeling/legacy/DataEntityBuilder.js +0 -221
- package/build/src/modeling/legacy/DataEntityBuilder.js.map +0 -1
- package/build/src/modeling/legacy/DataImpactAnalysis.d.ts +0 -298
- package/build/src/modeling/legacy/DataImpactAnalysis.d.ts.map +0 -1
- package/build/src/modeling/legacy/DataImpactAnalysis.js +0 -441
- package/build/src/modeling/legacy/DataImpactAnalysis.js.map +0 -1
- package/build/src/modeling/legacy/DataModel.d.ts +0 -99
- package/build/src/modeling/legacy/DataModel.d.ts.map +0 -1
- package/build/src/modeling/legacy/DataModel.js +0 -237
- package/build/src/modeling/legacy/DataModel.js.map +0 -1
- package/build/src/modeling/legacy/DataNamespace.d.ts +0 -340
- package/build/src/modeling/legacy/DataNamespace.d.ts.map +0 -1
- package/build/src/modeling/legacy/DataNamespace.js +0 -784
- package/build/src/modeling/legacy/DataNamespace.js.map +0 -1
- package/build/src/modeling/legacy/DataProperty.d.ts +0 -332
- package/build/src/modeling/legacy/DataProperty.d.ts.map +0 -1
- package/build/src/modeling/legacy/DataProperty.js +0 -415
- package/build/src/modeling/legacy/DataProperty.js.map +0 -1
- package/build/src/models/store/DataFile.d.ts +0 -29
- package/build/src/models/store/DataFile.d.ts.map +0 -1
- package/build/src/models/store/DataFile.js +0 -87
- package/build/src/models/store/DataFile.js.map +0 -1
- package/src/amf/AmfShapeGenerator.ts +0 -477
- package/src/modeling/legacy/DataAssociation.ts +0 -554
- package/src/modeling/legacy/DataEntity.ts +0 -1019
- package/src/modeling/legacy/DataEntityBuilder.ts +0 -236
- package/src/modeling/legacy/DataImpactAnalysis.ts +0 -530
- package/src/modeling/legacy/DataModel.ts +0 -276
- package/src/modeling/legacy/DataNamespace.ts +0 -929
- package/src/modeling/legacy/DataProperty.ts +0 -630
- package/src/models/store/DataFile.ts +0 -95
- package/tests/unit/modeling/legacy/amf_shape_generator.spec.ts +0 -1041
- package/tests/unit/modeling/legacy/data_association.spec.ts +0 -710
- package/tests/unit/modeling/legacy/data_entity.spec.ts +0 -2061
- package/tests/unit/modeling/legacy/data_entity_generator_json.spec.ts +0 -987
- package/tests/unit/modeling/legacy/data_entity_generator_xml.spec.ts +0 -1451
- package/tests/unit/modeling/legacy/data_model.spec.ts +0 -395
- package/tests/unit/modeling/legacy/data_namespace.spec.ts +0 -1312
- package/tests/unit/modeling/legacy/data_property.spec.ts +0 -887
- package/tests/unit/modeling/legacy/impact_analysis.spec.ts +0 -373
|
@@ -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 {
|
|
24
|
-
import {
|
|
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
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
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
|
-
|
|
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,
|
|
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 `
|
|
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 =
|
|
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
|
-
*
|
|
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
|
|
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
|
-
|
|
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(
|
|
277
|
-
result.
|
|
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.
|
|
357
|
-
this.
|
|
355
|
+
if (Array.isArray(init.semantics)) {
|
|
356
|
+
this.semantics = [...init.semantics]
|
|
358
357
|
} else {
|
|
359
|
-
this.
|
|
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.
|
|
423
|
-
result.
|
|
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
|
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import type { DomainPropertyType } from './DataFormat.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Defines the names for all available data semantics.
|
|
5
|
+
* Using a string enum makes it easy to add or remove semantics in a single place.
|
|
6
|
+
*/
|
|
7
|
+
export enum SemanticType {
|
|
8
|
+
// Entity-Level Semantics
|
|
9
|
+
/**
|
|
10
|
+
* Designates a Data Entity that represents users of the system.
|
|
11
|
+
*/
|
|
12
|
+
User = 'https://apinow.app/semantics/entities/#User',
|
|
13
|
+
|
|
14
|
+
// Property-Level Semantics
|
|
15
|
+
CreatedTimestamp = 'https://apinow.app/semantics/properties/#CreatedTimestamp',
|
|
16
|
+
UpdatedTimestamp = 'https://apinow.app/semantics/properties/#UpdatedTimestamp',
|
|
17
|
+
DeletedTimestamp = 'https://apinow.app/semantics/properties/#DeletedTimestamp',
|
|
18
|
+
DeletedFlag = 'https://apinow.app/semantics/properties/#DeletedFlag',
|
|
19
|
+
PublicUniqueName = 'https://apinow.app/semantics/properties/#PublicUniqueName',
|
|
20
|
+
// Association-Level Semantics
|
|
21
|
+
ResourceOwnerIdentifier = 'https://apinow.app/semantics/associations/#ResourceOwnerIdentifier',
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Defines the scope at which a semantic can be applied.
|
|
26
|
+
*/
|
|
27
|
+
export enum SemanticScope {
|
|
28
|
+
Entity = 'Entity',
|
|
29
|
+
Property = 'Property',
|
|
30
|
+
Association = 'Association',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A base interface for all Data Semantics, containing common properties.
|
|
35
|
+
* A semantic is an annotation applied to a Data Entity, Property, or Association
|
|
36
|
+
* to provide additional context or constraints.
|
|
37
|
+
* This interface is extended by more specific semantic types.
|
|
38
|
+
*/
|
|
39
|
+
interface BaseDataSemantic {
|
|
40
|
+
/**
|
|
41
|
+
* A unique identifier for the semantic definition.
|
|
42
|
+
*/
|
|
43
|
+
id: SemanticType
|
|
44
|
+
/**
|
|
45
|
+
* A human-readable name for the semantic.
|
|
46
|
+
*/
|
|
47
|
+
displayName: string
|
|
48
|
+
/**
|
|
49
|
+
* A description of the semantic's purpose and impact.
|
|
50
|
+
*/
|
|
51
|
+
description: string
|
|
52
|
+
/**
|
|
53
|
+
* Specifies whether the semantic applies to an Entity, Property, or Association.
|
|
54
|
+
*/
|
|
55
|
+
scope: SemanticScope
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Represents a semantic that can be applied to an entire Data Entity.
|
|
60
|
+
*/
|
|
61
|
+
export interface EntitySemantic extends BaseDataSemantic {
|
|
62
|
+
scope: SemanticScope.Entity
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Represents a semantic that can be applied to a single property.
|
|
67
|
+
*/
|
|
68
|
+
export interface PropertySemantic extends BaseDataSemantic {
|
|
69
|
+
scope: SemanticScope.Property
|
|
70
|
+
/**
|
|
71
|
+
* Optional array of data types this semantic can be applied to.
|
|
72
|
+
* Enforces constraints, e.g., DeletedTimestamp on a DateTime property.
|
|
73
|
+
*/
|
|
74
|
+
applicableDataTypes?: DomainPropertyType[]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Represents a semantic that can be applied to an association between entities.
|
|
79
|
+
*/
|
|
80
|
+
export interface AssociationSemantic extends BaseDataSemantic {
|
|
81
|
+
scope: SemanticScope.Association
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* A type guard to check if a semantic is an EntitySemantic.
|
|
86
|
+
*/
|
|
87
|
+
export const isEntitySemantic = (semantic: DataSemantic): semantic is EntitySemantic =>
|
|
88
|
+
semantic.scope === SemanticScope.Entity
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* A type guard to check if a semantic is a PropertySemantic.
|
|
92
|
+
*/
|
|
93
|
+
export const isPropertySemantic = (semantic: DataSemantic): semantic is PropertySemantic =>
|
|
94
|
+
semantic.scope === SemanticScope.Property
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* A type guard to check if a semantic is a AssociationSemantic.
|
|
98
|
+
*/
|
|
99
|
+
export const isAssociationSemantic = (semantic: DataSemantic): semantic is AssociationSemantic =>
|
|
100
|
+
semantic.scope === SemanticScope.Association
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Union type for any kind of data semantic
|
|
104
|
+
*/
|
|
105
|
+
export type DataSemantic = EntitySemantic | PropertySemantic | AssociationSemantic
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* A map to store the definitions of all available data semantics.
|
|
109
|
+
* This acts as a central registry for the application.
|
|
110
|
+
*/
|
|
111
|
+
export const DataSemantics: Record<SemanticType, DataSemantic> = {
|
|
112
|
+
// Entity-Level Definitions
|
|
113
|
+
[SemanticType.User]: {
|
|
114
|
+
id: SemanticType.User,
|
|
115
|
+
displayName: 'User Entity',
|
|
116
|
+
scope: SemanticScope.Entity,
|
|
117
|
+
description: 'Designates an entity that represents system users, crucial for authentication and authorization.',
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
// Property-Level Definitions
|
|
121
|
+
[SemanticType.CreatedTimestamp]: {
|
|
122
|
+
id: SemanticType.CreatedTimestamp,
|
|
123
|
+
displayName: 'Creation Timestamp',
|
|
124
|
+
scope: SemanticScope.Property,
|
|
125
|
+
description: "Marks a field as the one that contains the object's creation timestamp.",
|
|
126
|
+
applicableDataTypes: ['datetime'],
|
|
127
|
+
},
|
|
128
|
+
[SemanticType.UpdatedTimestamp]: {
|
|
129
|
+
id: SemanticType.UpdatedTimestamp,
|
|
130
|
+
displayName: 'Update Timestamp',
|
|
131
|
+
scope: SemanticScope.Property,
|
|
132
|
+
description: "Marks a field as the field that contains object's last modification timestamp.",
|
|
133
|
+
applicableDataTypes: ['datetime'],
|
|
134
|
+
},
|
|
135
|
+
[SemanticType.DeletedTimestamp]: {
|
|
136
|
+
id: SemanticType.DeletedTimestamp,
|
|
137
|
+
displayName: 'Soft Delete Timestamp',
|
|
138
|
+
scope: SemanticScope.Property,
|
|
139
|
+
description: "Marks a field as the field that contains object's deletion timestamp.",
|
|
140
|
+
applicableDataTypes: ['datetime'],
|
|
141
|
+
},
|
|
142
|
+
[SemanticType.DeletedFlag]: {
|
|
143
|
+
id: SemanticType.DeletedFlag,
|
|
144
|
+
displayName: 'Soft Delete Flag',
|
|
145
|
+
scope: SemanticScope.Property,
|
|
146
|
+
description: 'A boolean property that marks the object as deleted without physically removing it.',
|
|
147
|
+
applicableDataTypes: ['boolean'],
|
|
148
|
+
},
|
|
149
|
+
[SemanticType.ResourceOwnerIdentifier]: {
|
|
150
|
+
id: SemanticType.ResourceOwnerIdentifier,
|
|
151
|
+
displayName: 'Resource Owner Identifier',
|
|
152
|
+
scope: SemanticScope.Association,
|
|
153
|
+
description: 'Links a resource to a "User" entity instance, indicating ownership for access control.',
|
|
154
|
+
},
|
|
155
|
+
[SemanticType.PublicUniqueName]: {
|
|
156
|
+
id: SemanticType.PublicUniqueName,
|
|
157
|
+
displayName: 'Public Unique Name (Slug)',
|
|
158
|
+
scope: SemanticScope.Property,
|
|
159
|
+
description: 'A user-friendly, unique public identifier for a resource, often used in URLs.',
|
|
160
|
+
applicableDataTypes: ['string'],
|
|
161
|
+
},
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Represents the application of a data semantic to a specific
|
|
166
|
+
* entity or property within a user's data model.
|
|
167
|
+
*/
|
|
168
|
+
export interface AppliedDataSemantic {
|
|
169
|
+
/**
|
|
170
|
+
* The unique identifier of the semantic being applied.
|
|
171
|
+
*/
|
|
172
|
+
id: SemanticType
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Optional configuration or values specific to this application.
|
|
176
|
+
*/
|
|
177
|
+
config?: Record<string, unknown>
|
|
178
|
+
}
|
package/src/modeling/graph.md
CHANGED
|
@@ -4,20 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
```plain
|
|
6
6
|
DataDomain (Root container)
|
|
7
|
-
├──
|
|
8
|
-
│ └──
|
|
9
|
-
│ └──
|
|
7
|
+
├── DomainNamespace (logical grouping)
|
|
8
|
+
│ └── DomainModel
|
|
9
|
+
│ └── DomainEntity
|
|
10
10
|
│ ├── Property (name, type, ...)
|
|
11
11
|
│ ├── Association (name, cardinality, target Entity)
|
|
12
|
-
│ └── ParentEntity (reference to another
|
|
13
|
-
├──
|
|
14
|
-
│ └──
|
|
12
|
+
│ └── ParentEntity (reference to another DomainEntity)
|
|
13
|
+
├── DomainModel
|
|
14
|
+
│ └── DomainEntity
|
|
15
15
|
│ ├── Property
|
|
16
16
|
│ ├── Association
|
|
17
17
|
│ └── ParentEntity
|
|
18
|
-
└──
|
|
19
|
-
└──
|
|
20
|
-
└──
|
|
18
|
+
└── ForeignDomainNamespace (immutable, imported from another DataDomain)
|
|
19
|
+
└── DomainModel
|
|
20
|
+
└── DomainEntity
|
|
21
21
|
├── Property
|
|
22
22
|
├── Association
|
|
23
23
|
└── ParentEntity
|
|
@@ -31,11 +31,11 @@ Here's a breakdown of how each element is represented in the graph:
|
|
|
31
31
|
|
|
32
32
|
**Nodes:**
|
|
33
33
|
|
|
34
|
-
* **Namespace:** Represents a `
|
|
35
|
-
* **Model:** Represents a `
|
|
36
|
-
* **Entity:** Represents a `
|
|
37
|
-
* **Property:** Represents a `
|
|
38
|
-
* **Association:** Represents a `
|
|
34
|
+
* **Namespace:** Represents a `DomainNamespace`. It's a container for models and other namespaces.
|
|
35
|
+
* **Model:** Represents a `DomainModel`. It's a container for entities.
|
|
36
|
+
* **Entity:** Represents a `DomainEntity`. It's the fundamental building block, defining a specific type of data.
|
|
37
|
+
* **Property:** Represents a `DomainProperty`. It's an attribute of an entity.
|
|
38
|
+
* **Association:** Represents a `DomainAssociation`. It defines a relationship between entities.
|
|
39
39
|
|
|
40
40
|
**Edges:**
|
|
41
41
|
|
package/src/modeling/readme.md
CHANGED
|
@@ -4,53 +4,53 @@
|
|
|
4
4
|
|
|
5
5
|
At the heart of this data modeling system are the following fundamental concepts.
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### DomainNamespace
|
|
8
8
|
|
|
9
9
|
This is the top-level container, representing a logical grouping of data. Think of it as a "domain" or a "schema" in a database. It can contain:
|
|
10
10
|
|
|
11
|
-
- `
|
|
11
|
+
- `DomainModels`: Logical groupings of entities.
|
|
12
12
|
- `DataEntities`: The basic building blocks, representing individual data structures.
|
|
13
13
|
- `DataProperties`: Attributes of entities (e.g., name, age, address).
|
|
14
|
-
- `
|
|
14
|
+
- `DomainAssociations`: Relationships between entities (e.g., a user has an address).
|
|
15
15
|
- `Sub-namespaces`: Namespaces can be nested within each other, creating a hierarchical structure.
|
|
16
16
|
- `Foreign Namespaces`: References to external namespaces, enabling the use of entities defined elsewhere.
|
|
17
17
|
- `Tags`: Common tags for the entire namespace.
|
|
18
18
|
|
|
19
|
-
###
|
|
19
|
+
### DomainModel
|
|
20
20
|
|
|
21
|
-
A logical grouping of `
|
|
21
|
+
A logical grouping of `DomainEntity` instances. It represents a specific data structure, like a "Product" or "User" model. A `DomainModel` can contain multiple `DomainEntity` instances.
|
|
22
22
|
|
|
23
|
-
###
|
|
23
|
+
### DomainEntity
|
|
24
24
|
|
|
25
25
|
The fundamental building block of the data model. It represents a specific type of data, like a "User," "Product," or "Address."
|
|
26
26
|
|
|
27
|
-
- `Properties`:
|
|
28
|
-
- `Associations`:
|
|
27
|
+
- `Properties`: DomainProperty instances that describe the attributes of the entity.
|
|
28
|
+
- `Associations`: DomainAssociation instances that define relationships to other entities.
|
|
29
29
|
- `Parents`: An entity can inherit from other entities, creating a hierarchy.
|
|
30
30
|
- `Fields`: Ordered list of properties and associations.
|
|
31
31
|
- `Tags`: Optional tags for the UI.
|
|
32
|
-
- `
|
|
32
|
+
- `Semantics`: A system of predefined, meaningful labels or classifications that can be applied to Data Entities or their individual properties.
|
|
33
33
|
- `Deprecated`: Whether the entity is deprecated.
|
|
34
34
|
- `Schema`: The schema allowing to translate the model into a specific format (like JSON, RAML, XML, etc.)
|
|
35
35
|
|
|
36
|
-
###
|
|
36
|
+
### DomainProperty
|
|
37
37
|
|
|
38
|
-
Represents an attribute of a `
|
|
38
|
+
Represents an attribute of a `DomainEntity`. It has a name, a data type (e.g., string, number, boolean), and optional constraints (e.g., required, multiple, min/max values).
|
|
39
39
|
|
|
40
40
|
- `Type`: The data type of the property.
|
|
41
41
|
- `Schema`: The general schema definition of this property.
|
|
42
42
|
- `Bindings`: The list of bindings for this property.
|
|
43
43
|
- `Tags`: Optional tags for the UI.
|
|
44
|
-
- `
|
|
44
|
+
- `Semantics`: A system of predefined, meaningful labels or classifications that can be applied to Data Entities or their individual properties.
|
|
45
45
|
- `Deprecated`: Whether the property is deprecated.
|
|
46
46
|
- `Primary`: Whether this property describes a primary key of the entity.
|
|
47
47
|
- `Index`: Whether this property describes an indexed property of the entity.
|
|
48
48
|
- `ReadOnly`: Whether the property is read only in the schema.
|
|
49
49
|
- `WriteOnly`: Whether the property is write only in the schema.
|
|
50
50
|
|
|
51
|
-
###
|
|
51
|
+
### DomainAssociation
|
|
52
52
|
|
|
53
|
-
Defines a relationship between `
|
|
53
|
+
Defines a relationship between `DomainEntity` instances. It specifies the target entities and the nature of the relationship (e.g., one-to-one, one-to-many).
|
|
54
54
|
|
|
55
55
|
- `Targets`: The list of target entities.
|
|
56
56
|
- `Multiple`: Whether the association allows multiple target entities.
|
|
@@ -67,24 +67,24 @@ Defines a translation from a data model to a specific format (like JSON, RAML, X
|
|
|
67
67
|
|
|
68
68
|
Here's how these components work together to structure a data domain:
|
|
69
69
|
|
|
70
|
-
1. **Root Namespace**: You start with a `
|
|
70
|
+
1. **Root Namespace**: You start with a `DomainNamespace`, which acts as the root of your data domain. This namespace is the top-level container for all other elements.
|
|
71
71
|
|
|
72
72
|
1. **Sub-namespaces (Optional)**: You can create sub-namespaces within the root namespace to further organize your data. This is useful for large domains with many entities and relationships.
|
|
73
73
|
|
|
74
|
-
1. **Data Models**: Within a namespace (or sub-namespace), you define `
|
|
74
|
+
1. **Data Models**: Within a namespace (or sub-namespace), you define `DomainModel` instances. Each `DomainModel` represents a specific area of your domain. For example, you might have a "User Management" `DomainModel`, a "Product Catalog" `DomainModel`, and an "Order Processing" `DomainModel`.
|
|
75
75
|
|
|
76
|
-
1. **Data Entities**: Inside each `
|
|
76
|
+
1. **Data Entities**: Inside each `DomainModel`, you define `DomainEntity` instances. These are the core data structures. For example, in the "User Management" `DomainModel`, you might have `DomainEntity` instances for "User," "Role," and "Permission."
|
|
77
77
|
|
|
78
|
-
1. **Data Properties**: Each `
|
|
78
|
+
1. **Data Properties**: Each `DomainEntity` has `DomainProperty` instances that describe its attributes. For example, the "User" `DomainEntity` might have `DomainProperty` instances for "firstName" (string), "lastName" (string), "email" (string), "age" (number), etc.
|
|
79
79
|
|
|
80
|
-
1. **Data Associations**: You use `
|
|
80
|
+
1. **Data Associations**: You use `DomainAssociation` instances to define relationships between `DomainEntity` instances. For example:
|
|
81
81
|
|
|
82
82
|
- A "User" has an "Address" (one-to-one).
|
|
83
83
|
- A "User" has multiple "Roles" (one-to-many).
|
|
84
84
|
- A "Product" belongs to a "Category" (many-to-one).
|
|
85
85
|
- An "Order" contains multiple "Order Items" (one-to-many).
|
|
86
86
|
|
|
87
|
-
1. **Inheritance**: `
|
|
87
|
+
1. **Inheritance**: `DomainEntity` instances can inherit from other `DomainEntity` instances using the parents property. This allows you to create a hierarchy of entities and reuse common properties and associations.
|
|
88
88
|
|
|
89
89
|
1. **Foreign Namespaces**: You can reference entities from other namespaces using the foreign property of the root namespace. This allows you to reuse data structures defined elsewhere.
|
|
90
90
|
|
|
@@ -109,18 +109,18 @@ Let's imagine a simple e-commerce domain:
|
|
|
109
109
|
- **Data Association**: `address` (references `Address` entity)
|
|
110
110
|
- **Data Entity**: `Address`
|
|
111
111
|
- **Data Properties**: `street` (string), `city` (string), `zipCode` (string), `country` (string)
|
|
112
|
-
- **Foreign Namespace**: `
|
|
113
|
-
- **Data Model**: `
|
|
114
|
-
- **Data Entity**: `
|
|
112
|
+
- **Foreign Namespace**: `Semantics` (defined elsewhere)
|
|
113
|
+
- **Data Model**: `Semantics`
|
|
114
|
+
- **Data Entity**: `SemanticsItem`
|
|
115
115
|
|
|
116
116
|
### Key Relationships
|
|
117
117
|
|
|
118
|
-
- **Namespace-Model**: A `
|
|
119
|
-
- **Model-Entity**: A `
|
|
120
|
-
- **Entity-Property**: A `
|
|
121
|
-
- **Entity-Association**: A `
|
|
122
|
-
- **Entity-Parent**: A `
|
|
123
|
-
- **Namespace-Foreign**: A `
|
|
118
|
+
- **Namespace-Model**: A `DomainNamespace` contains `DomainModel` instances.
|
|
119
|
+
- **Model-Entity**: A `DomainModel` contains `DomainEntity` instances.
|
|
120
|
+
- **Entity-Property**: A `DomainEntity` has `DomainProperty` instances.
|
|
121
|
+
- **Entity-Association**: A `DomainEntity` has `DomainAssociation` instances.
|
|
122
|
+
- **Entity-Parent**: A `DomainEntity` can have `DomainEntity` instances as parents.
|
|
123
|
+
- **Namespace-Foreign**: A `DomainNamespace` can have references to `DomainNamespace` instances.
|
|
124
124
|
|
|
125
125
|
## Summary
|
|
126
126
|
|
package/src/models/kinds.ts
CHANGED
|
@@ -20,28 +20,3 @@ export const DataCatalogKind = 'Core#DataCatalog'
|
|
|
20
20
|
export const DataCatalogVersionKind = 'Core#DataCatalogVersion'
|
|
21
21
|
export const OrganizationKind = 'Core#Organization'
|
|
22
22
|
export const InvitationKind = 'Core#Invitation'
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @deprecated Not used anymore.
|
|
26
|
-
*/
|
|
27
|
-
export const DataFileKind = 'Core#DataFile'
|
|
28
|
-
/**
|
|
29
|
-
* @deprecated Not used anymore.
|
|
30
|
-
*/
|
|
31
|
-
export const DataNamespaceKind = 'Data#DataNamespace'
|
|
32
|
-
/**
|
|
33
|
-
* @deprecated Not used anymore.
|
|
34
|
-
*/
|
|
35
|
-
export const DataModelKind = 'Data#DataModel'
|
|
36
|
-
/**
|
|
37
|
-
* @deprecated Not used anymore.
|
|
38
|
-
*/
|
|
39
|
-
export const DataEntityKind = 'Data#DataEntity'
|
|
40
|
-
/**
|
|
41
|
-
* @deprecated Not used anymore.
|
|
42
|
-
*/
|
|
43
|
-
export const DataAssociationKind = 'Data#DataAssociation'
|
|
44
|
-
/**
|
|
45
|
-
* @deprecated Not used anymore.
|
|
46
|
-
*/
|
|
47
|
-
export const DataPropertyKind = 'Data#DataProperty'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { test } from '@japa/runner'
|
|
2
2
|
import { DataDomain, DataFormat } from '../../../src/index.js'
|
|
3
|
+
import { SemanticType } from '../../../src/modeling/Semantics.js'
|
|
3
4
|
|
|
4
5
|
test.group('DataDomain change observers', () => {
|
|
5
6
|
test('does not notifies a change when initializing a domain', async ({ assert }) => {
|
|
@@ -276,24 +277,24 @@ test.group('DomainEntity change observers', () => {
|
|
|
276
277
|
await assert.dispatchCount(domain, 'change', 1, { timeout: 1 })
|
|
277
278
|
})
|
|
278
279
|
|
|
279
|
-
test('notifies a change when adding a
|
|
280
|
+
test('notifies a change when adding a semantics', async ({ assert, sleep }) => {
|
|
280
281
|
const domain = new DataDomain()
|
|
281
282
|
const n1 = domain.addNamespace()
|
|
282
283
|
const m1 = n1.addModel()
|
|
283
284
|
const e1 = m1.addEntity()
|
|
284
285
|
await sleep(1)
|
|
285
|
-
e1.
|
|
286
|
+
e1.semantics.push({ id: SemanticType.User })
|
|
286
287
|
await assert.dispatchCount(domain, 'change', 1, { timeout: 1 })
|
|
287
288
|
})
|
|
288
289
|
|
|
289
|
-
test('notifies a change when removing a
|
|
290
|
+
test('notifies a change when removing a semantics', async ({ assert, sleep }) => {
|
|
290
291
|
const domain = new DataDomain()
|
|
291
292
|
const n1 = domain.addNamespace()
|
|
292
293
|
const m1 = n1.addModel()
|
|
293
294
|
const e1 = m1.addEntity()
|
|
294
|
-
e1.
|
|
295
|
+
e1.semantics.push({ id: SemanticType.User })
|
|
295
296
|
await sleep(1)
|
|
296
|
-
e1.
|
|
297
|
+
e1.semantics.pop()
|
|
297
298
|
await assert.dispatchCount(domain, 'change', 1, { timeout: 1 })
|
|
298
299
|
})
|
|
299
300
|
|
|
@@ -508,26 +509,26 @@ test.group('DomainProperty change observers', () => {
|
|
|
508
509
|
await assert.dispatchCount(domain, 'change', 1, { timeout: 1 })
|
|
509
510
|
})
|
|
510
511
|
|
|
511
|
-
test('notifies a change when adding a
|
|
512
|
+
test('notifies a change when adding a semantics', async ({ assert, sleep }) => {
|
|
512
513
|
const domain = new DataDomain()
|
|
513
514
|
const n1 = domain.addNamespace()
|
|
514
515
|
const m1 = n1.addModel()
|
|
515
516
|
const e1 = m1.addEntity()
|
|
516
517
|
const p1 = e1.addProperty()
|
|
517
518
|
await sleep(1)
|
|
518
|
-
p1.
|
|
519
|
+
p1.semantics.push({ id: SemanticType.CreatedTimestamp })
|
|
519
520
|
await assert.dispatchCount(domain, 'change', 1, { timeout: 1 })
|
|
520
521
|
})
|
|
521
522
|
|
|
522
|
-
test('notifies a change when removing a
|
|
523
|
+
test('notifies a change when removing a semantics', async ({ assert, sleep }) => {
|
|
523
524
|
const domain = new DataDomain()
|
|
524
525
|
const n1 = domain.addNamespace()
|
|
525
526
|
const m1 = n1.addModel()
|
|
526
527
|
const e1 = m1.addEntity()
|
|
527
528
|
const p1 = e1.addProperty()
|
|
528
|
-
p1.
|
|
529
|
+
p1.semantics.push({ id: SemanticType.CreatedTimestamp })
|
|
529
530
|
await sleep(1)
|
|
530
|
-
p1.
|
|
531
|
+
p1.semantics.pop()
|
|
531
532
|
await assert.dispatchCount(domain, 'change', 1, { timeout: 1 })
|
|
532
533
|
})
|
|
533
534
|
|