npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bwt-st/http

v0.2.1

Published

Framework-agnostic HTTP client for BWT-ST projects.

Readme

@bwt-st/http

基于原生 fetch 的无框架 TypeScript HTTP 客户端,不依赖 Axios。提供统一的请求配置、查询参数、JSON 请求体、Token 注入、超时、响应解包和错误标准化能力。

安装

pnpm add @bwt-st/http

库不会读取 import.meta.env,不会创建全局单例,也不会自动重试或刷新 Token。基础 URL、认证状态和业务错误提示由宿主项目负责。

快速使用

建议在业务项目的基础设施层创建一次客户端并统一导出:

// src/services/http.ts
import { createHttpClient } from '@bwt-st/http'

export const http = createHttpClient({
  baseURL: '/api',
  timeout: 15_000,
  hooks: {
    getAccessToken: () => localStorage.getItem('access-token'),
    onUnauthorized: () => {
      // 在业务层处理退出登录或跳转
    },
  },
})

const user = await http.get<User>('/users/1')

工厂和客户端

createHttpClient(options)

创建一个 HttpClient 实例。

| 配置 | 类型 | 默认值 | 说明 | | -------------- | ----------------- | ------------------ | ------------------------------------------------------- | | baseURL | string | 必填 | 相对路径使用的基础地址;请求路径是绝对 URL 时直接使用。 | | timeout | number | 15000 | 超时时间,单位为毫秒。 | | successCodes | ApiCode[] | [0, 200] | API 响应信封中的成功业务码。 | | headers | HeadersInit | {} | 所有请求的默认请求头。 | | hooks | HttpClientHooks | {} | Token、未授权和错误回调。 | | fetch | typeof fetch | globalThis.fetch | 测试或特殊运行环境使用的 fetch 实现。 |

HttpClient

实例提供以下方法:

http.get<Response>(url, options?)
http.post<Response, Data>(url, data?, options?)
http.put<Response, Data>(url, data?, options?)
http.patch<Response, Data>(url, data?, options?)
http.delete<Response>(url, options?)
http.request<Response, Data>(config)
http.configureHooks(hooks)

请求配置

HttpRequestConfig 在原生 RequestInit 基础上增加:

| 属性 | 类型 | 说明 | | ---------------- | ---------------- | ---------------------------------------------- | | url | string | 请求路径或绝对 URL。 | | method | string | HTTP 方法,快捷方法会自动设置。 | | headers | HeadersInit | 覆盖或追加当前请求头。 | | params | HttpQuery | 查询参数,数组会生成多个同名参数。 | | data | Data | 请求数据,普通对象会自动 JSON 序列化。 | | body | BodyInit \\ | null | 直接指定请求体,优先于 data。 | | responseType | 'json' \\ | 'text' \\ | 'blob' \\ | 'arraybuffer' | 响应解析方式。 | | requestOptions | RequestOptions | Token 和响应解包控制。 | | 原生选项 | RequestInit | 支持 signal、credentials、cache 等选项。 |

const result = await http.get<PageResult<User>>('/users', {
  params: {
    page: 1,
    pageSize: 20,
    status: ['active', 'pending'],
  },
})

null 和 undefined 查询参数会被忽略。普通对象、数组和基础值通过 data 发送时会转为 JSON,并自动设置 Content-Type: application/json;FormData、Blob、ArrayBuffer 和 URLSearchParams 会直接作为请求体发送。

const user = await http.post<User, CreateUserInput>('/users', {
  name: 'Ada',
  email: '[email protected]',
})

const form = new FormData()
form.append('avatar', file)
await http.post<{ url: string }>('/avatar', form)

响应约定

默认 JSON 响应需要符合以下信封结构:

interface ApiResponse<T> {
  code: number | string
  message?: string
  data: T
}

code 为 0 或 200 时,客户端默认返回 data:

const user = await http.get<User>('/users/1')

需要保留完整信封时关闭解包:

const response = await http.get<ApiResponse<User>>('/users/1', {
  requestOptions: { unwrap: false },
})

公开接口可以关闭 Token 注入:

await http.get<PublicConfig>('/public/config', {
  requestOptions: { withToken: false },
})

二进制或文本响应:

const file = await http.get<Blob>('/reports/latest', {
  responseType: 'blob',
})

const text = await http.get<string>('/version.txt', {
  responseType: 'text',
  requestOptions: { unwrap: false },
})

204、blob 和 arraybuffer 响应不会进行 API 信封解包。使用 responseType: 'text' 时,通常应同时设置 unwrap: false。

错误处理

所有请求错误都会被转换为 HttpError:

class HttpError extends Error {
  readonly code?: ApiCode
  readonly status?: number
  readonly details?: unknown
}

常见错误码:

| code | 含义 | | ------------------- | ------------------------- | | ETIMEDOUT | 超过客户端超时时间。 | | ERR_CANCELED | 请求被 AbortSignal 取消。 | | ERR_NETWORK | 网络连接失败。 | | HTTP 状态码或业务码 | 服务端返回错误。 |

import { HttpError } from '@bwt-st/http'

try {
  await http.get<User>('/users/1')
} catch (error) {
  if (error instanceof HttpError && error.status === 404) {
    showMessage('用户不存在')
  } else {
    showMessage('请求失败,请稍后重试')
  }
}

onUnauthorized 会在 HTTP 状态码或业务码为 401 时执行;onError 会在每次错误标准化后执行。请求超时只会中止当前客户端请求,不提供重试策略。

其他导出

| 导出 | 类型 | 用途 | | ----------------------------------------------- | ---- | ------------------------------- | | HttpError | 类 | 统一的请求错误类型。 | | isApiResponse | 函数 | 判断数据是否符合 API 信封结构。 | | unwrapResponse | 函数 | 按成功码解包响应。 | | normalizeHttpError | 函数 | 将未知错误转换为 HttpError。 | | ApiCode、ApiResponse<T> | 类型 | 业务码和 API 信封。 | | HttpQueryValue、HttpQuery | 类型 | 查询参数类型。 | | PageQuery、PageResult<T> | 类型 | 常见分页类型。 | | HttpRequestConfig<T>、HttpRequestOptions<T> | 类型 | 完整请求配置和快捷方法配置。 | | HttpResponseType、RequestOptions | 类型 | 响应解析和解包配置。 | | HttpClientHooks、HttpClientOptions | 类型 | 客户端和回调配置。 |

运行环境

  • Node.js >=20.19.0
  • 浏览器或 Node.js 原生支持 fetch
  • 详细 API 与场景示例可参阅仓库的 docs/http/index.md