@prisma/orm-family-sql 8.0.0-rc.2-dev.2 → 8.0.0-rc.20
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,2280 @@
|
|
|
1
|
+
import { n as isAuthoredIndexInput } from "./index-naming-BOcJT1B3-mG8Fd6KN.mjs";
|
|
2
|
+
import { u as sqlCodecColumnLength } from "./sql-data-type-D7M-YTTY-D2vRqDxn.mjs";
|
|
3
|
+
import { n as providesPslEntityPlacement } from "./entity-handle-lowering-hook-BJZSlVVF.mjs";
|
|
4
|
+
import "./foreign-key-materialization-BM59w_Xg.mjs";
|
|
5
|
+
import { p as sqlTextFromStored } from "./sql-expression-CKgKznXS.mjs";
|
|
6
|
+
import { t as deriveValueSetFromEntity } from "./value-set-derivation-hook-HVaxhALD.mjs";
|
|
7
|
+
import { n as buildSqlContractFromDefinition } from "./derived-checks-D5HVRvqN-BJx1gwPA.mjs";
|
|
8
|
+
import { i as mapFieldNamesToColumns, n as getAttribute, o as storageName, r as getNamedArgument, t as formatDbAttributeMigrationMessage } from "./psl-attribute-parsing-BCsFWsSp-BJ-wGlY6.mjs";
|
|
9
|
+
import { _ as modelSpecContext, b as sqlAttributeSpecs, d as interpretModelAttribute, f as lowerEnumDefault, g as modelCoordinateKey, h as modelAttributeSpecsFrom, l as instantiatePslTypeConstructor, m as lowerTypeGenerators, n as collectResolvedFields, o as fieldSpecContext, p as lowerTypeDefault, r as contractError, s as getAuthoringEntity, t as PSL_CHECK_ON_STI_VARIANT, u as interpretFieldAttribute, y as resolveFieldTypeDescriptor } from "./psl-field-resolution-C5KQ7kzP-B0NwuRWV.mjs";
|
|
10
|
+
import { t as defaultTableName } from "./default-table-name-BfFY8qYR-CWZFDX6v.mjs";
|
|
11
|
+
import { isStructuredError } from "@prisma/orm-framework/utils/structured-error";
|
|
12
|
+
import { ifDefined } from "@prisma/orm-framework/utils/defined";
|
|
13
|
+
import { applyDiscriminatorRule, describeDiscriminatorRefusal, encodeEnumMembers, instantiateAuthoringEntityType, instantiateAuthoringTypeAlias, instantiateAuthoringTypeConstructor, isAuthoringEntityTypeDescriptor, isAuthoringModelAttributeDescriptor, resolveTypeAliasGenerators } from "@prisma/orm-framework/components/authoring";
|
|
14
|
+
import { UNBOUND_NAMESPACE_ID } from "@prisma/orm-framework/components/ir";
|
|
15
|
+
import { blindCast } from "@prisma/orm-framework/utils/casts";
|
|
16
|
+
import { InternalError } from "@prisma/orm-framework/utils/internal-error";
|
|
17
|
+
import { crossRef } from "@prisma/orm-framework/contract/types";
|
|
18
|
+
import { NamespaceDeclarationAst } from "@prisma/orm-framework/psl-parser/syntax";
|
|
19
|
+
import { resolveToOneRelationNullable } from "@prisma/orm-framework/contract-authoring";
|
|
20
|
+
import { assertDefined, invariant } from "@prisma/orm-framework/utils/assertions";
|
|
21
|
+
import { notOk, ok } from "@prisma/orm-framework/utils/result";
|
|
22
|
+
import { contributedTypeAliasOf, createPslDiagnosticCollector, diagnosticSource, findBlockDescriptor, interpretExtensionBlocks, nodePslSpan, resolveTypeAliases, typeAliasAttributeNames, typeAliasSpecContext, typeReferenceNode } from "@prisma/orm-framework/psl-parser";
|
|
23
|
+
import { claimedBlockKeywords, enumMemberAttributeDiagnostics, fkRelationPairKey, requiredOneToOneBackrelationDiagnostic, unsupportedBlockDiagnostic } from "@prisma/orm-framework/psl-parser/interpret";
|
|
24
|
+
//#region ../../../2-sql-family/2-authoring/contract-psl/dist/interpreter-D5qk4B--.mjs
|
|
25
|
+
function describeUnsupportedSqlAliasAttribute(attribute) {
|
|
26
|
+
return attribute.name.startsWith("db.") ? formatDbAttributeMigrationMessage(attribute) : void 0;
|
|
27
|
+
}
|
|
28
|
+
function aliasDescriptor(alias, input) {
|
|
29
|
+
const { base, symbol } = alias;
|
|
30
|
+
const source = diagnosticSource(input.sources, symbol.node.syntax);
|
|
31
|
+
if (base.kind === "typeConstructor") {
|
|
32
|
+
if (base.call === void 0) return instantiateAuthoringTypeConstructor(base.descriptor, []);
|
|
33
|
+
return instantiatePslTypeConstructor({
|
|
34
|
+
call: base.call,
|
|
35
|
+
descriptor: base.descriptor,
|
|
36
|
+
codecLookup: input.codecLookup,
|
|
37
|
+
diagnostics: input.diagnostics,
|
|
38
|
+
source,
|
|
39
|
+
entityLabel: `Type alias "${symbol.name}"`,
|
|
40
|
+
dataTypes: input.dataTypes
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const descriptor = input.enumTypeDescriptors.get(base.symbol);
|
|
44
|
+
if (descriptor === void 0) input.diagnostics.push({
|
|
45
|
+
code: "PSL_UNSUPPORTED_NAMED_TYPE_BASE",
|
|
46
|
+
message: `Type alias "${symbol.name}" references unsupported base type "${alias.baseName}"`,
|
|
47
|
+
...source.at(symbol.span)
|
|
48
|
+
});
|
|
49
|
+
return descriptor;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resolves each `types {}` alias once: its column type, with the params inline, and its `@default`, `@onCreate` and `@onUpdate`, lowered for that column. A diagnostic about the alias is reported here, once, not at each field typed by it.
|
|
53
|
+
*/
|
|
54
|
+
function resolveNamedTypeDeclarations(input) {
|
|
55
|
+
const declared = resolveDeclaredTypeAliases(input);
|
|
56
|
+
const contributed = /* @__PURE__ */ new Map();
|
|
57
|
+
const resolveContributed = (alias) => {
|
|
58
|
+
const existing = contributed.get(alias.descriptor);
|
|
59
|
+
if (existing !== void 0) return existing;
|
|
60
|
+
const resolved = resolveContributedTypeAlias(alias, input);
|
|
61
|
+
contributed.set(alias.descriptor, resolved);
|
|
62
|
+
return resolved;
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
get: (symbol) => declared.get(symbol),
|
|
66
|
+
ofResolution(resolution) {
|
|
67
|
+
if (resolution?.kind === "namedType") return declared.get(resolution.symbol);
|
|
68
|
+
const alias = contributedTypeAliasOf(resolution);
|
|
69
|
+
return alias === void 0 ? void 0 : resolveContributed(alias);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function resolveContributedTypeAlias(alias, input) {
|
|
74
|
+
const { type: descriptor } = instantiateAuthoringTypeAlias(alias.descriptor);
|
|
75
|
+
const executionDefaults = resolveTypeAliasGenerators({
|
|
76
|
+
path: alias.name,
|
|
77
|
+
descriptor: alias.descriptor,
|
|
78
|
+
generatorFunctions: input.generatorFunctions,
|
|
79
|
+
length: sqlCodecColumnLength(input.dataTypes, descriptor.codecId, descriptor.typeParams)
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
alias,
|
|
83
|
+
name: alias.name,
|
|
84
|
+
attributes: [],
|
|
85
|
+
descriptor,
|
|
86
|
+
enumHandle: void 0,
|
|
87
|
+
defaultValue: void 0,
|
|
88
|
+
executionDefaults
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function resolveDeclaredTypeAliases(input) {
|
|
92
|
+
const aliases = resolveTypeAliases({
|
|
93
|
+
declarations: input.declarations,
|
|
94
|
+
binder: input.binder,
|
|
95
|
+
sources: input.sources,
|
|
96
|
+
diagnostics: input.diagnostics,
|
|
97
|
+
authoringTypes: input.authoringTypes,
|
|
98
|
+
describeUnsupportedAttribute: describeUnsupportedSqlAliasAttribute
|
|
99
|
+
});
|
|
100
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
101
|
+
for (const alias of aliases.values()) {
|
|
102
|
+
const descriptor = aliasDescriptor(alias, input);
|
|
103
|
+
if (descriptor === void 0) continue;
|
|
104
|
+
const owner = {
|
|
105
|
+
attributes: alias.attributes,
|
|
106
|
+
optional: false,
|
|
107
|
+
list: false,
|
|
108
|
+
elementOptional: false,
|
|
109
|
+
specContext: typeAliasSpecContext(alias, {
|
|
110
|
+
...input,
|
|
111
|
+
symbols: input.symbolTable
|
|
112
|
+
}),
|
|
113
|
+
loweringNames: {
|
|
114
|
+
modelName: "types",
|
|
115
|
+
fieldName: alias.symbol.name
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const enumHandle = alias.base.kind === "block" ? input.enumHandles.get(alias.base.symbol) : void 0;
|
|
119
|
+
const lowering = {
|
|
120
|
+
...input,
|
|
121
|
+
owner
|
|
122
|
+
};
|
|
123
|
+
const { defaultValue } = enumHandle === void 0 ? lowerTypeDefault({
|
|
124
|
+
...lowering,
|
|
125
|
+
columnDescriptor: descriptor,
|
|
126
|
+
columnTypeParams: descriptor.typeParams,
|
|
127
|
+
isListColumn: false,
|
|
128
|
+
valueObjectDefault: void 0
|
|
129
|
+
}) : lowerEnumDefault({
|
|
130
|
+
...lowering,
|
|
131
|
+
enumHandle
|
|
132
|
+
});
|
|
133
|
+
const executionDefaults = lowerTypeGenerators({
|
|
134
|
+
...lowering,
|
|
135
|
+
columnDescriptor: descriptor,
|
|
136
|
+
columnTypeParams: descriptor.typeParams
|
|
137
|
+
});
|
|
138
|
+
resolved.set(alias.symbol, {
|
|
139
|
+
alias,
|
|
140
|
+
name: alias.symbol.name,
|
|
141
|
+
attributes: alias.attributes,
|
|
142
|
+
descriptor,
|
|
143
|
+
enumHandle,
|
|
144
|
+
defaultValue,
|
|
145
|
+
executionDefaults
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
return resolved;
|
|
149
|
+
}
|
|
150
|
+
const REFERENTIAL_ACTION_MAP = {
|
|
151
|
+
NoAction: "noAction",
|
|
152
|
+
Restrict: "restrict",
|
|
153
|
+
Cascade: "cascade",
|
|
154
|
+
SetNull: "setNull",
|
|
155
|
+
SetDefault: "setDefault",
|
|
156
|
+
noAction: "noAction",
|
|
157
|
+
restrict: "restrict",
|
|
158
|
+
cascade: "cascade",
|
|
159
|
+
setNull: "setNull",
|
|
160
|
+
setDefault: "setDefault"
|
|
161
|
+
};
|
|
162
|
+
function modelName(key) {
|
|
163
|
+
return typeof key === "string" ? key : key.name;
|
|
164
|
+
}
|
|
165
|
+
function normalizeReferentialAction(actionToken) {
|
|
166
|
+
return REFERENTIAL_ACTION_MAP[actionToken];
|
|
167
|
+
}
|
|
168
|
+
function interpretRelationAttribute(input) {
|
|
169
|
+
const node = getAttribute(input.field.attributes, "relation")?.node;
|
|
170
|
+
if (node === void 0) return void 0;
|
|
171
|
+
return interpretFieldAttribute({
|
|
172
|
+
symbols: input.symbols,
|
|
173
|
+
node,
|
|
174
|
+
spec: sqlAttributeSpecs.field.relation(input.specContext),
|
|
175
|
+
model: input.selfModel,
|
|
176
|
+
field: input.field,
|
|
177
|
+
sources: input.sources,
|
|
178
|
+
binder: input.binder,
|
|
179
|
+
diagnostics: input.diagnostics
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
function indexFkRelations(input) {
|
|
183
|
+
const modelRelations = /* @__PURE__ */ new Map();
|
|
184
|
+
const fkRelationsByPair = /* @__PURE__ */ new Map();
|
|
185
|
+
const fkRelationsByDeclaringModel = /* @__PURE__ */ new Map();
|
|
186
|
+
for (const relation of input.fkRelationMetadata) {
|
|
187
|
+
const declaringFkRelations = fkRelationsByDeclaringModel.get(relation.declaringModelName);
|
|
188
|
+
if (declaringFkRelations) declaringFkRelations.push(relation);
|
|
189
|
+
else fkRelationsByDeclaringModel.set(relation.declaringModelName, [relation]);
|
|
190
|
+
const existing = modelRelations.get(relation.declaringModelName);
|
|
191
|
+
const current = existing ?? [];
|
|
192
|
+
if (!existing) modelRelations.set(relation.declaringModelName, current);
|
|
193
|
+
current.push({
|
|
194
|
+
fieldName: relation.declaringFieldName,
|
|
195
|
+
toModel: modelName(relation.targetModelName),
|
|
196
|
+
toTable: relation.targetTableName,
|
|
197
|
+
...ifDefined("toNamespaceId", relation.targetNamespaceId),
|
|
198
|
+
cardinality: "N:1",
|
|
199
|
+
nullable: relation.nullable,
|
|
200
|
+
on: {
|
|
201
|
+
parentTable: relation.declaringTableName,
|
|
202
|
+
parentColumns: relation.localColumns,
|
|
203
|
+
childTable: relation.targetTableName,
|
|
204
|
+
childColumns: relation.referencedColumns
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
let targets = fkRelationsByPair.get(relation.declaringModelName);
|
|
208
|
+
if (!targets) {
|
|
209
|
+
targets = /* @__PURE__ */ new Map();
|
|
210
|
+
fkRelationsByPair.set(relation.declaringModelName, targets);
|
|
211
|
+
}
|
|
212
|
+
const pairRelations = targets.get(relation.targetModelName);
|
|
213
|
+
if (pairRelations) pairRelations.push(relation);
|
|
214
|
+
else targets.set(relation.targetModelName, [relation]);
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
modelRelations,
|
|
218
|
+
fkRelationsByPair,
|
|
219
|
+
fkRelationsByDeclaringModel
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function idColumnsAreExactlyFkPair(idColumns, parentColumns, childColumns) {
|
|
223
|
+
if (idColumns.length !== parentColumns.length + childColumns.length) return false;
|
|
224
|
+
const fkColumns = /* @__PURE__ */ new Set([...parentColumns, ...childColumns]);
|
|
225
|
+
if (fkColumns.size !== parentColumns.length + childColumns.length) return false;
|
|
226
|
+
return idColumns.every((column) => fkColumns.has(column));
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Reorders the child FK's junction columns into the target model's id-column
|
|
230
|
+
* order. Returns undefined unless the FK references exactly the target's full
|
|
231
|
+
* id, because downstream consumers pair `through.childColumns` positionally
|
|
232
|
+
* against the target id columns — an FK referencing anything else (a non-id
|
|
233
|
+
* unique, a partial id) would produce a silently wrong join.
|
|
234
|
+
*/
|
|
235
|
+
function childColumnsInTargetIdOrder(childFk, targetIdColumns) {
|
|
236
|
+
if (childFk.referencedColumns.length !== targetIdColumns.length) return;
|
|
237
|
+
const localByReferenced = /* @__PURE__ */ new Map();
|
|
238
|
+
for (const [index, referencedColumn] of childFk.referencedColumns.entries()) {
|
|
239
|
+
const localColumn = childFk.localColumns[index];
|
|
240
|
+
if (localColumn === void 0) return;
|
|
241
|
+
localByReferenced.set(referencedColumn, localColumn);
|
|
242
|
+
}
|
|
243
|
+
if (localByReferenced.size !== targetIdColumns.length) return;
|
|
244
|
+
const ordered = [];
|
|
245
|
+
for (const idColumn of targetIdColumns) {
|
|
246
|
+
const localColumn = localByReferenced.get(idColumn);
|
|
247
|
+
if (localColumn === void 0) return;
|
|
248
|
+
ordered.push(localColumn);
|
|
249
|
+
}
|
|
250
|
+
return ordered;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Finds explicit junction models that connect a bare backrelation list field
|
|
254
|
+
* to its target model: a model whose composite id columns are exactly the FK
|
|
255
|
+
* columns of one relation back to the candidate's model (the parent side) and
|
|
256
|
+
* one relation to the candidate's target model (the child side). The child
|
|
257
|
+
* FK must reference exactly the target model's id columns; its junction
|
|
258
|
+
* columns are carried in target-id order on the pair. A relation name on the
|
|
259
|
+
* list field pins the parent-side FK relation, which is how self-referential
|
|
260
|
+
* many-to-many sides are disambiguated.
|
|
261
|
+
*
|
|
262
|
+
* Alongside the recognised pairs, returns junction-shaped near-misses (models
|
|
263
|
+
* that link both sides but were declined) so the caller can emit a
|
|
264
|
+
* junction-specific diagnostic instead of the generic orphaned-list message.
|
|
265
|
+
*/
|
|
266
|
+
function findJunctionFkPairs(input) {
|
|
267
|
+
const targetIdColumns = input.modelIdColumns.get(input.candidate.targetModelName);
|
|
268
|
+
if (!targetIdColumns || targetIdColumns.length === 0) return {
|
|
269
|
+
pairs: [],
|
|
270
|
+
nearMisses: []
|
|
271
|
+
};
|
|
272
|
+
const pairs = [];
|
|
273
|
+
const nearMisses = [];
|
|
274
|
+
for (const [junctionModelName, junctionFks] of input.fkRelationsByDeclaringModel) {
|
|
275
|
+
const idColumns = input.modelIdColumns.get(junctionModelName);
|
|
276
|
+
for (const parentFk of junctionFks) {
|
|
277
|
+
if (parentFk.targetModelName !== input.candidate.modelName) continue;
|
|
278
|
+
if (input.candidate.relationName !== void 0 && parentFk.relationName !== input.candidate.relationName) continue;
|
|
279
|
+
for (const childFk of junctionFks) {
|
|
280
|
+
if (childFk === parentFk || childFk.targetModelName !== input.candidate.targetModelName) continue;
|
|
281
|
+
if (!idColumns || !idColumnsAreExactlyFkPair(idColumns, parentFk.localColumns, childFk.localColumns)) {
|
|
282
|
+
nearMisses.push({
|
|
283
|
+
junctionModelName: modelName(junctionModelName),
|
|
284
|
+
reason: "id-not-fk-covering"
|
|
285
|
+
});
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
const orderedChildColumns = childColumnsInTargetIdOrder(childFk, targetIdColumns);
|
|
289
|
+
if (!orderedChildColumns) {
|
|
290
|
+
nearMisses.push({
|
|
291
|
+
junctionModelName: modelName(junctionModelName),
|
|
292
|
+
reason: "target-fk-not-id"
|
|
293
|
+
});
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
pairs.push({
|
|
297
|
+
parentFk,
|
|
298
|
+
childFk,
|
|
299
|
+
childColumnsInTargetIdOrder: orderedChildColumns
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
pairs,
|
|
306
|
+
nearMisses
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
function junctionNearMissDiagnostic(candidate, nearMiss, sources) {
|
|
310
|
+
const source = diagnosticSource(sources, candidate.field.node.syntax);
|
|
311
|
+
const listField = `${modelName(candidate.modelName)}.${candidate.field.name}`;
|
|
312
|
+
const targetModelName = modelName(candidate.targetModelName);
|
|
313
|
+
const data = {
|
|
314
|
+
listField,
|
|
315
|
+
junctionModel: nearMiss.junctionModelName,
|
|
316
|
+
targetModel: targetModelName
|
|
317
|
+
};
|
|
318
|
+
if (nearMiss.reason === "target-fk-not-id") return {
|
|
319
|
+
code: "PSL_JUNCTION_TARGET_FK_NOT_ID",
|
|
320
|
+
message: `Backrelation list field "${listField}" found junction model "${nearMiss.junctionModelName}", but its foreign key to "${targetModelName}" does not reference "${targetModelName}"'s @id. The junction's target-side foreign key must reference "${targetModelName}"'s full @id columns for many-to-many recognition.`,
|
|
321
|
+
...source.at(candidate.field.span),
|
|
322
|
+
data
|
|
323
|
+
};
|
|
324
|
+
return {
|
|
325
|
+
code: "PSL_JUNCTION_ID_NOT_FK_COVERING",
|
|
326
|
+
message: `Backrelation list field "${listField}" found junction-shaped model "${nearMiss.junctionModelName}" linking "${modelName(candidate.modelName)}" and "${targetModelName}", but its id does not cover exactly its foreign-key columns. Declare @@id([...]) on "${nearMiss.junctionModelName}" listing exactly the two foreign-key columns for many-to-many recognition.`,
|
|
327
|
+
...source.at(candidate.field.span),
|
|
328
|
+
data
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
function manyToManyRelationNode(candidate, pair) {
|
|
332
|
+
return {
|
|
333
|
+
fieldName: candidate.field.name,
|
|
334
|
+
toModel: modelName(pair.childFk.targetModelName),
|
|
335
|
+
toTable: pair.childFk.targetTableName,
|
|
336
|
+
...ifDefined("toNamespaceId", pair.childFk.targetNamespaceId),
|
|
337
|
+
cardinality: "N:M",
|
|
338
|
+
on: {
|
|
339
|
+
parentTable: candidate.tableName,
|
|
340
|
+
parentColumns: pair.parentFk.referencedColumns,
|
|
341
|
+
childTable: pair.parentFk.declaringTableName,
|
|
342
|
+
childColumns: pair.parentFk.localColumns
|
|
343
|
+
},
|
|
344
|
+
through: {
|
|
345
|
+
table: pair.parentFk.declaringTableName,
|
|
346
|
+
...ifDefined("namespaceId", pair.parentFk.declaringNamespaceId),
|
|
347
|
+
parentColumns: pair.parentFk.localColumns,
|
|
348
|
+
childColumns: pair.childColumnsInTargetIdOrder
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function relationsForModel(modelRelations, modelName) {
|
|
353
|
+
const existing = modelRelations.get(modelName);
|
|
354
|
+
if (existing) return existing;
|
|
355
|
+
const created = [];
|
|
356
|
+
modelRelations.set(modelName, created);
|
|
357
|
+
return created;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* A set of columns is unique when it exactly matches one of the model's unique
|
|
361
|
+
* column sets — its primary key, any single- or multi-column `@unique` /
|
|
362
|
+
* `@@unique` constraint, or a unique index over plain columns with no `where`
|
|
363
|
+
* clause. Set equality (not subset) is required: a singular back-relation means
|
|
364
|
+
* at most one child per parent, which a unique constraint covering exactly the
|
|
365
|
+
* FK columns guarantees.
|
|
366
|
+
*/
|
|
367
|
+
function fkColumnsAreUnique(localColumns, uniqueColumnSets) {
|
|
368
|
+
const local = new Set(localColumns);
|
|
369
|
+
return uniqueColumnSets.some((columns) => columns.length === local.size && columns.every((column) => local.has(column)));
|
|
370
|
+
}
|
|
371
|
+
function applyBackrelationCandidates(input) {
|
|
372
|
+
for (const candidate of input.backrelationCandidates) {
|
|
373
|
+
const source = diagnosticSource(input.sources, candidate.field.node.syntax);
|
|
374
|
+
const pairMatches = input.fkRelationsByPair.get(candidate.targetModelName)?.get(candidate.modelName) ?? [];
|
|
375
|
+
const matches = candidate.relationName ? pairMatches.filter((relation) => relation.relationName === candidate.relationName) : [...pairMatches];
|
|
376
|
+
if (matches.length === 0) {
|
|
377
|
+
const invalidIndex = input.invalidFkPairings.findIndex((pairing) => {
|
|
378
|
+
if (pairing.relationName !== candidate.relationName) return false;
|
|
379
|
+
if ("pairKey" in pairing) return typeof candidate.targetModelName === "string" && typeof candidate.modelName === "string" && pairing.pairKey === fkRelationPairKey(candidate.targetModelName, candidate.modelName);
|
|
380
|
+
return pairing.declaringModel === candidate.targetModelName && pairing.targetModel === candidate.modelName;
|
|
381
|
+
});
|
|
382
|
+
if (invalidIndex !== -1) {
|
|
383
|
+
input.invalidFkPairings.splice(invalidIndex, 1);
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
if (candidate.isList) {
|
|
387
|
+
const { pairs: junctionPairs, nearMisses } = findJunctionFkPairs({
|
|
388
|
+
candidate,
|
|
389
|
+
fkRelationsByDeclaringModel: input.fkRelationsByDeclaringModel,
|
|
390
|
+
modelIdColumns: input.modelIdColumns
|
|
391
|
+
});
|
|
392
|
+
const junctionPair = junctionPairs[0];
|
|
393
|
+
if (junctionPairs.length === 1 && junctionPair) {
|
|
394
|
+
relationsForModel(input.modelRelations, candidate.modelName).push(manyToManyRelationNode(candidate, junctionPair));
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
if (junctionPairs.length > 1) {
|
|
398
|
+
input.diagnostics.push({
|
|
399
|
+
code: "PSL_AMBIGUOUS_BACKRELATION",
|
|
400
|
+
message: `Backrelation list field "${modelName(candidate.modelName)}.${candidate.field.name}" matches multiple junction FK pairs for a many-to-many relation. Add @relation(name: "...") (or @relation("...")) to the list field and the junction FK-side relation pointing back at "${modelName(candidate.modelName)}" to disambiguate.`,
|
|
401
|
+
...source.at(candidate.field.span)
|
|
402
|
+
});
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
const nearMiss = nearMisses[0];
|
|
406
|
+
if (nearMiss) {
|
|
407
|
+
input.diagnostics.push(junctionNearMissDiagnostic(candidate, nearMiss, input.sources));
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
input.diagnostics.push({
|
|
412
|
+
code: "PSL_ORPHANED_BACKRELATION",
|
|
413
|
+
message: `Backrelation field "${modelName(candidate.modelName)}.${candidate.field.name}" has no matching FK-side relation on model "${modelName(candidate.targetModelName)}". Add @relation(fields: [...], references: [...]) on the FK-side relation${candidate.isList ? " or use an explicit join model for many-to-many" : ""}.`,
|
|
414
|
+
...source.at(candidate.field.span)
|
|
415
|
+
});
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
if (matches.length > 1) {
|
|
419
|
+
input.diagnostics.push({
|
|
420
|
+
code: "PSL_AMBIGUOUS_BACKRELATION",
|
|
421
|
+
message: `Backrelation field "${modelName(candidate.modelName)}.${candidate.field.name}" matches multiple FK-side relations on model "${modelName(candidate.targetModelName)}". Add @relation(name: "...") (or @relation("...")) to both sides to disambiguate.`,
|
|
422
|
+
...source.at(candidate.field.span)
|
|
423
|
+
});
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
invariant(matches.length === 1, "Backrelation matching requires exactly one match");
|
|
427
|
+
const matched = matches[0];
|
|
428
|
+
assertDefined(matched, "Backrelation matching requires a defined relation match");
|
|
429
|
+
if (!candidate.isList) {
|
|
430
|
+
const uniqueColumnSets = input.modelUniqueColumnSets.get(matched.declaringModelName) ?? [];
|
|
431
|
+
if (!fkColumnsAreUnique(matched.localColumns, uniqueColumnSets)) {
|
|
432
|
+
input.diagnostics.push({
|
|
433
|
+
code: "PSL_NON_UNIQUE_BACKRELATION",
|
|
434
|
+
message: `Backrelation field "${modelName(candidate.modelName)}.${candidate.field.name}" is singular, but the matching FK on "${modelName(matched.declaringModelName)}" (fields ${matched.localColumns.map((column) => `"${column}"`).join(", ")}) is not unique. A singular back-relation implies at most one related row; add @unique (or @@unique([...])) to the FK fields, or make "${candidate.field.name}" a list.`,
|
|
435
|
+
...source.at(candidate.field.span)
|
|
436
|
+
});
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (!candidate.isList && !candidate.field.optional) input.diagnostics.push(requiredOneToOneBackrelationDiagnostic({
|
|
441
|
+
modelName: modelName(candidate.modelName),
|
|
442
|
+
field: candidate.field,
|
|
443
|
+
targetModelName: modelName(candidate.targetModelName),
|
|
444
|
+
sources: input.sources,
|
|
445
|
+
recordNoun: "row"
|
|
446
|
+
}));
|
|
447
|
+
relationsForModel(input.modelRelations, candidate.modelName).push({
|
|
448
|
+
fieldName: candidate.field.name,
|
|
449
|
+
toModel: modelName(matched.declaringModelName),
|
|
450
|
+
toTable: matched.declaringTableName,
|
|
451
|
+
...ifDefined("toNamespaceId", matched.declaringNamespaceId),
|
|
452
|
+
...candidate.isList ? { cardinality: "1:N" } : {
|
|
453
|
+
cardinality: "1:1",
|
|
454
|
+
nullable: true
|
|
455
|
+
},
|
|
456
|
+
on: {
|
|
457
|
+
parentTable: candidate.tableName,
|
|
458
|
+
parentColumns: matched.referencedColumns,
|
|
459
|
+
childTable: matched.declaringTableName,
|
|
460
|
+
childColumns: matched.localColumns
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function validateBackrelationFieldAttributes(input) {
|
|
466
|
+
const source = diagnosticSource(input.sources, input.field.node.syntax);
|
|
467
|
+
let valid = true;
|
|
468
|
+
for (const attribute of input.field.attributes) {
|
|
469
|
+
if (attribute.name === "relation") continue;
|
|
470
|
+
input.diagnostics.push({
|
|
471
|
+
code: "PSL_UNSUPPORTED_FIELD_ATTRIBUTE",
|
|
472
|
+
message: `Field "${input.modelName}.${input.field.name}" uses unsupported attribute "@${attribute.name}"`,
|
|
473
|
+
...source.at(attribute.span)
|
|
474
|
+
});
|
|
475
|
+
valid = false;
|
|
476
|
+
}
|
|
477
|
+
return valid;
|
|
478
|
+
}
|
|
479
|
+
function buildComposedExtensionPackRefs(target, extensionIds, extensionPackRefs = []) {
|
|
480
|
+
if (extensionIds.length === 0) return;
|
|
481
|
+
const extensionPackRefById = new Map(extensionPackRefs.map((packRef) => [packRef.id, packRef]));
|
|
482
|
+
return Object.fromEntries(extensionIds.map((extensionId) => [extensionId, extensionPackRefById.get(extensionId) ?? {
|
|
483
|
+
kind: "extension",
|
|
484
|
+
id: extensionId,
|
|
485
|
+
familyId: target.familyId,
|
|
486
|
+
targetId: target.targetId,
|
|
487
|
+
version: "0.0.1"
|
|
488
|
+
}]));
|
|
489
|
+
}
|
|
490
|
+
function compareStrings(left, right) {
|
|
491
|
+
if (left < right) return -1;
|
|
492
|
+
if (left > right) return 1;
|
|
493
|
+
return 0;
|
|
494
|
+
}
|
|
495
|
+
function declarationsHoldingModels(namespace) {
|
|
496
|
+
const declarations = /* @__PURE__ */ new Set();
|
|
497
|
+
for (const model of Object.values(namespace.models)) {
|
|
498
|
+
const written = model.node.syntax.findAncestor(NamespaceDeclarationAst.cast);
|
|
499
|
+
if (written !== void 0) declarations.add(written.syntax);
|
|
500
|
+
}
|
|
501
|
+
return declarations;
|
|
502
|
+
}
|
|
503
|
+
function validateNamespaceBlocksForSqlTarget(input) {
|
|
504
|
+
if (input.target.supportsNamespaces === false) {
|
|
505
|
+
const targetName = input.target.displayName ?? input.target.targetId;
|
|
506
|
+
for (const namespace of input.namespaces) for (const { node, span } of namespace.declarations) input.diagnostics.push({
|
|
507
|
+
code: "PSL_UNSUPPORTED_NAMESPACE_BLOCK",
|
|
508
|
+
message: `${targetName} does not support \`namespace ${node.name()?.name() ?? namespace.name} { … }\` blocks (declare models at the document top level instead).`,
|
|
509
|
+
...diagnosticSource(input.sources, node.syntax).at(span)
|
|
510
|
+
});
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
const unboundNamespace = input.namespaces.find((namespace) => namespace.id === UNBOUND_NAMESPACE_ID && Object.keys(namespace.models).length > 0);
|
|
514
|
+
const hasSibling = input.namespaces.some((namespace) => namespace.id !== UNBOUND_NAMESPACE_ID && namespace.declarations.length > 0);
|
|
515
|
+
if (unboundNamespace !== void 0 && hasSibling) {
|
|
516
|
+
const holdingModels = declarationsHoldingModels(unboundNamespace);
|
|
517
|
+
for (const { node, span } of unboundNamespace.declarations) {
|
|
518
|
+
if (!holdingModels.has(node.syntax)) continue;
|
|
519
|
+
input.diagnostics.push({
|
|
520
|
+
code: "PSL_RESERVED_NAMESPACE_NAME",
|
|
521
|
+
message: "Namespace \"unbound\" is reserved for the late-binding sentinel mapping; a `namespace unbound { … }` containing models cannot appear alongside other named namespace blocks. Use `namespace unbound { … }` alone (no sibling named namespaces) for late-binding multi-tenant contracts.",
|
|
522
|
+
...diagnosticSource(input.sources, node.syntax).at(span)
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Walks the flat `entityTypes` namespace tree in `authoringContributions` and
|
|
529
|
+
* returns a map from discriminator string to the matching descriptor. The
|
|
530
|
+
* interpreter uses this to dispatch parsed extension blocks to their factory
|
|
531
|
+
* without naming any specific discriminator value (generic, by-discriminator).
|
|
532
|
+
*/
|
|
533
|
+
function buildEntityTypesByDiscriminator(contributions) {
|
|
534
|
+
const result = /* @__PURE__ */ new Map();
|
|
535
|
+
const namespace = contributions?.entityTypes;
|
|
536
|
+
if (namespace === void 0) return result;
|
|
537
|
+
const walk = (node) => {
|
|
538
|
+
for (const value of Object.values(node)) if (isAuthoringEntityTypeDescriptor(value)) result.set(value.discriminator, value);
|
|
539
|
+
else if (typeof value === "object" && value !== null) walk(value);
|
|
540
|
+
};
|
|
541
|
+
walk(namespace);
|
|
542
|
+
return result;
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* The `PSL_DUPLICATE_ATTRIBUTE` diagnostic for a model attribute declared
|
|
546
|
+
* more than once on one model. Shared by the built-in `@@control` path and
|
|
547
|
+
* the contributed-model-attribute path so the code and wording stay in one
|
|
548
|
+
* place. `name` is the bare attribute name (`control`, `rls`, …).
|
|
549
|
+
*/
|
|
550
|
+
function duplicateModelAttributeDiagnostic(input) {
|
|
551
|
+
return {
|
|
552
|
+
code: "PSL_DUPLICATE_ATTRIBUTE",
|
|
553
|
+
message: `\`@@${input.name}\` declared more than once on model "${input.modelName}".`,
|
|
554
|
+
...input.source.at(input.span)
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
function isResolvedModelReference(value) {
|
|
558
|
+
if (typeof value !== "object" || value === null || !("declaration" in value)) return false;
|
|
559
|
+
const declaration = value.declaration;
|
|
560
|
+
return typeof declaration === "object" && declaration !== null && "kind" in declaration && declaration.kind === "model";
|
|
561
|
+
}
|
|
562
|
+
function validateBlockModelAttributeRequirements(input) {
|
|
563
|
+
for (const [blockSymbol, envelope] of input.parsedBlocks) {
|
|
564
|
+
const requirement = findBlockDescriptor(input.pslBlockDescriptors, blockSymbol.keyword)?.requiresModelAttribute;
|
|
565
|
+
if (requirement === void 0) continue;
|
|
566
|
+
const target = envelope.values[requirement.parameter];
|
|
567
|
+
if (!isResolvedModelReference(target)) continue;
|
|
568
|
+
const model = target.declaration;
|
|
569
|
+
if (model.attributes.some((attribute) => attribute.name === requirement.attribute)) continue;
|
|
570
|
+
input.diagnostics.push({
|
|
571
|
+
code: "PSL_EXTENSION_TARGET_MODEL_MISSING_ATTRIBUTE",
|
|
572
|
+
message: `\`${blockSymbol.keyword}\` block "${envelope.name}" targets model "${model.name}", which does not declare \`@@${requirement.attribute}\`. Add \`@@${requirement.attribute}\` to model "${model.name}".`,
|
|
573
|
+
...diagnosticSource(input.sources, blockSymbol.node.syntax).at(envelope.parameterSpans[requirement.parameter] ?? envelope.span)
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Walks the flat `modelAttributes` namespace tree in `authoringContributions`
|
|
579
|
+
* and returns a map from bare `@@` attribute name to the matching
|
|
580
|
+
* descriptor. The model-attribute loop in `buildModelNodeFromPsl` uses this
|
|
581
|
+
* to dispatch a contributed attribute without naming any specific attribute.
|
|
582
|
+
*/
|
|
583
|
+
function buildModelAttributesByName(contributions) {
|
|
584
|
+
const result = /* @__PURE__ */ new Map();
|
|
585
|
+
const namespace = contributions?.modelAttributes;
|
|
586
|
+
if (namespace === void 0) return result;
|
|
587
|
+
const walk = (node) => {
|
|
588
|
+
for (const value of Object.values(node)) if (isAuthoringModelAttributeDescriptor(value)) result.set(value.attribute, value);
|
|
589
|
+
else if (typeof value === "object" && value !== null) walk(value);
|
|
590
|
+
};
|
|
591
|
+
walk(namespace);
|
|
592
|
+
return result;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* This pass is intentionally generic: no discriminator value is named here.
|
|
596
|
+
* The factory (registered by the target pack) owns all block-specific logic.
|
|
597
|
+
*/
|
|
598
|
+
function lowerExtensionBlocksForNamespace(blocks, ownerNamespaceId, entityTypesByDiscriminator, entityContext, parsedBlocks, modelCoordinateOf, sources) {
|
|
599
|
+
const rows = [];
|
|
600
|
+
for (const blockSymbol of Object.values(blocks)) {
|
|
601
|
+
const envelope = parsedBlocks.get(blockSymbol);
|
|
602
|
+
if (envelope === void 0) continue;
|
|
603
|
+
const descriptor = entityTypesByDiscriminator.get(envelope.kind);
|
|
604
|
+
if (descriptor === void 0) continue;
|
|
605
|
+
let resolvedModelRefs;
|
|
606
|
+
for (const [paramName, value] of Object.entries(envelope.values)) {
|
|
607
|
+
if (!isResolvedModelReference(value)) continue;
|
|
608
|
+
const coordinate = modelCoordinateOf(value.declaration);
|
|
609
|
+
invariant(coordinate !== void 0, `model mappings cover every collected model; \`${envelope.keyword}\` block "${envelope.name}" selected model "${value.declaration.name}" in \`${paramName}\` without a storage coordinate`);
|
|
610
|
+
resolvedModelRefs = {
|
|
611
|
+
...resolvedModelRefs ?? {},
|
|
612
|
+
[paramName]: coordinate
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
const annotatedBlock = {
|
|
616
|
+
...envelope,
|
|
617
|
+
namespaceId: ownerNamespaceId,
|
|
618
|
+
...resolvedModelRefs !== void 0 ? { resolvedModelRefs } : {}
|
|
619
|
+
};
|
|
620
|
+
const entity = instantiateAuthoringEntityType(descriptor.discriminator, descriptor, [annotatedBlock], {
|
|
621
|
+
...entityContext,
|
|
622
|
+
sourceId: sources.sourceFileFor(blockSymbol.node.syntax).filename
|
|
623
|
+
});
|
|
624
|
+
if (entity === void 0) continue;
|
|
625
|
+
const namespaceId = providesPslEntityPlacement(descriptor.output) ? descriptor.output.pslPlacement(entity).namespaceId : ownerNamespaceId;
|
|
626
|
+
rows.push({
|
|
627
|
+
namespaceId,
|
|
628
|
+
entityKind: descriptor.discriminator,
|
|
629
|
+
key: envelope.name,
|
|
630
|
+
entity
|
|
631
|
+
});
|
|
632
|
+
const derivedValueSet = deriveValueSetFromEntity(descriptor.output, entity);
|
|
633
|
+
if (derivedValueSet !== void 0) rows.push({
|
|
634
|
+
namespaceId,
|
|
635
|
+
entityKind: "valueSet",
|
|
636
|
+
key: envelope.name,
|
|
637
|
+
entity: derivedValueSet
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
return rows;
|
|
641
|
+
}
|
|
642
|
+
function processEnumDeclarations(input) {
|
|
643
|
+
const enumHandles = /* @__PURE__ */ new Map();
|
|
644
|
+
const enumTypeDescriptors = /* @__PURE__ */ new Map();
|
|
645
|
+
if (input.enumBlocks.length === 0) return {
|
|
646
|
+
enumHandles,
|
|
647
|
+
enumTypeDescriptors
|
|
648
|
+
};
|
|
649
|
+
const enumDescriptor = getAuthoringEntity(input.authoringContributions, ["enum"]);
|
|
650
|
+
if (!enumDescriptor) {
|
|
651
|
+
for (const symbol of input.enumBlocks) input.diagnostics.push({
|
|
652
|
+
code: "PSL_ENUM_MISSING_FACTORY",
|
|
653
|
+
message: `enum "${symbol.name}" requires an "enum" entityType factory in the active authoring contributions`,
|
|
654
|
+
...diagnosticSource(input.source.sources, symbol.node.syntax).at(symbol.span)
|
|
655
|
+
});
|
|
656
|
+
return {
|
|
657
|
+
enumHandles,
|
|
658
|
+
enumTypeDescriptors
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
for (const symbol of input.enumBlocks) {
|
|
662
|
+
const envelope = input.parsedBlocks.get(symbol);
|
|
663
|
+
input.diagnostics.push(...enumMemberAttributeDiagnostics(symbol, input.source.sources));
|
|
664
|
+
if (envelope === void 0) continue;
|
|
665
|
+
const handle = instantiateAuthoringEntityType("enum", enumDescriptor, [envelope], {
|
|
666
|
+
...input.entityContext,
|
|
667
|
+
sourceId: input.source.sources.sourceFileFor(symbol.node.syntax).filename
|
|
668
|
+
});
|
|
669
|
+
if (handle === void 0 || handle === null) continue;
|
|
670
|
+
enumHandles.set(symbol, handle);
|
|
671
|
+
enumTypeDescriptors.set(symbol, { codecId: handle.codecId });
|
|
672
|
+
}
|
|
673
|
+
return {
|
|
674
|
+
enumHandles,
|
|
675
|
+
enumTypeDescriptors
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* The owning side of a relation is the one that declares `fields`/`references` on its
|
|
680
|
+
* `@relation` attribute — those name the FK columns. A singular model-typed field whose
|
|
681
|
+
* `@relation` carries only a name (or nothing at all) is the back side: infer prints exactly
|
|
682
|
+
* that shape for a 1:1 back-relation whenever the FK needs disambiguating (two FKs between the
|
|
683
|
+
* same table pair, or a self-referencing unique FK). Checking for the attribute's mere presence
|
|
684
|
+
* would misclassify that back side as the owning side.
|
|
685
|
+
*/
|
|
686
|
+
function relationAttributeDeclaresOwningSide(relationAttribute) {
|
|
687
|
+
return getNamedArgument(relationAttribute, "fields") !== void 0 || getNamedArgument(relationAttribute, "references") !== void 0;
|
|
688
|
+
}
|
|
689
|
+
function relationNullabilityMismatch(relationField, localColumns, resolvedFields) {
|
|
690
|
+
return resolveToOneRelationNullable({
|
|
691
|
+
declaredNullable: relationField.optional,
|
|
692
|
+
localFieldNullability: resolvedFields.filter((resolvedField) => localColumns.includes(resolvedField.columnName)).map((resolvedField) => resolvedField.nullable),
|
|
693
|
+
ownsReference: true
|
|
694
|
+
}).contradiction !== void 0;
|
|
695
|
+
}
|
|
696
|
+
function relationNullabilityMismatchDiagnostic(modelName, relationAttribute, source) {
|
|
697
|
+
const fieldLabel = `Relation field "${modelName}.${relationAttribute.field.name}"`;
|
|
698
|
+
return {
|
|
699
|
+
code: "PSL_RELATION_NULLABILITY_MISMATCH",
|
|
700
|
+
message: relationAttribute.field.optional ? `${fieldLabel} is optional but every field in @relation(fields: [...]) is required. Make one of those fields optional with "?" or remove "?" from "${relationAttribute.field.name}".` : `${fieldLabel} is required but a field in @relation(fields: [...]) is optional. Add "?" to "${relationAttribute.field.name}" or make those fields required.`,
|
|
701
|
+
...source.at(relationAttribute.field.span)
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
function buildModelNodeFromPsl(input) {
|
|
705
|
+
const { model, diagnostics } = input;
|
|
706
|
+
const source = diagnosticSource(input.sources, model.node.syntax);
|
|
707
|
+
const tableName = storageName(model, input.physicalNames);
|
|
708
|
+
const specContext = modelSpecContext({
|
|
709
|
+
symbols: input.symbolTable,
|
|
710
|
+
model,
|
|
711
|
+
defaultFunctionRegistry: input.defaultFunctionRegistry,
|
|
712
|
+
generatorFunctions: input.generatorFunctions,
|
|
713
|
+
dataTypes: input.dataTypes
|
|
714
|
+
});
|
|
715
|
+
const modelNamespaceId = input.namespaceId;
|
|
716
|
+
const resolvedFields = collectResolvedFields({
|
|
717
|
+
model,
|
|
718
|
+
physicalNames: input.physicalNames,
|
|
719
|
+
symbolTable: input.symbolTable,
|
|
720
|
+
enumTypeDescriptors: input.enumTypeDescriptors,
|
|
721
|
+
typeAliases: input.typeAliases,
|
|
722
|
+
valueObjectTypes: input.valueObjectTypes,
|
|
723
|
+
authoringContributions: input.authoringContributions,
|
|
724
|
+
targetId: input.targetId,
|
|
725
|
+
defaultFunctionRegistry: input.defaultFunctionRegistry,
|
|
726
|
+
generatorFunctions: input.generatorFunctions,
|
|
727
|
+
dataTypes: input.dataTypes,
|
|
728
|
+
diagnostics,
|
|
729
|
+
sources: input.sources,
|
|
730
|
+
binder: input.binder,
|
|
731
|
+
scalarColumnDescriptors: input.scalarColumnDescriptors,
|
|
732
|
+
enumHandles: input.enumHandles,
|
|
733
|
+
capabilities: input.capabilities,
|
|
734
|
+
namespaceId: modelNamespaceId,
|
|
735
|
+
...ifDefined("namespaceExtensionEntities", input.namespaceExtensionEntities),
|
|
736
|
+
codecLookup: input.codecLookup
|
|
737
|
+
});
|
|
738
|
+
const inlineIdFields = resolvedFields.filter((field) => field.isId);
|
|
739
|
+
if (inlineIdFields.length > 1) diagnostics.push({
|
|
740
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
741
|
+
message: `Model "${model.name}" cannot declare inline @id on multiple fields; use model-level @@id([...]) for composite identity`,
|
|
742
|
+
...source.at(model.span)
|
|
743
|
+
});
|
|
744
|
+
const singleInlineIdField = inlineIdFields.length === 1 ? inlineIdFields[0] : void 0;
|
|
745
|
+
let primaryKey = singleInlineIdField ? {
|
|
746
|
+
columns: [singleInlineIdField.columnName],
|
|
747
|
+
...ifDefined("name", singleInlineIdField.idName)
|
|
748
|
+
} : void 0;
|
|
749
|
+
const hasInlinePrimaryKey = primaryKey !== void 0;
|
|
750
|
+
let blockPrimaryKeyDeclared = false;
|
|
751
|
+
let controlPolicyDeclared = false;
|
|
752
|
+
let controlPolicy;
|
|
753
|
+
const declaredContributedModelAttributes = /* @__PURE__ */ new Set();
|
|
754
|
+
const modelAttributeEntities = {};
|
|
755
|
+
const resultBackrelationCandidates = [];
|
|
756
|
+
for (const field of Object.values(model.fields)) {
|
|
757
|
+
const backrelationTarget = backrelationTargetSymbol(field, input.binder);
|
|
758
|
+
if (backrelationTarget === void 0) continue;
|
|
759
|
+
const relationAttribute = getAttribute(field.attributes, "relation");
|
|
760
|
+
if (!field.list && relationAttribute && relationAttributeDeclaresOwningSide(relationAttribute)) continue;
|
|
761
|
+
const attributesValid = validateBackrelationFieldAttributes({
|
|
762
|
+
modelName: model.name,
|
|
763
|
+
field,
|
|
764
|
+
sources: input.sources,
|
|
765
|
+
binder: input.binder,
|
|
766
|
+
diagnostics
|
|
767
|
+
});
|
|
768
|
+
let relationName;
|
|
769
|
+
if (relationAttribute) {
|
|
770
|
+
const parsedRelation = interpretRelationAttribute({
|
|
771
|
+
selfModel: model,
|
|
772
|
+
field,
|
|
773
|
+
specContext: fieldSpecContext({
|
|
774
|
+
...specContext,
|
|
775
|
+
field,
|
|
776
|
+
binder: input.binder
|
|
777
|
+
}),
|
|
778
|
+
symbols: input.symbolTable,
|
|
779
|
+
sources: input.sources,
|
|
780
|
+
binder: input.binder,
|
|
781
|
+
diagnostics
|
|
782
|
+
});
|
|
783
|
+
if (!parsedRelation) continue;
|
|
784
|
+
if (parsedRelation.fields || parsedRelation.references) {
|
|
785
|
+
diagnostics.push({
|
|
786
|
+
code: "PSL_INVALID_RELATION_ATTRIBUTE",
|
|
787
|
+
message: `Backrelation list field "${model.name}.${field.name}" cannot declare fields/references; define them on the FK-side relation field`,
|
|
788
|
+
...source.at(relationAttribute.span)
|
|
789
|
+
});
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
if (parsedRelation.onDelete || parsedRelation.onUpdate || parsedRelation.index !== void 0) {
|
|
793
|
+
diagnostics.push({
|
|
794
|
+
code: "PSL_INVALID_RELATION_ATTRIBUTE",
|
|
795
|
+
message: `Backrelation list field "${model.name}.${field.name}" cannot declare onDelete/onUpdate/index; define them on the FK-side relation field`,
|
|
796
|
+
...source.at(relationAttribute.span)
|
|
797
|
+
});
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
relationName = parsedRelation.name;
|
|
801
|
+
}
|
|
802
|
+
if (!attributesValid) continue;
|
|
803
|
+
resultBackrelationCandidates.push({
|
|
804
|
+
modelName: model,
|
|
805
|
+
tableName,
|
|
806
|
+
field,
|
|
807
|
+
targetModelName: backrelationTarget,
|
|
808
|
+
isList: field.list,
|
|
809
|
+
...ifDefined("relationName", relationName)
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
const relationAttributes = Object.values(model.fields).map((field) => ({
|
|
813
|
+
field,
|
|
814
|
+
relation: getAttribute(field.attributes, "relation")
|
|
815
|
+
})).filter((entry) => Boolean(entry.relation));
|
|
816
|
+
const uniqueConstraints = resolvedFields.filter((field) => field.isUnique).map((field) => ({
|
|
817
|
+
columns: [field.columnName],
|
|
818
|
+
...ifDefined("name", field.uniqueName)
|
|
819
|
+
}));
|
|
820
|
+
const indexNodes = [];
|
|
821
|
+
const checkNodes = [];
|
|
822
|
+
const foreignKeyNodes = [];
|
|
823
|
+
for (const modelAttribute of model.attributes) {
|
|
824
|
+
if (!Object.hasOwn(sqlAttributeSpecs.model, modelAttribute.name) && !input.modelAttributesByName.has(modelAttribute.name)) continue;
|
|
825
|
+
if (modelAttribute.name === "map") continue;
|
|
826
|
+
if (modelAttribute.name === "discriminator" || modelAttribute.name === "base") continue;
|
|
827
|
+
if (modelAttribute.name === "control") {
|
|
828
|
+
if (controlPolicyDeclared) {
|
|
829
|
+
diagnostics.push(duplicateModelAttributeDiagnostic({
|
|
830
|
+
name: "control",
|
|
831
|
+
modelName: model.name,
|
|
832
|
+
source,
|
|
833
|
+
span: modelAttribute.span
|
|
834
|
+
}));
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
837
|
+
controlPolicyDeclared = true;
|
|
838
|
+
const node = modelAttribute.node;
|
|
839
|
+
const parsed = interpretModelAttribute({
|
|
840
|
+
node,
|
|
841
|
+
spec: sqlAttributeSpecs.model.control(specContext),
|
|
842
|
+
model,
|
|
843
|
+
symbols: input.symbolTable,
|
|
844
|
+
sources: input.sources,
|
|
845
|
+
binder: input.binder,
|
|
846
|
+
diagnostics
|
|
847
|
+
});
|
|
848
|
+
if (parsed !== void 0) controlPolicy = parsed.policy;
|
|
849
|
+
continue;
|
|
850
|
+
}
|
|
851
|
+
const attributeLabel = `Model "${model.name}" @@${modelAttribute.name}`;
|
|
852
|
+
if (modelAttribute.name === "id") {
|
|
853
|
+
if (blockPrimaryKeyDeclared) {
|
|
854
|
+
diagnostics.push({
|
|
855
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
856
|
+
message: `Model "${model.name}" declares @@id more than once`,
|
|
857
|
+
...source.at(modelAttribute.span)
|
|
858
|
+
});
|
|
859
|
+
continue;
|
|
860
|
+
}
|
|
861
|
+
if (hasInlinePrimaryKey) {
|
|
862
|
+
diagnostics.push({
|
|
863
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
864
|
+
message: `Model "${model.name}" cannot declare both field-level @id and model-level @@id`,
|
|
865
|
+
...source.at(modelAttribute.span)
|
|
866
|
+
});
|
|
867
|
+
blockPrimaryKeyDeclared = true;
|
|
868
|
+
continue;
|
|
869
|
+
}
|
|
870
|
+
const node = modelAttribute.node;
|
|
871
|
+
const parsed = interpretModelAttribute({
|
|
872
|
+
node,
|
|
873
|
+
spec: sqlAttributeSpecs.model.id(specContext),
|
|
874
|
+
model,
|
|
875
|
+
symbols: input.symbolTable,
|
|
876
|
+
sources: input.sources,
|
|
877
|
+
binder: input.binder,
|
|
878
|
+
diagnostics
|
|
879
|
+
});
|
|
880
|
+
if (parsed === void 0) continue;
|
|
881
|
+
const fieldNames = parsed.fields;
|
|
882
|
+
const nullableFieldName = fieldNames.find((name) => model.fields[name]?.optional === true);
|
|
883
|
+
if (nullableFieldName !== void 0) {
|
|
884
|
+
diagnostics.push({
|
|
885
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
886
|
+
message: `${attributeLabel} cannot include optional field "${nullableFieldName}"; primary key columns must be NOT NULL`,
|
|
887
|
+
...source.at(modelAttribute.span)
|
|
888
|
+
});
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
const columnNames = mapFieldNamesToColumns({
|
|
892
|
+
model,
|
|
893
|
+
physicalNames: input.physicalNames,
|
|
894
|
+
fieldNames,
|
|
895
|
+
source,
|
|
896
|
+
diagnostics,
|
|
897
|
+
span: modelAttribute.span,
|
|
898
|
+
entityLabel: attributeLabel
|
|
899
|
+
});
|
|
900
|
+
if (!columnNames) continue;
|
|
901
|
+
primaryKey = {
|
|
902
|
+
columns: columnNames,
|
|
903
|
+
...ifDefined("name", parsed.map)
|
|
904
|
+
};
|
|
905
|
+
blockPrimaryKeyDeclared = true;
|
|
906
|
+
continue;
|
|
907
|
+
}
|
|
908
|
+
if (modelAttribute.name === "unique") {
|
|
909
|
+
const node = modelAttribute.node;
|
|
910
|
+
const parsed = interpretModelAttribute({
|
|
911
|
+
node,
|
|
912
|
+
spec: sqlAttributeSpecs.model.unique(specContext),
|
|
913
|
+
model,
|
|
914
|
+
symbols: input.symbolTable,
|
|
915
|
+
sources: input.sources,
|
|
916
|
+
binder: input.binder,
|
|
917
|
+
diagnostics
|
|
918
|
+
});
|
|
919
|
+
if (parsed === void 0) continue;
|
|
920
|
+
const columnNames = mapFieldNamesToColumns({
|
|
921
|
+
model,
|
|
922
|
+
physicalNames: input.physicalNames,
|
|
923
|
+
fieldNames: parsed.fields,
|
|
924
|
+
source,
|
|
925
|
+
diagnostics,
|
|
926
|
+
span: modelAttribute.span,
|
|
927
|
+
entityLabel: attributeLabel
|
|
928
|
+
});
|
|
929
|
+
if (!columnNames) continue;
|
|
930
|
+
uniqueConstraints.push({
|
|
931
|
+
columns: columnNames,
|
|
932
|
+
...ifDefined("name", parsed.map)
|
|
933
|
+
});
|
|
934
|
+
continue;
|
|
935
|
+
}
|
|
936
|
+
if (modelAttribute.name === "index") {
|
|
937
|
+
const node = modelAttribute.node;
|
|
938
|
+
const parsed = interpretModelAttribute({
|
|
939
|
+
node,
|
|
940
|
+
spec: sqlAttributeSpecs.model.index(specContext),
|
|
941
|
+
model,
|
|
942
|
+
symbols: input.symbolTable,
|
|
943
|
+
sources: input.sources,
|
|
944
|
+
binder: input.binder,
|
|
945
|
+
diagnostics
|
|
946
|
+
});
|
|
947
|
+
if (parsed === void 0) continue;
|
|
948
|
+
let columnNames;
|
|
949
|
+
if (parsed.fields !== void 0) {
|
|
950
|
+
const mapped = mapFieldNamesToColumns({
|
|
951
|
+
model,
|
|
952
|
+
physicalNames: input.physicalNames,
|
|
953
|
+
fieldNames: parsed.fields,
|
|
954
|
+
source,
|
|
955
|
+
diagnostics,
|
|
956
|
+
span: modelAttribute.span,
|
|
957
|
+
entityLabel: attributeLabel
|
|
958
|
+
});
|
|
959
|
+
if (!mapped) continue;
|
|
960
|
+
columnNames = mapped;
|
|
961
|
+
}
|
|
962
|
+
indexNodes.push(blindCast({
|
|
963
|
+
...ifDefined("columns", columnNames),
|
|
964
|
+
...ifDefined("expression", parsed.expression === void 0 ? void 0 : sqlTextFromStored(parsed.expression.value.value)),
|
|
965
|
+
where: parsed.where === void 0 ? void 0 : sqlTextFromStored(parsed.where.value.value),
|
|
966
|
+
unique: parsed.unique,
|
|
967
|
+
name: parsed.name,
|
|
968
|
+
map: parsed.map,
|
|
969
|
+
type: parsed.type,
|
|
970
|
+
options: parsed.options
|
|
971
|
+
}));
|
|
972
|
+
continue;
|
|
973
|
+
}
|
|
974
|
+
if (modelAttribute.name === "check") {
|
|
975
|
+
const node = modelAttribute.node;
|
|
976
|
+
if (input.capabilities["sql"]?.["checkConstraint"] !== true) {
|
|
977
|
+
diagnostics.push({
|
|
978
|
+
code: "PSL_CHECK_UNSUPPORTED_TARGET",
|
|
979
|
+
message: `Model "${model.name}" declares "@@check", but target "${input.targetId}" does not support check constraints (the adapter does not report the "checkConstraint" capability). Remove the check or author it against a target that supports check constraints.`,
|
|
980
|
+
...source.at(modelAttribute.span)
|
|
981
|
+
});
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
const parsed = interpretModelAttribute({
|
|
985
|
+
node,
|
|
986
|
+
spec: sqlAttributeSpecs.model.check(specContext),
|
|
987
|
+
model,
|
|
988
|
+
symbols: input.symbolTable,
|
|
989
|
+
sources: input.sources,
|
|
990
|
+
binder: input.binder,
|
|
991
|
+
diagnostics
|
|
992
|
+
});
|
|
993
|
+
if (parsed === void 0) continue;
|
|
994
|
+
checkNodes.push({
|
|
995
|
+
expression: sqlTextFromStored(parsed.expression.value.value),
|
|
996
|
+
name: parsed.name,
|
|
997
|
+
map: parsed.map
|
|
998
|
+
});
|
|
999
|
+
continue;
|
|
1000
|
+
}
|
|
1001
|
+
const contributedModelAttribute = input.modelAttributesByName.get(modelAttribute.name);
|
|
1002
|
+
if (contributedModelAttribute !== void 0) {
|
|
1003
|
+
if (contributedModelAttribute.repeatable !== true && declaredContributedModelAttributes.has(modelAttribute.name)) {
|
|
1004
|
+
diagnostics.push(duplicateModelAttributeDiagnostic({
|
|
1005
|
+
name: modelAttribute.name,
|
|
1006
|
+
modelName: model.name,
|
|
1007
|
+
source,
|
|
1008
|
+
span: modelAttribute.span
|
|
1009
|
+
}));
|
|
1010
|
+
continue;
|
|
1011
|
+
}
|
|
1012
|
+
declaredContributedModelAttributes.add(modelAttribute.name);
|
|
1013
|
+
const node = modelAttribute.node;
|
|
1014
|
+
const specFactory = input.contributedModelAttributeSpecs[contributedModelAttribute.attribute];
|
|
1015
|
+
if (specFactory === void 0) continue;
|
|
1016
|
+
const parsed = interpretModelAttribute({
|
|
1017
|
+
node,
|
|
1018
|
+
spec: specFactory(specContext),
|
|
1019
|
+
model,
|
|
1020
|
+
symbols: input.symbolTable,
|
|
1021
|
+
sources: input.sources,
|
|
1022
|
+
binder: input.binder,
|
|
1023
|
+
diagnostics
|
|
1024
|
+
});
|
|
1025
|
+
if (parsed === void 0) continue;
|
|
1026
|
+
const lowered = blindCast(contributedModelAttribute.lower)(parsed, {
|
|
1027
|
+
family: input.familyId,
|
|
1028
|
+
target: input.targetId,
|
|
1029
|
+
codecLookup: input.codecLookup,
|
|
1030
|
+
dataTypes: input.dataTypes,
|
|
1031
|
+
modelName: model.name,
|
|
1032
|
+
storageName: tableName,
|
|
1033
|
+
fieldStorageName: (fieldName) => {
|
|
1034
|
+
const field = model.fields[fieldName];
|
|
1035
|
+
return field === void 0 ? void 0 : storageName(field, input.physicalNames);
|
|
1036
|
+
},
|
|
1037
|
+
fieldCodecId: (fieldName) => resolvedFields.find((resolved) => resolved.field.name === fieldName)?.descriptor.codecId,
|
|
1038
|
+
namespaceId: modelNamespaceId,
|
|
1039
|
+
sourceId: source.sources.sourceFileFor(source.node).filename,
|
|
1040
|
+
diagnostics: { push: (d) => {
|
|
1041
|
+
diagnostics.pushExternal(blindCast(d));
|
|
1042
|
+
} }
|
|
1043
|
+
});
|
|
1044
|
+
if (lowered === void 0) continue;
|
|
1045
|
+
if ("index" in lowered) {
|
|
1046
|
+
if (!isAuthoredIndexInput(lowered.index)) throw contractError("CONTRACT.PACK_CONTRIBUTION_INVALID", `model attribute "@@${modelAttribute.name}" on model "${model.name}" lowered to a malformed index. A contributed attribute that returns { index } must return an authored-index input: exactly one of a columns list or an expression, plus explicit where/unique/name/map and a type-with-options pair.`, { meta: {
|
|
1047
|
+
attribute: modelAttribute.name,
|
|
1048
|
+
modelName: model.name
|
|
1049
|
+
} });
|
|
1050
|
+
indexNodes.push(lowered.index);
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
const slot = modelAttributeEntities[contributedModelAttribute.attribute] ?? {};
|
|
1054
|
+
modelAttributeEntities[contributedModelAttribute.attribute] = slot;
|
|
1055
|
+
slot[lowered.key] = lowered.entity;
|
|
1056
|
+
continue;
|
|
1057
|
+
}
|
|
1058
|
+
throw new InternalError(`Model attribute "@@${modelAttribute.name}" is registered but has no interpreter branch`);
|
|
1059
|
+
}
|
|
1060
|
+
const resultFkRelationMetadata = [];
|
|
1061
|
+
const relationIndexLocations = [];
|
|
1062
|
+
const resultInvalidFkPairings = [];
|
|
1063
|
+
const resultCrossSpaceRelations = [];
|
|
1064
|
+
for (const relationAttribute of relationAttributes) {
|
|
1065
|
+
const { typeName: fieldTypeName, typeNamespaceId: fieldTypeNamespaceId, typeContractSpaceId: fieldTypeContractSpaceId } = relationAttribute.field;
|
|
1066
|
+
if (relationAttribute.field.list) {
|
|
1067
|
+
if (fieldTypeContractSpaceId !== void 0) diagnostics.push({
|
|
1068
|
+
code: "PSL_UNSUPPORTED_CROSS_SPACE_LIST",
|
|
1069
|
+
message: `Relation field "${model.name}.${relationAttribute.field.name}" is a cross-space list relation (type "${fieldTypeContractSpaceId}:${fieldTypeNamespaceId !== void 0 ? `${fieldTypeNamespaceId}.` : ""}${fieldTypeName}[]"). Cross-space relations must be singular in v0.1 — list cross-space relations are not supported.`,
|
|
1070
|
+
...source.at(relationAttribute.field.span)
|
|
1071
|
+
});
|
|
1072
|
+
continue;
|
|
1073
|
+
}
|
|
1074
|
+
if (!relationAttributeDeclaresOwningSide(relationAttribute.relation)) continue;
|
|
1075
|
+
if (fieldTypeContractSpaceId !== void 0) {
|
|
1076
|
+
const extContractForSpace = input.composedExtensionContracts.get(fieldTypeContractSpaceId);
|
|
1077
|
+
if (extContractForSpace === void 0) {
|
|
1078
|
+
diagnostics.push({
|
|
1079
|
+
code: "PSL_UNKNOWN_CONTRACT_SPACE",
|
|
1080
|
+
message: `Relation field "${model.name}.${relationAttribute.field.name}" references contract space "${fieldTypeContractSpaceId}" which is not declared in extensions. Add "${fieldTypeContractSpaceId}" to extensions in prisma.config.ts.`,
|
|
1081
|
+
...source.at(relationAttribute.field.span),
|
|
1082
|
+
data: {
|
|
1083
|
+
space: fieldTypeContractSpaceId,
|
|
1084
|
+
suggestedPack: fieldTypeContractSpaceId
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
const parsedRelation = interpretRelationAttribute({
|
|
1090
|
+
selfModel: model,
|
|
1091
|
+
field: relationAttribute.field,
|
|
1092
|
+
specContext: fieldSpecContext({
|
|
1093
|
+
...specContext,
|
|
1094
|
+
field: relationAttribute.field,
|
|
1095
|
+
binder: input.binder
|
|
1096
|
+
}),
|
|
1097
|
+
symbols: input.symbolTable,
|
|
1098
|
+
sources: input.sources,
|
|
1099
|
+
binder: input.binder,
|
|
1100
|
+
diagnostics
|
|
1101
|
+
});
|
|
1102
|
+
if (!parsedRelation) continue;
|
|
1103
|
+
if (!parsedRelation.fields || !parsedRelation.references) {
|
|
1104
|
+
diagnostics.push({
|
|
1105
|
+
code: "PSL_INVALID_RELATION_ATTRIBUTE",
|
|
1106
|
+
message: `Relation field "${model.name}.${relationAttribute.field.name}" requires fields and references arguments`,
|
|
1107
|
+
...source.at(relationAttribute.relation.span)
|
|
1108
|
+
});
|
|
1109
|
+
continue;
|
|
1110
|
+
}
|
|
1111
|
+
const localColumns = mapFieldNamesToColumns({
|
|
1112
|
+
model,
|
|
1113
|
+
physicalNames: input.physicalNames,
|
|
1114
|
+
fieldNames: parsedRelation.fields,
|
|
1115
|
+
source,
|
|
1116
|
+
diagnostics,
|
|
1117
|
+
span: relationAttribute.relation.span,
|
|
1118
|
+
entityLabel: `Relation field "${model.name}.${relationAttribute.field.name}"`
|
|
1119
|
+
});
|
|
1120
|
+
if (!localColumns) continue;
|
|
1121
|
+
if (relationNullabilityMismatch(relationAttribute.field, localColumns, resolvedFields)) {
|
|
1122
|
+
diagnostics.push(relationNullabilityMismatchDiagnostic(model.name, relationAttribute, source));
|
|
1123
|
+
continue;
|
|
1124
|
+
}
|
|
1125
|
+
const referencedColumns = parsedRelation.references;
|
|
1126
|
+
if (localColumns.length !== referencedColumns.length) {
|
|
1127
|
+
diagnostics.push({
|
|
1128
|
+
code: "PSL_INVALID_RELATION_ATTRIBUTE",
|
|
1129
|
+
message: `Relation field "${model.name}.${relationAttribute.field.name}" must provide the same number of fields and references`,
|
|
1130
|
+
...source.at(relationAttribute.relation.span)
|
|
1131
|
+
});
|
|
1132
|
+
continue;
|
|
1133
|
+
}
|
|
1134
|
+
const onDelete = parsedRelation.onDelete ? normalizeReferentialAction(parsedRelation.onDelete) : void 0;
|
|
1135
|
+
const onUpdate = parsedRelation.onUpdate ? normalizeReferentialAction(parsedRelation.onUpdate) : void 0;
|
|
1136
|
+
const crossTargetNamespaceId = fieldTypeNamespaceId ?? UNBOUND_NAMESPACE_ID;
|
|
1137
|
+
const extContract = extContractForSpace;
|
|
1138
|
+
const resolvedTable = extContract.domain.namespaces[crossTargetNamespaceId]?.models[fieldTypeName]?.storage["table"];
|
|
1139
|
+
if (typeof resolvedTable !== "string") {
|
|
1140
|
+
const availableModels = Object.keys(extContract.domain.namespaces[crossTargetNamespaceId]?.models ?? {}).join(", ") || "(none)";
|
|
1141
|
+
diagnostics.push({
|
|
1142
|
+
code: "PSL_UNKNOWN_CROSS_SPACE_TARGET",
|
|
1143
|
+
message: `Relation field "${model.name}.${relationAttribute.field.name}" references model "${fieldTypeName}" in namespace "${crossTargetNamespaceId}" of space "${fieldTypeContractSpaceId}", but that model was not found in the extension contract. Available models: ${availableModels}`,
|
|
1144
|
+
...source.at(relationAttribute.field.span),
|
|
1145
|
+
data: {
|
|
1146
|
+
space: fieldTypeContractSpaceId,
|
|
1147
|
+
namespace: crossTargetNamespaceId,
|
|
1148
|
+
model: fieldTypeName
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
1151
|
+
continue;
|
|
1152
|
+
}
|
|
1153
|
+
const crossTargetTableName = resolvedTable;
|
|
1154
|
+
foreignKeyNodes.push({
|
|
1155
|
+
columns: localColumns,
|
|
1156
|
+
references: {
|
|
1157
|
+
model: fieldTypeName,
|
|
1158
|
+
table: crossTargetTableName,
|
|
1159
|
+
columns: referencedColumns,
|
|
1160
|
+
namespaceId: crossTargetNamespaceId,
|
|
1161
|
+
spaceId: fieldTypeContractSpaceId
|
|
1162
|
+
},
|
|
1163
|
+
...ifDefined("name", parsedRelation.map),
|
|
1164
|
+
...ifDefined("onDelete", onDelete),
|
|
1165
|
+
...ifDefined("onUpdate", onUpdate),
|
|
1166
|
+
...ifDefined("index", parsedRelation.index)
|
|
1167
|
+
});
|
|
1168
|
+
if (typeof parsedRelation.index === "string") relationIndexLocations.push({
|
|
1169
|
+
namespaceId: modelNamespaceId,
|
|
1170
|
+
tableName,
|
|
1171
|
+
columns: localColumns,
|
|
1172
|
+
index: parsedRelation.index,
|
|
1173
|
+
location: source.at(relationAttribute.relation.span)
|
|
1174
|
+
});
|
|
1175
|
+
resultCrossSpaceRelations.push({
|
|
1176
|
+
fieldName: relationAttribute.field.name,
|
|
1177
|
+
toModel: fieldTypeName,
|
|
1178
|
+
toTable: crossTargetTableName,
|
|
1179
|
+
cardinality: "N:1",
|
|
1180
|
+
nullable: relationAttribute.field.optional,
|
|
1181
|
+
spaceId: fieldTypeContractSpaceId,
|
|
1182
|
+
namespaceId: crossTargetNamespaceId,
|
|
1183
|
+
on: {
|
|
1184
|
+
parentTable: tableName,
|
|
1185
|
+
parentColumns: localColumns,
|
|
1186
|
+
childTable: crossTargetTableName,
|
|
1187
|
+
childColumns: referencedColumns
|
|
1188
|
+
}
|
|
1189
|
+
});
|
|
1190
|
+
continue;
|
|
1191
|
+
}
|
|
1192
|
+
const qualifiedTypeName = fieldTypeNamespaceId ? `${fieldTypeNamespaceId}.${fieldTypeName}` : fieldTypeName;
|
|
1193
|
+
const typeReference = typeReferenceNode(relationAttribute.field);
|
|
1194
|
+
const targetResolution = typeReference === void 0 ? void 0 : input.binder.symbolForNode(typeReference);
|
|
1195
|
+
if (targetResolution?.kind === "unresolved") continue;
|
|
1196
|
+
if (targetResolution?.kind !== "model") {
|
|
1197
|
+
const foundKind = targetResolution === void 0 ? void 0 : relationTargetKindLabel(targetResolution);
|
|
1198
|
+
diagnostics.push({
|
|
1199
|
+
code: "PSL_INVALID_RELATION_TARGET",
|
|
1200
|
+
message: foundKind === void 0 ? `Relation field "${model.name}.${relationAttribute.field.name}" references unknown model "${qualifiedTypeName}"` : `Relation field "${model.name}.${relationAttribute.field.name}" references ${foundKind} "${qualifiedTypeName}"; a relation target must be a model`,
|
|
1201
|
+
...source.at(relationAttribute.field.span)
|
|
1202
|
+
});
|
|
1203
|
+
continue;
|
|
1204
|
+
}
|
|
1205
|
+
const targetModel = targetResolution.symbol;
|
|
1206
|
+
const targetNamespaceId = targetResolution.namespace.id;
|
|
1207
|
+
const parsedRelation = interpretRelationAttribute({
|
|
1208
|
+
selfModel: model,
|
|
1209
|
+
field: relationAttribute.field,
|
|
1210
|
+
specContext: fieldSpecContext({
|
|
1211
|
+
...specContext,
|
|
1212
|
+
field: relationAttribute.field,
|
|
1213
|
+
binder: input.binder
|
|
1214
|
+
}),
|
|
1215
|
+
symbols: input.symbolTable,
|
|
1216
|
+
sources: input.sources,
|
|
1217
|
+
binder: input.binder,
|
|
1218
|
+
diagnostics
|
|
1219
|
+
});
|
|
1220
|
+
if (!parsedRelation) continue;
|
|
1221
|
+
if (!parsedRelation.fields || !parsedRelation.references) {
|
|
1222
|
+
diagnostics.push({
|
|
1223
|
+
code: "PSL_INVALID_RELATION_ATTRIBUTE",
|
|
1224
|
+
message: `Relation field "${model.name}.${relationAttribute.field.name}" requires fields and references arguments`,
|
|
1225
|
+
...source.at(relationAttribute.relation.span)
|
|
1226
|
+
});
|
|
1227
|
+
continue;
|
|
1228
|
+
}
|
|
1229
|
+
const localColumns = mapFieldNamesToColumns({
|
|
1230
|
+
model,
|
|
1231
|
+
physicalNames: input.physicalNames,
|
|
1232
|
+
fieldNames: parsedRelation.fields,
|
|
1233
|
+
source,
|
|
1234
|
+
diagnostics,
|
|
1235
|
+
span: relationAttribute.relation.span,
|
|
1236
|
+
entityLabel: `Relation field "${model.name}.${relationAttribute.field.name}"`
|
|
1237
|
+
});
|
|
1238
|
+
if (!localColumns) continue;
|
|
1239
|
+
if (relationNullabilityMismatch(relationAttribute.field, localColumns, resolvedFields)) {
|
|
1240
|
+
diagnostics.push(relationNullabilityMismatchDiagnostic(model.name, relationAttribute, source));
|
|
1241
|
+
resultInvalidFkPairings.push({
|
|
1242
|
+
declaringModel: model,
|
|
1243
|
+
targetModel,
|
|
1244
|
+
...ifDefined("relationName", parsedRelation.name)
|
|
1245
|
+
});
|
|
1246
|
+
continue;
|
|
1247
|
+
}
|
|
1248
|
+
const referencedColumns = mapFieldNamesToColumns({
|
|
1249
|
+
model: targetModel,
|
|
1250
|
+
physicalNames: input.physicalNames,
|
|
1251
|
+
fieldNames: parsedRelation.references,
|
|
1252
|
+
source,
|
|
1253
|
+
diagnostics,
|
|
1254
|
+
span: relationAttribute.relation.span,
|
|
1255
|
+
entityLabel: `Relation field "${model.name}.${relationAttribute.field.name}"`
|
|
1256
|
+
});
|
|
1257
|
+
if (!referencedColumns) continue;
|
|
1258
|
+
if (localColumns.length !== referencedColumns.length) {
|
|
1259
|
+
diagnostics.push({
|
|
1260
|
+
code: "PSL_INVALID_RELATION_ATTRIBUTE",
|
|
1261
|
+
message: `Relation field "${model.name}.${relationAttribute.field.name}" must provide the same number of fields and references`,
|
|
1262
|
+
...source.at(relationAttribute.relation.span)
|
|
1263
|
+
});
|
|
1264
|
+
continue;
|
|
1265
|
+
}
|
|
1266
|
+
const onDelete = parsedRelation.onDelete ? normalizeReferentialAction(parsedRelation.onDelete) : void 0;
|
|
1267
|
+
const onUpdate = parsedRelation.onUpdate ? normalizeReferentialAction(parsedRelation.onUpdate) : void 0;
|
|
1268
|
+
const targetTableName = storageName(targetModel, input.physicalNames);
|
|
1269
|
+
foreignKeyNodes.push({
|
|
1270
|
+
columns: localColumns,
|
|
1271
|
+
references: {
|
|
1272
|
+
model: targetModel.name,
|
|
1273
|
+
table: targetTableName,
|
|
1274
|
+
columns: referencedColumns,
|
|
1275
|
+
namespaceId: targetNamespaceId
|
|
1276
|
+
},
|
|
1277
|
+
...ifDefined("name", parsedRelation.map),
|
|
1278
|
+
...ifDefined("onDelete", onDelete),
|
|
1279
|
+
...ifDefined("onUpdate", onUpdate),
|
|
1280
|
+
...ifDefined("index", parsedRelation.index)
|
|
1281
|
+
});
|
|
1282
|
+
if (typeof parsedRelation.index === "string") relationIndexLocations.push({
|
|
1283
|
+
namespaceId: modelNamespaceId,
|
|
1284
|
+
tableName,
|
|
1285
|
+
columns: localColumns,
|
|
1286
|
+
index: parsedRelation.index,
|
|
1287
|
+
location: source.at(relationAttribute.relation.span)
|
|
1288
|
+
});
|
|
1289
|
+
resultFkRelationMetadata.push({
|
|
1290
|
+
declaringModelName: model,
|
|
1291
|
+
declaringFieldName: relationAttribute.field.name,
|
|
1292
|
+
declaringTableName: tableName,
|
|
1293
|
+
...ifDefined("declaringNamespaceId", modelNamespaceId),
|
|
1294
|
+
targetModelName: targetModel,
|
|
1295
|
+
targetTableName,
|
|
1296
|
+
...ifDefined("targetNamespaceId", targetNamespaceId),
|
|
1297
|
+
...ifDefined("relationName", parsedRelation.name),
|
|
1298
|
+
nullable: relationAttribute.field.optional,
|
|
1299
|
+
localColumns,
|
|
1300
|
+
referencedColumns
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
return {
|
|
1304
|
+
modelNode: {
|
|
1305
|
+
modelName: model.name,
|
|
1306
|
+
tableName,
|
|
1307
|
+
fields: resolvedFields.map((resolvedField) => {
|
|
1308
|
+
const common = {
|
|
1309
|
+
fieldName: resolvedField.field.name,
|
|
1310
|
+
columnName: resolvedField.columnName,
|
|
1311
|
+
descriptor: resolvedField.descriptor,
|
|
1312
|
+
nullable: resolvedField.nullable,
|
|
1313
|
+
...ifDefined("many", resolvedField.many),
|
|
1314
|
+
...ifDefined("elementNullable", resolvedField.many ? resolvedField.elementNullable === true : void 0),
|
|
1315
|
+
...ifDefined("default", resolvedField.defaultValue),
|
|
1316
|
+
...ifDefined("executionDefaults", resolvedField.executionDefaults)
|
|
1317
|
+
};
|
|
1318
|
+
if (resolvedField.valueObjectTypeName !== void 0) return {
|
|
1319
|
+
...common,
|
|
1320
|
+
valueObjectName: resolvedField.valueObjectTypeName
|
|
1321
|
+
};
|
|
1322
|
+
return {
|
|
1323
|
+
...common,
|
|
1324
|
+
...ifDefined("enumTypeHandle", resolvedField.enumTypeHandle)
|
|
1325
|
+
};
|
|
1326
|
+
}),
|
|
1327
|
+
...ifDefined("id", primaryKey),
|
|
1328
|
+
...uniqueConstraints.length > 0 ? { uniques: uniqueConstraints } : {},
|
|
1329
|
+
...indexNodes.length > 0 ? { indexes: indexNodes } : {},
|
|
1330
|
+
...checkNodes.length > 0 ? { checks: checkNodes } : {},
|
|
1331
|
+
...foreignKeyNodes.length > 0 ? { foreignKeys: foreignKeyNodes } : {},
|
|
1332
|
+
...ifDefined("control", controlPolicy)
|
|
1333
|
+
},
|
|
1334
|
+
fkRelationMetadata: resultFkRelationMetadata,
|
|
1335
|
+
relationIndexLocations,
|
|
1336
|
+
invalidFkPairings: resultInvalidFkPairings,
|
|
1337
|
+
crossSpaceRelations: resultCrossSpaceRelations,
|
|
1338
|
+
backrelationCandidates: resultBackrelationCandidates,
|
|
1339
|
+
modelAttributeEntities
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1342
|
+
function buildValueObjectNodes(input) {
|
|
1343
|
+
const { compositeTypes, enumHandles, diagnostics, sources, binder } = input;
|
|
1344
|
+
return compositeTypes.map((compositeType) => {
|
|
1345
|
+
for (const attribute of compositeType.attributes) diagnostics.push({
|
|
1346
|
+
code: "PSL_UNSUPPORTED_COMPOSITE_TYPE_ATTRIBUTE",
|
|
1347
|
+
message: `Composite type "${compositeType.name}" uses attribute "@@${attribute.name}", which a composite type does not take`,
|
|
1348
|
+
...diagnosticSource(sources, compositeType.node.syntax).at(attribute.span)
|
|
1349
|
+
});
|
|
1350
|
+
const fields = [];
|
|
1351
|
+
for (const field of Object.values(compositeType.fields)) {
|
|
1352
|
+
for (const attribute of field.attributes) diagnostics.push({
|
|
1353
|
+
code: "PSL_UNSUPPORTED_FIELD_ATTRIBUTE",
|
|
1354
|
+
message: `Member "${field.name}" of composite type "${compositeType.name}" uses attribute "@${attribute.name}", which a composite type member does not take`,
|
|
1355
|
+
...diagnosticSource(sources, field.node.syntax).at(attribute.span)
|
|
1356
|
+
});
|
|
1357
|
+
const common = {
|
|
1358
|
+
fieldName: field.name,
|
|
1359
|
+
nullable: field.optional,
|
|
1360
|
+
...ifDefined("many", field.list ? true : void 0),
|
|
1361
|
+
...ifDefined("elementNullable", field.list ? field.elementOptional : void 0)
|
|
1362
|
+
};
|
|
1363
|
+
const fieldTypeReference = typeReferenceNode(field);
|
|
1364
|
+
const fieldTypeResolution = fieldTypeReference === void 0 ? void 0 : binder.symbolForNode(fieldTypeReference);
|
|
1365
|
+
if (fieldTypeResolution?.kind === "compositeType") {
|
|
1366
|
+
fields.push({
|
|
1367
|
+
...common,
|
|
1368
|
+
valueObjectName: fieldTypeResolution.symbol.name
|
|
1369
|
+
});
|
|
1370
|
+
continue;
|
|
1371
|
+
}
|
|
1372
|
+
const resolved = resolveFieldTypeDescriptor({
|
|
1373
|
+
field,
|
|
1374
|
+
resolution: fieldTypeResolution,
|
|
1375
|
+
enumTypeDescriptors: input.enumTypeDescriptors,
|
|
1376
|
+
typeAliases: input.typeAliases,
|
|
1377
|
+
diagnostics,
|
|
1378
|
+
sources,
|
|
1379
|
+
entityLabel: `Field "${compositeType.name}.${field.name}"`,
|
|
1380
|
+
namespaceId: input.defaultNamespaceId,
|
|
1381
|
+
namespaceExtensionEntities: input.namespaceExtensionEntities,
|
|
1382
|
+
binder,
|
|
1383
|
+
codecLookup: input.codecLookup,
|
|
1384
|
+
dataTypes: input.dataTypes
|
|
1385
|
+
});
|
|
1386
|
+
if (!resolved.ok) continue;
|
|
1387
|
+
const { descriptor } = resolved;
|
|
1388
|
+
if (descriptor.valueSet !== void 0) {
|
|
1389
|
+
diagnostics.push({
|
|
1390
|
+
code: "PSL_UNSUPPORTED_FIELD_TYPE",
|
|
1391
|
+
message: `Field "${compositeType.name}.${field.name}" is typed by the storage enum "${descriptor.valueSet.entityName}", which a composite type member cannot use: a member has no column to store it in. Use a PSL enum instead.`,
|
|
1392
|
+
...diagnosticSource(sources, field.node.syntax).at(field.span)
|
|
1393
|
+
});
|
|
1394
|
+
continue;
|
|
1395
|
+
}
|
|
1396
|
+
const typeAlias = input.typeAliases.ofResolution(fieldTypeResolution);
|
|
1397
|
+
for (const attribute of typeAlias === void 0 ? [] : typeAliasAttributeNames(typeAlias.alias)) diagnostics.push({
|
|
1398
|
+
code: "PSL_UNSUPPORTED_FIELD_ATTRIBUTE",
|
|
1399
|
+
message: `Member "${field.name}" of composite type "${compositeType.name}" is typed by the type alias "${field.typeName}", which carries "@${attribute}", an attribute a composite type member does not take`,
|
|
1400
|
+
...diagnosticSource(sources, field.node.syntax).at(field.span)
|
|
1401
|
+
});
|
|
1402
|
+
fields.push({
|
|
1403
|
+
...common,
|
|
1404
|
+
descriptor: {
|
|
1405
|
+
codecId: descriptor.codecId,
|
|
1406
|
+
...ifDefined("typeParams", descriptor.typeParams)
|
|
1407
|
+
},
|
|
1408
|
+
...ifDefined("enumTypeHandle", fieldTypeResolution?.kind === "block" ? enumHandles.get(fieldTypeResolution.symbol) : typeAlias?.enumHandle)
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
return {
|
|
1412
|
+
name: compositeType.name,
|
|
1413
|
+
fields
|
|
1414
|
+
};
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
function collectPolymorphismDeclarations(identities, symbols, sources, binder, specContextFor, discriminatorFieldOf, codecLookup, dataTypes, diagnostics) {
|
|
1418
|
+
const pendingDiscriminators = /* @__PURE__ */ new Map();
|
|
1419
|
+
const pendingBaseDeclarations = /* @__PURE__ */ new Map();
|
|
1420
|
+
const reported = { discriminators: /* @__PURE__ */ new Set() };
|
|
1421
|
+
for (const { model, namespaceId, key } of identities.values()) {
|
|
1422
|
+
const source = diagnosticSource(sources, model.node.syntax);
|
|
1423
|
+
const discriminatorNode = getAttribute(model.attributes, "discriminator")?.node;
|
|
1424
|
+
if (discriminatorNode !== void 0) {
|
|
1425
|
+
const parsed = interpretModelAttribute({
|
|
1426
|
+
node: discriminatorNode,
|
|
1427
|
+
symbols,
|
|
1428
|
+
spec: sqlAttributeSpecs.model.discriminator(specContextFor(model)),
|
|
1429
|
+
model,
|
|
1430
|
+
sources,
|
|
1431
|
+
binder,
|
|
1432
|
+
diagnostics
|
|
1433
|
+
});
|
|
1434
|
+
if (parsed !== void 0) pendingDiscriminators.set(key, {
|
|
1435
|
+
declaration: {
|
|
1436
|
+
model,
|
|
1437
|
+
fieldName: parsed.field,
|
|
1438
|
+
span: nodePslSpan(discriminatorNode.syntax, sources),
|
|
1439
|
+
source
|
|
1440
|
+
},
|
|
1441
|
+
field: discriminatorFieldOf(model, parsed.field)
|
|
1442
|
+
});
|
|
1443
|
+
else reported.discriminators.add(key);
|
|
1444
|
+
}
|
|
1445
|
+
const baseNode = getAttribute(model.attributes, "base")?.node;
|
|
1446
|
+
if (baseNode !== void 0) {
|
|
1447
|
+
const parsed = interpretModelAttribute({
|
|
1448
|
+
node: baseNode,
|
|
1449
|
+
symbols,
|
|
1450
|
+
spec: sqlAttributeSpecs.model.base(specContextFor(model)),
|
|
1451
|
+
model,
|
|
1452
|
+
sources,
|
|
1453
|
+
binder,
|
|
1454
|
+
diagnostics
|
|
1455
|
+
});
|
|
1456
|
+
if (parsed !== void 0) {
|
|
1457
|
+
const base = identities.get(parsed.base.declaration);
|
|
1458
|
+
invariant(base !== void 0, `Resolved base model "${parsed.base.declaration.name}" is missing from the collected model identities`);
|
|
1459
|
+
pendingBaseDeclarations.set(key, {
|
|
1460
|
+
model,
|
|
1461
|
+
namespaceId,
|
|
1462
|
+
source,
|
|
1463
|
+
base,
|
|
1464
|
+
written: parsed.value,
|
|
1465
|
+
span: nodePslSpan(baseNode.syntax, sources)
|
|
1466
|
+
});
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
const discriminatorDeclarations = /* @__PURE__ */ new Map();
|
|
1471
|
+
const values = /* @__PURE__ */ new Map();
|
|
1472
|
+
for (const [baseKey, { declaration, field }] of pendingDiscriminators) {
|
|
1473
|
+
const accepted = acceptedDiscriminator(declaration, field, [...pendingBaseDeclarations].filter(([, base]) => base.base.key === baseKey), {
|
|
1474
|
+
codecLookup,
|
|
1475
|
+
dataTypes,
|
|
1476
|
+
diagnostics
|
|
1477
|
+
});
|
|
1478
|
+
if (accepted === void 0) {
|
|
1479
|
+
reported.discriminators.add(baseKey);
|
|
1480
|
+
continue;
|
|
1481
|
+
}
|
|
1482
|
+
discriminatorDeclarations.set(baseKey, declaration);
|
|
1483
|
+
for (const [variantKey, value] of accepted) values.set(variantKey, value);
|
|
1484
|
+
}
|
|
1485
|
+
const baseDeclarations = /* @__PURE__ */ new Map();
|
|
1486
|
+
for (const [key, { model, namespaceId, source, base, span }] of pendingBaseDeclarations) baseDeclarations.set(key, {
|
|
1487
|
+
model,
|
|
1488
|
+
namespaceId,
|
|
1489
|
+
source,
|
|
1490
|
+
base,
|
|
1491
|
+
span,
|
|
1492
|
+
value: values.get(key)
|
|
1493
|
+
});
|
|
1494
|
+
return {
|
|
1495
|
+
discriminatorDeclarations,
|
|
1496
|
+
baseDeclarations,
|
|
1497
|
+
reported
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1500
|
+
/**
|
|
1501
|
+
* The stored discriminator value of each variant, by the variant's key, when the discriminator rule accepts the field; `undefined` when it refuses the field. A refusal is reported at the `@@discriminator` attribute or at the `@@base` value it is about.
|
|
1502
|
+
*/
|
|
1503
|
+
function acceptedDiscriminator(declaration, discriminatorField, bases, input) {
|
|
1504
|
+
const { model, fieldName } = declaration;
|
|
1505
|
+
const baseByKey = new Map(bases);
|
|
1506
|
+
const decision = applyDiscriminatorRule({
|
|
1507
|
+
field: discriminatorField.field,
|
|
1508
|
+
variants: bases.map(([key, base]) => ({
|
|
1509
|
+
key,
|
|
1510
|
+
written: writtenBaseValue(base)
|
|
1511
|
+
})),
|
|
1512
|
+
subject: `Field "${model.name}.${fieldName}"`,
|
|
1513
|
+
codecLookup: input.codecLookup,
|
|
1514
|
+
dataTypes: input.dataTypes
|
|
1515
|
+
});
|
|
1516
|
+
const baseOf = (variantKey) => {
|
|
1517
|
+
const base = baseByKey.get(variantKey);
|
|
1518
|
+
invariant(base !== void 0, "A refused @@base value belongs to a collected variant");
|
|
1519
|
+
return base;
|
|
1520
|
+
};
|
|
1521
|
+
const subject = {
|
|
1522
|
+
modelName: model.name,
|
|
1523
|
+
fieldName,
|
|
1524
|
+
typeName: model.fields[fieldName]?.typeName ?? fieldName,
|
|
1525
|
+
enumName: discriminatorField.enumName,
|
|
1526
|
+
variantName: (variantKey) => baseOf(variantKey).model.name
|
|
1527
|
+
};
|
|
1528
|
+
for (const refusal of decision.fieldRefusals) input.diagnostics.push({
|
|
1529
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
1530
|
+
message: describeDiscriminatorRefusal(refusal, subject),
|
|
1531
|
+
...declaration.source.at(declaration.span)
|
|
1532
|
+
});
|
|
1533
|
+
if (decision.fieldRefusals.length > 0) return void 0;
|
|
1534
|
+
for (const refusal of decision.variantRefusals) {
|
|
1535
|
+
const base = baseOf(refusal.key);
|
|
1536
|
+
input.diagnostics.push({
|
|
1537
|
+
...refusal.kind === "unreadable" ? refusal.refusal : {
|
|
1538
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
1539
|
+
message: describeDiscriminatorRefusal(refusal, subject)
|
|
1540
|
+
},
|
|
1541
|
+
...base.source.at(base.written.span)
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
return decision.values;
|
|
1545
|
+
}
|
|
1546
|
+
/** A `@@base` value as it is written; the grammar reads only a quoted string there. */
|
|
1547
|
+
function writtenBaseValue(base) {
|
|
1548
|
+
if (base.written.written === void 0) throw new InternalError("A @@base value is a quoted string, never a tagged literal.");
|
|
1549
|
+
return base.written.written;
|
|
1550
|
+
}
|
|
1551
|
+
function modelLabel(namespaceId, modelName, qualified) {
|
|
1552
|
+
return qualified ? `${namespaceId}.${modelName}` : modelName;
|
|
1553
|
+
}
|
|
1554
|
+
function resolvePolymorphism(models, physicalNames, discriminatorDeclarations, baseDeclarations, reported, syntheticPkFieldsByVariant, stiBaseFieldsByBase, diagnostics) {
|
|
1555
|
+
let patched = models;
|
|
1556
|
+
for (const [baseKey, fieldNames] of stiBaseFieldsByBase) {
|
|
1557
|
+
const baseModel = patched[baseKey];
|
|
1558
|
+
if (!baseModel || fieldNames.length === 0) continue;
|
|
1559
|
+
patched = {
|
|
1560
|
+
...patched,
|
|
1561
|
+
[baseKey]: stripStorageOnlyDomainFields(baseModel, fieldNames)
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
for (const [modelKey, decl] of discriminatorDeclarations) {
|
|
1565
|
+
const modelName = decl.model.name;
|
|
1566
|
+
if (baseDeclarations.has(modelKey)) {
|
|
1567
|
+
diagnostics.push({
|
|
1568
|
+
code: "PSL_DISCRIMINATOR_AND_BASE",
|
|
1569
|
+
message: `Model "${modelName}" cannot have both @@discriminator and @@base`,
|
|
1570
|
+
...decl.source.at(decl.span)
|
|
1571
|
+
});
|
|
1572
|
+
continue;
|
|
1573
|
+
}
|
|
1574
|
+
const model = patched[modelKey];
|
|
1575
|
+
if (!model) continue;
|
|
1576
|
+
const variants = {};
|
|
1577
|
+
for (const baseDecl of baseDeclarations.values()) {
|
|
1578
|
+
if (baseDecl.base.key !== modelKey || baseDecl.value === void 0) continue;
|
|
1579
|
+
const variantName = baseDecl.model.name;
|
|
1580
|
+
const existingVariant = variants[baseDecl.value];
|
|
1581
|
+
if (existingVariant) {
|
|
1582
|
+
const qualified = existingVariant.namespace !== baseDecl.base.namespaceId || baseDecl.namespaceId !== baseDecl.base.namespaceId;
|
|
1583
|
+
diagnostics.push({
|
|
1584
|
+
code: "PSL_DUPLICATE_DISCRIMINATOR_VALUE",
|
|
1585
|
+
message: `Discriminator value "${baseDecl.value}" is used by both "${modelLabel(existingVariant.namespace, existingVariant.model, qualified)}" and "${modelLabel(baseDecl.namespaceId, variantName, qualified)}" on base model "${modelLabel(baseDecl.base.namespaceId, modelName, qualified)}"`,
|
|
1586
|
+
...baseDecl.source.at(baseDecl.span)
|
|
1587
|
+
});
|
|
1588
|
+
continue;
|
|
1589
|
+
}
|
|
1590
|
+
variants[baseDecl.value] = crossRef(variantName, baseDecl.namespaceId);
|
|
1591
|
+
}
|
|
1592
|
+
if (Object.keys(variants).length === 0) {
|
|
1593
|
+
if ([...baseDeclarations.values()].some((baseDecl) => baseDecl.base.key === modelKey && baseDecl.value === void 0)) continue;
|
|
1594
|
+
diagnostics.push({
|
|
1595
|
+
code: "PSL_ORPHANED_DISCRIMINATOR",
|
|
1596
|
+
message: `Model "${modelName}" has @@discriminator but no variant models declare @@base(${modelName}, ...)`,
|
|
1597
|
+
...decl.source.at(decl.span)
|
|
1598
|
+
});
|
|
1599
|
+
continue;
|
|
1600
|
+
}
|
|
1601
|
+
patched = {
|
|
1602
|
+
...patched,
|
|
1603
|
+
[modelKey]: {
|
|
1604
|
+
...model,
|
|
1605
|
+
discriminator: { field: decl.fieldName },
|
|
1606
|
+
variants
|
|
1607
|
+
}
|
|
1608
|
+
};
|
|
1609
|
+
}
|
|
1610
|
+
for (const [variantKey, baseDecl] of baseDeclarations) {
|
|
1611
|
+
const baseName = baseDecl.base.model.name;
|
|
1612
|
+
if (!discriminatorDeclarations.has(baseDecl.base.key)) {
|
|
1613
|
+
if (reported.discriminators.has(baseDecl.base.key)) continue;
|
|
1614
|
+
const qualified = baseDecl.namespaceId !== baseDecl.base.namespaceId;
|
|
1615
|
+
const variantLabel = modelLabel(baseDecl.namespaceId, baseDecl.model.name, qualified);
|
|
1616
|
+
const baseLabel = modelLabel(baseDecl.base.namespaceId, baseName, qualified);
|
|
1617
|
+
diagnostics.push({
|
|
1618
|
+
code: "PSL_ORPHANED_BASE",
|
|
1619
|
+
message: `Model "${variantLabel}" declares @@base(${baseLabel}, ...) but "${baseLabel}" has no @@discriminator`,
|
|
1620
|
+
...baseDecl.source.at(baseDecl.span)
|
|
1621
|
+
});
|
|
1622
|
+
continue;
|
|
1623
|
+
}
|
|
1624
|
+
if (discriminatorDeclarations.has(variantKey)) continue;
|
|
1625
|
+
const variantModel = patched[variantKey];
|
|
1626
|
+
if (!variantModel) continue;
|
|
1627
|
+
const resolvedTable = storageName(getAttribute(baseDecl.model.attributes, "map") !== void 0 ? baseDecl.model : baseDecl.base.model, physicalNames);
|
|
1628
|
+
const patchedVariant = {
|
|
1629
|
+
...variantModel,
|
|
1630
|
+
base: crossRef(baseName, baseDecl.base.namespaceId),
|
|
1631
|
+
...resolvedTable ? { storage: {
|
|
1632
|
+
...variantModel.storage,
|
|
1633
|
+
table: resolvedTable
|
|
1634
|
+
} } : {}
|
|
1635
|
+
};
|
|
1636
|
+
patched = {
|
|
1637
|
+
...patched,
|
|
1638
|
+
[variantKey]: stripStorageOnlyDomainFields(patchedVariant, syntheticPkFieldsByVariant.get(variantKey) ?? [])
|
|
1639
|
+
};
|
|
1640
|
+
}
|
|
1641
|
+
return patched;
|
|
1642
|
+
}
|
|
1643
|
+
/**
|
|
1644
|
+
* Multi-table-inheritance variants (`@@base` + their own `@@map`) live in a
|
|
1645
|
+
* separate table from their base. The ORM joins that table to the base on the
|
|
1646
|
+
* shared primary key (`base.id = variant.id`), so the variant storage table
|
|
1647
|
+
* must carry the base PK column even though the variant domain model declares
|
|
1648
|
+
* only its own fields. This enriches each MTI variant's `ModelNode` with that
|
|
1649
|
+
* link column, a primary key on it, and a FK back to the base table.
|
|
1650
|
+
*
|
|
1651
|
+
* The link column is reported back per variant in `syntheticPkFieldsByVariant`
|
|
1652
|
+
* so the domain-model patch can drop it again — keeping the variant's domain
|
|
1653
|
+
* surface thin (its create/read inputs don't gain a redundant `id`) while the
|
|
1654
|
+
* storage table stays joinable. Single-table-inheritance variants (no own
|
|
1655
|
+
* table) are left untouched.
|
|
1656
|
+
*/
|
|
1657
|
+
function materializeMtiVariantStorageLinks(modelNodes, baseDeclarations, stiVariantKeys, defaultNamespaceId) {
|
|
1658
|
+
const keyOf = (node) => modelCoordinateKey(node.namespaceId ?? defaultNamespaceId, node.modelName);
|
|
1659
|
+
const nodeByModel = new Map(modelNodes.map((node) => [keyOf(node), node]));
|
|
1660
|
+
const syntheticPkFieldsByVariant = /* @__PURE__ */ new Map();
|
|
1661
|
+
return {
|
|
1662
|
+
modelNodes: modelNodes.map((node) => {
|
|
1663
|
+
const variantKey = keyOf(node);
|
|
1664
|
+
const baseDecl = baseDeclarations.get(variantKey);
|
|
1665
|
+
if (!baseDecl) return node;
|
|
1666
|
+
const baseNode = nodeByModel.get(baseDecl.base.key);
|
|
1667
|
+
if (!baseNode) return node;
|
|
1668
|
+
if (stiVariantKeys.has(variantKey)) return node;
|
|
1669
|
+
const basePrimaryKey = baseNode.id;
|
|
1670
|
+
if (!basePrimaryKey || basePrimaryKey.columns.length === 0) return node;
|
|
1671
|
+
const existingColumns = new Set(node.fields.map((field) => field.columnName));
|
|
1672
|
+
const linkFields = [];
|
|
1673
|
+
for (const pkColumn of basePrimaryKey.columns) {
|
|
1674
|
+
if (existingColumns.has(pkColumn)) continue;
|
|
1675
|
+
const baseField = baseNode.fields.find((field) => field.columnName === pkColumn);
|
|
1676
|
+
if (!baseField) continue;
|
|
1677
|
+
linkFields.push({
|
|
1678
|
+
fieldName: baseField.fieldName,
|
|
1679
|
+
columnName: pkColumn,
|
|
1680
|
+
descriptor: baseField.descriptor,
|
|
1681
|
+
nullable: false,
|
|
1682
|
+
many: false
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
if (linkFields.length === 0) return node;
|
|
1686
|
+
syntheticPkFieldsByVariant.set(variantKey, linkFields.map((field) => field.fieldName));
|
|
1687
|
+
const foreignKey = {
|
|
1688
|
+
columns: basePrimaryKey.columns,
|
|
1689
|
+
references: {
|
|
1690
|
+
model: baseNode.modelName,
|
|
1691
|
+
table: baseNode.tableName,
|
|
1692
|
+
columns: basePrimaryKey.columns,
|
|
1693
|
+
...ifDefined("namespaceId", baseNode.namespaceId)
|
|
1694
|
+
},
|
|
1695
|
+
constraint: true,
|
|
1696
|
+
onDelete: "cascade"
|
|
1697
|
+
};
|
|
1698
|
+
return {
|
|
1699
|
+
...node,
|
|
1700
|
+
fields: [...linkFields, ...node.fields],
|
|
1701
|
+
id: { columns: basePrimaryKey.columns },
|
|
1702
|
+
foreignKeys: [...node.foreignKeys ?? [], foreignKey]
|
|
1703
|
+
};
|
|
1704
|
+
}),
|
|
1705
|
+
syntheticPkFieldsByVariant
|
|
1706
|
+
};
|
|
1707
|
+
}
|
|
1708
|
+
/**
|
|
1709
|
+
* Single-table-inheritance variants (`@@base` with no own `@@map`) share the
|
|
1710
|
+
* base table: `resolvePolymorphism` points the variant's `storage.table` at the
|
|
1711
|
+
* base, and the ORM reads variant-declared fields straight off the base table.
|
|
1712
|
+
* For that to validate and round-trip, the base storage table must physically
|
|
1713
|
+
* carry every STI variant's declared columns. This enriches the base
|
|
1714
|
+
* `ModelNode` with those columns.
|
|
1715
|
+
*
|
|
1716
|
+
* The materialised columns are always nullable in storage: the base table hosts
|
|
1717
|
+
* every variant's rows, so a column a variant declares as required is still
|
|
1718
|
+
* NULL on sibling-variant rows. The variant's domain field keeps its declared
|
|
1719
|
+
* nullability — required-in-domain / nullable-in-storage is the intended STI
|
|
1720
|
+
* shape.
|
|
1721
|
+
*
|
|
1722
|
+
* Collisions (two variants declaring the same column, or a variant column name
|
|
1723
|
+
* clashing with a base column) are resolved skip-if-exists here, mirroring the
|
|
1724
|
+
* MTI link guard; surfacing them as diagnostics is tracked separately
|
|
1725
|
+
* (TML-2827).
|
|
1726
|
+
*/
|
|
1727
|
+
function materializeStiVariantStorageColumns(modelNodes, baseDeclarations, stiVariantKeys, defaultNamespaceId) {
|
|
1728
|
+
if (stiVariantKeys.size === 0) return {
|
|
1729
|
+
modelNodes: [...modelNodes],
|
|
1730
|
+
stiBaseFieldsByBase: /* @__PURE__ */ new Map()
|
|
1731
|
+
};
|
|
1732
|
+
const keyOf = (node) => modelCoordinateKey(node.namespaceId ?? defaultNamespaceId, node.modelName);
|
|
1733
|
+
const nodeByModel = new Map(modelNodes.map((node) => [keyOf(node), node]));
|
|
1734
|
+
const stiColumnsByBase = /* @__PURE__ */ new Map();
|
|
1735
|
+
for (const variantKey of stiVariantKeys) {
|
|
1736
|
+
const variantNode = nodeByModel.get(variantKey);
|
|
1737
|
+
const baseDecl = baseDeclarations.get(variantKey);
|
|
1738
|
+
if (!variantNode || !baseDecl) continue;
|
|
1739
|
+
const baseNode = nodeByModel.get(baseDecl.base.key);
|
|
1740
|
+
if (!baseNode) continue;
|
|
1741
|
+
const baseColumns = new Set(baseNode.fields.map((field) => field.columnName));
|
|
1742
|
+
const claimed = stiColumnsByBase.get(baseDecl.base.key) ?? [];
|
|
1743
|
+
const claimedColumns = new Set(claimed.map((field) => field.columnName));
|
|
1744
|
+
for (const field of variantNode.fields) {
|
|
1745
|
+
if (baseColumns.has(field.columnName) || claimedColumns.has(field.columnName)) continue;
|
|
1746
|
+
claimedColumns.add(field.columnName);
|
|
1747
|
+
claimed.push({
|
|
1748
|
+
...field,
|
|
1749
|
+
nullable: true
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1752
|
+
stiColumnsByBase.set(baseDecl.base.key, claimed);
|
|
1753
|
+
}
|
|
1754
|
+
const stiBaseFieldsByBase = /* @__PURE__ */ new Map();
|
|
1755
|
+
for (const [baseName, columns] of stiColumnsByBase) stiBaseFieldsByBase.set(baseName, columns.map((field) => field.fieldName));
|
|
1756
|
+
return {
|
|
1757
|
+
modelNodes: modelNodes.map((node) => {
|
|
1758
|
+
if (stiVariantKeys.has(keyOf(node))) return {
|
|
1759
|
+
...node,
|
|
1760
|
+
sharesBaseTable: true
|
|
1761
|
+
};
|
|
1762
|
+
const stiColumns = stiColumnsByBase.get(keyOf(node));
|
|
1763
|
+
if (!stiColumns || stiColumns.length === 0) return node;
|
|
1764
|
+
return {
|
|
1765
|
+
...node,
|
|
1766
|
+
fields: [...node.fields, ...stiColumns]
|
|
1767
|
+
};
|
|
1768
|
+
}),
|
|
1769
|
+
stiBaseFieldsByBase
|
|
1770
|
+
};
|
|
1771
|
+
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Drop the storage-only link fields (added by
|
|
1774
|
+
* {@link materializeMtiVariantStorageLinks}) from a variant's domain model, so
|
|
1775
|
+
* the domain surface stays thin while the storage table keeps the link column.
|
|
1776
|
+
*/
|
|
1777
|
+
function stripStorageOnlyDomainFields(model, fieldNames) {
|
|
1778
|
+
if (fieldNames.length === 0) return model;
|
|
1779
|
+
const fields = { ...model.fields };
|
|
1780
|
+
for (const name of fieldNames) delete fields[name];
|
|
1781
|
+
const storage = blindCast(model.storage);
|
|
1782
|
+
const storageFields = { ...storage.fields };
|
|
1783
|
+
for (const name of fieldNames) delete storageFields[name];
|
|
1784
|
+
return {
|
|
1785
|
+
...model,
|
|
1786
|
+
fields,
|
|
1787
|
+
storage: {
|
|
1788
|
+
...storage,
|
|
1789
|
+
fields: storageFields
|
|
1790
|
+
}
|
|
1791
|
+
};
|
|
1792
|
+
}
|
|
1793
|
+
function backrelationTargetSymbol(field, binder) {
|
|
1794
|
+
const typeReference = typeReferenceNode(field);
|
|
1795
|
+
if (typeReference === void 0) return void 0;
|
|
1796
|
+
const resolution = binder.symbolForNode(typeReference);
|
|
1797
|
+
return resolution?.kind === "model" ? resolution.symbol : void 0;
|
|
1798
|
+
}
|
|
1799
|
+
function relationTargetKindLabel(resolution) {
|
|
1800
|
+
switch (resolution.kind) {
|
|
1801
|
+
case "compositeType": return "composite type";
|
|
1802
|
+
case "namedType": return "type alias";
|
|
1803
|
+
case "block": return resolution.symbol.keyword;
|
|
1804
|
+
case "namespace":
|
|
1805
|
+
case "contributedNamespace": return "namespace";
|
|
1806
|
+
case "contributedType": return "type";
|
|
1807
|
+
default: return;
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* The relation a refusal of `index: "<name>"` belongs to, and the message to report there; `undefined` for every other error.
|
|
1812
|
+
*/
|
|
1813
|
+
function relationIndexRefusal(error, locations) {
|
|
1814
|
+
if (!isStructuredError(error) || error.meta?.["reason"] !== "foreign-key-index-unresolved") return;
|
|
1815
|
+
const { namespaceId, tableName, columns, index } = error.meta ?? {};
|
|
1816
|
+
const at = locations.find((candidate) => candidate.namespaceId === namespaceId && candidate.tableName === tableName && candidate.index === index && Array.isArray(columns) && candidate.columns.length === columns.length && candidate.columns.every((column, position) => column === columns[position]));
|
|
1817
|
+
if (at === void 0) return void 0;
|
|
1818
|
+
return {
|
|
1819
|
+
at,
|
|
1820
|
+
message: error.fix === void 0 ? error.message : `${error.message} ${error.fix}`
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
function interpretPslDocumentToSqlContract(input) {
|
|
1824
|
+
if (!input.target) throw new InternalError("PSL interpretation requires an explicit target context from composition.");
|
|
1825
|
+
if (!input.scalarColumnDescriptors) throw new InternalError("PSL interpretation requires composed scalar type descriptors.");
|
|
1826
|
+
const [anchorDocument] = input.documents;
|
|
1827
|
+
assertDefined(anchorDocument, "interpretPslDocumentToSqlContract requires at least one document");
|
|
1828
|
+
const source = diagnosticSource(input.sources, anchorDocument.syntax);
|
|
1829
|
+
const diagnostics = createPslDiagnosticCollector(input.sources);
|
|
1830
|
+
const modelAttributesByName = buildModelAttributesByName(input.authoringContributions);
|
|
1831
|
+
const contributedModelSpecs = modelAttributeSpecsFrom(modelAttributesByName);
|
|
1832
|
+
const composedPslBlockDescriptors = input.authoringContributions?.pslBlockDescriptors ?? {};
|
|
1833
|
+
const { binder, dataTypes } = input;
|
|
1834
|
+
const defaultFunctionRegistry = input.controlMutationDefaults?.defaultFunctionRegistry ?? /* @__PURE__ */ new Map();
|
|
1835
|
+
const { generatorFunctions } = input;
|
|
1836
|
+
const specContextFor = (model) => modelSpecContext({
|
|
1837
|
+
symbols: input.symbolTable,
|
|
1838
|
+
model,
|
|
1839
|
+
defaultFunctionRegistry,
|
|
1840
|
+
generatorFunctions,
|
|
1841
|
+
dataTypes
|
|
1842
|
+
});
|
|
1843
|
+
const namespaceSymbols = Object.values(input.symbolTable.namespaces);
|
|
1844
|
+
validateNamespaceBlocksForSqlTarget({
|
|
1845
|
+
namespaces: namespaceSymbols,
|
|
1846
|
+
target: input.target,
|
|
1847
|
+
source,
|
|
1848
|
+
sources: input.sources,
|
|
1849
|
+
binder,
|
|
1850
|
+
diagnostics
|
|
1851
|
+
});
|
|
1852
|
+
const { parsedBlocks, diagnostics: blockDiagnostics } = interpretExtensionBlocks({
|
|
1853
|
+
symbolTable: input.symbolTable,
|
|
1854
|
+
sources: input.sources,
|
|
1855
|
+
pslBlockDescriptors: composedPslBlockDescriptors,
|
|
1856
|
+
binder,
|
|
1857
|
+
dataTypes
|
|
1858
|
+
});
|
|
1859
|
+
diagnostics.push(...blockDiagnostics);
|
|
1860
|
+
validateBlockModelAttributeRequirements({
|
|
1861
|
+
parsedBlocks,
|
|
1862
|
+
pslBlockDescriptors: composedPslBlockDescriptors,
|
|
1863
|
+
sources: input.sources,
|
|
1864
|
+
diagnostics
|
|
1865
|
+
});
|
|
1866
|
+
const models = [];
|
|
1867
|
+
const modelEntries = [];
|
|
1868
|
+
const compositeTypes = [];
|
|
1869
|
+
for (const namespace of namespaceSymbols) {
|
|
1870
|
+
for (const model of Object.values(namespace.models)) {
|
|
1871
|
+
models.push(model);
|
|
1872
|
+
modelEntries.push({
|
|
1873
|
+
model,
|
|
1874
|
+
namespaceId: namespace.id
|
|
1875
|
+
});
|
|
1876
|
+
}
|
|
1877
|
+
compositeTypes.push(...Object.values(namespace.compositeTypes));
|
|
1878
|
+
}
|
|
1879
|
+
const physicalNames = /* @__PURE__ */ new Map();
|
|
1880
|
+
for (const model of models) {
|
|
1881
|
+
const mapNode = getAttribute(model.attributes, "map")?.node;
|
|
1882
|
+
const mapped = mapNode === void 0 ? void 0 : interpretModelAttribute({
|
|
1883
|
+
node: mapNode,
|
|
1884
|
+
symbols: input.symbolTable,
|
|
1885
|
+
spec: sqlAttributeSpecs.model.map(specContextFor(model)),
|
|
1886
|
+
model,
|
|
1887
|
+
sources: input.sources,
|
|
1888
|
+
binder,
|
|
1889
|
+
diagnostics
|
|
1890
|
+
});
|
|
1891
|
+
physicalNames.set(model, mapped?.name ?? defaultTableName(model.name));
|
|
1892
|
+
for (const field of Object.values(model.fields)) {
|
|
1893
|
+
const mapNode = getAttribute(field.attributes, "map")?.node;
|
|
1894
|
+
const mapped = mapNode === void 0 ? void 0 : interpretFieldAttribute({
|
|
1895
|
+
node: mapNode,
|
|
1896
|
+
symbols: input.symbolTable,
|
|
1897
|
+
spec: sqlAttributeSpecs.field.map(fieldSpecContext({
|
|
1898
|
+
...specContextFor(model),
|
|
1899
|
+
field,
|
|
1900
|
+
binder
|
|
1901
|
+
})),
|
|
1902
|
+
model,
|
|
1903
|
+
field,
|
|
1904
|
+
sources: input.sources,
|
|
1905
|
+
binder,
|
|
1906
|
+
diagnostics
|
|
1907
|
+
});
|
|
1908
|
+
physicalNames.set(field, mapped?.name ?? field.name);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
const defaultNamespaceId = input.symbolTable.defaultNamespace.id;
|
|
1912
|
+
const composedExtensions = new Set(input.composedExtensions ?? []);
|
|
1913
|
+
const composedExtensionContracts = input.composedExtensionContracts;
|
|
1914
|
+
const isEnumBlock = (block) => block.keyword === "enum";
|
|
1915
|
+
const legitimateBlockKeywords = claimedBlockKeywords(input.authoringContributions?.pslBlockDescriptors);
|
|
1916
|
+
const reportUnsupportedTopLevelBlock = (block) => {
|
|
1917
|
+
diagnostics.push(unsupportedBlockDiagnostic(block, input.sources));
|
|
1918
|
+
};
|
|
1919
|
+
const topLevelEnums = [];
|
|
1920
|
+
const extensionBlocksByNamespace = /* @__PURE__ */ new Map();
|
|
1921
|
+
for (const namespace of namespaceSymbols) {
|
|
1922
|
+
const extensionBlocks = {};
|
|
1923
|
+
extensionBlocksByNamespace.set(namespace, extensionBlocks);
|
|
1924
|
+
for (const [blockName, block] of Object.entries(namespace.blocks)) {
|
|
1925
|
+
const writtenNamespace = block.node.syntax.findAncestor(NamespaceDeclarationAst.cast);
|
|
1926
|
+
if (writtenNamespace === void 0) {
|
|
1927
|
+
if (!legitimateBlockKeywords.has(block.keyword)) reportUnsupportedTopLevelBlock(block);
|
|
1928
|
+
else if (isEnumBlock(block)) topLevelEnums.push(block);
|
|
1929
|
+
else extensionBlocks[blockName] = block;
|
|
1930
|
+
continue;
|
|
1931
|
+
}
|
|
1932
|
+
extensionBlocks[blockName] = block;
|
|
1933
|
+
if (isEnumBlock(block)) {
|
|
1934
|
+
diagnostics.push({
|
|
1935
|
+
code: "PSL_ENUM_NAMESPACE_NOT_SUPPORTED",
|
|
1936
|
+
message: `enum "${block.name}" inside namespace "${writtenNamespace.name()?.name() ?? namespace.name}" is not supported; declare enum at the top level`,
|
|
1937
|
+
...diagnosticSource(input.sources, block.node.syntax).at(nodePslSpan(block.node.syntax, input.sources))
|
|
1938
|
+
});
|
|
1939
|
+
continue;
|
|
1940
|
+
}
|
|
1941
|
+
if (!legitimateBlockKeywords.has(block.keyword)) reportUnsupportedTopLevelBlock(block);
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
const enumResult = processEnumDeclarations({
|
|
1945
|
+
enumBlocks: topLevelEnums,
|
|
1946
|
+
parsedBlocks,
|
|
1947
|
+
source,
|
|
1948
|
+
authoringContributions: input.authoringContributions,
|
|
1949
|
+
entityContext: {
|
|
1950
|
+
family: input.target.familyId,
|
|
1951
|
+
target: input.target.targetId,
|
|
1952
|
+
codecLookup: input.codecLookup,
|
|
1953
|
+
dataTypes: input.dataTypes,
|
|
1954
|
+
sourceId: source.sources.sourceFileFor(source.node).filename,
|
|
1955
|
+
diagnostics: { push: (d) => {
|
|
1956
|
+
diagnostics.pushExternal(blindCast(d));
|
|
1957
|
+
} },
|
|
1958
|
+
...ifDefined("enumInferenceCodecs", input.enumInferenceCodecs)
|
|
1959
|
+
},
|
|
1960
|
+
diagnostics
|
|
1961
|
+
});
|
|
1962
|
+
const allEnumTypeDescriptors = enumResult.enumTypeDescriptors;
|
|
1963
|
+
const enumHandles = enumResult.enumHandles;
|
|
1964
|
+
const validEnumHandles = Object.fromEntries(Array.from(enumHandles, ([symbol, handle]) => [symbol.name, handle]));
|
|
1965
|
+
const entityTypesByDiscriminator = buildEntityTypesByDiscriminator(input.authoringContributions);
|
|
1966
|
+
const authoringWarnings = [];
|
|
1967
|
+
const extensionEntityContext = {
|
|
1968
|
+
family: input.target.familyId,
|
|
1969
|
+
target: input.target.targetId,
|
|
1970
|
+
...ifDefined("enumInferenceCodecs", input.enumInferenceCodecs),
|
|
1971
|
+
codecLookup: input.codecLookup,
|
|
1972
|
+
dataTypes: input.dataTypes,
|
|
1973
|
+
sourceId: source.sources.sourceFileFor(source.node).filename,
|
|
1974
|
+
diagnostics: { push: (d) => {
|
|
1975
|
+
diagnostics.pushExternal(blindCast(d));
|
|
1976
|
+
} },
|
|
1977
|
+
warnings: authoringWarnings
|
|
1978
|
+
};
|
|
1979
|
+
const namespaceIdByModel = new Map(modelEntries.map(({ model, namespaceId }) => [model, namespaceId]));
|
|
1980
|
+
const modelCoordinateOf = (model) => {
|
|
1981
|
+
const namespaceId = namespaceIdByModel.get(model);
|
|
1982
|
+
return namespaceId === void 0 ? void 0 : {
|
|
1983
|
+
namespaceId,
|
|
1984
|
+
tableName: storageName(model, physicalNames)
|
|
1985
|
+
};
|
|
1986
|
+
};
|
|
1987
|
+
const namespaceExtensionEntities = /* @__PURE__ */ new Map();
|
|
1988
|
+
const fileExtensionEntityRows = (rows, blocks) => {
|
|
1989
|
+
for (const row of rows) {
|
|
1990
|
+
let entities = namespaceExtensionEntities.get(row.namespaceId);
|
|
1991
|
+
if (entities === void 0) {
|
|
1992
|
+
entities = {};
|
|
1993
|
+
namespaceExtensionEntities.set(row.namespaceId, entities);
|
|
1994
|
+
}
|
|
1995
|
+
const slot = entities[row.entityKind] ?? {};
|
|
1996
|
+
entities[row.entityKind] = slot;
|
|
1997
|
+
if (Object.hasOwn(slot, row.key)) {
|
|
1998
|
+
const block = Object.values(blocks).find((candidate) => candidate.name === row.key);
|
|
1999
|
+
invariant(block !== void 0, "Lowered entity has an owning block");
|
|
2000
|
+
diagnostics.pushUnlocated({
|
|
2001
|
+
code: "PSL_DUPLICATE_EXTENSION_ENTITY",
|
|
2002
|
+
message: `entries slot "${row.entityKind}" in namespace "${row.namespaceId}": entity "${row.key}" is declared more than once in the same namespace.`,
|
|
2003
|
+
...diagnosticSource(input.sources, block.node.syntax).at()
|
|
2004
|
+
});
|
|
2005
|
+
continue;
|
|
2006
|
+
}
|
|
2007
|
+
slot[row.key] = row.entity;
|
|
2008
|
+
}
|
|
2009
|
+
};
|
|
2010
|
+
for (const [namespace, extensionBlocks] of extensionBlocksByNamespace) fileExtensionEntityRows(lowerExtensionBlocksForNamespace(extensionBlocks, namespace.id, entityTypesByDiscriminator, extensionEntityContext, parsedBlocks, modelCoordinateOf, input.sources), extensionBlocks);
|
|
2011
|
+
const defaultNsExtensionValueSets = namespaceExtensionEntities.get(defaultNamespaceId)?.["valueSet"];
|
|
2012
|
+
if (defaultNsExtensionValueSets !== void 0) {
|
|
2013
|
+
for (const name of Object.keys(defaultNsExtensionValueSets)) if (Object.hasOwn(validEnumHandles, name)) {
|
|
2014
|
+
const enumSymbol = input.symbolTable.defaultNamespace.blocks[name];
|
|
2015
|
+
invariant(enumSymbol !== void 0, "Domain enum has an owning block");
|
|
2016
|
+
diagnostics.pushUnlocated({
|
|
2017
|
+
code: "PSL_VALUE_SET_NAME_COLLISION",
|
|
2018
|
+
message: `namespace "${defaultNamespaceId}": name "${name}" is declared both as a domain enum and as an extension entity that derives a value-set; rename one`,
|
|
2019
|
+
...diagnosticSource(input.sources, enumSymbol.node.syntax).at()
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
const typeAliases = resolveNamedTypeDeclarations({
|
|
2024
|
+
declarations: Object.values(input.symbolTable.namedTypes),
|
|
2025
|
+
sources: input.sources,
|
|
2026
|
+
symbolTable: input.symbolTable,
|
|
2027
|
+
binder,
|
|
2028
|
+
enumTypeDescriptors: allEnumTypeDescriptors,
|
|
2029
|
+
enumHandles,
|
|
2030
|
+
codecLookup: input.codecLookup,
|
|
2031
|
+
defaultFunctionRegistry,
|
|
2032
|
+
generatorFunctions,
|
|
2033
|
+
dataTypes,
|
|
2034
|
+
diagnostics,
|
|
2035
|
+
authoringTypes: input.authoringContributions?.type
|
|
2036
|
+
});
|
|
2037
|
+
const modelNodes = /* @__PURE__ */ new Map();
|
|
2038
|
+
const fkRelationMetadata = [];
|
|
2039
|
+
const relationIndexLocations = [];
|
|
2040
|
+
const invalidFkPairings = [];
|
|
2041
|
+
const backrelationCandidates = [];
|
|
2042
|
+
const crossSpaceRelationsByModel = /* @__PURE__ */ new Map();
|
|
2043
|
+
const modelAttributeEntitiesByNamespace = /* @__PURE__ */ new Map();
|
|
2044
|
+
const valueObjects = buildValueObjectNodes({
|
|
2045
|
+
compositeTypes,
|
|
2046
|
+
enumTypeDescriptors: allEnumTypeDescriptors,
|
|
2047
|
+
enumHandles,
|
|
2048
|
+
typeAliases,
|
|
2049
|
+
diagnostics,
|
|
2050
|
+
sources: input.sources,
|
|
2051
|
+
defaultNamespaceId,
|
|
2052
|
+
namespaceExtensionEntities,
|
|
2053
|
+
codecLookup: input.codecLookup,
|
|
2054
|
+
dataTypes: input.dataTypes,
|
|
2055
|
+
binder
|
|
2056
|
+
});
|
|
2057
|
+
const valueObjectTypes = {
|
|
2058
|
+
nodes: new Map(valueObjects.map((valueObject) => [valueObject.name, valueObject])),
|
|
2059
|
+
declaredMembers: new Map(compositeTypes.map((compositeType) => [compositeType.name, new Set(Object.keys(compositeType.fields))]))
|
|
2060
|
+
};
|
|
2061
|
+
for (const { model, namespaceId } of modelEntries) {
|
|
2062
|
+
const result = buildModelNodeFromPsl({
|
|
2063
|
+
model,
|
|
2064
|
+
physicalNames,
|
|
2065
|
+
namespaceId,
|
|
2066
|
+
valueObjectTypes,
|
|
2067
|
+
enumTypeDescriptors: allEnumTypeDescriptors,
|
|
2068
|
+
typeAliases,
|
|
2069
|
+
composedExtensionContracts,
|
|
2070
|
+
familyId: input.target.familyId,
|
|
2071
|
+
targetId: input.target.targetId,
|
|
2072
|
+
authoringContributions: input.authoringContributions,
|
|
2073
|
+
defaultFunctionRegistry,
|
|
2074
|
+
generatorFunctions,
|
|
2075
|
+
dataTypes,
|
|
2076
|
+
scalarColumnDescriptors: input.scalarColumnDescriptors,
|
|
2077
|
+
sources: input.sources,
|
|
2078
|
+
binder,
|
|
2079
|
+
symbolTable: input.symbolTable,
|
|
2080
|
+
diagnostics,
|
|
2081
|
+
enumHandles,
|
|
2082
|
+
capabilities: input.capabilities,
|
|
2083
|
+
...namespaceExtensionEntities.size > 0 ? { namespaceExtensionEntities } : {},
|
|
2084
|
+
codecLookup: input.codecLookup,
|
|
2085
|
+
modelAttributesByName,
|
|
2086
|
+
contributedModelAttributeSpecs: contributedModelSpecs,
|
|
2087
|
+
parsedBlocks
|
|
2088
|
+
});
|
|
2089
|
+
modelNodes.set(model, {
|
|
2090
|
+
...result.modelNode,
|
|
2091
|
+
namespaceId
|
|
2092
|
+
});
|
|
2093
|
+
fkRelationMetadata.push(...result.fkRelationMetadata);
|
|
2094
|
+
relationIndexLocations.push(...result.relationIndexLocations);
|
|
2095
|
+
invalidFkPairings.push(...result.invalidFkPairings);
|
|
2096
|
+
backrelationCandidates.push(...result.backrelationCandidates);
|
|
2097
|
+
if (result.crossSpaceRelations.length > 0) {
|
|
2098
|
+
const existing = crossSpaceRelationsByModel.get(model) ?? [];
|
|
2099
|
+
crossSpaceRelationsByModel.set(model, [...existing, ...result.crossSpaceRelations]);
|
|
2100
|
+
}
|
|
2101
|
+
if (Object.keys(result.modelAttributeEntities).length > 0) {
|
|
2102
|
+
const existingByAttribute = modelAttributeEntitiesByNamespace.get(namespaceId) ?? {};
|
|
2103
|
+
for (const [attribute, keyed] of Object.entries(result.modelAttributeEntities)) existingByAttribute[attribute] = {
|
|
2104
|
+
...existingByAttribute[attribute] ?? {},
|
|
2105
|
+
...keyed
|
|
2106
|
+
};
|
|
2107
|
+
modelAttributeEntitiesByNamespace.set(namespaceId, existingByAttribute);
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
const { modelRelations, fkRelationsByPair, fkRelationsByDeclaringModel } = indexFkRelations({ fkRelationMetadata });
|
|
2111
|
+
const modelIdColumns = /* @__PURE__ */ new Map();
|
|
2112
|
+
const modelUniqueColumnSets = /* @__PURE__ */ new Map();
|
|
2113
|
+
for (const [model, modelNode] of modelNodes) {
|
|
2114
|
+
if (modelNode.id) modelIdColumns.set(model, modelNode.id.columns);
|
|
2115
|
+
const uniqueColumnSets = [];
|
|
2116
|
+
if (modelNode.id) uniqueColumnSets.push(modelNode.id.columns);
|
|
2117
|
+
for (const unique of modelNode.uniques ?? []) uniqueColumnSets.push(unique.columns);
|
|
2118
|
+
for (const index of modelNode.indexes ?? []) if (index.unique === true && index.columns !== void 0 && index.where === void 0) uniqueColumnSets.push(index.columns);
|
|
2119
|
+
modelUniqueColumnSets.set(model, uniqueColumnSets);
|
|
2120
|
+
}
|
|
2121
|
+
applyBackrelationCandidates({
|
|
2122
|
+
backrelationCandidates,
|
|
2123
|
+
fkRelationsByPair,
|
|
2124
|
+
invalidFkPairings,
|
|
2125
|
+
fkRelationsByDeclaringModel,
|
|
2126
|
+
modelIdColumns,
|
|
2127
|
+
modelUniqueColumnSets,
|
|
2128
|
+
modelRelations,
|
|
2129
|
+
diagnostics,
|
|
2130
|
+
sources: input.sources
|
|
2131
|
+
});
|
|
2132
|
+
for (const [modelName, relations] of crossSpaceRelationsByModel) {
|
|
2133
|
+
const existing = modelRelations.get(modelName);
|
|
2134
|
+
if (existing) existing.push(...relations);
|
|
2135
|
+
else modelRelations.set(modelName, [...relations]);
|
|
2136
|
+
}
|
|
2137
|
+
const modelIdentities = new Map(modelEntries.map(({ model, namespaceId }) => [model, {
|
|
2138
|
+
model,
|
|
2139
|
+
namespaceId,
|
|
2140
|
+
key: modelCoordinateKey(namespaceId, model.name)
|
|
2141
|
+
}]));
|
|
2142
|
+
const discriminatorFieldOf = (model, fieldName) => {
|
|
2143
|
+
const field = modelNodes.get(model)?.fields.find((node) => node.fieldName === fieldName);
|
|
2144
|
+
if (field === void 0 || !("columnName" in field)) return {
|
|
2145
|
+
field: {
|
|
2146
|
+
ref: void 0,
|
|
2147
|
+
nullable: false,
|
|
2148
|
+
many: false,
|
|
2149
|
+
enumMembers: void 0
|
|
2150
|
+
},
|
|
2151
|
+
enumName: void 0
|
|
2152
|
+
};
|
|
2153
|
+
const handle = "enumTypeHandle" in field ? field.enumTypeHandle : void 0;
|
|
2154
|
+
const encoded = handle === void 0 ? void 0 : encodeEnumMembers(handle, input.codecLookup);
|
|
2155
|
+
return {
|
|
2156
|
+
field: {
|
|
2157
|
+
ref: {
|
|
2158
|
+
codecId: field.descriptor.codecId,
|
|
2159
|
+
...ifDefined("typeParams", field.descriptor.typeParams === void 0 ? void 0 : blindCast(field.descriptor.typeParams))
|
|
2160
|
+
},
|
|
2161
|
+
nullable: field.nullable,
|
|
2162
|
+
many: field.many === true,
|
|
2163
|
+
enumMembers: encoded?.ok ? encoded.value.map(({ value }) => value) : void 0
|
|
2164
|
+
},
|
|
2165
|
+
enumName: handle?.enumName
|
|
2166
|
+
};
|
|
2167
|
+
};
|
|
2168
|
+
const { discriminatorDeclarations, baseDeclarations, reported } = collectPolymorphismDeclarations(modelIdentities, input.symbolTable, input.sources, binder, specContextFor, discriminatorFieldOf, input.codecLookup, dataTypes, diagnostics);
|
|
2169
|
+
const stiVariantKeys = /* @__PURE__ */ new Set();
|
|
2170
|
+
for (const [variantKey, declaration] of baseDeclarations) if (!(getAttribute(declaration.model.attributes, "map") !== void 0)) stiVariantKeys.add(variantKey);
|
|
2171
|
+
for (const variantKey of stiVariantKeys) {
|
|
2172
|
+
const baseDecl = baseDeclarations.get(variantKey);
|
|
2173
|
+
invariant(baseDecl !== void 0, `stiVariantKeys is derived from baseDeclarations.keys(), so "${variantKey}" must have a base declaration`);
|
|
2174
|
+
const variantName = baseDecl.model.name;
|
|
2175
|
+
if (baseDecl.namespaceId !== baseDecl.base.namespaceId) {
|
|
2176
|
+
const variantLabel = modelLabel(baseDecl.namespaceId, variantName, true);
|
|
2177
|
+
const baseLabel = modelLabel(baseDecl.base.namespaceId, baseDecl.base.model.name, true);
|
|
2178
|
+
diagnostics.push({
|
|
2179
|
+
code: "PSL_BASE_IN_OTHER_NAMESPACE_WITHOUT_MAP",
|
|
2180
|
+
message: `Model "${variantLabel}" declares @@base(${baseLabel}, ...) without @@map, so it would share the table of "${baseLabel}", which belongs to namespace "${baseDecl.base.namespaceId}". Add @@map to give "${variantLabel}" its own table.`,
|
|
2181
|
+
...baseDecl.source.at(baseDecl.span)
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2184
|
+
for (const attribute of baseDecl.model.attributes) {
|
|
2185
|
+
if (attribute.node.name()?.isSimpleName("check") !== true) continue;
|
|
2186
|
+
diagnostics.push({
|
|
2187
|
+
code: PSL_CHECK_ON_STI_VARIANT,
|
|
2188
|
+
message: `Model "${variantName}" declares "@@check", but it shares its base model "${baseDecl.base.model.name}"'s storage table (single-table inheritance via @@base) and has no table of its own to declare a check constraint on. Declare the check on "${baseDecl.base.model.name}" instead.`,
|
|
2189
|
+
...diagnosticSource(input.sources, attribute.node.syntax).at(nodePslSpan(attribute.node.syntax, input.sources))
|
|
2190
|
+
});
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
const { modelNodes: mtiLinkedModelNodes, syntheticPkFieldsByVariant } = materializeMtiVariantStorageLinks(Array.from(modelNodes, ([symbol, model]) => ({
|
|
2194
|
+
...model,
|
|
2195
|
+
...modelRelations.has(symbol) ? { relations: [...modelRelations.get(symbol) ?? []].sort((left, right) => compareStrings(left.fieldName, right.fieldName)) } : {}
|
|
2196
|
+
})), baseDeclarations, stiVariantKeys, defaultNamespaceId);
|
|
2197
|
+
const { modelNodes: stiColumnModelNodes, stiBaseFieldsByBase } = materializeStiVariantStorageColumns(mtiLinkedModelNodes, baseDeclarations, stiVariantKeys, defaultNamespaceId);
|
|
2198
|
+
if (diagnostics.length > 0 || (input.seedDiagnostics?.length ?? 0) > 0) return notOk({
|
|
2199
|
+
summary: "PSL to SQL contract interpretation failed",
|
|
2200
|
+
diagnostics: [...input.seedDiagnostics ?? [], ...diagnostics.toExternal()]
|
|
2201
|
+
});
|
|
2202
|
+
const { createNamespace } = input;
|
|
2203
|
+
const createNamespaceWithExtensions = (nsInput) => {
|
|
2204
|
+
const entities = namespaceExtensionEntities.get(nsInput.id);
|
|
2205
|
+
const attributeEntities = modelAttributeEntitiesByNamespace.get(nsInput.id);
|
|
2206
|
+
if (entities === void 0 && attributeEntities === void 0) return createNamespace(nsInput);
|
|
2207
|
+
if (attributeEntities !== void 0) {
|
|
2208
|
+
for (const slot of Object.keys(attributeEntities)) if (Object.hasOwn(nsInput.entries, slot) || entities !== void 0 && slot in entities) throw contractError("CONTRACT.PACK_CONTRIBUTION_INVALID", `entries slot "${slot}" in namespace "${nsInput.id}" is contributed by both a model attribute and a block/base entry kind. A model-attribute entries key must be unique across the namespace's entry kinds.`, { meta: {
|
|
2209
|
+
slot,
|
|
2210
|
+
namespaceId: nsInput.id
|
|
2211
|
+
} });
|
|
2212
|
+
}
|
|
2213
|
+
const mergedValueSet = {
|
|
2214
|
+
...nsInput.entries["valueSet"],
|
|
2215
|
+
...entities?.["valueSet"]
|
|
2216
|
+
};
|
|
2217
|
+
const extended = {
|
|
2218
|
+
...nsInput,
|
|
2219
|
+
entries: {
|
|
2220
|
+
...nsInput.entries,
|
|
2221
|
+
...entities,
|
|
2222
|
+
...attributeEntities,
|
|
2223
|
+
...Object.keys(mergedValueSet).length > 0 ? { valueSet: mergedValueSet } : {}
|
|
2224
|
+
}
|
|
2225
|
+
};
|
|
2226
|
+
return createNamespace(extended);
|
|
2227
|
+
};
|
|
2228
|
+
let contract;
|
|
2229
|
+
try {
|
|
2230
|
+
contract = buildSqlContractFromDefinition({
|
|
2231
|
+
target: input.target,
|
|
2232
|
+
capabilities: input.capabilities,
|
|
2233
|
+
warnings: authoringWarnings.length > 0 ? authoringWarnings : void 0,
|
|
2234
|
+
...ifDefined("extensions", buildComposedExtensionPackRefs(input.target, [...composedExtensions].sort(compareStrings), input.composedExtensionPackRefs)),
|
|
2235
|
+
...Object.keys(validEnumHandles).length > 0 ? { enums: validEnumHandles } : {},
|
|
2236
|
+
...namespaceExtensionEntities.size > 0 ? { namespaces: [...namespaceExtensionEntities.keys()] } : {},
|
|
2237
|
+
createNamespace: createNamespaceWithExtensions,
|
|
2238
|
+
...ifDefined("valueObjects", valueObjects.length > 0 ? valueObjects : void 0),
|
|
2239
|
+
models: stiColumnModelNodes
|
|
2240
|
+
}, input.codecLookup, input.dataTypes.lookup);
|
|
2241
|
+
} catch (error) {
|
|
2242
|
+
const refusal = relationIndexRefusal(error, relationIndexLocations);
|
|
2243
|
+
if (refusal === void 0) throw error;
|
|
2244
|
+
diagnostics.push({
|
|
2245
|
+
code: "PSL_INVALID_RELATION_ATTRIBUTE",
|
|
2246
|
+
message: refusal.message,
|
|
2247
|
+
...refusal.at.location
|
|
2248
|
+
});
|
|
2249
|
+
return notOk({
|
|
2250
|
+
summary: "PSL to SQL contract interpretation failed",
|
|
2251
|
+
diagnostics: diagnostics.toExternal()
|
|
2252
|
+
});
|
|
2253
|
+
}
|
|
2254
|
+
const modelsByCoordinate = {};
|
|
2255
|
+
for (const [namespaceId, namespaceSlice] of Object.entries(contract.domain.namespaces)) for (const [modelName, model] of Object.entries(namespaceSlice.models)) {
|
|
2256
|
+
const coordinate = modelCoordinateKey(namespaceId, modelName);
|
|
2257
|
+
invariant(!Object.hasOwn(modelsByCoordinate, coordinate), `symbol table guarantees coordinate uniqueness; duplicate model "${namespaceId}.${modelName}" reached interpretation`);
|
|
2258
|
+
modelsByCoordinate[coordinate] = model;
|
|
2259
|
+
}
|
|
2260
|
+
const polyDiagnostics = createPslDiagnosticCollector(input.sources);
|
|
2261
|
+
const polymorphicModels = resolvePolymorphism(modelsByCoordinate, physicalNames, discriminatorDeclarations, baseDeclarations, reported, syntheticPkFieldsByVariant, stiBaseFieldsByBase, polyDiagnostics);
|
|
2262
|
+
if (polyDiagnostics.length > 0) return notOk({
|
|
2263
|
+
summary: "PSL to SQL contract interpretation failed",
|
|
2264
|
+
diagnostics: polyDiagnostics.toExternal()
|
|
2265
|
+
});
|
|
2266
|
+
const filteredRoots = Object.fromEntries(Object.entries(contract.roots).filter(([, crossReference]) => !baseDeclarations.has(modelCoordinateKey(crossReference.namespace, crossReference.model))));
|
|
2267
|
+
return ok({
|
|
2268
|
+
...contract,
|
|
2269
|
+
roots: filteredRoots,
|
|
2270
|
+
domain: { namespaces: Object.fromEntries(Object.entries(contract.domain.namespaces).map(([namespaceId, namespaceSlice]) => [namespaceId, {
|
|
2271
|
+
models: Object.fromEntries(Object.entries(namespaceSlice.models).map(([modelName, model]) => [modelName, polymorphicModels[modelCoordinateKey(namespaceId, modelName)] ?? model])),
|
|
2272
|
+
...ifDefined("enum", namespaceSlice.enum),
|
|
2273
|
+
...ifDefined("valueObjects", namespaceSlice.valueObjects)
|
|
2274
|
+
}])) }
|
|
2275
|
+
});
|
|
2276
|
+
}
|
|
2277
|
+
//#endregion
|
|
2278
|
+
export { normalizeReferentialAction as a, interpretPslDocumentToSqlContract as i, buildEntityTypesByDiscriminator as n, indexFkRelations as r, applyBackrelationCandidates as t };
|
|
2279
|
+
|
|
2280
|
+
//# sourceMappingURL=interpreter-D5qk4B---CG0C7kdx.mjs.map
|