Created
April 28, 2020 10:50
-
-
Save nilsnolde/1be4fa6155c2770d0657c244c371987a to your computer and use it in GitHub Desktop.
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
/* eslint-disable camelcase */ | |
import axios from 'axios' | |
import OAuth from 'oauth-1.0a' | |
import crypto from 'crypto-browserify' | |
import * as R from 'ramda' | |
import queryString from 'query-string' | |
/** | |
* WooCommerce REST API wrappercat | |
* | |
* @param {String} consumerKey | |
* @param {String} consumerSecret | |
* @param {Number} timeout | |
*/ | |
class WooCommerceAPI { | |
constructor(consumerKey, consumerSecret, timeout = 60000) { | |
this.consumerKey = consumerKey | |
this.consumerSecret = consumerSecret | |
this.timeout = timeout | |
this._request = axios.create({ | |
//baseURL: process.env.REACT_APP_WC_API_URL + '/wp-json/wc/v3', | |
baseURL : 'http://localhost:8080/wp-json/wc/v3', | |
timeout: this.timeout | |
}) | |
} | |
/** | |
* Check for object | |
* | |
* @param {object} param | |
* @return {bool} | |
*/ | |
static _isObject(obj) { | |
return obj === Object(obj) | |
} | |
/** | |
* Normalize query string for oAuth | |
* | |
* @param {object} params | |
* @return {string} | |
*/ | |
static _normalizeQueryString(params) { | |
if (!params) { | |
return '' | |
} | |
const params_list = [] | |
for (const p in params) { | |
params_list.push(p) | |
} | |
params_list.sort() | |
const urlQueryString = {} | |
for (const idx in params_list) { | |
/** we can't use POST with oauth which is why we have to make sure | |
our POST payload (may be nested, objects or arrays) is added correctly | |
as GET parameters which woocommerce can read **/ | |
if ( | |
Object.prototype.toString.call(params[params_list[idx]]) === | |
'[object Object]' | |
) { | |
const prepNestedParam = (paramValue, paramKey) => { | |
urlQueryString[params_list[idx] + '[' + paramKey + ']'] = paramValue | |
} | |
R.forEachObjIndexed(prepNestedParam, params[params_list[idx]]) | |
} else if ( | |
Object.prototype.toString.call(params[params_list[idx]]) === | |
'[object Array]' | |
) { | |
let cnt = 0 | |
for (const item of params[params_list[idx]]) { | |
if (Object.prototype.toString.call(item) === '[object Object]') { | |
for (const k in item) { | |
urlQueryString[ | |
params_list[idx] + '[' + cnt + ']' + '[' + k + ']' | |
] = item[k] | |
} | |
cnt += 1 | |
} else { | |
urlQueryString[params_list[idx] + '[' + cnt + ']'] = item | |
} | |
} | |
} else { | |
const paramKey = encodeURIComponent(params_list[idx]) | |
.replace('%5B', '[') | |
.replace('%5D', ']') | |
const paramValue = encodeURIComponent(params[params_list[idx]]) | |
urlQueryString[paramKey] = paramValue | |
} | |
} | |
return '?' + queryString.stringify(urlQueryString, { encode: false }) | |
} | |
/** | |
* Get OAuth | |
* | |
* @return {OAuth} | |
*/ | |
_getOAuth() { | |
const data = { | |
consumer: { | |
key: this.consumerKey, | |
secret: this.consumerSecret | |
}, | |
signature_method: 'HMAC-SHA1', | |
hash_function: (base_string, key) => { | |
return crypto | |
.createHmac('sha1', key) | |
.update(base_string) | |
.digest('base64') | |
} | |
} | |
return new OAuth(data) | |
} | |
/** | |
* GET requests | |
* | |
* @param {String} endpoint | |
* @param {Object} params | |
* | |
* @return {Object} | |
*/ | |
get(endpoint, params = null) { | |
const method = 'GET' | |
const urlString = WooCommerceAPI._normalizeQueryString(params) | |
const oauth_params = this._getOAuth().authorize({ | |
url: | |
'http://localhost:8080' + | |
//process.env.REACT_APP_WC_API_URL + | |
'/wp-json/wc/v3' + | |
endpoint + | |
urlString, | |
method: method | |
}) | |
return this._request.get(endpoint, { | |
params: { ...params, ...oauth_params } | |
}) | |
} | |
post(endpoint, data_params) { | |
// This is a hack. Problem is WC has some limitations for browser-side OAuth and POST | |
// Problem: OPTIONS preflights are not supported by WC for POST queries with body and headers | |
// Solution: put all parameters into querystring, incl OAuth params and don't set headers | |
// https://github.com/woocommerce/woocommerce/issues/14987#issuecomment-300581467 | |
// https://github.com/woocommerce/woocommerce/issues/15395#issuecomment-305471553 | |
const method = 'POST' | |
const oauth_params = this._getOAuth().authorize({ | |
url: | |
//process.env.REACT_APP_WC_API_URL + | |
'http://localhost:8080' + | |
'/wp-json/wc/v3' + | |
endpoint + | |
WooCommerceAPI._normalizeQueryString(data_params), | |
method: method | |
}) | |
return this._request.post(endpoint, null, { | |
params: oauth_params | |
}) | |
} | |
put(endpoint, data_params) { | |
// This is a hack. Problem is WC has some limitations for browser-side OAuth and PUT | |
// Problem: OPTIONS preflights are not supported by WC for POST queries with body and headers | |
// Solution: WP introduced the _method parameter for GET to describe what should be done on the backend | |
// https://github.com/woocommerce/woocommerce/issues/14987#issuecomment-300581467 | |
const _method = 'PUT' | |
return this.post(endpoint, { ...data_params, _method }) | |
} | |
} | |
export default new WooCommerceAPI( | |
// process.env.REACT_APP_WC_CONSUMER_KEY, | |
// process.env.REACT_APP_WC_CONSUMER_SECRET | |
'ck_305da442a35475f60b32701261c72766e7597e8a', | |
'cs_87f87684c81e6a6df6cc5f4d393c9221047a423a' | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment