@geekmidas/cli 10.0.0-alpha.3 → 10.0.0-alpha.31
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 +25 -48
- package/bin/adjacent-tsconfig.mjs +97 -0
- package/bin/gkm.mjs +7 -1
- 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-c9bpieI5.cjs → OpenApiTsGenerator-D1nhN98m.cjs} +135 -298
- package/dist/OpenApiTsGenerator-D1nhN98m.cjs.map +1 -0
- package/dist/{openapi-CY9xFkTH.mjs → OpenApiTsGenerator-hDINScnz.mjs} +106 -250
- package/dist/OpenApiTsGenerator-hDINScnz.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/{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-CYF5mWi9.cjs} +10 -28
- package/dist/bundler-CYF5mWi9.cjs.map +1 -0
- package/dist/{bundler-Be8Zg4Wd.mjs → bundler-D9IPNvDt.mjs} +9 -26
- package/dist/bundler-D9IPNvDt.mjs.map +1 -0
- package/dist/{config-CzWnfcXM.mjs → config-BH3Ki69F.mjs} +49 -89
- package/dist/config-BH3Ki69F.mjs.map +1 -0
- package/dist/{config-BholeD-0.cjs → config-URVD4bTj.cjs} +101 -148
- package/dist/config-URVD4bTj.cjs.map +1 -0
- package/dist/config.cjs +5 -5
- package/dist/config.d.cts +25 -17
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +25 -17
- 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-CMxesskG.mjs} +66 -22
- package/dist/discover-CMxesskG.mjs.map +1 -0
- package/dist/{discover-DTmFeloL.cjs → discover-CroTIm0K.cjs} +117 -66
- package/dist/discover-CroTIm0K.cjs.map +1 -0
- package/dist/{emit-CbcRolsa.cjs → emit-BdoPFjZf.cjs} +53 -36
- package/dist/emit-BdoPFjZf.cjs.map +1 -0
- package/dist/{emit-CiZS_5Ub.mjs → emit-Bzq7JsMP.mjs} +24 -6
- package/dist/emit-Bzq7JsMP.mjs.map +1 -0
- package/dist/github-B2fis34P.cjs +216 -0
- package/dist/github-B2fis34P.cjs.map +1 -0
- package/dist/github-BrDmlm1x.mjs +216 -0
- package/dist/github-BrDmlm1x.mjs.map +1 -0
- package/dist/{index-CHB4tSzX.d.cts → index-p89EzILa.d.mts} +4 -23
- package/dist/index-p89EzILa.d.mts.map +1 -0
- package/dist/{index-BThUzEIp.d.mts → index-rU9u761a.d.cts} +4 -23
- package/dist/index-rU9u761a.d.cts.map +1 -0
- package/dist/index.cjs +6028 -4452
- 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 +5922 -4367
- package/dist/index.mjs.map +1 -1
- package/dist/migrate-BuCx7tIv.cjs +498 -0
- package/dist/migrate-BuCx7tIv.cjs.map +1 -0
- package/dist/migrate-CBICVMAi.mjs +493 -0
- package/dist/migrate-CBICVMAi.mjs.map +1 -0
- package/dist/openapi.cjs +197 -8
- package/dist/openapi.cjs.map +1 -0
- package/dist/openapi.d.cts +47 -14
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +47 -14
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +191 -5
- package/dist/openapi.mjs.map +1 -0
- package/dist/ready-CvP3JVEw.mjs +355 -0
- package/dist/ready-CvP3JVEw.mjs.map +1 -0
- package/dist/ready-DXtNfk7v.cjs +390 -0
- package/dist/ready-DXtNfk7v.cjs.map +1 -0
- package/dist/reconcile/public.cjs +4 -4
- package/dist/reconcile/public.d.cts +27 -26
- package/dist/reconcile/public.d.cts.map +1 -1
- package/dist/reconcile/public.d.mts +27 -26
- package/dist/reconcile/public.d.mts.map +1 -1
- package/dist/reconcile/public.mjs +3 -4
- package/dist/reconcile-BxZTV2vl.cjs +332 -0
- package/dist/reconcile-BxZTV2vl.cjs.map +1 -0
- package/dist/reconcile-yNq6Shau.mjs +279 -0
- package/dist/reconcile-yNq6Shau.mjs.map +1 -0
- package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
- package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
- package/dist/ssm-BKN1Cg4z.mjs +60 -0
- package/dist/ssm-BKN1Cg4z.mjs.map +1 -0
- package/dist/ssm-FxeSAt35.cjs +60 -0
- package/dist/ssm-FxeSAt35.cjs.map +1 -0
- package/dist/{storage-Bi24WfoW.mjs → storage-BjTLjDDp.mjs} +22 -22
- package/dist/storage-BjTLjDDp.mjs.map +1 -0
- package/dist/{storage-BJmzYxt8.cjs → storage-C2JC31V9.cjs} +65 -84
- package/dist/storage-C2JC31V9.cjs.map +1 -0
- package/dist/types-CzK6hsXP.d.mts +6286 -0
- package/dist/types-CzK6hsXP.d.mts.map +1 -0
- package/dist/types-DOOAevjG.d.cts +6287 -0
- package/dist/types-DOOAevjG.d.cts.map +1 -0
- package/dist/vitest.cjs +61 -0
- package/dist/vitest.cjs.map +1 -0
- package/dist/vitest.d.cts +28 -0
- package/dist/vitest.d.cts.map +1 -0
- package/dist/vitest.d.mts +28 -0
- package/dist/vitest.d.mts.map +1 -0
- package/dist/vitest.mjs +61 -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-Bav3TVrP.cjs +6710 -0
- package/dist/workspace-Bav3TVrP.cjs.map +1 -0
- package/dist/{credentials-DQmbRnr1.cjs → workspace-BhiMkRuA.cjs} +2076 -1963
- package/dist/workspace-BhiMkRuA.cjs.map +1 -0
- package/dist/{credentials-BZcp3CGx.mjs → workspace-C97QUCIf.mjs} +1957 -1837
- package/dist/workspace-C97QUCIf.mjs.map +1 -0
- package/dist/workspace-T4IVGSoB.mjs +6538 -0
- package/dist/workspace-T4IVGSoB.mjs.map +1 -0
- package/package.json +45 -38
- 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-BholeD-0.cjs.map +0 -1
- package/dist/config-CzWnfcXM.mjs.map +0 -1
- package/dist/credentials-B5zRHdAl.mjs +0 -141
- package/dist/credentials-B5zRHdAl.mjs.map +0 -1
- package/dist/credentials-BZcp3CGx.mjs.map +0 -1
- package/dist/credentials-BapzjyV5.cjs +0 -195
- package/dist/credentials-BapzjyV5.cjs.map +0 -1
- package/dist/credentials-DQmbRnr1.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-CY9xFkTH.mjs.map +0 -1
- package/dist/openapi-c9bpieI5.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 +0 -37
- package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
- package/dist/reconcile-D0pimNiy.cjs +0 -37
- package/dist/reconcile-D0pimNiy.cjs.map +0 -1
- package/dist/setup-Bc73t0ve.mjs +0 -443
- package/dist/setup-Bc73t0ve.mjs.map +0 -1
- package/dist/setup-C48C9hto.cjs +0 -473
- package/dist/setup-C48C9hto.cjs.map +0 -1
- package/dist/setup-DCuudnCl.mjs +0 -11
- package/dist/setup-fG_ivuxO.cjs +0 -11
- package/dist/storage-BJmzYxt8.cjs.map +0 -1
- package/dist/storage-BM9hGpgv.cjs +0 -7
- 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-7FqprxuJ.mjs +0 -4323
- package/dist/workspace-7FqprxuJ.mjs.map +0 -1
- package/dist/workspace-BO_KWohI.cjs +0 -9
- package/dist/workspace-DK4WWJIn.mjs +0 -8
- package/dist/workspace-XvqO9jIv.cjs +0 -4472
- package/dist/workspace-XvqO9jIv.cjs.map +0 -1
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { ConstructGenerator
|
|
2
|
-
import { loadWorkspaceConfig } from "./config-CzWnfcXM.mjs";
|
|
3
|
-
import { dirname, join, relative } from "node:path";
|
|
1
|
+
import { i as ConstructGenerator } from "./discover-CMxesskG.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) {
|
|
@@ -734,8 +720,7 @@ var EndpointGenerator = class extends ConstructGenerator {
|
|
|
734
720
|
async generateHandlerFile(outputDir, sourceFile, exportName, provider, _endpoint, context) {
|
|
735
721
|
const handlerFileName = `${exportName}.ts`;
|
|
736
722
|
const handlerPath = join(outputDir, handlerFileName);
|
|
737
|
-
const
|
|
738
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
723
|
+
const importPath = relative(dirname(handlerPath), sourceFile).replace(/\.ts$/, ".js");
|
|
739
724
|
let content;
|
|
740
725
|
switch (provider) {
|
|
741
726
|
case "aws-apigatewayv1":
|
|
@@ -753,12 +738,10 @@ var EndpointGenerator = class extends ConstructGenerator {
|
|
|
753
738
|
return handlerPath;
|
|
754
739
|
}
|
|
755
740
|
async generateEndpointsFile(outputDir, endpoints, context) {
|
|
756
|
-
const
|
|
757
|
-
const endpointsPath = join(outputDir, endpointsFileName);
|
|
741
|
+
const endpointsPath = join(outputDir, "endpoints.ts");
|
|
758
742
|
const importsByFile = /* @__PURE__ */ new Map();
|
|
759
743
|
for (const { path, key } of endpoints) {
|
|
760
|
-
const
|
|
761
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
744
|
+
const importPath = relative(dirname(endpointsPath), path.relative).replace(/\.ts$/, ".js");
|
|
762
745
|
if (!importsByFile.has(importPath)) importsByFile.set(importPath, []);
|
|
763
746
|
importsByFile.get(importPath)?.push(key);
|
|
764
747
|
}
|
|
@@ -824,11 +807,9 @@ export async function setupEndpoints(
|
|
|
824
807
|
const analyses = endpoints.map(({ key, construct }) => analyzeEndpoint(construct, key));
|
|
825
808
|
const endpointImports = endpoints.map(({ key, path }) => {
|
|
826
809
|
const tierDir = join(endpointsDir, "standard");
|
|
827
|
-
const relativePath = relative(tierDir, path.relative);
|
|
828
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
829
810
|
return {
|
|
830
811
|
exportName: key,
|
|
831
|
-
importPath
|
|
812
|
+
importPath: relative(tierDir, path.relative).replace(/\.ts$/, ".js")
|
|
832
813
|
};
|
|
833
814
|
});
|
|
834
815
|
const summary = summarizeAnalysis(analyses);
|
|
@@ -850,8 +831,7 @@ export async function setupEndpoints(
|
|
|
850
831
|
}
|
|
851
832
|
async generateAppFile(outputDir, context) {
|
|
852
833
|
if (context.production?.enabled) return this.generateProductionAppFile(outputDir, context);
|
|
853
|
-
const
|
|
854
|
-
const appPath = join(outputDir, appFileName);
|
|
834
|
+
const appPath = join(outputDir, "app.ts");
|
|
855
835
|
const runtime = runtimeFor(context, dirname(appPath));
|
|
856
836
|
const telescopeEnabled = context.telescope?.enabled;
|
|
857
837
|
const telescopeWebSocketEnabled = context.telescope?.websocket;
|
|
@@ -861,32 +841,36 @@ export async function setupEndpoints(
|
|
|
861
841
|
const studioFromDatabase = !usesExternalStudio && !!context.studio?.database;
|
|
862
842
|
const telescopeFromSurface = !!context.surface?.module && !usesExternalTelescope;
|
|
863
843
|
let telescopeImports = "";
|
|
864
|
-
if (telescopeEnabled)
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
844
|
+
if (telescopeEnabled) {
|
|
845
|
+
if (telescopeFromSurface) telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
|
|
846
|
+
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
847
|
+
else if (usesExternalTelescope) {
|
|
848
|
+
const relativeTelescopePath = relative(dirname(appPath), context.telescope?.telescopePath);
|
|
849
|
+
telescopeImports = `import ${context.telescope?.telescopeImportPattern} from '${relativeTelescopePath}';
|
|
868
850
|
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
869
|
-
|
|
851
|
+
} else telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
|
|
870
852
|
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
853
|
+
}
|
|
871
854
|
let studioImports = "";
|
|
872
|
-
if (studioEnabled)
|
|
873
|
-
|
|
874
|
-
|
|
855
|
+
if (studioEnabled) {
|
|
856
|
+
if (usesExternalStudio) {
|
|
857
|
+
const relativeStudioPath = relative(dirname(appPath), context.studio?.studioPath);
|
|
858
|
+
studioImports = `import ${context.studio?.studioImportPattern} from '${relativeStudioPath}';
|
|
875
859
|
import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
860
|
+
} else if (studioFromDatabase) {
|
|
861
|
+
const dbSpecifier = importSpecifier(dirname(appPath), context.studio.database.specifier);
|
|
862
|
+
studioImports = `import { snifferContext } from '@geekmidas/constructs';
|
|
879
863
|
import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';
|
|
880
864
|
import { ${context.studio.database.exportName} as __studioDb } from '${dbSpecifier}';
|
|
881
865
|
import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
882
|
-
|
|
866
|
+
} else studioImports = "";
|
|
867
|
+
}
|
|
883
868
|
const cors = corsFor(context.surface);
|
|
884
869
|
let hooksImports = "";
|
|
885
870
|
let beforeSetupCall = "";
|
|
886
871
|
let afterSetupCall = "";
|
|
887
872
|
if (context.hooks?.serverHooksPath) {
|
|
888
|
-
|
|
889
|
-
hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
|
|
873
|
+
hooksImports = `import * as serverHooks from '${relative(dirname(appPath), context.hooks.serverHooksPath)}';`;
|
|
890
874
|
beforeSetupCall = `
|
|
891
875
|
// Call beforeSetup hook if defined
|
|
892
876
|
if (typeof serverHooks.beforeSetup === 'function') {
|
|
@@ -932,7 +916,8 @@ import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
|
932
916
|
}
|
|
933
917
|
` : "";
|
|
934
918
|
let telescopeSetup = "";
|
|
935
|
-
if (telescopeEnabled)
|
|
919
|
+
if (telescopeEnabled) {
|
|
920
|
+
if (telescopeFromSurface || usesExternalTelescope) telescopeSetup = `
|
|
936
921
|
${telescopeWebSocketSetupCode}
|
|
937
922
|
// Add telescope middleware (before endpoints to capture all requests)
|
|
938
923
|
honoApp.use('*', createMiddleware(telescope));
|
|
@@ -941,7 +926,7 @@ ${telescopeWebSocketSetupCode}
|
|
|
941
926
|
const telescopeUI = createUI(telescope);
|
|
942
927
|
honoApp.route('${context.telescope?.path}', telescopeUI);
|
|
943
928
|
`;
|
|
944
|
-
|
|
929
|
+
else telescopeSetup = `
|
|
945
930
|
// Setup Telescope for debugging/monitoring
|
|
946
931
|
const telescopeStorage = new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} });
|
|
947
932
|
const telescope = new Telescope({
|
|
@@ -959,6 +944,7 @@ ${telescopeWebSocketSetupCode}
|
|
|
959
944
|
const telescopeUI = createUI(telescope);
|
|
960
945
|
honoApp.route('${context.telescope?.path}', telescopeUI);
|
|
961
946
|
`;
|
|
947
|
+
}
|
|
962
948
|
let studioSetup = "";
|
|
963
949
|
if (studioEnabled && studioFromDatabase) studioSetup = `
|
|
964
950
|
// Studio, built from the declared database. The client comes from the
|
|
@@ -992,6 +978,7 @@ import type { Hono as HonoType } from 'hono';
|
|
|
992
978
|
import { setupEndpoints } from './endpoints.js';
|
|
993
979
|
import { setupSubscribers } from './subscribers.js';
|
|
994
980
|
import { setupQueues } from './queues.js';
|
|
981
|
+
import { setupCrons } from './crons.js';
|
|
995
982
|
${runtime.imports}
|
|
996
983
|
${telescopeImports}
|
|
997
984
|
${studioImports}
|
|
@@ -1000,7 +987,16 @@ ${cors.imports}
|
|
|
1000
987
|
${context.storageDrivers?.imports ?? ""}
|
|
1001
988
|
|
|
1002
989
|
${runtime.bindings}
|
|
1003
|
-
${telescopeFromSurface ?
|
|
990
|
+
${telescopeEnabled && telescopeFromSurface ? `// The surface's own Telescope, or the one \`telescope\` config describes.
|
|
991
|
+
const telescope =
|
|
992
|
+
__surface.telescope ??
|
|
993
|
+
new Telescope({
|
|
994
|
+
enabled: true,
|
|
995
|
+
path: '${context.telescope?.path}',
|
|
996
|
+
ignorePatterns: ${JSON.stringify(context.telescope?.ignore)},
|
|
997
|
+
recordBody: ${context.telescope?.recordBody},
|
|
998
|
+
storage: new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} }),
|
|
999
|
+
});` : ""}
|
|
1004
1000
|
|
|
1005
1001
|
${context.storageDrivers?.setup ? `// Which storage drivers exist is the entry point's decision: the scheme in
|
|
1006
1002
|
// each injected URL picks one, so no construct and no application module names
|
|
@@ -1079,6 +1075,12 @@ ${afterSetupCall}
|
|
|
1079
1075
|
logger.error({ error }, 'Failed to start queue workers');
|
|
1080
1076
|
});
|
|
1081
1077
|
|
|
1078
|
+
// Schedule this app's crons. Caught like the others: a scheduler that
|
|
1079
|
+
// cannot start is not a reason for the HTTP server not to.
|
|
1080
|
+
await setupCrons(envParser, logger).catch((error) => {
|
|
1081
|
+
logger.error({ error }, 'Failed to schedule crons');
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1082
1084
|
logger.info({ port }, 'Starting server');
|
|
1083
1085
|
|
|
1084
1086
|
// Start HTTP server using provided serve function
|
|
@@ -1147,10 +1149,8 @@ export const handler = ${exportName};
|
|
|
1147
1149
|
* No dev tools (Telescope, Studio, WebSocket), includes health checks and graceful shutdown
|
|
1148
1150
|
*/
|
|
1149
1151
|
async generateProductionAppFile(outputDir, context) {
|
|
1150
|
-
const
|
|
1151
|
-
const
|
|
1152
|
-
const relativeLoggerPath = relative(dirname(appPath), context.loggerPath);
|
|
1153
|
-
const relativeEnvParserPath = relative(dirname(appPath), context.envParserPath);
|
|
1152
|
+
const appPath = join(outputDir, "app.ts");
|
|
1153
|
+
const runtime = runtimeFor(context, dirname(appPath));
|
|
1154
1154
|
const production = context.production;
|
|
1155
1155
|
const healthCheckPath = production.healthCheck;
|
|
1156
1156
|
const enableGracefulShutdown = production.gracefulShutdown;
|
|
@@ -1161,8 +1161,7 @@ export const handler = ${exportName};
|
|
|
1161
1161
|
let beforeSetupCall = "";
|
|
1162
1162
|
let afterSetupCall = "";
|
|
1163
1163
|
if (context.hooks?.serverHooksPath) {
|
|
1164
|
-
|
|
1165
|
-
hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
|
|
1164
|
+
hooksImports = `import * as serverHooks from '${relative(dirname(appPath), context.hooks.serverHooksPath)}';`;
|
|
1166
1165
|
beforeSetupCall = `
|
|
1167
1166
|
// Call beforeSetup hook if defined
|
|
1168
1167
|
if (typeof serverHooks.beforeSetup === 'function') {
|
|
@@ -1186,9 +1185,16 @@ export const handler = ${exportName};
|
|
|
1186
1185
|
await setupQueues(envParser, logger).catch((error) => {
|
|
1187
1186
|
logger.error({ error }, 'Failed to start queue workers');
|
|
1188
1187
|
});
|
|
1188
|
+
|
|
1189
|
+
// Schedule this app's crons. Caught like the others: a scheduler that
|
|
1190
|
+
// cannot start is not a reason for the HTTP server not to.
|
|
1191
|
+
await setupCrons(envParser, logger).catch((error) => {
|
|
1192
|
+
logger.error({ error }, 'Failed to schedule crons');
|
|
1193
|
+
});
|
|
1189
1194
|
` : "";
|
|
1190
1195
|
const subscriberImport = includeSubscribers ? `import { setupSubscribers } from './subscribers.js';
|
|
1191
|
-
import { setupQueues } from './queues.js'
|
|
1196
|
+
import { setupQueues } from './queues.js';
|
|
1197
|
+
import { setupCrons } from './crons.js';` : "";
|
|
1192
1198
|
const gracefulShutdownCode = enableGracefulShutdown ? `
|
|
1193
1199
|
// Graceful shutdown handling
|
|
1194
1200
|
let isShuttingDown = false;
|
|
@@ -1204,7 +1210,6 @@ import { setupQueues } from './queues.js';` : "";
|
|
|
1204
1210
|
process.on('SIGTERM', shutdown);
|
|
1205
1211
|
process.on('SIGINT', shutdown);
|
|
1206
1212
|
` : "";
|
|
1207
|
-
const endpointsImportPath = production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js";
|
|
1208
1213
|
const content = `/**
|
|
1209
1214
|
* Generated production server application
|
|
1210
1215
|
*
|
|
@@ -1216,10 +1221,10 @@ import { setupQueues } from './queues.js';` : "";
|
|
|
1216
1221
|
*/
|
|
1217
1222
|
import { Hono } from 'hono';
|
|
1218
1223
|
import type { Hono as HonoType } from 'hono';
|
|
1219
|
-
import { setupEndpoints } from '${
|
|
1224
|
+
import { setupEndpoints } from '${production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js"}';
|
|
1220
1225
|
${subscriberImport}
|
|
1221
|
-
|
|
1222
|
-
|
|
1226
|
+
${runtime.imports}
|
|
1227
|
+
${runtime.bindings}
|
|
1223
1228
|
${hooksImports}
|
|
1224
1229
|
${cors.imports}
|
|
1225
1230
|
${context.storageDrivers?.imports ?? ""}
|
|
@@ -1283,7 +1288,7 @@ export default createApp;
|
|
|
1283
1288
|
*/
|
|
1284
1289
|
async generateProductionServerEntry(outputDir) {
|
|
1285
1290
|
const serverPath = join(outputDir, "server.ts");
|
|
1286
|
-
|
|
1291
|
+
await writeFile(serverPath, `#!/usr/bin/env node
|
|
1287
1292
|
/**
|
|
1288
1293
|
* Production server entry point
|
|
1289
1294
|
* Generated by 'gkm build --provider server --production'
|
|
@@ -1299,11 +1304,9 @@ await start({
|
|
|
1299
1304
|
port,
|
|
1300
1305
|
serve: (app, port) => { serve({ fetch: app.fetch, port }); },
|
|
1301
1306
|
});
|
|
1302
|
-
|
|
1303
|
-
await writeFile(serverPath, content);
|
|
1307
|
+
`);
|
|
1304
1308
|
}
|
|
1305
1309
|
};
|
|
1306
|
-
|
|
1307
1310
|
//#endregion
|
|
1308
1311
|
//#region src/generators/OpenApiTsGenerator.ts
|
|
1309
1312
|
/**
|
|
@@ -1458,7 +1461,7 @@ var OpenApiTsGenerator = class {
|
|
|
1458
1461
|
for (const [rawName, rawSchema] of Object.entries(registrySchemas)) {
|
|
1459
1462
|
const defName = this.pascalCase(rawName);
|
|
1460
1463
|
if (collectedDefs.has(defName) || generatedNames.has(defName)) continue;
|
|
1461
|
-
const { id: _id, $defs: _defs
|
|
1464
|
+
const { id: _id, $defs: _defs, ...rest } = rawSchema;
|
|
1462
1465
|
collectedDefs.set(defName, rest);
|
|
1463
1466
|
}
|
|
1464
1467
|
for (const [defName, defSchema] of collectedDefs) if (!generatedNames.has(defName)) {
|
|
@@ -1494,27 +1497,29 @@ var OpenApiTsGenerator = class {
|
|
|
1494
1497
|
async schemaToInterfaceWithDefs(schema, name, collectedDefs) {
|
|
1495
1498
|
try {
|
|
1496
1499
|
const vendor = schema["~standard"]?.vendor;
|
|
1497
|
-
if (!vendor || !(vendor in StandardSchemaJsonSchema)) return
|
|
1500
|
+
if (!vendor || !(vendor in StandardSchemaJsonSchema)) return unknownType(name);
|
|
1498
1501
|
const toJsonSchema = StandardSchemaJsonSchema[vendor];
|
|
1499
1502
|
const jsonSchema = await toJsonSchema(schema);
|
|
1500
|
-
if (!jsonSchema) return
|
|
1503
|
+
if (!jsonSchema) return unknownType(name);
|
|
1501
1504
|
if (jsonSchema.$defs && typeof jsonSchema.$defs === "object") {
|
|
1502
1505
|
for (const [defName, defSchema] of Object.entries(jsonSchema.$defs)) if (!collectedDefs.has(defName)) {
|
|
1503
|
-
const { id
|
|
1506
|
+
const { id, ...schemaWithoutId } = defSchema;
|
|
1504
1507
|
collectedDefs.set(defName, schemaWithoutId);
|
|
1505
1508
|
}
|
|
1506
1509
|
}
|
|
1507
|
-
const { $defs
|
|
1510
|
+
const { $defs, ...schemaWithoutDefs } = jsonSchema;
|
|
1511
|
+
const ref = schemaWithoutDefs.$ref;
|
|
1512
|
+
if (ref && Object.keys(schemaWithoutDefs).every((k) => k === "$ref" || k === "$schema")) {
|
|
1513
|
+
const target = ref.split("/").pop();
|
|
1514
|
+
return target === name ? null : `export type ${name} = ${target};`;
|
|
1515
|
+
}
|
|
1508
1516
|
return this.jsonSchemaToInterface(schemaWithoutDefs, name);
|
|
1509
1517
|
} catch {
|
|
1510
|
-
return
|
|
1518
|
+
return unknownType(name);
|
|
1511
1519
|
}
|
|
1512
1520
|
}
|
|
1513
1521
|
jsonSchemaToInterface(schema, name) {
|
|
1514
|
-
if (schema.type !== "object" || !schema.properties) {
|
|
1515
|
-
const typeStr = this.jsonSchemaTypeToTs(schema);
|
|
1516
|
-
return `export type ${name} = ${typeStr};`;
|
|
1517
|
-
}
|
|
1522
|
+
if (schema.type !== "object" || !schema.properties) return `export type ${name} = ${this.jsonSchemaTypeToTs(schema)};`;
|
|
1518
1523
|
const props = [];
|
|
1519
1524
|
const required = new Set(schema.required || []);
|
|
1520
1525
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
@@ -1527,13 +1532,15 @@ var OpenApiTsGenerator = class {
|
|
|
1527
1532
|
}
|
|
1528
1533
|
jsonSchemaTypeToTs(schema) {
|
|
1529
1534
|
if (!schema) return "unknown";
|
|
1530
|
-
if (schema.$ref)
|
|
1531
|
-
|
|
1532
|
-
return refName;
|
|
1533
|
-
}
|
|
1535
|
+
if (schema.$ref) return schema.$ref.split("/").pop() || "unknown";
|
|
1536
|
+
if (schema.const !== void 0) return typeof schema.const === "string" ? `'${schema.const}'` : String(schema.const);
|
|
1534
1537
|
if (schema.anyOf) return schema.anyOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
|
|
1535
1538
|
if (schema.oneOf) return schema.oneOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
|
|
1536
1539
|
if (schema.allOf) return schema.allOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" & ");
|
|
1540
|
+
if (Array.isArray(schema.type)) return schema.type.map((type) => this.jsonSchemaTypeToTs({
|
|
1541
|
+
...schema,
|
|
1542
|
+
type
|
|
1543
|
+
})).join(" | ");
|
|
1537
1544
|
switch (schema.type) {
|
|
1538
1545
|
case "string":
|
|
1539
1546
|
if (schema.enum) return schema.enum.map((e) => `'${e}'`).join(" | ");
|
|
@@ -1557,10 +1564,7 @@ var OpenApiTsGenerator = class {
|
|
|
1557
1564
|
}
|
|
1558
1565
|
return `{ ${props.join("; ")} }`;
|
|
1559
1566
|
}
|
|
1560
|
-
if (schema.additionalProperties) {
|
|
1561
|
-
const valueType = this.jsonSchemaTypeToTs(schema.additionalProperties);
|
|
1562
|
-
return `Record<string, ${valueType}>`;
|
|
1563
|
-
}
|
|
1567
|
+
if (schema.additionalProperties) return `Record<string, ${this.jsonSchemaTypeToTs(schema.additionalProperties)}>`;
|
|
1564
1568
|
return "Record<string, unknown>";
|
|
1565
1569
|
default: return "unknown";
|
|
1566
1570
|
}
|
|
@@ -1581,10 +1585,7 @@ var OpenApiTsGenerator = class {
|
|
|
1581
1585
|
}
|
|
1582
1586
|
const firstWithParams = infos.find((i) => i.input?.params);
|
|
1583
1587
|
let paramsEntry = "";
|
|
1584
|
-
if (firstWithParams?.input?.params) {
|
|
1585
|
-
const paramsName = await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`);
|
|
1586
|
-
paramsEntry = `\n parameters: {\n path: ${paramsName};\n };`;
|
|
1587
|
-
}
|
|
1588
|
+
if (firstWithParams?.input?.params) paramsEntry = `\n parameters: {\n path: ${await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`)};\n };`;
|
|
1588
1589
|
pathEntries.push(` '${route}': {${paramsEntry}\n${methodEntries.join("\n")}\n };`);
|
|
1589
1590
|
}
|
|
1590
1591
|
return `export interface paths {\n${pathEntries.join("\n")}\n}`;
|
|
@@ -1623,8 +1624,7 @@ var OpenApiTsGenerator = class {
|
|
|
1623
1624
|
return acc;
|
|
1624
1625
|
}, {});
|
|
1625
1626
|
const schemeNames = securitySchemes.map((s) => `'${s.name}'`).join(" | ");
|
|
1626
|
-
const
|
|
1627
|
-
const createApiSection = hasSecuritySchemes ? `
|
|
1627
|
+
const createApiSection = schemeNames.length > 0 ? `
|
|
1628
1628
|
// ============================================================
|
|
1629
1629
|
// API Client Factory
|
|
1630
1630
|
// ============================================================
|
|
@@ -1648,6 +1648,8 @@ export interface CreateApiOptions {
|
|
|
1648
1648
|
queryClient?: QueryClient;
|
|
1649
1649
|
/** Optional request interceptor */
|
|
1650
1650
|
onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
|
|
1651
|
+
/** The \`fetch\` requests go out on — a test browser's, for one */
|
|
1652
|
+
fetch?: typeof fetch;
|
|
1651
1653
|
}
|
|
1652
1654
|
|
|
1653
1655
|
/**
|
|
@@ -1677,6 +1679,7 @@ export function createApi(options: CreateApiOptions) {
|
|
|
1677
1679
|
securitySchemes,
|
|
1678
1680
|
authStrategies: options.authStrategies,
|
|
1679
1681
|
onRequest: options.onRequest,
|
|
1682
|
+
...(options.fetch ? { fetch: options.fetch } : {}),
|
|
1680
1683
|
});
|
|
1681
1684
|
|
|
1682
1685
|
const hooks = createEndpointHooks<paths>(fetcher, { queryClient: options.queryClient });
|
|
@@ -1801,162 +1804,15 @@ ${createApiSection}
|
|
|
1801
1804
|
`;
|
|
1802
1805
|
}
|
|
1803
1806
|
};
|
|
1804
|
-
|
|
1805
|
-
//#endregion
|
|
1806
|
-
//#region src/workspace/client-generator.ts
|
|
1807
1807
|
/**
|
|
1808
|
-
*
|
|
1809
|
-
*
|
|
1810
|
-
*
|
|
1808
|
+
* The declaration for a schema that cannot be converted — a vendor with no
|
|
1809
|
+
* converter, or one that fails. The paths interface names it either way, so
|
|
1810
|
+
* leaving it undeclared made the generated client fail to compile.
|
|
1811
1811
|
*/
|
|
1812
|
-
function
|
|
1813
|
-
|
|
1814
|
-
if (isPartitionedRoutes(routes)) return Array.isArray(routes.paths) ? routes.paths : [routes.paths];
|
|
1815
|
-
return Array.isArray(routes) ? routes : [routes];
|
|
1812
|
+
function unknownType(name) {
|
|
1813
|
+
return `export type ${name} = unknown;`;
|
|
1816
1814
|
}
|
|
1817
|
-
|
|
1818
1815
|
//#endregion
|
|
1819
|
-
|
|
1820
|
-
/**
|
|
1821
|
-
* Default output path for generated OpenAPI client (used for single-app configs)
|
|
1822
|
-
*/
|
|
1823
|
-
const OPENAPI_OUTPUT_PATH = "./.gkm/openapi.ts";
|
|
1824
|
-
/**
|
|
1825
|
-
* Resolve OpenAPI config from GkmConfig
|
|
1826
|
-
*/
|
|
1827
|
-
function resolveOpenApiConfig(config) {
|
|
1828
|
-
if (config.openapi === false) return { enabled: false };
|
|
1829
|
-
if (config.openapi === true || config.openapi === void 0) return {
|
|
1830
|
-
enabled: true,
|
|
1831
|
-
title: "API Documentation",
|
|
1832
|
-
version: "1.0.0",
|
|
1833
|
-
description: "Auto-generated API documentation from endpoints"
|
|
1834
|
-
};
|
|
1835
|
-
return {
|
|
1836
|
-
enabled: config.openapi.enabled !== false,
|
|
1837
|
-
title: config.openapi.title || "API Documentation",
|
|
1838
|
-
version: config.openapi.version || "1.0.0",
|
|
1839
|
-
description: config.openapi.description || "Auto-generated API documentation from endpoints"
|
|
1840
|
-
};
|
|
1841
|
-
}
|
|
1842
|
-
/**
|
|
1843
|
-
* Generate OpenAPI spec from endpoints
|
|
1844
|
-
* @returns Object with output path and endpoint count, or null if disabled
|
|
1845
|
-
*/
|
|
1846
|
-
async function generateOpenApi(config, options = {}) {
|
|
1847
|
-
const logger = options.silent ? { log: () => {} } : console;
|
|
1848
|
-
const openApiConfig = resolveOpenApiConfig(config);
|
|
1849
|
-
if (!openApiConfig.enabled) return null;
|
|
1850
|
-
const endpointGenerator = new EndpointGenerator();
|
|
1851
|
-
const loadedEndpoints = await endpointGenerator.load(config.routes, void 0, options.bustCache);
|
|
1852
|
-
if (loadedEndpoints.length === 0) {
|
|
1853
|
-
logger.log("No valid endpoints found for OpenAPI generation");
|
|
1854
|
-
return null;
|
|
1855
|
-
}
|
|
1856
|
-
const endpoints = loadedEndpoints.map(({ construct }) => construct);
|
|
1857
|
-
const outputPath = join(process.cwd(), OPENAPI_OUTPUT_PATH);
|
|
1858
|
-
await mkdir(dirname(outputPath), { recursive: true });
|
|
1859
|
-
const tsGenerator = new OpenApiTsGenerator();
|
|
1860
|
-
const tsContent = await tsGenerator.generate(endpoints, {
|
|
1861
|
-
title: openApiConfig.title,
|
|
1862
|
-
version: openApiConfig.version,
|
|
1863
|
-
description: openApiConfig.description
|
|
1864
|
-
});
|
|
1865
|
-
await writeFile(outputPath, tsContent);
|
|
1866
|
-
logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);
|
|
1867
|
-
return {
|
|
1868
|
-
outputPath,
|
|
1869
|
-
endpointCount: loadedEndpoints.length
|
|
1870
|
-
};
|
|
1871
|
-
}
|
|
1872
|
-
async function openapiCommand(options = {}) {
|
|
1873
|
-
const logger = console;
|
|
1874
|
-
try {
|
|
1875
|
-
const loadedConfig = await loadWorkspaceConfig(options.cwd);
|
|
1876
|
-
if (loadedConfig.type === "single") {
|
|
1877
|
-
const config = loadedConfig.raw;
|
|
1878
|
-
if (!config.openapi) config.openapi = { enabled: true };
|
|
1879
|
-
const result = await generateOpenApi(config);
|
|
1880
|
-
if (result) logger.log(`Found ${result.endpointCount} endpoints`);
|
|
1881
|
-
} else {
|
|
1882
|
-
const { workspace } = loadedConfig;
|
|
1883
|
-
const workspaceRoot = workspace.root;
|
|
1884
|
-
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));
|
|
1885
|
-
if (backendApps.length === 0) {
|
|
1886
|
-
logger.log("No backend apps with OpenAPI enabled found");
|
|
1887
|
-
return;
|
|
1888
|
-
}
|
|
1889
|
-
if (options.app) {
|
|
1890
|
-
const entry = backendApps.find(([name]) => name === options.app);
|
|
1891
|
-
if (!entry) throw new Error(`App "${options.app}" not found or has OpenAPI disabled`);
|
|
1892
|
-
const [appName, app] = entry;
|
|
1893
|
-
const result = await generateOpenApiForApp(workspaceRoot, appName, app);
|
|
1894
|
-
if (result) logger.log(`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`);
|
|
1895
|
-
return;
|
|
1896
|
-
}
|
|
1897
|
-
for (const [appName, app] of backendApps) {
|
|
1898
|
-
if (app.type !== "backend" || !app.routes) continue;
|
|
1899
|
-
const appPath = join(workspaceRoot, app.path);
|
|
1900
|
-
await runOpenApiInSubprocess(appPath, appName);
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
} catch (error) {
|
|
1904
|
-
throw new Error(`OpenAPI generation failed: ${error.message}`);
|
|
1905
|
-
}
|
|
1906
|
-
}
|
|
1907
|
-
/**
|
|
1908
|
-
* Generate OpenAPI for a single named app within a workspace.
|
|
1909
|
-
* Runs in-process. The caller is responsible for ensuring `process.cwd()`
|
|
1910
|
-
* is the app's directory so tsx loads the app's tsconfig path aliases.
|
|
1911
|
-
*/
|
|
1912
|
-
async function generateOpenApiForApp(workspaceRoot, _appName, app) {
|
|
1913
|
-
if (app.type !== "backend" || !app.routes) return null;
|
|
1914
|
-
const appPath = join(workspaceRoot, app.path);
|
|
1915
|
-
const routes = normalizeRoutes(app.routes);
|
|
1916
|
-
const routesGlob = routes.map((r) => join(appPath, r));
|
|
1917
|
-
const gkmConfig = {
|
|
1918
|
-
routes: routesGlob,
|
|
1919
|
-
envParser: app.envParser || "",
|
|
1920
|
-
logger: app.logger || "",
|
|
1921
|
-
openapi: app.openapi
|
|
1922
|
-
};
|
|
1923
|
-
return generateOpenApi(gkmConfig, { silent: true });
|
|
1924
|
-
}
|
|
1925
|
-
/**
|
|
1926
|
-
* Resolve the gkm bin path. Tests can override via `GKM_BIN_PATH` env var
|
|
1927
|
-
* to avoid depending on the built dist.
|
|
1928
|
-
*/
|
|
1929
|
-
function resolveGkmBinPath() {
|
|
1930
|
-
if (process.env.GKM_BIN_PATH) return process.env.GKM_BIN_PATH;
|
|
1931
|
-
return fileURLToPath(new URL("../bin/gkm.mjs", import.meta.url));
|
|
1932
|
-
}
|
|
1933
|
-
/**
|
|
1934
|
-
* Spawn a subprocess that runs `gkm openapi --app <name>` with `cwd` set to
|
|
1935
|
-
* the app's directory. Inherits `NODE_OPTIONS` (which already contains
|
|
1936
|
-
* `--import tsx`), so the child gets a fresh tsx instance whose tsconfig
|
|
1937
|
-
* discovery picks up the app's tsconfig path aliases.
|
|
1938
|
-
*/
|
|
1939
|
-
async function runOpenApiInSubprocess(appCwd, appName) {
|
|
1940
|
-
const binPath = resolveGkmBinPath();
|
|
1941
|
-
await new Promise((resolve$1, reject) => {
|
|
1942
|
-
const child = spawn(process.execPath, [
|
|
1943
|
-
binPath,
|
|
1944
|
-
"openapi",
|
|
1945
|
-
"--app",
|
|
1946
|
-
appName
|
|
1947
|
-
], {
|
|
1948
|
-
cwd: appCwd,
|
|
1949
|
-
stdio: "inherit",
|
|
1950
|
-
env: process.env
|
|
1951
|
-
});
|
|
1952
|
-
child.on("error", reject);
|
|
1953
|
-
child.on("close", (code) => {
|
|
1954
|
-
if (code === 0) resolve$1();
|
|
1955
|
-
else reject(new Error(`OpenAPI generation for app "${appName}" exited with code ${code}`));
|
|
1956
|
-
});
|
|
1957
|
-
});
|
|
1958
|
-
}
|
|
1816
|
+
export { EndpointGenerator as n, runtimeFor as r, OpenApiTsGenerator as t };
|
|
1959
1817
|
|
|
1960
|
-
//#
|
|
1961
|
-
export { EndpointGenerator, OPENAPI_OUTPUT_PATH, generateOpenApi, normalizeRoutes, openapiCommand, resolveOpenApiConfig };
|
|
1962
|
-
//# sourceMappingURL=openapi-CY9xFkTH.mjs.map
|
|
1818
|
+
//# sourceMappingURL=OpenApiTsGenerator-hDINScnz.mjs.map
|