Skip to content

Commit 56fb982

Browse files
committed
feat: add new API routes for managing output cleanup items and library links
- Implemented `latest-json.js` to fetch the latest updater manifest from GitHub. - Created `library-link.js` for submitting library link requests to GitHub issues. - Added `library-links-data.js` to fetch library links data from the repository. - Developed `livery-patterns-data.js` to retrieve livery patterns data from GitHub. - Introduced `output-cleanup-item-submission.js` for submitting output cleanup items. - Created `output-cleanup-items-data.js` to fetch output cleanup items data. - Added `release-redirect.js` for redirecting to GitHub release pages. - Implemented `update-release.js` to fetch and normalize release data. - Added `OutputCleanup.vue` component for managing output cleanup items in the UI.
1 parent 5ab2099 commit 56fb982

20 files changed

Lines changed: 811 additions & 713 deletions
Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
import bugReportHandler from '../bug-report.js'
2-
import feedbackIssueHandler from '../feedback-issue.js'
3-
import issueCommentHandler from '../issue-comment.js'
4-
import issueDetailHandler from '../issue-detail.js'
5-
import issueDraftHandler from '../issue-draft.js'
6-
import issueRedirectHandler from '../issue-redirect.js'
7-
import issueUpdatesHandler from '../issue-updates.js'
8-
import latestJsonHandler from '../latest-json.js'
9-
import libraryLinkHandler from '../library-link.js'
10-
import libraryLinksDataHandler from '../library-links-data.js'
11-
import liveryPatternsDataHandler from '../livery-patterns-data.js'
12-
import releaseRedirectHandler from '../release-redirect.js'
13-
import updateReleaseHandler from '../update-release.js'
1+
import bugReportHandler from './_lib/routes/bug-report.js'
2+
import feedbackIssueHandler from './_lib/routes/feedback-issue.js'
3+
import issueCommentHandler from './_lib/routes/issue-comment.js'
4+
import issueDetailHandler from './_lib/routes/issue-detail.js'
5+
import issueDraftHandler from './_lib/routes/issue-draft.js'
6+
import issueRedirectHandler from './_lib/routes/issue-redirect.js'
7+
import issueUpdatesHandler from './_lib/routes/issue-updates.js'
8+
import latestJsonHandler from './_lib/routes/latest-json.js'
9+
import libraryLinkHandler from './_lib/routes/library-link.js'
10+
import libraryLinksDataHandler from './_lib/routes/library-links-data.js'
11+
import liveryPatternsDataHandler from './_lib/routes/livery-patterns-data.js'
12+
import outputCleanupItemSubmissionHandler from './_lib/routes/output-cleanup-item-submission.js'
13+
import outputCleanupItemsDataHandler from './_lib/routes/output-cleanup-items-data.js'
14+
import releaseRedirectHandler from './_lib/routes/release-redirect.js'
15+
import updateReleaseHandler from './_lib/routes/update-release.js'
1416

