@prisma/orm-toolchain 8.0.0-rc.1-dev.45 → 8.0.0-rc.1-dev.46
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 +3 -3
- package/dist/{aggregate-BBsCbXgJ.mjs → aggregate-CPZB020V.mjs} +9 -9
- package/dist/{aggregate-BBsCbXgJ.mjs.map → aggregate-CPZB020V.mjs.map} +1 -1
- package/dist/{aggregate-CA6bJ8UO.d.mts → aggregate-DLUJLq5Y.d.mts} +3 -3
- package/dist/{aggregate-CA6bJ8UO.d.mts.map → aggregate-DLUJLq5Y.d.mts.map} +1 -1
- package/dist/cli-telemetry.d.mts +19 -5
- package/dist/cli-telemetry.d.mts.map +1 -1
- package/dist/cli-telemetry.mjs +287 -8
- package/dist/cli-telemetry.mjs.map +1 -1
- package/dist/cli.d.mts +11 -13
- package/dist/cli.d.mts.map +1 -1
- package/dist/cli.mjs +5382 -1095
- package/dist/cli.mjs.map +1 -1
- package/dist/cli__control-api.d.mts +298 -27
- package/dist/cli__control-api.d.mts.map +1 -1
- package/dist/cli__control-api.mjs +2 -19
- package/dist/cli__control-api__testing.d.mts +1 -1
- package/dist/cli__control-api__testing.mjs.map +1 -1
- package/dist/cli__init-output.d.mts +0 -1
- package/dist/cli__init-output.d.mts.map +1 -1
- package/dist/cli__init-output.mjs +1 -1
- package/dist/cli__migration-cli.mjs +9 -9
- package/dist/cli__migration-cli.mjs.map +1 -1
- package/dist/config-loader.d.mts +1 -1
- package/dist/config-loader.mjs +1 -1
- package/dist/{contract-snapshot-store-B0G1Fw_F-C4JjmWEA.mjs → contract-snapshot-store-B0G1Fw_F-CHc4QfKb.mjs} +4 -4
- package/dist/{contract-snapshot-store-B0G1Fw_F-C4JjmWEA.mjs.map → contract-snapshot-store-B0G1Fw_F-CHc4QfKb.mjs.map} +1 -1
- package/dist/{cli-errors-iquUoY6O-BFboxglv.d.mts → db-verify-BwgNK50T-DGvKgFCK.d.mts} +81 -81
- package/dist/db-verify-BwgNK50T-DGvKgFCK.d.mts.map +1 -0
- package/dist/emitter.d.mts +1 -1
- package/dist/{errors-CXbGUWGu-BQi6YS-H.mjs → errors-CXbGUWGu-CstQHPh6.mjs} +2 -2
- package/dist/{errors-CXbGUWGu-BQi6YS-H.mjs.map → errors-CXbGUWGu-CstQHPh6.mjs.map} +1 -1
- package/dist/{errors-KWM8yBAL.d.mts → errors-D59OCpoI.d.mts} +2 -2
- package/dist/{errors-KWM8yBAL.d.mts.map → errors-D59OCpoI.d.mts.map} +1 -1
- package/dist/{exports-B3xY_FHp.mjs → exports-8ZUN43ve.mjs} +6 -6
- package/dist/exports-8ZUN43ve.mjs.map +1 -0
- package/dist/{exports-BZLNbtkY.mjs → exports-BZaG8_w_.mjs} +64 -36
- package/dist/exports-BZaG8_w_.mjs.map +1 -0
- package/dist/{graph-membership-BViWUMpP-Cgu4Z2ox.mjs → graph-membership-BViWUMpP-C4lYYJdU.mjs} +2 -2
- package/dist/{graph-membership-BViWUMpP-Cgu4Z2ox.mjs.map → graph-membership-BViWUMpP-C4lYYJdU.mjs.map} +1 -1
- package/dist/{import-roots-NDOIEDVj.mjs → import-roots-CNFBPAT1.mjs} +10 -3
- package/dist/{import-roots-NDOIEDVj.mjs.map → import-roots-CNFBPAT1.mjs.map} +1 -1
- package/dist/{import-roots-B6CtsWXb.d.mts → import-roots-CfoYgejL.d.mts} +2 -2
- package/dist/{import-roots-B6CtsWXb.d.mts.map → import-roots-CfoYgejL.d.mts.map} +1 -1
- package/dist/{index-mCsi_ND5.d.mts → index-DRs7L6N0.d.mts} +11 -3
- package/dist/index-DRs7L6N0.d.mts.map +1 -0
- package/dist/{index-CnOyYxmv.d.mts → index-Dgwl8Tzs.d.mts} +2 -2
- package/dist/{index-CnOyYxmv.d.mts.map → index-Dgwl8Tzs.d.mts.map} +1 -1
- package/dist/{invariants-CTHy88OP-DJ-i5yTz.mjs → invariants-CTHy88OP-CYI2a8IO.mjs} +2 -2
- package/dist/{invariants-CTHy88OP-DJ-i5yTz.mjs.map → invariants-CTHy88OP-CYI2a8IO.mjs.map} +1 -1
- package/dist/{io-635GlNx1-D94PxRc-.mjs → io-635GlNx1-D3zrw2qu.mjs} +4 -4
- package/dist/{io-635GlNx1-D94PxRc-.mjs.map → io-635GlNx1-D3zrw2qu.mjs.map} +1 -1
- package/dist/{migration-graph-_SJImD5V-D5RCc651.mjs → migration-graph-_SJImD5V-BURyY1KM.mjs} +2 -2
- package/dist/{migration-graph-_SJImD5V-D5RCc651.mjs.map → migration-graph-_SJImD5V-BURyY1KM.mjs.map} +1 -1
- package/dist/{migration-gubSSeMk.mjs → migration-hspPIEeV.mjs} +4 -4
- package/dist/{migration-gubSSeMk.mjs.map → migration-hspPIEeV.mjs.map} +1 -1
- package/dist/migration-tools.d.mts +4 -4
- package/dist/migration-tools.mjs +13 -13
- package/dist/migration-tools__aggregate.d.mts +1 -1
- package/dist/migration-tools__aggregate.mjs +1 -1
- package/dist/migration-tools__contract-snapshot-store.mjs +1 -1
- package/dist/migration-tools__errors.d.mts +1 -1
- package/dist/migration-tools__errors.mjs +1 -1
- package/dist/migration-tools__invariants.mjs +1 -1
- package/dist/migration-tools__io.mjs +1 -1
- package/dist/migration-tools__migration-graph.mjs +2 -2
- package/dist/migration-tools__migration-ts.mjs +1 -1
- package/dist/migration-tools__migration.mjs +1 -1
- package/dist/migration-tools__ref-resolution.mjs +1 -1
- package/dist/migration-tools__refs.mjs +1 -1
- package/dist/migration-tools__spaces.d.mts +2 -2
- package/dist/migration-tools__spaces.mjs +2 -2
- package/dist/{migration-ts-BoHxxGvi.mjs → migration-ts-DdVm0rws.mjs} +2 -2
- package/dist/{migration-ts-BoHxxGvi.mjs.map → migration-ts-DdVm0rws.mjs.map} +1 -1
- package/dist/{output-DP3woAjV-BxCr9nHA.mjs → output-CovTDY14-CUoAqLML.mjs} +3 -45
- package/dist/output-CovTDY14-CUoAqLML.mjs.map +1 -0
- package/dist/publish-surface.d.mts +2 -2
- package/dist/publish-surface.mjs +2 -2
- package/dist/publish-surface__import-roots.d.mts +1 -1
- package/dist/publish-surface__import-roots.mjs +1 -1
- package/dist/publish-surface__shells.d.mts +1 -1
- package/dist/publish-surface__shells.mjs +1 -1
- package/dist/quick-reference-mongo.md +12 -9
- package/dist/quick-reference-postgres.md +12 -9
- package/dist/readme-mongo.md +2 -2
- package/dist/readme-postgres.md +2 -2
- package/dist/ref-h6InR6dO-rGfl18Jv.mjs +4686 -0
- package/dist/ref-h6InR6dO-rGfl18Jv.mjs.map +1 -0
- package/dist/{ref-resolution-sGcINe7o.mjs → ref-resolution-HeNBXW53.mjs} +2 -2
- package/dist/{ref-resolution-sGcINe7o.mjs.map → ref-resolution-HeNBXW53.mjs.map} +1 -1
- package/dist/{refs-WK86uYYp-B6EZkmmT.mjs → refs-WK86uYYp-gM8tvWQP.mjs} +2 -2
- package/dist/{refs-WK86uYYp-B6EZkmmT.mjs.map → refs-WK86uYYp-gM8tvWQP.mjs.map} +1 -1
- package/dist/{shells-BenrJHp2.mjs → shells-C4HbRAr5.mjs} +13 -14
- package/dist/shells-C4HbRAr5.mjs.map +1 -0
- package/dist/{shells-COHV_Ozf.d.mts → shells-CIUmT4u4.d.mts} +14 -20
- package/dist/shells-CIUmT4u4.d.mts.map +1 -0
- package/dist/{spaces-BG2w0P8d.mjs → spaces-4qMOAYE9.mjs} +7 -7
- package/dist/{spaces-BG2w0P8d.mjs.map → spaces-4qMOAYE9.mjs.map} +1 -1
- package/dist/{spaces-tWQi7CUv.d.mts → spaces-Dj65JrwZ.d.mts} +2 -2
- package/dist/{spaces-tWQi7CUv.d.mts.map → spaces-Dj65JrwZ.d.mts.map} +1 -1
- package/dist/{verify-contract-spaces-Cc1u_wJo-BilPJS2S.d.mts → verify-contract-spaces-C3PiFBk3-DfomYyOE.d.mts} +3 -3
- package/dist/{verify-contract-spaces-Cc1u_wJo-BilPJS2S.d.mts.map → verify-contract-spaces-C3PiFBk3-DfomYyOE.d.mts.map} +1 -1
- package/dist/{verify-contract-spaces-DhJTb0zM-_oh6W6lp.mjs → verify-contract-spaces-DhJTb0zM-B62maCfE.mjs} +4 -4
- package/dist/{verify-contract-spaces-DhJTb0zM-_oh6W6lp.mjs.map → verify-contract-spaces-DhJTb0zM-B62maCfE.mjs.map} +1 -1
- package/dist/vite-plugin-contract-emit.d.mts +2 -2
- package/dist/vite-plugin-contract-emit.mjs +5 -5
- package/dist/vite-plugin-contract-emit.mjs.map +1 -1
- package/package.json +14 -38
- package/dist/bin__prisma-next.mjs +0 -512
- package/dist/bin__prisma-next.mjs.map +0 -1
- package/dist/caught-errors-BZo7zcRc-C-pIEasG.mjs +0 -14
- package/dist/caught-errors-BZo7zcRc-C-pIEasG.mjs.map +0 -1
- package/dist/cli-errors-B4zTLaqQ-CXgjO9t4.mjs +0 -347
- package/dist/cli-errors-B4zTLaqQ-CXgjO9t4.mjs.map +0 -1
- package/dist/cli-errors-iquUoY6O-BFboxglv.d.mts.map +0 -1
- package/dist/cli__commands__contract-emit.d.mts +0 -2
- package/dist/cli__commands__contract-emit.mjs +0 -2
- package/dist/cli__commands__contract-infer.d.mts +0 -7
- package/dist/cli__commands__contract-infer.d.mts.map +0 -1
- package/dist/cli__commands__contract-infer.mjs +0 -2
- package/dist/cli__commands__db-init.d.mts +0 -7
- package/dist/cli__commands__db-init.d.mts.map +0 -1
- package/dist/cli__commands__db-init.mjs +0 -2
- package/dist/cli__commands__db-schema.d.mts +0 -7
- package/dist/cli__commands__db-schema.d.mts.map +0 -1
- package/dist/cli__commands__db-schema.mjs +0 -2
- package/dist/cli__commands__db-sign.d.mts +0 -7
- package/dist/cli__commands__db-sign.d.mts.map +0 -1
- package/dist/cli__commands__db-sign.mjs +0 -2
- package/dist/cli__commands__db-update.d.mts +0 -7
- package/dist/cli__commands__db-update.d.mts.map +0 -1
- package/dist/cli__commands__db-update.mjs +0 -2
- package/dist/cli__commands__db-verify.d.mts +0 -7
- package/dist/cli__commands__db-verify.d.mts.map +0 -1
- package/dist/cli__commands__db-verify.mjs +0 -2
- package/dist/cli__commands__migrate.d.mts +0 -57
- package/dist/cli__commands__migrate.d.mts.map +0 -1
- package/dist/cli__commands__migrate.mjs +0 -2
- package/dist/cli__commands__migration-check.d.mts +0 -8
- package/dist/cli__commands__migration-check.d.mts.map +0 -1
- package/dist/cli__commands__migration-check.mjs +0 -3
- package/dist/cli__commands__migration-graph.d.mts +0 -38
- package/dist/cli__commands__migration-graph.d.mts.map +0 -1
- package/dist/cli__commands__migration-graph.mjs +0 -2
- package/dist/cli__commands__migration-list.d.mts +0 -39
- package/dist/cli__commands__migration-list.d.mts.map +0 -1
- package/dist/cli__commands__migration-list.mjs +0 -2
- package/dist/cli__commands__migration-log.d.mts +0 -20
- package/dist/cli__commands__migration-log.d.mts.map +0 -1
- package/dist/cli__commands__migration-log.mjs +0 -2
- package/dist/cli__commands__migration-new.d.mts +0 -7
- package/dist/cli__commands__migration-new.d.mts.map +0 -1
- package/dist/cli__commands__migration-new.mjs +0 -2
- package/dist/cli__commands__migration-plan.d.mts +0 -34
- package/dist/cli__commands__migration-plan.d.mts.map +0 -1
- package/dist/cli__commands__migration-plan.mjs +0 -2
- package/dist/cli__commands__migration-show.d.mts +0 -27
- package/dist/cli__commands__migration-show.d.mts.map +0 -1
- package/dist/cli__commands__migration-show.mjs +0 -2
- package/dist/cli__commands__migration-status.d.mts +0 -55
- package/dist/cli__commands__migration-status.d.mts.map +0 -1
- package/dist/cli__commands__migration-status.mjs +0 -3
- package/dist/cli__commands__ref.d.mts +0 -7
- package/dist/cli__commands__ref.d.mts.map +0 -1
- package/dist/cli__commands__ref.mjs +0 -2
- package/dist/cli__commands__telemetry.d.mts +0 -7
- package/dist/cli__commands__telemetry.d.mts.map +0 -1
- package/dist/cli__commands__telemetry.mjs +0 -2
- package/dist/client-C6Qp5ujC-Dxb7r79B.mjs +0 -1653
- package/dist/client-C6Qp5ujC-Dxb7r79B.mjs.map +0 -1
- package/dist/code-templates-C-jirr19-DDQB0WGo.mjs +0 -295
- package/dist/code-templates-C-jirr19-DDQB0WGo.mjs.map +0 -1
- package/dist/combine-verify-results-B87B_pMc-D4l22OqY.mjs +0 -65
- package/dist/combine-verify-results-B87B_pMc-D4l22OqY.mjs.map +0 -1
- package/dist/command-helpers-BCgwcqTe-lNCtppzM.mjs +0 -776
- package/dist/command-helpers-BCgwcqTe-lNCtppzM.mjs.map +0 -1
- package/dist/contract-at-errors-BSoDI0Hw-BXeUNE3s.mjs +0 -44
- package/dist/contract-at-errors-BSoDI0Hw-BXeUNE3s.mjs.map +0 -1
- package/dist/contract-emit-BG7KL4zk-_a0J310Z.mjs +0 -331
- package/dist/contract-emit-BG7KL4zk-_a0J310Z.mjs.map +0 -1
- package/dist/contract-emit-BkEj3siG-C8M-IyvS.mjs +0 -2
- package/dist/contract-emit-CvwNE4R1-DEn1V1Zo.d.mts +0 -7
- package/dist/contract-emit-CvwNE4R1-DEn1V1Zo.d.mts.map +0 -1
- package/dist/contract-emit-GknCmgn_-BSWdFprC.mjs +0 -154
- package/dist/contract-emit-GknCmgn_-BSWdFprC.mjs.map +0 -1
- package/dist/contract-enrichment-DrMvvY2A-DxNGeF4d.mjs +0 -56
- package/dist/contract-enrichment-DrMvvY2A-DxNGeF4d.mjs.map +0 -1
- package/dist/contract-infer-BwIDGl7v-CZrdWXAr.mjs +0 -74
- package/dist/contract-infer-BwIDGl7v-CZrdWXAr.mjs.map +0 -1
- package/dist/contract-snapshot-resolution-De2VvOJn-DqIAV9cr.mjs +0 -82
- package/dist/contract-snapshot-resolution-De2VvOJn-DqIAV9cr.mjs.map +0 -1
- package/dist/contract-space-aggregate-loader-fa04OIaL-B7LXHle3.mjs +0 -303
- package/dist/contract-space-aggregate-loader-fa04OIaL-B7LXHle3.mjs.map +0 -1
- package/dist/db-init-BolXrKAI-CwG-zEDW.mjs +0 -109
- package/dist/db-init-BolXrKAI-CwG-zEDW.mjs.map +0 -1
- package/dist/db-init-failure-B5cQML4A-5zr-99Ek.mjs +0 -44
- package/dist/db-init-failure-B5cQML4A-5zr-99Ek.mjs.map +0 -1
- package/dist/db-schema-DvdLBdEY-Dl6e1d_Y.mjs +0 -48
- package/dist/db-schema-DvdLBdEY-Dl6e1d_Y.mjs.map +0 -1
- package/dist/db-sign-DCp4c8CA-B3tun-kh.mjs +0 -172
- package/dist/db-sign-DCp4c8CA-B3tun-kh.mjs.map +0 -1
- package/dist/db-update-CfayE8WE-CPhQyDaZ.mjs +0 -171
- package/dist/db-update-CfayE8WE-CPhQyDaZ.mjs.map +0 -1
- package/dist/db-verify-BN7IrOAL-kEzRNJUl.mjs +0 -358
- package/dist/db-verify-BN7IrOAL-kEzRNJUl.mjs.map +0 -1
- package/dist/exports-B3xY_FHp.mjs.map +0 -1
- package/dist/exports-BZLNbtkY.mjs.map +0 -1
- package/dist/exports-CqNUihkI.mjs +0 -276
- package/dist/exports-CqNUihkI.mjs.map +0 -1
- package/dist/format-Ca7dUE6B-BMFqrc6D.mjs +0 -110
- package/dist/format-Ca7dUE6B-BMFqrc6D.mjs.map +0 -1
- package/dist/framework-components-Bau7o1-J-DTp6AUoq.mjs +0 -60
- package/dist/framework-components-Bau7o1-J-DTp6AUoq.mjs.map +0 -1
- package/dist/global-flags-BpoOYtNZ-CHZD3fud.d.mts +0 -35
- package/dist/global-flags-BpoOYtNZ-CHZD3fud.d.mts.map +0 -1
- package/dist/index-mCsi_ND5.d.mts.map +0 -1
- package/dist/init-DC7zPKka-BSiUrPw3.mjs +0 -800
- package/dist/init-DC7zPKka-BSiUrPw3.mjs.map +0 -1
- package/dist/inspect-live-schema-BPHXdvqW-DrzL2ZkQ.mjs +0 -95
- package/dist/inspect-live-schema-BPHXdvqW-DrzL2ZkQ.mjs.map +0 -1
- package/dist/integrity-violation-to-check-failure-BmWMLAae-DqiC4_3p.mjs +0 -115
- package/dist/integrity-violation-to-check-failure-BmWMLAae-DqiC4_3p.mjs.map +0 -1
- package/dist/invariants-Bltd8DyA-Cg_1Lu0q.mjs +0 -53
- package/dist/invariants-Bltd8DyA-Cg_1Lu0q.mjs.map +0 -1
- package/dist/legend-DGv9e2_0-BtetgRz4.mjs +0 -22
- package/dist/legend-DGv9e2_0-BtetgRz4.mjs.map +0 -1
- package/dist/migrate-BXATUjYE-Do79Imf-.mjs +0 -343
- package/dist/migrate-BXATUjYE-Do79Imf-.mjs.map +0 -1
- package/dist/migrate-failure-D4NvkoCk-0bttmQs2.mjs +0 -96
- package/dist/migrate-failure-D4NvkoCk-0bttmQs2.mjs.map +0 -1
- package/dist/migrate-show-B8UJ9dmb-C4RTPbDk.d.mts +0 -63
- package/dist/migrate-show-B8UJ9dmb-C4RTPbDk.d.mts.map +0 -1
- package/dist/migrate-show-C_9xR4Qt-B-Y0PGKw.mjs +0 -199
- package/dist/migrate-show-C_9xR4Qt-B-Y0PGKw.mjs.map +0 -1
- package/dist/migration-check-Bbdw7t-r-C2VTMK61.mjs +0 -358
- package/dist/migration-check-Bbdw7t-r-C2VTMK61.mjs.map +0 -1
- package/dist/migration-check-DbHgYK7F-7mtYNVFu.mjs +0 -163
- package/dist/migration-check-DbHgYK7F-7mtYNVFu.mjs.map +0 -1
- package/dist/migration-command-scaffold-SzjR2naH-Yi3-rNfX.mjs +0 -121
- package/dist/migration-command-scaffold-SzjR2naH-Yi3-rNfX.mjs.map +0 -1
- package/dist/migration-graph-B8WxW_tm-qGNf7jQh.mjs +0 -35
- package/dist/migration-graph-B8WxW_tm-qGNf7jQh.mjs.map +0 -1
- package/dist/migration-graph-BOwu76mF-kOTWFvfV.mjs +0 -144
- package/dist/migration-graph-BOwu76mF-kOTWFvfV.mjs.map +0 -1
- package/dist/migration-graph-command-render-h0VdTkSM-C3rPZEw1.mjs +0 -2127
- package/dist/migration-graph-command-render-h0VdTkSM-C3rPZEw1.mjs.map +0 -1
- package/dist/migration-graph-sections-BBHPOFN--COKyUKQ4.mjs +0 -69
- package/dist/migration-graph-sections-BBHPOFN--COKyUKQ4.mjs.map +0 -1
- package/dist/migration-list-CKuYcMQq-CubZzE9i.mjs +0 -130
- package/dist/migration-list-CKuYcMQq-CubZzE9i.mjs.map +0 -1
- package/dist/migration-list-CY08bD8I-PoXuv94c.mjs +0 -102
- package/dist/migration-list-CY08bD8I-PoXuv94c.mjs.map +0 -1
- package/dist/migration-log-CUbGla-9-BLIrWjwN.mjs +0 -123
- package/dist/migration-log-CUbGla-9-BLIrWjwN.mjs.map +0 -1
- package/dist/migration-log-table-eES9lPjv-BCFm8qJr.mjs +0 -116
- package/dist/migration-log-table-eES9lPjv-BCFm8qJr.mjs.map +0 -1
- package/dist/migration-new-ChvZjf5X-BFhEM0BF.mjs +0 -70
- package/dist/migration-new-ChvZjf5X-BFhEM0BF.mjs.map +0 -1
- package/dist/migration-new-DXMvJdbB-BkrpDfcr.mjs +0 -130
- package/dist/migration-new-DXMvJdbB-BkrpDfcr.mjs.map +0 -1
- package/dist/migration-path-target-JDWqF9kj-B7zoMq6X.mjs +0 -38
- package/dist/migration-path-target-JDWqF9kj-B7zoMq6X.mjs.map +0 -1
- package/dist/migration-plan-BV9f5Xjq-DiyscOMc.d.mts +0 -164
- package/dist/migration-plan-BV9f5Xjq-DiyscOMc.d.mts.map +0 -1
- package/dist/migration-plan-Bz1hOTHF-CFCtPuOv.mjs +0 -192
- package/dist/migration-plan-Bz1hOTHF-CFCtPuOv.mjs.map +0 -1
- package/dist/migration-plan-Cfz0efEL-DMNFq5b2.mjs +0 -621
- package/dist/migration-plan-Cfz0efEL-DMNFq5b2.mjs.map +0 -1
- package/dist/migration-show-BGdR1xnT-Cg3M0FPh.mjs +0 -178
- package/dist/migration-show-BGdR1xnT-Cg3M0FPh.mjs.map +0 -1
- package/dist/migration-status-BIrAJ5af-D-_mMBUA.mjs +0 -427
- package/dist/migration-status-BIrAJ5af-D-_mMBUA.mjs.map +0 -1
- package/dist/output-DP3woAjV-BxCr9nHA.mjs.map +0 -1
- package/dist/progress-adapter-CjAeTxY_-BXYSd1eY.mjs +0 -43
- package/dist/progress-adapter-CjAeTxY_-BXYSd1eY.mjs.map +0 -1
- package/dist/project-import-root-B4nM-VWX-D__g0hTb.mjs +0 -101
- package/dist/project-import-root-B4nM-VWX-D__g0hTb.mjs.map +0 -1
- package/dist/redact-secrets-DuKoiMax-Cfe2XVhc.mjs +0 -1476
- package/dist/redact-secrets-DuKoiMax-Cfe2XVhc.mjs.map +0 -1
- package/dist/ref-4x6BGSsd-ClaoZIQh.mjs +0 -95
- package/dist/ref-4x6BGSsd-ClaoZIQh.mjs.map +0 -1
- package/dist/ref-WXLIR9Xm-12IUtoBU.mjs +0 -104
- package/dist/ref-WXLIR9Xm-12IUtoBU.mjs.map +0 -1
- package/dist/ref-advancement-DaZBzm7m-WoqnFAyr.mjs +0 -96
- package/dist/ref-advancement-DaZBzm7m-WoqnFAyr.mjs.map +0 -1
- package/dist/ref-resolution-BSN1amKm-C6-TTM2N.mjs +0 -16
- package/dist/ref-resolution-BSN1amKm-C6-TTM2N.mjs.map +0 -1
- package/dist/refs-fQLFcMoq-aTBeUU9H.mjs +0 -47
- package/dist/refs-fQLFcMoq-aTBeUU9H.mjs.map +0 -1
- package/dist/schemas-BGgjiKV0-Rh8RlMCl.d.mts +0 -206
- package/dist/schemas-BGgjiKV0-Rh8RlMCl.d.mts.map +0 -1
- package/dist/schemas-CYSD83Cu-Bff4PPoi.mjs +0 -119
- package/dist/schemas-CYSD83Cu-Bff4PPoi.mjs.map +0 -1
- package/dist/shells-BenrJHp2.mjs.map +0 -1
- package/dist/shells-COHV_Ozf.d.mts.map +0 -1
- package/dist/telemetry-BD52LETE-Cqeb7ebh.mjs +0 -121
- package/dist/telemetry-BD52LETE-Cqeb7ebh.mjs.map +0 -1
- package/dist/terminal-ui-BN4QOsm5-Bf3pim46.d.mts +0 -133
- package/dist/terminal-ui-BN4QOsm5-Bf3pim46.d.mts.map +0 -1
- package/dist/terminal-ui-Cqz4LVL7-B0mcVdLy.mjs +0 -676
- package/dist/terminal-ui-Cqz4LVL7-B0mcVdLy.mjs.map +0 -1
- package/dist/verify-Cogr_Fj9-D3lCWA6t.mjs +0 -283
- package/dist/verify-Cogr_Fj9-D3lCWA6t.mjs.map +0 -1
|
@@ -1,1476 +0,0 @@
|
|
|
1
|
-
import { t as CliStructuredError$1 } from "./cli-errors-B4zTLaqQ-CXgjO9t4.mjs";
|
|
2
|
-
import { a as schemaSample, l as targetPackageName, s as targetEntrypoint, u as version } from "./code-templates-C-jirr19-DDQB0WGo.mjs";
|
|
3
|
-
import { createRequire } from "node:module";
|
|
4
|
-
import { CliStructuredError } from "@prisma/orm-framework/errors/control";
|
|
5
|
-
import { ifDefined } from "@prisma/orm-framework/utils/defined";
|
|
6
|
-
import { dirname, extname, join, normalize } from "pathe";
|
|
7
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
8
|
-
import { docsUrlFor } from "@prisma/orm-framework/utils/structured-error";
|
|
9
|
-
import { keepInternalSpecifiers } from "@prisma/orm-framework/components/emission";
|
|
10
|
-
import { blindCast } from "@prisma/orm-framework/utils/casts";
|
|
11
|
-
import { InternalError } from "@prisma/orm-framework/utils/internal-error";
|
|
12
|
-
import { detect, getUserAgent } from "package-manager-detector/detect";
|
|
13
|
-
import { applyEdits, modify, parse, printParseErrorCode } from "jsonc-parser";
|
|
14
|
-
//#region ../../../1-framework/3-tooling/cli/dist/redact-secrets-DuKoiMax.mjs
|
|
15
|
-
/**
|
|
16
|
-
* Walks up from `baseDir` looking for `pnpm-workspace.yaml`, then scans
|
|
17
|
-
* its top-level `catalog:` block for entries that match any of `packages`.
|
|
18
|
-
*
|
|
19
|
-
* Implements FR7.3 / Spec Decision 8 (honour-and-warn): when `init` runs
|
|
20
|
-
* inside a pnpm workspace whose catalog overrides one of the packages it
|
|
21
|
-
* installs, surface a structured warning so the user knows the catalog
|
|
22
|
-
* version (not the published `latest`) is what ended up in their
|
|
23
|
-
* `node_modules`. pnpm itself does this silently; the warning closes the
|
|
24
|
-
* "looks fine, must be wrong version six months later" gap.
|
|
25
|
-
*
|
|
26
|
-
* Notes / scope:
|
|
27
|
-
*
|
|
28
|
-
* - We only inspect the unnamed top-level `catalog:` block. pnpm also
|
|
29
|
-
* supports `catalogs:` (plural — *named* catalogs referenced via
|
|
30
|
-
* `catalog:foo` specifiers); those don't apply to a vanilla
|
|
31
|
-
* `pnpm add prisma-next` invocation, so we skip them.
|
|
32
|
-
* - We don't validate YAML syntax exhaustively. The file format pnpm
|
|
33
|
-
* ships is line-oriented and well-known; a minimal regex is more
|
|
34
|
-
* robust than depending on a YAML parser for one warning.
|
|
35
|
-
* - We don't compare against the registry's `latest` — pnpm uses the
|
|
36
|
-
* catalog version regardless, so the warning fires whenever a match
|
|
37
|
-
* exists. The user-facing copy explains how to opt out.
|
|
38
|
-
*/
|
|
39
|
-
function detectPnpmCatalogOverrides(baseDir, packages) {
|
|
40
|
-
const workspaceFile = findNearestPnpmWorkspaceFile(baseDir);
|
|
41
|
-
if (workspaceFile === null) return null;
|
|
42
|
-
const catalog = extractCatalogBlock(readFileSync(workspaceFile, "utf-8"));
|
|
43
|
-
if (catalog === null) return {
|
|
44
|
-
workspaceFile,
|
|
45
|
-
entries: []
|
|
46
|
-
};
|
|
47
|
-
const wanted = new Set(packages);
|
|
48
|
-
const entries = [];
|
|
49
|
-
for (const [name, version] of catalog) if (wanted.has(name)) entries.push({
|
|
50
|
-
name,
|
|
51
|
-
version
|
|
52
|
-
});
|
|
53
|
-
return {
|
|
54
|
-
workspaceFile,
|
|
55
|
-
entries
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
function findNearestPnpmWorkspaceFile(baseDir) {
|
|
59
|
-
let dir = baseDir;
|
|
60
|
-
let prev = "";
|
|
61
|
-
while (dir !== prev) {
|
|
62
|
-
const candidate = join(dir, "pnpm-workspace.yaml");
|
|
63
|
-
if (existsSync(candidate)) return candidate;
|
|
64
|
-
prev = dir;
|
|
65
|
-
dir = dirname(dir);
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Returns the entries inside the top-level `catalog:` block as `[name, version]`
|
|
71
|
-
* pairs in document order, or `null` when no `catalog:` block exists.
|
|
72
|
-
*
|
|
73
|
-
* The parser is intentionally minimal: it reads line-by-line, locates the
|
|
74
|
-
* top-level `catalog:` line (no leading whitespace), then collects every
|
|
75
|
-
* subsequent indented line of the form `<key>: <value>` until the next
|
|
76
|
-
* top-level key (or end of file). Quotes around `<key>` and `<value>`
|
|
77
|
-
* are stripped; comments (`#…`) are ignored.
|
|
78
|
-
*/
|
|
79
|
-
function extractCatalogBlock(contents) {
|
|
80
|
-
const lines = contents.split(/\r?\n/);
|
|
81
|
-
const startIdx = lines.findIndex((line) => /^catalog\s*:\s*$/.test(line));
|
|
82
|
-
if (startIdx === -1) return null;
|
|
83
|
-
const entries = [];
|
|
84
|
-
for (let i = startIdx + 1; i < lines.length; i++) {
|
|
85
|
-
const raw = lines[i] ?? "";
|
|
86
|
-
if (raw.trim() === "" || /^\s*#/.test(raw)) continue;
|
|
87
|
-
if (!/^\s/.test(raw)) break;
|
|
88
|
-
const match = raw.match(/^\s+(?:'([^']+)'|"([^"]+)"|([^:\s'"]+))\s*:\s*(.*?)\s*(?:#.*)?$/);
|
|
89
|
-
if (!match) continue;
|
|
90
|
-
const name = match[1] ?? match[2] ?? match[3];
|
|
91
|
-
if (name === void 0) continue;
|
|
92
|
-
const version = stripQuotes((match[4] ?? "").trim());
|
|
93
|
-
if (version === "") continue;
|
|
94
|
-
entries.push([name, version]);
|
|
95
|
-
}
|
|
96
|
-
return entries;
|
|
97
|
-
}
|
|
98
|
-
function stripQuotes(value) {
|
|
99
|
-
if (value.length >= 2) {
|
|
100
|
-
const first = value[0];
|
|
101
|
-
const last = value[value.length - 1];
|
|
102
|
-
if (first === "\"" && last === "\"" || first === "'" && last === "'") return value.slice(1, -1);
|
|
103
|
-
}
|
|
104
|
-
return value;
|
|
105
|
-
}
|
|
106
|
-
function formatCatalogWarning(workspaceFile, entries) {
|
|
107
|
-
return [
|
|
108
|
-
"pnpm workspace catalog overrides detected — pnpm will install these versions instead of `latest`:",
|
|
109
|
-
entries.map((entry) => ` • ${entry.name}: ${entry.version}`).join("\n"),
|
|
110
|
-
`Catalog source: ${workspaceFile}`,
|
|
111
|
-
"To use the published `latest` instead, remove or update the catalog entry, then re-run `pnpm install`."
|
|
112
|
-
].join("\n");
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Honour-and-warn: when the surrounding pnpm workspace pins one of the
|
|
116
|
-
* packages `init` installs through its catalog, say so — the catalog version,
|
|
117
|
-
* not the published `latest`, is what ends up in the project. Empty when there
|
|
118
|
-
* is no workspace above the project or its catalog names none of them.
|
|
119
|
-
*/
|
|
120
|
-
function buildCatalogWarnings(baseDir, packages) {
|
|
121
|
-
const result = detectPnpmCatalogOverrides(baseDir, packages);
|
|
122
|
-
if (result === null || result.entries.length === 0) return [];
|
|
123
|
-
return [formatCatalogWarning(result.workspaceFile, result.entries)];
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Re-init in non-interactive mode without `--force`. Distinct from the
|
|
127
|
-
* decline-the-prompt path (which is `errorInitUserAborted`) because here
|
|
128
|
-
* the user was never given the choice — `--force` is the contract.
|
|
129
|
-
*/
|
|
130
|
-
function errorInitReinitNeedsForce() {
|
|
131
|
-
return new CliStructuredError$1("CLI.INIT_REINIT_NEEDS_FORCE", "Project is already initialized", {
|
|
132
|
-
why: "A `prisma-next.config.ts` already exists in this directory. Re-running `init` would overwrite the scaffolded files; in non-interactive mode `init` will not do that without `--force`.",
|
|
133
|
-
fix: "Pass `--force` to overwrite the existing scaffold, or run `init` interactively to confirm.",
|
|
134
|
-
docsUrl: docsUrlFor("CLI.INIT_REINIT_NEEDS_FORCE")
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Non-interactive mode is missing one or more required inputs. Lists every
|
|
139
|
-
* missing flag in the error so an agent / CI script can react without
|
|
140
|
-
* needing to parse English.
|
|
141
|
-
*
|
|
142
|
-
* @param missing — kebab-case flag names without leading dashes
|
|
143
|
-
* @param why — additional context (e.g. "stdin is not a TTY") that helps
|
|
144
|
-
* the user understand why interactive fallback was skipped.
|
|
145
|
-
*/
|
|
146
|
-
function errorInitMissingFlags(options) {
|
|
147
|
-
const flagList = options.missing.map((flag) => `--${flag}`).join(", ");
|
|
148
|
-
const fixList = options.missing.map((flag) => {
|
|
149
|
-
switch (flag) {
|
|
150
|
-
case "target": return "--target postgres|mongodb";
|
|
151
|
-
case "authoring": return "--authoring psl|typescript";
|
|
152
|
-
case "schema-path": return "--schema-path <path>";
|
|
153
|
-
default: return `--${flag} <value>`;
|
|
154
|
-
}
|
|
155
|
-
}).join(" ");
|
|
156
|
-
return new CliStructuredError$1("CLI.INIT_MISSING_FLAGS", "Missing required flags", {
|
|
157
|
-
why: `${options.why} Missing required flag(s): ${flagList}.`,
|
|
158
|
-
fix: `Re-run with the missing flag(s) supplied, e.g. \`prisma-next init --yes ${fixList}\`. Use \`prisma-next init --help\` to see every flag.`,
|
|
159
|
-
docsUrl: docsUrlFor("CLI.INIT_MISSING_FLAGS"),
|
|
160
|
-
meta: { missingFlags: options.missing }
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* A flag value was supplied but is not in the allowed set. Lists the
|
|
165
|
-
* allowed values in `meta` for machine-readable consumption.
|
|
166
|
-
*/
|
|
167
|
-
function errorInitInvalidFlagValue(options) {
|
|
168
|
-
return new CliStructuredError$1("CLI.INIT_INVALID_FLAG_VALUE", `Invalid value for --${options.flag}`, {
|
|
169
|
-
why: `\`--${options.flag} ${options.value}\` is not one of: ${options.allowed.join(", ")}.`,
|
|
170
|
-
fix: `Use one of: ${options.allowed.map((v) => `--${options.flag} ${v}`).join(", ")}.`,
|
|
171
|
-
docsUrl: docsUrlFor("CLI.INIT_INVALID_FLAG_VALUE"),
|
|
172
|
-
meta: {
|
|
173
|
-
flag: options.flag,
|
|
174
|
-
value: options.value,
|
|
175
|
-
allowed: options.allowed
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* `--authoring` and `--schema-path` disagree on file extension (e.g. PSL
|
|
181
|
-
* authoring with a `.ts` path). Surfaces before any scaffold files are
|
|
182
|
-
* written so the project tree stays untouched.
|
|
183
|
-
*/
|
|
184
|
-
function errorInitAuthoringSchemaPathMismatch(options) {
|
|
185
|
-
const expectedAuthoring = options.expectedExtension === ".ts" ? "typescript" : "psl";
|
|
186
|
-
return new CliStructuredError$1("CLI.INIT_AUTHORING_SCHEMA_PATH_MISMATCH", "Authoring and schema path do not match", {
|
|
187
|
-
why: `\`--authoring ${options.authoring}\` requires a schema file ending in ${options.expectedExtension}, but \`--schema-path ${options.schemaPath}\` ends in ${options.actualExtension}.`,
|
|
188
|
-
fix: `Use a matching pair, for example \`--authoring ${expectedAuthoring} --schema-path <path>${options.expectedExtension}\`, or change \`--authoring\` to match the path you supplied. You can also omit \`--schema-path\` to use the default for the chosen authoring.`,
|
|
189
|
-
docsUrl: docsUrlFor("CLI.INIT_AUTHORING_SCHEMA_PATH_MISMATCH"),
|
|
190
|
-
meta: {
|
|
191
|
-
authoring: options.authoring,
|
|
192
|
-
schemaPath: options.schemaPath,
|
|
193
|
-
actualExtension: options.actualExtension,
|
|
194
|
-
expectedExtension: options.expectedExtension
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* The user cancelled an interactive prompt (Ctrl-C, escape, declined a
|
|
200
|
-
* selection). Distinct from `errorInitReinitNeedsForce` because that path
|
|
201
|
-
* applies to non-interactive mode where the user was never given the
|
|
202
|
-
* choice; this one is the generic "user said no" path. Maps to exit code
|
|
203
|
-
* 3 (USER_ABORTED).
|
|
204
|
-
*/
|
|
205
|
-
function errorInitUserAborted() {
|
|
206
|
-
return new CliStructuredError$1("CLI.INIT_USER_ABORTED", "Init cancelled", {
|
|
207
|
-
why: "The interactive prompt was cancelled before all required inputs were supplied. No files were modified.",
|
|
208
|
-
fix: "Re-run `prisma-next init` and complete the prompts, or pass the required inputs as flags (see `--help`) for a non-interactive run.",
|
|
209
|
-
severity: "info"
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* `--strict-probe` was supplied without `--probe-db`. Per FR8.3 / NFR9
|
|
214
|
-
* (offline-by-default), `--strict-probe` is a no-op without `--probe-db` —
|
|
215
|
-
* but rather than silently ignoring it we tell the user what they probably
|
|
216
|
-
* meant. Without this guard, the flag combination silently does nothing,
|
|
217
|
-
* which is exactly the kind of "looks like it worked" trap that a strict
|
|
218
|
-
* mode is supposed to prevent.
|
|
219
|
-
*/
|
|
220
|
-
function errorInitStrictProbeWithoutProbe() {
|
|
221
|
-
return new CliStructuredError$1("CLI.INIT_STRICT_PROBE_WITHOUT_PROBE", "`--strict-probe` requires `--probe-db`", {
|
|
222
|
-
why: "`--strict-probe` only changes how a *failed* probe is reported; without `--probe-db` no probe is attempted in the first place. (`init` is offline-by-default — it never opens a connection to your database without explicit consent.)",
|
|
223
|
-
fix: "Add `--probe-db` to opt in to the probe, or drop `--strict-probe` if you do not need the version check.",
|
|
224
|
-
docsUrl: docsUrlFor("CLI.INIT_STRICT_PROBE_WITHOUT_PROBE")
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Dependency installation failed and the pnpm → npm fallback (FR7.2)
|
|
229
|
-
* either did not apply (pm ≠ pnpm or stderr did not match a recognised
|
|
230
|
-
* leak) or also failed. Files scaffolded before the install step are
|
|
231
|
-
* already on disk; `meta.filesWritten` carries the list so a follow-up
|
|
232
|
-
* agent can resume manually. Maps to exit code `4 = INSTALL_FAILED`.
|
|
233
|
-
*/
|
|
234
|
-
function errorInitInstallFailed(options) {
|
|
235
|
-
const trimmed = options.stderrLines.map((s) => s.trim()).filter(Boolean);
|
|
236
|
-
return new CliStructuredError$1("CLI.INIT_INSTALL_FAILED", "Failed to install dependencies", {
|
|
237
|
-
why: trimmed.length === 0 ? "The package manager exited with an error and no recoverable fallback applied." : `The package manager exited with: ${trimmed[0]}`,
|
|
238
|
-
fix: `Install manually:\n ${options.addCommand}\n ${options.addDevCommand}\nThen run \`${options.emitCommand}\` to emit the contract.`,
|
|
239
|
-
docsUrl: docsUrlFor("CLI.INIT_INSTALL_FAILED"),
|
|
240
|
-
meta: {
|
|
241
|
-
filesWritten: options.filesWritten,
|
|
242
|
-
stderr: trimmed
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* The user's project manifest (typically `package.json`) failed to parse
|
|
248
|
-
* as JSON. Init reads the manifest to merge `scripts` (FR3.5) and to
|
|
249
|
-
* skip `@types/node` when it is already declared (FR2.1); a malformed
|
|
250
|
-
* file would otherwise surface as an `INTERNAL_ERROR` with a raw
|
|
251
|
-
* `SyntaxError` stack, which violates the FR1.6 contract that every
|
|
252
|
-
* documented failure mode maps to a stable exit code.
|
|
253
|
-
*
|
|
254
|
-
* Maps to exit code `2 = PRECONDITION` — the user can fix the manifest
|
|
255
|
-
* and re-run.
|
|
256
|
-
*/
|
|
257
|
-
function errorInitInvalidManifest(options) {
|
|
258
|
-
return new CliStructuredError$1("CLI.INIT_INVALID_MANIFEST", `Failed to parse ${options.path}`, {
|
|
259
|
-
why: `\`${options.path}\` is not valid JSON: ${options.cause}`,
|
|
260
|
-
fix: `Fix the JSON syntax in \`${options.path}\` (a missing comma or unbalanced brace is the most common cause), then re-run \`prisma-next init\`.`,
|
|
261
|
-
docsUrl: docsUrlFor("CLI.INIT_INVALID_MANIFEST"),
|
|
262
|
-
meta: {
|
|
263
|
-
path: options.path,
|
|
264
|
-
cause: options.cause
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* The user's existing `tsconfig.json` could not be parsed even with JSONC
|
|
270
|
-
* tolerance (comments + trailing commas) enabled. Init merges the
|
|
271
|
-
* minimum compiler options the scaffolded files need (FR2.2), so an
|
|
272
|
-
* unparseable tsconfig is a hard precondition failure: we cannot
|
|
273
|
-
* faithfully edit a file we cannot read.
|
|
274
|
-
*
|
|
275
|
-
* Init must surface this **before** writing any scaffold file so the
|
|
276
|
-
* user's working tree stays byte-identical (FR6.2 / NFR3) — see
|
|
277
|
-
* `runInit` for the precondition gate.
|
|
278
|
-
*
|
|
279
|
-
* Maps to exit code `2 = PRECONDITION` — the user can fix the file and
|
|
280
|
-
* re-run.
|
|
281
|
-
*/
|
|
282
|
-
function errorInitInvalidTsconfig(options) {
|
|
283
|
-
return new CliStructuredError$1("CLI.INIT_INVALID_TSCONFIG", `Failed to parse ${options.path}`, {
|
|
284
|
-
why: `\`${options.path}\` is not valid JSON or JSONC: ${options.cause}`,
|
|
285
|
-
fix: `Fix the syntax in \`${options.path}\` and re-run \`prisma-next init\`. \`init\` accepts JSONC (comments and trailing commas) but cannot recover from unbalanced braces or missing commas.`,
|
|
286
|
-
docsUrl: docsUrlFor("CLI.INIT_INVALID_TSCONFIG"),
|
|
287
|
-
meta: {
|
|
288
|
-
path: options.path,
|
|
289
|
-
cause: options.cause
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* `--probe-db` was supplied along with `--strict-probe` and the probe
|
|
295
|
-
* could not complete (no `DATABASE_URL`, network/auth error, the target
|
|
296
|
-
* driver was not installed, …). Without `--strict-probe` the probe
|
|
297
|
-
* surfaces these as warnings; `--strict-probe` escalates them to
|
|
298
|
-
* fatal so a CI gate can rely on "init exit code 2 means something
|
|
299
|
-
* about the runtime environment is wrong" (FR8.3).
|
|
300
|
-
*
|
|
301
|
-
* Maps to exit code `2 = PRECONDITION`. The caller's project files
|
|
302
|
-
* are already on disk by this point — the probe runs after the write
|
|
303
|
-
* phase — but the install/emit steps may or may not have completed
|
|
304
|
-
* depending on `--no-install` and the exact failure mode; `meta`
|
|
305
|
-
* carries `filesWritten` so a follow-up agent can resume manually.
|
|
306
|
-
*/
|
|
307
|
-
function errorInitProbeFailed(options) {
|
|
308
|
-
return new CliStructuredError$1("CLI.INIT_PROBE_FAILED", "Database probe failed", {
|
|
309
|
-
why: `\`--probe-db\` could not complete and \`--strict-probe\` was set: ${options.cause}`,
|
|
310
|
-
fix: "Confirm `DATABASE_URL` points at a reachable server, or drop `--strict-probe` to treat probe failures as warnings.",
|
|
311
|
-
docsUrl: docsUrlFor("CLI.INIT_PROBE_FAILED"),
|
|
312
|
-
meta: {
|
|
313
|
-
filesWritten: options.filesWritten,
|
|
314
|
-
cause: options.cause
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* `prisma-next contract emit` failed after a successful install. Surface
|
|
320
|
-
* the underlying error so the user can fix it and re-run; files and
|
|
321
|
-
* dependencies remain on disk untouched. Maps to exit code
|
|
322
|
-
* `5 = EMIT_FAILED`.
|
|
323
|
-
*/
|
|
324
|
-
function errorInitEmitFailed(options) {
|
|
325
|
-
return new CliStructuredError$1("CLI.INIT_EMIT_FAILED", "Failed to emit contract", {
|
|
326
|
-
why: `\`prisma-next contract emit\` failed: ${options.cause}`,
|
|
327
|
-
fix: `Inspect your contract file, fix the underlying issue, then re-run \`${options.emitCommand}\`. Pass \`-v\` for the full error envelope.`,
|
|
328
|
-
docsUrl: docsUrlFor("CLI.INIT_EMIT_FAILED"),
|
|
329
|
-
meta: {
|
|
330
|
-
filesWritten: options.filesWritten,
|
|
331
|
-
cause: options.cause
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* A scaffold file could not be written after earlier writes had already
|
|
337
|
-
* landed. The directory is half-scaffolded, so this carries the list of what
|
|
338
|
-
* did get written, the way every other post-write failure in `init` does.
|
|
339
|
-
*
|
|
340
|
-
* Maps to exit code `2 = PRECONDITION`: what stopped the write is something
|
|
341
|
-
* about the directory the user can fix.
|
|
342
|
-
*/
|
|
343
|
-
function errorInitWriteFailed(options) {
|
|
344
|
-
return new CliStructuredError$1("CLI.INIT_WRITE_FAILED", `Failed to write ${options.path}`, {
|
|
345
|
-
why: `\`${options.path}\` could not be written: ${options.cause}`,
|
|
346
|
-
fix: "Fix what stopped the write — a directory sitting where the file goes, permissions, a full disk — then run `prisma-next init` again. It will ask you to confirm replacing the files this run already wrote (listed in `meta.filesWritten`).",
|
|
347
|
-
docsUrl: docsUrlFor("CLI.INIT_WRITE_FAILED"),
|
|
348
|
-
meta: {
|
|
349
|
-
path: options.path,
|
|
350
|
-
cause: options.cause,
|
|
351
|
-
filesWritten: options.filesWritten
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* The project-level skills install (`npx skills add
|
|
357
|
-
* prisma/prisma#v<version>`) failed after a successful dependency
|
|
358
|
-
* install + emit. The project's scaffold remains on disk; the user
|
|
359
|
-
* can either fix the underlying issue (network, registry, PATH) and
|
|
360
|
-
* run the install command manually, or re-run `init --no-skill` to
|
|
361
|
-
* proceed without the skill.
|
|
362
|
-
*
|
|
363
|
-
* Non-rolling-back, matching the existing install/emit failure
|
|
364
|
-
* semantics. Maps to exit code `6 = SKILL_INSTALL_FAILED`.
|
|
365
|
-
*/
|
|
366
|
-
function errorInitSkillInstallFailed(options) {
|
|
367
|
-
return new CliStructuredError$1("CLI.INIT_SKILL_INSTALL_FAILED", "Failed to install Prisma Next skills", {
|
|
368
|
-
why: `\`${options.skillInstallCommand}\` exited with an error: ${options.cause}`,
|
|
369
|
-
fix: `Either:
|
|
370
|
-
- Re-run \`prisma-next init --no-skill${options.filesWritten.length > 0 ? " --force" : ""}\` to skip the skill install for this run, or\n - Fix the underlying issue (network, npm registry, \`npx skills\` on PATH) and install manually:\n ${options.skillInstallCommand}`,
|
|
371
|
-
docsUrl: docsUrlFor("CLI.INIT_SKILL_INSTALL_FAILED"),
|
|
372
|
-
meta: {
|
|
373
|
-
filesWritten: options.filesWritten,
|
|
374
|
-
skillInstallCommand: options.skillInstallCommand,
|
|
375
|
-
cause: options.cause
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
/**
|
|
380
|
-
* Connects (when configured) to the user's database and returns a
|
|
381
|
-
* structured outcome describing whether the server meets the declared
|
|
382
|
-
* minimum (FR8.1). Pure with respect to its inputs: no I/O happens
|
|
383
|
-
* unless `databaseUrl` is set.
|
|
384
|
-
*
|
|
385
|
-
* The outcome is shaped so that `--strict-probe` can branch on the
|
|
386
|
-
* `kind`/`meetsMinimum` pair without re-stringifying the message:
|
|
387
|
-
*
|
|
388
|
-
* - `ok` — informational; `init` continues.
|
|
389
|
-
* - `below-minimum` — warning; `init` continues regardless of
|
|
390
|
-
* `--strict-probe` (the spec scopes strict-probe to "probe
|
|
391
|
-
* *failures*", and a successful probe that finds an old server is
|
|
392
|
-
* not a failure).
|
|
393
|
-
* - `no-database-url` / `connection-failed` / `driver-missing` —
|
|
394
|
-
* warning by default, fatal under `--strict-probe`.
|
|
395
|
-
*/
|
|
396
|
-
async function probeServerVersion(ctx, overrides = {}) {
|
|
397
|
-
const { databaseUrl, minVersion, target } = ctx;
|
|
398
|
-
if (databaseUrl === void 0 || databaseUrl.trim().length === 0) return {
|
|
399
|
-
kind: "no-database-url",
|
|
400
|
-
minVersion,
|
|
401
|
-
meetsMinimum: null,
|
|
402
|
-
message: "Skipped --probe-db: DATABASE_URL is not set in the current shell environment. (init does not read .env for the probe; export the variable or drop --probe-db.)"
|
|
403
|
-
};
|
|
404
|
-
let driverResult;
|
|
405
|
-
try {
|
|
406
|
-
if (target === "postgres") driverResult = overrides.probePostgres !== void 0 ? await overrides.probePostgres(databaseUrl) : await defaultProbePostgres(databaseUrl, ctx.baseDir, overrides);
|
|
407
|
-
else driverResult = overrides.probeMongo !== void 0 ? await overrides.probeMongo(databaseUrl) : await defaultProbeMongo(databaseUrl, ctx.baseDir, overrides);
|
|
408
|
-
} catch (err) {
|
|
409
|
-
if (err instanceof DriverMissingError) return {
|
|
410
|
-
kind: "driver-missing",
|
|
411
|
-
minVersion,
|
|
412
|
-
meetsMinimum: null,
|
|
413
|
-
cause: err.message,
|
|
414
|
-
message: `Skipped --probe-db: ${err.message}. (Run with install enabled, or install the driver yourself, then re-run \`prisma-next init --probe-db\`.)`
|
|
415
|
-
};
|
|
416
|
-
const cause = redactDatabaseUrlSecrets(causeMessage(err));
|
|
417
|
-
return {
|
|
418
|
-
kind: "connection-failed",
|
|
419
|
-
minVersion,
|
|
420
|
-
meetsMinimum: null,
|
|
421
|
-
cause,
|
|
422
|
-
message: `--probe-db could not connect: ${cause}.`
|
|
423
|
-
};
|
|
424
|
-
}
|
|
425
|
-
if (compareVersionPrefix(driverResult.serverVersion, minVersion) < 0) return {
|
|
426
|
-
kind: "below-minimum",
|
|
427
|
-
serverVersion: driverResult.serverVersion,
|
|
428
|
-
minVersion,
|
|
429
|
-
meetsMinimum: false,
|
|
430
|
-
message: `--probe-db: server reports version ${driverResult.serverVersion}, below the declared minimum (${minVersion}). Some queries may fail until the server is upgraded.`
|
|
431
|
-
};
|
|
432
|
-
return {
|
|
433
|
-
kind: "ok",
|
|
434
|
-
serverVersion: driverResult.serverVersion,
|
|
435
|
-
minVersion,
|
|
436
|
-
meetsMinimum: true,
|
|
437
|
-
message: `--probe-db: server reports version ${driverResult.serverVersion} (>= ${minVersion}).`
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
/**
|
|
441
|
-
* Compares two semver-prefix strings ("14", "14.2", "6.0", …) by
|
|
442
|
-
* numeric components left-to-right. Returns a negative number when `a`
|
|
443
|
-
* is older than `b`, zero when both versions agree on every numeric
|
|
444
|
-
* component (treating missing trailing components as `0`), and a
|
|
445
|
-
* positive number when `a` is newer.
|
|
446
|
-
*
|
|
447
|
-
* The loop runs over the **longer** of the two prefixes so that
|
|
448
|
-
* `'14'` compares less than `'14.1'` — without that, the shorter
|
|
449
|
-
* prefix would be silently accepted whenever the configured minimum
|
|
450
|
-
* has a non-zero minor or patch.
|
|
451
|
-
*
|
|
452
|
-
* Exported for unit tests.
|
|
453
|
-
*/
|
|
454
|
-
function compareVersionPrefix(a, b) {
|
|
455
|
-
const aParts = parseNumericParts(a);
|
|
456
|
-
const bParts = parseNumericParts(b);
|
|
457
|
-
const len = Math.max(aParts.length, bParts.length);
|
|
458
|
-
for (let i = 0; i < len; i += 1) {
|
|
459
|
-
const aPart = aParts[i] ?? 0;
|
|
460
|
-
const bPart = bParts[i] ?? 0;
|
|
461
|
-
if (aPart !== bPart) return aPart - bPart;
|
|
462
|
-
}
|
|
463
|
-
return 0;
|
|
464
|
-
}
|
|
465
|
-
function parseNumericParts(version) {
|
|
466
|
-
const match = version.match(/^[^\d]*(\d+(?:\.\d+){0,3})/);
|
|
467
|
-
if (match === null) return [];
|
|
468
|
-
return (match[1] ?? "").split(".").map((part) => Number.parseInt(part, 10));
|
|
469
|
-
}
|
|
470
|
-
var DriverMissingError = class extends Error {};
|
|
471
|
-
function causeMessage(err) {
|
|
472
|
-
if (err instanceof Error) return err.message;
|
|
473
|
-
return String(err);
|
|
474
|
-
}
|
|
475
|
-
/**
|
|
476
|
-
* Strips `user:password@` userinfo from any URL-shaped substring before
|
|
477
|
-
* we surface the cause to the user. Mirrors `redactSecrets` in
|
|
478
|
-
* `init.ts` — the probe path has its own redactor because the inputs
|
|
479
|
-
* here include the raw connection string by construction (driver
|
|
480
|
-
* errors echo the URL back).
|
|
481
|
-
*
|
|
482
|
-
* Exported for unit tests.
|
|
483
|
-
*/
|
|
484
|
-
function redactDatabaseUrlSecrets(text) {
|
|
485
|
-
if (!text) return text;
|
|
486
|
-
return text.replace(/([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)([^/@\s]+)@/g, "$1***@");
|
|
487
|
-
}
|
|
488
|
-
async function defaultProbePostgres(databaseUrl, baseDir, overrides) {
|
|
489
|
-
const client = new (requirePeer("pg", baseDir, overrides)).Client({ connectionString: databaseUrl });
|
|
490
|
-
await client.connect();
|
|
491
|
-
try {
|
|
492
|
-
const result = await client.query("SELECT version() as version");
|
|
493
|
-
return { serverVersion: parsePostgresVersion(String(result?.rows?.[0]?.version ?? "")) };
|
|
494
|
-
} finally {
|
|
495
|
-
await client.end().catch(() => void 0);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
/**
|
|
499
|
-
* Extracts the numeric prefix from a Postgres `version()` row, e.g.
|
|
500
|
-
*
|
|
501
|
-
* `PostgreSQL 14.10 on x86_64-pc-linux-gnu, ...` → `"14.10"`
|
|
502
|
-
* `PostgreSQL 16beta1 on …` → `"16"` (we
|
|
503
|
-
* conservatively drop the suffix; minimum-version comparisons
|
|
504
|
-
* treat 16beta1 as 16, which is what every reasonable user
|
|
505
|
-
* expects).
|
|
506
|
-
*
|
|
507
|
-
* Exported for unit tests.
|
|
508
|
-
*/
|
|
509
|
-
function parsePostgresVersion(versionString) {
|
|
510
|
-
const match = versionString.match(/PostgreSQL\s+(\d+(?:\.\d+)?)/i);
|
|
511
|
-
if (match === null || match[1] === void 0) throw new CliStructuredError("CLI.INIT_PROBE_FAILED", `Could not parse PostgreSQL version from \`${versionString}\``);
|
|
512
|
-
return match[1];
|
|
513
|
-
}
|
|
514
|
-
async function defaultProbeMongo(databaseUrl, baseDir, overrides) {
|
|
515
|
-
const client = new (requirePeer("mongodb", baseDir, overrides)).MongoClient(databaseUrl);
|
|
516
|
-
await client.connect();
|
|
517
|
-
try {
|
|
518
|
-
const buildInfo = await client.db().admin().command({ buildInfo: 1 });
|
|
519
|
-
const versionString = String(buildInfo.version ?? "");
|
|
520
|
-
if (versionString.length === 0) throw new CliStructuredError("CLI.INIT_PROBE_FAILED", "buildInfo did not include a `version` field");
|
|
521
|
-
return { serverVersion: versionString };
|
|
522
|
-
} finally {
|
|
523
|
-
await client.close().catch(() => void 0);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
/**
|
|
527
|
-
* Loads a peer driver (`pg` / `mongodb`) from the user's project
|
|
528
|
-
* `node_modules`. We deliberately resolve from `baseDir` rather than
|
|
529
|
-
* from the CLI bundle — the CLI does not depend on `pg` or `mongodb`
|
|
530
|
-
* directly, but the user's `init`-generated `package.json` does (via
|
|
531
|
-
* the target facade). Failure to resolve is folded into a typed
|
|
532
|
-
* `DriverMissingError` so `probeServerVersion` can map it to a
|
|
533
|
-
* `driver-missing` outcome rather than letting a `MODULE_NOT_FOUND`
|
|
534
|
-
* leak as a generic connection failure.
|
|
535
|
-
*/
|
|
536
|
-
function requirePeer(moduleId, baseDir, overrides) {
|
|
537
|
-
try {
|
|
538
|
-
if (overrides.requireFromBaseDir !== void 0) return overrides.requireFromBaseDir(baseDir, moduleId);
|
|
539
|
-
return createRequire(join(baseDir, "package.json"))(moduleId);
|
|
540
|
-
} catch (err) {
|
|
541
|
-
throw new DriverMissingError(`\`${moduleId}\` is not installed in this project (resolved from ${baseDir}; cause: ${causeMessage(err)})`);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
/**
|
|
545
|
-
* Default base for the GitHub-URL form `<owner>/<repo>` consumed by
|
|
546
|
-
* upstream `skills add`. Each `SkillSource` joins this base with its
|
|
547
|
-
* own subpath (and optional `#ref` for version-pinned clusters).
|
|
548
|
-
*/
|
|
549
|
-
const DEFAULT_SKILL_BASE = "prisma/prisma";
|
|
550
|
-
const DEFAULT_SKILL_SOURCES = [
|
|
551
|
-
{
|
|
552
|
-
subpath: "skills",
|
|
553
|
-
skill: "prisma-8",
|
|
554
|
-
ref: "cli",
|
|
555
|
-
description: "usage skill (version-locked to installed Prisma Next)"
|
|
556
|
-
},
|
|
557
|
-
{
|
|
558
|
-
subpath: "skills",
|
|
559
|
-
skill: "prisma-next-upgrade",
|
|
560
|
-
ref: null,
|
|
561
|
-
description: "upgrade skill (always tracks `main`)"
|
|
562
|
-
},
|
|
563
|
-
{
|
|
564
|
-
subpath: "skills",
|
|
565
|
-
skill: "prisma-8-extension-upgrade",
|
|
566
|
-
ref: null,
|
|
567
|
-
description: "extension-author upgrade skill (always tracks `main`)"
|
|
568
|
-
}
|
|
569
|
-
];
|
|
570
|
-
/**
|
|
571
|
-
* Test-only escape hatch for pinning the install base to a local
|
|
572
|
-
* checkout. Production runs leave this unset, so installs always use
|
|
573
|
-
* `DEFAULT_SKILL_BASE`.
|
|
574
|
-
*
|
|
575
|
-
* When set to an absolute filesystem path (typical for tests), the
|
|
576
|
-
* `#ref` fragment is dropped — local-path mode in upstream's CLI does
|
|
577
|
-
* not accept refs, and the local clone has whatever content the test
|
|
578
|
-
* checked into it anyway. When set to anything else (e.g. a fork name
|
|
579
|
-
* `myuser/prisma-next`), the ref policy is preserved.
|
|
580
|
-
*/
|
|
581
|
-
function resolveAgentSkillBase(env) {
|
|
582
|
-
const override = env["PRISMA_NEXT_SKILLS_BASE"]?.trim();
|
|
583
|
-
return override && override.length > 0 ? override : DEFAULT_SKILL_BASE;
|
|
584
|
-
}
|
|
585
|
-
function isLocalPath(base) {
|
|
586
|
-
return base.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(base);
|
|
587
|
-
}
|
|
588
|
-
/**
|
|
589
|
-
* Agents passed to every project-level init install. Upstream `skills add`
|
|
590
|
-
* is the source of truth for per-agent install behaviour; the CLI lists
|
|
591
|
-
* every supported runtime on one invocation and delegates the rest.
|
|
592
|
-
*/
|
|
593
|
-
const DEFAULT_SKILL_AGENTS = [
|
|
594
|
-
"cursor",
|
|
595
|
-
"claude-code",
|
|
596
|
-
"codex",
|
|
597
|
-
"windsurf"
|
|
598
|
-
];
|
|
599
|
-
/**
|
|
600
|
-
* Build the `<base>/<subpath>[#ref]` URL the `skills` CLI will
|
|
601
|
-
* resolve. Exported for unit tests so the per-source format can be
|
|
602
|
-
* asserted without going through the full install loop.
|
|
603
|
-
*/
|
|
604
|
-
function formatSkillSourceUrl(source, env = process.env) {
|
|
605
|
-
const base = resolveAgentSkillBase(env);
|
|
606
|
-
const url = `${base}/${source.subpath}`;
|
|
607
|
-
if (source.ref === null) return url;
|
|
608
|
-
if (isLocalPath(base)) return url;
|
|
609
|
-
if (source.ref === "cli") return `${url}#v${version}`;
|
|
610
|
-
return url;
|
|
611
|
-
}
|
|
612
|
-
/**
|
|
613
|
-
* The skill-install command for one source, formatted for the
|
|
614
|
-
* project's detected package manager. `npx`/`pnpm dlx`/`bunx` are
|
|
615
|
-
* interchangeable to the user; we pick the variant that matches the
|
|
616
|
-
* rest of the install step so a single project consistently uses one
|
|
617
|
-
* runner.
|
|
618
|
-
*
|
|
619
|
-
* `--agent` takes space-separated slugs on one flag; the explicit
|
|
620
|
-
* `--skill <name>` and `-y` skip the multi-select prompts a
|
|
621
|
-
* non-interactive scaffold step cannot show.
|
|
622
|
-
*
|
|
623
|
-
* Exported for unit tests so the per-PM dispatch can be asserted
|
|
624
|
-
* without a live subprocess.
|
|
625
|
-
*/
|
|
626
|
-
function formatSkillInstallCommand(args) {
|
|
627
|
-
const agents = args.agents ?? DEFAULT_SKILL_AGENTS;
|
|
628
|
-
const cliArgs = [
|
|
629
|
-
"skills@latest",
|
|
630
|
-
"add",
|
|
631
|
-
formatSkillSourceUrl(args.source, args.env),
|
|
632
|
-
"--agent",
|
|
633
|
-
...agents,
|
|
634
|
-
"--skill",
|
|
635
|
-
args.source.skill,
|
|
636
|
-
"-y"
|
|
637
|
-
];
|
|
638
|
-
return formatPackageManagerCommand(args.pm, cliArgs);
|
|
639
|
-
}
|
|
640
|
-
/**
|
|
641
|
-
* Ordered skill-install commands for one init run. This is both what the
|
|
642
|
-
* commander shell runs and what either shell tells the user to run when the
|
|
643
|
-
* install is skipped or fails — the commands need no scaffold and no `init`.
|
|
644
|
-
*/
|
|
645
|
-
function resolveProjectSkillInstallCommands(pm, env) {
|
|
646
|
-
return DEFAULT_SKILL_SOURCES.map((source) => formatSkillInstallCommand({
|
|
647
|
-
pm,
|
|
648
|
-
source,
|
|
649
|
-
...ifDefined("env", env)
|
|
650
|
-
}));
|
|
651
|
-
}
|
|
652
|
-
function formatPackageManagerCommand(pm, args) {
|
|
653
|
-
switch (pm) {
|
|
654
|
-
case "pnpm": return `pnpm dlx ${args.join(" ")}`;
|
|
655
|
-
case "yarn": return `yarn dlx ${args.join(" ")}`;
|
|
656
|
-
case "bun": return `bunx ${args.join(" ")}`;
|
|
657
|
-
case "deno": return `deno run -A npm:${args.join(" ")}`;
|
|
658
|
-
case "npm": return `npx ${args.join(" ")}`;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
/**
|
|
662
|
-
* Skill directories that predate the consolidated `prisma-8` skill:
|
|
663
|
-
* the per-workflow usage cluster (including the renamed
|
|
664
|
-
* `prisma-8-migration-review` spelling it briefly shipped under), the
|
|
665
|
-
* pre-rename spellings of the consolidated skill and the
|
|
666
|
-
* extension-author upgrade skill, and any hand-rolled `prisma-next`
|
|
667
|
-
* stub. Projects initialised before the consolidation carry these as
|
|
668
|
-
* sibling directories in each agent's install root; left in place
|
|
669
|
-
* they compete with the current skills for activation, so init
|
|
670
|
-
* removes them on every run.
|
|
671
|
-
*/
|
|
672
|
-
const RETIRED_SKILL_NAMES = [
|
|
673
|
-
"prisma-next",
|
|
674
|
-
"prisma-next-quickstart",
|
|
675
|
-
"prisma-next-contract",
|
|
676
|
-
"prisma-next-migrations",
|
|
677
|
-
"prisma-next-migration-review",
|
|
678
|
-
"prisma-8-migration-review",
|
|
679
|
-
"prisma-next-queries",
|
|
680
|
-
"prisma-next-runtime",
|
|
681
|
-
"prisma-next-build",
|
|
682
|
-
"prisma-next-supabase",
|
|
683
|
-
"prisma-next-debug",
|
|
684
|
-
"prisma-next-feedback",
|
|
685
|
-
"prisma-next-extension-upgrade"
|
|
686
|
-
];
|
|
687
|
-
/**
|
|
688
|
-
* Project-level install roots the upstream `skills` CLI uses for the
|
|
689
|
-
* agents in `DEFAULT_SKILL_AGENTS`: cursor and codex install into
|
|
690
|
-
* `.agents/skills`, claude-code into `.claude/skills`, windsurf into
|
|
691
|
-
* `.windsurf/skills`.
|
|
692
|
-
*/
|
|
693
|
-
const AGENT_SKILL_ROOTS = [
|
|
694
|
-
".agents/skills",
|
|
695
|
-
".claude/skills",
|
|
696
|
-
".windsurf/skills"
|
|
697
|
-
];
|
|
698
|
-
/**
|
|
699
|
-
* Every directory a retired per-workflow skill may occupy in a
|
|
700
|
-
* consumer project. Init deletes each (recursively) before running the
|
|
701
|
-
* skill install.
|
|
702
|
-
*/
|
|
703
|
-
function legacySkillDirs() {
|
|
704
|
-
return AGENT_SKILL_ROOTS.flatMap((root) => RETIRED_SKILL_NAMES.map((name) => `${root}/${name}`));
|
|
705
|
-
}
|
|
706
|
-
/**
|
|
707
|
-
* The minimum supported server version for each target. The
|
|
708
|
-
* authoritative source of truth is each target package's
|
|
709
|
-
* `package.json#prismaNext.minServerVersion` field — this module
|
|
710
|
-
* mirrors those values and a workspace-level test asserts the two
|
|
711
|
-
* never drift (`templates/tsconfig-env.test.ts`).
|
|
712
|
-
*
|
|
713
|
-
* Bumping a value here in isolation is **not** safe: edit the
|
|
714
|
-
* corresponding target package's `package.json` first, then mirror
|
|
715
|
-
* here. The scaffold's `.env.example` and the "Requirements" section
|
|
716
|
-
* of `prisma-next.md` both read from this constant, so a stale value
|
|
717
|
-
* lies to every freshly initialised user.
|
|
718
|
-
*/
|
|
719
|
-
const MIN_SERVER_VERSION = {
|
|
720
|
-
postgres: "15",
|
|
721
|
-
mongo: "8.0"
|
|
722
|
-
};
|
|
723
|
-
const TARGET_LABEL = {
|
|
724
|
-
postgres: "PostgreSQL",
|
|
725
|
-
mongo: "MongoDB"
|
|
726
|
-
};
|
|
727
|
-
/**
|
|
728
|
-
* Renders the placeholder body shared by `.env` and `.env.example`:
|
|
729
|
-
* the target-specific connection-string requirement comments and the
|
|
730
|
-
* commented-shape `DATABASE_URL` line. The output is identical for both
|
|
731
|
-
* authoring styles — the env file is orthogonal to PSL vs TS schema
|
|
732
|
-
* authoring.
|
|
733
|
-
*/
|
|
734
|
-
function envPlaceholderBody(target) {
|
|
735
|
-
const label = TARGET_LABEL[target];
|
|
736
|
-
const minVersion = MIN_SERVER_VERSION[target];
|
|
737
|
-
const lines = [];
|
|
738
|
-
lines.push(`# Connection string for ${label}.`);
|
|
739
|
-
lines.push(`# Requires ${label} >= ${minVersion}.`);
|
|
740
|
-
lines.push("");
|
|
741
|
-
if (target === "postgres") lines.push("DATABASE_URL=\"postgresql://user:password@localhost:5432/mydb\"");
|
|
742
|
-
else {
|
|
743
|
-
lines.push("# Standalone local mongod / `docker run mongo:8` — no replica set required for first-run queries.");
|
|
744
|
-
lines.push("# Transactions and change streams need a replica set; add ?replicaSet=... only after initiating one.");
|
|
745
|
-
lines.push("");
|
|
746
|
-
lines.push("DATABASE_URL=\"mongodb://user:password@localhost:27017/mydb\"");
|
|
747
|
-
}
|
|
748
|
-
lines.push("");
|
|
749
|
-
return lines.join("\n");
|
|
750
|
-
}
|
|
751
|
-
/**
|
|
752
|
-
* Renders the `.env.example` content for a given target:
|
|
753
|
-
*
|
|
754
|
-
* - Carries a "Copy this file to `.env`…" intro that only makes sense
|
|
755
|
-
* for the example file (the real `.env` is the destination of that
|
|
756
|
-
* copy and so does not get the same intro).
|
|
757
|
-
* - Documents the `DATABASE_URL` placeholder in the target's native URL
|
|
758
|
-
* shape (Postgres: standard `postgresql://`, Mongo: `mongodb://` plus
|
|
759
|
-
* a `mydb` database segment so the lazy facade has a `dbName`).
|
|
760
|
-
* - Carries a `# Requires <db> >= <version>` comment so a fresh user
|
|
761
|
-
* knows the minimum supported server before they first try to connect.
|
|
762
|
-
*/
|
|
763
|
-
function envExampleContent(target) {
|
|
764
|
-
const lines = [];
|
|
765
|
-
lines.push("# Copy this file to `.env` and replace the placeholder with your real connection string.");
|
|
766
|
-
lines.push(envPlaceholderBody(target));
|
|
767
|
-
return lines.join("\n");
|
|
768
|
-
}
|
|
769
|
-
/**
|
|
770
|
-
* Renders the initial `.env` content for `--write-env` / interactive
|
|
771
|
-
* opt-in. Same placeholder body as `.env.example`, **without** the
|
|
772
|
-
* example file's "Copy this file to `.env`…" intro: the real `.env` is
|
|
773
|
-
* the destination of that copy, so the line would lie. Writing this
|
|
774
|
-
* file is gitignored (`.env` lands in `.gitignore` during init).
|
|
775
|
-
*/
|
|
776
|
-
function envFileContent(target) {
|
|
777
|
-
return envPlaceholderBody(target);
|
|
778
|
-
}
|
|
779
|
-
const TARGET_ALIASES = /* @__PURE__ */ new Map([
|
|
780
|
-
["postgres", "postgres"],
|
|
781
|
-
["postgresql", "postgres"],
|
|
782
|
-
["mongo", "mongo"],
|
|
783
|
-
["mongodb", "mongo"]
|
|
784
|
-
]);
|
|
785
|
-
const AUTHORING_VALUES = /* @__PURE__ */ new Map([
|
|
786
|
-
["psl", "psl"],
|
|
787
|
-
["typescript", "typescript"],
|
|
788
|
-
["ts", "typescript"]
|
|
789
|
-
]);
|
|
790
|
-
function resolveTarget(value) {
|
|
791
|
-
if (value === void 0) return void 0;
|
|
792
|
-
const mapped = TARGET_ALIASES.get(value.toLowerCase());
|
|
793
|
-
if (mapped === void 0) throw errorInitInvalidFlagValue({
|
|
794
|
-
flag: "target",
|
|
795
|
-
value,
|
|
796
|
-
allowed: ["postgres", "mongodb"]
|
|
797
|
-
});
|
|
798
|
-
return mapped;
|
|
799
|
-
}
|
|
800
|
-
function resolveAuthoring(value) {
|
|
801
|
-
if (value === void 0) return void 0;
|
|
802
|
-
const mapped = AUTHORING_VALUES.get(value.toLowerCase());
|
|
803
|
-
if (mapped === void 0) throw errorInitInvalidFlagValue({
|
|
804
|
-
flag: "authoring",
|
|
805
|
-
value,
|
|
806
|
-
allowed: ["psl", "typescript"]
|
|
807
|
-
});
|
|
808
|
-
return mapped;
|
|
809
|
-
}
|
|
810
|
-
/**
|
|
811
|
-
* Validates `--schema-path` against the chosen `--authoring` style: PSL
|
|
812
|
-
* authoring requires a `.prisma` file and TypeScript authoring requires a
|
|
813
|
-
* `.ts` file. Mismatched combinations would silently scaffold PSL content
|
|
814
|
-
* into a `.ts` file (or vice versa); this validator surfaces the mistake
|
|
815
|
-
* as a precondition error naming both flags.
|
|
816
|
-
*/
|
|
817
|
-
function validateSchemaPath(value, authoring) {
|
|
818
|
-
const trimmed = value.trim();
|
|
819
|
-
if (trimmed.length === 0) throw errorInitInvalidFlagValue({
|
|
820
|
-
flag: "schema-path",
|
|
821
|
-
value,
|
|
822
|
-
allowed: ["<non-empty file path with .prisma or .ts extension>"]
|
|
823
|
-
});
|
|
824
|
-
if (trimmed.endsWith("/") || trimmed.endsWith("\\")) throw errorInitInvalidFlagValue({
|
|
825
|
-
flag: "schema-path",
|
|
826
|
-
value,
|
|
827
|
-
allowed: ["<file path, not a directory>"]
|
|
828
|
-
});
|
|
829
|
-
const ext = extname(trimmed).toLowerCase();
|
|
830
|
-
const expected = authoring === "typescript" ? ".ts" : ".prisma";
|
|
831
|
-
if (ext !== expected) throw errorInitAuthoringSchemaPathMismatch({
|
|
832
|
-
authoring,
|
|
833
|
-
schemaPath: trimmed,
|
|
834
|
-
actualExtension: ext.length > 0 ? ext : "(none)",
|
|
835
|
-
expectedExtension: expected
|
|
836
|
-
});
|
|
837
|
-
return normalize(trimmed);
|
|
838
|
-
}
|
|
839
|
-
const KNOWN = /* @__PURE__ */ new Set([
|
|
840
|
-
"pnpm",
|
|
841
|
-
"npm",
|
|
842
|
-
"yarn",
|
|
843
|
-
"bun",
|
|
844
|
-
"deno"
|
|
845
|
-
]);
|
|
846
|
-
function isPackageManager(name) {
|
|
847
|
-
return KNOWN.has(name);
|
|
848
|
-
}
|
|
849
|
-
/**
|
|
850
|
-
* Resolves the package manager `init` should drive for `add` / `install`
|
|
851
|
-
* commands. Tries, in order:
|
|
852
|
-
*
|
|
853
|
-
* 1. **`detect()`** — walks up from `cwd` looking for a lockfile, the
|
|
854
|
-
* `packageManager` field, the `devEngines.packageManager` field, or
|
|
855
|
-
* install metadata. This is the right answer whenever the user is
|
|
856
|
-
* anywhere inside an existing project, including a deep workspace
|
|
857
|
-
* subdirectory.
|
|
858
|
-
*
|
|
859
|
-
* 2. **`getUserAgent()`** — parses `npm_config_user_agent`, the env var
|
|
860
|
-
* every PM sets when it spawns a script. This catches the
|
|
861
|
-
* bare-directory case where there's no project to walk up to but the
|
|
862
|
-
* user invoked us via `pnpm dlx prisma-next init` / `bunx
|
|
863
|
-
* prisma-next init` / `yarn dlx …`. Same signal used by every
|
|
864
|
-
* `create-*` tool in the ecosystem (`create-vite`, `create-next-app`,
|
|
865
|
-
* `create-astro`, `@antfu/ni`, …).
|
|
866
|
-
*
|
|
867
|
-
* 3. **`npm`** — final fallback. Always present alongside Node.
|
|
868
|
-
*/
|
|
869
|
-
async function detectPackageManager(cwd) {
|
|
870
|
-
const detected = await detect({ cwd });
|
|
871
|
-
if (detected && isPackageManager(detected.name)) return detected.name;
|
|
872
|
-
const userAgent = getUserAgent();
|
|
873
|
-
if (userAgent !== null && isPackageManager(userAgent)) return userAgent;
|
|
874
|
-
return "npm";
|
|
875
|
-
}
|
|
876
|
-
function hasProjectManifest(cwd) {
|
|
877
|
-
return existsSync(join(cwd, "package.json")) || existsSync(join(cwd, "deno.json")) || existsSync(join(cwd, "deno.jsonc"));
|
|
878
|
-
}
|
|
879
|
-
function formatRunCommand(pm, bin, args) {
|
|
880
|
-
if (pm === "npm") return `npx ${bin} ${args}`;
|
|
881
|
-
if (pm === "deno") return `deno run npm:${bin} ${args}`;
|
|
882
|
-
return `${pm} ${bin} ${args}`;
|
|
883
|
-
}
|
|
884
|
-
function formatRunScriptCommand(pm, scriptName) {
|
|
885
|
-
switch (pm) {
|
|
886
|
-
case "deno": return `deno task ${scriptName}`;
|
|
887
|
-
case "bun": return `bun run ${scriptName}`;
|
|
888
|
-
case "pnpm": return `pnpm run ${scriptName}`;
|
|
889
|
-
case "yarn": return `yarn run ${scriptName}`;
|
|
890
|
-
default: return `npm run ${scriptName}`;
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
function formatAddArgs(pm, packages) {
|
|
894
|
-
if (pm === "deno") return ["add", ...packages.map((p) => `npm:${p}`)];
|
|
895
|
-
return ["add", ...packages];
|
|
896
|
-
}
|
|
897
|
-
function formatAddDevArgs(pm, packages) {
|
|
898
|
-
if (pm === "deno") return [
|
|
899
|
-
"add",
|
|
900
|
-
"--dev",
|
|
901
|
-
...packages.map((p) => `npm:${p}`)
|
|
902
|
-
];
|
|
903
|
-
return [
|
|
904
|
-
"add",
|
|
905
|
-
"-D",
|
|
906
|
-
...packages
|
|
907
|
-
];
|
|
908
|
-
}
|
|
909
|
-
/**
|
|
910
|
-
* The `.gitattributes` entries written for a freshly initialised project
|
|
911
|
-
* (FR3.4). Mirrors the relevant subset of the repo-root
|
|
912
|
-
* [`.gitattributes`](../../../../../../../../.gitattributes):
|
|
913
|
-
*
|
|
914
|
-
* - **Today**: `contract.json`, `contract.d.ts` are emitted on every
|
|
915
|
-
* `prisma-next contract emit`. Marking them `linguist-generated`
|
|
916
|
-
* keeps GitHub's diff stats honest and collapses the file in code
|
|
917
|
-
* review by default.
|
|
918
|
-
* - **Forward-looking**: `ops.json`, `migration.json` are not yet emitted
|
|
919
|
-
* by `init` flows but will be produced by adjacent commands (lower /
|
|
920
|
-
* migration tooling). Adding them now matches Decision 5
|
|
921
|
-
* (forward-looking subset) so the file does not need to be amended
|
|
922
|
-
* every time a new artifact lands.
|
|
923
|
-
*
|
|
924
|
-
* `ARTIFACT_FILENAMES` entries are written relative to the schema
|
|
925
|
-
* directory so a user who runs `init --schema-path db/contract.prisma`
|
|
926
|
-
* gets `db/contract.json linguist-generated` — not the workspace-glob
|
|
927
|
-
* form `<glob>/contract.json` (which would over-match any unrelated
|
|
928
|
-
* `contract.json` the user has elsewhere) and not the absolute
|
|
929
|
-
* `DEFAULT_CONTRACT_SOURCE_DIR/contract.json` (which would silently
|
|
930
|
-
* break for a non-default schema path).
|
|
931
|
-
*
|
|
932
|
-
* The migration contract snapshot store (`migrations/snapshots/<hex>/`)
|
|
933
|
-
* is anchored to the migrations root instead, not the schema directory:
|
|
934
|
-
* migration package depth under `migrations/` varies (`app/<pkg>`,
|
|
935
|
-
* `<space>/<pkg>`, or a bare `<pkg>` in extension source repos), so no
|
|
936
|
-
* single schema-dir-relative pattern can reach every snapshot. See
|
|
937
|
-
* `STORE_GITATTRIBUTES_LINES` below.
|
|
938
|
-
*/
|
|
939
|
-
const ARTIFACT_FILENAMES$1 = [
|
|
940
|
-
"contract.json",
|
|
941
|
-
"contract.d.ts",
|
|
942
|
-
"ops.json",
|
|
943
|
-
"migration.json"
|
|
944
|
-
];
|
|
945
|
-
const ATTRIBUTE = "linguist-generated";
|
|
946
|
-
/**
|
|
947
|
-
* Full `.gitattributes` lines for the migration contract snapshot store,
|
|
948
|
-
* already anchored to the migrations root — unlike `ARTIFACT_FILENAMES`,
|
|
949
|
-
* these are not combined with the schema-relative prefix.
|
|
950
|
-
*/
|
|
951
|
-
const STORE_GITATTRIBUTES_LINES = [`migrations/snapshots/**/contract.json ${ATTRIBUTE}`, `migrations/snapshots/**/contract.d.ts ${ATTRIBUTE}`];
|
|
952
|
-
/**
|
|
953
|
-
* Computes the `.gitattributes` lines this scaffold expects to own. Each
|
|
954
|
-
* line has the shape `<path> linguist-generated`. The `target` parameter
|
|
955
|
-
* is currently unused but accepted for symmetry with the other hygiene
|
|
956
|
-
* helpers and to leave room for target-specific entries (e.g. a future
|
|
957
|
-
* family-specific artifact) without a signature break.
|
|
958
|
-
*/
|
|
959
|
-
function requiredGitattributesLines(schemaDir, _target) {
|
|
960
|
-
const dir = schemaDir === "." ? "" : schemaDir.replace(/\/+$/, "");
|
|
961
|
-
const prefix = dir === "" ? "" : `${dir}/`;
|
|
962
|
-
return [...ARTIFACT_FILENAMES$1.map((file) => `${prefix}${file} ${ATTRIBUTE}`), ...STORE_GITATTRIBUTES_LINES];
|
|
963
|
-
}
|
|
964
|
-
/**
|
|
965
|
-
* Idempotent `.gitattributes` merge (FR3.4 / FR9.3). Returns the new file
|
|
966
|
-
* content given the existing content (or `undefined` if the file does
|
|
967
|
-
* not yet exist).
|
|
968
|
-
*
|
|
969
|
-
* Equivalence is exact-line: a user-customised line like
|
|
970
|
-
* `prisma/*.json linguist-generated` is *not* recognised as covering
|
|
971
|
-
* `DEFAULT_CONTRACT_SOURCE_DIR/contract.json linguist-generated`. We accept that
|
|
972
|
-
* over-specification — preserving the user's broad pattern *and*
|
|
973
|
-
* appending the narrow one — because the narrow lines are what the
|
|
974
|
-
* acceptance criteria pin (FR3.4 AC).
|
|
975
|
-
*
|
|
976
|
-
* Returns `null` when no changes are required (file already contains
|
|
977
|
-
* every required entry).
|
|
978
|
-
*/
|
|
979
|
-
function mergeGitattributes(existing, required) {
|
|
980
|
-
if (existing === void 0) return `${required.join("\n")}\n`;
|
|
981
|
-
const presentLines = new Set(existing.split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")));
|
|
982
|
-
const missing = required.filter((line) => !presentLines.has(line));
|
|
983
|
-
if (missing.length === 0) return null;
|
|
984
|
-
return `${existing}${existing.length === 0 || existing.endsWith("\n") ? "" : "\n"}${missing.join("\n")}\n`;
|
|
985
|
-
}
|
|
986
|
-
/**
|
|
987
|
-
* The minimal `.gitignore` lines a Prisma Next scaffold needs (FR3.3).
|
|
988
|
-
* Order matches what Node tooling typically writes today.
|
|
989
|
-
*
|
|
990
|
-
* `node_modules/` first because it's the byte-largest miss; `dist/`
|
|
991
|
-
* because the scaffolded `tsconfig.json` writes there; `.env` last so
|
|
992
|
-
* the secret-bearing file is the one most-recently visible in any diff
|
|
993
|
-
* (a paranoid-correct ordering — humans skim from the top).
|
|
994
|
-
*/
|
|
995
|
-
const REQUIRED_GITIGNORE_ENTRIES = [
|
|
996
|
-
"node_modules/",
|
|
997
|
-
"dist/",
|
|
998
|
-
".env"
|
|
999
|
-
];
|
|
1000
|
-
/**
|
|
1001
|
-
* Idempotent `.gitignore` merge (FR3.3 / FR9.3). Returns the new file
|
|
1002
|
-
* content given the existing content (or `undefined` if the file does
|
|
1003
|
-
* not yet exist). Adds only entries that are not already present and
|
|
1004
|
-
* never duplicates a line. Existing comments and blank lines are
|
|
1005
|
-
* preserved verbatim — `.gitignore` is parsed by `git` without a tree,
|
|
1006
|
-
* so any line modification risks changing semantics.
|
|
1007
|
-
*
|
|
1008
|
-
* Pattern equivalence is line-literal: `node_modules/` and `node_modules`
|
|
1009
|
-
* are treated as different entries. This is intentional — `git` treats
|
|
1010
|
-
* them differently (the trailing slash restricts the match to
|
|
1011
|
-
* directories), and the AC pins the trailing-slash form.
|
|
1012
|
-
*
|
|
1013
|
-
* Returns `null` when no changes are required (file already contains
|
|
1014
|
-
* every required entry). The caller can use this to decide whether to
|
|
1015
|
-
* include `.gitignore` in `filesWritten`.
|
|
1016
|
-
*/
|
|
1017
|
-
function mergeGitignore(existing) {
|
|
1018
|
-
if (existing === void 0) return `${REQUIRED_GITIGNORE_ENTRIES.join("\n")}\n`;
|
|
1019
|
-
const present = new Set(existing.split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")));
|
|
1020
|
-
const missing = REQUIRED_GITIGNORE_ENTRIES.filter((entry) => !present.has(entry));
|
|
1021
|
-
if (missing.length === 0) return null;
|
|
1022
|
-
return `${existing}${existing.length === 0 || existing.endsWith("\n") ? "" : "\n"}${missing.join("\n")}\n`;
|
|
1023
|
-
}
|
|
1024
|
-
const REQUIRED_SCRIPTS = [{
|
|
1025
|
-
name: "contract:emit",
|
|
1026
|
-
command: "prisma-next contract emit"
|
|
1027
|
-
}];
|
|
1028
|
-
/**
|
|
1029
|
-
* Idempotent `package.json#scripts` merge with collision detection
|
|
1030
|
-
* (FR3.5 / FR9.3):
|
|
1031
|
-
*
|
|
1032
|
-
* - If a required script is **missing**, append it.
|
|
1033
|
-
* - If a required script is **already present and identical**, leave
|
|
1034
|
-
* the file alone (idempotency).
|
|
1035
|
-
* - If a required script is **present but maps to a different command**,
|
|
1036
|
-
* skip the write for that script and surface a structured warning.
|
|
1037
|
-
* The user's override is sacred — `init` should never silently
|
|
1038
|
-
* overwrite a custom build pipeline.
|
|
1039
|
-
*
|
|
1040
|
-
* Preserves the existing key order (so a user who has alphabetised
|
|
1041
|
-
* their scripts does not see them reshuffled) and appends new entries
|
|
1042
|
-
* at the end.
|
|
1043
|
-
*
|
|
1044
|
-
* The `package.json` is parsed and re-stringified through `JSON` —
|
|
1045
|
-
* comments are not preserved (package.json does not support them per
|
|
1046
|
-
* spec). Trailing newline matches the original input's trailing
|
|
1047
|
-
* newline behaviour.
|
|
1048
|
-
*/
|
|
1049
|
-
function mergePackageScripts(existing, required = REQUIRED_SCRIPTS) {
|
|
1050
|
-
const parsed = blindCast(JSON.parse(existing));
|
|
1051
|
-
const scripts = typeof parsed["scripts"] === "object" && parsed["scripts"] !== null ? { ...blindCast(parsed["scripts"]) } : {};
|
|
1052
|
-
const warnings = [];
|
|
1053
|
-
let mutated = false;
|
|
1054
|
-
for (const { name, command } of required) {
|
|
1055
|
-
const existingValue = scripts[name];
|
|
1056
|
-
if (existingValue === void 0) {
|
|
1057
|
-
scripts[name] = command;
|
|
1058
|
-
mutated = true;
|
|
1059
|
-
continue;
|
|
1060
|
-
}
|
|
1061
|
-
if (existingValue !== command) warnings.push(`package.json already has a "${name}" script with a different command — keeping yours.\n existing: ${existingValue}\n expected: ${command}\nIf you want the default, remove your "${name}" script and re-run \`init\`.`);
|
|
1062
|
-
}
|
|
1063
|
-
if (!mutated) return {
|
|
1064
|
-
content: null,
|
|
1065
|
-
warnings
|
|
1066
|
-
};
|
|
1067
|
-
parsed["scripts"] = scripts;
|
|
1068
|
-
const trailingNewline = existing.endsWith("\n") ? "\n" : "";
|
|
1069
|
-
return {
|
|
1070
|
-
content: `${JSON.stringify(parsed, null, 2)}${trailingNewline}`,
|
|
1071
|
-
warnings
|
|
1072
|
-
};
|
|
1073
|
-
}
|
|
1074
|
-
/**
|
|
1075
|
-
* Idempotently sets `"type": "module"` on a `package.json` so the
|
|
1076
|
-
* scaffolded `prisma/db.ts` — which uses the ESM-only `with { type: 'json' }`
|
|
1077
|
-
* import attribute — loads as ES module under Node's loader (TML-2494).
|
|
1078
|
-
*
|
|
1079
|
-
* Without this field Node either:
|
|
1080
|
-
*
|
|
1081
|
-
* - emits `MODULE_TYPELESS_PACKAGE_JSON` and reparses the file as ESM
|
|
1082
|
-
* with a perf penalty (Node 22+ with `--experimental-strip-types`), or
|
|
1083
|
-
* - hard-fails with `ERR_*` because the CJS loader cannot parse the
|
|
1084
|
-
* import-attribute syntax (older Node, or any tool that doesn't
|
|
1085
|
-
* reparse).
|
|
1086
|
-
*
|
|
1087
|
-
* Behaviour:
|
|
1088
|
-
*
|
|
1089
|
-
* - **Field missing** → set to `"module"`. New entry is inserted right
|
|
1090
|
-
* after `"name"` (when present) so the diff lands in a conventional
|
|
1091
|
-
* spot for human review; falls through to the natural append position
|
|
1092
|
-
* otherwise.
|
|
1093
|
-
* - **Field already `"module"`** → no-op (idempotent).
|
|
1094
|
-
* - **Field set to anything else** (e.g. `"commonjs"`) → leave it alone
|
|
1095
|
-
* and surface a structured warning. The user explicitly opted out of
|
|
1096
|
-
* ESM and we don't silently overwrite that.
|
|
1097
|
-
*/
|
|
1098
|
-
function ensureEsmModuleType(existing) {
|
|
1099
|
-
const parsed = blindCast(JSON.parse(existing));
|
|
1100
|
-
const currentType = parsed["type"];
|
|
1101
|
-
if (currentType === "module") return {
|
|
1102
|
-
content: null,
|
|
1103
|
-
warning: null
|
|
1104
|
-
};
|
|
1105
|
-
if (typeof currentType === "string" && currentType !== "module") return {
|
|
1106
|
-
content: null,
|
|
1107
|
-
warning: `package.json declares "type": "${currentType}" — keeping yours, but the scaffolded prisma/db.ts uses an ESM-only import attribute (\`with { type: 'json' }\`) and will not load under that module type.\nIf you want the default, set "type": "module" in package.json.`
|
|
1108
|
-
};
|
|
1109
|
-
const next = {};
|
|
1110
|
-
let inserted = false;
|
|
1111
|
-
for (const [key, value] of Object.entries(parsed)) {
|
|
1112
|
-
if (key === "type") continue;
|
|
1113
|
-
next[key] = value;
|
|
1114
|
-
if (!inserted && key === "name") {
|
|
1115
|
-
next["type"] = "module";
|
|
1116
|
-
inserted = true;
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
if (!inserted) next["type"] = "module";
|
|
1120
|
-
const trailingNewline = existing.endsWith("\n") ? "\n" : "";
|
|
1121
|
-
return {
|
|
1122
|
-
content: `${JSON.stringify(next, null, 2)}${trailingNewline}`,
|
|
1123
|
-
warning: null
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
/**
|
|
1127
|
-
* Filenames the contract pipeline emits next to the user's schema source
|
|
1128
|
-
* (`<schemaDir>/contract.json`, `<schemaDir>/contract.d.ts`, …). Mirrors
|
|
1129
|
-
* the schema-dir-relative `ARTIFACT_FILENAMES` in `hygiene-gitattributes.ts`
|
|
1130
|
-
* (not that file's migrations-root-anchored store lines, which are outside
|
|
1131
|
-
* this command's scope — reinit only ever touches `schemaDir`); kept as a
|
|
1132
|
-
* separate constant here because the cleanup contract is target-agnostic
|
|
1133
|
-
* and we deliberately do not want a stale artifact from a previous target
|
|
1134
|
-
* lingering after a re-init.
|
|
1135
|
-
*
|
|
1136
|
-
* If a future emit pipeline produces an additional schema-dir artifact,
|
|
1137
|
-
* add it here **and** to `ARTIFACT_FILENAMES` in `hygiene-gitattributes.ts`
|
|
1138
|
-
* — the two stay in lockstep so the file `init` advertises as
|
|
1139
|
-
* `linguist-generated` is exactly the file `init` is willing to delete on
|
|
1140
|
-
* re-init.
|
|
1141
|
-
*/
|
|
1142
|
-
const ARTIFACT_FILENAMES = [
|
|
1143
|
-
"contract.json",
|
|
1144
|
-
"contract.d.ts",
|
|
1145
|
-
"ops.json",
|
|
1146
|
-
"migration.json"
|
|
1147
|
-
];
|
|
1148
|
-
/**
|
|
1149
|
-
* Returns the schema-relative paths of stale contract artifacts the
|
|
1150
|
-
* previous `init` run (or a `contract emit`) left behind in `schemaDir`.
|
|
1151
|
-
* Paths are returned relative to `baseDir` so the caller can plumb them
|
|
1152
|
-
* into `filesWritten`-style logging without re-deriving the path.
|
|
1153
|
-
*
|
|
1154
|
-
* Pure function: no filesystem mutation. Used by `runInit`'s precondition
|
|
1155
|
-
* phase (FR6.2 / NFR3 atomicity) so a downstream parse failure leaves
|
|
1156
|
-
* the artifacts on disk and the project byte-identical to its pre-init
|
|
1157
|
-
* state.
|
|
1158
|
-
*/
|
|
1159
|
-
function findStaleArtifacts(baseDir, schemaDir) {
|
|
1160
|
-
const result = [];
|
|
1161
|
-
for (const filename of ARTIFACT_FILENAMES) {
|
|
1162
|
-
const rel = join(schemaDir, filename);
|
|
1163
|
-
if (existsSync(join(baseDir, rel))) result.push(rel);
|
|
1164
|
-
}
|
|
1165
|
-
return result;
|
|
1166
|
-
}
|
|
1167
|
-
/**
|
|
1168
|
-
* Drops a single key from `package.json#dependencies`, returning the new
|
|
1169
|
-
* file content. Returns `null` when the dependency was already absent —
|
|
1170
|
-
* the caller can skip the write to keep re-init idempotent (FR9.3).
|
|
1171
|
-
*
|
|
1172
|
-
* Used by `runInit` for the FR9.2 target-switch path: when the user
|
|
1173
|
-
* re-inits a project from `--target postgres` to `--target mongodb` (or
|
|
1174
|
-
* vice versa), the previous facade is removed from `dependencies` so the
|
|
1175
|
-
* resulting project depends only on the chosen target's facade.
|
|
1176
|
-
*
|
|
1177
|
-
* Devs/peers/optional dep groups are intentionally *not* touched — the
|
|
1178
|
-
* facades are only ever in `dependencies` (FR4 / FR7), and broadening
|
|
1179
|
-
* the search would risk clobbering an unrelated dep with the same name
|
|
1180
|
-
* in `peerDependencies`.
|
|
1181
|
-
*
|
|
1182
|
-
* Throws `SyntaxError` if `existing` is not parseable as JSON; the
|
|
1183
|
-
* caller (`runInit`) already guards on that with a structured 5010
|
|
1184
|
-
* error before this helper is reached.
|
|
1185
|
-
*/
|
|
1186
|
-
function removeDependency(existing, depName) {
|
|
1187
|
-
const parsed = JSON.parse(existing);
|
|
1188
|
-
const deps = parsed["dependencies"];
|
|
1189
|
-
if (deps === null || typeof deps !== "object" || Array.isArray(deps)) return null;
|
|
1190
|
-
if (!Object.hasOwn(deps, depName)) return null;
|
|
1191
|
-
const next = { ...deps };
|
|
1192
|
-
delete next[depName];
|
|
1193
|
-
parsed["dependencies"] = next;
|
|
1194
|
-
const trailingNewline = existing.endsWith("\n") ? "\n" : "";
|
|
1195
|
-
return `${JSON.stringify(parsed, null, 2)}${trailingNewline}`;
|
|
1196
|
-
}
|
|
1197
|
-
function renderTemplate(templateFile, variableNames, vars) {
|
|
1198
|
-
let result = readFileSync(join(import.meta.dirname, templateFile), "utf-8");
|
|
1199
|
-
for (const key of variableNames) {
|
|
1200
|
-
const value = vars[key];
|
|
1201
|
-
if (value === void 0) throw new InternalError(`Template variable '${key}' is not defined`);
|
|
1202
|
-
result = result.replaceAll(`{{${key}}}`, value);
|
|
1203
|
-
}
|
|
1204
|
-
return result;
|
|
1205
|
-
}
|
|
1206
|
-
const variables = [
|
|
1207
|
-
"schemaPath",
|
|
1208
|
-
"schemaDir",
|
|
1209
|
-
"dbImportPath",
|
|
1210
|
-
"pkgRun",
|
|
1211
|
-
"pkg",
|
|
1212
|
-
"configEntrypoint",
|
|
1213
|
-
"schemaSample",
|
|
1214
|
-
"requirements"
|
|
1215
|
-
];
|
|
1216
|
-
function quickReferenceMd(target, authoring, schemaPath, pkgRun, resolveImportSpecifier = keepInternalSpecifiers) {
|
|
1217
|
-
const schemaDir = dirname(schemaPath);
|
|
1218
|
-
const pkg = targetPackageName(target, resolveImportSpecifier);
|
|
1219
|
-
const vars = {
|
|
1220
|
-
schemaPath,
|
|
1221
|
-
schemaDir,
|
|
1222
|
-
dbImportPath: `./${schemaDir}/db`,
|
|
1223
|
-
pkgRun,
|
|
1224
|
-
pkg,
|
|
1225
|
-
configEntrypoint: targetEntrypoint(target, "config", resolveImportSpecifier),
|
|
1226
|
-
schemaSample: schemaSample(target, authoring, resolveImportSpecifier),
|
|
1227
|
-
requirements: requirementsBlock(target)
|
|
1228
|
-
};
|
|
1229
|
-
return renderTemplate(`quick-reference-${target}.md`, variables, vars);
|
|
1230
|
-
}
|
|
1231
|
-
/**
|
|
1232
|
-
* Renders the FR8.2 "Requirements" block injected into `prisma-next.md`
|
|
1233
|
-
* (the user-facing quick reference). Sources the minimum server
|
|
1234
|
-
* version from `MIN_SERVER_VERSION` — itself mirrored from each
|
|
1235
|
-
* target package's `package.json#prismaNext.minServerVersion`
|
|
1236
|
-
* (FR8.1).
|
|
1237
|
-
*
|
|
1238
|
-
* The verification command is target-specific — Postgres scaffolds
|
|
1239
|
-
* shouldn't ship Mongo's `db.runCommand` (and vice versa) just because
|
|
1240
|
-
* we couldn't be bothered to branch.
|
|
1241
|
-
*/
|
|
1242
|
-
function requirementsBlock(target) {
|
|
1243
|
-
return [
|
|
1244
|
-
"## Requirements",
|
|
1245
|
-
"",
|
|
1246
|
-
`- **${TARGET_LABEL[target]} ${MIN_SERVER_VERSION[target]} or newer.** Older servers are not supported. Run ${target === "postgres" ? "`SELECT version()`" : "`db.runCommand({ buildInfo: 1 })`"} against your server to verify.`,
|
|
1247
|
-
"- The CLI never connects to your database without explicit consent. Pass `--probe-db` to `prisma-next init` if you want `init` to verify the server version itself."
|
|
1248
|
-
].join("\n");
|
|
1249
|
-
}
|
|
1250
|
-
const sharedVariables = [
|
|
1251
|
-
"projectName",
|
|
1252
|
-
"contractPath",
|
|
1253
|
-
"runDev",
|
|
1254
|
-
"runContractEmit"
|
|
1255
|
-
];
|
|
1256
|
-
const postgresVariables = [
|
|
1257
|
-
...sharedVariables,
|
|
1258
|
-
"runDbInit",
|
|
1259
|
-
"runDbUpdate",
|
|
1260
|
-
"runMigrationPlan",
|
|
1261
|
-
"runMigrate",
|
|
1262
|
-
"runDbSeed"
|
|
1263
|
-
];
|
|
1264
|
-
const mongoVariables = [
|
|
1265
|
-
...sharedVariables,
|
|
1266
|
-
"runDbUp",
|
|
1267
|
-
"runDbDown",
|
|
1268
|
-
"runDbReset",
|
|
1269
|
-
"runMigrationPlan",
|
|
1270
|
-
"runMigrate",
|
|
1271
|
-
"runDbSeed"
|
|
1272
|
-
];
|
|
1273
|
-
function minimalProjectReadmeMd(target, schemaPath, projectName, pm) {
|
|
1274
|
-
const run = (script) => formatRunScriptCommand(pm, script);
|
|
1275
|
-
const shared = {
|
|
1276
|
-
projectName,
|
|
1277
|
-
contractPath: schemaPath,
|
|
1278
|
-
runDev: run("dev"),
|
|
1279
|
-
runContractEmit: run("contract:emit"),
|
|
1280
|
-
runMigrationPlan: run("migration:plan"),
|
|
1281
|
-
runMigrate: run("migrate"),
|
|
1282
|
-
runDbSeed: run("db:seed")
|
|
1283
|
-
};
|
|
1284
|
-
if (target === "mongo") {
|
|
1285
|
-
const vars = {
|
|
1286
|
-
...shared,
|
|
1287
|
-
runDbUp: run("db:up"),
|
|
1288
|
-
runDbDown: run("db:down"),
|
|
1289
|
-
runDbReset: run("db:reset")
|
|
1290
|
-
};
|
|
1291
|
-
return renderTemplate("readme-mongo.md", mongoVariables, vars);
|
|
1292
|
-
}
|
|
1293
|
-
const vars = {
|
|
1294
|
-
...shared,
|
|
1295
|
-
runDbInit: run("db:init"),
|
|
1296
|
-
runDbUpdate: run("db:update")
|
|
1297
|
-
};
|
|
1298
|
-
return renderTemplate("readme-postgres.md", postgresVariables, vars);
|
|
1299
|
-
}
|
|
1300
|
-
/**
|
|
1301
|
-
* Compiler options the scaffolded `prisma-next.config.ts` and `db.ts` need
|
|
1302
|
-
* to typecheck:
|
|
1303
|
-
*
|
|
1304
|
-
* - `module: 'preserve'` + `moduleResolution: 'bundler'` align with how
|
|
1305
|
-
* modern bundlers (and `tsdown`) consume our facade packages.
|
|
1306
|
-
* - `resolveJsonModule` lets `db.ts` import `contract.json with { type:
|
|
1307
|
-
* 'json' }` — the runtime path the facades document (FR4).
|
|
1308
|
-
*
|
|
1309
|
-
* `types: ['node']` is FR2.2 territory and lives in
|
|
1310
|
-
* `REQUIRED_COMPILER_OPTIONS_TYPES` because TS only honours an _array_
|
|
1311
|
-
* here, and a string-keyed merge would clobber any user-specified entries.
|
|
1312
|
-
* Merge handling preserves any extra `types` the user added.
|
|
1313
|
-
*/
|
|
1314
|
-
const REQUIRED_COMPILER_OPTIONS = {
|
|
1315
|
-
module: "preserve",
|
|
1316
|
-
moduleResolution: "bundler",
|
|
1317
|
-
resolveJsonModule: true
|
|
1318
|
-
};
|
|
1319
|
-
/**
|
|
1320
|
-
* Types that must be present in `compilerOptions.types` for the scaffold
|
|
1321
|
-
* to typecheck. With `moduleResolution: 'bundler'`, TypeScript does not
|
|
1322
|
-
* implicitly include all `@types/*` packages — `process.env` only resolves
|
|
1323
|
-
* when `node` is in this array (or `types` is omitted, but then any other
|
|
1324
|
-
* type listed here would force the same behaviour). Listing `node`
|
|
1325
|
-
* explicitly is the documented escape hatch (FR2.2).
|
|
1326
|
-
*/
|
|
1327
|
-
const REQUIRED_COMPILER_OPTIONS_TYPES = ["node"];
|
|
1328
|
-
function defaultTsConfig() {
|
|
1329
|
-
return JSON.stringify({
|
|
1330
|
-
compilerOptions: {
|
|
1331
|
-
target: "ES2022",
|
|
1332
|
-
...REQUIRED_COMPILER_OPTIONS,
|
|
1333
|
-
types: [...REQUIRED_COMPILER_OPTIONS_TYPES],
|
|
1334
|
-
strict: true,
|
|
1335
|
-
skipLibCheck: true,
|
|
1336
|
-
esModuleInterop: true,
|
|
1337
|
-
outDir: "dist"
|
|
1338
|
-
},
|
|
1339
|
-
include: ["**/*.ts"]
|
|
1340
|
-
}, null, 2);
|
|
1341
|
-
}
|
|
1342
|
-
/**
|
|
1343
|
-
* Thrown by `mergeTsConfig` when the user's existing `tsconfig.json` is
|
|
1344
|
-
* not parseable as JSONC (TypeScript's actual configured dialect — see
|
|
1345
|
-
* FR6.1). Carries the raw parse errors so the caller can render an
|
|
1346
|
-
* actionable, location-aware message.
|
|
1347
|
-
*
|
|
1348
|
-
* `runInit` catches this exception during the precondition phase and
|
|
1349
|
-
* maps it to a `CliStructuredError(5011)` so the user's working tree
|
|
1350
|
-
* stays byte-identical when init bails (FR6.2 / NFR3).
|
|
1351
|
-
*/
|
|
1352
|
-
var TsConfigParseError = class extends Error {
|
|
1353
|
-
errors;
|
|
1354
|
-
constructor(errors) {
|
|
1355
|
-
super(formatTsConfigParseErrors(errors));
|
|
1356
|
-
this.errors = errors;
|
|
1357
|
-
this.name = "TsConfigParseError";
|
|
1358
|
-
}
|
|
1359
|
-
};
|
|
1360
|
-
function formatTsConfigParseErrors(errors) {
|
|
1361
|
-
if (errors.length === 0) return "tsconfig.json is empty or not an object";
|
|
1362
|
-
return errors.map((e) => `${printParseErrorCode(e.error)} at offset ${e.offset}`).join("; ");
|
|
1363
|
-
}
|
|
1364
|
-
/**
|
|
1365
|
-
* Merges the required compiler options into an existing `tsconfig.json`.
|
|
1366
|
-
*
|
|
1367
|
-
* Parsing is delegated to `jsonc-parser` so JSONC inputs (comments,
|
|
1368
|
-
* trailing commas) — TypeScript's real configuration dialect — survive
|
|
1369
|
-
* unchanged: edits are applied as text patches via `modify` /
|
|
1370
|
-
* `applyEdits`, preserving the user's formatting, key ordering, and
|
|
1371
|
-
* comments wherever the touched paths permit (FR6.1, AC "Hostile
|
|
1372
|
-
* inputs").
|
|
1373
|
-
*
|
|
1374
|
-
* Throws `TsConfigParseError` when the input is not parseable as JSONC.
|
|
1375
|
-
* The caller must catch this and surface a structured error before
|
|
1376
|
-
* writing any scaffold files (FR6.2 atomicity).
|
|
1377
|
-
*/
|
|
1378
|
-
function mergeTsConfig(existing) {
|
|
1379
|
-
const { config } = parseTsConfigText(existing);
|
|
1380
|
-
const formattingOptions = {
|
|
1381
|
-
tabSize: detectIndent(existing),
|
|
1382
|
-
insertSpaces: true,
|
|
1383
|
-
eol: existing.includes("\r\n") ? "\r\n" : "\n"
|
|
1384
|
-
};
|
|
1385
|
-
let result = existing;
|
|
1386
|
-
for (const [key, value] of Object.entries(REQUIRED_COMPILER_OPTIONS)) {
|
|
1387
|
-
const edits = modify(result, ["compilerOptions", key], value, { formattingOptions });
|
|
1388
|
-
result = applyEdits(result, edits);
|
|
1389
|
-
}
|
|
1390
|
-
const existingTypes = config["compilerOptions"]?.["types"];
|
|
1391
|
-
const mergedTypes = mergeTypesArray(existingTypes);
|
|
1392
|
-
const typesEdits = modify(result, ["compilerOptions", "types"], mergedTypes, { formattingOptions });
|
|
1393
|
-
result = applyEdits(result, typesEdits);
|
|
1394
|
-
return result;
|
|
1395
|
-
}
|
|
1396
|
-
/**
|
|
1397
|
-
* Parses an existing `tsconfig.json` (JSONC) and returns the structured
|
|
1398
|
-
* config alongside any non-fatal parse warnings. Throws
|
|
1399
|
-
* `TsConfigParseError` if the input cannot be parsed at all or does
|
|
1400
|
-
* not resolve to a JSON object — both cases mean we cannot safely
|
|
1401
|
-
* apply edits.
|
|
1402
|
-
*
|
|
1403
|
-
* Exposed independently so callers (notably `runInit`'s precondition
|
|
1404
|
-
* gate) can validate the file *before* any scaffold file is written.
|
|
1405
|
-
*/
|
|
1406
|
-
function parseTsConfigText(text) {
|
|
1407
|
-
const errors = [];
|
|
1408
|
-
const value = parse(text, errors, {
|
|
1409
|
-
allowTrailingComma: true,
|
|
1410
|
-
disallowComments: false,
|
|
1411
|
-
allowEmptyContent: false
|
|
1412
|
-
});
|
|
1413
|
-
if (value === void 0 || value === null || typeof value !== "object" || Array.isArray(value)) throw new TsConfigParseError(errors);
|
|
1414
|
-
if (errors.length > 0) throw new TsConfigParseError(errors);
|
|
1415
|
-
return { config: value };
|
|
1416
|
-
}
|
|
1417
|
-
function detectIndent(text) {
|
|
1418
|
-
const match = text.match(/^([ \t]+)\S/m);
|
|
1419
|
-
if (match === null) return 2;
|
|
1420
|
-
const indent = match[1] ?? "";
|
|
1421
|
-
if (indent.startsWith(" ")) return 1;
|
|
1422
|
-
return indent.length || 2;
|
|
1423
|
-
}
|
|
1424
|
-
/**
|
|
1425
|
-
* Merges `REQUIRED_COMPILER_OPTIONS_TYPES` into the user's existing
|
|
1426
|
-
* `compilerOptions.types` array. Preserves order and dedupes. If the
|
|
1427
|
-
* user has no `types` array (or has set it to a non-array), we replace
|
|
1428
|
-
* with the required minimum — overwriting a non-array `types` is the
|
|
1429
|
-
* correct fix because anything other than a string array is invalid TS
|
|
1430
|
-
* config.
|
|
1431
|
-
*/
|
|
1432
|
-
function mergeTypesArray(existing) {
|
|
1433
|
-
const result = [];
|
|
1434
|
-
if (Array.isArray(existing)) {
|
|
1435
|
-
for (const item of existing) if (typeof item === "string" && !result.includes(item)) result.push(item);
|
|
1436
|
-
}
|
|
1437
|
-
for (const required of REQUIRED_COMPILER_OPTIONS_TYPES) if (!result.includes(required)) result.push(required);
|
|
1438
|
-
return result;
|
|
1439
|
-
}
|
|
1440
|
-
/**
|
|
1441
|
-
* Recognised pnpm error signatures that justify a fallback to npm.
|
|
1442
|
-
*
|
|
1443
|
-
* These patterns indicate the published artifact itself is at fault
|
|
1444
|
-
* (a leaked `workspace:*` or `catalog:` specifier), not the user's
|
|
1445
|
-
* environment — pnpm is faithfully reporting "I cannot resolve this
|
|
1446
|
-
* registry version", and npm is willing to install it because npm
|
|
1447
|
-
* doesn't care about the protocol prefix when there's a fallback range.
|
|
1448
|
-
*
|
|
1449
|
-
* The predicate lives on its own so both shells' `init` share one list:
|
|
1450
|
-
* the commander command matches it against captured child stderr, the
|
|
1451
|
-
* engine command against the stderr the package-manager capability
|
|
1452
|
-
* returns on a failed install.
|
|
1453
|
-
*/
|
|
1454
|
-
function isRecognisedPnpmResolutionError(stderr) {
|
|
1455
|
-
if (!stderr) return false;
|
|
1456
|
-
return stderr.includes("ERR_PNPM_WORKSPACE_PKG_NOT_FOUND") || stderr.includes("ERR_PNPM_NO_MATCHING_VERSION") || /No matching version found for .* in the catalog/i.test(stderr) || /workspace:[^\s]+ is not a valid (version|spec)/i.test(stderr) || /catalog:[^\s]* is not a valid (version|spec)/i.test(stderr);
|
|
1457
|
-
}
|
|
1458
|
-
/**
|
|
1459
|
-
* Strips credentials out of package-manager stderr before it reaches a warning,
|
|
1460
|
-
* an error's meta, or a log. Two shapes carry them: userinfo inside a registry
|
|
1461
|
-
* URL (`https://user:token@registry…`), and the npmrc settings npm and pnpm
|
|
1462
|
-
* echo back when authentication fails (`//registry.npmjs.org/:_authToken=…`,
|
|
1463
|
-
* or the top-level `_authToken=…` with no registry scope), which are not
|
|
1464
|
-
* URL-shaped and survive a userinfo-only pass.
|
|
1465
|
-
*
|
|
1466
|
-
* Both shells' `init` call this, and both call it on stderr they already
|
|
1467
|
-
* received from somewhere else: redaction is cheap and doubling it is harmless,
|
|
1468
|
-
* while trusting another layer to have done it is not.
|
|
1469
|
-
*/
|
|
1470
|
-
function redactSecrets(stderr) {
|
|
1471
|
-
return stderr.replace(/([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)([^/@\s]+)@/g, "$1***@").replace(/(\b_(?:authToken|auth|password)=)\S+/gi, "$1***");
|
|
1472
|
-
}
|
|
1473
|
-
//#endregion
|
|
1474
|
-
export { isRecognisedPnpmResolutionError as A, removeDependency as B, findStaleArtifacts as C, formatSkillInstallCommand as D, formatRunCommand as E, mergeTsConfig as F, validateSchemaPath as G, resolveAuthoring as H, minimalProjectReadmeMd as I, probeServerVersion as L, mergeGitattributes as M, mergeGitignore as N, formatSkillSourceUrl as O, mergePackageScripts as P, quickReferenceMd as R, errorInitWriteFailed as S, formatAddDevArgs as T, resolveProjectSkillInstallCommands as U, requiredGitattributesLines as V, resolveTarget as W, errorInitProbeFailed as _, TsConfigParseError as a, errorInitStrictProbeWithoutProbe as b, detectPackageManager as c, envFileContent as d, errorInitEmitFailed as f, errorInitMissingFlags as g, errorInitInvalidTsconfig as h, REQUIRED_SCRIPTS as i, legacySkillDirs as j, hasProjectManifest as k, ensureEsmModuleType as l, errorInitInvalidManifest as m, DEFAULT_SKILL_SOURCES as n, buildCatalogWarnings as o, errorInitInstallFailed as p, MIN_SERVER_VERSION as r, defaultTsConfig as s, DEFAULT_SKILL_AGENTS as t, envExampleContent as u, errorInitReinitNeedsForce as v, formatAddArgs as w, errorInitUserAborted as x, errorInitSkillInstallFailed as y, redactSecrets as z };
|
|
1475
|
-
|
|
1476
|
-
//# sourceMappingURL=redact-secrets-DuKoiMax-Cfe2XVhc.mjs.map
|