@unito/integration-sdk 1.4.1 → 1.4.3

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.
@@ -1184,6 +1184,7 @@ class Provider {
1184
1184
  defaultHeaders: {
1185
1185
  Accept: 'application/octet-stream',
1186
1186
  },
1187
+ rawBody: true,
1187
1188
  });
1188
1189
  }
1189
1190
  /**
@@ -1365,7 +1366,7 @@ class Provider {
1365
1366
  case 'TimeoutError':
1366
1367
  throw this.handleError(408, 'Request timeout', options);
1367
1368
  }
1368
- throw this.handleError(500, `Unexpected error while calling the provider: name: "${error.name}" \n message: "${error.message}" \n stack: ${error.stack}`, options);
1369
+ throw this.handleError(500, `Unexpected error while calling the provider. ErrorName: "${error.name}" \n message: "${error.message}" \n stack: ${error.stack} \n cause: ${error.cause} \n causeStack: ${error.cause?.stack}`, options);
1369
1370
  }
1370
1371
  throw this.handleError(500, 'Unexpected error while calling the provider - this is not normal, investigate', options);
1371
1372
  }
@@ -1375,7 +1376,11 @@ class Provider {
1375
1376
  }
1376
1377
  const responseContentType = response.headers.get('content-type');
1377
1378
  let body;
1378
- if (headers.Accept === 'application/json') {
1379
+ if (options.rawBody || headers.Accept === 'application/octet-stream') {
1380
+ // When we expect octet-stream, we accept any Content-Type the provider sends us, we just want to stream it
1381
+ body = response.body;
1382
+ }
1383
+ else if (headers.Accept === 'application/json') {
1379
1384
  // Validate that the response content type is at least similar to what we expect
1380
1385
  // (Provider's response Content-Type might be more specific, e.g. application/json;charset=utf-8)
1381
1386
  // Default to application/json if no Content-Type header is provided
@@ -1391,10 +1396,6 @@ class Provider {
1391
1396
  throw this.handleError(500, `Invalid JSON response`, options);
1392
1397
  }
1393
1398
  }
1394
- else if (headers.Accept == 'application/octet-stream') {
1395
- // When we expect octet-stream, we accept any Content-Type the provider sends us, we just want to stream it.
1396
- body = response.body;
1397
- }
1398
1399
  else if (headers.Accept?.includes('text/html')) {
1399
1400
  // Accept text based content types
1400
1401
  body = (await response.text());
@@ -29,6 +29,7 @@ export type RateLimiter = <T>(options: {
29
29
  * @property logger - The logger to use during the call.
30
30
  * @property queryParams - The query parameters to add when calling the provider.
31
31
  * @property additionnalheaders - The headers to add when calling the provider.
32
+ * @property rawBody - Whether to return the raw response body.
32
33
  */
