@geekmidas/cli 10.0.0-alpha.70 → 10.0.0-alpha.71

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.
Files changed (81) hide show
  1. package/dist/{OpenApiTsGenerator-BYD9EcJi.mjs → OpenApiTsGenerator-Bhr_XWWN.mjs} +15 -627
  2. package/dist/OpenApiTsGenerator-Bhr_XWWN.mjs.map +1 -0
  3. package/dist/{OpenApiTsGenerator-CpRWM0N6.cjs → OpenApiTsGenerator-DZZwHdDC.cjs} +15 -627
  4. package/dist/OpenApiTsGenerator-DZZwHdDC.cjs.map +1 -0
  5. package/dist/{add-DHIk61nK.cjs → add-DeC2Kyyv.cjs} +2 -2
  6. package/dist/{add-DHIk61nK.cjs.map → add-DeC2Kyyv.cjs.map} +1 -1
  7. package/dist/{add-BuviRszv.mjs → add-XTLU19_E.mjs} +2 -2
  8. package/dist/{add-BuviRszv.mjs.map → add-XTLU19_E.mjs.map} +1 -1
  9. package/dist/{bundler-D7dcJVgj.cjs → bundler-CEaR6Dpb.cjs} +6 -6
  10. package/dist/bundler-CEaR6Dpb.cjs.map +1 -0
  11. package/dist/{bundler-DJlsYzm7.mjs → bundler-CNTVLCCA.mjs} +6 -6
  12. package/dist/bundler-CNTVLCCA.mjs.map +1 -0
  13. package/dist/{cli-BjnqVnE6.mjs → cli-D1arS0p1.mjs} +3 -3
  14. package/dist/{cli-BjnqVnE6.mjs.map → cli-D1arS0p1.mjs.map} +1 -1
  15. package/dist/{cli-7zCum6uN.cjs → cli-MMgBrHx7.cjs} +3 -3
  16. package/dist/{cli-7zCum6uN.cjs.map → cli-MMgBrHx7.cjs.map} +1 -1
  17. package/dist/{compose-BJYHmuvx.cjs → compose-B-MME-4C.cjs} +2 -2
  18. package/dist/{compose-BJYHmuvx.cjs.map → compose-B-MME-4C.cjs.map} +1 -1
  19. package/dist/{compose-CByVaaeR.mjs → compose-T3hnnjKZ.mjs} +2 -2
  20. package/dist/{compose-CByVaaeR.mjs.map → compose-T3hnnjKZ.mjs.map} +1 -1
  21. package/dist/deploy/public.cjs +5 -5
  22. package/dist/deploy/public.mjs +5 -5
  23. package/dist/{deploy--ZU9gOOa.cjs → deploy-CZE0m6jd.cjs} +3 -3
  24. package/dist/{deploy--ZU9gOOa.cjs.map → deploy-CZE0m6jd.cjs.map} +1 -1
  25. package/dist/{deploy-CCSGr7be.mjs → deploy-ClC53rc6.mjs} +3 -3
  26. package/dist/{deploy-CCSGr7be.mjs.map → deploy-ClC53rc6.mjs.map} +1 -1
  27. package/dist/{dokploy-Bskfn1g5.mjs → dokploy-D1UwQKm3.mjs} +2 -2
  28. package/dist/{dokploy-Bskfn1g5.mjs.map → dokploy-D1UwQKm3.mjs.map} +1 -1
  29. package/dist/{dokploy-BOupc9PK.cjs → dokploy-lwmH05zr.cjs} +2 -2
  30. package/dist/{dokploy-BOupc9PK.cjs.map → dokploy-lwmH05zr.cjs.map} +1 -1
  31. package/dist/{encryption-D-VkoJG4.cjs → encryption-D05sNwED.cjs} +2 -2
  32. package/dist/{encryption-D-VkoJG4.cjs.map → encryption-D05sNwED.cjs.map} +1 -1
  33. package/dist/{encryption-DR-py9GX.mjs → encryption-DcrxWl1s.mjs} +2 -2
  34. package/dist/{encryption-DR-py9GX.mjs.map → encryption-DcrxWl1s.mjs.map} +1 -1
  35. package/dist/{engine-Da8dBxt5.cjs → engine-Cry1vwMz.cjs} +2 -2
  36. package/dist/{engine-Da8dBxt5.cjs.map → engine-Cry1vwMz.cjs.map} +1 -1
  37. package/dist/{engine-Xbv8NNdX.mjs → engine-DmQS3XHX.mjs} +2 -2
  38. package/dist/{engine-Xbv8NNdX.mjs.map → engine-DmQS3XHX.mjs.map} +1 -1
  39. package/dist/{github-DeXzs11c.cjs → github-BchWoiVx.cjs} +2 -2
  40. package/dist/{github-DeXzs11c.cjs.map → github-BchWoiVx.cjs.map} +1 -1
  41. package/dist/{github-D2pYzY7L.mjs → github-CqYOP8cI.mjs} +2 -2
  42. package/dist/{github-D2pYzY7L.mjs.map → github-CqYOP8cI.mjs.map} +1 -1
  43. package/dist/index.cjs +46 -47
  44. package/dist/index.cjs.map +1 -1
  45. package/dist/index.mjs +46 -47
  46. package/dist/index.mjs.map +1 -1
  47. package/dist/{migrate-DiJT84g9.mjs → migrate-guck0NJK.mjs} +2 -2
  48. package/dist/{migrate-DiJT84g9.mjs.map → migrate-guck0NJK.mjs.map} +1 -1
  49. package/dist/{migrate-BURDS8vy.cjs → migrate-qKeGYq21.cjs} +2 -2
  50. package/dist/{migrate-BURDS8vy.cjs.map → migrate-qKeGYq21.cjs.map} +1 -1
  51. package/dist/openapi.cjs +1 -1
  52. package/dist/openapi.mjs +1 -1
  53. package/dist/{ready-C-qNcux-.cjs → ready-Dp6arkI4.cjs} +5 -5
  54. package/dist/ready-Dp6arkI4.cjs.map +1 -0
  55. package/dist/{ready-CfIiMts4.mjs → ready-xpoX11uu.mjs} +5 -5
  56. package/dist/ready-xpoX11uu.mjs.map +1 -0
  57. package/dist/{resolve-Dj5TQKoD.mjs → resolve-BsXEXAUz.mjs} +3 -3
  58. package/dist/{resolve-Dj5TQKoD.mjs.map → resolve-BsXEXAUz.mjs.map} +1 -1
  59. package/dist/{resolve-B7jJQmTo.cjs → resolve-wEjEvbJ5.cjs} +3 -3
  60. package/dist/{resolve-B7jJQmTo.cjs.map → resolve-wEjEvbJ5.cjs.map} +1 -1
  61. package/dist/{rollback-Bw9kESjz.mjs → rollback-Bk91csFg.mjs} +3 -3
  62. package/dist/{rollback-Bw9kESjz.mjs.map → rollback-Bk91csFg.mjs.map} +1 -1
  63. package/dist/{rollback-DNK1HEHY.cjs → rollback-DmcU-efZ.cjs} +3 -3
  64. package/dist/{rollback-DNK1HEHY.cjs.map → rollback-DmcU-efZ.cjs.map} +1 -1
  65. package/dist/{state-527OmqvN.mjs → state-BJFherj1.mjs} +7 -2
  66. package/dist/state-BJFherj1.mjs.map +1 -0
  67. package/dist/{state-nS6I6s4u.cjs → state-CCuTJNRH.cjs} +7 -2
  68. package/dist/state-CCuTJNRH.cjs.map +1 -0
  69. package/dist/target/public.cjs +1 -1
  70. package/dist/target/public.mjs +1 -1
  71. package/dist/vitest.cjs +1 -1
  72. package/dist/vitest.mjs +1 -1
  73. package/package.json +15 -15
  74. package/dist/OpenApiTsGenerator-BYD9EcJi.mjs.map +0 -1
  75. package/dist/OpenApiTsGenerator-CpRWM0N6.cjs.map +0 -1
  76. package/dist/bundler-D7dcJVgj.cjs.map +0 -1
  77. package/dist/bundler-DJlsYzm7.mjs.map +0 -1
  78. package/dist/ready-C-qNcux-.cjs.map +0 -1
  79. package/dist/ready-CfIiMts4.mjs.map +0 -1
  80. package/dist/state-527OmqvN.mjs.map +0 -1
  81. package/dist/state-nS6I6s4u.cjs.map +0 -1
