fix(site-import): report asset references the archive cannot satisfy - #349
Open
mostafasadeghidev wants to merge 1 commit into
Open
fix(site-import): report asset references the archive cannot satisfy#349mostafasadeghidev wants to merge 1 commit into
mostafasadeghidev wants to merge 1 commit into
Conversation
An `<img src>` or CSS `url()` pointing at a file the archive does not contain resolved to null and was silently left alone — the page imported with a broken image and nothing in the import log said so. The user found out by opening the published site. Two changes: - On an exact-key miss, compare the path punctuation-insensitively against the archive. Exporters do not always agree with themselves about filenames: a Webflow export stores `101-&Berlin-Office-Us+ Coworking.webp` and references it from the HTML as `101-Berlin-Office-Us-Coworking.webp`. The match must be UNIQUE — two files differing only in punctuation are two different files, and guessing would put the wrong image on the page. - Whatever still does not resolve emits an `unresolved-asset` warning naming the path, once per path however many pages reference it. Only references whose extension maps to an uploadable media MIME are reported; anchors to extensionless routes and pages outside the archive are normal and would bury the real misses. The import log shows the first 12 warnings, so it now orders the kinds that name a missing file ahead of the CSS interpretation notes. The four URL normalisers all needed the same four things — file map, asset map, warnings, and the new lookup index — so they take one resolver instead of passing the pieces around individually. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mostafasadeghidev
marked this pull request as ready for review
August 7, 2026 00:03
mostafasadeghidev
added a commit
to mostafasadeghidev/Instatic
that referenced
this pull request
Aug 9, 2026
Brings in six upstream commits — collaborative-persistence and deterministic publishing, HEAD answered like GET on published pages, runtime script diagnostics, context-menu and data-token polish, the Selectors panel Used filter, and floating panels clearing docked sidebars. One of ours is now redundant and is dropped. Upstream's `e9e99dff` solves the opaque publish failure that CoreBunch#358 solved, and solves it better: its message carries `path:line:column`, mine carried only the diagnostic text. Its `RuntimeScriptBuildError` replaces `PublishRuntimeBuildError`, and both of my files are deleted rather than kept beside it. Three conflicts, all in the publish path or its tests: - `publishSite.ts` and `handlers/cms/publish.ts` — the same fix from two sides. Took upstream's wholesale and re-applied only the stale-plugin-asset sweep (CoreBunch#359), which upstream does not have. - `tables.test.ts` — not a contested edit at all: both sides had added an independent suite to one file (ours `created_by_plugin_id`, theirs `route_base`). Split into two describes with their own preamble; all ten pass. Two of our own gates needed the fix, not the exception: - `siteImport/types.ts` sat 2 lines over the 700-line ceiling because the file was already at 696 upstream and CoreBunch#349 added a six-line doc comment. Tightened our own prose rather than raising the ceiling or extracting a single union member into a module of its own. - The ContentPage bundle cap is raised 90 → 92 KB on this fork only, with the reason recorded in the budget entry: the stack layers twelve pending features whose shared imports land in that chunk, and each is inside 90 KB on its own branch. One test asserted the behaviour CoreBunch#359 deliberately changed — that an upgrade deletes the old version's directory. Updated to assert the new contract, with the reason, since that assertion is exactly what broke live sites. Verified: `bun run build` clean, `tsc -b` clean. Full suite compared against a clean upstream-main worktree — 327 failures there, and after these fixes the only remaining difference is environment flake (`EBUSY` on the Windows temp-db teardown, which hits upstream too). Zero architecture gates added. Both plugins typecheck and pass against the merged engine.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Site Import now says when an asset reference doesn't resolve, and matches a few more of them that should have resolved all along.
.and/removed.unresolved-assetwarning for whatever still doesn't resolve — naming the path, once per path however many pages reference it.Why
An
<img src>or a CSSurl()pointing at a file the archive doesn't contain resolved tonullinresolveAndRecordand was left alone. That's the right rewrite behaviour — dropping the element would be worse — but nothing recorded it. The page imported with a broken image and the import log said the import succeeded. The user finds out by opening the published site.The fallback exists because exporters don't always agree with themselves about filenames. A real Webflow static export stores:
and references it from three different pages as:
The
&is gone and+became-. The bytes are right there in the zip; only the punctuation disagrees. Exact-key matching imports that page with a broken image through no fault of the archive's owner.How
resolveFileMapKeytries the exact key, then a lazily built index of every FileMap key in normalised form. The fallback match must be unique — two files that differ only in punctuation are two different files, and picking one would silently put the wrong image on the page, which is worse than the broken reference. Ambiguity and genuine absence fall through to the same warning.isImportUploadableMimeType(guessMimeType(path))gates the warning, so<a href="/contact">and a link to a page living outside the archive stay quiet — a wall of warnings about those would bury the images that really are gone.One refactor came with it
The four URL normalisers (node props, CSS bags, raw CSS text,
@font-face) each threadedfileMap+assetMapdown toresolveAndRecord, and this change needed two more per-import values in the same places (the warning sink and the lookup index). Rather than grow every signature to four trailing parameters, they now take oneAssetResolver. Same call graph, fewer parameters.User impact
Additive. Every reference that resolved before still resolves to the same key; the fallback only runs where the old code was about to give up. A site with no missing assets sees no new warnings.
Verification
Five new tests in
src/__tests__/siteImport/assetPlan.test.ts, including the exact filename pair above:Full-suite note:
bun teston this Windows machine reports 302 pre-existing failures onorigin/mainunmodified (parallel temp-DB / port contention in the server suites). This branch reports the same 302 with 5 additional passing tests.