33
34
  export type RequestOptions = {
34
35
  credentials: Credentials;
@@ -40,6 +41,7 @@ export type RequestOptions = {
40
41
  additionnalheaders?: {
41
42
  [key: string]: string;
42
43
  };
44
+ rawBody?: boolean;
43
45
  };
44
46
  /**
45
47
  * Response object returned by the Provider's method.
@@ -85,6 +85,7 @@ export class Provider {
85
85
  defaultHeaders: {
86
86
  Accept: 'application/octet-stream',
87
87
  },
88
+ rawBody: true,
88
89
  });
89
90
  }
90
91
  /**
@@ -266,7 +267,7 @@ export class Provider {
266
267
  case 'TimeoutError':
267
268
  throw this.handleError(408, 'Request timeout', options);
268
269
  }
269
- throw this.handleError(500, `Unexpected error while calling the provider: name: "${error.name}" \n message: "${error.message}" \n stack: ${error.stack}`, options);
270
+ throw this.handleError(500, `Unexpected error while calling the provider. ErrorName: "${error.name}" \n message: "${error.message}" \n stack: ${error.stack} \n cause: ${error.cause} \n causeStack: ${error.cause?.stack}`, options);
270
271
  }
271
272
  throw this.handleError(500, 'Unexpected error while calling the provider - this is not normal, investigate', options);
272
273
  }
@@ -276,7 +277,11 @@ export class Provider {
276
277
  }
277
278
  const responseContentType = response.headers.get('content-type');
278
279
  let body;
279
- if (headers.Accept === 'application/json') {
280
+ if (options.rawBody || headers.Accept === 'application/octet-stream') {
281
+ // When we expect octet-stream, we accept any Content-Type the provider sends us, we just want to stream it
282
+ body = response.body;
283
+ }
284
+ else if (headers.Accept === 'application/json') {
280
285
  // Validate that the response content type is at least similar to what we expect
281
286
  // (Provider's response Content-Type might be more specific, e.g. application/json;charset=utf-8)
282
287
  // Default to application/json if no Content-Type header is provided
@@ -292,10 +297,6 @@ export class Provider {
292
297
  throw this.handleError(500, `Invalid JSON response`, options);
293
298
  }
294
299
  }
295
- else if (headers.Accept == 'application/octet-stream') {
296
- // When we expect octet-stream, we accept any Content-Type the provider sends us, we just want to stream it.
297
- body = response.body;
298
- }
299
300
  else if (headers.Accept?.includes('text/html')) {
300
301
  // Accept text based content types
301
302
  body = (await response.text());
@@ -79,6 +79,25 @@ describe('Provider', () => {
79
79
  ]);
80
80
  assert.deepEqual(actualResponse, { status: 200, headers: response.headers, body: '' });
81
81
  });
82
+ it('should return the raw response body if specified', async (context) => {
83
+ const response = new Response(`IMAGINE A HUGE PAYLOAD`, {
84
+ status: 200,
85
+ headers: { 'Content-Type': 'image/png' },
86
+ });
87
+ context.mock.method(global, 'fetch', () => Promise.resolve(response));
88
+ const providerResponse = await provider.streamingGet('/endpoint/123', {
89
+ credentials: { apiKey: 'apikey#1111' },
90
+ logger: logger,
91
+ signal: new AbortController().signal,
92
+ additionnalheaders: {
93
+ Accept: 'application/json',
94
+ },
95
+ rawBody: true,
96
+ });
97
+ assert.ok(providerResponse);
98
+ // What matters: still returns a stream
99
+ assert.ok(providerResponse.body instanceof ReadableStream);
100
+ });
82
101
  it('gets an endpoint which is an absolute url', async (context) => {
83
102
  const response = new Response('{"data": "value"}', {
84
103
  status: 200,
@@ -534,7 +553,7 @@ describe('Provider', () => {
534
553
  });
535
554
  it('throws on unknown errors', async (context) => {
536
555
  context.mock.method(global, 'fetch', () => {
537
- throw new Error('foo');
556
+ throw new TypeError('foo', { cause: new Error('bar') });
538
557
  });
539
558
  let error;
540
559
  try {
@@ -548,10 +567,12 @@ describe('Provider', () => {
548
567
  error = e;
549
568
  }
550
569
  assert.ok(error instanceof HttpErrors.HttpError);
551
- assert.ok(error.message.startsWith('Unexpected error while calling the provider:'));
552
- assert.ok(error.message.includes('name: "Error"'));
570
+ assert.ok(error.message.startsWith('Unexpected error while calling the provider.'));
571
+ assert.ok(error.message.includes('ErrorName: "TypeError"'));
553
572
  assert.ok(error.message.includes('message: "foo"'));
554
573
  assert.ok(error.message.includes('stack:'));
574
+ assert.ok(error.message.includes('cause:'));
575
+ assert.ok(error.message.includes('causeStack:'));
555
576
  });
556
577
  it('throws on status 429', async (context) => {
557
578
  const response = new Response('response body', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unito/integration-sdk",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "description": "Integration SDK",
5
5
  "type": "module",
6
6
  "types": "dist/src/index.d.ts",
@@ -34,6 +34,7 @@ export type RateLimiter = <T>(
34
34
  * @property logger - The logger to use during the call.
35
35
  * @property queryParams - The query parameters to add when calling the provider.
36
36
  * @property additionnalheaders - The headers to add when calling the provider.
37
+ * @property rawBody - Whether to return the raw response body.
37
38
  */
38
39
  export type RequestOptions = {
39
40
  credentials: Credentials;
@@ -41,6 +42,7 @@ export type RequestOptions = {
41
42
  signal?: AbortSignal;
42
43
  queryParams?: { [key: string]: string };
43
44
  additionnalheaders?: { [key: string]: string };
45
+ rawBody?: boolean;
44
46
  };
45
47
 
46
48
  /**
@@ -166,6 +168,7 @@ export class Provider {
166
168
  defaultHeaders: {
167
169
  Accept: 'application/octet-stream',
168
170
  },
171
+ rawBody: true,
169
172
  });
170
173
  }
171
174
 
@@ -369,9 +372,10 @@ export class Provider {
369
372
  case 'TimeoutError':
370
373
  throw this.handleError(408, 'Request timeout', options);
371
374
  }
375
+
372
376
  throw this.handleError(
373
377
  500,
374
- `Unexpected error while calling the provider: name: "${error.name}" \n message: "${error.message}" \n stack: ${error.stack}`,
378
+ `Unexpected error while calling the provider. ErrorName: "${error.name}" \n message: "${error.message}" \n stack: ${error.stack} \n cause: ${error.cause} \n causeStack: ${(error.cause as Error)?.stack}`,
375
379
  options,
376
380
  );
377
381
  }
@@ -391,7 +395,10 @@ export class Provider {
391
395
  const responseContentType = response.headers.get('content-type');
392
396
  let body: T;
393
397
 
394
- if (headers.Accept === 'application/json') {
398
+ if (options.rawBody || headers.Accept === 'application/octet-stream') {
399
+ // When we expect octet-stream, we accept any Content-Type the provider sends us, we just want to stream it
400
+ body = response.body as T;
401
+ } else if (headers.Accept === 'application/json') {
395
402
  // Validate that the response content type is at least similar to what we expect
396
403
  // (Provider's response Content-Type might be more specific, e.g. application/json;charset=utf-8)
397
404
  // Default to application/json if no Content-Type header is provided
@@ -410,9 +417,6 @@ export class Provider {
410
417
  } catch (err) {
411
418
  throw this.handleError(500, `Invalid JSON response`, options);
412
419
  }
413
- } else if (headers.Accept == 'application/octet-stream') {
414
- // When we expect octet-stream, we accept any Content-Type the provider sends us, we just want to stream it.
415
- body = response.body as T;
416
420
  } else if (headers.Accept?.includes('text/html')) {
417
421
  // Accept text based content types
418
422
  body = (await response.text()) as T;
@@ -94,6 +94,29 @@ describe('Provider', () => {
94
94
  assert.deepEqual(actualResponse, { status: 200, headers: response.headers, body: '' });
95
95
  });
96
96
 
97
+ it('should return the raw response body if specified', async context => {
98
+ const response = new Response(`IMAGINE A HUGE PAYLOAD`, {
99
+ status: 200,
100
+ headers: { 'Content-Type': 'image/png' },
101
+ });
102
+
103
+ context.mock.method(global, 'fetch', () => Promise.resolve(response));
104
+
105
+ const providerResponse = await provider.streamingGet('/endpoint/123', {
106
+ credentials: { apiKey: 'apikey#1111' },
107
+ logger: logger,
108
+ signal: new AbortController().signal,
109
+ additionnalheaders: {
110
+ Accept: 'application/json',
111
+ },
112
+ rawBody: true,
113
+ });
114
+
115
+ assert.ok(providerResponse);
116
+ // What matters: still returns a stream
117
+ assert.ok(providerResponse.body instanceof ReadableStream);
118
+ });
119
+
97
120
  it('gets an endpoint which is an absolute url', async context => {
98
121
  const response = new Response('{"data": "value"}', {
99
122
  status: 200,
@@ -635,7 +658,7 @@ describe('Provider', () => {
635
658
 
636
659
  it('throws on unknown errors', async context => {
637
660
  context.mock.method(global, 'fetch', () => {
638
- throw new Error('foo');
661
+ throw new TypeError('foo', { cause: new Error('bar') });
639
662
  });
640
663
 
641
664
  let error;
@@ -651,10 +674,12 @@ describe('Provider', () => {
651
674
  }
652
675
 
653
676
  assert.ok(error instanceof HttpErrors.HttpError);
654
- assert.ok(error.message.startsWith('Unexpected error while calling the provider:'));
655
- assert.ok(error.message.includes('name: "Error"'));
677
+ assert.ok(error.message.startsWith('Unexpected error while calling the provider.'));
678
+ assert.ok(error.message.includes('ErrorName: "TypeError"'));
656
679
  assert.ok(error.message.includes('message: "foo"'));
657
680
  assert.ok(error.message.includes('stack:'));
681
+ assert.ok(error.message.includes('cause:'));
682
+ assert.ok(error.message.includes('causeStack:'));
658
683
  });
659
684
 
660
685
  it('throws on status 429', async context => {