UNPKG

rest-client-sdk

Version:
1,533 lines (1,177 loc) 102 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('urijs'), require('deep-diff')) : typeof define === 'function' && define.amd ? define(['exports', 'urijs', 'deep-diff'], factory) : (global = global || self, factory(global['rest-client-sdk'] = {}, global.URI, global.diff)); }(this, (function (exports, URI, diff) { 'use strict'; URI = URI && Object.prototype.hasOwnProperty.call(URI, 'default') ? URI['default'] : URI; diff = diff && Object.prototype.hasOwnProperty.call(diff, 'default') ? diff['default'] : diff; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 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; } 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 _objectSpread2(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 _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } 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 _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function () {}; return { s: F, n: function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function (e) { throw e; }, 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 normalCompletion = true, didErr = false, err; return { s: function () { it = o[Symbol.iterator](); }, n: function () { var step = it.next(); normalCompletion = step.done; return step; }, e: function (e) { didErr = true; err = e; }, f: function () { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _classPrivateFieldGet(receiver, privateMap) { var descriptor = privateMap.get(receiver); if (!descriptor) { throw new TypeError("attempted to get private field on non-instance"); } if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = privateMap.get(receiver); if (!descriptor) { throw new TypeError("attempted to set private field on non-instance"); } if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } return value; } /* eslint-disable max-classes-per-file, no-use-before-define */ /** * 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) { _inherits(HttpError, _Error); var _super = _createSuper(HttpError); function HttpError(message, baseResponse) { var _this; _classCallCheck(this, HttpError); _this = _super.call(this, message || 'Http errort'); // Set the prototype explicitly. _defineProperty(_assertThisInitialized(_this), "baseResponse", void 0); Object.setPrototypeOf(_assertThisInitialized(_this), OauthError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this), OauthError); } _this.name = 'HttpError'; _this.baseResponse = baseResponse; return _this; } /** * Get the JSON of the baseResponse directly, if possible */ _createClass(HttpError, [{ key: "responseJson", value: function responseJson() { return this.baseResponse.json(); } }]); return HttpError; }( /*#__PURE__*/_wrapNativeSuper(Error)); var OauthError = /*#__PURE__*/function (_Error2) { _inherits(OauthError, _Error2); var _super2 = _createSuper(OauthError); function OauthError(message, previousError) { var _this2; _classCallCheck(this, OauthError); _this2 = _super2.call(this, message || 'Oauth error'); // Set the prototype explicitly. _defineProperty(_assertThisInitialized(_this2), "previousError", void 0); Object.setPrototypeOf(_assertThisInitialized(_this2), OauthError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this2), OauthError); } _this2.name = 'OauthError'; _this2.previousError = previousError; return _this2; } return OauthError; }( /*#__PURE__*/_wrapNativeSuper(Error)); var InvalidGrantError = /*#__PURE__*/function (_OauthError) { _inherits(InvalidGrantError, _OauthError); var _super3 = _createSuper(InvalidGrantError); function InvalidGrantError(message, previousError) { var _this3; _classCallCheck(this, InvalidGrantError); _this3 = _super3.call(this, message || 'Invalid grant error', previousError); // Set the prototype explicitly. _defineProperty(_assertThisInitialized(_this3), "previousError", void 0); Object.setPrototypeOf(_assertThisInitialized(_this3), InvalidGrantError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this3), InvalidGrantError); } _this3.name = 'InvalidGrantError'; _this3.previousError = previousError; return _this3; } return InvalidGrantError; }(OauthError); var InvalidScopeError = /*#__PURE__*/function (_OauthError2) { _inherits(InvalidScopeError, _OauthError2); var _super4 = _createSuper(InvalidScopeError); function InvalidScopeError(message, previousError) { var _this4; _classCallCheck(this, InvalidScopeError); _this4 = _super4.call(this, message || 'Invalid scope error', previousError); // Set the prototype explicitly. _defineProperty(_assertThisInitialized(_this4), "previousError", void 0); Object.setPrototypeOf(_assertThisInitialized(_this4), InvalidScopeError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this4), InvalidScopeError); } _this4.name = 'InvalidScopeError'; _this4.previousError = previousError; return _this4; } return InvalidScopeError; }(OauthError); // 400 var BadRequestError = /*#__PURE__*/function (_HttpError) { _inherits(BadRequestError, _HttpError); var _super5 = _createSuper(BadRequestError); function BadRequestError(message, baseResponse) { var _this5; _classCallCheck(this, BadRequestError); _this5 = _super5.call(this, message || 'Bad request', baseResponse); // Set the prototype explicitly. _defineProperty(_assertThisInitialized(_this5), "baseResponse", void 0); Object.setPrototypeOf(_assertThisInitialized(_this5), BadRequestError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this5), BadRequestError); } _this5.name = 'BadRequestError'; _this5.baseResponse = baseResponse; return _this5; } return BadRequestError; }(HttpError); // 401 var UnauthorizedError = /*#__PURE__*/function (_BadRequestError) { _inherits(UnauthorizedError, _BadRequestError); var _super6 = _createSuper(UnauthorizedError); function UnauthorizedError(message, baseResponse) { var _this6; _classCallCheck(this, UnauthorizedError); _this6 = _super6.call(this, message || 'Unauthorized', baseResponse); // Set the prototype explicitly. _defineProperty(_assertThisInitialized(_this6), "baseResponse", void 0); Object.setPrototypeOf(_assertThisInitialized(_this6), UnauthorizedError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this6), UnauthorizedError); } _this6.name = 'UnauthorizedError'; _this6.baseResponse = baseResponse; return _this6; } return UnauthorizedError; }(BadRequestError); // 403 var ForbiddenError = /*#__PURE__*/function (_BadRequestError2) { _inherits(ForbiddenError, _BadRequestError2); var _super7 = _createSuper(ForbiddenError); function ForbiddenError(message, baseResponse) { var _this7; _classCallCheck(this, ForbiddenError); _this7 = _super7.call(this, message || 'Forbidden', baseResponse); // Set the prototype explicitly. _defineProperty(_assertThisInitialized(_this7), "baseResponse", void 0); Object.setPrototypeOf(_assertThisInitialized(_this7), ForbiddenError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this7), ForbiddenError); } _this7.name = 'ForbiddenError'; _this7.baseResponse = baseResponse; return _this7; } return ForbiddenError; }(BadRequestError); // 404 var ResourceNotFoundError = /*#__PURE__*/function (_BadRequestError3) { _inherits(ResourceNotFoundError, _BadRequestError3); var _super8 = _createSuper(ResourceNotFoundError); function ResourceNotFoundError(message, baseResponse) { var _this8; _classCallCheck(this, ResourceNotFoundError); _this8 = _super8.call(this, message || 'Resource is not found', baseResponse); // Set the prototype explicitly. _defineProperty(_assertThisInitialized(_this8), "baseResponse", void 0); Object.setPrototypeOf(_assertThisInitialized(_this8), ResourceNotFoundError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this8), ResourceNotFoundError); } _this8.name = 'ResourceNotFoundError'; _this8.baseResponse = baseResponse; return _this8; } return ResourceNotFoundError; }(BadRequestError); // 409 var ConflictError = /*#__PURE__*/function (_BadRequestError4) { _inherits(ConflictError, _BadRequestError4); var _super9 = _createSuper(ConflictError); function ConflictError(message, baseResponse) { var _this9; _classCallCheck(this, ConflictError); _this9 = _super9.call(this, message || 'Conflict detected', baseResponse); // Set the prototype explicitly. _defineProperty(_assertThisInitialized(_this9), "baseResponse", void 0); Object.setPrototypeOf(_assertThisInitialized(_this9), ConflictError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this9), ConflictError); } _this9.name = 'ConflictError'; _this9.baseResponse = baseResponse; return _this9; } return ConflictError; }(BadRequestError); // 500 var InternalServerError = /*#__PURE__*/function (_HttpError2) { _inherits(InternalServerError, _HttpError2); var _super10 = _createSuper(InternalServerError); function InternalServerError(message, baseResponse) { var _this10; _classCallCheck(this, InternalServerError); _this10 = _super10.call(this, message || 'Internal server error', baseResponse); // Set the prototype explicitly. _defineProperty(_assertThisInitialized(_this10), "baseResponse", void 0); Object.setPrototypeOf(_assertThisInitialized(_this10), InternalServerError.prototype); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(_assertThisInitialized(_this10), InternalServerError); } _this10.name = 'InternalServerError'; _this10.baseResponse = baseResponse; return _this10; } return 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) { var _ref; return typeof ((_ref = body) === null || _ref === void 0 ? void 0 : _ref.error) === 'string'; } var DEFAULT_CONFIG = { collectionKey: 'hydra:member' }; var _config = new WeakMap(); var _classMetadataList = 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); _config.set(this, { writable: true, value: void 0 }); _classMetadataList.set(this, { writable: true, value: void 0 }); this.idPrefix = idPrefix; _classPrivateFieldSet(this, _classMetadataList, []); this.setConfig(config); } _createClass(Mapping, [{ key: "getConfig", value: function getConfig() { return _classPrivateFieldGet(this, _config); } }, { key: "setConfig", value: function setConfig(config) { _classPrivateFieldSet(this, _config, _objectSpread2(_objectSpread2({}, DEFAULT_CONFIG), config)); } }, { key: "setMapping", value: function setMapping() { var classMetadataList = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; _classPrivateFieldSet(this, _classMetadataList, classMetadataList); } }, { key: "getMappingKeys", value: function getMappingKeys() { return _classPrivateFieldGet(this, _classMetadataList).map(function (classMetadata) { return classMetadata.key; }); } }, { key: "getClassMetadataByKey", value: function getClassMetadataByKey(key) { var filterList = _classPrivateFieldGet(this, _classMetadataList).filter(function (classMetadata) { return classMetadata.key === key; }); return filterList.length > 0 ? filterList[0] : null; } }, { key: "isMappingValid", value: function isMappingValid() { var _this = this; return !_classPrivateFieldGet(this, _classMetadataList).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 global-require, import/no-extraneous-dependencies, @typescript-eslint/no-var-requires var pluralize = require('pluralize'); if (!endsWithList && !pluralize.isPlural(attribute.attributeName)) { return message; } } catch (e) { 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) { // eslint-disable-next-line no-console console.warn(error); } return error; }); return nbError.length > 0; }); } }]); return Mapping; }(); var Attribute = /** * @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; }; /* eslint-disable import/prefer-default-export */ // eslint-disable-next-line import/no-duplicates // eslint-disable-next-line import/no-duplicates 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); } /* eslint-disable consistent-return */ 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 EXPIRE_LIMIT_SECONDS = 300; // = 5 minutes var _tokenStorage = new WeakMap(); var _isUnitOfWorkEnabled = 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); _tokenStorage.set(this, { writable: true, value: void 0 }); _defineProperty(this, "serializer", void 0); _defineProperty(this, "metadata", void 0); _isUnitOfWorkEnabled.set(this, { writable: true, value: void 0 }); this.sdk = sdk; _classPrivateFieldSet(this, _tokenStorage, sdk.tokenStorage); this.serializer = sdk.serializer; this.metadata = metadata; _classPrivateFieldSet(this, _isUnitOfWorkEnabled, isUnitOfWorkEnabled); } _createClass(AbstractClient, [{ key: "withUnitOfWork", value: function withUnitOfWork(enabled) { // eslint-disable-next-line new-cap 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] : {}; 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: 'PUT', 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 (_classPrivateFieldGet(_this2, _isUnitOfWorkEnabled)) { // eslint-disable-next-line no-restricted-syntax 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 (_classPrivateFieldGet(_this2, _isUnitOfWorkEnabled) && 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 = null; 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 (_classPrivateFieldGet(this, _tokenStorage)) { return _classPrivateFieldGet(this, _tokenStorage).getCurrentTokenExpiresIn().then(function (accessTokenExpiresIn) { if (accessTokenExpiresIn !== null && accessTokenExpiresIn <= EXPIRE_LIMIT_SECONDS) { return _classPrivateFieldGet(_this3, _tokenStorage).refreshToken().then(function (refreshedTokenObject) { return refreshedTokenObject.access_token; })["catch"](function (e) { _this3._handleRefreshTokenFailure(e); throw e; }); } return _classPrivateFieldGet(_this3, _tokenStorage).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 _classPrivateFieldGet(this, _tokenStorage).refreshToken().then(function () { // eslint-disable-next-line prefer-const var headers = requestParams.headers, rest = _objectWithoutProperties(requestParams, ["headers"]); 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 && _classPrivateFieldGet(this, _tokenStorage)) { 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 (_classPrivateFieldGet(_this5, _tokenStorage) && (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)); } // eslint-disable-next-line consistent-return 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) { _classPrivateFieldGet(this, _tokenStorage).logout().then(function () { if (_this7.sdk.config.onRefreshTokenFailure) { _this7.sdk.config.onRefreshTokenFailure(error); } }); } } }]); return AbstractClient; }(); var _attributeList = new WeakMap(); var _relationList = new WeakMap(); var _identifierAttribute = 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); _attributeList.set(this, { writable: true, value: void 0 }); _relationList.set(this, { writable: true, value: void 0 }); _identifierAttribute.set(this, { writable: true, value: void 0 }); if (!key) { throw new TypeError('key attribute are required'); } this.key = key; this.pathRoot = pathRoot || key; // this.modelName = modelName; this.repositoryClass = repositoryClass; _classPrivateFieldSet(this, _attributeList, {}); _classPrivateFieldSet(this, _relationList, {}); } _createClass(ClassMetadata, [{ key: "getAttribute", value: function getAttribute(name) { return _classPrivateFieldGet(this, _attributeList)[name]; } }, { key: "hasIdentifierAttribute", value: function hasIdentifierAttribute() { return !!_classPrivateFieldGet(this, _identifierAttribute); } }, { key: "getIdentifierAttribute", value: function getIdentifierAttribute() { if (!_classPrivateFieldGet(this, _identifierAttribute)) { throw new TypeError("\"".concat(this.key, "\" has no identifier attribute set. Did you call \"setAttributeList\" first