init
This commit is contained in:
28
package.json
28
package.json
@@ -1,31 +1,37 @@
|
||||
{
|
||||
"name": "@kevisual/query-awesome",
|
||||
"version": "0.0.4",
|
||||
"name": "@kevisual/api",
|
||||
"version": "0.0.5",
|
||||
"description": "",
|
||||
"main": "mod.ts",
|
||||
"scripts": {
|
||||
"build": "turbo run build",
|
||||
"build": "bun run bun.config.ts",
|
||||
"postbuild": "bun bun.copy.config.mjs"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
"dist",
|
||||
"query",
|
||||
"mod.ts"
|
||||
],
|
||||
"keywords": [],
|
||||
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@10.24.0",
|
||||
"packageManager": "pnpm@10.26.1",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@kevisual/query": "^0.0.31",
|
||||
"@kevisual/router": "^0.0.36",
|
||||
"@kevisual/query": "^0.0.33",
|
||||
"@kevisual/router": "^0.0.41",
|
||||
"@kevisual/types": "^0.0.10",
|
||||
"@kevisual/use-config": "^1.0.21",
|
||||
"@types/bun": "^1.3.3",
|
||||
"@types/node": "^24.10.1",
|
||||
"fast-glob": "^3.3.3",
|
||||
"tsup": "^8.5.1"
|
||||
"@types/bun": "^1.3.5",
|
||||
"@types/node": "^25.0.3",
|
||||
"dotenv": "^17.2.3",
|
||||
"fast-glob": "^3.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"es-toolkit": "^1.43.0",
|
||||
"nanoid": "^5.1.6"
|
||||
}
|
||||
}
|
||||
1179
pnpm-lock.yaml
generated
1179
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,27 +1,21 @@
|
||||
{
|
||||
"$schema": "https://kevisual.xiongxiao.me/root/ai/kevisual/tools/kevisual-sync/schema.json?v=2",
|
||||
"metadata": {
|
||||
"name": "kevisual",
|
||||
"share": "public"
|
||||
},
|
||||
"checkDir": {
|
||||
"src/query": {
|
||||
"url": "https://kevisual.cn/root/ai/code/template/registry/query",
|
||||
"registry": "https://kevisual.cn/root/ai/kevisual/common/query/api",
|
||||
"clone": {
|
||||
".": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"syncDirectory": [
|
||||
"syncd": [
|
||||
{
|
||||
"files": [
|
||||
"**/*"
|
||||
],
|
||||
"ignore": [],
|
||||
"registry": "https://kevisual.cn/root/ai/code/template/registry/query"
|
||||
"registry": ""
|
||||
}
|
||||
],
|
||||
"sync": {
|
||||
"kevisual.json": {
|
||||
"url": "https://kevisual.cn/root/ai/code/template/registry/query/kevisual.json",
|
||||
"type": "none"
|
||||
}
|
||||
}
|
||||
"sync": {}
|
||||
}
|
||||
68
query/query-proxy/index.ts
Normal file
68
query/query-proxy/index.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Query } from '@kevisual/query/query';
|
||||
import { QueryRouterServer, Route } from '@kevisual/router/src/route.ts';
|
||||
export class QueryProxy {
|
||||
query: Query;
|
||||
router: QueryRouterServer;
|
||||
token?: string;
|
||||
constructor(opts?: { query: Query, router?: QueryRouterServer, token?: string }) {
|
||||
this.query = opts?.query || new Query();
|
||||
this.router = opts?.router || new QueryRouterServer();
|
||||
this.token = opts?.token;
|
||||
}
|
||||
/**
|
||||
* 初始化路由
|
||||
* @returns
|
||||
*/
|
||||
async init() {
|
||||
const that = this;
|
||||
const res = await this.query.post<{ list: RouterItem[] }>({ path: "router", key: 'list', token: this.token });
|
||||
if (res.code !== 200) {
|
||||
console.error('Failed to init query proxy router:', res.message);
|
||||
return
|
||||
}
|
||||
const _list = res.data?.list || []
|
||||
for (const item of _list) {
|
||||
if (item.path && item.key) {
|
||||
console.log(`Register route: [${item.path}] ${item.key}`);
|
||||
this.router.route({
|
||||
path: item.path,
|
||||
key: item.key,
|
||||
description: item.description,
|
||||
metadata: item.metadata,
|
||||
}).define(async (ctx) => {
|
||||
const msg = { ...ctx.query };
|
||||
if (msg.token === undefined && that.token !== undefined) {
|
||||
msg.token = that.token;
|
||||
}
|
||||
const r = await that.query.post<any>({ path: item.path, key: item.key, ...msg });
|
||||
ctx.forward(r)
|
||||
}).addTo(that.router);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 列出路由
|
||||
* @param filter
|
||||
* @returns
|
||||
*/
|
||||
async listRoutes(filter?: (item: Route) => boolean) {
|
||||
return this.router.routes.filter(filter || (() => true));
|
||||
}
|
||||
/**
|
||||
* 运行路由
|
||||
* @param msg
|
||||
* @returns
|
||||
*/
|
||||
async run(msg: { id?: string, path?: string, key?: string }) {
|
||||
return await this.router.run(msg);
|
||||
}
|
||||
}
|
||||
|
||||
type RouterItem = {
|
||||
id?: string;
|
||||
path?: string;
|
||||
key?: string;
|
||||
description?: string;
|
||||
middleware?: string[];
|
||||
metadata?: Record<string, any>;
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
* @updatedAt 2025-12-03 10:33:00
|
||||
*/
|
||||
import { Query } from '@kevisual/query';
|
||||
import type { Result } from '@kevisual/query/query';
|
||||
type QueryConfigOpts = {
|
||||
query?: Query;
|
||||
};
|
||||
|
||||
168
readme.md
168
readme.md
@@ -1,3 +1,169 @@
|
||||
# query-awesome
|
||||
# @kevisual/api
|
||||
|
||||
对 kevisual 相关的query router 的模块整理
|
||||
|
||||
包含的模块:
|
||||
|
||||
## query-config - 配置管理模块
|
||||
|
||||
提供配置的增删改查功能,支持默认配置项管理。
|
||||
|
||||
**主要功能:**
|
||||
- 配置的获取、更新、删除
|
||||
- 上传配置管理
|
||||
- 默认配置项支持(upload.json, workspace.json, ai.json, user.json, life.json)
|
||||
- 配置检测功能
|
||||
|
||||
**使用示例:**
|
||||
```typescript
|
||||
import { QueryConfig } from './query-config/query-config';
|
||||
|
||||
const config = new QueryConfig();
|
||||
await config.getConfig({ key: 'upload.json' });
|
||||
await config.updateConfig({ key: 'config.json', data: { setting: true } });
|
||||
```
|
||||
|
||||
## query-secret - 密钥管理模块
|
||||
|
||||
用于管理敏感信息和密钥的存储与检索。
|
||||
|
||||
**主要功能:**
|
||||
- 密钥的存储和获取
|
||||
- 支持按ID或key检索
|
||||
- 密钥列表管理
|
||||
|
||||
## query-proxy - 代理路由模块
|
||||
|
||||
提供动态路由代理功能,可以将请求转发到不同的后端服务。
|
||||
|
||||
**主要功能:**
|
||||
- 动态路由注册
|
||||
- 请求转发代理
|
||||
- 路由列表管理
|
||||
- Token认证支持
|
||||
|
||||
**使用示例:**
|
||||
```typescript
|
||||
import { QueryProxy } from './query-proxy/index';
|
||||
|
||||
const proxy = new QueryProxy({
|
||||
query: new Query(),
|
||||
token: 'your-token'
|
||||
});
|
||||
await proxy.init(); // 初始化路由
|
||||
const result = await proxy.run({ path: 'api', key: 'getData' });
|
||||
```
|
||||
|
||||
## query-upload - 文件上传模块
|
||||
|
||||
功能完整的文件上传解决方案,支持多种上传方式。
|
||||
|
||||
**主要功能:**
|
||||
- 普通文件上传
|
||||
- 分片上传(大文件)
|
||||
- 上传进度跟踪
|
||||
- 文件过滤工具
|
||||
- 文件格式转换
|
||||
|
||||
**核心组件:**
|
||||
- `uploadFiles` - 基础文件上传
|
||||
- `uploadFileChunked` - 分片上传
|
||||
- `UploadProgress` - 进度管理
|
||||
- `filterFiles` - 文件过滤
|
||||
- `toFile` - 格式转换
|
||||
|
||||
**使用示例:**
|
||||
```typescript
|
||||
import { uploadFiles, UploadProgress } from './query-upload/query-upload';
|
||||
|
||||
const progress = new UploadProgress();
|
||||
await uploadFiles(files, {
|
||||
onProgress: (loaded, total) => {
|
||||
console.log(`上传进度: ${loaded}/${total}`);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## query-app - 应用管理模块
|
||||
|
||||
管理应用的注册、获取和列表功能。
|
||||
|
||||
**主要功能:**
|
||||
- 获取应用列表
|
||||
- 获取公开应用
|
||||
- 获取私有应用
|
||||
- 应用定义管理
|
||||
|
||||
## query-shop - 应用商店模块
|
||||
|
||||
应用商店功能,处理应用的安装和获取。
|
||||
|
||||
**主要功能:**
|
||||
- 应用安装
|
||||
- 商店应用管理
|
||||
|
||||
## query-ai - AI对话模块
|
||||
|
||||
集成AI聊天功能,支持多种模型和对话管理。
|
||||
|
||||
**主要功能:**
|
||||
- AI对话(支持GPT等模型)
|
||||
- 模型列表获取
|
||||
- 聊天使用统计
|
||||
- 缓存管理
|
||||
- 使用限制管理
|
||||
|
||||
**使用示例:**
|
||||
```typescript
|
||||
import { QueryAI } from './query-ai/query-ai';
|
||||
|
||||
const ai = new QueryAI({ query: new Query() });
|
||||
const models = await ai.getModelList();
|
||||
const response = await ai.chat(
|
||||
{ message: '你好' },
|
||||
{ username: 'user', model: 'gpt-3.5', group: 'default' }
|
||||
);
|
||||
```
|
||||
|
||||
## query-login - 登录认证模块
|
||||
|
||||
完整的登录认证解决方案,支持token管理和缓存。
|
||||
|
||||
**主要功能:**
|
||||
- 用户登录认证
|
||||
- Token管理(access/refresh token)
|
||||
- 登录状态缓存
|
||||
- 浏览器/Node.js环境支持
|
||||
- 自动token刷新
|
||||
|
||||
**核心组件:**
|
||||
- `QueryLogin` - 主登录类
|
||||
- `LoginCacheStore` - 登录缓存
|
||||
- `Cache` - 通用缓存接口
|
||||
|
||||
## query-resources - 资源管理模块
|
||||
|
||||
管理用户资源的访问和获取。
|
||||
|
||||
**主要功能:**
|
||||
- 资源文件获取
|
||||
- 资源列表管理
|
||||
- 用户认证支持
|
||||
- 文件预览功能
|
||||
|
||||
**使用示例:**
|
||||
```typescript
|
||||
import { QueryResources } from './query-resources/index';
|
||||
|
||||
const resources = new QueryResources({ username: 'user' });
|
||||
const fileList = await resources.getList('images/');
|
||||
const fileContent = await resources.fetchFile('document.pdf');
|
||||
```
|
||||
|
||||
## 架构特点
|
||||
|
||||
- **模块化设计**:每个模块职责单一,可独立使用
|
||||
- **统一接口**:基于 `@kevisual/query` 的统一查询接口
|
||||
- **环境兼容**:支持浏览器和Node.js环境
|
||||
- **类型安全**:完整的TypeScript类型定义
|
||||
- **扩展性**:易于扩展和自定义
|
||||
|
||||
28
test/proxy.ts
Normal file
28
test/proxy.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { QueryProxy } from "../query/query-proxy";
|
||||
import { Query } from "@kevisual/query/query";
|
||||
import dotenv from "dotenv";
|
||||
import util from 'node:util'
|
||||
dotenv.config();
|
||||
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
const token = process.env.KEVISUAL_TOKEN;
|
||||
const url = process.env.KEVISUAL_URL;
|
||||
export const showMore = (obj: any) => {
|
||||
return util.inspect(obj, { showHidden: false, depth: null, colors: true });
|
||||
}
|
||||
const query = new Query({ url: url + '/api/router' });
|
||||
const proxy = new QueryProxy({ query, token });
|
||||
const res = await proxy.init();
|
||||
|
||||
console.log('Proxy Init Result:', showMore(res));
|
||||
|
||||
const routes = await proxy.listRoutes((item) => item.path?.startsWith('router') || false);
|
||||
console.log('Filtered Routes:', showMore(routes));
|
||||
|
||||
await sleep(1000);
|
||||
|
||||
// console.log('Running route [user/me]...', proxy.router.routes.length);
|
||||
|
||||
const run = await proxy.run({ path: 'user', key: 'me' });
|
||||
// const run = await proxy.run({ path: 'router', key: 'list' });
|
||||
console.log('Run Result:', showMore(run));
|
||||
Reference in New Issue
Block a user