Initial commit

This commit is contained in:
Devin Zuczek
2026-06-08 18:23:40 -04:00
commit 8e644a5c20
141 changed files with 21414 additions and 0 deletions
@@ -0,0 +1,14 @@
import type { HonoApp } from '@repo/hono-helpers'
import type { SharedHonoEnv, SharedHonoVariables } from '@repo/hono-helpers/src/types'
export type Env = SharedHonoEnv & {
// add additional Bindings here
}
/** Variables can be extended */
export type Variables = SharedHonoVariables
export interface App extends HonoApp {
Bindings: Env
Variables: Variables
}
@@ -0,0 +1,59 @@
import { env } from 'cloudflare:workers'
import { Hono } from 'hono'
import { useWorkersLogger } from 'workers-tagged-logger'
import { getRequestLogData, logger, withNotFound, withOnError } from '@repo/hono-helpers'
import type { App } from './context'
const app = new Hono<App>()
.use(
'*',
// middleware
(c, next) =>
useWorkersLogger(c.env.NAME, {
environment: c.env.ENVIRONMENT,
release: c.env.SENTRY_RELEASE,
})(c, next)
)
.onError(withOnError())
.notFound(withNotFound())
.all('*', async (c) => {
const url = new URL(c.req.url)
// we can also access env variables via
// import { env } from 'cloudflare:workers'
logger.info(`release: ${env.SENTRY_RELEASE}`)
let body: string | undefined
if (['PUT', 'POST'].includes(c.req.method) && c.req.raw.body !== null) {
body = await c.req.text()
}
const headers = new Headers(c.req.raw.headers)
const data = {
method: c.req.method,
url: c.req.url,
path: url.pathname,
host: url.host,
hostname: url.hostname,
headers: Object.fromEntries(headers.entries()),
body: body ?? null,
}
logger
.withTags({
type: 'echoback_request',
echoback_host: url.hostname,
})
.info(`echoback request: ${url.toString()}`, {
data: JSON.stringify(data),
request: getRequestLogData(c, Date.now()),
})
return c.json(data)
})
export default app
@@ -0,0 +1,143 @@
import { exports } from 'cloudflare:workers'
import { describe, expect, it, test } from 'vitest'
import '../../example-worker-echoback.app'
describe('echoback returns data about the request', () => {
test('GET', async () => {
const res = await exports.default.fetch('https://example.com/stuff?foo=bar', {
headers: {
'X-Test': 'true',
},
})
expect(res.status).toBe(200)
expect(await res.json()).toMatchInlineSnapshot(`
{
"body": null,
"headers": {
"x-test": "true",
},
"host": "example.com",
"hostname": "example.com",
"method": "GET",
"path": "/stuff",
"url": "https://example.com/stuff?foo=bar",
}
`)
})
test('POST', async () => {
const res = await exports.default.fetch('https://example.com/stuff?foo=bar', {
method: 'POST',
body: 'hello world!',
headers: {
'X-Test': 'true',
},
})
expect(res.status).toBe(200)
expect(await res.json()).toMatchInlineSnapshot(`
{
"body": "hello world!",
"headers": {
"content-length": "12",
"content-type": "text/plain;charset=UTF-8",
"x-test": "true",
},
"host": "example.com",
"hostname": "example.com",
"method": "POST",
"path": "/stuff",
"url": "https://example.com/stuff?foo=bar",
}
`)
})
test('PUT', async () => {
const res = await exports.default.fetch('https://example.com/stuff?foo=bar', {
method: 'PUT',
body: 'hello world!',
headers: {
'X-Test': 'true',
},
})
expect(res.status).toBe(200)
expect(await res.json()).toMatchInlineSnapshot(`
{
"body": "hello world!",
"headers": {
"content-length": "12",
"content-type": "text/plain;charset=UTF-8",
"x-test": "true",
},
"host": "example.com",
"hostname": "example.com",
"method": "PUT",
"path": "/stuff",
"url": "https://example.com/stuff?foo=bar",
}
`)
})
test('PATCH', async () => {
const res = await exports.default.fetch('https://example.com/stuff?foo=bar', {
method: 'PATCH',
body: 'hello world!',
headers: {
'X-Test': 'true',
},
})
expect(res.status).toBe(200)
expect(await res.json()).toMatchInlineSnapshot(`
{
"body": null,
"headers": {
"content-length": "12",
"content-type": "text/plain;charset=UTF-8",
"x-test": "true",
},
"host": "example.com",
"hostname": "example.com",
"method": "PATCH",
"path": "/stuff",
"url": "https://example.com/stuff?foo=bar",
}
`)
})
test('DELETE', async () => {
const res = await exports.default.fetch('https://example.com/stuff?foo=bar', {
method: 'DELETE',
body: 'hello world!',
headers: {
'X-Test': 'true',
},
})
expect(res.status).toBe(200)
expect(await res.json()).toMatchInlineSnapshot(`
{
"body": null,
"headers": {
"content-length": "12",
"content-type": "text/plain;charset=UTF-8",
"x-test": "true",
},
"host": "example.com",
"hostname": "example.com",
"method": "DELETE",
"path": "/stuff",
"url": "https://example.com/stuff?foo=bar",
}
`)
})
})
it(`Doesn't return body for HEAD`, async () => {
const res = await exports.default.fetch('https://example.com/stuff?foo=bar', {
method: 'HEAD',
headers: {
'X-Test': 'true',
},
})
expect(res.status).toBe(200)
expect(await res.text()).toMatchInlineSnapshot(`""`)
})
+5
View File
@@ -0,0 +1,5 @@
/** Get hostname from url in lower case */
export function getUrlHostname(url: string | URL): string {
const hostname = typeof url === 'string' ? new URL(url).hostname : url.hostname
return hostname.toLowerCase()
}