Files
Arcrun/landing/app/api-docs/page.tsx
T
Leo 4516cdee4b feat: add landing page + builtins Worker + BETA_TEST guide + README
- landing/: Next.js 15 app for arcrun.dev (dashboard, integrations,
  API docs, login). Deploys via Cloudflare Pages — CI scan skips
  this via pages_build_output_dir marker.
- builtins/: minimal Hono Worker at arcrun-builtins (/init for
  one-shot component registry seeding). initComponents logic is
  flagged stale in src/index.ts for future rewrite.
- BETA_TEST.md: pre-launch validation playbook.
- README.md: updated to match current arcrun.dev / acr CLI flow.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 17:52:41 +08:00

113 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useEffect, useRef } from 'react';
import Link from 'next/link';
const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? 'https://cypher.arcrun.dev';
export default function ApiDocsPage() {
const containerRef = useRef<HTMLDivElement>(null);
const initialized = useRef(false);
useEffect(() => {
if (initialized.current || !containerRef.current) return;
initialized.current = true;
// Dynamically load Swagger UI from CDN
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://unpkg.com/swagger-ui-dist@5/swagger-ui.css';
document.head.appendChild(link);
const script = document.createElement('script');
script.src = 'https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js';
script.onload = () => {
const SwaggerUIBundle = (window as unknown as { SwaggerUIBundle: (opts: unknown) => void }).SwaggerUIBundle;
if (!SwaggerUIBundle || !containerRef.current) return;
SwaggerUIBundle({
url: `${API_BASE}/docs`,
dom_id: '#swagger-ui',
presets: [(window as unknown as { SwaggerUIBundle: { presets: { apis: unknown } } }).SwaggerUIBundle.presets.apis],
layout: 'BaseLayout',
defaultModelsExpandDepth: -1,
docExpansion: 'list',
filter: true,
tryItOutEnabled: true,
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
requestInterceptor: (request: { headers: Record<string, string> }) => {
// Inject API key from localStorage if present
const key = localStorage.getItem('arcrun_api_key');
if (key) request.headers['X-Arcrun-API-Key'] = key;
return request;
},
});
};
document.head.appendChild(script);
return () => {
// cleanup not strictly needed for page navigation
};
}, []);
return (
<div className="min-h-screen bg-[#0a0a0a] text-[#ededed]">
{/* Nav */}
<nav className="flex items-center justify-between px-6 py-4 border-b border-[#1a1a1a]">
<Link href="/" className="text-white font-bold text-lg tracking-tight hover:opacity-80 transition-opacity">
arcrun
</Link>
<div className="flex items-center gap-4 text-sm">
<Link href="/integrations" className="text-[#666] hover:text-white transition-colors">Integrations</Link>
<Link href="/dashboard" className="text-[#666] hover:text-white transition-colors">Dashboard</Link>
<Link href="/login"
className="bg-indigo-600 hover:bg-indigo-500 text-white px-4 py-1.5 rounded-md text-sm font-medium transition-colors">
Get API Key
</Link>
</div>
</nav>
{/* Header */}
<div className="max-w-5xl mx-auto px-6 py-8">
<h1 className="text-2xl font-bold text-white mb-2">API Reference</h1>
<p className="text-[#555] text-sm mb-2">
這是 arcrun 的原始 APIPython / JS lib 是它的包裝,任何能發 HTTP request 的工具都能直接用。
</p>
<p className="text-[#444] text-xs mb-6">
Endpoint: <span className="font-mono text-[#666]">{API_BASE}</span>
</p>
{/* API Key hint */}
<div className="bg-[#111] border border-[#222] rounded-lg p-4 mb-8 text-sm">
<p className="text-[#666] mb-2">
若要在此頁面試打 API,請先設定 API Key
</p>
<ApiKeyInput />
</div>
{/* Swagger UI */}
<div className="bg-white rounded-xl overflow-hidden" ref={containerRef}>
<div id="swagger-ui" className="min-h-96"></div>
</div>
</div>
</div>
);
}
function ApiKeyInput() {
return (
<div className="flex gap-2">
<input
type="text"
placeholder="ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
className="flex-1 bg-[#0a0a0a] border border-[#2a2a2a] rounded px-3 py-1.5 text-xs font-mono text-[#cdd6f4] focus:outline-none focus:border-indigo-700"
onChange={(e) => {
if (e.target.value.startsWith('ak_')) {
localStorage.setItem('arcrun_api_key', e.target.value);
}
}}
/>
<span className="text-[#444] text-xs self-center">自動注入到 requests</span>
</div>
);
}