fix(scripts): allow the files.ts upload XHR in check-phase10 hygiene

- network rule exempts only the line-anchored upload XHR in admin/src/api/files.ts
- api-listing rule exempts only the exact path admin/src/api/files.ts
- self-test plants an XHR elsewhere and an extra admin/src/api file
This commit is contained in:
2026-10-11 16:08:19 +02:00
parent d2fa195a91
commit 42b5cf887f

View File

@@ -224,7 +224,9 @@ run_self_test() {
done
# The hygiene stage passes on a scratch copy of the tree and fails once a
# raw-HTML directive, a direct fetch or an app name is planted in it.
# raw-HTML directive, a direct fetch, an XMLHttpRequest outside the files.ts
# upload, an app name, a browser-storage call or an extra admin/src/api file
# is planted in it.
local scratch
scratch="$(mktemp -d)"
trap 'rm -rf "$scratch"' RETURN
@@ -240,8 +242,8 @@ run_self_test() {
# Each plant is imported by a scratch test, so only its own rule can fire;
# the refusal must name that rule.
local plant want out
for plant in vhtml fetch appname storage; do
rm -rf "$scratch/admin/src/__plant" "$scratch/admin/tests/__plant.test.ts"
for plant in vhtml fetch appname storage xhr apifile; do
rm -rf "$scratch/admin/src/__plant" "$scratch/admin/tests/__plant.test.ts" "$scratch/admin/src/api/__plant.ts"
mkdir -p "$scratch/admin/src/__plant"
case "$plant" in
vhtml)
@@ -261,6 +263,15 @@ run_self_test() {
printf 'export const keep = (v: string) => localStorage.setItem("token", v)\n' >"$scratch/admin/src/__plant/plant.ts"
want="browser storage"
;;
xhr)
printf 'export const open = () => new XMLHttpRequest()\n' >"$scratch/admin/src/__plant/plant.ts"
want="direct fetch"
;;
apifile)
printf 'export {}\n' >"$scratch/admin/src/api/__plant.ts"
printf "import '../src/api/__plant'\n" >"$scratch/admin/tests/__plant.test.ts"
want="unexpected files in admin/src/api"
;;
esac
[[ -f "$scratch/admin/tests/__plant.test.ts" ]] ||
printf "import '../src/__plant/plant'\n" >"$scratch/admin/tests/__plant.test.ts"
@@ -357,11 +368,14 @@ hygiene_checks() {
grep -vE '^admin/src/components/form/fields/MarkdownField\.vue:[0-9]+:[[:space:]]*v-html="sanitizedHtml"[[:space:]]*$' || true)"
[[ -z "$hits" ]] || fail "raw-HTML directive in admin/src: $hits"
# All HTTP goes through the typed openapi-fetch client.
# Uploads in admin/src/api/files.ts use XMLHttpRequest because only XHR reports upload progress (12.2-04); that XHR sends X-Requested-With (T-12.2-32) and refreshes through client.ts; every other XHR, fetch or axios call is still refused.
hits="$(cd "$tree" && grep -rnE '(^|[^A-Za-z0-9_.])fetch\(|XMLHttpRequest\(|axios' admin/src --include='*.ts' --include='*.vue' 2>/dev/null |
grep -v '^admin/src/api/client.ts:' || true)"
grep -v '^admin/src/api/client.ts:' |
grep -vE '^admin/src/api/files\.ts:[0-9]+:[[:space:]]*const request = new XMLHttpRequest\(\)[[:space:]]*$' || true)"
[[ -z "$hits" ]] || fail "direct fetch outside admin/src/api/client.ts: $hits"
# admin/src/api holds the generated schema, the client and aliases only.
hits="$(cd "$tree" && find admin/src/api -type f ! -name schema.d.ts ! -name client.ts ! -name types.ts 2>/dev/null || true)"
# admin/src/api holds the generated schema, the client, the aliases and the
# FileRoutes adapters (files.ts, 12.2-04) only.
hits="$(cd "$tree" && find admin/src/api -type f ! -name schema.d.ts ! -name client.ts ! -name types.ts ! -path admin/src/api/files.ts 2>/dev/null || true)"
[[ -z "$hits" ]] || fail "unexpected files in admin/src/api: $hits"
hits="$(cd "$tree" && grep -nE '\binterface\b|=\s*\{|:\s*\{' admin/src/api/types.ts 2>/dev/null || true)"
[[ -z "$hits" ]] || fail "admin/src/api/types.ts declares a shape instead of aliasing the generated schema: $hits"