update
This commit is contained in:
24
package.json
24
package.json
@@ -1,9 +1,7 @@
|
||||
{
|
||||
"name": "@kevisual/query",
|
||||
"version": "0.0.29",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"version": "0.0.30",
|
||||
"main": "dist/query-browser.js",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -23,16 +21,13 @@
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||
"@rollup/plugin-typescript": "^12.1.2",
|
||||
"rollup": "^4.41.1",
|
||||
"rollup-plugin-dts": "^6.2.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"zustand": "^5.0.5"
|
||||
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||
"@rollup/plugin-typescript": "^12.3.0",
|
||||
"rollup": "^4.53.3",
|
||||
"rollup-plugin-dts": "^6.3.0",
|
||||
"typescript": "^5.9.3",
|
||||
"zustand": "^5.0.9"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@@ -57,8 +52,5 @@
|
||||
"import": "./dist/query-ai.js",
|
||||
"require": "./dist/query-ai.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"openai": "^5.0.1"
|
||||
}
|
||||
}
|
||||
@@ -81,20 +81,4 @@ export default [
|
||||
},
|
||||
plugins: [dts()],
|
||||
},
|
||||
{
|
||||
input: 'src/query-ai.ts',
|
||||
output: {
|
||||
file: 'dist/query-ai.js',
|
||||
format: 'es',
|
||||
},
|
||||
plugins: [resolve(), typescript()],
|
||||
},
|
||||
{
|
||||
input: 'src/query-ai.ts', // TypeScript 入口文件
|
||||
output: {
|
||||
file: 'dist/query-ai.d.ts', // 输出文件
|
||||
format: 'es', // 输出格式设置为 ES 模块
|
||||
},
|
||||
plugins: [dts()],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -5,16 +5,31 @@ type SimpleObject = Record<string, any>;
|
||||
export type AdapterOpts = {
|
||||
url?: string;
|
||||
headers?: Record<string, string>;
|
||||
/**
|
||||
* 只用户POST请求,传递的查询参数,
|
||||
* GET请求默认方body自己转化为查询参数
|
||||
*/
|
||||
params?: Record<string, any>;
|
||||
body?: Record<string, any> | FormData; // body 可以是对象、字符串或 FormData
|
||||
timeout?: number;
|
||||
method?: Method;
|
||||
/**
|
||||
* @deprecated use responseType
|
||||
*/
|
||||
isBlob?: boolean; // 是否返回 Blob 对象, 第一优先
|
||||
/**
|
||||
* @deprecated use responseType
|
||||
*/
|
||||
isText?: boolean; // 是否返回文本内容, 第二优先
|
||||
/**
|
||||
* 响应类型,
|
||||
* */
|
||||
responseType?: 'json' | 'text' | 'blob';
|
||||
isPostFile?: boolean; // 是否为文件上传
|
||||
};
|
||||
export const isTextForContentType = (contentType: string | null) => {
|
||||
if (!contentType) return false;
|
||||
const textTypes = ['text/', 'xml', 'html', 'javascript', 'css', 'csv', 'plain', 'x-www-form-urlencoded'];
|
||||
const textTypes = ['text/', 'xml', 'html', 'javascript', 'css', 'csv', 'plain', 'x-www-form-urlencoded', 'md'];
|
||||
return textTypes.some((type) => contentType.includes(type));
|
||||
};
|
||||
/**
|
||||
@@ -26,9 +41,14 @@ export const isTextForContentType = (contentType: string | null) => {
|
||||
export const adapter = async (opts: AdapterOpts = {}, overloadOpts?: RequestInit) => {
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
const isBlob = opts.isBlob || false; // 是否返回 Blob 对象
|
||||
const isText = opts.isText || false; // 是否返回文本内容
|
||||
const isPostFile = opts.isPostFile || false; // 是否为文件上传
|
||||
let responseType = opts.responseType || 'json'; // 响应类型
|
||||
if (opts.isBlob) {
|
||||
responseType = 'blob';
|
||||
} else if (opts.isText) {
|
||||
responseType = 'text';
|
||||
}
|
||||
|
||||
const timeout = opts.timeout || 60000 * 3; // 默认超时时间为 60s * 3
|
||||
const timer = setTimeout(() => {
|
||||
controller.abort();
|
||||
@@ -46,6 +66,9 @@ export const adapter = async (opts: AdapterOpts = {}, overloadOpts?: RequestInit
|
||||
const isGet = method === 'GET';
|
||||
if (isGet) {
|
||||
url.search = new URLSearchParams(opts.body as SimpleObject).toString();
|
||||
} else {
|
||||
const params = opts.params || {};
|
||||
url.search = new URLSearchParams(params as SimpleObject).toString();
|
||||
}
|
||||
let body: string | FormData | undefined = undefined;
|
||||
if (isGet) {
|
||||
@@ -69,9 +92,10 @@ export const adapter = async (opts: AdapterOpts = {}, overloadOpts?: RequestInit
|
||||
.then(async (response) => {
|
||||
// 获取 Content-Type 头部信息
|
||||
const contentType = response.headers.get('Content-Type');
|
||||
if (isBlob) {
|
||||
if (responseType === 'blob') {
|
||||
return await response.blob(); // 直接返回 Blob 对象
|
||||
}
|
||||
const isText = responseType === 'text';
|
||||
const isJson = contentType && contentType.includes('application/json');
|
||||
// 判断返回的数据类型
|
||||
if (isJson && !isText) {
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import OpenAI, { ClientOptions } from 'openai';
|
||||
import type { RequestOptions } from 'openai/core.mjs';
|
||||
|
||||
type QueryOpts = {
|
||||
/**
|
||||
* OpenAI model name, example: deepseek-chat
|
||||
*/
|
||||
model: string;
|
||||
/**
|
||||
* OpenAI client options
|
||||
* QueryAi.init() will be called with these options
|
||||
*/
|
||||
openAiOpts?: ClientOptions;
|
||||
openai?: OpenAI;
|
||||
};
|
||||
export class QueryAI {
|
||||
private openai: OpenAI;
|
||||
model?: string;
|
||||
constructor(opts?: QueryOpts) {
|
||||
this.model = opts?.model;
|
||||
if (opts?.openai) {
|
||||
this.openai = opts.openai;
|
||||
} else if (opts?.openAiOpts) {
|
||||
this.init(opts?.openAiOpts);
|
||||
}
|
||||
}
|
||||
init(opts: ClientOptions) {
|
||||
this.openai = new OpenAI(opts);
|
||||
}
|
||||
async query(prompt: string, opts?: RequestOptions) {
|
||||
return this.openai.chat.completions.create({
|
||||
model: this.model,
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: prompt,
|
||||
},
|
||||
],
|
||||
stream: false,
|
||||
...opts,
|
||||
});
|
||||
}
|
||||
async queryAsync(prompt: string, opts?: RequestOptions) {
|
||||
return this.openai.chat.completions.create({
|
||||
model: this.model,
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: prompt,
|
||||
},
|
||||
],
|
||||
stream: true,
|
||||
...opts,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export { OpenAI };
|
||||
@@ -1,9 +1,9 @@
|
||||
import { adapter } from './adapter.ts';
|
||||
import { QueryWs, QueryWsOpts } from './ws.ts';
|
||||
import { Query, ClientQuery } from './query.ts';
|
||||
import { BaseQuery, wrapperError } from './query.ts';
|
||||
import { Query } from './query.ts';
|
||||
import { wrapperError } from './query.ts';
|
||||
|
||||
export { QueryOpts, QueryWs, ClientQuery, Query, QueryWsOpts, adapter, BaseQuery, wrapperError };
|
||||
export { QueryOpts, QueryWs, Query, QueryWsOpts, adapter, wrapperError };
|
||||
|
||||
export type { DataOpts, Result, Data } from './query.ts';
|
||||
|
||||
|
||||
45
src/query.ts
45
src/query.ts
@@ -1,4 +1,4 @@
|
||||
import { adapter, isTextForContentType, Method, AdapterOpts } from './adapter.ts';
|
||||
import { adapter, Method, AdapterOpts } from './adapter.ts';
|
||||
import type { QueryWs } from './ws.ts';
|
||||
/**
|
||||
* 请求前处理函数
|
||||
@@ -92,7 +92,13 @@ export const wrapperError = ({ code, message }: { code?: number; message?: strin
|
||||
export class Query {
|
||||
adapter: typeof adapter;
|
||||
url: string;
|
||||
/**
|
||||
* 请求前处理函数
|
||||
*/
|
||||
beforeRequest?: DataOpts['beforeRequest'];
|
||||
/**
|
||||
* 请求后处理函数
|
||||
*/
|
||||
afterResponse?: DataOpts['afterResponse'];
|
||||
headers?: Record<string, string>;
|
||||
timeout?: number;
|
||||
@@ -215,14 +221,14 @@ export class Query {
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 请求前处理,设置请求前处理函数
|
||||
* 设置请求前处理,设置请求前处理函数
|
||||
* @param fn 处理函数
|
||||
*/
|
||||
before(fn: DataOpts['beforeRequest']) {
|
||||
this.beforeRequest = fn;
|
||||
}
|
||||
/**
|
||||
* 请求后处理,设置请求后处理函数
|
||||
* 设置请求后处理,设置请求后处理函数
|
||||
* @param fn 处理函数
|
||||
*/
|
||||
after(fn: DataOpts['afterResponse']) {
|
||||
@@ -248,35 +254,4 @@ export class Query {
|
||||
}
|
||||
}
|
||||
|
||||
export { adapter };
|
||||
|
||||
export class BaseQuery<T extends Query = Query, R extends { queryChain?: any; query?: any } = { queryChain: any; query?: T }> {
|
||||
query: T;
|
||||
queryDefine: R;
|
||||
constructor(opts?: { query?: T; queryDefine?: R; clientQuery?: T }) {
|
||||
if (opts?.clientQuery) {
|
||||
this.query = opts.clientQuery;
|
||||
} else {
|
||||
this.query = opts?.query;
|
||||
}
|
||||
if (opts.queryDefine) {
|
||||
this.queryDefine = opts.queryDefine;
|
||||
this.queryDefine.query = this.query;
|
||||
}
|
||||
}
|
||||
get chain(): R['queryChain'] {
|
||||
return this.queryDefine.queryChain;
|
||||
}
|
||||
post<R = any, P = any>(data: P, options?: DataOpts): Promise<Result<R>> {
|
||||
return this.query.post(data, options);
|
||||
}
|
||||
get<R = any, P = any>(data: P, options?: DataOpts): Promise<Result<R>> {
|
||||
return this.query.get(data, options);
|
||||
}
|
||||
}
|
||||
|
||||
export class ClientQuery extends Query {
|
||||
constructor(opts?: QueryOpts) {
|
||||
super({ ...opts, url: opts?.url || '/client/router' });
|
||||
}
|
||||
}
|
||||
export { adapter };
|
||||
Reference in New Issue
Block a user