@travetto/model-s3 3.1.6 → 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 +2 -2
  2. package/src/service.ts +21 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-s3",
3
- "version": "3.1.6",
3
+ "version": "3.1.7",
4
4
  "description": "S3 backing for the travetto model module.",
5
5
  "keywords": [
6
6
  "s3",
@@ -28,7 +28,7 @@
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
34
  "@travetto/command": "^3.1.2"
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;
@@ -303,6 +304,25 @@ export class S3ModelService implements ModelCrudSupport, ModelStreamSupport, Mod
303
304
  throw new AppError(`Unable to read type: ${typeof res.Body}`);
304
305
  }
305
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
+
306
326
  async headStream(location: string): Promise<{ Metadata?: Partial<StreamMeta>, ContentLength?: number }> {
307
327
  const query = this.#q(STREAM_SPACE, location);
308
328
  try {