test(vite): narrow and validate Vite 7/8 support#367
Conversation
The SQL provider was updated to use context.configDir but the mongo provider was missed, causing watcher/loader path divergence when cwd differs from the config directory.
…onfigDir - Switch config-loader from node:path to pathe for consistency with the rest of the tooling layer. - Resolve .ts contract paths inside load() via context.configDir instead of capturing process.cwd() at config-definition time, so the watcher and loader always reference the same file.
The paths branch omitted the config file from the watch set, so edits to prisma-next.config.ts (e.g. changing paths or swapping provider) would not trigger re-emit. Also surface a partial-coverage warning when loadConfig fails instead of silently falling back.
Close D1 from the PR #356 review by driving a real Vite dev server through both scenarios that were previously only unit-mocked: modifying `contract.prisma` re-emits the contract, and editing the config to swap the declared PSL input re-emits against the new file.
Align with the Mongo PSL provider and with the parser step's sourceId. The absolute form stays accessible via meta.absoluteSchemaPath for downstream consumers that need it.
Collapse the ~20-line inline provider that postgres and mongo facades each build around a dynamic import of the user's `contract.ts`. The logic (path resolution, pathToFileURL, default-export extraction) is family-agnostic, so each contract-ts package exposes it as a sibling to typescriptContract.
- handleTrackedFileChange now runs ctx.file through pathe.resolve before comparing against watchedFiles / ignoredOutputFiles, so symlinked or case-folded paths line up with the resolved entries. - resolveContractOutputFiles no longer falls back to the hardcoded 'src/prisma/contract.json' when contract.output is missing. The filter simply skips; defineConfig() guarantees output is present in the happy path, and raw-object configs get a clean no-op instead of a path the CLI never actually writes.
…ceContext Left over from the split that moved configDir out of ContractSourceContext into ContractSourceEnvironment — the context builder no longer needs it.
…uts' into tml-2277-vite-plugin-watch-behavior
…watch-behavior # Conflicts: # packages/1-framework/3-tooling/cli/src/config-path-validation.ts # packages/1-framework/3-tooling/cli/test/config-loader.test.ts # packages/1-framework/3-tooling/vite-plugin-contract-emit/README.md # packages/1-framework/3-tooling/vite-plugin-contract-emit/src/plugin.ts # packages/1-framework/3-tooling/vite-plugin-contract-emit/test/plugin.test.ts
Extend the Vite plugin HMR integration suite with a PSL recovery journey. The new test proves a bad edit preserves the last good artifacts on disk and that a subsequent valid edit re-emits both contract files. Refs TML-2293
Add two short comments to the Vite HMR recovery integration test so the intentional failure phase and the expected recovery phase are easier to scan in review.
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (1)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including ⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAdds CI testing for Vite plugin compatibility (Vite 7 and 8), tightens the plugin's peer dependency to those versions, introduces a root script to run the Vite plugin tests, expands the integration HMR e2e tests to run against both Vite 7 and 8, and includes minor test and formatting tweaks. Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
@prisma-next/mongo-runtime
@prisma-next/family-mongo
@prisma-next/sql-runtime
@prisma-next/family-sql
@prisma-next/middleware-telemetry
@prisma-next/mongo
@prisma-next/extension-paradedb
@prisma-next/extension-pgvector
@prisma-next/postgres
@prisma-next/sql-orm-client
@prisma-next/sqlite
@prisma-next/target-mongo
@prisma-next/adapter-mongo
@prisma-next/driver-mongo
@prisma-next/contract
@prisma-next/utils
@prisma-next/config
@prisma-next/errors
@prisma-next/framework-components
@prisma-next/operations
@prisma-next/ts-render
@prisma-next/contract-authoring
@prisma-next/ids
@prisma-next/psl-parser
@prisma-next/psl-printer
@prisma-next/cli
@prisma-next/emitter
@prisma-next/migration-tools
prisma-next
@prisma-next/vite-plugin-contract-emit
@prisma-next/runtime-executor
@prisma-next/mongo-codec
@prisma-next/mongo-contract
@prisma-next/mongo-value
@prisma-next/mongo-contract-psl
@prisma-next/mongo-contract-ts
@prisma-next/mongo-emitter
@prisma-next/mongo-schema-ir
@prisma-next/mongo-query-ast
@prisma-next/mongo-orm
@prisma-next/mongo-query-builder
@prisma-next/mongo-lowering
@prisma-next/mongo-wire
@prisma-next/sql-contract
@prisma-next/sql-errors
@prisma-next/sql-operations
@prisma-next/sql-schema-ir
@prisma-next/sql-contract-psl
@prisma-next/sql-contract-ts
@prisma-next/sql-contract-emitter
@prisma-next/sql-lane-query-builder
@prisma-next/sql-relational-core
@prisma-next/sql-builder
@prisma-next/target-postgres
@prisma-next/target-sqlite
@prisma-next/adapter-postgres
@prisma-next/adapter-sqlite
@prisma-next/driver-postgres
@prisma-next/driver-sqlite
commit: |
Co-authored-by: Alberto Schiabel <jkomyno@users.noreply.github.com> Signed-off-by: Alberto Schiabel <jkomyno@users.noreply.github.com>
Signed-off-by: Alberto Schiabel <jkomyno@users.noreply.github.com>
SevInf
left a comment
There was a problem hiding this comment.
I would prefer we'd make it easier to run tests loсally. Right now, specific vite version are hardcoded in CI, pnpm outdated and renovate will not find them and we are almost certainly will forget to update them in time.
Additionally, running it locally requires copying very specific command from a GH Workflow and then not forgetting to undo your changes before you commit.
My suggestion is to do it that way:
- Add both versions to our dependencies explicitly under different aliases.
- Importing both in the test file:
import * as vite7 from 'vite7'
import * as vite8 from 'vite8'- Wrapping existing tests into a function that accepts generalized version of
vite.createServeras an input - run those tests over both
vite7.createServerandvite8.createServer
…-matrix # Conflicts: # packages/1-framework/3-tooling/cli/src/config-path-validation.ts # packages/1-framework/3-tooling/vite-plugin-contract-emit/src/plugin.ts # packages/1-framework/3-tooling/vite-plugin-contract-emit/test/plugin.test.ts
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/1-framework/3-tooling/vite-plugin-contract-emit/README.md (1)
14-14: Simplify the compatibility note by removing internal implementation detail.The phrase "there is no Vite-8-specific code path today, so the support matrix exists to catch future hook or overlay regressions early" is internal implementation reasoning that doesn't materially affect how users interact with the plugin. As per coding guidelines, user-facing package READMEs should avoid internal implementation detail unless it materially affects usage.
📝 Simplified compatibility note
-- Compatibility note: the current implementation uses the same `configureServer` and `handleHotUpdate` flow on Vite 7 and Vite 8; there is no Vite-8-specific code path today, so the support matrix exists to catch future hook or overlay regressions early +- Compatibility note: the plugin uses the same `configureServer` and `handleHotUpdate` flow on both Vite 7 and Vite 8Or remove it entirely if the implementation approach doesn't affect usage decisions.
As per coding guidelines: "For user-facing packages, keep README.md focused on what the package does, when to use it, and a few concrete examples. Avoid internal implementation detail unless it materially affects usage"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/1-framework/3-tooling/vite-plugin-contract-emit/README.md` at line 14, The compatibility note in README.md includes internal implementation detail ("there is no Vite-8-specific code path today, so the support matrix exists to catch future hook or overlay regressions early"); remove that clause or replace it with a short, user-focused statement such as "Compatibility: works with Vite 7 and Vite 8" so the README only communicates compatibility to users and omits internal reasoning; edit the line containing the compatibility note to delete the internal explanation and keep a concise, user-facing compatibility message.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 188-209: The new CI job "test-vite-support" is missing the
TEST_TIMEOUT_MULTIPLIER environment setting used by other test jobs, causing
flakiness; modify the test-vite-support job to include an env block that sets
TEST_TIMEOUT_MULTIPLIER: 2 (same as other CI test jobs) so the Vite matrix runs
use the shared timeout multiplier; locate the job by the name test-vite-support
in the workflow and add the env entry alongside existing keys to ensure the HMR
suite uses the increased timeout under CI load.
In `@test/integration/test/vite-plugin.hmr.e2e.test.ts`:
- Around line 443-557: Remove the duplicated "it('preserves the last good
artifacts after a bad PSL edit and recovers on the next good edit')" test block
(keep only the intended single copy), replace the hardcoded setTimeout delay
(new Promise(resolve => setTimeout(resolve, 100))) with the shared short timeout
helper from `@prisma-next/test-utils` (use the project's timeouts constant, e.g.
timeouts.fileWatchDebounce or a similar named helper), and avoid waiting the
full long TypeScript compilation timeout on the passing path by changing the
waitForFileChange calls that pass initialJsonStats.mtimeMs /
initialDtsStats.mtimeMs with timeouts.typeScriptCompilation to use a shorter
helper timeout (or a smaller explicit timeout constant from timeouts) for the
success path; adjust calls to waitForFileChange, readJsonFileWhenReady,
replaceInFileOrThrow and server.watcher.emit accordingly so the test is no
longer duplicated and uses the shared timeout helpers instead of raw numbers.
---
Nitpick comments:
In `@packages/1-framework/3-tooling/vite-plugin-contract-emit/README.md`:
- Line 14: The compatibility note in README.md includes internal implementation
detail ("there is no Vite-8-specific code path today, so the support matrix
exists to catch future hook or overlay regressions early"); remove that clause
or replace it with a short, user-focused statement such as "Compatibility: works
with Vite 7 and Vite 8" so the README only communicates compatibility to users
and omits internal reasoning; edit the line containing the compatibility note to
delete the internal explanation and keep a concise, user-facing compatibility
message.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 542d438a-2028-411f-ba89-8eeacd3ee72c
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
.github/workflows/ci.ymldocs/reference/framework-integration-analysis.mdpackage.jsonpackages/1-framework/3-tooling/cli/src/config-path-validation.tspackages/1-framework/3-tooling/vite-plugin-contract-emit/README.mdpackages/1-framework/3-tooling/vite-plugin-contract-emit/package.jsonpackages/1-framework/3-tooling/vite-plugin-contract-emit/test/plugin.test.tstest/integration/README.mdtest/integration/package.jsontest/integration/test/vite-plugin.hmr.e2e.test.ts
💤 Files with no reviewable changes (1)
- packages/1-framework/3-tooling/cli/src/config-path-validation.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@test/integration/package.json`:
- Around line 73-75: The test's Vite runtime and the plugin's resolved peer
dependency are mismatched: the package.json alias "vite" points to the catalog
(v7) while "vite8" points to npm:vite@8.0.9 and the HMR test calls
vite8.createServer(), but `@prisma-next/vite-plugin-contract-emit` is resolving to
Vite 7; fix by updating the package.json "vite" entry to "npm:vite@8.0.9" (to
match "vite8") or modify the test/vite.config.ts to explicitly import/pass the
Vite instance from the vite8 alias into the plugin (so the plugin runs against
the same Vite instance used by vite8.createServer()).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 2dd99e4b-adf5-4ffa-8c66-0b13c0dbf68f
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (4)
.github/workflows/ci.ymltest/integration/README.mdtest/integration/package.jsontest/integration/test/vite-plugin.hmr.e2e.test.ts
✅ Files skipped from review due to trivial changes (1)
- test/integration/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
- .github/workflows/ci.yml
- test/integration/test/vite-plugin.hmr.e2e.test.ts
| "vite": "catalog:", | ||
| "vite7": "npm:vite@7.3.1", | ||
| "vite8": "npm:vite@8.0.9", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect catalog-resolved vite version and peer-dep satisfaction
cat pnpm-workspace.yaml 2>/dev/null | sed -n '1,120p'
fd -a 'package.json' packages/1-framework/3-tooling/vite-plugin-contract-emit -x cat {}
# Find imports of 'vite' (unaliased) inside the HMR test
rg -nP "from ['\"]vite(7|8)?['\"]" test/integration/test/vite-plugin.hmr.e2e.test.tsRepository: prisma/prisma-next
Length of output: 2175
🏁 Script executed:
grep -n "vite-plugin-contract-emit\|from '@prisma-next" test/integration/test/vite-plugin.hmr.e2e.test.ts | head -20Repository: prisma/prisma-next
Length of output: 115
🏁 Script executed:
# Find test-utils package and check its dependencies
find . -path '*/test-utils/package.json' -type f | head -1 | xargs cat | grep -A 20 '"dependencies"'
# Also check if vite-plugin-contract-emit is imported anywhere in test-utils
rg -l "vite-plugin-contract-emit" test/ --type json --type tsRepository: prisma/prisma-next
Length of output: 271
🏁 Script executed:
# Check the HMR test to see if it references a vite config
head -30 test/integration/test/vite-plugin.hmr.e2e.test.ts
# Check the vite-plugin vite.config.ts that uses the plugin
cat test/integration/test/fixtures/cli/cli-e2e-test-app/fixtures/vite-plugin/vite.config.ts | head -40Repository: prisma/prisma-next
Length of output: 1266
🏁 Script executed:
# Check how the HMR test uses vite7/vite8 - does it swap which is used?
rg -n "vite7|vite8" test/integration/test/vite-plugin.hmr.e2e.test.ts | head -30Repository: prisma/prisma-next
Length of output: 283
Fix vite catalog version to match vite8 alias, or ensure plugin explicitly imports the correct Vite instance.
When the HMR test runs vite8.createServer(), it uses vite@8.0.9, but @prisma-next/vite-plugin-contract-emit (imported in the vite.config.ts) resolves its peer dependency to vite@7.3.1 (from the catalog). This creates a version mismatch: the plugin code runs against Vite 7 while the server instance is Vite 8. Update the catalog vite entry to 8.0.9 or refactor the test to explicitly pass the Vite instance to the plugin instead of relying on peer dependency resolution.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@test/integration/package.json` around lines 73 - 75, The test's Vite runtime
and the plugin's resolved peer dependency are mismatched: the package.json alias
"vite" points to the catalog (v7) while "vite8" points to npm:vite@8.0.9 and the
HMR test calls vite8.createServer(), but `@prisma-next/vite-plugin-contract-emit`
is resolving to Vite 7; fix by updating the package.json "vite" entry to
"npm:vite@8.0.9" (to match "vite8") or modify the test/vite.config.ts to
explicitly import/pass the Vite instance from the vite8 alias into the plugin
(so the plugin runs against the same Vite instance used by
vite8.createServer()).
There was a problem hiding this comment.
🧩 Analysis chain
Let me gather the necessary information before planning the changes.
🏁 Script executed:
#!/bin/bash
# Check catalog vite version
grep -A 5 -B 2 '"vite"' pnpm-workspace.yaml 2>/dev/null | head -30
# Check vite.config.ts fixture used by the HMR test
fd 'vite.config.ts' test/ -x cat {}
# Full HMR test file
cat test/integration/test/vite-plugin.hmr.e2e.test.ts
# Check plugin source to see how it imports/uses vite
fd 'src' packages/1-framework/3-tooling/vite-plugin-contract-emit --type d
fd '*.ts' packages/1-framework/3-tooling/vite-plugin-contract-emit/src -x cat {}
Length of output: 16448
🏁 Script executed:
#!/bin/bash
# Get catalog vite version
grep -n "vite" pnpm-workspace.yaml | head -20
# Get plugin source files using glob
find packages/1-framework/3-tooling/vite-plugin-contract-emit/src -name "*.ts" | xargs cat
# Check what vite APIs the plugin imports
rg -n "from ['\"]vite['\"]" packages/1-framework/3-tooling/vite-plugin-contract-emit/
# Also check the fixture vite.config.ts files copied during tests
find test/integration -name "vite.config.ts" | xargs cat
Length of output: 14736
@jkomyno — after digging into the plugin source, the fix is not actually needed. My original review comment was incorrect, and I apologize for the confusion.
Here's what the deeper analysis found:
The plugin only uses a type-only import from vite:
import type { Plugin, ViteDevServer } from 'vite';import type is completely erased at compile/build time — zero runtime Vite code is imported by the plugin. There is no runtime coupling to any specific Vite version.
At runtime, the plugin is just a plain object with hook functions (configResolved, configureServer, handleHotUpdate). These hooks receive their arguments (including the dev server instance) injected by whichever Vite version calls them — vite7.createServer injects Vite 7 objects, vite8.createServer injects Vite 8 objects. The plugin is version-agnostic at runtime.
The vite.config.ts fixture uses import { defineConfig } from 'vite', but defineConfig is essentially (config) => config in both Vite 7 and 8 — no behavioral difference regardless of which version resolves it.
The test structure with ViteServerLike duck-typing and CreateServerLike as a function parameter is correctly designed to avoid any static coupling to a specific Vite version. The current code is sound as-is.
Would you like me to create an issue to track removal of this false-positive concern, or should I simply resolve this review comment?
🧠 Learnings used
Learnt from: igalklebanov
Repo: prisma/prisma-next PR: 68
File: package.json:5-5
Timestamp: 2026-01-02T11:49:27.327Z
Learning: In package.json, when Corepack is involved, the packageManager field should use Corepack's hash format (hexadecimal, sha512.<hex>). This hex-based Corepack format is the standard representation of the hash; the base64 form (sha512-<base64>) is also a valid representation of the same hash but Corepack's hex format is the correct one to rely on in this field. Ensure you use the Corepack hex format for packageManager whenever Corepack is used to generate or verify integrity.
Learnt from: igalklebanov
Repo: prisma/prisma-next PR: 103
File: packages/1-framework/1-core/migration/control-plane/package.json:15-15
Timestamp: 2026-01-08T11:50:34.703Z
Learning: Guideline: If a repo configures tsc to emit to non-standard directories (e.g., dist-tsc and dist-tsc-prod) to avoid conflicts with other build tools, ensure clean scripts remove those directories. This applies broadly to package.json files that define npm scripts. Actionable checks:
- Verify package.json scripts include a clean script that deletes dist( or dist-tsc / dist-tsc-prod) directories before builds.
- Confirm tsc is configured to emit to dist-tsc or dist-tsc-prod in base and prod configurations, respectively.
- If such emission paths exist, add them to .gitignore if appropriate and to clean tasks to prevent stray emissions from affecting builds.
- For prisma-next or similar monorepos, ensure each relevant package.json maintaining build scripts includes removal of dist-tsc and dist-tsc-prod during clean.
Example addition to scripts:
"clean": " rm -rf dist dist-tsc dist-tsc-prod || true "
Rationale: Prevents accidental tsc emissions from interfering with tsup/tsdown outputs and keeps clean builds deterministic.
Learnt from: igalklebanov
Repo: prisma/prisma-next PR: 103
File: packages/2-sql/2-authoring/contract-ts/package.json:15-15
Timestamp: 2026-01-08T11:52:39.060Z
Learning: TypeScript outputs are configured to emit to dist-tsc (regular builds via base tsconfig) and dist-tsc-prod (production builds via prod tsconfig). Ensure clean scripts remove dist, dist-tsc, and dist-tsc-prod directories so a full clean is performed. This guideline should apply to package.json files that define a clean script across the repository.
Learnt from: wmadden
Repo: prisma/prisma-next PR: 191
File: packages/1-framework/2-authoring/psl-parser/package.json:33-34
Timestamp: 2026-03-01T14:44:49.349Z
Learning: In the prisma-next repository, ensure that for any package, package.json exports define the public subpath API while tsdown.config.ts entry settings specify the source files to build. Both are required and cannot replace one another. When adding new subpath exports (e.g., ./parser, ./types), configure both package.json exports and the corresponding tsdown.config.ts entry.
Summary
@prisma-next/vite-plugin-contract-emitpeer support to Vite 7 and 8Testing
pnpm test:vite-plugin@prisma-next/integration-teststovite@8.0.9locally and reranpnpm test:vite-pluginTracking
Summary by CodeRabbit
New Features
Tests
Documentation
Chores