@twin.org/auditable-item-stream-service 0.0.3-next.11 → 0.0.3-next.13

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # TWIN Auditable Item Stream Service
1
+ # Auditable Item Stream Service
2
2
 
3
- Auditable Item Stream contract implementation and REST endpoint definitions.
3
+ This package provides the service layer for auditable item streams, including stream and entry lifecycle operations, entity schema initialisation, and REST route generation for API hosts.
4
4
 
5
5
  ## Installation
6
6
 
@@ -39,21 +39,31 @@ export function generateRestRoutesAuditableItemStream(baseRouteName, componentNa
39
39
  id: "auditableItemStreamCreateRequestExample",
40
40
  request: {
41
41
  body: {
42
+ "@context": [
43
+ SchemaOrgContexts.Context,
44
+ AuditableItemStreamContexts.Context,
45
+ AuditableItemStreamContexts.ContextCommon
46
+ ],
47
+ type: AuditableItemStreamTypes.Stream,
42
48
  annotationObject: {
43
49
  "@context": "https://schema.org",
44
50
  "@type": "Note",
45
51
  content: "This is a simple note"
46
52
  },
47
- entries: [
48
- {
49
- entryObject: {
50
- "@context": "https://schema.org",
51
- "@type": "Event",
52
- startDate: "2011-04-09T20:00:00Z",
53
- description: "A description of the event"
53
+ entries: {
54
+ type: SchemaOrgTypes.ItemList,
55
+ [SchemaOrgTypes.ItemListElement]: [
56
+ {
57
+ type: AuditableItemStreamTypes.StreamEntry,
58
+ entryObject: {
59
+ "@context": "https://schema.org",
60
+ "@type": "Event",
61
+ startDate: "2011-04-09T20:00:00Z",
62
+ description: "A description of the event"
63
+ }
54
64
  }
55
- }
56
- ]
65
+ ]
66
+ }
57
67
  }
58
68
  }
59
69
  }
@@ -109,6 +119,7 @@ export function generateRestRoutesAuditableItemStream(baseRouteName, componentNa
109
119
  response: {
110
120
  body: {
111
121
  "@context": [
122
+ SchemaOrgContexts.Context,
112
123
  AuditableItemStreamContexts.Context,
113
124
  AuditableItemStreamContexts.ContextCommon
114
125
  ],
@@ -125,25 +136,28 @@ export function generateRestRoutesAuditableItemStream(baseRouteName, componentNa
125
136
  proofId: "0101010101010101010101010101010101010101010101010101010101010101",
126
137
  immutableInterval: 10,
127
138
  numberOfItems: 1,
128
- entries: [
129
- {
130
- "@context": [
131
- AuditableItemStreamContexts.Context,
132
- AuditableItemStreamContexts.ContextCommon
133
- ],
134
- type: AuditableItemStreamTypes.StreamEntry,
135
- id: "tst:1234567890",
136
- dateCreated: "2024-08-22T11:55:16.271Z",
137
- proofId: "0101010101010101010101010101010101010101010101010101010101010101",
138
- index: 0,
139
- entryObject: {
140
- "@context": "https://schema.org",
141
- "@type": "Event",
142
- startDate: "2011-04-09T20:00:00Z",
143
- description: "A description of the event"
139
+ entries: {
140
+ type: SchemaOrgTypes.ItemList,
141
+ [SchemaOrgTypes.ItemListElement]: [
142
+ {
143
+ "@context": [
144
+ AuditableItemStreamContexts.Context,
145
+ AuditableItemStreamContexts.ContextCommon
146
+ ],
147
+ type: AuditableItemStreamTypes.StreamEntry,
148
+ id: "tst:1234567890",
149
+ dateCreated: "2024-08-22T11:55:16.271Z",
150
+ proofId: "0101010101010101010101010101010101010101010101010101010101010101",
151
+ index: 0,
152
+ entryObject: {
153
+ "@context": "https://schema.org",
154
+ "@type": "Event",
155
+ startDate: "2011-04-09T20:00:00Z",
156
+ description: "A description of the event"
157
+ }
144
158
  }
145
- }
146
- ]
159
+ ]
160
+ }
147
161
  }
148
162
  }
149
163
  }
@@ -161,6 +175,7 @@ export function generateRestRoutesAuditableItemStream(baseRouteName, componentNa
161
175
  },
162
176
  body: {
163
177
  "@context": [
178
+ SchemaOrgContexts.Context,
164
179
  AuditableItemStreamContexts.Context,
165
180
  AuditableItemStreamContexts.ContextCommon
166
181
  ],
@@ -177,25 +192,28 @@ export function generateRestRoutesAuditableItemStream(baseRouteName, componentNa
177
192
  proofId: "0101010101010101010101010101010101010101010101010101010101010101",
178
193
  immutableInterval: 10,
179
194
  numberOfItems: 1,
180
- entries: [
181
- {
182
- "@context": [
183
- AuditableItemStreamContexts.Context,
184
- AuditableItemStreamContexts.ContextCommon
185
- ],
186
- type: AuditableItemStreamTypes.StreamEntry,
187
- id: "tst:1234567890",
188
- dateCreated: "2024-08-22T11:55:16.271Z",
189
- proofId: "0101010101010101010101010101010101010101010101010101010101010101",
190
- index: 0,
191
- entryObject: {
192
- "@context": "https://schema.org",
193
- "@type": "Event",
194
- startDate: "2011-04-09T20:00:00Z",
195
- description: "A description of the event"
195
+ entries: {
196
+ type: SchemaOrgTypes.ItemList,
197
+ [SchemaOrgTypes.ItemListElement]: [
198
+ {
199
+ "@context": [
200
+ AuditableItemStreamContexts.Context,
201
+ AuditableItemStreamContexts.ContextCommon
202
+ ],
203
+ type: AuditableItemStreamTypes.StreamEntry,
204
+ id: "tst:1234567890",
205
+ dateCreated: "2024-08-22T11:55:16.271Z",
206
+ proofId: "0101010101010101010101010101010101010101010101010101010101010101",
207
+ index: 0,
208
+ entryObject: {
209
+ "@context": "https://schema.org",
210
+ "@type": "Event",
211
+ startDate: "2011-04-09T20:00:00Z",
212
+ description: "A description of the event"
213
+ }
196
214
  }
197
- }
198
- ]
215
+ ]
216
+ }
199
217
  }
200
218
  }
201
219
  }
@@ -223,6 +241,12 @@ export function generateRestRoutesAuditableItemStream(baseRouteName, componentNa
223
241
  id: "ais:1234567890"
224
242
  },
225
243
  body: {
244
+ "@context": [
245
+ SchemaOrgContexts.Context,
246
+ AuditableItemStreamContexts.Context,
247
+ AuditableItemStreamContexts.ContextCommon
248
+ ],
249
+ type: AuditableItemStreamTypes.Stream,
226
250
  annotationObject: {
227
251
  "@context": "https://schema.org",
228
252
  "@type": "Note",
@@ -271,6 +295,35 @@ export function generateRestRoutesAuditableItemStream(baseRouteName, componentNa
271
295
  }
272
296
  ]
273
297
  };
298
+ const closeRoute = {
299
+ operationId: "auditableItemStreamClose",
300
+ summary: "Close a stream",
301
+ tag: tagsAuditableItemStream[0].name,
302
+ method: "POST",
303
+ path: `${baseRouteName}/:id/close`,
304
+ handler: async (httpRequestContext, request) => auditableItemStreamClose(httpRequestContext, componentName, request),
305
+ requestType: {
306
+ type: "IAuditableItemStreamCloseRequest",
307
+ examples: [
308
+ {
309
+ id: "auditableItemStreamCloseRequestExample",
310
+ request: {
311
+ pathParams: {
312
+ id: "ais:1234567890"
313
+ }
314
+ }
315
+ }
316
+ ]
317
+ },
318
+ responseType: [
319
+ {
320
+ type: "INoContentResponse"
321
+ },
322
+ {
323
+ type: "INotFoundResponse"
324
+ }
325
+ ]
326
+ };
274
327
  const listRoute = {
275
328
  operationId: "auditableItemStreamList",
276
329
  summary: "Query streams",
@@ -304,6 +357,7 @@ export function generateRestRoutesAuditableItemStream(baseRouteName, componentNa
304
357
  [SchemaOrgTypes.ItemListElement]: [
305
358
  {
306
359
  "@context": [
360
+ SchemaOrgContexts.Context,
307
361
  AuditableItemStreamContexts.Context,
308
362
  AuditableItemStreamContexts.ContextCommon
309
363
  ],
@@ -347,6 +401,7 @@ export function generateRestRoutesAuditableItemStream(baseRouteName, componentNa
347
401
  [SchemaOrgTypes.ItemListElement]: [
348
402
  {
349
403
  "@context": [
404
+ SchemaOrgContexts.Context,
350
405
  AuditableItemStreamContexts.Context,
351
406
  AuditableItemStreamContexts.ContextCommon
352
407
  ],
@@ -925,6 +980,7 @@ export function generateRestRoutesAuditableItemStream(baseRouteName, componentNa
925
980
  getRoute,
926
981
  updateRoute,
927
982
  deleteRoute,
983
+ closeRoute,
928
984
  listRoute,
929
985
  createEntryRoute,
930
986
  getEntryRoute,
@@ -948,12 +1004,7 @@ export async function auditableItemStreamCreate(httpRequestContext, componentNam
948
1004
  Guards.object(ROUTES_SOURCE, "request", request);
949
1005
  Guards.object(ROUTES_SOURCE, "request.body", request.body);
950
1006
  const component = ComponentFactory.get(componentName);
951
- const id = await component.create({
952
- annotationObject: request.body.annotationObject,
953
- entries: request.body.entries
954
- }, {
955
- immutableInterval: request.body?.immutableInterval
956
- });
1007
+ const id = await component.create(request.body);
957
1008
  return {
958
1009
  statusCode: HttpStatusCode.created,
959
1010
  headers: {
@@ -972,20 +1023,23 @@ export async function auditableItemStreamGet(httpRequestContext, componentName,
972
1023
  Guards.object(ROUTES_SOURCE, "request", request);
973
1024
  Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
974
1025
  Guards.stringValue(ROUTES_SOURCE, "request.pathParams.id", request.pathParams.id);
1026
+ const hostingComponent = ComponentFactory.get(httpRequestContext.hostingComponentType ?? "hosting");
975
1027
  const component = ComponentFactory.get(componentName);
976
- const result = await component.get(request.pathParams.id, {
1028
+ const result = await component.get(request.pathParams.id, request.query?.cursor, Coerce.integer(request.query?.limit), {
977
1029
  includeEntries: Coerce.boolean(request.query?.includeEntries),
978
1030
  includeDeleted: Coerce.boolean(request.query?.includeDeleted),
979
1031
  verifyStream: Coerce.boolean(request.query?.verifyStream),
980
1032
  verifyEntries: Coerce.boolean(request.query?.verifyEntries)
981
1033
  });
1034
+ const headers = {
1035
+ [HeaderTypes.ContentType]: request.headers?.[HeaderTypes.Accept] === MimeTypes.JsonLd ? MimeTypes.JsonLd : MimeTypes.Json
1036
+ };
1037
+ if (Is.stringValue(result.cursor)) {
1038
+ headers[HeaderTypes.Link] = HeaderHelper.createLinkHeader(await hostingComponent.buildPublicUrl(httpRequestContext.serverRequest.url), { cursor: result.cursor }, "next");
1039
+ }
982
1040
  return {
983
- headers: {
984
- [HeaderTypes.ContentType]: request.headers?.[HeaderTypes.Accept] === MimeTypes.JsonLd
985
- ? MimeTypes.JsonLd
986
- : MimeTypes.Json
987
- },
988
- body: result
1041
+ headers,
1042
+ body: result.stream
989
1043
  };
990
1044
  }
991
1045
  /**
@@ -1002,8 +1056,8 @@ export async function auditableItemStreamUpdate(httpRequestContext, componentNam
1002
1056
  Guards.object(ROUTES_SOURCE, "request.body", request.body);
1003
1057
  const component = ComponentFactory.get(componentName);
1004
1058
  await component.update({
1005
- id: request.pathParams.id,
1006
- annotationObject: request.body.annotationObject
1059
+ ...request.body,
1060
+ id: request.pathParams.id
1007
1061
  });
1008
1062
  return {
1009
1063
  statusCode: HttpStatusCode.noContent
@@ -1026,6 +1080,23 @@ export async function auditableItemStreamDelete(httpRequestContext, componentNam
1026
1080
  statusCode: HttpStatusCode.noContent
1027
1081
  };
1028
1082
  }
1083
+ /**
1084
+ * Close the stream.
1085
+ * @param httpRequestContext The request context for the API.
1086
+ * @param componentName The name of the component to use in the routes.
1087
+ * @param request The request.
1088
+ * @returns The response object with additional http response properties.
1089
+ */
1090
+ export async function auditableItemStreamClose(httpRequestContext, componentName, request) {
1091
+ Guards.object(ROUTES_SOURCE, "request", request);
1092
+ Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
1093
+ Guards.stringValue(ROUTES_SOURCE, "request.pathParams.id", request.pathParams.id);
1094
+ const component = ComponentFactory.get(componentName);
1095
+ await component.close(request.pathParams.id);
1096
+ return {
1097
+ statusCode: HttpStatusCode.noContent
1098
+ };
1099
+ }
1029
1100
  /**
1030
1101
  * Query the stream.
1031
1102
  * @param httpRequestContext The request context for the API.