Skip to content

Instantly share code, notes, and snippets.

@shlroland
Last active February 2, 2025 04:35
Show Gist options
  • Select an option

  • Save shlroland/550c29ed23b50d40387fb044092a483f to your computer and use it in GitHub Desktop.

Select an option

Save shlroland/550c29ed23b50d40387fb044092a483f to your computer and use it in GitHub Desktop.
hono superjson
// server
import type { Context, TypedResponse } from 'hono'
import type { StatusCode } from 'hono/utils/http-status'
import type { InvalidJSONValue, JSONParsed, JSONValue, SimplifyDeepArray } from 'hono/utils/types'
import superjson from 'superjson'
type JSONRespondReturn<
T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue,
U extends StatusCode,
> =
Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T> : never, U, 'json'>
type HeaderRecord = Record<string, string | string[]>
function getSuperjsonResponse<T = object>(c: Context, object: T, arg?: StatusCode | RequestInit, headers?: HeaderRecord) {
const body = superjson.stringify(object)
c.header('content-type', 'application/json; charset=UTF-8')
c.header('x-superjson', 'true')
return typeof arg === 'number' ? c.newResponse(body, arg, headers) : c.newResponse(body, arg)
}
export function jsonS<
C extends Context,
T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue,
U extends StatusCode = StatusCode,
>(c: C, object: T, arg?: StatusCode | RequestInit, headers?: HeaderRecord):
JSONRespondReturn<T, U> {
const response
= typeof arg === 'number'
? getSuperjsonResponse(c, object, arg, headers)
: getSuperjsonResponse(c, object, arg)
return response as any
}
// client
import superjson from 'superjson'
export type Callback = (opts: CallbackOptions) => unknown
interface CallbackOptions {
path: string[]
args: any[]
}
// export const hono = hc<AppType>('/')
function createProxy(callback: Callback, path: string[]) {
const proxy: unknown = new Proxy(() => { }, {
get(_obj, key) {
if (typeof key !== 'string')
return undefined
return createProxy(callback, [...path, key])
},
apply(_1, _2, args) {
return callback({
path,
args,
})
},
})
return proxy
}
export function hcs<T extends Hono<any, any, any>>(baseUrl: string, options?: ClientRequestOptions) {
return createProxy(async ({ path, args }) => {
let client: any = hc(baseUrl, options)
for (const part of path) {
client = client[part]
}
const res: Response = await client(...args)
if (res.headers.get('X-Superjson') === 'true') {
res.json = async () => {
const text = await res.text()
return superjson.parse(text)
}
}
return res
}, []) as ReturnType<typeof hc<T>>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment