feat(prisma): derive schemas from a datamodel - #841
Merged
Merged
Conversation
Adds the plan-017 analogue for prisma: defineSchemaWithModel, defineSchemaRegistryWithDatamodel and assertSchemaMatchesModel, mirroring the typeorm entity-derivation contract. Derivation supplies shape only: the schema name (lower-camel model name), the relation allow-list and the schemaMapping used for relation traversal, plus the 'inherit' sentinel expanding an allowed list to the model's scalar and enum field names. Authorization stays explicit; a derived schema without per-parameter options allows nothing. Hand-written schemas already present in the registry take precedence, derived-name collisions and unmatched schema option keys fail loudly, and assertSchemaMatchesModel turns schema/model drift into a boot-time SchemaModelMismatchError carrying every offending key (fields, filter allow-lists and default condition trees, sort keys, relation keys).
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ 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 |
A model delegate is now all it takes:
new PrismaAdapter({ model: prisma.user })
The model name, the datamodel (relations, cardinality, nullability,
column types) and the active provider are read off the client the
delegate belongs to, through its runtime backref. The client-bound
shape also accepts `{ client, model }` with a plain model name, plus
`provider`/`metadata` overrides; the fully explicit form stays as the
private-API-free path.
The reads use private but long-stable client internals
(`_runtimeDataModel`, `_activeProvider`, the delegate `$name`/`$parent`
markers; prisma has no public reflection API, prisma/orm#19392).
Every read fails typed instead of guessing, pruned edge/wasm runtime
datamodels are rejected typed, and the engine suite pins the shapes
against a real generated client: the delegate-bound adapter must
produce byte-identical arguments to the datamodel-bound one and select
the same records through the engine.
defineMetadata and the schema derivation entry points accept the same
widened sources (client instance, runtime datamodel, DMMF datamodel).
tada5hi
force-pushed
the
feat/prisma-schema-derivation
branch
from
July 26, 2026 12:13
ac65f00 to
db29d51
Compare
tada5hi
added a commit
that referenced
this pull request
Jul 26, 2026
* feat(prisma): derive schemas from a datamodel
Adds the plan-017 analogue for prisma: defineSchemaWithModel,
defineSchemaRegistryWithDatamodel and assertSchemaMatchesModel,
mirroring the typeorm entity-derivation contract. Derivation supplies
shape only: the schema name (lower-camel model name), the relation
allow-list and the schemaMapping used for relation traversal, plus the
'inherit' sentinel expanding an allowed list to the model's scalar and
enum field names. Authorization stays explicit; a derived schema
without per-parameter options allows nothing.
Hand-written schemas already present in the registry take precedence,
derived-name collisions and unmatched schema option keys fail loudly,
and assertSchemaMatchesModel turns schema/model drift into a boot-time
SchemaModelMismatchError carrying every offending key (fields, filter
allow-lists and default condition trees, sort keys, relation keys).
* feat(prisma): bind the adapter from a model delegate
A model delegate is now all it takes:
new PrismaAdapter({ model: prisma.user })
The model name, the datamodel (relations, cardinality, nullability,
column types) and the active provider are read off the client the
delegate belongs to, through its runtime backref. The client-bound
shape also accepts `{ client, model }` with a plain model name, plus
`provider`/`metadata` overrides; the fully explicit form stays as the
private-API-free path.
The reads use private but long-stable client internals
(`_runtimeDataModel`, `_activeProvider`, the delegate `$name`/`$parent`
markers; prisma has no public reflection API, prisma/orm#19392).
Every read fails typed instead of guessing, pruned edge/wasm runtime
datamodels are rejected typed, and the engine suite pins the shapes
against a real generated client: the delegate-bound adapter must
produce byte-identical arguments to the datamodel-bound one and select
the same records through the engine.
defineMetadata and the schema derivation entry points accept the same
widened sources (client instance, runtime datamodel, DMMF datamodel).
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #838. Two features: schema derivation from a datamodel, and client-bound adapter construction.
Bind the adapter from a model delegate
One argument. The model name, the datamodel (relations, cardinality, nullability, column types) and the active provider are read off the client the delegate belongs to, through its runtime backref.
{ client: prisma, model: 'User' }works with a plain name,provider/metadataremain overridable, and the fully explicit{ provider, metadata }form stays as the private-API-free path.Honesty note: the reads use private but long-stable client internals (
_runtimeDataModel,_activeProvider, the delegate$name/$parentmarkers; Prisma has no public reflection API, prisma/orm#19392). Guarded accordingly:$extends.Schema derivation
Mirrors
@rapiq/typeorm's entity derivation contract: derivation supplies shape (schema name, relation allow-list,schemaMapping), authorization stays explicit, hand-written schemas take precedence, and name collisions or unmatched option keys fail loudly.assertSchemaMatchesModelturns schema/model drift into a boot-timeSchemaModelMismatchErrorcarrying every offending key. All entry points accept a client instance, a runtime datamodel or a DMMF datamodel.Testing
33 new specs (client resolution, derivation, assert) plus engine-backed checks against the real generated client on SQLite and PostgreSQL. Acceptance test runs a derived registry through the full pipeline: wire input -> URL codec (relation traversal via derived
schemaMapping) -> adapter -> args object.Notes
change-caseadded as a dependency (same as@rapiq/typeorm, for the derived names)._countordering.