Skip to content

Commit 4e51fef

Browse files
SevInfclaude
andauthored
Port prisma functional wave 2: mongo composites, relationMode matrices, issue regressions (229 accounted) (#1042)
Second porting wave for the [`port-all-tests`](projects/port-all-tests/spec.md) project. **+229 checklist boxes accounted** (488 → 717); every box gated by an Opus reviewer before it was checked. ## What landed **Ported & passing** - **mongo composites** — `composites/list` and `composites/object` (create / createMany / delete / deleteMany / findFirst / findMany / update / upsert) against `withMongoPort`. - **relationMode foreignKeys matrices** — `1-to-1`, `1-to-n`, `m-to-n` referential actions (Cascade / NoAction / Restrict / SetNull × `@map` variants) plus the 17255 same/mixed-action `disconnect` cases. - **issue regressions** — 5952 (decimal), 14954 (date), 21631 (batching-in-tx, `Promise.all` forms), 29174 (jsonb), 13089 (dollar-in-search, mongo). **Ported & failing** (`test.fails`, faithful gap — one-to-one with `failing.md`) - 29267 `Uint8Array`-in-JSON serialization; required-composite `null`; implicit-default `onUpdate` (prisma-next `NoAction` vs Prisma `Cascade`). **Non-portable** (recorded per-test under `non-ported/functional/<suite>/`) - `relationLoadStrategy` (no such query option), `relationMode=prisma` client-side emulation, implicit embedded mongo m2m, array-batch `$transaction([...])`, and mongo-ORM gaps (embedded-subfield `select`, composite `where` operators, read-side `aggregate`/`count`). ## Verification - Full ports corpus: **68 files, 526 passed | 50 expected-fail**, `typecheck` + `lint` clean. - `failing.md` matches the 50 `test.fails` 1:1; non-ported ledgers mirror `functional/<suite>/`; checklist boxes carry per-line dispositions. - The reviewer gate caught and corrected two real faithfulness defects before finalize: composites/list had dropped the upstream `_id` assertion, and three issue suites had substituted array-batch `$transaction([...])` with the interactive-transaction facade (demoted to non-ported). No production code changed — test-only, per the project spec. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 7a39ef4 commit 4e51fef

275 files changed

Lines changed: 45410 additions & 232 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

projects/port-all-tests/briefs/implementer.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ A faithful port reproduces the SAME upstream test: same schema, logically the sa
4545
## Per-suite recipe
4646
1. Read the source `_matrix.ts`, `prisma/_schema.ts`, `tests.ts`. Determine provider applicability; port the **postgres** matrix entry. A suite exclusive to an unsupported DB (mysql/sqlserver/cockroachdb/sqlite) → `non-ported` lines (one per test). A **MongoDB**-applicable suite ports against the mongo ORM (`withMongoPort`) — do NOT mark mongo tests non-ported for being mongo.
4747
2. Each suite is its OWN directory `test/integration/test/ports/prisma/functional/<suite>/` holding both the test and its co-located fixture. Author the fixture as **PSL** (not TS builders): `prisma/functional/<suite>/_fixture/contract.prisma` — a faithful translation of the upstream `prisma/_schema.ts` (postgres branch). **The DB schema MUST match the original test exactly**: every model, field, scalar + native type (`@db.*`), nullability, list-ness, `@id`/`@@id`, `@unique`/`@@unique`, `@default`, `@map`/`@@map`, `@relation` (fields/references/onDelete/onUpdate), `@@index`, and enums. Do NOT drop or weaken any field/type/constraint/relation to dodge a prisma-next gap — if the faithful schema can't be authored or pushed, the affected tests are `non-ported`/`it.fails`, not a green on a simplified schema. Add `prisma/functional/<suite>/_fixture/prisma-next.config.ts`:
48-
`import { defineConfig } from '@prisma-next/postgres/config'; export default defineConfig({ contract: './contract.prisma', outputPath: 'generated' });`
48+
`import { defineConfig } from '@prisma-next/postgres/config'; export default defineConfig({ contract: './contract.prisma', output: 'generated' });`
4949
(mongo: `@prisma-next/mongo/config`, mongodb-provider PSL.) Emit:
5050
`node packages/1-framework/3-tooling/cli/dist/cli.js contract emit --config test/integration/test/ports/prisma/functional/<suite>/_fixture/prisma-next.config.ts`
5151
Commit the generated `contract.json` + `contract.d.ts` (leave them on disk). If a suite genuinely needs several schemas (e.g. a mapTable matrix), nest them under `_fixture/<variant>/`; if two suites truly share one schema, duplicate the `_fixture/` into each suite's directory so every suite stays self-contained.

projects/port-all-tests/checklists/prisma-functional-0-l.md

Lines changed: 68 additions & 68 deletions
Large diffs are not rendered by default.

projects/port-all-tests/checklists/prisma-functional-issues.md

Lines changed: 34 additions & 34 deletions
Large diffs are not rendered by default.

projects/port-all-tests/checklists/prisma-functional-m-z.md

Lines changed: 129 additions & 129 deletions
Large diffs are not rendered by default.

test/integration/test/ports/prisma/failing.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,26 @@ Every entry here corresponds one-to-one with a `test.fails` marker in the corpus
3838
- `test/ports/prisma/functional/multi-schema/multi-schema.test.ts``ports/prisma/functional/multi-schema (mapTable=IDENTICAL_NAMES)``multischema: update` — same gap as `read`: `posts.some()` with identical cross-namespace table names returns 0 rows in the read-back step; ORM emits an unqualified table name in the relation-filter subquery, which is ambiguous across the two namespaces
3939
- `test/ports/prisma/functional/methods-createManyAndReturn/methods-createManyAndReturn.test.ts``include _count should fail` — createManyAndReturn rejects `include: { _count: true }` — prisma-next type-rejects `include('_count')` (inline `@ts-expect-error` holds) but ignores the unknown relation at runtime instead of throwing, so the `.rejects.toThrow()` assertion fails
4040
- `test/ports/prisma/functional/methods-updateManyAndReturn/methods-updateManyAndReturn.test.ts``include _count should fail` — updateManyAndReturn rejects `include: { _count: true }` — prisma-next type-rejects `include('_count')` (inline `@ts-expect-error` holds) but ignores the unknown relation at runtime instead of throwing, so the `.rejects.toThrow()` assertion fails
41+
- `test/integration/test/ports/prisma/functional/composites-object-createMany/composites-object-createMany.test.ts``required content``set null` — createMany with null on a required embedded `content` field — type-rejects it (inline `@ts-expect-error` holds) but mongo has no runtime validation, so it does not throw (Prisma throws "Argument `set` must not be null")
42+
- `test/integration/test/ports/prisma/functional/composites-object-createMany/composites-object-createMany.test.ts``required content``set null shorthand` — same as `set null` for the required variant — type-rejected but no runtime throw
43+
- `test/integration/test/ports/prisma/functional/composites-object-upsert-create/composites-object-upsert-create.test.ts``required content``set null` — upsert (create path) with null on a required embedded `content` field — type-rejects it (inline `@ts-expect-error` holds) but mongo has no runtime validation, so it does not throw (Prisma throws "Argument `set` must not be null")
44+
- `test/integration/test/ports/prisma/functional/composites-object-upsert-create/composites-object-upsert-create.test.ts``required content``set null shorthand` — same as `set null` for the required variant — type-rejected but no runtime throw
45+
- `test/integration/test/ports/prisma/functional/composites-list-create/composites-list-create.test.ts``set null` — create with null on a required embedded `contents` list — type-rejects it (inline `@ts-expect-error` holds) but mongo has no runtime validation, so it does not throw (Prisma throws "Argument `set` must not be null")
46+
- `test/integration/test/ports/prisma/functional/composites-list-create/composites-list-create.test.ts``set null shorthand` — same as `set null` for the required list — type-rejected but no runtime throw
47+
- `test/integration/test/ports/prisma/functional/composites-list-createMany/composites-list-createMany.test.ts``set null` — createMany with null on a required embedded `contents` list — type-rejects it (inline `@ts-expect-error` holds) but mongo has no runtime validation, so it does not throw (Prisma throws "Argument `set` must not be null")
48+
- `test/integration/test/ports/prisma/functional/composites-list-createMany/composites-list-createMany.test.ts``set null shorthand` — same as `set null` for the required list — type-rejected but no runtime throw
49+
- `test/integration/test/ports/prisma/functional/composites-list-update/composites-list-update.test.ts``set null` — update with null on a required embedded `contents` list — type-rejects it (inline `@ts-expect-error` holds) but mongo has no runtime validation, so it does not throw (Prisma throws "Argument `set` must not be null")
50+
- `test/integration/test/ports/prisma/functional/composites-list-update/composites-list-update.test.ts``set null shorthand` — same as `set null` for the required list — type-rejected but no runtime throw
51+
- `test/integration/test/ports/prisma/functional/composites-list-upsert-create/composites-list-upsert-create.test.ts``set null` — upsert (create path) with null on a required embedded `contents` list — type-rejects it (inline `@ts-expect-error` holds) but mongo has no runtime validation, so it does not throw (Prisma throws "Argument `set` must not be null")
52+
- `test/integration/test/ports/prisma/functional/composites-list-upsert-create/composites-list-upsert-create.test.ts``set null shorthand` — same as `set null` for the required list — type-rejected but no runtime throw
53+
- `test/ports/prisma/functional/issues-29267-uint8array-in-json/issues-29267-uint8array-in-json.test.ts``serializes Uint8Array nested in object as base64` — prisma-next's JSON codec (`packages/3-extensions/arktype-json/src/core/arktype-json-codec.ts`, `serializeWire = JSON.stringify`) serialises a `Uint8Array` to an index-keyed object (`{"0":72,...}`), not base64; no Uint8Array→base64 hook
54+
- `test/ports/prisma/functional/issues-29267-uint8array-in-json/issues-29267-uint8array-in-json.test.ts``serializes Uint8Array nested in array as base64` — same gap: JSON codec `JSON.stringify` renders a `Uint8Array` as an index-keyed object, not base64
55+
- `test/ports/prisma/functional/issues-29267-uint8array-in-json/issues-29267-uint8array-in-json.test.ts``serializes Uint8Array directly as base64` — same gap: JSON codec `JSON.stringify` renders a `Uint8Array` as an index-keyed object, not base64
56+
- `test/ports/prisma/functional/issues-29267-uint8array-in-json/issues-29267-uint8array-in-json.test.ts``serializes deeply nested Uint8Array as base64` — same gap: JSON codec `JSON.stringify` renders a `Uint8Array` as an index-keyed object, not base64
57+
58+
- `test/ports/prisma/functional/relation-mode-gh-m-to-n/update.test.ts``onUpdate DEFAULT/SetNull (map=false) › [update] post id` — updating a referenced parent post id under the DEFAULT/SetNull m:n schema — prisma-next's implicit default `onUpdate` (no action line) is NO ACTION, so the FK-referenced parent-id update throws instead of cascading (Prisma's implicit default for a required relation is Cascade).
59+
- `test/ports/prisma/functional/relation-mode-gh-m-to-n/update.test.ts``onUpdate DEFAULT/SetNull (map=false) › [update] category id` — same gap, category side.
60+
- `test/ports/prisma/functional/relation-mode-gh-m-to-n/emit-map.test.ts``[emit @map] (index-name-length gap) › default-map › emitting the faithful @map contract succeeds` — emitting the DEFAULT/SetNull @map m:n schema — prisma-next #1047 rejects the mapped m:n join-table auto-index name `CategoriesOnPostsManyToMany_AtAtMap_categoryId_AtMap_idx` (>54-char prefix limit); the faithful @map schema is not emittable. Prisma truncates/hashes long index names. Blocks the m-to-n @map matrix variants.
61+
- `test/ports/prisma/functional/relation-mode-gh-m-to-n/emit-map.test.ts``[emit @map] (index-name-length gap) › cascade-map › emitting the faithful @map contract succeeds` — emitting the Cascade @map m:n schema — prisma-next #1047 rejects the mapped m:n join-table auto-index name `CategoriesOnPostsManyToMany_AtAtMap_categoryId_AtMap_idx` (>54-char prefix limit); the faithful @map schema is not emittable. Prisma truncates/hashes long index names. Blocks the m-to-n @map matrix variants.
62+
- `test/ports/prisma/functional/relation-mode-gh-m-to-n/emit-map.test.ts``[emit @map] (index-name-length gap) › noaction-map › emitting the faithful @map contract succeeds` — emitting the NoAction @map m:n schema — prisma-next #1047 rejects the mapped m:n join-table auto-index name `CategoriesOnPostsManyToMany_AtAtMap_categoryId_AtMap_idx` (>54-char prefix limit); the faithful @map schema is not emittable. Prisma truncates/hashes long index names. Blocks the m-to-n @map matrix variants.
63+
- `test/ports/prisma/functional/relation-mode-gh-m-to-n/emit-map.test.ts``[emit @map] (index-name-length gap) › restrict-map › emitting the faithful @map contract succeeds` — emitting the Restrict @map m:n schema — prisma-next #1047 rejects the mapped m:n join-table auto-index name `CategoriesOnPostsManyToMany_AtAtMap_categoryId_AtMap_idx` (>54-char prefix limit); the faithful @map schema is not emittable. Prisma truncates/hashes long index names. Blocks the m-to-n @map matrix variants.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Port of prisma/prisma@a6d0155 packages/client/tests/functional/composites/list
2+
// prisma/_schema.ts (mongodb matrix entry).
3+
//
4+
// Upstream schema:
5+
// model CommentRequiredList {
6+
// id String @id @default(auto()) @map("_id") @db.ObjectId
7+
// country String?
8+
// contents CommentContent[]
9+
// }
10+
// type CommentContent {
11+
// text String
12+
// upvotes CommentContentUpvotes[]
13+
// }
14+
// type CommentContentUpvotes {
15+
// vote Boolean
16+
// userId String
17+
// }
18+
//
19+
// MongoDB PSL `type` blocks become value objects in the contract.
20+
21+
type CommentContentUpvotes {
22+
vote Boolean
23+
userId String
24+
}
25+
26+
type CommentContent {
27+
text String
28+
upvotes CommentContentUpvotes[]
29+
}
30+
31+
model CommentRequiredList {
32+
id ObjectId @id @map("_id")
33+
country String?
34+
contents CommentContent[]
35+
@@map("comment_required_list")
36+
}

test/integration/test/ports/prisma/functional/composites-list-create/_fixture/generated/contract.d.ts

Lines changed: 217 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)