@geekmidas/cli 0.0.26 → 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/FUNCTION_CRON_SUPPORT.md +266 -0
- package/README.md +84 -17
- package/dist/CronGenerator-1PflEYe2.cjs +60 -0
- package/dist/CronGenerator-1PflEYe2.cjs.map +1 -0
- package/dist/CronGenerator-DXRfHQcV.mjs +54 -0
- package/dist/CronGenerator-DXRfHQcV.mjs.map +1 -0
- package/dist/EndpointGenerator-BbGrDiCP.cjs +264 -0
- package/dist/EndpointGenerator-BbGrDiCP.cjs.map +1 -0
- package/dist/EndpointGenerator-BmZ9BxbO.mjs +258 -0
- package/dist/EndpointGenerator-BmZ9BxbO.mjs.map +1 -0
- package/dist/FunctionGenerator-Clw64SwQ.cjs +59 -0
- package/dist/FunctionGenerator-Clw64SwQ.cjs.map +1 -0
- package/dist/FunctionGenerator-DOEB_yPh.mjs +53 -0
- package/dist/FunctionGenerator-DOEB_yPh.mjs.map +1 -0
- package/dist/Generator-CDoEXCDg.cjs +47 -0
- package/dist/Generator-CDoEXCDg.cjs.map +1 -0
- package/dist/Generator-UanJW0_V.mjs +41 -0
- 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 +12 -0
- package/dist/build/index.mjs +12 -0
- package/dist/build/manifests.cjs +3 -0
- package/dist/build/manifests.mjs +3 -0
- package/dist/build/providerResolver.cjs +5 -0
- package/dist/build/providerResolver.mjs +3 -0
- package/dist/build/types.cjs +0 -0
- package/dist/build/types.mjs +0 -0
- 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/config-D1EpSGk6.cjs +36 -0
- package/dist/config-D1EpSGk6.cjs.map +1 -0
- package/dist/config-U-mdW-7Y.mjs +30 -0
- package/dist/config-U-mdW-7Y.mjs.map +1 -0
- package/dist/config.cjs +1 -1
- package/dist/config.mjs +1 -1
- package/dist/generators/CronGenerator.cjs +4 -0
- package/dist/generators/CronGenerator.mjs +4 -0
- package/dist/generators/EndpointGenerator.cjs +4 -0
- package/dist/generators/EndpointGenerator.mjs +4 -0
- package/dist/generators/FunctionGenerator.cjs +4 -0
- package/dist/generators/FunctionGenerator.mjs +4 -0
- package/dist/generators/Generator.cjs +3 -0
- package/dist/generators/Generator.mjs +3 -0
- package/dist/generators/SubscriberGenerator.cjs +4 -0
- package/dist/generators/SubscriberGenerator.mjs +4 -0
- package/dist/generators/index.cjs +12 -0
- package/dist/generators/index.mjs +8 -0
- package/dist/generators-CEKtVh81.cjs +0 -0
- package/dist/generators-CsLujGXs.mjs +0 -0
- package/dist/index.cjs +71 -25
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +71 -25
- package/dist/index.mjs.map +1 -0
- package/dist/manifests-BrJXpHrf.mjs +21 -0
- package/dist/manifests-BrJXpHrf.mjs.map +1 -0
- package/dist/manifests-D0saShvH.cjs +27 -0
- package/dist/manifests-D0saShvH.cjs.map +1 -0
- package/dist/{openapi-CksVdkh2.mjs → openapi-BQx3_JbM.mjs} +8 -6
- package/dist/openapi-BQx3_JbM.mjs.map +1 -0
- package/dist/{openapi-D4QQJUPY.cjs → openapi-CMLr04cz.cjs} +9 -7
- package/dist/openapi-CMLr04cz.cjs.map +1 -0
- package/dist/{openapi-react-query-DpT3XHFC.mjs → openapi-react-query-DbrWwQzb.mjs} +5 -3
- package/dist/openapi-react-query-DbrWwQzb.mjs.map +1 -0
- package/dist/{openapi-react-query-C1JLYUOs.cjs → openapi-react-query-Dvjqx_Eo.cjs} +5 -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 -3
- package/dist/openapi.mjs +4 -3
- package/dist/providerResolver-B_TjNF0_.mjs +96 -0
- package/dist/providerResolver-B_TjNF0_.mjs.map +1 -0
- package/dist/providerResolver-DgvzNfP4.cjs +114 -0
- package/dist/providerResolver-DgvzNfP4.cjs.map +1 -0
- package/examples/cron-example.ts +45 -0
- package/examples/function-example.ts +40 -0
- package/examples/gkm.config.json +22 -0
- package/examples/gkm.minimal.config.json +7 -0
- package/examples/gkm.production.config.json +27 -0
- package/examples/logger.ts +1 -1
- package/package.json +38 -14
- package/src/__tests__/config.spec.ts +110 -0
- package/src/__tests__/openapi-react-query.spec.ts +506 -0
- package/src/__tests__/openapi.spec.ts +362 -0
- package/src/__tests__/test-helpers.ts +180 -0
- package/src/build/__tests__/index-new.spec.ts +577 -0
- package/src/build/index.ts +197 -0
- package/src/build/manifests.ts +35 -0
- package/src/build/providerResolver.ts +184 -0
- package/src/build/types.ts +37 -0
- package/src/config.ts +14 -6
- package/src/generators/CronGenerator.ts +98 -0
- package/src/generators/EndpointGenerator.ts +389 -0
- package/src/generators/FunctionGenerator.ts +97 -0
- package/src/generators/Generator.ts +95 -0
- package/src/generators/SubscriberGenerator.ts +271 -0
- package/src/generators/__tests__/CronGenerator.spec.ts +445 -0
- package/src/generators/__tests__/EndpointGenerator.spec.ts +394 -0
- package/src/generators/__tests__/FunctionGenerator.spec.ts +256 -0
- package/src/generators/__tests__/SubscriberGenerator.spec.ts +341 -0
- package/src/generators/index.ts +9 -0
- package/src/index.ts +57 -22
- package/src/openapi-react-query.ts +2 -1
- package/src/openapi.ts +5 -4
- package/src/types.ts +91 -2
- package/dist/build-BTggTCYL.cjs +0 -176
- package/dist/build-Ca4P6_lY.mjs +0 -170
- package/dist/build.cjs +0 -5
- package/dist/build.mjs +0 -5
- package/dist/config-BNqUMsvc.cjs +0 -24
- package/dist/config-BciAdY6_.mjs +0 -18
- package/dist/loadEndpoints-BBIavB9h.cjs +0 -37
- package/dist/loadEndpoints-DAZ53Og2.mjs +0 -31
- package/dist/loadEndpoints.cjs +0 -3
- package/dist/loadEndpoints.mjs +0 -3
- package/src/build.ts +0 -305
- package/src/loadEndpoints.ts +0 -48
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { itWithDir } from '@geekmidas/testkit/os';
|
|
4
|
+
import { describe, expect, vi } from 'vitest';
|
|
5
|
+
import {
|
|
6
|
+
createMockCronFile,
|
|
7
|
+
createMockEndpointFile,
|
|
8
|
+
createMockFunctionFile,
|
|
9
|
+
createTestFile,
|
|
10
|
+
} from '../../__tests__/test-helpers';
|
|
11
|
+
import { buildCommand } from '../index';
|
|
12
|
+
|
|
13
|
+
describe('buildCommand', () => {
|
|
14
|
+
itWithDir(
|
|
15
|
+
'should build endpoints, functions, and crons for multiple providers',
|
|
16
|
+
async ({ dir }) => {
|
|
17
|
+
// Create test files that will be discovered
|
|
18
|
+
await createMockEndpointFile(
|
|
19
|
+
dir,
|
|
20
|
+
'src/endpoints/users.ts',
|
|
21
|
+
'getUsersEndpoint',
|
|
22
|
+
'/users',
|
|
23
|
+
'GET',
|
|
24
|
+
);
|
|
25
|
+
await createMockEndpointFile(
|
|
26
|
+
dir,
|
|
27
|
+
'src/endpoints/posts.ts',
|
|
28
|
+
'getPostsEndpoint',
|
|
29
|
+
'/posts',
|
|
30
|
+
'GET',
|
|
31
|
+
);
|
|
32
|
+
await createMockFunctionFile(
|
|
33
|
+
dir,
|
|
34
|
+
'src/functions/process.ts',
|
|
35
|
+
'processDataFunction',
|
|
36
|
+
60,
|
|
37
|
+
);
|
|
38
|
+
await createMockCronFile(
|
|
39
|
+
dir,
|
|
40
|
+
'src/crons/cleanup.ts',
|
|
41
|
+
'cleanupCron',
|
|
42
|
+
'rate(1 day)',
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Create a basic config file
|
|
46
|
+
await createTestFile(
|
|
47
|
+
dir,
|
|
48
|
+
'gkm.config.ts',
|
|
49
|
+
`
|
|
50
|
+
export default {
|
|
51
|
+
routes: './src/endpoints/**/*.ts',
|
|
52
|
+
functions: './src/functions/**/*.ts',
|
|
53
|
+
crons: './src/crons/**/*.ts',
|
|
54
|
+
envParser: './config/env',
|
|
55
|
+
logger: './config/logger',
|
|
56
|
+
};
|
|
57
|
+
`,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Create env and logger files
|
|
61
|
+
await createTestFile(dir, 'config/env.ts', 'export default {}');
|
|
62
|
+
await createTestFile(dir, 'config/logger.ts', 'export default {}');
|
|
63
|
+
|
|
64
|
+
const originalCwd = process.cwd();
|
|
65
|
+
process.chdir(dir);
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
await buildCommand({ provider: 'server' });
|
|
69
|
+
|
|
70
|
+
// Check that output directories were created
|
|
71
|
+
const serverDir = join(dir, '.gkm', 'server');
|
|
72
|
+
|
|
73
|
+
// Check app.ts has the createApp function with new API
|
|
74
|
+
const appContent = await readFile(join(serverDir, 'app.ts'), 'utf-8');
|
|
75
|
+
expect(appContent).toContain('function createApp');
|
|
76
|
+
expect(appContent).toContain('interface ServerApp');
|
|
77
|
+
expect(appContent).toContain('async start(options');
|
|
78
|
+
|
|
79
|
+
// Check endpoints.ts has the HonoEndpoint setup
|
|
80
|
+
const endpointsContent = await readFile(
|
|
81
|
+
join(serverDir, 'endpoints.ts'),
|
|
82
|
+
'utf-8',
|
|
83
|
+
);
|
|
84
|
+
expect(endpointsContent).toContain('HonoEndpoint');
|
|
85
|
+
} finally {
|
|
86
|
+
process.chdir(originalCwd);
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
itWithDir(
|
|
92
|
+
'should perform complete build with all construct types for AWS Lambda',
|
|
93
|
+
async ({ dir }) => {
|
|
94
|
+
// Create comprehensive test setup with all construct types
|
|
95
|
+
await createMockEndpointFile(
|
|
96
|
+
dir,
|
|
97
|
+
'src/endpoints/users.ts',
|
|
98
|
+
'getUsersEndpoint',
|
|
99
|
+
'/users',
|
|
100
|
+
'GET',
|
|
101
|
+
);
|
|
102
|
+
await createMockEndpointFile(
|
|
103
|
+
dir,
|
|
104
|
+
'src/endpoints/posts.ts',
|
|
105
|
+
'getPostsEndpoint',
|
|
106
|
+
'/posts',
|
|
107
|
+
'POST',
|
|
108
|
+
);
|
|
109
|
+
await createMockFunctionFile(
|
|
110
|
+
dir,
|
|
111
|
+
'src/functions/processData.ts',
|
|
112
|
+
'processDataFunction',
|
|
113
|
+
300,
|
|
114
|
+
);
|
|
115
|
+
await createMockFunctionFile(
|
|
116
|
+
dir,
|
|
117
|
+
'src/functions/sendEmail.ts',
|
|
118
|
+
'sendEmailFunction',
|
|
119
|
+
30,
|
|
120
|
+
);
|
|
121
|
+
await createMockCronFile(
|
|
122
|
+
dir,
|
|
123
|
+
'src/crons/dailyCleanup.ts',
|
|
124
|
+
'dailyCleanupCron',
|
|
125
|
+
'rate(1 day)',
|
|
126
|
+
);
|
|
127
|
+
await createMockCronFile(
|
|
128
|
+
dir,
|
|
129
|
+
'src/crons/hourlyReport.ts',
|
|
130
|
+
'hourlyReportCron',
|
|
131
|
+
'cron(0 * * * ? *)',
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Create config
|
|
135
|
+
await createTestFile(
|
|
136
|
+
dir,
|
|
137
|
+
'gkm.config.ts',
|
|
138
|
+
`
|
|
139
|
+
export default {
|
|
140
|
+
routes: './src/endpoints/**/*.ts',
|
|
141
|
+
functions: './src/functions/**/*.ts',
|
|
142
|
+
crons: './src/crons/**/*.ts',
|
|
143
|
+
envParser: './config/env',
|
|
144
|
+
logger: './config/logger',
|
|
145
|
+
};
|
|
146
|
+
`,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// Create env and logger files
|
|
150
|
+
await createTestFile(dir, 'config/env.ts', 'export default {}');
|
|
151
|
+
await createTestFile(dir, 'config/logger.ts', 'export default {}');
|
|
152
|
+
|
|
153
|
+
const originalCwd = process.cwd();
|
|
154
|
+
process.chdir(dir);
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
// Build for AWS Lambda
|
|
158
|
+
await buildCommand({ provider: 'aws' });
|
|
159
|
+
|
|
160
|
+
const awsLambdaDir = join(dir, '.gkm', 'aws-lambda');
|
|
161
|
+
const awsApiGatewayV2Dir = join(dir, '.gkm', 'aws-apigatewayv2');
|
|
162
|
+
|
|
163
|
+
// Verify Lambda handlers were created
|
|
164
|
+
expect(
|
|
165
|
+
await readFile(
|
|
166
|
+
join(awsLambdaDir, 'functions', 'processDataFunction.ts'),
|
|
167
|
+
'utf-8',
|
|
168
|
+
),
|
|
169
|
+
).toContain('AWSLambdaFunction');
|
|
170
|
+
expect(
|
|
171
|
+
await readFile(
|
|
172
|
+
join(awsLambdaDir, 'functions', 'sendEmailFunction.ts'),
|
|
173
|
+
'utf-8',
|
|
174
|
+
),
|
|
175
|
+
).toContain('AWSLambdaFunction');
|
|
176
|
+
|
|
177
|
+
// Verify Cron handlers were created
|
|
178
|
+
expect(
|
|
179
|
+
await readFile(
|
|
180
|
+
join(awsLambdaDir, 'crons', 'dailyCleanupCron.ts'),
|
|
181
|
+
'utf-8',
|
|
182
|
+
),
|
|
183
|
+
).toContain('AWSScheduledFunction');
|
|
184
|
+
expect(
|
|
185
|
+
await readFile(
|
|
186
|
+
join(awsLambdaDir, 'crons', 'hourlyReportCron.ts'),
|
|
187
|
+
'utf-8',
|
|
188
|
+
),
|
|
189
|
+
).toContain('AWSScheduledFunction');
|
|
190
|
+
|
|
191
|
+
// Verify API Gateway handlers were created
|
|
192
|
+
expect(
|
|
193
|
+
await readFile(
|
|
194
|
+
join(awsApiGatewayV2Dir, 'getUsersEndpoint.ts'),
|
|
195
|
+
'utf-8',
|
|
196
|
+
),
|
|
197
|
+
).toContain('AmazonApiGatewayV2Endpoint');
|
|
198
|
+
expect(
|
|
199
|
+
await readFile(
|
|
200
|
+
join(awsApiGatewayV2Dir, 'getPostsEndpoint.ts'),
|
|
201
|
+
'utf-8',
|
|
202
|
+
),
|
|
203
|
+
).toContain('AmazonApiGatewayV2Endpoint');
|
|
204
|
+
|
|
205
|
+
// Verify unified manifest was created at root .gkm directory
|
|
206
|
+
const manifestPath = join(dir, '.gkm', 'manifest.json');
|
|
207
|
+
const manifest = JSON.parse(await readFile(manifestPath, 'utf-8'));
|
|
208
|
+
|
|
209
|
+
// Verify manifest structure includes all routes from both providers
|
|
210
|
+
expect(manifest).toMatchObject({
|
|
211
|
+
routes: expect.arrayContaining([
|
|
212
|
+
// Routes from aws-lambda provider
|
|
213
|
+
expect.objectContaining({
|
|
214
|
+
path: '/users',
|
|
215
|
+
method: 'GET',
|
|
216
|
+
handler: expect.stringContaining(
|
|
217
|
+
'routes/getUsersEndpoint.handler',
|
|
218
|
+
),
|
|
219
|
+
}),
|
|
220
|
+
expect.objectContaining({
|
|
221
|
+
path: '/posts',
|
|
222
|
+
method: 'POST',
|
|
223
|
+
handler: expect.stringContaining(
|
|
224
|
+
'routes/getPostsEndpoint.handler',
|
|
225
|
+
),
|
|
226
|
+
}),
|
|
227
|
+
// Routes from aws-apigatewayv2 provider
|
|
228
|
+
expect.objectContaining({
|
|
229
|
+
path: '/users',
|
|
230
|
+
method: 'GET',
|
|
231
|
+
handler: expect.stringContaining('getUsersEndpoint.handler'),
|
|
232
|
+
}),
|
|
233
|
+
expect.objectContaining({
|
|
234
|
+
path: '/posts',
|
|
235
|
+
method: 'POST',
|
|
236
|
+
handler: expect.stringContaining('getPostsEndpoint.handler'),
|
|
237
|
+
}),
|
|
238
|
+
]),
|
|
239
|
+
functions: expect.arrayContaining([
|
|
240
|
+
expect.objectContaining({
|
|
241
|
+
name: 'processDataFunction',
|
|
242
|
+
handler: expect.stringContaining(
|
|
243
|
+
'functions/processDataFunction.handler',
|
|
244
|
+
),
|
|
245
|
+
timeout: 300,
|
|
246
|
+
}),
|
|
247
|
+
expect.objectContaining({
|
|
248
|
+
name: 'sendEmailFunction',
|
|
249
|
+
handler: expect.stringContaining(
|
|
250
|
+
'functions/sendEmailFunction.handler',
|
|
251
|
+
),
|
|
252
|
+
timeout: 30,
|
|
253
|
+
}),
|
|
254
|
+
]),
|
|
255
|
+
crons: expect.arrayContaining([
|
|
256
|
+
expect.objectContaining({
|
|
257
|
+
name: 'dailyCleanupCron',
|
|
258
|
+
handler: expect.stringContaining(
|
|
259
|
+
'crons/dailyCleanupCron.handler',
|
|
260
|
+
),
|
|
261
|
+
schedule: 'rate(1 day)',
|
|
262
|
+
}),
|
|
263
|
+
expect.objectContaining({
|
|
264
|
+
name: 'hourlyReportCron',
|
|
265
|
+
handler: expect.stringContaining(
|
|
266
|
+
'crons/hourlyReportCron.handler',
|
|
267
|
+
),
|
|
268
|
+
schedule: 'cron(0 * * * ? *)',
|
|
269
|
+
}),
|
|
270
|
+
]),
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Verify counts - should have duplicated routes (one for each provider)
|
|
274
|
+
expect(manifest.routes).toHaveLength(4); // 2 routes x 2 providers
|
|
275
|
+
expect(manifest.functions).toHaveLength(2);
|
|
276
|
+
expect(manifest.crons).toHaveLength(2);
|
|
277
|
+
} finally {
|
|
278
|
+
process.chdir(originalCwd);
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
itWithDir('should handle case with no constructs found', async ({ dir }) => {
|
|
284
|
+
// Create a basic config file with no actual construct files
|
|
285
|
+
await createTestFile(
|
|
286
|
+
dir,
|
|
287
|
+
'gkm.config.ts',
|
|
288
|
+
`
|
|
289
|
+
export default {
|
|
290
|
+
routes: './src/endpoints/**/*.ts',
|
|
291
|
+
functions: './src/functions/**/*.ts',
|
|
292
|
+
crons: './src/crons/**/*.ts',
|
|
293
|
+
envParser: './config/env',
|
|
294
|
+
logger: './config/logger',
|
|
295
|
+
};
|
|
296
|
+
`,
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
// Create env and logger files
|
|
300
|
+
await createTestFile(dir, 'config/env.ts', 'export default {}');
|
|
301
|
+
await createTestFile(dir, 'config/logger.ts', 'export default {}');
|
|
302
|
+
|
|
303
|
+
const originalCwd = process.cwd();
|
|
304
|
+
process.chdir(dir);
|
|
305
|
+
|
|
306
|
+
const logSpy = vi.spyOn(console, 'log');
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
await buildCommand({ provider: 'server' });
|
|
310
|
+
|
|
311
|
+
expect(logSpy).toHaveBeenCalledWith('Found 0 endpoints');
|
|
312
|
+
expect(logSpy).toHaveBeenCalledWith('Found 0 functions');
|
|
313
|
+
expect(logSpy).toHaveBeenCalledWith('Found 0 crons');
|
|
314
|
+
expect(logSpy).toHaveBeenCalledWith('Found 0 subscribers');
|
|
315
|
+
expect(logSpy).toHaveBeenCalledWith(
|
|
316
|
+
'No endpoints, functions, crons, or subscribers found to process',
|
|
317
|
+
);
|
|
318
|
+
} finally {
|
|
319
|
+
process.chdir(originalCwd);
|
|
320
|
+
logSpy.mockRestore();
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
itWithDir(
|
|
325
|
+
'should handle optional functions and crons config',
|
|
326
|
+
async ({ dir }) => {
|
|
327
|
+
// Create config with undefined functions and crons
|
|
328
|
+
await createTestFile(
|
|
329
|
+
dir,
|
|
330
|
+
'gkm.config.ts',
|
|
331
|
+
`
|
|
332
|
+
export default {
|
|
333
|
+
routes: './src/endpoints/**/*.ts',
|
|
334
|
+
functions: undefined,
|
|
335
|
+
crons: undefined,
|
|
336
|
+
envParser: './config/env',
|
|
337
|
+
logger: './config/logger',
|
|
338
|
+
};
|
|
339
|
+
`,
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
await createMockEndpointFile(
|
|
343
|
+
dir,
|
|
344
|
+
'src/endpoints/test.ts',
|
|
345
|
+
'testEndpoint',
|
|
346
|
+
'/test',
|
|
347
|
+
'GET',
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
// Create env and logger files
|
|
351
|
+
await createTestFile(dir, 'config/env.ts', 'export default {}');
|
|
352
|
+
await createTestFile(dir, 'config/logger.ts', 'export default {}');
|
|
353
|
+
|
|
354
|
+
const originalCwd = process.cwd();
|
|
355
|
+
process.chdir(dir);
|
|
356
|
+
|
|
357
|
+
const logSpy = vi.spyOn(console, 'log');
|
|
358
|
+
|
|
359
|
+
try {
|
|
360
|
+
await buildCommand({ provider: 'server' });
|
|
361
|
+
|
|
362
|
+
expect(logSpy).toHaveBeenCalledWith('Found 1 endpoints');
|
|
363
|
+
expect(logSpy).toHaveBeenCalledWith('Found 0 functions');
|
|
364
|
+
expect(logSpy).toHaveBeenCalledWith('Found 0 crons');
|
|
365
|
+
|
|
366
|
+
// Should not log functions or crons loading messages
|
|
367
|
+
expect(logSpy).not.toHaveBeenCalledWith(
|
|
368
|
+
expect.stringContaining('Loading functions'),
|
|
369
|
+
);
|
|
370
|
+
expect(logSpy).not.toHaveBeenCalledWith(
|
|
371
|
+
expect.stringContaining('Loading crons'),
|
|
372
|
+
);
|
|
373
|
+
} finally {
|
|
374
|
+
process.chdir(originalCwd);
|
|
375
|
+
logSpy.mockRestore();
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
itWithDir(
|
|
381
|
+
'should parse envParser configuration correctly',
|
|
382
|
+
async ({ dir }) => {
|
|
383
|
+
// Create config with custom named exports
|
|
384
|
+
await createTestFile(
|
|
385
|
+
dir,
|
|
386
|
+
'gkm.config.ts',
|
|
387
|
+
`
|
|
388
|
+
export default {
|
|
389
|
+
routes: './src/endpoints/**/*.ts',
|
|
390
|
+
functions: undefined,
|
|
391
|
+
crons: undefined,
|
|
392
|
+
envParser: './config/env#customEnvParser',
|
|
393
|
+
logger: './config/logger#customLogger',
|
|
394
|
+
};
|
|
395
|
+
`,
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
await createMockEndpointFile(
|
|
399
|
+
dir,
|
|
400
|
+
'src/endpoints/test.ts',
|
|
401
|
+
'testEndpoint',
|
|
402
|
+
'/test',
|
|
403
|
+
'GET',
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
// Create env and logger files with named exports
|
|
407
|
+
await createTestFile(
|
|
408
|
+
dir,
|
|
409
|
+
'config/env.ts',
|
|
410
|
+
'export const customEnvParser = {}',
|
|
411
|
+
);
|
|
412
|
+
await createTestFile(
|
|
413
|
+
dir,
|
|
414
|
+
'config/logger.ts',
|
|
415
|
+
'export const customLogger = {}',
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
const originalCwd = process.cwd();
|
|
419
|
+
process.chdir(dir);
|
|
420
|
+
|
|
421
|
+
try {
|
|
422
|
+
await buildCommand({ provider: 'aws' });
|
|
423
|
+
|
|
424
|
+
// Verify that a handler file was generated with correct imports
|
|
425
|
+
const handlerFile = join(dir, '.gkm/aws-apigatewayv2/testEndpoint.ts');
|
|
426
|
+
const handlerContent = await readFile(handlerFile, 'utf-8');
|
|
427
|
+
expect(handlerContent).toContain('{ customEnvParser as envParser }');
|
|
428
|
+
} finally {
|
|
429
|
+
process.chdir(originalCwd);
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
);
|
|
433
|
+
|
|
434
|
+
itWithDir(
|
|
435
|
+
'should create output directories for each provider',
|
|
436
|
+
async ({ dir }) => {
|
|
437
|
+
// Create config with multiple providers
|
|
438
|
+
await createTestFile(
|
|
439
|
+
dir,
|
|
440
|
+
'gkm.config.ts',
|
|
441
|
+
`
|
|
442
|
+
export default {
|
|
443
|
+
routes: './src/endpoints/**/*.ts',
|
|
444
|
+
functions: undefined,
|
|
445
|
+
crons: undefined,
|
|
446
|
+
envParser: './config/env',
|
|
447
|
+
logger: './config/logger',
|
|
448
|
+
};
|
|
449
|
+
`,
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
await createMockEndpointFile(
|
|
453
|
+
dir,
|
|
454
|
+
'src/endpoints/test.ts',
|
|
455
|
+
'testEndpoint',
|
|
456
|
+
'/test',
|
|
457
|
+
'GET',
|
|
458
|
+
);
|
|
459
|
+
|
|
460
|
+
// Create env and logger files
|
|
461
|
+
await createTestFile(dir, 'config/env.ts', 'export default {}');
|
|
462
|
+
await createTestFile(dir, 'config/logger.ts', 'export default {}');
|
|
463
|
+
|
|
464
|
+
const originalCwd = process.cwd();
|
|
465
|
+
process.chdir(dir);
|
|
466
|
+
|
|
467
|
+
try {
|
|
468
|
+
await buildCommand({ provider: 'aws' });
|
|
469
|
+
|
|
470
|
+
const v2HandlerFile = join(
|
|
471
|
+
dir,
|
|
472
|
+
'.gkm/aws-apigatewayv2/testEndpoint.ts',
|
|
473
|
+
);
|
|
474
|
+
|
|
475
|
+
const v2Content = await readFile(v2HandlerFile, 'utf-8');
|
|
476
|
+
|
|
477
|
+
expect(v2Content).toContain('AmazonApiGatewayV2Endpoint');
|
|
478
|
+
} finally {
|
|
479
|
+
process.chdir(originalCwd);
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
itWithDir(
|
|
485
|
+
'should handle default import patterns for envParser and logger',
|
|
486
|
+
async ({ dir }) => {
|
|
487
|
+
// Create config with default import patterns
|
|
488
|
+
await createTestFile(
|
|
489
|
+
dir,
|
|
490
|
+
'gkm.config.ts',
|
|
491
|
+
`
|
|
492
|
+
export default {
|
|
493
|
+
routes: './src/endpoints/**/*.ts',
|
|
494
|
+
functions: undefined,
|
|
495
|
+
crons: undefined,
|
|
496
|
+
envParser: './config/env',
|
|
497
|
+
logger: './config/logger',
|
|
498
|
+
};
|
|
499
|
+
`,
|
|
500
|
+
);
|
|
501
|
+
|
|
502
|
+
await createMockEndpointFile(
|
|
503
|
+
dir,
|
|
504
|
+
'src/endpoints/test.ts',
|
|
505
|
+
'testEndpoint',
|
|
506
|
+
'/test',
|
|
507
|
+
'GET',
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
// Create env and logger files with default exports
|
|
511
|
+
await createTestFile(dir, 'config/env.ts', 'export default {}');
|
|
512
|
+
await createTestFile(dir, 'config/logger.ts', 'export default {}');
|
|
513
|
+
|
|
514
|
+
const originalCwd = process.cwd();
|
|
515
|
+
process.chdir(dir);
|
|
516
|
+
|
|
517
|
+
try {
|
|
518
|
+
await buildCommand({ provider: 'aws' });
|
|
519
|
+
|
|
520
|
+
// Verify that a handler file was generated with default imports
|
|
521
|
+
const handlerFile = join(dir, '.gkm/aws-apigatewayv2/testEndpoint.ts');
|
|
522
|
+
const handlerContent = await readFile(handlerFile, 'utf-8');
|
|
523
|
+
expect(handlerContent).toContain('import envParser');
|
|
524
|
+
expect(handlerContent).not.toContain('{ envParser }');
|
|
525
|
+
} finally {
|
|
526
|
+
process.chdir(originalCwd);
|
|
527
|
+
}
|
|
528
|
+
},
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
itWithDir(
|
|
532
|
+
'should handle envParser pattern with same name as expected',
|
|
533
|
+
async ({ dir }) => {
|
|
534
|
+
// Create config with named exports that match expected names
|
|
535
|
+
await createTestFile(
|
|
536
|
+
dir,
|
|
537
|
+
'gkm.config.ts',
|
|
538
|
+
`
|
|
539
|
+
export default {
|
|
540
|
+
routes: './src/endpoints/**/*.ts',
|
|
541
|
+
functions: undefined,
|
|
542
|
+
crons: undefined,
|
|
543
|
+
envParser: './config/env#envParser',
|
|
544
|
+
logger: './config/logger#logger',
|
|
545
|
+
};
|
|
546
|
+
`,
|
|
547
|
+
);
|
|
548
|
+
|
|
549
|
+
await createMockEndpointFile(
|
|
550
|
+
dir,
|
|
551
|
+
'src/endpoints/test.ts',
|
|
552
|
+
'testEndpoint',
|
|
553
|
+
'/test',
|
|
554
|
+
'GET',
|
|
555
|
+
);
|
|
556
|
+
|
|
557
|
+
// Create env and logger files with named exports
|
|
558
|
+
await createTestFile(dir, 'config/env.ts', 'export const envParser = {}');
|
|
559
|
+
await createTestFile(dir, 'config/logger.ts', 'export const logger = {}');
|
|
560
|
+
|
|
561
|
+
const originalCwd = process.cwd();
|
|
562
|
+
process.chdir(dir);
|
|
563
|
+
|
|
564
|
+
try {
|
|
565
|
+
await buildCommand({ provider: 'aws' });
|
|
566
|
+
|
|
567
|
+
// Verify that a handler file was generated with named imports
|
|
568
|
+
const handlerFile = join(dir, '.gkm/aws-apigatewayv2/testEndpoint.ts');
|
|
569
|
+
const handlerContent = await readFile(handlerFile, 'utf-8');
|
|
570
|
+
|
|
571
|
+
expect(handlerContent).toContain('{ envParser }');
|
|
572
|
+
} finally {
|
|
573
|
+
process.chdir(originalCwd);
|
|
574
|
+
}
|
|
575
|
+
},
|
|
576
|
+
);
|
|
577
|
+
});
|