| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
feat: an application depends on one Prisma package (ADR 242) (#29864) ## What changes for someone using Prisma Today, an application that talks to Postgres installs a long list of our packages: ```jsonc { "dependencies": { "@prisma-next/postgres": "...", "@prisma-next/sql-runtime": "...", "@prisma-next/sql-orm-client": "...", "@prisma-next/target-postgres": "...", "@prisma-next/adapter-postgres": "...", "@prisma-next/sql-contract": "..." // ...a dozen more } } ``` After this PR, it installs one: ```jsonc { "dependencies": { "@prisma/orm-postgres": "0.16.0" } } ``` Everything else arrives as that package's own dependencies. Three of our example apps are converted in this PR to prove it — one per database — and each has exactly one Prisma package in its `dependencies`. This implements [ADR 242](https://github.com/prisma/prisma/pull/29852), which is already merged. ## What gets published 17 packages, all under the `@prisma` scope: - **3 database packages** — `@prisma/orm-postgres`, `orm-sqlite`, `orm-mongo`. An application installs exactly one. We call these *facades*: each is a small package that wires its database together and re-exports everything an application needs. - **6 extension packs** — PostGIS, pgvector, ParadeDB, Supabase, arktype-json, middleware-cache. Optional, installed alongside a database package. - **7 platform packages** — the framework, the toolchain, one per database family, one per database target. Applications never install these directly; they arrive as dependencies. Extension authors do install them. - **the `prisma` command**, as a bin-only package. Every other workspace package — around 50 of them — stops being published. They still exist in the repo as the unit we organise code in; they just stop having a life on the registry. **This PR does not make that switch yet.** It builds and proves the new surface while leaving today's publish list exactly as it is. Flipping it is a separate change. ## The problem this design has to avoid A published package can't depend on packages that won't exist on the registry. So each published package *contains a compiled copy* of the internal packages it covers. That creates a trap. If one application ends up with the same code twice — once inside a published package, once as its own package — then classes, registries, and anything compared by reference exist twice too. An `instanceof` check quietly returns false. Nothing crashes, nothing fails to compile, and both copies behave identically in isolation. You find out much later, somewhere unrelated. So the rule the whole design follows is: **every piece of internal code is published from exactly one package.** Concretely, that means: - Each published package is built in one pass, so code shared between its own entry points exists once. Verified from the build's source maps: no module appears in more than one chunk, in any published package. - When one published package needs code from another, it imports it as a real dependency rather than compiling in a second copy. - A facade re-exports from the platform packages; it never carries its own copy. `@prisma/orm-postgres/orm-client` and `@prisma/orm-family-sql/orm-client` are two names for the same object, and there's a test that asserts exactly that from installed tarballs. - One table in `packages/0-shared/publish-surface` maps every internal package to where it's published. The build, the code generator, and the lint checks all read it, so there's one answer to "where does this live" rather than three that can drift. ## Generated code follows the application Prisma writes imports into your project — contract types and migration files. Those imports have to name packages your project actually depends on, or they won't resolve. So the generator now reads the `package.json` next to the config it's generating for. A project that depends on `@prisma/orm-postgres` gets imports from that package. A project on today's names keeps today's names. Nothing to configure, because the manifest already says which it is. Contract hashes are unaffected, and that isn't an assumption — hashes are computed from a structure that import text never enters, and there's a test asserting the hash is identical across naming schemes *while* the emitted imports demonstrably differ. ## What stops the trap coming back Two checks, because the failure is silent and won't show up in a test suite: - Every example app and test project must use one naming scheme, not a mix. `lint-single-import-root` scans them and fails the build if any project imports from both, since that's the situation that loads code twice. - `lint-consumer-internal-imports` counts how many internal-package imports remain in those projects and compares against a committed number. It fails if the number goes up (someone added one) and also if it goes down without the number being updated (so improvements get locked in). Target is zero. The build itself also refuses to proceed if the published-package map would put one module in two places, or if a published package's `package.json` no longer matches what its code actually needs. ## Reading this PR It's large — 257 files — because it's a migration. The commits are grouped and meant to be read in order: 1. **Platform packages** — the build mechanism, and the seven platform packages it produces. 2. **Database packages, extension packs, the `prisma` command** — completes the set of 17. 3. **Generated imports become configurable** — one place decides which names get written, with today's names still the default. 4. **Database-family symmetry, publishing the map, the identity checks.** 5. **One package per application** — the three converted examples, the re-exports they proved necessary, and the counting check. 6. **Migration files follow the project too.** One thing worth knowing while reading: re-exporting a package republishes all of its sub-paths, not just the one that was needed. This PR adds 115 published sub-paths across the three database packages. Two candidates were dropped for exactly that reason — see below. ## Alternatives considered **Let an application install platform packages alongside its facade.** Nothing would need re-exporting and the facades would stay thinner. Rejected: an application would again juggle several Prisma dependencies whose correct combination it maintains by hand, and getting it wrong — upgrading one and not the other — produces the silent two-copies failure above. Re-exporting costs a generated line and nothing at runtime. **Re-export everything an application might plausibly want.** Rejected in review: because re-exporting brings a package's entire sub-path surface, generosity is expensive and hard to undo. Migration tooling (54 sub-paths) was dropped because its only users are extension packs, which install platform packages anyway; the SQL driver re-export was dropped because nothing imported it at all. What remains is what a converted example actually needed. **Flip the publish list in this same PR.** Rejected: it would mix "does the new surface work" with "is it safe to stop publishing 50 packages" in one review. The switch is mechanical once this lands, and gets its own change. ## Verification `build`, `typecheck` (156 tasks), `test:packages` (1077 files / 14087 tests), `test:e2e`, `lint`, `lint:deps`, `lint:docs`, `lint:manifests`, `check:publish-deps`, `check:clean-tree`, `lint:casts` and `lint:throws` (no new instances), `test:scripts`, coverage, the tarball-install suites, and regenerating every committed artifact leaves the tree unchanged. Known-unstable and unrelated to this change: the `relation-mode-gh-*` port suites (TML-3140), and several test timeouts that are too tight under load. ## Follow-ups TML-3124 switch the publish list · TML-3127 build cache can validate a stale published package on CI · TML-3140 unstable port suites · TML-3141 a test-helper sub-path reaches a package that is never published. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added consolidated public ORM packages for PostgreSQL, MongoDB, SQLite, framework tooling, database targets, and extensions. - Generated contracts, migrations, and scaffolds now adapt imports to the consuming project’s package surface. - Added facade-provided `prisma-next` CLI access and consolidated migration entrypoints. - **Documentation** - Updated installation, package naming, public entrypoint, and migration scaffolding guidance. - **Tests** - Added coverage for package installation, exports, CLI behavior, module identity, and import compatibility. - **Chores** - Added checks preventing incompatible internal and public package imports. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 1 个月前 | |
feat(cli)!: stop publishing the prisma-next CLI — the unified prisma-cli replaces it (#30005) ## At a glance Before this PR, a Prisma Next user installed `prisma-next` from npm and their project looked like this: ```bash prisma-next db update ``` ```ts // prisma-next.config.ts import { defineConfig } from '@prisma/orm-postgres/config'; export default defineConfig({ contract: './contract.ts', output: './generated', }); ``` After this PR, this repo publishes no CLI binary at all. Users install `@prisma/cli@next` (the unified Prisma CLI, built in the prisma-cli repo) and run: ```bash prisma-cli db update ``` ```ts // prisma.config.ts import { defineConfig } from '@prisma/cli-engine'; import { defineConfig as ormConfig } from '@prisma/orm-postgres/config'; export default defineConfig({ orm: ormConfig({ contract: './contract.ts', output: './generated', }), }); ``` Same commands, same behaviour — the ORM commands this repo builds are mounted into the unified CLI as its `orm` command family. ## The decision Stop publishing a CLI from this repo, and delete the command-line shell that made publishing one possible. Some context for anyone who hasn't followed the port series: the ORM CLI used to be a commander program in this repo — commander parsed the flags, per-command renderers wrote styled output to stdout, and a `handleResult()` helper mapped results to exit codes. Over the previous PRs, every command was re-implemented as a command definition for `@prisma/cli-engine`, the shared CLI framework that the unified `prisma-cli` binary is built on. The engine parses arguments, prints help, renders each command's result envelope, and owns the exit code. That left the commander shell and the published `prisma-next` bin as duplicates of things the engine and the unified CLI already do. This PR removes both. The one deliberate survivor is the migration-file runtime: user-authored `migration.ts` files execute through their own small clipanion CLI (`MigrationCLI.run`) with a 0/1/2 exit scheme. That is a public contract of authored migrations, not part of the shell, so it stays — and a dedicated test now pins the exit scheme so the cutover cannot silently change it. ## What the PR does, step by step **1. The published bin goes away; a workspace-local bin stays.** `packages/9-public/prisma-next` (the bin-only shim package from ADRs 211/242) is deleted, and the public facade packages no longer declare launcher bins. `@internal/cli` keeps a workspace-local `prisma-next` bin pointing at `dist/bin.mjs` — a thin engine entry (`runOrmCli(process)`) that mounts the same 22 command paths the unified CLI mounts — so the repo's examples, dev flows, and spawn smoke tests keep working without a published package. The "install the CLI" journey now belongs to the unified CLI. **2. The commander shell is deleted.** Every command runs as an engine definition under `src/orm/`. Commander, the renderers, `handleResult`, the global-flag resolver, the shutdown handler, and the help formatter are gone; the engine provides all of it. **3. The legacy tests are re-expressed on the engine harness.** Commander-era tests asserted styled stdout, which no longer exists here. They were ported to `createTestCli`, the in-process engine harness, asserting data: the settled result envelope, emitted events, and the exit code — no stdout parsing, no snapshots. Pure formatting tests became presentation-model data assertions or were deleted with a per-file reason recorded in the porting ledger (a legacy test could only be deleted when the behaviour died with the shell or an engine test with the same name covers it). One suite, `cli.bin-smoke.e2e.test.ts`, still spawns the real bin to pin startup, dispatch, exit-code surfacing, and the telemetry sender spawn. **4. Config consolidates on `prisma.config.ts`, with a deprecation path.** The unified CLI reads `prisma.config.ts` in the nested shape shown above (`defineConfig({ orm: ormConfig({ … }) })` from `@prisma/cli-engine`). All 226 config files in this repo were renamed and rewrapped. The loader prefers the new filename and shape, and still accepts the old `prisma-next.config.*` filename and the old flat shape, each with a stderr deprecation warning (`CONFIG.DEPRECATED_FILENAME`, `CONFIG.DEPRECATED_SHAPE`), so existing projects keep loading until the codemod story lands. The bin adapter unwraps the `orm` section before handing config to command handlers, so the handlers are untouched. **5. `init` scaffolds for the unified CLI.** New projects get `prisma.config.ts` in the engine shape, package scripts that invoke `prisma-cli`, and devDependencies `@prisma/cli@next` + `@prisma/cli-engine` (the config file imports the engine's `defineConfig`). **6. User-facing prose names the bin users actually have.** The engine only substitutes its `{bin}` placeholder in help examples and command redirects, so ~100 hardcoded `prisma-next <cmd>` strings in next-actions, fix suggestions, and init templates now say `prisma-cli`. Telemetry threads the settled exit code through the pipeline. The framework-vocabulary ratchet drops 364 → 308. **7. Docs catch up.** The root README installs `@prisma/cli@next`; the CLI package README describes the engine entry; the style guide, error reference, and e2e-patterns doc describe commander in the past tense; ADR 242 carries a supersession note for the retired bin distribution; ADR 239 records the `CLI.*` error namespace as shared with `@prisma/cli-engine`. ## Operator-review items - **`init`'s devDependency choice**: `@prisma/cli@next` + `@prisma/cli-engine`, scripts on the `prisma-cli` bin. The alternative — the `prisma-next` npm name living on as an rc channel published from the prisma-cli repo — does not exist yet; scaffolding it today would install the stale artifact this repo used to publish. - **The npm `prisma-next` name**: this PR only stops publishing it; deprecating or handing off the name is operator-owned. - **Generated-artifact headers**: emitted artifacts still carry `prisma-next`-flavoured headers. The emitter cannot know which bin invoked it, and changing the header would churn every committed fixture, so they were left alone — flagging for an explicit call. - **Hardcoded `prisma-cli` in remediation strings**: the ~100 next-action/fix strings name the unified bin literally because the engine has no `{bin}` templating outside help/redirects. If the engine grows that affordance, these should switch to it. ## Verification | Check | Result | | --- | --- | | root `pnpm build` | exit 0 | | cli `pnpm typecheck` / `pnpm lint` / `pnpm test` | exit 0 / exit 0 (264 infos) / 113 files, 1410/1410 | | config-loader `pnpm test` | exit 0 — 53/53 | | `pnpm test:integration` (full) | 10 failed files on the loaded full run → triaged: 1 real (a retry-hint assertion behind the prose sweep — fixed), the known machine-local timezone artifact (`issues-28192-pg-historical-dates`, 2 tests), a mongodb-memory-server port collision, and 7 timeout flakes; everything except the timezone artifact passes isolated with `TEST_TIMEOUT_MULTIPLIER=2` (34/34 + 2/2) | | `pnpm fixtures:check` | exit 0, no fixture diffs (after repairing the two cutover leftovers it caught — see the last commit) | | `pnpm lint:deps` | exit 0 | | `node scripts/lint-framework-vocabulary.mjs` | exit 0 (count 308 = threshold) | The cutover's divergence record and porting ledger live in the prisma-cli repo on branch `s5-cutover-divergences` (`.drive/projects/prisma-cli-v8/assets/s2/parity-divergences-s5-cutover.md`, `assets/s5/cutover-ledger.md`). ## Alternatives considered - **Keep publishing `prisma-next` as a thin shim over the engine bin.** Rejected: it would ship a second binary with identical behaviour under a stale name, while the rollout plan's happy path is the unified CLI. - **Port the stdout-formatting tests onto the engine renderer instead of deleting them.** Rejected: the renderer belongs to the engine and is tested there; re-asserting its output here would pin another repo's presentation. - **A hard cut on config filenames — engine semantics only, no fallback.** Rejected for this repo's own users: the deprecation path keeps every existing project loading (with a warning) until the codemod story lands post-rc. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 1 个月前 | |
feat: implement CLI telemetry Implements Phase 1 CLI telemetry for Prisma Next: an explicit opt-in consent path in `prisma-next init`, a detached sender process that posts anonymous command-start events without blocking CLI work, and a Bun/Postgres backend that stores accepted events through Prisma Next itself. Deliberately out of scope: crash/error reporting. That path has different privacy and lifecycle constraints and is deferred to a separate Phase 2. ## At a glance ```ts const payload: ParentToSenderPayload = { installationId: config.installationId, version: inputs.version, command: sanitised.command, flags: sanitised.flags, databaseTarget: inputs.databaseTarget, extensions: inputs.extensions, projectRoot: inputs.projectRoot, endpoint: resolveTelemetryEndpoint(env), }; ``` Telemetry starts from a sanitized parent-process payload — command and flag names only, no positional args or flag values — and a detached child enriches and sends it. ## How it fits together - **Backend storage is contract-first.** `apps/telemetry-backend/src/prisma/contract.prisma` defines a single `TelemetryEvent` model, with committed `contract.json` / `contract.d.ts` artifacts and migration outputs so the ingest service dogfoods Prisma Next. - **The ingest API is small and forward-compatible.** `POST /events` requires the stable core fields, defaults omitted optional fields to `null` / `[]`, drops unknown future keys, enforces request-size limits, and rate-limits callers before INSERT. - **User consent is per-user and default-off.** `@prisma-next/cli-telemetry` stores `enableTelemetry` and a random v4 `installationId` under the user config directory; env overrides and CI suppress telemetry without mutating that file. - **The CLI fires at command start.** A `preAction` hook resolves CI/env/user gates first, then loads only the telemetry-safe pieces of project config, sanitizes Commander metadata, and forks a detached sender. - **The child owns all I/O.** The sender enriches the payload with runtime, package manager, TypeScript version, OS/arch, and best-effort agent markers, POSTs with a hard timeout, and exits 0 while swallowing failures. ## Behavior changes Adds the telemetry backend ingest service. Accepts `POST /events`, validates the payload, enforces 32 KiB request limits and per-IP rate limiting, then inserts via Prisma Next. - Implementation: `apps/telemetry-backend/src/handler.ts`, `apps/telemetry-backend/src/schema.ts`, `apps/telemetry-backend/src/rate-limiter.ts` - Tests: `apps/telemetry-backend/test/handler.test.ts`, `apps/telemetry-backend/test/rate-limit.handler.test.ts` Adds default-off, opt-in telemetry consent. `init` asks a final interactive consent question only when prompting is allowed, `--yes` is not auto-accepting, CI/env overrides are absent, and no stored answer exists. - Implementation: `packages/1-framework/3-tooling/cli/src/commands/init/inputs.ts`, `packages/1-framework/3-tooling/cli-telemetry/src/user-config.ts`, `packages/1-framework/3-tooling/cli-telemetry/src/gating.ts` - Tests: `packages/1-framework/3-tooling/cli/test/commands/init/consent-prompt.test.ts`, `packages/1-framework/3-tooling/cli-telemetry/test/gating.test.ts` Adds detached command-start delivery. The CLI preAction hook forks the sender, disconnects/unrefs it, and keeps telemetry failures out of the parent command's stdout/stderr and exit path. - Implementation: `packages/1-framework/3-tooling/cli/src/cli.ts`, `packages/1-framework/3-tooling/cli/src/utils/telemetry.ts`, `packages/1-framework/3-tooling/cli-telemetry/src/spawn.ts`, `packages/1-framework/3-tooling/cli-telemetry/src/sender.ts` - Tests: `packages/1-framework/3-tooling/cli/test/utils/telemetry.test.ts`, `packages/1-framework/3-tooling/cli-telemetry/test/spawn.test.ts`, `packages/1-framework/3-tooling/cli-telemetry/test/integration.test.ts` Adds sanitization and enrichment without user values. Events include command name, user-supplied long flag names, runtime/package metadata, target, extensions, and agent markers; they intentionally exclude positionals and flag values. - Implementation: `packages/1-framework/3-tooling/cli-telemetry/src/sanitize.ts`, `packages/1-framework/3-tooling/cli-telemetry/src/enrich.ts`, `packages/1-framework/3-tooling/cli-telemetry/src/detect-agent.ts` - Tests: `packages/1-framework/3-tooling/cli-telemetry/test/sanitize.test.ts`, `packages/1-framework/3-tooling/cli-telemetry/test/enrich.test.ts`, `packages/1-framework/3-tooling/cli-telemetry/test/detect-agent.test.ts` ## Compatibility, migration, risk - Telemetry remains off unless the user explicitly opts in; `PRISMA_NEXT_DISABLE_TELEMETRY`, `DO_NOT_TRACK=1`, and CI all suppress it. - The backend wire format is backward-compatible for optional fields and forward-compatible for unknown future fields. - `apps/*` is now part of the workspace, so the telemetry backend participates in install/build/test orchestration. Existing package-layer dependency checks remain scoped to `packages/`. - The production endpoint URL is currently a build-time constant; if Prisma Compute reassigns it, the client constant needs to be updated before release. ## Alternatives considered - **Send telemetry synchronously from the parent process.** Rejected because network failures or slow DNS could affect the CLI UX. - **Use a per-project telemetry setting.** Rejected because one developer's project config should not enroll or opt out teammates. - **Collect crash/error reporting in Phase 1.** Rejected because stack traces and failure lifecycle need separate consent and sanitization rules. Refs TML-2557 Co-authored-by: Alexey Orlenko <alex@aqrln.net> Signed-off-by: Alexey Orlenko <alex@aqrln.net> Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net> | 4 个月前 | |
feat: an application depends on one Prisma package (ADR 242) (#29864) ## What changes for someone using Prisma Today, an application that talks to Postgres installs a long list of our packages: ```jsonc { "dependencies": { "@prisma-next/postgres": "...", "@prisma-next/sql-runtime": "...", "@prisma-next/sql-orm-client": "...", "@prisma-next/target-postgres": "...", "@prisma-next/adapter-postgres": "...", "@prisma-next/sql-contract": "..." // ...a dozen more } } ``` After this PR, it installs one: ```jsonc { "dependencies": { "@prisma/orm-postgres": "0.16.0" } } ``` Everything else arrives as that package's own dependencies. Three of our example apps are converted in this PR to prove it — one per database — and each has exactly one Prisma package in its `dependencies`. This implements [ADR 242](https://github.com/prisma/prisma/pull/29852), which is already merged. ## What gets published 17 packages, all under the `@prisma` scope: - **3 database packages** — `@prisma/orm-postgres`, `orm-sqlite`, `orm-mongo`. An application installs exactly one. We call these *facades*: each is a small package that wires its database together and re-exports everything an application needs. - **6 extension packs** — PostGIS, pgvector, ParadeDB, Supabase, arktype-json, middleware-cache. Optional, installed alongside a database package. - **7 platform packages** — the framework, the toolchain, one per database family, one per database target. Applications never install these directly; they arrive as dependencies. Extension authors do install them. - **the `prisma` command**, as a bin-only package. Every other workspace package — around 50 of them — stops being published. They still exist in the repo as the unit we organise code in; they just stop having a life on the registry. **This PR does not make that switch yet.** It builds and proves the new surface while leaving today's publish list exactly as it is. Flipping it is a separate change. ## The problem this design has to avoid A published package can't depend on packages that won't exist on the registry. So each published package *contains a compiled copy* of the internal packages it covers. That creates a trap. If one application ends up with the same code twice — once inside a published package, once as its own package — then classes, registries, and anything compared by reference exist twice too. An `instanceof` check quietly returns false. Nothing crashes, nothing fails to compile, and both copies behave identically in isolation. You find out much later, somewhere unrelated. So the rule the whole design follows is: **every piece of internal code is published from exactly one package.** Concretely, that means: - Each published package is built in one pass, so code shared between its own entry points exists once. Verified from the build's source maps: no module appears in more than one chunk, in any published package. - When one published package needs code from another, it imports it as a real dependency rather than compiling in a second copy. - A facade re-exports from the platform packages; it never carries its own copy. `@prisma/orm-postgres/orm-client` and `@prisma/orm-family-sql/orm-client` are two names for the same object, and there's a test that asserts exactly that from installed tarballs. - One table in `packages/0-shared/publish-surface` maps every internal package to where it's published. The build, the code generator, and the lint checks all read it, so there's one answer to "where does this live" rather than three that can drift. ## Generated code follows the application Prisma writes imports into your project — contract types and migration files. Those imports have to name packages your project actually depends on, or they won't resolve. So the generator now reads the `package.json` next to the config it's generating for. A project that depends on `@prisma/orm-postgres` gets imports from that package. A project on today's names keeps today's names. Nothing to configure, because the manifest already says which it is. Contract hashes are unaffected, and that isn't an assumption — hashes are computed from a structure that import text never enters, and there's a test asserting the hash is identical across naming schemes *while* the emitted imports demonstrably differ. ## What stops the trap coming back Two checks, because the failure is silent and won't show up in a test suite: - Every example app and test project must use one naming scheme, not a mix. `lint-single-import-root` scans them and fails the build if any project imports from both, since that's the situation that loads code twice. - `lint-consumer-internal-imports` counts how many internal-package imports remain in those projects and compares against a committed number. It fails if the number goes up (someone added one) and also if it goes down without the number being updated (so improvements get locked in). Target is zero. The build itself also refuses to proceed if the published-package map would put one module in two places, or if a published package's `package.json` no longer matches what its code actually needs. ## Reading this PR It's large — 257 files — because it's a migration. The commits are grouped and meant to be read in order: 1. **Platform packages** — the build mechanism, and the seven platform packages it produces. 2. **Database packages, extension packs, the `prisma` command** — completes the set of 17. 3. **Generated imports become configurable** — one place decides which names get written, with today's names still the default. 4. **Database-family symmetry, publishing the map, the identity checks.** 5. **One package per application** — the three converted examples, the re-exports they proved necessary, and the counting check. 6. **Migration files follow the project too.** One thing worth knowing while reading: re-exporting a package republishes all of its sub-paths, not just the one that was needed. This PR adds 115 published sub-paths across the three database packages. Two candidates were dropped for exactly that reason — see below. ## Alternatives considered **Let an application install platform packages alongside its facade.** Nothing would need re-exporting and the facades would stay thinner. Rejected: an application would again juggle several Prisma dependencies whose correct combination it maintains by hand, and getting it wrong — upgrading one and not the other — produces the silent two-copies failure above. Re-exporting costs a generated line and nothing at runtime. **Re-export everything an application might plausibly want.** Rejected in review: because re-exporting brings a package's entire sub-path surface, generosity is expensive and hard to undo. Migration tooling (54 sub-paths) was dropped because its only users are extension packs, which install platform packages anyway; the SQL driver re-export was dropped because nothing imported it at all. What remains is what a converted example actually needed. **Flip the publish list in this same PR.** Rejected: it would mix "does the new surface work" with "is it safe to stop publishing 50 packages" in one review. The switch is mechanical once this lands, and gets its own change. ## Verification `build`, `typecheck` (156 tasks), `test:packages` (1077 files / 14087 tests), `test:e2e`, `lint`, `lint:deps`, `lint:docs`, `lint:manifests`, `check:publish-deps`, `check:clean-tree`, `lint:casts` and `lint:throws` (no new instances), `test:scripts`, coverage, the tarball-install suites, and regenerating every committed artifact leaves the tree unchanged. Known-unstable and unrelated to this change: the `relation-mode-gh-*` port suites (TML-3140), and several test timeouts that are too tight under load. ## Follow-ups TML-3124 switch the publish list · TML-3127 build cache can validate a stale published package on CI · TML-3140 unstable port suites · TML-3141 a test-helper sub-path reaches a package that is never published. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added consolidated public ORM packages for PostgreSQL, MongoDB, SQLite, framework tooling, database targets, and extensions. - Generated contracts, migrations, and scaffolds now adapt imports to the consuming project’s package surface. - Added facade-provided `prisma-next` CLI access and consolidated migration entrypoints. - **Documentation** - Updated installation, package naming, public entrypoint, and migration scaffolding guidance. - **Tests** - Added coverage for package installation, exports, CLI behavior, module identity, and import compatibility. - **Chores** - Added checks preventing incompatible internal and public package imports. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 1 个月前 | |
test(telemetry-backend): assert each warm-up call in refill rate-limit test The sibling burst-cap test already asserts `expect(limiter.allow(...)).toBe(true)` inside its 60-iteration warm-up loop; the refill-interval test was the only case-of-the-pair that called `limiter.allow(...)` without asserting on it, so a regression in token accounting during warm-up would pass through to the refill assertion. One-line consistency fix. Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net> | 4 个月前 | |
fix(telemetry-backend): exit non-zero when shutdown times out The signal-handler shutdown closure already logs an error via `log.error({ event: 'shutdown-timeout' })`, but it discarded `stopTelemetryBackend`'s return value and unconditionally exited 0 on the happy path. Process supervisors (systemd, Kubernetes, Prisma Compute) read that as a clean shutdown and never retry / alert. Extract a tiny `shutdownExitCode(result)` helper that maps `'stopped' | 'timed-out'` to `0 | 1`, and call it on the awaited result. The `catch` branch is unchanged (still `exitCode = 1`). Adds two focused unit tests for the helper: clean stop returns 0, timeout returns 1. Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net> | 4 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 1 个月前 | ||
| 4 个月前 | ||
| 1 个月前 | ||
| 4 个月前 | ||
| 4 个月前 |