@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 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
- describeBlob(location: string): Promise<BlobMeta>;
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.6",
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.6",
30
- "@travetto/di": "^5.0.6",
31
- "@travetto/registry": "^5.0.6",
32
- "@travetto/schema": "^5.0.6"
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.6",
36
- "@travetto/test": "^5.0.6"
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 streaming operation
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 streaming operation
44
+ * Type guard for determining if service supports bulk operation
45
45
  */
46
46
  export const isBulkSupported = hasFunction<ModelBulkSupport>('processBulk');
47
47
 
@@ -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
- describeBlob(location: string): Promise<BlobMeta>;
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
  }
@@ -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.describeBlob(id);
26
- const retrieved = await service.describeBlob(id);
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.describeBlob(id)).hash === '10');
38
+ assert((await service.getBlobMeta(id)).hash === '10');
39
39
 
40
40
  await service.upsertBlob(id, buffer, { hash: '20' });
41
- assert((await service.describeBlob(id)).hash === '20');
41
+ assert((await service.getBlobMeta(id)).hash === '20');
42
42
 
43
43
  await service.upsertBlob(id, buffer, { hash: '30' }, false);
44
- assert((await service.describeBlob(id)).hash === '20');
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.describeBlob(id);
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
  }