"chore: 更新依赖及适配Blob响应"

This commit is contained in:
熊潇 2025-06-02 11:36:59 +08:00
parent 366840bb1d
commit 66905f13a9
3 changed files with 80 additions and 8 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@kevisual/query", "name": "@kevisual/query",
"version": "0.0.20", "version": "0.0.22",
"main": "dist/index.js", "main": "dist/index.js",
"module": "dist/index.js", "module": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
@ -25,12 +25,12 @@
"devDependencies": { "devDependencies": {
"@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-typescript": "^12.1.2", "@rollup/plugin-typescript": "^12.1.2",
"rollup": "^4.40.2", "rollup": "^4.41.1",
"rollup-plugin-dts": "^6.2.1", "rollup-plugin-dts": "^6.2.1",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.8.3", "typescript": "^5.8.3",
"zustand": "^5.0.4" "zustand": "^5.0.5"
}, },
"packageManager": "yarn@1.22.22", "packageManager": "yarn@1.22.22",
"publishConfig": { "publishConfig": {
@ -59,6 +59,6 @@
} }
}, },
"dependencies": { "dependencies": {
"openai": "^4.98.0" "openai": "^5.0.1"
} }
} }

View File

@ -1,11 +1,12 @@
export const methods = ['GET', 'POST'] as const; export const methods = ['GET', 'POST'] as const;
export type Method = (typeof methods)[number]; export type Method = (typeof methods)[number];
export type AdapterOpts = { export type AdapterOpts = {
url: string; url?: string;
headers?: Record<string, string>; headers?: Record<string, string>;
body?: Record<string, any>; body?: Record<string, any>;
timeout?: number; timeout?: number;
method?: Method; method?: Method;
isBlob?: boolean; // 是否返回 Blob 对象
}; };
/** /**
@ -17,6 +18,7 @@ export type AdapterOpts = {
export const adapter = async (opts: AdapterOpts, overloadOpts?: RequestInit) => { export const adapter = async (opts: AdapterOpts, overloadOpts?: RequestInit) => {
const controller = new AbortController(); const controller = new AbortController();
const signal = controller.signal; const signal = controller.signal;
const isBlob = opts.isBlob || false; // 是否返回 Blob 对象
const timeout = opts.timeout || 60000 * 3; // 默认超时时间为 60s * 3 const timeout = opts.timeout || 60000 * 3; // 默认超时时间为 60s * 3
const timer = setTimeout(() => { const timer = setTimeout(() => {
controller.abort(); controller.abort();
@ -47,8 +49,12 @@ export const adapter = async (opts: AdapterOpts, overloadOpts?: RequestInit) =>
.then((response) => { .then((response) => {
// 获取 Content-Type 头部信息 // 获取 Content-Type 头部信息
const contentType = response.headers.get('Content-Type'); const contentType = response.headers.get('Content-Type');
if (isBlob) {
return response.blob(); // 直接返回 Blob 对象
}
const isJson = contentType && contentType.includes('application/json');
// 判断返回的数据类型 // 判断返回的数据类型
if (contentType && contentType.includes('application/json')) { if (isJson) {
return response.json(); // 解析为 JSON return response.json(); // 解析为 JSON
} else { } else {
return response.text(); // 解析为文本 return response.text(); // 解析为文本

View File

@ -15,10 +15,13 @@ export type Fn = (opts: {
export type QueryOpts = { export type QueryOpts = {
url?: string; url?: string;
adapter?: typeof adapter;
headers?: Record<string, string>; headers?: Record<string, string>;
body?: Record<string, any>;
timeout?: number; timeout?: number;
method?: Method; method?: Method;
isBlob?: boolean; // 是否返回 Blob 对象
adapter?: typeof adapter;
[key: string]: any; [key: string]: any;
}; };
export type Data = { export type Data = {
@ -55,7 +58,7 @@ export type DataOpts = Partial<QueryOpts> & {
* showError success false noMsg false, showError * showError success false noMsg false, showError
* @param res * @param res
*/ */
export const setBaseResponse = (res: Result) => { export const setBaseResponse = (res: Partial<Result>) => {
res.success = res.code === 200; res.success = res.code === 200;
/** /**
* *
@ -66,6 +69,7 @@ export const setBaseResponse = (res: Result) => {
fn?.(); fn?.();
} }
}; };
return res as Result;
}; };
export const wrapperError = ({ code, message }: { code?: number; message?: string }) => { export const wrapperError = ({ code, message }: { code?: number; message?: string }) => {
const result = { const result = {
@ -227,6 +231,68 @@ export class Query {
after(fn: DataOpts['afterResponse']) { after(fn: DataOpts['afterResponse']) {
this.afterResponse = fn; this.afterResponse = fn;
} }
async fetchText(urlOrOptions?: string | QueryOpts, options?: QueryOpts): Promise<Result<any>> {
let _options = { ...options };
if (typeof urlOrOptions === 'string' && !_options.url) {
_options.url = urlOrOptions;
}
if (typeof urlOrOptions === 'object') {
_options = { ...urlOrOptions, ..._options };
}
const res = await adapter({
method: 'GET',
..._options,
headers: {
...this.headers,
...(_options?.headers || {}),
},
});
if (!res.ok) {
return wrapperError({
code: res.status,
message: `fetch error: ${res.statusText}`,
});
}
const contentType = res.headers.get('Content-Type');
if (contentType && contentType.includes('application/json')) {
const data = await res.json();
const result = { code: res.status, data, success: res.ok };
return setBaseResponse(result);
}
if (contentType && contentType.includes('text/html')) {
const text = await res.text();
const result: Partial<Result> = {
code: res.status,
data: text,
success: res.ok,
};
return setBaseResponse(result);
}
if (contentType && contentType.includes('text/plain')) {
let text = await res.text();
// 处理特殊情况,比如返回的是纯文本
if (text.startsWith('{')) {
try {
text = JSON.parse(text);
} catch (e) {
// 如果解析失败,保持原样
}
}
const result: Partial<Result> = {
code: res.status,
data: text,
success: res.ok,
};
return setBaseResponse(result);
}
const blob = await res.blob();
const result: Partial<Result> = {
code: res.status,
data: blob,
success: res.ok,
};
return setBaseResponse(result);
}
} }
export { adapter }; export { adapter };