2022-12-28 02:25:48 +00:00
|
|
|
import type { InputToData } from './types.ts'
|
2022-07-12 14:25:47 +00:00
|
|
|
import { parseBody } from './utils/body.ts'
|
2022-09-20 13:01:03 +00:00
|
|
|
import type { BodyData } from './utils/body.ts'
|
2022-07-10 15:17:29 +00:00
|
|
|
import type { Cookie } from './utils/cookie.ts'
|
|
|
|
import { parse } from './utils/cookie.ts'
|
2022-09-05 10:08:10 +00:00
|
|
|
import { getQueryStringFromURL } from './utils/url.ts'
|
2022-07-10 15:17:29 +00:00
|
|
|
|
2022-12-28 02:25:48 +00:00
|
|
|
export class HonoRequest<ParamKey extends string = string, Input = unknown> {
|
2022-12-20 22:05:00 +00:00
|
|
|
raw: Request
|
2022-07-02 06:09:45 +00:00
|
|
|
|
2022-12-20 22:05:00 +00:00
|
|
|
private paramData: Record<string, string> | undefined
|
|
|
|
private headerData: Record<string, string> | undefined
|
|
|
|
private queryData: Record<string, string> | undefined
|
|
|
|
private bodyData: BodyData | undefined
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
private jsonData: Promise<any> | undefined
|
2022-12-28 02:25:48 +00:00
|
|
|
private data: InputToData<Input>
|
2022-12-20 22:05:00 +00:00
|
|
|
|
|
|
|
constructor(request: Request, paramData?: Record<string, string> | undefined) {
|
|
|
|
this.raw = request
|
|
|
|
this.paramData = paramData
|
2022-12-28 02:25:48 +00:00
|
|
|
this.data = {} as InputToData<Input>
|
2022-07-02 06:09:45 +00:00
|
|
|
}
|
|
|
|
|
2022-12-20 22:05:00 +00:00
|
|
|
param(key: ParamKey): string
|
|
|
|
param(): Record<ParamKey, string>
|
|
|
|
param(key?: string) {
|
2022-07-02 06:09:45 +00:00
|
|
|
if (this.paramData) {
|
|
|
|
if (key) {
|
2022-12-13 16:07:07 +00:00
|
|
|
const param = this.paramData[key]
|
|
|
|
return param ? decodeURIComponent(param) : undefined
|
2022-07-02 06:09:45 +00:00
|
|
|
} else {
|
2022-11-14 00:10:03 +00:00
|
|
|
const decoded: Record<string, string> = {}
|
|
|
|
|
|
|
|
for (const [key, value] of Object.entries(this.paramData)) {
|
2022-12-20 22:05:00 +00:00
|
|
|
if (value && typeof value === 'string') {
|
2022-12-13 16:07:07 +00:00
|
|
|
decoded[key] = decodeURIComponent(value)
|
|
|
|
}
|
2022-11-14 00:10:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return decoded
|
2022-07-02 06:09:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return null
|
2022-12-20 22:05:00 +00:00
|
|
|
}
|
2022-07-02 06:09:45 +00:00
|
|
|
|
2022-12-20 22:05:00 +00:00
|
|
|
query(key: string): string
|
|
|
|
query(): Record<string, string>
|
|
|
|
query(key?: string) {
|
2022-09-05 10:08:10 +00:00
|
|
|
const queryString = getQueryStringFromURL(this.url)
|
|
|
|
const searchParams = new URLSearchParams(queryString)
|
2022-09-12 22:54:06 +00:00
|
|
|
if (!this.queryData) {
|
|
|
|
this.queryData = {}
|
2022-09-05 10:08:10 +00:00
|
|
|
for (const key of searchParams.keys()) {
|
2022-09-12 22:54:06 +00:00
|
|
|
this.queryData[key] = searchParams.get(key) || ''
|
2022-07-02 06:09:45 +00:00
|
|
|
}
|
2022-09-12 22:54:06 +00:00
|
|
|
}
|
|
|
|
if (key) {
|
|
|
|
return this.queryData[key]
|
|
|
|
} else {
|
|
|
|
return this.queryData
|
2022-07-02 06:09:45 +00:00
|
|
|
}
|
2022-12-20 22:05:00 +00:00
|
|
|
}
|
2022-07-02 06:09:45 +00:00
|
|
|
|
2022-12-20 22:05:00 +00:00
|
|
|
queries(key: string): string[]
|
|
|
|
queries(): Record<string, string[]>
|
|
|
|
queries(key?: string) {
|
2022-09-05 10:08:10 +00:00
|
|
|
const queryString = getQueryStringFromURL(this.url)
|
|
|
|
const searchParams = new URLSearchParams(queryString)
|
2022-07-02 06:09:45 +00:00
|
|
|
if (key) {
|
2022-09-05 10:08:10 +00:00
|
|
|
return searchParams.getAll(key)
|
2022-07-02 06:09:45 +00:00
|
|
|
} else {
|
|
|
|
const result: Record<string, string[]> = {}
|
2022-09-05 10:08:10 +00:00
|
|
|
for (const key of searchParams.keys()) {
|
|
|
|
result[key] = searchParams.getAll(key)
|
2022-07-02 06:09:45 +00:00
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
2022-12-20 22:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
header(name: string): string
|
|
|
|
header(): Record<string, string>
|
|
|
|
header(name?: string) {
|
|
|
|
if (!this.headerData) {
|
|
|
|
this.headerData = {}
|
|
|
|
this.raw.headers.forEach((value, key) => {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
|
|
this.headerData![key] = value
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if (name) {
|
|
|
|
return this.headerData[name.toLowerCase()]
|
|
|
|
} else {
|
|
|
|
return this.headerData
|
|
|
|
}
|
|
|
|
}
|
2022-07-10 15:17:29 +00:00
|
|
|
|
2022-12-20 22:05:00 +00:00
|
|
|
cookie(key: string): string | undefined
|
|
|
|
cookie(): Cookie
|
|
|
|
cookie(key?: string) {
|
|
|
|
const cookie = this.raw.headers.get('Cookie')
|
|
|
|
if (!cookie) return
|
2022-07-10 15:17:29 +00:00
|
|
|
const obj = parse(cookie)
|
|
|
|
if (key) {
|
|
|
|
const value = obj[key]
|
|
|
|
return value
|
|
|
|
} else {
|
|
|
|
return obj
|
|
|
|
}
|
2022-12-20 22:05:00 +00:00
|
|
|
}
|
2022-07-12 14:25:47 +00:00
|
|
|
|
2022-12-20 22:05:00 +00:00
|
|
|
async parseBody<BodyType extends BodyData>(): Promise<BodyType> {
|
2022-09-12 22:54:06 +00:00
|
|
|
// Cache the parsed body
|
2022-09-20 13:01:03 +00:00
|
|
|
let body: BodyType
|
2022-09-12 22:54:06 +00:00
|
|
|
if (!this.bodyData) {
|
2022-12-20 22:05:00 +00:00
|
|
|
body = await parseBody<BodyType>(this.raw)
|
2022-09-12 22:54:06 +00:00
|
|
|
this.bodyData = body
|
2022-08-25 00:25:11 +00:00
|
|
|
} else {
|
2022-09-20 13:01:03 +00:00
|
|
|
body = this.bodyData as BodyType
|
2022-07-12 14:25:47 +00:00
|
|
|
}
|
2022-08-25 00:25:11 +00:00
|
|
|
return body
|
2022-12-20 22:05:00 +00:00
|
|
|
}
|
2022-09-12 22:54:06 +00:00
|
|
|
|
2022-12-20 22:05:00 +00:00
|
|
|
async json<JSONData = unknown>() {
|
2022-09-12 22:54:06 +00:00
|
|
|
// Cache the JSON body
|
2022-12-20 22:05:00 +00:00
|
|
|
let jsonData: Promise<Partial<JSONData>>
|
2022-09-12 22:54:06 +00:00
|
|
|
if (!this.jsonData) {
|
2022-12-20 22:05:00 +00:00
|
|
|
jsonData = this.raw.json()
|
2022-09-12 22:54:06 +00:00
|
|
|
this.jsonData = jsonData
|
|
|
|
} else {
|
|
|
|
jsonData = this.jsonData
|
|
|
|
}
|
|
|
|
return jsonData
|
2022-12-20 22:05:00 +00: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 01:11:34 +00:00
|
|
|
|
2022-12-20 22:05:00 +00:00
|
|
|
valid(data?: unknown) {
|
2022-09-20 01:11:34 +00:00
|
|
|
if (!this.data) {
|
2022-12-28 02:25:48 +00:00
|
|
|
this.data = {} as InputToData<Input>
|
2022-09-20 01:11:34 +00:00
|
|
|
}
|
2022-12-10 07:37:14 +00:00
|
|
|
if (data) {
|
2022-12-28 02:25:48 +00:00
|
|
|
this.data = data as InputToData<Input>
|
2022-09-20 01:11:34 +00:00
|
|
|
}
|
|
|
|
return this.data
|
2022-12-20 22:05:00 +00: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 06:09:45 +00:00
|
|
|
}
|