bb-api-platforma
Version:
API module for BetBooster Platform
1,181 lines • 93.5 kB
JavaScript
import * as I from './Types.js';
import { api } from './Types.js';
// #region Consts -----------------------------------------------------------------------
const locales = {
/** Be careful on the backend these values may change
* for chek:
* https://front-test.restin.win/api/account/GetAvailableLanguages
*/
en: 'en-US',
pt: 'pt-PT',
fr: 'fr-FR',
es: 'es-ES',
tr: 'tr-TR',
uk: 'uk-UA',
cr: 'cr-HA',
ru: 'ru-RU',
};
const languageIdsRemote = {
/** Be careful on the backend these values may change
* for chek:
* https://front-test.restin.win/api/account/GetAvailableLanguages
*/
en: 1,
pt: 0,
fr: 4,
es: 3,
tr: 5,
uk: 2,
cr: 6,
ru: 0,
};
const stringify = (obj) => {
return JSON.stringify(obj, null, 2);
};
export function routeNameId(id, text = '') {
return `${text
.replace(/[\s\.\,\(\)\[\]\\\/\-\~\`\"\']+/g, ' ')
.trim()
.replace(/\s+/g, '-')
.toLowerCase()}~${id}`;
}
export function clearPhone(draftPhoneNumber, prefix = '', suffix = '') {
return prefix + (String(draftPhoneNumber).match(/\d+/g) || []).join('') + suffix;
}
let IS_DEV_MODE = false;
// #endregion Consts -----------------------------------------------------------------------
export class BetBoosterOfficeApi {
// #endregion Class Properties --------------------------------------------------------
/**
* Represents the BetBoosterApi class.
* @constructor
* @param {AxiosInstance} axiosInstance - The Axios instance to be used for making HTTP requests. Aka axios.create()
* @param {string} baseUrl - The base URL of the API.
* @param {string} [lang='en'] - The language to be used for API requests. Defaults to 'en'.
* @param {number} [maxTimeExecutionMs=15000] - The maximum time allowed for API request execution in milliseconds. Defaults to 15000.
* @param {boolean} [isDev=false] - Indicates whether the API is running in development mode. Defaults to false.
*/
constructor(axiosInstance, baseUrl, lang = 'en', maxTimeExecutionMs = 15000, isDev = false) {
this._locale = 'en-EN';
this._locales = locales;
this._languageIdsRemote = languageIdsRemote;
this.EXIST_LANGUAGES = Object.keys(locales);
this._languageId = 1;
this._lang = 'en';
this._APIv1 = '/api';
this._APIv2 = '/api/v2';
this._API_LBC = '/v2/lbc/api';
this._USER_DATA = {};
this.LANG_DEFAULT = 'en';
this.LOCALE_DEFAULT = 'en-EN';
this.LANG_ID_DEFAULT = 1;
this.maxTimeExecutionMs = 15000;
this.liveTimestamp = 0;
this._liveTimestampReset = false;
this.liveRecivedIsFullPackage = false;
this.isNotActive = false;
const uri = new URL(baseUrl);
IS_DEV_MODE = isDev;
this._ENDPOINT_DOMAIN = uri.origin;
this.maxTimeExecutionMs = maxTimeExecutionMs;
this.axi = axiosInstance;
this.setBaseUrl(baseUrl);
this.setLanguage(lang);
}
// #region Getters & Setters -----------------------------------------------------------
get locale() {
return this._locale;
}
get isSinged() {
return this.user !== undefined && this.user.UserId !== undefined && this.user.UserId > 0;
}
get user() {
return this._USER_DATA;
}
set user(value) {
this._USER_DATA = value;
}
get lang() {
return this._lang;
}
get baseUrl() {
return this._baseUrl;
}
get languageId() {
return this._languageId;
}
get token() {
var _a;
return (_a = this._TOKEN) !== null && _a !== void 0 ? _a : undefined;
}
set token(value) {
if (typeof value === 'string') {
this._TOKEN = value.split(/\s*,\s*/)[0];
}
else {
this._TOKEN = undefined;
}
}
// #endregion Getters & Setters -----------------------------------------------------------
// #region Handlers -----------------------------------------------------------------------
/**
* Обрабатывает данные ответа и возвращает объект с данными, ошибкой, статусом и текстом статуса.
*
* @template T - Тип данных, возвращаемых в поле `data`.
* @param {any} rawData - Сырые данные ответа.
* @param {number} status - HTTP статус ответа.
* @param {string} statusText - Текст статуса HTTP ответа.
* @returns {{ data: T, error: string | null, status: number, statusText: string }} Объект, содержащий данные ответа, ошибку, статус и текст статуса.
*/
responseHandlerData(rawData, status, statusText) {
var _a, _b, _c;
let data = null;
if (((_a = rawData === null || rawData === void 0 ? void 0 : rawData.Data) === null || _a === void 0 ? void 0 : _a.Data) !== undefined) {
data = rawData.Data.Data;
}
else if (((_b = rawData === null || rawData === void 0 ? void 0 : rawData.Data) === null || _b === void 0 ? void 0 : _b._isSuccessful) !== undefined) {
data = rawData.Data._isSuccessful;
}
else if ((rawData === null || rawData === void 0 ? void 0 : rawData.Data) !== undefined) {
data = rawData.Data;
}
else if (rawData !== undefined) {
data = rawData;
}
// const data: T = rawData?.Data?.Data ?? rawData?.Data ?? rawData ?? null as T;
const error = ((_c = rawData === null || rawData === void 0 ? void 0 : rawData.Data) === null || _c === void 0 ? void 0 : _c.Error) || (rawData === null || rawData === void 0 ? void 0 : rawData.Error) || (status !== 200 ? statusText : null) || (!data ? 'Unknown error' : null);
return { data, error, status, statusText };
}
setDevMode(devMode) {
if (devMode === undefined) {
IS_DEV_MODE = true;
}
else {
IS_DEV_MODE = devMode;
}
}
checkLanguage(lang = 'en') {
try {
const _lang = lang.substring(0, 2) || this.LANG_DEFAULT;
const isExistInLanguages = this.EXIST_LANGUAGES.includes(_lang);
return isExistInLanguages ? _lang : this.LANG_DEFAULT;
}
catch (error) {
return this.LANG_DEFAULT;
}
}
setLanguage(lang = 'en') {
var _a, _b;
this._lang = this.checkLanguage(lang);
this._locale = (_a = this._locales[this._lang]) !== null && _a !== void 0 ? _a : this.LOCALE_DEFAULT;
this._languageId = (_b = this._languageIdsRemote[this._lang]) !== null && _b !== void 0 ? _b : this.LANG_ID_DEFAULT;
return this._lang;
}
/**
* Устанавливает язык и локаль для удаленного API.
* @param lang Язык (по умолчанию 'en').
* @returns Возвращает true, если язык и локаль успешно установлены, в противном случае возвращает false.
*/
async setLanguageRemoteLocale(lang = 'en') {
this.setLanguage(lang);
return true;
// !TODO setLanguageRemoteLocale - проверить как работает
// if (this.isSinged) {
// const url = this.url(`/account/SetLanguage`, api.LBC);
// const res = await this.POST(url, {culture: this.locale});
// return res || false;
// }
// return undefined;
}
setBaseUrl(baseUrl) {
if (baseUrl.endsWith('/')) {
baseUrl = baseUrl.slice(0, -1);
}
this._baseUrl = baseUrl;
return this._baseUrl;
}
statusHandler(status, statusText) {
if (status === 401) {
this.user = {};
this.token = undefined;
if (IS_DEV_MODE)
console.log('Status:', status, statusText);
}
}
/**
* Обработчик строки запроса. Заменяет значения
* * `null` на `'null'`
* * `false` на `'false'`
* * `true` на `'true'`
* * `undefined` на `''`
* @param queryStringData - queryString Record<string, any>
* @returns Обработанные данные строки запроса.
*/
queryStringHandler(queryStringData = {}) {
const keys = Object.keys(queryStringData);
keys.forEach(key => {
if (queryStringData[key] === null) {
queryStringData[key] = 'null';
}
else if (queryStringData[key] === true) {
queryStringData[key] = 'true';
}
else if (queryStringData[key] === false) {
queryStringData[key] = 'false';
}
else if (queryStringData[key] === undefined) {
queryStringData[key] = '';
}
});
return queryStringData;
}
responseHandler(response) {
var _a, _b, _c;
const xToken = (_a = response === null || response === void 0 ? void 0 : response.headers['x-token']) !== null && _a !== void 0 ? _a : null;
const urlPath = (_c = (_b = response === null || response === void 0 ? void 0 : response.request) === null || _b === void 0 ? void 0 : _b.path) !== null && _c !== void 0 ? _c : null;
if (IS_DEV_MODE && urlPath)
console.log(urlPath);
if (xToken) {
this.token = xToken;
if (IS_DEV_MODE)
console.log('isSinged:', this.isSinged + '\nX-Token:', xToken);
}
;
}
/**
* Обработчик ошибок для Axios.
*
* @param error - Объект ошибки AxiosError.
* @returns Объект с данными об ошибке, включая статус и текст ошибки.
*/
axiosErrorHandler(error) {
var _a, _b, _c, _d, _e, _f, _g, _h;
let errorMessage;
let status = (_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.status) !== null && _b !== void 0 ? _b : null;
let statusText = (_d = (_c = error.response) === null || _c === void 0 ? void 0 : _c.statusText) !== null && _d !== void 0 ? _d : null;
const response = (_e = error.response) !== null && _e !== void 0 ? _e : null;
// const request = err.request ?? null;
if (response) {
// Server responded with a status other than 200 range
// console.log('err.response.request.url:', response.request.url)
const brMessage = [
...(status ? [status] : []),
...(statusText ? [statusText] : []),
...(((_f = response === null || response === void 0 ? void 0 : response.data) === null || _f === void 0 ? void 0 : _f.Message) ? [response.data.Message] : []),
...(((_g = response === null || response === void 0 ? void 0 : response.data) === null || _g === void 0 ? void 0 : _g.MessageDetail) ? [response.data.MessageDetail] : []),
].join(' > ');
// errorMessage = `Error: ${brMessage}`;
errorMessage = brMessage;
if (IS_DEV_MODE) {
const requestMethod = ((_h = response.config.method) !== null && _h !== void 0 ? _h : '').toUpperCase();
const fullUrl = response.config.url;
const requestData = response.config.data;
console.log('```');
console.log('ERROR:', requestMethod, fullUrl);
console.log('DATA:', requestData);
console.log('RESPONCE:', response === null || response === void 0 ? void 0 : response.data);
console.log('```');
}
}
else if (error.request) {
// Request was made but no response was received
errorMessage = `Error: No response received`;
// 503 Service Unavailable
status = 503;
statusText = 'Service Unavailable';
}
else {
// Something else caused the error
errorMessage = `Error: ${error === null || error === void 0 ? void 0 : error.message}`;
status = 601;
statusText = (error === null || error === void 0 ? void 0 : error.message) || 'Unknown error';
}
console.error('Axios request error:', errorMessage);
return {
data: null,
status,
// statusText,
statusText: errorMessage || statusText || 'Unknown error',
};
}
/**
* Возвращает URL для указанного пути API и версии.
*
* @param apiPath - Путь API.
* @param apiVersion - Версия API.
* @returns URL для указанного пути API и версии.
*/
url(apiPath, apiVersion) {
if (apiPath.toLowerCase().startsWith('http')) {
return apiPath;
}
switch (apiVersion) {
case api.OFFICE:
return `${this._ENDPOINT_DOMAIN}/api/v1/office/${this.locale}${apiPath}`;
case api.V1:
return `${this._ENDPOINT_DOMAIN}/api/v1${apiPath}`;
case api.V2:
return `${this._ENDPOINT_DOMAIN}/api/v2${apiPath}`;
case api.LINE:
return `${this._ENDPOINT_DOMAIN}/api/line/${this.locale}${apiPath}`;
case api.LIVE:
return `${this._ENDPOINT_DOMAIN}/api/live/${this.locale}${apiPath}`;
case api.BASE:
return `${this._ENDPOINT_DOMAIN}`;
default:
return `${this._ENDPOINT_DOMAIN}/api${apiPath}`;
}
}
// #endregion Handlers --------------------------------------------------------------------
// #region AXIOS --------------------------------------------------------------------------
/**
* Выполняет HTTP-запрос с заданными параметрами.
* @param url - URL-адрес для выполнения запроса.
* @returns Объект, содержащий методы для настройки запроса и выполнения запроса.
*/
request(url) {
const queryStringHandler = this.queryStringHandler;
const axi = this.axi;
const axiosErrorHandler = this.axiosErrorHandler;
const statusHandler = (status, statusText) => {
if (status === 401) {
this.user = {};
this.token = undefined;
if (IS_DEV_MODE)
console.log('Status:', status, statusText);
}
};
const responseHandler = (response) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
// console.log('responseHandler:', response);
// console.log('Response body:', response.data);
// console.log('Response response?.config:', response?.config);
const xToken = (_a = response === null || response === void 0 ? void 0 : response.headers['x-token']) !== null && _a !== void 0 ? _a : null;
const urlPath = (_c = (_b = response === null || response === void 0 ? void 0 : response.request) === null || _b === void 0 ? void 0 : _b.path) !== null && _c !== void 0 ? _c : null;
// if (response?.data?.Error === 'Object reference not set to an instance of an object.') {
if ((_d = response === null || response === void 0 ? void 0 : response.data) === null || _d === void 0 ? void 0 : _d.Error) {
const Method = ((_f = (_e = response === null || response === void 0 ? void 0 : response.config) === null || _e === void 0 ? void 0 : _e.method) !== null && _f !== void 0 ? _f : '').toUpperCase();
const errorData = Object.assign(Object.assign(Object.assign({ method: Method, url: ((_g = response === null || response === void 0 ? void 0 : response.config) === null || _g === void 0 ? void 0 : _g.url) || '' }, (!!((_h = response === null || response === void 0 ? void 0 : response.config) === null || _h === void 0 ? void 0 : _h.params) ? { params: (_k = (_j = response === null || response === void 0 ? void 0 : response.config) === null || _j === void 0 ? void 0 : _j.params) !== null && _k !== void 0 ? _k : '' } : {})), (!!((_l = response === null || response === void 0 ? void 0 : response.config) === null || _l === void 0 ? void 0 : _l.data) ? { POST: (_o = (_m = response === null || response === void 0 ? void 0 : response.config) === null || _m === void 0 ? void 0 : _m.data) !== null && _o !== void 0 ? _o : '' } : {})), { error: (_p = response === null || response === void 0 ? void 0 : response.data) === null || _p === void 0 ? void 0 : _p.Error });
console.error(errorData);
}
if (IS_DEV_MODE && urlPath)
console.log(urlPath);
if (xToken) {
this.token = xToken;
if (IS_DEV_MODE)
console.log('isSinged:', this.isSinged + '\nX-Token:', xToken);
}
;
};
const now = Date.now();
const abortController = new AbortController();
const signal = setTimeout(() => {
abortController.abort();
}, this.maxTimeExecutionMs);
const requestConfig = {
url,
method: 'GET',
params: { _: now },
headers: Object.assign({}, (this.token ? { 'X-Token': this.token } : {})),
responseType: 'json',
signal: abortController.signal,
};
return {
/**
* Выполняет запрос с заданными параметрами.
* @param queryParams - Параметры запроса.
* @returns Экземпляр класса BetBoosterOfficeApi.
*/
query(queryParams = {}) {
const query = queryStringHandler(queryParams);
requestConfig.params = Object.assign(Object.assign({}, query), requestConfig.params);
return this;
},
/**
* Устанавливает заголовки запроса.
* @param headers - Объект с заголовками запроса.
* @returns Экземпляр класса BetBoosterOfficeApi.
*/
headers(headers = {}) {
requestConfig.headers = Object.assign(Object.assign({}, requestConfig.headers), headers);
return this;
},
/**
* Устанавливает метод запроса GET.
* @returns Экземпляр класса BetBoosterOfficeApi.
*/
GET() {
requestConfig.method = 'GET';
return this;
},
/**
* Устанавливает метод запроса POST.
* @param payload - Полезная нагрузка для запроса.
* @returns Экземпляр класса BetBoosterOfficeApi.
*/
POST(payload = {}) {
requestConfig.method = 'POST';
requestConfig.data = payload;
return this;
},
/**
* Устанавливает метод запроса PUT и устанавливает тело запроса.
* @param payload - Данные, которые будут отправлены в теле запроса.
* @returns Экземпляр класса BetBoosterOfficeApi с установленным методом запроса PUT и телом запроса.
*/
PUT(payload = {}) {
requestConfig.method = 'PUT';
requestConfig.data = payload;
return this;
},
/**
* Устанавливает метод запроса DELETE.
* @param payload Данные запроса в формате объекта или записи.
* @returns Экземпляр класса BetBoosterOfficeApi.
*/
DELETE(payload = {}) {
requestConfig.method = 'DELETE';
requestConfig.data = payload;
return this;
},
/**
* Выполняет запрос к API.
*
* @returns Объект, содержащий данные, статус и текст статуса ответа.
* ```
* { data, status, statusText }
* ```
*/
async exec() {
if (requestConfig.method !== 'GET') {
delete requestConfig.params._;
}
const response = axi.request(requestConfig)
.then(response => {
responseHandler(response);
return response;
})
.catch(axiosErrorHandler)
.finally(() => clearTimeout(signal));
const { data, status, statusText } = await response;
statusHandler(status, statusText);
return { data, status, statusText };
},
/**
* Получает значение.
* @returns Промис, который разрешается с данными.
*/
async value() {
const { data } = await this.exec();
await data;
}
};
}
/**
* Sends a GET request to the specified endpoint with optional query parameters and options.
* @param url - The endpoint to send the GET request to.
* @param queryParams - The query parameters to include in the request URL. Defaults to an empty object.
* @param headers - The options to include in the request. Defaults to an empty object.
* @returns A Promise that resolves to the response body of the GET request.
*/
async GET(url, queryParams = {}, headers = {}) {
const now = Date.now();
const abortController = new AbortController();
const signal = setTimeout(() => {
abortController.abort();
}, this.maxTimeExecutionMs);
const requestConfig = {
params: this.queryStringHandler(Object.assign(Object.assign({}, queryParams), { _: now })),
headers: Object.assign(Object.assign({}, (this.token ? { 'X-Token': this.token } : {})), (headers !== null && headers !== void 0 ? headers : {})),
responseType: 'json',
signal: abortController.signal,
};
const response = this.axi.get(url, requestConfig)
.then(response => {
this.responseHandler(response);
return response;
})
.catch(this.axiosErrorHandler)
.finally(() => clearTimeout(signal));
const { data, status, statusText } = await response;
this.statusHandler(status, statusText);
return data;
}
async POST(url, payload = {}, queryParams = {}, headers = {}) {
const abortController = new AbortController();
const signal = setTimeout(() => {
abortController.abort();
}, this.maxTimeExecutionMs);
const requestConfig = {
params: this.queryStringHandler(queryParams),
headers: Object.assign(Object.assign({}, (this.token ? { 'X-Token': this.token } : {})), (headers !== null && headers !== void 0 ? headers : {})),
responseType: 'json',
signal: abortController.signal,
};
const response = this.axi.post(url, payload, requestConfig)
.then(response => {
this.responseHandler(response);
return response;
})
.catch(this.axiosErrorHandler)
.finally(() => clearTimeout(signal));
const axiData = await response;
// console.log(axiData);
const { data, status, statusText } = axiData;
this.statusHandler(status, statusText);
return data;
}
async DELETE(url, payload = {}, queryParams = {}, headers = {}) {
const abortController = new AbortController();
const signal = setTimeout(() => {
abortController.abort();
}, this.maxTimeExecutionMs);
const requestConfig = {
params: this.queryStringHandler(queryParams),
headers: Object.assign(Object.assign({}, (this.token ? { 'X-Token': this.token } : {})), (headers !== null && headers !== void 0 ? headers : {})),
responseType: 'json',
signal: abortController.signal,
data: payload,
};
const response = this.axi.delete(url, requestConfig)
.then(response => {
this.responseHandler(response);
return response;
})
.catch(this.axiosErrorHandler)
.finally(() => clearTimeout(signal));
const { data, status, statusText } = await response;
this.statusHandler(status, statusText);
return data;
}
async PUT(url, payload = {}, queryParams = {}, headers = {}) {
const abortController = new AbortController();
const signal = setTimeout(() => {
abortController.abort();
}, this.maxTimeExecutionMs);
const requestConfig = {
params: this.queryStringHandler(queryParams),
headers: Object.assign(Object.assign({}, (this.token ? { 'X-Token': this.token } : {})), (headers !== null && headers !== void 0 ? headers : {})),
responseType: 'json',
signal: abortController.signal,
};
const response = this.axi.put(url, payload, requestConfig)
.then(response => {
this.responseHandler(response);
return response;
})
.catch(this.axiosErrorHandler)
.finally(() => clearTimeout(signal));
const { data, status, statusText } = await response;
this.statusHandler(status, statusText);
return data;
}
// #endregion AXIOS --------------------------------------------------------------------^^^
/**
* Асинхронно выполняет вход в систему.
* @description Если логин успешен, сохраняет токен в свойстве класса token
* и сохраняет объект, представляющий пользователя в свойстве класса user
* в последствии эти свойства используем для обработки запроса
* @param login Логин пользователя.
* @param password Пароль пользователя.
* @returns Объект, представляющий пользователя, если вход выполнен успешно. В противном случае, возвращает пустой объект.
*/
async login({ login, password }) {
const url = this.url(`/Login`, api.OFFICE);
const post = {
Login: login,
Password: password,
};
const res = await this.POST(url, post);
if (IS_DEV_MODE)
console.log(res);
const { Data } = res !== null && res !== void 0 ? res : {};
if (!Data && IS_DEV_MODE) {
console.log("\n```\n/account/LogIn:\n", res, "\n```\n");
}
if (Data && Data.UserId > 0) {
this.user = Data;
const token = Data['X-Token'];
this.token = token !== null && token !== void 0 ? token : null;
if (this.token) {
return this.user;
}
}
this.user = {};
return this.user;
}
/**
* Получает данные пользователя.
* @returns Данные пользователя или null, если пользователь не найден.
*/
async getUserData() {
const url = this.url(`/account/GetUserData`, api.V2);
const user = await this.GET(url);
if ((user === null || user === void 0 ? void 0 : user.UserId) > 0) {
this.user = user;
return user;
}
this.user = {};
return null;
}
async getOfficeUserData() {
const url = this.url(`/account/GetOfficeUserData`, api.V2);
const user = await this.GET(url);
if ((user === null || user === void 0 ? void 0 : user.UserId) > 0) {
this.user = user;
return user;
}
this.user = {};
return null;
}
// #region API Line --------------------------------------------------------------------
/**
* Returns the list of prematch sports
*
* @param minutes The number of minutes to consider for the data retrieval. Defaults to 0.
* @returns {Promise<Array<any>>} A promise that resolves to an array of line sports data.
*/
async getLineSports(minutes = 0) {
var _a;
// const url = this.url(`/sports/${minutes}`, api.LINE);
// +TODO Включить когда обновиться продакшен
const url = +minutes > 0
? this.url(`/sports/${minutes}`, api.LINE)
: this.url(`/allSports`, api.LINE);
const response = (_a = (await this.GET(url, {}, {}))) !== null && _a !== void 0 ? _a : [];
// console.log(JSON.stringify(response, null, 2));
return response;
}
/**
* Получает список стран для указанного идентификатора спорта.
* @param sportId - Идентификатор спорта.
* @param minutes - Опциональный параметр, количество минут.
* @returns Промис, который разрешается в массив объектов типа ICountry.
*/
async getCountriesList(sportId, minutes = 0) {
var _a;
const url = this.url(`/countries/sport${sportId}/${minutes}`, api.LINE);
// console.log(url)
return (_a = (await this.GET(url, {}, {}))) !== null && _a !== void 0 ? _a : [];
}
/**
* Retrieves prematch tournaments based on the specified sport ID, country ID, and minutes.
* @param sportId - The ID of the sport.
* @param countryId - The ID of the country.
* @param minutes - The number of minutes ago for which data is to be retrieved.
* @returns A promise that resolves to an array of prematch tournaments.
*/
async getPrematchTournaments(sportId, countryId, minutes = 0) {
var _a;
const url = this.url(`/tournaments/sport${sportId}/country${countryId}/${minutes}`, api.LINE);
// console.log(url)
return (_a = (await this.GET(url, {}, {}))) !== null && _a !== void 0 ? _a : [];
}
/**
* Retrieves prematch events based on the specified parameters.
* @param sportId - The ID of the sport.
* @param countryId - The ID of the country.
* @param tournamentId - The ID of the tournament.
* @param minutes - The number of minutes ago for which data is to be retrieved.
* @returns A Promise that resolves to an array of prematch events.
*/
async getPrematchEvents(sportId, countryId, tournamentId, minutes) {
var _a;
// ?TODO Хорошо бы сделать фильтр по нескольким турнирам.
const url = this.url(`/events/sport${sportId}/country${countryId}/tourney${tournamentId}/${minutes}`, api.LINE);
const list = (_a = (await this.GET(url, {}, {}))) !== null && _a !== void 0 ? _a : [];
return list;
}
/**
* Retrieves the hot prematch events
* @returns {Promise<Array<any>>} A promise that resolves to an array of hot events.
*/
async getHotEvents() {
var _a;
const url = this.url(`/hotevents`, api.LINE);
// console.log(url)
return (_a = (await this.GET(url, {}, {}))) !== null && _a !== void 0 ? _a : [];
}
/**
* Получает предматчевое событие по его ID.
* @param eventId - Идентификатор события.
* @returns Объект предматчевого события.
*/
async getEventPrematch(eventId) {
var _a;
const url = this.url(`/event/${eventId}`, api.LINE);
const list = (_a = (await this.GET(url, {}, {}))) !== null && _a !== void 0 ? _a : {};
// console.log(list);
return list;
}
/**
* Retrieves prematch tournaments based on the specified sport ID and minutes.
* @param sportId - The ID of the sport.
* @param minutes - The number of minutes ago for which data is to be retrieved.
* @returns A filtered list of prematch tournaments.
*/
async getPrematchTournamentsByMinutes(sportId = 0, minutes = 0) {
var _a;
const url = this.url(`/events/full/sport${sportId}/${minutes}`, api.LINE);
const list = (_a = (await this.GET(url, {}, {}))) !== null && _a !== void 0 ? _a : [];
return list;
// return list.filter((item: any) => (item?.EventsHeaders ?? []).length > 0)
}
/**
* Retrieves the headers of prematch tournaments based on the specified sport ID and minutes.
* @param sportId The ID of the sport. Defaults to 0 if not provided.
* @param minutes - The number of minutes ago for which data is to be retrieved.
* @returns A promise that resolves to an array of tournament headers.
*/
async getPrematchTournamentsHeadersByMinutes(sportId = 0, minutes = 0) {
var _a;
// const hours = Math.round(minutes / 60);
const url = this.url(`/tournaments/headers/sport${sportId}/${minutes}`, api.LINE);
const list = (_a = (await this.GET(url, {}, {}))) !== null && _a !== void 0 ? _a : [];
// console.log(list);
return list;
}
/**
* Sets or resets the live timestamp reset flag.
*
* @param value - Whether to enable live timestamp reset. Defaults to true.
*/
liveTimestampReset(value = true) {
this._liveTimestampReset = value;
}
// #endregion API Line --------------------------------------------------------------------
// #region API Live --------------------------------------------------------------------
/**
* Получает массив заголовков live событий с главными ставки.
* @description Для интервального выполнения запроса используется параметр ```this.liveTimestamp```
* который хранится в этом классе. После выполнения запроса, ```this.liveTimestamp```
* обновляется из ответа.
* @param requestFullEventsList - Флаг, указывающий, нужно ли запрашивать
* полный список событий или только изменения после предыдущего запроса.
* @param events - Массив ID live событий. В этом случае выбранные live события возвращаются со всеми ставками.
* @returns Промис, который разрешается в массив данных о live событиях.
*/
async getLive(requestFullEventsList = false, events = []) {
var _a;
let liveRecivedIsFullPackage = false;
if (requestFullEventsList || this._liveTimestampReset === true) {
this.liveTimestamp = 0;
this.liveTimestampReset(false);
}
const url = this.url(`/full/${this.liveTimestamp}/0`, api.LIVE);
const { data, status /* , statusText */ } = await this.request(url).GET().query({ events }).exec();
const { TimeStamp, LEvents, IsChanges, Error } = data !== null && data !== void 0 ? data : {};
if (IsChanges === false) {
liveRecivedIsFullPackage = true;
}
else {
liveRecivedIsFullPackage = false;
}
if (status === 200) {
this.liveTimestamp = (_a = TimeStamp !== null && TimeStamp !== void 0 ? TimeStamp : this.liveTimestamp) !== null && _a !== void 0 ? _a : 0;
}
else {
this.liveTimestamp = 0;
}
return Object.assign({ ts: +this.liveTimestamp, events: LEvents !== null && LEvents !== void 0 ? LEvents : [], isFullPackage: liveRecivedIsFullPackage }, (Error ? { Error } : {}));
}
/**
* Возвращает массив из одного полного лайв события со всеми ставками по ID .
* @param eventId - ID полного live события.
* @returns Массив с информацией о событии.
*/
async getLiveEventsAndFullEvent(eventId) {
var _a;
const url = this.url(`/bets/${eventId}`, api.LIVE);
const event = (_a = (await this.GET(url, {}, {}))) !== null && _a !== void 0 ? _a : {};
// console.log(list);
return [event];
}
/**
* Возвращает полное лайв событие со всеми ставками по ID .
* @param eventId - ID полного live события.
* @returns Массив с информацией о событии.
*/
async getLiveEventFull(eventId) {
const url = this.url(`/bets/${eventId}`, api.LIVE);
const { data /*, status , statusText */ } = await this.request(url).exec();
// console.log(data);
return data !== null && data !== void 0 ? data : null;
}
// #endregion API Live --------------------------------------------------------------------
// #region ---- API V2Betting --------------------------------------------------------------------
/**
* Получает ограничения на ставку.
* @returns Объект с минимальным и максимальным значением ограничений на ставки.
*/
async getBetsLimits() {
const url = this.url(`/betting/GetLimitations`, api.V2);
const res = await this.GET(url);
// console.log('getBetsLimits >>>> ', res);
return res !== null && res !== void 0 ? res : { Min: 0, Max: 0 };
// if (this.isSinged) {
// }
// return { Min: -Infinity, Max: Infinity };
}
/**
* Добавляет ставку в купон.
* @param basket - Корзина с информацией о ставке.
* @returns Результат операции добавления в бетслип или null, если операция не удалась.
*/
async addToBetslip(basket) {
basket.culture = this.locale;
const url = this.url(`/betting/AddToBetslip`, api.V2);
const res = await this.POST(url, basket);
return res !== null && res !== void 0 ? res : null;
}
/**
* Добавляет бонус в купон.
* @param odd - Коэффициент, к которому добавляется бонус.
* @returns Результат операции или null, если результат не определен.
*/
async addBonus(odd) {
const url = this.url(`/betting/AddBonus`, api.V2);
const res = await this.POST(url, {}, { odd });
console.log('addBonus >>>> ', res);
return res !== null && res !== void 0 ? res : null;
}
/**
* Удаляет бонус из купона.
* @returns {Promise<boolean>} Возвращает true, если бонус успешно удален, в противном случае возвращает false.
*/
async removeBonus() {
const url = this.url(`/betting/DeleteBonus`, api.V2);
const res = await this.POST(url);
console.log('removeBonus >>>> ', res);
return res !== null && res !== void 0 ? res : false;
}
/**
* Удаляет ставку из купона.
* @param basket - Объект, содержащий информацию о купоне.
* @returns Возвращает true, если элемент успешно удален, в противном случае возвращает false.
*/
async removeFromBetslip(basket) {
const url = this.url(`/betting/RemoveFromBetslip`, api.V2);
const res = await this.POST(url, basket);
return res || false;
}
/**
* Обновляет ставку в купоне.
* @param basket - Корзина с информацией о ставке.
* @returns Возвращает true, если ставка была успешно обновлена, в противном случае возвращает false.
*/
async updateBet(basket) {
basket.culture = this.locale;
const url = this.url(`/betting/UpdateBet`, api.V2);
const res = await this.POST(url, basket);
return res === null;
}
/**
* Получает информацию о билете.
* @description Требует авторизации.
* @returns {Promise<Betslip | null>} Объект с информацией о билете или null, если токен не установлен.
* @example
* ```typescript
{
BetslipType: 0,
Bets: [],
RecommendedAmount: 0,
bonuses: [
[ 'Koef', 9, 1.01 ],
[ 'Koef', 20, 1.02 ],
[ 'Koef', 50, 1.03 ],
[ 'Koef', 100, 1.04 ],
[ 'Koef', 200, 1.05 ],
[ 'Koef', 500, 1.06 ],
[ 'Kolvo', 5, 1.01 ],
[ 'Kolvo', 9, 1.02 ],
[ 'Kolvo', 22, 1.03 ],
[ 'Kolvo', 11, 1.04 ],
[ 'Kolvo', 13, 1.05 ],
[ 'Kolvo', 15, 1.06 ],
[ 'Perestavka', true, 1.03 ],
[ 'MinOdds', true, 1.02 ]
]
}
* ```
*/
async getBetslip() {
var _a, _b;
const url = this.url(`/betting/GetBetslip`, api.V2);
const res = await this.GET(url, {});
res['bonuses'] = this.convertBonuses((_a = res === null || res === void 0 ? void 0 : res.Bonus) !== null && _a !== void 0 ? _a : {});
(_b = res.Bets) !== null && _b !== void 0 ? _b : (res.Bets = []);
delete res.Bonus;
return res !== null && res !== void 0 ? res : {};
}
/**
* Очищает купон.
* @returns Промис, который разрешается в логическое значение, указывающее на успешность операции.
*/
async clearBetslip() {
const url = this.url(`/betting/ClearBetslip`, api.V2);
const res = await this.POST(url, {});
return res !== null && res !== void 0 ? res : false;
}
/**
* Изменяет тип купона.
* @param betslipType - Тип купона.
* @returns Возвращает true, если тип купона успешно изменен, в противном случае возвращает false.
*/
async changeBetslipType(betslipType) {
const url = this.url(`/betting/ChangeBetslipType`, api.V2);
const res = await this.POST(url, {}, { betslipType });
return res !== null && res !== void 0 ? res : false;
}
/**
* Создает купон для размещения ставки.
* @param betslip - Массив с информацией о ставках.
* @param amount - Сумма ставки.
* @param acceptCahngeCoefs - Флаг, указывающий, принимать ли изменения коэффициентов.
* @param systemIndex - Размер системы (например, из 3-х событий по 2, значит передаем 2). Значение по умолчанию: -1 (если не система).
* @returns Созданный купон для размещения ставки.
*/
createCoupon(betslip, amount, acceptCahngeCoefs, systemIndex = -1) {
var _a, _b, _c, _d, _e;
const coupon = {
betAmount: amount,
// "realAmount": amount,
// "bonusAmount": bonusSum,
// "totalCoef": totalOdds,
doAcceptOddsChanges: acceptCahngeCoefs,
statuses: {},
systemIndex: systemIndex, // systemIndex - размер системы (например из 3-х событий по 2, значит передаем 2) -1 если не система
};
for (let i = 0; i < betslip.length; i++) {
const v = betslip[i];
const betName = [(_a = v.LinesID) !== null && _a !== void 0 ? _a : 'null', (_b = v.BetVarID) !== null && _b !== void 0 ? _b : 'null', (_c = v.HandSize) !== null && _c !== void 0 ? _c : 'null', (_d = v.Add1) !== null && _d !== void 0 ? _d : 'null', (_e = v.Add2) !== null && _e !== void 0 ? _e : 'null'].join('_');
coupon.statuses[betName] = true;
}
return coupon;
}
/**
* Ставит ставку.
* @param payload - Параметры размещения ставки.
* @returns Результат размещения ставки.
*/
async placeCoupon(payload) {
if (this.isSinged) {
const url = this.url(`/betting/PlaceBet`, api.V2);
const res = await this.POST(url, payload);
return res;
}
return;
}
/**
* Удаляет купон по указанному коду в течении 10 минут.
*
* @param {string} code - Код купона, который необходимо удалить.
* @returns {Promise<any | null>} Объект ответа или null, если пользователь не авторизован.
*/
async deleteCoupon(code) {
const url = this.url(`/betting/DeleteBet`, api.V2);
const { data, status, statusText } = await this.request(url).query({ code }).exec();
// console.log('deleteCoupon data:', data , status , statusText);
return this.responseHandlerData(data, status, statusText);
}
/**
* Устанавливает настройки корзины ставок.
* @param betslipSettings - Настройки купона ставок.
* @returns Массив результатов или пустой массив, если пользователь не авторизован.
*/
async setBetslipSettings(betslipSettings) {
if (this.isSinged) {
const url = this.url(`/betting/SetBetslipSettings`, api.V2);
const res = await this.POST(url, betslipSettings);
return res !== null && res !== void 0 ? res : [];
}
return [];
}
/**
* Получает список ставок пользователя, доступных для кэшаута.
* @returns Список ставок пользователя, доступных для кэшаута.
*/
async getUserCashoutBets() {
// !TODO getUserCashoutBets - проверить
if (this.isSinged) {
const url = this.url(`/betting/GetUserCashoutBets`, api.V2);
const res = await this.GET(url, { culture: this.locale });
return res !== null && res !== void 0 ? res : [];
}
return [];
}
/**
* Метот делает попытку сделать CashOut для ставки
* @param betId - ID ставки.
* @returns Объект с ошибками, если возникли ошибки при выполнении запроса, или null, если запрос выполнен успешно.
*/
async returnCashOutBet(betId) {
if (this.isSinged) {
const url = this.url(`/betting/CashOutReturnBet`, api.V2);
const res = await this.POST(url, {}, { betId });
return res !== null && res !== void 0 ? res : null;
}
return null;
}
async payBet(payload) {
if (this.isSinged) {
const url = this.url(`/betting/PayBet`, api.V2);
const res = await this.POST(url, {}, payload);
return res !== null && res !== void 0 ? res : null;
}
return null;
}
// #endregion ---- API V2Betting --------------------------------------------------------------------
/**
* Retrieves the user's balance.
* @returns A promise that resolves to the user's balance.
*/
async balance() {
if (this.isSinged) {
const url = this.url(`/account/GetUserBalance`, api.V2);
const res = await this.GET(url);
// console.log('balance:', res);
return res !== null && res !== void 0 ? res : {};
}
return {};
}
/**
*
* @returns
* item1 = Лимит кассы на постановку ставки
* item2 = Frozzen balanse
* ```
* { item1: 10000, currence1: '₴', item2: 2371, currence2: '₴' }
* ```
*/
async balanceCashPoint() {
if (this.isSinged) {
const url = this.url(`/account/GetFinPointBalance`, api.V2);
const { data, status, statusText } = await this.request(url).exec();
return { data, status, statusText };
}
return { data: null, status: 401, statusText: 'Unauthorized' };
}
/**
* Возвращает подробности ставки по номеру купона
* @param code
* @returns Объект, содержащий данные, статус и текст статуса ответа.
* ```
* { data, status, statusText }
*
* ```
*
*/
async getBetByCoupon(code, locale) {
var _a;
const url = this.url(`/betting/GetBet`, api.V2);
// const url = this.url(`https://exam_plex.com`, api.V2);
const lLocale = (_a = locale !== null && locale !== void 0 ? locale : this.locale) !== null && _a !== void 0 ? _a : I.ELocales.en;
const query = {
code,
culture: lLocale,
};
const { data, status, statusText } = await this.request(url).query(query).exec();
return { data, status, statusText };
}
/**
* Выполняет погашение ставки.
* @param payload - Параметры для погашения ставки.
* ```
* {
* BetId: number;
* AmountOut: number;
* }
* ```
* @returns Результат выполнения погашения ставки.
*/
async redeemTheBet(payload) {
const url = this.url(`/betting/RedeemTheBet`, api.V2);
const { data, status, statusText } = await this.request(url).POST(payload).exec();
return { data, status, statusText };
}
async getLimitForPoint() {
const url = this.url(`/account/GetLimitForPoint`, api.V2);
const res = await this.GET(url);
// console.log('getAllHandbooks:', res);
return res !== null && res !== void 0 ? res : {};
}
/**
* Выполняет выход пользователя из системы.
* @returns Объект, содержащий информацию об успешности выхода и статусе авторизации пользователя.
*/
async logout() {
const url = this.url(`/Logout`, api.OFFICE);
const res = await this.GET(url);
const resOk = (res === false);
this.user = {};
this.token = undefined;
return {
ok: resOk,
isLogged: resOk ? res : false,
};
}
/**
* Изменяет пароль пользователя.
* @param payload - Объект, содержащий данные для изменения пароля. Doc: https://betseller.gitlab.io/bb-api-platforma/interfaces/Types.IChangePasswordOfficePayload.html
* @returns Возвращает `null` в случае, если пользователь не авторизован.
*/
async changePassword(payload) {
var _a;
if (this.isSinged) {
const url = this.url(`/ChangePassword`, api.OFFICE);
const res = await this.POST(url, payload);
// console.log(res);
return {
ok: !res.IsError || false,
status: (_a = res.ErrorCode) !== null && _a !== void 0 ? _a : 5001
};
}
return {
ok: false,
status: 5001
};
}
async setRemoteLanguage(lang) {
lang !== null && lang !== void 0 ? lang : (lang = this.lang);
return await this.setLanguageRemoteLocale(lang);
}
/**
* Получает содержимое ставки по идентификатору.
* @param betId - Идентификатор ставки.
* @returns Содержимое ставки.
*/
async getBetContent(betId) {
const payload = {
id: betId,
culture: this.locale
};
if (this.isSinged) {
const url = this.url(`/account/GetBetContent`, api.V2);
const res = await this.GET(url, payload);
return res;
}
return {};
}
/**
* Получает содержимое ставки по идентификатору.
* @param betId - Идентификатор ставки.
* @returns Содержимое ставки.
*/
async getBetContentByLang(betId, lang = 'en') {
const payload = {
id: betId,
culture: this._locales[lang] || 'en-US'
};
if (this.isSinged) {
const url = this.url(`/account/GetBetContent`, api.V2);
const res = await this.GET(url, payload);
return res;
}
return {};
}
/**
* Получает ставки пользователя.
* @param payload - Параметры запроса.
* @returns Промис, который разрешается с результатом запроса.
* @note Размер страницы должен быть не больше 20 строк на страни