@geekmidas/cli 10.0.0-alpha.3 → 10.0.0-alpha.30
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 +6001 -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 +5895 -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,13 +1,8 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const node_child_process = require_chunk.__toESM(require("node:child_process"));
|
|
7
|
-
const __geekmidas_constructs_endpoints = require_chunk.__toESM(require("@geekmidas/constructs/endpoints"));
|
|
8
|
-
const node_url = require_chunk.__toESM(require("node:url"));
|
|
9
|
-
const __geekmidas_schema_conversion = require_chunk.__toESM(require("@geekmidas/schema/conversion"));
|
|
10
|
-
|
|
1
|
+
const require_discover = require("./discover-CroTIm0K.cjs");
|
|
2
|
+
let node_fs_promises = require("node:fs/promises");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
let _geekmidas_constructs_endpoints = require("@geekmidas/constructs/endpoints");
|
|
5
|
+
let _geekmidas_schema_conversion = require("@geekmidas/schema/conversion");
|
|
11
6
|
//#region src/build/endpoint-analyzer.ts
|
|
12
7
|
/**
|
|
13
8
|
* Analyze an endpoint to extract its features
|
|
@@ -84,7 +79,6 @@ function summarizeAnalysis(analyses) {
|
|
|
84
79
|
byFeature
|
|
85
80
|
};
|
|
86
81
|
}
|
|
87
|
-
|
|
88
82
|
//#endregion
|
|
89
83
|
//#region src/build/handler-templates.ts
|
|
90
84
|
/**
|
|
@@ -106,8 +100,7 @@ function generateMinimalHandler(analysis) {
|
|
|
106
100
|
const { exportName, features } = analysis;
|
|
107
101
|
const method = analysis.method.toLowerCase();
|
|
108
102
|
const validators = generateValidators(exportName, features);
|
|
109
|
-
|
|
110
|
-
if (!hasValidators && !features.hasOutputValidation) return `
|
|
103
|
+
if (!(validators.length > 0) && !features.hasOutputValidation) return `
|
|
111
104
|
// Minimal handler: ${analysis.route} (${analysis.method})
|
|
112
105
|
app.${method}('${analysis.route}', async (c) => {
|
|
113
106
|
const result = await ${exportName}.handler(
|
|
@@ -255,10 +248,10 @@ function generateValidatorsFile(analyses) {
|
|
|
255
248
|
const needsQuery = analyses.some((a) => a.features.hasQueryValidation);
|
|
256
249
|
const needsParams = analyses.some((a) => a.features.hasParamValidation);
|
|
257
250
|
if (!needsBody && !needsQuery && !needsParams) return `// No validators needed for this build\nexport {};\n`;
|
|
258
|
-
const exports
|
|
251
|
+
const exports = [];
|
|
259
252
|
const factories = [];
|
|
260
253
|
if (needsBody) {
|
|
261
|
-
exports
|
|
254
|
+
exports.push("validateBody");
|
|
262
255
|
factories.push(`
|
|
263
256
|
export const validateBody = (endpoint: any) =>
|
|
264
257
|
validator('json', async (value, c) => {
|
|
@@ -269,7 +262,7 @@ export const validateBody = (endpoint: any) =>
|
|
|
269
262
|
});`);
|
|
270
263
|
}
|
|
271
264
|
if (needsQuery) {
|
|
272
|
-
exports
|
|
265
|
+
exports.push("validateQuery");
|
|
273
266
|
factories.push(`
|
|
274
267
|
export const validateQuery = (endpoint: any) =>
|
|
275
268
|
validator('query', async (_, c) => {
|
|
@@ -281,7 +274,7 @@ export const validateQuery = (endpoint: any) =>
|
|
|
281
274
|
});`);
|
|
282
275
|
}
|
|
283
276
|
if (needsParams) {
|
|
284
|
-
exports
|
|
277
|
+
exports.push("validateParams");
|
|
285
278
|
factories.push(`
|
|
286
279
|
export const validateParams = (endpoint: any) =>
|
|
287
280
|
validator('param', async (params, c) => {
|
|
@@ -305,8 +298,7 @@ ${factories.join("\n")}
|
|
|
305
298
|
*/
|
|
306
299
|
function generateMinimalEndpointFile(analysis, endpointImport) {
|
|
307
300
|
const { exportName, features } = analysis;
|
|
308
|
-
const
|
|
309
|
-
const validatorImport = needsValidators ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
301
|
+
const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
310
302
|
const handler = generateMinimalHandler(analysis);
|
|
311
303
|
return `/**
|
|
312
304
|
* Minimal endpoint: ${analysis.route} (${analysis.method})
|
|
@@ -331,8 +323,7 @@ ${handler}
|
|
|
331
323
|
*/
|
|
332
324
|
function generateStandardEndpointFile(analysis, endpointImport) {
|
|
333
325
|
const { exportName, features } = analysis;
|
|
334
|
-
const
|
|
335
|
-
const validatorImport = needsValidators ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
326
|
+
const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
|
|
336
327
|
const eventsImport = features.hasEvents ? `import { publishConstructEvents } from '@geekmidas/constructs/endpoints';` : "";
|
|
337
328
|
const handler = generateStandardHandler(analysis);
|
|
338
329
|
return `/**
|
|
@@ -424,7 +415,7 @@ export function setupFullEndpoints(
|
|
|
424
415
|
}
|
|
425
416
|
const imports = tierEndpoints.map((a) => `import { setup${capitalize(a.exportName)} } from './${a.exportName}.js';`).join("\n");
|
|
426
417
|
if (tier === "minimal") {
|
|
427
|
-
const calls
|
|
418
|
+
const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, logger);`).join("\n");
|
|
428
419
|
return `/**
|
|
429
420
|
* Minimal-tier endpoint index (${tierEndpoints.length} endpoints)
|
|
430
421
|
* Near-raw-Hono performance
|
|
@@ -437,12 +428,12 @@ export function setupMinimalEndpoints(
|
|
|
437
428
|
app: Hono,
|
|
438
429
|
logger: Logger,
|
|
439
430
|
): void {
|
|
440
|
-
${calls
|
|
431
|
+
${calls}
|
|
441
432
|
}
|
|
442
433
|
`;
|
|
443
434
|
}
|
|
444
435
|
if (tier === "standard") {
|
|
445
|
-
const calls
|
|
436
|
+
const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, serviceDiscovery, logger);`).join("\n");
|
|
446
437
|
return `/**
|
|
447
438
|
* Standard-tier endpoint index (${tierEndpoints.length} endpoints)
|
|
448
439
|
* Auth and/or services enabled
|
|
@@ -457,7 +448,7 @@ export function setupStandardEndpoints(
|
|
|
457
448
|
serviceDiscovery: ServiceDiscovery<any, any>,
|
|
458
449
|
logger: Logger,
|
|
459
450
|
): void {
|
|
460
|
-
${calls
|
|
451
|
+
${calls}
|
|
461
452
|
}
|
|
462
453
|
`;
|
|
463
454
|
}
|
|
@@ -527,9 +518,7 @@ function generateEndpointFilesNested(analyses, endpointImports) {
|
|
|
527
518
|
case "standard":
|
|
528
519
|
files[fileName] = generateStandardEndpointFile(analysis, endpointImport);
|
|
529
520
|
break;
|
|
530
|
-
case "full":
|
|
531
|
-
files[fileName] = generateFullEndpointFile(analysis, endpointImport);
|
|
532
|
-
break;
|
|
521
|
+
case "full": files[fileName] = generateFullEndpointFile(analysis, endpointImport);
|
|
533
522
|
}
|
|
534
523
|
}
|
|
535
524
|
return files;
|
|
@@ -586,7 +575,6 @@ export async function setupEndpoints(
|
|
|
586
575
|
}
|
|
587
576
|
`;
|
|
588
577
|
}
|
|
589
|
-
|
|
590
578
|
//#endregion
|
|
591
579
|
//#region src/generators/EndpointGenerator.ts
|
|
592
580
|
/**
|
|
@@ -603,24 +591,21 @@ export async function setupEndpoints(
|
|
|
603
591
|
*
|
|
604
592
|
* Falls back to the configured paths for an app that declares no surface.
|
|
605
593
|
*/
|
|
606
|
-
function runtimeFor(context, fromDir) {
|
|
607
|
-
const module
|
|
608
|
-
if (module
|
|
609
|
-
const specifier = importSpecifier(fromDir, module
|
|
594
|
+
function runtimeFor(context, fromDir, owner) {
|
|
595
|
+
const module = owner ? context.owners?.[owner] ?? context.surface?.module : context.surface?.module;
|
|
596
|
+
if (module) {
|
|
597
|
+
const specifier = importSpecifier(fromDir, module.specifier);
|
|
610
598
|
return {
|
|
611
|
-
imports: `import { ${module
|
|
599
|
+
imports: `import { ${module.exportName} as __surface } from '${specifier}';`,
|
|
612
600
|
bindings: [
|
|
613
|
-
"// What this
|
|
614
|
-
"// 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.",
|
|
615
603
|
"const envParser = __surface.envParser;",
|
|
616
604
|
"const logger = __surface.logger;"
|
|
617
605
|
].join("\n")
|
|
618
606
|
};
|
|
619
607
|
}
|
|
620
|
-
|
|
621
|
-
imports: [`import ${context.envParserImportPattern} from '${importSpecifier(fromDir, context.envParserPath)}';`, `import ${context.loggerImportPattern} from '${importSpecifier(fromDir, context.loggerPath)}';`].join("\n"),
|
|
622
|
-
bindings: ""
|
|
623
|
-
};
|
|
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\`.`);
|
|
624
609
|
}
|
|
625
610
|
/** A relative specifier ESM will accept: always prefixed, never bare. */
|
|
626
611
|
function importSpecifier(fromDir, target) {
|
|
@@ -679,7 +664,7 @@ function corsFor(surface) {
|
|
|
679
664
|
}
|
|
680
665
|
var EndpointGenerator = class extends require_discover.ConstructGenerator {
|
|
681
666
|
isConstruct(value) {
|
|
682
|
-
return
|
|
667
|
+
return _geekmidas_constructs_endpoints.Endpoint.isEndpoint(value);
|
|
683
668
|
}
|
|
684
669
|
async build(context, constructs, outputDir, options) {
|
|
685
670
|
const provider = options?.provider || "aws-apigatewayv2";
|
|
@@ -735,8 +720,7 @@ var EndpointGenerator = class extends require_discover.ConstructGenerator {
|
|
|
735
720
|
async generateHandlerFile(outputDir, sourceFile, exportName, provider, _endpoint, context) {
|
|
736
721
|
const handlerFileName = `${exportName}.ts`;
|
|
737
722
|
const handlerPath = (0, node_path.join)(outputDir, handlerFileName);
|
|
738
|
-
const
|
|
739
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
723
|
+
const importPath = (0, node_path.relative)((0, node_path.dirname)(handlerPath), sourceFile).replace(/\.ts$/, ".js");
|
|
740
724
|
let content;
|
|
741
725
|
switch (provider) {
|
|
742
726
|
case "aws-apigatewayv1":
|
|
@@ -754,16 +738,14 @@ var EndpointGenerator = class extends require_discover.ConstructGenerator {
|
|
|
754
738
|
return handlerPath;
|
|
755
739
|
}
|
|
756
740
|
async generateEndpointsFile(outputDir, endpoints, context) {
|
|
757
|
-
const
|
|
758
|
-
const endpointsPath = (0, node_path.join)(outputDir, endpointsFileName);
|
|
741
|
+
const endpointsPath = (0, node_path.join)(outputDir, "endpoints.ts");
|
|
759
742
|
const importsByFile = /* @__PURE__ */ new Map();
|
|
760
743
|
for (const { path, key } of endpoints) {
|
|
761
|
-
const
|
|
762
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
744
|
+
const importPath = (0, node_path.relative)((0, node_path.dirname)(endpointsPath), path.relative).replace(/\.ts$/, ".js");
|
|
763
745
|
if (!importsByFile.has(importPath)) importsByFile.set(importPath, []);
|
|
764
746
|
importsByFile.get(importPath)?.push(key);
|
|
765
747
|
}
|
|
766
|
-
const endpointImports = Array.from(importsByFile.entries()).map(([importPath, exports
|
|
748
|
+
const endpointImports = Array.from(importsByFile.entries()).map(([importPath, exports]) => `import { ${exports.join(", ")} } from '${importPath}';`).join("\n");
|
|
767
749
|
const allExportNames = endpoints.map(({ key }) => key);
|
|
768
750
|
if (context.production?.enabled && context.production.optimizedHandlers) return this.generateOptimizedEndpointsFile(endpointsPath, endpoints, endpointImports, allExportNames);
|
|
769
751
|
const content = `import type { EnvironmentParser } from '@geekmidas/envkit';
|
|
@@ -825,11 +807,9 @@ export async function setupEndpoints(
|
|
|
825
807
|
const analyses = endpoints.map(({ key, construct }) => analyzeEndpoint(construct, key));
|
|
826
808
|
const endpointImports = endpoints.map(({ key, path }) => {
|
|
827
809
|
const tierDir = (0, node_path.join)(endpointsDir, "standard");
|
|
828
|
-
const relativePath = (0, node_path.relative)(tierDir, path.relative);
|
|
829
|
-
const importPath = relativePath.replace(/\.ts$/, ".js");
|
|
830
810
|
return {
|
|
831
811
|
exportName: key,
|
|
832
|
-
importPath
|
|
812
|
+
importPath: (0, node_path.relative)(tierDir, path.relative).replace(/\.ts$/, ".js")
|
|
833
813
|
};
|
|
834
814
|
});
|
|
835
815
|
const summary = summarizeAnalysis(analyses);
|
|
@@ -851,8 +831,7 @@ export async function setupEndpoints(
|
|
|
851
831
|
}
|
|
852
832
|
async generateAppFile(outputDir, context) {
|
|
853
833
|
if (context.production?.enabled) return this.generateProductionAppFile(outputDir, context);
|
|
854
|
-
const
|
|
855
|
-
const appPath = (0, node_path.join)(outputDir, appFileName);
|
|
834
|
+
const appPath = (0, node_path.join)(outputDir, "app.ts");
|
|
856
835
|
const runtime = runtimeFor(context, (0, node_path.dirname)(appPath));
|
|
857
836
|
const telescopeEnabled = context.telescope?.enabled;
|
|
858
837
|
const telescopeWebSocketEnabled = context.telescope?.websocket;
|
|
@@ -862,32 +841,36 @@ export async function setupEndpoints(
|
|
|
862
841
|
const studioFromDatabase = !usesExternalStudio && !!context.studio?.database;
|
|
863
842
|
const telescopeFromSurface = !!context.surface?.module && !usesExternalTelescope;
|
|
864
843
|
let telescopeImports = "";
|
|
865
|
-
if (telescopeEnabled)
|
|
866
|
-
|
|
867
|
-
const relativeTelescopePath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.telescope?.telescopePath);
|
|
868
|
-
telescopeImports = `import ${context.telescope?.telescopeImportPattern} from '${relativeTelescopePath}';
|
|
844
|
+
if (telescopeEnabled) {
|
|
845
|
+
if (telescopeFromSurface) telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
|
|
869
846
|
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
870
|
-
|
|
847
|
+
else if (usesExternalTelescope) {
|
|
848
|
+
const relativeTelescopePath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.telescope?.telescopePath);
|
|
849
|
+
telescopeImports = `import ${context.telescope?.telescopeImportPattern} from '${relativeTelescopePath}';
|
|
871
850
|
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
851
|
+
} else telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
|
|
852
|
+
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
853
|
+
}
|
|
872
854
|
let studioImports = "";
|
|
873
|
-
if (studioEnabled)
|
|
874
|
-
|
|
875
|
-
|
|
855
|
+
if (studioEnabled) {
|
|
856
|
+
if (usesExternalStudio) {
|
|
857
|
+
const relativeStudioPath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.studio?.studioPath);
|
|
858
|
+
studioImports = `import ${context.studio?.studioImportPattern} from '${relativeStudioPath}';
|
|
876
859
|
import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
860
|
+
} else if (studioFromDatabase) {
|
|
861
|
+
const dbSpecifier = importSpecifier((0, node_path.dirname)(appPath), context.studio.database.specifier);
|
|
862
|
+
studioImports = `import { snifferContext } from '@geekmidas/constructs';
|
|
880
863
|
import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';
|
|
881
864
|
import { ${context.studio.database.exportName} as __studioDb } from '${dbSpecifier}';
|
|
882
865
|
import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
883
|
-
|
|
866
|
+
} else studioImports = "";
|
|
867
|
+
}
|
|
884
868
|
const cors = corsFor(context.surface);
|
|
885
869
|
let hooksImports = "";
|
|
886
870
|
let beforeSetupCall = "";
|
|
887
871
|
let afterSetupCall = "";
|
|
888
872
|
if (context.hooks?.serverHooksPath) {
|
|
889
|
-
|
|
890
|
-
hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
|
|
873
|
+
hooksImports = `import * as serverHooks from '${(0, node_path.relative)((0, node_path.dirname)(appPath), context.hooks.serverHooksPath)}';`;
|
|
891
874
|
beforeSetupCall = `
|
|
892
875
|
// Call beforeSetup hook if defined
|
|
893
876
|
if (typeof serverHooks.beforeSetup === 'function') {
|
|
@@ -933,7 +916,8 @@ import { createStudioApp } from '@geekmidas/studio/server/hono';`;
|
|
|
933
916
|
}
|
|
934
917
|
` : "";
|
|
935
918
|
let telescopeSetup = "";
|
|
936
|
-
if (telescopeEnabled)
|
|
919
|
+
if (telescopeEnabled) {
|
|
920
|
+
if (telescopeFromSurface || usesExternalTelescope) telescopeSetup = `
|
|
937
921
|
${telescopeWebSocketSetupCode}
|
|
938
922
|
// Add telescope middleware (before endpoints to capture all requests)
|
|
939
923
|
honoApp.use('*', createMiddleware(telescope));
|
|
@@ -942,7 +926,7 @@ ${telescopeWebSocketSetupCode}
|
|
|
942
926
|
const telescopeUI = createUI(telescope);
|
|
943
927
|
honoApp.route('${context.telescope?.path}', telescopeUI);
|
|
944
928
|
`;
|
|
945
|
-
|
|
929
|
+
else telescopeSetup = `
|
|
946
930
|
// Setup Telescope for debugging/monitoring
|
|
947
931
|
const telescopeStorage = new InMemoryStorage({ maxEntries: ${context.telescope?.maxEntries} });
|
|
948
932
|
const telescope = new Telescope({
|
|
@@ -960,6 +944,7 @@ ${telescopeWebSocketSetupCode}
|
|
|
960
944
|
const telescopeUI = createUI(telescope);
|
|
961
945
|
honoApp.route('${context.telescope?.path}', telescopeUI);
|
|
962
946
|
`;
|
|
947
|
+
}
|
|
963
948
|
let studioSetup = "";
|
|
964
949
|
if (studioEnabled && studioFromDatabase) studioSetup = `
|
|
965
950
|
// Studio, built from the declared database. The client comes from the
|
|
@@ -993,6 +978,7 @@ import type { Hono as HonoType } from 'hono';
|
|
|
993
978
|
import { setupEndpoints } from './endpoints.js';
|
|
994
979
|
import { setupSubscribers } from './subscribers.js';
|
|
995
980
|
import { setupQueues } from './queues.js';
|
|
981
|
+
import { setupCrons } from './crons.js';
|
|
996
982
|
${runtime.imports}
|
|
997
983
|
${telescopeImports}
|
|
998
984
|
${studioImports}
|
|
@@ -1001,7 +987,16 @@ ${cors.imports}
|
|
|
1001
987
|
${context.storageDrivers?.imports ?? ""}
|
|
1002
988
|
|
|
1003
989
|
${runtime.bindings}
|
|
1004
|
-
${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
|
+
});` : ""}
|
|
1005
1000
|
|
|
1006
1001
|
${context.storageDrivers?.setup ? `// Which storage drivers exist is the entry point's decision: the scheme in
|
|
1007
1002
|
// each injected URL picks one, so no construct and no application module names
|
|
@@ -1080,6 +1075,12 @@ ${afterSetupCall}
|
|
|
1080
1075
|
logger.error({ error }, 'Failed to start queue workers');
|
|
1081
1076
|
});
|
|
1082
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
|
+
|
|
1083
1084
|
logger.info({ port }, 'Starting server');
|
|
1084
1085
|
|
|
1085
1086
|
// Start HTTP server using provided serve function
|
|
@@ -1148,10 +1149,8 @@ export const handler = ${exportName};
|
|
|
1148
1149
|
* No dev tools (Telescope, Studio, WebSocket), includes health checks and graceful shutdown
|
|
1149
1150
|
*/
|
|
1150
1151
|
async generateProductionAppFile(outputDir, context) {
|
|
1151
|
-
const
|
|
1152
|
-
const
|
|
1153
|
-
const relativeLoggerPath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.loggerPath);
|
|
1154
|
-
const relativeEnvParserPath = (0, node_path.relative)((0, node_path.dirname)(appPath), context.envParserPath);
|
|
1152
|
+
const appPath = (0, node_path.join)(outputDir, "app.ts");
|
|
1153
|
+
const runtime = runtimeFor(context, (0, node_path.dirname)(appPath));
|
|
1155
1154
|
const production = context.production;
|
|
1156
1155
|
const healthCheckPath = production.healthCheck;
|
|
1157
1156
|
const enableGracefulShutdown = production.gracefulShutdown;
|
|
@@ -1162,8 +1161,7 @@ export const handler = ${exportName};
|
|
|
1162
1161
|
let beforeSetupCall = "";
|
|
1163
1162
|
let afterSetupCall = "";
|
|
1164
1163
|
if (context.hooks?.serverHooksPath) {
|
|
1165
|
-
|
|
1166
|
-
hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
|
|
1164
|
+
hooksImports = `import * as serverHooks from '${(0, node_path.relative)((0, node_path.dirname)(appPath), context.hooks.serverHooksPath)}';`;
|
|
1167
1165
|
beforeSetupCall = `
|
|
1168
1166
|
// Call beforeSetup hook if defined
|
|
1169
1167
|
if (typeof serverHooks.beforeSetup === 'function') {
|
|
@@ -1187,9 +1185,16 @@ export const handler = ${exportName};
|
|
|
1187
1185
|
await setupQueues(envParser, logger).catch((error) => {
|
|
1188
1186
|
logger.error({ error }, 'Failed to start queue workers');
|
|
1189
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
|
+
});
|
|
1190
1194
|
` : "";
|
|
1191
1195
|
const subscriberImport = includeSubscribers ? `import { setupSubscribers } from './subscribers.js';
|
|
1192
|
-
import { setupQueues } from './queues.js'
|
|
1196
|
+
import { setupQueues } from './queues.js';
|
|
1197
|
+
import { setupCrons } from './crons.js';` : "";
|
|
1193
1198
|
const gracefulShutdownCode = enableGracefulShutdown ? `
|
|
1194
1199
|
// Graceful shutdown handling
|
|
1195
1200
|
let isShuttingDown = false;
|
|
@@ -1205,7 +1210,6 @@ import { setupQueues } from './queues.js';` : "";
|
|
|
1205
1210
|
process.on('SIGTERM', shutdown);
|
|
1206
1211
|
process.on('SIGINT', shutdown);
|
|
1207
1212
|
` : "";
|
|
1208
|
-
const endpointsImportPath = production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js";
|
|
1209
1213
|
const content = `/**
|
|
1210
1214
|
* Generated production server application
|
|
1211
1215
|
*
|
|
@@ -1217,10 +1221,10 @@ import { setupQueues } from './queues.js';` : "";
|
|
|
1217
1221
|
*/
|
|
1218
1222
|
import { Hono } from 'hono';
|
|
1219
1223
|
import type { Hono as HonoType } from 'hono';
|
|
1220
|
-
import { setupEndpoints } from '${
|
|
1224
|
+
import { setupEndpoints } from '${production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js"}';
|
|
1221
1225
|
${subscriberImport}
|
|
1222
|
-
|
|
1223
|
-
|
|
1226
|
+
${runtime.imports}
|
|
1227
|
+
${runtime.bindings}
|
|
1224
1228
|
${hooksImports}
|
|
1225
1229
|
${cors.imports}
|
|
1226
1230
|
${context.storageDrivers?.imports ?? ""}
|
|
@@ -1284,7 +1288,7 @@ export default createApp;
|
|
|
1284
1288
|
*/
|
|
1285
1289
|
async generateProductionServerEntry(outputDir) {
|
|
1286
1290
|
const serverPath = (0, node_path.join)(outputDir, "server.ts");
|
|
1287
|
-
|
|
1291
|
+
await (0, node_fs_promises.writeFile)(serverPath, `#!/usr/bin/env node
|
|
1288
1292
|
/**
|
|
1289
1293
|
* Production server entry point
|
|
1290
1294
|
* Generated by 'gkm build --provider server --production'
|
|
@@ -1300,11 +1304,9 @@ await start({
|
|
|
1300
1304
|
port,
|
|
1301
1305
|
serve: (app, port) => { serve({ fetch: app.fetch, port }); },
|
|
1302
1306
|
});
|
|
1303
|
-
|
|
1304
|
-
await (0, node_fs_promises.writeFile)(serverPath, content);
|
|
1307
|
+
`);
|
|
1305
1308
|
}
|
|
1306
1309
|
};
|
|
1307
|
-
|
|
1308
1310
|
//#endregion
|
|
1309
1311
|
//#region src/generators/OpenApiTsGenerator.ts
|
|
1310
1312
|
/**
|
|
@@ -1455,11 +1457,11 @@ var OpenApiTsGenerator = class {
|
|
|
1455
1457
|
}
|
|
1456
1458
|
}
|
|
1457
1459
|
}
|
|
1458
|
-
const registrySchemas = await (0,
|
|
1460
|
+
const registrySchemas = await (0, _geekmidas_schema_conversion.getRegisteredZodJsonSchemas)();
|
|
1459
1461
|
for (const [rawName, rawSchema] of Object.entries(registrySchemas)) {
|
|
1460
1462
|
const defName = this.pascalCase(rawName);
|
|
1461
1463
|
if (collectedDefs.has(defName) || generatedNames.has(defName)) continue;
|
|
1462
|
-
const { id: _id, $defs: _defs
|
|
1464
|
+
const { id: _id, $defs: _defs, ...rest } = rawSchema;
|
|
1463
1465
|
collectedDefs.set(defName, rest);
|
|
1464
1466
|
}
|
|
1465
1467
|
for (const [defName, defSchema] of collectedDefs) if (!generatedNames.has(defName)) {
|
|
@@ -1475,7 +1477,7 @@ var OpenApiTsGenerator = class {
|
|
|
1475
1477
|
*/
|
|
1476
1478
|
async getSchemaName(schema, defaultName) {
|
|
1477
1479
|
try {
|
|
1478
|
-
const metadata = await (0,
|
|
1480
|
+
const metadata = await (0, _geekmidas_schema_conversion.getSchemaMetadata)(schema);
|
|
1479
1481
|
if (metadata?.id) return this.pascalCase(metadata.id);
|
|
1480
1482
|
} catch {}
|
|
1481
1483
|
return defaultName;
|
|
@@ -1495,27 +1497,29 @@ var OpenApiTsGenerator = class {
|
|
|
1495
1497
|
async schemaToInterfaceWithDefs(schema, name, collectedDefs) {
|
|
1496
1498
|
try {
|
|
1497
1499
|
const vendor = schema["~standard"]?.vendor;
|
|
1498
|
-
if (!vendor || !(vendor in
|
|
1499
|
-
const toJsonSchema =
|
|
1500
|
+
if (!vendor || !(vendor in _geekmidas_schema_conversion.StandardSchemaJsonSchema)) return unknownType(name);
|
|
1501
|
+
const toJsonSchema = _geekmidas_schema_conversion.StandardSchemaJsonSchema[vendor];
|
|
1500
1502
|
const jsonSchema = await toJsonSchema(schema);
|
|
1501
|
-
if (!jsonSchema) return
|
|
1503
|
+
if (!jsonSchema) return unknownType(name);
|
|
1502
1504
|
if (jsonSchema.$defs && typeof jsonSchema.$defs === "object") {
|
|
1503
1505
|
for (const [defName, defSchema] of Object.entries(jsonSchema.$defs)) if (!collectedDefs.has(defName)) {
|
|
1504
|
-
const { id
|
|
1506
|
+
const { id, ...schemaWithoutId } = defSchema;
|
|
1505
1507
|
collectedDefs.set(defName, schemaWithoutId);
|
|
1506
1508
|
}
|
|
1507
1509
|
}
|
|
1508
|
-
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
|
+
}
|
|
1509
1516
|
return this.jsonSchemaToInterface(schemaWithoutDefs, name);
|
|
1510
1517
|
} catch {
|
|
1511
|
-
return
|
|
1518
|
+
return unknownType(name);
|
|
1512
1519
|
}
|
|
1513
1520
|
}
|
|
1514
1521
|
jsonSchemaToInterface(schema, name) {
|
|
1515
|
-
if (schema.type !== "object" || !schema.properties) {
|
|
1516
|
-
const typeStr = this.jsonSchemaTypeToTs(schema);
|
|
1517
|
-
return `export type ${name} = ${typeStr};`;
|
|
1518
|
-
}
|
|
1522
|
+
if (schema.type !== "object" || !schema.properties) return `export type ${name} = ${this.jsonSchemaTypeToTs(schema)};`;
|
|
1519
1523
|
const props = [];
|
|
1520
1524
|
const required = new Set(schema.required || []);
|
|
1521
1525
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
@@ -1528,13 +1532,15 @@ var OpenApiTsGenerator = class {
|
|
|
1528
1532
|
}
|
|
1529
1533
|
jsonSchemaTypeToTs(schema) {
|
|
1530
1534
|
if (!schema) return "unknown";
|
|
1531
|
-
if (schema.$ref)
|
|
1532
|
-
|
|
1533
|
-
return refName;
|
|
1534
|
-
}
|
|
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);
|
|
1535
1537
|
if (schema.anyOf) return schema.anyOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
|
|
1536
1538
|
if (schema.oneOf) return schema.oneOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
|
|
1537
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(" | ");
|
|
1538
1544
|
switch (schema.type) {
|
|
1539
1545
|
case "string":
|
|
1540
1546
|
if (schema.enum) return schema.enum.map((e) => `'${e}'`).join(" | ");
|
|
@@ -1558,10 +1564,7 @@ var OpenApiTsGenerator = class {
|
|
|
1558
1564
|
}
|
|
1559
1565
|
return `{ ${props.join("; ")} }`;
|
|
1560
1566
|
}
|
|
1561
|
-
if (schema.additionalProperties) {
|
|
1562
|
-
const valueType = this.jsonSchemaTypeToTs(schema.additionalProperties);
|
|
1563
|
-
return `Record<string, ${valueType}>`;
|
|
1564
|
-
}
|
|
1567
|
+
if (schema.additionalProperties) return `Record<string, ${this.jsonSchemaTypeToTs(schema.additionalProperties)}>`;
|
|
1565
1568
|
return "Record<string, unknown>";
|
|
1566
1569
|
default: return "unknown";
|
|
1567
1570
|
}
|
|
@@ -1582,10 +1585,7 @@ var OpenApiTsGenerator = class {
|
|
|
1582
1585
|
}
|
|
1583
1586
|
const firstWithParams = infos.find((i) => i.input?.params);
|
|
1584
1587
|
let paramsEntry = "";
|
|
1585
|
-
if (firstWithParams?.input?.params) {
|
|
1586
|
-
const paramsName = await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`);
|
|
1587
|
-
paramsEntry = `\n parameters: {\n path: ${paramsName};\n };`;
|
|
1588
|
-
}
|
|
1588
|
+
if (firstWithParams?.input?.params) paramsEntry = `\n parameters: {\n path: ${await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`)};\n };`;
|
|
1589
1589
|
pathEntries.push(` '${route}': {${paramsEntry}\n${methodEntries.join("\n")}\n };`);
|
|
1590
1590
|
}
|
|
1591
1591
|
return `export interface paths {\n${pathEntries.join("\n")}\n}`;
|
|
@@ -1624,8 +1624,7 @@ var OpenApiTsGenerator = class {
|
|
|
1624
1624
|
return acc;
|
|
1625
1625
|
}, {});
|
|
1626
1626
|
const schemeNames = securitySchemes.map((s) => `'${s.name}'`).join(" | ");
|
|
1627
|
-
const
|
|
1628
|
-
const createApiSection = hasSecuritySchemes ? `
|
|
1627
|
+
const createApiSection = schemeNames.length > 0 ? `
|
|
1629
1628
|
// ============================================================
|
|
1630
1629
|
// API Client Factory
|
|
1631
1630
|
// ============================================================
|
|
@@ -1649,6 +1648,8 @@ export interface CreateApiOptions {
|
|
|
1649
1648
|
queryClient?: QueryClient;
|
|
1650
1649
|
/** Optional request interceptor */
|
|
1651
1650
|
onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
|
|
1651
|
+
/** The \`fetch\` requests go out on — a test browser's, for one */
|
|
1652
|
+
fetch?: typeof fetch;
|
|
1652
1653
|
}
|
|
1653
1654
|
|
|
1654
1655
|
/**
|
|
@@ -1678,6 +1679,7 @@ export function createApi(options: CreateApiOptions) {
|
|
|
1678
1679
|
securitySchemes,
|
|
1679
1680
|
authStrategies: options.authStrategies,
|
|
1680
1681
|
onRequest: options.onRequest,
|
|
1682
|
+
...(options.fetch ? { fetch: options.fetch } : {}),
|
|
1681
1683
|
});
|
|
1682
1684
|
|
|
1683
1685
|
const hooks = createEndpointHooks<paths>(fetcher, { queryClient: options.queryClient });
|
|
@@ -1802,197 +1804,32 @@ ${createApiSection}
|
|
|
1802
1804
|
`;
|
|
1803
1805
|
}
|
|
1804
1806
|
};
|
|
1805
|
-
|
|
1806
|
-
//#endregion
|
|
1807
|
-
//#region src/workspace/client-generator.ts
|
|
1808
1807
|
/**
|
|
1809
|
-
*
|
|
1810
|
-
*
|
|
1811
|
-
*
|
|
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.
|
|
1812
1811
|
*/
|
|
1813
|
-
function
|
|
1814
|
-
|
|
1815
|
-
if (require_discover.isPartitionedRoutes(routes)) return Array.isArray(routes.paths) ? routes.paths : [routes.paths];
|
|
1816
|
-
return Array.isArray(routes) ? routes : [routes];
|
|
1812
|
+
function unknownType(name) {
|
|
1813
|
+
return `export type ${name} = unknown;`;
|
|
1817
1814
|
}
|
|
1818
|
-
|
|
1819
1815
|
//#endregion
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
const OPENAPI_OUTPUT_PATH = "./.gkm/openapi.ts";
|
|
1825
|
-
/**
|
|
1826
|
-
* Resolve OpenAPI config from GkmConfig
|
|
1827
|
-
*/
|
|
1828
|
-
function resolveOpenApiConfig(config) {
|
|
1829
|
-
if (config.openapi === false) return { enabled: false };
|
|
1830
|
-
if (config.openapi === true || config.openapi === void 0) return {
|
|
1831
|
-
enabled: true,
|
|
1832
|
-
title: "API Documentation",
|
|
1833
|
-
version: "1.0.0",
|
|
1834
|
-
description: "Auto-generated API documentation from endpoints"
|
|
1835
|
-
};
|
|
1836
|
-
return {
|
|
1837
|
-
enabled: config.openapi.enabled !== false,
|
|
1838
|
-
title: config.openapi.title || "API Documentation",
|
|
1839
|
-
version: config.openapi.version || "1.0.0",
|
|
1840
|
-
description: config.openapi.description || "Auto-generated API documentation from endpoints"
|
|
1841
|
-
};
|
|
1842
|
-
}
|
|
1843
|
-
/**
|
|
1844
|
-
* Generate OpenAPI spec from endpoints
|
|
1845
|
-
* @returns Object with output path and endpoint count, or null if disabled
|
|
1846
|
-
*/
|
|
1847
|
-
async function generateOpenApi(config, options = {}) {
|
|
1848
|
-
const logger = options.silent ? { log: () => {} } : console;
|
|
1849
|
-
const openApiConfig = resolveOpenApiConfig(config);
|
|
1850
|
-
if (!openApiConfig.enabled) return null;
|
|
1851
|
-
const endpointGenerator = new EndpointGenerator();
|
|
1852
|
-
const loadedEndpoints = await endpointGenerator.load(config.routes, void 0, options.bustCache);
|
|
1853
|
-
if (loadedEndpoints.length === 0) {
|
|
1854
|
-
logger.log("No valid endpoints found for OpenAPI generation");
|
|
1855
|
-
return null;
|
|
1856
|
-
}
|
|
1857
|
-
const endpoints = loadedEndpoints.map(({ construct }) => construct);
|
|
1858
|
-
const outputPath = (0, node_path.join)(process.cwd(), OPENAPI_OUTPUT_PATH);
|
|
1859
|
-
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(outputPath), { recursive: true });
|
|
1860
|
-
const tsGenerator = new OpenApiTsGenerator();
|
|
1861
|
-
const tsContent = await tsGenerator.generate(endpoints, {
|
|
1862
|
-
title: openApiConfig.title,
|
|
1863
|
-
version: openApiConfig.version,
|
|
1864
|
-
description: openApiConfig.description
|
|
1865
|
-
});
|
|
1866
|
-
await (0, node_fs_promises.writeFile)(outputPath, tsContent);
|
|
1867
|
-
logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);
|
|
1868
|
-
return {
|
|
1869
|
-
outputPath,
|
|
1870
|
-
endpointCount: loadedEndpoints.length
|
|
1871
|
-
};
|
|
1872
|
-
}
|
|
1873
|
-
async function openapiCommand(options = {}) {
|
|
1874
|
-
const logger = console;
|
|
1875
|
-
try {
|
|
1876
|
-
const loadedConfig = await require_config.loadWorkspaceConfig(options.cwd);
|
|
1877
|
-
if (loadedConfig.type === "single") {
|
|
1878
|
-
const config = loadedConfig.raw;
|
|
1879
|
-
if (!config.openapi) config.openapi = { enabled: true };
|
|
1880
|
-
const result = await generateOpenApi(config);
|
|
1881
|
-
if (result) logger.log(`Found ${result.endpointCount} endpoints`);
|
|
1882
|
-
} else {
|
|
1883
|
-
const { workspace } = loadedConfig;
|
|
1884
|
-
const workspaceRoot = workspace.root;
|
|
1885
|
-
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));
|
|
1886
|
-
if (backendApps.length === 0) {
|
|
1887
|
-
logger.log("No backend apps with OpenAPI enabled found");
|
|
1888
|
-
return;
|
|
1889
|
-
}
|
|
1890
|
-
if (options.app) {
|
|
1891
|
-
const entry = backendApps.find(([name]) => name === options.app);
|
|
1892
|
-
if (!entry) throw new Error(`App "${options.app}" not found or has OpenAPI disabled`);
|
|
1893
|
-
const [appName, app] = entry;
|
|
1894
|
-
const result = await generateOpenApiForApp(workspaceRoot, appName, app);
|
|
1895
|
-
if (result) logger.log(`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`);
|
|
1896
|
-
return;
|
|
1897
|
-
}
|
|
1898
|
-
for (const [appName, app] of backendApps) {
|
|
1899
|
-
if (app.type !== "backend" || !app.routes) continue;
|
|
1900
|
-
const appPath = (0, node_path.join)(workspaceRoot, app.path);
|
|
1901
|
-
await runOpenApiInSubprocess(appPath, appName);
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
} catch (error) {
|
|
1905
|
-
throw new Error(`OpenAPI generation failed: ${error.message}`);
|
|
1816
|
+
Object.defineProperty(exports, "EndpointGenerator", {
|
|
1817
|
+
enumerable: true,
|
|
1818
|
+
get: function() {
|
|
1819
|
+
return EndpointGenerator;
|
|
1906
1820
|
}
|
|
1907
|
-
}
|
|
1908
|
-
/**
|
|
1909
|
-
* Generate OpenAPI for a single named app within a workspace.
|
|
1910
|
-
* Runs in-process. The caller is responsible for ensuring `process.cwd()`
|
|
1911
|
-
* is the app's directory so tsx loads the app's tsconfig path aliases.
|
|
1912
|
-
*/
|
|
1913
|
-
async function generateOpenApiForApp(workspaceRoot, _appName, app) {
|
|
1914
|
-
if (app.type !== "backend" || !app.routes) return null;
|
|
1915
|
-
const appPath = (0, node_path.join)(workspaceRoot, app.path);
|
|
1916
|
-
const routes = normalizeRoutes(app.routes);
|
|
1917
|
-
const routesGlob = routes.map((r) => (0, node_path.join)(appPath, r));
|
|
1918
|
-
const gkmConfig = {
|
|
1919
|
-
routes: routesGlob,
|
|
1920
|
-
envParser: app.envParser || "",
|
|
1921
|
-
logger: app.logger || "",
|
|
1922
|
-
openapi: app.openapi
|
|
1923
|
-
};
|
|
1924
|
-
return generateOpenApi(gkmConfig, { silent: true });
|
|
1925
|
-
}
|
|
1926
|
-
/**
|
|
1927
|
-
* Resolve the gkm bin path. Tests can override via `GKM_BIN_PATH` env var
|
|
1928
|
-
* to avoid depending on the built dist.
|
|
1929
|
-
*/
|
|
1930
|
-
function resolveGkmBinPath() {
|
|
1931
|
-
if (process.env.GKM_BIN_PATH) return process.env.GKM_BIN_PATH;
|
|
1932
|
-
return (0, node_url.fileURLToPath)(new URL("../bin/gkm.mjs", require("url").pathToFileURL(__filename).href));
|
|
1933
|
-
}
|
|
1934
|
-
/**
|
|
1935
|
-
* Spawn a subprocess that runs `gkm openapi --app <name>` with `cwd` set to
|
|
1936
|
-
* the app's directory. Inherits `NODE_OPTIONS` (which already contains
|
|
1937
|
-
* `--import tsx`), so the child gets a fresh tsx instance whose tsconfig
|
|
1938
|
-
* discovery picks up the app's tsconfig path aliases.
|
|
1939
|
-
*/
|
|
1940
|
-
async function runOpenApiInSubprocess(appCwd, appName) {
|
|
1941
|
-
const binPath = resolveGkmBinPath();
|
|
1942
|
-
await new Promise((resolve, reject) => {
|
|
1943
|
-
const child = (0, node_child_process.spawn)(process.execPath, [
|
|
1944
|
-
binPath,
|
|
1945
|
-
"openapi",
|
|
1946
|
-
"--app",
|
|
1947
|
-
appName
|
|
1948
|
-
], {
|
|
1949
|
-
cwd: appCwd,
|
|
1950
|
-
stdio: "inherit",
|
|
1951
|
-
env: process.env
|
|
1952
|
-
});
|
|
1953
|
-
child.on("error", reject);
|
|
1954
|
-
child.on("close", (code) => {
|
|
1955
|
-
if (code === 0) resolve();
|
|
1956
|
-
else reject(new Error(`OpenAPI generation for app "${appName}" exited with code ${code}`));
|
|
1957
|
-
});
|
|
1958
|
-
});
|
|
1959
|
-
}
|
|
1960
|
-
|
|
1961
|
-
//#endregion
|
|
1962
|
-
Object.defineProperty(exports, 'EndpointGenerator', {
|
|
1963
|
-
enumerable: true,
|
|
1964
|
-
get: function () {
|
|
1965
|
-
return EndpointGenerator;
|
|
1966
|
-
}
|
|
1967
|
-
});
|
|
1968
|
-
Object.defineProperty(exports, 'OPENAPI_OUTPUT_PATH', {
|
|
1969
|
-
enumerable: true,
|
|
1970
|
-
get: function () {
|
|
1971
|
-
return OPENAPI_OUTPUT_PATH;
|
|
1972
|
-
}
|
|
1973
1821
|
});
|
|
1974
|
-
Object.defineProperty(exports,
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
});
|
|
1980
|
-
Object.defineProperty(exports, 'normalizeRoutes', {
|
|
1981
|
-
enumerable: true,
|
|
1982
|
-
get: function () {
|
|
1983
|
-
return normalizeRoutes;
|
|
1984
|
-
}
|
|
1985
|
-
});
|
|
1986
|
-
Object.defineProperty(exports, 'openapiCommand', {
|
|
1987
|
-
enumerable: true,
|
|
1988
|
-
get: function () {
|
|
1989
|
-
return openapiCommand;
|
|
1990
|
-
}
|
|
1822
|
+
Object.defineProperty(exports, "OpenApiTsGenerator", {
|
|
1823
|
+
enumerable: true,
|
|
1824
|
+
get: function() {
|
|
1825
|
+
return OpenApiTsGenerator;
|
|
1826
|
+
}
|
|
1991
1827
|
});
|
|
1992
|
-
Object.defineProperty(exports,
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1828
|
+
Object.defineProperty(exports, "runtimeFor", {
|
|
1829
|
+
enumerable: true,
|
|
1830
|
+
get: function() {
|
|
1831
|
+
return runtimeFor;
|
|
1832
|
+
}
|
|
1997
1833
|
});
|
|
1998
|
-
|
|
1834
|
+
|
|
1835
|
+
//# sourceMappingURL=OpenApiTsGenerator-D1nhN98m.cjs.map
|