datocms-client
Version:
For new DatoCMS users, we recommend @datocms/cma-client-node
354 lines (274 loc) • 18.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = generateClient;
exports.isClient = void 0;
var _jsonSchemaRefParser = _interopRequireDefault(require("json-schema-ref-parser"));
var _pluralize = require("pluralize");
var _humps = require("humps");
var _object = _interopRequireDefault(require("object.omit"));
var _fetch = _interopRequireDefault(require("./fetch"));
var _deserializeJsonApi = _interopRequireDefault(require("./deserializeJsonApi"));
var _serializeJsonApi = _interopRequireDefault(require("./serializeJsonApi"));
var _Client = _interopRequireDefault(require("../Client"));
var _fetchAllPages = _interopRequireDefault(require("./fetchAllPages"));
var _ApiException = _interopRequireDefault(require("../ApiException"));
var _InvalidApiRequestException = _interopRequireDefault(require("../InvalidApiRequestException"));
var _wait = _interopRequireDefault(require("./wait"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var identityRegexp = /\{\(.*?definitions%2F(.*?)%2Fdefinitions%2Fidentity\)}/g;
var pluralResources = ['ssoSettings', 'whiteLabelSettings'];
var getProps = function getProps(obj) {
return Object.getOwnPropertyNames(obj).concat(Object.getPrototypeOf(obj) !== Object.prototype && Object.getOwnPropertyNames(Object.getPrototypeOf(obj))).filter(function (p) {
return p !== 'constructor';
});
};
var toMap = function toMap(keys) {
return keys.reduce(function (acc, prop) {
return Object.assign(acc, _defineProperty({}, prop, true));
}, {});
};
var findLinkFor = function findLinkFor(schema, namespace, apiCall) {
var sub = schema.properties[namespace];
if (!sub) {
throw new TypeError("".concat(namespace, " is not a valid namespace"));
}
var methodNames = {
instances: 'all',
self: 'find'
};
var link = sub.links.find(function (l) {
return (methodNames[l.rel] || (0, _humps.camelize)(l.rel)) === apiCall;
});
if (!link) {
throw new TypeError("".concat(namespace, ".").concat(apiCall, " is not a valid API method"));
}
return link;
};
var isClient = function isClient(object) {
return object && object.rawClient && object.rawClient.token;
};
exports.isClient = isClient;
function generateClient(subdomain, cache) {
var extraMethods = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
return function Client(token, rawLegacyHeadersArgOrOptions, legacyBaseUrlArg) {
var schemaPromise;
var legacyHeadersArgOrOptions = rawLegacyHeadersArgOrOptions || {};
var validOptions = ['environment', 'baseUrl', 'headers', 'logApiCalls'];
var headers = _objectSpread(_objectSpread({}, (0, _object["default"])(legacyHeadersArgOrOptions, validOptions)), legacyHeadersArgOrOptions.headers || {});
if (legacyHeadersArgOrOptions.environment) {
headers['x-environment'] = legacyHeadersArgOrOptions.environment;
}
var globalOptions = legacyHeadersArgOrOptions;
var baseUrl = legacyBaseUrlArg || legacyHeadersArgOrOptions.baseUrl || "https://".concat(subdomain, ".datocms.com");
var rawClient = new _Client["default"](token, headers, baseUrl);
var extraProps = getProps(extraMethods);
var rawClientProps = getProps(rawClient);
Object.assign(cache, {
rawClient: true
}, toMap(extraProps), toMap(rawClientProps));
var client = new Proxy(cache, {
get: function get(obj1, namespace) {
var preCallStack = new Error().stack;
if (namespace === 'rawClient') {
return rawClient;
}
if (rawClientProps.includes(namespace)) {
return typeof rawClient[namespace] === 'function' ? rawClient[namespace].bind(rawClient) : rawClient[namespace];
}
if (extraProps.includes(namespace)) {
return typeof extraMethods[namespace] === 'function' ? extraMethods[namespace].bind(client, client) : extraMethods[namespace];
}
return new Proxy(cache[namespace] || {}, {
get: function get(obj2, apiCall) {
return function call() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
if (!schemaPromise) {
schemaPromise = (0, _fetch["default"])("https://".concat(subdomain, ".datocms.com/docs/").concat(subdomain, "-hyperschema.json")).then(function (res) {
return res.json();
}).then(function (schema) {
return _jsonSchemaRefParser["default"].dereference(schema);
});
}
return schemaPromise.then( /*#__PURE__*/function () {
var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(schema) {
var singularized, resourceName, link, lastUrlId, url, body, queryString, options, deserializeResponse, deserialize, serializeRequest, _fetchRequest, _fetchRequest2, _fetchRequest3, allPages, perPage, request, fetchRequest;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
singularized = pluralResources.includes(namespace) ? namespace : (0, _pluralize.singular)(namespace);
resourceName = (0, _humps.decamelize)(singularized);
link = findLinkFor(schema, resourceName, apiCall);
url = link.href.replace(identityRegexp, function () {
lastUrlId = args.shift();
return lastUrlId;
});
body = {};
if (link.schema && (link.method === 'PUT' || link.method === 'POST')) {
body = args.shift() || {};
}
queryString = args.shift() || {};
queryString = Object.entries(queryString).reduce(function (acc, _ref2) {
var _ref3 = _slicedToArray(_ref2, 2),
key = _ref3[0],
value = _ref3[1];
acc[(0, _humps.decamelize)(key)] = value;
return acc;
}, {});
options = _objectSpread(_objectSpread({}, globalOptions), args.shift() || {});
deserializeResponse = Object.prototype.hasOwnProperty.call(options, 'deserializeResponse') ? options.deserializeResponse : true;
deserialize = /*#__PURE__*/function () {
var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(fetchRequest, response) {
var jobResult, retryCount;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(response && response.data.type === 'job')) {
_context.next = 19;
break;
}
retryCount = 0;
case 2:
_context.prev = 2;
retryCount += 1;
_context.next = 6;
return (0, _wait["default"])(retryCount * 1000);
case 6:
_context.next = 8;
return client.jobResult.find(response.data.id, {}, {
deserializeResponse: false
});
case 8:
jobResult = _context.sent.data;
_context.next = 15;
break;
case 11:
_context.prev = 11;
_context.t0 = _context["catch"](2);
if (!(!(_context.t0 instanceof _ApiException["default"]) || _context.t0.statusCode !== 404)) {
_context.next = 15;
break;
}
throw _context.t0;
case 15:
if (!jobResult) {
_context.next = 2;
break;
}
case 16:
if (!(jobResult.attributes.status < 200 || jobResult.attributes.status >= 300)) {
_context.next = 18;
break;
}
throw new _ApiException["default"]({
status: jobResult.attributes.status,
statusText: jobResult.attributes.statusText
}, jobResult.attributes.payload, _objectSpread(_objectSpread({}, fetchRequest), {}, {
preCallStack: preCallStack
}));
case 18:
return _context.abrupt("return", deserializeResponse ? (0, _deserializeJsonApi["default"])(link.jobSchema, jobResult.attributes.payload) : jobResult.attributes.payload);
case 19:
return _context.abrupt("return", deserializeResponse ? (0, _deserializeJsonApi["default"])(link.targetSchema, response) : response);
case 20:
case "end":
return _context.stop();
}
}
}, _callee, null, [[2, 11]]);
}));
return function deserialize(_x2, _x3) {
return _ref4.apply(this, arguments);
};
}();
serializeRequest = Object.prototype.hasOwnProperty.call(options, 'serializeRequest') ? options.serializeRequest : true;
if (!(link.schema && (link.method === 'PUT' || link.method === 'POST') && serializeRequest)) {
_context2.next = 20;
break;
}
_context2.prev = 13;
body = (0, _serializeJsonApi["default"])(body, link, link.method === 'PUT' && lastUrlId);
_context2.next = 20;
break;
case 17:
_context2.prev = 17;
_context2.t0 = _context2["catch"](13);
throw new _InvalidApiRequestException["default"](_context2.t0.message, preCallStack);
case 20:
if (!(link.method === 'POST')) {
_context2.next = 23;
break;
}
_fetchRequest = rawClient.buildPostRequest(url, body, queryString, options);
return _context2.abrupt("return", rawClient.request(_fetchRequest, preCallStack).then(function (response) {
return deserialize(_fetchRequest, response);
}));
case 23:
if (!(link.method === 'PUT')) {
_context2.next = 26;
break;
}
_fetchRequest2 = rawClient.buildPutRequest(url, body, queryString, options);
return _context2.abrupt("return", rawClient.request(_fetchRequest2, preCallStack).then(function (response) {
return deserialize(_fetchRequest2, response);
}));
case 26:
if (!(link.method === 'DELETE')) {
_context2.next = 29;
break;
}
_fetchRequest3 = rawClient.buildDeleteRequest(url, queryString, options);
return _context2.abrupt("return", rawClient.request(_fetchRequest3, preCallStack).then(function (response) {
return deserialize(_fetchRequest3, response);
}));
case 29:
allPages = Object.prototype.hasOwnProperty.call(options, 'allPages') ? options.allPages : false;
if (!allPages) {
_context2.next = 34;
break;
}
perPage = allPages === true ? undefined : allPages;
request = (0, _fetchAllPages["default"])(rawClient, url, queryString, perPage, options);
return _context2.abrupt("return", request.then(function (response) {
return deserialize(null, response);
}));
case 34:
fetchRequest = rawClient.buildGetRequest(url, queryString, options);
return _context2.abrupt("return", rawClient.request(fetchRequest, preCallStack).then(function (response) {
return deserialize(fetchRequest, response);
}));
case 36:
case "end":
return _context2.stop();
}
}
}, _callee2, null, [[13, 17]]);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}());
};
}
});
}
});
return client;
};
}