diff --git a/package.json b/package.json index 446ad3a..5f49dad 100644 --- a/package.json +++ b/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" } } \ No newline at end of file diff --git a/rollup.config.js b/rollup.config.js index 66b6295..92719f8 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -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()], - }, ]; diff --git a/src/adapter.ts b/src/adapter.ts index 8867de9..e9307a0 100644 --- a/src/adapter.ts +++ b/src/adapter.ts @@ -5,16 +5,31 @@ type SimpleObject = Record; export type AdapterOpts = { url?: string; headers?: Record; + /** + * 只用户POST请求,传递的查询参数, + * GET请求默认方body自己转化为查询参数 + */ + params?: Record; body?: Record | 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) { diff --git a/src/query-ai.ts b/src/query-ai.ts deleted file mode 100644 index e6d244f..0000000 --- a/src/query-ai.ts +++ /dev/null @@ -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 }; diff --git a/src/query-browser.ts b/src/query-browser.ts index 0faa4e5..908eedb 100644 --- a/src/query-browser.ts +++ b/src/query-browser.ts @@ -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'; diff --git a/src/query.ts b/src/query.ts index e7b7ad0..c06ff2f 100644 --- a/src/query.ts +++ b/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; 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 { - 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(data: P, options?: DataOpts): Promise> { - return this.query.post(data, options); - } - get(data: P, options?: DataOpts): Promise> { - return this.query.get(data, options); - } -} - -export class ClientQuery extends Query { - constructor(opts?: QueryOpts) { - super({ ...opts, url: opts?.url || '/client/router' }); - } -} +export { adapter }; \ No newline at end of file