Skip to content

Commit

Permalink
Merge pull request #448 from V4Fire/kormanowsky/fetch-redirect-support
Browse files Browse the repository at this point in the history
feat: add .redirect to RequestOptions and support in fetch engine
  • Loading branch information
kormanowsky authored Dec 2, 2024
2 parents 68a41ff + 180790e commit b8ac308
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 17 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ Changelog
_Note: Gaps between patch versions are faulty, broken or test releases._

## v4.0.0-alpha.51 (2024-12-02)

#### :rocket: New Feature

* Added support for propagating status code and headers from exactly one request of the composition
via `propagateStatusAndHeaders` option `core/request/engines/composition`
* Added support for `redirect` option `core/request/engines/fetch`

## v4.0.0-alpha.50 (2024-11-26)

#### :rocket: New Feature
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "lib/core/index.js",
"typings": "index.d.ts",
"license": "MIT",
"version": "4.0.0-alpha.50",
"version": "4.0.0-alpha.51",
"author": "kobezzza <[email protected]> (https://github.com/kobezzza)",
"repository": {
"type": "git",
Expand Down
7 changes: 7 additions & 0 deletions src/core/request/engines/composition/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ Changelog
> - :house: [Internal]
> - :nail_care: [Polish]
## v4.0.0-alpha.51 (2024-12-02)

#### :rocket: New Feature

* Added support for propagating status code and headers from exactly one request of the composition
via `propagateStatusAndHeaders` option

## v4.0.0-alpha.40 (2024-07-02)

#### :bug: Bug Fix
Expand Down
60 changes: 44 additions & 16 deletions src/core/request/engines/composition/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import type {
CompositionEngineOpts,
CompositionRequestEngine,
CompositionRequest,
CompositionRequestOptions
CompositionRequestOptions,
GatheredRequestsData

} from 'core/request/engines/composition/interface';

Expand Down Expand Up @@ -75,26 +76,43 @@ export function compositionEngine(
const promises = compositionRequests.map((r) => SyncPromise.resolve(r.requestFilter?.(options))
.then((filterValue) => {
if (filterValue === false) {
return;
return {};
}

return r.request(options)
.then(boundRequest.bind(null, async))
.then((request) => isRequestResponseObject(request) ? request.data : request)
.then(async (request) => {
if (isRequestResponseObject(request)) {
return {
data: await request.data,
headers: request.response.headers,
status: request.response.status
};
}

return {
data: await request,
headers: {},
status: statusCodes.OK
};
})
.catch((err) => {
if (r.failCompositionOnError) {
throw err;
}

return {};
});
}));

gatherDataFromRequests(promises, options).then((data) => {
gatherDataFromRequests(promises, options).then(({data, status, headers}) => {
resolve(new Response(data, {
parent: requestOptions.parent,
important: requestOptions.important,
responseType: 'object',
okStatuses: requestOptions.okStatuses,
status: statusCodes.OK,
status: status ?? statusCodes.OK,
headers: headers ?? {},
decoder: requestOptions.decoders,
noContentStatuses: requestOptions.noContentStatuses
}));
Expand Down Expand Up @@ -153,10 +171,12 @@ function boundRequest<T extends unknown>(
* @param options - Options related to composition requests.
*/
async function gatherDataFromRequests(
promises: Array<Promise<unknown>>,
promises: Array<Promise<GatheredRequestsData>>,
options: CompositionRequestOptions
): Promise<Dictionary> {
const accumulator = {};
): Promise<GatheredRequestsData> {
const accumulator = {
data: {}
};

if (options.engineOptions?.aggregateErrors) {
await Promise.allSettled(promises)
Expand Down Expand Up @@ -191,25 +211,33 @@ async function gatherDataFromRequests(
}

/**
* Accumulates data into an accumulator object based on the composition request.
* Accumulates new data into an accumulator object based on the composition request.
*
* @param accumulator
* @param data
* @param newData
* @param compositionRequest
*/
function accumulateData(
accumulator: Dictionary,
data: unknown,
accumulator: GatheredRequestsData,
newData: GatheredRequestsData,
compositionRequest: CompositionRequest
): Dictionary {
): GatheredRequestsData {
const
{as} = compositionRequest;
{as} = compositionRequest,
{status, headers, data} = newData;

accumulator.data ??= {};

if (as === compositionEngineSpreadResult) {
Object.assign(accumulator, data);
Object.assign(accumulator.data, data);

} else {
Object.set(accumulator, as, data);
Object.set(accumulator.data, as, data);
}

if (compositionRequest.propagateStatusAndHeaders === true) {
accumulator.status = status;
accumulator.headers = headers;
}

return accumulator;
Expand Down
15 changes: 15 additions & 0 deletions src/core/request/engines/composition/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import type Provider from 'core/data';
import type { ProviderOptions } from 'core/data';
import type { RequestOptions, RequestResponseObject, MiddlewareParams, RequestPromise, RequestEngine } from 'core/request';
import type { RawHeaders } from 'core/request/headers';
import type { StatusCodes } from 'core/status-codes';

export interface CompositionEngineOpts {
/**
Expand Down Expand Up @@ -130,6 +132,13 @@ export interface CompositionRequest {
* If false / undefined, request errors will be ignored.
*/
failCompositionOnError?: boolean;

/**
* If true, status code and reponse headers will be propagated from this request to the whole
* composition. Note that if there are more than one request with this option set to true,
* only last request's data will be propagated.
*/
propagateStatusAndHeaders?: boolean;
}

export interface CompositionRequestOptions {
Expand Down Expand Up @@ -166,3 +175,9 @@ export interface CompositionRequestEngine extends RequestEngine {
dropCache: NonNullable<RequestEngine['dropCache']>;
destroy: NonNullable<RequestEngine['destroy']>;
}

export interface GatheredRequestsData {
data?: Dictionary;
headers?: RawHeaders;
status?: StatusCodes;
}
6 changes: 6 additions & 0 deletions src/core/request/engines/fetch/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Changelog
> - :house: [Internal]
> - :nail_care: [Polish]
## v4.0.0-alpha.51 (2024-12-02)

#### :rocket: New Feature

* Added support for `redirect` option

## v3.78.0 (2022-03-16)

#### :rocket: New Feature
Expand Down
8 changes: 8 additions & 0 deletions src/core/request/engines/fetch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,18 @@ const request: RequestEngine = (params) => {
credentials = 'include';
}

let
redirect: RequestRedirect = 'follow';

if (Object.isString(p.redirect)) {
redirect = p.redirect;
}

const fetchOpts: RequestInit = {
body,
headers,
credentials,
redirect,
method: p.method,
signal: abortController.signal
};
Expand Down
1 change: 1 addition & 0 deletions src/core/request/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ export interface RequestOptions {

readonly important?: boolean;
readonly credentials?: boolean | RequestCredentials;
readonly redirect?: RequestRedirect;
}

/**
Expand Down

0 comments on commit b8ac308

Please sign in to comment.