Skip to content

🛠️ DX: Support full URLs and raw IDs in parsing and API methods#195

Open
bartholomej wants to merge 1 commit into
masterfrom
dx-bolt-url-parsing-improvements-11425765255038408731
Open

🛠️ DX: Support full URLs and raw IDs in parsing and API methods#195
bartholomej wants to merge 1 commit into
masterfrom
dx-bolt-url-parsing-improvements-11425765255038408731

Conversation

@bartholomej

@bartholomej bartholomej commented May 28, 2026

Copy link
Copy Markdown
Owner

🛠️ DX: Support full URLs and raw IDs in parsing and API methods

💡 What

  • Enhanced parseIdFromUrl to correctly extract IDs from both traditional slugs (/uzivatel/912-bart/) and raw IDs (/uzivatel/912/).
  • Updated userUrl to handle raw URL strings, preventing double encoding when a full profile URL is passed.
  • Refactored userRatings and userReviews methods to gracefully handle both raw IDs and full URLs by natively leveraging extractId.

🎯 Why

  • Greatly improves Developer Experience (DX) by making API methods robust against various inputs (raw numbers, URL slugs, or fully qualified URLs).
  • Prevents brittle failures when users pass a link copied directly from a browser.

🚀 Examples

// Before
csfd.userRatings(912) // ✅ ok
csfd.userRatings('https://www.csfd.cz/uzivatel/912-bart/') // ❌ double encoded as /uzivatel/http...

// After
csfd.userRatings(912) // ✅ ok
csfd.userRatings('https://www.csfd.cz/uzivatel/912-bart/') // ✅ cleanly extracts 912
csfd.userRatings('https://www.csfd.cz/uzivatel/912/') // ✅ cleanly extracts 912

PR created automatically by Jules for task 11425765255038408731 started by @bartholomej

Summary by CodeRabbit

  • New Features

    • Package now publicly exports all data types for improved type safety.
  • Bug Fixes

    • Fixed URL double-encoding issue when passing full URLs to user endpoints.
    • Enhanced user ID validation with descriptive error messages for invalid inputs.
  • Refactor

    • Improved code formatting and readability across utilities.
    • Optimized URL parsing to recognize both slug-based and purely numeric IDs.

Review Change Stack

💡 What
- Enhanced `parseIdFromUrl` to correctly extract IDs from both traditional slugs (`/uzivatel/912-bart/`) and raw IDs (`/uzivatel/912/`).
- Updated `userUrl` to handle raw URL strings, preventing double encoding when a full profile URL is passed.
- Refactored `userRatings` and `userReviews` methods to gracefully handle both raw IDs and full URLs by natively leveraging `extractId`.

🎯 Why
- Greatly improves Developer Experience (DX) by making API methods robust against various inputs (raw numbers, URL slugs, or fully qualified URLs).
- Prevents brittle failures when users pass a link copied directly from a browser.

🚀 Examples
```typescript
// Before
csfd.userRatings(912) // ✅ ok
csfd.userRatings('https://www.csfd.cz/uzivatel/912-bart/') // ❌ double encoded as /uzivatel/http...

// After
csfd.userRatings(912) // ✅ ok
csfd.userRatings('https://www.csfd.cz/uzivatel/912-bart/') // ✅ cleanly extracts 912
csfd.userRatings('https://www.csfd.cz/uzivatel/912/') // ✅ cleanly extracts 912
```

Co-authored-by: bartholomej <5861310+bartholomej@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR extends URL ID parsing to handle purely numeric path segments, refactors user-ratings and user-reviews services to extract and validate numeric user IDs with error handling, enhances the userUrl helper to pass through full HTTP URLs directly, re-exports DTO types from the main package index, and reformats CLI output and various code helpers for improved readability without functional changes.

Changes

Code refactoring and API improvements

Layer / File(s) Summary
URL ID parsing enhancement
src/helpers/global.helper.ts
parseIdFromUrl now recognizes URL path segments that are purely numeric (/^\d+$/) and returns the numeric value directly, complementing the existing hyphenated ID-prefix matching.
User service ID extraction and validation
src/services/user-ratings.service.ts, src/services/user-reviews.service.ts
Both services now extract a numeric user ID via extractId(user), validate that it is non-null and not NaN, and throw an error when invalid. Initial and paginated URL requests use the extracted ID instead of the raw user parameter.
URL helpers and public API exports
src/vars.ts, src/index.ts
userUrl now detects strings starting with http and returns them directly after removing trailing slashes. userRatingsUrl and userReviewsUrl are reformatted as multi-line exports. The main package index re-exports all DTO types via export type * from './dto'.
CLI output and code formatting improvements
src/bin/export-reviews.ts, src/bin/lookup-movie.ts, src/bin/search.ts, src/bin/utils.ts, src/helpers/search-user.helper.ts, src/services/movie.service.ts, src/types.ts, src/dto/options.ts
CSV headers, rating/name derivation, search results summary, ANSI color helpers, filter predicates, method calls, and import/export statements are reformatted into multi-line forms for readability and line-length control without changing underlying logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

enhancement

Poem

A rabbit hops through code so neat,
With parsing paths both short and sweet,
IDs extracted, formatted fine,
Types exported in a line. 🐰✨
Readability improved with care,
Cleaner code for all to share!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description provides detailed context with What, Why, and Examples sections, but the required checklist items are not marked as completed. Mark the checklist items to indicate self-review completion and whether tests were added to validate the new functionality.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: supporting full URLs and raw IDs in parsing and API methods, which aligns with the core objectives of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dx-bolt-url-parsing-improvements-11425765255038408731

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/bin/export-reviews.ts

