docs: add canonical svglide ppe setup

This commit is contained in:
songtianyi.theo
2026-07-09 15:29:58 +08:00
parent 1cac7ddf8f
commit 1a52644461
3 changed files with 289 additions and 2 deletions

258
scripts/dev-svglide-ppe-env.sh Executable file
View File

@@ -0,0 +1,258 @@
#!/usr/bin/env sh
RULE_GROUP="lark-cli"
CANONICAL_RULE_NAME="lark-cli-openapi-ppe-svg-slides"
PROXY_HOST="${LARK_CLI_PROXY_HOST:-127.0.0.1}"
PROXY_PORT="${LARK_CLI_PROXY_PORT:-8899}"
# Keep this list intentionally small and explicit. These were previous local
# SVGlide/PPE rule names that can route generated SVG Slides to the wrong lane.
# Do not store them in a whitespace-split variable: this script is meant to be
# sourced by zsh as well as POSIX shells, and zsh does not split scalars by
# whitespace unless SH_WORD_SPLIT is enabled.
fail() {
printf '%s\n' "[svglide-ppe] $*" >&2
return 1 2>/dev/null || exit 1
}
info() {
printf '%s\n' "[svglide-ppe] $*" >&2
}
usage() {
cat <<USAGE
Usage:
. ./scripts/dev-svglide-ppe-env.sh pre [--host <host>] [--port <port>] [--no-clear]
. ./scripts/dev-svglide-ppe-env.sh off
./scripts/dev-svglide-ppe-env.sh rules
Notes:
- Use "source" or "." for pre/off so proxy env vars apply to the current shell.
- pre writes the canonical Whistle rule "${CANONICAL_RULE_NAME}".
- pre also clears known legacy SVGlide/PPE rule names unless --no-clear is passed.
- This is dev-only PPE plumbing, not production publish behavior.
USAGE
}
is_sourced() {
if [ -n "${BASH_VERSION-}" ]; then
[ "${BASH_SOURCE[0]}" != "$0" ]
return
fi
if [ -n "${ZSH_VERSION-}" ]; then
case "${ZSH_EVAL_CONTEXT-}" in
*:file:*) return 0 ;;
*) return 1 ;;
esac
fi
return 1
}
pick_whistle_cmd() {
if command -v w2 >/dev/null 2>&1; then
printf '%s\n' "w2"
return 0
fi
if command -v whistle >/dev/null 2>&1; then
printf '%s\n' "whistle"
return 0
fi
info "missing required command: w2 (or whistle)"
info "install: npm install -g whistle"
info "then: w2 start && w2 ca"
fail "missing required command: w2 (or whistle)"
}
ensure_whistle_running() {
wcmd="$1"
whistle_status="$("$wcmd" status 2>&1 || true)"
case "$whistle_status" in
*"No running Whistle instances"*)
info "Whistle is not running, starting it now..."
"$wcmd" start >/dev/null 2>&1 || fail "failed to start Whistle"
;;
esac
}
canonical_rules() {
cat <<'RULES'
/^https:\/\/open\.feishu\.cn\/(.*)$/ https://open.feishu-pre.cn/$1
https://open.feishu.cn/ reqHeaders://Env=Pre_release
https://open.feishu.cn/ reqHeaders://x-tt-env=ppe_svg_slides
https://open.feishu.cn/ reqHeaders://x-use-ppe=1
https://open.feishu-pre.cn/ reqHeaders://Env=Pre_release
https://open.feishu-pre.cn/ reqHeaders://x-tt-env=ppe_svg_slides
https://open.feishu-pre.cn/ reqHeaders://x-use-ppe=1
/^https:\/\/accounts\.feishu\.cn\/(.*)$/ https://accounts.feishu-pre.cn/$1
RULES
}
disabled_rules() {
rule_name="$1"
cat <<RULES
# disabled by scripts/dev-svglide-ppe-env.sh
# canonical SVGlide PPE rule: ${CANONICAL_RULE_NAME}
# cleared legacy rule: ${rule_name}
RULES
}
write_rule_js() {
output="$1"
rule_name="$2"
rules="$3"
RULE_NAME="$rule_name" RULE_GROUP="$RULE_GROUP" RULES="$rules" node >"$output" <<'NODE'
const rule = {
name: process.env.RULE_NAME,
groupName: process.env.RULE_GROUP,
rules: process.env.RULES || "",
};
process.stdout.write(`module.exports = function (callback) {
callback(${JSON.stringify(rule, null, 2)});
};
`);
NODE
}
apply_rule() {
wcmd="$1"
rule_name="$2"
rules="$3"
tmp_js="$(mktemp "${TMPDIR:-/tmp}/svglide-ppe-rule.XXXXXX.js")" || fail "failed to create temp file"
write_rule_js "$tmp_js" "$rule_name" "$rules"
"$wcmd" add "$tmp_js" --force >/dev/null 2>&1 || {
rm -f "$tmp_js"
fail "failed to apply Whistle rule: ${rule_name}"
}
rm -f "$tmp_js"
}
clear_legacy_rules() {
wcmd="$1"
clear_legacy_rule "$wcmd" "lark-cli-openapi-env-switch"
clear_legacy_rule "$wcmd" "lark-cli-openapi-ppe-svglide"
clear_legacy_rule "$wcmd" "lark-cli-openapi-ppe-pure-svg"
clear_legacy_rule "$wcmd" "lark-cli-openapi-ppe-pure-svg-control"
clear_legacy_rule "$wcmd" "lark-cli-openapi-ppe-svg-slides-header-only"
clear_legacy_rule "$wcmd" "lark-cli-pre-ppe-svglide-combined"
clear_legacy_rule "$wcmd" "lark-cli-ppe-pure-svg"
clear_legacy_rule "$wcmd" "lark-cli-ppe-svglide"
clear_legacy_rule "$wcmd" "lark-cli-prod-host-pre-env-ppe-header"
clear_legacy_rule "$wcmd" "lark-cli-prod-ppe-svglide-header-only"
}
clear_legacy_rule() {
wcmd="$1"
rule_name="$2"
[ "$rule_name" = "$CANONICAL_RULE_NAME" ] && return 0
remove_rule "$wcmd" "$rule_name" || apply_rule "$wcmd" "$rule_name" "$(disabled_rules "$rule_name")"
info "cleared legacy Whistle rule: ${rule_name}"
}
remove_rule() {
_wcmd="$1"
rule_name="$2"
if ! command -v curl >/dev/null 2>&1; then
return 1
fi
curl -fsS \
-X POST \
-H 'Content-Type: application/json' \
--data "{\"name\":\"${rule_name}\"}" \
"http://${PROXY_HOST}:${PROXY_PORT}/cgi-bin/rules/remove" >/dev/null 2>&1
}
apply_proxy_env() {
proxy_url="http://${PROXY_HOST}:${PROXY_PORT}"
export HTTPS_PROXY="$proxy_url"
export https_proxy="$proxy_url"
export HTTP_PROXY="$proxy_url"
export http_proxy="$proxy_url"
export ALL_PROXY="$proxy_url"
export all_proxy="$proxy_url"
unset LARK_CLI_NO_PROXY
info "proxy env enabled: ${proxy_url}"
}
clear_proxy_env() {
unset HTTPS_PROXY https_proxy HTTP_PROXY http_proxy ALL_PROXY all_proxy
unset LARK_CLI_NO_PROXY
info "proxy env cleared"
}
mode="${1:-}"
[ "$mode" = "" ] && {
usage
return 0 2>/dev/null || exit 0
}
shift || true
clear_legacy="1"
while [ "$#" -gt 0 ]; do
case "$1" in
--host)
[ "$#" -ge 2 ] || fail "--host requires a value"
PROXY_HOST="$2"
shift 2
;;
--port)
[ "$#" -ge 2 ] || fail "--port requires a value"
PROXY_PORT="$2"
shift 2
;;
--no-clear)
clear_legacy="0"
shift
;;
-h|--help)
usage
return 0 2>/dev/null || exit 0
;;
*)
fail "unknown arg: $1"
;;
esac
done
case "$mode" in
rules)
canonical_rules
;;
pre)
wcmd="$(pick_whistle_cmd)"
ensure_whistle_running "$wcmd"
if [ "$clear_legacy" = "1" ]; then
clear_legacy_rules "$wcmd"
fi
apply_rule "$wcmd" "$CANONICAL_RULE_NAME" "$(canonical_rules)"
info "applied canonical Whistle rule: ${CANONICAL_RULE_NAME}"
if is_sourced; then
apply_proxy_env
else
info "Whistle rule updated, but current shell env is unchanged."
info "run with source: . ./scripts/dev-svglide-ppe-env.sh pre"
fi
info "active PPE lane: ppe_svg_slides"
;;
off|cancel)
wcmd="$(pick_whistle_cmd)"
ensure_whistle_running "$wcmd"
clear_legacy_rules "$wcmd"
apply_rule "$wcmd" "$CANONICAL_RULE_NAME" "$(disabled_rules "$CANONICAL_RULE_NAME")"
info "disabled canonical Whistle rule: ${CANONICAL_RULE_NAME}"
if is_sourced; then
clear_proxy_env
else
info "Whistle rules disabled, but current shell env is unchanged."
info "run with source: . ./scripts/dev-svglide-ppe-env.sh off"
fi
;;
-h|--help|help)
usage
;;
*)
fail "invalid mode: ${mode}; expected pre|off|rules"
;;
esac