1517
const handlers = {
1618
'bug-report': bugReportHandler,
@@ -24,6 +26,8 @@ const handlers = {
2426
'library-link': libraryLinkHandler,
2527
'library-links-data': libraryLinksDataHandler,
2628
'livery-patterns-data': liveryPatternsDataHandler,
29+
'output-cleanup-item-submission': outputCleanupItemSubmissionHandler,
30+
'output-cleanup-items-data': outputCleanupItemsDataHandler,
2731
'release-redirect': releaseRedirectHandler,
2832
'update-release': updateReleaseHandler,
2933
}
Lines changed: 78 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,86 @@
11
export default async function handler(req, res) {
2-
if (req.method !== 'POST') {
3-
return res.status(405).json({ error: 'Method not allowed' })
4-
}
5-
6-
const { appVersion, os, arch, errorTitle, errorMessage, logs, category } = req.body || {}
7-
8-
if (!errorMessage) {
9-
return res.status(400).json({ error: 'errorMessage is required' })
10-
}
11-
12-
const token = process.env.XFAST_GITHUB_TOKEN
13-
const owner = process.env.GITHUB_OWNER || 'CCA3370'
14-
const repo = process.env.GITHUB_REPO || 'XFast-Manager'
15-
16-
if (!token) {
17-
return res.status(500).json({ error: 'server token not configured' })
18-
}
19-
20-
const summary = String(errorTitle || errorMessage).trim().slice(0, 80)
21-
const issueTitle = `[Bug]: ${summary}`
22-
23-
const issueBody = [
24-
'### Bug Report (Auto-submitted)',
25-
'',
26-
'**Brief Description**',
27-
String(errorTitle || '(not provided)').trim(),
28-
'',
29-
'**Error Message**',
30-
'```',
31-
String(errorMessage).trim(),
32-
'```',
33-
'',
34-
'**Environment**',
35-
`- XFast Manager Version: \`${String(appVersion || 'unknown').trim()}\``,
36-
`- Operating System: \`${String(os || 'unknown').trim()}\``,
37-
`- CPU Architecture: \`${String(arch || 'unknown').trim()}\``,
38-
`- Category: ${String(category || 'Other').trim()}`,
39-
'',
40-
'**Logs**',
41-
'<details>',
42-
'<summary>Click to expand logs</summary>',
43-
'',
44-
'```',
45-
String(logs || '(no logs provided)').trim().slice(0, 50000),
46-
'```',
47-
'</details>',
48-
'',
49-
'---',
50-
'*This issue was auto-submitted from the XFast Manager error dialog.*'
51-
].join('\n')
52-
53-
const ghResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}/issues`, {
54-
method: 'POST',
55-
headers: {
56-
Authorization: `Bearer ${token}`,
57-
Accept: 'application/vnd.github+json',
58-
'Content-Type': 'application/json',
59-
'User-Agent': 'XFast-Manager-Bug-Reporter'
60-
},
61-
body: JSON.stringify({
62-
title: issueTitle,
63-
body: issueBody,
64-
labels: ['bug', 'auto-reported']
65-
})
66-
})
67-
2+
if (req.method !== 'POST') {
3+
return res.status(405).json({ error: 'Method not allowed' })
4+
}
5+
6+
const { appVersion, os, arch, errorTitle, errorMessage, logs, category } = req.body || {}
7+
8+
if (!errorMessage) {
9+
return res.status(400).json({ error: 'errorMessage is required' })
10+
}
11+
12+
const token = process.env.XFAST_GITHUB_TOKEN
13+
const owner = process.env.GITHUB_OWNER || 'CCA3370'
14+
const repo = process.env.GITHUB_REPO || 'XFast-Manager'
15+
16+
if (!token) {
17+
return res.status(500).json({ error: 'server token not configured' })
18+
}
19+
20+
const summary = String(errorTitle || errorMessage)
21+
.trim()
22+
.slice(0, 80)
23+
const issueTitle = `[Bug]: ${summary}`
24+
25+
const issueBody = [
26+
'### Bug Report (Auto-submitted)',
27+
'',
28+
'**Brief Description**',
29+
String(errorTitle || '(not provided)').trim(),
30+
'',
31+
'**Error Message**',
32+
'```',
33+
String(errorMessage).trim(),
34+
'```',
35+
'',
36+
'**Environment**',
37+
`- XFast Manager Version: \`${String(appVersion || 'unknown').trim()}\``,
38+
`- Operating System: \`${String(os || 'unknown').trim()}\``,
39+
`- CPU Architecture: \`${String(arch || 'unknown').trim()}\``,
40+
`- Category: ${String(category || 'Other').trim()}`,
41+
'',
42+
'**Logs**',
43+
'<details>',
44+
'<summary>Click to expand logs</summary>',
45+
'',
46+
'```',
47+
String(logs || '(no logs provided)')
48+
.trim()
49+
.slice(0, 50000),
50+
'```',
51+
'</details>',
52+
'',
53+
'---',
54+
'*This issue was auto-submitted from the XFast Manager error dialog.*',
55+
].join('\n')
56+
57+
const ghResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}/issues`, {
58+
method: 'POST',
59+
headers: {
60+
Authorization: `Bearer ${token}`,
61+
Accept: 'application/vnd.github+json',
62+
'Content-Type': 'application/json',
63+
'User-Agent': 'XFast-Manager-Bug-Reporter',
64+
},
65+
body: JSON.stringify({
66+
title: issueTitle,
67+
body: issueBody,
68+
labels: ['bug', 'auto-reported'],
69+
}),
70+
})
71+
6872
const ghData = await ghResponse.json().catch(() => ({}))
69-
70-
if (!ghResponse.ok) {
71-
return res.status(ghResponse.status).json({ error: ghData })
72-
}
73-
74-
const forwardedHost = req.headers['x-forwarded-host'] || req.headers.host || 'x-fast-manager.vercel.app'
73+
74+
if (!ghResponse.ok) {
75+
return res.status(ghResponse.status).json({ error: ghData })
76+
}
77+
78+
const forwardedHost =
79+
req.headers['x-forwarded-host'] || req.headers.host || 'x-fast-manager.vercel.app'
7580
const forwardedProto = req.headers['x-forwarded-proto'] || 'https'
7681
const origin = `${forwardedProto}://${forwardedHost}`
7782
const issueNumber = Number(ghData.number || 0)
78-
const proxyIssueUrl = issueNumber > 0
79-
? `${origin}/api/issue-redirect?number=${issueNumber}`
80-
: ''
83+
const proxyIssueUrl = issueNumber > 0 ? `${origin}/api/issue-redirect?number=${issueNumber}` : ''
8184

