Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@wordpress/api-fetch

Package Overview
Dependencies
Maintainers
8
Versions
186
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@wordpress/api-fetch - npm Package Compare versions

Comparing version 2.2.8 to 3.0.0

140

build-module/index.js

@@ -43,92 +43,110 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread";

};
var middlewares = [];
var middlewares = [userLocaleMiddleware, namespaceEndpointMiddleware, httpV1Middleware, fetchAllMiddleware];
function registerMiddleware(middleware) {
middlewares.push(middleware);
middlewares.unshift(middleware);
}
function apiFetch(options) {
var raw = function raw(nextOptions) {
var url = nextOptions.url,
path = nextOptions.path,
data = nextOptions.data,
_nextOptions$parse = nextOptions.parse,
parse = _nextOptions$parse === void 0 ? true : _nextOptions$parse,
remainingOptions = _objectWithoutProperties(nextOptions, ["url", "path", "data", "parse"]);
var defaultFetchHandler = function defaultFetchHandler(nextOptions) {
var url = nextOptions.url,
path = nextOptions.path,
data = nextOptions.data,
_nextOptions$parse = nextOptions.parse,
parse = _nextOptions$parse === void 0 ? true : _nextOptions$parse,
remainingOptions = _objectWithoutProperties(nextOptions, ["url", "path", "data", "parse"]);
var body = nextOptions.body,
headers = nextOptions.headers; // Merge explicitly-provided headers with default values.
var body = nextOptions.body,
headers = nextOptions.headers; // Merge explicitly-provided headers with default values.
headers = _objectSpread({}, DEFAULT_HEADERS, headers); // The `data` property is a shorthand for sending a JSON body.
headers = _objectSpread({}, DEFAULT_HEADERS, headers); // The `data` property is a shorthand for sending a JSON body.
if (data) {
body = JSON.stringify(data);
headers['Content-Type'] = 'application/json';
if (data) {
body = JSON.stringify(data);
headers['Content-Type'] = 'application/json';
}
var responsePromise = window.fetch(url || path, _objectSpread({}, DEFAULT_OPTIONS, remainingOptions, {
body: body,
headers: headers
}));
var checkStatus = function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
var responsePromise = window.fetch(url || path, _objectSpread({}, DEFAULT_OPTIONS, remainingOptions, {
body: body,
headers: headers
}));
throw response;
};
var checkStatus = function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
var parseResponse = function parseResponse(response) {
if (parse) {
if (response.status === 204) {
return null;
}
throw response;
};
return response.json ? response.json() : Promise.reject(response);
}
var parseResponse = function parseResponse(response) {
if (parse) {
if (response.status === 204) {
return null;
}
return response;
};
return response.json ? response.json() : Promise.reject(response);
}
return responsePromise.then(checkStatus).then(parseResponse).catch(function (response) {
if (!parse) {
throw response;
}
return response;
var invalidJsonError = {
code: 'invalid_json',
message: __('The response is not a valid JSON response.')
};
return responsePromise.then(checkStatus).then(parseResponse).catch(function (response) {
if (!parse) {
throw response;
}
if (!response || !response.json) {
throw invalidJsonError;
}
var invalidJsonError = {
code: 'invalid_json',
message: __('The response is not a valid JSON response.')
return response.json().catch(function () {
throw invalidJsonError;
}).then(function (error) {
var unknownError = {
code: 'unknown_error',
message: __('An unknown error occurred.')
};
throw error || unknownError;
});
});
};
if (!response || !response.json) {
throw invalidJsonError;
}
var fetchHandler = defaultFetchHandler;
/**
* Defines a custom fetch handler for making the requests that will override
* the default one using window.fetch
*
* @param {Function} newFetchHandler The new fetch handler
*/
return response.json().catch(function () {
throw invalidJsonError;
}).then(function (error) {
var unknownError = {
code: 'unknown_error',
message: __('An unknown error occurred.')
};
throw error || unknownError;
});
});
};
function setFetchHandler(newFetchHandler) {
fetchHandler = newFetchHandler;
}
var steps = [raw, fetchAllMiddleware, httpV1Middleware, namespaceEndpointMiddleware, userLocaleMiddleware].concat(middlewares).reverse();
function apiFetch(options) {
var steps = [].concat(middlewares, [fetchHandler]);
var runMiddleware = function runMiddleware(index) {
return function (nextOptions) {
var nextMiddleware = steps[index];
var next = runMiddleware(index + 1);
return nextMiddleware(nextOptions, next);
var createRunStep = function createRunStep(index) {
return function (workingOptions) {
var step = steps[index];
if (index === steps.length - 1) {
return step(workingOptions);
}
var next = createRunStep(index + 1);
return step(workingOptions, next);
};
};
return runMiddleware(0)(options);
return createRunStep(0)(options);
}
apiFetch.use = registerMiddleware;
apiFetch.setFetchHandler = setFetchHandler;
apiFetch.createNonceMiddleware = createNonceMiddleware;

@@ -135,0 +153,0 @@ apiFetch.createPreloadingMiddleware = createPreloadingMiddleware;

import _objectSpread from "@babel/runtime/helpers/esm/objectSpread";
/**
* External dependencies
*/
import { addAction } from '@wordpress/hooks';
var createNonceMiddleware = function createNonceMiddleware(nonce) {
var usedNonce = nonce;
/**
* This is not ideal but it's fine for now.
*
* Configure heartbeat to refresh the wp-api nonce, keeping the editor
* authorization intact.
*/
addAction('heartbeat.tick', 'core/api-fetch/create-nonce-middleware', function (response) {
if (response['rest-nonce']) {
usedNonce = response['rest-nonce'];
}
});
return function (options, next) {
var headers = options.headers || {}; // If an 'X-WP-Nonce' header (or any case-insensitive variation
function createNonceMiddleware(nonce) {
function middleware(options, next) {
var _options$headers = options.headers,
headers = _options$headers === void 0 ? {} : _options$headers; // If an 'X-WP-Nonce' header (or any case-insensitive variation
// thereof) was specified, no need to add a nonce header.
var addNonceHeader = true;
for (var headerName in headers) {
if (headers.hasOwnProperty(headerName)) {
if (headerName.toLowerCase() === 'x-wp-nonce') {
addNonceHeader = false;
break;
}
if (headerName.toLowerCase() === 'x-wp-nonce') {
return next(options);
}
}
if (addNonceHeader) {
// Do not mutate the original headers object, if any.
headers = _objectSpread({}, headers, {
'X-WP-Nonce': usedNonce
});
}
return next(_objectSpread({}, options, {
headers: headers
headers: _objectSpread({}, headers, {
'X-WP-Nonce': middleware.nonce
})
}));
};
};
}
middleware.nonce = nonce;
return middleware;
}
export default createNonceMiddleware;
//# sourceMappingURL=nonce.js.map

@@ -61,91 +61,109 @@ "use strict";

};
var middlewares = [];
var middlewares = [_userLocale.default, _namespaceEndpoint.default, _httpV.default, _fetchAllMiddleware.default];
function registerMiddleware(middleware) {
middlewares.push(middleware);
middlewares.unshift(middleware);
}
function apiFetch(options) {
var raw = function raw(nextOptions) {
var url = nextOptions.url,
path = nextOptions.path,
data = nextOptions.data,
_nextOptions$parse = nextOptions.parse,
parse = _nextOptions$parse === void 0 ? true : _nextOptions$parse,
remainingOptions = (0, _objectWithoutProperties2.default)(nextOptions, ["url", "path", "data", "parse"]);
var body = nextOptions.body,
headers = nextOptions.headers; // Merge explicitly-provided headers with default values.
var defaultFetchHandler = function defaultFetchHandler(nextOptions) {
var url = nextOptions.url,
path = nextOptions.path,
data = nextOptions.data,
_nextOptions$parse = nextOptions.parse,
parse = _nextOptions$parse === void 0 ? true : _nextOptions$parse,
remainingOptions = (0, _objectWithoutProperties2.default)(nextOptions, ["url", "path", "data", "parse"]);
var body = nextOptions.body,
headers = nextOptions.headers; // Merge explicitly-provided headers with default values.
headers = (0, _objectSpread2.default)({}, DEFAULT_HEADERS, headers); // The `data` property is a shorthand for sending a JSON body.
headers = (0, _objectSpread2.default)({}, DEFAULT_HEADERS, headers); // The `data` property is a shorthand for sending a JSON body.
if (data) {
body = JSON.stringify(data);
headers['Content-Type'] = 'application/json';
if (data) {
body = JSON.stringify(data);
headers['Content-Type'] = 'application/json';
}
var responsePromise = window.fetch(url || path, (0, _objectSpread2.default)({}, DEFAULT_OPTIONS, remainingOptions, {
body: body,
headers: headers
}));
var checkStatus = function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
var responsePromise = window.fetch(url || path, (0, _objectSpread2.default)({}, DEFAULT_OPTIONS, remainingOptions, {
body: body,
headers: headers
}));
throw response;
};
var checkStatus = function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
var parseResponse = function parseResponse(response) {
if (parse) {
if (response.status === 204) {
return null;
}
throw response;
};
return response.json ? response.json() : Promise.reject(response);
}
var parseResponse = function parseResponse(response) {
if (parse) {
if (response.status === 204) {
return null;
}
return response;
};
return response.json ? response.json() : Promise.reject(response);
}
return responsePromise.then(checkStatus).then(parseResponse).catch(function (response) {
if (!parse) {
throw response;
}
return response;
var invalidJsonError = {
code: 'invalid_json',
message: (0, _i18n.__)('The response is not a valid JSON response.')
};
return responsePromise.then(checkStatus).then(parseResponse).catch(function (response) {
if (!parse) {
throw response;
}
if (!response || !response.json) {
throw invalidJsonError;
}
var invalidJsonError = {
code: 'invalid_json',
message: (0, _i18n.__)('The response is not a valid JSON response.')
return response.json().catch(function () {
throw invalidJsonError;
}).then(function (error) {
var unknownError = {
code: 'unknown_error',
message: (0, _i18n.__)('An unknown error occurred.')
};
throw error || unknownError;
});
});
};
if (!response || !response.json) {
throw invalidJsonError;
}
var fetchHandler = defaultFetchHandler;
/**
* Defines a custom fetch handler for making the requests that will override
* the default one using window.fetch
*
* @param {Function} newFetchHandler The new fetch handler
*/
return response.json().catch(function () {
throw invalidJsonError;
}).then(function (error) {
var unknownError = {
code: 'unknown_error',
message: (0, _i18n.__)('An unknown error occurred.')
};
throw error || unknownError;
});
});
};
function setFetchHandler(newFetchHandler) {
fetchHandler = newFetchHandler;
}
var steps = [raw, _fetchAllMiddleware.default, _httpV.default, _namespaceEndpoint.default, _userLocale.default].concat(middlewares).reverse();
function apiFetch(options) {
var steps = [].concat(middlewares, [fetchHandler]);
var runMiddleware = function runMiddleware(index) {
return function (nextOptions) {
var nextMiddleware = steps[index];
var next = runMiddleware(index + 1);
return nextMiddleware(nextOptions, next);
var createRunStep = function createRunStep(index) {
return function (workingOptions) {
var step = steps[index];
if (index === steps.length - 1) {
return step(workingOptions);
}
var next = createRunStep(index + 1);
return step(workingOptions, next);
};
};
return runMiddleware(0)(options);
return createRunStep(0)(options);
}
apiFetch.use = registerMiddleware;
apiFetch.setFetchHandler = setFetchHandler;
apiFetch.createNonceMiddleware = _nonce.default;

@@ -152,0 +170,0 @@ apiFetch.createPreloadingMiddleware = _preloading.default;

@@ -12,51 +12,27 @@ "use strict";

var _hooks = require("@wordpress/hooks");
/**
* External dependencies
*/
var createNonceMiddleware = function createNonceMiddleware(nonce) {
var usedNonce = nonce;
/**
* This is not ideal but it's fine for now.
*
* Configure heartbeat to refresh the wp-api nonce, keeping the editor
* authorization intact.
*/
(0, _hooks.addAction)('heartbeat.tick', 'core/api-fetch/create-nonce-middleware', function (response) {
if (response['rest-nonce']) {
usedNonce = response['rest-nonce'];
}
});
return function (options, next) {
var headers = options.headers || {}; // If an 'X-WP-Nonce' header (or any case-insensitive variation
function createNonceMiddleware(nonce) {
function middleware(options, next) {
var _options$headers = options.headers,
headers = _options$headers === void 0 ? {} : _options$headers; // If an 'X-WP-Nonce' header (or any case-insensitive variation
// thereof) was specified, no need to add a nonce header.
var addNonceHeader = true;
for (var headerName in headers) {
if (headers.hasOwnProperty(headerName)) {
if (headerName.toLowerCase() === 'x-wp-nonce') {
addNonceHeader = false;
break;
}
if (headerName.toLowerCase() === 'x-wp-nonce') {
return next(options);
}
}
if (addNonceHeader) {
// Do not mutate the original headers object, if any.
headers = (0, _objectSpread2.default)({}, headers, {
'X-WP-Nonce': usedNonce
});
}
return next((0, _objectSpread2.default)({}, options, {
headers: headers
headers: (0, _objectSpread2.default)({}, headers, {
'X-WP-Nonce': middleware.nonce
})
}));
};
};
}
middleware.nonce = nonce;
return middleware;
}
var _default = createNonceMiddleware;
exports.default = _default;
//# sourceMappingURL=nonce.js.map

@@ -0,1 +1,12 @@

## 3.0.0 (Unreleased)
### Breaking Changes
- A created nonce middleware will no longer automatically listen for `heartbeat.tick` actions. Assign to the new `nonce` middleware property instead.
### New Feature
- The function returned by `createNonceMiddleware` includes an assignable `nonce` property corresponding to the active nonce to be used.
- Default fetch handler can be overridden with a custom fetch handler
## 2.2.7 (2019-01-03)

@@ -2,0 +13,0 @@

### WordPress - Web publishing software
Copyright 2011-2018 by the contributors
Copyright 2011-2019 by the contributors

@@ -5,0 +5,0 @@ This program is free software; you can redistribute it and/or modify

{
"name": "@wordpress/api-fetch",
"version": "2.2.8",
"version": "3.0.0",
"description": "Utility to make WordPress REST API requests.",

@@ -15,3 +15,4 @@ "author": "The WordPress Contributors",

"type": "git",
"url": "https://github.com/WordPress/gutenberg.git"
"url": "https://github.com/WordPress/gutenberg.git",
"directory": "packages/api-fetch"
},

@@ -25,6 +26,5 @@ "bugs": {

"dependencies": {
"@babel/runtime": "^7.0.0",
"@wordpress/hooks": "^2.0.5",
"@wordpress/i18n": "^3.1.1",
"@wordpress/url": "^2.3.3"
"@babel/runtime": "^7.3.1",
"@wordpress/i18n": "^3.2.0",
"@wordpress/url": "^2.4.0"
},

@@ -34,3 +34,3 @@ "publishConfig": {

},
"gitHead": "c59ef56fe16bdcc1fffd70b6e8a2fda4bf9c28fe"
"gitHead": "80d228669adadb8dfcd24b8421517fed3be2d474"
}

@@ -79,2 +79,4 @@ # API Fetch

The function returned by `createNonceMiddleware` includes a `nonce` property corresponding to the actively used nonce. You may also assign to this property if you have a fresh nonce value to use.
**Root URL middleware**

@@ -89,2 +91,25 @@

### Custom fetch handler
The `api-fetch` package uses `window.fetch` for making the requests but you can use a custom fetch handler by using the `setFetchHandler` method. The custom fetch handler will receive the `options` passed to the `apiFetch` calls.
**Example**
The example below uses a custom fetch handler for making all the requests with [`axios`](https://github.com/axios/axios).
```js
import apiFetch from '@wordpress/api-fetch';
import axios from 'axios';
apiFetch.setFetchHandler( ( options ) => {
const { url, path, data, method } = options;
return axios( {
url: url || path,
method,
data,
} );
} );
```
<br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p>

@@ -41,102 +41,117 @@ /**

const middlewares = [];
const middlewares = [
userLocaleMiddleware,
namespaceEndpointMiddleware,
httpV1Middleware,
fetchAllMiddleware,
];
function registerMiddleware( middleware ) {
middlewares.push( middleware );
middlewares.unshift( middleware );
}
function apiFetch( options ) {
const raw = ( nextOptions ) => {
const { url, path, data, parse = true, ...remainingOptions } = nextOptions;
let { body, headers } = nextOptions;
const defaultFetchHandler = ( nextOptions ) => {
const { url, path, data, parse = true, ...remainingOptions } = nextOptions;
let { body, headers } = nextOptions;
// Merge explicitly-provided headers with default values.
headers = { ...DEFAULT_HEADERS, ...headers };
// Merge explicitly-provided headers with default values.
headers = { ...DEFAULT_HEADERS, ...headers };
// The `data` property is a shorthand for sending a JSON body.
if ( data ) {
body = JSON.stringify( data );
headers[ 'Content-Type' ] = 'application/json';
// The `data` property is a shorthand for sending a JSON body.
if ( data ) {
body = JSON.stringify( data );
headers[ 'Content-Type' ] = 'application/json';
}
const responsePromise = window.fetch(
url || path,
{
...DEFAULT_OPTIONS,
...remainingOptions,
body,
headers,
}
);
const checkStatus = ( response ) => {
if ( response.status >= 200 && response.status < 300 ) {
return response;
}
const responsePromise = window.fetch(
url || path,
{
...DEFAULT_OPTIONS,
...remainingOptions,
body,
headers,
throw response;
};
const parseResponse = ( response ) => {
if ( parse ) {
if ( response.status === 204 ) {
return null;
}
);
const checkStatus = ( response ) => {
if ( response.status >= 200 && response.status < 300 ) {
return response;
}
throw response;
};
return response.json ? response.json() : Promise.reject( response );
}
const parseResponse = ( response ) => {
if ( parse ) {
if ( response.status === 204 ) {
return null;
}
return response;
};
return response.json ? response.json() : Promise.reject( response );
return responsePromise
.then( checkStatus )
.then( parseResponse )
.catch( ( response ) => {
if ( ! parse ) {
throw response;
}
return response;
};
const invalidJsonError = {
code: 'invalid_json',
message: __( 'The response is not a valid JSON response.' ),
};
return responsePromise
.then( checkStatus )
.then( parseResponse )
.catch( ( response ) => {
if ( ! parse ) {
throw response;
}
if ( ! response || ! response.json ) {
throw invalidJsonError;
}
const invalidJsonError = {
code: 'invalid_json',
message: __( 'The response is not a valid JSON response.' ),
};
if ( ! response || ! response.json ) {
return response.json()
.catch( () => {
throw invalidJsonError;
}
} )
.then( ( error ) => {
const unknownError = {
code: 'unknown_error',
message: __( 'An unknown error occurred.' ),
};
return response.json()
.catch( () => {
throw invalidJsonError;
} )
.then( ( error ) => {
const unknownError = {
code: 'unknown_error',
message: __( 'An unknown error occurred.' ),
};
throw error || unknownError;
} );
} );
};
throw error || unknownError;
} );
} );
};
let fetchHandler = defaultFetchHandler;
const steps = [
raw,
fetchAllMiddleware,
httpV1Middleware,
namespaceEndpointMiddleware,
userLocaleMiddleware,
...middlewares,
].reverse();
/**
* Defines a custom fetch handler for making the requests that will override
* the default one using window.fetch
*
* @param {Function} newFetchHandler The new fetch handler
*/
function setFetchHandler( newFetchHandler ) {
fetchHandler = newFetchHandler;
}
const runMiddleware = ( index ) => ( nextOptions ) => {
const nextMiddleware = steps[ index ];
const next = runMiddleware( index + 1 );
return nextMiddleware( nextOptions, next );
function apiFetch( options ) {
const steps = [ ...middlewares, fetchHandler ];
const createRunStep = ( index ) => ( workingOptions ) => {
const step = steps[ index ];
if ( index === steps.length - 1 ) {
return step( workingOptions );
}
const next = createRunStep( index + 1 );
return step( workingOptions, next );
};
return runMiddleware( 0 )( options );
return createRunStep( 0 )( options );
}
apiFetch.use = registerMiddleware;
apiFetch.setFetchHandler = setFetchHandler;

@@ -143,0 +158,0 @@ apiFetch.createNonceMiddleware = createNonceMiddleware;

@@ -1,50 +0,27 @@

/**
* External dependencies
*/
import { addAction } from '@wordpress/hooks';
function createNonceMiddleware( nonce ) {
function middleware( options, next ) {
const { headers = {} } = options;
const createNonceMiddleware = ( nonce ) => {
let usedNonce = nonce;
/**
* This is not ideal but it's fine for now.
*
* Configure heartbeat to refresh the wp-api nonce, keeping the editor
* authorization intact.
*/
addAction( 'heartbeat.tick', 'core/api-fetch/create-nonce-middleware', ( response ) => {
if ( response[ 'rest-nonce' ] ) {
usedNonce = response[ 'rest-nonce' ];
}
} );
return function( options, next ) {
let headers = options.headers || {};
// If an 'X-WP-Nonce' header (or any case-insensitive variation
// thereof) was specified, no need to add a nonce header.
let addNonceHeader = true;
for ( const headerName in headers ) {
if ( headers.hasOwnProperty( headerName ) ) {
if ( headerName.toLowerCase() === 'x-wp-nonce' ) {
addNonceHeader = false;
break;
}
if ( headerName.toLowerCase() === 'x-wp-nonce' ) {
return next( options );
}
}
if ( addNonceHeader ) {
// Do not mutate the original headers object, if any.
headers = {
...headers,
'X-WP-Nonce': usedNonce,
};
}
return next( {
...options,
headers,
headers: {
...headers,
'X-WP-Nonce': middleware.nonce,
},
} );
};
};
}
middleware.nonce = nonce;
return middleware;
}
export default createNonceMiddleware;

@@ -34,2 +34,3 @@ /**

const callback = ( options ) => {
expect( options ).toBe( requestOptions );
expect( options.headers[ 'X-WP-Nonce' ] ).toBe( 'existing nonce' );

@@ -36,0 +37,0 @@ };

@@ -186,2 +186,36 @@ /**

} );
it( 'should not use the default fetch handler when using a custom fetch handler', () => {
const customFetchHandler = jest.fn();
apiFetch.setFetchHandler( customFetchHandler );
apiFetch( { path: '/random' } );
expect( window.fetch ).not.toHaveBeenCalled();
expect( customFetchHandler ).toHaveBeenCalledWith( {
path: '/random?_locale=user',
} );
} );
it( 'should run the last-registered user-defined middleware first', () => {
// This could potentially impact other tests in that a lingering
// middleware is left. For the purposes of this test, it is sufficient
// to ensure that the last-registered middleware receives the original
// options object. It also assumes that some built-in middleware would
// either mutate or clone the original options if the extra middleware
// had been pushed to the stack.
expect.assertions( 1 );
const expectedOptions = {};
apiFetch.use( ( actualOptions, next ) => {
expect( actualOptions ).toBe( expectedOptions );
return next( actualOptions );
} );
apiFetch( expectedOptions );
} );
} );

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc