@geekmidas/cli 10.0.0-alpha.5 → 10.0.0-alpha.50
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 +196 -257
- 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-BZFGYYVA.cjs} +21 -22
- package/dist/HostingerProvider-BZFGYYVA.cjs.map +1 -0
- package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-GF6NAZAK.mjs} +20 -21
- package/dist/HostingerProvider-GF6NAZAK.mjs.map +1 -0
- package/dist/{LocalStateProvider-Db9SEjyH.cjs → LocalStateProvider-7HR6SS2t.cjs} +11 -6
- package/dist/LocalStateProvider-7HR6SS2t.cjs.map +1 -0
- package/dist/{LocalStateProvider-Bn6tS-oL.mjs → LocalStateProvider-D7QyJoLM.mjs} +10 -4
- package/dist/LocalStateProvider-D7QyJoLM.mjs.map +1 -0
- package/dist/{openapi-CA0yJUTN.cjs → OpenApiTsGenerator-BN0PIZxd.cjs} +157 -372
- package/dist/OpenApiTsGenerator-BN0PIZxd.cjs.map +1 -0
- package/dist/{openapi-kkQbsRVj.mjs → OpenApiTsGenerator-BzIGy8KE.mjs} +128 -324
- package/dist/OpenApiTsGenerator-BzIGy8KE.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/{SSMStateProvider-BRt2py-A.mjs → SSMStateProvider-B0Hu1MKZ.mjs} +13 -4
- package/dist/SSMStateProvider-B0Hu1MKZ.mjs.map +1 -0
- package/dist/{SSMStateProvider-DyX8s9HI.cjs → SSMStateProvider-VrQ-yeqd.cjs} +17 -9
- package/dist/SSMStateProvider-VrQ-yeqd.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/backends-B9V2XD2M.cjs +82 -0
- package/dist/backends-B9V2XD2M.cjs.map +1 -0
- package/dist/backends-CSuLl0YP.mjs +59 -0
- package/dist/backends-CSuLl0YP.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-Be8Zg4Wd.mjs → bundler--fyybf1N.mjs} +19 -30
- package/dist/bundler--fyybf1N.mjs.map +1 -0
- package/dist/{bundler-BY1OmV1e.cjs → bundler-By6_sXiL.cjs} +20 -32
- package/dist/bundler-By6_sXiL.cjs.map +1 -0
- package/dist/{config-C21ocYNd.cjs → config-CsYSyUya.cjs} +209 -210
- package/dist/config-CsYSyUya.cjs.map +1 -0
- package/dist/{config-WRdsQYZK.mjs → config-D8J5rrTb.mjs} +142 -154
- package/dist/config-D8J5rrTb.mjs.map +1 -0
- package/dist/config.cjs +9 -6
- package/dist/config.d.cts +62 -33
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +62 -33
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +3 -5
- 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 +9 -2
- 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 +13 -2
- 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/{discover-CAlFgYec.mjs → discover-Cf2jAcgF.mjs} +56 -63
- package/dist/discover-Cf2jAcgF.mjs.map +1 -0
- package/dist/{discover-DTmFeloL.cjs → discover-DXNviAh-.cjs} +86 -110
- package/dist/discover-DXNviAh-.cjs.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-C7OGMve_.cjs +91 -0
- package/dist/encryption-C7OGMve_.cjs.map +1 -0
- package/dist/encryption-DyQnPsZN.mjs +90 -0
- package/dist/encryption-DyQnPsZN.mjs.map +1 -0
- package/dist/github-BfpadQWQ.mjs +213 -0
- package/dist/github-BfpadQWQ.mjs.map +1 -0
- package/dist/github-BrI1tv6u.cjs +213 -0
- package/dist/github-BrI1tv6u.cjs.map +1 -0
- package/dist/{index-CHB4tSzX.d.cts → index-BQhJXpaQ.d.mts} +4 -23
- package/dist/index-BQhJXpaQ.d.mts.map +1 -0
- package/dist/{index-BThUzEIp.d.mts → index-DHJePE0y.d.cts} +4 -23
- package/dist/index-DHJePE0y.d.cts.map +1 -0
- package/dist/index.cjs +9531 -7200
- 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 +9412 -7108
- package/dist/index.mjs.map +1 -1
- package/dist/migrate-B00XpVaO.mjs +736 -0
- package/dist/migrate-B00XpVaO.mjs.map +1 -0
- package/dist/migrate-CNlew9Ek.cjs +743 -0
- package/dist/migrate-CNlew9Ek.cjs.map +1 -0
- package/dist/openapi.cjs +198 -8
- package/dist/openapi.cjs.map +1 -0
- package/dist/openapi.d.cts +53 -15
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +53 -15
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +193 -5
- package/dist/openapi.mjs.map +1 -0
- package/dist/ready-WfT-eWlm.mjs +861 -0
- package/dist/ready-WfT-eWlm.mjs.map +1 -0
- package/dist/ready-lr2Fm-ep.cjs +932 -0
- package/dist/ready-lr2Fm-ep.cjs.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/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-DQgxT_WR.cjs +211 -0
- package/dist/store-DQgxT_WR.cjs.map +1 -0
- package/dist/store-DeGATCS-.mjs +182 -0
- package/dist/store-DeGATCS-.mjs.map +1 -0
- package/dist/types-BbrNu83u.d.mts +6229 -0
- package/dist/types-BbrNu83u.d.mts.map +1 -0
- package/dist/types-DNqEsctD.d.cts +6230 -0
- package/dist/types-DNqEsctD.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/{credentials-BBIRJVp4.mjs → workspace-BsbxbqV-.mjs} +2201 -1732
- package/dist/workspace-BsbxbqV-.mjs.map +1 -0
- package/dist/{workspace-BcucjwvA.cjs → workspace-DEibcoBe.cjs} +1038 -1118
- package/dist/workspace-DEibcoBe.cjs.map +1 -0
- package/dist/{workspace-BFMrAKqI.mjs → workspace-DNzWgM1J.mjs} +869 -972
- package/dist/workspace-DNzWgM1J.mjs.map +1 -0
- package/dist/{credentials-G1JwBoXH.cjs → workspace-j6ZxvJqq.cjs} +2337 -1849
- package/dist/workspace-j6ZxvJqq.cjs.map +1 -0
- package/package.json +29 -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.map +0 -1
- 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.map +0 -1
- 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-C21ocYNd.cjs.map +0 -1
- package/dist/config-WRdsQYZK.mjs.map +0 -1
- package/dist/credentials-B5zRHdAl.mjs +0 -141
- package/dist/credentials-B5zRHdAl.mjs.map +0 -1
- package/dist/credentials-BBIRJVp4.mjs.map +0 -1
- package/dist/credentials-BapzjyV5.cjs +0 -195
- package/dist/credentials-BapzjyV5.cjs.map +0 -1
- package/dist/credentials-G1JwBoXH.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-BThUzEIp.d.mts.map +0 -1
- package/dist/index-CHB4tSzX.d.cts.map +0 -1
- package/dist/openapi-CA0yJUTN.cjs.map +0 -1
- package/dist/openapi-kkQbsRVj.mjs.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-B5_oHHUj.cjs +0 -11
- package/dist/setup-Cm2UnAdh.cjs +0 -473
- package/dist/setup-Cm2UnAdh.cjs.map +0 -1
- package/dist/setup-DXvRLTZN.mjs +0 -443
- package/dist/setup-DXvRLTZN.mjs.map +0 -1
- package/dist/setup-ZijS4qeC.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-C-arnQ1r.d.mts +0 -2184
- package/dist/types-C-arnQ1r.d.mts.map +0 -1
- package/dist/types-abJQuk7m.d.cts +0 -2184
- package/dist/types-abJQuk7m.d.cts.map +0 -1
- package/dist/workspace-BFMrAKqI.mjs.map +0 -1
- package/dist/workspace-BcucjwvA.cjs.map +0 -1
- package/dist/workspace-DdJss8I6.cjs +0 -9
- package/dist/workspace-k4l3rsFh.mjs +0 -8
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { ConstructGenerator
|
|
2
|
-
import { loadWorkspaceConfig } from "./config-WRdsQYZK.mjs";
|
|
3
|
-
import { dirname, join, relative } from "node:path";
|
|
1
|
+
import { i as ConstructGenerator } from "./discover-Cf2jAcgF.mjs";
|
|
4
2
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
5
|
-
import {
|
|
3
|
+
import { dirname, join, relative } from "node:path";
|
|
6
4
|
import { Endpoint } from "@geekmidas/constructs/endpoints";
|
|
7
|
-
import { fileURLToPath } from "node:url";
|
|
8
5
|
import { StandardSchemaJsonSchema, getRegisteredZodJsonSchemas, getSchemaMetadata } from "@geekmidas/schema/conversion";
|
|
9
|
-
|
|
10
6
|
//#region src/build/endpoint-analyzer.ts
|
|
11
7
|
/**
|
|
12
8
|
* Analyze an endpoint to extract its features
|
|
@@ -83,7 +79,6 @@ function summarizeAnalysis(analyses) {
|
|
|
83
79
|
byFeature
|
|
84
80
|
};
|
|
85
81
|
}
|
|
86
|
-
|
|
87
82
|
//#endregion
|
|
88
83
|
//#region src/build/handler-templates.ts
|
|
89
84
|
/**
|
|
@@ -105,8 +100,7 @@ function generateMinimalHandler(analysis) {
|
|
|
105
100
|
const { exportName, features } = analysis;
|
|
106
101
|
const method = analysis.method.toLowerCase();
|
|
107
102
|
const validators = generateValidators(exportName, features);
|
|
108
|
-
|
|
109
|
-
if (!hasValidators && !features.hasOutputValidation) return `
|
|
103
|
+
if (!(validators.length > 0) && !features.hasOutputValidation) return `
|
|
110
104
|
// Minimal handler: ${analysis.route} (${analysis.method})
|
|
111
105
|
app.${method}('${analysis.route}', async (c) => {
|
|
112
106
|
const result = await ${exportName}.handler(
|
|
@@ -304,8 +298,7 @@ ${factories.join("\n")}
|
|
|
304
298
|
*/
|
|
305
299
|
function generateMinimalEndpointFile(analysis, endpointImport) {
|
|
306
300
|
const { exportName, features } = analysis;
|
|
307
|
-
const
|
|
308
|
-
const validatorImport = needsValidators ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
301
|
+
const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
309
302
|
const handler = generateMinimalHandler(analysis);
|
|
310
303
|
return `/**
|
|
311
304
|
* Minimal endpoint: ${analysis.route} (${analysis.method})
|
|
@@ -330,8 +323,7 @@ ${handler}
|
|
|
330
323
|
*/
|
|
331
324
|
function generateStandardEndpointFile(analysis, endpointImport) {
|
|
332
325
|
const { exportName, features } = analysis;
|
|
333
|
-
const
|
|
334
|
-
const validatorImport = needsValidators ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
326
|
+
const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
335
327
|
const eventsImport = features.hasEvents ? `import { publishConstructEvents } from '@geekmidas/constructs/endpoints';` : "";
|
|
336
328
|
const handler = generateStandardHandler(analysis);
|
|
337
329
|
return `/**
|
|
@@ -423,7 +415,7 @@ export function setupFullEndpoints(
|
|
|
423
415
|
}
|
|
424
416
|
const imports = tierEndpoints.map((a) => `import { setup${capitalize(a.exportName)} } from './${a.exportName}.js';`).join("\n");
|
|
425
417
|
if (tier === "minimal") {
|
|
426
|
-
const calls
|
|
418
|
+
const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, logger);`).join("\n");
|
|
427
419
|
return `/**
|
|
428
420
|
* Minimal-tier endpoint index (${tierEndpoints.length} endpoints)
|
|
429
421
|
* Near-raw-Hono performance
|
|
@@ -436,12 +428,12 @@ export function setupMinimalEndpoints(
|
|
|
436
428
|
app: Hono,
|
|
437
429
|
logger: Logger,
|
|
438
430
|
): void {
|
|
439
|
-
${calls
|
|
431
|
+
${calls}
|
|
440
432
|
}
|
|
441
433
|
`;
|
|
442
434
|
}
|
|
443
435
|
if (tier === "standard") {
|
|
444
|
-
const calls
|
|
436
|
+
const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, serviceDiscovery, logger);`).join("\n");
|
|
445
437
|
return `/**
|
|
446
438
|
* Standard-tier endpoint index (${tierEndpoints.length} endpoints)
|
|
447
439
|
* Auth and/or services enabled
|
|
@@ -456,7 +448,7 @@ export function setupStandardEndpoints(
|
|
|
456
448
|
serviceDiscovery: ServiceDiscovery<any, any>,
|
|
457
449
|
logger: Logger,
|
|
458
450
|
): void {
|
|
459
|
-
${calls
|
|
451
|
+
${calls}
|
|
460
452
|
}
|
|
461
453
|
`;
|
|
462
454
|
}
|
|
@@ -526,9 +518,7 @@ function generateEndpointFilesNested(analyses, endpointImports) {
|
|
|
526
518
|
case "standard":
|
|
527
519
|
files[fileName] = generateStandardEndpointFile(analysis, endpointImport);
|
|
528
520
|
break;
|
|
529
|
-
case "full":
|
|
530
|
-
files[fileName] = generateFullEndpointFile(analysis, endpointImport);
|
|
531
|
-
break;
|
|
521
|
+
case "full": files[fileName] = generateFullEndpointFile(analysis, endpointImport);
|
|
532
522
|
}
|
|
533
523
|
}
|
|
534
524
|
return files;
|
|
@@ -585,7 +575,6 @@ export async function setupEndpoints(
|
|
|
585
575
|
}
|
|
586
576
|
`;
|
|
587
577
|
}
|
|
588
|
-
|
|
589
578
|
//#endregion
|
|
590
579
|
//#region src/generators/EndpointGenerator.ts
|
|
591
580
|
/**
|
|
@@ -602,24 +591,21 @@ export async function setupEndpoints(
|
|
|
602
591
|
*
|
|
603
592
|
* Falls back to the configured paths for an app that declares no surface.
|
|
604
593
|
*/
|
|
605
|
-
function runtimeFor(context, fromDir) {
|
|
606
|
-
const module = context.surface?.module;
|
|
594
|
+
function runtimeFor(context, fromDir, owner) {
|
|
595
|
+
const module = owner ? context.owners?.[owner] ?? context.surface?.module : context.surface?.module;
|
|
607
596
|
if (module) {
|
|
608
597
|
const specifier = importSpecifier(fromDir, module.specifier);
|
|
609
598
|
return {
|
|
610
599
|
imports: `import { ${module.exportName} as __surface } from '${specifier}';`,
|
|
611
600
|
bindings: [
|
|
612
|
-
"// What this
|
|
613
|
-
"// the entry imports the
|
|
601
|
+
"// What this construct was declared with. Objects, not module paths:",
|
|
602
|
+
"// the entry imports the owner, so there is nothing to print.",
|
|
614
603
|
"const envParser = __surface.envParser;",
|
|
615
604
|
"const logger = __surface.logger;"
|
|
616
605
|
].join("\n")
|
|
617
606
|
};
|
|
618
607
|
}
|
|
619
|
-
|
|
620
|
-
imports: [`import ${context.envParserImportPattern} from '${importSpecifier(fromDir, context.envParserPath)}';`, `import ${context.loggerImportPattern} from '${importSpecifier(fromDir, context.loggerPath)}';`].join("\n"),
|
|
621
|
-
bindings: ""
|
|
622
|
-
};
|
|
608
|
+
throw new Error(`No owner to take a logger and an environment parser from${owner ? ` for "${owner}"` : ""}. Build it from a \`RestApi\` or a \`Worker\`.`);
|
|
623
609
|
}
|
|
624
610
|
/** A relative specifier ESM will accept: always prefixed, never bare. */
|
|
625
611
|
function importSpecifier(fromDir, target) {
|
|
@@ -681,45 +667,32 @@ var EndpointGenerator = class extends ConstructGenerator {
|
|
|
681
667
|
return Endpoint.isEndpoint(value);
|
|
682
668
|
}
|
|
683
669
|
async build(context, constructs, outputDir, options) {
|
|
684
|
-
const
|
|
670
|
+
const target = options?.target ?? "aws";
|
|
671
|
+
const root = options?.root ?? process.cwd();
|
|
685
672
|
const enableOpenApi = options?.enableOpenApi || false;
|
|
686
673
|
const logger = console;
|
|
687
674
|
const routes = [];
|
|
688
675
|
if (constructs.length === 0) return routes;
|
|
689
|
-
if (
|
|
676
|
+
if (target === "server") {
|
|
690
677
|
await this.generateEndpointsFile(outputDir, constructs, context);
|
|
691
678
|
const appFile = await this.generateAppFile(outputDir, context);
|
|
692
679
|
routes.push({
|
|
693
680
|
path: "*",
|
|
694
681
|
method: "ALL",
|
|
695
|
-
handler: relative(
|
|
682
|
+
handler: relative(root, appFile),
|
|
696
683
|
authorizer: "none"
|
|
697
684
|
});
|
|
698
685
|
logger.log(`Generated server with ${constructs.length} endpoints${enableOpenApi ? " (OpenAPI enabled)" : ""}`);
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
path: construct._path,
|
|
706
|
-
method: construct.method,
|
|
707
|
-
handler: relative(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
|
|
708
|
-
timeout: construct.timeout,
|
|
709
|
-
memorySize: construct.memorySize,
|
|
710
|
-
environment: await construct.getEnvironment({ markOptional: context.markOptional }),
|
|
711
|
-
dependencies: construct.constructs,
|
|
712
|
-
authorizer: construct.authorizer?.name ?? "none"
|
|
713
|
-
};
|
|
714
|
-
routes.push(routeInfo);
|
|
715
|
-
logger.log(`Generated handler for ${routeInfo.method} ${routeInfo.path}`);
|
|
716
|
-
}
|
|
717
|
-
} else for (const { key, construct, path } of constructs) {
|
|
718
|
-
const handlerFile = await this.generateHandlerFile(outputDir, path.relative, key, provider, construct, context);
|
|
686
|
+
return routes;
|
|
687
|
+
}
|
|
688
|
+
const routesDir = join(outputDir, "routes");
|
|
689
|
+
await mkdir(routesDir, { recursive: true });
|
|
690
|
+
for (const { key, construct, path } of constructs) {
|
|
691
|
+
const handlerFile = await this.generateHandlerFile(routesDir, path.relative, key, context);
|
|
719
692
|
const routeInfo = {
|
|
720
693
|
path: construct._path,
|
|
721
694
|
method: construct.method,
|
|
722
|
-
handler: relative(
|
|
695
|
+
handler: relative(root, handlerFile).replace(/\.ts$/, ".handler"),
|
|
723
696
|
timeout: construct.timeout,
|
|
724
697
|
memorySize: construct.memorySize,
|
|
725
698
|
environment: await construct.getEnvironment({ markOptional: context.markOptional }),
|
|
@@ -731,34 +704,17 @@ var EndpointGenerator = class extends ConstructGenerator {
|
|
|
731
704
|
}
|
|
732
705
|
return routes;
|
|
733
706
|
}
|
|
734
|
-
async generateHandlerFile(outputDir, sourceFile, exportName,
|
|
735
|
-
const
|
|
736
|
-
const
|
|
737
|
-
|
|
738
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
739
|
-
let content;
|
|
740
|
-
switch (provider) {
|
|
741
|
-
case "aws-apigatewayv1":
|
|
742
|
-
content = this.generateAWSApiGatewayV1Handler(importPath, exportName, context.storageDrivers);
|
|
743
|
-
break;
|
|
744
|
-
case "aws-apigatewayv2":
|
|
745
|
-
content = this.generateAWSApiGatewayV2Handler(importPath, exportName, context.storageDrivers);
|
|
746
|
-
break;
|
|
747
|
-
case "server":
|
|
748
|
-
content = this.generateServerHandler(importPath, exportName);
|
|
749
|
-
break;
|
|
750
|
-
default: throw new Error(`Unsupported provider: ${provider}`);
|
|
751
|
-
}
|
|
752
|
-
await writeFile(handlerPath, content);
|
|
707
|
+
async generateHandlerFile(outputDir, sourceFile, exportName, context) {
|
|
708
|
+
const handlerPath = join(outputDir, `${exportName}.ts`);
|
|
709
|
+
const importPath = relative(dirname(handlerPath), sourceFile).replace(/\.ts$/, ".js");
|
|
710
|
+
await writeFile(handlerPath, this.generateAWSApiGatewayV2Handler(importPath, exportName, context.storageDrivers));
|
|
753
711
|
return handlerPath;
|
|
754
712
|
}
|
|
755
713
|
async generateEndpointsFile(outputDir, endpoints, context) {
|
|
756
|
-
const
|
|
757
|
-
const endpointsPath = join(outputDir, endpointsFileName);
|
|
714
|
+
const endpointsPath = join(outputDir, "endpoints.ts");
|
|
758
715
|
const importsByFile = /* @__PURE__ */ new Map();
|
|
759
716
|
for (const { path, key } of endpoints) {
|
|
760
|
-
const
|
|
761
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
717
|
+
const importPath = relative(dirname(endpointsPath), path.relative).replace(/\.ts$/, ".js");
|
|
762
718
|
if (!importsByFile.has(importPath)) importsByFile.set(importPath, []);
|
|
763
719
|
importsByFile.get(importPath)?.push(key);
|
|
764
720
|
}
|
|
@@ -773,7 +729,7 @@ import { ServiceDiscovery } from '@geekmidas/services';
|
|
|
773
729
|
import type { Hono } from 'hono';
|
|
774
730
|
${endpointImports}
|
|
775
731
|
|
|
776
|
-
export const endpoints: Endpoint<any, any, any, any, any, any, any, any, any, any, any, any
|
|
732
|
+
export const endpoints: Endpoint<any, any, any, any, any, any, any, any, any, any, any, any>[] = [
|
|
777
733
|
${allExportNames.join(",\n ")}
|
|
778
734
|
];
|
|
779
735
|
|
|
@@ -824,11 +780,9 @@ export async function setupEndpoints(
|
|
|
824
780
|
const analyses = endpoints.map(({ key, construct }) => analyzeEndpoint(construct, key));
|
|
825
781
|
const endpointImports = endpoints.map(({ key, path }) => {
|
|
826
782
|
const tierDir = join(endpointsDir, "standard");
|
|
827
|
-
const relativePath = relative(tierDir, path.relative);
|
|
828
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
829
783
|
return {
|
|
830
784
|
exportName: key,
|
|
831
|
-
importPath
|
|
785
|
+
importPath: relative(tierDir, path.relative).replace(/\.ts$/, ".js")
|
|
832
786
|
};
|
|
833
787
|
});
|
|
834
788
|
const summary = summarizeAnalysis(analyses);
|
|
@@ -850,8 +804,7 @@ export async function setupEndpoints(
|
|
|
850
804
|
}
|
|
851
805
|
async generateAppFile(outputDir, context) {
|
|
852
806
|
if (context.production?.enabled) return this.generateProductionAppFile(outputDir, context);
|
|
853
|
-
const
|
|
854
|
-
const appPath = join(outputDir, appFileName);
|
|
807
|
+
const appPath = join(outputDir, "app.ts");
|
|
855
808
|
const runtime = runtimeFor(context, dirname(appPath));
|
|
856
809
|
const telescopeEnabled = context.telescope?.enabled;
|
|
857
810
|
const telescopeWebSocketEnabled = context.telescope?.websocket;
|
|
@@ -861,32 +814,36 @@ export async function setupEndpoints(
|
|
|
861
814
|
const studioFromDatabase = !usesExternalStudio && !!context.studio?.database;
|
|
862
815
|
const telescopeFromSurface = !!context.surface?.module && !usesExternalTelescope;
|
|
863
816
|
let telescopeImports = "";
|
|
864
|
-
if (telescopeEnabled)
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
817
|
+
if (telescopeEnabled) {
|
|
818
|
+
if (telescopeFromSurface) telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
|
|
819
|
+
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
820
|
+
else if (usesExternalTelescope) {
|
|
821
|
+
const relativeTelescopePath = relative(dirname(appPath), context.telescope?.telescopePath);
|
|
822
|
+
telescopeImports = `import ${context.telescope?.telescopeImportPattern} from '${relativeTelescopePath}';
|
|
868
823
|
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
869
|
-
|
|
824
|
+
} else telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
|
|
870
825
|
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
826
|
+
}
|
|
871
827
|
let studioImports = "";
|
|
872
|
-
if (studioEnabled)
|
|
873
|
-
|
|
874
|
-
|
|
828
|
+
if (studioEnabled) {
|
|
829
|
+
if (usesExternalStudio) {
|
|
830
|
+
const relativeStudioPath = relative(dirname(appPath), context.studio?.studioPath);
|
|
831
|
+
studioImports = `import ${context.studio?.studioImportPattern} from '${relativeStudioPath}';
|
|
875
832
|
import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
833
|
+
} else if (studioFromDatabase) {
|
|
834
|
+
const dbSpecifier = importSpecifier(dirname(appPath), context.studio.database.specifier);
|
|
835
|
+
studioImports = `import { snifferContext } from '@geekmidas/constructs';
|
|
879
836
|
import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';
|
|
880
837
|
import { ${context.studio.database.exportName} as __studioDb } from '${dbSpecifier}';
|
|
881
838
|
import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
882
|
-
|
|
839
|
+
} else studioImports = "";
|
|
840
|
+
}
|
|
883
841
|
const cors = corsFor(context.surface);
|
|
884
842
|
let hooksImports = "";
|
|
885
843
|
let beforeSetupCall = "";
|
|
886
844
|
let afterSetupCall = "";
|
|
887
845
|
if (context.hooks?.serverHooksPath) {
|
|
888
|
-
|
|
889
|
-
hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
|
|
846
|
+
hooksImports = `import * as serverHooks from '${relative(dirname(appPath), context.hooks.serverHooksPath)}';`;
|
|
890
847
|
beforeSetupCall = `
|
|
891
848
|
// Call beforeSetup hook if defined
|
|
892
849
|
if (typeof serverHooks.beforeSetup === 'function') {
|
|
@@ -932,7 +889,8 @@ import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
|
932
889
|
}
|
|
933
890
|
` : "";
|
|
934
891
|
let telescopeSetup = "";
|
|
935
|
-
if (telescopeEnabled)
|
|
892
|
+
if (telescopeEnabled) {
|
|
893
|
+
if (telescopeFromSurface || usesExternalTelescope) telescopeSetup = `
|
|
936
894
|
${telescopeWebSocketSetupCode}
|
|
937
895
|
// Add telescope middleware (before endpoints to capture all requests)
|
|
938
896
|
honoApp.use('*', createMiddleware(telescope));
|
|
@@ -941,7 +899,7 @@ ${telescopeWebSocketSetupCode}
|
|
|
941
899
|
const telescopeUI = createUI(telescope);
|
|
942
900
|
honoApp.route('${context.telescope?.path}', telescopeUI);
|
|
943
901
|
`;
|
|
944
|
-
|
|
902
|
+
else telescopeSetup = `
|
|
945
903
|
// Setup Telescope for debugging/monitoring
|
|
946
904
|
const telescopeStorage = new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} });
|
|
947
905
|
const telescope = new Telescope({
|
|
@@ -959,6 +917,7 @@ ${telescopeWebSocketSetupCode}
|
|
|
959
917
|
const telescopeUI = createUI(telescope);
|
|
960
918
|
honoApp.route('${context.telescope?.path}', telescopeUI);
|
|
961
919
|
`;
|
|
920
|
+
}
|
|
962
921
|
let studioSetup = "";
|
|
963
922
|
if (studioEnabled && studioFromDatabase) studioSetup = `
|
|
964
923
|
// Studio, built from the declared database. The client comes from the
|
|
@@ -992,6 +951,7 @@ import type { Hono as HonoType } from 'hono';
|
|
|
992
951
|
import { setupEndpoints } from './endpoints.js';
|
|
993
952
|
import { setupSubscribers } from './subscribers.js';
|
|
994
953
|
import { setupQueues } from './queues.js';
|
|
954
|
+
import { setupCrons } from './crons.js';
|
|
995
955
|
${runtime.imports}
|
|
996
956
|
${telescopeImports}
|
|
997
957
|
${studioImports}
|
|
@@ -1000,7 +960,16 @@ ${cors.imports}
|
|
|
1000
960
|
${context.storageDrivers?.imports ?? ""}
|
|
1001
961
|
|
|
1002
962
|
${runtime.bindings}
|
|
1003
|
-
${telescopeFromSurface ?
|
|
963
|
+
${telescopeEnabled && telescopeFromSurface ? `// The surface's own Telescope, or the one \`telescope\` config describes.
|
|
964
|
+
const telescope =
|
|
965
|
+
__surface.telescope ??
|
|
966
|
+
new Telescope({
|
|
967
|
+
enabled: true,
|
|
968
|
+
path: '${context.telescope?.path}',
|
|
969
|
+
ignorePatterns: ${JSON.stringify(context.telescope?.ignore)},
|
|
970
|
+
recordBody: ${context.telescope?.recordBody},
|
|
971
|
+
storage: new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} }),
|
|
972
|
+
});` : ""}
|
|
1004
973
|
|
|
1005
974
|
${context.storageDrivers?.setup ? `// Which storage drivers exist is the entry point's decision: the scheme in
|
|
1006
975
|
// each injected URL picks one, so no construct and no application module names
|
|
@@ -1069,9 +1038,11 @@ ${afterSetupCall}
|
|
|
1069
1038
|
|
|
1070
1039
|
const port = options.port ?? 3000;
|
|
1071
1040
|
|
|
1072
|
-
//
|
|
1073
|
-
|
|
1041
|
+
// Mount pushed subscribers' routes and start polled ones. What comes
|
|
1042
|
+
// back subscribes the routes, once the server can answer them.
|
|
1043
|
+
const subscribeForPush = await setupSubscribers(honoApp, envParser, logger).catch((error) => {
|
|
1074
1044
|
logger.error({ error }, 'Failed to start subscribers');
|
|
1045
|
+
return async (_port: number) => {};
|
|
1075
1046
|
});
|
|
1076
1047
|
|
|
1077
1048
|
// Start queue workers in background (non-blocking, local development only)
|
|
@@ -1079,12 +1050,20 @@ ${afterSetupCall}
|
|
|
1079
1050
|
logger.error({ error }, 'Failed to start queue workers');
|
|
1080
1051
|
});
|
|
1081
1052
|
|
|
1053
|
+
// Schedule this app's crons. Caught like the others: a scheduler that
|
|
1054
|
+
// cannot start is not a reason for the HTTP server not to.
|
|
1055
|
+
await setupCrons(envParser, logger).catch((error) => {
|
|
1056
|
+
logger.error({ error }, 'Failed to schedule crons');
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1082
1059
|
logger.info({ port }, 'Starting server');
|
|
1083
1060
|
|
|
1084
1061
|
// Start HTTP server using provided serve function
|
|
1085
1062
|
await options.serve(honoApp, port);
|
|
1086
1063
|
|
|
1087
1064
|
logger.info({ port }, 'Server started');
|
|
1065
|
+
|
|
1066
|
+
await subscribeForPush(port);
|
|
1088
1067
|
}
|
|
1089
1068
|
};
|
|
1090
1069
|
}
|
|
@@ -1105,26 +1084,6 @@ export default createApp;
|
|
|
1105
1084
|
* object. Nothing has to be printed now, which is also why nothing has to be
|
|
1106
1085
|
* named in config.
|
|
1107
1086
|
*/
|
|
1108
|
-
generateAWSApiGatewayV1Handler(importPath, exportName, drivers) {
|
|
1109
|
-
return `import { AmazonApiGatewayV1Endpoint } from '@geekmidas/constructs/aws';
|
|
1110
|
-
import { ${exportName} } from '${importPath}';
|
|
1111
|
-
${drivers?.imports ?? ""}
|
|
1112
|
-
${drivers?.setup ? `\n// The handler registers the drivers its target needs.\n${drivers.setup}\n` : ""}
|
|
1113
|
-
const adapter = new AmazonApiGatewayV1Endpoint(${exportName});
|
|
1114
|
-
|
|
1115
|
-
export const handler = adapter.handler;
|
|
1116
|
-
`;
|
|
1117
|
-
}
|
|
1118
|
-
/**
|
|
1119
|
-
* One Lambda, one endpoint — and no environment import.
|
|
1120
|
-
*
|
|
1121
|
-
* The endpoint was built from its surface, so it carries the parser the
|
|
1122
|
-
* adaptor needs. This used to read
|
|
1123
|
-
* `import { envParser } from '../../config/env'`, a line the build wrote
|
|
1124
|
-
* because a generator can print a module specifier and cannot print an
|
|
1125
|
-
* object. Nothing has to be printed now, which is also why nothing has to be
|
|
1126
|
-
* named in config.
|
|
1127
|
-
*/
|
|
1128
1087
|
generateAWSApiGatewayV2Handler(importPath, exportName, drivers) {
|
|
1129
1088
|
return `import { AmazonApiGatewayV2Endpoint } from '@geekmidas/constructs/aws';
|
|
1130
1089
|
import { ${exportName} } from '${importPath}';
|
|
@@ -1133,13 +1092,6 @@ ${drivers?.setup ? `\n// The handler registers the drivers its target needs.\n${
|
|
|
1133
1092
|
const adapter = new AmazonApiGatewayV2Endpoint(${exportName});
|
|
1134
1093
|
|
|
1135
1094
|
export const handler = adapter.handler;
|
|
1136
|
-
`;
|
|
1137
|
-
}
|
|
1138
|
-
generateServerHandler(importPath, exportName) {
|
|
1139
|
-
return `import { ${exportName} } from '${importPath}';
|
|
1140
|
-
|
|
1141
|
-
// Server handler - implement based on your server framework
|
|
1142
|
-
export const handler = ${exportName};
|
|
1143
1095
|
`;
|
|
1144
1096
|
}
|
|
1145
1097
|
/**
|
|
@@ -1147,10 +1099,8 @@ export const handler = ${exportName};
|
|
|
1147
1099
|
* No dev tools (Telescope, Studio, WebSocket), includes health checks and graceful shutdown
|
|
1148
1100
|
*/
|
|
1149
1101
|
async generateProductionAppFile(outputDir, context) {
|
|
1150
|
-
const
|
|
1151
|
-
const
|
|
1152
|
-
const relativeLoggerPath = relative(dirname(appPath), context.loggerPath);
|
|
1153
|
-
const relativeEnvParserPath = relative(dirname(appPath), context.envParserPath);
|
|
1102
|
+
const appPath = join(outputDir, "app.ts");
|
|
1103
|
+
const runtime = runtimeFor(context, dirname(appPath));
|
|
1154
1104
|
const production = context.production;
|
|
1155
1105
|
const healthCheckPath = production.healthCheck;
|
|
1156
1106
|
const enableGracefulShutdown = production.gracefulShutdown;
|
|
@@ -1161,8 +1111,7 @@ export const handler = ${exportName};
|
|
|
1161
1111
|
let beforeSetupCall = "";
|
|
1162
1112
|
let afterSetupCall = "";
|
|
1163
1113
|
if (context.hooks?.serverHooksPath) {
|
|
1164
|
-
|
|
1165
|
-
hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
|
|
1114
|
+
hooksImports = `import * as serverHooks from '${relative(dirname(appPath), context.hooks.serverHooksPath)}';`;
|
|
1166
1115
|
beforeSetupCall = `
|
|
1167
1116
|
// Call beforeSetup hook if defined
|
|
1168
1117
|
if (typeof serverHooks.beforeSetup === 'function') {
|
|
@@ -1177,18 +1126,27 @@ export const handler = ${exportName};
|
|
|
1177
1126
|
`;
|
|
1178
1127
|
}
|
|
1179
1128
|
const subscriberSetup = includeSubscribers ? `
|
|
1180
|
-
//
|
|
1181
|
-
|
|
1129
|
+
// Mount pushed subscribers' routes and start polled ones. What comes
|
|
1130
|
+
// back subscribes the routes, once the server can answer them.
|
|
1131
|
+
const subscribeForPush = await setupSubscribers(honoApp, envParser, logger).catch((error) => {
|
|
1182
1132
|
logger.error({ error }, 'Failed to start subscribers');
|
|
1133
|
+
return async (_port: number) => {};
|
|
1183
1134
|
});
|
|
1184
1135
|
|
|
1185
1136
|
// Start queue workers in background
|
|
1186
1137
|
await setupQueues(envParser, logger).catch((error) => {
|
|
1187
1138
|
logger.error({ error }, 'Failed to start queue workers');
|
|
1188
1139
|
});
|
|
1140
|
+
|
|
1141
|
+
// Schedule this app's crons. Caught like the others: a scheduler that
|
|
1142
|
+
// cannot start is not a reason for the HTTP server not to.
|
|
1143
|
+
await setupCrons(envParser, logger).catch((error) => {
|
|
1144
|
+
logger.error({ error }, 'Failed to schedule crons');
|
|
1145
|
+
});
|
|
1189
1146
|
` : "";
|
|
1190
1147
|
const subscriberImport = includeSubscribers ? `import { setupSubscribers } from './subscribers.js';
|
|
1191
|
-
import { setupQueues } from './queues.js'
|
|
1148
|
+
import { setupQueues } from './queues.js';
|
|
1149
|
+
import { setupCrons } from './crons.js';` : "";
|
|
1192
1150
|
const gracefulShutdownCode = enableGracefulShutdown ? `
|
|
1193
1151
|
// Graceful shutdown handling
|
|
1194
1152
|
let isShuttingDown = false;
|
|
@@ -1204,7 +1162,6 @@ import { setupQueues } from './queues.js';` : "";
|
|
|
1204
1162
|
process.on('SIGTERM', shutdown);
|
|
1205
1163
|
process.on('SIGINT', shutdown);
|
|
1206
1164
|
` : "";
|
|
1207
|
-
const endpointsImportPath = production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js";
|
|
1208
1165
|
const content = `/**
|
|
1209
1166
|
* Generated production server application
|
|
1210
1167
|
*
|
|
@@ -1216,10 +1173,10 @@ import { setupQueues } from './queues.js';` : "";
|
|
|
1216
1173
|
*/
|
|
1217
1174
|
import { Hono } from 'hono';
|
|
1218
1175
|
import type { Hono as HonoType } from 'hono';
|
|
1219
|
-
import { setupEndpoints } from '${
|
|
1176
|
+
import { setupEndpoints } from '${production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js"}';
|
|
1220
1177
|
${subscriberImport}
|
|
1221
|
-
|
|
1222
|
-
|
|
1178
|
+
${runtime.imports}
|
|
1179
|
+
${runtime.bindings}
|
|
1223
1180
|
${hooksImports}
|
|
1224
1181
|
${cors.imports}
|
|
1225
1182
|
${context.storageDrivers?.imports ?? ""}
|
|
@@ -1267,6 +1224,7 @@ ${gracefulShutdownCode}${subscriberSetup}
|
|
|
1267
1224
|
await options.serve(honoApp, port);
|
|
1268
1225
|
|
|
1269
1226
|
logger.info({ port }, 'Production server started');
|
|
1227
|
+
${includeSubscribers ? "\n await subscribeForPush(port);" : ""}
|
|
1270
1228
|
}
|
|
1271
1229
|
};
|
|
1272
1230
|
}
|
|
@@ -1283,10 +1241,10 @@ export default createApp;
|
|
|
1283
1241
|
*/
|
|
1284
1242
|
async generateProductionServerEntry(outputDir) {
|
|
1285
1243
|
const serverPath = join(outputDir, "server.ts");
|
|
1286
|
-
|
|
1244
|
+
await writeFile(serverPath, `#!/usr/bin/env node
|
|
1287
1245
|
/**
|
|
1288
1246
|
* Production server entry point
|
|
1289
|
-
* Generated by 'gkm build --
|
|
1247
|
+
* Generated by 'gkm build --production'
|
|
1290
1248
|
*/
|
|
1291
1249
|
import { serve } from '@hono/node-server';
|
|
1292
1250
|
import { createApp } from './app.js';
|
|
@@ -1299,11 +1257,9 @@ await start({
|
|
|
1299
1257
|
port,
|
|
1300
1258
|
serve: (app, port) => { serve({ fetch: app.fetch, port }); },
|
|
1301
1259
|
});
|
|
1302
|
-
|
|
1303
|
-
await writeFile(serverPath, content);
|
|
1260
|
+
`);
|
|
1304
1261
|
}
|
|
1305
1262
|
};
|
|
1306
|
-
|
|
1307
1263
|
//#endregion
|
|
1308
1264
|
//#region src/generators/OpenApiTsGenerator.ts
|
|
1309
1265
|
/**
|
|
@@ -1458,7 +1414,7 @@ var OpenApiTsGenerator = class {
|
|
|
1458
1414
|
for (const [rawName, rawSchema] of Object.entries(registrySchemas)) {
|
|
1459
1415
|
const defName = this.pascalCase(rawName);
|
|
1460
1416
|
if (collectedDefs.has(defName) || generatedNames.has(defName)) continue;
|
|
1461
|
-
const { id: _id, $defs: _defs
|
|
1417
|
+
const { id: _id, $defs: _defs, ...rest } = rawSchema;
|
|
1462
1418
|
collectedDefs.set(defName, rest);
|
|
1463
1419
|
}
|
|
1464
1420
|
for (const [defName, defSchema] of collectedDefs) if (!generatedNames.has(defName)) {
|
|
@@ -1494,17 +1450,17 @@ var OpenApiTsGenerator = class {
|
|
|
1494
1450
|
async schemaToInterfaceWithDefs(schema, name, collectedDefs) {
|
|
1495
1451
|
try {
|
|
1496
1452
|
const vendor = schema["~standard"]?.vendor;
|
|
1497
|
-
if (!vendor || !(vendor in StandardSchemaJsonSchema)) return
|
|
1453
|
+
if (!vendor || !(vendor in StandardSchemaJsonSchema)) return unknownType(name);
|
|
1498
1454
|
const toJsonSchema = StandardSchemaJsonSchema[vendor];
|
|
1499
1455
|
const jsonSchema = await toJsonSchema(schema);
|
|
1500
|
-
if (!jsonSchema) return
|
|
1456
|
+
if (!jsonSchema) return unknownType(name);
|
|
1501
1457
|
if (jsonSchema.$defs && typeof jsonSchema.$defs === "object") {
|
|
1502
1458
|
for (const [defName, defSchema] of Object.entries(jsonSchema.$defs)) if (!collectedDefs.has(defName)) {
|
|
1503
|
-
const { id
|
|
1459
|
+
const { id, ...schemaWithoutId } = defSchema;
|
|
1504
1460
|
collectedDefs.set(defName, schemaWithoutId);
|
|
1505
1461
|
}
|
|
1506
1462
|
}
|
|
1507
|
-
const { $defs
|
|
1463
|
+
const { $defs, ...schemaWithoutDefs } = jsonSchema;
|
|
1508
1464
|
const ref = schemaWithoutDefs.$ref;
|
|
1509
1465
|
if (ref && Object.keys(schemaWithoutDefs).every((k) => k === "$ref" || k === "$schema")) {
|
|
1510
1466
|
const target = ref.split("/").pop();
|
|
@@ -1512,14 +1468,11 @@ var OpenApiTsGenerator = class {
|
|
|
1512
1468
|
}
|
|
1513
1469
|
return this.jsonSchemaToInterface(schemaWithoutDefs, name);
|
|
1514
1470
|
} catch {
|
|
1515
|
-
return
|
|
1471
|
+
return unknownType(name);
|
|
1516
1472
|
}
|
|
1517
1473
|
}
|
|
1518
1474
|
jsonSchemaToInterface(schema, name) {
|
|
1519
|
-
if (schema.type !== "object" || !schema.properties) {
|
|
1520
|
-
const typeStr = this.jsonSchemaTypeToTs(schema);
|
|
1521
|
-
return `export type ${name} = ${typeStr};`;
|
|
1522
|
-
}
|
|
1475
|
+
if (schema.type !== "object" || !schema.properties) return `export type ${name} = ${this.jsonSchemaTypeToTs(schema)};`;
|
|
1523
1476
|
const props = [];
|
|
1524
1477
|
const required = new Set(schema.required || []);
|
|
1525
1478
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
@@ -1532,13 +1485,15 @@ var OpenApiTsGenerator = class {
|
|
|
1532
1485
|
}
|
|
1533
1486
|
jsonSchemaTypeToTs(schema) {
|
|
1534
1487
|
if (!schema) return "unknown";
|
|
1535
|
-
if (schema.$ref)
|
|
1536
|
-
|
|
1537
|
-
return refName;
|
|
1538
|
-
}
|
|
1488
|
+
if (schema.$ref) return schema.$ref.split("/").pop() || "unknown";
|
|
1489
|
+
if (schema.const !== void 0) return typeof schema.const === "string" ? `'${schema.const}'` : String(schema.const);
|
|
1539
1490
|
if (schema.anyOf) return schema.anyOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
|
|
1540
1491
|
if (schema.oneOf) return schema.oneOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
|
|
1541
1492
|
if (schema.allOf) return schema.allOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" & ");
|
|
1493
|
+
if (Array.isArray(schema.type)) return schema.type.map((type) => this.jsonSchemaTypeToTs({
|
|
1494
|
+
...schema,
|
|
1495
|
+
type
|
|
1496
|
+
})).join(" | ");
|
|
1542
1497
|
switch (schema.type) {
|
|
1543
1498
|
case "string":
|
|
1544
1499
|
if (schema.enum) return schema.enum.map((e) => `'${e}'`).join(" | ");
|
|
@@ -1562,10 +1517,7 @@ var OpenApiTsGenerator = class {
|
|
|
1562
1517
|
}
|
|
1563
1518
|
return `{ ${props.join("; ")} }`;
|
|
1564
1519
|
}
|
|
1565
|
-
if (schema.additionalProperties) {
|
|
1566
|
-
const valueType = this.jsonSchemaTypeToTs(schema.additionalProperties);
|
|
1567
|
-
return `Record<string, ${valueType}>`;
|
|
1568
|
-
}
|
|
1520
|
+
if (schema.additionalProperties) return `Record<string, ${this.jsonSchemaTypeToTs(schema.additionalProperties)}>`;
|
|
1569
1521
|
return "Record<string, unknown>";
|
|
1570
1522
|
default: return "unknown";
|
|
1571
1523
|
}
|
|
@@ -1586,10 +1538,7 @@ var OpenApiTsGenerator = class {
|
|
|
1586
1538
|
}
|
|
1587
1539
|
const firstWithParams = infos.find((i) => i.input?.params);
|
|
1588
1540
|
let paramsEntry = "";
|
|
1589
|
-
if (firstWithParams?.input?.params) {
|
|
1590
|
-
const paramsName = await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`);
|
|
1591
|
-
paramsEntry = `\n parameters: {\n path: ${paramsName};\n };`;
|
|
1592
|
-
}
|
|
1541
|
+
if (firstWithParams?.input?.params) paramsEntry = `\n parameters: {\n path: ${await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`)};\n };`;
|
|
1593
1542
|
pathEntries.push(` '${route}': {${paramsEntry}\n${methodEntries.join("\n")}\n };`);
|
|
1594
1543
|
}
|
|
1595
1544
|
return `export interface paths {\n${pathEntries.join("\n")}\n}`;
|
|
@@ -1628,8 +1577,7 @@ var OpenApiTsGenerator = class {
|
|
|
1628
1577
|
return acc;
|
|
1629
1578
|
}, {});
|
|
1630
1579
|
const schemeNames = securitySchemes.map((s) => `'${s.name}'`).join(" | ");
|
|
1631
|
-
const
|
|
1632
|
-
const createApiSection = hasSecuritySchemes ? `
|
|
1580
|
+
const createApiSection = schemeNames.length > 0 ? `
|
|
1633
1581
|
// ============================================================
|
|
1634
1582
|
// API Client Factory
|
|
1635
1583
|
// ============================================================
|
|
@@ -1653,6 +1601,8 @@ export interface CreateApiOptions {
|
|
|
1653
1601
|
queryClient?: QueryClient;
|
|
1654
1602
|
/** Optional request interceptor */
|
|
1655
1603
|
onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
|
|
1604
|
+
/** The \`fetch\` requests go out on — a test browser's, for one */
|
|
1605
|
+
fetch?: typeof fetch;
|
|
1656
1606
|
}
|
|
1657
1607
|
|
|
1658
1608
|
/**
|
|
@@ -1682,6 +1632,7 @@ export function createApi(options: CreateApiOptions) {
|
|
|
1682
1632
|
securitySchemes,
|
|
1683
1633
|
authStrategies: options.authStrategies,
|
|
1684
1634
|
onRequest: options.onRequest,
|
|
1635
|
+
...(options.fetch ? { fetch: options.fetch } : {}),
|
|
1685
1636
|
});
|
|
1686
1637
|
|
|
1687
1638
|
const hooks = createEndpointHooks<paths>(fetcher, { queryClient: options.queryClient });
|
|
@@ -1806,162 +1757,15 @@ ${createApiSection}
|
|
|
1806
1757
|
`;
|
|
1807
1758
|
}
|
|
1808
1759
|
};
|
|
1809
|
-
|
|
1810
|
-
//#endregion
|
|
1811
|
-
//#region src/workspace/client-generator.ts
|
|
1812
1760
|
/**
|
|
1813
|
-
*
|
|
1814
|
-
*
|
|
1815
|
-
*
|
|
1761
|
+
* The declaration for a schema that cannot be converted — a vendor with no
|
|
1762
|
+
* converter, or one that fails. The paths interface names it either way, so
|
|
1763
|
+
* leaving it undeclared made the generated client fail to compile.
|
|
1816
1764
|
*/
|
|
1817
|
-
function
|
|
1818
|
-
|
|
1819
|
-
if (isPartitionedRoutes(routes)) return Array.isArray(routes.paths) ? routes.paths : [routes.paths];
|
|
1820
|
-
return Array.isArray(routes) ? routes : [routes];
|
|
1765
|
+
function unknownType(name) {
|
|
1766
|
+
return `export type ${name} = unknown;`;
|
|
1821
1767
|
}
|
|
1822
|
-
|
|
1823
1768
|
//#endregion
|
|
1824
|
-
|
|
1825
|
-
/**
|
|
1826
|
-
* Default output path for generated OpenAPI client (used for single-app configs)
|
|
1827
|
-
*/
|
|
1828
|
-
const OPENAPI_OUTPUT_PATH = "./.gkm/openapi.ts";
|
|
1829
|
-
/**
|
|
1830
|
-
* Resolve OpenAPI config from GkmConfig
|
|
1831
|
-
*/
|
|
1832
|
-
function resolveOpenApiConfig(config) {
|
|
1833
|
-
if (config.openapi === false) return { enabled: false };
|
|
1834
|
-
if (config.openapi === true || config.openapi === void 0) return {
|
|
1835
|
-
enabled: true,
|
|
1836
|
-
title: "API Documentation",
|
|
1837
|
-
version: "1.0.0",
|
|
1838
|
-
description: "Auto-generated API documentation from endpoints"
|
|
1839
|
-
};
|
|
1840
|
-
return {
|
|
1841
|
-
enabled: config.openapi.enabled !== false,
|
|
1842
|
-
title: config.openapi.title || "API Documentation",
|
|
1843
|
-
version: config.openapi.version || "1.0.0",
|
|
1844
|
-
description: config.openapi.description || "Auto-generated API documentation from endpoints"
|
|
1845
|
-
};
|
|
1846
|
-
}
|
|
1847
|
-
/**
|
|
1848
|
-
* Generate OpenAPI spec from endpoints
|
|
1849
|
-
* @returns Object with output path and endpoint count, or null if disabled
|
|
1850
|
-
*/
|
|
1851
|
-
async function generateOpenApi(config, options = {}) {
|
|
1852
|
-
const logger = options.silent ? { log: () => {} } : console;
|
|
1853
|
-
const openApiConfig = resolveOpenApiConfig(config);
|
|
1854
|
-
if (!openApiConfig.enabled) return null;
|
|
1855
|
-
const endpointGenerator = new EndpointGenerator();
|
|
1856
|
-
const loadedEndpoints = await endpointGenerator.load(config.routes, void 0, options.bustCache);
|
|
1857
|
-
if (loadedEndpoints.length === 0) {
|
|
1858
|
-
logger.log("No valid endpoints found for OpenAPI generation");
|
|
1859
|
-
return null;
|
|
1860
|
-
}
|
|
1861
|
-
const endpoints = loadedEndpoints.map(({ construct }) => construct);
|
|
1862
|
-
const outputPath = join(process.cwd(), OPENAPI_OUTPUT_PATH);
|
|
1863
|
-
await mkdir(dirname(outputPath), { recursive: true });
|
|
1864
|
-
const tsGenerator = new OpenApiTsGenerator();
|
|
1865
|
-
const tsContent = await tsGenerator.generate(endpoints, {
|
|
1866
|
-
title: openApiConfig.title,
|
|
1867
|
-
version: openApiConfig.version,
|
|
1868
|
-
description: openApiConfig.description
|
|
1869
|
-
});
|
|
1870
|
-
await writeFile(outputPath, tsContent);
|
|
1871
|
-
logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);
|
|
1872
|
-
return {
|
|
1873
|
-
outputPath,
|
|
1874
|
-
endpointCount: loadedEndpoints.length
|
|
1875
|
-
};
|
|
1876
|
-
}
|
|
1877
|
-
async function openapiCommand(options = {}) {
|
|
1878
|
-
const logger = console;
|
|
1879
|
-
try {
|
|
1880
|
-
const loadedConfig = await loadWorkspaceConfig(options.cwd);
|
|
1881
|
-
if (loadedConfig.type === "single") {
|
|
1882
|
-
const config = loadedConfig.raw;
|
|
1883
|
-
if (!config.openapi) config.openapi = { enabled: true };
|
|
1884
|
-
const result = await generateOpenApi(config);
|
|
1885
|
-
if (result) logger.log(`Found ${result.endpointCount} endpoints`);
|
|
1886
|
-
} else {
|
|
1887
|
-
const { workspace } = loadedConfig;
|
|
1888
|
-
const workspaceRoot = workspace.root;
|
|
1889
|
-
const backendApps = Object.entries(workspace.apps).filter(([_, app]) => app.type === "backend" && app.routes !== void 0 && app.openapi !== false && (typeof app.openapi !== "object" || app.openapi.enabled !== false));
|
|
1890
|
-
if (backendApps.length === 0) {
|
|
1891
|
-
logger.log("No backend apps with OpenAPI enabled found");
|
|
1892
|
-
return;
|
|
1893
|
-
}
|
|
1894
|
-
if (options.app) {
|
|
1895
|
-
const entry = backendApps.find(([name]) => name === options.app);
|
|
1896
|
-
if (!entry) throw new Error(`App "${options.app}" not found or has OpenAPI disabled`);
|
|
1897
|
-
const [appName, app] = entry;
|
|
1898
|
-
const result = await generateOpenApiForApp(workspaceRoot, appName, app);
|
|
1899
|
-
if (result) logger.log(`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`);
|
|
1900
|
-
return;
|
|
1901
|
-
}
|
|
1902
|
-
for (const [appName, app] of backendApps) {
|
|
1903
|
-
if (app.type !== "backend" || !app.routes) continue;
|
|
1904
|
-
const appPath = join(workspaceRoot, app.path);
|
|
1905
|
-
await runOpenApiInSubprocess(appPath, appName);
|
|
1906
|
-
}
|
|
1907
|
-
}
|
|
1908
|
-
} catch (error) {
|
|
1909
|
-
throw new Error(`OpenAPI generation failed: ${error.message}`);
|
|
1910
|
-
}
|
|
1911
|
-
}
|
|
1912
|
-
/**
|
|
1913
|
-
* Generate OpenAPI for a single named app within a workspace.
|
|
1914
|
-
* Runs in-process. The caller is responsible for ensuring `process.cwd()`
|
|
1915
|
-
* is the app's directory so tsx loads the app's tsconfig path aliases.
|
|
1916
|
-
*/
|
|
1917
|
-
async function generateOpenApiForApp(workspaceRoot, _appName, app) {
|
|
1918
|
-
if (app.type !== "backend" || !app.routes) return null;
|
|
1919
|
-
const appPath = join(workspaceRoot, app.path);
|
|
1920
|
-
const routes = normalizeRoutes(app.routes);
|
|
1921
|
-
const routesGlob = routes.map((r) => join(appPath, r));
|
|
1922
|
-
const gkmConfig = {
|
|
1923
|
-
routes: routesGlob,
|
|
1924
|
-
envParser: app.envParser || "",
|
|
1925
|
-
logger: app.logger || "",
|
|
1926
|
-
openapi: app.openapi
|
|
1927
|
-
};
|
|
1928
|
-
return generateOpenApi(gkmConfig, { silent: true });
|
|
1929
|
-
}
|
|
1930
|
-
/**
|
|
1931
|
-
* Resolve the gkm bin path. Tests can override via `GKM_BIN_PATH` env var
|
|
1932
|
-
* to avoid depending on the built dist.
|
|
1933
|
-
*/
|
|
1934
|
-
function resolveGkmBinPath() {
|
|
1935
|
-
if (process.env.GKM_BIN_PATH) return process.env.GKM_BIN_PATH;
|
|
1936
|
-
return fileURLToPath(new URL("../bin/gkm.mjs", import.meta.url));
|
|
1937
|
-
}
|
|
1938
|
-
/**
|
|
1939
|
-
* Spawn a subprocess that runs `gkm openapi --app <name>` with `cwd` set to
|
|
1940
|
-
* the app's directory. Inherits `NODE_OPTIONS` (which already contains
|
|
1941
|
-
* `--import tsx`), so the child gets a fresh tsx instance whose tsconfig
|
|
1942
|
-
* discovery picks up the app's tsconfig path aliases.
|
|
1943
|
-
*/
|
|
1944
|
-
async function runOpenApiInSubprocess(appCwd, appName) {
|
|
1945
|
-
const binPath = resolveGkmBinPath();
|
|
1946
|
-
await new Promise((resolve$1, reject) => {
|
|
1947
|
-
const child = spawn(process.execPath, [
|
|
1948
|
-
binPath,
|
|
1949
|
-
"openapi",
|
|
1950
|
-
"--app",
|
|
1951
|
-
appName
|
|
1952
|
-
], {
|
|
1953
|
-
cwd: appCwd,
|
|
1954
|
-
stdio: "inherit",
|
|
1955
|
-
env: process.env
|
|
1956
|
-
});
|
|
1957
|
-
child.on("error", reject);
|
|
1958
|
-
child.on("close", (code) => {
|
|
1959
|
-
if (code === 0) resolve$1();
|
|
1960
|
-
else reject(new Error(`OpenAPI generation for app "${appName}" exited with code ${code}`));
|
|
1961
|
-
});
|
|
1962
|
-
});
|
|
1963
|
-
}
|
|
1769
|
+
export { EndpointGenerator as n, runtimeFor as r, OpenApiTsGenerator as t };
|
|
1964
1770
|
|
|
1965
|
-
//#
|
|
1966
|
-
export { EndpointGenerator, OPENAPI_OUTPUT_PATH, generateOpenApi, normalizeRoutes, openapiCommand, resolveOpenApiConfig };
|
|
1967
|
-
//# sourceMappingURL=openapi-kkQbsRVj.mjs.map
|
|
1771
|
+
//# sourceMappingURL=OpenApiTsGenerator-BzIGy8KE.mjs.map
|