vue-rest-client
Version:
A VueJS RESTful client component to easily integrate apps with APIs
325 lines (265 loc) • 11.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _httpClient = _interopRequireDefault(require("./http-client"));
var _model = _interopRequireDefault(require("./model"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
/**
* Model service class that allows the running of REST api actions in a remote server for a defined endpoint resource.
* It is intended to be used in conjunction with the Model class @see @/core/model to read more
*
* @param {*} endPoint the relative url of the resource
* @param {*} resourceName the resource name (used to build the default confirmation messages)
* @param {*} options optional options that allows to customize the model service behavior
* @author <amoncaldas@gmail.com> Amon santana
*
* The options object may contain the following attributes:
* - transformRequest (function): executed before the request is made. Useful to change data in special circumstances.
* This function will receive an object with the endpoint and filters (when available) attributes. It is not intended to replace the axios
* request interceptor!
* - transformResponse (function): executed after the request is made, passing the original response object received.
* Useful if it necessary to modify the data returned before transforming them in a Model instance
* - raw (boolean): defines if the default transformation of the results into Model instances must be skipped.
* If it is true, the active record will not work with the returned items. Useful when you just want to get data, and not destroy/update them
* - pk (string): overwrites the default primary key attribute, that is 'id'. Use it if your model on the remote server uses a different field as primary key
*/
function ModelService(endPoint, resourceName, options) {
var _this = this;
// if options is not passed, initialize it
options = options || {};
this.endPoint = endPoint;
this.endPointTemplate = endPoint;
this.resourceName = resourceName;
this.options = options;
var httpClient = new _httpClient["default"](options.httpClientOptions);
this.httpClient = httpClient.http;
/**
* Provides an accessor to get the name of the resource
*/
this.getName = function () {
return resourceName;
};
/**
* Clone the current model service
* @returns {ModelService} service
*/
this.clone = function () {
var service = new ModelService(_this.endPoint, _this.resourceName, _this.options);
return service;
};
/**
* Provides an accessor to get the endpoint
* @param String append
* @param String prepend
*/
this.getEndPoint = function (append, prepend) {
var baseEndPoint = _this.endPoint;
if (append) {
baseEndPoint = "".concat(baseEndPoint, "/").concat(append);
}
if (prepend) {
baseEndPoint = "".concat(prepend, "/").concat(baseEndPoint);
}
return baseEndPoint;
};
/**
* Provides an accessor to get the endpoint template
* @param String append
* @param String prepend
*/
this.getEndPointTemplate = function () {
return _this.endPointTemplate;
};
/**
* Provides an accessor to set the endpoint
* @param String endPoint
*/
this.setEndPoint = function (endPoint) {
_this.endPoint = endPoint;
};
/**
* Queries the model service endpoint, retrieve the resources and (by default) transform them in active record Models
* @param {*} filters filters to be applied to retrieve the resources
*/
this.query = function (filters) {
var endpointAppend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
var http = _this.httpClient;
return new Promise(function (resolve, reject) {
var endPoint = _this.endPoint + endpointAppend;
endPoint += _this.buildParams(filters);
var request = {
endPoint: endPoint,
filters: filters,
running: 'query'
}; // if the transform request is defined, run it
if (options.transformRequest) {
options.transformRequest(request);
} // run the get action using the http client
http.get(request.endPoint, request.filters).then(function (response) {
// add the filters applied to the response so it can be used in some business logic
response.filtersApplied = filters; // if the transform response is defined, run it
if (options.transformResponse) {
options.transformResponse(response);
} // if the raw option is defined, skip the transformation to Model and resolve the promise
if (options.raw === true) {
response.raw = true;
resolve(response);
} else {
// transform each resource returned in a active record Model
// @see @/core/model to read more
var items = modelCollection(response.data, _this);
resolve(items);
}
}, function (error) {
reject(error);
})["catch"](function (error) {
reject(error);
});
});
};
/**
* Queries the model service endpoint, retrieve the resources and (by default) transform them in active record Models
* @param {*} customOptions options to be applied to the request. The following options attributes can defined:
* - query (object): containing key -> value attributes to be used as query string)
* - data (object): containing key -> value attributes to be used as post data)
* - verb (string): verb to be used - default is 'get'
* - transformRequest: function to be called back on transformRequest event
* @param {*} endPoint the endpoint to which the request will be made
*/
this.customQuery = function (customOptions, endPoint) {
var cOptions = customOptions || options; // set the raw option
cOptions.raw = cOptions.raw === undefined ? options.raw : cOptions.raw;
var http = _this.httpClient;
return new Promise(function (resolve, reject) {
endPoint = endPoint || _this.getEndPoint();
var request = {
endPoint: endPoint,
query: cOptions.query,
running: 'customQuery',
data: cOptions.data
};
request.endPoint += _this.buildParams(request.query); // set the verb (from options or default)
request.verb = cOptions.verb || 'get'; // if the transform request is defined, run it
if (cOptions.transformRequest) {
options.transformRequest(request);
} // run the get action using the http client
http[request.verb](request.endPoint, request.data).then(function (response) {
// if the transform response is defined, run it
if (cOptions.transformResponse) {
options.transformResponse(response);
} // if the raw option is defined, skip the transformation to Model and resolve the promise
if (cOptions.raw === true) {
if (_typeof(response.data) === 'object') {
response.data.httpStatusCode = response.status;
}
response.raw = true;
resolve(response.data);
} else {
// transform each resource returned in a active record Model
// @see @/core/model to read more
var items = modelCollection(response.data, _this);
resolve(items);
}
}, function (error) {
reject(error);
})["catch"](function (error) {
reject(error);
});
});
};
/**
* Retrieve a single specified resource from the service endpoint
* @param string|numeric id
*/
this.get = function (pkValue) {
var http = _this.httpClient;
return new Promise(function (resolve, reject) {
var endPoint = "".concat(_this.endPoint, "/").concat(pkValue);
var request = {
endPoint: endPoint,
running: 'get'
}; // if the transform request is defined, run it
if (options.transformRequest) {
options.transformRequest(request);
}
http.get(request.endPoint).then(function (response) {
// add the pkValue used to the response so it can be used in some business logic
response.pkValue = pkValue; // if the transform response is defined, run it
if (options.transformResponse) {
options.transformResponse(response);
}
if (options.raw === true) {
response.raw = true;
resolve(response.data);
} else {
// transform the resource returned in a active record Model
// @see @/core/model to read more
var model = new _model["default"](response.data, _this.endPoint, _this.resourceName, _this.options);
resolve(model);
}
}, function (error) {
reject(error);
})["catch"](function (error) {
reject(error);
});
});
};
/**
* Build url params based in an object
* @param {*} obj
*/
this.buildParams = function (obj) {
if (obj === undefined || obj === null) {
return '';
}
var str = Object.keys(obj).map(function (key) {
return key + '=' + obj[key];
}).join('&');
if (str && str.length > 0) {
str = '?' + str;
}
return str;
};
/**
* Create a new active record Model instance using a
* raw object and the model service configuration.
* @param {Object} rawObject
* @returns Model
*/
this.newModelInstance = function () {
var rawObject = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
return new _model["default"](rawObject, _this.endPoint, _this.resourceName, _this.options);
};
return this;
}
/**
* Transform the raw returned data into an active record Model
* @param {*} rawObj
* @param {*} arrayInst
* @param {*} context
*/
var wrapAsNewModelInstance = function wrapAsNewModelInstance(rawObj, arrayInst, context) {
// create an instance
var instance = rawObj.constructor === _model["default"] ? rawObj : new _model["default"](rawObj, context.endPoint, context.resourceName, context.options); // Set a pointer to the array
instance.$$array = arrayInst;
return instance;
};
/**
* Transform the raw returned data collection in a array of active record Models
* @param {*} value
* @param {*} context
*/
var modelCollection = function modelCollection(value, context) {
value = Array.isArray(value) ? value : []; // Transform each value item in a Model object with active record strategy
value.forEach(function (v, i) {
// this should not happen but prevent blow up
if (v === null || v === undefined) return; // reset to new instance
value[i] = wrapAsNewModelInstance(v, value, context);
});
return value;
}; // export the model Service class
var _default = ModelService;
exports["default"] = _default;