feat:移除了弹窗,服务器添加sls
This commit is contained in:
178
tools/curseforge-mock.mjs
Normal file
178
tools/curseforge-mock.mjs
Normal file
@ -0,0 +1,178 @@
|
||||
import { createServer } from 'node:http'
|
||||
|
||||
const host = '127.0.0.1'
|
||||
const port = Number(process.env.CURSEFORGE_MOCK_PORT ?? 18081)
|
||||
const projectId = 100001
|
||||
const fileId = 200001
|
||||
const fileBody = Buffer.from('Axolotl CurseForge local fixture\n')
|
||||
const now = '2026-07-14T00:00:00Z'
|
||||
|
||||
const file = {
|
||||
id: fileId,
|
||||
gameId: 432,
|
||||
modId: projectId,
|
||||
isAvailable: true,
|
||||
displayName: 'Local Fixture 1.0.0',
|
||||
fileName: 'axolotl-local-fixture-1.0.0.jar',
|
||||
releaseType: 1,
|
||||
fileStatus: 4,
|
||||
hashes: [],
|
||||
fileDate: now,
|
||||
fileLength: fileBody.length,
|
||||
downloadCount: 1,
|
||||
fileSizeOnDisk: fileBody.length,
|
||||
downloadUrl: `http://${host}:${port}/files/axolotl-local-fixture-1.0.0.jar`,
|
||||
gameVersions: ['1.21.1', 'Fabric'],
|
||||
sortableGameVersions: [],
|
||||
dependencies: [],
|
||||
exposeAsAlternative: false,
|
||||
parentProjectFileId: null,
|
||||
alternateFileId: null,
|
||||
isServerPack: false,
|
||||
serverPackFileId: null,
|
||||
isEarlyAccessContent: false,
|
||||
earlyAccessEndDate: null,
|
||||
fileFingerprint: 123456789,
|
||||
modules: [],
|
||||
}
|
||||
|
||||
const project = {
|
||||
id: projectId,
|
||||
gameId: 432,
|
||||
name: 'Axolotl Local Fixture',
|
||||
slug: 'axolotl-local-fixture',
|
||||
links: {
|
||||
websiteUrl: 'https://www.curseforge.com/minecraft/mc-mods',
|
||||
wikiUrl: null,
|
||||
issuesUrl: null,
|
||||
sourceUrl: null,
|
||||
},
|
||||
summary: 'A local CurseForge API fixture used to exercise search, details and installation.',
|
||||
status: 4,
|
||||
downloadCount: 42,
|
||||
isFeatured: false,
|
||||
primaryCategoryId: 6,
|
||||
categories: [
|
||||
{
|
||||
id: 6,
|
||||
gameId: 432,
|
||||
name: 'Fabric',
|
||||
slug: 'fabric',
|
||||
url: 'https://www.curseforge.com/minecraft/mc-mods/fabric',
|
||||
iconUrl: null,
|
||||
dateModified: now,
|
||||
isClass: false,
|
||||
classId: 6,
|
||||
parentCategoryId: null,
|
||||
displayIndex: 0,
|
||||
},
|
||||
],
|
||||
classId: 6,
|
||||
authors: [{ id: 1, name: 'Local Fixture', url: 'https://example.invalid/local-fixture' }],
|
||||
logo: null,
|
||||
screenshots: [],
|
||||
mainFileId: fileId,
|
||||
latestFiles: [file],
|
||||
latestFilesIndexes: [
|
||||
{
|
||||
gameVersion: '1.21.1',
|
||||
fileId,
|
||||
filename: file.fileName,
|
||||
releaseType: 1,
|
||||
gameVersionTypeId: null,
|
||||
modLoader: 4,
|
||||
},
|
||||
],
|
||||
dateCreated: now,
|
||||
dateModified: now,
|
||||
dateReleased: now,
|
||||
allowModDistribution: true,
|
||||
gamePopularityRank: 1,
|
||||
isAvailable: true,
|
||||
thumbsUpCount: 1,
|
||||
}
|
||||
|
||||
function json(response, status, value) {
|
||||
response.writeHead(status, { 'content-type': 'application/json; charset=utf-8' })
|
||||
response.end(JSON.stringify(value))
|
||||
}
|
||||
|
||||
function api(data, pagination) {
|
||||
return pagination ? { data, pagination } : { data }
|
||||
}
|
||||
|
||||
const server = createServer((request, response) => {
|
||||
const url = new URL(request.url ?? '/', `http://${host}:${port}`)
|
||||
const path = url.pathname
|
||||
process.stdout.write(`${request.method} ${url.pathname}${url.search}\n`)
|
||||
|
||||
if (path === '/files/axolotl-local-fixture-1.0.0.jar') {
|
||||
response.writeHead(200, {
|
||||
'content-type': 'application/java-archive',
|
||||
'content-length': fileBody.length,
|
||||
})
|
||||
response.end(fileBody)
|
||||
return
|
||||
}
|
||||
|
||||
if (path === '/v1/games') return json(response, 200, api([]))
|
||||
if (path === '/v1/categories') return json(response, 200, api(project.categories))
|
||||
if (path === '/v1/mods/search') {
|
||||
return json(
|
||||
response,
|
||||
200,
|
||||
api([project], { index: 0, pageSize: 20, resultCount: 1, totalCount: 1 }),
|
||||
)
|
||||
}
|
||||
if (path === '/v1/mods' && request.method === 'POST') {
|
||||
return json(response, 200, api([project]))
|
||||
}
|
||||
if (path === `/v1/mods/${projectId}`) return json(response, 200, api(project))
|
||||
if (path === `/v1/mods/${projectId}/description`) {
|
||||
return json(
|
||||
response,
|
||||
200,
|
||||
api('<h2>Local fixture</h2><p>This response comes from tools/curseforge-mock.mjs.</p>'),
|
||||
)
|
||||
}
|
||||
if (path === `/v1/mods/${projectId}/files`) {
|
||||
return json(
|
||||
response,
|
||||
200,
|
||||
api([file], { index: 0, pageSize: 50, resultCount: 1, totalCount: 1 }),
|
||||
)
|
||||
}
|
||||
if (path === `/v1/mods/${projectId}/files/${fileId}`) {
|
||||
return json(response, 200, api(file))
|
||||
}
|
||||
if (path === `/v1/mods/${projectId}/files/${fileId}/download-url`) {
|
||||
return json(response, 200, api(file.downloadUrl))
|
||||
}
|
||||
if (path === `/v1/mods/${projectId}/files/${fileId}/changelog`) {
|
||||
return json(response, 200, api('<p>Initial local fixture release.</p>'))
|
||||
}
|
||||
if (path === '/v1/mods/files' && request.method === 'POST') {
|
||||
return json(response, 200, api([file]))
|
||||
}
|
||||
if (path === '/v1/fingerprints/432' && request.method === 'POST') {
|
||||
return json(
|
||||
response,
|
||||
200,
|
||||
api({
|
||||
isCacheBuilt: true,
|
||||
exactMatches: [],
|
||||
exactFingerprints: [],
|
||||
partialMatches: [],
|
||||
partialMatchFingerprints: {},
|
||||
installedFingerprints: [],
|
||||
unmatchedFingerprints: [],
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
json(response, 404, { message: `No local fixture route for ${request.method} ${path}` })
|
||||
})
|
||||
|
||||
server.listen(port, host, () => {
|
||||
process.stdout.write(`CurseForge fixture listening on http://${host}:${port}\n`)
|
||||
})
|
||||
Reference in New Issue
Block a user