@openapi-qraft/react 2.6.2 → 2.6.4
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/CHANGELOG.md +18 -0
- package/dist/cjs/lib/responseUtils.cjs +15 -5
- package/dist/cjs/lib/responseUtils.cjs.map +1 -1
- package/dist/esm/lib/responseUtils.js +15 -5
- package/dist/esm/lib/responseUtils.js.map +1 -1
- package/dist/types/lib/__tests__/responseUtils.test.d.ts +2 -0
- package/dist/types/lib/__tests__/responseUtils.test.d.ts.map +1 -0
- package/package.json +5 -5
- package/src/lib/__tests__/responseUtils.test.ts +105 -0
- package/src/lib/responseUtils.ts +15 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @openapi-qraft/react
|
|
2
2
|
|
|
3
|
+
## 2.6.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c796132: Ensure `resolveResponse` always **resolves** promises.
|
|
8
|
+
|
|
9
|
+
This change modifies the `resolveResponse` function to always return a resolved Promise
|
|
10
|
+
rather than rejecting when no `responsePromise` is provided. This brings the function's
|
|
11
|
+
behavior in line with the `requestFn` pattern, ensuring consistent error handling.
|
|
12
|
+
|
|
13
|
+
- @openapi-qraft/tanstack-query-react-types@2.6.4
|
|
14
|
+
|
|
15
|
+
## 2.6.3
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- @openapi-qraft/tanstack-query-react-types@2.6.3
|
|
20
|
+
|
|
3
21
|
## 2.6.2
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -22,11 +22,21 @@
|
|
|
22
22
|
return resolveResponse(response, response.ok ? textResponse : Promise.reject(await textResponse));
|
|
23
23
|
}
|
|
24
24
|
function resolveResponse(responseToReturn, responsePromise) {
|
|
25
|
-
if (!responsePromise)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
if (!responsePromise) {
|
|
26
|
+
if (responseToReturn instanceof Response) {
|
|
27
|
+
return Promise.resolve({
|
|
28
|
+
error: new Error('Unhandled response without promise to resolve'),
|
|
29
|
+
response: responseToReturn,
|
|
30
|
+
data: undefined
|
|
31
|
+
});
|
|
32
|
+
} else {
|
|
33
|
+
return Promise.resolve({
|
|
34
|
+
error: responseToReturn,
|
|
35
|
+
response: undefined,
|
|
36
|
+
data: undefined
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
30
40
|
return responsePromise.then((data)=>({
|
|
31
41
|
data,
|
|
32
42
|
response: responseToReturn
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responseUtils.cjs","sources":["../../../src/lib/responseUtils.ts"],"sourcesContent":["import type { RequestFnResponse } from '@openapi-qraft/tanstack-query-react-types';\n\n/**\n * Processes the response from the server.\n * @beta\n */\nexport async function processResponse<TData, TError>(\n response: Response\n): Promise<RequestFnResponse<TData, TError>> {\n if (response.status === 204 || response.headers.get('Content-Length') === '0')\n return (\n response.ok ? { data: null, response } : { error: null, response }\n ) as RequestFnResponse<TData, TError>;\n\n const contentType = response.headers.get('Content-Type')?.toLowerCase();\n\n const isJsonResponse =\n contentType?.includes('/json') || contentType?.includes('+json');\n\n if (isJsonResponse) {\n // clone response before parsing every time to allow multiple reads\n const jsonResponse = response.clone().json();\n return resolveResponse(\n response,\n response.ok ? jsonResponse : Promise.reject(await jsonResponse)\n );\n }\n\n const textResponse = response.clone().text() as Promise<TData>;\n\n return resolveResponse(\n response,\n response.ok ? textResponse : Promise.reject(await textResponse)\n );\n}\n\n/**\n * Resolves the response from the server.\n * @beta\n */\nexport function resolveResponse<TData, TError>(\n error: Error\n): Promise<RequestFnResponse<TData, TError>>;\nexport function resolveResponse<TData, TError>(\n responseToReturn: Response,\n responsePromise: Promise<TData>\n): Promise<RequestFnResponse<TData, TError>>;\nexport function resolveResponse<TData, TError>(\n responseToReturn: Response | Error,\n responsePromise?: Promise<TData>\n): Promise<RequestFnResponse<TData, TError>> {\n if (!responsePromise)\n return Promise.
|
|
1
|
+
{"version":3,"file":"responseUtils.cjs","sources":["../../../src/lib/responseUtils.ts"],"sourcesContent":["import type { RequestFnResponse } from '@openapi-qraft/tanstack-query-react-types';\n\n/**\n * Processes the response from the server.\n * @beta\n */\nexport async function processResponse<TData, TError>(\n response: Response\n): Promise<RequestFnResponse<TData, TError>> {\n if (response.status === 204 || response.headers.get('Content-Length') === '0')\n return (\n response.ok ? { data: null, response } : { error: null, response }\n ) as RequestFnResponse<TData, TError>;\n\n const contentType = response.headers.get('Content-Type')?.toLowerCase();\n\n const isJsonResponse =\n contentType?.includes('/json') || contentType?.includes('+json');\n\n if (isJsonResponse) {\n // clone response before parsing every time to allow multiple reads\n const jsonResponse = response.clone().json();\n return resolveResponse(\n response,\n response.ok ? jsonResponse : Promise.reject(await jsonResponse)\n );\n }\n\n const textResponse = response.clone().text() as Promise<TData>;\n\n return resolveResponse(\n response,\n response.ok ? textResponse : Promise.reject(await textResponse)\n );\n}\n\n/**\n * Resolves the response from the server.\n * @beta\n */\nexport function resolveResponse<TData, TError>(\n error: Error\n): Promise<RequestFnResponse<TData, TError>>;\nexport function resolveResponse<TData, TError>(\n responseToReturn: Response,\n responsePromise: Promise<TData>\n): Promise<RequestFnResponse<TData, TError>>;\nexport function resolveResponse<TData, TError>(\n responseToReturn: Response | Error,\n responsePromise?: Promise<TData>\n): Promise<RequestFnResponse<TData, TError>> {\n if (!responsePromise) {\n if (responseToReturn instanceof Response) {\n return Promise.resolve({\n error: new Error('Unhandled response without promise to resolve'),\n response: responseToReturn,\n data: undefined,\n });\n } else {\n return Promise.resolve({\n error: responseToReturn,\n response: undefined,\n data: undefined,\n });\n }\n }\n\n return responsePromise\n .then(\n (data) =>\n ({ data, response: responseToReturn }) as RequestFnResponse<\n TData,\n TError\n >\n )\n .catch(\n (error) =>\n ({ error, response: responseToReturn }) as RequestFnResponse<\n TData,\n TError\n >\n );\n}\n"],"names":["processResponse","response","status","headers","get","ok","data","error","contentType","toLowerCase","isJsonResponse","includes","jsonResponse","clone","json","resolveResponse","Promise","reject","textResponse","text","responseToReturn","responsePromise","Response","resolve","Error","undefined","then","catch"],"mappings":";;AAEA;;;IAIO,eAAeA,eAAAA,CACpBC,QAAkB,EAAA;AAElB,IAAA,IAAIA,QAASC,CAAAA,MAAM,KAAK,GAAA,IAAOD,SAASE,OAAO,CAACC,GAAG,CAAC,gBAAsB,CAAA,KAAA,GAAA,EACxE,OACEH,QAAAA,CAASI,EAAE,GAAG;QAAEC,IAAM,EAAA,IAAA;AAAML,QAAAA,QAAAA;KAAa,GAAA;QAAEM,KAAO,EAAA,IAAA;AAAMN,QAAAA,QAAAA;AAAS,KAAA,CAAA;AAGrE,IAAA,MAAMO,cAAcP,QAASE,CAAAA,OAAO,CAACC,GAAG,CAAC,cAAiBK,CAAAA,EAAAA,WAAAA,EAAAA,CAAAA;AAE1D,IAAA,MAAMC,cACJF,GAAAA,WAAAA,EAAaG,QAAS,CAAA,OAAA,CAAA,IAAYH,aAAaG,QAAS,CAAA,OAAA,CAAA,CAAA;AAE1D,IAAA,IAAID,cAAgB,EAAA;;AAElB,QAAA,MAAME,YAAeX,GAAAA,QAAAA,CAASY,KAAK,EAAA,CAAGC,IAAI,EAAA,CAAA;QAC1C,OAAOC,eAAAA,CACLd,UACAA,QAASI,CAAAA,EAAE,GAAGO,YAAeI,GAAAA,OAAAA,CAAQC,MAAM,CAAC,MAAML,YAAAA,CAAAA,CAAAA,CAAAA;AAEtD,KAAA;AAEA,IAAA,MAAMM,YAAejB,GAAAA,QAAAA,CAASY,KAAK,EAAA,CAAGM,IAAI,EAAA,CAAA;IAE1C,OAAOJ,eAAAA,CACLd,UACAA,QAASI,CAAAA,EAAE,GAAGa,YAAeF,GAAAA,OAAAA,CAAQC,MAAM,CAAC,MAAMC,YAAAA,CAAAA,CAAAA,CAAAA;AAEtD,CAAA;AAaO,SAASH,eAAAA,CACdK,gBAAkC,EAClCC,eAAgC,EAAA;AAEhC,IAAA,IAAI,CAACA,eAAiB,EAAA;AACpB,QAAA,IAAID,4BAA4BE,QAAU,EAAA;YACxC,OAAON,OAAAA,CAAQO,OAAO,CAAC;AACrBhB,gBAAAA,KAAAA,EAAO,IAAIiB,KAAM,CAAA,+CAAA,CAAA;gBACjBvB,QAAUmB,EAAAA,gBAAAA;gBACVd,IAAMmB,EAAAA,SAAAA;AACR,aAAA,CAAA,CAAA;SACK,MAAA;YACL,OAAOT,OAAAA,CAAQO,OAAO,CAAC;gBACrBhB,KAAOa,EAAAA,gBAAAA;gBACPnB,QAAUwB,EAAAA,SAAAA;gBACVnB,IAAMmB,EAAAA,SAAAA;AACR,aAAA,CAAA,CAAA;AACF,SAAA;AACF,KAAA;AAEA,IAAA,OAAOJ,eACJK,CAAAA,IAAI,CACH,CAACpB,QACE;AAAEA,YAAAA,IAAAA;YAAML,QAAUmB,EAAAA,gBAAAA;AAAiB,SAAA,CAKvCO,CAAAA,CAAAA,KAAK,CACJ,CAACpB,SACE;AAAEA,YAAAA,KAAAA;YAAON,QAAUmB,EAAAA,gBAAAA;SAAiB,CAAA,CAAA,CAAA;AAK7C;;;;;"}
|
|
@@ -20,11 +20,21 @@
|
|
|
20
20
|
return resolveResponse(response, response.ok ? textResponse : Promise.reject(await textResponse));
|
|
21
21
|
}
|
|
22
22
|
function resolveResponse(responseToReturn, responsePromise) {
|
|
23
|
-
if (!responsePromise)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
if (!responsePromise) {
|
|
24
|
+
if (responseToReturn instanceof Response) {
|
|
25
|
+
return Promise.resolve({
|
|
26
|
+
error: new Error('Unhandled response without promise to resolve'),
|
|
27
|
+
response: responseToReturn,
|
|
28
|
+
data: undefined
|
|
29
|
+
});
|
|
30
|
+
} else {
|
|
31
|
+
return Promise.resolve({
|
|
32
|
+
error: responseToReturn,
|
|
33
|
+
response: undefined,
|
|
34
|
+
data: undefined
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
28
38
|
return responsePromise.then((data)=>({
|
|
29
39
|
data,
|
|
30
40
|
response: responseToReturn
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responseUtils.js","sources":["../../../src/lib/responseUtils.ts"],"sourcesContent":["import type { RequestFnResponse } from '@openapi-qraft/tanstack-query-react-types';\n\n/**\n * Processes the response from the server.\n * @beta\n */\nexport async function processResponse<TData, TError>(\n response: Response\n): Promise<RequestFnResponse<TData, TError>> {\n if (response.status === 204 || response.headers.get('Content-Length') === '0')\n return (\n response.ok ? { data: null, response } : { error: null, response }\n ) as RequestFnResponse<TData, TError>;\n\n const contentType = response.headers.get('Content-Type')?.toLowerCase();\n\n const isJsonResponse =\n contentType?.includes('/json') || contentType?.includes('+json');\n\n if (isJsonResponse) {\n // clone response before parsing every time to allow multiple reads\n const jsonResponse = response.clone().json();\n return resolveResponse(\n response,\n response.ok ? jsonResponse : Promise.reject(await jsonResponse)\n );\n }\n\n const textResponse = response.clone().text() as Promise<TData>;\n\n return resolveResponse(\n response,\n response.ok ? textResponse : Promise.reject(await textResponse)\n );\n}\n\n/**\n * Resolves the response from the server.\n * @beta\n */\nexport function resolveResponse<TData, TError>(\n error: Error\n): Promise<RequestFnResponse<TData, TError>>;\nexport function resolveResponse<TData, TError>(\n responseToReturn: Response,\n responsePromise: Promise<TData>\n): Promise<RequestFnResponse<TData, TError>>;\nexport function resolveResponse<TData, TError>(\n responseToReturn: Response | Error,\n responsePromise?: Promise<TData>\n): Promise<RequestFnResponse<TData, TError>> {\n if (!responsePromise)\n return Promise.
|
|
1
|
+
{"version":3,"file":"responseUtils.js","sources":["../../../src/lib/responseUtils.ts"],"sourcesContent":["import type { RequestFnResponse } from '@openapi-qraft/tanstack-query-react-types';\n\n/**\n * Processes the response from the server.\n * @beta\n */\nexport async function processResponse<TData, TError>(\n response: Response\n): Promise<RequestFnResponse<TData, TError>> {\n if (response.status === 204 || response.headers.get('Content-Length') === '0')\n return (\n response.ok ? { data: null, response } : { error: null, response }\n ) as RequestFnResponse<TData, TError>;\n\n const contentType = response.headers.get('Content-Type')?.toLowerCase();\n\n const isJsonResponse =\n contentType?.includes('/json') || contentType?.includes('+json');\n\n if (isJsonResponse) {\n // clone response before parsing every time to allow multiple reads\n const jsonResponse = response.clone().json();\n return resolveResponse(\n response,\n response.ok ? jsonResponse : Promise.reject(await jsonResponse)\n );\n }\n\n const textResponse = response.clone().text() as Promise<TData>;\n\n return resolveResponse(\n response,\n response.ok ? textResponse : Promise.reject(await textResponse)\n );\n}\n\n/**\n * Resolves the response from the server.\n * @beta\n */\nexport function resolveResponse<TData, TError>(\n error: Error\n): Promise<RequestFnResponse<TData, TError>>;\nexport function resolveResponse<TData, TError>(\n responseToReturn: Response,\n responsePromise: Promise<TData>\n): Promise<RequestFnResponse<TData, TError>>;\nexport function resolveResponse<TData, TError>(\n responseToReturn: Response | Error,\n responsePromise?: Promise<TData>\n): Promise<RequestFnResponse<TData, TError>> {\n if (!responsePromise) {\n if (responseToReturn instanceof Response) {\n return Promise.resolve({\n error: new Error('Unhandled response without promise to resolve'),\n response: responseToReturn,\n data: undefined,\n });\n } else {\n return Promise.resolve({\n error: responseToReturn,\n response: undefined,\n data: undefined,\n });\n }\n }\n\n return responsePromise\n .then(\n (data) =>\n ({ data, response: responseToReturn }) as RequestFnResponse<\n TData,\n TError\n >\n )\n .catch(\n (error) =>\n ({ error, response: responseToReturn }) as RequestFnResponse<\n TData,\n TError\n >\n );\n}\n"],"names":["processResponse","response","status","headers","get","ok","data","error","contentType","toLowerCase","isJsonResponse","includes","jsonResponse","clone","json","resolveResponse","Promise","reject","textResponse","text","responseToReturn","responsePromise","Response","resolve","Error","undefined","then","catch"],"mappings":"AAEA;;;IAIO,eAAeA,eAAAA,CACpBC,QAAkB,EAAA;AAElB,IAAA,IAAIA,QAASC,CAAAA,MAAM,KAAK,GAAA,IAAOD,SAASE,OAAO,CAACC,GAAG,CAAC,gBAAsB,CAAA,KAAA,GAAA,EACxE,OACEH,QAAAA,CAASI,EAAE,GAAG;QAAEC,IAAM,EAAA,IAAA;AAAML,QAAAA,QAAAA;KAAa,GAAA;QAAEM,KAAO,EAAA,IAAA;AAAMN,QAAAA,QAAAA;AAAS,KAAA,CAAA;AAGrE,IAAA,MAAMO,cAAcP,QAASE,CAAAA,OAAO,CAACC,GAAG,CAAC,cAAiBK,CAAAA,EAAAA,WAAAA,EAAAA,CAAAA;AAE1D,IAAA,MAAMC,cACJF,GAAAA,WAAAA,EAAaG,QAAS,CAAA,OAAA,CAAA,IAAYH,aAAaG,QAAS,CAAA,OAAA,CAAA,CAAA;AAE1D,IAAA,IAAID,cAAgB,EAAA;;AAElB,QAAA,MAAME,YAAeX,GAAAA,QAAAA,CAASY,KAAK,EAAA,CAAGC,IAAI,EAAA,CAAA;QAC1C,OAAOC,eAAAA,CACLd,UACAA,QAASI,CAAAA,EAAE,GAAGO,YAAeI,GAAAA,OAAAA,CAAQC,MAAM,CAAC,MAAML,YAAAA,CAAAA,CAAAA,CAAAA;AAEtD,KAAA;AAEA,IAAA,MAAMM,YAAejB,GAAAA,QAAAA,CAASY,KAAK,EAAA,CAAGM,IAAI,EAAA,CAAA;IAE1C,OAAOJ,eAAAA,CACLd,UACAA,QAASI,CAAAA,EAAE,GAAGa,YAAeF,GAAAA,OAAAA,CAAQC,MAAM,CAAC,MAAMC,YAAAA,CAAAA,CAAAA,CAAAA;AAEtD,CAAA;AAaO,SAASH,eAAAA,CACdK,gBAAkC,EAClCC,eAAgC,EAAA;AAEhC,IAAA,IAAI,CAACA,eAAiB,EAAA;AACpB,QAAA,IAAID,4BAA4BE,QAAU,EAAA;YACxC,OAAON,OAAAA,CAAQO,OAAO,CAAC;AACrBhB,gBAAAA,KAAAA,EAAO,IAAIiB,KAAM,CAAA,+CAAA,CAAA;gBACjBvB,QAAUmB,EAAAA,gBAAAA;gBACVd,IAAMmB,EAAAA,SAAAA;AACR,aAAA,CAAA,CAAA;SACK,MAAA;YACL,OAAOT,OAAAA,CAAQO,OAAO,CAAC;gBACrBhB,KAAOa,EAAAA,gBAAAA;gBACPnB,QAAUwB,EAAAA,SAAAA;gBACVnB,IAAMmB,EAAAA,SAAAA;AACR,aAAA,CAAA,CAAA;AACF,SAAA;AACF,KAAA;AAEA,IAAA,OAAOJ,eACJK,CAAAA,IAAI,CACH,CAACpB,QACE;AAAEA,YAAAA,IAAAA;YAAML,QAAUmB,EAAAA,gBAAAA;AAAiB,SAAA,CAKvCO,CAAAA,CAAAA,KAAK,CACJ,CAACpB,SACE;AAAEA,YAAAA,KAAAA;YAAON,QAAUmB,EAAAA,gBAAAA;SAAiB,CAAA,CAAA,CAAA;AAK7C;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responseUtils.test.d.ts","sourceRoot":"","sources":["../../../../src/lib/__tests__/responseUtils.test.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openapi-qraft/react",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.4",
|
|
4
4
|
"description": "OpenAPI client for React, providing type-safe requests and dynamic TanStack Query React Hooks via a modular, Proxy-based architecture.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "NODE_ENV=production rollup --config rollup.config.mjs && tsc --project tsconfig.build.json --emitDeclarationOnly",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"sideEffects": false,
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@openapi-qraft/tanstack-query-react-types": "2.6.
|
|
18
|
+
"@openapi-qraft/tanstack-query-react-types": "2.6.4"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"@tanstack/query-core": "^5.0.0",
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"react": "^18 || ^19"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@openapi-qraft/cli": "2.6.
|
|
26
|
+
"@openapi-qraft/cli": "2.6.4",
|
|
27
27
|
"@openapi-qraft/eslint-config": "1.0.1",
|
|
28
|
-
"@openapi-qraft/openapi-typescript-plugin": "^1.2.
|
|
28
|
+
"@openapi-qraft/openapi-typescript-plugin": "^1.2.20",
|
|
29
29
|
"@openapi-qraft/rollup-config": "1.1.1",
|
|
30
|
-
"@openapi-qraft/tanstack-query-react-plugin": "2.6.
|
|
30
|
+
"@openapi-qraft/tanstack-query-react-plugin": "2.6.4",
|
|
31
31
|
"@openapi-qraft/test-fixtures": "1.1.0",
|
|
32
32
|
"@tanstack/query-core": "^5.66.3",
|
|
33
33
|
"@tanstack/react-query": "^5.66.3",
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { resolveResponse } from '../responseUtils.js';
|
|
3
|
+
|
|
4
|
+
describe('resolveResponse', () => {
|
|
5
|
+
it('should handle Error without promise', async () => {
|
|
6
|
+
const testError = new Error('Test error');
|
|
7
|
+
|
|
8
|
+
const result = await resolveResponse<unknown, Error>(testError);
|
|
9
|
+
|
|
10
|
+
expect(result).toEqual({
|
|
11
|
+
error: testError,
|
|
12
|
+
response: undefined,
|
|
13
|
+
data: undefined,
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should handle Response without promise', async () => {
|
|
18
|
+
const mockResponse = new Response(null);
|
|
19
|
+
|
|
20
|
+
// We use casting to bypass type checking, since we know that the function accepts Response
|
|
21
|
+
// without a promise in the implementation, although types do not allow it directly.
|
|
22
|
+
const result = await (resolveResponse as any)(mockResponse);
|
|
23
|
+
|
|
24
|
+
expect(result).toEqual({
|
|
25
|
+
error: expect.any(Error),
|
|
26
|
+
response: mockResponse,
|
|
27
|
+
data: undefined,
|
|
28
|
+
});
|
|
29
|
+
expect((result.error as Error).message).toBe(
|
|
30
|
+
'Unhandled response without promise to resolve'
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should resolve promise with data and response', async () => {
|
|
35
|
+
const mockResponse = new Response(null);
|
|
36
|
+
const testData = { test: 'data' };
|
|
37
|
+
const dataPromise = Promise.resolve(testData);
|
|
38
|
+
|
|
39
|
+
const result = await resolveResponse<typeof testData, Error>(
|
|
40
|
+
mockResponse,
|
|
41
|
+
dataPromise
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(result).toEqual({
|
|
45
|
+
data: testData,
|
|
46
|
+
response: mockResponse,
|
|
47
|
+
error: undefined,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should handle rejected promise with error and response', async () => {
|
|
52
|
+
const mockResponse = new Response(null);
|
|
53
|
+
const testError = new Error('Test rejection');
|
|
54
|
+
const dataPromise = Promise.reject(testError);
|
|
55
|
+
|
|
56
|
+
const result = await resolveResponse<unknown, Error>(
|
|
57
|
+
mockResponse,
|
|
58
|
+
dataPromise
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
expect(result).toEqual({
|
|
62
|
+
error: testError,
|
|
63
|
+
response: mockResponse,
|
|
64
|
+
data: undefined,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should handle custom error objects in rejected promise', async () => {
|
|
69
|
+
const mockResponse = new Response(null);
|
|
70
|
+
type CustomError = { code: string; message: string };
|
|
71
|
+
const customError: CustomError = {
|
|
72
|
+
code: 'CUSTOM_ERROR',
|
|
73
|
+
message: 'Custom error object',
|
|
74
|
+
};
|
|
75
|
+
const dataPromise = Promise.reject(customError);
|
|
76
|
+
|
|
77
|
+
const result = await resolveResponse<unknown, CustomError>(
|
|
78
|
+
mockResponse,
|
|
79
|
+
dataPromise
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
expect(result).toEqual({
|
|
83
|
+
error: customError,
|
|
84
|
+
response: mockResponse,
|
|
85
|
+
data: undefined,
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should preserve response object when promise resolves', async () => {
|
|
90
|
+
const headers = new Headers();
|
|
91
|
+
headers.append('Content-Type', 'application/json');
|
|
92
|
+
const mockResponse = new Response('{"key":"value"}', { headers });
|
|
93
|
+
const testData = { key: 'value' };
|
|
94
|
+
const dataPromise = Promise.resolve(testData);
|
|
95
|
+
|
|
96
|
+
const result = await resolveResponse<typeof testData, Error>(
|
|
97
|
+
mockResponse,
|
|
98
|
+
dataPromise
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
expect(result.response).toBe(mockResponse);
|
|
102
|
+
expect(result.data).toEqual(testData);
|
|
103
|
+
expect(result.error).toBeUndefined();
|
|
104
|
+
});
|
|
105
|
+
});
|
package/src/lib/responseUtils.ts
CHANGED
|
@@ -49,12 +49,21 @@ export function resolveResponse<TData, TError>(
|
|
|
49
49
|
responseToReturn: Response | Error,
|
|
50
50
|
responsePromise?: Promise<TData>
|
|
51
51
|
): Promise<RequestFnResponse<TData, TError>> {
|
|
52
|
-
if (!responsePromise)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
if (!responsePromise) {
|
|
53
|
+
if (responseToReturn instanceof Response) {
|
|
54
|
+
return Promise.resolve({
|
|
55
|
+
error: new Error('Unhandled response without promise to resolve'),
|
|
56
|
+
response: responseToReturn,
|
|
57
|
+
data: undefined,
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
return Promise.resolve({
|
|
61
|
+
error: responseToReturn,
|
|
62
|
+
response: undefined,
|
|
63
|
+
data: undefined,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
58
67
|
|
|
59
68
|
return responsePromise
|
|
60
69
|
.then(
|