Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: expose headerNameToString #2525

Merged
merged 1 commit into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/api/Util.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Util

Utility API for third-party implementations of the dispatcher API.

## `parseHeaders(headers, [obj])`

Receives a header object and returns the parsed value.

Arguments:

- **headers** `Record<string, string | string[]> | (Buffer | string | (Buffer | string)[])[]` (required) - Header object.

- **obj** `Record<string, string | string[]>` (optional) - Object to specify a proxy object. The parsed value is assigned to this object. But, if **headers** is an object, it is not used.

Returns: `Record<string, string | string[]>` If **headers** is an object, it is **headers**. Otherwise, if **obj** is specified, it is equivalent to **obj**.

## `headerNameToString(value)`

Retrieves a header name and returns its lowercase value.

Arguments:

- **value** `string | Buffer` (required) - Header name.

Returns: `string`
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const { getGlobalDispatcher, setGlobalDispatcher } = require('./lib/global')
const DecoratorHandler = require('./lib/handler/DecoratorHandler')
const RedirectHandler = require('./lib/handler/RedirectHandler')
const createRedirectInterceptor = require('./lib/interceptor/redirectInterceptor')
const { parseHeaders } = require('./lib/core/util')

let hasCrypto
try {
Expand All @@ -47,7 +46,8 @@ module.exports.createRedirectInterceptor = createRedirectInterceptor
module.exports.buildConnector = buildConnector
module.exports.errors = errors
module.exports.util = {
parseHeaders
parseHeaders: util.parseHeaders,
headerNameToString: util.headerNameToString
}

function makeDispatcher (fn) {
Expand Down
8 changes: 6 additions & 2 deletions lib/core/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,9 @@ function parseKeepAliveTimeout (val) {
}

/**
* @param {string | Buffer} value
* Retrieves a header name and returns its lowercase value.
* @param {string | Buffer} value Header name
* @returns {string}
*/
function headerNameToString (value) {
return typeof value === 'string'
Expand All @@ -230,7 +232,9 @@ function headerNameToString (value) {
}

/**
* @param {Buffer} value
* Receive the buffer as a string and return its lowercase value.
* @param {Buffer} value Header name
* @returns {string}
*/
function bufferToLowerCasedHeaderName (value) {
return tree.lookup(value) ?? value.toString('latin1').toLowerCase()
Expand Down
38 changes: 38 additions & 0 deletions test/types/util.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expectAssignable } from 'tsd';
import { util } from '../../types/util';

expectAssignable<Record<string, string | string[]>>(
util.parseHeaders({ 'content-type': 'text/plain' })
);

expectAssignable<Record<string, string | string[]>>(
//@ts-ignore
util.parseHeaders({ 'content-type': 'text/plain' }, {})
);

expectAssignable<Record<string, string | string[]>>(
util.parseHeaders({} as Record<string, string> | string[], {})
);

expectAssignable<Record<string, string | string[]>>(
util.parseHeaders(['content-type', 'text/plain'])
);

expectAssignable<Record<string, string | string[]>>(
util.parseHeaders([Buffer.from('content-type'), Buffer.from('text/plain')])
);

expectAssignable<Record<string, string | string[]>>(
util.parseHeaders(
[Buffer.from('content-type'), Buffer.from('text/plain')],
{}
)
);

expectAssignable<Record<string, string | string[]>>(
util.parseHeaders([Buffer.from('content-type'), [Buffer.from('text/plain')]])
);

expectAssignable<string>(util.headerNameToString('content-type'));

expectAssignable<string>(util.headerNameToString(Buffer.from('content-type')));
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import ProxyAgent from'./proxy-agent'
import RetryHandler from'./retry-handler'
import { request, pipeline, stream, connect, upgrade } from './api'

export * from './util'
export * from './cookies'
export * from './fetch'
export * from './file'
Expand Down
31 changes: 31 additions & 0 deletions types/util.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export namespace util {
/**
* Retrieves a header name and returns its lowercase value.
* @param value Header name
*/
export function headerNameToString(value: string | Buffer): string;

/**
* Receives a header object and returns the parsed value.
* @param headers Header object
*/
export function parseHeaders(
headers:
| Record<string, string | string[]>
| (Buffer | string | (Buffer | string)[])[]
): Record<string, string | string[]>;
/**
* Receives a header object and returns the parsed value.
* @param headers Header object
* @param obj Object to specify a proxy object. Used to assign parsed values. But, if `headers` is an object, it is not used.
* @returns If `headers` is an object, it is `headers`. Otherwise, if `obj` is specified, it is equivalent to `obj`.
*/
export function parseHeaders<
H extends
| Record<string, string | string[]>
| (Buffer | string | (Buffer | string)[])[]
>(
headers: H,
obj?: H extends any[] ? Record<string, string | string[]> : never
): Record<string, string | string[]>;
}