@@ -4,579 +4,6 @@ import { existsSync, realpathSync } from "node:fs";
4
4
  import { mkdir, writeFile } from "node:fs/promises";
5
5
  import { Endpoint } from "@geekmidas/constructs/endpoints";
6
6
  import { StandardSchemaJsonSchema, getRegisteredZodJsonSchemas, getSchemaMetadata } from "@geekmidas/schema/conversion";
7
- //#region src/build/endpoint-analyzer.ts
8
- /**
9
- * Analyze an endpoint to extract its features
10
- */
11
- function analyzeEndpointFeatures(endpoint) {
12
- return {
13
- hasAuth: !!endpoint.authorizer || endpoint.hasSession === true,
14
- hasServices: endpoint.services.length > 0,
15
- hasDatabase: !!endpoint.databaseService,
16
- hasBodyValidation: !!endpoint.input?.body,
17
- hasQueryValidation: !!endpoint.input?.query,
18
- hasParamValidation: !!endpoint.input?.params,
19
- hasAudits: (endpoint.audits?.length ?? 0) > 0,
20
- hasEvents: (endpoint.events?.length ?? 0) > 0,
21
- hasRateLimit: !!endpoint.rateLimit,
22
- hasRls: !!endpoint.rlsConfig && !endpoint.rlsBypass,
23
- hasOutputValidation: !!endpoint.outputSchema
24
- };
25
- }
26
- /**
27
- * Determine the optimization tier for an endpoint based on its features
28
- */
29
- function determineEndpointTier(features) {
30
- const { hasAuth, hasServices, hasDatabase, hasAudits, hasEvents, hasRateLimit, hasRls } = features;
31
- if (!hasAuth && !hasServices && !hasDatabase && !hasAudits && !hasEvents && !hasRateLimit && !hasRls) return "minimal";
32
- if (hasAudits || hasRls || hasRateLimit) return "full";
33
- return "standard";
34
- }
35
- /**
36
- * Perform complete analysis of an endpoint
37
- */
38
- function analyzeEndpoint(endpoint, exportName) {
39
- const features = analyzeEndpointFeatures(endpoint);
40
- const tier = determineEndpointTier(features);
41
- return {
42
- route: endpoint.route,
43
- method: endpoint.method,
44
- exportName,
45
- features,
46
- tier,
47
- serviceNames: endpoint.services.map((s) => s.serviceName),
48
- databaseServiceName: endpoint.databaseService?.serviceName
49
- };
50
- }
51
- /**
52
- * Generate a summary of endpoint analysis for logging
53
- */
54
- function summarizeAnalysis(analyses) {
55
- const byTier = {
56
- minimal: 0,
57
- standard: 0,
58
- full: 0
59
- };
60
- const byFeature = {
61
- hasAuth: 0,
62
- hasServices: 0,
63
- hasDatabase: 0,
64
- hasBodyValidation: 0,
65
- hasQueryValidation: 0,
66
- hasParamValidation: 0,
67
- hasAudits: 0,
68
- hasEvents: 0,
69
- hasRateLimit: 0,
70
- hasRls: 0,
71
- hasOutputValidation: 0
72
- };
73
- for (const analysis of analyses) {
74
- byTier[analysis.tier]++;
75
- for (const [feature, enabled] of Object.entries(analysis.features)) if (enabled) byFeature[feature]++;
76
- }
77
- return {
78
- total: analyses.length,
79
- byTier,
80
- byFeature
81
- };
82
- }
83
- //#endregion
84
- //#region src/build/handler-templates.ts
85
- /**
86
- * Generate validator references for an endpoint
87
- */
88
- function generateValidators(exportName, features) {
89
- const validators = [];
90
- if (features.hasBodyValidation) validators.push(`validateBody(${exportName})`);
91
- if (features.hasQueryValidation) validators.push(`validateQuery(${exportName})`);
92
- if (features.hasParamValidation) validators.push(`validateParams(${exportName})`);
93
- return validators.length > 0 ? `\n ${validators.join(",\n ")},` : "";
94
- }
95
- /**
96
- * Generate a minimal handler (near-raw-Hono performance)
97
- *
98
- * Used for: Health checks, public endpoints with no services
99
- */
100
- function generateMinimalHandler(analysis) {
101
- const { exportName, features } = analysis;
102
- const method = analysis.method.toLowerCase();
103
- const validators = generateValidators(exportName, features);
104
- if (!(validators.length > 0) && !features.hasOutputValidation) return `
105
- // Minimal handler: ${analysis.route} (${analysis.method})
106
- app.${method}('${analysis.route}', async (c) => {
107
- const result = await ${exportName}.handler(
108
- {
109
- services: {},
110
- logger,
111
- body: undefined,
112
- query: undefined,
113
- params: undefined,
114
- session: undefined,
115
- header: Endpoint.createHeaders(c.req.header()),
116
- cookie: Endpoint.createCookies(c.req.header().cookie),
117
- auditor: undefined,
118
- db: undefined,
119
- } as any,
120
- { getMetadata: () => ({}) } as any,
121
- );
122
- return c.json(result, ${exportName}.status as any);
123
- });`;
124
- return `
125
- // Minimal handler with validation: ${analysis.route} (${analysis.method})
126
- app.${method}('${analysis.route}',${validators}
127
- async (c) => {
128
- const result = await ${exportName}.handler(
129
- {
130
- services: {},
131
- logger,
132
- body: ${features.hasBodyValidation ? "(c.req.valid as any)('json')" : "undefined"},
133
- query: ${features.hasQueryValidation ? "(c.req.valid as any)('query')" : "undefined"},
134
- params: ${features.hasParamValidation ? "(c.req.valid as any)('param')" : "undefined"},
135
- session: undefined,
136
- header: Endpoint.createHeaders(c.req.header()),
137
- cookie: Endpoint.createCookies(c.req.header().cookie),
138
- auditor: undefined,
139
- db: undefined,
140
- } as any,
141
- { getMetadata: () => ({}) } as any,
142
- );
143
- ${features.hasOutputValidation ? `const output = await ${exportName}.parseOutput(result);
144
- return c.json(output, ${exportName}.status as any);` : `return c.json(result, ${exportName}.status as any);`}
145
- }
146
- );`;
147
- }
148
- /**
149
- * Generate a standard handler (auth and/or services)
150
- *
151
- * Used for: Authenticated endpoints, endpoints with services
152
- */
153
- function generateStandardHandler(analysis) {
154
- const { exportName, features } = analysis;
155
- const method = analysis.method.toLowerCase();
156
- const validators = generateValidators(exportName, features);
157
- let serviceResolution = "";
158
- if (features.hasServices || features.hasDatabase) serviceResolution = `
159
- const services = await serviceDiscovery.register(${exportName}.services);
160
- ${features.hasDatabase ? `const db = ${exportName}.databaseService
161
- ? (await serviceDiscovery.register([${exportName}.databaseService]) as any)[${exportName}.databaseService.serviceName]
162
- : undefined;` : "const db = undefined;"}`;
163
- else serviceResolution = `
164
- const services = {};
165
- const db = undefined;`;
166
- let authCode = "";
167
- if (features.hasAuth) authCode = `
168
- // Authentication
169
- const session = await ${exportName}.getSession({
170
- services,
171
- logger,
172
- header,
173
- cookie,
174
- ...(db !== undefined && { db }),
175
- } as any);
176
-
177
- const isAuthorized = await ${exportName}.authorize({
178
- header,
179
- cookie,
180
- services,
181
- logger,
182
- session,
183
- } as any);
184
-
185
- if (!isAuthorized) {
186
- return c.json({ error: 'Unauthorized' }, 401);
187
- }`;
188
- let eventCode = "";
189
- if (features.hasEvents) eventCode = `
190
- // Publish events on success
191
- if (Endpoint.isSuccessStatus(${exportName}.status)) {
192
- await (publishConstructEvents as any)(
193
- ${exportName},
194
- result,
195
- serviceDiscovery,
196
- logger,
197
- );
198
- }`;
199
- return `
200
- // Standard handler: ${analysis.route} (${analysis.method})
201
- app.${method}('${analysis.route}',${validators}
202
- async (c) => {
203
- const headerValues = c.req.header();
204
- const header = Endpoint.createHeaders(headerValues);
205
- const cookie = Endpoint.createCookies(headerValues.cookie);
206
- ${serviceResolution}
207
- ${authCode}
208
-
209
- const responseBuilder = new ResponseBuilder();
210
- const result = await ${exportName}.handler(
211
- {
212
- services,
213
- logger,
214
- body: ${features.hasBodyValidation ? "(c.req.valid as any)('json')" : "undefined"},
215
- query: ${features.hasQueryValidation ? "(c.req.valid as any)('query')" : "undefined"},
216
- params: ${features.hasParamValidation ? "(c.req.valid as any)('param')" : "undefined"},
217
- session: ${features.hasAuth ? "session" : "undefined"},
218
- header,
219
- cookie,
220
- auditor: undefined,
221
- db,
222
- } as any,
223
- responseBuilder,
224
- );
225
-
226
- let data = result;
227
- let metadata = responseBuilder.getMetadata();
228
-
229
- if (Endpoint.hasMetadata(result)) {
230
- data = result.data;
231
- metadata = result.metadata;
232
- }
233
-
234
- ${features.hasOutputValidation ? `const output = ${exportName}.outputSchema
235
- ? await ${exportName}.parseOutput(data)
236
- : data;` : "const output = data;"}
237
- ${eventCode}
238
-
239
- const status = (metadata.status ?? ${exportName}.status) as any;
240
- return c.json(output, status);
241
- }
242
- );`;
243
- }
244
- /**
245
- * Generate validators.ts - Shared validator middleware factories
246
- */
247
- function generateValidatorsFile(analyses) {
248
- const needsBody = analyses.some((a) => a.features.hasBodyValidation);
249
- const needsQuery = analyses.some((a) => a.features.hasQueryValidation);
250
- const needsParams = analyses.some((a) => a.features.hasParamValidation);
251
- if (!needsBody && !needsQuery && !needsParams) return `// No validators needed for this build\nexport {};\n`;
252
- const exports = [];
253
- const factories = [];
254
- if (needsBody) {
255
- exports.push("validateBody");
256
- factories.push(`
257
- export const validateBody = (endpoint: any) =>
258
- validator('json', async (value, c) => {
259
- if (!endpoint.input?.body) return undefined;
260
- const parsed = await Endpoint.validate(endpoint.input.body, value);
261
- if (parsed.issues) return c.json(parsed.issues, 422);
262
- return parsed.value;
263
- });`);
264
- }
265
- if (needsQuery) {
266
- exports.push("validateQuery");
267
- factories.push(`
268
- export const validateQuery = (endpoint: any) =>
269
- validator('query', async (_, c) => {
270
- if (!endpoint.input?.query) return undefined;
271
- const rawQuery = Object.fromEntries(new URL(c.req.url).searchParams);
272
- const parsed = await Endpoint.validate(endpoint.input.query, rawQuery);
273
- if (parsed.issues) return c.json(parsed.issues, 422);
274
- return parsed.value;
275
- });`);
276
- }
277
- if (needsParams) {
278
- exports.push("validateParams");
279
- factories.push(`
280
- export const validateParams = (endpoint: any) =>
281
- validator('param', async (params, c) => {
282
- if (!endpoint.input?.params) return undefined;
283
- const parsed = await Endpoint.validate(endpoint.input.params, params);
284
- if (parsed.issues) return c.json(parsed.issues, 422);
285
- return parsed.value;
286
- });`);
287
- }
288
- return `/**
289
- * Generated validator middleware factories
290
- * Shared across all endpoint tiers that need validation
291
- */
292
- import { validator } from 'hono/validator';
293
- import { Endpoint } from '@geekmidas/constructs/endpoints';
294
- ${factories.join("\n")}
295
- `;
296
- }
297
- /**
298
- * Generate a standalone minimal endpoint file
299
- */
300
- function generateMinimalEndpointFile(analysis, endpointImport) {
301
- const { exportName, features } = analysis;
302
- const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
303
- const handler = generateMinimalHandler(analysis);
304
- return `/**
305
- * Minimal endpoint: ${analysis.route} (${analysis.method})
306
- * Near-raw-Hono performance
307
- */
308
- import type { Hono } from 'hono';
309
- import type { Logger } from '@geekmidas/logger';
310
- import { Endpoint } from '@geekmidas/constructs/endpoints';
311
- ${validatorImport}
312
- import { ${exportName} } from '${endpointImport.importPath}';
313
-
314
- export function setup${capitalize(exportName)}(
315
- app: Hono,
316
- logger: Logger,
317
- ): void {
318
- ${handler}
319
- }
320
- `;
321
- }
322
- /**
323
- * Generate a standalone standard endpoint file
324
- */
325
- function generateStandardEndpointFile(analysis, endpointImport) {
326
- const { exportName, features } = analysis;
327
- const validatorImport = features.hasBodyValidation || features.hasQueryValidation || features.hasParamValidation ? generateValidatorImportsForEndpoint(analysis) : "";
328
- const eventsImport = features.hasEvents ? `import { publishConstructEvents } from '@geekmidas/constructs/endpoints';` : "";
329
- const handler = generateStandardHandler(analysis);
330
- return `/**
331
- * Standard endpoint: ${analysis.route} (${analysis.method})
332
- * Auth and/or services enabled
333
- */
334
- import type { Hono } from 'hono';
335
- import type { Logger } from '@geekmidas/logger';
336
- import type { ServiceDiscovery } from '@geekmidas/services';
337
- import { Endpoint, ResponseBuilder } from '@geekmidas/constructs/endpoints';
338
- ${eventsImport}
339
- ${validatorImport}
340
- import { ${exportName} } from '${endpointImport.importPath}';
341
-
342
- export function setup${capitalize(exportName)}(
343
- app: Hono,
344
- serviceDiscovery: ServiceDiscovery<any, any>,
345
- logger: Logger,
346
- ): void {
347
- ${handler}
348
- }
349
- `;
350
- }
351
- /**
352
- * Generate a standalone full endpoint file
353
- */
354
- function generateFullEndpointFile(analysis, endpointImport) {
355
- const { exportName } = analysis;
356
- return `/**
357
- * Full endpoint: ${analysis.route} (${analysis.method})
358
- * Complex features: audits, RLS, rate limiting
359
- */
360
- import type { Hono } from 'hono';
361
- import type { ServiceDiscovery } from '@geekmidas/services';
362
- import { HonoEndpoint } from '@geekmidas/constructs/hono';
363
- import { ${exportName} } from '${endpointImport.importPath}';
364
-
365
- export function setup${capitalize(exportName)}(
366
- app: Hono,
367
- serviceDiscovery: ServiceDiscovery<any, any>,
368
- openApiOptions: any,
369
- ): void {
370
- HonoEndpoint.addRoutes([${exportName}] as any, serviceDiscovery, app, openApiOptions);
371
- }
372
- `;
373
- }
374
- /**
375
- * Generate tier index file that imports and calls all endpoint setup functions
376
- */
377
- function generateTierIndexFile(tier, analyses) {
378
- const tierEndpoints = analyses.filter((a) => a.tier === tier);
379
- if (tierEndpoints.length === 0) {
380
- if (tier === "minimal") return `// No minimal-tier endpoints in this build
381
- import type { Hono } from 'hono';
382
- import type { Logger } from '@geekmidas/logger';
383
-
384
- export function setupMinimalEndpoints(
385
- _app: Hono,
386
- _logger: Logger,
387
- ): void {
388
- // No minimal endpoints
389
- }
390
- `;
391
- if (tier === "standard") return `// No standard-tier endpoints in this build
392
- import type { Hono } from 'hono';
393
- import type { Logger } from '@geekmidas/logger';
394
- import type { ServiceDiscovery } from '@geekmidas/services';
395
-
396
- export function setupStandardEndpoints(
397
- _app: Hono,
398
- _serviceDiscovery: ServiceDiscovery<any, any>,
399
- _logger: Logger,
400
- ): void {
401
- // No standard endpoints
402
- }
403
- `;
404
- return `// No full-tier endpoints in this build
405
- import type { Hono } from 'hono';
406
- import type { ServiceDiscovery } from '@geekmidas/services';
407
-
408
- export function setupFullEndpoints(
409
- _app: Hono,
410
- _serviceDiscovery: ServiceDiscovery<any, any>,
411
- _enableOpenApi: boolean,
412
- ): void {
413
- // No full endpoints
414
- }
415
- `;
416
- }
417
- const imports = tierEndpoints.map((a) => `import { setup${capitalize(a.exportName)} } from './${a.exportName}.js';`).join("\n");
418
- if (tier === "minimal") {
419
- const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, logger);`).join("\n");
420
- return `/**
421
- * Minimal-tier endpoint index (${tierEndpoints.length} endpoints)
422
- * Near-raw-Hono performance
423
- */
424
- import type { Hono } from 'hono';
425
- import type { Logger } from '@geekmidas/logger';
426
- ${imports}
427
-
428
- export function setupMinimalEndpoints(
429
- app: Hono,
430
- logger: Logger,
431
- ): void {
432
- ${calls}
433
- }
434
- `;
435
- }
436
- if (tier === "standard") {
437
- const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, serviceDiscovery, logger);`).join("\n");
438
- return `/**
439
- * Standard-tier endpoint index (${tierEndpoints.length} endpoints)
440
- * Auth and/or services enabled
441
- */
442
- import type { Hono } from 'hono';
443
- import type { Logger } from '@geekmidas/logger';
444
- import type { ServiceDiscovery } from '@geekmidas/services';
445
- ${imports}
446
-
447
- export function setupStandardEndpoints(
448
- app: Hono,
449
- serviceDiscovery: ServiceDiscovery<any, any>,
450
- logger: Logger,
451
- ): void {
452
- ${calls}
453
- }
454
- `;
455
- }
456
- const calls = tierEndpoints.map((a) => ` setup${capitalize(a.exportName)}(app, serviceDiscovery, openApiOptions);`).join("\n");
457
- return `/**
458
- * Full-tier endpoint index (${tierEndpoints.length} endpoints)
459
- * Complex features: audits, RLS, rate limiting
460
- */
461
- import type { Hono } from 'hono';
462
- import type { ServiceDiscovery } from '@geekmidas/services';
463
- ${imports}
464
-
465
- export function setupFullEndpoints(
466
- app: Hono,
467
- serviceDiscovery: ServiceDiscovery<any, any>,
468
- enableOpenApi: boolean,
469
- ): void {
470
- const openApiOptions: any = enableOpenApi ? {
471
- docsPath: '/__docs',
472
- openApiOptions: {
473
- title: 'API Documentation',
474
- version: '1.0.0',
475
- description: 'Generated API documentation'
476
- }
477
- } : { docsPath: false };
478
-
479
- ${calls}
480
- }
481
- `;
482
- }
483
- /**
484
- * Generate validator imports for a single endpoint
485
- */
486
- function generateValidatorImportsForEndpoint(analysis) {
487
- const imports = [];
488
- if (analysis.features.hasBodyValidation) imports.push("validateBody");
489
- if (analysis.features.hasQueryValidation) imports.push("validateQuery");
490
- if (analysis.features.hasParamValidation) imports.push("validateParams");
491
- if (imports.length === 0) return "";
492
- return `import { ${imports.join(", ")} } from '../validators.js';`;
493
- }
494
- /**
495
- * Capitalize first letter
496
- */
497
- function capitalize(str) {
498
- return str.charAt(0).toUpperCase() + str.slice(1);
499
- }
500
- /**
501
- * Generate all endpoint files with nested folder structure (per-endpoint files)
502
- */
503
- function generateEndpointFilesNested(analyses, endpointImports) {
504
- const files = {
505
- "validators.ts": generateValidatorsFile(analyses),
506
- "minimal/index.ts": generateTierIndexFile("minimal", analyses),
507
- "standard/index.ts": generateTierIndexFile("standard", analyses),
508
- "full/index.ts": generateTierIndexFile("full", analyses),
509
- "index.ts": generateNestedIndexFile(analyses)
510
- };
511
- for (const analysis of analyses) {
512
- const endpointImport = endpointImports.find((i) => i.exportName === analysis.exportName);
513
- if (!endpointImport) continue;
514
- const fileName = `${analysis.tier}/${analysis.exportName}.ts`;
515
- switch (analysis.tier) {
516
- case "minimal":
517
- files[fileName] = generateMinimalEndpointFile(analysis, endpointImport);
518
- break;
519
- case "standard":
520
- files[fileName] = generateStandardEndpointFile(analysis, endpointImport);
521
- break;
522
- case "full": files[fileName] = generateFullEndpointFile(analysis, endpointImport);
523
- }
524
- }
525
- return files;
526
- }
527
- /**
528
- * Generate index.ts for nested structure
529
- */
530
- function generateNestedIndexFile(analyses) {
531
- const minimalCount = analyses.filter((a) => a.tier === "minimal").length;
532
- const standardCount = analyses.filter((a) => a.tier === "standard").length;
533
- const fullCount = analyses.filter((a) => a.tier === "full").length;
534
- return `/**
535
- * Generated optimized endpoints
536
- *
537
- * Build-time optimization tiers:
538
- * - minimal: ${minimalCount} endpoints (near-raw-Hono)
539
- * - standard: ${standardCount} endpoints (auth/services)
540
- * - full: ${fullCount} endpoints (audits/rls/rate-limit)
541
- */
542
- import type { EnvironmentParser } from '@geekmidas/envkit';
543
- import type { Logger } from '@geekmidas/logger';
544
- import type { Hono } from 'hono';
545
- import { ServiceDiscovery } from '@geekmidas/services';
546
- import { setupMinimalEndpoints } from './minimal/index.js';
547
- import { setupStandardEndpoints } from './standard/index.js';
548
- import { setupFullEndpoints } from './full/index.js';
549
-
550
- export async function setupEndpoints(
551
- app: Hono,
552
- envParser: EnvironmentParser<any>,
553
- logger: Logger,
554
- enableOpenApi: boolean = false,
555
- ): Promise<void> {
556
- const serviceDiscovery = ServiceDiscovery.getInstance(envParser);
557
-
558
- // Minimal handlers (${minimalCount} endpoints) - near-raw-Hono performance
559
- setupMinimalEndpoints(app, logger);
560
-
561
- // Standard handlers (${standardCount} endpoints) - auth/services
562
- setupStandardEndpoints(app, serviceDiscovery, logger);
563
-
564
- // Full handlers (${fullCount} endpoints) - audits/rls/rate-limit
565
- setupFullEndpoints(app, serviceDiscovery, enableOpenApi);
566
-
567
- // Add Swagger UI if OpenAPI is enabled
568
- if (enableOpenApi) {
569
- try {
570
- const { swaggerUI } = await import('@hono/swagger-ui');
571
- app.get('/__docs/ui', swaggerUI({ url: '/__docs' }));
572
- } catch {
573
- // @hono/swagger-ui not installed, skip Swagger UI
574
- }
575
- }
576
- }
577
- `;
578
- }
579
- //#endregion
580
7
  //#region src/generators/telemetry.ts
