refactor(lint): consolidate asset-src placeholder skip into a shared predicate (#2894)

* refactor(lint): route asset-src skips through a shared isUnresolvedAssetPlaceholder predicate

Follow-up to the templating-token fix. The __UPPER__ + templating-token skip was
copy-pasted across the asset-src sites and had drifted: two non-lint sites carried only
the __UPPER__ half, and htmlCompiler's comment still claimed it "matches lint's skip"
after lint's skip became a superset. Extract one isUnresolvedAssetPlaceholder(rawSrc) in
@hyperframes/parsers/asset-resolution (both placeholder shapes, checked on the raw value)
and route every site through it: the four project.ts lint sites, hevcPreviewLint, and the
two previously-missed post-substitution sites (studio-server mediaCodecMap, producer
htmlCompiler). Remote/inline handling stays per-site (audio uses a narrower check).
Behavior-preserving for the lint sites (full suite green); the two non-lint sites are
post-substitution so they don't false-positive today, but now share one definition and
can't drift again. Adds unit tests for the predicate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(parsers): refresh hasUnresolvedTemplatingToken aside for the shared predicate

The parenthetical said the __UPPER__ shape keeps its own inline check at each call
site; this branch folded it into isUnresolvedAssetPlaceholder, so point there instead.
Addresses review nit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Somansh Reddy
2026-07-30 14:52:10 -07:00
committed by GitHub
co-authored by Claude Opus 4.8
parent b813b17345
commit 5a6e4b1a8f
6 changed files with 71 additions and 22 deletions
@@ -4,6 +4,7 @@ import { rewriteAssetPath } from "@hyperframes/parsers/asset-paths";
import {
cleanAssetUrl,
isRemoteOrInlineUrl,
isUnresolvedAssetPlaceholder,
maskNonScannableRanges,
resolveLocalAssetCandidates,
} from "@hyperframes/parsers/asset-resolution";
@@ -228,9 +229,11 @@ function collectLocalVideoAssets(
const re = new RegExp(VIDEO_SRC_RE.source, VIDEO_SRC_RE.flags);
let match: RegExpExecArray | null;
while ((match = re.exec(scannable)) !== null) {
const src = cleanAssetUrl(match[1] ?? "");
const rawSrc = match[1] ?? "";
// Placeholder check runs on the RAW value: cleanAssetUrl() splits on ?/# and would chop inside a ${...} token.
if (isUnresolvedAssetPlaceholder(rawSrc)) continue;
const src = cleanAssetUrl(rawSrc);
if (!src || isRemoteOrInlineUrl(src)) continue;
if (/^__[A-Z_]+__$/.test(src)) continue;
const rootRelativeSrc = compSrcPath ? rewriteAssetPath(compSrcPath, src) : src;
const resolved = resolveExistingLocalAsset(projectDir, rootRelativeSrc);
if (!resolved) continue;