feat: add API Gateway route testing and discovery

This commit is contained in:
Zakaria
2026-09-24 08:56:22 -04:00
parent 7e49be27f1
commit 9bbe80b5f2
10 changed files with 802 additions and 6 deletions
+38
View File
@@ -522,6 +522,31 @@ export function createCloudRoutes(injectedService?: CloudProxyService) {
})
})
app.get('/:cloud/services/apigateway/resources/:id/routes', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => c.json(await svc(c).listApiGatewayRoutes(cloud, c.req.param('id'))))
})
app.post('/:cloud/services/apigateway/resources/:id/routes/test', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => {
const input = await c.req.json<Record<string, unknown>>()
const result = await svc(c).testApiGatewayRoute(cloud, c.req.param('id'), {
path: typeof input.path === 'string' ? input.path : '',
method: typeof input.method === 'string' ? input.method : '',
stage: typeof input.stage === 'string' ? input.stage : '',
body: typeof input.body === 'string' ? input.body : '',
headers: stringHeaders(input.headers),
query: typeof input.query === 'string' ? input.query : '',
})
return c.json(result)
})
})
app.get('/:cloud/services/:service/resources/:id/collections', async (c) => {
const target = childTarget(c)
if (!target) return c.json({error: 'Unknown cloud or service'}, 404)
@@ -857,6 +882,19 @@ function encryptionContext(value: unknown): Record<string, string> | undefined {
return entries.length === 0 ? undefined : Object.fromEntries(entries) as Record<string, string>
}
function stringHeaders(value: unknown): Record<string, string> {
if (value === undefined) return {}
if (!value || typeof value !== 'object' || Array.isArray(value)) {
throw new ValidationError('headers must be an object of string values')
}
const entries = Object.entries(value)
if (entries.some(([, headerValue]) => typeof headerValue !== 'string')) {
throw new ValidationError('headers must be an object of string values')
}
return Object.fromEntries(entries) as Record<string, string>
}
function decodeBase64(value: unknown, field: string, maxLength: number): Uint8Array {
if (typeof value !== 'string') throw new ValidationError(`${field} must be a base64 string`)
if (value.length > maxLength) throw new ValidationError(`${field} is too large`)