Skip to content

feat(openapi-react-query): generate useInfiniteQuery hooks for paginated endpoints#281

Merged
benjamineckstein merged 1 commit into
mainfrom
feat/189-use-infinite-query
Jun 5, 2026
Merged

feat(openapi-react-query): generate useInfiniteQuery hooks for paginated endpoints#281
benjamineckstein merged 1 commit into
mainfrom
feat/189-use-infinite-query

Conversation

@benjamineckstein

Copy link
Copy Markdown
Contributor

Closes #189.

This is an additive, non-breaking feature that generates useInfiniteQuery hooks for paginated endpoints.

Detection Strategy

The feature uses a three-level priority system:

  1. Operation Extension (highest priority): x-infinite: true/false on an operation. This wins even on detail endpoints. Warns and skips silently if detected but no query params exist.

  2. Heuristic Detection: For GET list operations without path params, detects pagination param names (page, cursor, offset, pageToken, after, before, etc.).

  3. Configuration Field: New infinite_query config field (boolean | 'auto', default 'auto') allows explicit control.

Generated Hooks

  • Named use{Name}Infinite (e.g., useItemsInfinite)
  • Query key extends the list key with an 'infinite' segment (prevents cache collision)
  • queryFn merges pageParam into the detected pagination param
  • Options typing: callers can pass partial options (getNextPageParam and initialPageParam omitted from required surface, but overridable at runtime via options spread)

Testing & Output

  • 410 new tests in openapi-react-query package
  • Regenerated integration and showcase output (6 specs)
  • Consumer-simulation typecheck patterns validating partial options ergonomics

Code Review

This change went through internal code review with 2 blocking findings fixed:

  • Options typing ergonomics (now consumer-friendly)
  • Silent no-op behavior when x-infinite detected but pagination params missing (now warns)

…ted endpoints (#189)

Emits a useXxxInfinite hook alongside the regular useQuery hook whenever a
list-level GET operation is detected as paginated. Fully additive and
non-breaking: the regular hook is always generated unchanged.

Detection priority:
1. x-infinite: true/false on the operation (explicit override).
2. Heuristic: list GET (no path params) with a recognised pagination query
   param name (page, cursor, offset, pageToken, after, before, next_page,
   nextPage, page_token). Detection runs on resolved $ref params.
3. infiniteQuery config field (boolean | 'auto', default 'auto') allows
   force-on, force-off, or heuristic mode.

Generated hook shape:
- Named use${funcName}Infinite (mirrors useSuspense* suffix pattern).
- queryKey: [...resourceKeys.list(params), 'infinite'] to namespace away
  from regular list queries.
- queryFn injects pageParam into the params object at the detected param name.
- Provides initialPageParam: undefined and getNextPageParam: () => undefined
  as defaults; callers override both via the options argument.
- options type: Omit<UseInfiniteQueryOptions<...>, 'queryKey' | 'queryFn'>
  so callers can supply getNextPageParam and initialPageParam.

Config: added infinite_query field to ReactQueryConfig with validation.
Regenerated: packages/integration/generated/hooks.ts (gains useListTasksInfinite),
and 6 showcase specs in examples/generated-rq/ that have pagination params
(1password-connect, devto, openai, redocly-museum, resend, spotify).
@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Fallow audit report

Found 18 findings.

Dependencies (2)
Severity Rule Location Description
minor fallow/unused-dev-dependency examples/package.json:15 Package '@tanstack/react-query' is in devDependencies but never imported; imported in other workspaces: packages/integration
minor fallow/unused-dev-dependency examples/package.json:17 Package 'react' is in devDependencies but never imported; imported in other workspaces: packages/integration
Duplication (15)
Severity Rule Location Description
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2435 Code clone group 2 (5 lines, 3 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2435 Code clone group 1 (6 lines, 2 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2436 Code clone group 4 (8 lines, 3 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2436 Code clone group 3 (5 lines, 2 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2454 Code clone group 2 (5 lines, 3 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2454 Code clone group 1 (6 lines, 2 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2463 Code clone group 3 (5 lines, 2 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2463 Code clone group 4 (8 lines, 3 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2470 Code clone group 2 (5 lines, 3 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2526 Code clone group 4 (8 lines, 3 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2686 Code clone group 5 (8 lines, 2 instances)
minor fallow/code-duplication packages/openapi-react-query/src/\_\_tests\_\_/hooks.test.ts:2713 Code clone group 5 (8 lines, 2 instances)
minor fallow/code-duplication packages/openapi-react-query/src/plugins/hooks.ts:137 Code clone group 6 (25 lines, 2 instances)
minor fallow/code-duplication packages/openapi-react-query/src/plugins/hooks.ts:175 Code clone group 7 (10 lines, 2 instances)
minor fallow/code-duplication packages/openapi-react-query/src/plugins/hooks.ts:677 Code clone group 9 (8 lines, 3 instances)
Health (1)
Severity Rule Location Description
minor fallow/high-cognitive-complexity packages/openapi-react-query/src/plugins/hooks.ts:881 'collectOperations' has cognitive complexity 19 (threshold: 12)

Generated by fallow.

@github-actions github-actions Bot 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.

Fallow audit report

12 inline findings selected for GitHub review.

Comment thread packages/openapi-react-query/src/__tests__/hooks.test.ts
Comment thread packages/openapi-react-query/src/__tests__/hooks.test.ts
Comment thread packages/openapi-react-query/src/__tests__/hooks.test.ts
Comment thread packages/openapi-react-query/src/__tests__/hooks.test.ts
Comment thread packages/openapi-react-query/src/__tests__/hooks.test.ts
Comment thread packages/openapi-react-query/src/__tests__/hooks.test.ts
Comment thread packages/openapi-react-query/src/plugins/hooks.ts
Comment thread packages/openapi-react-query/src/plugins/hooks.ts
Comment thread packages/openapi-react-query/src/plugins/hooks.ts
Comment thread packages/openapi-react-query/src/plugins/hooks.ts
Comment thread packages/openapi-react-query/src/plugins/hooks.ts
Comment thread packages/openapi-react-query/src/plugins/hooks.ts
@benjamineckstein benjamineckstein merged commit 7d7aa2d into main Jun 5, 2026
7 checks passed
@benjamineckstein benjamineckstein deleted the feat/189-use-infinite-query branch June 5, 2026 07:03
@github-actions github-actions Bot mentioned this pull request Jun 5, 2026
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.

openapi-react-query: generate useInfiniteQuery for paginated endpoints

2 participants