Skip to content

20 support rich filtering sorting options#21

Merged
angelxmoreno merged 2 commits intomainfrom
20-support-rich-filteringsorting-options
Dec 19, 2025
Merged

20 support rich filtering sorting options#21
angelxmoreno merged 2 commits intomainfrom
20-support-rich-filteringsorting-options

Conversation

@angelxmoreno
Copy link
Copy Markdown
Owner

@angelxmoreno angelxmoreno commented Dec 19, 2025

Summary by CodeRabbit

  • New Features

    • Added filtering and sorting capabilities to API queries with support for multiple fields.
    • Introduced validation for single-filter requests per query.
  • Documentation

    • Updated usage examples with higher result limits.
    • Added comprehensive filtering and sorting examples with supported fields and constraints.
  • Tests

    • Expanded test coverage for sorting, filtering, and error handling scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

@angelxmoreno angelxmoreno linked an issue Dec 19, 2025 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 19, 2025

Walkthrough

The pull request introduces filtering and sorting capabilities to the sneaker database client. New type definitions specify filterable fields, operators, and sort options. Core logic validates input, normalizes query parameters, and serializes them for API requests. Comprehensive test coverage validates serialization, field whitelisting, and error handling.

Changes

Cohort / File(s) Summary
Documentation
README.md
Increased example limit to 15; added filtering and sorting usage example with explanation of single-filter constraint and supported fields.
Interface Definitions
src/interfaces.ts
Added filtering types (FilterOperator, FilterOption, FilterValue, FILTERABLE_FIELDS, ComparableField) and sorting types (SortOrder, SortField, SortOption). Extended PaginatedOptions with sort and filters fields; refined GetSneakersOptions to inherit from new structure.
Core Implementation
src/TheSneakerDatabaseClient.ts
Introduced query parameter normalization layer: prepareQueryParams(), serializeSortOption(), ensureSingleFilter(), serializeFilter(), and serializeFilterValue(). Added validation sets for filterable fields and operators. Updated request construction to use prepared query params.
Public Exports
src/index.ts
Added SortOption and SortOrder to public exports.
E2E Tests
src/TheSneakerDatabaseClient.e2e.test.ts
Added 1.5s delay between tests; enhanced expectSuccessful() with optional error message callback; added sorting tests per field, multi-filter rejection guard, and API-level error verification with AxiosError handling.
Integration Tests
src/TheSneakerDatabaseClient.integration.test.ts
Added filterFixtures constant; updated sort serialization expectations from string to object format; added comprehensive tests for sort serialization, filter serialization per field, date handling, default operators, and rejection paths for unsupported filters and multiple filters.

Sequence Diagram

sequenceDiagram
    participant C as getSneakers()
    participant P as prepareQueryParams()
    participant S as serializeSortOption()
    participant V as ensureSingleFilter()
    participant F as serializeFilter()
    participant R as Request Builder

    C->>P: options (sort?, filters?)
    
    alt sort exists
        P->>S: SortOption
        S-->>P: "field:order"
    end
    
    alt filters exists
        P->>V: FilterOption
        V->>V: validate field whitelist
        V->>V: validate operator
        V-->>P: FilterOption | undefined
        
        alt single filter valid
            P->>F: FilterOption
            F->>F: serializeFilterValue()
            F-->>P: "field=op:value"
        end
    end
    
    P-->>C: prepared query params
    C->>R: use prepared params
    R-->>C: HTTP request
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Validation logic in TheSneakerDatabaseClient.ts: Multiple interdependent serialization and validation methods; careful review needed for field whitelist enforcement, operator validation, and date serialization correctness.
  • Date formatting in serializeFilterValue(): Verify YYYY-MM-DD format handling and edge cases.
  • Integration test expectations: Updated API parameter format (field=op:value for filters, field:order for sort) requires cross-referencing with implementation logic.
  • Public API surface changes: GetSneakersOptions structure changes and new exported types affect consumer-facing contract.
  • Error handling in e2e tests: AxiosError handling and multi-filter rejection verification logic.

Poem

🐰 Filters and sorts now bloom so bright,
With operators guarding each request's flight,
One filter per hop, the rules stay tight,
Validation wheels spin through the night,
This sneaker search soars to new height! ✨👟

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature added: support for rich filtering and sorting options across the codebase, as evidenced by new filter/sort types, validation logic, and comprehensive test coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 20-support-rich-filteringsorting-options

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
Copy link
Copy Markdown

codecov bot commented Dec 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.42%. Comparing base (edbc5f3) to head (4a36072).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #21      +/-   ##
==========================================
+ Coverage   98.00%   99.42%   +1.42%     
==========================================
  Files           2        3       +1     
  Lines         100      174      +74     
==========================================
+ Hits           98      173      +75     
+ Misses          2        1       -1     

☔ 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.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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 (3)
src/index.ts (1)

10-11: Consider exporting filter-related types for public API completeness.

SortOption and SortOrder are now exported, but users constructing filter parameters may also need FilterOption, FilterOperator, and FILTERABLE_FIELDS. The README example shows filter usage, so these types would help consumers build type-safe filter objects.

