rest-client-sdk
Version:
Rest Client SDK for API
1,533 lines (1,177 loc) • 102 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 = 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