feat(postgres): make ilike adapter-specific via trait-targeted operations#330
feat(postgres): make ilike adapter-specific via trait-targeted operations#330
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughDecouples return metadata from ParamSpec; introduces trait-based Field/Arg specs; removes AST-level Changes
Sequence DiagramsequenceDiagram
participant User as User Code
participant MA as Model Accessor
participant Ops as Operation Index
participant RE as ResolveExtArg
participant Expr as Expression Builder
participant Adapter as Adapter Query Ops
User->>MA: Access field (e.g., post.title)
MA->>Ops: Lookup ops by codecId
MA->>Ops: Lookup ops by trait(s)
Ops-->>MA: Return combined ops list
User->>MA: Call extension method (e.g., ilike(pattern))
MA->>RE: Resolve arg spec (codecId or traits)
RE-->>MA: Return resolved arg/expression types
MA->>Adapter: Select query operation descriptor (ilike)
MA->>Expr: Build OperationExpr node
Expr-->>User: Return Boolean Expression
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~55 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/3-extensions/sql-orm-client/src/model-accessor.ts`:
- Around line 157-160: The code in model-accessor.ts currently maps userArgSpecs
to ParamRef.of(args[i], ...) but only forwards codecId, losing trait-based
metadata; update the astArgs mapping so ParamRef.of receives the trait metadata
when codecId is absent (e.g., include argSpec.traits or traitTarget in the
options object you pass to ParamRef.of), and add a minimal fail-fast guard in
the same mapping (inside the userArgSpecs.map) to throw a clear error if an
argSpec has neither codecId nor traits so unsupported untyped params fail early;
refer to the symbols userArgSpecs, astArgs, ParamRef.of, and
argSpec.traits/traitTarget when making the change.
In `@packages/3-extensions/sql-orm-client/src/types.ts`:
- Around line 236-247: QueryOperationMethod currently maps user args via
MapArgsToJsTypes which only uses CodecArgJsType and therefore yields unknown for
args that specify traits; update the mapping so trait-based args resolve to
their JS types by reusing the trait-aware resolution logic used in ResolveExtArg
(as in sql-builder) and/or OpMatchesField. Specifically, modify MapArgsToJsTypes
(and/or CodecArgJsType) to detect ext-arg shapes with traits and apply the same
ResolveExtArg/OpMatchesField resolution path so QueryOperationMethod's parameter
types become the concrete JS types rather than unknown; keep function/type names
QueryOperationMethod, MapArgsToJsTypes, CodecArgJsType, ResolveExtArg and
OpMatchesField as reference points when implementing the fix.
🪄 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: 6319e707-06b1-4abd-bffa-e05389f7bcea
⛔ Files ignored due to path filters (2)
packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**
📒 Files selected for processing (28)
packages/1-framework/1-core/operations/src/index.tspackages/2-sql/1-core/contract/src/exports/types.tspackages/2-sql/1-core/contract/src/types.tspackages/2-sql/2-authoring/contract-ts/package.jsonpackages/2-sql/2-authoring/contract-ts/tsdown.config.tspackages/2-sql/4-lanes/relational-core/src/ast/types.tspackages/2-sql/4-lanes/relational-core/test/ast/predicate.test.tspackages/2-sql/4-lanes/sql-builder/src/expression.tspackages/2-sql/4-lanes/sql-builder/src/scope.tspackages/2-sql/4-lanes/sql-builder/test/integration/extension-functions.test.tspackages/2-sql/4-lanes/sql-builder/test/playground/extension-functions.test-d.tspackages/3-extensions/sql-orm-client/src/model-accessor.tspackages/3-extensions/sql-orm-client/src/types.tspackages/3-extensions/sql-orm-client/test/extension-operations.test-d.tspackages/3-extensions/sql-orm-client/test/filters.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-extensions/sql-orm-client/test/orm.types.test-d.tspackages/3-extensions/sql-orm-client/test/where-binding.test.tspackages/3-targets/6-adapters/postgres/package.jsonpackages/3-targets/6-adapters/postgres/src/core/adapter.tspackages/3-targets/6-adapters/postgres/src/core/descriptor-meta.tspackages/3-targets/6-adapters/postgres/src/exports/operation-types.tspackages/3-targets/6-adapters/postgres/src/exports/runtime.tspackages/3-targets/6-adapters/postgres/src/types/operation-types.tspackages/3-targets/6-adapters/postgres/tsdown.config.tspackages/3-targets/6-adapters/sqlite/src/core/adapter.tspackages/3-targets/6-adapters/sqlite/test/adapter.test.ts
💤 Files with no reviewable changes (6)
- packages/3-targets/6-adapters/postgres/src/core/adapter.ts
- packages/2-sql/4-lanes/relational-core/test/ast/predicate.test.ts
- packages/3-extensions/sql-orm-client/test/where-binding.test.ts
- packages/3-targets/6-adapters/sqlite/src/core/adapter.ts
- packages/3-targets/6-adapters/sqlite/test/adapter.test.ts
- packages/3-extensions/sql-orm-client/test/model-accessor.test.ts
e22d894 to
128c098
Compare
@prisma-next/mongo-runtime
@prisma-next/family-mongo
@prisma-next/sql-runtime
@prisma-next/family-sql
@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/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/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-pipeline-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.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/3-extensions/sql-orm-client/src/model-accessor.ts (1)
157-160:⚠️ Potential issue | 🟠 MajorTrait-targeted non-self args are still erased during AST binding.
Line 159 only forwards
codecIdintoParamRef. If an extension operation defines a user arg viatraits, that metadata is dropped here and the ORM runtime builds an untyped param, so later lowering/binding cannot distinguish the trait-targeted contract anymore. This leaves trait-based args only partially implemented outside theselfposition.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/3-extensions/sql-orm-client/src/model-accessor.ts` around lines 157 - 160, The mapping that builds astArgs from userArgSpecs drops trait metadata (only codecId is forwarded), so update the ParamRef construction in the userArgSpecs -> astArgs code path to include argSpec.traits (and any other metadata needed for trait-targeted non-self args) in the options passed to ParamRef.of; ensure you read from entry.args / argSpec and pass through codecId plus traits (or a combined metadata object) so trait-targeted args remain typed and available for later lowering/binding.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/2-sql/1-core/contract/src/types.ts`:
- Around line 167-170: The QueryOperationArgSpec type currently declares traits
as string which widens the API; change the traits field in QueryOperationArgSpec
to use the canonical codec trait union type used elsewhere (e.g., CodecTrait or
CodecTraits) instead of plain string, preserving readonly and optional semantics
(readonly traits?: CanonicalTraitUnion) so only valid trait members type-check
and typos are caught at compile time; update any imports to reference that union
where QueryOperationArgSpec is declared.
---
Duplicate comments:
In `@packages/3-extensions/sql-orm-client/src/model-accessor.ts`:
- Around line 157-160: The mapping that builds astArgs from userArgSpecs drops
trait metadata (only codecId is forwarded), so update the ParamRef construction
in the userArgSpecs -> astArgs code path to include argSpec.traits (and any
other metadata needed for trait-targeted non-self args) in the options passed to
ParamRef.of; ensure you read from entry.args / argSpec and pass through codecId
plus traits (or a combined metadata object) so trait-targeted args remain typed
and available for later lowering/binding.
🪄 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: cde64526-2ab9-40f9-b10e-82443440065f
⛔ Files ignored due to path filters (2)
packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**
📒 Files selected for processing (26)
packages/1-framework/1-core/operations/src/index.tspackages/2-sql/1-core/contract/src/exports/types.tspackages/2-sql/1-core/contract/src/types.tspackages/2-sql/4-lanes/relational-core/src/ast/types.tspackages/2-sql/4-lanes/relational-core/test/ast/predicate.test.tspackages/2-sql/4-lanes/sql-builder/src/expression.tspackages/2-sql/4-lanes/sql-builder/src/scope.tspackages/2-sql/4-lanes/sql-builder/test/integration/extension-functions.test.tspackages/2-sql/4-lanes/sql-builder/test/playground/extension-functions.test-d.tspackages/3-extensions/sql-orm-client/src/model-accessor.tspackages/3-extensions/sql-orm-client/src/types.tspackages/3-extensions/sql-orm-client/test/extension-operations.test-d.tspackages/3-extensions/sql-orm-client/test/filters.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-extensions/sql-orm-client/test/orm.types.test-d.tspackages/3-extensions/sql-orm-client/test/where-binding.test.tspackages/3-targets/6-adapters/postgres/package.jsonpackages/3-targets/6-adapters/postgres/src/core/adapter.tspackages/3-targets/6-adapters/postgres/src/core/descriptor-meta.tspackages/3-targets/6-adapters/postgres/src/exports/operation-types.tspackages/3-targets/6-adapters/postgres/src/exports/runtime.tspackages/3-targets/6-adapters/postgres/src/types/operation-types.tspackages/3-targets/6-adapters/postgres/tsdown.config.tspackages/3-targets/6-adapters/sqlite/src/core/adapter.tspackages/3-targets/6-adapters/sqlite/test/adapter.test.ts
💤 Files with no reviewable changes (6)
- packages/3-targets/6-adapters/sqlite/src/core/adapter.ts
- packages/3-targets/6-adapters/postgres/src/core/adapter.ts
- packages/2-sql/4-lanes/relational-core/test/ast/predicate.test.ts
- packages/3-targets/6-adapters/sqlite/test/adapter.test.ts
- packages/3-extensions/sql-orm-client/test/model-accessor.test.ts
- packages/3-extensions/sql-orm-client/test/where-binding.test.ts
✅ Files skipped from review due to trivial changes (8)
- packages/3-extensions/sql-orm-client/test/orm.types.test-d.ts
- packages/2-sql/1-core/contract/src/exports/types.ts
- packages/3-extensions/sql-orm-client/test/generated-contract-types.test-d.ts
- packages/3-targets/6-adapters/postgres/tsdown.config.ts
- packages/2-sql/4-lanes/sql-builder/test/integration/extension-functions.test.ts
- packages/3-targets/6-adapters/postgres/package.json
- packages/3-targets/6-adapters/postgres/src/exports/operation-types.ts
- packages/3-targets/6-adapters/postgres/src/core/descriptor-meta.ts
🚧 Files skipped from review as they are similar to previous changes (10)
- packages/3-extensions/sql-orm-client/test/filters.test.ts
- packages/3-targets/6-adapters/postgres/src/exports/runtime.ts
- packages/2-sql/4-lanes/sql-builder/src/scope.ts
- packages/2-sql/4-lanes/sql-builder/test/playground/extension-functions.test-d.ts
- packages/3-extensions/sql-orm-client/test/extension-operations.test-d.ts
- packages/2-sql/4-lanes/relational-core/src/ast/types.ts
- packages/1-framework/1-core/operations/src/index.ts
- packages/3-targets/6-adapters/postgres/src/types/operation-types.ts
- packages/2-sql/4-lanes/sql-builder/src/expression.ts
- packages/3-extensions/sql-orm-client/src/types.ts
128c098 to
4ee59bb
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
packages/3-extensions/sql-orm-client/src/types.ts (1)
242-245:⚠️ Potential issue | 🟠 MajorTrait-based operation args still degrade to
unknown.
QueryOperationMethodnow exposes the new trait-targeted operations, but its parameter tuple still comes fromMapArgsToJsTypes -> CodecArgJsType, which only understands{ codecId: ... }. Any non-self arg declared with{ traits: ... }will therefore surface here asunknown, so the ORM method signatures still lose the concrete JS types this PR is trying to preserve.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/3-extensions/sql-orm-client/src/types.ts` around lines 242 - 245, The method parameter types degrade to unknown because MapArgsToJsTypes and CodecArgJsType only handle { codecId: ... } shapes and do not resolve args declared with { traits: ... }; update the type pipeline so QueryOperationMethod receives resolved JS types for trait-based args by extending CodecArgJsType (or MapArgsToJsTypes) to detect a { traits: T } shape and map it to the corresponding codec/JS type via the existing trait-to-codec lookup helper (or add a small type-level resolver that converts trait names to their codec types), ensuring MapArgsToJsTypes<...> returns concrete types for args with { traits: ... } instead of unknown so QueryOperationMethod signatures preserve the correct JS types.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/2-sql/4-lanes/sql-builder/src/expression.ts`:
- Around line 81-90: ResolveExtArg currently maps trait-based arguments to
Expression<...> while codecId-based arguments use ExpressionOrValue<...>,
causing asymmetric API surface; change the trait branch in ResolveExtArg to
allow both expressions and raw values by returning ExpressionOrValue<{ codecId:
CodecIdsWithTrait<CT, T>; nullable: N }, CT> instead of Expression<{ codecId:
CodecIdsWithTrait<CT, T>; nullable: N }>, so both codecId and trait paths accept
the same input range; update the ResolveExtArg conditional that references
"traits: infer T" and "nullable: infer N" to use ExpressionOrValue and keep
CT/CodecIdsWithTrait references intact.
In `@packages/3-extensions/sql-orm-client/src/types.ts`:
- Around line 255-264: The conditional currently treats `codecId` and `traits`
as alternatives, so a matching `codecId` bypasses trait checks; change the
branching in the type conditional so it first checks for the combined shape
(e.g., `Self extends { readonly codecId: CodecId; readonly traits: infer
RequiredTraits extends string }`) and if so ensure `CodecId extends keyof CT ?
CT[CodecId] extends { readonly traits: infer FieldTraits } ? RequiredTraits
extends FieldTraits ? true : false : false : false`; otherwise fall back to the
single-property branches for `codecId` or `traits`. This preserves existing
`CT`, `CodecId`, `Self`, `RequiredTraits`, and `FieldTraits` symbols while
enforcing both constraints when both fields are present.
In `@packages/3-targets/6-adapters/postgres/src/core/descriptor-meta.ts`:
- Around line 131-136: Update the operation type for the ilike operator so its
first argument is non-nullable to match the runtime descriptor: change the
nullable flag for the first ilike arg in the operation-types declaration (the
ilike entry in packages/.../operation-types.ts) from nullable: true/boolean to
nullable: false so it aligns with the runtime postgresQueryOperations descriptor
(ilike entry) and prevents nullable textual fields from being incorrectly typed
as supporting .ilike().
---
Duplicate comments:
In `@packages/3-extensions/sql-orm-client/src/types.ts`:
- Around line 242-245: The method parameter types degrade to unknown because
MapArgsToJsTypes and CodecArgJsType only handle { codecId: ... } shapes and do
not resolve args declared with { traits: ... }; update the type pipeline so
QueryOperationMethod receives resolved JS types for trait-based args by
extending CodecArgJsType (or MapArgsToJsTypes) to detect a { traits: T } shape
and map it to the corresponding codec/JS type via the existing trait-to-codec
lookup helper (or add a small type-level resolver that converts trait names to
their codec types), ensuring MapArgsToJsTypes<...> returns concrete types for
args with { traits: ... } instead of unknown so QueryOperationMethod signatures
preserve the correct JS types.
🪄 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: bfe58c26-5a99-49ef-b0a2-46183837bc3b
⛔ Files ignored due to path filters (3)
packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/e2e/framework/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**
📒 Files selected for processing (28)
examples/prisma-next-demo/src/prisma/contract.d.tspackages/1-framework/1-core/operations/src/index.tspackages/2-sql/1-core/contract/src/exports/types.tspackages/2-sql/1-core/contract/src/types.tspackages/2-sql/4-lanes/relational-core/src/ast/types.tspackages/2-sql/4-lanes/relational-core/test/ast/predicate.test.tspackages/2-sql/4-lanes/sql-builder/src/expression.tspackages/2-sql/4-lanes/sql-builder/src/scope.tspackages/2-sql/4-lanes/sql-builder/test/integration/extension-functions.test.tspackages/2-sql/4-lanes/sql-builder/test/playground/extension-functions.test-d.tspackages/3-extensions/sql-orm-client/src/model-accessor.tspackages/3-extensions/sql-orm-client/src/types.tspackages/3-extensions/sql-orm-client/test/extension-operations.test-d.tspackages/3-extensions/sql-orm-client/test/filters.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-extensions/sql-orm-client/test/orm.types.test-d.tspackages/3-extensions/sql-orm-client/test/where-binding.test.tspackages/3-targets/6-adapters/postgres/package.jsonpackages/3-targets/6-adapters/postgres/src/core/adapter.tspackages/3-targets/6-adapters/postgres/src/core/descriptor-meta.tspackages/3-targets/6-adapters/postgres/src/exports/operation-types.tspackages/3-targets/6-adapters/postgres/src/exports/runtime.tspackages/3-targets/6-adapters/postgres/src/types/operation-types.tspackages/3-targets/6-adapters/postgres/tsdown.config.tspackages/3-targets/6-adapters/sqlite/src/core/adapter.tspackages/3-targets/6-adapters/sqlite/test/adapter.test.tstest/integration/test/fixtures/contract.d.ts
💤 Files with no reviewable changes (6)
- packages/3-targets/6-adapters/sqlite/test/adapter.test.ts
- packages/3-targets/6-adapters/postgres/src/core/adapter.ts
- packages/3-targets/6-adapters/sqlite/src/core/adapter.ts
- packages/3-extensions/sql-orm-client/test/where-binding.test.ts
- packages/2-sql/4-lanes/relational-core/test/ast/predicate.test.ts
- packages/3-extensions/sql-orm-client/test/model-accessor.test.ts
✅ Files skipped from review due to trivial changes (10)
- packages/3-targets/6-adapters/postgres/src/exports/operation-types.ts
- packages/3-extensions/sql-orm-client/test/generated-contract-types.test-d.ts
- packages/2-sql/4-lanes/sql-builder/test/integration/extension-functions.test.ts
- packages/3-targets/6-adapters/postgres/tsdown.config.ts
- packages/3-extensions/sql-orm-client/test/orm.types.test-d.ts
- packages/3-targets/6-adapters/postgres/package.json
- packages/2-sql/4-lanes/sql-builder/src/scope.ts
- packages/2-sql/4-lanes/sql-builder/test/playground/extension-functions.test-d.ts
- packages/3-targets/6-adapters/postgres/src/types/operation-types.ts
- packages/2-sql/1-core/contract/src/exports/types.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- packages/3-extensions/sql-orm-client/test/filters.test.ts
- packages/3-targets/6-adapters/postgres/src/exports/runtime.ts
- packages/3-extensions/sql-orm-client/test/extension-operations.test-d.ts
- packages/2-sql/1-core/contract/src/types.ts
- packages/1-framework/1-core/operations/src/index.ts
- packages/2-sql/4-lanes/relational-core/src/ast/types.ts
- packages/3-extensions/sql-orm-client/src/model-accessor.ts
4ee59bb to
5195631
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
packages/2-sql/1-core/contract/src/types.ts (1)
167-170:⚠️ Potential issue | 🟠 MajorKeep
traitson the canonical codec-trait union.
readonly traits?: stringmakes misspellings type-check and weakens the compile-time gating this PR is adding for trait-targeted operations. This should stay aligned with the shared codec-trait type instead of widening to arbitrary strings.Verify which canonical trait alias already exists before changing this field:
#!/bin/bash set -euo pipefail echo "== current QueryOperationArgSpec ==" sed -n '167,171p' packages/2-sql/1-core/contract/src/types.ts echo echo "== candidate canonical trait aliases in repo ==" rg -n --type=ts '\b(CodecTrait|CodecTraits)\b' packages🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/2-sql/1-core/contract/src/types.ts` around lines 167 - 170, The QueryOperationArgSpec currently declares readonly traits?: string which weakens type safety; change this field to use the existing canonical codec-trait alias (e.g. CodecTrait or CodecTraits) used across the repo instead of plain string. Locate the type QueryOperationArgSpec in types.ts and replace traits?: string with the correct canonical type (nullable/optional as appropriate), but first confirm which alias name is present in the codebase (search for CodecTrait or CodecTraits) and import or reference that alias so the field aligns with the shared codec-trait union.packages/2-sql/4-lanes/sql-builder/src/expression.ts (1)
81-90:⚠️ Potential issue | 🟡 MinorTrait-targeted args should accept literals too.
The codecId branch returns
ExpressionOrValue, but the trait branch only acceptsExpression. That makes trait-only args stricter than codecId-targeted args and blocks raw literals for the same logical operation surface.Suggested type fix
type ResolveExtArg<Arg, CT extends Record<string, { readonly input: unknown }>> = Arg extends { readonly codecId: infer CId extends string; readonly nullable: infer N extends boolean; } ? ExpressionOrValue<{ codecId: CId; nullable: N }, CT> : Arg extends { readonly traits: infer T extends string; readonly nullable: infer N extends boolean; } - ? Expression<{ codecId: CodecIdsWithTrait<CT, T>; nullable: N }> + ? ExpressionOrValue<{ codecId: CodecIdsWithTrait<CT, T>; nullable: N }, CT> : never;Verify whether any current operation types rely on trait-only args:
#!/bin/bash set -euo pipefail echo "== current ResolveExtArg trait branch ==" sed -n '81,91p' packages/2-sql/4-lanes/sql-builder/src/expression.ts echo echo "== trait-based operation arg specs ==" rg -n -C2 'traits:' packages/3-targets packages/2-sql test --type=ts🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/2-sql/4-lanes/sql-builder/src/expression.ts` around lines 81 - 90, The trait-only branch of the ResolveExtArg type is too strict and disallows raw literals; update the second conditional branch in ResolveExtArg so it returns the same ExpressionOrValue wrapper as the codecId branch (using CodecIdsWithTrait<CT, T> and the inferred N) instead of plain Expression, so trait-targeted args accept literals; locate ResolveExtArg in expression.ts and replace the trait branch's return type to ExpressionOrValue<{ codecId: CodecIdsWithTrait<CT, T>; nullable: N }, CT> (keeping the existing inference of T and N).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/3-extensions/sql-orm-client/src/model-accessor.ts`:
- Around line 59-75: The current indexing and lookup widen trait matching by
indexing ops under each individual trait and later unioning them, and the else
if prevents trait indexing when a self arg has both codecId and traits; update
the code so codecId and trait paths run independently (remove the else if
branching) and, when selecting trait-based candidates from opsByTrait for a
field, only include operations whose self.traits are a subset of the field’s
traits by filtering with self.traits.every(t => field.traits.includes(t))
(reference opsByCodecId, opsByTrait, and the self.traits usage and the matching
logic that currently unions trait candidates).
---
Duplicate comments:
In `@packages/2-sql/1-core/contract/src/types.ts`:
- Around line 167-170: The QueryOperationArgSpec currently declares readonly
traits?: string which weakens type safety; change this field to use the existing
canonical codec-trait alias (e.g. CodecTrait or CodecTraits) used across the
repo instead of plain string. Locate the type QueryOperationArgSpec in types.ts
and replace traits?: string with the correct canonical type (nullable/optional
as appropriate), but first confirm which alias name is present in the codebase
(search for CodecTrait or CodecTraits) and import or reference that alias so the
field aligns with the shared codec-trait union.
In `@packages/2-sql/4-lanes/sql-builder/src/expression.ts`:
- Around line 81-90: The trait-only branch of the ResolveExtArg type is too
strict and disallows raw literals; update the second conditional branch in
ResolveExtArg so it returns the same ExpressionOrValue wrapper as the codecId
branch (using CodecIdsWithTrait<CT, T> and the inferred N) instead of plain
Expression, so trait-targeted args accept literals; locate ResolveExtArg in
expression.ts and replace the trait branch's return type to ExpressionOrValue<{
codecId: CodecIdsWithTrait<CT, T>; nullable: N }, CT> (keeping the existing
inference of T and N).
🪄 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: 5496665e-609a-486b-b3fa-d7bafa07ab92
⛔ Files ignored due to path filters (3)
packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/e2e/framework/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**
📒 Files selected for processing (28)
examples/prisma-next-demo/src/prisma/contract.d.tspackages/1-framework/1-core/operations/src/index.tspackages/2-sql/1-core/contract/src/exports/types.tspackages/2-sql/1-core/contract/src/types.tspackages/2-sql/4-lanes/relational-core/src/ast/types.tspackages/2-sql/4-lanes/relational-core/test/ast/predicate.test.tspackages/2-sql/4-lanes/sql-builder/src/expression.tspackages/2-sql/4-lanes/sql-builder/src/scope.tspackages/2-sql/4-lanes/sql-builder/test/integration/extension-functions.test.tspackages/2-sql/4-lanes/sql-builder/test/playground/extension-functions.test-d.tspackages/3-extensions/sql-orm-client/src/model-accessor.tspackages/3-extensions/sql-orm-client/src/types.tspackages/3-extensions/sql-orm-client/test/extension-operations.test-d.tspackages/3-extensions/sql-orm-client/test/filters.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-extensions/sql-orm-client/test/orm.types.test-d.tspackages/3-extensions/sql-orm-client/test/where-binding.test.tspackages/3-targets/6-adapters/postgres/package.jsonpackages/3-targets/6-adapters/postgres/src/core/adapter.tspackages/3-targets/6-adapters/postgres/src/core/descriptor-meta.tspackages/3-targets/6-adapters/postgres/src/exports/operation-types.tspackages/3-targets/6-adapters/postgres/src/exports/runtime.tspackages/3-targets/6-adapters/postgres/src/types/operation-types.tspackages/3-targets/6-adapters/postgres/tsdown.config.tspackages/3-targets/6-adapters/sqlite/src/core/adapter.tspackages/3-targets/6-adapters/sqlite/test/adapter.test.tstest/integration/test/fixtures/contract.d.ts
💤 Files with no reviewable changes (5)
- packages/3-extensions/sql-orm-client/test/where-binding.test.ts
- packages/3-targets/6-adapters/sqlite/test/adapter.test.ts
- packages/3-targets/6-adapters/sqlite/src/core/adapter.ts
- packages/2-sql/4-lanes/relational-core/test/ast/predicate.test.ts
- packages/3-targets/6-adapters/postgres/src/core/adapter.ts
✅ Files skipped from review due to trivial changes (6)
- packages/3-targets/6-adapters/postgres/src/exports/operation-types.ts
- packages/3-targets/6-adapters/postgres/package.json
- packages/2-sql/1-core/contract/src/exports/types.ts
- packages/3-extensions/sql-orm-client/test/generated-contract-types.test-d.ts
- packages/2-sql/4-lanes/sql-builder/test/integration/extension-functions.test.ts
- packages/3-targets/6-adapters/postgres/src/core/descriptor-meta.ts
🚧 Files skipped from review as they are similar to previous changes (12)
- packages/3-targets/6-adapters/postgres/tsdown.config.ts
- packages/3-extensions/sql-orm-client/test/orm.types.test-d.ts
- test/integration/test/fixtures/contract.d.ts
- packages/2-sql/4-lanes/sql-builder/src/scope.ts
- packages/3-targets/6-adapters/postgres/src/types/operation-types.ts
- packages/3-extensions/sql-orm-client/test/model-accessor.test.ts
- examples/prisma-next-demo/src/prisma/contract.d.ts
- packages/3-extensions/sql-orm-client/test/filters.test.ts
- packages/3-extensions/sql-orm-client/test/extension-operations.test-d.ts
- packages/2-sql/4-lanes/sql-builder/test/playground/extension-functions.test-d.ts
- packages/1-framework/1-core/operations/src/index.ts
- packages/3-extensions/sql-orm-client/src/types.ts
5195631 to
b57097f
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/2-sql/4-lanes/sql-builder/src/expression.ts (1)
81-90:⚠️ Potential issue | 🟡 MinorKeep trait-targeted args symmetric with codecId-targeted args.
Line 90 only accepts
Expression<...>for trait-gated params, while line 85 accepts raw inputs viaExpressionOrValue. That makes trait-targeted operation args stricter than codecId-targeted ones and can block valid literal inputs for adapter ops.Suggested fix
- ? Expression<{ codecId: CodecIdsWithTrait<CT, T>; nullable: N }> + ? ExpressionOrValue<{ codecId: CodecIdsWithTrait<CT, T>; nullable: N }, CT>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/2-sql/4-lanes/sql-builder/src/expression.ts` around lines 81 - 90, ResolveExtArg is asymmetric: the codecId branch returns ExpressionOrValue but the traits branch returns only Expression, disallowing literal inputs for trait-gated params; change the traits branch to return ExpressionOrValue as well (i.e., replace Expression<{ codecId: CodecIdsWithTrait<CT, T>; nullable: N }> with ExpressionOrValue<{ codecId: CodecIdsWithTrait<CT, T>; nullable: N }, CT>) so trait-targeted args accept both Expressions and raw values consistent with the codecId path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/3-extensions/sql-orm-client/test/extension-operations.test-d.ts`:
- Around line 96-101: Update the type assertion in the 'ilike returns
AnyExpression (predicate)' test to use the non-deprecated matcher: replace the
expectTypeOf<ReturnType<IlikeFn>>().toMatchTypeOf<import('@prisma-next/sql-relational-core/ast').AnyExpression>()
call with
expectTypeOf<ReturnType<IlikeFn>>().toExtend<import('@prisma-next/sql-relational-core/ast').AnyExpression>();
locate the test by the IlikeFn alias (PostAccessor['title']['ilike']) and adjust
only the matcher name so the test verifies the return type extends
AnyExpression.
---
Duplicate comments:
In `@packages/2-sql/4-lanes/sql-builder/src/expression.ts`:
- Around line 81-90: ResolveExtArg is asymmetric: the codecId branch returns
ExpressionOrValue but the traits branch returns only Expression, disallowing
literal inputs for trait-gated params; change the traits branch to return
ExpressionOrValue as well (i.e., replace Expression<{ codecId:
CodecIdsWithTrait<CT, T>; nullable: N }> with ExpressionOrValue<{ codecId:
CodecIdsWithTrait<CT, T>; nullable: N }, CT>) so trait-targeted args accept both
Expressions and raw values consistent with the codecId path.
🪄 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: 04848f22-85e2-4aac-a0c3-4dd505ccf86f
⛔ Files ignored due to path filters (3)
packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/e2e/framework/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**
📒 Files selected for processing (28)
examples/prisma-next-demo/src/prisma/contract.d.tspackages/1-framework/1-core/operations/src/index.tspackages/2-sql/1-core/contract/src/exports/types.tspackages/2-sql/1-core/contract/src/types.tspackages/2-sql/4-lanes/relational-core/src/ast/types.tspackages/2-sql/4-lanes/relational-core/test/ast/predicate.test.tspackages/2-sql/4-lanes/sql-builder/src/expression.tspackages/2-sql/4-lanes/sql-builder/src/scope.tspackages/2-sql/4-lanes/sql-builder/test/integration/extension-functions.test.tspackages/2-sql/4-lanes/sql-builder/test/playground/extension-functions.test-d.tspackages/3-extensions/sql-orm-client/src/model-accessor.tspackages/3-extensions/sql-orm-client/src/types.tspackages/3-extensions/sql-orm-client/test/extension-operations.test-d.tspackages/3-extensions/sql-orm-client/test/filters.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-extensions/sql-orm-client/test/orm.types.test-d.tspackages/3-extensions/sql-orm-client/test/where-binding.test.tspackages/3-targets/6-adapters/postgres/package.jsonpackages/3-targets/6-adapters/postgres/src/core/adapter.tspackages/3-targets/6-adapters/postgres/src/core/descriptor-meta.tspackages/3-targets/6-adapters/postgres/src/exports/operation-types.tspackages/3-targets/6-adapters/postgres/src/exports/runtime.tspackages/3-targets/6-adapters/postgres/src/types/operation-types.tspackages/3-targets/6-adapters/postgres/tsdown.config.tspackages/3-targets/6-adapters/sqlite/src/core/adapter.tspackages/3-targets/6-adapters/sqlite/test/adapter.test.tstest/integration/test/fixtures/contract.d.ts
💤 Files with no reviewable changes (5)
- packages/3-targets/6-adapters/postgres/src/core/adapter.ts
- packages/3-targets/6-adapters/sqlite/test/adapter.test.ts
- packages/3-extensions/sql-orm-client/test/where-binding.test.ts
- packages/3-targets/6-adapters/sqlite/src/core/adapter.ts
- packages/2-sql/4-lanes/relational-core/test/ast/predicate.test.ts
✅ Files skipped from review due to trivial changes (9)
- packages/3-extensions/sql-orm-client/test/orm.types.test-d.ts
- packages/3-extensions/sql-orm-client/test/generated-contract-types.test-d.ts
- packages/3-targets/6-adapters/postgres/tsdown.config.ts
- packages/2-sql/4-lanes/sql-builder/test/integration/extension-functions.test.ts
- packages/3-targets/6-adapters/postgres/src/exports/operation-types.ts
- packages/2-sql/1-core/contract/src/exports/types.ts
- packages/3-targets/6-adapters/postgres/package.json
- packages/2-sql/4-lanes/relational-core/src/ast/types.ts
- packages/3-extensions/sql-orm-client/src/types.ts
🚧 Files skipped from review as they are similar to previous changes (11)
- packages/3-extensions/sql-orm-client/test/filters.test.ts
- packages/2-sql/4-lanes/sql-builder/test/playground/extension-functions.test-d.ts
- packages/3-targets/6-adapters/postgres/src/core/descriptor-meta.ts
- packages/2-sql/4-lanes/sql-builder/src/scope.ts
- packages/3-extensions/sql-orm-client/test/model-accessor.test.ts
- packages/3-targets/6-adapters/postgres/src/exports/runtime.ts
- packages/3-targets/6-adapters/postgres/src/types/operation-types.ts
- packages/1-framework/1-core/operations/src/index.ts
- packages/2-sql/1-core/contract/src/types.ts
- packages/3-extensions/sql-orm-client/src/model-accessor.ts
- examples/prisma-next-demo/src/prisma/contract.d.ts
packages/3-extensions/sql-orm-client/test/extension-operations.test-d.ts
Show resolved
Hide resolved
d232ad8 to
65d5bf2
Compare
…tions Move ilike from a core comparison method to a postgres adapter-provided extension operation. Operation args now support targeting by trait (e.g., `traits: ['textual']`) in addition to codecId, allowing adapter operations to match any codec with the required traits. - Extend ParamSpec and QueryOperationArgSpec with optional `traits` field - Add FieldSpec/TraitField to sql-builder scope for trait-targeted expressions - Update FieldOperations type matching to support trait-based operations - Boolean-trait return detection makes predicate ops return AnyExpression - Register ilike in postgres adapter's queryOperations() - Remove ilike from BinaryOp union, BinaryExpr, ComparisonMethodFns - Remove ilike runtime guard from SQLite adapter - Fix tsdown exports stripping ./schema-sql in sql-contract-ts
65d5bf2 to
bf38492
Compare
closes TML-2238
Intent
ilike(case-insensitive LIKE) is a PostgreSQL-specific operator that has no SQLite equivalent. Until now it lived in core as aBinaryOp/ComparisonMethod, available on every textual field regardless of target. SQLite threw a runtime error when it encountered anilikeAST node. This PR movesiliketo the postgres adapter so it is only available at the type level for postgres contracts — SQLite contracts never see it.The deeper change: operation args can now target by codec trait (e.g.
traits: 'textual') in addition to exactcodecId. This lets a single adapter-provided operation match every codec that carries a given trait, without enumerating codec IDs.Change map
ParamSpecgains optionaltraits(runtime:readonly string[]). NewReturnSpec(requiredcodecId) split fromParamSpecforOperationEntry.returns.QueryOperationArgSpecwith optionaltraits: string(type-level union).QueryOperationTypeEntry.argsuses it.TraitField/FieldSpecscope types.Expression<T>broadened toFieldSpec.ResolveExtArg+CodecIdsWithTraitresolve trait args to the union of matching codec IDs.ilikeremoved fromComparisonMethodFnsandCOMPARISON_METHODS_META. NewOpMatchesFieldhelper does codecId-exact OR trait-subset matching.IsBooleanReturndetects predicate ops → returnAnyExpressioninstead ofComparisonMethods.opsByTraitindex alongsideopsByCodecId.createExtensionMethodFactoryreturnsOperationExprdirectly for boolean-returning ops.postgresQueryOperationsarray with ilike descriptor (traits: ['textual'], template{{self}} ILIKE {{arg0}}).queryOperations()wired into runtime descriptor. Newoperation-typesexport.ilikeremoved fromoperatorMap.ilikethrow guard andoperatorMapentry removed.'ilike'removed fromBinaryOpunion andBinaryExpr.ilike()static method.customExportshook preserves./schema-sqlJSON export that tsdown's export-sync was stripping.The story
Trait-targeted args —
ParamSpecandQueryOperationArgSpecgain an optionaltraitsfield. At the type level it's a string union ('textual'); at runtime it's an array (['textual']). This is the foundational primitive that lets operations match by codec capability rather than identity.ilike leaves core — Removed from
BinaryOp,BinaryExpr,ComparisonMethodFns, andCOMPARISON_METHODS_META. The AST, adapters, and ORM no longer treat it as a built-in comparison.Postgres adapter registers ilike — A new
postgresQueryOperationsarray defines ilike with{ traits: ['textual'] }as self arg,pg/text@1as pattern arg,pg/bool@1as return, and infix template{{self}} ILIKE {{arg0}}. The adapter's runtime descriptor exposesqueryOperations(). Contract emission picks it up viatypes.queryOperationTypesin descriptor meta.Type-level matching —
OpMatchesFieldchecks whether an operation's self arg matches a field: either exactcodecIdmatch (existing pgvector path) or trait-subset match (new).FieldOperationsuses this to surface ilike on text fields in postgres contracts and hide it from sqlite contracts.Predicate detection —
IsBooleanReturnchecks whether the return codec has the'boolean'trait. If so,QueryOperationMethodreturnsAnyExpressiondirectly (a WHERE predicate), notComparisonMethods<...>. At runtime,createExtensionMethodFactoryreturns theOperationExprdirectly for boolean-returning ops. This meansuser.name.ilike('%alice%')is a predicate expression, not a chainable value.SQL builder support —
Expression<T>now acceptsFieldSpec(=ScopeField | TraitField).ResolveExtArgmaps trait-targeted args toExpression<{ codecId: CodecIdsWithTrait<CT, T> }>, sofns.ilike(f.name, '%test%')accepts any textual column expression.Behavior changes & evidence
ilike: extension-operations.test-d.ts —PostAccessor['title']hasilikeproperty, returnsAnyExpression.ilike: Same file —PostAccessor['views']andPostAccessor['embedding']do not exposeilike.ilike: NoQueryOperationTypesfrom the adapter →FieldOperationsfinds nothing → field type has noilike.fns.ilike(f.name, '%alice%')typechecks and returnsExpression<BooleanCodecType>.Compatibility / migration / risk
.ilike()on a SQLite contract field will get a compile error instead of a runtime error. This is the intended improvement.ParamSpec.codecIdis always present needs adjustment.ReturnSpec(new) guaranteescodecIdfor return types.pg/bool@1codec will automatically be treated as a predicate (returnsAnyExpression). This is the correct behavior for boolean-returning operations.Follow-ups / open questions
QueryOperationTypesshould includePgAdapterQueryOpsautomatically (the descriptor meta is wired, but no e2e emit test exists yet).~,~*,SIMILAR TO) can follow the same pattern.Non-goals / intentionally out of scope
OperationTypes(codec-keyed) for the postgres adapter — onlyQueryOperationTypes(flat) is needed since trait matching handles the codec-to-operation mapping.Summary by CodeRabbit
New Features
Improvements
Behavioral Changes
Tests