UNPKG

rest-client-sdk

Version:
1,300 lines (1,250 loc) 93.2 kB
import URI from 'urijs'; import diff from 'deep-diff'; function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); } function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _classPrivateFieldGet2(s, a) { return s.get(_assertClassBrand(s, a)); } function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); } function _classPrivateFieldSet2(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; } function _construct(t, e, r) { if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); var o = [null]; o.push.apply(o, e); var p = new (t.bind.apply(t, o))(); return r && _setPrototypeOf(p, r.prototype), p; } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), Object.defineProperty(e, "prototype", { writable: false }), e; } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) { t && (r = t); var n = 0, F = function () {}; return { s: F, n: function () { return n >= r.length ? { done: true } : { done: false, value: r[n++] }; }, e: function (r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = true, u = false; return { s: function () { t = t.call(r); }, n: function () { var r = t.next(); return a = r.done, r; }, e: function (r) { u = true, o = r; }, f: function () { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e; } function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: true, configurable: true } }), Object.defineProperty(t, "prototype", { writable: false }), e && _setPrototypeOf(t, e); } function _isNativeFunction(t) { try { return -1 !== Function.toString.call(t).indexOf("[native code]"); } catch (n) { return "function" == typeof t; } } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; } function _possibleConstructorReturn(t, e) { if (e && ("object" == typeof e || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); } function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _wrapNativeSuper(t) { var r = "function" == typeof Map ? new Map() : void 0; return _wrapNativeSuper = function (t) { if (null === t || !_isNativeFunction(t)) return t; if ("function" != typeof t) throw new TypeError("Super expression must either be null or a function"); if (void 0 !== r) { if (r.has(t)) return r.get(t); r.set(t, Wrapper); } function Wrapper() { return _construct(t, arguments, _getPrototypeOf(this).constructor); } return Wrapper.prototype = Object.create(t.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }), _setPrototypeOf(Wrapper, t); }, _wrapNativeSuper(t); } /** * It's a bit tricky to extends native errors * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error */ var HttpError = /*#__PURE__*/function (_Error) { function HttpError(message, baseResponse) { var _this; _classCallCheck(this, HttpError); _this = _callSuper(this, HttpError, [message || 'Http errort']); // Set the prototype explicitly. _defineProperty(_this, "baseResponse", void 0); Object.setPrototypeOf(_this, OauthError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_this, OauthError); } _this.name = 'HttpError'; _this.baseResponse = baseResponse; return _this; } /** * Get the JSON of the baseResponse directly, if possible */ _inherits(HttpError, _Error); return _createClass(HttpError, [{ key: "responseJson", value: function responseJson() { return this.baseResponse.json(); } }]); }(/*#__PURE__*/_wrapNativeSuper(Error)); var OauthError = /*#__PURE__*/function (_Error2) { function OauthError(message, previousError) { var _this2; _classCallCheck(this, OauthError); _this2 = _callSuper(this, OauthError, [message || 'Oauth error']); // Set the prototype explicitly. _defineProperty(_this2, "previousError", void 0); Object.setPrototypeOf(_this2, OauthError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_this2, OauthError); } _this2.name = 'OauthError'; _this2.previousError = previousError; return _this2; } _inherits(OauthError, _Error2); return _createClass(OauthError); }(/*#__PURE__*/_wrapNativeSuper(Error)); var InvalidGrantError = /*#__PURE__*/function (_OauthError2) { function InvalidGrantError(message, previousError) { var _this3; _classCallCheck(this, InvalidGrantError); _this3 = _callSuper(this, InvalidGrantError, [message || 'Invalid grant error', previousError]); // Set the prototype explicitly. _defineProperty(_this3, "previousError", void 0); Object.setPrototypeOf(_this3, InvalidGrantError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_this3, InvalidGrantError); } _this3.name = 'InvalidGrantError'; _this3.previousError = previousError; return _this3; } _inherits(InvalidGrantError, _OauthError2); return _createClass(InvalidGrantError); }(OauthError); var InvalidScopeError = /*#__PURE__*/function (_OauthError3) { function InvalidScopeError(message, previousError) { var _this4; _classCallCheck(this, InvalidScopeError); _this4 = _callSuper(this, InvalidScopeError, [message || 'Invalid scope error', previousError]); // Set the prototype explicitly. _defineProperty(_this4, "previousError", void 0); Object.setPrototypeOf(_this4, InvalidScopeError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_this4, InvalidScopeError); } _this4.name = 'InvalidScopeError'; _this4.previousError = previousError; return _this4; } _inherits(InvalidScopeError, _OauthError3); return _createClass(InvalidScopeError); }(OauthError); // 400 var BadRequestError = /*#__PURE__*/function (_HttpError2) { function BadRequestError(message, baseResponse) { var _this5; _classCallCheck(this, BadRequestError); _this5 = _callSuper(this, BadRequestError, [message || 'Bad request', baseResponse]); // Set the prototype explicitly. _defineProperty(_this5, "baseResponse", void 0); Object.setPrototypeOf(_this5, BadRequestError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_this5, BadRequestError); } _this5.name = 'BadRequestError'; _this5.baseResponse = baseResponse; return _this5; } _inherits(BadRequestError, _HttpError2); return _createClass(BadRequestError); }(HttpError); // 401 var UnauthorizedError = /*#__PURE__*/function (_BadRequestError2) { function UnauthorizedError(message, baseResponse) { var _this6; _classCallCheck(this, UnauthorizedError); _this6 = _callSuper(this, UnauthorizedError, [message || 'Unauthorized', baseResponse]); // Set the prototype explicitly. _defineProperty(_this6, "baseResponse", void 0); Object.setPrototypeOf(_this6, UnauthorizedError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_this6, UnauthorizedError); } _this6.name = 'UnauthorizedError'; _this6.baseResponse = baseResponse; return _this6; } _inherits(UnauthorizedError, _BadRequestError2); return _createClass(UnauthorizedError); }(BadRequestError); // 403 var ForbiddenError = /*#__PURE__*/function (_BadRequestError3) { function ForbiddenError(message, baseResponse) { var _this7; _classCallCheck(this, ForbiddenError); _this7 = _callSuper(this, ForbiddenError, [message || 'Forbidden', baseResponse]); // Set the prototype explicitly. _defineProperty(_this7, "baseResponse", void 0); Object.setPrototypeOf(_this7, ForbiddenError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_this7, ForbiddenError); } _this7.name = 'ForbiddenError'; _this7.baseResponse = baseResponse; return _this7; } _inherits(ForbiddenError, _BadRequestError3); return _createClass(ForbiddenError); }(BadRequestError); // 404 var ResourceNotFoundError = /*#__PURE__*/function (_BadRequestError4) { function ResourceNotFoundError(message, baseResponse) { var _this8; _classCallCheck(this, ResourceNotFoundError); _this8 = _callSuper(this, ResourceNotFoundError, [message || 'Resource is not found', baseResponse]); // Set the prototype explicitly. _defineProperty(_this8, "baseResponse", void 0); Object.setPrototypeOf(_this8, ResourceNotFoundError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_this8, ResourceNotFoundError); } _this8.name = 'ResourceNotFoundError'; _this8.baseResponse = baseResponse; return _this8; } _inherits(ResourceNotFoundError, _BadRequestError4); return _createClass(ResourceNotFoundError); }(BadRequestError); // 409 var ConflictError = /*#__PURE__*/function (_BadRequestError5) { function ConflictError(message, baseResponse) { var _this9; _classCallCheck(this, ConflictError); _this9 = _callSuper(this, ConflictError, [message || 'Conflict detected', baseResponse]); // Set the prototype explicitly. _defineProperty(_this9, "baseResponse", void 0); Object.setPrototypeOf(_this9, ConflictError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_this9, ConflictError); } _this9.name = 'ConflictError'; _this9.baseResponse = baseResponse; return _this9; } _inherits(ConflictError, _BadRequestError5); return _createClass(ConflictError); }(BadRequestError); // 500 var InternalServerError = /*#__PURE__*/function (_HttpError3) { function InternalServerError(message, baseResponse) { var _this0; _classCallCheck(this, InternalServerError); _this0 = _callSuper(this, InternalServerError, [message || 'Internal server error', baseResponse]); // Set the prototype explicitly. _defineProperty(_this0, "baseResponse", void 0); Object.setPrototypeOf(_this0, InternalServerError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_this0, InternalServerError); } _this0.name = 'InternalServerError'; _this0.baseResponse = baseResponse; return _this0; } _inherits(InternalServerError, _HttpError3); return _createClass(InternalServerError); }(HttpError); /** * @returns {HttpError} */ function getHttpErrorFromResponse(originalResponse) { var response = originalResponse.clone(); switch (true) { case response.status === 401: return new UnauthorizedError(null, response); case response.status === 403: return new ForbiddenError(null, response); case response.status === 404: return new ResourceNotFoundError(null, response); case response.status === 409: return new ConflictError(null, response); case response.status >= 400 && response.status < 500: return new BadRequestError(null, response); case response.status >= 500 && response.status < 600: return new InternalServerError(null, response); default: return new HttpError(null, response); } } function isOauthError(body) { return typeof (body === null || body === void 0 ? void 0 : body.error) === 'string'; } var DEFAULT_CONFIG = { collectionKey: 'hydra:member' }; var _config = /*#__PURE__*/new WeakMap(); var _classMetadataList = /*#__PURE__*/new WeakMap(); var Mapping = /*#__PURE__*/function () { function Mapping() { var idPrefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; _classCallCheck(this, Mapping); _defineProperty(this, "idPrefix", void 0); _classPrivateFieldInitSpec(this, _config, void 0); _classPrivateFieldInitSpec(this, _classMetadataList, void 0); this.idPrefix = idPrefix; _classPrivateFieldSet2(_classMetadataList, this, []); this.setConfig(config); } return _createClass(Mapping, [{ key: "getConfig", value: function getConfig() { return _classPrivateFieldGet2(_config, this); } }, { key: "setConfig", value: function setConfig(config) { _classPrivateFieldSet2(_config, this, _objectSpread2(_objectSpread2({}, DEFAULT_CONFIG), config)); } }, { key: "setMapping", value: function setMapping() { var classMetadataList = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; _classPrivateFieldSet2(_classMetadataList, this, classMetadataList); } }, { key: "getMappingKeys", value: function getMappingKeys() { return _classPrivateFieldGet2(_classMetadataList, this).map(function (classMetadata) { return classMetadata.key; }); } }, { key: "getClassMetadataByKey", value: function getClassMetadataByKey(key) { var filterList = _classPrivateFieldGet2(_classMetadataList, this).filter(function (classMetadata) { return classMetadata.key === key; }); return filterList.length > 0 ? filterList[0] : null; } }, { key: "isMappingValid", value: function isMappingValid() { var _this = this; return !_classPrivateFieldGet2(_classMetadataList, this).some(function (classMetadata) { // check that the relations exists var errorList = Object.values(classMetadata.getAttributeList()).map(function (attribute) { var relation = classMetadata.getRelation(attribute.serializedKey); if (!relation) { // attribute can not be "invalid" (for now ?) return false; } var relationMetadata = _this.getClassMetadataByKey(relation.targetMetadataKey); // relation name seems weird if (relation.isRelationToOne() && attribute.attributeName.endsWith('List')) { return "\"".concat(classMetadata.key, ".").concat(attribute.serializedKey, " is defined as a MANY_TO_ONE relation, but the attribute name ends with \"List\"."); } if (relation.isRelationToMany()) { var message = "\"".concat(classMetadata.key, ".").concat(attribute.serializedKey, " is defined as a ").concat(relation.type, " relation, but the attribute name is nor plural not ends with \"List\"."); var endsWithList = attribute.attributeName.endsWith('List'); try { // eslint-disable-next-line @typescript-eslint/no-require-imports var pluralize = require('pluralize'); if (!endsWithList && !pluralize.isPlural(attribute.attributeName)) { return message; } } catch (_unused) { if (!endsWithList) { return "".concat(message, ".\nIf your keys does not ends with \"List\", then you should install the \"pluralize\" package."); } } } // no error if there is metadata linked if (!relationMetadata) { return "\"".concat(classMetadata.key, ".").concat(attribute.serializedKey, "\" defined a relation to the metadata named \"").concat(relation.targetMetadataKey, "\" but this metadata is not knowned by the mapping"); } return false; }); if (!classMetadata.hasIdentifierAttribute()) { errorList.push("\"".concat(classMetadata.key, "\" has no identifier attribute set")); } var nbError = errorList.filter(function (error) { if (error) { console.warn(error); } return error; }); return nbError.length > 0; }); } }]); }(); var Attribute = /*#__PURE__*/_createClass( /** * @param {string} serializedKey the key returned from your API * @param {null|string} attributeName the name in your entity, default to the `serializedKey` attribute * @param {string} type type of the attribute * @param {boolean} isIdentifier is this attribute the entity identifier */ function Attribute(serializedKey) { var attributeName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'string'; var isIdentifier = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; _classCallCheck(this, Attribute); _defineProperty(this, "serializedKey", void 0); _defineProperty(this, "attributeName", void 0); _defineProperty(this, "type", void 0); _defineProperty(this, "isIdentifier", void 0); if (!serializedKey) { throw new TypeError('`serializedKey` must not be empty'); } this.serializedKey = serializedKey; this.attributeName = attributeName || this.serializedKey; this.type = type; this.isIdentifier = isIdentifier; }); function generateRepository(sdk, metadata) { var isUnitOfWorkEnabled = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; // eslint-disable-next-line new-cap return new metadata.repositoryClass(sdk, metadata, isUnitOfWorkEnabled); } function removeAuthorization(headers) { if (!headers) { return; } if (headers instanceof Headers) { headers["delete"]('Authorization'); return headers; } var filterAuthorization = function filterAuthorization(entries) { return entries.filter(function (header) { return header[0] !== 'Authorization'; }); }; if (Array.isArray(headers)) { return filterAuthorization(headers); } return Object.fromEntries(filterAuthorization(Object.entries(headers))); } /** * remove undefined key, usefull to remove Content-Type for example. * Does not apply on "Headers" instance as values are string in there. */ function removeUndefinedHeaders(headers) { if (headers instanceof Headers) { return headers; } var filterEntries = function filterEntries(entries) { return entries.filter(function (header) { return header[1] !== undefined; }); }; if (Array.isArray(headers)) { return filterEntries(headers); } return Object.fromEntries(filterEntries(Object.entries(headers))); } function convertToRecord(headers) { if (headers instanceof Headers) { return Object.fromEntries(headers.entries()); } if (Array.isArray(headers)) { return Object.fromEntries(headers); } return headers; } var _excluded = ["headers"]; var EXPIRE_LIMIT_SECONDS = 300; // = 5 minutes var _tokenStorage = /*#__PURE__*/new WeakMap(); var _isUnitOfWorkEnabled = /*#__PURE__*/new WeakMap(); var AbstractClient = /*#__PURE__*/function () { function AbstractClient(sdk, metadata) { var isUnitOfWorkEnabled = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; _classCallCheck(this, AbstractClient); _defineProperty(this, "sdk", void 0); _classPrivateFieldInitSpec(this, _tokenStorage, void 0); _defineProperty(this, "serializer", void 0); _defineProperty(this, "metadata", void 0); _classPrivateFieldInitSpec(this, _isUnitOfWorkEnabled, void 0); this.sdk = sdk; _classPrivateFieldSet2(_tokenStorage, this, sdk.tokenStorage); this.serializer = sdk.serializer; this.metadata = metadata; _classPrivateFieldSet2(_isUnitOfWorkEnabled, this, isUnitOfWorkEnabled); } return _createClass(AbstractClient, [{ key: "withUnitOfWork", value: function withUnitOfWork(enabled) { return generateRepository(this.sdk, this.metadata, enabled); } }, { key: "getDefaultParameters", value: function getDefaultParameters() { return {}; } // eslint-disable-next-line @typescript-eslint/no-unused-vars }, { key: "getPathBase", value: function getPathBase(pathParameters) { return "/".concat(this.metadata.pathRoot); } }, { key: "getEntityURI", value: function getEntityURI(entity) { var idValue = this._getEntityIdentifier(entity); if (idValue === null) { throw new Error('Cannot call `getEntityURI for entity without id.`'); } if (typeof idValue === 'number') { if (Number.isFinite(idValue)) { idValue = idValue.toString(); } else { throw new Error('Unable to handle non-finite number'); } } var pathBase = this.getPathBase({}); if (idValue.indexOf(pathBase) > -1) { return idValue; } return "".concat(pathBase, "/").concat(idValue); } /** * get an entity by its id * * @param {string|number} id the entity identifier * @param {Record<string, unknown>} queryParam query parameters that will be added to the request * @param {Record<string, unknown>} pathParameters path parameters, will be pass to the `getPathBase` method * @param {Record<string, unknown>} requestParams parameters that will be send as second parameter to the `fetch` call */ }, { key: "find", value: function find(id) { var queryParam = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var pathParameters = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var requestParams = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var url = this._generateUrlFromParams(queryParam, pathParameters, id); return this.deserializeResponse(this.authorizedFetch(url, requestParams), 'item'); } /** * get a list of entities by some parameters * * @param {Record<string, unknown>} queryParam query parameters that will be added to the request * @param {Record<string, unknown>} pathParameters path parameters, will be pass to the `getPathBase` method * @param {Record<string, unknown>} requestParams parameters that will be send as second parameter to the `fetch` call */ }, { key: "findBy", value: function findBy(queryParam) { var pathParameters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var requestParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var url = this._generateUrlFromParams(queryParam, pathParameters); return this.deserializeResponse(this.authorizedFetch(url, requestParams), 'list'); } /** * get a list of all entities * * @param {Record<string, unknown>} queryParam query parameters that will be added to the request * @param {Record<string, unknown>} pathParameters path parameters, will be pass to the `getPathBase` method * @param {Record<string, unknown>} requestParams parameters that will be send as second parameter to the `fetch` call */ }, { key: "findAll", value: function findAll() { var queryParam = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var pathParameters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var requestParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return this.findBy(queryParam, pathParameters, requestParams); } /** * create an entity * * @param {Record<string, unknown>} entity the entity to persist * @param {Record<string, unknown>} queryParam query parameters that will be added to the request * @param {Record<string, unknown>} pathParameters path parameters, will be pass to the `getPathBase` method * @param {Record<string, unknown>} requestParams parameters that will be send as second parameter to the `fetch` call */ }, { key: "create", value: function create(entity) { var queryParam = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var pathParameters = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var requestParams = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var url = new URI(this.getPathBase(pathParameters)); url.addSearch(queryParam); var oldSerializedModel = this.metadata.getDefaultSerializedModel(); var newSerializedModel = this.serializer.normalizeItem(entity, this.metadata); var diff = this.sdk.unitOfWork.getDirtyData(newSerializedModel, oldSerializedModel, this.metadata); return this.deserializeResponse(this.authorizedFetch(url, _objectSpread2({ method: 'POST', body: this.serializer.encodeItem(diff, this.metadata) }, requestParams)), 'item'); } /** * update an entity * * @param {Record<string, unknown>} entity the entity to update * @param {Record<string, unknown>} queryParam query parameters that will be added to the request * @param {Record<string, unknown>} requestParams parameters that will be send as second parameter to the `fetch` call */ }, { key: "update", value: function update(entity) { var queryParam = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var requestParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return this._update('PUT', entity, queryParam, requestParams); } /** * partially update an entity using the `PATCH` HTTP verb * * @param {Record<string, unknown>} entity the entity to update * @param {Record<string, unknown>} queryParam query parameters that will be added to the request * @param {Record<string, unknown>} requestParams parameters that will be send as second parameter to the `fetch` call */ }, { key: "patch", value: function patch(entity) { var queryParam = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var requestParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return this._update('PATCH', entity, queryParam, requestParams); } }, { key: "_update", value: function _update(method, entity) { var queryParam = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var requestParams = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var url = new URI(this.getEntityURI(entity)); url.addSearch(queryParam); var newSerializedModel = this.serializer.normalizeItem(entity, this.metadata); var identifier = this._getEntityIdentifier(newSerializedModel); var oldModel; if (identifier !== null) { oldModel = this.sdk.unitOfWork.getDirtyEntity(identifier); } if (oldModel) { newSerializedModel = this.sdk.unitOfWork.getDirtyData(newSerializedModel, oldModel, this.metadata); } return this.deserializeResponse(this.authorizedFetch(url, _objectSpread2({ method: method, body: this.serializer.encodeItem(newSerializedModel, this.metadata) }, requestParams)), 'item'); } /** * delete an entity * * @param {Record<string, unknown>} the entity to delete * @param {Record<string, unknown>} requestParams parameters that will be send as second parameter to the `fetch` call */ }, { key: "delete", value: function _delete(entity) { var _this = this; var requestParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var url = this.getEntityURI(entity); var identifier = this._getEntityIdentifier(entity); return this.authorizedFetch(url, _objectSpread2({ method: 'DELETE' }, requestParams)).then(function (response) { if (identifier !== null) { _this.sdk.unitOfWork.clear(identifier); } return response; }); } }, { key: "deserializeResponse", value: function deserializeResponse(requestPromise, listOrItem) { var _this2 = this; return requestPromise.then(function (response) { return response.text().then(function (text) { return { response: response, text: text }; }); }).then(function (_ref) { var response = _ref.response, text = _ref.text; if (listOrItem === 'list') { // for list, we need to deserialize the result to get an object var itemList = _this2.serializer.deserializeList(text, _this2.metadata, response); if (_classPrivateFieldGet2(_isUnitOfWorkEnabled, _this2)) { var _iterator = _createForOfIteratorHelper(itemList), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var _decodedItem = _step.value; var _identifier = _this2._getEntityIdentifier(_decodedItem); var normalizedItem = _this2.serializer.normalizeItem(_decodedItem, _this2.metadata); // then we register the re-normalized item if (_identifier !== null) { _this2.sdk.unitOfWork.registerClean(_identifier, normalizedItem); } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } } return itemList; } // for items, we can just decode the item (ie. transform it to JS object) var decodedItem = _this2.serializer.decodeItem(text, _this2.metadata, response); // and register it directy without deserializing + renormalizing var identifier = _this2._getEntityIdentifier(decodedItem); // and finally return the denormalized item var item = _this2.serializer.denormalizeItem(decodedItem, _this2.metadata, response); if (_classPrivateFieldGet2(_isUnitOfWorkEnabled, _this2) && identifier !== null) { _this2.sdk.unitOfWork.registerClean(identifier, _this2.serializer.normalizeItem(item, _this2.metadata)); } return item; }); } }, { key: "makeUri", value: function makeUri(input) { var url = input instanceof URI ? input : new URI(input); url.host(this.sdk.config.path).scheme(this.sdk.config.scheme); if (this.sdk.config.port) { url.port(String(this.sdk.config.port)); } if (this.sdk.mapping.idPrefix) { var segments = url.segment(); if (!url.pathname().startsWith(this.sdk.mapping.idPrefix)) { segments.unshift(this.sdk.mapping.idPrefix); url.segment(segments); } } return url; } }, { key: "authorizedFetch", value: function authorizedFetch(input) { var requestParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var url = this.makeUri(input); return this._fetchWithToken(url.toString(), requestParams); } }, { key: "_generateUrlFromParams", value: function _generateUrlFromParams(queryParam) { var pathParameters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var id = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var params = queryParam; if (this.sdk.config.useDefaultParameters) { Object.assign(params, this.getDefaultParameters()); } var pathBase = this.getPathBase(pathParameters); var url; if (id) { var testPathBase = this.sdk.mapping.idPrefix ? "".concat(this.sdk.mapping.idPrefix).concat(pathBase) : pathBase; if (typeof id === 'string' && id.startsWith(testPathBase)) { url = new URI(id); } else { url = new URI("".concat(pathBase, "/").concat(id)); } } else { url = new URI(pathBase); } if (params) { url.addSearch(params); } return url; } }, { key: "_fetchWithToken", value: function _fetchWithToken(input) { var _this3 = this; var requestParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!input) { throw new Error('input is empty'); } if (_classPrivateFieldGet2(_tokenStorage, this)) { return _classPrivateFieldGet2(_tokenStorage, this).getCurrentTokenExpiresIn().then(function (accessTokenExpiresIn) { if (accessTokenExpiresIn !== null && accessTokenExpiresIn <= EXPIRE_LIMIT_SECONDS) { return _classPrivateFieldGet2(_tokenStorage, _this3).refreshToken().then(function (refreshedTokenObject) { return refreshedTokenObject.access_token; })["catch"](function (e) { _this3._handleRefreshTokenFailure(e); throw e; }); } return _classPrivateFieldGet2(_tokenStorage, _this3).getAccessToken(); }).then(function (token) { return _this3._doFetch(token, input, requestParams); }); } return this._doFetch(null, input, requestParams); } }, { key: "_refreshTokenAndRefetch", value: function _refreshTokenAndRefetch(input) { var _this4 = this; var requestParams = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return _classPrivateFieldGet2(_tokenStorage, this).refreshToken().then(function () { // eslint-disable-next-line prefer-const var headers = requestParams.headers, rest = _objectWithoutProperties(requestParams, _excluded); var updatedRequestParams = _objectSpread2(_objectSpread2({}, rest), {}, { headers: removeAuthorization(headers) }); return _this4._fetchWithToken(input, updatedRequestParams); })["catch"](function (e) { _this4._handleRefreshTokenFailure(e); throw e; }); } }, { key: "_manageUnauthorized", value: function _manageUnauthorized(response, input) { var _this5 = this; var requestParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var error = getHttpErrorFromResponse(response); // https://tools.ietf.org/html/rfc2617#section-1.2 var authorizationHeader = response.headers.get('www-authenticate'); if (authorizationHeader) { var invalidGrant = authorizationHeader.indexOf('error="invalid_grant"') > -1; if (invalidGrant && _classPrivateFieldGet2(_tokenStorage, this)) { return this._refreshTokenAndRefetch(input, requestParams); } throw error; } else { // if www-authenticate header is missing, try and read json response return response.json().then(function (body) { if (_classPrivateFieldGet2(_tokenStorage, _this5) && (body.error === 'invalid_scope' || body.error === 'access_denied')) { return _this5._refreshTokenAndRefetch(input, requestParams); } throw error; })["catch"](function (err) { if (err instanceof OauthError) { throw err; } throw error; }); } } }, { key: "_doFetch", value: function _doFetch(accessToken, input, requestParams) { var _this6 = this; var params = requestParams; var baseHeaders = {}; if (params.method !== 'GET' || params.method !== 'GET' && params.method !== 'DELETE') { baseHeaders = { 'Content-Type': 'application/json' }; } if (accessToken) { baseHeaders.Authorization = "".concat(this.sdk.config.authorizationType, " ").concat(accessToken); } if (params) { if (!params.headers) { params.headers = {}; } params.headers = Object.assign(baseHeaders, params.headers); } else { params = { headers: baseHeaders }; } if (params.headers) { params.headers = removeUndefinedHeaders(params.headers); } var logId; if (this.sdk.logger) { logId = this.sdk.logger.logRequest(_objectSpread2({ url: input }, params)); } return fetch(input, params).then(function (response) { if (_this6.sdk.logger) { _this6.sdk.logger.logResponse(response, logId); } if (response.status < 400) { return response; } if (response.status === 401) { return _this6._manageUnauthorized(response, input, params); } var httpError = getHttpErrorFromResponse(response); throw httpError; }); } }, { key: "_getEntityIdentifier", value: function _getEntityIdentifier(object) { var idKey = this.metadata.getIdentifierAttribute().serializedKey; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return object[idKey]; } }, { key: "_handleRefreshTokenFailure", value: function _handleRefreshTokenFailure(error) { var _this7 = this; if (error instanceof OauthError) { _classPrivateFieldGet2(_tokenStorage, this).logout().then(function () { if (_this7.sdk.config.onRefreshTokenFailure) { _this7.sdk.config.onRefreshTokenFailure(error); } }); } } }]); }(); var _attributeList = /*#__PURE__*/new WeakMap(); var _relationList = /*#__PURE__*/new WeakMap(); var _identifierAttribute = /*#__PURE__*/new WeakMap(); var ClassMetadata = /*#__PURE__*/function () { /** * @param {string} key mandatory, will be passed in your serializer * @param {string|null} pathRoot the endpoint of your API: will be added to the mapping prefix ('/v1' here) * @param {typeof AbstractClient} repositoryClass [Overriding repository]{@link https://github.com/mapado/rest-client-js-sdk#overriding-repository} for more detail */ function ClassMetadata(key) { var pathRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var repositoryClass = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : AbstractClient; _classCallCheck(this, ClassMetadata); _defineProperty(this, "key", void 0); _defineProperty(this, "pathRoot", void 0); _defineProperty(this, "repositoryClass", void 0); _classPrivateFieldInitSpec(this, _attributeList, void 0); _classPrivateFieldInitSpec(this, _relationList, void 0); _classPrivateFieldInitSpec(this, _identifierAttribute, void 0); if (!key) { throw new TypeError('key attribute are required'); } this.key = key; this.pathRoot = pathRoot || key; // this.modelName = modelName; this.repositoryClass = repositoryClass; _classPrivateFieldSet2(_attributeList, this, {}); _classPrivateFieldSet2(_relationList, this, {}); } return _createClass(ClassMetadata, [{ key: "getAttribute", value: function getAttribute(name) { return _classPrivateFieldGet2(_attributeList, this)[name]; } }, { key: "hasIdentifierAttribute", value: function hasIdentifierAttribute() { return !!_classPrivateFieldGet2(_identifierAttribute, this); } }, { key: "getIdentifierAttribute", value: function getIdentifierAttribute() { if (!_classPrivateFieldGet2(_identifierAttribute, this)) { throw new TypeError("\"".concat(this.key, "\" has no identifier attribute set. Did you call \"setAttributeList\" first ?")); } return _classPrivateFieldGet2(_identifierAttribute, this); } }, { key: "getAttributeList", value: function getAttributeList() { return _classPrivateFieldGet2(_attributeList, this); } }, { key: "setAttributeList", value: function setAttributeList(attributeList) { var _this = this; _classPrivateFieldSet2(_attributeList, this, {}); _classPrivateFieldSet2(_identifierAttribute, this, undefined); attributeList.forEach(function (attribute) { _classPrivateFieldGet2(_attributeList, _this)[attribute.serializedKey] = attribute; if (attribute.isIdentifier) { _classPrivateFieldSet2(_identifierAttribute, _this, attribute); } }); if (!_classPrivateFieldGet2(_identifierAttribute, this)) { throw new TypeError("\"".concat(this.key, "\" has no identifier attribute set. You must set all your attributes in one time and send an attribute with \"isIdentifier=true\"")); } } }, { key: "setRelationList", value: function setRelationList(relationList) { var _this2 = this; _classPrivateFieldSet2(_relationList, this, {}); relationList.forEach(function (relation) { _classPrivateFieldGet2(_relationList, _this2)[relation.serializedKey] = relation; _classPrivateFieldGet2(_attributeList, _this2)[relation.serializedKey] = new Attribute(relation.serializedKey, relation.serializedKey, relation.isRelationToMany() ? 'array' : 'object'); }); } }, { key: "getRelation", value: function getRelation(key) { return _classPrivateFieldGet2(_relationList, this)[key]; } }, { key: "getDefaultSerializedModel", value: function getDefaultSerializedModel() { var _this3 = this; var out = {}; Object.keys(_classPrivateFieldGet2(_attributeList, this)).forEach(function (serializedKey) { out[serializedKey] = null; }); Object.keys(_classPrivateFieldGet2(_relationList, this)).forEach(function (serializedKey) { var relation = _classPrivateFieldGet2(_relationList, _this3)[serializedKey]; if (relation.isRelationToMany()) { out[serializedKey] = []; } }); return out; } }]); }(); var RelationTypes = /*#__PURE__*/function (RelationTypes) { RelationTypes["ONE_TO_ONE"] = "ONE_TO_ONE"; RelationTypes["ONE_TO_MANY"] = "ONE_TO_MANY"; RelationTypes["MANY_TO_MANY"] = "MANY_TO_MANY"; RelationTypes["MANY_TO_ONE"] = "MANY_TO_ONE"; return RelationTypes; }(RelationTypes || {}); var Relation = /*#__PURE__*/function () { /** * @param {RelationTypes} type the type of relation * @param {string} targetMetadataKey must match the first argument of `ClassMetadata` constructor of the target entity * @param {string} serializedKey the key returned from your API * @param {string|null} attributeName the name in your entity, default to the `serializedKey` attribute */ function Relation(type, targetMetadataKey, serializedKey) { var attributeName = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; _classCallCheck(this, Relation); _defineProperty(this, "type", void 0); _defineProperty(this, "targetMetadataKey", void 0); _defineProperty(this, "serializedKey", void 0); _defineProperty(this, "attributeName", void 0); this.type = type; this.targetMetadataKey = targetMetadataKey; this.serializedKey = serializedKey; this.attributeName = attributeName || this.serializedKey; } return _createClass(Relation, [{ key: "isOneToOne", value: function isOneToOne() { return this.type === Relation.ONE_TO_ONE; } }, { key: "isOneToMany", value: function isOneToMany() { return this.type === Relation.ONE_TO_MANY; } }, { key: "isManyToOne", value: function isManyToOne() { return this.type === Relation.MANY_TO_ONE; } }, { key: "isManyToMany", value: function isManyToMany() { return this.type === Relation.MANY_TO_MANY; } }, { key: "isRelationToMany", value: function isRelationToMany() { return this.isManyToMany() || this.isOneToMany(); } }, { key: "isRelationToOne", value: function isRelationToOne() { return this.isManyToOne() || this.isOneToOne(); } }]); }(); _defineProperty(Relation, "ONE_TO_ONE", RelationTypes.ONE_TO_ONE); _defineProperty(Relation, "ONE_TO_MANY", RelationTypes.ONE_TO_MANY); _defineProperty(Relation, "MANY_TO_ONE", RelationTypes.MANY_TO_ONE); _defineProperty(Relation, "MANY_TO_MANY", RelationTypes.MANY_TO_MANY); /* eslint-disable */ // "fork" of https://github.com/facebook/immutable-js/blob/v4.0.0-rc.9/src/Predicates.js // because tree-shaking does not seems to work as expected /** * Copyright (c) 2014-present, Facebook, Inc. * * This sou