@geekmidas/cli 9.0.2 → 10.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -120
- 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 +2329 -1584
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +2306 -1561
- 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,316 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Backup Destination Provisioner
|
|
3
|
-
*
|
|
4
|
-
* Creates AWS resources (S3 bucket, IAM user, access keys) and configures
|
|
5
|
-
* Dokploy backup destinations for database backups.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
CreateAccessKeyCommand,
|
|
10
|
-
CreateUserCommand,
|
|
11
|
-
GetUserCommand,
|
|
12
|
-
IAMClient,
|
|
13
|
-
type IAMClientConfig,
|
|
14
|
-
PutUserPolicyCommand,
|
|
15
|
-
} from '@aws-sdk/client-iam';
|
|
16
|
-
import {
|
|
17
|
-
type BucketLocationConstraint,
|
|
18
|
-
CreateBucketCommand,
|
|
19
|
-
HeadBucketCommand,
|
|
20
|
-
PutBucketVersioningCommand,
|
|
21
|
-
S3Client,
|
|
22
|
-
type S3ClientConfig,
|
|
23
|
-
} from '@aws-sdk/client-s3';
|
|
24
|
-
import type { BackupsConfig } from '../workspace/types.js';
|
|
25
|
-
import type { DokployApi } from './dokploy-api.js';
|
|
26
|
-
import type { BackupState } from './state.js';
|
|
27
|
-
|
|
28
|
-
export interface ProvisionBackupOptions {
|
|
29
|
-
/** Dokploy API client */
|
|
30
|
-
api: DokployApi;
|
|
31
|
-
/** Dokploy project ID */
|
|
32
|
-
projectId: string;
|
|
33
|
-
/** Workspace name (used for resource naming) */
|
|
34
|
-
projectName: string;
|
|
35
|
-
/** Deploy stage (e.g., 'production', 'staging') */
|
|
36
|
-
stage: string;
|
|
37
|
-
/** Backup configuration */
|
|
38
|
-
config: BackupsConfig;
|
|
39
|
-
/** Existing backup state (if any) */
|
|
40
|
-
existingState?: BackupState;
|
|
41
|
-
/** Logger for progress output */
|
|
42
|
-
logger: { log: (msg: string) => void };
|
|
43
|
-
/** AWS endpoint override (for testing with LocalStack) */
|
|
44
|
-
awsEndpoint?: string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Generate a random suffix for unique resource names
|
|
49
|
-
*/
|
|
50
|
-
function randomSuffix(): string {
|
|
51
|
-
return Math.random().toString(36).substring(2, 8);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Sanitize a name for AWS resources (lowercase alphanumeric and hyphens)
|
|
56
|
-
*/
|
|
57
|
-
function sanitizeName(name: string): string {
|
|
58
|
-
return name.toLowerCase().replace(/[^a-z0-9-]/g, '-');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Create AWS clients with optional profile credentials
|
|
63
|
-
*/
|
|
64
|
-
async function createAwsClients(
|
|
65
|
-
region: string,
|
|
66
|
-
profile?: string,
|
|
67
|
-
endpoint?: string,
|
|
68
|
-
): Promise<{ s3: S3Client; iam: IAMClient }> {
|
|
69
|
-
const config: S3ClientConfig & IAMClientConfig = { region };
|
|
70
|
-
|
|
71
|
-
if (profile) {
|
|
72
|
-
const { fromIni } = await import('@aws-sdk/credential-providers');
|
|
73
|
-
config.credentials = fromIni({ profile });
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Support custom endpoint for testing (e.g., LocalStack)
|
|
77
|
-
if (endpoint) {
|
|
78
|
-
config.endpoint = endpoint;
|
|
79
|
-
(config as S3ClientConfig).forcePathStyle = true;
|
|
80
|
-
// Use test credentials when endpoint is specified
|
|
81
|
-
config.credentials = {
|
|
82
|
-
accessKeyId: 'test',
|
|
83
|
-
secretAccessKey: 'test',
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
s3: new S3Client(config),
|
|
89
|
-
iam: new IAMClient(config),
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Check if an S3 bucket exists
|
|
95
|
-
*/
|
|
96
|
-
async function bucketExists(
|
|
97
|
-
s3: S3Client,
|
|
98
|
-
bucketName: string,
|
|
99
|
-
): Promise<boolean> {
|
|
100
|
-
try {
|
|
101
|
-
await s3.send(new HeadBucketCommand({ Bucket: bucketName }));
|
|
102
|
-
return true;
|
|
103
|
-
} catch (error) {
|
|
104
|
-
if ((error as { name?: string }).name === 'NotFound') {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
// 403 means bucket exists but we don't have access
|
|
108
|
-
if (
|
|
109
|
-
(error as { $metadata?: { httpStatusCode?: number } }).$metadata
|
|
110
|
-
?.httpStatusCode === 403
|
|
111
|
-
) {
|
|
112
|
-
return true;
|
|
113
|
-
}
|
|
114
|
-
throw error;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Check if an IAM user exists
|
|
120
|
-
*/
|
|
121
|
-
async function userExists(iam: IAMClient, userName: string): Promise<boolean> {
|
|
122
|
-
try {
|
|
123
|
-
await iam.send(new GetUserCommand({ UserName: userName }));
|
|
124
|
-
return true;
|
|
125
|
-
} catch (error) {
|
|
126
|
-
const errorName = (error as { name?: string }).name;
|
|
127
|
-
// AWS returns 'NoSuchEntity', LocalStack returns 'NoSuchEntityException'
|
|
128
|
-
if (errorName === 'NoSuchEntity' || errorName === 'NoSuchEntityException') {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
throw error;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Provision backup destination for a deployment.
|
|
137
|
-
*
|
|
138
|
-
* Creates AWS resources (S3 bucket, IAM user) and Dokploy destination if needed.
|
|
139
|
-
* Reuses existing resources from state when possible.
|
|
140
|
-
*/
|
|
141
|
-
export async function provisionBackupDestination(
|
|
142
|
-
options: ProvisionBackupOptions,
|
|
143
|
-
): Promise<BackupState> {
|
|
144
|
-
const {
|
|
145
|
-
api,
|
|
146
|
-
projectName,
|
|
147
|
-
stage,
|
|
148
|
-
config,
|
|
149
|
-
existingState,
|
|
150
|
-
logger,
|
|
151
|
-
awsEndpoint,
|
|
152
|
-
} = options;
|
|
153
|
-
|
|
154
|
-
// If we have existing state, verify the Dokploy destination still exists
|
|
155
|
-
if (existingState?.destinationId) {
|
|
156
|
-
try {
|
|
157
|
-
await api.getDestination(existingState.destinationId);
|
|
158
|
-
logger.log(' Using existing backup destination');
|
|
159
|
-
return existingState;
|
|
160
|
-
} catch {
|
|
161
|
-
logger.log(' Existing destination not found, recreating...');
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Create AWS clients
|
|
166
|
-
const aws = await createAwsClients(
|
|
167
|
-
config.region,
|
|
168
|
-
config.profile,
|
|
169
|
-
awsEndpoint,
|
|
170
|
-
);
|
|
171
|
-
const sanitizedProject = sanitizeName(projectName);
|
|
172
|
-
|
|
173
|
-
// 1. Create or verify S3 bucket
|
|
174
|
-
const bucketName =
|
|
175
|
-
existingState?.bucketName ??
|
|
176
|
-
`${sanitizedProject}-${stage}-backups-${randomSuffix()}`;
|
|
177
|
-
|
|
178
|
-
const bucketAlreadyExists = await bucketExists(aws.s3, bucketName);
|
|
179
|
-
if (!bucketAlreadyExists) {
|
|
180
|
-
logger.log(` Creating S3 bucket: ${bucketName}`);
|
|
181
|
-
|
|
182
|
-
// CreateBucket needs LocationConstraint for non-us-east-1 regions
|
|
183
|
-
const createBucketParams: {
|
|
184
|
-
Bucket: string;
|
|
185
|
-
CreateBucketConfiguration?: {
|
|
186
|
-
LocationConstraint: BucketLocationConstraint;
|
|
187
|
-
};
|
|
188
|
-
} = {
|
|
189
|
-
Bucket: bucketName,
|
|
190
|
-
};
|
|
191
|
-
if (config.region !== 'us-east-1') {
|
|
192
|
-
createBucketParams.CreateBucketConfiguration = {
|
|
193
|
-
LocationConstraint: config.region as BucketLocationConstraint,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
await aws.s3.send(new CreateBucketCommand(createBucketParams));
|
|
198
|
-
|
|
199
|
-
// Enable versioning for backup integrity
|
|
200
|
-
await aws.s3.send(
|
|
201
|
-
new PutBucketVersioningCommand({
|
|
202
|
-
Bucket: bucketName,
|
|
203
|
-
VersioningConfiguration: { Status: 'Enabled' },
|
|
204
|
-
}),
|
|
205
|
-
);
|
|
206
|
-
} else {
|
|
207
|
-
logger.log(` Using existing S3 bucket: ${bucketName}`);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// 2. Create or verify IAM user
|
|
211
|
-
const iamUserName =
|
|
212
|
-
existingState?.iamUserName ?? `dokploy-backup-${sanitizedProject}-${stage}`;
|
|
213
|
-
|
|
214
|
-
const iamUserAlreadyExists = await userExists(aws.iam, iamUserName);
|
|
215
|
-
if (!iamUserAlreadyExists) {
|
|
216
|
-
logger.log(` Creating IAM user: ${iamUserName}`);
|
|
217
|
-
await aws.iam.send(new CreateUserCommand({ UserName: iamUserName }));
|
|
218
|
-
} else {
|
|
219
|
-
logger.log(` Using existing IAM user: ${iamUserName}`);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// 3. Attach bucket policy to IAM user
|
|
223
|
-
const policyDocument = {
|
|
224
|
-
Version: '2012-10-17',
|
|
225
|
-
Statement: [
|
|
226
|
-
{
|
|
227
|
-
Effect: 'Allow',
|
|
228
|
-
Action: [
|
|
229
|
-
's3:GetObject',
|
|
230
|
-
's3:PutObject',
|
|
231
|
-
's3:DeleteObject',
|
|
232
|
-
's3:ListBucket',
|
|
233
|
-
's3:GetBucketLocation',
|
|
234
|
-
],
|
|
235
|
-
Resource: [
|
|
236
|
-
`arn:aws:s3:::${bucketName}`,
|
|
237
|
-
`arn:aws:s3:::${bucketName}/*`,
|
|
238
|
-
],
|
|
239
|
-
},
|
|
240
|
-
],
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
logger.log(' Updating IAM policy');
|
|
244
|
-
await aws.iam.send(
|
|
245
|
-
new PutUserPolicyCommand({
|
|
246
|
-
UserName: iamUserName,
|
|
247
|
-
PolicyName: 'DokployBackupAccess',
|
|
248
|
-
PolicyDocument: JSON.stringify(policyDocument),
|
|
249
|
-
}),
|
|
250
|
-
);
|
|
251
|
-
|
|
252
|
-
// 4. Create access key (or reuse existing if state has it and destination needs recreation)
|
|
253
|
-
let accessKeyId: string;
|
|
254
|
-
let secretAccessKey: string;
|
|
255
|
-
|
|
256
|
-
if (existingState?.iamAccessKeyId && existingState?.iamSecretAccessKey) {
|
|
257
|
-
// Reuse existing credentials
|
|
258
|
-
logger.log(' Using existing IAM access key');
|
|
259
|
-
accessKeyId = existingState.iamAccessKeyId;
|
|
260
|
-
secretAccessKey = existingState.iamSecretAccessKey;
|
|
261
|
-
} else {
|
|
262
|
-
// Create new access key
|
|
263
|
-
logger.log(' Creating IAM access key');
|
|
264
|
-
const accessKeyResult = await aws.iam.send(
|
|
265
|
-
new CreateAccessKeyCommand({ UserName: iamUserName }),
|
|
266
|
-
);
|
|
267
|
-
|
|
268
|
-
if (!accessKeyResult.AccessKey) {
|
|
269
|
-
throw new Error('Failed to create IAM access key');
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
accessKeyId = accessKeyResult.AccessKey.AccessKeyId!;
|
|
273
|
-
secretAccessKey = accessKeyResult.AccessKey.SecretAccessKey!;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// 5. Create Dokploy destination
|
|
277
|
-
const destinationName = `${sanitizedProject}-${stage}-s3`;
|
|
278
|
-
logger.log(` Creating Dokploy destination: ${destinationName}`);
|
|
279
|
-
|
|
280
|
-
const { destination, created } = await api.findOrCreateDestination(
|
|
281
|
-
destinationName,
|
|
282
|
-
{
|
|
283
|
-
accessKey: accessKeyId,
|
|
284
|
-
secretAccessKey: secretAccessKey,
|
|
285
|
-
bucket: bucketName,
|
|
286
|
-
region: config.region,
|
|
287
|
-
},
|
|
288
|
-
);
|
|
289
|
-
|
|
290
|
-
if (created) {
|
|
291
|
-
logger.log(' ✓ Dokploy destination created');
|
|
292
|
-
} else {
|
|
293
|
-
logger.log(' ✓ Using existing Dokploy destination');
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// 6. Test connection
|
|
297
|
-
try {
|
|
298
|
-
await api.testDestinationConnection(destination.destinationId);
|
|
299
|
-
logger.log(' ✓ Destination connection verified');
|
|
300
|
-
} catch (error) {
|
|
301
|
-
logger.log(
|
|
302
|
-
` ⚠ Warning: Could not verify destination connection: ${error}`,
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
return {
|
|
307
|
-
bucketName,
|
|
308
|
-
bucketArn: `arn:aws:s3:::${bucketName}`,
|
|
309
|
-
iamUserName,
|
|
310
|
-
iamAccessKeyId: accessKeyId,
|
|
311
|
-
iamSecretAccessKey: secretAccessKey,
|
|
312
|
-
destinationId: destination.destinationId,
|
|
313
|
-
region: config.region,
|
|
314
|
-
createdAt: existingState?.createdAt ?? new Date().toISOString(),
|
|
315
|
-
};
|
|
316
|
-
}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DNS Provider Interface
|
|
3
|
-
*
|
|
4
|
-
* Abstracts DNS operations for different providers.
|
|
5
|
-
* Built-in providers: HostingerProvider, Route53Provider
|
|
6
|
-
* Users can also supply custom implementations.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { z } from 'zod/v4';
|
|
10
|
-
import type {
|
|
11
|
-
CloudflareDnsProviderSchema,
|
|
12
|
-
CustomDnsProviderSchema,
|
|
13
|
-
DnsProviderSchema,
|
|
14
|
-
DnsRecordSchema,
|
|
15
|
-
DnsRecordTypeSchema,
|
|
16
|
-
HostingerDnsProviderSchema,
|
|
17
|
-
ManualDnsProviderSchema,
|
|
18
|
-
Route53DnsProviderSchema,
|
|
19
|
-
UpsertDnsRecordSchema,
|
|
20
|
-
UpsertResultSchema,
|
|
21
|
-
} from '../../workspace/schema';
|
|
22
|
-
|
|
23
|
-
// =============================================================================
|
|
24
|
-
// DNS Record Types (derived from Zod schemas)
|
|
25
|
-
// =============================================================================
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* DNS record types supported across providers.
|
|
29
|
-
*/
|
|
30
|
-
export type DnsRecordType = z.infer<typeof DnsRecordTypeSchema>;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* A DNS record as returned by the provider.
|
|
34
|
-
*/
|
|
35
|
-
export type DnsRecord = z.infer<typeof DnsRecordSchema>;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* A DNS record to create or update.
|
|
39
|
-
*/
|
|
40
|
-
export type UpsertDnsRecord = z.infer<typeof UpsertDnsRecordSchema>;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Result of an upsert operation.
|
|
44
|
-
*/
|
|
45
|
-
export type UpsertResult = z.infer<typeof UpsertResultSchema>;
|
|
46
|
-
|
|
47
|
-
// =============================================================================
|
|
48
|
-
// DNS Provider Interface
|
|
49
|
-
// =============================================================================
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* A record to delete from DNS.
|
|
53
|
-
*/
|
|
54
|
-
export interface DeleteDnsRecord {
|
|
55
|
-
/** Record name/subdomain (e.g., 'api' or '@' for root) */
|
|
56
|
-
name: string;
|
|
57
|
-
/** Record type (A, CNAME, etc.) */
|
|
58
|
-
type: DnsRecordType;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Result of a delete operation.
|
|
63
|
-
*/
|
|
64
|
-
export interface DeleteResult {
|
|
65
|
-
/** The record that was requested for deletion */
|
|
66
|
-
record: DeleteDnsRecord;
|
|
67
|
-
/** Whether the record was deleted */
|
|
68
|
-
deleted: boolean;
|
|
69
|
-
/** Whether the record was not found (already deleted) */
|
|
70
|
-
notFound: boolean;
|
|
71
|
-
/** Error message if deletion failed */
|
|
72
|
-
error?: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Interface for DNS providers.
|
|
77
|
-
*
|
|
78
|
-
* Implementations must handle:
|
|
79
|
-
* - Getting all records for a domain
|
|
80
|
-
* - Creating or updating records for a domain
|
|
81
|
-
* - Deleting records from a domain
|
|
82
|
-
*/
|
|
83
|
-
export interface DnsProvider {
|
|
84
|
-
/** Provider name for logging */
|
|
85
|
-
readonly name: string;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Get all DNS records for a domain.
|
|
89
|
-
*
|
|
90
|
-
* @param domain - Root domain (e.g., 'example.com')
|
|
91
|
-
* @returns Array of DNS records
|
|
92
|
-
*/
|
|
93
|
-
getRecords(domain: string): Promise<DnsRecord[]>;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Create or update DNS records.
|
|
97
|
-
*
|
|
98
|
-
* @param domain - Root domain (e.g., 'example.com')
|
|
99
|
-
* @param records - Records to create or update
|
|
100
|
-
* @returns Results of the upsert operations
|
|
101
|
-
*/
|
|
102
|
-
upsertRecords(
|
|
103
|
-
domain: string,
|
|
104
|
-
records: UpsertDnsRecord[],
|
|
105
|
-
): Promise<UpsertResult[]>;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Delete DNS records.
|
|
109
|
-
*
|
|
110
|
-
* @param domain - Root domain (e.g., 'example.com')
|
|
111
|
-
* @param records - Records to delete
|
|
112
|
-
* @returns Results of the delete operations
|
|
113
|
-
*/
|
|
114
|
-
deleteRecords(
|
|
115
|
-
domain: string,
|
|
116
|
-
records: DeleteDnsRecord[],
|
|
117
|
-
): Promise<DeleteResult[]>;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// =============================================================================
|
|
121
|
-
// DNS Provider Config Types (derived from Zod schemas)
|
|
122
|
-
// =============================================================================
|
|
123
|
-
|
|
124
|
-
export type HostingerDnsConfig = z.infer<typeof HostingerDnsProviderSchema>;
|
|
125
|
-
export type Route53DnsConfig = z.infer<typeof Route53DnsProviderSchema>;
|
|
126
|
-
export type CloudflareDnsConfig = z.infer<typeof CloudflareDnsProviderSchema>;
|
|
127
|
-
export type ManualDnsConfig = z.infer<typeof ManualDnsProviderSchema>;
|
|
128
|
-
export type CustomDnsConfig = z.infer<typeof CustomDnsProviderSchema>;
|
|
129
|
-
/** Single DNS provider config (for one domain) */
|
|
130
|
-
export type DnsConfig = z.infer<typeof DnsProviderSchema>;
|
|
131
|
-
|
|
132
|
-
// =============================================================================
|
|
133
|
-
// DNS Provider Factory
|
|
134
|
-
// =============================================================================
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Check if value is a DnsProvider implementation.
|
|
138
|
-
*/
|
|
139
|
-
export function isDnsProvider(value: unknown): value is DnsProvider {
|
|
140
|
-
return (
|
|
141
|
-
typeof value === 'object' &&
|
|
142
|
-
value !== null &&
|
|
143
|
-
typeof (value as DnsProvider).name === 'string' &&
|
|
144
|
-
typeof (value as DnsProvider).getRecords === 'function' &&
|
|
145
|
-
typeof (value as DnsProvider).upsertRecords === 'function' &&
|
|
146
|
-
typeof (value as DnsProvider).deleteRecords === 'function'
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export interface CreateDnsProviderOptions {
|
|
151
|
-
/** DNS config from workspace */
|
|
152
|
-
config: DnsConfig;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Create a DNS provider based on configuration.
|
|
157
|
-
*
|
|
158
|
-
* - 'hostinger': HostingerProvider
|
|
159
|
-
* - 'route53': Route53Provider
|
|
160
|
-
* - 'manual': Returns null (user handles DNS)
|
|
161
|
-
* - Custom: Use provided DnsProvider implementation
|
|
162
|
-
*/
|
|
163
|
-
export async function createDnsProvider(
|
|
164
|
-
options: CreateDnsProviderOptions,
|
|
165
|
-
): Promise<DnsProvider | null> {
|
|
166
|
-
const { config } = options;
|
|
167
|
-
|
|
168
|
-
// Manual mode - no provider needed
|
|
169
|
-
if (config.provider === 'manual') {
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Custom provider implementation
|
|
174
|
-
if (isDnsProvider(config.provider)) {
|
|
175
|
-
return config.provider;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Built-in providers
|
|
179
|
-
const provider = config.provider;
|
|
180
|
-
|
|
181
|
-
if (provider === 'hostinger') {
|
|
182
|
-
const { HostingerProvider } = await import('./HostingerProvider');
|
|
183
|
-
return new HostingerProvider();
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (provider === 'route53') {
|
|
187
|
-
const { Route53Provider } = await import('./Route53Provider');
|
|
188
|
-
const route53Config = config as Route53DnsConfig;
|
|
189
|
-
return new Route53Provider({
|
|
190
|
-
region: route53Config.region,
|
|
191
|
-
profile: route53Config.profile,
|
|
192
|
-
hostedZoneId: route53Config.hostedZoneId,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (provider === 'cloudflare') {
|
|
197
|
-
throw new Error('Cloudflare DNS provider not yet implemented');
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
throw new Error(`Unknown DNS provider: ${JSON.stringify(config)}`);
|
|
201
|
-
}
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hostinger DNS Provider
|
|
3
|
-
*
|
|
4
|
-
* Implements DnsProvider interface using the Hostinger DNS API.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { getHostingerToken } from '../../auth/credentials';
|
|
8
|
-
import type {
|
|
9
|
-
DeleteDnsRecord,
|
|
10
|
-
DeleteResult,
|
|
11
|
-
DnsProvider,
|
|
12
|
-
DnsRecord,
|
|
13
|
-
UpsertDnsRecord,
|
|
14
|
-
UpsertResult,
|
|
15
|
-
} from './DnsProvider';
|
|
16
|
-
import { HostingerApi } from './hostinger-api';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Hostinger DNS provider implementation.
|
|
20
|
-
*/
|
|
21
|
-
export class HostingerProvider implements DnsProvider {
|
|
22
|
-
readonly name = 'hostinger';
|
|
23
|
-
private api: HostingerApi | null = null;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Get or create the Hostinger API client.
|
|
27
|
-
*/
|
|
28
|
-
private async getApi(): Promise<HostingerApi> {
|
|
29
|
-
if (this.api) {
|
|
30
|
-
return this.api;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const token = await getHostingerToken();
|
|
34
|
-
if (!token) {
|
|
35
|
-
throw new Error(
|
|
36
|
-
'Hostinger API token not configured. Run `gkm login --service=hostinger` or get your token from https://hpanel.hostinger.com/profile/api',
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
this.api = new HostingerApi(token);
|
|
41
|
-
return this.api;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async getRecords(domain: string): Promise<DnsRecord[]> {
|
|
45
|
-
const api = await this.getApi();
|
|
46
|
-
const records = await api.getRecords(domain);
|
|
47
|
-
|
|
48
|
-
return records.map((r) => ({
|
|
49
|
-
name: r.name,
|
|
50
|
-
type: r.type,
|
|
51
|
-
ttl: r.ttl,
|
|
52
|
-
values: r.records.map((rec) => rec.content),
|
|
53
|
-
}));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async upsertRecords(
|
|
57
|
-
domain: string,
|
|
58
|
-
records: UpsertDnsRecord[],
|
|
59
|
-
): Promise<UpsertResult[]> {
|
|
60
|
-
const api = await this.getApi();
|
|
61
|
-
const results: UpsertResult[] = [];
|
|
62
|
-
|
|
63
|
-
// Get existing records to check what already exists
|
|
64
|
-
const existingRecords = await api.getRecords(domain);
|
|
65
|
-
|
|
66
|
-
for (const record of records) {
|
|
67
|
-
const existing = existingRecords.find(
|
|
68
|
-
(r) => r.name === record.name && r.type === record.type,
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
const existingValue = existing?.records?.[0]?.content;
|
|
72
|
-
|
|
73
|
-
if (existing && existingValue === record.value) {
|
|
74
|
-
// Record exists with same value - unchanged
|
|
75
|
-
results.push({
|
|
76
|
-
record,
|
|
77
|
-
created: false,
|
|
78
|
-
unchanged: true,
|
|
79
|
-
});
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Create or update the record
|
|
84
|
-
await api.upsertRecords(domain, [
|
|
85
|
-
{
|
|
86
|
-
name: record.name,
|
|
87
|
-
type: record.type,
|
|
88
|
-
ttl: record.ttl,
|
|
89
|
-
records: [{ content: record.value }],
|
|
90
|
-
},
|
|
91
|
-
]);
|
|
92
|
-
|
|
93
|
-
results.push({
|
|
94
|
-
record,
|
|
95
|
-
created: !existing,
|
|
96
|
-
unchanged: false,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return results;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async deleteRecords(
|
|
104
|
-
domain: string,
|
|
105
|
-
records: DeleteDnsRecord[],
|
|
106
|
-
): Promise<DeleteResult[]> {
|
|
107
|
-
const api = await this.getApi();
|
|
108
|
-
const results: DeleteResult[] = [];
|
|
109
|
-
|
|
110
|
-
// Get existing records to check what exists
|
|
111
|
-
const existingRecords = await api.getRecords(domain);
|
|
112
|
-
|
|
113
|
-
// Filter to only records that exist
|
|
114
|
-
const recordsToDelete = records.filter((record) =>
|
|
115
|
-
existingRecords.some(
|
|
116
|
-
(r) => r.name === record.name && r.type === record.type,
|
|
117
|
-
),
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
// Delete existing records
|
|
121
|
-
if (recordsToDelete.length > 0) {
|
|
122
|
-
try {
|
|
123
|
-
await api.deleteRecords(
|
|
124
|
-
domain,
|
|
125
|
-
recordsToDelete.map((r) => ({
|
|
126
|
-
name: r.name,
|
|
127
|
-
type: r.type as
|
|
128
|
-
| 'A'
|
|
129
|
-
| 'AAAA'
|
|
130
|
-
| 'CNAME'
|
|
131
|
-
| 'MX'
|
|
132
|
-
| 'TXT'
|
|
133
|
-
| 'SRV'
|
|
134
|
-
| 'CAA',
|
|
135
|
-
})),
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
for (const record of recordsToDelete) {
|
|
139
|
-
results.push({
|
|
140
|
-
record,
|
|
141
|
-
deleted: true,
|
|
142
|
-
notFound: false,
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
} catch (error) {
|
|
146
|
-
// If batch delete fails, report error for all records
|
|
147
|
-
for (const record of recordsToDelete) {
|
|
148
|
-
results.push({
|
|
149
|
-
record,
|
|
150
|
-
deleted: false,
|
|
151
|
-
notFound: false,
|
|
152
|
-
error: String(error),
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Mark non-existent records as not found
|
|
159
|
-
for (const record of records) {
|
|
160
|
-
const existing = existingRecords.find(
|
|
161
|
-
(r) => r.name === record.name && r.type === record.type,
|
|
162
|
-
);
|
|
163
|
-
if (!existing) {
|
|
164
|
-
results.push({
|
|
165
|
-
record,
|
|
166
|
-
deleted: false,
|
|
167
|
-
notFound: true,
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return results;
|
|
173
|
-
}
|
|
174
|
-
}
|