Skip to content
Draft
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
216 changes: 123 additions & 93 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,9 +445,11 @@
* })
* ```
*/
render: Renderer = (...args) => {
this.#renderer ??= (content: string | Promise<string>) => this.html(content)
return this.#renderer(...args)
get render(): Renderer {
return (...args) => {
this.#renderer ??= (content: string | Promise<string>) => this.html(content)
return this.#renderer(...args)
}
}

/**
Expand All @@ -456,20 +458,24 @@
* @param layout - The layout to set.
* @returns The layout function.
*/
setLayout = (
layout: Layout<PropsForRenderer & { Layout: Layout }>
): Layout<
PropsForRenderer & {
Layout: Layout
}
> => (this.#layout = layout)
get setLayout() {

Check failure on line 461 in src/context.ts

View workflow job for this annotation

GitHub Actions / Checking if it's valid for JSR

missing explicit return type in the public API
return (
layout: Layout<PropsForRenderer & { Layout: Layout }>
): Layout<
PropsForRenderer & {
Layout: Layout
}
> => (this.#layout = layout)
}

/**
* Gets the current layout for the response.
*
* @returns The current layout function.
*/
getLayout = (): Layout<PropsForRenderer & { Layout: Layout }> | undefined => this.#layout
get getLayout() {

Check failure on line 476 in src/context.ts

View workflow job for this annotation

GitHub Actions / Checking if it's valid for JSR

missing explicit return type in the public API
return (): Layout<PropsForRenderer & { Layout: Layout }> | undefined => this.#layout
}

/**
* `.setRenderer()` can set the layout in the custom middleware.
Expand All @@ -492,8 +498,10 @@
* })
* ```
*/
setRenderer = (renderer: Renderer): void => {
this.#renderer = renderer
get setRenderer() {

Check failure on line 501 in src/context.ts

View workflow job for this annotation

GitHub Actions / Checking if it's valid for JSR

missing explicit return type in the public API
return (renderer: Renderer): void => {
this.#renderer = renderer
}
}

/**
Expand All @@ -512,22 +520,26 @@
* })
* ```
*/
header: SetHeaders = (name, value, options): void => {
if (this.finalized) {
this.#res = createResponseInstance((this.#res as Response).body, this.#res)
}
const headers = this.#res ? this.#res.headers : (this.#preparedHeaders ??= new Headers())
if (value === undefined) {
headers.delete(name)
} else if (options?.append) {
headers.append(name, value)
} else {
headers.set(name, value)
get header(): SetHeaders {
return (name, value, options): void => {
if (this.finalized) {
this.#res = createResponseInstance((this.#res as Response).body, this.#res)
}
const headers = this.#res ? this.#res.headers : (this.#preparedHeaders ??= new Headers())
if (value === undefined) {
headers.delete(name)
} else if (options?.append) {
headers.append(name, value)
} else {
headers.set(name, value)
}
}
}

status = (status: StatusCode): void => {
this.#status = status
get status(): (status: StatusCode) => void {
return (status: StatusCode): void => {
this.#status = status
}
}

/**
Expand All @@ -543,16 +555,18 @@
* })
* ```
*/
set: Set<
get set(): Set<
IsAny<E> extends true
? {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Variables: ContextVariableMap & Record<string, any>
}
: E
> = (key: string, value: unknown) => {
this.#var ??= new Map()
this.#var.set(key, value)
> {
return (key: string, value: unknown) => {
this.#var ??= new Map()
this.#var.set(key, value)
}
}

/**
Expand All @@ -568,15 +582,17 @@
* })
* ```
*/
get: Get<
get get(): Get<
IsAny<E> extends true
? {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Variables: ContextVariableMap & Record<string, any>
}
: E
> = (key: string) => {
return this.#var ? this.#var.get(key) : undefined
> {
return (key: string) => {
return this.#var ? this.#var.get(key) : undefined
}
}

/**
Expand Down Expand Up @@ -638,7 +654,9 @@
return createResponseInstance(data, { status, headers: responseHeaders })
}

newResponse: NewResponse = (...args) => this.#newResponse(...(args as Parameters<NewResponse>))
get newResponse(): NewResponse {
return (...args) => this.#newResponse(...(args as Parameters<NewResponse>))
}

/**
* `.body()` can return the HTTP response.
Expand All @@ -661,11 +679,13 @@
* })
* ```
*/
body: BodyRespond = (
data: Data | null,
arg?: StatusCode | RequestInit,
headers?: HeaderRecord
): ReturnType<BodyRespond> => this.#newResponse(data, arg, headers) as ReturnType<BodyRespond>
get body(): BodyRespond {
return (
data: Data | null,
arg?: StatusCode | RequestInit,
headers?: HeaderRecord
): ReturnType<BodyRespond> => this.#newResponse(data, arg, headers) as ReturnType<BodyRespond>
}

#useFastPath(): boolean {
return !this.#preparedHeaders && !this.#status && !this.finalized
Expand All @@ -683,18 +703,20 @@
* })
* ```
*/
text: TextRespond = (
text: string,
arg?: ContentfulStatusCode | ResponseOrInit,
headers?: HeaderRecord
): ReturnType<TextRespond> => {
return this.#useFastPath() && !arg && !headers
? (createResponseInstance(text) as ReturnType<TextRespond>)
: (this.#newResponse(
text,
arg,
setDefaultContentType(TEXT_PLAIN, headers)
) as ReturnType<TextRespond>)
get text(): TextRespond {
return (
text: string,
arg?: ContentfulStatusCode | ResponseOrInit,
headers?: HeaderRecord
): ReturnType<TextRespond> => {
return this.#useFastPath() && !arg && !headers
? (createResponseInstance(text) as ReturnType<TextRespond>)
: (this.#newResponse(
text,
arg,
setDefaultContentType(TEXT_PLAIN, headers)
) as ReturnType<TextRespond>)
}
}

/**
Expand All @@ -709,35 +731,39 @@
* })
* ```
*/
json: JSONRespond = <
T extends JSONValue | {} | InvalidJSONValue,
U extends ContentfulStatusCode = ContentfulStatusCode,
>(
object: T,
arg?: U | ResponseOrInit<U>,
headers?: HeaderRecord
): JSONRespondReturn<T, U> => {
return (
this.#useFastPath() && !arg && !headers
? Response.json(object)
: this.#newResponse(
JSON.stringify(object),
arg,
setDefaultContentType('application/json', headers)
)
) as JSONRespondReturn<T, U>
get json(): JSONRespond {
return <
T extends JSONValue | {} | InvalidJSONValue,
U extends ContentfulStatusCode = ContentfulStatusCode,
>(
object: T,
arg?: U | ResponseOrInit<U>,
headers?: HeaderRecord
): JSONRespondReturn<T, U> => {
return (
this.#useFastPath() && !arg && !headers
? Response.json(object)
: this.#newResponse(
JSON.stringify(object),
arg,
setDefaultContentType('application/json', headers)
)
) as JSONRespondReturn<T, U>
}
}

html: HTMLRespond = (
html: string | Promise<string>,
arg?: ContentfulStatusCode | ResponseOrInit<ContentfulStatusCode>,
headers?: HeaderRecord
): Response | Promise<Response> => {
const res = (html: string) =>
this.#newResponse(html, arg, setDefaultContentType('text/html; charset=UTF-8', headers))
return typeof html === 'object'
? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res)
: res(html)
get html(): HTMLRespond {
return (
html: string | Promise<string>,
arg?: ContentfulStatusCode | ResponseOrInit<ContentfulStatusCode>,
headers?: HeaderRecord
): Response | Promise<Response> => {
const res = (html: string) =>
this.#newResponse(html, arg, setDefaultContentType('text/html; charset=UTF-8', headers))
return typeof html === 'object'
? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res)
: res(html)
}
}

/**
Expand All @@ -755,18 +781,20 @@
* })
* ```
*/
redirect = <T extends RedirectStatusCode = 302>(
location: string | URL,
status?: T
): Response & TypedResponse<undefined, T, 'redirect'> => {
const locationString = String(location)
this.header(
'Location',
// Multibyes should be encoded
// eslint-disable-next-line no-control-regex
!/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
)
return this.newResponse(null, status ?? 302) as any
get redirect() {

Check failure on line 784 in src/context.ts

View workflow job for this annotation

GitHub Actions / Checking if it's valid for JSR

missing explicit return type in the public API
return <T extends RedirectStatusCode = 302>(
location: string | URL,
status?: T
): Response & TypedResponse<undefined, T, 'redirect'> => {
const locationString = String(location)
this.header(
'Location',
// Multibyes should be encoded
// eslint-disable-next-line no-control-regex
!/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
)
return this.newResponse(null, status ?? 302) as any
}
}

/**
Expand All @@ -781,8 +809,10 @@
* })
* ```
*/
notFound = (): ReturnType<NotFoundHandler> => {
this.#notFoundHandler ??= () => createResponseInstance()
return this.#notFoundHandler(this)
get notFound() {

Check failure on line 812 in src/context.ts

View workflow job for this annotation

GitHub Actions / Checking if it's valid for JSR

missing explicit return type in the public API
return (): ReturnType<NotFoundHandler> => {
this.#notFoundHandler ??= () => createResponseInstance()
return this.#notFoundHandler(this)
}
}
}
Loading