✨ Add composable for interacting with Challonge API
This commit is contained in:
@@ -0,0 +1,197 @@
|
|||||||
|
/**
|
||||||
|
* Challonge Client Composable
|
||||||
|
*
|
||||||
|
* Manages Challonge API client initialization with support for:
|
||||||
|
* - API v1 and v2.1
|
||||||
|
* - Multiple authentication methods (API Key, OAuth, Client Credentials)
|
||||||
|
* - Smart auth selection based on tournament scope
|
||||||
|
* - Reactive client updates
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* const {
|
||||||
|
* client,
|
||||||
|
* apiVersion,
|
||||||
|
* tournamentScope,
|
||||||
|
* switchVersion,
|
||||||
|
* setScope
|
||||||
|
* } = useChallongeClient();
|
||||||
|
*
|
||||||
|
* // Use client for API calls
|
||||||
|
* await client.value.tournaments.list();
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { useChallongeApiKey } from './useChallongeApiKey.js';
|
||||||
|
import { useChallongeOAuth } from './useChallongeOAuth.js';
|
||||||
|
import { useChallongeClientCredentials } from './useChallongeClientCredentials.js';
|
||||||
|
import {
|
||||||
|
createChallongeV1Client,
|
||||||
|
createChallongeV2Client,
|
||||||
|
AuthType,
|
||||||
|
ScopeType
|
||||||
|
} from '../services/challonge.service.js';
|
||||||
|
|
||||||
|
export function useChallongeClient(options = {}) {
|
||||||
|
const { debug = false } = options;
|
||||||
|
|
||||||
|
// Get authentication sources
|
||||||
|
const { getApiKey } = useChallongeApiKey();
|
||||||
|
const {
|
||||||
|
isAuthenticated: isOAuthAuthenticated,
|
||||||
|
accessToken: oauthToken
|
||||||
|
} = useChallongeOAuth();
|
||||||
|
const {
|
||||||
|
isAuthenticated: isClientCredsAuthenticated,
|
||||||
|
accessToken: clientCredsToken
|
||||||
|
} = useChallongeClientCredentials();
|
||||||
|
|
||||||
|
// Configuration state
|
||||||
|
const apiVersion = ref('v2.1'); // 'v1' or 'v2.1'
|
||||||
|
const tournamentScope = ref(ScopeType.USER);
|
||||||
|
const debugMode = ref(debug);
|
||||||
|
|
||||||
|
// Reactive API key
|
||||||
|
const apiKey = computed(() => getApiKey());
|
||||||
|
|
||||||
|
// Masked API key for display
|
||||||
|
const maskedApiKey = computed(() => {
|
||||||
|
if (!apiKey.value) return '';
|
||||||
|
return apiKey.value.slice(0, 4) + '•••••••' + apiKey.value.slice(-4);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create API client reactively based on version, auth method, and scope
|
||||||
|
*/
|
||||||
|
const client = computed(() => {
|
||||||
|
if (apiVersion.value === 'v1') {
|
||||||
|
// v1 only supports API key
|
||||||
|
if (!apiKey.value) return null;
|
||||||
|
return createChallongeV1Client(apiKey.value);
|
||||||
|
} else {
|
||||||
|
// v2.1 supports OAuth, client credentials, and API key
|
||||||
|
// Smart priority based on scope selection:
|
||||||
|
// - APPLICATION scope: prefer client credentials (designed for this)
|
||||||
|
// - USER scope: prefer OAuth user tokens or API key
|
||||||
|
|
||||||
|
if (tournamentScope.value === ScopeType.APPLICATION) {
|
||||||
|
// APPLICATION scope - prefer client credentials
|
||||||
|
if (isClientCredsAuthenticated.value && clientCredsToken.value) {
|
||||||
|
if (debugMode.value) {
|
||||||
|
console.log('🔐 Using Client Credentials token for APPLICATION scope');
|
||||||
|
}
|
||||||
|
return createChallongeV2Client(
|
||||||
|
{ token: clientCredsToken.value, type: AuthType.OAUTH },
|
||||||
|
{ debug: debugMode.value }
|
||||||
|
);
|
||||||
|
} else if (isOAuthAuthenticated.value && oauthToken.value) {
|
||||||
|
if (debugMode.value) {
|
||||||
|
console.log('🔐 Using OAuth user token for APPLICATION scope');
|
||||||
|
}
|
||||||
|
return createChallongeV2Client(
|
||||||
|
{ token: oauthToken.value, type: AuthType.OAUTH },
|
||||||
|
{ debug: debugMode.value }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// USER scope - prefer OAuth user tokens or API key
|
||||||
|
if (isOAuthAuthenticated.value && oauthToken.value) {
|
||||||
|
if (debugMode.value) {
|
||||||
|
console.log('🔐 Using OAuth user token for USER scope');
|
||||||
|
}
|
||||||
|
return createChallongeV2Client(
|
||||||
|
{ token: oauthToken.value, type: AuthType.OAUTH },
|
||||||
|
{ debug: debugMode.value }
|
||||||
|
);
|
||||||
|
} else if (apiKey.value) {
|
||||||
|
if (debugMode.value) {
|
||||||
|
console.log('🔑 Using API Key for USER scope');
|
||||||
|
}
|
||||||
|
return createChallongeV2Client(
|
||||||
|
{ token: apiKey.value, type: AuthType.API_KEY },
|
||||||
|
{ debug: debugMode.value }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: try API key
|
||||||
|
if (apiKey.value) {
|
||||||
|
if (debugMode.value) {
|
||||||
|
console.log('🔑 Using API Key (fallback)');
|
||||||
|
}
|
||||||
|
return createChallongeV2Client(
|
||||||
|
{ token: apiKey.value, type: AuthType.API_KEY },
|
||||||
|
{ debug: debugMode.value }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current authentication type being used
|
||||||
|
*/
|
||||||
|
const authType = computed(() => {
|
||||||
|
if (apiVersion.value === 'v1') {
|
||||||
|
return 'API Key';
|
||||||
|
}
|
||||||
|
if (isClientCredsAuthenticated.value) {
|
||||||
|
return 'Client Credentials';
|
||||||
|
}
|
||||||
|
if (isOAuthAuthenticated.value) {
|
||||||
|
return 'OAuth';
|
||||||
|
}
|
||||||
|
return 'API Key';
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switch API version
|
||||||
|
*/
|
||||||
|
function switchVersion(version) {
|
||||||
|
if (version !== 'v1' && version !== 'v2.1') {
|
||||||
|
throw new Error('Invalid API version. Must be "v1" or "v2.1"');
|
||||||
|
}
|
||||||
|
apiVersion.value = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set tournament scope (v2.1 only)
|
||||||
|
*/
|
||||||
|
function setScope(scope) {
|
||||||
|
if (scope !== ScopeType.USER && scope !== ScopeType.APPLICATION) {
|
||||||
|
throw new Error('Invalid scope type');
|
||||||
|
}
|
||||||
|
tournamentScope.value = scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle debug mode
|
||||||
|
*/
|
||||||
|
function setDebugMode(enabled) {
|
||||||
|
debugMode.value = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
// State
|
||||||
|
apiVersion,
|
||||||
|
tournamentScope,
|
||||||
|
debugMode,
|
||||||
|
apiKey,
|
||||||
|
maskedApiKey,
|
||||||
|
client,
|
||||||
|
authType,
|
||||||
|
isOAuthAuthenticated,
|
||||||
|
isClientCredsAuthenticated,
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
switchVersion,
|
||||||
|
setScope,
|
||||||
|
setDebugMode,
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
ScopeType,
|
||||||
|
AuthType
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user