fix: 更新依赖项版本并优化远程应用连接逻辑
This commit is contained in:
@@ -44,7 +44,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@inquirer/prompts": "^8.2.1",
|
"@inquirer/prompts": "^8.2.1",
|
||||||
"@kevisual/ai": "^0.0.24",
|
"@kevisual/ai": "^0.0.24",
|
||||||
"@kevisual/api": "^0.0.55",
|
"@kevisual/api": "^0.0.57",
|
||||||
"@kevisual/load": "^0.0.6",
|
"@kevisual/load": "^0.0.6",
|
||||||
"@kevisual/local-app-manager": "^0.1.32",
|
"@kevisual/local-app-manager": "^0.1.32",
|
||||||
"@kevisual/logger": "^0.0.4",
|
"@kevisual/logger": "^0.0.4",
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.994.0",
|
"@aws-sdk/client-s3": "^3.995.0",
|
||||||
"@kevisual/js-filter": "^0.0.5",
|
"@kevisual/js-filter": "^0.0.5",
|
||||||
"@kevisual/oss": "^0.0.19",
|
"@kevisual/oss": "^0.0.19",
|
||||||
"@kevisual/video-tools": "^0.0.13",
|
"@kevisual/video-tools": "^0.0.13",
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ export type AssistantConfigData = {
|
|||||||
*/
|
*/
|
||||||
url?: string;
|
url?: string;
|
||||||
}
|
}
|
||||||
token?: string;
|
|
||||||
registry?: string; // https://kevisual.cn
|
registry?: string; // https://kevisual.cn
|
||||||
/**
|
/**
|
||||||
* 前端代理,比如/root/home 转到https://kevisual.cn/root/home
|
* 前端代理,比如/root/home 转到https://kevisual.cn/root/home
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ import glob from 'fast-glob';
|
|||||||
import type { App } from '@kevisual/router';
|
import type { App } from '@kevisual/router';
|
||||||
import { RemoteApp } from '@/module/remote-app/remote-app.ts';
|
import { RemoteApp } from '@/module/remote-app/remote-app.ts';
|
||||||
import { logger } from '@/module/logger.ts';
|
import { logger } from '@/module/logger.ts';
|
||||||
import { getEnvToken } from '@/module/http-token.ts';
|
|
||||||
import { initApi } from '@kevisual/api/proxy'
|
import { initApi } from '@kevisual/api/proxy'
|
||||||
import { Query } from '@kevisual/query';
|
import { Query } from '@kevisual/query';
|
||||||
import { initLightCode } from '@/module/light-code/index.ts';
|
import { initLightCode } from '@/module/light-code/index.ts';
|
||||||
import { ModuleResolver } from './assistant-app-resolve.ts';
|
import { ModuleResolver } from './assistant-app-resolve.ts';
|
||||||
import z from 'zod';
|
import z from 'zod';
|
||||||
|
import { assistantQuery } from '@/app.ts';
|
||||||
|
import { useKey } from '@kevisual/context';
|
||||||
export class AssistantApp extends Manager {
|
export class AssistantApp extends Manager {
|
||||||
config: AssistantConfig;
|
config: AssistantConfig;
|
||||||
pagesPath: string;
|
pagesPath: string;
|
||||||
@@ -23,8 +24,8 @@ export class AssistantApp extends Manager {
|
|||||||
|
|
||||||
constructor(config: AssistantConfig, mainApp?: App) {
|
constructor(config: AssistantConfig, mainApp?: App) {
|
||||||
config.checkMounted();
|
config.checkMounted();
|
||||||
const appsPath = config?.configPath?.appsDir || path.join(process.cwd(), 'apps');
|
const appsPath = config?.configPath?.appsDir
|
||||||
const pagesPath = config?.configPath?.pagesDir || path.join(process.cwd(), 'pages');
|
const pagesPath = config?.configPath?.pagesDir;
|
||||||
const appsConfigPath = config.configPath?.appsConfigPath;
|
const appsConfigPath = config.configPath?.appsConfigPath;
|
||||||
const configFimename = path.basename(appsConfigPath || '');
|
const configFimename = path.basename(appsConfigPath || '');
|
||||||
super({
|
super({
|
||||||
@@ -80,6 +81,12 @@ export class AssistantApp extends Manager {
|
|||||||
return pagesParse;
|
return pagesParse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化远程应用连接,如果配置了远程应用且启用,则尝试连接远程应用服务器,并设置自动重连机制.
|
||||||
|
* 应用暴露
|
||||||
|
* @info 需要登录权限
|
||||||
|
* @param opts
|
||||||
|
*/
|
||||||
async initRemoteApp(opts?: { token?: string, enabled?: boolean }) {
|
async initRemoteApp(opts?: { token?: string, enabled?: boolean }) {
|
||||||
const config = this.config.getConfig();
|
const config = this.config.getConfig();
|
||||||
const share = config?.share;
|
const share = config?.share;
|
||||||
@@ -90,8 +97,17 @@ export class AssistantApp extends Manager {
|
|||||||
this.remoteApp = null;
|
this.remoteApp = null;
|
||||||
this.remoteIsConnected = false;
|
this.remoteIsConnected = false;
|
||||||
}
|
}
|
||||||
const token = config?.token || opts?.token || getEnvToken() as string;
|
let token = opts?.token;
|
||||||
const url = new URL(share.url || 'https://kevisual.cn/ws/proxy');
|
if (!token) {
|
||||||
|
token = await assistantQuery.queryLogin.getToken();
|
||||||
|
}
|
||||||
|
let shareUrl = share?.url;
|
||||||
|
if (!shareUrl) {
|
||||||
|
const _url = new URL(config?.registry || 'https://kevisual.cn/');
|
||||||
|
_url.pathname = '/ws/proxy';
|
||||||
|
shareUrl = _url.toString();
|
||||||
|
}
|
||||||
|
const url = new URL(shareUrl);
|
||||||
const id = config?.app?.id;
|
const id = config?.app?.id;
|
||||||
if (token && url && id) {
|
if (token && url && id) {
|
||||||
const remoteApp = new RemoteApp({
|
const remoteApp = new RemoteApp({
|
||||||
@@ -129,11 +145,22 @@ export class AssistantApp extends Manager {
|
|||||||
this.remoteApp = remoteApp;
|
this.remoteApp = remoteApp;
|
||||||
} else {
|
} else {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
logger.error('Token是远程应用连接必须的参数');
|
logger.error('[remote-app] cli当前未登录,无法连接远程app');
|
||||||
|
} else if (!id) {
|
||||||
|
logger.error('[remote-app] app id不存在,无法连接远程app');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 本地路由初始化,根据配置加载应用的模块。
|
||||||
|
* 加载局域网或者某一个链接的远程路由, 或者代码仓库的动态加载的light-code模块(实时同步远程文件执行)
|
||||||
|
* @info 不需要登录
|
||||||
|
* 配置项说明:
|
||||||
|
* - router.proxy: 数组,包含需要代理的路由信息,每项可以是以下两种类型:
|
||||||
|
* - lightcode: 轻代码模块配置
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
async initRouterApp() {
|
async initRouterApp() {
|
||||||
const config = this.config.getConfig();
|
const config = this.config.getConfig();
|
||||||
const routerProxy = config?.router?.proxy || [];
|
const routerProxy = config?.router?.proxy || [];
|
||||||
@@ -209,6 +236,10 @@ export class AssistantApp extends Manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 动态加载文件插件模块的应用模块
|
||||||
|
* @info 不需要登录
|
||||||
|
*/
|
||||||
async initRoutes() {
|
async initRoutes() {
|
||||||
const routes = this.config.getConfig().routes || [];
|
const routes = this.config.getConfig().routes || [];
|
||||||
for (const route of routes) {
|
for (const route of routes) {
|
||||||
@@ -222,4 +253,53 @@ export class AssistantApp extends Manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 检查本地用户登录状态,如果未登录且存在 CNB_TOKEN,则尝试使用 CNB_TOKEN 登录并更新用户信息
|
||||||
|
*/
|
||||||
|
async checkLocalUser() {
|
||||||
|
const config = this.config.getConfig();
|
||||||
|
const auth = config?.auth;
|
||||||
|
let checkCNB = false;
|
||||||
|
if (!auth?.username) {
|
||||||
|
checkCNB = true;
|
||||||
|
} else {
|
||||||
|
let temp = await assistantQuery.queryLogin.getToken()
|
||||||
|
if (temp) {
|
||||||
|
const isExpired = await assistantQuery.queryLogin.checkTokenValid()
|
||||||
|
console.log('Token 是否过期', isExpired);
|
||||||
|
}
|
||||||
|
logger.info('[assistant] 当前登录用户', auth.username, 'token有效性检查结果', !!temp);
|
||||||
|
}
|
||||||
|
const cnbToken = useKey('CNB_TOKEN');
|
||||||
|
if (!checkCNB && cnbToken) {
|
||||||
|
const res = await assistantQuery.query.post({
|
||||||
|
path: 'user',
|
||||||
|
key: 'cnb-login',
|
||||||
|
payload: {
|
||||||
|
data: {
|
||||||
|
cnbToken: cnbToken,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (res.code === 200) {
|
||||||
|
logger.info('CNB登录成功,用户信息已更新');
|
||||||
|
const resUser = await assistantQuery.queryLogin.beforeSetLoginUser(res.data)
|
||||||
|
if (resUser.code === 200) {
|
||||||
|
const userInfo = resUser.data;
|
||||||
|
auth.username = userInfo.username;
|
||||||
|
auth.share = 'protected'
|
||||||
|
const app = config?.app || {};
|
||||||
|
if (!app?.id) {
|
||||||
|
app.id = 'dev-cnb'
|
||||||
|
}
|
||||||
|
this.config.setConfig({
|
||||||
|
auth,
|
||||||
|
app
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error('CNB登录失败,无法获取用户信息', resUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { useKey } from '@kevisual/use-config';
|
import { IncomingMessage } from 'node:http';
|
||||||
import http from 'node:http';
|
|
||||||
export const error = (msg: string, code = 500) => {
|
export const error = (msg: string, code = 500) => {
|
||||||
return JSON.stringify({ code, message: msg });
|
return JSON.stringify({ code, message: msg });
|
||||||
};
|
};
|
||||||
@@ -16,7 +15,12 @@ const cookie = {
|
|||||||
return cookies;
|
return cookies;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const getToken = async (req: http.IncomingMessage) => {
|
/**
|
||||||
|
* 从请求中获取token,优先级:Authorization header > query parameter > cookie
|
||||||
|
* @param req
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const getToken = async (req: IncomingMessage) => {
|
||||||
let token = (req.headers?.['authorization'] as string) || (req.headers?.['Authorization'] as string) || '';
|
let token = (req.headers?.['authorization'] as string) || (req.headers?.['Authorization'] as string) || '';
|
||||||
const url = new URL(req.url || '', 'http://localhost');
|
const url = new URL(req.url || '', 'http://localhost');
|
||||||
if (!token) {
|
if (!token) {
|
||||||
@@ -32,8 +36,3 @@ export const getToken = async (req: http.IncomingMessage) => {
|
|||||||
|
|
||||||
return { token };
|
return { token };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getEnvToken = () => {
|
|
||||||
const envTokne = useKey('KEVISUAL_TOKEN') || '';
|
|
||||||
return envTokne;
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,7 @@ const codeDemoId = '0e700dc8-90dd-41b7-91dd-336ea51de3d2'
|
|||||||
import { filter } from "@kevisual/js-filter";
|
import { filter } from "@kevisual/js-filter";
|
||||||
import { getHash, getStringHash } from '../file-hash.ts';
|
import { getHash, getStringHash } from '../file-hash.ts';
|
||||||
import { AssistantConfig } from '@/lib.ts';
|
import { AssistantConfig } from '@/lib.ts';
|
||||||
|
import { assistantQuery } from '@/app.ts';
|
||||||
|
|
||||||
const codeDemo = `// 这是一个示例代码文件
|
const codeDemo = `// 这是一个示例代码文件
|
||||||
import {App} from '@kevisual/router';
|
import {App} from '@kevisual/router';
|
||||||
@@ -48,11 +49,11 @@ export const initLightCode = async (opts: Opts) => {
|
|||||||
console.log('初始化 light-code 路由');
|
console.log('初始化 light-code 路由');
|
||||||
const config = opts.config as AssistantInit;
|
const config = opts.config as AssistantInit;
|
||||||
const app = opts.router;
|
const app = opts.router;
|
||||||
const token = config.getConfig()?.token || '';
|
const token = await assistantQuery.getToken();
|
||||||
const query = config.query;
|
const query = config.query;
|
||||||
const sync = opts.sync ?? 'remote';
|
const sync = opts.sync ?? 'remote';
|
||||||
if (!config || !app) {
|
if (!config || !app) {
|
||||||
console.error('initLightCode 缺少必要参数, config 或 app');
|
console.error('[light-code] initLightCode 缺少必要参数, config 或 app');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const lightcodeDir = opts.rootPath;
|
const lightcodeDir = opts.rootPath;
|
||||||
@@ -126,7 +127,7 @@ export const initLightCode = async (opts: Opts) => {
|
|||||||
}
|
}
|
||||||
diffList = findGlob({ cwd: lightcodeDir });
|
diffList = findGlob({ cwd: lightcodeDir });
|
||||||
} else {
|
} else {
|
||||||
console.error('light-code 同步失败', queryRes.message);
|
console.error('[light-code] 同步失败', queryRes.message);
|
||||||
diffList = codeFiles;
|
diffList = codeFiles;
|
||||||
}
|
}
|
||||||
} else if (sync === 'local') {
|
} else if (sync === 'local') {
|
||||||
@@ -191,22 +192,22 @@ export const initLightCode = async (opts: Opts) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('light-code 路由执行失败', runRes.error);
|
console.error('[light-code] 路由执行失败', runRes.error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(`light-code 路由注册成功`, `注册${diffList.length}个路由`);
|
console.log(`[light-code] 路由注册成功`, `注册${diffList.length}个路由`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const clearLightCodeRoutes = (opts: Pick<Opts, 'router'>) => {
|
export const clearLightCodeRoutes = (opts: Pick<Opts, 'router'>) => {
|
||||||
const app = opts.router;
|
const app = opts.router;
|
||||||
if (!app) {
|
if (!app) {
|
||||||
console.error('clearLightCodeRoutes 缺少必要参数, app');
|
console.error('[light-code] clearLightCodeRoutes 缺少必要参数, app');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const routes = app.getList();
|
const routes = app.getList();
|
||||||
for (const route of routes) {
|
for (const route of routes) {
|
||||||
if (route.metadata?.source === 'light-code') {
|
if (route.metadata?.source === 'light-code') {
|
||||||
// console.log(`删除 light-code 路由: ${route.path} ${route.id}`);
|
// console.log(`[light-code] 删除 light-code 路由: ${route.path} ${route.id}`);
|
||||||
app.removeById(route.id);
|
app.removeById(route.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,14 +41,14 @@ app.route({
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await manager.initRemoteApp({ enabled: true, token: ctx.query?.token }).then(() => {
|
try {
|
||||||
|
const res = await manager.initRemoteApp({ enabled: true, token: ctx.query?.token })
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
content: '远程app连接成功',
|
content: '远程app连接成功',
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
} catch (error) {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
content: `远程app连接失败: ${err.message}`,
|
content: '远程app连接失败',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
}).addTo(app);
|
}).addTo(app);
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { app, assistantConfig } from '../../app.ts';
|
import { app, assistantConfig } from '../../app.ts';
|
||||||
|
import { forwardCookie } from './utils/cookie.ts';
|
||||||
|
|
||||||
app.route({
|
app.route({
|
||||||
path: 'admin',
|
path: 'admin',
|
||||||
@@ -23,19 +24,7 @@ app.route({
|
|||||||
password,
|
password,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
forwardCookie(ctx, res);
|
||||||
// 转发上游服务器返回的所有 set-cookie(支持多个 cookie)
|
|
||||||
const setCookieHeaders = res.headers.getSetCookie?.() || [];
|
|
||||||
if (setCookieHeaders.length > 0) {
|
|
||||||
// 设置多个 cookie 到原生 http.ServerResponse
|
|
||||||
ctx.res.setHeader('Set-Cookie', setCookieHeaders);
|
|
||||||
} else {
|
|
||||||
// 兼容旧版本,使用 get 方法
|
|
||||||
const setCookieHeader = res.headers.get('set-cookie');
|
|
||||||
if (setCookieHeader) {
|
|
||||||
ctx.res.setHeader('Set-Cookie', setCookieHeader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const responseData = await res.json();
|
const responseData = await res.json();
|
||||||
console.debug('admin login response', { res: responseData });
|
console.debug('admin login response', { res: responseData });
|
||||||
@@ -73,6 +62,9 @@ app.route({
|
|||||||
key: 'me'
|
key: 'me'
|
||||||
}).define(async (ctx) => {
|
}).define(async (ctx) => {
|
||||||
const token = ctx.query.token;
|
const token = ctx.query.token;
|
||||||
|
if (!token) {
|
||||||
|
ctx.throw(401, 'token is required');
|
||||||
|
}
|
||||||
const res = await assistantConfig.query.post({
|
const res = await assistantConfig.query.post({
|
||||||
path: 'user',
|
path: 'user',
|
||||||
key: 'me',
|
key: 'me',
|
||||||
|
|||||||
14
assistant/src/routes/user/utils/cookie.ts
Normal file
14
assistant/src/routes/user/utils/cookie.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export const forwardCookie = (ctx: any, res: any) => {
|
||||||
|
// 转发上游服务器返回的所有 set-cookie(支持多个 cookie)
|
||||||
|
const setCookieHeaders = res.headers.getSetCookie?.() || [];
|
||||||
|
if (setCookieHeaders.length > 0) {
|
||||||
|
// 设置多个 cookie 到原生 http.ServerResponse
|
||||||
|
ctx.res.setHeader('Set-Cookie', setCookieHeaders);
|
||||||
|
} else {
|
||||||
|
// 兼容旧版本,使用 get 方法
|
||||||
|
const setCookieHeader = res.headers.get('set-cookie');
|
||||||
|
if (setCookieHeader) {
|
||||||
|
ctx.res.setHeader('Set-Cookie', setCookieHeader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,14 +47,14 @@ export const runServer = async (port: number = 51515, listenPath = '127.0.0.1')
|
|||||||
qwenAsr,
|
qwenAsr,
|
||||||
]);
|
]);
|
||||||
const manager = useContextKey('manager', new AssistantApp(assistantConfig, app));
|
const manager = useContextKey('manager', new AssistantApp(assistantConfig, app));
|
||||||
setTimeout(() => {
|
setTimeout(async () => {
|
||||||
manager.load({ runtime: 'client' }).then(() => {
|
await manager.load({ runtime: 'client' });
|
||||||
console.log('Assistant App Loaded');
|
console.log('Assistant App Loaded');
|
||||||
});
|
await manager.checkLocalUser()
|
||||||
manager.initRemoteApp()
|
await manager.initRemoteApp();
|
||||||
manager.initRouterApp()
|
await manager.initRouterApp();
|
||||||
if (runtime.isServer) {
|
if (runtime.isServer) {
|
||||||
manager.initRoutes();
|
await manager.initRoutes();
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const authFilter = async (req: http.IncomingMessage, res: http.ServerResponse) =
|
|||||||
return { code: 200, message: '允许访问根路径' };
|
return { code: 200, message: '允许访问根路径' };
|
||||||
}
|
}
|
||||||
// 放开首页
|
// 放开首页
|
||||||
if (pathname.startsWith('/root/home') || pathname === '/root/cli/docs/') {
|
if (pathname.startsWith('/root/home') || pathname === '/root/cli-center/') {
|
||||||
return { code: 200, message: '允许访问首页' };
|
return { code: 200, message: '允许访问首页' };
|
||||||
}
|
}
|
||||||
// 放开api, 以 /api, /v1, /client, /serve 开头的请求
|
// 放开api, 以 /api, /v1, /client, /serve 开头的请求
|
||||||
@@ -86,7 +86,7 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp
|
|||||||
let noAdmin = !auth.username;
|
let noAdmin = !auth.username;
|
||||||
|
|
||||||
const toSetting = () => {
|
const toSetting = () => {
|
||||||
res.writeHead(302, { Location: `/root/cli/setting/` });
|
res.writeHead(302, { Location: `/root/cli-center/` });
|
||||||
res.end();
|
res.end();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const main = async () => {
|
|||||||
const config = assistantConfig?.getConfig();
|
const config = assistantConfig?.getConfig();
|
||||||
const share = config?.share;
|
const share = config?.share;
|
||||||
if (share && share.enabled !== false) {
|
if (share && share.enabled !== false) {
|
||||||
const token = config?.token;
|
const token = ''
|
||||||
const url = new URL(share.url || 'https://kevisual.cn/ws/proxy');
|
const url = new URL(share.url || 'https://kevisual.cn/ws/proxy');
|
||||||
const id = config?.app?.id;
|
const id = config?.app?.id;
|
||||||
if (!id) {
|
if (!id) {
|
||||||
@@ -14,7 +14,6 @@ const main = async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!token) {
|
if (!token) {
|
||||||
console.error('Token is required for remote app connection.');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const remoteApp = new RemoteApp({
|
const remoteApp = new RemoteApp({
|
||||||
|
|||||||
66
pnpm-lock.yaml
generated
66
pnpm-lock.yaml
generated
@@ -127,8 +127,8 @@ importers:
|
|||||||
assistant:
|
assistant:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@aws-sdk/client-s3':
|
'@aws-sdk/client-s3':
|
||||||
specifier: ^3.994.0
|
specifier: ^3.995.0
|
||||||
version: 3.994.0
|
version: 3.995.0
|
||||||
'@kevisual/js-filter':
|
'@kevisual/js-filter':
|
||||||
specifier: ^0.0.5
|
specifier: ^0.0.5
|
||||||
version: 0.0.5
|
version: 0.0.5
|
||||||
@@ -170,8 +170,8 @@ importers:
|
|||||||
specifier: ^0.0.24
|
specifier: ^0.0.24
|
||||||
version: 0.0.24
|
version: 0.0.24
|
||||||
'@kevisual/api':
|
'@kevisual/api':
|
||||||
specifier: ^0.0.55
|
specifier: ^0.0.57
|
||||||
version: 0.0.55(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
version: 0.0.57(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
'@kevisual/load':
|
'@kevisual/load':
|
||||||
specifier: ^0.0.6
|
specifier: ^0.0.6
|
||||||
version: 0.0.6
|
version: 0.0.6
|
||||||
@@ -459,8 +459,8 @@ packages:
|
|||||||
'@aws-crypto/util@5.2.0':
|
'@aws-crypto/util@5.2.0':
|
||||||
resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==}
|
resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==}
|
||||||
|
|
||||||
'@aws-sdk/client-s3@3.994.0':
|
'@aws-sdk/client-s3@3.995.0':
|
||||||
resolution: {integrity: sha512-zIVQt/XfE2zTFrcPEf8R+KRaRD1++XHMPRhxXM2kVA6NA6Aq/cFCUyYOYYwSbWLF/XeToaX1auYGn3IoZKruPQ==}
|
resolution: {integrity: sha512-r+t8qrQ0m9zoovYOH+wilp/glFRB/E+blsDyWzq2C+9qmyhCAQwaxjLaHM8T/uluAmhtZQIYqOH9ILRnvWtRNw==}
|
||||||
engines: {node: '>=20.0.0'}
|
engines: {node: '>=20.0.0'}
|
||||||
|
|
||||||
'@aws-sdk/client-sso@3.993.0':
|
'@aws-sdk/client-sso@3.993.0':
|
||||||
@@ -555,8 +555,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==}
|
resolution: {integrity: sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==}
|
||||||
engines: {node: '>=20.0.0'}
|
engines: {node: '>=20.0.0'}
|
||||||
|
|
||||||
'@aws-sdk/signature-v4-multi-region@3.994.0':
|
'@aws-sdk/signature-v4-multi-region@3.995.0':
|
||||||
resolution: {integrity: sha512-8y04Lv497KKd7f2TVlm2RaKQaNfnY17ZH8d3m+7sW/3R3BhZvHgWQZyqTb/vcN2ERz1YAnWx6woJyB3ZNFvakw==}
|
resolution: {integrity: sha512-9Qx5JcAucnxnomREPb2D6L8K8GLG0rknt3+VK/BU3qTUynAcV4W21DQ04Z2RKDw+DYpW88lsZpXbVetWST2WUg==}
|
||||||
engines: {node: '>=20.0.0'}
|
engines: {node: '>=20.0.0'}
|
||||||
|
|
||||||
'@aws-sdk/token-providers@3.993.0':
|
'@aws-sdk/token-providers@3.993.0':
|
||||||
@@ -575,8 +575,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw==}
|
resolution: {integrity: sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw==}
|
||||||
engines: {node: '>=20.0.0'}
|
engines: {node: '>=20.0.0'}
|
||||||
|
|
||||||
'@aws-sdk/util-endpoints@3.994.0':
|
'@aws-sdk/util-endpoints@3.995.0':
|
||||||
resolution: {integrity: sha512-L2obUBw4ACMMd1F/SG5LdfPyZ0xJNs9Maifwr3w0uWO+4YvHmk9FfRskfSfE/SLZ9S387oSZ+1xiP7BfVCP/Og==}
|
resolution: {integrity: sha512-aym/pjB8SLbo9w2nmkrDdAAVKVlf7CM71B9mKhjDbJTzwpSFBPHqJIMdDyj0mLumKC0aIVDr1H6U+59m9GvMFw==}
|
||||||
engines: {node: '>=20.0.0'}
|
engines: {node: '>=20.0.0'}
|
||||||
|
|
||||||
'@aws-sdk/util-locate-window@3.965.2':
|
'@aws-sdk/util-locate-window@3.965.2':
|
||||||
@@ -586,8 +586,8 @@ packages:
|
|||||||
'@aws-sdk/util-user-agent-browser@3.972.3':
|
'@aws-sdk/util-user-agent-browser@3.972.3':
|
||||||
resolution: {integrity: sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw==}
|
resolution: {integrity: sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw==}
|
||||||
|
|
||||||
'@aws-sdk/util-user-agent-node@3.972.9':
|
'@aws-sdk/util-user-agent-node@3.972.10':
|
||||||
resolution: {integrity: sha512-JNswdsLdQemxqaSIBL2HRhsHPUBBziAgoi5RQv6/9avmE5g5RSdt1hWr3mHJ7OxqRYf+KeB11ExWbiqfrnoeaA==}
|
resolution: {integrity: sha512-LVXzICPlsheET+sE6tkcS47Q5HkSTrANIlqL1iFxGAY/wRQ236DX/PCAK56qMh9QJoXAfXfoRW0B0Og4R+X7Nw==}
|
||||||
engines: {node: '>=20.0.0'}
|
engines: {node: '>=20.0.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
aws-crt: '>=1.0.0'
|
aws-crt: '>=1.0.0'
|
||||||
@@ -1293,6 +1293,9 @@ packages:
|
|||||||
'@kevisual/api@0.0.55':
|
'@kevisual/api@0.0.55':
|
||||||
resolution: {integrity: sha512-ylWpX12tzAULuvxJHhvt7N21SmVOiIV2eVbKSdJ51soo9XO2J7rGNrLcczQ1vPdaSHzCq+9RlAUyd0ogleGJCA==}
|
resolution: {integrity: sha512-ylWpX12tzAULuvxJHhvt7N21SmVOiIV2eVbKSdJ51soo9XO2J7rGNrLcczQ1vPdaSHzCq+9RlAUyd0ogleGJCA==}
|
||||||
|
|
||||||
|
'@kevisual/api@0.0.57':
|
||||||
|
resolution: {integrity: sha512-U2nz+ckWZ4XGASC08xJT6WKQajhFQDd1iDb9tU1dHZECsvNvIzpHLG7RHFN1vahG1MdbQtppPmHgVTF2Zw7RWg==}
|
||||||
|
|
||||||
'@kevisual/app@0.0.1':
|
'@kevisual/app@0.0.1':
|
||||||
resolution: {integrity: sha512-PEx8P3l0iNSqrz9Ib9kVCYfqNMX6/LfNu+cEafmY6ECP1cV5Vmv+TH2fuasMosKjtbH2fAdDi97sbd29tdEK+g==}
|
resolution: {integrity: sha512-PEx8P3l0iNSqrz9Ib9kVCYfqNMX6/LfNu+cEafmY6ECP1cV5Vmv+TH2fuasMosKjtbH2fAdDi97sbd29tdEK+g==}
|
||||||
|
|
||||||
@@ -5509,7 +5512,7 @@ snapshots:
|
|||||||
'@smithy/util-utf8': 2.3.0
|
'@smithy/util-utf8': 2.3.0
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
'@aws-sdk/client-s3@3.994.0':
|
'@aws-sdk/client-s3@3.995.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@aws-crypto/sha1-browser': 5.2.0
|
'@aws-crypto/sha1-browser': 5.2.0
|
||||||
'@aws-crypto/sha256-browser': 5.2.0
|
'@aws-crypto/sha256-browser': 5.2.0
|
||||||
@@ -5527,11 +5530,11 @@ snapshots:
|
|||||||
'@aws-sdk/middleware-ssec': 3.972.3
|
'@aws-sdk/middleware-ssec': 3.972.3
|
||||||
'@aws-sdk/middleware-user-agent': 3.972.11
|
'@aws-sdk/middleware-user-agent': 3.972.11
|
||||||
'@aws-sdk/region-config-resolver': 3.972.3
|
'@aws-sdk/region-config-resolver': 3.972.3
|
||||||
'@aws-sdk/signature-v4-multi-region': 3.994.0
|
'@aws-sdk/signature-v4-multi-region': 3.995.0
|
||||||
'@aws-sdk/types': 3.973.1
|
'@aws-sdk/types': 3.973.1
|
||||||
'@aws-sdk/util-endpoints': 3.994.0
|
'@aws-sdk/util-endpoints': 3.995.0
|
||||||
'@aws-sdk/util-user-agent-browser': 3.972.3
|
'@aws-sdk/util-user-agent-browser': 3.972.3
|
||||||
'@aws-sdk/util-user-agent-node': 3.972.9
|
'@aws-sdk/util-user-agent-node': 3.972.10
|
||||||
'@smithy/config-resolver': 4.4.6
|
'@smithy/config-resolver': 4.4.6
|
||||||
'@smithy/core': 3.23.2
|
'@smithy/core': 3.23.2
|
||||||
'@smithy/eventstream-serde-browser': 4.2.8
|
'@smithy/eventstream-serde-browser': 4.2.8
|
||||||
@@ -5582,7 +5585,7 @@ snapshots:
|
|||||||
'@aws-sdk/types': 3.973.1
|
'@aws-sdk/types': 3.973.1
|
||||||
'@aws-sdk/util-endpoints': 3.993.0
|
'@aws-sdk/util-endpoints': 3.993.0
|
||||||
'@aws-sdk/util-user-agent-browser': 3.972.3
|
'@aws-sdk/util-user-agent-browser': 3.972.3
|
||||||
'@aws-sdk/util-user-agent-node': 3.972.9
|
'@aws-sdk/util-user-agent-node': 3.972.10
|
||||||
'@smithy/config-resolver': 4.4.6
|
'@smithy/config-resolver': 4.4.6
|
||||||
'@smithy/core': 3.23.2
|
'@smithy/core': 3.23.2
|
||||||
'@smithy/fetch-http-handler': 5.3.9
|
'@smithy/fetch-http-handler': 5.3.9
|
||||||
@@ -5844,7 +5847,7 @@ snapshots:
|
|||||||
'@aws-sdk/types': 3.973.1
|
'@aws-sdk/types': 3.973.1
|
||||||
'@aws-sdk/util-endpoints': 3.993.0
|
'@aws-sdk/util-endpoints': 3.993.0
|
||||||
'@aws-sdk/util-user-agent-browser': 3.972.3
|
'@aws-sdk/util-user-agent-browser': 3.972.3
|
||||||
'@aws-sdk/util-user-agent-node': 3.972.9
|
'@aws-sdk/util-user-agent-node': 3.972.10
|
||||||
'@smithy/config-resolver': 4.4.6
|
'@smithy/config-resolver': 4.4.6
|
||||||
'@smithy/core': 3.23.2
|
'@smithy/core': 3.23.2
|
||||||
'@smithy/fetch-http-handler': 5.3.9
|
'@smithy/fetch-http-handler': 5.3.9
|
||||||
@@ -5882,7 +5885,7 @@ snapshots:
|
|||||||
'@smithy/types': 4.12.0
|
'@smithy/types': 4.12.0
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
'@aws-sdk/signature-v4-multi-region@3.994.0':
|
'@aws-sdk/signature-v4-multi-region@3.995.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@aws-sdk/middleware-sdk-s3': 3.972.11
|
'@aws-sdk/middleware-sdk-s3': 3.972.11
|
||||||
'@aws-sdk/types': 3.973.1
|
'@aws-sdk/types': 3.973.1
|
||||||
@@ -5920,7 +5923,7 @@ snapshots:
|
|||||||
'@smithy/util-endpoints': 3.2.8
|
'@smithy/util-endpoints': 3.2.8
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
'@aws-sdk/util-endpoints@3.994.0':
|
'@aws-sdk/util-endpoints@3.995.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@aws-sdk/types': 3.973.1
|
'@aws-sdk/types': 3.973.1
|
||||||
'@smithy/types': 4.12.0
|
'@smithy/types': 4.12.0
|
||||||
@@ -5939,7 +5942,7 @@ snapshots:
|
|||||||
bowser: 2.13.1
|
bowser: 2.13.1
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
'@aws-sdk/util-user-agent-node@3.972.9':
|
'@aws-sdk/util-user-agent-node@3.972.10':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@aws-sdk/middleware-user-agent': 3.972.11
|
'@aws-sdk/middleware-user-agent': 3.972.11
|
||||||
'@aws-sdk/types': 3.973.1
|
'@aws-sdk/types': 3.973.1
|
||||||
@@ -6630,6 +6633,27 @@ snapshots:
|
|||||||
- react-dom
|
- react-dom
|
||||||
- use-sync-external-store
|
- use-sync-external-store
|
||||||
|
|
||||||
|
'@kevisual/api@0.0.57(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
|
||||||
|
dependencies:
|
||||||
|
'@kevisual/context': 0.0.8
|
||||||
|
'@kevisual/js-filter': 0.0.5
|
||||||
|
'@kevisual/load': 0.0.6
|
||||||
|
'@paralleldrive/cuid2': 3.3.0
|
||||||
|
es-toolkit: 1.44.0
|
||||||
|
eventemitter3: 5.0.4
|
||||||
|
fuse.js: 7.1.0
|
||||||
|
nanoid: 5.1.6
|
||||||
|
path-browserify-esm: 1.0.6
|
||||||
|
sonner: 2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
|
spark-md5: 3.0.2
|
||||||
|
zustand: 5.0.11(@types/react@19.2.10)(react@19.2.4)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/react'
|
||||||
|
- immer
|
||||||
|
- react
|
||||||
|
- react-dom
|
||||||
|
- use-sync-external-store
|
||||||
|
|
||||||
'@kevisual/app@0.0.1(dotenv@17.2.3)':
|
'@kevisual/app@0.0.1(dotenv@17.2.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@kevisual/ai': 0.0.19
|
'@kevisual/ai': 0.0.19
|
||||||
|
|||||||
Reference in New Issue
Block a user