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
Because this pure string utility is housed inside server/services/youtubeImport.js (an import service for Google Takeout ZIP files), server/services/youtubeSync.js:38, server/services/youtubeIngest.js:55, and even the test server/lib/youtubeUrl.mirror.test.js:18 all import across service boundaries from services/youtubeImport.js. server/lib/ importing from server/services/ violates the core dependency rule that libraries must not depend on services.
server/services/youtubeIngest.js:70-71 declares YOUTUBE_INGEST_URL_RE, which is duplicated verbatim in client/src/lib/youtubeUrl.js:15-16 as SINGLE_VIDEO_RE.
server/services/trackYoutubeImport.js:29 and server/routes/tracks.js:105 declare an older, drifted regex: YOUTUBE_URL_RE = /^https?:\/\/(www\.|m\.)?(youtube\.com\/watch\?[^\s#]*\bv=[\w-]{6,}|youtu\.be\/[\w-]{6,})/i;
This pattern rejects music.youtube.com, shorts, live, and embed URLs. A user pasting a YouTube Music or YouTube Shorts link into Music Video track import is rejected with 400 YOUTUBE_URL_INVALID (Not a recognized YouTube URL), even though yt-dlp supports audio extraction from those URLs and the Takeout and Ingest pipelines accept them.
client/src/lib/youtubeUrl.js:19-26 reimplements youtubeVideoId(url) with identical regexes to youtubeVideoIdFromUrl.
Trigger
A user attempts to import an audio track into Music Video (POST /api/tracks/import/youtube) using a music.youtube.com/watch?v=... link or a youtube.com/shorts/... link.
Developers maintaining URL parsing regexes must update duplicate patterns across multiple files, risking further divergence.
Impact
Users cannot import tracks from YouTube Music or Shorts into the music library. Furthermore, server/lib/ tests import from server/services/, introducing fragile coupling.
Export youtubeVideoIdFromUrl(url) (with youtubeVideoId alias matching client naming).
Export isYoutubeVideoUrl(url).
Export assertYoutubeVideoUrl(url).
Re-export server/lib/youtubeUrl.js in server/lib/index.js and add a catalog entry in server/lib/README.md.
Update server/services/youtubeImport.js to re-export youtubeVideoIdFromUrl from ../lib/youtubeUrl.js for backward compatibility.
Update server/services/youtubeIngest.js, server/services/youtubeSync.js, server/services/trackYoutubeImport.js, and server/routes/tracks.js to import URL regexes and validators from ../lib/youtubeUrl.js.
Update server/lib/youtubeUrl.mirror.test.js to test server/lib/youtubeUrl.js against client/src/lib/youtubeUrl.js, removing the illegal server/lib -> server/services import.
Rejected alternative: Keeping the regexes in youtubeIngest.js and re-exporting from there was rejected because pure regexes and string parsers belong in server/lib/ and should not force importers to pull in the 881-line ingest service.
Acceptance Criteria
server/lib/youtubeUrl.js is created, re-exported in server/lib/index.js, and documented in server/lib/README.md.
trackYoutubeImport.js and routes/tracks.js accept music.youtube.com, shorts, live, and embed URLs.
youtubeImport.js, youtubeIngest.js, and youtubeSync.js import video ID extraction from server/lib/youtubeUrl.js.
server/lib/youtubeUrl.mirror.test.js has no imports from server/services/.
All existing test suites in server/lib/youtubeUrl.mirror.test.js, trackYoutubeImport.test.js, youtubeImport.test.js, and youtubeIngest.test.js pass.
Problem
YouTube single-video URL validation and video ID extraction are duplicated across 5 files with copy-paste drift and architectural layering violations:
server/services/youtubeImport.js:46-57definesyoutubeVideoIdFromUrl(url):server/services/youtubeImport.js(an import service for Google Takeout ZIP files),server/services/youtubeSync.js:38,server/services/youtubeIngest.js:55, and even the testserver/lib/youtubeUrl.mirror.test.js:18all import across service boundaries fromservices/youtubeImport.js.server/lib/importing fromserver/services/violates the core dependency rule that libraries must not depend on services.server/services/youtubeIngest.js:70-71declaresYOUTUBE_INGEST_URL_RE, which is duplicated verbatim inclient/src/lib/youtubeUrl.js:15-16asSINGLE_VIDEO_RE.server/services/trackYoutubeImport.js:29andserver/routes/tracks.js:105declare an older, drifted regex:YOUTUBE_URL_RE = /^https?:\/\/(www\.|m\.)?(youtube\.com\/watch\?[^\s#]*\bv=[\w-]{6,}|youtu\.be\/[\w-]{6,})/i;This pattern rejects
music.youtube.com,shorts,live, andembedURLs. A user pasting a YouTube Music or YouTube Shorts link into Music Video track import is rejected with400 YOUTUBE_URL_INVALID(Not a recognized YouTube URL), even though yt-dlp supports audio extraction from those URLs and the Takeout and Ingest pipelines accept them.client/src/lib/youtubeUrl.js:19-26reimplementsyoutubeVideoId(url)with identical regexes toyoutubeVideoIdFromUrl.Trigger
POST /api/tracks/import/youtube) using amusic.youtube.com/watch?v=...link or ayoutube.com/shorts/...link.Impact
Users cannot import tracks from YouTube Music or Shorts into the music library. Furthermore,
server/lib/tests import fromserver/services/, introducing fragile coupling.Fix
server/lib/youtubeUrl.js:YOUTUBE_VIDEO_URL_RE:/^https?:\/\/(www\.|m\.|music\.)?(youtube\.com\/(watch\?[^\s#]*\bv=[\w-]{6,}|shorts\/[\w-]{6,}|live\/[\w-]{6,}|embed\/[\w-]{6,})|youtu\.be\/[\w-]{6,})/iyoutubeVideoIdFromUrl(url)(withyoutubeVideoIdalias matching client naming).isYoutubeVideoUrl(url).assertYoutubeVideoUrl(url).server/lib/youtubeUrl.jsinserver/lib/index.jsand add a catalog entry inserver/lib/README.md.server/services/youtubeImport.jsto re-exportyoutubeVideoIdFromUrlfrom../lib/youtubeUrl.jsfor backward compatibility.server/services/youtubeIngest.js,server/services/youtubeSync.js,server/services/trackYoutubeImport.js, andserver/routes/tracks.jsto import URL regexes and validators from../lib/youtubeUrl.js.server/lib/youtubeUrl.mirror.test.jsto testserver/lib/youtubeUrl.jsagainstclient/src/lib/youtubeUrl.js, removing the illegalserver/lib->server/servicesimport.youtubeIngest.jsand re-exporting from there was rejected because pure regexes and string parsers belong inserver/lib/and should not force importers to pull in the 881-line ingest service.Acceptance Criteria
server/lib/youtubeUrl.jsis created, re-exported inserver/lib/index.js, and documented inserver/lib/README.md.trackYoutubeImport.jsandroutes/tracks.jsacceptmusic.youtube.com,shorts,live, andembedURLs.youtubeImport.js,youtubeIngest.js, andyoutubeSync.jsimport video ID extraction fromserver/lib/youtubeUrl.js.server/lib/youtubeUrl.mirror.test.jshas no imports fromserver/services/.server/lib/youtubeUrl.mirror.test.js,trackYoutubeImport.test.js,youtubeImport.test.js, andyoutubeIngest.test.jspass.