| import { Context, Hono } from 'hono' |
| import * as dotenv from 'dotenv' |
| import { cors } from "hono/cors"; |
| import { compress } from "hono/compress"; |
| import { prettyJSON } from "hono/pretty-json"; |
| import { trimTrailingSlash } from "hono/trailing-slash"; |
| import { serve } from '@hono/node-server' |
| import { createStorage } from "unstorage"; |
| import cloudflareKVHTTPDriver from "unstorage/drivers/cloudflare-kv-http"; |
| import { serveStatic } from '@hono/node-server/serve-static' |
|
|
| import path from 'path' |
| import { fileURLToPath } from 'url' |
| import { dirname } from 'path' |
|
|
| |
| import { onRequest as handleAccount } from './functions/api/account.js' |
| import { onRequest as handleLogin } from './functions/api/login.js' |
| import { onRequest as handleSetting } from './functions/api/setting.js' |
| import { onRequest as handleGithub } from './functions/api/github/[[path]].js' |
| import { onRequest as handleHF } from './functions/api/hf/[[path]].js' |
|
|
| dotenv.config({ path: ['.env', '.env.local'], override: true }); |
| const isDev = process.env.NODE_ENV === 'development' |
|
|
| const app = new Hono<{ Bindings: Env }>() |
| app.use(compress()); |
| app.use(prettyJSON()); |
| app.use(trimTrailingSlash()); |
| app.use('*', cors({ |
| origin: '*', |
| allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], |
| allowHeaders: ['Content-Type', 'Authorization'], |
| exposeHeaders: ['Content-Length'], |
| credentials: true, |
| })); |
|
|
|
|
| const storage = createStorage({ |
| driver: cloudflareKVHTTPDriver({ |
| accountId: process.env.CLOUDFLARE_ACCOUNT_ID || "", |
| namespaceId: process.env.CLOUDFLARE_NAMESPACE_ID || "", |
| apiToken: process.env.CLOUDFLARE_API_TOKEN || "", |
| }), |
| }); |
|
|
| var kv: KVNamespace = { |
| get: async (key: string) => { |
| const value = await storage.getItemRaw(key); |
| return value as string; |
| }, |
| put: async (key: string, value: string) => { |
| await storage.setItem(key, value); |
| }, |
| delete: async (key: string) => { |
| await storage.removeItem(key); |
| } |
| }; |
|
|
| app.use('*', async (c, next) => { |
| c.env.KV = kv; |
| await next() |
| }) |
|
|
|
|
| const scriptPath = fileURLToPath(import.meta.url) |
| const scriptDir = dirname(scriptPath) |
| const rootDir = isDev ? dirname(scriptPath) : dirname(scriptDir) |
| const currentDir = process.cwd(); |
| let staticPath = path.relative(currentDir, rootDir); |
| if (!isDev) { |
| staticPath = path.relative(currentDir, path.join(rootDir, "dist")) |
| } |
| console.log('Script dir:', scriptDir) |
| console.log('Root dir:', rootDir) |
| console.log('Current dir:', currentDir); |
| console.log('Relative path for static files:', staticPath || '.'); |
|
|
|
|
|
|
| const createContext = (c: Context) => { |
| const eventContext: RouteContext = { |
| request: c.req.raw, |
| functionPath: c.req.path, |
| waitUntil: (promise: Promise<any>) => { |
| if (c.executionCtx?.waitUntil) { |
| c.executionCtx.waitUntil(promise); |
| } |
| }, |
| passThroughOnException: () => { |
| if (c.executionCtx?.passThroughOnException) { |
| c.executionCtx.passThroughOnException(); |
| } |
| }, |
| next: async (input?: Request | string, init?: RequestInit) => { |
| if (typeof input === 'string') { |
| return fetch(input, init); |
| } else if (input instanceof Request) { |
| return fetch(input); |
| } |
| return new Response('Not Found', { status: 404 }); |
| }, |
| env: { |
| ...c.env, |
| ASSETS: { |
| fetch: fetch.bind(globalThis) |
| } |
| }, |
| params: c.req.param(), |
| |
| data: c.get('data') || {} |
| }; |
| return eventContext; |
| } |
|
|
| app.all('/api/*', async (c) => { |
| try { |
| const context = createContext(c); |
| const path = c.req.path; |
| |
| let response: Response; |
| switch (path) { |
| case '/api/account': |
| response = await handleAccount(context); |
| break; |
| case '/api/login': |
| response = await handleLogin(context); |
| break; |
| case '/api/setting': |
| response = await handleSetting(context); |
| break; |
| default: |
| if (path.startsWith('/api/github/')) { |
| response = await handleGithub(context); |
| break; |
| } else if (path.startsWith('/api/hf/')) { |
| response = await handleHF(context); |
| break; |
| } |
| return c.json({ error: 'Route not found' }, 404); |
| } |
| return response; |
| } catch (error) { |
| return c.json({ error: (error as Error).message }, 500); |
| } |
| }) |
|
|
|
|
| |
| app.get('/*', serveStatic({ |
| root: staticPath, |
| rewriteRequestPath: (path) => { |
| return path === '/' ? '/index.html' : path; |
| }, |
| onFound: async (path, c) => { |
| console.log('Found:', path) |
| }, |
| onNotFound: async (path, c) => { |
| console.log('Not Found:', path) |
| } |
| })) |
|
|
|
|
| |
| const port = parseInt(process.env.PORT || '8788') |
| serve({ |
| fetch: (request: Request, env) => app.fetch(request, { ...env, ...process.env }), |
| port |
| }, () => { |
| console.log(`Server running at http://localhost:${port}`) |
| }) |
|
|
| export default app |