@twin.org/blob-storage-service 0.0.1-next.8 → 0.0.1-next.9
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/cjs/index.cjs +200 -46
- package/dist/esm/index.mjs +201 -47
- package/dist/types/blobStorageRoutes.d.ts +7 -1
- package/dist/types/blobStorageService.d.ts +12 -6
- package/dist/types/entities/blobMetadata.d.ts +8 -0
- package/dist/types/models/IBlobStorageServiceConfig.d.ts +8 -0
- package/dist/types/restEntryPoints.d.ts +5 -0
- package/docs/changelog.md +1 -1
- package/docs/open-api/spec.json +10 -10
- package/docs/reference/classes/BlobMetadata.md +16 -0
- package/docs/reference/classes/BlobStorageService.md +30 -6
- package/docs/reference/functions/generateRestRoutesBlobStorage.md +13 -1
- package/docs/reference/interfaces/IBlobStorageServiceConfig.md +16 -0
- package/docs/reference/variables/restEntryPoints.md +4 -0
- package/package.json +2 -2
package/dist/cjs/index.cjs
CHANGED
|
@@ -4,9 +4,9 @@ var core = require('@twin.org/core');
|
|
|
4
4
|
var web = require('@twin.org/web');
|
|
5
5
|
var blobStorageModels = require('@twin.org/blob-storage-models');
|
|
6
6
|
var dataJsonLd = require('@twin.org/data-json-ld');
|
|
7
|
+
var entity = require('@twin.org/entity');
|
|
7
8
|
var entityStorageModels = require('@twin.org/entity-storage-models');
|
|
8
9
|
var vaultModels = require('@twin.org/vault-models');
|
|
9
|
-
var entity = require('@twin.org/entity');
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* The source used when communicating about these routes.
|
|
@@ -25,13 +25,19 @@ const tagsBlobStorage = [
|
|
|
25
25
|
* The REST routes for blob storage.
|
|
26
26
|
* @param baseRouteName Prefix to prepend to the paths.
|
|
27
27
|
* @param componentName The name of the component to use in the routes stored in the ComponentFactory.
|
|
28
|
+
* @param options Additional options for the routes.
|
|
29
|
+
* @param options.typeName Optional type name to use in the routes, defaults to Blob Storage.
|
|
30
|
+
* @param options.tagName Optional name to use in OpenAPI spec for tag.
|
|
28
31
|
* @returns The generated routes.
|
|
29
32
|
*/
|
|
30
|
-
function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
33
|
+
function generateRestRoutesBlobStorage(baseRouteName, componentName, options) {
|
|
34
|
+
const typeName = options?.typeName ?? "Blob Storage";
|
|
35
|
+
const lowerName = typeName.toLowerCase();
|
|
36
|
+
const camelTypeName = core.StringHelper.camelCase(typeName);
|
|
31
37
|
const blobStorageCreateRoute = {
|
|
32
|
-
operationId:
|
|
33
|
-
summary:
|
|
34
|
-
tag: tagsBlobStorage[0].name,
|
|
38
|
+
operationId: `${camelTypeName}Create`,
|
|
39
|
+
summary: `Create an entry in ${lowerName}`,
|
|
40
|
+
tag: options?.tagName ?? tagsBlobStorage[0].name,
|
|
35
41
|
method: "POST",
|
|
36
42
|
path: `${baseRouteName}/`,
|
|
37
43
|
handler: async (httpRequestContext, request) => blobStorageCreate(httpRequestContext, componentName, request),
|
|
@@ -39,7 +45,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
39
45
|
type: "IBlobStorageCreateRequest",
|
|
40
46
|
examples: [
|
|
41
47
|
{
|
|
42
|
-
id:
|
|
48
|
+
id: `${camelTypeName}CreateRequestExample`,
|
|
43
49
|
request: {
|
|
44
50
|
body: {
|
|
45
51
|
blob: "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw==",
|
|
@@ -58,7 +64,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
58
64
|
type: "ICreatedResponse",
|
|
59
65
|
examples: [
|
|
60
66
|
{
|
|
61
|
-
id:
|
|
67
|
+
id: `${camelTypeName}CreateResponseExample`,
|
|
62
68
|
response: {
|
|
63
69
|
statusCode: web.HttpStatusCode.created,
|
|
64
70
|
headers: {
|
|
@@ -71,9 +77,9 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
71
77
|
]
|
|
72
78
|
};
|
|
73
79
|
const blobStorageGetRoute = {
|
|
74
|
-
operationId:
|
|
75
|
-
summary:
|
|
76
|
-
tag: tagsBlobStorage[0].name,
|
|
80
|
+
operationId: `${camelTypeName}Get`,
|
|
81
|
+
summary: `Get the metadata for an item from ${lowerName}`,
|
|
82
|
+
tag: options?.tagName ?? tagsBlobStorage[0].name,
|
|
77
83
|
method: "GET",
|
|
78
84
|
path: `${baseRouteName}/:id`,
|
|
79
85
|
handler: async (httpRequestContext, request) => blobStorageGet(httpRequestContext, componentName, request),
|
|
@@ -81,7 +87,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
81
87
|
type: "IBlobStorageGetRequest",
|
|
82
88
|
examples: [
|
|
83
89
|
{
|
|
84
|
-
id:
|
|
90
|
+
id: `${camelTypeName}GetRequestExample`,
|
|
85
91
|
request: {
|
|
86
92
|
pathParams: {
|
|
87
93
|
id: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70"
|
|
@@ -98,7 +104,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
98
104
|
type: "IBlobStorageGetResponse",
|
|
99
105
|
examples: [
|
|
100
106
|
{
|
|
101
|
-
id:
|
|
107
|
+
id: `${camelTypeName}GetResponseExample`,
|
|
102
108
|
response: {
|
|
103
109
|
body: {
|
|
104
110
|
metadata: {
|
|
@@ -118,9 +124,9 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
118
124
|
]
|
|
119
125
|
};
|
|
120
126
|
const blobStorageGetContentRoute = {
|
|
121
|
-
operationId:
|
|
122
|
-
summary:
|
|
123
|
-
tag: tagsBlobStorage[0].name,
|
|
127
|
+
operationId: `${camelTypeName}GetContent`,
|
|
128
|
+
summary: `Get the content for an item in ${lowerName}`,
|
|
129
|
+
tag: options?.tagName ?? tagsBlobStorage[0].name,
|
|
124
130
|
method: "GET",
|
|
125
131
|
path: `${baseRouteName}/:id/content`,
|
|
126
132
|
handler: async (httpRequestContext, request) => blobStorageGetContent(httpRequestContext, componentName, request),
|
|
@@ -128,7 +134,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
128
134
|
type: "IBlobStorageGetRequest",
|
|
129
135
|
examples: [
|
|
130
136
|
{
|
|
131
|
-
id:
|
|
137
|
+
id: `${camelTypeName}GetContentRequestExample`,
|
|
132
138
|
request: {
|
|
133
139
|
pathParams: {
|
|
134
140
|
id: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70"
|
|
@@ -147,7 +153,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
147
153
|
mimeType: web.MimeTypes.OctetStream,
|
|
148
154
|
examples: [
|
|
149
155
|
{
|
|
150
|
-
id:
|
|
156
|
+
id: `${camelTypeName}GetContentResponseExample`,
|
|
151
157
|
description: `The content of the blob, which will be a specific mime type if one can be detected from the content (or set as mimeType in the metadata), or defaults to ${web.MimeTypes.OctetStream}.`,
|
|
152
158
|
response: {
|
|
153
159
|
body: new Uint8Array()
|
|
@@ -161,9 +167,9 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
161
167
|
]
|
|
162
168
|
};
|
|
163
169
|
const blobStorageUpdateRoute = {
|
|
164
|
-
operationId:
|
|
165
|
-
summary:
|
|
166
|
-
tag: tagsBlobStorage[0].name,
|
|
170
|
+
operationId: `${camelTypeName}Update`,
|
|
171
|
+
summary: `Update the metadata for an item in ${lowerName}`,
|
|
172
|
+
tag: options?.tagName ?? tagsBlobStorage[0].name,
|
|
167
173
|
method: "PUT",
|
|
168
174
|
path: `${baseRouteName}/:id`,
|
|
169
175
|
handler: async (httpRequestContext, request) => blobStorageUpdate(httpRequestContext, componentName, request),
|
|
@@ -171,7 +177,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
171
177
|
type: "IBlobStorageUpdateRequest",
|
|
172
178
|
examples: [
|
|
173
179
|
{
|
|
174
|
-
id:
|
|
180
|
+
id: `${camelTypeName}UpdateRequestExample`,
|
|
175
181
|
request: {
|
|
176
182
|
pathParams: {
|
|
177
183
|
id: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70"
|
|
@@ -194,9 +200,9 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
194
200
|
]
|
|
195
201
|
};
|
|
196
202
|
const blobStorageRemoveRoute = {
|
|
197
|
-
operationId:
|
|
198
|
-
summary:
|
|
199
|
-
tag: tagsBlobStorage[0].name,
|
|
203
|
+
operationId: `${camelTypeName}Remove`,
|
|
204
|
+
summary: `Remove an item from ${lowerName}`,
|
|
205
|
+
tag: options?.tagName ?? tagsBlobStorage[0].name,
|
|
200
206
|
method: "DELETE",
|
|
201
207
|
path: `${baseRouteName}/:id`,
|
|
202
208
|
handler: async (httpRequestContext, request) => blobStorageRemove(httpRequestContext, componentName, request),
|
|
@@ -204,7 +210,7 @@ function generateRestRoutesBlobStorage(baseRouteName, componentName) {
|
|
|
204
210
|
type: "IBlobStorageRemoveRequest",
|
|
205
211
|
examples: [
|
|
206
212
|
{
|
|
207
|
-
id:
|
|
213
|
+
id: `${camelTypeName}RemoveRequestExample`,
|
|
208
214
|
request: {
|
|
209
215
|
pathParams: {
|
|
210
216
|
id: "blob-memory:c57d94b088f4c6d2cb32ded014813d0c786aa00134c8ee22f84b1e2545602a70"
|
|
@@ -262,7 +268,7 @@ async function blobStorageGet(httpRequestContext, componentName, request) {
|
|
|
262
268
|
core.Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
|
|
263
269
|
core.Guards.stringValue(ROUTES_SOURCE, "request.pathParams.id", request.pathParams.id);
|
|
264
270
|
const component = core.ComponentFactory.get(componentName);
|
|
265
|
-
const result = await component.get(request.pathParams.id, request.query?.includeContent ?? false, httpRequestContext.nodeIdentity);
|
|
271
|
+
const result = await component.get(request.pathParams.id, request.query?.includeContent ?? false, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
|
|
266
272
|
return {
|
|
267
273
|
body: result
|
|
268
274
|
};
|
|
@@ -279,7 +285,7 @@ async function blobStorageGetContent(httpRequestContext, componentName, request)
|
|
|
279
285
|
core.Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
|
|
280
286
|
core.Guards.stringValue(ROUTES_SOURCE, "request.pathParams.id", request.pathParams.id);
|
|
281
287
|
const component = core.ComponentFactory.get(componentName);
|
|
282
|
-
const result = await component.get(request.pathParams.id, true, httpRequestContext.nodeIdentity);
|
|
288
|
+
const result = await component.get(request.pathParams.id, true, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
|
|
283
289
|
const mimeType = result?.mimeType ?? web.MimeTypes.OctetStream;
|
|
284
290
|
let filename = request.query?.filename;
|
|
285
291
|
if (!core.Is.stringValue(filename)) {
|
|
@@ -306,7 +312,7 @@ async function blobStorageUpdate(httpRequestContext, componentName, request) {
|
|
|
306
312
|
core.Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
|
|
307
313
|
core.Guards.stringValue(ROUTES_SOURCE, "request.pathParams.id", request.pathParams.id);
|
|
308
314
|
const component = core.ComponentFactory.get(componentName);
|
|
309
|
-
await component.update(request.pathParams.id, request.body.mimeType, request.body.extension, request.body.metadata);
|
|
315
|
+
await component.update(request.pathParams.id, request.body.mimeType, request.body.extension, request.body.metadata, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
|
|
310
316
|
return {
|
|
311
317
|
statusCode: web.HttpStatusCode.noContent
|
|
312
318
|
};
|
|
@@ -323,7 +329,7 @@ async function blobStorageRemove(httpRequestContext, componentName, request) {
|
|
|
323
329
|
core.Guards.object(ROUTES_SOURCE, "request.pathParams", request.pathParams);
|
|
324
330
|
core.Guards.stringValue(ROUTES_SOURCE, "request.pathParams.id", request.pathParams.id);
|
|
325
331
|
const component = core.ComponentFactory.get(componentName);
|
|
326
|
-
await component.remove(request.pathParams.id);
|
|
332
|
+
await component.remove(request.pathParams.id, httpRequestContext.userIdentity, httpRequestContext.nodeIdentity);
|
|
327
333
|
return {
|
|
328
334
|
statusCode: web.HttpStatusCode.noContent
|
|
329
335
|
};
|
|
@@ -364,6 +370,16 @@ class BlobStorageService {
|
|
|
364
370
|
* @internal
|
|
365
371
|
*/
|
|
366
372
|
_vaultKeyId;
|
|
373
|
+
/**
|
|
374
|
+
* Include the node identity when performing storage operations, defaults to true.
|
|
375
|
+
* @internal
|
|
376
|
+
*/
|
|
377
|
+
_includeNodeIdentity;
|
|
378
|
+
/**
|
|
379
|
+
* Include the user identity when performing storage operations, defaults to true.
|
|
380
|
+
* @internal
|
|
381
|
+
*/
|
|
382
|
+
_includeUserIdentity;
|
|
367
383
|
/**
|
|
368
384
|
* Create a new instance of BlobStorageService.
|
|
369
385
|
* @param options The dependencies for the service.
|
|
@@ -382,6 +398,8 @@ class BlobStorageService {
|
|
|
382
398
|
}
|
|
383
399
|
this._defaultNamespace = options?.config?.defaultNamespace ?? names[0];
|
|
384
400
|
this._vaultKeyId = options?.config?.vaultKeyId ?? "blob-storage";
|
|
401
|
+
this._includeNodeIdentity = options?.config?.includeNodeIdentity ?? true;
|
|
402
|
+
this._includeUserIdentity = options?.config?.includeUserIdentity ?? true;
|
|
385
403
|
}
|
|
386
404
|
/**
|
|
387
405
|
* Create the blob with some metadata.
|
|
@@ -390,12 +408,16 @@ class BlobStorageService {
|
|
|
390
408
|
* @param extension Extension for the blob, will be detected if left undefined.
|
|
391
409
|
* @param metadata Data for the custom metadata as JSON-LD.
|
|
392
410
|
* @param namespace The namespace to use for storing, defaults to component configured namespace.
|
|
393
|
-
* @param
|
|
411
|
+
* @param userIdentity The user identity to use with storage operations.
|
|
412
|
+
* @param nodeIdentity The node identity to use with storage operations.
|
|
394
413
|
* @returns The id of the stored blob in urn format.
|
|
395
414
|
*/
|
|
396
|
-
async create(blob, mimeType, extension, metadata, namespace, nodeIdentity) {
|
|
415
|
+
async create(blob, mimeType, extension, metadata, namespace, userIdentity, nodeIdentity) {
|
|
397
416
|
core.Guards.stringBase64(this.CLASS_NAME, "blob", blob);
|
|
398
|
-
if (this.
|
|
417
|
+
if (this._includeUserIdentity) {
|
|
418
|
+
core.Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
|
|
419
|
+
}
|
|
420
|
+
if (this._includeNodeIdentity || core.Is.notEmpty(this._vaultConnector)) {
|
|
399
421
|
core.Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
|
|
400
422
|
}
|
|
401
423
|
try {
|
|
@@ -423,12 +445,23 @@ class BlobStorageService {
|
|
|
423
445
|
}
|
|
424
446
|
// Set the blob in the storage connector, which may now be encrypted
|
|
425
447
|
const blobId = await blobStorageConnector.set(storeBlob);
|
|
426
|
-
|
|
448
|
+
// Now store the metadata in entity storage
|
|
449
|
+
const blobMetadata = {
|
|
427
450
|
id: blobId,
|
|
428
451
|
mimeType,
|
|
429
452
|
extension,
|
|
430
453
|
metadata
|
|
431
|
-
}
|
|
454
|
+
};
|
|
455
|
+
const conditions = [];
|
|
456
|
+
if (this._includeUserIdentity) {
|
|
457
|
+
core.ObjectHelper.propertySet(blobMetadata, "userIdentity", userIdentity);
|
|
458
|
+
conditions.push({ property: "userIdentity", value: userIdentity });
|
|
459
|
+
}
|
|
460
|
+
if (this._includeNodeIdentity) {
|
|
461
|
+
core.ObjectHelper.propertySet(blobMetadata, "nodeIdentity", nodeIdentity);
|
|
462
|
+
conditions.push({ property: "nodeIdentity", value: nodeIdentity });
|
|
463
|
+
}
|
|
464
|
+
await this._metadataEntityStorage.set(blobMetadata, conditions);
|
|
432
465
|
return blobId;
|
|
433
466
|
}
|
|
434
467
|
catch (error) {
|
|
@@ -439,18 +472,32 @@ class BlobStorageService {
|
|
|
439
472
|
* Get the blob and metadata.
|
|
440
473
|
* @param id The id of the blob to get in urn format.
|
|
441
474
|
* @param includeContent Include the content, or just get the metadata.
|
|
442
|
-
* @param
|
|
475
|
+
* @param userIdentity The user identity to use with storage operations.
|
|
476
|
+
* @param nodeIdentity The node identity to use with storage operations.
|
|
443
477
|
* @returns The metadata and data for the blob if it can be found.
|
|
444
478
|
* @throws Not found error if the blob cannot be found.
|
|
445
479
|
*/
|
|
446
|
-
async get(id, includeContent, nodeIdentity) {
|
|
480
|
+
async get(id, includeContent, userIdentity, nodeIdentity) {
|
|
447
481
|
core.Urn.guard(this.CLASS_NAME, "id", id);
|
|
448
|
-
|
|
482
|
+
const conditions = [];
|
|
483
|
+
if (this._includeUserIdentity) {
|
|
484
|
+
core.Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
|
|
485
|
+
conditions.push({
|
|
486
|
+
property: "userIdentity",
|
|
487
|
+
comparison: entity.ComparisonOperator.Equals,
|
|
488
|
+
value: userIdentity
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
if (this._includeNodeIdentity || (core.Is.notEmpty(this._vaultConnector) && includeContent)) {
|
|
449
492
|
core.Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
|
|
493
|
+
conditions.push({
|
|
494
|
+
property: "nodeIdentity",
|
|
495
|
+
comparison: entity.ComparisonOperator.Equals,
|
|
496
|
+
value: nodeIdentity
|
|
497
|
+
});
|
|
450
498
|
}
|
|
451
499
|
try {
|
|
452
|
-
|
|
453
|
-
const blobMetadata = await this._metadataEntityStorage.get(id);
|
|
500
|
+
const blobMetadata = await this.internalGet(id, userIdentity, nodeIdentity);
|
|
454
501
|
let returnBlob;
|
|
455
502
|
if (includeContent) {
|
|
456
503
|
const blobStorageConnector = this.getConnector(id);
|
|
@@ -480,11 +527,19 @@ class BlobStorageService {
|
|
|
480
527
|
* @param mimeType Mime type for the blob, will be detected if left undefined.
|
|
481
528
|
* @param extension Extension for the blob, will be detected if left undefined.
|
|
482
529
|
* @param metadata Data for the custom metadata as JSON-LD.
|
|
530
|
+
* @param userIdentity The user identity to use with storage operations.
|
|
531
|
+
* @param nodeIdentity The node identity to use with storage operations.
|
|
483
532
|
* @returns Nothing.
|
|
484
533
|
* @throws Not found error if the blob cannot be found.
|
|
485
534
|
*/
|
|
486
|
-
async update(id, mimeType, extension, metadata) {
|
|
535
|
+
async update(id, mimeType, extension, metadata, userIdentity, nodeIdentity) {
|
|
487
536
|
core.Urn.guard(this.CLASS_NAME, "id", id);
|
|
537
|
+
if (this._includeUserIdentity) {
|
|
538
|
+
core.Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
|
|
539
|
+
}
|
|
540
|
+
if (this._includeNodeIdentity || core.Is.notEmpty(this._vaultConnector)) {
|
|
541
|
+
core.Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
|
|
542
|
+
}
|
|
488
543
|
try {
|
|
489
544
|
const blobMetadata = await this._metadataEntityStorage.get(id);
|
|
490
545
|
if (core.Is.undefined(blobMetadata)) {
|
|
@@ -495,12 +550,23 @@ class BlobStorageService {
|
|
|
495
550
|
await dataJsonLd.JsonLdHelper.validate(metadata, validationFailures);
|
|
496
551
|
core.Validation.asValidationError(this.CLASS_NAME, "metadata", validationFailures);
|
|
497
552
|
}
|
|
498
|
-
|
|
553
|
+
// Now store the metadata in entity storage
|
|
554
|
+
const updatedBlobMetadata = {
|
|
499
555
|
id: blobMetadata.id,
|
|
500
556
|
mimeType: mimeType ?? blobMetadata.mimeType,
|
|
501
557
|
extension: extension ?? blobMetadata.extension,
|
|
502
558
|
metadata: metadata ?? blobMetadata.metadata
|
|
503
|
-
}
|
|
559
|
+
};
|
|
560
|
+
const conditions = [];
|
|
561
|
+
if (this._includeUserIdentity) {
|
|
562
|
+
core.ObjectHelper.propertySet(updatedBlobMetadata, "userIdentity", userIdentity);
|
|
563
|
+
conditions.push({ property: "userIdentity", value: userIdentity });
|
|
564
|
+
}
|
|
565
|
+
if (this._includeNodeIdentity) {
|
|
566
|
+
core.ObjectHelper.propertySet(updatedBlobMetadata, "nodeIdentity", nodeIdentity);
|
|
567
|
+
conditions.push({ property: "nodeIdentity", value: nodeIdentity });
|
|
568
|
+
}
|
|
569
|
+
await this._metadataEntityStorage.set(updatedBlobMetadata, conditions);
|
|
504
570
|
}
|
|
505
571
|
catch (error) {
|
|
506
572
|
throw new core.GeneralError(this.CLASS_NAME, "updateFailed", undefined, error);
|
|
@@ -509,17 +575,32 @@ class BlobStorageService {
|
|
|
509
575
|
/**
|
|
510
576
|
* Remove the blob.
|
|
511
577
|
* @param id The id of the blob to remove in urn format.
|
|
578
|
+
* @param userIdentity The user identity to use with storage operations.
|
|
579
|
+
* @param nodeIdentity The node identity to use with storage operations.
|
|
512
580
|
* @returns Nothing.
|
|
513
581
|
*/
|
|
514
|
-
async remove(id) {
|
|
582
|
+
async remove(id, userIdentity, nodeIdentity) {
|
|
515
583
|
core.Urn.guard(this.CLASS_NAME, "id", id);
|
|
584
|
+
if (this._includeUserIdentity) {
|
|
585
|
+
core.Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
|
|
586
|
+
}
|
|
587
|
+
if (this._includeNodeIdentity || core.Is.notEmpty(this._vaultConnector)) {
|
|
588
|
+
core.Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
|
|
589
|
+
}
|
|
516
590
|
try {
|
|
517
591
|
const blobStorageConnector = this.getConnector(id);
|
|
592
|
+
const conditions = [];
|
|
593
|
+
if (this._includeUserIdentity) {
|
|
594
|
+
conditions.push({ property: "userIdentity", value: userIdentity });
|
|
595
|
+
}
|
|
596
|
+
if (this._includeNodeIdentity) {
|
|
597
|
+
conditions.push({ property: "nodeIdentity", value: nodeIdentity });
|
|
598
|
+
}
|
|
599
|
+
await this._metadataEntityStorage.remove(id, conditions);
|
|
518
600
|
const removed = await blobStorageConnector.remove(id);
|
|
519
601
|
if (!removed) {
|
|
520
602
|
throw new core.NotFoundError(this.CLASS_NAME, "blobNotFound", id);
|
|
521
603
|
}
|
|
522
|
-
await this._metadataEntityStorage.remove(id);
|
|
523
604
|
}
|
|
524
605
|
catch (error) {
|
|
525
606
|
throw new core.GeneralError(this.CLASS_NAME, "removeFailed", undefined, error);
|
|
@@ -541,6 +622,58 @@ class BlobStorageService {
|
|
|
541
622
|
}
|
|
542
623
|
return blobStorageModels.BlobStorageConnectorFactory.get(idUri.namespaceMethod());
|
|
543
624
|
}
|
|
625
|
+
/**
|
|
626
|
+
* Get an entity.
|
|
627
|
+
* @param id The id of the entity to get, or the index value if secondaryIndex is set.
|
|
628
|
+
* @param secondaryIndex Get the item using a secondary index.
|
|
629
|
+
* @param userIdentity The user identity to use with storage operations.
|
|
630
|
+
* @param nodeIdentity The node identity to use with storage operations.
|
|
631
|
+
* @returns The object if it can be found or throws.
|
|
632
|
+
* @internal
|
|
633
|
+
*/
|
|
634
|
+
async internalGet(id, userIdentity, nodeIdentity) {
|
|
635
|
+
const conditions = [];
|
|
636
|
+
if (this._includeUserIdentity) {
|
|
637
|
+
core.Guards.stringValue(this.CLASS_NAME, "userIdentity", userIdentity);
|
|
638
|
+
conditions.push({
|
|
639
|
+
property: "userIdentity",
|
|
640
|
+
comparison: entity.ComparisonOperator.Equals,
|
|
641
|
+
value: userIdentity
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
if (this._includeNodeIdentity) {
|
|
645
|
+
core.Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
|
|
646
|
+
conditions.push({
|
|
647
|
+
property: "nodeIdentity",
|
|
648
|
+
comparison: entity.ComparisonOperator.Equals,
|
|
649
|
+
value: nodeIdentity
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
let entity$1;
|
|
653
|
+
if (conditions.length === 0) {
|
|
654
|
+
entity$1 = await this._metadataEntityStorage.get(id);
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
const schema = this._metadataEntityStorage.getSchema();
|
|
658
|
+
const primaryKey = entity.EntitySchemaHelper.getPrimaryKey(schema);
|
|
659
|
+
conditions.unshift({
|
|
660
|
+
property: primaryKey.property,
|
|
661
|
+
comparison: entity.ComparisonOperator.Equals,
|
|
662
|
+
value: id
|
|
663
|
+
});
|
|
664
|
+
const results = await this._metadataEntityStorage.query({
|
|
665
|
+
conditions,
|
|
666
|
+
logicalOperator: entity.LogicalOperator.And
|
|
667
|
+
}, undefined, undefined, undefined, 1);
|
|
668
|
+
entity$1 = results.entities[0];
|
|
669
|
+
}
|
|
670
|
+
if (core.Is.empty(entity$1)) {
|
|
671
|
+
throw new core.NotFoundError(this.CLASS_NAME, "entityNotFound", id);
|
|
672
|
+
}
|
|
673
|
+
core.ObjectHelper.propertyDelete(entity$1, "nodeIdentity");
|
|
674
|
+
core.ObjectHelper.propertyDelete(entity$1, "userIdentity");
|
|
675
|
+
return entity$1;
|
|
676
|
+
}
|
|
544
677
|
}
|
|
545
678
|
|
|
546
679
|
/**
|
|
@@ -563,6 +696,14 @@ exports.BlobMetadata = class BlobMetadata {
|
|
|
563
696
|
* The metadata for the blob as JSON-LD.
|
|
564
697
|
*/
|
|
565
698
|
metadata;
|
|
699
|
+
/**
|
|
700
|
+
* The user identity that created the blob.
|
|
701
|
+
*/
|
|
702
|
+
userIdentity;
|
|
703
|
+
/**
|
|
704
|
+
* The node identity that created the blob.
|
|
705
|
+
*/
|
|
706
|
+
nodeIdentity;
|
|
566
707
|
};
|
|
567
708
|
__decorate([
|
|
568
709
|
entity.property({ type: "string", isPrimary: true }),
|
|
@@ -580,14 +721,27 @@ __decorate([
|
|
|
580
721
|
entity.property({ type: "object", itemTypeRef: "IJsonLdNodeObject" }),
|
|
581
722
|
__metadata("design:type", Object)
|
|
582
723
|
], exports.BlobMetadata.prototype, "metadata", void 0);
|
|
724
|
+
__decorate([
|
|
725
|
+
entity.property({ type: "string" }),
|
|
726
|
+
__metadata("design:type", String)
|
|
727
|
+
], exports.BlobMetadata.prototype, "userIdentity", void 0);
|
|
728
|
+
__decorate([
|
|
729
|
+
entity.property({ type: "string" }),
|
|
730
|
+
__metadata("design:type", String)
|
|
731
|
+
], exports.BlobMetadata.prototype, "nodeIdentity", void 0);
|
|
583
732
|
exports.BlobMetadata = __decorate([
|
|
584
733
|
entity.entity()
|
|
585
734
|
], exports.BlobMetadata);
|
|
586
735
|
|
|
736
|
+
/**
|
|
737
|
+
* These are dummy entry points for the blob storage service.
|
|
738
|
+
* In reality your application would create its own entry points based on the
|
|
739
|
+
* blob types it wants to store, using a custom defaultBaseRoute.
|
|
740
|
+
*/
|
|
587
741
|
const restEntryPoints = [
|
|
588
742
|
{
|
|
589
|
-
name: "
|
|
590
|
-
defaultBaseRoute: "blob",
|
|
743
|
+
name: "blob-storage",
|
|
744
|
+
defaultBaseRoute: "blob-storage",
|
|
591
745
|
tags: tagsBlobStorage,
|
|
592
746
|
generateRoutes: generateRestRoutesBlobStorage
|
|
593
747
|
}
|