vendor m3e-canvas 5c83ac6, with the import rewrite scripted
upstream imports through a @/ alias, and this platform already binds @/* to src/apps/officer-web and @/components/* to its own shared components — so an unrewritten import resolves to the WRONG module rather than failing. the rewrite is mechanical and lives in scripts/vendor.sh so a re-vendor produces a readable diff. lib/ai.ts and AiPanel are vendored despite being unwanted: deleting them meant editing vendored code, and Canvas.tsx references them throughout. a faithful copy carrying an unused module beats a doctored one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Executable
+113
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env bash
|
||||
# Re-vendor the M3E Canvas editor from upstream.
|
||||
#
|
||||
# ./scripts/vendor.sh [<git-ref>] default: main
|
||||
#
|
||||
# ── Why a script rather than a copy ──
|
||||
#
|
||||
# The vendored copy is NOT byte-identical to upstream, and it cannot be. Upstream imports through a
|
||||
# `@/` path alias, and this platform already binds `@/*` to `src/apps/officer-web` and
|
||||
# `@/components/*` to its own shared components. Left alone, `import { M3Node } from
|
||||
# "@/components/M3Node"` inside the vendored editor would silently resolve to Officer's components
|
||||
# directory — a wrong module rather than a build error, which is the worst way to be broken.
|
||||
#
|
||||
# So every import is rewritten to a relative path. That transformation is MECHANICAL and lives here,
|
||||
# which is what keeps the copy reviewable: `git diff` after a re-vendor shows upstream's real changes,
|
||||
# because the rewrite produces the same output for the same input every time.
|
||||
#
|
||||
# Nothing else is edited. Officer's own changes live outside `web/vendor/`, reached through
|
||||
# `web/adapter.ts`.
|
||||
set -euo pipefail
|
||||
|
||||
REF="${1:-main}"
|
||||
UPSTREAM="https://github.com/lnkiai/m3e-canvas.git"
|
||||
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
DEST="$HERE/web/vendor"
|
||||
WORK="$(mktemp -d)"
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
|
||||
echo "cloning $UPSTREAM @ $REF"
|
||||
git clone -q --depth 1 --branch "$REF" "$UPSTREAM" "$WORK/src"
|
||||
SHA="$(git -C "$WORK/src" rev-parse HEAD)"
|
||||
WHEN="$(git -C "$WORK/src" log -1 --format=%ad --date=short)"
|
||||
|
||||
rm -rf "$DEST"
|
||||
mkdir -p "$DEST"
|
||||
|
||||
# lib/ and components/ only. `app/` is upstream's Next.js route and is deliberately NOT taken:
|
||||
# app/page.tsx becomes web/vendor/Canvas.tsx below, and app/layout.tsx has no meaning here.
|
||||
cp -r "$WORK/src/lib" "$DEST/lib"
|
||||
cp -r "$WORK/src/components" "$DEST/components"
|
||||
cp "$WORK/src/app/page.tsx" "$DEST/Canvas.tsx"
|
||||
cp "$WORK/src/app/globals.css" "$DEST/globals.css"
|
||||
cp "$WORK/src/LICENSE" "$DEST/LICENSE"
|
||||
|
||||
# lib/ai.ts and components/AiPanel.tsx ARE vendored, despite being the parts Officer least needs.
|
||||
#
|
||||
# The first attempt deleted them — they keep model-provider API keys in localStorage and call the
|
||||
# provider from the browser, which Officer has no use for and would not do that way. But Canvas.tsx
|
||||
# references them in about a dozen places, so deleting meant editing vendored code, and the rule one
|
||||
# paragraph up says not to. A faithful copy that carries an unused module beats a doctored one that
|
||||
# cannot be re-vendored.
|
||||
#
|
||||
# They stay inert: the panel does nothing without a key, and Officer's shell does not surface the
|
||||
# entry point. See ../README.md, "What we do not use".
|
||||
|
||||
# ── the mechanical rewrite ──
|
||||
# `@/lib/x` -> relative path to vendor/lib/x
|
||||
# `@/components/x` -> relative path to vendor/components/x
|
||||
python3 - "$DEST" <<'PY'
|
||||
import os, re, sys
|
||||
dest = sys.argv[1]
|
||||
for root, _, files in os.walk(dest):
|
||||
for name in files:
|
||||
if not name.endswith((".ts", ".tsx")):
|
||||
continue
|
||||
path = os.path.join(root, name)
|
||||
depth = os.path.relpath(root, dest)
|
||||
prefix = "./" if depth == "." else "../" * len(depth.split(os.sep))
|
||||
src = open(path, encoding="utf-8").read()
|
||||
out = re.sub(r'(["\'])@/(lib|components)/', lambda m: f"{m.group(1)}{prefix}{m.group(2)}/", src)
|
||||
if out != src:
|
||||
open(path, "w", encoding="utf-8").write(out)
|
||||
PY
|
||||
|
||||
cat > "$DEST/PROVENANCE.md" <<PROV
|
||||
# Vendored from lnkiai/m3e-canvas
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| upstream | $UPSTREAM |
|
||||
| ref | \`$REF\` |
|
||||
| commit | \`$SHA\` |
|
||||
| dated | $WHEN |
|
||||
| licence | MIT — see \`LICENSE\` beside this file |
|
||||
| vendored | $(date -u +%Y-%m-%d) by \`scripts/vendor.sh\` |
|
||||
|
||||
**Do not edit anything in this directory.** Officer's changes live outside it, reached through
|
||||
\`web/adapter.ts\`. Editing here makes the next \`vendor.sh\` run either clobber the change or
|
||||
produce a diff nobody can read.
|
||||
|
||||
## What was taken, and what was not
|
||||
|
||||
Taken: \`lib/\`, \`components/\`, upstream's \`app/page.tsx\` as \`Canvas.tsx\`, and \`globals.css\`.
|
||||
|
||||
Not taken: \`app/layout.tsx\` — a Next.js route shell with no meaning here.
|
||||
|
||||
\`lib/ai.ts\` and \`components/AiPanel.tsx\` ARE taken even though Officer does not use them. They
|
||||
keep model-provider API keys in \`localStorage\`, which is not how anything here should work — but
|
||||
\`Canvas.tsx\` references them throughout, so removing them would mean editing vendored code. A
|
||||
faithful copy carrying an unused module beats a doctored one that cannot be re-vendored. They are
|
||||
inert without a key, and the shell does not surface them.
|
||||
|
||||
## The one edit \`vendor.sh\` makes
|
||||
|
||||
Every \`@/lib/…\` and \`@/components/…\` import is rewritten to a relative path. This platform already
|
||||
binds \`@/*\` to \`src/apps/officer-web\` and \`@/components/*\` to its own shared components, so an
|
||||
unrewritten import resolves to the WRONG module rather than failing — silent breakage.
|
||||
|
||||
The rewrite is deterministic, so a re-vendor produces a readable diff of upstream's real changes.
|
||||
PROV
|
||||
|
||||
echo "vendored $SHA ($WHEN) -> web/vendor/"
|
||||
echo " $(find "$DEST" -name '*.ts' -o -name '*.tsx' | wc -l) source files"
|
||||
Reference in New Issue
Block a user