Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(utils/color): support cloudflare workers (edge) #3752

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions runtime-tests/deno/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { assertEquals } from '@std/assert'
import { Context } from '../../src/context'
import { getColorEnabled } from '../../src/utils/color'

Deno.test('getColorEnabled() - With colors enabled', () => {
assertEquals(getColorEnabled(), true)
})

Deno.test('getColorEnabled() - With Deno.noColor set', () => {
const mockContext = new Context(new Request('http://localhost/'))

assertEquals(getColorEnabled(mockContext), true)
})
15 changes: 15 additions & 0 deletions runtime-tests/workerd/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,18 @@ describe('workerd with WebSocket', () => {
expect(closeHandler).toHaveBeenCalled()
})
})

describe('worked with getColorEnabled()', async () => {
const worker = await unstable_dev('./runtime-tests/workerd/index.ts', {
experimental: { disableExperimentalWarning: true },
})

it('Should return 200 response with the colorEnabled', async () => {
const res = await worker.fetch('/color')
await worker.stop()
expect(res.status).toBe(200)
expect(await res.json()).toEqual({
colorEnabled: false,
})
})
})
19 changes: 17 additions & 2 deletions runtime-tests/workerd/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { upgradeWebSocket } from '../../src/adapter/cloudflare-workers'
import { env, getRuntimeKey } from '../../src/helper/adapter'
import { Hono } from '../../src/hono'
import { getColorEnabled } from '../../src/utils/color'

const app = new Hono()
interface Env {
NO_COLOR: boolean
NAME: string
}

const app = new Hono<{
Bindings: Env
}>()

app.get('/', (c) => c.text(`Hello from ${getRuntimeKey()}`))

app.get('/env', (c) => {
const { NAME } = env<{ NAME: string }>(c)
const { NAME } = env(c)
return c.text(NAME)
})

Expand All @@ -22,4 +30,11 @@ app.get(
})
)

app.get('/color', (c) => {
c.env.NO_COLOR = true
return c.json({
colorEnabled: getColorEnabled(c),
})
})

export default app
12 changes: 7 additions & 5 deletions src/middleware/logger/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Logger Middleware for Hono.
*/

import type { Context } from '../../context'
import type { MiddlewareHandler } from '../../types'
import { getColorEnabled } from '../../utils/color'
import { getPath } from '../../utils/url'
Expand All @@ -26,8 +27,8 @@ const time = (start: number) => {
return humanize([delta < 1000 ? delta + 'ms' : Math.round(delta / 1000) + 's'])
}

const colorStatus = (status: number) => {
const colorEnabled = getColorEnabled()
const colorStatus = (status: number, c: Context) => {
const colorEnabled = getColorEnabled(c)
if (colorEnabled) {
switch ((status / 100) | 0) {
case 5: // red = error
Expand All @@ -53,13 +54,14 @@ function log(
prefix: string,
method: string,
path: string,
c: Context,
status: number = 0,
elapsed?: string
) {
const out =
prefix === LogPrefix.Incoming
? `${prefix} ${method} ${path}`
: `${prefix} ${method} ${path} ${colorStatus(status)} ${elapsed}`
: `${prefix} ${method} ${path} ${colorStatus(status, c)} ${elapsed}`
fn(out)
}

Expand All @@ -85,12 +87,12 @@ export const logger = (fn: PrintFunc = console.log): MiddlewareHandler => {

const path = getPath(c.req.raw)

log(fn, LogPrefix.Incoming, method, path)
log(fn, LogPrefix.Incoming, method, path, c)

const start = Date.now()

await next()

log(fn, LogPrefix.Outgoing, method, path, c.res.status, time(start))
log(fn, LogPrefix.Outgoing, method, path, c, c.res.status, time(start))
}
}
5 changes: 4 additions & 1 deletion src/utils/color.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Context } from '../context'
import { getColorEnabled } from './color'

describe('getColorEnabled() - With colors enabled', () => {
Expand All @@ -7,6 +8,8 @@ describe('getColorEnabled() - With colors enabled', () => {
})

describe('getColorEnabled() - With NO_COLOR environment variable set', () => {
const mockContext = new Context(new Request('http://localhost/'))

beforeAll(() => {
vi.stubEnv('NO_COLOR', '1')
})
Expand All @@ -16,6 +19,6 @@ describe('getColorEnabled() - With NO_COLOR environment variable set', () => {
})

it('should return false', async () => {
expect(getColorEnabled()).toBe(false)
expect(getColorEnabled(mockContext)).toBe(false)
})
})
19 changes: 11 additions & 8 deletions src/utils/color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,28 @@
* @module
* Color utility.
*/
import type { Context } from '../context'
import { getRuntimeKey, env } from '../helper/adapter'

/**
* Get whether color change on terminal is enabled or disabled.
* If `NO_COLOR` environment variable is set, this function returns `false`.
* @see {@link https://no-color.org/}
*
* @param {Context} c - the context of request
*
* @returns {boolean}
*/
export function getColorEnabled(): boolean {
export function getColorEnabled(c?: Context): boolean {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { process, Deno } = globalThis as any
const { Deno, process } = globalThis as any

const isNoColor =
typeof Deno?.noColor === 'boolean'
? (Deno.noColor as boolean)
: process !== undefined
? // eslint-disable-next-line no-unsafe-optional-chaining
'NO_COLOR' in process?.env
: false
getRuntimeKey() === 'deno'
? Deno?.noColor
: c
? env(c).NO_COLOR
: process?.env && 'NO_COLOR' in process.env

return !isNoColor
}
Loading