-
-
Notifications
You must be signed in to change notification settings - Fork 0
feat: implement queryOptions export pattern and type-safe query key builder #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Transform hook-file.ts to export queryOptions instead of wrapper hooks - Update query key structure to [service, method, params] pattern - Create non-hook service getters in context-file.ts for queryOptions access - Update naming conventions to remove 'use' prefix (e.g., widgetsQueryOptions) - Regenerate snapshots with new export patterns - Update tsconfig.json to exclude snapshot directory from build This is the first step in migrating from wrapper hooks to queryOptions exports, following the pattern recommended by the React Query team. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add comprehensive usage examples in README - Update CLAUDE.md to reflect new queryOptions architecture - Create MIGRATION.md guide for v0.1.x to v0.2.0 upgrade - Document new query key structure and benefits 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- All tests passing with 80.53% code coverage - Linting and formatting verified - Build successful without errors - Updated version to 0.2.0 - Created comprehensive CHANGELOG.md - Removed outdated TODO comment - Verified backward compatibility documentation - Project ready for v0.2.0 release 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Remove the automatic stripping of "get" prefix from GET method names to maintain consistency across all generated query/mutation options. This change makes the API more predictable by keeping operation names exactly as defined in the service specification. - Update getQueryOptionsName to preserve full method names - Update documentation to reflect new naming convention - Regenerate snapshots with new naming pattern BREAKING CHANGE: Query options for GET methods now include the full operation name (e.g., getWidgetsQueryOptions instead of widgetsQueryOptions) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Create QueryKeyBuilderFile class to generate type-safe query keys - Generate QueryKeyMap interface mapping services → operations → params - Add type extraction helpers (ServiceKeys, OperationKeys, OperationParams) - Implement matchQueryKey function with three overloads for partial matching - Handle optional parameters with ParamsType | undefined pattern Part of v0.2.0 release 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Update matchQueryKey to properly handle 3-argument calls with undefined params
- Ensure query keys always have consistent structure [service, operation, params]
- Use empty object {} for undefined params when explicitly passed
- Add query-key-builder.ts to generated hooks directory
- Include comprehensive snapshot test for query key builder
This enhancement improves type safety and consistency in query key matching,
particularly for operations with optional parameters.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove redundant '-file' suffix from filename - Update import in hook-generator.ts - Preserve git history using git mv 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…ntation - Created 16 unit tests covering all aspects of query key builder functionality - Updated snapshots to include generated query-key-builder.ts file - Added usage examples to README demonstrating matchQueryKey function - Updated CLAUDE.md with architecture details for type-safe query keys - All tests passing with 99% coverage of query-key-builder.ts 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add documentation for the new type-safe matchQueryKey function that enables flexible query key construction with full IntelliSense support. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
These files were accidentally committed but should not be in the repository.
|
Addresses #14 |
|
One design concern I have here is with the For example, it's not intended to be used to provide custom query keys to queryOptions, but rather for non-queryOption-related functionality, like: queryClient.invalidateQueries({
// Invalidation via a full key with params
queryKey: matchQueryKey('widgets', 'getWidgets', { status 'active' }),
});
queryClient.invalidateQueries({
// Invalidation via a partial key at the operation level
queryKey: matchQueryKey('widgets', 'getWidgets'),
});
queryClient.invalidateQueries({
// Invalidation via a partial key at the service level
queryKey: matchQueryKey('widgets'),
}); |
- Replace generic ClientContext/ClientProvider with service-specific names (e.g., BasketryExampleContext, BasketryExampleProvider) - Fix context reference bug where hooks were using old ClientContext name - Update error messages to use service-specific provider names - Remove unused buildHookName method from NameFactory - Remove use prefix from query options exports (e.g., getWidgetFooQueryOptions) - Keep service hooks (e.g., useWidgetService) for React Context integration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Remove logic that stripped 'get' prefix from infinite query option names - Use full method name (e.g., getWidgetsInfiniteQueryOptions instead of widgetsInfiniteQueryOptions) - Remove unused getHttpMethodByName import from NameFactory - Ensures consistency with regular query options naming 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add focused tests for relay-paginated methods that generate infinite query options - Verify that full method names are preserved (including 'get' prefix) - Ensure non-paginated methods don't generate infinite options - Test that query keys include the infinite flag for proper cache isolation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Document service-specific naming changes for contexts and providers - Add notes about preserving full method names in exports - Include fixes for context reference bugs - Note removal of 'get' prefix stripping logic - Add test coverage additions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add explicit check for operation \!== undefined to avoid TypeScript non-null assertion - Improves type safety in generated code by eliminating escape hatches - Updates test to match new implementation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
| expect(output).toContain('export interface QueryKeyMap {'); | ||
| expect(output).toContain('widget: {'); | ||
| expect(output).toContain('getWidgets: GetWidgetsParams | undefined;'); | ||
| expect(output).toContain('getWidgetById: GetWidgetByIdParams;'); | ||
| expect(output).toContain('gizmo: {'); | ||
| expect(output).toContain('getGizmos: GetGizmosParams | undefined;'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine. I want to find a solution like this to unit testing generator outputs other than just snapshot tests. The only issue I see with this is testing indentation (not critical) and line order.
| }, | ||
| "include": ["src"], | ||
| "exclude": ["**/*.test?.*"] | ||
| "exclude": ["**/*.test?.*", "src/snapshot/**"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a note, I do like including the snapshot folder so that we get compile-time type checks on the generated snapshots.
skonves
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Looks good! I left some notes.
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Task Group 1 Complete: - Added hook name generation methods to NameFactory - Set up ImportBuilder for React Query hooks - Created deprecation message templates and helper method This prepares the foundation for generating deprecated hook wrappers alongside the new query options pattern. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Generate useXxx() and useSuspenseXxx() wrappers for query operations - Generate useXxx() wrappers for mutation operations with query invalidation - Generate useXxxInfinite() and useSuspenseXxxInfinite() for paginated queries - Add comprehensive deprecation messages with migration examples - Update snapshots with new deprecated exports - All tests passing (19/19) Part of Task Group 2: Generate Deprecated Hooks
- Add comprehensive unit tests for all deprecated hook types - Fix deprecation message formatting with proper pluralization - Update test snapshots to include both old and new patterns - Ensure 98%+ test coverage maintained - All 23 tests passing
- Update version to 0.2.0-alpha.1 - Add comprehensive migration guide to README - Document backwards compatibility in CHANGELOG - Include examples for migrating from hooks to queryOptions pattern This release provides a smooth upgrade path for users with deprecated hook wrappers that maintain full backwards compatibility while encouraging adoption of the new queryOptions pattern. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add automated migration tool to help users upgrade from v0.1.x to v0.2.x: - jscodeshift transform that converts deprecated hooks to queryOptions pattern - Handles all hook types: query, mutation, infinite, and suspense - Preserves TypeScript type parameters and existing imports - Includes comprehensive test suite with fixtures - Provides detailed documentation and helper script - Safe by default with dry-run mode Users can now run: ./codemod/run-migration.sh --apply To automatically migrate their codebase from the old hook pattern to the new queryOptions pattern, significantly reducing manual migration effort. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add instructions for using the automated migration tool in the README's migration guide section, making it easier for users to discover and use the jscodeshift codemod. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Include direct jscodeshift/npx commands in the automated migration section for users who prefer running the codemod without the wrapper script. Shows both dry-run and apply examples. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Update .npmignore to include codemod in npm package - Apply prettier formatting to codemod files - Update CHANGELOG to mention jscodeshift codemod - Ensure all files pass linting and formatting checks The package is now ready for the v0.2.0-alpha.1 release with full backwards compatibility and automated migration tooling. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
The version bump should be handled by the GitHub Actions workflow, not manually. Reverting to let the automated release process handle the version increment. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
The old v0.1.x version stripped "Get" prefix from GET method hook names: - getWidgets → useWidgets (not useGetWidgets) - getWidgetById → useWidgetById (not useGetWidgetById) This fix ensures true backwards compatibility by: - Updating NameFactory to strip "Get" prefix for GET methods - Passing HTTP verb info to name generation methods - Updating codemod to handle both patterns (with and without Get) - Fixing tests to expect the correct naming - Regenerating snapshots with proper hook names Now the deprecated hooks match the v0.1.x naming exactly. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…-query into export-query-options
Apply code formatting to ensure consistent style across: - name-factory.ts - hook-file.ts - hook-file.test.ts - react-query-v0.2-migration.js 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
- Restored original hook implementation that accepts React Query options - Query hooks now properly accept and spread options parameter - Mutation hooks accept options and merge with mutation options - Infinite query hooks work with original naming pattern (useWidgetsInfinite) - All deprecated hooks maintain backwards compatibility while guiding to new pattern - New query/mutation options exports remain as purely additive feature - No breaking changes to existing hook patterns The deprecated hooks now work exactly as in v0.1.0, accepting options parameters while the new query options exports provide the migration path forward. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…-query into export-query-options
|
Closing in favor of #20 which preserves backwards compatibility while this PR does not. |
Summary
matchQueryKeyfunctionBreaking Changes
useGetWidgets) to exporting query/mutation options (getWidgetsQueryOptions)getWidgets→getWidgetsQueryOptionsinstead ofwidgets)New Features
matchQueryKeyfunction for building query keys with full IntelliSense support[serviceName, methodName, params || {}]Test plan
npm testto verify all tests passnpm run buildto ensure clean compilationsrc/snapshot/v1/🤖 Generated with Claude Code