You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
shared/lml-client/src/streaming-url-guard.ts — safeHttpHostname: the same set in two steps (char scan <= 0x20 || 0x7f, then if (url.includes('\\')) return null).
The rejection sets are identical; only the arrangement differs. safeHttpHostname's doc comment names the duplication explicitly and justifies it: "shared/lml-client has no dependency on apps/backend, and importing one in would invert the package graph ... a same-workspace copy of its predicate, not a re-export."
The justification is sound about direction and wrong about necessity. apps/backend/utils/album-metadata-projection.ts already imports from the shared package (import { isSpotifyUrl, isAppleMusicUrl } from '@wxyc/lml-client';). The graph runs apps/backend -> shared/lml-client, so the primitive can live in shared and be consumed by apps/backend without inverting anything.
The cost of the copy is not hypothetical: a third copy of the same bar landed the same night in Python (library-metadata-lookup/release/host_matching.py::is_well_formed_web_url) and dropped the 0x5c leg (WXYC/library-metadata-lookup#1298). Every additional hand-maintained copy widens the surface a cross-language parity corpus has to pin.
Desired end state
One exported primitive — the character scan — in shared/lml-client (or a small neutral shared/ module if that package's public surface shouldn't grow). hasWireUrlParserDifferential delegates to it; safeHttpHostname calls it instead of open-coding the two-step. Both call sites keep their own surrounding behavior:
wireUrl still trims before scanning and returns the trimmed original;
safeHttpHostname still does not trim, and still returns the lowercased hostname;
This is behavior-preserving by construction: the merged union of safeHttpHostname's two steps is exactly hasWireUrlParserDifferential's single predicate.
Where
shared/lml-client/src/streaming-url-guard.ts — safeHttpHostname; export the extracted scan from shared/lml-client/src/index.ts.
apps/backend/utils/album-metadata-projection.ts — hasWireUrlParserDifferential (keep the exported name; it has its own callers and its own doc comment explaining the differential).
Tests: tests/unit/shared/lml-client/streaming-url-guard.test.ts, and the album-metadata-projection coverage of wireUrl/hasWireUrlParserDifferential.
Keep the per-call-site trim/no-trim difference. wireUrl trims because it is an output filter; safeHttpHostname does not because it is a predicate over the persisted string.
Don't move wireUrl itself — its doc comment is the source of truth for the wire contract and it depends on apps/backend concerns.
Acceptance criteria
One implementation of the <= 0x20 || 0x7f || 0x5c scan in the repo; both call sites delegate
hasWireUrlParserDifferential keeps its exported name and doc comment
isSpotifyUrl/isAppleMusicUrl characterization tests unchanged and green
npm run test:unit, typecheck, lint, format:check green
Problem
After #2351, Backend-Service has two byte-equivalent implementations of the same character bar, in two workspaces:
apps/backend/utils/album-metadata-projection.ts—hasWireUrlParserDifferential:if (code <= 0x20 || code === 0x7f || code === 0x5c) return true;shared/lml-client/src/streaming-url-guard.ts—safeHttpHostname: the same set in two steps (char scan<= 0x20 || 0x7f, thenif (url.includes('\\')) return null).The rejection sets are identical; only the arrangement differs.
safeHttpHostname's doc comment names the duplication explicitly and justifies it: "shared/lml-clienthas no dependency onapps/backend, and importing one in would invert the package graph ... a same-workspace copy of its predicate, not a re-export."The justification is sound about direction and wrong about necessity.
apps/backend/utils/album-metadata-projection.tsalready imports from the shared package (import { isSpotifyUrl, isAppleMusicUrl } from '@wxyc/lml-client';). The graph runs apps/backend -> shared/lml-client, so the primitive can live insharedand be consumed byapps/backendwithout inverting anything.The cost of the copy is not hypothetical: a third copy of the same bar landed the same night in Python (
library-metadata-lookup/release/host_matching.py::is_well_formed_web_url) and dropped the0x5cleg (WXYC/library-metadata-lookup#1298). Every additional hand-maintained copy widens the surface a cross-language parity corpus has to pin.Desired end state
One exported primitive — the character scan — in
shared/lml-client(or a small neutralshared/module if that package's public surface shouldn't grow).hasWireUrlParserDifferentialdelegates to it;safeHttpHostnamecalls it instead of open-coding the two-step. Both call sites keep their own surrounding behavior:wireUrlstill trims before scanning and returns the trimmed original;safeHttpHostnamestill does not trim, and still returns the lowercased hostname;safeHostname(spotify/apple) stays as it is — its looser bar is load-bearing and pinned by Extend sanitizeLookupStreamingUrls to all five streaming URL fields #2351's characterization tests.This is behavior-preserving by construction: the merged union of
safeHttpHostname's two steps is exactlyhasWireUrlParserDifferential's single predicate.Where
shared/lml-client/src/streaming-url-guard.ts—safeHttpHostname; export the extracted scan fromshared/lml-client/src/index.ts.apps/backend/utils/album-metadata-projection.ts—hasWireUrlParserDifferential(keep the exported name; it has its own callers and its own doc comment explaining the differential).tests/unit/shared/lml-client/streaming-url-guard.test.ts, and the album-metadata-projection coverage ofwireUrl/hasWireUrlParserDifferential.Constraints
isSpotifyUrl/isAppleMusicUrlmust stay byte-identical — Extend sanitizeLookupStreamingUrls to all five streaming URL fields #2351's characterization tests are the guard; do not route them through the extracted scan.wireUrltrims because it is an output filter;safeHttpHostnamedoes not because it is a predicate over the persisted string.wireUrlitself — its doc comment is the source of truth for the wire contract and it depends onapps/backendconcerns.Acceptance criteria
<= 0x20 || 0x7f || 0x5cscan in the repo; both call sites delegatehasWireUrlParserDifferentialkeeps its exported name and doc commentisSpotifyUrl/isAppleMusicUrlcharacterization tests unchanged and greennpm run test:unit,typecheck,lint,format:checkgreenRelated
safeHttpHostnameand documented it as a deliberate same-workspace copy0x5c