From d3b16f83a241a3a317c709c1cd8f4a08b0ff0481 Mon Sep 17 00:00:00 2001 From: yishideyun01 Date: Fri, 20 Dec 2024 01:30:25 +0000 Subject: [PATCH 1/3] feat(http-status): to generate a type error when generating the wrong response --- src/context.ts | 28 ++++++++++++++-------------- src/utils/http-status.ts | 3 ++- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/context.ts b/src/context.ts index 8447f2128..094b7cfe7 100644 --- a/src/context.ts +++ b/src/context.ts @@ -11,7 +11,7 @@ import type { } from './types' import type { ResponseHeader } from './utils/headers' import { HtmlEscapedCallbackPhase, resolveCallback } from './utils/html' -import type { RedirectStatusCode, StatusCode } from './utils/http-status' +import type { NoContentStatusCode, RedirectStatusCode, StatusCode } from './utils/http-status' import type { BaseMime } from './utils/mime' import type { InvalidJSONValue, @@ -121,7 +121,7 @@ interface BodyRespond extends NewResponse {} * * @interface TextRespond * @template T - The type of the text content. - * @template U - The type of the status code. + * @template U - The type of the status code without 204. * * @param {T} text - The text content to be included in the response. * @param {U} [status] - An optional status code for the response. @@ -130,12 +130,12 @@ interface BodyRespond extends NewResponse {} * @returns {Response & TypedResponse} - The response after rendering the text content, typed with the provided text and status code types. */ interface TextRespond { - ( + = Exclude>( text: T, status?: U, headers?: HeaderRecord ): Response & TypedResponse - (text: T, init?: ResponseInit): Response & + = Exclude>(text: T, init?: ResponseInit): Response & TypedResponse } @@ -144,7 +144,7 @@ interface TextRespond { * * @interface JSONRespond * @template T - The type of the JSON value or simplified unknown type. - * @template U - The type of the status code. + * @template U - The type of the status code without 204. * * @param {T} object - The JSON object to be included in the response. * @param {U} [status] - An optional status code for the response. @@ -155,7 +155,7 @@ interface TextRespond { interface JSONRespond { < T extends JSONValue | SimplifyDeepArray | InvalidJSONValue, - U extends StatusCode = StatusCode + U extends Exclude = Exclude >( object: T, status?: U, @@ -163,7 +163,7 @@ interface JSONRespond { ): JSONRespondReturn < T extends JSONValue | SimplifyDeepArray | InvalidJSONValue, - U extends StatusCode = StatusCode + U extends Exclude = Exclude >( object: T, init?: ResponseInit @@ -172,13 +172,13 @@ interface JSONRespond { /** * @template T - The type of the JSON value or simplified unknown type. - * @template U - The type of the status code. + * @template U - The type of the status code without 204. * * @returns {Response & TypedResponse extends JSONValue ? (JSONValue extends SimplifyDeepArray ? never : JSONParsed) : never, U, 'json'>} - The response after rendering the JSON object, typed with the provided object and status code types. */ type JSONRespondReturn< T extends JSONValue | SimplifyDeepArray | InvalidJSONValue, - U extends StatusCode + U extends Exclude > = Response & TypedResponse< SimplifyDeepArray extends JSONValue @@ -194,7 +194,7 @@ 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 status - (Optional) The HTTP status code for the response. + * @param status - (Optional) The HTTP status code without 204 for the response. * @param headers - (Optional) A record of headers to include in the response. * @param init - (Optional) The response initialization object. * @@ -203,7 +203,7 @@ type JSONRespondReturn< interface HTMLRespond { >( html: T, - status?: StatusCode, + status?: Exclude, headers?: HeaderRecord ): T extends string ? Response : Promise >(html: T, init?: ResponseInit): T extends string @@ -736,7 +736,7 @@ export class Context< */ text: TextRespond = ( text: string, - arg?: StatusCode | ResponseInit, + arg?: Exclude | ResponseInit, headers?: HeaderRecord ): ReturnType => { // If the header is empty, return Response immediately. @@ -769,7 +769,7 @@ export class Context< */ json: JSONRespond = < T extends JSONValue | SimplifyDeepArray | InvalidJSONValue, - U extends StatusCode = StatusCode + U extends Exclude = Exclude >( object: T, arg?: U | ResponseInit, @@ -786,7 +786,7 @@ export class Context< html: HTMLRespond = ( html: string | Promise, - arg?: StatusCode | ResponseInit, + arg?: Exclude | ResponseInit, headers?: HeaderRecord ): Response | Promise => { this.#preparedHeaders ??= {} diff --git a/src/utils/http-status.ts b/src/utils/http-status.ts index 6882394f4..a147bddb5 100644 --- a/src/utils/http-status.ts +++ b/src/utils/http-status.ts @@ -4,7 +4,8 @@ */ export type InfoStatusCode = 100 | 101 | 102 | 103 -export type SuccessStatusCode = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226 +export type NoContentStatusCode = 204 +export type SuccessStatusCode = 200 | 201 | 202 | 203 | NoContentStatusCode | 205 | 206 | 207 | 208 | 226 export type DeprecatedStatusCode = 305 | 306 export type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | DeprecatedStatusCode | 307 | 308 export type ClientErrorStatusCode = From e356b67d6a1156511110c5c3f5f5a1406a76c73b Mon Sep 17 00:00:00 2001 From: yishideyun01 Date: Fri, 20 Dec 2024 01:45:54 +0000 Subject: [PATCH 2/3] update --- src/context.ts | 14 +++++++++++--- src/types.test.ts | 40 ++++++++++++++++++++-------------------- src/utils/http-status.ts | 12 +++++++++++- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/context.ts b/src/context.ts index 094b7cfe7..85ccbc71c 100644 --- a/src/context.ts +++ b/src/context.ts @@ -130,13 +130,21 @@ interface BodyRespond extends NewResponse {} * @returns {Response & TypedResponse} - The response after rendering the text content, typed with the provided text and status code types. */ interface TextRespond { - = Exclude>( + < + T extends string, + U extends Exclude = Exclude + >( text: T, status?: U, headers?: HeaderRecord ): Response & TypedResponse - = Exclude>(text: T, init?: ResponseInit): Response & - TypedResponse + < + T extends string, + U extends Exclude = Exclude + >( + text: T, + init?: ResponseInit + ): Response & TypedResponse } /** diff --git a/src/types.test.ts b/src/types.test.ts index 421570abe..a717d4425 100644 --- a/src/types.test.ts +++ b/src/types.test.ts @@ -20,7 +20,7 @@ import type { ToSchema, TypedResponse, } from './types' -import type { StatusCode } from './utils/http-status' +import type { NoContentStatusCode, StatusCode } from './utils/http-status' import type { Equal, Expect } from './utils/types' import { validator } from './validator' @@ -96,7 +96,7 @@ describe('HandlerInterface', () => { message: string } outputFormat: 'json' - status: StatusCode + status: Exclude } } } @@ -135,7 +135,7 @@ describe('HandlerInterface', () => { message: string } outputFormat: 'json' - status: StatusCode + status: Exclude } } } @@ -163,7 +163,7 @@ describe('HandlerInterface', () => { } output: 'foo' outputFormat: 'text' - status: StatusCode + status: Exclude } } } @@ -192,7 +192,7 @@ describe('HandlerInterface', () => { } output: string outputFormat: 'text' - status: StatusCode + status: Exclude } } } @@ -217,7 +217,7 @@ describe('HandlerInterface', () => { } output: string outputFormat: 'text' - status: StatusCode + status: Exclude } } } & { @@ -271,7 +271,7 @@ describe('OnHandlerInterface', () => { success: boolean } outputFormat: 'json' - status: StatusCode + status: Exclude } } } @@ -376,7 +376,7 @@ describe('Support c.json(undefined)', () => { input: {} output: never outputFormat: 'json' - status: StatusCode + status: Exclude } } } @@ -460,7 +460,7 @@ describe('`json()`', () => { message: string } outputFormat: 'json' - status: StatusCode + status: Exclude } } } @@ -714,7 +714,7 @@ describe('MergeSchemaPath', () => { } output: {} outputFormat: 'json' - status: StatusCode + status: Exclude } } }, @@ -733,7 +733,7 @@ describe('MergeSchemaPath', () => { } output: {} outputFormat: 'json' - status: StatusCode + status: Exclude } } } @@ -902,7 +902,7 @@ describe('Different types using json()', () => { ng: boolean } outputFormat: 'json' - status: StatusCode + status: Exclude } | { input: {} @@ -910,7 +910,7 @@ describe('Different types using json()', () => { ok: boolean } outputFormat: 'json' - status: StatusCode + status: Exclude } | { input: {} @@ -918,7 +918,7 @@ describe('Different types using json()', () => { default: boolean } outputFormat: 'json' - status: StatusCode + status: Exclude } } } @@ -974,7 +974,7 @@ describe('Different types using json()', () => { default: boolean } outputFormat: 'json' - status: StatusCode + status: Exclude } } } @@ -1012,7 +1012,7 @@ describe('Different types using json()', () => { ng: boolean } outputFormat: 'json' - status: StatusCode + status: Exclude } | { input: {} @@ -1020,7 +1020,7 @@ describe('Different types using json()', () => { ok: boolean } outputFormat: 'json' - status: StatusCode + status: Exclude } | { input: {} @@ -1028,7 +1028,7 @@ describe('Different types using json()', () => { default: boolean } outputFormat: 'json' - status: StatusCode + status: Exclude } } } @@ -1084,7 +1084,7 @@ describe('Different types using json()', () => { default: boolean } outputFormat: 'json' - status: StatusCode + status: Exclude } } } @@ -1111,7 +1111,7 @@ describe('json() in an async handler', () => { ok: boolean } outputFormat: 'json' - status: StatusCode + status: Exclude } } } diff --git a/src/utils/http-status.ts b/src/utils/http-status.ts index a147bddb5..96678470b 100644 --- a/src/utils/http-status.ts +++ b/src/utils/http-status.ts @@ -5,7 +5,17 @@ export type InfoStatusCode = 100 | 101 | 102 | 103 export type NoContentStatusCode = 204 -export type SuccessStatusCode = 200 | 201 | 202 | 203 | NoContentStatusCode | 205 | 206 | 207 | 208 | 226 +export type SuccessStatusCode = + | 200 + | 201 + | 202 + | 203 + | NoContentStatusCode + | 205 + | 206 + | 207 + | 208 + | 226 export type DeprecatedStatusCode = 305 | 306 export type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | DeprecatedStatusCode | 307 | 308 export type ClientErrorStatusCode = From 75e084aeaf4399abb61b7a984c03731845276665 Mon Sep 17 00:00:00 2001 From: EdamAmex <121654029+EdamAme-x@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:10:12 +0900 Subject: [PATCH 3/3] Update http-status.ts --- src/utils/http-status.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/http-status.ts b/src/utils/http-status.ts index 96678470b..bc1079ebd 100644 --- a/src/utils/http-status.ts +++ b/src/utils/http-status.ts @@ -2,7 +2,7 @@ * @module * HTTP Status utility. */ - + export type InfoStatusCode = 100 | 101 | 102 | 103 export type NoContentStatusCode = 204 export type SuccessStatusCode =