@geekmidas/cli 10.0.0-alpha.4 → 10.0.0-alpha.40
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 +52 -74
- 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-Bh6K7QYz.mjs} +20 -21
- package/dist/HostingerProvider-Bh6K7QYz.mjs.map +1 -0
- package/dist/{LocalStateProvider-Db9SEjyH.cjs → LocalStateProvider-7HR6SS2t.cjs} +11 -6
- package/dist/LocalStateProvider-7HR6SS2t.cjs.map +1 -0
- package/dist/{LocalStateProvider-Bn6tS-oL.mjs → LocalStateProvider-D7QyJoLM.mjs} +10 -4
- package/dist/LocalStateProvider-D7QyJoLM.mjs.map +1 -0
- package/dist/{openapi-CA0yJUTN.cjs → OpenApiTsGenerator-B4Kj_qNU.cjs} +142 -303
- package/dist/OpenApiTsGenerator-B4Kj_qNU.cjs.map +1 -0
- package/dist/{openapi-kkQbsRVj.mjs → OpenApiTsGenerator-CEh3EKN3.mjs} +113 -255
- package/dist/OpenApiTsGenerator-CEh3EKN3.mjs.map +1 -0
- package/dist/{Route53Provider-RdpUDJQk.mjs → Route53Provider-Cvj40A8I.mjs} +12 -12
- package/dist/Route53Provider-Cvj40A8I.mjs.map +1 -0
- package/dist/{Route53Provider-di2fMM5N.cjs → Route53Provider-DVILBsvV.cjs} +20 -21
- package/dist/Route53Provider-DVILBsvV.cjs.map +1 -0
- package/dist/{SSMStateProvider-BRt2py-A.mjs → SSMStateProvider-B0Hu1MKZ.mjs} +13 -4
- package/dist/SSMStateProvider-B0Hu1MKZ.mjs.map +1 -0
- package/dist/{SSMStateProvider-DyX8s9HI.cjs → SSMStateProvider-VrQ-yeqd.cjs} +17 -9
- package/dist/SSMStateProvider-VrQ-yeqd.cjs.map +1 -0
- package/dist/aws-DkHdTV-p.cjs +61 -0
- package/dist/aws-DkHdTV-p.cjs.map +1 -0
- package/dist/aws-DojzQnLd.mjs +61 -0
- package/dist/aws-DojzQnLd.mjs.map +1 -0
- package/dist/{backup-provisioner-BrsHwYG0.cjs → backup-provisioner-BmhIO_Yr.cjs} +21 -19
- package/dist/backup-provisioner-BmhIO_Yr.cjs.map +1 -0
- package/dist/{backup-provisioner-Bgj5Vi_L.mjs → backup-provisioner-DIVCbfee.mjs} +10 -7
- package/dist/backup-provisioner-DIVCbfee.mjs.map +1 -0
- package/dist/{bundler-Be8Zg4Wd.mjs → bundler--fyybf1N.mjs} +19 -30
- package/dist/bundler--fyybf1N.mjs.map +1 -0
- package/dist/{bundler-BY1OmV1e.cjs → bundler-By6_sXiL.cjs} +20 -32
- package/dist/bundler-By6_sXiL.cjs.map +1 -0
- package/dist/{config-WRdsQYZK.mjs → config-5watB1D0.mjs} +142 -154
- package/dist/config-5watB1D0.mjs.map +1 -0
- package/dist/{config-C21ocYNd.cjs → config-CJ-PAb7M.cjs} +209 -210
- package/dist/config-CJ-PAb7M.cjs.map +1 -0
- package/dist/config.cjs +9 -6
- package/dist/config.d.cts +62 -33
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +62 -33
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +3 -5
- package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
- package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
- package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
- package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
- package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
- package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
- package/dist/deploy/sniffer-hooks.cjs +13 -7
- package/dist/deploy/sniffer-hooks.cjs.map +1 -1
- package/dist/deploy/sniffer-hooks.d.cts +1 -2
- package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
- package/dist/deploy/sniffer-hooks.d.mts +1 -2
- package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
- package/dist/deploy/sniffer-hooks.mjs +9 -2
- package/dist/deploy/sniffer-hooks.mjs.map +1 -1
- package/dist/deploy/sniffer-loader.cjs +16 -7
- package/dist/deploy/sniffer-loader.cjs.map +1 -1
- package/dist/deploy/sniffer-loader.d.cts +1 -1
- package/dist/deploy/sniffer-loader.d.mts +1 -1
- package/dist/deploy/sniffer-loader.mjs +13 -2
- package/dist/deploy/sniffer-loader.mjs.map +1 -1
- package/dist/deploy/sniffer-routes-worker.cjs +11 -11
- package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
- package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
- package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
- package/dist/deploy/sniffer-routes-worker.mjs +3 -3
- package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
- package/dist/deploy/sniffer-worker.cjs +15 -6
- package/dist/deploy/sniffer-worker.cjs.map +1 -1
- package/dist/deploy/sniffer-worker.d.cts +1 -3
- package/dist/deploy/sniffer-worker.d.cts.map +1 -1
- package/dist/deploy/sniffer-worker.d.mts +1 -3
- package/dist/deploy/sniffer-worker.d.mts.map +1 -1
- package/dist/deploy/sniffer-worker.mjs +15 -4
- package/dist/deploy/sniffer-worker.mjs.map +1 -1
- package/dist/{discover-DTmFeloL.cjs → discover-B0f_kuNN.cjs} +118 -66
- package/dist/discover-B0f_kuNN.cjs.map +1 -0
- package/dist/{discover-CAlFgYec.mjs → discover-BLhf7V_J.mjs} +67 -22
- package/dist/discover-BLhf7V_J.mjs.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-BAr8WGkR.cjs +213 -0
- package/dist/github-BAr8WGkR.cjs.map +1 -0
- package/dist/github-D5MthUlR.mjs +213 -0
- package/dist/github-D5MthUlR.mjs.map +1 -0
- package/dist/{index-DCtipn2h.d.cts → index-B3PeGOQp.d.cts} +4 -23
- package/dist/index-B3PeGOQp.d.cts.map +1 -0
- package/dist/{index-BThUzEIp.d.mts → index-BOyaGcCm.d.mts} +4 -23
- package/dist/index-BOyaGcCm.d.mts.map +1 -0
- package/dist/index.cjs +7071 -4519
- 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 +7117 -4586
- package/dist/index.mjs.map +1 -1
- package/dist/migrate-BVI3yqcE.mjs +736 -0
- package/dist/migrate-BVI3yqcE.mjs.map +1 -0
- package/dist/migrate-CFOUApUt.cjs +743 -0
- package/dist/migrate-CFOUApUt.cjs.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-D8UXsP6q.mjs +516 -0
- package/dist/ready-D8UXsP6q.mjs.map +1 -0
- package/dist/ready-mcxamf73.cjs +563 -0
- package/dist/ready-mcxamf73.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-CFs8C_1a.mjs → reconcile--I7V4Klj.mjs} +4 -7
- package/dist/reconcile--I7V4Klj.mjs.map +1 -0
- package/dist/{reconcile-D0pimNiy.cjs → reconcile-CuCQBa5-.cjs} +5 -8
- package/dist/reconcile-CuCQBa5-.cjs.map +1 -0
- package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
- package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
- package/dist/storage-BzaUxmqe.mjs +124 -0
- package/dist/storage-BzaUxmqe.mjs.map +1 -0
- package/dist/storage-CSGoC3bK.cjs +152 -0
- package/dist/storage-CSGoC3bK.cjs.map +1 -0
- package/dist/store-DQgxT_WR.cjs +211 -0
- package/dist/store-DQgxT_WR.cjs.map +1 -0
- package/dist/store-DeGATCS-.mjs +182 -0
- package/dist/store-DeGATCS-.mjs.map +1 -0
- package/dist/types-0R124hrY.d.mts +6324 -0
- package/dist/types-0R124hrY.d.mts.map +1 -0
- package/dist/types-DfdYe31u.d.cts +6325 -0
- package/dist/types-DfdYe31u.d.cts.map +1 -0
- package/dist/vitest.cjs +65 -0
- package/dist/vitest.cjs.map +1 -0
- package/dist/vitest.d.cts +29 -0
- package/dist/vitest.d.cts.map +1 -0
- package/dist/vitest.d.mts +29 -0
- package/dist/vitest.d.mts.map +1 -0
- package/dist/vitest.mjs +65 -0
- package/dist/vitest.mjs.map +1 -0
- package/dist/workspace/index.cjs +3 -4
- package/dist/workspace/index.d.cts +3 -3
- package/dist/workspace/index.d.mts +3 -3
- package/dist/workspace/index.mjs +2 -3
- package/dist/{credentials-G1JwBoXH.cjs → workspace-BIqeeqcR.cjs} +2248 -1809
- package/dist/workspace-BIqeeqcR.cjs.map +1 -0
- package/dist/{workspace-BFMrAKqI.mjs → workspace-DOmIhiau.mjs} +863 -952
- package/dist/workspace-DOmIhiau.mjs.map +1 -0
- package/dist/{credentials-BBIRJVp4.mjs → workspace-DwS1JK5u.mjs} +2114 -1706
- package/dist/workspace-DwS1JK5u.mjs.map +1 -0
- package/dist/{workspace-BcucjwvA.cjs → workspace-RYSYtHP7.cjs} +1032 -1098
- package/dist/workspace-RYSYtHP7.cjs.map +1 -0
- package/package.json +29 -20
- package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
- package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
- package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
- package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
- package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
- package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
- package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
- package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
- package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
- package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
- package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
- package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
- package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
- package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
- package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
- package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
- package/dist/bundler-BY1OmV1e.cjs.map +0 -1
- package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
- package/dist/chunk-Duj1WY3L.mjs +0 -7
- package/dist/config-C21ocYNd.cjs.map +0 -1
- package/dist/config-WRdsQYZK.mjs.map +0 -1
- package/dist/credentials-B5zRHdAl.mjs +0 -141
- package/dist/credentials-B5zRHdAl.mjs.map +0 -1
- package/dist/credentials-BBIRJVp4.mjs.map +0 -1
- package/dist/credentials-BapzjyV5.cjs +0 -195
- package/dist/credentials-BapzjyV5.cjs.map +0 -1
- package/dist/credentials-G1JwBoXH.cjs.map +0 -1
- package/dist/discover-CAlFgYec.mjs.map +0 -1
- package/dist/discover-DTmFeloL.cjs.map +0 -1
- package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
- package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
- package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
- package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
- package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
- package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
- package/dist/emit-CbcRolsa.cjs.map +0 -1
- package/dist/emit-CiZS_5Ub.mjs.map +0 -1
- package/dist/encryption-C6jaU0hE.cjs +0 -54
- package/dist/encryption-C6jaU0hE.cjs.map +0 -1
- package/dist/encryption-CHzzeR8a.cjs +0 -4
- package/dist/encryption-CQUncu7v.mjs +0 -3
- package/dist/encryption-D-abyhZx.mjs +0 -42
- package/dist/encryption-D-abyhZx.mjs.map +0 -1
- package/dist/fullstack-secrets-C-GGohke.cjs +0 -111
- package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
- package/dist/fullstack-secrets-D1o9-G5l.mjs +0 -87
- package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
- package/dist/generator-CNzBw7g5.cjs +0 -289
- package/dist/generator-CNzBw7g5.cjs.map +0 -1
- package/dist/generator-VE2JrFlY.mjs +0 -253
- package/dist/generator-VE2JrFlY.mjs.map +0 -1
- package/dist/index-BThUzEIp.d.mts.map +0 -1
- package/dist/index-DCtipn2h.d.cts.map +0 -1
- package/dist/openapi-CA0yJUTN.cjs.map +0 -1
- package/dist/openapi-kkQbsRVj.mjs.map +0 -1
- package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
- package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
- package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
- package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
- package/dist/openapi-react-query.cjs +0 -4
- package/dist/openapi-react-query.d.cts +0 -11
- package/dist/openapi-react-query.d.cts.map +0 -1
- package/dist/openapi-react-query.d.mts +0 -11
- package/dist/openapi-react-query.d.mts.map +0 -1
- package/dist/openapi-react-query.mjs +0 -4
- package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
- package/dist/reconcile-D0pimNiy.cjs.map +0 -1
- package/dist/setup-B5_oHHUj.cjs +0 -11
- package/dist/setup-Cm2UnAdh.cjs +0 -473
- package/dist/setup-Cm2UnAdh.cjs.map +0 -1
- package/dist/setup-DXvRLTZN.mjs +0 -443
- package/dist/setup-DXvRLTZN.mjs.map +0 -1
- package/dist/setup-ZijS4qeC.mjs +0 -11
- package/dist/storage-BJmzYxt8.cjs +0 -363
- package/dist/storage-BJmzYxt8.cjs.map +0 -1
- package/dist/storage-BM9hGpgv.cjs +0 -7
- package/dist/storage-Bi24WfoW.mjs +0 -297
- package/dist/storage-Bi24WfoW.mjs.map +0 -1
- package/dist/storage-CYlGwWTj.mjs +0 -3
- package/dist/sync-CmEuNZsB.mjs +0 -76
- package/dist/sync-CmEuNZsB.mjs.map +0 -1
- package/dist/sync-D306yOWu.cjs +0 -4
- package/dist/sync-SizaChmC.cjs +0 -93
- package/dist/sync-SizaChmC.cjs.map +0 -1
- package/dist/sync-hOqAWHR6.mjs +0 -3
- package/dist/types-BhIl-COG.d.cts +0 -2184
- package/dist/types-BhIl-COG.d.cts.map +0 -1
- package/dist/types-C-arnQ1r.d.mts +0 -2184
- package/dist/types-C-arnQ1r.d.mts.map +0 -1
- package/dist/workspace-BFMrAKqI.mjs.map +0 -1
- package/dist/workspace-BcucjwvA.cjs.map +0 -1
- package/dist/workspace-DdJss8I6.cjs +0 -9
- package/dist/workspace-k4l3rsFh.mjs +0 -8
|
@@ -1,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-B0f_kuNN.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';
|
|
@@ -774,7 +756,7 @@ import { ServiceDiscovery } from '@geekmidas/services';
|
|
|
774
756
|
import type { Hono } from 'hono';
|
|
775
757
|
${endpointImports}
|
|
776
758
|
|
|
777
|
-
export const endpoints: Endpoint<any, any, any, any, any, any, any, any, any, any, any, any
|
|
759
|
+
export const endpoints: Endpoint<any, any, any, any, any, any, any, any, any, any, any, any>[] = [
|
|
778
760
|
${allExportNames.join(",\n ")}
|
|
779
761
|
];
|
|
780
762
|
|
|
@@ -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
|
|
@@ -1070,9 +1065,11 @@ ${afterSetupCall}
|
|
|
1070
1065
|
|
|
1071
1066
|
const port = options.port ?? 3000;
|
|
1072
1067
|
|
|
1073
|
-
//
|
|
1074
|
-
|
|
1068
|
+
// Mount pushed subscribers' routes and start polled ones. What comes
|
|
1069
|
+
// back subscribes the routes, once the server can answer them.
|
|
1070
|
+
const subscribeForPush = await setupSubscribers(honoApp, envParser, logger).catch((error) => {
|
|
1075
1071
|
logger.error({ error }, 'Failed to start subscribers');
|
|
1072
|
+
return async (_port: number) => {};
|
|
1076
1073
|
});
|
|
1077
1074
|
|
|
1078
1075
|
// Start queue workers in background (non-blocking, local development only)
|
|
@@ -1080,12 +1077,20 @@ ${afterSetupCall}
|
|
|
1080
1077
|
logger.error({ error }, 'Failed to start queue workers');
|
|
1081
1078
|
});
|
|
1082
1079
|
|
|
1080
|
+
// Schedule this app's crons. Caught like the others: a scheduler that
|
|
1081
|
+
// cannot start is not a reason for the HTTP server not to.
|
|
1082
|
+
await setupCrons(envParser, logger).catch((error) => {
|
|
1083
|
+
logger.error({ error }, 'Failed to schedule crons');
|
|
1084
|
+
});
|
|
1085
|
+
|
|
1083
1086
|
logger.info({ port }, 'Starting server');
|
|
1084
1087
|
|
|
1085
1088
|
// Start HTTP server using provided serve function
|
|
1086
1089
|
await options.serve(honoApp, port);
|
|
1087
1090
|
|
|
1088
1091
|
logger.info({ port }, 'Server started');
|
|
1092
|
+
|
|
1093
|
+
await subscribeForPush(port);
|
|
1089
1094
|
}
|
|
1090
1095
|
};
|
|
1091
1096
|
}
|
|
@@ -1148,10 +1153,8 @@ export const handler = ${exportName};
|
|
|
1148
1153
|
* No dev tools (Telescope, Studio, WebSocket), includes health checks and graceful shutdown
|
|
1149
1154
|
*/
|
|
1150
1155
|
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);
|
|
1156
|
+
const appPath = (0, node_path.join)(outputDir, "app.ts");
|
|
1157
|
+
const runtime = runtimeFor(context, (0, node_path.dirname)(appPath));
|
|
1155
1158
|
const production = context.production;
|
|
1156
1159
|
const healthCheckPath = production.healthCheck;
|
|
1157
1160
|
const enableGracefulShutdown = production.gracefulShutdown;
|
|
@@ -1162,8 +1165,7 @@ export const handler = ${exportName};
|
|
|
1162
1165
|
let beforeSetupCall = "";
|
|
1163
1166
|
let afterSetupCall = "";
|
|
1164
1167
|
if (context.hooks?.serverHooksPath) {
|
|
1165
|
-
|
|
1166
|
-
hooksImports = `import * as serverHooks from '${relativeHooksPath}';`;
|
|
1168
|
+
hooksImports = `import * as serverHooks from '${(0, node_path.relative)((0, node_path.dirname)(appPath), context.hooks.serverHooksPath)}';`;
|
|
1167
1169
|
beforeSetupCall = `
|
|
1168
1170
|
// Call beforeSetup hook if defined
|
|
1169
1171
|
if (typeof serverHooks.beforeSetup === 'function') {
|
|
@@ -1178,18 +1180,27 @@ export const handler = ${exportName};
|
|
|
1178
1180
|
`;
|
|
1179
1181
|
}
|
|
1180
1182
|
const subscriberSetup = includeSubscribers ? `
|
|
1181
|
-
//
|
|
1182
|
-
|
|
1183
|
+
// Mount pushed subscribers' routes and start polled ones. What comes
|
|
1184
|
+
// back subscribes the routes, once the server can answer them.
|
|
1185
|
+
const subscribeForPush = await setupSubscribers(honoApp, envParser, logger).catch((error) => {
|
|
1183
1186
|
logger.error({ error }, 'Failed to start subscribers');
|
|
1187
|
+
return async (_port: number) => {};
|
|
1184
1188
|
});
|
|
1185
1189
|
|
|
1186
1190
|
// Start queue workers in background
|
|
1187
1191
|
await setupQueues(envParser, logger).catch((error) => {
|
|
1188
1192
|
logger.error({ error }, 'Failed to start queue workers');
|
|
1189
1193
|
});
|
|
1194
|
+
|
|
1195
|
+
// Schedule this app's crons. Caught like the others: a scheduler that
|
|
1196
|
+
// cannot start is not a reason for the HTTP server not to.
|
|
1197
|
+
await setupCrons(envParser, logger).catch((error) => {
|
|
1198
|
+
logger.error({ error }, 'Failed to schedule crons');
|
|
1199
|
+
});
|
|
1190
1200
|
` : "";
|
|
1191
1201
|
const subscriberImport = includeSubscribers ? `import { setupSubscribers } from './subscribers.js';
|
|
1192
|
-
import { setupQueues } from './queues.js'
|
|
1202
|
+
import { setupQueues } from './queues.js';
|
|
1203
|
+
import { setupCrons } from './crons.js';` : "";
|
|
1193
1204
|
const gracefulShutdownCode = enableGracefulShutdown ? `
|
|
1194
1205
|
// Graceful shutdown handling
|
|
1195
1206
|
let isShuttingDown = false;
|
|
@@ -1205,7 +1216,6 @@ import { setupQueues } from './queues.js';` : "";
|
|
|
1205
1216
|
process.on('SIGTERM', shutdown);
|
|
1206
1217
|
process.on('SIGINT', shutdown);
|
|
1207
1218
|
` : "";
|
|
1208
|
-
const endpointsImportPath = production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js";
|
|
1209
1219
|
const content = `/**
|
|
1210
1220
|
* Generated production server application
|
|
1211
1221
|
*
|
|
@@ -1217,10 +1227,10 @@ import { setupQueues } from './queues.js';` : "";
|
|
|
1217
1227
|
*/
|
|
1218
1228
|
import { Hono } from 'hono';
|
|
1219
1229
|
import type { Hono as HonoType } from 'hono';
|
|
1220
|
-
import { setupEndpoints } from '${
|
|
1230
|
+
import { setupEndpoints } from '${production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js"}';
|
|
1221
1231
|
${subscriberImport}
|
|
1222
|
-
|
|
1223
|
-
|
|
1232
|
+
${runtime.imports}
|
|
1233
|
+
${runtime.bindings}
|
|
1224
1234
|
${hooksImports}
|
|
1225
1235
|
${cors.imports}
|
|
1226
1236
|
${context.storageDrivers?.imports ?? ""}
|
|
@@ -1268,6 +1278,7 @@ ${gracefulShutdownCode}${subscriberSetup}
|
|
|
1268
1278
|
await options.serve(honoApp, port);
|
|
1269
1279
|
|
|
1270
1280
|
logger.info({ port }, 'Production server started');
|
|
1281
|
+
${includeSubscribers ? "\n await subscribeForPush(port);" : ""}
|
|
1271
1282
|
}
|
|
1272
1283
|
};
|
|
1273
1284
|
}
|
|
@@ -1284,7 +1295,7 @@ export default createApp;
|
|
|
1284
1295
|
*/
|
|
1285
1296
|
async generateProductionServerEntry(outputDir) {
|
|
1286
1297
|
const serverPath = (0, node_path.join)(outputDir, "server.ts");
|
|
1287
|
-
|
|
1298
|
+
await (0, node_fs_promises.writeFile)(serverPath, `#!/usr/bin/env node
|
|
1288
1299
|
/**
|
|
1289
1300
|
* Production server entry point
|
|
1290
1301
|
* Generated by 'gkm build --provider server --production'
|
|
@@ -1300,11 +1311,9 @@ await start({
|
|
|
1300
1311
|
port,
|
|
1301
1312
|
serve: (app, port) => { serve({ fetch: app.fetch, port }); },
|
|
1302
1313
|
});
|
|
1303
|
-
|
|
1304
|
-
await (0, node_fs_promises.writeFile)(serverPath, content);
|
|
1314
|
+
`);
|
|
1305
1315
|
}
|
|
1306
1316
|
};
|
|
1307
|
-
|
|
1308
1317
|
//#endregion
|
|
1309
1318
|
//#region src/generators/OpenApiTsGenerator.ts
|
|
1310
1319
|
/**
|
|
@@ -1455,11 +1464,11 @@ var OpenApiTsGenerator = class {
|
|
|
1455
1464
|
}
|
|
1456
1465
|
}
|
|
1457
1466
|
}
|
|
1458
|
-
const registrySchemas = await (0,
|
|
1467
|
+
const registrySchemas = await (0, _geekmidas_schema_conversion.getRegisteredZodJsonSchemas)();
|
|
1459
1468
|
for (const [rawName, rawSchema] of Object.entries(registrySchemas)) {
|
|
1460
1469
|
const defName = this.pascalCase(rawName);
|
|
1461
1470
|
if (collectedDefs.has(defName) || generatedNames.has(defName)) continue;
|
|
1462
|
-
const { id: _id, $defs: _defs
|
|
1471
|
+
const { id: _id, $defs: _defs, ...rest } = rawSchema;
|
|
1463
1472
|
collectedDefs.set(defName, rest);
|
|
1464
1473
|
}
|
|
1465
1474
|
for (const [defName, defSchema] of collectedDefs) if (!generatedNames.has(defName)) {
|
|
@@ -1475,7 +1484,7 @@ var OpenApiTsGenerator = class {
|
|
|
1475
1484
|
*/
|
|
1476
1485
|
async getSchemaName(schema, defaultName) {
|
|
1477
1486
|
try {
|
|
1478
|
-
const metadata = await (0,
|
|
1487
|
+
const metadata = await (0, _geekmidas_schema_conversion.getSchemaMetadata)(schema);
|
|
1479
1488
|
if (metadata?.id) return this.pascalCase(metadata.id);
|
|
1480
1489
|
} catch {}
|
|
1481
1490
|
return defaultName;
|
|
@@ -1495,17 +1504,17 @@ var OpenApiTsGenerator = class {
|
|
|
1495
1504
|
async schemaToInterfaceWithDefs(schema, name, collectedDefs) {
|
|
1496
1505
|
try {
|
|
1497
1506
|
const vendor = schema["~standard"]?.vendor;
|
|
1498
|
-
if (!vendor || !(vendor in
|
|
1499
|
-
const toJsonSchema =
|
|
1507
|
+
if (!vendor || !(vendor in _geekmidas_schema_conversion.StandardSchemaJsonSchema)) return unknownType(name);
|
|
1508
|
+
const toJsonSchema = _geekmidas_schema_conversion.StandardSchemaJsonSchema[vendor];
|
|
1500
1509
|
const jsonSchema = await toJsonSchema(schema);
|
|
1501
|
-
if (!jsonSchema) return
|
|
1510
|
+
if (!jsonSchema) return unknownType(name);
|
|
1502
1511
|
if (jsonSchema.$defs && typeof jsonSchema.$defs === "object") {
|
|
1503
1512
|
for (const [defName, defSchema] of Object.entries(jsonSchema.$defs)) if (!collectedDefs.has(defName)) {
|
|
1504
|
-
const { id
|
|
1513
|
+
const { id, ...schemaWithoutId } = defSchema;
|
|
1505
1514
|
collectedDefs.set(defName, schemaWithoutId);
|
|
1506
1515
|
}
|
|
1507
1516
|
}
|
|
1508
|
-
const { $defs
|
|
1517
|
+
const { $defs, ...schemaWithoutDefs } = jsonSchema;
|
|
1509
1518
|
const ref = schemaWithoutDefs.$ref;
|
|
1510
1519
|
if (ref && Object.keys(schemaWithoutDefs).every((k) => k === "$ref" || k === "$schema")) {
|
|
1511
1520
|
const target = ref.split("/").pop();
|
|
@@ -1513,14 +1522,11 @@ var OpenApiTsGenerator = class {
|
|
|
1513
1522
|
}
|
|
1514
1523
|
return this.jsonSchemaToInterface(schemaWithoutDefs, name);
|
|
1515
1524
|
} catch {
|
|
1516
|
-
return
|
|
1525
|
+
return unknownType(name);
|
|
1517
1526
|
}
|
|
1518
1527
|
}
|
|
1519
1528
|
jsonSchemaToInterface(schema, name) {
|
|
1520
|
-
if (schema.type !== "object" || !schema.properties) {
|
|
1521
|
-
const typeStr = this.jsonSchemaTypeToTs(schema);
|
|
1522
|
-
return `export type ${name} = ${typeStr};`;
|
|
1523
|
-
}
|
|
1529
|
+
if (schema.type !== "object" || !schema.properties) return `export type ${name} = ${this.jsonSchemaTypeToTs(schema)};`;
|
|
1524
1530
|
const props = [];
|
|
1525
1531
|
const required = new Set(schema.required || []);
|
|
1526
1532
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
@@ -1533,13 +1539,15 @@ var OpenApiTsGenerator = class {
|
|
|
1533
1539
|
}
|
|
1534
1540
|
jsonSchemaTypeToTs(schema) {
|
|
1535
1541
|
if (!schema) return "unknown";
|
|
1536
|
-
if (schema.$ref)
|
|
1537
|
-
|
|
1538
|
-
return refName;
|
|
1539
|
-
}
|
|
1542
|
+
if (schema.$ref) return schema.$ref.split("/").pop() || "unknown";
|
|
1543
|
+
if (schema.const !== void 0) return typeof schema.const === "string" ? `'${schema.const}'` : String(schema.const);
|
|
1540
1544
|
if (schema.anyOf) return schema.anyOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
|
|
1541
1545
|
if (schema.oneOf) return schema.oneOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" | ");
|
|
1542
1546
|
if (schema.allOf) return schema.allOf.map((s) => this.jsonSchemaTypeToTs(s)).join(" & ");
|
|
1547
|
+
if (Array.isArray(schema.type)) return schema.type.map((type) => this.jsonSchemaTypeToTs({
|
|
1548
|
+
...schema,
|
|
1549
|
+
type
|
|
1550
|
+
})).join(" | ");
|
|
1543
1551
|
switch (schema.type) {
|
|
1544
1552
|
case "string":
|
|
1545
1553
|
if (schema.enum) return schema.enum.map((e) => `'${e}'`).join(" | ");
|
|
@@ -1563,10 +1571,7 @@ var OpenApiTsGenerator = class {
|
|
|
1563
1571
|
}
|
|
1564
1572
|
return `{ ${props.join("; ")} }`;
|
|
1565
1573
|
}
|
|
1566
|
-
if (schema.additionalProperties) {
|
|
1567
|
-
const valueType = this.jsonSchemaTypeToTs(schema.additionalProperties);
|
|
1568
|
-
return `Record<string, ${valueType}>`;
|
|
1569
|
-
}
|
|
1574
|
+
if (schema.additionalProperties) return `Record<string, ${this.jsonSchemaTypeToTs(schema.additionalProperties)}>`;
|
|
1570
1575
|
return "Record<string, unknown>";
|
|
1571
1576
|
default: return "unknown";
|
|
1572
1577
|
}
|
|
@@ -1587,10 +1592,7 @@ var OpenApiTsGenerator = class {
|
|
|
1587
1592
|
}
|
|
1588
1593
|
const firstWithParams = infos.find((i) => i.input?.params);
|
|
1589
1594
|
let paramsEntry = "";
|
|
1590
|
-
if (firstWithParams?.input?.params) {
|
|
1591
|
-
const paramsName = await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`);
|
|
1592
|
-
paramsEntry = `\n parameters: {\n path: ${paramsName};\n };`;
|
|
1593
|
-
}
|
|
1595
|
+
if (firstWithParams?.input?.params) paramsEntry = `\n parameters: {\n path: ${await this.getSchemaName(firstWithParams.input.params, `${this.getSchemaBaseName(firstWithParams)}Params`)};\n };`;
|
|
1594
1596
|
pathEntries.push(` '${route}': {${paramsEntry}\n${methodEntries.join("\n")}\n };`);
|
|
1595
1597
|
}
|
|
1596
1598
|
return `export interface paths {\n${pathEntries.join("\n")}\n}`;
|
|
@@ -1629,8 +1631,7 @@ var OpenApiTsGenerator = class {
|
|
|
1629
1631
|
return acc;
|
|
1630
1632
|
}, {});
|
|
1631
1633
|
const schemeNames = securitySchemes.map((s) => `'${s.name}'`).join(" | ");
|
|
1632
|
-
const
|
|
1633
|
-
const createApiSection = hasSecuritySchemes ? `
|
|
1634
|
+
const createApiSection = schemeNames.length > 0 ? `
|
|
1634
1635
|
// ============================================================
|
|
1635
1636
|
// API Client Factory
|
|
1636
1637
|
// ============================================================
|
|
@@ -1654,6 +1655,8 @@ export interface CreateApiOptions {
|
|
|
1654
1655
|
queryClient?: QueryClient;
|
|
1655
1656
|
/** Optional request interceptor */
|
|
1656
1657
|
onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
|
|
1658
|
+
/** The \`fetch\` requests go out on — a test browser's, for one */
|
|
1659
|
+
fetch?: typeof fetch;
|
|
1657
1660
|
}
|
|
1658
1661
|
|
|
1659
1662
|
/**
|
|
@@ -1683,6 +1686,7 @@ export function createApi(options: CreateApiOptions) {
|
|
|
1683
1686
|
securitySchemes,
|
|
1684
1687
|
authStrategies: options.authStrategies,
|
|
1685
1688
|
onRequest: options.onRequest,
|
|
1689
|
+
...(options.fetch ? { fetch: options.fetch } : {}),
|
|
1686
1690
|
});
|
|
1687
1691
|
|
|
1688
1692
|
const hooks = createEndpointHooks<paths>(fetcher, { queryClient: options.queryClient });
|
|
@@ -1807,197 +1811,32 @@ ${createApiSection}
|
|
|
1807
1811
|
`;
|
|
1808
1812
|
}
|
|
1809
1813
|
};
|
|
1810
|
-
|
|
1811
|
-
//#endregion
|
|
1812
|
-
//#region src/workspace/client-generator.ts
|
|
1813
1814
|
/**
|
|
1814
|
-
*
|
|
1815
|
-
*
|
|
1816
|
-
*
|
|
1815
|
+
* The declaration for a schema that cannot be converted — a vendor with no
|
|
1816
|
+
* converter, or one that fails. The paths interface names it either way, so
|
|
1817
|
+
* leaving it undeclared made the generated client fail to compile.
|
|
1817
1818
|
*/
|
|
1818
|
-
function
|
|
1819
|
-
|
|
1820
|
-
if (require_discover.isPartitionedRoutes(routes)) return Array.isArray(routes.paths) ? routes.paths : [routes.paths];
|
|
1821
|
-
return Array.isArray(routes) ? routes : [routes];
|
|
1819
|
+
function unknownType(name) {
|
|
1820
|
+
return `export type ${name} = unknown;`;
|
|
1822
1821
|
}
|
|
1823
|
-
|
|
1824
1822
|
//#endregion
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
const OPENAPI_OUTPUT_PATH = "./.gkm/openapi.ts";
|
|
1830
|
-
/**
|
|
1831
|
-
* Resolve OpenAPI config from GkmConfig
|
|
1832
|
-
*/
|
|
1833
|
-
function resolveOpenApiConfig(config) {
|
|
1834
|
-
if (config.openapi === false) return { enabled: false };
|
|
1835
|
-
if (config.openapi === true || config.openapi === void 0) return {
|
|
1836
|
-
enabled: true,
|
|
1837
|
-
title: "API Documentation",
|
|
1838
|
-
version: "1.0.0",
|
|
1839
|
-
description: "Auto-generated API documentation from endpoints"
|
|
1840
|
-
};
|
|
1841
|
-
return {
|
|
1842
|
-
enabled: config.openapi.enabled !== false,
|
|
1843
|
-
title: config.openapi.title || "API Documentation",
|
|
1844
|
-
version: config.openapi.version || "1.0.0",
|
|
1845
|
-
description: config.openapi.description || "Auto-generated API documentation from endpoints"
|
|
1846
|
-
};
|
|
1847
|
-
}
|
|
1848
|
-
/**
|
|
1849
|
-
* Generate OpenAPI spec from endpoints
|
|
1850
|
-
* @returns Object with output path and endpoint count, or null if disabled
|
|
1851
|
-
*/
|
|
1852
|
-
async function generateOpenApi(config, options = {}) {
|
|
1853
|
-
const logger = options.silent ? { log: () => {} } : console;
|
|
1854
|
-
const openApiConfig = resolveOpenApiConfig(config);
|
|
1855
|
-
if (!openApiConfig.enabled) return null;
|
|
1856
|
-
const endpointGenerator = new EndpointGenerator();
|
|
1857
|
-
const loadedEndpoints = await endpointGenerator.load(config.routes, void 0, options.bustCache);
|
|
1858
|
-
if (loadedEndpoints.length === 0) {
|
|
1859
|
-
logger.log("No valid endpoints found for OpenAPI generation");
|
|
1860
|
-
return null;
|
|
1861
|
-
}
|
|
1862
|
-
const endpoints = loadedEndpoints.map(({ construct }) => construct);
|
|
1863
|
-
const outputPath = (0, node_path.join)(process.cwd(), OPENAPI_OUTPUT_PATH);
|
|
1864
|
-
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(outputPath), { recursive: true });
|
|
1865
|
-
const tsGenerator = new OpenApiTsGenerator();
|
|
1866
|
-
const tsContent = await tsGenerator.generate(endpoints, {
|
|
1867
|
-
title: openApiConfig.title,
|
|
1868
|
-
version: openApiConfig.version,
|
|
1869
|
-
description: openApiConfig.description
|
|
1870
|
-
});
|
|
1871
|
-
await (0, node_fs_promises.writeFile)(outputPath, tsContent);
|
|
1872
|
-
logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);
|
|
1873
|
-
return {
|
|
1874
|
-
outputPath,
|
|
1875
|
-
endpointCount: loadedEndpoints.length
|
|
1876
|
-
};
|
|
1877
|
-
}
|
|
1878
|
-
async function openapiCommand(options = {}) {
|
|
1879
|
-
const logger = console;
|
|
1880
|
-
try {
|
|
1881
|
-
const loadedConfig = await require_config.loadWorkspaceConfig(options.cwd);
|
|
1882
|
-
if (loadedConfig.type === "single") {
|
|
1883
|
-
const config = loadedConfig.raw;
|
|
1884
|
-
if (!config.openapi) config.openapi = { enabled: true };
|
|
1885
|
-
const result = await generateOpenApi(config);
|
|
1886
|
-
if (result) logger.log(`Found ${result.endpointCount} endpoints`);
|
|
1887
|
-
} else {
|
|
1888
|
-
const { workspace } = loadedConfig;
|
|
1889
|
-
const workspaceRoot = workspace.root;
|
|
1890
|
-
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));
|
|
1891
|
-
if (backendApps.length === 0) {
|
|
1892
|
-
logger.log("No backend apps with OpenAPI enabled found");
|
|
1893
|
-
return;
|
|
1894
|
-
}
|
|
1895
|
-
if (options.app) {
|
|
1896
|
-
const entry = backendApps.find(([name]) => name === options.app);
|
|
1897
|
-
if (!entry) throw new Error(`App "${options.app}" not found or has OpenAPI disabled`);
|
|
1898
|
-
const [appName, app] = entry;
|
|
1899
|
-
const result = await generateOpenApiForApp(workspaceRoot, appName, app);
|
|
1900
|
-
if (result) logger.log(`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`);
|
|
1901
|
-
return;
|
|
1902
|
-
}
|
|
1903
|
-
for (const [appName, app] of backendApps) {
|
|
1904
|
-
if (app.type !== "backend" || !app.routes) continue;
|
|
1905
|
-
const appPath = (0, node_path.join)(workspaceRoot, app.path);
|
|
1906
|
-
await runOpenApiInSubprocess(appPath, appName);
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
|
-
} catch (error) {
|
|
1910
|
-
throw new Error(`OpenAPI generation failed: ${error.message}`);
|
|
1823
|
+
Object.defineProperty(exports, "EndpointGenerator", {
|
|
1824
|
+
enumerable: true,
|
|
1825
|
+
get: function() {
|
|
1826
|
+
return EndpointGenerator;
|
|
1911
1827
|
}
|
|
1912
|
-
}
|
|
1913
|
-
/**
|
|
1914
|
-
* Generate OpenAPI for a single named app within a workspace.
|
|
1915
|
-
* Runs in-process. The caller is responsible for ensuring `process.cwd()`
|
|
1916
|
-
* is the app's directory so tsx loads the app's tsconfig path aliases.
|
|
1917
|
-
*/
|
|
1918
|
-
async function generateOpenApiForApp(workspaceRoot, _appName, app) {
|
|
1919
|
-
if (app.type !== "backend" || !app.routes) return null;
|
|
1920
|
-
const appPath = (0, node_path.join)(workspaceRoot, app.path);
|
|
1921
|
-
const routes = normalizeRoutes(app.routes);
|
|
1922
|
-
const routesGlob = routes.map((r) => (0, node_path.join)(appPath, r));
|
|
1923
|
-
const gkmConfig = {
|
|
1924
|
-
routes: routesGlob,
|
|
1925
|
-
envParser: app.envParser || "",
|
|
1926
|
-
logger: app.logger || "",
|
|
1927
|
-
openapi: app.openapi
|
|
1928
|
-
};
|
|
1929
|
-
return generateOpenApi(gkmConfig, { silent: true });
|
|
1930
|
-
}
|
|
1931
|
-
/**
|
|
1932
|
-
* Resolve the gkm bin path. Tests can override via `GKM_BIN_PATH` env var
|
|
1933
|
-
* to avoid depending on the built dist.
|
|
1934
|
-
*/
|
|
1935
|
-
function resolveGkmBinPath() {
|
|
1936
|
-
if (process.env.GKM_BIN_PATH) return process.env.GKM_BIN_PATH;
|
|
1937
|
-
return (0, node_url.fileURLToPath)(new URL("../bin/gkm.mjs", require("url").pathToFileURL(__filename).href));
|
|
1938
|
-
}
|
|
1939
|
-
/**
|
|
1940
|
-
* Spawn a subprocess that runs `gkm openapi --app <name>` with `cwd` set to
|
|
1941
|
-
* the app's directory. Inherits `NODE_OPTIONS` (which already contains
|
|
1942
|
-
* `--import tsx`), so the child gets a fresh tsx instance whose tsconfig
|
|
1943
|
-
* discovery picks up the app's tsconfig path aliases.
|
|
1944
|
-
*/
|
|
1945
|
-
async function runOpenApiInSubprocess(appCwd, appName) {
|
|
1946
|
-
const binPath = resolveGkmBinPath();
|
|
1947
|
-
await new Promise((resolve, reject) => {
|
|
1948
|
-
const child = (0, node_child_process.spawn)(process.execPath, [
|
|
1949
|
-
binPath,
|
|
1950
|
-
"openapi",
|
|
1951
|
-
"--app",
|
|
1952
|
-
appName
|
|
1953
|
-
], {
|
|
1954
|
-
cwd: appCwd,
|
|
1955
|
-
stdio: "inherit",
|
|
1956
|
-
env: process.env
|
|
1957
|
-
});
|
|
1958
|
-
child.on("error", reject);
|
|
1959
|
-
child.on("close", (code) => {
|
|
1960
|
-
if (code === 0) resolve();
|
|
1961
|
-
else reject(new Error(`OpenAPI generation for app "${appName}" exited with code ${code}`));
|
|
1962
|
-
});
|
|
1963
|
-
});
|
|
1964
|
-
}
|
|
1965
|
-
|
|
1966
|
-
//#endregion
|
|
1967
|
-
Object.defineProperty(exports, 'EndpointGenerator', {
|
|
1968
|
-
enumerable: true,
|
|
1969
|
-
get: function () {
|
|
1970
|
-
return EndpointGenerator;
|
|
1971
|
-
}
|
|
1972
|
-
});
|
|
1973
|
-
Object.defineProperty(exports, 'OPENAPI_OUTPUT_PATH', {
|
|
1974
|
-
enumerable: true,
|
|
1975
|
-
get: function () {
|
|
1976
|
-
return OPENAPI_OUTPUT_PATH;
|
|
1977
|
-
}
|
|
1978
1828
|
});
|
|
1979
|
-
Object.defineProperty(exports,
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
});
|
|
1985
|
-
Object.defineProperty(exports, 'normalizeRoutes', {
|
|
1986
|
-
enumerable: true,
|
|
1987
|
-
get: function () {
|
|
1988
|
-
return normalizeRoutes;
|
|
1989
|
-
}
|
|
1990
|
-
});
|
|
1991
|
-
Object.defineProperty(exports, 'openapiCommand', {
|
|
1992
|
-
enumerable: true,
|
|
1993
|
-
get: function () {
|
|
1994
|
-
return openapiCommand;
|
|
1995
|
-
}
|
|
1829
|
+
Object.defineProperty(exports, "OpenApiTsGenerator", {
|
|
1830
|
+
enumerable: true,
|
|
1831
|
+
get: function() {
|
|
1832
|
+
return OpenApiTsGenerator;
|
|
1833
|
+
}
|
|
1996
1834
|
});
|
|
1997
|
-
Object.defineProperty(exports,
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
1835
|
+
Object.defineProperty(exports, "runtimeFor", {
|
|
1836
|
+
enumerable: true,
|
|
1837
|
+
get: function() {
|
|
1838
|
+
return runtimeFor;
|
|
1839
|
+
}
|
|
2002
1840
|
});
|
|
2003
|
-
|
|
1841
|
+
|
|
1842
|
+
//# sourceMappingURL=OpenApiTsGenerator-B4Kj_qNU.cjs.map
|