Skip to content

Commit 6c955ff

Browse files
authored
Refactor index.ts for improved structure and clarity
1 parent bd51fd8 commit 6c955ff

1 file changed

Lines changed: 65 additions & 79 deletions

File tree

src/index.ts

Lines changed: 65 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
import { OpenAPIHono } from '@hono/zod-openapi'
88
import type { MiddlewareHandler } from 'hono'
99
import { swaggerUI } from '@hono/swagger-ui'
10-
import { app, Bindings } from './utils/hono' // Main 'app' for RUNTIME
10+
// 'app' is the Hono app that handles all our API routes
11+
import { app, Bindings } from './utils/hono'
1112
import { GitHubWorkerRPC } from './rpc'
1213
import { convertOpenAPIToYAML, buildCompleteOpenAPIDocument } from './utils/openapi'
1314
import { MCP_TOOLS, getToolStats, getTool, MCPExecuteRequest, TOOL_ROUTES, serializeTools } from './mcp/tools'
@@ -93,6 +94,7 @@ app.use('*', async (c, next) => {
9394
}
9495
})
9596

97+
// API Key Auth Middleware
9698
const requireApiKey: MiddlewareHandler<{ Bindings: Bindings }> = async (c, next) => {
9799
if (c.req.method === 'OPTIONS') {
98100
await next()
@@ -118,6 +120,7 @@ const requireApiKey: MiddlewareHandler<{ Bindings: Bindings }> = async (c, next)
118120
await next()
119121
}
120122

123+
// Apply auth middleware to all API routes
121124
app.use('/api/*', requireApiKey)
122125
app.use('/mcp/*', requireApiKey)
123126
app.use('/a2a/*', requireApiKey)
@@ -134,17 +137,15 @@ app.post('/webhook', webhookHandler)
134137

135138
// --- 3. API Spec Generation Apps ---
136139

137-
// --- App 1: Full Spec (for /openapi.json) ---
138-
// This app contains *all* API routes for a complete spec.
140+
// App 1: Full Spec (for /openapi.json)
139141
const fullSpecApp = new OpenAPIHono<{ Bindings: Bindings }>()
140142
fullSpecApp.route('/octokit', octokitApi)
141143
fullSpecApp.route('/tools', toolsApi)
142144
fullSpecApp.route('/agents', agentsApi)
143145
fullSpecApp.route('/retrofit', retrofitApi)
144146
fullSpecApp.route('/flows', flowsApi)
145147

146-
// --- App 2: GPT-Specific Spec (for /gpt/openapi.json) ---
147-
// This app contains *only* the 7 methods you requested.
148+
// App 2: GPT-Specific Spec (for /gpt/openapi.json)
148149
const gptSpecApp = new OpenAPIHono<{ Bindings: Bindings }>()
149150
gptSpecApp.route('/octokit', octokitApi) // 3 methods
150151
gptSpecApp.route('/agents', agentsApi) // 2 methods
@@ -272,17 +273,6 @@ app.post('/mcp-execute', async (c) => {
272273
const startTime = Date.now()
273274

274275
try {
275-
// Validate request size (DoS prevention)
276-
const contentLength = c.req.header('content-length')
277-
const MAX_REQUEST_SIZE = 1024 * 1024 // 1MB
278-
if (contentLength && parseInt(contentLength) > MAX_REQUEST_SIZE) {
279-
return c.json({
280-
success: false,
281-
error: 'Request too large',
282-
maxSize: MAX_REQUEST_SIZE,
283-
}, 413)
284-
}
285-
286276
const body = await c.req.json()
287277

288278
// Validate JSON structure
@@ -352,7 +342,7 @@ app.post('/mcp-execute', async (c) => {
352342
}
353343
const result = await response.json();
354344

355-
const durationMs = Date.now() - startTime
345+
const durationMs = Date.Now() - startTime
356346

357347
return c.json({
358348
success: true,
@@ -550,31 +540,39 @@ export default {
550540
*/
551541
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
552542

553-
// This is the correct "SPA Mode" pattern
543+
// --- THIS IS THE CORRECT FETCH HANDLER ---
544+
// It correctly routes API calls to Hono and all other calls to ASSETS.
545+
554546
const url = new URL(request.url);
555-
if (url.pathname === '/') {
556-
// This is a request for the root.
557-
// Manually create a new request for /index.html
558-
const indexRequest = new Request(
559-
new URL('/index.html', request.url),
560-
request
561-
);
562-
try {
563-
return await env.ASSETS.fetch(indexRequest);
564-
} catch (e) {
565-
// Fallback if index.html doesn't exist, just in case
566-
return app.fetch(request, env, ctx);
567-
}
568-
}
569547

570-
try {
571-
// 1. First, try to fetch the request as a static asset.
572-
// This will serve public/landing.html at /landing.html
573-
return await env.ASSETS.fetch(request);
574-
} catch (e) {
575-
// 2. If it's not a static asset (e.g., 404), fall back to the Hono API app.
576-
// The Hono app handles /api, /mcp, /a2a, /openapi.json, etc.
548+
// List of all your API/dynamic prefixes.
549+
// Any request *not* matching these will be treated as a static asset request.
550+
const apiPrefixes = [
551+
'/api/',
552+
'/mcp/',
553+
'/a2a/',
554+
'/openapi.json',
555+
'/openapi.yaml',
556+
'/gpt/openapi.json',
557+
'/gpt/openapi.yaml',
558+
'/doc', // The Swagger UI
559+
'/healthz',
560+
'/webhook',
561+
'/mcp-tools',
562+
'/ws' // WebSocket endpoint
563+
];
564+
565+
const isApiRoute = apiPrefixes.some(prefix => url.pathname.startsWith(prefix));
566+
567+
if (isApiRoute) {
568+
// It's an API route. Let the Hono app handle it.
577569
return app.fetch(request, env, ctx);
570+
} else {
571+
// It's not an API route.
572+
// Assume it's a static asset and let env.ASSETS handle it.
573+
// env.ASSETS will automatically serve /index.html for /
574+
// and a 404 for any other file it can't find.
575+
return env.ASSETS.fetch(request);
578576
}
579577
},
580578

@@ -596,32 +594,37 @@ export default {
596594
const searchResults = await searchRepositoriesWithRetry(searchTerm, env, ctx)
597595

598596
// 2. Analyze each repository
599-
for (const repo of searchResults.items) {
600-
// 2a. Check if the repository has already been analyzed for this session
601-
const { results } = await env.DB.prepare(
602-
'SELECT id FROM repo_analysis WHERE session_id = ? AND repo_full_name = ?'
603-
).bind(sessionId, repo.full_name).all()
604-
605-
if (results.length > 0) {
606-
continue
597+
if (searchResults && searchResults.items) {
598+
for (const repo of searchResults.items) {
599+
// 2a. Check if the repository has already been analyzed for this session
600+
const { results } = await env.DB.prepare(
601+
'SELECT id FROM repo_analysis WHERE session_id = ? AND repo_full_name = ?'
602+
).bind(sessionId, repo.full_name).all()
603+
604+
if (results.length > 0) {
605+
continue
606+
}
607+
608+
// 2b. Analyze the repository
609+
const analysis = await analyzeRepository(repo, searchTerm, aiBinding)
610+
611+
// 2c. Persist the analysis to D1
612+
await env.DB.prepare(
613+
'INSERT INTO repo_analysis (session_id, search_id, repo_full_name, repo_url, description, relevancy_score) VALUES (?, ?, ?, ?, ?, ?)'
614+
).bind(
615+
sessionId,
616+
searchId,
617+
repo.full_name,
618+
repo.html_url,
619+
repo.description,
620+
analysis.relevancyScore
621+
).run()
607622
}
608-
609-
// 2b. Analyze the repository
610-
const analysis = await analyzeRepository(repo, searchTerm, aiBinding)
611-
612-
// 2c. Persist the analysis to D1
613-
await env.DB.prepare(
614-
'INSERT INTO repo_analysis (session_id, search_id, repo_full_name, repo_url, description, relevancy_score) VALUES (?, ?, ?, ?, ?, ?)'
615-
).bind(
616-
sessionId,
617-
searchId,
618-
repo.full_name,
619-
repo.html_url,
620-
repo.description,
621-
analysis.relevancyScore
622-
).run()
623+
} else {
624+
console.warn(`No search results for term: ${searchTerm}`);
623625
}
624626

627+
625628
// 3. Update the search status
626629
await env.DB.prepare(
627630
'UPDATE searches SET status = ? WHERE id = ?'
@@ -644,28 +647,11 @@ export default {
644647
*
645648
* This class is a NAMED export. Other workers must use this name as the 'entrypoint'
646649
* in their service binding configuration to call these RPC methods.
647-
*
648-
* Example consumer wrangler.jsonc:
649-
* {
650-
* "services": [
651-
* {
652-
* "binding": "GITHUB_WORKER",
653-
* "service": "core-github-api",
654-
* "entrypoint": "GitHubWorker" // <-- This is the new required key
655-
* }
656-
* ]
657-
* }
658650
*/
659651
export class GitHubWorker {
660652
private rpc: GitHubWorkerRPC | null = null
661653
private env: Env | null = null
662654

663-
// NOTE: 'fetch' and 'queue' handlers are removed from this class
664-
// and are now on the 'export default' object.
665-
666-
// ==================== RPC Methods ====================
667-
// These methods can be called directly when this worker is used as a service binding
668-
669655
private getRPC(env: Env): GitHubWorkerRPC {
670656
if (!this.rpc || this.env !== env) {
671657
this.env = env

0 commit comments

Comments
 (0)