@twin.org/document-management-service 0.0.1-next.9 → 0.0.2-next.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.
@@ -1,10 +1,10 @@
1
+ import { AuditableItemGraphTypes, AuditableItemGraphContexts } from '@twin.org/auditable-item-graph-models';
1
2
  import { Guards, ComponentFactory, Converter, Coerce, Is, BaseError, GeneralError, Urn, NotFoundError, ObjectHelper } from '@twin.org/core';
2
3
  import { DocumentTypes, DocumentContexts } from '@twin.org/document-management-models';
3
- import { SchemaOrgContexts, SchemaOrgDataTypes } from '@twin.org/standards-schema-org';
4
+ import { SchemaOrgContexts, SchemaOrgTypes, SchemaOrgDataTypes } from '@twin.org/standards-schema-org';
4
5
  import { UneceDocumentCodes } from '@twin.org/standards-unece';
5
6
  import { HttpStatusCode, HeaderTypes, MimeTypes } from '@twin.org/web';
6
7
  import { AttestationContexts } from '@twin.org/attestation-models';
7
- import { AuditableItemGraphTypes, AuditableItemGraphContexts } from '@twin.org/auditable-item-graph-models';
8
8
  import { BlobStorageContexts } from '@twin.org/blob-storage-models';
9
9
  import { Sha256 } from '@twin.org/crypto';
10
10
  import { JsonLdProcessor } from '@twin.org/data-json-ld';
