@codraoss/api 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +625 -0
- package/README.md +15 -0
- package/dist/index.d.ts +138 -0
- package/dist/index.js +1165 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/router.ts","../src/middleware/auth.ts","../src/http.ts","../src/sessions.ts","../src/middleware/csrf.ts","../src/logger.ts","../src/middleware/observability.ts","../src/routes/auth.ts","../src/routes/webhook.ts","../src/routes/api/auth.ts","../src/routes/api/jobs.ts","../src/routes/api/repos.ts","../src/routes/api/stats.ts","../src/routes/api/models.ts","../src/routes/api/settings.ts"],"sourcesContent":["import { Hono } from 'hono';\nimport type { Context } from 'hono';\nimport type { ApiEnv } from './ports';\nimport { requireSession } from './middleware/auth';\nimport { requireCsrfHeader } from './middleware/csrf';\nimport { observability } from './middleware/observability';\nimport { createAuthRouter } from './routes/auth';\nimport { createWebhookRouter } from './routes/webhook';\nimport { createAuthApiRouter } from './routes/api/auth';\nimport { createJobsRouter } from './routes/api/jobs';\nimport { createReposRouter } from './routes/api/repos';\nimport { createStatsRouter } from './routes/api/stats';\nimport { createModelsRouter } from './routes/api/models';\nimport { createSettingsRouter } from './routes/api/settings';\n\nasync function serveIndex(c: Context<ApiEnv>) {\n // If the host platform passes an ASSETS binding via `c.env`, use it (e.g., Cloudflare Workers).\n const assetsFetch = (c.env as any).ASSETS?.fetch;\n if (typeof assetsFetch === 'function') {\n return assetsFetch(new URL('/index.html', c.req.url));\n }\n \n return c.text('Not Found: Please mount UI static assets handler here.', 404);\n}\n\nexport function createApiRouter() {\n const app = new Hono<ApiEnv>();\n\n app.use('*', observability);\n app.use('/auth/logout', requireSession);\n app.use('/auth/logout', requireCsrfHeader);\n\n app.route('/auth', createAuthRouter());\n app.route('/webhook', createWebhookRouter());\n\n app.use('/api/*', requireSession);\n app.use('/api/*', requireCsrfHeader);\n\n app.route('/api/auth', createAuthApiRouter());\n app.route('/api/jobs', createJobsRouter());\n app.route('/api/repos', createReposRouter());\n app.route('/api/stats', createStatsRouter());\n app.route('/api/models', createModelsRouter());\n app.route('/api/settings', createSettingsRouter());\n\n app.get('/login', serveIndex);\n app.get('/', serveIndex); // Unauthenticated landing page\n app.get('/dashboard', requireSession, serveIndex);\n app.get('/jobs', requireSession, serveIndex);\n app.get('/jobs/*', requireSession, serveIndex);\n app.get('/repos', requireSession, serveIndex);\n app.get('/stats', requireSession, serveIndex);\n app.get('/health', requireSession, serveIndex);\n app.get('/settings', requireSession, serveIndex);\n app.get('/account', requireSession, serveIndex);\n\n return app;\n}\n","import { createMiddleware } from 'hono/factory';\nimport type { ApiEnv } from '../ports';\nimport { wantsHtml } from '../http';\nimport { readSession } from '../sessions';\n\nexport const requireSession = createMiddleware<ApiEnv>(async (c, next) => {\n const session = await readSession(c);\n if (!session) {\n if (wantsHtml(c.req.raw)) {\n return c.redirect('/login');\n }\n\n return Response.json({ error: 'Unauthorized' }, { status: 401 });\n }\n\n await next();\n});\n","export function jsonError(message: string, status = 400) {\n return Response.json({ error: message }, { status });\n}\n\nexport function wantsHtml(request: Request) {\n const accept = request.headers.get('accept') ?? '';\n return accept.includes('text/html');\n}\n","import { deleteCookie, getCookie, setCookie } from 'hono/cookie';\nimport type { Context } from 'hono';\nimport type { ApiEnv } from './ports';\nimport type { DashboardSessionUser } from '@codraoss/core/ports';\n\nconst SESSION_COOKIE_NAME = 'codra_session';\nconst SESSION_TTL_SECONDS = 60 * 60 * 24 * 7;\n\ntype SessionRecord = DashboardSessionUser;\n\nexport async function createSession(c: Context<ApiEnv>, session: SessionRecord) {\n const token = await c.env.deps.sessionStore.createSession(session);\n\n setCookie(c, SESSION_COOKIE_NAME, token, {\n httpOnly: true,\n sameSite: 'Lax',\n secure: true,\n path: '/',\n maxAge: SESSION_TTL_SECONDS,\n });\n\n c.set('sessionToken', token);\n c.set('sessionUser', session);\n\n return token;\n}\n\nexport async function destroySession(c: Context<ApiEnv>) {\n const token = getCookie(c, SESSION_COOKIE_NAME);\n if (token) {\n await c.env.deps.sessionStore.destroySession(token);\n }\n\n c.set('sessionToken', null);\n c.set('sessionUser', null);\n\n deleteCookie(c, SESSION_COOKIE_NAME, {\n path: '/',\n });\n}\n\nexport async function readSession(c: Context<ApiEnv>) {\n const token = getCookie(c, SESSION_COOKIE_NAME) ?? null;\n c.set('sessionToken', token);\n\n if (!token) {\n c.set('sessionUser', null);\n return null;\n }\n\n const session = await c.env.deps.sessionStore.readSession(token);\n c.set('sessionUser', session);\n return session;\n}\n","import { createMiddleware } from 'hono/factory';\nimport type { ApiEnv } from '../ports';\n\nconst SAFE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);\nconst REQUESTED_WITH = 'XMLHttpRequest';\n\nexport const requireCsrfHeader = createMiddleware<ApiEnv>(async (c, next) => {\n if (SAFE_METHODS.has(c.req.method.toUpperCase())) {\n await next();\n return;\n }\n\n if (c.req.header('x-requested-with') !== REQUESTED_WITH) {\n return c.json({ error: 'Forbidden' }, 403);\n }\n\n await next();\n});\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport { formatLogRecord, setLoggerSink } from '@codraoss/core/logger';\n\n// The request-context half of the logger. Scrubbing and record shaping live in @codraoss/core/logger;\n// this file owns everything platform-bound -- AsyncLocalStorage and the console sink -- so that\n// node:async_hooks never enters the engine package. Importing this module installs it as the sink\n// that @codraoss/core's `logger` facade delegates to (see the bottom of the file).\nconst storage = new AsyncLocalStorage<Record<string, any>>();\n\nclass Logger {\n constructor(private context: Record<string, any> = {}) {}\n\n withContext(newContext: Record<string, any>) {\n return new Logger({ ...this.context, ...newContext });\n }\n\n private log(level: string, message: string, data?: any) {\n const store = storage.getStore() || {};\n const output = formatLogRecord(level, message, [store, this.context], data);\n\n if (level === 'error') {\n console.error(JSON.stringify(output));\n } else if (level === 'warn') {\n console.warn(JSON.stringify(output));\n } else {\n console.log(JSON.stringify(output));\n }\n }\n\n runWithContext<T>(context: Record<string, any>, fn: () => T): T {\n return storage.run({ ...storage.getStore(), ...context }, fn);\n }\n\n info(message: string, data?: any) {\n this.log('info', message, data);\n }\n\n error(message: string, data?: any) {\n if (data instanceof Error) {\n this.log('error', message, {\n name: data.name,\n message: data.message,\n stack: data.stack,\n });\n } else {\n this.log('error', message, data);\n }\n }\n\n warn(message: string, data?: any) {\n this.log('warn', message, data);\n }\n\n debug(message: string, data?: any) {\n this.log('debug', message, data);\n }\n}\n\nexport const logger = new Logger();\n\n// Wired at import scope so engine code logging through @codraoss/core's facade lands here, with request\n// context attached, rather than in core's bare console fallback.\nsetLoggerSink(logger);\n","import type { MiddlewareHandler } from 'hono';\nimport type { ApiEnv } from '../ports';\nimport { logger } from '../logger';\n\nexport const observability: MiddlewareHandler<ApiEnv> = async (c, next) => {\n const requestId = c.req.header('x-request-id') || crypto.randomUUID();\n c.set('requestId', requestId);\n\n return logger.runWithContext({\n requestId,\n method: c.req.method,\n path: c.req.path,\n }, async () => {\n logger.info(`Incoming request: ${c.req.method} ${c.req.path}`);\n\n const start = Date.now();\n await next();\n const duration = Date.now() - start;\n\n logger.info(`Request completed: ${c.req.method} ${c.req.path}`, {\n status: c.res.status,\n durationMs: duration,\n });\n });\n};\n","import { Hono } from 'hono';\nimport type { ApiEnv } from '../ports';\nimport { createSession, destroySession } from '../sessions';\n\nfunction redirectToLogin(reason: string) {\n const params = new URLSearchParams({ error: reason });\n return `/login?${params.toString()}`;\n}\n\nexport function parseAllowedUsers(input: string) {\n return new Set(\n input\n .split(',')\n .map((value) => value.trim().toLowerCase())\n .filter(Boolean),\n );\n}\n\nexport function createAuthRouter() {\n const app = new Hono<ApiEnv>();\n\n app.get('/github', async (c) => {\n const state = await c.env.deps.authProvider.createOAuthState();\n const result = await c.env.deps.authProvider.beginAuthorization(c.env.AUTH_CALLBACK_URL, state);\n return c.redirect(result.url, 302);\n });\n\n app.get('/github/callback', async (c) => {\n const error = c.req.query('error');\n if (error) {\n return c.redirect(redirectToLogin(error), 302);\n }\n\n const code = c.req.query('code')?.trim();\n const state = c.req.query('state')?.trim();\n if (!code || !state) {\n return c.redirect(redirectToLogin('invalid_callback'), 302);\n }\n\n const stateMatches = await c.env.deps.authProvider.consumeOAuthState(state);\n if (!stateMatches) {\n return c.redirect(redirectToLogin('invalid_state'), 302);\n }\n\n try {\n const { identity } = await c.env.deps.authProvider.completeAuthorization(code, state, state);\n const allowedUsers = parseAllowedUsers(c.env.DASHBOARD_ALLOWED_USERS);\n\n if (!allowedUsers.has(identity.login.toLowerCase())) {\n return c.redirect(redirectToLogin('not_allowed'), 302);\n }\n\n await destroySession(c);\n await createSession(c, identity);\n\n // Best-effort: a DB hiccup must not block sign-in (the account page self-heals on next load).\n try {\n await c.env.deps.repositories.accounts.upsertAccountSettings(c.env as any, {\n githubUserId: Number(identity.providerUserId),\n githubUsername: identity.login,\n accountName: identity.name,\n accountEmail: identity.email,\n });\n } catch (err) {\n c.env.deps.platform.logger.warn('Failed to persist account settings on sign-in', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n\n return c.redirect('/dashboard', 302);\n } catch {\n return c.redirect(redirectToLogin('oauth_failed'), 302);\n }\n });\n\n app.post('/logout', async (c) => {\n await destroySession(c);\n return c.json({ ok: true });\n });\n\n return app;\n}\n","import { Hono } from 'hono';\nimport type { Context } from 'hono';\nimport {\n isFeedbackGitHubWebhookEvent,\n type FeedbackWebhookPayload,\n type GitHubReviewCommentPayload,\n type GitHubWebhookPayload,\n} from '@codraoss/schema/github';\nimport type { ApiEnv } from '../ports';\nimport { jsonError } from '../http';\n\n// Matches via the invisible `codra-fp` marker GitHub echoes back verbatim; comments without one are ignored. Best-effort: failures here must never surface as a webhook error GitHub retries.\nasync function handleFeedbackEvent(\n c: Context<ApiEnv>,\n input: {\n eventName: string;\n payload: FeedbackWebhookPayload;\n repositoryId: number | null;\n },\n): Promise<number> {\n const { eventName, payload, repositoryId } = input;\n // The repository has to be one we know; the FK would reject anything else.\n if (repositoryId === null) return 0;\n\n const botLogin = (c.env.BOT_USERNAME ?? '').toLowerCase();\n // GitHub fires these events for human threads too; without this filter we'd suppress our own findings based on humans deleting each other's comments.\n const isOurs = (comment: GitHubReviewCommentPayload) =>\n Boolean(botLogin) && (comment.user?.login ?? '').toLowerCase().startsWith(botLogin);\n\n const prNumber = payload.pull_request?.number ?? null;\n const entries: any[] = [];\n const reopened: number[] = [];\n\n const add = (comment: GitHubReviewCommentPayload, outcome: any) => {\n if (!isOurs(comment) || !comment?.body) return;\n \n // We need a port for parsing finding markers since it used to come from @server/services/formatter\n // We'll use a local minimal parser or expect the webhook port to provide it\n const markerMatch = (comment.body || '').match(/<!-- codra-fp: (.*?) -->/);\n if (!markerMatch) return;\n \n let fingerprint = markerMatch[1];\n let anchorHash = '';\n let fingerprintV2 = null;\n try {\n const parts = JSON.parse(fingerprint);\n if (Array.isArray(parts) && parts.length >= 2) {\n fingerprintV2 = parts[0];\n fingerprint = parts[1];\n if (parts.length >= 3) anchorHash = parts[2];\n }\n } catch {\n // old format\n }\n \n entries.push({\n repositoryId,\n prNumber,\n fingerprint,\n anchorHash,\n fingerprintV2,\n githubCommentId: comment.id,\n outcome,\n });\n };\n\n if (eventName === 'pull_request_review_comment') {\n const { action, comment } = payload as Extract<FeedbackWebhookPayload, { comment: unknown }>;\n // 'created' is how we learn the real GitHub comment id for free, with no extra request; 'deleted' is the only negative signal we act on.\n if (action === 'created') add(comment, 'posted');\n else if (action === 'deleted') add(comment, 'deleted');\n } else if (eventName === 'pull_request_review_thread') {\n const { action, thread } = payload as Extract<FeedbackWebhookPayload, { thread: unknown }>;\n for (const comment of thread?.comments ?? []) {\n if (action === 'resolved') {\n add(comment, 'resolved');\n } else if (action === 'unresolved') {\n add(comment, 'unresolved');\n if (isOurs(comment)) reopened.push(comment.id);\n }\n }\n }\n\n if (entries.length === 0) return 0;\n\n try {\n const feedbackRepo = c.env.deps.repositories.commentFeedback;\n // Reopening a thread must retract the earlier 'resolved' row, or the finding stays recorded as accepted forever.\n if (reopened.length > 0) await feedbackRepo.clearResolvedFeedback(c.env as any, repositoryId, reopened);\n return await feedbackRepo.recordCommentFeedback(c.env as any, entries);\n } catch (error) {\n c.env.deps.platform.logger.warn('Could not record comment feedback', {\n eventName,\n repositoryId,\n error: error instanceof Error ? error.message : String(error),\n });\n return 0;\n }\n}\n\nexport async function handleGitHubWebhook(c: Context<ApiEnv>) {\n const eventName = c.req.header('x-github-event');\n const deliveryId = c.req.header('x-github-delivery');\n const signature = c.req.header('x-hub-signature-256');\n const rawBody = await c.req.text();\n\n if (!eventName || !deliveryId) {\n return jsonError('Missing GitHub webhook headers.', 400);\n }\n\n const verified = await c.env.deps.webhook.verifySignature(signature ?? null, rawBody);\n if (!verified) {\n return jsonError('Invalid webhook signature.', 401);\n }\n\n let payload: GitHubWebhookPayload;\n try {\n payload = JSON.parse(rawBody) as GitHubWebhookPayload;\n } catch {\n return jsonError('Invalid webhook JSON payload.', 400);\n }\n\n // Feedback deliveries carry the whole PR object plus diff hunks per comment; skip storing the payload (row is still written, so dedup still works).\n const isFeedbackEvent = isFeedbackGitHubWebhookEvent(eventName);\n\n const delivery = await c.env.deps.repositories.webhookDeliveries.recordWebhookDelivery(c.env as any, {\n deliveryId,\n eventName,\n owner: 'repository' in payload ? (payload as any).repository.owner.login : null,\n repo: 'repository' in payload ? (payload as any).repository.name : null,\n payload: isFeedbackEvent ? null : payload,\n });\n\n if (!delivery.inserted) {\n return c.json({ ok: true, duplicate: true }, 202);\n }\n\n const installationId = String((payload as any).installation?.id ?? '');\n if (!installationId || !('repository' in payload) || !payload.repository) {\n return c.json({ ok: true, ignored: true }, 202);\n }\n\n // Handled inline before loadRepoConfig: recording feedback needs no repo config, queue message, or Workflow, so skip that KV/DB cost entirely.\n if (isFeedbackEvent) {\n const recorded = await handleFeedbackEvent(c, {\n eventName,\n payload: payload as unknown as FeedbackWebhookPayload,\n repositoryId: delivery.repositoryId,\n });\n return c.json({ ok: true, feedback: true, recorded }, 202);\n }\n\n const normalized = c.env.deps.webhook.normalizePayload(eventName, payload);\n if (!normalized) {\n return c.json({ ok: true, ignored: true, eventName }, 202);\n }\n\n const repoConfig = await c.env.deps.config.loadRepoConfig({\n installationId,\n owner: (payload as any).repository.owner.login,\n repo: (payload as any).repository.name,\n });\n\n if (repoConfig.enabled === false) {\n return c.json({ ok: true, ignored: true, reason: 'repository_disabled' }, 202);\n }\n\n const extracted = c.env.deps.webhook.extractReviewRequest({\n eventName: normalized.eventName,\n payload: normalized.payload,\n botUsername: c.env.BOT_USERNAME,\n config: repoConfig.parsedJson,\n });\n\n if (extracted?.commitSha && extracted.baseSha) {\n const jobsRepo = c.env.deps.repositories.jobs;\n const existingJob = await jobsRepo.findExistingJobForHead(c.env as any, {\n owner: extracted.owner,\n repo: extracted.repo,\n prNumber: extracted.prNumber,\n commitSha: extracted.commitSha,\n trigger: extracted.trigger,\n });\n\n if (existingJob) {\n return c.json({\n ok: true,\n duplicate: true,\n message: existingJob.status === 'queued' ? 'queued' : 'duplicate',\n job: existingJob,\n }, 202);\n }\n\n const job = await jobsRepo.insertJob(c.env as any, {\n installationId: extracted.installationId,\n owner: extracted.owner,\n repo: extracted.repo,\n prNumber: extracted.prNumber,\n prTitle: extracted.prTitle,\n prAuthor: extracted.prAuthor,\n commitSha: extracted.commitSha,\n baseSha: extracted.baseSha,\n trigger: extracted.trigger,\n headRef: extracted.headRef,\n baseRef: extracted.baseRef,\n configSnapshot: repoConfig.parsedJson,\n });\n\n await jobsRepo.supersedeOlderJobs(c.env as any, {\n installationId: extracted.installationId,\n owner: extracted.owner,\n repo: extracted.repo,\n prNumber: extracted.prNumber,\n newJobId: job.id,\n });\n\n await c.env.deps.platform.enqueueReviewJob({\n jobId: job.id,\n deliveryId,\n phase: 'prepare',\n requestId: c.get('requestId'),\n });\n\n return c.json({ ok: true, message: 'queued', job }, 202);\n }\n\n // Events without a concrete job (e.g. PR close cleanup, mention lookups) still get handled by the worker.\n await c.env.deps.platform.enqueueReviewJob({\n deliveryId,\n eventName,\n requestId: c.get('requestId'),\n } as any);\n\n return c.json({ ok: true, message: 'queued' }, 202);\n}\n\nexport function createWebhookRouter() {\n const app = new Hono<ApiEnv>();\n\n app.post('/', handleGitHubWebhook);\n\n return app;\n}\n","import { isSupportedTimeZone } from '@codraoss/schema/timezone';\nimport { Hono } from 'hono';\nimport { z } from 'zod';\nimport { jsonError } from '../../http';\nimport type { ApiEnv } from '../../ports';\n\nconst emailSchema = z.strictObject({\n email: z.string().trim().email().max(254),\n});\n\n// Fields are independently optional (at least one required); timezone null means \"follow the browser\", else must be an Intl-known zone.\nconst accountUpdateSchema = z.strictObject({\n name: z.string().trim().min(1).max(120).optional(),\n timezone: z.string().trim().min(1).max(64).refine(isSupportedTimeZone, {\n message: 'Unknown time zone.',\n }).nullable().optional(),\n}).refine(\n (body) => body.name !== undefined || body.timezone !== undefined,\n { message: 'Nothing to update.' },\n);\n\nexport function createAuthApiRouter() {\n const app = new Hono<ApiEnv>();\n\n app.get('/session', async (c) => {\n const sessionUser = c.get('sessionUser');\n if (!sessionUser) {\n return Response.json({ error: 'Unauthorized' }, { status: 401 });\n }\n\n return c.json({ user: sessionUser });\n });\n\n app.get('/account', async (c) => {\n const sessionUser = c.get('sessionUser');\n if (!sessionUser) {\n return Response.json({ error: 'Unauthorized' }, { status: 401 });\n }\n\n const accounts = c.env.deps.repositories.accounts;\n const githubUserId = Number(sessionUser.providerUserId);\n\n // Self-heals for sessions created before the account_settings table existed.\n let account = await accounts.getAccountSettings(c.env as any, githubUserId);\n if (!account) {\n account = await accounts.upsertAccountSettings(c.env as any, {\n githubUserId,\n githubUsername: sessionUser.login,\n accountName: sessionUser.name,\n accountEmail: sessionUser.email,\n });\n }\n\n return c.json({ account });\n });\n\n app.patch('/account', async (c) => {\n const sessionUser = c.get('sessionUser');\n if (!sessionUser) {\n return Response.json({ error: 'Unauthorized' }, { status: 401 });\n }\n\n const body = await c.req.json().catch(() => null);\n const parsed = accountUpdateSchema.safeParse(body);\n if (!parsed.success) {\n const issue = parsed.error.issues[0]?.message;\n return jsonError(\n issue && issue !== 'Invalid input' ? issue : 'Enter a name (1-120 characters).',\n 400,\n );\n }\n\n const accounts = c.env.deps.repositories.accounts;\n const githubUserId = Number(sessionUser.providerUserId);\n\n // Ensure a row exists first (self-heal for pre-existing sessions), then update.\n const existing = await accounts.getAccountSettings(c.env as any, githubUserId);\n if (!existing) {\n await accounts.upsertAccountSettings(c.env as any, {\n githubUserId,\n githubUsername: sessionUser.login,\n accountName: sessionUser.name,\n accountEmail: sessionUser.email,\n });\n }\n\n const account = await accounts.updateAccountSettings(c.env as any, githubUserId, {\n accountName: parsed.data.name,\n timezone: parsed.data.timezone,\n });\n return c.json({ account });\n });\n\n app.get('/updates-email', async (c) => {\n const sessionUser = c.get('sessionUser');\n if (!sessionUser) {\n return Response.json({ error: 'Unauthorized' }, { status: 401 });\n }\n\n const githubUserId = Number(sessionUser.providerUserId);\n const preference = await c.env.deps.platform.getUpdatesEmailPreference(githubUserId);\n return c.json({\n status: preference?.status ?? 'pending',\n email: preference?.email ?? null,\n updatedAt: preference?.updatedAt ?? null,\n });\n });\n\n app.post('/updates-email', async (c) => {\n const sessionUser = c.get('sessionUser');\n if (!sessionUser) {\n return Response.json({ error: 'Unauthorized' }, { status: 401 });\n }\n\n const body = await c.req.json().catch(() => null);\n const parsed = emailSchema.safeParse(body);\n if (!parsed.success) {\n return jsonError('Enter a valid email address.', 400);\n }\n\n const platform = c.env.deps.platform;\n const githubUserId = Number(sessionUser.providerUserId);\n\n const existingPreference = await platform.getUpdatesEmailPreference(githubUserId);\n if (existingPreference) {\n return c.json({\n status: existingPreference.status,\n email: existingPreference.email,\n updatedAt: existingPreference.updatedAt,\n });\n }\n\n const synced = await platform.syncUpdatesEmail(githubUserId, parsed.data.email);\n if (!synced) {\n return jsonError('Could not save updates email right now.', 502);\n }\n\n const preference = await platform.getUpdatesEmailPreference(githubUserId);\n\n return c.json({\n status: preference?.status ?? 'pending',\n email: preference?.email ?? null,\n updatedAt: preference?.updatedAt ?? null,\n });\n });\n\n return app;\n}\n","import { Hono } from 'hono';\nimport type { Context } from 'hono';\nimport { defaultRepoConfig, findingLabelSchema, jobsQuerySchema } from '@codraoss/schema';\nimport { jsonError } from '../../http';\nimport { parseUnifiedDiff } from '@codraoss/core/diff';\nimport { buildFileReviewPrompts } from '@codraoss/core/prompts/file-review';\nimport type { ApiEnv } from '../../ports';\n\n// Best-effort terminate; .get() throws if the instance is gone and .terminate() if already terminal, both non-fatal.\nasync function terminateJobWorkflow(c: Context<ApiEnv>, job: { id: string; workflowInstanceId?: string | null }) {\n // This interacts with bindings. The plan says \"No binding access in a handler\".\n // So we need to put workflow termination behind a platform port.\n // Wait! The user plan says: \"call a packages/core use case\". \n // Let's add it to `platform` port as well.\n await c.env.deps.platform.terminateJobWorkflow(job);\n}\n\nfunction jobEtag(input: { id: string; status: string; updatedAt: string; fileCount: number; commentCount: number }) {\n return `\"job-${input.id}-${input.status}-${input.fileCount}-${input.commentCount}-${new Date(input.updatedAt).getTime()}\"`;\n}\n\nfunction getExecutionContext(c: Context<ApiEnv>) {\n try {\n return c.executionCtx;\n } catch {\n return undefined;\n }\n}\n\nexport function createJobsRouter() {\n const app = new Hono<ApiEnv>();\n\n app.get('/', async (c) => {\n c.env.deps.platform.scheduleBestEffortJobMaintenance(getExecutionContext(c));\n\n const rawQuery = c.req.query();\n const query = jobsQuerySchema.parse(rawQuery);\n\n const result = await c.env.deps.repositories.jobs.listJobs(c.env as any, query as any);\n return c.json(result);\n });\n\n app.get('/:id', async (c) => {\n c.env.deps.platform.scheduleBestEffortJobMaintenance(getExecutionContext(c));\n\n const job = await c.env.deps.repositories.jobs.getJobDetail(c.env as any, c.req.param('id'));\n if (!job) {\n return jsonError('Job not found.', 404);\n }\n\n const etag = jobEtag(job);\n const lastModified = new Date(job.updatedAt).toUTCString();\n if (c.req.header('if-none-match') === etag) {\n return new Response(null, {\n status: 304,\n headers: {\n ETag: etag,\n 'Last-Modified': lastModified,\n },\n });\n }\n\n const response = c.json({ job });\n response.headers.set('ETag', etag);\n response.headers.set('Last-Modified', lastModified);\n response.headers.set('Cache-Control', 'private, no-cache');\n return response;\n });\n\n // diff_input is not persisted; rebuilt on demand from the job's own base/head commits (not the live PR), using the KV cache while warm.\n app.get('/:id/diffs', async (c) => {\n const job = await c.env.deps.repositories.jobs.getJobDetail(c.env as any, c.req.param('id'));\n if (!job) {\n return jsonError('Job not found.', 404);\n }\n\n const config = job.configSnapshot ?? defaultRepoConfig;\n const github = c.env.deps.gitProvider.createService(job.installationId);\n\n let rawDiff: string;\n try {\n rawDiff = await c.env.deps.platform.getOrFetchRawDiffForCompletedJob(\n c.env.deps.platform.createReviewRuntime(),\n { id: job.id, owner: job.owner, repo: job.repo, baseSha: job.baseSha, commitSha: job.commitSha },\n github,\n );\n } catch (error) {\n // Need logger from deps or imported directly since we moved it\n c.env.deps.platform.logger.warn(`Could not reconstruct diff for job ${job.id}`, error instanceof Error ? error : new Error(String(error)));\n return c.json({ diffs: {} });\n }\n\n // Must include the PR description: this reconstructs the prompt the model actually saw.\n let prDescription: string | null = null;\n try {\n prDescription = (await github.getPullRequest(job.owner, job.repo, job.prNumber)).body ?? null;\n } catch (error) {\n // Best-effort: a missing description degrades fidelity, never fails the view.\n c.env.deps.platform.logger.warn(`Could not load the PR body for job ${job.id}; prompts will omit the description`,\n error instanceof Error ? error : new Error(String(error)));\n }\n\n // The ENTIRE PR diff, not just files with a review row, so Files-changed matches GitHub mid-review.\n const diffs: Record<string, string> = {};\n for (const file of parseUnifiedDiff(rawDiff, config.review)) {\n if (file.isDeleted || file.isBinary || !file.path) continue;\n diffs[file.path] = buildFileReviewPrompts({\n file,\n prTitle: job.prTitle,\n prDescription,\n config: config.review,\n }).userPrompt;\n }\n\n const response = c.json({ diffs });\n response.headers.set('Cache-Control', 'private, max-age=60');\n return response;\n });\n\n // Shared by re-run and rerun-from-start; inherit=true links retryOfJobId and reuses `done` file reviews, false reviews everything.\n async function startReplacementJob(c: Context<ApiEnv>, rawSource: any, options: { inherit: boolean }) {\n const jobs = c.env.deps.repositories.jobs;\n const source = jobs.mapJob(rawSource);\n let configSnapshot;\n try {\n const currentConfig = await c.env.deps.config.loadRepoConfig({\n installationId: source.installationId,\n owner: source.owner,\n repo: source.repo,\n });\n configSnapshot = currentConfig?.parsedJson ?? defaultRepoConfig;\n } catch (e) {\n configSnapshot = defaultRepoConfig;\n }\n\n const job = await jobs.insertJob(c.env as any, {\n installationId: source.installationId,\n owner: source.owner,\n repo: source.repo,\n prNumber: source.prNumber,\n prTitle: source.prTitle,\n prAuthor: source.prAuthor,\n commitSha: source.commitSha,\n baseSha: jobs.bytesToHex(rawSource.base_sha), // base_sha is only in raw row/detail\n trigger: 'retry',\n headRef: rawSource.head_ref,\n baseRef: rawSource.base_ref,\n configSnapshot,\n ...(options.inherit ? { retryOfJobId: source.id } : {}),\n });\n\n await jobs.supersedeOlderJobs(c.env as any, {\n installationId: source.installationId,\n owner: source.owner,\n repo: source.repo,\n prNumber: source.prNumber,\n newJobId: job.id,\n });\n\n await c.env.deps.platform.enqueueReviewJob({\n jobId: job.id,\n deliveryId: crypto.randomUUID(),\n phase: 'prepare',\n requestId: c.get('requestId'),\n });\n\n return job;\n }\n\n // Re-run: reuse the parent's completed reviews where the model strategy still matches.\n app.post('/:id/retry', async (c) => {\n const jobs = c.env.deps.repositories.jobs;\n const rawSource = await jobs.getJobForProcessing(c.env as any, c.req.param('id'));\n if (!rawSource) {\n return jsonError('Job not found.', 404);\n }\n const job = await startReplacementJob(c, rawSource, { inherit: true });\n return c.json({ job }, 202);\n });\n\n // Rerun from start: no inheritance. Stops the current run so two workflows cannot race.\n app.post('/:id/rerun', async (c) => {\n const jobs = c.env.deps.repositories.jobs;\n const rawSource = await jobs.getJobForProcessing(c.env as any, c.req.param('id'));\n if (!rawSource) {\n return jsonError('Job not found.', 404);\n }\n const source = jobs.mapJob(rawSource);\n if (source.status === 'queued' || source.status === 'running') {\n await terminateJobWorkflow(c, source);\n }\n const job = await startReplacementJob(c, rawSource, { inherit: false });\n return c.json({ job }, 202);\n });\n\n app.post('/:id/stop', async (c) => {\n const jobs = c.env.deps.repositories.jobs;\n const id = c.req.param('id');\n const raw = await jobs.getJobForProcessing(c.env as any, id);\n if (!raw) {\n return jsonError('Job not found.', 404);\n }\n const job = jobs.mapJob(raw);\n if (job.status !== 'queued' && job.status !== 'running') {\n return jsonError('Only a queued or running job can be stopped.', 409);\n }\n await terminateJobWorkflow(c, job);\n await jobs.cancelJob(c.env as any, id);\n const updated = await jobs.getJobForProcessing(c.env as any, id);\n return c.json({ job: updated ? jobs.mapJob(updated) : job }, 200);\n });\n\n // Human verdict on one finding: WRONG suppresses repository-wide, RIGHT suppresses nothing and is purely measurement.\n app.put('/:id/findings/:fingerprint/label', async (c) => {\n const jobId = c.req.param('id');\n const fingerprint = c.req.param('fingerprint');\n\n const parsed = findingLabelSchema.safeParse(await c.req.json().catch(() => null));\n if (!parsed.success) return jsonError('Body must be {\"label\":\"right\"|\"wrong\"}.', 400);\n\n const target = await c.env.deps.repositories.fileReviews.getFindingLabelTarget(c.env as any, jobId, fingerprint);\n if (!target) return jsonError('Finding not found on this job.', 404);\n\n await c.env.deps.repositories.commentFeedback.upsertDashboardFeedback(c.env as any, {\n repositoryId: target.repository_id,\n prNumber: target.pr_number,\n fingerprint,\n anchorHash: target.anchor_hash,\n // Carried so a rejection survives the model rewording its title.\n fingerprintV2: target.fingerprint_v2,\n jobId,\n labelledBy: c.get('sessionUser')?.providerUserId ? Number(c.get('sessionUser')?.providerUserId) : null,\n outcome: parsed.data.label === 'wrong' ? 'marked_wrong' : 'marked_right',\n });\n\n return c.json({ label: parsed.data.label }, 200);\n });\n\n // Undo a label, scoped to dashboard rows so a real GitHub deletion stays recorded.\n app.delete('/:id/findings/:fingerprint/label', async (c) => {\n const jobId = c.req.param('id');\n const fingerprint = c.req.param('fingerprint');\n\n const target = await c.env.deps.repositories.fileReviews.getFindingLabelTarget(c.env as any, jobId, fingerprint);\n if (!target) return jsonError('Finding not found on this job.', 404);\n\n await c.env.deps.repositories.commentFeedback.clearDashboardFeedback(c.env as any, target.repository_id, fingerprint);\n return c.body(null, 204);\n });\n\n app.delete('/:id', async (c) => {\n const jobs = c.env.deps.repositories.jobs;\n const id = c.req.param('id');\n const raw = await jobs.getJobForProcessing(c.env as any, id);\n if (!raw) {\n return jsonError('Job not found.', 404);\n }\n const job = jobs.mapJob(raw);\n if (job.status === 'queued' || job.status === 'running') {\n await terminateJobWorkflow(c, job);\n }\n await jobs.deleteJob(c.env as any, id);\n return c.body(null, 204);\n });\n\n return app;\n}\n","import { Hono } from 'hono';\nimport { z } from 'zod';\nimport type { ApiEnv } from '../../ports';\nimport { jsonError } from '../../http';\nimport { repoConfigSchema } from '@codraoss/schema';\n\nconst repoConfigPatchSchema = z\n .strictObject({\n enabled: z.boolean().optional(),\n review: repoConfigSchema.shape.review.optional(),\n model: repoConfigSchema.shape.model.optional(),\n })\n .refine(\n (patch) => patch.enabled !== undefined || patch.review !== undefined || patch.model !== undefined,\n 'Repository config patch cannot be empty.',\n );\n\nasync function mapWithConcurrency<T, R>(\n items: T[],\n limit: number,\n mapper: (item: T) => Promise<R>,\n) {\n const results: R[] = new Array(items.length);\n let nextIndex = 0;\n\n async function worker() {\n while (nextIndex < items.length) {\n const currentIndex = nextIndex;\n nextIndex += 1;\n results[currentIndex] = await mapper(items[currentIndex]);\n }\n }\n\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));\n return results;\n}\n\nexport function createReposRouter() {\n const app = new Hono<ApiEnv>();\n\n app.get('/', async (c) => {\n const repos = await c.env.deps.repositories.repoConfigs.listRepoConfigs(c.env as any);\n return c.json({ repos });\n });\n\n app.get('/install', async (c) => {\n try {\n return c.redirect(await c.env.deps.gitProvider.getAppInstallationUrl(), 302);\n } catch (error) {\n c.env.deps.platform.logger.error('Failed to resolve GitHub App installation URL:', error);\n return jsonError(`Failed to resolve GitHub App installation URL: ${error instanceof Error ? error.message : String(error)}`, 500);\n }\n });\n\n app.post('/sync', async (c) => {\n try {\n const installations = await c.env.deps.gitProvider.listInstallations();\n const synced: string[] = [];\n const repoConfigs = c.env.deps.repositories.repoConfigs;\n\n for (const inst of installations) {\n const github = c.env.deps.gitProvider.createService(String(inst.id));\n const repos = await github.listRepositories();\n\n const results = await mapWithConcurrency(\n repos,\n 5,\n async (repo: any) => {\n const owner = repo.owner.login;\n const name = repo.name;\n const fullName = `${owner}/${name}`;\n try {\n await repoConfigs.syncRepoConfig(c.env as any, {\n installationId: String(inst.id),\n owner,\n repo: name,\n });\n return fullName;\n } catch (repoError) {\n c.env.deps.platform.logger.error(`Failed to sync repo: ${fullName}`, repoError);\n return null;\n }\n },\n );\n\n const installationSynced: string[] = [];\n for (const res of results) {\n if (res) {\n synced.push(res);\n installationSynced.push(res);\n }\n }\n \n await repoConfigs.deleteStaleRepoConfigs(c.env as any, String(inst.id), installationSynced);\n }\n\n return c.json({ ok: true, synced });\n } catch (error) {\n c.env.deps.platform.logger.error('Manual sync failed:', error);\n return jsonError(`Sync failed: ${error instanceof Error ? error.message : String(error)}`, 500);\n }\n });\n\n app.get('/:owner/:repo/config', async (c) => {\n const repo = await c.env.deps.repositories.repoConfigs.getRepoConfigRecord(c.env as any, c.req.param('owner'), c.req.param('repo'));\n if (!repo) {\n return jsonError('Repository config not found.', 404);\n }\n\n return c.json({ repo });\n });\n \n app.patch('/:owner/:repo/config', async (c) => {\n const { owner, repo } = c.req.param();\n const body = await c.req.json();\n const parsedPatch = repoConfigPatchSchema.safeParse(body);\n if (!parsedPatch.success) {\n return jsonError('Invalid repository config patch.', 400);\n }\n\n const repoConfigs = c.env.deps.repositories.repoConfigs;\n const existing = await repoConfigs.getRepoConfigRecord(c.env as any, owner, repo);\n \n if (!existing) {\n return jsonError('Repository config not found.', 404);\n }\n\n const patch = parsedPatch.data;\n const hasConfigPatch = patch.review !== undefined || patch.model !== undefined;\n\n if (!hasConfigPatch && patch.enabled !== undefined) {\n await repoConfigs.updateRepoConfigEnabled(c.env as any, {\n owner,\n repo,\n enabled: patch.enabled,\n });\n await c.env.deps.config.invalidateRepoConfigCache(owner, repo);\n return c.json({ ok: true });\n }\n\n const configPatch: Partial<z.infer<typeof repoConfigSchema>> = {};\n if (patch.review !== undefined) {\n configPatch.review = patch.review;\n }\n if (patch.model !== undefined) {\n configPatch.model = patch.model;\n }\n \n const updatedParsedJson = {\n ...existing.parsedJson,\n ...configPatch,\n };\n const parsedConfig = repoConfigSchema.safeParse(updatedParsedJson);\n\n if (!parsedConfig.success) {\n return jsonError('Invalid repository config.', 400);\n }\n \n await repoConfigs.upsertRepoConfig(c.env as any, {\n installationId: existing.installationId,\n owner,\n repo,\n parsedJson: parsedConfig.data,\n enabled: patch.enabled,\n });\n await c.env.deps.config.invalidateRepoConfigCache(owner, repo);\n \n return c.json({ ok: true });\n });\n\n return app;\n}\n","import { Hono } from 'hono';\nimport type { ApiEnv } from '../../ports';\n\nexport function createStatsRouter() {\n const app = new Hono<ApiEnv>();\n\n app.get('/', async (c) => {\n const daysParam = c.req.query('days');\n const days = daysParam ? parseInt(daysParam, 10) : 30;\n // Grouped in the caller's display zone so the trend matches timestamps shown elsewhere; getStats falls back to UTC if invalid.\n const timeZone = c.req.query('tz') ?? 'UTC';\n const stats = await c.env.deps.repositories.stats.getStats(c.env as any, days, timeZone);\n return c.json({ stats });\n });\n\n return app;\n}\n","import { Hono } from 'hono';\nimport { z } from 'zod';\nimport { jsonError } from '../../http';\nimport { llmApiFormats } from '@codraoss/schema';\nimport type { ApiEnv } from '../../ports';\n\nconst apiFormatSchema = z.enum(llmApiFormats);\nconst positiveIntegerSchema = z.number().int().positive().finite();\nconst modelIdSchema = z.string().trim().min(1);\nconst optionalUrlSchema = z.string().trim().url().nullable().optional();\nconst providerIdSchema = z.string().uuid();\n\nconst providerCreateSchema = z.strictObject({\n name: z.string().trim().min(1),\n apiFormat: apiFormatSchema,\n baseUrl: optionalUrlSchema,\n apiKey: z.string().optional(),\n enabled: z.boolean().default(true),\n});\n\n// `.extend()` carries the parent's strictness through, so no second `.strict()` is needed here.\nconst providerUpdateSchema = providerCreateSchema.extend({\n clearApiKey: z.boolean().optional(),\n});\n\nconst modelConfigUpdateSchema = z.strictObject({\n providerId: providerIdSchema,\n modelName: z.string().trim().min(1),\n});\n\nconst globalModelConfigSchema = z.strictObject({\n main: modelIdSchema.nullable().default(null),\n fallbacks: z.array(modelIdSchema).nullable().default([]),\n size_overrides: z\n .array(\n z.strictObject({\n max_lines: positiveIntegerSchema,\n model: modelIdSchema,\n fallbacks: z.array(modelIdSchema).optional(),\n }),\n )\n .nullable()\n .optional(),\n});\n\nfunction requiresExplicitBaseUrl(apiFormat: z.infer<typeof apiFormatSchema>, baseUrl: string | null | undefined) {\n return apiFormat === 'vertex' && !baseUrl;\n}\n\nfunction readModelIdParam(value: string) {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n\nexport function createModelsRouter() {\n const app = new Hono<ApiEnv>();\n\n app.get('/', async (c) => {\n const modelConfigsRepo = c.env.deps.repositories.modelConfigs;\n const [providers, configs] = await Promise.all([\n modelConfigsRepo.listLlmProviders(c.env as any),\n modelConfigsRepo.listModelConfigs(c.env as any),\n ]);\n return c.json({ providers, configs });\n });\n\n app.post('/sync', async (c) => {\n const modelConfigsRepo = c.env.deps.repositories.modelConfigs;\n const syncErrors = await c.env.deps.modelRunner.syncProviderModelCatalog();\n const [providers, configs] = await Promise.all([\n modelConfigsRepo.listLlmProviders(c.env as any),\n modelConfigsRepo.listModelConfigs(c.env as any),\n ]);\n return c.json({ providers, configs, syncErrors });\n });\n\n app.get('/global', async (c) => {\n const config = await c.env.deps.config.getGlobalConfig();\n return c.json({ config });\n });\n\n app.patch('/global', async (c) => {\n const body = await c.req.json();\n const parsed = globalModelConfigSchema.safeParse(body);\n if (!parsed.success) {\n return jsonError('Invalid global model config.', 400);\n }\n\n await c.env.deps.config.updateGlobalConfig(parsed.data);\n return c.json({ ok: true });\n });\n\n app.post('/providers', async (c) => {\n const parsed = providerCreateSchema.safeParse(await c.req.json());\n if (!parsed.success) {\n return jsonError('Invalid provider config.', 400);\n }\n\n const input = parsed.data;\n if (requiresExplicitBaseUrl(input.apiFormat, input.baseUrl)) {\n return jsonError('Vertex AI requires a base URL with your GCP project ID and region, e.g. https://us-central1-aiplatform.googleapis.com/v1/projects/YOUR_PROJECT_ID/locations/us-central1', 400);\n }\n\n try {\n const provider = await c.env.deps.modelRunner.createProviderWithSecret(input);\n return c.json({ provider }, 201);\n } catch (error) {\n const err = error as any;\n if (err.isUniqueNameError) {\n return jsonError(`Provider ${input.name} already exists. Update the existing provider instead.`, 409);\n }\n if (err.isEncryptionConfigError) {\n return jsonError(err.message || 'LLM encryption is not configured.', 400);\n }\n if (err.isKeyRequiredError) {\n return jsonError(`Provider ${input.name} needs an API key before it can be enabled.`, 400);\n }\n throw error;\n }\n });\n\n app.patch('/providers/:id', async (c) => {\n const id = c.req.param('id');\n if (!providerIdSchema.safeParse(id).success) {\n return jsonError('Invalid provider id.', 400);\n }\n\n const parsed = providerUpdateSchema.safeParse(await c.req.json());\n if (!parsed.success) {\n return jsonError('Invalid provider config.', 400);\n }\n\n const input = parsed.data;\n if (requiresExplicitBaseUrl(input.apiFormat, input.baseUrl)) {\n return jsonError('Vertex AI requires a base URL with your GCP project ID and region, e.g. https://us-central1-aiplatform.googleapis.com/v1/projects/YOUR_PROJECT_ID/locations/us-central1', 400);\n }\n\n try {\n const provider = await c.env.deps.modelRunner.updateProviderWithSecret(id, input);\n if (!provider) return jsonError('Provider not found.', 404);\n return c.json({ provider });\n } catch (error) {\n const err = error as any;\n if (err.isUniqueNameError) {\n return jsonError(`Provider ${input.name} already exists. Choose a different provider name.`, 409);\n }\n if (err.isEncryptionConfigError) {\n return jsonError(err.message || 'LLM encryption is not configured.', 400);\n }\n if (err.isKeyRequiredError) {\n return jsonError(`Provider ${input.name} needs an API key before it can be enabled.`, 400);\n }\n throw error;\n }\n });\n\n app.delete('/providers/:id', async (c) => {\n const id = c.req.param('id');\n if (!providerIdSchema.safeParse(id).success) {\n return jsonError('Invalid provider id.', 400);\n }\n\n const result = await c.env.deps.repositories.modelConfigs.deleteLlmProvider(c.env as any, id);\n if (!result.deleted) {\n return jsonError(result.reason ?? 'Provider not found.', result.reason ? 409 : 404);\n }\n return c.json({ ok: true });\n });\n\n app.post('/:id/test', async (c) => {\n const modelId = readModelIdParam(c.req.param('id'));\n const parsedModelId = modelIdSchema.safeParse(modelId);\n if (!parsedModelId.success) {\n return jsonError('Invalid model id.', 400);\n }\n\n try {\n const response = await c.env.deps.modelRunner.testConnection(parsedModelId.data);\n return c.json(response);\n } catch (error) {\n const err = error as any;\n if (err.isNotFoundError) return jsonError('Model not found.', 404);\n if (err.isDisabledError || err.isMissingKeyError) return jsonError(err.message, 400);\n \n return jsonError(\n err.message || 'Connection test failed.',\n err.status || 502,\n );\n }\n });\n\n app.post('/:id', async (c) => {\n const modelId = readModelIdParam(c.req.param('id'));\n const parsedModelId = modelIdSchema.safeParse(modelId);\n if (!parsedModelId.success) {\n return jsonError('Invalid model id.', 400);\n }\n\n const body = await c.req.json();\n const parsed = modelConfigUpdateSchema.safeParse(body);\n if (!parsed.success) {\n return jsonError('Invalid model config.', 400);\n }\n\n const saved = await c.env.deps.repositories.modelConfigs.updateModelConfig(c.env as any, {\n modelId: parsedModelId.data,\n providerId: parsed.data.providerId,\n modelName: parsed.data.modelName,\n });\n\n if (!saved) return jsonError('Provider not found.', 404);\n return c.json({ ok: true, config: saved });\n });\n\n app.delete('/:id', async (c) => {\n const modelId = readModelIdParam(c.req.param('id'));\n const parsedModelId = modelIdSchema.safeParse(modelId);\n if (!parsedModelId.success) {\n return jsonError('Invalid model id.', 400);\n }\n\n const deleted = await c.env.deps.repositories.modelConfigs.deleteModelConfig(c.env as any, parsedModelId.data);\n if (!deleted) return jsonError('Model not found.', 404);\n return c.json({ ok: true });\n });\n\n return app;\n}\n","import { Hono } from 'hono';\nimport { z } from 'zod';\nimport type { ApiEnv } from '../../ports';\nimport { jsonError } from '../../http';\nimport { reviewConcurrencyLevels, reviewMaxCommentsOptions, reviewMaxFilesRange, reviewSettingsSchema } from '@codraoss/schema';\n\nconst reviewSettingsPatchSchema = z.strictObject({\n concurrencyLevel: z.enum(reviewConcurrencyLevels).optional(),\n maxComments: z.number().int().refine(\n (value) => (reviewMaxCommentsOptions as readonly number[]).includes(value),\n 'Invalid max comments value.',\n ).optional(),\n maxFiles: z.number().int().min(reviewMaxFilesRange.min).max(reviewMaxFilesRange.max).optional(),\n}).refine(\n (settings) => Object.values(settings).some((value) => value !== undefined),\n 'At least one setting must be provided.',\n);\n\nexport function createSettingsRouter() {\n const app = new Hono<ApiEnv>();\n\n app.get('/', async (c) => {\n const settings = await c.env.deps.repositories.appSettings.getReviewSettings(c.env as any);\n return c.json({ settings });\n });\n\n app.patch('/', async (c) => {\n const body = await c.req.json().catch(() => null);\n const parsed = reviewSettingsPatchSchema.safeParse(body);\n if (!parsed.success) {\n return jsonError('Invalid review settings.', 400);\n }\n\n const current = await c.env.deps.repositories.appSettings.getReviewSettings(c.env as any);\n const next = reviewSettingsSchema.parse({ ...current, ...parsed.data });\n await c.env.deps.repositories.appSettings.updateReviewSettings(c.env as any, next);\n return c.json({ ok: true, settings: next });\n });\n\n return app;\n}\n"],"mappings":"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","names":["Hono","createMiddleware","Hono","Hono","Hono","Hono","Hono","Hono","Hono","z","z","Hono","Hono","Hono","z","z","Hono","Hono","z","z","Hono","Hono"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codraoss/api",
|
|
3
|
+
"version": "0.9.4",
|
|
4
|
+
"description": "Codra's HTTP surface as a mountable Hono router, wired through ports.",
|
|
5
|
+
"author": "Devarshi Shimpi",
|
|
6
|
+
"license": "AGPL-3.0-only",
|
|
7
|
+
"homepage": "https://codra.run",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/devarshishimpi/codra.git",
|
|
11
|
+
"directory": "packages/api"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/devarshishimpi/codra/issues"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"LICENSE",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public",
|
|
31
|
+
"main": "./dist/index.js",
|
|
32
|
+
"module": "./dist/index.js",
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup",
|
|
43
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
44
|
+
"prepack": "node ../../scripts/swap-publish-exports.mjs promote",
|
|
45
|
+
"postpack": "node ../../scripts/swap-publish-exports.mjs restore"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"hono": "^4.12.25",
|
|
49
|
+
"zod": "^4.3.6",
|
|
50
|
+
"@codraoss/schema": "^0.9.4",
|
|
51
|
+
"@codraoss/core": "^0.9.4",
|
|
52
|
+
"@codraoss/db": "^0.9.4",
|
|
53
|
+
"@codraoss/provider-github": "^0.9.4",
|
|
54
|
+
"@codraoss/models": "^0.9.4"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/node": "^22.0.0",
|
|
58
|
+
"tsup": "^8.0.0"
|
|
59
|
+
},
|
|
60
|
+
"main": "./dist/index.js",
|
|
61
|
+
"module": "./dist/index.js",
|
|
62
|
+
"types": "./dist/index.d.ts"
|
|
63
|
+
}
|