refactor(operations): clean up registry and emission types#436
refactor(operations): clean up registry and emission types#436
Conversation
|
Warning Rate limit exceeded
To continue reviewing without waiting, purchase usage credits in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (10)
📒 Files selected for processing (63)
📝 WalkthroughWalkthroughThis PR consolidates the operation type system by removing static ChangesOperation Type System Consolidation
🎯 4 (Complex) | ⏱️ ~60 minutes Possibly Related PRs
Suggested Reviewers
✨ Finishing Touches🧪 Generate unit tests (beta)
|
@prisma-next/mongo-runtime
@prisma-next/family-mongo
@prisma-next/sql-runtime
@prisma-next/family-sql
@prisma-next/extension-arktype-json
@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/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: |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/3-mongo-target/2-mongo-adapter/src/core/operations.ts (1)
9-11: 💤 Low valueConsider
Object.freeze()on the exported descriptors map for runtime immutability parity.
mongoVectorNearOperationis frozen (line 4), butmongoVectorOperationDescriptorsis not.Readonly<Record<...>>is compile-time only; the exported object can be mutated at runtime. The previous array-based export was frozen.🔒 Proposed fix
-export const mongoVectorOperationDescriptors: OperationDescriptors = { - near: mongoVectorNearOperation, -}; +export const mongoVectorOperationDescriptors: OperationDescriptors = Object.freeze({ + near: mongoVectorNearOperation, +});🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/3-mongo-target/2-mongo-adapter/src/core/operations.ts` around lines 9 - 11, The exported map mongoVectorOperationDescriptors is not frozen at runtime (unlike mongoVectorNearOperation), allowing mutation despite its TypeScript readonly type; update the export so the object is frozen with Object.freeze(...) to enforce immutability at runtime while preserving the OperationDescriptors shape so consumers get the same API but cannot mutate the map.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/3-mongo-target/2-mongo-adapter/src/core/operations.ts`:
- Around line 9-11: The exported map mongoVectorOperationDescriptors is not
frozen at runtime (unlike mongoVectorNearOperation), allowing mutation despite
its TypeScript readonly type; update the export so the object is frozen with
Object.freeze(...) to enforce immutability at runtime while preserving the
OperationDescriptors shape so consumers get the same API but cannot mutate the
map.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: c9f83a79-31b6-416b-91a0-65ffac6548a9
⛔ Files ignored due to path filters (10)
packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.jsonis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.jsonis excluded by!**/generated/**test/e2e/framework/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/e2e/framework/test/fixtures/generated/contract.jsonis excluded by!**/generated/**test/e2e/framework/test/sqlite/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/integration/test/mongo/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/integration/test/sql-builder/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/integration/test/sql-builder/fixtures/generated/contract.jsonis excluded by!**/generated/**
📒 Files selected for processing (62)
examples/prisma-next-demo/src/prisma/contract.d.tsexamples/prisma-next-demo/src/prisma/contract.jsonexamples/prisma-next-demo/test/demo-dx.types.test.tspackages/1-framework/1-core/framework-components/src/control/control-stack.tspackages/1-framework/1-core/framework-components/src/control/emission-types.tspackages/1-framework/1-core/framework-components/src/exports/control.tspackages/1-framework/1-core/framework-components/src/shared/framework-components.tspackages/1-framework/1-core/framework-components/test/control-stack.test.tspackages/1-framework/1-core/operations/README.mdpackages/1-framework/1-core/operations/src/index.tspackages/1-framework/1-core/operations/test/operations-registry.test.tspackages/1-framework/3-tooling/cli/README.mdpackages/1-framework/3-tooling/emitter/README.mdpackages/1-framework/3-tooling/emitter/src/emit-types.tspackages/1-framework/3-tooling/emitter/src/emit.tspackages/1-framework/3-tooling/emitter/src/generate-contract-dts.tspackages/1-framework/3-tooling/emitter/test/emitter.integration.test.tspackages/1-framework/3-tooling/emitter/test/emitter.roundtrip.test.tspackages/1-framework/3-tooling/emitter/test/emitter.test.tspackages/1-framework/3-tooling/emitter/test/mock-spi.tspackages/2-mongo-family/1-foundation/mongo-contract/src/contract-types.tspackages/2-mongo-family/1-foundation/mongo-contract/test/contract-types.test-d.tspackages/2-mongo-family/3-tooling/emitter/src/index.tspackages/2-mongo-family/3-tooling/emitter/test/emitter-hook.e2e.test.tspackages/2-mongo-family/3-tooling/emitter/test/emitter-hook.generation.test.tspackages/2-mongo-family/5-query-builders/orm/test/value-object-inputs.test-d.tspackages/2-sql/1-core/contract/src/exports/types.tspackages/2-sql/1-core/contract/src/types.tspackages/2-sql/1-core/contract/test/contract-typemaps-shape.test.tspackages/2-sql/1-core/operations/README.mdpackages/2-sql/1-core/operations/src/index.tspackages/2-sql/1-core/operations/test/operations-registry.test.tspackages/2-sql/3-tooling/emitter/README.mdpackages/2-sql/3-tooling/emitter/src/index.tspackages/2-sql/3-tooling/emitter/test/emitter-hook.generation.advanced.test.tspackages/2-sql/3-tooling/emitter/test/emitter-hook.generation.basic.test.tspackages/2-sql/3-tooling/emitter/test/emitter-hook.typeref-resolver.test.tspackages/2-sql/5-runtime/src/sql-context.tspackages/2-sql/5-runtime/test/execution-stack.test.tspackages/2-sql/5-runtime/test/sql-context.test.tspackages/2-sql/9-family/src/core/control-instance.tspackages/2-sql/9-family/src/core/migrations/types.tspackages/2-sql/9-family/src/exports/test-utils.tspackages/2-sql/9-family/test/compute-column-js-type.test-d.tspackages/2-sql/9-family/test/operation-preview.test.tspackages/3-extensions/pgvector/src/core/descriptor-meta.tspackages/3-extensions/pgvector/src/exports/operation-types.tspackages/3-extensions/pgvector/src/types/operation-types.tspackages/3-extensions/pgvector/test/manifest.test.tspackages/3-extensions/pgvector/test/operations.test.tspackages/3-extensions/sql-orm-client/test/generated-contract-types.test-d.tspackages/3-extensions/sql-orm-client/test/model-accessor.test.tspackages/3-mongo-target/2-mongo-adapter/src/core/operations.tspackages/3-mongo-target/2-mongo-adapter/test/codecs.test.tspackages/3-targets/6-adapters/postgres/src/core/descriptor-meta.tstest/integration/test/authoring/parity/callback-mode-scalars/expected.contract.jsontest/integration/test/authoring/parity/pgvector-named-type/expected.contract.jsontest/integration/test/cli.emit.test.tstest/integration/test/contract-imports.test.tstest/integration/test/emitter.adapter-query-operation-types.test.tstest/integration/test/fixtures/contract.d.tstest/integration/test/pgvector.test.ts
💤 Files with no reviewable changes (22)
- test/integration/test/authoring/parity/pgvector-named-type/expected.contract.json
- test/integration/test/authoring/parity/callback-mode-scalars/expected.contract.json
- packages/1-framework/3-tooling/emitter/test/emitter.integration.test.ts
- packages/1-framework/3-tooling/emitter/test/emitter.roundtrip.test.ts
- test/integration/test/emitter.adapter-query-operation-types.test.ts
- packages/3-extensions/pgvector/test/manifest.test.ts
- packages/2-sql/3-tooling/emitter/test/emitter-hook.typeref-resolver.test.ts
- packages/1-framework/1-core/framework-components/src/control/control-stack.ts
- examples/prisma-next-demo/src/prisma/contract.json
- packages/1-framework/3-tooling/emitter/src/emit-types.ts
- test/integration/test/fixtures/contract.d.ts
- packages/1-framework/1-core/framework-components/src/control/emission-types.ts
- packages/3-extensions/pgvector/src/types/operation-types.ts
- packages/2-sql/9-family/src/exports/test-utils.ts
- packages/1-framework/1-core/framework-components/src/exports/control.ts
- examples/prisma-next-demo/src/prisma/contract.d.ts
- packages/2-sql/1-core/contract/src/exports/types.ts
- packages/1-framework/1-core/framework-components/test/control-stack.test.ts
- packages/2-mongo-family/1-foundation/mongo-contract/src/contract-types.ts
- packages/2-sql/9-family/test/operation-preview.test.ts
- packages/2-sql/1-core/contract/src/types.ts
- packages/1-framework/1-core/framework-components/src/shared/framework-components.ts
…ors via registry `types.operationTypes` on component descriptors fed into the generated `contract.d.ts` `OperationTypes` alias and a matching `TypeMaps` slot, but neither was read at runtime: `OperationTypesOf` was only referenced by `ResolveOperationTypes`, which was exported but never imported. Remove the field, the extraction helpers, and the `TypeMaps` slot for both SQL and Mongo. `queryOperationTypes` (the live type-level dispatch surface) is unaffected. Drop `method` from `OperationDescriptor` and switch `OperationRegistry.register(name, descriptor)` to take the key explicitly. `queryOperations()` factories now return `Readonly<Record<string, SqlOperationEntry>>`; consumers iterate `Object.entries` and register by record key. Adapter/extension factories annotate their return type with their own `QueryOperationTypes<CT>`, so the type-level signature is the single source of truth and impl drift is a compile error. Regenerated all on-disk contract fixtures.
The cloudflare-worker example was added to main after this branch forked. Its committed contract.d.ts still carried the now-removed OperationTypes alias and TypeMaps slot; regenerated to match.
d1c0824 to
0d0c66e
Compare
Intent
Two small cleanups to
@prisma-next/operationsand the surrounding emission machinery:operationTypespipeline. Atypes.operationTypesfield on component descriptors flowed all the way through emission into a generatedOperationTypesalias incontract.d.tsand a matching slot onTypeMaps, but neither was ever read at runtime. The only type-level consumer (ResolveOperationTypes) was exported and unimported.queryOperationTypes— the real type-level dispatch surface — is unaffected.OperationRegistry.register(name, descriptor)now takes the key explicitly, descriptor factories return a keyedRecord<string, Descriptor>, and the per-operationmethodproperty goes away.Change map
OperationDescriptorlosesmethod; newOperationDescriptorsrecord alias;register(name, descriptor)takes the key as a parameter.OperationDescriptorsalias asSqlOperationDescriptors.operationTypesplumbing removed:operationTypeImportsfield andextractOperationTypeImportshelper.operationTypeImportsfromValidationContext.operationTypeImportsargument and stop emittingexport type OperationTypes = ...incontract.d.ts.operationTypesslot fromTypeMapsand removesOperationTypesOf/ResolveOperationTypes.operationTypesslot fromMongoTypeMaps.MongoTypeMaps<...>expression no longer referencesOperationTypes.postgresQueryOperations<CT>()returnsQueryOperationTypes<CT>; per-op type annotations onimplgo away (the return-type annotation drives inference).types.operationTypesimport spec from its component descriptor.OperationTypesalias.mongoVectorOperationDescriptorsbecomes a keyedOperationDescriptorsrecord.SqlStaticContributions.queryOperationsnow returnsSqlOperationDescriptors(a record); the registration loop iteratesObject.entries.register(name, descriptor)signature; the "strips method from stored entry" test is deleted (no method to strip anymore).extractOperationTypeImportstest block.operationTypesshape assertions.OperationTypesline removed fromcontract.d.ts;typeMaps.operationTypesblock removed fromcontract.json).The story
operationTypesslot onTypeMapsand the matchingOperationTypesalias in generatedcontract.d.tswere leftover scaffolding. The only thing that referenced them wasResolveOperationTypes, which was exported but never imported. Deleting the slot and the helper alias removes a surface that pretended to be load-bearing.extractOperationTypeImportsstep on the control stack and theoperationTypeImportsargument threaded through the emitter become dead too. They get pulled out together so the contract pipeline has one fewer parallel "imports" channel that emits nothing meaningful.method: stringfield that did double duty as both the registry key and a value attached to each entry. The factory thenObject.freeze'd an array of descriptors that the runtime walked just to readdescriptor.methodback. Switching toregister(name, descriptor)lets factories return aReadonly<Record<string, Descriptor>>directly — the record's keys are the operation names, the descriptor stops carrying its own name, and theas unknown as Tcast that existed only to stripmethodfrom the stored entry goes away.QueryOperationTypes<CT>(the type-level dispatch surface that already existed). That makes the type-level signature the single source of truth: per-operationimplno longer needs hand-written argument and return-type annotations, and any drift between the type signature and the implementation becomes a compile error at the factory boundary.Behavior changes & evidence
OperationRegistry.registersignature changes:register(descriptor)→register(name, descriptor). Descriptors no longer carrymethod.descriptor.method), and strippingmethodbefore storage required anas unknown as Tcast.createExecutionContext.Operation factories return keyed records:
postgresQueryOperations,pgvectorQueryOperations, andmongoVectorOperationDescriptorsnow exposeRecord<name, descriptor>shapes (typed asQueryOperationTypes<CT>for the SQL side,OperationDescriptorsfor mongo).implno longer needs per-arg annotations because the surrounding signature constrains them.Generated
contract.d.tsno longer declaresOperationTypes;contract.jsonno longer carriestypeMaps.operationTypes: the alias and the slot are gone.TypeMaps(SQL) andMongoTypeMapsshrink by one type parameter;MongoTypeMaps<...>is now<CodecTypes, FieldOutputTypes, FieldInputTypes>.contract.d.ts/contract.jsonfixtures regenerated to match the new shape.Compatibility / migration / risk
contract.d.tsandcontract.jsonchange shape. Anyone hand-importing the generatedOperationTypesalias or readingtypeMaps.operationTypesfrom a contract JSON would break — but no caller in this repo does, and neither was a documented public surface.TypeMaps(SQL) andMongoTypeMapslose a type parameter (theTOperationTypesslot). Direct callers that explicitly named that parameter will need to drop it. There are no such callers in the repo.OperationRegistry.registerandSqlStaticContributions.queryOperationschange shape. Both are internal extension-point APIs; all in-repo extensions and adapters are migrated in the same change.Non-goals / intentionally out of scope
queryOperationTypes(the live type-level dispatch surface) is intentionally untouched.Summary by CodeRabbit
New Features
Bug Fixes
Refactor