feat(next-transpile-modules): modernize for Next.js 16 and React 19#41
feat(next-transpile-modules): modernize for Next.js 16 and React 19#41riceharvest wants to merge 77 commits intomainfrom
Conversation
- Upgraded multiple packages to modern standards (Next.js, Next-auth, PWA, SEO). - Added new utility packages: critters, next-circuit-breaker, next-csrf, next-images, next-json-ld. - Integrated Changesets for versioning. - Updated CI/CD workflows and linting configurations. - Fixed numerous linting and type-checking issues across the monorepo.
- Remove legacy NextAuth adapters and resolve workspace version conflicts - Clean up test warning noise and fix tsconfig/jest setups for next-auth - Update Workbox/Terser dependencies in next-pwa to align with workspace - Synchronize root lockfile to reflect nested package resolutions
Fixes `JWT_AUTO_GENERATED_SIGNING_KEY` and `JWT_AUTO_GENERATED_ENCRYPTION_KEY` warnings properly by supplying JWKs directly in the test suite rather than mocking the logger.
ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan Review Summary by QodoModernize monorepo for Next.js 16 and React 19 with comprehensive enhancements and test coverage
WalkthroughsDescription• **Modernized next-transpile-modules for Next.js 13+ support** with native transpilePackages detection and fallback to webpack configuration for older versions • **Comprehensive test coverage additions** across multiple packages including next-transpile-modules, next-csrf, next-session, react-query-auth, and react-virtualized • **Enhanced session handling** with Web API support (getWebSession), improved time parsing with duration units (s, m, h, d), and better separation of concerns • **CSRF security improvements** including token validation from multiple sources (headers, body, query), new error codes for missing/mismatched tokens, and App Router support • **Bug fixes in critters** for stylesheet handling, container detection fallback logic, and security sanitization • **Test framework migrations** from Jest to Vitest and from vitest to Node.js native test runner for better compatibility • **New MDX functionality** with configuration loading, file discovery, node retrieval, path generation, and client-side hydration support • **OAuth implementation refactoring** removing external oauth package dependency with native async/await implementation • **Type definitions and documentation improvements** across multiple packages including PWA plugin types, react-virtualized stubs, and TypeORM adapter types • **Performance optimizations** including cookie instance caching in next-cookies and improved middleware execution in next-connect • **Authentication example implementation** with react-query-auth including mock API server, database, and client functions Diagramflowchart LR
A["Next.js 16<br/>React 19"] -->|Version Detection| B["next-transpile-modules"]
B -->|Native Support| C["transpilePackages"]
B -->|Fallback| D["Webpack Config"]
E["Session Management"] -->|Web APIs| F["getWebSession"]
E -->|Time Parsing| G["Duration Units"]
H["CSRF Security"] -->|Token Sources| I["Headers/Body/Query"]
H -->|Validation| J["Error Codes"]
H -->|App Router| K["verifyCsrfToken"]
L["Test Coverage"] -->|Vitest| M["Jest Migration"]
L -->|Node.js Native| N["Test Runner"]
O["MDX Features"] -->|Config| P["getConfig"]
O -->|Files| Q["getFiles"]
O -->|Nodes| R["getMdxNode"]
O -->|Client| S["useHydrate"]
T["OAuth"] -->|Native| U["Async/Await"]
U -->|Removed| V["oauth Package"]
File Changes1. packages/next-images/test/index.test.ts
|
Code Review by Qodo
1. vitest.config.js not Prettier
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5973bd9187
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (isNext13Plus() && !options.skipNative) { | ||
| logger('Next.js 13+ detected, using native transpilePackages'); | ||
|
|
||
| const existingTranspilePackages = nextConfig.transpilePackages || []; | ||
| const newTranspilePackages = Array.from(new Set([ | ||
| ...(Array.isArray(existingTranspilePackages) ? existingTranspilePackages : [existingTranspilePackages]), | ||
| ...modules | ||
| ])); | ||
|
|
||
| return Object.assign({}, nextConfig, { | ||
| transpilePackages: newTranspilePackages | ||
| }); | ||
| } |
There was a problem hiding this comment.
Preserve resolveSymlinks handling for Next 13+ users
The new isNext13Plus() fast path returns before resolveSymlinks is read, so configs that explicitly pass resolveSymlinks: false now silently lose that behavior on Next 13+ and always fall back to Next’s default symlink resolution. That is a functional regression for linked-workspace/npm-link setups where this option is required to keep transpilation matching the package path, and it changes runtime behavior without any warning.
Useful? React with 👍 / 👎.
| @@ -1,6 +1,6 @@ | |||
| { | |||
| "name": "@opensourceframework/next-transpile-modules", | |||
| "version": "10.0.3", | |||
| "version": "10.0.2", | |||
There was a problem hiding this comment.
Keep package version monotonic in next-transpile-modules
This change decreases the published package version from 10.0.3 to 10.0.2, which breaks normal semver progression and conflicts with the existing changelog state for 10.0.3. Keeping a lower version here can disrupt release automation (for example, generating or attempting to publish an already-used version) and should be corrected before release.
Useful? React with 👍 / 👎.
| import { defineConfig } from "vitest/config" | ||
|
|
||
| export default defineConfig({ | ||
| test: { | ||
| globals: true, | ||
| env: { | ||
| NEXTAUTH_URL: "http://localhost:3000/api/auth", | ||
| }, | ||
| }, | ||
| }) |
There was a problem hiding this comment.
1. vitest.config.js not prettier 📘 Rule violation ✓ Correctness
The newly added vitest.config.js uses double quotes and omits semicolons, contradicting the monorepo Prettier formatting standards. This can cause inconsistent formatting and churn in future diffs.
Agent Prompt
## Issue description
A new file (`vitest.config.js`) was added with formatting that contradicts the repo’s Prettier standards (double quotes and missing semicolons).
## Issue Context
The compliance checklist requires Prettier conventions (2-space indentation, single quotes, semicolons, trailing commas).
## Fix Focus Areas
- vitest.config.js[1-10]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| #!/bin/bash | ||
| # script to sync starters repo wth monorepo. | ||
|
|
||
| set -e # bail on errors | ||
| GLOB=$1 | ||
| IS_CI="${CI:-false}" | ||
| BASE=$(pwd) | ||
| COMMIT_MESSAGE=$(git log -1 --pretty=%B) |
There was a problem hiding this comment.
2. deploy-www.sh misplaced location 📘 Rule violation ⛯ Reliability
A new automation script was added under packages/next-mdx/scripts/ instead of the standard repo-level scripts/ location. This breaks the documented monorepo layout conventions and makes automation harder to discover.
Agent Prompt
## Issue description
A new automation script was added at `packages/next-mdx/scripts/deploy-www.sh`, which conflicts with the documented monorepo layout rule that repo automation should live under the top-level `scripts/` directory.
## Issue Context
This script appears to be repo automation (cloning/pushing to GitHub), and should be placed where contributors expect automation to live.
## Fix Focus Areas
- packages/next-mdx/scripts/deploy-www.sh[1-34]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| const withOptimizedImages = require('../lib'); | ||
|
|
||
| const getNextConfig = (options, webpackOptions = {}) => { |
There was a problem hiding this comment.
3. New *.test.js added 📘 Rule violation ⛯ Reliability
A new test file was added using the .test.js extension rather than the required *.test.ts/*.test.tsx naming pattern. This can break standardized test discovery and violates the monorepo testing filename convention.
Agent Prompt
## Issue description
New test coverage was added as `*.test.js`, but the repo’s compliance requirement is to name new tests `*.test.ts` or `*.test.tsx`.
## Issue Context
The affected file is newly added under `__tests__` and should follow the standard naming convention so test tooling discovers tests consistently across the monorepo.
## Fix Focus Areas
- packages/next-optimized-images/__tests__/index.test.js[1-116]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| # Specific test file | ||
| pnpm --filter @opensourceframework/next-csrf vitest run src/index.test.ts |
There was a problem hiding this comment.
4. Docs invoke vitest run 📘 Rule violation ⛯ Reliability
The new contributing guide instructs running Vitest directly (vitest run) instead of using the package's own test script. This can bypass package-specific test configuration and violates the requirement to run tests via each package’s test script.
Agent Prompt
## Issue description
Documentation instructs contributors to run `vitest run` directly, which conflicts with the compliance requirement to run tests via each package’s own `test` script.
## Issue Context
Direct `vitest` invocation can bypass package-level scripts/configuration and creates inconsistent instructions across the monorepo.
## Fix Focus Areas
- packages/critters/CONTRIBUTING.md[217-218]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| export default function oAuthClient(provider) { | ||
| if (provider.version?.startsWith("2.")) { | ||
| // Handle OAuth v2.x | ||
| const authorizationUrl = new URL(provider.authorizationUrl) | ||
| const basePath = authorizationUrl.origin | ||
| const authorizePath = authorizationUrl.pathname | ||
| const accessTokenPath = new URL(provider.accessTokenUrl).pathname | ||
| const oauth2Client = new OAuth2( | ||
| provider.clientId, | ||
| provider.clientSecret, | ||
| basePath, | ||
| authorizePath, | ||
| accessTokenPath, | ||
| provider.headers | ||
| ) | ||
| oauth2Client.getOAuthAccessToken = getOAuth2AccessToken | ||
| oauth2Client.get = getOAuth2 | ||
| return oauth2Client | ||
| } | ||
| // Handle OAuth v1.x | ||
| const oauth1Client = new OAuth( | ||
| provider.requestTokenUrl, | ||
| provider.accessTokenUrl, | ||
| provider.clientId, | ||
| provider.clientSecret, | ||
| provider.version || "1.0", | ||
| provider.callbackUrl, | ||
| provider.encoding || "HMAC-SHA1" | ||
| ) | ||
|
|
||
| // Promisify get() and getOAuth2AccessToken() for OAuth1 | ||
| const originalGet = oauth1Client.get.bind(oauth1Client) | ||
| oauth1Client.get = (...args) => { | ||
| return new Promise((resolve, reject) => { | ||
| originalGet(...args, (error, result) => { | ||
| if (error) { | ||
| return reject(error) | ||
| } | ||
| resolve(result) | ||
| }) | ||
| }) | ||
| } | ||
| const originalGetOAuth1AccessToken = | ||
| oauth1Client.getOAuthAccessToken.bind(oauth1Client) | ||
| oauth1Client.getOAuthAccessToken = (...args) => { | ||
| return new Promise((resolve, reject) => { | ||
| // eslint-disable-next-line camelcase | ||
| originalGetOAuth1AccessToken( | ||
| ...args, | ||
| (error, oauth_token, oauth_token_secret, params) => { | ||
| if (error) { | ||
| return reject(error) | ||
| } | ||
|
|
||
| resolve({ | ||
| // TODO: Remove, this is only kept for backward compativility | ||
| // These are not in the OAuth 1.x spec | ||
| accessToken: oauth_token, | ||
| refreshToken: oauth_token_secret, | ||
| results: params, | ||
|
|
||
| oauth_token, | ||
| oauth_token_secret, | ||
| params, | ||
| }) | ||
| } | ||
| ) | ||
| }) | ||
| return { | ||
| getOAuthAccessToken: (code, codeVerifier) => getOAuth2AccessToken(code, provider, codeVerifier), | ||
| get: (accessToken, results) => getOAuth2(provider, accessToken, results) | ||
| } |
There was a problem hiding this comment.
5. Oauth2 client api mismatch 🐞 Bug ✓ Correctness
In next-auth, oAuthClient() now returns a minimal object for OAuth2 providers that omits required methods and changes method signatures, but the OAuth sign-in/callback code still calls the old API, causing runtime TypeErrors and broken OAuth2 authentication.
Agent Prompt
## Issue description
`oAuthClient()` for OAuth2 providers returns only `{ getOAuthAccessToken(code, codeVerifier), get(accessToken, results) }`, but the OAuth sign-in and callback flows still call `getAuthorizeUrl()` / `useAuthorizationHeaderforGET()` and pass the legacy argument shapes. This causes runtime failures and breaks OAuth2 authentication.
## Issue Context
The refactor removed the `oauth` package dependency, but the rest of the codebase still assumes the previous OAuth2 client surface area.
## Fix Focus Areas
- packages/next-auth/src/server/lib/oauth/client.js[11-17]
- packages/next-auth/src/server/lib/signin/oauth.js[14-21]
- packages/next-auth/src/server/lib/oauth/callback.js[38-63]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| async getOAuthRequestToken(params = {}) { | ||
| // Implement OAuth 1.0a request token logic | ||
| throw new Error("OAuth 1.0a is not yet fully implemented in the native client. Please use OAuth 2.0 or contact maintainers.") | ||
| } | ||
|
|
||
| async getOAuthAccessToken(oauth_token, oauth_token_secret, oauth_verifier) { | ||
| // Implement OAuth 1.0a access token logic | ||
| throw new Error("OAuth 1.0a is not yet fully implemented in the native client.") | ||
| } | ||
|
|
||
| async get(url, oauth_token, oauth_token_secret) { | ||
| // Implement OAuth 1.0a authenticated request | ||
| throw new Error("OAuth 1.0a is not yet fully implemented in the native client.") |
There was a problem hiding this comment.
6. Oauth1 client unimplemented 🐞 Bug ✓ Correctness
OAuth 1.x authentication is broken because the new OAuth1Client throws "not yet fully implemented" for request-token/access-token/signed requests, while OAuth1 providers (e.g. Twitter) and the OAuth flow still rely on these methods.
Agent Prompt
## Issue description
OAuth 1.0a is currently a stub that throws errors for all required operations. OAuth1 providers (e.g., Twitter) still exist and the sign-in/callback code calls OAuth1 methods, so OAuth1 authentication will always fail.
## Issue Context
The OAuth refactor removed the dependency that previously implemented OAuth1. The codebase still includes OAuth1 providers and flows.
## Fix Focus Areas
- packages/next-auth/src/server/lib/oauth/client.js[215-238]
- packages/next-auth/src/server/lib/signin/oauth.js[40-48]
- packages/next-auth/src/server/lib/oauth/callback.js[71-87]
- packages/next-auth/src/providers/twitter.js[1-12]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| "name": "@opensourceframework/next-transpile-modules", | ||
| "version": "10.0.3", | ||
| "version": "10.0.2", | ||
| "license": "MIT", |
There was a problem hiding this comment.
7. Version/changelog mismatch 🐞 Bug ⛯ Reliability
@opensourceframework/next-transpile-modules has inconsistent version metadata: package.json is 10.0.2 while the package CHANGELOG shows 10.0.3 as the latest entry and the changeset requests a minor bump, risking incorrect versioning/release output.
Agent Prompt
## Issue description
`packages/next-transpile-modules/package.json` declares version `10.0.2`, but the package CHANGELOG documents `10.0.3` as the latest entry and the changeset requests a `minor` bump for this PR. This inconsistency can break or confuse release/version generation.
## Issue Context
The repo uses Changesets for versioning, and package versions/changelogs should remain consistent and monotonic.
## Fix Focus Areas
- packages/next-transpile-modules/package.json[1-4]
- packages/next-transpile-modules/CHANGELOG.md[1-6]
- .changeset/fix-pr23-feedback.md[1-14]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
|
3 similar comments
|
|
|
|
|
|
- OAuth2 client: add missing getAuthorizeUrl() and useAuthorizationHeaderforGET() methods - OAuth2 client: support legacy argument signatures from signin/callback flows - getOAuthAccessToken(code, provider, codeVerifier) and getOAuthAccessToken(code, codeVerifier) - get(provider, accessToken, results) and get(accessToken, results) - next-transpile-modules: sync package.json version (10.0.2 -> 10.0.3) to match CHANGELOG
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
|
|
Superseded by #59 (squash merge of all modernization PRs). Changes included in main. |
Closes #22 (roadmap).
nextto ^16.0.0 andreact/react-domto ^19.0.0 indevDependencies.peerDependenciesto support Next.js 16 and React 19.