@kitmi/jacaranda
Version:
JavaScript application framework
183 lines (182 loc) • 6.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return _default;
}
});
const _utils = require("@kitmi/utils");
/**
* Enable a http client as service
* @module Feature_HttpClient
*/ const DefaultMethods = {
get: 'get',
post: 'post',
put: 'put',
del: 'del',
delete: 'del',
upload: 'post',
download: 'get'
};
function resToPath(parts) {
return parts ? Array.isArray(parts) ? parts.map((res)=>encodeURIComponent(res)).join('/') : parts : '';
}
/**
* HTTP client.
* @class
*/ class HttpClient {
/**
*
* @param {string} method
* @param {string} path
* @param {object} query
* @param {object} body
* @param {object} options - Request options
* @property {string} [options.httpMethod] - Specified the http method to override the method argument
* @property {string} [options.endpoint] - Specified the base endpoint for this request only
* @property {function} [options.onSend] - Specified the onSend hook for this request only
* @property {integer} [options.timeout] - Specified the timeout setting for this request only
* @property {object} [options.headers] - Specified the headers for this request only
* @property {boolean} [options.withCredentials] - Specified the withCredentials header for CORS
* @property {object} [options.formData] - Specified the form fields
* @property {object} [options.fileField='file'] - Specified the file field name
* @property {object} [options.fileName] - Specified the file name to override the file to upload
* @property {function} [options.onProgress] - Specified the on progress callback
* @returns {*}
*/ async do(method, path, query, body, options) {
method = method.toLowerCase();
const _options = {
...this.options,
...options,
_method: method
};
let httpMethod = _options.httpMethod ?? DefaultMethods[method];
if (!httpMethod) {
throw new Error('Invalid method: ' + method);
}
let url = path.startsWith('http:') || path.startsWith('https:') ? path : _utils.url.join(_options.endpoint, path);
let req = this.adapter.createRequest(httpMethod, url, _options);
if (this.onSending) {
this.onSending(req);
}
if (_options.onSending) {
_options.onSending(req);
}
if (_options.timeout) {
req.timeout(_options.timeout);
}
if (_options.headers) {
_utils._.each(_options.headers, (v, k)=>{
req.set(k, v);
});
}
if (_options.withCredentials) {
req.withCredentials();
}
if (query) {
req.query(query);
}
if (method === 'download') {
if (httpMethod !== 'get') {
req.send(body);
}
} else if (method === 'upload') {
if (_options.formData) {
_utils._.each(_options.formData, (v, k)=>{
req.field(k, v);
});
}
let fileOpts = null;
if (_options.fileName) {
fileOpts = {
filename: _options.fileName
};
}
if (_options.contentType) {
fileOpts = {
...fileOpts,
contentType: _options.contentType
};
}
req.attach(_options.fileField ?? 'file', body, fileOpts);
} else if (httpMethod !== 'get') {
if (_options.usePipe) {
req = new Promise((resolve, reject)=>{
req.on('response', resolve);
req.on('error', reject);
body.pipe(req);
});
} else {
req.send(body ?? _options.body);
}
}
if (_options.onProgress) {
req.on('progress', _options.onProgress);
}
try {
const res = await req;
const result = res.type.startsWith('text/') ? res.text : res.body;
if (this.onResponse) {
this.onResponse(result, req, res);
}
if (_options.onResponse) {
_options.onResponse(result, req, res);
}
return result;
} catch (error) {
const onOtherError = _options.onOtherError ?? this.onOtherError;
const onResponseError = _options.onResponseError ?? this.onResponseError;
if (error.response) {
if (onResponseError) {
let body = error.response.body;
if (!body && error.response.type === 'application/json') {
try {
body = JSON.parse(error.response.text);
} catch (e) {}
}
return onResponseError(body, error);
}
throw error;
}
if (onOtherError) {
return onOtherError(error);
}
throw error;
}
}
async get(resource, query, options) {
return this.do('get', resToPath(resource), query, null, options);
}
async post(resource, data, query, options) {
return this.do('post', resToPath(resource), query, data, options);
}
async put(resource, data, query, options) {
return this.do('put', resToPath(resource), query, data, options);
}
async del(resource, query, options) {
return this.do('del', resToPath(resource), query, null, options);
}
async delete(...args) {
return this.del(...args);
}
async upload(resource, file, query, options) {
return this.do('upload', resToPath(resource), query, file, options);
}
async download(resource, query, options) {
return this.do('download', resToPath(resource), query, null, options);
}
/**
*
* @param {*} endpoint
*/ constructor(adapter, endpointOrOptions){
this.adapter = adapter;
this.options = typeof endpointOrOptions === 'string' ? {
endpoint: endpointOrOptions
} : endpointOrOptions;
}
}
const _default = HttpClient;
//# sourceMappingURL=HttpClient.js.map