
Research
/Security News
jscrambler npm Package Compromised in Supply Chain Attack
A compromised jscrambler npm release added a malicious preinstall hook that runs hidden native binaries on Linux, macOS, and Windows.
@complex-suite/request
Advanced tools
这是一个功能强大且高度可扩展的 TypeScript 请求库,旨在通过分层、可组合的规则引擎,优雅地处理复杂的 Web 请求场景。
BaseRequest: 抽象请求基类,负责驱动整个请求生命周期,包括 Token 处理、请求重试、错误捕获等。Rule: 可定制的规则引擎,将所有与具体业务相关的逻辑(如响应解析、登录/刷新流程)集中管理。Token: 封装单个 Token 的所有行为,包括值的获取、存储、附加到请求和生命周期管理。Token 和一个 refreshToken。localStorage 和 sessionStorage 中自动获取和缓存 Token。header, body, params)和附加键名。login 或 refresh 操作,并无缝地重试原始请求。parse 函数,将任何格式的服务器响应,适配为统一的 { status, data, ... } 格式。format 函数,在请求发送前,对请求参数进行最后一次修改。BaseRequest 是一个抽象类,您可以继承它,并使用任何底层的请求库(如 axios, fetch)来实现 $request 方法。json 和 form-data 之间自动转换请求数据。npm install @complex-suite/request
下面是一个使用 fetch 作为底层实现的简单示例:
import { BaseRequest, Rule, Token } from '@complex-suite/request';
// 1. 创建一个继承自 BaseRequest 的具体请求类
// 我们在这里为泛型 R (原始响应) 和 L (本地配置) 提供了具体的类型
class MyRequest extends BaseRequest<any, { signal?: AbortSignal }> {
$request(requestConfig) {
// 使用 fetch 实现底层的请求逻辑
const { url, method, headers, data, params, local } = requestConfig;
const finalUrl = new URL(url);
Object.keys(params).forEach(key => finalUrl.searchParams.append(key, params[key]));
return fetch(finalUrl.toString(), {
method,
headers,
body: data,
signal: local?.signal // 传递 AbortSignal 以便取消请求
}).then(res => res.json());
}
$parseError(error) {
// 解析 fetch 抛出的错误
return { type: 'internal', msg: error.message, data: error };
}
}
// 2. 定义一套规则
const myRule = new Rule({
prop: 'api',
token: {
data: {
// 定义一个名为 'accessToken' 的 Token
accessToken: {
location: 'header', // 存储在 Header 中
require: true // 这是一个必需的 Token
}
}
},
parse: (response) => {
// 解析服务器响应
if (response.code === 200) {
return { status: 'success', data: response.data };
} else if (response.code === 401) {
return { status: 'login', data: null, msg: '请先登录' };
} else {
return { status: 'fail', data: null, msg: response.message };
}
},
login: () => {
// 定义登录逻辑
return new Promise(resolve => {
// ... 执行登录操作,例如弹出一个登录框
// ... 登录成功后,使用 setToken 设置新的 Token
myRequest.setToken('accessToken', 'new-token-from-server');
resolve();
});
}
});
// 3. 实例化请求对象
const myRequest = new MyRequest({
baseUrl: 'https://api.example.com',
rule: myRule
});
// 4. 发送请求
// 4. 发送请求,并传递一个本地配置
const controller = new AbortController();
myRequest.get({
url: '/user/profile',
local: { signal: controller.signal }
})
.then(response => {
console.log('用户信息:', response.data);
})
.catch(error => {
console.error('请求失败:', error);
});
// 可以在需要时取消请求
// controller.abort();
@complex-suite/request 大量使用泛型来提供强大的类型安全。理解 R 和 L 这两个核心泛型,能帮助您更好地利用这个库。
R - 原始响应 (Raw Response)R 代表的是底层请求工具(如 fetch, axios)直接返回的、未经 rule.parse 解析的原始响应数据的类型。
在 Rule 的 parse 函数中,response 参数的类型就是 R。
// 假设服务器返回的数据结构是 { code: number, data: T, message: string }
type ServerResponse<T> = {
code: number;
data: T;
message: string;
}
// 在定义 Rule 时,我们可以将 R 指定为 ServerResponse<any>
const myRule = new Rule<ServerResponse<any>>({
// ...
parse: (response) => { // 在这里,`response` 的类型就是 ServerResponse<any>
if (response.code === 200) {
return { status: 'success', data: response.data };
}
// ...
}
});
L - 本地配置 (Local Config)L 代表的是一个可选的、用于传递给底层请求工具的、特定于实现的配置对象的类型。
这非常有用,因为不同的底层请求库(fetch, axios)有它们自己独特的配置选项(例如,axios 的 cancelToken,fetch 的 signal)。L 允许您以类型安全的方式,将这些特定于实现的配置,一路传递到您自己实现的 $request 方法中。
在上面的“快速开始”示例中,我们通过 L 泛型,为 fetch 实现了一个请求取消的功能。
parse 函数:请求的“交通警察”parse 函数是 @complex-suite/request 库的核心。它就像一个交通警察,负责检查每一个从服务器返回的原始响应 (R),并根据您定义的业务逻辑,告诉 BaseRequest 下一步应该做什么。
parse 函数必须返回一个 responseType 对象,其 status 字段决定了整个请求的走向:
interface responseType<D = any> {
status: 'success' | 'fail' | 'login' | 'refresh'
data: D
code?: number | string
msg?: string
}
下面是 BaseRequest 对每种 status 的处理方式:
'success': 请求成功
BaseRequest 的行为: request 方法返回的 Promise 将被 resolve,并将 data 字段作为结果传递下去。'fail': 请求失败
BaseRequest 的行为: request 方法返回的 Promise 将被 reject,并将整个 responseType 对象作为错误信息传递下去。'login': 需要登录
BaseRequest 的行为:
Rule 中定义的 login 函数。login 函数成功执行后(即其返回的 Promise 被 resolve),BaseRequest 会自动重新发送之前失败的那个请求。'refresh': 需要刷新 Token
BaseRequest 的行为:
Rule 中定义的 refresh 函数。refresh 函数成功执行后,BaseRequest 会自动重新发送之前失败的那个请求。refresh 本身也失败了,或者刷新后重试的请求依然返回 'refresh',BaseRequest 会自动将流程降级为 'login'。通过精心设计您的 parse 函数,您可以以一种非常优雅和集中的方式,实现极其复杂的认证和重试逻辑。
notice 通知插件。FAQs
a complex request
We found that @complex-suite/request demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
A compromised jscrambler npm release added a malicious preinstall hook that runs hidden native binaries on Linux, macOS, and Windows.

Research
/Security News
A malicious .NET package is typosquatting the Braintree SDK to steal live payment card data, merchant API keys, and host secrets from production apps.

Security News
/Research
Compromised Injective SDK npm version 1.20.21 exfiltrates wallet private keys and mnemonics through fake telemetry functionality.