@geekmidas/cli 2.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 -623
- 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,408 +0,0 @@
|
|
|
1
|
-
# OpenAPI TypeScript Generation - Design Document
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
This document describes the design for generating TypeScript OpenAPI specifications with integrated authentication support. The feature extends `gkm openapi` with a `--ts` flag that outputs a TypeScript module instead of JSON, enabling:
|
|
6
|
-
|
|
7
|
-
1. **Type-safe paths** - Full TypeScript interface for API routes
|
|
8
|
-
2. **Runtime auth map** - Per-endpoint authentication requirements
|
|
9
|
-
3. **Reusable schemas** - TypeScript interfaces extracted from Zod/Valibot schemas
|
|
10
|
-
4. **Security scheme definitions** - OpenAPI security schemes as typed constants
|
|
11
|
-
|
|
12
|
-
## Motivation
|
|
13
|
-
|
|
14
|
-
### Current Flow (JSON-based)
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
Endpoints → gkm openapi → openapi.json → openapi-typescript → types.d.ts
|
|
18
|
-
↓
|
|
19
|
-
(no auth info at runtime)
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
**Problems:**
|
|
23
|
-
- Auth requirements lost at runtime - OpenAPI security info exists but isn't usable by the fetcher
|
|
24
|
-
- Two-step generation - need external tool (`openapi-typescript`) for types
|
|
25
|
-
- No schema reuse - generated types are isolated, can't reference shared interfaces
|
|
26
|
-
|
|
27
|
-
### Proposed Flow (TypeScript-native)
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
Endpoints → gkm openapi --ts → openapi.ts
|
|
31
|
-
↓
|
|
32
|
-
Exports:
|
|
33
|
-
├── paths (type)
|
|
34
|
-
├── endpointAuth (runtime map)
|
|
35
|
-
├── securitySchemes (runtime definitions)
|
|
36
|
-
└── schema interfaces (reusable types)
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Command Interface
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
# Default: generates TypeScript
|
|
43
|
-
gkm openapi --output ./src/api/openapi.ts
|
|
44
|
-
|
|
45
|
-
# Explicit JSON output (legacy)
|
|
46
|
-
gkm openapi --json --output ./openapi.json
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### Options
|
|
50
|
-
|
|
51
|
-
| Flag | Description | Default |
|
|
52
|
-
|------|-------------|---------|
|
|
53
|
-
| `--json` | Generate JSON instead of TypeScript (legacy) | `false` |
|
|
54
|
-
| `--output` | Output file path | `openapi.ts` |
|
|
55
|
-
|
|
56
|
-
## Generated Output Structure
|
|
57
|
-
|
|
58
|
-
### File: `openapi.ts`
|
|
59
|
-
|
|
60
|
-
```typescript
|
|
61
|
-
// Auto-generated by @geekmidas/cli - DO NOT EDIT
|
|
62
|
-
import type { OpenAPIV3_1 } from 'openapi-types';
|
|
63
|
-
|
|
64
|
-
// ============================================================
|
|
65
|
-
// Security Schemes
|
|
66
|
-
// ============================================================
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Available security schemes for this API.
|
|
70
|
-
* Maps authorizer names to OpenAPI security scheme definitions.
|
|
71
|
-
*/
|
|
72
|
-
export const securitySchemes = {
|
|
73
|
-
bearer: {
|
|
74
|
-
type: 'http',
|
|
75
|
-
scheme: 'bearer',
|
|
76
|
-
bearerFormat: 'JWT',
|
|
77
|
-
},
|
|
78
|
-
iam: {
|
|
79
|
-
type: 'apiKey',
|
|
80
|
-
in: 'header',
|
|
81
|
-
name: 'Authorization',
|
|
82
|
-
'x-amazon-apigateway-authtype': 'awsSigv4',
|
|
83
|
-
},
|
|
84
|
-
apiKey: {
|
|
85
|
-
type: 'apiKey',
|
|
86
|
-
in: 'header',
|
|
87
|
-
name: 'X-API-Key',
|
|
88
|
-
},
|
|
89
|
-
} as const satisfies Record<string, OpenAPIV3_1.SecuritySchemeObject>;
|
|
90
|
-
|
|
91
|
-
export type SecuritySchemeId = keyof typeof securitySchemes;
|
|
92
|
-
|
|
93
|
-
// ============================================================
|
|
94
|
-
// Endpoint Authentication Map
|
|
95
|
-
// ============================================================
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Runtime map of endpoints to their required authentication scheme.
|
|
99
|
-
* `null` indicates a public endpoint (no auth required).
|
|
100
|
-
*/
|
|
101
|
-
export const endpointAuth = {
|
|
102
|
-
'POST /tenants': 'iam',
|
|
103
|
-
'GET /tenants/{id}': 'bearer',
|
|
104
|
-
'PUT /tenants/{id}': 'bearer',
|
|
105
|
-
'DELETE /tenants/{id}': 'bearer',
|
|
106
|
-
'GET /health': null,
|
|
107
|
-
'GET /docs': null,
|
|
108
|
-
} as const satisfies Record<string, SecuritySchemeId | null>;
|
|
109
|
-
|
|
110
|
-
export type AuthenticatedEndpoint = {
|
|
111
|
-
[K in keyof typeof endpointAuth]: typeof endpointAuth[K] extends null ? never : K;
|
|
112
|
-
}[keyof typeof endpointAuth];
|
|
113
|
-
|
|
114
|
-
export type PublicEndpoint = {
|
|
115
|
-
[K in keyof typeof endpointAuth]: typeof endpointAuth[K] extends null ? K : never;
|
|
116
|
-
}[keyof typeof endpointAuth];
|
|
117
|
-
|
|
118
|
-
// ============================================================
|
|
119
|
-
// Schema Definitions (Reusable Types)
|
|
120
|
-
// ============================================================
|
|
121
|
-
|
|
122
|
-
export interface Tenant {
|
|
123
|
-
id: string;
|
|
124
|
-
name: string;
|
|
125
|
-
createdAt: string;
|
|
126
|
-
updatedAt: string;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export interface CreateTenantInput {
|
|
130
|
-
name: string;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export interface UpdateTenantInput {
|
|
134
|
-
name?: string;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// ============================================================
|
|
138
|
-
// OpenAPI Paths
|
|
139
|
-
// ============================================================
|
|
140
|
-
|
|
141
|
-
export interface paths {
|
|
142
|
-
'/tenants': {
|
|
143
|
-
post: {
|
|
144
|
-
requestBody: {
|
|
145
|
-
content: {
|
|
146
|
-
'application/json': CreateTenantInput;
|
|
147
|
-
};
|
|
148
|
-
};
|
|
149
|
-
responses: {
|
|
150
|
-
201: {
|
|
151
|
-
content: {
|
|
152
|
-
'application/json': Tenant;
|
|
153
|
-
};
|
|
154
|
-
};
|
|
155
|
-
};
|
|
156
|
-
};
|
|
157
|
-
};
|
|
158
|
-
'/tenants/{id}': {
|
|
159
|
-
parameters: {
|
|
160
|
-
path: {
|
|
161
|
-
id: string;
|
|
162
|
-
};
|
|
163
|
-
};
|
|
164
|
-
get: {
|
|
165
|
-
responses: {
|
|
166
|
-
200: {
|
|
167
|
-
content: {
|
|
168
|
-
'application/json': Tenant;
|
|
169
|
-
};
|
|
170
|
-
};
|
|
171
|
-
};
|
|
172
|
-
};
|
|
173
|
-
put: {
|
|
174
|
-
requestBody: {
|
|
175
|
-
content: {
|
|
176
|
-
'application/json': UpdateTenantInput;
|
|
177
|
-
};
|
|
178
|
-
};
|
|
179
|
-
responses: {
|
|
180
|
-
200: {
|
|
181
|
-
content: {
|
|
182
|
-
'application/json': Tenant;
|
|
183
|
-
};
|
|
184
|
-
};
|
|
185
|
-
};
|
|
186
|
-
};
|
|
187
|
-
delete: {
|
|
188
|
-
responses: {
|
|
189
|
-
204: {
|
|
190
|
-
content: never;
|
|
191
|
-
};
|
|
192
|
-
};
|
|
193
|
-
};
|
|
194
|
-
};
|
|
195
|
-
'/health': {
|
|
196
|
-
get: {
|
|
197
|
-
responses: {
|
|
198
|
-
200: {
|
|
199
|
-
content: {
|
|
200
|
-
'application/json': { status: string };
|
|
201
|
-
};
|
|
202
|
-
};
|
|
203
|
-
};
|
|
204
|
-
};
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// ============================================================
|
|
209
|
-
// Full OpenAPI Specification (Optional)
|
|
210
|
-
// ============================================================
|
|
211
|
-
|
|
212
|
-
export const spec = {
|
|
213
|
-
openapi: '3.1.0',
|
|
214
|
-
info: {
|
|
215
|
-
title: 'Tenant API',
|
|
216
|
-
version: '1.0.0',
|
|
217
|
-
},
|
|
218
|
-
paths: { /* ... */ },
|
|
219
|
-
components: {
|
|
220
|
-
securitySchemes,
|
|
221
|
-
schemas: { /* ... */ },
|
|
222
|
-
},
|
|
223
|
-
} as const satisfies OpenAPIV3_1.Document;
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
## Implementation Details
|
|
227
|
-
|
|
228
|
-
### 1. Authorizer to Security Scheme Mapping
|
|
229
|
-
|
|
230
|
-
The `Authorizer.type` field maps to OpenAPI security schemes:
|
|
231
|
-
|
|
232
|
-
| Authorizer Type | OpenAPI Security Scheme |
|
|
233
|
-
|-----------------|------------------------|
|
|
234
|
-
| `jwt`, `bearer` | `{ type: 'http', scheme: 'bearer', bearerFormat: 'JWT' }` |
|
|
235
|
-
| `iam`, `aws-sigv4` | `{ type: 'apiKey', in: 'header', name: 'Authorization', 'x-amazon-apigateway-authtype': 'awsSigv4' }` |
|
|
236
|
-
| `apiKey` | `{ type: 'apiKey', in: metadata.in, name: metadata.name }` |
|
|
237
|
-
| `oauth2` | `{ type: 'oauth2', flows: { ... } }` |
|
|
238
|
-
| `oidc` | `{ type: 'openIdConnect', openIdConnectUrl: metadata.issuer }` |
|
|
239
|
-
| `none` / undefined | `null` (public endpoint) |
|
|
240
|
-
|
|
241
|
-
### 2. Schema Extraction
|
|
242
|
-
|
|
243
|
-
Schemas are extracted from StandardSchema (Zod/Valibot) definitions:
|
|
244
|
-
|
|
245
|
-
```typescript
|
|
246
|
-
// From endpoint definition
|
|
247
|
-
const endpoint = e
|
|
248
|
-
.post('/tenants')
|
|
249
|
-
.body(z.object({ name: z.string() }))
|
|
250
|
-
.output(z.object({ id: z.string(), name: z.string() }))
|
|
251
|
-
.handle(async ({ body }) => { ... });
|
|
252
|
-
|
|
253
|
-
// Extracted as
|
|
254
|
-
export interface CreateTenantInput {
|
|
255
|
-
name: string;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
export interface CreateTenantOutput {
|
|
259
|
-
id: string;
|
|
260
|
-
name: string;
|
|
261
|
-
}
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### 3. Naming Strategy
|
|
265
|
-
|
|
266
|
-
| Schema Location | Generated Name |
|
|
267
|
-
|-----------------|----------------|
|
|
268
|
-
| Body schema | `{OperationId}Input` or `{Method}{Route}Input` |
|
|
269
|
-
| Output schema | `{OperationId}Output` or `{Method}{Route}Output` |
|
|
270
|
-
| Params schema | `{OperationId}Params` |
|
|
271
|
-
| Query schema | `{OperationId}Query` |
|
|
272
|
-
|
|
273
|
-
### 4. Component Collector Enhancement
|
|
274
|
-
|
|
275
|
-
```typescript
|
|
276
|
-
// packages/schema/src/openapi.ts
|
|
277
|
-
export interface ComponentCollector {
|
|
278
|
-
schemas: Record<string, OpenAPIV3_1.SchemaObject>;
|
|
279
|
-
securitySchemes: Record<string, OpenAPIV3_1.SecuritySchemeObject>;
|
|
280
|
-
addSchema(id: string, schema: OpenAPIV3_1.SchemaObject): void;
|
|
281
|
-
addSecurityScheme(id: string, scheme: OpenAPIV3_1.SecuritySchemeObject): void;
|
|
282
|
-
getReference(id: string): OpenAPIV3_1.ReferenceObject;
|
|
283
|
-
}
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
## Integration with Auth-Aware Fetcher
|
|
287
|
-
|
|
288
|
-
The generated `endpointAuth` map enables automatic auth handling:
|
|
289
|
-
|
|
290
|
-
```typescript
|
|
291
|
-
// packages/client/src/auth-fetcher.ts
|
|
292
|
-
import { endpointAuth, securitySchemes, type paths } from './openapi';
|
|
293
|
-
import { TokenClient } from '@geekmidas/auth/client';
|
|
294
|
-
|
|
295
|
-
export function createAuthAwareFetcher<Paths>(options: AuthFetcherOptions) {
|
|
296
|
-
const { tokenClient, awsSigner, apiKeyProvider } = options;
|
|
297
|
-
|
|
298
|
-
return async <T extends TypedEndpoint<Paths>>(
|
|
299
|
-
endpoint: T,
|
|
300
|
-
config?: FilteredRequestConfig<Paths, T>,
|
|
301
|
-
) => {
|
|
302
|
-
const authScheme = endpointAuth[endpoint as keyof typeof endpointAuth];
|
|
303
|
-
let headers: Record<string, string> = {};
|
|
304
|
-
|
|
305
|
-
if (authScheme) {
|
|
306
|
-
const scheme = securitySchemes[authScheme];
|
|
307
|
-
|
|
308
|
-
switch (scheme.type) {
|
|
309
|
-
case 'http':
|
|
310
|
-
if (scheme.scheme === 'bearer') {
|
|
311
|
-
headers = await tokenClient.createValidAuthHeaders();
|
|
312
|
-
}
|
|
313
|
-
break;
|
|
314
|
-
case 'apiKey':
|
|
315
|
-
if (scheme['x-amazon-apigateway-authtype'] === 'awsSigv4') {
|
|
316
|
-
headers = await awsSigner.sign(endpoint, config);
|
|
317
|
-
} else {
|
|
318
|
-
headers[scheme.name] = await apiKeyProvider.getKey();
|
|
319
|
-
}
|
|
320
|
-
break;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
return baseFetcher.request(endpoint, {
|
|
325
|
-
...config,
|
|
326
|
-
headers: { ...headers, ...config?.headers },
|
|
327
|
-
});
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
## File Structure Changes
|
|
333
|
-
|
|
334
|
-
```
|
|
335
|
-
packages/
|
|
336
|
-
├── cli/
|
|
337
|
-
│ └── src/
|
|
338
|
-
│ ├── openapi.ts # Updated: add --ts support
|
|
339
|
-
│ └── generators/
|
|
340
|
-
│ └── OpenApiTsGenerator.ts # New: TypeScript generation
|
|
341
|
-
├── schema/
|
|
342
|
-
│ └── src/
|
|
343
|
-
│ └── openapi.ts # Updated: security scheme support
|
|
344
|
-
└── client/
|
|
345
|
-
└── src/
|
|
346
|
-
└── auth-fetcher.ts # New: auth-aware fetcher
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
## Migration Path
|
|
350
|
-
|
|
351
|
-
### Breaking Change
|
|
352
|
-
|
|
353
|
-
TypeScript is now the default output format. Existing JSON users must add `--json` flag.
|
|
354
|
-
|
|
355
|
-
### Existing JSON Users
|
|
356
|
-
|
|
357
|
-
```bash
|
|
358
|
-
# Before
|
|
359
|
-
gkm openapi --output ./openapi.json
|
|
360
|
-
|
|
361
|
-
# After (explicit JSON)
|
|
362
|
-
gkm openapi --json --output ./openapi.json
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
### Adopting TypeScript Output (New Default)
|
|
366
|
-
|
|
367
|
-
1. Run `gkm openapi --output ./src/api/openapi.ts`
|
|
368
|
-
2. Update imports from `./openapi-types` to `./openapi`
|
|
369
|
-
3. Use `createAuthAwareFetcher` instead of `createTypedFetcher`
|
|
370
|
-
|
|
371
|
-
## Testing Strategy
|
|
372
|
-
|
|
373
|
-
1. **Unit Tests**
|
|
374
|
-
- Authorizer → security scheme mapping
|
|
375
|
-
- Schema extraction from StandardSchema
|
|
376
|
-
- TypeScript code generation
|
|
377
|
-
|
|
378
|
-
2. **Integration Tests**
|
|
379
|
-
- Full endpoint → TypeScript output pipeline
|
|
380
|
-
- Generated code compiles without errors
|
|
381
|
-
- Auth map matches endpoint authorizers
|
|
382
|
-
|
|
383
|
-
3. **E2E Tests**
|
|
384
|
-
- Auth-aware fetcher selects correct auth per endpoint
|
|
385
|
-
- Bearer endpoints get JWT headers
|
|
386
|
-
- IAM endpoints get SigV4 signatures
|
|
387
|
-
- Public endpoints get no auth headers
|
|
388
|
-
|
|
389
|
-
## Open Questions
|
|
390
|
-
|
|
391
|
-
1. **Schema naming conflicts** - What if two endpoints have the same operationId?
|
|
392
|
-
- Proposal: Append route hash suffix if conflict detected
|
|
393
|
-
|
|
394
|
-
2. **Circular schema references** - How to handle `User { friends: User[] }`?
|
|
395
|
-
- Proposal: Use TypeScript `interface` declarations which support self-reference
|
|
396
|
-
|
|
397
|
-
3. **Optional vs required auth** - Some endpoints allow optional auth (return more data if authenticated)
|
|
398
|
-
- Proposal: Add `optional` auth type: `'bearer' | 'bearer?' | null`
|
|
399
|
-
|
|
400
|
-
## Timeline
|
|
401
|
-
|
|
402
|
-
| Phase | Description | Estimate |
|
|
403
|
-
|-------|-------------|----------|
|
|
404
|
-
| 1 | Schema package updates (ComponentCollector) | - |
|
|
405
|
-
| 2 | CLI TypeScript generator | - |
|
|
406
|
-
| 3 | Client auth-aware fetcher | - |
|
|
407
|
-
| 4 | Documentation and examples | - |
|
|
408
|
-
| 5 | Testing and refinement | - |
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
# Dev Server Resilience Design
|
|
2
|
-
|
|
3
|
-
Status: parked / not yet started
|
|
4
|
-
Owner: TBD
|
|
5
|
-
Scope: `packages/cli/src/dev/index.ts`, `packages/cli/src/generators/Generator.ts`
|
|
6
|
-
|
|
7
|
-
## Background
|
|
8
|
-
|
|
9
|
-
Running `gkm dev` against a real workspace (e.g. `rezgo`: api, auth, web, app/Expo)
|
|
10
|
-
exposes three classes of failure. None are caused by user code; they are
|
|
11
|
-
limitations of the current dev orchestrator and hot-reload implementation.
|
|
12
|
-
|
|
13
|
-
## Issue 1 — Hot reload misses new files and serves stale transitive modules
|
|
14
|
-
|
|
15
|
-
### Symptoms
|
|
16
|
-
|
|
17
|
-
- Adding a new route file does not trigger a rebuild.
|
|
18
|
-
- After adding a new export to a non-route file, route files that import it
|
|
19
|
-
fail with:
|
|
20
|
-
`SyntaxError: The requested module '~/.../foo.ts' does not provide an export named 'bar'`
|
|
21
|
-
- Some changes "just don't get picked up" until the dev server is restarted.
|
|
22
|
-
|
|
23
|
-
### Root causes
|
|
24
|
-
|
|
25
|
-
1. **`add`/`unlink` events are ignored.** The chokidar watcher in `dev/index.ts`
|
|
26
|
-
only listens for `change`:
|
|
27
|
-
```ts
|
|
28
|
-
watcher.on('change', async (path) => { ... });
|
|
29
|
-
```
|
|
30
|
-
New or deleted files never trigger a rebuild.
|
|
31
|
-
|
|
32
|
-
2. **Cache-bust is shallow.** `Generator.ts:load()` appends `?t=<now>` only to
|
|
33
|
-
the top-level globbed route file URL. Node's ESM cache is keyed by URL, so
|
|
34
|
-
any *transitive* import (services, domain modules, env, etc.) is served from
|
|
35
|
-
cache forever within the CLI process. When a transitive module is edited,
|
|
36
|
-
the route file is re-evaluated against the stale cached version → the
|
|
37
|
-
"does not provide an export named" error above.
|
|
38
|
-
|
|
39
|
-
3. **Watch patterns are too narrow.** Only `routes`, `functions`, `crons`,
|
|
40
|
-
`subscribers` (plus envParser / logger / hooks files) are watched. Edits to
|
|
41
|
-
`src/domain/**`, `src/services/**`, etc. don't fire any rebuild even though
|
|
42
|
-
those files are pulled in transitively at openapi/build time.
|
|
43
|
-
|
|
44
|
-
### Proposed fix
|
|
45
|
-
|
|
46
|
-
- Subscribe to `add` and `unlink` on the watcher and re-resolve the glob set
|
|
47
|
-
before rebuilding.
|
|
48
|
-
- Broaden the watch pattern to cover the app's `src/**/*.{ts,tsx}` (configurable),
|
|
49
|
-
not just construct entry directories.
|
|
50
|
-
- Bust transitive caches. Two viable approaches:
|
|
51
|
-
- **Worker thread per rebuild** (preferred): move `EndpointGenerator.load` /
|
|
52
|
-
`FunctionGenerator.load` / etc. into a short-lived `worker_threads` worker
|
|
53
|
-
that gets recreated on each rebuild. Each worker has a fresh module graph,
|
|
54
|
-
so transitive imports are guaranteed fresh. Cost is one worker spawn per
|
|
55
|
-
rebuild (~50-100ms), but avoids the unbounded-memory leak of accumulating
|
|
56
|
-
`?t=N` URLs in the main process.
|
|
57
|
-
- **Custom loader hook**: install a Node loader that rewrites every resolved
|
|
58
|
-
URL to include the current rebuild generation. Cheaper per rebuild but
|
|
59
|
-
fragile (loader compatibility with tsx, source maps, etc.).
|
|
60
|
-
|
|
61
|
-
Worker thread is the recommended path.
|
|
62
|
-
|
|
63
|
-
## Issue 2 — Ctrl+C orphans `tsx`/`node` processes
|
|
64
|
-
|
|
65
|
-
### Symptoms
|
|
66
|
-
|
|
67
|
-
After pressing Ctrl+C in a workspace `gkm dev`, the shell returns but
|
|
68
|
-
`tsx` and `node` processes remain alive. Workaround is `killall node`.
|
|
69
|
-
|
|
70
|
-
### Process chain in workspace mode
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
shell
|
|
74
|
-
└── gkm dev (top-level, workspace)
|
|
75
|
-
└── pnpm turbo run dev [spawned with detached: true]
|
|
76
|
-
├── @rezgo/api: gkm dev (per-app)
|
|
77
|
-
│ └── tsx [spawned with detached: true]
|
|
78
|
-
│ └── node (Hono server)
|
|
79
|
-
├── @rezgo/auth: ...
|
|
80
|
-
└── @rezgo/app: ...
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Root cause
|
|
84
|
-
|
|
85
|
-
The per-app `gkm dev` spawns `tsx` with `detached: true`
|
|
86
|
-
(`dev/index.ts:1521`). That moves tsx into a *new process group* outside the
|
|
87
|
-
turbo subtree. The workspace shutdown handler only sends SIGTERM/SIGKILL to
|
|
88
|
-
turbo's pgid; tsx's pgid is never targeted. After SIGKILL hits turbo's group,
|
|
89
|
-
the per-app gkm processes die *before* their async shutdown finishes calling
|
|
90
|
-
`process.kill(-tsxPgid, 'SIGKILL')`. tsx and its node child are orphaned.
|
|
91
|
-
|
|
92
|
-
The `detached: true` flag exists because the user's running Hono server may
|
|
93
|
-
ignore SIGTERM, so we need to kill its whole group. The design conflict is:
|
|
94
|
-
detaching tsx is necessary to forcibly kill it, but it also escapes the
|
|
95
|
-
top-level reachability tree.
|
|
96
|
-
|
|
97
|
-
### Proposed fix
|
|
98
|
-
|
|
99
|
-
Track every tsx PID centrally:
|
|
100
|
-
|
|
101
|
-
- Each `DevServer` registers its `tsx` pid into a shared `Set<number>` at the
|
|
102
|
-
workspace level (or writes to a state file under `.gkm/`).
|
|
103
|
-
- Workspace shutdown iterates that set and issues `process.kill(-pid, 'SIGKILL')`
|
|
104
|
-
for each known tsx pgid *before* falling back to the turbo-pgid SIGKILL.
|
|
105
|
-
- As belt-and-suspenders, drain the registry on per-app `gkm dev` exit so dead
|
|
106
|
-
pids are not retargeted.
|
|
107
|
-
|
|
108
|
-
This makes the kill reachable regardless of process-group escape.
|
|
109
|
-
|
|
110
|
-
## Issue 3 — One app's crash brings down the whole workspace
|
|
111
|
-
|
|
112
|
-
### Symptoms
|
|
113
|
-
|
|
114
|
-
`@rezgo/app` (Expo) crashed with a Metro `DependencyGraph._onHasteChange`
|
|
115
|
-
TypeError. Within seconds, `@rezgo/api`, `@rezgo/auth`, `@rezgo/web` all
|
|
116
|
-
received SIGTERM and shut down. The user lost 21 minutes of warmed dev state.
|
|
117
|
-
|
|
118
|
-
### Root causes
|
|
119
|
-
|
|
120
|
-
1. **Turbo's persistent-task semantics.** When a persistent task in
|
|
121
|
-
`turbo run dev` exits non-zero, turbo cancels sibling persistent tasks. There
|
|
122
|
-
is no flag (as of turbo 2.x) that keeps survivors running through a sibling
|
|
123
|
-
crash. `--continue` only affects scheduling of *queued* tasks, not running
|
|
124
|
-
persistent ones.
|
|
125
|
-
2. **gkm's orchestrator treats turbo's non-zero exit as fatal.** In
|
|
126
|
-
`workspaceDevCommand`:
|
|
127
|
-
```ts
|
|
128
|
-
turboProcess.on('exit', (code) => {
|
|
129
|
-
if (code !== null && code !== 0) {
|
|
130
|
-
reject(new Error(`Turbo exited with code ${code}`));
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
```
|
|
134
|
-
The reject fires the shutdown handler, which kills any survivors that
|
|
135
|
-
turbo hadn't already torn down.
|
|
136
|
-
|
|
137
|
-
### Proposed fix
|
|
138
|
-
|
|
139
|
-
Stop using `turbo run dev` for the persistent dev loop. Build an in-process
|
|
140
|
-
supervisor inside `workspaceDevCommand`:
|
|
141
|
-
|
|
142
|
-
- Resolve dependency order via the existing `getAppBuildOrder` (we still use
|
|
143
|
-
turbo's task graph indirectly via workspace config).
|
|
144
|
-
- For each app, `spawn` its dev command directly (`pnpm dev` in that app's
|
|
145
|
-
cwd, or for backend apps invoke the per-app gkm dev codepath directly without
|
|
146
|
-
going through pnpm/turbo).
|
|
147
|
-
- Supervise each child:
|
|
148
|
-
- `on('exit', code)`: log the crash, do **not** propagate, schedule a restart
|
|
149
|
-
with exponential backoff (start at 1s, cap at 30s, reset after a 60s clean
|
|
150
|
-
run).
|
|
151
|
-
- Stream stdout/stderr to the parent with an app-name prefix so output stays
|
|
152
|
-
readable.
|
|
153
|
-
- Centralize the PID registry from Issue 2 here.
|
|
154
|
-
- Ctrl+C handler: iterate registry, SIGKILL each child group, then exit.
|
|
155
|
-
|
|
156
|
-
Turbo remains the build-time orchestrator (`gkm build`, dependency-ordered
|
|
157
|
-
package builds). Only the dev persistent loop is moved off it.
|
|
158
|
-
|
|
159
|
-
### Why not fix turbo's behavior instead
|
|
160
|
-
|
|
161
|
-
Tried first. `--continue=dependencies-successful` and friends don't apply to
|
|
162
|
-
sibling persistent tasks. Filing it upstream is fine, but the dev experience
|
|
163
|
-
needs to be fixed now and the supervisor pattern is also what makes Issues 1
|
|
164
|
-
and 2 solvable cleanly.
|
|
165
|
-
|
|
166
|
-
## Implementation order (when unparked)
|
|
167
|
-
|
|
168
|
-
1. Land the in-process supervisor (Issue 3 fix). This gives us a single owner
|
|
169
|
-
of the dev process tree.
|
|
170
|
-
2. Move tsx PID registration into the supervisor (Issue 2 fix).
|
|
171
|
-
3. Move hot-reload (worker thread + broadened watcher + `add`/`unlink`) into
|
|
172
|
-
the per-app branch of the supervisor (Issue 1 fix).
|
|
173
|
-
|
|
174
|
-
Each step is shippable independently. Order matters: 1 unblocks the cleanest
|
|
175
|
-
form of 2 and 3.
|
|
176
|
-
|
|
177
|
-
## Out of scope
|
|
178
|
-
|
|
179
|
-
- Replacing `tsx` (e.g. with `node --experimental-strip-types`).
|
|
180
|
-
- Native Bun runtime for dev — separate decision.
|
|
181
|
-
- Replacing chokidar.
|
|
182
|
-
|
|
183
|
-
## Open questions
|
|
184
|
-
|
|
185
|
-
- Should the supervisor expose a `--no-restart` flag for CI-like local runs?
|
|
186
|
-
- Restart backoff thresholds — should they be configurable per app in
|
|
187
|
-
workspace config, or fixed?
|
|
188
|
-
- Should we surface a small status line ("3 of 4 apps running") when one app
|
|
189
|
-
is dead but the rest are healthy?
|