@twin.org/blob-storage-service 0.0.1-next.21 → 0.0.1-next.23

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.
@@ -5,6 +5,7 @@ var blobStorageModels = require('@twin.org/blob-storage-models');
5
5
  var core = require('@twin.org/core');
6
6
  var standardsSchemaOrg = require('@twin.org/standards-schema-org');
7
7
  var web = require('@twin.org/web');
8
+ var crypto = require('@twin.org/crypto');
8
9
  var dataJsonLd = require('@twin.org/data-json-ld');
9
10
  var entity = require('@twin.org/entity');
10
11
  var entityStorageModels = require('@twin.org/entity-storage-models');
@@ -53,7 +54,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName, options) {
53
54
  request: {
54
55
  body: {
55
56
  blob: "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw==",
56
- metadata: {
57
+ annotationObject: {
57
58
  "@context": "https://schema.org",
58
59
  "@type": "DigitalDocument",
59
60
  name: "myfile.pdf"
@@ -82,7 +83,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName, options) {
82
83
  };
83
84
  const blobStorageGetRoute = {
84
85
  operationId: `${camelTypeName}Get`,
85
- summary: `Get the metadata for an item from ${lowerName}`,
86
+ summary: `Get the annotation for an item from ${lowerName}`,
86
87
  tag: options?.tagName ?? tagsBlobStorage[0].name,
87
88
  method: "GET",
88
89
  path: `${baseRouteName}/:id`,
@@ -111,14 +112,19 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName, options) {
111
112
  id: `${camelTypeName}GetResponseExample`,
112
113
  response: {
113
114
  body: {
114
- "@context": [blobStorageModels.BlobStorageTypes.ContextRoot, standardsSchemaOrg.SchemaOrgTypes.ContextRoot],
115
+ "@context": [
116
+ blobStorageModels.BlobStorageTypes.ContextRoot,
117
+ blobStorageModels.BlobStorageTypes.ContextRootCommon,
118
+ standardsSchemaOrg.SchemaOrgTypes.ContextRoot
119
+ ],
115
120
  type: blobStorageModels.BlobStorageTypes.Entry,
116
121
  id: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
117
122
  dateCreated: "2024-01-01T00:00:00Z",
118
123
  encodingFormat: web.MimeTypes.Pdf,
119
124
  blobSize: 42,
125
+ blobHash: "sha256:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
120
126
  fileExtension: "pdf",
121
- metadata: {
127
+ annotationObject: {
122
128
  "@context": "https://schema.org",
123
129
  "@type": "DigitalDocument",
124
130
  name: "myfile.pdf"
@@ -137,14 +143,19 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName, options) {
137
143
  id: `${camelTypeName}GetResponseJsonLdExample`,
138
144
  response: {
139
145
  body: {
140
- "@context": [blobStorageModels.BlobStorageTypes.ContextRoot, standardsSchemaOrg.SchemaOrgTypes.ContextRoot],
146
+ "@context": [
147
+ blobStorageModels.BlobStorageTypes.ContextRoot,
148
+ blobStorageModels.BlobStorageTypes.ContextRootCommon,
149
+ standardsSchemaOrg.SchemaOrgTypes.ContextRoot
150
+ ],
141
151
  type: blobStorageModels.BlobStorageTypes.Entry,
142
152
  id: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
143
153
  dateCreated: "2024-01-01T00:00:00Z",
144
154
  encodingFormat: web.MimeTypes.Pdf,
145
155
  blobSize: 42,
156
+ blobHash: "sha256:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
146
157
  fileExtension: "pdf",
147
- metadata: {
158
+ annotationObject: {
148
159
  "@context": "https://schema.org",
149
160
  "@type": "DigitalDocument",
150
161
  name: "myfile.pdf"
@@ -205,7 +216,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName, options) {
205
216
  };
206
217
  const blobStorageUpdateRoute = {
207
218
  operationId: `${camelTypeName}Update`,
208
- summary: `Update the metadata for an item in ${lowerName}`,
219
+ summary: `Update the annotation for an item in ${lowerName}`,
209
220
  tag: options?.tagName ?? tagsBlobStorage[0].name,
210
221
  method: "PUT",
211
222
  path: `${baseRouteName}/:id`,
@@ -220,7 +231,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName, options) {
220
231
  id: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70"
221
232
  },
222
233
  body: {
223
- metadata: {
234
+ annotationObject: {
224
235
  "@context": "https://schema.org",
225
236
  "@type": "DigitalDocument",
226
237
  name: "myfile.pdf"
@@ -289,18 +300,23 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName, options) {
289
300
  id: `${camelTypeName}ListResponseExample`,
290
301
  response: {
291
302
  body: {
292
- "@context": [blobStorageModels.BlobStorageTypes.ContextRoot],
303
+ "@context": [blobStorageModels.BlobStorageTypes.ContextRoot, blobStorageModels.BlobStorageTypes.ContextRootCommon],
293
304
  type: blobStorageModels.BlobStorageTypes.EntryList,
294
305
  entries: [
295
306
  {
296
- "@context": [blobStorageModels.BlobStorageTypes.ContextRoot, standardsSchemaOrg.SchemaOrgTypes.ContextRoot],
307
+ "@context": [
308
+ blobStorageModels.BlobStorageTypes.ContextRoot,
309
+ blobStorageModels.BlobStorageTypes.ContextRootCommon,
310
+ standardsSchemaOrg.SchemaOrgTypes.ContextRoot
311
+ ],
297
312
  type: blobStorageModels.BlobStorageTypes.Entry,
298
313
  id: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
299
314
  dateCreated: "2024-01-01T00:00:00Z",
300
315
  encodingFormat: web.MimeTypes.Pdf,
301
316
  blobSize: 42,
317
+ blobHash: "sha256:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
302
318
  fileExtension: "pdf",
303
- metadata: {
319
+ annotationObject: {
304
320
  "@context": "https://schema.org",
305
321
  "@type": "DigitalDocument",
306
322
  name: "myfile.pdf"
@@ -321,18 +337,23 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName, options) {
321
337
  id: `${camelTypeName}ListResponseJsonLdExample`,
322
338
  response: {
323
339
  body: {
324
- "@context": [blobStorageModels.BlobStorageTypes.ContextRoot],
340
+ "@context": [blobStorageModels.BlobStorageTypes.ContextRoot, blobStorageModels.BlobStorageTypes.ContextRootCommon],
325
341
  type: blobStorageModels.BlobStorageTypes.EntryList,
326
342
  entries: [
327
343
  {
328
- "@context": [blobStorageModels.BlobStorageTypes.ContextRoot, standardsSchemaOrg.SchemaOrgTypes.ContextRoot],
344
+ "@context": [
345
+ blobStorageModels.BlobStorageTypes.ContextRoot,
346
+ blobStorageModels.BlobStorageTypes.ContextRootCommon,
347
+ standardsSchemaOrg.SchemaOrgTypes.ContextRoot
348
+ ],
329
349
  type: blobStorageModels.BlobStorageTypes.Entry,
330
350
  id: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
331
351
  dateCreated: "2024-01-01T00:00:00Z",
332
352
  encodingFormat: web.MimeTypes.Pdf,
333
353
  blobSize: 42,
354
+ blobHash: "sha256:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70",
334
355
  fileExtension: "pdf",
335
- metadata: {
356
+ annotationObject: {
336
357
  "@context": "https://schema.org",
337
358
  "@type": "DigitalDocument",
338
359
  name: "myfile.pdf"
@@ -371,7 +392,7 @@ async function blobStorageCreate(httpRequestContext, componentName, request) {
371
392
  core.Guards.object(ROUTES_SOURCE, "request.body", request.body);
372
393
  core.Guards.stringBase64(ROUTES_SOURCE, "request.body.blob", request.body.blob);
373
394
  const component = core.ComponentFactory.get(componentName);
374
- const id = await component.create(request.body.blob, request.body.encodingFormat, request.body.fileExtension, request.body.metadata, request.body.namespace, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
395
+ const id = await component.create(request.body.blob, request.body.encodingFormat, request.body.fileExtension, request.body.annotationObject, request.body.namespace, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
375
396
  return {
376
397
  statusCode: web.HttpStatusCode.created,
377
398
  headers: {
@@ -428,7 +449,7 @@ async function blobStorageGetContent(httpRequestContext, componentName, request)
428
449
  };
429
450
  }
430
451
  /**
431
- * Update the blob storage metadata.
452
+ * Update the blob storage annotation.
432
453
  * @param httpRequestContext The request context for the API.
433
454
  * @param componentName The name of the component to use in the routes.
434
455
  * @param request The request.
@@ -439,7 +460,7 @@ async function blobStorageUpdate(httpRequestContext, componentName, request) {
439
460
  core.Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
440
461
  core.Guards.stringValue(ROUTES_SOURCE, "request.pathParams.id", request.pathParams.id);
441
462
  const component = core.ComponentFactory.get(componentName);
442
- await component.update(request.pathParams.id, request.body.encodingFormat, request.body.fileExtension, request.body.metadata, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
463
+ await component.update(request.pathParams.id, request.body.encodingFormat, request.body.fileExtension, request.body.annotationObject, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
443
464
  return {
444
465
  statusCode: web.HttpStatusCode.noContent
445
466
  };
@@ -502,7 +523,7 @@ class BlobStorageService {
502
523
  */
503
524
  _defaultNamespace;
504
525
  /**
505
- * The storage connector for the metadata.
526
+ * The storage connector for the annotation.
506
527
  * @internal
507
528
  */
508
529
  _entryEntityStorage;
@@ -546,17 +567,17 @@ class BlobStorageService {
546
567
  standardsSchemaOrg.SchemaOrgDataTypes.registerRedirects();
547
568
  }
548
569
  /**
549
- * Create the blob with some metadata.
570
+ * Create the blob with some annotation.
550
571
  * @param blob The data for the blob in base64 format.
551
572
  * @param encodingFormat Mime type for the blob, will be detected if left undefined.
552
573
  * @param fileExtension Extension for the blob, will be detected if left undefined.
553
- * @param metadata Data for the custom metadata as JSON-LD.
574
+ * @param annotationObject Data for the custom annotation as JSON-LD.
554
575
  * @param namespace The namespace to use for storing, defaults to component configured namespace.
555
576
  * @param userIdentity The user identity to use with storage operations.
556
577
  * @param nodeIdentity The node identity to use with storage operations.
557
578
  * @returns The id of the stored blob in urn format.
558
579
  */
559
- async create(blob, encodingFormat, fileExtension, metadata, namespace, userIdentity, nodeIdentity) {
580
+ async create(blob, encodingFormat, fileExtension, annotationObject, namespace, userIdentity, nodeIdentity) {
560
581
  core.Guards.stringBase64(this.CLASS_NAME, "blob", blob);
561
582
  if (this._includeUserIdentity) {
562
583
  core.Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
@@ -579,11 +600,12 @@ class BlobStorageService {
579
600
  if (!core.Is.stringValue(fileExtension) && core.Is.stringValue(encodingFormat)) {
580
601
  fileExtension = await web.MimeTypeHelper.defaultExtension(encodingFormat);
581
602
  }
582
- if (core.Is.object(metadata)) {
603
+ if (core.Is.object(annotationObject)) {
583
604
  const validationFailures = [];
584
- dataJsonLd.JsonLdHelper.validate(metadata, validationFailures);
585
- core.Validation.asValidationError(this.CLASS_NAME, "metadata", validationFailures);
605
+ dataJsonLd.JsonLdHelper.validate(annotationObject, validationFailures);
606
+ core.Validation.asValidationError(this.CLASS_NAME, "annotationObject", validationFailures);
586
607
  }
608
+ const blobHash = `sha256:${core.Converter.bytesToBase64(crypto.Sha256.sum256(storeBlob))}`;
587
609
  // If we have a vault connector then encrypt the data.
588
610
  if (this._vaultConnector) {
589
611
  storeBlob = await this._vaultConnector.encrypt(`${nodeIdentity}/${this._vaultKeyId}`, vaultModels.VaultEncryptionType.ChaCha20Poly1305, storeBlob);
@@ -595,9 +617,10 @@ class BlobStorageService {
595
617
  id: blobId,
596
618
  dateCreated: new Date(Date.now()).toISOString(),
597
619
  blobSize,
620
+ blobHash,
598
621
  encodingFormat,
599
622
  fileExtension,
600
- metadata
623
+ annotationObject
601
624
  };
602
625
  const conditions = [];
603
626
  if (this._includeUserIdentity) {
@@ -618,7 +641,7 @@ class BlobStorageService {
618
641
  /**
619
642
  * Get the blob entry.
620
643
  * @param id The id of the blob to get in urn format.
621
- * @param includeContent Include the content, or just get the metadata.
644
+ * @param includeContent Include the content, or just get the annotation.
622
645
  * @param userIdentity The user identity to use with storage operations.
623
646
  * @param nodeIdentity The node identity to use with storage operations.
624
647
  * @returns The entry and data for the blob if it can be found.
@@ -658,25 +681,24 @@ class BlobStorageService {
658
681
  }
659
682
  }
660
683
  const jsonLd = this.entryToJsonLd(blobEntry, returnBlob);
661
- const compacted = await dataJsonLd.JsonLdProcessor.compact(jsonLd, jsonLd["@context"]);
662
- return compacted;
684
+ return dataJsonLd.JsonLdProcessor.compact(jsonLd);
663
685
  }
664
686
  catch (error) {
665
687
  throw new core.GeneralError(this.CLASS_NAME, "getFailed", undefined, error);
666
688
  }
667
689
  }
668
690
  /**
669
- * Update the blob with metadata.
691
+ * Update the blob with annotation.
670
692
  * @param id The id of the blob entry to update.
671
693
  * @param encodingFormat Mime type for the blob, will be detected if left undefined.
672
694
  * @param fileExtension Extension for the blob, will be detected if left undefined.
673
- * @param metadata Data for the custom metadata as JSON-LD.
695
+ * @param annotationObject Data for the custom annotation as JSON-LD.
674
696
  * @param userIdentity The user identity to use with storage operations.
675
697
  * @param nodeIdentity The node identity to use with storage operations.
676
698
  * @returns Nothing.
677
699
  * @throws Not found error if the blob cannot be found.
678
700
  */
679
- async update(id, encodingFormat, fileExtension, metadata, userIdentity, nodeIdentity) {
701
+ async update(id, encodingFormat, fileExtension, annotationObject, userIdentity, nodeIdentity) {
680
702
  core.Urn.guard(this.CLASS_NAME, "id", id);
681
703
  if (this._includeUserIdentity) {
682
704
  core.Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
@@ -689,10 +711,10 @@ class BlobStorageService {
689
711
  if (core.Is.undefined(blobEntry)) {
690
712
  throw new core.NotFoundError(this.CLASS_NAME, "blobNotFound", id);
691
713
  }
692
- if (core.Is.object(metadata)) {
714
+ if (core.Is.object(annotationObject)) {
693
715
  const validationFailures = [];
694
- await dataJsonLd.JsonLdHelper.validate(metadata, validationFailures);
695
- core.Validation.asValidationError(this.CLASS_NAME, "metadata", validationFailures);
716
+ await dataJsonLd.JsonLdHelper.validate(annotationObject, validationFailures);
717
+ core.Validation.asValidationError(this.CLASS_NAME, "annotationObject", validationFailures);
696
718
  }
697
719
  // Now store the entry in entity storage
698
720
  const updatedBlobEntry = {
@@ -700,9 +722,10 @@ class BlobStorageService {
700
722
  dateCreated: blobEntry.dateCreated,
701
723
  dateModified: new Date(Date.now()).toISOString(),
702
724
  blobSize: blobEntry.blobSize,
725
+ blobHash: blobEntry.blobHash,
703
726
  encodingFormat: encodingFormat ?? blobEntry.encodingFormat,
704
727
  fileExtension: fileExtension ?? blobEntry.fileExtension,
705
- metadata: metadata ?? blobEntry.metadata
728
+ annotationObject: annotationObject ?? blobEntry.annotationObject
706
729
  };
707
730
  const conditions = [];
708
731
  if (this._includeUserIdentity) {
@@ -802,14 +825,17 @@ class BlobStorageService {
802
825
  core.ObjectHelper.propertyDelete(entity, "userIdentity");
803
826
  }
804
827
  const jsonLd = {
805
- "@context": [blobStorageModels.BlobStorageTypes.ContextRoot, standardsSchemaOrg.SchemaOrgTypes.ContextRoot],
828
+ "@context": [
829
+ blobStorageModels.BlobStorageTypes.ContextRoot,
830
+ blobStorageModels.BlobStorageTypes.ContextRootCommon,
831
+ standardsSchemaOrg.SchemaOrgTypes.ContextRoot
832
+ ],
806
833
  type: blobStorageModels.BlobStorageTypes.EntryList,
807
834
  // The entries are never Partial as we don't allow custom property requests.
808
835
  entries: result.entities.map(entry => this.entryToJsonLd(entry)),
809
836
  cursor: result.cursor
810
837
  };
811
- const compacted = await dataJsonLd.JsonLdProcessor.compact(jsonLd, jsonLd["@context"]);
812
- return compacted;
838
+ return dataJsonLd.JsonLdProcessor.compact(jsonLd);
813
839
  }
814
840
  /**
815
841
  * Get the connector from the uri.
@@ -888,15 +914,20 @@ class BlobStorageService {
888
914
  */
889
915
  entryToJsonLd(entry, blob) {
890
916
  return {
891
- "@context": [blobStorageModels.BlobStorageTypes.ContextRoot, standardsSchemaOrg.SchemaOrgTypes.ContextRoot],
917
+ "@context": [
918
+ blobStorageModels.BlobStorageTypes.ContextRoot,
919
+ blobStorageModels.BlobStorageTypes.ContextRootCommon,
920
+ standardsSchemaOrg.SchemaOrgTypes.ContextRoot
921
+ ],
892
922
  id: entry.id,
893
923
  type: blobStorageModels.BlobStorageTypes.Entry,
894
924
  dateCreated: entry.dateCreated,
895
925
  dateModified: entry.dateModified,
896
926
  blobSize: entry.blobSize,
927
+ blobHash: entry.blobHash,
897
928
  encodingFormat: entry?.encodingFormat,
898
929
  fileExtension: entry?.fileExtension,
899
- metadata: entry?.metadata,
930
+ annotationObject: entry?.annotationObject,
900
931
  blob: core.Is.uint8Array(blob) ? core.Converter.bytesToBase64(blob) : undefined
901
932
  };
902
933
  }
@@ -922,6 +953,10 @@ exports.BlobStorageEntry = class BlobStorageEntry {
922
953
  * The length of the data in the blob.
923
954
  */
924
955
  blobSize;
956
+ /**
957
+ * The hash of the data in the blob.
958
+ */
959
+ blobHash;
925
960
  /**
926
961
  * The mime type for the blob.
927
962
  */
@@ -931,9 +966,9 @@ exports.BlobStorageEntry = class BlobStorageEntry {
931
966
  */
932
967
  fileExtension;
933
968
  /**
934
- * The metadata for the blob as JSON-LD.
969
+ * The annotation object for the blob as JSON-LD.
935
970
  */
936
- metadata;
971
+ annotationObject;
937
972
  /**
938
973
  * The user identity that created the blob.
939
974
  */
@@ -959,6 +994,10 @@ __decorate([
959
994
  entity.property({ type: "number" }),
960
995
  __metadata("design:type", Number)
961
996
  ], exports.BlobStorageEntry.prototype, "blobSize", void 0);
997
+ __decorate([
998
+ entity.property({ type: "string" }),
999
+ __metadata("design:type", String)
1000
+ ], exports.BlobStorageEntry.prototype, "blobHash", void 0);
962
1001
  __decorate([
963
1002
  entity.property({ type: "string" }),
964
1003
  __metadata("design:type", String)
@@ -970,7 +1009,7 @@ __decorate([
970
1009
  __decorate([
971
1010
  entity.property({ type: "object", itemTypeRef: "IJsonLdNodeObject" }),
972
1011
  __metadata("design:type", Object)
973
- ], exports.BlobStorageEntry.prototype, "metadata", void 0);
1012
+ ], exports.BlobStorageEntry.prototype, "annotationObject", void 0);
974
1013
  __decorate([
975
1014
  entity.property({ type: "string" }),
976
1015
  __metadata("design:type", String)