@wordpress/api-fetch 7.29.0 → 7.29.1-next.e256d081a.0
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/build/index.js +25 -34
- package/build/index.js.map +1 -1
- package/build/middlewares/fetch-all-middleware.js +14 -14
- package/build/middlewares/fetch-all-middleware.js.map +1 -1
- package/build/middlewares/http-v1.js +6 -5
- package/build/middlewares/http-v1.js.map +1 -1
- package/build/middlewares/media-upload.js +6 -6
- package/build/middlewares/media-upload.js.map +1 -1
- package/build/middlewares/namespace-endpoint.js +2 -1
- package/build/middlewares/namespace-endpoint.js.map +1 -1
- package/build/middlewares/nonce.js +7 -5
- package/build/middlewares/nonce.js.map +1 -1
- package/build/middlewares/preloading.js +10 -7
- package/build/middlewares/preloading.js.map +1 -1
- package/build/middlewares/root-url.js +2 -2
- package/build/middlewares/root-url.js.map +1 -1
- package/build/middlewares/theme-preview.js +6 -2
- package/build/middlewares/theme-preview.js.map +1 -1
- package/build/middlewares/user-locale.js +2 -1
- package/build/middlewares/user-locale.js.map +1 -1
- package/build/types.js.map +1 -1
- package/build/utils/response.js +11 -11
- package/build/utils/response.js.map +1 -1
- package/build-module/index.js +13 -35
- package/build-module/index.js.map +1 -1
- package/build-module/middlewares/fetch-all-middleware.js +14 -15
- package/build-module/middlewares/fetch-all-middleware.js.map +1 -1
- package/build-module/middlewares/http-v1.js +6 -5
- package/build-module/middlewares/http-v1.js.map +1 -1
- package/build-module/middlewares/media-upload.js +6 -7
- package/build-module/middlewares/media-upload.js.map +1 -1
- package/build-module/middlewares/namespace-endpoint.js +2 -1
- package/build-module/middlewares/namespace-endpoint.js.map +1 -1
- package/build-module/middlewares/nonce.js +7 -5
- package/build-module/middlewares/nonce.js.map +1 -1
- package/build-module/middlewares/preloading.js +10 -7
- package/build-module/middlewares/preloading.js.map +1 -1
- package/build-module/middlewares/root-url.js +3 -2
- package/build-module/middlewares/root-url.js.map +1 -1
- package/build-module/middlewares/theme-preview.js +5 -2
- package/build-module/middlewares/theme-preview.js.map +1 -1
- package/build-module/middlewares/user-locale.js +2 -1
- package/build-module/middlewares/user-locale.js.map +1 -1
- package/build-module/types.js.map +1 -1
- package/build-module/utils/response.js +11 -11
- package/build-module/utils/response.js.map +1 -1
- package/build-types/index.d.ts +25 -32
- package/build-types/index.d.ts.map +1 -1
- package/build-types/middlewares/fetch-all-middleware.d.ts +5 -4
- package/build-types/middlewares/fetch-all-middleware.d.ts.map +1 -1
- package/build-types/middlewares/http-v1.d.ts +8 -3
- package/build-types/middlewares/http-v1.d.ts.map +1 -1
- package/build-types/middlewares/media-upload.d.ts +5 -4
- package/build-types/middlewares/media-upload.d.ts.map +1 -1
- package/build-types/middlewares/namespace-endpoint.d.ts +4 -3
- package/build-types/middlewares/namespace-endpoint.d.ts.map +1 -1
- package/build-types/middlewares/nonce.d.ts +9 -4
- package/build-types/middlewares/nonce.d.ts.map +1 -1
- package/build-types/middlewares/preloading.d.ts +8 -4
- package/build-types/middlewares/preloading.d.ts.map +1 -1
- package/build-types/middlewares/root-url.d.ts +8 -4
- package/build-types/middlewares/root-url.d.ts.map +1 -1
- package/build-types/middlewares/theme-preview.d.ts +8 -4
- package/build-types/middlewares/theme-preview.d.ts.map +1 -1
- package/build-types/middlewares/user-locale.d.ts +4 -3
- package/build-types/middlewares/user-locale.d.ts.map +1 -1
- package/build-types/types.d.ts +4 -3
- package/build-types/types.d.ts.map +1 -1
- package/build-types/utils/response.d.ts +13 -5
- package/build-types/utils/response.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/{index.js → index.ts} +49 -46
- package/src/middlewares/{fetch-all-middleware.js → fetch-all-middleware.ts} +24 -20
- package/src/middlewares/{http-v1.js → http-v1.ts} +8 -6
- package/src/middlewares/{media-upload.js → media-upload.ts} +10 -9
- package/src/middlewares/{namespace-endpoint.js → namespace-endpoint.ts} +7 -2
- package/src/middlewares/{nonce.js → nonce.ts} +15 -7
- package/src/middlewares/{preloading.js → preloading.ts} +21 -11
- package/src/middlewares/root-url.ts +47 -0
- package/src/middlewares/test/{fetch-all-middleware.js → fetch-all-middleware.ts} +1 -1
- package/src/middlewares/test/{http-v1.js → http-v1.ts} +7 -4
- package/src/middlewares/test/{media-upload.js → media-upload.ts} +2 -1
- package/src/middlewares/test/{namespace-endpoint.js → namespace-endpoint.ts} +2 -1
- package/src/middlewares/test/{nonce.js → nonce.ts} +5 -4
- package/src/middlewares/test/{preloading.js → preloading.ts} +31 -11
- package/src/middlewares/test/{root-url.js → root-url.ts} +2 -1
- package/src/middlewares/test/{user-locale.js → user-locale.ts} +9 -8
- package/src/middlewares/theme-preview.ts +60 -0
- package/src/middlewares/{user-locale.js → user-locale.ts} +4 -2
- package/src/types.ts +10 -5
- package/src/utils/{response.js → response.ts} +18 -15
- package/tsconfig.tsbuildinfo +1 -1
- package/src/middlewares/root-url.js +0 -44
- package/src/middlewares/theme-preview.js +0 -42
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/api-fetch",
|
|
3
|
-
"version": "7.29.0",
|
|
3
|
+
"version": "7.29.1-next.e256d081a.0",
|
|
4
4
|
"description": "Utility to make WordPress REST API requests.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"types": "build-types",
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@babel/runtime": "7.25.7",
|
|
33
|
-
"@wordpress/i18n": "^6.2.0",
|
|
34
|
-
"@wordpress/url": "^4.29.0"
|
|
33
|
+
"@wordpress/i18n": "^6.2.1-next.e256d081a.0",
|
|
34
|
+
"@wordpress/url": "^4.29.1-next.e256d081a.0"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "7d529ba9a461795d5f1572d3856de33f744287c2"
|
|
40
40
|
}
|
|
@@ -19,14 +19,17 @@ import {
|
|
|
19
19
|
parseResponseAndNormalizeError,
|
|
20
20
|
parseAndThrowError,
|
|
21
21
|
} from './utils/response';
|
|
22
|
+
import type {
|
|
23
|
+
APIFetchMiddleware,
|
|
24
|
+
APIFetchOptions,
|
|
25
|
+
FetchHandler,
|
|
26
|
+
} from './types';
|
|
22
27
|
|
|
23
28
|
/**
|
|
24
29
|
* Default set of header values which should be sent with every request unless
|
|
25
30
|
* explicitly provided through apiFetch options.
|
|
26
|
-
*
|
|
27
|
-
* @type {Record<string, string>}
|
|
28
31
|
*/
|
|
29
|
-
const DEFAULT_HEADERS = {
|
|
32
|
+
const DEFAULT_HEADERS: APIFetchOptions[ 'headers' ] = {
|
|
30
33
|
// The backend uses the Accept header as a condition for considering an
|
|
31
34
|
// incoming request as a REST request.
|
|
32
35
|
//
|
|
@@ -37,20 +40,12 @@ const DEFAULT_HEADERS = {
|
|
|
37
40
|
/**
|
|
38
41
|
* Default set of fetch option values which should be sent with every request
|
|
39
42
|
* unless explicitly provided through apiFetch options.
|
|
40
|
-
*
|
|
41
|
-
* @type {Object}
|
|
42
43
|
*/
|
|
43
|
-
const DEFAULT_OPTIONS = {
|
|
44
|
+
const DEFAULT_OPTIONS: APIFetchOptions = {
|
|
44
45
|
credentials: 'include',
|
|
45
46
|
};
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
/** @typedef {import('./types').APIFetchOptions} APIFetchOptions */
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @type {import('./types').APIFetchMiddleware[]}
|
|
52
|
-
*/
|
|
53
|
-
const middlewares = [
|
|
48
|
+
const middlewares: Array< APIFetchMiddleware > = [
|
|
54
49
|
userLocaleMiddleware,
|
|
55
50
|
namespaceEndpointMiddleware,
|
|
56
51
|
httpV1Middleware,
|
|
@@ -60,9 +55,9 @@ const middlewares = [
|
|
|
60
55
|
/**
|
|
61
56
|
* Register a middleware
|
|
62
57
|
*
|
|
63
|
-
* @param
|
|
58
|
+
* @param middleware
|
|
64
59
|
*/
|
|
65
|
-
function registerMiddleware( middleware ) {
|
|
60
|
+
function registerMiddleware( middleware: APIFetchMiddleware ) {
|
|
66
61
|
middlewares.unshift( middleware );
|
|
67
62
|
}
|
|
68
63
|
|
|
@@ -70,10 +65,10 @@ function registerMiddleware( middleware ) {
|
|
|
70
65
|
* Checks the status of a response, throwing the Response as an error if
|
|
71
66
|
* it is outside the 200 range.
|
|
72
67
|
*
|
|
73
|
-
* @param
|
|
74
|
-
* @return
|
|
68
|
+
* @param response
|
|
69
|
+
* @return The response if the status is in the 200 range.
|
|
75
70
|
*/
|
|
76
|
-
const checkStatus = ( response ) => {
|
|
71
|
+
const checkStatus = ( response: Response ) => {
|
|
77
72
|
if ( response.status >= 200 && response.status < 300 ) {
|
|
78
73
|
return response;
|
|
79
74
|
}
|
|
@@ -81,12 +76,7 @@ const checkStatus = ( response ) => {
|
|
|
81
76
|
throw response;
|
|
82
77
|
};
|
|
83
78
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* @type {FetchHandler}
|
|
88
|
-
*/
|
|
89
|
-
const defaultFetchHandler = ( nextOptions ) => {
|
|
79
|
+
const defaultFetchHandler: FetchHandler = ( nextOptions ) => {
|
|
90
80
|
const { url, path, data, parse = true, ...remainingOptions } = nextOptions;
|
|
91
81
|
let { body, headers } = nextOptions;
|
|
92
82
|
|
|
@@ -134,32 +124,48 @@ const defaultFetchHandler = ( nextOptions ) => {
|
|
|
134
124
|
);
|
|
135
125
|
};
|
|
136
126
|
|
|
137
|
-
/** @type {FetchHandler} */
|
|
138
127
|
let fetchHandler = defaultFetchHandler;
|
|
139
128
|
|
|
140
129
|
/**
|
|
141
130
|
* Defines a custom fetch handler for making the requests that will override
|
|
142
131
|
* the default one using window.fetch
|
|
143
132
|
*
|
|
144
|
-
* @param
|
|
133
|
+
* @param newFetchHandler The new fetch handler
|
|
145
134
|
*/
|
|
146
|
-
function setFetchHandler( newFetchHandler ) {
|
|
135
|
+
function setFetchHandler( newFetchHandler: FetchHandler ) {
|
|
147
136
|
fetchHandler = newFetchHandler;
|
|
148
137
|
}
|
|
149
138
|
|
|
139
|
+
interface apiFetch {
|
|
140
|
+
< T, Parse extends boolean = true >(
|
|
141
|
+
options: APIFetchOptions< Parse >
|
|
142
|
+
): Promise< Parse extends true ? T : Response >;
|
|
143
|
+
nonceEndpoint?: string;
|
|
144
|
+
nonceMiddleware?: ReturnType< typeof createNonceMiddleware >;
|
|
145
|
+
use: ( middleware: APIFetchMiddleware ) => void;
|
|
146
|
+
setFetchHandler: ( newFetchHandler: FetchHandler ) => void;
|
|
147
|
+
createNonceMiddleware: typeof createNonceMiddleware;
|
|
148
|
+
createPreloadingMiddleware: typeof createPreloadingMiddleware;
|
|
149
|
+
createRootURLMiddleware: typeof createRootURLMiddleware;
|
|
150
|
+
fetchAllMiddleware: typeof fetchAllMiddleware;
|
|
151
|
+
mediaUploadMiddleware: typeof mediaUploadMiddleware;
|
|
152
|
+
createThemePreviewMiddleware: typeof createThemePreviewMiddleware;
|
|
153
|
+
}
|
|
154
|
+
|
|
150
155
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* @
|
|
156
|
+
* Fetch
|
|
157
|
+
*
|
|
158
|
+
* @param options The options for the fetch.
|
|
159
|
+
* @return A promise representing the request processed via the registered middlewares.
|
|
154
160
|
*/
|
|
155
|
-
|
|
161
|
+
const apiFetch: apiFetch = ( options ) => {
|
|
156
162
|
// creates a nested function chain that calls all middlewares and finally the `fetchHandler`,
|
|
157
163
|
// converting `middlewares = [ m1, m2, m3 ]` into:
|
|
158
164
|
// ```
|
|
159
165
|
// opts1 => m1( opts1, opts2 => m2( opts2, opts3 => m3( opts3, fetchHandler ) ) );
|
|
160
166
|
// ```
|
|
161
|
-
const enhancedHandler = middlewares.reduceRight(
|
|
162
|
-
(
|
|
167
|
+
const enhancedHandler = middlewares.reduceRight< FetchHandler >(
|
|
168
|
+
( next, middleware ) => {
|
|
163
169
|
return ( workingOptions ) => middleware( workingOptions, next );
|
|
164
170
|
},
|
|
165
171
|
fetchHandler
|
|
@@ -171,20 +177,16 @@ function apiFetch( options ) {
|
|
|
171
177
|
}
|
|
172
178
|
|
|
173
179
|
// If the nonce is invalid, refresh it and try again.
|
|
174
|
-
return
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
apiFetch.nonceMiddleware.nonce = text;
|
|
183
|
-
return apiFetch( options );
|
|
184
|
-
} )
|
|
185
|
-
);
|
|
180
|
+
return window
|
|
181
|
+
.fetch( apiFetch.nonceEndpoint! )
|
|
182
|
+
.then( checkStatus )
|
|
183
|
+
.then( ( data ) => data.text() )
|
|
184
|
+
.then( ( text ) => {
|
|
185
|
+
apiFetch.nonceMiddleware!.nonce = text;
|
|
186
|
+
return apiFetch( options );
|
|
187
|
+
} );
|
|
186
188
|
} );
|
|
187
|
-
}
|
|
189
|
+
};
|
|
188
190
|
|
|
189
191
|
apiFetch.use = registerMiddleware;
|
|
190
192
|
apiFetch.setFetchHandler = setFetchHandler;
|
|
@@ -197,3 +199,4 @@ apiFetch.mediaUploadMiddleware = mediaUploadMiddleware;
|
|
|
197
199
|
apiFetch.createThemePreviewMiddleware = createThemePreviewMiddleware;
|
|
198
200
|
|
|
199
201
|
export default apiFetch;
|
|
202
|
+
export * from './types';
|
|
@@ -7,15 +7,19 @@ import { addQueryArgs } from '@wordpress/url';
|
|
|
7
7
|
* Internal dependencies
|
|
8
8
|
*/
|
|
9
9
|
import apiFetch from '..';
|
|
10
|
+
import type { APIFetchMiddleware, APIFetchOptions } from '../types';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Apply query arguments to both URL and Path, whichever is present.
|
|
13
14
|
*
|
|
14
|
-
* @param {
|
|
15
|
-
* @param {Record<string, string | number>}
|
|
16
|
-
* @return
|
|
15
|
+
* @param {APIFetchOptions} props The request options
|
|
16
|
+
* @param {Record< string, string | number >} queryArgs
|
|
17
|
+
* @return The request with the modified query args
|
|
17
18
|
*/
|
|
18
|
-
const modifyQuery = (
|
|
19
|
+
const modifyQuery = (
|
|
20
|
+
{ path, url, ...options }: APIFetchOptions,
|
|
21
|
+
queryArgs: Record< string, string | number >
|
|
22
|
+
): APIFetchOptions => ( {
|
|
19
23
|
...options,
|
|
20
24
|
url: url && addQueryArgs( url, queryArgs ),
|
|
21
25
|
path: path && addQueryArgs( path, queryArgs ),
|
|
@@ -24,17 +28,17 @@ const modifyQuery = ( { path, url, ...options }, queryArgs ) => ( {
|
|
|
24
28
|
/**
|
|
25
29
|
* Duplicates parsing functionality from apiFetch.
|
|
26
30
|
*
|
|
27
|
-
* @param
|
|
28
|
-
* @return
|
|
31
|
+
* @param response
|
|
32
|
+
* @return Parsed response json.
|
|
29
33
|
*/
|
|
30
|
-
const parseResponse = ( response ) =>
|
|
34
|
+
const parseResponse = ( response: Response ) =>
|
|
31
35
|
response.json ? response.json() : Promise.reject( response );
|
|
32
36
|
|
|
33
37
|
/**
|
|
34
|
-
* @param
|
|
35
|
-
* @return
|
|
38
|
+
* @param linkHeader
|
|
39
|
+
* @return The parsed link header.
|
|
36
40
|
*/
|
|
37
|
-
const parseLinkHeader = ( linkHeader ) => {
|
|
41
|
+
const parseLinkHeader = ( linkHeader: string | null ) => {
|
|
38
42
|
if ( ! linkHeader ) {
|
|
39
43
|
return {};
|
|
40
44
|
}
|
|
@@ -47,19 +51,19 @@ const parseLinkHeader = ( linkHeader ) => {
|
|
|
47
51
|
};
|
|
48
52
|
|
|
49
53
|
/**
|
|
50
|
-
* @param
|
|
51
|
-
* @return
|
|
54
|
+
* @param response
|
|
55
|
+
* @return The next page URL.
|
|
52
56
|
*/
|
|
53
|
-
const getNextPageUrl = ( response ) => {
|
|
57
|
+
const getNextPageUrl = ( response: Response ) => {
|
|
54
58
|
const { next } = parseLinkHeader( response.headers.get( 'link' ) );
|
|
55
59
|
return next;
|
|
56
60
|
};
|
|
57
61
|
|
|
58
62
|
/**
|
|
59
|
-
* @param
|
|
60
|
-
* @return
|
|
63
|
+
* @param options
|
|
64
|
+
* @return True if the request contains an unbounded query.
|
|
61
65
|
*/
|
|
62
|
-
const requestContainsUnboundedQuery = ( options ) => {
|
|
66
|
+
const requestContainsUnboundedQuery = ( options: APIFetchOptions ) => {
|
|
63
67
|
const pathIsUnbounded =
|
|
64
68
|
!! options.path && options.path.indexOf( 'per_page=-1' ) !== -1;
|
|
65
69
|
const urlIsUnbounded =
|
|
@@ -71,10 +75,10 @@ const requestContainsUnboundedQuery = ( options ) => {
|
|
|
71
75
|
* The REST API enforces an upper limit on the per_page option. To handle large
|
|
72
76
|
* collections, apiFetch consumers can pass `per_page=-1`; this middleware will
|
|
73
77
|
* then recursively assemble a full response array from all available pages.
|
|
74
|
-
*
|
|
75
|
-
* @
|
|
78
|
+
* @param options
|
|
79
|
+
* @param next
|
|
76
80
|
*/
|
|
77
|
-
const fetchAllMiddleware = async ( options, next ) => {
|
|
81
|
+
const fetchAllMiddleware: APIFetchMiddleware = async ( options, next ) => {
|
|
78
82
|
if ( options.parse === false ) {
|
|
79
83
|
// If a consumer has opted out of parsing, do not apply middleware.
|
|
80
84
|
return next( options );
|
|
@@ -108,7 +112,7 @@ const fetchAllMiddleware = async ( options, next ) => {
|
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
// Iteratively fetch all remaining pages until no "next" header is found.
|
|
111
|
-
let mergedResults =
|
|
115
|
+
let mergedResults = ( [] as Array< any > ).concat( results );
|
|
112
116
|
while ( nextPage ) {
|
|
113
117
|
const nextResponse = await apiFetch( {
|
|
114
118
|
...options,
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { APIFetchMiddleware } from '../types';
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Set of HTTP methods which are eligible to be overridden.
|
|
3
|
-
*
|
|
4
|
-
* @type {Set<string>}
|
|
5
8
|
*/
|
|
6
9
|
const OVERRIDE_METHODS = new Set( [ 'PATCH', 'PUT', 'DELETE' ] );
|
|
7
10
|
|
|
@@ -12,8 +15,6 @@ const OVERRIDE_METHODS = new Set( [ 'PATCH', 'PUT', 'DELETE' ] );
|
|
|
12
15
|
* is `GET`."
|
|
13
16
|
*
|
|
14
17
|
* @see https://fetch.spec.whatwg.org/#requests
|
|
15
|
-
*
|
|
16
|
-
* @type {string}
|
|
17
18
|
*/
|
|
18
19
|
const DEFAULT_METHOD = 'GET';
|
|
19
20
|
|
|
@@ -21,9 +22,10 @@ const DEFAULT_METHOD = 'GET';
|
|
|
21
22
|
* API Fetch middleware which overrides the request method for HTTP v1
|
|
22
23
|
* compatibility leveraging the REST API X-HTTP-Method-Override header.
|
|
23
24
|
*
|
|
24
|
-
* @
|
|
25
|
+
* @param options
|
|
26
|
+
* @param next
|
|
25
27
|
*/
|
|
26
|
-
const httpV1Middleware = ( options, next ) => {
|
|
28
|
+
const httpV1Middleware: APIFetchMiddleware = ( options, next ) => {
|
|
27
29
|
const { method = DEFAULT_METHOD } = options;
|
|
28
30
|
if ( OVERRIDE_METHODS.has( method.toUpperCase() ) ) {
|
|
29
31
|
options = {
|
|
@@ -10,12 +10,13 @@ import {
|
|
|
10
10
|
parseAndThrowError,
|
|
11
11
|
parseResponseAndNormalizeError,
|
|
12
12
|
} from '../utils/response';
|
|
13
|
+
import type { APIFetchOptions, APIFetchMiddleware } from '../types';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
|
-
* @param
|
|
16
|
-
* @return
|
|
16
|
+
* @param options
|
|
17
|
+
* @return True if the request is for media upload.
|
|
17
18
|
*/
|
|
18
|
-
function isMediaUploadRequest( options ) {
|
|
19
|
+
function isMediaUploadRequest( options: APIFetchOptions ) {
|
|
19
20
|
const isCreateMethod = !! options.method && options.method === 'POST';
|
|
20
21
|
const isMediaEndpoint =
|
|
21
22
|
( !! options.path && options.path.indexOf( '/wp/v2/media' ) !== -1 ) ||
|
|
@@ -26,10 +27,10 @@ function isMediaUploadRequest( options ) {
|
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Middleware handling media upload failures and retries.
|
|
29
|
-
*
|
|
30
|
-
* @
|
|
30
|
+
* @param options
|
|
31
|
+
* @param next
|
|
31
32
|
*/
|
|
32
|
-
const mediaUploadMiddleware = ( options, next ) => {
|
|
33
|
+
const mediaUploadMiddleware: APIFetchMiddleware = ( options, next ) => {
|
|
33
34
|
if ( ! isMediaUploadRequest( options ) ) {
|
|
34
35
|
return next( options );
|
|
35
36
|
}
|
|
@@ -38,10 +39,10 @@ const mediaUploadMiddleware = ( options, next ) => {
|
|
|
38
39
|
const maxRetries = 5;
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
|
-
* @param
|
|
42
|
-
* @return
|
|
42
|
+
* @param attachmentId
|
|
43
|
+
* @return Processed post response.
|
|
43
44
|
*/
|
|
44
|
-
const postProcess = ( attachmentId ) => {
|
|
45
|
+
const postProcess = ( attachmentId: string ): Promise< any > => {
|
|
45
46
|
retries++;
|
|
46
47
|
return next( {
|
|
47
48
|
path: `/wp/v2/media/${ attachmentId }/post-process`,
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Internal dependencies
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
import type { APIFetchMiddleware } from '../types';
|
|
5
|
+
|
|
6
|
+
const namespaceAndEndpointMiddleware: APIFetchMiddleware = (
|
|
7
|
+
options,
|
|
8
|
+
next
|
|
9
|
+
) => {
|
|
5
10
|
let path = options.path;
|
|
6
11
|
let namespaceTrimmed, endpointTrimmed;
|
|
7
12
|
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @return {import('../types').APIFetchMiddleware & { nonce: string }} A middleware to enhance a request with a nonce.
|
|
2
|
+
* Internal dependencies
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
import type { APIFetchMiddleware } from '../types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param nonce
|
|
8
|
+
*
|
|
9
|
+
* @return A middleware to enhance a request with a nonce.
|
|
10
|
+
*/
|
|
11
|
+
function createNonceMiddleware(
|
|
12
|
+
nonce: string
|
|
13
|
+
): APIFetchMiddleware & { nonce: string } {
|
|
14
|
+
const middleware: APIFetchMiddleware & { nonce: string } = (
|
|
15
|
+
options,
|
|
16
|
+
next
|
|
17
|
+
) => {
|
|
10
18
|
const { headers = {} } = options;
|
|
11
19
|
|
|
12
20
|
// If an 'X-WP-Nonce' header (or any case-insensitive variation
|
|
@@ -4,10 +4,17 @@
|
|
|
4
4
|
import { addQueryArgs, getQueryArgs, normalizePath } from '@wordpress/url';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @return {import('../types').APIFetchMiddleware} Preloading middleware.
|
|
7
|
+
* Internal dependencies
|
|
9
8
|
*/
|
|
10
|
-
|
|
9
|
+
import type { APIFetchMiddleware } from '../types';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param preloadedData
|
|
13
|
+
* @return Preloading middleware.
|
|
14
|
+
*/
|
|
15
|
+
function createPreloadingMiddleware(
|
|
16
|
+
preloadedData: Record< string, any >
|
|
17
|
+
): APIFetchMiddleware {
|
|
11
18
|
const cache = Object.fromEntries(
|
|
12
19
|
Object.entries( preloadedData ).map( ( [ path, data ] ) => [
|
|
13
20
|
normalizePath( path ),
|
|
@@ -17,7 +24,6 @@ function createPreloadingMiddleware( preloadedData ) {
|
|
|
17
24
|
|
|
18
25
|
return ( options, next ) => {
|
|
19
26
|
const { parse = true } = options;
|
|
20
|
-
/** @type {string | void} */
|
|
21
27
|
let rawPath = options.path;
|
|
22
28
|
if ( ! rawPath && options.url ) {
|
|
23
29
|
const { rest_route: pathFromQuery, ...queryArgs } = getQueryArgs(
|
|
@@ -63,11 +69,14 @@ function createPreloadingMiddleware( preloadedData ) {
|
|
|
63
69
|
/**
|
|
64
70
|
* This is a helper function that sends a success response.
|
|
65
71
|
*
|
|
66
|
-
* @param
|
|
67
|
-
* @param
|
|
68
|
-
* @return
|
|
72
|
+
* @param responseData
|
|
73
|
+
* @param parse
|
|
74
|
+
* @return Promise with the response.
|
|
69
75
|
*/
|
|
70
|
-
function prepareResponse(
|
|
76
|
+
function prepareResponse(
|
|
77
|
+
responseData: Record< string, any >,
|
|
78
|
+
parse: boolean
|
|
79
|
+
) {
|
|
71
80
|
if ( parse ) {
|
|
72
81
|
return Promise.resolve( responseData.body );
|
|
73
82
|
}
|
|
@@ -82,12 +91,13 @@ function prepareResponse( responseData, parse ) {
|
|
|
82
91
|
);
|
|
83
92
|
} catch {
|
|
84
93
|
// See: https://github.com/WordPress/gutenberg/issues/67358#issuecomment-2621163926.
|
|
85
|
-
Object.entries(
|
|
94
|
+
Object.entries(
|
|
95
|
+
responseData.headers as Record< string, string >
|
|
96
|
+
).forEach( ( [ key, value ] ) => {
|
|
86
97
|
if ( key.toLowerCase() === 'link' ) {
|
|
87
98
|
responseData.headers[ key ] = value.replace(
|
|
88
99
|
/<([^>]+)>/,
|
|
89
|
-
(
|
|
90
|
-
`<${ encodeURI( url ) }>`
|
|
100
|
+
( _, url ) => `<${ encodeURI( url ) }>`
|
|
91
101
|
);
|
|
92
102
|
}
|
|
93
103
|
} );
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { APIFetchMiddleware } from '../types';
|
|
5
|
+
import namespaceAndEndpointMiddleware from './namespace-endpoint';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param rootURL
|
|
9
|
+
* @return Root URL middleware.
|
|
10
|
+
*/
|
|
11
|
+
const createRootURLMiddleware =
|
|
12
|
+
( rootURL: string ): APIFetchMiddleware =>
|
|
13
|
+
( options, next ) => {
|
|
14
|
+
return namespaceAndEndpointMiddleware( options, ( optionsWithPath ) => {
|
|
15
|
+
let url = optionsWithPath.url;
|
|
16
|
+
let path = optionsWithPath.path;
|
|
17
|
+
let apiRoot;
|
|
18
|
+
|
|
19
|
+
if ( typeof path === 'string' ) {
|
|
20
|
+
apiRoot = rootURL;
|
|
21
|
+
|
|
22
|
+
if ( -1 !== rootURL.indexOf( '?' ) ) {
|
|
23
|
+
path = path.replace( '?', '&' );
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
path = path.replace( /^\//, '' );
|
|
27
|
+
|
|
28
|
+
// API root may already include query parameter prefix if site is
|
|
29
|
+
// configured to use plain permalinks.
|
|
30
|
+
if (
|
|
31
|
+
'string' === typeof apiRoot &&
|
|
32
|
+
-1 !== apiRoot.indexOf( '?' )
|
|
33
|
+
) {
|
|
34
|
+
path = path.replace( '?', '&' );
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
url = apiRoot + path;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return next( {
|
|
41
|
+
...optionsWithPath,
|
|
42
|
+
url,
|
|
43
|
+
} );
|
|
44
|
+
} );
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default createRootURLMiddleware;
|
|
@@ -19,7 +19,7 @@ describe( 'Fetch All Middleware', () => {
|
|
|
19
19
|
expect.hasAssertions();
|
|
20
20
|
const originalOptions = { url: '/posts?per_page=-1' };
|
|
21
21
|
let counter = 1;
|
|
22
|
-
jest.doMock( '../../index.
|
|
22
|
+
jest.doMock( '../../index.ts', () => ( options ) => {
|
|
23
23
|
const expectedUrl =
|
|
24
24
|
counter === 1
|
|
25
25
|
? '/posts?per_page=100'
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
|
+
import type { FetchHandler } from '../../types';
|
|
4
5
|
import httpV1Middleware from '../http-v1';
|
|
5
6
|
|
|
6
7
|
describe( 'HTTP v1 Middleware', () => {
|
|
7
8
|
it( 'should use a POST for a PUT requests', () => {
|
|
8
9
|
expect.hasAssertions();
|
|
9
10
|
|
|
10
|
-
const callback = ( options ) => {
|
|
11
|
+
const callback: FetchHandler = async ( options ) => {
|
|
11
12
|
expect( options.method ).toBe( 'POST' );
|
|
12
|
-
expect( options.headers[ 'X-HTTP-Method-Override' ] ).toBe(
|
|
13
|
+
expect( options.headers![ 'X-HTTP-Method-Override' ] ).toBe(
|
|
14
|
+
'PUT'
|
|
15
|
+
);
|
|
13
16
|
};
|
|
14
17
|
|
|
15
18
|
httpV1Middleware( { method: 'PUT', data: {} }, callback );
|
|
@@ -19,7 +22,7 @@ describe( 'HTTP v1 Middleware', () => {
|
|
|
19
22
|
expect.hasAssertions();
|
|
20
23
|
|
|
21
24
|
const requestOptions = { method: 'GET', path: '/wp/v2/posts' };
|
|
22
|
-
const callback = ( options ) => {
|
|
25
|
+
const callback: FetchHandler = async ( options ) => {
|
|
23
26
|
expect( options ).toBe( requestOptions );
|
|
24
27
|
};
|
|
25
28
|
|
|
@@ -30,7 +33,7 @@ describe( 'HTTP v1 Middleware', () => {
|
|
|
30
33
|
expect.hasAssertions();
|
|
31
34
|
|
|
32
35
|
const requestOptions = { path: '/wp/v2/posts' };
|
|
33
|
-
const callback = ( options ) => {
|
|
36
|
+
const callback: FetchHandler = async ( options ) => {
|
|
34
37
|
expect( options ).toBe( requestOptions );
|
|
35
38
|
};
|
|
36
39
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
|
+
import type { FetchHandler } from '../../types';
|
|
4
5
|
import mediaUploadMiddleware from '../media-upload';
|
|
5
6
|
|
|
6
7
|
describe( 'Media Upload Middleware', () => {
|
|
@@ -8,7 +9,7 @@ describe( 'Media Upload Middleware', () => {
|
|
|
8
9
|
expect.hasAssertions();
|
|
9
10
|
|
|
10
11
|
const originalOptions = { path: '/wp/v2/media' };
|
|
11
|
-
const next = ( options ) => {
|
|
12
|
+
const next: FetchHandler = async ( options ) => {
|
|
12
13
|
expect( options ).toBe( originalOptions );
|
|
13
14
|
};
|
|
14
15
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
|
+
import type { FetchHandler } from '../../types';
|
|
4
5
|
import namespaceEndpointMiddleware from '../namespace-endpoint';
|
|
5
6
|
|
|
6
7
|
describe( 'Namespace & Endpoint middleware', () => {
|
|
@@ -12,7 +13,7 @@ describe( 'Namespace & Endpoint middleware', () => {
|
|
|
12
13
|
namespace: '/wp/v2',
|
|
13
14
|
endpoint: '/posts',
|
|
14
15
|
};
|
|
15
|
-
const callback = ( options ) => {
|
|
16
|
+
const callback: FetchHandler = async ( options ) => {
|
|
16
17
|
expect( options.path ).toBe( 'wp/v2/posts' );
|
|
17
18
|
expect( options.namespace ).toBeUndefined();
|
|
18
19
|
expect( options.endpoint ).toBeUndefined();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
|
+
import type { FetchHandler } from '../../types';
|
|
4
5
|
import createNonceMiddleware from '../nonce';
|
|
5
6
|
|
|
6
7
|
describe( 'Nonce middleware', () => {
|
|
@@ -13,8 +14,8 @@ describe( 'Nonce middleware', () => {
|
|
|
13
14
|
method: 'GET',
|
|
14
15
|
path: '/wp/v2/posts',
|
|
15
16
|
};
|
|
16
|
-
const callback = ( options ) => {
|
|
17
|
-
expect( options.headers[ 'X-WP-Nonce' ] ).toBe( nonce );
|
|
17
|
+
const callback: FetchHandler = async ( options ) => {
|
|
18
|
+
expect( options.headers![ 'X-WP-Nonce' ] ).toBe( nonce );
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
nonceMiddleware( requestOptions, callback );
|
|
@@ -31,8 +32,8 @@ describe( 'Nonce middleware', () => {
|
|
|
31
32
|
headers: { 'X-WP-Nonce': 'existing nonce' },
|
|
32
33
|
};
|
|
33
34
|
|
|
34
|
-
const callback = ( options ) => {
|
|
35
|
-
expect( options.headers[ 'X-WP-Nonce' ] ).toBe( 'new nonce' );
|
|
35
|
+
const callback: FetchHandler = async ( options ) => {
|
|
36
|
+
expect( options.headers![ 'X-WP-Nonce' ] ).toBe( 'new nonce' );
|
|
36
37
|
};
|
|
37
38
|
|
|
38
39
|
nonceMiddleware( requestOptions, callback );
|