UNPKG

bb-api-platforma

Version:

API module for BetBooster Platform

1,181 lines 93.5 kB
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 строк на страни