Some checks failed
Release / build-and-release (push) Failing after 1m31s
- Go 后端 (Gin + GORM + SQLite) 提供 API 和纯文本脚本服务 - Vite + React + TypeScript + Tailwind 前端 - 单二进制部署 (Go embed 前端静态文件) - Gitea Actions CI/CD: 打标签自动构建多平台 Release - 支持 bash/zsh/sh/fish/python3/node/ruby/php 8种运行环境 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
6.6 KiB
6.6 KiB
ScriptForge 设计文档
概述
脚本快速转运行链接服务。用户粘贴脚本内容,选择运行环境,生成一个短链。在终端执行 curl URL | <runtime> 即可运行脚本。
- 前端:Next.js (App Router + Tailwind CSS + TypeScript)
- 后端:Go (Gin + GORM + SQLite)
- 部署:Go embed 前端静态文件,单二进制部署
- CI/CD:Gitea Actions
核心流程
- 用户打开首页
/ - 粘贴脚本内容(上限 16KB)
- 选择运行环境(bash / zsh / sh / fish / python3 / node / ruby / php)
- 选择过期时间(1小时 / 24小时 / 7天 / 30天)
- 提交 → 后端存入 SQLite → 返回短链 ID
- 页面展示生成的命令:
curl https://example.com/raw/xK8mPq | bash - 用户可以复制命令到终端执行
API 设计
POST /api/scripts — 创建脚本
请求体:
{
"content": "#!/bin/bash\necho hello",
"runtime": "bash",
"expires_in": "24h"
}
响应:
{
"id": "xK8mPq",
"admin_token": "dGhpcyBpcyBhIHRva2Vu",
"url": "https://example.com/raw/xK8mPq",
"command": "curl https://example.com/raw/xK8mPq | bash",
"runtime": "bash",
"expires_at": "2026-05-29T16:27:00Z"
}
GET /api/scripts/:id — 获取脚本元数据
响应:
{
"id": "xK8mPq",
"runtime": "bash",
"content_length": 25,
"created_at": "2026-05-28T16:27:00Z",
"expires_at": "2026-05-29T16:27:00Z",
"expired": false
}
注意:此接口不返回脚本原始内容(内容通过
/raw/:id获取),避免前端二次暴露。
GET /raw/:id — 获取脚本纯文本内容
- 响应头
Content-Type: 根据 runtime 设置对应 MIME(见运行时配置表) - 响应头
Content-Disposition:attachment; filename="script.<ext>"(根据 runtime 设置扩展名) - 响应体:脚本纯文本内容
- 如脚本已过期,返回 404
DELETE /api/scripts/:id?token=xxx — 删除脚本
- 需要
admin_token参数 - 成功返回 204
数据模型
type Script struct {
ID string `gorm:"primaryKey;size:8"`
Content string `gorm:"type:text;not null"`
Runtime string `gorm:"size:16;not null;index"`
AdminToken string `gorm:"size:64;not null"`
ExpiresAt time.Time `gorm:"not null;index"`
CreatedAt time.Time `gorm:"not null"`
}
运行时配置
| Runtime | 扩展名 | MIME 类型 | 命令模板 |
|---|---|---|---|
| bash | .sh |
text/x-shellscript |
curl {url} | bash |
| zsh | .zsh |
text/x-shellscript |
curl {url} | zsh |
| sh | .sh |
text/x-shellscript |
curl {url} | sh |
| fish | .fish |
text/x-shellscript |
curl {url} | fish |
| python3 | .py |
text/x-python |
curl {url} | python3 |
| node | .js |
text/javascript |
curl {url} | node |
| ruby | .rb |
text/x-ruby |
curl {url} | ruby |
| php | .php |
text/x-php |
curl {url} | php |
运行环境列表在 Go 后端定义为常量数组,用于校验请求中的 runtime 字段。
过期策略
- 用户保存时选择:1小时 / 24小时 / 7天 / 30天
- 后端定时任务(每分钟扫描一次),删除过期记录
- 过期后
/raw/:id返回 404,详情页标记为已过期
限流策略
- 创建接口:10 次/分钟/IP
- 其他接口:60 次/分钟/IP
- 请求体上限:17KB
安全设计
- 完全公开,无需注册/登录
- 创建时返回
admin_token(随机 64 位字符串),持有者可删除脚本 - 无内容过滤,靠过期机制和限流控制风险
- 编辑功能:无(
admin_token仅用于删除,不能改内容。设计上 script 是一次性的,编辑会带来版本管理等复杂问题)
前端路由
| 路由 | 页面 | 说明 |
|---|---|---|
/ |
首页 | 粘贴脚本 + 选择运行环境/过期时间 + 提交 + 结果展示 |
/s/[id] |
脚本详情页 | 展示脚本内容(语法高亮)、元数据、curl 命令卡片 |
/s/[id]/delete |
删除确认页 | 输入 admin_token 确认删除 |
项目目录结构
scriptforge/
├── frontend/ # Next.js 项目
│ ├── src/
│ │ ├── app/
│ │ │ ├── page.tsx # 首页
│ │ │ ├── layout.tsx # 根布局
│ │ │ └── s/[id]/
│ │ │ ├── page.tsx # 脚本详情页
│ │ │ └── delete/
│ │ │ └── page.tsx # 删除确认页
│ │ ├── components/
│ │ │ ├── ScriptForm.tsx # 脚本提交表单
│ │ │ ├── ResultCard.tsx # 结果展示卡(含复制按钮)
│ │ │ ├── ScriptViewer.tsx # 脚本内容展示(语法高亮)
│ │ │ └── CommandCard.tsx # curl 命令展示卡
│ │ └── lib/
│ │ └── api.ts # API 调用封装
│ ├── package.json
│ └── next.config.js
├── backend/ # Go 项目
│ ├── cmd/
│ │ └── server/
│ │ └── main.go # 入口
│ ├── internal/
│ │ ├── handler/
│ │ │ ├── script.go # 脚本 CRUD handlers
│ │ │ └── raw.go # 原始内容 handler
│ │ ├── model/
│ │ │ └── script.go # GORM model
│ │ ├── service/
│ │ │ └── script.go # 业务逻辑
│ │ ├── middleware/
│ │ │ └── ratelimit.go # 限流中间件
│ │ └── config/
│ │ └── runtime.go # 运行时配置列表
│ ├── go.mod
│ └── go.sum
├── .gitea/
│ └── workflows/
│ └── deploy.yml # Gitea Actions 部署流程
├── Makefile # 统一构建命令
├── DESIGN.md # 本设计文档
└── README.md
CI/CD 部署流程(Gitea Actions)
- 触发条件:push 到
main分支 - 构建步骤:
cd frontend && npm ci && npm run build→ 输出out/cd backend && cp -r ../frontend/out ./internal/embed && go build -o server ./cmd/server
- 部署步骤:
scp二进制到服务器ssh执行systemctl restart scriptforge
后续可扩展方向
- 大模型集成:根据脚本内容自动推荐运行环境
- 更多运行时:dockerfile、powershell、deno、bun 等
- 脚本版本管理(不基于 admin_token,需要真正的用户系统)
- 统计数据:脚本执行次数、来源 IP 等(需要跟踪 curl 请求)
- WebSocket 实时执行输出流