From 49c86ba2ea5aa20d1cb44788ed88c9d8141bb34f Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Thu, 27 Jun 2024 12:13:51 +0300 Subject: [PATCH 01/12] feat: allow specifying custom no content statuses --- .../request/engines/provider/interface.ts | 4 +-- src/core/request/index.ts | 1 + src/core/request/interface.ts | 15 ++++++-- src/core/request/response/const.ts | 21 ++++++----- src/core/request/response/helpers.ts | 16 +++++++++ src/core/request/response/index.ts | 35 +++++++++++++------ src/core/request/response/interface.ts | 5 +-- 7 files changed, 71 insertions(+), 26 deletions(-) create mode 100644 src/core/request/response/helpers.ts diff --git a/src/core/request/engines/provider/interface.ts b/src/core/request/engines/provider/interface.ts index 969b24d3a..90de2099f 100644 --- a/src/core/request/engines/provider/interface.ts +++ b/src/core/request/engines/provider/interface.ts @@ -11,7 +11,7 @@ import type { Provider, ModelMethod } from 'core/data'; import type { - OkStatuses, + Statuses, RequestBody, RequestMethod, @@ -40,7 +40,7 @@ export interface AvailableOptions { timeout?: number; contentType?: string; - okStatuses?: OkStatuses; + okStatuses?: Statuses; meta: Meta; important?: boolean; diff --git a/src/core/request/index.ts b/src/core/request/index.ts index fd36ba7cd..a7866e540 100644 --- a/src/core/request/index.ts +++ b/src/core/request/index.ts @@ -44,6 +44,7 @@ import type { export * from 'core/request/helpers'; export * from 'core/request/interface'; +export * from 'core/request/response/helpers'; export * from 'core/request/response/interface'; export { globalOpts, cache, pendingCache } from 'core/request/const'; diff --git a/src/core/request/interface.ts b/src/core/request/interface.ts index a4bc3fc89..059a93034 100644 --- a/src/core/request/interface.ts +++ b/src/core/request/interface.ts @@ -65,7 +65,7 @@ export type NormalizedRequestBody = Exclude< number | boolean | Dictionary >; -export type OkStatuses = +export type Statuses = Range | StatusCodes | StatusCodes[]; @@ -267,7 +267,16 @@ export interface CreateRequestOptions { * * @default `new Range(200, 299)` */ - okStatuses?: OkStatuses; + okStatuses?: Statuses; + + /** + * A list of status codes (or a single code) that match response with no content. + * Also, you can pass a range of codes. + * + * @default `[statusCodes.NO_CONTENT, statusCodes.NOT_MODIFIED] + * .concat(new Range(100, 199).toArray(1))` + */ + noContentStatuses?: Statuses; /** * Value in milliseconds for a request timeout @@ -671,7 +680,7 @@ export interface RequestOptions { readonly parent: AbortablePromise; readonly timeout?: number; - readonly okStatuses?: OkStatuses; + readonly okStatuses?: Statuses; readonly contentType?: string; readonly responseType?: ResponseType; diff --git a/src/core/request/response/const.ts b/src/core/request/response/const.ts index 9fa94abd2..6a857dde2 100644 --- a/src/core/request/response/const.ts +++ b/src/core/request/response/const.ts @@ -10,15 +10,6 @@ import Range from 'core/range'; import statusCodes from 'core/status-codes'; import type { ResponseType } from 'core/request'; -export const defaultResponseOpts = { - url: '', - redirected: false, - status: 200, - statusText: 'OK', - okStatuses: new Range(200, 299), - responseType: 'text', - headers: {} -}; /** * Status codes that cannot contain any content according to the HTTP standard @@ -30,3 +21,15 @@ export const defaultResponseOpts = { export const noContentStatusCodes: number[] = [statusCodes.NO_CONTENT, statusCodes.NOT_MODIFIED] .concat(new Range(100, 199).toArray(1)); + + +export const defaultResponseOpts = { + url: '', + redirected: false, + status: 200, + statusText: 'OK', + okStatuses: new Range(200, 299), + noContentStatuses: noContentStatusCodes, + responseType: 'text', + headers: {} +}; diff --git a/src/core/request/response/helpers.ts b/src/core/request/response/helpers.ts new file mode 100644 index 000000000..88bb6b503 --- /dev/null +++ b/src/core/request/response/helpers.ts @@ -0,0 +1,16 @@ +import type { StatusCodes } from 'core/status-codes'; +import type { Statuses } from 'core/request/interface'; +import Range from 'core/range'; + +/** + * Returns true if specified `statuses` contain specified `statusCode` + * + * @param statuses + * @param statusCode + */ +export function statusesContainStatus(statuses: Statuses, statusCode: StatusCodes): boolean { + + return statuses instanceof Range ? + statuses.contains(statusCode) : + Array.concat([], statuses).includes(statusCode); +} diff --git a/src/core/request/response/index.ts b/src/core/request/response/index.ts index b89277ab6..7d723d43b 100644 --- a/src/core/request/response/index.ts +++ b/src/core/request/response/index.ts @@ -23,17 +23,16 @@ import Parser, { Token } from 'core/json/stream/parser'; import { createControllablePromise } from 'core/promise'; import AbortablePromise from 'core/promise/abortable'; -import Range from 'core/range'; import symbolGenerator from 'core/symbol'; import Headers from 'core/request/headers'; import { FormData, Blob } from 'core/request/engines'; -import { defaultResponseOpts, noContentStatusCodes } from 'core/request/response/const'; +import { defaultResponseOpts } from 'core/request/response/const'; import type { - OkStatuses, + Statuses, RequestResponseChunk, WrappedDecoder, @@ -53,10 +52,13 @@ import type { } from 'core/request/response/interface'; +import { statusesContainStatus } from 'core/request/response/helpers'; + export * from 'core/request/headers'; export * from 'core/request/response/const'; export * from 'core/request/response/interface'; +export * from 'core/request/response/helpers'; export const $$ = symbolGenerator(); @@ -130,11 +132,23 @@ export default class Response< */ readonly ok: boolean; + /** + * True if the response status matches with no content status codes + * (by default it should match range from 100 to 199, 204 or 304) + */ + readonly hasNoContent: boolean; + /** * A list of status codes (or a single code) that match successful operation. * Also, you can pass a range of codes. */ - readonly okStatuses: OkStatuses; + readonly okStatuses: Statuses; + + /** + * A list of status codes (or a single code) that match a response with no content. + * Also, you can pass a range of codes. + */ + readonly noContentStatuses: Statuses; /** * Set of response headers @@ -225,15 +239,16 @@ export default class Response< this.important = p.important; const - ok = p.okStatuses; + ok = p.okStatuses, + noContent = p.noContentStatuses; this.status = p.status; this.okStatuses = ok; + this.noContentStatuses = noContent; this.statusText = p.statusText; - this.ok = ok instanceof Range ? - ok.contains(this.status) : - Array.concat([], ok).includes(this.status); + this.ok = statusesContainStatus(ok, this.status); + this.hasNoContent = statusesContainStatus(noContent, this.status); this.headers = Object.freeze(new Headers(p.headers)); @@ -350,7 +365,7 @@ export default class Response< let data; - if (noContentStatusCodes.includes(this.status)) { + if (this.hasNoContent) { data = null; } else { @@ -403,7 +418,7 @@ export default class Response< let stream; - if (noContentStatusCodes.includes(this.status)) { + if (this.hasNoContent) { stream = [].values(); } else { diff --git a/src/core/request/response/interface.ts b/src/core/request/response/interface.ts index 46f935e40..b485559a5 100644 --- a/src/core/request/response/interface.ts +++ b/src/core/request/response/interface.ts @@ -13,7 +13,7 @@ import type { DataType } from 'core/mime-type'; import type { - OkStatuses, + Statuses, WrappedDecoder, WrappedDecoders, @@ -76,7 +76,8 @@ export interface ResponseOptions { status?: StatusCodes; statusText?: string; - okStatuses?: OkStatuses; + okStatuses?: Statuses; + noContentStatuses?: Statuses; responseType?: ResponseType; forceResponseType?: boolean; From a2ba462be976aaf9965a995c02a55c4da38101ba Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Thu, 27 Jun 2024 12:27:14 +0300 Subject: [PATCH 02/12] test: custom empty body statuses --- src/core/request/spec.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/core/request/spec.js b/src/core/request/spec.js index d191dc612..47b149dfb 100644 --- a/src/core/request/spec.js +++ b/src/core/request/spec.js @@ -35,6 +35,7 @@ class TestRequestChainProvider extends Provider { const emptyBodyStatuses = [204, 304], + customEmptyBodyStatuses = [121, 222, 323, 424, 525], faviconBase64 = 'AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAnISL6JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL5JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL1JyEi9ichIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEihCchIpgnISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEixCUgIRMmICEvJyEi5ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIrYnISKSJyEi9ichIlxQREUAHxobAichIo4nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISJeJyEiICchIuAnISJJJiAhbCYgITgmICEnJyEi4ichIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEiXichIiAnISLdJyEihichIuknISKkIRwdBCchIoUnISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIl4nISIgJyEi4ichIu4nISL/JyEi8CYgIT8mICEhJyEi3CchIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISJeJyEiHychIuUnISL/JyEi/ychIv8nISKrIh0eBiYhInwnISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEiXSYgITUnISLvJyEi/ychIv8nISL/JyEi9CYgIUcmICEbJyEi1ichIv8nISL/JyEi/ychIv8nISL/JyEi/ichImknISKjJyEi/ychIv8nISL/JyEi/ychIv8nISKzIRwdBiYhIX0nISL/JyEi/ychIv8nISL/JyEi/ychIvwnISK+JyEi9CchIv8nISL/JyEi/ychIv8nISL/JyEi9yYhIoonISKzJyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ichIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL6JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='; describe('core/request', () => { @@ -460,6 +461,17 @@ describe('core/request', () => { expect(await req.data).toBe(null); }); } + + for (const status of customEmptyBodyStatuses) { + it(`response with ${status} status included in custom noContentStatuses`, async () => { + const req = await request(`http://localhost:4000/octet/${status}`, { + okStatuses: status, + noContentStatuses: status + }); + + expect(await req.data).toBe(null); + }); + } }); it('retrying of a request', async () => { @@ -795,7 +807,7 @@ function createServer() { res.send(Buffer.from(faviconBase64, 'base64')); }); - for (const status of emptyBodyStatuses) { + for (const status of [].concat(emptyBodyStatuses, customEmptyBodyStatuses)) { serverApp.get(`/octet/${status}`, (req, res) => { res.type('application/octet-stream').status(status).end(); }); From e70689594f32819a07b73db16f077b81add6b63c Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Thu, 27 Jun 2024 12:30:58 +0300 Subject: [PATCH 03/12] chore: fix eslint --- src/core/request/interface.ts | 2 +- src/core/request/response/const.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/request/interface.ts b/src/core/request/interface.ts index 059a93034..5ce3916cd 100644 --- a/src/core/request/interface.ts +++ b/src/core/request/interface.ts @@ -274,7 +274,7 @@ export interface CreateRequestOptions { * Also, you can pass a range of codes. * * @default `[statusCodes.NO_CONTENT, statusCodes.NOT_MODIFIED] - * .concat(new Range(100, 199).toArray(1))` + * .concat(new Range(100, 199).toArray(1))` */ noContentStatuses?: Statuses; diff --git a/src/core/request/response/const.ts b/src/core/request/response/const.ts index 6a857dde2..9090d2a8c 100644 --- a/src/core/request/response/const.ts +++ b/src/core/request/response/const.ts @@ -10,7 +10,6 @@ import Range from 'core/range'; import statusCodes from 'core/status-codes'; import type { ResponseType } from 'core/request'; - /** * Status codes that cannot contain any content according to the HTTP standard * @@ -22,7 +21,6 @@ export const noContentStatusCodes: number[] = [statusCodes.NO_CONTENT, statusCodes.NOT_MODIFIED] .concat(new Range(100, 199).toArray(1)); - export const defaultResponseOpts = { url: '', redirected: false, From 62fe5b93523d8db1f93719bbc97d198f9204926a Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Thu, 27 Jun 2024 13:11:38 +0300 Subject: [PATCH 04/12] fix: pass noContentStatuses where needed --- src/core/data/middlewares/attach-mock/attach-mock.ts | 1 + src/core/request/engines/fetch/index.ts | 1 + src/core/request/engines/provider/const.ts | 1 + src/core/request/engines/provider/index.ts | 1 + src/core/request/engines/provider/interface.ts | 2 +- src/core/request/engines/xhr/index.ts | 1 + src/core/request/interface.ts | 1 + src/core/request/spec.js | 2 +- 8 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/core/data/middlewares/attach-mock/attach-mock.ts b/src/core/data/middlewares/attach-mock/attach-mock.ts index d2cb0b489..91a5602f1 100644 --- a/src/core/data/middlewares/attach-mock/attach-mock.ts +++ b/src/core/data/middlewares/attach-mock/attach-mock.ts @@ -63,6 +63,7 @@ export async function attachMock(this: Provider, params: MiddlewareParams): Prom status: customResponse.status ?? mock.status ?? 200, responseType: customResponse.responseType ?? (mock).responseType ?? opts.responseType, okStatuses: opts.okStatuses, + noContentStatuses: opts.noContentStatuses, decoder: mock.decoders === false ? undefined : customResponse.decoders ?? ctx.decoders, headers: customResponse.headers ?? mock.headers }); diff --git a/src/core/request/engines/fetch/index.ts b/src/core/request/engines/fetch/index.ts index 9ca580fb5..7bc907941 100644 --- a/src/core/request/engines/fetch/index.ts +++ b/src/core/request/engines/fetch/index.ts @@ -152,6 +152,7 @@ const request: RequestEngine = (params) => { important: p.important, okStatuses: p.okStatuses, + noContentStatuses: p.noContentStatuses, status: res.status, statusText: res.statusText, diff --git a/src/core/request/engines/provider/const.ts b/src/core/request/engines/provider/const.ts index 3e796e7e0..d583b46e4 100644 --- a/src/core/request/engines/provider/const.ts +++ b/src/core/request/engines/provider/const.ts @@ -14,6 +14,7 @@ export const availableParams = [ 'query', 'headers', 'okStatuses', + 'noContentStatuses', 'timeout', 'important', 'meta', diff --git a/src/core/request/engines/provider/index.ts b/src/core/request/engines/provider/index.ts index b891058ea..1deae41dc 100644 --- a/src/core/request/engines/provider/index.ts +++ b/src/core/request/engines/provider/index.ts @@ -189,6 +189,7 @@ export default function createProviderEngine( important: providerResponse.important, okStatuses: providerResponse.okStatuses, + noContentStatuses: providerResponse.noContentStatuses, status: providerResponse.status, statusText: providerResponse.statusText, diff --git a/src/core/request/engines/provider/interface.ts b/src/core/request/engines/provider/interface.ts index 90de2099f..b8c561932 100644 --- a/src/core/request/engines/provider/interface.ts +++ b/src/core/request/engines/provider/interface.ts @@ -41,7 +41,7 @@ export interface AvailableOptions { timeout?: number; contentType?: string; okStatuses?: Statuses; - + noContentStatuses?: Statuses; meta: Meta; important?: boolean; diff --git a/src/core/request/engines/xhr/index.ts b/src/core/request/engines/xhr/index.ts index 1024a4c20..dcb9e5b68 100644 --- a/src/core/request/engines/xhr/index.ts +++ b/src/core/request/engines/xhr/index.ts @@ -143,6 +143,7 @@ const request: RequestEngine = (params) => { important: p.important, okStatuses: p.okStatuses, + noContentStatuses: p.noContentStatuses, status: xhr.status, statusText: xhr.statusText, diff --git a/src/core/request/interface.ts b/src/core/request/interface.ts index 5ce3916cd..12b5d9168 100644 --- a/src/core/request/interface.ts +++ b/src/core/request/interface.ts @@ -681,6 +681,7 @@ export interface RequestOptions { readonly timeout?: number; readonly okStatuses?: Statuses; + readonly noContentStatuses?: Statuses; readonly contentType?: string; readonly responseType?: ResponseType; diff --git a/src/core/request/spec.js b/src/core/request/spec.js index 47b149dfb..96d2bb665 100644 --- a/src/core/request/spec.js +++ b/src/core/request/spec.js @@ -35,7 +35,7 @@ class TestRequestChainProvider extends Provider { const emptyBodyStatuses = [204, 304], - customEmptyBodyStatuses = [121, 222, 323, 424, 525], + customEmptyBodyStatuses = [222, 323, 424, 525], faviconBase64 = 'AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAnISL6JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL5JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL1JyEi9ichIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEihCchIpgnISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEixCUgIRMmICEvJyEi5ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIrYnISKSJyEi9ichIlxQREUAHxobAichIo4nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISJeJyEiICchIuAnISJJJiAhbCYgITgmICEnJyEi4ichIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEiXichIiAnISLdJyEihichIuknISKkIRwdBCchIoUnISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIl4nISIgJyEi4ichIu4nISL/JyEi8CYgIT8mICEhJyEi3CchIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISJeJyEiHychIuUnISL/JyEi/ychIv8nISKrIh0eBiYhInwnISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEiXSYgITUnISLvJyEi/ychIv8nISL/JyEi9CYgIUcmICEbJyEi1ichIv8nISL/JyEi/ychIv8nISL/JyEi/ichImknISKjJyEi/ychIv8nISL/JyEi/ychIv8nISKzIRwdBiYhIX0nISL/JyEi/ychIv8nISL/JyEi/ychIvwnISK+JyEi9CchIv8nISL/JyEi/ychIv8nISL/JyEi9yYhIoonISKzJyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ichIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL6JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL/JyEi/ychIv8nISL6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='; describe('core/request', () => { From 6da59e4404510150b9565c2e98922235dbd1128c Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Thu, 27 Jun 2024 13:11:53 +0300 Subject: [PATCH 05/12] chore: improve test name --- src/core/request/spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/request/spec.js b/src/core/request/spec.js index 96d2bb665..e50562314 100644 --- a/src/core/request/spec.js +++ b/src/core/request/spec.js @@ -463,7 +463,7 @@ describe('core/request', () => { } for (const status of customEmptyBodyStatuses) { - it(`response with ${status} status included in custom noContentStatuses`, async () => { + it(`response with ${status} status included in custom no-content statuses`, async () => { const req = await request(`http://localhost:4000/octet/${status}`, { okStatuses: status, noContentStatuses: status From 6867aaf13551fa036b134b273d6f13ad8a5efd99 Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Thu, 27 Jun 2024 18:42:30 +0300 Subject: [PATCH 06/12] chore: improve types near Array.concat() --- src/core/request/response/helpers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/request/response/helpers.ts b/src/core/request/response/helpers.ts index 88bb6b503..cf52c67f8 100644 --- a/src/core/request/response/helpers.ts +++ b/src/core/request/response/helpers.ts @@ -12,5 +12,5 @@ export function statusesContainStatus(statuses: Statuses, statusCode: StatusCode return statuses instanceof Range ? statuses.contains(statusCode) : - Array.concat([], statuses).includes(statusCode); + Array.concat([], statuses).includes(statusCode); } From fbb7b9f92463d2a1954631bc49c6c3d27a710689 Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Thu, 27 Jun 2024 18:45:04 +0300 Subject: [PATCH 07/12] chore: explicitly handle all cases in statusesContainStatus() --- src/core/request/response/helpers.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/request/response/helpers.ts b/src/core/request/response/helpers.ts index cf52c67f8..7e66ac43c 100644 --- a/src/core/request/response/helpers.ts +++ b/src/core/request/response/helpers.ts @@ -9,8 +9,13 @@ import Range from 'core/range'; * @param statusCode */ export function statusesContainStatus(statuses: Statuses, statusCode: StatusCodes): boolean { + if (statuses instanceof Range) { + return statuses.contains(statusCode); + } - return statuses instanceof Range ? - statuses.contains(statusCode) : - Array.concat([], statuses).includes(statusCode); + if (Object.isArray(statuses)) { + return statuses.includes(statusCode); + } + + return statuses === statusCode; } From f9d8bb371403bac14cd8c0adea6e63a864a9f787 Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Thu, 27 Jun 2024 18:57:11 +0300 Subject: [PATCH 08/12] chore: add a TODO about noContentStatusCodes --- src/core/request/response/const.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/request/response/const.ts b/src/core/request/response/const.ts index 9090d2a8c..01e61a45d 100644 --- a/src/core/request/response/const.ts +++ b/src/core/request/response/const.ts @@ -16,6 +16,8 @@ import type { ResponseType } from 'core/request'; * 1xx - https://tools.ietf.org/html/rfc7231#section-6.2 * 204 - https://tools.ietf.org/html/rfc7231#section-6.3.5 * 304 - https://tools.ietf.org/html/rfc7232#section-4.1 + * + * TODO: https://github.com/V4Fire/Core/issues/421 */ export const noContentStatusCodes: number[] = [statusCodes.NO_CONTENT, statusCodes.NOT_MODIFIED] From 848a99ffb471dc3b51bfe8606579da9e0fd46282 Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Fri, 28 Jun 2024 16:54:17 +0300 Subject: [PATCH 09/12] chore: up changelog & readme --- CHANGELOG.md | 8 ++++++++ src/core/request/CHANGELOG.md | 8 ++++++++ src/core/request/README.md | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a2cb3884..a33cc7dad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,14 @@ Changelog _Note: Gaps between patch versions are faulty, broken or test releases._ +## v?.?.? (????-??-??) + +#### :rocket: New Feature + +* Added a new option `noContentStatuses`. This option allows to pass custom status code, array or range of status codes + which indicate a no-content response. By default, an array `[...Range(100, 199), 204, 304]` is used, but it may be useful + to override this value if your backend uses different status codes for no-content responses. `core/request` + ## v3.99.0 (2024-04-25) #### :rocket: New Feature diff --git a/src/core/request/CHANGELOG.md b/src/core/request/CHANGELOG.md index 40851e27f..7f2d47048 100644 --- a/src/core/request/CHANGELOG.md +++ b/src/core/request/CHANGELOG.md @@ -9,6 +9,14 @@ Changelog > - :house: [Internal] > - :nail_care: [Polish] +## v?.?.? (????-??-??) + +#### :rocket: New Feature + +* Added a new option `noContentStatuses`. This option allows to pass custom status code, array or range of status codes + which indicate a no-content response. By default, an array `[...Range(100, 199), 204, 304]` is used, but it may be useful + to override this value if your backend uses different status codes for no-content responses. `core/request` + ## v3.93.1 (2023-03-14) #### :bug: Bug Fix diff --git a/src/core/request/README.md b/src/core/request/README.md index b907833b7..f4731dc39 100644 --- a/src/core/request/README.md +++ b/src/core/request/README.md @@ -478,6 +478,24 @@ request('//users', { }).data.then(console.log); ``` +#### [noContentStatuses = `[statusCodes.NO_CONTENT, statusCodes.NOT_MODIFIED].concat(new Range(100, 199).toArray(1))`] + +A list of status codes (or a single code) that match response with no content. +Also, you can pass a range of codes. + +```js +import request from 'core/request'; +import Range from 'core/range'; + +request('//users', { + noContentStatuses: [204, 304, 424] +}).data.then(console.log); + +request('//users', { + noContentStatuses: new Range(420, 430) +}).data.then(console.log); +``` + #### timeout A value in milliseconds for a request timeout. From a5c92019b0138088edd8b088397bcc5b131df136 Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Wed, 17 Jul 2024 12:27:21 +0300 Subject: [PATCH 10/12] fix: add noContentStatuses to node engine --- src/core/request/engines/node/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/request/engines/node/index.ts b/src/core/request/engines/node/index.ts index 66ced5e6b..6fed1e12d 100644 --- a/src/core/request/engines/node/index.ts +++ b/src/core/request/engines/node/index.ts @@ -152,6 +152,7 @@ const request: RequestEngine = (params) => { important: p.important, okStatuses: p.okStatuses, + noContentStatuses: p.noContentStatuses, status: response.statusCode, statusText: response.statusMessage, From f860938e5d39540277c6773965d4d416b2d50b17 Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Wed, 17 Jul 2024 12:41:16 +0300 Subject: [PATCH 11/12] fix: add noContentStatuses to composition engine --- src/core/request/engines/composition/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/request/engines/composition/index.ts b/src/core/request/engines/composition/index.ts index 9f6bf88b6..e6428abcc 100644 --- a/src/core/request/engines/composition/index.ts +++ b/src/core/request/engines/composition/index.ts @@ -90,6 +90,7 @@ export function compositionEngine( important: requestOptions.important, responseType: 'object', okStatuses: requestOptions.okStatuses, + noContentStatuses: requestOptions.noContentStatuses, status: statusCodes.OK, decoder: requestOptions.decoders })); From f738247cde10f5f1510f49c39730ea501b60c355 Mon Sep 17 00:00:00 2001 From: Mikhail Kormanovskii Date: Thu, 25 Jul 2024 15:46:13 +0300 Subject: [PATCH 12/12] :up: date, version --- CHANGELOG.md | 2 +- package.json | 2 +- src/core/request/CHANGELOG.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c6ddf569..0974a02d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ Changelog _Note: Gaps between patch versions are faulty, broken or test releases._ -## v?.?.? (????-??-??) +## v3.100.0-rc.3 (2024-07-25) #### :rocket: New Feature diff --git a/package.json b/package.json index b37afcf90..29e85e599 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/core/index.js", "typings": "index.d.ts", "license": "MIT", - "version": "3.100.0-rc.2", + "version": "3.100.0-rc.3", "author": "kobezzza (https://github.com/kobezzza)", "repository": { "type": "git", diff --git a/src/core/request/CHANGELOG.md b/src/core/request/CHANGELOG.md index 7f2d47048..8c6ce50f1 100644 --- a/src/core/request/CHANGELOG.md +++ b/src/core/request/CHANGELOG.md @@ -9,7 +9,7 @@ Changelog > - :house: [Internal] > - :nail_care: [Polish] -## v?.?.? (????-??-??) +## v3.100.0-rc.3 (2024-07-25) #### :rocket: New Feature