rest-client-sdk
Version:
Rest Client SDK for API
1,223 lines (1,176 loc) • 99 kB
JavaScript
(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 = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["rest-client-sdk"] = {}, global.URI, global.diff));
})(this, (function (exports, URI, diff) { 'use strict';
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)[