581
8
  /**
582
9
  * Every package `@geekmidas/telescope/instrumentation` loads at runtime.
@@ -834,7 +261,7 @@ var EndpointGenerator = class extends ConstructGenerator {
834
261
  const routes = [];
835
262
  if (constructs.length === 0) return routes;
836
263
  if (target === "server") {
837
- await this.generateEndpointsFile(outputDir, constructs, context);
264
+ await this.generateEndpointsFile(outputDir, constructs);
838
265
  const appFile = await this.generateAppFile(outputDir, context);
839
266
  routes.push({
840
267
  path: "*",
@@ -870,7 +297,7 @@ var EndpointGenerator = class extends ConstructGenerator {
870
297
  await writeFile(handlerPath, this.generateAWSApiGatewayV2Handler(importPath, exportName, context.storageDrivers));
871
298
  return handlerPath;
872
299
  }
873
- async generateEndpointsFile(outputDir, endpoints, context) {
300
+ async generateEndpointsFile(outputDir, endpoints) {
874
301
  const endpointsPath = join(outputDir, "endpoints.ts");
875
302
  const importsByFile = /* @__PURE__ */ new Map();
876
303
  for (const { path, key } of endpoints) {
@@ -878,19 +305,16 @@ var EndpointGenerator = class extends ConstructGenerator {
878
305
  if (!importsByFile.has(importPath)) importsByFile.set(importPath, []);
879
306
  importsByFile.get(importPath)?.push(key);
880
307
  }
881
- const endpointImports = Array.from(importsByFile.entries()).map(([importPath, exports]) => `import { ${exports.join(", ")} } from '${importPath}';`).join("\n");
882
- const allExportNames = endpoints.map(({ key }) => key);
883
- if (context.production?.enabled && context.production.optimizedHandlers) return this.generateOptimizedEndpointsFile(endpointsPath, endpoints, endpointImports, allExportNames);
884
308
  const content = `import type { EnvironmentParser } from '@geekmidas/envkit';
885
309
  import type { Logger } from '@geekmidas/logger';
886
310
  import { HonoEndpoint } from '@geekmidas/constructs/hono';
887
311
  import { Endpoint } from '@geekmidas/constructs/endpoints';
888
312
  import { ServiceDiscovery } from '@geekmidas/services';
889
313
  import type { Hono } from 'hono';
890
- ${endpointImports}
314
+ ${Array.from(importsByFile.entries()).map(([importPath, exports]) => `import { ${exports.join(", ")} } from '${importPath}';`).join("\n")}
891
315
 
892
316
  export const endpoints: Endpoint<any, any, any, any, any, any, any, any, any, any, any, any>[] = [
893
- ${allExportNames.join(",\n ")}
317
+ ${endpoints.map(({ key }) => key).join(",\n ")}
894
318
  ];
895
319
 
896
320
  export async function setupEndpoints(
@@ -927,41 +351,6 @@ export async function setupEndpoints(
927
351
  await writeFile(endpointsPath, content);
928
352
  return endpointsPath;
929
353
  }
930
- /**
931
- * Generate optimized endpoints files with nested folder structure (per-endpoint files)
932
- */
933
- async generateOptimizedEndpointsFile(endpointsPath, endpoints, _endpointImports, _allExportNames) {
934
- const logger = console;
935
- const outputDir = dirname(endpointsPath);
936
- const endpointsDir = join(outputDir, "endpoints");
937
- await mkdir(join(endpointsDir, "minimal"), { recursive: true });
938
- await mkdir(join(endpointsDir, "standard"), { recursive: true });
939
- await mkdir(join(endpointsDir, "full"), { recursive: true });
940
- const analyses = endpoints.map(({ key, construct }) => analyzeEndpoint(construct, key));
941
- const endpointImports = endpoints.map(({ key, path }) => {
942
- const tierDir = join(endpointsDir, "standard");
943
- return {
944
- exportName: key,
945
- importPath: relative(tierDir, path.relative).replace(/\.ts$/, ".js")
946
- };
947
- });
948
- const summary = summarizeAnalysis(analyses);
949
- logger.log(`\n📊 Endpoint Analysis:`);
950
- logger.log(` Total: ${summary.total} endpoints`);
951
- logger.log(` - Minimal (near-raw-Hono): ${summary.byTier.minimal} endpoints`);
952
- logger.log(` - Standard (auth/services): ${summary.byTier.standard} endpoints`);
953
- logger.log(` - Full (audits/rls/rate-limit): ${summary.byTier.full} endpoints`);
954
- const files = generateEndpointFilesNested(analyses, endpointImports);
955
- for (const [filename, content] of Object.entries(files)) {
956
- const filePath = join(endpointsDir, filename);
957
- await mkdir(dirname(filePath), { recursive: true });
958
- await writeFile(filePath, content);
959
- }
960
- const endpointFiles = Object.keys(files).filter((f) => !f.endsWith("index.ts") && !f.endsWith("validators.ts")).length;
961
- const indexFiles = Object.keys(files).filter((f) => f.endsWith("index.ts")).length;
962
- logger.log(` Generated ${endpointFiles} endpoint files + ${indexFiles} index files + validators.ts`);
963
- return join(endpointsDir, "index.ts");
964
- }
965
354
  async generateAppFile(outputDir, context) {
966
355
  if (context.production?.enabled) return this.generateProductionAppFile(outputDir, context);
967
356
  const appPath = join(outputDir, "app.ts");
@@ -1032,7 +421,7 @@ import { ${databaseApi.database.exportName} as __introspectedDb } from '${import
1032
421
  (honoApp as any).__injectWebSocket = injectWebSocket;
1033
422
  logger.info('Telescope WebSocket enabled');
1034
423
  } catch (e) {
1035
- logger.warn({ error: e }, 'WebSocket support not available - install @hono/node-ws for real-time updates');
424
+ logger.warn({ err: e }, 'WebSocket support not available - install @hono/node-ws for real-time updates');
1036
425
  }
1037
426
  ` : "";
1038
427
  let telescopeSetup = "";
@@ -1181,19 +570,19 @@ ${afterSetupCall}
1181
570
  // Mount pushed subscribers' routes and start polled ones. What comes
1182
571
  // back subscribes the routes, once the server can answer them.
1183
572
  const subscribeForPush = await setupSubscribers(honoApp, envParser, logger).catch((error) => {
1184
- logger.error({ error }, 'Failed to start subscribers');
573
+ logger.error({ err: error }, 'Failed to start subscribers');
1185
574
  return async (_port: number) => {};
1186
575
  });
1187
576
 
1188
577
  // Start queue workers in background (non-blocking, local development only)
1189
578
  await setupQueues(envParser, logger).catch((error) => {
1190
- logger.error({ error }, 'Failed to start queue workers');
579
+ logger.error({ err: error }, 'Failed to start queue workers');
1191
580
  });
1192
581
 
1193
582
  // Schedule this app's crons. Caught like the others: a scheduler that
1194
583
  // cannot start is not a reason for the HTTP server not to.
1195
584
  await setupCrons(envParser, logger).catch((error) => {
1196
- logger.error({ error }, 'Failed to schedule crons');
585
+ logger.error({ err: error }, 'Failed to schedule crons');
1197
586
  });
1198
587
 
1199
588
  logger.info({ port }, 'Starting server');
@@ -1269,19 +658,19 @@ export const handler = adapter.handler;
1269
658
  // Mount pushed subscribers' routes and start polled ones. What comes
1270
659
  // back subscribes the routes, once the server can answer them.
1271
660
  const subscribeForPush = await setupSubscribers(honoApp, envParser, logger).catch((error) => {
1272
- logger.error({ error }, 'Failed to start subscribers');
661
+ logger.error({ err: error }, 'Failed to start subscribers');
1273
662
  return async (_port: number) => {};
1274
663
  });
1275
664
 
1276
665
  // Start queue workers in background
1277
666
  await setupQueues(envParser, logger).catch((error) => {
1278
- logger.error({ error }, 'Failed to start queue workers');
667
+ logger.error({ err: error }, 'Failed to start queue workers');
1279
668
  });
1280
669
 
1281
670
  // Schedule this app's crons. Caught like the others: a scheduler that
1282
671
  // cannot start is not a reason for the HTTP server not to.
1283
672
  await setupCrons(envParser, logger).catch((error) => {
1284
- logger.error({ error }, 'Failed to schedule crons');
673
+ logger.error({ err: error }, 'Failed to schedule crons');
1285
674
  });
1286
675
  ` : "";
1287
676
  const subscriberImport = includeSubscribers ? `import { setupSubscribers } from './subscribers.js';
@@ -1309,14 +698,13 @@ import { setupCrons } from './crons.js';` : "";
1309
698
  if (typeof close === 'function') close.call(server, () => resolve());
1310
699
  else resolve();
1311
700
  });
1312
- await runShutdownHooks((error) => logger.error({ error }, 'Shutdown hook failed'));
701
+ await runShutdownHooks((error) => logger.error({ err: error }, 'Shutdown hook failed'));
1313
702
  process.exit(0);
1314
703
  };
1315
704
 
1316
705
  process.on('SIGTERM', shutdown);
1317
706
  process.on('SIGINT', shutdown);
1318
707
  ` : "";
1319
- const endpointsImportPath = production.optimizedHandlers ? "./endpoints/index.js" : "./endpoints.js";
1320
708
  const content = `/**
1321
709
  * Generated production server application
1322
710
  *
@@ -1328,7 +716,7 @@ import { setupCrons } from './crons.js';` : "";
1328
716
  */
1329
717
  import { Hono } from 'hono';
1330
718
  import type { Hono as HonoType } from 'hono';
1331
- ${enableGracefulShutdown ? "import { runShutdownHooks } from '@geekmidas/constructs';\n" : ""}import { setupEndpoints } from '${endpointsImportPath}';
719
+ ${enableGracefulShutdown ? "import { runShutdownHooks } from '@geekmidas/constructs';\n" : ""}import { setupEndpoints } from './endpoints.js';
1332
720
  ${subscriberImport}
1333
721
  ${runtime.imports}
1334
722
  ${runtime.bindings}
@@ -1385,7 +773,7 @@ export async function createApp(app?: HonoType): Promise<ServerApp> {
1385
773
  http.statusCode as 500,
1386
774
  );
1387
775
  }
1388
- logger.error({ error }, 'Unhandled error');
776
+ logger.error({ err: error }, 'Unhandled error');
1389
777
  return c.json({ message: 'Internal Server Error' }, 500);
1390
778
  });
1391
779
  ${cors.setup}${beforeSetupCall}
@@ -1970,4 +1358,4 @@ function unknownType(name) {
1970
1358
  //#endregion
1971
1359
  export { telemetryFor as i, EndpointGenerator as n, runtimeFor as r, OpenApiTsGenerator as t };
1972
1360
 
1973
- //# sourceMappingURL=OpenApiTsGenerator-BYD9EcJi.mjs.map
1361
+ //# sourceMappingURL=OpenApiTsGenerator-Bhr_XWWN.mjs.map