@geekmidas/cli 0.1.0 → 0.2.1

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 (146) hide show
  1. package/README.md +63 -13
  2. package/dist/{CronGenerator-Ctl4USy4.cjs → CronGenerator-1PflEYe2.cjs} +8 -7
  3. package/dist/CronGenerator-1PflEYe2.cjs.map +1 -0
  4. package/dist/{CronGenerator-ClbRcmz_.mjs → CronGenerator-DXRfHQcV.mjs} +6 -5
  5. package/dist/CronGenerator-DXRfHQcV.mjs.map +1 -0
  6. package/dist/{EndpointGenerator-Dj7AumHi.cjs → EndpointGenerator-BbGrDiCP.cjs} +134 -34
  7. package/dist/EndpointGenerator-BbGrDiCP.cjs.map +1 -0
  8. package/dist/{EndpointGenerator-uBA1ixUw.mjs → EndpointGenerator-BmZ9BxbO.mjs} +132 -32
  9. package/dist/EndpointGenerator-BmZ9BxbO.mjs.map +1 -0
  10. package/dist/{FunctionGenerator-DN681IUn.cjs → FunctionGenerator-Clw64SwQ.cjs} +8 -7
  11. package/dist/FunctionGenerator-Clw64SwQ.cjs.map +1 -0
  12. package/dist/{FunctionGenerator-crAa-JC7.mjs → FunctionGenerator-DOEB_yPh.mjs} +6 -5
  13. package/dist/FunctionGenerator-DOEB_yPh.mjs.map +1 -0
  14. package/dist/{Generator-C3tYSTQY.cjs → Generator-CDoEXCDg.cjs} +2 -2
  15. package/dist/Generator-CDoEXCDg.cjs.map +1 -0
  16. package/dist/{Generator-CDt4pB3W.mjs → Generator-UanJW0_V.mjs} +1 -1
  17. package/dist/Generator-UanJW0_V.mjs.map +1 -0
  18. package/dist/SubscriberGenerator-CB-NHtZW.cjs +205 -0
  19. package/dist/SubscriberGenerator-CB-NHtZW.cjs.map +1 -0
  20. package/dist/SubscriberGenerator-Cuu4co3-.mjs +199 -0
  21. package/dist/SubscriberGenerator-Cuu4co3-.mjs.map +1 -0
  22. package/dist/build/index.cjs +10 -9
  23. package/dist/build/index.mjs +8 -7
  24. package/dist/build/manifests.cjs +1 -1
  25. package/dist/build/manifests.mjs +1 -1
  26. package/dist/build/providerResolver.cjs +1 -1
  27. package/dist/build-Ajg356_5.cjs +89 -0
  28. package/dist/build-Ajg356_5.cjs.map +1 -0
  29. package/dist/build-zpABVsc0.mjs +83 -0
  30. package/dist/build-zpABVsc0.mjs.map +1 -0
  31. package/dist/{chunk-CsX-DzYB.cjs → chunk-CUT6urMc.cjs} +0 -12
  32. package/dist/{config-RcNESK0T.cjs → config-D1EpSGk6.cjs} +2 -2
  33. package/dist/{config-RcNESK0T.cjs.map → config-D1EpSGk6.cjs.map} +1 -1
  34. package/dist/{config-CXxYmz_o.mjs → config-U-mdW-7Y.mjs} +1 -1
  35. package/dist/{config-CXxYmz_o.mjs.map → config-U-mdW-7Y.mjs.map} +1 -1
  36. package/dist/config.cjs +1 -1
  37. package/dist/config.mjs +1 -1
  38. package/dist/generators/CronGenerator.cjs +2 -2
  39. package/dist/generators/CronGenerator.mjs +2 -2
  40. package/dist/generators/EndpointGenerator.cjs +2 -2
  41. package/dist/generators/EndpointGenerator.mjs +2 -2
  42. package/dist/generators/FunctionGenerator.cjs +2 -2
  43. package/dist/generators/FunctionGenerator.mjs +2 -2
  44. package/dist/generators/Generator.cjs +1 -1
  45. package/dist/generators/Generator.mjs +1 -1
  46. package/dist/generators/SubscriberGenerator.cjs +4 -0
  47. package/dist/generators/SubscriberGenerator.mjs +4 -0
  48. package/dist/generators/index.cjs +8 -6
  49. package/dist/generators/index.mjs +6 -5
  50. package/dist/index.cjs +18 -14
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.mjs +15 -11
  53. package/dist/index.mjs.map +1 -1
  54. package/dist/{manifests-HX4z4kkz.mjs → manifests-BrJXpHrf.mjs} +5 -4
  55. package/dist/manifests-BrJXpHrf.mjs.map +1 -0
  56. package/dist/{manifests-BTtfDMX8.cjs → manifests-D0saShvH.cjs} +6 -5
  57. package/dist/manifests-D0saShvH.cjs.map +1 -0
  58. package/dist/{openapi-BivnatiC.mjs → openapi-BQx3_JbM.mjs} +4 -4
  59. package/dist/openapi-BQx3_JbM.mjs.map +1 -0
  60. package/dist/{openapi-DW-qF3oW.cjs → openapi-CMLr04cz.cjs} +6 -6
  61. package/dist/openapi-CMLr04cz.cjs.map +1 -0
  62. package/dist/{openapi-react-query-lgS7AVEz.mjs → openapi-react-query-DbrWwQzb.mjs} +3 -2
  63. package/dist/openapi-react-query-DbrWwQzb.mjs.map +1 -0
  64. package/dist/{openapi-react-query-J0BzBHhN.cjs → openapi-react-query-Dvjqx_Eo.cjs} +4 -3
  65. package/dist/openapi-react-query-Dvjqx_Eo.cjs.map +1 -0
  66. package/dist/openapi-react-query.cjs +1 -1
  67. package/dist/openapi-react-query.mjs +1 -1
  68. package/dist/openapi.cjs +4 -4
  69. package/dist/openapi.mjs +4 -4
  70. package/dist/{providerResolver-Cs-0YCaP.cjs → providerResolver-DgvzNfP4.cjs} +1 -1
  71. package/dist/{providerResolver-Cs-0YCaP.cjs.map → providerResolver-DgvzNfP4.cjs.map} +1 -1
  72. package/examples/cron-example.ts +1 -1
  73. package/examples/function-example.ts +1 -1
  74. package/examples/logger.ts +1 -1
  75. package/package.json +6 -3
  76. package/src/__tests__/openapi-react-query.spec.ts +506 -0
  77. package/src/__tests__/openapi.spec.ts +362 -0
  78. package/src/__tests__/test-helpers.ts +10 -8
  79. package/src/build/__tests__/index-new.spec.ts +41 -42
  80. package/src/build/index.ts +89 -28
  81. package/src/build/manifests.ts +4 -1
  82. package/src/build/types.ts +2 -2
  83. package/src/generators/CronGenerator.ts +3 -2
  84. package/src/generators/EndpointGenerator.ts +141 -42
  85. package/src/generators/FunctionGenerator.ts +3 -2
  86. package/src/generators/Generator.ts +1 -1
  87. package/src/generators/SubscriberGenerator.ts +274 -0
  88. package/src/generators/__tests__/CronGenerator.spec.ts +1 -1
  89. package/src/generators/__tests__/EndpointGenerator.spec.ts +33 -11
  90. package/src/generators/__tests__/FunctionGenerator.spec.ts +21 -22
  91. package/src/generators/__tests__/SubscriberGenerator.spec.ts +392 -0
  92. package/src/generators/index.ts +1 -0
  93. package/src/openapi-react-query.ts +2 -1
  94. package/src/openapi.ts +1 -1
  95. package/src/types.ts +18 -0
  96. package/dist/CronGenerator-ClbRcmz_.mjs.map +0 -1
  97. package/dist/CronGenerator-Ctl4USy4.cjs.map +0 -1
  98. package/dist/EndpointGenerator-Dj7AumHi.cjs.map +0 -1
  99. package/dist/EndpointGenerator-uBA1ixUw.mjs.map +0 -1
  100. package/dist/FunctionGenerator-DN681IUn.cjs.map +0 -1
  101. package/dist/FunctionGenerator-crAa-JC7.mjs.map +0 -1
  102. package/dist/Generator-C3tYSTQY.cjs.map +0 -1
  103. package/dist/Generator-CDt4pB3W.mjs.map +0 -1
  104. package/dist/__tests__/config.spec.cjs +0 -98
  105. package/dist/__tests__/config.spec.cjs.map +0 -1
  106. package/dist/__tests__/config.spec.mjs +0 -97
  107. package/dist/__tests__/config.spec.mjs.map +0 -1
  108. package/dist/__tests__/test-helpers.cjs +0 -14
  109. package/dist/__tests__/test-helpers.mjs +0 -4
  110. package/dist/build/__tests__/index-new.spec.cjs +0 -286
  111. package/dist/build/__tests__/index-new.spec.cjs.map +0 -1
  112. package/dist/build/__tests__/index-new.spec.mjs +0 -285
  113. package/dist/build/__tests__/index-new.spec.mjs.map +0 -1
  114. package/dist/build-BZdwxCLW.mjs +0 -64
  115. package/dist/build-BZdwxCLW.mjs.map +0 -1
  116. package/dist/build-BfQFnU5-.cjs +0 -70
  117. package/dist/build-BfQFnU5-.cjs.map +0 -1
  118. package/dist/esm-9eeZntth.mjs +0 -3777
  119. package/dist/esm-9eeZntth.mjs.map +0 -1
  120. package/dist/esm-Crmo4h9t.cjs +0 -4392
  121. package/dist/esm-Crmo4h9t.cjs.map +0 -1
  122. package/dist/esm-CsJbr7gi.mjs +0 -3
  123. package/dist/esm-w09tAC4l.cjs +0 -8
  124. package/dist/generators/__tests__/CronGenerator.spec.cjs +0 -216
  125. package/dist/generators/__tests__/CronGenerator.spec.cjs.map +0 -1
  126. package/dist/generators/__tests__/CronGenerator.spec.mjs +0 -215
  127. package/dist/generators/__tests__/CronGenerator.spec.mjs.map +0 -1
  128. package/dist/generators/__tests__/EndpointGenerator.spec.cjs +0 -182
  129. package/dist/generators/__tests__/EndpointGenerator.spec.cjs.map +0 -1
  130. package/dist/generators/__tests__/EndpointGenerator.spec.mjs +0 -181
  131. package/dist/generators/__tests__/EndpointGenerator.spec.mjs.map +0 -1
  132. package/dist/generators/__tests__/FunctionGenerator.spec.cjs +0 -152
  133. package/dist/generators/__tests__/FunctionGenerator.spec.cjs.map +0 -1
  134. package/dist/generators/__tests__/FunctionGenerator.spec.mjs +0 -151
  135. package/dist/generators/__tests__/FunctionGenerator.spec.mjs.map +0 -1
  136. package/dist/manifests-BTtfDMX8.cjs.map +0 -1
  137. package/dist/manifests-HX4z4kkz.mjs.map +0 -1
  138. package/dist/openapi-BivnatiC.mjs.map +0 -1
  139. package/dist/openapi-DW-qF3oW.cjs.map +0 -1
  140. package/dist/openapi-react-query-J0BzBHhN.cjs.map +0 -1
  141. package/dist/openapi-react-query-lgS7AVEz.mjs.map +0 -1
  142. package/dist/test-helpers-ARd8GDgx.cjs +0 -199
  143. package/dist/test-helpers-ARd8GDgx.cjs.map +0 -1
  144. package/dist/test-helpers-DdVBk23F.mjs +0 -133
  145. package/dist/test-helpers-DdVBk23F.mjs.map +0 -1
  146. /package/dist/{generators-_pY7sHy1.cjs → generators-CEKtVh81.cjs} +0 -0
