@kevisual/api 0.0.43 → 0.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevisual/api",
3
- "version": "0.0.43",
3
+ "version": "0.0.46",
4
4
  "description": "",
5
5
  "main": "mod.ts",
6
6
  "scripts": {
@@ -21,18 +21,20 @@
21
21
  "type": "module",
22
22
  "devDependencies": {
23
23
  "@kevisual/cache": "^0.0.5",
24
- "@kevisual/code-builder": "^0.0.5",
24
+ "@kevisual/code-builder": "^0.0.6",
25
25
  "@kevisual/query": "^0.0.39",
26
- "@kevisual/router": "^0.0.69",
26
+ "@kevisual/remote-app": "^0.0.2",
27
+ "@kevisual/router": "^0.0.70",
27
28
  "@kevisual/types": "^0.0.12",
28
29
  "@kevisual/use-config": "^1.0.30",
29
- "@types/spark-md5": "^3.0.5",
30
30
  "@types/bun": "^1.3.8",
31
31
  "@types/crypto-js": "^4.2.2",
32
32
  "@types/node": "^25.2.0",
33
+ "@types/spark-md5": "^3.0.5",
33
34
  "crypto-js": "^4.2.0",
34
35
  "dotenv": "^17.2.3",
35
- "fast-glob": "^3.3.3"
36
+ "fast-glob": "^3.3.3",
37
+ "ws": "npm:@kevisual/ws"
36
38
  },
37
39
  "dependencies": {
38
40
  "@kevisual/js-filter": "^0.0.5",
@@ -22,11 +22,38 @@ export class QueryApp extends BaseQuery {
22
22
  data: data,
23
23
  }, opts);
24
24
  }
25
- getApp(data: any, opts?: DataOpts) {
25
+ getApp(data: {
26
+ key?: string;
27
+ version?: string;
28
+ /**
29
+ * 当app不存在,会创建一个新的,
30
+ * 之后上传文件就好了,会执行检测任务
31
+ */
32
+ create?: boolean;
33
+ }, opts?: DataOpts) {
26
34
  return this.query.post({
27
35
  path: 'app',
28
36
  key: 'get',
29
37
  data: data,
30
38
  }, opts);
31
39
  }
40
+ /**
41
+ * 发布应用
42
+ * @param data
43
+ * @param opts
44
+ * @returns
45
+ */
46
+ publichApp(data: {
47
+ id?: string;
48
+ username?: string,
49
+ detect?: boolean,
50
+ appKey?: string;
51
+ version?: string;
52
+ }, opts?: DataOpts) {
53
+ return this.query.post({
54
+ path: 'app',
55
+ key: 'publish',
56
+ data: { detect: true, ...data },
57
+ }, opts);
58
+ }
32
59
  }
@@ -1,5 +1,5 @@
1
1
  import { QueryClient as Query, Result } from '@kevisual/query';
2
- import { QueryRouterServer, type App, type Route } from '@kevisual/router/browser';
2
+ import { QueryRouterServer, type App, type Route, fromJSONSchema, toJSONSchema } from '@kevisual/router/browser';
3
3
  import { filter } from '@kevisual/js-filter'
4
4
  import { EventEmitter } from 'eventemitter3';
5
5
  import { initApi } from './router-api-proxy.ts';
