@geekmidas/cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -13
- package/dist/{CronGenerator-Ctl4USy4.cjs → CronGenerator-1PflEYe2.cjs} +8 -7
- package/dist/CronGenerator-1PflEYe2.cjs.map +1 -0
- package/dist/{CronGenerator-ClbRcmz_.mjs → CronGenerator-DXRfHQcV.mjs} +6 -5
- package/dist/CronGenerator-DXRfHQcV.mjs.map +1 -0
- package/dist/{EndpointGenerator-Dj7AumHi.cjs → EndpointGenerator-BbGrDiCP.cjs} +134 -34
- package/dist/EndpointGenerator-BbGrDiCP.cjs.map +1 -0
- package/dist/{EndpointGenerator-uBA1ixUw.mjs → EndpointGenerator-BmZ9BxbO.mjs} +132 -32
- package/dist/EndpointGenerator-BmZ9BxbO.mjs.map +1 -0
- package/dist/{FunctionGenerator-DN681IUn.cjs → FunctionGenerator-Clw64SwQ.cjs} +8 -7
- package/dist/FunctionGenerator-Clw64SwQ.cjs.map +1 -0
- package/dist/{FunctionGenerator-crAa-JC7.mjs → FunctionGenerator-DOEB_yPh.mjs} +6 -5
- package/dist/FunctionGenerator-DOEB_yPh.mjs.map +1 -0
- package/dist/{Generator-C3tYSTQY.cjs → Generator-CDoEXCDg.cjs} +2 -2
- package/dist/Generator-CDoEXCDg.cjs.map +1 -0
- package/dist/{Generator-CDt4pB3W.mjs → Generator-UanJW0_V.mjs} +1 -1
- package/dist/Generator-UanJW0_V.mjs.map +1 -0
- package/dist/SubscriberGenerator-BfMZCVNy.cjs +204 -0
- package/dist/SubscriberGenerator-BfMZCVNy.cjs.map +1 -0
- package/dist/SubscriberGenerator-D2u00NI3.mjs +198 -0
- package/dist/SubscriberGenerator-D2u00NI3.mjs.map +1 -0
- package/dist/build/index.cjs +10 -9
- package/dist/build/index.mjs +8 -7
- package/dist/build/manifests.cjs +1 -1
- package/dist/build/manifests.mjs +1 -1
- package/dist/build/providerResolver.cjs +1 -1
- package/dist/build-BBhlEjf5.cjs +89 -0
- package/dist/build-BBhlEjf5.cjs.map +1 -0
- package/dist/build-kY-lG30Q.mjs +83 -0
- package/dist/build-kY-lG30Q.mjs.map +1 -0
- package/dist/{chunk-CsX-DzYB.cjs → chunk-CUT6urMc.cjs} +0 -12
- package/dist/{config-RcNESK0T.cjs → config-D1EpSGk6.cjs} +2 -2
- package/dist/{config-RcNESK0T.cjs.map → config-D1EpSGk6.cjs.map} +1 -1
- package/dist/{config-CXxYmz_o.mjs → config-U-mdW-7Y.mjs} +1 -1
- package/dist/{config-CXxYmz_o.mjs.map → config-U-mdW-7Y.mjs.map} +1 -1
- package/dist/config.cjs +1 -1
- package/dist/config.mjs +1 -1
- package/dist/generators/CronGenerator.cjs +2 -2
- package/dist/generators/CronGenerator.mjs +2 -2
- package/dist/generators/EndpointGenerator.cjs +2 -2
- package/dist/generators/EndpointGenerator.mjs +2 -2
- package/dist/generators/FunctionGenerator.cjs +2 -2
- package/dist/generators/FunctionGenerator.mjs +2 -2
- package/dist/generators/Generator.cjs +1 -1
- package/dist/generators/Generator.mjs +1 -1
- package/dist/generators/SubscriberGenerator.cjs +4 -0
- package/dist/generators/SubscriberGenerator.mjs +4 -0
- package/dist/generators/index.cjs +8 -6
- package/dist/generators/index.mjs +6 -5
- package/dist/index.cjs +18 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +15 -11
- package/dist/index.mjs.map +1 -1
- package/dist/{manifests-HX4z4kkz.mjs → manifests-BrJXpHrf.mjs} +5 -4
- package/dist/manifests-BrJXpHrf.mjs.map +1 -0
- package/dist/{manifests-BTtfDMX8.cjs → manifests-D0saShvH.cjs} +6 -5
- package/dist/manifests-D0saShvH.cjs.map +1 -0
- package/dist/{openapi-BivnatiC.mjs → openapi-BQx3_JbM.mjs} +4 -4
- package/dist/openapi-BQx3_JbM.mjs.map +1 -0
- package/dist/{openapi-DW-qF3oW.cjs → openapi-CMLr04cz.cjs} +6 -6
- package/dist/openapi-CMLr04cz.cjs.map +1 -0
- package/dist/{openapi-react-query-lgS7AVEz.mjs → openapi-react-query-DbrWwQzb.mjs} +3 -2
- package/dist/openapi-react-query-DbrWwQzb.mjs.map +1 -0
- package/dist/{openapi-react-query-J0BzBHhN.cjs → openapi-react-query-Dvjqx_Eo.cjs} +4 -3
- package/dist/openapi-react-query-Dvjqx_Eo.cjs.map +1 -0
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +4 -4
- package/dist/openapi.mjs +4 -4
- package/dist/{providerResolver-Cs-0YCaP.cjs → providerResolver-DgvzNfP4.cjs} +1 -1
- package/dist/{providerResolver-Cs-0YCaP.cjs.map → providerResolver-DgvzNfP4.cjs.map} +1 -1
- package/examples/cron-example.ts +1 -1
- package/examples/function-example.ts +1 -1
- package/examples/logger.ts +1 -1
- package/package.json +6 -3
- package/src/__tests__/openapi-react-query.spec.ts +506 -0
- package/src/__tests__/openapi.spec.ts +362 -0
- package/src/__tests__/test-helpers.ts +10 -8
- package/src/build/__tests__/index-new.spec.ts +41 -42
- package/src/build/index.ts +89 -28
- package/src/build/manifests.ts +4 -1
- package/src/build/types.ts +2 -2
- package/src/generators/CronGenerator.ts +3 -2
- package/src/generators/EndpointGenerator.ts +141 -42
- package/src/generators/FunctionGenerator.ts +3 -2
- package/src/generators/Generator.ts +1 -1
- package/src/generators/SubscriberGenerator.ts +271 -0
- package/src/generators/__tests__/CronGenerator.spec.ts +1 -1
- package/src/generators/__tests__/EndpointGenerator.spec.ts +33 -11
- package/src/generators/__tests__/FunctionGenerator.spec.ts +21 -22
- package/src/generators/__tests__/SubscriberGenerator.spec.ts +341 -0
- package/src/generators/index.ts +1 -0
- package/src/openapi-react-query.ts +2 -1
- package/src/openapi.ts +1 -1
- package/src/types.ts +18 -0
- package/dist/CronGenerator-ClbRcmz_.mjs.map +0 -1
- package/dist/CronGenerator-Ctl4USy4.cjs.map +0 -1
- package/dist/EndpointGenerator-Dj7AumHi.cjs.map +0 -1
- package/dist/EndpointGenerator-uBA1ixUw.mjs.map +0 -1
- package/dist/FunctionGenerator-DN681IUn.cjs.map +0 -1
- package/dist/FunctionGenerator-crAa-JC7.mjs.map +0 -1
- package/dist/Generator-C3tYSTQY.cjs.map +0 -1
- package/dist/Generator-CDt4pB3W.mjs.map +0 -1
- package/dist/__tests__/config.spec.cjs +0 -98
- package/dist/__tests__/config.spec.cjs.map +0 -1
- package/dist/__tests__/config.spec.mjs +0 -97
- package/dist/__tests__/config.spec.mjs.map +0 -1
- package/dist/__tests__/test-helpers.cjs +0 -14
- package/dist/__tests__/test-helpers.mjs +0 -4
- package/dist/build/__tests__/index-new.spec.cjs +0 -286
- package/dist/build/__tests__/index-new.spec.cjs.map +0 -1
- package/dist/build/__tests__/index-new.spec.mjs +0 -285
- package/dist/build/__tests__/index-new.spec.mjs.map +0 -1
- package/dist/build-BZdwxCLW.mjs +0 -64
- package/dist/build-BZdwxCLW.mjs.map +0 -1
- package/dist/build-BfQFnU5-.cjs +0 -70
- package/dist/build-BfQFnU5-.cjs.map +0 -1
- package/dist/esm-9eeZntth.mjs +0 -3777
- package/dist/esm-9eeZntth.mjs.map +0 -1
- package/dist/esm-Crmo4h9t.cjs +0 -4392
- package/dist/esm-Crmo4h9t.cjs.map +0 -1
- package/dist/esm-CsJbr7gi.mjs +0 -3
- package/dist/esm-w09tAC4l.cjs +0 -8
- package/dist/generators/__tests__/CronGenerator.spec.cjs +0 -216
- package/dist/generators/__tests__/CronGenerator.spec.cjs.map +0 -1
- package/dist/generators/__tests__/CronGenerator.spec.mjs +0 -215
- package/dist/generators/__tests__/CronGenerator.spec.mjs.map +0 -1
- package/dist/generators/__tests__/EndpointGenerator.spec.cjs +0 -182
- package/dist/generators/__tests__/EndpointGenerator.spec.cjs.map +0 -1
- package/dist/generators/__tests__/EndpointGenerator.spec.mjs +0 -181
- package/dist/generators/__tests__/EndpointGenerator.spec.mjs.map +0 -1
- package/dist/generators/__tests__/FunctionGenerator.spec.cjs +0 -152
- package/dist/generators/__tests__/FunctionGenerator.spec.cjs.map +0 -1
- package/dist/generators/__tests__/FunctionGenerator.spec.mjs +0 -151
- package/dist/generators/__tests__/FunctionGenerator.spec.mjs.map +0 -1
- package/dist/manifests-BTtfDMX8.cjs.map +0 -1
- package/dist/manifests-HX4z4kkz.mjs.map +0 -1
- package/dist/openapi-BivnatiC.mjs.map +0 -1
- package/dist/openapi-DW-qF3oW.cjs.map +0 -1
- package/dist/openapi-react-query-J0BzBHhN.cjs.map +0 -1
- package/dist/openapi-react-query-lgS7AVEz.mjs.map +0 -1
- package/dist/test-helpers-ARd8GDgx.cjs +0 -199
- package/dist/test-helpers-ARd8GDgx.cjs.map +0 -1
- package/dist/test-helpers-DdVBk23F.mjs +0 -133
- package/dist/test-helpers-DdVBk23F.mjs.map +0 -1
- /package/dist/{generators-_pY7sHy1.cjs → generators-CEKtVh81.cjs} +0 -0
package/src/build/index.ts
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
import { mkdir } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import type { Cron
|
|
4
|
-
import type { Endpoint } from '@geekmidas/
|
|
3
|
+
import type { Cron } from '@geekmidas/constructs/crons';
|
|
4
|
+
import type { Endpoint } from '@geekmidas/constructs/endpoints';
|
|
5
|
+
import type { Function } from '@geekmidas/constructs/functions';
|
|
6
|
+
import type { Subscriber } from '@geekmidas/constructs/subscribers';
|
|
5
7
|
import { loadConfig } from '../config';
|
|
6
8
|
import {
|
|
7
9
|
CronGenerator,
|
|
8
10
|
EndpointGenerator,
|
|
9
11
|
FunctionGenerator,
|
|
10
12
|
type GeneratedConstruct,
|
|
13
|
+
SubscriberGenerator,
|
|
11
14
|
} from '../generators';
|
|
12
|
-
import type {
|
|
15
|
+
import type {
|
|
16
|
+
BuildOptions,
|
|
17
|
+
CronInfo,
|
|
18
|
+
FunctionInfo,
|
|
19
|
+
LegacyProvider,
|
|
20
|
+
RouteInfo,
|
|
21
|
+
SubscriberInfo,
|
|
22
|
+
} from '../types';
|
|
13
23
|
import { generateManifests } from './manifests';
|
|
14
24
|
import { resolveProviders } from './providerResolver';
|
|
15
25
|
import type { BuildContext } from './types';
|
|
@@ -30,6 +40,9 @@ export async function buildCommand(options: BuildOptions): Promise<void> {
|
|
|
30
40
|
if (config.crons) {
|
|
31
41
|
logger.log(`Loading crons from: ${config.crons}`);
|
|
32
42
|
}
|
|
43
|
+
if (config.subscribers) {
|
|
44
|
+
logger.log(`Loading subscribers from: ${config.subscribers}`);
|
|
45
|
+
}
|
|
33
46
|
logger.log(`Using envParser: ${config.envParser}`);
|
|
34
47
|
|
|
35
48
|
// Parse envParser configuration
|
|
@@ -59,29 +72,40 @@ export async function buildCommand(options: BuildOptions): Promise<void> {
|
|
|
59
72
|
const endpointGenerator = new EndpointGenerator();
|
|
60
73
|
const functionGenerator = new FunctionGenerator();
|
|
61
74
|
const cronGenerator = new CronGenerator();
|
|
75
|
+
const subscriberGenerator = new SubscriberGenerator();
|
|
62
76
|
|
|
63
77
|
// Load all constructs in parallel
|
|
64
|
-
const [allEndpoints, allFunctions, allCrons] =
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
const [allEndpoints, allFunctions, allCrons, allSubscribers] =
|
|
79
|
+
await Promise.all([
|
|
80
|
+
endpointGenerator.load(config.routes),
|
|
81
|
+
config.functions ? functionGenerator.load(config.functions) : [],
|
|
82
|
+
config.crons ? cronGenerator.load(config.crons) : [],
|
|
83
|
+
config.subscribers ? subscriberGenerator.load(config.subscribers) : [],
|
|
84
|
+
]);
|
|
69
85
|
|
|
70
86
|
logger.log(`Found ${allEndpoints.length} endpoints`);
|
|
71
87
|
logger.log(`Found ${allFunctions.length} functions`);
|
|
72
88
|
logger.log(`Found ${allCrons.length} crons`);
|
|
89
|
+
logger.log(`Found ${allSubscribers.length} subscribers`);
|
|
73
90
|
|
|
74
91
|
if (
|
|
75
92
|
allEndpoints.length === 0 &&
|
|
76
93
|
allFunctions.length === 0 &&
|
|
77
|
-
allCrons.length === 0
|
|
94
|
+
allCrons.length === 0 &&
|
|
95
|
+
allSubscribers.length === 0
|
|
78
96
|
) {
|
|
79
|
-
logger.log(
|
|
97
|
+
logger.log(
|
|
98
|
+
'No endpoints, functions, crons, or subscribers found to process',
|
|
99
|
+
);
|
|
80
100
|
return;
|
|
81
101
|
}
|
|
82
102
|
|
|
83
|
-
//
|
|
84
|
-
|
|
103
|
+
// Ensure .gkm directory exists
|
|
104
|
+
const rootOutputDir = join(process.cwd(), '.gkm');
|
|
105
|
+
await mkdir(rootOutputDir, { recursive: true });
|
|
106
|
+
|
|
107
|
+
// Collect all build results from each provider
|
|
108
|
+
const allBuildResults = await Promise.all(
|
|
85
109
|
resolved.providers.map((provider) =>
|
|
86
110
|
buildForProvider(
|
|
87
111
|
provider,
|
|
@@ -89,13 +113,41 @@ export async function buildCommand(options: BuildOptions): Promise<void> {
|
|
|
89
113
|
endpointGenerator,
|
|
90
114
|
functionGenerator,
|
|
91
115
|
cronGenerator,
|
|
116
|
+
subscriberGenerator,
|
|
92
117
|
allEndpoints,
|
|
93
118
|
allFunctions,
|
|
94
119
|
allCrons,
|
|
120
|
+
allSubscribers,
|
|
95
121
|
resolved.enableOpenApi,
|
|
96
122
|
),
|
|
97
123
|
),
|
|
98
124
|
);
|
|
125
|
+
|
|
126
|
+
// Aggregate all routes, functions, crons, and subscribers from all providers
|
|
127
|
+
const aggregatedRoutes = allBuildResults.flatMap((result) => result.routes);
|
|
128
|
+
const aggregatedFunctions = allBuildResults.flatMap(
|
|
129
|
+
(result) => result.functions,
|
|
130
|
+
);
|
|
131
|
+
const aggregatedCrons = allBuildResults.flatMap((result) => result.crons);
|
|
132
|
+
const aggregatedSubscribers = allBuildResults.flatMap(
|
|
133
|
+
(result) => result.subscribers,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
// Generate single manifest at root .gkm directory
|
|
137
|
+
await generateManifests(
|
|
138
|
+
rootOutputDir,
|
|
139
|
+
aggregatedRoutes,
|
|
140
|
+
aggregatedFunctions,
|
|
141
|
+
aggregatedCrons,
|
|
142
|
+
aggregatedSubscribers,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface BuildResult {
|
|
147
|
+
routes: RouteInfo[];
|
|
148
|
+
functions: FunctionInfo[];
|
|
149
|
+
crons: CronInfo[];
|
|
150
|
+
subscribers: SubscriberInfo[];
|
|
99
151
|
}
|
|
100
152
|
|
|
101
153
|
async function buildForProvider(
|
|
@@ -104,11 +156,13 @@ async function buildForProvider(
|
|
|
104
156
|
endpointGenerator: EndpointGenerator,
|
|
105
157
|
functionGenerator: FunctionGenerator,
|
|
106
158
|
cronGenerator: CronGenerator,
|
|
159
|
+
subscriberGenerator: SubscriberGenerator,
|
|
107
160
|
endpoints: GeneratedConstruct<Endpoint<any, any, any, any, any, any>>[],
|
|
108
161
|
functions: GeneratedConstruct<Function<any, any, any, any>>[],
|
|
109
162
|
crons: GeneratedConstruct<Cron<any, any, any, any>>[],
|
|
163
|
+
subscribers: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[],
|
|
110
164
|
enableOpenApi: boolean,
|
|
111
|
-
): Promise<
|
|
165
|
+
): Promise<BuildResult> {
|
|
112
166
|
const outputDir = join(process.cwd(), '.gkm', provider);
|
|
113
167
|
|
|
114
168
|
// Ensure output directory exists
|
|
@@ -117,20 +171,27 @@ async function buildForProvider(
|
|
|
117
171
|
logger.log(`\nGenerating handlers for provider: ${provider}`);
|
|
118
172
|
|
|
119
173
|
// Build all constructs in parallel
|
|
120
|
-
const [routes, functionInfos, cronInfos] = await Promise.all(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
await generateManifests(
|
|
131
|
-
outputDir,
|
|
132
|
-
routes,
|
|
133
|
-
functionInfos,
|
|
134
|
-
cronInfos,
|
|
174
|
+
const [routes, functionInfos, cronInfos, subscriberInfos] = await Promise.all(
|
|
175
|
+
[
|
|
176
|
+
endpointGenerator.build(context, endpoints, outputDir, {
|
|
177
|
+
provider,
|
|
178
|
+
enableOpenApi,
|
|
179
|
+
}),
|
|
180
|
+
functionGenerator.build(context, functions, outputDir, { provider }),
|
|
181
|
+
cronGenerator.build(context, crons, outputDir, { provider }),
|
|
182
|
+
subscriberGenerator.build(context, subscribers, outputDir, { provider }),
|
|
183
|
+
],
|
|
135
184
|
);
|
|
185
|
+
|
|
186
|
+
logger.log(
|
|
187
|
+
`Generated ${routes.length} routes, ${functionInfos.length} functions, ${cronInfos.length} crons, ${subscriberInfos.length} subscribers for ${provider}`,
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
// Return build results instead of generating manifest here
|
|
191
|
+
return {
|
|
192
|
+
routes,
|
|
193
|
+
functions: functionInfos,
|
|
194
|
+
crons: cronInfos,
|
|
195
|
+
subscribers: subscriberInfos,
|
|
196
|
+
};
|
|
136
197
|
}
|
package/src/build/manifests.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
CronInfo,
|
|
6
6
|
FunctionInfo,
|
|
7
7
|
RouteInfo,
|
|
8
|
+
SubscriberInfo,
|
|
8
9
|
} from '../types';
|
|
9
10
|
|
|
10
11
|
const logger = console;
|
|
@@ -14,19 +15,21 @@ export async function generateManifests(
|
|
|
14
15
|
routes: RouteInfo[],
|
|
15
16
|
functions: FunctionInfo[],
|
|
16
17
|
crons: CronInfo[],
|
|
18
|
+
subscribers: SubscriberInfo[],
|
|
17
19
|
): Promise<void> {
|
|
18
20
|
// Generate unified manifest for all providers
|
|
19
21
|
const manifest: BuildManifest = {
|
|
20
22
|
routes,
|
|
21
23
|
functions,
|
|
22
24
|
crons,
|
|
25
|
+
subscribers,
|
|
23
26
|
};
|
|
24
27
|
|
|
25
28
|
const manifestPath = join(outputDir, 'manifest.json');
|
|
26
29
|
await writeFile(manifestPath, JSON.stringify(manifest, null, 2));
|
|
27
30
|
|
|
28
31
|
logger.log(
|
|
29
|
-
|
|
32
|
+
`\nGenerated unified manifest with ${routes.length} routes, ${functions.length} functions, ${crons.length} crons, ${subscribers.length} subscribers`,
|
|
30
33
|
);
|
|
31
34
|
logger.log(`Manifest: ${relative(process.cwd(), manifestPath)}`);
|
|
32
35
|
}
|
package/src/build/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Cron, Function } from '@geekmidas/
|
|
2
|
-
import type { Endpoint } from '@geekmidas/
|
|
1
|
+
import type { Cron, Function } from '@geekmidas/constructs';
|
|
2
|
+
import type { Endpoint } from '@geekmidas/constructs';
|
|
3
3
|
|
|
4
4
|
import type { CronInfo, FunctionInfo, RouteInfo } from '../types';
|
|
5
5
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join, relative } from 'node:path';
|
|
3
|
-
import { Cron } from '@geekmidas/
|
|
3
|
+
import { Cron } from '@geekmidas/constructs/crons';
|
|
4
4
|
import type { BuildContext } from '../build/types';
|
|
5
5
|
import type { CronInfo } from '../types';
|
|
6
6
|
import {
|
|
@@ -48,6 +48,7 @@ export class CronGenerator extends ConstructGenerator<
|
|
|
48
48
|
),
|
|
49
49
|
schedule: construct.schedule || 'rate(1 hour)',
|
|
50
50
|
timeout: construct.timeout,
|
|
51
|
+
environment: await construct.getEnvironment(),
|
|
51
52
|
});
|
|
52
53
|
|
|
53
54
|
logger.log(`Generated cron handler: ${key}`);
|
|
@@ -81,7 +82,7 @@ export class CronGenerator extends ConstructGenerator<
|
|
|
81
82
|
context.loggerPath,
|
|
82
83
|
);
|
|
83
84
|
|
|
84
|
-
const content = `import { AWSScheduledFunction } from '@geekmidas/
|
|
85
|
+
const content = `import { AWSScheduledFunction } from '@geekmidas/constructs/crons';
|
|
85
86
|
import { ${exportName} } from '${importPath}';
|
|
86
87
|
import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
|
|
87
88
|
import ${context.loggerImportPattern} from '${relativeLoggerPath}';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join, relative } from 'node:path';
|
|
3
|
-
import { Endpoint } from '@geekmidas/
|
|
3
|
+
import { Endpoint } from '@geekmidas/constructs/endpoints';
|
|
4
4
|
import type { BuildContext } from '../build/types';
|
|
5
5
|
import type { LegacyProvider, RouteInfo } from '../types';
|
|
6
6
|
import {
|
|
@@ -33,22 +33,18 @@ export class EndpointGenerator extends ConstructGenerator<
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
if (provider === 'server') {
|
|
36
|
-
// Generate
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
constructs,
|
|
40
|
-
context,
|
|
41
|
-
enableOpenApi,
|
|
42
|
-
);
|
|
36
|
+
// Generate endpoints.ts and app.ts
|
|
37
|
+
await this.generateEndpointsFile(outputDir, constructs, context);
|
|
38
|
+
const appFile = await this.generateAppFile(outputDir, context);
|
|
43
39
|
|
|
44
40
|
routes.push({
|
|
45
41
|
path: '*',
|
|
46
42
|
method: 'ALL',
|
|
47
|
-
handler: relative(process.cwd(),
|
|
43
|
+
handler: relative(process.cwd(), appFile),
|
|
48
44
|
});
|
|
49
45
|
|
|
50
46
|
logger.log(
|
|
51
|
-
`Generated server
|
|
47
|
+
`Generated server with ${constructs.length} endpoints${enableOpenApi ? ' (OpenAPI enabled)' : ''}`,
|
|
52
48
|
);
|
|
53
49
|
} else if (provider === 'aws-lambda') {
|
|
54
50
|
// For aws-lambda, create routes subdirectory
|
|
@@ -73,6 +69,7 @@ export class EndpointGenerator extends ConstructGenerator<
|
|
|
73
69
|
/\.ts$/,
|
|
74
70
|
'.handler',
|
|
75
71
|
),
|
|
72
|
+
environment: await construct.getEnvironment(),
|
|
76
73
|
};
|
|
77
74
|
|
|
78
75
|
routes.push(routeInfo);
|
|
@@ -99,6 +96,7 @@ export class EndpointGenerator extends ConstructGenerator<
|
|
|
99
96
|
/\.ts$/,
|
|
100
97
|
'.handler',
|
|
101
98
|
),
|
|
99
|
+
environment: await construct.getEnvironment(),
|
|
102
100
|
};
|
|
103
101
|
|
|
104
102
|
routes.push(routeInfo);
|
|
@@ -160,20 +158,19 @@ export class EndpointGenerator extends ConstructGenerator<
|
|
|
160
158
|
return handlerPath;
|
|
161
159
|
}
|
|
162
160
|
|
|
163
|
-
private async
|
|
161
|
+
private async generateEndpointsFile(
|
|
164
162
|
outputDir: string,
|
|
165
163
|
endpoints: GeneratedConstruct<Endpoint<any, any, any, any, any, any>>[],
|
|
166
164
|
context: BuildContext,
|
|
167
|
-
enableOpenApi: boolean,
|
|
168
165
|
): Promise<string> {
|
|
169
|
-
const
|
|
170
|
-
const
|
|
166
|
+
const endpointsFileName = 'endpoints.ts';
|
|
167
|
+
const endpointsPath = join(outputDir, endpointsFileName);
|
|
171
168
|
|
|
172
169
|
// Group imports by file
|
|
173
170
|
const importsByFile = new Map<string, string[]>();
|
|
174
171
|
|
|
175
172
|
for (const { path, key } of endpoints) {
|
|
176
|
-
const relativePath = relative(dirname(
|
|
173
|
+
const relativePath = relative(dirname(endpointsPath), path.relative);
|
|
177
174
|
const importPath = relativePath.replace(/\.ts$/, '.js');
|
|
178
175
|
|
|
179
176
|
if (!importsByFile.has(importPath)) {
|
|
@@ -182,15 +179,6 @@ export class EndpointGenerator extends ConstructGenerator<
|
|
|
182
179
|
importsByFile.get(importPath)!.push(key);
|
|
183
180
|
}
|
|
184
181
|
|
|
185
|
-
const relativeEnvParserPath = relative(
|
|
186
|
-
dirname(serverPath),
|
|
187
|
-
context.envParserPath,
|
|
188
|
-
);
|
|
189
|
-
const relativeLoggerPath = relative(
|
|
190
|
-
dirname(serverPath),
|
|
191
|
-
context.loggerPath,
|
|
192
|
-
);
|
|
193
|
-
|
|
194
182
|
// Generate import statements
|
|
195
183
|
const imports = Array.from(importsByFile.entries())
|
|
196
184
|
.map(
|
|
@@ -201,21 +189,24 @@ export class EndpointGenerator extends ConstructGenerator<
|
|
|
201
189
|
|
|
202
190
|
const allExportNames = endpoints.map(({ key }) => key);
|
|
203
191
|
|
|
204
|
-
const content = `import {
|
|
205
|
-
import {
|
|
206
|
-
import {
|
|
207
|
-
import {
|
|
208
|
-
import
|
|
209
|
-
import
|
|
192
|
+
const content = `import type { EnvironmentParser } from '@geekmidas/envkit';
|
|
193
|
+
import type { Logger } from '@geekmidas/logger';
|
|
194
|
+
import { HonoEndpoint } from '@geekmidas/constructs/hono';
|
|
195
|
+
import { Endpoint } from '@geekmidas/constructs/endpoints';
|
|
196
|
+
import { ServiceDiscovery } from '@geekmidas/services';
|
|
197
|
+
import type { Hono } from 'hono';
|
|
210
198
|
${imports}
|
|
211
199
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const endpoints: Endpoint<any, any, any, any, any, any, any>[] = [
|
|
216
|
-
${allExportNames.join(',\n ')}
|
|
217
|
-
];
|
|
200
|
+
const endpoints: Endpoint<any, any, any, any, any, any, any, any>[] = [
|
|
201
|
+
${allExportNames.join(',\n ')}
|
|
202
|
+
];
|
|
218
203
|
|
|
204
|
+
export function setupEndpoints(
|
|
205
|
+
app: Hono,
|
|
206
|
+
envParser: EnvironmentParser<any>,
|
|
207
|
+
logger: Logger,
|
|
208
|
+
enableOpenApi: boolean = true,
|
|
209
|
+
): void {
|
|
219
210
|
const serviceDiscovery = ServiceDiscovery.getInstance(
|
|
220
211
|
logger,
|
|
221
212
|
envParser
|
|
@@ -231,18 +222,126 @@ export function createApp(app?: Hono, enableOpenApi: boolean = ${enableOpenApi})
|
|
|
231
222
|
}
|
|
232
223
|
} : { docsPath: false };
|
|
233
224
|
|
|
234
|
-
HonoEndpoint.addRoutes(endpoints, serviceDiscovery,
|
|
225
|
+
HonoEndpoint.addRoutes(endpoints, serviceDiscovery, app, openApiOptions);
|
|
226
|
+
}
|
|
227
|
+
`;
|
|
228
|
+
|
|
229
|
+
await writeFile(endpointsPath, content);
|
|
230
|
+
|
|
231
|
+
return endpointsPath;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
private async generateAppFile(
|
|
235
|
+
outputDir: string,
|
|
236
|
+
context: BuildContext,
|
|
237
|
+
): Promise<string> {
|
|
238
|
+
const appFileName = 'app.ts';
|
|
239
|
+
const appPath = join(outputDir, appFileName);
|
|
235
240
|
|
|
236
|
-
|
|
241
|
+
const relativeLoggerPath = relative(dirname(appPath), context.loggerPath);
|
|
242
|
+
|
|
243
|
+
const relativeEnvParserPath = relative(
|
|
244
|
+
dirname(appPath),
|
|
245
|
+
context.envParserPath,
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
const content = `/**
|
|
249
|
+
* Generated server application
|
|
250
|
+
*
|
|
251
|
+
* ⚠️ WARNING: This is for LOCAL DEVELOPMENT ONLY
|
|
252
|
+
* The subscriber polling mechanism is not production-ready.
|
|
253
|
+
* For production, use AWS Lambda with SQS/SNS event sources.
|
|
254
|
+
*/
|
|
255
|
+
import { Hono } from 'hono';
|
|
256
|
+
import type { Hono as HonoType } from 'hono';
|
|
257
|
+
import { setupEndpoints } from './endpoints.js';
|
|
258
|
+
import { setupSubscribers } from './subscribers.js';
|
|
259
|
+
import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
|
|
260
|
+
import ${context.loggerImportPattern} from '${relativeLoggerPath}';
|
|
261
|
+
|
|
262
|
+
export interface ServerApp {
|
|
263
|
+
app: HonoType;
|
|
264
|
+
start: (options?: {
|
|
265
|
+
port?: number;
|
|
266
|
+
serve: (app: HonoType, port: number) => void | Promise<void>;
|
|
267
|
+
}) => Promise<void>;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Create and configure the Hono application
|
|
272
|
+
*
|
|
273
|
+
* @param app - Optional Hono app instance to configure (creates new one if not provided)
|
|
274
|
+
* @param enableOpenApi - Enable OpenAPI documentation (default: true)
|
|
275
|
+
* @returns Server app with configured Hono app and start function
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* // With Bun
|
|
279
|
+
* import { createApp } from './.gkm/server/app.js';
|
|
280
|
+
*
|
|
281
|
+
* const { app, start } = createApp();
|
|
282
|
+
*
|
|
283
|
+
* await start({
|
|
284
|
+
* port: 3000,
|
|
285
|
+
* serve: (app, port) => {
|
|
286
|
+
* Bun.serve({ port, fetch: app.fetch });
|
|
287
|
+
* }
|
|
288
|
+
* });
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* // With Node.js (using @hono/node-server)
|
|
292
|
+
* import { serve } from '@hono/node-server';
|
|
293
|
+
* import { createApp } from './.gkm/server/app.js';
|
|
294
|
+
*
|
|
295
|
+
* const { app, start } = createApp();
|
|
296
|
+
*
|
|
297
|
+
* await start({
|
|
298
|
+
* port: 3000,
|
|
299
|
+
* serve: (app, port) => {
|
|
300
|
+
* serve({ fetch: app.fetch, port });
|
|
301
|
+
* }
|
|
302
|
+
* });
|
|
303
|
+
*/
|
|
304
|
+
export function createApp(app?: HonoType, enableOpenApi: boolean = true): ServerApp {
|
|
305
|
+
const honoApp = app || new Hono();
|
|
306
|
+
|
|
307
|
+
// Setup HTTP endpoints
|
|
308
|
+
setupEndpoints(honoApp, envParser, logger, enableOpenApi);
|
|
309
|
+
|
|
310
|
+
return {
|
|
311
|
+
app: honoApp,
|
|
312
|
+
async start(options) {
|
|
313
|
+
if (!options?.serve) {
|
|
314
|
+
throw new Error(
|
|
315
|
+
'serve function is required. Pass a serve function for your runtime:\\n' +
|
|
316
|
+
' - Bun: (app, port) => Bun.serve({ port, fetch: app.fetch })\\n' +
|
|
317
|
+
' - Node: (app, port) => serve({ fetch: app.fetch, port })'
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const port = options.port ?? 3000;
|
|
322
|
+
|
|
323
|
+
// Start subscribers in background (non-blocking, local development only)
|
|
324
|
+
await setupSubscribers(envParser, logger).catch((error) => {
|
|
325
|
+
logger.error({ error }, 'Failed to start subscribers');
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
logger.info({ port }, 'Starting server');
|
|
329
|
+
|
|
330
|
+
// Start HTTP server using provided serve function
|
|
331
|
+
await options.serve(honoApp, port);
|
|
332
|
+
|
|
333
|
+
logger.info({ port }, 'Server started');
|
|
334
|
+
}
|
|
335
|
+
};
|
|
237
336
|
}
|
|
238
337
|
|
|
239
338
|
// Default export for convenience
|
|
240
339
|
export default createApp;
|
|
241
340
|
`;
|
|
242
341
|
|
|
243
|
-
await writeFile(
|
|
342
|
+
await writeFile(appPath, content);
|
|
244
343
|
|
|
245
|
-
return
|
|
344
|
+
return appPath;
|
|
246
345
|
}
|
|
247
346
|
|
|
248
347
|
private generateAWSApiGatewayV1Handler(
|
|
@@ -251,7 +350,7 @@ export default createApp;
|
|
|
251
350
|
envParserPath: string,
|
|
252
351
|
envParserImportPattern: string,
|
|
253
352
|
): string {
|
|
254
|
-
return `import { AmazonApiGatewayV1Endpoint } from '@geekmidas/
|
|
353
|
+
return `import { AmazonApiGatewayV1Endpoint } from '@geekmidas/constructs/aws';
|
|
255
354
|
import { ${exportName} } from '${importPath}';
|
|
256
355
|
import ${envParserImportPattern} from '${envParserPath}';
|
|
257
356
|
|
|
@@ -267,7 +366,7 @@ export const handler = adapter.handler;
|
|
|
267
366
|
envParserPath: string,
|
|
268
367
|
envParserImportPattern: string,
|
|
269
368
|
): string {
|
|
270
|
-
return `import { AmazonApiGatewayV2Endpoint } from '@geekmidas/
|
|
369
|
+
return `import { AmazonApiGatewayV2Endpoint } from '@geekmidas/constructs/aws';
|
|
271
370
|
import { ${exportName} } from '${importPath}';
|
|
272
371
|
import ${envParserImportPattern} from '${envParserPath}';
|
|
273
372
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join, relative } from 'node:path';
|
|
3
|
-
import { Function } from '@geekmidas/
|
|
3
|
+
import { Function } from '@geekmidas/constructs/functions';
|
|
4
4
|
import type { BuildContext } from '../build/types';
|
|
5
5
|
import type { FunctionInfo } from '../types';
|
|
6
6
|
import {
|
|
@@ -51,6 +51,7 @@ export class FunctionGenerator extends ConstructGenerator<
|
|
|
51
51
|
'.handler',
|
|
52
52
|
),
|
|
53
53
|
timeout: construct.timeout,
|
|
54
|
+
environment: await construct.getEnvironment(),
|
|
54
55
|
});
|
|
55
56
|
|
|
56
57
|
logger.log(`Generated function handler: ${key}`);
|
|
@@ -80,7 +81,7 @@ export class FunctionGenerator extends ConstructGenerator<
|
|
|
80
81
|
context.loggerPath,
|
|
81
82
|
);
|
|
82
83
|
|
|
83
|
-
const content = `import { AWSLambdaFunction } from '@geekmidas/
|
|
84
|
+
const content = `import { AWSLambdaFunction } from '@geekmidas/constructs/functions';
|
|
84
85
|
import { ${exportName} } from '${importPath}';
|
|
85
86
|
import ${context.envParserImportPattern} from '${relativeEnvParserPath}';
|
|
86
87
|
import ${context.loggerImportPattern} from '${relativeLoggerPath}';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { relative } from 'path';
|
|
2
|
-
import type { Construct } from '@geekmidas/
|
|
2
|
+
import type { Construct } from '@geekmidas/constructs';
|
|
3
3
|
import fg from 'fast-glob';
|
|
4
4
|
import kebabCase from 'lodash.kebabcase';
|
|
5
5
|
import type { BuildContext } from '../build/types';
|