diff --git a/package-lock.json b/package-lock.json index 267a577..ca53b08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/env": "^3.0.2", + "@humanwhocodes/env": "^3.0.5", "@krutoo/fetch-tools": "^0.0.16", "@opentelemetry/api": "^1.4.1", "@opentelemetry/exporter-prometheus": "^0.38.0", @@ -2339,9 +2339,9 @@ } }, "node_modules/@humanwhocodes/env": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/env/-/env-3.0.2.tgz", - "integrity": "sha512-javcHttnb+kJamJQZZoQ5+um1yx07/tHx56bJ81Dt+jpPR42u+xvDhWe6yDiz+wtBchfcg5vNqanxC9+Gjpnrg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/env/-/env-3.0.5.tgz", + "integrity": "sha512-IpnujSwQ93i/amSy4GoynqaOAjbYKAI1b28JmPogfEytAh2aSjOE2ZlFnOAuXHUt3OQA41RvU0JL4lzTnVKeIw==", "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" @@ -6026,11 +6026,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -8077,9 +8077,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -17516,9 +17516,9 @@ } }, "@humanwhocodes/env": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/env/-/env-3.0.2.tgz", - "integrity": "sha512-javcHttnb+kJamJQZZoQ5+um1yx07/tHx56bJ81Dt+jpPR42u+xvDhWe6yDiz+wtBchfcg5vNqanxC9+Gjpnrg==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/env/-/env-3.0.5.tgz", + "integrity": "sha512-IpnujSwQ93i/amSy4GoynqaOAjbYKAI1b28JmPogfEytAh2aSjOE2ZlFnOAuXHUt3OQA41RvU0JL4lzTnVKeIw==" }, "@humanwhocodes/module-importer": { "version": "1.0.1", @@ -20356,11 +20356,11 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browser-process-hrtime": { @@ -21864,9 +21864,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "requires": { "to-regex-range": "^5.0.1" } diff --git a/package.json b/package.json index fcb93c6..7517cae 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "whatwg-fetch": "^3.6.17" }, "dependencies": { - "@humanwhocodes/env": "^3.0.2", + "@humanwhocodes/env": "^3.0.5", "@krutoo/fetch-tools": "^0.0.16", "@opentelemetry/api": "^1.4.1", "@opentelemetry/exporter-prometheus": "^0.38.0", diff --git a/src/config/source.ts b/src/config/source.ts index 871f4e9..a7f3c8e 100644 --- a/src/config/source.ts +++ b/src/config/source.ts @@ -1,6 +1,4 @@ import type { ConfigSource, Dictionary } from './types'; - -// @ts-expect-error: https://github.com/humanwhocodes/env/issues/133 (@todo разобраться и убрать) import { Env } from '@humanwhocodes/env'; declare const __ISOMORPH_ENV__: unknown; diff --git a/src/http/__test__/utils.test.ts b/src/http/__test__/utils.test.ts index bcf78fe..55913a3 100644 --- a/src/http/__test__/utils.test.ts +++ b/src/http/__test__/utils.test.ts @@ -91,13 +91,16 @@ describe('FetchUtil', () => { error: null, status: 200, statusText: 'GOOD', + headers: new Headers({ 'content-type': 'text/plain;charset=UTF-8' }), }); expect(await handleDone(responseFail)).toEqual({ ok: false, - error: `Request failed with status 400`, + data: { data: 'bar' }, + error: new Error(`Request failed with status code 400`), status: 400, statusText: 'BAD', + headers: new Headers({ 'content-type': 'text/plain;charset=UTF-8' }), }); const error = new Error('Fetch failed'); diff --git a/src/http/types.ts b/src/http/types.ts index a85c770..4d9b76a 100644 --- a/src/http/types.ts +++ b/src/http/types.ts @@ -19,6 +19,7 @@ export interface ResponseDone { error: null; status: number; statusText: string; + headers: Headers; } export interface ResponseFail { @@ -27,6 +28,7 @@ export interface ResponseFail { error: unknown; status?: number; statusText?: string; + headers?: Headers; } export type EitherResponse = ResponseDone | ResponseFail; diff --git a/src/http/utils.ts b/src/http/utils.ts index 3f2c99e..98a18d2 100644 --- a/src/http/utils.ts +++ b/src/http/utils.ts @@ -55,33 +55,41 @@ export const FetchUtil = { /** * Возвращает кортеж обработчиков для Promise из fetch. * Полученный Promise никогда не уйдет в состояние rejected. + * @param options Опции. * @return Кортеж. */ - eitherResponse() { + eitherResponse({ + parseBody = response => response.json(), + }: { + /** Парсер body. */ + parseBody?: (response: Response) => Promise; + } = {}) { return [ - (response: Response): Promise | ResponseFail> => { - if (response.ok) { - return response.json().then(data => ({ - ok: true, - data: data as T, - error: null, - status: response.status, - statusText: response.statusText, - })); - } else { - return Promise.resolve({ + async (response: Response): Promise | ResponseFail> => { + if (!response.ok) { + return { ok: false, - error: `Request failed with status ${response.status}`, + data: (await parseBody(response).catch(() => null)) as T, + error: new Error(`Request failed with status code ${response.status}`), status: response.status, statusText: response.statusText, - }); + headers: response.headers, + }; } + + return { + ok: true, + data: (await parseBody(response).catch(() => null)) as T, + error: null, + status: response.status, + statusText: response.statusText, + headers: response.headers, + }; }, - (error: unknown): Promise> => - Promise.resolve({ - ok: false, - error, - }), + async (error: unknown): Promise> => ({ + ok: false, + error, + }), ] as const; }, } as const;