@prisma/orm-toolchain 0.16.0
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/LICENSE +201 -0
- package/README.md +28 -0
- package/dist/aggregate-B4mhR4Sk.mjs +1012 -0
- package/dist/aggregate-B4mhR4Sk.mjs.map +1 -0
- package/dist/aggregate-BflrjWPO.d.mts +803 -0
- package/dist/aggregate-BflrjWPO.d.mts.map +1 -0
- package/dist/bin__prisma-next.mjs +800 -0
- package/dist/bin__prisma-next.mjs.map +1 -0
- package/dist/cli-telemetry.d.mts +367 -0
- package/dist/cli-telemetry.d.mts.map +1 -0
- package/dist/cli-telemetry.mjs +48 -0
- package/dist/cli-telemetry.mjs.map +1 -0
- package/dist/cli-telemetry__sender.d.mts +1 -0
- package/dist/cli-telemetry__sender.mjs +1 -0
- package/dist/cli.d.mts +31 -0
- package/dist/cli.d.mts.map +1 -0
- package/dist/cli.mjs +180 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/cli__commands__contract-emit.d.mts +2 -0
- package/dist/cli__commands__contract-emit.mjs +2 -0
- package/dist/cli__commands__contract-infer.d.mts +7 -0
- package/dist/cli__commands__contract-infer.d.mts.map +1 -0
- package/dist/cli__commands__contract-infer.mjs +2 -0
- package/dist/cli__commands__db-init.d.mts +7 -0
- package/dist/cli__commands__db-init.d.mts.map +1 -0
- package/dist/cli__commands__db-init.mjs +2 -0
- package/dist/cli__commands__db-schema.d.mts +7 -0
- package/dist/cli__commands__db-schema.d.mts.map +1 -0
- package/dist/cli__commands__db-schema.mjs +2 -0
- package/dist/cli__commands__db-sign.d.mts +7 -0
- package/dist/cli__commands__db-sign.d.mts.map +1 -0
- package/dist/cli__commands__db-sign.mjs +2 -0
- package/dist/cli__commands__db-update.d.mts +7 -0
- package/dist/cli__commands__db-update.d.mts.map +1 -0
- package/dist/cli__commands__db-update.mjs +2 -0
- package/dist/cli__commands__db-verify.d.mts +7 -0
- package/dist/cli__commands__db-verify.d.mts.map +1 -0
- package/dist/cli__commands__db-verify.mjs +2 -0
- package/dist/cli__commands__migrate.d.mts +66 -0
- package/dist/cli__commands__migrate.d.mts.map +1 -0
- package/dist/cli__commands__migrate.mjs +2 -0
- package/dist/cli__commands__migration-check.d.mts +64 -0
- package/dist/cli__commands__migration-check.d.mts.map +1 -0
- package/dist/cli__commands__migration-check.mjs +3 -0
- package/dist/cli__commands__migration-graph.d.mts +36 -0
- package/dist/cli__commands__migration-graph.d.mts.map +1 -0
- package/dist/cli__commands__migration-graph.mjs +2 -0
- package/dist/cli__commands__migration-list.d.mts +79 -0
- package/dist/cli__commands__migration-list.d.mts.map +1 -0
- package/dist/cli__commands__migration-list.mjs +2 -0
- package/dist/cli__commands__migration-log.d.mts +20 -0
- package/dist/cli__commands__migration-log.d.mts.map +1 -0
- package/dist/cli__commands__migration-log.mjs +2 -0
- package/dist/cli__commands__migration-new.d.mts +7 -0
- package/dist/cli__commands__migration-new.d.mts.map +1 -0
- package/dist/cli__commands__migration-new.mjs +2 -0
- package/dist/cli__commands__migration-plan.d.mts +79 -0
- package/dist/cli__commands__migration-plan.d.mts.map +1 -0
- package/dist/cli__commands__migration-plan.mjs +2 -0
- package/dist/cli__commands__migration-show.d.mts +27 -0
- package/dist/cli__commands__migration-show.d.mts.map +1 -0
- package/dist/cli__commands__migration-show.mjs +2 -0
- package/dist/cli__commands__migration-status.d.mts +55 -0
- package/dist/cli__commands__migration-status.d.mts.map +1 -0
- package/dist/cli__commands__migration-status.mjs +3 -0
- package/dist/cli__commands__ref.d.mts +34 -0
- package/dist/cli__commands__ref.d.mts.map +1 -0
- package/dist/cli__commands__ref.mjs +2 -0
- package/dist/cli__commands__telemetry.d.mts +7 -0
- package/dist/cli__commands__telemetry.d.mts.map +1 -0
- package/dist/cli__commands__telemetry.mjs +2 -0
- package/dist/cli__config-types.d.mts +2 -0
- package/dist/cli__config-types.mjs +2 -0
- package/dist/cli__control-api.d.mts +141 -0
- package/dist/cli__control-api.d.mts.map +1 -0
- package/dist/cli__control-api.mjs +4 -0
- package/dist/cli__init-output.d.mts +37 -0
- package/dist/cli__init-output.d.mts.map +1 -0
- package/dist/cli__init-output.mjs +2 -0
- package/dist/cli__migration-cli.d.mts +79 -0
- package/dist/cli__migration-cli.d.mts.map +1 -0
- package/dist/cli__migration-cli.mjs +407 -0
- package/dist/cli__migration-cli.mjs.map +1 -0
- package/dist/client-75qrAPqf-DZAVUxFa.mjs +1606 -0
- package/dist/client-75qrAPqf-DZAVUxFa.mjs.map +1 -0
- package/dist/command-helpers-CAoXqAY9-DWUBcTXM.mjs +1671 -0
- package/dist/command-helpers-CAoXqAY9-DWUBcTXM.mjs.map +1 -0
- package/dist/config-loader.d.mts +18 -0
- package/dist/config-loader.d.mts.map +1 -0
- package/dist/config-loader.mjs +2 -0
- package/dist/constants-CM-w38DQ-Cz_EXbOc.mjs +10 -0
- package/dist/constants-CM-w38DQ-Cz_EXbOc.mjs.map +1 -0
- package/dist/constants-Dkcn8Qu4.d.mts +10 -0
- package/dist/constants-Dkcn8Qu4.d.mts.map +1 -0
- package/dist/contract-at-errors-BX7w-p19-SxA8eaV2.mjs +36 -0
- package/dist/contract-at-errors-BX7w-p19-SxA8eaV2.mjs.map +1 -0
- package/dist/contract-emit-0hSjbuxp-BBOKldTZ.mjs +148 -0
- package/dist/contract-emit-0hSjbuxp-BBOKldTZ.mjs.map +1 -0
- package/dist/contract-emit-B65_UiFn.d.mts +7 -0
- package/dist/contract-emit-B65_UiFn.d.mts.map +1 -0
- package/dist/contract-emit-B6odMoem-CK3diBPk.mjs +359 -0
- package/dist/contract-emit-B6odMoem-CK3diBPk.mjs.map +1 -0
- package/dist/contract-enrichment-DrMvvY2A-DxNGeF4d.mjs +56 -0
- package/dist/contract-enrichment-DrMvvY2A-DxNGeF4d.mjs.map +1 -0
- package/dist/contract-infer-BnkqpftN-DVM2eKJ3.mjs +73 -0
- package/dist/contract-infer-BnkqpftN-DVM2eKJ3.mjs.map +1 -0
- package/dist/contract-snapshot-store-CbqynbtE.d.mts +28 -0
- package/dist/contract-snapshot-store-CbqynbtE.d.mts.map +1 -0
- package/dist/contract-snapshot-store-sf5nP4mb-MLpG-ihh.mjs +118 -0
- package/dist/contract-snapshot-store-sf5nP4mb-MLpG-ihh.mjs.map +1 -0
- package/dist/contract-space-aggregate-loader-CFH-336b-BhAyRQEL.mjs +302 -0
- package/dist/contract-space-aggregate-loader-CFH-336b-BhAyRQEL.mjs.map +1 -0
- package/dist/db-init-Vbkb_TKZ.mjs +153 -0
- package/dist/db-init-Vbkb_TKZ.mjs.map +1 -0
- package/dist/db-schema-ClQCu3xY.mjs +47 -0
- package/dist/db-schema-ClQCu3xY.mjs.map +1 -0
- package/dist/db-sign-jjXDgQ1u.mjs +175 -0
- package/dist/db-sign-jjXDgQ1u.mjs.map +1 -0
- package/dist/db-update-BQlrqtDD.mjs +183 -0
- package/dist/db-update-BQlrqtDD.mjs.map +1 -0
- package/dist/db-verify-CKPsRFrj-3udprZQD.mjs +396 -0
- package/dist/db-verify-CKPsRFrj-3udprZQD.mjs.map +1 -0
- package/dist/domain-type-generation-DAn9y5d2-BgoT5uKI.mjs +334 -0
- package/dist/domain-type-generation-DAn9y5d2-BgoT5uKI.mjs.map +1 -0
- package/dist/domain-type-generation-PkAb39ob-Ct8AGqow.d.mts +63 -0
- package/dist/domain-type-generation-PkAb39ob-Ct8AGqow.d.mts.map +1 -0
- package/dist/emitter.d.mts +75 -0
- package/dist/emitter.d.mts.map +1 -0
- package/dist/emitter.mjs +3 -0
- package/dist/emitter__domain-type-generation.d.mts +2 -0
- package/dist/emitter__domain-type-generation.mjs +2 -0
- package/dist/emitter__type-expression-safety.d.mts +6 -0
- package/dist/emitter__type-expression-safety.d.mts.map +1 -0
- package/dist/emitter__type-expression-safety.mjs +2 -0
- package/dist/errors--qsXZUtL.d.mts +72 -0
- package/dist/errors--qsXZUtL.d.mts.map +1 -0
- package/dist/errors-IpZm1Skp-BH495dRd.mjs +378 -0
- package/dist/errors-IpZm1Skp-BH495dRd.mjs.map +1 -0
- package/dist/exports-BN0vFTxG.mjs +276 -0
- package/dist/exports-BN0vFTxG.mjs.map +1 -0
- package/dist/exports-B_xhKZmC.mjs +1436 -0
- package/dist/exports-B_xhKZmC.mjs.map +1 -0
- package/dist/exports-D3-NwrMA-CadaBGQ3.mjs +154 -0
- package/dist/exports-D3-NwrMA-CadaBGQ3.mjs.map +1 -0
- package/dist/exports-Dl2aGAk7.mjs +119 -0
- package/dist/exports-Dl2aGAk7.mjs.map +1 -0
- package/dist/format-ByDm2goZ-DKLyhNHo.mjs +101 -0
- package/dist/format-ByDm2goZ-DKLyhNHo.mjs.map +1 -0
- package/dist/framework-components-CjshQKHA-Dlp6Leo5.mjs +58 -0
- package/dist/framework-components-CjshQKHA-Dlp6Leo5.mjs.map +1 -0
- package/dist/global-flags-BpoOYtNZ-CHZD3fud.d.mts +35 -0
- package/dist/global-flags-BpoOYtNZ-CHZD3fud.d.mts.map +1 -0
- package/dist/graph-bDjJ4GL9-BhFevsJS.d.mts +28 -0
- package/dist/graph-bDjJ4GL9-BhFevsJS.d.mts.map +1 -0
- package/dist/graph-membership-DW6nnbyQ-Bp2KcVwR.mjs +14 -0
- package/dist/graph-membership-DW6nnbyQ-Bp2KcVwR.mjs.map +1 -0
- package/dist/hash-DH8hl5Rq-BpM2t3Nu.mjs +64 -0
- package/dist/hash-DH8hl5Rq-BpM2t3Nu.mjs.map +1 -0
- package/dist/hash-XZYYKJ-i.d.mts +53 -0
- package/dist/hash-XZYYKJ-i.d.mts.map +1 -0
- package/dist/import-roots-B6CtsWXb.d.mts +119 -0
- package/dist/import-roots-B6CtsWXb.d.mts.map +1 -0
- package/dist/import-roots-NDOIEDVj.mjs +217 -0
- package/dist/import-roots-NDOIEDVj.mjs.map +1 -0
- package/dist/init-DHctXAI9-DSlaaYXN.mjs +2186 -0
- package/dist/init-DHctXAI9-DSlaaYXN.mjs.map +1 -0
- package/dist/inspect-live-schema-CnwYTRZ0-BErPHMni.mjs +91 -0
- package/dist/inspect-live-schema-CnwYTRZ0-BErPHMni.mjs.map +1 -0
- package/dist/invariants-B5wLrgQS.d.mts +39 -0
- package/dist/invariants-B5wLrgQS.d.mts.map +1 -0
- package/dist/invariants-lXzy6txi-DAoP4nTE.mjs +57 -0
- package/dist/invariants-lXzy6txi-DAoP4nTE.mjs.map +1 -0
- package/dist/io-C8TdyBKt-DloEBi70.mjs +313 -0
- package/dist/io-C8TdyBKt-DloEBi70.mjs.map +1 -0
- package/dist/io-DYfeLJxR.d.mts +1 -0
- package/dist/io-sr4CO9_t-C3eV_kn-.d.mts +125 -0
- package/dist/io-sr4CO9_t-C3eV_kn-.d.mts.map +1 -0
- package/dist/ledger-origin-BGRN77Oy.d.mts +6 -0
- package/dist/ledger-origin-BGRN77Oy.d.mts.map +1 -0
- package/dist/ledger-origin-D7PN4Fon.mjs +9 -0
- package/dist/ledger-origin-D7PN4Fon.mjs.map +1 -0
- package/dist/metadata-2nbOAGsV-uYNeq2Cp.d.mts +2 -0
- package/dist/metadata-BtscDay2.d.mts +1 -0
- package/dist/migrate-Cb_iv264.mjs +500 -0
- package/dist/migrate-Cb_iv264.mjs.map +1 -0
- package/dist/migration-B2ljMJim.d.mts +155 -0
- package/dist/migration-B2ljMJim.d.mts.map +1 -0
- package/dist/migration-BuUmO7It.mjs +209 -0
- package/dist/migration-BuUmO7It.mjs.map +1 -0
- package/dist/migration-check-DcwUnadt-B6Qoh0ot.mjs +597 -0
- package/dist/migration-check-DcwUnadt-B6Qoh0ot.mjs.map +1 -0
- package/dist/migration-command-scaffold-BCuoeAki-B1pVGX8d.mjs +103 -0
- package/dist/migration-command-scaffold-BCuoeAki-B1pVGX8d.mjs.map +1 -0
- package/dist/migration-graph-CBf9ORe7-B4xAF8GN.mjs +500 -0
- package/dist/migration-graph-CBf9ORe7-B4xAF8GN.mjs.map +1 -0
- package/dist/migration-graph-DkoCC0Qy.mjs +185 -0
- package/dist/migration-graph-DkoCC0Qy.mjs.map +1 -0
- package/dist/migration-graph-Dqndu0i5.d.mts +9 -0
- package/dist/migration-graph-Dqndu0i5.d.mts.map +1 -0
- package/dist/migration-graph-command-render-BKrg6BPv-BP8Pfj4J.mjs +1945 -0
- package/dist/migration-graph-command-render-BKrg6BPv-BP8Pfj4J.mjs.map +1 -0
- package/dist/migration-graph-tarTxJ99-BrGBANeE.d.mts +124 -0
- package/dist/migration-graph-tarTxJ99-BrGBANeE.d.mts.map +1 -0
- package/dist/migration-list-BFBeo1_X-c0kqYokL.mjs +228 -0
- package/dist/migration-list-BFBeo1_X-c0kqYokL.mjs.map +1 -0
- package/dist/migration-log-CS5IWcNq-BQ-32Low.mjs +220 -0
- package/dist/migration-log-CS5IWcNq-BQ-32Low.mjs.map +1 -0
- package/dist/migration-new-BurCjyaQ.mjs +168 -0
- package/dist/migration-new-BurCjyaQ.mjs.map +1 -0
- package/dist/migration-path-target-D3Sj55PI-BICblCuk.mjs +38 -0
- package/dist/migration-path-target-D3Sj55PI-BICblCuk.mjs.map +1 -0
- package/dist/migration-plan-q_L84PN1-BWE0LTH6.mjs +759 -0
- package/dist/migration-plan-q_L84PN1-BWE0LTH6.mjs.map +1 -0
- package/dist/migration-show-Bx5I5aW9.mjs +171 -0
- package/dist/migration-show-Bx5I5aW9.mjs.map +1 -0
- package/dist/migration-status-CE7cQLDq-B1jDVmqG.mjs +444 -0
- package/dist/migration-status-CE7cQLDq-B1jDVmqG.mjs.map +1 -0
- package/dist/migration-tools.d.mts +23 -0
- package/dist/migration-tools.mjs +17 -0
- package/dist/migration-tools__aggregate.d.mts +2 -0
- package/dist/migration-tools__aggregate.mjs +2 -0
- package/dist/migration-tools__constants.d.mts +2 -0
- package/dist/migration-tools__constants.mjs +2 -0
- package/dist/migration-tools__contract-snapshot-store.d.mts +2 -0
- package/dist/migration-tools__contract-snapshot-store.mjs +2 -0
- package/dist/migration-tools__errors.d.mts +2 -0
- package/dist/migration-tools__errors.mjs +2 -0
- package/dist/migration-tools__graph.d.mts +2 -0
- package/dist/migration-tools__graph.mjs +1 -0
- package/dist/migration-tools__hash.d.mts +2 -0
- package/dist/migration-tools__hash.mjs +2 -0
- package/dist/migration-tools__invariants.d.mts +2 -0
- package/dist/migration-tools__invariants.mjs +2 -0
- package/dist/migration-tools__io.d.mts +3 -0
- package/dist/migration-tools__io.mjs +2 -0
- package/dist/migration-tools__ledger-origin.d.mts +2 -0
- package/dist/migration-tools__ledger-origin.mjs +2 -0
- package/dist/migration-tools__metadata.d.mts +3 -0
- package/dist/migration-tools__metadata.mjs +1 -0
- package/dist/migration-tools__migration-graph.d.mts +3 -0
- package/dist/migration-tools__migration-graph.mjs +3 -0
- package/dist/migration-tools__migration-ts.d.mts +2 -0
- package/dist/migration-tools__migration-ts.mjs +2 -0
- package/dist/migration-tools__migration.d.mts +2 -0
- package/dist/migration-tools__migration.mjs +2 -0
- package/dist/migration-tools__package.d.mts +3 -0
- package/dist/migration-tools__package.mjs +1 -0
- package/dist/migration-tools__ref-resolution.d.mts +2 -0
- package/dist/migration-tools__ref-resolution.mjs +2 -0
- package/dist/migration-tools__refs.d.mts +2 -0
- package/dist/migration-tools__refs.mjs +2 -0
- package/dist/migration-tools__spaces.d.mts +3 -0
- package/dist/migration-tools__spaces.mjs +3 -0
- package/dist/migration-ts-CNaAtK8C.d.mts +38 -0
- package/dist/migration-ts-CNaAtK8C.d.mts.map +1 -0
- package/dist/migration-ts-FyF55c4M.mjs +67 -0
- package/dist/migration-ts-FyF55c4M.mjs.map +1 -0
- package/dist/op-schema-BSVHzEQN-DIWt28D8.mjs +13 -0
- package/dist/op-schema-BSVHzEQN-DIWt28D8.mjs.map +1 -0
- package/dist/output-DWNYqZGc-D2sRgLAm.mjs +109 -0
- package/dist/output-DWNYqZGc-D2sRgLAm.mjs.map +1 -0
- package/dist/package-CfWiDNrr-ZR4HM_Iz.d.mts +21 -0
- package/dist/package-CfWiDNrr-ZR4HM_Iz.d.mts.map +1 -0
- package/dist/package-N9PPdFV_.d.mts +3 -0
- package/dist/progress-adapter-CjAeTxY_-BXYSd1eY.mjs +43 -0
- package/dist/progress-adapter-CjAeTxY_-BXYSd1eY.mjs.map +1 -0
- package/dist/project-import-root-CpwLCDLY-DkVwAnWj.mjs +99 -0
- package/dist/project-import-root-CpwLCDLY-DkVwAnWj.mjs.map +1 -0
- package/dist/publish-surface.d.mts +3 -0
- package/dist/publish-surface.mjs +3 -0
- package/dist/publish-surface__import-roots.d.mts +2 -0
- package/dist/publish-surface__import-roots.mjs +2 -0
- package/dist/publish-surface__shells.d.mts +2 -0
- package/dist/publish-surface__shells.mjs +2 -0
- package/dist/quick-reference-mongo.md +114 -0
- package/dist/quick-reference-postgres.md +93 -0
- package/dist/readme-mongo.md +35 -0
- package/dist/readme-postgres.md +34 -0
- package/dist/ref-B6cTthTi.mjs +171 -0
- package/dist/ref-B6cTthTi.mjs.map +1 -0
- package/dist/ref-advancement-CSPMoQs3-fEipZrdu.mjs +57 -0
- package/dist/ref-advancement-CSPMoQs3-fEipZrdu.mjs.map +1 -0
- package/dist/ref-resolution-BjJBWPjX.mjs +250 -0
- package/dist/ref-resolution-BjJBWPjX.mjs.map +1 -0
- package/dist/ref-resolution-COGOSL57.d.mts +127 -0
- package/dist/ref-resolution-COGOSL57.d.mts.map +1 -0
- package/dist/refs-BDbB9BRB-D6Za3Q49.mjs +241 -0
- package/dist/refs-BDbB9BRB-D6Za3Q49.mjs.map +1 -0
- package/dist/refs-BNCUu58Y-BIso5Jfg.d.mts +43 -0
- package/dist/refs-BNCUu58Y-BIso5Jfg.d.mts.map +1 -0
- package/dist/schemas-CfGSxH5b-BSjB3nZS.d.mts +192 -0
- package/dist/schemas-CfGSxH5b-BSjB3nZS.d.mts.map +1 -0
- package/dist/schemas-KhXMzNA_-CzZ7GFX_.mjs +112 -0
- package/dist/schemas-KhXMzNA_-CzZ7GFX_.mjs.map +1 -0
- package/dist/shells-BenrJHp2.mjs +602 -0
- package/dist/shells-BenrJHp2.mjs.map +1 -0
- package/dist/shells-COHV_Ozf.d.mts +135 -0
- package/dist/shells-COHV_Ozf.d.mts.map +1 -0
- package/dist/spaces-C27bA-xc.mjs +267 -0
- package/dist/spaces-C27bA-xc.mjs.map +1 -0
- package/dist/spaces-DxFj5y8l.d.mts +415 -0
- package/dist/spaces-DxFj5y8l.d.mts.map +1 -0
- package/dist/telemetry-CmbCa3Ld-CmE5zcIG.mjs +120 -0
- package/dist/telemetry-CmbCa3Ld-CmE5zcIG.mjs.map +1 -0
- package/dist/terminal-ui-BN4QOsm5-Bf3pim46.d.mts +133 -0
- package/dist/terminal-ui-BN4QOsm5-Bf3pim46.d.mts.map +1 -0
- package/dist/type-expression-safety-CgHTWypx.mjs +8 -0
- package/dist/type-expression-safety-CgHTWypx.mjs.map +1 -0
- package/dist/types-DZWEs4si-D8UlyJI0.d.mts +893 -0
- package/dist/types-DZWEs4si-D8UlyJI0.d.mts.map +1 -0
- package/dist/verify-DnVNjc5C-BGdsblBK.mjs +283 -0
- package/dist/verify-DnVNjc5C-BGdsblBK.mjs.map +1 -0
- package/dist/verify-contract-spaces-BZDcJsuA-De8v4Z4T.mjs +252 -0
- package/dist/verify-contract-spaces-BZDcJsuA-De8v4Z4T.mjs.map +1 -0
- package/dist/verify-contract-spaces-Cc1u_wJo-BilPJS2S.d.mts +136 -0
- package/dist/verify-contract-spaces-Cc1u_wJo-BilPJS2S.d.mts.map +1 -0
- package/dist/vite-plugin-contract-emit.d.mts +54 -0
- package/dist/vite-plugin-contract-emit.d.mts.map +1 -0
- package/dist/vite-plugin-contract-emit.mjs +303 -0
- package/dist/vite-plugin-contract-emit.mjs.map +1 -0
- package/package.json +122 -0
|
@@ -0,0 +1,1436 @@
|
|
|
1
|
+
import { n as findNearestConfigPathForFile, r as loadConfig } from "./exports-Dl2aGAk7.mjs";
|
|
2
|
+
import { CliStructuredError } from "@prisma/orm-framework/errors/control";
|
|
3
|
+
import { join } from "pathe";
|
|
4
|
+
import { createControlStack } from "@prisma/orm-framework/components/control";
|
|
5
|
+
import { InternalError } from "@prisma/orm-framework/utils/internal-error";
|
|
6
|
+
import { format } from "@prisma/orm-framework/psl-parser/format";
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
+
import { CompletionItemKind, DiagnosticSeverity, DidChangeWatchedFilesNotification, DocumentDiagnosticReportKind, FoldingRangeKind, InsertTextFormat, RegistrationRequest, SemanticTokenModifiers, SemanticTokenTypes, TextDocumentSyncKind, TextDocuments } from "vscode-languageserver";
|
|
9
|
+
import { TextDocument } from "vscode-languageserver-textdocument";
|
|
10
|
+
import { ArrayLiteralAst, AttributeArgListAst, BooleanLiteralExprAst, CompositeTypeDeclarationAst, FieldAttributeAst, FieldDeclarationAst, FunctionCallAst, GenericBlockDeclarationAst, IdentifierAst, KeyValuePairAst, ModelAttributeAst, ModelDeclarationAst, NamespaceDeclarationAst, NumberLiteralExprAst, ObjectLiteralExprAst, StringLiteralExprAst, TypesBlockAst, any, filterChildren, findChildToken, parse, skipTriviaToken } from "@prisma/orm-framework/psl-parser/syntax";
|
|
11
|
+
import { isAuthoringPslBlockDescriptor } from "@prisma/orm-framework/components/authoring";
|
|
12
|
+
import { buildSymbolTable, findBlockDescriptor } from "@prisma/orm-framework/psl-parser";
|
|
13
|
+
import { hasPslInterpreter } from "@prisma/orm-framework/psl-parser/interpret";
|
|
14
|
+
import { ProposedFeatures, createConnection } from "vscode-languageserver/node";
|
|
15
|
+
//#region ../../../1-framework/3-tooling/language-server/dist/exports/index.mjs
|
|
16
|
+
const ParseDiagnosticSeverity = {
|
|
17
|
+
Error: 1,
|
|
18
|
+
Warning: 2,
|
|
19
|
+
Information: 3,
|
|
20
|
+
Hint: 4
|
|
21
|
+
};
|
|
22
|
+
function mapParseDiagnostics(diagnostics) {
|
|
23
|
+
return diagnostics.map((diagnostic) => ({
|
|
24
|
+
range: diagnostic.range,
|
|
25
|
+
message: diagnostic.message,
|
|
26
|
+
code: diagnostic.code,
|
|
27
|
+
severity: ParseDiagnosticSeverity.Error
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
const documentStartRange = {
|
|
31
|
+
start: {
|
|
32
|
+
line: 0,
|
|
33
|
+
character: 0
|
|
34
|
+
},
|
|
35
|
+
end: {
|
|
36
|
+
line: 0,
|
|
37
|
+
character: 1
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
function mapInterpreterDiagnostics(diagnostics, sourceFile) {
|
|
41
|
+
return diagnostics.map((diagnostic) => ({
|
|
42
|
+
range: diagnostic.span === void 0 ? documentStartRange : pslSpanToRange(diagnostic.span, sourceFile),
|
|
43
|
+
message: diagnostic.message,
|
|
44
|
+
code: diagnostic.code,
|
|
45
|
+
severity: ParseDiagnosticSeverity.Error
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
function pslSpanToRange(span, sourceFile) {
|
|
49
|
+
return {
|
|
50
|
+
start: sourceFile.positionAt(span.start.offset),
|
|
51
|
+
end: sourceFile.positionAt(span.end.offset)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const UNSUPPORTED = { kind: "unsupported" };
|
|
55
|
+
function classifyPslCompletionContext(input) {
|
|
56
|
+
const root = input.document.syntax;
|
|
57
|
+
const offset = input.sourceFile.offsetAt(input.position);
|
|
58
|
+
const at = root.tokenAtOffset(offset);
|
|
59
|
+
if (at.leftBiased()?.kind === "Comment") return UNSUPPORTED;
|
|
60
|
+
const edit = cursorIdentifier(at, offset);
|
|
61
|
+
const preceding = precedingToken(at, edit);
|
|
62
|
+
const precedingNode = preceding?.parent;
|
|
63
|
+
const replacementStartOffset = edit?.offset ?? offset;
|
|
64
|
+
const declarationKeywordContext = classifyDeclarationKeyword({
|
|
65
|
+
node: precedingNode,
|
|
66
|
+
offset,
|
|
67
|
+
replacementStartOffset
|
|
68
|
+
});
|
|
69
|
+
if (declarationKeywordContext !== void 0) return declarationKeywordContext;
|
|
70
|
+
const genericBlockContext = classifyGenericBlockParameter({
|
|
71
|
+
offset,
|
|
72
|
+
at,
|
|
73
|
+
precedingToken: preceding,
|
|
74
|
+
replacementStartOffset
|
|
75
|
+
});
|
|
76
|
+
if (genericBlockContext !== void 0) return genericBlockContext;
|
|
77
|
+
const field = fieldForTypeSlot(precedingNode);
|
|
78
|
+
if (field === void 0) return UNSUPPORTED;
|
|
79
|
+
if (field.syntax.findAncestor(any(ModelDeclarationAst.cast, CompositeTypeDeclarationAst.cast)) === void 0) return UNSUPPORTED;
|
|
80
|
+
return classifyModelFieldType({
|
|
81
|
+
field,
|
|
82
|
+
offset,
|
|
83
|
+
replacementStartOffset,
|
|
84
|
+
precedingToken: preceding
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Locates the field whose type position the cursor occupies. The preceding token
|
|
89
|
+
* climbs to the field whether the cursor sits inside a present type (the type
|
|
90
|
+
* identifier's predecessor still belongs to the field) or in the empty type slot
|
|
91
|
+
* of a typeless field (whose trailing trivia lives in the enclosing block, so
|
|
92
|
+
* the nearest significant token to the left is the field's own name).
|
|
93
|
+
*/
|
|
94
|
+
function fieldForTypeSlot(precedingNode) {
|
|
95
|
+
return precedingNode?.findAncestor(FieldDeclarationAst.cast);
|
|
96
|
+
}
|
|
97
|
+
function classifyModelFieldType(input) {
|
|
98
|
+
const fieldName = input.field.name();
|
|
99
|
+
if (fieldName === void 0) return UNSUPPORTED;
|
|
100
|
+
const fieldNameText = fieldName.name();
|
|
101
|
+
if (fieldNameText === void 0) return UNSUPPORTED;
|
|
102
|
+
if (fieldName.syntax.isInside(input.offset)) return UNSUPPORTED;
|
|
103
|
+
const typeAnnotation = input.field.typeAnnotation();
|
|
104
|
+
if (typeAnnotation === void 0) {
|
|
105
|
+
if (input.precedingToken !== void 0 && fieldName.syntax.isInside(input.precedingToken.offset)) return {
|
|
106
|
+
kind: "modelType",
|
|
107
|
+
offset: input.offset,
|
|
108
|
+
fieldName: fieldNameText,
|
|
109
|
+
replacementStartOffset: input.offset
|
|
110
|
+
};
|
|
111
|
+
return UNSUPPORTED;
|
|
112
|
+
}
|
|
113
|
+
if (typeAnnotation.syntax.isOutside(input.offset)) return UNSUPPORTED;
|
|
114
|
+
if (typeAnnotation.argList()?.syntax.isInside(input.offset)) return UNSUPPORTED;
|
|
115
|
+
const name = typeAnnotation.name();
|
|
116
|
+
if (name === void 0) return UNSUPPORTED;
|
|
117
|
+
if (name.syntax.isOutside(input.offset)) return UNSUPPORTED;
|
|
118
|
+
if (name.isOverQualified()) return UNSUPPORTED;
|
|
119
|
+
return classifyTypePosition(name, input.offset, fieldNameText, input.replacementStartOffset);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Builds the type-completion context for a qualified name. Roles are read
|
|
123
|
+
* straight off the separator-positional accessors: a populated namespace
|
|
124
|
+
* segment is a `.`-qualified name, a populated space segment is a `:`-qualified
|
|
125
|
+
* name, and the absence of both is a bare model type.
|
|
126
|
+
*
|
|
127
|
+
* Behaviour change: a `:`-qualified name with no `.` (e.g. `supabase:`,
|
|
128
|
+
* `supabase:U`) is a `spaceMember` position rather than falling through to bare
|
|
129
|
+
* model-type completions. A malformed leading-separator name (`:User`, `.User`)
|
|
130
|
+
* carries no populated segment and resolves to `modelType` rather than
|
|
131
|
+
* `unsupported`.
|
|
132
|
+
*/
|
|
133
|
+
function classifyTypePosition(name, offset, fieldName, replacementStartOffset) {
|
|
134
|
+
const namespace = name.namespace()?.name();
|
|
135
|
+
if (namespace !== void 0 && namespace.length > 0) {
|
|
136
|
+
const namespaceSpace = name.space()?.name();
|
|
137
|
+
return {
|
|
138
|
+
kind: "namespaceMember",
|
|
139
|
+
offset,
|
|
140
|
+
fieldName,
|
|
141
|
+
replacementStartOffset,
|
|
142
|
+
namespace,
|
|
143
|
+
...namespaceSpace !== void 0 && namespaceSpace.length > 0 ? { space: namespaceSpace } : {}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
const space = name.space()?.name();
|
|
147
|
+
if (space !== void 0 && space.length > 0) return {
|
|
148
|
+
kind: "spaceMember",
|
|
149
|
+
offset,
|
|
150
|
+
fieldName,
|
|
151
|
+
replacementStartOffset,
|
|
152
|
+
space
|
|
153
|
+
};
|
|
154
|
+
return {
|
|
155
|
+
kind: "modelType",
|
|
156
|
+
offset,
|
|
157
|
+
fieldName,
|
|
158
|
+
replacementStartOffset
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const declarationCast = any(ModelDeclarationAst.cast, CompositeTypeDeclarationAst.cast, TypesBlockAst.cast, GenericBlockDeclarationAst.cast, NamespaceDeclarationAst.cast);
|
|
162
|
+
function classifyDeclarationKeyword(input) {
|
|
163
|
+
const precedingDeclaration = input.node?.findAncestor(declarationCast);
|
|
164
|
+
const namespace = input.node?.findAncestor(NamespaceDeclarationAst.cast);
|
|
165
|
+
const inNamespaceBody = blockBodyContainsOffset(namespace, input.offset);
|
|
166
|
+
if (precedingDeclaration !== void 0 && !canCompleteDeclaration(precedingDeclaration, input.offset, inNamespaceBody)) return;
|
|
167
|
+
return {
|
|
168
|
+
kind: "declarationKeyword",
|
|
169
|
+
offset: input.offset,
|
|
170
|
+
scope: inNamespaceBody ? "namespace" : "document",
|
|
171
|
+
replacementStartOffset: input.replacementStartOffset
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Whether a new declaration can begin at the cursor, given the nearest enclosing
|
|
176
|
+
* declaration. Allowed when that declaration is still nascent (only its keyword
|
|
177
|
+
* typed, no name or body yet), when it is a namespace whose body holds further
|
|
178
|
+
* declarations, or when the cursor sits past its closing `}`.
|
|
179
|
+
*/
|
|
180
|
+
function canCompleteDeclaration(precedingDeclaration, offset, inNamespaceBody) {
|
|
181
|
+
if (precedingDeclaration.lbrace() === void 0 && (precedingDeclaration instanceof TypesBlockAst || precedingDeclaration.name() === void 0)) return true;
|
|
182
|
+
if (precedingDeclaration instanceof NamespaceDeclarationAst && inNamespaceBody) return true;
|
|
183
|
+
const rbrace = precedingDeclaration.rbrace();
|
|
184
|
+
return rbrace !== void 0 && offset >= rbrace.endOffset;
|
|
185
|
+
}
|
|
186
|
+
function blockBodyContainsOffset(block, offset) {
|
|
187
|
+
if (block === void 0) return false;
|
|
188
|
+
const lbrace = block.lbrace();
|
|
189
|
+
if (lbrace === void 0) return false;
|
|
190
|
+
const bodyStart = lbrace.endOffset;
|
|
191
|
+
const bodyEnd = block.rbrace()?.offset ?? block.syntax.endOffset;
|
|
192
|
+
return offset >= bodyStart && offset <= bodyEnd;
|
|
193
|
+
}
|
|
194
|
+
function classifyGenericBlockParameter(input) {
|
|
195
|
+
const node = input.at.leftBiased()?.parent;
|
|
196
|
+
const block = node?.findAncestor(GenericBlockDeclarationAst.cast);
|
|
197
|
+
if (block === void 0) return;
|
|
198
|
+
if (hasUnsupportedAncestor(node)) return UNSUPPORTED;
|
|
199
|
+
if (!blockBodyContainsOffset(block, input.offset)) return UNSUPPORTED;
|
|
200
|
+
if ((node?.findAncestor(FieldDeclarationAst.cast))?.syntax.isInside(input.offset)) return UNSUPPORTED;
|
|
201
|
+
const keyword = block.keyword()?.text;
|
|
202
|
+
if (keyword === void 0 || keyword.length === 0) return UNSUPPORTED;
|
|
203
|
+
if (input.precedingToken?.kind === "Equals") return {
|
|
204
|
+
kind: "genericBlockValue",
|
|
205
|
+
offset: input.offset,
|
|
206
|
+
blockKeyword: keyword,
|
|
207
|
+
replacementStartOffset: input.replacementStartOffset
|
|
208
|
+
};
|
|
209
|
+
const activePair = activeKeyValuePair(node, input.offset);
|
|
210
|
+
if (activePair !== void 0 && isAfterEquals(activePair, input.offset)) return UNSUPPORTED;
|
|
211
|
+
return {
|
|
212
|
+
kind: "genericBlockKey",
|
|
213
|
+
offset: input.offset,
|
|
214
|
+
blockKeyword: keyword,
|
|
215
|
+
replacementStartOffset: input.replacementStartOffset,
|
|
216
|
+
block
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function activeKeyValuePair(node, offset) {
|
|
220
|
+
const pair = node?.findAncestor(KeyValuePairAst.cast);
|
|
221
|
+
if (pair === void 0 || pair.syntax.isOutside(offset)) return;
|
|
222
|
+
return pair;
|
|
223
|
+
}
|
|
224
|
+
function isAfterEquals(pair, offset) {
|
|
225
|
+
const equals = pair.equals();
|
|
226
|
+
return equals !== void 0 && offset > equals.offset;
|
|
227
|
+
}
|
|
228
|
+
function hasUnsupportedAncestor(node) {
|
|
229
|
+
return node?.findAncestor(any(AttributeArgListAst.cast, FieldAttributeAst.cast, ModelAttributeAst.cast)) !== void 0;
|
|
230
|
+
}
|
|
231
|
+
/** The significant token preceding the cursor — the in-progress edit identifier
|
|
232
|
+
* is skipped, so the result is the token the classifier anchors on. */
|
|
233
|
+
function precedingToken(at, edit) {
|
|
234
|
+
const start = edit !== void 0 ? edit.prevToken : at.leftBiased();
|
|
235
|
+
return start === void 0 ? void 0 : skipTriviaToken(start, "prev");
|
|
236
|
+
}
|
|
237
|
+
/** The identifier token the cursor is editing, if any. */
|
|
238
|
+
function cursorIdentifier(at, offset) {
|
|
239
|
+
const right = at.rightBiased();
|
|
240
|
+
if (right?.kind === "Ident" && offset < right.endOffset) return right;
|
|
241
|
+
const left = at.leftBiased();
|
|
242
|
+
if (left?.kind === "Ident" && left.endOffset === offset) return left;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Presentation-level classification of a `types {}` binding: a
|
|
246
|
+
* non-constructor binding whose base is a configured scalar type refines that
|
|
247
|
+
* scalar (rendered as a default-library type); everything else reads as a
|
|
248
|
+
* plain alias. The authoritative scalar-or-not pronouncement lives in the
|
|
249
|
+
* interpreter's named-type resolution — this mirrors it for display only.
|
|
250
|
+
*/
|
|
251
|
+
function refinesScalarType(symbol, scalarTypes) {
|
|
252
|
+
return !symbol.isConstructor && symbol.baseType !== void 0 && scalarTypes.includes(symbol.baseType);
|
|
253
|
+
}
|
|
254
|
+
const categoryOrder = {
|
|
255
|
+
configuredScalar: 0,
|
|
256
|
+
topLevelModel: 1,
|
|
257
|
+
topLevelCompositeType: 2,
|
|
258
|
+
scalar: 3,
|
|
259
|
+
typeAlias: 4,
|
|
260
|
+
namespace: 5,
|
|
261
|
+
namespaceModel: 6,
|
|
262
|
+
namespaceCompositeType: 7
|
|
263
|
+
};
|
|
264
|
+
const declarationKeywordCategoryOrder = {
|
|
265
|
+
native: 0,
|
|
266
|
+
genericBlock: 1
|
|
267
|
+
};
|
|
268
|
+
const nameSnippetPlaceholder = "${1:Name}";
|
|
269
|
+
const documentNativeDeclarationKeywords = [
|
|
270
|
+
nativeDeclarationKeyword("model", "model ", `model ${nameSnippetPlaceholder} {\n $0\n}`),
|
|
271
|
+
nativeDeclarationKeyword("type", "type ", `type ${nameSnippetPlaceholder} {\n $0\n}`),
|
|
272
|
+
nativeDeclarationKeyword("types", "types ", "types {\n $0\n}"),
|
|
273
|
+
nativeDeclarationKeyword("namespace", "namespace ", `namespace \${1:name} {\n $0\n}`)
|
|
274
|
+
];
|
|
275
|
+
const namespaceNativeDeclarationKeywords = [nativeDeclarationKeyword("model", "model ", `model ${nameSnippetPlaceholder} {\n $0\n}`), nativeDeclarationKeyword("type", "type ", `type ${nameSnippetPlaceholder} {\n $0\n}`)];
|
|
276
|
+
function providePslCompletionItems(input) {
|
|
277
|
+
const { context } = input;
|
|
278
|
+
switch (context.kind) {
|
|
279
|
+
case "unsupported": return [];
|
|
280
|
+
case "spaceMember": return [];
|
|
281
|
+
case "genericBlockValue": return [];
|
|
282
|
+
case "declarationKeyword": return provideDeclarationKeywordCompletionItems(context, input.sourceFile, input.candidates, input.clientSupportsSnippets);
|
|
283
|
+
case "genericBlockKey": return provideGenericBlockKeyCompletionItems(context, input.sourceFile, input.candidates);
|
|
284
|
+
case "modelType": return provideModelTypeCompletionItems(context, input.sourceFile, input.candidates);
|
|
285
|
+
case "namespaceMember": return provideNamespaceMemberCompletionItems(context, input.sourceFile, input.candidates);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
function provideDeclarationKeywordCompletionItems(context, sourceFile, source, clientSupportsSnippets) {
|
|
289
|
+
const replacementRange = {
|
|
290
|
+
start: sourceFile.positionAt(context.replacementStartOffset),
|
|
291
|
+
end: sourceFile.positionAt(context.offset)
|
|
292
|
+
};
|
|
293
|
+
return declarationKeywordCandidates(context.scope, source).map((candidate) => ({
|
|
294
|
+
label: candidate.label,
|
|
295
|
+
kind: candidate.kind,
|
|
296
|
+
detail: candidate.detail,
|
|
297
|
+
sortText: declarationKeywordSortText(candidate),
|
|
298
|
+
filterText: candidate.label,
|
|
299
|
+
...clientSupportsSnippets ? { insertTextFormat: InsertTextFormat.Snippet } : {},
|
|
300
|
+
textEdit: {
|
|
301
|
+
range: replacementRange,
|
|
302
|
+
newText: clientSupportsSnippets ? candidate.snippetText : candidate.insertText
|
|
303
|
+
}
|
|
304
|
+
}));
|
|
305
|
+
}
|
|
306
|
+
function declarationKeywordCandidates(scope, source) {
|
|
307
|
+
return [...scope === "namespace" ? namespaceNativeDeclarationKeywords : documentNativeDeclarationKeywords, ...genericBlockDeclarationKeywordCandidates(source.pslBlockDescriptors)];
|
|
308
|
+
}
|
|
309
|
+
function nativeDeclarationKeyword(label, insertText, snippetText) {
|
|
310
|
+
return {
|
|
311
|
+
category: "native",
|
|
312
|
+
label,
|
|
313
|
+
insertText,
|
|
314
|
+
snippetText,
|
|
315
|
+
detail: "PSL declaration keyword",
|
|
316
|
+
kind: CompletionItemKind.Keyword
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function genericBlockDeclarationKeywordCandidates(descriptors) {
|
|
320
|
+
return descriptorBlockKeywords(descriptors).map((keyword) => ({
|
|
321
|
+
category: "genericBlock",
|
|
322
|
+
label: keyword,
|
|
323
|
+
insertText: `${keyword} `,
|
|
324
|
+
snippetText: `${keyword} ${nameSnippetPlaceholder} {\n $0\n}`,
|
|
325
|
+
detail: "Generic block keyword",
|
|
326
|
+
kind: CompletionItemKind.Keyword
|
|
327
|
+
}));
|
|
328
|
+
}
|
|
329
|
+
function descriptorBlockKeywords(descriptors) {
|
|
330
|
+
const keywords = [];
|
|
331
|
+
collectDescriptorBlockKeywords(descriptors, keywords);
|
|
332
|
+
return sortedUnique(keywords);
|
|
333
|
+
}
|
|
334
|
+
function collectDescriptorBlockKeywords(descriptors, keywords) {
|
|
335
|
+
for (const value of Object.values(descriptors)) {
|
|
336
|
+
if (isAuthoringPslBlockDescriptor(value)) {
|
|
337
|
+
keywords.push(value.keyword);
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
collectDescriptorBlockKeywords(value, keywords);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
function declarationKeywordSortText(candidate) {
|
|
344
|
+
return `${declarationKeywordCategoryOrder[candidate.category]}:${candidate.label}`;
|
|
345
|
+
}
|
|
346
|
+
function provideGenericBlockKeyCompletionItems(context, sourceFile, source) {
|
|
347
|
+
const descriptor = findBlockDescriptor(source.pslBlockDescriptors, context.blockKeyword);
|
|
348
|
+
if (descriptor === void 0) return [];
|
|
349
|
+
const existing = existingGenericBlockParameterNames(context.block, context.offset);
|
|
350
|
+
const replacementRange = {
|
|
351
|
+
start: sourceFile.positionAt(context.replacementStartOffset),
|
|
352
|
+
end: sourceFile.positionAt(context.offset)
|
|
353
|
+
};
|
|
354
|
+
return Object.keys(descriptor.parameters).filter((parameterName) => !existing.has(parameterName)).map((parameterName, index) => ({
|
|
355
|
+
label: parameterName,
|
|
356
|
+
kind: CompletionItemKind.Property,
|
|
357
|
+
detail: "Generic block parameter",
|
|
358
|
+
sortText: genericBlockParameterSortText(index, parameterName),
|
|
359
|
+
filterText: parameterName,
|
|
360
|
+
textEdit: {
|
|
361
|
+
range: replacementRange,
|
|
362
|
+
newText: parameterName
|
|
363
|
+
}
|
|
364
|
+
}));
|
|
365
|
+
}
|
|
366
|
+
function existingGenericBlockParameterNames(block, cursorOffset) {
|
|
367
|
+
const names = /* @__PURE__ */ new Set();
|
|
368
|
+
for (const entry of block.entries()) {
|
|
369
|
+
if (!entry.syntax.isOutside(cursorOffset)) continue;
|
|
370
|
+
const name = entry.key()?.name();
|
|
371
|
+
if (name !== void 0) names.add(name);
|
|
372
|
+
}
|
|
373
|
+
return names;
|
|
374
|
+
}
|
|
375
|
+
function provideModelTypeCompletionItems(context, sourceFile, source) {
|
|
376
|
+
return modelTypeCompletionItems(context, sourceFile, [
|
|
377
|
+
...configuredScalarCandidates(source.scalarTypes),
|
|
378
|
+
...topLevelSymbolCandidates(source.symbolTable, source.scalarTypes),
|
|
379
|
+
...allNamespaceCandidates(source.symbolTable)
|
|
380
|
+
]);
|
|
381
|
+
}
|
|
382
|
+
function provideNamespaceMemberCompletionItems(context, sourceFile, source) {
|
|
383
|
+
if (context.space !== void 0) return [];
|
|
384
|
+
return modelTypeCompletionItems(context, sourceFile, namespaceCandidates(source.symbolTable.topLevel.namespaces[context.namespace]));
|
|
385
|
+
}
|
|
386
|
+
function modelTypeCompletionItems(context, sourceFile, candidates) {
|
|
387
|
+
const replacementRange = {
|
|
388
|
+
start: sourceFile.positionAt(context.replacementStartOffset),
|
|
389
|
+
end: sourceFile.positionAt(context.offset)
|
|
390
|
+
};
|
|
391
|
+
return candidates.map((candidate) => ({
|
|
392
|
+
label: candidate.label,
|
|
393
|
+
kind: candidate.kind,
|
|
394
|
+
detail: candidate.detail,
|
|
395
|
+
sortText: sortText(candidate),
|
|
396
|
+
filterText: candidate.filterText,
|
|
397
|
+
textEdit: {
|
|
398
|
+
range: replacementRange,
|
|
399
|
+
newText: candidate.insertText
|
|
400
|
+
}
|
|
401
|
+
}));
|
|
402
|
+
}
|
|
403
|
+
function configuredScalarCandidates(scalarTypes) {
|
|
404
|
+
return sortedUnique(scalarTypes).map((name) => ({
|
|
405
|
+
category: "configuredScalar",
|
|
406
|
+
label: name,
|
|
407
|
+
insertText: name,
|
|
408
|
+
filterText: name,
|
|
409
|
+
detail: "Configured scalar type",
|
|
410
|
+
kind: CompletionItemKind.Keyword
|
|
411
|
+
}));
|
|
412
|
+
}
|
|
413
|
+
function topLevelSymbolCandidates(symbolTable, scalarTypes) {
|
|
414
|
+
const { topLevel } = symbolTable;
|
|
415
|
+
const namedTypes = Object.values(topLevel.namedTypes);
|
|
416
|
+
const scalarRefinementNames = namedTypes.filter((symbol) => refinesScalarType(symbol, scalarTypes)).map((symbol) => symbol.name).sort(compareNames);
|
|
417
|
+
const aliasNames = namedTypes.filter((symbol) => !refinesScalarType(symbol, scalarTypes)).map((symbol) => symbol.name).sort(compareNames);
|
|
418
|
+
return [
|
|
419
|
+
...symbolCandidates(recordNames(topLevel.models), "topLevelModel", "Model", CompletionItemKind.Class),
|
|
420
|
+
...symbolCandidates(recordNames(topLevel.compositeTypes), "topLevelCompositeType", "Composite type", CompletionItemKind.Struct),
|
|
421
|
+
...symbolCandidates(scalarRefinementNames, "scalar", "Scalar type", CompletionItemKind.Unit),
|
|
422
|
+
...symbolCandidates(aliasNames, "typeAlias", "Type alias", CompletionItemKind.Reference)
|
|
423
|
+
];
|
|
424
|
+
}
|
|
425
|
+
function allNamespaceCandidates(symbolTable) {
|
|
426
|
+
return Object.values(symbolTable.topLevel.namespaces).sort((left, right) => compareNames(left.name, right.name)).map(namespaceQualifierCandidate);
|
|
427
|
+
}
|
|
428
|
+
function namespaceCandidates(namespace) {
|
|
429
|
+
if (namespace === void 0) return [];
|
|
430
|
+
return [...symbolCandidates(recordNames(namespace.models), "namespaceModel", `Model in namespace ${namespace.name}`, CompletionItemKind.Class), ...symbolCandidates(recordNames(namespace.compositeTypes), "namespaceCompositeType", `Composite type in namespace ${namespace.name}`, CompletionItemKind.Struct)];
|
|
431
|
+
}
|
|
432
|
+
function namespaceQualifierCandidate(namespace) {
|
|
433
|
+
return {
|
|
434
|
+
category: "namespace",
|
|
435
|
+
label: namespace.name,
|
|
436
|
+
insertText: namespace.name,
|
|
437
|
+
filterText: namespace.name,
|
|
438
|
+
detail: "Namespace",
|
|
439
|
+
kind: CompletionItemKind.Module
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
function symbolCandidates(names, category, detail, kind) {
|
|
443
|
+
return names.map((name) => ({
|
|
444
|
+
category,
|
|
445
|
+
label: name,
|
|
446
|
+
insertText: name,
|
|
447
|
+
filterText: name,
|
|
448
|
+
detail,
|
|
449
|
+
kind
|
|
450
|
+
}));
|
|
451
|
+
}
|
|
452
|
+
function recordNames(record) {
|
|
453
|
+
return Object.values(record).map((symbol) => symbol.name).sort(compareNames);
|
|
454
|
+
}
|
|
455
|
+
function sortedUnique(names) {
|
|
456
|
+
return [...new Set(names)].sort(compareNames);
|
|
457
|
+
}
|
|
458
|
+
function sortText(candidate) {
|
|
459
|
+
return `${categoryOrder[candidate.category]}:${candidate.label}`;
|
|
460
|
+
}
|
|
461
|
+
function genericBlockParameterSortText(index, label) {
|
|
462
|
+
return `${index.toString().padStart(4, "0")}:${label}`;
|
|
463
|
+
}
|
|
464
|
+
function compareNames(left, right) {
|
|
465
|
+
if (left < right) return -1;
|
|
466
|
+
if (left > right) return 1;
|
|
467
|
+
return 0;
|
|
468
|
+
}
|
|
469
|
+
function hasPslInputs(config) {
|
|
470
|
+
const source = config.contract?.source;
|
|
471
|
+
return source?.format === "psl" && source.inputs !== void 0;
|
|
472
|
+
}
|
|
473
|
+
function resolveSchemaInputs(config) {
|
|
474
|
+
const inputs = hasPslInputs(config) ? config.contract?.source.inputs : void 0;
|
|
475
|
+
const uris = new Set(inputs?.map((input) => pathToFileURL(input).toString()));
|
|
476
|
+
return {
|
|
477
|
+
includes: (uri) => uris.has(uri),
|
|
478
|
+
uris: () => uris
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
const CONFIG_FILENAME = "prisma-next.config.ts";
|
|
482
|
+
const emptyPipelineInputs = {
|
|
483
|
+
scalarTypes: [],
|
|
484
|
+
pslBlockDescriptors: {}
|
|
485
|
+
};
|
|
486
|
+
async function resolveConfigInputs(configPath) {
|
|
487
|
+
const config = await loadConfig(configPath);
|
|
488
|
+
const inputs = resolveSchemaInputs(config);
|
|
489
|
+
if (!hasPslInputs(config)) return {
|
|
490
|
+
inputs,
|
|
491
|
+
controlStack: emptyPipelineInputs,
|
|
492
|
+
...config.formatter === void 0 ? {} : { formatter: config.formatter }
|
|
493
|
+
};
|
|
494
|
+
const stack = createControlStack(config);
|
|
495
|
+
const interpretation = resolveInterpretation(config, stack, inputs);
|
|
496
|
+
return {
|
|
497
|
+
inputs,
|
|
498
|
+
controlStack: pipelineInputsFromStack(stack),
|
|
499
|
+
...config.formatter === void 0 ? {} : { formatter: config.formatter },
|
|
500
|
+
...interpretation === void 0 ? {} : { interpretation }
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
function pipelineInputsFromStack(stack) {
|
|
504
|
+
return {
|
|
505
|
+
scalarTypes: [...stack.scalarTypes],
|
|
506
|
+
pslBlockDescriptors: stack.authoringContributions.pslBlockDescriptors
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
function resolveInterpretation(config, stack, inputs) {
|
|
510
|
+
const source = config.contract?.source;
|
|
511
|
+
if (source === void 0 || !hasPslInterpreter(source)) return;
|
|
512
|
+
return {
|
|
513
|
+
source,
|
|
514
|
+
context: {
|
|
515
|
+
composedExtensions: stack.extensions.map((p) => p.id),
|
|
516
|
+
composedExtensionContracts: stack.extensionContracts,
|
|
517
|
+
authoringContributions: stack.authoringContributions,
|
|
518
|
+
codecLookup: stack.codecLookup,
|
|
519
|
+
controlMutationDefaults: stack.controlMutationDefaults,
|
|
520
|
+
resolvedInputs: [...inputs.uris()],
|
|
521
|
+
capabilities: stack.capabilities
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Computes folding ranges for block declarations in a PSL document.
|
|
527
|
+
*
|
|
528
|
+
* Block types that produce folding ranges:
|
|
529
|
+
* - model (e.g., `model User { ... }`)
|
|
530
|
+
* - composite type (e.g., `type Address { ... }`)
|
|
531
|
+
* - namespace (e.g., `namespace billing { ... }`)
|
|
532
|
+
* - generic blocks (generator, datasource, extension blocks)
|
|
533
|
+
* - types block (e.g., `types { ... }`)
|
|
534
|
+
*
|
|
535
|
+
* The range spans from the line containing `{` to the line containing `}`.
|
|
536
|
+
*/
|
|
537
|
+
function computeFoldingRanges(document, sourceFile) {
|
|
538
|
+
const ranges = [];
|
|
539
|
+
collectFoldingRanges(document, sourceFile, ranges);
|
|
540
|
+
return ranges;
|
|
541
|
+
}
|
|
542
|
+
function collectFoldingRanges(document, sourceFile, ranges) {
|
|
543
|
+
for (const declaration of document.declarations()) {
|
|
544
|
+
addFoldingRange(declaration, sourceFile, ranges);
|
|
545
|
+
const namespace = NamespaceDeclarationAst.cast(declaration.syntax);
|
|
546
|
+
if (namespace !== void 0) for (const nested of namespace.declarations()) addFoldingRange(nested, sourceFile, ranges);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
function addFoldingRange(declaration, sourceFile, ranges) {
|
|
550
|
+
const lbrace = declaration.lbrace();
|
|
551
|
+
const rbrace = declaration.rbrace();
|
|
552
|
+
if (lbrace === void 0 || rbrace === void 0) return;
|
|
553
|
+
const startLine = sourceFile.positionAt(lbrace.offset).line;
|
|
554
|
+
const endLine = sourceFile.positionAt(rbrace.offset).line;
|
|
555
|
+
ranges.push({
|
|
556
|
+
startLine,
|
|
557
|
+
endLine,
|
|
558
|
+
kind: FoldingRangeKind.Region
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Composes the stages exactly as the contract-psl provider does, so the editor
|
|
563
|
+
* and the build agree: `parse` then `buildSymbolTable`, parse diagnostics ahead
|
|
564
|
+
* of symbol-table diagnostics. Never throws on malformed input — `parse`
|
|
565
|
+
* recovers and `buildSymbolTable` is documented not to throw.
|
|
566
|
+
*/
|
|
567
|
+
function runPipeline(text, inputs) {
|
|
568
|
+
const { document, sourceFile, diagnostics: parseDiagnostics } = parse(text);
|
|
569
|
+
const { table: symbolTable, diagnostics: symbolTableDiagnostics } = buildSymbolTable({
|
|
570
|
+
document,
|
|
571
|
+
sourceFile,
|
|
572
|
+
pslBlockDescriptors: inputs.pslBlockDescriptors
|
|
573
|
+
});
|
|
574
|
+
return {
|
|
575
|
+
document,
|
|
576
|
+
sourceFile,
|
|
577
|
+
symbolTable,
|
|
578
|
+
diagnostics: mapParseDiagnostics([...parseDiagnostics, ...symbolTableDiagnostics])
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* `null` (not a configured input) is distinct from a `DocumentDiagnostics` whose
|
|
583
|
+
* `diagnostics` are `[]` (an input that parsed clean): the caller treats both as
|
|
584
|
+
* "publish no diagnostics", but only the latter is a document we own and keep
|
|
585
|
+
* diagnosing.
|
|
586
|
+
*/
|
|
587
|
+
function computeDocumentDiagnostics(uri, text, inputs, controlStack) {
|
|
588
|
+
if (!inputs.includes(uri)) return null;
|
|
589
|
+
const { document, sourceFile, symbolTable, diagnostics } = runPipeline(text, controlStack);
|
|
590
|
+
return {
|
|
591
|
+
diagnostics,
|
|
592
|
+
document,
|
|
593
|
+
sourceFile,
|
|
594
|
+
symbolTable
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
function createProjectArtifacts(options) {
|
|
598
|
+
const { inputs, controlStack, getText, interpretation } = options;
|
|
599
|
+
const documents = /* @__PURE__ */ new Map();
|
|
600
|
+
let symbolTable;
|
|
601
|
+
function createInterpretSlot(uri, computed) {
|
|
602
|
+
if (interpretation === void 0) return () => [];
|
|
603
|
+
let memo;
|
|
604
|
+
return () => {
|
|
605
|
+
if (memo === void 0) {
|
|
606
|
+
const result = interpretation.source.interpret({
|
|
607
|
+
document: computed.document,
|
|
608
|
+
sourceFile: computed.sourceFile,
|
|
609
|
+
symbolTable: computed.symbolTable,
|
|
610
|
+
sourceId: uri
|
|
611
|
+
}, interpretation.context);
|
|
612
|
+
memo = mapInterpreterDiagnostics(result.ok ? [] : result.failure.diagnostics, computed.sourceFile);
|
|
613
|
+
}
|
|
614
|
+
return memo;
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
function drop(uri) {
|
|
618
|
+
if (documents.delete(uri)) symbolTable = void 0;
|
|
619
|
+
}
|
|
620
|
+
function readDocument(uri) {
|
|
621
|
+
const existing = documents.get(uri);
|
|
622
|
+
if (existing !== void 0) return existing;
|
|
623
|
+
const text = getText(uri);
|
|
624
|
+
if (text === void 0) return;
|
|
625
|
+
const computed = computeDocumentDiagnostics(uri, text, inputs, controlStack);
|
|
626
|
+
if (computed === null) return;
|
|
627
|
+
const artifacts = {
|
|
628
|
+
document: computed.document,
|
|
629
|
+
sourceFile: computed.sourceFile,
|
|
630
|
+
diagnostics: computed.diagnostics,
|
|
631
|
+
interpretDiagnostics: createInterpretSlot(uri, computed)
|
|
632
|
+
};
|
|
633
|
+
documents.set(uri, artifacts);
|
|
634
|
+
symbolTable = computed.symbolTable;
|
|
635
|
+
return artifacts;
|
|
636
|
+
}
|
|
637
|
+
return {
|
|
638
|
+
document: readDocument,
|
|
639
|
+
symbolTable: () => {
|
|
640
|
+
if (symbolTable !== void 0) return symbolTable;
|
|
641
|
+
for (const uri of inputs.uris()) {
|
|
642
|
+
const artifacts = readDocument(uri);
|
|
643
|
+
if (artifacts === void 0) continue;
|
|
644
|
+
symbolTable ??= buildSymbolTable({
|
|
645
|
+
document: artifacts.document,
|
|
646
|
+
sourceFile: artifacts.sourceFile,
|
|
647
|
+
pslBlockDescriptors: controlStack.pslBlockDescriptors
|
|
648
|
+
}).table;
|
|
649
|
+
return symbolTable;
|
|
650
|
+
}
|
|
651
|
+
throw new InternalError("invariant violated: project has no open configured input — the server must drop such projects");
|
|
652
|
+
},
|
|
653
|
+
documentChanged: drop,
|
|
654
|
+
documentClosed: drop
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
const semanticTokenTypes = [
|
|
658
|
+
SemanticTokenTypes.keyword,
|
|
659
|
+
SemanticTokenTypes.namespace,
|
|
660
|
+
SemanticTokenTypes.class,
|
|
661
|
+
SemanticTokenTypes.struct,
|
|
662
|
+
SemanticTokenTypes.type,
|
|
663
|
+
SemanticTokenTypes.property,
|
|
664
|
+
SemanticTokenTypes.decorator,
|
|
665
|
+
SemanticTokenTypes.string,
|
|
666
|
+
SemanticTokenTypes.number,
|
|
667
|
+
SemanticTokenTypes.comment
|
|
668
|
+
];
|
|
669
|
+
const semanticTokenModifiers = [SemanticTokenModifiers.declaration, SemanticTokenModifiers.defaultLibrary];
|
|
670
|
+
const semanticTokenModifierIndexes = {
|
|
671
|
+
declaration: 0,
|
|
672
|
+
defaultLibrary: 1
|
|
673
|
+
};
|
|
674
|
+
const semanticTokenModifierBits = {
|
|
675
|
+
declaration: 1 << semanticTokenModifierIndexes.declaration,
|
|
676
|
+
defaultLibrary: 1 << semanticTokenModifierIndexes.defaultLibrary
|
|
677
|
+
};
|
|
678
|
+
const semanticTokensLegend = {
|
|
679
|
+
tokenTypes: [...semanticTokenTypes],
|
|
680
|
+
tokenModifiers: [...semanticTokenModifiers]
|
|
681
|
+
};
|
|
682
|
+
function buildSemanticTokens(source, range) {
|
|
683
|
+
const builder = new SemanticTokensBuilder(source.sourceFile, range);
|
|
684
|
+
for (const token of collectSemanticTokenEvents(source)) builder.add(token);
|
|
685
|
+
return builder.build();
|
|
686
|
+
}
|
|
687
|
+
function collectSemanticTokenEvents(source) {
|
|
688
|
+
const comments = collectCommentTokens(source.document);
|
|
689
|
+
const tokens = [];
|
|
690
|
+
collectDeclarations(source, tokens);
|
|
691
|
+
return mergeSourceOrderedTokens(comments, tokens);
|
|
692
|
+
}
|
|
693
|
+
var SemanticTokensBuilder = class {
|
|
694
|
+
#data = [];
|
|
695
|
+
#sourceFile;
|
|
696
|
+
#rangeOffsets;
|
|
697
|
+
#previousLine = 0;
|
|
698
|
+
#previousCharacter = 0;
|
|
699
|
+
#first = true;
|
|
700
|
+
constructor(sourceFile, range) {
|
|
701
|
+
this.#sourceFile = sourceFile;
|
|
702
|
+
if (range !== void 0) {
|
|
703
|
+
const startOffset = sourceFile.offsetAt(range.start);
|
|
704
|
+
const endOffset = sourceFile.offsetAt(range.end);
|
|
705
|
+
this.#rangeOffsets = {
|
|
706
|
+
lower: Math.min(startOffset, endOffset),
|
|
707
|
+
upper: Math.max(startOffset, endOffset)
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
add(token) {
|
|
712
|
+
if (!this.#intersectsRange(token.startOffset, token.endOffset)) return;
|
|
713
|
+
if (token.splitMultiline) {
|
|
714
|
+
this.#addMultilineSplitToken(token);
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
this.#encode(token.startOffset, token.endOffset, token.tokenTypeIndex, token.modifierBitset);
|
|
718
|
+
}
|
|
719
|
+
build() {
|
|
720
|
+
return { data: this.#data };
|
|
721
|
+
}
|
|
722
|
+
#intersectsRange(startOffset, endOffset) {
|
|
723
|
+
const rangeOffsets = this.#rangeOffsets;
|
|
724
|
+
return rangeOffsets === void 0 || startOffset < rangeOffsets.upper && endOffset > rangeOffsets.lower;
|
|
725
|
+
}
|
|
726
|
+
#addMultilineSplitToken(token) {
|
|
727
|
+
const start = this.#sourceFile.positionAt(token.startOffset);
|
|
728
|
+
const end = this.#sourceFile.positionAt(token.endOffset);
|
|
729
|
+
if (start.line === end.line) {
|
|
730
|
+
this.#encode(token.startOffset, token.endOffset, token.tokenTypeIndex, token.modifierBitset);
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
for (let line = start.line; line <= end.line; line++) {
|
|
734
|
+
const startOffset = line === start.line ? token.startOffset : this.#sourceFile.lineStartOffset(line);
|
|
735
|
+
const endOffset = line === end.line ? token.endOffset : this.#sourceFile.lineEndOffset(line);
|
|
736
|
+
if (endOffset > startOffset && this.#intersectsRange(startOffset, endOffset)) this.#encode(startOffset, endOffset, token.tokenTypeIndex, token.modifierBitset);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
#encode(startOffset, endOffset, tokenTypeIndex, modifierBitset) {
|
|
740
|
+
const start = this.#sourceFile.positionAt(startOffset);
|
|
741
|
+
const deltaLine = this.#first ? start.line : start.line - this.#previousLine;
|
|
742
|
+
const deltaStart = this.#first || deltaLine !== 0 ? start.character : start.character - this.#previousCharacter;
|
|
743
|
+
this.#data.push(deltaLine, deltaStart, endOffset - startOffset, tokenTypeIndex, modifierBitset);
|
|
744
|
+
this.#previousLine = start.line;
|
|
745
|
+
this.#previousCharacter = start.character;
|
|
746
|
+
this.#first = false;
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
function collectCommentTokens(document) {
|
|
750
|
+
const tokens = [];
|
|
751
|
+
for (const token of document.syntax.tokens()) if (token.kind === "Comment") tokens.push(pendingTokenForToken(token, "comment"));
|
|
752
|
+
return tokens;
|
|
753
|
+
}
|
|
754
|
+
function collectDeclarations(source, tokens) {
|
|
755
|
+
for (const declaration of source.document.declarations()) collectDeclaration(declaration, source, tokens, void 0);
|
|
756
|
+
}
|
|
757
|
+
function collectDeclaration(declaration, source, tokens, namespace) {
|
|
758
|
+
if (declaration instanceof ModelDeclarationAst) {
|
|
759
|
+
addToken(declaration.keyword(), "keyword", tokens);
|
|
760
|
+
addIdentifier(declaration.name(), "class", tokens, semanticTokenModifierBits.declaration);
|
|
761
|
+
collectBlockMembers(declaration.members(), source, tokens, namespace);
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
if (declaration instanceof CompositeTypeDeclarationAst) {
|
|
765
|
+
addToken(declaration.keyword(), "keyword", tokens);
|
|
766
|
+
addIdentifier(declaration.name(), "struct", tokens, semanticTokenModifierBits.declaration);
|
|
767
|
+
collectBlockMembers(declaration.members(), source, tokens, namespace);
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
if (declaration instanceof NamespaceDeclarationAst) {
|
|
771
|
+
addToken(declaration.keyword(), "keyword", tokens);
|
|
772
|
+
addIdentifier(declaration.name(), "namespace", tokens, semanticTokenModifierBits.declaration);
|
|
773
|
+
const nestedNamespace = declaration.name()?.name();
|
|
774
|
+
for (const nested of declaration.declarations()) collectDeclaration(nested, source, tokens, nestedNamespace);
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
if (declaration instanceof TypesBlockAst) {
|
|
778
|
+
addToken(declaration.keyword(), "keyword", tokens);
|
|
779
|
+
for (const namedType of declaration.declarations()) collectNamedTypeDeclaration(namedType, source, tokens, namespace);
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
addToken(declaration.keyword(), "keyword", tokens);
|
|
783
|
+
addIdentifier(declaration.name(), "type", tokens, semanticTokenModifierBits.declaration);
|
|
784
|
+
collectGenericBlockMembers(declaration.members(), source, tokens, namespace);
|
|
785
|
+
}
|
|
786
|
+
function collectNamedTypeDeclaration(declaration, source, tokens, namespace) {
|
|
787
|
+
addIdentifier(declaration.name(), "type", tokens, semanticTokenModifierBits.declaration);
|
|
788
|
+
collectTypeAnnotation(declaration.typeAnnotation(), source, tokens, namespace);
|
|
789
|
+
collectAttributes(declaration.attributes(), source, tokens, namespace);
|
|
790
|
+
}
|
|
791
|
+
function collectGenericBlockMembers(members, source, tokens, namespace) {
|
|
792
|
+
for (const member of members) {
|
|
793
|
+
if ("key" in member) {
|
|
794
|
+
addIdentifier(member.key(), "property", tokens);
|
|
795
|
+
collectExpression(member.value(), source, tokens, namespace);
|
|
796
|
+
continue;
|
|
797
|
+
}
|
|
798
|
+
collectAttribute(member, source, tokens, namespace);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
function collectBlockMembers(members, source, tokens, namespace) {
|
|
802
|
+
for (const member of members) {
|
|
803
|
+
if (member instanceof FieldDeclarationAst) {
|
|
804
|
+
collectField(member, source, tokens, namespace);
|
|
805
|
+
continue;
|
|
806
|
+
}
|
|
807
|
+
collectAttribute(member, source, tokens, namespace);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
function collectField(field, source, tokens, namespace) {
|
|
811
|
+
addIdentifier(field.name(), "property", tokens, semanticTokenModifierBits.declaration);
|
|
812
|
+
collectTypeAnnotation(field.typeAnnotation(), source, tokens, namespace);
|
|
813
|
+
collectAttributes(field.attributes(), source, tokens, namespace);
|
|
814
|
+
}
|
|
815
|
+
function collectTypeAnnotation(annotation, source, tokens, namespace) {
|
|
816
|
+
if (annotation === void 0) return;
|
|
817
|
+
collectTypeReference(annotation.name(), source, tokens, namespace);
|
|
818
|
+
collectAttributeArgList(annotation.argList(), source, tokens, namespace);
|
|
819
|
+
}
|
|
820
|
+
function collectAttributes(attributes, source, tokens, namespace) {
|
|
821
|
+
for (const attribute of attributes) collectAttribute(attribute, source, tokens, namespace);
|
|
822
|
+
}
|
|
823
|
+
function collectAttribute(attribute, source, tokens, namespace) {
|
|
824
|
+
const marker = findChildToken(attribute.syntax, "At") ?? findChildToken(attribute.syntax, "DoubleAt");
|
|
825
|
+
collectDecoratorName(attribute.name(), marker, tokens);
|
|
826
|
+
collectAttributeArgList(attribute.argList(), source, tokens, namespace);
|
|
827
|
+
}
|
|
828
|
+
function collectDecoratorName(name, marker, tokens) {
|
|
829
|
+
if (name === void 0) return;
|
|
830
|
+
const segments = identifierSegments(name);
|
|
831
|
+
for (const [index, segment] of segments.entries()) tokens.push(rangeForDecoratorIdentifier(segment.identifier, index === 0 ? marker : void 0));
|
|
832
|
+
}
|
|
833
|
+
function collectAttributeArgList(argList, source, tokens, namespace) {
|
|
834
|
+
if (argList === void 0) return;
|
|
835
|
+
for (const arg of argList.args()) collectAttributeArg(arg, source, tokens, namespace);
|
|
836
|
+
}
|
|
837
|
+
function collectAttributeArg(arg, source, tokens, namespace) {
|
|
838
|
+
const name = arg.name();
|
|
839
|
+
addIdentifier(name, "property", tokens);
|
|
840
|
+
collectExpression(arg.value(), source, tokens, namespace, expressionContextForAttributeArg(name));
|
|
841
|
+
}
|
|
842
|
+
function collectExpression(expression, source, tokens, namespace, context = {}) {
|
|
843
|
+
if (expression === void 0) return;
|
|
844
|
+
if (expression instanceof StringLiteralExprAst) {
|
|
845
|
+
addToken(expression.token(), "string", tokens);
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
if (expression instanceof NumberLiteralExprAst) {
|
|
849
|
+
addToken(expression.token(), "number", tokens);
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
if (expression instanceof BooleanLiteralExprAst) {
|
|
853
|
+
addToken(expression.token(), "keyword", tokens);
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
if (expression instanceof FunctionCallAst) {
|
|
857
|
+
collectTypeReference(expression.name(), source, tokens, namespace);
|
|
858
|
+
for (const arg of expression.args()) collectAttributeArg(arg, source, tokens, namespace);
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
if (expression instanceof ArrayLiteralAst) {
|
|
862
|
+
for (const element of expression.elements()) collectExpression(element, source, tokens, namespace, context);
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
if (expression instanceof ObjectLiteralExprAst) {
|
|
866
|
+
for (const field of expression.fields()) {
|
|
867
|
+
addIdentifier(field.key(), "property", tokens);
|
|
868
|
+
collectExpression(field.value(), source, tokens, namespace);
|
|
869
|
+
}
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
collectIdentifierExpression(expression, source, tokens, namespace, context);
|
|
873
|
+
}
|
|
874
|
+
function collectIdentifierExpression(identifier, source, tokens, namespace, context) {
|
|
875
|
+
const text = identifier.name();
|
|
876
|
+
if (text === void 0) return;
|
|
877
|
+
const bareIdentifierTokenType = context.bareIdentifierTokenType;
|
|
878
|
+
if (bareIdentifierTokenType !== void 0) {
|
|
879
|
+
tokens.push(rangeForIdentifier(identifier, bareIdentifierTokenType));
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
const classification = classifyTypeReference([text], source, namespace);
|
|
883
|
+
tokens.push(rangeForIdentifier(identifier, classification.tokenType, classification.modifierBitset));
|
|
884
|
+
}
|
|
885
|
+
function expressionContextForAttributeArg(name) {
|
|
886
|
+
const argName = name?.name();
|
|
887
|
+
return argName === "fields" || argName === "references" ? { bareIdentifierTokenType: "property" } : {};
|
|
888
|
+
}
|
|
889
|
+
function collectTypeReference(name, source, tokens, namespace) {
|
|
890
|
+
if (name === void 0) return;
|
|
891
|
+
const segments = identifierSegments(name);
|
|
892
|
+
if (segments.length === 0) return;
|
|
893
|
+
const path = segments.map((segment) => segment.text);
|
|
894
|
+
for (const segment of segments.slice(0, -1)) if (isKnownNamespace(segment.text, source.symbolTable)) tokens.push(rangeForIdentifier(segment.identifier, "namespace"));
|
|
895
|
+
const finalSegment = segments[segments.length - 1];
|
|
896
|
+
if (finalSegment === void 0) return;
|
|
897
|
+
const classification = classifyTypeReference(path, source, namespace);
|
|
898
|
+
tokens.push(rangeForIdentifier(finalSegment.identifier, classification.tokenType, classification.modifierBitset));
|
|
899
|
+
}
|
|
900
|
+
function classifyTypeReference(path, source, namespace) {
|
|
901
|
+
const name = path[path.length - 1];
|
|
902
|
+
if (name === void 0) return { tokenType: "type" };
|
|
903
|
+
const table = source.symbolTable;
|
|
904
|
+
const namespaceName = path.length > 1 ? path[path.length - 2] : namespace;
|
|
905
|
+
const namespaceScope = namespaceName !== void 0 ? table.topLevel.namespaces[namespaceName] : void 0;
|
|
906
|
+
if (namespaceScope !== void 0) {
|
|
907
|
+
if (Object.hasOwn(namespaceScope.models, name)) return { tokenType: "class" };
|
|
908
|
+
if (Object.hasOwn(namespaceScope.compositeTypes, name)) return { tokenType: "struct" };
|
|
909
|
+
if (Object.hasOwn(namespaceScope.blocks, name)) return { tokenType: "type" };
|
|
910
|
+
}
|
|
911
|
+
if (Object.hasOwn(table.topLevel.models, name)) return { tokenType: "class" };
|
|
912
|
+
if (Object.hasOwn(table.topLevel.compositeTypes, name)) return { tokenType: "struct" };
|
|
913
|
+
const namedType = table.topLevel.namedTypes[name];
|
|
914
|
+
if (namedType !== void 0) return refinesScalarType(namedType, source.scalarTypes) ? {
|
|
915
|
+
tokenType: "type",
|
|
916
|
+
modifierBitset: semanticTokenModifierBits.defaultLibrary
|
|
917
|
+
} : { tokenType: "type" };
|
|
918
|
+
if (Object.hasOwn(table.topLevel.blocks, name)) return { tokenType: "type" };
|
|
919
|
+
if (source.scalarTypes.includes(name)) return {
|
|
920
|
+
tokenType: "type",
|
|
921
|
+
modifierBitset: semanticTokenModifierBits.defaultLibrary
|
|
922
|
+
};
|
|
923
|
+
return { tokenType: "type" };
|
|
924
|
+
}
|
|
925
|
+
function isKnownNamespace(name, table) {
|
|
926
|
+
return Object.hasOwn(table.topLevel.namespaces, name);
|
|
927
|
+
}
|
|
928
|
+
function identifierSegments(name) {
|
|
929
|
+
const segments = [];
|
|
930
|
+
for (const identifier of filterChildren(name.syntax, IdentifierAst.cast)) {
|
|
931
|
+
const text = identifier.name();
|
|
932
|
+
if (text !== void 0) segments.push({
|
|
933
|
+
identifier,
|
|
934
|
+
text
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
return segments;
|
|
938
|
+
}
|
|
939
|
+
function addIdentifier(identifier, tokenType, tokens, modifierBitset = 0) {
|
|
940
|
+
if (identifier === void 0) return;
|
|
941
|
+
tokens.push(rangeForIdentifier(identifier, tokenType, modifierBitset));
|
|
942
|
+
}
|
|
943
|
+
function addToken(token, tokenType, tokens, modifierBitset = 0) {
|
|
944
|
+
if (token === void 0) return;
|
|
945
|
+
tokens.push(pendingTokenForToken(token, tokenType, modifierBitset));
|
|
946
|
+
}
|
|
947
|
+
function rangeForIdentifier(identifier, tokenType, modifierBitset = 0) {
|
|
948
|
+
const token = identifier.token();
|
|
949
|
+
if (token === void 0) return createPendingSemanticToken(identifier.syntax.offset, identifier.syntax.offset, tokenType, modifierBitset);
|
|
950
|
+
return pendingTokenForToken(token, tokenType, modifierBitset);
|
|
951
|
+
}
|
|
952
|
+
function rangeForDecoratorIdentifier(identifier, marker) {
|
|
953
|
+
const range = rangeForIdentifier(identifier, "decorator");
|
|
954
|
+
if (marker === void 0 || marker.offset >= range.startOffset) return range;
|
|
955
|
+
return createPendingSemanticToken(marker.offset, range.endOffset, "decorator", range.modifierBitset);
|
|
956
|
+
}
|
|
957
|
+
function pendingTokenForToken(token, tokenType, modifierBitset = 0) {
|
|
958
|
+
return createPendingSemanticToken(token.offset, token.offset + token.text.length, tokenType, modifierBitset);
|
|
959
|
+
}
|
|
960
|
+
function mergeSourceOrderedTokens(left, right) {
|
|
961
|
+
const result = [];
|
|
962
|
+
let leftIndex = 0;
|
|
963
|
+
let rightIndex = 0;
|
|
964
|
+
while (leftIndex < left.length || rightIndex < right.length) {
|
|
965
|
+
const leftToken = left[leftIndex];
|
|
966
|
+
const rightToken = right[rightIndex];
|
|
967
|
+
if (leftToken !== void 0 && (rightToken === void 0 || leftToken.startOffset <= rightToken.startOffset)) {
|
|
968
|
+
result.push(leftToken);
|
|
969
|
+
leftIndex++;
|
|
970
|
+
} else if (rightToken !== void 0) {
|
|
971
|
+
result.push(rightToken);
|
|
972
|
+
rightIndex++;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
return result;
|
|
976
|
+
}
|
|
977
|
+
function createPendingSemanticToken(startOffset, endOffset, tokenType, modifierBitset = 0) {
|
|
978
|
+
return {
|
|
979
|
+
startOffset,
|
|
980
|
+
endOffset,
|
|
981
|
+
tokenTypeIndex: tokenTypeIndex(tokenType),
|
|
982
|
+
modifierBitset,
|
|
983
|
+
splitMultiline: tokenType === "string" || tokenType === "comment"
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
function tokenTypeIndex(tokenType) {
|
|
987
|
+
return semanticTokenTypes.indexOf(tokenType);
|
|
988
|
+
}
|
|
989
|
+
/** The project a new load of this config could fall back to. */
|
|
990
|
+
function lastGoodProject(entry) {
|
|
991
|
+
if (entry === void 0 || entry.status === "failed") return;
|
|
992
|
+
return entry.status === "loaded" ? entry.project : entry.lastGood;
|
|
993
|
+
}
|
|
994
|
+
const CONFIG_LOAD_FAILED_CODE = "PRISMA_NEXT_CONFIG_LOAD_FAILED";
|
|
995
|
+
const semanticTokenSourceLimit = 1e5;
|
|
996
|
+
function createServer(connection) {
|
|
997
|
+
const documents = new TextDocuments(TextDocument);
|
|
998
|
+
const managedProjects = /* @__PURE__ */ new Map();
|
|
999
|
+
const documentConfigPaths = /* @__PURE__ */ new Map();
|
|
1000
|
+
let rootPath = process.cwd();
|
|
1001
|
+
let watchedConfigGlob = join(rootPath, "**", CONFIG_FILENAME);
|
|
1002
|
+
let clientCapabilities = noClientCapabilities;
|
|
1003
|
+
let disposed = false;
|
|
1004
|
+
function sendDiagnostics(params) {
|
|
1005
|
+
if (disposed) return;
|
|
1006
|
+
connection.sendDiagnostics(params);
|
|
1007
|
+
}
|
|
1008
|
+
function logWarn(message) {
|
|
1009
|
+
if (disposed) return;
|
|
1010
|
+
connection.console.warn(message);
|
|
1011
|
+
}
|
|
1012
|
+
async function publish(uri) {
|
|
1013
|
+
const project = await resolveProjectForDocument(uri);
|
|
1014
|
+
if (project === void 0) return;
|
|
1015
|
+
if (documents.get(uri) === void 0) {
|
|
1016
|
+
documentConfigPaths.delete(uri);
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
const artifacts = project.artifacts.document(uri);
|
|
1020
|
+
if (artifacts === void 0) {
|
|
1021
|
+
sendDiagnostics({
|
|
1022
|
+
uri,
|
|
1023
|
+
diagnostics: []
|
|
1024
|
+
});
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
sendDiagnostics({
|
|
1028
|
+
uri,
|
|
1029
|
+
diagnostics: combinedDiagnostics(artifacts)
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
function combinedDiagnostics(artifacts) {
|
|
1033
|
+
return toDiagnostics([...artifacts.diagnostics, ...artifacts.interpretDiagnostics()]);
|
|
1034
|
+
}
|
|
1035
|
+
/**
|
|
1036
|
+
* Project-scoped so a future multi-input symbol table can attach
|
|
1037
|
+
* `relatedDocuments` for cross-file effects.
|
|
1038
|
+
*/
|
|
1039
|
+
function buildDocumentDiagnosticReport(project, uri) {
|
|
1040
|
+
const artifacts = project.artifacts.document(uri);
|
|
1041
|
+
return {
|
|
1042
|
+
kind: DocumentDiagnosticReportKind.Full,
|
|
1043
|
+
items: artifacts === void 0 ? [] : combinedDiagnostics(artifacts)
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
async function resolveProjectForDocument(uri) {
|
|
1047
|
+
const project = await projectForNearestConfig(uri);
|
|
1048
|
+
if (project === void 0 || project.inputs.includes(uri)) return project;
|
|
1049
|
+
documentConfigPaths.delete(uri);
|
|
1050
|
+
dropProjectWithoutManagedDocuments(project.configPath);
|
|
1051
|
+
}
|
|
1052
|
+
async function projectForNearestConfig(uri) {
|
|
1053
|
+
const knownConfigPath = documentConfigPaths.get(uri);
|
|
1054
|
+
if (knownConfigPath !== void 0) return resolveProjectIfLoadable(knownConfigPath);
|
|
1055
|
+
const filePath = filePathFromUri(uri);
|
|
1056
|
+
if (filePath === void 0) return;
|
|
1057
|
+
let configPath;
|
|
1058
|
+
try {
|
|
1059
|
+
configPath = await findNearestConfigPathForFile(filePath);
|
|
1060
|
+
} catch {
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
if (configPath === void 0) return;
|
|
1064
|
+
documentConfigPaths.set(uri, configPath);
|
|
1065
|
+
return resolveProjectIfLoadable(configPath);
|
|
1066
|
+
}
|
|
1067
|
+
async function resolveProjectIfLoadable(configPath) {
|
|
1068
|
+
try {
|
|
1069
|
+
return await resolveProject(configPath);
|
|
1070
|
+
} catch {
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
async function resolveProject(configPath) {
|
|
1075
|
+
const entry = managedProjects.get(configPath);
|
|
1076
|
+
if (entry === void 0 || entry.status === "failed") return startProjectLoad(configPath);
|
|
1077
|
+
return entry.status === "loaded" ? entry.project : entry.load;
|
|
1078
|
+
}
|
|
1079
|
+
function refreshProject(configPath) {
|
|
1080
|
+
return startProjectLoad(configPath);
|
|
1081
|
+
}
|
|
1082
|
+
function startProjectLoad(configPath) {
|
|
1083
|
+
const existing = managedProjects.get(configPath);
|
|
1084
|
+
const previousLoad = existing?.status === "loading" ? existing.load : void 0;
|
|
1085
|
+
const lastGood = lastGoodProject(existing);
|
|
1086
|
+
const load = (previousLoad ?? Promise.resolve(void 0)).catch(() => void 0).then(() => loadProject(configPath)).then((project) => {
|
|
1087
|
+
if (isCurrentLoad(configPath, load)) {
|
|
1088
|
+
if (hasManagedDocuments(configPath)) managedProjects.set(configPath, {
|
|
1089
|
+
status: "loaded",
|
|
1090
|
+
project
|
|
1091
|
+
});
|
|
1092
|
+
else managedProjects.delete(configPath);
|
|
1093
|
+
clearConfigFailure(configPath);
|
|
1094
|
+
}
|
|
1095
|
+
return project;
|
|
1096
|
+
}, (error) => {
|
|
1097
|
+
if (isCurrentLoad(configPath, load)) if (!hasManagedDocuments(configPath)) {
|
|
1098
|
+
managedProjects.delete(configPath);
|
|
1099
|
+
clearConfigFailure(configPath);
|
|
1100
|
+
} else {
|
|
1101
|
+
publishConfigFailure(configPath, error);
|
|
1102
|
+
if (lastGood !== void 0) {
|
|
1103
|
+
managedProjects.set(configPath, {
|
|
1104
|
+
status: "loaded",
|
|
1105
|
+
project: lastGood
|
|
1106
|
+
});
|
|
1107
|
+
return lastGood;
|
|
1108
|
+
}
|
|
1109
|
+
managedProjects.set(configPath, { status: "failed" });
|
|
1110
|
+
unmanageDocuments(configPath);
|
|
1111
|
+
}
|
|
1112
|
+
throw error;
|
|
1113
|
+
});
|
|
1114
|
+
managedProjects.set(configPath, {
|
|
1115
|
+
status: "loading",
|
|
1116
|
+
load,
|
|
1117
|
+
lastGood
|
|
1118
|
+
});
|
|
1119
|
+
return load;
|
|
1120
|
+
}
|
|
1121
|
+
function publishConfigFailure(configPath, error) {
|
|
1122
|
+
sendDiagnostics({
|
|
1123
|
+
uri: pathToFileURL(configPath).toString(),
|
|
1124
|
+
diagnostics: [{
|
|
1125
|
+
range: {
|
|
1126
|
+
start: {
|
|
1127
|
+
line: 0,
|
|
1128
|
+
character: 0
|
|
1129
|
+
},
|
|
1130
|
+
end: {
|
|
1131
|
+
line: 0,
|
|
1132
|
+
character: 1
|
|
1133
|
+
}
|
|
1134
|
+
},
|
|
1135
|
+
message: configFailureMessage(error),
|
|
1136
|
+
code: CONFIG_LOAD_FAILED_CODE,
|
|
1137
|
+
severity: DiagnosticSeverity.Error,
|
|
1138
|
+
source: "prisma-next"
|
|
1139
|
+
}]
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1142
|
+
function configFailureMessage(error) {
|
|
1143
|
+
if (CliStructuredError.is(error)) return error.why ?? error.message;
|
|
1144
|
+
return error instanceof Error ? error.message : String(error);
|
|
1145
|
+
}
|
|
1146
|
+
function clearConfigFailure(configPath) {
|
|
1147
|
+
sendDiagnostics({
|
|
1148
|
+
uri: pathToFileURL(configPath).toString(),
|
|
1149
|
+
diagnostics: []
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
function isCurrentLoad(configPath, load) {
|
|
1153
|
+
const entry = managedProjects.get(configPath);
|
|
1154
|
+
return entry?.status === "loading" && entry.load === load;
|
|
1155
|
+
}
|
|
1156
|
+
async function loadProject(configPath) {
|
|
1157
|
+
const resolution = await resolveConfigInputs(configPath);
|
|
1158
|
+
const artifacts = createProjectArtifacts({
|
|
1159
|
+
inputs: resolution.inputs,
|
|
1160
|
+
controlStack: resolution.controlStack,
|
|
1161
|
+
getText: (uri) => documents.get(uri)?.getText(),
|
|
1162
|
+
...resolution.interpretation === void 0 ? {} : { interpretation: resolution.interpretation }
|
|
1163
|
+
});
|
|
1164
|
+
return {
|
|
1165
|
+
configPath,
|
|
1166
|
+
inputs: resolution.inputs,
|
|
1167
|
+
controlStack: resolution.controlStack,
|
|
1168
|
+
artifacts,
|
|
1169
|
+
...resolution.formatter === void 0 ? {} : { formatter: resolution.formatter },
|
|
1170
|
+
...resolution.interpretation === void 0 ? {} : { interpretation: resolution.interpretation }
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
function unmanageDocuments(configPath) {
|
|
1174
|
+
for (const document of documents.all()) if (documentConfigPaths.get(document.uri) === configPath) documentConfigPaths.delete(document.uri);
|
|
1175
|
+
}
|
|
1176
|
+
async function republishOpenDocumentsForConfig(configPath) {
|
|
1177
|
+
for (const document of documents.all()) {
|
|
1178
|
+
if (documentConfigPaths.get(document.uri) === configPath) {
|
|
1179
|
+
if (await resolveProjectForDocument(document.uri) === void 0) {
|
|
1180
|
+
sendDiagnostics({
|
|
1181
|
+
uri: document.uri,
|
|
1182
|
+
diagnostics: []
|
|
1183
|
+
});
|
|
1184
|
+
continue;
|
|
1185
|
+
}
|
|
1186
|
+
await publish(document.uri);
|
|
1187
|
+
continue;
|
|
1188
|
+
}
|
|
1189
|
+
const filePath = filePathFromUri(document.uri);
|
|
1190
|
+
if (filePath === void 0) continue;
|
|
1191
|
+
if (await findNearestConfigPathForFile(filePath) === configPath) {
|
|
1192
|
+
documentConfigPaths.set(document.uri, configPath);
|
|
1193
|
+
await publish(document.uri);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
function publishSafely(uri) {
|
|
1198
|
+
publish(uri).catch((error) => {
|
|
1199
|
+
if (disposed) return;
|
|
1200
|
+
try {
|
|
1201
|
+
connection.console.error(error instanceof Error ? error.message : String(error));
|
|
1202
|
+
} catch {}
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
async function formatDocument(uri) {
|
|
1206
|
+
const document = documents.get(uri);
|
|
1207
|
+
if (document === void 0) return [];
|
|
1208
|
+
const project = await resolveProjectForDocument(uri);
|
|
1209
|
+
if (project === void 0) return [];
|
|
1210
|
+
const source = document.getText();
|
|
1211
|
+
let formatted;
|
|
1212
|
+
try {
|
|
1213
|
+
formatted = format(source, project.formatter);
|
|
1214
|
+
} catch {
|
|
1215
|
+
return [];
|
|
1216
|
+
}
|
|
1217
|
+
if (formatted === source) return [];
|
|
1218
|
+
return [{
|
|
1219
|
+
range: {
|
|
1220
|
+
start: {
|
|
1221
|
+
line: 0,
|
|
1222
|
+
character: 0
|
|
1223
|
+
},
|
|
1224
|
+
end: document.positionAt(source.length)
|
|
1225
|
+
},
|
|
1226
|
+
newText: formatted
|
|
1227
|
+
}];
|
|
1228
|
+
}
|
|
1229
|
+
async function semanticTokensForDocument(uri, range) {
|
|
1230
|
+
const document = documents.get(uri);
|
|
1231
|
+
if (document === void 0) return emptySemanticTokens();
|
|
1232
|
+
if (document.getText().length > semanticTokenSourceLimit) return emptySemanticTokens();
|
|
1233
|
+
const project = await resolveProjectForDocument(uri);
|
|
1234
|
+
if (project === void 0) return emptySemanticTokens();
|
|
1235
|
+
const artifacts = project.artifacts.document(uri);
|
|
1236
|
+
if (artifacts === void 0) return emptySemanticTokens();
|
|
1237
|
+
return buildSemanticTokens({
|
|
1238
|
+
document: artifacts.document,
|
|
1239
|
+
sourceFile: artifacts.sourceFile,
|
|
1240
|
+
symbolTable: project.artifacts.symbolTable(),
|
|
1241
|
+
scalarTypes: project.controlStack.scalarTypes
|
|
1242
|
+
}, range);
|
|
1243
|
+
}
|
|
1244
|
+
async function completeDocument(uri, position) {
|
|
1245
|
+
if (documents.get(uri) === void 0) return [];
|
|
1246
|
+
const project = await resolveProjectForDocument(uri);
|
|
1247
|
+
if (project === void 0) return [];
|
|
1248
|
+
const artifacts = project.artifacts.document(uri);
|
|
1249
|
+
if (artifacts === void 0) return [];
|
|
1250
|
+
try {
|
|
1251
|
+
return [...providePslCompletionItems({
|
|
1252
|
+
context: classifyPslCompletionContext({
|
|
1253
|
+
document: artifacts.document,
|
|
1254
|
+
sourceFile: artifacts.sourceFile,
|
|
1255
|
+
position
|
|
1256
|
+
}),
|
|
1257
|
+
sourceFile: artifacts.sourceFile,
|
|
1258
|
+
candidates: {
|
|
1259
|
+
scalarTypes: project.controlStack.scalarTypes,
|
|
1260
|
+
pslBlockDescriptors: project.controlStack.pslBlockDescriptors,
|
|
1261
|
+
symbolTable: project.artifacts.symbolTable()
|
|
1262
|
+
},
|
|
1263
|
+
clientSupportsSnippets: clientCapabilities.completionSnippets
|
|
1264
|
+
})];
|
|
1265
|
+
} catch {
|
|
1266
|
+
return [];
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
connection.onInitialize(async (params) => {
|
|
1270
|
+
rootPath = resolveRootPath(params);
|
|
1271
|
+
watchedConfigGlob = join(rootPath, "**", CONFIG_FILENAME);
|
|
1272
|
+
clientCapabilities = resolveClientCapabilities(params);
|
|
1273
|
+
return { capabilities: {
|
|
1274
|
+
textDocumentSync: TextDocumentSyncKind.Incremental,
|
|
1275
|
+
documentFormattingProvider: true,
|
|
1276
|
+
foldingRangeProvider: true,
|
|
1277
|
+
semanticTokensProvider: {
|
|
1278
|
+
legend: semanticTokensLegend,
|
|
1279
|
+
full: true,
|
|
1280
|
+
range: true
|
|
1281
|
+
},
|
|
1282
|
+
completionProvider: { triggerCharacters: ["."] },
|
|
1283
|
+
...clientCapabilities.pullDiagnostics ? { diagnosticProvider: {
|
|
1284
|
+
interFileDependencies: false,
|
|
1285
|
+
workspaceDiagnostics: false
|
|
1286
|
+
} } : {}
|
|
1287
|
+
} };
|
|
1288
|
+
});
|
|
1289
|
+
connection.onInitialized(() => {
|
|
1290
|
+
if (clientCapabilities.watchedFilesRegistration) connection.sendRequest(RegistrationRequest.type, { registrations: [{
|
|
1291
|
+
id: "prisma-8-config-watcher",
|
|
1292
|
+
method: DidChangeWatchedFilesNotification.type.method,
|
|
1293
|
+
registerOptions: { watchers: [{ globPattern: watchedConfigGlob }] }
|
|
1294
|
+
}] }).catch(() => void 0);
|
|
1295
|
+
else logWarn("Client does not support dynamic file-watcher registration; Prisma Next config changes will not be picked up without a restart.");
|
|
1296
|
+
});
|
|
1297
|
+
connection.onDidChangeWatchedFiles(async (params) => {
|
|
1298
|
+
const changedConfigPaths = configPathsFromWatchedChanges(params.changes.map((change) => filePathFromUri(change.uri)));
|
|
1299
|
+
for (const configPath of changedConfigPaths) {
|
|
1300
|
+
if (managedProjects.has(configPath)) try {
|
|
1301
|
+
await refreshProject(configPath);
|
|
1302
|
+
} catch {
|
|
1303
|
+
continue;
|
|
1304
|
+
}
|
|
1305
|
+
if (!clientCapabilities.pullDiagnostics) await republishOpenDocumentsForConfig(configPath);
|
|
1306
|
+
}
|
|
1307
|
+
if (clientCapabilities.pullDiagnostics && clientCapabilities.diagnosticsRefresh && changedConfigPaths.size > 0 && !disposed) connection.languages.diagnostics.refresh().catch(() => void 0);
|
|
1308
|
+
});
|
|
1309
|
+
connection.onDocumentFormatting((params) => formatDocument(params.textDocument.uri));
|
|
1310
|
+
connection.onCompletion((params) => completeDocument(params.textDocument.uri, params.position));
|
|
1311
|
+
connection.languages.semanticTokens.on((params) => semanticTokensForDocument(params.textDocument.uri));
|
|
1312
|
+
connection.languages.semanticTokens.onRange((params) => semanticTokensForDocument(params.textDocument.uri, params.range));
|
|
1313
|
+
connection.languages.diagnostics.on(async (params) => {
|
|
1314
|
+
const project = await resolveProjectForDocument(params.textDocument.uri);
|
|
1315
|
+
if (project === void 0) return {
|
|
1316
|
+
kind: DocumentDiagnosticReportKind.Full,
|
|
1317
|
+
items: []
|
|
1318
|
+
};
|
|
1319
|
+
return buildDocumentDiagnosticReport(project, params.textDocument.uri);
|
|
1320
|
+
});
|
|
1321
|
+
connection.onFoldingRanges(async (params) => {
|
|
1322
|
+
const project = await resolveProjectForDocument(params.textDocument.uri);
|
|
1323
|
+
if (project === void 0) return [];
|
|
1324
|
+
const artifacts = project.artifacts.document(params.textDocument.uri);
|
|
1325
|
+
if (artifacts === void 0) return [];
|
|
1326
|
+
return computeFoldingRanges(artifacts.document, artifacts.sourceFile);
|
|
1327
|
+
});
|
|
1328
|
+
documents.onDidOpen((event) => {
|
|
1329
|
+
artifactsForDocument(event.document.uri)?.documentChanged(event.document.uri);
|
|
1330
|
+
if (clientCapabilities.pullDiagnostics) return;
|
|
1331
|
+
publishSafely(event.document.uri);
|
|
1332
|
+
});
|
|
1333
|
+
documents.onDidChangeContent((event) => {
|
|
1334
|
+
artifactsForDocument(event.document.uri)?.documentChanged(event.document.uri);
|
|
1335
|
+
if (clientCapabilities.pullDiagnostics) return;
|
|
1336
|
+
publishSafely(event.document.uri);
|
|
1337
|
+
});
|
|
1338
|
+
documents.onDidClose((event) => {
|
|
1339
|
+
const uri = event.document.uri;
|
|
1340
|
+
const configPath = documentConfigPaths.get(uri);
|
|
1341
|
+
artifactsForDocument(uri)?.documentClosed(uri);
|
|
1342
|
+
documentConfigPaths.delete(uri);
|
|
1343
|
+
if (configPath !== void 0) dropProjectWithoutManagedDocuments(configPath);
|
|
1344
|
+
if (!clientCapabilities.pullDiagnostics) sendDiagnostics({
|
|
1345
|
+
uri,
|
|
1346
|
+
diagnostics: []
|
|
1347
|
+
});
|
|
1348
|
+
});
|
|
1349
|
+
documents.listen(connection);
|
|
1350
|
+
connection.listen();
|
|
1351
|
+
function artifactsForDocument(uri) {
|
|
1352
|
+
const configPath = documentConfigPaths.get(uri);
|
|
1353
|
+
if (configPath === void 0) return;
|
|
1354
|
+
const entry = managedProjects.get(configPath);
|
|
1355
|
+
return entry?.status === "loaded" ? entry.project.artifacts : void 0;
|
|
1356
|
+
}
|
|
1357
|
+
function hasManagedDocuments(configPath) {
|
|
1358
|
+
for (const managedConfigPath of documentConfigPaths.values()) if (managedConfigPath === configPath) return true;
|
|
1359
|
+
return false;
|
|
1360
|
+
}
|
|
1361
|
+
function dropProjectWithoutManagedDocuments(configPath) {
|
|
1362
|
+
if (hasManagedDocuments(configPath)) return;
|
|
1363
|
+
const entry = managedProjects.get(configPath);
|
|
1364
|
+
if (entry === void 0 || entry.status === "loading") return;
|
|
1365
|
+
managedProjects.delete(configPath);
|
|
1366
|
+
clearConfigFailure(configPath);
|
|
1367
|
+
}
|
|
1368
|
+
return {
|
|
1369
|
+
dispose: () => {
|
|
1370
|
+
disposed = true;
|
|
1371
|
+
connection.dispose();
|
|
1372
|
+
},
|
|
1373
|
+
getDocumentAst: (uri) => artifactsForDocument(uri)?.document(uri),
|
|
1374
|
+
getProjectSymbolTable: (uri) => artifactsForDocument(uri)?.symbolTable()
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
function emptySemanticTokens() {
|
|
1378
|
+
return { data: [] };
|
|
1379
|
+
}
|
|
1380
|
+
function toDiagnostics(computed) {
|
|
1381
|
+
return computed.map((diagnostic) => ({
|
|
1382
|
+
range: diagnostic.range,
|
|
1383
|
+
message: diagnostic.message,
|
|
1384
|
+
code: diagnostic.code,
|
|
1385
|
+
severity: toLspSeverity(diagnostic.severity),
|
|
1386
|
+
source: "prisma-next"
|
|
1387
|
+
}));
|
|
1388
|
+
}
|
|
1389
|
+
function toLspSeverity(severity) {
|
|
1390
|
+
switch (severity) {
|
|
1391
|
+
case ParseDiagnosticSeverity.Warning: return DiagnosticSeverity.Warning;
|
|
1392
|
+
case ParseDiagnosticSeverity.Information: return DiagnosticSeverity.Information;
|
|
1393
|
+
case ParseDiagnosticSeverity.Hint: return DiagnosticSeverity.Hint;
|
|
1394
|
+
default: return DiagnosticSeverity.Error;
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
const noClientCapabilities = {
|
|
1398
|
+
watchedFilesRegistration: false,
|
|
1399
|
+
completionSnippets: false,
|
|
1400
|
+
pullDiagnostics: false,
|
|
1401
|
+
diagnosticsRefresh: false
|
|
1402
|
+
};
|
|
1403
|
+
function resolveClientCapabilities(params) {
|
|
1404
|
+
return {
|
|
1405
|
+
watchedFilesRegistration: params.capabilities.workspace?.didChangeWatchedFiles?.dynamicRegistration === true,
|
|
1406
|
+
completionSnippets: params.capabilities.textDocument?.completion?.completionItem?.snippetSupport === true,
|
|
1407
|
+
pullDiagnostics: params.capabilities.textDocument?.diagnostic !== void 0,
|
|
1408
|
+
diagnosticsRefresh: params.capabilities.workspace?.diagnostics?.refreshSupport === true
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
function resolveRootPath(params) {
|
|
1412
|
+
const workspaceFolder = params.workspaceFolders?.[0];
|
|
1413
|
+
if (workspaceFolder !== void 0) return fileURLToPath(workspaceFolder.uri);
|
|
1414
|
+
if (params.rootUri) return fileURLToPath(params.rootUri);
|
|
1415
|
+
if (params.rootPath) return params.rootPath;
|
|
1416
|
+
return process.cwd();
|
|
1417
|
+
}
|
|
1418
|
+
function filePathFromUri(uri) {
|
|
1419
|
+
try {
|
|
1420
|
+
return fileURLToPath(uri);
|
|
1421
|
+
} catch {
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
function configPathsFromWatchedChanges(paths) {
|
|
1426
|
+
const configPaths = /* @__PURE__ */ new Set();
|
|
1427
|
+
for (const path of paths) if (path?.endsWith("prisma-next.config.ts")) configPaths.add(path);
|
|
1428
|
+
return configPaths;
|
|
1429
|
+
}
|
|
1430
|
+
function startServer() {
|
|
1431
|
+
return createServer(createConnection(ProposedFeatures.all));
|
|
1432
|
+
}
|
|
1433
|
+
//#endregion
|
|
1434
|
+
export { startServer };
|
|
1435
|
+
|
|
1436
|
+
//# sourceMappingURL=exports-B_xhKZmC.mjs.map
|