@tatumio/tatum
Version:
Tatum JS SDK
188 lines • 7.41 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TatumConnector = void 0;
const typedi_1 = require("typedi");
const service_1 = require("../service");
const util_1 = require("../util");
let TatumConnector = class TatumConnector {
constructor(id) {
this.id = id;
}
async get(request) {
return this.request({ ...request, method: 'GET' });
}
async rpcCall(url, body) {
return this.request({ body, method: 'POST' }, 0, url);
}
async post(request) {
return this.request({
...request,
method: 'POST',
});
}
async put(request) {
return this.request({
...request,
method: 'PUT',
});
}
async delete(request) {
return this.request({ ...request, method: 'DELETE' });
}
async uploadFile(request) {
const formData = new FormData();
formData.append('file', new Blob([request.body]));
return this.request({ ...request, method: 'POST', body: formData }, 0);
}
async getFile(request) {
return this.request({ ...request, method: 'GET', isDownload: true });
}
async request({ path, params, body, method, basePath, isDownload }, retry = 0, externalUrl) {
const url = externalUrl || this.getUrl({ path, params, basePath });
const isUpload = body && body instanceof FormData;
const headers = isUpload ? util_1.Utils.getBasicHeaders(this.id) : util_1.Utils.getHeaders(this.id);
let requestBody = null;
if (isUpload) {
requestBody = body;
}
else if (body) {
requestBody = JSON.stringify(body);
}
const request = {
headers: headers,
method,
body: requestBody,
};
const start = Date.now();
try {
const res = await fetch(url, request);
const end = Date.now() - start;
const responseBody = isDownload ? `Binary data` : await res.clone().text();
// Structure your log entry here
util_1.Utils.log({
id: this.id,
message: `[${request.method}] ${url} -> ${res.status} (${end}ms)`,
data: {
request: {
method: request.method,
url: url,
body: request.body,
},
response: {
status: res.status,
time: `${end}ms`,
body: responseBody,
},
headers: util_1.Utils.headersToJson(headers),
},
});
if (res.ok) {
if (!responseBody) {
return undefined;
}
if (isDownload) {
return await res.blob();
}
const response = await res.json();
if (response?.error) {
return response;
}
return response;
}
// Retry only in case of 5xx error
if (res.status >= 500 && res.status < 600) {
return await this.retry(url, request, responseBody, retry);
}
throw responseBody;
}
catch (error) {
const end = Date.now() - start;
util_1.Utils.log({
id: this.id,
message: `[${request.method}] ${url} -> (${end}ms)`,
data: {
request: {
method: request.method,
url: url,
body: request.body,
},
error: JSON.stringify(error, Object.getOwnPropertyNames(error)),
time: `${end}ms`,
headers: util_1.Utils.headersToJson(headers),
},
});
return Promise.reject(error);
}
}
getBaseUrl() {
const config = typedi_1.Container.of(this.id).get(util_1.CONFIG);
if (util_1.EnvUtils.isProcessAvailable() && process.env?.TATUM_URL) {
return process.env.TATUM_URL;
}
return config.version === service_1.ApiVersion.V3 ? util_1.Constant.TATUM_API_URL.V3 : util_1.Constant.TATUM_API_URL.V4;
}
getUrl({ path, params, basePath, }) {
const config = typedi_1.Container.of(this.id).get(util_1.CONFIG);
const base = basePath || this.getBaseUrl();
const url = new URL(path && path?.length > 1 ? `${base}${path}` : base);
if (params) {
Object.keys(params)
.filter((key) => !!params[key])
.forEach((key) => url.searchParams.append(key, `${params[key]}`));
}
if (!Object.keys(config.apiKey || {})?.length && util_1.Constant.RPC.TESTNETS.includes(config.network)) {
url.searchParams.append('type', 'testnet');
}
return url.toString();
}
async retry(url, request, responseBody, retry) {
const { retryDelay, retryCount } = typedi_1.Container.of(this.id).get(util_1.CONFIG);
if (!retryCount) {
util_1.Utils.log({
id: this.id,
message: `Not retrying the request - no max retry count defined`,
data: { url, requestBody: request.body },
});
return Promise.reject(responseBody);
}
if (retry >= retryCount) {
util_1.Utils.log({
id: this.id,
message: `Not retrying the request for the '${retry}' time - exceeded max retry count ${retryCount}: `,
data: { url, requestBody: request.body },
});
return Promise.reject(responseBody);
}
retry++;
await util_1.Utils.delay(retryDelay || 1000);
util_1.Utils.log({
id: this.id,
message: `Retrying the request for the '${retry}' time: `,
data: { url, requestBody: request.body },
});
return this.request({
method: request.method,
body: request.body ? JSON.parse(request.body) : null,
}, retry, url);
}
};
exports.TatumConnector = TatumConnector;
exports.TatumConnector = TatumConnector = __decorate([
(0, typedi_1.Service)({
factory: (data) => {
return new TatumConnector(data.id);
},
transient: true,
}),
__metadata("design:paramtypes", [String])
], TatumConnector);
//# sourceMappingURL=tatum.connector.js.map