@api-client/core 0.18.23 → 0.18.25
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/modeling/DomainEntity.d.ts +6 -1
- package/build/src/modeling/DomainEntity.d.ts.map +1 -1
- package/build/src/modeling/DomainEntity.js +24 -5
- package/build/src/modeling/DomainEntity.js.map +1 -1
- package/build/src/modeling/Semantics.d.ts +68 -0
- package/build/src/modeling/Semantics.d.ts.map +1 -1
- package/build/src/modeling/Semantics.js +217 -0
- package/build/src/modeling/Semantics.js.map +1 -1
- package/build/src/modeling/definitions/Email.d.ts +0 -4
- package/build/src/modeling/definitions/Email.d.ts.map +1 -1
- package/build/src/modeling/definitions/Email.js +1 -2
- package/build/src/modeling/definitions/Email.js.map +1 -1
- package/build/src/modeling/definitions/Password.d.ts.map +1 -1
- package/build/src/modeling/definitions/Password.js +1 -3
- package/build/src/modeling/definitions/Password.js.map +1 -1
- package/build/src/modeling/helpers/Intelisense.d.ts.map +1 -1
- package/build/src/modeling/helpers/Intelisense.js +24 -58
- package/build/src/modeling/helpers/Intelisense.js.map +1 -1
- package/build/src/modeling/helpers/database.js +2 -2
- package/build/src/modeling/helpers/database.js.map +1 -1
- package/build/src/modeling/templates/verticals/business-services/ecommerce-domain.js +3 -3
- package/build/src/modeling/templates/verticals/business-services/ecommerce-domain.js.map +1 -1
- package/build/src/modeling/templates/verticals/technology-media/blog-domain.js +5 -5
- package/build/src/modeling/templates/verticals/technology-media/blog-domain.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +20 -20
- package/package.json +1 -1
- package/src/modeling/DomainEntity.ts +27 -5
- package/src/modeling/Semantics.ts +254 -0
- package/src/modeling/definitions/Email.ts +1 -6
- package/src/modeling/definitions/Password.ts +1 -3
- package/src/modeling/helpers/Intelisense.ts +26 -58
- package/src/modeling/helpers/database.ts +2 -2
- package/src/modeling/templates/verticals/business-services/ecommerce-domain.ts +3 -3
- package/src/modeling/templates/verticals/technology-media/blog-domain.ts +5 -5
- package/tests/unit/modeling/definitions/email.spec.ts +0 -1
- package/tests/unit/modeling/definitions/password.spec.ts +0 -2
- package/tests/unit/modeling/domain_entity_parents.spec.ts +243 -0
- package/tests/unit/modeling/semantic-configs.spec.ts +0 -1
- package/tests/unit/modeling/semantic_runtime.spec.ts +113 -0
- package/tests/unit/modeling/semantics.spec.ts +68 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import {
|
|
3
|
+
SemanticType,
|
|
4
|
+
SemanticTiming,
|
|
5
|
+
SemanticOperation,
|
|
6
|
+
getSemanticsForOperation,
|
|
7
|
+
canSemanticBeDisabled,
|
|
8
|
+
type AppliedDataSemantic,
|
|
9
|
+
} from '../../../src/modeling/Semantics.js'
|
|
10
|
+
|
|
11
|
+
test.group('Semantic Runtime Control', () => {
|
|
12
|
+
test('getSemanticsForOperation should filter semantics by operation and timing', ({ assert }) => {
|
|
13
|
+
const semantics: AppliedDataSemantic[] = [
|
|
14
|
+
{ id: SemanticType.Password },
|
|
15
|
+
{ id: SemanticType.CreatedTimestamp },
|
|
16
|
+
{ id: SemanticType.UpdatedTimestamp },
|
|
17
|
+
{ id: SemanticType.Status },
|
|
18
|
+
{ id: SemanticType.Title },
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
// Test CREATE operation with BEFORE timing
|
|
22
|
+
const createBeforeSemantics = getSemanticsForOperation(semantics, SemanticOperation.Create, SemanticTiming.Before)
|
|
23
|
+
const createBeforeTypes = createBeforeSemantics.map((s) => s.id)
|
|
24
|
+
|
|
25
|
+
assert.includeMembers(createBeforeTypes, [SemanticType.Password, SemanticType.CreatedTimestamp])
|
|
26
|
+
assert.notInclude(createBeforeTypes, SemanticType.UpdatedTimestamp) // Only runs on UPDATE
|
|
27
|
+
assert.notInclude(createBeforeTypes, SemanticType.Title) // No runtime operations
|
|
28
|
+
|
|
29
|
+
// Test UPDATE operation with BEFORE timing
|
|
30
|
+
const updateBeforeSemantics = getSemanticsForOperation(semantics, SemanticOperation.Update, SemanticTiming.Before)
|
|
31
|
+
const updateBeforeTypes = updateBeforeSemantics.map((s) => s.id)
|
|
32
|
+
|
|
33
|
+
assert.includeMembers(updateBeforeTypes, [SemanticType.Password, SemanticType.UpdatedTimestamp])
|
|
34
|
+
assert.notInclude(updateBeforeTypes, SemanticType.CreatedTimestamp) // Only runs on CREATE
|
|
35
|
+
|
|
36
|
+
// Test Status semantic runs on both CREATE and UPDATE
|
|
37
|
+
assert.include(createBeforeTypes, SemanticType.Status)
|
|
38
|
+
assert.include(updateBeforeTypes, SemanticType.Status)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('getSemanticsForOperation should sort semantics by priority', ({ assert }) => {
|
|
42
|
+
const semantics: AppliedDataSemantic[] = [
|
|
43
|
+
{ id: SemanticType.Password }, // priority: 10
|
|
44
|
+
{ id: SemanticType.ResourceOwnerIdentifier }, // priority: 5
|
|
45
|
+
{ id: SemanticType.UserRole }, // priority: 20
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
const createSemantics = getSemanticsForOperation(semantics, SemanticOperation.Create, SemanticTiming.Before)
|
|
49
|
+
|
|
50
|
+
// Should be sorted by priority: ResourceOwnerIdentifier (5), Password (10), UserRole (20)
|
|
51
|
+
assert.equal(createSemantics[0].id, SemanticType.ResourceOwnerIdentifier)
|
|
52
|
+
assert.equal(createSemantics[1].id, SemanticType.Password)
|
|
53
|
+
assert.equal(createSemantics[2].id, SemanticType.UserRole)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test('getSemanticsForOperation should handle BOTH timing correctly', ({ assert }) => {
|
|
57
|
+
const semantics: AppliedDataSemantic[] = [
|
|
58
|
+
{ id: SemanticType.Status }, // timing: Both
|
|
59
|
+
{ id: SemanticType.Password }, // timing: Before
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
const beforeSemantics = getSemanticsForOperation(semantics, SemanticOperation.Create, SemanticTiming.Before)
|
|
63
|
+
const afterSemantics = getSemanticsForOperation(semantics, SemanticOperation.Create, SemanticTiming.After)
|
|
64
|
+
|
|
65
|
+
// Status should appear in both BEFORE and AFTER
|
|
66
|
+
assert.equal(beforeSemantics.length, 2) // Status and Password
|
|
67
|
+
assert.equal(afterSemantics.length, 1) // Only Status
|
|
68
|
+
assert.equal(afterSemantics[0].id, SemanticType.Status)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('canSemanticBeDisabled should check if semantic can be disabled', ({ assert }) => {
|
|
72
|
+
// Security semantics cannot be disabled
|
|
73
|
+
assert.isFalse(canSemanticBeDisabled(SemanticType.Password))
|
|
74
|
+
assert.isFalse(canSemanticBeDisabled(SemanticType.ResourceOwnerIdentifier))
|
|
75
|
+
|
|
76
|
+
// Other semantics can be disabled (default)
|
|
77
|
+
assert.isTrue(canSemanticBeDisabled(SemanticType.CreatedTimestamp))
|
|
78
|
+
assert.isTrue(canSemanticBeDisabled(SemanticType.Email))
|
|
79
|
+
assert.isTrue(canSemanticBeDisabled(SemanticType.Status))
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test('getSemanticsForOperation should return empty array for semantics with no runtime', ({ assert }) => {
|
|
83
|
+
const semantics: AppliedDataSemantic[] = [
|
|
84
|
+
{ id: SemanticType.Title }, // No runtime operations
|
|
85
|
+
{ id: SemanticType.Description }, // No runtime operations
|
|
86
|
+
{ id: SemanticType.User }, // No runtime operations
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
const result = getSemanticsForOperation(semantics, SemanticOperation.Create, SemanticTiming.Before)
|
|
90
|
+
assert.lengthOf(result, 0)
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
test('getSemanticsForOperation should filter by specific operations', ({ assert }) => {
|
|
94
|
+
const semantics: AppliedDataSemantic[] = [
|
|
95
|
+
{ id: SemanticType.CreatedTimestamp }, // Only CREATE
|
|
96
|
+
{ id: SemanticType.UpdatedTimestamp }, // Only UPDATE
|
|
97
|
+
{ id: SemanticType.DeletedTimestamp }, // Only DELETE
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
const createSemantics = getSemanticsForOperation(semantics, SemanticOperation.Create, SemanticTiming.Before)
|
|
101
|
+
const updateSemantics = getSemanticsForOperation(semantics, SemanticOperation.Update, SemanticTiming.Before)
|
|
102
|
+
const deleteSemantics = getSemanticsForOperation(semantics, SemanticOperation.Delete, SemanticTiming.Before)
|
|
103
|
+
|
|
104
|
+
assert.lengthOf(createSemantics, 1)
|
|
105
|
+
assert.equal(createSemantics[0].id, SemanticType.CreatedTimestamp)
|
|
106
|
+
|
|
107
|
+
assert.lengthOf(updateSemantics, 1)
|
|
108
|
+
assert.equal(updateSemantics[0].id, SemanticType.UpdatedTimestamp)
|
|
109
|
+
|
|
110
|
+
assert.lengthOf(deleteSemantics, 1)
|
|
111
|
+
assert.equal(deleteSemantics[0].id, SemanticType.DeletedTimestamp)
|
|
112
|
+
})
|
|
113
|
+
})
|
|
@@ -3,6 +3,8 @@ import {
|
|
|
3
3
|
SemanticType,
|
|
4
4
|
SemanticScope,
|
|
5
5
|
SemanticCategory,
|
|
6
|
+
SemanticTiming,
|
|
7
|
+
SemanticOperation,
|
|
6
8
|
isEntitySemantic,
|
|
7
9
|
isPropertySemantic,
|
|
8
10
|
isAssociationSemantic,
|
|
@@ -50,6 +52,10 @@ test.group('Semantics', () => {
|
|
|
50
52
|
scope: SemanticScope.Entity,
|
|
51
53
|
category: SemanticCategory.Identity,
|
|
52
54
|
hasConfig: false,
|
|
55
|
+
runtime: {
|
|
56
|
+
timing: SemanticTiming.None,
|
|
57
|
+
operations: [],
|
|
58
|
+
},
|
|
53
59
|
}
|
|
54
60
|
const propertySemantic: PropertySemantic = {
|
|
55
61
|
id: SemanticType.CreatedTimestamp,
|
|
@@ -58,6 +64,12 @@ test.group('Semantics', () => {
|
|
|
58
64
|
scope: SemanticScope.Property,
|
|
59
65
|
category: SemanticCategory.Lifecycle,
|
|
60
66
|
hasConfig: false,
|
|
67
|
+
applicableDataTypes: ['datetime'],
|
|
68
|
+
runtime: {
|
|
69
|
+
timing: SemanticTiming.Before,
|
|
70
|
+
operations: [SemanticOperation.Create],
|
|
71
|
+
priority: 90,
|
|
72
|
+
},
|
|
61
73
|
}
|
|
62
74
|
const associationSemantic: AssociationSemantic = {
|
|
63
75
|
id: SemanticType.ResourceOwnerIdentifier,
|
|
@@ -66,6 +78,18 @@ test.group('Semantics', () => {
|
|
|
66
78
|
scope: SemanticScope.Association,
|
|
67
79
|
category: SemanticCategory.Identity,
|
|
68
80
|
hasConfig: false,
|
|
81
|
+
runtime: {
|
|
82
|
+
timing: SemanticTiming.Before,
|
|
83
|
+
operations: [
|
|
84
|
+
SemanticOperation.Create,
|
|
85
|
+
SemanticOperation.Read,
|
|
86
|
+
SemanticOperation.Update,
|
|
87
|
+
SemanticOperation.Delete,
|
|
88
|
+
SemanticOperation.List,
|
|
89
|
+
],
|
|
90
|
+
priority: 5,
|
|
91
|
+
canDisable: false,
|
|
92
|
+
},
|
|
69
93
|
}
|
|
70
94
|
|
|
71
95
|
assert.isTrue(isEntitySemantic(entitySemantic))
|
|
@@ -81,6 +105,10 @@ test.group('Semantics', () => {
|
|
|
81
105
|
scope: SemanticScope.Entity,
|
|
82
106
|
category: SemanticCategory.Identity,
|
|
83
107
|
hasConfig: false,
|
|
108
|
+
runtime: {
|
|
109
|
+
timing: SemanticTiming.None,
|
|
110
|
+
operations: [],
|
|
111
|
+
},
|
|
84
112
|
}
|
|
85
113
|
const propertySemantic: PropertySemantic = {
|
|
86
114
|
id: SemanticType.CreatedTimestamp,
|
|
@@ -89,6 +117,12 @@ test.group('Semantics', () => {
|
|
|
89
117
|
scope: SemanticScope.Property,
|
|
90
118
|
category: SemanticCategory.Lifecycle,
|
|
91
119
|
hasConfig: false,
|
|
120
|
+
applicableDataTypes: ['datetime'],
|
|
121
|
+
runtime: {
|
|
122
|
+
timing: SemanticTiming.Before,
|
|
123
|
+
operations: [SemanticOperation.Create],
|
|
124
|
+
priority: 90,
|
|
125
|
+
},
|
|
92
126
|
}
|
|
93
127
|
const associationSemantic: AssociationSemantic = {
|
|
94
128
|
id: SemanticType.ResourceOwnerIdentifier,
|
|
@@ -97,6 +131,18 @@ test.group('Semantics', () => {
|
|
|
97
131
|
scope: SemanticScope.Association,
|
|
98
132
|
category: SemanticCategory.Identity,
|
|
99
133
|
hasConfig: false,
|
|
134
|
+
runtime: {
|
|
135
|
+
timing: SemanticTiming.Before,
|
|
136
|
+
operations: [
|
|
137
|
+
SemanticOperation.Create,
|
|
138
|
+
SemanticOperation.Read,
|
|
139
|
+
SemanticOperation.Update,
|
|
140
|
+
SemanticOperation.Delete,
|
|
141
|
+
SemanticOperation.List,
|
|
142
|
+
],
|
|
143
|
+
priority: 5,
|
|
144
|
+
canDisable: false,
|
|
145
|
+
},
|
|
100
146
|
}
|
|
101
147
|
|
|
102
148
|
assert.isFalse(isPropertySemantic(entitySemantic))
|
|
@@ -112,6 +158,10 @@ test.group('Semantics', () => {
|
|
|
112
158
|
scope: SemanticScope.Entity,
|
|
113
159
|
category: SemanticCategory.Identity,
|
|
114
160
|
hasConfig: false,
|
|
161
|
+
runtime: {
|
|
162
|
+
timing: SemanticTiming.None,
|
|
163
|
+
operations: [],
|
|
164
|
+
},
|
|
115
165
|
}
|
|
116
166
|
const propertySemantic: PropertySemantic = {
|
|
117
167
|
id: SemanticType.CreatedTimestamp,
|
|
@@ -120,6 +170,12 @@ test.group('Semantics', () => {
|
|
|
120
170
|
scope: SemanticScope.Property,
|
|
121
171
|
category: SemanticCategory.Lifecycle,
|
|
122
172
|
hasConfig: false,
|
|
173
|
+
applicableDataTypes: ['datetime'],
|
|
174
|
+
runtime: {
|
|
175
|
+
timing: SemanticTiming.Before,
|
|
176
|
+
operations: [SemanticOperation.Create],
|
|
177
|
+
priority: 90,
|
|
178
|
+
},
|
|
123
179
|
}
|
|
124
180
|
const associationSemantic: AssociationSemantic = {
|
|
125
181
|
id: SemanticType.ResourceOwnerIdentifier,
|
|
@@ -128,6 +184,18 @@ test.group('Semantics', () => {
|
|
|
128
184
|
scope: SemanticScope.Association,
|
|
129
185
|
category: SemanticCategory.Identity,
|
|
130
186
|
hasConfig: false,
|
|
187
|
+
runtime: {
|
|
188
|
+
timing: SemanticTiming.Before,
|
|
189
|
+
operations: [
|
|
190
|
+
SemanticOperation.Create,
|
|
191
|
+
SemanticOperation.Read,
|
|
192
|
+
SemanticOperation.Update,
|
|
193
|
+
SemanticOperation.Delete,
|
|
194
|
+
SemanticOperation.List,
|
|
195
|
+
],
|
|
196
|
+
priority: 5,
|
|
197
|
+
canDisable: false,
|
|
198
|
+
},
|
|
131
199
|
}
|
|
132
200
|
|
|
133
201
|
assert.isFalse(isAssociationSemantic(entitySemantic))
|