🎨 Improve code readability by reformatting and updating function definitions and comments
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* Challonge API v1 Service (DEPRECATED - REFERENCE ONLY)
|
||||
*
|
||||
* ⚠️ DEPRECATED: This service is maintained for reference purposes only.
|
||||
* Use challonge-v2.1.service.js for new development.
|
||||
*
|
||||
* Client for interacting with Challonge tournament platform API v1
|
||||
* Adapted from Discord bot for Vue 3 browser environment
|
||||
*/
|
||||
|
||||
import { API_CONFIG } from '../utilities/constants.js';
|
||||
|
||||
/**
|
||||
* Get the appropriate base URL based on environment
|
||||
* Development: Use Vite proxy to avoid CORS
|
||||
* Production: Use direct API (requires backend proxy or CORS handling)
|
||||
*/
|
||||
function getBaseURL() {
|
||||
// In development, use Vite proxy
|
||||
if (import.meta.env.DEV) {
|
||||
return '/api/challonge/v1/';
|
||||
}
|
||||
// In production, use direct API (will need backend proxy for CORS)
|
||||
return API_CONFIG.CHALLONGE_BASE_URL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Challonge API v1 client
|
||||
* @param {string} apiKey - Challonge API v1 key
|
||||
* @returns {Object} API client with methods
|
||||
*/
|
||||
export function createChallongeV1Client(apiKey) {
|
||||
const baseURL = getBaseURL();
|
||||
|
||||
/**
|
||||
* Make API request
|
||||
* @param {string} endpoint - API endpoint
|
||||
* @param {Object} options - Fetch options
|
||||
* @returns {Promise<Object>} Response data
|
||||
*/
|
||||
async function makeRequest(endpoint, options = {}) {
|
||||
const cleanEndpoint = endpoint.startsWith('/')
|
||||
? endpoint.slice(1)
|
||||
: endpoint;
|
||||
const url = new URL(`${baseURL}${cleanEndpoint}`, window.location.origin);
|
||||
url.searchParams.append('api_key', apiKey);
|
||||
|
||||
if (options.params) {
|
||||
Object.entries(options.params).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== null) {
|
||||
url.searchParams.append(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const fetchOptions = {
|
||||
method: options.method || 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
...options.headers
|
||||
}
|
||||
};
|
||||
|
||||
if (options.body) {
|
||||
fetchOptions.body = JSON.stringify(options.body);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(url.toString(), fetchOptions);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({}));
|
||||
throw new Error(
|
||||
error.errors?.[0] || `HTTP ${response.status}: ${response.statusText}`
|
||||
);
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('Challonge API v1 Error:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Tournament Methods
|
||||
const tournaments = {
|
||||
list: params => makeRequest('tournaments', { params }),
|
||||
get: (id, options = {}) =>
|
||||
makeRequest(`tournaments/${id}`, {
|
||||
params: {
|
||||
include_participants: options.includeParticipants ? 1 : 0,
|
||||
include_matches: options.includeMatches ? 1 : 0
|
||||
}
|
||||
}),
|
||||
create: data =>
|
||||
makeRequest('tournaments', {
|
||||
method: 'POST',
|
||||
body: { tournament: data }
|
||||
}),
|
||||
update: (id, data) =>
|
||||
makeRequest(`tournaments/${id}`, {
|
||||
method: 'PUT',
|
||||
body: { tournament: data }
|
||||
}),
|
||||
delete: id => makeRequest(`tournaments/${id}`, { method: 'DELETE' }),
|
||||
start: (id, options = {}) =>
|
||||
makeRequest(`tournaments/${id}/start`, {
|
||||
method: 'POST',
|
||||
params: options
|
||||
}),
|
||||
finalize: id =>
|
||||
makeRequest(`tournaments/${id}/finalize`, { method: 'POST' }),
|
||||
reset: id => makeRequest(`tournaments/${id}/reset`, { method: 'POST' })
|
||||
};
|
||||
|
||||
// Participant Methods
|
||||
const participants = {
|
||||
list: tournamentId =>
|
||||
makeRequest(`tournaments/${tournamentId}/participants`),
|
||||
add: (tournamentId, data) =>
|
||||
makeRequest(`tournaments/${tournamentId}/participants`, {
|
||||
method: 'POST',
|
||||
body: { participant: data }
|
||||
}),
|
||||
bulkAdd: (tournamentId, participants) =>
|
||||
makeRequest(`tournaments/${tournamentId}/participants/bulk_add`, {
|
||||
method: 'POST',
|
||||
body: { participants }
|
||||
}),
|
||||
update: (tournamentId, participantId, data) =>
|
||||
makeRequest(`tournaments/${tournamentId}/participants/${participantId}`, {
|
||||
method: 'PUT',
|
||||
body: { participant: data }
|
||||
}),
|
||||
delete: (tournamentId, participantId) =>
|
||||
makeRequest(`tournaments/${tournamentId}/participants/${participantId}`, {
|
||||
method: 'DELETE'
|
||||
}),
|
||||
checkIn: (tournamentId, participantId) =>
|
||||
makeRequest(
|
||||
`tournaments/${tournamentId}/participants/${participantId}/check_in`,
|
||||
{ method: 'POST' }
|
||||
),
|
||||
undoCheckIn: (tournamentId, participantId) =>
|
||||
makeRequest(
|
||||
`tournaments/${tournamentId}/participants/${participantId}/undo_check_in`,
|
||||
{ method: 'POST' }
|
||||
),
|
||||
randomize: tournamentId =>
|
||||
makeRequest(`tournaments/${tournamentId}/participants/randomize`, {
|
||||
method: 'POST'
|
||||
})
|
||||
};
|
||||
|
||||
// Match Methods
|
||||
const matches = {
|
||||
list: (tournamentId, params = {}) =>
|
||||
makeRequest(`tournaments/${tournamentId}/matches`, { params }),
|
||||
get: (tournamentId, matchId) =>
|
||||
makeRequest(`tournaments/${tournamentId}/matches/${matchId}`),
|
||||
update: (tournamentId, matchId, data) =>
|
||||
makeRequest(`tournaments/${tournamentId}/matches/${matchId}`, {
|
||||
method: 'PUT',
|
||||
body: { match: data }
|
||||
}),
|
||||
reopen: (tournamentId, matchId) =>
|
||||
makeRequest(`tournaments/${tournamentId}/matches/${matchId}/reopen`, {
|
||||
method: 'POST'
|
||||
}),
|
||||
markAsUnderway: (tournamentId, matchId) =>
|
||||
makeRequest(
|
||||
`tournaments/${tournamentId}/matches/${matchId}/mark_as_underway`,
|
||||
{ method: 'POST' }
|
||||
),
|
||||
unmarkAsUnderway: (tournamentId, matchId) =>
|
||||
makeRequest(
|
||||
`tournaments/${tournamentId}/matches/${matchId}/unmark_as_underway`,
|
||||
{ method: 'POST' }
|
||||
)
|
||||
};
|
||||
|
||||
return { tournaments, participants, matches };
|
||||
}
|
||||
|
||||
// Backwards compatibility export
|
||||
export const createChallongeClient = createChallongeV1Client;
|
||||
@@ -0,0 +1,553 @@
|
||||
/**
|
||||
* Challonge API v2.1 Service
|
||||
* Client for interacting with Challonge API v2.1 (current version)
|
||||
*
|
||||
* Features:
|
||||
* - OAuth 2.0 support (Bearer tokens)
|
||||
* - API v1 key compatibility
|
||||
* - JSON:API specification compliant
|
||||
* - Tournament, Participant, Match, Race endpoints
|
||||
* - Community and Application scoping
|
||||
*
|
||||
* @see https://challonge.apidog.io/getting-started-1726706m0
|
||||
* @see https://challonge.apidog.io/llms.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the appropriate base URL based on environment
|
||||
*/
|
||||
function getBaseURL() {
|
||||
if (import.meta.env.DEV) {
|
||||
return '/api/challonge/v2.1';
|
||||
}
|
||||
return 'https://api.challonge.com/v2.1';
|
||||
}
|
||||
|
||||
/**
|
||||
* Authentication types for Challonge API v2.1
|
||||
*/
|
||||
export const AuthType = {
|
||||
OAUTH: 'v2', // Bearer token
|
||||
API_KEY: 'v1' // Legacy API key
|
||||
};
|
||||
|
||||
/**
|
||||
* Resource scoping options
|
||||
*/
|
||||
export const ScopeType = {
|
||||
USER: 'user', // /v2.1/tournaments (default)
|
||||
COMMUNITY: 'community', // /v2.1/communities/{id}/tournaments
|
||||
APPLICATION: 'app' // /v2.1/application/tournaments
|
||||
};
|
||||
|
||||
/**
|
||||
* Create Challonge API v2.1 client
|
||||
*
|
||||
* @param {Object} auth - Authentication configuration
|
||||
* @param {string} auth.token - OAuth Bearer token or API v1 key
|
||||
* @param {string} auth.type - AuthType.OAUTH or AuthType.API_KEY (default: API_KEY)
|
||||
* @param {Object} options - Client options
|
||||
* @param {string} options.communityId - Default community ID for scoping
|
||||
* @param {boolean} options.debug - Enable debug logging
|
||||
* @returns {Object} API client with methods
|
||||
*/
|
||||
export function createChallongeV2Client(auth, options = {}) {
|
||||
const { token, type = AuthType.API_KEY } = auth;
|
||||
const { communityId: defaultCommunityId, debug = false } = options;
|
||||
const baseURL = getBaseURL();
|
||||
|
||||
if (!token) {
|
||||
throw new Error('Authentication token is required');
|
||||
}
|
||||
|
||||
// Request tracking for debug mode
|
||||
let requestCount = 0;
|
||||
|
||||
/**
|
||||
* Make API request with JSON:API format
|
||||
*/
|
||||
async function makeRequest(endpoint, options = {}) {
|
||||
const {
|
||||
method = 'GET',
|
||||
body,
|
||||
params = {},
|
||||
headers = {},
|
||||
communityId = defaultCommunityId,
|
||||
scopeType = ScopeType.USER
|
||||
} = options;
|
||||
|
||||
const startTime = performance.now();
|
||||
requestCount++;
|
||||
|
||||
// Build URL with scoping
|
||||
let url = baseURL;
|
||||
|
||||
if (scopeType === ScopeType.COMMUNITY && communityId) {
|
||||
url += `/communities/${communityId}`;
|
||||
} else if (scopeType === ScopeType.APPLICATION) {
|
||||
url += '/application';
|
||||
}
|
||||
|
||||
url += `/${endpoint}`;
|
||||
|
||||
// Add query parameters
|
||||
const urlObj = new URL(url, window.location.origin);
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== null) {
|
||||
urlObj.searchParams.append(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
// Add communityId as query param if not in path
|
||||
if (communityId && scopeType === ScopeType.USER) {
|
||||
urlObj.searchParams.append('community_id', communityId);
|
||||
}
|
||||
|
||||
// Prepare headers (JSON:API required format)
|
||||
const requestHeaders = {
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Accept: 'application/json',
|
||||
'Authorization-Type': type,
|
||||
...headers
|
||||
};
|
||||
|
||||
// Add authorization header
|
||||
if (type === AuthType.OAUTH) {
|
||||
requestHeaders['Authorization'] = `Bearer ${token}`;
|
||||
} else {
|
||||
requestHeaders['Authorization'] = token;
|
||||
}
|
||||
|
||||
const fetchOptions = {
|
||||
method,
|
||||
headers: requestHeaders
|
||||
};
|
||||
|
||||
if (body && method !== 'GET') {
|
||||
// Wrap in JSON:API format if not already wrapped
|
||||
const jsonApiBody = body.data ? body : { data: body };
|
||||
fetchOptions.body = JSON.stringify(jsonApiBody);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
console.log(
|
||||
`[Challonge v2.1 Request #${requestCount}]`,
|
||||
method,
|
||||
urlObj.toString()
|
||||
);
|
||||
if (body) console.log('Body:', fetchOptions.body);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(urlObj.toString(), fetchOptions);
|
||||
const duration = performance.now() - startTime;
|
||||
|
||||
// Handle 204 No Content
|
||||
if (response.status === 204) {
|
||||
if (debug)
|
||||
console.log(
|
||||
`[Challonge v2.1 Response] 204 No Content (${duration.toFixed(0)}ms)`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
let data;
|
||||
try {
|
||||
data = await response.json();
|
||||
} catch (parseError) {
|
||||
// If JSON parsing fails, create an error with the status
|
||||
if (debug)
|
||||
console.error('[Challonge v2.1 JSON Parse Error]', parseError);
|
||||
const error = new Error(
|
||||
`HTTP ${response.status}: Failed to parse response`
|
||||
);
|
||||
error.status = response.status;
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
console.log(
|
||||
`[Challonge v2.1 Response] ${response.status} (${duration.toFixed(0)}ms)`,
|
||||
data
|
||||
);
|
||||
}
|
||||
|
||||
// Handle JSON:API errors
|
||||
if (!response.ok) {
|
||||
if (data.errors && Array.isArray(data.errors)) {
|
||||
const errorDetails = data.errors.map(e => ({
|
||||
status: e.status || response.status,
|
||||
message: e.detail || e.title || response.statusText,
|
||||
field: e.source?.pointer
|
||||
}));
|
||||
|
||||
const errorMessage = errorDetails
|
||||
.map(
|
||||
e => `${e.status}: ${e.message}${e.field ? ` (${e.field})` : ''}`
|
||||
)
|
||||
.join('\n');
|
||||
|
||||
const error = new Error(errorMessage);
|
||||
error.errors = errorDetails;
|
||||
error.response = data;
|
||||
throw error;
|
||||
}
|
||||
// Handle non-JSON:API error format
|
||||
const error = new Error(
|
||||
`HTTP ${response.status}: ${data.message || response.statusText}`
|
||||
);
|
||||
error.status = response.status;
|
||||
error.response = data;
|
||||
throw error;
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
if (debug) {
|
||||
console.error('[Challonge v2.1 Error]', error);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to unwrap JSON:API response and normalize structure
|
||||
*/
|
||||
function unwrapResponse(response) {
|
||||
if (!response) return null;
|
||||
|
||||
// If response has data property, it's JSON:API format
|
||||
if (response.data) {
|
||||
const data = response.data;
|
||||
|
||||
// Handle array of resources
|
||||
if (Array.isArray(data)) {
|
||||
return data.map(item => normalizeResource(item));
|
||||
}
|
||||
|
||||
// Handle single resource
|
||||
return normalizeResource(data);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize JSON:API resource to flat structure
|
||||
*/
|
||||
function normalizeResource(resource) {
|
||||
if (!resource || !resource.attributes) return resource;
|
||||
|
||||
return {
|
||||
id: resource.id,
|
||||
type: resource.type,
|
||||
...resource.attributes,
|
||||
relationships: resource.relationships,
|
||||
links: resource.links
|
||||
};
|
||||
}
|
||||
|
||||
// ==================== Tournament Methods ====================
|
||||
const tournaments = {
|
||||
/**
|
||||
* List tournaments
|
||||
* @param {Object} options - Query options
|
||||
* @returns {Promise<Array>}
|
||||
*/
|
||||
list: async (options = {}) => {
|
||||
const { communityId, scopeType, ...params } = options;
|
||||
const response = await makeRequest('tournaments.json', {
|
||||
params,
|
||||
communityId,
|
||||
scopeType
|
||||
});
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get tournament details
|
||||
* @param {string} id - Tournament ID or URL
|
||||
* @param {Object} options - Options
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
get: async (id, options = {}) => {
|
||||
const { communityId, scopeType, ifNoneMatch } = options;
|
||||
const response = await makeRequest(`tournaments/${id}.json`, {
|
||||
communityId,
|
||||
scopeType,
|
||||
headers: ifNoneMatch ? { 'If-None-Match': ifNoneMatch } : {}
|
||||
});
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create tournament
|
||||
* @param {Object} data - Tournament data
|
||||
* @param {Object} options - Options
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
create: async (data, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest('tournaments.json', {
|
||||
method: 'POST',
|
||||
body: { type: 'Tournaments', attributes: data },
|
||||
communityId,
|
||||
scopeType
|
||||
});
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update tournament
|
||||
* @param {string} id - Tournament ID
|
||||
* @param {Object} data - Updated fields
|
||||
* @param {Object} options - Options
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
update: async (id, data, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest(`tournaments/${id}.json`, {
|
||||
method: 'PUT',
|
||||
body: { type: 'Tournaments', attributes: data },
|
||||
communityId,
|
||||
scopeType
|
||||
});
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete tournament
|
||||
* @param {string} id - Tournament ID
|
||||
* @param {Object} options - Options
|
||||
* @returns {Promise<null>}
|
||||
*/
|
||||
delete: async (id, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
return await makeRequest(`tournaments/${id}.json`, {
|
||||
method: 'DELETE',
|
||||
communityId,
|
||||
scopeType
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Change tournament state
|
||||
* @param {string} id - Tournament ID
|
||||
* @param {string} state - New state
|
||||
* @param {Object} options - Options
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
changeState: async (id, state, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${id}/change_state.json`,
|
||||
{
|
||||
method: 'PUT',
|
||||
body: { type: 'TournamentState', attributes: { state } },
|
||||
communityId,
|
||||
scopeType
|
||||
}
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
// Convenience methods
|
||||
start: (id, options) => tournaments.changeState(id, 'start', options),
|
||||
finalize: (id, options) => tournaments.changeState(id, 'finalize', options),
|
||||
reset: (id, options) => tournaments.changeState(id, 'reset', options),
|
||||
processCheckIn: (id, options) =>
|
||||
tournaments.changeState(id, 'process_checkin', options)
|
||||
};
|
||||
|
||||
// ==================== Participant Methods ====================
|
||||
const participants = {
|
||||
list: async (tournamentId, options = {}) => {
|
||||
const { communityId, scopeType, page, per_page, ifNoneMatch } = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${tournamentId}/participants.json`,
|
||||
{
|
||||
params: { page, per_page },
|
||||
communityId,
|
||||
scopeType,
|
||||
headers: ifNoneMatch ? { 'If-None-Match': ifNoneMatch } : {}
|
||||
}
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
get: async (tournamentId, participantId, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${tournamentId}/participants/${participantId}.json`,
|
||||
{ communityId, scopeType }
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
create: async (tournamentId, data, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${tournamentId}/participants.json`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: { type: 'Participants', attributes: data },
|
||||
communityId,
|
||||
scopeType
|
||||
}
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
update: async (tournamentId, participantId, data, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${tournamentId}/participants/${participantId}.json`,
|
||||
{
|
||||
method: 'PUT',
|
||||
body: { type: 'Participants', attributes: data },
|
||||
communityId,
|
||||
scopeType
|
||||
}
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
delete: async (tournamentId, participantId, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
return await makeRequest(
|
||||
`tournaments/${tournamentId}/participants/${participantId}.json`,
|
||||
{ method: 'DELETE', communityId, scopeType }
|
||||
);
|
||||
},
|
||||
|
||||
bulkAdd: async (tournamentId, participantsData, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${tournamentId}/participants/bulk_add.json`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: {
|
||||
type: 'Participants',
|
||||
attributes: { participants: participantsData }
|
||||
},
|
||||
communityId,
|
||||
scopeType
|
||||
}
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
clear: async (tournamentId, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
return await makeRequest(
|
||||
`tournaments/${tournamentId}/participants/clear.json`,
|
||||
{
|
||||
method: 'DELETE',
|
||||
communityId,
|
||||
scopeType
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
randomize: async (tournamentId, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${tournamentId}/participants/randomize.json`,
|
||||
{ method: 'PUT', communityId, scopeType }
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== Match Methods ====================
|
||||
const matches = {
|
||||
list: async (tournamentId, options = {}) => {
|
||||
const {
|
||||
communityId,
|
||||
scopeType,
|
||||
state,
|
||||
participant_id,
|
||||
page,
|
||||
per_page,
|
||||
ifNoneMatch
|
||||
} = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${tournamentId}/matches.json`,
|
||||
{
|
||||
params: { state, participant_id, page, per_page },
|
||||
communityId,
|
||||
scopeType,
|
||||
headers: ifNoneMatch ? { 'If-None-Match': ifNoneMatch } : {}
|
||||
}
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
get: async (tournamentId, matchId, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${tournamentId}/matches/${matchId}.json`,
|
||||
{ communityId, scopeType }
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
update: async (tournamentId, matchId, data, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${tournamentId}/matches/${matchId}.json`,
|
||||
{
|
||||
method: 'PUT',
|
||||
body: { type: 'Match', attributes: data },
|
||||
communityId,
|
||||
scopeType
|
||||
}
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
changeState: async (tournamentId, matchId, state, options = {}) => {
|
||||
const { communityId, scopeType } = options;
|
||||
const response = await makeRequest(
|
||||
`tournaments/${tournamentId}/matches/${matchId}/change_state.json`,
|
||||
{
|
||||
method: 'PUT',
|
||||
body: { type: 'MatchState', attributes: { state } },
|
||||
communityId,
|
||||
scopeType
|
||||
}
|
||||
);
|
||||
return unwrapResponse(response);
|
||||
},
|
||||
|
||||
reopen: (tournamentId, matchId, options) =>
|
||||
matches.changeState(tournamentId, matchId, 'reopen', options),
|
||||
markAsUnderway: (tournamentId, matchId, options) =>
|
||||
matches.changeState(tournamentId, matchId, 'mark_as_underway', options)
|
||||
};
|
||||
|
||||
// ==================== User & Community Methods ====================
|
||||
const user = {
|
||||
getMe: async () => {
|
||||
const response = await makeRequest('me.json');
|
||||
return unwrapResponse(response);
|
||||
}
|
||||
};
|
||||
|
||||
const communities = {
|
||||
list: async () => {
|
||||
const response = await makeRequest('communities.json');
|
||||
return unwrapResponse(response);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
tournaments,
|
||||
participants,
|
||||
matches,
|
||||
user,
|
||||
communities,
|
||||
// Expose request count for debugging
|
||||
getRequestCount: () => requestCount
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Challonge Service - Backwards Compatibility Wrapper
|
||||
*
|
||||
* This file maintains backwards compatibility by re-exporting both API versions.
|
||||
*
|
||||
* For new code, import directly from:
|
||||
* - './challonge-v1.service.js' for legacy API (deprecated)
|
||||
* - './challonge-v2.1.service.js' for current API (recommended)
|
||||
*
|
||||
* @example Using v2.1 (recommended)
|
||||
* import { createChallongeV2Client, AuthType } from './challonge.service.js';
|
||||
* const client = createChallongeV2Client({ token: apiKey, type: AuthType.API_KEY });
|
||||
*
|
||||
* @example Using v1 (backwards compatibility)
|
||||
* import { createChallongeClient } from './challonge.service.js';
|
||||
* const client = createChallongeClient(apiKey);
|
||||
*/
|
||||
|
||||
// Primary exports (v2.1 - recommended for new code)
|
||||
export {
|
||||
createChallongeV2Client,
|
||||
AuthType,
|
||||
ScopeType
|
||||
} from './challonge-v2.1.service.js';
|
||||
|
||||
// Legacy exports (v1 - backwards compatibility)
|
||||
export {
|
||||
createChallongeV1Client,
|
||||
createChallongeClient
|
||||
} from './challonge-v1.service.js';
|
||||
Reference in New Issue
Block a user