@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,694 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
-
import type { GkmConfig } from '../../types';
|
|
5
|
-
import {
|
|
6
|
-
detectPackageManager,
|
|
7
|
-
findLockfilePath,
|
|
8
|
-
generateBackendDockerfile,
|
|
9
|
-
generateDockerEntrypoint,
|
|
10
|
-
generateDockerignore,
|
|
11
|
-
generateEntryDockerfile,
|
|
12
|
-
generateMultiStageDockerfile,
|
|
13
|
-
generateNextjsDockerfile,
|
|
14
|
-
generateSlimDockerfile,
|
|
15
|
-
getLockfileName,
|
|
16
|
-
hasTurboConfig,
|
|
17
|
-
isMonorepo,
|
|
18
|
-
resolveDockerConfig,
|
|
19
|
-
} from '../templates';
|
|
20
|
-
|
|
21
|
-
// Mock fs.existsSync
|
|
22
|
-
vi.mock('node:fs', async () => {
|
|
23
|
-
const actual = await vi.importActual<typeof import('node:fs')>('node:fs');
|
|
24
|
-
return {
|
|
25
|
-
...actual,
|
|
26
|
-
existsSync: vi.fn(),
|
|
27
|
-
};
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const mockExistsSync = vi.mocked(existsSync);
|
|
31
|
-
|
|
32
|
-
describe('docker templates', () => {
|
|
33
|
-
beforeEach(() => {
|
|
34
|
-
vi.resetAllMocks();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
describe('detectPackageManager', () => {
|
|
38
|
-
it('should detect pnpm from lockfile', () => {
|
|
39
|
-
mockExistsSync.mockImplementation((path) => {
|
|
40
|
-
return String(path).includes('pnpm-lock.yaml');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
expect(detectPackageManager('/test/project')).toBe('pnpm');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should detect npm from lockfile', () => {
|
|
47
|
-
mockExistsSync.mockImplementation((path) => {
|
|
48
|
-
return String(path).includes('package-lock.json');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
expect(detectPackageManager('/test/project')).toBe('npm');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should detect yarn from lockfile', () => {
|
|
55
|
-
mockExistsSync.mockImplementation((path) => {
|
|
56
|
-
return String(path).includes('yarn.lock');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
expect(detectPackageManager('/test/project')).toBe('yarn');
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should detect bun from lockfile', () => {
|
|
63
|
-
mockExistsSync.mockImplementation((path) => {
|
|
64
|
-
return String(path).includes('bun.lockb');
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
expect(detectPackageManager('/test/project')).toBe('bun');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should default to pnpm when no lockfile found', () => {
|
|
71
|
-
mockExistsSync.mockReturnValue(false);
|
|
72
|
-
|
|
73
|
-
expect(detectPackageManager('/test/project')).toBe('pnpm');
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should prioritize pnpm over npm when both exist', () => {
|
|
77
|
-
mockExistsSync.mockImplementation((path) => {
|
|
78
|
-
const pathStr = String(path);
|
|
79
|
-
return (
|
|
80
|
-
pathStr.includes('pnpm-lock.yaml') ||
|
|
81
|
-
pathStr.includes('package-lock.json')
|
|
82
|
-
);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
// pnpm should be detected first due to order
|
|
86
|
-
expect(detectPackageManager('/test/project')).toBe('pnpm');
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
describe('generateMultiStageDockerfile', () => {
|
|
91
|
-
const baseOptions = {
|
|
92
|
-
imageName: 'my-app',
|
|
93
|
-
baseImage: 'node:22-alpine',
|
|
94
|
-
port: 3000,
|
|
95
|
-
healthCheckPath: '/health',
|
|
96
|
-
prebuilt: false,
|
|
97
|
-
packageManager: 'pnpm' as const,
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
it('should generate Dockerfile with BuildKit syntax', () => {
|
|
101
|
-
const dockerfile = generateMultiStageDockerfile(baseOptions);
|
|
102
|
-
|
|
103
|
-
expect(dockerfile).toContain('# syntax=docker/dockerfile:1');
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('should include three stages: deps, builder, runner', () => {
|
|
107
|
-
const dockerfile = generateMultiStageDockerfile(baseOptions);
|
|
108
|
-
|
|
109
|
-
expect(dockerfile).toContain('FROM node:22-alpine AS deps');
|
|
110
|
-
expect(dockerfile).toContain('FROM deps AS builder');
|
|
111
|
-
expect(dockerfile).toContain('FROM node:22-alpine AS runner');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should use pnpm fetch for better caching', () => {
|
|
115
|
-
const dockerfile = generateMultiStageDockerfile(baseOptions);
|
|
116
|
-
|
|
117
|
-
expect(dockerfile).toContain('pnpm fetch');
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('should install tini for signal handling', () => {
|
|
121
|
-
const dockerfile = generateMultiStageDockerfile(baseOptions);
|
|
122
|
-
|
|
123
|
-
expect(dockerfile).toContain('apk add --no-cache tini');
|
|
124
|
-
expect(dockerfile).toContain('ENTRYPOINT ["/sbin/tini", "--"]');
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it('should create non-root user', () => {
|
|
128
|
-
const dockerfile = generateMultiStageDockerfile(baseOptions);
|
|
129
|
-
|
|
130
|
-
expect(dockerfile).toContain('addgroup --system --gid 1001 nodejs');
|
|
131
|
-
expect(dockerfile).toContain('adduser --system --uid 1001 hono');
|
|
132
|
-
expect(dockerfile).toContain('USER hono');
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('should include health check', () => {
|
|
136
|
-
const dockerfile = generateMultiStageDockerfile(baseOptions);
|
|
137
|
-
|
|
138
|
-
expect(dockerfile).toContain('HEALTHCHECK');
|
|
139
|
-
expect(dockerfile).toContain('/health');
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('should expose configured port', () => {
|
|
143
|
-
const dockerfile = generateMultiStageDockerfile(baseOptions);
|
|
144
|
-
|
|
145
|
-
expect(dockerfile).toContain('EXPOSE 3000');
|
|
146
|
-
expect(dockerfile).toContain('ENV PORT=3000');
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('should use npm when specified', () => {
|
|
150
|
-
const dockerfile = generateMultiStageDockerfile({
|
|
151
|
-
...baseOptions,
|
|
152
|
-
packageManager: 'npm',
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
expect(dockerfile).toContain('npm ci');
|
|
156
|
-
expect(dockerfile).not.toContain('pnpm');
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('should use yarn when specified', () => {
|
|
160
|
-
const dockerfile = generateMultiStageDockerfile({
|
|
161
|
-
...baseOptions,
|
|
162
|
-
packageManager: 'yarn',
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
expect(dockerfile).toContain('yarn install --frozen-lockfile');
|
|
166
|
-
expect(dockerfile).toContain('yarn.lock');
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it('should generate turbo Dockerfile when turbo option is set', () => {
|
|
170
|
-
const dockerfile = generateMultiStageDockerfile({
|
|
171
|
-
...baseOptions,
|
|
172
|
-
turbo: true,
|
|
173
|
-
turboPackage: 'api',
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
expect(dockerfile).toContain('turbo');
|
|
177
|
-
expect(dockerfile).toContain('pruner');
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
describe('generateSlimDockerfile', () => {
|
|
182
|
-
const baseOptions = {
|
|
183
|
-
imageName: 'my-app',
|
|
184
|
-
baseImage: 'node:22-alpine',
|
|
185
|
-
port: 3000,
|
|
186
|
-
healthCheckPath: '/health',
|
|
187
|
-
prebuilt: true,
|
|
188
|
-
packageManager: 'pnpm' as const,
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
it('should generate single-stage Dockerfile', () => {
|
|
192
|
-
const dockerfile = generateSlimDockerfile(baseOptions);
|
|
193
|
-
|
|
194
|
-
// Should not have multiple FROM statements
|
|
195
|
-
const fromMatches = dockerfile.match(/FROM\s+/g);
|
|
196
|
-
expect(fromMatches?.length).toBe(1);
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('should copy pre-built bundle', () => {
|
|
200
|
-
const dockerfile = generateSlimDockerfile(baseOptions);
|
|
201
|
-
|
|
202
|
-
expect(dockerfile).toContain('COPY .gkm/server/dist/server.mjs');
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it('should install tini', () => {
|
|
206
|
-
const dockerfile = generateSlimDockerfile(baseOptions);
|
|
207
|
-
|
|
208
|
-
expect(dockerfile).toContain('tini');
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it('should include health check', () => {
|
|
212
|
-
const dockerfile = generateSlimDockerfile(baseOptions);
|
|
213
|
-
|
|
214
|
-
expect(dockerfile).toContain('HEALTHCHECK');
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
describe('generateDockerignore', () => {
|
|
219
|
-
it('should include common ignores', () => {
|
|
220
|
-
const ignore = generateDockerignore();
|
|
221
|
-
|
|
222
|
-
expect(ignore).toContain('node_modules');
|
|
223
|
-
expect(ignore).toContain('.git');
|
|
224
|
-
expect(ignore).toContain('.env');
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it('should not ignore .gkm/server/dist for slim builds', () => {
|
|
228
|
-
const ignore = generateDockerignore();
|
|
229
|
-
|
|
230
|
-
expect(ignore).toContain('!.gkm/server/dist');
|
|
231
|
-
});
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
describe('generateDockerEntrypoint', () => {
|
|
235
|
-
it('should generate shell entrypoint script', () => {
|
|
236
|
-
const entrypoint = generateDockerEntrypoint();
|
|
237
|
-
|
|
238
|
-
expect(entrypoint).toContain('#!/bin/sh');
|
|
239
|
-
expect(entrypoint).toContain('exec');
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
it('should set error handling', () => {
|
|
243
|
-
const entrypoint = generateDockerEntrypoint();
|
|
244
|
-
|
|
245
|
-
expect(entrypoint).toContain('set -e');
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
describe('resolveDockerConfig', () => {
|
|
250
|
-
it('should use defaults when no config provided', () => {
|
|
251
|
-
const config: GkmConfig = {};
|
|
252
|
-
const result = resolveDockerConfig(config);
|
|
253
|
-
|
|
254
|
-
// imageName comes from package.json or defaults to 'api'
|
|
255
|
-
expect(typeof result.imageName).toBe('string');
|
|
256
|
-
expect(result.baseImage).toBe('node:22-alpine');
|
|
257
|
-
expect(result.port).toBe(3000);
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
it('should use config values when provided', () => {
|
|
261
|
-
const config: GkmConfig = {
|
|
262
|
-
docker: {
|
|
263
|
-
imageName: 'my-custom-app',
|
|
264
|
-
baseImage: 'node:20-alpine',
|
|
265
|
-
port: 8080,
|
|
266
|
-
},
|
|
267
|
-
};
|
|
268
|
-
const result = resolveDockerConfig(config);
|
|
269
|
-
|
|
270
|
-
expect(result.imageName).toBe('my-custom-app');
|
|
271
|
-
expect(result.baseImage).toBe('node:20-alpine');
|
|
272
|
-
expect(result.port).toBe(8080);
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
it('should merge partial config with defaults', () => {
|
|
276
|
-
const config: GkmConfig = {
|
|
277
|
-
docker: {
|
|
278
|
-
imageName: 'partial-app',
|
|
279
|
-
},
|
|
280
|
-
};
|
|
281
|
-
const result = resolveDockerConfig(config);
|
|
282
|
-
|
|
283
|
-
expect(result.imageName).toBe('partial-app');
|
|
284
|
-
expect(result.baseImage).toBe('node:22-alpine'); // default
|
|
285
|
-
expect(result.port).toBe(3000); // default
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
describe('findLockfilePath', () => {
|
|
290
|
-
it('should find pnpm-lock.yaml in current directory', () => {
|
|
291
|
-
mockExistsSync.mockImplementation((path) => {
|
|
292
|
-
return path === join('/test/project', 'pnpm-lock.yaml');
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
expect(findLockfilePath('/test/project')).toBe(
|
|
296
|
-
join('/test/project', 'pnpm-lock.yaml'),
|
|
297
|
-
);
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
it('should find lockfile in parent directory (monorepo)', () => {
|
|
301
|
-
mockExistsSync.mockImplementation((path) => {
|
|
302
|
-
// Lockfile only exists at monorepo root
|
|
303
|
-
return path === join('/test', 'pnpm-lock.yaml');
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
expect(findLockfilePath('/test/project/apps/api')).toBe(
|
|
307
|
-
join('/test', 'pnpm-lock.yaml'),
|
|
308
|
-
);
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
it('should find yarn.lock when present', () => {
|
|
312
|
-
mockExistsSync.mockImplementation((path) => {
|
|
313
|
-
return path === join('/test/project', 'yarn.lock');
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
expect(findLockfilePath('/test/project')).toBe(
|
|
317
|
-
join('/test/project', 'yarn.lock'),
|
|
318
|
-
);
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
it('should find package-lock.json when present', () => {
|
|
322
|
-
mockExistsSync.mockImplementation((path) => {
|
|
323
|
-
return path === join('/test/project', 'package-lock.json');
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
expect(findLockfilePath('/test/project')).toBe(
|
|
327
|
-
join('/test/project', 'package-lock.json'),
|
|
328
|
-
);
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
it('should find bun.lockb when present', () => {
|
|
332
|
-
mockExistsSync.mockImplementation((path) => {
|
|
333
|
-
return path === join('/test/project', 'bun.lockb');
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
expect(findLockfilePath('/test/project')).toBe(
|
|
337
|
-
join('/test/project', 'bun.lockb'),
|
|
338
|
-
);
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
it('should return null when no lockfile found', () => {
|
|
342
|
-
mockExistsSync.mockReturnValue(false);
|
|
343
|
-
|
|
344
|
-
expect(findLockfilePath('/test/project')).toBeNull();
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
it('should prioritize lockfiles in order: pnpm, bun, yarn, npm', () => {
|
|
348
|
-
// If multiple lockfiles exist, pnpm should be found first
|
|
349
|
-
mockExistsSync.mockImplementation((path) => {
|
|
350
|
-
const pathStr = String(path);
|
|
351
|
-
return (
|
|
352
|
-
pathStr.endsWith('pnpm-lock.yaml') ||
|
|
353
|
-
pathStr.endsWith('package-lock.json')
|
|
354
|
-
);
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
const result = findLockfilePath('/test/project');
|
|
358
|
-
expect(result).toContain('pnpm-lock.yaml');
|
|
359
|
-
});
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
describe('getLockfileName', () => {
|
|
363
|
-
it('should return pnpm-lock.yaml for pnpm', () => {
|
|
364
|
-
expect(getLockfileName('pnpm')).toBe('pnpm-lock.yaml');
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
it('should return package-lock.json for npm', () => {
|
|
368
|
-
expect(getLockfileName('npm')).toBe('package-lock.json');
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
it('should return yarn.lock for yarn', () => {
|
|
372
|
-
expect(getLockfileName('yarn')).toBe('yarn.lock');
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
it('should return bun.lockb for bun', () => {
|
|
376
|
-
expect(getLockfileName('bun')).toBe('bun.lockb');
|
|
377
|
-
});
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
describe('isMonorepo', () => {
|
|
381
|
-
it('should return false when lockfile is in current directory', () => {
|
|
382
|
-
mockExistsSync.mockImplementation((path) => {
|
|
383
|
-
return path === join('/test/project', 'pnpm-lock.yaml');
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
expect(isMonorepo('/test/project')).toBe(false);
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
it('should return true when lockfile is in parent directory', () => {
|
|
390
|
-
mockExistsSync.mockImplementation((path) => {
|
|
391
|
-
return path === join('/test', 'pnpm-lock.yaml');
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
expect(isMonorepo('/test/project/apps/api')).toBe(true);
|
|
395
|
-
});
|
|
396
|
-
|
|
397
|
-
it('should return false when no lockfile found', () => {
|
|
398
|
-
mockExistsSync.mockReturnValue(false);
|
|
399
|
-
|
|
400
|
-
expect(isMonorepo('/test/project')).toBe(false);
|
|
401
|
-
});
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
describe('hasTurboConfig', () => {
|
|
405
|
-
it('should return true when turbo.json exists in current directory', () => {
|
|
406
|
-
mockExistsSync.mockImplementation((path) => {
|
|
407
|
-
return path === join('/test/project', 'turbo.json');
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
expect(hasTurboConfig('/test/project')).toBe(true);
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
it('should return true when turbo.json exists in parent directory', () => {
|
|
414
|
-
mockExistsSync.mockImplementation((path) => {
|
|
415
|
-
return path === join('/test', 'turbo.json');
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
expect(hasTurboConfig('/test/project/apps/api')).toBe(true);
|
|
419
|
-
});
|
|
420
|
-
|
|
421
|
-
it('should return false when turbo.json not found', () => {
|
|
422
|
-
mockExistsSync.mockReturnValue(false);
|
|
423
|
-
|
|
424
|
-
expect(hasTurboConfig('/test/project')).toBe(false);
|
|
425
|
-
});
|
|
426
|
-
});
|
|
427
|
-
|
|
428
|
-
describe('generateNextjsDockerfile', () => {
|
|
429
|
-
const baseOptions = {
|
|
430
|
-
imageName: 'web',
|
|
431
|
-
baseImage: 'node:22-alpine',
|
|
432
|
-
port: 3001,
|
|
433
|
-
appPath: 'apps/web',
|
|
434
|
-
turboPackage: '@myapp/web',
|
|
435
|
-
packageManager: 'pnpm' as const,
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
it('should generate Next.js standalone Dockerfile', () => {
|
|
439
|
-
const dockerfile = generateNextjsDockerfile(baseOptions);
|
|
440
|
-
|
|
441
|
-
expect(dockerfile).toContain('# Next.js standalone Dockerfile');
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
it('should include four stages: pruner, deps, builder, runner', () => {
|
|
445
|
-
const dockerfile = generateNextjsDockerfile(baseOptions);
|
|
446
|
-
|
|
447
|
-
expect(dockerfile).toContain('AS pruner');
|
|
448
|
-
expect(dockerfile).toContain('AS deps');
|
|
449
|
-
expect(dockerfile).toContain('AS builder');
|
|
450
|
-
expect(dockerfile).toContain('AS runner');
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
it('should use turbo prune for monorepo optimization', () => {
|
|
454
|
-
const dockerfile = generateNextjsDockerfile(baseOptions);
|
|
455
|
-
|
|
456
|
-
expect(dockerfile).toContain('turbo prune @myapp/web --docker');
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
it('should copy standalone output', () => {
|
|
460
|
-
const dockerfile = generateNextjsDockerfile(baseOptions);
|
|
461
|
-
|
|
462
|
-
expect(dockerfile).toContain('.next/standalone');
|
|
463
|
-
expect(dockerfile).toContain('.next/static');
|
|
464
|
-
});
|
|
465
|
-
|
|
466
|
-
it('should set NEXT_TELEMETRY_DISABLED', () => {
|
|
467
|
-
const dockerfile = generateNextjsDockerfile(baseOptions);
|
|
468
|
-
|
|
469
|
-
expect(dockerfile).toContain('NEXT_TELEMETRY_DISABLED=1');
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
it('should create nextjs user', () => {
|
|
473
|
-
const dockerfile = generateNextjsDockerfile(baseOptions);
|
|
474
|
-
|
|
475
|
-
expect(dockerfile).toContain('adduser --system --uid 1001 nextjs');
|
|
476
|
-
expect(dockerfile).toContain('USER nextjs');
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
it('should expose configured port', () => {
|
|
480
|
-
const dockerfile = generateNextjsDockerfile(baseOptions);
|
|
481
|
-
|
|
482
|
-
expect(dockerfile).toContain('EXPOSE 3001');
|
|
483
|
-
expect(dockerfile).toContain('ENV PORT=3001');
|
|
484
|
-
});
|
|
485
|
-
|
|
486
|
-
it('should use npm when specified', () => {
|
|
487
|
-
const dockerfile = generateNextjsDockerfile({
|
|
488
|
-
...baseOptions,
|
|
489
|
-
packageManager: 'npm',
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
expect(dockerfile).toContain('npx turbo');
|
|
493
|
-
expect(dockerfile).toContain('package-lock.json');
|
|
494
|
-
});
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
describe('generateBackendDockerfile', () => {
|
|
498
|
-
const baseOptions = {
|
|
499
|
-
imageName: 'api',
|
|
500
|
-
baseImage: 'node:22-alpine',
|
|
501
|
-
port: 3000,
|
|
502
|
-
appPath: 'apps/api',
|
|
503
|
-
turboPackage: '@myapp/api',
|
|
504
|
-
packageManager: 'pnpm' as const,
|
|
505
|
-
};
|
|
506
|
-
|
|
507
|
-
it('should generate backend Dockerfile with turbo prune', () => {
|
|
508
|
-
const dockerfile = generateBackendDockerfile(baseOptions);
|
|
509
|
-
|
|
510
|
-
expect(dockerfile).toContain('# Backend Dockerfile with turbo prune');
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
it('should include four stages: pruner, deps, builder, runner', () => {
|
|
514
|
-
const dockerfile = generateBackendDockerfile(baseOptions);
|
|
515
|
-
|
|
516
|
-
expect(dockerfile).toContain('AS pruner');
|
|
517
|
-
expect(dockerfile).toContain('AS deps');
|
|
518
|
-
expect(dockerfile).toContain('AS builder');
|
|
519
|
-
expect(dockerfile).toContain('AS runner');
|
|
520
|
-
});
|
|
521
|
-
|
|
522
|
-
it('should use turbo prune for the package', () => {
|
|
523
|
-
const dockerfile = generateBackendDockerfile(baseOptions);
|
|
524
|
-
|
|
525
|
-
expect(dockerfile).toContain('turbo prune @myapp/api --docker');
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
it('should build using gkm', () => {
|
|
529
|
-
const dockerfile = generateBackendDockerfile(baseOptions);
|
|
530
|
-
|
|
531
|
-
expect(dockerfile).toContain('gkm build --provider server --production');
|
|
532
|
-
});
|
|
533
|
-
|
|
534
|
-
it('should copy bundled server.mjs', () => {
|
|
535
|
-
const dockerfile = generateBackendDockerfile(baseOptions);
|
|
536
|
-
|
|
537
|
-
expect(dockerfile).toContain('.gkm/server/dist/server.mjs');
|
|
538
|
-
});
|
|
539
|
-
|
|
540
|
-
it('should create hono user', () => {
|
|
541
|
-
const dockerfile = generateBackendDockerfile(baseOptions);
|
|
542
|
-
|
|
543
|
-
expect(dockerfile).toContain('adduser --system --uid 1001 hono');
|
|
544
|
-
expect(dockerfile).toContain('USER hono');
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
it('should include health check with default path', () => {
|
|
548
|
-
const dockerfile = generateBackendDockerfile(baseOptions);
|
|
549
|
-
|
|
550
|
-
expect(dockerfile).toContain('HEALTHCHECK');
|
|
551
|
-
expect(dockerfile).toContain('/health');
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
it('should use custom health check path when provided', () => {
|
|
555
|
-
const dockerfile = generateBackendDockerfile({
|
|
556
|
-
...baseOptions,
|
|
557
|
-
healthCheckPath: '/api/health',
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
expect(dockerfile).toContain('/api/health');
|
|
561
|
-
});
|
|
562
|
-
|
|
563
|
-
it('should expose configured port', () => {
|
|
564
|
-
const dockerfile = generateBackendDockerfile(baseOptions);
|
|
565
|
-
|
|
566
|
-
expect(dockerfile).toContain('EXPOSE 3000');
|
|
567
|
-
expect(dockerfile).toContain('ENV PORT=3000');
|
|
568
|
-
});
|
|
569
|
-
});
|
|
570
|
-
|
|
571
|
-
describe('generateEntryDockerfile', () => {
|
|
572
|
-
const baseOptions = {
|
|
573
|
-
baseImage: 'node:22-alpine',
|
|
574
|
-
port: 3002,
|
|
575
|
-
appPath: 'apps/auth',
|
|
576
|
-
entry: './src/index.ts',
|
|
577
|
-
turboPackage: '@myapp/auth',
|
|
578
|
-
packageManager: 'pnpm' as const,
|
|
579
|
-
};
|
|
580
|
-
|
|
581
|
-
it('should generate entry-based Dockerfile with esbuild bundling', () => {
|
|
582
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
583
|
-
|
|
584
|
-
expect(dockerfile).toContain('# Entry-based Dockerfile');
|
|
585
|
-
});
|
|
586
|
-
|
|
587
|
-
it('should include four stages: pruner, deps, builder, runner', () => {
|
|
588
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
589
|
-
|
|
590
|
-
expect(dockerfile).toContain('AS pruner');
|
|
591
|
-
expect(dockerfile).toContain('AS deps');
|
|
592
|
-
expect(dockerfile).toContain('AS builder');
|
|
593
|
-
expect(dockerfile).toContain('AS runner');
|
|
594
|
-
});
|
|
595
|
-
|
|
596
|
-
it('should use turbo prune for the package', () => {
|
|
597
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
598
|
-
|
|
599
|
-
expect(dockerfile).toContain('turbo prune @myapp/auth --docker');
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
it('should bundle with esbuild and packages=bundle flag', () => {
|
|
603
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
604
|
-
|
|
605
|
-
expect(dockerfile).toContain('npx esbuild ./src/index.ts');
|
|
606
|
-
expect(dockerfile).toContain('--packages=bundle');
|
|
607
|
-
expect(dockerfile).toContain('--bundle');
|
|
608
|
-
expect(dockerfile).toContain('--platform=node');
|
|
609
|
-
expect(dockerfile).toContain('--target=node22');
|
|
610
|
-
expect(dockerfile).toContain('--format=esm');
|
|
611
|
-
});
|
|
612
|
-
|
|
613
|
-
it('should include CJS compatibility banner for packages like pino', () => {
|
|
614
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
615
|
-
|
|
616
|
-
expect(dockerfile).toContain('import { createRequire } from "module"');
|
|
617
|
-
expect(dockerfile).toContain(
|
|
618
|
-
'const require = createRequire(import.meta.url)',
|
|
619
|
-
);
|
|
620
|
-
});
|
|
621
|
-
|
|
622
|
-
it('should output to dist/index.mjs', () => {
|
|
623
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
624
|
-
|
|
625
|
-
expect(dockerfile).toContain('--outfile=dist/index.mjs');
|
|
626
|
-
expect(dockerfile).toContain('CMD ["node", "index.mjs"]');
|
|
627
|
-
});
|
|
628
|
-
|
|
629
|
-
it('should copy bundled output only', () => {
|
|
630
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
631
|
-
|
|
632
|
-
expect(dockerfile).toContain('COPY --from=builder');
|
|
633
|
-
expect(dockerfile).toContain('dist/index.mjs');
|
|
634
|
-
// Comment mentions no node_modules needed - fully bundled
|
|
635
|
-
expect(dockerfile).toContain('no node_modules needed');
|
|
636
|
-
});
|
|
637
|
-
|
|
638
|
-
it('should handle encrypted credentials injection', () => {
|
|
639
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
640
|
-
|
|
641
|
-
expect(dockerfile).toContain('ARG GKM_ENCRYPTED_CREDENTIALS');
|
|
642
|
-
expect(dockerfile).toContain('ARG GKM_CREDENTIALS_IV');
|
|
643
|
-
expect(dockerfile).toContain('--define:__GKM_ENCRYPTED_CREDENTIALS__');
|
|
644
|
-
expect(dockerfile).toContain('--define:__GKM_CREDENTIALS_IV__');
|
|
645
|
-
});
|
|
646
|
-
|
|
647
|
-
it('should create app user instead of hono user', () => {
|
|
648
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
649
|
-
|
|
650
|
-
expect(dockerfile).toContain('adduser --system --uid 1001 app');
|
|
651
|
-
expect(dockerfile).toContain('USER app');
|
|
652
|
-
});
|
|
653
|
-
|
|
654
|
-
it('should include health check with default path', () => {
|
|
655
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
656
|
-
|
|
657
|
-
expect(dockerfile).toContain('HEALTHCHECK');
|
|
658
|
-
expect(dockerfile).toContain('/health');
|
|
659
|
-
});
|
|
660
|
-
|
|
661
|
-
it('should use custom health check path when provided', () => {
|
|
662
|
-
const dockerfile = generateEntryDockerfile({
|
|
663
|
-
...baseOptions,
|
|
664
|
-
healthCheckPath: '/api/auth/health',
|
|
665
|
-
});
|
|
666
|
-
|
|
667
|
-
expect(dockerfile).toContain('/api/auth/health');
|
|
668
|
-
});
|
|
669
|
-
|
|
670
|
-
it('should expose configured port', () => {
|
|
671
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
672
|
-
|
|
673
|
-
expect(dockerfile).toContain('EXPOSE 3002');
|
|
674
|
-
expect(dockerfile).toContain('ENV PORT=3002');
|
|
675
|
-
});
|
|
676
|
-
|
|
677
|
-
it('should use npm when specified', () => {
|
|
678
|
-
const dockerfile = generateEntryDockerfile({
|
|
679
|
-
...baseOptions,
|
|
680
|
-
packageManager: 'npm',
|
|
681
|
-
});
|
|
682
|
-
|
|
683
|
-
expect(dockerfile).toContain('npx turbo');
|
|
684
|
-
expect(dockerfile).toContain('package-lock.json');
|
|
685
|
-
});
|
|
686
|
-
|
|
687
|
-
it('should install tini for signal handling', () => {
|
|
688
|
-
const dockerfile = generateEntryDockerfile(baseOptions);
|
|
689
|
-
|
|
690
|
-
expect(dockerfile).toContain('apk add --no-cache tini');
|
|
691
|
-
expect(dockerfile).toContain('ENTRYPOINT ["/sbin/tini", "--"]');
|
|
692
|
-
});
|
|
693
|
-
});
|
|
694
|
-
});
|