Enhance API with OIDC support, including login and callback endpoints. Update environment variables for OIDC configuration in .env.example. Add new features to the catalog service for listing software families, Minecraft versions, and deployment regions. Implement server management actions such as kill, delete, and update in the servers module. Integrate feature flags for maintenance mode in server operations. Update pnpm-lock.yaml with new dependencies and versions.
This commit is contained in:
74
packages/catalog/src/curseforge.ts
Normal file
74
packages/catalog/src/curseforge.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
export interface CurseForgeProject {
|
||||
id: number;
|
||||
name: string;
|
||||
slug: string;
|
||||
summary: string;
|
||||
downloadCount: number;
|
||||
logo?: { thumbnailUrl?: string };
|
||||
}
|
||||
|
||||
export interface CurseForgeSearchResponse {
|
||||
data: CurseForgeProject[];
|
||||
pagination: { totalCount: number };
|
||||
}
|
||||
|
||||
export interface CurseForgeFile {
|
||||
id: number;
|
||||
displayName: string;
|
||||
fileName: string;
|
||||
downloadUrl: string;
|
||||
fileLength: number;
|
||||
gameVersions: string[];
|
||||
modLoader?: number;
|
||||
}
|
||||
|
||||
const CURSEFORGE_API = 'https://api.curseforge.com/v1';
|
||||
|
||||
function apiKey(): string {
|
||||
const key = process.env['CURSEFORGE_API_KEY'];
|
||||
if (!key) {
|
||||
throw new Error('CURSEFORGE_API_KEY is not configured');
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
async function curseforgeFetch<T>(path: string): Promise<T> {
|
||||
const response = await fetch(`${CURSEFORGE_API}${path}`, {
|
||||
headers: {
|
||||
'x-api-key': apiKey(),
|
||||
Accept: 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`CurseForge API error: ${response.status}`);
|
||||
}
|
||||
|
||||
return (await response.json()) as T;
|
||||
}
|
||||
|
||||
export async function searchCurseForgeMods(input: {
|
||||
gameId?: number;
|
||||
searchFilter: string;
|
||||
pageSize?: number;
|
||||
classId?: number;
|
||||
}): Promise<CurseForgeSearchResponse> {
|
||||
const params = new URLSearchParams({
|
||||
gameId: String(input.gameId ?? 432),
|
||||
searchFilter: input.searchFilter,
|
||||
pageSize: String(input.pageSize ?? 20),
|
||||
});
|
||||
if (input.classId !== undefined) {
|
||||
params.set('classId', String(input.classId));
|
||||
}
|
||||
|
||||
return curseforgeFetch<CurseForgeSearchResponse>(`/mods/search?${params.toString()}`);
|
||||
}
|
||||
|
||||
export async function getCurseForgeModFiles(modId: number): Promise<{ data: CurseForgeFile[] }> {
|
||||
return curseforgeFetch<{ data: CurseForgeFile[] }>(`/mods/${modId}/files`);
|
||||
}
|
||||
|
||||
export async function getCurseForgeMod(modId: number): Promise<{ data: CurseForgeProject }> {
|
||||
return curseforgeFetch<{ data: CurseForgeProject }>(`/mods/${modId}`);
|
||||
}
|
||||
@@ -11,6 +11,15 @@ export {
|
||||
type SoftwareFamily,
|
||||
} from './modrinth';
|
||||
|
||||
export {
|
||||
searchCurseForgeMods,
|
||||
getCurseForgeModFiles,
|
||||
getCurseForgeMod,
|
||||
type CurseForgeProject,
|
||||
type CurseForgeSearchResponse,
|
||||
type CurseForgeFile,
|
||||
} from './curseforge';
|
||||
|
||||
export {
|
||||
resolveModrinthLoader,
|
||||
resolveProjectType,
|
||||
|
||||
Reference in New Issue
Block a user