rest-chronicle
Version:
autodocumentate rest api
140 lines (136 loc) • 4.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _utils = require("../utils");
var _chronicle = _interopRequireDefault(require("../chronicle"));
var _constants = require("../constants");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
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 || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const NativeFetch = _utils.PeerDependency.load('node-fetch');
function fillParams(url, params = {}) {
let filled = url;
for (const [key, value] of Object.entries(params)) {
filled = filled.replace(`:${key}`, encodeURIComponent(value));
}
return filled;
}
class Fetch {
constructor(chronicle = _chronicle.default, useContext = null) {
_defineProperty(this, "with", context => {
return new Fetch(this._chronicle, context);
});
this._chronicle = chronicle;
this._useContext = useContext;
const fetchImpl = global.fetch || NativeFetch;
_utils.PeerDependency.check(fetchImpl);
this._fetch = fetchImpl;
// eslint-disable-next-line no-constructor-return
return this._decorate(this.fetch.bind(this));
}
_decorate(target) {
if (target[_constants.isDecorated]) return target;
// eslint-disable-next-line no-param-reassign
target.with = this.with;
return (0, _utils.decorate)(target, this);
}
_resolveContext(init) {
var _this$_chronicle;
if (init !== null && init !== void 0 && init.with) return init.with;
if (this._useContext) return this._useContext;
if ((_this$_chronicle = this._chronicle) !== null && _this$_chronicle !== void 0 && _this$_chronicle.clsEnabled) {
return this._chronicle.getCLSContext();
}
return null;
}
async fetch(input, init = {}) {
const context = this._resolveContext(init);
let url = typeof input === 'string' ? input : input.url;
const rawUrl = url;
if (context !== null && context !== void 0 && context.urlParams) {
url = fillParams(url, context.urlParams);
}
if (context) {
context.rawUrl = rawUrl;
}
const requestInit = {
...init,
method: init.method || 'GET',
headers: init.headers || {}
};
let response;
try {
response = await this._fetch(url, requestInit);
} catch (error) {
if (context) this._handleError(error, url, requestInit, context);
throw error;
}
if (context) {
await this._processResponse(response, url, requestInit, context);
}
return response;
}
async _processResponse(response, url, requestInit, context) {
var _requestInit$headers, _requestInit$headers2;
const action = this._chronicle.action(context);
// Identify if the request is multipart
let requestType = ((_requestInit$headers = requestInit.headers) === null || _requestInit$headers === void 0 ? void 0 : _requestInit$headers['content-type']) || ((_requestInit$headers2 = requestInit.headers) === null || _requestInit$headers2 === void 0 ? void 0 : _requestInit$headers2['Content-Type']);
if (!requestType && requestInit.body && typeof requestInit.body.append === 'function') {
requestType = 'multipart/form-data';
}
let body;
try {
body = await response.clone().json();
} catch {
try {
body = await response.clone().text();
} catch {
body = null;
}
}
action.request = {
url,
headers: requestInit.headers,
method: requestInit.method,
body: requestInit.body,
type: requestType
};
action.response = {
body,
// eslint-disable-next-line node/no-unsupported-features/es-builtins
headers: Object.fromEntries(response.headers.entries()),
http: {
version: '1.1'
},
status: {
code: response.status,
message: response.statusText
},
type: response.headers.get('content-type'),
charset: null
};
}
_handleError(error, url, requestInit, context) {
try {
const action = this._chronicle.action(context);
action.request = {
url,
headers: requestInit.headers,
method: requestInit.method,
body: requestInit.body
};
action.response = {
status: {
code: 0,
message: error.message
}
};
} catch (err) {
console.error(err);
}
}
}
exports.default = Fetch;