@twin.org/auditable-item-graph-service 0.0.3-next.22 → 0.0.3-next.24
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/dist/es/auditableItemGraphRoutes.js +6 -5
- package/dist/es/auditableItemGraphRoutes.js.map +1 -1
- package/dist/es/auditableItemGraphService.js +33 -22
- package/dist/es/auditableItemGraphService.js.map +1 -1
- package/dist/es/entities/auditableItemGraphVertex.js +1 -1
- package/dist/es/entities/auditableItemGraphVertex.js.map +1 -1
- package/dist/es/models/IAuditableItemGraphServiceContext.js +2 -0
- package/dist/es/models/IAuditableItemGraphServiceContext.js.map +1 -1
- package/dist/es/restEntryPoints.js +3 -0
- package/dist/es/restEntryPoints.js.map +1 -1
- package/dist/types/auditableItemGraphRoutes.d.ts +1 -1
- package/dist/types/auditableItemGraphService.d.ts +4 -3
- package/dist/types/entities/auditableItemGraphVertex.d.ts +1 -1
- package/dist/types/models/IAuditableItemGraphServiceContext.d.ts +6 -3
- package/dist/types/restEntryPoints.d.ts +3 -0
- package/docs/changelog.md +34 -0
- package/docs/reference/classes/AuditableItemGraphService.md +5 -3
- package/docs/reference/classes/AuditableItemGraphVertex.md +2 -2
- package/docs/reference/variables/restEntryPoints.md +2 -0
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright 2024 IOTA Stiftung.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
3
|
import { AuditableItemGraphContexts, AuditableItemGraphDataTypes, AuditableItemGraphMetricIds, AuditableItemGraphMetrics, AuditableItemGraphTopics, AuditableItemGraphTypes, VerifyDepth } from "@twin.org/auditable-item-graph-models";
|
|
4
|
-
import { ContextIdKeys, ContextIdStore } from "@twin.org/context";
|
|
4
|
+
import { ContextIdHelper, ContextIdKeys, ContextIdStore } from "@twin.org/context";
|
|
5
5
|
import { ArrayHelper, Coerce, ComponentFactory, GeneralError, Guards, Is, JsonHelper, Mutex, NotFoundError, ObjectHelper, RandomHelper, StringHelper, Urn, Validation } from "@twin.org/core";
|
|
6
6
|
import { DataTypeHelper } from "@twin.org/data-core";
|
|
7
7
|
import { JsonLdDataTypes, JsonLdHelper, JsonLdProcessor } from "@twin.org/data-json-ld";
|
|
@@ -90,6 +90,7 @@ export class AuditableItemGraphService {
|
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
92
|
* Register all AIG metrics with the telemetry component.
|
|
93
|
+
* @returns A promise that resolves when all metrics have been registered.
|
|
93
94
|
*/
|
|
94
95
|
async start() {
|
|
95
96
|
if (Is.undefined(this._telemetryComponent)) {
|
|
@@ -109,6 +110,7 @@ export class AuditableItemGraphService {
|
|
|
109
110
|
async create(vertex) {
|
|
110
111
|
Guards.object(AuditableItemGraphService.CLASS_NAME, "vertex", vertex);
|
|
111
112
|
const contextIds = await ContextIdStore.getContextIds();
|
|
113
|
+
ContextIdHelper.guard(contextIds, ContextIdKeys.Organization);
|
|
112
114
|
try {
|
|
113
115
|
const id = RandomHelper.generateUuidV7("compact");
|
|
114
116
|
const schemaValidationFailures = [];
|
|
@@ -122,13 +124,15 @@ export class AuditableItemGraphService {
|
|
|
122
124
|
await JsonLdHelper.validate(vertex.annotationObject, validationFailures);
|
|
123
125
|
Validation.asValidationError(AuditableItemGraphService.CLASS_NAME, "vertex.annotationObject", validationFailures);
|
|
124
126
|
}
|
|
127
|
+
const ownerOrganizationId = contextIds?.[ContextIdKeys.UserOrganization] ?? contextIds?.[ContextIdKeys.Organization];
|
|
125
128
|
const context = {
|
|
126
129
|
now: new Date(Date.now()).toISOString(),
|
|
127
|
-
|
|
130
|
+
organizationIdentity: ownerOrganizationId,
|
|
131
|
+
userIdentity: contextIds?.[ContextIdKeys.User]
|
|
128
132
|
};
|
|
129
133
|
const vertexModel = {
|
|
130
134
|
id,
|
|
131
|
-
organizationIdentity: contextIds
|
|
135
|
+
organizationIdentity: contextIds[ContextIdKeys.Organization],
|
|
132
136
|
dateCreated: context.now
|
|
133
137
|
};
|
|
134
138
|
const originalEntity = ObjectHelper.clone(vertexModel);
|
|
@@ -157,7 +161,7 @@ export class AuditableItemGraphService {
|
|
|
157
161
|
* Update a graph vertex (PUT — full replacement of vertex state).
|
|
158
162
|
* Concurrent updates for the same vertex are serialized via `Mutex` on the vertex id.
|
|
159
163
|
* @param vertex The vertex to update.
|
|
160
|
-
* @returns
|
|
164
|
+
* @returns A promise that resolves when the vertex has been updated.
|
|
161
165
|
*/
|
|
162
166
|
async update(vertex) {
|
|
163
167
|
Guards.object(AuditableItemGraphService.CLASS_NAME, "vertex", vertex);
|
|
@@ -165,7 +169,6 @@ export class AuditableItemGraphService {
|
|
|
165
169
|
const vertexId = this.parseVertexId(vertex.id);
|
|
166
170
|
await Mutex.lock(vertexId, { throwOnTimeout: true });
|
|
167
171
|
try {
|
|
168
|
-
const contextIds = await ContextIdStore.getContextIds();
|
|
169
172
|
try {
|
|
170
173
|
const schemaValidationFailures = [];
|
|
171
174
|
await DataTypeHelper.validate("vertex", `${AuditableItemGraphContexts.Namespace}${AuditableItemGraphTypes.Vertex}`, vertex, schemaValidationFailures);
|
|
@@ -179,20 +182,18 @@ export class AuditableItemGraphService {
|
|
|
179
182
|
await JsonLdHelper.validate(vertex.annotationObject, validationFailures);
|
|
180
183
|
Validation.asValidationError(AuditableItemGraphService.CLASS_NAME, "vertex.annotationObject", validationFailures);
|
|
181
184
|
}
|
|
185
|
+
const contextIds = await ContextIdStore.getContextIds();
|
|
186
|
+
const ownerOrganizationId = vertexEntity.organizationIdentity ??
|
|
187
|
+
contextIds?.[ContextIdKeys.UserOrganization] ??
|
|
188
|
+
contextIds?.[ContextIdKeys.Organization];
|
|
182
189
|
const context = {
|
|
183
190
|
now: new Date(Date.now()).toISOString(),
|
|
184
|
-
|
|
191
|
+
organizationIdentity: ownerOrganizationId,
|
|
192
|
+
userIdentity: contextIds?.[ContextIdKeys.User]
|
|
185
193
|
};
|
|
186
194
|
delete vertexEntity.aliasIndex;
|
|
187
195
|
const originalEntity = ObjectHelper.clone(vertexEntity);
|
|
188
196
|
const newEntity = ObjectHelper.clone(vertexEntity);
|
|
189
|
-
// Capture org from context if vertex doesn't have one yet.
|
|
190
|
-
// Enables ownership transition: when an authenticated user first
|
|
191
|
-
// interacts with a vertex that was received without an org, the org
|
|
192
|
-
// is set here and recorded as a patch in the changeset proof.
|
|
193
|
-
if (!Is.stringValue(newEntity.organizationIdentity)) {
|
|
194
|
-
newEntity.organizationIdentity = context.contextIds?.[ContextIdKeys.Organization];
|
|
195
|
-
}
|
|
196
197
|
newEntity.annotationObject = vertex.annotationObject;
|
|
197
198
|
await this.updateAliasList(context, newEntity, vertex.aliases);
|
|
198
199
|
await this.updateResourceList(context, newEntity, vertex.resources);
|
|
@@ -211,7 +212,7 @@ export class AuditableItemGraphService {
|
|
|
211
212
|
* Partially update a graph vertex (PATCH — explicit list patches; only defined properties applied).
|
|
212
213
|
* Serialized with `update` via `Mutex` on the same vertex id within this instance.
|
|
213
214
|
* @param partial The partial vertex update.
|
|
214
|
-
* @returns
|
|
215
|
+
* @returns A promise that resolves when the partial update has been applied.
|
|
215
216
|
*/
|
|
216
217
|
async updatePartial(partial) {
|
|
217
218
|
Guards.object(AuditableItemGraphService.CLASS_NAME, "partial", partial);
|
|
@@ -219,7 +220,6 @@ export class AuditableItemGraphService {
|
|
|
219
220
|
const vertexId = this.parseVertexId(partial.id);
|
|
220
221
|
await Mutex.lock(vertexId, { throwOnTimeout: true });
|
|
221
222
|
try {
|
|
222
|
-
const contextIds = await ContextIdStore.getContextIds();
|
|
223
223
|
try {
|
|
224
224
|
const vertexEntity = await this._vertexStorage.get(vertexId);
|
|
225
225
|
if (Is.empty(vertexEntity)) {
|
|
@@ -230,17 +230,18 @@ export class AuditableItemGraphService {
|
|
|
230
230
|
await JsonLdHelper.validate(partial.annotationObject, validationFailures);
|
|
231
231
|
Validation.asValidationError(AuditableItemGraphService.CLASS_NAME, "partial.annotationObject", validationFailures);
|
|
232
232
|
}
|
|
233
|
+
const contextIds = await ContextIdStore.getContextIds();
|
|
234
|
+
const ownerOrganizationId = vertexEntity.organizationIdentity ??
|
|
235
|
+
contextIds?.[ContextIdKeys.UserOrganization] ??
|
|
236
|
+
contextIds?.[ContextIdKeys.Organization];
|
|
233
237
|
const context = {
|
|
234
238
|
now: new Date(Date.now()).toISOString(),
|
|
235
|
-
|
|
239
|
+
organizationIdentity: ownerOrganizationId,
|
|
240
|
+
userIdentity: contextIds?.[ContextIdKeys.User]
|
|
236
241
|
};
|
|
237
242
|
delete vertexEntity.aliasIndex;
|
|
238
243
|
const originalEntity = ObjectHelper.clone(vertexEntity);
|
|
239
244
|
const newEntity = ObjectHelper.clone(vertexEntity);
|
|
240
|
-
// Capture org from context if vertex doesn't have one yet.
|
|
241
|
-
if (!Is.stringValue(newEntity.organizationIdentity)) {
|
|
242
|
-
newEntity.organizationIdentity = context.contextIds?.[ContextIdKeys.Organization];
|
|
243
|
-
}
|
|
244
245
|
if (partial.annotationObject !== undefined) {
|
|
245
246
|
newEntity.annotationObject = partial.annotationObject;
|
|
246
247
|
}
|
|
@@ -543,7 +544,7 @@ export class AuditableItemGraphService {
|
|
|
543
544
|
/**
|
|
544
545
|
* Remove the proof for an item.
|
|
545
546
|
* @param id The id of the vertex to remove the proof from.
|
|
546
|
-
* @returns
|
|
547
|
+
* @returns A promise that resolves when the proof has been removed from all changesets.
|
|
547
548
|
* @throws NotFoundError if the vertex is not found.
|
|
548
549
|
*/
|
|
549
550
|
async removeProof(id) {
|
|
@@ -717,6 +718,7 @@ export class AuditableItemGraphService {
|
|
|
717
718
|
* @param vertexUrn The vertex URN for events.
|
|
718
719
|
* @param originalEntity The entity before changes.
|
|
719
720
|
* @param newEntity The entity after changes.
|
|
721
|
+
* @returns A promise that resolves when the changes have been persisted and events published.
|
|
720
722
|
* @internal
|
|
721
723
|
*/
|
|
722
724
|
async persistVertexChanges(context, vertexId, vertexUrn, originalEntity, newEntity) {
|
|
@@ -900,6 +902,7 @@ export class AuditableItemGraphService {
|
|
|
900
902
|
* @param context The context for the operation.
|
|
901
903
|
* @param vertex The vertex.
|
|
902
904
|
* @param aliases The new active alias set.
|
|
905
|
+
* @returns A promise that resolves when the alias list has been replaced.
|
|
903
906
|
* @internal
|
|
904
907
|
*/
|
|
905
908
|
async updateAliasList(context, vertex, aliases) {
|
|
@@ -923,6 +926,7 @@ export class AuditableItemGraphService {
|
|
|
923
926
|
* @param context The context for the operation.
|
|
924
927
|
* @param vertex The vertex.
|
|
925
928
|
* @param patch The alias patch.
|
|
929
|
+
* @returns A promise that resolves when the alias patch has been applied.
|
|
926
930
|
* @internal
|
|
927
931
|
*/
|
|
928
932
|
async applyAliasPatch(context, vertex, patch) {
|
|
@@ -947,6 +951,7 @@ export class AuditableItemGraphService {
|
|
|
947
951
|
* @param context The context for the operation.
|
|
948
952
|
* @param vertex The vertex.
|
|
949
953
|
* @param alias The alias.
|
|
954
|
+
* @returns A promise that resolves when the alias has been added or updated.
|
|
950
955
|
* @internal
|
|
951
956
|
*/
|
|
952
957
|
async updateAlias(context, vertex, alias) {
|
|
@@ -996,6 +1001,7 @@ export class AuditableItemGraphService {
|
|
|
996
1001
|
* @param context The context for the operation.
|
|
997
1002
|
* @param vertex The vertex.
|
|
998
1003
|
* @param resources The new active resource set.
|
|
1004
|
+
* @returns A promise that resolves when the resource list has been replaced.
|
|
999
1005
|
* @internal
|
|
1000
1006
|
*/
|
|
1001
1007
|
async updateResourceList(context, vertex, resources) {
|
|
@@ -1029,6 +1035,7 @@ export class AuditableItemGraphService {
|
|
|
1029
1035
|
* @param context The context for the operation.
|
|
1030
1036
|
* @param vertex The vertex.
|
|
1031
1037
|
* @param patch The resource patch.
|
|
1038
|
+
* @returns A promise that resolves when the resource patch has been applied.
|
|
1032
1039
|
* @internal
|
|
1033
1040
|
*/
|
|
1034
1041
|
async applyResourcePatch(context, vertex, patch) {
|
|
@@ -1053,6 +1060,7 @@ export class AuditableItemGraphService {
|
|
|
1053
1060
|
* @param context The context for the operation.
|
|
1054
1061
|
* @param vertex The vertex.
|
|
1055
1062
|
* @param resource The resource.
|
|
1063
|
+
* @returns A promise that resolves when the resource has been added or updated.
|
|
1056
1064
|
* @internal
|
|
1057
1065
|
*/
|
|
1058
1066
|
async updateResource(context, vertex, resource) {
|
|
@@ -1087,6 +1095,7 @@ export class AuditableItemGraphService {
|
|
|
1087
1095
|
* @param context The context for the operation.
|
|
1088
1096
|
* @param vertex The vertex.
|
|
1089
1097
|
* @param edges The new active edge set.
|
|
1098
|
+
* @returns A promise that resolves when the edge list has been replaced.
|
|
1090
1099
|
* @internal
|
|
1091
1100
|
*/
|
|
1092
1101
|
async updateEdgeList(context, vertex, edges) {
|
|
@@ -1112,6 +1121,7 @@ export class AuditableItemGraphService {
|
|
|
1112
1121
|
* @param context The context for the operation.
|
|
1113
1122
|
* @param vertex The vertex.
|
|
1114
1123
|
* @param patch The edge patch.
|
|
1124
|
+
* @returns A promise that resolves when the edge patch has been applied.
|
|
1115
1125
|
* @internal
|
|
1116
1126
|
*/
|
|
1117
1127
|
async applyEdgePatch(context, vertex, patch) {
|
|
@@ -1136,6 +1146,7 @@ export class AuditableItemGraphService {
|
|
|
1136
1146
|
* @param context The context for the operation.
|
|
1137
1147
|
* @param vertex The vertex.
|
|
1138
1148
|
* @param edge The edge.
|
|
1149
|
+
* @returns A promise that resolves when the edge has been added or updated.
|
|
1139
1150
|
* @internal
|
|
1140
1151
|
*/
|
|
1141
1152
|
async updateEdge(context, vertex, edge) {
|
|
@@ -1207,7 +1218,7 @@ export class AuditableItemGraphService {
|
|
|
1207
1218
|
id: RandomHelper.generateUuidV7("compact"),
|
|
1208
1219
|
vertexId: updated.id,
|
|
1209
1220
|
dateCreated: context.now,
|
|
1210
|
-
userIdentity: context.
|
|
1221
|
+
userIdentity: context.userIdentity,
|
|
1211
1222
|
patches,
|
|
1212
1223
|
version
|
|
1213
1224
|
};
|