extra-request 8.5.0 → 8.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/index.ts +3 -0
- package/src/pipe-request-options-transformers.ts +23 -0
- package/src/request.ts +45 -0
- package/src/transformers/accept.ts +6 -0
- package/src/transformers/append-header.ts +14 -0
- package/src/transformers/append-pathname.ts +11 -0
- package/src/transformers/append-search-param.ts +14 -0
- package/src/transformers/basic-auth.ts +9 -0
- package/src/transformers/bearer-auth.ts +6 -0
- package/src/transformers/body.ts +10 -0
- package/src/transformers/csv.ts +26 -0
- package/src/transformers/form-data-field.ts +33 -0
- package/src/transformers/header.ts +14 -0
- package/src/transformers/headers.ts +16 -0
- package/src/transformers/host.ts +11 -0
- package/src/transformers/index.ts +29 -0
- package/src/transformers/json.ts +18 -0
- package/src/transformers/keepalive.ts +10 -0
- package/src/transformers/pathname.ts +11 -0
- package/src/transformers/port.ts +11 -0
- package/src/transformers/redirect.ts +10 -0
- package/src/transformers/search-param.ts +14 -0
- package/src/transformers/search-params.ts +13 -0
- package/src/transformers/search.ts +11 -0
- package/src/transformers/signal.ts +10 -0
- package/src/transformers/text.ts +15 -0
- package/src/transformers/url.ts +15 -0
- package/src/types.ts +21 -0
- package/lib/browser.d.ts +0 -3
- package/lib/browser.js +0 -4
- package/lib/browser.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "extra-request",
|
|
3
|
-
"version": "8.5.
|
|
3
|
+
"version": "8.5.1",
|
|
4
4
|
"description": "Utilities for Request",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"Request"
|
|
10
10
|
],
|
|
11
11
|
"files": [
|
|
12
|
-
"lib"
|
|
12
|
+
"lib",
|
|
13
|
+
"src"
|
|
13
14
|
],
|
|
14
15
|
"main": "lib/index.js",
|
|
15
16
|
"exports": {
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Headers } from 'extra-fetch'
|
|
2
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
3
|
+
import { isntFalsy } from '@blackglory/prelude'
|
|
4
|
+
import { Falsy } from '@blackglory/prelude'
|
|
5
|
+
import { pipe } from 'extra-utils'
|
|
6
|
+
|
|
7
|
+
export function pipeRequestOptionsTransformers(
|
|
8
|
+
...transformers: Array<IRequestOptionsTransformer | Falsy>
|
|
9
|
+
): IRequestOptions {
|
|
10
|
+
const base: IRequestOptions = {
|
|
11
|
+
url: new URL(
|
|
12
|
+
typeof document !== 'undefined'
|
|
13
|
+
? document.baseURI
|
|
14
|
+
: 'http://localhost'
|
|
15
|
+
)
|
|
16
|
+
, headers: new Headers()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return pipe(
|
|
20
|
+
base
|
|
21
|
+
, ...transformers.filter<IRequestOptionsTransformer>(isntFalsy)
|
|
22
|
+
)
|
|
23
|
+
}
|
package/src/request.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Headers, Request } from 'extra-fetch'
|
|
2
|
+
import { IRequestOptionsTransformer } from '@src/types.js'
|
|
3
|
+
import { pipeRequestOptionsTransformers } from '@src/pipe-request-options-transformers.js'
|
|
4
|
+
import { Falsy } from '@blackglory/prelude'
|
|
5
|
+
|
|
6
|
+
export function get(...transformers: Array<IRequestOptionsTransformer | Falsy>): Request {
|
|
7
|
+
return request('GET', ...transformers)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function head(...transformers: Array<IRequestOptionsTransformer | Falsy>): Request {
|
|
11
|
+
return request('HEAD', ...transformers)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function post(...transformers: Array<IRequestOptionsTransformer | Falsy>): Request {
|
|
15
|
+
return request('POST', ...transformers)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function put(...transformers: Array<IRequestOptionsTransformer | Falsy>): Request {
|
|
19
|
+
return request('PUT', ...transformers)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function patch(...transformers: Array<IRequestOptionsTransformer | Falsy>): Request {
|
|
23
|
+
return request('PATCH', ...transformers)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function del(...transformers: Array<IRequestOptionsTransformer | Falsy>): Request {
|
|
27
|
+
return request('DELETE', ...transformers)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function request(
|
|
31
|
+
method: 'GET' | 'HEAD' | 'PUT' | 'POST' | 'PATCH' | 'DELETE'
|
|
32
|
+
, ...transformers: Array<IRequestOptionsTransformer | Falsy>
|
|
33
|
+
): Request {
|
|
34
|
+
const requestOptions = pipeRequestOptionsTransformers(...transformers)
|
|
35
|
+
const headers = new Headers(requestOptions.headers)
|
|
36
|
+
|
|
37
|
+
return new Request(requestOptions.url.href, {
|
|
38
|
+
method
|
|
39
|
+
, headers
|
|
40
|
+
, signal: requestOptions.signal
|
|
41
|
+
, body: requestOptions.payload as any
|
|
42
|
+
, keepalive: requestOptions.keepalive
|
|
43
|
+
, redirect: requestOptions.redirect
|
|
44
|
+
})
|
|
45
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Headers } from 'extra-fetch'
|
|
2
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
3
|
+
|
|
4
|
+
export function appendHeader(name: string, value: string): IRequestOptionsTransformer {
|
|
5
|
+
return (options: IRequestOptions) => {
|
|
6
|
+
const headers = new Headers(options.headers)
|
|
7
|
+
headers.append(name, value)
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
...options
|
|
11
|
+
, headers
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
2
|
+
import * as URL from 'url-operator'
|
|
3
|
+
|
|
4
|
+
export function appendPathname(pathname: string): IRequestOptionsTransformer {
|
|
5
|
+
return (options: IRequestOptions) => {
|
|
6
|
+
return {
|
|
7
|
+
...options
|
|
8
|
+
, url: URL.appendPathname(options.url, pathname)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
2
|
+
import * as URL from 'url-operator'
|
|
3
|
+
|
|
4
|
+
export function appendSearchParam(
|
|
5
|
+
name: string
|
|
6
|
+
, value: string | number
|
|
7
|
+
): IRequestOptionsTransformer {
|
|
8
|
+
return (options: IRequestOptions) => {
|
|
9
|
+
return {
|
|
10
|
+
...options
|
|
11
|
+
, url: URL.appendSearchParam(options.url, name, value)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { header } from './header.js'
|
|
2
|
+
import { IRequestOptionsTransformer } from '@src/types.js'
|
|
3
|
+
|
|
4
|
+
export function basicAuth(
|
|
5
|
+
username: string
|
|
6
|
+
, password: string
|
|
7
|
+
): IRequestOptionsTransformer {
|
|
8
|
+
return header('Authorization', 'Basic ' + btoa(`${username}:${password}`))
|
|
9
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
2
|
+
|
|
3
|
+
export function body(val: BodyInit | NodeJS.ReadableStream): IRequestOptionsTransformer {
|
|
4
|
+
return (options: IRequestOptions) => {
|
|
5
|
+
return {
|
|
6
|
+
...options
|
|
7
|
+
, payload: val
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Headers } from 'extra-fetch'
|
|
2
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
3
|
+
import papaparse from 'papaparse'
|
|
4
|
+
import { assert } from '@blackglory/prelude'
|
|
5
|
+
|
|
6
|
+
const { unparse } = papaparse
|
|
7
|
+
|
|
8
|
+
export function csv<T extends object>(payload: T[]): IRequestOptionsTransformer {
|
|
9
|
+
assert(payload.length > 0, 'payload must be a non-empty array')
|
|
10
|
+
|
|
11
|
+
return (options: IRequestOptions) => {
|
|
12
|
+
const headers = new Headers(options.headers)
|
|
13
|
+
headers.set('Content-Type', 'text/csv')
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
...options
|
|
17
|
+
, headers
|
|
18
|
+
, payload: stringify(payload)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function stringify<T extends object>(data: T[]): string {
|
|
24
|
+
const fields = Object.keys(data[0])
|
|
25
|
+
return unparse({ data, fields })
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { FormData } from 'extra-fetch'
|
|
2
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
3
|
+
import { isArray } from '@blackglory/prelude'
|
|
4
|
+
|
|
5
|
+
export function formDataField(
|
|
6
|
+
name: string
|
|
7
|
+
, value: string | string[] | Blob
|
|
8
|
+
): IRequestOptionsTransformer {
|
|
9
|
+
return (options: IRequestOptions) => {
|
|
10
|
+
const formData = options.payload instanceof FormData
|
|
11
|
+
? cloneFormData(options.payload)
|
|
12
|
+
: new FormData()
|
|
13
|
+
|
|
14
|
+
if (isArray(value)) {
|
|
15
|
+
value.forEach(x => formData.append(name, x))
|
|
16
|
+
} else {
|
|
17
|
+
formData.append(name, value)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
...options
|
|
22
|
+
, payload: formData
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function cloneFormData(formData: FormData): FormData{
|
|
28
|
+
const result = new FormData()
|
|
29
|
+
for (const [name, value] of formData.entries()) {
|
|
30
|
+
result.append(name, value)
|
|
31
|
+
}
|
|
32
|
+
return result
|
|
33
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Headers } from 'extra-fetch'
|
|
2
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
3
|
+
|
|
4
|
+
export function header(name: string, value: string): IRequestOptionsTransformer {
|
|
5
|
+
return (options: IRequestOptions) => {
|
|
6
|
+
const headers = new Headers(options.headers)
|
|
7
|
+
headers.set(name, value)
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
...options
|
|
11
|
+
, headers
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Headers } from 'extra-fetch'
|
|
2
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
3
|
+
|
|
4
|
+
export function headers(headers: { [name: string]: string }): IRequestOptionsTransformer {
|
|
5
|
+
return (options: IRequestOptions) => {
|
|
6
|
+
const newHeaders = new Headers(options.headers)
|
|
7
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
8
|
+
newHeaders.set(name, value)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
...options
|
|
13
|
+
, headers: newHeaders
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
2
|
+
import { setHost } from 'url-operator'
|
|
3
|
+
|
|
4
|
+
export function host(host: string): IRequestOptionsTransformer {
|
|
5
|
+
return (options: IRequestOptions) => {
|
|
6
|
+
return {
|
|
7
|
+
...options
|
|
8
|
+
, url: setHost(options.url, host)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export * from '@transformers/url.js'
|
|
2
|
+
|
|
3
|
+
export * from '@transformers/text.js'
|
|
4
|
+
export * from '@transformers/json.js'
|
|
5
|
+
export * from '@transformers/csv.js'
|
|
6
|
+
|
|
7
|
+
export * from '@transformers/header.js'
|
|
8
|
+
export * from '@transformers/append-header.js'
|
|
9
|
+
export * from '@transformers/headers.js'
|
|
10
|
+
export * from '@transformers/accept.js'
|
|
11
|
+
|
|
12
|
+
export * from '@transformers/host.js'
|
|
13
|
+
export * from '@transformers/port.js'
|
|
14
|
+
export * from '@transformers/pathname.js'
|
|
15
|
+
export * from '@transformers/append-pathname.js'
|
|
16
|
+
export * from '@transformers/search.js'
|
|
17
|
+
export * from '@transformers/search-param.js'
|
|
18
|
+
export * from '@transformers/search-params.js'
|
|
19
|
+
export * from '@transformers/append-search-param.js'
|
|
20
|
+
|
|
21
|
+
export * from '@transformers/form-data-field.js'
|
|
22
|
+
|
|
23
|
+
export * from '@transformers/basic-auth.js'
|
|
24
|
+
export * from '@transformers/bearer-auth.js'
|
|
25
|
+
|
|
26
|
+
export * from '@transformers/signal.js'
|
|
27
|
+
export * from '@transformers/keepalive.js'
|
|
28
|
+
export * from '@transformers/redirect.js'
|
|
29
|
+
export * from '@transformers/body.js'
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Headers } from 'extra-fetch'
|
|
2
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
3
|
+
import { JSONValue, JSONSerializable } from 'justypes'
|
|
4
|
+
|
|
5
|
+
export function json<T extends JSONValue | JSONSerializable<any>>(
|
|
6
|
+
payload: T
|
|
7
|
+
): IRequestOptionsTransformer {
|
|
8
|
+
return (options: IRequestOptions) => {
|
|
9
|
+
const headers = new Headers(options.headers)
|
|
10
|
+
headers.set('Content-Type', 'application/json')
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
...options
|
|
14
|
+
, headers
|
|
15
|
+
, payload: JSON.stringify(payload)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
2
|
+
import { setPathname } from 'url-operator'
|
|
3
|
+
|
|
4
|
+
export function pathname(pathname: string): IRequestOptionsTransformer {
|
|
5
|
+
return (options: IRequestOptions) => {
|
|
6
|
+
return {
|
|
7
|
+
...options
|
|
8
|
+
, url: setPathname(options.url, pathname)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
2
|
+
import { setPort } from 'url-operator'
|
|
3
|
+
|
|
4
|
+
export function port(port: number): IRequestOptionsTransformer {
|
|
5
|
+
return (options: IRequestOptions) => {
|
|
6
|
+
return {
|
|
7
|
+
...options
|
|
8
|
+
, url: setPort(options.url, port)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
2
|
+
import { setSearchParam } from 'url-operator'
|
|
3
|
+
|
|
4
|
+
export function searchParam(
|
|
5
|
+
name: string
|
|
6
|
+
, value: string | number
|
|
7
|
+
): IRequestOptionsTransformer {
|
|
8
|
+
return (options: IRequestOptions) => {
|
|
9
|
+
return {
|
|
10
|
+
...options
|
|
11
|
+
, url: setSearchParam(options.url, name, value)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
2
|
+
import { setSearchParams } from 'url-operator'
|
|
3
|
+
|
|
4
|
+
export function searchParams(
|
|
5
|
+
searchParams: Record<string, string | number>
|
|
6
|
+
): IRequestOptionsTransformer {
|
|
7
|
+
return (options: IRequestOptions) => {
|
|
8
|
+
return {
|
|
9
|
+
...options
|
|
10
|
+
, url: setSearchParams(options.url, searchParams)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
2
|
+
import { setSearch } from 'url-operator'
|
|
3
|
+
|
|
4
|
+
export function search(search: string): IRequestOptionsTransformer {
|
|
5
|
+
return (options: IRequestOptions) => {
|
|
6
|
+
return {
|
|
7
|
+
...options
|
|
8
|
+
, url: setSearch(options.url, search)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Headers } from 'extra-fetch'
|
|
2
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
3
|
+
|
|
4
|
+
export function text(payload: string): IRequestOptionsTransformer {
|
|
5
|
+
return (options: IRequestOptions) => {
|
|
6
|
+
const headers = new Headers(options.headers)
|
|
7
|
+
headers.set('Content-Type', 'application/x-www-form-urlencoded')
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
...options
|
|
11
|
+
, headers
|
|
12
|
+
, payload
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IRequestOptions, IRequestOptionsTransformer } from '@src/types.js'
|
|
2
|
+
import { NonEmptyArray } from 'justypes'
|
|
3
|
+
|
|
4
|
+
export function url(...urls: NonEmptyArray<string | URL>): IRequestOptionsTransformer {
|
|
5
|
+
return (options: IRequestOptions) => {
|
|
6
|
+
const newURL = new URL(
|
|
7
|
+
[options.url, ...urls].reduce((acc, cur) => new URL(cur, acc))
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
...options
|
|
12
|
+
, url: newURL
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type IRequestOptionsTransformer = (options: IRequestOptions) => IRequestOptions
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Q: Why not use `Request` interface?
|
|
5
|
+
* A: Because `Request['body']` is `ReadableStream`,
|
|
6
|
+
* it is very difficult to use.
|
|
7
|
+
*
|
|
8
|
+
* Q: Why not use `RequestInit` interface?
|
|
9
|
+
* A: Because `RequestInit` has no `url` property,
|
|
10
|
+
* and its optional properties are not suitable for our cases.
|
|
11
|
+
*/
|
|
12
|
+
export interface IRequestOptions {
|
|
13
|
+
url: URL
|
|
14
|
+
headers: Headers
|
|
15
|
+
payload?:
|
|
16
|
+
| BodyInit // WHATWG
|
|
17
|
+
| NodeJS.ReadableStream // node-fetch
|
|
18
|
+
signal?: AbortSignal
|
|
19
|
+
keepalive?: boolean
|
|
20
|
+
redirect?: RequestRedirect
|
|
21
|
+
}
|
package/lib/browser.d.ts
DELETED
package/lib/browser.js
DELETED
package/lib/browser.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,yBAAyB,CAAA"}
|