@travetto/model-s3 3.1.5 → 3.1.7

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.
Files changed (2) hide show
  1. package/package.json +3 -3
  2. package/src/service.ts +25 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-s3",
3
- "version": "3.1.5",
3
+ "version": "3.1.7",
4
4
  "description": "S3 backing for the travetto model module.",
5
5
  "keywords": [
6
6
  "s3",
@@ -28,10 +28,10 @@
28
28
  "@aws-sdk/client-s3": "^3.272.0",
29
29
  "@aws-sdk/credential-provider-ini": "^3.218.0",
30
30
  "@travetto/config": "^3.1.2",
31
- "@travetto/model": "^3.1.6"
31
+ "@travetto/model": "^3.1.7"
32
32
  },
33
33
  "peerDependencies": {
34
- "@travetto/command": "^3.1.1"
34
+ "@travetto/command": "^3.1.2"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@travetto/command": {
package/src/service.ts CHANGED
@@ -5,7 +5,7 @@ import type { MetadataBearer } from '@aws-sdk/types';
5
5
 
6
6
  import {
7
7
  ModelCrudSupport, ModelStreamSupport, ModelStorageSupport, StreamMeta,
8
- ModelType, ModelRegistry, ExistsError, NotFoundError, OptionalId
8
+ ModelType, ModelRegistry, ExistsError, NotFoundError, OptionalId, PartialStream
9
9
  } from '@travetto/model';
10
10
  import { Injectable } from '@travetto/di';
11
11
  import { StreamUtil, Class, AppError } from '@travetto/base';
@@ -16,6 +16,7 @@ import { ModelExpiryUtil } from '@travetto/model/src/internal/service/expiry';
16
16
  import { ModelStorageUtil } from '@travetto/model/src/internal/service/storage';
17
17
 
18
18
  import { S3ModelConfig } from './config';
19
+ import { ModelStreamUtil } from '@travetto/model/src/internal/service/stream';
19
20
 
20
21
  function isMetadataBearer(o: unknown): o is MetadataBearer {
21
22
  return !!o && typeof o === 'object' && '$metadata' in o;
@@ -93,6 +94,10 @@ export class S3ModelService implements ModelCrudSupport, ModelStreamSupport, Mod
93
94
  const { UploadId } = await this.client.createMultipartUpload(this.#q(STREAM_SPACE, id, {
94
95
  ContentType: meta.contentType,
95
96
  ContentLength: meta.size,
97
+ Metadata: {
98
+ ...meta,
99
+ size: `${meta.size}`
100
+ }
96
101
  }));
97
102
 
98
103
  const parts: s3.CompletedPart[] = [];
@@ -299,6 +304,25 @@ export class S3ModelService implements ModelCrudSupport, ModelStreamSupport, Mod
299
304
  throw new AppError(`Unable to read type: ${typeof res.Body}`);
300
305
  }
301
306
 
307
+ async getStreamPartial(location: string, start: number, end?: number): Promise<PartialStream> {
308
+ const meta = await this.describeStream(location);
309
+ end ??= meta.size - 1;
310
+
311
+ ModelStreamUtil.checkRange(start, end, meta.size);
312
+
313
+ // Read from s3
314
+ const res = await this.client.getObject(this.#q(STREAM_SPACE, location, {
315
+ Range: `bytes=${start}-${end}`
316
+ }));
317
+ if (res.Body instanceof Buffer || // Buffer
318
+ typeof res.Body === 'string' || // string
319
+ res.Body && ('pipe' in res.Body) // Stream
320
+ ) {
321
+ return { stream: await StreamUtil.toStream(res.Body), range: [start, end] };
322
+ }
323
+ throw new AppError(`Unable to read type: ${typeof res.Body}`);
324
+ }
325
+
302
326
  async headStream(location: string): Promise<{ Metadata?: Partial<StreamMeta>, ContentLength?: number }> {
303
327
  const query = this.#q(STREAM_SPACE, location);
304
328
  try {