@withqwerty/sportmonks-typescript-sdk
Version:
TypeScript SDK for SportMonks Football API v3
1,636 lines (1,613 loc) • 56.9 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var axios = require('axios');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var axios__default = /*#__PURE__*/_interopDefault(axios);
// src/client.ts
// src/core/errors.ts
var SportMonksError = class extends Error {
constructor(message, statusCode, apiMessage, errors, errorType) {
super(message);
this.statusCode = statusCode;
this.apiMessage = apiMessage;
this.errors = errors;
this.errorType = errorType;
this.name = "SportMonksError";
}
/**
* Check if this is a network/connection error
*/
isNetworkError() {
return this.errorType === "NETWORK_ERROR";
}
/**
* Check if this is an authentication error
*/
isAuthError() {
return this.errorType === "AUTH_ERROR";
}
/**
* Check if this is a rate limit error
*/
isRateLimitError() {
return this.errorType === "RATE_LIMIT_ERROR";
}
/**
* Get a user-friendly error message
*/
getUserMessage() {
switch (this.errorType) {
case "AUTH_ERROR":
return "Authentication failed. Please check your API key is valid and has the necessary permissions.";
case "NETWORK_ERROR":
return "Unable to connect to SportMonks API. Please check your network connection.";
case "RATE_LIMIT_ERROR":
return "API rate limit exceeded. Please wait before making more requests.";
case "SERVER_ERROR":
return "SportMonks API server error. Please try again later.";
case "CLIENT_ERROR":
return this.message;
default:
return "An unexpected error occurred.";
}
}
};
// src/core/base-resource.ts
var BaseResource = class {
client;
basePath;
includeSeparator;
retryOptions;
constructor(client, basePath, includeSeparator = ";", retryOptions = {}) {
this.client = client;
this.basePath = basePath;
this.includeSeparator = includeSeparator;
this.retryOptions = {
maxRetries: retryOptions.maxRetries || 0,
retryDelay: retryOptions.retryDelay || 1e3,
maxRetryDelay: retryOptions.maxRetryDelay || 3e4,
retryOnRateLimit: retryOptions.retryOnRateLimit ?? true,
retryStatusCodes: retryOptions.retryStatusCodes || [502, 503, 504]
};
}
/**
* Make a request to the API with optional retry logic
*/
async request(endpoint, params = {}) {
const url = `${this.basePath}${endpoint}`;
let lastError;
for (let attempt = 0; attempt <= this.retryOptions.maxRetries; attempt++) {
try {
const response = await this.client.get(url, { params });
return response.data;
} catch (error) {
lastError = error;
if (!this.shouldRetry(error, attempt)) {
throw this.handleError(error, url);
}
const delay = Math.min(
this.retryOptions.retryDelay * Math.pow(2, attempt),
this.retryOptions.maxRetryDelay
);
if (axios__default.default.isAxiosError(error) && error.response?.status === 429) {
const responseData = error.response.data;
const rateLimit = responseData?.rate_limit;
const resetIn = rateLimit?.resets_in_seconds;
if (resetIn) {
await this.sleep(resetIn * 1e3);
continue;
}
}
await this.sleep(delay);
}
}
throw this.handleError(lastError, url);
}
/**
* Determine if a request should be retried
*/
shouldRetry(error, attempt) {
if (attempt >= this.retryOptions.maxRetries) {
return false;
}
if (!axios__default.default.isAxiosError(error)) {
return false;
}
const status = error.response?.status;
if (!status) {
return true;
}
if (status === 429 && this.retryOptions.retryOnRateLimit) {
return true;
}
return this.retryOptions.retryStatusCodes.includes(status);
}
/**
* Handle and transform errors
*/
handleError(error, url) {
if (axios__default.default.isAxiosError(error)) {
const errorData = error.response?.data;
const status = error.response?.status;
let errorType;
if (!error.response) {
errorType = "NETWORK_ERROR";
let message2 = "Network error";
if (error.code === "ECONNREFUSED") {
message2 = "Connection refused. The server may be down or unreachable.";
} else if (error.code === "ENOTFOUND") {
message2 = "Server not found. Please check the API URL.";
} else if (error.code === "ETIMEDOUT") {
message2 = "Request timeout. The server is not responding.";
} else if (error.message) {
message2 = `Network error: ${error.message}`;
}
return new SportMonksError(message2, void 0, void 0, void 0, errorType);
}
let message = errorData?.message || error.message;
if (status === 401 || status === 403) {
errorType = "AUTH_ERROR";
message = errorData?.message || "Authentication failed. Invalid or missing API key.";
} else if (status === 404) {
errorType = "CLIENT_ERROR";
message = errorData?.message || `Resource not found: ${url}`;
} else if (status === 429) {
errorType = "RATE_LIMIT_ERROR";
const rateLimit = errorData?.rate_limit;
const resetIn = rateLimit?.resets_in_seconds;
message = resetIn ? `Rate limit exceeded. Resets in ${resetIn} seconds.` : "Rate limit exceeded. Please wait before making more requests.";
} else if (status && status >= 500) {
errorType = "SERVER_ERROR";
message = errorData?.message || "Server error. Please try again later.";
} else if (status && status >= 400) {
errorType = "CLIENT_ERROR";
}
return new SportMonksError(
message,
status,
errorData?.message,
errorData?.errors,
errorType
);
}
return new SportMonksError(
error.message || "Unknown error occurred",
void 0,
void 0,
void 0,
"CLIENT_ERROR"
);
}
/**
* Sleep for a specified number of milliseconds
*/
sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
};
// src/core/query-builder.ts
var QueryBuilder = class {
resource;
endpoint;
queryParams = {};
includeParams = [];
selectFields = [];
filterParams = {};
orderParams = [];
hasParams = [];
constructor(resource, endpoint) {
this.resource = resource;
this.endpoint = endpoint;
}
/**
* Include related resources in the response
* @param includes Array of relationship names, dot notation for nested includes, or field selection
* @example .include(['country', 'seasons.stages'])
* @example .include(['lineups:player_name', 'events:player_name,related_player_name,minute'])
* @example .include(['lineups;events;participants']) // Multiple includes with semicolon
*/
include(includes) {
if (typeof includes === "string") {
this.includeParams.push(includes);
} else {
this.includeParams = [.../* @__PURE__ */ new Set([...this.includeParams, ...includes])];
}
return this;
}
/**
* Include a relation with specific field selection
* @param relation The relation name
* @param fields Array of fields to select from the relation
* @example .includeFields('lineups', ['player_name', 'jersey_number'])
* @example .includeFields('events', ['player_name', 'related_player_name', 'minute'])
*/
includeFields(relation, fields) {
const fieldsString = fields.join(",");
this.includeParams.push(`${relation}:${fieldsString}`);
return this;
}
/**
* Select specific fields to include in the response
* @param fields Array of field names
* @example .select(['id', 'name', 'country_id'])
*/
select(fields) {
this.selectFields = [.../* @__PURE__ */ new Set([...this.selectFields, ...fields])];
return this;
}
/**
* Add a filter parameter to the request
* @example .filter('name', 'Premier League')
* @example .filter('active', true)
* @example .filter('eventTypes', [15, 16]) // Multiple values
*/
filter(key, value) {
if (Array.isArray(value)) {
this.filterParams[key] = value.join(",");
} else {
this.filterParams[key] = value;
}
return this;
}
/**
* Add multiple filters at once
* @example .filters({ active: true, country_id: 462 })
*/
filters(filters) {
this.filterParams = { ...this.filterParams, ...filters };
return this;
}
/**
* Add sorting to the results
* @param field Field name with optional - prefix for descending
* @example .orderBy('name') or .orderBy('-created_at')
*/
orderBy(field) {
this.orderParams.push(field);
return this;
}
/**
* Filter results that have specific relationships
* @param relationships Array of relationship names
* @example .has(['seasons'])
*/
has(relationships) {
this.hasParams = [.../* @__PURE__ */ new Set([...this.hasParams, ...relationships])];
return this;
}
/**
* Set the page number for paginated results
*/
page(page) {
this.queryParams.page = page;
return this;
}
/**
* Set the number of items per page
*/
limit(limit) {
this.queryParams.limit = limit;
return this;
}
/**
* Set the number of items per page (alias for limit)
*/
perPage(perPage) {
return this.limit(perPage);
}
/**
* Execute the API request and return the results
*/
async get() {
if (this.includeParams.length > 0) {
this.queryParams.include = this.includeParams.join(this.resource["includeSeparator"]);
}
if (this.selectFields.length > 0) {
this.queryParams.select = this.selectFields.join(",");
}
if (Object.keys(this.filterParams).length > 0) {
const filterStrings = Object.entries(this.filterParams).map(([key, value]) => {
return `${key}:${value}`;
});
this.queryParams.filters = filterStrings.join(";");
}
if (this.orderParams.length > 0) {
this.queryParams.order = this.orderParams.join(",");
}
if (this.hasParams.length > 0) {
this.queryParams.has = this.hasParams.join(",");
}
if (this.queryParams.limit) {
this.queryParams.per_page = this.queryParams.limit;
delete this.queryParams.limit;
}
return this.resource["request"](this.endpoint, this.queryParams);
}
/**
* Build complex includes with SportMonks syntax
* @param includes Object defining includes with optional field selection
* @example .withIncludes({
* lineups: ['player_name', 'jersey_number'],
* events: ['player_name', 'related_player_name', 'minute'],
* participants: true // Include all fields
* })
*/
withIncludes(includes) {
Object.entries(includes).forEach(([relation, fields]) => {
if (fields === true) {
this.includeParams.push(relation);
} else if (Array.isArray(fields) && fields.length > 0) {
this.includeParams.push(`${relation}:${fields.join(",")}`);
}
});
return this;
}
/**
* Get all pages of results (be careful with rate limits!)
*/
async getAll() {
const results = [];
let currentPage = 1;
let hasMore = true;
while (hasMore) {
this.page(currentPage);
const response = await this.get();
if (response.data) {
results.push(...Array.isArray(response.data) ? response.data : [response.data]);
}
hasMore = response.pagination?.has_more || false;
currentPage++;
}
return results;
}
};
// src/utils/validators.ts
function validateDateFormat(date) {
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
if (!dateRegex.test(date)) {
throw new Error(`Invalid date format: ${date}. Expected YYYY-MM-DD`);
}
const dateObj = new Date(date);
if (isNaN(dateObj.getTime())) {
throw new Error(`Invalid date: ${date}`);
}
}
function validateDateRange(startDate, endDate) {
validateDateFormat(startDate);
validateDateFormat(endDate);
const start = new Date(startDate);
const end = new Date(endDate);
if (start > end) {
throw new Error(`Invalid date range: start date (${startDate}) is after end date (${endDate})`);
}
const oneYear = 365 * 24 * 60 * 60 * 1e3;
if (end.getTime() - start.getTime() > oneYear) {
throw new Error("Date range cannot exceed 1 year");
}
}
function formatDate(date) {
const dateObj = typeof date === "string" ? new Date(date) : date;
if (isNaN(dateObj.getTime())) {
throw new Error("Invalid date provided");
}
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, "0");
const day = String(dateObj.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
function getToday() {
return formatDate(/* @__PURE__ */ new Date());
}
function getDaysFromNow(days) {
const date = /* @__PURE__ */ new Date();
date.setDate(date.getDate() + days);
return formatDate(date);
}
function getDaysAgo(days) {
return getDaysFromNow(-days);
}
function validateId(id, name = "ID") {
const numId = typeof id === "string" ? parseInt(id, 10) : id;
if (isNaN(numId) || numId <= 0) {
throw new Error(`Invalid ${name}: ${id}. Must be a positive number`);
}
return numId;
}
function validateIds(ids, name = "IDs") {
if (!Array.isArray(ids) || ids.length === 0) {
throw new Error(`${name} must be a non-empty array`);
}
return ids.map((id, index) => {
try {
return validateId(id, `${name}[${index}]`);
} catch {
throw new Error(`Invalid ${name}[${index}]: ${id}`);
}
});
}
function validateSearchQuery(query, minLength = 3) {
if (typeof query !== "string") {
throw new Error("Search query must be a string");
}
const trimmed = query.trim();
if (trimmed.length === 0) {
throw new Error("Invalid search query");
}
if (trimmed.length < minLength) {
throw new Error(`Search query must be at least ${minLength} characters`);
}
return trimmed;
}
function validatePagination(page, perPage) {
if (page !== void 0) {
if (!Number.isInteger(page) || page < 1) {
throw new Error("Page must be a positive integer");
}
}
if (perPage !== void 0) {
if (!Number.isInteger(perPage) || perPage < 1 || perPage > 100) {
throw new Error("Per page must be an integer between 1 and 100");
}
}
}
function validateEnum(value, enumObject, name) {
const values = Object.values(enumObject);
if (!values.includes(value)) {
throw new Error(`Invalid ${name}: ${String(value)}. Must be one of: ${values.join(", ")}`);
}
return value;
}
function sanitizeUrlParam(param) {
return encodeURIComponent(param.trim());
}
function parseJsonSafely(json) {
try {
return JSON.parse(json);
} catch {
throw new Error("Invalid JSON response from API");
}
}
// src/resources/leagues.ts
var LeaguesResource = class extends BaseResource {
/**
* Get all leagues
* @example
* const leagues = await api.leagues.all()
* .include(['country', 'currentSeason'])
* .filter('active', true)
* .orderBy('name')
* .get();
*/
all() {
return new QueryBuilder(this, "");
}
/**
* Get a league by ID
* @param id The league ID
* @example
* const league = await api.leagues.byId(271)
* .include(['country', 'seasons', 'stages'])
* .get();
*/
byId(id) {
return new QueryBuilder(this, `/${id}`);
}
/**
* Get leagues by country ID
* @param countryId The country ID
* @example
* const leagues = await api.leagues.byCountry(462)
* .filter('active', true)
* .get();
*/
byCountry(countryId) {
return new QueryBuilder(this, `/countries/${countryId}`);
}
/**
* Search leagues by name
* @param query The search query
* @example
* const leagues = await api.leagues.search('premier')
* .include(['country'])
* .get();
*/
search(query) {
const encodedQuery = encodeURIComponent(query);
return new QueryBuilder(this, `/search/${encodedQuery}`);
}
/**
* Get leagues with live fixtures
* @example
* const liveLeagues = await api.leagues.live()
* .include(['fixtures'])
* .get();
*/
live() {
return new QueryBuilder(this, "/live");
}
/**
* Get leagues by fixture date
* @param date Date in YYYY-MM-DD format
* @example
* const leagues = await api.leagues.byDate('2024-01-15')
* .include(['fixtures'])
* .get();
*/
byDate(date) {
validateDateFormat(date);
return new QueryBuilder(this, `/date/${date}`);
}
/**
* Get all leagues for a team (historical and current)
* @param teamId The team ID
* @example
* const leagues = await api.leagues.byTeam(1)
* .include(['seasons'])
* .get();
*/
byTeam(teamId) {
return new QueryBuilder(this, `/teams/${teamId}`);
}
/**
* Get current leagues for a team
* @param teamId The team ID
* @example
* const currentLeagues = await api.leagues.currentByTeam(1)
* .include(['currentSeason'])
* .get();
*/
currentByTeam(teamId) {
return new QueryBuilder(this, `/teams/${teamId}/current`);
}
};
// src/resources/teams.ts
var TeamsResource = class extends BaseResource {
/**
* Get all teams
* @returns QueryBuilder for chaining
*/
all() {
return new QueryBuilder(this, "");
}
/**
* Get a team by ID
* @param id - The team ID
* @returns QueryBuilder for chaining
*/
byId(id) {
return new QueryBuilder(this, `/${id}`);
}
/**
* Get teams by country ID
* @param countryId - The country ID
* @returns QueryBuilder for chaining
*/
byCountry(countryId) {
return new QueryBuilder(this, `/countries/${countryId}`);
}
/**
* Get teams by season ID
* @param seasonId - The season ID
* @returns QueryBuilder for chaining
*/
bySeason(seasonId) {
return new QueryBuilder(this, `/seasons/${seasonId}`);
}
/**
* Search for teams by name
* @param searchQuery - The search query
* @returns QueryBuilder for chaining
*/
search(searchQuery) {
const encodedQuery = encodeURIComponent(searchQuery);
return new QueryBuilder(this, `/search/${encodedQuery}`);
}
/**
* Get squad for a team. If seasonId is provided, fetch squad for that season.
* @param teamId Team ID
* @param seasonId Optional season ID
* @example
* // Current squad
* const current = await client.teams.squad(1).include(['player']).get()
* // Squad for season 2023/24
* const historical = await client.teams.squad(1, 21646).include(['player']).get()
*/
squad(teamId, seasonId) {
if (seasonId) {
return this.squadBySeason(seasonId, teamId);
}
const squadResource = Object.create(this);
squadResource.basePath = "/football";
return new QueryBuilder(squadResource, `/squads/teams/${teamId}`);
}
/**
* Get squad for a team in a specific season.
* @param seasonId Season ID
* @param teamId Team ID
*/
squadBySeason(seasonId, teamId) {
const squadResource = Object.create(this);
squadResource.basePath = "/football";
return new QueryBuilder(
squadResource,
`/squads/seasons/${seasonId}/teams/${teamId}`
);
}
};
// src/resources/players.ts
var PlayersResource = class extends BaseResource {
/**
* Get all players
* @returns QueryBuilder for chaining
*/
all() {
return new QueryBuilder(this, "");
}
/**
* Get a player by ID
* @param id - The player ID
* @returns QueryBuilder for chaining
*/
byId(id) {
const validatedId = validateId(id, "ID");
return new QueryBuilder(this, `/${validatedId}`);
}
/**
* Get players by country ID
* @param countryId - The country ID
* @returns QueryBuilder for chaining
*/
byCountry(countryId) {
const validatedId = validateId(countryId, "Country ID");
return new QueryBuilder(this, `/countries/${validatedId}`);
}
/**
* Search for players by name
* @param searchQuery - The search query
* @returns QueryBuilder for chaining
*/
search(searchQuery) {
const validatedQuery = validateSearchQuery(searchQuery, 2);
const encodedQuery = encodeURIComponent(validatedQuery);
return new QueryBuilder(this, `/search/${encodedQuery}`);
}
/**
* Get the latest updated players
* @returns QueryBuilder for chaining
*/
latest() {
return new QueryBuilder(this, "/latest");
}
/**
* Get statistics for a player.
* @param playerId Player ID
* @example
* const stats = await client.players.statistics(278).get()
*/
statistics(playerId) {
return new QueryBuilder(this, `/${playerId}/statistics`);
}
/**
* Get statistics for a player in a specific season.
* @param playerId Player ID
* @param seasonId Season ID
*/
statisticsBySeason(playerId, seasonId) {
return this.statistics(playerId).filter("season_id", seasonId);
}
};
// src/resources/standings.ts
var StandingsResource = class extends BaseResource {
/**
* Get all standings
* Note: This endpoint requires season_id filter
* @example
* const standings = await api.standings.all()
* .filter('season_id', 19735)
* .include(['participant', 'league'])
* .get();
*/
all() {
return new QueryBuilder(this, "");
}
/**
* Get standings by season ID
* @param seasonId The season ID
* @example
* const standings = await api.standings.bySeason(19735)
* .include(['participant.country'])
* .get();
*/
bySeason(seasonId) {
return new QueryBuilder(this, `/seasons/${seasonId}`);
}
/**
* Get standings by round ID
* @param roundId The round ID
* @example
* const standings = await api.standings.byRound(274719)
* .include(['participant'])
* .get();
*/
byRound(roundId) {
return new QueryBuilder(this, `/rounds/${roundId}`);
}
/**
* Get standing corrections by season ID
* @param seasonId The season ID
* @example
* const corrections = await api.standings.correctionsBySeason(19735)
* .include(['participant'])
* .get();
*/
correctionsBySeason(seasonId) {
return new QueryBuilder(
this,
`/corrections/seasons/${seasonId}`
);
}
/**
* Get live standings by league ID
* @param leagueId The league ID
* @example
* const liveStandings = await api.standings.liveByLeague(8)
* .include(['participant'])
* .get();
*/
liveByLeague(leagueId) {
return new QueryBuilder(this, `/live/leagues/${leagueId}`);
}
};
// src/resources/livescores.ts
var LivescoresResource = class extends BaseResource {
/**
* Get all inplay fixtures (currently being played)
* @example
* const inplayMatches = await api.livescores.inplay()
* .include(['league', 'participants', 'scores', 'state'])
* .get();
*/
inplay() {
return new QueryBuilder(this, "/inplay");
}
/**
* Get all livescores (fixtures starting within 15 minutes)
* @example
* const upcomingMatches = await api.livescores.all()
* .include(['league', 'participants', 'venue'])
* .filter('leagues', '8,564') // Filter by league IDs
* .get();
*/
all() {
return new QueryBuilder(this, "");
}
/**
* Get latest updated livescores (updated within 10 seconds)
* @example
* const latestUpdates = await api.livescores.latest()
* .include(['events.type', 'scores', 'participants'])
* .get();
*/
latest() {
return new QueryBuilder(this, "/latest");
}
};
// src/resources/coaches.ts
var CoachesResource = class extends BaseResource {
/**
* Get all coaches
* @example
* const coaches = await api.coaches.all()
* .include(['country', 'nationality', 'teams'])
* .orderBy('name')
* .get();
*/
all() {
return new QueryBuilder(this, "");
}
/**
* Get a coach by ID
* @param id The coach ID
* @example
* const coach = await api.coaches.byId(123)
* .include(['country', 'nationality', 'teams'])
* .get();
*/
byId(id) {
return new QueryBuilder(this, `/${id}`);
}
/**
* Get coaches by country ID
* @param countryId The country ID
* @example
* const coaches = await api.coaches.byCountry(462)
* .include(['teams'])
* .get();
*/
byCountry(countryId) {
return new QueryBuilder(this, `/countries/${countryId}`);
}
/**
* Search coaches by name
* @param query The search query
* @example
* const coaches = await api.coaches.search('mourinho')
* .include(['teams'])
* .get();
*/
search(query) {
const encodedQuery = encodeURIComponent(query);
return new QueryBuilder(this, `/search/${encodedQuery}`);
}
/**
* Get last updated coaches (updated in the past two hours)
* @example
* const recentlyUpdated = await api.coaches.latest()
* .include(['teams'])
* .get();
*/
latest() {
return new QueryBuilder(this, "/latest");
}
};
// src/resources/referees.ts
var RefereesResource = class extends BaseResource {
/**
* Get all referees
* @example
* const referees = await api.referees.all()
* .include(['country'])
* .page(1)
* .limit(25)
* .get();
*/
all() {
return new QueryBuilder(this, "");
}
/**
* Get referee by ID
* @param refereeId The referee ID
* @example
* const referee = await api.referees.byId(1)
* .include(['country', 'fixtures'])
* .get();
*/
byId(refereeId) {
return new QueryBuilder(this, `/${refereeId}`);
}
/**
* Get referees by country ID
* @param countryId The country ID
* @example
* const referees = await api.referees.byCountry(1161)
* .include(['country'])
* .get();
*/
byCountry(countryId) {
return new QueryBuilder(this, `/countries/${countryId}`);
}
/**
* Get referees by season ID
* @param seasonId The season ID
* @example
* const referees = await api.referees.bySeason(19735)
* .include(['country'])
* .get();
*/
bySeason(seasonId) {
return new QueryBuilder(this, `/seasons/${seasonId}`);
}
/**
* Search referees by name
* @param searchQuery The search query (minimum 3 characters)
* @example
* const referees = await api.referees.search('Michael Oliver')
* .include(['country'])
* .get();
*/
search(searchQuery) {
if (searchQuery.length < 3) {
throw new Error("Search query must be at least 3 characters long");
}
return new QueryBuilder(
this,
`/search/${encodeURIComponent(searchQuery)}`
);
}
};
// src/resources/transfers.ts
var TransfersResource = class extends BaseResource {
/**
* Get all transfers
*
* @example
* ```typescript
* const transfers = await client.transfers.all()
* .include(['player', 'fromteam', 'toteam', 'type'])
* .limit(25)
* .get();
* ```
*/
all() {
return new QueryBuilder(this, "");
}
/**
* Get a transfer by ID
*
* @param id - The transfer ID
*
* @example
* ```typescript
* const transfer = await client.transfers.byId(123)
* .include(['player', 'fromteam', 'toteam', 'type'])
* .get();
* ```
*/
byId(id) {
return new QueryBuilder(this, `/${id}`);
}
/**
* Get latest transfers
*
* @example
* ```typescript
* const latestTransfers = await client.transfers.latest()
* .include(['player', 'fromteam', 'toteam'])
* .limit(50)
* .get();
* ```
*/
latest() {
return new QueryBuilder(this, "/latest");
}
/**
* Get transfers between a date range
*
* @param startDate - Start date in YYYY-MM-DD format
* @param endDate - End date in YYYY-MM-DD format
*
* @example
* ```typescript
* const transfers = await client.transfers.between('2024-01-01', '2024-01-31')
* .include(['player', 'fromteam', 'toteam', 'type'])
* .filter('completed', 1)
* .get();
* ```
*/
between(startDate, endDate) {
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
if (!dateRegex.test(startDate) || !dateRegex.test(endDate)) {
throw new Error("Dates must be in YYYY-MM-DD format");
}
return new QueryBuilder(this, `/between/${startDate}/${endDate}`);
}
/**
* Get transfers by team ID (both incoming and outgoing)
*
* @param teamId - The team ID
*
* @example
* ```typescript
* // Get all transfers for Manchester United
* const transfers = await client.transfers.byTeam(14)
* .include(['player', 'fromteam', 'toteam', 'type'])
* .filter('completed', 1)
* .get();
* ```
*/
byTeam(teamId) {
return new QueryBuilder(this, `/teams/${teamId}`);
}
/**
* Get transfers by player ID
*
* @param playerId - The player ID
*
* @example
* ```typescript
* const playerTransfers = await client.transfers.byPlayer(12345)
* .include(['fromteam', 'toteam', 'type'])
* .get();
* ```
*/
byPlayer(playerId) {
return new QueryBuilder(this, `/players/${playerId}`);
}
};
// src/resources/venues.ts
var VenuesResource = class extends BaseResource {
/**
* Get all venues
* @example
* const venues = await api.venues.all()
* .include(['country'])
* .page(1)
* .get();
*/
all() {
return new QueryBuilder(this, "");
}
/**
* Get a venue by ID
* @param id The venue ID
* @example
* const venue = await api.venues.byId(5)
* .include(['country'])
* .get();
*/
byId(id) {
return new QueryBuilder(this, `/${id}`);
}
/**
* Get venues by season ID
* Returns all venues used in a specific season
* @param seasonId The season ID
* @example
* const venues = await api.venues.bySeason(19735)
* .include(['country'])
* .get();
*/
bySeason(seasonId) {
return new QueryBuilder(this, `/seasons/${seasonId}`);
}
/**
* Search venues by name
* @param searchQuery The search query (minimum 3 characters)
* @example
* const venues = await api.venues.search('Old Trafford')
* .include(['country'])
* .get();
*/
search(searchQuery) {
if (searchQuery.length < 3) {
throw new Error("Search query must be at least 3 characters long");
}
return new QueryBuilder(
this,
`/search/${encodeURIComponent(searchQuery)}`
);
}
};
// src/resources/news.ts
var NewsResource = class extends BaseResource {
/**
* Get pre-match news articles.
* Supports standard filters (fixture_id, league_id, season_id).
* @example
* const news = await client.news.prematch().filter('league_id', 8).get()
*/
prematch() {
return new QueryBuilder(this, "/pre-match");
}
/**
* Get post-match news articles.
* @example
* const news = await client.news.postmatch().filter('fixture_id', 18535482).get()
*/
postmatch() {
return new QueryBuilder(this, "/post-match");
}
/**
* Get a single news article by ID.
* @param id News article ID
*/
byId(id) {
const validated = validateId(id, "News ID");
return new QueryBuilder(this, `/${validated}`);
}
};
// src/resources/fixtures.ts
var FixturesResource = class extends BaseResource {
/**
* Get all fixtures
* @example
* const fixtures = await api.fixtures.all()
* .include(['localteam', 'visitorteam'])
* .page(1)
* .get();
*/
all() {
return new QueryBuilder(this, "");
}
/**
* Get a fixture by ID
* @param id The fixture ID
* @example
* const fixture = await api.fixtures.byId(18535517)
* .include(['localteam', 'visitorteam', 'venue', 'referee'])
* .get();
*/
byId(id) {
return new QueryBuilder(this, `/${id}`);
}
/**
* Get fixtures by multiple IDs
* @param ids Array of fixture IDs
* @example
* const fixtures = await api.fixtures.byIds([18535517, 18535518])
* .include(['localteam', 'visitorteam'])
* .get();
*/
byIds(ids) {
const idsString = ids.join(",");
return new QueryBuilder(this, `/multi/${idsString}`);
}
/**
* Get fixtures by date
* @param date Date in YYYY-MM-DD format
* @example
* const fixtures = await api.fixtures.byDate('2024-01-15')
* .include(['localteam', 'visitorteam'])
* .get();
*/
byDate(date) {
validateDateFormat(date);
return new QueryBuilder(this, `/date/${date}`);
}
/**
* Get fixtures by date range
* @param startDate Start date in YYYY-MM-DD format
* @param endDate End date in YYYY-MM-DD format
* @example
* const fixtures = await api.fixtures.byDateRange('2024-01-01', '2024-01-31')
* .include(['localteam', 'visitorteam'])
* .get();
*/
byDateRange(startDate, endDate) {
validateDateRange(startDate, endDate);
return new QueryBuilder(this, `/between/${startDate}/${endDate}`);
}
/**
* Get fixtures by date range for a specific team
* @param teamId The team ID
* @param startDate Start date in YYYY-MM-DD format
* @param endDate End date in YYYY-MM-DD format
* @example
* const fixtures = await api.fixtures.byTeamAndDateRange(1, '2024-01-01', '2024-01-31')
* .include(['localteam', 'visitorteam', 'venue'])
* .get();
*/
byTeamAndDateRange(teamId, startDate, endDate) {
validateId(teamId, "Team ID");
validateDateRange(startDate, endDate);
return new QueryBuilder(
this,
`/between/${startDate}/${endDate}/${teamId}`
);
}
/**
* Get head-to-head fixtures between two teams
* @param team1Id First team ID
* @param team2Id Second team ID
* @example
* const h2h = await api.fixtures.headToHead(1, 14)
* .include(['localteam', 'visitorteam', 'venue'])
* .get();
*/
headToHead(team1Id, team2Id) {
return new QueryBuilder(this, `/head-to-head/${team1Id}/${team2Id}`);
}
/**
* Search fixtures by name
* @param searchQuery The search query
* @example
* const fixtures = await api.fixtures.search('Manchester United vs Liverpool')
* .include(['localteam', 'visitorteam'])
* .get();
*/
search(searchQuery) {
const query = validateSearchQuery(searchQuery);
return new QueryBuilder(
this,
`/search/${encodeURIComponent(query)}`
);
}
/**
* Get upcoming fixtures by market ID
* @param marketId The market ID
* @example
* const fixtures = await api.fixtures.upcomingByMarket(1)
* .include(['localteam', 'visitorteam'])
* .get();
*/
upcomingByMarket(marketId) {
return new QueryBuilder(this, `/upcoming/markets/${marketId}`);
}
/**
* Get upcoming fixtures by TV station ID
* @param tvStationId The TV station ID
* @example
* const fixtures = await api.fixtures.upcomingByTvStation(1)
* .include(['localteam', 'visitorteam', 'tvstations'])
* .get();
*/
upcomingByTvStation(tvStationId) {
return new QueryBuilder(
this,
`/upcoming/tv-stations/${tvStationId}`
);
}
/**
* Get past fixtures by TV station ID
* @param tvStationId The TV station ID
* @example
* const fixtures = await api.fixtures.pastByTvStation(1)
* .include(['localteam', 'visitorteam', 'tvstations'])
* .get();
*/
pastByTvStation(tvStationId) {
return new QueryBuilder(this, `/past/tv-stations/${tvStationId}`);
}
/**
* Get latest updated fixtures
* Returns fixtures that have received updates within 10 seconds
* @example
* const fixtures = await api.fixtures.latest()
* .include(['localteam', 'visitorteam'])
* .get();
*/
latest() {
return new QueryBuilder(this, "/latest");
}
};
// src/client.ts
var SportMonksClient = class {
client;
options;
// Resource instances
leagues;
teams;
players;
standings;
livescores;
coaches;
referees;
transfers;
venues;
fixtures;
news;
/**
* Create a new SportMonks API client
*/
constructor(apiKey, options = {}) {
this.options = {
baseUrl: "https://api.sportmonks.com/v3",
timeout: 3e4,
version: "v3",
includeSeparator: ";",
...options
};
this.client = axios__default.default.create({
baseURL: this.options.baseUrl,
timeout: this.options.timeout,
params: {
api_token: apiKey
}
});
this.client.interceptors.response.use(
(response) => response,
(error) => {
if (process.env.NODE_ENV === "development" && axios__default.default.isAxiosError(error) && error.response) {
const responseData = error.response.data;
console.error("API Error:", {
status: error.response.status,
message: responseData?.message,
url: error.config?.url
});
}
return Promise.reject(axios__default.default.isAxiosError(error) ? error : new Error(String(error)));
}
);
this.leagues = new LeaguesResource(
this.client,
"/football/leagues",
this.options.includeSeparator,
this.options.retry
);
this.teams = new TeamsResource(
this.client,
"/football/teams",
this.options.includeSeparator,
this.options.retry
);
this.players = new PlayersResource(
this.client,
"/football/players",
this.options.includeSeparator,
this.options.retry
);
this.standings = new StandingsResource(
this.client,
"/football/standings",
this.options.includeSeparator,
this.options.retry
);
this.livescores = new LivescoresResource(
this.client,
"/football/livescores",
this.options.includeSeparator,
this.options.retry
);
this.coaches = new CoachesResource(
this.client,
"/football/coaches",
this.options.includeSeparator,
this.options.retry
);
this.referees = new RefereesResource(
this.client,
"/football/referees",
this.options.includeSeparator,
this.options.retry
);
this.transfers = new TransfersResource(
this.client,
"/football/transfers",
this.options.includeSeparator,
this.options.retry
);
this.venues = new VenuesResource(
this.client,
"/football/venues",
this.options.includeSeparator,
this.options.retry
);
this.news = new NewsResource(
this.client,
"/football/news",
this.options.includeSeparator,
this.options.retry
);
this.fixtures = new FixturesResource(
this.client,
"/football/fixtures",
this.options.includeSeparator,
this.options.retry
);
}
/**
* Update the API key
*/
setApiKey(apiKey) {
if (!this.client.defaults.params) {
this.client.defaults.params = {};
}
this.client.defaults.params.api_token = apiKey;
}
/**
* Update the request timeout
*/
setTimeout(timeout) {
this.client.defaults.timeout = timeout;
}
};
// src/types/enums.ts
var LeagueType = /* @__PURE__ */ ((LeagueType2) => {
LeagueType2["LEAGUE"] = "league";
LeagueType2["CUP"] = "cup";
LeagueType2["SUPER_CUP"] = "super_cup";
LeagueType2["FRIENDLY"] = "friendly";
LeagueType2["DOMESTIC"] = "domestic";
LeagueType2["INTERNATIONAL"] = "international";
LeagueType2["PLAYOFFS"] = "playoffs";
return LeagueType2;
})(LeagueType || {});
var LeagueSubType = /* @__PURE__ */ ((LeagueSubType2) => {
LeagueSubType2["TOP_LEVEL"] = "top_level";
LeagueSubType2["SECOND_LEVEL"] = "second_level";
LeagueSubType2["THIRD_LEVEL"] = "third_level";
LeagueSubType2["FOURTH_LEVEL"] = "fourth_level";
LeagueSubType2["FIFTH_LEVEL"] = "fifth_level";
LeagueSubType2["PLAYOFF"] = "playoff";
LeagueSubType2["AMATEUR"] = "amateur";
LeagueSubType2["YOUTH"] = "youth";
LeagueSubType2["WOMEN"] = "women";
return LeagueSubType2;
})(LeagueSubType || {});
var FixtureStatus = /* @__PURE__ */ ((FixtureStatus2) => {
FixtureStatus2[FixtureStatus2["NS"] = 1] = "NS";
FixtureStatus2[FixtureStatus2["LIVE"] = 2] = "LIVE";
FixtureStatus2[FixtureStatus2["HT"] = 3] = "HT";
FixtureStatus2[FixtureStatus2["FT"] = 5] = "FT";
FixtureStatus2[FixtureStatus2["AET"] = 6] = "AET";
FixtureStatus2[FixtureStatus2["FT_PEN"] = 7] = "FT_PEN";
FixtureStatus2[FixtureStatus2["CANC"] = 8] = "CANC";
FixtureStatus2[FixtureStatus2["POSTP"] = 9] = "POSTP";
FixtureStatus2[FixtureStatus2["INT"] = 10] = "INT";
FixtureStatus2[FixtureStatus2["ABAN"] = 11] = "ABAN";
FixtureStatus2[FixtureStatus2["SUSP"] = 12] = "SUSP";
FixtureStatus2[FixtureStatus2["AWARDED"] = 13] = "AWARDED";
FixtureStatus2[FixtureStatus2["DELAYED"] = 14] = "DELAYED";
FixtureStatus2[FixtureStatus2["TBA"] = 15] = "TBA";
FixtureStatus2[FixtureStatus2["WO"] = 16] = "WO";
FixtureStatus2[FixtureStatus2["AU"] = 17] = "AU";
FixtureStatus2[FixtureStatus2["AP"] = 18] = "AP";
return FixtureStatus2;
})(FixtureStatus || {});
var EventTypeId = /* @__PURE__ */ ((EventTypeId2) => {
EventTypeId2[EventTypeId2["VAR"] = 10] = "VAR";
EventTypeId2[EventTypeId2["GOAL"] = 14] = "GOAL";
EventTypeId2[EventTypeId2["OWNGOAL"] = 15] = "OWNGOAL";
EventTypeId2[EventTypeId2["PENALTY"] = 16] = "PENALTY";
EventTypeId2[EventTypeId2["MISSED_PENALTY"] = 17] = "MISSED_PENALTY";
EventTypeId2[EventTypeId2["SUBSTITUTION"] = 18] = "SUBSTITUTION";
EventTypeId2[EventTypeId2["YELLOWCARD"] = 19] = "YELLOWCARD";
EventTypeId2[EventTypeId2["REDCARD"] = 20] = "REDCARD";
EventTypeId2[EventTypeId2["YELLOWREDCARD"] = 21] = "YELLOWREDCARD";
EventTypeId2[EventTypeId2["PENALTY_SHOOTOUT_MISS"] = 22] = "PENALTY_SHOOTOUT_MISS";
EventTypeId2[EventTypeId2["PENALTY_SHOOTOUT_GOAL"] = 23] = "PENALTY_SHOOTOUT_GOAL";
EventTypeId2[EventTypeId2["CORNER"] = 126] = "CORNER";
EventTypeId2[EventTypeId2["OFFSIDE"] = 568] = "OFFSIDE";
EventTypeId2[EventTypeId2["SHOT_ON_TARGET"] = 569] = "SHOT_ON_TARGET";
EventTypeId2[EventTypeId2["SHOT_OFF_TARGET"] = 570] = "SHOT_OFF_TARGET";
EventTypeId2[EventTypeId2["VAR_CARD"] = 1697] = "VAR_CARD";
EventTypeId2[EventTypeId2["WOODWORK"] = 48995] = "WOODWORK";
return EventTypeId2;
})(EventTypeId || {});
var FixtureStatisticTypeId = /* @__PURE__ */ ((FixtureStatisticTypeId2) => {
FixtureStatisticTypeId2[FixtureStatisticTypeId2["BALL_POSSESSION"] = 45] = "BALL_POSSESSION";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["SHOTS_ON_TARGET"] = 86] = "SHOTS_ON_TARGET";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["SHOTS_TOTAL"] = 42] = "SHOTS_TOTAL";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["SHOTS_OFF_TARGET"] = 41] = "SHOTS_OFF_TARGET";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["CORNERS"] = 34] = "CORNERS";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["OFFSIDES"] = 51] = "OFFSIDES";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["FOULS"] = 56] = "FOULS";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["YELLOWCARDS"] = 84] = "YELLOWCARDS";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["REDCARDS"] = 83] = "REDCARDS";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["PASSES"] = 80] = "PASSES";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["SUCCESSFUL_PASSES"] = 81] = "SUCCESSFUL_PASSES";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["SUCCESSFUL_PASSES_PERCENTAGE"] = 82] = "SUCCESSFUL_PASSES_PERCENTAGE";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["ATTACKS"] = 43] = "ATTACKS";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["DANGEROUS_ATTACKS"] = 44] = "DANGEROUS_ATTACKS";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["GOALS"] = 52] = "GOALS";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["SAVES"] = 57] = "SAVES";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["EXPECTED_GOALS"] = 5304] = "EXPECTED_GOALS";
FixtureStatisticTypeId2[FixtureStatisticTypeId2["EXPECTED_GOALS_ON_TARGET"] = 5305] = "EXPECTED_GOALS_ON_TARGET";
return FixtureStatisticTypeId2;
})(FixtureStatisticTypeId || {});
var PositionType = /* @__PURE__ */ ((PositionType2) => {
PositionType2[PositionType2["GOALKEEPER"] = 1] = "GOALKEEPER";
PositionType2[PositionType2["DEFENDER"] = 2] = "DEFENDER";
PositionType2[PositionType2["MIDFIELDER"] = 3] = "MIDFIELDER";
PositionType2[PositionType2["ATTACKER"] = 4] = "ATTACKER";
return PositionType2;
})(PositionType || {});
var TeamType = /* @__PURE__ */ ((TeamType2) => {
TeamType2["DOMESTIC"] = "domestic";
TeamType2["NATIONAL"] = "national";
return TeamType2;
})(TeamType || {});
var Gender = /* @__PURE__ */ ((Gender2) => {
Gender2["MALE"] = "male";
Gender2["FEMALE"] = "female";
return Gender2;
})(Gender || {});
var LineupType = /* @__PURE__ */ ((LineupType2) => {
LineupType2[LineupType2["LINEUP"] = 11] = "LINEUP";
LineupType2[LineupType2["BENCH"] = 12] = "BENCH";
LineupType2[LineupType2["SIDELINED"] = 13] = "SIDELINED";
LineupType2[LineupType2["MISSING"] = 14] = "MISSING";
return LineupType2;
})(LineupType || {});
var TransferTypeEnum = /* @__PURE__ */ ((TransferTypeEnum2) => {
TransferTypeEnum2["TRANSFER"] = "transfer";
TransferTypeEnum2["LOAN"] = "loan";
TransferTypeEnum2["FREE"] = "free";
return TransferTypeEnum2;
})(TransferTypeEnum || {});
var StandingRule = /* @__PURE__ */ ((StandingRule2) => {
StandingRule2[StandingRule2["POINTS"] = 1] = "POINTS";
StandingRule2[StandingRule2["GOAL_DIFFERENCE"] = 2] = "GOAL_DIFFERENCE";
StandingRule2[StandingRule2["HEAD_TO_HEAD"] = 3] = "HEAD_TO_HEAD";
StandingRule2[StandingRule2["GOALS_FOR"] = 4] = "GOALS_FOR";
StandingRule2[StandingRule2["AWAY_GOALS"] = 5] = "AWAY_GOALS";
StandingRule2[StandingRule2["WINS"] = 6] = "WINS";
StandingRule2[StandingRule2["DRAWS"] = 7] = "DRAWS";
StandingRule2[StandingRule2["LOSSES"] = 8] = "LOSSES";
return StandingRule2;
})(StandingRule || {});
var ScoreType = /* @__PURE__ */ ((ScoreType2) => {
ScoreType2[ScoreType2["CURRENT"] = 1208] = "CURRENT";
ScoreType2[ScoreType2["HALFTIME"] = 1209] = "HALFTIME";
ScoreType2[ScoreType2["NORMALTIME"] = 1456] = "NORMALTIME";
ScoreType2[ScoreType2["EXTRATIME"] = 1457] = "EXTRATIME";
ScoreType2[ScoreType2["PENALTIES"] = 1458] = "PENALTIES";
ScoreType2[ScoreType2["AGGREGATED"] = 1713] = "AGGREGATED";
return ScoreType2;
})(ScoreType || {});
var VenueSurface = /* @__PURE__ */ ((VenueSurface2) => {
VenueSurface2["GRASS"] = "grass";
VenueSurface2["ARTIFICIAL"] = "artificial";
VenueSurface2["HYBRID"] = "hybrid";
VenueSurface2["ASTROTURF"] = "astroturf";
VenueSurface2["CONCRETE"] = "concrete";
VenueSurface2["GRAVEL"] = "gravel";
return VenueSurface2;
})(VenueSurface || {});
var SortOrder = /* @__PURE__ */ ((SortOrder2) => {
SortOrder2["ASC"] = "asc";
SortOrder2["DESC"] = "desc";
return SortOrder2;
})(SortOrder || {});
var PlayerStatisticType = /* @__PURE__ */ ((PlayerStatisticType2) => {
PlayerStatisticType2[PlayerStatisticType2["MINUTES_PLAYED"] = 90] = "MINUTES_PLAYED";
PlayerStatisticType2[PlayerStatisticType2["GOALS"] = 208] = "GOALS";
PlayerStatisticType2[PlayerStatisticType2["ASSISTS"] = 209] = "ASSISTS";
PlayerStatisticType2[PlayerStatisticType2["OFFSIDES"] = 210] = "OFFSIDES";
PlayerStatisticType2[PlayerStatisticType2["SHOTS_TOTAL"] = 211] = "SHOTS_TOTAL";
PlayerStatisticType2[PlayerStatisticType2["SHOTS_ON_TARGET"] = 217] = "SHOTS_ON_TARGET";
PlayerStatisticType2[PlayerStatisticType2["GOALS_CONCEDED"] = 220] = "GOALS_CONCEDED";
PlayerStatisticType2[PlayerStatisticType2["PENALTIES"] = 215] = "PENALTIES";
PlayerStatisticType2[PlayerStatisticType2["PENALTIES_SCORED"] = 216] = "PENALTIES_SCORED";
PlayerStatisticType2[PlayerStatisticType2["PENALTIES_MISSED"] = 218] = "PENALTIES_MISSED";
PlayerStatisticType2[PlayerStatisticType2["PENALTIES_SAVED"] = 223] = "PENALTIES_SAVED";
PlayerStatisticType2[PlayerStatisticType2["SAVES"] = 214] = "SAVES";
PlayerStatisticType2[PlayerStatisticType2["YELLOWCARDS"] = 212] = "YELLOWCARDS";
PlayerStatisticType2[PlayerStatisticType2["REDCARDS"] = 213] = "REDCARDS";
PlayerStatisticType2[PlayerStatisticType2["HIT_WOODWORK"] = 602] = "HIT_WOODWORK";
PlayerStatisticType2[PlayerStatisticType2["PASSES"] = 595] = "PASSES";
PlayerStatisticType2[PlayerStatisticType2["PASSES_ACCURATE"] = 596] = "PASSES_ACCURATE";
PlayerStatisticType2[PlayerStatisticType2["CLEANSHEETS"] = 597] = "CLEANSHEETS";
PlayerStatisticType2[PlayerStatisticType2["TACKLES"] = 598] = "TACKLES";
PlayerStatisticType2[PlayerStatisticType2["FOULS_COMMITTED"] = 594] = "FOULS_COMMITTED";
return PlayerStatisticType2;
})(PlayerStatisticType || {});
// src/types/sportmonks-syntax.ts
var SportMonksSyntaxBuilder = class {
/**
* Build include string from configuration
*/
static buildIncludes(config, separator = ";") {
const includes = [];
Object.entries(config).forEach(([relation, settings]) => {
if (settings === true) {
includes.push(relation);
} else if (settings && typeof settings === "object") {
let includeStr = relation;
if (Array.isArray(settings.fields) && settings.fields.length > 0) {
includeStr += ":" + settings.fields.join(",");
}
includes.push(includeStr);
if (settings.nested) {
Object.entries(settings.nested).forEach(([nestedRelation, nestedSettings]) => {
let nestedStr = `${relation}.${nestedRelation}`;
if (nestedSettings && typeof nestedSettings === "object" && Array.isArray(nestedSettings.fields)) {
nestedStr += ":" + nestedSettings.fields.join(",");
}
includes.push(nestedStr);
});
}
}
});
return includes.join(separator);
}
/**
* Build filter string from configuration
*/
static buildFilters(filters) {
return Object.entries(filters).map(([key, value]) => {
const filterValue = Array.isArray(value) ? value.join(",") : String(value);
return `${key}:${filterValue}`;
}).join(";");
}
};
var SportMonksFilters = {
/**
* Event type filters
*/
EventTypes: {
GOAL: 14,
OWN_GOAL: 15,
PENALTY: 16,
MISSED_PENALTY: 17,
YELLOW_CARD: 19,
RED_CARD: 20,
SUBSTITUTION: 18,
VAR: 10
},
/**
* Fixture status filters
*/
Status: {
NOT_STARTED: "NS",
L