@tokcalc/mcp-server 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.zscripts/build.sh +175 -0
- package/.zscripts/database-runtime-build.sh +33 -0
- package/.zscripts/dev.pid +1 -0
- package/.zscripts/dev.sh +154 -0
- package/.zscripts/mini-services-build.sh +78 -0
- package/.zscripts/mini-services-install.sh +65 -0
- package/.zscripts/mini-services-start.sh +123 -0
- package/.zscripts/python-runtime-build.sh +120 -0
- package/.zscripts/start.sh +145 -0
- package/CAPACITY_STUDY.md +283 -0
- package/CODE_OF_CONDUCT.md +55 -0
- package/CONTRIBUTING.md +177 -0
- package/Caddyfile +23 -0
- package/LICENSE +204 -0
- package/README.md +406 -86
- package/bun.lock +1965 -0
- package/components.json +21 -0
- package/db/custom.db +0 -0
- package/download/README.md +1 -0
- package/download/tokcalc-dark-calculator.png +0 -0
- package/download/tokcalc-dark-default.png +0 -0
- package/download/tokcalc-demo.webm +0 -0
- package/download/tokcalc-github-link.png +0 -0
- package/download/tokcalc-hydration-fixed.png +0 -0
- package/download/tokcalc-issue-resolved.png +0 -0
- package/download/tokcalc-light-mode.png +0 -0
- package/download/tokcalc-light-reference.png +0 -0
- package/download/tokcalc-long-context-qwen.png +0 -0
- package/download/tokcalc-long-context.png +0 -0
- package/download/tokcalc-og-image-preview.png +0 -0
- package/download/tokcalc-phase2-3.png +0 -0
- package/download/tokcalc-plain-english.png +0 -0
- package/download/tokcalc-preview.png +0 -0
- package/download/tokcalc-share-bvb.png +0 -0
- package/download/tokcalc-share-feature.png +0 -0
- package/download/tokcalc-tab-build-vs-buy.png +0 -0
- package/download/tokcalc-tab-calculator.png +0 -0
- package/download/tokcalc-tab-reference.png +0 -0
- package/eslint.config.mjs +50 -0
- package/examples/websocket/frontend.tsx +196 -0
- package/examples/websocket/server.ts +138 -0
- package/mini-services/.gitkeep +0 -0
- package/mini-services/mcp-server/README.md +86 -0
- package/mini-services/mcp-server/bun.lock +202 -0
- package/mini-services/mcp-server/index.ts +504 -0
- package/mini-services/mcp-server/package.json +40 -0
- package/next.config.ts +12 -0
- package/package.json +92 -35
- package/postcss.config.mjs +5 -0
- package/prisma/schema.prisma +32 -0
- package/public/google6f58ca6be85fa903.html +1 -0
- package/public/logo.svg +29 -0
- package/public/manifest.json +51 -0
- package/public/og-icon-256.png +0 -0
- package/public/og.png +0 -0
- package/public/robots.txt +25 -0
- package/public/sitemap.xml +23 -0
- package/public/tokcalc-demo.gif +0 -0
- package/scripts/og-template.html +120 -0
- package/scripts/render-og.mjs +43 -0
- package/server.json +21 -0
- package/src/app/api/pricing/aws/route.ts +186 -0
- package/src/app/api/pricing/azure/route.ts +168 -0
- package/src/app/api/pricing/gcp/route.ts +230 -0
- package/src/app/api/pricing/vast-ai/route.ts +164 -0
- package/src/app/api/route.ts +5 -0
- package/src/app/compare/h100-vs-h200/layout.tsx +30 -0
- package/src/app/compare/h100-vs-h200/page.tsx +328 -0
- package/src/app/globals.css +122 -0
- package/src/app/layout.tsx +276 -0
- package/src/app/page.tsx +2670 -0
- package/src/components/azure-live-pricing.tsx +185 -0
- package/src/components/benchmark-import.tsx +340 -0
- package/src/components/confidence-badge.tsx +116 -0
- package/src/components/live-pricing-comparison.tsx +241 -0
- package/src/components/theme-provider.tsx +11 -0
- package/src/components/theme-toggle.tsx +55 -0
- package/src/components/ui/accordion.tsx +66 -0
- package/src/components/ui/alert-dialog.tsx +157 -0
- package/src/components/ui/alert.tsx +66 -0
- package/src/components/ui/aspect-ratio.tsx +11 -0
- package/src/components/ui/avatar.tsx +53 -0
- package/src/components/ui/badge.tsx +46 -0
- package/src/components/ui/breadcrumb.tsx +109 -0
- package/src/components/ui/button.tsx +59 -0
- package/src/components/ui/calendar.tsx +213 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/carousel.tsx +241 -0
- package/src/components/ui/chart.tsx +353 -0
- package/src/components/ui/checkbox.tsx +32 -0
- package/src/components/ui/collapsible.tsx +33 -0
- package/src/components/ui/command.tsx +184 -0
- package/src/components/ui/context-menu.tsx +252 -0
- package/src/components/ui/dialog.tsx +143 -0
- package/src/components/ui/drawer.tsx +135 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/form.tsx +167 -0
- package/src/components/ui/hover-card.tsx +44 -0
- package/src/components/ui/input-otp.tsx +77 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/menubar.tsx +276 -0
- package/src/components/ui/navigation-menu.tsx +168 -0
- package/src/components/ui/pagination.tsx +127 -0
- package/src/components/ui/popover.tsx +48 -0
- package/src/components/ui/progress.tsx +31 -0
- package/src/components/ui/radio-group.tsx +45 -0
- package/src/components/ui/resizable.tsx +56 -0
- package/src/components/ui/scroll-area.tsx +58 -0
- package/src/components/ui/select.tsx +185 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +139 -0
- package/src/components/ui/sidebar.tsx +726 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/slider.tsx +63 -0
- package/src/components/ui/sonner.tsx +25 -0
- package/src/components/ui/switch.tsx +31 -0
- package/src/components/ui/table.tsx +116 -0
- package/src/components/ui/tabs.tsx +66 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/toast.tsx +129 -0
- package/src/components/ui/toaster.tsx +35 -0
- package/src/components/ui/toggle-group.tsx +73 -0
- package/src/components/ui/toggle.tsx +47 -0
- package/src/components/ui/tooltip.tsx +61 -0
- package/src/components/vast-ai-live-pricing.tsx +176 -0
- package/src/hooks/use-mobile.ts +19 -0
- package/src/hooks/use-toast.ts +194 -0
- package/src/lib/benchmark-parser-sglang.ts +150 -0
- package/src/lib/benchmark-parser-tokcalc.ts +247 -0
- package/src/lib/benchmark-parser-trtllm.ts +152 -0
- package/src/lib/benchmark-parser-vllm.ts +198 -0
- package/src/lib/benchmark-schema.ts +263 -0
- package/src/lib/db.ts +13 -0
- package/src/lib/engine-presets.ts +183 -0
- package/src/lib/price-schema.ts +141 -0
- package/src/lib/token-calc.ts +808 -0
- package/src/lib/track.ts +31 -0
- package/src/lib/url-state.ts +256 -0
- package/src/lib/utils.ts +6 -0
- package/tailwind.config.ts +64 -0
- package/tests/database-runtime-build.sh +75 -0
- package/tests/python-runtime-build.sh +64 -0
- package/tests/python-runtime-container.sh +31 -0
- package/tool-results/bash_1789888171144_2c5381860539.txt +161 -0
- package/tool-results/bash_1789888175925_49c53ba3c61b.txt +191 -0
- package/tool-results/bash_1789888181202_49c53ba3c61b.txt +191 -0
- package/tool-results/bash_1789888195219_4a86a5c91411.txt +200 -0
- package/tool-results/bash_1789888203128_6cca13c71b47.txt +199 -0
- package/tool-results/bash_1789929256963_2a52aff0d0a8.txt +160 -0
- package/tool-results/read_1789888151021_69f58eec6a5b.txt +653 -0
- package/tool-results/read_1789888153837_1d3a8bfc2a94.txt +653 -0
- package/tool-results/read_1789888163087_ccc406d47505.txt +122 -0
- package/tool-results/read_1789888167347_67d1d7c9830a.txt +122 -0
- package/tool-results/read_1789929252529_d90e8f383a25.txt +285 -0
- package/tsconfig.json +42 -0
- package/upload/Pasted Content_1789887800864.txt +652 -0
- package/upload/Pasted Content_1789887909561.txt +652 -0
- package/upload/Pasted Content_1789887918428.txt +652 -0
- package/upload/Pasted Content_1789887959420.txt +652 -0
- package/upload/Pasted Content_1789888020485.txt +652 -0
- package/upload/Pasted Content_1789888058079.txt +652 -0
- package/upload/Pasted Content_1789888885033.txt +686 -0
- package/upload/Pasted Content_1789928912741.txt +285 -0
- package/upload/Pasted Content_1789928938402.txt +285 -0
- package/upload/Pasted Content_1789929160389.txt +285 -0
- package/upload/Pasted Content_1789929176660.txt +285 -0
- package/upload/issue_vision.json +28 -0
- package/upload/pasted_image_1789883175209.png +0 -0
- package/upload/pasted_image_1789899056690.png +0 -0
- package/upload/pasted_image_1789900371483.png +0 -0
- package/upload/pasted_image_1789900472823.png +0 -0
- package/upload/pasted_image_1789900490374.png +0 -0
- package/upload/pasted_image_1789900585552.png +0 -0
- package/upload/pasted_image_1789900606519.png +0 -0
- package/upload/pasted_image_1789901598705.png +0 -0
- package/upload/pasted_image_1789901613545.png +0 -0
- package/upload/pasted_image_1789978382674.png +0 -0
- package/upload/pasted_image_1789978392749.png +0 -0
- package/upload/pasted_image_1789978474879.png +0 -0
- package/upload/pasted_image_1789978523652.png +0 -0
- package/upload/pasted_image_1789984219089.png +0 -0
- package/upload/pasted_image_1789984491896.png +0 -0
- package/upload/pasted_image_1789985017950.png +0 -0
- package/upload/pasted_image_1789985036765.png +0 -0
- package/upload/pasted_image_1789985049848.png +0 -0
- package/upload/pasted_image_1790002427833.png +0 -0
- package/upload/pasted_image_1790002659944.png +0 -0
- package/upload/pasted_image_1790037038476.png +0 -0
- package/upload/screenshot_analysis.json +28 -0
- package/upload/vision_output.json +28 -0
- package/dist/index.js +0 -21014
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# 将 stderr 重定向到 stdout,避免 execute_command 因为 stderr 输出而报错
|
|
4
|
+
exec 2>&1
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# 获取脚本所在目录(.zscripts 目录,即 workspace-agent/.zscripts)
|
|
9
|
+
# 使用 $0 获取脚本路径(兼容 sh 和 bash)
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
11
|
+
|
|
12
|
+
# Next.js 项目路径
|
|
13
|
+
NEXTJS_PROJECT_DIR="/home/z/my-project"
|
|
14
|
+
|
|
15
|
+
# 检查 Next.js 项目目录是否存在
|
|
16
|
+
if [ ! -d "$NEXTJS_PROJECT_DIR" ]; then
|
|
17
|
+
echo "❌ 错误: Next.js 项目目录不存在: $NEXTJS_PROJECT_DIR"
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
echo "🚀 开始构建 Next.js 应用和 mini-services..."
|
|
22
|
+
echo "📁 Next.js 项目路径: $NEXTJS_PROJECT_DIR"
|
|
23
|
+
|
|
24
|
+
# 切换到 Next.js 项目目录
|
|
25
|
+
cd "$NEXTJS_PROJECT_DIR" || exit 1
|
|
26
|
+
|
|
27
|
+
# 设置环境变量
|
|
28
|
+
export NEXT_TELEMETRY_DISABLED=1
|
|
29
|
+
|
|
30
|
+
BUILD_DIR="/tmp/build_fullstack_$BUILD_ID"
|
|
31
|
+
echo "📁 清理并创建构建目录: $BUILD_DIR"
|
|
32
|
+
mkdir -p "$BUILD_DIR"
|
|
33
|
+
|
|
34
|
+
# 安装依赖
|
|
35
|
+
echo "📦 安装依赖..."
|
|
36
|
+
bun install
|
|
37
|
+
|
|
38
|
+
# 构建 Next.js 应用
|
|
39
|
+
echo "🔨 构建 Next.js 应用..."
|
|
40
|
+
bun run build
|
|
41
|
+
|
|
42
|
+
# 校验 standalone 服务端入口是否生成(部署成功率守卫)。
|
|
43
|
+
# Next 仅在 next.config 含 output:"standalone" 时产出 .next/standalone/server.js。
|
|
44
|
+
# 若用户/AI 编辑项目时改写或删除了该配置,bun run build 仍会成功(static 照常
|
|
45
|
+
# 产出、退出码 0),但 standalone 缺失——打出的包里没有 server.js,部署到 FC 后
|
|
46
|
+
# start.sh 找不到 next-service-dist/server.js → 不启动 Next → Caddy:81 反代空的
|
|
47
|
+
# 3000 → FC 健康检查 120s 超时失败(线上 warmup_412 / FunctionNotStarted 的主因)。
|
|
48
|
+
# 这里做一次自愈:仅在确实缺失时,给 next.config 补回 output:"standalone" 并重建。
|
|
49
|
+
# 正常项目(已生成 server.js)整段跳过,不读写任何用户文件。
|
|
50
|
+
if [ ! -f ".next/standalone/server.js" ]; then
|
|
51
|
+
echo "⚠️ 构建未产出 .next/standalone/server.js,开始自愈 next.config 的 output 配置..."
|
|
52
|
+
NEXT_CONFIG_FILE="$(ls next.config.ts next.config.js next.config.mjs next.config.cjs 2>/dev/null | head -1)"
|
|
53
|
+
|
|
54
|
+
if [ -z "$NEXT_CONFIG_FILE" ]; then
|
|
55
|
+
echo "❌ 构建失败:未找到 next.config.*,无法生成 standalone 部署产物。"
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
if grep -Eq "output\s*:\s*['\"]standalone['\"]" "$NEXT_CONFIG_FILE"; then
|
|
60
|
+
# 已声明 standalone 却仍没产出 server.js,说明不是配置缺失(可能 build 真
|
|
61
|
+
# 出错、自定义 distDir 等)。不臆改用户配置,直接失败并暴露原因。
|
|
62
|
+
echo "❌ 构建失败:$NEXT_CONFIG_FILE 已含 output:\"standalone\",但仍未生成 .next/standalone/server.js。"
|
|
63
|
+
echo " 请检查上方构建日志中的报错或项目自定义的构建配置。"
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
if grep -Eq "output\s*:\s*['\"]" "$NEXT_CONFIG_FILE"; then
|
|
68
|
+
# 已显式声明了其它 output(如 "export" 静态导出 / "standalone" 之外的值)。
|
|
69
|
+
# "export" 与本部署模型(standalone + 自定义 server)互斥——不能注入第二个
|
|
70
|
+
# output 覆盖用户意图(JS 对象重复 key 后者生效,注入也无效)。明确失败。
|
|
71
|
+
echo "❌ 构建失败:$NEXT_CONFIG_FILE 已声明非 standalone 的 output(如 \"export\" 静态导出),与当前部署模型不兼容。"
|
|
72
|
+
echo " 当前部署需要 output:\"standalone\"。请改为 standalone,或确认该项目是否应走静态托管而非部署沙箱。"
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
echo "🔧 检测到 $NEXT_CONFIG_FILE 缺少 output:\"standalone\",自动注入后重新构建..."
|
|
77
|
+
cp "$NEXT_CONFIG_FILE" "${NEXT_CONFIG_FILE}.zbak"
|
|
78
|
+
# 在第一个配置对象字面量起始的 { 之后插入 output:"standalone",
|
|
79
|
+
# 覆盖脚手架常见写法:const nextConfig...= { / export default { / module.exports = {
|
|
80
|
+
perl -0pi -e 's/((?:const\s+\w+[^=]*=|export\s+default|module\.exports\s*=)\s*\{)/$1\n output: "standalone",/' "$NEXT_CONFIG_FILE"
|
|
81
|
+
|
|
82
|
+
if ! grep -Eq "output\s*:\s*['\"]standalone['\"]" "$NEXT_CONFIG_FILE"; then
|
|
83
|
+
echo "❌ 未能匹配到可注入的配置对象,next.config 写法非常规,需人工添加 output:\"standalone\"。"
|
|
84
|
+
echo " 当前 $NEXT_CONFIG_FILE 内容:"
|
|
85
|
+
cat "$NEXT_CONFIG_FILE"
|
|
86
|
+
mv "${NEXT_CONFIG_FILE}.zbak" "$NEXT_CONFIG_FILE"
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
echo "🔨 已注入 output:\"standalone\",重新构建..."
|
|
91
|
+
bun run build
|
|
92
|
+
|
|
93
|
+
if [ ! -f ".next/standalone/server.js" ]; then
|
|
94
|
+
echo "❌ 注入 output:\"standalone\" 并重建后,仍未生成 .next/standalone/server.js。"
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
echo "✅ 自愈成功:standalone 服务端入口已生成。"
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# 构建 mini-services
|
|
101
|
+
# 检查 Next.js 项目目录下是否有 mini-services 目录
|
|
102
|
+
if [ -d "$NEXTJS_PROJECT_DIR/mini-services" ]; then
|
|
103
|
+
echo "🔨 构建 mini-services..."
|
|
104
|
+
# 使用 workspace-agent 目录下的 mini-services 脚本
|
|
105
|
+
sh "$SCRIPT_DIR/mini-services-install.sh"
|
|
106
|
+
sh "$SCRIPT_DIR/mini-services-build.sh"
|
|
107
|
+
|
|
108
|
+
# 复制 mini-services-start.sh 到 mini-services-dist 目录
|
|
109
|
+
echo " - 复制 mini-services-start.sh 到 $BUILD_DIR"
|
|
110
|
+
cp "$SCRIPT_DIR/mini-services-start.sh" "$BUILD_DIR/mini-services-start.sh"
|
|
111
|
+
chmod +x "$BUILD_DIR/mini-services-start.sh"
|
|
112
|
+
else
|
|
113
|
+
echo "ℹ️ mini-services 目录不存在,跳过"
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# 将所有构建产物复制到临时构建目录
|
|
117
|
+
echo "📦 收集构建产物到 $BUILD_DIR..."
|
|
118
|
+
|
|
119
|
+
# 复制 Next.js standalone 构建输出
|
|
120
|
+
if [ -d ".next/standalone" ]; then
|
|
121
|
+
echo " - 复制 .next/standalone"
|
|
122
|
+
cp -r .next/standalone "$BUILD_DIR/next-service-dist/"
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
# 复制 Next.js 静态文件
|
|
126
|
+
if [ -d ".next/static" ]; then
|
|
127
|
+
echo " - 复制 .next/static"
|
|
128
|
+
mkdir -p "$BUILD_DIR/next-service-dist/.next"
|
|
129
|
+
cp -r .next/static "$BUILD_DIR/next-service-dist/.next/"
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
# 复制 public 目录
|
|
133
|
+
if [ -d "public" ]; then
|
|
134
|
+
echo " - 复制 public"
|
|
135
|
+
cp -r public "$BUILD_DIR/next-service-dist/"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# Python 不继承 workspace-agent 的 /home/z/.venv。若项目包含 Python 源码或
|
|
139
|
+
# 依赖清单,在构建期将生产依赖固化到产物,并保持 Python 源码的项目相对路径。
|
|
140
|
+
PROJECT_DIR="$NEXTJS_PROJECT_DIR" BUILD_DIR="$BUILD_DIR" \
|
|
141
|
+
bash "$SCRIPT_DIR/python-runtime-build.sh"
|
|
142
|
+
|
|
143
|
+
# 有 Preview 数据库时复制现有数据;没有时直接在部署产物中初始化空库。
|
|
144
|
+
# 模板源码不携带 db/custom.db,不能依赖 dev.sh 必须在 Deploy 前成功运行过。
|
|
145
|
+
PROJECT_DIR="$NEXTJS_PROJECT_DIR" BUILD_DIR="$BUILD_DIR" \
|
|
146
|
+
bash "$SCRIPT_DIR/database-runtime-build.sh"
|
|
147
|
+
|
|
148
|
+
# 复制 Caddyfile(如果存在)
|
|
149
|
+
if [ -f "Caddyfile" ]; then
|
|
150
|
+
echo " - 复制 Caddyfile"
|
|
151
|
+
cp Caddyfile "$BUILD_DIR/"
|
|
152
|
+
else
|
|
153
|
+
echo "ℹ️ Caddyfile 不存在,跳过"
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# 复制 start.sh 脚本
|
|
157
|
+
echo " - 复制 start.sh 到 $BUILD_DIR"
|
|
158
|
+
cp "$SCRIPT_DIR/start.sh" "$BUILD_DIR/start.sh"
|
|
159
|
+
chmod +x "$BUILD_DIR/start.sh"
|
|
160
|
+
|
|
161
|
+
# 打包到 $BUILD_DIR.tar.gz
|
|
162
|
+
PACKAGE_FILE="${BUILD_DIR}.tar.gz"
|
|
163
|
+
echo ""
|
|
164
|
+
echo "📦 打包构建产物到 $PACKAGE_FILE..."
|
|
165
|
+
cd "$BUILD_DIR" || exit 1
|
|
166
|
+
tar -czf "$PACKAGE_FILE" .
|
|
167
|
+
cd - > /dev/null || exit 1
|
|
168
|
+
|
|
169
|
+
# # 清理临时目录
|
|
170
|
+
# rm -rf "$BUILD_DIR"
|
|
171
|
+
|
|
172
|
+
echo ""
|
|
173
|
+
echo "✅ 构建完成!所有产物已打包到 $PACKAGE_FILE"
|
|
174
|
+
echo "📊 打包文件大小:"
|
|
175
|
+
ls -lh "$PACKAGE_FILE"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
PROJECT_DIR="${PROJECT_DIR:-/home/z/my-project}"
|
|
6
|
+
BUILD_DIR="${BUILD_DIR:?BUILD_DIR is required}"
|
|
7
|
+
SOURCE_DB_DIR="$PROJECT_DIR/db"
|
|
8
|
+
SOURCE_DB_PATH="$SOURCE_DB_DIR/custom.db"
|
|
9
|
+
TARGET_DB_DIR="$BUILD_DIR/db"
|
|
10
|
+
TARGET_DB_PATH="$TARGET_DB_DIR/custom.db"
|
|
11
|
+
|
|
12
|
+
mkdir -p "$TARGET_DB_DIR"
|
|
13
|
+
|
|
14
|
+
if [ -f "$SOURCE_DB_PATH" ]; then
|
|
15
|
+
echo "🗄️ 复制 Preview 数据库到构建产物..."
|
|
16
|
+
cp -a "$SOURCE_DB_DIR/." "$TARGET_DB_DIR/"
|
|
17
|
+
else
|
|
18
|
+
echo "ℹ️ 未找到 Preview 数据库 db/custom.db,将初始化空的生产数据库"
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
echo "🗄️ 同步构建产物中的数据库结构..."
|
|
22
|
+
(
|
|
23
|
+
cd "$PROJECT_DIR"
|
|
24
|
+
DATABASE_URL="file:$TARGET_DB_PATH" bun run db:push
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if [ ! -f "$TARGET_DB_PATH" ]; then
|
|
28
|
+
echo "❌ 数据库初始化命令执行成功,但未生成 $TARGET_DB_PATH"
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
echo "✅ 构建产物数据库已准备完成"
|
|
33
|
+
ls -lah "$TARGET_DB_DIR"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1204
|
package/.zscripts/dev.sh
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
# 获取脚本所在目录(.zscripts)
|
|
6
|
+
# 使用 $0 获取脚本路径(与 build.sh 保持一致)
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
+
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
9
|
+
|
|
10
|
+
log_step_start() {
|
|
11
|
+
local step_name="$1"
|
|
12
|
+
echo "=========================================="
|
|
13
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting: $step_name"
|
|
14
|
+
echo "=========================================="
|
|
15
|
+
export STEP_START_TIME
|
|
16
|
+
STEP_START_TIME=$(date +%s)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
log_step_end() {
|
|
20
|
+
local step_name="${1:-Unknown step}"
|
|
21
|
+
local end_time
|
|
22
|
+
end_time=$(date +%s)
|
|
23
|
+
local duration=$((end_time - STEP_START_TIME))
|
|
24
|
+
echo "=========================================="
|
|
25
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Completed: $step_name"
|
|
26
|
+
echo "[LOG] Step: $step_name | Duration: ${duration}s"
|
|
27
|
+
echo "=========================================="
|
|
28
|
+
echo ""
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
start_mini_services() {
|
|
32
|
+
local mini_services_dir="$PROJECT_DIR/mini-services"
|
|
33
|
+
local started_count=0
|
|
34
|
+
|
|
35
|
+
log_step_start "Starting mini-services"
|
|
36
|
+
if [ ! -d "$mini_services_dir" ]; then
|
|
37
|
+
echo "Mini-services directory not found, skipping..."
|
|
38
|
+
log_step_end "Starting mini-services"
|
|
39
|
+
return 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
echo "Found mini-services directory, scanning for sub-services..."
|
|
43
|
+
|
|
44
|
+
for service_dir in "$mini_services_dir"/*; do
|
|
45
|
+
if [ ! -d "$service_dir" ]; then
|
|
46
|
+
continue
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
local service_name
|
|
50
|
+
service_name=$(basename "$service_dir")
|
|
51
|
+
echo "Checking service: $service_name"
|
|
52
|
+
|
|
53
|
+
if [ ! -f "$service_dir/package.json" ]; then
|
|
54
|
+
echo "[$service_name] No package.json found, skipping..."
|
|
55
|
+
continue
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
if ! grep -q '"dev"' "$service_dir/package.json"; then
|
|
59
|
+
echo "[$service_name] No dev script found, skipping..."
|
|
60
|
+
continue
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
echo "Starting $service_name in background..."
|
|
64
|
+
(
|
|
65
|
+
cd "$service_dir"
|
|
66
|
+
echo "[$service_name] Installing dependencies..."
|
|
67
|
+
bun install
|
|
68
|
+
echo "[$service_name] Running bun run dev..."
|
|
69
|
+
exec bun run dev
|
|
70
|
+
) >"$PROJECT_DIR/.zscripts/mini-service-${service_name}.log" 2>&1 &
|
|
71
|
+
|
|
72
|
+
local service_pid=$!
|
|
73
|
+
echo "[$service_name] Started in background (PID: $service_pid)"
|
|
74
|
+
echo "[$service_name] Log: $PROJECT_DIR/.zscripts/mini-service-${service_name}.log"
|
|
75
|
+
disown "$service_pid" 2>/dev/null || true
|
|
76
|
+
started_count=$((started_count + 1))
|
|
77
|
+
done
|
|
78
|
+
|
|
79
|
+
echo "Mini-services startup completed. Started $started_count service(s)."
|
|
80
|
+
log_step_end "Starting mini-services"
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
wait_for_service() {
|
|
84
|
+
local host="$1"
|
|
85
|
+
local port="$2"
|
|
86
|
+
local service_name="$3"
|
|
87
|
+
local max_attempts="${4:-60}"
|
|
88
|
+
local attempt=1
|
|
89
|
+
|
|
90
|
+
echo "Waiting for $service_name to be ready on $host:$port..."
|
|
91
|
+
|
|
92
|
+
while [ "$attempt" -le "$max_attempts" ]; do
|
|
93
|
+
if curl -s --connect-timeout 2 --max-time 5 "http://$host:$port" >/dev/null 2>&1; then
|
|
94
|
+
echo "$service_name is ready!"
|
|
95
|
+
return 0
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
echo "Attempt $attempt/$max_attempts: $service_name not ready yet, waiting..."
|
|
99
|
+
sleep 1
|
|
100
|
+
attempt=$((attempt + 1))
|
|
101
|
+
done
|
|
102
|
+
|
|
103
|
+
echo "ERROR: $service_name failed to start within $max_attempts seconds"
|
|
104
|
+
return 1
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
cleanup() {
|
|
108
|
+
if [ -n "${DEV_PID:-}" ] && kill -0 "$DEV_PID" >/dev/null 2>&1; then
|
|
109
|
+
echo "Stopping Next.js dev server (PID: $DEV_PID)..."
|
|
110
|
+
kill "$DEV_PID" >/dev/null 2>&1 || true
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
trap cleanup EXIT INT TERM
|
|
115
|
+
|
|
116
|
+
cd "$PROJECT_DIR"
|
|
117
|
+
|
|
118
|
+
if ! command -v bun >/dev/null 2>&1; then
|
|
119
|
+
echo "ERROR: bun is not installed or not in PATH"
|
|
120
|
+
exit 1
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
log_step_start "bun install"
|
|
124
|
+
echo "[BUN] Installing dependencies..."
|
|
125
|
+
bun install
|
|
126
|
+
log_step_end "bun install"
|
|
127
|
+
|
|
128
|
+
log_step_start "bun run db:push"
|
|
129
|
+
echo "[BUN] Setting up database..."
|
|
130
|
+
bun run db:push
|
|
131
|
+
log_step_end "bun run db:push"
|
|
132
|
+
|
|
133
|
+
log_step_start "Starting Next.js dev server"
|
|
134
|
+
echo "[BUN] Starting development server..."
|
|
135
|
+
bun run dev &
|
|
136
|
+
DEV_PID=$!
|
|
137
|
+
log_step_end "Starting Next.js dev server"
|
|
138
|
+
|
|
139
|
+
log_step_start "Waiting for Next.js dev server"
|
|
140
|
+
wait_for_service "localhost" "3000" "Next.js dev server"
|
|
141
|
+
log_step_end "Waiting for Next.js dev server"
|
|
142
|
+
|
|
143
|
+
log_step_start "Health check"
|
|
144
|
+
echo "[BUN] Performing health check..."
|
|
145
|
+
curl -fsS localhost:3000 >/dev/null
|
|
146
|
+
echo "[BUN] Health check passed"
|
|
147
|
+
log_step_end "Health check"
|
|
148
|
+
|
|
149
|
+
start_mini_services
|
|
150
|
+
|
|
151
|
+
echo "Next.js dev server is running in background (PID: $DEV_PID)."
|
|
152
|
+
echo "Use 'kill $DEV_PID' to stop it."
|
|
153
|
+
disown "$DEV_PID" 2>/dev/null || true
|
|
154
|
+
unset DEV_PID
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# 配置项
|
|
4
|
+
ROOT_DIR="/home/z/my-project/mini-services"
|
|
5
|
+
DIST_DIR="/tmp/build_fullstack_$BUILD_ID/mini-services-dist"
|
|
6
|
+
|
|
7
|
+
main() {
|
|
8
|
+
echo "🚀 开始批量构建..."
|
|
9
|
+
|
|
10
|
+
# 检查 rootdir 是否存在
|
|
11
|
+
if [ ! -d "$ROOT_DIR" ]; then
|
|
12
|
+
echo "ℹ️ 目录 $ROOT_DIR 不存在,跳过构建"
|
|
13
|
+
return
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
# 创建输出目录(如果不存在)
|
|
17
|
+
mkdir -p "$DIST_DIR"
|
|
18
|
+
|
|
19
|
+
# 统计变量
|
|
20
|
+
success_count=0
|
|
21
|
+
fail_count=0
|
|
22
|
+
|
|
23
|
+
# 遍历 mini-services 目录下的所有文件夹
|
|
24
|
+
for dir in "$ROOT_DIR"/*; do
|
|
25
|
+
# 检查是否是目录且包含 package.json
|
|
26
|
+
if [ -d "$dir" ] && [ -f "$dir/package.json" ]; then
|
|
27
|
+
project_name=$(basename "$dir")
|
|
28
|
+
|
|
29
|
+
# 智能查找入口文件 (按优先级查找)
|
|
30
|
+
entry_path=""
|
|
31
|
+
for entry in "src/index.ts" "index.ts" "src/index.js" "index.js"; do
|
|
32
|
+
if [ -f "$dir/$entry" ]; then
|
|
33
|
+
entry_path="$dir/$entry"
|
|
34
|
+
break
|
|
35
|
+
fi
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
if [ -z "$entry_path" ]; then
|
|
39
|
+
echo "⚠️ 跳过 $project_name: 未找到入口文件 (index.ts/js)"
|
|
40
|
+
continue
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
echo ""
|
|
44
|
+
echo "📦 正在构建: $project_name..."
|
|
45
|
+
|
|
46
|
+
# 使用 bun build CLI 构建
|
|
47
|
+
output_file="$DIST_DIR/mini-service-$project_name.js"
|
|
48
|
+
|
|
49
|
+
if bun build "$entry_path" \
|
|
50
|
+
--outfile "$output_file" \
|
|
51
|
+
--target bun \
|
|
52
|
+
--minify; then
|
|
53
|
+
echo "✅ $project_name 构建成功 -> $output_file"
|
|
54
|
+
success_count=$((success_count + 1))
|
|
55
|
+
else
|
|
56
|
+
echo "❌ $project_name 构建失败"
|
|
57
|
+
fail_count=$((fail_count + 1))
|
|
58
|
+
fi
|
|
59
|
+
fi
|
|
60
|
+
done
|
|
61
|
+
|
|
62
|
+
if [ -f ./.zscripts/mini-services-start.sh ]; then
|
|
63
|
+
cp ./.zscripts/mini-services-start.sh "$DIST_DIR/mini-services-start.sh"
|
|
64
|
+
chmod +x "$DIST_DIR/mini-services-start.sh"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
echo ""
|
|
68
|
+
echo "🎉 所有任务完成!"
|
|
69
|
+
if [ $success_count -gt 0 ] || [ $fail_count -gt 0 ]; then
|
|
70
|
+
echo "✅ 成功: $success_count 个"
|
|
71
|
+
if [ $fail_count -gt 0 ]; then
|
|
72
|
+
echo "❌ 失败: $fail_count 个"
|
|
73
|
+
fi
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
main
|
|
78
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# 配置项
|
|
4
|
+
ROOT_DIR="/home/z/my-project/mini-services"
|
|
5
|
+
|
|
6
|
+
main() {
|
|
7
|
+
echo "🚀 开始批量安装依赖..."
|
|
8
|
+
|
|
9
|
+
# 检查 rootdir 是否存在
|
|
10
|
+
if [ ! -d "$ROOT_DIR" ]; then
|
|
11
|
+
echo "ℹ️ 目录 $ROOT_DIR 不存在,跳过安装"
|
|
12
|
+
return
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# 统计变量
|
|
16
|
+
success_count=0
|
|
17
|
+
fail_count=0
|
|
18
|
+
failed_projects=""
|
|
19
|
+
|
|
20
|
+
# 遍历 mini-services 目录下的所有文件夹
|
|
21
|
+
for dir in "$ROOT_DIR"/*; do
|
|
22
|
+
# 检查是否是目录且包含 package.json
|
|
23
|
+
if [ -d "$dir" ] && [ -f "$dir/package.json" ]; then
|
|
24
|
+
project_name=$(basename "$dir")
|
|
25
|
+
echo ""
|
|
26
|
+
echo "📦 正在安装依赖: $project_name..."
|
|
27
|
+
|
|
28
|
+
# 进入项目目录并执行 bun install
|
|
29
|
+
if (cd "$dir" && bun install); then
|
|
30
|
+
echo "✅ $project_name 依赖安装成功"
|
|
31
|
+
success_count=$((success_count + 1))
|
|
32
|
+
else
|
|
33
|
+
echo "❌ $project_name 依赖安装失败"
|
|
34
|
+
fail_count=$((fail_count + 1))
|
|
35
|
+
if [ -z "$failed_projects" ]; then
|
|
36
|
+
failed_projects="$project_name"
|
|
37
|
+
else
|
|
38
|
+
failed_projects="$failed_projects $project_name"
|
|
39
|
+
fi
|
|
40
|
+
fi
|
|
41
|
+
fi
|
|
42
|
+
done
|
|
43
|
+
|
|
44
|
+
# 汇总结果
|
|
45
|
+
echo ""
|
|
46
|
+
echo "=================================================="
|
|
47
|
+
if [ $success_count -gt 0 ] || [ $fail_count -gt 0 ]; then
|
|
48
|
+
echo "🎉 安装完成!"
|
|
49
|
+
echo "✅ 成功: $success_count 个"
|
|
50
|
+
if [ $fail_count -gt 0 ]; then
|
|
51
|
+
echo "❌ 失败: $fail_count 个"
|
|
52
|
+
echo ""
|
|
53
|
+
echo "失败的项目:"
|
|
54
|
+
for project in $failed_projects; do
|
|
55
|
+
echo " - $project"
|
|
56
|
+
done
|
|
57
|
+
fi
|
|
58
|
+
else
|
|
59
|
+
echo "ℹ️ 未找到任何包含 package.json 的项目"
|
|
60
|
+
fi
|
|
61
|
+
echo "=================================================="
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
main
|
|
65
|
+
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
# 配置项
|
|
4
|
+
DIST_DIR="./mini-services-dist"
|
|
5
|
+
|
|
6
|
+
# 存储所有子进程的 PID
|
|
7
|
+
pids=""
|
|
8
|
+
|
|
9
|
+
# 清理函数:优雅关闭所有服务
|
|
10
|
+
cleanup() {
|
|
11
|
+
echo ""
|
|
12
|
+
echo "🛑 正在关闭所有服务..."
|
|
13
|
+
|
|
14
|
+
# 发送 SIGTERM 信号给所有子进程
|
|
15
|
+
for pid in $pids; do
|
|
16
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
17
|
+
service_name=$(ps -p "$pid" -o comm= 2>/dev/null || echo "unknown")
|
|
18
|
+
echo " 关闭进程 $pid ($service_name)..."
|
|
19
|
+
kill -TERM "$pid" 2>/dev/null
|
|
20
|
+
fi
|
|
21
|
+
done
|
|
22
|
+
|
|
23
|
+
# 等待所有进程退出(最多等待 5 秒)
|
|
24
|
+
sleep 1
|
|
25
|
+
for pid in $pids; do
|
|
26
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
27
|
+
# 如果还在运行,等待最多 4 秒
|
|
28
|
+
timeout=4
|
|
29
|
+
while [ $timeout -gt 0 ] && kill -0 "$pid" 2>/dev/null; do
|
|
30
|
+
sleep 1
|
|
31
|
+
timeout=$((timeout - 1))
|
|
32
|
+
done
|
|
33
|
+
# 如果仍然在运行,强制关闭
|
|
34
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
35
|
+
echo " 强制关闭进程 $pid..."
|
|
36
|
+
kill -KILL "$pid" 2>/dev/null
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
done
|
|
40
|
+
|
|
41
|
+
echo "✅ 所有服务已关闭"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
main() {
|
|
45
|
+
echo "🚀 开始启动所有 mini services..."
|
|
46
|
+
|
|
47
|
+
# 检查 dist 目录是否存在
|
|
48
|
+
if [ ! -d "$DIST_DIR" ]; then
|
|
49
|
+
echo "ℹ️ 目录 $DIST_DIR 不存在"
|
|
50
|
+
return
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# 查找所有 mini-service-*.js 文件
|
|
54
|
+
service_files=""
|
|
55
|
+
for file in "$DIST_DIR"/mini-service-*.js; do
|
|
56
|
+
if [ -f "$file" ]; then
|
|
57
|
+
if [ -z "$service_files" ]; then
|
|
58
|
+
service_files="$file"
|
|
59
|
+
else
|
|
60
|
+
service_files="$service_files $file"
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
done
|
|
64
|
+
|
|
65
|
+
# 计算服务文件数量
|
|
66
|
+
service_count=0
|
|
67
|
+
for file in $service_files; do
|
|
68
|
+
service_count=$((service_count + 1))
|
|
69
|
+
done
|
|
70
|
+
|
|
71
|
+
if [ $service_count -eq 0 ]; then
|
|
72
|
+
echo "ℹ️ 未找到任何 mini service 文件"
|
|
73
|
+
return
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
echo "📦 找到 $service_count 个服务,开始启动..."
|
|
77
|
+
echo ""
|
|
78
|
+
|
|
79
|
+
# 启动每个服务
|
|
80
|
+
for file in $service_files; do
|
|
81
|
+
service_name=$(basename "$file" .js | sed 's/mini-service-//')
|
|
82
|
+
echo "▶️ 启动服务: $service_name..."
|
|
83
|
+
|
|
84
|
+
# 使用 bun 运行服务(后台运行)
|
|
85
|
+
bun "$file" &
|
|
86
|
+
pid=$!
|
|
87
|
+
if [ -z "$pids" ]; then
|
|
88
|
+
pids="$pid"
|
|
89
|
+
else
|
|
90
|
+
pids="$pids $pid"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# 等待一小段时间检查进程是否成功启动
|
|
94
|
+
sleep 0.5
|
|
95
|
+
if ! kill -0 "$pid" 2>/dev/null; then
|
|
96
|
+
echo "❌ $service_name 启动失败"
|
|
97
|
+
# 从字符串中移除失败的 PID
|
|
98
|
+
pids=$(echo "$pids" | sed "s/\b$pid\b//" | sed 's/ */ /g' | sed 's/^ *//' | sed 's/ *$//')
|
|
99
|
+
else
|
|
100
|
+
echo "✅ $service_name 已启动 (PID: $pid)"
|
|
101
|
+
fi
|
|
102
|
+
done
|
|
103
|
+
|
|
104
|
+
# 计算运行中的服务数量
|
|
105
|
+
running_count=0
|
|
106
|
+
for pid in $pids; do
|
|
107
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
108
|
+
running_count=$((running_count + 1))
|
|
109
|
+
fi
|
|
110
|
+
done
|
|
111
|
+
|
|
112
|
+
echo ""
|
|
113
|
+
echo "🎉 所有服务已启动!共 $running_count 个服务正在运行"
|
|
114
|
+
echo ""
|
|
115
|
+
echo "💡 按 Ctrl+C 停止所有服务"
|
|
116
|
+
echo ""
|
|
117
|
+
|
|
118
|
+
# 等待所有后台进程
|
|
119
|
+
wait
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
main
|
|
123
|
+
|