@geekmidas/cli 10.0.0-alpha.123 → 10.0.0-alpha.125
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/dist/{EndpointGenerator-BDa6pPgE.cjs → EndpointGenerator-BGxf9jWE.cjs} +8 -4
- package/dist/{EndpointGenerator-BDa6pPgE.cjs.map → EndpointGenerator-BGxf9jWE.cjs.map} +1 -1
- package/dist/{EndpointGenerator-CP_z_E3e.mjs → EndpointGenerator-errMeldx.mjs} +8 -4
- package/dist/{EndpointGenerator-CP_z_E3e.mjs.map → EndpointGenerator-errMeldx.mjs.map} +1 -1
- package/dist/{GoDaddyProvider-BlB5nJky.mjs → GoDaddyProvider-BN1dODm9.mjs} +3 -3
- package/dist/{GoDaddyProvider-BlB5nJky.mjs.map → GoDaddyProvider-BN1dODm9.mjs.map} +1 -1
- package/dist/{GoDaddyProvider-Dubq-pCc.cjs → GoDaddyProvider-BTdtqhI_.cjs} +3 -3
- package/dist/{GoDaddyProvider-Dubq-pCc.cjs.map → GoDaddyProvider-BTdtqhI_.cjs.map} +1 -1
- package/dist/{HostingerProvider-BNpS9aRJ.mjs → HostingerProvider-Cjh_2Ml6.mjs} +2 -2
- package/dist/{HostingerProvider-BNpS9aRJ.mjs.map → HostingerProvider-Cjh_2Ml6.mjs.map} +1 -1
- package/dist/{HostingerProvider-DR1iws1P.cjs → HostingerProvider-OdQmKXE3.cjs} +2 -2
- package/dist/{HostingerProvider-DR1iws1P.cjs.map → HostingerProvider-OdQmKXE3.cjs.map} +1 -1
- package/dist/{LegacyStateStore-ClvUC8qy.cjs → LegacyStateStore-C2S8TGwx.cjs} +3 -3
- package/dist/{LegacyStateStore-ClvUC8qy.cjs.map → LegacyStateStore-C2S8TGwx.cjs.map} +1 -1
- package/dist/{LegacyStateStore-DGALQGZu.mjs → LegacyStateStore-DgXmuG87.mjs} +3 -3
- package/dist/{LegacyStateStore-DGALQGZu.mjs.map → LegacyStateStore-DgXmuG87.mjs.map} +1 -1
- package/dist/{LocalStateStore-43kSYNpw.cjs → LocalStateStore-CaJw9H-3.cjs} +2 -2
- package/dist/{LocalStateStore-43kSYNpw.cjs.map → LocalStateStore-CaJw9H-3.cjs.map} +1 -1
- package/dist/{LocalStateStore-CBYUzVR5.mjs → LocalStateStore-ojY_BiMK.mjs} +2 -2
- package/dist/{LocalStateStore-CBYUzVR5.mjs.map → LocalStateStore-ojY_BiMK.mjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-CsrukCE-.mjs → OpenApiTsGenerator-W_HRXH1X.mjs} +2 -2
- package/dist/{OpenApiTsGenerator-CsrukCE-.mjs.map → OpenApiTsGenerator-W_HRXH1X.mjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-FNhY7Ssz.cjs → OpenApiTsGenerator-cQgtxWQo.cjs} +2 -2
- package/dist/{OpenApiTsGenerator-FNhY7Ssz.cjs.map → OpenApiTsGenerator-cQgtxWQo.cjs.map} +1 -1
- package/dist/{S3StateStore-DLHjDYYP.mjs → S3StateStore-BSPkxhrx.mjs} +2 -2
- package/dist/{S3StateStore-DLHjDYYP.mjs.map → S3StateStore-BSPkxhrx.mjs.map} +1 -1
- package/dist/{S3StateStore-ahE7hSNK.cjs → S3StateStore-BqugXIcb.cjs} +2 -2
- package/dist/{S3StateStore-ahE7hSNK.cjs.map → S3StateStore-BqugXIcb.cjs.map} +1 -1
- package/dist/{SSMStateStore-qIzIuazA.cjs → SSMStateStore-B0OsuT_k.cjs} +2 -2
- package/dist/{SSMStateStore-qIzIuazA.cjs.map → SSMStateStore-B0OsuT_k.cjs.map} +1 -1
- package/dist/{SSMStateStore-j5RuMkch.mjs → SSMStateStore-DM85OiH0.mjs} +2 -2
- package/dist/{SSMStateStore-j5RuMkch.mjs.map → SSMStateStore-DM85OiH0.mjs.map} +1 -1
- package/dist/{SubscriberGenerator-C8CPxrCK.cjs → SubscriberGenerator-BDUp7OeY.cjs} +237 -54
- package/dist/SubscriberGenerator-BDUp7OeY.cjs.map +1 -0
- package/dist/{SubscriberGenerator-y3pncae_.mjs → SubscriberGenerator-ocQ2yj0K.mjs} +227 -56
- package/dist/SubscriberGenerator-ocQ2yj0K.mjs.map +1 -0
- package/dist/{add-Bm-C56lH.mjs → add-C7ZBXIzM.mjs} +6 -6
- package/dist/{add-Bm-C56lH.mjs.map → add-C7ZBXIzM.mjs.map} +1 -1
- package/dist/{add-C2CvXrYw.cjs → add-CrxvmSpq.cjs} +7 -7
- package/dist/{add-C2CvXrYw.cjs.map → add-CrxvmSpq.cjs.map} +1 -1
- package/dist/{bundler-Dk7tAvAX.cjs → bundler-DVUXW95p.cjs} +5 -5
- package/dist/{bundler-Dk7tAvAX.cjs.map → bundler-DVUXW95p.cjs.map} +1 -1
- package/dist/{bundler-DnkFt4mn.mjs → bundler-DpZ9uBGN.mjs} +5 -5
- package/dist/{bundler-DnkFt4mn.mjs.map → bundler-DpZ9uBGN.mjs.map} +1 -1
- package/dist/{cli-Di464j1O.cjs → cli-BMRhE6cZ.cjs} +4 -4
- package/dist/{cli-Di464j1O.cjs.map → cli-BMRhE6cZ.cjs.map} +1 -1
- package/dist/{cli-CVeHFXNE.mjs → cli-BWfYyy1k.mjs} +4 -4
- package/dist/{cli-CVeHFXNE.mjs.map → cli-BWfYyy1k.mjs.map} +1 -1
- package/dist/{compose-cHkF---f.mjs → compose-BFmdLig3.mjs} +525 -55
- package/dist/compose-BFmdLig3.mjs.map +1 -0
- package/dist/{compose-ChVvb3xM.cjs → compose-Bqcy0lqo.cjs} +554 -84
- package/dist/compose-Bqcy0lqo.cjs.map +1 -0
- package/dist/{config-DrOX29sT.d.mts → config-CdytFgSR.d.cts} +3 -4
- package/dist/config-CdytFgSR.d.cts.map +1 -0
- package/dist/{config-B3iz9BtK.d.cts → config-_y1FGBWR.d.mts} +3 -4
- package/dist/config-_y1FGBWR.d.mts.map +1 -0
- package/dist/config.cjs +2 -2
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +2 -2
- package/dist/{credentialSchemas-B67WJOOm.cjs → credentialSchemas-DFxvGEwa.cjs} +2 -2
- package/dist/{credentialSchemas-B67WJOOm.cjs.map → credentialSchemas-DFxvGEwa.cjs.map} +1 -1
- package/dist/{credentialSchemas-DDOLRCLF.mjs → credentialSchemas-DaMpt-Dx.mjs} +2 -2
- package/dist/{credentialSchemas-DDOLRCLF.mjs.map → credentialSchemas-DaMpt-Dx.mjs.map} +1 -1
- package/dist/{credentials-Zqr3QQYB.cjs → credentials-D7XJypNd.cjs} +173 -3
- package/dist/credentials-D7XJypNd.cjs.map +1 -0
- package/dist/{credentials-B5N5yKk6.mjs → credentials-DpfnUvIR.mjs} +132 -4
- package/dist/credentials-DpfnUvIR.mjs.map +1 -0
- package/dist/deploy/public.cjs +16 -17
- package/dist/deploy/public.cjs.map +1 -1
- package/dist/deploy/public.d.cts +3 -5
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +3 -5
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +11 -12
- package/dist/deploy/public.mjs.map +1 -1
- package/dist/{deploy-DO4djCHb.mjs → deploy-D8pUA9Y0.mjs} +1240 -130
- package/dist/deploy-D8pUA9Y0.mjs.map +1 -0
- package/dist/{deploy-BffR_uEN.cjs → deploy-DVrNjX1X.cjs} +1261 -169
- package/dist/deploy-DVrNjX1X.cjs.map +1 -0
- package/dist/{discover-C5roJuc9.mjs → discover-CzGM5P3p.mjs} +136 -14
- package/dist/discover-CzGM5P3p.mjs.map +1 -0
- package/dist/{discover-DozUKs8f.cjs → discover-DL6h-J97.cjs} +158 -12
- package/dist/discover-DL6h-J97.cjs.map +1 -0
- package/dist/{dokploy-BcZm93Cc.mjs → dokploy-CzDGNB6A.mjs} +2 -2
- package/dist/{dokploy-BcZm93Cc.mjs.map → dokploy-CzDGNB6A.mjs.map} +1 -1
- package/dist/{dokploy-CsdvfH3t.cjs → dokploy-TtK6Zyl3.cjs} +2 -2
- package/dist/{dokploy-CsdvfH3t.cjs.map → dokploy-TtK6Zyl3.cjs.map} +1 -1
- package/dist/{drivers-BjGDYfnC.mjs → drivers-C-VqMtld.mjs} +2 -2
- package/dist/{drivers-BjGDYfnC.mjs.map → drivers-C-VqMtld.mjs.map} +1 -1
- package/dist/{drivers-DbjiYpW6.cjs → drivers-L29WvE95.cjs} +2 -2
- package/dist/{drivers-DbjiYpW6.cjs.map → drivers-L29WvE95.cjs.map} +1 -1
- package/dist/{eas-CN_cUXth.cjs → eas-D3clzkni.cjs} +2 -2
- package/dist/{eas-CN_cUXth.cjs.map → eas-D3clzkni.cjs.map} +1 -1
- package/dist/{eas-CBShP20v.mjs → eas-DaobzDks.mjs} +2 -2
- package/dist/{eas-CBShP20v.mjs.map → eas-DaobzDks.mjs.map} +1 -1
- package/dist/{emit-Dmc1nvdS.cjs → emit-CYloptRS.cjs} +34 -1
- package/dist/emit-CYloptRS.cjs.map +1 -0
- package/dist/{emit-C1e8qD08.mjs → emit-CiJGdy_f.mjs} +34 -1
- package/dist/emit-CiJGdy_f.mjs.map +1 -0
- package/dist/{encryption-CPDM49Hi.cjs → encryption-DBkIFiR2.cjs} +3 -3
- package/dist/{encryption-CPDM49Hi.cjs.map → encryption-DBkIFiR2.cjs.map} +1 -1
- package/dist/{encryption-CITa6dXL.mjs → encryption-DV31gEY8.mjs} +3 -3
- package/dist/{encryption-CITa6dXL.mjs.map → encryption-DV31gEY8.mjs.map} +1 -1
- package/dist/{engine-CTnHmHjz.mjs → engine-CFOR9h6X.mjs} +140 -16
- package/dist/engine-CFOR9h6X.mjs.map +1 -0
- package/dist/{engine-D-jfMVj-.cjs → engine-CuZUGbEh.cjs} +143 -19
- package/dist/engine-CuZUGbEh.cjs.map +1 -0
- package/dist/{github-D56PSK39.cjs → github-CsvtWSBW.cjs} +115 -47
- package/dist/github-CsvtWSBW.cjs.map +1 -0
- package/dist/{github-9RlA7EjN.mjs → github-Nep8pI4_.mjs} +113 -45
- package/dist/github-Nep8pI4_.mjs.map +1 -0
- package/dist/{googlePlay-SX_jQeJf.cjs → googlePlay-C-UfBXJU.cjs} +5 -5
- package/dist/{googlePlay-SX_jQeJf.cjs.map → googlePlay-C-UfBXJU.cjs.map} +1 -1
- package/dist/{googlePlay-COi5LXON.mjs → googlePlay-lF7Atm_N.mjs} +4 -4
- package/dist/{googlePlay-COi5LXON.mjs.map → googlePlay-lF7Atm_N.mjs.map} +1 -1
- package/dist/{index-DcyRA5Rf.d.mts → index-DrkV7N5w.d.mts} +2 -2
- package/dist/{index-DcyRA5Rf.d.mts.map → index-DrkV7N5w.d.mts.map} +1 -1
- package/dist/{index-DjLSMgAL.d.cts → index-yaXZ9m-J.d.cts} +2 -2
- package/dist/{index-DjLSMgAL.d.cts.map → index-yaXZ9m-J.d.cts.map} +1 -1
- package/dist/index.cjs +166 -85
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +149 -68
- package/dist/index.mjs.map +1 -1
- package/dist/{local-BwC2v2Y8.mjs → local-B7Zv1NoA.mjs} +2 -2
- package/dist/{local-BwC2v2Y8.mjs.map → local-B7Zv1NoA.mjs.map} +1 -1
- package/dist/{local-DNhnkugT.cjs → local-OPC9BCZt.cjs} +3 -3
- package/dist/{local-DNhnkugT.cjs.map → local-OPC9BCZt.cjs.map} +1 -1
- package/dist/{migrate-CrtxXeGY.cjs → migrate-Dp3GhFnf.cjs} +4 -4
- package/dist/{migrate-CrtxXeGY.cjs.map → migrate-Dp3GhFnf.cjs.map} +1 -1
- package/dist/{migrate-0J6gsfrQ.mjs → migrate-NfbPVhi9.mjs} +4 -4
- package/dist/{migrate-0J6gsfrQ.mjs.map → migrate-NfbPVhi9.mjs.map} +1 -1
- package/dist/{migrate-DJa_Dlsl.mjs → migrate-_sBX0pve.mjs} +3 -3
- package/dist/{migrate-DJa_Dlsl.mjs.map → migrate-_sBX0pve.mjs.map} +1 -1
- package/dist/{migrate-BCz1lkh_.cjs → migrate-hlNKNWmg.cjs} +3 -3
- package/dist/{migrate-BCz1lkh_.cjs.map → migrate-hlNKNWmg.cjs.map} +1 -1
- package/dist/openapi.cjs +3 -3
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +3 -3
- package/dist/{publish-CuQlOW5p.mjs → publish-BuUVaZVy.mjs} +2 -2
- package/dist/{publish-CuQlOW5p.mjs.map → publish-BuUVaZVy.mjs.map} +1 -1
- package/dist/{publish-qSpnvmdX.cjs → publish-ZOo4xEuZ.cjs} +2 -2
- package/dist/{publish-qSpnvmdX.cjs.map → publish-ZOo4xEuZ.cjs.map} +1 -1
- package/dist/{ready-BOfogqzr.mjs → ready-Ca883OvY.mjs} +6 -6
- package/dist/{ready-BOfogqzr.mjs.map → ready-Ca883OvY.mjs.map} +1 -1
- package/dist/{ready-BFFP838V.cjs → ready-qnqp6JAY.cjs} +6 -6
- package/dist/{ready-BFFP838V.cjs.map → ready-qnqp6JAY.cjs.map} +1 -1
- package/dist/reconcile/public.cjs +2 -2
- package/dist/reconcile/public.d.cts +1 -2
- package/dist/reconcile/public.d.cts.map +1 -1
- package/dist/reconcile/public.d.mts +1 -2
- package/dist/reconcile/public.d.mts.map +1 -1
- package/dist/reconcile/public.mjs +2 -2
- package/dist/{resolve-j8hUcbGz.mjs → resolve-BCU9pYDx.mjs} +4 -4
- package/dist/{resolve-j8hUcbGz.mjs.map → resolve-BCU9pYDx.mjs.map} +1 -1
- package/dist/{resolve-AsfohXd1.cjs → resolve-C9QqOl5t.cjs} +4 -4
- package/dist/{resolve-AsfohXd1.cjs.map → resolve-C9QqOl5t.cjs.map} +1 -1
- package/dist/{rollback-Bxq_URgL.cjs → rollback-CTWdDBgB.cjs} +7 -7
- package/dist/{rollback-Bxq_URgL.cjs.map → rollback-CTWdDBgB.cjs.map} +1 -1
- package/dist/{rollback-JgbAY43C.mjs → rollback-CWyyTQ0B.mjs} +7 -7
- package/dist/{rollback-JgbAY43C.mjs.map → rollback-CWyyTQ0B.mjs.map} +1 -1
- package/dist/{runtime-DIZTeGJV.d.cts → runtime-DCkfI2E7.d.mts} +2 -2
- package/dist/{runtime-DIZTeGJV.d.cts.map → runtime-DCkfI2E7.d.mts.map} +1 -1
- package/dist/{runtime-WMLJY-db.d.mts → runtime-Ie4znWIB.d.cts} +2 -2
- package/dist/{runtime-WMLJY-db.d.mts.map → runtime-Ie4znWIB.d.cts.map} +1 -1
- package/dist/{s3-B4FTQQkV.mjs → s3-BZzSnker.mjs} +2 -2
- package/dist/{s3-B4FTQQkV.mjs.map → s3-BZzSnker.mjs.map} +1 -1
- package/dist/{s3-DwKLXwUT.cjs → s3-pqgmCTOq.cjs} +2 -2
- package/dist/{s3-DwKLXwUT.cjs.map → s3-pqgmCTOq.cjs.map} +1 -1
- package/dist/sandbox/credentials-worker.cjs +2 -2
- package/dist/sandbox/credentials-worker.mjs +2 -2
- package/dist/sandbox/discover-worker.cjs +1 -1
- package/dist/sandbox/discover-worker.mjs +1 -1
- package/dist/sandbox/migrate-worker.cjs +1 -1
- package/dist/sandbox/migrate-worker.mjs +1 -1
- package/dist/{seeds-Dv78P9LS.mjs → seeds-CK7w79VC.mjs} +848 -61
- package/dist/seeds-CK7w79VC.mjs.map +1 -0
- package/dist/{seeds-BWC-qjSI.cjs → seeds-CPEcmoPn.cjs} +953 -64
- package/dist/seeds-CPEcmoPn.cjs.map +1 -0
- package/dist/{serverSetup-DB6sKwAy.mjs → serverSetup-BAPNuNEX.mjs} +6 -6
- package/dist/{serverSetup-DB6sKwAy.mjs.map → serverSetup-BAPNuNEX.mjs.map} +1 -1
- package/dist/{serverSetup-CtV80a5M.cjs → serverSetup-C6t6Vtt7.cjs} +6 -6
- package/dist/{serverSetup-CtV80a5M.cjs.map → serverSetup-C6t6Vtt7.cjs.map} +1 -1
- package/dist/{sniffer-ctpwBBkT.cjs → sniffer-DdX_WN_-.cjs} +9 -9
- package/dist/{sniffer-ctpwBBkT.cjs.map → sniffer-DdX_WN_-.cjs.map} +1 -1
- package/dist/{sniffer-qDFUQmWP.mjs → sniffer-g9v7cqDN.mjs} +9 -9
- package/dist/{sniffer-qDFUQmWP.mjs.map → sniffer-g9v7cqDN.mjs.map} +1 -1
- package/dist/{dns-Bmnuttja.cjs → snsSubscriptions-5Cqww8S7.cjs} +351 -3
- package/dist/snsSubscriptions-5Cqww8S7.cjs.map +1 -0
- package/dist/{dns-DFvO5a53.mjs → snsSubscriptions-BmYeeTH8.mjs} +280 -4
- package/dist/snsSubscriptions-BmYeeTH8.mjs.map +1 -0
- package/dist/{sst-C1pxbFEd.mjs → sst-CTqZZl1_.mjs} +3 -4
- package/dist/{sst-C1pxbFEd.mjs.map → sst-CTqZZl1_.mjs.map} +1 -1
- package/dist/{sst-B-Uz4cvm.cjs → sst-lEkBwzGc.cjs} +4 -5
- package/dist/{sst-B-Uz4cvm.cjs.map → sst-lEkBwzGc.cjs.map} +1 -1
- package/dist/{stage-C7lf36az.mjs → stage-C-I2dVw1.mjs} +6 -6
- package/dist/{stage-C7lf36az.mjs.map → stage-C-I2dVw1.mjs.map} +1 -1
- package/dist/{stage-DzALYUwY.cjs → stage-CUE5pMmw.cjs} +7 -7
- package/dist/{stage-DzALYUwY.cjs.map → stage-CUE5pMmw.cjs.map} +1 -1
- package/dist/{stages-B7mCWI_R.cjs → stages-3yUZaZeA.cjs} +2 -2
- package/dist/{stages-B7mCWI_R.cjs.map → stages-3yUZaZeA.cjs.map} +1 -1
- package/dist/{stages-DSltTW2d.mjs → stages-DTTv0NZW.mjs} +2 -2
- package/dist/{stages-DSltTW2d.mjs.map → stages-DTTv0NZW.mjs.map} +1 -1
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.d.cts +2 -2
- package/dist/target/public.d.mts +2 -2
- package/dist/target/public.mjs +1 -1
- package/dist/{terminal-DJlqcW_U.cjs → terminal-PKhPAajN.cjs} +3 -3
- package/dist/{terminal-DJlqcW_U.cjs.map → terminal-PKhPAajN.cjs.map} +1 -1
- package/dist/{terminal-CW_dWeTe.mjs → terminal-bqY33lpN.mjs} +3 -3
- package/dist/{terminal-CW_dWeTe.mjs.map → terminal-bqY33lpN.mjs.map} +1 -1
- package/dist/{types-Q2SC_ly2.d.cts → types-Bmjs4jZV.d.mts} +248 -4
- package/dist/types-Bmjs4jZV.d.mts.map +1 -0
- package/dist/{types-C8gXOLWL.d.mts → types-D0IsQxES.d.cts} +249 -3
- package/dist/types-D0IsQxES.d.cts.map +1 -0
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-DUnnVjqC.mjs → workspace-DBHF9Gba.mjs} +5 -3
- package/dist/workspace-DBHF9Gba.mjs.map +1 -0
- package/dist/{workspace-C82GLPnf.cjs → workspace-Du4Afb03.cjs} +5 -3
- package/dist/workspace-Du4Afb03.cjs.map +1 -0
- package/package.json +17 -15
- package/dist/SubscriberGenerator-C8CPxrCK.cjs.map +0 -1
- package/dist/SubscriberGenerator-y3pncae_.mjs.map +0 -1
- package/dist/compose-ChVvb3xM.cjs.map +0 -1
- package/dist/compose-cHkF---f.mjs.map +0 -1
- package/dist/config-B3iz9BtK.d.cts.map +0 -1
- package/dist/config-DrOX29sT.d.mts.map +0 -1
- package/dist/credentials-B5N5yKk6.mjs.map +0 -1
- package/dist/credentials-Zqr3QQYB.cjs.map +0 -1
- package/dist/deploy-BffR_uEN.cjs.map +0 -1
- package/dist/deploy-DO4djCHb.mjs.map +0 -1
- package/dist/discover-C08meHhu.d.mts +0 -125
- package/dist/discover-C08meHhu.d.mts.map +0 -1
- package/dist/discover-C5roJuc9.mjs.map +0 -1
- package/dist/discover-DipvfWpK.d.cts +0 -125
- package/dist/discover-DipvfWpK.d.cts.map +0 -1
- package/dist/discover-DozUKs8f.cjs.map +0 -1
- package/dist/dns-Bmnuttja.cjs.map +0 -1
- package/dist/dns-DFvO5a53.mjs.map +0 -1
- package/dist/emit-C1e8qD08.mjs.map +0 -1
- package/dist/emit-Dmc1nvdS.cjs.map +0 -1
- package/dist/engine-CTnHmHjz.mjs.map +0 -1
- package/dist/engine-D-jfMVj-.cjs.map +0 -1
- package/dist/github-9RlA7EjN.mjs.map +0 -1
- package/dist/github-D56PSK39.cjs.map +0 -1
- package/dist/run-BJLIerMM.mjs +0 -133
- package/dist/run-BJLIerMM.mjs.map +0 -1
- package/dist/run-fVZ-rLnc.cjs +0 -174
- package/dist/run-fVZ-rLnc.cjs.map +0 -1
- package/dist/sandbox-Co1y2CmF.d.mts +0 -104
- package/dist/sandbox-Co1y2CmF.d.mts.map +0 -1
- package/dist/sandbox-DvNqr6od.d.cts +0 -104
- package/dist/sandbox-DvNqr6od.d.cts.map +0 -1
- package/dist/seeds-BWC-qjSI.cjs.map +0 -1
- package/dist/seeds-Dv78P9LS.mjs.map +0 -1
- package/dist/types-C8gXOLWL.d.mts.map +0 -1
- package/dist/types-Q2SC_ly2.d.cts.map +0 -1
- package/dist/workspace-C82GLPnf.cjs.map +0 -1
- package/dist/workspace-DUnnVjqC.mjs.map +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
2
2
|
const require_errors = require("./errors-DMC4Umsb.cjs");
|
|
3
|
-
const
|
|
4
|
-
const require_workspace = require("./workspace-
|
|
3
|
+
const require_credentials = require("./credentials-D7XJypNd.cjs");
|
|
4
|
+
const require_workspace = require("./workspace-Du4Afb03.cjs");
|
|
5
5
|
const require_derive = require("./derive-DAbo49sm.cjs");
|
|
6
|
-
const require_SubscriberGenerator = require("./SubscriberGenerator-
|
|
6
|
+
const require_SubscriberGenerator = require("./SubscriberGenerator-BDUp7OeY.cjs");
|
|
7
7
|
const require_identity = require("./identity-CbLfgQNT.cjs");
|
|
8
|
-
const require_EndpointGenerator = require("./EndpointGenerator-
|
|
9
|
-
const require_discover = require("./discover-
|
|
8
|
+
const require_EndpointGenerator = require("./EndpointGenerator-BGxf9jWE.cjs");
|
|
9
|
+
const require_discover = require("./discover-DL6h-J97.cjs");
|
|
10
10
|
const require_config = require("./config.cjs");
|
|
11
|
-
const require_resolve = require("./resolve-
|
|
11
|
+
const require_resolve = require("./resolve-C9QqOl5t.cjs");
|
|
12
12
|
let node_path = require("node:path");
|
|
13
13
|
let node_fs = require("node:fs");
|
|
14
14
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -27,6 +27,7 @@ let _geekmidas_cache_postgres = require("@geekmidas/cache/postgres");
|
|
|
27
27
|
let dotenv = require("dotenv");
|
|
28
28
|
let node_util = require("node:util");
|
|
29
29
|
let _geekmidas_constructs_crons = require("@geekmidas/constructs/crons");
|
|
30
|
+
let _geekmidas_constructs_processors = require("@geekmidas/constructs/processors");
|
|
30
31
|
let _geekmidas_constructs_queue = require("@geekmidas/constructs/queue");
|
|
31
32
|
let _aws_sdk_client_s3 = require("@aws-sdk/client-s3");
|
|
32
33
|
let _aws_sdk_client_sns = require("@aws-sdk/client-sns");
|
|
@@ -488,6 +489,21 @@ function volumeOf(container) {
|
|
|
488
489
|
}[container];
|
|
489
490
|
}
|
|
490
491
|
//#endregion
|
|
492
|
+
//#region src/generators/processorRoute.ts
|
|
493
|
+
/**
|
|
494
|
+
* Where `gkm dev` serves a file server's processors, on the dev server of the
|
|
495
|
+
* app holding them: named after the file server.
|
|
496
|
+
*
|
|
497
|
+
* One definition for both sides — the dev server mounts it, and the local
|
|
498
|
+
* edge rewrites each processor pattern on the file server's host onto it — so
|
|
499
|
+
* the path the edge sends and the path the server answers cannot drift.
|
|
500
|
+
*/
|
|
501
|
+
const PROCESSORS_DEV_PREFIX = "/__gkm/processors/";
|
|
502
|
+
/** The base a file server's processors answer under, in `gkm dev`. */
|
|
503
|
+
function processorsDevRoute(fileServerId) {
|
|
504
|
+
return `${PROCESSORS_DEV_PREFIX}${fileServerId}`;
|
|
505
|
+
}
|
|
506
|
+
//#endregion
|
|
491
507
|
//#region src/reconcile/caddyfile.ts
|
|
492
508
|
/**
|
|
493
509
|
* The Caddy configuration a plan implies.
|
|
@@ -537,7 +553,7 @@ const EDGE_KINDS = {
|
|
|
537
553
|
* Docker Desktop resolves this name already; on Linux the compose definition
|
|
538
554
|
* maps it to the host gateway.
|
|
539
555
|
*/
|
|
540
|
-
const HOST_GATEWAY = "host.docker.internal";
|
|
556
|
+
const HOST_GATEWAY$1 = "host.docker.internal";
|
|
541
557
|
/**
|
|
542
558
|
* The suffix every local host shares.
|
|
543
559
|
*
|
|
@@ -554,19 +570,26 @@ const LOCAL_TLD = "localhost";
|
|
|
554
570
|
* are a legitimate arrangement — two cache behaviours, one origin — and naming
|
|
555
571
|
* the host after the bucket would make them collide.
|
|
556
572
|
*/
|
|
557
|
-
function sitesFor(plan, project, addresses = {}) {
|
|
573
|
+
function sitesFor(plan, project, addresses = {}, processorAddresses = {}) {
|
|
558
574
|
const byId = new Map(plan.resources.map((r) => [r.id, r]));
|
|
559
575
|
const sites = [];
|
|
560
576
|
for (const resource of plan.resources) {
|
|
561
577
|
if (!EDGE_KINDS[resource.kind]) continue;
|
|
562
|
-
const host = hostFor(resource, project);
|
|
578
|
+
const host = hostFor$1(resource, project);
|
|
563
579
|
if (resource.kind === "file-server") {
|
|
564
580
|
const origin = resource.of ? byId.get(resource.of) : void 0;
|
|
565
581
|
if (!origin) continue;
|
|
582
|
+
const address = processorAddresses[resource.id];
|
|
583
|
+
const port = address ? portOf(address) : void 0;
|
|
566
584
|
sites.push({
|
|
567
585
|
host,
|
|
568
586
|
upstream: "http://minio:9000",
|
|
569
|
-
rewrite: `/${origin.name}{uri}
|
|
587
|
+
rewrite: `/${origin.name}{uri}`,
|
|
588
|
+
...resource.processors?.length && port ? { processors: {
|
|
589
|
+
prefixes: resource.processors,
|
|
590
|
+
upstream: `http://${HOST_GATEWAY$1}:${port}`,
|
|
591
|
+
under: processorsDevRoute(resource.id)
|
|
592
|
+
} } : {}
|
|
570
593
|
});
|
|
571
594
|
continue;
|
|
572
595
|
}
|
|
@@ -576,7 +599,7 @@ function sitesFor(plan, project, addresses = {}) {
|
|
|
576
599
|
if (!port) continue;
|
|
577
600
|
sites.push({
|
|
578
601
|
host,
|
|
579
|
-
upstream: `http://${HOST_GATEWAY}:${port}`
|
|
602
|
+
upstream: `http://${HOST_GATEWAY$1}:${port}`
|
|
580
603
|
});
|
|
581
604
|
}
|
|
582
605
|
return sites;
|
|
@@ -598,7 +621,7 @@ function portOf(address) {
|
|
|
598
621
|
* name, because an empty label makes `uploads..localhost` — a host nothing
|
|
599
622
|
* resolves and no certificate can be issued for.
|
|
600
623
|
*/
|
|
601
|
-
function hostFor(resource, project) {
|
|
624
|
+
function hostFor$1(resource, project) {
|
|
602
625
|
return [
|
|
603
626
|
resource.root && project ? stageOf(resource) : labelOf(resource),
|
|
604
627
|
project,
|
|
@@ -656,14 +679,24 @@ function toCaddyfile(sites) {
|
|
|
656
679
|
if (sites.length === 0) return `${GENERATED}
|
|
657
680
|
# No file server is declared in this stage, so it routes nothing.
|
|
658
681
|
`;
|
|
659
|
-
const blocks = sites.map(({ host, upstream, rewrite }) => `
|
|
682
|
+
const blocks = sites.map(({ host, upstream, rewrite, processors }) => `
|
|
660
683
|
https://${host} {
|
|
661
684
|
tls internal
|
|
662
685
|
|
|
663
686
|
# gkm's own header, which only a service of this stack may send: the auth
|
|
664
687
|
# server rate-limits by the client address it carries.
|
|
665
688
|
request_header -${_geekmidas_manifest.CLIENT_IP_HEADER}
|
|
666
|
-
|
|
689
|
+
${processors ? `
|
|
690
|
+
# Its processors' patterns, to the dev server holding them — under the
|
|
691
|
+
# route it mounts them on. Answered there, so the bucket below never is.
|
|
692
|
+
@processors path ${processors.prefixes.map((prefix) => `${prefix}*`).join(" ")}
|
|
693
|
+
handle @processors {
|
|
694
|
+
reverse_proxy ${processors.upstream} {
|
|
695
|
+
rewrite ${processors.under}{uri}
|
|
696
|
+
header_up Host {host}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
` : ""}
|
|
667
700
|
reverse_proxy ${upstream} {${rewrite ? `
|
|
668
701
|
rewrite ${rewrite}
|
|
669
702
|
# MinIO routes and signs on the Host header, so forwarding the requested
|
|
@@ -722,6 +755,108 @@ function emulatorQueueUrl(name, port) {
|
|
|
722
755
|
return `${emulatorEndpoint(port)}/${EMULATOR_ACCOUNT}/${name}`;
|
|
723
756
|
}
|
|
724
757
|
//#endregion
|
|
758
|
+
//#region src/reconcile/objectEvents.ts
|
|
759
|
+
/**
|
|
760
|
+
* A bucket's object events, where the bucket is a local MinIO.
|
|
761
|
+
*
|
|
762
|
+
* S3 publishes a bucket's events to a topic the deploy creates; MinIO has no
|
|
763
|
+
* topic to publish to, but it can post each event to a webhook. So where MinIO
|
|
764
|
+
* holds a watched bucket, it posts the bucket's events to the process that
|
|
765
|
+
* runs the bucket's subscribers, on a route only it can use, and that process
|
|
766
|
+
* relays each one onto the events broker — under the bucket's name, as
|
|
767
|
+
* `object.created` or `object.deleted` — where every subscriber drains a queue
|
|
768
|
+
* of its own, as a topic's subscribers do.
|
|
769
|
+
*
|
|
770
|
+
* Declared to MinIO in two halves, both derived here so they cannot drift:
|
|
771
|
+
*
|
|
772
|
+
* - **a webhook target per bucket**, as container environment: where to post,
|
|
773
|
+
* the token to present, and a queue on disk, because MinIO starts before the
|
|
774
|
+
* process it posts to and must keep what it could not deliver;
|
|
775
|
+
* - **the bucket's notification**, written through the S3 API once the bucket
|
|
776
|
+
* exists: every created and removed object, to that target. Unfiltered —
|
|
777
|
+
* two subscribers watching overlapping prefixes are two rules S3 refuses on
|
|
778
|
+
* one bucket, and each subscriber filters what it is handed anyway.
|
|
779
|
+
*/
|
|
780
|
+
/**
|
|
781
|
+
* The token MinIO presents when it posts a bucket's events.
|
|
782
|
+
*
|
|
783
|
+
* Derived, never stored: the container and the process it posts to are handed
|
|
784
|
+
* the same value by the same derivation — with the stage's random seed where a
|
|
785
|
+
* deployed stage's stack has one, so the token is a secret there, and from the
|
|
786
|
+
* project alone locally, where everything it would protect is on loopback.
|
|
787
|
+
* Not salted by the stage: one MinIO serves `gkm dev` and `gkm test`, and a
|
|
788
|
+
* target is declared once per container.
|
|
789
|
+
*/
|
|
790
|
+
function objectsWebhookToken(project, bucket, seed) {
|
|
791
|
+
return (0, node_crypto.createHash)("sha256").update(`${seed ? `${seed}:` : ""}${project}:objects-webhook:${bucket}`).digest("base64url").slice(0, 32);
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* The target's id in MinIO's environment — `MINIO_NOTIFY_WEBHOOK_*_<ID>`.
|
|
795
|
+
*
|
|
796
|
+
* Upper-cased with nothing between words: a canonical id is letters and
|
|
797
|
+
* digits, and an underscore inside the id would read as part of the setting's
|
|
798
|
+
* name.
|
|
799
|
+
*/
|
|
800
|
+
function minioTargetId(bucket) {
|
|
801
|
+
return bucket.toUpperCase();
|
|
802
|
+
}
|
|
803
|
+
/** The target as a notification names it. */
|
|
804
|
+
function minioTargetArn(bucket) {
|
|
805
|
+
return `arn:minio:sqs::${minioTargetId(bucket)}:webhook`;
|
|
806
|
+
}
|
|
807
|
+
/** How a container reaches a process on the host. */
|
|
808
|
+
const HOST_GATEWAY = "host.docker.internal";
|
|
809
|
+
/** Where MinIO keeps what it could not deliver yet, inside its container. */
|
|
810
|
+
const QUEUE_ROOT = "/gkm-object-events";
|
|
811
|
+
/** The id of the notification rule gkm owns on a bucket. */
|
|
812
|
+
const NOTIFICATION_RULE_PREFIX = "gkm-";
|
|
813
|
+
/**
|
|
814
|
+
* MinIO's environment for each watched bucket's webhook target.
|
|
815
|
+
*
|
|
816
|
+
* Sorted, so the same buckets always render the same environment and a
|
|
817
|
+
* reconcile that changed nothing does not recreate the container.
|
|
818
|
+
*/
|
|
819
|
+
function minioWebhookEnv(hooks) {
|
|
820
|
+
const env = {};
|
|
821
|
+
for (const hook of [...hooks].sort((a, b) => a.bucket.localeCompare(b.bucket))) {
|
|
822
|
+
const id = minioTargetId(hook.bucket);
|
|
823
|
+
env[`MINIO_NOTIFY_WEBHOOK_ENABLE_${id}`] = "on";
|
|
824
|
+
env[`MINIO_NOTIFY_WEBHOOK_ENDPOINT_${id}`] = hook.endpoint;
|
|
825
|
+
env[`MINIO_NOTIFY_WEBHOOK_AUTH_TOKEN_${id}`] = hook.token;
|
|
826
|
+
env[`MINIO_NOTIFY_WEBHOOK_QUEUE_DIR_${id}`] = `${QUEUE_ROOT}/${id.toLowerCase()}`;
|
|
827
|
+
}
|
|
828
|
+
return env;
|
|
829
|
+
}
|
|
830
|
+
/** The rule that sends every created and removed object to the bucket's target. */
|
|
831
|
+
function minioNotificationRule(bucket) {
|
|
832
|
+
return {
|
|
833
|
+
Id: `${NOTIFICATION_RULE_PREFIX}${bucket}`,
|
|
834
|
+
QueueArn: minioTargetArn(bucket),
|
|
835
|
+
Events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"]
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* Each watched bucket, and the workers that run one of its subscribers.
|
|
840
|
+
*
|
|
841
|
+
* A bucket is watched when a subscriber reads its events key. MinIO posts a
|
|
842
|
+
* bucket's events to one place, and the relay fans them out to every
|
|
843
|
+
* subscriber whichever worker received them — so one worker per bucket is
|
|
844
|
+
* enough, and the first, by id, is the one chosen, so the choice is stable.
|
|
845
|
+
*/
|
|
846
|
+
function watchedBuckets(manifest, subscribers) {
|
|
847
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
848
|
+
for (const declaration of Object.values(manifest)) {
|
|
849
|
+
if (declaration.kind !== "objects") continue;
|
|
850
|
+
byKey.set((0, _geekmidas_manifest.provideKey)(declaration.id, "eventsConnectionString"), declaration.id);
|
|
851
|
+
}
|
|
852
|
+
const watched = /* @__PURE__ */ new Map();
|
|
853
|
+
for (const worker of Object.keys(subscribers).sort()) for (const { connectionKey } of subscribers[worker] ?? []) {
|
|
854
|
+
const bucket = byKey.get(connectionKey);
|
|
855
|
+
if (bucket && !watched.has(bucket)) watched.set(bucket, worker);
|
|
856
|
+
}
|
|
857
|
+
return watched;
|
|
858
|
+
}
|
|
859
|
+
//#endregion
|
|
725
860
|
//#region src/telemetry/edges.ts
|
|
726
861
|
/**
|
|
727
862
|
* Which processes use a `Telemetry` node — read off the manifest's edges.
|
|
@@ -746,13 +881,14 @@ function nodeOf(manifest, id) {
|
|
|
746
881
|
return node?.kind === "telemetry" ? node : void 0;
|
|
747
882
|
}
|
|
748
883
|
/**
|
|
749
|
-
* The `Telemetry` node the process for `id` — a surface
|
|
750
|
-
* construct id — emits through, or undefined
|
|
884
|
+
* The `Telemetry` node the process for `id` — a surface, a worker, or a file
|
|
885
|
+
* server's processor unit, by construct id — emits through, or undefined
|
|
886
|
+
* when it has no edge to one.
|
|
751
887
|
*/
|
|
752
888
|
function telemetryOf(manifest, id) {
|
|
753
889
|
const declaration = manifest[id];
|
|
754
890
|
if (!declaration) return void 0;
|
|
755
|
-
if (declaration.kind === "worker") return nodeOf(manifest, declaration.telemetry);
|
|
891
|
+
if (declaration.kind === "worker" || declaration.kind === "file-server") return nodeOf(manifest, declaration.telemetry);
|
|
756
892
|
if (declaration.kind !== "rest-api") return void 0;
|
|
757
893
|
return nodeOf(manifest, declaration.telemetry);
|
|
758
894
|
}
|
|
@@ -766,7 +902,7 @@ function appTelemetry(manifest, appName) {
|
|
|
766
902
|
}
|
|
767
903
|
/** Whether any process in the manifest emits through a `Telemetry` node. */
|
|
768
904
|
function usesTelemetry(manifest) {
|
|
769
|
-
return Object.entries(manifest).some(([id, d]) => (d.kind === "rest-api" || d.kind === "worker") && telemetryOf(manifest, id) !== void 0);
|
|
905
|
+
return Object.entries(manifest).some(([id, d]) => (d.kind === "rest-api" || d.kind === "worker" || d.kind === "file-server") && telemetryOf(manifest, id) !== void 0);
|
|
770
906
|
}
|
|
771
907
|
/**
|
|
772
908
|
* One process's share of the telemetry keys a stage resolved: all of them,
|
|
@@ -1027,7 +1163,8 @@ function planFor(manifest, stage, order, options = {}) {
|
|
|
1027
1163
|
...declaration.scheme ? { scheme: declaration.scheme } : {}
|
|
1028
1164
|
} : {},
|
|
1029
1165
|
...declaration.kind === "file-server" && declaration.open?.length ? { open: declaration.open } : {},
|
|
1030
|
-
...declaration.kind === "
|
|
1166
|
+
...declaration.kind === "file-server" && declaration.processors?.length ? { processors: [...new Set(declaration.processors.map((p) => p.prefix))].sort() } : {},
|
|
1167
|
+
...declaration.kind === "objects" && (0, _geekmidas_manifest.bucketExpiry)(manifest, id) ? { expire: (0, _geekmidas_manifest.bucketExpiry)(manifest, id) } : {},
|
|
1031
1168
|
...(declaration.kind === "rest-api" || declaration.kind === "site") && declaration.subdomain ? { subdomain: declaration.subdomain } : {},
|
|
1032
1169
|
...fake ? { fake: {
|
|
1033
1170
|
key: fake.key,
|
|
@@ -1217,6 +1354,14 @@ function envFor(plan, options) {
|
|
|
1217
1354
|
}
|
|
1218
1355
|
Object.assign(env, publicEnv(plan, env, options.addresses));
|
|
1219
1356
|
Object.assign(env, brokerEnv(plan, options.ports, credential));
|
|
1357
|
+
const relay = env.EVENT_PUBLISHER_CONNECTION_STRING;
|
|
1358
|
+
if (relay && options.relayedBuckets?.length) for (const resource of plan.resources) {
|
|
1359
|
+
if (resource.kind !== "objects" || resource.container !== "minio") continue;
|
|
1360
|
+
if (!options.relayedBuckets.includes(resource.id)) continue;
|
|
1361
|
+
if (!env[resource.envKey]) continue;
|
|
1362
|
+
env[(0, _geekmidas_manifest.provideKey)(resource.id, "eventsConnectionString")] = relay;
|
|
1363
|
+
env[(0, _geekmidas_manifest.provideKey)(resource.id, "eventsToken")] = objectsWebhookToken(options.project ?? "", resource.id, credential.seed);
|
|
1364
|
+
}
|
|
1220
1365
|
if (plan.resources.some((r) => r.kind === "objects" && env[r.envKey])) Object.assign(env, storageCredentials(options.credentials));
|
|
1221
1366
|
return env;
|
|
1222
1367
|
}
|
|
@@ -1368,7 +1513,7 @@ function urlFor(resource, plan, ports, project, addresses, credential) {
|
|
|
1368
1513
|
if (resource.kind === "rest-api" || resource.kind === "site") {
|
|
1369
1514
|
const address = addresses?.[resource.id];
|
|
1370
1515
|
const edge = plan.containers.includes("caddy") ? ports[primaryPortKey("caddy")] : void 0;
|
|
1371
|
-
return address && edge !== void 0 ? `https://${hostFor(resource, project)}:${edge}` : address;
|
|
1516
|
+
return address && edge !== void 0 ? `https://${hostFor$1(resource, project)}:${edge}` : address;
|
|
1372
1517
|
}
|
|
1373
1518
|
if (!resource.container) return void 0;
|
|
1374
1519
|
const port = ports[primaryPortKey(resource.container)];
|
|
@@ -1395,7 +1540,7 @@ function urlFor(resource, plan, ports, project, addresses, credential) {
|
|
|
1395
1540
|
case "file-server": {
|
|
1396
1541
|
const origin = plan.resources.find((r) => r.id === resource.of);
|
|
1397
1542
|
if (!origin) return void 0;
|
|
1398
|
-
return plan.containers.includes("caddy") ? `https://${hostFor(resource, project)}:${port}` : `http://${LOCAL_HOST}:${port}/${origin.name}`;
|
|
1543
|
+
return plan.containers.includes("caddy") ? `https://${hostFor$1(resource, project)}:${port}` : `http://${LOCAL_HOST}:${port}/${origin.name}`;
|
|
1399
1544
|
}
|
|
1400
1545
|
case "cache":
|
|
1401
1546
|
if (resource.of) {
|
|
@@ -1869,7 +2014,7 @@ function folderName(path) {
|
|
|
1869
2014
|
function getKeystoreDir(project) {
|
|
1870
2015
|
if (!PROJECT_KEY.test(project.key)) throw new KeystoreProjectInvalid(project.key);
|
|
1871
2016
|
const [namespace, name] = project.key.split("/");
|
|
1872
|
-
return (0, node_path.join)(project.home ??
|
|
2017
|
+
return (0, node_path.join)(project.home ?? require_credentials.gkmHome(), "keys", namespace, name);
|
|
1873
2018
|
}
|
|
1874
2019
|
/** Get the path to a stage's encryption key. */
|
|
1875
2020
|
function getKeyPath(stage, project) {
|
|
@@ -1886,7 +2031,7 @@ function legacyKeyPaths(stage, project) {
|
|
|
1886
2031
|
key,
|
|
1887
2032
|
home: project.home
|
|
1888
2033
|
}));
|
|
1889
|
-
const homes = [.../* @__PURE__ */ new Set([project.home ??
|
|
2034
|
+
const homes = [.../* @__PURE__ */ new Set([project.home ?? require_credentials.gkmHome(), (0, node_path.join)((0, node_os.homedir)(), ".gkm")])];
|
|
1890
2035
|
const names = (project.legacy ?? []).filter(isLegacyName);
|
|
1891
2036
|
return [...aliases, ...names.flatMap((name) => homes.map((home) => (0, node_path.join)(home, name, `${stage}.key`)))];
|
|
1892
2037
|
}
|
|
@@ -2140,7 +2285,7 @@ function localCredentialsPath(project) {
|
|
|
2140
2285
|
const keys = getKeystoreDir(project);
|
|
2141
2286
|
const name = keys.split(/[\\/]/).at(-1);
|
|
2142
2287
|
const namespace = keys.split(/[\\/]/).at(-2);
|
|
2143
|
-
return (0, node_path.join)(project.home ??
|
|
2288
|
+
return (0, node_path.join)(project.home ?? require_credentials.gkmHome(), "local", namespace, `${name}.json`);
|
|
2144
2289
|
}
|
|
2145
2290
|
/** The local stage's logins file is there, and its key is not. */
|
|
2146
2291
|
var LocalCredentialsKeyMissing = class extends require_errors.GkmError {
|
|
@@ -2584,6 +2729,56 @@ async function databasesExist(client, names) {
|
|
|
2584
2729
|
}
|
|
2585
2730
|
}
|
|
2586
2731
|
/**
|
|
2732
|
+
* Point each watched bucket's events at its webhook target, and stop sending
|
|
2733
|
+
* an unwatched one's.
|
|
2734
|
+
*
|
|
2735
|
+
* Merged rather than written whole: only the rule gkm owns on a bucket
|
|
2736
|
+
* (`gkm-<Bucket>`) is added or removed, and every other rule — one somebody
|
|
2737
|
+
* added by hand — is kept. Compared before writing, so a converged reconcile
|
|
2738
|
+
* changes nothing.
|
|
2739
|
+
*
|
|
2740
|
+
* @param buckets - each bucket the plan names, by construct id and name
|
|
2741
|
+
* @param watched - the construct ids whose events are relayed
|
|
2742
|
+
*/
|
|
2743
|
+
async function applyNotifications(client, buckets, watched) {
|
|
2744
|
+
const applied = [];
|
|
2745
|
+
for (const { id, name } of buckets) {
|
|
2746
|
+
const current = await client.notification(name);
|
|
2747
|
+
const queues = current.QueueConfigurations ?? [];
|
|
2748
|
+
const others = queues.filter((rule) => !rule.Id?.startsWith(NOTIFICATION_RULE_PREFIX));
|
|
2749
|
+
const wanted = watched.has(id) ? [...others, minioNotificationRule(id)] : others;
|
|
2750
|
+
if (!watched.has(id) && others.length === queues.length) continue;
|
|
2751
|
+
const describe = `object events from ${name}`;
|
|
2752
|
+
const ours = queues.filter((rule) => rule.Id?.startsWith(NOTIFICATION_RULE_PREFIX));
|
|
2753
|
+
if (watched.has(id) ? ours.length === 1 && sameRule(ours[0], minioNotificationRule(id)) : ours.length === 0) {
|
|
2754
|
+
applied.push({
|
|
2755
|
+
id: `${name}:events`,
|
|
2756
|
+
describe,
|
|
2757
|
+
created: false
|
|
2758
|
+
});
|
|
2759
|
+
continue;
|
|
2760
|
+
}
|
|
2761
|
+
await client.setNotification(name, {
|
|
2762
|
+
...current,
|
|
2763
|
+
QueueConfigurations: wanted
|
|
2764
|
+
});
|
|
2765
|
+
applied.push({
|
|
2766
|
+
id: `${name}:events`,
|
|
2767
|
+
describe,
|
|
2768
|
+
created: true
|
|
2769
|
+
});
|
|
2770
|
+
}
|
|
2771
|
+
return applied;
|
|
2772
|
+
}
|
|
2773
|
+
/**
|
|
2774
|
+
* Whether a rule read back says what gkm wrote: the same target, the same
|
|
2775
|
+
* events in any order, and no filter — the store may hand back an empty one.
|
|
2776
|
+
*/
|
|
2777
|
+
function sameRule(current, wanted) {
|
|
2778
|
+
const filter = current.Filter;
|
|
2779
|
+
return current.Id === wanted.Id && current.QueueArn === wanted.QueueArn && JSON.stringify([...current.Events ?? []].sort()) === JSON.stringify([...wanted.Events ?? []].sort()) && (filter?.Key?.FilterRules?.length ?? 0) === 0;
|
|
2780
|
+
}
|
|
2781
|
+
/**
|
|
2587
2782
|
* Apply each bucket's expiry, beside whatever other rules it has, skipping
|
|
2588
2783
|
* those already correct — the same merge the `s3` provider makes deployed.
|
|
2589
2784
|
*/
|
|
@@ -2705,14 +2900,7 @@ var WorkerNameTaken = class extends require_errors.GkmError {
|
|
|
2705
2900
|
* @param background Each worker's files, from discovery's `background`.
|
|
2706
2901
|
*/
|
|
2707
2902
|
function workerUnits(workspace, manifest, background) {
|
|
2708
|
-
const hosts =
|
|
2709
|
-
const surface = Object.entries(manifest).find(([id, d]) => d.kind === "rest-api" && require_derive.appKey(id) === name)?.[1];
|
|
2710
|
-
return {
|
|
2711
|
-
name,
|
|
2712
|
-
root: (0, node_path.isAbsolute)(app.path) ? app.path : (0, node_path.join)(workspace.root, app.path),
|
|
2713
|
-
generated: !(surface?.kind === "rest-api" && surface.endpoints.length > 0)
|
|
2714
|
-
};
|
|
2715
|
-
}).sort((a, b) => a.name.localeCompare(b.name));
|
|
2903
|
+
const hosts = hostApps(workspace, manifest);
|
|
2716
2904
|
const units = [];
|
|
2717
2905
|
for (const [id, declaration] of Object.entries(manifest)) {
|
|
2718
2906
|
if (declaration.kind !== "worker") continue;
|
|
@@ -2720,12 +2908,8 @@ function workerUnits(workspace, manifest, background) {
|
|
|
2720
2908
|
if (files.length === 0) continue;
|
|
2721
2909
|
const name = require_derive.appKey(id);
|
|
2722
2910
|
if (workspace.apps[name]) throw new WorkerNameTaken(id, name);
|
|
2723
|
-
const
|
|
2724
|
-
|
|
2725
|
-
holds: files.filter((file) => isUnder(file, host.root)).length
|
|
2726
|
-
})).sort((a, b) => b.holds - a.holds || Number(b.host.generated) - Number(a.host.generated));
|
|
2727
|
-
const host = ranked[0]?.host;
|
|
2728
|
-
if (!host || ranked[0].holds === 0 && !host.generated) throw new WorkerHasNoApp(id);
|
|
2911
|
+
const host = hostFor(hosts, files);
|
|
2912
|
+
if (!host) throw new WorkerHasNoApp(id);
|
|
2729
2913
|
units.push({
|
|
2730
2914
|
id,
|
|
2731
2915
|
name,
|
|
@@ -2734,6 +2918,70 @@ function workerUnits(workspace, manifest, background) {
|
|
|
2734
2918
|
}
|
|
2735
2919
|
return units.sort((a, b) => a.name.localeCompare(b.name));
|
|
2736
2920
|
}
|
|
2921
|
+
/** The service and image name of a file server's processors: `assets-processors`. */
|
|
2922
|
+
function processorUnitName(fileServerId) {
|
|
2923
|
+
return `${require_derive.appKey(fileServerId.replace(/Server$/, ""))}-processors`;
|
|
2924
|
+
}
|
|
2925
|
+
/** A file server with processors and no backend app to build them from. */
|
|
2926
|
+
var ProcessorsHaveNoApp = class extends require_errors.GkmError {
|
|
2927
|
+
fileServer;
|
|
2928
|
+
constructor(fileServer) {
|
|
2929
|
+
super(`The file server '${fileServer}' has processors, and the workspace has no backend app that builds a server to carry their entry. Declare a RestApi whose app holds the processors' code.`);
|
|
2930
|
+
this.fileServer = fileServer;
|
|
2931
|
+
this.name = "ProcessorsHaveNoApp";
|
|
2932
|
+
}
|
|
2933
|
+
};
|
|
2934
|
+
/**
|
|
2935
|
+
* The processor units a workspace deploys — each file server with processors
|
|
2936
|
+
* — and the app each is built from, chosen as a worker's is: the backend app
|
|
2937
|
+
* holding the most of its processors' files.
|
|
2938
|
+
*/
|
|
2939
|
+
function processorUnits(workspace, manifest) {
|
|
2940
|
+
const hosts = hostApps(workspace, manifest);
|
|
2941
|
+
const units = [];
|
|
2942
|
+
for (const declaration of Object.values(manifest)) {
|
|
2943
|
+
if (declaration.kind !== "file-server") continue;
|
|
2944
|
+
const processors = declaration.processors ?? [];
|
|
2945
|
+
if (processors.length === 0) continue;
|
|
2946
|
+
const host = hostFor(hosts, processors.map(({ handler }) => {
|
|
2947
|
+
const file = handler.split("#")[0] ?? handler;
|
|
2948
|
+
return (0, node_path.isAbsolute)(file) ? file : (0, node_path.join)(workspace.root, file);
|
|
2949
|
+
}));
|
|
2950
|
+
if (!host) throw new ProcessorsHaveNoApp(declaration.id);
|
|
2951
|
+
const name = processorUnitName(declaration.id);
|
|
2952
|
+
if (workspace.apps[name]) throw new WorkerNameTaken(declaration.id, name);
|
|
2953
|
+
units.push({
|
|
2954
|
+
id: declaration.id,
|
|
2955
|
+
name,
|
|
2956
|
+
app: host.name
|
|
2957
|
+
});
|
|
2958
|
+
}
|
|
2959
|
+
return units.sort((a, b) => a.name.localeCompare(b.name));
|
|
2960
|
+
}
|
|
2961
|
+
/** The backend apps whose builds generate a server, each where it lives. */
|
|
2962
|
+
function hostApps(workspace, manifest) {
|
|
2963
|
+
return Object.entries(workspace.apps).filter(([, app]) => app.type === "backend" && !app.entry).map(([name, app]) => {
|
|
2964
|
+
const surface = Object.entries(manifest).find(([id, d]) => d.kind === "rest-api" && require_derive.appKey(id) === name)?.[1];
|
|
2965
|
+
return {
|
|
2966
|
+
name,
|
|
2967
|
+
root: (0, node_path.isAbsolute)(app.path) ? app.path : (0, node_path.join)(workspace.root, app.path),
|
|
2968
|
+
generated: !(surface?.kind === "rest-api" && surface.endpoints.length > 0)
|
|
2969
|
+
};
|
|
2970
|
+
}).sort((a, b) => a.name.localeCompare(b.name));
|
|
2971
|
+
}
|
|
2972
|
+
/**
|
|
2973
|
+
* The app holding the most of these files; then one that generates a server;
|
|
2974
|
+
* then by name. None when no app holds any and none generates a server.
|
|
2975
|
+
*/
|
|
2976
|
+
function hostFor(hosts, files) {
|
|
2977
|
+
const ranked = hosts.map((host) => ({
|
|
2978
|
+
host,
|
|
2979
|
+
holds: files.filter((file) => isUnder(file, host.root)).length
|
|
2980
|
+
})).sort((a, b) => b.holds - a.holds || Number(b.host.generated) - Number(a.host.generated));
|
|
2981
|
+
const host = ranked[0]?.host;
|
|
2982
|
+
if (!host || ranked[0].holds === 0 && !host.generated) return void 0;
|
|
2983
|
+
return host;
|
|
2984
|
+
}
|
|
2737
2985
|
/** Whether `file` is inside `dir`. */
|
|
2738
2986
|
function isUnder(file, dir) {
|
|
2739
2987
|
const rel = (0, node_path.relative)(dir, file);
|
|
@@ -3383,6 +3631,8 @@ function generateBackendDockerfile(options) {
|
|
|
3383
3631
|
}
|
|
3384
3632
|
/** The port a worker answers its health check on, inside its container. */
|
|
3385
3633
|
const WORKER_PORT = 3e3;
|
|
3634
|
+
/** The port a processor unit answers on, inside its container. */
|
|
3635
|
+
const PROCESSOR_PORT = 3e3;
|
|
3386
3636
|
/**
|
|
3387
3637
|
* A Worker's image: the same build as its host app's backend — a pruned
|
|
3388
3638
|
* slice, `gkm build --provider server --production` in the image, with the
|
|
@@ -3399,6 +3649,19 @@ function generateWorkerDockerfile(options) {
|
|
|
3399
3649
|
expose: false
|
|
3400
3650
|
});
|
|
3401
3651
|
}
|
|
3652
|
+
/**
|
|
3653
|
+
* A file server's processor unit: its host app's build, and the unit's bundle
|
|
3654
|
+
* as the runner. Its native packages — `sharp` — are installed for the image's
|
|
3655
|
+
* platform beside the bundle, at the versions the build resolved.
|
|
3656
|
+
*/
|
|
3657
|
+
function generateProcessorDockerfile(options) {
|
|
3658
|
+
return gkmBundleDockerfile(options, {
|
|
3659
|
+
title: `Processors Dockerfile (${options.fileServer})`,
|
|
3660
|
+
bundle: options.bundle,
|
|
3661
|
+
as: "processors.mjs",
|
|
3662
|
+
expose: true
|
|
3663
|
+
});
|
|
3664
|
+
}
|
|
3402
3665
|
function gkmBundleDockerfile(options, runner) {
|
|
3403
3666
|
const { port, healthCheckPath = "/health" } = options;
|
|
3404
3667
|
const { app } = layout(options);
|
|
@@ -3425,7 +3688,7 @@ RUN apk add --no-cache tini
|
|
|
3425
3688
|
RUN addgroup --system --gid 1001 nodejs && \\
|
|
3426
3689
|
adduser --system --uid 1001 hono
|
|
3427
3690
|
|
|
3428
|
-
# The bundled ${runner.as
|
|
3691
|
+
# The bundled ${runner.as.replace(/\.mjs$/, "")}
|
|
3429
3692
|
COPY --from=builder --chown=hono:nodejs ${app}/.gkm/server/dist/${runner.bundle} ./${runner.as === runner.bundle ? "" : runner.as}${externals.copy}
|
|
3430
3693
|
|
|
3431
3694
|
ENV NODE_ENV=production
|
|
@@ -3917,7 +4180,7 @@ async function storeFromConfig(workspace, config, options = {}) {
|
|
|
3917
4180
|
const profile = options.profile ? { profile: options.profile } : {};
|
|
3918
4181
|
switch (config.provider) {
|
|
3919
4182
|
case "s3": {
|
|
3920
|
-
const { S3SecretsStore } = await Promise.resolve().then(() => require("./s3-
|
|
4183
|
+
const { S3SecretsStore } = await Promise.resolve().then(() => require("./s3-pqgmCTOq.cjs"));
|
|
3921
4184
|
const { deployIdentity } = await Promise.resolve().then(() => require("./identity-CbLfgQNT.cjs")).then((n) => n.identity_exports);
|
|
3922
4185
|
const location = require_workspace.s3SecretsLocation(config, workspace.state);
|
|
3923
4186
|
return new S3SecretsStore({
|
|
@@ -4291,6 +4554,14 @@ function composeFor(plan, options) {
|
|
|
4291
4554
|
const volume = volumeOf(container);
|
|
4292
4555
|
if (volume) volumes[volume] = {};
|
|
4293
4556
|
}
|
|
4557
|
+
const minio = services.minio;
|
|
4558
|
+
if (minio && options.objectWebhooks?.length) {
|
|
4559
|
+
minio.environment = {
|
|
4560
|
+
...minio.environment,
|
|
4561
|
+
...minioWebhookEnv(options.objectWebhooks)
|
|
4562
|
+
};
|
|
4563
|
+
if (options.objectWebhooks.some((hook) => hook.endpoint.includes(`//host.docker.internal:`))) minio.extra_hosts = [`${HOST_GATEWAY}:host-gateway`];
|
|
4564
|
+
}
|
|
4294
4565
|
return {
|
|
4295
4566
|
name: options.project,
|
|
4296
4567
|
services: {
|
|
@@ -4664,6 +4935,16 @@ function bucketClient(port, credentials) {
|
|
|
4664
4935
|
Bucket: bucket,
|
|
4665
4936
|
LifecycleConfiguration: { Rules: rules }
|
|
4666
4937
|
}));
|
|
4938
|
+
},
|
|
4939
|
+
async notification(bucket) {
|
|
4940
|
+
const { $metadata: _, ...notification } = await s3.send(new _aws_sdk_client_s3.GetBucketNotificationConfigurationCommand({ Bucket: bucket }));
|
|
4941
|
+
return notification;
|
|
4942
|
+
},
|
|
4943
|
+
async setNotification(bucket, notification) {
|
|
4944
|
+
await s3.send(new _aws_sdk_client_s3.PutBucketNotificationConfigurationCommand({
|
|
4945
|
+
Bucket: bucket,
|
|
4946
|
+
NotificationConfiguration: notification
|
|
4947
|
+
}));
|
|
4667
4948
|
}
|
|
4668
4949
|
};
|
|
4669
4950
|
}
|
|
@@ -5500,9 +5781,10 @@ async function reconcile(options) {
|
|
|
5500
5781
|
project,
|
|
5501
5782
|
ports,
|
|
5502
5783
|
credentials: options.credentials,
|
|
5503
|
-
...options.apps ? { apps: options.apps(plan.containers) } : {}
|
|
5784
|
+
...options.apps ? { apps: options.apps(plan.containers) } : {},
|
|
5785
|
+
...options.objectWebhooks?.length ? { objectWebhooks: options.objectWebhooks } : {}
|
|
5504
5786
|
});
|
|
5505
|
-
const caddyfile = toCaddyfile(sitesFor(plan, project, options.addresses));
|
|
5787
|
+
const caddyfile = toCaddyfile(sitesFor(plan, project, options.addresses, options.processorAddresses));
|
|
5506
5788
|
const hash = planHash(plan, compose, {
|
|
5507
5789
|
caddyfile,
|
|
5508
5790
|
postgres: postgresStatements(plan, project, seed).map((statement) => statement.create).join(";\n")
|
|
@@ -5518,7 +5800,8 @@ async function reconcile(options) {
|
|
|
5518
5800
|
...options.mailFrom ? { mailFrom: options.mailFrom } : {},
|
|
5519
5801
|
...options.addresses ? { addresses: options.addresses } : {},
|
|
5520
5802
|
...lan ? { lanAddress: lan } : {},
|
|
5521
|
-
...options.metroPorts ? { metroPorts: options.metroPorts } : {}
|
|
5803
|
+
...options.metroPorts ? { metroPorts: options.metroPorts } : {},
|
|
5804
|
+
...options.objectWebhooks?.length ? { relayedBuckets: options.objectWebhooks.map((hook) => hook.bucket) } : {}
|
|
5522
5805
|
});
|
|
5523
5806
|
const env = exports ? resolved : scopeTelemetryEnv(resolved, {
|
|
5524
5807
|
uses: false,
|
|
@@ -5575,7 +5858,7 @@ async function reconcile(options) {
|
|
|
5575
5858
|
};
|
|
5576
5859
|
const credentials = checked.credentials;
|
|
5577
5860
|
if (start && provision) options.progress?.("🗄️ Creating what the constructs declare — databases, roles, buckets, topics");
|
|
5578
|
-
const provisioned = start && provision ? await create(plan, ports, credentials, sql, buckets, carriers, project) : [];
|
|
5861
|
+
const provisioned = start && provision ? await create(plan, ports, credentials, sql, buckets, carriers, project, new Set(stage === (options.localStage ?? stage) ? (options.objectWebhooks ?? []).map((hook) => hook.bucket) : [])) : [];
|
|
5579
5862
|
await saveState(root, {
|
|
5580
5863
|
hash,
|
|
5581
5864
|
stage
|
|
@@ -5595,7 +5878,7 @@ async function reconcile(options) {
|
|
|
5595
5878
|
* Idempotent throughout, so this runs on every non-converged reconcile rather
|
|
5596
5879
|
* than being something to remember.
|
|
5597
5880
|
*/
|
|
5598
|
-
async function create(plan, ports, credentials, sql, buckets, emulatorCarriers, project) {
|
|
5881
|
+
async function create(plan, ports, credentials, sql, buckets, emulatorCarriers, project, watched) {
|
|
5599
5882
|
const applied = [];
|
|
5600
5883
|
const postgresPort = ports[primaryPortKey("postgres")];
|
|
5601
5884
|
const statements = postgresStatements(plan, project, credentials.seed);
|
|
@@ -5609,6 +5892,10 @@ async function create(plan, ports, credentials, sql, buckets, emulatorCarriers,
|
|
|
5609
5892
|
if (names.length > 0) applied.push(...await applyBuckets(client, names));
|
|
5610
5893
|
if (policies.length > 0) applied.push(...await applyPolicies(client, policies));
|
|
5611
5894
|
if (lifecycles.length > 0) applied.push(...await applyLifecycles(client, lifecycles));
|
|
5895
|
+
if (names.length > 0) applied.push(...await applyNotifications(client, plan.resources.filter((r) => r.provisions && r.kind === "objects").map((r) => ({
|
|
5896
|
+
id: r.id,
|
|
5897
|
+
name: r.name
|
|
5898
|
+
})), watched));
|
|
5612
5899
|
}
|
|
5613
5900
|
const emulatorPort = ports[primaryPortKey("localstack")];
|
|
5614
5901
|
const carriers = carrierNames(plan);
|
|
@@ -5674,7 +5961,9 @@ var workspace_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
|
5674
5961
|
constructGlobs: () => constructGlobs,
|
|
5675
5962
|
derivedContainers: () => derivedContainers,
|
|
5676
5963
|
fakesApply: () => fakesApply,
|
|
5964
|
+
localObjectWebhooks: () => localObjectWebhooks,
|
|
5677
5965
|
metroPorts: () => metroPorts,
|
|
5966
|
+
processorAddresses: () => processorAddresses,
|
|
5678
5967
|
reconcileWorkspace: () => reconcileWorkspace,
|
|
5679
5968
|
surfaceAddresses: () => surfaceAddresses
|
|
5680
5969
|
});
|
|
@@ -5737,16 +6026,25 @@ function fakesApply(stage, fake, env = process.env) {
|
|
|
5737
6026
|
*/
|
|
5738
6027
|
async function reconcileWorkspace(workspace, options) {
|
|
5739
6028
|
const runnables = {};
|
|
6029
|
+
const background = {};
|
|
6030
|
+
const subscribers = {};
|
|
5740
6031
|
const discovered = await require_discover.discover({
|
|
5741
6032
|
patterns: constructGlobs(workspace),
|
|
5742
6033
|
cwd: workspace.root,
|
|
5743
|
-
runnables
|
|
6034
|
+
runnables,
|
|
6035
|
+
background,
|
|
6036
|
+
subscribers
|
|
5744
6037
|
});
|
|
5745
6038
|
const manifest = options.manifest ?? discovered;
|
|
5746
6039
|
const faked = fakesApply(options.stage, options.fake);
|
|
5747
6040
|
const fakes = faked ? await require_SubscriberGenerator.readFakes(workspace.root, manifest) : {};
|
|
5748
6041
|
const credentialFakes = faked ? await require_SubscriberGenerator.readCredentialFakes(workspace.root, manifest) : {};
|
|
5749
6042
|
const { credentials } = await loadLocalCredentials(workspace);
|
|
6043
|
+
const objectWebhooks = localObjectWebhooks(workspace, manifest, {
|
|
6044
|
+
background,
|
|
6045
|
+
subscribers,
|
|
6046
|
+
seed: credentials.seed
|
|
6047
|
+
});
|
|
5750
6048
|
const result = await reconcile({
|
|
5751
6049
|
credentials,
|
|
5752
6050
|
root: workspace.root,
|
|
@@ -5757,9 +6055,11 @@ async function reconcileWorkspace(workspace, options) {
|
|
|
5757
6055
|
...backendsOf(workspace),
|
|
5758
6056
|
saved: await loadPortState(workspace.root),
|
|
5759
6057
|
addresses: surfaceAddresses(workspace, manifest),
|
|
6058
|
+
processorAddresses: processorAddresses(workspace, manifest),
|
|
5760
6059
|
metroPorts: metroPorts(workspace, manifest),
|
|
5761
6060
|
fakes,
|
|
5762
6061
|
credentialFakes,
|
|
6062
|
+
...objectWebhooks.length > 0 ? { objectWebhooks } : {},
|
|
5763
6063
|
apps: (containers) => appServices(workspace, manifest, containers, credentials, runnables, fakes, credentialFakes),
|
|
5764
6064
|
...options.start === void 0 ? {} : { start: options.start },
|
|
5765
6065
|
...options.progress ? { progress: options.progress } : {}
|
|
@@ -5774,6 +6074,40 @@ async function reconcileWorkspace(workspace, options) {
|
|
|
5774
6074
|
};
|
|
5775
6075
|
}
|
|
5776
6076
|
/**
|
|
6077
|
+
* Where MinIO posts each watched bucket's events under `gkm dev`: the dev
|
|
6078
|
+
* server of the app that builds the worker running the bucket's subscribers,
|
|
6079
|
+
* on the host, on that app's port — the process that relays them onto the
|
|
6080
|
+
* broker.
|
|
6081
|
+
*
|
|
6082
|
+
* None where the broker is SNS: there a bucket's events come from a topic, and
|
|
6083
|
+
* nothing relays them. None for a worker no app can build — `gkm build` says
|
|
6084
|
+
* so; a dev loop has nothing to post to.
|
|
6085
|
+
*/
|
|
6086
|
+
function localObjectWebhooks(workspace, manifest, options) {
|
|
6087
|
+
if (backendsOf(workspace).events === "sns") return [];
|
|
6088
|
+
const watched = watchedBuckets(manifest, options.subscribers);
|
|
6089
|
+
if (watched.size === 0) return [];
|
|
6090
|
+
let units;
|
|
6091
|
+
try {
|
|
6092
|
+
units = workerUnits(workspace, manifest, options.background);
|
|
6093
|
+
} catch (error) {
|
|
6094
|
+
if (error instanceof WorkerHasNoApp) return [];
|
|
6095
|
+
throw error;
|
|
6096
|
+
}
|
|
6097
|
+
const hooks = [];
|
|
6098
|
+
for (const [bucket, worker] of watched) {
|
|
6099
|
+
const app = units.find((unit) => unit.id === worker)?.app;
|
|
6100
|
+
const port = app ? workspace.apps[app]?.port : void 0;
|
|
6101
|
+
if (!port) continue;
|
|
6102
|
+
hooks.push({
|
|
6103
|
+
bucket,
|
|
6104
|
+
endpoint: `http://${HOST_GATEWAY}:${port}${require_SubscriberGenerator.objectsRoute(bucket)}`,
|
|
6105
|
+
token: objectsWebhookToken(workspace.name, bucket, options.seed)
|
|
6106
|
+
});
|
|
6107
|
+
}
|
|
6108
|
+
return hooks;
|
|
6109
|
+
}
|
|
6110
|
+
/**
|
|
5777
6111
|
* Where each mobile app's Metro runs: its app's port, which `gkm exec` hands
|
|
5778
6112
|
* Expo as `RCT_METRO_PORT`. Kept apart from the surfaces' addresses — a phone
|
|
5779
6113
|
* reaches Metro by `exp://`, not through the edge.
|
|
@@ -5788,6 +6122,19 @@ function metroPorts(workspace, manifest) {
|
|
|
5788
6122
|
return ports;
|
|
5789
6123
|
}
|
|
5790
6124
|
/**
|
|
6125
|
+
* Where each file server's processors answer locally: the dev server of the
|
|
6126
|
+
* app holding them, which `gkm dev` mounts them on — the same app whose build
|
|
6127
|
+
* writes their unit deployed.
|
|
6128
|
+
*/
|
|
6129
|
+
function processorAddresses(workspace, manifest) {
|
|
6130
|
+
const addresses = {};
|
|
6131
|
+
for (const unit of processorUnits(workspace, manifest)) {
|
|
6132
|
+
const port = workspace.apps[unit.app]?.port;
|
|
6133
|
+
if (port) addresses[unit.id] = localAddress(port);
|
|
6134
|
+
}
|
|
6135
|
+
return addresses;
|
|
6136
|
+
}
|
|
6137
|
+
/**
|
|
5791
6138
|
* Where each declared surface and site answers locally.
|
|
5792
6139
|
*
|
|
5793
6140
|
* The addresses come from the ports the workspace already assigns; which
|
|
@@ -5966,8 +6313,31 @@ function workerEnvKeys(manifest, workerId, runnables = {}) {
|
|
|
5966
6313
|
return keys;
|
|
5967
6314
|
}
|
|
5968
6315
|
/** What each construct an edge reaches hands the process that reaches it. */
|
|
6316
|
+
/**
|
|
6317
|
+
* The keys a file server's processor unit reads: its bucket's, and what each
|
|
6318
|
+
* of its processors depends on. `undefined` for a file server with none.
|
|
6319
|
+
*/
|
|
6320
|
+
function processorEnvKeys(manifest, fileServerId, runnables = {}) {
|
|
6321
|
+
const server = manifest[fileServerId];
|
|
6322
|
+
if (server?.kind !== "file-server" || !server.processors?.length) return;
|
|
6323
|
+
const keys = /* @__PURE__ */ new Set();
|
|
6324
|
+
addEdgeKeys(manifest, [
|
|
6325
|
+
server.of,
|
|
6326
|
+
...server.processors.flatMap((p) => p.dependencies.map((d) => d.target)),
|
|
6327
|
+
...runnables[fileServerId] ?? []
|
|
6328
|
+
], keys);
|
|
6329
|
+
return keys;
|
|
6330
|
+
}
|
|
5969
6331
|
function addEdgeKeys(manifest, edges, keys) {
|
|
5970
6332
|
for (const id of edges) {
|
|
6333
|
+
const bucket = require_discover.eventsEdgeBucket(id);
|
|
6334
|
+
if (bucket) {
|
|
6335
|
+
if (manifest[bucket]?.kind === "objects") {
|
|
6336
|
+
keys.add((0, _geekmidas_manifest.provideKey)(bucket, "eventsConnectionString"));
|
|
6337
|
+
keys.add((0, _geekmidas_manifest.provideKey)(bucket, "eventsToken"));
|
|
6338
|
+
}
|
|
6339
|
+
continue;
|
|
6340
|
+
}
|
|
5971
6341
|
const target = manifest[id];
|
|
5972
6342
|
if (!target) continue;
|
|
5973
6343
|
if (target.kind === "rest-api") {
|
|
@@ -6425,6 +6795,308 @@ function validateImageRef(ref) {
|
|
|
6425
6795
|
return ref;
|
|
6426
6796
|
}
|
|
6427
6797
|
//#endregion
|
|
6798
|
+
//#region src/providers/processorOrigin.ts
|
|
6799
|
+
/**
|
|
6800
|
+
* A file server's processors as a CDN origin: the names both sides agree on.
|
|
6801
|
+
*
|
|
6802
|
+
* On a compose stage whose bucket is on S3, the CDN serves the bucket and
|
|
6803
|
+
* sends each processor pattern to the stack's processor unit, at a host of
|
|
6804
|
+
* its own. That host is public — a CDN reaches its origin over the internet —
|
|
6805
|
+
* so the CDN adds a secret header and the edge refuses any request without
|
|
6806
|
+
* it. One definition, read by the CDN that sends the header and by the stack
|
|
6807
|
+
* whose edge checks it, so the two cannot drift.
|
|
6808
|
+
*/
|
|
6809
|
+
/** The header the CDN adds to every request it sends a processor. */
|
|
6810
|
+
const ORIGIN_VERIFY_HEADER = "X-Gkm-Origin-Verify";
|
|
6811
|
+
/** Where a file server's processors answer the CDN: `<fileserver>-processors.<domain>`. */
|
|
6812
|
+
function processorOriginHost(serverId, domain) {
|
|
6813
|
+
return `${require_derive.appKey(serverId)}-processors.${domain}`.toLowerCase();
|
|
6814
|
+
}
|
|
6815
|
+
/** The stage secret holding the header's value: `ASSETS_SERVER_ORIGIN_SECRET`. */
|
|
6816
|
+
function originSecretKey(serverId) {
|
|
6817
|
+
return (0, _geekmidas_manifest.provideKey)(serverId, "originSecret");
|
|
6818
|
+
}
|
|
6819
|
+
/**
|
|
6820
|
+
* What the processor unit reads that secret from. Set wherever the CDN fronts
|
|
6821
|
+
* it, so the unit refuses a request without the header itself — on Dokploy,
|
|
6822
|
+
* whose edge cannot match a header, the only check; behind the stack's own
|
|
6823
|
+
* edge, a second one.
|
|
6824
|
+
*/
|
|
6825
|
+
const PROCESSOR_ORIGIN_SECRET_ENV = "GKM_PROCESSOR_ORIGIN_SECRET";
|
|
6826
|
+
/** A new value for that secret: random, generated once, kept in the stage. */
|
|
6827
|
+
function newOriginSecret() {
|
|
6828
|
+
return (0, node_crypto.randomBytes)(32).toString("base64url");
|
|
6829
|
+
}
|
|
6830
|
+
//#endregion
|
|
6831
|
+
//#region src/generators/ProcessorGenerator.ts
|
|
6832
|
+
/** Where a file server's processor entry lives, under an app's `.gkm/server`. */
|
|
6833
|
+
function processorEntryDir(serverDir, fileServerId) {
|
|
6834
|
+
return (0, node_path.join)(serverDir, "processors", processorUnitName(fileServerId));
|
|
6835
|
+
}
|
|
6836
|
+
/** The file its bundle is written to, beside the server's. */
|
|
6837
|
+
function processorBundleName(fileServerId) {
|
|
6838
|
+
return `${processorUnitName(fileServerId)}.mjs`;
|
|
6839
|
+
}
|
|
6840
|
+
/**
|
|
6841
|
+
* A file server's processors, as the build generates them.
|
|
6842
|
+
*
|
|
6843
|
+
* On AWS each is a Lambda behind a function URL — the CDN's origin for its
|
|
6844
|
+
* pattern. On a server they are one process per file server, the processor
|
|
6845
|
+
* unit (see {@link ProcessorGenerator.buildEntry}), so the `server` target
|
|
6846
|
+
* generates nothing per processor here.
|
|
6847
|
+
*/
|
|
6848
|
+
var ProcessorGenerator = class extends require_discover.ConstructGenerator {
|
|
6849
|
+
isConstruct(value) {
|
|
6850
|
+
return _geekmidas_constructs_processors.Processor.isProcessor(value);
|
|
6851
|
+
}
|
|
6852
|
+
async build(context, constructs, outputDir, options) {
|
|
6853
|
+
if ((options?.target ?? "aws") !== "aws" || constructs.length === 0) return [];
|
|
6854
|
+
const dir = (0, node_path.join)(outputDir, "processors");
|
|
6855
|
+
await (0, node_fs_promises.mkdir)(dir, { recursive: true });
|
|
6856
|
+
const infos = [];
|
|
6857
|
+
for (const { key, construct, path } of constructs) {
|
|
6858
|
+
const file = (0, node_path.join)(dir, `${key}.ts`);
|
|
6859
|
+
const importPath = (0, node_path.relative)((0, node_path.dirname)(file), path.relative).replace(/\.ts$/, ".js");
|
|
6860
|
+
await (0, node_fs_promises.writeFile)(file, `import { AWSLambdaProcessor } from '@geekmidas/constructs/processors';
|
|
6861
|
+
import { ${key} } from '${importPath}';
|
|
6862
|
+
${context.storageDrivers?.imports ?? ""}
|
|
6863
|
+
${context.storageDrivers?.setup ? `\n// The handler registers the drivers its target needs.\n${context.storageDrivers.setup}\n` : ""}
|
|
6864
|
+
const adapter = new AWSLambdaProcessor(${key});
|
|
6865
|
+
|
|
6866
|
+
export const handler = adapter.handler;
|
|
6867
|
+
`);
|
|
6868
|
+
infos.push(await processorInfo(key, construct, (0, node_path.relative)(options?.root ?? process.cwd(), file).replace(/\.ts$/, ".handler"), context));
|
|
6869
|
+
}
|
|
6870
|
+
return infos;
|
|
6871
|
+
}
|
|
6872
|
+
/**
|
|
6873
|
+
* `gkm dev`'s half: `processors.ts` beside the dev server's app, mounting
|
|
6874
|
+
* each file server's processors under `/__gkm/processors/<FileServer>`.
|
|
6875
|
+
* The local edge sends each pattern on the file server's host there, so
|
|
6876
|
+
* `processedUrl()` answers locally as it does deployed.
|
|
6877
|
+
*
|
|
6878
|
+
* In the dev server's own process rather than a unit of its own: locally
|
|
6879
|
+
* there is no CPU to protect, and the dev server already reloads on change.
|
|
6880
|
+
*/
|
|
6881
|
+
async buildDev(outputDir, processors) {
|
|
6882
|
+
await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
|
|
6883
|
+
const file = (0, node_path.join)(outputDir, "processors.ts");
|
|
6884
|
+
const imports = processors.map(({ key, path }) => {
|
|
6885
|
+
const specifier = (0, node_path.relative)(outputDir, path.absolute).replace(/\.ts$/, ".js");
|
|
6886
|
+
return `import { ${key} } from '${specifier.startsWith(".") ? specifier : `./${specifier}`}';`;
|
|
6887
|
+
}).join("\n");
|
|
6888
|
+
const byServer = /* @__PURE__ */ new Map();
|
|
6889
|
+
for (const { key, construct } of processors) byServer.set(construct.surfaceId, [...byServer.get(construct.surfaceId) ?? [], key]);
|
|
6890
|
+
const units = [...byServer.entries()].map(([id, keys]) => ` ${JSON.stringify(id)}: [${keys.join(", ")}],`).join("\n");
|
|
6891
|
+
await (0, node_fs_promises.writeFile)(file, `/**
|
|
6892
|
+
* Generated processors setup for \`gkm dev\`.
|
|
6893
|
+
*
|
|
6894
|
+
* Each file server's processors, under ${PROCESSORS_DEV_PREFIX}<FileServer>: the
|
|
6895
|
+
* local edge rewrites each processor pattern on the file server's host here.
|
|
6896
|
+
*/
|
|
6897
|
+
import type { EnvironmentParser } from '@geekmidas/envkit';
|
|
6898
|
+
import { processorServer } from '@geekmidas/constructs/processors';
|
|
6899
|
+
${imports}
|
|
6900
|
+
|
|
6901
|
+
export function setupProcessors(
|
|
6902
|
+
app: { all: (path: string, handler: (c: any) => unknown) => unknown },
|
|
6903
|
+
envParser: EnvironmentParser<any>,
|
|
6904
|
+
): void {
|
|
6905
|
+
const units: Record<string, ReturnType<typeof processorServer>> = Object.fromEntries(
|
|
6906
|
+
Object.entries({
|
|
6907
|
+
${units}
|
|
6908
|
+
}).map(([id, processors]) => [id, processorServer(processors, envParser)]),
|
|
6909
|
+
);
|
|
6910
|
+
|
|
6911
|
+
app.all('${PROCESSORS_DEV_PREFIX}:server/*', async (c: any) => {
|
|
6912
|
+
const server = c.req.param('server') as string;
|
|
6913
|
+
const serve = units[server];
|
|
6914
|
+
if (!serve) return c.notFound();
|
|
6915
|
+
const path = c.req.path.slice(\`${PROCESSORS_DEV_PREFIX}\${server}\`.length) || '/';
|
|
6916
|
+
const response = await serve({ method: c.req.method, path });
|
|
6917
|
+
if (!response) {
|
|
6918
|
+
return new Response(null, {
|
|
6919
|
+
status: 404,
|
|
6920
|
+
headers: { 'cache-control': 'public, max-age=60' },
|
|
6921
|
+
});
|
|
6922
|
+
}
|
|
6923
|
+
return new Response(c.req.method === 'HEAD' ? null : response.body, {
|
|
6924
|
+
status: response.status,
|
|
6925
|
+
headers: response.headers,
|
|
6926
|
+
});
|
|
6927
|
+
});
|
|
6928
|
+
}
|
|
6929
|
+
`);
|
|
6930
|
+
return file;
|
|
6931
|
+
}
|
|
6932
|
+
/**
|
|
6933
|
+
* A file server's processor unit: one process answering each of its
|
|
6934
|
+
* processors' patterns, and `/health`. Returns its entry, `processors.ts`.
|
|
6935
|
+
*
|
|
6936
|
+
* Its own process because making a derivative is CPU-bound — a resize
|
|
6937
|
+
* spike in the API's process would be every request's latency.
|
|
6938
|
+
*/
|
|
6939
|
+
async buildEntry(input) {
|
|
6940
|
+
const { context, outputDir, processors } = input;
|
|
6941
|
+
await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
|
|
6942
|
+
await require_EndpointGenerator.writeTelemetryModule(outputDir, input.telemetry);
|
|
6943
|
+
const healthCheck = context.production?.healthCheck ?? "/health";
|
|
6944
|
+
const imports = processors.map(({ key, path }) => {
|
|
6945
|
+
const specifier = (0, node_path.relative)(outputDir, path.absolute).replace(/\.ts$/, ".js");
|
|
6946
|
+
return `import { ${key} } from '${specifier.startsWith(".") ? specifier : `./${specifier}`}';`;
|
|
6947
|
+
}).join("\n");
|
|
6948
|
+
const entry = (0, node_path.join)(outputDir, "processors.ts");
|
|
6949
|
+
await (0, node_fs_promises.writeFile)(entry, `#!/usr/bin/env node
|
|
6950
|
+
/**
|
|
6951
|
+
* Production entry for ${input.fileServerId}'s processors.
|
|
6952
|
+
* Generated by 'gkm build --production'.
|
|
6953
|
+
*
|
|
6954
|
+
* Answers each processor's pattern, and ${healthCheck} on PORT. The edge
|
|
6955
|
+
* routes only those patterns here; everything else on the file server's
|
|
6956
|
+
* domain is the bucket.
|
|
6957
|
+
*/
|
|
6958
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
6959
|
+
import { createServer } from 'node:http';
|
|
6960
|
+
import { runShutdownHooks } from '@geekmidas/constructs';
|
|
6961
|
+
import { processorServer } from '@geekmidas/constructs/processors';
|
|
6962
|
+
${context.storageDrivers?.imports ?? ""}
|
|
6963
|
+
${imports}
|
|
6964
|
+
|
|
6965
|
+
${require_EndpointGenerator.startTelemetryCode([healthCheck])}
|
|
6966
|
+
${context.storageDrivers?.setup ? `// The entry point registers the drivers its target needs.\n${context.storageDrivers.setup}\n` : ""}
|
|
6967
|
+
process.env.GKM_APP_NAME ??= ${JSON.stringify(processorUnitName(input.fileServerId))};
|
|
6968
|
+
|
|
6969
|
+
const processors = [${processors.map(({ key }) => key).join(", ")}];
|
|
6970
|
+
const serve = processorServer(processors);
|
|
6971
|
+
const port = Number(process.env.PORT) || 3000;
|
|
6972
|
+
let stopping = false;
|
|
6973
|
+
|
|
6974
|
+
${input.telemetry ? REQUEST_SPANS : NO_REQUEST_SPANS}
|
|
6975
|
+
// Where the CDN fronts this unit, the secret it adds to every request: one
|
|
6976
|
+
// without it is refused here, whatever the edge in front did or could not.
|
|
6977
|
+
const originSecret = process.env.${PROCESSOR_ORIGIN_SECRET_ENV}
|
|
6978
|
+
? Buffer.from(process.env.${PROCESSOR_ORIGIN_SECRET_ENV})
|
|
6979
|
+
: undefined;
|
|
6980
|
+
const fromOrigin = (header: string | string[] | undefined) => {
|
|
6981
|
+
if (!originSecret) return true;
|
|
6982
|
+
const given = Buffer.from(typeof header === 'string' ? header : '');
|
|
6983
|
+
return given.length === originSecret.length && timingSafeEqual(given, originSecret);
|
|
6984
|
+
};
|
|
6985
|
+
|
|
6986
|
+
const server = createServer(async (req, res) => {
|
|
6987
|
+
const method = req.method ?? 'GET';
|
|
6988
|
+
const path = (req.url ?? '/').split('?')[0] ?? '/';
|
|
6989
|
+
if (path === ${JSON.stringify(healthCheck)}) {
|
|
6990
|
+
res.writeHead(stopping ? 503 : 200, { 'content-type': 'application/json' });
|
|
6991
|
+
res.end(JSON.stringify({ status: stopping ? 'stopping' : 'ok' }));
|
|
6992
|
+
return;
|
|
6993
|
+
}
|
|
6994
|
+
if (!fromOrigin(req.headers[${JSON.stringify(ORIGIN_VERIFY_HEADER.toLowerCase())}])) {
|
|
6995
|
+
res.writeHead(403, { 'cache-control': 'no-store' }).end();
|
|
6996
|
+
return;
|
|
6997
|
+
}
|
|
6998
|
+
await traced(method, path, async () => {
|
|
6999
|
+
try {
|
|
7000
|
+
const response = await serve({ method, path });
|
|
7001
|
+
if (!response) {
|
|
7002
|
+
res.writeHead(404, { 'cache-control': 'public, max-age=60' }).end();
|
|
7003
|
+
return 404;
|
|
7004
|
+
}
|
|
7005
|
+
res.writeHead(response.status, response.headers);
|
|
7006
|
+
res.end(method === 'HEAD' ? undefined : response.body);
|
|
7007
|
+
return response.status;
|
|
7008
|
+
} catch (error) {
|
|
7009
|
+
console.error(error);
|
|
7010
|
+
res.writeHead(500, { 'cache-control': 'no-store' }).end();
|
|
7011
|
+
return 500;
|
|
7012
|
+
}
|
|
7013
|
+
});
|
|
7014
|
+
});
|
|
7015
|
+
server.listen(port);
|
|
7016
|
+
|
|
7017
|
+
const shutdown = async () => {
|
|
7018
|
+
if (stopping) return;
|
|
7019
|
+
stopping = true;
|
|
7020
|
+
setTimeout(() => process.exit(1), Number(process.env.GKM_SHUTDOWN_TIMEOUT_MS) || 8000).unref();
|
|
7021
|
+
server.close();
|
|
7022
|
+
await runShutdownHooks((error) => console.error(error));
|
|
7023
|
+
process.exit(0);
|
|
7024
|
+
};
|
|
7025
|
+
process.on('SIGTERM', shutdown);
|
|
7026
|
+
process.on('SIGINT', shutdown);
|
|
7027
|
+
`);
|
|
7028
|
+
return entry;
|
|
7029
|
+
}
|
|
7030
|
+
};
|
|
7031
|
+
/**
|
|
7032
|
+
* A SERVER span per request, once telemetry has started — opened by the unit
|
|
7033
|
+
* rather than by hooking node:http, which sees nothing inside a bundle. Named
|
|
7034
|
+
* after the processor's pattern, never the key, which has no bound.
|
|
7035
|
+
*
|
|
7036
|
+
* Only in an entry whose file server has a `Telemetry` node: the bundle
|
|
7037
|
+
* follows the import, and an app without one need not install the API.
|
|
7038
|
+
*/
|
|
7039
|
+
const REQUEST_SPANS = `const tracing = requestSpans ? await import('@opentelemetry/api') : undefined;
|
|
7040
|
+
const routeOf = (path: string) =>
|
|
7041
|
+
processors.find((processor) => path.startsWith(processor.prefix))?.pattern;
|
|
7042
|
+
|
|
7043
|
+
async function traced(
|
|
7044
|
+
method: string,
|
|
7045
|
+
path: string,
|
|
7046
|
+
run: () => Promise<number>,
|
|
7047
|
+
): Promise<void> {
|
|
7048
|
+
if (!tracing) {
|
|
7049
|
+
await run();
|
|
7050
|
+
return;
|
|
7051
|
+
}
|
|
7052
|
+
const route = routeOf(path);
|
|
7053
|
+
await tracing.trace.getTracer('@geekmidas/processors').startActiveSpan(
|
|
7054
|
+
route ? \`\${method} \${route}\` : method,
|
|
7055
|
+
{
|
|
7056
|
+
kind: tracing.SpanKind.SERVER,
|
|
7057
|
+
attributes: {
|
|
7058
|
+
'http.request.method': method,
|
|
7059
|
+
'url.path': path,
|
|
7060
|
+
...(route ? { 'http.route': route } : {}),
|
|
7061
|
+
},
|
|
7062
|
+
},
|
|
7063
|
+
async (span) => {
|
|
7064
|
+
try {
|
|
7065
|
+
const status = await run();
|
|
7066
|
+
span.setAttribute('http.response.status_code', status);
|
|
7067
|
+
if (status >= 500) span.setStatus({ code: tracing.SpanStatusCode.ERROR });
|
|
7068
|
+
} finally {
|
|
7069
|
+
span.end();
|
|
7070
|
+
}
|
|
7071
|
+
},
|
|
7072
|
+
);
|
|
7073
|
+
}
|
|
7074
|
+
`;
|
|
7075
|
+
/** The same shape without telemetry: each request just runs. */
|
|
7076
|
+
const NO_REQUEST_SPANS = `async function traced(
|
|
7077
|
+
_method: string,
|
|
7078
|
+
_path: string,
|
|
7079
|
+
run: () => Promise<number>,
|
|
7080
|
+
): Promise<void> {
|
|
7081
|
+
await run();
|
|
7082
|
+
}
|
|
7083
|
+
`;
|
|
7084
|
+
/** What the manifest records of one processor. */
|
|
7085
|
+
async function processorInfo(name, processor, handler, context) {
|
|
7086
|
+
return {
|
|
7087
|
+
name,
|
|
7088
|
+
handler,
|
|
7089
|
+
fileServer: processor.surfaceId,
|
|
7090
|
+
path: processor.pattern,
|
|
7091
|
+
prefix: processor.prefix,
|
|
7092
|
+
...processor.native.length ? { native: [...processor.native] } : {},
|
|
7093
|
+
...processor.timeout !== void 0 ? { timeout: processor.timeout } : {},
|
|
7094
|
+
...processor.memorySize !== void 0 ? { memorySize: processor.memorySize } : {},
|
|
7095
|
+
environment: await processor.getEnvironment({ markOptional: context.markOptional }),
|
|
7096
|
+
dependencies: processor.constructs
|
|
7097
|
+
};
|
|
7098
|
+
}
|
|
7099
|
+
//#endregion
|
|
6428
7100
|
//#region src/generators/CronGenerator.ts
|
|
6429
7101
|
var CronGenerator = class extends require_discover.ConstructGenerator {
|
|
6430
7102
|
async build(context, constructs, outputDir, options) {
|
|
@@ -7003,17 +7675,59 @@ async function answers(connection: unknown): Promise<boolean> {
|
|
|
7003
7675
|
}
|
|
7004
7676
|
}
|
|
7005
7677
|
|
|
7678
|
+
/** A request to a route this worker mounted, and what it answered. */
|
|
7679
|
+
export interface WorkerRequest {
|
|
7680
|
+
headers: Record<string, string | string[] | undefined>;
|
|
7681
|
+
body: string;
|
|
7682
|
+
}
|
|
7683
|
+
export interface WorkerAnswer {
|
|
7684
|
+
status: number;
|
|
7685
|
+
body: unknown;
|
|
7686
|
+
}
|
|
7687
|
+
|
|
7688
|
+
// The routes something pushes to: an SNS subscriber's, and the one a local
|
|
7689
|
+
// object store posts a bucket's events to. Mounted by the subscribers, served
|
|
7690
|
+
// by the entry's HTTP server beside the health check.
|
|
7691
|
+
const routes = new Map<string, (c: any) => unknown>();
|
|
7692
|
+
const app = {
|
|
7693
|
+
post: (path: string, handler: (c: any) => unknown) => {
|
|
7694
|
+
routes.set(path, handler);
|
|
7695
|
+
},
|
|
7696
|
+
};
|
|
7697
|
+
|
|
7698
|
+
/** Run one mounted route, as the subscribers' handlers expect to be called. */
|
|
7699
|
+
async function route(path: string, request: WorkerRequest): Promise<WorkerAnswer | undefined> {
|
|
7700
|
+
const handler = routes.get(path);
|
|
7701
|
+
if (!handler) return undefined;
|
|
7702
|
+
let answer: WorkerAnswer | undefined;
|
|
7703
|
+
const c = {
|
|
7704
|
+
req: {
|
|
7705
|
+
text: async () => request.body,
|
|
7706
|
+
header: (name: string) => {
|
|
7707
|
+
const value = request.headers[name.toLowerCase()];
|
|
7708
|
+
return Array.isArray(value) ? value[0] : value;
|
|
7709
|
+
},
|
|
7710
|
+
},
|
|
7711
|
+
json: (body: unknown, status = 200) => {
|
|
7712
|
+
answer = { status, body };
|
|
7713
|
+
return answer;
|
|
7714
|
+
},
|
|
7715
|
+
};
|
|
7716
|
+
await handler(c);
|
|
7717
|
+
return answer ?? { status: 204, body: null };
|
|
7718
|
+
}
|
|
7719
|
+
|
|
7006
7720
|
/** Start everything this worker runs. */
|
|
7007
7721
|
export async function startWorker(): Promise<{
|
|
7008
7722
|
health: () => Promise<WorkerHealth>;
|
|
7009
7723
|
stop: () => Promise<void>;
|
|
7724
|
+
route: typeof route;
|
|
7725
|
+
/** Subscribe the pushed routes, once the server answers on \`port\`. */
|
|
7726
|
+
subscribeForPush: (port: number) => Promise<void>;
|
|
7010
7727
|
}> {
|
|
7011
|
-
|
|
7012
|
-
// subscriber, so there is nothing to mount.
|
|
7013
|
-
const noRoutes = { post: () => undefined };
|
|
7014
|
-
|
|
7015
|
-
await setupSubscribers(noRoutes, envParser, logger).catch((error) => {
|
|
7728
|
+
const subscribeForPush = await setupSubscribers(app, envParser, logger).catch((error) => {
|
|
7016
7729
|
logger.error({ err: error }, 'Failed to start subscribers');
|
|
7730
|
+
return async (_port: number) => {};
|
|
7017
7731
|
});
|
|
7018
7732
|
await setupQueues(envParser, logger).catch((error) => {
|
|
7019
7733
|
logger.error({ err: error }, 'Failed to start queue consumers');
|
|
@@ -7025,6 +7739,8 @@ export async function startWorker(): Promise<{
|
|
|
7025
7739
|
const statuses = () => [subscribersStatus(), queuesStatus(), cronsStatus()];
|
|
7026
7740
|
|
|
7027
7741
|
return {
|
|
7742
|
+
route,
|
|
7743
|
+
subscribeForPush,
|
|
7028
7744
|
async health() {
|
|
7029
7745
|
const all = statuses();
|
|
7030
7746
|
const failed = all.flatMap((s) => s.failed);
|
|
@@ -7055,8 +7771,10 @@ function workerEntry(healthCheck) {
|
|
|
7055
7771
|
* Generated by 'gkm build --production'.
|
|
7056
7772
|
*
|
|
7057
7773
|
* Runs this worker's crons, queue consumers and topic subscribers, and serves
|
|
7058
|
-
*
|
|
7059
|
-
* every broker connection answers, 503 otherwise.
|
|
7774
|
+
* its health check: ${healthCheck}, on PORT — 200 when every consumer started
|
|
7775
|
+
* and every broker connection answers, 503 otherwise. Beside it, on the same
|
|
7776
|
+
* port, the POST routes its subscribers mounted: where a local object store
|
|
7777
|
+
* posts a bucket's events.
|
|
7060
7778
|
*
|
|
7061
7779
|
* On SIGTERM it stops pulling messages and scheduling crons, lets the handlers
|
|
7062
7780
|
* in flight finish, closes its broker connections and database pools, and
|
|
@@ -7075,15 +7793,39 @@ let worker: Awaited<ReturnType<typeof startWorker>> | undefined;
|
|
|
7075
7793
|
let stopping = false;
|
|
7076
7794
|
|
|
7077
7795
|
const server = createServer((req, res) => {
|
|
7078
|
-
const path = (req.url ?? '/').split('?')[0];
|
|
7079
|
-
if (path !== ${JSON.stringify(healthCheck)} || (req.method !== 'GET' && req.method !== 'HEAD')) {
|
|
7080
|
-
res.writeHead(404).end();
|
|
7081
|
-
return;
|
|
7082
|
-
}
|
|
7796
|
+
const path = (req.url ?? '/').split('?')[0] ?? '/';
|
|
7083
7797
|
const answer = (status: number, body: unknown) => {
|
|
7084
7798
|
res.writeHead(status, { 'content-type': 'application/json' });
|
|
7085
7799
|
res.end(JSON.stringify(body));
|
|
7086
7800
|
};
|
|
7801
|
+
|
|
7802
|
+
// A route a subscriber mounted: what SNS pushes to, or what a local object
|
|
7803
|
+
// store posts a bucket's events to. Refused while starting or stopping, so
|
|
7804
|
+
// the sender keeps the message and sends it again.
|
|
7805
|
+
if (req.method === 'POST') {
|
|
7806
|
+
let body = '';
|
|
7807
|
+
req.setEncoding('utf8');
|
|
7808
|
+
req.on('data', (chunk) => {
|
|
7809
|
+
body += chunk;
|
|
7810
|
+
});
|
|
7811
|
+
req.on('end', () => {
|
|
7812
|
+
if (stopping) return answer(503, { status: 'stopping' });
|
|
7813
|
+
if (!worker) return answer(503, { status: 'starting' });
|
|
7814
|
+
worker.route(path, { headers: req.headers, body }).then(
|
|
7815
|
+
(routed) => (routed ? answer(routed.status, routed.body) : answer(404, { status: 'not found' })),
|
|
7816
|
+
(error) => {
|
|
7817
|
+
logger.error({ err: error, path }, 'Route failed');
|
|
7818
|
+
answer(500, { status: 'failed' });
|
|
7819
|
+
},
|
|
7820
|
+
);
|
|
7821
|
+
});
|
|
7822
|
+
return;
|
|
7823
|
+
}
|
|
7824
|
+
|
|
7825
|
+
if (path !== ${JSON.stringify(healthCheck)} || (req.method !== 'GET' && req.method !== 'HEAD')) {
|
|
7826
|
+
res.writeHead(404).end();
|
|
7827
|
+
return;
|
|
7828
|
+
}
|
|
7087
7829
|
if (stopping) return answer(503, { status: 'stopping' });
|
|
7088
7830
|
if (!worker) return answer(503, { status: 'starting' });
|
|
7089
7831
|
worker.health().then(
|
|
@@ -7117,6 +7859,9 @@ process.on('SIGINT', shutdown);
|
|
|
7117
7859
|
|
|
7118
7860
|
worker = await startWorker();
|
|
7119
7861
|
logger.info({ port }, 'Worker started');
|
|
7862
|
+
await worker.subscribeForPush(port).catch((error) => {
|
|
7863
|
+
logger.error({ err: error }, 'Failed to subscribe for push');
|
|
7864
|
+
});
|
|
7120
7865
|
`;
|
|
7121
7866
|
}
|
|
7122
7867
|
//#endregion
|
|
@@ -7174,7 +7919,7 @@ async function buildDockerImage(app, buildRoot, options) {
|
|
|
7174
7919
|
const fullImageName = validateImageRef(registry ? `${registry}/${app.imageName}:${tag}` : `${app.imageName}:${tag}`);
|
|
7175
7920
|
logger$1.log(`\n🐳 Building Docker image: ${fullImageName}`);
|
|
7176
7921
|
try {
|
|
7177
|
-
await
|
|
7922
|
+
await require_credentials.run("docker", [
|
|
7178
7923
|
"build",
|
|
7179
7924
|
`--file=${(0, node_path.relative)(buildRoot, app.dockerfile)}`,
|
|
7180
7925
|
`--tag=${fullImageName}`,
|
|
@@ -7201,7 +7946,7 @@ async function pushDockerImage(imageName, options, cwd) {
|
|
|
7201
7946
|
const fullImageName = validateImageRef(`${registry}/${imageName}:${tag}`);
|
|
7202
7947
|
logger$1.log(`\n🚀 Pushing Docker image: ${fullImageName}`);
|
|
7203
7948
|
try {
|
|
7204
|
-
await
|
|
7949
|
+
await require_credentials.run("docker", ["push", fullImageName], { cwd });
|
|
7205
7950
|
logger$1.log(`✅ Docker image pushed: ${fullImageName}`);
|
|
7206
7951
|
} catch (error) {
|
|
7207
7952
|
throw new DockerPushFailed(fullImageName, error);
|
|
@@ -7262,6 +8007,25 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
|
|
|
7262
8007
|
imageName: imageNames[worker.name] ?? worker.name
|
|
7263
8008
|
});
|
|
7264
8009
|
}
|
|
8010
|
+
for (const unit of manifest ? processorUnits(workspace, manifest) : []) {
|
|
8011
|
+
logger$1.log(`\n 📄 Generating Dockerfile for ${unit.name} (processors of ${unit.id}, built from ${unit.app})`);
|
|
8012
|
+
const dockerfile = processorDockerfile(unit, workspace.apps[unit.app], {
|
|
8013
|
+
layout,
|
|
8014
|
+
workspaceRoot: workspace.root,
|
|
8015
|
+
native: processorNative(manifest, unit.id)
|
|
8016
|
+
});
|
|
8017
|
+
const path = workerDockerfileOf(unit.name);
|
|
8018
|
+
const dockerfilePath = (0, node_path.join)(workspace.root, path);
|
|
8019
|
+
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(dockerfilePath), { recursive: true });
|
|
8020
|
+
await (0, node_fs_promises.writeFile)(dockerfilePath, dockerfile);
|
|
8021
|
+
logger$1.log(` Generated: ${path}`);
|
|
8022
|
+
results.push({
|
|
8023
|
+
appName: unit.name,
|
|
8024
|
+
type: "backend",
|
|
8025
|
+
dockerfile: dockerfilePath,
|
|
8026
|
+
imageName: imageNames[unit.name] ?? unit.name
|
|
8027
|
+
});
|
|
8028
|
+
}
|
|
7265
8029
|
const dockerignorePath = await ensureDockerignore(layout.buildRoot);
|
|
7266
8030
|
logger$1.log(`\n Ensured: ${dockerignorePath}`);
|
|
7267
8031
|
const composePath = await writeConstructsCompose(workspace);
|
|
@@ -7321,6 +8085,29 @@ function workerDockerfile(worker, host, options) {
|
|
|
7321
8085
|
...options.cache ? { cache: options.cache } : {}
|
|
7322
8086
|
});
|
|
7323
8087
|
}
|
|
8088
|
+
/** The native packages a file server's processors named, once each. */
|
|
8089
|
+
function processorNative(manifest, fileServerId) {
|
|
8090
|
+
const server = manifest[fileServerId];
|
|
8091
|
+
if (server?.kind !== "file-server") return [];
|
|
8092
|
+
return [...new Set((server.processors ?? []).flatMap((p) => p.native ?? []))].sort();
|
|
8093
|
+
}
|
|
8094
|
+
/**
|
|
8095
|
+
* A file server's processor unit's Dockerfile: its host app's build, and the
|
|
8096
|
+
* unit's bundle as the runner, with its processors' native packages
|
|
8097
|
+
* installed beside it — see `generateProcessorDockerfile`.
|
|
8098
|
+
*/
|
|
8099
|
+
function processorDockerfile(unit, host, options) {
|
|
8100
|
+
return generateProcessorDockerfile({
|
|
8101
|
+
...appImageOptions(options.layout, unit.app, host, options.workspaceRoot),
|
|
8102
|
+
imageName: unit.name,
|
|
8103
|
+
port: PROCESSOR_PORT,
|
|
8104
|
+
fileServer: unit.id,
|
|
8105
|
+
bundle: processorBundleName(unit.id),
|
|
8106
|
+
healthCheckPath: "/health",
|
|
8107
|
+
...options.native.length ? { external: [...options.native] } : {},
|
|
8108
|
+
...options.cache ? { cache: options.cache } : {}
|
|
8109
|
+
});
|
|
8110
|
+
}
|
|
7324
8111
|
/**
|
|
7325
8112
|
* A site's Dockerfile, with an `ARG` for every key its bundler inlines.
|
|
7326
8113
|
*
|
|
@@ -7485,7 +8272,7 @@ async function createDnsProvider(options) {
|
|
|
7485
8272
|
if (isDnsProvider(config.provider)) return config.provider;
|
|
7486
8273
|
const provider = config.provider;
|
|
7487
8274
|
if (provider === "hostinger") {
|
|
7488
|
-
const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-
|
|
8275
|
+
const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-OdQmKXE3.cjs"));
|
|
7489
8276
|
return new HostingerProvider(options.hostinger);
|
|
7490
8277
|
}
|
|
7491
8278
|
if (provider === "route53") {
|
|
@@ -7498,7 +8285,7 @@ async function createDnsProvider(options) {
|
|
|
7498
8285
|
});
|
|
7499
8286
|
}
|
|
7500
8287
|
if (provider === "godaddy") {
|
|
7501
|
-
const { GoDaddyProvider } = await Promise.resolve().then(() => require("./GoDaddyProvider-
|
|
8288
|
+
const { GoDaddyProvider } = await Promise.resolve().then(() => require("./GoDaddyProvider-BTdtqhI_.cjs"));
|
|
7502
8289
|
return new GoDaddyProvider(options.godaddy ?? {});
|
|
7503
8290
|
}
|
|
7504
8291
|
if (provider === "cloudflare") throw new DnsProviderNotImplemented("cloudflare");
|
|
@@ -8485,12 +9272,36 @@ Object.defineProperty(exports, "NoDomainForStage", {
|
|
|
8485
9272
|
return NoDomainForStage;
|
|
8486
9273
|
}
|
|
8487
9274
|
});
|
|
9275
|
+
Object.defineProperty(exports, "ORIGIN_VERIFY_HEADER", {
|
|
9276
|
+
enumerable: true,
|
|
9277
|
+
get: function() {
|
|
9278
|
+
return ORIGIN_VERIFY_HEADER;
|
|
9279
|
+
}
|
|
9280
|
+
});
|
|
9281
|
+
Object.defineProperty(exports, "PROCESSOR_ORIGIN_SECRET_ENV", {
|
|
9282
|
+
enumerable: true,
|
|
9283
|
+
get: function() {
|
|
9284
|
+
return PROCESSOR_ORIGIN_SECRET_ENV;
|
|
9285
|
+
}
|
|
9286
|
+
});
|
|
9287
|
+
Object.defineProperty(exports, "PROCESSOR_PORT", {
|
|
9288
|
+
enumerable: true,
|
|
9289
|
+
get: function() {
|
|
9290
|
+
return PROCESSOR_PORT;
|
|
9291
|
+
}
|
|
9292
|
+
});
|
|
8488
9293
|
Object.defineProperty(exports, "PROVIDER_KINDS", {
|
|
8489
9294
|
enumerable: true,
|
|
8490
9295
|
get: function() {
|
|
8491
9296
|
return PROVIDER_KINDS;
|
|
8492
9297
|
}
|
|
8493
9298
|
});
|
|
9299
|
+
Object.defineProperty(exports, "ProcessorGenerator", {
|
|
9300
|
+
enumerable: true,
|
|
9301
|
+
get: function() {
|
|
9302
|
+
return ProcessorGenerator;
|
|
9303
|
+
}
|
|
9304
|
+
});
|
|
8494
9305
|
Object.defineProperty(exports, "QueueGenerator", {
|
|
8495
9306
|
enumerable: true,
|
|
8496
9307
|
get: function() {
|
|
@@ -8575,6 +9386,12 @@ Object.defineProperty(exports, "applyLifecycles", {
|
|
|
8575
9386
|
return applyLifecycles;
|
|
8576
9387
|
}
|
|
8577
9388
|
});
|
|
9389
|
+
Object.defineProperty(exports, "applyNotifications", {
|
|
9390
|
+
enumerable: true,
|
|
9391
|
+
get: function() {
|
|
9392
|
+
return applyNotifications;
|
|
9393
|
+
}
|
|
9394
|
+
});
|
|
8578
9395
|
Object.defineProperty(exports, "applyPolicies", {
|
|
8579
9396
|
enumerable: true,
|
|
8580
9397
|
get: function() {
|
|
@@ -8836,7 +9653,7 @@ Object.defineProperty(exports, "getKeyPath", {
|
|
|
8836
9653
|
Object.defineProperty(exports, "hostFor", {
|
|
8837
9654
|
enumerable: true,
|
|
8838
9655
|
get: function() {
|
|
8839
|
-
return hostFor;
|
|
9656
|
+
return hostFor$1;
|
|
8840
9657
|
}
|
|
8841
9658
|
});
|
|
8842
9659
|
Object.defineProperty(exports, "imageBuildCredentials", {
|
|
@@ -8959,12 +9776,24 @@ Object.defineProperty(exports, "mergeLifecycle", {
|
|
|
8959
9776
|
return mergeLifecycle;
|
|
8960
9777
|
}
|
|
8961
9778
|
});
|
|
9779
|
+
Object.defineProperty(exports, "minioWebhookEnv", {
|
|
9780
|
+
enumerable: true,
|
|
9781
|
+
get: function() {
|
|
9782
|
+
return minioWebhookEnv;
|
|
9783
|
+
}
|
|
9784
|
+
});
|
|
8962
9785
|
Object.defineProperty(exports, "networkEnv", {
|
|
8963
9786
|
enumerable: true,
|
|
8964
9787
|
get: function() {
|
|
8965
9788
|
return networkEnv;
|
|
8966
9789
|
}
|
|
8967
9790
|
});
|
|
9791
|
+
Object.defineProperty(exports, "newOriginSecret", {
|
|
9792
|
+
enumerable: true,
|
|
9793
|
+
get: function() {
|
|
9794
|
+
return newOriginSecret;
|
|
9795
|
+
}
|
|
9796
|
+
});
|
|
8968
9797
|
Object.defineProperty(exports, "normalizeDnsConfig", {
|
|
8969
9798
|
enumerable: true,
|
|
8970
9799
|
get: function() {
|
|
@@ -8977,6 +9806,12 @@ Object.defineProperty(exports, "orchestrateDns", {
|
|
|
8977
9806
|
return orchestrateDns;
|
|
8978
9807
|
}
|
|
8979
9808
|
});
|
|
9809
|
+
Object.defineProperty(exports, "originSecretKey", {
|
|
9810
|
+
enumerable: true,
|
|
9811
|
+
get: function() {
|
|
9812
|
+
return originSecretKey;
|
|
9813
|
+
}
|
|
9814
|
+
});
|
|
8980
9815
|
Object.defineProperty(exports, "pgClient", {
|
|
8981
9816
|
enumerable: true,
|
|
8982
9817
|
get: function() {
|
|
@@ -9043,6 +9878,54 @@ Object.defineProperty(exports, "primaryPortKey", {
|
|
|
9043
9878
|
return primaryPortKey;
|
|
9044
9879
|
}
|
|
9045
9880
|
});
|
|
9881
|
+
Object.defineProperty(exports, "processorBundleName", {
|
|
9882
|
+
enumerable: true,
|
|
9883
|
+
get: function() {
|
|
9884
|
+
return processorBundleName;
|
|
9885
|
+
}
|
|
9886
|
+
});
|
|
9887
|
+
Object.defineProperty(exports, "processorDockerfile", {
|
|
9888
|
+
enumerable: true,
|
|
9889
|
+
get: function() {
|
|
9890
|
+
return processorDockerfile;
|
|
9891
|
+
}
|
|
9892
|
+
});
|
|
9893
|
+
Object.defineProperty(exports, "processorEntryDir", {
|
|
9894
|
+
enumerable: true,
|
|
9895
|
+
get: function() {
|
|
9896
|
+
return processorEntryDir;
|
|
9897
|
+
}
|
|
9898
|
+
});
|
|
9899
|
+
Object.defineProperty(exports, "processorEnvKeys", {
|
|
9900
|
+
enumerable: true,
|
|
9901
|
+
get: function() {
|
|
9902
|
+
return processorEnvKeys;
|
|
9903
|
+
}
|
|
9904
|
+
});
|
|
9905
|
+
Object.defineProperty(exports, "processorInfo", {
|
|
9906
|
+
enumerable: true,
|
|
9907
|
+
get: function() {
|
|
9908
|
+
return processorInfo;
|
|
9909
|
+
}
|
|
9910
|
+
});
|
|
9911
|
+
Object.defineProperty(exports, "processorNative", {
|
|
9912
|
+
enumerable: true,
|
|
9913
|
+
get: function() {
|
|
9914
|
+
return processorNative;
|
|
9915
|
+
}
|
|
9916
|
+
});
|
|
9917
|
+
Object.defineProperty(exports, "processorOriginHost", {
|
|
9918
|
+
enumerable: true,
|
|
9919
|
+
get: function() {
|
|
9920
|
+
return processorOriginHost;
|
|
9921
|
+
}
|
|
9922
|
+
});
|
|
9923
|
+
Object.defineProperty(exports, "processorUnits", {
|
|
9924
|
+
enumerable: true,
|
|
9925
|
+
get: function() {
|
|
9926
|
+
return processorUnits;
|
|
9927
|
+
}
|
|
9928
|
+
});
|
|
9046
9929
|
Object.defineProperty(exports, "projectKey", {
|
|
9047
9930
|
enumerable: true,
|
|
9048
9931
|
get: function() {
|
|
@@ -9283,6 +10166,12 @@ Object.defineProperty(exports, "verifyDnsRecords", {
|
|
|
9283
10166
|
return verifyDnsRecords;
|
|
9284
10167
|
}
|
|
9285
10168
|
});
|
|
10169
|
+
Object.defineProperty(exports, "watchedBuckets", {
|
|
10170
|
+
enumerable: true,
|
|
10171
|
+
get: function() {
|
|
10172
|
+
return watchedBuckets;
|
|
10173
|
+
}
|
|
10174
|
+
});
|
|
9286
10175
|
Object.defineProperty(exports, "withCustomSecret", {
|
|
9287
10176
|
enumerable: true,
|
|
9288
10177
|
get: function() {
|
|
@@ -9350,4 +10239,4 @@ Object.defineProperty(exports, "workspace_exports", {
|
|
|
9350
10239
|
}
|
|
9351
10240
|
});
|
|
9352
10241
|
|
|
9353
|
-
//# sourceMappingURL=seeds-
|
|
10242
|
+
//# sourceMappingURL=seeds-CPEcmoPn.cjs.map
|