feat: 更新项目名称为 One API on Workers
This commit is contained in:
1 parent
6071f18f7a
commit
1ef5502083
11 files changed
+122
-134
No files matched your search
@@ -1,4 +1,4 @@
|
||||
# AWSL One API
|
||||
# One API on Workers
|
||||
|
||||
一个基于 Cloudflare Workers 的 OpenAI API 代理服务,支持多渠道管理、Token 管理和使用量统计。
|
||||
|
||||
@@ -22,7 +22,7 @@ flowchart LR
|
||||
end
|
||||
|
||||
subgraph CF["Cloudflare Workers"]
|
||||
B[AWSL One API]
|
||||
B[One API on Workers]
|
||||
D[(Cloudflare D1<br/>Database)]
|
||||
end
|
||||
|
||||
@@ -41,7 +41,7 @@ flowchart LR
|
||||
<summary><h2>📁 项目结构</h2></summary>
|
||||
|
||||
```text
|
||||
awsl-one-api/
|
||||
one-api-workers/
|
||||
├── src/ # 源代码目录
|
||||
│ ├── admin/ # 管理接口
|
||||
│ │ ├── channel_api.ts # 渠道管理 API
|
||||
@@ -93,7 +93,7 @@ bun install
|
||||
```jsonc
|
||||
{
|
||||
"$schema": "node_modules/wrangler/config-schema.json",
|
||||
"name": "awsl-one-api",
|
||||
"name": "one-api-workers",
|
||||
"main": "src/index.ts",
|
||||
"compatibility_date": "2025-04-28",
|
||||
"workers_dev": false,
|
||||
@@ -120,7 +120,7 @@ bun install
|
||||
```jsonc
|
||||
{
|
||||
"$schema": "node_modules/wrangler/config-schema.json",
|
||||
"name": "awsl-one-api",
|
||||
"name": "one-api-workers",
|
||||
"main": "src/index.ts",
|
||||
"compatibility_date": "2025-04-28",
|
||||
"workers_dev": false,
|
||||
@@ -134,7 +134,7 @@ bun install
|
||||
3. 创建 Cloudflare D1 数据库:
|
||||
|
||||
```bash
|
||||
wrangler d1 create awsl-one-api
|
||||
wrangler d1 create one-api-workers
|
||||
```
|
||||
|
||||
4. 在 Cloudflare Dashboard 中手动绑定生产域名:
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
# AWSL One API Frontend
|
||||
# One API on Workers Frontend
|
||||
|
||||
Modern React + Vite + TypeScript frontend for AWSL One API management platform.
|
||||
Modern React + Vite + TypeScript frontend for One API on Workers management platform.
|
||||
|
||||
## Features
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>☁️</text></svg>" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Awsl One API - 管理控制台</title>
|
||||
<title>One API on Workers - 管理控制台</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -77,7 +77,7 @@ export function AppLayout({ children }: AppLayoutProps) {
|
||||
<div className="w-7 h-7 rounded-lg bg-gradient-to-br from-primary to-primary/70 flex items-center justify-center">
|
||||
<Zap className="h-3.5 w-3.5 text-white" />
|
||||
</div>
|
||||
<span className="font-semibold text-sm tracking-tight">Awsl One API</span>
|
||||
<span className="font-semibold text-sm tracking-tight">One API on Workers</span>
|
||||
</div>
|
||||
<div className="h-9 w-9" />
|
||||
</header>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
Link as LinkIcon,
|
||||
Key,
|
||||
@@ -13,30 +13,30 @@ import {
|
||||
PanelLeftClose,
|
||||
PanelLeftOpen,
|
||||
Zap,
|
||||
} from 'lucide-react'
|
||||
import { useAuthStore } from '@/store/auth'
|
||||
import { useState } from 'react'
|
||||
} from "lucide-react";
|
||||
import { useAuthStore } from "@/store/auth";
|
||||
import { useState } from "react";
|
||||
|
||||
interface NavItem {
|
||||
title: string
|
||||
href: string
|
||||
icon: React.ComponentType<{ className?: string }>
|
||||
title: string;
|
||||
href: string;
|
||||
icon: React.ComponentType<{ className?: string }>;
|
||||
}
|
||||
|
||||
const navItems: NavItem[] = [
|
||||
{ title: '渠道管理', href: '/channels', icon: LinkIcon },
|
||||
{ title: '令牌管理', href: '/tokens', icon: Key },
|
||||
{ title: '定价管理', href: '/pricing', icon: DollarSign },
|
||||
{ title: 'API 测试', href: '/api-test', icon: TestTube2 },
|
||||
]
|
||||
{ title: "渠道管理", href: "/channels", icon: LinkIcon },
|
||||
{ title: "令牌管理", href: "/tokens", icon: Key },
|
||||
{ title: "定价管理", href: "/pricing", icon: DollarSign },
|
||||
{ title: "API 测试", href: "/api-test", icon: TestTube2 },
|
||||
];
|
||||
|
||||
interface SidebarProps {
|
||||
className?: string
|
||||
onNavigate?: () => void
|
||||
onClose?: () => void
|
||||
collapsed?: boolean
|
||||
onToggleCollapse?: () => void
|
||||
showCollapseToggle?: boolean
|
||||
className?: string;
|
||||
onNavigate?: () => void;
|
||||
onClose?: () => void;
|
||||
collapsed?: boolean;
|
||||
onToggleCollapse?: () => void;
|
||||
showCollapseToggle?: boolean;
|
||||
}
|
||||
|
||||
export function Sidebar({
|
||||
@@ -47,89 +47,84 @@ export function Sidebar({
|
||||
onToggleCollapse,
|
||||
showCollapseToggle = false,
|
||||
}: SidebarProps) {
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const { logout } = useAuthStore()
|
||||
const [theme, setTheme] = useState<'light' | 'dark'>(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const savedTheme = localStorage.getItem('theme')
|
||||
const isDark = savedTheme === 'dark' || (!savedTheme && document.documentElement.classList.contains('dark'))
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const { logout } = useAuthStore();
|
||||
const [theme, setTheme] = useState<"light" | "dark">(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
const savedTheme = localStorage.getItem("theme");
|
||||
const isDark = savedTheme === "dark" || (!savedTheme && document.documentElement.classList.contains("dark"));
|
||||
if (isDark) {
|
||||
document.documentElement.classList.add('dark')
|
||||
document.documentElement.classList.add("dark");
|
||||
}
|
||||
return isDark ? 'dark' : 'light'
|
||||
return isDark ? "dark" : "light";
|
||||
}
|
||||
return 'light'
|
||||
})
|
||||
return "light";
|
||||
});
|
||||
|
||||
const toggleTheme = () => {
|
||||
const newTheme = theme === 'light' ? 'dark' : 'light'
|
||||
setTheme(newTheme)
|
||||
localStorage.setItem('theme', newTheme)
|
||||
if (newTheme === 'dark') {
|
||||
document.documentElement.classList.add('dark')
|
||||
const newTheme = theme === "light" ? "dark" : "light";
|
||||
setTheme(newTheme);
|
||||
localStorage.setItem("theme", newTheme);
|
||||
if (newTheme === "dark") {
|
||||
document.documentElement.classList.add("dark");
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark')
|
||||
document.documentElement.classList.remove("dark");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleLogout = () => {
|
||||
logout()
|
||||
navigate('/', { replace: true })
|
||||
onNavigate?.()
|
||||
}
|
||||
logout();
|
||||
navigate("/", { replace: true });
|
||||
onNavigate?.();
|
||||
};
|
||||
|
||||
const NavLink = ({ item }: { item: NavItem }) => {
|
||||
const isActive = location.pathname === item.href
|
||||
const isActive = location.pathname === item.href;
|
||||
return (
|
||||
<Link
|
||||
to={item.href}
|
||||
onClick={() => onNavigate?.()}
|
||||
title={collapsed ? item.title : undefined}
|
||||
className={cn(
|
||||
'group relative flex items-center gap-3 px-3 py-2 rounded-lg text-[13px] font-medium transition-all duration-150',
|
||||
collapsed && 'justify-center px-0 w-10 h-10 mx-auto',
|
||||
"group relative flex items-center gap-3 px-3 py-2 rounded-lg text-[13px] font-medium transition-all duration-150",
|
||||
collapsed && "justify-center px-0 w-10 h-10 mx-auto",
|
||||
isActive
|
||||
? 'bg-primary text-primary-foreground shadow-sm shadow-primary/20'
|
||||
: 'text-muted-foreground hover:text-foreground hover:bg-muted/80'
|
||||
? "bg-primary text-primary-foreground shadow-sm shadow-primary/20"
|
||||
: "text-muted-foreground hover:text-foreground hover:bg-muted/80",
|
||||
)}
|
||||
>
|
||||
<item.icon className={cn(
|
||||
"h-[17px] w-[17px] flex-shrink-0",
|
||||
!isActive && "group-hover:scale-105 transition-transform duration-150"
|
||||
)} />
|
||||
<item.icon
|
||||
className={cn(
|
||||
"h-[17px] w-[17px] flex-shrink-0",
|
||||
!isActive && "group-hover:scale-105 transition-transform duration-150",
|
||||
)}
|
||||
/>
|
||||
{!collapsed && <span>{item.title}</span>}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={cn(
|
||||
"bg-card border-r flex flex-col h-full transition-all duration-300 ease-out",
|
||||
collapsed ? "w-[68px]" : "w-60",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{/* Header */}
|
||||
<div className={cn(
|
||||
"h-14 flex items-center border-b px-4",
|
||||
collapsed ? "justify-center px-0" : "justify-between"
|
||||
)}>
|
||||
<div
|
||||
className={cn("h-14 flex items-center border-b px-2", collapsed ? "justify-center px-0" : "justify-between")}
|
||||
>
|
||||
{collapsed ? (
|
||||
<div className="w-9 h-9 rounded-lg bg-gradient-to-br from-primary to-primary/70 flex items-center justify-center">
|
||||
<Zap className="h-4 w-4 text-white" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="flex items-center gap-2.5">
|
||||
<div className="w-9 h-9 rounded-lg bg-gradient-to-br from-primary to-primary/70 flex items-center justify-center shadow-md shadow-primary/15">
|
||||
<Zap className="h-4 w-4 text-white" />
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-semibold text-[14px] tracking-tight leading-tight">Awsl One API</span>
|
||||
<span className="text-[10px] text-muted-foreground leading-tight">AI Gateway</span>
|
||||
</div>
|
||||
<div className="w-full flex items-center justify-center gap-2.5">
|
||||
<span className="font-semibold text-[14px] tracking-tight leading-tight">One API on Workers</span>
|
||||
</div>
|
||||
{onClose && (
|
||||
<button
|
||||
@@ -144,29 +139,6 @@ export function Sidebar({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Collapse Toggle */}
|
||||
{showCollapseToggle && (
|
||||
<div className={cn("px-3 py-1.5 hidden lg:flex", collapsed && "px-0 justify-center")}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onToggleCollapse}
|
||||
className={cn(
|
||||
"flex items-center gap-2 px-2.5 py-1.5 rounded-md text-[11px] font-medium text-muted-foreground/70 hover:text-muted-foreground hover:bg-muted/50 transition-colors",
|
||||
collapsed ? "w-10 h-8 p-0 justify-center" : "w-full"
|
||||
)}
|
||||
>
|
||||
{collapsed ? (
|
||||
<PanelLeftOpen className="h-3.5 w-3.5" />
|
||||
) : (
|
||||
<>
|
||||
<PanelLeftClose className="h-3.5 w-3.5" />
|
||||
<span>收起</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Navigation */}
|
||||
<nav className="flex-1 px-2.5 py-3 overflow-y-auto scrollbar-thin">
|
||||
<div className="space-y-1">
|
||||
@@ -179,31 +151,24 @@ export function Sidebar({
|
||||
{/* Footer */}
|
||||
<div className={cn("p-2.5 border-t", collapsed && "p-2")}>
|
||||
{/* Action Buttons */}
|
||||
<div className={cn(
|
||||
"flex gap-1",
|
||||
collapsed ? "flex-col items-center" : "mb-2"
|
||||
)}>
|
||||
<div className={cn("flex gap-1 mb-2", collapsed ? "flex-col items-center" : "")}>
|
||||
<button
|
||||
type="button"
|
||||
title={collapsed ? (theme === 'dark' ? '浅色模式' : '深色模式') : undefined}
|
||||
title={collapsed ? (theme === "dark" ? "浅色模式" : "深色模式") : undefined}
|
||||
className={cn(
|
||||
"flex items-center justify-center rounded-md transition-colors duration-150",
|
||||
collapsed
|
||||
? "w-10 h-9 hover:bg-muted text-muted-foreground hover:text-foreground"
|
||||
: "flex-1 h-8 gap-1.5 px-2.5 hover:bg-muted/70 text-muted-foreground hover:text-foreground text-[11px] font-medium"
|
||||
: "flex-1 h-8 gap-1.5 px-2.5 hover:bg-muted/70 text-muted-foreground hover:text-foreground text-[11px] font-medium",
|
||||
)}
|
||||
onClick={toggleTheme}
|
||||
>
|
||||
{theme === 'dark' ? (
|
||||
<Sun className="h-3.5 w-3.5" />
|
||||
) : (
|
||||
<Moon className="h-3.5 w-3.5" />
|
||||
)}
|
||||
{!collapsed && <span>{theme === 'dark' ? '浅色' : '深色'}</span>}
|
||||
{theme === "dark" ? <Sun className="h-3.5 w-3.5" /> : <Moon className="h-3.5 w-3.5" />}
|
||||
{!collapsed && <span>{theme === "dark" ? "浅色" : "深色"}</span>}
|
||||
</button>
|
||||
|
||||
<a
|
||||
href="https://github.com/Tokinx/awsl-one-api"
|
||||
href="https://github.com/Tokinx/one-api-workers"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title={collapsed ? "GitHub" : undefined}
|
||||
@@ -211,22 +176,45 @@ export function Sidebar({
|
||||
"flex items-center justify-center rounded-md transition-colors duration-150",
|
||||
collapsed
|
||||
? "w-10 h-9 hover:bg-muted text-muted-foreground hover:text-foreground"
|
||||
: "flex-1 h-8 gap-1.5 px-2.5 hover:bg-muted/70 text-muted-foreground hover:text-foreground text-[11px] font-medium"
|
||||
: "flex-1 h-8 gap-1.5 px-2.5 hover:bg-muted/70 text-muted-foreground hover:text-foreground text-[11px] font-medium",
|
||||
)}
|
||||
>
|
||||
<Github className="h-3.5 w-3.5" />
|
||||
{!collapsed && <span>GitHub</span>}
|
||||
</a>
|
||||
|
||||
{/* Collapse Toggle */}
|
||||
{showCollapseToggle && (
|
||||
<div className={cn("hidden lg:flex", collapsed && "px-0 justify-center")}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onToggleCollapse}
|
||||
className={cn(
|
||||
"flex items-center justify-center rounded-md transition-colors duration-150",
|
||||
collapsed ? "w-10 h-9 hover:bg-muted text-muted-foreground hover:text-foreground" : "flex-1 h-8 gap-1.5 px-2.5 hover:bg-muted/70 text-muted-foreground hover:text-foreground text-[11px] font-medium",
|
||||
)}
|
||||
>
|
||||
{collapsed ? (
|
||||
<PanelLeftOpen className="h-3.5 w-3.5" />
|
||||
) : (
|
||||
<>
|
||||
<PanelLeftClose className="h-3.5 w-3.5" />
|
||||
<span>收起</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Logout Button */}
|
||||
<button
|
||||
type="button"
|
||||
title={collapsed ? '退出登录' : undefined}
|
||||
title={collapsed ? "退出登录" : undefined}
|
||||
className={cn(
|
||||
'flex items-center justify-center gap-2 w-full rounded-lg text-[13px] font-medium transition-all duration-150',
|
||||
collapsed ? 'h-9' : 'h-9 px-3',
|
||||
'bg-destructive/8 text-destructive hover:bg-destructive/15'
|
||||
"flex items-center justify-center gap-2 w-full rounded-lg text-[13px] font-medium transition-all duration-150",
|
||||
collapsed ? "h-9" : "h-9 px-3",
|
||||
"bg-destructive/8 text-destructive hover:bg-destructive/15",
|
||||
)}
|
||||
onClick={handleLogout}
|
||||
>
|
||||
@@ -235,5 +223,5 @@ export function Sidebar({
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -62,7 +62,7 @@ export function Dashboard() {
|
||||
</div>
|
||||
<h1 className="text-4xl md:text-5xl lg:text-[3.5rem] font-bold tracking-tight leading-[1.1] mb-5">
|
||||
<span className="bg-gradient-to-r from-foreground via-foreground to-foreground/70 bg-clip-text text-transparent">
|
||||
Awsl One API
|
||||
One API on Workers
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-lg md:text-xl text-muted-foreground leading-relaxed mb-8 max-w-2xl">
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "awsl-ai-proxy",
|
||||
"name": "one-api-workers",
|
||||
"workspaces": [
|
||||
"frontend"
|
||||
],
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ const app = new Hono<HonoCustomType>()
|
||||
const openapi = fromHono(app, {
|
||||
schema: {
|
||||
info: {
|
||||
title: 'Awsl One API',
|
||||
title: 'One API on Workers',
|
||||
version: '1.0.0',
|
||||
}
|
||||
},
|
||||
|
||||
+4
-4
@@ -174,10 +174,10 @@ assert_http "azure responses stream → 200 + SSE" "200" "event:" "$R"
|
||||
echo ""
|
||||
echo "--- Quota check ---"
|
||||
|
||||
npx wrangler d1 execute awsl-one-api --local --command "UPDATE api_token SET usage = 99999999 WHERE key = 'sk-mock-all'" > /dev/null 2>&1
|
||||
npx wrangler d1 execute one-api-workers --local --command "UPDATE api_token SET usage = 99999999 WHERE key = 'sk-mock-all'" > /dev/null 2>&1
|
||||
R=$(do_post -H "Authorization: Bearer sk-mock-all" "$API/v1/chat/completions" -H "Content-Type: application/json" -d '{"model":"gpt-4o","messages":[]}')
|
||||
assert_http "quota exceeded → 402" "402" "Quota exceeded" "$R"
|
||||
npx wrangler d1 execute awsl-one-api --local --command "UPDATE api_token SET usage = 0 WHERE key = 'sk-mock-all'" > /dev/null 2>&1
|
||||
npx wrangler d1 execute one-api-workers --local --command "UPDATE api_token SET usage = 0 WHERE key = 'sk-mock-all'" > /dev/null 2>&1
|
||||
|
||||
# ---- Error recovery ----
|
||||
echo ""
|
||||
@@ -197,10 +197,10 @@ echo "========================================="
|
||||
echo ""
|
||||
echo "Cleaning up test data..."
|
||||
for key in test-openai test-azure test-claude test-c2o test-responses test-azure-resp; do
|
||||
npx wrangler d1 execute awsl-one-api --local --command "DELETE FROM channel_config WHERE key = '$key'" > /dev/null 2>&1
|
||||
npx wrangler d1 execute one-api-workers --local --command "DELETE FROM channel_config WHERE key = '$key'" > /dev/null 2>&1
|
||||
done
|
||||
for key in sk-mock-all sk-mock-openai sk-mock-quota; do
|
||||
npx wrangler d1 execute awsl-one-api --local --command "DELETE FROM api_token WHERE key = '$key'" > /dev/null 2>&1
|
||||
npx wrangler d1 execute one-api-workers --local --command "DELETE FROM api_token WHERE key = '$key'" > /dev/null 2>&1
|
||||
done
|
||||
echo "Cleanup done."
|
||||
|
||||
|
||||
@@ -7,30 +7,30 @@ MOCK="http://localhost:9999"
|
||||
echo "Setting up test channels and tokens..."
|
||||
|
||||
# Channel: openai type
|
||||
npx wrangler d1 execute awsl-one-api --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-openai', '{\"name\":\"test-openai\",\"type\":\"openai\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"deployment_mapper\":{\"gpt-4o\":\"gpt-4o\",\"gpt-4\":\"gpt-4\"}}')"
|
||||
npx wrangler d1 execute one-api-workers --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-openai', '{\"name\":\"test-openai\",\"type\":\"openai\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"deployment_mapper\":{\"gpt-4o\":\"gpt-4o\",\"gpt-4\":\"gpt-4\"}}')"
|
||||
|
||||
# Channel: azure-openai type
|
||||
npx wrangler d1 execute awsl-one-api --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-azure', '{\"name\":\"test-azure\",\"type\":\"azure-openai\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"api_version\":\"2024-02-01\",\"deployment_mapper\":{\"gpt-4o-azure\":\"gpt-4o-deployment\"}}')"
|
||||
npx wrangler d1 execute one-api-workers --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-azure', '{\"name\":\"test-azure\",\"type\":\"azure-openai\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"api_version\":\"2024-02-01\",\"deployment_mapper\":{\"gpt-4o-azure\":\"gpt-4o-deployment\"}}')"
|
||||
|
||||
# Channel: claude type
|
||||
npx wrangler d1 execute awsl-one-api --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-claude', '{\"name\":\"test-claude\",\"type\":\"claude\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"deployment_mapper\":{\"claude-3-opus\":\"claude-3-opus-20240229\"}}')"
|
||||
npx wrangler d1 execute one-api-workers --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-claude', '{\"name\":\"test-claude\",\"type\":\"claude\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"deployment_mapper\":{\"claude-3-opus\":\"claude-3-opus-20240229\"}}')"
|
||||
|
||||
# Channel: claude-to-openai type
|
||||
npx wrangler d1 execute awsl-one-api --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-c2o', '{\"name\":\"test-c2o\",\"type\":\"claude-to-openai\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"deployment_mapper\":{\"claude-via-openai\":\"claude-3-opus\"}}')"
|
||||
npx wrangler d1 execute one-api-workers --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-c2o', '{\"name\":\"test-c2o\",\"type\":\"claude-to-openai\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"deployment_mapper\":{\"claude-via-openai\":\"claude-3-opus\"}}')"
|
||||
|
||||
# Channel: openai-responses type
|
||||
npx wrangler d1 execute awsl-one-api --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-responses', '{\"name\":\"test-responses\",\"type\":\"openai-responses\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"deployment_mapper\":{\"gpt-4o-resp\":\"gpt-4o\"}}')"
|
||||
npx wrangler d1 execute one-api-workers --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-responses', '{\"name\":\"test-responses\",\"type\":\"openai-responses\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"deployment_mapper\":{\"gpt-4o-resp\":\"gpt-4o\"}}')"
|
||||
|
||||
# Channel: azure-openai-responses type
|
||||
npx wrangler d1 execute awsl-one-api --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-azure-resp', '{\"name\":\"test-azure-resp\",\"type\":\"azure-openai-responses\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"api_version\":\"2025-01-01\",\"deployment_mapper\":{\"gpt-4o-azure-resp\":\"gpt-4o-deployment\"}}')"
|
||||
npx wrangler d1 execute one-api-workers --local --command "INSERT OR REPLACE INTO channel_config (key, value) VALUES ('test-azure-resp', '{\"name\":\"test-azure-resp\",\"type\":\"azure-openai-responses\",\"endpoint\":\"$MOCK\",\"api_key\":\"mock-key\",\"api_version\":\"2025-01-01\",\"deployment_mapper\":{\"gpt-4o-azure-resp\":\"gpt-4o-deployment\"}}')"
|
||||
|
||||
# Token: access to all test channels only
|
||||
npx wrangler d1 execute awsl-one-api --local --command "INSERT OR REPLACE INTO api_token (key, value, usage) VALUES ('sk-mock-all', '{\"name\":\"mock-all\",\"channel_keys\":[\"test-openai\",\"test-azure\",\"test-claude\",\"test-c2o\",\"test-responses\",\"test-azure-resp\"],\"total_quota\":99999999}', 0)"
|
||||
npx wrangler d1 execute one-api-workers --local --command "INSERT OR REPLACE INTO api_token (key, value, usage) VALUES ('sk-mock-all', '{\"name\":\"mock-all\",\"channel_keys\":[\"test-openai\",\"test-azure\",\"test-claude\",\"test-c2o\",\"test-responses\",\"test-azure-resp\"],\"total_quota\":99999999}', 0)"
|
||||
|
||||
# Token: limited to openai only
|
||||
npx wrangler d1 execute awsl-one-api --local --command "INSERT OR REPLACE INTO api_token (key, value, usage) VALUES ('sk-mock-openai', '{\"name\":\"mock-openai\",\"channel_keys\":[\"test-openai\"],\"total_quota\":99999999}', 0)"
|
||||
npx wrangler d1 execute one-api-workers --local --command "INSERT OR REPLACE INTO api_token (key, value, usage) VALUES ('sk-mock-openai', '{\"name\":\"mock-openai\",\"channel_keys\":[\"test-openai\"],\"total_quota\":99999999}', 0)"
|
||||
|
||||
# Token: quota almost full
|
||||
npx wrangler d1 execute awsl-one-api --local --command "INSERT OR REPLACE INTO api_token (key, value, usage) VALUES ('sk-mock-quota', '{\"name\":\"mock-quota\",\"channel_keys\":[\"test-openai\"],\"total_quota\":100}', 99)"
|
||||
npx wrangler d1 execute one-api-workers --local --command "INSERT OR REPLACE INTO api_token (key, value, usage) VALUES ('sk-mock-quota', '{\"name\":\"mock-quota\",\"channel_keys\":[\"test-openai\"],\"total_quota\":100}', 99)"
|
||||
|
||||
echo "Test data setup complete!"
|
||||
Reference in new issue
Block a user