update
This commit is contained in:
24
package.json
24
package.json
@@ -1,9 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@kevisual/query",
|
"name": "@kevisual/query",
|
||||||
"version": "0.0.29",
|
"version": "0.0.30",
|
||||||
"main": "dist/index.js",
|
"main": "dist/query-browser.js",
|
||||||
"module": "dist/index.js",
|
|
||||||
"types": "dist/index.d.ts",
|
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -23,16 +21,13 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"description": "",
|
"description": "",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||||
"@rollup/plugin-typescript": "^12.1.2",
|
"@rollup/plugin-typescript": "^12.3.0",
|
||||||
"rollup": "^4.41.1",
|
"rollup": "^4.53.3",
|
||||||
"rollup-plugin-dts": "^6.2.1",
|
"rollup-plugin-dts": "^6.3.0",
|
||||||
"ts-node": "^10.9.2",
|
"typescript": "^5.9.3",
|
||||||
"tslib": "^2.8.1",
|
"zustand": "^5.0.9"
|
||||||
"typescript": "^5.8.3",
|
|
||||||
"zustand": "^5.0.5"
|
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@1.22.22",
|
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -57,8 +52,5 @@
|
|||||||
"import": "./dist/query-ai.js",
|
"import": "./dist/query-ai.js",
|
||||||
"require": "./dist/query-ai.js"
|
"require": "./dist/query-ai.js"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"openai": "^5.0.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,20 +81,4 @@ export default [
|
|||||||
},
|
},
|
||||||
plugins: [dts()],
|
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 = {
|
export type AdapterOpts = {
|
||||||
url?: string;
|
url?: string;
|
||||||
headers?: Record<string, string>;
|
headers?: Record<string, string>;
|
||||||
|
/**
|
||||||
|
* 只用户POST请求,传递的查询参数,
|
||||||
|
* GET请求默认方body自己转化为查询参数
|
||||||
|
*/
|
||||||
|
params?: Record<string, any>;
|
||||||
body?: Record<string, any> | FormData; // body 可以是对象、字符串或 FormData
|
body?: Record<string, any> | FormData; // body 可以是对象、字符串或 FormData
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
method?: Method;
|
method?: Method;
|
||||||
|
/**
|
||||||
|
* @deprecated use responseType
|
||||||
|
*/
|
||||||
isBlob?: boolean; // 是否返回 Blob 对象, 第一优先
|
isBlob?: boolean; // 是否返回 Blob 对象, 第一优先
|
||||||
|
/**
|
||||||
|
* @deprecated use responseType
|
||||||
|
*/
|
||||||
isText?: boolean; // 是否返回文本内容, 第二优先
|
isText?: boolean; // 是否返回文本内容, 第二优先
|
||||||
|
/**
|
||||||
|
* 响应类型,
|
||||||
|
* */
|
||||||
|
responseType?: 'json' | 'text' | 'blob';
|
||||||
isPostFile?: boolean; // 是否为文件上传
|
isPostFile?: boolean; // 是否为文件上传
|
||||||
};
|
};
|
||||||
export const isTextForContentType = (contentType: string | null) => {
|
export const isTextForContentType = (contentType: string | null) => {
|
||||||
if (!contentType) return false;
|
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));
|
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) => {
|
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 isText = opts.isText || false; // 是否返回文本内容
|
|
||||||
const isPostFile = opts.isPostFile || 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 timeout = opts.timeout || 60000 * 3; // 默认超时时间为 60s * 3
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
controller.abort();
|
controller.abort();
|
||||||
@@ -46,6 +66,9 @@ export const adapter = async (opts: AdapterOpts = {}, overloadOpts?: RequestInit
|
|||||||
const isGet = method === 'GET';
|
const isGet = method === 'GET';
|
||||||
if (isGet) {
|
if (isGet) {
|
||||||
url.search = new URLSearchParams(opts.body as SimpleObject).toString();
|
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;
|
let body: string | FormData | undefined = undefined;
|
||||||
if (isGet) {
|
if (isGet) {
|
||||||
@@ -69,9 +92,10 @@ export const adapter = async (opts: AdapterOpts = {}, overloadOpts?: RequestInit
|
|||||||
.then(async (response) => {
|
.then(async (response) => {
|
||||||
// 获取 Content-Type 头部信息
|
// 获取 Content-Type 头部信息
|
||||||
const contentType = response.headers.get('Content-Type');
|
const contentType = response.headers.get('Content-Type');
|
||||||
if (isBlob) {
|
if (responseType === 'blob') {
|
||||||
return await response.blob(); // 直接返回 Blob 对象
|
return await response.blob(); // 直接返回 Blob 对象
|
||||||
}
|
}
|
||||||
|
const isText = responseType === 'text';
|
||||||
const isJson = contentType && contentType.includes('application/json');
|
const isJson = contentType && contentType.includes('application/json');
|
||||||
// 判断返回的数据类型
|
// 判断返回的数据类型
|
||||||
if (isJson && !isText) {
|
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 { adapter } from './adapter.ts';
|
||||||
import { QueryWs, QueryWsOpts } from './ws.ts';
|
import { QueryWs, QueryWsOpts } from './ws.ts';
|
||||||
import { Query, ClientQuery } from './query.ts';
|
import { Query } from './query.ts';
|
||||||
import { BaseQuery, wrapperError } 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';
|
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';
|
import type { QueryWs } from './ws.ts';
|
||||||
/**
|
/**
|
||||||
* 请求前处理函数
|
* 请求前处理函数
|
||||||
@@ -92,7 +92,13 @@ export const wrapperError = ({ code, message }: { code?: number; message?: strin
|
|||||||
export class Query {
|
export class Query {
|
||||||
adapter: typeof adapter;
|
adapter: typeof adapter;
|
||||||
url: string;
|
url: string;
|
||||||
|
/**
|
||||||
|
* 请求前处理函数
|
||||||
|
*/
|
||||||
beforeRequest?: DataOpts['beforeRequest'];
|
beforeRequest?: DataOpts['beforeRequest'];
|
||||||
|
/**
|
||||||
|
* 请求后处理函数
|
||||||
|
*/
|
||||||
afterResponse?: DataOpts['afterResponse'];
|
afterResponse?: DataOpts['afterResponse'];
|
||||||
headers?: Record<string, string>;
|
headers?: Record<string, string>;
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
@@ -215,14 +221,14 @@ export class Query {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 请求前处理,设置请求前处理函数
|
* 设置请求前处理,设置请求前处理函数
|
||||||
* @param fn 处理函数
|
* @param fn 处理函数
|
||||||
*/
|
*/
|
||||||
before(fn: DataOpts['beforeRequest']) {
|
before(fn: DataOpts['beforeRequest']) {
|
||||||
this.beforeRequest = fn;
|
this.beforeRequest = fn;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 请求后处理,设置请求后处理函数
|
* 设置请求后处理,设置请求后处理函数
|
||||||
* @param fn 处理函数
|
* @param fn 处理函数
|
||||||
*/
|
*/
|
||||||
after(fn: DataOpts['afterResponse']) {
|
after(fn: DataOpts['afterResponse']) {
|
||||||
@@ -248,35 +254,4 @@ export class Query {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { adapter };
|
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' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user