@@ -190,6 +190,7 @@ export class QueryProxy {
190
190
 
191
191
  /**
192
192
  * 初始化路由
193
+ * main
193
194
  * @returns
194
195
  */
195
196
  async init() {
@@ -246,6 +247,8 @@ export class QueryProxy {
246
247
  return
247
248
  }
248
249
  const routes = router.getList();
250
+ // TODO: args
251
+ // const args = fromJSONSchema(r);
249
252
  for (const r of routes) {
250
253
  console.debug(`注册路由: [${r.path}] ${r?.key}`, 'Context');
251
254
  let metadata = r.metadata || {};
@@ -378,6 +381,13 @@ export class QueryProxy {
378
381
  return;
379
382
  }
380
383
  }
384
+ getQueryByViewId(viewId: string): string | undefined {
385
+ const view = this.views.find(v => v.id === viewId);
386
+ if (view) {
387
+ return view.query;
388
+ }
389
+ return undefined;
390
+ }
381
391
  /**
382
392
  * 列出路由
383
393
  * @param filter
@@ -386,14 +396,10 @@ export class QueryProxy {
386
396
  */
387
397
  async listRoutes(filterFn?: (item: Route) => boolean, opts?: { viewId?: string, query?: string }) {
388
398
  let query = opts?.query;
389
- if (opts?.viewId) {
390
- const view = this.views.find(v => v.id === opts.viewId);
391
- if (view) {
392
- query = view.query;
393
- }
394
- } if (opts?.query) {
395
- query = opts.query;
399
+ if (opts?.viewId && !query) {
400
+ query = this.getQueryByViewId(opts.viewId);
396
401
  }
402
+
397
403
  const routes = this.router.routes.filter(filterFn || (() => true));
398
404
  if (query) {
399
405
  if (query.toLocaleUpperCase().startsWith('WHERE')) {
@@ -0,0 +1,2 @@
1
+ import { RemoteApp } from '@Kevisual/remote-app'
2
+
@@ -1,78 +0,0 @@
1
- import { Query, BaseQuery, DataOpts } from '@kevisual/query/query';
2
-
3
- type Message = {
4
- role?: 'user' | 'assistant' | 'system' | 'tool';
5
- content?: string;
6
- name?: string;
7
- };
8
- type PostChat = {
9
- messages?: Message[];
10
- model?: string;
11
- group?: string;
12
- user?: string;
13
- };
14
- type ChatDataOpts = {
15
- id?: string;
16
- title?: string;
17
- messages?: any[];
18
- data?: any;
19
- type?: 'temp' | 'keep' | string;
20
- };
21
- type ChatOpts = {
22
- username: string;
23
- model: string;
24
- /**
25
- * 获取完整消息回复
26
- */
27
- getFull?: boolean;
28
- group: string;
29
- /**
30
- * openai的参数
31
- */
32
- options?: any;
33
- };
34
- declare const appDefine: any;
35
-
36
- declare class QueryApp<T extends Query = Query> extends BaseQuery<T, typeof appDefine> {
37
- constructor(opts?: {
38
- query: T;
39
- });
40
- /**
41
- * 与 AI 进行对话, 调用 GPT 的AI 服务,生成结果,并返回。
42
- * @param data
43
- * @param opts
44
- * @returns
45
- */
46
- postChat(data: PostChat, opts?: DataOpts): any;
47
- /**
48
- * 获取模型列表
49
- * @param opts
50
- * @returns
51
- */
52
- getModelList(data?: {
53
- usernames?: string[];
54
- }, opts?: DataOpts): any;
55
- /**
56
- * 聊天对话模型
57
- * @param data
58
- * @param chatOpts
59
- * @param opts
60
- * @returns
61
- */
62
- chat(data: ChatDataOpts, chatOpts: ChatOpts, opts?: DataOpts): any;
63
- clearConfigCache(opts?: DataOpts): any;
64
- /**
65
- * 获取聊天使用情况
66
- * @param opts
67
- * @returns
68
- */
69
- getChatUsage(opts?: DataOpts): any;
70
- /**
71
- * 清除当前用户模型自己的统计
72
- * @param opts
73
- * @returns
74
- */
75
- clearSelfUsage(opts?: DataOpts): any;
76
- }
77
-
78
- export { QueryApp, appDefine };
package/dist/query-ai.js DELETED
@@ -1,472 +0,0 @@
1
- // node_modules/.pnpm/@kevisual+query@0.0.39/node_modules/@kevisual/query/dist/query-browser.js
2
- var isTextForContentType = (contentType) => {
3
- if (!contentType)
4
- return false;
5
- const textTypes = ["text/", "xml", "html", "javascript", "css", "csv", "plain", "x-www-form-urlencoded", "md"];
6
- return textTypes.some((type) => contentType.includes(type));
7
- };
8
- var adapter = async (opts = {}, overloadOpts) => {
9
- const controller = new AbortController;
10
- const signal = controller.signal;
11
- const isPostFile = opts.isPostFile || false;
12
- let responseType = opts.responseType || "json";
13
- if (opts.isBlob) {
14
- responseType = "blob";
15
- } else if (opts.isText) {
16
- responseType = "text";
17
- }
18
- const timeout = opts.timeout || 60000 * 3;
19
- const timer = setTimeout(() => {
20
- controller.abort();
21
- }, timeout);
22
- let method = overloadOpts?.method || opts?.method || "POST";
23
- let headers = { ...opts?.headers, ...overloadOpts?.headers };
24
- let origin = "";
25
- let url;
26
- if (opts?.url?.startsWith("http")) {
27
- url = new URL(opts.url);
28
- } else {
29
- origin = window?.location?.origin || "http://localhost:51515";
30
- url = new URL(opts.url, origin);
31
- }
32
- const isGet = method === "GET";
33
- const oldSearchParams = url.searchParams;
34
- if (isGet) {
35
- let searchParams = new URLSearchParams({ ...Object.fromEntries(oldSearchParams), ...opts.body });
36
- url.search = searchParams.toString();
37
- } else {
38
- const params = {
39
- ...Object.fromEntries(oldSearchParams),
40
- ...opts.params
41
- };
42
- const searchParams = new URLSearchParams(params);
43
- if (typeof opts.body === "object" && opts.body !== null) {
44
- let body2 = opts.body || {};
45
- if (!params.path && body2?.path) {
46
- searchParams.set("path", body2.path);
47
- if (body2?.key) {
48
- searchParams.set("key", body2.key);
49
- }
50
- }
51
- }
52
- url.search = searchParams.toString();
53
- }
54
- let body = undefined;
55
- if (isGet) {
56
- body = undefined;
57
- } else if (isPostFile) {
58
- body = opts.body;
59
- } else {
60
- headers = {
61
- "Content-Type": "application/json",
62
- ...headers
63
- };
64
- body = JSON.stringify(opts.body);
65
- }
66
- return fetch(url, {
67
- method: method.toUpperCase(),
68
- signal,
69
- body,
70
- ...overloadOpts,
71
- headers
72
- }).then(async (response) => {
73
- const contentType = response.headers.get("Content-Type");
74
- if (responseType === "blob") {
75
- return await response.blob();
76
- }
77
- const isText = responseType === "text";
78
- const isJson = contentType && contentType.includes("application/json");
79
- if (isJson && !isText) {
80
- return await response.json();
81
- } else if (isTextForContentType(contentType)) {
82
- return {
83
- code: response.status,
84
- status: response.status,
85
- data: await response.text()
86
- };
87
- } else {
88
- return response;
89
- }
90
- }).catch((err) => {
91
- if (err.name === "AbortError") {
92
- return {
93
- code: 408,
94
- message: "请求超时"
95
- };
96
- }
97
- return {
98
- code: 500,
99
- message: err.message || "网络错误"
100
- };
101
- }).finally(() => {
102
- clearTimeout(timer);
103
- });
104
- };
105
- var wrapperError = ({ code, message }) => {
106
- const result = {
107
- code: code || 500,
108
- success: false,
109
- message: message || "api request error",
110
- showError: (fn) => {},
111
- noMsg: true
112
- };
113
- return result;
114
- };
115
-
116
- class Query {
117
- adapter;
118
- url;
119
- beforeRequest;
120
- afterResponse;
121
- headers;
122
- timeout;
123
- stop;
124
- qws;
125
- isClient = false;
126
- constructor(opts) {
127
- this.adapter = opts?.adapter || adapter;
128
- const defaultURL = opts?.isClient ? "/client/router" : "/api/router";
129
- this.url = opts?.url || defaultURL;
130
- this.headers = opts?.headers || {
131
- "Content-Type": "application/json"
132
- };
133
- this.timeout = opts?.timeout || 60000 * 3;
134
- if (opts.beforeRequest) {
135
- this.beforeRequest = opts.beforeRequest;
136
- } else {
137
- this.beforeRequest = async (opts2) => {
138
- const token = globalThis?.localStorage?.getItem("token");
139
- if (token) {
140
- opts2.headers = {
141
- ...opts2.headers,
142
- Authorization: `Bearer ${token}`
143
- };
144
- }
145
- return opts2;
146
- };
147
- }
148
- }
149
- setQueryWs(qws) {
150
- this.qws = qws;
151
- }
152
- setStop(stop) {
153
- this.stop = stop;
154
- }
155
- async get(params, options) {
156
- return this.post(params, options);
157
- }
158
- async post(body, options) {
159
- const url = options?.url || this.url;
160
- const { headers, adapter: adapter2, beforeRequest, afterResponse, timeout, ...rest } = options || {};
161
- const _headers = { ...this.headers, ...headers };
162
- const _adapter = adapter2 || this.adapter;
163
- const _beforeRequest = beforeRequest || this.beforeRequest;
164
- const _afterResponse = afterResponse || this.afterResponse;
165
- const _timeout = timeout || this.timeout;
166
- const req = {
167
- url,
168
- headers: _headers,
169
- body,
170
- timeout: _timeout,
171
- ...rest
172
- };
173
- try {
174
- if (_beforeRequest) {
175
- const res = await _beforeRequest(req);
176
- if (res === false) {
177
- return wrapperError({
178
- code: 500,
179
- message: "request is cancel",
180
- req
181
- });
182
- }
183
- }
184
- } catch (e) {
185
- console.error("request beforeFn error", e, req);
186
- return wrapperError({
187
- code: 500,
188
- message: "api request beforeFn error"
189
- });
190
- }
191
- if (this.stop && !options?.noStop) {
192
- const that = this;
193
- await new Promise((resolve) => {
194
- let timer = 0;
195
- const detect = setInterval(() => {
196
- if (!that.stop) {
197
- clearInterval(detect);
198
- resolve(true);
199
- }
200
- timer++;
201
- if (timer > 30) {
202
- console.error("request stop: timeout", req.url, timer);
203
- }
204
- }, 1000);
205
- });
206
- }
207
- return _adapter(req).then(async (res) => {
208
- try {
209
- if (_afterResponse) {
210
- return await _afterResponse(res, {
211
- req,
212
- res,
213
- fetch: adapter2
214
- });
215
- }
216
- return res;
217
- } catch (e) {
218
- console.error("request afterFn error", e, req);
219
- return wrapperError({
220
- code: 500,
221
- message: "api request afterFn error"
222
- });
223
- }
224
- });
225
- }
226
- before(fn) {
227
- this.beforeRequest = fn;
228
- }
229
- after(fn) {
230
- this.afterResponse = fn;
231
- }
232
- async fetchText(urlOrOptions, options) {
233
- let _options = { ...options };
234
- if (typeof urlOrOptions === "string" && !_options.url) {
235
- _options.url = urlOrOptions;
236
- }
237
- if (typeof urlOrOptions === "object") {
238
- _options = { ...urlOrOptions, ..._options };
239
- }
240
- const res = await adapter({
241
- method: "GET",
242
- ..._options,
243
- headers: {
244
- ...this.headers,
245
- ..._options?.headers || {}
246
- }
247
- });
248
- if (res && !res.code) {
249
- return {
250
- code: 200,
251
- data: res
252
- };
253
- }
254
- return res;
255
- }
256
- }
257
-
258
- // node_modules/.pnpm/@kevisual+router@0.0.69/node_modules/@kevisual/router/dist/router-define.js
259
- class Chain {
260
- object;
261
- app;
262
- constructor(object, opts) {
263
- this.object = object;
264
- this.app = opts?.app;
265
- }
266
- get key() {
267
- return this.object.key;
268
- }
269
- get path() {
270
- return this.object.path;
271
- }
272
- setDescription(desc) {
273
- this.object.description = desc;
274
- return this;
275
- }
276
- setMeta(metadata) {
277
- this.object.metadata = metadata;
278
- return this;
279
- }
280
- setPath(path) {
281
- this.object.path = path;
282
- return this;
283
- }
284
- setMiddleware(middleware) {
285
- this.object.middleware = middleware;
286
- return this;
287
- }
288
- setKey(key) {
289
- this.object.key = key;
290
- return this;
291
- }
292
- setId(key) {
293
- this.object.id = key;
294
- return this;
295
- }
296
- setRun(run) {
297
- this.object.run = run;
298
- return this;
299
- }
300
- define(run) {
301
- this.object.run = run;
302
- return this;
303
- }
304
- createRoute() {
305
- this.app.route(this.object).addTo(this.app);
306
- return this;
307
- }
308
- }
309
-
310
- class QueryChain {
311
- obj = {};
312
- query;
313
- omitKeys = ["metadata", "description", "validator"];
314
- constructor(value, opts) {
315
- this.obj = value || {};
316
- this.query = opts?.query;
317
- if (opts?.omitKeys)
318
- this.omitKeys = opts.omitKeys;
319
- }
320
- omit(obj, key = []) {
321
- const newObj = { ...obj };
322
- key.forEach((k) => {
323
- delete newObj[k];
324
- });
325
- return newObj;
326
- }
327
- getKey(queryData) {
328
- const obj = this.omit(this.obj, this.omitKeys);
329
- return {
330
- ...obj,
331
- ...queryData
332
- };
333
- }
334
- post(data, options) {
335
- const _queryData = this.getKey(data);
336
- return this.query.post(_queryData, options);
337
- }
338
- get(data, options) {
339
- const _queryData = this.getKey(data);
340
- return this.query.get(_queryData, options);
341
- }
342
- }
343
- class QueryUtil {
344
- obj;
345
- app;
346
- query;
347
- constructor(object, opts) {
348
- this.obj = object;
349
- this.app = opts?.app;
350
- this.query = opts?.query;
351
- }
352
- static createFormObj(object, opts) {
353
- return new QueryUtil(object, opts);
354
- }
355
- static create(value, opts) {
356
- const obj = value;
357
- return new QueryUtil(obj, opts);
358
- }
359
- get(key) {
360
- return this.obj[key];
361
- }
362
- chain(key, opts) {
363
- const obj = this.obj[key];
364
- let newOpts = { app: this.app, ...opts };
365
- return new QueryUtil.Chain(obj, newOpts);
366
- }
367
- queryChain(key, opts) {
368
- const value = this.obj[key];
369
- let newOpts = { query: this.query, ...opts };
370
- return new QueryUtil.QueryChain(value, newOpts);
371
- }
372
- static Chain = Chain;
373
- static QueryChain = QueryChain;
374
- get routeObject() {
375
- return this.obj;
376
- }
377
- }
378
-
379
- // query/index.ts
380
- var query = new Query;
381
- var clientQuery = new Query({ url: "/client/router" });
382
-
383
- // query/query-ai/defines/ai.ts
384
- var appDefine = QueryUtil.create({
385
- chat: {
386
- path: "ai",
387
- key: "chat",
388
- description: "与 AI 进行对话, 调用 GPT 的AI 服务,生成结果,并返回。"
389
- }
390
- });
391
-
392
- // node_modules/.pnpm/@kevisual+query@0.0.39/node_modules/@kevisual/query/dist/query.js
393
- class BaseQuery {
394
- query;
395
- queryDefine;
396
- constructor(opts) {
397
- if (opts?.clientQuery) {
398
- this.query = opts.clientQuery;
399
- } else {
400
- this.query = opts?.query;
401
- }
402
- if (opts.queryDefine) {
403
- this.queryDefine = opts.queryDefine;
404
- this.queryDefine.query = this.query;
405
- }
406
- }
407
- get chain() {
408
- return this.queryDefine.queryChain;
409
- }
410
- post(data, options) {
411
- return this.query.post(data, options);
412
- }
413
- get(data, options) {
414
- return this.query.get(data, options);
415
- }
416
- }
417
-
418
- // query/query-ai/query-ai.ts
419
- class QueryApp extends BaseQuery {
420
- constructor(opts) {
421
- super({
422
- ...opts,
423
- query: opts?.query,
424
- queryDefine: appDefine
425
- });
426
- }
427
- postChat(data, opts) {
428
- return this.chain("chat").post(data, opts);
429
- }
430
- getModelList(data, opts) {
431
- return this.query.post({
432
- path: "ai",
433
- key: "get-model-list",
434
- data
435
- }, opts);
436
- }
437
- chat(data, chatOpts, opts) {
438
- const { username, model, group, getFull = true } = chatOpts;
439
- if (!username || !model || !group) {
440
- throw new Error("username, model, group is required");
441
- }
442
- return this.query.post({
443
- path: "ai",
444
- key: "chat",
445
- ...chatOpts,
446
- getFull,
447
- data
448
- }, opts);
449
- }
450
- clearConfigCache(opts) {
451
- return this.query.post({
452
- path: "ai",
453
- key: "clear-cache"
454
- }, opts);
455
- }
456
- getChatUsage(opts) {
457
- return this.query.post({
458
- path: "ai",
459
- key: "get-chat-usage"
460
- }, opts);
461
- }
462
- clearSelfUsage(opts) {
463
- return this.query.post({
464
- path: "ai",
465
- key: "clear-chat-limit"
466
- }, opts);
467
- }
468
- }
469
- export {
470
- appDefine,
471
- QueryApp
472
- };
@@ -1,18 +0,0 @@
1
- import { BaseQuery, Query, DataOpts } from '@kevisual/query/query';
2
-
3
- declare const appDefine: any;
4
-
5
- declare const userAppDefine: any;
6
-
7
- declare class QueryApp extends BaseQuery {
8
- appDefine: any;
9
- userAppDefine: any;
10
- constructor(opts?: {
11
- query: Query;
12
- });
13
- getList(data: any, opts?: DataOpts): any;
14
- getPublicApp(data: any, opts?: DataOpts): any;
15
- getApp(data: any, opts?: DataOpts): any;
16
- }
17
-
18
- export { QueryApp, appDefine, userAppDefine };