From 3ca4816ad8141bdbd0e36172bdcdc4a3ab1a0358 Mon Sep 17 00:00:00 2001 From: Shigma Date: Mon, 26 Feb 2024 13:43:05 +0800 Subject: [PATCH] feat(undios): support `validateStatus` --- packages/core/readme.md | 6 ++- packages/core/src/adapter/index.d.ts | 56 ---------------------------- packages/core/src/index.ts | 22 ++++++----- 3 files changed, 16 insertions(+), 68 deletions(-) delete mode 100644 packages/core/src/adapter/index.d.ts diff --git a/packages/core/readme.md b/packages/core/readme.md index 260c88d..322608f 100644 --- a/packages/core/readme.md +++ b/packages/core/readme.md @@ -83,7 +83,7 @@ Open a WebSocket connection. > [!NOTE] > -> Currently we will use [`ws`](https://github.com/websockets/ws) package to polyfill `WebSocket` in Node.js. +> Currently we will use [`ws`](https://github.com/websockets/ws) package to polyfill [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) in Node.js. > > Once Node.js has a stable WebSocket API, we will switch to it. @@ -161,7 +161,9 @@ The request timeout in milliseconds. #### config.proxyAgent -> [!NOTE] In order to use a proxy agent, you need to install `undios-proxy-agent`. +> [!NOTE] +> +> In order to use a proxy agent, you need to install `undios-proxy-agent`. ### Response diff --git a/packages/core/src/adapter/index.d.ts b/packages/core/src/adapter/index.d.ts deleted file mode 100644 index 3122325..0000000 --- a/packages/core/src/adapter/index.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -export namespace WebSocket { - /** The connection is not yet open. */ - export const CONNECTING = 0 - /** The connection is open and ready to communicate. */ - export const OPEN = 1 - /** The connection is in the process of closing. */ - export const CLOSING = 2 - /** The connection is closed. */ - export const CLOSED = 3 - - export type ReadyState = - | typeof CONNECTING - | typeof OPEN - | typeof CLOSING - | typeof CLOSED - - export interface EventMap { - open: Event - error: ErrorEvent - message: MessageEvent - close: CloseEvent - } - - export interface EventListener { - (event: Event): void - } - - export interface Event { - type: string - target: WebSocket - } - - export interface CloseEvent extends Event { - code: number - reason: string - } - - export interface MessageEvent extends Event { - data: string - } - - export interface ErrorEvent extends Event { - message?: string - } -} - -export interface WebSocket { - readonly url?: string - readonly protocol?: string - readonly readyState?: number - close(code?: number, reason?: string): void - send(data: string): void - dispatchEvent?(event: any): boolean - addEventListener(type: K, listener: (event: WebSocket.EventMap[K]) => void): void - removeEventListener(type: K, listener: (event: WebSocket.EventMap[K]) => void): void -} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index a44871d..af65866 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -91,6 +91,7 @@ export namespace HTTP { keepAlive?: boolean redirect?: RequestRedirect responseType?: keyof ResponseTypes + validateStatus?: (status: number) => boolean } export interface Response { @@ -164,7 +165,7 @@ export class HTTP extends Service { }) decoder(type: K, decoder: (raw: Response) => Awaitable) { - return this[Context.trace].effect(() => { + return this[Context.current].effect(() => { this._decoders[type] = decoder return () => delete this._decoders[type] }) @@ -177,7 +178,7 @@ export class HTTP extends Service { } resolveConfig(init?: HTTP.RequestConfig): HTTP.RequestConfig { - const caller = this[Context.trace] + const caller = this[Context.current] let result = { headers: {}, ...this.config } caller.emit('http/config', result) let intercept = caller[Context.intercept] @@ -191,7 +192,7 @@ export class HTTP extends Service { resolveURL(url: string | URL, config: HTTP.RequestConfig) { if (config.endpoint) { - // this[Context.trace].emit('internal/warning', 'endpoint is deprecated, please use baseURL instead') + // this[Context.current].emit('internal/warning', 'endpoint is deprecated, please use baseURL instead') try { new URL(url) } catch { @@ -222,7 +223,7 @@ export class HTTP extends Service { } async [Service.invoke](...args: any[]) { - const caller = this[Context.trace] + const caller = this[Context.current] let method: HTTP.Method | undefined if (typeof args[1] === 'string' || args[1] instanceof URL) { method = args.shift() @@ -235,11 +236,11 @@ export class HTTP extends Service { let timer: NodeJS.Timeout | number | undefined const dispose = caller.on('dispose', () => { clearTimeout(timer) - controller.abort('context disposed') + controller.abort(new Error('context disposed')) }) if (config.timeout) { timer = setTimeout(() => { - controller.abort('timeout') + controller.abort(new Error('timeout')) }, config.timeout) } @@ -276,7 +277,8 @@ export class HTTP extends Service { } // we don't use `raw.ok` because it may be a 3xx redirect - if (raw.status >= 400) { + const validateStatus = config.validateStatus ?? (status => status < 400) + if (!validateStatus(raw.status)) { const error = new HTTP.Error(raw.statusText) error.response = response try { @@ -309,7 +311,7 @@ export class HTTP extends Service { axios(config: { url: string } & HTTP.RequestConfig): Promise> axios(url: string, config?: HTTP.RequestConfig): Promise> axios(...args: any[]) { - const caller = this[Context.trace] + const caller = this[Context.current] caller.emit('internal/warning', 'ctx.http.axios() is deprecated, use ctx.http() instead') if (typeof args[0] === 'string') { return this(args[0], args[1]) @@ -319,7 +321,7 @@ export class HTTP extends Service { } ws(url: string | URL, init?: HTTP.Config) { - const caller = this[Context.trace] + const caller = this[Context.current] const config = this.resolveConfig(init) url = this.resolveURL(url, config) let options: ClientOptions | undefined @@ -330,7 +332,7 @@ export class HTTP extends Service { } caller.emit('http/websocket-init', options, config) } - const socket = new WebSocket(url, options) + const socket = new WebSocket(url, options as never) const dispose = caller.on('dispose', () => { socket.close(1001, 'context disposed') })