2023-01-31 22:36:48 +01:00
|
|
|
import type {
|
|
|
|
Input,
|
2023-02-13 22:21:30 +01:00
|
|
|
InputToDataByTarget,
|
2023-01-31 22:36:48 +01:00
|
|
|
ParamKeys,
|
|
|
|
ParamKeyToRecord,
|
|
|
|
RemoveQuestion,
|
|
|
|
UndefinedIfHavingQuestion,
|
2023-02-13 22:21:30 +01:00
|
|
|
ValidationTargets,
|
2023-01-31 22:36:48 +01:00
|
|
|
} from './types.ts'
|
2022-07-12 16:25:47 +02:00
|
|
|
import { parseBody } from './utils/body.ts'
|
2022-09-20 15:01:03 +02:00
|
|
|
import type { BodyData } from './utils/body.ts'
|
2022-07-10 17:17:29 +02:00
|
|
|
import type { Cookie } from './utils/cookie.ts'
|
|
|
|
import { parse } from './utils/cookie.ts'
|
2023-01-22 05:32:33 +01:00
|
|
|
import type { UnionToIntersection } from './utils/types.ts'
|
2023-01-17 10:30:02 +01:00
|
|
|
import { getQueryStringFromURL, getQueryParam, getQueryParams } from './utils/url.ts'
|
2022-07-10 17:17:29 +02:00
|
|
|
|
2023-01-31 22:36:48 +01:00
|
|
|
export class HonoRequest<P extends string = '/', I extends Input = {}> {
|
2022-12-20 23:05:00 +01:00
|
|
|
raw: Request
|
2022-07-02 08:09:45 +02:00
|
|
|
|
2022-12-20 23:05:00 +01:00
|
|
|
private paramData: Record<string, string> | undefined
|
2023-02-13 22:21:30 +01:00
|
|
|
private validatedData: { [K in keyof ValidationTargets]?: {} }
|
2022-12-20 23:05:00 +01:00
|
|
|
|
2023-02-13 13:40:51 +01:00
|
|
|
constructor(request: Request, paramData?: Record<string, string> | undefined) {
|
2022-12-20 23:05:00 +01:00
|
|
|
this.raw = request
|
|
|
|
this.paramData = paramData
|
2023-01-22 23:47:29 +01:00
|
|
|
this.validatedData = {}
|
2022-07-02 08:09:45 +02:00
|
|
|
}
|
|
|
|
|
2023-01-31 22:36:48 +01:00
|
|
|
param(key: RemoveQuestion<ParamKeys<P>>): UndefinedIfHavingQuestion<ParamKeys<P>>
|
|
|
|
param(): UnionToIntersection<ParamKeyToRecord<ParamKeys<P>>>
|
2023-01-22 06:28:13 +01:00
|
|
|
param(key?: string): unknown {
|
2022-07-02 08:09:45 +02:00
|
|
|
if (this.paramData) {
|
|
|
|
if (key) {
|
2022-12-13 17:07:07 +01:00
|
|
|
const param = this.paramData[key]
|
2023-01-22 05:59:31 +01:00
|
|
|
return param ? (/\%/.test(param) ? decodeURIComponent(param) : param) : undefined
|
2022-07-02 08:09:45 +02:00
|
|
|
} else {
|
2022-11-14 01:10:03 +01:00
|
|
|
const decoded: Record<string, string> = {}
|
|
|
|
|
|
|
|
for (const [key, value] of Object.entries(this.paramData)) {
|
2022-12-20 23:05:00 +01:00
|
|
|
if (value && typeof value === 'string') {
|
2023-01-22 05:59:31 +01:00
|
|
|
decoded[key] = /\%/.test(value) ? decodeURIComponent(value) : value
|
2022-12-13 17:07:07 +01:00
|
|
|
}
|
2022-11-14 01:10:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return decoded
|
2022-07-02 08:09:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return null
|
2022-12-20 23:05:00 +01:00
|
|
|
}
|
2022-07-02 08:09:45 +02:00
|
|
|
|
2023-02-13 13:40:51 +01:00
|
|
|
query(key: string): string | undefined
|
2022-12-20 23:05:00 +01:00
|
|
|
query(): Record<string, string>
|
|
|
|
query(key?: string) {
|
2023-02-13 13:40:51 +01:00
|
|
|
const queryString = getQueryStringFromURL(this.url)
|
|
|
|
const result = getQueryParam(queryString, key)
|
|
|
|
if (result === null) return undefined
|
|
|
|
return result
|
2022-12-20 23:05:00 +01:00
|
|
|
}
|
2022-07-02 08:09:45 +02:00
|
|
|
|
2023-02-13 13:40:51 +01:00
|
|
|
queries(key: string): string[] | undefined
|
2022-12-20 23:05:00 +01:00
|
|
|
queries(): Record<string, string[]>
|
|
|
|
queries(key?: string) {
|
2023-02-13 13:40:51 +01:00
|
|
|
const queryString = getQueryStringFromURL(this.url)
|
|
|
|
const result = getQueryParams(queryString, key)
|
|
|
|
if (result === null) return undefined
|
|
|
|
return result
|
2022-12-20 23:05:00 +01:00
|
|
|
}
|
|
|
|
|
2023-02-12 22:47:05 +01:00
|
|
|
header(name: string): string | undefined
|
2022-12-20 23:05:00 +01:00
|
|
|
header(): Record<string, string>
|
|
|
|
header(name?: string) {
|
2023-02-01 16:25:58 +01:00
|
|
|
const headerData: Record<string, string> = {}
|
|
|
|
this.raw.headers.forEach((value, key) => {
|
|
|
|
headerData[key] = value
|
|
|
|
})
|
2023-02-12 22:47:05 +01:00
|
|
|
if (!name) {
|
2023-02-01 16:25:58 +01:00
|
|
|
return headerData
|
2022-12-20 23:05:00 +01:00
|
|
|
}
|
2023-02-12 22:47:05 +01:00
|
|
|
return headerData[name.toLowerCase()] || undefined
|
2022-12-20 23:05:00 +01:00
|
|
|
}
|
2022-07-10 17:17:29 +02:00
|
|
|
|
2022-12-20 23:05:00 +01:00
|
|
|
cookie(key: string): string | undefined
|
|
|
|
cookie(): Cookie
|
|
|
|
cookie(key?: string) {
|
|
|
|
const cookie = this.raw.headers.get('Cookie')
|
|
|
|
if (!cookie) return
|
2022-07-10 17:17:29 +02:00
|
|
|
const obj = parse(cookie)
|
|
|
|
if (key) {
|
|
|
|
const value = obj[key]
|
|
|
|
return value
|
|
|
|
} else {
|
|
|
|
return obj
|
|
|
|
}
|
2022-12-20 23:05:00 +01:00
|
|
|
}
|
2022-07-12 16:25:47 +02:00
|
|
|
|
2023-01-03 00:25:21 +01:00
|
|
|
async parseBody(): Promise<BodyData> {
|
2023-02-01 16:25:58 +01:00
|
|
|
return await parseBody(this.raw)
|
2022-12-20 23:05:00 +01:00
|
|
|
}
|
2022-09-13 00:54:06 +02:00
|
|
|
|
2023-02-01 16:25:58 +01:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
async json<T = any>(): Promise<T> {
|
|
|
|
return this.raw.json() as T
|
2022-12-20 23:05:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
async text() {
|
|
|
|
return this.raw.text()
|
|
|
|
}
|
|
|
|
|
|
|
|
async arrayBuffer() {
|
|
|
|
return this.raw.arrayBuffer()
|
|
|
|
}
|
|
|
|
|
|
|
|
async blob() {
|
|
|
|
return this.raw.blob()
|
|
|
|
}
|
|
|
|
|
|
|
|
async formData() {
|
|
|
|
return this.raw.formData()
|
|
|
|
}
|
2022-09-20 03:11:34 +02:00
|
|
|
|
2023-02-13 22:21:30 +01:00
|
|
|
addValidatedData(target: keyof ValidationTargets, data: {}) {
|
|
|
|
this.validatedData[target] = data
|
2023-02-01 14:02:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
valid<
|
2023-02-13 22:21:30 +01:00
|
|
|
T extends keyof ValidationTargets = I extends Record<infer R, unknown>
|
|
|
|
? R extends keyof ValidationTargets
|
2023-02-01 14:02:09 +01:00
|
|
|
? R
|
|
|
|
: never
|
|
|
|
: never
|
2023-02-13 22:21:30 +01:00
|
|
|
>(target: T): InputToDataByTarget<I, T>
|
2023-02-02 00:06:19 +01:00
|
|
|
valid(): never
|
2023-02-13 22:21:30 +01:00
|
|
|
valid(target?: keyof ValidationTargets) {
|
|
|
|
if (target) {
|
|
|
|
return this.validatedData[target] as unknown
|
2022-09-20 03:11:34 +02:00
|
|
|
}
|
2022-12-20 23:05:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
get url() {
|
|
|
|
return this.raw.url
|
|
|
|
}
|
|
|
|
get method() {
|
|
|
|
return this.raw.method
|
|
|
|
}
|
|
|
|
get headers() {
|
|
|
|
return this.raw.headers
|
|
|
|
}
|
|
|
|
get redirect() {
|
|
|
|
return this.raw.redirect
|
|
|
|
}
|
|
|
|
get body() {
|
|
|
|
return this.raw.body
|
|
|
|
}
|
|
|
|
get bodyUsed() {
|
|
|
|
return this.raw.bodyUsed
|
|
|
|
}
|
|
|
|
get cache() {
|
|
|
|
return this.raw.cache
|
|
|
|
}
|
|
|
|
get credentials() {
|
|
|
|
return this.raw.credentials
|
|
|
|
}
|
|
|
|
get integrity() {
|
|
|
|
return this.raw.integrity
|
|
|
|
}
|
|
|
|
get keepalive() {
|
|
|
|
return this.raw.keepalive
|
|
|
|
}
|
|
|
|
get mode() {
|
|
|
|
return this.raw.mode
|
|
|
|
}
|
|
|
|
get referrer() {
|
|
|
|
return this.raw.referrer
|
|
|
|
}
|
|
|
|
get refererPolicy() {
|
|
|
|
return this.raw.referrerPolicy
|
|
|
|
}
|
|
|
|
get signal() {
|
|
|
|
return this.raw.signal
|
|
|
|
}
|
2022-07-02 08:09:45 +02:00
|
|
|
}
|