Oops! Something went wrong! :(

ESLint: 10.4.0

TypeError [ERR_IMPORT_ATTRIBUTE_MISSING]: Module "file:///.eslintrc.json?mtime=1779963837916" needs an import attribute of "type: json"
at validateAttributes (node:internal/modules/esm/assert:88:15)
at defaultLoadSync (node:internal/modules/esm/load:164:3)
at #loadAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:776:12)
at #loadSync (node:internal/modules/esm/loader:796:49)
at ModuleLoader.load (node:internal/modules/esm/loader:762:26)
at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:504:31)
at #getOrCreateModuleJobAfterResolve (node:internal/modules/esm/loader:555:36)
at afterResolve (node:internal/modules/esm/loader:603:52)
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:609:12)
at node:internal/modules/esm/loader:628:32

src/bin/lookup-movie.ts

Oops! Something went wrong! :(

ESLint: 10.4.0

TypeError [ERR_IMPORT_ATTRIBUTE_MISSING]: Module "file:///.eslintrc.json?mtime=1779963837916" needs an import attribute of "type: json"
at validateAttributes (node:internal/modules/esm/assert:88:15)
at defaultLoadSync (node:internal/modules/esm/load:164:3)
at #loadAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:776:12)
at #loadSync (node:internal/modules/esm/loader:796:49)
at ModuleLoader.load (node:internal/modules/esm/loader:762:26)
at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:504:31)
at #getOrCreateModuleJobAfterResolve (node:internal/modules/esm/loader:555:36)
at afterResolve (node:internal/modules/esm/loader:603:52)
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:609:12)
at node:internal/modules/esm/loader:628:32

src/bin/search.ts

Oops! Something went wrong! :(

ESLint: 10.4.0

TypeError [ERR_IMPORT_ATTRIBUTE_MISSING]: Module "file:///.eslintrc.json?mtime=1779963837916" needs an import attribute of "type: json"
at validateAttributes (node:internal/modules/esm/assert:88:15)
at defaultLoadSync (node:internal/modules/esm/load:164:3)
at #loadAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:776:12)
at #loadSync (node:internal/modules/esm/loader:796:49)
at ModuleLoader.load (node:internal/modules/esm/loader:762:26)
at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:504:31)
at #getOrCreateModuleJobAfterResolve (node:internal/modules/esm/loader:555:36)
at afterResolve (node:internal/modules/esm/loader:603:52)
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:609:12)
at node:internal/modules/esm/loader:628:32

  • 9 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.23529% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.48%. Comparing base (51c7528) to head (4a28368).

Files with missing lines Patch % Lines
src/services/user-ratings.service.ts 83.33% 1 Missing ⚠️
src/services/user-reviews.service.ts 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #195      +/-   ##
==========================================
- Coverage   98.71%   98.48%   -0.24%     
==========================================
  Files          34       34              
  Lines         781      790       +9     
  Branches      202      206       +4     
==========================================
+ Hits          771      778       +7     
- Misses         10       12       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/services/user-ratings.service.ts (1)

26-30: ⚡ Quick win

Extract shared user-ID validation to a single helper.

The same normalization/throw logic is now duplicated here and in src/services/user-reviews.service.ts. Centralizing it avoids drift in validation/error behavior.

♻️ Proposed refactor
-    const id = extractId(user);
-    if (id === null || isNaN(id)) {
-      throw new Error('node-csfd-api: user must be a valid number or url');
-    }
+    const id = resolveUserIdOrThrow(user);
// src/helpers/global.helper.ts
export const resolveUserIdOrThrow = (user: string | number): number => {
  const id = extractId(user);
  if (id === null || isNaN(id)) {
    throw new Error('node-csfd-api: user must be a valid number or url');
  }
  return id;
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/user-ratings.service.ts` around lines 26 - 30, Create a new
helper function resolveUserIdOrThrow that wraps the existing extractId call and
throws the same Error when id is null or NaN, returning the numeric id; then
replace the duplicated validation block in both user-ratings.service (the code
using extractId currently throwing 'node-csfd-api: user must be a valid number
or url') and user-reviews.service to call resolveUserIdOrThrow instead; ensure
the helper is exported and imported where needed and retains the exact error
message and number return type so behavior stays identical to extractId + manual
check.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/services/user-ratings.service.ts`:
- Around line 26-30: Create a new helper function resolveUserIdOrThrow that
wraps the existing extractId call and throws the same Error when id is null or
NaN, returning the numeric id; then replace the duplicated validation block in
both user-ratings.service (the code using extractId currently throwing
'node-csfd-api: user must be a valid number or url') and user-reviews.service to
call resolveUserIdOrThrow instead; ensure the helper is exported and imported
where needed and retains the exact error message and number return type so
behavior stays identical to extractId + manual check.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 16c346f6-4c61-4f2d-b78a-1f1d43589a85

📥 Commits

Reviewing files that changed from the base of the PR and between 51c7528 and 4a28368.

📒 Files selected for processing (13)
  • src/bin/export-reviews.ts
  • src/bin/lookup-movie.ts
  • src/bin/search.ts
  • src/bin/utils.ts
  • src/dto/options.ts
  • src/helpers/global.helper.ts
  • src/helpers/search-user.helper.ts
  • src/index.ts
  • src/services/movie.service.ts
  • src/services/user-ratings.service.ts
  • src/services/user-reviews.service.ts
  • src/types.ts
  • src/vars.ts
💤 Files with no reviewable changes (1)
  • src/index.ts

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants