@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.
package/dist/src/index.cjs
CHANGED
|
@@ -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
|
|
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/
|
|
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
|
|
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/
|
|
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
|
|
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('
|
|
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
|
@@ -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
|
|
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/
|
|
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
|
|
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('
|
|
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 => {
|