Skip to content

Extract canonical server/lib/youtubeUrl.js to eliminate duplicated YouTube regexes, URL parsers, and cross-layer imports #6014

Description

@atomantic

Problem

YouTube single-video URL validation and video ID extraction are duplicated across 5 files with copy-paste drift and architectural layering violations:

  1. server/services/youtubeImport.js:46-57 defines youtubeVideoIdFromUrl(url):
    export function youtubeVideoIdFromUrl(url) {
      if (!url) return null;
      const s = String(url).trim();
      const vParam = /[?&]v=([A-Za-z0-9_-]{6,20})/.exec(s);
      if (vParam) return vParam[1];
      const pathId = /(?:youtu\.be\/|\/shorts\/|\/embed\/|\/live\/|\/v\/)([A-Za-z0-9_-]{6,20})/.exec(s);
      if (pathId) return pathId[1];
      return null;
    }
    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.
  2. 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.
  3. 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.
  4. client/src/lib/youtubeUrl.js:19-26 reimplements youtubeVideoId(url) with identical regexes to youtubeVideoIdFromUrl.

Trigger

  1. 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.
  2. 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.

Fix

  1. Create server/lib/youtubeUrl.js:
    • Define canonical 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,})/i
    • Export youtubeVideoIdFromUrl(url) (with youtubeVideoId alias matching client naming).
    • Export isYoutubeVideoUrl(url).
    • Export assertYoutubeVideoUrl(url).
  2. Re-export server/lib/youtubeUrl.js in server/lib/index.js and add a catalog entry in server/lib/README.md.
  3. Update server/services/youtubeImport.js to re-export youtubeVideoIdFromUrl from ../lib/youtubeUrl.js for backward compatibility.
  4. 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.
  5. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions