⏰ 60s API 免费接口。每天 60 秒看世界、奥运奖牌榜、小红书/B站/微博/抖音/知乎热搜、金价、油价、天气、翻译、壁纸、Epic 游戏、二维码、猫眼票房|一系列 高质量、开源、可靠、全球 CDN 加速 的开放 API 集合,支持 Docker / Deno / Bun / Cloudflare Workers / Node.js 部署
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
60s API is a comprehensive API collection providing news, trending topics, and utility services. Built with Deno and Oak framework, it supports multiple runtime environments (Deno, Node.js, Bun) and deployment platforms (Docker, Cloudflare Workers).
## Development Commands
### Running the application
```bash
# Development mode (port 4398)
pnpm run dev
# Production mode (port 4398)
pnpm run start
# Docker
pnpm run docker:build
pnpm run docker:run
```
### Common operations
```bash
# Update all lockfiles
pnpm run update-lockfile
# Release new version (bumps version and creates git tag)
pnpm run release
```
## Architecture
### Core Structure
- **Entry points**: `deno.ts`, `node.ts`, `bun.ts`, `cf-worker.ts` for different runtimes
- **Main app**: `src/app.ts` - Oak application with middleware setup
- **Routing**: `src/router.ts` - centralized route definitions with `/v2` prefix
- **Modules**: `src/modules/` - individual API service implementations
- **Middlewares**: `src/middlewares/` - cross-cutting concerns (CORS, error handling, encoding)
### Key Components
- **Common utilities**: `src/common.ts` - shared functions for JSON building, parameter extraction, date formatting
- **Configuration**: `src/config.ts` - environment-based settings
- **Encoding middleware**: Handles `encoding` query parameter for response format transformation
## Development Guidelines
### Module Development Pattern
Each API endpoint follows a consistent module pattern:
1. **Create service class** in `src/modules/[name].module.ts`
2. **Implement `handle()` method** returning Oak RouterMiddleware
3. **Handle different encoding formats** in the middleware (see Response Formats below)
4. **Register route** in `src/router.ts`
5. **Import and add** to router configuration
Example structure:
```typescript
export class MyModule {
async handle(): RouterMiddleware<any> {
return async (ctx) => {
const encoding = ctx.state.encoding
const data = await this.fetchData()
if (encoding === 'text') {
ctx.response.body = this.formatAsText(data)
} else if (encoding === 'markdown') {
ctx.response.body = this.formatAsMarkdown(data)
} else {
ctx.response.body = Common.buildJson(data)
}
}
}
}
```
### Response Format Standards
**IMPORTANT**: Unless specifically noted otherwise, ALL APIs MUST support these three encoding formats:
- `json` (default) - structured JSON response via `Common.buildJson()`
- `text` - plain text format for terminal/script usage
- `markdown` - markdown formatted text for documentation/display
Special formats (only when explicitly needed):
- `image` - redirect to image URL
- `image-proxy` - proxied image content
- `html` - HTML encoded output
### Time Handling Standards
**ALWAYS use `dayjs` for time operations:**
```typescript
import { dayjs, TZ_SHANGHAI } from './common.ts'
// Get current time in Shanghai timezone
const now = dayjs().tz(TZ_SHANGHAI)
// Format date
const dateStr = now.format('YYYY-MM-DD')
// Parse and convert timezone
const parsedDate = dayjs(timestamp).tz(TZ_SHANGHAI)
```
**Default timezone**: Always use `TZ_SHANGHAI` (`Asia/Shanghai`) for all time operations unless explicitly specified otherwise.
### Common Patterns
**Response Building:**
```typescript
// Success response
ctx.response.body = Common.buildJson(data)
// Error response with custom message
ctx.response.status = 400
ctx.response.body = Common.buildJson(null, 400, 'Custom error message')
// Require arguments
if (!param) {
Common.requireArguments('paramName', ctx.response)
return
}
```
**Parameter Handling:**
```typescript
// Query parameters
const param = ctx.request.url.searchParams.get('param')
// Support both query and POST body (for large params)
const largeParam = await Common.getParam('param', ctx.request, true)
```
**Web Scraping:**
```typescript
// Always use Common.chromeUA for User-Agent
const response = await fetch(url, {
headers: { 'User-Agent': Common.chromeUA }
})
```
**Caching:**
```typescript
// Implement caching for expensive operations
const cache = new Map<string, { data: any; timestamp: number }>()
const CACHE_TTL = 30 * 60 * 1000 // 30 minutes
// Check cache before fetching
const cached = cache.get(key)
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data
}
```
### Code Quality Standards
- **Type Safety**: Use TypeScript types, avoid `any` when possible
- **Error Handling**: Always handle fetch errors and invalid responses
- **Validation**: Validate required parameters using `Common.requireArguments()`
- **Consistency**: Follow existing code patterns in `src/modules/`
- **Documentation**: Add JSDoc comments for complex functions
- **Testing**: Test all three encoding formats (json/text/markdown) when adding new APIs
### Useful Utilities
From `src/common.ts`:
- `Common.buildJson()` - Standard JSON response builder
- `Common.requireArguments()` - Parameter validation
- `dayjs` / `TZ_SHANGHAI` - Time operations (prefer over `Common.localeDate()`/`Common.localeTime()`)
- `Common.randomInt()` / `Common.randomItem()` - Random utilities
- `Common.md5()` - MD5 hashing
- `Common.qs()` - Query string builder
- `Common.tryRepoUrl()` - GitHub CDN fallback fetcher
**Note**: `Common.localeDate()` and `Common.localeTime()` are legacy utilities. For new code, always use `dayjs` with `TZ_SHANGHAI` timezone as shown in the Time Handling Standards section.