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

fix(context): update HTMLRespond type #3313

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
17 changes: 9 additions & 8 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
RouterRoute,
TypedResponse,
} from './types'
import type { HTMLInput } from './utils/html'
import { HtmlEscapedCallbackPhase, resolveCallback } from './utils/html'
import type { RedirectStatusCode, StatusCode } from './utils/http-status'
import type {
Expand Down Expand Up @@ -192,20 +193,20 @@ type JSONRespondReturn<
/**
* Interface representing a function that responds with HTML content.
*
* @param html - The HTML content to respond with, which can be a string or a Promise that resolves to a string.
* @param html - The HTML content to respond with, which can be anything with a `toString` method or a Promise that resolves to anything with a `toString` method.
* @param status - (Optional) The HTTP status code for the response.
* @param headers - (Optional) A record of headers to include in the response.
* @param init - (Optional) The response initialization object.
*
* @returns A Response object or a Promise that resolves to a Response object.
*/
interface HTMLRespond {
<T extends string | Promise<string>>(
<T extends HTMLInput | Promise<HTMLInput>>(
html: T,
status?: StatusCode,
headers?: HeaderRecord
): T extends string ? Response : Promise<Response>
<T extends string | Promise<string>>(html: T, init?: ResponseInit): T extends string
): T extends HTMLInput ? Response : Promise<Response>
<T extends HTMLInput | Promise<HTMLInput>>(html: T, init?: ResponseInit): T extends HTMLInput
? Response
: Promise<Response>
}
Expand Down Expand Up @@ -836,7 +837,7 @@ export class Context<
}

html: HTMLRespond = (
html: string | Promise<string>,
html: HTMLInput | Promise<HTMLInput>,
arg?: StatusCode | ResponseInit,
headers?: HeaderRecord
): Response | Promise<Response> => {
Expand All @@ -845,10 +846,10 @@ export class Context<

if (typeof html === 'object') {
if (!(html instanceof Promise)) {
html = (html as string).toString() // HtmlEscapedString object to string
html = html.toString() // HtmlEscapedString object to string
}
if ((html as string | Promise<string>) instanceof Promise) {
return (html as unknown as Promise<string>)
if (html instanceof Promise) {
return html
.then((html) => resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}))
.then((html) => {
return typeof arg === 'number'
Expand Down
15 changes: 12 additions & 3 deletions src/utils/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ export type HtmlEscaped = {
}
export type HtmlEscapedString = string & HtmlEscaped

/**
* Anything that has a `toString` method.
*/
type HasToString = {
toString(): string
}

export type HTMLInput = string | HtmlEscapedString | HasToString

/**
* StringBuffer contains string and Promise<string> alternately
* The length of the array will be odd, the odd numbered element will be a string,
Expand Down Expand Up @@ -140,20 +149,20 @@ export const resolveCallbackSync = (str: string | HtmlEscapedString): string =>
}

export const resolveCallback = async (
str: string | HtmlEscapedString,
str: HTMLInput,
phase: (typeof HtmlEscapedCallbackPhase)[keyof typeof HtmlEscapedCallbackPhase],
preserveCallbacks: boolean,
context: object,
buffer?: [string]
): Promise<string> => {
const callbacks = (str as HtmlEscapedString).callbacks as HtmlEscapedCallback[]
if (!callbacks?.length) {
return Promise.resolve(str)
return Promise.resolve(str.toString())
}
if (buffer) {
buffer[0] += str
} else {
buffer = [str]
buffer = [str.toString()]
}

const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then((res) =>
Expand Down
Loading