Suggested additions
 export type {
     CacheOptions,
+    ComparableField,
+    FilterOperator,
+    FilterOption,
+    FilterValue,
     GetSneakersOptions,
     GetSneakersResponse,
     MethodResponse,
     PaginatedOptions,
     SearchOptions,
     SearchResponse,
     Sneaker,
     SortOption,
     SortOrder,
     TheSneakerDatabaseClientOptions,
 } from './interfaces';
+export { FILTERABLE_FIELDS } from './interfaces';
 export { TheSneakerDatabaseClient } from './TheSneakerDatabaseClient';
src/TheSneakerDatabaseClient.e2e.test.ts (1)

91-108: Consider adding a timeout to the API call.

This test makes a direct API call that's expected to fail. If the API is slow to respond with an error, this could cause test timeouts.

src/TheSneakerDatabaseClient.ts (1)

220-225: Consider validating Date objects before serialization.

The toISOString() call on line 222 will throw a RangeError if passed an invalid Date object (e.g., new Date(NaN) or new Date('invalid')). While this error would be caught by the try-catch in handleRequest, it might result in a less helpful error message since handleAxiosError may not be designed for non-Axios errors.

🔎 Proposed validation to handle invalid dates gracefully
 protected serializeFilterValue(value: FilterValue) {
     if (value instanceof Date) {
+        if (isNaN(value.getTime())) {
+            throw new Error('filters.value must be a valid Date object.');
+        }
         return value.toISOString().split('T')[0];
     }
     return String(value);
 }

Alternatively, verify that handleAxiosError gracefully handles non-Axios errors and produces appropriate error messages.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d39a401 and 4a36072.

📒 Files selected for processing (6)
  • README.md (1 hunks)
  • src/TheSneakerDatabaseClient.e2e.test.ts (4 hunks)
  • src/TheSneakerDatabaseClient.integration.test.ts (5 hunks)
  • src/TheSneakerDatabaseClient.ts (4 hunks)
  • src/index.ts (1 hunks)
  • src/interfaces.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.ts: Source TypeScript files should be organized in src/ directory with TheSneakerDatabaseClient.ts exposing the SDK, interfaces.ts for shared types, utils.ts for helpers, and index.ts re-exporting public modules
Use Prettier-equivalent formatting with 4-space indent, single quotes, trailing commas, semicolons, and 120-character line wraps in TypeScript files
Use PascalCase for class names in TypeScript
Use camelCase for function names in TypeScript
Use UPPER_SNAKE_CASE for exported constants in TypeScript
Validate payloads with the interfaces module before sending requests in TypeScript client code

Files:

  • src/index.ts
  • src/TheSneakerDatabaseClient.e2e.test.ts
  • src/TheSneakerDatabaseClient.ts
  • src/interfaces.ts
  • src/TheSneakerDatabaseClient.integration.test.ts
src/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Surface public APIs through src/index.ts as the main export file

Files:

  • src/index.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Test files should use the *.test.ts naming convention and be colocated with their target implementation files
Add unit test specs alongside code using *.test.ts with Bun's built-in test runner and axios-mock-adapter for offline testing

Files:

  • src/TheSneakerDatabaseClient.e2e.test.ts
  • src/TheSneakerDatabaseClient.integration.test.ts
🧠 Learnings (4)
📚 Learning: 2025-12-17T08:35:10.837Z
Learnt from: CR
Repo: angelxmoreno/sneakerdb-client PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T08:35:10.837Z
Learning: Applies to src/index.ts : Surface public APIs through `src/index.ts` as the main export file

Applied to files:

  • src/index.ts
📚 Learning: 2025-12-17T08:35:10.837Z
Learnt from: CR
Repo: angelxmoreno/sneakerdb-client PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T08:35:10.837Z
Learning: Applies to src/**/*.ts : Use UPPER_SNAKE_CASE for exported constants in TypeScript

Applied to files:

  • src/index.ts
📚 Learning: 2025-12-17T08:35:10.837Z
Learnt from: CR
Repo: angelxmoreno/sneakerdb-client PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T08:35:10.837Z
Learning: Applies to src/**/*.ts : Source TypeScript files should be organized in `src/` directory with `TheSneakerDatabaseClient.ts` exposing the SDK, `interfaces.ts` for shared types, `utils.ts` for helpers, and `index.ts` re-exporting public modules

Applied to files:

  • src/index.ts
  • README.md
  • src/TheSneakerDatabaseClient.e2e.test.ts
  • src/TheSneakerDatabaseClient.ts
  • src/TheSneakerDatabaseClient.integration.test.ts
