-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
76 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,21 @@ | ||
import { isBoolean, isDate, isNumber, isObject, isString } from './utils/type-is'; | ||
|
||
export enum ContentKind { | ||
JSON = 'JSON', | ||
URL_ENCODED = 'URL_ENCODED', | ||
FORM_DATA = 'FORM_DATA', | ||
TEXT = 'TEXT', | ||
OTHER = 'OTHER', | ||
} | ||
|
||
/** | ||
* 格式化请求头 | ||
* @param {ContentKind} contentKind | ||
* @returns {{"content-type": string} | undefined} | ||
*/ | ||
export function formatHeaders(contentKind: ContentKind) { | ||
const contentType = { | ||
[ContentKind.JSON]: 'application/json', | ||
[ContentKind.URL_ENCODED]: 'application/x-www-form-urlencoded', | ||
[ContentKind.FORM_DATA]: 'multipart/form-data', | ||
[ContentKind.TEXT]: 'text/plain', | ||
[ContentKind.OTHER]: '', | ||
}[contentKind]; | ||
return contentType ? { 'Content-Type': contentType } : undefined; | ||
} | ||
|
||
/** | ||
* 判断是否为二进制 | ||
* @param value | ||
* @returns {boolean} | ||
*/ | ||
export function isBlob(value: unknown): value is Blob { | ||
if (typeof Blob !== 'undefined' && value instanceof Blob) return true; | ||
if (typeof File !== 'undefined' && value instanceof File) return true; | ||
|
||
return false; | ||
} | ||
|
||
export function toFormDataValue(value: unknown): string | Blob { | ||
if (isString(value) || isNumber(value) || isBoolean(value)) return String(value); | ||
if (isObject(value)) return JSON.stringify(value); | ||
if (isDate(value)) return value.toISOString(); | ||
if (isBlob(value)) return value; | ||
return ''; | ||
} | ||
|
||
/** | ||
* 格式化请求体 | ||
* @param {string} contentKind | ||
* @param body | ||
* @returns {FormData | string} | ||
*/ | ||
export function formatBody<D>(contentKind: ContentKind, body: D) { | ||
switch (contentKind) { | ||
case ContentKind.URL_ENCODED: | ||
return isObject(body) ? new URLSearchParams(body as Record<string, string>).toString() : ''; | ||
|
||
case ContentKind.FORM_DATA: { | ||
const fd = new FormData(); | ||
if (!isObject(body)) return fd; | ||
|
||
return Object.keys(body).reduce((fd, key) => { | ||
const val = body[key as keyof D]; | ||
fd.append(key, toFormDataValue(val)); | ||
return fd; | ||
}, fd); | ||
} | ||
|
||
default: | ||
return JSON.stringify(body); | ||
} | ||
// @ref https://github.com/drwpow/openapi-typescript/blob/bc52343c44f9dab4006e04c27411e405fb67a739/src/index.ts#L215 | ||
export type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }; | ||
export type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U; | ||
export type OneOf<T extends any[]> = T extends [infer Only] | ||
? Only | ||
: T extends [infer A, infer B, ...infer Rest] | ||
? OneOf<[XOR<A, B>, ...Rest]> | ||
: never; | ||
|
||
export const DELETE = 'DELETE'; | ||
export const GET = 'GET'; | ||
export const HEAD = 'HEAD'; | ||
export const OPTIONS = 'OPTIONS'; | ||
export const PATCH = 'PATCH'; | ||
export const POST = 'POST'; | ||
export const PUT = 'PUT'; | ||
export const TRACE = 'TRACE'; | ||
|
||
export function resolveURL(baseURL: string, url: string) { | ||
return baseURL.replace(/\/+$/, '') + '/' + url.replace(/^\/+/, ''); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,38 @@ | ||
import { ContentKind, formatBody, formatHeaders, isBlob } from '../src/helpers'; | ||
// import { ContentKind, formatBody, formatHeaders, isBlob } from '../src/helpers'; | ||
// | ||
// test('formatHeaders', () => { | ||
// expect(formatHeaders(ContentKind.JSON)).toEqual({ 'Content-Type': 'application/json' }); | ||
// expect(formatHeaders(ContentKind.OTHER)).toBeUndefined(); | ||
// }); | ||
// | ||
// test('isBlob', () => { | ||
// expect(isBlob('')).toBeFalsy(); | ||
// expect(isBlob(new Blob())).toBeTruthy(); | ||
// }); | ||
// | ||
// test('formatBody', () => { | ||
// const body = { | ||
// a: 1, | ||
// b: '2', | ||
// c: new Blob([]), | ||
// d: [true, null, undefined], | ||
// e: new Date(2000, 1, 1, 1, 1, 1, 1), | ||
// }; | ||
// | ||
// expect(formatBody(ContentKind.JSON, body)).toEqual(JSON.stringify(body)); | ||
// expect(formatBody(ContentKind.URL_ENCODED, body)).toMatchInlineSnapshot( | ||
// '"a=1&b=2&c=%5Bobject+Blob%5D&d=true%2C%2C&e=Tue+Feb+01+2000+01%3A01%3A01+GMT%2B0800+%28China+Standard+Time%29"' | ||
// ); | ||
// expect((formatBody(ContentKind.FORM_DATA, body) as FormData).append).toBeTypeOf('function'); | ||
// expect(formatBody(ContentKind.TEXT, body)).toEqual(JSON.stringify(body)); | ||
// expect(formatBody(ContentKind.OTHER, body)).toEqual(JSON.stringify(body)); | ||
// }); | ||
|
||
test('formatHeaders', () => { | ||
expect(formatHeaders(ContentKind.JSON)).toEqual({ 'Content-Type': 'application/json' }); | ||
expect(formatHeaders(ContentKind.OTHER)).toBeUndefined(); | ||
}); | ||
|
||
test('isBlob', () => { | ||
expect(isBlob('')).toBeFalsy(); | ||
expect(isBlob(new Blob())).toBeTruthy(); | ||
}); | ||
|
||
test('formatBody', () => { | ||
const body = { | ||
a: 1, | ||
b: '2', | ||
c: new Blob([]), | ||
d: [true, null, undefined], | ||
e: new Date(2000, 1, 1, 1, 1, 1, 1), | ||
}; | ||
import { resolveURL } from '../src/helpers'; | ||
|
||
expect(formatBody(ContentKind.JSON, body)).toEqual(JSON.stringify(body)); | ||
expect(formatBody(ContentKind.URL_ENCODED, body)).toMatchInlineSnapshot( | ||
'"a=1&b=2&c=%5Bobject+Blob%5D&d=true%2C%2C&e=Tue+Feb+01+2000+01%3A01%3A01+GMT%2B0800+%28China+Standard+Time%29"' | ||
); | ||
expect((formatBody(ContentKind.FORM_DATA, body) as FormData).append).toBeTypeOf('function'); | ||
expect(formatBody(ContentKind.TEXT, body)).toEqual(JSON.stringify(body)); | ||
expect(formatBody(ContentKind.OTHER, body)).toEqual(JSON.stringify(body)); | ||
test('resolveBaseURL', () => { | ||
expect(resolveURL('/', '/a/b')).toEqual('/a/b'); | ||
expect(resolveURL('/api/v1', '/a/b')).toEqual('/api/v1/a/b'); | ||
expect(resolveURL('https//example.com/api/v1', '/a/b')).toEqual('https//example.com/api/v1/a/b'); | ||
expect(resolveURL('https//example.com/api/v1/', '/a/b')).toEqual('https//example.com/api/v1/a/b'); | ||
}); |