{showRetry?.() && onRetry && (
diff --git a/src/components/SystemRoleSettings.tsx b/src/components/SystemRoleSettings.tsx
index 1513e88b0..5bb11aa08 100644
--- a/src/components/SystemRoleSettings.tsx
+++ b/src/components/SystemRoleSettings.tsx
@@ -1,6 +1,6 @@
import { Show } from 'solid-js'
-import type { Accessor, Setter } from 'solid-js'
import IconEnv from './icons/Env'
+import type { Accessor, Setter } from 'solid-js'
interface Props {
canEdit: Accessor
diff --git a/src/components/Themetoggle.astro b/src/components/Themetoggle.astro
index 3955a71e6..e24bb5857 100644
--- a/src/components/Themetoggle.astro
+++ b/src/components/Themetoggle.astro
@@ -32,22 +32,22 @@
\ No newline at end of file
+const handleToggleClick = () => {
+ const element = document.documentElement
+ element.classList.toggle('dark')
+ const isDark = element.classList.contains('dark')
+ localStorage.setItem('theme', isDark ? 'dark' : 'light')
+}
+document
+ .getElementById('themeToggle')
+ .addEventListener('click', handleToggleClick)
+
diff --git a/src/components/icons/Clear.tsx b/src/components/icons/Clear.tsx
index 4ba65b9ad..9741b6b05 100644
--- a/src/components/icons/Clear.tsx
+++ b/src/components/icons/Clear.tsx
@@ -1,5 +1,5 @@
export default () => {
return (
-
+
)
-}
\ No newline at end of file
+}
diff --git a/src/components/icons/Env.tsx b/src/components/icons/Env.tsx
index cbdbfc102..8dc4dd2ba 100644
--- a/src/components/icons/Env.tsx
+++ b/src/components/icons/Env.tsx
@@ -1,5 +1,5 @@
export default () => {
return (
-
+
)
-}
\ No newline at end of file
+}
diff --git a/src/components/icons/Refresh.tsx b/src/components/icons/Refresh.tsx
index e41be4aa3..c7cca6187 100644
--- a/src/components/icons/Refresh.tsx
+++ b/src/components/icons/Refresh.tsx
@@ -1,5 +1,5 @@
export default () => {
return (
-
+
)
-}
\ No newline at end of file
+}
diff --git a/src/env.d.ts b/src/env.d.ts
index f964fe0cf..88e0666bc 100644
--- a/src/env.d.ts
+++ b/src/env.d.ts
@@ -1 +1,16 @@
///
+
+interface ImportMetaEnv {
+ readonly OPENAI_API_KEY: string
+ readonly HTTPS_PROXY: string
+ readonly OPENAI_API_BASE_URL: string
+ readonly HEAD_SCRIPTS: string
+ readonly SECRET_KEY: string
+ readonly SITE_PASSWORD: string
+ readonly OPENAI_API_MODEL: string
+
+}
+
+interface ImportMeta {
+ readonly env: ImportMetaEnv
+}
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
index 3555e00cb..b77394598 100644
--- a/src/layouts/Layout.astro
+++ b/src/layouts/Layout.astro
@@ -1,7 +1,6 @@
---
-
export interface Props {
- title: string;
+ title: string;
}
const { title } = Astro.props;
@@ -9,74 +8,87 @@ const { title } = Astro.props;
-
-
-
-
-
- {title}
- { import.meta.env.HEAD_SCRIPTS ? : null }
-
-
-
-
+
+
+
+
+
+ {title}
+ {
+ import.meta.env.HEAD_SCRIPTS
+ ? (
+
+ )
+ : null
+ }
+
+
+
+
\ No newline at end of file
+
diff --git a/src/pages/api/auth.ts b/src/pages/api/auth.ts
index 57d7dd9ef..b0029e35e 100644
--- a/src/pages/api/auth.ts
+++ b/src/pages/api/auth.ts
@@ -2,7 +2,7 @@ import type { APIRoute } from 'astro'
const realPassword = import.meta.env.SITE_PASSWORD
-export const post: APIRoute = async (context) => {
+export const post: APIRoute = async(context) => {
const body = await context.request.json()
const { pass } = body
diff --git a/src/pages/api/generate.ts b/src/pages/api/generate.ts
index 9d21ebab5..893fecafa 100644
--- a/src/pages/api/generate.ts
+++ b/src/pages/api/generate.ts
@@ -1,54 +1,54 @@
-import type { APIRoute } from 'astro'
-import { generatePayload, parseOpenAIStream } from '@/utils/openAI'
-import { verifySignature } from '@/utils/auth'
// #vercel-disable-blocks
-import { fetch, ProxyAgent } from 'undici'
+import { ProxyAgent, fetch } from 'undici'
// #vercel-end
+import { generatePayload, parseOpenAIStream } from '@/utils/openAI'
+import { verifySignature } from '@/utils/auth'
+import type { APIRoute } from 'astro'
const apiKey = import.meta.env.OPENAI_API_KEY
const httpsProxy = import.meta.env.HTTPS_PROXY
-const baseUrl = (import.meta.env.OPENAI_API_BASE_URL || 'https://api.openai.com').trim().replace(/\/$/,'')
+const baseUrl = (import.meta.env.OPENAI_API_BASE_URL || 'https://api.openai.com').trim().replace(/\/$/, '')
const sitePassword = import.meta.env.SITE_PASSWORD
-export const post: APIRoute = async (context) => {
+export const post: APIRoute = async(context) => {
const body = await context.request.json()
const { sign, time, messages, pass } = body
if (!messages) {
return new Response(JSON.stringify({
error: {
message: 'No input text.',
- }
+ },
}), { status: 400 })
}
if (sitePassword && sitePassword !== pass) {
return new Response(JSON.stringify({
error: {
message: 'Invalid password.',
- }
+ },
}), { status: 401 })
}
- if (import.meta.env.PROD && !await verifySignature({ t: time, m: messages?.[messages.length - 1]?.content || '', }, sign)) {
+ if (import.meta.env.PROD && !await verifySignature({ t: time, m: messages?.[messages.length - 1]?.content || '' }, sign)) {
return new Response(JSON.stringify({
error: {
message: 'Invalid signature.',
- }
+ },
}), { status: 401 })
}
const initOptions = generatePayload(apiKey, messages)
// #vercel-disable-blocks
- if (httpsProxy) {
- initOptions['dispatcher'] = new ProxyAgent(httpsProxy)
- }
+ if (httpsProxy)
+ initOptions.dispatcher = new ProxyAgent(httpsProxy)
// #vercel-end
- // @ts-ignore
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-expect-error
const response = await fetch(`${baseUrl}/v1/chat/completions`, initOptions).catch((err: Error) => {
console.error(err)
return new Response(JSON.stringify({
error: {
code: err.name,
message: err.message,
- }
+ },
}), { status: 500 })
}) as Response
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 2113e0270..76f6a7ccd 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -31,10 +31,8 @@ async function checkCurrentAuth() {
}),
})
const responseJson = await response.json()
- if (responseJson.code !== 0) {
+ if (responseJson.code !== 0)
window.location.href = '/password'
- }
}
checkCurrentAuth()
-
diff --git a/src/pages/password.astro b/src/pages/password.astro
index e2e1b9d22..a12047977 100644
--- a/src/pages/password.astro
+++ b/src/pages/password.astro
@@ -19,10 +19,9 @@ const inputContainer = document.getElementById('input_container') as HTMLDivElem
const input = document.getElementById('password_input') as HTMLInputElement
const submitButton = document.getElementById('submit') as HTMLDivElement
-input.onkeydown = async (event) => {
- if (event.key === 'Enter') {
+input.onkeydown = async(event) => {
+ if (event.key === 'Enter')
handleSubmit()
- }
}
submitButton.onclick = handleSubmit
diff --git a/src/utils/auth.ts b/src/utils/auth.ts
index 337e065e5..7c9bdb95e 100644
--- a/src/utils/auth.ts
+++ b/src/utils/auth.ts
@@ -9,20 +9,21 @@ async function digestMessage(message: string) {
const msgUint8 = new TextEncoder().encode(message)
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8)
const hashArray = Array.from(new Uint8Array(hashBuffer))
- return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')
+ return hashArray.map(b => b.toString(16).padStart(2, '0')).join('')
} else {
return sha256(message).toString()
}
}
-export const generateSignature = async (payload: AuthPayload) => {
+export const generateSignature = async(payload: AuthPayload) => {
const { t: timestamp, m: lastMessage } = payload
const secretKey = import.meta.env.PUBLIC_SECRET_KEY as string
const signText = `${timestamp}:${lastMessage}:${secretKey}`
+ // eslint-disable-next-line no-return-await
return await digestMessage(signText)
}
-export const verifySignature = async (payload: AuthPayload, sign: string) => {
+export const verifySignature = async(payload: AuthPayload, sign: string) => {
// if (Math.abs(payload.t - Date.now()) > 1000 * 60 * 5) {
// return false
// }
diff --git a/src/utils/openAI.ts b/src/utils/openAI.ts
index e035a6578..7507f516a 100644
--- a/src/utils/openAI.ts
+++ b/src/utils/openAI.ts
@@ -1,12 +1,13 @@
-import { createParser, ParsedEvent, ReconnectInterval } from 'eventsource-parser'
+import { createParser } from 'eventsource-parser'
+import type { ParsedEvent, ReconnectInterval } from 'eventsource-parser'
import type { ChatMessage } from '@/types'
const model = import.meta.env.OPENAI_API_MODEL || 'gpt-3.5-turbo'
-export const generatePayload = (apiKey: string, messages: ChatMessage[]): RequestInit => ({
+export const generatePayload = (apiKey: string, messages: ChatMessage[]): RequestInit & { dispatcher?: any } => ({
headers: {
'Content-Type': 'application/json',
- Authorization: `Bearer ${apiKey}`,
+ 'Authorization': `Bearer ${apiKey}`,
},
method: 'POST',
body: JSON.stringify({
@@ -57,9 +58,8 @@ export const parseOpenAIStream = (rawResponse: Response) => {
}
const parser = createParser(streamParser)
- for await (const chunk of rawResponse.body as any) {
+ for await (const chunk of rawResponse.body as any)
parser.feed(decoder.decode(chunk))
- }
},
})
diff --git a/unocss.config.ts b/unocss.config.ts
index 669b7144d..7b4988f48 100644
--- a/unocss.config.ts
+++ b/unocss.config.ts
@@ -18,10 +18,10 @@ export default defineConfig({
}),
presetTypography({
cssExtend: {
- "ul,ol": {
- "list-style-position":"inside"
- }
- }
+ 'ul,ol': {
+ 'list-style-position': 'inside',
+ },
+ },
}),
],
transformers: [transformerVariantGroup(), transformerDirectives()],
@@ -50,6 +50,5 @@ export default defineConfig({
'gen-text-wrapper': 'my-4 fc gap-2 transition-opacity',
'gen-textarea': 'w-full px-3 py-3 min-h-12 max-h-36 rounded-sm bg-(slate op-15) resize-none base-focus placeholder:op-50 dark:(placeholder:op-30) scroll-pa-8px',
'sys-edit-btn': 'inline-fcc gap-1 text-sm bg-slate/20 px-2 py-1 rounded-md transition-colors cursor-pointer hover:bg-slate/50',
- }]
+ }],
})
-