From aa099be4ff35085c7e90ebe5eeeebe851be47fdf Mon Sep 17 00:00:00 2001 From: Kholstinin Dmitry Date: Sun, 10 Aug 2025 22:34:50 +0500 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=A4=96=20Merge=20PR=20#73338=20[webpa?= =?UTF-8?q?ck-hot-middleware]=20statsOptions=20typing=20by=20@kholstinin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: d.kholstinin --- types/webpack-hot-middleware/index.d.ts | 1 + types/webpack-hot-middleware/webpack-hot-middleware-tests.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/types/webpack-hot-middleware/index.d.ts b/types/webpack-hot-middleware/index.d.ts index 3728c70417a1a6..f85ad417cda924 100644 --- a/types/webpack-hot-middleware/index.d.ts +++ b/types/webpack-hot-middleware/index.d.ts @@ -31,6 +31,7 @@ declare namespace WebpackHotMiddleware { log?: false | Logger | undefined; path?: string | undefined; heartbeat?: number | undefined; + statsOptions?: webpack.StatsOptions; } type Logger = (message?: any, ...optionalParams: any[]) => void; diff --git a/types/webpack-hot-middleware/webpack-hot-middleware-tests.ts b/types/webpack-hot-middleware/webpack-hot-middleware-tests.ts index 798d388ebcfb2b..44f4f2f35da489 100644 --- a/types/webpack-hot-middleware/webpack-hot-middleware-tests.ts +++ b/types/webpack-hot-middleware/webpack-hot-middleware-tests.ts @@ -7,6 +7,7 @@ const compiler = webpack({})!; let webpackHotMiddlewareInstance = webpackHotMiddleware(compiler); webpackHotMiddlewareInstance = webpackHotMiddleware(compiler, { + statsOptions: { cached: false }, log: console.log.bind(console), path: "/__what", heartbeat: 2000, From a3e120322e4ff5b5c6aa19876c5f15d977dc97ef Mon Sep 17 00:00:00 2001 From: Alexander Brandon Coles Date: Sun, 10 Aug 2025 20:59:38 +0100 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=A4=96=20Merge=20PR=20#73437=20Flesh?= =?UTF-8?q?=20out=20typings=20for=20Rails=20Request.JS,=20targeting=20late?= =?UTF-8?q?st=20version=20v0.0.12=20by=20@myabc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- types/rails__request.js/index.d.ts | 49 ++++++++++++---- .../rails__request.js-tests.ts | 57 ++++++++++++++++++- 2 files changed, 93 insertions(+), 13 deletions(-) diff --git a/types/rails__request.js/index.d.ts b/types/rails__request.js/index.d.ts index d897768199dd03..3e3f9708d71ffb 100644 --- a/types/rails__request.js/index.d.ts +++ b/types/rails__request.js/index.d.ts @@ -1,36 +1,65 @@ export class FetchRequest { - constructor(method: string, url: string, options?: Options); - addHeader(key: string, value: string): void; + constructor(method: string, url: string | URL, options?: Options); perform(): Promise; + addHeader(key: string, value: string): void; + sameHostname(): boolean; + get fetchOptions(): RequestInit & { method: string; headers: HeadersInit }; + get headers(): HeadersInit; + get csrfToken(): string | undefined; + get contentType(): string | undefined; + get accept(): string; + get body(): BodyInit | Record | null | undefined; + get query(): string; + get url(): string; + get responseKind(): ResponseKind; + get signal(): AbortSignal | null | undefined; + get redirect(): RequestRedirect; + get credentials(): RequestCredentials; + get keepalive(): boolean; + get additionalHeaders(): HeadersInit; + get formattedBody(): string; } +export type ResponseKind = "html" | "turbo-stream" | "json" | "script"; + export interface Options { - body?: BodyInit | Record; + body?: BodyInit | Record | null; contentType?: string; headers?: HeadersInit; credentials?: RequestCredentials; - query?: Record | FormData | URLSearchParams; - responseKind?: "html" | "turbo-stream" | "json"; + query?: Record | FormData | URLSearchParams; + responseKind?: ResponseKind; + signal?: AbortSignal | null; + redirect?: RequestRedirect; + keepalive?: boolean; } export class FetchResponse { get statusCode(): number; get redirected(): boolean; get ok(): boolean; + get unauthenticated(): boolean; + get unprocessableEntity(): boolean; + get authenticationURL(): string | null; get contentType(): string; get headers(): Headers; get html(): Promise; get json(): Promise; get text(): Promise; + get isTurboStream(): boolean; + get isScript(): boolean; + renderTurboStream(): Promise; + activeScript(): Promise; } export class RequestInterceptor { static register(interceptor: (request: FetchRequest) => void | Promise): void; + static get(): (request: FetchRequest) => void | Promise; static reset(): void; } -export function get(url: string, options?: Options): Promise; -export function post(url: string, options?: Options): Promise; -export function put(url: string, options?: Options): Promise; -export function patch(url: string, options?: Options): Promise; -export function destroy(url: string, options?: Options): Promise; +export function get(url: string | URL, options?: Options): Promise; +export function post(url: string | URL, options?: Options): Promise; +export function put(url: string | URL, options?: Options): Promise; +export function patch(url: string | URL, options?: Options): Promise; +export function destroy(url: string | URL, options?: Options): Promise; diff --git a/types/rails__request.js/rails__request.js-tests.ts b/types/rails__request.js/rails__request.js-tests.ts index d4c47a63b74d34..ea8e98b575b2bb 100644 --- a/types/rails__request.js/rails__request.js-tests.ts +++ b/types/rails__request.js/rails__request.js-tests.ts @@ -5,6 +5,8 @@ interface TestJsonResponse { key2: number; } +const { signal } = new AbortController(); + const request = new FetchRequest("post", "https://example.com", { body: { name: "Request.JS" }, contentType: "application/json", @@ -12,8 +14,30 @@ const request = new FetchRequest("post", "https://example.com", { credentials: "include", query: { "test": "test" }, responseKind: "json", + signal, }); +// $ExpectType HeadersInit +request.headers; +// $ExpectType string | undefined +request.csrfToken; +// $ExpectType string | undefined +request.contentType; +// $ExpectType string +request.accept; +// $ExpectType BodyInit | Record | null | undefined +request.body; +// $ExpectType string +request.query; +// $ExpectType AbortSignal | null | undefined +request.signal; + +// $ExpectType string +request.fetchOptions.method; + +// $ExpectType (HeadersInit | undefined) & HeadersInit +request.fetchOptions.headers; + let testJsonResponseVar: TestJsonResponse; let headersVar: Headers; let stringVar: string; @@ -36,20 +60,47 @@ async function main() { numberVar = response.statusCode; stringVar = await response.text; - response = await get("https://example.com"); + response = await get("https://example.com", { responseKind: "json" }); testJsonResponseVar = await response.json as TestJsonResponse; + response = await get("https://example.com/ex/turbo-stream", { responseKind: "turbo-stream" }); + await response.renderTurboStream(); + + response = await get("https://example.com/ex/script", { responseKind: "script" }); + await response.activeScript(); + response = await post("https://example.com", { body: new FormData(), }); + response = await post("https://example.com", { + body: new FormData(), + keepalive: true, + }); + + const emptyFile = new File([], "empty.txt", { + type: "text/plain", + lastModified: Date.now(), + }); + + response = await post("https://example.com", { + body: emptyFile, + keepalive: true, + }); + response = await put("https://example.com", { query: new URLSearchParams(), }); - response = await patch("https://example.com"); + const myURL = new URL("https://example.com"); + + response = await patch(myURL); + + response = await patch("https://example.com/this-will-redirect", { + redirect: "follow", + }); - response = await destroy("https://example.com"); + response = await destroy("https://example.com", { body: null }); RequestInterceptor.register(async (request) => { request.addHeader("Authorization", "Bearer 12345");