@prisma/orm-family-sql 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 +2 -6
- package/dist/{aggregate-descriptor-registry-C7hel5O7.mjs → aggregate-descriptor-registry-ZrKjxwQe.mjs} +5 -5
- package/dist/aggregate-descriptor-registry-ZrKjxwQe.mjs.map +1 -0
- package/dist/ast-D0miQ1B6.mjs +372 -0
- package/dist/ast-D0miQ1B6.mjs.map +1 -0
- package/dist/ast-YEMe_B8z.d.mts +292 -0
- package/dist/ast-YEMe_B8z.d.mts.map +1 -0
- package/dist/attribute-specs-DA_RwQFB.d.mts +114 -0
- package/dist/attribute-specs-DA_RwQFB.d.mts.map +1 -0
- package/dist/{authored-check-naming-Hf9990DV.mjs → authored-check-naming-BHGJhjqn.mjs} +5 -5
- package/dist/authored-check-naming-BHGJhjqn.mjs.map +1 -0
- package/dist/{authored-check-naming-BWBe-PVE.d.mts → authored-check-naming-D-o196ry.d.mts} +3 -3
- package/dist/authored-check-naming-D-o196ry.d.mts.map +1 -0
- package/dist/authoring-entity-types-CgKIgWq5-pEdfjam5.d.mts +9 -0
- package/dist/authoring-entity-types-CgKIgWq5-pEdfjam5.d.mts.map +1 -0
- package/dist/builder.d.mts +4 -3
- package/dist/builder__runtime.d.mts +29 -31
- package/dist/builder__runtime.d.mts.map +1 -1
- package/dist/builder__runtime.mjs +261 -191
- package/dist/builder__runtime.mjs.map +1 -1
- package/dist/builder__types.d.mts +6 -3
- package/dist/{canonicalization-hooks-dmXkOR4a.mjs → canonicalization-hooks-Ce1v_TDl.mjs} +2 -2
- package/dist/canonicalization-hooks-Ce1v_TDl.mjs.map +1 -0
- package/dist/{canonicalization-hooks-CYnW_sGn.d.mts → canonicalization-hooks-DyapQ0my.d.mts} +2 -2
- package/dist/canonicalization-hooks-DyapQ0my.d.mts.map +1 -0
- package/dist/{check-constraint-B7qGu6rc-HvQjjX82.d.mts → check-constraint-B7qGu6rc-Bk2ezWXu.d.mts} +4 -4
- package/dist/check-constraint-B7qGu6rc-Bk2ezWXu.d.mts.map +1 -0
- package/dist/{codec-descriptor-registry-N0dhtKaH.mjs → codec-descriptor-registry-CiiFzMtb.mjs} +13 -40
- package/dist/codec-descriptor-registry-CiiFzMtb.mjs.map +1 -0
- package/dist/collection-methods-BB8YH69u.d.mts +1 -0
- package/dist/collection-methods-D2UnCS0S-DOy2qHYS.d.mts +77 -0
- package/dist/collection-methods-D2UnCS0S-DOy2qHYS.d.mts.map +1 -0
- package/dist/{config-types-D9fdKG3g.d.mts → config-types-C-1mIiJO.d.mts} +5 -5
- package/dist/config-types-C-1mIiJO.d.mts.map +1 -0
- package/dist/{config-types-gAm54C_v.mjs → config-types-DkEeq_qq.mjs} +10 -6
- package/dist/config-types-DkEeq_qq.mjs.map +1 -0
- package/dist/{contract-builder-D4a5dT7j.mjs → contract-builder-50lF0kz1.mjs} +431 -226
- package/dist/contract-builder-50lF0kz1.mjs.map +1 -0
- package/dist/contract-builder-C_Zi57iD.d.mts +1967 -0
- package/dist/contract-builder-C_Zi57iD.d.mts.map +1 -0
- package/dist/contract-emitter.d.mts +4 -7
- package/dist/contract-emitter.d.mts.map +1 -1
- package/dist/contract-emitter.mjs +1 -1
- package/dist/{contract-errors-BCN6RVI5-5IHBF_lg.mjs → contract-errors-BCN6RVI5-DoH6b_KZ.mjs} +2 -2
- package/dist/contract-errors-BCN6RVI5-DoH6b_KZ.mjs.map +1 -0
- package/dist/contract-prisma7__provider.d.mts +97 -0
- package/dist/contract-prisma7__provider.d.mts.map +1 -0
- package/dist/contract-prisma7__provider.mjs +2011 -0
- package/dist/contract-prisma7__provider.mjs.map +1 -0
- package/dist/contract-psl.d.mts +18 -29
- package/dist/contract-psl.d.mts.map +1 -1
- package/dist/contract-psl.mjs +1 -1
- package/dist/contract-psl__attribute-specs.d.mts +2 -0
- package/dist/contract-psl__attribute-specs.mjs +2 -0
- package/dist/contract-psl__default-table-name.d.mts +7 -0
- package/dist/contract-psl__default-table-name.d.mts.map +1 -0
- package/dist/contract-psl__default-table-name.mjs +2 -0
- package/dist/contract-psl__diagnostics.d.mts +12 -0
- package/dist/contract-psl__diagnostics.d.mts.map +1 -0
- package/dist/contract-psl__diagnostics.mjs +2 -0
- package/dist/contract-psl__map-names.d.mts +16 -0
- package/dist/contract-psl__map-names.d.mts.map +1 -0
- package/dist/contract-psl__map-names.mjs +21 -0
- package/dist/contract-psl__map-names.mjs.map +1 -0
- package/dist/contract-psl__provider.d.mts +3 -3
- package/dist/contract-psl__provider.d.mts.map +1 -1
- package/dist/contract-psl__provider.mjs +95 -46
- package/dist/contract-psl__provider.mjs.map +1 -1
- package/dist/contract-ts.d.mts +5 -5
- package/dist/contract-ts.mjs +5 -4
- package/dist/contract-ts__config-types.d.mts +1 -1
- package/dist/contract-ts__config-types.mjs +1 -1
- package/dist/contract-ts__contract-builder.d.mts +4 -4
- package/dist/contract-ts__contract-builder.mjs +4 -3
- package/dist/{contract-view-BMR5IWk4.mjs → contract-view-DqpzeYeE.mjs} +2 -2
- package/dist/contract-view-DqpzeYeE.mjs.map +1 -0
- package/dist/{contract-view-CPHxoAEX.d.mts → contract-view-DuB35or0.d.mts} +3 -3
- package/dist/contract-view-DuB35or0.d.mts.map +1 -0
- package/dist/contract.d.mts +30 -28
- package/dist/contract.mjs +23 -18
- package/dist/contract__authored-check-naming.d.mts +1 -1
- package/dist/contract__authored-check-naming.mjs +1 -1
- package/dist/contract__canonicalization-hooks.d.mts +1 -1
- package/dist/contract__canonicalization-hooks.mjs +1 -1
- package/dist/contract__contract-view.d.mts +1 -1
- package/dist/contract__contract-view.mjs +1 -1
- package/dist/contract__data-type-support.d.mts +2 -0
- package/dist/contract__data-type-support.mjs +2 -0
- package/dist/contract__data-type.d.mts +2 -0
- package/dist/contract__data-type.mjs +3 -0
- package/dist/contract__entity-handle-lowering-hook.d.mts +2 -2
- package/dist/contract__entity-handle-lowering-hook.mjs +2 -2
- package/dist/contract__entity-kinds.d.mts +1 -1
- package/dist/contract__entity-kinds.mjs +1 -1
- package/dist/contract__factories.d.mts +1 -1
- package/dist/contract__factories.mjs +1 -1
- package/dist/contract__foreign-key-materialization.d.mts +2 -2
- package/dist/contract__foreign-key-materialization.mjs +3 -2
- package/dist/contract__index-naming.d.mts +2 -2
- package/dist/contract__index-naming.mjs +2 -2
- package/dist/contract__index-type-validation.d.mts +2 -2
- package/dist/contract__index-type-validation.mjs +1 -1
- package/dist/contract__index-types.d.mts +3 -3
- package/dist/contract__index-types.mjs +2 -2
- package/dist/contract__referential-action-sql.d.mts +1 -1
- package/dist/contract__referential-action-sql.mjs +1 -1
- package/dist/contract__resolve-storage-table.d.mts +1 -1
- package/dist/contract__resolve-storage-table.mjs +1 -1
- package/dist/contract__sql-expression.d.mts +2 -0
- package/dist/contract__sql-expression.mjs +2 -0
- package/dist/contract__types.d.mts +12 -12
- package/dist/contract__types.mjs +4 -4
- package/dist/contract__validators.d.mts +2 -2
- package/dist/contract__validators.mjs +3 -3
- package/dist/contract__value-set-derivation-hook.d.mts +1 -1
- package/dist/contract__value-set-derivation-hook.mjs +1 -1
- package/dist/control-BK50zF6c.mjs +2721 -0
- package/dist/control-BK50zF6c.mjs.map +1 -0
- package/dist/control-ChAUdOOu.d.mts +1416 -0
- package/dist/control-ChAUdOOu.d.mts.map +1 -0
- package/dist/{control-adapter-C99J7aEF-B7eQd7vD.d.mts → control-adapter-Bn0uhplA-BzP2uPqJ.d.mts} +27 -44
- package/dist/control-adapter-Bn0uhplA-BzP2uPqJ.d.mts.map +1 -0
- package/dist/control-adapter-NZ2kKc4x.d.mts +13 -0
- package/dist/control-adapter-NZ2kKc4x.d.mts.map +1 -0
- package/dist/control-adapter-SlQkTEwT.mjs +16 -0
- package/dist/control-adapter-SlQkTEwT.mjs.map +1 -0
- package/dist/data-type-BFSpaotu.mjs +52 -0
- package/dist/data-type-BFSpaotu.mjs.map +1 -0
- package/dist/data-type-DJIvKQHf.d.mts +158 -0
- package/dist/data-type-DJIvKQHf.d.mts.map +1 -0
- package/dist/data-type-support-BhSoPUFj.mjs +9 -0
- package/dist/data-type-support-BhSoPUFj.mjs.map +1 -0
- package/dist/data-type-support-CXpA0ex-.d.mts +7 -0
- package/dist/data-type-support-CXpA0ex-.d.mts.map +1 -0
- package/dist/{db-D18PrXKW-DvTv4JFn.d.mts → db-D1d75IvM-D4mRDC6w.d.mts} +123 -128
- package/dist/db-D1d75IvM-D4mRDC6w.d.mts.map +1 -0
- package/dist/{ddl-types-CXx4vPz6-BsgrnSUY.d.mts → ddl-types-By5mT2_S-CdaaFvsX.d.mts} +24 -29
- package/dist/ddl-types-By5mT2_S-CdaaFvsX.d.mts.map +1 -0
- package/dist/default-mapping-CAOONlKQ-4m07nb-O.d.mts +39 -0
- package/dist/default-mapping-CAOONlKQ-4m07nb-O.d.mts.map +1 -0
- package/dist/default-table-name-BfFY8qYR-CWZFDX6v.mjs +9 -0
- package/dist/default-table-name-BfFY8qYR-CWZFDX6v.mjs.map +1 -0
- package/dist/derived-checks-D5HVRvqN-BJx1gwPA.mjs +1508 -0
- package/dist/derived-checks-D5HVRvqN-BJx1gwPA.mjs.map +1 -0
- package/dist/{derived-checks-DPdD01O0-DGqOFjs6.d.mts → derived-checks-DpPkO6Dt-9U9UJZOo.d.mts} +4 -4
- package/dist/derived-checks-DpPkO6Dt-9U9UJZOo.d.mts.map +1 -0
- package/dist/diagnostics-RHJxoiIk.mjs +23 -0
- package/dist/diagnostics-RHJxoiIk.mjs.map +1 -0
- package/dist/{diff-DbTNVm2f.d.mts → diff-1qHOLoUB.d.mts} +23 -10
- package/dist/diff-1qHOLoUB.d.mts.map +1 -0
- package/dist/diff-C1rFOhek.mjs +21 -0
- package/dist/diff-C1rFOhek.mjs.map +1 -0
- package/dist/{dist-ZK6oeI5e.mjs → dist-C8Y-PPuE.mjs} +36 -212
- package/dist/dist-C8Y-PPuE.mjs.map +1 -0
- package/dist/{dist-C_q1_QR9.mjs → dist-CHz1hF8M.mjs} +2 -2
- package/dist/dist-CHz1hF8M.mjs.map +1 -0
- package/dist/{dist-x6jvtkKM.mjs → dist-CMDXybwm.mjs} +2 -2
- package/dist/dist-CMDXybwm.mjs.map +1 -0
- package/dist/{driver-types-BQtRkOJ0-Bv2RPSfr.d.mts → driver-types-DRsYeq3j-BimeCnUk.d.mts} +11 -2
- package/dist/driver-types-DRsYeq3j-BimeCnUk.d.mts.map +1 -0
- package/dist/entity-handle-lowering-hook-BJZSlVVF.mjs +16 -0
- package/dist/entity-handle-lowering-hook-BJZSlVVF.mjs.map +1 -0
- package/dist/{entity-handle-lowering-hook-CIvRKBfa.d.mts → entity-handle-lowering-hook-BuvLtgFi.d.mts} +8 -11
- package/dist/entity-handle-lowering-hook-BuvLtgFi.d.mts.map +1 -0
- package/dist/{entity-kinds-B5cUFU22.d.mts → entity-kinds-BPG2xCZV.d.mts} +7 -7
- package/dist/entity-kinds-BPG2xCZV.d.mts.map +1 -0
- package/dist/{entity-kinds-D7vwoN_T-CCBwFJy0.mjs → entity-kinds-JR5SAm5h-DOH6VUtL.mjs} +31 -28
- package/dist/entity-kinds-JR5SAm5h-DOH6VUtL.mjs.map +1 -0
- package/dist/{errors-B5g0xWro-mWH2C07F.mjs → errors-B5g0xWro-C8plbqga.mjs} +2 -2
- package/dist/errors-B5g0xWro-C8plbqga.mjs.map +1 -0
- package/dist/errors.d.mts +1 -1
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +1 -1
- package/dist/exports-C3wGYtID-D65DEUTC.mjs +2389 -0
- package/dist/exports-C3wGYtID-D65DEUTC.mjs.map +1 -0
- package/dist/{expression-FJK6Ar-d.d.mts → expression-6ld_ZQL6-fOuazzzm.d.mts} +37 -16
- package/dist/expression-6ld_ZQL6-fOuazzzm.d.mts.map +1 -0
- package/dist/expression-CieaNuRM-B1uVqxwd.d.mts +22 -0
- package/dist/expression-CieaNuRM-B1uVqxwd.d.mts.map +1 -0
- package/dist/expression-D8HstQiB.d.mts +2 -0
- package/dist/{expression-CX5mTA-z.mjs → expression-impl-B-XNINxr-BhN2sysZ.mjs} +41 -18
- package/dist/expression-impl-B-XNINxr-BhN2sysZ.mjs.map +1 -0
- package/dist/{factories-SVor5xIT.mjs → factories-Crobuxwn.mjs} +27 -20
- package/dist/factories-Crobuxwn.mjs.map +1 -0
- package/dist/{factories-P3qBQhO-.d.mts → factories-DbNP9qfs.d.mts} +16 -10
- package/dist/factories-DbNP9qfs.d.mts.map +1 -0
- package/dist/family.d.mts +17 -13
- package/dist/family.mjs +17 -12
- package/dist/family__control-adapter.d.mts +3 -3
- package/dist/family__control-adapter.mjs +2 -1
- package/dist/family__control.d.mts +5 -4
- package/dist/family__control.mjs +4 -4
- package/dist/family__diff.d.mts +2 -3
- package/dist/family__diff.mjs +2 -2
- package/dist/family__ir.d.mts +1 -1
- package/dist/family__ir.mjs +2 -2
- package/dist/family__migration.d.mts +1 -1
- package/dist/family__migration.mjs +1 -1
- package/dist/family__pack.d.mts +2 -249
- package/dist/family__pack.mjs +3 -18
- package/dist/family__psl-build.d.mts +3 -0
- package/dist/family__psl-build.mjs +3 -0
- package/dist/family__psl-infer.d.mts +2 -2
- package/dist/family__psl-infer.mjs +2 -2
- package/dist/family__runtime.d.mts +2 -2
- package/dist/family__runtime.mjs +2 -2
- package/dist/family__verify.d.mts +1 -1
- package/dist/family__verify.mjs +1 -1
- package/dist/foreign-key-materialization-48P2V8on.d.mts +98 -0
- package/dist/foreign-key-materialization-48P2V8on.d.mts.map +1 -0
- package/dist/foreign-key-materialization-BM59w_Xg.mjs +287 -0
- package/dist/foreign-key-materialization-BM59w_Xg.mjs.map +1 -0
- package/dist/{foreign-key-C-iTPuRT-C9ip8zFx.d.mts → foreign-key-qkDFfG8t-TaK_GYWR.d.mts} +21 -5
- package/dist/foreign-key-qkDFfG8t-TaK_GYWR.d.mts.map +1 -0
- package/dist/functions-CsOoN7I3.mjs +88 -0
- package/dist/functions-CsOoN7I3.mjs.map +1 -0
- package/dist/functions-EW-RrRn3.d.mts +73 -0
- package/dist/functions-EW-RrRn3.d.mts.map +1 -0
- package/dist/generator-functions-D_qdqBV--Bq296cED.mjs +544 -0
- package/dist/generator-functions-D_qdqBV--Bq296cED.mjs.map +1 -0
- package/dist/index-7nHHQsAj.d.mts +606 -0
- package/dist/index-7nHHQsAj.d.mts.map +1 -0
- package/dist/{index-C5I8D-MB.d.mts → index-Nqc3OHR_.d.mts} +4 -5
- package/dist/index-Nqc3OHR_.d.mts.map +1 -0
- package/dist/index-equivalence-DswCiq5l-CGsyPP9B.mjs +109 -0
- package/dist/index-equivalence-DswCiq5l-CGsyPP9B.mjs.map +1 -0
- package/dist/{index-naming-DREt6js7-CRH27yUv.mjs → index-naming-BOcJT1B3-mG8Fd6KN.mjs} +35 -9
- package/dist/index-naming-BOcJT1B3-mG8Fd6KN.mjs.map +1 -0
- package/dist/{index-naming-Ct65z5Xk.d.mts → index-naming-Cs6wwia3.d.mts} +15 -5
- package/dist/index-naming-Cs6wwia3.d.mts.map +1 -0
- package/dist/index-reference-4wsdeB7v-DCwswK-q.d.mts +67 -0
- package/dist/index-reference-4wsdeB7v-DCwswK-q.d.mts.map +1 -0
- package/dist/index-reference-BQSrkRfT.mjs +55 -0
- package/dist/index-reference-BQSrkRfT.mjs.map +1 -0
- package/dist/index-reference-D8ewQRJr.d.mts +1 -0
- package/dist/index-type-validation-DJEMmmw0.mjs +42 -0
- package/dist/index-type-validation-DJEMmmw0.mjs.map +1 -0
- package/dist/index-type-validation-fGGwAHWc.d.mts +16 -0
- package/dist/index-type-validation-fGGwAHWc.d.mts.map +1 -0
- package/dist/index-types-H1O43iYT-BD0VwPqV.d.mts +66 -0
- package/dist/index-types-H1O43iYT-BD0VwPqV.d.mts.map +1 -0
- package/dist/index-types-pC_5vADQ-BOOBi14R.mjs +95 -0
- package/dist/index-types-pC_5vADQ-BOOBi14R.mjs.map +1 -0
- package/dist/index-types-snhtt_Fo.d.mts +1 -0
- package/dist/interpreter-D5qk4B---CG0C7kdx.mjs +2280 -0
- package/dist/interpreter-D5qk4B---CG0C7kdx.mjs.map +1 -0
- package/dist/{ir-Bghjt-FG.d.mts → ir-BvptQsFW.d.mts} +11 -5
- package/dist/ir-BvptQsFW.d.mts.map +1 -0
- package/dist/{ir-I-xciGUH.mjs → ir-DzsUDO8e.mjs} +2 -2
- package/dist/ir-DzsUDO8e.mjs.map +1 -0
- package/dist/{middleware-AhTz1BOW-th-Suxuf.d.mts → middleware-DHkW6pRr-DM6hd9iZ.d.mts} +5 -5
- package/dist/middleware-DHkW6pRr-DM6hd9iZ.d.mts.map +1 -0
- package/dist/middleware-gqy3l13N.d.mts +1 -0
- package/dist/{middleware-CMr4CHNz-DHIUdxlm.mjs → middleware-yBAfiVWn-DZO0vCRQ.mjs} +3 -3
- package/dist/middleware-yBAfiVWn-DZO0vCRQ.mjs.map +1 -0
- package/dist/{migration-CK4oePIo.mjs → migration-BJQjkqFz.mjs} +4 -4
- package/dist/migration-BJQjkqFz.mjs.map +1 -0
- package/dist/{migration-CjDRZNep.d.mts → migration-Cxmpzaz0.d.mts} +6 -6
- package/dist/migration-Cxmpzaz0.d.mts.map +1 -0
- package/dist/{naming-CV9j2pXl-KARaDReS.d.mts → naming-BcD36g9T-Mfe_xGGL.d.mts} +9 -14
- package/dist/naming-BcD36g9T-Mfe_xGGL.d.mts.map +1 -0
- package/dist/{naming-DKr4TJd7-Cszhq9RV.mjs → naming-bM5qm5PY-jOg3JFMb.mjs} +20 -31
- package/dist/naming-bM5qm5PY-jOg3JFMb.mjs.map +1 -0
- package/dist/{ddl-types-BGdnAbXo-DKPHPUGx.mjs → opaque-sql-Dset3kln-CtsPDTXn.mjs} +24 -11
- package/dist/opaque-sql-Dset3kln-CtsPDTXn.mjs.map +1 -0
- package/dist/operations.d.mts +1 -1
- package/dist/operations.mjs +1 -1
- package/dist/orm-client.d.mts +817 -267
- package/dist/orm-client.d.mts.map +1 -1
- package/dist/orm-client.mjs +4719 -2942
- package/dist/orm-client.mjs.map +1 -1
- package/dist/pack-DA8HZ2mo.d.mts +535 -0
- package/dist/pack-DA8HZ2mo.d.mts.map +1 -0
- package/dist/pack-gSvGQWqs.mjs +80 -0
- package/dist/pack-gSvGQWqs.mjs.map +1 -0
- package/dist/{plan-CDxduYaN-pLIyyJaB.d.mts → plan-Cr4azjnG-CuL8FqXC.d.mts} +12 -8
- package/dist/plan-Cr4azjnG-CuL8FqXC.d.mts.map +1 -0
- package/dist/{plan-Dh0LbYIv-Crx5-ThG.mjs → plan-Dh0LbYIv-ubBSdUgl.mjs} +2 -2
- package/dist/plan-Dh0LbYIv-ubBSdUgl.mjs.map +1 -0
- package/dist/plan-Di6Gs2JD.d.mts +2 -0
- package/dist/psl-attribute-parsing-BCsFWsSp-BJ-wGlY6.mjs +42 -0
- package/dist/psl-attribute-parsing-BCsFWsSp-BJ-wGlY6.mjs.map +1 -0
- package/dist/psl-build-DFBG6vhz.mjs +426 -0
- package/dist/psl-build-DFBG6vhz.mjs.map +1 -0
- package/dist/psl-build-RelubU2E.d.mts +112 -0
- package/dist/psl-build-RelubU2E.d.mts.map +1 -0
- package/dist/psl-column-resolution-ChZqioOc-BREg4J7d.d.mts +24 -0
- package/dist/psl-column-resolution-ChZqioOc-BREg4J7d.d.mts.map +1 -0
- package/dist/psl-field-resolution-C5KQ7kzP-B0NwuRWV.mjs +1960 -0
- package/dist/psl-field-resolution-C5KQ7kzP-B0NwuRWV.mjs.map +1 -0
- package/dist/psl-infer--g4i84Go.mjs +201 -0
- package/dist/psl-infer--g4i84Go.mjs.map +1 -0
- package/dist/psl-infer-DzoxPZGd.d.mts +80 -0
- package/dist/psl-infer-DzoxPZGd.d.mts.map +1 -0
- package/dist/psl-names-C3cwe0rg-D1CTmC3a.mjs +66 -0
- package/dist/psl-names-C3cwe0rg-D1CTmC3a.mjs.map +1 -0
- package/dist/{query-lane-context-Qa-eddrE-kuZ8Z86-.d.mts → query-lane-context-BCEoKy0_-CzmyavC9.d.mts} +20 -49
- package/dist/query-lane-context-BCEoKy0_-CzmyavC9.d.mts.map +1 -0
- package/dist/query-lane-context-VqH0mS9B.d.mts +1 -0
- package/dist/{referential-action-sql-DJ9ps6-S.d.mts → referential-action-sql-B2vKoUK6.d.mts} +3 -3
- package/dist/referential-action-sql-B2vKoUK6.d.mts.map +1 -0
- package/dist/{referential-action-sql-DSqkrySN.mjs → referential-action-sql-BLzCtTi8.mjs} +2 -2
- package/dist/referential-action-sql-BLzCtTi8.mjs.map +1 -0
- package/dist/relational-core.d.mts +14 -13
- package/dist/relational-core.mjs +8 -8
- package/dist/relational-core__aggregate-descriptor-registry.d.mts +2 -2
- package/dist/relational-core__aggregate-descriptor-registry.d.mts.map +1 -1
- package/dist/relational-core__aggregate-descriptor-registry.mjs +1 -1
- package/dist/relational-core__ast.d.mts +5 -5
- package/dist/relational-core__ast.mjs +5 -5
- package/dist/relational-core__codec-descriptor-registry.d.mts +7 -8
- package/dist/relational-core__codec-descriptor-registry.d.mts.map +1 -1
- package/dist/relational-core__codec-descriptor-registry.mjs +1 -1
- package/dist/relational-core__collection-methods.d.mts +3 -0
- package/dist/relational-core__contract-free.d.mts +18 -8
- package/dist/relational-core__contract-free.d.mts.map +1 -1
- package/dist/relational-core__contract-free.mjs +26 -10
- package/dist/relational-core__contract-free.mjs.map +1 -1
- package/dist/relational-core__expression.d.mts +4 -2
- package/dist/relational-core__expression.mjs +2 -2
- package/dist/relational-core__functions.d.mts +2 -0
- package/dist/relational-core__functions.mjs +2 -0
- package/dist/relational-core__index-reference.d.mts +3 -0
- package/dist/relational-core__index-reference.mjs +2 -0
- package/dist/relational-core__middleware.d.mts +2 -2
- package/dist/relational-core__middleware.mjs +1 -1
- package/dist/relational-core__plan.d.mts +4 -4
- package/dist/relational-core__plan.mjs +1 -1
- package/dist/relational-core__query-lane-context.d.mts +3 -3
- package/dist/relational-core__types.d.mts +2 -2
- package/dist/{resolve-storage-table-DZsfnzeW.mjs → resolve-storage-table-BHLQsOza.mjs} +3 -3
- package/dist/resolve-storage-table-BHLQsOza.mjs.map +1 -0
- package/dist/{resolve-storage-table-Nyrgk4h8.d.mts → resolve-storage-table-DCqtmnSU.d.mts} +4 -4
- package/dist/resolve-storage-table-DCqtmnSU.d.mts.map +1 -0
- package/dist/{runtime-tIHpGCcG.mjs → runtime-6tH1yOxK.mjs} +6 -6
- package/dist/runtime-6tH1yOxK.mjs.map +1 -0
- package/dist/{runtime-DpKF2Yu2.d.mts → runtime-CF6rAlE5.d.mts} +7 -8
- package/dist/runtime-CF6rAlE5.d.mts.map +1 -0
- package/dist/runtime.d.mts +5 -5
- package/dist/runtime.mjs +2 -1799
- package/dist/runtime__internal__prepared-query.d.mts +2 -2
- package/dist/runtime__internal__prepared-query.mjs +2 -2
- package/dist/{schema-differ-DpG_gnur-DFAtGezx.d.mts → schema-differ-DmP74bB8-tqHKiJ88.d.mts} +6 -6
- package/dist/schema-differ-DmP74bB8-tqHKiJ88.d.mts.map +1 -0
- package/dist/schema-ir.d.mts +2 -2
- package/dist/schema-ir.mjs +2 -2
- package/dist/schema-ir__naming.d.mts +1 -1
- package/dist/schema-ir__naming.mjs +1 -1
- package/dist/schema-ir__types.d.mts +3 -3
- package/dist/schema-ir__types.mjs +2 -2
- package/dist/{schema-verify-C_PEdlAr-Dxxjm6EM.mjs → schema-verify-C3wbdviw-DMjIubOr.mjs} +50 -8
- package/dist/schema-verify-C3wbdviw-DMjIubOr.mjs.map +1 -0
- package/dist/{serialized-index-CrgG8ct1-DG3JpHc7.d.mts → serialized-index-CrgG8ct1-DKVJ7TDX.d.mts} +4 -4
- package/dist/serialized-index-CrgG8ct1-DKVJ7TDX.d.mts.map +1 -0
- package/dist/{serialized-index-nBTwanKy-_ddEK4tk.mjs → serialized-index-DjCCnXB1-DMA7BtO2.mjs} +4 -4
- package/dist/serialized-index-DjCCnXB1-DMA7BtO2.mjs.map +1 -0
- package/dist/{sql-contract-serializer-2oBWuxTe-DKZTf2n8.mjs → sql-contract-serializer-sMY3prTx-D2BfrNxs.mjs} +41 -16
- package/dist/sql-contract-serializer-sMY3prTx-D2BfrNxs.mjs.map +1 -0
- package/dist/sql-data-type-D7M-YTTY-D2vRqDxn.mjs +400 -0
- package/dist/sql-data-type-D7M-YTTY-D2vRqDxn.mjs.map +1 -0
- package/dist/{sql-execution-plan--jKyLpe5-CMGhgO0M.d.mts → sql-execution-plan-3uxYjHyu-DLknM-Pj.d.mts} +3 -3
- package/dist/sql-execution-plan-3uxYjHyu-DLknM-Pj.d.mts.map +1 -0
- package/dist/sql-expression-B4BrhGPi.d.mts +62 -0
- package/dist/sql-expression-B4BrhGPi.d.mts.map +1 -0
- package/dist/sql-expression-CKgKznXS.mjs +137 -0
- package/dist/sql-expression-CKgKznXS.mjs.map +1 -0
- package/dist/{sql-index-ByAAE7K8-DKj2V86p.d.mts → sql-index-ByAAE7K8-Dqtn_vUL.d.mts} +4 -4
- package/dist/sql-index-ByAAE7K8-Dqtn_vUL.d.mts.map +1 -0
- package/dist/{sql-node-kEz6YFZo-v2F7delx.d.mts → sql-node-kEz6YFZo-1ogT6Cxt.d.mts} +2 -2
- package/dist/sql-node-kEz6YFZo-1ogT6Cxt.d.mts.map +1 -0
- package/dist/{sql-storage-8LqxeLAY-DH4DdUXx.d.mts → sql-storage-DeCAh5Hi-CEM-m8cs.d.mts} +19 -22
- package/dist/sql-storage-DeCAh5Hi-CEM-m8cs.d.mts.map +1 -0
- package/dist/{storage-table-DSeWszOL-CI-cItEK.d.mts → storage-table-Bf1ZjnxO-pUj6pyP0.d.mts} +17 -24
- package/dist/storage-table-Bf1ZjnxO-pUj6pyP0.d.mts.map +1 -0
- package/dist/{storage-table-ZzbR-xzQ-BRoTQE_2.mjs → storage-table-DDvN83mw-DkbBFmK9.mjs} +12 -9
- package/dist/storage-table-DDvN83mw-DkbBFmK9.mjs.map +1 -0
- package/dist/{storage-value-set-BGlj5Uus-CvZD--GG.d.mts → storage-value-set-BGlj5Uus-ny2k-0PA.d.mts} +3 -3
- package/dist/storage-value-set-BGlj5Uus-ny2k-0PA.d.mts.map +1 -0
- package/dist/transaction-state-BfXhs7D7-DhmbySW9.mjs +45 -0
- package/dist/transaction-state-BfXhs7D7-DhmbySW9.mjs.map +1 -0
- package/dist/transaction-state-DR3nKTmH-D29jmVE-.d.mts +115 -0
- package/dist/transaction-state-DR3nKTmH-D29jmVE-.d.mts.map +1 -0
- package/dist/types-B9wSEUsV.d.mts +1 -0
- package/dist/{types-CUsJrvEl.mjs → types-CTdSkl0s.mjs} +13 -6
- package/dist/types-CTdSkl0s.mjs.map +1 -0
- package/dist/types-CkAd8SWm.d.mts +57 -0
- package/dist/types-CkAd8SWm.d.mts.map +1 -0
- package/dist/{types-IqZMLrFC-DcH8v_u3.d.mts → types-Cq6ImLAB-RlU4jJAX.d.mts} +27 -41
- package/dist/types-Cq6ImLAB-RlU4jJAX.d.mts.map +1 -0
- package/dist/{types-YStFFkKs-D9UAmnON.d.mts → types-CuCxAQat-Dz8P4xyt.d.mts} +141 -86
- package/dist/types-CuCxAQat-Dz8P4xyt.d.mts.map +1 -0
- package/dist/types-DfKvtJwS-CrpWTGBJ.d.mts +273 -0
- package/dist/types-DfKvtJwS-CrpWTGBJ.d.mts.map +1 -0
- package/dist/{types-4YenawkP-CwaaZSid.mjs → types-DoyiTsjg-2YMhMJDA.mjs} +181 -80
- package/dist/types-DoyiTsjg-2YMhMJDA.mjs.map +1 -0
- package/dist/{types-v3qxLLxo-DCeKv7yY.d.mts → types-DriMIMNQ-BkbsW7w3.d.mts} +68 -34
- package/dist/types-DriMIMNQ-BkbsW7w3.d.mts.map +1 -0
- package/dist/{types-Dt4e_jC--COeP8xzN.mjs → types-NTQsD2MS-xcLtvKO9.mjs} +83 -17
- package/dist/types-NTQsD2MS-xcLtvKO9.mjs.map +1 -0
- package/dist/{types-CyxGtOOh-BggSa6Fe.d.mts → types-TXO7x1BA-CYYIY8NI.d.mts} +14 -14
- package/dist/types-TXO7x1BA-CYYIY8NI.d.mts.map +1 -0
- package/dist/types-ljUNyiWe.d.mts +1 -0
- package/dist/{unique-constraint-M5TlQnJQ-BiIHJ85k.d.mts → unique-constraint-M5TlQnJQ-qX-maNUV.d.mts} +3 -3
- package/dist/unique-constraint-M5TlQnJQ-qX-maNUV.d.mts.map +1 -0
- package/dist/{util-DQQgv2j1-D6INZaRG.mjs → util-BBgcP3gI-CpL-0VuC.mjs} +12 -3
- package/dist/util-BBgcP3gI-CpL-0VuC.mjs.map +1 -0
- package/dist/{validators-CrWD6bSP.mjs → validators-BwA7ttZM.mjs} +0 -0
- package/dist/validators-BwA7ttZM.mjs.map +1 -0
- package/dist/{validators-Belo8QqM.d.mts → validators-FJs8HvFr.d.mts} +54 -16
- package/dist/validators-FJs8HvFr.d.mts.map +1 -0
- package/dist/{value-set-derivation-hook-BhgGVtw0.d.mts → value-set-derivation-hook-3E437jPU.d.mts} +3 -3
- package/dist/value-set-derivation-hook-3E437jPU.d.mts.map +1 -0
- package/dist/{value-set-derivation-hook-Di9JZ0X7.mjs → value-set-derivation-hook-HVaxhALD.mjs} +2 -2
- package/dist/value-set-derivation-hook-HVaxhALD.mjs.map +1 -0
- package/dist/{verify-u0UTdZgD-DSAaz9rW.mjs → verify-BVk5bjdH-DhKm6hB3.mjs} +8 -7
- package/dist/verify-BVk5bjdH-DhKm6hB3.mjs.map +1 -0
- package/dist/{verify-zDRnw0Rn.d.mts → verify-DHXbuZPB.d.mts} +2 -2
- package/dist/verify-DHXbuZPB.d.mts.map +1 -0
- package/package.json +33 -22
- package/dist/aggregate-descriptor-registry-C7hel5O7.mjs.map +0 -1
- package/dist/ast-HFcfQZr-.d.mts +0 -206
- package/dist/ast-HFcfQZr-.d.mts.map +0 -1
- package/dist/ast-Lbl4VwqP.mjs +0 -325
- package/dist/ast-Lbl4VwqP.mjs.map +0 -1
- package/dist/authored-check-naming-BWBe-PVE.d.mts.map +0 -1
- package/dist/authored-check-naming-Hf9990DV.mjs.map +0 -1
- package/dist/authoring-type-constructors-Blqoa2Ua-DqvNCOb2.mjs +0 -316
- package/dist/authoring-type-constructors-Blqoa2Ua-DqvNCOb2.mjs.map +0 -1
- package/dist/canonicalization-hooks-CYnW_sGn.d.mts.map +0 -1
- package/dist/canonicalization-hooks-dmXkOR4a.mjs.map +0 -1
- package/dist/check-constraint-B7qGu6rc-HvQjjX82.d.mts.map +0 -1
- package/dist/codec-descriptor-registry-N0dhtKaH.mjs.map +0 -1
- package/dist/config-types-D9fdKG3g.d.mts.map +0 -1
- package/dist/config-types-gAm54C_v.mjs.map +0 -1
- package/dist/contract-builder-CG_tGDbB.d.mts +0 -1360
- package/dist/contract-builder-CG_tGDbB.d.mts.map +0 -1
- package/dist/contract-builder-D4a5dT7j.mjs.map +0 -1
- package/dist/contract-errors-BCN6RVI5-5IHBF_lg.mjs.map +0 -1
- package/dist/contract-view-BMR5IWk4.mjs.map +0 -1
- package/dist/contract-view-CPHxoAEX.d.mts.map +0 -1
- package/dist/contract__pack-types.d.mts +0 -2
- package/dist/control-D3cB5YQp.mjs +0 -1267
- package/dist/control-D3cB5YQp.mjs.map +0 -1
- package/dist/control-DTLJ1WtZ.d.mts +0 -945
- package/dist/control-DTLJ1WtZ.d.mts.map +0 -1
- package/dist/control-adapter-C99J7aEF-B7eQd7vD.d.mts.map +0 -1
- package/dist/control-adapter-MZJQiwcE.d.mts +0 -1
- package/dist/db-D18PrXKW-DvTv4JFn.d.mts.map +0 -1
- package/dist/ddl-types-BGdnAbXo-DKPHPUGx.mjs.map +0 -1
- package/dist/ddl-types-CXx4vPz6-BsgrnSUY.d.mts.map +0 -1
- package/dist/derived-checks-DFMRmiAu-DGfB8aS4.mjs +0 -1057
- package/dist/derived-checks-DFMRmiAu-DGfB8aS4.mjs.map +0 -1
- package/dist/derived-checks-DPdD01O0-DGqOFjs6.d.mts.map +0 -1
- package/dist/diff-B16bL_IR.mjs +0 -13
- package/dist/diff-B16bL_IR.mjs.map +0 -1
- package/dist/diff-DbTNVm2f.d.mts.map +0 -1
- package/dist/dist-C_q1_QR9.mjs.map +0 -1
- package/dist/dist-ZK6oeI5e.mjs.map +0 -1
- package/dist/dist-x6jvtkKM.mjs.map +0 -1
- package/dist/driver-types-BQtRkOJ0-Bv2RPSfr.d.mts.map +0 -1
- package/dist/entity-handle-lowering-hook-CIvRKBfa.d.mts.map +0 -1
- package/dist/entity-handle-lowering-hook-DwLIKNiS.mjs +0 -11
- package/dist/entity-handle-lowering-hook-DwLIKNiS.mjs.map +0 -1
- package/dist/entity-kinds-B5cUFU22.d.mts.map +0 -1
- package/dist/entity-kinds-D7vwoN_T-CCBwFJy0.mjs.map +0 -1
- package/dist/errors-B5g0xWro-mWH2C07F.mjs.map +0 -1
- package/dist/expression-CX5mTA-z.mjs.map +0 -1
- package/dist/expression-FJK6Ar-d.d.mts.map +0 -1
- package/dist/factories-P3qBQhO-.d.mts.map +0 -1
- package/dist/factories-SVor5xIT.mjs.map +0 -1
- package/dist/family__pack.d.mts.map +0 -1
- package/dist/family__pack.mjs.map +0 -1
- package/dist/foreign-key-C-iTPuRT-C9ip8zFx.d.mts.map +0 -1
- package/dist/foreign-key-materialization-CkvOzJWy.d.mts +0 -65
- package/dist/foreign-key-materialization-CkvOzJWy.d.mts.map +0 -1
- package/dist/foreign-key-materialization-Cu7-7LHl.mjs +0 -73
- package/dist/foreign-key-materialization-Cu7-7LHl.mjs.map +0 -1
- package/dist/index-C-vQOMY_.d.mts +0 -84
- package/dist/index-C-vQOMY_.d.mts.map +0 -1
- package/dist/index-C5I8D-MB.d.mts.map +0 -1
- package/dist/index-naming-Ct65z5Xk.d.mts.map +0 -1
- package/dist/index-naming-DREt6js7-CRH27yUv.mjs.map +0 -1
- package/dist/index-type-validation-COH4d78M.mjs +0 -17
- package/dist/index-type-validation-COH4d78M.mjs.map +0 -1
- package/dist/index-type-validation-CZ5L2lli.d.mts +0 -10
- package/dist/index-type-validation-CZ5L2lli.d.mts.map +0 -1
- package/dist/index-types-CNhHgKHi.d.mts +0 -1
- package/dist/index-types-DJQ_xwaE.mjs +0 -40
- package/dist/index-types-DJQ_xwaE.mjs.map +0 -1
- package/dist/index-types-DPVhsW0v-D-BikM4h.d.mts +0 -31
- package/dist/index-types-DPVhsW0v-D-BikM4h.d.mts.map +0 -1
- package/dist/interpreter-DyiUUAWh-DYdjIpiE.mjs +0 -3680
- package/dist/interpreter-DyiUUAWh-DYdjIpiE.mjs.map +0 -1
- package/dist/ir-Bghjt-FG.d.mts.map +0 -1
- package/dist/ir-I-xciGUH.mjs.map +0 -1
- package/dist/lane-query-builder.d.mts +0 -236
- package/dist/lane-query-builder.d.mts.map +0 -1
- package/dist/lane-query-builder.mjs +0 -67
- package/dist/lane-query-builder.mjs.map +0 -1
- package/dist/middleware--TtoxUiW.d.mts +0 -1
- package/dist/middleware-AhTz1BOW-th-Suxuf.d.mts.map +0 -1
- package/dist/middleware-CMr4CHNz-DHIUdxlm.mjs.map +0 -1
- package/dist/migration-CK4oePIo.mjs.map +0 -1
- package/dist/migration-CjDRZNep.d.mts.map +0 -1
- package/dist/naming-CV9j2pXl-KARaDReS.d.mts.map +0 -1
- package/dist/naming-DKr4TJd7-Cszhq9RV.mjs.map +0 -1
- package/dist/pack-types-BcLTpwbv.d.mts +0 -14
- package/dist/pack-types-BcLTpwbv.d.mts.map +0 -1
- package/dist/plan-BHLdb0Z7.d.mts +0 -2
- package/dist/plan-CDxduYaN-pLIyyJaB.d.mts.map +0 -1
- package/dist/plan-Dh0LbYIv-Crx5-ThG.mjs.map +0 -1
- package/dist/prepared-query-BJr50wPm-ChoqfJbX.mjs +0 -22
- package/dist/prepared-query-BJr50wPm-ChoqfJbX.mjs.map +0 -1
- package/dist/prepared-statement-9QpkE6JG-C430V3MO.d.mts +0 -529
- package/dist/prepared-statement-9QpkE6JG-C430V3MO.d.mts.map +0 -1
- package/dist/psl-infer-CCAD6FWA.d.mts +0 -119
- package/dist/psl-infer-CCAD6FWA.d.mts.map +0 -1
- package/dist/psl-infer-Dk5kgKre.mjs +0 -362
- package/dist/psl-infer-Dk5kgKre.mjs.map +0 -1
- package/dist/query-lane-context-Qa-eddrE-kuZ8Z86-.d.mts.map +0 -1
- package/dist/query-lane-context-XMvk7fmY.d.mts +0 -1
- package/dist/referential-action-sql-DJ9ps6-S.d.mts.map +0 -1
- package/dist/referential-action-sql-DSqkrySN.mjs.map +0 -1
- package/dist/resolve-storage-table-DZsfnzeW.mjs.map +0 -1
- package/dist/resolve-storage-table-Nyrgk4h8.d.mts.map +0 -1
- package/dist/runtime-DpKF2Yu2.d.mts.map +0 -1
- package/dist/runtime-tIHpGCcG.mjs.map +0 -1
- package/dist/runtime.mjs.map +0 -1
- package/dist/schema-differ-DpG_gnur-DFAtGezx.d.mts.map +0 -1
- package/dist/schema-verify-C_PEdlAr-Dxxjm6EM.mjs.map +0 -1
- package/dist/serialized-index-CrgG8ct1-DG3JpHc7.d.mts.map +0 -1
- package/dist/serialized-index-nBTwanKy-_ddEK4tk.mjs.map +0 -1
- package/dist/sql-contract-serializer-2oBWuxTe-DKZTf2n8.mjs.map +0 -1
- package/dist/sql-execution-plan--jKyLpe5-CMGhgO0M.d.mts.map +0 -1
- package/dist/sql-index-ByAAE7K8-DKj2V86p.d.mts.map +0 -1
- package/dist/sql-node-kEz6YFZo-v2F7delx.d.mts.map +0 -1
- package/dist/sql-storage-8LqxeLAY-DH4DdUXx.d.mts.map +0 -1
- package/dist/storage-table-DSeWszOL-CI-cItEK.d.mts.map +0 -1
- package/dist/storage-table-ZzbR-xzQ-BRoTQE_2.mjs.map +0 -1
- package/dist/storage-value-set-BGlj5Uus-CvZD--GG.d.mts.map +0 -1
- package/dist/timestamp-now-generator-DRXygu32-DN9Qb1uI.mjs +0 -173
- package/dist/timestamp-now-generator-DRXygu32-DN9Qb1uI.mjs.map +0 -1
- package/dist/types-4YenawkP-CwaaZSid.mjs.map +0 -1
- package/dist/types-B0msOnBM.d.mts +0 -1
- package/dist/types-BDUG29Df-LE85dIXP.d.mts +0 -161
- package/dist/types-BDUG29Df-LE85dIXP.d.mts.map +0 -1
- package/dist/types-CUsJrvEl.mjs.map +0 -1
- package/dist/types-CyxGtOOh-BggSa6Fe.d.mts.map +0 -1
- package/dist/types-Dt4e_jC--COeP8xzN.mjs.map +0 -1
- package/dist/types-Dwcw0F8X.d.mts +0 -1
- package/dist/types-IqZMLrFC-DcH8v_u3.d.mts.map +0 -1
- package/dist/types-UcHa2cTe.d.mts +0 -17
- package/dist/types-UcHa2cTe.d.mts.map +0 -1
- package/dist/types-YStFFkKs-D9UAmnON.d.mts.map +0 -1
- package/dist/types-v3qxLLxo-DCeKv7yY.d.mts.map +0 -1
- package/dist/unique-constraint-M5TlQnJQ-BiIHJ85k.d.mts.map +0 -1
- package/dist/util-DQQgv2j1-D6INZaRG.mjs.map +0 -1
- package/dist/validators-Belo8QqM.d.mts.map +0 -1
- package/dist/validators-CrWD6bSP.mjs.map +0 -1
- package/dist/value-set-derivation-hook-BhgGVtw0.d.mts.map +0 -1
- package/dist/value-set-derivation-hook-Di9JZ0X7.mjs.map +0 -1
- package/dist/verify-u0UTdZgD-DSAaz9rW.mjs.map +0 -1
- package/dist/verify-zDRnw0Rn.d.mts.map +0 -1
- /package/dist/{contract__pack-types.mjs → relational-core__collection-methods.mjs} +0 -0
|
@@ -0,0 +1,2011 @@
|
|
|
1
|
+
import { r as lowerAuthoredIndex } from "./index-naming-BOcJT1B3-mG8Fd6KN.mjs";
|
|
2
|
+
import { p as sqlDataTypeOfCodec, u as sqlCodecColumnLength } from "./sql-data-type-D7M-YTTY-D2vRqDxn.mjs";
|
|
3
|
+
import { n as declaredBackingObjectName, r as declaredIndexesServeForeignKey } from "./foreign-key-materialization-BM59w_Xg.mjs";
|
|
4
|
+
import { h as storedSqlText } from "./sql-expression-CKgKznXS.mjs";
|
|
5
|
+
import { p as validateSqlStorageConsistency, u as validateModelStorageReferences } from "./validators-BwA7ttZM.mjs";
|
|
6
|
+
import { t as deriveValueSetFromEntity } from "./value-set-derivation-hook-HVaxhALD.mjs";
|
|
7
|
+
import { n as buildSqlContractFromDefinition, t as applySqlSpecifierControlPolicy } from "./derived-checks-D5HVRvqN-BJx1gwPA.mjs";
|
|
8
|
+
import { c as instantiateFieldTypeConstructor, i as defaultFunctionCall, v as readDataTypeDefault } from "./psl-field-resolution-C5KQ7kzP-B0NwuRWV.mjs";
|
|
9
|
+
import { a as normalizeReferentialAction, n as buildEntityTypesByDiscriminator, r as indexFkRelations, t as applyBackrelationCandidates } from "./interpreter-D5qk4B---CG0C7kdx.mjs";
|
|
10
|
+
import { isStructuredError } from "@prisma/orm-framework/utils/structured-error";
|
|
11
|
+
import { ifDefined } from "@prisma/orm-framework/utils/defined";
|
|
12
|
+
import { entryForTag, getAuthoringTypeConstructor, instantiateAuthoringEntityType, instantiateAuthoringTypeConstructorFromValues } from "@prisma/orm-framework/components/authoring";
|
|
13
|
+
import { clipToUtf8Bytes, utf8ByteLength } from "@prisma/orm-framework/utils/text";
|
|
14
|
+
import { blindCast } from "@prisma/orm-framework/utils/casts";
|
|
15
|
+
import { InternalError } from "@prisma/orm-framework/utils/internal-error";
|
|
16
|
+
import { EMPTY_GENERATOR_FUNCTIONS } from "@prisma/orm-framework/components/components";
|
|
17
|
+
import { validateContractDomain } from "@prisma/orm-framework/contract/validate-domain";
|
|
18
|
+
import { readFile, readdir, stat } from "node:fs/promises";
|
|
19
|
+
import { ArrayLiteralAst, BooleanLiteralExprAst, FunctionCallAst, IdentifierAst, ModelAttributeAst, NumberLiteralExprAst, PathExprAst, StringLiteralExprAst, dottedPathsIn, parse, printSyntax } from "@prisma/orm-framework/psl-parser/syntax";
|
|
20
|
+
import { notOk, ok } from "@prisma/orm-framework/utils/result";
|
|
21
|
+
import { basename, dirname, extname, join, normalize } from "pathe";
|
|
22
|
+
import { assembleAuthoringContributions } from "@prisma/orm-framework/components/control";
|
|
23
|
+
import { EMPTY_DATA_TYPES, buildSymbolTable, createBinder, createPslDiagnosticCollector, diagnosticSource, generatorFunctionCall, keywordPslSpan, mapPslDiagnostics, nodePslSpan, readResolvedAttribute } from "@prisma/orm-framework/psl-parser";
|
|
24
|
+
import { fkRelationPairKey } from "@prisma/orm-framework/psl-parser/interpret";
|
|
25
|
+
import { CUID_VERSION } from "@prisma/orm-framework/ids";
|
|
26
|
+
//#region ../../../2-sql-family/2-authoring/contract-prisma7/dist/provider.mjs
|
|
27
|
+
function prisma7Diagnostic(code, message, sourceId, span) {
|
|
28
|
+
return {
|
|
29
|
+
code,
|
|
30
|
+
message,
|
|
31
|
+
sourceId,
|
|
32
|
+
...span !== void 0 ? { span } : {}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function andList(items) {
|
|
36
|
+
const leading = items.slice(0, -1);
|
|
37
|
+
const last = items[items.length - 1] ?? "";
|
|
38
|
+
return leading.length === 0 ? last : `${leading.join(", ")} and ${last}`;
|
|
39
|
+
}
|
|
40
|
+
function fieldList(modelName, fieldNames) {
|
|
41
|
+
return andList(fieldNames.map((name) => `"${modelName}.${name}"`));
|
|
42
|
+
}
|
|
43
|
+
const UNMAPPED_REASONS = ["ignored", "unsupported"];
|
|
44
|
+
function unmappedClause(reason, one) {
|
|
45
|
+
if (reason === "ignored") return `${one ? "is" : "are"} marked @ignore`;
|
|
46
|
+
return `${one ? "has" : "have"} type Unsupported(...), so the Prisma 8 model has no field for ${one ? "it" : "them"}`;
|
|
47
|
+
}
|
|
48
|
+
/** A field with no Prisma 8 field in the model's primary key: without it the model has no field that identifies a row. */
|
|
49
|
+
function unmappedFieldInPrimaryKey(input) {
|
|
50
|
+
const fields = fieldList(input.modelName, input.fieldNames);
|
|
51
|
+
const one = input.fieldNames.length === 1;
|
|
52
|
+
const modelIgnore = `@@ignore on model "${input.modelName}": Prisma 7 then requires @ignore on every relation field that points to the model, its next migration is empty, Prisma 8 keeps the model's table with its primary key, and the model disappears from both clients.`;
|
|
53
|
+
const edits = input.reason === "ignored" ? `Remove @ignore from ${fields}: Prisma 7's next migration is then empty, and ${one ? "the field appears" : "the fields appear"} in the Prisma 7 client again. Or replace ${one ? "it" : "them"} with ${modelIgnore}` : `Add ${modelIgnore}`;
|
|
54
|
+
return prisma7Diagnostic("PSL.PRISMA7_IGNORED_FIELD_REFERENCED", `${one ? "Field" : "Fields"} ${fields} ${unmappedClause(input.reason, one)}, but ${input.usedBy} uses ${one ? "it" : "them"}, and without ${one ? "it" : "them"} model "${input.modelName}" has no field that identifies a row, so Prisma 8 could not update, delete or relate its rows. ${edits}`, input.sourceId, input.span);
|
|
55
|
+
}
|
|
56
|
+
/** A relation that is not `@ignore` joins on fields with no Prisma 8 field: Prisma 8 relations join on fields. */
|
|
57
|
+
function unmappedFieldJoined(input) {
|
|
58
|
+
const fields = fieldList(input.modelName, input.fieldNames);
|
|
59
|
+
const one = input.fieldNames.length === 1;
|
|
60
|
+
const relation = `relation field "${input.relationField}"`;
|
|
61
|
+
const relationIgnore = `${relation} @ignore${input.reason === "ignored" ? " as well" : ""}: Prisma 7's next migration is then empty, the relation field disappears from the Prisma 7 client, and Prisma 8 keeps its foreign key while leaving the relation out of the contract's models.`;
|
|
62
|
+
const edits = input.reason === "ignored" ? `Remove @ignore from ${fields}: Prisma 7's next migration is then empty, and ${one ? "the field appears" : "the fields appear"} in the Prisma 7 client again. Or mark ${relationIgnore}` : `Mark ${relationIgnore}`;
|
|
63
|
+
return prisma7Diagnostic("PSL.PRISMA7_IGNORED_FIELD_REFERENCED", `${one ? "Field" : "Fields"} ${fields} ${unmappedClause(input.reason, one)}, but ${relation} joins on ${one ? "it" : "them"}, and Prisma 8 relations join on fields. ${edits}`, input.sourceId, input.span);
|
|
64
|
+
}
|
|
65
|
+
/** The diagnostics for the fields among `fieldNames` that have no Prisma 8 field, one per reason. */
|
|
66
|
+
function unmappedFieldDiagnostics(fieldNames, unmapped, diagnostic) {
|
|
67
|
+
return UNMAPPED_REASONS.flatMap((reason) => {
|
|
68
|
+
const names = fieldNames.filter((name) => unmapped.get(name) === reason);
|
|
69
|
+
return names.length === 0 ? [] : [diagnostic(names, reason)];
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function parseIndexAttribute(attribute, owner, sourceId, indexTypes, diagnostics) {
|
|
73
|
+
const unsupported = (what, span) => {
|
|
74
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_INDEX_ARGUMENT_UNSUPPORTED", `"${owner}": @${attribute.name} ${what}`, sourceId, span));
|
|
75
|
+
};
|
|
76
|
+
let fields;
|
|
77
|
+
let map;
|
|
78
|
+
let type;
|
|
79
|
+
for (const arg of attribute.args) {
|
|
80
|
+
const key = arg.kind === "positional" ? "fields" : arg.name;
|
|
81
|
+
const expression = arg.expression;
|
|
82
|
+
switch (key) {
|
|
83
|
+
case "fields": {
|
|
84
|
+
const array = expression === void 0 ? void 0 : ArrayLiteralAst.cast(expression.syntax);
|
|
85
|
+
if (array === void 0) return unsupported("expects a list of field names.", arg.span);
|
|
86
|
+
const names = [];
|
|
87
|
+
for (const element of array.elements()) {
|
|
88
|
+
const path = PathExprAst.cast(element.syntax) ?? FunctionCallAst.cast(element.syntax)?.memberPath();
|
|
89
|
+
if (path !== void 0) return unsupported(`lists the dotted path "${path.path().join(".")}"; an index lists fields of its model by name, and Prisma 7 refuses the path as an unknown field.`, arg.span);
|
|
90
|
+
const name = IdentifierAst.cast(element.syntax)?.name();
|
|
91
|
+
if (name === void 0) return unsupported("field arguments such as sort or length are not supported; Prisma 8 indexes carry none.", arg.span);
|
|
92
|
+
names.push(name);
|
|
93
|
+
}
|
|
94
|
+
fields = names;
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case "map":
|
|
98
|
+
map = expression === void 0 ? void 0 : StringLiteralExprAst.cast(expression.syntax)?.value();
|
|
99
|
+
if (map === void 0) return unsupported("map must be a string.", arg.span);
|
|
100
|
+
break;
|
|
101
|
+
case "name": break;
|
|
102
|
+
case "type": {
|
|
103
|
+
const token = expression === void 0 ? void 0 : IdentifierAst.cast(expression.syntax)?.name();
|
|
104
|
+
type = token !== void 0 && Object.hasOwn(indexTypes, token) ? indexTypes[token] : void 0;
|
|
105
|
+
if (type === void 0) return unsupported(`type "${token ?? ""}" is not an index type Prisma 8 supports.`, arg.span);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
default: return unsupported(`argument "${key ?? ""}" is not supported.`, arg.span);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
fields,
|
|
113
|
+
map,
|
|
114
|
+
type,
|
|
115
|
+
span: attribute.span
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* A generated constraint name as Prisma 7 spells it: `base` cut so that
|
|
120
|
+
* `base + suffix` is at most `maxBytes` bytes, cut on a character boundary,
|
|
121
|
+
* with the suffix kept whole. Prisma 7.10.0 emits `..._aVeryLongCo_idx` for a
|
|
122
|
+
* long `@@index`, `..._AB_pkey` and `..._B_index` for a long implicit junction,
|
|
123
|
+
* and cuts a multi-byte name before the character that would cross the budget.
|
|
124
|
+
*/
|
|
125
|
+
function prisma7ConstraintName(base, suffix, maxBytes) {
|
|
126
|
+
return `${clipToUtf8Bytes(base, maxBytes - utf8ByteLength(suffix))}${suffix}`;
|
|
127
|
+
}
|
|
128
|
+
/** Prisma 7's default index name: `{table}_{columns}_idx`, or `_key` for a unique index, cut to `maxBytes`. */
|
|
129
|
+
function defaultIndexName(tableName, columns, unique, maxBytes) {
|
|
130
|
+
return prisma7ConstraintName(`${tableName}_${columns.join("_")}`, unique ? "_key" : "_idx", maxBytes);
|
|
131
|
+
}
|
|
132
|
+
function indexNode(tableName, columns, attribute, unique, maxBytes) {
|
|
133
|
+
return {
|
|
134
|
+
columns,
|
|
135
|
+
...attribute.type === void 0 ? {
|
|
136
|
+
type: void 0,
|
|
137
|
+
options: void 0
|
|
138
|
+
} : {
|
|
139
|
+
type: attribute.type,
|
|
140
|
+
options: {}
|
|
141
|
+
},
|
|
142
|
+
where: void 0,
|
|
143
|
+
unique: unique ? true : void 0,
|
|
144
|
+
map: attribute.map ?? defaultIndexName(tableName, columns, unique, maxBytes),
|
|
145
|
+
name: void 0
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/** Prisma 7's primary key name: `map`, or `{table}_pkey` cut to `maxBytes`. */
|
|
149
|
+
function prisma7PrimaryKeyName(tableName, map, maxBytes) {
|
|
150
|
+
return map ?? prisma7ConstraintName(tableName, "_pkey", maxBytes);
|
|
151
|
+
}
|
|
152
|
+
/** Prisma 7's foreign key name: `map`, or `{table}_{columns}_fkey` cut to `maxBytes`. */
|
|
153
|
+
function prisma7ForeignKeyName(tableName, columns, map, maxBytes) {
|
|
154
|
+
return map ?? prisma7ConstraintName(`${tableName}_${columns.join("_")}`, "_fkey", maxBytes);
|
|
155
|
+
}
|
|
156
|
+
/** Prisma 7's primary key name for the junction table of an implicit many-to-many relation. */
|
|
157
|
+
function prisma7JunctionPrimaryKeyName(relationName, maxBytes) {
|
|
158
|
+
return prisma7ConstraintName(`_${relationName}`, "_AB_pkey", maxBytes);
|
|
159
|
+
}
|
|
160
|
+
/** Prisma 7's name for the junction foreign key on column `A` or `B`. */
|
|
161
|
+
function prisma7JunctionForeignKeyName(relationName, column, maxBytes) {
|
|
162
|
+
return prisma7ConstraintName(`_${relationName}`, `_${column}_fkey`, maxBytes);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* The name a contract states for a constraint Prisma 7 named `prisma7Name`: the name itself where the target would derive a different one, and `undefined` where the two agree, so the contract stays unnamed there and a table rename keeps deriving it.
|
|
166
|
+
*/
|
|
167
|
+
function statedConstraintName(prisma7Name, derivedName) {
|
|
168
|
+
return prisma7Name === derivedName ? void 0 : prisma7Name;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Refuses a `map` on `@id`, `@@id`, `@unique`, `@@unique`, `@@index` or `@relation` longer than the database keeps, as Prisma 7 does. The database would store the name cut short, so a contract holding it whole would rename or drop a constraint the database does not have.
|
|
172
|
+
*/
|
|
173
|
+
function checkStatedConstraintNameLength(input) {
|
|
174
|
+
const { attribute, maxBytes } = input;
|
|
175
|
+
const mapArgument = attribute.args.find((arg) => arg.kind === "named" && arg.name === "map");
|
|
176
|
+
const expression = mapArgument?.expression;
|
|
177
|
+
const name = expression === void 0 ? void 0 : StringLiteralExprAst.cast(expression.syntax)?.value();
|
|
178
|
+
if (mapArgument === void 0 || name === void 0) return;
|
|
179
|
+
const bytes = utf8ByteLength(name);
|
|
180
|
+
if (bytes <= maxBytes) return;
|
|
181
|
+
const spelling = `${attribute.node instanceof ModelAttributeAst ? "@@" : "@"}${attribute.name}`;
|
|
182
|
+
input.diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_CONSTRAINT_NAME_TOO_LONG", `${input.owner}: the name "${name}" in the map argument of ${spelling} is ${bytes} bytes, longer than the ${maxBytes} bytes the database keeps. Shorten the map to ${maxBytes} bytes or fewer; Prisma 7 refuses this name too.`, input.sourceId, mapArgument.span));
|
|
183
|
+
}
|
|
184
|
+
/** The default functions of Prisma 7's schema language. */
|
|
185
|
+
const PRISMA7_DEFAULT_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
186
|
+
"autoincrement",
|
|
187
|
+
"now",
|
|
188
|
+
"uuid",
|
|
189
|
+
"cuid",
|
|
190
|
+
"nanoid",
|
|
191
|
+
"ulid"
|
|
192
|
+
]);
|
|
193
|
+
function lowerPrisma7Default(input) {
|
|
194
|
+
const { attribute, field, sourceId, diagnostics } = input;
|
|
195
|
+
const label = `Field "${input.modelName}.${field.name}"`;
|
|
196
|
+
const unknown = (reason, span) => {
|
|
197
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_DEFAULT", `${label}: @default ${reason}`, sourceId, span));
|
|
198
|
+
};
|
|
199
|
+
const argument = attribute.args.find((arg) => arg.kind === "positional");
|
|
200
|
+
const expression = argument?.expression;
|
|
201
|
+
if (argument === void 0 || expression === void 0) return unknown("needs one value.", attribute.span);
|
|
202
|
+
const call = FunctionCallAst.cast(expression.syntax);
|
|
203
|
+
if (input.onlyDbgenerated && call?.path().join(".") !== "dbgenerated") return unknown("on a field of type Unsupported(...) must be dbgenerated(\"...\"). Prisma 7 refuses this schema too: \"Only @default(dbgenerated(\"...\")) can be used for Unsupported types.\" Write the default as @default(dbgenerated(\"<sql expression>\")), or remove it.", attribute.span);
|
|
204
|
+
if (call !== void 0) return lowerFunction(call, expression, input, label, unknown);
|
|
205
|
+
const scalar = scalarValue$1(expression, input, unknown);
|
|
206
|
+
if (scalar === void 0) return void 0;
|
|
207
|
+
return {
|
|
208
|
+
storage: {
|
|
209
|
+
kind: "literal",
|
|
210
|
+
value: scalar,
|
|
211
|
+
inStoredForm: true
|
|
212
|
+
},
|
|
213
|
+
onCreate: void 0
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* The stored value of a written default: an enum member resolves through the enum's members, and
|
|
218
|
+
* every other value is read by the authoring entry for its syntax, cast into the column's data type
|
|
219
|
+
* and validated by the column's codec — the same path the current schema language takes.
|
|
220
|
+
*/
|
|
221
|
+
function scalarValue$1(expression, input, unknown) {
|
|
222
|
+
const span = input.attribute.span;
|
|
223
|
+
const enumValue = enumMemberValue$1(expression, input);
|
|
224
|
+
if (enumValue !== void 0) return enumValue;
|
|
225
|
+
const array = ArrayLiteralAst.cast(expression.syntax);
|
|
226
|
+
const elements = array === void 0 ? void 0 : [...array.elements()];
|
|
227
|
+
if (elements?.some((element) => enumMemberValue$1(element, input) !== void 0) === true) {
|
|
228
|
+
const values = [];
|
|
229
|
+
for (const element of elements) {
|
|
230
|
+
const value = enumMemberValue$1(element, input);
|
|
231
|
+
if (value === void 0) return unknown("lists may only hold literals or enum members.", span);
|
|
232
|
+
values.push(value);
|
|
233
|
+
}
|
|
234
|
+
return values;
|
|
235
|
+
}
|
|
236
|
+
const finer = finerThanColumn(elements ?? [expression], elements !== void 0, input);
|
|
237
|
+
if (finer !== void 0) return unknown(finer, span);
|
|
238
|
+
const written = writtenLiteralFor(expression, elements, input);
|
|
239
|
+
if (written === void 0) return unreadableValue(expression, input, unknown);
|
|
240
|
+
const jsonNull = jsonNullDefault(written, expression, input);
|
|
241
|
+
if (jsonNull !== void 0) return jsonNull;
|
|
242
|
+
const read = readDataTypeDefault({
|
|
243
|
+
written,
|
|
244
|
+
isList: input.field.list,
|
|
245
|
+
column: {
|
|
246
|
+
codecId: input.codecId,
|
|
247
|
+
typeParams: input.typeParams
|
|
248
|
+
},
|
|
249
|
+
codecLookup: input.codecLookup,
|
|
250
|
+
dataTypes: input.dataTypes,
|
|
251
|
+
fieldPath: `${input.modelName}.${input.field.name}`
|
|
252
|
+
});
|
|
253
|
+
return read.ok ? read.value : unknown(refusalReason(read.refusal), span);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Why a written date and time is refused when it has more fraction digits than the column holds:
|
|
257
|
+
* Prisma 7 let the database round it, so the reason names the value the database stores.
|
|
258
|
+
*/
|
|
259
|
+
function finerThanColumn(values, isList, input) {
|
|
260
|
+
const form = input.literalForm;
|
|
261
|
+
if (form?.kind !== "tag" || form.finerThanColumn === void 0) return void 0;
|
|
262
|
+
for (const [index, value] of values.entries()) {
|
|
263
|
+
const text = StringLiteralExprAst.cast(value.syntax)?.value();
|
|
264
|
+
const finer = text === void 0 ? void 0 : form.finerThanColumn(text);
|
|
265
|
+
if (text === void 0 || finer === void 0) continue;
|
|
266
|
+
const at = isList ? ` at element ${index + 1}` : "";
|
|
267
|
+
const writtenDigits = /\.(\d+)/.exec(text)?.[1]?.length ?? 0;
|
|
268
|
+
const held = finer.heldDigits === 0 ? "none" : String(finer.heldDigits);
|
|
269
|
+
return `holds "${text}"${at}, with ${writtenDigits} ${writtenDigits === 1 ? "digit" : "digits"} after the decimal point, but the column holds ${held}. PostgreSQL stores it as "${finer.stored}"; write that instead.`;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/** The storage value of an enum member name, when the field is typed by a Prisma 7 enum. */
|
|
273
|
+
function enumMemberValue$1(expression, input) {
|
|
274
|
+
const member = IdentifierAst.cast(expression.syntax)?.name();
|
|
275
|
+
return member === void 0 ? void 0 : input.enumMembers?.get(member);
|
|
276
|
+
}
|
|
277
|
+
function writtenLiteralFor(expression, elements, input) {
|
|
278
|
+
if (elements === void 0) return writtenLiteral(expression, input);
|
|
279
|
+
const written = [];
|
|
280
|
+
for (const element of elements) {
|
|
281
|
+
const elementLiteral = writtenLiteral(element, input);
|
|
282
|
+
if (elementLiteral === void 0) return void 0;
|
|
283
|
+
written.push(elementLiteral);
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
kind: "list",
|
|
287
|
+
elements: written
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* The JSON value null, which the contract cannot tell apart from SQL NULL, reported before the
|
|
292
|
+
* column's codec sees the literal.
|
|
293
|
+
*/
|
|
294
|
+
function jsonNullDefault(written, expression, input) {
|
|
295
|
+
if (input.literalForm?.kind !== "json") return void 0;
|
|
296
|
+
const value = jsonDocumentOf(written, input);
|
|
297
|
+
if (value === void 0) return void 0;
|
|
298
|
+
if (!(Array.isArray(value) ? value.includes(null) : value === null)) return void 0;
|
|
299
|
+
input.diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_JSON_NULL_DEFAULT_UNSUPPORTED", `Field "${input.modelName}.${input.field.name}": @default(${printSyntax(expression.syntax).trim()}) ${written.kind === "list" ? "holds" : "is"} the JSON value null, which the contract cannot tell apart from SQL NULL. Remove the @default or give it another JSON value; either changes the column default on Prisma 7's next migration.`, input.sourceId, input.attribute.span));
|
|
300
|
+
}
|
|
301
|
+
/** A `@default(...)` this contract source cannot read as a literal at all. */
|
|
302
|
+
function unreadableValue(expression, input, unknown) {
|
|
303
|
+
const span = input.attribute.span;
|
|
304
|
+
const identifier = IdentifierAst.cast(expression.syntax)?.name();
|
|
305
|
+
if (identifier !== void 0) return unknown(input.enumMembers === void 0 ? `refers to "${identifier}", but the field is not an enum.` : `refers to "${identifier}", which is not a member of the field's enum.`, span);
|
|
306
|
+
if (ArrayLiteralAst.cast(expression.syntax) !== void 0) return unknown("lists may only hold literals or enum members.", span);
|
|
307
|
+
return unknown("holds a value this contract source does not read.", span);
|
|
308
|
+
}
|
|
309
|
+
/** The written literal a Prisma 7 expression is, or `undefined` when it is not a literal at all. */
|
|
310
|
+
function writtenLiteral(expression, input) {
|
|
311
|
+
const text = StringLiteralExprAst.cast(expression.syntax)?.value();
|
|
312
|
+
if (text !== void 0) {
|
|
313
|
+
const form = input.literalForm;
|
|
314
|
+
if (form?.kind === "json") return {
|
|
315
|
+
kind: "tag",
|
|
316
|
+
tag: "json",
|
|
317
|
+
text
|
|
318
|
+
};
|
|
319
|
+
if (form?.kind === "tag") {
|
|
320
|
+
const body = form.body(text);
|
|
321
|
+
return body === void 0 ? void 0 : {
|
|
322
|
+
kind: "tag",
|
|
323
|
+
tag: form.tag,
|
|
324
|
+
text: body
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
kind: "string",
|
|
329
|
+
text
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
const number = NumberLiteralExprAst.cast(expression.syntax)?.token()?.text;
|
|
333
|
+
if (number !== void 0) return {
|
|
334
|
+
kind: "number",
|
|
335
|
+
text: number
|
|
336
|
+
};
|
|
337
|
+
const boolean = BooleanLiteralExprAst.cast(expression.syntax)?.value();
|
|
338
|
+
return boolean === void 0 ? void 0 : {
|
|
339
|
+
kind: "boolean",
|
|
340
|
+
value: boolean
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* The document a written JSON value holds, read through the same entry the interpreter uses, or
|
|
345
|
+
* `undefined` when the body is not a document.
|
|
346
|
+
*/
|
|
347
|
+
function jsonDocumentOf(written, input) {
|
|
348
|
+
const entry = entryForTag(input.dataTypes, "json");
|
|
349
|
+
if (entry === void 0 || entry.entry.written.kind !== "tag") return void 0;
|
|
350
|
+
const bodies = written.kind === "list" ? written.elements.flatMap((element) => element.kind === "tag" ? [element.text] : []) : written.kind === "tag" ? [written.text] : [];
|
|
351
|
+
const parse = entry.entry.written.parse;
|
|
352
|
+
try {
|
|
353
|
+
const documents = bodies.map((body) => parse(body));
|
|
354
|
+
return written.kind === "list" ? documents : documents[0];
|
|
355
|
+
} catch {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/** Why the column refused the value, as a phrase following `@default `. */
|
|
360
|
+
function refusalReason(refusal) {
|
|
361
|
+
const at = refusal.elementIndex === void 0 ? "" : ` at element ${refusal.elementIndex + 1}`;
|
|
362
|
+
switch (refusal.kind) {
|
|
363
|
+
case "unreadable": return `holds text${at} that this contract source does not read: ${refusal.message}`;
|
|
364
|
+
case "unknown-tag": return `holds a ${refusal.tag} literal${at}, which this stack does not register.`;
|
|
365
|
+
case "unwritable": return `holds a ${refusal.syntax} value${at}, which this target has no data type for.`;
|
|
366
|
+
case "not-a-list": return "holds a single value on a list column, which takes a list literal.";
|
|
367
|
+
case "no-cast": return `holds a ${refusal.valueType} value${at}, which ${refusal.receivingType} has no cast from; ${describeCasts(refusal.casts)}.`;
|
|
368
|
+
case "no-list-cast": return `holds a list, which ${refusal.receivingType} has no cast from; ${describeCasts(refusal.casts)}.`;
|
|
369
|
+
case "no-element-cast": return `holds a ${refusal.valueType} value${at}, which the list cast of ${refusal.receivingType} does not take; it takes ${refusal.elementTypes.join(", ")}.`;
|
|
370
|
+
case "refused-by-column": return `holds a value${at} that ${refusal.codecId} does not read: ${refusal.message}`;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
function describeCasts(casts) {
|
|
374
|
+
return casts.length === 0 ? "it casts from nothing" : `it casts from ${casts.join(", ")}`;
|
|
375
|
+
}
|
|
376
|
+
function lowerFunction(call, expression, input, label, unknown) {
|
|
377
|
+
const fn = call.path().join(".");
|
|
378
|
+
const span = input.attribute.span;
|
|
379
|
+
const callArgs = [...call.args()];
|
|
380
|
+
if (fn === "dbgenerated") return dbgeneratedDefault(callArgs, unknown, span);
|
|
381
|
+
const entry = input.controlMutationDefaults.defaultFunctionRegistry.get(fn);
|
|
382
|
+
const generator = entry === void 0 ? input.generatorFunctions.functionsFor(input.codecId).find(({ name }) => name === fn) : void 0;
|
|
383
|
+
if (!PRISMA7_DEFAULT_FUNCTIONS.has(fn) || entry === void 0 && !input.generatorFunctions.has(fn)) return unknown(`function "${fn}()" is not a Prisma 7 default function this target supports.`, span);
|
|
384
|
+
if (entry === void 0) {
|
|
385
|
+
if (generator === void 0) return unknown(`function "${fn}()" cannot fill a column of codec "${input.codecId}".`, span);
|
|
386
|
+
const args = fn === "cuid" && callArgs.length === 0 ? { version: CUID_VERSION } : boundArguments(generatorFunctionCall(fn, generator.signature, input.dataTypes), expression, input, label);
|
|
387
|
+
if (args === void 0) return void 0;
|
|
388
|
+
const resolution = input.generatorFunctions.resolve({
|
|
389
|
+
name: fn,
|
|
390
|
+
args
|
|
391
|
+
}, {
|
|
392
|
+
codecId: input.codecId,
|
|
393
|
+
typeParams: input.typeParams,
|
|
394
|
+
length: sqlCodecColumnLength(input.dataTypes, input.codecId, input.typeParams)
|
|
395
|
+
});
|
|
396
|
+
if (resolution.ok) return {
|
|
397
|
+
storage: void 0,
|
|
398
|
+
onCreate: resolution.generator
|
|
399
|
+
};
|
|
400
|
+
if (resolution.reason === "refused") {
|
|
401
|
+
const written = input.attribute.args.find((arg) => arg.kind === "positional")?.value.trim() ?? `${fn}()`;
|
|
402
|
+
input.diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_GENERATOR_REFUSED", `${label}: @default(${written}) cannot fill its column: ${resolution.message}`, input.sourceId, span));
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
return unknown(`function "${fn}()" cannot fill a column of codec "${input.codecId}".`, span);
|
|
406
|
+
}
|
|
407
|
+
const args = boundArguments(defaultFunctionCall(fn, entry, input.dataTypes), expression, input, label);
|
|
408
|
+
if (args === void 0) return void 0;
|
|
409
|
+
const lowered = entry.lower({
|
|
410
|
+
call: {
|
|
411
|
+
fn,
|
|
412
|
+
span,
|
|
413
|
+
args
|
|
414
|
+
},
|
|
415
|
+
context: {
|
|
416
|
+
sourceId: input.sourceId,
|
|
417
|
+
modelName: input.modelName,
|
|
418
|
+
fieldName: input.field.name,
|
|
419
|
+
columnCodecId: input.codecId
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
if (!lowered.ok) {
|
|
423
|
+
input.diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_DEFAULT", `${label}: ${lowered.diagnostic.message}`, input.sourceId, span));
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
storage: lowered.value.defaultValue,
|
|
428
|
+
onCreate: void 0
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* The arguments of a call, bound and checked through its function's signature as Prisma 8 PSL binds them, or `undefined` after reporting each refusal at its argument.
|
|
433
|
+
*/
|
|
434
|
+
function boundArguments(arm, expression, input, label) {
|
|
435
|
+
const ctx = input.argumentContext();
|
|
436
|
+
const bound = arm.parse(expression, ctx);
|
|
437
|
+
if (bound.ok) return bound.value.args;
|
|
438
|
+
for (const diagnostic of mapPslDiagnostics(bound.failure, ctx.sources)) input.diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_DEFAULT", `${label}: ${diagnostic.message}`, input.sourceId, diagnostic.span));
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Prisma 7's `dbgenerated("<sql>")` is a raw SQL default, carried as written; the empty form
|
|
442
|
+
* `dbgenerated()` means the column has no default. Prisma 7 refuses a blank string, so this
|
|
443
|
+
* source does too.
|
|
444
|
+
*/
|
|
445
|
+
function dbgeneratedDefault(callArgs, unknown, span) {
|
|
446
|
+
if (callArgs.length === 0) return {
|
|
447
|
+
storage: void 0,
|
|
448
|
+
onCreate: void 0
|
|
449
|
+
};
|
|
450
|
+
const [argument] = callArgs;
|
|
451
|
+
const value = argument?.value();
|
|
452
|
+
const expression = callArgs.length === 1 && argument?.name() === void 0 && value !== void 0 ? StringLiteralExprAst.cast(value.syntax)?.value() : void 0;
|
|
453
|
+
if (expression === void 0 || expression.trim() === "") return unknown("function \"dbgenerated()\" has an argument this contract source does not read.", span);
|
|
454
|
+
return {
|
|
455
|
+
storage: {
|
|
456
|
+
kind: "function",
|
|
457
|
+
expression
|
|
458
|
+
},
|
|
459
|
+
onCreate: void 0
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
function prisma7ScalarMapping(typeMap, scalar) {
|
|
463
|
+
return Object.hasOwn(typeMap.scalars, scalar) ? typeMap.scalars[scalar] : void 0;
|
|
464
|
+
}
|
|
465
|
+
function prisma7NativeTypeMapping(typeMap, nativeType) {
|
|
466
|
+
return Object.hasOwn(typeMap.nativeTypes, nativeType) ? typeMap.nativeTypes[nativeType] : void 0;
|
|
467
|
+
}
|
|
468
|
+
/** The codes `applyBackrelationCandidates` reports, each shown as `PSL.PRISMA7_RELATION_UNRESOLVED`. */
|
|
469
|
+
const RELATION_PAIRING_CODES = /* @__PURE__ */ new Set([
|
|
470
|
+
"PSL_ORPHANED_BACKRELATION",
|
|
471
|
+
"PSL_AMBIGUOUS_BACKRELATION",
|
|
472
|
+
"PSL_NON_UNIQUE_BACKRELATION",
|
|
473
|
+
"PSL_REQUIRED_ONE_TO_ONE_BACKRELATION",
|
|
474
|
+
"PSL_JUNCTION_ID_NOT_FK_COVERING",
|
|
475
|
+
"PSL_JUNCTION_TARGET_FK_NOT_ID"
|
|
476
|
+
]);
|
|
477
|
+
function identifierNames(expression) {
|
|
478
|
+
if (expression === void 0) return void 0;
|
|
479
|
+
const array = ArrayLiteralAst.cast(expression.syntax);
|
|
480
|
+
if (array === void 0) return void 0;
|
|
481
|
+
const names = [];
|
|
482
|
+
for (const element of array.elements()) {
|
|
483
|
+
const name = IdentifierAst.cast(element.syntax)?.name();
|
|
484
|
+
if (name === void 0) return void 0;
|
|
485
|
+
names.push(name);
|
|
486
|
+
}
|
|
487
|
+
return names;
|
|
488
|
+
}
|
|
489
|
+
function stringValue(expression) {
|
|
490
|
+
return expression === void 0 ? void 0 : StringLiteralExprAst.cast(expression.syntax)?.value();
|
|
491
|
+
}
|
|
492
|
+
const PRISMA7_REFERENTIAL_ACTIONS = /* @__PURE__ */ new Set([
|
|
493
|
+
"Cascade",
|
|
494
|
+
"Restrict",
|
|
495
|
+
"NoAction",
|
|
496
|
+
"SetNull",
|
|
497
|
+
"SetDefault"
|
|
498
|
+
]);
|
|
499
|
+
function actionValue(expression) {
|
|
500
|
+
const token = expression === void 0 ? void 0 : IdentifierAst.cast(expression.syntax)?.name();
|
|
501
|
+
return token !== void 0 && PRISMA7_REFERENTIAL_ACTIONS.has(token) ? normalizeReferentialAction(token) : void 0;
|
|
502
|
+
}
|
|
503
|
+
function parseRelationAttribute(attribute, label, sourceId, diagnostics) {
|
|
504
|
+
let name;
|
|
505
|
+
let map;
|
|
506
|
+
let fields;
|
|
507
|
+
let references;
|
|
508
|
+
let onDelete;
|
|
509
|
+
let onUpdate;
|
|
510
|
+
const invalid = (what, span) => {
|
|
511
|
+
diagnostics.push({
|
|
512
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
513
|
+
message: `${label}: @relation ${what}.`,
|
|
514
|
+
sourceId,
|
|
515
|
+
span
|
|
516
|
+
});
|
|
517
|
+
};
|
|
518
|
+
for (const arg of attribute.args) {
|
|
519
|
+
const key = arg.kind === "positional" ? "name" : arg.name;
|
|
520
|
+
switch (key) {
|
|
521
|
+
case "name":
|
|
522
|
+
name = stringValue(arg.expression);
|
|
523
|
+
if (name === void 0) return invalid("name must be a string", arg.span);
|
|
524
|
+
break;
|
|
525
|
+
case "fields":
|
|
526
|
+
fields = identifierNames(arg.expression);
|
|
527
|
+
if (fields === void 0) return invalid("fields must be a list of field names", arg.span);
|
|
528
|
+
break;
|
|
529
|
+
case "references":
|
|
530
|
+
references = identifierNames(arg.expression);
|
|
531
|
+
if (references === void 0) return invalid("references must be a list of field names", arg.span);
|
|
532
|
+
break;
|
|
533
|
+
case "onDelete":
|
|
534
|
+
onDelete = actionValue(arg.expression);
|
|
535
|
+
if (onDelete === void 0) return invalid("onDelete must be a referential action", arg.span);
|
|
536
|
+
break;
|
|
537
|
+
case "onUpdate":
|
|
538
|
+
onUpdate = actionValue(arg.expression);
|
|
539
|
+
if (onUpdate === void 0) return invalid("onUpdate must be a referential action", arg.span);
|
|
540
|
+
break;
|
|
541
|
+
case "map":
|
|
542
|
+
map = stringValue(arg.expression);
|
|
543
|
+
if (map === void 0) return invalid("map must be a string", arg.span);
|
|
544
|
+
break;
|
|
545
|
+
default: return invalid(`argument "${key ?? ""}" is not supported`, arg.span);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return {
|
|
549
|
+
name,
|
|
550
|
+
map,
|
|
551
|
+
fields,
|
|
552
|
+
references,
|
|
553
|
+
onDelete,
|
|
554
|
+
onUpdate,
|
|
555
|
+
span: attribute.span
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
function storageColumn(model, fieldName) {
|
|
559
|
+
return model.columns.get(fieldName) ?? model.unmappedColumns.get(fieldName);
|
|
560
|
+
}
|
|
561
|
+
/** A foreign key reaches a table with a model through the model, and an `@@ignore` model's table by its name. */
|
|
562
|
+
function referenceTo(model, columns) {
|
|
563
|
+
const table = {
|
|
564
|
+
table: model.tableName,
|
|
565
|
+
columns,
|
|
566
|
+
namespaceId: model.namespaceId
|
|
567
|
+
};
|
|
568
|
+
return model.ignored ? table : {
|
|
569
|
+
model: model.modelName,
|
|
570
|
+
...table
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
function columnNames(model, fieldNames) {
|
|
574
|
+
const columns = [];
|
|
575
|
+
for (const fieldName of fieldNames) {
|
|
576
|
+
const column = storageColumn(model, fieldName);
|
|
577
|
+
if (column === void 0) return void 0;
|
|
578
|
+
columns.push(column.columnName);
|
|
579
|
+
}
|
|
580
|
+
return columns;
|
|
581
|
+
}
|
|
582
|
+
function unresolved(label, reason, sourceId, span) {
|
|
583
|
+
return prisma7Diagnostic("PSL.PRISMA7_RELATION_UNRESOLVED", `${label} ${reason}`, sourceId, span);
|
|
584
|
+
}
|
|
585
|
+
function groupBy(items, keyOf) {
|
|
586
|
+
const groups = /* @__PURE__ */ new Map();
|
|
587
|
+
for (const item of items) {
|
|
588
|
+
const group = groups.get(keyOf(item)) ?? [];
|
|
589
|
+
groups.set(keyOf(item), group);
|
|
590
|
+
group.push(item);
|
|
591
|
+
}
|
|
592
|
+
return groups;
|
|
593
|
+
}
|
|
594
|
+
function orderJunctionSides(requester, partner) {
|
|
595
|
+
return (requester.model === partner.model ? requester.field.field.name < partner.field.field.name : requester.model.modelName < partner.model.modelName) ? [requester, partner] : [partner, requester];
|
|
596
|
+
}
|
|
597
|
+
function junctionKey(namespaceId, name) {
|
|
598
|
+
return JSON.stringify([namespaceId, name]);
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Prisma 7's default relation name: the two model names in alphabetical
|
|
602
|
+
* order joined by `To`. Giving every unnamed relation that name lets the
|
|
603
|
+
* shared pairing helper match Prisma 7's rule that an unnamed side pairs only
|
|
604
|
+
* with the unnamed side of the same model pair.
|
|
605
|
+
*/
|
|
606
|
+
function effectiveRelationName(attribute, modelName, targetModelName) {
|
|
607
|
+
if (attribute?.name !== void 0) return attribute.name;
|
|
608
|
+
const [first, second] = modelName < targetModelName ? [modelName, targetModelName] : [targetModelName, modelName];
|
|
609
|
+
return `${first}To${second}`;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Prisma 7 accepts `SetNull` over a required field and `SetDefault` over a
|
|
613
|
+
* required field with no default, and writes them into the foreign key; the
|
|
614
|
+
* contract rejects both, because the action would fail the first time it runs.
|
|
615
|
+
*/
|
|
616
|
+
function referentialActionRejections(input) {
|
|
617
|
+
const { model, relationField, label, fieldNames, span } = input;
|
|
618
|
+
const anotherAction = "choose another action, which replaces the foreign key on Prisma 7's next migration and leaves the Prisma 7 client unchanged.";
|
|
619
|
+
const fieldsWhere = (predicate) => fieldNames.filter((name) => {
|
|
620
|
+
const column = storageColumn(model, name);
|
|
621
|
+
return column !== void 0 && predicate(column);
|
|
622
|
+
});
|
|
623
|
+
const rejections = [];
|
|
624
|
+
for (const [key, action] of Object.entries(input.actions)) {
|
|
625
|
+
if (action === "setNull") {
|
|
626
|
+
const required = fieldsWhere((column) => !column.nullable);
|
|
627
|
+
if (required.length === 0) continue;
|
|
628
|
+
const fields = fieldList(model.modelName, required);
|
|
629
|
+
rejections.push(prisma7Diagnostic("PSL.PRISMA7_REFERENTIAL_ACTION_UNSUPPORTED", `${label}: ${key}: SetNull sets the foreign key fields to null, but ${fields} ${required.length === 1 ? "is" : "are"} required, so Prisma 8 cannot describe this foreign key. Make ${fields}${relationField.optional ? "" : ` and "${model.modelName}.${relationField.name}"`} optional, which drops NOT NULL on Prisma 7's next migration and makes ${required.length === 1 && relationField.optional ? "it" : "them"} nullable in the Prisma 7 client, or ${anotherAction}`, model.sourceId, span));
|
|
630
|
+
}
|
|
631
|
+
if (action === "setDefault") {
|
|
632
|
+
const withoutDefault = fieldsWhere((column) => !column.nullable && column.default === void 0);
|
|
633
|
+
if (withoutDefault.length === 0) continue;
|
|
634
|
+
const fields = fieldList(model.modelName, withoutDefault);
|
|
635
|
+
const one = withoutDefault.length === 1;
|
|
636
|
+
const generated = withoutDefault.filter((name) => model.columns.get(name)?.executionDefaults?.onCreate !== void 0);
|
|
637
|
+
const plain = withoutDefault.filter((name) => !generated.includes(name));
|
|
638
|
+
const generatorNote = generated.length > 0 ? " (a client-side generator such as uuid() does not give the column one)" : "";
|
|
639
|
+
const example = "a column default, such as a literal or @default(dbgenerated(\"<expression>\"))";
|
|
640
|
+
const plainFields = fieldList(model.modelName, plain);
|
|
641
|
+
const generatedFields = fieldList(model.modelName, generated);
|
|
642
|
+
const edit = generated.length === 0 ? `Give ${plainFields} ${example}` : plain.length === 0 ? `Replace the @default on ${generatedFields} with ${example}, because a field takes only one @default` : `Give ${plainFields} ${example}, and replace the @default on ${generatedFields} with one, because a field takes only one @default`;
|
|
643
|
+
const effects = [
|
|
644
|
+
`Prisma 7's next migration sets ${one ? "it" : "them"}`,
|
|
645
|
+
...plain.length > 0 ? [`${plainFields} ${plain.length === 1 ? "becomes" : "become"} optional when creating records with the Prisma 7 client`] : [],
|
|
646
|
+
...generated.length > 0 ? [`the Prisma 7 client stops generating ${generated.length === 1 ? "a value" : "values"} for ${generatedFields}`] : []
|
|
647
|
+
];
|
|
648
|
+
rejections.push(prisma7Diagnostic("PSL.PRISMA7_REFERENTIAL_ACTION_UNSUPPORTED", `${label}: ${key}: SetDefault sets the foreign key fields to their column defaults, but ${fields} ${one ? "is" : "are"} required and ${one ? "has" : "have"} no column default${generatorNote}, so Prisma 8 cannot describe this foreign key. ${edit}: ${andList(effects)}. Or ${anotherAction}`, model.sourceId, span));
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return rejections;
|
|
652
|
+
}
|
|
653
|
+
function lowerRelations(models, naming, diagnostics) {
|
|
654
|
+
const fkRelationMetadata = [];
|
|
655
|
+
const candidates = [];
|
|
656
|
+
const invalidFkPairings = [];
|
|
657
|
+
const foreignKeys = /* @__PURE__ */ new Map();
|
|
658
|
+
const junctions = /* @__PURE__ */ new Map();
|
|
659
|
+
const ignoredJunctions = /* @__PURE__ */ new Map();
|
|
660
|
+
const reportedJunctionNames = /* @__PURE__ */ new Set();
|
|
661
|
+
const junctionRequests = [];
|
|
662
|
+
const addForeignKey = (modelName, node) => {
|
|
663
|
+
const existing = foreignKeys.get(modelName) ?? [];
|
|
664
|
+
foreignKeys.set(modelName, existing);
|
|
665
|
+
existing.push(node);
|
|
666
|
+
};
|
|
667
|
+
const isFkSide = (relationField) => relationField.attribute?.fields !== void 0;
|
|
668
|
+
const sameName = (left, right) => left.attribute?.name === right.attribute?.name;
|
|
669
|
+
const rejectFkSide = (model, relationField, ...rejections) => {
|
|
670
|
+
diagnostics.push(...rejections);
|
|
671
|
+
invalidFkPairings.push({
|
|
672
|
+
pairKey: fkRelationPairKey(model.modelName, relationField.targetModelName),
|
|
673
|
+
relationName: effectiveRelationName(relationField.attribute, model.modelName, relationField.targetModelName)
|
|
674
|
+
});
|
|
675
|
+
};
|
|
676
|
+
for (const model of models.values()) for (const relationField of [...model.relationFields, ...model.ignoredRelationFields]) {
|
|
677
|
+
const { field, targetModelName } = relationField;
|
|
678
|
+
const label = `Relation field "${model.modelName}.${field.name}"`;
|
|
679
|
+
const target = models.get(targetModelName);
|
|
680
|
+
if (target === void 0) continue;
|
|
681
|
+
if (isFkSide(relationField)) {
|
|
682
|
+
const attribute = relationField.attribute;
|
|
683
|
+
if (attribute === void 0 || attribute.fields === void 0) continue;
|
|
684
|
+
const ignoredRelation = model.ignoredRelationFields.includes(relationField);
|
|
685
|
+
const joinedIgnored = ignoredRelation ? [] : [{
|
|
686
|
+
owner: model,
|
|
687
|
+
names: attribute.fields
|
|
688
|
+
}, {
|
|
689
|
+
owner: target,
|
|
690
|
+
names: attribute.references ?? []
|
|
691
|
+
}].flatMap(({ owner, names }) => unmappedFieldDiagnostics(names, owner.unmappedFields, (fieldNames, reason) => unmappedFieldJoined({
|
|
692
|
+
modelName: owner.modelName,
|
|
693
|
+
fieldNames,
|
|
694
|
+
reason,
|
|
695
|
+
relationField: `${model.modelName}.${field.name}`,
|
|
696
|
+
sourceId: model.sourceId,
|
|
697
|
+
span: attribute.span
|
|
698
|
+
})));
|
|
699
|
+
if (joinedIgnored.length > 0) {
|
|
700
|
+
rejectFkSide(model, relationField, ...joinedIgnored);
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
if (attribute.references === void 0) {
|
|
704
|
+
rejectFkSide(model, relationField, unresolved(label, "declares fields without references.", model.sourceId, attribute.span));
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
if (attribute.fields.some((name) => model.rejectedFields.has(name)) || attribute.references.some((name) => target.rejectedFields.has(name))) {
|
|
708
|
+
rejectFkSide(model, relationField);
|
|
709
|
+
continue;
|
|
710
|
+
}
|
|
711
|
+
const localColumns = columnNames(model, attribute.fields);
|
|
712
|
+
const referencedColumns = columnNames(target, attribute.references);
|
|
713
|
+
if (localColumns === void 0 || referencedColumns === void 0) {
|
|
714
|
+
rejectFkSide(model, relationField, unresolved(label, "names a field that is not a scalar column of the model or its target.", model.sourceId, attribute.span));
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
717
|
+
if (localColumns.length !== referencedColumns.length) {
|
|
718
|
+
rejectFkSide(model, relationField, unresolved(label, "must list as many fields as references.", model.sourceId, attribute.span));
|
|
719
|
+
continue;
|
|
720
|
+
}
|
|
721
|
+
const nullability = attribute.fields.map((name) => storageColumn(model, name)?.nullable === true);
|
|
722
|
+
const anyNullable = nullability.includes(true);
|
|
723
|
+
if (anyNullable && !field.optional) {
|
|
724
|
+
rejectFkSide(model, relationField, unresolved(label, "must be optional because one of its fields is optional.", model.sourceId, field.span));
|
|
725
|
+
continue;
|
|
726
|
+
}
|
|
727
|
+
const onDelete = attribute.onDelete ?? (nullability.includes(false) ? "restrict" : "setNull");
|
|
728
|
+
const onUpdate = attribute.onUpdate ?? "cascade";
|
|
729
|
+
const actionRejections = referentialActionRejections({
|
|
730
|
+
model,
|
|
731
|
+
relationField: field,
|
|
732
|
+
label,
|
|
733
|
+
fieldNames: attribute.fields,
|
|
734
|
+
actions: {
|
|
735
|
+
onDelete,
|
|
736
|
+
onUpdate
|
|
737
|
+
},
|
|
738
|
+
span: attribute.span
|
|
739
|
+
});
|
|
740
|
+
if (actionRejections.length > 0) {
|
|
741
|
+
rejectFkSide(model, relationField, ...actionRejections);
|
|
742
|
+
continue;
|
|
743
|
+
}
|
|
744
|
+
const foreignKeyName = statedConstraintName(prisma7ForeignKeyName(model.tableName, localColumns, attribute.map, naming.identifierMaxBytes), naming.defaultConstraintNames.foreignKey(model.tableName, localColumns));
|
|
745
|
+
addForeignKey(model.modelName, {
|
|
746
|
+
...ifDefined("name", foreignKeyName),
|
|
747
|
+
columns: localColumns,
|
|
748
|
+
references: referenceTo(target, referencedColumns),
|
|
749
|
+
onDelete,
|
|
750
|
+
onUpdate,
|
|
751
|
+
index: false
|
|
752
|
+
});
|
|
753
|
+
if (ignoredRelation) continue;
|
|
754
|
+
fkRelationMetadata.push({
|
|
755
|
+
declaringModelName: model.modelName,
|
|
756
|
+
declaringFieldName: field.name,
|
|
757
|
+
declaringTableName: model.tableName,
|
|
758
|
+
declaringNamespaceId: model.namespaceId,
|
|
759
|
+
targetModelName: target.modelName,
|
|
760
|
+
targetTableName: target.tableName,
|
|
761
|
+
targetNamespaceId: target.namespaceId,
|
|
762
|
+
relationName: effectiveRelationName(attribute, model.modelName, target.modelName),
|
|
763
|
+
nullable: anyNullable,
|
|
764
|
+
localColumns,
|
|
765
|
+
referencedColumns
|
|
766
|
+
});
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
769
|
+
const ignoredPair = model.ignoredRelationFields.includes(relationField) || target.ignoredRelationFields.some((other) => other.targetModelName === model.modelName && sameName(other, relationField));
|
|
770
|
+
const targetRelationFields = [...target.relationFields, ...target.ignoredRelationFields];
|
|
771
|
+
if (targetRelationFields.filter((other) => other.targetModelName === model.modelName && isFkSide(other) && sameName(other, relationField)).length > 0 || !field.list) {
|
|
772
|
+
if (ignoredPair) continue;
|
|
773
|
+
candidates.push({
|
|
774
|
+
modelName: model.modelName,
|
|
775
|
+
tableName: model.tableName,
|
|
776
|
+
field,
|
|
777
|
+
targetModelName: target.modelName,
|
|
778
|
+
isList: field.list,
|
|
779
|
+
relationName: effectiveRelationName(relationField.attribute, model.modelName, target.modelName)
|
|
780
|
+
});
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
const partners = targetRelationFields.filter((other) => other !== relationField && other.targetModelName === model.modelName && other.field.list && !isFkSide(other) && sameName(other, relationField));
|
|
784
|
+
const [partner] = partners;
|
|
785
|
+
if (partner === void 0) {
|
|
786
|
+
diagnostics.push(unresolved(label, `has no matching relation field on "${target.modelName}".`, model.sourceId, field.span));
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
if (partners.length > 1 || target === model && relationField.attribute?.name === void 0) {
|
|
790
|
+
diagnostics.push(unresolved(label, `is ambiguous: more than one list field on "${target.modelName}" could pair with it. Name both sides with @relation("name").`, model.sourceId, field.span));
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
793
|
+
const junctionName = effectiveRelationName(relationField.attribute, model.modelName, target.modelName);
|
|
794
|
+
const requester = {
|
|
795
|
+
model,
|
|
796
|
+
field: relationField
|
|
797
|
+
};
|
|
798
|
+
const partnerSide = {
|
|
799
|
+
model: target,
|
|
800
|
+
field: partner
|
|
801
|
+
};
|
|
802
|
+
const junctionNamespaceId = orderJunctionSides(requester, partnerSide)[0].model.namespaceId;
|
|
803
|
+
const namesake = models.get(junctionName);
|
|
804
|
+
if (namesake !== void 0 && namesake.namespaceId === junctionNamespaceId) {
|
|
805
|
+
const reportedKey = junctionKey(junctionNamespaceId, junctionName);
|
|
806
|
+
if (!reportedJunctionNames.has(reportedKey)) {
|
|
807
|
+
reportedJunctionNames.add(reportedKey);
|
|
808
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_JUNCTION_NAME_COLLISION", `${label} is an implicit many-to-many relation whose junction model would be named "${junctionName}", but model "${junctionName}" already has that name. Rename model "${junctionName}" and keep its table with @@map("${namesake.tableName}"); Prisma 7's next migration is then empty.`, model.sourceId, field.span));
|
|
809
|
+
}
|
|
810
|
+
continue;
|
|
811
|
+
}
|
|
812
|
+
junctionRequests.push({
|
|
813
|
+
requester,
|
|
814
|
+
partner: partnerSide,
|
|
815
|
+
name: junctionName,
|
|
816
|
+
ignored: ignoredPair
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
const requestsByJunction = groupBy(junctionRequests, (request) => junctionKey(orderJunctionSides(request.requester, request.partner)[0].model.namespaceId, request.name));
|
|
820
|
+
for (const requests of requestsByJunction.values()) {
|
|
821
|
+
const [first] = requests;
|
|
822
|
+
if (first === void 0) continue;
|
|
823
|
+
const name = first.name;
|
|
824
|
+
const [sideA] = orderJunctionSides(first.requester, first.partner);
|
|
825
|
+
const tableName = prisma7ConstraintName(`_${name}`, "", naming.identifierMaxBytes);
|
|
826
|
+
const sideLabel = (side) => `${side.model.modelName}.${side.field.field.name}`;
|
|
827
|
+
const pairs = /* @__PURE__ */ new Map();
|
|
828
|
+
for (const request of requests) {
|
|
829
|
+
const key = [sideLabel(request.requester), sideLabel(request.partner)].sort().join("|");
|
|
830
|
+
if (!pairs.has(key)) pairs.set(key, request);
|
|
831
|
+
}
|
|
832
|
+
if (pairs.size > 1) {
|
|
833
|
+
const pairRequests = [...pairs.values()];
|
|
834
|
+
for (const request of pairRequests) {
|
|
835
|
+
const others = pairRequests.filter((other) => other !== request).map((other) => `"${sideLabel(other.requester)}"`);
|
|
836
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_RELATION_NAME_SHARED", `Relation field "${sideLabel(request.requester)}" is an implicit many-to-many relation named "${name}", and so ${others.length === 1 ? "is relation field" : "are relation fields"} ${andList(others)}; Prisma 7 creates one table "${tableName}" for them, wired to only one of the relations (its foreign keys show which). Give each relation its own name with @relation("<name>") on both fields: renaming a relation that "${tableName}" does not reference makes Prisma 7's next migration create its own table, while renaming the one it references moves "${tableName}"'s foreign keys to another relation, which fails on rows whose ids that relation's models lack and attaches the rest to the wrong records.`, request.requester.model.sourceId, request.requester.field.field.span));
|
|
837
|
+
}
|
|
838
|
+
continue;
|
|
839
|
+
}
|
|
840
|
+
const tableOwner = [...models.values()].find((other) => other.tableName === tableName && other.namespaceId === sideA.model.namespaceId);
|
|
841
|
+
if (tableOwner !== void 0) {
|
|
842
|
+
const relationField = `${first.requester.model.modelName}.${first.requester.field.field.name}`;
|
|
843
|
+
const message = `Model "${tableOwner.modelName}" and the implicit many-to-many relation "${relationField}" both use table "${tableOwner.namespaceId}"."${tableName}"; Prisma 7 creates the relation's table there and never creates the model's. Rename the model's table with @@map, which makes Prisma 7's next migration create it, or give the relation its own name with @relation("<name>") on both fields, which makes Prisma 7's next migration rebuild "${tableName}" as the model's table and create an empty table for the relation, losing the relation's rows.`;
|
|
844
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_TABLE_COLLISION", message, tableOwner.sourceId, tableOwner.tableSpan), prisma7Diagnostic("PSL.PRISMA7_TABLE_COLLISION", message, first.requester.model.sourceId, first.requester.field.field.span));
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
for (const { requester, partner, ignored } of requests) {
|
|
848
|
+
const junction = synthesizeJunction(requester, partner, naming, diagnostics);
|
|
849
|
+
if (junction === void 0) continue;
|
|
850
|
+
if (ignored) {
|
|
851
|
+
ignoredJunctions.set(junction.key, junction.table);
|
|
852
|
+
continue;
|
|
853
|
+
}
|
|
854
|
+
if (!junctions.has(junction.key)) {
|
|
855
|
+
junctions.set(junction.key, junctionModel(junction.name, junction.table));
|
|
856
|
+
fkRelationMetadata.push(...junction.foreignKeys);
|
|
857
|
+
}
|
|
858
|
+
candidates.push({
|
|
859
|
+
modelName: requester.model.modelName,
|
|
860
|
+
tableName: requester.model.tableName,
|
|
861
|
+
field: requester.field.field,
|
|
862
|
+
targetModelName: partner.model.modelName,
|
|
863
|
+
isList: true,
|
|
864
|
+
relationName: junction.candidateRelationName
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
const { modelRelations, fkRelationsByPair, fkRelationsByDeclaringModel } = indexFkRelations({ fkRelationMetadata });
|
|
869
|
+
const modelIdColumns = /* @__PURE__ */ new Map();
|
|
870
|
+
const modelUniqueColumnSets = /* @__PURE__ */ new Map();
|
|
871
|
+
for (const model of models.values()) {
|
|
872
|
+
const id = columnNames(model, model.idFields);
|
|
873
|
+
if (id !== void 0 && id.length > 0) modelIdColumns.set(model.modelName, id);
|
|
874
|
+
const sets = [];
|
|
875
|
+
if (id !== void 0 && id.length > 0) sets.push(id);
|
|
876
|
+
for (const unique of model.uniqueFieldSets) {
|
|
877
|
+
const columns = columnNames(model, unique);
|
|
878
|
+
if (columns !== void 0) sets.push(columns);
|
|
879
|
+
}
|
|
880
|
+
modelUniqueColumnSets.set(model.modelName, sets);
|
|
881
|
+
}
|
|
882
|
+
for (const key of junctions.keys()) {
|
|
883
|
+
modelIdColumns.set(key, ["A", "B"]);
|
|
884
|
+
modelUniqueColumnSets.set(key, [["A", "B"]]);
|
|
885
|
+
}
|
|
886
|
+
const candidatesBySourceId = /* @__PURE__ */ new Map();
|
|
887
|
+
for (const candidate of candidates) {
|
|
888
|
+
const model = models.get(candidate.modelName);
|
|
889
|
+
if (model === void 0) continue;
|
|
890
|
+
const group = candidatesBySourceId.get(model.sourceId) ?? {
|
|
891
|
+
sources: model.sources,
|
|
892
|
+
candidates: []
|
|
893
|
+
};
|
|
894
|
+
candidatesBySourceId.set(model.sourceId, group);
|
|
895
|
+
group.candidates.push(candidate);
|
|
896
|
+
}
|
|
897
|
+
for (const { sources, candidates: backrelationCandidates } of candidatesBySourceId.values()) {
|
|
898
|
+
const pairingDiagnostics = createPslDiagnosticCollector(sources);
|
|
899
|
+
applyBackrelationCandidates({
|
|
900
|
+
backrelationCandidates,
|
|
901
|
+
fkRelationsByPair,
|
|
902
|
+
invalidFkPairings,
|
|
903
|
+
fkRelationsByDeclaringModel,
|
|
904
|
+
modelIdColumns,
|
|
905
|
+
modelUniqueColumnSets,
|
|
906
|
+
modelRelations,
|
|
907
|
+
diagnostics: pairingDiagnostics,
|
|
908
|
+
sources
|
|
909
|
+
});
|
|
910
|
+
for (const diagnostic of pairingDiagnostics.toExternal()) diagnostics.push(RELATION_PAIRING_CODES.has(diagnostic.code) ? {
|
|
911
|
+
...diagnostic,
|
|
912
|
+
code: "PSL.PRISMA7_RELATION_UNRESOLVED"
|
|
913
|
+
} : diagnostic);
|
|
914
|
+
}
|
|
915
|
+
const relations = /* @__PURE__ */ new Map();
|
|
916
|
+
for (const [modelName, nodes] of modelRelations) relations.set(modelName, [...nodes].sort((left, right) => left.fieldName.localeCompare(right.fieldName)));
|
|
917
|
+
return {
|
|
918
|
+
junctions,
|
|
919
|
+
ignoredJunctions,
|
|
920
|
+
foreignKeys,
|
|
921
|
+
relations
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
/** The junction model over a junction table: a field for each of its columns. */
|
|
925
|
+
function junctionModel(name, table) {
|
|
926
|
+
const { columns, ...properties } = table;
|
|
927
|
+
return {
|
|
928
|
+
...properties,
|
|
929
|
+
modelName: name,
|
|
930
|
+
fields: columns.map((column) => ({
|
|
931
|
+
fieldName: column.columnName,
|
|
932
|
+
...column
|
|
933
|
+
}))
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* The id column a junction side contributes. The diagnostic names the
|
|
938
|
+
* requesting relation field, so it is located at that field, whichever side's
|
|
939
|
+
* id is at fault.
|
|
940
|
+
*/
|
|
941
|
+
function singleIdColumn(side, requester, diagnostics) {
|
|
942
|
+
if (side.model.idFields.some((name) => side.model.unmappedFields.has(name) || side.model.rejectedFields.has(name))) return;
|
|
943
|
+
const [idField, ...rest] = side.model.idFields;
|
|
944
|
+
const column = idField === void 0 ? void 0 : storageColumn(side.model, idField);
|
|
945
|
+
if (column === void 0 || rest.length > 0) {
|
|
946
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_JUNCTION_ID_UNSUPPORTED", `Relation field "${requester.model.modelName}.${requester.field.field.name}" is an implicit many-to-many relation, but "${side.model.modelName}" ${column === void 0 ? "has no single-field @id" : "has a composite id"}; Prisma 7 requires a single-field @id on both models of an implicit many-to-many relation.`, requester.model.sourceId, requester.field.field.span));
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
return column;
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Prisma 7's implicit junction: table `_AToB` (or `_Name`), columns `A` and `B`
|
|
953
|
+
* typed like the two ids, primary key `(A, B)`, index `_AToB_B_index`, and two
|
|
954
|
+
* cascading foreign keys, with relation fields named as `contract infer` names
|
|
955
|
+
* them. `A` is the model whose name is smaller in plain
|
|
956
|
+
* string order; for a self-relation, the field whose name is smaller. This is
|
|
957
|
+
* prisma-engines' rule (`psl/parser-database/src/relations.rs`,
|
|
958
|
+
* `ingest_relation`: the side with the greater model name, or field name for a
|
|
959
|
+
* self relation, is skipped so the smaller one owns `field_a`).
|
|
960
|
+
*/
|
|
961
|
+
function synthesizeJunction(requester, partner, naming, diagnostics) {
|
|
962
|
+
const [sideA, sideB] = orderJunctionSides(requester, partner);
|
|
963
|
+
const requesterFirst = sideA === requester;
|
|
964
|
+
const name = requester.field.attribute?.name ?? `${sideA.model.modelName}To${sideB.model.modelName}`;
|
|
965
|
+
const idA = singleIdColumn(sideA, requester, diagnostics);
|
|
966
|
+
const idB = singleIdColumn(sideB, requester, diagnostics);
|
|
967
|
+
if (idA === void 0 || idB === void 0) return void 0;
|
|
968
|
+
const tableName = prisma7ConstraintName(`_${name}`, "", naming.identifierMaxBytes);
|
|
969
|
+
const namespaceId = sideA.model.namespaceId;
|
|
970
|
+
const key = junctionKey(namespaceId, name);
|
|
971
|
+
const [relationFieldA, relationFieldB] = naming.junctionRelationFieldNames(sideA.model.tableName, sideB.model.tableName);
|
|
972
|
+
const foreignKeyName = (column) => statedConstraintName(prisma7JunctionForeignKeyName(name, column, naming.identifierMaxBytes), naming.defaultConstraintNames.foreignKey(tableName, [column]));
|
|
973
|
+
const primaryKeyName = statedConstraintName(prisma7JunctionPrimaryKeyName(name, naming.identifierMaxBytes), naming.defaultConstraintNames.primaryKey(tableName));
|
|
974
|
+
const foreignKey = (column, side, id) => ({
|
|
975
|
+
...ifDefined("name", foreignKeyName(column)),
|
|
976
|
+
columns: [column],
|
|
977
|
+
references: referenceTo(side.model, [id.columnName]),
|
|
978
|
+
onDelete: "cascade",
|
|
979
|
+
onUpdate: "cascade",
|
|
980
|
+
index: false
|
|
981
|
+
});
|
|
982
|
+
const metadata = (column, side, id) => ({
|
|
983
|
+
declaringModelName: key,
|
|
984
|
+
declaringFieldName: column === "A" ? relationFieldA : relationFieldB,
|
|
985
|
+
declaringTableName: tableName,
|
|
986
|
+
declaringNamespaceId: namespaceId,
|
|
987
|
+
targetModelName: side.model.modelName,
|
|
988
|
+
targetTableName: side.model.tableName,
|
|
989
|
+
targetNamespaceId: side.model.namespaceId,
|
|
990
|
+
relationName: `${name}:${column}`,
|
|
991
|
+
nullable: false,
|
|
992
|
+
localColumns: [column],
|
|
993
|
+
referencedColumns: [id.columnName]
|
|
994
|
+
});
|
|
995
|
+
const index = {
|
|
996
|
+
columns: ["B"],
|
|
997
|
+
type: void 0,
|
|
998
|
+
options: void 0,
|
|
999
|
+
where: void 0,
|
|
1000
|
+
unique: void 0,
|
|
1001
|
+
map: prisma7ConstraintName(`_${name}`, "_B_index", naming.identifierMaxBytes),
|
|
1002
|
+
name: void 0
|
|
1003
|
+
};
|
|
1004
|
+
return {
|
|
1005
|
+
key,
|
|
1006
|
+
name,
|
|
1007
|
+
table: {
|
|
1008
|
+
tableName,
|
|
1009
|
+
namespaceId,
|
|
1010
|
+
columns: [{
|
|
1011
|
+
columnName: "A",
|
|
1012
|
+
descriptor: idA.descriptor,
|
|
1013
|
+
nullable: false,
|
|
1014
|
+
many: false
|
|
1015
|
+
}, {
|
|
1016
|
+
columnName: "B",
|
|
1017
|
+
descriptor: idB.descriptor,
|
|
1018
|
+
nullable: false,
|
|
1019
|
+
many: false
|
|
1020
|
+
}],
|
|
1021
|
+
id: {
|
|
1022
|
+
columns: ["A", "B"],
|
|
1023
|
+
...ifDefined("name", primaryKeyName)
|
|
1024
|
+
},
|
|
1025
|
+
indexes: [index],
|
|
1026
|
+
foreignKeys: [foreignKey("A", sideA, idA), foreignKey("B", sideB, idB)]
|
|
1027
|
+
},
|
|
1028
|
+
foreignKeys: [metadata("A", sideA, idA), metadata("B", sideB, idB)],
|
|
1029
|
+
candidateRelationName: requesterFirst ? `${name}:A` : `${name}:B`
|
|
1030
|
+
};
|
|
1031
|
+
}
|
|
1032
|
+
/** The generator `now()` resolves to for a column, which `@updatedAt` writes on create and on update; `undefined` when no generator function binds `now` to its codec. */
|
|
1033
|
+
function nowGeneratorFor(generatorFunctions, dataTypes, column) {
|
|
1034
|
+
const resolution = generatorFunctions.resolve({
|
|
1035
|
+
name: "now",
|
|
1036
|
+
args: {}
|
|
1037
|
+
}, {
|
|
1038
|
+
codecId: column.codecId,
|
|
1039
|
+
typeParams: column.typeParams,
|
|
1040
|
+
length: sqlCodecColumnLength(dataTypes, column.codecId, column.typeParams)
|
|
1041
|
+
});
|
|
1042
|
+
return resolution.ok ? resolution.generator : void 0;
|
|
1043
|
+
}
|
|
1044
|
+
const SUMMARY = "Prisma 7 schema interpretation failed";
|
|
1045
|
+
/**
|
|
1046
|
+
* The binder context of a Prisma 7 document's argument context. A default function's arguments are literals, so the binder needs no Prisma 8 attribute specs, functions or data types.
|
|
1047
|
+
*/
|
|
1048
|
+
const ARGUMENT_BINDER_CONTEXT = {
|
|
1049
|
+
authoringContributions: assembleAuthoringContributions([]),
|
|
1050
|
+
controlMutationDefaults: { defaultFunctionRegistry: /* @__PURE__ */ new Map() },
|
|
1051
|
+
generatorFunctions: EMPTY_GENERATOR_FUNCTIONS,
|
|
1052
|
+
dataTypes: EMPTY_DATA_TYPES
|
|
1053
|
+
};
|
|
1054
|
+
function stringArgument(attribute) {
|
|
1055
|
+
const expression = (attribute.args.find((arg) => arg.kind === "positional") ?? attribute.args.find((arg) => arg.name === "name"))?.expression;
|
|
1056
|
+
if (expression === void 0) return void 0;
|
|
1057
|
+
return StringLiteralExprAst.cast(expression.syntax)?.value();
|
|
1058
|
+
}
|
|
1059
|
+
function blockEntry(source, key) {
|
|
1060
|
+
for (const entry of source.block.entries) if (entry.key()?.name() === key) return entry;
|
|
1061
|
+
}
|
|
1062
|
+
function scalarValue(source, key) {
|
|
1063
|
+
const value = blockEntry(source, key)?.value();
|
|
1064
|
+
if (value === void 0) return void 0;
|
|
1065
|
+
return StringLiteralExprAst.cast(value.syntax)?.value();
|
|
1066
|
+
}
|
|
1067
|
+
function parameterSpan(source, key) {
|
|
1068
|
+
const entry = blockEntry(source, key);
|
|
1069
|
+
return entry === void 0 ? source.block.span : nodePslSpan(entry.syntax, source.sources);
|
|
1070
|
+
}
|
|
1071
|
+
/** Prisma 7 accepts no dotted path in a datasource or generator block, though the parser reads one as a value. */
|
|
1072
|
+
function reportDottedBlockValues(block, sourceId, sources, diagnostics) {
|
|
1073
|
+
for (const entry of block.entries) {
|
|
1074
|
+
const value = entry.value();
|
|
1075
|
+
if (value === void 0) continue;
|
|
1076
|
+
for (const path of dottedPathsIn(value)) diagnostics.push({
|
|
1077
|
+
code: "PSL_INVALID_EXTENSION_BLOCK_MEMBER",
|
|
1078
|
+
message: `${block.keyword} "${block.name}": the value of "${entry.key()?.name() ?? ""}" holds the dotted path ${path.path().join(".")}, which Prisma 7 does not accept in a ${block.keyword} block.`,
|
|
1079
|
+
sourceId,
|
|
1080
|
+
span: nodePslSpan(path.syntax, sources)
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
function reportDuplicateBlockEntries(source, diagnostics) {
|
|
1085
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1086
|
+
for (const entry of source.block.entries) {
|
|
1087
|
+
const key = entry.key()?.name();
|
|
1088
|
+
if (key === void 0) continue;
|
|
1089
|
+
if (seen.has(key)) {
|
|
1090
|
+
diagnostics.push({
|
|
1091
|
+
code: "PSL_EXTENSION_DUPLICATE_PARAMETER",
|
|
1092
|
+
message: `Duplicate parameter "${key}" in "${source.block.keyword}" block "${source.block.name}"; first occurrence wins`,
|
|
1093
|
+
sourceId: source.sourceId,
|
|
1094
|
+
span: nodePslSpan(entry.syntax, source.sources)
|
|
1095
|
+
});
|
|
1096
|
+
continue;
|
|
1097
|
+
}
|
|
1098
|
+
seen.add(key);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
function interpretPrisma7Documents(input) {
|
|
1102
|
+
const { binding } = input;
|
|
1103
|
+
const diagnostics = [...input.seedDiagnostics];
|
|
1104
|
+
const { defaultNamespaceId } = input;
|
|
1105
|
+
const datasources = [];
|
|
1106
|
+
const enumBlocks = [];
|
|
1107
|
+
const models = [];
|
|
1108
|
+
const declaredNames = /* @__PURE__ */ new Map();
|
|
1109
|
+
const claimName = (kind, name, sourceId, span) => {
|
|
1110
|
+
const previous = declaredNames.get(name);
|
|
1111
|
+
if (previous === void 0) {
|
|
1112
|
+
declaredNames.set(name, sourceId);
|
|
1113
|
+
return true;
|
|
1114
|
+
}
|
|
1115
|
+
diagnostics.push({
|
|
1116
|
+
code: "PSL_DUPLICATE_DECLARATION",
|
|
1117
|
+
message: `Duplicate declaration of ${kind} "${name}"; first declared in ${basename(previous)}.`,
|
|
1118
|
+
sourceId,
|
|
1119
|
+
span
|
|
1120
|
+
});
|
|
1121
|
+
return false;
|
|
1122
|
+
};
|
|
1123
|
+
for (const { document, sources, sourceFile, sourceId } of input.documents) {
|
|
1124
|
+
const { symbolTable, diagnostics: tableDiagnostics } = buildSymbolTable({
|
|
1125
|
+
documents: [document],
|
|
1126
|
+
sources,
|
|
1127
|
+
defaultNamespaceId
|
|
1128
|
+
});
|
|
1129
|
+
for (const diagnostic of tableDiagnostics) diagnostics.push({
|
|
1130
|
+
code: diagnostic.code,
|
|
1131
|
+
message: diagnostic.message,
|
|
1132
|
+
sourceId,
|
|
1133
|
+
span: sourceFile.rangeToPslSpan(diagnostic.range)
|
|
1134
|
+
});
|
|
1135
|
+
const unsupported = (keyword, span) => {
|
|
1136
|
+
diagnostics.push({
|
|
1137
|
+
code: "PSL_UNSUPPORTED_TOP_LEVEL_BLOCK",
|
|
1138
|
+
message: `Unsupported top-level block "${keyword}"`,
|
|
1139
|
+
sourceId,
|
|
1140
|
+
span
|
|
1141
|
+
});
|
|
1142
|
+
};
|
|
1143
|
+
const unsupportedInclusions = (code, holders) => {
|
|
1144
|
+
for (const holder of Object.values(holders)) for (const inclusion of holder.node.inclusions()) diagnostics.push({
|
|
1145
|
+
code,
|
|
1146
|
+
message: `Unsupported mixin inclusion "${printSyntax(inclusion.syntax).trim()}"`,
|
|
1147
|
+
sourceId,
|
|
1148
|
+
span: nodePslSpan(inclusion.syntax, sources)
|
|
1149
|
+
});
|
|
1150
|
+
};
|
|
1151
|
+
for (const block of Object.values(symbolTable.defaultNamespace.blocks)) switch (block.keyword) {
|
|
1152
|
+
case "datasource":
|
|
1153
|
+
datasources.push({
|
|
1154
|
+
block,
|
|
1155
|
+
sourceId,
|
|
1156
|
+
sources,
|
|
1157
|
+
sourceFile
|
|
1158
|
+
});
|
|
1159
|
+
reportDottedBlockValues(block, sourceId, sources, diagnostics);
|
|
1160
|
+
break;
|
|
1161
|
+
case "generator":
|
|
1162
|
+
reportDottedBlockValues(block, sourceId, sources, diagnostics);
|
|
1163
|
+
break;
|
|
1164
|
+
case "enum":
|
|
1165
|
+
if (claimName("enum", block.name, sourceId, block.span)) enumBlocks.push({
|
|
1166
|
+
block,
|
|
1167
|
+
sourceId,
|
|
1168
|
+
sources,
|
|
1169
|
+
sourceFile
|
|
1170
|
+
});
|
|
1171
|
+
break;
|
|
1172
|
+
case "view":
|
|
1173
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_VIEW_UNSUPPORTED", `View "${block.name}" is not supported; Prisma 8 has no views. Remove the view or replace it with a model over the underlying table.`, sourceId, keywordPslSpan(block.node.syntax, block.keyword, sources)));
|
|
1174
|
+
break;
|
|
1175
|
+
default: unsupported(block.keyword, keywordPslSpan(block.node.syntax, block.keyword, sources));
|
|
1176
|
+
}
|
|
1177
|
+
for (const namespace of Object.values(symbolTable.namespaces)) for (const { span } of namespace.declarations) unsupported("namespace", span);
|
|
1178
|
+
for (const compositeType of Object.values(symbolTable.defaultNamespace.compositeTypes)) unsupported("type", compositeType.span);
|
|
1179
|
+
for (const namedType of Object.values(symbolTable.namedTypes)) unsupported("types", namedType.span);
|
|
1180
|
+
for (const mixin of Object.values(symbolTable.defaultNamespace.mixins)) unsupported(`${mixin.keyword} mixin`, mixin.span);
|
|
1181
|
+
unsupportedInclusions("PSL_INVALID_MODEL_MEMBER", symbolTable.defaultNamespace.models);
|
|
1182
|
+
unsupportedInclusions("PSL_INVALID_EXTENSION_BLOCK_MEMBER", symbolTable.defaultNamespace.blocks);
|
|
1183
|
+
let argumentContext;
|
|
1184
|
+
const argumentContextOf = () => {
|
|
1185
|
+
argumentContext ??= {
|
|
1186
|
+
sources,
|
|
1187
|
+
symbols: symbolTable,
|
|
1188
|
+
binder: createBinder({
|
|
1189
|
+
sources,
|
|
1190
|
+
symbolTable,
|
|
1191
|
+
context: ARGUMENT_BINDER_CONTEXT
|
|
1192
|
+
}).binder
|
|
1193
|
+
};
|
|
1194
|
+
return argumentContext;
|
|
1195
|
+
};
|
|
1196
|
+
for (const symbol of Object.values(symbolTable.defaultNamespace.models)) {
|
|
1197
|
+
if (!claimName("model", symbol.name, sourceId, symbol.span)) continue;
|
|
1198
|
+
models.push(readModelDeclaration(symbol, sourceId, sources, defaultNamespaceId, binding, diagnostics, argumentContextOf));
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
checkDatasource(datasources, input.documents[0]?.sourceId ?? "schema.prisma", binding, diagnostics);
|
|
1202
|
+
reportTableCollisions(models, diagnostics);
|
|
1203
|
+
const enums = /* @__PURE__ */ new Map();
|
|
1204
|
+
for (const source of enumBlocks) {
|
|
1205
|
+
const declaration = readEnumDeclaration(source, defaultNamespaceId, diagnostics);
|
|
1206
|
+
if (declaration !== void 0) enums.set(declaration.name, declaration);
|
|
1207
|
+
}
|
|
1208
|
+
const namespaceEntities = lowerNativeEnums(enums, input, diagnostics);
|
|
1209
|
+
const modelNames = new Set(models.map((model) => model.symbol.name));
|
|
1210
|
+
const ignoredModels = new Set(models.filter((model) => model.ignored).map((model) => model.symbol.name));
|
|
1211
|
+
const composedExtensions = new Set(input.composedExtensions);
|
|
1212
|
+
const builds = /* @__PURE__ */ new Map();
|
|
1213
|
+
for (const declaration of models) {
|
|
1214
|
+
const build = {
|
|
1215
|
+
declaration,
|
|
1216
|
+
columns: /* @__PURE__ */ new Map(),
|
|
1217
|
+
unmappedColumns: /* @__PURE__ */ new Map(),
|
|
1218
|
+
unmappedFields: /* @__PURE__ */ new Map(),
|
|
1219
|
+
ignoredRelationFields: [],
|
|
1220
|
+
rejectedFields: /* @__PURE__ */ new Set(),
|
|
1221
|
+
idFields: declaration.id?.fields ?? [],
|
|
1222
|
+
idMap: declaration.id?.map,
|
|
1223
|
+
uniqueIndexes: [...declaration.uniqueIndexes],
|
|
1224
|
+
relationFields: []
|
|
1225
|
+
};
|
|
1226
|
+
for (const field of Object.values(declaration.symbol.fields)) {
|
|
1227
|
+
const reported = diagnostics.length;
|
|
1228
|
+
readField({
|
|
1229
|
+
field,
|
|
1230
|
+
build,
|
|
1231
|
+
modelNames,
|
|
1232
|
+
ignoredModels,
|
|
1233
|
+
enums,
|
|
1234
|
+
namespaceEntities,
|
|
1235
|
+
composedExtensions,
|
|
1236
|
+
input,
|
|
1237
|
+
diagnostics
|
|
1238
|
+
});
|
|
1239
|
+
if (diagnostics.length > reported && !build.columns.has(field.name) && !build.unmappedColumns.has(field.name)) build.rejectedFields.add(field.name);
|
|
1240
|
+
}
|
|
1241
|
+
builds.set(declaration.symbol.name, build);
|
|
1242
|
+
}
|
|
1243
|
+
const relationModels = /* @__PURE__ */ new Map();
|
|
1244
|
+
for (const [modelName, build] of builds) relationModels.set(modelName, {
|
|
1245
|
+
modelName,
|
|
1246
|
+
tableName: build.declaration.tableName,
|
|
1247
|
+
ignored: build.declaration.ignored,
|
|
1248
|
+
tableSpan: build.declaration.symbol.attributes.find((attribute) => attribute.name === "map")?.span ?? build.declaration.symbol.span,
|
|
1249
|
+
namespaceId: build.declaration.namespaceId,
|
|
1250
|
+
sourceId: build.declaration.sourceId,
|
|
1251
|
+
sources: build.declaration.sources,
|
|
1252
|
+
columns: build.columns,
|
|
1253
|
+
unmappedColumns: build.unmappedColumns,
|
|
1254
|
+
unmappedFields: build.unmappedFields,
|
|
1255
|
+
ignoredRelationFields: build.ignoredRelationFields,
|
|
1256
|
+
rejectedFields: build.rejectedFields,
|
|
1257
|
+
idFields: build.idFields,
|
|
1258
|
+
uniqueFieldSets: build.uniqueIndexes.flatMap((index) => index.fields === void 0 ? [] : [index.fields]),
|
|
1259
|
+
relationFields: build.relationFields
|
|
1260
|
+
});
|
|
1261
|
+
const lowered = lowerRelations(relationModels, binding, diagnostics);
|
|
1262
|
+
const modelNodes = [];
|
|
1263
|
+
const tables = [];
|
|
1264
|
+
for (const [modelName, build] of builds) {
|
|
1265
|
+
const model = relationModels.get(modelName);
|
|
1266
|
+
if (model === void 0) continue;
|
|
1267
|
+
const idAttribute = build.declaration.id;
|
|
1268
|
+
if (idAttribute?.fields !== void 0) diagnostics.push(...unmappedFieldDiagnostics(idAttribute.fields, build.unmappedFields, (fieldNames, reason) => unmappedFieldInPrimaryKey({
|
|
1269
|
+
modelName,
|
|
1270
|
+
fieldNames,
|
|
1271
|
+
reason,
|
|
1272
|
+
usedBy: `@@id on model "${modelName}"`,
|
|
1273
|
+
sourceId: model.sourceId,
|
|
1274
|
+
span: idAttribute.span
|
|
1275
|
+
})));
|
|
1276
|
+
const id = keyColumns(model, model.idFields);
|
|
1277
|
+
const indexes = [...build.uniqueIndexes.map((attribute) => ({
|
|
1278
|
+
attribute,
|
|
1279
|
+
unique: true
|
|
1280
|
+
})), ...build.declaration.indexes.map((attribute) => ({
|
|
1281
|
+
attribute,
|
|
1282
|
+
unique: false
|
|
1283
|
+
}))].flatMap(({ attribute, unique }) => {
|
|
1284
|
+
if (attribute.fields?.some((name) => build.rejectedFields.has(name))) return [];
|
|
1285
|
+
const columns = attribute.fields === void 0 ? void 0 : keyColumns(model, attribute.fields);
|
|
1286
|
+
if (columns === void 0) {
|
|
1287
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_INDEX_ARGUMENT_UNSUPPORTED", `Model "${modelName}": an index names a field that is not a scalar column of the model.`, model.sourceId, attribute.span));
|
|
1288
|
+
return [];
|
|
1289
|
+
}
|
|
1290
|
+
return [indexNode(model.tableName, columns, attribute, unique, binding.identifierMaxBytes)];
|
|
1291
|
+
});
|
|
1292
|
+
const foreignKeys = lowered.foreignKeys.get(modelName);
|
|
1293
|
+
const relations = lowered.relations.get(modelName);
|
|
1294
|
+
const primaryKeyName = statedConstraintName(prisma7PrimaryKeyName(model.tableName, build.idMap, binding.identifierMaxBytes), binding.defaultConstraintNames.primaryKey(model.tableName));
|
|
1295
|
+
const tableProperties = stateServedBackingIndexes({
|
|
1296
|
+
tableName: model.tableName,
|
|
1297
|
+
...id !== void 0 && id.length > 0 ? { id: {
|
|
1298
|
+
columns: id,
|
|
1299
|
+
...ifDefined("name", primaryKeyName)
|
|
1300
|
+
} } : {},
|
|
1301
|
+
...indexes.length > 0 ? { indexes } : {},
|
|
1302
|
+
...foreignKeys !== void 0 ? { foreignKeys } : {}
|
|
1303
|
+
});
|
|
1304
|
+
const unmappedColumns = [...build.unmappedColumns.values()];
|
|
1305
|
+
if (model.ignored) {
|
|
1306
|
+
tables.push({
|
|
1307
|
+
...tableProperties,
|
|
1308
|
+
namespaceId: model.namespaceId,
|
|
1309
|
+
columns: unmappedColumns
|
|
1310
|
+
});
|
|
1311
|
+
continue;
|
|
1312
|
+
}
|
|
1313
|
+
modelNodes.push({
|
|
1314
|
+
...tableProperties,
|
|
1315
|
+
modelName,
|
|
1316
|
+
namespaceId: model.namespaceId,
|
|
1317
|
+
fields: [...build.columns.values()],
|
|
1318
|
+
...relations !== void 0 ? { relations } : {}
|
|
1319
|
+
});
|
|
1320
|
+
if (unmappedColumns.length > 0) tables.push({
|
|
1321
|
+
namespaceId: model.namespaceId,
|
|
1322
|
+
tableName: model.tableName,
|
|
1323
|
+
columns: unmappedColumns
|
|
1324
|
+
});
|
|
1325
|
+
}
|
|
1326
|
+
tables.push(...[...lowered.ignoredJunctions.values()].map(stateServedBackingIndexes));
|
|
1327
|
+
for (const [key, junction] of lowered.junctions) {
|
|
1328
|
+
const relations = lowered.relations.get(key);
|
|
1329
|
+
modelNodes.push(stateServedBackingIndexes(relations === void 0 ? junction : {
|
|
1330
|
+
...junction,
|
|
1331
|
+
relations
|
|
1332
|
+
}));
|
|
1333
|
+
}
|
|
1334
|
+
if (diagnostics.length > 0) return notOk({
|
|
1335
|
+
summary: SUMMARY,
|
|
1336
|
+
diagnostics
|
|
1337
|
+
});
|
|
1338
|
+
const createNamespace = (namespace) => {
|
|
1339
|
+
const entities = namespaceEntities.get(namespace.id);
|
|
1340
|
+
if (entities === void 0) return binding.createNamespace(namespace);
|
|
1341
|
+
const valueSet = {
|
|
1342
|
+
...namespace.entries["valueSet"],
|
|
1343
|
+
...entities["valueSet"]
|
|
1344
|
+
};
|
|
1345
|
+
return binding.createNamespace({
|
|
1346
|
+
...namespace,
|
|
1347
|
+
entries: {
|
|
1348
|
+
...namespace.entries,
|
|
1349
|
+
...entities,
|
|
1350
|
+
...Object.keys(valueSet).length > 0 ? { valueSet } : {}
|
|
1351
|
+
}
|
|
1352
|
+
});
|
|
1353
|
+
};
|
|
1354
|
+
return ok(buildSqlContractFromDefinition({
|
|
1355
|
+
target: binding.target,
|
|
1356
|
+
warnings: void 0,
|
|
1357
|
+
createNamespace,
|
|
1358
|
+
...namespaceEntities.size > 0 ? { namespaces: [...namespaceEntities.keys()] } : {},
|
|
1359
|
+
models: modelNodes,
|
|
1360
|
+
...tables.length > 0 ? { tables } : {}
|
|
1361
|
+
}, input.codecLookup, input.dataTypes.lookup));
|
|
1362
|
+
}
|
|
1363
|
+
/**
|
|
1364
|
+
* Prisma 7 never derives a backing index for a foreign key, so its relations say `index: false`. Where the model's own indexes or keys already serve a foreign key, the relation takes the default instead, so the build drops the derived index again, or names the named key or plain index whose first columns are the foreign key's. Either way the stored foreign key states what backs it, and no index is added.
|
|
1365
|
+
*/
|
|
1366
|
+
function stateServedBackingIndexes(node) {
|
|
1367
|
+
if (node.foreignKeys === void 0) return node;
|
|
1368
|
+
const table = {
|
|
1369
|
+
indexes: (node.indexes ?? []).map((index) => lowerAuthoredIndex(node.tableName, blindCast(index), [])),
|
|
1370
|
+
uniques: node.uniques ?? [],
|
|
1371
|
+
primaryKey: node.id
|
|
1372
|
+
};
|
|
1373
|
+
return {
|
|
1374
|
+
...node,
|
|
1375
|
+
foreignKeys: node.foreignKeys.map((foreignKey) => {
|
|
1376
|
+
if (foreignKey.index !== false) return foreignKey;
|
|
1377
|
+
if (declaredIndexesServeForeignKey(foreignKey.columns, table)) return {
|
|
1378
|
+
...foreignKey,
|
|
1379
|
+
index: true
|
|
1380
|
+
};
|
|
1381
|
+
const name = declaredBackingObjectName(foreignKey.columns, table);
|
|
1382
|
+
return name === void 0 ? foreignKey : {
|
|
1383
|
+
...foreignKey,
|
|
1384
|
+
index: name
|
|
1385
|
+
};
|
|
1386
|
+
})
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
function checkDatasource(datasources, fallbackSourceId, binding, diagnostics) {
|
|
1390
|
+
const [datasource] = datasources;
|
|
1391
|
+
const [namedProvider] = binding.providers;
|
|
1392
|
+
if (datasource === void 0) {
|
|
1393
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_PROVIDER_MISMATCH", `No datasource block found; add \`datasource db { provider = "${namedProvider}" }\`.`, fallbackSourceId, void 0));
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
reportDuplicateBlockEntries(datasource, diagnostics);
|
|
1397
|
+
const provider = scalarValue(datasource, "provider");
|
|
1398
|
+
if (provider === void 0 || !binding.providers.includes(provider)) diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_PROVIDER_MISMATCH", provider === void 0 ? `The datasource block declares no string \`provider\`; this contract source reads Prisma 7 schemas for provider "${namedProvider}".` : `The datasource provider is "${provider}"; this contract source reads Prisma 7 schemas for provider "${namedProvider}".`, datasource.sourceId, parameterSpan(datasource, "provider")));
|
|
1399
|
+
for (const [property, edit] of Object.entries({
|
|
1400
|
+
relationMode: "Removing relationMode, or setting it to \"foreignKeys\"",
|
|
1401
|
+
referentialIntegrity: "Removing referentialIntegrity, or replacing it with relationMode = \"foreignKeys\""
|
|
1402
|
+
})) {
|
|
1403
|
+
if (scalarValue(datasource, property) !== "prisma") continue;
|
|
1404
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_RELATION_MODE_UNSUPPORTED", `${property} = "prisma" is not supported: the contract declares the foreign keys its relations need, and in this mode Prisma 7 creates none. ${edit}, makes Prisma 7's next migration add those foreign keys, and that migration fails if any existing row breaks one.`, datasource.sourceId, parameterSpan(datasource, property)));
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
function reportTableCollisions(models, diagnostics) {
|
|
1408
|
+
const byTable = /* @__PURE__ */ new Map();
|
|
1409
|
+
for (const model of models) {
|
|
1410
|
+
const key = `${model.namespaceId}.${model.tableName}`;
|
|
1411
|
+
const group = byTable.get(key) ?? [];
|
|
1412
|
+
byTable.set(key, group);
|
|
1413
|
+
group.push(model);
|
|
1414
|
+
}
|
|
1415
|
+
for (const group of byTable.values()) {
|
|
1416
|
+
if (group.length < 2) continue;
|
|
1417
|
+
const names = group.map((model) => `"${model.symbol.name}"`).join(", ");
|
|
1418
|
+
for (const model of group) {
|
|
1419
|
+
const mapAttribute = model.symbol.attributes.find((attribute) => attribute.name === "map");
|
|
1420
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_TABLE_COLLISION", `Models ${names} all map to table "${model.namespaceId}"."${model.tableName}"; each model needs its own table.`, model.sourceId, mapAttribute?.span ?? model.symbol.span));
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
function keyColumns(model, fieldNames) {
|
|
1425
|
+
const columns = [];
|
|
1426
|
+
for (const fieldName of fieldNames) {
|
|
1427
|
+
const column = model.columns.get(fieldName) ?? model.unmappedColumns.get(fieldName);
|
|
1428
|
+
if (column === void 0) return void 0;
|
|
1429
|
+
columns.push(column.columnName);
|
|
1430
|
+
}
|
|
1431
|
+
return columns;
|
|
1432
|
+
}
|
|
1433
|
+
function readModelDeclaration(symbol, sourceId, sources, defaultNamespaceId, binding, diagnostics, argumentContext) {
|
|
1434
|
+
const { indexTypes } = binding;
|
|
1435
|
+
let ignored = false;
|
|
1436
|
+
let tableName = symbol.name;
|
|
1437
|
+
let namespaceId = defaultNamespaceId;
|
|
1438
|
+
let id;
|
|
1439
|
+
const uniqueIndexes = [];
|
|
1440
|
+
const indexes = [];
|
|
1441
|
+
for (const attribute of symbol.attributes) {
|
|
1442
|
+
if ([
|
|
1443
|
+
"id",
|
|
1444
|
+
"unique",
|
|
1445
|
+
"index"
|
|
1446
|
+
].includes(attribute.name)) checkStatedConstraintNameLength({
|
|
1447
|
+
attribute,
|
|
1448
|
+
owner: `Model "${symbol.name}"`,
|
|
1449
|
+
maxBytes: binding.identifierMaxBytes,
|
|
1450
|
+
sourceId,
|
|
1451
|
+
diagnostics
|
|
1452
|
+
});
|
|
1453
|
+
switch (attribute.name) {
|
|
1454
|
+
case "map":
|
|
1455
|
+
tableName = requireStringArgument(attribute, symbol.name, sourceId, diagnostics) ?? tableName;
|
|
1456
|
+
break;
|
|
1457
|
+
case "schema":
|
|
1458
|
+
namespaceId = requireStringArgument(attribute, symbol.name, sourceId, diagnostics) ?? namespaceId;
|
|
1459
|
+
break;
|
|
1460
|
+
case "id": {
|
|
1461
|
+
const parsed = parseIndexAttribute(attribute, symbol.name, sourceId, indexTypes, diagnostics);
|
|
1462
|
+
if (parsed?.fields !== void 0) id = parsed;
|
|
1463
|
+
break;
|
|
1464
|
+
}
|
|
1465
|
+
case "unique": {
|
|
1466
|
+
const parsed = parseIndexAttribute(attribute, symbol.name, sourceId, indexTypes, diagnostics);
|
|
1467
|
+
if (parsed?.fields !== void 0) uniqueIndexes.push(parsed);
|
|
1468
|
+
break;
|
|
1469
|
+
}
|
|
1470
|
+
case "index": {
|
|
1471
|
+
const parsed = parseIndexAttribute(attribute, symbol.name, sourceId, indexTypes, diagnostics);
|
|
1472
|
+
if (parsed?.fields !== void 0) indexes.push(parsed);
|
|
1473
|
+
break;
|
|
1474
|
+
}
|
|
1475
|
+
case "ignore":
|
|
1476
|
+
ignored = true;
|
|
1477
|
+
break;
|
|
1478
|
+
default: diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_ATTRIBUTE", `Model "${symbol.name}": attribute "@@${attribute.name}" is not supported yet by the Prisma 7 contract source.`, sourceId, attribute.span));
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
return {
|
|
1482
|
+
symbol,
|
|
1483
|
+
sourceId,
|
|
1484
|
+
sources,
|
|
1485
|
+
namespaceId,
|
|
1486
|
+
tableName,
|
|
1487
|
+
ignored,
|
|
1488
|
+
id,
|
|
1489
|
+
uniqueIndexes,
|
|
1490
|
+
indexes,
|
|
1491
|
+
argumentContext
|
|
1492
|
+
};
|
|
1493
|
+
}
|
|
1494
|
+
function requireStringArgument(attribute, owner, sourceId, diagnostics) {
|
|
1495
|
+
const value = stringArgument(attribute);
|
|
1496
|
+
if (value === void 0) diagnostics.push({
|
|
1497
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
1498
|
+
message: `"${owner}": attribute "${attribute.name}" expects one string argument.`,
|
|
1499
|
+
sourceId,
|
|
1500
|
+
span: attribute.span
|
|
1501
|
+
});
|
|
1502
|
+
return value;
|
|
1503
|
+
}
|
|
1504
|
+
function readEnumDeclaration(source, defaultNamespaceId, diagnostics) {
|
|
1505
|
+
const { block, sourceId, sources } = source;
|
|
1506
|
+
let typeName = block.name;
|
|
1507
|
+
let namespaceId = defaultNamespaceId;
|
|
1508
|
+
for (const attribute of block.attributes) switch (attribute.name) {
|
|
1509
|
+
case "map":
|
|
1510
|
+
typeName = requireStringArgument(attribute, block.name, sourceId, diagnostics) ?? typeName;
|
|
1511
|
+
break;
|
|
1512
|
+
case "schema":
|
|
1513
|
+
namespaceId = requireStringArgument(attribute, block.name, sourceId, diagnostics) ?? namespaceId;
|
|
1514
|
+
break;
|
|
1515
|
+
default: diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_ATTRIBUTE", `Enum "${block.name}": attribute "@@${attribute.name}" is not supported by the Prisma 7 contract source.`, sourceId, attribute.span));
|
|
1516
|
+
}
|
|
1517
|
+
const members = [];
|
|
1518
|
+
const seenMemberNames = /* @__PURE__ */ new Set();
|
|
1519
|
+
for (const entry of block.entries) {
|
|
1520
|
+
const name = entry.key()?.name();
|
|
1521
|
+
if (name === void 0) continue;
|
|
1522
|
+
if (seenMemberNames.has(name)) {
|
|
1523
|
+
diagnostics.push({
|
|
1524
|
+
code: "PSL_EXTENSION_DUPLICATE_PARAMETER",
|
|
1525
|
+
message: `Duplicate parameter "${name}" in "${block.keyword}" block "${block.name}"; first occurrence wins`,
|
|
1526
|
+
sourceId,
|
|
1527
|
+
span: nodePslSpan(entry.syntax, sources)
|
|
1528
|
+
});
|
|
1529
|
+
continue;
|
|
1530
|
+
}
|
|
1531
|
+
seenMemberNames.add(name);
|
|
1532
|
+
let value = name;
|
|
1533
|
+
const span = nodePslSpan(entry.syntax, sources);
|
|
1534
|
+
for (const attributeNode of entry.attributes()) {
|
|
1535
|
+
const attribute = readResolvedAttribute(attributeNode, sources);
|
|
1536
|
+
if (attribute.name === "map") value = requireStringArgument(attribute, `${block.name}.${name}`, sourceId, diagnostics) ?? value;
|
|
1537
|
+
else diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_ATTRIBUTE", `Enum member "${block.name}.${name}": attribute "@${attribute.name}" is not supported by the Prisma 7 contract source.`, sourceId, attribute.span));
|
|
1538
|
+
}
|
|
1539
|
+
members.push({
|
|
1540
|
+
name,
|
|
1541
|
+
value,
|
|
1542
|
+
span
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
return {
|
|
1546
|
+
name: block.name,
|
|
1547
|
+
typeName,
|
|
1548
|
+
namespaceId,
|
|
1549
|
+
members,
|
|
1550
|
+
span: block.span,
|
|
1551
|
+
sourceId
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1554
|
+
function lowerNativeEnums(enums, input, diagnostics) {
|
|
1555
|
+
const result = /* @__PURE__ */ new Map();
|
|
1556
|
+
if (enums.size === 0) return result;
|
|
1557
|
+
const { entityKind } = input.binding.nativeEnum;
|
|
1558
|
+
const descriptor = buildEntityTypesByDiscriminator(input.authoringContributions).get(entityKind);
|
|
1559
|
+
for (const declaration of enums.values()) {
|
|
1560
|
+
if (descriptor === void 0) {
|
|
1561
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNSUPPORTED_TYPE", `Enum "${declaration.name}" cannot be lowered: target "${input.binding.target.targetId}" registers no "${entityKind}" entity kind.`, declaration.sourceId, declaration.span));
|
|
1562
|
+
continue;
|
|
1563
|
+
}
|
|
1564
|
+
const context = {
|
|
1565
|
+
family: input.binding.target.familyId,
|
|
1566
|
+
target: input.binding.target.targetId,
|
|
1567
|
+
codecLookup: input.codecLookup,
|
|
1568
|
+
dataTypes: input.dataTypes,
|
|
1569
|
+
sourceId: declaration.sourceId,
|
|
1570
|
+
diagnostics: { push: (diagnostic) => {
|
|
1571
|
+
diagnostics.push(blindCast(diagnostic));
|
|
1572
|
+
} }
|
|
1573
|
+
};
|
|
1574
|
+
const values = Object.create(null);
|
|
1575
|
+
const writtenValues = Object.create(null);
|
|
1576
|
+
const parameterSpans = Object.create(null);
|
|
1577
|
+
for (const member of declaration.members) {
|
|
1578
|
+
values[member.name] = member.value;
|
|
1579
|
+
writtenValues[member.name] = {
|
|
1580
|
+
kind: "string",
|
|
1581
|
+
text: member.value
|
|
1582
|
+
};
|
|
1583
|
+
parameterSpans[member.name] = member.span;
|
|
1584
|
+
}
|
|
1585
|
+
const entity = instantiateAuthoringEntityType(entityKind, descriptor, [{
|
|
1586
|
+
kind: entityKind,
|
|
1587
|
+
keyword: entityKind,
|
|
1588
|
+
name: declaration.name,
|
|
1589
|
+
values,
|
|
1590
|
+
writtenValues,
|
|
1591
|
+
parameterSpans,
|
|
1592
|
+
attributes: { map: {
|
|
1593
|
+
args: { name: declaration.typeName },
|
|
1594
|
+
span: declaration.span
|
|
1595
|
+
} },
|
|
1596
|
+
span: declaration.span,
|
|
1597
|
+
namespaceId: declaration.namespaceId
|
|
1598
|
+
}], context);
|
|
1599
|
+
if (entity === void 0) continue;
|
|
1600
|
+
const entities = result.get(declaration.namespaceId) ?? {};
|
|
1601
|
+
result.set(declaration.namespaceId, entities);
|
|
1602
|
+
entities[entityKind] = {
|
|
1603
|
+
...entities[entityKind],
|
|
1604
|
+
[declaration.name]: entity
|
|
1605
|
+
};
|
|
1606
|
+
const valueSet = deriveValueSetFromEntity(descriptor.output, entity);
|
|
1607
|
+
if (valueSet !== void 0) entities["valueSet"] = {
|
|
1608
|
+
...entities["valueSet"],
|
|
1609
|
+
[declaration.name]: valueSet
|
|
1610
|
+
};
|
|
1611
|
+
}
|
|
1612
|
+
return result;
|
|
1613
|
+
}
|
|
1614
|
+
/** The SQL family's type constructor for a column of a type no data type claims (ADR 273). */
|
|
1615
|
+
const RAW_TYPE_CONSTRUCTOR = ["Raw"];
|
|
1616
|
+
/** Prisma 7's `Unsupported("...")`, which this source reads as ``Raw(sql`...`)``. */
|
|
1617
|
+
function isUnsupportedType(call) {
|
|
1618
|
+
return call?.path.length === 1 && call.path[0] === "Unsupported";
|
|
1619
|
+
}
|
|
1620
|
+
/** The one double-quoted string `Unsupported(...)` takes, as written and with its escapes undone. */
|
|
1621
|
+
function unsupportedTypeArgument(call) {
|
|
1622
|
+
const [written, ...rest] = call.args;
|
|
1623
|
+
if (written === void 0 || rest.length > 0 || written.kind !== "positional") return void 0;
|
|
1624
|
+
const literal = written.expression === void 0 ? void 0 : StringLiteralExprAst.cast(written.expression.syntax);
|
|
1625
|
+
const text = literal?.quote() === "\"" ? literal.value() : void 0;
|
|
1626
|
+
return text === void 0 ? void 0 : {
|
|
1627
|
+
written,
|
|
1628
|
+
text
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
function nativeTypeMessage(label, nativeType) {
|
|
1632
|
+
return `${label}: native type "@db.${nativeType}" has no Prisma 8 codec yet, and Prisma 8 cannot read this schema until it supports the column type. @ignore on the field or @@ignore on the model does not help: Prisma 8 keeps the columns of ignored fields and models in the contract. Changing the field's type to one Prisma 8 supports changes the column type on Prisma 7's next migration.`;
|
|
1633
|
+
}
|
|
1634
|
+
function readField(args) {
|
|
1635
|
+
const { field, build, diagnostics, input } = args;
|
|
1636
|
+
const { binding } = input;
|
|
1637
|
+
const model = build.declaration;
|
|
1638
|
+
const sourceId = model.sourceId;
|
|
1639
|
+
const label = `Field "${model.symbol.name}.${field.name}"`;
|
|
1640
|
+
const isRelationField = args.modelNames.has(field.typeName) && field.typeConstructor === void 0;
|
|
1641
|
+
const fieldIgnored = field.attributes.some((attribute) => attribute.name === "ignore") || isRelationField && args.ignoredModels.has(field.typeName);
|
|
1642
|
+
const unsupported = isUnsupportedType(field.typeConstructor);
|
|
1643
|
+
const unmappedReason = unsupported && !model.ignored ? "unsupported" : fieldIgnored ? "ignored" : void 0;
|
|
1644
|
+
if (unmappedReason !== void 0) build.unmappedFields.set(field.name, unmappedReason);
|
|
1645
|
+
const ignored = fieldIgnored || model.ignored || unsupported;
|
|
1646
|
+
let columnName = field.name;
|
|
1647
|
+
let nativeType;
|
|
1648
|
+
let relation;
|
|
1649
|
+
let defaultAttribute;
|
|
1650
|
+
let updatedAt;
|
|
1651
|
+
for (const attribute of field.attributes) {
|
|
1652
|
+
if (isRelationField ? attribute.name === "relation" : ["id", "unique"].includes(attribute.name)) checkStatedConstraintNameLength({
|
|
1653
|
+
attribute,
|
|
1654
|
+
owner: label,
|
|
1655
|
+
maxBytes: binding.identifierMaxBytes,
|
|
1656
|
+
sourceId,
|
|
1657
|
+
diagnostics
|
|
1658
|
+
});
|
|
1659
|
+
if (attribute.name === "map" && !isRelationField) columnName = requireStringArgument(attribute, label, sourceId, diagnostics) ?? columnName;
|
|
1660
|
+
else if (attribute.name.startsWith("db.") && !isRelationField) nativeType = {
|
|
1661
|
+
name: attribute.name.slice(3),
|
|
1662
|
+
attribute
|
|
1663
|
+
};
|
|
1664
|
+
else if (attribute.name === "id" && !isRelationField) {
|
|
1665
|
+
const parsed = parseIndexAttribute(attribute, label, sourceId, binding.indexTypes, diagnostics);
|
|
1666
|
+
if (parsed !== void 0) {
|
|
1667
|
+
build.idFields = [field.name];
|
|
1668
|
+
build.idMap = parsed.map;
|
|
1669
|
+
}
|
|
1670
|
+
if (unmappedReason !== void 0) diagnostics.push(unmappedFieldInPrimaryKey({
|
|
1671
|
+
modelName: model.symbol.name,
|
|
1672
|
+
fieldNames: [field.name],
|
|
1673
|
+
reason: unmappedReason,
|
|
1674
|
+
usedBy: "its @id",
|
|
1675
|
+
sourceId,
|
|
1676
|
+
span: attribute.span
|
|
1677
|
+
}));
|
|
1678
|
+
} else if (attribute.name === "unique" && !isRelationField) {
|
|
1679
|
+
const parsed = parseIndexAttribute(attribute, label, sourceId, binding.indexTypes, diagnostics);
|
|
1680
|
+
if (parsed !== void 0) build.uniqueIndexes.push({
|
|
1681
|
+
...parsed,
|
|
1682
|
+
fields: [field.name]
|
|
1683
|
+
});
|
|
1684
|
+
} else if (attribute.name === "default" && !isRelationField) defaultAttribute = attribute;
|
|
1685
|
+
else if (attribute.name === "updatedAt" && !isRelationField) updatedAt = attribute;
|
|
1686
|
+
else if (attribute.name === "relation" && isRelationField) relation = attribute;
|
|
1687
|
+
else if (attribute.name === "ignore") {} else diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_ATTRIBUTE", `${label}: attribute "@${attribute.name}" is not supported yet by the Prisma 7 contract source.`, sourceId, attribute.span));
|
|
1688
|
+
}
|
|
1689
|
+
if (field.malformedType) return;
|
|
1690
|
+
if (field.typeConstructor !== void 0 && !unsupported) {
|
|
1691
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNSUPPORTED_TYPE", `${label} has type "${field.typeConstructor.path.join(".")}(...)", which is not a Prisma 7 type. Prisma 7 refuses this schema too.`, sourceId, field.typeConstructor.span));
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
if (unsupported && nativeType !== void 0) {
|
|
1695
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_ATTRIBUTE", `${label} has type Unsupported(...), which takes no native type, but has attribute "@db.${nativeType.name}". Prisma 7 refuses this schema too: "Attribute not known". Remove "@db.${nativeType.name}".`, sourceId, nativeType.attribute.span));
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
const unsupportedArgument = field.typeConstructor === void 0 ? void 0 : unsupportedTypeArgument(field.typeConstructor);
|
|
1699
|
+
if (field.typeConstructor !== void 0 && unsupportedArgument === void 0) {
|
|
1700
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNSUPPORTED_TYPE", `${label}: Unsupported(...) takes one string, the column's type as the database prints it, such as Unsupported("tsvector").`, sourceId, field.typeConstructor.span));
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
if (isRelationField) {
|
|
1704
|
+
const attribute = relation === void 0 ? void 0 : parseRelationAttribute(relation, label, sourceId, diagnostics);
|
|
1705
|
+
if (relation !== void 0 && attribute === void 0) return;
|
|
1706
|
+
(ignored ? build.ignoredRelationFields : build.relationFields).push({
|
|
1707
|
+
field,
|
|
1708
|
+
targetModelName: field.typeName,
|
|
1709
|
+
attribute
|
|
1710
|
+
});
|
|
1711
|
+
return;
|
|
1712
|
+
}
|
|
1713
|
+
if (updatedAt !== void 0 && field.typeName !== "DateTime") {
|
|
1714
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UPDATED_AT_FIELD_INVALID", `${label} has type "${field.typeName}", but @updatedAt is only allowed on a DateTime field. Prisma 7 refuses this schema too: "Fields that are marked with @updatedAt must be of type DateTime." Remove @updatedAt, or change the field's type to DateTime.`, sourceId, updatedAt.span));
|
|
1715
|
+
return;
|
|
1716
|
+
}
|
|
1717
|
+
if (updatedAt !== void 0 && field.list) {
|
|
1718
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UPDATED_AT_FIELD_INVALID", `${label} is a list, but @updatedAt is not allowed on a list field. Prisma 7 refuses this schema too: "Fields that are marked with @updatedAt cannot be lists." Remove @updatedAt, or make the field a single DateTime.`, sourceId, updatedAt.span));
|
|
1719
|
+
return;
|
|
1720
|
+
}
|
|
1721
|
+
const enumDeclaration = unsupported ? void 0 : args.enums.get(field.typeName);
|
|
1722
|
+
let fieldType;
|
|
1723
|
+
if (unsupportedArgument !== void 0) {
|
|
1724
|
+
const sqlText = storedSqlText(unsupportedArgument.text);
|
|
1725
|
+
if (sqlText === void 0) {
|
|
1726
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNSUPPORTED_TYPE", `${label}: Unsupported(${unsupportedArgument.written.value}) is not one type name: a sql literal cannot hold it, because it has a NUL character or is too large.`, sourceId, unsupportedArgument.written.span));
|
|
1727
|
+
return;
|
|
1728
|
+
}
|
|
1729
|
+
fieldType = {
|
|
1730
|
+
kind: "values",
|
|
1731
|
+
path: RAW_TYPE_CONSTRUCTOR,
|
|
1732
|
+
values: [sqlText]
|
|
1733
|
+
};
|
|
1734
|
+
} else if (enumDeclaration !== void 0) {
|
|
1735
|
+
if (enumDeclaration.namespaceId !== model.namespaceId) {
|
|
1736
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_ENUM_NAMESPACE_MISMATCH", `${label} uses enum "${enumDeclaration.name}" from schema "${enumDeclaration.namespaceId}", but the model is in schema "${model.namespaceId}". Prisma 8 columns reference the enum type of their own schema; declare the enum in "${model.namespaceId}" or move the model.`, sourceId, field.span));
|
|
1737
|
+
return;
|
|
1738
|
+
}
|
|
1739
|
+
fieldType = {
|
|
1740
|
+
kind: "written",
|
|
1741
|
+
call: {
|
|
1742
|
+
path: binding.nativeEnum.typeConstructor,
|
|
1743
|
+
args: [{
|
|
1744
|
+
kind: "positional",
|
|
1745
|
+
value: enumDeclaration.name,
|
|
1746
|
+
span: field.span
|
|
1747
|
+
}],
|
|
1748
|
+
span: field.span
|
|
1749
|
+
}
|
|
1750
|
+
};
|
|
1751
|
+
} else {
|
|
1752
|
+
const scalar = prisma7ScalarMapping(binding.typeMap, field.typeName);
|
|
1753
|
+
if (scalar === void 0) {
|
|
1754
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNSUPPORTED_TYPE", `${label} has unknown type "${field.typeName}".`, sourceId, field.span));
|
|
1755
|
+
return;
|
|
1756
|
+
}
|
|
1757
|
+
const native = nativeType === void 0 ? void 0 : prisma7NativeTypeMapping(binding.typeMap, nativeType.name);
|
|
1758
|
+
if (nativeType !== void 0 && native === void 0) {
|
|
1759
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_NATIVE_TYPE_UNSUPPORTED", nativeTypeMessage(label, nativeType.name), sourceId, nativeType.attribute.span));
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1762
|
+
const mapping = native ?? scalar;
|
|
1763
|
+
fieldType = nativeType === void 0 || nativeType.attribute.args.length === 0 ? {
|
|
1764
|
+
kind: "values",
|
|
1765
|
+
path: [mapping.constructorName],
|
|
1766
|
+
values: mapping.args
|
|
1767
|
+
} : {
|
|
1768
|
+
kind: "written",
|
|
1769
|
+
call: {
|
|
1770
|
+
path: [mapping.constructorName],
|
|
1771
|
+
args: nativeType.attribute.args,
|
|
1772
|
+
span: nativeType.attribute.span
|
|
1773
|
+
}
|
|
1774
|
+
};
|
|
1775
|
+
}
|
|
1776
|
+
const constructorPath = fieldType.kind === "written" ? fieldType.call.path : fieldType.path;
|
|
1777
|
+
const typeConstructor = getAuthoringTypeConstructor(input.authoringContributions, constructorPath);
|
|
1778
|
+
if (typeConstructor === void 0) {
|
|
1779
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNSUPPORTED_TYPE", `${label} type "${field.typeName}" could not be resolved against target "${binding.target.targetId}".`, sourceId, field.span));
|
|
1780
|
+
return;
|
|
1781
|
+
}
|
|
1782
|
+
let resolved;
|
|
1783
|
+
if (fieldType.kind === "written") {
|
|
1784
|
+
const typeDiagnostics = createPslDiagnosticCollector(model.sources);
|
|
1785
|
+
resolved = instantiateFieldTypeConstructor({
|
|
1786
|
+
call: fieldType.call,
|
|
1787
|
+
descriptor: typeConstructor,
|
|
1788
|
+
diagnostics: typeDiagnostics,
|
|
1789
|
+
source: diagnosticSource(model.sources, field.node.syntax),
|
|
1790
|
+
entityLabel: label,
|
|
1791
|
+
namespaceId: model.namespaceId,
|
|
1792
|
+
namespaceExtensionEntities: args.namespaceEntities,
|
|
1793
|
+
codecLookup: input.codecLookup,
|
|
1794
|
+
dataTypes: input.dataTypes
|
|
1795
|
+
});
|
|
1796
|
+
diagnostics.push(...typeDiagnostics.toExternal());
|
|
1797
|
+
} else {
|
|
1798
|
+
const instantiated = instantiateAuthoringTypeConstructorFromValues(typeConstructor, fieldType.values, input.codecLookup.descriptorFor(typeConstructor.output.codecId)?.paramsSchema);
|
|
1799
|
+
if (!instantiated.ok && unsupportedArgument !== void 0) {
|
|
1800
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNSUPPORTED_TYPE", `${label}: Unsupported(${unsupportedArgument.written.value}) is not one type name: ${instantiated.failure.message}`, sourceId, unsupportedArgument.written.span));
|
|
1801
|
+
return;
|
|
1802
|
+
}
|
|
1803
|
+
if (!instantiated.ok) throw new InternalError(`The Prisma 7 target binding maps ${label} to constructor "${fieldType.path.join(".")}" with arguments its codec refuses: ${instantiated.failure.message}`);
|
|
1804
|
+
resolved = {
|
|
1805
|
+
ok: true,
|
|
1806
|
+
descriptor: instantiated.value
|
|
1807
|
+
};
|
|
1808
|
+
}
|
|
1809
|
+
if (!resolved.ok) return;
|
|
1810
|
+
const typeLookups = {
|
|
1811
|
+
codecLookup: input.codecLookup,
|
|
1812
|
+
dataTypeLookup: input.dataTypes.lookup
|
|
1813
|
+
};
|
|
1814
|
+
const updatedAtGenerator = updatedAt === void 0 || ignored ? void 0 : nowGeneratorFor(input.generatorFunctions, input.dataTypes, resolved.descriptor);
|
|
1815
|
+
if (updatedAt !== void 0 && !ignored && updatedAtGenerator === void 0) {
|
|
1816
|
+
if (nativeType === void 0) throw new InternalError(`The Prisma 7 target binding has no "now" generator for codec "${resolved.descriptor.codecId}", which the DateTime scalar maps to.`);
|
|
1817
|
+
diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UPDATED_AT_FIELD_INVALID", `${label} has @updatedAt, but "@db.${nativeType.name}" makes it a column that is not a date or time, so @updatedAt cannot set it. Prisma 7 refuses this schema too: "Native type ${nativeType.name} is not compatible with declared field type DateTime". Remove @updatedAt, or use a date or time native type such as @db.Timestamp.`, sourceId, nativeType.attribute.span));
|
|
1818
|
+
return;
|
|
1819
|
+
}
|
|
1820
|
+
const lowered = defaultAttribute === void 0 ? void 0 : lowerPrisma7Default({
|
|
1821
|
+
attribute: defaultAttribute,
|
|
1822
|
+
field,
|
|
1823
|
+
modelName: model.symbol.name,
|
|
1824
|
+
onlyDbgenerated: unsupported,
|
|
1825
|
+
codecId: resolved.descriptor.codecId,
|
|
1826
|
+
typeParams: resolved.descriptor.typeParams,
|
|
1827
|
+
codecLookup: input.codecLookup,
|
|
1828
|
+
dataTypes: input.dataTypes,
|
|
1829
|
+
literalForm: binding.literalDefaultForm({
|
|
1830
|
+
codecId: resolved.descriptor.codecId,
|
|
1831
|
+
dataType: sqlDataTypeOfCodec(resolved.descriptor.codecId, typeLookups).id,
|
|
1832
|
+
typeParams: resolved.descriptor.typeParams
|
|
1833
|
+
}),
|
|
1834
|
+
enumMembers: enumDeclaration === void 0 ? void 0 : new Map(enumDeclaration.members.map((member) => [member.name, member.value])),
|
|
1835
|
+
controlMutationDefaults: input.controlMutationDefaults,
|
|
1836
|
+
argumentContext: model.argumentContext,
|
|
1837
|
+
generatorFunctions: input.generatorFunctions,
|
|
1838
|
+
sourceId,
|
|
1839
|
+
diagnostics
|
|
1840
|
+
});
|
|
1841
|
+
if (defaultAttribute !== void 0 && lowered === void 0) return;
|
|
1842
|
+
const column = {
|
|
1843
|
+
columnName,
|
|
1844
|
+
descriptor: resolved.descriptor,
|
|
1845
|
+
nullable: field.optional || field.list,
|
|
1846
|
+
many: field.list,
|
|
1847
|
+
...field.list ? { elementNullable: true } : {},
|
|
1848
|
+
...ifDefined("default", lowered?.storage)
|
|
1849
|
+
};
|
|
1850
|
+
if (ignored) {
|
|
1851
|
+
build.unmappedColumns.set(field.name, column);
|
|
1852
|
+
return;
|
|
1853
|
+
}
|
|
1854
|
+
const executionDefaults = updatedAtGenerator !== void 0 ? {
|
|
1855
|
+
onCreate: updatedAtGenerator,
|
|
1856
|
+
onUpdate: updatedAtGenerator
|
|
1857
|
+
} : lowered?.onCreate !== void 0 ? { onCreate: lowered.onCreate } : void 0;
|
|
1858
|
+
build.columns.set(field.name, {
|
|
1859
|
+
fieldName: field.name,
|
|
1860
|
+
...column,
|
|
1861
|
+
...ifDefined("executionDefaults", executionDefaults)
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
function defaultOutputFromSchemaPath(schemaPath) {
|
|
1865
|
+
return join(dirname(schemaPath), "contract.json");
|
|
1866
|
+
}
|
|
1867
|
+
function mapParseDiagnostics(diagnostics, sourceFile, sourceId) {
|
|
1868
|
+
return diagnostics.map((diagnostic) => ({
|
|
1869
|
+
code: diagnostic.code,
|
|
1870
|
+
message: diagnostic.message,
|
|
1871
|
+
sourceId,
|
|
1872
|
+
span: sourceFile.rangeToPslSpan(diagnostic.range)
|
|
1873
|
+
}));
|
|
1874
|
+
}
|
|
1875
|
+
/**
|
|
1876
|
+
* The files a Prisma 7 schema input names: the file itself, or every regular
|
|
1877
|
+
* `.prisma` file under the directory, nested directories and symbolic links
|
|
1878
|
+
* included, as Prisma 7 reads a schema directory. Sorted by path so duplicate
|
|
1879
|
+
* detection blames the later file deterministically.
|
|
1880
|
+
*/
|
|
1881
|
+
async function listSchemaFiles(absolutePath, displayPath) {
|
|
1882
|
+
if (!(await stat(absolutePath)).isDirectory()) return [{
|
|
1883
|
+
sourceId: displayPath,
|
|
1884
|
+
absolutePath
|
|
1885
|
+
}];
|
|
1886
|
+
const entries = await readdir(absolutePath, { recursive: true });
|
|
1887
|
+
const files = [];
|
|
1888
|
+
for (const entry of entries.filter((name) => extname(name) === ".prisma").map((name) => normalize(name)).sort()) {
|
|
1889
|
+
const entryPath = join(absolutePath, entry);
|
|
1890
|
+
if ((await stat(entryPath)).isFile()) files.push({
|
|
1891
|
+
sourceId: join(displayPath, entry),
|
|
1892
|
+
absolutePath: entryPath
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1895
|
+
return files;
|
|
1896
|
+
}
|
|
1897
|
+
/**
|
|
1898
|
+
* The checks `contract emit` runs on the contract after `load` that the
|
|
1899
|
+
* contract builder does not: domain roots and relations, column defaults
|
|
1900
|
+
* against nullability, and model storage references. The structural check also
|
|
1901
|
+
* needs the target's entity kinds, which `load` does not receive.
|
|
1902
|
+
*/
|
|
1903
|
+
function validateInterpretedContract(contract) {
|
|
1904
|
+
validateContractDomain(contract);
|
|
1905
|
+
const sqlContract = blindCast(contract);
|
|
1906
|
+
validateSqlStorageConsistency(sqlContract);
|
|
1907
|
+
validateModelStorageReferences(sqlContract);
|
|
1908
|
+
}
|
|
1909
|
+
function isMissingPath(error) {
|
|
1910
|
+
return error instanceof Error && Reflect.get(error, "code") === "ENOENT";
|
|
1911
|
+
}
|
|
1912
|
+
function prisma7Contract(schemaPath, options) {
|
|
1913
|
+
const parserOptions = { grammar: "prisma-7" };
|
|
1914
|
+
return {
|
|
1915
|
+
source: {
|
|
1916
|
+
format: "psl",
|
|
1917
|
+
inputs: [schemaPath],
|
|
1918
|
+
parserOptions,
|
|
1919
|
+
async load(context) {
|
|
1920
|
+
const [absolutePath] = context.resolvedInputs;
|
|
1921
|
+
if (absolutePath === void 0) throw new InternalError("prisma7Contract: context.resolvedInputs is empty. The CLI config loader should populate it from source.inputs.");
|
|
1922
|
+
let files;
|
|
1923
|
+
try {
|
|
1924
|
+
files = await listSchemaFiles(absolutePath, schemaPath);
|
|
1925
|
+
} catch (error) {
|
|
1926
|
+
const cause = String(error);
|
|
1927
|
+
const message = isMissingPath(error) ? `There is no file or directory at "${schemaPath}". Fix the path passed to prisma7Schema() in prisma.config.ts.` : cause;
|
|
1928
|
+
return notOk({
|
|
1929
|
+
summary: `Failed to read Prisma 7 schema at "${schemaPath}"`,
|
|
1930
|
+
diagnostics: [prisma7Diagnostic("PSL.PRISMA7_SCHEMA_READ_FAILED", message, schemaPath, void 0)],
|
|
1931
|
+
meta: {
|
|
1932
|
+
schemaPath,
|
|
1933
|
+
absolutePath,
|
|
1934
|
+
cause
|
|
1935
|
+
}
|
|
1936
|
+
});
|
|
1937
|
+
}
|
|
1938
|
+
if (files.length === 0) return notOk({
|
|
1939
|
+
summary: `Failed to read Prisma 7 schema at "${schemaPath}"`,
|
|
1940
|
+
diagnostics: [prisma7Diagnostic("PSL.PRISMA7_SCHEMA_READ_FAILED", `The schema directory "${schemaPath}" contains no .prisma file.`, schemaPath, void 0)],
|
|
1941
|
+
meta: {
|
|
1942
|
+
schemaPath,
|
|
1943
|
+
absolutePath
|
|
1944
|
+
}
|
|
1945
|
+
});
|
|
1946
|
+
const documents = [];
|
|
1947
|
+
const seedDiagnostics = [];
|
|
1948
|
+
for (const file of files) {
|
|
1949
|
+
let schema;
|
|
1950
|
+
try {
|
|
1951
|
+
schema = await readFile(file.absolutePath, "utf-8");
|
|
1952
|
+
} catch (error) {
|
|
1953
|
+
const message = String(error);
|
|
1954
|
+
return notOk({
|
|
1955
|
+
summary: `Failed to read Prisma 7 schema at "${file.sourceId}"`,
|
|
1956
|
+
diagnostics: [prisma7Diagnostic("PSL.PRISMA7_SCHEMA_READ_FAILED", message, file.sourceId, void 0)],
|
|
1957
|
+
meta: {
|
|
1958
|
+
schemaPath: file.sourceId,
|
|
1959
|
+
absoluteSchemaPath: file.absolutePath,
|
|
1960
|
+
cause: message
|
|
1961
|
+
}
|
|
1962
|
+
});
|
|
1963
|
+
}
|
|
1964
|
+
const { document, sources, diagnostics } = parse(schema, file.sourceId, parserOptions);
|
|
1965
|
+
const sourceFile = sources.sourceFileFor(document.syntax);
|
|
1966
|
+
seedDiagnostics.push(...mapParseDiagnostics(diagnostics, sourceFile, file.sourceId));
|
|
1967
|
+
documents.push({
|
|
1968
|
+
document,
|
|
1969
|
+
sources,
|
|
1970
|
+
sourceFile,
|
|
1971
|
+
sourceId: file.sourceId
|
|
1972
|
+
});
|
|
1973
|
+
}
|
|
1974
|
+
let contract;
|
|
1975
|
+
try {
|
|
1976
|
+
const interpreted = interpretPrisma7Documents({
|
|
1977
|
+
documents,
|
|
1978
|
+
seedDiagnostics,
|
|
1979
|
+
binding: options.binding,
|
|
1980
|
+
controlMutationDefaults: context.controlMutationDefaults,
|
|
1981
|
+
generatorFunctions: context.generatorFunctions,
|
|
1982
|
+
authoringContributions: context.authoringContributions,
|
|
1983
|
+
codecLookup: context.codecLookup,
|
|
1984
|
+
dataTypes: context.dataTypes,
|
|
1985
|
+
composedExtensions: context.composedExtensions,
|
|
1986
|
+
defaultNamespaceId: context.defaultNamespaceId
|
|
1987
|
+
});
|
|
1988
|
+
if (!interpreted.ok) return interpreted;
|
|
1989
|
+
contract = applySqlSpecifierControlPolicy(interpreted.value, options.defaultControlPolicy, options.binding.createNamespace);
|
|
1990
|
+
validateInterpretedContract(contract);
|
|
1991
|
+
} catch (error) {
|
|
1992
|
+
if (!isStructuredError(error)) throw error;
|
|
1993
|
+
return notOk({
|
|
1994
|
+
summary: "Prisma 7 schema interpretation failed",
|
|
1995
|
+
diagnostics: [prisma7Diagnostic("PSL.PRISMA7_CONTRACT_INVALID", `This schema gives a contract that Prisma 8 rejects, and the Prisma 7 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)],
|
|
1996
|
+
meta: {
|
|
1997
|
+
schemaPath,
|
|
1998
|
+
code: error.code
|
|
1999
|
+
}
|
|
2000
|
+
});
|
|
2001
|
+
}
|
|
2002
|
+
return ok(contract);
|
|
2003
|
+
}
|
|
2004
|
+
},
|
|
2005
|
+
output: options.output ?? defaultOutputFromSchemaPath(schemaPath)
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
//#endregion
|
|
2009
|
+
export { prisma7Contract };
|
|
2010
|
+
|
|
2011
|
+
//# sourceMappingURL=contract-prisma7__provider.mjs.map
|