@@ -145,9 +145,13 @@ function generateRestRoutesDocumentManagement(baseRouteName, componentName) {
145
145
  id: "DocumentManagementGetResponseExample",
146
146
  response: {
147
147
  body: {
148
- "@context": [DocumentContexts.ContextRoot, DocumentContexts.ContextRootCommon],
149
- type: DocumentTypes.DocumentList,
150
- documents: [
148
+ "@context": [
149
+ SchemaOrgContexts.ContextRoot,
150
+ DocumentContexts.ContextRoot,
151
+ DocumentContexts.ContextRootCommon
152
+ ],
153
+ type: SchemaOrgTypes.ItemList,
154
+ [SchemaOrgTypes.ItemListElement]: [
151
155
  {
152
156
  "@context": [
153
157
  DocumentContexts.ContextRoot,
@@ -185,9 +189,13 @@ function generateRestRoutesDocumentManagement(baseRouteName, componentName) {
185
189
  id: "DocumentManagementGetResponseExample",
186
190
  response: {
187
191
  body: {
188
- "@context": [DocumentContexts.ContextRoot, DocumentContexts.ContextRootCommon],
189
- type: DocumentTypes.DocumentList,
190
- documents: [
192
+ "@context": [
193
+ SchemaOrgContexts.ContextRoot,
194
+ DocumentContexts.ContextRoot,
195
+ DocumentContexts.ContextRootCommon
196
+ ],
197
+ type: SchemaOrgTypes.ItemList,
198
+ [SchemaOrgTypes.ItemListElement]: [
191
199
  {
192
200
  "@context": [
193
201
  DocumentContexts.ContextRoot,
@@ -222,7 +230,101 @@ function generateRestRoutesDocumentManagement(baseRouteName, componentName) {
222
230
  }
223
231
  ]
224
232
  };
225
- const documentManagementRemoveRoute = {
233
+ const documentManagementGetRevisionRoute = {
234
+ operationId: "DocumentManagementGetRevision",
235
+ summary: "Get the data for a document revision from document management",
236
+ tag: tagsDocumentManagement[0].name,
237
+ method: "GET",
238
+ path: `${baseRouteName}/:auditableItemGraphDocumentId/:revision`,
239
+ handler: async (httpRequestContext, request) => documentManagementGetRevision(httpRequestContext, componentName, request),
240
+ requestType: {
241
+ type: "IDocumentManagementGetRequest",
242
+ examples: [
243
+ {
244
+ id: "DocumentManagementGetRevisionRequestExample",
245
+ request: {
246
+ pathParams: {
247
+ auditableItemGraphDocumentId: "aig:123456",
248
+ revision: "1"
249
+ }
250
+ }
251
+ }
252
+ ]
253
+ },
254
+ responseType: [
255
+ {
256
+ type: "IDocumentManagementGetRevisionResponse",
257
+ examples: [
258
+ {
259
+ id: "DocumentManagementGetRevisionResponseExample",
260
+ response: {
261
+ body: {
262
+ "@context": [
263
+ DocumentContexts.ContextRoot,
264
+ DocumentContexts.ContextRootCommon,
265
+ SchemaOrgContexts.ContextRoot
266
+ ],
267
+ type: DocumentTypes.Document,
268
+ id: "2721000:0",
269
+ documentId: "2721000",
270
+ documentIdFormat: "bol",
271
+ documentCode: UneceDocumentCodes.BillOfLading,
272
+ documentRevision: 1,
273
+ blobStorageId: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
274
+ blobHash: "sha256:123456",
275
+ dateCreated: "2024-01-01T00:00:00Z",
276
+ annotationObject: {
277
+ "@context": "https://schema.org",
278
+ "@type": "DigitalDocument",
279
+ name: "myfile.pdf"
280
+ },
281
+ nodeIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363",
282
+ userIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363"
283
+ }
284
+ }
285
+ }
286
+ ]
287
+ },
288
+ {
289
+ type: "IDocumentManagementGetRevisionResponse",
290
+ mimeType: MimeTypes.JsonLd,
291
+ examples: [
292
+ {
293
+ id: "DocumentManagementGetRevisionResponseExample",
294
+ response: {
295
+ body: {
296
+ "@context": [
297
+ DocumentContexts.ContextRoot,
298
+ DocumentContexts.ContextRootCommon,
299
+ SchemaOrgContexts.ContextRoot
300
+ ],
301
+ type: DocumentTypes.Document,
302
+ id: "2721000:0",
303
+ documentId: "2721000",
304
+ documentIdFormat: "bol",
305
+ documentCode: UneceDocumentCodes.BillOfLading,
306
+ documentRevision: 1,
307
+ blobStorageId: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
308
+ blobHash: "sha256:123456",
309
+ dateCreated: "2024-01-01T00:00:00Z",
310
+ annotationObject: {
311
+ "@context": "https://schema.org",
312
+ "@type": "DigitalDocument",
313
+ name: "myfile.pdf"
314
+ },
315
+ nodeIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363",
316
+ userIdentity: "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363"
317
+ }
318
+ }
319
+ }
320
+ ]
321
+ },
322
+ {
323
+ type: "INotFoundResponse"
324
+ }
325
+ ]
326
+ };
327
+ const documentManagementRemoveRevisionRoute = {
226
328
  operationId: "DocumentManagementRemove",
227
329
  summary: "Remove an document from an auditable item graph vertex",
228
330
  tag: tagsDocumentManagement[0].name,
@@ -273,98 +375,76 @@ function generateRestRoutesDocumentManagement(baseRouteName, componentName) {
273
375
  ]
274
376
  },
275
377
  responseType: [
276
- // {
277
- // type: nameof<IDocumentManagementQueryResponse>(),
278
- // examples: [
279
- // {
280
- // id: "DocumentManagementQueryResponseExample",
281
- // response: {
282
- // body: {
283
- // "@context": [DocumentContexts.ContextRoot, DocumentContexts.ContextRootCommon],
284
- // type: DocumentTypes.DocumentList,
285
- // documents: [
286
- // {
287
- // "@context": [
288
- // DocumentContexts.ContextRoot,
289
- // DocumentContexts.ContextRootCommon,
290
- // SchemaOrgContexts.ContextRoot
291
- // ],
292
- // type: DocumentTypes.Document,
293
- // id: "2721000:0",
294
- // documentId: "2721000",
295
- // documentIdFormat: "bol",
296
- // documentCode: UneceDocumentCodes.BillOfLading,
297
- // documentRevision: 0,
298
- // blobStorageId:
299
- // "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
300
- // blobHash: "sha256:123456",
301
- // dateCreated: "2024-01-01T00:00:00Z",
302
- // annotationObject: {
303
- // "@context": "https://schema.org",
304
- // "@type": "DigitalDocument",
305
- // name: "myfile.pdf"
306
- // },
307
- // nodeIdentity:
308
- // "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363",
309
- // userIdentity:
310
- // "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363"
311
- // }
312
- // ]
313
- // }
314
- // }
315
- // }
316
- // ]
317
- // },
318
- // {
319
- // type: nameof<IDocumentManagementQueryResponse>(),
320
- // mimeType: MimeTypes.JsonLd,
321
- // examples: [
322
- // {
323
- // id: "DocumentManagementListResponseJsonLdExample",
324
- // response: {
325
- // body: {
326
- // "@context": [DocumentContexts.ContextRoot, DocumentContexts.ContextRootCommon],
327
- // type: DocumentTypes.DocumentList,
328
- // documents: [
329
- // {
330
- // "@context": [
331
- // DocumentContexts.ContextRoot,
332
- // DocumentContexts.ContextRootCommon,
333
- // SchemaOrgContexts.ContextRoot
334
- // ],
335
- // type: DocumentTypes.Document,
336
- // id: "2721000:0",
337
- // documentId: "2721000",
338
- // documentIdFormat: "bol",
339
- // documentCode: UneceDocumentCodes.BillOfLading,
340
- // documentRevision: 0,
341
- // blobStorageId:
342
- // "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
343
- // blobHash: "sha256:123456",
344
- // dateCreated: "2024-01-01T00:00:00Z",
345
- // annotationObject: {
346
- // "@context": "https://schema.org",
347
- // "@type": "DigitalDocument",
348
- // name: "myfile.pdf"
349
- // },
350
- // nodeIdentity:
351
- // "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363",
352
- // userIdentity:
353
- // "did:entity-storage:0x6363636363636363636363636363636363636363636363636363636363636363"
354
- // }
355
- // ]
356
- // }
357
- // }
358
- // }
359
- // ]
360
- // }
378
+ {
379
+ type: "IDocumentManagementQueryResponse",
380
+ examples: [
381
+ {
382
+ id: "DocumentManagementQueryResponseExample",
383
+ response: {
384
+ body: {
385
+ "@context": [SchemaOrgContexts.ContextRoot, AuditableItemGraphContexts.ContextRoot],
386
+ type: [SchemaOrgTypes.ItemList, AuditableItemGraphTypes.VertexList],
387
+ [SchemaOrgTypes.ItemListElement]: [
388
+ {
389
+ "@context": [
390
+ AuditableItemGraphContexts.ContextRoot,
391
+ AuditableItemGraphContexts.ContextRootCommon
392
+ ],
393
+ id: "aig:c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7",
394
+ type: AuditableItemGraphTypes.Vertex,
395
+ dateCreated: "2024-08-22T04:13:20.000Z",
396
+ aliases: [
397
+ {
398
+ "@context": [AuditableItemGraphContexts.ContextRoot],
399
+ id: "test-id-0",
400
+ type: AuditableItemGraphTypes.Alias,
401
+ dateCreated: "2024-08-22T04:13:20.000Z"
402
+ }
403
+ ],
404
+ resources: [
405
+ {
406
+ "@context": AuditableItemGraphContexts.ContextRoot,
407
+ type: AuditableItemGraphTypes.Resource,
408
+ dateCreated: "2024-08-22T04:13:20.000Z",
409
+ resourceObject: {
410
+ "@context": [
411
+ "https://schema.twindev.org/documents/",
412
+ "https://schema.twindev.org/common/",
413
+ "https://schema.org"
414
+ ],
415
+ type: "Document",
416
+ id: "test-id-0:0",
417
+ documentId: "test-id-0",
418
+ documentCode: "unece:DocumentCodeList#705",
419
+ documentRevision: 0,
420
+ annotationObject: {
421
+ "@context": "https://schema.org",
422
+ type: "DigitalDocument",
423
+ name: "bill-of-lading"
424
+ },
425
+ blobHash: "sha256:E3Duqrp6bHojSx+CzDttAToAiP1eFkCDAPBbKLABVGM=",
426
+ blobStorageId: "blob:memory:1370eeaaba7a6c7a234b1f82cc3b6d013a0088fd5e16408300f05b28b0015463",
427
+ dateCreated: "2024-08-22T04:13:20.000Z",
428
+ nodeIdentity: "did:entity-storage:0x0101010101010101010101010101010101010101010101010101010101010101",
429
+ userIdentity: "did:entity-storage:0x0404040404040404040404040404040404040404040404040404040404040404"
430
+ }
431
+ }
432
+ ]
433
+ }
434
+ ]
435
+ }
436
+ }
437
+ }
438
+ ]
439
+ }
361
440
  ]
362
441
  };
363
442
  return [
364
443
  documentManagementCreateRoute,
365
444
  documentManagementUpdateRoute,
366
445
  documentManagementGetRoute,
367
- documentManagementRemoveRoute,
446
+ documentManagementGetRevisionRoute,
447
+ documentManagementRemoveRevisionRoute,
368
448
  documentManagementQueryRoute
369
449
  ];
370
450
  }
@@ -409,7 +489,9 @@ async function documentManagementGet(httpRequestContext, componentName, request)
409
489
  includeBlobStorageMetadata: Coerce.boolean(request.query?.includeBlobStorageMetadata),
410
490
  includeBlobStorageData: Coerce.boolean(request.query?.includeBlobStorageData),
411
491
  includeAttestation: Coerce.boolean(request.query?.includeAttestation),
412
- includeRemoved: Coerce.boolean(request.query?.includeRemoved)
492
+ includeRemoved: Coerce.boolean(request.query?.includeRemoved),
493
+ extractRuleGroupId: request.query?.extractRuleGroupId,
494
+ extractMimeType: request.query?.extractMimeType
413
495
  }, request.query?.cursor, Coerce.integer(request.query?.pageSize), httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
414
496
  return {
415
497
  headers: {
@@ -419,7 +501,36 @@ async function documentManagementGet(httpRequestContext, componentName, request)
419
501
  };
420
502
  }
421
503
  /**
422
- * UPdate the document from the auditable item graph vertex.
504
+ * Get the document revision from the auditable item graph vertex.
505
+ * @param httpRequestContext The request context for the API.
506
+ * @param componentName The name of the component to use in the routes.
507
+ * @param request The request.
508
+ * @returns The response object with additional http response properties.
509
+ */
510
+ async function documentManagementGetRevision(httpRequestContext, componentName, request) {
511
+ Guards.object(ROUTES_SOURCE, "request", request);
512
+ Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
513
+ Guards.stringValue(ROUTES_SOURCE, "request.pathParams.auditableItemGraphDocumentId", request.pathParams.auditableItemGraphDocumentId);
514
+ const revision = Coerce.integer(request.pathParams.revision);
515
+ Guards.integer(ROUTES_SOURCE, "revision", revision);
516
+ const mimeType = request.headers?.[HeaderTypes.Accept] === MimeTypes.JsonLd ? "jsonld" : "json";
517
+ const component = ComponentFactory.get(componentName);
518
+ const result = await component.getRevision(request.pathParams.auditableItemGraphDocumentId, revision, {
519
+ includeBlobStorageMetadata: Coerce.boolean(request.query?.includeBlobStorageMetadata),
520
+ includeBlobStorageData: Coerce.boolean(request.query?.includeBlobStorageData),
521
+ includeAttestation: Coerce.boolean(request.query?.includeAttestation),
522
+ extractRuleGroupId: request.query?.extractRuleGroupId,
523
+ extractMimeType: request.query?.extractMimeType
524
+ }, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
525
+ return {
526
+ headers: {
527
+ [HeaderTypes.ContentType]: mimeType === "json" ? MimeTypes.Json : MimeTypes.JsonLd
528
+ },
529
+ body: result
530
+ };
531
+ }
532
+ /**
533
+ * Update the document from the auditable item graph vertex.
423
534
  * @param httpRequestContext The request context for the API.
424
535
  * @param componentName The name of the component to use in the routes.
425
536
  * @param request The request.
@@ -480,10 +591,6 @@ async function documentManagementQuery(httpRequestContext, componentName, reques
480
591
  * Service for performing document management operations.
481
592
  */
482
593
  class DocumentManagementService {
483
- /**
484
- * The namespace supported by the document management service.
485
- */
486
- static NAMESPACE = "documents";
487
594
  /**
488
595
  * Runtime name for the class.
489
596
  */
@@ -503,6 +610,11 @@ class DocumentManagementService {
503
610
  * @internal
504
611
  */
505
612
  _attestationComponent;
613
+ /**
614
+ * The connector for the data processing.
615
+ * @internal
616
+ */
617
+ _dataProcessingComponent;
506
618
  /**
507
619
  * Create a new instance of DocumentManagementService.
508
620
  * @param options The options for the service.
@@ -511,6 +623,7 @@ class DocumentManagementService {
511
623
  this._auditableItemGraphComponent = ComponentFactory.get(options?.auditableItemGraphComponentType ?? "auditable-item-graph");
512
624
  this._blobStorageComponent = ComponentFactory.get(options?.blobStorageComponentType ?? "blob-storage");
513
625
  this._attestationComponent = ComponentFactory.get(options?.attestationComponentType ?? "attestation");
626
+ this._dataProcessingComponent = ComponentFactory.get(options?.dataProcessingComponentType ?? "data-processing");
514
627
  SchemaOrgDataTypes.registerRedirects();
515
628
  }
516
629
  /**
@@ -565,7 +678,7 @@ class DocumentManagementService {
565
678
  SchemaOrgContexts.ContextRoot
566
679
  ],
567
680
  type: DocumentTypes.Document,
568
- id: `${documentId}:0`,
681
+ id: this.createDocumentId(documentId, 0),
569
682
  documentId,
570
683
  documentIdFormat,
571
684
  documentCode,
@@ -619,12 +732,13 @@ class DocumentManagementService {
619
732
  Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
620
733
  Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
621
734
  try {
622
- const documentVertex = await this._auditableItemGraphComponent.get(auditableItemGraphDocumentId);
735
+ const documentVertex = await this._auditableItemGraphComponent.get(auditableItemGraphDocumentId, { includeDeleted: true });
623
736
  if (Is.empty(documentVertex.resources)) {
624
737
  throw new NotFoundError(this.CLASS_NAME, "documentRevisionNone");
625
738
  }
626
739
  const documents = await this.getDocumentsFromVertex(documentVertex);
627
- const latestRevision = documents.documents[0];
740
+ const latestRevision = documents.itemListElement[0];
741
+ documentVertex.resources = documentVertex.resources.filter(r => Is.empty(r.dateDeleted));
628
742
  if (Is.empty(latestRevision)) {
629
743
  throw new NotFoundError(this.CLASS_NAME, "documentRevisionNone");
630
744
  }
@@ -655,7 +769,7 @@ class DocumentManagementService {
655
769
  const blobStorageId = await this._blobStorageComponent.create(Converter.bytesToBase64(blob), undefined, undefined, undefined, undefined, userIdentity, nodeIdentity);
656
770
  const newRevision = ObjectHelper.clone(latestRevision);
657
771
  newRevision.documentRevision++;
658
- newRevision.id = `${newRevision.documentId}:${newRevision.documentRevision}`;
772
+ newRevision.id = this.createDocumentId(newRevision.documentId, newRevision.documentRevision);
659
773
  newRevision.blobHash = newBlobHash;
660
774
  newRevision.blobStorageId = blobStorageId;
661
775
  newRevision.annotationObject = annotationObject;
@@ -706,6 +820,8 @@ class DocumentManagementService {
706
820
  * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
707
821
  * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
708
822
  * @param options.includeRemoved Flag to include deleted documents, defaults to false.
823
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
824
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
709
825
  * @param cursor The cursor to get the next chunk of revisions.
710
826
  * @param pageSize Page size of items to return, defaults to 1 so only most recent is returned.
711
827
  * @param userIdentity The identity to perform the auditable item graph operation with.
@@ -727,6 +843,43 @@ class DocumentManagementService {
727
843
  throw new GeneralError(this.CLASS_NAME, "getFailed", undefined, error);
728
844
  }
729
845
  }
846
+ /**
847
+ * Get a document revision using it's auditable item graph vertex id.
848
+ * @param auditableItemGraphDocumentId The auditable item graph vertex id which contains the document.
849
+ * @param revision The revision id for the document.
850
+ * @param options Additional options for the get operation.
851
+ * @param options.includeBlobStorageMetadata Flag to include the blob storage metadata for the document, defaults to false.
852
+ * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
853
+ * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
854
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
855
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
856
+ * @param userIdentity The identity to perform the auditable item graph operation with.
857
+ * @param nodeIdentity The node identity to use for vault operations.
858
+ * @returns The documents and revisions if requested, ordered by revision descending, cursor is set if there are more document revisions.
859
+ */
860
+ async getRevision(auditableItemGraphDocumentId, revision, options, userIdentity, nodeIdentity) {
861
+ Urn.guard(this.CLASS_NAME, "auditableItemGraphDocumentId", auditableItemGraphDocumentId);
862
+ Guards.integer(this.CLASS_NAME, "revision", revision);
863
+ try {
864
+ const documentVertex = await this._auditableItemGraphComponent.get(auditableItemGraphDocumentId, { includeDeleted: true });
865
+ if (Is.empty(documentVertex.resources)) {
866
+ throw new NotFoundError(this.CLASS_NAME, "documentRevisionNone");
867
+ }
868
+ documentVertex.resources = documentVertex.resources.filter(d => d.resourceObject?.documentRevision === revision);
869
+ if (documentVertex.resources.length === 0) {
870
+ throw new NotFoundError(this.CLASS_NAME, "documentRevisionNotFound", revision.toString());
871
+ }
872
+ // Populate the document and revisions with the options set
873
+ const docList = await this.getDocumentsFromVertex(documentVertex, options, undefined, undefined, userIdentity, nodeIdentity);
874
+ return JsonLdProcessor.compact(docList.itemListElement[0], docList.itemListElement[0]["@context"]);
875
+ }
876
+ catch (error) {
877
+ if (BaseError.someErrorName(error, "NotFoundError")) {
878
+ throw error;
879
+ }
880
+ throw new GeneralError(this.CLASS_NAME, "getRevisionFailed", undefined, error);
881
+ }
882
+ }
730
883
  /**
731
884
  * Remove an auditable item graph vertex using it's id.
732
885
  * The document dateDeleted will be set, but can still be queried with the includeRemoved flag.
@@ -939,7 +1092,8 @@ class DocumentManagementService {
939
1092
  * @param options.includeBlobStorageMetadata Flag to include the blob storage metadata for the document, defaults to false.
940
1093
  * @param options.includeBlobStorageData Flag to include the blob storage data for the document, defaults to false.
941
1094
  * @param options.includeAttestation Flag to include the attestation information for the document, defaults to false.
942
- * @param options.includeRemoved Flag to include deleted documents, defaults to false.
1095
+ * @param options.extractRuleGroupId If provided will extract data from the document using the specified rule group id.
1096
+ * @param options.extractMimeType By default extraction will auto detect the mime type of the document, this can be used to override the detection.
943
1097
  * @param cursor The cursor to get the next chunk of revisions.
944
1098
  * @param pageSize Page size of items to return, defaults to 1 so only most recent is returned.
945
1099
  * @param userIdentity The identity to perform the auditable item graph operation with.
@@ -950,12 +1104,12 @@ class DocumentManagementService {
950
1104
  async getDocumentsFromVertex(documentVertex, options, cursor, pageSize, userIdentity, nodeIdentity) {
951
1105
  const docList = {
952
1106
  "@context": [
1107
+ SchemaOrgContexts.ContextRoot,
953
1108
  DocumentContexts.ContextRoot,
954
- DocumentContexts.ContextRootCommon,
955
- SchemaOrgContexts.ContextRoot
1109
+ DocumentContexts.ContextRootCommon
956
1110
  ],
957
- type: DocumentTypes.DocumentList,
958
- documents: []
1111
+ type: SchemaOrgTypes.ItemList,
1112
+ [SchemaOrgTypes.ItemListElement]: []
959
1113
  };
960
1114
  if (Is.arrayValue(documentVertex.resources)) {
961
1115
  // Sort by newest revision first
@@ -964,20 +1118,39 @@ class DocumentManagementService {
964
1118
  const startIndex = Coerce.integer(cursor) ?? 0;
965
1119
  const endIndex = Math.min(startIndex + (pageSize ?? 1), documentVertex.resources.length);
966
1120
  const slicedResources = documentVertex.resources.slice(startIndex, endIndex);
967
- docList.cursor =
1121
+ docList[SchemaOrgTypes.NextItem] =
968
1122
  documentVertex.resources.length > endIndex ? (endIndex + 1).toString() : undefined;
969
1123
  const includeBlobStorageMetadata = options?.includeBlobStorageMetadata ?? false;
970
1124
  const includeBlobStorageData = options?.includeBlobStorageData ?? false;
971
1125
  const includeAttestation = options?.includeAttestation ?? false;
1126
+ const extractData = Is.stringValue(options?.extractRuleGroupId);
972
1127
  for (let i = 0; i < slicedResources.length; i++) {
973
1128
  const document = slicedResources[i].resourceObject;
974
1129
  if (Is.object(document)) {
975
- docList.documents.push(document);
976
- if (includeBlobStorageMetadata || includeBlobStorageData) {
977
- const blobEntry = await this._blobStorageComponent.get(document.blobStorageId, includeBlobStorageData, userIdentity, nodeIdentity);
978
- document.blobStorageEntry = blobEntry;
979
- if (!docList["@context"].includes(BlobStorageContexts.ContextRoot)) {
980
- docList["@context"].push(BlobStorageContexts.ContextRoot);
1130
+ document.dateDeleted = slicedResources[i].dateDeleted;
1131
+ docList[SchemaOrgTypes.ItemListElement].push(document);
1132
+ const blobRequired = includeBlobStorageMetadata || includeBlobStorageData;
1133
+ if (blobRequired || extractData) {
1134
+ const blobEntry = await this._blobStorageComponent.get(document.blobStorageId, {
1135
+ includeContent: includeBlobStorageData || extractData
1136
+ }, userIdentity, nodeIdentity);
1137
+ if (blobRequired) {
1138
+ document.blobStorageEntry = blobEntry;
1139
+ if (!docList["@context"].includes(BlobStorageContexts.ContextRoot)) {
1140
+ docList["@context"].push(BlobStorageContexts.ContextRoot);
1141
+ }
1142
+ }
1143
+ if (Is.stringValue(options?.extractRuleGroupId) && Is.stringValue(blobEntry.blob)) {
1144
+ const binaryBlob = Converter.base64ToBytes(blobEntry.blob);
1145
+ document.extractedData = await this._dataProcessingComponent.extract(options.extractRuleGroupId, binaryBlob, undefined, options?.extractMimeType);
1146
+ }
1147
+ // If we have the blob data due to extraction but we weren't asked for it
1148
+ // then we remove it from the document
1149
+ if (!blobRequired) {
1150
+ delete document.blobStorageEntry;
1151
+ }
1152
+ else if (!includeBlobStorageData) {
1153
+ delete document.blobStorageEntry?.blob;
981
1154
  }
982
1155
  }
983
1156
  if (includeAttestation && Is.stringValue(document.attestationId)) {
@@ -1024,15 +1197,26 @@ class DocumentManagementService {
1024
1197
  };
1025
1198
  return this._attestationComponent.create(documentAttestation, undefined, userIdentity, nodeIdentity);
1026
1199
  }
1200
+ /**
1201
+ * Create a document id from the document id and revision.
1202
+ * @param documentId The document id to create.
1203
+ * @param revision The revision of the document.
1204
+ * @returns The document id.
1205
+ * @internal
1206
+ */
1207
+ createDocumentId(documentId, revision) {
1208
+ const documentIdHash = Converter.bytesToBase64Url(Sha256.sum256(Converter.utf8ToBytes(documentId)));
1209
+ return `document:${documentIdHash}:${revision}`;
1210
+ }
1027
1211
  }
1028
1212
 
1029
1213
  const restEntryPoints = [
1030
1214
  {
1031
- name: "documents",
1032
- defaultBaseRoute: "documents",
1215
+ name: "document-management",
1216
+ defaultBaseRoute: "document-management",
1033
1217
  tags: tagsDocumentManagement,
1034
1218
  generateRoutes: generateRestRoutesDocumentManagement
1035
1219
  }
1036
1220
  ];
1037
1221
 
1038
- export { DocumentManagementService, documentManagementCreate, documentManagementGet, documentManagementQuery, documentManagementRemove, documentManagementUpdate, generateRestRoutesDocumentManagement, restEntryPoints, tagsDocumentManagement };
1222
+ export { DocumentManagementService, documentManagementCreate, documentManagementGet, documentManagementGetRevision, documentManagementQuery, documentManagementRemove, documentManagementUpdate, generateRestRoutesDocumentManagement, restEntryPoints, tagsDocumentManagement };
@@ -1,5 +1,5 @@
1
1
  import type { ICreatedResponse, IHttpRequestContext, INoContentResponse, IRestRoute, ITag } from "@twin.org/api-models";
2
- import { type IDocumentManagementCreateRequest, type IDocumentManagementGetRequest, type IDocumentManagementGetResponse, type IDocumentManagementQueryRequest, type IDocumentManagementQueryResponse, type IDocumentManagementRemoveRequest, type IDocumentManagementUpdateRequest } from "@twin.org/document-management-models";
2
+ import { type IDocumentManagementGetRevisionRequest, type IDocumentManagementGetRevisionResponse, type IDocumentManagementCreateRequest, type IDocumentManagementGetRequest, type IDocumentManagementGetResponse, type IDocumentManagementQueryRequest, type IDocumentManagementQueryResponse, type IDocumentManagementRemoveRequest, type IDocumentManagementUpdateRequest } from "@twin.org/document-management-models";
3
3
  /**
4
4
  * The tag to associate with the routes.
5
5
  */
@@ -28,7 +28,15 @@ export declare function documentManagementCreate(httpRequestContext: IHttpReques
28
28
  */
29
29
  export declare function documentManagementGet(httpRequestContext: IHttpRequestContext, componentName: string, request: IDocumentManagementGetRequest): Promise<IDocumentManagementGetResponse>;
30
30
  /**
31
- * UPdate the document from the auditable item graph vertex.
31
+ * Get the document revision from the auditable item graph vertex.
32
+ * @param httpRequestContext The request context for the API.
33
+ * @param componentName The name of the component to use in the routes.
34
+ * @param request The request.
35
+ * @returns The response object with additional http response properties.
36
+ */
37
+ export declare function documentManagementGetRevision(httpRequestContext: IHttpRequestContext, componentName: string, request: IDocumentManagementGetRevisionRequest): Promise<IDocumentManagementGetRevisionResponse>;
38
+ /**
39
+ * Update the document from the auditable item graph vertex.
32
40
  * @param httpRequestContext The request context for the API.
33
41
  * @param componentName The name of the component to use in the routes.
34
42
  * @param request The request.