@travetto/model 3.1.7 → 3.1.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
@@ -317,7 +317,7 @@ export class MemoryModelService implements ModelCrudSupport, ModelStreamSupport,
317
317
  async getStreamPartial(location: string, start: number, end?: number): Promise<PartialStream>;
318
318
  async describeStream(location: string): Promise<StreamMeta>;
319
319
  async deleteStream(location: string): Promise<void>;
320
- // Expiry Support
320
+ // Expiry
321
321
  async deleteExpired<T extends ModelType>(cls: Class<T>): Promise<number>;
322
322
  // Storage Support
323
323
  async createStorage(): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model",
3
- "version": "3.1.7",
3
+ "version": "3.1.8",
4
4
  "description": "Datastore abstraction for core operations.",
5
5
  "keywords": [
6
6
  "datastore",
@@ -6,9 +6,16 @@ export const StreamModel: Class<ModelType> = Cls;
6
6
  export const STREAMS = '_streams';
7
7
 
8
8
  export class ModelStreamUtil {
9
- static checkRange(start: number, end: number, size: number): void {
10
- if (Number.isNaN(start) || Number.isNaN(end) || !Number.isFinite(start) || start < 0 || end >= size) {
9
+ static enforceRange(start: number, end: number | undefined, size: number): [start: number, end: number] {
10
+
11
+ end ??= size - 1;
12
+
13
+ if (Number.isNaN(start) || Number.isNaN(end) || !Number.isFinite(start) || start >= size || start < 0) {
11
14
  throw new AppError('Invalid position, out of range', 'data');
12
15
  }
16
+ if (end >= size) {
17
+ end = size - 1;
18
+ }
19
+ return [start, end];
13
20
  }
14
21
  }
@@ -193,9 +193,8 @@ export class FileModelService implements ModelCrudSupport, ModelStreamSupport, M
193
193
  async getStreamPartial(location: string, start: number, end?: number): Promise<PartialStream> {
194
194
  const file = await this.#find(STREAMS, BIN, location);
195
195
  const meta = await this.describeStream(location);
196
- end ??= meta.size - 1;
197
196
 
198
- ModelStreamUtil.checkRange(start, end, meta.size);
197
+ [start, end] = ModelStreamUtil.enforceRange(start, end, meta.size);
199
198
 
200
199
  const stream = createReadStream(file, { start, end });
201
200
  return { stream, range: [start, end] };
@@ -252,8 +252,9 @@ export class MemoryModelService implements ModelCrudSupport, ModelStreamSupport,
252
252
  async getStreamPartial(location: string, start: number, end?: number): Promise<PartialStream> {
253
253
  const streams = this.#find(STREAMS, location, 'notfound');
254
254
  const buffer = streams.get(location)!;
255
- end ??= (buffer.length - 1);
256
- ModelStreamUtil.checkRange(start, end, buffer.length);
255
+
256
+ [start, end] = ModelStreamUtil.enforceRange(start, end, buffer.length);
257
+
257
258
  const stream = await StreamUtil.bufferToStream(buffer.subarray(start, end + 1));
258
259
  return { stream, range: [start, end] };
259
260
  }
@@ -98,7 +98,12 @@ export abstract class ModelStreamSuite extends BaseModelSuite<ModelStreamSupport
98
98
  assert(subContent3.length === 1);
99
99
  assert(subContent3 === 'k');
100
100
 
101
+ const partialOverbounded = await service.getStreamPartial(meta.hash, 20, 40);
102
+ const subContent4 = (await StreamUtil.toBuffer(partialOverbounded.stream)).toString('utf8');
103
+ assert(subContent4.length === 6);
104
+ assert(subContent4.endsWith('xyz'));
105
+
101
106
  await assert.rejects(() => service.getStreamPartial(meta.hash, -10, 10));
102
- await assert.rejects(() => service.getStreamPartial(meta.hash, 0, 27));
107
+ await assert.rejects(() => service.getStreamPartial(meta.hash, 30, 37));
103
108
  }
104
109
  }