import { Query } from '@kevisual/query/query'; import { QueryRouterServer, Route } from '@kevisual/router/src/route.ts'; import { filter } from '@kevisual/js-filter' export type ProxyItem = { title?: string; type?: 'api' | 'context' | 'page'; description?: string; api?: { url: string; }, context?: { key: string; }, page?: {}, where?: string; whereList?: Array<{ title: string; where: string }>; } 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 || this.getDefulatToken(); } getDefulatToken() { try { if (localStorage) { return localStorage.getItem('token') || undefined; } } catch (e) { return undefined; } } /** * 初始化路由 * @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.id) { console.log(`Register route: [${item.path}] ${item?.key}`); this.router.route({ path: item.path, key: item.key || '', id: item.id, 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({ path: item.path, key: item.key, ...msg }); ctx.forward(r) }).addTo(that.router); } } } /** * 列出路由 * @param filter * @param query WHERE metadata.tags CONTAINS 'premium' * @returns */ async listRoutes(filterFn?: (item: Route) => boolean, query?: string) { const routes = this.router.routes.filter(filterFn || (() => true)); if (query) { return filter(routes, query); } return routes; } /** * 运行路由 * @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; }