msmail / index.ts
github-actions[bot]
Update from GitHub Actions
7fc5208
raw
history blame
5.91 kB
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 handleMailAuth } from './functions/api/mail/auth.js'
import { onRequest as handleMailCallback } from './functions/api/mail/callback.js'
import { onRequest as handleMailAll } from './functions/api/mail/all.js'
import { onRequest as handleMailNew } from './functions/api/mail/new.js'
import { onRequest as handleMailSend } from './functions/api/mail/send.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(),
// 可以从 c.get() 获取数据,或者传入空对象
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;
case '/api/mail/auth':
response = await handleMailAuth(context);
break;
case '/api/mail/callback':
response = await handleMailCallback(context);
break;
case '/api/mail/all':
response = await handleMailAll(context);
break;
case '/api/mail/new':
response = await handleMailNew(context);
break;
case '/api/mail/send':
response = await handleMailSend(context);
break;
default:
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