📚 Learning: 2025-12-17T08:35:10.837Z
Learnt from: CR
Repo: angelxmoreno/sneakerdb-client PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T08:35:10.837Z
Learning: Applies to **/*.test.ts : Add unit test specs alongside code using `*.test.ts` with Bun's built-in test runner and `axios-mock-adapter` for offline testing

Applied to files:

  • src/TheSneakerDatabaseClient.e2e.test.ts
  • src/TheSneakerDatabaseClient.integration.test.ts
🧬 Code graph analysis (4)
src/TheSneakerDatabaseClient.e2e.test.ts (1)
src/interfaces.ts (4)
  • MethodResponse (34-34)
  • SortOption (59-62)
  • GetSneakersResponse (83-86)
  • GetSneakersOptions (71-81)
src/TheSneakerDatabaseClient.ts (2)
src/interfaces.ts (7)
  • ComparableField (45-45)
  • FILTERABLE_FIELDS (43-43)
  • FilterOperator (41-41)
  • SortOption (59-62)
  • SortOrder (55-55)
  • FilterOption (49-53)
  • FilterValue (47-47)
src/index.ts (2)
  • SortOption (10-10)
  • SortOrder (11-11)
src/interfaces.ts (1)
src/index.ts (4)
  • SortOrder (11-11)
  • SortOption (10-10)
  • PaginatedOptions (6-6)
  • CacheOptions (2-2)
src/TheSneakerDatabaseClient.integration.test.ts (1)
src/interfaces.ts (6)
  • FilterOption (49-53)
  • FilterOperator (41-41)
  • FilterValue (47-47)
  • GetSneakersResponse (83-86)
  • GetSneakersOptions (71-81)
  • FILTERABLE_FIELDS (43-43)
🔇 Additional comments (18)
README.md (1)

36-49: LGTM!

The new documentation clearly demonstrates the filtering and sorting API with proper examples and helpful inline comments listing supported fields. The note about single filter limitation aligns with the client validation logic.

src/TheSneakerDatabaseClient.e2e.test.ts (2)

40-42: Good practice: Rate limiting for E2E tests.

The 1.5s sleep between tests helps avoid rate limiting issues when running against the live RapidAPI endpoint.


54-71: LGTM!

Systematic coverage of all sortable fields with clear per-field error messages. The loop-based approach keeps tests DRY while ensuring each field is validated against the real API.

src/interfaces.ts (3)

41-53: LGTM!

Well-structured filter type definitions. The FILTERABLE_FIELDS const with as const provides both runtime validation and compile-time type inference. The FilterOption interface cleanly encapsulates field, value, and optional operator.

As per coding guidelines, FILTERABLE_FIELDS correctly uses UPPER_SNAKE_CASE.


55-62: LGTM!

Clean sort type definitions with sensible defaults (order is optional, defaulting presumably to 'asc' in the implementation).


67-68: Filters typed as singular object enforces single-filter constraint.

The filters?: FilterOption type (singular) prevents arrays at compile-time, which aligns with the API's single-filter limitation documented in the README. This is a good design choice.

src/TheSneakerDatabaseClient.integration.test.ts (5)

58-63: LGTM!

The filterFixtures constant provides well-structured test data for each filterable field, enabling systematic test coverage through iteration.


239-251: LGTM!

Good test coverage for sort option serialization. Verifies that { field: 'retailPrice', order: 'asc' } is serialized to 'retailPrice:asc' in the API request.


267-287: LGTM!

Thorough test coverage iterating over all FILTERABLE_FIELDS to verify filter serialization for each field type, including proper Date handling.


303-320: Verify no network request is made when validation fails.

Line 319 asserts expect(getHistoryRequests()).toHaveLength(0), confirming the client rejects invalid input before making an API call. This is good defensive behavior.


322-336: LGTM!

Test correctly verifies that unsupported filter fields are rejected with a descriptive error message before any network request is made.

src/TheSneakerDatabaseClient.ts (7)

8-10: LGTM! Imports are clean and complete.

The new imports for filtering and sorting types align correctly with the interface definitions. Importing the FILTERABLE_FIELDS constant for validation is a good practice.

Also applies to: 18-19, 22-22


25-27: LGTM! Efficient validation constants.

Creating Set instances for filterable fields and operators enables O(1) lookup during validation. The FILTER_OPERATORS array with const assertion correctly matches the FilterOperator type definition.


78-79: LGTM! Correct integration of query parameter normalization.

The flow properly normalizes query parameters before both caching and sending the request, ensuring consistency between the cache key and the actual API call.

Also applies to: 89-89


133-160: LGTM! Clear parameter normalization logic.

The method correctly normalizes query parameters by serializing sort and filter options, then removing any undefined values. The explicit handling of undefined cases makes the logic clear and defensive.


162-170: LGTM! Correct sort option serialization.

The method properly serializes sort options to the "field:order" format, with sensible defaults (desc for order) and appropriate handling of missing fields.


172-208: LGTM! Thorough filter validation with excellent error messages.

The validation logic is comprehensive and defensive, with clear error messages that guide users toward correct usage. The checks for field whitelisting, operator validation, and required properties are well-implemented.


210-218: LGTM! Clean filter serialization.

The method correctly serializes filter options to the "field=operator:value" format with a sensible default operator (eq), delegating value serialization to a dedicated helper.

@angelxmoreno angelxmoreno merged commit 43f0a2f into main Dec 19, 2025
4 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 2.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@angelxmoreno angelxmoreno deleted the 20-support-rich-filteringsorting-options branch December 19, 2025 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support rich filtering/sorting options

1 participant