@prisma/orm-family-mongo 8.0.0-rc.2-dev.3 → 8.0.0-rc.20-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -5
- package/dist/authoring-entity-types-UA5sY_Xm-DeYf_cYq.mjs +87 -0
- package/dist/authoring-entity-types-UA5sY_Xm-DeYf_cYq.mjs.map +1 -0
- package/dist/{canonicalization-hooks-DF3Z6sjO.mjs → canonicalization-hooks-CRVM-Kqh-Qi-VmEVg.mjs} +4 -3
- package/dist/canonicalization-hooks-CRVM-Kqh-Qi-VmEVg.mjs.map +1 -0
- package/dist/codec.d.mts +1 -1
- package/dist/codec.mjs +1 -1
- package/dist/{config-types-CFDf9ivE.mjs → config-types-DYTCUpAs.mjs} +5 -5
- package/dist/config-types-DYTCUpAs.mjs.map +1 -0
- package/dist/contract-builder-BHzQQk70.mjs +965 -0
- package/dist/contract-builder-BHzQQk70.mjs.map +1 -0
- package/dist/{contract-builder-DB8nguDE.d.mts → contract-builder-ClL-xMK2.d.mts} +271 -89
- package/dist/contract-builder-ClL-xMK2.d.mts.map +1 -0
- package/dist/contract-prisma6__provider.d.mts +35 -0
- package/dist/contract-prisma6__provider.d.mts.map +1 -0
- package/dist/contract-prisma6__provider.mjs +1202 -0
- package/dist/contract-prisma6__provider.mjs.map +1 -0
- package/dist/contract-psl.d.mts +152 -28
- package/dist/contract-psl.d.mts.map +1 -1
- package/dist/contract-psl.mjs +3 -2
- package/dist/contract-psl__provider.mjs +74 -44
- package/dist/contract-psl__provider.mjs.map +1 -1
- package/dist/contract-ts.d.mts +2 -2
- package/dist/contract-ts.mjs +2 -2
- package/dist/contract-ts__config-types.mjs +1 -1
- package/dist/contract-ts__contract-builder.d.mts +2 -2
- package/dist/contract-ts__contract-builder.mjs +1 -1
- package/dist/contract.d.mts +3 -3
- package/dist/contract.mjs +3 -3
- package/dist/contract__canonicalization-hooks.mjs +1 -1
- package/dist/contract__data-type.d.mts +37 -0
- package/dist/contract__data-type.d.mts.map +1 -0
- package/dist/contract__data-type.mjs +2 -0
- package/dist/contract__entity-kinds.d.mts +1 -1
- package/dist/contract__entity-kinds.mjs +1 -1
- package/dist/{control-C7-kthr1.d.mts → control-4pC8N2Rb.d.mts} +32 -19
- package/dist/control-4pC8N2Rb.d.mts.map +1 -0
- package/dist/{control-CClR5JMr.mjs → control-BQMBG11d.mjs} +19 -2
- package/dist/control-BQMBG11d.mjs.map +1 -0
- package/dist/{control-BbZQqmxo.mjs → control-B_pPN58L.mjs} +195 -87
- package/dist/control-B_pPN58L.mjs.map +1 -0
- package/dist/{control-Cj81sPbj.d.mts → control-CvQSMuxa.d.mts} +29 -6
- package/dist/control-CvQSMuxa.d.mts.map +1 -0
- package/dist/{control-adapter-Db5pT77b.d.mts → control-adapter-Bh_ZraGM--5JDb99k.d.mts} +48 -4
- package/dist/control-adapter-Bh_ZraGM--5JDb99k.d.mts.map +1 -0
- package/dist/control-adapter-CndDiTXW.d.mts +1 -0
- package/dist/dist-B8f-pfcT.mjs +1031 -0
- package/dist/dist-B8f-pfcT.mjs.map +1 -0
- package/dist/dist-Bgk36iLI.mjs +53 -0
- package/dist/dist-Bgk36iLI.mjs.map +1 -0
- package/dist/{dist-C7Ykq48Q.mjs → dist-CO2arS1K.mjs} +3 -1
- package/dist/dist-CO2arS1K.mjs.map +1 -0
- package/dist/{dist-Dyp05u64.mjs → dist-gmGbjhmk.mjs} +56 -32
- package/dist/dist-gmGbjhmk.mjs.map +1 -0
- package/dist/dist-xk_0xOR-.mjs +28 -0
- package/dist/dist-xk_0xOR-.mjs.map +1 -0
- package/dist/emitter.d.mts +2 -4
- package/dist/emitter.d.mts.map +1 -1
- package/dist/emitter.mjs +1 -1
- package/dist/{entity-kinds-B4KNTF8z-DPIuUuuB.mjs → entity-kinds-BQBtfVet-B-Px7NHp.mjs} +35 -18
- package/dist/entity-kinds-BQBtfVet-B-Px7NHp.mjs.map +1 -0
- package/dist/{execution-D5XyZ5XS.mjs → execution-CgP1Sdbr.mjs} +6 -3
- package/dist/execution-CgP1Sdbr.mjs.map +1 -0
- package/dist/{execution-CKnUiOfm.d.mts → execution-tPmN5pge.d.mts} +6 -2
- package/dist/execution-tPmN5pge.d.mts.map +1 -0
- package/dist/{exports-Bx-hlnZ3.mjs → exports-BAimNKOs.mjs} +31 -21
- package/dist/exports-BAimNKOs.mjs.map +1 -0
- package/dist/exports-BHQVApAg.mjs +86 -0
- package/dist/exports-BHQVApAg.mjs.map +1 -0
- package/dist/family.d.mts +11 -10
- package/dist/family.mjs +10 -9
- package/dist/family__control-adapter.d.mts +3 -2
- package/dist/family__control.d.mts +2 -2
- package/dist/family__control.mjs +3 -3
- package/dist/family__ir.d.mts +2 -2
- package/dist/family__ir.mjs +3 -3
- package/dist/family__migration.d.mts +1 -1
- package/dist/family__migration.mjs +1 -1
- package/dist/family__pack.d.mts +1 -1
- package/dist/family__pack.mjs +4 -2
- package/dist/family__pack.mjs.map +1 -1
- package/dist/family__runtime.d.mts +3 -3
- package/dist/family__runtime.mjs +3 -2
- package/dist/family__schema-verify.d.mts +1 -1
- package/dist/family__schema-verify.mjs +1 -1
- package/dist/{field-accessor-0oUt6RZC-B_Z30uAA.mjs → field-accessor-0oUt6RZC-CrJVzQiS.mjs} +2 -2
- package/dist/{field-accessor-0oUt6RZC-B_Z30uAA.mjs.map → field-accessor-0oUt6RZC-CrJVzQiS.mjs.map} +1 -1
- package/dist/{field-accessor-DHsAPiW3-BdYCspQC.d.mts → field-accessor-CmxCw9xP-C6jMngbK.d.mts} +35 -24
- package/dist/field-accessor-CmxCw9xP-C6jMngbK.d.mts.map +1 -0
- package/dist/index-9DDQlC5U.d.mts +87 -0
- package/dist/index-9DDQlC5U.d.mts.map +1 -0
- package/dist/{index-BR0ue13b.d.mts → index-BdXzdXGE.d.mts} +14 -8
- package/dist/index-BdXzdXGE.d.mts.map +1 -0
- package/dist/index-BhIiYIXu.d.mts +845 -0
- package/dist/index-BhIiYIXu.d.mts.map +1 -0
- package/dist/index-CQG5l2o9.d.mts +67 -0
- package/dist/index-CQG5l2o9.d.mts.map +1 -0
- package/dist/{index-DAOkcTCK.d.mts → index-FeVOOdZ0.d.mts} +9 -8
- package/dist/index-FeVOOdZ0.d.mts.map +1 -0
- package/dist/index-YY1SU_7o.d.mts +366 -0
- package/dist/index-YY1SU_7o.d.mts.map +1 -0
- package/dist/{index-DxoO-ywI.d.mts → index-rANtsIZG.d.mts} +9 -5
- package/dist/{index-DxoO-ywI.d.mts.map → index-rANtsIZG.d.mts.map} +1 -1
- package/dist/interpreter-BfHdPd7T-DGqi2_Um.mjs +2186 -0
- package/dist/interpreter-BfHdPd7T-DGqi2_Um.mjs.map +1 -0
- package/dist/{ir-CQrenTYt.d.mts → ir-BLC0t6_x.d.mts} +5 -27
- package/dist/ir-BLC0t6_x.d.mts.map +1 -0
- package/dist/{ir-Ch2aPr7a.mjs → ir-DGm0HXbP.mjs} +3 -8
- package/dist/ir-DGm0HXbP.mjs.map +1 -0
- package/dist/lowering.d.mts +1 -1
- package/dist/{migration-dcM7u4HG.mjs → migration-DnQ7_A_B.mjs} +4 -4
- package/dist/migration-DnQ7_A_B.mjs.map +1 -0
- package/dist/{migration-CNDQv5yB.d.mts → migration-YQVmgFU8.d.mts} +7 -7
- package/dist/{migration-CNDQv5yB.d.mts.map → migration-YQVmgFU8.d.mts.map} +1 -1
- package/dist/{mongo-contract-serializer-Cx7Fae8e-C8ZYPXpc.mjs → mongo-contract-serializer-Zx1rvil3-BywiKCpn.mjs} +27 -8
- package/dist/mongo-contract-serializer-Zx1rvil3-BywiKCpn.mjs.map +1 -0
- package/dist/{mongo-contract-view-AnejqfrQ-BaCFT0xm.d.mts → mongo-contract-view-AnejqfrQ-Wj_ulq2L.d.mts} +3 -3
- package/dist/{mongo-contract-view-AnejqfrQ-BaCFT0xm.d.mts.map → mongo-contract-view-AnejqfrQ-Wj_ulq2L.d.mts.map} +1 -1
- package/dist/{mongo-contract-view-rcWzby6f-wRBCUnBt.mjs → mongo-contract-view-D5yu2LrY-DCAZYJ4q.mjs} +4 -4
- package/dist/{mongo-contract-view-rcWzby6f-wRBCUnBt.mjs.map → mongo-contract-view-D5yu2LrY-DCAZYJ4q.mjs.map} +1 -1
- package/dist/mongo-data-type-DzyzU4LF-C1ydFXgE.mjs +53 -0
- package/dist/mongo-data-type-DzyzU4LF-C1ydFXgE.mjs.map +1 -0
- package/dist/{mongo-value-set-tNn9-pun-dJYx_rVD.d.mts → mongo-value-set-DEd7WLCT-B2Ar2GkJ.d.mts} +20 -4
- package/dist/mongo-value-set-DEd7WLCT-B2Ar2GkJ.d.mts.map +1 -0
- package/dist/orm.d.mts +154 -96
- package/dist/orm.d.mts.map +1 -1
- package/dist/orm.mjs +670 -148
- package/dist/orm.mjs.map +1 -1
- package/dist/pack-qw77Jt2G.d.mts +58 -0
- package/dist/pack-qw77Jt2G.d.mts.map +1 -0
- package/dist/query-ast.d.mts +5 -5
- package/dist/query-ast.mjs +3 -3
- package/dist/query-ast__control.d.mts +4 -4
- package/dist/query-ast__control.mjs +2 -2
- package/dist/query-ast__execution.d.mts +2 -2
- package/dist/query-ast__execution.mjs +1 -1
- package/dist/query-builder.d.mts +4 -836
- package/dist/query-builder.mjs +2 -2
- package/dist/query-builder__contract-free.d.mts +6 -6
- package/dist/query-builder__contract-free.mjs +3 -3
- package/dist/{query-plan-C0-Yu8hf-DdilEdW6.d.mts → query-plan-3fs1HokF-CrNsr-Wx.d.mts} +10 -4
- package/dist/{query-plan-C0-Yu8hf-DdilEdW6.d.mts.map → query-plan-3fs1HokF-CrNsr-Wx.d.mts.map} +1 -1
- package/dist/runtime-B5fNQHQZ.mjs +16 -0
- package/dist/runtime-B5fNQHQZ.mjs.map +1 -0
- package/dist/runtime-yZA30qM2.d.mts +11 -0
- package/dist/runtime-yZA30qM2.d.mts.map +1 -0
- package/dist/runtime.d.mts +74 -87
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +133 -67
- package/dist/runtime.mjs.map +1 -1
- package/dist/schema-ir.d.mts +2 -2
- package/dist/schema-ir.mjs +2 -2
- package/dist/{schema-verify-DJGr28XW.d.mts → schema-verify-CVOG6EZx.d.mts} +5 -5
- package/dist/{schema-verify-DJGr28XW.d.mts.map → schema-verify-CVOG6EZx.d.mts.map} +1 -1
- package/dist/value.d.mts +2 -2
- package/dist/value.mjs +1 -1
- package/dist/{verify-mongo-schema-De0FG2Rm-CCzwnNPY.mjs → verify-mongo-schema-CeQP5N4k-CNOctppM.mjs} +9 -26
- package/dist/verify-mongo-schema-CeQP5N4k-CNOctppM.mjs.map +1 -0
- package/dist/wire.d.mts +3 -3
- package/dist/wire.mjs +14 -2
- package/dist/wire.mjs.map +1 -1
- package/package.json +24 -21
- package/dist/authoring-entity-types-BGtkMyoN-D32kzx28.mjs +0 -176
- package/dist/authoring-entity-types-BGtkMyoN-D32kzx28.mjs.map +0 -1
- package/dist/canonicalization-hooks-DF3Z6sjO.mjs.map +0 -1
- package/dist/config-types-CFDf9ivE.mjs.map +0 -1
- package/dist/contract-builder-BFq0gOMV.mjs +0 -634
- package/dist/contract-builder-BFq0gOMV.mjs.map +0 -1
- package/dist/contract-builder-DB8nguDE.d.mts.map +0 -1
- package/dist/control-BbZQqmxo.mjs.map +0 -1
- package/dist/control-C7-kthr1.d.mts.map +0 -1
- package/dist/control-CClR5JMr.mjs.map +0 -1
- package/dist/control-Cj81sPbj.d.mts.map +0 -1
- package/dist/control-adapter-Db5pT77b.d.mts.map +0 -1
- package/dist/dist-C7Ykq48Q.mjs.map +0 -1
- package/dist/dist-Czwqx_i3.mjs +0 -58
- package/dist/dist-Czwqx_i3.mjs.map +0 -1
- package/dist/dist-DHrEJnhK.mjs +0 -236
- package/dist/dist-DHrEJnhK.mjs.map +0 -1
- package/dist/dist-Dyp05u64.mjs.map +0 -1
- package/dist/entity-kinds-B4KNTF8z-DPIuUuuB.mjs.map +0 -1
- package/dist/execution-CKnUiOfm.d.mts.map +0 -1
- package/dist/execution-D5XyZ5XS.mjs.map +0 -1
- package/dist/exports-Bx-hlnZ3.mjs.map +0 -1
- package/dist/exports-C4RGBGzZ.mjs +0 -156
- package/dist/exports-C4RGBGzZ.mjs.map +0 -1
- package/dist/field-accessor-DHsAPiW3-BdYCspQC.d.mts.map +0 -1
- package/dist/index-BR0ue13b.d.mts.map +0 -1
- package/dist/index-Cd2zLiU6.d.mts +0 -128
- package/dist/index-Cd2zLiU6.d.mts.map +0 -1
- package/dist/index-DAOkcTCK.d.mts.map +0 -1
- package/dist/index-Dv2PNMiG.d.mts +0 -53
- package/dist/index-Dv2PNMiG.d.mts.map +0 -1
- package/dist/index-wKMm41HC.d.mts +0 -30
- package/dist/index-wKMm41HC.d.mts.map +0 -1
- package/dist/interpreter-BxbUTQ3k-ClR98Ned.mjs +0 -1091
- package/dist/interpreter-BxbUTQ3k-ClR98Ned.mjs.map +0 -1
- package/dist/ir-CQrenTYt.d.mts.map +0 -1
- package/dist/ir-Ch2aPr7a.mjs.map +0 -1
- package/dist/migration-dcM7u4HG.mjs.map +0 -1
- package/dist/mongo-contract-serializer-Cx7Fae8e-C8ZYPXpc.mjs.map +0 -1
- package/dist/mongo-value-set-tNn9-pun-dJYx_rVD.d.mts.map +0 -1
- package/dist/pack-D9aLY50F.d.mts +0 -44
- package/dist/pack-D9aLY50F.d.mts.map +0 -1
- package/dist/query-builder.d.mts.map +0 -1
- package/dist/runtime-DPkRW4iu.d.mts +0 -1
- package/dist/verify-mongo-schema-De0FG2Rm-CCzwnNPY.mjs.map +0 -1
|
@@ -0,0 +1,1202 @@
|
|
|
1
|
+
import { o as MongoIndex } from "./entity-kinds-BQBtfVet-B-Px7NHp.mjs";
|
|
2
|
+
import { N as validateMongoStorage, u as buildMongoStorage, w as mongoValueSetsOf } from "./dist-B8f-pfcT.mjs";
|
|
3
|
+
import { i as pairMongoBackRelations } from "./interpreter-BfHdPd7T-DGqi2_Um.mjs";
|
|
4
|
+
import { isStructuredError } from "@prisma/orm-framework/utils/structured-error";
|
|
5
|
+
import { blindCast } from "@prisma/orm-framework/utils/casts";
|
|
6
|
+
import { crossRef } from "@prisma/orm-framework/contract/types";
|
|
7
|
+
import { buildExecutionSection, computeProfileHash } from "@prisma/orm-framework/contract/hashing";
|
|
8
|
+
import { InternalError } from "@prisma/orm-framework/utils/internal-error";
|
|
9
|
+
import { readFile, readdir, stat } from "node:fs/promises";
|
|
10
|
+
import { applySpecifierDefaultControlPolicy } from "@prisma/orm-framework/contract/apply-specifier-default-control-policy";
|
|
11
|
+
import { validateContractDomain } from "@prisma/orm-framework/contract/validate-domain";
|
|
12
|
+
import { ArrayLiteralAst, FunctionCallAst, IdentifierAst, PathExprAst, StringLiteralExprAst, dottedPathsIn, parse, printSyntax } from "@prisma/orm-framework/psl-parser/syntax";
|
|
13
|
+
import { notOk, ok } from "@prisma/orm-framework/utils/result";
|
|
14
|
+
import { basename, dirname, extname, join, normalize } from "pathe";
|
|
15
|
+
import { resolveToOneRelationNullable } from "@prisma/orm-framework/contract-authoring";
|
|
16
|
+
import { encodeEnumMembers, enumMemberProblemDiagnostic, instantiateAuthoringEntityType, isAuthoringEntityTypeDescriptor } from "@prisma/orm-framework/components/authoring";
|
|
17
|
+
import { buildSymbolTable, keywordPslSpan, mapPslDiagnostics, nodePslSpan, readResolvedAttribute } from "@prisma/orm-framework/psl-parser";
|
|
18
|
+
import { fkRelationPairKey } from "@prisma/orm-framework/psl-parser/interpret";
|
|
19
|
+
import { ifDefined } from "@prisma/orm-framework/utils/defined";
|
|
20
|
+
//#region ../../../2-mongo-family/2-authoring/contract-prisma6/dist/provider.mjs
|
|
21
|
+
function prisma6Diagnostic(code, message, sourceId, span) {
|
|
22
|
+
return {
|
|
23
|
+
code,
|
|
24
|
+
message,
|
|
25
|
+
sourceId,
|
|
26
|
+
...span !== void 0 ? { span } : {}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function unsupported(attribute, what, span, ctx) {
|
|
30
|
+
ctx.diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_INDEX_ARGUMENT_UNSUPPORTED", `${ctx.owner}: ${ctx.prefix}${attribute.name} ${what}`, ctx.sourceId, span));
|
|
31
|
+
}
|
|
32
|
+
function sortDirection(expression) {
|
|
33
|
+
if (expression === void 0) return void 0;
|
|
34
|
+
const token = IdentifierAst.cast(expression.syntax)?.name();
|
|
35
|
+
return token === "Asc" ? 1 : token === "Desc" ? -1 : void 0;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Reads `sort:` from one index element's or `@unique`'s arguments. `length:` and every other argument are refused: a MongoDB index has no prefix length, and Prisma 6 accepts no other argument there on MongoDB.
|
|
39
|
+
*/
|
|
40
|
+
function readSort(attribute, args, ctx) {
|
|
41
|
+
let direction;
|
|
42
|
+
for (const arg of args) {
|
|
43
|
+
const key = arg.name()?.name();
|
|
44
|
+
const span = nodePslSpan(arg.syntax, ctx.sources);
|
|
45
|
+
if (key !== "sort") return unsupported(attribute, key === "length" ? "argument \"length\" is not supported: a MongoDB index has no prefix length. Remove it; Prisma 6 ignores it on MongoDB." : `argument "${key ?? ""}" is not supported.`, span, ctx);
|
|
46
|
+
direction = sortDirection(arg.value());
|
|
47
|
+
if (direction === void 0) return unsupported(attribute, "sort must be Asc or Desc.", span, ctx);
|
|
48
|
+
}
|
|
49
|
+
return { direction };
|
|
50
|
+
}
|
|
51
|
+
function readFields(attribute, expression, span, ctx) {
|
|
52
|
+
const array = expression === void 0 ? void 0 : ArrayLiteralAst.cast(expression.syntax);
|
|
53
|
+
if (array === void 0) return unsupported(attribute, "expects a list of field names.", span, ctx);
|
|
54
|
+
const fields = [];
|
|
55
|
+
for (const element of array.elements()) {
|
|
56
|
+
const name = IdentifierAst.cast(element.syntax)?.name();
|
|
57
|
+
if (name !== void 0) {
|
|
58
|
+
fields.push({
|
|
59
|
+
name,
|
|
60
|
+
direction: void 0
|
|
61
|
+
});
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const call = FunctionCallAst.cast(element.syntax);
|
|
65
|
+
const path = PathExprAst.cast(element.syntax)?.path() ?? call?.path() ?? [];
|
|
66
|
+
const [callee] = path;
|
|
67
|
+
if (path.length > 1 && (callee === void 0 || !ctx.compositeFields.has(callee))) return unsupported(attribute, `lists the dotted path "${path.join(".")}", but "${callee ?? ""}" is not a composite-type field of the model, and Prisma 6 refuses the path as an unknown field. List fields of the model by name.`, nodePslSpan(element.syntax, ctx.sources), ctx);
|
|
68
|
+
if (path.length > 1) {
|
|
69
|
+
ctx.diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_COMPOSITE_INDEX_PATH_UNSUPPORTED", `Index path "${path.join(".")}" reaches into a composite type; indexes on composite-type fields are not supported yet. Index a top-level field or remove the index. Either change also reaches the Prisma 6 app, whose \`db push\` builds its indexes from this schema.`, ctx.sourceId, nodePslSpan(element.syntax, ctx.sources)));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (call === void 0 || callee === void 0) return unsupported(attribute, "expects a list of field names.", nodePslSpan(element.syntax, ctx.sources), ctx);
|
|
73
|
+
const sort = readSort(attribute, call.args(), ctx);
|
|
74
|
+
if (sort === void 0) return void 0;
|
|
75
|
+
fields.push({
|
|
76
|
+
name: callee,
|
|
77
|
+
direction: sort.direction
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return fields;
|
|
81
|
+
}
|
|
82
|
+
/** Reads `@@index`, `@@unique` or `@@fulltext`. `map:` and `name:` are dropped: MongoDB verify never compares index names. */
|
|
83
|
+
function parseIndexAttribute(attribute, ctx) {
|
|
84
|
+
let fields;
|
|
85
|
+
for (const arg of attribute.args) {
|
|
86
|
+
const key = arg.kind === "positional" ? "fields" : arg.name;
|
|
87
|
+
if (key === "map" || key === "name") continue;
|
|
88
|
+
if (key !== "fields") return unsupported(attribute, `argument "${key ?? ""}" is not supported.`, arg.span, ctx);
|
|
89
|
+
fields = readFields(attribute, arg.expression, arg.span, ctx);
|
|
90
|
+
if (fields === void 0) return void 0;
|
|
91
|
+
}
|
|
92
|
+
if (fields === void 0 || fields.length === 0) return unsupported(attribute, "expects a list of field names.", attribute.span, ctx);
|
|
93
|
+
return {
|
|
94
|
+
kind: attribute.name,
|
|
95
|
+
fields,
|
|
96
|
+
span: attribute.span
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/** Reads a field's `@unique`: `sort:` sets the key direction; `map:` and `name:` are dropped. */
|
|
100
|
+
function parseFieldUnique(attribute, fieldName, ctx) {
|
|
101
|
+
let direction;
|
|
102
|
+
for (const arg of attribute.args) {
|
|
103
|
+
const key = arg.kind === "positional" ? void 0 : arg.name;
|
|
104
|
+
if (key === "map" || key === "name") continue;
|
|
105
|
+
if (key === "sort") {
|
|
106
|
+
direction = sortDirection(arg.expression);
|
|
107
|
+
if (direction === void 0) return unsupported(attribute, "sort must be Asc or Desc.", arg.span, ctx);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
return unsupported(attribute, key === "length" ? "argument \"length\" is not supported: a MongoDB index has no prefix length. Remove it; Prisma 6 ignores it on MongoDB." : `argument "${key ?? ""}" is not supported.`, arg.span, ctx);
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
kind: "unique",
|
|
114
|
+
fields: [{
|
|
115
|
+
name: fieldName,
|
|
116
|
+
direction
|
|
117
|
+
}],
|
|
118
|
+
span: attribute.span
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const SUMMARY = "Prisma 6 MongoDB schema interpretation failed";
|
|
122
|
+
function stringArgument(attribute) {
|
|
123
|
+
const expression = (attribute.args.find((arg) => arg.kind === "positional") ?? attribute.args.find((arg) => arg.name === "name"))?.expression;
|
|
124
|
+
return expression === void 0 ? void 0 : StringLiteralExprAst.cast(expression.syntax)?.value();
|
|
125
|
+
}
|
|
126
|
+
function requireString(attribute, owner, sourceId, diagnostics) {
|
|
127
|
+
const value = stringArgument(attribute);
|
|
128
|
+
if (value === void 0) diagnostics.push({
|
|
129
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
130
|
+
message: `${owner}: attribute "@${attribute.name}" expects one string argument.`,
|
|
131
|
+
sourceId,
|
|
132
|
+
span: attribute.span
|
|
133
|
+
});
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
function attributeText(attribute) {
|
|
137
|
+
const args = attribute.args.map((arg) => arg.kind === "named" ? `${arg.name}: ${arg.value}` : arg.value);
|
|
138
|
+
return args.length === 0 ? `@${attribute.name}` : `@${attribute.name}(${args.join(", ")})`;
|
|
139
|
+
}
|
|
140
|
+
/** `auto()` and `now()` with no arguments; any other `@default` value is `other`. */
|
|
141
|
+
function defaultKind(attribute) {
|
|
142
|
+
const expression = attribute.args.find((arg) => arg.kind === "positional")?.expression;
|
|
143
|
+
const call = expression === void 0 ? void 0 : FunctionCallAst.cast(expression.syntax);
|
|
144
|
+
if (call === void 0 || [...call.args()].length > 0) return "other";
|
|
145
|
+
const path = call.path().join(".");
|
|
146
|
+
return path === "auto" ? "auto" : path === "now" ? "now" : "other";
|
|
147
|
+
}
|
|
148
|
+
function unknownAttribute(owner, attribute, prefix, sourceId) {
|
|
149
|
+
return prisma6Diagnostic("PSL.PRISMA6_MONGO_UNKNOWN_ATTRIBUTE", `${owner}: attribute "${prefix}${attribute.name}" is not supported by the Prisma 6 MongoDB contract source.`, sourceId, attribute.span);
|
|
150
|
+
}
|
|
151
|
+
function interpretPrisma6Documents(input) {
|
|
152
|
+
const { binding } = input;
|
|
153
|
+
const diagnostics = [...input.seedDiagnostics];
|
|
154
|
+
const datasources = [];
|
|
155
|
+
const enumBlocks = [];
|
|
156
|
+
const compositeTypes = [];
|
|
157
|
+
const models = [];
|
|
158
|
+
const ignoredModels = /* @__PURE__ */ new Set();
|
|
159
|
+
const declaredNames = /* @__PURE__ */ new Map();
|
|
160
|
+
const claimName = (kind, name, sourceId, span) => {
|
|
161
|
+
const previous = declaredNames.get(name);
|
|
162
|
+
if (previous === void 0) {
|
|
163
|
+
declaredNames.set(name, sourceId);
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
diagnostics.push({
|
|
167
|
+
code: "PSL_DUPLICATE_DECLARATION",
|
|
168
|
+
message: `Duplicate declaration of ${kind} "${name}"; first declared in ${basename(previous)}.`,
|
|
169
|
+
sourceId,
|
|
170
|
+
span
|
|
171
|
+
});
|
|
172
|
+
return false;
|
|
173
|
+
};
|
|
174
|
+
for (const { document, sources, sourceFile, sourceId } of input.documents) {
|
|
175
|
+
const { symbolTable, diagnostics: tableDiagnostics } = buildSymbolTable({
|
|
176
|
+
documents: [document],
|
|
177
|
+
sources,
|
|
178
|
+
defaultNamespaceId: input.defaultNamespaceId
|
|
179
|
+
});
|
|
180
|
+
for (const diagnostic of tableDiagnostics) diagnostics.push({
|
|
181
|
+
code: diagnostic.code,
|
|
182
|
+
message: diagnostic.message,
|
|
183
|
+
sourceId,
|
|
184
|
+
span: sourceFile.rangeToPslSpan(diagnostic.range)
|
|
185
|
+
});
|
|
186
|
+
const unsupported = (keyword, span) => {
|
|
187
|
+
diagnostics.push({
|
|
188
|
+
code: "PSL_UNSUPPORTED_TOP_LEVEL_BLOCK",
|
|
189
|
+
message: `Unsupported top-level block "${keyword}"`,
|
|
190
|
+
sourceId,
|
|
191
|
+
span
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
const unsupportedInclusions = (code, holders) => {
|
|
195
|
+
for (const holder of Object.values(holders)) for (const inclusion of holder.node.inclusions()) diagnostics.push({
|
|
196
|
+
code,
|
|
197
|
+
message: `Unsupported mixin inclusion "${printSyntax(inclusion.syntax).trim()}"`,
|
|
198
|
+
sourceId,
|
|
199
|
+
span: nodePslSpan(inclusion.syntax, sources)
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
for (const block of Object.values(symbolTable.defaultNamespace.blocks)) switch (block.keyword) {
|
|
203
|
+
case "datasource":
|
|
204
|
+
datasources.push({
|
|
205
|
+
symbol: block,
|
|
206
|
+
sourceId,
|
|
207
|
+
sources
|
|
208
|
+
});
|
|
209
|
+
reportDottedBlockValues(block, sourceId, sources, diagnostics);
|
|
210
|
+
break;
|
|
211
|
+
case "generator":
|
|
212
|
+
reportDottedBlockValues(block, sourceId, sources, diagnostics);
|
|
213
|
+
break;
|
|
214
|
+
case "enum":
|
|
215
|
+
if (claimName("enum", block.name, sourceId, block.span)) enumBlocks.push({
|
|
216
|
+
symbol: block,
|
|
217
|
+
sourceId,
|
|
218
|
+
sources
|
|
219
|
+
});
|
|
220
|
+
break;
|
|
221
|
+
case "view":
|
|
222
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_VIEW_UNSUPPORTED", `View "${block.name}" is not supported; Prisma 8 has no views on MongoDB. Remove the view from the schema this contract source reads. The Prisma 6 client then loses the view's model too.`, sourceId, keywordPslSpan(block.node.syntax, block.keyword, sources)));
|
|
223
|
+
break;
|
|
224
|
+
default: unsupported(block.keyword, keywordPslSpan(block.node.syntax, block.keyword, sources));
|
|
225
|
+
}
|
|
226
|
+
for (const namespace of Object.values(symbolTable.namespaces)) for (const { span } of namespace.declarations) unsupported("namespace", span);
|
|
227
|
+
for (const namedType of Object.values(symbolTable.namedTypes)) unsupported("types", namedType.span);
|
|
228
|
+
for (const mixin of Object.values(symbolTable.defaultNamespace.mixins)) unsupported(`${mixin.keyword} mixin`, mixin.span);
|
|
229
|
+
unsupportedInclusions("PSL_INVALID_MODEL_MEMBER", symbolTable.defaultNamespace.models);
|
|
230
|
+
unsupportedInclusions("PSL_INVALID_MODEL_MEMBER", symbolTable.defaultNamespace.compositeTypes);
|
|
231
|
+
unsupportedInclusions("PSL_INVALID_EXTENSION_BLOCK_MEMBER", symbolTable.defaultNamespace.blocks);
|
|
232
|
+
for (const symbol of Object.values(symbolTable.defaultNamespace.compositeTypes)) if (claimName("type", symbol.name, sourceId, symbol.span)) compositeTypes.push({
|
|
233
|
+
symbol,
|
|
234
|
+
sourceId,
|
|
235
|
+
sources
|
|
236
|
+
});
|
|
237
|
+
for (const symbol of Object.values(symbolTable.defaultNamespace.models)) {
|
|
238
|
+
if (!claimName("model", symbol.name, sourceId, symbol.span)) continue;
|
|
239
|
+
if (symbol.attributes.some((attribute) => attribute.name === "ignore")) ignoredModels.add(symbol.name);
|
|
240
|
+
else models.push({
|
|
241
|
+
symbol,
|
|
242
|
+
sourceId,
|
|
243
|
+
sources
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const providerMismatch = checkDatasource(datasources, input.documents[0]?.sourceId ?? "schema.prisma", binding);
|
|
248
|
+
if (providerMismatch !== void 0) return notOk({
|
|
249
|
+
summary: SUMMARY,
|
|
250
|
+
diagnostics: inSourceOrder([...input.seedDiagnostics, providerMismatch], input.documents)
|
|
251
|
+
});
|
|
252
|
+
const enums = /* @__PURE__ */ new Map();
|
|
253
|
+
for (const located of enumBlocks) {
|
|
254
|
+
const built = buildEnum(located, input, diagnostics);
|
|
255
|
+
if (built !== void 0) enums.set(located.symbol.name, built);
|
|
256
|
+
}
|
|
257
|
+
const modelNames = /* @__PURE__ */ new Set([...models.map((m) => m.symbol.name), ...ignoredModels]);
|
|
258
|
+
const compositeTypeNames = new Set(compositeTypes.map((c) => c.symbol.name));
|
|
259
|
+
const enumNames = new Set(enumBlocks.map((located) => located.symbol.name));
|
|
260
|
+
const typeContext = {
|
|
261
|
+
binding,
|
|
262
|
+
generatorFunctions: input.generatorFunctions,
|
|
263
|
+
enums,
|
|
264
|
+
enumNames,
|
|
265
|
+
compositeTypeNames,
|
|
266
|
+
diagnostics,
|
|
267
|
+
namespaceId: input.defaultNamespaceId
|
|
268
|
+
};
|
|
269
|
+
const valueObjects = {};
|
|
270
|
+
for (const located of compositeTypes) valueObjects[located.symbol.name] = { fields: readCompositeFields(located, typeContext) };
|
|
271
|
+
const builds = /* @__PURE__ */ new Map();
|
|
272
|
+
for (const located of models) builds.set(located.symbol.name, readModel(located, modelNames, ignoredModels, typeContext));
|
|
273
|
+
const foreignKeys = [];
|
|
274
|
+
const invalidFkPairings = [];
|
|
275
|
+
const backRelations = [];
|
|
276
|
+
for (const build of builds.values()) readRelationFields(build, builds, {
|
|
277
|
+
foreignKeys,
|
|
278
|
+
invalidFkPairings,
|
|
279
|
+
backRelations
|
|
280
|
+
}, diagnostics, input.defaultNamespaceId);
|
|
281
|
+
const paired = pairMongoBackRelations({
|
|
282
|
+
foreignKeys,
|
|
283
|
+
candidates: backRelations,
|
|
284
|
+
invalidFkPairings,
|
|
285
|
+
namespaceId: input.defaultNamespaceId
|
|
286
|
+
});
|
|
287
|
+
diagnostics.push(...mapPslDiagnostics(paired.diagnostics, mergedSources(input.documents)));
|
|
288
|
+
for (const { modelName, fieldName, relation } of paired.relations) {
|
|
289
|
+
const build = builds.get(modelName);
|
|
290
|
+
if (build !== void 0) build.relations[fieldName] = relation;
|
|
291
|
+
}
|
|
292
|
+
const collections = {};
|
|
293
|
+
const roots = {};
|
|
294
|
+
const executionDefaults = [];
|
|
295
|
+
for (const [modelName, build] of builds) {
|
|
296
|
+
const indexes = buildIndexes(build, diagnostics);
|
|
297
|
+
const existing = collections[build.collection];
|
|
298
|
+
collections[build.collection] = { indexes: [...existing?.indexes ?? [], ...indexes] };
|
|
299
|
+
roots[build.collection] = crossRef(modelName, input.defaultNamespaceId);
|
|
300
|
+
for (const { field, phases } of build.executionDefaults) executionDefaults.push({
|
|
301
|
+
ref: {
|
|
302
|
+
namespace: input.defaultNamespaceId,
|
|
303
|
+
entry: build.collection,
|
|
304
|
+
field
|
|
305
|
+
},
|
|
306
|
+
...phases
|
|
307
|
+
});
|
|
308
|
+
if (!build.hasId) diagnostics.push({
|
|
309
|
+
code: "PSL_MISSING_ID_FIELD",
|
|
310
|
+
message: `Model "${modelName}" has no field with @id attribute. Every model must have exactly one @id field.`,
|
|
311
|
+
sourceId: build.located.sourceId,
|
|
312
|
+
span: build.located.symbol.span
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
if (diagnostics.length > 0) return notOk({
|
|
316
|
+
summary: SUMMARY,
|
|
317
|
+
diagnostics: inSourceOrder(diagnostics, input.documents)
|
|
318
|
+
});
|
|
319
|
+
return ok(assembleContract({
|
|
320
|
+
binding,
|
|
321
|
+
builds,
|
|
322
|
+
collections,
|
|
323
|
+
roots,
|
|
324
|
+
valueObjects,
|
|
325
|
+
enums,
|
|
326
|
+
executionDefaults,
|
|
327
|
+
namespaceId: input.defaultNamespaceId
|
|
328
|
+
}));
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Diagnostics by file, in the order the schema files were read, then by position; one with no position comes first in its file.
|
|
332
|
+
*/
|
|
333
|
+
function inSourceOrder(diagnostics, documents) {
|
|
334
|
+
const fileOrder = new Map(documents.map((document, index) => [document.sourceId, index]));
|
|
335
|
+
const fileRank = (diagnostic) => fileOrder.get(diagnostic.sourceId) ?? documents.length;
|
|
336
|
+
const offset = (diagnostic) => diagnostic.span?.start.offset ?? -1;
|
|
337
|
+
return [...diagnostics].sort((a, b) => fileRank(a) - fileRank(b) || offset(a) - offset(b));
|
|
338
|
+
}
|
|
339
|
+
/** Prisma 6 accepts no dotted path in a datasource or generator block, though the parser reads one as a value. */
|
|
340
|
+
function reportDottedBlockValues(block, sourceId, sources, diagnostics) {
|
|
341
|
+
for (const entry of block.entries) {
|
|
342
|
+
const value = entry.value();
|
|
343
|
+
if (value === void 0) continue;
|
|
344
|
+
for (const path of dottedPathsIn(value)) diagnostics.push({
|
|
345
|
+
code: "PSL_INVALID_EXTENSION_BLOCK_MEMBER",
|
|
346
|
+
message: `${block.keyword} "${block.name}": the value of "${entry.key()?.name() ?? ""}" holds the dotted path ${path.path().join(".")}, which Prisma 6 does not accept in a ${block.keyword} block.`,
|
|
347
|
+
sourceId,
|
|
348
|
+
span: nodePslSpan(path.syntax, sources)
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/** The provider-mismatch diagnostic, or `undefined` when the schema names a provider the target reads. */
|
|
353
|
+
function checkDatasource(datasources, fallbackSourceId, binding) {
|
|
354
|
+
const [datasource] = datasources;
|
|
355
|
+
const [namedProvider] = binding.providers;
|
|
356
|
+
if (datasource === void 0) return prisma6Diagnostic("PSL.PRISMA6_MONGO_PROVIDER_MISMATCH", `No datasource block found; add \`datasource db { provider = "${namedProvider}" }\`.`, fallbackSourceId, void 0);
|
|
357
|
+
const block = datasource.symbol;
|
|
358
|
+
let parameter;
|
|
359
|
+
for (const entry of block.entries) if (entry.key()?.name() === "provider") {
|
|
360
|
+
parameter = entry;
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
const expression = parameter?.value();
|
|
364
|
+
const provider = expression instanceof StringLiteralExprAst ? expression.value() : void 0;
|
|
365
|
+
if (provider !== void 0 && binding.providers.includes(provider)) return void 0;
|
|
366
|
+
return prisma6Diagnostic("PSL.PRISMA6_MONGO_PROVIDER_MISMATCH", provider === void 0 ? `The datasource block declares no string \`provider\`; this contract source reads Prisma 6 schemas for provider "${namedProvider}".` : `The datasource provider is "${provider}"; this contract source reads Prisma 6 schemas for provider "${namedProvider}".`, datasource.sourceId, parameter === void 0 ? block.span : nodePslSpan(parameter.syntax, datasource.sources));
|
|
367
|
+
}
|
|
368
|
+
function buildEnum(located, input, diagnostics) {
|
|
369
|
+
const { symbol: block, sourceId, sources } = located;
|
|
370
|
+
for (const attribute of block.attributes) {
|
|
371
|
+
if (attribute.name === "map") continue;
|
|
372
|
+
if (attribute.name === "schema") {
|
|
373
|
+
diagnostics.push(schemaUnsupported(`Enum "${block.name}"`, attribute, sourceId));
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
diagnostics.push(unknownAttribute(`Enum "${block.name}"`, attribute, "@@", sourceId));
|
|
377
|
+
}
|
|
378
|
+
const values = Object.create(null);
|
|
379
|
+
const writtenValues = Object.create(null);
|
|
380
|
+
const parameterSpans = Object.create(null);
|
|
381
|
+
for (const entry of block.entries) {
|
|
382
|
+
const name = entry.key()?.name();
|
|
383
|
+
if (name === void 0) continue;
|
|
384
|
+
let value = name;
|
|
385
|
+
for (const attributeNode of entry.attributes()) {
|
|
386
|
+
const attribute = readResolvedAttribute(attributeNode, sources);
|
|
387
|
+
if (attribute.name === "map") value = requireString(attribute, `Enum member "${block.name}.${name}"`, sourceId, diagnostics) ?? value;
|
|
388
|
+
else diagnostics.push(unknownAttribute(`Enum member "${block.name}.${name}"`, attribute, "@", sourceId));
|
|
389
|
+
}
|
|
390
|
+
values[name] = value;
|
|
391
|
+
writtenValues[name] = {
|
|
392
|
+
kind: "string",
|
|
393
|
+
text: value
|
|
394
|
+
};
|
|
395
|
+
parameterSpans[name] = nodePslSpan(entry.syntax, sources);
|
|
396
|
+
}
|
|
397
|
+
const descriptor = input.authoringContributions.entityTypes["enum"];
|
|
398
|
+
if (descriptor === void 0 || !isAuthoringEntityTypeDescriptor(descriptor)) {
|
|
399
|
+
diagnostics.push({
|
|
400
|
+
code: "PSL_ENUM_MISSING_FACTORY",
|
|
401
|
+
message: `enum "${block.name}" requires an "enum" entityType factory in the active authoring contributions`,
|
|
402
|
+
sourceId,
|
|
403
|
+
span: block.span
|
|
404
|
+
});
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
const context = {
|
|
408
|
+
family: input.binding.target.familyId,
|
|
409
|
+
target: input.binding.target.targetId,
|
|
410
|
+
codecLookup: input.codecLookup,
|
|
411
|
+
dataTypes: input.dataTypes,
|
|
412
|
+
sourceId,
|
|
413
|
+
enumInferenceCodecs: {
|
|
414
|
+
text: input.binding.scalarCodecIds.String,
|
|
415
|
+
int: input.binding.scalarCodecIds.Int
|
|
416
|
+
},
|
|
417
|
+
diagnostics: { push: (diagnostic) => {
|
|
418
|
+
diagnostics.push(blindCast(diagnostic));
|
|
419
|
+
} }
|
|
420
|
+
};
|
|
421
|
+
const handle = instantiateAuthoringEntityType("enum", descriptor, [{
|
|
422
|
+
kind: "enum",
|
|
423
|
+
keyword: "enum",
|
|
424
|
+
name: block.name,
|
|
425
|
+
values,
|
|
426
|
+
writtenValues,
|
|
427
|
+
parameterSpans,
|
|
428
|
+
attributes: {},
|
|
429
|
+
span: block.span
|
|
430
|
+
}], context);
|
|
431
|
+
if (handle === void 0 || handle === null) return void 0;
|
|
432
|
+
const encoded = encodeEnumMembers(handle, input.codecLookup);
|
|
433
|
+
if (!encoded.ok) {
|
|
434
|
+
const site = {
|
|
435
|
+
enumName: block.name,
|
|
436
|
+
codecId: handle.codecId,
|
|
437
|
+
sourceId,
|
|
438
|
+
span: block.span,
|
|
439
|
+
memberSpans: parameterSpans
|
|
440
|
+
};
|
|
441
|
+
diagnostics.push(...encoded.failure.map((problem) => enumMemberProblemDiagnostic(problem, site)));
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
return {
|
|
445
|
+
codecId: handle.codecId,
|
|
446
|
+
members: encoded.value
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
function schemaUnsupported(owner, attribute, sourceId) {
|
|
450
|
+
return prisma6Diagnostic("PSL.PRISMA6_MONGO_SCHEMA_UNSUPPORTED", `${owner}: "@@schema" is not supported; a MongoDB contract has one database, bound by the connection string. Remove @@schema.`, sourceId, attribute.span);
|
|
451
|
+
}
|
|
452
|
+
function unsupportedTypeMessage(label, typeName, owner) {
|
|
453
|
+
const base = `${label} has type "${typeName}(...)", which has no Prisma 8 codec, so ${`${owner.kind} "${owner.name}"`} cannot use this contract source while it has the field. Prisma 6 rejects @ignore on an Unsupported field. Removing the field from the schema leaves its stored values in the documents, but the Prisma 6 client no longer reads or writes them.`;
|
|
454
|
+
if (owner.kind === "type") return base;
|
|
455
|
+
return `${base} Adding @@ignore to model "${owner.name}" keeps the model out of the contract, but the model disappears from the Prisma 6 client too, and every relation field in another model that points to it needs @ignore, which removes that field from the Prisma 6 client as well.`;
|
|
456
|
+
}
|
|
457
|
+
/** The native types Prisma 6 accepts on each MongoDB scalar, checked with Prisma 6.19. */
|
|
458
|
+
const PRISMA6_NATIVE_TYPES = {
|
|
459
|
+
String: ["db.String", "db.ObjectId"],
|
|
460
|
+
Boolean: ["db.Bool"],
|
|
461
|
+
Int: ["db.Int", "db.Long"],
|
|
462
|
+
BigInt: ["db.Long"],
|
|
463
|
+
Float: ["db.Double"],
|
|
464
|
+
DateTime: ["db.Date", "db.Timestamp"],
|
|
465
|
+
Bytes: ["db.BinData", "db.ObjectId"],
|
|
466
|
+
Json: ["db.Json"]
|
|
467
|
+
};
|
|
468
|
+
/** The BSON type Prisma 6 stores for each native type. */
|
|
469
|
+
const PRISMA6_NATIVE_TYPE_BSON = {
|
|
470
|
+
"db.String": "string",
|
|
471
|
+
"db.ObjectId": "objectId",
|
|
472
|
+
"db.Bool": "bool",
|
|
473
|
+
"db.Int": "int",
|
|
474
|
+
"db.Long": "long",
|
|
475
|
+
"db.Double": "double",
|
|
476
|
+
"db.Date": "date",
|
|
477
|
+
"db.Timestamp": "timestamp",
|
|
478
|
+
"db.BinData": "binData",
|
|
479
|
+
"db.Json": "object"
|
|
480
|
+
};
|
|
481
|
+
/** The BSON type Prisma 6 stores for each MongoDB scalar that has no native type. `Int` is a long. */
|
|
482
|
+
const PRISMA6_SCALAR_BSON = {
|
|
483
|
+
String: "string",
|
|
484
|
+
Boolean: "bool",
|
|
485
|
+
Int: "long",
|
|
486
|
+
BigInt: "long",
|
|
487
|
+
Float: "double",
|
|
488
|
+
DateTime: "date",
|
|
489
|
+
Bytes: "binData",
|
|
490
|
+
Json: "object"
|
|
491
|
+
};
|
|
492
|
+
function withArticle(typeName) {
|
|
493
|
+
return `${/^[AEIOU]/.test(typeName) ? "an" : "a"} ${typeName}`;
|
|
494
|
+
}
|
|
495
|
+
function acceptedByPrisma6(nativeType, typeName) {
|
|
496
|
+
return (Object.hasOwn(PRISMA6_NATIVE_TYPES, typeName) ? PRISMA6_NATIVE_TYPES[typeName] : void 0)?.includes(nativeType) === true;
|
|
497
|
+
}
|
|
498
|
+
/** Why the reader refuses a native type, and what removing it does to the Prisma 6 app. */
|
|
499
|
+
function nativeTypeRefusal(label, nativeType, typeName) {
|
|
500
|
+
const refused = `${label}: native type "@${nativeType}" is not supported`;
|
|
501
|
+
if (!acceptedByPrisma6(nativeType, typeName)) return `${refused}, and Prisma 6 does not accept it on ${withArticle(typeName)} field either. Remove it.`;
|
|
502
|
+
const declared = PRISMA6_NATIVE_TYPE_BSON[nativeType];
|
|
503
|
+
const plain = PRISMA6_SCALAR_BSON[typeName];
|
|
504
|
+
return `${refused}: Prisma 6 stores it as a BSON ${declared}, and Prisma 8 has no codec for that BSON type. Remove it; this also changes the Prisma 6 app: its client then stores new ${typeName} values as BSON ${plain} instead of ${declared}. Documents already stored keep their ${declared} values, so rewrite them as ${plain}s before Prisma 8 reads them.`;
|
|
505
|
+
}
|
|
506
|
+
function nativeTypeCodecId(binding, typeName, nativeType) {
|
|
507
|
+
const forType = Object.hasOwn(binding.nativeTypeCodecIds, typeName) ? binding.nativeTypeCodecIds[typeName] : void 0;
|
|
508
|
+
return forType !== void 0 && Object.hasOwn(forType, nativeType) ? forType[nativeType] : void 0;
|
|
509
|
+
}
|
|
510
|
+
/** The field's contract type, or `undefined` after reporting why it has none. */
|
|
511
|
+
function resolveFieldType(field, owner, nativeType, sourceId, ctx) {
|
|
512
|
+
const { binding, diagnostics } = ctx;
|
|
513
|
+
const label = `Field "${owner.name}.${field.name}"`;
|
|
514
|
+
if (field.typeConstructor !== void 0) {
|
|
515
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_UNSUPPORTED_TYPE", unsupportedTypeMessage(label, field.typeConstructor.path.join("."), owner), sourceId, field.typeConstructor.span));
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
const nativeTypeUnsupported = (attribute) => {
|
|
519
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_NATIVE_TYPE_UNSUPPORTED", nativeTypeRefusal(label, attribute.name, field.typeName), sourceId, attribute.span));
|
|
520
|
+
};
|
|
521
|
+
const many = { many: field.list ? { elementNullable: false } : false };
|
|
522
|
+
if (ctx.compositeTypeNames.has(field.typeName)) {
|
|
523
|
+
if (nativeType !== void 0) return nativeTypeUnsupported(nativeType);
|
|
524
|
+
return {
|
|
525
|
+
type: {
|
|
526
|
+
kind: "valueObject",
|
|
527
|
+
name: field.typeName
|
|
528
|
+
},
|
|
529
|
+
nullable: field.optional,
|
|
530
|
+
...many
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
const enumBuild = ctx.enums.get(field.typeName);
|
|
534
|
+
if (enumBuild !== void 0) {
|
|
535
|
+
if (nativeType !== void 0) return nativeTypeUnsupported(nativeType);
|
|
536
|
+
const valueSet = {
|
|
537
|
+
plane: "domain",
|
|
538
|
+
entityKind: "enum",
|
|
539
|
+
namespaceId: ctx.namespaceId,
|
|
540
|
+
entityName: field.typeName
|
|
541
|
+
};
|
|
542
|
+
return {
|
|
543
|
+
type: {
|
|
544
|
+
kind: "scalar",
|
|
545
|
+
codecId: enumBuild.codecId
|
|
546
|
+
},
|
|
547
|
+
nullable: field.optional,
|
|
548
|
+
valueSet,
|
|
549
|
+
...many
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
if (ctx.enumNames.has(field.typeName)) return nativeType === void 0 ? void 0 : nativeTypeUnsupported(nativeType);
|
|
553
|
+
const scalarCodecId = Object.hasOwn(binding.scalarCodecIds, field.typeName) ? binding.scalarCodecIds[field.typeName] : void 0;
|
|
554
|
+
if (scalarCodecId === void 0) {
|
|
555
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_UNSUPPORTED_TYPE", `${label} has unknown type "${field.typeName}": it is not a scalar type, an enum, a composite type, or a model. Correct the type name.`, sourceId, field.span));
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
let codecId = scalarCodecId;
|
|
559
|
+
if (nativeType !== void 0) {
|
|
560
|
+
const nativeCodecId = nativeTypeCodecId(binding, field.typeName, nativeType.name);
|
|
561
|
+
if (nativeCodecId === void 0) return nativeTypeUnsupported(nativeType);
|
|
562
|
+
codecId = nativeCodecId;
|
|
563
|
+
}
|
|
564
|
+
return {
|
|
565
|
+
type: {
|
|
566
|
+
kind: "scalar",
|
|
567
|
+
codecId
|
|
568
|
+
},
|
|
569
|
+
nullable: field.optional,
|
|
570
|
+
...many
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
function readCompositeFields(located, ctx) {
|
|
574
|
+
const { symbol, sourceId } = located;
|
|
575
|
+
for (const attribute of symbol.attributes) ctx.diagnostics.push(unknownAttribute(`Type "${symbol.name}"`, attribute, "@@", sourceId));
|
|
576
|
+
const fields = {};
|
|
577
|
+
for (const field of Object.values(symbol.fields)) {
|
|
578
|
+
if (field.malformedType) continue;
|
|
579
|
+
const label = `Field "${symbol.name}.${field.name}"`;
|
|
580
|
+
let nativeType;
|
|
581
|
+
let rejected = false;
|
|
582
|
+
for (const attribute of field.attributes) if (attribute.name.startsWith("db.")) nativeType = attribute;
|
|
583
|
+
else if (attribute.name === "map") {
|
|
584
|
+
ctx.diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_COMPOSITE_MAP_UNSUPPORTED", `${label}: @map on a field of a composite type is not supported yet. The stored field keeps the name "${stringArgument(attribute) ?? field.name}", so removing @map renames it in storage; keep the schema as it is until Prisma 8 supports it.`, sourceId, attribute.span));
|
|
585
|
+
rejected = true;
|
|
586
|
+
} else if (attribute.name === "default") {
|
|
587
|
+
ctx.diagnostics.push(defaultUnsupported(label, attribute, {
|
|
588
|
+
kind: "type",
|
|
589
|
+
name: symbol.name
|
|
590
|
+
}, field, sourceId));
|
|
591
|
+
rejected = true;
|
|
592
|
+
} else {
|
|
593
|
+
ctx.diagnostics.push(unknownAttribute(label, attribute, "@", sourceId));
|
|
594
|
+
rejected = true;
|
|
595
|
+
}
|
|
596
|
+
if (rejected) continue;
|
|
597
|
+
const resolved = resolveFieldType(field, {
|
|
598
|
+
kind: "type",
|
|
599
|
+
name: symbol.name
|
|
600
|
+
}, nativeType, sourceId, ctx);
|
|
601
|
+
if (resolved !== void 0) fields[field.name] = resolved;
|
|
602
|
+
}
|
|
603
|
+
return fields;
|
|
604
|
+
}
|
|
605
|
+
/** What the Prisma 6 app loses when the Prisma 6 client stops filling a default. */
|
|
606
|
+
function defaultRemovalConsequence(owner, field) {
|
|
607
|
+
if (field.optional || field.list) return owner.kind === "model" ? `a Prisma 6 create call that leaves "${field.name}" out no longer gets the default value` : `a "${owner.name}" value written without "${field.name}" no longer gets the default value`;
|
|
608
|
+
return owner.kind === "model" ? `every Prisma 6 create call must then pass "${field.name}"` : `every "${owner.name}" value the Prisma 6 app writes must then include "${field.name}"`;
|
|
609
|
+
}
|
|
610
|
+
function defaultUnsupported(label, attribute, owner, field, sourceId) {
|
|
611
|
+
return prisma6Diagnostic("PSL.PRISMA6_MONGO_DEFAULT_UNSUPPORTED", `${label}: ${attributeText(attribute)} is not supported. MongoDB has no stored defaults, and Prisma 8 fills only \`now()\` on DateTime fields. The Prisma 6 client fills this default today, so removing it also changes the Prisma 6 app: ${defaultRemovalConsequence(owner, field)}. Set the value in the application code that creates documents, then remove the default.`, sourceId, attribute.span);
|
|
612
|
+
}
|
|
613
|
+
function readModel(located, modelNames, ignoredModels, ctx) {
|
|
614
|
+
const { symbol, sourceId, sources } = located;
|
|
615
|
+
const { diagnostics } = ctx;
|
|
616
|
+
const modelLabel = `Model "${symbol.name}"`;
|
|
617
|
+
let collection = symbol.name;
|
|
618
|
+
const build = {
|
|
619
|
+
located,
|
|
620
|
+
collection: symbol.name,
|
|
621
|
+
storedNames: /* @__PURE__ */ new Map(),
|
|
622
|
+
ignoredFields: /* @__PURE__ */ new Set(),
|
|
623
|
+
rejectedFields: /* @__PURE__ */ new Set(),
|
|
624
|
+
fields: {},
|
|
625
|
+
relations: {},
|
|
626
|
+
executionDefaults: [],
|
|
627
|
+
uniqueFields: [],
|
|
628
|
+
modelIndexes: [],
|
|
629
|
+
relationFields: [],
|
|
630
|
+
hasId: false
|
|
631
|
+
};
|
|
632
|
+
const indexContext = {
|
|
633
|
+
owner: modelLabel,
|
|
634
|
+
prefix: "@@",
|
|
635
|
+
sourceId,
|
|
636
|
+
sources,
|
|
637
|
+
diagnostics,
|
|
638
|
+
compositeFields: new Set(Object.values(symbol.fields).filter((field) => ctx.compositeTypeNames.has(field.typeName)).map((field) => field.name))
|
|
639
|
+
};
|
|
640
|
+
for (const attribute of symbol.attributes) switch (attribute.name) {
|
|
641
|
+
case "map":
|
|
642
|
+
collection = requireString(attribute, modelLabel, sourceId, diagnostics) ?? collection;
|
|
643
|
+
break;
|
|
644
|
+
case "index":
|
|
645
|
+
case "unique":
|
|
646
|
+
case "fulltext": {
|
|
647
|
+
const parsed = parseIndexAttribute({
|
|
648
|
+
...attribute,
|
|
649
|
+
name: attribute.name
|
|
650
|
+
}, indexContext);
|
|
651
|
+
if (parsed !== void 0) build.modelIndexes.push(parsed);
|
|
652
|
+
break;
|
|
653
|
+
}
|
|
654
|
+
case "id":
|
|
655
|
+
build.hasId = true;
|
|
656
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_COMPOSITE_ID_UNSUPPORTED", `${modelLabel}: @@id is not supported; a MongoDB document is identified by its "_id" field. Declare the id as \`id String @id @default(auto()) @map("_id") @db.ObjectId\`.`, sourceId, attribute.span));
|
|
657
|
+
break;
|
|
658
|
+
case "schema":
|
|
659
|
+
diagnostics.push(schemaUnsupported(modelLabel, attribute, sourceId));
|
|
660
|
+
break;
|
|
661
|
+
case "ignore": break;
|
|
662
|
+
default: diagnostics.push(unknownAttribute(modelLabel, attribute, "@@", sourceId));
|
|
663
|
+
}
|
|
664
|
+
for (const field of Object.values(symbol.fields)) {
|
|
665
|
+
const reported = diagnostics.length;
|
|
666
|
+
readModelField(field, build, modelNames, ignoredModels, ctx);
|
|
667
|
+
if (diagnostics.length > reported) build.rejectedFields.add(field.name);
|
|
668
|
+
}
|
|
669
|
+
return {
|
|
670
|
+
...build,
|
|
671
|
+
collection
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function readModelField(field, build, modelNames, ignoredModels, ctx) {
|
|
675
|
+
const { symbol, sourceId, sources } = build.located;
|
|
676
|
+
const { diagnostics, binding } = ctx;
|
|
677
|
+
const label = `Field "${symbol.name}.${field.name}"`;
|
|
678
|
+
const isRelationField = modelNames.has(field.typeName) && field.typeConstructor === void 0;
|
|
679
|
+
if (field.attributes.some((attribute) => attribute.name === "ignore")) {
|
|
680
|
+
build.ignoredFields.add(field.name);
|
|
681
|
+
const unique = field.attributes.find((attribute) => attribute.name === "unique");
|
|
682
|
+
if (unique !== void 0) diagnostics.push(ignoredFieldReferenced(symbol.name, [field.name], {
|
|
683
|
+
kind: "index",
|
|
684
|
+
text: `@unique on field "${symbol.name}.${field.name}"`
|
|
685
|
+
}, sourceId, unique.span));
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
if (isRelationField) {
|
|
689
|
+
if (ignoredModels.has(field.typeName)) return;
|
|
690
|
+
let relation;
|
|
691
|
+
for (const attribute of field.attributes) if (attribute.name === "relation") relation = attribute;
|
|
692
|
+
else diagnostics.push(unknownAttribute(label, attribute, "@", sourceId));
|
|
693
|
+
build.relationFields.push({
|
|
694
|
+
field,
|
|
695
|
+
relation
|
|
696
|
+
});
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
let storedName = field.name;
|
|
700
|
+
let nativeType;
|
|
701
|
+
let idAttribute;
|
|
702
|
+
let defaultAttribute;
|
|
703
|
+
let updatedAt;
|
|
704
|
+
for (const attribute of field.attributes) switch (attribute.name) {
|
|
705
|
+
case "map":
|
|
706
|
+
storedName = requireString(attribute, label, sourceId, diagnostics) ?? storedName;
|
|
707
|
+
break;
|
|
708
|
+
case "id":
|
|
709
|
+
idAttribute = attribute;
|
|
710
|
+
break;
|
|
711
|
+
case "default":
|
|
712
|
+
defaultAttribute = attribute;
|
|
713
|
+
break;
|
|
714
|
+
case "updatedAt":
|
|
715
|
+
updatedAt = attribute;
|
|
716
|
+
break;
|
|
717
|
+
case "unique": {
|
|
718
|
+
const parsed = parseFieldUnique(attribute, field.name, {
|
|
719
|
+
owner: label,
|
|
720
|
+
prefix: "@",
|
|
721
|
+
sourceId,
|
|
722
|
+
sources,
|
|
723
|
+
diagnostics,
|
|
724
|
+
compositeFields: /* @__PURE__ */ new Set()
|
|
725
|
+
});
|
|
726
|
+
if (parsed !== void 0) build.uniqueFields.push(parsed);
|
|
727
|
+
break;
|
|
728
|
+
}
|
|
729
|
+
default: if (attribute.name.startsWith("db.")) nativeType = attribute;
|
|
730
|
+
else diagnostics.push(unknownAttribute(label, attribute, "@", sourceId));
|
|
731
|
+
}
|
|
732
|
+
build.storedNames.set(field.name, storedName);
|
|
733
|
+
if (field.malformedType) return;
|
|
734
|
+
const owner = {
|
|
735
|
+
kind: "model",
|
|
736
|
+
name: symbol.name
|
|
737
|
+
};
|
|
738
|
+
const resolved = resolveFieldType(field, owner, nativeType, sourceId, ctx);
|
|
739
|
+
if (resolved === void 0) return;
|
|
740
|
+
const codecId = resolved.type.kind === "scalar" ? resolved.type.codecId : void 0;
|
|
741
|
+
if (idAttribute !== void 0) {
|
|
742
|
+
build.hasId = true;
|
|
743
|
+
if (codecId !== binding.objectIdCodecId || storedName !== "_id" || field.optional || field.list) {
|
|
744
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_ID_NOT_OBJECTID", `${label} is the model's @id, but it is not a required ObjectId stored as "_id". Prisma 8 identifies a MongoDB document by an ObjectId "_id"; declare the id as \`${field.name} String @id @default(auto()) @map("_id") @db.ObjectId\`. If stored documents have "_id" values that are not ObjectIds, this model cannot use this contract source until they are rewritten with ObjectId "_id" values, along with every field that refers to them.`, sourceId, idAttribute.span));
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
if (defaultAttribute !== void 0 && defaultKind(defaultAttribute) !== "auto") {
|
|
748
|
+
diagnostics.push(defaultUnsupported(label, defaultAttribute, owner, field, sourceId));
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
build.fields[field.name] = resolved;
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
const isDateTime = codecId === binding.scalarCodecIds.DateTime && !field.list;
|
|
755
|
+
if (updatedAt !== void 0 && !isDateTime) {
|
|
756
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_UPDATED_AT_TYPE_UNSUPPORTED", `${label}: @updatedAt is only supported on a DateTime field. Removing it also stops the Prisma 6 client from setting the field on every update. Set the value in application code when you write documents, then remove @updatedAt.`, sourceId, updatedAt.span));
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
const defaultIsNow = defaultAttribute !== void 0 && defaultKind(defaultAttribute) === "now";
|
|
760
|
+
if (defaultAttribute !== void 0 && (!defaultIsNow || !isDateTime)) {
|
|
761
|
+
diagnostics.push(defaultUnsupported(label, defaultAttribute, owner, field, sourceId));
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
const generator = updatedAt !== void 0 || defaultIsNow ? dateTimeNowGenerator(ctx.generatorFunctions, binding.scalarCodecIds.DateTime) : void 0;
|
|
765
|
+
const phases = generator === void 0 ? void 0 : updatedAt !== void 0 ? {
|
|
766
|
+
onCreate: generator,
|
|
767
|
+
onUpdate: generator
|
|
768
|
+
} : defaultIsNow ? { onCreate: generator } : void 0;
|
|
769
|
+
if (phases !== void 0 && field.optional) {
|
|
770
|
+
const written = updatedAt ?? defaultAttribute;
|
|
771
|
+
const generator = written === void 0 ? "the generator" : attributeText(written);
|
|
772
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_OPTIONAL_GENERATED_FIELD_UNSUPPORTED", `${label} is optional and its value comes from ${generator}, which Prisma 8 cannot express on an optional field yet. Either fix also changes the Prisma 6 app: a required field makes the Prisma 6 client fail on a stored document that lacks it, and without ${generator} the Prisma 6 client no longer fills it. Make the field required once every stored document has a value, or set the value in application code and remove ${generator}.`, sourceId, written?.span ?? field.span));
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
build.fields[field.name] = resolved;
|
|
776
|
+
if (phases !== void 0) build.executionDefaults.push({
|
|
777
|
+
field: storedName,
|
|
778
|
+
phases
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
/** The generator `now()` resolves to on the DateTime codec, which `@default(now())` and `@updatedAt` write. */
|
|
782
|
+
function dateTimeNowGenerator(generatorFunctions, codecId) {
|
|
783
|
+
const now = generatorFunctions.resolve({
|
|
784
|
+
name: "now",
|
|
785
|
+
args: {}
|
|
786
|
+
}, {
|
|
787
|
+
codecId,
|
|
788
|
+
typeParams: void 0,
|
|
789
|
+
length: void 0
|
|
790
|
+
});
|
|
791
|
+
if (!now.ok) throw new InternalError(`The stack binds no "now" generator function to codec "${codecId}", which the DateTime scalar maps to.`);
|
|
792
|
+
return now.generator;
|
|
793
|
+
}
|
|
794
|
+
function identifierList(attributeArg) {
|
|
795
|
+
const expression = attributeArg.expression;
|
|
796
|
+
const array = expression === void 0 ? void 0 : ArrayLiteralAst.cast(expression.syntax);
|
|
797
|
+
if (array === void 0) return void 0;
|
|
798
|
+
const names = [];
|
|
799
|
+
for (const element of array.elements()) {
|
|
800
|
+
const name = IdentifierAst.cast(element.syntax)?.name();
|
|
801
|
+
if (name === void 0) return void 0;
|
|
802
|
+
names.push(name);
|
|
803
|
+
}
|
|
804
|
+
return names;
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* What removing `onDelete` or `onUpdate` does to the Prisma 6 app. The Prisma 6 client emulates referential actions on MongoDB with these defaults: `onDelete` is `Restrict` on a required relation (a delete fails with P2014) and `SetNull` on an optional one, and `onUpdate` is `Cascade`.
|
|
808
|
+
*/
|
|
809
|
+
function referentialActionRemoval(key, declared, sides) {
|
|
810
|
+
const fallback = key === "onUpdate" ? {
|
|
811
|
+
action: "Cascade",
|
|
812
|
+
when: "its default",
|
|
813
|
+
effect: `changing the field a ${sides.model} refers to in a ${sides.target} updates the key in its ${sides.model} documents`
|
|
814
|
+
} : sides.optional ? {
|
|
815
|
+
action: "SetNull",
|
|
816
|
+
when: "its default for an optional relation",
|
|
817
|
+
effect: `deleting a ${sides.target} sets the key to null in its ${sides.model} documents`
|
|
818
|
+
} : {
|
|
819
|
+
action: "Restrict",
|
|
820
|
+
when: "its default for a required relation",
|
|
821
|
+
effect: `deleting a ${sides.target} that still has ${sides.model} documents fails with P2014`
|
|
822
|
+
};
|
|
823
|
+
if (declared === fallback.action) return `Removing "${key}: ${declared}" leaves the Prisma 6 app as it is: ${declared} is already what the Prisma 6 client does for this relation.`;
|
|
824
|
+
return `The Prisma 6 client emulates referential actions, so removing "${key}: ${declared}" also changes the Prisma 6 app: its client then applies ${fallback.action}, ${fallback.when}, so ${fallback.effect}.`;
|
|
825
|
+
}
|
|
826
|
+
function readRelationArguments(attribute, label, sides, sourceId, diagnostics) {
|
|
827
|
+
let name;
|
|
828
|
+
let fields;
|
|
829
|
+
let references;
|
|
830
|
+
let rejected = false;
|
|
831
|
+
const invalid = (what, span) => {
|
|
832
|
+
rejected = true;
|
|
833
|
+
diagnostics.push({
|
|
834
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
835
|
+
message: `${label}: @relation ${what}.`,
|
|
836
|
+
sourceId,
|
|
837
|
+
span
|
|
838
|
+
});
|
|
839
|
+
};
|
|
840
|
+
for (const arg of attribute.args) {
|
|
841
|
+
const key = arg.kind === "positional" ? "name" : arg.name;
|
|
842
|
+
switch (key) {
|
|
843
|
+
case "name": {
|
|
844
|
+
const expression = arg.expression;
|
|
845
|
+
name = expression === void 0 ? void 0 : StringLiteralExprAst.cast(expression.syntax)?.value();
|
|
846
|
+
if (name === void 0) invalid("name must be a string", arg.span);
|
|
847
|
+
break;
|
|
848
|
+
}
|
|
849
|
+
case "fields":
|
|
850
|
+
fields = identifierList(arg);
|
|
851
|
+
if (fields === void 0) invalid("fields must be a list of field names", arg.span);
|
|
852
|
+
break;
|
|
853
|
+
case "references":
|
|
854
|
+
references = identifierList(arg);
|
|
855
|
+
if (references === void 0) invalid("references must be a list of field names", arg.span);
|
|
856
|
+
break;
|
|
857
|
+
case "onDelete":
|
|
858
|
+
case "onUpdate":
|
|
859
|
+
case "map":
|
|
860
|
+
rejected = true;
|
|
861
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_REFERENTIAL_ACTION_UNSUPPORTED", key === "map" ? `${label}: @relation argument "map" is not supported; it names a foreign key constraint, and MongoDB has none. Remove "map"; the Prisma 6 app has no foreign key on MongoDB either, so nothing changes there.` : `${label}: @relation argument "${key}" is not supported; Prisma 8 enforces no referential actions on MongoDB. ${referentialActionRemoval(key, arg.value, sides)} Handle related documents in application code, then remove "${key}".`, sourceId, arg.span));
|
|
862
|
+
break;
|
|
863
|
+
default: invalid(`argument "${key ?? ""}" is not supported`, arg.span);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
return rejected ? void 0 : {
|
|
867
|
+
name,
|
|
868
|
+
fields,
|
|
869
|
+
references
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
function ignoredFieldReferenced(modelName, fieldNames, usedBy, sourceId, span) {
|
|
873
|
+
const one = fieldNames.length === 1;
|
|
874
|
+
const fields = fieldNames.map((name) => `"${modelName}.${name}"`).join(", ");
|
|
875
|
+
const removal = usedBy.kind === "index" ? "which makes Prisma 6 `db push` drop the index" : "which removes that relation from the Prisma 6 client";
|
|
876
|
+
return prisma6Diagnostic("PSL.PRISMA6_MONGO_IGNORED_FIELD_REFERENCED", `${one ? "Field" : "Fields"} ${fields} ${one ? "is" : "are"} marked @ignore, but ${usedBy.text} uses ${one ? "it" : "them"}. Remove @ignore from ${fields}, which adds ${one ? "it" : "them"} to the Prisma 6 client, or remove ${usedBy.text}, ${removal}.`, sourceId, span);
|
|
877
|
+
}
|
|
878
|
+
function readRelationFields(build, builds, out, diagnostics, namespaceId) {
|
|
879
|
+
const { symbol, sourceId, sources } = build.located;
|
|
880
|
+
for (const { field, relation } of build.relationFields) {
|
|
881
|
+
const label = `Relation field "${symbol.name}.${field.name}"`;
|
|
882
|
+
const reject = () => {
|
|
883
|
+
out.invalidFkPairings.push({
|
|
884
|
+
pairKey: fkRelationPairKey(symbol.name, field.typeName),
|
|
885
|
+
...ifDefined("relationName", relation === void 0 ? void 0 : stringArgument(relation))
|
|
886
|
+
});
|
|
887
|
+
};
|
|
888
|
+
const args = relation === void 0 ? void 0 : readRelationArguments(relation, label, {
|
|
889
|
+
model: symbol.name,
|
|
890
|
+
target: field.typeName,
|
|
891
|
+
optional: field.optional
|
|
892
|
+
}, sourceId, diagnostics);
|
|
893
|
+
if (relation !== void 0 && args === void 0) {
|
|
894
|
+
reject();
|
|
895
|
+
continue;
|
|
896
|
+
}
|
|
897
|
+
const target = builds.get(field.typeName);
|
|
898
|
+
if (target === void 0) continue;
|
|
899
|
+
if (!(args?.fields !== void 0 || args?.references !== void 0)) {
|
|
900
|
+
out.backRelations.push({
|
|
901
|
+
modelName: symbol.name,
|
|
902
|
+
field,
|
|
903
|
+
targetModelName: field.typeName,
|
|
904
|
+
...ifDefined("relationName", args?.name),
|
|
905
|
+
cardinality: field.list ? "1:N" : "1:1",
|
|
906
|
+
sources
|
|
907
|
+
});
|
|
908
|
+
continue;
|
|
909
|
+
}
|
|
910
|
+
if (field.list) {
|
|
911
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_LIST_RELATION_UNSUPPORTED", `${label} is a list relation that stores its keys in a list field (a many-to-many relation on MongoDB), which Prisma 8 does not support yet. Remove the relation fields from the schema this contract source reads and keep the key list as a plain field. The Prisma 6 client then loses the relation fields too, so Prisma 6 code that reads or writes the relation through them (\`include\`, \`connect\`) has to use the key list instead.`, sourceId, relation?.span ?? field.span));
|
|
912
|
+
reject();
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
const localNames = args?.fields ?? [];
|
|
916
|
+
const targetNames = args?.references ?? [];
|
|
917
|
+
const ignoredLocal = localNames.filter((name) => build.ignoredFields.has(name));
|
|
918
|
+
if (ignoredLocal.length > 0) {
|
|
919
|
+
diagnostics.push(ignoredFieldReferenced(symbol.name, ignoredLocal, {
|
|
920
|
+
kind: "relation",
|
|
921
|
+
text: `relation field "${symbol.name}.${field.name}"`
|
|
922
|
+
}, sourceId, relation?.span ?? field.span));
|
|
923
|
+
reject();
|
|
924
|
+
continue;
|
|
925
|
+
}
|
|
926
|
+
const ignoredTarget = targetNames.filter((name) => target.ignoredFields.has(name));
|
|
927
|
+
if (ignoredTarget.length > 0) {
|
|
928
|
+
diagnostics.push(ignoredFieldReferenced(target.located.symbol.name, ignoredTarget, {
|
|
929
|
+
kind: "relation",
|
|
930
|
+
text: `relation field "${symbol.name}.${field.name}"`
|
|
931
|
+
}, sourceId, relation?.span ?? field.span));
|
|
932
|
+
reject();
|
|
933
|
+
continue;
|
|
934
|
+
}
|
|
935
|
+
const localFields = localNames.map((name) => build.storedNames.get(name));
|
|
936
|
+
const targetFields = targetNames.map((name) => target.storedNames.get(name));
|
|
937
|
+
if (localFields.some((name) => name === void 0) || targetFields.some((name) => name === void 0) || localNames.length !== targetNames.length || localNames.length === 0) {
|
|
938
|
+
diagnostics.push({
|
|
939
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
940
|
+
message: `${label}: @relation fields and references must name the same number of scalar fields of "${symbol.name}" and "${field.typeName}".`,
|
|
941
|
+
sourceId,
|
|
942
|
+
span: relation?.span ?? field.span
|
|
943
|
+
});
|
|
944
|
+
reject();
|
|
945
|
+
continue;
|
|
946
|
+
}
|
|
947
|
+
if (resolveToOneRelationNullable({
|
|
948
|
+
declaredNullable: field.optional,
|
|
949
|
+
localFieldNullability: localNames.map((name) => symbol.fields[name]?.optional === true),
|
|
950
|
+
ownsReference: true
|
|
951
|
+
}).contradiction !== void 0) {
|
|
952
|
+
diagnostics.push({
|
|
953
|
+
code: "PSL_RELATION_NULLABILITY_MISMATCH",
|
|
954
|
+
message: field.optional ? `${label} is optional but every field in @relation(fields: [...]) is required. Make one of those fields optional with "?" or remove "?" from "${field.name}".` : `${label} is required but a field in @relation(fields: [...]) is optional. Add "?" to "${field.name}" or make those fields required.`,
|
|
955
|
+
sourceId,
|
|
956
|
+
span: field.span
|
|
957
|
+
});
|
|
958
|
+
reject();
|
|
959
|
+
continue;
|
|
960
|
+
}
|
|
961
|
+
build.relations[field.name] = {
|
|
962
|
+
to: crossRef(field.typeName, namespaceId),
|
|
963
|
+
cardinality: "N:1",
|
|
964
|
+
nullable: field.optional,
|
|
965
|
+
on: {
|
|
966
|
+
localFields: localNames,
|
|
967
|
+
targetFields: targetNames
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
out.foreignKeys.push({
|
|
971
|
+
declaringModel: symbol.name,
|
|
972
|
+
targetModel: field.typeName,
|
|
973
|
+
...ifDefined("relationName", args?.name),
|
|
974
|
+
localFields: localNames,
|
|
975
|
+
targetFields: targetNames
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
function buildIndexes(build, diagnostics) {
|
|
980
|
+
const { symbol, sourceId } = build.located;
|
|
981
|
+
const indexes = [];
|
|
982
|
+
let textIndexes = 0;
|
|
983
|
+
const keyFor = (field, text) => ({
|
|
984
|
+
field: build.storedNames.get(field.name) ?? field.name,
|
|
985
|
+
direction: field.direction ?? (text ? "text" : 1)
|
|
986
|
+
});
|
|
987
|
+
for (const attribute of [...build.uniqueFields, ...build.modelIndexes]) {
|
|
988
|
+
const names = attribute.fields.map((field) => field.name);
|
|
989
|
+
const usedBy = {
|
|
990
|
+
kind: "index",
|
|
991
|
+
text: build.uniqueFields.includes(attribute) ? `@unique on field "${symbol.name}.${attribute.fields[0]?.name ?? ""}"` : `@@${attribute.kind} on model "${symbol.name}"`
|
|
992
|
+
};
|
|
993
|
+
const ignored = names.filter((name) => build.ignoredFields.has(name));
|
|
994
|
+
if (ignored.length > 0) {
|
|
995
|
+
diagnostics.push(ignoredFieldReferenced(symbol.name, ignored, usedBy, sourceId, attribute.span));
|
|
996
|
+
continue;
|
|
997
|
+
}
|
|
998
|
+
if (names.some((name) => build.rejectedFields.has(name))) continue;
|
|
999
|
+
const unknown = names.find((name) => !build.storedNames.has(name));
|
|
1000
|
+
if (unknown !== void 0) {
|
|
1001
|
+
diagnostics.push({
|
|
1002
|
+
code: "PSL_INDEX_FIELD_NOT_FOUND",
|
|
1003
|
+
message: `Index on model "${symbol.name}" references unknown field "${unknown}"`,
|
|
1004
|
+
sourceId,
|
|
1005
|
+
span: attribute.span
|
|
1006
|
+
});
|
|
1007
|
+
continue;
|
|
1008
|
+
}
|
|
1009
|
+
if (attribute.kind === "fulltext") {
|
|
1010
|
+
textIndexes++;
|
|
1011
|
+
if (textIndexes > 1) {
|
|
1012
|
+
diagnostics.push(prisma6Diagnostic("PSL.PRISMA6_MONGO_TEXT_INDEX_LIMIT", `Model "${symbol.name}" has more than one @@fulltext; MongoDB allows one text index per collection. Merge the fields into one @@fulltext.`, sourceId, attribute.span));
|
|
1013
|
+
continue;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
indexes.push(new MongoIndex({
|
|
1017
|
+
keys: attribute.fields.map((field) => keyFor(field, attribute.kind === "fulltext")),
|
|
1018
|
+
...attribute.kind === "unique" ? { unique: true } : {}
|
|
1019
|
+
}));
|
|
1020
|
+
}
|
|
1021
|
+
return indexes;
|
|
1022
|
+
}
|
|
1023
|
+
function assembleContract(input) {
|
|
1024
|
+
const target = input.binding.target.targetId;
|
|
1025
|
+
const targetFamily = input.binding.target.familyId;
|
|
1026
|
+
const builtEnums = Object.fromEntries(input.enums);
|
|
1027
|
+
const collections = {};
|
|
1028
|
+
for (const [name, collection] of Object.entries(input.collections)) collections[name] = collection.indexes.length > 0 ? { indexes: collection.indexes } : {};
|
|
1029
|
+
const storage = buildMongoStorage({
|
|
1030
|
+
collections,
|
|
1031
|
+
valueSets: mongoValueSetsOf(builtEnums)
|
|
1032
|
+
});
|
|
1033
|
+
const models = {};
|
|
1034
|
+
for (const [modelName, build] of input.builds) models[modelName] = {
|
|
1035
|
+
fields: build.fields,
|
|
1036
|
+
relations: build.relations,
|
|
1037
|
+
storage: {
|
|
1038
|
+
collection: build.collection,
|
|
1039
|
+
fields: Object.fromEntries(Object.keys(build.fields).map((name) => [name, { field: build.storedNames.get(name) ?? name }]))
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
const capabilities = {};
|
|
1043
|
+
const execution = buildExecutionSection({
|
|
1044
|
+
target,
|
|
1045
|
+
targetFamily,
|
|
1046
|
+
defaults: input.executionDefaults
|
|
1047
|
+
});
|
|
1048
|
+
return {
|
|
1049
|
+
targetFamily,
|
|
1050
|
+
target,
|
|
1051
|
+
roots: input.roots,
|
|
1052
|
+
domain: { namespaces: { [input.namespaceId]: {
|
|
1053
|
+
models: blindCast(models),
|
|
1054
|
+
...Object.keys(input.valueObjects).length > 0 ? { valueObjects: input.valueObjects } : {},
|
|
1055
|
+
...Object.keys(builtEnums).length > 0 ? { enum: builtEnums } : {}
|
|
1056
|
+
} } },
|
|
1057
|
+
storage,
|
|
1058
|
+
extensions: {},
|
|
1059
|
+
capabilities,
|
|
1060
|
+
profileHash: computeProfileHash({
|
|
1061
|
+
target,
|
|
1062
|
+
targetFamily,
|
|
1063
|
+
capabilities
|
|
1064
|
+
}),
|
|
1065
|
+
meta: {},
|
|
1066
|
+
...execution !== void 0 ? { execution } : {}
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
function mergedSources(documents) {
|
|
1070
|
+
const [first, ...rest] = documents.map((document) => document.sources);
|
|
1071
|
+
if (first === void 0) throw new InternalError("A Prisma 6 schema has at least one document");
|
|
1072
|
+
return first.merge(...rest);
|
|
1073
|
+
}
|
|
1074
|
+
function defaultOutputFromSchemaPath(schemaPath) {
|
|
1075
|
+
return join(dirname(schemaPath), "contract.json");
|
|
1076
|
+
}
|
|
1077
|
+
function mapParseDiagnostics(diagnostics, sourceFile, sourceId) {
|
|
1078
|
+
return diagnostics.map((diagnostic) => ({
|
|
1079
|
+
code: diagnostic.code,
|
|
1080
|
+
message: diagnostic.message,
|
|
1081
|
+
sourceId,
|
|
1082
|
+
span: sourceFile.rangeToPslSpan(diagnostic.range)
|
|
1083
|
+
}));
|
|
1084
|
+
}
|
|
1085
|
+
/**
|
|
1086
|
+
* The files a Prisma 6 schema input names: the file itself, or every regular `.prisma` file under the directory, nested directories and symbolic links included, as Prisma 6 reads a schema directory. Sorted by path so duplicate detection blames the later file deterministically.
|
|
1087
|
+
*/
|
|
1088
|
+
async function listSchemaFiles(absolutePath, displayPath) {
|
|
1089
|
+
if (!(await stat(absolutePath)).isDirectory()) return [{
|
|
1090
|
+
sourceId: displayPath,
|
|
1091
|
+
absolutePath
|
|
1092
|
+
}];
|
|
1093
|
+
const entries = await readdir(absolutePath, { recursive: true });
|
|
1094
|
+
const files = [];
|
|
1095
|
+
for (const entry of entries.filter((name) => extname(name) === ".prisma").map((name) => normalize(name)).sort()) {
|
|
1096
|
+
const entryPath = join(absolutePath, entry);
|
|
1097
|
+
if ((await stat(entryPath)).isFile()) files.push({
|
|
1098
|
+
sourceId: join(displayPath, entry),
|
|
1099
|
+
absolutePath: entryPath
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
return files;
|
|
1103
|
+
}
|
|
1104
|
+
function isMissingPath(error) {
|
|
1105
|
+
return error instanceof Error && Reflect.get(error, "code") === "ENOENT";
|
|
1106
|
+
}
|
|
1107
|
+
function readFailure(schemaPath, message, meta) {
|
|
1108
|
+
return notOk({
|
|
1109
|
+
summary: `Failed to read Prisma 6 schema at "${schemaPath}"`,
|
|
1110
|
+
diagnostics: [prisma6Diagnostic("PSL.PRISMA6_MONGO_SCHEMA_READ_FAILED", message, schemaPath, void 0)],
|
|
1111
|
+
meta
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
/**
|
|
1115
|
+
* A `ContractConfig` that reads a Prisma 6 MongoDB `schema.prisma` (a file, or a directory of `.prisma` files) as the contract source.
|
|
1116
|
+
*/
|
|
1117
|
+
function prisma6Contract(schemaPath, options) {
|
|
1118
|
+
const parserOptions = { grammar: "prisma-7" };
|
|
1119
|
+
return {
|
|
1120
|
+
source: {
|
|
1121
|
+
format: "psl",
|
|
1122
|
+
inputs: [schemaPath],
|
|
1123
|
+
parserOptions,
|
|
1124
|
+
async load(context) {
|
|
1125
|
+
const [absolutePath] = context.resolvedInputs;
|
|
1126
|
+
if (absolutePath === void 0) throw new InternalError("prisma6Contract: context.resolvedInputs is empty. The CLI config loader should populate it from source.inputs.");
|
|
1127
|
+
let files;
|
|
1128
|
+
try {
|
|
1129
|
+
files = await listSchemaFiles(absolutePath, schemaPath);
|
|
1130
|
+
} catch (error) {
|
|
1131
|
+
const cause = String(error);
|
|
1132
|
+
return readFailure(schemaPath, isMissingPath(error) ? `There is no file or directory at "${schemaPath}". Fix the path passed to prisma6Schema() in prisma.config.ts.` : cause, {
|
|
1133
|
+
schemaPath,
|
|
1134
|
+
absolutePath,
|
|
1135
|
+
cause
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
if (files.length === 0) return readFailure(schemaPath, `The schema directory "${schemaPath}" contains no .prisma file.`, {
|
|
1139
|
+
schemaPath,
|
|
1140
|
+
absolutePath
|
|
1141
|
+
});
|
|
1142
|
+
const documents = [];
|
|
1143
|
+
const seedDiagnostics = [];
|
|
1144
|
+
for (const file of files) {
|
|
1145
|
+
let schema;
|
|
1146
|
+
try {
|
|
1147
|
+
schema = await readFile(file.absolutePath, "utf-8");
|
|
1148
|
+
} catch (error) {
|
|
1149
|
+
const message = String(error);
|
|
1150
|
+
return readFailure(file.sourceId, message, {
|
|
1151
|
+
schemaPath: file.sourceId,
|
|
1152
|
+
absoluteSchemaPath: file.absolutePath,
|
|
1153
|
+
cause: message
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
const { document, sources, diagnostics } = parse(schema, file.sourceId, parserOptions);
|
|
1157
|
+
const sourceFile = sources.sourceFileFor(document.syntax);
|
|
1158
|
+
seedDiagnostics.push(...mapParseDiagnostics(diagnostics, sourceFile, file.sourceId));
|
|
1159
|
+
documents.push({
|
|
1160
|
+
document,
|
|
1161
|
+
sources,
|
|
1162
|
+
sourceFile,
|
|
1163
|
+
sourceId: file.sourceId
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
let contract;
|
|
1167
|
+
try {
|
|
1168
|
+
const interpreted = interpretPrisma6Documents({
|
|
1169
|
+
documents,
|
|
1170
|
+
seedDiagnostics,
|
|
1171
|
+
binding: options.binding,
|
|
1172
|
+
generatorFunctions: context.generatorFunctions,
|
|
1173
|
+
authoringContributions: context.authoringContributions,
|
|
1174
|
+
codecLookup: context.codecLookup,
|
|
1175
|
+
dataTypes: context.dataTypes,
|
|
1176
|
+
defaultNamespaceId: context.defaultNamespaceId
|
|
1177
|
+
});
|
|
1178
|
+
if (!interpreted.ok) return interpreted;
|
|
1179
|
+
contract = applySpecifierDefaultControlPolicy(interpreted.value, options.defaultControlPolicy);
|
|
1180
|
+
validateContractDomain(contract);
|
|
1181
|
+
validateMongoStorage(blindCast(contract));
|
|
1182
|
+
} catch (error) {
|
|
1183
|
+
if (!isStructuredError(error)) throw error;
|
|
1184
|
+
return notOk({
|
|
1185
|
+
summary: "Prisma 6 MongoDB schema interpretation failed",
|
|
1186
|
+
diagnostics: [prisma6Diagnostic("PSL.PRISMA6_MONGO_CONTRACT_INVALID", `This schema gives a contract that Prisma 8 rejects, and the Prisma 6 MongoDB contract source has no specific diagnostic for the cause: ${error.message.replace(/\.$/, "")}. This is a bug in Prisma ORM; please report it with this schema.`, schemaPath, void 0)],
|
|
1187
|
+
meta: {
|
|
1188
|
+
schemaPath,
|
|
1189
|
+
code: error.code
|
|
1190
|
+
}
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
return ok(contract);
|
|
1194
|
+
}
|
|
1195
|
+
},
|
|
1196
|
+
output: options.output ?? defaultOutputFromSchemaPath(schemaPath)
|
|
1197
|
+
};
|
|
1198
|
+
}
|
|
1199
|
+
//#endregion
|
|
1200
|
+
export { prisma6Contract };
|
|
1201
|
+
|
|
1202
|
+
//# sourceMappingURL=contract-prisma6__provider.mjs.map
|