diff --git a/docs/architecture docs/ADR-INDEX.md b/docs/architecture docs/ADR-INDEX.md index df3f4368832e..2aa1a8206d08 100644 --- a/docs/architecture docs/ADR-INDEX.md +++ b/docs/architecture docs/ADR-INDEX.md @@ -157,6 +157,7 @@ Open this list before you propose a new feature or surface, or judge a feature r | 240 | Contract snapshots live in a content-addressed store | Every distinct migration contract is stored once per migrations root at `migrations/snapshots//contract.{json,d.ts}`, keyed by storage hash; the old per-package sibling contract files and per-space head copies are gone, and `migration.ts` imports resolve through the store. Amends ADR 197 and ADR 232. | [ADR 240 - Contract snapshots live in a content-addressed store.md](adrs/ADR%20240%20-%20Contract%20snapshots%20live%20in%20a%20content-addressed%20store.md) | | 243 | Name-identified indexes and exact-name adoption | Extends ADR 234's content-addressed wire names from RLS policies to every index, so expression and partial indexes become authorable and verifiable without comparing SQL bodies; adds an exact-name mode (`map:`/`@@map`) whose equivalence is content comparison, which makes a foreign database adoptable with zero operations; naming is a two-arm union (`wire`/`exact`) at construction with flat derived storage. Constraints stay outside the rule (amended: check constraints joined it in ADR 244). | [ADR 243 - Name-identified indexes and exact-name adoption.md](adrs/ADR%20243%20-%20Name-identified%20indexes%20and%20exact-name%20adoption.md) | | 244 | Check constraints are opaque wire-named expressions | Extends ADR 234's content-addressed wire names to a third object kind: a check is one opaque SQL predicate whose name commits to its content, so equivalence is name equality and introspection never parses a predicate. Supersedes ADR 156's structured `inSet` check shape. The target renders the SQL, the family composes and byte-caps the wire prefix, legacy exact-named checks adopt by drop + add rather than rename, and derivation is scoped to `managed` tables — the contract describes an external schema without prescribing enforcement for it. | [ADR 244 - Check constraints are opaque wire-named expressions.md](adrs/ADR%20244%20-%20Check%20constraints%20are%20opaque%20wire-named%20expressions.md) | +| 317 | MongoDB indexes carry their names | A MongoDB contract records each index's name: `map:`/`name` when written, otherwise its keys and directions (`email_1`), or Prisma 6's name for a Prisma 6 schema; two indexes of a collection with one name are refused. The planner pairs indexes by content and drops and creates one whose name changed; operations create, drop and check indexes by name; `db verify` reports a name difference | [ADR 317 - MongoDB indexes carry their names.md](adrs/ADR%20317%20-%20MongoDB%20indexes%20carry%20their%20names.md) | | 239 | Errors are structural envelopes with dotted namespace codes | Every user-facing error is a structural envelope with a dotted `NAMESPACE.SUBCODE` code, recognized by field shape rather than `instanceof`, so it survives the control/execution split, the wire, and duplicate library copies; bugs take the separate `InternalError` path; the numeric `PN-DOMAIN-NNNN` codes retire against a published crosswalk. Amended 2026-08-11: a command that ran to its end and found problems reports them as diagnostics in a completed envelope with a documented `4`–`99` exit code (never a thrown failure at exit `2`), and the freeform `fix` prose field becomes typed `nextActions`. | [ADR 239 - Errors are structural envelopes with dotted namespace codes.md](adrs/ADR%20239%20-%20Errors%20are%20structural%20envelopes%20with%20dotted%20namespace%20codes.md) | | 245 | Errors are structured at origin; results carry one ok discriminator | Governs how ADR 239’s envelopes are built and carried: every surfaced failure is structured where it is raised, with its own dotted code, `why`, and typed `nextActions` (no catch-all codes; the generic factory takes the code as a required first argument; a non-structured error at a process boundary is a bug, exit 1); `code` is the error’s only machine identity (`meta` never carries an alternative one, and the error-reference registry records each code’s producing sites and meta shapes); every operation returns the shared `Result` with the single `ok` discriminator and a `CliStructuredError` failure (per-operation outcome enums banned). Error subclasses extend the one base class — structured data in `meta`, `name` untouched so structural recognition holds, no boundary mappers. Composer records the same rules as its ADR-0043/0044. | [ADR 245 - Errors are structured at origin; results carry one ok discriminator.md](adrs/ADR%20245%20-%20Errors%20are%20structured%20at%20origin%3B%20results%20carry%20one%20ok%20discriminator.md) | diff --git a/docs/architecture docs/adrs/ADR 188 - MongoDB migration operation model.md b/docs/architecture docs/adrs/ADR 188 - MongoDB migration operation model.md index 831fbf40bf97..32f3fa68660e 100644 --- a/docs/architecture docs/adrs/ADR 188 - MongoDB migration operation model.md +++ b/docs/architecture docs/adrs/ADR 188 - MongoDB migration operation model.md @@ -18,14 +18,14 @@ Here is what the operation looks like: ```ts const op: MongoMigrationPlanOperation = { - id: 'index.users.create(email:1)', - label: 'Create index on users (email ascending)', + id: 'index.users.create(email_1)', + label: 'Create index email_1 on users (email:1)', operationClass: 'additive', precheck: [ { - description: 'index does not already exist', + description: 'no index named email_1 exists on users', source: new ListIndexesCommand('users'), - filter: MongoFieldFilter.eq('key', { email: 1 }), + filter: MongoFieldFilter.eq('name', 'email_1'), expect: 'notExists', }, ], @@ -40,9 +40,10 @@ const op: MongoMigrationPlanOperation = { ], postcheck: [ { - description: 'unique index exists', + description: 'index email_1 exists on users', source: new ListIndexesCommand('users'), filter: MongoAndExpr.of([ + MongoFieldFilter.eq('name', 'email_1'), MongoFieldFilter.eq('key', { email: 1 }), MongoFieldFilter.eq('unique', true), ]), diff --git a/docs/architecture docs/adrs/ADR 195 - Planner IR with two renderers.md b/docs/architecture docs/adrs/ADR 195 - Planner IR with two renderers.md index 465c34f0dd27..c47dda13f14e 100644 --- a/docs/architecture docs/adrs/ADR 195 - Planner IR with two renderers.md +++ b/docs/architecture docs/adrs/ADR 195 - Planner IR with two renderers.md @@ -9,7 +9,7 @@ The planner diffs two contracts and determines that a unique ascending index on `users.email` needs to be created. Rather than directly constructing the full operation ([ADR 188](ADR%20188%20-%20MongoDB%20migration%20operation%20model.md)), it produces an IR node: ```ts -const call = new CreateIndexCall('users', [{ field: 'email', direction: 1 }], { unique: true }); +const call = new CreateIndexCall('users', [{ field: 'email', direction: 1 }], { name: 'email_1', unique: true }); ``` Two renderers interpret this node. @@ -18,7 +18,7 @@ The **operation renderer** calls the `createIndex` factory function and produces ```ts renderOps([call]); -// → [{ id: 'index.users.create(email:1)', operationClass: 'additive', +// → [{ id: 'index.users.create(email_1)', operationClass: 'additive', // precheck: [...], execute: [...], postcheck: [...] }] ``` @@ -27,7 +27,7 @@ The **TypeScript renderer** produces a line of source code that calls the same f ```ts renderCallsToTypeScript([call], meta); // → ... -// createIndex('users', [{ field: 'email', direction: 1 }], { unique: true }) +// createIndex('users', [{ field: 'email', direction: 1 }], { name: 'email_1', unique: true }) // ... ``` diff --git a/docs/architecture docs/adrs/ADR 306 - One plain-data definition and one builder per family.md b/docs/architecture docs/adrs/ADR 306 - One plain-data definition and one builder per family.md index 85f77a27ddc0..97a7c1346bbe 100644 --- a/docs/architecture docs/adrs/ADR 306 - One plain-data definition and one builder per family.md +++ b/docs/architecture docs/adrs/ADR 306 - One plain-data definition and one builder per family.md @@ -64,9 +64,9 @@ The builder checks the assembled contract last. Those refusals (kind `validator` - One rule, one implementation. A rule added to the builder applies to every source. - A source can report every refusal at once, at its own position, because refusals are data, not thrown errors. - Sources cannot differ in what they accept. A parity suite writes each case in TypeScript and in PSL and checks that the two emitted `contract.json` files are byte-identical. -- Index order is the source's own. The builder does not reorder indexes, because the storage hash depends on their order. MongoDB PSL and TypeScript `defineContract` merge indexes before they call the builder, with `mergeRedundantIndexes`: when two indexes in one collection are identical, or one is a non-unique index made redundant by a unique index on the same keys and otherwise identical options, they remove one and keep the survivor where it was written. The builder itself refuses two identical indexes in one collection. +- Index order is the source's own. The builder does not reorder indexes, because the storage hash depends on their order. MongoDB PSL and TypeScript `defineContract` name and merge indexes before they call the builder. `nameIndexes` names each index written without a name after its stored keys, such as `email_1` ([ADR 317](ADR%20317%20-%20MongoDB%20indexes%20carry%20their%20names.md)). `mergeRedundantIndexes` then merges two indexes in one collection that have the same name. It merges them when they are identical. It also merges them when one is a non-unique index and the other is a unique index on the same keys with otherwise identical options, because the unique index makes the non-unique one redundant. It removes one index and keeps the survivor where it was written. The builder takes each index's name from the definition. It refuses two identical indexes in one collection, and two indexes with one name in one collection. The Prisma 6 reader names each index as Prisma 6 did. -SQL does not follow this ADR fully yet. Its builder throws its first refusal, so SQL PSL places only the errors it catches and matches (TML-3730). SQL PSL also adds polymorphism to the contract after the builder runs, instead of carrying it in the definition (TML-2228). +SQL does not follow this ADR fully yet. Its builder throws its first refusal, so SQL PSL places only the errors it catches and matches. SQL PSL also adds polymorphism to the contract after the builder runs, instead of carrying it in the definition. ## Alternatives considered diff --git a/docs/architecture docs/adrs/ADR 317 - MongoDB indexes carry their names.md b/docs/architecture docs/adrs/ADR 317 - MongoDB indexes carry their names.md new file mode 100644 index 000000000000..98766f830bec --- /dev/null +++ b/docs/architecture docs/adrs/ADR 317 - MongoDB indexes carry their names.md @@ -0,0 +1,118 @@ +# ADR 317 — MongoDB indexes carry their names + +**Status:** Accepted +**Builds on:** [ADR 188 — MongoDB migration operation model](ADR%20188%20-%20MongoDB%20migration%20operation%20model.md), [ADR 306 — One plain-data definition and one builder per family](ADR%20306%20-%20One%20plain-data%20definition%20and%20one%20builder%20per%20family.md) + +## At a glance + +This Prisma 8 schema asks for two indexes on `email`: a unique one and a sparse one. + +```prisma +model User { + id ObjectId @id @map("_id") + email String @unique + + @@index([email], sparse: true, map: "email_sparse") +} +``` + +The contract records each index with its name: + +```json +"indexes": [ + { "keys": [{ "direction": 1, "field": "email" }], "kind": "mongo-index", "name": "email_1", "unique": true }, + { "keys": [{ "direction": 1, "field": "email" }], "kind": "mongo-index", "name": "email_sparse", "sparse": true } +] +``` + +Both indexes can exist in the database at once. A migration creates each one under its name, drops it by its name, and `db verify` checks it by its name. + +## Decision + +`MongoIndex`, the contract's index node, has a required `name`. It is the name MongoDB stores the index under. The contract builder refuses two indexes with one name in one collection. + +## Why MongoDB needs names + +MongoDB identifies an index by its name, not by its keys. Several indexes in one collection may have the same keys and differ only in their options: a unique and a plain index, a plain and a sparse one, two indexes with different collations. Creating, dropping and checking an index by its keys alone cannot tell these apart, so the contract has to carry the name. + +MongoDB cannot rename an index. Changing a name means dropping the index and creating it again. + +## Where a name comes from + +**A written name.** In Prisma 8 PSL, `map:` on `@unique`, `@@index`, `@@unique` and `@@textIndex` names the index. In TypeScript `defineContract`, the index option `name` does. + +**No written name.** The index gets the name MongoDB gives an index created without one: each key's field and direction, joined by underscores, such as `email_1` or `title_text`. `defaultMongoIndexName` in `@internal/mongo-contract` builds it. Because this is MongoDB's own rule, an index created without a name already holds this name in the database. + +**Two indexes with one name.** Prisma 8 PSL and `defineContract` first merge an index that another index with the same name makes redundant, as described under "Where naming sits in the pipeline". When two indexes in one collection still have the same name after that, written or not, the schema is refused. The message asks for a name with `map:` or `name`. No second name is invented, because an invented name would depend on the order the indexes are written in, or change when another index appears. Either would drop and rebuild an index the user did not touch, since MongoDB cannot rename one. + +**Prisma 6 schemas.** The Prisma 6 reader gives each index the name Prisma 6 gives it, so that a database Prisma 6 built verifies as it is. The name is `map:` (or `name:` on `@@index`) when written. Otherwise it is the collection name, then the stored field names, joined by underscores, with `_key` for a unique index and `_idx` for any other, such as `User_email_key` or `User_email_idx`. The part before the suffix is cut so the whole name fits in 127 bytes. This follows prisma-engines 6.19.3 `ConstraintNames`. The reader refuses what Prisma 6 refuses: two indexes of one model with one name, an empty `map`, and a `map` longer than 127 bytes. + +## Where naming sits in the pipeline + +ADR 306 says each family has one plain-data definition and one builder, and the builder builds the definition it is given. Naming happens in the sources, before the builder. + +```mermaid +flowchart LR + subgraph sources [Sources] + direction TB + psl[Prisma 8 PSL] + ts[TypeScript defineContract] + p6[Prisma 6 reader] + end + name[nameIndexes] + merge[mergeRedundantIndexes] + builder[Builder] + psl --> name + ts --> name + name --> merge + merge --> builder + p6 --> builder +``` + +1. `nameIndexes` gives every index written without a name its default name. Prisma 8 PSL and `defineContract` call it. The Prisma 6 reader names its indexes itself. +2. `mergeRedundantIndexes` removes indexes another index makes unnecessary: the later of two identical indexes, or a plain index beside a unique index that is otherwise identical. It merges only indexes with the same name. Two identical indexes with different names are both kept, because the user named them apart. +3. The builder takes each name from the definition. It refuses two identical indexes in one collection, because MongoDB cannot hold both, and two indexes with one name in one collection (`indexNameDuplicate`). + +## How the planner pairs indexes + +The migration planner pairs an index of the starting state with an index of the target state by content: keys and options, with the name left out. `indexLookupKey` in `@internal/mongo-contract` computes this content key. Between two contracts, both sides hold indexes as they were written, so the content compares exactly. A schema read from a database needs one more step, described in the next section. + +This is why a MongoDB index name holds no content hash, unlike the SQL family's index names ([ADR 243](ADR%20243%20-%20Name-identified%20indexes%20and%20exact-name%20adoption.md)). SQL puts a hash of an index's content into its name because Postgres rewrites expression text, so SQL cannot compare two indexes' content directly and compares their names instead. MongoDB index content can be compared for equality exactly, so the planner compares the content itself, and the name only has to be the name the database holds. + +A pair whose content matches but whose names differ is planned as a drop and then a create, because MongoDB cannot rename an index. A pair with the same name and the same content plans nothing. Drops run before creates in every plan, which MongoDB needs: it refuses an index with the content of one it already holds. + +## Schemas read from a database + +A database does not list every index as it was written. It lists a text index's keys as `_fts` and `_ftsx` and fills in weights, the default language and the language override. It fills in the unwritten fields of a collation. So a database's index must be rewritten into its written form before it can be paired with a contract's index. + +Every `MongoSchemaIR` states whether it was read from a database, in its `fromDatabase` field. When the starting state was read from a database, as in `db init` and `db update`, the planner first rewrites both sides with `canonicalizeSchemasForVerification`, the rewrite `db verify` uses before it compares. It strips the values the database filled in for fields the contract did not write. When several contract indexes share a database index's keys, it matches the one with the same name. + +The rewritten forms are used for pairing only. Each create is built from the contract's own index, so `db init` and `db update` create exactly what `migration plan` writes. + +## The operations + +`createIndex(collection, keys, options)` creates the index under `options.name`. Its prechecks require that the collection holds no index with that name and none with the same keys and options. Its postcheck requires an index with that name, those keys and those options. + +`dropIndex(collection, keys, options)` drops the index named `options.name`. `options` lists every option the index has. Its precheck requires an index with that name, those keys and exactly those options. Its postcheck requires that no index with that name is left. + +The operation id is `index..()`, such as `index.users.create(email_sparse)`. + +Both factories accept a call without a name. Then the index is named after its keys, with `defaultMongoIndexName`. A `dropIndex` without options checks the keys only. + +## `db verify` + +`db verify` pairs the contract's indexes with the database's indexes by content, after the rewrite described above. An index of the contract whose content the database holds under another name is a failure. The failure carries the contract's index as `expected` and the database's index as `actual`. + +## Consequences + +- An index's name is part of the contract's storage section, so it is part of the storage hash. Renaming an index changes the hash. +- A schema with two unnamed indexes on the same keys and different options is refused until one of them is named, unless one makes the other redundant and they merge. Naming one keeps both apart; the builder still refuses them if their content is identical. +- The schema IR's index, `MongoSchemaIndex`, carries `name`, and its `id` is the name. Introspection reads it from `listIndexes`. +- A collation field the contract does not write may hold any value in the database, because the rewrite strips unwritten fields before comparing. Removing a field from a contract's collation, such as `strength`, is seen by `migration plan`, which compares two contracts, but not by `db update` or `db verify`. +- A MongoDB contract snapshot under `migrations/snapshots/` may hold a storage hash its content does not recompute to, because database markers, the ledger and every migration's `from` and `to` refer to that hash. A content check of MongoDB snapshots must allow this. + +## Alternatives considered + +- **Content-hashed names, as SQL's [ADR 243](ADR%20243%20-%20Name-identified%20indexes%20and%20exact-name%20adoption.md) does (`email_1_<8 hex>`).** The hash is not needed, because MongoDB index content compares exactly, as described under "How the planner pairs indexes". And MongoDB cannot rename an index, so moving existing databases to hashed names would rebuild every index. +- **No names in the contract, with drops that look an index up by content when the migration runs.** This needs a new runner command that finds an index by content and drops it. It leaves names unchecked. And it cannot describe the names Prisma 6 gives. +- **An optional name, where a missing one means the key-derived default.** This keeps storage hashes unchanged, but the contract would not state what the database holds, and every reader of the contract would have to know the default rule. diff --git a/docs/architecture docs/subsystems/10. MongoDB Family.md b/docs/architecture docs/subsystems/10. MongoDB Family.md index c15a2e529b42..8fdd39910be2 100644 --- a/docs/architecture docs/subsystems/10. MongoDB Family.md +++ b/docs/architecture docs/subsystems/10. MongoDB Family.md @@ -256,7 +256,8 @@ The builder decides these behaviours the same way for every source: | Behaviour | Every source | | --- | --- | -| Two identical indexes in one collection, after variant scoping | Refused. Two indexes are identical when they have the same keys and options, counting an option set to `false` as unset (`indexLookupKey`, which the planner also uses). A unique and a plain index on the same keys are both kept | +| Two identical indexes in one collection, after variant scoping | Refused. Two indexes are identical when they have the same keys and options, counting an option set to `false` as unset (`indexLookupKey`, which the planner also uses). The name does not count. A unique and a plain index on the same keys are both kept | +| Two indexes with one name in one collection | Refused (`indexNameDuplicate`). Every index has the name MongoDB stores it under ([ADR 317](../adrs/ADR%20317%20-%20MongoDB%20indexes%20carry%20their%20names.md)); the builder throws for an index without one | | `extensions` | The stack's extension packs | | Roots | Explicit roots when the source gives them, else one per model with a collection, no owner and no base | | A variant's collection | Its base's; another collection is refused | @@ -268,7 +269,7 @@ The builder decides these behaviours the same way for every source: | Generated values | As on SQL: an optional generated field is accepted; a list that generates a value is refused | | Index order | Each source's own; the builder does not reorder, because the storage hash depends on the order | -MongoDB PSL and TypeScript `defineContract` merge indexes before they call the builder, with `mergeRedundantIndexes` from `@internal/mongo-contract-ts`. Of two identical indexes in one collection the first is kept. A non-unique index beside a unique one that is otherwise identical is removed, so `@unique` and `@@index` on one field give one unique index. The index that is kept stays where it was written. The Prisma 6 reader merges nothing: it refuses two indexes of one model with the same fields and the same written sort, as Prisma 6 does (`PSL.PRISMA6_MONGO_INDEX_ALREADY_EXISTS`). +MongoDB PSL and TypeScript `defineContract` name indexes and then merge them before they call the builder, with `nameIndexes` and `mergeRedundantIndexes` from `@internal/mongo-contract-ts`. An index takes its name from `map:` in PSL or the index option `name` in TypeScript; without one, `nameIndexes` names it after its stored keys and directions, such as `email_1` or `title_text`, the name MongoDB gives an index created without one. Two indexes of one collection that get one name are refused, so a unique and a plain index on the same keys, or one index on the same field in each of two variants, need a name for one of them. `mergeRedundantIndexes` merges only indexes with the same name. Of two identical indexes in one collection the first is kept. A non-unique index beside a unique one that is otherwise identical is removed, so `@unique` and `@@index` on one field give one unique index. The index that is kept stays where it was written. The Prisma 6 reader merges nothing: it refuses two indexes of one model with the same fields and the same written sort, as Prisma 6 does (`PSL.PRISMA6_MONGO_INDEX_ALREADY_EXISTS`). It names each index as Prisma 6 did: by `map:` (or `name:` on `@@index`), otherwise `__key` for a unique index and `_idx` for any other, cut to 127 bytes, and it refuses two indexes of one model with one name, as Prisma 6 does (`PSL.PRISMA6_MONGO_INDEX_NAME_DUPLICATE`). A parity suite, `test/integration/test/authoring/mongo-parity.test.ts`, writes each case in TypeScript and in PSL and checks that the two emitted `contract.json` files are byte-identical. @@ -515,6 +516,8 @@ The factories the scaffold imports live in two layered modules: - `@internal/family-mongo/migration` — the `Migration` base class (a `MongoMigration` subclass that `implements MigrationPlan`) plus `Migration.run(...)` for the shebang self-emit path ([ADR 196](../adrs/ADR%20196%20-%20In-process%20emit%20for%20class-flow%20targets.md)). - `@internal/target-mongo/migration` — the operation factories (`createCollection`, `dropCollection`, `renameCollection`, `createIndex`, `dropIndex`, `collMod`, `setValidation`, `validatedCollection`, `renameField`, `unsetField`, `dataTransform`) and the `placeholder(slot)` utility for unfilled scaffold slots. +`createIndex(collection, keys, options)` creates the index named `options.name`; its prechecks require that the collection holds no index with that name and none with the same keys and options. `dropIndex(collection, keys, options)` drops the index named `options.name`, after checking that an index with that name, those keys and exactly the options it lists exists; `options` lists every option the index has. Without a name, both use the name MongoDB gives the keys, as migration files written before index names did. The planner pairs the origin's and the contract's indexes by `indexLookupKey`, which leaves the name out; for an origin read from a database (`MongoSchemaIR.fromDatabase`), it first undoes the server's text-index and collation defaults as the verifier does. It plans a drop and a create for a pair whose names differ, because MongoDB cannot rename an index; drops run before creates. Operation ids name the index: `index.users.create(email_1)`. `db verify` reports an index the database holds under another name than the contract's, and the schema IR identifies each index by its name ([ADR 317](../adrs/ADR%20317%20-%20MongoDB%20indexes%20carry%20their%20names.md)). + `renameCollection(from, to)` renames a collection, keeping its documents, indexes and validator; it checks that the source exists and the target does not. `renameField(collection, from, to, { filter? })` and `unsetField(collection, field, { filter? })` rewrite the documents that hold the field with one `updateMany` (`$rename` or `$unset`) that skips validation; `filter` limits them to one variant's documents. They refuse an empty field name, `_id`, and a name containing `.` or starting with `$`. The planner emits all three for `--rename` and `--delete` statements; see [Subsystem 7 — Rename statements](7.%20Migration%20System.md#rename-statements). A scaffolded `migration.ts` therefore looks like: @@ -528,7 +531,7 @@ class M extends Migration { override describe() { return { from: 'abc', to: 'def' } } override plan() { return [ - createIndex('users', [{ field: 'email', direction: 1 }], { unique: true }), + createIndex('users', [{ field: 'email', direction: 1 }], { name: 'email_1', unique: true }), ] } } diff --git a/docs/architecture docs/subsystems/7. Migration System.md b/docs/architecture docs/subsystems/7. Migration System.md index 9f3fe202ff0e..46cd80e25864 100644 --- a/docs/architecture docs/subsystems/7. Migration System.md +++ b/docs/architecture docs/subsystems/7. Migration System.md @@ -296,7 +296,7 @@ class M extends Migration { override plan() { return [ - createIndex('users', [{ field: 'email', direction: 1 }], { unique: true }), + createIndex('users', [{ field: 'email', direction: 1 }], { name: 'email_1', unique: true }), ] } } diff --git a/docs/reference/error-reference.md b/docs/reference/error-reference.md index 56666919a062..f47475d42b16 100644 --- a/docs/reference/error-reference.md +++ b/docs/reference/error-reference.md @@ -535,7 +535,7 @@ The contract module at the configured path loads but exposes neither a `default` ### CONTRACT.NAME_DUPLICATE -Two declarations claim the same name: duplicate namespace entries, model names, value objects, relations, tables (two models mapping to one table, two table nodes for one table, or duplicate table in a namespace), column mappings (two fields to one column, a field and a table node's column node for one column, or two column nodes for one column), stored names (two fields of one MongoDB model stored under one name with `.mongo({ field })`: `Model "" stores both "" and "" as "".`, `kind: 'field'`), indexes (two identical indexes in one MongoDB collection: `kind: 'index'`, with `collection`; TypeScript `defineContract` merges identical indexes before the build, so only a definition passed to `buildMongoContractFromDefinition` directly reaches this), value-sets (enum and pack entity minting the same value-set), or pack entities of the same kind and name in one namespace. A Postgres extension is unique across the whole contract: one declared in two namespaces is refused while building a contract and again when a contract is read (`kind: 'extension'`, `namespaces`). Payload: `kind`, `name`, `namespaceId`, `tableName` (for a column), `first`, `second`. A MongoDB variant field stored under a name a field of its base is stored under, the discriminator included, is refused too (`reason: 'stored-name-shared-with-base'`, with `first` the base's field and `second` the variant's): a variant's documents hold its base's fields, so the two would overwrite each other. Mongo PSL reports it as `PSL_DUPLICATE_STORED_NAME`. +Two declarations claim the same name: duplicate namespace entries, model names, value objects, relations, tables (two models mapping to one table, two table nodes for one table, or duplicate table in a namespace), column mappings (two fields to one column, a field and a table node's column node for one column, or two column nodes for one column), stored names (two fields of one MongoDB model stored under one name with `.mongo({ field })`: `Model "" stores both "" and "" as "".`, `kind: 'field'`), indexes (two identical indexes in one MongoDB collection: `kind: 'index'`, with `collection`; TypeScript `defineContract` merges identical indexes with the same name before the build, so it reaches this for two identical indexes that the index option `name` names apart, which MongoDB cannot hold both of; and two indexes of one MongoDB collection with one name, written with the index option `name` or given after their keys and directions, such as two unnamed indexes on `email`, one unique and one plain, both named `email_1`: `Collection "" has two indexes named "": ... Give one of them another name with the index option name.`, `kind: 'index'`, `reason: 'index-name-duplicate'`, with `collection`; Mongo PSL reports both as `PSL_INVALID_INDEX` at the second index), value-sets (enum and pack entity minting the same value-set), or pack entities of the same kind and name in one namespace. A Postgres extension is unique across the whole contract: one declared in two namespaces is refused while building a contract and again when a contract is read (`kind: 'extension'`, `namespaces`). Payload: `kind`, `name`, `namespaceId`, `tableName` (for a column), `first`, `second`. A MongoDB variant field stored under a name a field of its base is stored under, the discriminator included, is refused too (`reason: 'stored-name-shared-with-base'`, with `first` the base's field and `second` the variant's): a variant's documents hold its base's fields, so the two would overwrite each other. Mongo PSL reports it as `PSL_DUPLICATE_STORED_NAME`. ### CONTRACT.NAMESPACE_INVALID @@ -728,7 +728,15 @@ Reported by the Prisma 6 MongoDB contract source (`prisma6Schema`) during `contr ### PSL.PRISMA6_MONGO_INDEX_ARGUMENT_UNSUPPORTED -An index argument a Mongo contract index cannot carry, such as `length`, an unknown argument, or a dotted path whose first segment is not a composite-type field (`title.first`), which Prisma 6 refuses as an unknown field. `sort` is read, and `map` and `name` are accepted and dropped, since Mongo verify matches indexes by keys and options. Remove the argument. Reported by the Prisma 6 MongoDB contract source (`prisma6Schema`) during `contract emit`, as a finding in the `diagnostics` list of `CONTRACT.SOURCE_LOAD_FAILED`, never on its own. `summary` is `:: `, with only the file when there is no position (the terminal prints the code before it), and `where` carries `path` and, when known, `line`. Payload: none. +An index argument a Mongo contract index cannot carry, such as `length`, an unknown argument, or a dotted path whose first segment is not a composite-type field (`title.first`), which Prisma 6 refuses as an unknown field. `sort` and `map` are read, and so is `name` on `@@index`, which Prisma 6 reads as `map`; `name` on `@@unique` names the Prisma 6 client field and is dropped. An index with both `map` and `name` on `@@index`, or a `map` or `name` that is not a string, is refused here too. Remove the argument. Reported by the Prisma 6 MongoDB contract source (`prisma6Schema`) during `contract emit`, as a finding in the `diagnostics` list of `CONTRACT.SOURCE_LOAD_FAILED`, never on its own. `summary` is `:: `, with only the file when there is no position (the terminal prints the code before it), and `where` carries `path` and, when known, `line`. Payload: none. + +### PSL.PRISMA6_MONGO_INDEX_NAME_DUPLICATE + +Two indexes of one Prisma 6 model get one name, which Prisma 6 refuses: "The given constraint name `` has to be unique in the following namespace: on model `` for indexes and unique constraints." An index is named by `map:` (or `name:` on `@@index`), otherwise `__key` for a unique index and `_idx` for others, so `@@index([name])` beside `@@index([name(sort: Asc)])` are both `User_name_idx`. The code is reported at each index of the pair, naming the other. It is also reported at the second index when indexes of two models stored in one collection get one name, which MongoDB cannot hold. Give one of them another name with `map`. Reported by the Prisma 6 MongoDB contract source (`prisma6Schema`) during `contract emit`, as a finding in the `diagnostics` list of `CONTRACT.SOURCE_LOAD_FAILED`, never on its own. `summary` is `:: `, with only the file when there is no position (the terminal prints the code before it), and `where` carries `path` and, when known, `line`. Payload: none. + +### PSL.PRISMA6_MONGO_INDEX_NAME_INVALID + +A `map:` that Prisma 6 refuses: an empty string, or a name longer than 127 bytes, the longest index name Prisma 6 accepts on MongoDB. Give the index a name Prisma 6 accepts. Reported by the Prisma 6 MongoDB contract source (`prisma6Schema`) during `contract emit`, as a finding in the `diagnostics` list of `CONTRACT.SOURCE_LOAD_FAILED`, never on its own. `summary` is `:: `, with only the file when there is no position (the terminal prints the code before it), and `where` carries `path` and, when known, `line`. Payload: none. ### PSL.PRISMA6_MONGO_LIST_RELATION_UNSUPPORTED diff --git a/examples/mongo-blog-leaderboard/src/contract.d.ts b/examples/mongo-blog-leaderboard/src/contract.d.ts index cfcf297baede..42f8443899ec 100644 --- a/examples/mongo-blog-leaderboard/src/contract.d.ts +++ b/examples/mongo-blog-leaderboard/src/contract.d.ts @@ -23,7 +23,7 @@ import type { } from '@prisma/orm-mongo/contract/types'; export type StorageHash = - StorageHashBase<'4211584674f0ef61d518d3b24b3380e1760d7e46d6dd7098b1b0b1dc19ff3e30'>; + StorageHashBase<'395d910a151cb498283db67859cb88f21bff6fc73aeb92e3840d0e981a515359'>; export type ExecutionHash = ExecutionHashBase; export type ProfileHash = ProfileHashBase<'251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3'>; @@ -136,10 +136,12 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'authorId' }]; readonly kind: 'mongo-index'; + readonly name: 'authorId_1'; }, { readonly keys: readonly [{ readonly direction: -1; readonly field: 'createdAt' }]; readonly kind: 'mongo-index'; + readonly name: 'createdAt_-1'; }, ]; readonly kind: 'mongo-collection'; diff --git a/examples/mongo-blog-leaderboard/src/contract.json b/examples/mongo-blog-leaderboard/src/contract.json index 491858a73218..42d5e51f6c17 100644 --- a/examples/mongo-blog-leaderboard/src/contract.json +++ b/examples/mongo-blog-leaderboard/src/contract.json @@ -272,7 +272,8 @@ "field": "authorId" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "authorId_1" }, { "keys": [ @@ -281,7 +282,8 @@ "field": "createdAt" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "createdAt_-1" } ], "kind": "mongo-collection", @@ -499,7 +501,7 @@ "kind": "mongo-database" } }, - "storageHash": "4211584674f0ef61d518d3b24b3380e1760d7e46d6dd7098b1b0b1dc19ff3e30" + "storageHash": "395d910a151cb498283db67859cb88f21bff6fc73aeb92e3840d0e981a515359" }, "capabilities": {}, "extensions": {}, diff --git a/examples/mongo-demo/migrations/app/20260409T1030_migration/migration.json b/examples/mongo-demo/migrations/app/20260409T1030_migration/migration.json index eb148543a554..389379778414 100644 --- a/examples/mongo-demo/migrations/app/20260409T1030_migration/migration.json +++ b/examples/mongo-demo/migrations/app/20260409T1030_migration/migration.json @@ -1,7 +1,7 @@ { "from": null, - "to": "396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901", + "to": "3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95", "providedInvariants": [], "createdAt": "2026-04-09T10:30:13.948Z", - "migrationHash": "a4dbf4e008b176a2fed392de87662f68cd4c2f537b60cf760e234048e6f55abe" + "migrationHash": "05d5b9fc0b3085156f8a977d357cedfbeea399b5b4d816adf8c981fa8da863c5" } diff --git a/examples/mongo-demo/migrations/app/20260409T1030_migration/migration.ts b/examples/mongo-demo/migrations/app/20260409T1030_migration/migration.ts index 24f8a81660b0..b8f0965c7f3a 100644 --- a/examples/mongo-demo/migrations/app/20260409T1030_migration/migration.ts +++ b/examples/mongo-demo/migrations/app/20260409T1030_migration/migration.ts @@ -1,6 +1,6 @@ import { createIndex, Migration, MigrationCLI } from '@prisma/orm-mongo/target/migration'; -import type { Contract as End } from '../../snapshots/396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901/contract'; -import endContract from '../../snapshots/396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901/contract.json' with { +import type { Contract as End } from '../../snapshots/3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95/contract'; +import endContract from '../../snapshots/3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95/contract.json' with { type: 'json', }; diff --git a/examples/mongo-demo/migrations/app/20260409T1030_migration/ops.json b/examples/mongo-demo/migrations/app/20260409T1030_migration/ops.json index 533b620b26a8..a8c90805d59d 100644 --- a/examples/mongo-demo/migrations/app/20260409T1030_migration/ops.json +++ b/examples/mongo-demo/migrations/app/20260409T1030_migration/ops.json @@ -1,47 +1,26 @@ [ { - "id": "index.users.create(email:1)", - "label": "Create index on users (email:1)", + "id": "index.users.create(email_1)", + "label": "Create index email_1 on users (email:1)", "operationClass": "additive", "precheck": [ { - "description": "index does not already exist on users", + "description": "no index named email_1 exists on users", "source": { "kind": "listIndexes", "collection": "users" }, "filter": { "kind": "field", - "field": "key", + "field": "name", "op": "$eq", - "value": { - "email": 1 - } + "value": "email_1" }, "expect": "notExists", - "object": "an index on { email: 1 } in \"users\"" - } - ], - "execute": [ + "object": "an index named \"email_1\" in \"users\"" + }, { - "description": "create index on users", - "command": { - "kind": "createIndex", - "collection": "users", - "keys": [ - { - "field": "email", - "direction": 1 - } - ], - "unique": true, - "name": "email_1" - } - } - ], - "postcheck": [ - { - "description": "index exists on users", + "description": "no index with the same keys and options exists on users", "source": { "kind": "listIndexes", "collection": "users" @@ -94,6 +73,93 @@ } ] }, + "expect": "notExists", + "object": "an index on { email: 1 } in \"users\"" + } + ], + "execute": [ + { + "description": "create index email_1 on users", + "command": { + "kind": "createIndex", + "collection": "users", + "keys": [ + { + "field": "email", + "direction": 1 + } + ], + "unique": true, + "name": "email_1" + } + } + ], + "postcheck": [ + { + "description": "index email_1 exists on users", + "source": { + "kind": "listIndexes", + "collection": "users" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "email_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "email": 1 + } + }, + { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, "expect": "exists" } ] diff --git a/examples/mongo-demo/migrations/app/20260626T1605_add_user_role_enum/migration.json b/examples/mongo-demo/migrations/app/20260626T1605_add_user_role_enum/migration.json index 8ee13dc3e337..d489b67899b1 100644 --- a/examples/mongo-demo/migrations/app/20260626T1605_add_user_role_enum/migration.json +++ b/examples/mongo-demo/migrations/app/20260626T1605_add_user_role_enum/migration.json @@ -1,7 +1,7 @@ { - "from": "396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901", - "to": "95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9", + "from": "3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95", + "to": "b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4", "providedInvariants": [], "createdAt": "2026-06-26T16:05:45.955Z", - "migrationHash": "08ac0867c606d262ac4dc80b3ad7f1f0afc8418bd72fe957c13c9c549bfc4651" + "migrationHash": "7f999b8c8dbbc73f6aba713227f5dbc8046fd6151c906d9fb35115abaed458dd" } diff --git a/examples/mongo-demo/migrations/app/20260626T1605_add_user_role_enum/migration.ts b/examples/mongo-demo/migrations/app/20260626T1605_add_user_role_enum/migration.ts index 9284d486566d..926b1ac3d889 100755 --- a/examples/mongo-demo/migrations/app/20260626T1605_add_user_role_enum/migration.ts +++ b/examples/mongo-demo/migrations/app/20260626T1605_add_user_role_enum/migration.ts @@ -1,11 +1,11 @@ #!/usr/bin/env -S node import { collMod, Migration, MigrationCLI } from '@prisma/orm-mongo/target/migration'; -import type { Contract as End } from '../../snapshots/95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9/contract'; -import endContract from '../../snapshots/95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9/contract.json' with { +import type { Contract as Start } from '../../snapshots/3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95/contract'; +import startContract from '../../snapshots/3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95/contract.json' with { type: 'json', }; -import type { Contract as Start } from '../../snapshots/396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901/contract'; -import startContract from '../../snapshots/396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901/contract.json' with { +import type { Contract as End } from '../../snapshots/b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4/contract'; +import endContract from '../../snapshots/b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4/contract.json' with { type: 'json', }; diff --git a/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/migration.json b/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/migration.json index 76235940857c..e11af264265d 100644 --- a/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/migration.json +++ b/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/migration.json @@ -1,7 +1,7 @@ { - "from": "95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9", - "to": "406b672b68a6b01f04c0d6f910f5fefa4ac16d48b26e6c91b43856cd42c8cc5d", + "from": "b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4", + "to": "61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c", "providedInvariants": [], "createdAt": "2026-06-26T19:16:47.657Z", - "migrationHash": "a77e60df92e1d3ee6a5a000904e3aa1869a382d602279a64bce9038c17c0475d" + "migrationHash": "20311870daddb0ddf2d164992fdc817698a53056ac165d23d200652a7fb33703" } diff --git a/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/migration.ts b/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/migration.ts index 83da597d716d..08174ce35eca 100755 --- a/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/migration.ts +++ b/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/migration.ts @@ -1,11 +1,11 @@ #!/usr/bin/env -S node import { createIndex, Migration, MigrationCLI } from '@prisma/orm-mongo/target/migration'; -import type { Contract as End } from '../../snapshots/406b672b68a6b01f04c0d6f910f5fefa4ac16d48b26e6c91b43856cd42c8cc5d/contract'; -import endContract from '../../snapshots/406b672b68a6b01f04c0d6f910f5fefa4ac16d48b26e6c91b43856cd42c8cc5d/contract.json' with { +import type { Contract as End } from '../../snapshots/61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c/contract'; +import endContract from '../../snapshots/61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c/contract.json' with { type: 'json', }; -import type { Contract as Start } from '../../snapshots/95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9/contract'; -import startContract from '../../snapshots/95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9/contract.json' with { +import type { Contract as Start } from '../../snapshots/b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4/contract'; +import startContract from '../../snapshots/b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4/contract.json' with { type: 'json', }; diff --git a/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/ops.json b/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/ops.json index d9b60da89298..46a55531e6c4 100644 --- a/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/ops.json +++ b/examples/mongo-demo/migrations/app/20260626T1916_add_posts_indexes/ops.json @@ -1,46 +1,26 @@ [ { - "id": "index.posts.create(authorId:1)", - "label": "Create index on posts (authorId:1)", + "id": "index.posts.create(authorId_1)", + "label": "Create index authorId_1 on posts (authorId:1)", "operationClass": "additive", "precheck": [ { - "description": "index does not already exist on posts", + "description": "no index named authorId_1 exists on posts", "source": { "kind": "listIndexes", "collection": "posts" }, "filter": { "kind": "field", - "field": "key", + "field": "name", "op": "$eq", - "value": { - "authorId": 1 - } + "value": "authorId_1" }, "expect": "notExists", - "object": "an index on { authorId: 1 } in \"posts\"" - } - ], - "execute": [ + "object": "an index named \"authorId_1\" in \"posts\"" + }, { - "description": "create index on posts", - "command": { - "kind": "createIndex", - "collection": "posts", - "keys": [ - { - "direction": 1, - "field": "authorId" - } - ], - "name": "authorId_1" - } - } - ], - "postcheck": [ - { - "description": "index exists on posts", + "description": "no index with the same keys and options exists on posts", "source": { "kind": "listIndexes", "collection": "posts" @@ -96,57 +76,121 @@ } ] }, - "expect": "exists" - } - ] - }, - { - "id": "index.posts.create(createdAt:-1,authorId:1)", - "label": "Create index on posts (createdAt:-1, authorId:1)", - "operationClass": "additive", - "precheck": [ - { - "description": "index does not already exist on posts", - "source": { - "kind": "listIndexes", - "collection": "posts" - }, - "filter": { - "kind": "field", - "field": "key", - "op": "$eq", - "value": { - "createdAt": -1, - "authorId": 1 - } - }, "expect": "notExists", - "object": "an index on { createdAt: -1, authorId: 1 } in \"posts\"" + "object": "an index on { authorId: 1 } in \"posts\"" } ], "execute": [ { - "description": "create index on posts", + "description": "create index authorId_1 on posts", "command": { "kind": "createIndex", "collection": "posts", "keys": [ - { - "direction": -1, - "field": "createdAt" - }, { "direction": 1, "field": "authorId" } ], - "name": "createdAt_-1_authorId_1" + "name": "authorId_1" } } ], "postcheck": [ { - "description": "index exists on posts", + "description": "index authorId_1 exists on posts", + "source": { + "kind": "listIndexes", + "collection": "posts" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "authorId_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "authorId": 1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, + "expect": "exists" + } + ] + }, + { + "id": "index.posts.create(createdAt_-1_authorId_1)", + "label": "Create index createdAt_-1_authorId_1 on posts (createdAt:-1, authorId:1)", + "operationClass": "additive", + "precheck": [ + { + "description": "no index named createdAt_-1_authorId_1 exists on posts", + "source": { + "kind": "listIndexes", + "collection": "posts" + }, + "filter": { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "createdAt_-1_authorId_1" + }, + "expect": "notExists", + "object": "an index named \"createdAt_-1_authorId_1\" in \"posts\"" + }, + { + "description": "no index with the same keys and options exists on posts", "source": { "kind": "listIndexes", "collection": "posts" @@ -203,6 +247,100 @@ } ] }, + "expect": "notExists", + "object": "an index on { createdAt: -1, authorId: 1 } in \"posts\"" + } + ], + "execute": [ + { + "description": "create index createdAt_-1_authorId_1 on posts", + "command": { + "kind": "createIndex", + "collection": "posts", + "keys": [ + { + "direction": -1, + "field": "createdAt" + }, + { + "direction": 1, + "field": "authorId" + } + ], + "name": "createdAt_-1_authorId_1" + } + } + ], + "postcheck": [ + { + "description": "index createdAt_-1_authorId_1 exists on posts", + "source": { + "kind": "listIndexes", + "collection": "posts" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "createdAt_-1_authorId_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "createdAt": -1, + "authorId": 1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, "expect": "exists" } ] diff --git a/examples/mongo-demo/migrations/snapshots/396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901/contract.d.ts b/examples/mongo-demo/migrations/snapshots/3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95/contract.d.ts similarity index 99% rename from examples/mongo-demo/migrations/snapshots/396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901/contract.d.ts rename to examples/mongo-demo/migrations/snapshots/3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95/contract.d.ts index 450aa81593d9..5240d73487ee 100644 --- a/examples/mongo-demo/migrations/snapshots/396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901/contract.d.ts +++ b/examples/mongo-demo/migrations/snapshots/3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95/contract.d.ts @@ -23,7 +23,7 @@ import type { } from '@prisma/orm-mongo/contract/types'; export type StorageHash = - StorageHashBase<'396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901'>; + StorageHashBase<'3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95'>; export type ExecutionHash = ExecutionHashBase; export type ProfileHash = ProfileHashBase<'251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3'>; @@ -136,6 +136,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'summary' }]; readonly kind: 'mongo-index'; + readonly name: 'summary_1'; readonly partialFilterExpression: { readonly kind: 'article' }; readonly unique: true; }, diff --git a/examples/mongo-demo/migrations/snapshots/396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901/contract.json b/examples/mongo-demo/migrations/snapshots/3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95/contract.json similarity index 56% rename from examples/mongo-demo/migrations/snapshots/396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901/contract.json rename to examples/mongo-demo/migrations/snapshots/3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95/contract.json index 5699666ec9cd..dc755c355b17 100644 --- a/examples/mongo-demo/migrations/snapshots/396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901/contract.json +++ b/examples/mongo-demo/migrations/snapshots/3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95/contract.json @@ -1 +1 @@ -{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"models":{"Article":{"base":{"model":"Post","namespace":"__unbound__"},"fields":{"summary":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"posts","fields":{"summary":{"field":"summary"}}}},"Post":{"discriminator":{"field":"kind"},"fields":{"authorId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"content":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"createdAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"kind":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"title":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"author":{"cardinality":"N:1","nullable":false,"on":{"localFields":["authorId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"posts","fields":{"authorId":{"field":"authorId"},"content":{"field":"content"},"createdAt":{"field":"createdAt"},"id":{"field":"_id"},"kind":{"field":"kind"},"title":{"field":"title"}}},"variants":{"article":{"model":"Article","namespace":"__unbound__"},"tutorial":{"model":"Tutorial","namespace":"__unbound__"}}},"Tutorial":{"base":{"model":"Post","namespace":"__unbound__"},"fields":{"difficulty":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"duration":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"posts","fields":{"difficulty":{"field":"difficulty"},"duration":{"field":"duration"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"bio":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"posts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["authorId"]},"to":{"model":"Post","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"bio":{"field":"bio"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"posts":{"model":"Post","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"posts":{"indexes":[{"keys":[{"direction":1,"field":"summary"}],"kind":"mongo-index","partialFilterExpression":{"kind":"article"},"unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"kind":{"enum":["article"]},"summary":{"bsonType":"string"},"title":{"bsonType":"string"}},"required":["kind","summary"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"difficulty":{"bsonType":"string"},"duration":{"bsonType":"int"},"kind":{"enum":["tutorial"]},"title":{"bsonType":"string"}},"required":["difficulty","duration","kind"]}],"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"kind":{"bsonType":"string"},"title":{"bsonType":"string"}},"required":["_id","authorId","content","createdAt","kind","title"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"street":{"bsonType":"string"},"zip":{"bsonType":["null","string"]}},"required":["city","country","street"]}]},"bio":{"bsonType":["null","string"]},"email":{"bsonType":"string"},"name":{"bsonType":"string"}},"required":["_id","email","name"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"street":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"zip":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"396942f6c9ee5f946d7f67b397929bab327fe84dd8f7f80e87b8097f416fb901"},"target":"mongo","targetFamily":"mongo"} +{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"models":{"Article":{"base":{"model":"Post","namespace":"__unbound__"},"fields":{"summary":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"posts","fields":{"summary":{"field":"summary"}}}},"Post":{"discriminator":{"field":"kind"},"fields":{"authorId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"content":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"createdAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"kind":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"title":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"author":{"cardinality":"N:1","nullable":false,"on":{"localFields":["authorId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"posts","fields":{"authorId":{"field":"authorId"},"content":{"field":"content"},"createdAt":{"field":"createdAt"},"id":{"field":"_id"},"kind":{"field":"kind"},"title":{"field":"title"}}},"variants":{"article":{"model":"Article","namespace":"__unbound__"},"tutorial":{"model":"Tutorial","namespace":"__unbound__"}}},"Tutorial":{"base":{"model":"Post","namespace":"__unbound__"},"fields":{"difficulty":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"duration":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"posts","fields":{"difficulty":{"field":"difficulty"},"duration":{"field":"duration"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"bio":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"posts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["authorId"]},"to":{"model":"Post","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"bio":{"field":"bio"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"posts":{"model":"Post","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"posts":{"indexes":[{"keys":[{"direction":1,"field":"summary"}],"kind":"mongo-index","name":"summary_1","partialFilterExpression":{"kind":"article"},"unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"kind":{"enum":["article"]},"summary":{"bsonType":"string"},"title":{"bsonType":"string"}},"required":["kind","summary"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"difficulty":{"bsonType":"string"},"duration":{"bsonType":"int"},"kind":{"enum":["tutorial"]},"title":{"bsonType":"string"}},"required":["difficulty","duration","kind"]}],"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"kind":{"bsonType":"string"},"title":{"bsonType":"string"}},"required":["_id","authorId","content","createdAt","kind","title"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"street":{"bsonType":"string"},"zip":{"bsonType":["null","string"]}},"required":["city","country","street"]}]},"bio":{"bsonType":["null","string"]},"email":{"bsonType":"string"},"name":{"bsonType":"string"}},"required":["_id","email","name"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"street":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"zip":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"3055d5ffb87a65023bf2809ae55770f7be848d798989bff1a9613474898dcd95"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/mongo-demo/migrations/snapshots/61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c/contract.d.ts b/examples/mongo-demo/migrations/snapshots/61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c/contract.d.ts new file mode 100644 index 000000000000..4a7ff7a4b1d5 --- /dev/null +++ b/examples/mongo-demo/migrations/snapshots/61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c/contract.d.ts @@ -0,0 +1,493 @@ +// ⚠️ GENERATED FILE - DO NOT EDIT +// This file is automatically generated by 'prisma contract emit'. +// To regenerate, run: prisma contract emit +import type { + CodecTypes as MongoCodecTypes, + ParameterizedOutputTypesForTypeParams as MongoParameterizedOutputTypes, +} from '@prisma/orm-mongo/target/codec-types'; + +import type { + MongoCollection, + MongoContractWithTypeMaps, + MongoTypeMaps, + RelationKeys, +} from '@prisma/orm-mongo/family-contract'; +import type { + Contract as ContractType, + ExecutionHashBase, + FieldTypesFromDomain, + NamespaceId, + ProfileHashBase, + StorageHashBase, + ValueObjectTypesFromStorage, +} from '@prisma/orm-mongo/contract/types'; + +export type StorageHash = + StorageHashBase<'61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c'>; +export type ExecutionHash = ExecutionHashBase; +export type ProfileHash = + ProfileHashBase<'251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3'>; + +export type CodecTypes = MongoCodecTypes; + +type ParameterizedOutputTypeFunctions = MongoParameterizedOutputTypes; +type ValueObjectOutputTypes = ValueObjectTypesFromStorage< + ContractBase['storage']['namespaces'], + CodecTypes, + ParameterizedOutputTypeFunctions, + FieldTypeOverrides, + 'output' +>; +type ValueObjectInputTypes = ValueObjectTypesFromStorage< + ContractBase['storage']['namespaces'], + CodecTypes, + ParameterizedOutputTypeFunctions, + FieldTypeOverrides, + 'input' +>; +export type AddressOutput = ValueObjectOutputTypes['__unbound__']['Address']; +export type AddressInput = ValueObjectInputTypes['__unbound__']['Address']; +type FieldTypeOverrides = { + readonly __unbound__: { + readonly models: { + readonly User: { + readonly role: { + readonly output: 'admin' | 'author' | 'reader'; + readonly input: 'admin' | 'author' | 'reader'; + }; + }; + }; + }; +}; +export type FieldOutputTypes = FieldTypesFromDomain< + ContractBase['domain']['namespaces'], + CodecTypes, + ParameterizedOutputTypeFunctions, + FieldTypeOverrides, + 'output', + ContractBase['storage']['namespaces'] +>; +export type FieldInputTypes = FieldTypesFromDomain< + ContractBase['domain']['namespaces'], + CodecTypes, + ParameterizedOutputTypeFunctions, + FieldTypeOverrides, + 'input', + ContractBase['storage']['namespaces'] +>; + +export namespace Models { + export type unbound_Article = { + authorId: FieldOutputTypes['__unbound__']['Post']['authorId']; + content: FieldOutputTypes['__unbound__']['Post']['content']; + createdAt: FieldOutputTypes['__unbound__']['Post']['createdAt']; + id: FieldOutputTypes['__unbound__']['Post']['id']; + kind: 'article'; + title: FieldOutputTypes['__unbound__']['Post']['title']; + summary: FieldOutputTypes['__unbound__']['Article']['summary']; + author: unbound_User; + readonly [RelationKeys]?: 'author'; + }; + export type unbound_Post = { + authorId: FieldOutputTypes['__unbound__']['Post']['authorId']; + content: FieldOutputTypes['__unbound__']['Post']['content']; + createdAt: FieldOutputTypes['__unbound__']['Post']['createdAt']; + id: FieldOutputTypes['__unbound__']['Post']['id']; + kind: 'article' | 'tutorial'; + title: FieldOutputTypes['__unbound__']['Post']['title']; + author: unbound_User; + readonly [RelationKeys]?: 'author'; + }; + export type unbound_Tutorial = { + authorId: FieldOutputTypes['__unbound__']['Post']['authorId']; + content: FieldOutputTypes['__unbound__']['Post']['content']; + createdAt: FieldOutputTypes['__unbound__']['Post']['createdAt']; + id: FieldOutputTypes['__unbound__']['Post']['id']; + kind: 'tutorial'; + title: FieldOutputTypes['__unbound__']['Post']['title']; + difficulty: FieldOutputTypes['__unbound__']['Tutorial']['difficulty']; + duration: FieldOutputTypes['__unbound__']['Tutorial']['duration']; + author: unbound_User; + readonly [RelationKeys]?: 'author'; + }; + export type unbound_User = { + address: FieldOutputTypes['__unbound__']['User']['address']; + bio: FieldOutputTypes['__unbound__']['User']['bio']; + email: FieldOutputTypes['__unbound__']['User']['email']; + id: FieldOutputTypes['__unbound__']['User']['id']; + name: FieldOutputTypes['__unbound__']['User']['name']; + role: FieldOutputTypes['__unbound__']['User']['role']; + posts: unbound_AnyPost[]; + readonly [RelationKeys]?: 'posts'; + }; + export type unbound_AnyPost = unbound_Article | unbound_Tutorial; +} + +export declare const models: { + __unbound__: { + Article: Models.unbound_Article; + Post: Models.unbound_Post; + Tutorial: Models.unbound_Tutorial; + User: Models.unbound_User; + AnyPost: Models.unbound_AnyPost; + }; +}; + +export type TypeMaps = MongoTypeMaps; + +type ContractBase = Omit< + ContractType<{ + readonly namespaces: { + readonly __unbound__: { + readonly id: '__unbound__'; + readonly kind: 'mongo-database'; + readonly entries: { + readonly collection: { + readonly posts: { + readonly indexes: readonly [ + { + readonly keys: readonly [{ readonly direction: 1; readonly field: 'authorId' }]; + readonly kind: 'mongo-index'; + readonly name: 'authorId_1'; + }, + { + readonly keys: readonly [ + { readonly direction: -1; readonly field: 'createdAt' }, + { readonly direction: 1; readonly field: 'authorId' }, + ]; + readonly kind: 'mongo-index'; + readonly name: 'createdAt_-1_authorId_1'; + }, + { + readonly keys: readonly [{ readonly direction: 1; readonly field: 'summary' }]; + readonly kind: 'mongo-index'; + readonly name: 'summary_1'; + readonly partialFilterExpression: { readonly kind: 'article' }; + readonly unique: true; + }, + ]; + readonly kind: 'mongo-collection'; + readonly validator: { + readonly jsonSchema: { + readonly bsonType: 'object'; + readonly oneOf: readonly [ + { + readonly additionalProperties: false; + readonly properties: { + readonly _id: { readonly bsonType: 'objectId' }; + readonly authorId: { readonly bsonType: 'objectId' }; + readonly content: { readonly bsonType: 'string' }; + readonly createdAt: { readonly bsonType: 'date' }; + readonly kind: { readonly enum: readonly ['article'] }; + readonly summary: { readonly bsonType: 'string' }; + readonly title: { readonly bsonType: 'string' }; + }; + readonly required: readonly ['kind', 'summary']; + }, + { + readonly additionalProperties: false; + readonly properties: { + readonly _id: { readonly bsonType: 'objectId' }; + readonly authorId: { readonly bsonType: 'objectId' }; + readonly content: { readonly bsonType: 'string' }; + readonly createdAt: { readonly bsonType: 'date' }; + readonly difficulty: { readonly bsonType: 'string' }; + readonly duration: { readonly bsonType: 'int' }; + readonly kind: { readonly enum: readonly ['tutorial'] }; + readonly title: { readonly bsonType: 'string' }; + }; + readonly required: readonly ['difficulty', 'duration', 'kind']; + }, + ]; + readonly properties: { + readonly _id: { readonly bsonType: 'objectId' }; + readonly authorId: { readonly bsonType: 'objectId' }; + readonly content: { readonly bsonType: 'string' }; + readonly createdAt: { readonly bsonType: 'date' }; + readonly kind: { readonly bsonType: 'string' }; + readonly title: { readonly bsonType: 'string' }; + }; + readonly required: readonly [ + '_id', + 'authorId', + 'content', + 'createdAt', + 'kind', + 'title', + ]; + }; + readonly kind: 'mongo-validator'; + readonly validationAction: 'error'; + readonly validationLevel: 'strict'; + }; + }; + readonly users: { + readonly kind: 'mongo-collection'; + readonly validator: { + readonly jsonSchema: { + readonly additionalProperties: false; + readonly bsonType: 'object'; + readonly properties: { + readonly _id: { readonly bsonType: 'objectId' }; + readonly address: { + readonly oneOf: readonly [ + { readonly bsonType: 'null' }, + { + readonly additionalProperties: false; + readonly bsonType: 'object'; + readonly properties: { + readonly city: { readonly bsonType: 'string' }; + readonly country: { readonly bsonType: 'string' }; + readonly street: { readonly bsonType: 'string' }; + readonly zip: { readonly bsonType: readonly ['null', 'string'] }; + }; + readonly required: readonly ['city', 'country', 'street']; + }, + ]; + }; + readonly bio: { readonly bsonType: readonly ['null', 'string'] }; + readonly email: { readonly bsonType: 'string' }; + readonly name: { readonly bsonType: 'string' }; + readonly role: { + readonly bsonType: 'string'; + readonly enum: readonly ['admin', 'author', 'reader']; + }; + }; + readonly required: readonly ['_id', 'email', 'name', 'role']; + }; + readonly kind: 'mongo-validator'; + readonly validationAction: 'error'; + readonly validationLevel: 'strict'; + }; + }; + }; + readonly valueObject: { + readonly Address: { + readonly fields: { + readonly city: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + readonly country: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + readonly street: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + readonly zip: { + readonly nullable: true; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + }; + }; + }; + }; + }; + }; + readonly storageHash: StorageHash; + }>, + 'roots' | 'domain' +> & { + readonly target: 'mongo'; + readonly targetFamily: 'mongo'; + readonly roots: { + readonly posts: { readonly namespace: '__unbound__' & NamespaceId; readonly model: 'Post' }; + readonly users: { readonly namespace: '__unbound__' & NamespaceId; readonly model: 'User' }; + }; + readonly domain: { + readonly namespaces: { + readonly __unbound__: { + readonly models: { + readonly Article: { + readonly fields: { + readonly summary: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + }; + readonly relations: Record; + readonly storage: { + readonly collection: 'posts'; + readonly fields: { readonly summary: { readonly field: 'summary' } }; + }; + readonly base: { + readonly namespace: '__unbound__' & NamespaceId; + readonly model: 'Post'; + }; + }; + readonly Post: { + readonly fields: { + readonly authorId: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/objectId@1' }; + }; + readonly content: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + readonly createdAt: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/date@1' }; + }; + readonly id: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/objectId@1' }; + }; + readonly kind: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + readonly title: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + }; + readonly relations: { + readonly author: { + readonly to: { + readonly namespace: '__unbound__' & NamespaceId; + readonly model: 'User'; + }; + readonly cardinality: 'N:1'; + readonly nullable: false; + readonly on: { + readonly localFields: readonly ['authorId']; + readonly targetFields: readonly ['id']; + }; + }; + }; + readonly storage: { + readonly collection: 'posts'; + readonly fields: { + readonly authorId: { readonly field: 'authorId' }; + readonly content: { readonly field: 'content' }; + readonly createdAt: { readonly field: 'createdAt' }; + readonly id: { readonly field: '_id' }; + readonly kind: { readonly field: 'kind' }; + readonly title: { readonly field: 'title' }; + }; + }; + readonly discriminator: { readonly field: 'kind' }; + readonly variants: { + readonly article: { + readonly namespace: '__unbound__' & NamespaceId; + readonly model: 'Article'; + }; + readonly tutorial: { + readonly namespace: '__unbound__' & NamespaceId; + readonly model: 'Tutorial'; + }; + }; + }; + readonly Tutorial: { + readonly fields: { + readonly difficulty: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + readonly duration: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/int32@1' }; + }; + }; + readonly relations: Record; + readonly storage: { + readonly collection: 'posts'; + readonly fields: { + readonly difficulty: { readonly field: 'difficulty' }; + readonly duration: { readonly field: 'duration' }; + }; + }; + readonly base: { + readonly namespace: '__unbound__' & NamespaceId; + readonly model: 'Post'; + }; + }; + readonly User: { + readonly fields: { + readonly address: { + readonly nullable: true; + readonly type: { + readonly kind: 'valueObject'; + readonly plane: 'storage'; + readonly namespaceId: '__unbound__'; + readonly entityKind: 'valueObject'; + readonly entityName: 'Address'; + }; + }; + readonly bio: { + readonly nullable: true; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + readonly email: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + readonly id: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/objectId@1' }; + }; + readonly name: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + readonly role: { + readonly nullable: false; + readonly type: { readonly kind: 'scalar'; readonly codecId: 'mongo/string@1' }; + }; + }; + readonly relations: { + readonly posts: { + readonly to: { + readonly namespace: '__unbound__' & NamespaceId; + readonly model: 'Post'; + }; + readonly cardinality: '1:N'; + readonly on: { + readonly localFields: readonly ['id']; + readonly targetFields: readonly ['authorId']; + }; + }; + }; + readonly storage: { + readonly collection: 'users'; + readonly fields: { + readonly address: { readonly field: 'address' }; + readonly bio: { readonly field: 'bio' }; + readonly email: { readonly field: 'email' }; + readonly id: { readonly field: '_id' }; + readonly name: { readonly field: 'name' }; + readonly role: { readonly field: 'role' }; + }; + }; + }; + }; + readonly enum: { + readonly UserRole: { + readonly codecId: 'mongo/string@1'; + readonly members: readonly [ + { readonly name: 'Admin'; readonly value: 'admin' }, + { readonly name: 'Author'; readonly value: 'author' }, + { readonly name: 'Reader'; readonly value: 'reader' }, + ]; + }; + }; + readonly enumMemberTypes?: { + readonly UserRole: readonly [ + { readonly name: 'Admin'; readonly value: 'admin' }, + { readonly name: 'Author'; readonly value: 'author' }, + { readonly name: 'Reader'; readonly value: 'reader' }, + ]; + }; + }; + }; + }; + readonly capabilities: {}; + readonly extensions: {}; + readonly meta: {}; + readonly profileHash: ProfileHash; +}; + +export type Contract = MongoContractWithTypeMaps; diff --git a/examples/mongo-demo/migrations/snapshots/61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c/contract.json b/examples/mongo-demo/migrations/snapshots/61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c/contract.json new file mode 100644 index 000000000000..a63481ae2799 --- /dev/null +++ b/examples/mongo-demo/migrations/snapshots/61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c/contract.json @@ -0,0 +1 @@ +{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"enum":{"UserRole":{"codecId":"mongo/string@1","members":[{"name":"Admin","value":"admin"},{"name":"Author","value":"author"},{"name":"Reader","value":"reader"}]}},"models":{"Article":{"base":{"model":"Post","namespace":"__unbound__"},"fields":{"summary":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"posts","fields":{"summary":{"field":"summary"}}}},"Post":{"discriminator":{"field":"kind"},"fields":{"authorId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"content":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"createdAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"kind":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"title":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"author":{"cardinality":"N:1","nullable":false,"on":{"localFields":["authorId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"posts","fields":{"authorId":{"field":"authorId"},"content":{"field":"content"},"createdAt":{"field":"createdAt"},"id":{"field":"_id"},"kind":{"field":"kind"},"title":{"field":"title"}}},"variants":{"article":{"model":"Article","namespace":"__unbound__"},"tutorial":{"model":"Tutorial","namespace":"__unbound__"}}},"Tutorial":{"base":{"model":"Post","namespace":"__unbound__"},"fields":{"difficulty":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"duration":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"posts","fields":{"difficulty":{"field":"difficulty"},"duration":{"field":"duration"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"bio":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"role":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"},"valueSet":{"entityKind":"enum","entityName":"UserRole","namespaceId":"__unbound__","plane":"domain"}}},"relations":{"posts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["authorId"]},"to":{"model":"Post","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"bio":{"field":"bio"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"},"role":{"field":"role"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"posts":{"model":"Post","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"posts":{"indexes":[{"keys":[{"direction":1,"field":"authorId"}],"kind":"mongo-index","name":"authorId_1"},{"keys":[{"direction":-1,"field":"createdAt"},{"direction":1,"field":"authorId"}],"kind":"mongo-index","name":"createdAt_-1_authorId_1"},{"keys":[{"direction":1,"field":"summary"}],"kind":"mongo-index","name":"summary_1","partialFilterExpression":{"kind":"article"},"unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"kind":{"enum":["article"]},"summary":{"bsonType":"string"},"title":{"bsonType":"string"}},"required":["kind","summary"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"difficulty":{"bsonType":"string"},"duration":{"bsonType":"int"},"kind":{"enum":["tutorial"]},"title":{"bsonType":"string"}},"required":["difficulty","duration","kind"]}],"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"kind":{"bsonType":"string"},"title":{"bsonType":"string"}},"required":["_id","authorId","content","createdAt","kind","title"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"street":{"bsonType":"string"},"zip":{"bsonType":["null","string"]}},"required":["city","country","street"]}]},"bio":{"bsonType":["null","string"]},"email":{"bsonType":"string"},"name":{"bsonType":"string"},"role":{"bsonType":"string","enum":["admin","author","reader"]}},"required":["_id","email","name","role"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"street":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"zip":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}}},"valueSet":{"UserRole":{"kind":"valueSet","values":["admin","author","reader"]}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/mongo-demo/migrations/snapshots/95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9/contract.d.ts b/examples/mongo-demo/migrations/snapshots/b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4/contract.d.ts similarity index 99% rename from examples/mongo-demo/migrations/snapshots/95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9/contract.d.ts rename to examples/mongo-demo/migrations/snapshots/b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4/contract.d.ts index c61fa21a4db6..53ab2b5b5805 100644 --- a/examples/mongo-demo/migrations/snapshots/95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9/contract.d.ts +++ b/examples/mongo-demo/migrations/snapshots/b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4/contract.d.ts @@ -23,7 +23,7 @@ import type { } from '@prisma/orm-mongo/contract/types'; export type StorageHash = - StorageHashBase<'95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9'>; + StorageHashBase<'b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4'>; export type ExecutionHash = ExecutionHashBase; export type ProfileHash = ProfileHashBase<'251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3'>; @@ -148,6 +148,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'summary' }]; readonly kind: 'mongo-index'; + readonly name: 'summary_1'; readonly partialFilterExpression: { readonly kind: 'article' }; readonly unique: true; }, diff --git a/examples/mongo-demo/migrations/snapshots/95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9/contract.json b/examples/mongo-demo/migrations/snapshots/b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4/contract.json similarity index 58% rename from examples/mongo-demo/migrations/snapshots/95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9/contract.json rename to examples/mongo-demo/migrations/snapshots/b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4/contract.json index feed3a57d193..53996930235a 100644 --- a/examples/mongo-demo/migrations/snapshots/95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9/contract.json +++ b/examples/mongo-demo/migrations/snapshots/b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4/contract.json @@ -1 +1 @@ -{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"enum":{"UserRole":{"codecId":"mongo/string@1","members":[{"name":"Admin","value":"admin"},{"name":"Author","value":"author"},{"name":"Reader","value":"reader"}]}},"models":{"Article":{"base":{"model":"Post","namespace":"__unbound__"},"fields":{"summary":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"posts","fields":{"summary":{"field":"summary"}}}},"Post":{"discriminator":{"field":"kind"},"fields":{"authorId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"content":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"createdAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"kind":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"title":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"author":{"cardinality":"N:1","nullable":false,"on":{"localFields":["authorId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"posts","fields":{"authorId":{"field":"authorId"},"content":{"field":"content"},"createdAt":{"field":"createdAt"},"id":{"field":"_id"},"kind":{"field":"kind"},"title":{"field":"title"}}},"variants":{"article":{"model":"Article","namespace":"__unbound__"},"tutorial":{"model":"Tutorial","namespace":"__unbound__"}}},"Tutorial":{"base":{"model":"Post","namespace":"__unbound__"},"fields":{"difficulty":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"duration":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"posts","fields":{"difficulty":{"field":"difficulty"},"duration":{"field":"duration"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"bio":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"role":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"},"valueSet":{"entityKind":"enum","entityName":"UserRole","namespaceId":"__unbound__","plane":"domain"}}},"relations":{"posts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["authorId"]},"to":{"model":"Post","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"bio":{"field":"bio"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"},"role":{"field":"role"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"posts":{"model":"Post","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"posts":{"indexes":[{"keys":[{"direction":1,"field":"summary"}],"kind":"mongo-index","partialFilterExpression":{"kind":"article"},"unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"kind":{"enum":["article"]},"summary":{"bsonType":"string"},"title":{"bsonType":"string"}},"required":["kind","summary"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"difficulty":{"bsonType":"string"},"duration":{"bsonType":"int"},"kind":{"enum":["tutorial"]},"title":{"bsonType":"string"}},"required":["difficulty","duration","kind"]}],"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"kind":{"bsonType":"string"},"title":{"bsonType":"string"}},"required":["_id","authorId","content","createdAt","kind","title"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"street":{"bsonType":"string"},"zip":{"bsonType":["null","string"]}},"required":["city","country","street"]}]},"bio":{"bsonType":["null","string"]},"email":{"bsonType":"string"},"name":{"bsonType":"string"},"role":{"bsonType":"string","enum":["admin","author","reader"]}},"required":["_id","email","name","role"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"street":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"zip":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}}},"valueSet":{"UserRole":{"kind":"valueSet","values":["admin","author","reader"]}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"95332b0bd6fbbfab4462d882c037a574c92e51897249c333ba681b12c4d603c9"},"target":"mongo","targetFamily":"mongo"} +{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"enum":{"UserRole":{"codecId":"mongo/string@1","members":[{"name":"Admin","value":"admin"},{"name":"Author","value":"author"},{"name":"Reader","value":"reader"}]}},"models":{"Article":{"base":{"model":"Post","namespace":"__unbound__"},"fields":{"summary":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"posts","fields":{"summary":{"field":"summary"}}}},"Post":{"discriminator":{"field":"kind"},"fields":{"authorId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"content":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"createdAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"kind":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"title":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"author":{"cardinality":"N:1","nullable":false,"on":{"localFields":["authorId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"posts","fields":{"authorId":{"field":"authorId"},"content":{"field":"content"},"createdAt":{"field":"createdAt"},"id":{"field":"_id"},"kind":{"field":"kind"},"title":{"field":"title"}}},"variants":{"article":{"model":"Article","namespace":"__unbound__"},"tutorial":{"model":"Tutorial","namespace":"__unbound__"}}},"Tutorial":{"base":{"model":"Post","namespace":"__unbound__"},"fields":{"difficulty":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"duration":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"posts","fields":{"difficulty":{"field":"difficulty"},"duration":{"field":"duration"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"bio":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"role":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"},"valueSet":{"entityKind":"enum","entityName":"UserRole","namespaceId":"__unbound__","plane":"domain"}}},"relations":{"posts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["authorId"]},"to":{"model":"Post","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"bio":{"field":"bio"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"},"role":{"field":"role"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"posts":{"model":"Post","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"posts":{"indexes":[{"keys":[{"direction":1,"field":"summary"}],"kind":"mongo-index","name":"summary_1","partialFilterExpression":{"kind":"article"},"unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"kind":{"enum":["article"]},"summary":{"bsonType":"string"},"title":{"bsonType":"string"}},"required":["kind","summary"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"difficulty":{"bsonType":"string"},"duration":{"bsonType":"int"},"kind":{"enum":["tutorial"]},"title":{"bsonType":"string"}},"required":["difficulty","duration","kind"]}],"properties":{"_id":{"bsonType":"objectId"},"authorId":{"bsonType":"objectId"},"content":{"bsonType":"string"},"createdAt":{"bsonType":"date"},"kind":{"bsonType":"string"},"title":{"bsonType":"string"}},"required":["_id","authorId","content","createdAt","kind","title"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"street":{"bsonType":"string"},"zip":{"bsonType":["null","string"]}},"required":["city","country","street"]}]},"bio":{"bsonType":["null","string"]},"email":{"bsonType":"string"},"name":{"bsonType":"string"},"role":{"bsonType":"string","enum":["admin","author","reader"]}},"required":["_id","email","name","role"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"street":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"zip":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}}},"valueSet":{"UserRole":{"kind":"valueSet","values":["admin","author","reader"]}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"b6f6bd5351ad4383f8a46c585bf7f7f65483aaf898f124a130dadc46a9b373a4"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/mongo-demo/src/contract.d.ts b/examples/mongo-demo/src/contract.d.ts index 80c6ac7a1cf7..4a7ff7a4b1d5 100644 --- a/examples/mongo-demo/src/contract.d.ts +++ b/examples/mongo-demo/src/contract.d.ts @@ -23,7 +23,7 @@ import type { } from '@prisma/orm-mongo/contract/types'; export type StorageHash = - StorageHashBase<'406b672b68a6b01f04c0d6f910f5fefa4ac16d48b26e6c91b43856cd42c8cc5d'>; + StorageHashBase<'61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c'>; export type ExecutionHash = ExecutionHashBase; export type ProfileHash = ProfileHashBase<'251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3'>; @@ -148,6 +148,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'authorId' }]; readonly kind: 'mongo-index'; + readonly name: 'authorId_1'; }, { readonly keys: readonly [ @@ -155,10 +156,12 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'authorId' }, ]; readonly kind: 'mongo-index'; + readonly name: 'createdAt_-1_authorId_1'; }, { readonly keys: readonly [{ readonly direction: 1; readonly field: 'summary' }]; readonly kind: 'mongo-index'; + readonly name: 'summary_1'; readonly partialFilterExpression: { readonly kind: 'article' }; readonly unique: true; }, diff --git a/examples/mongo-demo/src/contract.json b/examples/mongo-demo/src/contract.json index 536570edf7cb..737aecc0653b 100644 --- a/examples/mongo-demo/src/contract.json +++ b/examples/mongo-demo/src/contract.json @@ -307,7 +307,8 @@ "field": "authorId" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "authorId_1" }, { "keys": [ @@ -320,7 +321,8 @@ "field": "authorId" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "createdAt_-1_authorId_1" }, { "keys": [ @@ -330,6 +332,7 @@ } ], "kind": "mongo-index", + "name": "summary_1", "partialFilterExpression": { "kind": "article" }, @@ -570,7 +573,7 @@ "kind": "mongo-database" } }, - "storageHash": "406b672b68a6b01f04c0d6f910f5fefa4ac16d48b26e6c91b43856cd42c8cc5d" + "storageHash": "61c3f027c298b11d22e875ed76ab6460d2b4396afa94bdf58d85e26aded3416c" }, "capabilities": {}, "extensions": {}, diff --git a/examples/retail-store/migrations/app/20260513T0505_initial/migration.json b/examples/retail-store/migrations/app/20260513T0505_initial/migration.json index 40d95ab97a4e..52a90fb523bc 100644 --- a/examples/retail-store/migrations/app/20260513T0505_initial/migration.json +++ b/examples/retail-store/migrations/app/20260513T0505_initial/migration.json @@ -1,7 +1,7 @@ { "from": null, - "to": "917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f", + "to": "fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad", "providedInvariants": [], "createdAt": "2026-05-13T05:05:47.654Z", - "migrationHash": "886de0ddc5bc235badc57ae7ae88bf4b360c26823e57a2667ce4f9d5b151f12a" + "migrationHash": "ee31caadf1e29ff1093e31d02deeaab6b7de9e2b316db537abbe5bdee1d1c85f" } diff --git a/examples/retail-store/migrations/app/20260513T0505_initial/migration.ts b/examples/retail-store/migrations/app/20260513T0505_initial/migration.ts index f142f7d8f49a..bae64e48e880 100755 --- a/examples/retail-store/migrations/app/20260513T0505_initial/migration.ts +++ b/examples/retail-store/migrations/app/20260513T0505_initial/migration.ts @@ -5,8 +5,8 @@ import { Migration, MigrationCLI, } from '@prisma/orm-mongo/target/migration'; -import type { Contract as End } from '../../snapshots/917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f/contract'; -import endContract from '../../snapshots/917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f/contract.json' with { +import type { Contract as End } from '../../snapshots/fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad/contract'; +import endContract from '../../snapshots/fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad/contract.json' with { type: 'json', }; diff --git a/examples/retail-store/migrations/app/20260513T0505_initial/ops.json b/examples/retail-store/migrations/app/20260513T0505_initial/ops.json index f902a9a31160..4bc28b294f83 100644 --- a/examples/retail-store/migrations/app/20260513T0505_initial/ops.json +++ b/examples/retail-store/migrations/app/20260513T0505_initial/ops.json @@ -669,48 +669,27 @@ "postcheck": [] }, { - "id": "index.carts.create(userId:1)", - "label": "Create index on carts (userId:1)", + "id": "index.carts.create(userId_1)", + "label": "Create index userId_1 on carts (userId:1)", "operationClass": "additive", "precheck": [ { - "description": "index does not already exist on carts", + "description": "no index named userId_1 exists on carts", "source": { "kind": "listIndexes", "collection": "carts" }, "filter": { "kind": "field", - "field": "key", + "field": "name", "op": "$eq", - "value": { - "userId": 1 - } + "value": "userId_1" }, "expect": "notExists", - "object": "an index on { userId: 1 } in \"carts\"" - } - ], - "execute": [ - { - "description": "create index on carts", - "command": { - "kind": "createIndex", - "collection": "carts", - "keys": [ - { - "direction": 1, - "field": "userId" - } - ], - "unique": true, - "name": "userId_1" - } - } - ], - "postcheck": [ + "object": "an index named \"userId_1\" in \"carts\"" + }, { - "description": "index exists on carts", + "description": "no index with the same keys and options exists on carts", "source": { "kind": "listIndexes", "collection": "carts" @@ -763,57 +742,119 @@ } ] }, - "expect": "exists" - } - ] - }, - { - "id": "index.events.create(userId:1,timestamp:-1)", - "label": "Create index on events (userId:1, timestamp:-1)", - "operationClass": "additive", - "precheck": [ - { - "description": "index does not already exist on events", - "source": { - "kind": "listIndexes", - "collection": "events" - }, - "filter": { - "kind": "field", - "field": "key", - "op": "$eq", - "value": { - "userId": 1, - "timestamp": -1 - } - }, "expect": "notExists", - "object": "an index on { userId: 1, timestamp: -1 } in \"events\"" + "object": "an index on { userId: 1 } in \"carts\"" } ], "execute": [ { - "description": "create index on events", + "description": "create index userId_1 on carts", "command": { "kind": "createIndex", - "collection": "events", + "collection": "carts", "keys": [ { "direction": 1, "field": "userId" - }, - { - "direction": -1, - "field": "timestamp" } ], - "name": "userId_1_timestamp_-1" + "unique": true, + "name": "userId_1" } } ], "postcheck": [ { - "description": "index exists on events", + "description": "index userId_1 exists on carts", + "source": { + "kind": "listIndexes", + "collection": "carts" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "userId_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "userId": 1 + } + }, + { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, + "expect": "exists" + } + ] + }, + { + "id": "index.events.create(userId_1_timestamp_-1)", + "label": "Create index userId_1_timestamp_-1 on events (userId:1, timestamp:-1)", + "operationClass": "additive", + "precheck": [ + { + "description": "no index named userId_1_timestamp_-1 exists on events", + "source": { + "kind": "listIndexes", + "collection": "events" + }, + "filter": { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "userId_1_timestamp_-1" + }, + "expect": "notExists", + "object": "an index named \"userId_1_timestamp_-1\" in \"events\"" + }, + { + "description": "no index with the same keys and options exists on events", "source": { "kind": "listIndexes", "collection": "events" @@ -870,53 +911,126 @@ } ] }, - "expect": "exists" - } - ] - }, - { - "id": "index.events.create(timestamp:1)", - "label": "Create index on events (timestamp:1)", - "operationClass": "additive", - "precheck": [ - { - "description": "index does not already exist on events", - "source": { - "kind": "listIndexes", - "collection": "events" - }, - "filter": { - "kind": "field", - "field": "key", - "op": "$eq", - "value": { - "timestamp": 1 - } - }, "expect": "notExists", - "object": "an index on { timestamp: 1 } in \"events\"" + "object": "an index on { userId: 1, timestamp: -1 } in \"events\"" } ], "execute": [ { - "description": "create index on events", + "description": "create index userId_1_timestamp_-1 on events", "command": { "kind": "createIndex", "collection": "events", "keys": [ { "direction": 1, + "field": "userId" + }, + { + "direction": -1, "field": "timestamp" } ], - "expireAfterSeconds": 7776000, - "name": "timestamp_1" + "name": "userId_1_timestamp_-1" } } ], "postcheck": [ { - "description": "index exists on events", + "description": "index userId_1_timestamp_-1 exists on events", + "source": { + "kind": "listIndexes", + "collection": "events" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "userId_1_timestamp_-1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "userId": 1, + "timestamp": -1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, + "expect": "exists" + } + ] + }, + { + "id": "index.events.create(timestamp_1)", + "label": "Create index timestamp_1 on events (timestamp:1)", + "operationClass": "additive", + "precheck": [ + { + "description": "no index named timestamp_1 exists on events", + "source": { + "kind": "listIndexes", + "collection": "events" + }, + "filter": { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "timestamp_1" + }, + "expect": "notExists", + "object": "an index named \"timestamp_1\" in \"events\"" + }, + { + "description": "no index with the same keys and options exists on events", "source": { "kind": "listIndexes", "collection": "events" @@ -973,52 +1087,123 @@ } ] }, + "expect": "notExists", + "object": "an index on { timestamp: 1 } in \"events\"" + } + ], + "execute": [ + { + "description": "create index timestamp_1 on events", + "command": { + "kind": "createIndex", + "collection": "events", + "keys": [ + { + "direction": 1, + "field": "timestamp" + } + ], + "expireAfterSeconds": 7776000, + "name": "timestamp_1" + } + } + ], + "postcheck": [ + { + "description": "index timestamp_1 exists on events", + "source": { + "kind": "listIndexes", + "collection": "events" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "timestamp_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "timestamp": 1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "field", + "field": "expireAfterSeconds", + "op": "$eq", + "value": 7776000 + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, "expect": "exists" } ] }, { - "id": "index.invoices.create(orderId:1)", - "label": "Create index on invoices (orderId:1)", + "id": "index.invoices.create(orderId_1)", + "label": "Create index orderId_1 on invoices (orderId:1)", "operationClass": "additive", "precheck": [ { - "description": "index does not already exist on invoices", + "description": "no index named orderId_1 exists on invoices", "source": { "kind": "listIndexes", "collection": "invoices" }, "filter": { "kind": "field", - "field": "key", + "field": "name", "op": "$eq", - "value": { - "orderId": 1 - } + "value": "orderId_1" }, "expect": "notExists", - "object": "an index on { orderId: 1 } in \"invoices\"" - } - ], - "execute": [ + "object": "an index named \"orderId_1\" in \"invoices\"" + }, { - "description": "create index on invoices", - "command": { - "kind": "createIndex", - "collection": "invoices", - "keys": [ - { - "direction": 1, - "field": "orderId" - } - ], - "name": "orderId_1" - } - } - ], - "postcheck": [ - { - "description": "index exists on invoices", + "description": "no index with the same keys and options exists on invoices", "source": { "kind": "listIndexes", "collection": "invoices" @@ -1074,53 +1259,121 @@ } ] }, - "expect": "exists" - } - ] - }, - { - "id": "index.invoices.create(issuedAt:-1)", - "label": "Create index on invoices (issuedAt:-1)", - "operationClass": "additive", - "precheck": [ - { - "description": "index does not already exist on invoices", - "source": { - "kind": "listIndexes", - "collection": "invoices" - }, - "filter": { - "kind": "field", - "field": "key", - "op": "$eq", - "value": { - "issuedAt": -1 - } - }, "expect": "notExists", - "object": "an index on { issuedAt: -1 } in \"invoices\"" + "object": "an index on { orderId: 1 } in \"invoices\"" } ], "execute": [ { - "description": "create index on invoices", + "description": "create index orderId_1 on invoices", "command": { "kind": "createIndex", "collection": "invoices", "keys": [ { - "direction": -1, - "field": "issuedAt" + "direction": 1, + "field": "orderId" } ], - "sparse": true, - "name": "issuedAt_-1" + "name": "orderId_1" } } ], "postcheck": [ { - "description": "index exists on invoices", + "description": "index orderId_1 exists on invoices", + "source": { + "kind": "listIndexes", + "collection": "invoices" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "orderId_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "orderId": 1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, + "expect": "exists" + } + ] + }, + { + "id": "index.invoices.create(issuedAt_-1)", + "label": "Create index issuedAt_-1 on invoices (issuedAt:-1)", + "operationClass": "additive", + "precheck": [ + { + "description": "no index named issuedAt_-1 exists on invoices", + "source": { + "kind": "listIndexes", + "collection": "invoices" + }, + "filter": { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "issuedAt_-1" + }, + "expect": "notExists", + "object": "an index named \"issuedAt_-1\" in \"invoices\"" + }, + { + "description": "no index with the same keys and options exists on invoices", "source": { "kind": "listIndexes", "collection": "invoices" @@ -1173,61 +1426,119 @@ } ] }, + "expect": "notExists", + "object": "an index on { issuedAt: -1 } in \"invoices\"" + } + ], + "execute": [ + { + "description": "create index issuedAt_-1 on invoices", + "command": { + "kind": "createIndex", + "collection": "invoices", + "keys": [ + { + "direction": -1, + "field": "issuedAt" + } + ], + "sparse": true, + "name": "issuedAt_-1" + } + } + ], + "postcheck": [ + { + "description": "index issuedAt_-1 exists on invoices", + "source": { + "kind": "listIndexes", + "collection": "invoices" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "issuedAt_-1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "issuedAt": -1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, "expect": "exists" } ] }, { - "id": "index.locations.create(city:1,country:1)", - "label": "Create index on locations (city:1, country:1)", + "id": "index.locations.create(city_1_country_1)", + "label": "Create index city_1_country_1 on locations (city:1, country:1)", "operationClass": "additive", "precheck": [ { - "description": "index does not already exist on locations", + "description": "no index named city_1_country_1 exists on locations", "source": { "kind": "listIndexes", "collection": "locations" }, "filter": { "kind": "field", - "field": "key", + "field": "name", "op": "$eq", - "value": { - "city": 1, - "country": 1 - } + "value": "city_1_country_1" }, "expect": "notExists", - "object": "an index on { city: 1, country: 1 } in \"locations\"" - } - ], - "execute": [ - { - "description": "create index on locations", - "command": { - "kind": "createIndex", - "collection": "locations", - "keys": [ - { - "direction": 1, - "field": "city" - }, - { - "direction": 1, - "field": "country" - } - ], - "name": "city_1_country_1", - "collation": { - "locale": "en", - "strength": 2 - } - } - } - ], - "postcheck": [ + "object": "an index named \"city_1_country_1\" in \"locations\"" + }, { - "description": "index exists on locations", + "description": "no index with the same keys and options exists on locations", "source": { "kind": "listIndexes", "collection": "locations" @@ -1291,28 +1602,191 @@ } ] }, + "expect": "notExists", + "object": "an index on { city: 1, country: 1 } in \"locations\"" + } + ], + "execute": [ + { + "description": "create index city_1_country_1 on locations", + "command": { + "kind": "createIndex", + "collection": "locations", + "keys": [ + { + "direction": 1, + "field": "city" + }, + { + "direction": 1, + "field": "country" + } + ], + "name": "city_1_country_1", + "collation": { + "locale": "en", + "strength": 2 + } + } + } + ], + "postcheck": [ + { + "description": "index city_1_country_1 exists on locations", + "source": { + "kind": "listIndexes", + "collection": "locations" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "city_1_country_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "city": 1, + "country": 1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "field", + "field": "collation.locale", + "op": "$eq", + "value": "en" + }, + { + "kind": "field", + "field": "collation.strength", + "op": "$eq", + "value": 2 + } + ] + } + ] + }, "expect": "exists" } ] }, { - "id": "index.orders.create(userId:1)", - "label": "Create index on orders (userId:1)", + "id": "index.orders.create(userId_1)", + "label": "Create index userId_1 on orders (userId:1)", "operationClass": "additive", "precheck": [ { - "description": "index does not already exist on orders", + "description": "no index named userId_1 exists on orders", "source": { "kind": "listIndexes", "collection": "orders" }, "filter": { "kind": "field", - "field": "key", + "field": "name", "op": "$eq", - "value": { - "userId": 1 - } + "value": "userId_1" + }, + "expect": "notExists", + "object": "an index named \"userId_1\" in \"orders\"" + }, + { + "description": "no index with the same keys and options exists on orders", + "source": { + "kind": "listIndexes", + "collection": "orders" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "userId": 1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] }, "expect": "notExists", "object": "an index on { userId: 1 } in \"orders\"" @@ -1320,7 +1794,7 @@ ], "execute": [ { - "description": "create index on orders", + "description": "create index userId_1 on orders", "command": { "kind": "createIndex", "collection": "orders", @@ -1336,11 +1810,103 @@ ], "postcheck": [ { - "description": "index exists on orders", + "description": "index userId_1 exists on orders", "source": { "kind": "listIndexes", "collection": "orders" }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "userId_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "userId": 1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, + "expect": "exists" + } + ] + }, + { + "id": "index.products.create(name_text_description_text)", + "label": "Create index name_text_description_text on products (name:text, description:text)", + "operationClass": "additive", + "precheck": [ + { + "description": "no index named name_text_description_text exists on products", + "source": { + "kind": "listIndexes", + "collection": "products" + }, + "filter": { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "name_text_description_text" + }, + "expect": "notExists", + "object": "an index named \"name_text_description_text\" in \"products\"" + }, + { + "description": "no index with the same keys and options exists on products", + "source": { + "kind": "listIndexes", + "collection": "products" + }, "filter": { "kind": "and", "exprs": [ @@ -1349,7 +1915,8 @@ "field": "key", "op": "$eq", "value": { - "userId": 1 + "_fts": "text", + "_ftsx": 1 } }, { @@ -1389,37 +1956,37 @@ "kind": "exists", "field": "collation", "exists": false + }, + { + "kind": "field", + "field": "weights", + "op": "$eq", + "value": { + "description": 1, + "name": 10 + } + }, + { + "kind": "field", + "field": "default_language", + "op": "$eq", + "value": "english" + }, + { + "kind": "field", + "field": "language_override", + "op": "$eq", + "value": "language" } ] }, - "expect": "exists" - } - ] - }, - { - "id": "index.products.create(name:text,description:text)", - "label": "Create index on products (name:text, description:text)", - "operationClass": "additive", - "precheck": [ - { - "description": "index does not already exist on products", - "source": { - "kind": "listIndexes", - "collection": "products" - }, - "filter": { - "kind": "field", - "field": "key._fts", - "op": "$eq", - "value": "text" - }, "expect": "notExists", "object": "a text index in \"products\"" } ], "execute": [ { - "description": "create index on products", + "description": "create index name_text_description_text on products", "command": { "kind": "createIndex", "collection": "products", @@ -1443,7 +2010,121 @@ ], "postcheck": [ { - "description": "index exists on products", + "description": "index name_text_description_text exists on products", + "source": { + "kind": "listIndexes", + "collection": "products" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "name_text_description_text" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "_fts": "text", + "_ftsx": 1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + }, + { + "kind": "field", + "field": "weights", + "op": "$eq", + "value": { + "description": 1, + "name": 10 + } + }, + { + "kind": "field", + "field": "default_language", + "op": "$eq", + "value": "english" + }, + { + "kind": "field", + "field": "language_override", + "op": "$eq", + "value": "language" + } + ] + } + ] + }, + "expect": "exists" + } + ] + }, + { + "id": "index.products.create(brand_1_subCategory_1)", + "label": "Create index brand_1_subCategory_1 on products (brand:1, subCategory:1)", + "operationClass": "additive", + "precheck": [ + { + "description": "no index named brand_1_subCategory_1 exists on products", + "source": { + "kind": "listIndexes", + "collection": "products" + }, + "filter": { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "brand_1_subCategory_1" + }, + "expect": "notExists", + "object": "an index named \"brand_1_subCategory_1\" in \"products\"" + }, + { + "description": "no index with the same keys and options exists on products", "source": { "kind": "listIndexes", "collection": "products" @@ -1456,8 +2137,8 @@ "field": "key", "op": "$eq", "value": { - "_fts": "text", - "_ftsx": 1 + "brand": 1, + "subCategory": 1 } }, { @@ -1497,61 +2178,16 @@ "kind": "exists", "field": "collation", "exists": false - }, - { - "kind": "field", - "field": "weights", - "op": "$eq", - "value": { - "description": 1, - "name": 10 - } - }, - { - "kind": "field", - "field": "default_language", - "op": "$eq", - "value": "english" - }, - { - "kind": "field", - "field": "language_override", - "op": "$eq", - "value": "language" } ] }, - "expect": "exists" - } - ] - }, - { - "id": "index.products.create(brand:1,subCategory:1)", - "label": "Create index on products (brand:1, subCategory:1)", - "operationClass": "additive", - "precheck": [ - { - "description": "index does not already exist on products", - "source": { - "kind": "listIndexes", - "collection": "products" - }, - "filter": { - "kind": "field", - "field": "key", - "op": "$eq", - "value": { - "brand": 1, - "subCategory": 1 - } - }, "expect": "notExists", "object": "an index on { brand: 1, subCategory: 1 } in \"products\"" } ], "execute": [ { - "description": "create index on products", + "description": "create index brand_1_subCategory_1 on products", "command": { "kind": "createIndex", "collection": "products", @@ -1571,7 +2207,100 @@ ], "postcheck": [ { - "description": "index exists on products", + "description": "index brand_1_subCategory_1 exists on products", + "source": { + "kind": "listIndexes", + "collection": "products" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "brand_1_subCategory_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "brand": 1, + "subCategory": 1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, + "expect": "exists" + } + ] + }, + { + "id": "index.products.create(code_hashed)", + "label": "Create index code_hashed on products (code:hashed)", + "operationClass": "additive", + "precheck": [ + { + "description": "no index named code_hashed exists on products", + "source": { + "kind": "listIndexes", + "collection": "products" + }, + "filter": { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "code_hashed" + }, + "expect": "notExists", + "object": "an index named \"code_hashed\" in \"products\"" + }, + { + "description": "no index with the same keys and options exists on products", "source": { "kind": "listIndexes", "collection": "products" @@ -1584,8 +2313,7 @@ "field": "key", "op": "$eq", "value": { - "brand": 1, - "subCategory": 1 + "code": "hashed" } }, { @@ -1628,36 +2356,13 @@ } ] }, - "expect": "exists" - } - ] - }, - { - "id": "index.products.create(code:hashed)", - "label": "Create index on products (code:hashed)", - "operationClass": "additive", - "precheck": [ - { - "description": "index does not already exist on products", - "source": { - "kind": "listIndexes", - "collection": "products" - }, - "filter": { - "kind": "field", - "field": "key", - "op": "$eq", - "value": { - "code": "hashed" - } - }, "expect": "notExists", "object": "an index on { code: \"hashed\" } in \"products\"" } ], "execute": [ { - "description": "create index on products", + "description": "create index code_hashed on products", "command": { "kind": "createIndex", "collection": "products", @@ -1673,7 +2378,7 @@ ], "postcheck": [ { - "description": "index exists on products", + "description": "index code_hashed exists on products", "source": { "kind": "listIndexes", "collection": "products" @@ -1683,49 +2388,60 @@ "exprs": [ { "kind": "field", - "field": "key", + "field": "name", "op": "$eq", - "value": { - "code": "hashed" - } - }, - { - "kind": "not", - "expr": { - "kind": "field", - "field": "unique", - "op": "$eq", - "value": true - } - }, - { - "kind": "not", - "expr": { - "kind": "field", - "field": "sparse", - "op": "$eq", - "value": true - } + "value": "code_hashed" }, { - "kind": "exists", - "field": "expireAfterSeconds", - "exists": false - }, - { - "kind": "exists", - "field": "partialFilterExpression", - "exists": false - }, - { - "kind": "exists", - "field": "wildcardProjection", - "exists": false - }, - { - "kind": "exists", - "field": "collation", - "exists": false + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "code": "hashed" + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] } ] }, @@ -1734,48 +2450,27 @@ ] }, { - "id": "index.users.create(email:1)", - "label": "Create index on users (email:1)", + "id": "index.users.create(email_1)", + "label": "Create index email_1 on users (email:1)", "operationClass": "additive", "precheck": [ { - "description": "index does not already exist on users", + "description": "no index named email_1 exists on users", "source": { "kind": "listIndexes", "collection": "users" }, "filter": { "kind": "field", - "field": "key", + "field": "name", "op": "$eq", - "value": { - "email": 1 - } + "value": "email_1" }, "expect": "notExists", - "object": "an index on { email: 1 } in \"users\"" - } - ], - "execute": [ - { - "description": "create index on users", - "command": { - "kind": "createIndex", - "collection": "users", - "keys": [ - { - "direction": 1, - "field": "email" - } - ], - "unique": true, - "name": "email_1" - } - } - ], - "postcheck": [ + "object": "an index named \"email_1\" in \"users\"" + }, { - "description": "index exists on users", + "description": "no index with the same keys and options exists on users", "source": { "kind": "listIndexes", "collection": "users" @@ -1828,6 +2523,93 @@ } ] }, + "expect": "notExists", + "object": "an index on { email: 1 } in \"users\"" + } + ], + "execute": [ + { + "description": "create index email_1 on users", + "command": { + "kind": "createIndex", + "collection": "users", + "keys": [ + { + "direction": 1, + "field": "email" + } + ], + "unique": true, + "name": "email_1" + } + } + ], + "postcheck": [ + { + "description": "index email_1 exists on users", + "source": { + "kind": "listIndexes", + "collection": "users" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "email_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "email": 1 + } + }, + { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, "expect": "exists" } ] diff --git a/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/migration.json b/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/migration.json index dfa8eca04a51..ee2edad0e961 100644 --- a/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/migration.json +++ b/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/migration.json @@ -1,7 +1,7 @@ { - "from": "917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f", - "to": "32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78", + "from": "fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad", + "to": "315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4", "providedInvariants": [], "createdAt": "2026-05-13T05:07:50.592Z", - "migrationHash": "7b8a1159dfd91a4ca23ea45e5fb96f6b6ddfe3fc565f00811af1251963292486" + "migrationHash": "ce6a5688e0cda86d8da827aaa2a93d308e3adf80ab89ac3cbf505f14dbfae377" } diff --git a/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/migration.ts b/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/migration.ts index 2c25737eda59..ce65c9973f8f 100755 --- a/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/migration.ts +++ b/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/migration.ts @@ -1,11 +1,11 @@ #!/usr/bin/env -S node import { createIndex, Migration, MigrationCLI } from '@prisma/orm-mongo/target/migration'; -import type { Contract as End } from '../../snapshots/32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78/contract'; -import endContract from '../../snapshots/32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78/contract.json' with { +import type { Contract as End } from '../../snapshots/315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4/contract'; +import endContract from '../../snapshots/315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4/contract.json' with { type: 'json', }; -import type { Contract as Start } from '../../snapshots/917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f/contract'; -import startContract from '../../snapshots/917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f/contract.json' with { +import type { Contract as Start } from '../../snapshots/fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad/contract'; +import startContract from '../../snapshots/fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad/contract.json' with { type: 'json', }; diff --git a/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/ops.json b/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/ops.json index 6112f4c35500..fe0e2fde4669 100644 --- a/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/ops.json +++ b/examples/retail-store/migrations/app/20260513T0507_add_product_category_index/ops.json @@ -1,51 +1,26 @@ [ { - "id": "index.products.create(primaryCategory:1,articleType:1)", - "label": "Create index on products (primaryCategory:1, articleType:1)", + "id": "index.products.create(primaryCategory_1_articleType_1)", + "label": "Create index primaryCategory_1_articleType_1 on products (primaryCategory:1, articleType:1)", "operationClass": "additive", "precheck": [ { - "description": "index does not already exist on products", + "description": "no index named primaryCategory_1_articleType_1 exists on products", "source": { "kind": "listIndexes", "collection": "products" }, "filter": { "kind": "field", - "field": "key", + "field": "name", "op": "$eq", - "value": { - "primaryCategory": 1, - "articleType": 1 - } + "value": "primaryCategory_1_articleType_1" }, "expect": "notExists", - "object": "an index on { primaryCategory: 1, articleType: 1 } in \"products\"" - } - ], - "execute": [ - { - "description": "create index on products", - "command": { - "kind": "createIndex", - "collection": "products", - "keys": [ - { - "direction": 1, - "field": "primaryCategory" - }, - { - "direction": 1, - "field": "articleType" - } - ], - "name": "primaryCategory_1_articleType_1" - } - } - ], - "postcheck": [ + "object": "an index named \"primaryCategory_1_articleType_1\" in \"products\"" + }, { - "description": "index exists on products", + "description": "no index with the same keys and options exists on products", "source": { "kind": "listIndexes", "collection": "products" @@ -102,6 +77,100 @@ } ] }, + "expect": "notExists", + "object": "an index on { primaryCategory: 1, articleType: 1 } in \"products\"" + } + ], + "execute": [ + { + "description": "create index primaryCategory_1_articleType_1 on products", + "command": { + "kind": "createIndex", + "collection": "products", + "keys": [ + { + "direction": 1, + "field": "primaryCategory" + }, + { + "direction": 1, + "field": "articleType" + } + ], + "name": "primaryCategory_1_articleType_1" + } + } + ], + "postcheck": [ + { + "description": "index primaryCategory_1_articleType_1 exists on products", + "source": { + "kind": "listIndexes", + "collection": "products" + }, + "filter": { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "name", + "op": "$eq", + "value": "primaryCategory_1_articleType_1" + }, + { + "kind": "and", + "exprs": [ + { + "kind": "field", + "field": "key", + "op": "$eq", + "value": { + "primaryCategory": 1, + "articleType": 1 + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "unique", + "op": "$eq", + "value": true + } + }, + { + "kind": "not", + "expr": { + "kind": "field", + "field": "sparse", + "op": "$eq", + "value": true + } + }, + { + "kind": "exists", + "field": "expireAfterSeconds", + "exists": false + }, + { + "kind": "exists", + "field": "partialFilterExpression", + "exists": false + }, + { + "kind": "exists", + "field": "wildcardProjection", + "exists": false + }, + { + "kind": "exists", + "field": "collation", + "exists": false + } + ] + } + ] + }, "expect": "exists" } ] diff --git a/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/migration.json b/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/migration.json index 115dcae34373..92e4618b4fa9 100644 --- a/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/migration.json +++ b/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/migration.json @@ -1,7 +1,7 @@ { - "from": "32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78", - "to": "c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467", + "from": "315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4", + "to": "5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748", "providedInvariants": [], "createdAt": "2026-05-13T05:08:23.957Z", - "migrationHash": "21376cd04dd2ac1a87eea87af86728fce737c346bb0acfd066ff3842525daa0e" + "migrationHash": "6fc0e3ad71da6431b56ed317ac81f7198f5e31cc0e746775bad04f9dce8f82d6" } diff --git a/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/migration.ts b/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/migration.ts index 11167ec9355b..95488255337c 100755 --- a/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/migration.ts +++ b/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/migration.ts @@ -13,12 +13,12 @@ import { MigrationCLI, setValidation, } from '@prisma/orm-mongo/target/migration'; -import type { Contract as Start } from '../../snapshots/32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78/contract'; -import startContract from '../../snapshots/32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78/contract.json' with { +import type { Contract as End } from '../../snapshots/5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748/contract'; +import endContract from '../../snapshots/5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748/contract.json' with { type: 'json', }; -import type { Contract as End } from '../../snapshots/c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467/contract'; -import endContract from '../../snapshots/c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467/contract.json' with { +import type { Contract as Start } from '../../snapshots/315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4/contract'; +import startContract from '../../snapshots/315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4/contract.json' with { type: 'json', }; diff --git a/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/ops.json b/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/ops.json index 662bc61d3ce0..ca3c44d60958 100644 --- a/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/ops.json +++ b/examples/retail-store/migrations/app/20260513T0508_backfill_product_status/ops.json @@ -124,7 +124,7 @@ }, "meta": { "target": "mongo", - "storageHash": "c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467", + "storageHash": "5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748", "lane": "mongo-pipeline" } }, @@ -155,7 +155,7 @@ }, "meta": { "target": "mongo", - "storageHash": "c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467", + "storageHash": "5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748", "lane": "mongo-raw" } } @@ -185,7 +185,7 @@ }, "meta": { "target": "mongo", - "storageHash": "c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467", + "storageHash": "5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748", "lane": "mongo-pipeline" } }, diff --git a/examples/retail-store/migrations/app/20260628T0931_add_product_status_order_type_enums/migration.json b/examples/retail-store/migrations/app/20260628T0931_add_product_status_order_type_enums/migration.json index a4b442280405..0027f0df0997 100644 --- a/examples/retail-store/migrations/app/20260628T0931_add_product_status_order_type_enums/migration.json +++ b/examples/retail-store/migrations/app/20260628T0931_add_product_status_order_type_enums/migration.json @@ -1,7 +1,7 @@ { - "from": "c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467", - "to": "2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5", + "from": "5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748", + "to": "1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8", "providedInvariants": [], "createdAt": "2026-06-28T09:31:36.433Z", - "migrationHash": "057aed8cf407d30641357e655e7efc330ae7c6cf5b4352e9edf6f20e5c18e487" + "migrationHash": "f867f591d757df2615e68d1a46a27f50f1a98a509abb21df541e6411f7df6622" } diff --git a/examples/retail-store/migrations/app/20260628T0931_add_product_status_order_type_enums/migration.ts b/examples/retail-store/migrations/app/20260628T0931_add_product_status_order_type_enums/migration.ts index 317b0871a34c..be866ec55903 100755 --- a/examples/retail-store/migrations/app/20260628T0931_add_product_status_order_type_enums/migration.ts +++ b/examples/retail-store/migrations/app/20260628T0931_add_product_status_order_type_enums/migration.ts @@ -1,11 +1,11 @@ #!/usr/bin/env -S node import { collMod, Migration, MigrationCLI } from '@prisma/orm-mongo/target/migration'; -import type { Contract as End } from '../../snapshots/2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5/contract'; -import endContract from '../../snapshots/2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5/contract.json' with { +import type { Contract as End } from '../../snapshots/1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8/contract'; +import endContract from '../../snapshots/1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8/contract.json' with { type: 'json', }; -import type { Contract as Start } from '../../snapshots/c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467/contract'; -import startContract from '../../snapshots/c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467/contract.json' with { +import type { Contract as Start } from '../../snapshots/5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748/contract'; +import startContract from '../../snapshots/5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748/contract.json' with { type: 'json', }; diff --git a/examples/retail-store/migrations/snapshots/2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5/contract.d.ts b/examples/retail-store/migrations/snapshots/1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8/contract.d.ts similarity index 98% rename from examples/retail-store/migrations/snapshots/2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5/contract.d.ts rename to examples/retail-store/migrations/snapshots/1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8/contract.d.ts index 1d1e6c05a177..9b4923d61327 100644 --- a/examples/retail-store/migrations/snapshots/2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5/contract.d.ts +++ b/examples/retail-store/migrations/snapshots/1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8/contract.d.ts @@ -23,7 +23,7 @@ import type { } from '@prisma/orm-mongo/contract/types'; export type StorageHash = - StorageHashBase<'2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5'>; + StorageHashBase<'1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8'>; export type ExecutionHash = ExecutionHashBase; export type ProfileHash = ProfileHashBase<'251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3'>; @@ -231,6 +231,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'userId' }]; readonly kind: 'mongo-index'; + readonly name: 'userId_1'; readonly unique: true; }, ]; @@ -294,11 +295,13 @@ type ContractBase = Omit< { readonly direction: -1; readonly field: 'timestamp' }, ]; readonly kind: 'mongo-index'; + readonly name: 'userId_1_timestamp_-1'; }, { readonly expireAfterSeconds: 7776000; readonly keys: readonly [{ readonly direction: 1; readonly field: 'timestamp' }]; readonly kind: 'mongo-index'; + readonly name: 'timestamp_1'; }, ]; readonly kind: 'mongo-collection'; @@ -366,10 +369,12 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'orderId' }]; readonly kind: 'mongo-index'; + readonly name: 'orderId_1'; }, { readonly keys: readonly [{ readonly direction: -1; readonly field: 'issuedAt' }]; readonly kind: 'mongo-index'; + readonly name: 'issuedAt_-1'; readonly sparse: true; }, ]; @@ -424,6 +429,7 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'country' }, ]; readonly kind: 'mongo-index'; + readonly name: 'city_1_country_1'; }, ]; readonly kind: 'mongo-collection'; @@ -458,6 +464,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'userId' }]; readonly kind: 'mongo-index'; + readonly name: 'userId_1'; }, ]; readonly kind: 'mongo-collection'; @@ -544,6 +551,7 @@ type ContractBase = Omit< { readonly direction: 'text'; readonly field: 'description' }, ]; readonly kind: 'mongo-index'; + readonly name: 'name_text_description_text'; readonly weights: { readonly description: 1; readonly name: 10 }; }, { @@ -552,6 +560,7 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'subCategory' }, ]; readonly kind: 'mongo-index'; + readonly name: 'brand_1_subCategory_1'; }, { readonly keys: readonly [ @@ -559,12 +568,14 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'articleType' }, ]; readonly kind: 'mongo-index'; + readonly name: 'primaryCategory_1_articleType_1'; }, { readonly keys: readonly [ { readonly direction: 'hashed'; readonly field: 'code' }, ]; readonly kind: 'mongo-index'; + readonly name: 'code_hashed'; }, ]; readonly kind: 'mongo-collection'; @@ -629,6 +640,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'email' }]; readonly kind: 'mongo-index'; + readonly name: 'email_1'; readonly unique: true; }, ]; diff --git a/examples/retail-store/migrations/snapshots/1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8/contract.json b/examples/retail-store/migrations/snapshots/1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8/contract.json new file mode 100644 index 000000000000..0a0fa1119d0f --- /dev/null +++ b/examples/retail-store/migrations/snapshots/1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8/contract.json @@ -0,0 +1 @@ +{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"enum":{"OrderType":{"codecId":"mongo/string@1","members":[{"name":"Delivery","value":"delivery"},{"name":"Pickup","value":"pickup"}]},"ProductStatus":{"codecId":"mongo/string@1","members":[{"name":"Active","value":"active"},{"name":"Discontinued","value":"discontinued"},{"name":"OutOfStock","value":"out-of-stock"}]}},"models":{"AddToCartEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"productId":{"field":"productId"}}}},"Cart":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"CartItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"carts","fields":{"id":{"field":"_id"},"items":{"field":"items"},"userId":{"field":"userId"}}}},"Event":{"discriminator":{"field":"type"},"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"sessionId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"id":{"field":"_id"},"sessionId":{"field":"sessionId"},"timestamp":{"field":"timestamp"},"type":{"field":"type"},"userId":{"field":"userId"}}},"variants":{"add-to-cart":{"model":"AddToCartEvent","namespace":"__unbound__"},"search":{"model":"SearchEvent","namespace":"__unbound__"},"view-product":{"model":"ViewProductEvent","namespace":"__unbound__"}}},"Invoice":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"issuedAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"InvoiceLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"orderId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"subtotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"tax":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"total":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}},"relations":{"order":{"cardinality":"N:1","nullable":false,"on":{"localFields":["orderId"],"targetFields":["id"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"invoices","fields":{"id":{"field":"_id"},"issuedAt":{"field":"issuedAt"},"items":{"field":"items"},"orderId":{"field":"orderId"},"subtotal":{"field":"subtotal"},"tax":{"field":"tax"},"total":{"field":"total"}}}},"Location":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"locations","fields":{"city":{"field":"city"},"country":{"field":"country"},"id":{"field":"_id"},"name":{"field":"name"},"postalCode":{"field":"postalCode"},"streetAndNumber":{"field":"streetAndNumber"}}}},"Order":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"OrderLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"shippingAddress":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"statusHistory":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"StatusEntry","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"},"valueSet":{"entityKind":"enum","entityName":"OrderType","namespaceId":"__unbound__","plane":"domain"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"invoices":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["orderId"]},"to":{"model":"Invoice","namespace":"__unbound__"}},"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"orders","fields":{"id":{"field":"_id"},"items":{"field":"items"},"shippingAddress":{"field":"shippingAddress"},"statusHistory":{"field":"statusHistory"},"type":{"field":"type"},"userId":{"field":"userId"}}}},"Product":{"fields":{"articleType":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"code":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"description":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"embedding":{"many":{"elementNullable":false},"nullable":true,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"primaryCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"},"valueSet":{"entityKind":"enum","entityName":"ProductStatus","namespaceId":"__unbound__","plane":"domain"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"products","fields":{"articleType":{"field":"articleType"},"brand":{"field":"brand"},"code":{"field":"code"},"description":{"field":"description"},"embedding":{"field":"embedding"},"id":{"field":"_id"},"image":{"field":"image"},"name":{"field":"name"},"price":{"field":"price"},"primaryCategory":{"field":"primaryCategory"},"status":{"field":"status"},"subCategory":{"field":"subCategory"}}}},"SearchEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"query":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"query":{"field":"query"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"carts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Cart","namespace":"__unbound__"}},"orders":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"}}}},"ViewProductEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"exitMethod":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"exitMethod":{"field":"exitMethod"},"productId":{"field":"productId"},"subCategory":{"field":"subCategory"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"carts":{"model":"Cart","namespace":"__unbound__"},"events":{"model":"Event","namespace":"__unbound__"},"invoices":{"model":"Invoice","namespace":"__unbound__"},"locations":{"model":"Location","namespace":"__unbound__"},"orders":{"model":"Order","namespace":"__unbound__"},"products":{"model":"Product","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"carts":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","name":"userId_1","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"userId":{"bsonType":"objectId"}},"required":["_id","items","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"events":{"indexes":[{"keys":[{"direction":1,"field":"userId"},{"direction":-1,"field":"timestamp"}],"kind":"mongo-index","name":"userId_1_timestamp_-1"},{"expireAfterSeconds":7776000,"keys":[{"direction":1,"field":"timestamp"}],"kind":"mongo-index","name":"timestamp_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"exitMethod":{"bsonType":["null","string"]},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"subCategory":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["view-product"]},"userId":{"bsonType":"string"}},"required":["brand","productId","subCategory","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"query":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["search"]},"userId":{"bsonType":"string"}},"required":["query","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["add-to-cart"]},"userId":{"bsonType":"string"}},"required":["brand","productId","type"]}],"properties":{"_id":{"bsonType":"objectId"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"bsonType":"string"},"userId":{"bsonType":"string"}},"required":["_id","sessionId","timestamp","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"invoices":{"indexes":[{"keys":[{"direction":1,"field":"orderId"}],"kind":"mongo-index","name":"orderId_1"},{"keys":[{"direction":-1,"field":"issuedAt"}],"kind":"mongo-index","name":"issuedAt_-1","sparse":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"issuedAt":{"bsonType":"date"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"lineTotal":{"bsonType":"double"},"name":{"bsonType":"string"},"unitPrice":{"bsonType":"double"}},"required":["amount","lineTotal","name","unitPrice"]}},"orderId":{"bsonType":"objectId"},"subtotal":{"bsonType":"double"},"tax":{"bsonType":"double"},"total":{"bsonType":"double"}},"required":["_id","issuedAt","items","orderId","subtotal","tax","total"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"locations":{"indexes":[{"collation":{"locale":"en","strength":2},"keys":[{"direction":1,"field":"city"},{"direction":1,"field":"country"}],"kind":"mongo-index","name":"city_1_country_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"city":{"bsonType":"string"},"country":{"bsonType":"string"},"name":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["_id","city","country","name","postalCode","streetAndNumber"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"orders":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","name":"userId_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"shippingAddress":{"bsonType":"string"},"statusHistory":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"status":{"bsonType":"string"},"timestamp":{"bsonType":"date"}},"required":["status","timestamp"]}},"type":{"bsonType":"string","enum":["delivery","pickup"]},"userId":{"bsonType":"objectId"}},"required":["_id","items","shippingAddress","statusHistory","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"products":{"indexes":[{"keys":[{"direction":"text","field":"name"},{"direction":"text","field":"description"}],"kind":"mongo-index","name":"name_text_description_text","weights":{"description":1,"name":10}},{"keys":[{"direction":1,"field":"brand"},{"direction":1,"field":"subCategory"}],"kind":"mongo-index","name":"brand_1_subCategory_1"},{"keys":[{"direction":1,"field":"primaryCategory"},{"direction":1,"field":"articleType"}],"kind":"mongo-index","name":"primaryCategory_1_articleType_1"},{"keys":[{"direction":"hashed","field":"code"}],"kind":"mongo-index","name":"code_hashed"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"articleType":{"bsonType":"string"},"brand":{"bsonType":"string"},"code":{"bsonType":"string"},"description":{"bsonType":"string"},"embedding":{"bsonType":["null","array"],"items":{"bsonType":"double"}},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"primaryCategory":{"bsonType":"string"},"status":{"bsonType":"string","enum":["active","discontinued","out-of-stock"]},"subCategory":{"bsonType":"string"}},"required":["_id","articleType","brand","code","description","image","name","price","primaryCategory","status","subCategory"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"indexes":[{"keys":[{"direction":1,"field":"email"}],"kind":"mongo-index","name":"email_1","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["city","country","postalCode","streetAndNumber"]}]},"email":{"bsonType":"string"},"name":{"bsonType":"string"}},"required":["_id","email","name"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"CartItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Image":{"fields":{"url":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"InvoiceLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"lineTotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"unitPrice":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}}},"OrderLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Price":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"currency":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"StatusEntry":{"fields":{"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}}}}},"valueSet":{"OrderType":{"kind":"valueSet","values":["delivery","pickup"]},"ProductStatus":{"kind":"valueSet","values":["active","discontinued","out-of-stock"]}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/retail-store/migrations/snapshots/2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5/contract.json b/examples/retail-store/migrations/snapshots/2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5/contract.json deleted file mode 100644 index 14ba6239f9d8..000000000000 --- a/examples/retail-store/migrations/snapshots/2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5/contract.json +++ /dev/null @@ -1 +0,0 @@ -{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"enum":{"OrderType":{"codecId":"mongo/string@1","members":[{"name":"Delivery","value":"delivery"},{"name":"Pickup","value":"pickup"}]},"ProductStatus":{"codecId":"mongo/string@1","members":[{"name":"Active","value":"active"},{"name":"Discontinued","value":"discontinued"},{"name":"OutOfStock","value":"out-of-stock"}]}},"models":{"AddToCartEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"productId":{"field":"productId"}}}},"Cart":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"CartItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"carts","fields":{"id":{"field":"_id"},"items":{"field":"items"},"userId":{"field":"userId"}}}},"Event":{"discriminator":{"field":"type"},"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"sessionId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"id":{"field":"_id"},"sessionId":{"field":"sessionId"},"timestamp":{"field":"timestamp"},"type":{"field":"type"},"userId":{"field":"userId"}}},"variants":{"add-to-cart":{"model":"AddToCartEvent","namespace":"__unbound__"},"search":{"model":"SearchEvent","namespace":"__unbound__"},"view-product":{"model":"ViewProductEvent","namespace":"__unbound__"}}},"Invoice":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"issuedAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"InvoiceLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"orderId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"subtotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"tax":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"total":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}},"relations":{"order":{"cardinality":"N:1","nullable":false,"on":{"localFields":["orderId"],"targetFields":["id"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"invoices","fields":{"id":{"field":"_id"},"issuedAt":{"field":"issuedAt"},"items":{"field":"items"},"orderId":{"field":"orderId"},"subtotal":{"field":"subtotal"},"tax":{"field":"tax"},"total":{"field":"total"}}}},"Location":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"locations","fields":{"city":{"field":"city"},"country":{"field":"country"},"id":{"field":"_id"},"name":{"field":"name"},"postalCode":{"field":"postalCode"},"streetAndNumber":{"field":"streetAndNumber"}}}},"Order":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"OrderLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"shippingAddress":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"statusHistory":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"StatusEntry","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"},"valueSet":{"entityKind":"enum","entityName":"OrderType","namespaceId":"__unbound__","plane":"domain"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"invoices":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["orderId"]},"to":{"model":"Invoice","namespace":"__unbound__"}},"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"orders","fields":{"id":{"field":"_id"},"items":{"field":"items"},"shippingAddress":{"field":"shippingAddress"},"statusHistory":{"field":"statusHistory"},"type":{"field":"type"},"userId":{"field":"userId"}}}},"Product":{"fields":{"articleType":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"code":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"description":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"embedding":{"many":{"elementNullable":false},"nullable":true,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"primaryCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"},"valueSet":{"entityKind":"enum","entityName":"ProductStatus","namespaceId":"__unbound__","plane":"domain"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"products","fields":{"articleType":{"field":"articleType"},"brand":{"field":"brand"},"code":{"field":"code"},"description":{"field":"description"},"embedding":{"field":"embedding"},"id":{"field":"_id"},"image":{"field":"image"},"name":{"field":"name"},"price":{"field":"price"},"primaryCategory":{"field":"primaryCategory"},"status":{"field":"status"},"subCategory":{"field":"subCategory"}}}},"SearchEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"query":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"query":{"field":"query"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"carts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Cart","namespace":"__unbound__"}},"orders":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"}}}},"ViewProductEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"exitMethod":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"exitMethod":{"field":"exitMethod"},"productId":{"field":"productId"},"subCategory":{"field":"subCategory"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"carts":{"model":"Cart","namespace":"__unbound__"},"events":{"model":"Event","namespace":"__unbound__"},"invoices":{"model":"Invoice","namespace":"__unbound__"},"locations":{"model":"Location","namespace":"__unbound__"},"orders":{"model":"Order","namespace":"__unbound__"},"products":{"model":"Product","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"carts":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"userId":{"bsonType":"objectId"}},"required":["_id","items","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"events":{"indexes":[{"keys":[{"direction":1,"field":"userId"},{"direction":-1,"field":"timestamp"}],"kind":"mongo-index"},{"expireAfterSeconds":7776000,"keys":[{"direction":1,"field":"timestamp"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"exitMethod":{"bsonType":["null","string"]},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"subCategory":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["view-product"]},"userId":{"bsonType":"string"}},"required":["brand","productId","subCategory","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"query":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["search"]},"userId":{"bsonType":"string"}},"required":["query","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["add-to-cart"]},"userId":{"bsonType":"string"}},"required":["brand","productId","type"]}],"properties":{"_id":{"bsonType":"objectId"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"bsonType":"string"},"userId":{"bsonType":"string"}},"required":["_id","sessionId","timestamp","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"invoices":{"indexes":[{"keys":[{"direction":1,"field":"orderId"}],"kind":"mongo-index"},{"keys":[{"direction":-1,"field":"issuedAt"}],"kind":"mongo-index","sparse":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"issuedAt":{"bsonType":"date"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"lineTotal":{"bsonType":"double"},"name":{"bsonType":"string"},"unitPrice":{"bsonType":"double"}},"required":["amount","lineTotal","name","unitPrice"]}},"orderId":{"bsonType":"objectId"},"subtotal":{"bsonType":"double"},"tax":{"bsonType":"double"},"total":{"bsonType":"double"}},"required":["_id","issuedAt","items","orderId","subtotal","tax","total"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"locations":{"indexes":[{"collation":{"locale":"en","strength":2},"keys":[{"direction":1,"field":"city"},{"direction":1,"field":"country"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"city":{"bsonType":"string"},"country":{"bsonType":"string"},"name":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["_id","city","country","name","postalCode","streetAndNumber"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"orders":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"shippingAddress":{"bsonType":"string"},"statusHistory":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"status":{"bsonType":"string"},"timestamp":{"bsonType":"date"}},"required":["status","timestamp"]}},"type":{"bsonType":"string","enum":["delivery","pickup"]},"userId":{"bsonType":"objectId"}},"required":["_id","items","shippingAddress","statusHistory","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"products":{"indexes":[{"keys":[{"direction":"text","field":"name"},{"direction":"text","field":"description"}],"kind":"mongo-index","weights":{"description":1,"name":10}},{"keys":[{"direction":1,"field":"brand"},{"direction":1,"field":"subCategory"}],"kind":"mongo-index"},{"keys":[{"direction":1,"field":"primaryCategory"},{"direction":1,"field":"articleType"}],"kind":"mongo-index"},{"keys":[{"direction":"hashed","field":"code"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"articleType":{"bsonType":"string"},"brand":{"bsonType":"string"},"code":{"bsonType":"string"},"description":{"bsonType":"string"},"embedding":{"bsonType":["null","array"],"items":{"bsonType":"double"}},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"primaryCategory":{"bsonType":"string"},"status":{"bsonType":"string","enum":["active","discontinued","out-of-stock"]},"subCategory":{"bsonType":"string"}},"required":["_id","articleType","brand","code","description","image","name","price","primaryCategory","status","subCategory"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"indexes":[{"keys":[{"direction":1,"field":"email"}],"kind":"mongo-index","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["city","country","postalCode","streetAndNumber"]}]},"email":{"bsonType":"string"},"name":{"bsonType":"string"}},"required":["_id","email","name"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"CartItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Image":{"fields":{"url":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"InvoiceLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"lineTotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"unitPrice":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}}},"OrderLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Price":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"currency":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"StatusEntry":{"fields":{"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}}}}},"valueSet":{"OrderType":{"kind":"valueSet","values":["delivery","pickup"]},"ProductStatus":{"kind":"valueSet","values":["active","discontinued","out-of-stock"]}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/retail-store/migrations/snapshots/32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78/contract.d.ts b/examples/retail-store/migrations/snapshots/315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4/contract.d.ts similarity index 98% rename from examples/retail-store/migrations/snapshots/32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78/contract.d.ts rename to examples/retail-store/migrations/snapshots/315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4/contract.d.ts index 65c76ed39bf5..ac89cddec35b 100644 --- a/examples/retail-store/migrations/snapshots/32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78/contract.d.ts +++ b/examples/retail-store/migrations/snapshots/315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4/contract.d.ts @@ -23,7 +23,7 @@ import type { } from '@prisma/orm-mongo/contract/types'; export type StorageHash = - StorageHashBase<'32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78'>; + StorageHashBase<'315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4'>; export type ExecutionHash = ExecutionHashBase; export type ProfileHash = ProfileHashBase<'251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3'>; @@ -212,6 +212,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'userId' }]; readonly kind: 'mongo-index'; + readonly name: 'userId_1'; readonly unique: true; }, ]; @@ -275,11 +276,13 @@ type ContractBase = Omit< { readonly direction: -1; readonly field: 'timestamp' }, ]; readonly kind: 'mongo-index'; + readonly name: 'userId_1_timestamp_-1'; }, { readonly expireAfterSeconds: 7776000; readonly keys: readonly [{ readonly direction: 1; readonly field: 'timestamp' }]; readonly kind: 'mongo-index'; + readonly name: 'timestamp_1'; }, ]; readonly kind: 'mongo-collection'; @@ -347,10 +350,12 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'orderId' }]; readonly kind: 'mongo-index'; + readonly name: 'orderId_1'; }, { readonly keys: readonly [{ readonly direction: -1; readonly field: 'issuedAt' }]; readonly kind: 'mongo-index'; + readonly name: 'issuedAt_-1'; readonly sparse: true; }, ]; @@ -405,6 +410,7 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'country' }, ]; readonly kind: 'mongo-index'; + readonly name: 'city_1_country_1'; }, ]; readonly kind: 'mongo-collection'; @@ -439,6 +445,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'userId' }]; readonly kind: 'mongo-index'; + readonly name: 'userId_1'; }, ]; readonly kind: 'mongo-collection'; @@ -522,6 +529,7 @@ type ContractBase = Omit< { readonly direction: 'text'; readonly field: 'description' }, ]; readonly kind: 'mongo-index'; + readonly name: 'name_text_description_text'; readonly weights: { readonly description: 1; readonly name: 10 }; }, { @@ -530,6 +538,7 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'subCategory' }, ]; readonly kind: 'mongo-index'; + readonly name: 'brand_1_subCategory_1'; }, { readonly keys: readonly [ @@ -537,12 +546,14 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'articleType' }, ]; readonly kind: 'mongo-index'; + readonly name: 'primaryCategory_1_articleType_1'; }, { readonly keys: readonly [ { readonly direction: 'hashed'; readonly field: 'code' }, ]; readonly kind: 'mongo-index'; + readonly name: 'code_hashed'; }, ]; readonly kind: 'mongo-collection'; @@ -598,6 +609,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'email' }]; readonly kind: 'mongo-index'; + readonly name: 'email_1'; readonly unique: true; }, ]; diff --git a/examples/retail-store/migrations/snapshots/315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4/contract.json b/examples/retail-store/migrations/snapshots/315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4/contract.json new file mode 100644 index 000000000000..448c30f843b7 --- /dev/null +++ b/examples/retail-store/migrations/snapshots/315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4/contract.json @@ -0,0 +1 @@ +{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"models":{"AddToCartEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"productId":{"field":"productId"}}}},"Cart":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"CartItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"carts","fields":{"id":{"field":"_id"},"items":{"field":"items"},"userId":{"field":"userId"}}}},"Event":{"discriminator":{"field":"type"},"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"sessionId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"id":{"field":"_id"},"sessionId":{"field":"sessionId"},"timestamp":{"field":"timestamp"},"type":{"field":"type"},"userId":{"field":"userId"}}},"variants":{"add-to-cart":{"model":"AddToCartEvent","namespace":"__unbound__"},"search":{"model":"SearchEvent","namespace":"__unbound__"},"view-product":{"model":"ViewProductEvent","namespace":"__unbound__"}}},"Invoice":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"issuedAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"InvoiceLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"orderId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"subtotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"tax":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"total":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}},"relations":{"order":{"cardinality":"N:1","nullable":false,"on":{"localFields":["orderId"],"targetFields":["id"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"invoices","fields":{"id":{"field":"_id"},"issuedAt":{"field":"issuedAt"},"items":{"field":"items"},"orderId":{"field":"orderId"},"subtotal":{"field":"subtotal"},"tax":{"field":"tax"},"total":{"field":"total"}}}},"Location":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"locations","fields":{"city":{"field":"city"},"country":{"field":"country"},"id":{"field":"_id"},"name":{"field":"name"},"postalCode":{"field":"postalCode"},"streetAndNumber":{"field":"streetAndNumber"}}}},"Order":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"OrderLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"shippingAddress":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"statusHistory":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"StatusEntry","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"invoices":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["orderId"]},"to":{"model":"Invoice","namespace":"__unbound__"}},"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"orders","fields":{"id":{"field":"_id"},"items":{"field":"items"},"shippingAddress":{"field":"shippingAddress"},"statusHistory":{"field":"statusHistory"},"type":{"field":"type"},"userId":{"field":"userId"}}}},"Product":{"fields":{"articleType":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"code":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"description":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"primaryCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"products","fields":{"articleType":{"field":"articleType"},"brand":{"field":"brand"},"code":{"field":"code"},"description":{"field":"description"},"id":{"field":"_id"},"image":{"field":"image"},"name":{"field":"name"},"price":{"field":"price"},"primaryCategory":{"field":"primaryCategory"},"subCategory":{"field":"subCategory"}}}},"SearchEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"query":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"query":{"field":"query"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"carts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Cart","namespace":"__unbound__"}},"orders":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"}}}},"ViewProductEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"exitMethod":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"exitMethod":{"field":"exitMethod"},"productId":{"field":"productId"},"subCategory":{"field":"subCategory"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"carts":{"model":"Cart","namespace":"__unbound__"},"events":{"model":"Event","namespace":"__unbound__"},"invoices":{"model":"Invoice","namespace":"__unbound__"},"locations":{"model":"Location","namespace":"__unbound__"},"orders":{"model":"Order","namespace":"__unbound__"},"products":{"model":"Product","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"carts":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","name":"userId_1","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"userId":{"bsonType":"objectId"}},"required":["_id","items","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"events":{"indexes":[{"keys":[{"direction":1,"field":"userId"},{"direction":-1,"field":"timestamp"}],"kind":"mongo-index","name":"userId_1_timestamp_-1"},{"expireAfterSeconds":7776000,"keys":[{"direction":1,"field":"timestamp"}],"kind":"mongo-index","name":"timestamp_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"exitMethod":{"bsonType":["null","string"]},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"subCategory":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["view-product"]},"userId":{"bsonType":"string"}},"required":["brand","productId","subCategory","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"query":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["search"]},"userId":{"bsonType":"string"}},"required":["query","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["add-to-cart"]},"userId":{"bsonType":"string"}},"required":["brand","productId","type"]}],"properties":{"_id":{"bsonType":"objectId"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"bsonType":"string"},"userId":{"bsonType":"string"}},"required":["_id","sessionId","timestamp","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"invoices":{"indexes":[{"keys":[{"direction":1,"field":"orderId"}],"kind":"mongo-index","name":"orderId_1"},{"keys":[{"direction":-1,"field":"issuedAt"}],"kind":"mongo-index","name":"issuedAt_-1","sparse":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"issuedAt":{"bsonType":"date"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"lineTotal":{"bsonType":"double"},"name":{"bsonType":"string"},"unitPrice":{"bsonType":"double"}},"required":["amount","lineTotal","name","unitPrice"]}},"orderId":{"bsonType":"objectId"},"subtotal":{"bsonType":"double"},"tax":{"bsonType":"double"},"total":{"bsonType":"double"}},"required":["_id","issuedAt","items","orderId","subtotal","tax","total"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"locations":{"indexes":[{"collation":{"locale":"en","strength":2},"keys":[{"direction":1,"field":"city"},{"direction":1,"field":"country"}],"kind":"mongo-index","name":"city_1_country_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"city":{"bsonType":"string"},"country":{"bsonType":"string"},"name":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["_id","city","country","name","postalCode","streetAndNumber"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"orders":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","name":"userId_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"shippingAddress":{"bsonType":"string"},"statusHistory":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"status":{"bsonType":"string"},"timestamp":{"bsonType":"date"}},"required":["status","timestamp"]}},"type":{"bsonType":"string"},"userId":{"bsonType":"objectId"}},"required":["_id","items","shippingAddress","statusHistory","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"products":{"indexes":[{"keys":[{"direction":"text","field":"name"},{"direction":"text","field":"description"}],"kind":"mongo-index","name":"name_text_description_text","weights":{"description":1,"name":10}},{"keys":[{"direction":1,"field":"brand"},{"direction":1,"field":"subCategory"}],"kind":"mongo-index","name":"brand_1_subCategory_1"},{"keys":[{"direction":1,"field":"primaryCategory"},{"direction":1,"field":"articleType"}],"kind":"mongo-index","name":"primaryCategory_1_articleType_1"},{"keys":[{"direction":"hashed","field":"code"}],"kind":"mongo-index","name":"code_hashed"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"articleType":{"bsonType":"string"},"brand":{"bsonType":"string"},"code":{"bsonType":"string"},"description":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"primaryCategory":{"bsonType":"string"},"subCategory":{"bsonType":"string"}},"required":["_id","articleType","brand","code","description","image","name","price","primaryCategory","subCategory"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"indexes":[{"keys":[{"direction":1,"field":"email"}],"kind":"mongo-index","name":"email_1","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["city","country","postalCode","streetAndNumber"]}]},"email":{"bsonType":"string"},"name":{"bsonType":"string"}},"required":["_id","email","name"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"CartItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Image":{"fields":{"url":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"InvoiceLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"lineTotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"unitPrice":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}}},"OrderLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Price":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"currency":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"StatusEntry":{"fields":{"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}}}}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"315ba05dd789203ec66ae19c9e637054e1b70d1c1151341f551040cb908c82e4"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/retail-store/migrations/snapshots/32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78/contract.json b/examples/retail-store/migrations/snapshots/32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78/contract.json deleted file mode 100644 index efc89272ddd9..000000000000 --- a/examples/retail-store/migrations/snapshots/32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78/contract.json +++ /dev/null @@ -1 +0,0 @@ -{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"models":{"AddToCartEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"productId":{"field":"productId"}}}},"Cart":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"CartItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"carts","fields":{"id":{"field":"_id"},"items":{"field":"items"},"userId":{"field":"userId"}}}},"Event":{"discriminator":{"field":"type"},"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"sessionId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"id":{"field":"_id"},"sessionId":{"field":"sessionId"},"timestamp":{"field":"timestamp"},"type":{"field":"type"},"userId":{"field":"userId"}}},"variants":{"add-to-cart":{"model":"AddToCartEvent","namespace":"__unbound__"},"search":{"model":"SearchEvent","namespace":"__unbound__"},"view-product":{"model":"ViewProductEvent","namespace":"__unbound__"}}},"Invoice":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"issuedAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"InvoiceLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"orderId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"subtotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"tax":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"total":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}},"relations":{"order":{"cardinality":"N:1","nullable":false,"on":{"localFields":["orderId"],"targetFields":["id"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"invoices","fields":{"id":{"field":"_id"},"issuedAt":{"field":"issuedAt"},"items":{"field":"items"},"orderId":{"field":"orderId"},"subtotal":{"field":"subtotal"},"tax":{"field":"tax"},"total":{"field":"total"}}}},"Location":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"locations","fields":{"city":{"field":"city"},"country":{"field":"country"},"id":{"field":"_id"},"name":{"field":"name"},"postalCode":{"field":"postalCode"},"streetAndNumber":{"field":"streetAndNumber"}}}},"Order":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"OrderLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"shippingAddress":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"statusHistory":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"StatusEntry","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"invoices":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["orderId"]},"to":{"model":"Invoice","namespace":"__unbound__"}},"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"orders","fields":{"id":{"field":"_id"},"items":{"field":"items"},"shippingAddress":{"field":"shippingAddress"},"statusHistory":{"field":"statusHistory"},"type":{"field":"type"},"userId":{"field":"userId"}}}},"Product":{"fields":{"articleType":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"code":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"description":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"primaryCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"products","fields":{"articleType":{"field":"articleType"},"brand":{"field":"brand"},"code":{"field":"code"},"description":{"field":"description"},"id":{"field":"_id"},"image":{"field":"image"},"name":{"field":"name"},"price":{"field":"price"},"primaryCategory":{"field":"primaryCategory"},"subCategory":{"field":"subCategory"}}}},"SearchEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"query":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"query":{"field":"query"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"carts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Cart","namespace":"__unbound__"}},"orders":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"}}}},"ViewProductEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"exitMethod":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"exitMethod":{"field":"exitMethod"},"productId":{"field":"productId"},"subCategory":{"field":"subCategory"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"carts":{"model":"Cart","namespace":"__unbound__"},"events":{"model":"Event","namespace":"__unbound__"},"invoices":{"model":"Invoice","namespace":"__unbound__"},"locations":{"model":"Location","namespace":"__unbound__"},"orders":{"model":"Order","namespace":"__unbound__"},"products":{"model":"Product","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"carts":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"userId":{"bsonType":"objectId"}},"required":["_id","items","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"events":{"indexes":[{"keys":[{"direction":1,"field":"userId"},{"direction":-1,"field":"timestamp"}],"kind":"mongo-index"},{"expireAfterSeconds":7776000,"keys":[{"direction":1,"field":"timestamp"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"exitMethod":{"bsonType":["null","string"]},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"subCategory":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["view-product"]},"userId":{"bsonType":"string"}},"required":["brand","productId","subCategory","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"query":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["search"]},"userId":{"bsonType":"string"}},"required":["query","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["add-to-cart"]},"userId":{"bsonType":"string"}},"required":["brand","productId","type"]}],"properties":{"_id":{"bsonType":"objectId"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"bsonType":"string"},"userId":{"bsonType":"string"}},"required":["_id","sessionId","timestamp","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"invoices":{"indexes":[{"keys":[{"direction":1,"field":"orderId"}],"kind":"mongo-index"},{"keys":[{"direction":-1,"field":"issuedAt"}],"kind":"mongo-index","sparse":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"issuedAt":{"bsonType":"date"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"lineTotal":{"bsonType":"double"},"name":{"bsonType":"string"},"unitPrice":{"bsonType":"double"}},"required":["amount","lineTotal","name","unitPrice"]}},"orderId":{"bsonType":"objectId"},"subtotal":{"bsonType":"double"},"tax":{"bsonType":"double"},"total":{"bsonType":"double"}},"required":["_id","issuedAt","items","orderId","subtotal","tax","total"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"locations":{"indexes":[{"collation":{"locale":"en","strength":2},"keys":[{"direction":1,"field":"city"},{"direction":1,"field":"country"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"city":{"bsonType":"string"},"country":{"bsonType":"string"},"name":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["_id","city","country","name","postalCode","streetAndNumber"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"orders":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"shippingAddress":{"bsonType":"string"},"statusHistory":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"status":{"bsonType":"string"},"timestamp":{"bsonType":"date"}},"required":["status","timestamp"]}},"type":{"bsonType":"string"},"userId":{"bsonType":"objectId"}},"required":["_id","items","shippingAddress","statusHistory","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"products":{"indexes":[{"keys":[{"direction":"text","field":"name"},{"direction":"text","field":"description"}],"kind":"mongo-index","weights":{"description":1,"name":10}},{"keys":[{"direction":1,"field":"brand"},{"direction":1,"field":"subCategory"}],"kind":"mongo-index"},{"keys":[{"direction":1,"field":"primaryCategory"},{"direction":1,"field":"articleType"}],"kind":"mongo-index"},{"keys":[{"direction":"hashed","field":"code"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"articleType":{"bsonType":"string"},"brand":{"bsonType":"string"},"code":{"bsonType":"string"},"description":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"primaryCategory":{"bsonType":"string"},"subCategory":{"bsonType":"string"}},"required":["_id","articleType","brand","code","description","image","name","price","primaryCategory","subCategory"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"indexes":[{"keys":[{"direction":1,"field":"email"}],"kind":"mongo-index","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["city","country","postalCode","streetAndNumber"]}]},"email":{"bsonType":"string"},"name":{"bsonType":"string"}},"required":["_id","email","name"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"CartItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Image":{"fields":{"url":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"InvoiceLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"lineTotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"unitPrice":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}}},"OrderLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Price":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"currency":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"StatusEntry":{"fields":{"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}}}}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"32b49a010a6bec06827848a71ade1588d7863e429644edc402becee50580be78"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/retail-store/migrations/snapshots/c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467/contract.d.ts b/examples/retail-store/migrations/snapshots/5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748/contract.d.ts similarity index 98% rename from examples/retail-store/migrations/snapshots/c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467/contract.d.ts rename to examples/retail-store/migrations/snapshots/5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748/contract.d.ts index 419f49b78331..6d6cf2d13e73 100644 --- a/examples/retail-store/migrations/snapshots/c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467/contract.d.ts +++ b/examples/retail-store/migrations/snapshots/5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748/contract.d.ts @@ -23,7 +23,7 @@ import type { } from '@prisma/orm-mongo/contract/types'; export type StorageHash = - StorageHashBase<'c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467'>; + StorageHashBase<'5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748'>; export type ExecutionHash = ExecutionHashBase; export type ProfileHash = ProfileHashBase<'251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3'>; @@ -214,6 +214,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'userId' }]; readonly kind: 'mongo-index'; + readonly name: 'userId_1'; readonly unique: true; }, ]; @@ -277,11 +278,13 @@ type ContractBase = Omit< { readonly direction: -1; readonly field: 'timestamp' }, ]; readonly kind: 'mongo-index'; + readonly name: 'userId_1_timestamp_-1'; }, { readonly expireAfterSeconds: 7776000; readonly keys: readonly [{ readonly direction: 1; readonly field: 'timestamp' }]; readonly kind: 'mongo-index'; + readonly name: 'timestamp_1'; }, ]; readonly kind: 'mongo-collection'; @@ -349,10 +352,12 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'orderId' }]; readonly kind: 'mongo-index'; + readonly name: 'orderId_1'; }, { readonly keys: readonly [{ readonly direction: -1; readonly field: 'issuedAt' }]; readonly kind: 'mongo-index'; + readonly name: 'issuedAt_-1'; readonly sparse: true; }, ]; @@ -407,6 +412,7 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'country' }, ]; readonly kind: 'mongo-index'; + readonly name: 'city_1_country_1'; }, ]; readonly kind: 'mongo-collection'; @@ -441,6 +447,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'userId' }]; readonly kind: 'mongo-index'; + readonly name: 'userId_1'; }, ]; readonly kind: 'mongo-collection'; @@ -524,6 +531,7 @@ type ContractBase = Omit< { readonly direction: 'text'; readonly field: 'description' }, ]; readonly kind: 'mongo-index'; + readonly name: 'name_text_description_text'; readonly weights: { readonly description: 1; readonly name: 10 }; }, { @@ -532,6 +540,7 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'subCategory' }, ]; readonly kind: 'mongo-index'; + readonly name: 'brand_1_subCategory_1'; }, { readonly keys: readonly [ @@ -539,12 +548,14 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'articleType' }, ]; readonly kind: 'mongo-index'; + readonly name: 'primaryCategory_1_articleType_1'; }, { readonly keys: readonly [ { readonly direction: 'hashed'; readonly field: 'code' }, ]; readonly kind: 'mongo-index'; + readonly name: 'code_hashed'; }, ]; readonly kind: 'mongo-collection'; @@ -606,6 +617,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'email' }]; readonly kind: 'mongo-index'; + readonly name: 'email_1'; readonly unique: true; }, ]; diff --git a/examples/retail-store/migrations/snapshots/5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748/contract.json b/examples/retail-store/migrations/snapshots/5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748/contract.json new file mode 100644 index 000000000000..6fa31d46fc0b --- /dev/null +++ b/examples/retail-store/migrations/snapshots/5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748/contract.json @@ -0,0 +1 @@ +{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"models":{"AddToCartEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"productId":{"field":"productId"}}}},"Cart":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"CartItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"carts","fields":{"id":{"field":"_id"},"items":{"field":"items"},"userId":{"field":"userId"}}}},"Event":{"discriminator":{"field":"type"},"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"sessionId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"id":{"field":"_id"},"sessionId":{"field":"sessionId"},"timestamp":{"field":"timestamp"},"type":{"field":"type"},"userId":{"field":"userId"}}},"variants":{"add-to-cart":{"model":"AddToCartEvent","namespace":"__unbound__"},"search":{"model":"SearchEvent","namespace":"__unbound__"},"view-product":{"model":"ViewProductEvent","namespace":"__unbound__"}}},"Invoice":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"issuedAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"InvoiceLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"orderId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"subtotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"tax":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"total":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}},"relations":{"order":{"cardinality":"N:1","nullable":false,"on":{"localFields":["orderId"],"targetFields":["id"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"invoices","fields":{"id":{"field":"_id"},"issuedAt":{"field":"issuedAt"},"items":{"field":"items"},"orderId":{"field":"orderId"},"subtotal":{"field":"subtotal"},"tax":{"field":"tax"},"total":{"field":"total"}}}},"Location":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"locations","fields":{"city":{"field":"city"},"country":{"field":"country"},"id":{"field":"_id"},"name":{"field":"name"},"postalCode":{"field":"postalCode"},"streetAndNumber":{"field":"streetAndNumber"}}}},"Order":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"OrderLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"shippingAddress":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"statusHistory":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"StatusEntry","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"invoices":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["orderId"]},"to":{"model":"Invoice","namespace":"__unbound__"}},"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"orders","fields":{"id":{"field":"_id"},"items":{"field":"items"},"shippingAddress":{"field":"shippingAddress"},"statusHistory":{"field":"statusHistory"},"type":{"field":"type"},"userId":{"field":"userId"}}}},"Product":{"fields":{"articleType":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"code":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"description":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"embedding":{"many":{"elementNullable":false},"nullable":true,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"primaryCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"products","fields":{"articleType":{"field":"articleType"},"brand":{"field":"brand"},"code":{"field":"code"},"description":{"field":"description"},"embedding":{"field":"embedding"},"id":{"field":"_id"},"image":{"field":"image"},"name":{"field":"name"},"price":{"field":"price"},"primaryCategory":{"field":"primaryCategory"},"status":{"field":"status"},"subCategory":{"field":"subCategory"}}}},"SearchEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"query":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"query":{"field":"query"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"carts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Cart","namespace":"__unbound__"}},"orders":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"}}}},"ViewProductEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"exitMethod":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"exitMethod":{"field":"exitMethod"},"productId":{"field":"productId"},"subCategory":{"field":"subCategory"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"carts":{"model":"Cart","namespace":"__unbound__"},"events":{"model":"Event","namespace":"__unbound__"},"invoices":{"model":"Invoice","namespace":"__unbound__"},"locations":{"model":"Location","namespace":"__unbound__"},"orders":{"model":"Order","namespace":"__unbound__"},"products":{"model":"Product","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"carts":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","name":"userId_1","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"userId":{"bsonType":"objectId"}},"required":["_id","items","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"events":{"indexes":[{"keys":[{"direction":1,"field":"userId"},{"direction":-1,"field":"timestamp"}],"kind":"mongo-index","name":"userId_1_timestamp_-1"},{"expireAfterSeconds":7776000,"keys":[{"direction":1,"field":"timestamp"}],"kind":"mongo-index","name":"timestamp_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"exitMethod":{"bsonType":["null","string"]},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"subCategory":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["view-product"]},"userId":{"bsonType":"string"}},"required":["brand","productId","subCategory","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"query":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["search"]},"userId":{"bsonType":"string"}},"required":["query","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["add-to-cart"]},"userId":{"bsonType":"string"}},"required":["brand","productId","type"]}],"properties":{"_id":{"bsonType":"objectId"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"bsonType":"string"},"userId":{"bsonType":"string"}},"required":["_id","sessionId","timestamp","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"invoices":{"indexes":[{"keys":[{"direction":1,"field":"orderId"}],"kind":"mongo-index","name":"orderId_1"},{"keys":[{"direction":-1,"field":"issuedAt"}],"kind":"mongo-index","name":"issuedAt_-1","sparse":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"issuedAt":{"bsonType":"date"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"lineTotal":{"bsonType":"double"},"name":{"bsonType":"string"},"unitPrice":{"bsonType":"double"}},"required":["amount","lineTotal","name","unitPrice"]}},"orderId":{"bsonType":"objectId"},"subtotal":{"bsonType":"double"},"tax":{"bsonType":"double"},"total":{"bsonType":"double"}},"required":["_id","issuedAt","items","orderId","subtotal","tax","total"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"locations":{"indexes":[{"collation":{"locale":"en","strength":2},"keys":[{"direction":1,"field":"city"},{"direction":1,"field":"country"}],"kind":"mongo-index","name":"city_1_country_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"city":{"bsonType":"string"},"country":{"bsonType":"string"},"name":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["_id","city","country","name","postalCode","streetAndNumber"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"orders":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","name":"userId_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"shippingAddress":{"bsonType":"string"},"statusHistory":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"status":{"bsonType":"string"},"timestamp":{"bsonType":"date"}},"required":["status","timestamp"]}},"type":{"bsonType":"string"},"userId":{"bsonType":"objectId"}},"required":["_id","items","shippingAddress","statusHistory","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"products":{"indexes":[{"keys":[{"direction":"text","field":"name"},{"direction":"text","field":"description"}],"kind":"mongo-index","name":"name_text_description_text","weights":{"description":1,"name":10}},{"keys":[{"direction":1,"field":"brand"},{"direction":1,"field":"subCategory"}],"kind":"mongo-index","name":"brand_1_subCategory_1"},{"keys":[{"direction":1,"field":"primaryCategory"},{"direction":1,"field":"articleType"}],"kind":"mongo-index","name":"primaryCategory_1_articleType_1"},{"keys":[{"direction":"hashed","field":"code"}],"kind":"mongo-index","name":"code_hashed"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"articleType":{"bsonType":"string"},"brand":{"bsonType":"string"},"code":{"bsonType":"string"},"description":{"bsonType":"string"},"embedding":{"bsonType":["null","array"],"items":{"bsonType":"double"}},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"primaryCategory":{"bsonType":"string"},"status":{"bsonType":"string"},"subCategory":{"bsonType":"string"}},"required":["_id","articleType","brand","code","description","image","name","price","primaryCategory","status","subCategory"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"indexes":[{"keys":[{"direction":1,"field":"email"}],"kind":"mongo-index","name":"email_1","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["city","country","postalCode","streetAndNumber"]}]},"email":{"bsonType":"string"},"name":{"bsonType":"string"}},"required":["_id","email","name"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"CartItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Image":{"fields":{"url":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"InvoiceLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"lineTotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"unitPrice":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}}},"OrderLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Price":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"currency":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"StatusEntry":{"fields":{"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}}}}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"5b423686089e2ada5ece2b224849ac73ce6b998fb062e88217d2f30a1a567748"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/retail-store/migrations/snapshots/917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f/contract.json b/examples/retail-store/migrations/snapshots/917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f/contract.json deleted file mode 100644 index 199fa0bca020..000000000000 --- a/examples/retail-store/migrations/snapshots/917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f/contract.json +++ /dev/null @@ -1 +0,0 @@ -{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"models":{"AddToCartEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"productId":{"field":"productId"}}}},"Cart":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"CartItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"carts","fields":{"id":{"field":"_id"},"items":{"field":"items"},"userId":{"field":"userId"}}}},"Event":{"discriminator":{"field":"type"},"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"sessionId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"id":{"field":"_id"},"sessionId":{"field":"sessionId"},"timestamp":{"field":"timestamp"},"type":{"field":"type"},"userId":{"field":"userId"}}},"variants":{"add-to-cart":{"model":"AddToCartEvent","namespace":"__unbound__"},"search":{"model":"SearchEvent","namespace":"__unbound__"},"view-product":{"model":"ViewProductEvent","namespace":"__unbound__"}}},"Invoice":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"issuedAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"InvoiceLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"orderId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"subtotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"tax":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"total":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}},"relations":{"order":{"cardinality":"N:1","nullable":false,"on":{"localFields":["orderId"],"targetFields":["id"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"invoices","fields":{"id":{"field":"_id"},"issuedAt":{"field":"issuedAt"},"items":{"field":"items"},"orderId":{"field":"orderId"},"subtotal":{"field":"subtotal"},"tax":{"field":"tax"},"total":{"field":"total"}}}},"Location":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"locations","fields":{"city":{"field":"city"},"country":{"field":"country"},"id":{"field":"_id"},"name":{"field":"name"},"postalCode":{"field":"postalCode"},"streetAndNumber":{"field":"streetAndNumber"}}}},"Order":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"OrderLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"shippingAddress":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"statusHistory":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"StatusEntry","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"invoices":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["orderId"]},"to":{"model":"Invoice","namespace":"__unbound__"}},"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"orders","fields":{"id":{"field":"_id"},"items":{"field":"items"},"shippingAddress":{"field":"shippingAddress"},"statusHistory":{"field":"statusHistory"},"type":{"field":"type"},"userId":{"field":"userId"}}}},"Product":{"fields":{"articleType":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"code":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"description":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"primaryCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"products","fields":{"articleType":{"field":"articleType"},"brand":{"field":"brand"},"code":{"field":"code"},"description":{"field":"description"},"id":{"field":"_id"},"image":{"field":"image"},"name":{"field":"name"},"price":{"field":"price"},"primaryCategory":{"field":"primaryCategory"},"subCategory":{"field":"subCategory"}}}},"SearchEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"query":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"query":{"field":"query"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"carts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Cart","namespace":"__unbound__"}},"orders":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"}}}},"ViewProductEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"exitMethod":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"exitMethod":{"field":"exitMethod"},"productId":{"field":"productId"},"subCategory":{"field":"subCategory"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"carts":{"model":"Cart","namespace":"__unbound__"},"events":{"model":"Event","namespace":"__unbound__"},"invoices":{"model":"Invoice","namespace":"__unbound__"},"locations":{"model":"Location","namespace":"__unbound__"},"orders":{"model":"Order","namespace":"__unbound__"},"products":{"model":"Product","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"carts":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"userId":{"bsonType":"objectId"}},"required":["_id","items","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"events":{"indexes":[{"keys":[{"direction":1,"field":"userId"},{"direction":-1,"field":"timestamp"}],"kind":"mongo-index"},{"expireAfterSeconds":7776000,"keys":[{"direction":1,"field":"timestamp"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"exitMethod":{"bsonType":["null","string"]},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"subCategory":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["view-product"]},"userId":{"bsonType":"string"}},"required":["brand","productId","subCategory","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"query":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["search"]},"userId":{"bsonType":"string"}},"required":["query","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["add-to-cart"]},"userId":{"bsonType":"string"}},"required":["brand","productId","type"]}],"properties":{"_id":{"bsonType":"objectId"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"bsonType":"string"},"userId":{"bsonType":"string"}},"required":["_id","sessionId","timestamp","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"invoices":{"indexes":[{"keys":[{"direction":1,"field":"orderId"}],"kind":"mongo-index"},{"keys":[{"direction":-1,"field":"issuedAt"}],"kind":"mongo-index","sparse":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"issuedAt":{"bsonType":"date"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"lineTotal":{"bsonType":"double"},"name":{"bsonType":"string"},"unitPrice":{"bsonType":"double"}},"required":["amount","lineTotal","name","unitPrice"]}},"orderId":{"bsonType":"objectId"},"subtotal":{"bsonType":"double"},"tax":{"bsonType":"double"},"total":{"bsonType":"double"}},"required":["_id","issuedAt","items","orderId","subtotal","tax","total"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"locations":{"indexes":[{"collation":{"locale":"en","strength":2},"keys":[{"direction":1,"field":"city"},{"direction":1,"field":"country"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"city":{"bsonType":"string"},"country":{"bsonType":"string"},"name":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["_id","city","country","name","postalCode","streetAndNumber"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"orders":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"shippingAddress":{"bsonType":"string"},"statusHistory":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"status":{"bsonType":"string"},"timestamp":{"bsonType":"date"}},"required":["status","timestamp"]}},"type":{"bsonType":"string"},"userId":{"bsonType":"objectId"}},"required":["_id","items","shippingAddress","statusHistory","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"products":{"indexes":[{"keys":[{"direction":"text","field":"name"},{"direction":"text","field":"description"}],"kind":"mongo-index","weights":{"description":1,"name":10}},{"keys":[{"direction":1,"field":"brand"},{"direction":1,"field":"subCategory"}],"kind":"mongo-index"},{"keys":[{"direction":"hashed","field":"code"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"articleType":{"bsonType":"string"},"brand":{"bsonType":"string"},"code":{"bsonType":"string"},"description":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"primaryCategory":{"bsonType":"string"},"subCategory":{"bsonType":"string"}},"required":["_id","articleType","brand","code","description","image","name","price","primaryCategory","subCategory"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"indexes":[{"keys":[{"direction":1,"field":"email"}],"kind":"mongo-index","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["city","country","postalCode","streetAndNumber"]}]},"email":{"bsonType":"string"},"name":{"bsonType":"string"}},"required":["_id","email","name"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"CartItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Image":{"fields":{"url":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"InvoiceLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"lineTotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"unitPrice":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}}},"OrderLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Price":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"currency":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"StatusEntry":{"fields":{"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}}}}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/retail-store/migrations/snapshots/c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467/contract.json b/examples/retail-store/migrations/snapshots/c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467/contract.json deleted file mode 100644 index ece0d2834161..000000000000 --- a/examples/retail-store/migrations/snapshots/c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467/contract.json +++ /dev/null @@ -1 +0,0 @@ -{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"models":{"AddToCartEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"productId":{"field":"productId"}}}},"Cart":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"CartItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"carts","fields":{"id":{"field":"_id"},"items":{"field":"items"},"userId":{"field":"userId"}}}},"Event":{"discriminator":{"field":"type"},"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"sessionId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"id":{"field":"_id"},"sessionId":{"field":"sessionId"},"timestamp":{"field":"timestamp"},"type":{"field":"type"},"userId":{"field":"userId"}}},"variants":{"add-to-cart":{"model":"AddToCartEvent","namespace":"__unbound__"},"search":{"model":"SearchEvent","namespace":"__unbound__"},"view-product":{"model":"ViewProductEvent","namespace":"__unbound__"}}},"Invoice":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"issuedAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"InvoiceLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"orderId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"subtotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"tax":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"total":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}},"relations":{"order":{"cardinality":"N:1","nullable":false,"on":{"localFields":["orderId"],"targetFields":["id"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"invoices","fields":{"id":{"field":"_id"},"issuedAt":{"field":"issuedAt"},"items":{"field":"items"},"orderId":{"field":"orderId"},"subtotal":{"field":"subtotal"},"tax":{"field":"tax"},"total":{"field":"total"}}}},"Location":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"locations","fields":{"city":{"field":"city"},"country":{"field":"country"},"id":{"field":"_id"},"name":{"field":"name"},"postalCode":{"field":"postalCode"},"streetAndNumber":{"field":"streetAndNumber"}}}},"Order":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"OrderLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"shippingAddress":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"statusHistory":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"StatusEntry","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"invoices":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["orderId"]},"to":{"model":"Invoice","namespace":"__unbound__"}},"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"orders","fields":{"id":{"field":"_id"},"items":{"field":"items"},"shippingAddress":{"field":"shippingAddress"},"statusHistory":{"field":"statusHistory"},"type":{"field":"type"},"userId":{"field":"userId"}}}},"Product":{"fields":{"articleType":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"code":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"description":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"embedding":{"many":{"elementNullable":false},"nullable":true,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"primaryCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"products","fields":{"articleType":{"field":"articleType"},"brand":{"field":"brand"},"code":{"field":"code"},"description":{"field":"description"},"embedding":{"field":"embedding"},"id":{"field":"_id"},"image":{"field":"image"},"name":{"field":"name"},"price":{"field":"price"},"primaryCategory":{"field":"primaryCategory"},"status":{"field":"status"},"subCategory":{"field":"subCategory"}}}},"SearchEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"query":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"query":{"field":"query"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"carts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Cart","namespace":"__unbound__"}},"orders":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"}}}},"ViewProductEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"exitMethod":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"exitMethod":{"field":"exitMethod"},"productId":{"field":"productId"},"subCategory":{"field":"subCategory"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"carts":{"model":"Cart","namespace":"__unbound__"},"events":{"model":"Event","namespace":"__unbound__"},"invoices":{"model":"Invoice","namespace":"__unbound__"},"locations":{"model":"Location","namespace":"__unbound__"},"orders":{"model":"Order","namespace":"__unbound__"},"products":{"model":"Product","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"carts":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"userId":{"bsonType":"objectId"}},"required":["_id","items","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"events":{"indexes":[{"keys":[{"direction":1,"field":"userId"},{"direction":-1,"field":"timestamp"}],"kind":"mongo-index"},{"expireAfterSeconds":7776000,"keys":[{"direction":1,"field":"timestamp"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"exitMethod":{"bsonType":["null","string"]},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"subCategory":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["view-product"]},"userId":{"bsonType":"string"}},"required":["brand","productId","subCategory","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"query":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["search"]},"userId":{"bsonType":"string"}},"required":["query","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["add-to-cart"]},"userId":{"bsonType":"string"}},"required":["brand","productId","type"]}],"properties":{"_id":{"bsonType":"objectId"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"bsonType":"string"},"userId":{"bsonType":"string"}},"required":["_id","sessionId","timestamp","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"invoices":{"indexes":[{"keys":[{"direction":1,"field":"orderId"}],"kind":"mongo-index"},{"keys":[{"direction":-1,"field":"issuedAt"}],"kind":"mongo-index","sparse":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"issuedAt":{"bsonType":"date"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"lineTotal":{"bsonType":"double"},"name":{"bsonType":"string"},"unitPrice":{"bsonType":"double"}},"required":["amount","lineTotal","name","unitPrice"]}},"orderId":{"bsonType":"objectId"},"subtotal":{"bsonType":"double"},"tax":{"bsonType":"double"},"total":{"bsonType":"double"}},"required":["_id","issuedAt","items","orderId","subtotal","tax","total"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"locations":{"indexes":[{"collation":{"locale":"en","strength":2},"keys":[{"direction":1,"field":"city"},{"direction":1,"field":"country"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"city":{"bsonType":"string"},"country":{"bsonType":"string"},"name":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["_id","city","country","name","postalCode","streetAndNumber"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"orders":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"shippingAddress":{"bsonType":"string"},"statusHistory":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"status":{"bsonType":"string"},"timestamp":{"bsonType":"date"}},"required":["status","timestamp"]}},"type":{"bsonType":"string"},"userId":{"bsonType":"objectId"}},"required":["_id","items","shippingAddress","statusHistory","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"products":{"indexes":[{"keys":[{"direction":"text","field":"name"},{"direction":"text","field":"description"}],"kind":"mongo-index","weights":{"description":1,"name":10}},{"keys":[{"direction":1,"field":"brand"},{"direction":1,"field":"subCategory"}],"kind":"mongo-index"},{"keys":[{"direction":1,"field":"primaryCategory"},{"direction":1,"field":"articleType"}],"kind":"mongo-index"},{"keys":[{"direction":"hashed","field":"code"}],"kind":"mongo-index"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"articleType":{"bsonType":"string"},"brand":{"bsonType":"string"},"code":{"bsonType":"string"},"description":{"bsonType":"string"},"embedding":{"bsonType":["null","array"],"items":{"bsonType":"double"}},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"primaryCategory":{"bsonType":"string"},"status":{"bsonType":"string"},"subCategory":{"bsonType":"string"}},"required":["_id","articleType","brand","code","description","image","name","price","primaryCategory","status","subCategory"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"indexes":[{"keys":[{"direction":1,"field":"email"}],"kind":"mongo-index","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["city","country","postalCode","streetAndNumber"]}]},"email":{"bsonType":"string"},"name":{"bsonType":"string"}},"required":["_id","email","name"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"CartItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Image":{"fields":{"url":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"InvoiceLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"lineTotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"unitPrice":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}}},"OrderLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Price":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"currency":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"StatusEntry":{"fields":{"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}}}}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"c529f34639ba48ec978d133093cd95ac2a5a76196ea39b3fa71179a9ef2c3467"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/retail-store/migrations/snapshots/917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f/contract.d.ts b/examples/retail-store/migrations/snapshots/fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad/contract.d.ts similarity index 98% rename from examples/retail-store/migrations/snapshots/917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f/contract.d.ts rename to examples/retail-store/migrations/snapshots/fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad/contract.d.ts index 2d1156267de5..da0dd0347b57 100644 --- a/examples/retail-store/migrations/snapshots/917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f/contract.d.ts +++ b/examples/retail-store/migrations/snapshots/fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad/contract.d.ts @@ -23,7 +23,7 @@ import type { } from '@prisma/orm-mongo/contract/types'; export type StorageHash = - StorageHashBase<'917a8cff4030fa9140b93367a663f33d66cd14e92547b51e23a9ff82ffabf27f'>; + StorageHashBase<'fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad'>; export type ExecutionHash = ExecutionHashBase; export type ProfileHash = ProfileHashBase<'251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3'>; @@ -212,6 +212,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'userId' }]; readonly kind: 'mongo-index'; + readonly name: 'userId_1'; readonly unique: true; }, ]; @@ -275,11 +276,13 @@ type ContractBase = Omit< { readonly direction: -1; readonly field: 'timestamp' }, ]; readonly kind: 'mongo-index'; + readonly name: 'userId_1_timestamp_-1'; }, { readonly expireAfterSeconds: 7776000; readonly keys: readonly [{ readonly direction: 1; readonly field: 'timestamp' }]; readonly kind: 'mongo-index'; + readonly name: 'timestamp_1'; }, ]; readonly kind: 'mongo-collection'; @@ -347,10 +350,12 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'orderId' }]; readonly kind: 'mongo-index'; + readonly name: 'orderId_1'; }, { readonly keys: readonly [{ readonly direction: -1; readonly field: 'issuedAt' }]; readonly kind: 'mongo-index'; + readonly name: 'issuedAt_-1'; readonly sparse: true; }, ]; @@ -405,6 +410,7 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'country' }, ]; readonly kind: 'mongo-index'; + readonly name: 'city_1_country_1'; }, ]; readonly kind: 'mongo-collection'; @@ -439,6 +445,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'userId' }]; readonly kind: 'mongo-index'; + readonly name: 'userId_1'; }, ]; readonly kind: 'mongo-collection'; @@ -522,6 +529,7 @@ type ContractBase = Omit< { readonly direction: 'text'; readonly field: 'description' }, ]; readonly kind: 'mongo-index'; + readonly name: 'name_text_description_text'; readonly weights: { readonly description: 1; readonly name: 10 }; }, { @@ -530,12 +538,14 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'subCategory' }, ]; readonly kind: 'mongo-index'; + readonly name: 'brand_1_subCategory_1'; }, { readonly keys: readonly [ { readonly direction: 'hashed'; readonly field: 'code' }, ]; readonly kind: 'mongo-index'; + readonly name: 'code_hashed'; }, ]; readonly kind: 'mongo-collection'; @@ -591,6 +601,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'email' }]; readonly kind: 'mongo-index'; + readonly name: 'email_1'; readonly unique: true; }, ]; diff --git a/examples/retail-store/migrations/snapshots/fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad/contract.json b/examples/retail-store/migrations/snapshots/fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad/contract.json new file mode 100644 index 000000000000..f76cf8853d50 --- /dev/null +++ b/examples/retail-store/migrations/snapshots/fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad/contract.json @@ -0,0 +1 @@ +{"_generated":{"message":"This file is automatically generated by \"prisma contract emit\".","regenerate":"To regenerate, run: prisma contract emit","warning":"⚠️ GENERATED FILE - DO NOT EDIT"},"capabilities":{},"domain":{"namespaces":{"__unbound__":{"models":{"AddToCartEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"productId":{"field":"productId"}}}},"Cart":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"CartItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"carts","fields":{"id":{"field":"_id"},"items":{"field":"items"},"userId":{"field":"userId"}}}},"Event":{"discriminator":{"field":"type"},"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"sessionId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"id":{"field":"_id"},"sessionId":{"field":"sessionId"},"timestamp":{"field":"timestamp"},"type":{"field":"type"},"userId":{"field":"userId"}}},"variants":{"add-to-cart":{"model":"AddToCartEvent","namespace":"__unbound__"},"search":{"model":"SearchEvent","namespace":"__unbound__"},"view-product":{"model":"ViewProductEvent","namespace":"__unbound__"}}},"Invoice":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"issuedAt":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"InvoiceLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"orderId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"subtotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"tax":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"total":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}},"relations":{"order":{"cardinality":"N:1","nullable":false,"on":{"localFields":["orderId"],"targetFields":["id"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"invoices","fields":{"id":{"field":"_id"},"issuedAt":{"field":"issuedAt"},"items":{"field":"items"},"orderId":{"field":"orderId"},"subtotal":{"field":"subtotal"},"tax":{"field":"tax"},"total":{"field":"total"}}}},"Location":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"locations","fields":{"city":{"field":"city"},"country":{"field":"country"},"id":{"field":"_id"},"name":{"field":"name"},"postalCode":{"field":"postalCode"},"streetAndNumber":{"field":"streetAndNumber"}}}},"Order":{"fields":{"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"items":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"OrderLineItem","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"shippingAddress":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"statusHistory":{"many":{"elementNullable":false},"nullable":false,"type":{"entityKind":"valueObject","entityName":"StatusEntry","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"type":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"userId":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}}},"relations":{"invoices":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["orderId"]},"to":{"model":"Invoice","namespace":"__unbound__"}},"user":{"cardinality":"N:1","nullable":false,"on":{"localFields":["userId"],"targetFields":["id"]},"to":{"model":"User","namespace":"__unbound__"}}},"storage":{"collection":"orders","fields":{"id":{"field":"_id"},"items":{"field":"items"},"shippingAddress":{"field":"shippingAddress"},"statusHistory":{"field":"statusHistory"},"type":{"field":"type"},"userId":{"field":"userId"}}}},"Product":{"fields":{"articleType":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"code":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"description":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"primaryCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"products","fields":{"articleType":{"field":"articleType"},"brand":{"field":"brand"},"code":{"field":"code"},"description":{"field":"description"},"id":{"field":"_id"},"image":{"field":"image"},"name":{"field":"name"},"price":{"field":"price"},"primaryCategory":{"field":"primaryCategory"},"subCategory":{"field":"subCategory"}}}},"SearchEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"query":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"query":{"field":"query"}}}},"User":{"fields":{"address":{"nullable":true,"type":{"entityKind":"valueObject","entityName":"Address","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"email":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"id":{"nullable":false,"type":{"codecId":"mongo/objectId@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{"carts":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Cart","namespace":"__unbound__"}},"orders":{"cardinality":"1:N","on":{"localFields":["id"],"targetFields":["userId"]},"to":{"model":"Order","namespace":"__unbound__"}}},"storage":{"collection":"users","fields":{"address":{"field":"address"},"email":{"field":"email"},"id":{"field":"_id"},"name":{"field":"name"}}}},"ViewProductEvent":{"base":{"model":"Event","namespace":"__unbound__"},"fields":{"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"exitMethod":{"nullable":true,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"subCategory":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}},"relations":{},"storage":{"collection":"events","fields":{"brand":{"field":"brand"},"exitMethod":{"field":"exitMethod"},"productId":{"field":"productId"},"subCategory":{"field":"subCategory"}}}}}}}},"extensions":{},"meta":{},"profileHash":"251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3","roots":{"carts":{"model":"Cart","namespace":"__unbound__"},"events":{"model":"Event","namespace":"__unbound__"},"invoices":{"model":"Invoice","namespace":"__unbound__"},"locations":{"model":"Location","namespace":"__unbound__"},"orders":{"model":"Order","namespace":"__unbound__"},"products":{"model":"Product","namespace":"__unbound__"},"users":{"model":"User","namespace":"__unbound__"}},"schemaVersion":"1","storage":{"namespaces":{"__unbound__":{"entries":{"collection":{"carts":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","name":"userId_1","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"userId":{"bsonType":"objectId"}},"required":["_id","items","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"events":{"indexes":[{"keys":[{"direction":1,"field":"userId"},{"direction":-1,"field":"timestamp"}],"kind":"mongo-index","name":"userId_1_timestamp_-1"},{"expireAfterSeconds":7776000,"keys":[{"direction":1,"field":"timestamp"}],"kind":"mongo-index","name":"timestamp_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"bsonType":"object","oneOf":[{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"exitMethod":{"bsonType":["null","string"]},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"subCategory":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["view-product"]},"userId":{"bsonType":"string"}},"required":["brand","productId","subCategory","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"query":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["search"]},"userId":{"bsonType":"string"}},"required":["query","type"]},{"additionalProperties":false,"properties":{"_id":{"bsonType":"objectId"},"brand":{"bsonType":"string"},"productId":{"bsonType":"string"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"enum":["add-to-cart"]},"userId":{"bsonType":"string"}},"required":["brand","productId","type"]}],"properties":{"_id":{"bsonType":"objectId"},"sessionId":{"bsonType":"string"},"timestamp":{"bsonType":"date"},"type":{"bsonType":"string"},"userId":{"bsonType":"string"}},"required":["_id","sessionId","timestamp","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"invoices":{"indexes":[{"keys":[{"direction":1,"field":"orderId"}],"kind":"mongo-index","name":"orderId_1"},{"keys":[{"direction":-1,"field":"issuedAt"}],"kind":"mongo-index","name":"issuedAt_-1","sparse":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"issuedAt":{"bsonType":"date"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"lineTotal":{"bsonType":"double"},"name":{"bsonType":"string"},"unitPrice":{"bsonType":"double"}},"required":["amount","lineTotal","name","unitPrice"]}},"orderId":{"bsonType":"objectId"},"subtotal":{"bsonType":"double"},"tax":{"bsonType":"double"},"total":{"bsonType":"double"}},"required":["_id","issuedAt","items","orderId","subtotal","tax","total"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"locations":{"indexes":[{"collation":{"locale":"en","strength":2},"keys":[{"direction":1,"field":"city"},{"direction":1,"field":"country"}],"kind":"mongo-index","name":"city_1_country_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"city":{"bsonType":"string"},"country":{"bsonType":"string"},"name":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["_id","city","country","name","postalCode","streetAndNumber"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"orders":{"indexes":[{"keys":[{"direction":1,"field":"userId"}],"kind":"mongo-index","name":"userId_1"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"items":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"int"},"brand":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"productId":{"bsonType":"string"}},"required":["amount","brand","image","name","price","productId"]}},"shippingAddress":{"bsonType":"string"},"statusHistory":{"bsonType":"array","items":{"additionalProperties":false,"bsonType":"object","properties":{"status":{"bsonType":"string"},"timestamp":{"bsonType":"date"}},"required":["status","timestamp"]}},"type":{"bsonType":"string"},"userId":{"bsonType":"objectId"}},"required":["_id","items","shippingAddress","statusHistory","type","userId"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"products":{"indexes":[{"keys":[{"direction":"text","field":"name"},{"direction":"text","field":"description"}],"kind":"mongo-index","name":"name_text_description_text","weights":{"description":1,"name":10}},{"keys":[{"direction":1,"field":"brand"},{"direction":1,"field":"subCategory"}],"kind":"mongo-index","name":"brand_1_subCategory_1"},{"keys":[{"direction":"hashed","field":"code"}],"kind":"mongo-index","name":"code_hashed"}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"articleType":{"bsonType":"string"},"brand":{"bsonType":"string"},"code":{"bsonType":"string"},"description":{"bsonType":"string"},"image":{"additionalProperties":false,"bsonType":"object","properties":{"url":{"bsonType":"string"}},"required":["url"]},"name":{"bsonType":"string"},"price":{"additionalProperties":false,"bsonType":"object","properties":{"amount":{"bsonType":"double"},"currency":{"bsonType":"string"}},"required":["amount","currency"]},"primaryCategory":{"bsonType":"string"},"subCategory":{"bsonType":"string"}},"required":["_id","articleType","brand","code","description","image","name","price","primaryCategory","subCategory"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}},"users":{"indexes":[{"keys":[{"direction":1,"field":"email"}],"kind":"mongo-index","name":"email_1","unique":true}],"kind":"mongo-collection","validator":{"jsonSchema":{"additionalProperties":false,"bsonType":"object","properties":{"_id":{"bsonType":"objectId"},"address":{"oneOf":[{"bsonType":"null"},{"additionalProperties":false,"bsonType":"object","properties":{"city":{"bsonType":"string"},"country":{"bsonType":"string"},"postalCode":{"bsonType":"string"},"streetAndNumber":{"bsonType":"string"}},"required":["city","country","postalCode","streetAndNumber"]}]},"email":{"bsonType":"string"},"name":{"bsonType":"string"}},"required":["_id","email","name"]},"kind":"mongo-validator","validationAction":"error","validationLevel":"strict"}}},"valueObject":{"Address":{"fields":{"city":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"country":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"postalCode":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"streetAndNumber":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"CartItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Image":{"fields":{"url":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"InvoiceLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"lineTotal":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"unitPrice":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}}}},"OrderLineItem":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/int32@1","kind":"scalar"}},"brand":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"image":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Image","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"name":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"price":{"nullable":false,"type":{"entityKind":"valueObject","entityName":"Price","kind":"valueObject","namespaceId":"__unbound__","plane":"storage"}},"productId":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"Price":{"fields":{"amount":{"nullable":false,"type":{"codecId":"mongo/double@1","kind":"scalar"}},"currency":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}}}},"StatusEntry":{"fields":{"status":{"nullable":false,"type":{"codecId":"mongo/string@1","kind":"scalar"}},"timestamp":{"nullable":false,"type":{"codecId":"mongo/date@1","kind":"scalar"}}}}}},"id":"__unbound__","kind":"mongo-database"}},"storageHash":"fb3df4c4899adcd423e9b75164870cef1be789fe6871a24b7fda64e707f324ad"},"target":"mongo","targetFamily":"mongo"} diff --git a/examples/retail-store/src/contract.d.ts b/examples/retail-store/src/contract.d.ts index 1d1e6c05a177..9b4923d61327 100644 --- a/examples/retail-store/src/contract.d.ts +++ b/examples/retail-store/src/contract.d.ts @@ -23,7 +23,7 @@ import type { } from '@prisma/orm-mongo/contract/types'; export type StorageHash = - StorageHashBase<'2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5'>; + StorageHashBase<'1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8'>; export type ExecutionHash = ExecutionHashBase; export type ProfileHash = ProfileHashBase<'251b3ce23f6c9f561892e7c1af9d2cc941a13d64ba1aa7226b90036b09568cc3'>; @@ -231,6 +231,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'userId' }]; readonly kind: 'mongo-index'; + readonly name: 'userId_1'; readonly unique: true; }, ]; @@ -294,11 +295,13 @@ type ContractBase = Omit< { readonly direction: -1; readonly field: 'timestamp' }, ]; readonly kind: 'mongo-index'; + readonly name: 'userId_1_timestamp_-1'; }, { readonly expireAfterSeconds: 7776000; readonly keys: readonly [{ readonly direction: 1; readonly field: 'timestamp' }]; readonly kind: 'mongo-index'; + readonly name: 'timestamp_1'; }, ]; readonly kind: 'mongo-collection'; @@ -366,10 +369,12 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'orderId' }]; readonly kind: 'mongo-index'; + readonly name: 'orderId_1'; }, { readonly keys: readonly [{ readonly direction: -1; readonly field: 'issuedAt' }]; readonly kind: 'mongo-index'; + readonly name: 'issuedAt_-1'; readonly sparse: true; }, ]; @@ -424,6 +429,7 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'country' }, ]; readonly kind: 'mongo-index'; + readonly name: 'city_1_country_1'; }, ]; readonly kind: 'mongo-collection'; @@ -458,6 +464,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'userId' }]; readonly kind: 'mongo-index'; + readonly name: 'userId_1'; }, ]; readonly kind: 'mongo-collection'; @@ -544,6 +551,7 @@ type ContractBase = Omit< { readonly direction: 'text'; readonly field: 'description' }, ]; readonly kind: 'mongo-index'; + readonly name: 'name_text_description_text'; readonly weights: { readonly description: 1; readonly name: 10 }; }, { @@ -552,6 +560,7 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'subCategory' }, ]; readonly kind: 'mongo-index'; + readonly name: 'brand_1_subCategory_1'; }, { readonly keys: readonly [ @@ -559,12 +568,14 @@ type ContractBase = Omit< { readonly direction: 1; readonly field: 'articleType' }, ]; readonly kind: 'mongo-index'; + readonly name: 'primaryCategory_1_articleType_1'; }, { readonly keys: readonly [ { readonly direction: 'hashed'; readonly field: 'code' }, ]; readonly kind: 'mongo-index'; + readonly name: 'code_hashed'; }, ]; readonly kind: 'mongo-collection'; @@ -629,6 +640,7 @@ type ContractBase = Omit< { readonly keys: readonly [{ readonly direction: 1; readonly field: 'email' }]; readonly kind: 'mongo-index'; + readonly name: 'email_1'; readonly unique: true; }, ]; diff --git a/examples/retail-store/src/contract.json b/examples/retail-store/src/contract.json index 0b7f73438f44..87ed2f8f9620 100644 --- a/examples/retail-store/src/contract.json +++ b/examples/retail-store/src/contract.json @@ -862,6 +862,7 @@ } ], "kind": "mongo-index", + "name": "userId_1", "unique": true } ], @@ -959,7 +960,8 @@ "field": "timestamp" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "userId_1_timestamp_-1" }, { "expireAfterSeconds": 7776000, @@ -969,7 +971,8 @@ "field": "timestamp" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "timestamp_1" } ], "kind": "mongo-collection", @@ -1122,7 +1125,8 @@ "field": "orderId" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "orderId_1" }, { "keys": [ @@ -1132,6 +1136,7 @@ } ], "kind": "mongo-index", + "name": "issuedAt_-1", "sparse": true } ], @@ -1219,7 +1224,8 @@ "field": "country" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "city_1_country_1" } ], "kind": "mongo-collection", @@ -1270,7 +1276,8 @@ "field": "userId" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "userId_1" } ], "kind": "mongo-collection", @@ -1400,6 +1407,7 @@ } ], "kind": "mongo-index", + "name": "name_text_description_text", "weights": { "description": 1, "name": 10 @@ -1416,7 +1424,8 @@ "field": "subCategory" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "brand_1_subCategory_1" }, { "keys": [ @@ -1429,7 +1438,8 @@ "field": "articleType" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "primaryCategory_1_articleType_1" }, { "keys": [ @@ -1438,7 +1448,8 @@ "field": "code" } ], - "kind": "mongo-index" + "kind": "mongo-index", + "name": "code_hashed" } ], "kind": "mongo-collection", @@ -1546,6 +1557,7 @@ } ], "kind": "mongo-index", + "name": "email_1", "unique": true } ], @@ -1847,7 +1859,7 @@ "kind": "mongo-database" } }, - "storageHash": "2f0e67cbc2a193e280f07c26972a484af4b62d3472c018c73bfd095749d4d0f5" + "storageHash": "1c73a5a88943362a9b01f6476e85fddc574031accb9ada12be61e9da24fe0fd8" }, "capabilities": {}, "extensions": {}, diff --git a/packages/1-framework/3-tooling/language-server/test/completion-provider.attributes.test.ts b/packages/1-framework/3-tooling/language-server/test/completion-provider.attributes.test.ts index 2feb807a506f..6ea7add63675 100644 --- a/packages/1-framework/3-tooling/language-server/test/completion-provider.attributes.test.ts +++ b/packages/1-framework/3-tooling/language-server/test/completion-provider.attributes.test.ts @@ -437,6 +437,7 @@ describe('providePslCompletionItems', () => { stack, ).items.map((item) => item.label), ).toEqual([ + 'map', 'type', 'sparse', 'expireAfterSeconds', diff --git a/packages/2-mongo-family/1-foundation/mongo-contract/README.md b/packages/2-mongo-family/1-foundation/mongo-contract/README.md index b01b67ca990c..0a0b8e207085 100644 --- a/packages/2-mongo-family/1-foundation/mongo-contract/README.md +++ b/packages/2-mongo-family/1-foundation/mongo-contract/README.md @@ -7,5 +7,6 @@ Contract types and validation for the MongoDB family. - **Contract types**: `MongoContract`, `MongoContractWithTypeMaps`, `MongoTypeMaps`, `MongoStorageShape` (raw-JSON storage shape) — the typed contract representation for MongoDB targets - **Storage IR**: `MongoStorage` — the in-memory storage class instantiated by the per-target contract serializer; structurally satisfies `MongoStorageShape` and additionally carries the `namespaces` map - **Type-level extraction**: `ExtractMongoTypeMaps`, `ExtractMongoCodecTypes`, `InferModelRow` — utility types for deriving codec types and row shapes from a contract -- **Index identity**: `MONGO_INDEX_OPTION_KEYS` lists every index option; the compiler rejects the list when an option of `MongoIndexInput` is missing. `indexLookupKey()` turns an index into a string from its keys and those options, with an option set to `false` counting as unset; `canonicalize()` writes option values with sorted keys. Two indexes are the same when their lookup keys are equal. The contract builder merges indexes, and the planner and the verifier match indexes, by this one function. +- **Index names**: every `MongoIndex` has a required `name`, the name MongoDB stores it under. `defaultMongoIndexName(keys)` gives the name MongoDB gives an index created without one, such as `email_1`. +- **Index identity**: `MONGO_INDEX_OPTION_KEYS` lists every index option; the compiler rejects the list when an option of `MongoIndexInput` other than `name` is missing. The name is not an option, and `indexLookupKey()` leaves it out. `indexLookupKey()` turns an index into a string from its keys and those options, with an option set to `false` counting as unset; `canonicalize()` writes option values with sorted keys. Two indexes are the same when their lookup keys are equal. The contract builder merges indexes, and the planner and the verifier match indexes, by this one function. - **Structural schema + storage validation primitives**: `MongoContractSchema` (arktype envelope) and `validateMongoStorage()` — consumed by the family `ContractSerializerBase` to validate Mongo contracts at the deserializer seam. No freestanding `validateMongoContract` wrapper is exported; callers cross the seam via `familyInstance.deserializeContract(...)`. diff --git a/packages/2-mongo-family/1-foundation/mongo-contract/src/contract-schema.ts b/packages/2-mongo-family/1-foundation/mongo-contract/src/contract-schema.ts index 4bccbe714815..700697fdf6b9 100644 --- a/packages/2-mongo-family/1-foundation/mongo-contract/src/contract-schema.ts +++ b/packages/2-mongo-family/1-foundation/mongo-contract/src/contract-schema.ts @@ -281,6 +281,7 @@ const MongoIndexKeySchema = type({ const MongoStorageIndexSchema = type({ '+': 'reject', 'kind?': "'mongo-index'", + name: 'string > 0', keys: MongoIndexKeySchema.array().atLeastLength(1), 'unique?': 'boolean', 'sparse?': 'boolean', diff --git a/packages/2-mongo-family/1-foundation/mongo-contract/src/default-index-name.ts b/packages/2-mongo-family/1-foundation/mongo-contract/src/default-index-name.ts new file mode 100644 index 000000000000..390dfd295d35 --- /dev/null +++ b/packages/2-mongo-family/1-foundation/mongo-contract/src/default-index-name.ts @@ -0,0 +1,6 @@ +import type { MongoIndexKey } from './contract-types'; + +/** The name MongoDB gives an index created without one: each key's field and direction, joined by `_`, such as `email_1` or `title_text`. */ +export function defaultMongoIndexName(keys: ReadonlyArray): string { + return keys.map((k) => `${k.field}_${k.direction}`).join('_'); +} diff --git a/packages/2-mongo-family/1-foundation/mongo-contract/src/exports/index.ts b/packages/2-mongo-family/1-foundation/mongo-contract/src/exports/index.ts index 0d8b1267a839..500b38e6f821 100644 --- a/packages/2-mongo-family/1-foundation/mongo-contract/src/exports/index.ts +++ b/packages/2-mongo-family/1-foundation/mongo-contract/src/exports/index.ts @@ -57,6 +57,7 @@ export type { } from '../contract-types'; export type { MongoContractAccessors, MongoContractView } from '../contract-view'; export { buildMongoContractView } from '../contract-view'; +export { defaultMongoIndexName } from '../default-index-name'; export { defaultMongoDomainNamespaceId, defaultMongoStorageNamespaceId, diff --git a/packages/2-mongo-family/1-foundation/mongo-contract/src/index-lookup-key.ts b/packages/2-mongo-family/1-foundation/mongo-contract/src/index-lookup-key.ts index c32971c4d4b8..c27ff316f978 100644 --- a/packages/2-mongo-family/1-foundation/mongo-contract/src/index-lookup-key.ts +++ b/packages/2-mongo-family/1-foundation/mongo-contract/src/index-lookup-key.ts @@ -15,8 +15,10 @@ export function listsEveryOption