Files
raisfast/scripts/gen-plugin-sdk.sh

145 lines
4.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
TSC="${TSC:-}"
if [ -z "$TSC" ]; then
for candidate in \
"$ROOT_DIR/frontend/web/node_modules/.bin/tsc" \
"$ROOT_DIR/frontend/sdk/node_modules/.bin/tsc" \
"$ROOT_DIR/node_modules/.bin/tsc"; do
if [ -x "$candidate" ]; then
TSC="$candidate"
break
fi
done
fi
if [ -z "$TSC" ]; then
echo "error: tsc not found. Install typescript or set TSC=/path/to/tsc"
exit 1
fi
# ── 1. 校验:JS host 函数 vs TS SDK ──
JS_HOST="$ROOT_DIR/crates/core/src/plugins/js_host.rs"
TS_SDK="$ROOT_DIR/plugin-sdk/js/js_plugin_v1.ts"
CONSTANTS="$ROOT_DIR/crates/core/src/constants.rs"
# 从 js_host.rs 提取 host.set("functionName", ...) 的函数名
js_host_fns=$(grep -oE 'host\.set\("([a-zA-Z]+)"' "$JS_HOST" | sed 's/host\.set("//;s/"//' | sort -u)
# 从 TS SDK 提取 RaisFastHost.functionName 调用
ts_sdk_fns=$(grep -oE 'RaisFastHost\.([a-zA-Z]+)\(' "$TS_SDK" | sed 's/RaisFastHost\.//;s/(//' | sort -u)
# 从 constants.rs 提取全局名
global_name=$(grep 'PLUGIN_HOST_GLOBAL' "$CONSTANTS" | grep -oE '"([^"]+)"' | sed 's/"//g')
# 从 TS SDK 提取 declare const 行
ts_global_name=$(grep -oE 'declare const ([A-Za-z]+):' "$TS_SDK" | sed 's/declare const //;s/://')
echo "Checking JS host ($JS_HOST) vs TS SDK ($TS_SDK) ..."
errors=0
# 检查全局名一致性
if [ "$global_name" != "$ts_global_name" ]; then
echo " error: global name mismatch: constants.rs='$global_name', ts_sdk='$ts_global_name'"
errors=$((errors + 1))
else
echo " ok: global name = $global_name"
fi
# 检查 Rust 端有但 TS 端没有的函数
missing_in_ts=""
for fn in $js_host_fns; do
if ! echo "$ts_sdk_fns" | grep -qx "$fn"; then
missing_in_ts="$missing_in_ts $fn"
fi
done
if [ -n "$missing_in_ts" ]; then
echo " error: functions in js_host.rs but NOT in TS SDK:$missing_in_ts"
errors=$((errors + 1))
fi
# 检查 TS 端有但 Rust 端没有的函数
missing_in_rs=""
for fn in $ts_sdk_fns; do
if ! echo "$js_host_fns" | grep -qx "$fn"; then
missing_in_rs="$missing_in_rs $fn"
fi
done
if [ -n "$missing_in_rs" ]; then
echo " error: functions in TS SDK but NOT in js_host.rs:$missing_in_rs"
errors=$((errors + 1))
fi
host_fn_count=$(echo "$js_host_fns" | wc -l | tr -d ' ')
sdk_fn_count=$(echo "$ts_sdk_fns" | wc -l | tr -d ' ')
echo " js_host.rs: $host_fn_count functions, TS SDK calls: $sdk_fn_count unique"
# ── 2. 校验:Lua SDK vs JS host 函数 ──
LUA_SDK="$ROOT_DIR/plugin-sdk/lua/lua_plugin_v1.lua"
# 从 Lua SDK 提取全局名 (找 Host.jsonEncode 模式)
lua_global_name=$(grep -o '[A-Za-z]*\.jsonEncode' "$LUA_SDK" | head -1 | sed 's/\.jsonEncode//')
# 提取 GlobalName.function( 调用(任意位置)
lua_sdk_fns=$(grep -o "${lua_global_name}"'\.[a-zA-Z]*(' "$LUA_SDK" | sed "s/${lua_global_name}//" | sed 's/^\.//' | sed 's/($//' | sort -u)
echo ""
echo "Checking Lua SDK ($LUA_SDK) ..."
if [ "$global_name" != "$lua_global_name" ]; then
echo " error: global name mismatch: constants.rs='$global_name', lua_sdk='$lua_global_name'"
errors=$((errors + 1))
else
echo " ok: global name = $lua_global_name"
fi
# Lua 可以调用 Host 上没有直接注册的函数(jsonEncode/jsonDecode 是 Lua-only),
# 但 Host 上注册的函数不应该在 Lua SDK 中缺失
missing_in_lua=""
for fn in $js_host_fns; do
if ! echo "$lua_sdk_fns" | grep -qx "$fn"; then
missing_in_lua="$missing_in_lua $fn"
fi
done
if [ -n "$missing_in_lua" ]; then
echo " warn: functions in js_host.rs but NOT in Lua SDK:$missing_in_lua"
fi
lua_fn_count=$(echo "$lua_sdk_fns" | wc -l | tr -d ' ')
echo " Lua SDK calls: $lua_fn_count unique"
# ── 3. 生成 ──
if [ $errors -gt 0 ]; then
echo ""
echo "error: $errors check(s) failed. Fix the mismatches above before generating."
exit 1
fi
echo ""
echo "All checks passed. Generating ..."
SDK_DIR="$ROOT_DIR/plugin-sdk/js"
echo "Compiling js_plugin_v1.ts → .js + .d.ts ..."
rm -rf "$SDK_DIR/dist"
"$TSC" --project "$SDK_DIR/tsconfig.json"
cp "$SDK_DIR/dist/js_plugin_v1.js" "$SDK_DIR/js_plugin_v1.js"
echo " → plugin-sdk/js/js_plugin_v1.js"
for dir in "$ROOT_DIR"/extensions/plugins/*/; do
cp "$SDK_DIR/dist/js_plugin_v1.d.ts" "${dir}sdk.d.ts"
echo " → ${dir}sdk.d.ts"
done
rm -rf "$SDK_DIR/dist"
echo "done"