Skip to content

[CDX-619] Align browse types with JS SDK - #273

Open
TarekAlQaddy wants to merge 1 commit into
masterfrom
cdx-619-result-retrieval-align-node-sdk-browse-types-with-javascript
Open

TarekAlQaddy wants to merge 1 commit into
masterfrom
cdx-619-result-retrieval-align-node-sdk-browse-types-with-javascript

Conversation

@TarekAlQaddy

Copy link
Copy Markdown
Contributor

Related to #268
This PR aligns the types with the JS SDK which has more accurate typings. This also adds filter_match_types to both search and browse.
Implemented all the changes that look safe and wouldn't break any existing code except for rarely used or unrealistic cases.

Compatibility

Nothing changes at runtime except that filterMatchTypes is now sent. Calling the SDK with any parameters that work today still compiles, and so does code that checks optional fields with ?. or if. The type-level edge cases are:

Breaks when Strict mode only? Fix
A hand-built browse response (e.g. a test mock) leaves out request, response or result_id No Add the field
related_searches / related_browse_pages are read without a check, or used as a non-array (they were any) Unchecked reads: yes. Non-array use: no ?. / fix the type
collection, variations, variations_map, filter_match_types, filters or query are read without a check on a variable typed with the named type (GetBrowseResultsResponseData, BrowseResultData, BrowseRequestType) Yes ?. or a default
An echoed aggregation value is assigned to the old four-value type, or used in an exhaustive switch No Widen the annotation / handle the new cases

Reads through a browse response object (res.response.collection, res.request.filters, …) are unaffected, because request and response are still Partial<>.

Deferred (breaking, for a major release)

  • VariationsMap.group_by optional.
  • BrowseResultData.variations_map typed as VariationsMapResponse (unknown values instead of any).
  • Removing Partial<> from request / response and their lists (result_sources, facets, groups, results, sort_options, features). Full model sharing with the JS SDK depends on this.
  • BrowseRequestType.facet_name.

@TarekAlQaddy
TarekAlQaddy requested a review from a team October 9, 2026 14:53
@TarekAlQaddy
TarekAlQaddy requested a review from a team as a code owner October 9, 2026 14:53
Copilot AI balanced review requested due to automatic review settings October 9, 2026 14:53

@constructor-claude-bedrock constructor-claude-bedrock 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.

Code Review

This PR aligns the Node SDK's TypeScript types with the JS SDK, adding filterMatchTypes to search/browse parameters and refining several response/request type definitions.

Inline comments: 5 discussions added

Overall Assessment: ⚠️ Needs Work

Comment thread src/types/browse.d.ts
browse_filter_value: string;
filter_match_types: Record<string, any>;
filters: Record<string, any>;
filter_match_types?: Record<string, any>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Important Issue: BrowseRequestType.filter_match_types is typed as Record<string, any> (the server-echoed request field), while the input parameter BrowseParameters.filterMatchTypes is correctly typed as Record<string, 'all' | 'any' | 'none'>. These should be consistent. Since this field is echoed back from the server, it should be Record<string, 'all' | 'any' | 'none'> here too, to allow callers to read the echoed value with the same precision.

Suggested fix:

filter_match_types?: Record<string, 'all' | 'any' | 'none'>;

Comment thread src/types/search.d.ts
total_num_results: number;
features: Partial<Feature>[];
related_searches?: Record<string, any>[];
related_browse_pages?: Record<string, any>[];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: related_searches and related_browse_pages are added to the Response (search) interface as Record<string, any>[]. These same fields are also added to GetBrowseResultsResponseData in the same fashion. If the shapes of these objects are known (e.g. { term: string } for related_searches, and { filter_name: string; filter_value: string } for related_browse_pages), defining dedicated interfaces would provide better type safety and IDE auto-completion. At minimum, these could be extracted to shared, named interfaces in index.d.ts to avoid duplication between the search and browse types.

Comment thread src/types/index.d.ts
export * from './tracker';
export * from './searchandising';

type RequireAtLeastOne<T, Keys extends keyof T = keyof T> =

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Important Issue: RequireAtLeastOne is defined as a non-exported type (lowercase type, no export). However, FilterBy which depends on it is exported. This works because the utility type is only needed internally for type-level computation, but it creates an inconsistency: the utility type is invisible to consumers who might want to use it directly. If intentionally unexported, a comment explaining the decision would help future maintainers. If it should be reusable, add export.

Also note the utility type is defined after the export * from '...' barrel re-exports — if any of the re-exported modules also need this type (they currently do not), it would not be available. Consider moving it before the re-exports or at least before its first usage.

fetch: fetchSpy,
});

browse.getBrowseResults(filterName, filterValue, { filters, filterMatchTypes }).then((res) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The new integration tests for filterMatchTypes use promise .then() + done callback style, which is the existing pattern in this file. However, these tests are missing rejection handling — if the promise rejects the test will time out rather than fail with a useful error message. The surrounding existing tests share this pattern, but since new tests are being added, consider adding a .catch(done) or switching to async/await with try/catch to align with more modern patterns and provide better failure diagnostics:

browse.getBrowseResults(filterName, filterValue, { filters, filterMatchTypes })
  .then((res) => {
    // assertions...
    done();
  })
  .catch(done);

filterMatchTypes: { size: 'some' },
});

expectNotAssignable<GetBrowseResultsResponse>({

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The expectNotAssignable<GetBrowseResultsResponse> test checks that an object missing result_id is not assignable. This is a good test for the breaking change introduced by making result_id required. However, there is no corresponding expectNotAssignable test in src/types/tests/search.test-d.ts for SearchResponse, even though SearchResponse already had request, response, and result_id as required fields before this PR. For consistency and to guard against future regressions, a parallel test in search.test-d.ts would be valuable.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The type and runtime changes are consistent with the stated compatibility scope and have appropriate coverage.

0 open findings

What changed in this PR

Aligns Node SDK browse/search typings with the JavaScript SDK and adds filterMatchTypes request support.

Changes:

  • Adds and tests filter_match_types serialization.
  • Refines browse responses and variations-map typings.
  • Corrects an ESLint suppression directive.
File Description
src/​types/​tests/​types.test-d.ts Tests variations-map types.
src/​types/​tests/​browse.test-d.ts Tests browse type changes.
src/​types/​search.d.ts Adds search parameter and response fields.
src/​types/​index.d.ts Expands variations-map models.
src/​types/​browse.d.ts Aligns browse request and response types.
src/​modules/​search.js Sends search filter match types.
src/​modules/​browse.js Sends browse filter match types.
spec/​src/​modules/​search.js Tests search serialization.
spec/​src/​modules/​catalog/​catalog-facet-configurations-v2.js Fixes ESLint suppression scope.
spec/​src/​modules/​browse.js Tests browse serialization.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

This branch has not been deployed

No deployments
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