@geekmidas/cli 9.0.2 → 10.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -122
- package/dist/{CachedStateProvider-BdX7klRc.cjs → CachedStateProvider-BLo7zv7S.cjs} +1 -1
- package/dist/CachedStateProvider-BxoAm-B2.mjs +3 -0
- package/dist/{CachedStateProvider-klLWZXWF.cjs → CachedStateProvider-CqPdW7CB.cjs} +1 -1
- package/dist/{CachedStateProvider-klLWZXWF.cjs.map → CachedStateProvider-CqPdW7CB.cjs.map} +1 -1
- package/dist/{CachedStateProvider-CzyFct42.mjs → CachedStateProvider-DTniehMP.mjs} +1 -1
- package/dist/{CachedStateProvider-CzyFct42.mjs.map → CachedStateProvider-DTniehMP.mjs.map} +1 -1
- package/dist/{HostingerProvider-B2ZYz7Yc.mjs → HostingerProvider-Cft7lEYr.mjs} +4 -3
- package/dist/HostingerProvider-Cft7lEYr.mjs.map +1 -0
- package/dist/{HostingerProvider-CrHfsgz9.cjs → HostingerProvider-h3EbEp-Z.cjs} +4 -3
- package/dist/HostingerProvider-h3EbEp-Z.cjs.map +1 -0
- package/dist/{LocalStateProvider-CP49rjzt.mjs → LocalStateProvider-Bn6tS-oL.mjs} +1 -1
- package/dist/{LocalStateProvider-CP49rjzt.mjs.map → LocalStateProvider-Bn6tS-oL.mjs.map} +1 -1
- package/dist/{LocalStateProvider-CalzNfNA.cjs → LocalStateProvider-Db9SEjyH.cjs} +1 -1
- package/dist/{LocalStateProvider-CalzNfNA.cjs.map → LocalStateProvider-Db9SEjyH.cjs.map} +1 -1
- package/dist/{Route53Provider-tlgBzrRQ.mjs → Route53Provider-RdpUDJQk.mjs} +1 -1
- package/dist/{Route53Provider-tlgBzrRQ.mjs.map → Route53Provider-RdpUDJQk.mjs.map} +1 -1
- package/dist/{Route53Provider-DwgXiLxt.cjs → Route53Provider-di2fMM5N.cjs} +1 -1
- package/dist/{Route53Provider-DwgXiLxt.cjs.map → Route53Provider-di2fMM5N.cjs.map} +1 -1
- package/dist/{SSMStateProvider-BlrTiV5m.mjs → SSMStateProvider-BRt2py-A.mjs} +1 -1
- package/dist/{SSMStateProvider-BlrTiV5m.mjs.map → SSMStateProvider-BRt2py-A.mjs.map} +1 -1
- package/dist/{SSMStateProvider-Bt6r8CTL.cjs → SSMStateProvider-DyX8s9HI.cjs} +1 -1
- package/dist/{SSMStateProvider-Bt6r8CTL.cjs.map → SSMStateProvider-DyX8s9HI.cjs.map} +1 -1
- package/dist/{backup-provisioner-Xunq-p_8.mjs → backup-provisioner-Bgj5Vi_L.mjs} +2 -2
- package/dist/{backup-provisioner-Xunq-p_8.mjs.map → backup-provisioner-Bgj5Vi_L.mjs.map} +1 -1
- package/dist/{backup-provisioner-B3HBN-2k.cjs → backup-provisioner-BrsHwYG0.cjs} +2 -2
- package/dist/{backup-provisioner-B3HBN-2k.cjs.map → backup-provisioner-BrsHwYG0.cjs.map} +1 -1
- package/dist/{bundler-Dufq3uvI.cjs → bundler-BY1OmV1e.cjs} +44 -14
- package/dist/bundler-BY1OmV1e.cjs.map +1 -0
- package/dist/{bundler-DkA4qzUD.mjs → bundler-Be8Zg4Wd.mjs} +45 -15
- package/dist/bundler-Be8Zg4Wd.mjs.map +1 -0
- package/dist/config-D8o6I_7Z.mjs +469 -0
- package/dist/config-D8o6I_7Z.mjs.map +1 -0
- package/dist/config-DbPE1KXF.cjs +535 -0
- package/dist/config-DbPE1KXF.cjs.map +1 -0
- package/dist/config.cjs +3 -2
- package/dist/config.d.cts +2 -2
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +2 -2
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +3 -2
- package/dist/{credentials-s1kLcIzK.mjs → credentials-B5zRHdAl.mjs} +21 -6
- package/dist/credentials-B5zRHdAl.mjs.map +1 -0
- package/dist/{credentials-C8DWtnMY.cjs → credentials-BapzjyV5.cjs} +26 -5
- package/dist/credentials-BapzjyV5.cjs.map +1 -0
- package/dist/credentials-Dh0Q6HzY.mjs +2548 -0
- package/dist/credentials-Dh0Q6HzY.mjs.map +1 -0
- package/dist/credentials-K961ThG3.cjs +2680 -0
- package/dist/credentials-K961ThG3.cjs.map +1 -0
- package/dist/deploy/sniffer-routes-worker.cjs +6 -2
- package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
- package/dist/deploy/sniffer-routes-worker.mjs +6 -2
- package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
- package/dist/discover-CAlFgYec.mjs +229 -0
- package/dist/discover-CAlFgYec.mjs.map +1 -0
- package/dist/discover-DTmFeloL.cjs +271 -0
- package/dist/discover-DTmFeloL.cjs.map +1 -0
- package/dist/dokploy-api-BS2xnJLZ.mjs +3 -0
- package/dist/{dokploy-api-CqOIKHme.cjs → dokploy-api-BsVH0y_s.cjs} +141 -32
- package/dist/dokploy-api-BsVH0y_s.cjs.map +1 -0
- package/dist/dokploy-api-BuxDRo3l.cjs +3 -0
- package/dist/{dokploy-api-sfZFlWuE.mjs → dokploy-api-aTFPz7_4.mjs} +141 -32
- package/dist/dokploy-api-aTFPz7_4.mjs.map +1 -0
- package/dist/emit-CbcRolsa.cjs +236 -0
- package/dist/emit-CbcRolsa.cjs.map +1 -0
- package/dist/emit-CiZS_5Ub.mjs +206 -0
- package/dist/emit-CiZS_5Ub.mjs.map +1 -0
- package/dist/{encryption-MfXAiFTm.cjs → encryption-C6jaU0hE.cjs} +1 -1
- package/dist/{encryption-MfXAiFTm.cjs.map → encryption-C6jaU0hE.cjs.map} +1 -1
- package/dist/{encryption-BVS7Vmzs.cjs → encryption-CHzzeR8a.cjs} +1 -1
- package/dist/encryption-CQUncu7v.mjs +3 -0
- package/dist/{encryption-CO5Q4Bhf.mjs → encryption-D-abyhZx.mjs} +1 -1
- package/dist/{encryption-CO5Q4Bhf.mjs.map → encryption-D-abyhZx.mjs.map} +1 -1
- package/dist/fullstack-secrets-C-GGohke.cjs +111 -0
- package/dist/fullstack-secrets-C-GGohke.cjs.map +1 -0
- package/dist/fullstack-secrets-D1o9-G5l.mjs +87 -0
- package/dist/fullstack-secrets-D1o9-G5l.mjs.map +1 -0
- package/dist/{fullstack-secrets-BYzi6Hwl.cjs → generator-CNzBw7g5.cjs} +1 -114
- package/dist/generator-CNzBw7g5.cjs.map +1 -0
- package/dist/{fullstack-secrets-l8s3II_H.mjs → generator-VE2JrFlY.mjs} +2 -85
- package/dist/generator-VE2JrFlY.mjs.map +1 -0
- package/dist/index-BThUzEIp.d.mts +175 -0
- package/dist/index-BThUzEIp.d.mts.map +1 -0
- package/dist/index-CHB4tSzX.d.cts +175 -0
- package/dist/index-CHB4tSzX.d.cts.map +1 -0
- package/dist/index.cjs +2530 -1810
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +2506 -1786
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-Cfwi0fqF.mjs → openapi-CgpMWMmM.mjs} +174 -95
- package/dist/openapi-CgpMWMmM.mjs.map +1 -0
- package/dist/{openapi-BzNOC7_i.cjs → openapi-CljONd_M.cjs} +175 -108
- package/dist/openapi-CljONd_M.cjs.map +1 -0
- package/dist/{openapi-react-query-C4iIvpPf.mjs → openapi-react-query-Byltvm_7.mjs} +2 -2
- package/dist/openapi-react-query-Byltvm_7.mjs.map +1 -0
- package/dist/{openapi-react-query-CYWik72n.cjs → openapi-react-query-CmJ1xDbn.cjs} +2 -2
- package/dist/openapi-react-query-CmJ1xDbn.cjs.map +1 -0
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +4 -3
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +4 -3
- package/dist/reconcile/public.cjs +9 -0
- package/dist/reconcile/public.d.cts +125 -0
- package/dist/reconcile/public.d.cts.map +1 -0
- package/dist/reconcile/public.d.mts +125 -0
- package/dist/reconcile/public.d.mts.map +1 -0
- package/dist/reconcile/public.mjs +4 -0
- package/dist/{reconcile-B2FoJE0a.mjs → reconcile-CFs8C_1a.mjs} +5 -4
- package/dist/reconcile-CFs8C_1a.mjs.map +1 -0
- package/dist/{reconcile-BzqKJ2Rt.cjs → reconcile-D0pimNiy.cjs} +5 -4
- package/dist/reconcile-D0pimNiy.cjs.map +1 -0
- package/dist/setup-CJiQM2pX.cjs +473 -0
- package/dist/setup-CJiQM2pX.cjs.map +1 -0
- package/dist/setup-DMtU3p41.cjs +11 -0
- package/dist/setup-DOsYueeQ.mjs +443 -0
- package/dist/setup-DOsYueeQ.mjs.map +1 -0
- package/dist/setup-DSutDAlt.mjs +11 -0
- package/dist/{storage-B1wvztiJ.cjs → storage-BJmzYxt8.cjs} +1 -1
- package/dist/{storage-B1wvztiJ.cjs.map → storage-BJmzYxt8.cjs.map} +1 -1
- package/dist/{storage-DOEtT2Hr.cjs → storage-BM9hGpgv.cjs} +1 -1
- package/dist/{storage-dbb9RyBl.mjs → storage-Bi24WfoW.mjs} +1 -1
- package/dist/{storage-dbb9RyBl.mjs.map → storage-Bi24WfoW.mjs.map} +1 -1
- package/dist/{storage-Cs4WBsc4.mjs → storage-CYlGwWTj.mjs} +1 -1
- package/dist/{sync-CSooqRQ8.mjs → sync-CmEuNZsB.mjs} +2 -2
- package/dist/{sync-CSooqRQ8.mjs.map → sync-CmEuNZsB.mjs.map} +1 -1
- package/dist/sync-D306yOWu.cjs +4 -0
- package/dist/{sync-o_CtEbvR.cjs → sync-SizaChmC.cjs} +2 -2
- package/dist/{sync-o_CtEbvR.cjs.map → sync-SizaChmC.cjs.map} +1 -1
- package/dist/{sync-B5UHXwRM.mjs → sync-hOqAWHR6.mjs} +1 -1
- package/dist/{index-Bw548Bta.d.mts → types-C-arnQ1r.d.mts} +590 -143
- package/dist/types-C-arnQ1r.d.mts.map +1 -0
- package/dist/{index-DTpkeFb8.d.cts → types-abJQuk7m.d.cts} +590 -143
- package/dist/types-abJQuk7m.d.cts.map +1 -0
- package/dist/workspace/index.cjs +5 -1
- package/dist/workspace/index.d.cts +3 -3
- package/dist/workspace/index.d.mts +3 -3
- package/dist/workspace/index.mjs +2 -2
- package/dist/{workspace-D-37Ylqo.mjs → workspace-7FqprxuJ.mjs} +117 -30
- package/dist/workspace-7FqprxuJ.mjs.map +1 -0
- package/dist/workspace-8acupeaI.cjs +9 -0
- package/dist/{workspace-CQTT7HJQ.cjs → workspace-XvqO9jIv.cjs} +139 -28
- package/dist/workspace-XvqO9jIv.cjs.map +1 -0
- package/dist/workspace-yP5AHnrn.mjs +8 -0
- package/package.json +26 -9
- package/CHANGELOG.md +0 -650
- package/FUNCTION_CRON_SUPPORT.md +0 -266
- package/dist/CachedStateProvider-GcGziXh1.mjs +0 -3
- package/dist/HostingerProvider-B2ZYz7Yc.mjs.map +0 -1
- package/dist/HostingerProvider-CrHfsgz9.cjs.map +0 -1
- package/dist/bundler-DkA4qzUD.mjs.map +0 -1
- package/dist/bundler-Dufq3uvI.cjs.map +0 -1
- package/dist/config-Bbu1JKvf.mjs +0 -211
- package/dist/config-Bbu1JKvf.mjs.map +0 -1
- package/dist/config-DujV8DbR.cjs +0 -253
- package/dist/config-DujV8DbR.cjs.map +0 -1
- package/dist/credentials-C8DWtnMY.cjs.map +0 -1
- package/dist/credentials-s1kLcIzK.mjs.map +0 -1
- package/dist/dokploy-api-BPYkG-ZZ.cjs +0 -3
- package/dist/dokploy-api-BiSzWM4v.mjs +0 -3
- package/dist/dokploy-api-CqOIKHme.cjs.map +0 -1
- package/dist/dokploy-api-sfZFlWuE.mjs.map +0 -1
- package/dist/encryption-Bd_m4q3g.mjs +0 -3
- package/dist/fullstack-secrets-BYzi6Hwl.cjs.map +0 -1
- package/dist/fullstack-secrets-l8s3II_H.mjs.map +0 -1
- package/dist/index-Bw548Bta.d.mts.map +0 -1
- package/dist/index-DTpkeFb8.d.cts.map +0 -1
- package/dist/openapi-BzNOC7_i.cjs.map +0 -1
- package/dist/openapi-Cfwi0fqF.mjs.map +0 -1
- package/dist/openapi-react-query-C4iIvpPf.mjs.map +0 -1
- package/dist/openapi-react-query-CYWik72n.cjs.map +0 -1
- package/dist/reconcile-B2FoJE0a.mjs.map +0 -1
- package/dist/reconcile-BzqKJ2Rt.cjs.map +0 -1
- package/dist/setup-DDXUXzzl.mjs +0 -765
- package/dist/setup-DDXUXzzl.mjs.map +0 -1
- package/dist/setup-DLwhfyt-.cjs +0 -8
- package/dist/setup-Dh-B7YTX.mjs +0 -8
- package/dist/setup-WZ-xqAQO.cjs +0 -849
- package/dist/setup-WZ-xqAQO.cjs.map +0 -1
- package/dist/sync-BLA94rgC.cjs +0 -4
- package/dist/types-B3GQUg3k.d.mts +0 -280
- package/dist/types-B3GQUg3k.d.mts.map +0 -1
- package/dist/types-BWQDiooe.d.cts +0 -280
- package/dist/types-BWQDiooe.d.cts.map +0 -1
- package/dist/workspace-CQTT7HJQ.cjs.map +0 -1
- package/dist/workspace-D-37Ylqo.mjs.map +0 -1
- package/docs/OPENAPI_TYPESCRIPT_DESIGN.md +0 -408
- package/docs/dev-server-resilience-design.md +0 -189
- package/docs/manifest-refactor-design.md +0 -287
- package/examples/cron-example.ts +0 -45
- package/examples/env.ts +0 -33
- package/examples/function-example.ts +0 -40
- package/examples/gkm.config.json +0 -22
- package/examples/gkm.config.ts +0 -14
- package/examples/gkm.minimal.config.json +0 -7
- package/examples/gkm.production.config.json +0 -27
- package/examples/logger.ts +0 -10
- package/scripts/sync-versions.ts +0 -108
- package/src/__tests__/EndpointGenerator.hooks.spec.ts +0 -204
- package/src/__tests__/config.spec.ts +0 -422
- package/src/__tests__/loadEnvFiles.spec.ts +0 -131
- package/src/__tests__/normalizeHooksConfig.spec.ts +0 -63
- package/src/__tests__/openapi-react-query.spec.ts +0 -506
- package/src/__tests__/openapi.spec.ts +0 -625
- package/src/__tests__/test-helpers.ts +0 -181
- package/src/auth/__tests__/credentials.spec.ts +0 -331
- package/src/auth/__tests__/index.spec.ts +0 -237
- package/src/auth/credentials.ts +0 -286
- package/src/auth/index.ts +0 -233
- package/src/build/__tests__/bundler.spec.ts +0 -446
- package/src/build/__tests__/endpoint-analyzer.spec.ts +0 -623
- package/src/build/__tests__/handler-templates.spec.ts +0 -1287
- package/src/build/__tests__/index-new.spec.ts +0 -550
- package/src/build/__tests__/manifests.spec.ts +0 -583
- package/src/build/__tests__/partitions.spec.ts +0 -110
- package/src/build/__tests__/workspace-build.spec.ts +0 -215
- package/src/build/bundler.ts +0 -256
- package/src/build/endpoint-analyzer.ts +0 -236
- package/src/build/handler-templates.ts +0 -1253
- package/src/build/index.ts +0 -616
- package/src/build/manifests.ts +0 -285
- package/src/build/partitions.ts +0 -58
- package/src/build/providerResolver.ts +0 -184
- package/src/build/types.ts +0 -104
- package/src/config.ts +0 -330
- package/src/credentials/__tests__/fullDockerPorts.spec.ts +0 -144
- package/src/credentials/__tests__/helpers.ts +0 -112
- package/src/credentials/__tests__/prepareEntryCredentials.spec.ts +0 -125
- package/src/credentials/__tests__/readonlyDockerPorts.spec.ts +0 -190
- package/src/credentials/__tests__/workspaceCredentials.spec.ts +0 -209
- package/src/credentials/index.ts +0 -843
- package/src/debug.ts +0 -68
- package/src/deploy/CachedStateProvider.ts +0 -86
- package/src/deploy/LocalStateProvider.ts +0 -57
- package/src/deploy/SSMStateProvider.ts +0 -117
- package/src/deploy/StateProvider.ts +0 -175
- package/src/deploy/__tests__/CachedStateProvider.spec.ts +0 -235
- package/src/deploy/__tests__/HostingerProvider.spec.ts +0 -347
- package/src/deploy/__tests__/LocalStateProvider.spec.ts +0 -130
- package/src/deploy/__tests__/Route53Provider.spec.ts +0 -425
- package/src/deploy/__tests__/SSMStateProvider.spec.ts +0 -201
- package/src/deploy/__tests__/__fixtures__/entry-apps/async-entry.ts +0 -24
- package/src/deploy/__tests__/__fixtures__/entry-apps/nested-config-entry.ts +0 -24
- package/src/deploy/__tests__/__fixtures__/entry-apps/no-env-entry.ts +0 -12
- package/src/deploy/__tests__/__fixtures__/entry-apps/simple-entry.ts +0 -14
- package/src/deploy/__tests__/__fixtures__/entry-apps/throwing-entry.ts +0 -16
- package/src/deploy/__tests__/__fixtures__/env-parsers/non-function-export.ts +0 -10
- package/src/deploy/__tests__/__fixtures__/env-parsers/optional-env-parser.ts +0 -21
- package/src/deploy/__tests__/__fixtures__/env-parsers/parseable-env-parser.ts +0 -18
- package/src/deploy/__tests__/__fixtures__/env-parsers/throwing-env-parser.ts +0 -16
- package/src/deploy/__tests__/__fixtures__/env-parsers/valid-env-parser.ts +0 -16
- package/src/deploy/__tests__/__fixtures__/route-apps/endpoints/auth.ts +0 -16
- package/src/deploy/__tests__/__fixtures__/route-apps/endpoints/health.ts +0 -13
- package/src/deploy/__tests__/__fixtures__/route-apps/endpoints/users.ts +0 -15
- package/src/deploy/__tests__/__fixtures__/route-apps/services.ts +0 -55
- package/src/deploy/__tests__/backup-provisioner.spec.ts +0 -428
- package/src/deploy/__tests__/createDnsProvider.spec.ts +0 -195
- package/src/deploy/__tests__/createStateProvider.spec.ts +0 -126
- package/src/deploy/__tests__/dns-orchestration.spec.ts +0 -192
- package/src/deploy/__tests__/dns-verification.spec.ts +0 -229
- package/src/deploy/__tests__/docker.spec.ts +0 -149
- package/src/deploy/__tests__/dokploy-api.spec.ts +0 -697
- package/src/deploy/__tests__/dokploy.spec.ts +0 -435
- package/src/deploy/__tests__/domain.spec.ts +0 -235
- package/src/deploy/__tests__/env-resolver.spec.ts +0 -903
- package/src/deploy/__tests__/index.spec.ts +0 -1091
- package/src/deploy/__tests__/init.spec.ts +0 -793
- package/src/deploy/__tests__/secrets.spec.ts +0 -303
- package/src/deploy/__tests__/sniffer.spec.ts +0 -838
- package/src/deploy/__tests__/state-e2e.spec.ts +0 -387
- package/src/deploy/__tests__/state.spec.ts +0 -876
- package/src/deploy/__tests__/undeploy.spec.ts +0 -758
- package/src/deploy/backup-provisioner.ts +0 -316
- package/src/deploy/dns/DnsProvider.ts +0 -201
- package/src/deploy/dns/HostingerProvider.ts +0 -174
- package/src/deploy/dns/Route53Provider.ts +0 -340
- package/src/deploy/dns/hostinger-api.ts +0 -261
- package/src/deploy/dns/index.ts +0 -627
- package/src/deploy/docker.ts +0 -260
- package/src/deploy/dokploy-api.ts +0 -1101
- package/src/deploy/dokploy.ts +0 -177
- package/src/deploy/domain.ts +0 -134
- package/src/deploy/env-resolver.ts +0 -305
- package/src/deploy/index.ts +0 -2094
- package/src/deploy/init.ts +0 -427
- package/src/deploy/secrets.ts +0 -187
- package/src/deploy/sniffer-envkit-patch.ts +0 -61
- package/src/deploy/sniffer-hooks.ts +0 -57
- package/src/deploy/sniffer-loader.ts +0 -28
- package/src/deploy/sniffer-routes-worker.ts +0 -104
- package/src/deploy/sniffer-worker.ts +0 -75
- package/src/deploy/sniffer.ts +0 -578
- package/src/deploy/state-commands.ts +0 -274
- package/src/deploy/state.ts +0 -482
- package/src/deploy/types.ts +0 -102
- package/src/deploy/undeploy.ts +0 -407
- package/src/dev/__tests__/entry-integration.spec.ts +0 -347
- package/src/dev/__tests__/entry.spec.ts +0 -144
- package/src/dev/__tests__/index.spec.ts +0 -2084
- package/src/dev/index.ts +0 -1649
- package/src/docker/__tests__/compose.spec.ts +0 -1142
- package/src/docker/__tests__/templates.spec.ts +0 -694
- package/src/docker/compose.ts +0 -808
- package/src/docker/index.ts +0 -523
- package/src/docker/templates.ts +0 -1067
- package/src/exec/index.ts +0 -118
- package/src/generators/CronGenerator.ts +0 -105
- package/src/generators/EndpointGenerator.ts +0 -954
- package/src/generators/FunctionGenerator.ts +0 -117
- package/src/generators/Generator.ts +0 -147
- package/src/generators/OpenApiTsGenerator.ts +0 -821
- package/src/generators/QueueGenerator.ts +0 -245
- package/src/generators/SubscriberGenerator.ts +0 -282
- package/src/generators/TopicGenerator.ts +0 -45
- package/src/generators/__tests__/CronGenerator.spec.ts +0 -445
- package/src/generators/__tests__/EndpointGenerator.spec.ts +0 -544
- package/src/generators/__tests__/FunctionGenerator.spec.ts +0 -256
- package/src/generators/__tests__/Generator.bustCache.spec.ts +0 -72
- package/src/generators/__tests__/OpenApiTsGenerator.registry.spec.ts +0 -98
- package/src/generators/__tests__/OpenApiTsGenerator.responseType.spec.ts +0 -56
- package/src/generators/__tests__/QueueGenerator.spec.ts +0 -141
- package/src/generators/__tests__/SubscriberGenerator.spec.ts +0 -410
- package/src/generators/index.ts +0 -11
- package/src/index.ts +0 -972
- package/src/init/__tests__/generators.spec.ts +0 -1070
- package/src/init/__tests__/init.spec.ts +0 -577
- package/src/init/__tests__/utils.spec.ts +0 -104
- package/src/init/generators/auth.ts +0 -225
- package/src/init/generators/config.ts +0 -316
- package/src/init/generators/docker.ts +0 -388
- package/src/init/generators/env.ts +0 -62
- package/src/init/generators/index.ts +0 -6
- package/src/init/generators/mobile-expo.ts +0 -576
- package/src/init/generators/models.ts +0 -153
- package/src/init/generators/monorepo.ts +0 -475
- package/src/init/generators/package.ts +0 -95
- package/src/init/generators/source.ts +0 -15
- package/src/init/generators/test.ts +0 -178
- package/src/init/generators/ui.ts +0 -1473
- package/src/init/generators/web-tanstack.ts +0 -348
- package/src/init/generators/web.ts +0 -363
- package/src/init/index.ts +0 -542
- package/src/init/templates/api.ts +0 -404
- package/src/init/templates/index.ts +0 -342
- package/src/init/templates/minimal.ts +0 -207
- package/src/init/templates/serverless.ts +0 -148
- package/src/init/templates/worker.ts +0 -216
- package/src/init/utils.ts +0 -197
- package/src/init/versions.ts +0 -52
- package/src/openapi-react-query.ts +0 -288
- package/src/openapi.ts +0 -259
- package/src/secrets/__tests__/encryption.spec.ts +0 -226
- package/src/secrets/__tests__/generator.spec.ts +0 -575
- package/src/secrets/__tests__/index.spec.ts +0 -91
- package/src/secrets/__tests__/reconcile.spec.ts +0 -123
- package/src/secrets/__tests__/storage.spec.ts +0 -645
- package/src/secrets/encryption.ts +0 -91
- package/src/secrets/generator.ts +0 -329
- package/src/secrets/index.ts +0 -417
- package/src/secrets/keystore.ts +0 -144
- package/src/secrets/reconcile.ts +0 -53
- package/src/secrets/storage.ts +0 -337
- package/src/secrets/sync.ts +0 -136
- package/src/secrets/types.ts +0 -70
- package/src/setup/__tests__/auto-setup.spec.ts +0 -147
- package/src/setup/__tests__/reconcile-secrets.spec.ts +0 -439
- package/src/setup/fullstack-secrets.ts +0 -140
- package/src/setup/index.ts +0 -411
- package/src/test/__tests__/__fixtures__/workspace.ts +0 -104
- package/src/test/__tests__/api.spec.ts +0 -199
- package/src/test/__tests__/auth.spec.ts +0 -162
- package/src/test/__tests__/index.spec.ts +0 -502
- package/src/test/__tests__/web.spec.ts +0 -210
- package/src/test/index.ts +0 -198
- package/src/types.ts +0 -363
- package/src/upgrade/__tests__/index.spec.ts +0 -354
- package/src/upgrade/index.ts +0 -253
- package/src/workspace/__tests__/client-generator.spec.ts +0 -326
- package/src/workspace/__tests__/index.spec.ts +0 -766
- package/src/workspace/__tests__/publicEnv.spec.ts +0 -64
- package/src/workspace/__tests__/schema.spec.ts +0 -737
- package/src/workspace/__tests__/type-inference.spec.ts +0 -251
- package/src/workspace/client-generator.ts +0 -109
- package/src/workspace/index.ts +0 -433
- package/src/workspace/publicEnv.ts +0 -57
- package/src/workspace/schema.ts +0 -861
- package/src/workspace/types.ts +0 -943
- package/tsconfig.json +0 -9
- package/tsdown.config.ts +0 -22
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Entry app fixture that throws during initialization.
|
|
3
|
-
* Tests that env vars are still captured even when the entry throws.
|
|
4
|
-
*/
|
|
5
|
-
import { EnvironmentParser } from '@geekmidas/envkit';
|
|
6
|
-
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
8
|
-
const _config = new EnvironmentParser(process.env as Record<string, string>)
|
|
9
|
-
.create((get) => ({
|
|
10
|
-
port: get('PORT').string().transform(Number),
|
|
11
|
-
apiKey: get('API_KEY').string(),
|
|
12
|
-
}))
|
|
13
|
-
.parse();
|
|
14
|
-
|
|
15
|
-
// Throw after env vars are accessed
|
|
16
|
-
throw new Error('Initialization failed: Missing required configuration');
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A fixture that exports a non-function for testing error handling.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// Export a string instead of a function
|
|
6
|
-
export const envParser = 'not a function';
|
|
7
|
-
|
|
8
|
-
// Default export is also not a function
|
|
9
|
-
const defaultValue = { notAFunction: true };
|
|
10
|
-
export default defaultValue;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* An envParser fixture that mixes required and optional/default variables.
|
|
3
|
-
* Used to test the markOptional feature.
|
|
4
|
-
*/
|
|
5
|
-
import type { SnifferEnvironmentParser } from '@geekmidas/envkit/sniffer';
|
|
6
|
-
|
|
7
|
-
export function envParser(parser: SnifferEnvironmentParser) {
|
|
8
|
-
return parser.create((get) => ({
|
|
9
|
-
// Required
|
|
10
|
-
databaseUrl: get('DATABASE_URL').string(),
|
|
11
|
-
apiKey: get('API_KEY').string(),
|
|
12
|
-
// Optional via .optional()
|
|
13
|
-
logLevel: get('LOG_LEVEL').string().optional(),
|
|
14
|
-
// Optional via .default()
|
|
15
|
-
port: get('PORT').string().default('3000'),
|
|
16
|
-
// Optional via .default() after transform
|
|
17
|
-
timeout: get('TIMEOUT').string().transform(Number).default(5000),
|
|
18
|
-
}));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export default envParser;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* An envParser that returns a config with a parse() method.
|
|
3
|
-
*/
|
|
4
|
-
import type { SnifferEnvironmentParser } from '@geekmidas/envkit/sniffer';
|
|
5
|
-
|
|
6
|
-
export function envParser(parser: SnifferEnvironmentParser) {
|
|
7
|
-
// Create a config that will fail on parse() due to missing env vars
|
|
8
|
-
// This tests the try/catch around result.parse()
|
|
9
|
-
const config = parser.create((get) => ({
|
|
10
|
-
port: get('PORT').string(),
|
|
11
|
-
databaseUrl: get('DATABASE_URL').string(),
|
|
12
|
-
apiKey: get('API_KEY').string(),
|
|
13
|
-
}));
|
|
14
|
-
|
|
15
|
-
return config;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export default envParser;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* An envParser that accesses some env vars then throws.
|
|
3
|
-
*/
|
|
4
|
-
import type { SnifferEnvironmentParser } from '@geekmidas/envkit/sniffer';
|
|
5
|
-
|
|
6
|
-
export function envParser(parser: SnifferEnvironmentParser) {
|
|
7
|
-
const _config = parser.create((get) => ({
|
|
8
|
-
port: get('PORT').string(),
|
|
9
|
-
apiKey: get('API_KEY').string(),
|
|
10
|
-
}));
|
|
11
|
-
|
|
12
|
-
// Throw after creating the parser but before returning
|
|
13
|
-
throw new Error('EnvParser initialization failed');
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export default envParser;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A valid envParser fixture that returns a parseable config.
|
|
3
|
-
*/
|
|
4
|
-
import type { SnifferEnvironmentParser } from '@geekmidas/envkit/sniffer';
|
|
5
|
-
|
|
6
|
-
export function envParser(parser: SnifferEnvironmentParser) {
|
|
7
|
-
return parser.create((get) => ({
|
|
8
|
-
port: get('PORT').string(),
|
|
9
|
-
database: {
|
|
10
|
-
url: get('DATABASE_URL').string(),
|
|
11
|
-
poolSize: get('DB_POOL_SIZE').string(),
|
|
12
|
-
},
|
|
13
|
-
}));
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export default envParser;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test endpoint with multiple services.
|
|
3
|
-
* getEnvironment() should return ['AUTH_SECRET', 'AUTH_URL', 'DATABASE_URL', 'DB_POOL_SIZE'].
|
|
4
|
-
*/
|
|
5
|
-
import { e } from '@geekmidas/constructs/endpoints';
|
|
6
|
-
import { z } from 'zod';
|
|
7
|
-
import { authService, databaseService } from '../services';
|
|
8
|
-
|
|
9
|
-
export const login = e
|
|
10
|
-
.services([databaseService, authService])
|
|
11
|
-
.post('/auth/login')
|
|
12
|
-
.body(z.object({ email: z.string(), password: z.string() }))
|
|
13
|
-
.output(z.object({ token: z.string() }))
|
|
14
|
-
.handle(async () => {
|
|
15
|
-
return { token: 'test-token' };
|
|
16
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test endpoint without any services.
|
|
3
|
-
* getEnvironment() should return [].
|
|
4
|
-
*/
|
|
5
|
-
import { e } from '@geekmidas/constructs/endpoints';
|
|
6
|
-
import { z } from 'zod';
|
|
7
|
-
|
|
8
|
-
export const healthCheck = e
|
|
9
|
-
.get('/health')
|
|
10
|
-
.output(z.object({ status: z.string() }))
|
|
11
|
-
.handle(async () => {
|
|
12
|
-
return { status: 'ok' };
|
|
13
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test endpoint with database service.
|
|
3
|
-
* getEnvironment() should return ['DATABASE_URL', 'DB_POOL_SIZE'].
|
|
4
|
-
*/
|
|
5
|
-
import { e } from '@geekmidas/constructs/endpoints';
|
|
6
|
-
import { z } from 'zod';
|
|
7
|
-
import { databaseService } from '../services';
|
|
8
|
-
|
|
9
|
-
export const getUsers = e
|
|
10
|
-
.services([databaseService])
|
|
11
|
-
.get('/users')
|
|
12
|
-
.output(z.array(z.object({ id: z.string(), name: z.string() })))
|
|
13
|
-
.handle(async () => {
|
|
14
|
-
return [{ id: '1', name: 'Test User' }];
|
|
15
|
-
});
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test services for route-based app sniffing fixtures.
|
|
3
|
-
* These services access environment variables via envParser.create().
|
|
4
|
-
*/
|
|
5
|
-
import type { EnvironmentParser } from '@geekmidas/envkit';
|
|
6
|
-
|
|
7
|
-
// Simple Service type for test fixtures (avoids importing @geekmidas/services)
|
|
8
|
-
type TestService<TName extends string, TInstance> = {
|
|
9
|
-
serviceName: TName;
|
|
10
|
-
register(ctx: {
|
|
11
|
-
envParser: EnvironmentParser<Record<string, string | undefined>>;
|
|
12
|
-
}): Promise<TInstance>;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
// Database service - requires DATABASE_URL
|
|
16
|
-
export const databaseService: TestService<'database', { url: string }> = {
|
|
17
|
-
serviceName: 'database' as const,
|
|
18
|
-
async register({ envParser }) {
|
|
19
|
-
const config = envParser
|
|
20
|
-
.create((get) => ({
|
|
21
|
-
url: get('DATABASE_URL').string(),
|
|
22
|
-
poolSize: get('DB_POOL_SIZE').string().transform(Number).optional(),
|
|
23
|
-
}))
|
|
24
|
-
.parse();
|
|
25
|
-
return { url: config.url };
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// Cache service - requires REDIS_URL
|
|
30
|
-
export const cacheService: TestService<'cache', { url: string }> = {
|
|
31
|
-
serviceName: 'cache' as const,
|
|
32
|
-
async register({ envParser }) {
|
|
33
|
-
const config = envParser
|
|
34
|
-
.create((get) => ({
|
|
35
|
-
url: get('REDIS_URL').string(),
|
|
36
|
-
}))
|
|
37
|
-
.parse();
|
|
38
|
-
return { url: config.url };
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// Auth service - requires AUTH_SECRET and AUTH_URL
|
|
43
|
-
export const authService: TestService<'auth', { secret: string; url: string }> =
|
|
44
|
-
{
|
|
45
|
-
serviceName: 'auth' as const,
|
|
46
|
-
async register({ envParser }) {
|
|
47
|
-
const config = envParser
|
|
48
|
-
.create((get) => ({
|
|
49
|
-
secret: get('AUTH_SECRET').string(),
|
|
50
|
-
url: get('AUTH_URL').string(),
|
|
51
|
-
}))
|
|
52
|
-
.parse();
|
|
53
|
-
return { secret: config.secret, url: config.url };
|
|
54
|
-
},
|
|
55
|
-
};
|
|
@@ -1,428 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DeleteAccessKeyCommand,
|
|
3
|
-
DeleteUserCommand,
|
|
4
|
-
DeleteUserPolicyCommand,
|
|
5
|
-
GetUserCommand,
|
|
6
|
-
IAMClient,
|
|
7
|
-
ListAccessKeysCommand,
|
|
8
|
-
} from '@aws-sdk/client-iam';
|
|
9
|
-
import {
|
|
10
|
-
DeleteBucketCommand,
|
|
11
|
-
DeleteObjectsCommand,
|
|
12
|
-
ListObjectsV2Command,
|
|
13
|
-
S3Client,
|
|
14
|
-
} from '@aws-sdk/client-s3';
|
|
15
|
-
import { HttpResponse, http } from 'msw';
|
|
16
|
-
import { setupServer } from 'msw/node';
|
|
17
|
-
import {
|
|
18
|
-
afterAll,
|
|
19
|
-
afterEach,
|
|
20
|
-
beforeAll,
|
|
21
|
-
beforeEach,
|
|
22
|
-
describe,
|
|
23
|
-
expect,
|
|
24
|
-
it,
|
|
25
|
-
} from 'vitest';
|
|
26
|
-
import {
|
|
27
|
-
type ProvisionBackupOptions,
|
|
28
|
-
provisionBackupDestination,
|
|
29
|
-
} from '../backup-provisioner';
|
|
30
|
-
import { DokployApi } from '../dokploy-api';
|
|
31
|
-
import type { BackupState } from '../state';
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Backup Provisioner Tests
|
|
35
|
-
*
|
|
36
|
-
* These tests require LocalStack to be running with S3 and IAM enabled.
|
|
37
|
-
* Run: docker compose up -d localstack
|
|
38
|
-
*/
|
|
39
|
-
describe('backup-provisioner', () => {
|
|
40
|
-
const LOCALSTACK_ENDPOINT = 'http://localhost:4566';
|
|
41
|
-
const DOKPLOY_BASE_URL = 'https://dokploy.example.com';
|
|
42
|
-
|
|
43
|
-
let s3Client: S3Client;
|
|
44
|
-
let iamClient: IAMClient;
|
|
45
|
-
let dokployApi: DokployApi;
|
|
46
|
-
|
|
47
|
-
const server = setupServer();
|
|
48
|
-
const logs: string[] = [];
|
|
49
|
-
const logger = { log: (msg: string) => logs.push(msg) };
|
|
50
|
-
|
|
51
|
-
// Track created resources for cleanup
|
|
52
|
-
const createdBuckets: string[] = [];
|
|
53
|
-
const createdUsers: string[] = [];
|
|
54
|
-
|
|
55
|
-
beforeAll(() => {
|
|
56
|
-
process.env.AWS_ACCESS_KEY_ID = 'test';
|
|
57
|
-
process.env.AWS_SECRET_ACCESS_KEY = 'test';
|
|
58
|
-
server.listen({ onUnhandledRequest: 'bypass' });
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
beforeEach(() => {
|
|
62
|
-
logs.length = 0;
|
|
63
|
-
|
|
64
|
-
s3Client = new S3Client({
|
|
65
|
-
region: 'us-east-1',
|
|
66
|
-
endpoint: LOCALSTACK_ENDPOINT,
|
|
67
|
-
forcePathStyle: true,
|
|
68
|
-
credentials: {
|
|
69
|
-
accessKeyId: 'test',
|
|
70
|
-
secretAccessKey: 'test',
|
|
71
|
-
},
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
iamClient = new IAMClient({
|
|
75
|
-
region: 'us-east-1',
|
|
76
|
-
endpoint: LOCALSTACK_ENDPOINT,
|
|
77
|
-
credentials: {
|
|
78
|
-
accessKeyId: 'test',
|
|
79
|
-
secretAccessKey: 'test',
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
dokployApi = new DokployApi({
|
|
84
|
-
baseUrl: DOKPLOY_BASE_URL,
|
|
85
|
-
token: 'test-api-token',
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
afterEach(async () => {
|
|
90
|
-
server.resetHandlers();
|
|
91
|
-
|
|
92
|
-
// Cleanup created buckets
|
|
93
|
-
for (const bucket of createdBuckets) {
|
|
94
|
-
try {
|
|
95
|
-
// First delete all objects in the bucket
|
|
96
|
-
const objects = await s3Client.send(
|
|
97
|
-
new ListObjectsV2Command({ Bucket: bucket }),
|
|
98
|
-
);
|
|
99
|
-
if (objects.Contents?.length) {
|
|
100
|
-
await s3Client.send(
|
|
101
|
-
new DeleteObjectsCommand({
|
|
102
|
-
Bucket: bucket,
|
|
103
|
-
Delete: {
|
|
104
|
-
Objects: objects.Contents.map((o) => ({ Key: o.Key })),
|
|
105
|
-
},
|
|
106
|
-
}),
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
await s3Client.send(new DeleteBucketCommand({ Bucket: bucket }));
|
|
110
|
-
} catch {
|
|
111
|
-
// Ignore cleanup errors
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
createdBuckets.length = 0;
|
|
115
|
-
|
|
116
|
-
// Cleanup created IAM users
|
|
117
|
-
for (const userName of createdUsers) {
|
|
118
|
-
try {
|
|
119
|
-
// Delete access keys first
|
|
120
|
-
const keys = await iamClient.send(
|
|
121
|
-
new ListAccessKeysCommand({ UserName: userName }),
|
|
122
|
-
);
|
|
123
|
-
for (const key of keys.AccessKeyMetadata ?? []) {
|
|
124
|
-
await iamClient.send(
|
|
125
|
-
new DeleteAccessKeyCommand({
|
|
126
|
-
UserName: userName,
|
|
127
|
-
AccessKeyId: key.AccessKeyId,
|
|
128
|
-
}),
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
// Delete user policy
|
|
132
|
-
await iamClient.send(
|
|
133
|
-
new DeleteUserPolicyCommand({
|
|
134
|
-
UserName: userName,
|
|
135
|
-
PolicyName: 'DokployBackupAccess',
|
|
136
|
-
}),
|
|
137
|
-
);
|
|
138
|
-
// Delete user
|
|
139
|
-
await iamClient.send(new DeleteUserCommand({ UserName: userName }));
|
|
140
|
-
} catch {
|
|
141
|
-
// Ignore cleanup errors
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
createdUsers.length = 0;
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
afterAll(() => {
|
|
148
|
-
server.close();
|
|
149
|
-
s3Client.destroy();
|
|
150
|
-
iamClient.destroy();
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Helper to create provision options with LocalStack clients
|
|
155
|
-
*/
|
|
156
|
-
function createOptions(
|
|
157
|
-
overrides: Partial<ProvisionBackupOptions> = {},
|
|
158
|
-
): ProvisionBackupOptions {
|
|
159
|
-
return {
|
|
160
|
-
api: dokployApi,
|
|
161
|
-
projectId: 'proj_test123',
|
|
162
|
-
projectName: 'test-project',
|
|
163
|
-
stage: 'production',
|
|
164
|
-
config: {
|
|
165
|
-
type: 's3',
|
|
166
|
-
region: 'us-east-1',
|
|
167
|
-
},
|
|
168
|
-
logger,
|
|
169
|
-
awsEndpoint: LOCALSTACK_ENDPOINT,
|
|
170
|
-
...overrides,
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Setup mock Dokploy API responses
|
|
176
|
-
*/
|
|
177
|
-
function setupDokployMocks(options: {
|
|
178
|
-
existingDestination?: { destinationId: string; name: string };
|
|
179
|
-
createDestinationId?: string;
|
|
180
|
-
}) {
|
|
181
|
-
const handlers = [
|
|
182
|
-
// List destinations
|
|
183
|
-
http.get(`${DOKPLOY_BASE_URL}/api/destination.all`, () => {
|
|
184
|
-
if (options.existingDestination) {
|
|
185
|
-
return HttpResponse.json([options.existingDestination]);
|
|
186
|
-
}
|
|
187
|
-
return HttpResponse.json([]);
|
|
188
|
-
}),
|
|
189
|
-
|
|
190
|
-
// Get destination
|
|
191
|
-
http.get(`${DOKPLOY_BASE_URL}/api/destination.one`, ({ request }) => {
|
|
192
|
-
const url = new URL(request.url);
|
|
193
|
-
const destId = url.searchParams.get('destinationId');
|
|
194
|
-
if (
|
|
195
|
-
options.existingDestination &&
|
|
196
|
-
destId === options.existingDestination.destinationId
|
|
197
|
-
) {
|
|
198
|
-
return HttpResponse.json(options.existingDestination);
|
|
199
|
-
}
|
|
200
|
-
return HttpResponse.json({ message: 'Not found' }, { status: 404 });
|
|
201
|
-
}),
|
|
202
|
-
|
|
203
|
-
// Create destination
|
|
204
|
-
http.post(`${DOKPLOY_BASE_URL}/api/destination.create`, () => {
|
|
205
|
-
return HttpResponse.json({
|
|
206
|
-
destinationId: options.createDestinationId ?? 'dest_new123',
|
|
207
|
-
name: 'test-project-production-s3',
|
|
208
|
-
});
|
|
209
|
-
}),
|
|
210
|
-
|
|
211
|
-
// Test destination connection
|
|
212
|
-
http.post(`${DOKPLOY_BASE_URL}/api/destination.testConnection`, () => {
|
|
213
|
-
return HttpResponse.json({ success: true });
|
|
214
|
-
}),
|
|
215
|
-
];
|
|
216
|
-
|
|
217
|
-
server.use(...handlers);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
describe('provisionBackupDestination', () => {
|
|
221
|
-
it('should create S3 bucket with unique name', async () => {
|
|
222
|
-
setupDokployMocks({ createDestinationId: 'dest_123' });
|
|
223
|
-
|
|
224
|
-
const options = createOptions();
|
|
225
|
-
const result = await provisionBackupDestination(options);
|
|
226
|
-
|
|
227
|
-
// Track for cleanup
|
|
228
|
-
createdBuckets.push(result.bucketName);
|
|
229
|
-
createdUsers.push(result.iamUserName);
|
|
230
|
-
|
|
231
|
-
expect(result.bucketName).toMatch(/^test-project-production-backups-/);
|
|
232
|
-
expect(result.bucketArn).toBe(`arn:aws:s3:::${result.bucketName}`);
|
|
233
|
-
expect(logs.some((l) => l.includes('Creating S3 bucket'))).toBe(true);
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it('should create IAM user with correct name', async () => {
|
|
237
|
-
setupDokployMocks({ createDestinationId: 'dest_123' });
|
|
238
|
-
|
|
239
|
-
const options = createOptions();
|
|
240
|
-
const result = await provisionBackupDestination(options);
|
|
241
|
-
|
|
242
|
-
// Track for cleanup
|
|
243
|
-
createdBuckets.push(result.bucketName);
|
|
244
|
-
createdUsers.push(result.iamUserName);
|
|
245
|
-
|
|
246
|
-
expect(result.iamUserName).toBe('dokploy-backup-test-project-production');
|
|
247
|
-
|
|
248
|
-
// Verify user exists in IAM
|
|
249
|
-
const userResponse = await iamClient.send(
|
|
250
|
-
new GetUserCommand({ UserName: result.iamUserName }),
|
|
251
|
-
);
|
|
252
|
-
expect(userResponse.User?.UserName).toBe(result.iamUserName);
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it('should create IAM access key', async () => {
|
|
256
|
-
setupDokployMocks({ createDestinationId: 'dest_123' });
|
|
257
|
-
|
|
258
|
-
const options = createOptions();
|
|
259
|
-
const result = await provisionBackupDestination(options);
|
|
260
|
-
|
|
261
|
-
// Track for cleanup
|
|
262
|
-
createdBuckets.push(result.bucketName);
|
|
263
|
-
createdUsers.push(result.iamUserName);
|
|
264
|
-
|
|
265
|
-
expect(result.iamAccessKeyId).toBeDefined();
|
|
266
|
-
expect(result.iamSecretAccessKey).toBeDefined();
|
|
267
|
-
expect(result.iamAccessKeyId.length).toBeGreaterThan(0);
|
|
268
|
-
expect(result.iamSecretAccessKey.length).toBeGreaterThan(0);
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
it('should create Dokploy destination', async () => {
|
|
272
|
-
setupDokployMocks({ createDestinationId: 'dest_created' });
|
|
273
|
-
|
|
274
|
-
const options = createOptions();
|
|
275
|
-
const result = await provisionBackupDestination(options);
|
|
276
|
-
|
|
277
|
-
// Track for cleanup
|
|
278
|
-
createdBuckets.push(result.bucketName);
|
|
279
|
-
createdUsers.push(result.iamUserName);
|
|
280
|
-
|
|
281
|
-
expect(result.destinationId).toBe('dest_created');
|
|
282
|
-
expect(logs.some((l) => l.includes('Dokploy destination created'))).toBe(
|
|
283
|
-
true,
|
|
284
|
-
);
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
it('should reuse existing state when destination still exists', async () => {
|
|
288
|
-
const existingState: BackupState = {
|
|
289
|
-
bucketName: 'existing-bucket',
|
|
290
|
-
bucketArn: 'arn:aws:s3:::existing-bucket',
|
|
291
|
-
iamUserName: 'existing-user',
|
|
292
|
-
iamAccessKeyId: 'AKIA123',
|
|
293
|
-
iamSecretAccessKey: 'secret123',
|
|
294
|
-
destinationId: 'dest_existing',
|
|
295
|
-
region: 'us-east-1',
|
|
296
|
-
createdAt: '2024-01-01T00:00:00.000Z',
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
setupDokployMocks({
|
|
300
|
-
existingDestination: {
|
|
301
|
-
destinationId: 'dest_existing',
|
|
302
|
-
name: 'existing',
|
|
303
|
-
},
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
const options = createOptions({ existingState });
|
|
307
|
-
const result = await provisionBackupDestination(options);
|
|
308
|
-
|
|
309
|
-
// Should return existing state without creating new resources
|
|
310
|
-
expect(result).toEqual(existingState);
|
|
311
|
-
expect(
|
|
312
|
-
logs.some((l) => l.includes('Using existing backup destination')),
|
|
313
|
-
).toBe(true);
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
it('should recreate destination if existing one not found', async () => {
|
|
317
|
-
const existingState: BackupState = {
|
|
318
|
-
bucketName: 'existing-bucket',
|
|
319
|
-
bucketArn: 'arn:aws:s3:::existing-bucket',
|
|
320
|
-
iamUserName: 'dokploy-backup-test-project-production',
|
|
321
|
-
iamAccessKeyId: 'AKIA123',
|
|
322
|
-
iamSecretAccessKey: 'secret123',
|
|
323
|
-
destinationId: 'dest_deleted',
|
|
324
|
-
region: 'us-east-1',
|
|
325
|
-
createdAt: '2024-01-01T00:00:00.000Z',
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
// Mock: destination.one returns 404, meaning destination was deleted
|
|
329
|
-
setupDokployMocks({ createDestinationId: 'dest_new' });
|
|
330
|
-
|
|
331
|
-
const options = createOptions({ existingState });
|
|
332
|
-
const result = await provisionBackupDestination(options);
|
|
333
|
-
|
|
334
|
-
// Track for cleanup (uses existing bucket name from state)
|
|
335
|
-
createdBuckets.push(result.bucketName);
|
|
336
|
-
createdUsers.push(result.iamUserName);
|
|
337
|
-
|
|
338
|
-
// Should reuse bucket name from state
|
|
339
|
-
expect(result.bucketName).toBe('existing-bucket');
|
|
340
|
-
// Should reuse IAM user name
|
|
341
|
-
expect(result.iamUserName).toBe('dokploy-backup-test-project-production');
|
|
342
|
-
// Should reuse credentials from state
|
|
343
|
-
expect(result.iamAccessKeyId).toBe('AKIA123');
|
|
344
|
-
// Should create new destination
|
|
345
|
-
expect(result.destinationId).toBe('dest_new');
|
|
346
|
-
expect(
|
|
347
|
-
logs.some((l) => l.includes('Existing destination not found')),
|
|
348
|
-
).toBe(true);
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
it('should sanitize project name for AWS resources', async () => {
|
|
352
|
-
setupDokployMocks({ createDestinationId: 'dest_123' });
|
|
353
|
-
|
|
354
|
-
const options = createOptions({
|
|
355
|
-
projectName: 'My Project_Name!@#',
|
|
356
|
-
});
|
|
357
|
-
const result = await provisionBackupDestination(options);
|
|
358
|
-
|
|
359
|
-
// Track for cleanup
|
|
360
|
-
createdBuckets.push(result.bucketName);
|
|
361
|
-
createdUsers.push(result.iamUserName);
|
|
362
|
-
|
|
363
|
-
// Should be lowercase with only alphanumeric and hyphens
|
|
364
|
-
// 'My Project_Name!@#' -> 'my-project-name----' (space, underscore, !, @, # all become hyphens)
|
|
365
|
-
expect(result.bucketName).toMatch(
|
|
366
|
-
/^my-project-name----production-backups-/,
|
|
367
|
-
);
|
|
368
|
-
expect(result.iamUserName).toBe(
|
|
369
|
-
'dokploy-backup-my-project-name----production',
|
|
370
|
-
);
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
it('should return complete BackupState', async () => {
|
|
374
|
-
setupDokployMocks({ createDestinationId: 'dest_complete' });
|
|
375
|
-
|
|
376
|
-
const options = createOptions();
|
|
377
|
-
const result = await provisionBackupDestination(options);
|
|
378
|
-
|
|
379
|
-
// Track for cleanup
|
|
380
|
-
createdBuckets.push(result.bucketName);
|
|
381
|
-
createdUsers.push(result.iamUserName);
|
|
382
|
-
|
|
383
|
-
expect(result).toMatchObject({
|
|
384
|
-
bucketName: expect.stringMatching(/^test-project-production-backups-/),
|
|
385
|
-
bucketArn: expect.stringMatching(/^arn:aws:s3:::/),
|
|
386
|
-
iamUserName: 'dokploy-backup-test-project-production',
|
|
387
|
-
iamAccessKeyId: expect.any(String),
|
|
388
|
-
iamSecretAccessKey: expect.any(String),
|
|
389
|
-
destinationId: 'dest_complete',
|
|
390
|
-
region: 'us-east-1',
|
|
391
|
-
createdAt: expect.any(String),
|
|
392
|
-
});
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
it('should handle connection test failure gracefully', async () => {
|
|
396
|
-
server.use(
|
|
397
|
-
http.get(`${DOKPLOY_BASE_URL}/api/destination.all`, () => {
|
|
398
|
-
return HttpResponse.json([]);
|
|
399
|
-
}),
|
|
400
|
-
http.post(`${DOKPLOY_BASE_URL}/api/destination.create`, () => {
|
|
401
|
-
return HttpResponse.json({
|
|
402
|
-
destinationId: 'dest_123',
|
|
403
|
-
name: 'test',
|
|
404
|
-
});
|
|
405
|
-
}),
|
|
406
|
-
http.post(`${DOKPLOY_BASE_URL}/api/destination.testConnection`, () => {
|
|
407
|
-
return HttpResponse.json(
|
|
408
|
-
{ message: 'Connection failed' },
|
|
409
|
-
{ status: 500 },
|
|
410
|
-
);
|
|
411
|
-
}),
|
|
412
|
-
);
|
|
413
|
-
|
|
414
|
-
const options = createOptions();
|
|
415
|
-
const result = await provisionBackupDestination(options);
|
|
416
|
-
|
|
417
|
-
// Track for cleanup
|
|
418
|
-
createdBuckets.push(result.bucketName);
|
|
419
|
-
createdUsers.push(result.iamUserName);
|
|
420
|
-
|
|
421
|
-
// Should still succeed but log warning
|
|
422
|
-
expect(result.destinationId).toBe('dest_123');
|
|
423
|
-
expect(
|
|
424
|
-
logs.some((l) => l.includes('Warning: Could not verify destination')),
|
|
425
|
-
).toBe(true);
|
|
426
|
-
});
|
|
427
|
-
});
|
|
428
|
-
});
|