@geekmidas/cli 10.0.0-alpha.6 → 10.0.0-alpha.60
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 +225 -268
- package/bin/adjacent-tsconfig.mjs +97 -0
- package/bin/gkm.mjs +16 -2
- package/bin/owning-tsconfig-jsx-register.mjs +18 -0
- package/bin/owning-tsconfig-jsx.mjs +108 -0
- package/dist/{HostingerProvider-h3EbEp-Z.cjs → HostingerProvider-BTZd2u0f.cjs} +21 -22
- package/dist/HostingerProvider-BTZd2u0f.cjs.map +1 -0
- package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-DgzKa_Tj.mjs} +20 -21
- package/dist/HostingerProvider-DgzKa_Tj.mjs.map +1 -0
- package/dist/LegacyStateStore-CToa2hga.mjs +89 -0
- package/dist/LegacyStateStore-CToa2hga.mjs.map +1 -0
- package/dist/LegacyStateStore-CidlPT0N.cjs +89 -0
- package/dist/LegacyStateStore-CidlPT0N.cjs.map +1 -0
- package/dist/LocalStateStore-BFLiOocU.mjs +165 -0
- package/dist/LocalStateStore-BFLiOocU.mjs.map +1 -0
- package/dist/LocalStateStore-Dpuqka1N.cjs +176 -0
- package/dist/LocalStateStore-Dpuqka1N.cjs.map +1 -0
- package/dist/{openapi-D-dx9Akj.cjs → OpenApiTsGenerator-BTuUumsV.cjs} +330 -469
- package/dist/OpenApiTsGenerator-BTuUumsV.cjs.map +1 -0
- package/dist/{openapi-Bw8DWFWz.mjs → OpenApiTsGenerator-CvVr1Ilz.mjs} +295 -403
- package/dist/OpenApiTsGenerator-CvVr1Ilz.mjs.map +1 -0
- package/dist/{Route53Provider-RdpUDJQk.mjs → Route53Provider-Cvj40A8I.mjs} +12 -12
- package/dist/Route53Provider-Cvj40A8I.mjs.map +1 -0
- package/dist/{Route53Provider-di2fMM5N.cjs → Route53Provider-DVILBsvV.cjs} +20 -21
- package/dist/Route53Provider-DVILBsvV.cjs.map +1 -0
- package/dist/S3StateStore-aaGkjcxO.mjs +161 -0
- package/dist/S3StateStore-aaGkjcxO.mjs.map +1 -0
- package/dist/S3StateStore-cnm813Xn.cjs +160 -0
- package/dist/S3StateStore-cnm813Xn.cjs.map +1 -0
- package/dist/SSMStateStore-BllaJKGo.mjs +154 -0
- package/dist/SSMStateStore-BllaJKGo.mjs.map +1 -0
- package/dist/SSMStateStore-DwaGprVX.cjs +153 -0
- package/dist/SSMStateStore-DwaGprVX.cjs.map +1 -0
- package/dist/appPorts-C9z9Pzn9.mjs +223 -0
- package/dist/appPorts-C9z9Pzn9.mjs.map +1 -0
- package/dist/appPorts-Cu79hJF6.cjs +264 -0
- package/dist/appPorts-Cu79hJF6.cjs.map +1 -0
- package/dist/aws-DkHdTV-p.cjs +61 -0
- package/dist/aws-DkHdTV-p.cjs.map +1 -0
- package/dist/aws-DojzQnLd.mjs +61 -0
- package/dist/aws-DojzQnLd.mjs.map +1 -0
- package/dist/{backup-provisioner-BrsHwYG0.cjs → backup-provisioner-BmhIO_Yr.cjs} +21 -19
- package/dist/backup-provisioner-BmhIO_Yr.cjs.map +1 -0
- package/dist/{backup-provisioner-Bgj5Vi_L.mjs → backup-provisioner-DIVCbfee.mjs} +10 -7
- package/dist/backup-provisioner-DIVCbfee.mjs.map +1 -0
- package/dist/{bundler-BY1OmV1e.cjs → bundler-CzXZPSBJ.cjs} +20 -32
- package/dist/bundler-CzXZPSBJ.cjs.map +1 -0
- package/dist/{bundler-Be8Zg4Wd.mjs → bundler-DJVR4QlW.mjs} +18 -29
- package/dist/bundler-DJVR4QlW.mjs.map +1 -0
- package/dist/cli-D_qTl20Z.cjs +69 -0
- package/dist/cli-D_qTl20Z.cjs.map +1 -0
- package/dist/cli-DzR1hpum.mjs +69 -0
- package/dist/cli-DzR1hpum.mjs.map +1 -0
- package/dist/{config-CxP7P-qG.mjs → config-C5-EEdmr.mjs} +144 -127
- package/dist/config-C5-EEdmr.mjs.map +1 -0
- package/dist/{config-CNz5KaSR.cjs → config-DXnkCEq0.cjs} +212 -184
- package/dist/config-DXnkCEq0.cjs.map +1 -0
- package/dist/config.cjs +9 -6
- package/dist/config.d.cts +124 -33
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +124 -33
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +3 -5
- package/dist/deploy/public.cjs +22 -0
- package/dist/deploy/public.d.cts +459 -0
- package/dist/deploy/public.d.cts.map +1 -0
- package/dist/deploy/public.d.mts +459 -0
- package/dist/deploy/public.d.mts.map +1 -0
- package/dist/deploy/public.mjs +5 -0
- package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
- package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
- package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
- package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
- package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
- package/dist/deploy/sniffer-hooks.cjs +13 -7
- package/dist/deploy/sniffer-hooks.cjs.map +1 -1
- package/dist/deploy/sniffer-hooks.d.cts +1 -2
- package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
- package/dist/deploy/sniffer-hooks.d.mts +1 -2
- package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
- package/dist/deploy/sniffer-hooks.mjs +10 -3
- package/dist/deploy/sniffer-hooks.mjs.map +1 -1
- package/dist/deploy/sniffer-loader.cjs +16 -7
- package/dist/deploy/sniffer-loader.cjs.map +1 -1
- package/dist/deploy/sniffer-loader.d.cts +1 -1
- package/dist/deploy/sniffer-loader.d.mts +1 -1
- package/dist/deploy/sniffer-loader.mjs +14 -3
- package/dist/deploy/sniffer-loader.mjs.map +1 -1
- package/dist/deploy/sniffer-routes-worker.cjs +11 -11
- package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
- package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
- package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
- package/dist/deploy/sniffer-routes-worker.mjs +3 -3
- package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
- package/dist/deploy/sniffer-worker.cjs +15 -6
- package/dist/deploy/sniffer-worker.cjs.map +1 -1
- package/dist/deploy/sniffer-worker.d.cts +1 -3
- package/dist/deploy/sniffer-worker.d.cts.map +1 -1
- package/dist/deploy/sniffer-worker.d.mts +1 -3
- package/dist/deploy/sniffer-worker.d.mts.map +1 -1
- package/dist/deploy/sniffer-worker.mjs +15 -4
- package/dist/deploy/sniffer-worker.mjs.map +1 -1
- package/dist/deploy-0fBVeWO-.cjs +3518 -0
- package/dist/deploy-0fBVeWO-.cjs.map +1 -0
- package/dist/deploy-D6Q09OkA.mjs +3429 -0
- package/dist/deploy-D6Q09OkA.mjs.map +1 -0
- package/dist/{discover-DTmFeloL.cjs → discover-Bc-4eA_p.cjs} +131 -103
- package/dist/discover-Bc-4eA_p.cjs.map +1 -0
- package/dist/{discover-CAlFgYec.mjs → discover-FrYvzkeC.mjs} +91 -58
- package/dist/discover-FrYvzkeC.mjs.map +1 -0
- package/dist/{emit-CiZS_5Ub.mjs → emit-C1e8qD08.mjs} +13 -26
- package/dist/emit-C1e8qD08.mjs.map +1 -0
- package/dist/{emit-CbcRolsa.cjs → emit-Dmc1nvdS.cjs} +31 -57
- package/dist/emit-Dmc1nvdS.cjs.map +1 -0
- package/dist/encryption-CML4UaPi.cjs +91 -0
- package/dist/encryption-CML4UaPi.cjs.map +1 -0
- package/dist/encryption-aDA2AzVx.mjs +90 -0
- package/dist/encryption-aDA2AzVx.mjs.map +1 -0
- package/dist/fakes-C9RiT6XG.mjs +125 -0
- package/dist/fakes-C9RiT6XG.mjs.map +1 -0
- package/dist/fakes-zW-jNAbQ.cjs +148 -0
- package/dist/fakes-zW-jNAbQ.cjs.map +1 -0
- package/dist/github-Cq57poPj.cjs +213 -0
- package/dist/github-Cq57poPj.cjs.map +1 -0
- package/dist/github-DmCj2u95.mjs +213 -0
- package/dist/github-DmCj2u95.mjs.map +1 -0
- package/dist/home-DOzBaWaL.cjs +33 -0
- package/dist/home-DOzBaWaL.cjs.map +1 -0
- package/dist/home-GI7pJl1M.mjs +22 -0
- package/dist/home-GI7pJl1M.mjs.map +1 -0
- package/dist/{index-DEbaleny.d.mts → index-Da1-oa9W.d.mts} +4 -23
- package/dist/index-Da1-oa9W.d.mts.map +1 -0
- package/dist/{index-BGGdjueF.d.cts → index-UiWCaGzU.d.cts} +4 -23
- package/dist/index-UiWCaGzU.d.cts.map +1 -0
- package/dist/index.cjs +9096 -12213
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +9067 -12192
- package/dist/index.mjs.map +1 -1
- package/dist/migrate-BTqIflwc.cjs +743 -0
- package/dist/migrate-BTqIflwc.cjs.map +1 -0
- package/dist/migrate-B_6KofUo.mjs +736 -0
- package/dist/migrate-B_6KofUo.mjs.map +1 -0
- package/dist/openapi.cjs +198 -10
- package/dist/openapi.cjs.map +1 -0
- package/dist/openapi.d.cts +21 -19
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +21 -19
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +193 -5
- package/dist/openapi.mjs.map +1 -0
- package/dist/ready-CCLIAkwR.cjs +807 -0
- package/dist/ready-CCLIAkwR.cjs.map +1 -0
- package/dist/ready-CIHpnUc5.mjs +760 -0
- package/dist/ready-CIHpnUc5.mjs.map +1 -0
- package/dist/reconcile/public.cjs +3 -5
- package/dist/reconcile/public.d.cts +30 -33
- package/dist/reconcile/public.d.cts.map +1 -1
- package/dist/reconcile/public.d.mts +30 -33
- package/dist/reconcile/public.d.mts.map +1 -1
- package/dist/reconcile/public.mjs +3 -4
- package/dist/{reconcile-CFs8C_1a.mjs → reconcile--I7V4Klj.mjs} +4 -7
- package/dist/reconcile--I7V4Klj.mjs.map +1 -0
- package/dist/{reconcile-D0pimNiy.cjs → reconcile-CuCQBa5-.cjs} +5 -8
- package/dist/reconcile-CuCQBa5-.cjs.map +1 -0
- package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
- package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
- package/dist/sniffer-BM8fpCas.mjs +6321 -0
- package/dist/sniffer-BM8fpCas.mjs.map +1 -0
- package/dist/sniffer-DIv12ncU.cjs +6707 -0
- package/dist/sniffer-DIv12ncU.cjs.map +1 -0
- package/dist/storage-BzaUxmqe.mjs +124 -0
- package/dist/storage-BzaUxmqe.mjs.map +1 -0
- package/dist/storage-CSGoC3bK.cjs +152 -0
- package/dist/storage-CSGoC3bK.cjs.map +1 -0
- package/dist/store-BS8A7NcA.mjs +415 -0
- package/dist/store-BS8A7NcA.mjs.map +1 -0
- package/dist/store-KvNQwYaB.cjs +510 -0
- package/dist/store-KvNQwYaB.cjs.map +1 -0
- package/dist/types-Bp1mVxG0.d.mts +6410 -0
- package/dist/types-Bp1mVxG0.d.mts.map +1 -0
- package/dist/types-efNLu9xu.d.cts +6411 -0
- package/dist/types-efNLu9xu.d.cts.map +1 -0
- package/dist/vitest.cjs +65 -0
- package/dist/vitest.cjs.map +1 -0
- package/dist/vitest.d.cts +29 -0
- package/dist/vitest.d.cts.map +1 -0
- package/dist/vitest.d.mts +29 -0
- package/dist/vitest.d.mts.map +1 -0
- package/dist/vitest.mjs +65 -0
- package/dist/vitest.mjs.map +1 -0
- package/dist/workspace/index.cjs +3 -4
- package/dist/workspace/index.d.cts +3 -3
- package/dist/workspace/index.d.mts +3 -3
- package/dist/workspace/index.mjs +2 -3
- package/dist/{workspace-LKiNyaDy.cjs → workspace-B64Xk1Mb.cjs} +1070 -1118
- package/dist/workspace-B64Xk1Mb.cjs.map +1 -0
- package/dist/{workspace-DIuZx-cc.mjs → workspace-Bp1xVaOz.mjs} +901 -972
- package/dist/workspace-Bp1xVaOz.mjs.map +1 -0
- package/package.json +38 -20
- package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
- package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
- package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
- package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
- package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
- package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
- package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
- package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
- package/dist/LocalStateProvider-Bn6tS-oL.mjs +0 -42
- package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
- package/dist/LocalStateProvider-Db9SEjyH.cjs +0 -43
- package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
- package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
- package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
- package/dist/SSMStateProvider-BRt2py-A.mjs +0 -66
- package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
- package/dist/SSMStateProvider-DyX8s9HI.cjs +0 -66
- package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
- package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
- package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
- package/dist/bundler-BY1OmV1e.cjs.map +0 -1
- package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
- package/dist/chunk-Duj1WY3L.mjs +0 -7
- package/dist/config-CNz5KaSR.cjs.map +0 -1
- package/dist/config-CxP7P-qG.mjs.map +0 -1
- package/dist/credentials-B5zRHdAl.mjs +0 -141
- package/dist/credentials-B5zRHdAl.mjs.map +0 -1
- package/dist/credentials-BK3Z93MX.mjs +0 -2548
- package/dist/credentials-BK3Z93MX.mjs.map +0 -1
- package/dist/credentials-BapzjyV5.cjs +0 -195
- package/dist/credentials-BapzjyV5.cjs.map +0 -1
- package/dist/credentials-DzsXZzkx.cjs +0 -2680
- package/dist/credentials-DzsXZzkx.cjs.map +0 -1
- package/dist/discover-CAlFgYec.mjs.map +0 -1
- package/dist/discover-DTmFeloL.cjs.map +0 -1
- package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
- package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
- package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
- package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
- package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
- package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
- package/dist/emit-CbcRolsa.cjs.map +0 -1
- package/dist/emit-CiZS_5Ub.mjs.map +0 -1
- package/dist/encryption-C6jaU0hE.cjs +0 -54
- package/dist/encryption-C6jaU0hE.cjs.map +0 -1
- package/dist/encryption-CHzzeR8a.cjs +0 -4
- package/dist/encryption-CQUncu7v.mjs +0 -3
- package/dist/encryption-D-abyhZx.mjs +0 -42
- package/dist/encryption-D-abyhZx.mjs.map +0 -1
- package/dist/fullstack-secrets-C-GGohke.cjs +0 -111
- package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
- package/dist/fullstack-secrets-D1o9-G5l.mjs +0 -87
- package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
- package/dist/generator-CNzBw7g5.cjs +0 -289
- package/dist/generator-CNzBw7g5.cjs.map +0 -1
- package/dist/generator-VE2JrFlY.mjs +0 -253
- package/dist/generator-VE2JrFlY.mjs.map +0 -1
- package/dist/index-BGGdjueF.d.cts.map +0 -1
- package/dist/index-DEbaleny.d.mts.map +0 -1
- package/dist/openapi-Bw8DWFWz.mjs.map +0 -1
- package/dist/openapi-D-dx9Akj.cjs.map +0 -1
- package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
- package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
- package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
- package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
- package/dist/openapi-react-query.cjs +0 -4
- package/dist/openapi-react-query.d.cts +0 -11
- package/dist/openapi-react-query.d.cts.map +0 -1
- package/dist/openapi-react-query.d.mts +0 -11
- package/dist/openapi-react-query.d.mts.map +0 -1
- package/dist/openapi-react-query.mjs +0 -4
- package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
- package/dist/reconcile-D0pimNiy.cjs.map +0 -1
- package/dist/setup-8IWPsRIN.cjs +0 -11
- package/dist/setup-BWMhbW-p.mjs +0 -443
- package/dist/setup-BWMhbW-p.mjs.map +0 -1
- package/dist/setup-D7L4BgBT.cjs +0 -473
- package/dist/setup-D7L4BgBT.cjs.map +0 -1
- package/dist/setup-DGIPd2fh.mjs +0 -11
- package/dist/storage-BJmzYxt8.cjs +0 -363
- package/dist/storage-BJmzYxt8.cjs.map +0 -1
- package/dist/storage-BM9hGpgv.cjs +0 -7
- package/dist/storage-Bi24WfoW.mjs +0 -297
- package/dist/storage-Bi24WfoW.mjs.map +0 -1
- package/dist/storage-CYlGwWTj.mjs +0 -3
- package/dist/sync-CmEuNZsB.mjs +0 -76
- package/dist/sync-CmEuNZsB.mjs.map +0 -1
- package/dist/sync-D306yOWu.cjs +0 -4
- package/dist/sync-SizaChmC.cjs +0 -93
- package/dist/sync-SizaChmC.cjs.map +0 -1
- package/dist/sync-hOqAWHR6.mjs +0 -3
- package/dist/types-BLSNdrk0.d.cts +0 -2176
- package/dist/types-BLSNdrk0.d.cts.map +0 -1
- package/dist/types-C3POXhw3.d.mts +0 -2176
- package/dist/types-C3POXhw3.d.mts.map +0 -1
- package/dist/workspace-CGaUAw5A.cjs +0 -9
- package/dist/workspace-CnTqIlB3.mjs +0 -8
- package/dist/workspace-DIuZx-cc.mjs.map +0 -1
- package/dist/workspace-LKiNyaDy.cjs.map +0 -1
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const node_child_process = require_chunk.__toESM(require("node:child_process"));
|
|
8
|
-
const __geekmidas_constructs_endpoints = require_chunk.__toESM(require("@geekmidas/constructs/endpoints"));
|
|
9
|
-
const node_url = require_chunk.__toESM(require("node:url"));
|
|
10
|
-
const __geekmidas_schema_conversion = require_chunk.__toESM(require("@geekmidas/schema/conversion"));
|
|
11
|
-
|
|
1
|
+
const require_discover = require("./discover-Bc-4eA_p.cjs");
|
|
2
|
+
let node_path = require("node:path");
|
|
3
|
+
let node_fs = require("node:fs");
|
|
4
|
+
let node_fs_promises = require("node:fs/promises");
|
|
5
|
+
let _geekmidas_constructs_endpoints = require("@geekmidas/constructs/endpoints");
|
|
6
|
+
let _geekmidas_schema_conversion = require("@geekmidas/schema/conversion");
|
|
12
7
|
//#region src/build/endpoint-analyzer.ts
|
|
13
8
|
/**
|
|
14
9
|
* Analyze an endpoint to extract its features
|
|
@@ -85,7 +80,6 @@ function summarizeAnalysis(analyses) {
|
|
|
85
80
|
byFeature
|
|
86
81
|
};
|
|
87
82
|
}
|
|
88
|
-
|
|
89
83
|
//#endregion
|
|
90
84
|
//#region src/build/handler-templates.ts
|
|
91
85
|
/**
|
|
@@ -107,8 +101,7 @@ function generateMinimalHandler(analysis) {
|
|
|
107
101
|
const { exportName, features } = analysis;
|
|
108
102
|
const method = analysis.method.toLowerCase();
|
|
109
103
|
const validators = generateValidators(exportName, features);
|
|
110
|
-
|
|
111
|
-
if (!hasValidators && !features.hasOutputValidation) return `
|
|
104
|
+
if (!(validators.length > 0) && !features.hasOutputValidation) return `
|
|
112
105
|
// Minimal handler: ${analysis.route} (${analysis.method})
|
|
113
106
|
app.${method}('${analysis.route}', async (c) => {
|
|
114
107
|
const result = await ${exportName}.handler(
|
|
@@ -256,10 +249,10 @@ function generateValidatorsFile(analyses) {
|
|
|
256
249
|
const needsQuery = analyses.some((a) => a.features.hasQueryValidation);
|
|
257
250
|
const needsParams = analyses.some((a) => a.features.hasParamValidation);
|
|
258
251
|
if (!needsBody && !needsQuery && !needsParams) return `// No validators needed for this build\nexport {};\n`;
|
|
259
|
-
const exports
|
|
252
|
+
const exports = [];
|
|
260
253
|
const factories = [];
|
|
261
254
|
if (needsBody) {
|
|
262
|
-
exports
|
|
255
|
+
exports.push("validateBody");
|
|
263
256
|
factories.push(`
|
|
264
257
|
export const validateBody = (endpoint: any) =>
|
|
265
258
|
validator('json', async (value, c) => {
|
|
@@ -270,7 +263,7 @@ export const validateBody = (endpoint: any) =>
|
|
|
270
263
|
});`);
|
|
271
264
|
}
|
|
272
265
|
if (needsQuery) {
|
|
273
|
-
exports
|
|
266
|
+
exports.push("validateQuery");
|
|
274
267
|
factories.push(`
|
|
275
268
|
export const validateQuery = (endpoint: any) =>
|
|
276
269
|
validator('query', async (_, c) => {
|
|
@@ -282,7 +275,7 @@ export const validateQuery = (endpoint: any) =>
|
|
|
282
275
|
});`);
|
|
283
276
|
}
|
|
284
277
|
if (needsParams) {
|
|
285
|
-
exports
|
|
278
|
+
exports.push("validateParams");
|
|
286
279
|
factories.push(`
|
|
287
280
|
export const validateParams = (endpoint: any) =>
|
|
288
281
|
validator('param', async (params, c) => {
|
|
@@ -306,8 +299,7 @@ ${factories.join("\n")}
|
|
|
306
299
|
*/
|
|
307
300
|
function generateMinimalEndpointFile(analysis, endpointImport) {
|
|
308
301
|
const { exportName, features } = analysis;
|
|
309
|
-
const
|
|
310
|
-
const validatorImport = needsValidators ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
302
|
+
const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
311
303
|
const handler = generateMinimalHandler(analysis);
|
|
312
304
|
return `/**
|
|
313
305
|
* Minimal endpoint: ${analysis.route} (${analysis.method})
|
|
@@ -332,8 +324,7 @@ ${handler}
|
|
|
332
324
|
*/
|
|
333
325
|
function generateStandardEndpointFile(analysis, endpointImport) {
|
|
334
326
|
const { exportName, features } = analysis;
|
|
335
|
-
const
|
|
336
|
-
const validatorImport = needsValidators ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
327
|
+
const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
337
328
|
const eventsImport = features.hasEvents ? `import { publishConstructEvents } from '@geekmidas/constructs/endpoints';` : "";
|
|
338
329
|
const handler = generateStandardHandler(analysis);
|
|
339
330
|
return `/**
|
|
@@ -425,7 +416,7 @@ export function setupFullEndpoints(
|
|
|
425
416
|
}
|
|
426
417
|
const imports = tierEndpoints.map((a) => `import { setup${capitalize(a.exportName)} } from './${a.exportName}.js';`).join("\n");
|
|
427
418
|
if (tier === "minimal") {
|
|
428
|
-
const calls
|
|
419
|
+
const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, logger);`).join("\n");
|
|
429
420
|
return `/**
|
|
430
421
|
* Minimal-tier endpoint index (${tierEndpoints.length} endpoints)
|
|
431
422
|
* Near-raw-Hono performance
|
|
@@ -438,12 +429,12 @@ export function setupMinimalEndpoints(
|
|
|
438
429
|
app: Hono,
|
|
439
430
|
logger: Logger,
|
|
440
431
|
): void {
|
|
441
|
-
${calls
|
|
432
|
+
${calls}
|
|
442
433
|
}
|
|
443
434
|
`;
|
|
444
435
|
}
|
|
445
436
|
if (tier === "standard") {
|
|
446
|
-
const calls
|
|
437
|
+
const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, serviceDiscovery, logger);`).join("\n");
|
|
447
438
|
return `/**
|
|
448
439
|
* Standard-tier endpoint index (${tierEndpoints.length} endpoints)
|
|
449
440
|
* Auth and/or services enabled
|
|
@@ -458,7 +449,7 @@ export function setupStandardEndpoints(
|
|
|
458
449
|
serviceDiscovery: ServiceDiscovery<any, any>,
|
|
459
450
|
logger: Logger,
|
|
460
451
|
): void {
|
|
461
|
-
${calls
|
|
452
|
+
${calls}
|
|
462
453
|
}
|
|
463
454
|
`;
|
|
464
455
|
}
|
|
@@ -528,9 +519,7 @@ function generateEndpointFilesNested(analyses, endpointImports) {
|
|
|
528
519
|
case "standard":
|
|
529
520
|
files[fileName] = generateStandardEndpointFile(analysis, endpointImport);
|
|
530
521
|
break;
|
|
531
|
-
case "full":
|
|
532
|
-
files[fileName] = generateFullEndpointFile(analysis, endpointImport);
|
|
533
|
-
break;
|
|
522
|
+
case "full": files[fileName] = generateFullEndpointFile(analysis, endpointImport);
|
|
534
523
|
}
|
|
535
524
|
}
|
|
536
525
|
return files;
|
|
@@ -587,7 +576,142 @@ export async function setupEndpoints(
|
|
|
587
576
|
}
|
|
588
577
|
`;
|
|
589
578
|
}
|
|
579
|
+
//#endregion
|
|
580
|
+
//#region src/generators/telemetry.ts
|
|
581
|
+
/**
|
|
582
|
+
* Every package `@geekmidas/telescope/instrumentation` loads at runtime.
|
|
583
|
+
*
|
|
584
|
+
* All of them, rather than one as a proxy: the production bundle follows each
|
|
585
|
+
* import, and a single missing one fails the build rather than the telemetry.
|
|
586
|
+
*/
|
|
587
|
+
const TELEMETRY_PACKAGES = [
|
|
588
|
+
"@opentelemetry/api",
|
|
589
|
+
"@opentelemetry/auto-instrumentations-node",
|
|
590
|
+
"@opentelemetry/exporter-logs-otlp-http",
|
|
591
|
+
"@opentelemetry/exporter-trace-otlp-http",
|
|
592
|
+
"@opentelemetry/instrumentation-pino",
|
|
593
|
+
"@opentelemetry/resources",
|
|
594
|
+
"@opentelemetry/sdk-logs",
|
|
595
|
+
"@opentelemetry/sdk-node",
|
|
596
|
+
"@opentelemetry/sdk-trace-base",
|
|
597
|
+
"@opentelemetry/sdk-trace-node",
|
|
598
|
+
"@opentelemetry/semantic-conventions"
|
|
599
|
+
];
|
|
600
|
+
/**
|
|
601
|
+
* The directory of `name` as `node_modules` lookup finds it from `fromDir`,
|
|
602
|
+
* symlinks resolved — or undefined.
|
|
603
|
+
*
|
|
604
|
+
* The directory walk alone, not `require.resolve`: that also searches
|
|
605
|
+
* `NODE_PATH`, which a package manager's bin shim sets to its own store, so a
|
|
606
|
+
* `gkm build` run through one would find packages the app never installed —
|
|
607
|
+
* and the bundler, which does not look there, would then fail on them.
|
|
608
|
+
*/
|
|
609
|
+
function packageDir(fromDir, name) {
|
|
610
|
+
for (let dir = (0, node_path.resolve)(fromDir);; dir = (0, node_path.dirname)(dir)) {
|
|
611
|
+
const candidate = (0, node_path.join)(dir, "node_modules", name);
|
|
612
|
+
if ((0, node_fs.existsSync)((0, node_path.join)(candidate, "package.json"))) return (0, node_fs.realpathSync)(candidate);
|
|
613
|
+
if ((0, node_path.dirname)(dir) === dir) return void 0;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Whether the telemetry packages resolve the way the bundler will resolve them:
|
|
618
|
+
* telescope from the app, and the OpenTelemetry packages from telescope —
|
|
619
|
+
* where a peer is linked under pnpm, which need not be where the app sees it.
|
|
620
|
+
*/
|
|
621
|
+
function telemetryResolvesFrom(appRoot) {
|
|
622
|
+
const telescope = packageDir(appRoot, "@geekmidas/telescope");
|
|
623
|
+
if (!telescope) return false;
|
|
624
|
+
return TELEMETRY_PACKAGES.every((pkg) => packageDir(telescope, pkg));
|
|
625
|
+
}
|
|
626
|
+
/** The telemetry half of a build context. */
|
|
627
|
+
function telemetryFor(options) {
|
|
628
|
+
return {
|
|
629
|
+
serviceName: options.surfaceId ?? (0, node_path.basename)(options.appRoot),
|
|
630
|
+
...options.workspaceName && { serviceNamespace: options.workspaceName },
|
|
631
|
+
available: telemetryResolvesFrom(options.appRoot)
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
const HEADER = `/**
|
|
635
|
+
* Generated by 'gkm build --production'.
|
|
636
|
+
*
|
|
637
|
+
* Starts OpenTelemetry when OTEL_EXPORTER_OTLP_ENDPOINT names a collector, and
|
|
638
|
+
* does nothing otherwise: without it, the telemetry packages are not loaded.
|
|
639
|
+
* The standard OTEL_* variables (OTEL_TRACES_SAMPLER, OTEL_TRACES_SAMPLER_ARG,
|
|
640
|
+
* OTEL_EXPORTER_OTLP_HEADERS, OTEL_RESOURCE_ATTRIBUTES, OTEL_SERVICE_NAME)
|
|
641
|
+
* configure the rest.
|
|
642
|
+
*/
|
|
643
|
+
|
|
644
|
+
/** Telemetry was asked for and cannot start. The server runs without it. */
|
|
645
|
+
export class TelemetryUnavailable extends Error {
|
|
646
|
+
constructor(readonly reason: string, options?: { cause?: unknown }) {
|
|
647
|
+
super(
|
|
648
|
+
\`OTEL_EXPORTER_OTLP_ENDPOINT is set, but \${reason} This server exports no traces or logs until that is fixed.\`,
|
|
649
|
+
options,
|
|
650
|
+
);
|
|
651
|
+
this.name = 'TelemetryUnavailable';
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
`;
|
|
655
|
+
/**
|
|
656
|
+
* The entry's `telemetry.ts`: a `startTelemetry()` the server awaits before it
|
|
657
|
+
* imports the app, so the libraries the app loads are instrumented.
|
|
658
|
+
*
|
|
659
|
+
* Failing to start telemetry warns (a named `TelemetryUnavailable`, through
|
|
660
|
+
* `process.emitWarning`) and never stops the server: an outage in observability
|
|
661
|
+
* is not a reason to have an outage in the service.
|
|
662
|
+
*/
|
|
663
|
+
function generateTelemetryModule(telemetry) {
|
|
664
|
+
if (!telemetry?.available) return `${HEADER}
|
|
665
|
+
export async function startTelemetry(): Promise<void> {
|
|
666
|
+
if (!process.env.OTEL_EXPORTER_OTLP_ENDPOINT) return;
|
|
667
|
+
|
|
668
|
+
process.emitWarning(
|
|
669
|
+
new TelemetryUnavailable(
|
|
670
|
+
'this server was built without @geekmidas/telescope and the @opentelemetry packages it needs. Add them to the app and rebuild.',
|
|
671
|
+
),
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
`;
|
|
675
|
+
const options = [
|
|
676
|
+
`serviceName: ${JSON.stringify(telemetry.serviceName)},`,
|
|
677
|
+
...telemetry.serviceNamespace ? [`serviceNamespace: ${JSON.stringify(telemetry.serviceNamespace)},`] : [],
|
|
678
|
+
"deploymentEnvironment: process.env.STAGE,",
|
|
679
|
+
"handleSignals: false,"
|
|
680
|
+
];
|
|
681
|
+
return `${HEADER}
|
|
682
|
+
export async function startTelemetry(): Promise<void> {
|
|
683
|
+
if (!process.env.OTEL_EXPORTER_OTLP_ENDPOINT) return;
|
|
684
|
+
|
|
685
|
+
let instrumentation;
|
|
686
|
+
try {
|
|
687
|
+
instrumentation = await import('@geekmidas/telescope/instrumentation');
|
|
688
|
+
} catch (cause) {
|
|
689
|
+
process.emitWarning(
|
|
690
|
+
new TelemetryUnavailable(
|
|
691
|
+
'@geekmidas/telescope/instrumentation or an @opentelemetry package it needs could not be loaded. Install them in the app and rebuild.',
|
|
692
|
+
{ cause },
|
|
693
|
+
),
|
|
694
|
+
);
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
590
697
|
|
|
698
|
+
instrumentation.setupTelemetry({
|
|
699
|
+
${options.join("\n ")}
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
// Flush what is buffered when the process is told to stop. When nothing
|
|
703
|
+
// else handles the signal, re-raise it once flushed, so the process still
|
|
704
|
+
// stops the way it would have without this listener.
|
|
705
|
+
for (const signal of ['SIGTERM', 'SIGINT'] as const) {
|
|
706
|
+
process.once(signal, () => {
|
|
707
|
+
void instrumentation.flushTelemetry().finally(() => {
|
|
708
|
+
if (process.listenerCount(signal) === 0) process.kill(process.pid, signal);
|
|
709
|
+
});
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
`;
|
|
714
|
+
}
|
|
591
715
|
//#endregion
|
|
592
716
|
//#region src/generators/EndpointGenerator.ts
|
|
593
717
|
/**
|
|
@@ -605,11 +729,11 @@ export async function setupEndpoints(
|
|
|
605
729
|
* Falls back to the configured paths for an app that declares no surface.
|
|
606
730
|
*/
|
|
607
731
|
function runtimeFor(context, fromDir, owner) {
|
|
608
|
-
const module
|
|
609
|
-
if (module
|
|
610
|
-
const specifier = importSpecifier(fromDir, module
|
|
732
|
+
const module = owner ? context.owners?.[owner] ?? context.surface?.module : context.surface?.module;
|
|
733
|
+
if (module) {
|
|
734
|
+
const specifier = importSpecifier(fromDir, module.specifier);
|
|
611
735
|
return {
|
|
612
|
-
imports: `import { ${module
|
|
736
|
+
imports: `import { ${module.exportName} as __surface } from '${specifier}';`,
|
|
613
737
|
bindings: [
|
|
614
738
|
"// What this construct was declared with. Objects, not module paths:",
|
|
615
739
|
"// the entry imports the owner, so there is nothing to print.",
|
|
@@ -677,48 +801,35 @@ function corsFor(surface) {
|
|
|
677
801
|
}
|
|
678
802
|
var EndpointGenerator = class extends require_discover.ConstructGenerator {
|
|
679
803
|
isConstruct(value) {
|
|
680
|
-
return
|
|
804
|
+
return _geekmidas_constructs_endpoints.Endpoint.isEndpoint(value);
|
|
681
805
|
}
|
|
682
806
|
async build(context, constructs, outputDir, options) {
|
|
683
|
-
const
|
|
807
|
+
const target = options?.target ?? "aws";
|
|
808
|
+
const root = options?.root ?? process.cwd();
|
|
684
809
|
const enableOpenApi = options?.enableOpenApi || false;
|
|
685
810
|
const logger = console;
|
|
686
811
|
const routes = [];
|
|
687
812
|
if (constructs.length === 0) return routes;
|
|
688
|
-
if (
|
|
813
|
+
if (target === "server") {
|
|
689
814
|
await this.generateEndpointsFile(outputDir, constructs, context);
|
|
690
815
|
const appFile = await this.generateAppFile(outputDir, context);
|
|
691
816
|
routes.push({
|
|
692
817
|
path: "*",
|
|
693
818
|
method: "ALL",
|
|
694
|
-
handler: (0, node_path.relative)(
|
|
819
|
+
handler: (0, node_path.relative)(root, appFile),
|
|
695
820
|
authorizer: "none"
|
|
696
821
|
});
|
|
697
822
|
logger.log(`Generated server with ${constructs.length} endpoints${enableOpenApi ? " (OpenAPI enabled)" : ""}`);
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
path: construct._path,
|
|
705
|
-
method: construct.method,
|
|
706
|
-
handler: (0, node_path.relative)(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
|
|
707
|
-
timeout: construct.timeout,
|
|
708
|
-
memorySize: construct.memorySize,
|
|
709
|
-
environment: await construct.getEnvironment({ markOptional: context.markOptional }),
|
|
710
|
-
dependencies: construct.constructs,
|
|
711
|
-
authorizer: construct.authorizer?.name ?? "none"
|
|
712
|
-
};
|
|
713
|
-
routes.push(routeInfo);
|
|
714
|
-
logger.log(`Generated handler for ${routeInfo.method} ${routeInfo.path}`);
|
|
715
|
-
}
|
|
716
|
-
} else for (const { key, construct, path } of constructs) {
|
|
717
|
-
const handlerFile = await this.generateHandlerFile(outputDir, path.relative, key, provider, construct, context);
|
|
823
|
+
return routes;
|
|
824
|
+
}
|
|
825
|
+
const routesDir = (0, node_path.join)(outputDir, "routes");
|
|
826
|
+
await (0, node_fs_promises.mkdir)(routesDir, { recursive: true });
|
|
827
|
+
for (const { key, construct, path } of constructs) {
|
|
828
|
+
const handlerFile = await this.generateHandlerFile(routesDir, path.relative, key, context);
|
|
718
829
|
const routeInfo = {
|
|
719
830
|
path: construct._path,
|
|
720
831
|
method: construct.method,
|
|
721
|
-
handler: (0, node_path.relative)(
|
|
832
|
+
handler: (0, node_path.relative)(root, handlerFile).replace(/\.ts$/, ".handler"),
|
|
722
833
|
timeout: construct.timeout,
|
|
723
834
|
memorySize: construct.memorySize,
|
|
724
835
|
environment: await construct.getEnvironment({ markOptional: context.markOptional }),
|
|
@@ -730,38 +841,21 @@ var EndpointGenerator = class extends require_discover.ConstructGenerator {
|
|
|
730
841
|
}
|
|
731
842
|
return routes;
|
|
732
843
|
}
|
|
733
|
-
async generateHandlerFile(outputDir, sourceFile, exportName,
|
|
734
|
-
const
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
738
|
-
let content;
|
|
739
|
-
switch (provider) {
|
|
740
|
-
case "aws-apigatewayv1":
|
|
741
|
-
content = this.generateAWSApiGatewayV1Handler(importPath, exportName, context.storageDrivers);
|
|
742
|
-
break;
|
|
743
|
-
case "aws-apigatewayv2":
|
|
744
|
-
content = this.generateAWSApiGatewayV2Handler(importPath, exportName, context.storageDrivers);
|
|
745
|
-
break;
|
|
746
|
-
case "server":
|
|
747
|
-
content = this.generateServerHandler(importPath, exportName);
|
|
748
|
-
break;
|
|
749
|
-
default: throw new Error(`Unsupported provider: ${provider}`);
|
|
750
|
-
}
|
|
751
|
-
await (0, node_fs_promises.writeFile)(handlerPath, content);
|
|
844
|
+
async generateHandlerFile(outputDir, sourceFile, exportName, context) {
|
|
845
|
+
const handlerPath = (0, node_path.join)(outputDir, `${exportName}.ts`);
|
|
846
|
+
const importPath = (0, node_path.relative)((0, node_path.dirname)(handlerPath), sourceFile).replace(/\.ts$/, ".js");
|
|
847
|
+
await (0, node_fs_promises.writeFile)(handlerPath, this.generateAWSApiGatewayV2Handler(importPath, exportName, context.storageDrivers));
|
|
752
848
|
return handlerPath;
|
|
753
849
|
}
|
|
754
850
|
async generateEndpointsFile(outputDir, endpoints, context) {
|
|
755
|
-
const
|
|
756
|
-
const endpointsPath = (0, node_path.join)(outputDir, endpointsFileName);
|
|
851
|
+
const endpointsPath = (0, node_path.join)(outputDir, "endpoints.ts");
|
|
757
852
|
const importsByFile = /* @__PURE__ */ new Map();
|
|
758
853
|
for (const { path, key } of endpoints) {
|
|
759
|
-
const
|
|
760
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
854
|
+
const importPath = (0, node_path.relative)((0, node_path.dirname)(endpointsPath), path.relative).replace(/\.ts$/, ".js");
|
|
761
855
|
if (!importsByFile.has(importPath)) importsByFile.set(importPath, []);
|
|
762
856
|
importsByFile.get(importPath)?.push(key);
|
|
763
857
|
}
|
|
764
|
-
const endpointImports = Array.from(importsByFile.entries()).map(([importPath, exports
|
|
858
|
+
const endpointImports = Array.from(importsByFile.entries()).map(([importPath, exports]) => `import { ${exports.join(", ")} } from '${importPath}';`).join("\n");
|
|
765
859
|
const allExportNames = endpoints.map(({ key }) => key);
|
|
766
860
|
if (context.production?.enabled && context.production.optimizedHandlers) return this.generateOptimizedEndpointsFile(endpointsPath, endpoints, endpointImports, allExportNames);
|
|
767
861
|
const content = `import type { EnvironmentParser } from '@geekmidas/envkit';
|
|
@@ -772,7 +866,7 @@ import { ServiceDiscovery } from '@geekmidas/services';
|
|
|
772
866
|
import type { Hono } from 'hono';
|
|
773
867
|
${endpointImports}
|
|
774
868
|
|
|
775
|
-
export const endpoints: Endpoint<any, any, any, any, any, any, any, any, any, any, any, any
|
|
869
|
+
export const endpoints: Endpoint<any, any, any, any, any, any, any, any, any, any, any, any>[] = [
|
|
776
870
|
${allExportNames.join(",\n ")}
|
|
777
871
|
];
|
|
778
872
|
|
|
@@ -823,11 +917,9 @@ export async function setupEndpoints(
|
|
|
823
917
|
const analyses = endpoints.map(({ key, construct }) => analyzeEndpoint(construct, key));
|
|
824
918
|
const endpointImports = endpoints.map(({ key, path }) => {
|
|
825
919
|
const tierDir = (0, node_path.join)(endpointsDir, "standard");
|
|
826
|
-
const relativePath = (0, node_path.relative)(tierDir, path.relative);
|
|
827
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
828
920
|
return {
|
|
829
921
|
exportName: key,
|
|
830
|
-
importPath
|
|
922
|
+
importPath: (0, node_path.relative)(tierDir, path.relative).replace(/\.ts$/, ".js")
|
|
831
923
|
};
|
|
832
924
|
});
|
|
833
925
|
const summary = summarizeAnalysis(analyses);
|
|
@@ -849,43 +941,33 @@ export async function setupEndpoints(
|
|
|
849
941
|
}
|
|
850
942
|
async generateAppFile(outputDir, context) {
|
|
851
943
|
if (context.production?.enabled) return this.generateProductionAppFile(outputDir, context);
|
|
852
|
-
const
|
|
853
|
-
const appPath = (0, node_path.join)(outputDir, appFileName);
|
|
944
|
+
const appPath = (0, node_path.join)(outputDir, "app.ts");
|
|
854
945
|
const runtime = runtimeFor(context, (0, node_path.dirname)(appPath));
|
|
855
946
|
const telescopeEnabled = context.telescope?.enabled;
|
|
856
947
|
const telescopeWebSocketEnabled = context.telescope?.websocket;
|
|
857
948
|
const usesExternalTelescope = !!context.telescope?.telescopePath;
|
|
858
|
-
const studioEnabled = context.studio?.enabled;
|
|
859
|
-
const usesExternalStudio = !!context.studio?.studioPath;
|
|
860
|
-
const studioFromDatabase = !usesExternalStudio && !!context.studio?.database;
|
|
861
949
|
const telescopeFromSurface = !!context.surface?.module && !usesExternalTelescope;
|
|
862
950
|
let telescopeImports = "";
|
|
863
|
-
if (telescopeEnabled)
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
import {
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
import {
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
studioImports = `import { snifferContext } from '@geekmidas/constructs';
|
|
878
|
-
import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';
|
|
879
|
-
import { ${context.studio.database.exportName} as __studioDb } from '${dbSpecifier}';
|
|
880
|
-
import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
881
|
-
} else studioImports = "";
|
|
951
|
+
if (telescopeEnabled) {
|
|
952
|
+
if (telescopeFromSurface) telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
|
|
953
|
+
import { createApi, createMiddleware } from '@geekmidas/telescope/hono';`;
|
|
954
|
+
else if (usesExternalTelescope) {
|
|
955
|
+
const relativeTelescopePath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.telescope?.telescopePath);
|
|
956
|
+
telescopeImports = `import ${context.telescope?.telescopeImportPattern} from '${relativeTelescopePath}';
|
|
957
|
+
import { createApi, createMiddleware } from '@geekmidas/telescope/hono';`;
|
|
958
|
+
} else telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
|
|
959
|
+
import { createApi, createMiddleware } from '@geekmidas/telescope/hono';`;
|
|
960
|
+
}
|
|
961
|
+
const databaseApi = context.databaseApi;
|
|
962
|
+
const databaseApiImports = databaseApi ? `import { snifferContext } from '@geekmidas/constructs';
|
|
963
|
+
import { createIntrospectionHandler } from '@geekmidas/db/introspect';
|
|
964
|
+
import { ${databaseApi.database.exportName} as __introspectedDb } from '${importSpecifier((0, node_path.dirname)(appPath), databaseApi.database.specifier)}';` : "";
|
|
882
965
|
const cors = corsFor(context.surface);
|
|
883
966
|
let hooksImports = "";
|
|
884
967
|
let beforeSetupCall = "";
|
|
885
968
|
let afterSetupCall = "";
|
|
886
969
|
if (context.hooks?.serverHooksPath) {
|
|
887
|
-
|
|
888
|
-
hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
|
|
970
|
+
hooksImports = `import * as serverHooks from '${(0, node_path.relative)((0, node_path.dirname)(appPath), context.hooks.serverHooksPath)}';`;
|
|
889
971
|
beforeSetupCall = `
|
|
890
972
|
// Call beforeSetup hook if defined
|
|
891
973
|
if (typeof serverHooks.beforeSetup === 'function') {
|
|
@@ -931,16 +1013,17 @@ import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
|
931
1013
|
}
|
|
932
1014
|
` : "";
|
|
933
1015
|
let telescopeSetup = "";
|
|
934
|
-
if (telescopeEnabled)
|
|
1016
|
+
if (telescopeEnabled) {
|
|
1017
|
+
if (telescopeFromSurface || usesExternalTelescope) telescopeSetup = `
|
|
935
1018
|
${telescopeWebSocketSetupCode}
|
|
936
1019
|
// Add telescope middleware (before endpoints to capture all requests)
|
|
937
1020
|
honoApp.use('*', createMiddleware(telescope));
|
|
938
1021
|
|
|
939
|
-
// Mount
|
|
940
|
-
const
|
|
941
|
-
honoApp.route('${context.telescope?.path}',
|
|
1022
|
+
// Mount Telescope's JSON API
|
|
1023
|
+
const telescopeApi = createApi(telescope);
|
|
1024
|
+
honoApp.route('${context.telescope?.path}', telescopeApi);
|
|
942
1025
|
`;
|
|
943
|
-
|
|
1026
|
+
else telescopeSetup = `
|
|
944
1027
|
// Setup Telescope for debugging/monitoring
|
|
945
1028
|
const telescopeStorage = new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} });
|
|
946
1029
|
const telescope = new Telescope({
|
|
@@ -954,31 +1037,21 @@ ${telescopeWebSocketSetupCode}
|
|
|
954
1037
|
// Add telescope middleware (before endpoints to capture all requests)
|
|
955
1038
|
honoApp.use('*', createMiddleware(telescope));
|
|
956
1039
|
|
|
957
|
-
// Mount
|
|
958
|
-
const
|
|
959
|
-
honoApp.route('${context.telescope?.path}',
|
|
1040
|
+
// Mount Telescope's JSON API
|
|
1041
|
+
const telescopeApi = createApi(telescope);
|
|
1042
|
+
honoApp.route('${context.telescope?.path}', telescopeApi);
|
|
960
1043
|
`;
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
//
|
|
964
|
-
//
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
cursor: { field: 'id', direction: Direction.Desc },
|
|
970
|
-
},
|
|
971
|
-
enabled: true,
|
|
1044
|
+
}
|
|
1045
|
+
const databaseApiSetup = databaseApi ? `
|
|
1046
|
+
// The database's structure and rows as JSON, read-only, for whatever tool
|
|
1047
|
+
// the developer points at it. Dev only: it answers anyone who can reach the
|
|
1048
|
+
// port.
|
|
1049
|
+
const databaseApi = createIntrospectionHandler({
|
|
1050
|
+
db: await __introspectedDb.service.register({ envParser, context: snifferContext }),
|
|
1051
|
+
basePath: '${databaseApi.path}',
|
|
972
1052
|
});
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
honoApp.route('${context.studio?.path}', studioApp);
|
|
976
|
-
`;
|
|
977
|
-
else if (studioEnabled && usesExternalStudio) studioSetup = `
|
|
978
|
-
// Mount Studio data browser UI
|
|
979
|
-
const studioApp = createStudioApp(studio);
|
|
980
|
-
honoApp.route('${context.studio?.path}', studioApp);
|
|
981
|
-
`;
|
|
1053
|
+
honoApp.all('${databaseApi.path}/*', (c) => databaseApi(c.req.raw));
|
|
1054
|
+
` : "";
|
|
982
1055
|
const content = `/**
|
|
983
1056
|
* Generated server application
|
|
984
1057
|
*
|
|
@@ -994,24 +1067,37 @@ import { setupQueues } from './queues.js';
|
|
|
994
1067
|
import { setupCrons } from './crons.js';
|
|
995
1068
|
${runtime.imports}
|
|
996
1069
|
${telescopeImports}
|
|
997
|
-
${
|
|
1070
|
+
${databaseApiImports}
|
|
998
1071
|
${hooksImports}
|
|
999
1072
|
${cors.imports}
|
|
1000
1073
|
${context.storageDrivers?.imports ?? ""}
|
|
1001
1074
|
|
|
1002
1075
|
${runtime.bindings}
|
|
1003
|
-
${telescopeFromSurface ?
|
|
1076
|
+
${telescopeEnabled && telescopeFromSurface ? `// The surface's own Telescope, or the one \`telescope\` config describes.
|
|
1077
|
+
const telescope =
|
|
1078
|
+
__surface.telescope ??
|
|
1079
|
+
new Telescope({
|
|
1080
|
+
enabled: true,
|
|
1081
|
+
path: '${context.telescope?.path}',
|
|
1082
|
+
ignorePatterns: ${JSON.stringify(context.telescope?.ignore)},
|
|
1083
|
+
recordBody: ${context.telescope?.recordBody},
|
|
1084
|
+
storage: new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} }),
|
|
1085
|
+
});` : ""}
|
|
1004
1086
|
|
|
1005
1087
|
${context.storageDrivers?.setup ? `// Which storage drivers exist is the entry point's decision: the scheme in
|
|
1006
1088
|
// each injected URL picks one, so no construct and no application module names
|
|
1007
1089
|
// a provider.
|
|
1008
1090
|
${context.storageDrivers.setup}
|
|
1009
1091
|
` : ""}
|
|
1010
|
-
|
|
1092
|
+
${context.surface ? `// Who this server is to Postgres: application_name on every connection.
|
|
1093
|
+
process.env.GKM_APP_NAME ??= ${JSON.stringify(context.surface.id)};
|
|
1094
|
+
|
|
1095
|
+
` : ""}export interface ServerApp {
|
|
1011
1096
|
app: HonoType;
|
|
1012
1097
|
start: (options?: {
|
|
1013
1098
|
port?: number;
|
|
1014
|
-
|
|
1099
|
+
/** Returns the server, so a shutdown can stop it taking requests. */
|
|
1100
|
+
serve: (app: HonoType, port: number) => unknown;
|
|
1015
1101
|
}) => Promise<void>;
|
|
1016
1102
|
}
|
|
1017
1103
|
|
|
@@ -1051,7 +1137,7 @@ export interface ServerApp {
|
|
|
1051
1137
|
*/
|
|
1052
1138
|
export async function createApp(app?: HonoType, enableOpenApi: boolean = true): Promise<ServerApp> {
|
|
1053
1139
|
const honoApp = app || new Hono();
|
|
1054
|
-
${telescopeSetup}${cors.setup}${beforeSetupCall}${
|
|
1140
|
+
${telescopeSetup}${cors.setup}${beforeSetupCall}${databaseApiSetup}
|
|
1055
1141
|
// Setup HTTP endpoints
|
|
1056
1142
|
await setupEndpoints(honoApp, envParser, logger, enableOpenApi);
|
|
1057
1143
|
${afterSetupCall}
|
|
@@ -1069,9 +1155,11 @@ ${afterSetupCall}
|
|
|
1069
1155
|
|
|
1070
1156
|
const port = options.port ?? 3000;
|
|
1071
1157
|
|
|
1072
|
-
//
|
|
1073
|
-
|
|
1158
|
+
// Mount pushed subscribers' routes and start polled ones. What comes
|
|
1159
|
+
// back subscribes the routes, once the server can answer them.
|
|
1160
|
+
const subscribeForPush = await setupSubscribers(honoApp, envParser, logger).catch((error) => {
|
|
1074
1161
|
logger.error({ error }, 'Failed to start subscribers');
|
|
1162
|
+
return async (_port: number) => {};
|
|
1075
1163
|
});
|
|
1076
1164
|
|
|
1077
1165
|
// Start queue workers in background (non-blocking, local development only)
|
|
@@ -1091,6 +1179,8 @@ ${afterSetupCall}
|
|
|
1091
1179
|
await options.serve(honoApp, port);
|
|
1092
1180
|
|
|
1093
1181
|
logger.info({ port }, 'Server started');
|
|
1182
|
+
|
|
1183
|
+
await subscribeForPush(port);
|
|
1094
1184
|
}
|
|
1095
1185
|
};
|
|
1096
1186
|
}
|
|
@@ -1111,26 +1201,6 @@ export default createApp;
|
|
|
1111
1201
|
* object. Nothing has to be printed now, which is also why nothing has to be
|
|
1112
1202
|
* named in config.
|
|
1113
1203
|
*/
|
|
1114
|
-
generateAWSApiGatewayV1Handler(importPath, exportName, drivers) {
|
|
1115
|
-
return `import { AmazonApiGatewayV1Endpoint } from '@geekmidas/constructs/aws';
|
|
1116
|
-
import { ${exportName} } from '${importPath}';
|
|
1117
|
-
${drivers?.imports ?? ""}
|
|
1118
|
-
${drivers?.setup ? `\n// The handler registers the drivers its target needs.\n${drivers.setup}\n` : ""}
|
|
1119
|
-
const adapter = new AmazonApiGatewayV1Endpoint(${exportName});
|
|
1120
|
-
|
|
1121
|
-
export const handler = adapter.handler;
|
|
1122
|
-
`;
|
|
1123
|
-
}
|
|
1124
|
-
/**
|
|
1125
|
-
* One Lambda, one endpoint — and no environment import.
|
|
1126
|
-
*
|
|
1127
|
-
* The endpoint was built from its surface, so it carries the parser the
|
|
1128
|
-
* adaptor needs. This used to read
|
|
1129
|
-
* `import { envParser } from '../../config/env'`, a line the build wrote
|
|
1130
|
-
* because a generator can print a module specifier and cannot print an
|
|
1131
|
-
* object. Nothing has to be printed now, which is also why nothing has to be
|
|
1132
|
-
* named in config.
|
|
1133
|
-
*/
|
|
1134
1204
|
generateAWSApiGatewayV2Handler(importPath, exportName, drivers) {
|
|
1135
1205
|
return `import { AmazonApiGatewayV2Endpoint } from '@geekmidas/constructs/aws';
|
|
1136
1206
|
import { ${exportName} } from '${importPath}';
|
|
@@ -1139,13 +1209,6 @@ ${drivers?.setup ? `\n// The handler registers the drivers its target needs.\n${
|
|
|
1139
1209
|
const adapter = new AmazonApiGatewayV2Endpoint(${exportName});
|
|
1140
1210
|
|
|
1141
1211
|
export const handler = adapter.handler;
|
|
1142
|
-
`;
|
|
1143
|
-
}
|
|
1144
|
-
generateServerHandler(importPath, exportName) {
|
|
1145
|
-
return `import { ${exportName} } from '${importPath}';
|
|
1146
|
-
|
|
1147
|
-
// Server handler - implement based on your server framework
|
|
1148
|
-
export const handler = ${exportName};
|
|
1149
1212
|
`;
|
|
1150
1213
|
}
|
|
1151
1214
|
/**
|
|
@@ -1153,8 +1216,7 @@ export const handler = ${exportName};
|
|
|
1153
1216
|
* No dev tools (Telescope, Studio, WebSocket), includes health checks and graceful shutdown
|
|
1154
1217
|
*/
|
|
1155
1218
|
async generateProductionAppFile(outputDir, context) {
|
|
1156
|
-
const
|
|
1157
|
-
const appPath = (0, node_path.join)(outputDir, appFileName);
|
|
1219
|
+
const appPath = (0, node_path.join)(outputDir, "app.ts");
|
|
1158
1220
|
const runtime = runtimeFor(context, (0, node_path.dirname)(appPath));
|
|
1159
1221
|
const production = context.production;
|
|
1160
1222
|
const healthCheckPath = production.healthCheck;
|
|
@@ -1166,8 +1228,7 @@ export const handler = ${exportName};
|
|
|
1166
1228
|
let beforeSetupCall = "";
|
|
1167
1229
|
let afterSetupCall = "";
|
|
1168
1230
|
if (context.hooks?.serverHooksPath) {
|
|
1169
|
-
|
|
1170
|
-
hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
|
|
1231
|
+
hooksImports = `import * as serverHooks from '${(0, node_path.relative)((0, node_path.dirname)(appPath), context.hooks.serverHooksPath)}';`;
|
|
1171
1232
|
beforeSetupCall = `
|
|
1172
1233
|
// Call beforeSetup hook if defined
|
|
1173
1234
|
if (typeof serverHooks.beforeSetup === 'function') {
|
|
@@ -1182,9 +1243,11 @@ export const handler = ${exportName};
|
|
|
1182
1243
|
`;
|
|
1183
1244
|
}
|
|
1184
1245
|
const subscriberSetup = includeSubscribers ? `
|
|
1185
|
-
//
|
|
1186
|
-
|
|
1246
|
+
// Mount pushed subscribers' routes and start polled ones. What comes
|
|
1247
|
+
// back subscribes the routes, once the server can answer them.
|
|
1248
|
+
const subscribeForPush = await setupSubscribers(honoApp, envParser, logger).catch((error) => {
|
|
1187
1249
|
logger.error({ error }, 'Failed to start subscribers');
|
|
1250
|
+
return async (_port: number) => {};
|
|
1188
1251
|
});
|
|
1189
1252
|
|
|
1190
1253
|
// Start queue workers in background
|
|
@@ -1202,15 +1265,29 @@ export const handler = ${exportName};
|
|
|
1202
1265
|
import { setupQueues } from './queues.js';
|
|
1203
1266
|
import { setupCrons } from './crons.js';` : "";
|
|
1204
1267
|
const gracefulShutdownCode = enableGracefulShutdown ? `
|
|
1205
|
-
// Graceful shutdown
|
|
1268
|
+
// Graceful shutdown: stop taking requests, let in-flight ones finish, then
|
|
1269
|
+
// close what constructs opened (database pools) — so a rolling deploy does
|
|
1270
|
+
// not leave the old task holding connections. Bounded by
|
|
1271
|
+
// GKM_SHUTDOWN_TIMEOUT_MS, 8s by default: under Docker's 10s stop timeout,
|
|
1272
|
+
// so the process exits on its own terms rather than being killed mid-drain.
|
|
1206
1273
|
let isShuttingDown = false;
|
|
1207
1274
|
|
|
1208
1275
|
const shutdown = async () => {
|
|
1209
1276
|
if (isShuttingDown) return;
|
|
1210
1277
|
isShuttingDown = true;
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
setTimeout(() =>
|
|
1278
|
+
const deadline = Number(process.env.GKM_SHUTDOWN_TIMEOUT_MS) || 8000;
|
|
1279
|
+
logger.info({ deadline }, 'Graceful shutdown initiated');
|
|
1280
|
+
setTimeout(() => {
|
|
1281
|
+
logger.warn({ deadline }, 'Shutdown deadline reached, exiting');
|
|
1282
|
+
process.exit(1);
|
|
1283
|
+
}, deadline).unref();
|
|
1284
|
+
await new Promise<void>((resolve) => {
|
|
1285
|
+
const close = (server as { close?: (done: () => void) => void } | undefined)?.close;
|
|
1286
|
+
if (typeof close === 'function') close.call(server, () => resolve());
|
|
1287
|
+
else resolve();
|
|
1288
|
+
});
|
|
1289
|
+
await runShutdownHooks((error) => logger.error({ error }, 'Shutdown hook failed'));
|
|
1290
|
+
process.exit(0);
|
|
1214
1291
|
};
|
|
1215
1292
|
|
|
1216
1293
|
process.on('SIGTERM', shutdown);
|
|
@@ -1228,7 +1305,7 @@ import { setupCrons } from './crons.js';` : "";
|
|
|
1228
1305
|
*/
|
|
1229
1306
|
import { Hono } from 'hono';
|
|
1230
1307
|
import type { Hono as HonoType } from 'hono';
|
|
1231
|
-
import { setupEndpoints } from '${endpointsImportPath}';
|
|
1308
|
+
${enableGracefulShutdown ? "import { runShutdownHooks } from '@geekmidas/constructs';\n" : ""}import { setupEndpoints } from '${endpointsImportPath}';
|
|
1232
1309
|
${subscriberImport}
|
|
1233
1310
|
${runtime.imports}
|
|
1234
1311
|
${runtime.bindings}
|
|
@@ -1239,7 +1316,10 @@ ${context.storageDrivers?.imports ?? ""}
|
|
|
1239
1316
|
${context.storageDrivers?.setup ? `// The entry point registers the drivers its target needs.
|
|
1240
1317
|
${context.storageDrivers.setup}
|
|
1241
1318
|
` : ""}
|
|
1242
|
-
|
|
1319
|
+
${context.surface ? `// Who this server is to Postgres: application_name on every connection.
|
|
1320
|
+
process.env.GKM_APP_NAME ??= ${JSON.stringify(context.surface.id)};
|
|
1321
|
+
|
|
1322
|
+
` : ""}export interface ServerApp {
|
|
1243
1323
|
app: HonoType;
|
|
1244
1324
|
start: (options?: {
|
|
1245
1325
|
port?: number;
|
|
@@ -1272,13 +1352,15 @@ ${afterSetupCall}
|
|
|
1272
1352
|
}
|
|
1273
1353
|
|
|
1274
1354
|
const port = options.port ?? Number(process.env.PORT) ?? 3000;
|
|
1355
|
+
let server: unknown;
|
|
1275
1356
|
${gracefulShutdownCode}${subscriberSetup}
|
|
1276
1357
|
logger.info({ port }, 'Starting production server');
|
|
1277
1358
|
|
|
1278
1359
|
// Start HTTP server using provided serve function
|
|
1279
|
-
await options.serve(honoApp, port);
|
|
1360
|
+
server = await options.serve(honoApp, port);
|
|
1280
1361
|
|
|
1281
1362
|
logger.info({ port }, 'Production server started');
|
|
1363
|
+
${includeSubscribers ? "\n await subscribeForPush(port);" : ""}
|
|
1282
1364
|
}
|
|
1283
1365
|
};
|
|
1284
1366
|
}
|
|
@@ -1287,21 +1369,27 @@ ${gracefulShutdownCode}${subscriberSetup}
|
|
|
1287
1369
|
export default createApp;
|
|
1288
1370
|
`;
|
|
1289
1371
|
await (0, node_fs_promises.writeFile)(appPath, content);
|
|
1290
|
-
await this.generateProductionServerEntry(outputDir);
|
|
1372
|
+
await this.generateProductionServerEntry(outputDir, context);
|
|
1291
1373
|
return appPath;
|
|
1292
1374
|
}
|
|
1293
1375
|
/**
|
|
1294
1376
|
* Generate production server.ts entry point
|
|
1295
1377
|
*/
|
|
1296
|
-
async generateProductionServerEntry(outputDir) {
|
|
1378
|
+
async generateProductionServerEntry(outputDir, context) {
|
|
1297
1379
|
const serverPath = (0, node_path.join)(outputDir, "server.ts");
|
|
1298
|
-
|
|
1380
|
+
await (0, node_fs_promises.writeFile)((0, node_path.join)(outputDir, "telemetry.ts"), generateTelemetryModule(context.telemetry));
|
|
1381
|
+
await (0, node_fs_promises.writeFile)(serverPath, `#!/usr/bin/env node
|
|
1299
1382
|
/**
|
|
1300
1383
|
* Production server entry point
|
|
1301
|
-
* Generated by 'gkm build --
|
|
1384
|
+
* Generated by 'gkm build --production'
|
|
1302
1385
|
*/
|
|
1303
1386
|
import { serve } from '@hono/node-server';
|
|
1304
|
-
import {
|
|
1387
|
+
import { startTelemetry } from './telemetry.js';
|
|
1388
|
+
|
|
1389
|
+
// Before the app is imported, so the libraries it loads are instrumented.
|
|
1390
|
+
await startTelemetry();
|
|
1391
|
+
|
|
1392
|
+
const { createApp } = await import('./app.js');
|
|
1305
1393
|
|
|
1306
1394
|
const port = Number(process.env.PORT) || 3000;
|
|
1307
1395
|
|
|
@@ -1309,13 +1397,11 @@ const { start } = await createApp();
|
|
|
1309
1397
|
|
|
1310
1398
|
await start({
|
|
1311
1399
|
port,
|
|
1312
|
-
serve: (app, port) =>
|
|
1400
|
+
serve: (app, port) => serve({ fetch: app.fetch, port }),
|
|
1313
1401
|
});
|
|
1314
|
-
|
|
1315
|
-
await (0, node_fs_promises.writeFile)(serverPath, content);
|
|
1402
|
+
`);
|
|
1316
1403
|
}
|
|
1317
1404
|
};
|
|
1318
|
-
|
|
1319
1405
|
//#endregion
|
|
1320
1406
|
//#region src/generators/OpenApiTsGenerator.ts
|
|
1321
1407
|
/**
|
|
@@ -1466,11 +1552,11 @@ var OpenApiTsGenerator = class {
|
|
|
1466
1552
|
}
|
|
1467
1553
|
}
|
|
1468
1554
|
}
|
|
1469
|
-
const registrySchemas = await (0,
|
|
1555
|
+
const registrySchemas = await (0, _geekmidas_schema_conversion.getRegisteredZodJsonSchemas)();
|
|
1470
1556
|
for (const [rawName, rawSchema] of Object.entries(registrySchemas)) {
|
|
1471
1557
|
const defName = this.pascalCase(rawName);
|
|
1472
1558
|
if (collectedDefs.has(defName) || generatedNames.has(defName)) continue;
|
|
1473
|
-
const { id: _id, $defs: _defs
|
|
1559
|
+
const { id: _id, $defs: _defs, ...rest } = rawSchema;
|
|
1474
1560
|
collectedDefs.set(defName, rest);
|
|
1475
1561
|
}
|
|
1476
1562
|
for (const [defName, defSchema] of collectedDefs) if (!generatedNames.has(defName)) {
|
|
@@ -1486,7 +1572,7 @@ var OpenApiTsGenerator = class {
|
|
|
1486
1572
|
*/
|
|
1487
1573
|
async getSchemaName(schema, defaultName) {
|
|
1488
1574
|
try {
|
|
1489
|
-
const metadata = await (0,
|
|
1575
|
+
const metadata = await (0, _geekmidas_schema_conversion.getSchemaMetadata)(schema);
|
|
1490
1576
|
if (metadata?.id) return this.pascalCase(metadata.id);
|
|
1491
1577
|
} catch {}
|
|
1492
1578
|
return defaultName;
|
|
@@ -1506,17 +1592,17 @@ var OpenApiTsGenerator = class {
|
|
|
1506
1592
|
async schemaToInterfaceWithDefs(schema, name, collectedDefs) {
|
|
1507
1593
|
try {
|
|
1508
1594
|
const vendor = schema["~standard"]?.vendor;
|
|
1509
|
-
if (!vendor || !(vendor in
|
|
1510
|
-
const toJsonSchema =
|
|
1595
|
+
if (!vendor || !(vendor in _geekmidas_schema_conversion.StandardSchemaJsonSchema)) return unknownType(name);
|
|
1596
|
+
const toJsonSchema = _geekmidas_schema_conversion.StandardSchemaJsonSchema[vendor];
|
|
1511
1597
|
const jsonSchema = await toJsonSchema(schema);
|
|
1512
|
-
if (!jsonSchema) return
|
|
1598
|
+
if (!jsonSchema) return unknownType(name);
|
|
1513
1599
|
if (jsonSchema.$defs && typeof jsonSchema.$defs === "object") {
|
|
1514
1600
|
for (const [defName, defSchema] of Object.entries(jsonSchema.$defs)) if (!collectedDefs.has(defName)) {
|
|
1515
|
-
const { id
|
|
1601
|
+
const { id, ...schemaWithoutId } = defSchema;
|
|
1516
1602
|
collectedDefs.set(defName, schemaWithoutId);
|
|
1517
1603
|
}
|
|
1518
1604
|
}
|
|
1519
|
-
const { $defs
|
|
1605
|
+
const { $defs, ...schemaWithoutDefs } = jsonSchema;
|
|
1520
1606
|
const ref = schemaWithoutDefs.$ref;
|
|
1521
1607
|
if (ref && Object.keys(schemaWithoutDefs).every((k) => k === "$ref" || k === "$schema")) {
|
|
1522
1608
|
const target = ref.split("/").pop();
|
|
@@ -1524,14 +1610,11 @@ var OpenApiTsGenerator = class {
|
|
|
1524
1610
|
}
|
|
1525
1611
|
return this.jsonSchemaToInterface(schemaWithoutDefs, name);
|
|
1526
1612
|
} catch {
|
|
1527
|
-
return
|
|
1613
|
+
return unknownType(name);
|
|
1528
1614
|
}
|
|
1529
1615
|
}
|
|
1530
1616
|
jsonSchemaToInterface(schema, name) {
|
|
1531
|
-
if (schema.type !== "object" || !schema.properties) {
|
|
1532
|
-
const typeStr = this.jsonSchemaTypeToTs(schema);
|
|
1533
|
-
return `export type ${name} = ${typeStr};`;
|
|
1534
|
-
}
|
|
1617
|
+
if (schema.type !== "object" || !schema.properties) return `export type ${name} = ${this.jsonSchemaTypeToTs(schema)};`;
|
|
1535
1618
|
const props = [];
|
|
1536
1619
|
const required = new Set(schema.required || []);
|
|
1537
1620
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
@@ -1544,13 +1627,15 @@ var OpenApiTsGenerator = class {
|
|
|
1544
1627
|
}
|
|
1545
1628
|
jsonSchemaTypeToTs(schema) {
|
|
1546
1629
|
if (!schema) return "unknown";
|
|
1547
|
-
if (schema.$ref)
|
|
1548
|
-
|
|
1549
|
-
return refName;
|
|
1550
|
-
}
|
|
1630
|
+
if (schema.$ref) return schema.$ref.split("/").pop() || "unknown";
|
|
1631
|
+
if (schema.const !== void 0) return typeof schema.const === "string" ? `'${schema.const}'` : String(schema.const);
|
|
1551
1632
|
if (schema.anyOf) return schema.anyOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
|
|
1552
1633
|
if (schema.oneOf) return schema.oneOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
|
|
1553
1634
|
if (schema.allOf) return schema.allOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" & ");
|
|
1635
|
+
if (Array.isArray(schema.type)) return schema.type.map((type) => this.jsonSchemaTypeToTs({
|
|
1636
|
+
...schema,
|
|
1637
|
+
type
|
|
1638
|
+
})).join(" | ");
|
|
1554
1639
|
switch (schema.type) {
|
|
1555
1640
|
case "string":
|
|
1556
1641
|
if (schema.enum) return schema.enum.map((e) => `'${e}'`).join(" | ");
|
|
@@ -1574,10 +1659,7 @@ var OpenApiTsGenerator = class {
|
|
|
1574
1659
|
}
|
|
1575
1660
|
return `{ ${props.join("; ")} }`;
|
|
1576
1661
|
}
|
|
1577
|
-
if (schema.additionalProperties) {
|
|
1578
|
-
const valueType = this.jsonSchemaTypeToTs(schema.additionalProperties);
|
|
1579
|
-
return `Record<string, ${valueType}>`;
|
|
1580
|
-
}
|
|
1662
|
+
if (schema.additionalProperties) return `Record<string, ${this.jsonSchemaTypeToTs(schema.additionalProperties)}>`;
|
|
1581
1663
|
return "Record<string, unknown>";
|
|
1582
1664
|
default: return "unknown";
|
|
1583
1665
|
}
|
|
@@ -1598,10 +1680,7 @@ var OpenApiTsGenerator = class {
|
|
|
1598
1680
|
}
|
|
1599
1681
|
const firstWithParams = infos.find((i) => i.input?.params);
|
|
1600
1682
|
let paramsEntry = "";
|
|
1601
|
-
if (firstWithParams?.input?.params) {
|
|
1602
|
-
const paramsName = await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`);
|
|
1603
|
-
paramsEntry = `\n parameters: {\n path: ${paramsName};\n };`;
|
|
1604
|
-
}
|
|
1683
|
+
if (firstWithParams?.input?.params) paramsEntry = `\n parameters: {\n path: ${await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`)};\n };`;
|
|
1605
1684
|
pathEntries.push(` '${route}': {${paramsEntry}\n${methodEntries.join("\n")}\n };`);
|
|
1606
1685
|
}
|
|
1607
1686
|
return `export interface paths {\n${pathEntries.join("\n")}\n}`;
|
|
@@ -1640,8 +1719,7 @@ var OpenApiTsGenerator = class {
|
|
|
1640
1719
|
return acc;
|
|
1641
1720
|
}, {});
|
|
1642
1721
|
const schemeNames = securitySchemes.map((s) => `'${s.name}'`).join(" | ");
|
|
1643
|
-
const
|
|
1644
|
-
const createApiSection = hasSecuritySchemes ? `
|
|
1722
|
+
const createApiSection = schemeNames.length > 0 ? `
|
|
1645
1723
|
// ============================================================
|
|
1646
1724
|
// API Client Factory
|
|
1647
1725
|
// ============================================================
|
|
@@ -1665,6 +1743,8 @@ export interface CreateApiOptions {
|
|
|
1665
1743
|
queryClient?: QueryClient;
|
|
1666
1744
|
/** Optional request interceptor */
|
|
1667
1745
|
onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
|
|
1746
|
+
/** The \`fetch\` requests go out on — a test browser's, for one */
|
|
1747
|
+
fetch?: typeof fetch;
|
|
1668
1748
|
}
|
|
1669
1749
|
|
|
1670
1750
|
/**
|
|
@@ -1694,6 +1774,7 @@ export function createApi(options: CreateApiOptions) {
|
|
|
1694
1774
|
securitySchemes,
|
|
1695
1775
|
authStrategies: options.authStrategies,
|
|
1696
1776
|
onRequest: options.onRequest,
|
|
1777
|
+
...(options.fetch ? { fetch: options.fetch } : {}),
|
|
1697
1778
|
});
|
|
1698
1779
|
|
|
1699
1780
|
const hooks = createEndpointHooks<paths>(fetcher, { queryClient: options.queryClient });
|
|
@@ -1818,258 +1899,38 @@ ${createApiSection}
|
|
|
1818
1899
|
`;
|
|
1819
1900
|
}
|
|
1820
1901
|
};
|
|
1821
|
-
|
|
1822
|
-
//#endregion
|
|
1823
|
-
//#region src/workspace/client-generator.ts
|
|
1824
1902
|
/**
|
|
1825
|
-
*
|
|
1826
|
-
*
|
|
1827
|
-
*
|
|
1903
|
+
* The declaration for a schema that cannot be converted — a vendor with no
|
|
1904
|
+
* converter, or one that fails. The paths interface names it either way, so
|
|
1905
|
+
* leaving it undeclared made the generated client fail to compile.
|
|
1828
1906
|
*/
|
|
1829
|
-
function
|
|
1830
|
-
|
|
1831
|
-
if (require_discover.isPartitionedRoutes(routes)) return Array.isArray(routes.paths) ? routes.paths : [routes.paths];
|
|
1832
|
-
return Array.isArray(routes) ? routes : [routes];
|
|
1907
|
+
function unknownType(name) {
|
|
1908
|
+
return `export type ${name} = unknown;`;
|
|
1833
1909
|
}
|
|
1834
|
-
|
|
1835
1910
|
//#endregion
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
const OPENAPI_OUTPUT_PATH = "./.gkm/openapi.ts";
|
|
1841
|
-
/**
|
|
1842
|
-
* Where a surface's generated client lands.
|
|
1843
|
-
*
|
|
1844
|
-
* Named from the surface, so `new RestApi('Webhooks')` writes
|
|
1845
|
-
* `.gkm/openapi/webhooks.ts` — the same kebab form that gives it its container
|
|
1846
|
-
* name and its `WEBHOOKS_URL`.
|
|
1847
|
-
*/
|
|
1848
|
-
function openApiPathFor(surfaceId) {
|
|
1849
|
-
return `./.gkm/openapi/${(0, __geekmidas_manifest.kebabCase)(surfaceId)}.ts`;
|
|
1850
|
-
}
|
|
1851
|
-
/**
|
|
1852
|
-
* Resolve OpenAPI config from GkmConfig
|
|
1853
|
-
*/
|
|
1854
|
-
function resolveOpenApiConfig(config) {
|
|
1855
|
-
if (config.openapi === false) return { enabled: false };
|
|
1856
|
-
if (config.openapi === true || config.openapi === void 0) return {
|
|
1857
|
-
enabled: true,
|
|
1858
|
-
title: "API Documentation",
|
|
1859
|
-
version: "1.0.0",
|
|
1860
|
-
description: "Auto-generated API documentation from endpoints"
|
|
1861
|
-
};
|
|
1862
|
-
return {
|
|
1863
|
-
enabled: config.openapi.enabled !== false,
|
|
1864
|
-
title: config.openapi.title || "API Documentation",
|
|
1865
|
-
version: config.openapi.version || "1.0.0",
|
|
1866
|
-
description: config.openapi.description || "Auto-generated API documentation from endpoints"
|
|
1867
|
-
};
|
|
1868
|
-
}
|
|
1869
|
-
/**
|
|
1870
|
-
* Load endpoints from a glob, then generate.
|
|
1871
|
-
*
|
|
1872
|
-
* For the callers that have no endpoints in hand — `gkm openapi`, and `gkm dev`
|
|
1873
|
-
* regenerating on reload. The glob is the app's derived one, off `AppSpec.code`,
|
|
1874
|
-
* not a `routes` field anybody wrote.
|
|
1875
|
-
*/
|
|
1876
|
-
async function generateOpenApiFrom(routes, options = {}) {
|
|
1877
|
-
const loaded = await new EndpointGenerator().load(routes, void 0, options.bustCache);
|
|
1878
|
-
return generateOpenApi(loaded.map(({ construct }) => construct), options);
|
|
1879
|
-
}
|
|
1880
|
-
/**
|
|
1881
|
-
* Generate an OpenAPI spec for each surface these endpoints name.
|
|
1882
|
-
*
|
|
1883
|
-
* Takes the endpoints, not a glob to find them with. The build has already
|
|
1884
|
-
* loaded every one of them to generate handlers, so globbing again was a second
|
|
1885
|
-
* discovery pass over the same files — and the reason this function needed a
|
|
1886
|
-
* `routes` to be told where to look, which is how a retired config field stayed
|
|
1887
|
-
* load-bearing.
|
|
1888
|
-
*
|
|
1889
|
-
* @returns What was written, or null if disabled or there were none
|
|
1890
|
-
*/
|
|
1891
|
-
async function generateOpenApi(endpoints, options = {}) {
|
|
1892
|
-
const logger = options.silent ? { log: () => {} } : console;
|
|
1893
|
-
const openApiConfig = resolveOpenApiConfig({ openapi: options.openapi });
|
|
1894
|
-
if (!openApiConfig.enabled) return null;
|
|
1895
|
-
if (endpoints.length === 0) {
|
|
1896
|
-
logger.log("No valid endpoints found for OpenAPI generation");
|
|
1897
|
-
return null;
|
|
1911
|
+
Object.defineProperty(exports, "EndpointGenerator", {
|
|
1912
|
+
enumerable: true,
|
|
1913
|
+
get: function() {
|
|
1914
|
+
return EndpointGenerator;
|
|
1898
1915
|
}
|
|
1899
|
-
const bySurface = /* @__PURE__ */ new Map();
|
|
1900
|
-
for (const endpoint of endpoints) {
|
|
1901
|
-
const owner = endpoint.owner ?? endpoint.surface?.id;
|
|
1902
|
-
if (!owner) continue;
|
|
1903
|
-
const existing = bySurface.get(owner);
|
|
1904
|
-
if (existing) existing.push(endpoint);
|
|
1905
|
-
else bySurface.set(owner, [endpoint]);
|
|
1906
|
-
}
|
|
1907
|
-
if (bySurface.size === 0) {
|
|
1908
|
-
logger.log("No endpoints named a surface, so no OpenAPI was generated");
|
|
1909
|
-
return null;
|
|
1910
|
-
}
|
|
1911
|
-
const tsGenerator = new OpenApiTsGenerator();
|
|
1912
|
-
const written = [];
|
|
1913
|
-
for (const [surfaceId, surfaceEndpoints] of bySurface) {
|
|
1914
|
-
const relative$1 = openApiPathFor(surfaceId);
|
|
1915
|
-
const outputPath = (0, node_path.join)(process.cwd(), relative$1);
|
|
1916
|
-
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(outputPath), { recursive: true });
|
|
1917
|
-
const tsContent = await tsGenerator.generate(surfaceEndpoints, {
|
|
1918
|
-
title: openApiConfig.title ?? surfaceId,
|
|
1919
|
-
version: openApiConfig.version,
|
|
1920
|
-
description: openApiConfig.description
|
|
1921
|
-
});
|
|
1922
|
-
await (0, node_fs_promises.writeFile)(outputPath, tsContent);
|
|
1923
|
-
written.push(relative$1);
|
|
1924
|
-
logger.log(`📄 OpenAPI client generated: ${relative$1} (${surfaceEndpoints.length} endpoints)`);
|
|
1925
|
-
}
|
|
1926
|
-
return {
|
|
1927
|
-
outputPath: (0, node_path.join)(process.cwd(), written[0]),
|
|
1928
|
-
outputPaths: written.map((r) => (0, node_path.join)(process.cwd(), r)),
|
|
1929
|
-
endpointCount: endpoints.length
|
|
1930
|
-
};
|
|
1931
|
-
}
|
|
1932
|
-
async function openapiCommand(options = {}) {
|
|
1933
|
-
const logger = console;
|
|
1934
|
-
try {
|
|
1935
|
-
const loadedConfig = await require_config.loadWorkspaceConfig(options.cwd);
|
|
1936
|
-
if (loadedConfig.type === "single") {
|
|
1937
|
-
const config = loadedConfig.raw;
|
|
1938
|
-
if (!config.openapi) config.openapi = { enabled: true };
|
|
1939
|
-
const result = await generateOpenApiFrom(config.constructs, { openapi: config.openapi });
|
|
1940
|
-
if (result) logger.log(`Found ${result.endpointCount} endpoints`);
|
|
1941
|
-
} else {
|
|
1942
|
-
const { workspace } = loadedConfig;
|
|
1943
|
-
const workspaceRoot = workspace.root;
|
|
1944
|
-
const backendApps = Object.entries(workspace.apps).filter(([_, app]) => app.type === "backend" && app.openapi !== false && (typeof app.openapi !== "object" || app.openapi.enabled !== false));
|
|
1945
|
-
if (backendApps.length === 0) {
|
|
1946
|
-
logger.log("No backend apps with OpenAPI enabled found");
|
|
1947
|
-
return;
|
|
1948
|
-
}
|
|
1949
|
-
if (options.app) {
|
|
1950
|
-
const entry = backendApps.find(([name]) => name === options.app);
|
|
1951
|
-
if (!entry) throw new Error(`App "${options.app}" not found or has OpenAPI disabled`);
|
|
1952
|
-
const [appName, app] = entry;
|
|
1953
|
-
const result = await generateOpenApiForApp(workspaceRoot, appName, app);
|
|
1954
|
-
if (result) logger.log(`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`);
|
|
1955
|
-
return;
|
|
1956
|
-
}
|
|
1957
|
-
for (const [appName, app] of backendApps) {
|
|
1958
|
-
const appPath = (0, node_path.join)(workspaceRoot, app.path);
|
|
1959
|
-
if ((0, node_path.resolve)(appPath) === (0, node_path.resolve)(workspaceRoot)) {
|
|
1960
|
-
const result = await generateOpenApiForApp(workspaceRoot, appName, app, false);
|
|
1961
|
-
if (result) logger.log(`Found ${result.endpointCount} endpoints`);
|
|
1962
|
-
continue;
|
|
1963
|
-
}
|
|
1964
|
-
await runOpenApiInSubprocess(appPath, appName);
|
|
1965
|
-
}
|
|
1966
|
-
}
|
|
1967
|
-
} catch (error) {
|
|
1968
|
-
throw new Error(`OpenAPI generation failed: ${error.message}`);
|
|
1969
|
-
}
|
|
1970
|
-
}
|
|
1971
|
-
/**
|
|
1972
|
-
* Generate OpenAPI for a single named app within a workspace.
|
|
1973
|
-
* Runs in-process. The caller is responsible for ensuring `process.cwd()`
|
|
1974
|
-
* is the app's directory so tsx loads the app's tsconfig path aliases.
|
|
1975
|
-
*/
|
|
1976
|
-
async function generateOpenApiForApp(workspaceRoot, _appName, app, silent = true) {
|
|
1977
|
-
if (app.type !== "backend") return null;
|
|
1978
|
-
const appPath = (0, node_path.join)(workspaceRoot, app.path);
|
|
1979
|
-
const globs = [(0, node_path.join)(appPath, "**/*.ts")];
|
|
1980
|
-
return generateOpenApiFrom(globs, {
|
|
1981
|
-
openapi: app.openapi ?? { enabled: true },
|
|
1982
|
-
silent
|
|
1983
|
-
});
|
|
1984
|
-
}
|
|
1985
|
-
/**
|
|
1986
|
-
* Resolve the gkm bin path. Tests can override via `GKM_BIN_PATH` env var
|
|
1987
|
-
* to avoid depending on the built dist.
|
|
1988
|
-
*/
|
|
1989
|
-
function resolveGkmBinPath() {
|
|
1990
|
-
if (process.env.GKM_BIN_PATH) return process.env.GKM_BIN_PATH;
|
|
1991
|
-
return (0, node_url.fileURLToPath)(new URL("../bin/gkm.mjs", require("url").pathToFileURL(__filename).href));
|
|
1992
|
-
}
|
|
1993
|
-
/**
|
|
1994
|
-
* Spawn a subprocess that runs `gkm openapi --app <name>` with `cwd` set to
|
|
1995
|
-
* the app's directory. Inherits `NODE_OPTIONS` (which already contains
|
|
1996
|
-
* `--import tsx`), so the child gets a fresh tsx instance whose tsconfig
|
|
1997
|
-
* discovery picks up the app's tsconfig path aliases.
|
|
1998
|
-
*/
|
|
1999
|
-
async function runOpenApiInSubprocess(appCwd, appName) {
|
|
2000
|
-
const binPath = resolveGkmBinPath();
|
|
2001
|
-
await new Promise((resolve$1, reject) => {
|
|
2002
|
-
const child = (0, node_child_process.spawn)(process.execPath, [
|
|
2003
|
-
binPath,
|
|
2004
|
-
"openapi",
|
|
2005
|
-
"--app",
|
|
2006
|
-
appName
|
|
2007
|
-
], {
|
|
2008
|
-
cwd: appCwd,
|
|
2009
|
-
stdio: "inherit",
|
|
2010
|
-
env: process.env
|
|
2011
|
-
});
|
|
2012
|
-
child.on("error", reject);
|
|
2013
|
-
child.on("close", (code) => {
|
|
2014
|
-
if (code === 0) resolve$1();
|
|
2015
|
-
else reject(new Error(`OpenAPI generation for app "${appName}" exited with code ${code}`));
|
|
2016
|
-
});
|
|
2017
|
-
});
|
|
2018
|
-
}
|
|
2019
|
-
|
|
2020
|
-
//#endregion
|
|
2021
|
-
Object.defineProperty(exports, 'EndpointGenerator', {
|
|
2022
|
-
enumerable: true,
|
|
2023
|
-
get: function () {
|
|
2024
|
-
return EndpointGenerator;
|
|
2025
|
-
}
|
|
2026
|
-
});
|
|
2027
|
-
Object.defineProperty(exports, 'OPENAPI_OUTPUT_PATH', {
|
|
2028
|
-
enumerable: true,
|
|
2029
|
-
get: function () {
|
|
2030
|
-
return OPENAPI_OUTPUT_PATH;
|
|
2031
|
-
}
|
|
2032
|
-
});
|
|
2033
|
-
Object.defineProperty(exports, 'generateOpenApi', {
|
|
2034
|
-
enumerable: true,
|
|
2035
|
-
get: function () {
|
|
2036
|
-
return generateOpenApi;
|
|
2037
|
-
}
|
|
2038
|
-
});
|
|
2039
|
-
Object.defineProperty(exports, 'generateOpenApiFrom', {
|
|
2040
|
-
enumerable: true,
|
|
2041
|
-
get: function () {
|
|
2042
|
-
return generateOpenApiFrom;
|
|
2043
|
-
}
|
|
2044
|
-
});
|
|
2045
|
-
Object.defineProperty(exports, 'normalizeRoutes', {
|
|
2046
|
-
enumerable: true,
|
|
2047
|
-
get: function () {
|
|
2048
|
-
return normalizeRoutes;
|
|
2049
|
-
}
|
|
2050
|
-
});
|
|
2051
|
-
Object.defineProperty(exports, 'openApiPathFor', {
|
|
2052
|
-
enumerable: true,
|
|
2053
|
-
get: function () {
|
|
2054
|
-
return openApiPathFor;
|
|
2055
|
-
}
|
|
2056
1916
|
});
|
|
2057
|
-
Object.defineProperty(exports,
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
1917
|
+
Object.defineProperty(exports, "OpenApiTsGenerator", {
|
|
1918
|
+
enumerable: true,
|
|
1919
|
+
get: function() {
|
|
1920
|
+
return OpenApiTsGenerator;
|
|
1921
|
+
}
|
|
2062
1922
|
});
|
|
2063
|
-
Object.defineProperty(exports,
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
1923
|
+
Object.defineProperty(exports, "runtimeFor", {
|
|
1924
|
+
enumerable: true,
|
|
1925
|
+
get: function() {
|
|
1926
|
+
return runtimeFor;
|
|
1927
|
+
}
|
|
2068
1928
|
});
|
|
2069
|
-
Object.defineProperty(exports,
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
1929
|
+
Object.defineProperty(exports, "telemetryFor", {
|
|
1930
|
+
enumerable: true,
|
|
1931
|
+
get: function() {
|
|
1932
|
+
return telemetryFor;
|
|
1933
|
+
}
|
|
2074
1934
|
});
|
|
2075
|
-
|
|
1935
|
+
|
|
1936
|
+
//# sourceMappingURL=OpenApiTsGenerator-BTuUumsV.cjs.map
|