8285
return res.status(200).json({
8386
issueUrl: proxyIssueUrl || ghData.html_url,
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ export default async function handler(req, res) {
1919

2020
const { title, type, content, appVersion, os, arch } = req.body || {}
2121
const feedbackTitle = String(title || '').trim()
22-
const feedbackType = String(type || 'other').trim().toLowerCase()
22+
const feedbackType = String(type || 'other')
23+
.trim()
24+
.toLowerCase()
2325
const feedbackContent = String(content || '').trim()
2426

2527
if (!feedbackTitle) {
@@ -84,13 +86,12 @@ export default async function handler(req, res) {
8486
return res.status(ghResponse.status).json({ error: ghData })
8587
}
8688

87-
const forwardedHost = req.headers['x-forwarded-host'] || req.headers.host || 'x-fast-manager.vercel.app'
89+
const forwardedHost =
90+
req.headers['x-forwarded-host'] || req.headers.host || 'x-fast-manager.vercel.app'
8891
const forwardedProto = req.headers['x-forwarded-proto'] || 'https'
8992
const origin = `${forwardedProto}://${forwardedHost}`
9093
const issueNumber = Number(ghData.number || 0)
91-
const proxyIssueUrl = issueNumber > 0
92-
? `${origin}/api/issue-redirect?number=${issueNumber}`
93-
: ''
94+
const proxyIssueUrl = issueNumber > 0 ? `${origin}/api/issue-redirect?number=${issueNumber}` : ''
9495

9596
return res.status(200).json({
9697
issueUrl: proxyIssueUrl || ghData.html_url,
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ export default async function handler(req, res) {
2121

2222
const issueNumber = toPositiveInt(req.query.issueNumber || req.query.issue_number)
2323
const page = Math.max(1, toPositiveInt(req.query.page, 1))
24-
const perPage = Math.min(100, Math.max(1, toPositiveInt(req.query.perPage || req.query.per_page, 30)))
24+
const perPage = Math.min(
25+
100,
26+
Math.max(1, toPositiveInt(req.query.perPage || req.query.per_page, 30)),
27+
)
2528
if (!issueNumber) {
2629
return res.status(400).json({ error: 'issueNumber must be a positive integer' })
2730
}
@@ -30,7 +33,8 @@ export default async function handler(req, res) {
3033
const repo = process.env.GITHUB_REPO || 'XFast-Manager'
3134
const token = process.env.XFAST_GITHUB_TOKEN || ''
3235
const headers = buildGitHubHeaders(token, 'XFast-Manager-Issue-Detail-Proxy')
33-
const forwardedHost = req.headers['x-forwarded-host'] || req.headers.host || 'x-fast-manager.vercel.app'
36+
const forwardedHost =
37+
req.headers['x-forwarded-host'] || req.headers.host || 'x-fast-manager.vercel.app'
3438
const forwardedProto = req.headers['x-forwarded-proto'] || 'https'
3539
const origin = `${forwardedProto}://${forwardedHost}`
3640

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ export default function handler(req, res) {
2727
const labels = String(req.query.labels || '').trim()
2828
const title = String(req.query.title || '').trim()
2929
const body = String(req.query.body || '').trim()
30-
const mode = String(req.query.mode || '').trim().toLowerCase()
30+
const mode = String(req.query.mode || '')
31+
.trim()
32+
.toLowerCase()
3133

3234
const url = buildIssueNewUrl({
3335
owner,
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ export default async function handler(req, res) {
5151
}
5252

5353
const commentsResponse = await fetch(commentsUrl.toString(), { headers })
54-
const commentsData = commentsResponse.ok
55-
? await commentsResponse.json().catch(() => [])
56-
: []
54+
const commentsData = commentsResponse.ok ? await commentsResponse.json().catch(() => []) : []
5755

5856
const newComments = Array.isArray(commentsData)
5957
? commentsData.map((comment) => ({
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
buildGitHubHeaders,
3-
parseIncludePreRelease,
4-
selectRelease,
5-
} from './_lib/github-release.js'
1+
import { buildGitHubHeaders, parseIncludePreRelease, selectRelease } from '../github-release.js'
62

73
export default async function handler(req, res) {
84
if (req.method !== 'GET') {

0 commit comments

Comments
 (0)