mirror of
https://github.com/honojs/hono.git
synced 2024-12-01 10:51:01 +00:00
Merge branch 'main' into next
This commit is contained in:
commit
1bfecc15e2
@ -9,6 +9,12 @@ describe('AWS Lambda Adapter for Hono', () => {
|
|||||||
return c.text('Hello Lambda!')
|
return c.text('Hello Lambda!')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.get('/binary', (c) => {
|
||||||
|
return c.body('Fake Image', 200, {
|
||||||
|
'Content-Type': 'image/png',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
app.post('/post', async (c) => {
|
app.post('/post', async (c) => {
|
||||||
const body = (await c.req.parseBody()) as { message: string }
|
const body = (await c.req.parseBody()) as { message: string }
|
||||||
return c.text(body.message)
|
return c.text(body.message)
|
||||||
@ -35,8 +41,27 @@ describe('AWS Lambda Adapter for Hono', () => {
|
|||||||
|
|
||||||
const response = await handler(event)
|
const response = await handler(event)
|
||||||
expect(response.statusCode).toBe(200)
|
expect(response.statusCode).toBe(200)
|
||||||
expect(response.body).toBe('SGVsbG8gTGFtYmRhIQ==')
|
expect(response.body).toBe('Hello Lambda!')
|
||||||
expect(response.headers['content-type']).toMatch(/^text\/plain/)
|
expect(response.headers['content-type']).toMatch(/^text\/plain/)
|
||||||
|
expect(response.isBase64Encoded).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should handle a GET request and return a 200 response with binary', async () => {
|
||||||
|
const event = {
|
||||||
|
httpMethod: 'GET',
|
||||||
|
headers: {},
|
||||||
|
path: '/binary',
|
||||||
|
body: null,
|
||||||
|
isBase64Encoded: false,
|
||||||
|
requestContext: {
|
||||||
|
domainName: 'example.com',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await handler(event)
|
||||||
|
expect(response.statusCode).toBe(200)
|
||||||
|
expect(response.body).toBe('RmFrZSBJbWFnZQ==')
|
||||||
|
expect(response.headers['content-type']).toMatch(/^image\/png/)
|
||||||
expect(response.isBase64Encoded).toBe(true)
|
expect(response.isBase64Encoded).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -53,14 +78,14 @@ describe('AWS Lambda Adapter for Hono', () => {
|
|||||||
method: 'GET',
|
method: 'GET',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
const response = await handler(event);
|
const response = await handler(event)
|
||||||
expect(response.statusCode).toBe(200);
|
expect(response.statusCode).toBe(200)
|
||||||
expect(response.body).toBe('SGVsbG8gTGFtYmRhIQ==');
|
expect(response.body).toBe('Hello Lambda!')
|
||||||
expect(response.headers['content-type']).toMatch(/^text\/plain/);
|
expect(response.headers['content-type']).toMatch(/^text\/plain/)
|
||||||
expect(response.isBase64Encoded).toBe(true);
|
expect(response.isBase64Encoded).toBe(false)
|
||||||
});
|
})
|
||||||
|
|
||||||
it('Should handle a GET request and return a 404 response', async () => {
|
it('Should handle a GET request and return a 404 response', async () => {
|
||||||
const event = {
|
const event = {
|
||||||
@ -96,12 +121,12 @@ describe('AWS Lambda Adapter for Hono', () => {
|
|||||||
|
|
||||||
const response = await handler(event)
|
const response = await handler(event)
|
||||||
expect(response.statusCode).toBe(200)
|
expect(response.statusCode).toBe(200)
|
||||||
expect(response.body).toBe('R29vZCBNb3JuaW5nIExhbWJkYSE=')
|
expect(response.body).toBe('Good Morning Lambda!')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should handle a POST request and return a 200 response (LambdaFunctionUrlEvent)', async () => {
|
it('Should handle a POST request and return a 200 response (LambdaFunctionUrlEvent)', async () => {
|
||||||
const searchParam = new URLSearchParams();
|
const searchParam = new URLSearchParams()
|
||||||
searchParam.append('message', 'Good Morning Lambda!');
|
searchParam.append('message', 'Good Morning Lambda!')
|
||||||
const event = {
|
const event = {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
@ -116,12 +141,12 @@ describe('AWS Lambda Adapter for Hono', () => {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
const response = await handler(event);
|
const response = await handler(event)
|
||||||
expect(response.statusCode).toBe(200);
|
expect(response.statusCode).toBe(200)
|
||||||
expect(response.body).toBe('R29vZCBNb3JuaW5nIExhbWJkYSE=');
|
expect(response.body).toBe('Good Morning Lambda!')
|
||||||
});
|
})
|
||||||
|
|
||||||
it('Should handle a request and return a 401 response with Basic auth', async () => {
|
it('Should handle a request and return a 401 response with Basic auth', async () => {
|
||||||
const event = {
|
const event = {
|
||||||
@ -159,6 +184,6 @@ describe('AWS Lambda Adapter for Hono', () => {
|
|||||||
|
|
||||||
const response = await handler(event)
|
const response = await handler(event)
|
||||||
expect(response.statusCode).toBe(200)
|
expect(response.statusCode).toBe(200)
|
||||||
expect(response.body).toBe('R29vZCBOaWdodCBMYW1iZGEh')
|
expect(response.body).toBe('Good Night Lambda!')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
15
src/adapter/aws-lambda/handler.test.ts
Normal file
15
src/adapter/aws-lambda/handler.test.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { isContentTypeBinary } from './handler'
|
||||||
|
|
||||||
|
describe('isContentTypeBinary', () => {
|
||||||
|
it('Should determine whether it is binary', () => {
|
||||||
|
expect(isContentTypeBinary('image/png')).toBe(true)
|
||||||
|
expect(isContentTypeBinary('font/woff2')).toBe(true)
|
||||||
|
expect(isContentTypeBinary('text/plain')).toBe(false)
|
||||||
|
expect(isContentTypeBinary('text/plain; charset=UTF-8')).toBe(false)
|
||||||
|
expect(isContentTypeBinary('text/css')).toBe(false)
|
||||||
|
expect(isContentTypeBinary('text/javascript')).toBe(false)
|
||||||
|
expect(isContentTypeBinary('application/json')).toBe(false)
|
||||||
|
expect(isContentTypeBinary('application/ld+json')).toBe(false)
|
||||||
|
expect(isContentTypeBinary('application/json; charset=UTF-8')).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
@ -40,9 +40,9 @@ interface LambdaFunctionUrlEvent {
|
|||||||
body: string | null
|
body: string | null
|
||||||
isBase64Encoded: boolean
|
isBase64Encoded: boolean
|
||||||
requestContext: {
|
requestContext: {
|
||||||
domainName: string,
|
domainName: string
|
||||||
http: {
|
http: {
|
||||||
method: string,
|
method: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,11 +69,16 @@ export const handle = (app: Hono) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const createResult = async (res: Response): Promise<APIGatewayProxyResult> => {
|
const createResult = async (res: Response): Promise<APIGatewayProxyResult> => {
|
||||||
|
const contentType = res.headers.get('content-type')
|
||||||
|
const isBase64Encoded = contentType && isContentTypeBinary(contentType) ? true : false
|
||||||
|
|
||||||
|
const body = isBase64Encoded ? await fromReadableToString(res) : await res.text()
|
||||||
|
|
||||||
const result: APIGatewayProxyResult = {
|
const result: APIGatewayProxyResult = {
|
||||||
body: await fromReadableToString(res),
|
body: body,
|
||||||
headers: {},
|
headers: {},
|
||||||
statusCode: res.status,
|
statusCode: res.status,
|
||||||
isBase64Encoded: true,
|
isBase64Encoded,
|
||||||
}
|
}
|
||||||
|
|
||||||
res.headers.forEach((value, key) => {
|
res.headers.forEach((value, key) => {
|
||||||
@ -83,9 +88,13 @@ const createResult = async (res: Response): Promise<APIGatewayProxyResult> => {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const createRequest = (event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | LambdaFunctionUrlEvent) => {
|
const createRequest = (
|
||||||
|
event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | LambdaFunctionUrlEvent
|
||||||
|
) => {
|
||||||
const queryString = extractQueryString(event)
|
const queryString = extractQueryString(event)
|
||||||
const urlPath = `https://${event.requestContext.domainName}${isProxyEvent(event) ? event.path : event.rawPath}`
|
const urlPath = `https://${event.requestContext.domainName}${
|
||||||
|
isProxyEvent(event) ? event.path : event.rawPath
|
||||||
|
}`
|
||||||
const url = queryString ? `${urlPath}?${queryString}` : urlPath
|
const url = queryString ? `${urlPath}?${queryString}` : urlPath
|
||||||
|
|
||||||
const headers = new Headers()
|
const headers = new Headers()
|
||||||
@ -96,7 +105,7 @@ const createRequest = (event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | La
|
|||||||
const method = 'httpMethod' in event ? event.httpMethod : event.requestContext.http.method
|
const method = 'httpMethod' in event ? event.httpMethod : event.requestContext.http.method
|
||||||
const requestInit: RequestInit = {
|
const requestInit: RequestInit = {
|
||||||
headers,
|
headers,
|
||||||
method
|
method,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.body) {
|
if (event.body) {
|
||||||
@ -106,7 +115,9 @@ const createRequest = (event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | La
|
|||||||
return new Request(url, requestInit)
|
return new Request(url, requestInit)
|
||||||
}
|
}
|
||||||
|
|
||||||
const extractQueryString = (event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | LambdaFunctionUrlEvent) => {
|
const extractQueryString = (
|
||||||
|
event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | LambdaFunctionUrlEvent
|
||||||
|
) => {
|
||||||
if (isProxyEvent(event)) {
|
if (isProxyEvent(event)) {
|
||||||
return Object.entries(event.queryStringParameters || {})
|
return Object.entries(event.queryStringParameters || {})
|
||||||
.filter(([, value]) => value)
|
.filter(([, value]) => value)
|
||||||
@ -142,3 +153,9 @@ const fromReadableToString = async (res: Response) => {
|
|||||||
|
|
||||||
return btoa(string)
|
return btoa(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const isContentTypeBinary = (contentType: string) => {
|
||||||
|
return !/^(text\/(plain|html|css|javascript|csv).*|application\/(.*json|.*xml).*|image\/svg\+xml)$/.test(
|
||||||
|
contentType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user