@travetto/model 5.0.6 → 5.0.8
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 +24 -1
- package/package.json +7 -7
- package/src/internal/service/common.ts +2 -2
- package/src/service/blob.ts +25 -2
- package/support/test/blob.ts +67 -6
package/README.md
CHANGED
|
@@ -179,13 +179,36 @@ export interface ModelBlobSupport {
|
|
|
179
179
|
* Get metadata for blob
|
|
180
180
|
* @param location The location of the blob
|
|
181
181
|
*/
|
|
182
|
-
|
|
182
|
+
getBlobMeta(location: string): Promise<BlobMeta>;
|
|
183
183
|
|
|
184
184
|
/**
|
|
185
185
|
* Delete blob by location
|
|
186
186
|
* @param location The location of the blob
|
|
187
187
|
*/
|
|
188
188
|
deleteBlob(location: string): Promise<void>;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Update blob metadata
|
|
192
|
+
* @param location The location of the blob
|
|
193
|
+
*/
|
|
194
|
+
updateBlobMeta(location: string, meta: BlobMeta): Promise<void>;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Produces an externally usable URL for sharing limited read access to a specific resource
|
|
198
|
+
*
|
|
199
|
+
* @param location The asset location to read from
|
|
200
|
+
* @param exp Expiry
|
|
201
|
+
*/
|
|
202
|
+
getBlobReadUrl?(location: string, exp?: TimeSpan): Promise<string>;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Produces an externally usable URL for sharing allowing direct write access
|
|
206
|
+
*
|
|
207
|
+
* @param location The asset location to write to
|
|
208
|
+
* @param meta The metadata to associate with the final asset
|
|
209
|
+
* @param exp Expiry
|
|
210
|
+
*/
|
|
211
|
+
getBlobWriteUrl?(location: string, meta: BlobMeta, exp?: TimeSpan): Promise<string>;
|
|
189
212
|
}
|
|
190
213
|
```
|
|
191
214
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.8",
|
|
4
4
|
"description": "Datastore abstraction for core operations.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"datastore",
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
"directory": "module/model"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@travetto/config": "^5.0.
|
|
30
|
-
"@travetto/di": "^5.0.
|
|
31
|
-
"@travetto/registry": "^5.0.
|
|
32
|
-
"@travetto/schema": "^5.0.
|
|
29
|
+
"@travetto/config": "^5.0.7",
|
|
30
|
+
"@travetto/di": "^5.0.7",
|
|
31
|
+
"@travetto/registry": "^5.0.7",
|
|
32
|
+
"@travetto/schema": "^5.0.7"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@travetto/cli": "^5.0.
|
|
36
|
-
"@travetto/test": "^5.0.
|
|
35
|
+
"@travetto/cli": "^5.0.7",
|
|
36
|
+
"@travetto/test": "^5.0.7"
|
|
37
37
|
},
|
|
38
38
|
"peerDependenciesMeta": {
|
|
39
39
|
"@travetto/cli": {
|
|
@@ -31,7 +31,7 @@ export const isCrudSupported = hasFunction<ModelCrudSupport>('upsert');
|
|
|
31
31
|
export const isExpirySupported = hasFunction<ModelExpirySupport>('deleteExpired');
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* Type guard for determining if service supports
|
|
34
|
+
* Type guard for determining if service supports blob operations
|
|
35
35
|
*/
|
|
36
36
|
export const isBlobSupported = hasFunction<ModelBlobSupport>('getBlob');
|
|
37
37
|
|
|
@@ -41,7 +41,7 @@ export const isBlobSupported = hasFunction<ModelBlobSupport>('getBlob');
|
|
|
41
41
|
export const isStorageSupported = hasFunction<ModelStorageSupport>('createStorage');
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* Type guard for determining if service supports
|
|
44
|
+
* Type guard for determining if service supports bulk operation
|
|
45
45
|
*/
|
|
46
46
|
export const isBulkSupported = hasFunction<ModelBulkSupport>('processBulk');
|
|
47
47
|
|
package/src/service/blob.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BinaryInput, BlobMeta, ByteRange } from '@travetto/runtime';
|
|
1
|
+
import { BinaryInput, BlobMeta, ByteRange, TimeSpan } from '@travetto/runtime';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Support for Blobs CRUD.
|
|
@@ -26,11 +26,34 @@ export interface ModelBlobSupport {
|
|
|
26
26
|
* Get metadata for blob
|
|
27
27
|
* @param location The location of the blob
|
|
28
28
|
*/
|
|
29
|
-
|
|
29
|
+
getBlobMeta(location: string): Promise<BlobMeta>;
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Delete blob by location
|
|
33
33
|
* @param location The location of the blob
|
|
34
34
|
*/
|
|
35
35
|
deleteBlob(location: string): Promise<void>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Update blob metadata
|
|
39
|
+
* @param location The location of the blob
|
|
40
|
+
*/
|
|
41
|
+
updateBlobMeta(location: string, meta: BlobMeta): Promise<void>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Produces an externally usable URL for sharing limited read access to a specific resource
|
|
45
|
+
*
|
|
46
|
+
* @param location The asset location to read from
|
|
47
|
+
* @param exp Expiry
|
|
48
|
+
*/
|
|
49
|
+
getBlobReadUrl?(location: string, exp?: TimeSpan): Promise<string>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Produces an externally usable URL for sharing allowing direct write access
|
|
53
|
+
*
|
|
54
|
+
* @param location The asset location to write to
|
|
55
|
+
* @param meta The metadata to associate with the final asset
|
|
56
|
+
* @param exp Expiry
|
|
57
|
+
*/
|
|
58
|
+
getBlobWriteUrl?(location: string, meta: BlobMeta, exp?: TimeSpan): Promise<string>;
|
|
36
59
|
}
|
package/support/test/blob.ts
CHANGED
|
@@ -22,8 +22,8 @@ export abstract class ModelBlobSuite extends BaseModelSuite<ModelBlobSupport> {
|
|
|
22
22
|
const id = Util.uuid();
|
|
23
23
|
|
|
24
24
|
await service.upsertBlob(id, buffer);
|
|
25
|
-
const m = await service.
|
|
26
|
-
const retrieved = await service.
|
|
25
|
+
const m = await service.getBlobMeta(id);
|
|
26
|
+
const retrieved = await service.getBlobMeta(id);
|
|
27
27
|
assert.deepStrictEqual(m, retrieved);
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -35,13 +35,13 @@ export abstract class ModelBlobSuite extends BaseModelSuite<ModelBlobSupport> {
|
|
|
35
35
|
const id = Util.uuid();
|
|
36
36
|
|
|
37
37
|
await service.upsertBlob(id, buffer, { hash: '10' });
|
|
38
|
-
assert((await service.
|
|
38
|
+
assert((await service.getBlobMeta(id)).hash === '10');
|
|
39
39
|
|
|
40
40
|
await service.upsertBlob(id, buffer, { hash: '20' });
|
|
41
|
-
assert((await service.
|
|
41
|
+
assert((await service.getBlobMeta(id)).hash === '20');
|
|
42
42
|
|
|
43
43
|
await service.upsertBlob(id, buffer, { hash: '30' }, false);
|
|
44
|
-
assert((await service.
|
|
44
|
+
assert((await service.getBlobMeta(id)).hash === '20');
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
@Test()
|
|
@@ -51,7 +51,7 @@ export abstract class ModelBlobSuite extends BaseModelSuite<ModelBlobSupport> {
|
|
|
51
51
|
|
|
52
52
|
const id = Util.uuid();
|
|
53
53
|
await service.upsertBlob(id, buffer);
|
|
54
|
-
const { hash } = await service.
|
|
54
|
+
const { hash } = await service.getBlobMeta(id);
|
|
55
55
|
|
|
56
56
|
const retrieved = await service.getBlob(id);
|
|
57
57
|
const { hash: received } = meta(retrieved)!;
|
|
@@ -133,4 +133,65 @@ export abstract class ModelBlobSuite extends BaseModelSuite<ModelBlobSupport> {
|
|
|
133
133
|
assert('asset.yml' === savedMeta.filename);
|
|
134
134
|
assert(undefined === savedMeta.hash);
|
|
135
135
|
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
@Test()
|
|
139
|
+
async metadataUpdate() {
|
|
140
|
+
const service = await this.service;
|
|
141
|
+
|
|
142
|
+
await this.writeAndGet();
|
|
143
|
+
|
|
144
|
+
await service.updateBlobMeta('orange', {
|
|
145
|
+
contentType: 'text/yml',
|
|
146
|
+
filename: 'orange.yml'
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const savedMeta = await service.getBlobMeta('orange');
|
|
150
|
+
|
|
151
|
+
assert('text/yml' === savedMeta.contentType);
|
|
152
|
+
assert('orange.yml' === savedMeta.filename);
|
|
153
|
+
assert(undefined === savedMeta.hash);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
158
|
+
@Test({ skip: (x: unknown) => !(x as ModelBlobSuite).serviceClass.prototype.getBlobWriteUrl })
|
|
159
|
+
async signedUrl() {
|
|
160
|
+
const service = await this.service;
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
const buffer = Buffer.alloc(1.5 * 10000);
|
|
164
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
165
|
+
buffer.writeUInt8(Math.trunc(Math.random() * 255), i);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const writable = await service.getBlobWriteUrl!('largeFile/one', {
|
|
169
|
+
contentType: 'image/jpeg',
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
console.log(writable);
|
|
173
|
+
assert(writable);
|
|
174
|
+
|
|
175
|
+
const res = await fetch(writable, {
|
|
176
|
+
method: 'PUT',
|
|
177
|
+
body: new File([buffer], 'gary', { type: 'image/jpeg' }),
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
console.error(await res.text());
|
|
181
|
+
|
|
182
|
+
assert(res.ok);
|
|
183
|
+
|
|
184
|
+
await service.updateBlobMeta('largeFile/one', {
|
|
185
|
+
contentType: 'image/jpeg',
|
|
186
|
+
title: 'orange',
|
|
187
|
+
filename: 'gary',
|
|
188
|
+
size: buffer.length,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const found = await service.getBlob('largeFile/one');
|
|
192
|
+
assert(found.size === buffer.length);
|
|
193
|
+
assert(found.type === 'image/jpeg');
|
|
194
|
+
assert(BinaryUtil.getBlobMeta(found)?.title === 'orange');
|
|
195
|
+
assert(BinaryUtil.getBlobMeta(found)?.filename === 'gary');
|
|
196
|
+
}
|
|
136
197
|
}
|