@@ -1,7 +1,7 @@
1
- import { ConstructGenerator } from "./Generator-CDt4pB3W.mjs";
1
+ import { ConstructGenerator } from "./Generator-UanJW0_V.mjs";
2
2
  import { mkdir, writeFile } from "node:fs/promises";
3
3
  import { dirname, join, relative } from "node:path";
4
- import { Endpoint } from "@geekmidas/api/server";
4
+ import { Endpoint } from "@geekmidas/constructs/endpoints";
5
5
 
6
6
  //#region src/generators/EndpointGenerator.ts
7
7
  var EndpointGenerator = class extends ConstructGenerator {
@@ -15,13 +15,14 @@ var EndpointGenerator = class extends ConstructGenerator {
15
15
  const routes = [];
16
16
  if (constructs.length === 0) return routes;
17
17
  if (provider === "server") {
18
- const serverFile = await this.generateServerFile(outputDir, constructs, context, enableOpenApi);
18
+ await this.generateEndpointsFile(outputDir, constructs, context);
19
+ const appFile = await this.generateAppFile(outputDir, context);
19
20
  routes.push({
20
21
  path: "*",
21
22
  method: "ALL",
22
- handler: relative(process.cwd(), serverFile)
23
+ handler: relative(process.cwd(), appFile)
23
24
  });
24
- logger.log(`Generated server app with ${constructs.length} endpoints${enableOpenApi ? " (OpenAPI enabled)" : ""}`);
25
+ logger.log(`Generated server with ${constructs.length} endpoints${enableOpenApi ? " (OpenAPI enabled)" : ""}`);
25
26
  } else if (provider === "aws-lambda") {
26
27
  const routesDir = join(outputDir, "routes");
27
28
  await mkdir(routesDir, { recursive: true });
@@ -30,7 +31,8 @@ var EndpointGenerator = class extends ConstructGenerator {
30
31
  const routeInfo = {
31
32
  path: construct._path,
32
33
  method: construct.method,
33
- handler: relative(process.cwd(), handlerFile).replace(/\.ts$/, ".handler")
34
+ handler: relative(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
35
+ environment: await construct.getEnvironment()
34
36
  };
35
37
  routes.push(routeInfo);
36
38
  logger.log(`Generated handler for ${routeInfo.method} ${routeInfo.path}`);
@@ -40,7 +42,8 @@ var EndpointGenerator = class extends ConstructGenerator {
40
42
  const routeInfo = {
41
43
  path: construct._path,
42
44
  method: construct.method,
43
- handler: relative(process.cwd(), handlerFile).replace(/\.ts$/, ".handler")
45
+ handler: relative(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
46
+ environment: await construct.getEnvironment()
44
47
  };
45
48
  routes.push(routeInfo);
46
49
  logger.log(`Generated handler for ${routeInfo.method} ${routeInfo.path}`);
@@ -69,35 +72,36 @@ var EndpointGenerator = class extends ConstructGenerator {
69
72
  await writeFile(handlerPath, content);
70
73
  return handlerPath;
71
74
  }
72
- async generateServerFile(outputDir, endpoints, context, enableOpenApi) {
73
- const serverFileName = "app.ts";
74
- const serverPath = join(outputDir, serverFileName);
75
+ async generateEndpointsFile(outputDir, endpoints, context) {
76
+ const endpointsFileName = "endpoints.ts";
77
+ const endpointsPath = join(outputDir, endpointsFileName);
75
78
  const importsByFile = /* @__PURE__ */ new Map();
76
79
  for (const { path, key } of endpoints) {
77
- const relativePath = relative(dirname(serverPath), path.relative);
80
+ const relativePath = relative(dirname(endpointsPath), path.relative);
78
81
  const importPath = relativePath.replace(/\.ts$/, ".js");
79
82
  if (!importsByFile.has(importPath)) importsByFile.set(importPath, []);
80
83
  importsByFile.get(importPath).push(key);
81
84
  }
82
- const relativeEnvParserPath = relative(dirname(serverPath), context.envParserPath);
83
- const relativeLoggerPath = relative(dirname(serverPath), context.loggerPath);
84
85
  const imports = Array.from(importsByFile.entries()).map(([importPath, exports]) => `import { ${exports.join(", ")} } from '${importPath}';`).join("\n");
85
86
  const allExportNames = endpoints.map(({ key }) => key);
86
- const content = `import { HonoEndpoint } from '@geekmidas/api/hono';
87
- import { Endpoint } from '@geekmidas/api/server';
88
- import { ServiceDiscovery } from '@geekmidas/api/services';
89
- import { Hono } from 'hono';
90
- import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
91
- import ${context.loggerImportPattern} from '${relativeLoggerPath}';
87
+ const content = `import type { EnvironmentParser } from '@geekmidas/envkit';
88
+ import type { Logger } from '@geekmidas/logger';
89
+ import { HonoEndpoint } from '@geekmidas/constructs/hono';
90
+ import { Endpoint } from '@geekmidas/constructs/endpoints';
91
+ import { ServiceDiscovery } from '@geekmidas/services';
92
+ import type { Hono } from 'hono';
92
93
  ${imports}
93
94
 
94
- export function createApp(app?: Hono, enableOpenApi: boolean = ${enableOpenApi}): Hono {
95
- const honoApp = app || new Hono();
96
-
97
- const endpoints: Endpoint<any, any, any, any, any, any, any>[] = [
98
- ${allExportNames.join(",\n ")}
99
- ];
95
+ const endpoints: Endpoint<any, any, any, any, any, any, any, any>[] = [
96
+ ${allExportNames.join(",\n ")}
97
+ ];
100
98
 
99
+ export function setupEndpoints(
100
+ app: Hono,
101
+ envParser: EnvironmentParser<any>,
102
+ logger: Logger,
103
+ enableOpenApi: boolean = true,
104
+ ): void {
101
105
  const serviceDiscovery = ServiceDiscovery.getInstance(
102
106
  logger,
103
107
  envParser
@@ -113,19 +117,115 @@ export function createApp(app?: Hono, enableOpenApi: boolean = ${enableOpenApi})
113
117
  }
114
118
  } : { docsPath: false };
115
119
 
116
- HonoEndpoint.addRoutes(endpoints, serviceDiscovery, honoApp, openApiOptions);
120
+ HonoEndpoint.addRoutes(endpoints, serviceDiscovery, app, openApiOptions);
121
+ }
122
+ `;
123
+ await writeFile(endpointsPath, content);
124
+ return endpointsPath;
125
+ }
126
+ async generateAppFile(outputDir, context) {
127
+ const appFileName = "app.ts";
128
+ const appPath = join(outputDir, appFileName);
129
+ const relativeLoggerPath = relative(dirname(appPath), context.loggerPath);
130
+ const relativeEnvParserPath = relative(dirname(appPath), context.envParserPath);
131
+ const content = `/**
132
+ * Generated server application
133
+ *
134
+ * ⚠️ WARNING: This is for LOCAL DEVELOPMENT ONLY
135
+ * The subscriber polling mechanism is not production-ready.
136
+ * For production, use AWS Lambda with SQS/SNS event sources.
137
+ */
138
+ import { Hono } from 'hono';
139
+ import type { Hono as HonoType } from 'hono';
140
+ import { setupEndpoints } from './endpoints.js';
141
+ import { setupSubscribers } from './subscribers.js';
142
+ import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
143
+ import ${context.loggerImportPattern} from '${relativeLoggerPath}';
117
144
 
118
- return honoApp;
145
+ export interface ServerApp {
146
+ app: HonoType;
147
+ start: (options?: {
148
+ port?: number;
149
+ serve: (app: HonoType, port: number) => void | Promise<void>;
150
+ }) => Promise<void>;
151
+ }
152
+
153
+ /**
154
+ * Create and configure the Hono application
155
+ *
156
+ * @param app - Optional Hono app instance to configure (creates new one if not provided)
157
+ * @param enableOpenApi - Enable OpenAPI documentation (default: true)
158
+ * @returns Server app with configured Hono app and start function
159
+ *
160
+ * @example
161
+ * // With Bun
162
+ * import { createApp } from './.gkm/server/app.js';
163
+ *
164
+ * const { app, start } = createApp();
165
+ *
166
+ * await start({
167
+ * port: 3000,
168
+ * serve: (app, port) => {
169
+ * Bun.serve({ port, fetch: app.fetch });
170
+ * }
171
+ * });
172
+ *
173
+ * @example
174
+ * // With Node.js (using @hono/node-server)
175
+ * import { serve } from '@hono/node-server';
176
+ * import { createApp } from './.gkm/server/app.js';
177
+ *
178
+ * const { app, start } = createApp();
179
+ *
180
+ * await start({
181
+ * port: 3000,
182
+ * serve: (app, port) => {
183
+ * serve({ fetch: app.fetch, port });
184
+ * }
185
+ * });
186
+ */
187
+ export function createApp(app?: HonoType, enableOpenApi: boolean = true): ServerApp {
188
+ const honoApp = app || new Hono();
189
+
190
+ // Setup HTTP endpoints
191
+ setupEndpoints(honoApp, envParser, logger, enableOpenApi);
192
+
193
+ return {
194
+ app: honoApp,
195
+ async start(options) {
196
+ if (!options?.serve) {
197
+ throw new Error(
198
+ 'serve function is required. Pass a serve function for your runtime:\\n' +
199
+ ' - Bun: (app, port) => Bun.serve({ port, fetch: app.fetch })\\n' +
200
+ ' - Node: (app, port) => serve({ fetch: app.fetch, port })'
201
+ );
202
+ }
203
+
204
+ const port = options.port ?? 3000;
205
+
206
+ // Start subscribers in background (non-blocking, local development only)
207
+ await setupSubscribers(envParser, logger).catch((error) => {
208
+ logger.error({ error }, 'Failed to start subscribers');
209
+ });
210
+
211
+ logger.info({ port }, 'Starting server');
212
+
213
+ // Start HTTP server using provided serve function
214
+ await options.serve(honoApp, port);
215
+
216
+ logger.info({ port }, 'Server started');
217
+ }
218
+ };
119
219
  }
120
220
 
121
221
  // Default export for convenience
122
222
  export default createApp;
123
223
  `;
124
- await writeFile(serverPath, content);
125
- return serverPath;
224
+ await writeFile(appPath, content);
225
+ return appPath;
126
226
  }
127
227
  generateAWSApiGatewayV1Handler(importPath, exportName, envParserPath, envParserImportPattern) {
128
- return `import { AmazonApiGatewayV1Endpoint } from '@geekmidas/api/aws-apigateway';
228
+ return `import { AmazonApiGatewayV1Endpoint } from '@geekmidas/constructs/aws';
129
229
  import { ${exportName} } from '${importPath}';
130
230
  import ${envParserImportPattern} from '${envParserPath}';
131
231
 
@@ -135,7 +235,7 @@ export const handler = adapter.handler;
135
235
  `;
136
236
  }
137
237
  generateAWSApiGatewayV2Handler(importPath, exportName, envParserPath, envParserImportPattern) {
138
- return `import { AmazonApiGatewayV2Endpoint } from '@geekmidas/api/aws-apigateway';
238
+ return `import { AmazonApiGatewayV2Endpoint } from '@geekmidas/constructs/aws';
139
239
  import { ${exportName} } from '${importPath}';
140
240
  import ${envParserImportPattern} from '${envParserPath}';
141
241
 
@@ -155,4 +255,4 @@ export const handler = ${exportName};
155
255
 
156
256
  //#endregion
157
257
  export { EndpointGenerator };
158
- //# sourceMappingURL=EndpointGenerator-uBA1ixUw.mjs.map
258
+ //# sourceMappingURL=EndpointGenerator-BmZ9BxbO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EndpointGenerator-BmZ9BxbO.mjs","names":["value: any","context: BuildContext","constructs: GeneratedConstruct<Endpoint<any, any, any, any, any, any>>[]","outputDir: string","options?: GeneratorOptions","routes: RouteInfo[]","routeInfo: RouteInfo","sourceFile: string","exportName: string","provider: LegacyProvider","_endpoint: Endpoint<any, any, any, any, any, any>","content: string","endpoints: GeneratedConstruct<Endpoint<any, any, any, any, any, any>>[]","importPath: string","envParserPath: string","envParserImportPattern: string"],"sources":["../src/generators/EndpointGenerator.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { Endpoint } from '@geekmidas/constructs/endpoints';\nimport type { BuildContext } from '../build/types';\nimport type { LegacyProvider, RouteInfo } from '../types';\nimport {\n ConstructGenerator,\n type GeneratedConstruct,\n type GeneratorOptions,\n} from './Generator';\n\nexport class EndpointGenerator extends ConstructGenerator<\n Endpoint<any, any, any, any, any, any>,\n RouteInfo[]\n> {\n isConstruct(value: any): value is Endpoint<any, any, any, any, any, any> {\n return Endpoint.isEndpoint(value);\n }\n\n async build(\n context: BuildContext,\n constructs: GeneratedConstruct<Endpoint<any, any, any, any, any, any>>[],\n outputDir: string,\n options?: GeneratorOptions,\n ): Promise<RouteInfo[]> {\n const provider = options?.provider || 'aws-apigatewayv2';\n const enableOpenApi = options?.enableOpenApi || false;\n const logger = console;\n const routes: RouteInfo[] = [];\n\n if (constructs.length === 0) {\n return routes;\n }\n\n if (provider === 'server') {\n // Generate endpoints.ts and app.ts\n await this.generateEndpointsFile(outputDir, constructs, context);\n const appFile = await this.generateAppFile(outputDir, context);\n\n routes.push({\n path: '*',\n method: 'ALL',\n handler: relative(process.cwd(), appFile),\n });\n\n logger.log(\n `Generated server with ${constructs.length} endpoints${enableOpenApi ? ' (OpenAPI enabled)' : ''}`,\n );\n } else if (provider === 'aws-lambda') {\n // For aws-lambda, create routes subdirectory\n const routesDir = join(outputDir, 'routes');\n await mkdir(routesDir, { recursive: true });\n\n // Generate individual handlers for API Gateway routes\n for (const { key, construct, path } of constructs) {\n const handlerFile = await this.generateHandlerFile(\n routesDir,\n path.relative,\n key,\n 'aws-apigatewayv2',\n construct,\n context,\n );\n\n const routeInfo: RouteInfo = {\n path: construct._path,\n method: construct.method,\n handler: relative(process.cwd(), handlerFile).replace(\n /\\.ts$/,\n '.handler',\n ),\n environment: await construct.getEnvironment(),\n };\n\n routes.push(routeInfo);\n logger.log(\n `Generated handler for ${routeInfo.method} ${routeInfo.path}`,\n );\n }\n } else {\n // Generate individual handler files for AWS API Gateway providers\n for (const { key, construct, path } of constructs) {\n const handlerFile = await this.generateHandlerFile(\n outputDir,\n path.relative,\n key,\n provider,\n construct,\n context,\n );\n\n const routeInfo: RouteInfo = {\n path: construct._path,\n method: construct.method,\n handler: relative(process.cwd(), handlerFile).replace(\n /\\.ts$/,\n '.handler',\n ),\n environment: await construct.getEnvironment(),\n };\n\n routes.push(routeInfo);\n logger.log(\n `Generated handler for ${routeInfo.method} ${routeInfo.path}`,\n );\n }\n }\n\n return routes;\n }\n\n private async generateHandlerFile(\n outputDir: string,\n sourceFile: string,\n exportName: string,\n provider: LegacyProvider,\n _endpoint: Endpoint<any, any, any, any, any, any>,\n context: BuildContext,\n ): Promise<string> {\n const handlerFileName = `${exportName}.ts`;\n const handlerPath = join(outputDir, handlerFileName);\n\n const relativePath = relative(dirname(handlerPath), sourceFile);\n const importPath = relativePath.replace(/\\.ts$/, '.js');\n\n const relativeEnvParserPath = relative(\n dirname(handlerPath),\n context.envParserPath,\n );\n\n let content: string;\n\n switch (provider) {\n case 'aws-apigatewayv1':\n content = this.generateAWSApiGatewayV1Handler(\n importPath,\n exportName,\n relativeEnvParserPath,\n context.envParserImportPattern,\n );\n break;\n case 'aws-apigatewayv2':\n content = this.generateAWSApiGatewayV2Handler(\n importPath,\n exportName,\n relativeEnvParserPath,\n context.envParserImportPattern,\n );\n break;\n case 'server':\n content = this.generateServerHandler(importPath, exportName);\n break;\n default:\n throw new Error(`Unsupported provider: ${provider}`);\n }\n\n await writeFile(handlerPath, content);\n return handlerPath;\n }\n\n private async generateEndpointsFile(\n outputDir: string,\n endpoints: GeneratedConstruct<Endpoint<any, any, any, any, any, any>>[],\n context: BuildContext,\n ): Promise<string> {\n const endpointsFileName = 'endpoints.ts';\n const endpointsPath = join(outputDir, endpointsFileName);\n\n // Group imports by file\n const importsByFile = new Map<string, string[]>();\n\n for (const { path, key } of endpoints) {\n const relativePath = relative(dirname(endpointsPath), path.relative);\n const importPath = relativePath.replace(/\\.ts$/, '.js');\n\n if (!importsByFile.has(importPath)) {\n importsByFile.set(importPath, []);\n }\n importsByFile.get(importPath)!.push(key);\n }\n\n // Generate import statements\n const imports = Array.from(importsByFile.entries())\n .map(\n ([importPath, exports]) =>\n `import { ${exports.join(', ')} } from '${importPath}';`,\n )\n .join('\\n');\n\n const allExportNames = endpoints.map(({ key }) => key);\n\n const content = `import type { EnvironmentParser } from '@geekmidas/envkit';\nimport type { Logger } from '@geekmidas/logger';\nimport { HonoEndpoint } from '@geekmidas/constructs/hono';\nimport { Endpoint } from '@geekmidas/constructs/endpoints';\nimport { ServiceDiscovery } from '@geekmidas/services';\nimport type { Hono } from 'hono';\n${imports}\n\nconst endpoints: Endpoint<any, any, any, any, any, any, any, any>[] = [\n ${allExportNames.join(',\\n ')}\n];\n\nexport function setupEndpoints(\n app: Hono,\n envParser: EnvironmentParser<any>,\n logger: Logger,\n enableOpenApi: boolean = true,\n): void {\n const serviceDiscovery = ServiceDiscovery.getInstance(\n logger,\n envParser\n );\n\n // Configure OpenAPI options based on enableOpenApi flag\n const openApiOptions: any = enableOpenApi ? {\n docsPath: '/docs',\n openApiOptions: {\n title: 'API Documentation',\n version: '1.0.0',\n description: 'Generated API documentation'\n }\n } : { docsPath: false };\n\n HonoEndpoint.addRoutes(endpoints, serviceDiscovery, app, openApiOptions);\n}\n`;\n\n await writeFile(endpointsPath, content);\n\n return endpointsPath;\n }\n\n private async generateAppFile(\n outputDir: string,\n context: BuildContext,\n ): Promise<string> {\n const appFileName = 'app.ts';\n const appPath = join(outputDir, appFileName);\n\n const relativeLoggerPath = relative(dirname(appPath), context.loggerPath);\n\n const relativeEnvParserPath = relative(\n dirname(appPath),\n context.envParserPath,\n );\n\n const content = `/**\n * Generated server application\n *\n * ⚠️ WARNING: This is for LOCAL DEVELOPMENT ONLY\n * The subscriber polling mechanism is not production-ready.\n * For production, use AWS Lambda with SQS/SNS event sources.\n */\nimport { Hono } from 'hono';\nimport type { Hono as HonoType } from 'hono';\nimport { setupEndpoints } from './endpoints.js';\nimport { setupSubscribers } from './subscribers.js';\nimport ${context.envParserImportPattern} from '${relativeEnvParserPath}';\nimport ${context.loggerImportPattern} from '${relativeLoggerPath}';\n\nexport interface ServerApp {\n app: HonoType;\n start: (options?: {\n port?: number;\n serve: (app: HonoType, port: number) => void | Promise<void>;\n }) => Promise<void>;\n}\n\n/**\n * Create and configure the Hono application\n *\n * @param app - Optional Hono app instance to configure (creates new one if not provided)\n * @param enableOpenApi - Enable OpenAPI documentation (default: true)\n * @returns Server app with configured Hono app and start function\n *\n * @example\n * // With Bun\n * import { createApp } from './.gkm/server/app.js';\n *\n * const { app, start } = createApp();\n *\n * await start({\n * port: 3000,\n * serve: (app, port) => {\n * Bun.serve({ port, fetch: app.fetch });\n * }\n * });\n *\n * @example\n * // With Node.js (using @hono/node-server)\n * import { serve } from '@hono/node-server';\n * import { createApp } from './.gkm/server/app.js';\n *\n * const { app, start } = createApp();\n *\n * await start({\n * port: 3000,\n * serve: (app, port) => {\n * serve({ fetch: app.fetch, port });\n * }\n * });\n */\nexport function createApp(app?: HonoType, enableOpenApi: boolean = true): ServerApp {\n const honoApp = app || new Hono();\n\n // Setup HTTP endpoints\n setupEndpoints(honoApp, envParser, logger, enableOpenApi);\n\n return {\n app: honoApp,\n async start(options) {\n if (!options?.serve) {\n throw new Error(\n 'serve function is required. Pass a serve function for your runtime:\\\\n' +\n ' - Bun: (app, port) => Bun.serve({ port, fetch: app.fetch })\\\\n' +\n ' - Node: (app, port) => serve({ fetch: app.fetch, port })'\n );\n }\n\n const port = options.port ?? 3000;\n\n // Start subscribers in background (non-blocking, local development only)\n await setupSubscribers(envParser, logger).catch((error) => {\n logger.error({ error }, 'Failed to start subscribers');\n });\n\n logger.info({ port }, 'Starting server');\n\n // Start HTTP server using provided serve function\n await options.serve(honoApp, port);\n\n logger.info({ port }, 'Server started');\n }\n };\n}\n\n// Default export for convenience\nexport default createApp;\n`;\n\n await writeFile(appPath, content);\n\n return appPath;\n }\n\n private generateAWSApiGatewayV1Handler(\n importPath: string,\n exportName: string,\n envParserPath: string,\n envParserImportPattern: string,\n ): string {\n return `import { AmazonApiGatewayV1Endpoint } from '@geekmidas/constructs/aws';\nimport { ${exportName} } from '${importPath}';\nimport ${envParserImportPattern} from '${envParserPath}';\n\nconst adapter = new AmazonApiGatewayV1Endpoint(envParser, ${exportName});\n\nexport const handler = adapter.handler;\n`;\n }\n\n private generateAWSApiGatewayV2Handler(\n importPath: string,\n exportName: string,\n envParserPath: string,\n envParserImportPattern: string,\n ): string {\n return `import { AmazonApiGatewayV2Endpoint } from '@geekmidas/constructs/aws';\nimport { ${exportName} } from '${importPath}';\nimport ${envParserImportPattern} from '${envParserPath}';\n\nconst adapter = new AmazonApiGatewayV2Endpoint(envParser, ${exportName});\n\nexport const handler = adapter.handler;\n`;\n }\n\n private generateServerHandler(\n importPath: string,\n exportName: string,\n ): string {\n return `import { ${exportName} } from '${importPath}';\n\n// Server handler - implement based on your server framework\nexport const handler = ${exportName};\n`;\n }\n}\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
- const require_chunk = require('./chunk-CsX-DzYB.cjs');
2
- const require_Generator = require('./Generator-C3tYSTQY.cjs');
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
+ const require_Generator = require('./Generator-CDoEXCDg.cjs');
3
3
  const node_fs_promises = require_chunk.__toESM(require("node:fs/promises"));
4
4
  const node_path = require_chunk.__toESM(require("node:path"));
5
- const __geekmidas_api_constructs = require_chunk.__toESM(require("@geekmidas/api/constructs"));
5
+ const __geekmidas_constructs_functions = require_chunk.__toESM(require("@geekmidas/constructs/functions"));
6
6
 
7
7
  //#region src/generators/FunctionGenerator.ts
8
8
  var FunctionGenerator = class extends require_Generator.ConstructGenerator {
9
9
  isConstruct(value) {
10
- return __geekmidas_api_constructs.Function.isFunction(value);
10
+ return __geekmidas_constructs_functions.Function.isFunction(value);
11
11
  }
12
12
  async build(context, constructs, outputDir, options) {
13
13
  const provider = options?.provider || "aws-lambda";
@@ -21,7 +21,8 @@ var FunctionGenerator = class extends require_Generator.ConstructGenerator {
21
21
  functionInfos.push({
22
22
  name: key,
23
23
  handler: (0, node_path.relative)(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
24
- timeout: construct.timeout
24
+ timeout: construct.timeout,
25
+ environment: await construct.getEnvironment()
25
26
  });
26
27
  logger.log(`Generated function handler: ${key}`);
27
28
  }
@@ -34,7 +35,7 @@ var FunctionGenerator = class extends require_Generator.ConstructGenerator {
34
35
  const importPath = relativePath.replace(/\.ts$/, ".js");
35
36
  const relativeEnvParserPath = (0, node_path.relative)((0, node_path.dirname)(handlerPath), context.envParserPath);
36
37
  const relativeLoggerPath = (0, node_path.relative)((0, node_path.dirname)(handlerPath), context.loggerPath);
37
- const content = `import { AWSLambdaFunction } from '@geekmidas/api/aws-lambda';
38
+ const content = `import { AWSLambdaFunction } from '@geekmidas/constructs/functions';
38
39
  import { ${exportName} } from '${importPath}';
39
40
  import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
40
41
  import ${context.loggerImportPattern} from '${relativeLoggerPath}';
@@ -55,4 +56,4 @@ Object.defineProperty(exports, 'FunctionGenerator', {
55
56
  return FunctionGenerator;
56
57
  }
57
58
  });
58
- //# sourceMappingURL=FunctionGenerator-DN681IUn.cjs.map
59
+ //# sourceMappingURL=FunctionGenerator-Clw64SwQ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FunctionGenerator-Clw64SwQ.cjs","names":["ConstructGenerator","value: any","context: BuildContext","constructs: GeneratedConstruct<Function<any, any, any, any>>[]","outputDir: string","options?: GeneratorOptions","functionInfos: FunctionInfo[]","sourceFile: string","exportName: string"],"sources":["../src/generators/FunctionGenerator.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { Function } from '@geekmidas/constructs/functions';\nimport type { BuildContext } from '../build/types';\nimport type { FunctionInfo } from '../types';\nimport {\n ConstructGenerator,\n type GeneratedConstruct,\n type GeneratorOptions,\n} from './Generator';\n\nexport class FunctionGenerator extends ConstructGenerator<\n Function<any, any, any, any>,\n FunctionInfo[]\n> {\n isConstruct(value: any): value is Function<any, any, any, any> {\n return Function.isFunction(value);\n }\n\n async build(\n context: BuildContext,\n constructs: GeneratedConstruct<Function<any, any, any, any>>[],\n outputDir: string,\n options?: GeneratorOptions,\n ): Promise<FunctionInfo[]> {\n const provider = options?.provider || 'aws-lambda';\n const logger = console;\n const functionInfos: FunctionInfo[] = [];\n\n if (constructs.length === 0 || provider !== 'aws-lambda') {\n return functionInfos;\n }\n\n // Create functions subdirectory\n const functionsDir = join(outputDir, 'functions');\n await mkdir(functionsDir, { recursive: true });\n\n // Generate function handlers\n for (const { key, construct, path } of constructs) {\n const handlerFile = await this.generateFunctionHandler(\n functionsDir,\n path.relative,\n key,\n context,\n );\n\n functionInfos.push({\n name: key,\n handler: relative(process.cwd(), handlerFile).replace(\n /\\.ts$/,\n '.handler',\n ),\n timeout: construct.timeout,\n environment: await construct.getEnvironment(),\n });\n\n logger.log(`Generated function handler: ${key}`);\n }\n\n return functionInfos;\n }\n\n private async generateFunctionHandler(\n outputDir: string,\n sourceFile: string,\n exportName: string,\n context: BuildContext,\n ): Promise<string> {\n const handlerFileName = `${exportName}.ts`;\n const handlerPath = join(outputDir, handlerFileName);\n\n const relativePath = relative(dirname(handlerPath), sourceFile);\n const importPath = relativePath.replace(/\\.ts$/, '.js');\n\n const relativeEnvParserPath = relative(\n dirname(handlerPath),\n context.envParserPath,\n );\n const relativeLoggerPath = relative(\n dirname(handlerPath),\n context.loggerPath,\n );\n\n const content = `import { AWSLambdaFunction } from '@geekmidas/constructs/functions';\nimport { ${exportName} } from '${importPath}';\nimport ${context.envParserImportPattern} from '${relativeEnvParserPath}';\nimport ${context.loggerImportPattern} from '${relativeLoggerPath}';\n\nconst adapter = new AWSLambdaFunction(envParser, ${exportName});\n\nexport const handler = adapter.handler;\n`;\n\n await writeFile(handlerPath, content);\n return handlerPath;\n }\n}\n"],"mappings":";;;;;;;AAWA,IAAa,oBAAb,cAAuCA,qCAGrC;CACA,YAAYC,OAAmD;AAC7D,SAAO,0CAAS,WAAW,MAAM;CAClC;CAED,MAAM,MACJC,SACAC,YACAC,WACAC,SACyB;EACzB,MAAM,WAAW,SAAS,YAAY;EACtC,MAAM,SAAS;EACf,MAAMC,gBAAgC,CAAE;AAExC,MAAI,WAAW,WAAW,KAAK,aAAa,aAC1C,QAAO;EAIT,MAAM,eAAe,oBAAK,WAAW,YAAY;AACjD,QAAM,4BAAM,cAAc,EAAE,WAAW,KAAM,EAAC;AAG9C,OAAK,MAAM,EAAE,KAAK,WAAW,MAAM,IAAI,YAAY;GACjD,MAAM,cAAc,MAAM,KAAK,wBAC7B,cACA,KAAK,UACL,KACA,QACD;AAED,iBAAc,KAAK;IACjB,MAAM;IACN,SAAS,wBAAS,QAAQ,KAAK,EAAE,YAAY,CAAC,QAC5C,SACA,WACD;IACD,SAAS,UAAU;IACnB,aAAa,MAAM,UAAU,gBAAgB;GAC9C,EAAC;AAEF,UAAO,KAAK,8BAA8B,IAAI,EAAE;EACjD;AAED,SAAO;CACR;CAED,MAAc,wBACZF,WACAG,YACAC,YACAN,SACiB;EACjB,MAAM,mBAAmB,EAAE,WAAW;EACtC,MAAM,cAAc,oBAAK,WAAW,gBAAgB;EAEpD,MAAM,eAAe,wBAAS,uBAAQ,YAAY,EAAE,WAAW;EAC/D,MAAM,aAAa,aAAa,QAAQ,SAAS,MAAM;EAEvD,MAAM,wBAAwB,wBAC5B,uBAAQ,YAAY,EACpB,QAAQ,cACT;EACD,MAAM,qBAAqB,wBACzB,uBAAQ,YAAY,EACpB,QAAQ,WACT;EAED,MAAM,WAAW;WACV,WAAW,WAAW,WAAW;SACnC,QAAQ,uBAAuB,SAAS,sBAAsB;SAC9D,QAAQ,oBAAoB,SAAS,mBAAmB;;mDAEd,WAAW;;;;AAK1D,QAAM,gCAAU,aAAa,QAAQ;AACrC,SAAO;CACR;AACF"}
@@ -1,7 +1,7 @@
1
- import { ConstructGenerator } from "./Generator-CDt4pB3W.mjs";
1
+ import { ConstructGenerator } from "./Generator-UanJW0_V.mjs";
2
2
  import { mkdir, writeFile } from "node:fs/promises";
3
3
  import { dirname, join, relative } from "node:path";
4
- import { Function } from "@geekmidas/api/constructs";
4
+ import { Function } from "@geekmidas/constructs/functions";
5
5
 
6
6
  //#region src/generators/FunctionGenerator.ts
7
7
  var FunctionGenerator = class extends ConstructGenerator {
@@ -20,7 +20,8 @@ var FunctionGenerator = class extends ConstructGenerator {
20
20
  functionInfos.push({
21
21
  name: key,
22
22
  handler: relative(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
23
- timeout: construct.timeout
23
+ timeout: construct.timeout,
24
+ environment: await construct.getEnvironment()
24
25
  });
25
26
  logger.log(`Generated function handler: ${key}`);
26
27
  }
@@ -33,7 +34,7 @@ var FunctionGenerator = class extends ConstructGenerator {
33
34
  const importPath = relativePath.replace(/\.ts$/, ".js");
34
35
  const relativeEnvParserPath = relative(dirname(handlerPath), context.envParserPath);
35
36
  const relativeLoggerPath = relative(dirname(handlerPath), context.loggerPath);
36
- const content = `import { AWSLambdaFunction } from '@geekmidas/api/aws-lambda';
37
+ const content = `import { AWSLambdaFunction } from '@geekmidas/constructs/functions';
37
38
  import { ${exportName} } from '${importPath}';
38
39
  import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
39
40
  import ${context.loggerImportPattern} from '${relativeLoggerPath}';
@@ -49,4 +50,4 @@ export const handler = adapter.handler;
49
50
 
50
51
  //#endregion
51
52
  export { FunctionGenerator };
52
- //# sourceMappingURL=FunctionGenerator-crAa-JC7.mjs.map
53
+ //# sourceMappingURL=FunctionGenerator-DOEB_yPh.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FunctionGenerator-DOEB_yPh.mjs","names":["value: any","context: BuildContext","constructs: GeneratedConstruct<Function<any, any, any, any>>[]","outputDir: string","options?: GeneratorOptions","functionInfos: FunctionInfo[]","sourceFile: string","exportName: string"],"sources":["../src/generators/FunctionGenerator.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { Function } from '@geekmidas/constructs/functions';\nimport type { BuildContext } from '../build/types';\nimport type { FunctionInfo } from '../types';\nimport {\n ConstructGenerator,\n type GeneratedConstruct,\n type GeneratorOptions,\n} from './Generator';\n\nexport class FunctionGenerator extends ConstructGenerator<\n Function<any, any, any, any>,\n FunctionInfo[]\n> {\n isConstruct(value: any): value is Function<any, any, any, any> {\n return Function.isFunction(value);\n }\n\n async build(\n context: BuildContext,\n constructs: GeneratedConstruct<Function<any, any, any, any>>[],\n outputDir: string,\n options?: GeneratorOptions,\n ): Promise<FunctionInfo[]> {\n const provider = options?.provider || 'aws-lambda';\n const logger = console;\n const functionInfos: FunctionInfo[] = [];\n\n if (constructs.length === 0 || provider !== 'aws-lambda') {\n return functionInfos;\n }\n\n // Create functions subdirectory\n const functionsDir = join(outputDir, 'functions');\n await mkdir(functionsDir, { recursive: true });\n\n // Generate function handlers\n for (const { key, construct, path } of constructs) {\n const handlerFile = await this.generateFunctionHandler(\n functionsDir,\n path.relative,\n key,\n context,\n );\n\n functionInfos.push({\n name: key,\n handler: relative(process.cwd(), handlerFile).replace(\n /\\.ts$/,\n '.handler',\n ),\n timeout: construct.timeout,\n environment: await construct.getEnvironment(),\n });\n\n logger.log(`Generated function handler: ${key}`);\n }\n\n return functionInfos;\n }\n\n private async generateFunctionHandler(\n outputDir: string,\n sourceFile: string,\n exportName: string,\n context: BuildContext,\n ): Promise<string> {\n const handlerFileName = `${exportName}.ts`;\n const handlerPath = join(outputDir, handlerFileName);\n\n const relativePath = relative(dirname(handlerPath), sourceFile);\n const importPath = relativePath.replace(/\\.ts$/, '.js');\n\n const relativeEnvParserPath = relative(\n dirname(handlerPath),\n context.envParserPath,\n );\n const relativeLoggerPath = relative(\n dirname(handlerPath),\n context.loggerPath,\n );\n\n const content = `import { AWSLambdaFunction } from '@geekmidas/constructs/functions';\nimport { ${exportName} } from '${importPath}';\nimport ${context.envParserImportPattern} from '${relativeEnvParserPath}';\nimport ${context.loggerImportPattern} from '${relativeLoggerPath}';\n\nconst adapter = new AWSLambdaFunction(envParser, ${exportName});\n\nexport const handler = adapter.handler;\n`;\n\n await writeFile(handlerPath, content);\n return handlerPath;\n }\n}\n"],"mappings":";;;;;;AAWA,IAAa,oBAAb,cAAuC,mBAGrC;CACA,YAAYA,OAAmD;AAC7D,SAAO,SAAS,WAAW,MAAM;CAClC;CAED,MAAM,MACJC,SACAC,YACAC,WACAC,SACyB;EACzB,MAAM,WAAW,SAAS,YAAY;EACtC,MAAM,SAAS;EACf,MAAMC,gBAAgC,CAAE;AAExC,MAAI,WAAW,WAAW,KAAK,aAAa,aAC1C,QAAO;EAIT,MAAM,eAAe,KAAK,WAAW,YAAY;AACjD,QAAM,MAAM,cAAc,EAAE,WAAW,KAAM,EAAC;AAG9C,OAAK,MAAM,EAAE,KAAK,WAAW,MAAM,IAAI,YAAY;GACjD,MAAM,cAAc,MAAM,KAAK,wBAC7B,cACA,KAAK,UACL,KACA,QACD;AAED,iBAAc,KAAK;IACjB,MAAM;IACN,SAAS,SAAS,QAAQ,KAAK,EAAE,YAAY,CAAC,QAC5C,SACA,WACD;IACD,SAAS,UAAU;IACnB,aAAa,MAAM,UAAU,gBAAgB;GAC9C,EAAC;AAEF,UAAO,KAAK,8BAA8B,IAAI,EAAE;EACjD;AAED,SAAO;CACR;CAED,MAAc,wBACZF,WACAG,YACAC,YACAN,SACiB;EACjB,MAAM,mBAAmB,EAAE,WAAW;EACtC,MAAM,cAAc,KAAK,WAAW,gBAAgB;EAEpD,MAAM,eAAe,SAAS,QAAQ,YAAY,EAAE,WAAW;EAC/D,MAAM,aAAa,aAAa,QAAQ,SAAS,MAAM;EAEvD,MAAM,wBAAwB,SAC5B,QAAQ,YAAY,EACpB,QAAQ,cACT;EACD,MAAM,qBAAqB,SACzB,QAAQ,YAAY,EACpB,QAAQ,WACT;EAED,MAAM,WAAW;WACV,WAAW,WAAW,WAAW;SACnC,QAAQ,uBAAuB,SAAS,sBAAsB;SAC9D,QAAQ,oBAAoB,SAAS,mBAAmB;;mDAEd,WAAW;;;;AAK1D,QAAM,UAAU,aAAa,QAAQ;AACrC,SAAO;CACR;AACF"}
@@ -1,4 +1,4 @@
1
- const require_chunk = require('./chunk-CsX-DzYB.cjs');
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
2
  const path = require_chunk.__toESM(require("path"));
3
3
  const fast_glob = require_chunk.__toESM(require("fast-glob"));
4
4
  const lodash_kebabcase = require_chunk.__toESM(require("lodash.kebabcase"));
@@ -44,4 +44,4 @@ Object.defineProperty(exports, 'ConstructGenerator', {
44
44
  return ConstructGenerator;
45
45
  }
46
46
  });
47
- //# sourceMappingURL=Generator-C3tYSTQY.cjs.map
47
+ //# sourceMappingURL=Generator-CDoEXCDg.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Generator-CDoEXCDg.cjs","names":["context: BuildContext","outputDir: string","generator: ConstructGenerator<T, R>","patterns?: Routes","options?: GeneratorOptions","constructs: GeneratedConstruct<T>[]","module"],"sources":["../src/generators/Generator.ts"],"sourcesContent":["import { relative } from 'path';\nimport type { Construct } from '@geekmidas/constructs';\nimport fg from 'fast-glob';\nimport kebabCase from 'lodash.kebabcase';\nimport type { BuildContext } from '../build/types';\nimport type { LegacyProvider, Routes } from '../types';\n\nexport interface GeneratorOptions {\n provider?: LegacyProvider;\n [key: string]: any;\n}\n\nexport abstract class ConstructGenerator<T extends Construct, R = void> {\n abstract isConstruct(value: any): value is T;\n\n static async build<T extends Construct, R = void>(\n context: BuildContext,\n outputDir: string,\n generator: ConstructGenerator<T, R>,\n patterns?: Routes,\n options?: GeneratorOptions,\n ): Promise<R> {\n const constructs = await generator.load(patterns);\n return generator.build(context, constructs, outputDir, options);\n }\n\n abstract build(\n context: BuildContext,\n constructs: GeneratedConstruct<T>[],\n outputDir: string,\n options?: GeneratorOptions,\n ): Promise<R>;\n\n async load(\n patterns?: Routes,\n cwd = process.cwd(),\n ): Promise<GeneratedConstruct<T>[]> {\n const logger = console;\n\n // Normalize patterns to array\n const globPatterns = Array.isArray(patterns)\n ? patterns\n : patterns\n ? [patterns]\n : [];\n\n // Find all files\n const files = fg.stream(globPatterns, {\n cwd,\n absolute: true,\n });\n\n // Load constructs\n const constructs: GeneratedConstruct<T>[] = [];\n\n for await (const f of files) {\n try {\n const file = f.toString();\n const module = await import(file);\n\n // Check all exports for constructs\n for (const [key, construct] of Object.entries(module)) {\n if (this.isConstruct(construct)) {\n constructs.push({\n key,\n name: kebabCase(key),\n construct,\n path: {\n absolute: file,\n relative: relative(process.cwd(), file),\n },\n });\n }\n }\n } catch (error) {\n logger.warn(`Failed to load ${f}:`, (error as Error).message);\n throw new Error(\n 'Failed to load constructs. Please check the logs for details.',\n );\n }\n }\n\n return constructs;\n }\n}\n\nexport interface GeneratedConstruct<T extends Construct> {\n key: string;\n name: string;\n construct: T;\n path: {\n absolute: string;\n relative: string;\n };\n}\n"],"mappings":";;;;;;AAYA,IAAsB,qBAAtB,MAAwE;CAGtE,aAAa,MACXA,SACAC,WACAC,WACAC,UACAC,SACY;EACZ,MAAM,aAAa,MAAM,UAAU,KAAK,SAAS;AACjD,SAAO,UAAU,MAAM,SAAS,YAAY,WAAW,QAAQ;CAChE;CASD,MAAM,KACJD,UACA,MAAM,QAAQ,KAAK,EACe;EAClC,MAAM,SAAS;EAGf,MAAM,eAAe,MAAM,QAAQ,SAAS,GACxC,WACA,WACE,CAAC,QAAS,IACV,CAAE;EAGR,MAAM,QAAQ,kBAAG,OAAO,cAAc;GACpC;GACA,UAAU;EACX,EAAC;EAGF,MAAME,aAAsC,CAAE;AAE9C,aAAW,MAAM,KAAK,MACpB,KAAI;GACF,MAAM,OAAO,EAAE,UAAU;GACzB,MAAMC,WAAS,MAAM,OAAO;AAG5B,QAAK,MAAM,CAAC,KAAK,UAAU,IAAI,OAAO,QAAQA,SAAO,CACnD,KAAI,KAAK,YAAY,UAAU,CAC7B,YAAW,KAAK;IACd;IACA,MAAM,8BAAU,IAAI;IACpB;IACA,MAAM;KACJ,UAAU;KACV,UAAU,mBAAS,QAAQ,KAAK,EAAE,KAAK;IACxC;GACF,EAAC;EAGP,SAAQ,OAAO;AACd,UAAO,MAAM,iBAAiB,EAAE,IAAK,MAAgB,QAAQ;AAC7D,SAAM,IAAI,MACR;EAEH;AAGH,SAAO;CACR;AACF"}
@@ -38,4 +38,4 @@ var ConstructGenerator = class {
38
38
 
39
39
  //#endregion
40
40
  export { ConstructGenerator };
41
- //# sourceMappingURL=Generator-CDt4pB3W.mjs.map
41
+ //# sourceMappingURL=Generator-UanJW0_V.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Generator-UanJW0_V.mjs","names":["context: BuildContext","outputDir: string","generator: ConstructGenerator<T, R>","patterns?: Routes","options?: GeneratorOptions","constructs: GeneratedConstruct<T>[]"],"sources":["../src/generators/Generator.ts"],"sourcesContent":["import { relative } from 'path';\nimport type { Construct } from '@geekmidas/constructs';\nimport fg from 'fast-glob';\nimport kebabCase from 'lodash.kebabcase';\nimport type { BuildContext } from '../build/types';\nimport type { LegacyProvider, Routes } from '../types';\n\nexport interface GeneratorOptions {\n provider?: LegacyProvider;\n [key: string]: any;\n}\n\nexport abstract class ConstructGenerator<T extends Construct, R = void> {\n abstract isConstruct(value: any): value is T;\n\n static async build<T extends Construct, R = void>(\n context: BuildContext,\n outputDir: string,\n generator: ConstructGenerator<T, R>,\n patterns?: Routes,\n options?: GeneratorOptions,\n ): Promise<R> {\n const constructs = await generator.load(patterns);\n return generator.build(context, constructs, outputDir, options);\n }\n\n abstract build(\n context: BuildContext,\n constructs: GeneratedConstruct<T>[],\n outputDir: string,\n options?: GeneratorOptions,\n ): Promise<R>;\n\n async load(\n patterns?: Routes,\n cwd = process.cwd(),\n ): Promise<GeneratedConstruct<T>[]> {\n const logger = console;\n\n // Normalize patterns to array\n const globPatterns = Array.isArray(patterns)\n ? patterns\n : patterns\n ? [patterns]\n : [];\n\n // Find all files\n const files = fg.stream(globPatterns, {\n cwd,\n absolute: true,\n });\n\n // Load constructs\n const constructs: GeneratedConstruct<T>[] = [];\n\n for await (const f of files) {\n try {\n const file = f.toString();\n const module = await import(file);\n\n // Check all exports for constructs\n for (const [key, construct] of Object.entries(module)) {\n if (this.isConstruct(construct)) {\n constructs.push({\n key,\n name: kebabCase(key),\n construct,\n path: {\n absolute: file,\n relative: relative(process.cwd(), file),\n },\n });\n }\n }\n } catch (error) {\n logger.warn(`Failed to load ${f}:`, (error as Error).message);\n throw new Error(\n 'Failed to load constructs. Please check the logs for details.',\n );\n }\n }\n\n return constructs;\n }\n}\n\nexport interface GeneratedConstruct<T extends Construct> {\n key: string;\n name: string;\n construct: T;\n path: {\n absolute: string;\n relative: string;\n };\n}\n"],"mappings":";;;;;AAYA,IAAsB,qBAAtB,MAAwE;CAGtE,aAAa,MACXA,SACAC,WACAC,WACAC,UACAC,SACY;EACZ,MAAM,aAAa,MAAM,UAAU,KAAK,SAAS;AACjD,SAAO,UAAU,MAAM,SAAS,YAAY,WAAW,QAAQ;CAChE;CASD,MAAM,KACJD,UACA,MAAM,QAAQ,KAAK,EACe;EAClC,MAAM,SAAS;EAGf,MAAM,eAAe,MAAM,QAAQ,SAAS,GACxC,WACA,WACE,CAAC,QAAS,IACV,CAAE;EAGR,MAAM,QAAQ,GAAG,OAAO,cAAc;GACpC;GACA,UAAU;EACX,EAAC;EAGF,MAAME,aAAsC,CAAE;AAE9C,aAAW,MAAM,KAAK,MACpB,KAAI;GACF,MAAM,OAAO,EAAE,UAAU;GACzB,MAAM,SAAS,MAAM,OAAO;AAG5B,QAAK,MAAM,CAAC,KAAK,UAAU,IAAI,OAAO,QAAQ,OAAO,CACnD,KAAI,KAAK,YAAY,UAAU,CAC7B,YAAW,KAAK;IACd;IACA,MAAM,UAAU,IAAI;IACpB;IACA,MAAM;KACJ,UAAU;KACV,UAAU,SAAS,QAAQ,KAAK,EAAE,KAAK;IACxC;GACF,EAAC;EAGP,SAAQ,OAAO;AACd,UAAO,MAAM,iBAAiB,EAAE,IAAK,MAAgB,QAAQ;AAC7D,SAAM,IAAI,MACR;EAEH;AAGH,SAAO;CACR;AACF"}
@@ -0,0 +1,205 @@
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
+ const require_Generator = require('./Generator-CDoEXCDg.cjs');
3
+ const node_fs_promises = require_chunk.__toESM(require("node:fs/promises"));
4
+ const node_path = require_chunk.__toESM(require("node:path"));
5
+ const __geekmidas_constructs_subscribers = require_chunk.__toESM(require("@geekmidas/constructs/subscribers"));
6
+
7
+ //#region src/generators/SubscriberGenerator.ts
8
+ var SubscriberGenerator = class extends require_Generator.ConstructGenerator {
9
+ isConstruct(value) {
10
+ return __geekmidas_constructs_subscribers.Subscriber.isSubscriber(value);
11
+ }
12
+ async build(context, constructs, outputDir, options) {
13
+ const provider = options?.provider || "aws-lambda";
14
+ const logger = console;
15
+ const subscriberInfos = [];
16
+ if (provider === "server") {
17
+ await this.generateServerSubscribersFile(outputDir, constructs);
18
+ logger.log(`Generated server subscribers file with ${constructs.length} subscribers (polling mode)`);
19
+ return subscriberInfos;
20
+ }
21
+ if (constructs.length === 0) return subscriberInfos;
22
+ if (provider !== "aws-lambda") return subscriberInfos;
23
+ const subscribersDir = (0, node_path.join)(outputDir, "subscribers");
24
+ await (0, node_fs_promises.mkdir)(subscribersDir, { recursive: true });
25
+ for (const { key, construct, path } of constructs) {
26
+ const handlerFile = await this.generateSubscriberHandler(subscribersDir, path.relative, key, construct, context);
27
+ subscriberInfos.push({
28
+ name: key,
29
+ handler: (0, node_path.relative)(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
30
+ subscribedEvents: construct.subscribedEvents || [],
31
+ timeout: construct.timeout,
32
+ environment: await construct.getEnvironment()
33
+ });
34
+ logger.log(`Generated subscriber handler: ${key}`);
35
+ }
36
+ return subscriberInfos;
37
+ }
38
+ async generateSubscriberHandler(outputDir, sourceFile, exportName, _subscriber, context) {
39
+ const handlerFileName = `${exportName}.ts`;
40
+ const handlerPath = (0, node_path.join)(outputDir, handlerFileName);
41
+ const relativePath = (0, node_path.relative)((0, node_path.dirname)(handlerPath), sourceFile);
42
+ const importPath = relativePath.replace(/\.ts$/, ".js");
43
+ const relativeEnvParserPath = (0, node_path.relative)((0, node_path.dirname)(handlerPath), context.envParserPath);
44
+ const content = `import { AWSLambdaSubscriber } from '@geekmidas/constructs/aws';
45
+ import { ${exportName} } from '${importPath}';
46
+ import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
47
+
48
+ const adapter = new AWSLambdaSubscriber(envParser, ${exportName});
49
+
50
+ export const handler = adapter.handler;
51
+ `;
52
+ await (0, node_fs_promises.writeFile)(handlerPath, content);
53
+ return handlerPath;
54
+ }
55
+ async generateServerSubscribersFile(outputDir, subscribers) {
56
+ await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
57
+ const subscribersFileName = "subscribers.ts";
58
+ const subscribersPath = (0, node_path.join)(outputDir, subscribersFileName);
59
+ const importsByFile = /* @__PURE__ */ new Map();
60
+ for (const { path, key } of subscribers) {
61
+ const relativePath = (0, node_path.relative)((0, node_path.dirname)(subscribersPath), path.relative);
62
+ const importPath = relativePath.replace(/\.ts$/, ".js");
63
+ if (!importsByFile.has(importPath)) importsByFile.set(importPath, []);
64
+ importsByFile.get(importPath).push(key);
65
+ }
66
+ const imports = Array.from(importsByFile.entries()).map(([importPath, exports$1]) => `import { ${exports$1.join(", ")} } from '${importPath}';`).join("\n");
67
+ const allExportNames = subscribers.map(({ key }) => key);
68
+ const content = `/**
69
+ * Generated subscribers setup
70
+ *
71
+ * ⚠️ WARNING: This is for LOCAL DEVELOPMENT ONLY
72
+ * This uses event polling which is not suitable for production.
73
+ *
74
+ * For production, use AWS Lambda with SQS/SNS event source mappings.
75
+ * Lambda automatically:
76
+ * - Scales based on queue depth
77
+ * - Handles batch processing and retries
78
+ * - Manages dead letter queues
79
+ * - Provides better cost optimization
80
+ *
81
+ * This polling implementation is useful for:
82
+ * - Local development and testing
83
+ * - Understanding event flow without Lambda deployment
84
+ *
85
+ * Supported connection strings:
86
+ * - sqs://region/account-id/queue-name (SQS queue)
87
+ * - sns://region/account-id/topic-name (SNS topic)
88
+ * - rabbitmq://host:port/queue-name (RabbitMQ)
89
+ * - basic://in-memory (In-memory for testing)
90
+ */
91
+ import type { EnvironmentParser } from '@geekmidas/envkit';
92
+ import type { Logger } from '@geekmidas/logger';
93
+ import { EventConnectionFactory, Subscriber } from '@geekmidas/events';
94
+ import type { EventConnection, EventSubscriber } from '@geekmidas/events';
95
+ import { ServiceDiscovery } from '@geekmidas/services';
96
+ ${imports}
97
+
98
+ const subscribers = [
99
+ ${allExportNames.join(",\n ")}
100
+ ];
101
+
102
+ const activeSubscribers: EventSubscriber<any>[] = [];
103
+
104
+ export async function setupSubscribers(
105
+ envParser: EnvironmentParser<any>,
106
+ logger: Logger,
107
+ ): Promise<void> {
108
+ logger.info('Setting up subscribers in polling mode (local development)');
109
+
110
+ const config = envParser.create((get) => ({
111
+ connectionString: get('EVENT_SUBSCRIBER_CONNECTION_STRING').string().optional(),
112
+ })).parse();
113
+
114
+ if (!config.connectionString) {
115
+ logger.warn('EVENT_SUBSCRIBER_CONNECTION_STRING not configured, skipping subscriber setup');
116
+ return;
117
+ }
118
+
119
+ const serviceDiscovery = ServiceDiscovery.getInstance(logger, envParser);
120
+
121
+ // Create connection once, outside the loop (more efficient)
122
+ // EventConnectionFactory automatically determines the right connection type
123
+ let connection: EventConnection;
124
+ try {
125
+ connection = await EventConnectionFactory.fromConnectionString(config.connectionString);
126
+
127
+ const connectionType = new URL(config.connectionString).protocol.replace(':', '');
128
+ logger.info({ connectionType }, 'Created shared event connection');
129
+ } catch (error) {
130
+ logger.error({ error }, 'Failed to create event connection');
131
+ return;
132
+ }
133
+
134
+ for (const subscriber of subscribers) {
135
+ try {
136
+ // Create subscriber from shared connection
137
+ const eventSubscriber = await Subscriber.fromConnection(connection);
138
+
139
+ // Register services
140
+ const services = subscriber.services.length > 0
141
+ ? await serviceDiscovery.register(subscriber.services)
142
+ : {};
143
+
144
+ // Subscribe to events
145
+ const subscribedEvents = subscriber.subscribedEvents || [];
146
+
147
+ if (subscribedEvents.length === 0) {
148
+ logger.warn({ subscriber: subscriber.constructor.name }, 'Subscriber has no subscribed events, skipping');
149
+ continue;
150
+ }
151
+
152
+ await eventSubscriber.subscribe(subscribedEvents, async (event) => {
153
+ try {
154
+ // Process single event (batch of 1)
155
+ await subscriber.handler({
156
+ events: [event],
157
+ services: services as any,
158
+ logger: subscriber.logger,
159
+ });
160
+
161
+ logger.debug({ eventType: event.type }, 'Successfully processed event');
162
+ } catch (error) {
163
+ logger.error({ error, event }, 'Failed to process event');
164
+ // Event will become visible again for retry
165
+ }
166
+ });
167
+
168
+ activeSubscribers.push(eventSubscriber);
169
+
170
+ logger.info(
171
+ {
172
+ events: subscribedEvents,
173
+ },
174
+ 'Subscriber started polling'
175
+ );
176
+ } catch (error) {
177
+ logger.error({ error, subscriber: subscriber.constructor.name }, 'Failed to setup subscriber');
178
+ }
179
+ }
180
+
181
+ // Setup graceful shutdown
182
+ const shutdown = () => {
183
+ logger.info('Stopping all subscribers');
184
+ for (const eventSubscriber of activeSubscribers) {
185
+ connection.stop();
186
+ }
187
+ };
188
+
189
+ process.on('SIGTERM', shutdown);
190
+ process.on('SIGINT', shutdown);
191
+ }
192
+ `;
193
+ await (0, node_fs_promises.writeFile)(subscribersPath, content);
194
+ return subscribersPath;
195
+ }
196
+ };
197
+
198
+ //#endregion
199
+ Object.defineProperty(exports, 'SubscriberGenerator', {
200
+ enumerable: true,
201
+ get: function () {
202
+ return SubscriberGenerator;
203
+ }
204
+ });
205
+ //# sourceMappingURL=SubscriberGenerator-CB-NHtZW.cjs.map