refactor(http): moved `getHeaderValue` from `contentType.utils`
MODIFY
packages/http/src/+internal/contentType.util.ts
packages/http/src/+internal/contentType.util.ts
import * as fileType from 'file-type';
import * as mime from 'mime';
import * as O from 'fp-ts/lib/Option';
-import * as A from 'fp-ts/lib/Array';
import { constant, pipe } from 'fp-ts/lib/function';
import { isString } from '@marblejs/core/dist/+internal/utils';
import { HttpHeaders } from '../http.interface';
+import { getHeaderValue } from './header.util';
export enum ContentType {
APPLICATION = 'application/*',
@@ -42,20 +42,6 @@ export enum ContentType {
MULTIPART_FORM_DATA = 'multipart/form-data',
}
-/**
- * Get header value for given key from provided headers object
- *
- * @param key header key
- * @since 4.0.0
- */
-export const getHeaderValue = <T extends string = string>(key: string) => (headers: HttpHeaders): O.Option<T> =>
- pipe(
- O.fromNullable(headers[key] ?? headers[key.toLowerCase()]),
- O.chain(value => Array.isArray(value)
- ? A.head(value) as O.Option<T>
- : O.some(String(value)) as O.Option<T>),
- );
-
/**
* Get `Content-Type` header value from provided headers object
*

MODIFY
packages/http/src/+internal/header.util.spec.ts
packages/http/src/+internal/header.util.spec.ts
import { createServer, Server } from 'http';
-import { getHeaderValueHead, normalizeHeaders } from './header.util';
+import * as O from 'fp-ts/lib/Option';
+import { getHeaderValue, normalizeHeaders } from './header.util';
import { closeServer, getServerAddress } from './server.util';
import { createHttpRequest } from './testing.util';
-test('#getHeaderValueHead', () => {
- const headers = {
+test('#getHeaderValue', () => {
+ const req = createHttpRequest({
+ headers: {
'x-test-1': 'a',
'x-test-2': ['b', 'c'],
- };
- const req = createHttpRequest({ headers });
+ }
+ });
- expect(getHeaderValueHead('x-test-1')(req)).toEqual('a');
- expect(getHeaderValueHead('x-test-2')(req)).toEqual('b');
- expect(getHeaderValueHead('x-test-3')(req)).toBeUndefined();
+ expect(getHeaderValue('x-test-1')(req.headers)).toEqual(O.some('a'));
+ expect(getHeaderValue('x-test-2')(req.headers)).toEqual(O.some('b'));
+ expect(getHeaderValue('x-test-3')(req.headers)).toEqual(O.none);
});
test('#getServerAddress', async () => {

MODIFY
packages/http/src/+internal/header.util.ts
packages/http/src/+internal/header.util.ts
+import * as O from 'fp-ts/lib/Option';
+import * as A from 'fp-ts/lib/Array';
import { pipe } from 'fp-ts/lib/function';
-import { toUndefined } from 'fp-ts/lib/Option';
import { TESTING_REQUEST_ID_HEADER } from '@marblejs/core/dist/+internal/testing';
-import { getHead } from '@marblejs/core/dist/+internal/utils';
-import { HttpHeaders, HttpRequest } from '../http.interface';
+import { HttpHeaders } from '../http.interface';
-type GetHeaderValue<Value extends string = string> = (req: HttpRequest) => Value | undefined;
-
-export const getHeaderValueHead = (key: string): GetHeaderValue => req => {
- const header = req.headers[key.toLowerCase()];
-
- return Array.isArray(header)
- ? pipe(getHead(header), toUndefined)
- : header;
-};
+/**
+ * Get header value for given key from provided headers object
+ *
+ * @param key header key
+ * @since 4.0.0
+ */
+ export const getHeaderValue = <T extends string = string>(key: string) => (headers: HttpHeaders): O.Option<T> =>
+ pipe(
+ O.fromNullable(headers[key] ?? headers[key.toLowerCase()]),
+ O.chain(value => Array.isArray(value)
+ ? A.head(value) as O.Option<T>
+ : O.some(String(value)) as O.Option<T>),
+ );
+/**
+ * Normalize HTTP headers (transform keys to lowercase)
+ *
+ * @param headers
+ * @since 4.0.0
+ */
export const normalizeHeaders = (headers: HttpHeaders): HttpHeaders =>
pipe(
Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value]),
Object.fromEntries,
);
-export const getTestingRequestIdHeader: GetHeaderValue =
- getHeaderValueHead(TESTING_REQUEST_ID_HEADER);
+/**
+ * Get custom `X-Testing-Request-Id` header value
+ *
+ * @param req
+ */
+export const getTestingRequestIdHeader =
+ getHeaderValue(TESTING_REQUEST_ID_HEADER);

MODIFY
packages/http/src/response/http.responseHandler.ts
packages/http/src/response/http.responseHandler.ts
import * as url from 'url';
import { EMPTY } from 'rxjs';
-import { fold } from 'fp-ts/lib/Option';
+import * as O from 'fp-ts/lib/Option';
import { constVoid, pipe } from 'fp-ts/lib/function';
import { ContextProvider } from '@marblejs/core';
import { isStream } from '@marblejs/core/dist/+internal/utils';
@@ -24,12 +24,12 @@ export const handleResponse = (ask: ContextProvider) => (res: HttpResponse) => (
const bodyFactoryWithHeaders = factorizeBody(headers);
const body = bodyFactoryWithHeaders(effectResponse.body);
- const testingHeader = getTestingRequestIdHeader(req);
+ const testingHeaderValue = pipe(getTestingRequestIdHeader(req.headers), O.toNullable);
- if (isTestingMetadataOn()) {
+ if (isTestingMetadataOn() && testingHeaderValue) {
pipe(
ask(HttpRequestMetadataStorageToken),
- fold(constVoid, storage => storage.set(testingHeader, req.meta)),
+ O.fold(constVoid, storage => storage.set(testingHeaderValue, req.meta)),
);
}

MODIFY
packages/testing/src/testBed/http/http.testBed.request.ts
packages/testing/src/testBed/http/http.testBed.request.ts
import { HttpMethod, HttpHeaders } from '@marblejs/http';
import * as O from 'fp-ts/lib/Option';
import { pipe } from 'fp-ts/lib/function';
-import { ContentType, getHeaderValue, getMimeType } from '@marblejs/http/dist/+internal/contentType.util';
+import { getHeaderValue } from '@marblejs/http/dist/+internal/header.util';
+import { ContentType, getMimeType } from '@marblejs/http/dist/+internal/contentType.util';
import { HttpTestBedRequest, WithBodyApplied } from './http.testBed.request.interface';
import { createTestingRequestHeader } from './http.testBed.util';

refactor(http): moved `getHeaderValue` from `contentType.utils`