173 lines
5.5 KiB
JavaScript
173 lines
5.5 KiB
JavaScript
'use strict';
|
|
|
|
// var debug = require('debug')('pinterest:PinterestHttpClient');
|
|
var Promise = require('bluebird');
|
|
var utils = require('./utils');
|
|
var OPTIONAL_REGEX = /^optional!/;
|
|
var _ = require('lodash');
|
|
|
|
/**
|
|
* Create an API method from the declared spec.
|
|
*
|
|
* @param [spec.method='GET'] Request Method (POST, GET, DELETE, PUT)
|
|
* @param [spec.path=''] Path to be appended to the API BASE_PATH, joined with
|
|
* the instance's path (e.g. 'users' or 'boards')
|
|
* @param [spec.required=[]] Array of required arguments in the order that they
|
|
* must be passed by the consumer of the API. Subsequent optional arguments are
|
|
* optionally passed through a hash (Object) as the penultimate argument
|
|
* (preceding the also-optional callback argument
|
|
* @param [spec.encode] Function for mutating input parameters to a method.
|
|
* Usefully for applying transforms to data on a per-method basis.
|
|
*/
|
|
|
|
module.exports = {
|
|
|
|
pinterestMethod: function (spec) {
|
|
var commandPath = typeof spec.path === 'function' ? spec.path
|
|
: utils.makeURLInterpolator(spec.path || '');
|
|
var requestMethod = (spec.method || 'GET').toUpperCase();
|
|
var urlParams = spec.urlParams || [];
|
|
var encode = spec.encode || function (data) {
|
|
return data;
|
|
};
|
|
return function () {
|
|
var self = this;
|
|
var args = [].slice.call(arguments);
|
|
var callback = typeof args[args.length - 1] === 'function' && args.pop();
|
|
var urlData = this.createUrlData();
|
|
|
|
return this.wrapTimeout(new Promise((function (resolve, reject) {
|
|
for (var i = 0, l = urlParams.length; i < l; ++i) {
|
|
// Note that we shift the args array after every iteration so this just
|
|
// grabs the "next" argument for use as a URL parameter.
|
|
var arg = args[0];
|
|
|
|
var param = urlParams[i];
|
|
|
|
var isOptional = OPTIONAL_REGEX.test(param);
|
|
param = param.replace(OPTIONAL_REGEX, '');
|
|
|
|
if (!arg) {
|
|
if (isOptional) {
|
|
urlData[param] = '';
|
|
continue;
|
|
}
|
|
|
|
return reject(new Error(
|
|
'pinterest: Argument "' + urlParams[i] + '" required, but got: ' + arg +
|
|
' (on API request to ' + requestMethod + ' ' + commandPath + ')'
|
|
));
|
|
}
|
|
|
|
urlData[param] = args.shift();
|
|
}
|
|
|
|
var data = encode(utils.getDataFromArgs(args));
|
|
var opts = utils.getOptionsFromArgs(args);
|
|
|
|
if (args.length) {
|
|
var err = new Error('pinterest: Unknown arguments (' + args + ').');
|
|
return reject(err);
|
|
}
|
|
|
|
|
|
var requestPath = this.createFullPath(commandPath, urlData);
|
|
|
|
function requestCallback(err, response) {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve(
|
|
spec.transformResponseData ?
|
|
spec.transformResponseData(response) :
|
|
response
|
|
);
|
|
}
|
|
}
|
|
|
|
var options = { headers: Object.assign(opts.headers, spec.headers) };
|
|
options.useBody = spec.useBody || false;
|
|
options.authorization = spec.authorization || '';
|
|
options.contentType = spec.contentType || '';
|
|
self._request(requestMethod, requestPath, data, opts.auth, options, requestCallback);
|
|
}).bind(this)), callback);
|
|
};
|
|
},
|
|
|
|
setMetadata: function (id, key, value, auth, cb) {
|
|
var self = this;
|
|
var data = key;
|
|
var isObject = _.isPlainObject(key);
|
|
// We assume null for an empty object
|
|
var isNull = data === null || (isObject && !Object.keys(data).length);
|
|
|
|
// Allow optional passing of auth & cb:
|
|
if ((isNull || isObject) && typeof value === 'string') {
|
|
auth = value;
|
|
} else if (typeof auth !== 'string') {
|
|
if (!cb && typeof auth === 'function') {
|
|
cb = auth;
|
|
}
|
|
auth = null;
|
|
}
|
|
|
|
var urlData = this.createUrlData();
|
|
var path = this.createFullPath('/' + id, urlData);
|
|
|
|
return this.wrapTimeout(new Promise((function (resolve, reject) {
|
|
if (isNull) {
|
|
// Reset metadata:
|
|
sendMetadata(null, auth);
|
|
} else if (!isObject) {
|
|
// Set individual metadata property:
|
|
var metadata = {};
|
|
metadata[key] = value;
|
|
sendMetadata(metadata, auth);
|
|
} else {
|
|
// Set entire metadata object after resetting it:
|
|
this._request('POST', path, {
|
|
metadata: null
|
|
}, auth, {}, function (err) {
|
|
if (err) {
|
|
return reject(err);
|
|
}
|
|
sendMetadata(data, auth);
|
|
});
|
|
}
|
|
|
|
function sendMetadata(metadata, auth) {
|
|
self._request('POST', path, {
|
|
metadata: metadata
|
|
}, auth, {}, function (err, response) {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve(response.metadata);
|
|
}
|
|
});
|
|
}
|
|
}).bind(this)), cb);
|
|
},
|
|
|
|
getMetadata: function (id, auth, cb) {
|
|
if (!cb && typeof auth === 'function') {
|
|
cb = auth;
|
|
auth = null;
|
|
}
|
|
|
|
var urlData = this.createUrlData();
|
|
var path = this.createFullPath('/' + id, urlData);
|
|
|
|
return this.wrapTimeout(new Promise((function (resolve, reject) {
|
|
this._request('GET', path, {}, auth, {}, function (err, response) {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve(response.metadata);
|
|
}
|
|
});
|
|
}).bind(this)), cb);
|
|
}
|
|
|
|
};
|