Compare commits
2 Commits
2cb12644ea
...
91d4fed474
| Author | SHA1 | Date | |
|---|---|---|---|
| 91d4fed474 | |||
| 5395449751 |
@@ -6,87 +6,6 @@ import { AssistantApp, checkFileExists } from '@/lib.ts';
|
|||||||
import { logger } from '@/module/logger.ts';
|
import { logger } from '@/module/logger.ts';
|
||||||
import { LoadApp, StopApp } from '@/module/local-apps/src/modules/manager.ts';
|
import { LoadApp, StopApp } from '@/module/local-apps/src/modules/manager.ts';
|
||||||
|
|
||||||
const runScriptsCommand = new Command('run-scripts')
|
|
||||||
.alias('run')
|
|
||||||
.arguments('<cmd> [env]')
|
|
||||||
.option('-l --local', '使用当前文件夹的package.json中的scripts', false)
|
|
||||||
.description('运行脚本,在assistant.config.json中配置的脚本')
|
|
||||||
.action(async (cmd, env, opts) => {
|
|
||||||
const useLocal = opts.local;
|
|
||||||
const showScripts = cmd === 'show';
|
|
||||||
const showScriptFunc = (scripts: any) => {
|
|
||||||
console.log('可用的本地脚本:');
|
|
||||||
let has = false;
|
|
||||||
Object.keys(scripts).forEach((key) => {
|
|
||||||
console.log(`- ${key}: ${scripts[key]}`);
|
|
||||||
has = true;
|
|
||||||
});
|
|
||||||
if (!has) {
|
|
||||||
console.log('当前未定义任何脚本。');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (useLocal) {
|
|
||||||
const pkgPath = path.join(process.cwd(), 'package.json');
|
|
||||||
if (checkFileExists(pkgPath) === false) {
|
|
||||||
console.error('当前目录下未找到 package.json 文件。');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
||||||
const scripts = pkg.scripts || {};
|
|
||||||
if (showScripts) {
|
|
||||||
showScriptFunc(scripts);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const script = scripts[cmd];
|
|
||||||
if (!script) {
|
|
||||||
console.error(`Script "${cmd}" not found in local package.json.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const command = [script, ...(env ? [env] : [])].join(' ');
|
|
||||||
const res = spawnSync(command, { shell: true, stdio: 'inherit', cwd: assistantConfig.configDir });
|
|
||||||
console.log(`执行 "[${command}]"...`);
|
|
||||||
if (res.error) {
|
|
||||||
console.error(`执行失败 "${cmd}":`, res.error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (res.status !== 0) {
|
|
||||||
console.error(`本地脚本 "${cmd}" 以代码 ${res.status} 退出`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
assistantConfig.checkMounted();
|
|
||||||
const configs = assistantConfig.getCacheAssistantConfig();
|
|
||||||
const scripts = configs?.scripts || {};
|
|
||||||
try {
|
|
||||||
const script = scripts[cmd];
|
|
||||||
if (showScripts) {
|
|
||||||
showScriptFunc(scripts);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!script) {
|
|
||||||
console.error(`Script "${cmd}" not found.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// console.log(`Running script "${script}"...`);
|
|
||||||
const command = [script, ...(env ? [env] : [])].join(' ');
|
|
||||||
// console.log(`Command: ${command}`, env);
|
|
||||||
const res = spawnSync(command, { shell: true, stdio: 'inherit', cwd: assistantConfig.configDir });
|
|
||||||
if (res.error) {
|
|
||||||
console.error(`Error running script "${cmd}":`, res.error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (res.status !== 0) {
|
|
||||||
console.error(`Script "${cmd}" exited with code ${res.status}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(`Script "${cmd}" run successfully.`);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to run script "${cmd}":`, error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
program.addCommand(runScriptsCommand);
|
|
||||||
|
|
||||||
const createRandomApp = (opts: { app: any, package: any, pwd: string, status?: string }) => {
|
const createRandomApp = (opts: { app: any, package: any, pwd: string, status?: string }) => {
|
||||||
const { app, package: packageJson, pwd } = opts;
|
const { app, package: packageJson, pwd } = opts;
|
||||||
if (!app.status) {
|
if (!app.status) {
|
||||||
|
|||||||
@@ -143,19 +143,29 @@ export type AssistantConfigData = {
|
|||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
token?: string;
|
token?: string;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 自定义脚本, asst 启动时会执行这些脚本
|
|
||||||
*/
|
|
||||||
scripts?: {
|
|
||||||
[key: string]: string;
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* 认证和权限配置
|
* 认证和权限配置
|
||||||
* share: protected 需要认证代理访问(默认), public 公开访问, private 私有访问
|
* share: protected 需要认证代理访问(默认), public 公开访问, private 私有访问
|
||||||
* share 是对外共享 pages 目录下的页面
|
* share 是对外共享 pages 目录下的页面
|
||||||
*/
|
*/
|
||||||
auth?: AuthPermission;
|
auth?: AuthPermission;
|
||||||
|
storage?: AssistantStorage[];
|
||||||
};
|
};
|
||||||
|
type AssistantStorage = FileStorage | S3Storage;
|
||||||
|
type FileStorage = {
|
||||||
|
id: string;
|
||||||
|
path: string;
|
||||||
|
type: 'local'
|
||||||
|
}
|
||||||
|
type S3Storage = {
|
||||||
|
id: string;
|
||||||
|
bucket: string;
|
||||||
|
region: string;
|
||||||
|
accessKeyId: string;
|
||||||
|
secretAccessKey: string;
|
||||||
|
endpoint?: string;
|
||||||
|
type: 's3' | 'minio';
|
||||||
|
}
|
||||||
let assistantConfig: AssistantConfigData;
|
let assistantConfig: AssistantConfigData;
|
||||||
type AssistantConfigOptions = {
|
type AssistantConfigOptions = {
|
||||||
configDir?: string;
|
configDir?: string;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export const defaultApiProxy = [
|
|||||||
* @param paths ['/api/router', '/v1' ]
|
* @param paths ['/api/router', '/v1' ]
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const createApiProxy = (api: string, paths: string[] = ['/api', '/v1']) => {
|
export const createApiProxy = (api: string, paths: string[] = ['/api', '/v1']): ProxyInfo[] => {
|
||||||
const pathList = paths.map((item) => {
|
const pathList = paths.map((item) => {
|
||||||
return {
|
return {
|
||||||
path: item,
|
path: item,
|
||||||
|
|||||||
@@ -36,10 +36,14 @@ export type ProxyInfo = {
|
|||||||
*/
|
*/
|
||||||
rootPath?: string;
|
rootPath?: string;
|
||||||
s3?: {
|
s3?: {
|
||||||
bucket: string;
|
/**
|
||||||
region: string;
|
* 如何id存在,使用assistan-config的storage配置
|
||||||
accessKeyId: string;
|
*/
|
||||||
secretAccessKey: string;
|
id?: string;
|
||||||
|
bucket?: string;
|
||||||
|
region?: string;
|
||||||
|
accessKeyId?: string;
|
||||||
|
secretAccessKey?: string;
|
||||||
endpoint?: string;
|
endpoint?: string;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const authFilter = async (req: http.IncomingMessage, res: http.ServerResponse) =
|
|||||||
const auth = _assistantConfig?.auth || {};
|
const auth = _assistantConfig?.auth || {};
|
||||||
const share = auth.share || 'protected';
|
const share = auth.share || 'protected';
|
||||||
const noAdmin = !auth.username;
|
const noAdmin = !auth.username;
|
||||||
if (noAdmin) return false;
|
if (noAdmin) return { code: 500, message: '没有管理员' };
|
||||||
const admin = auth.username;
|
const admin = auth.username;
|
||||||
const admins = auth.admin || [];
|
const admins = auth.admin || [];
|
||||||
if (admin) {
|
if (admin) {
|
||||||
@@ -41,42 +41,43 @@ const authFilter = async (req: http.IncomingMessage, res: http.ServerResponse) =
|
|||||||
const pathname = decodeURIComponent(url.pathname);
|
const pathname = decodeURIComponent(url.pathname);
|
||||||
// 放开 /
|
// 放开 /
|
||||||
if (pathname === '/' || pathname === '/favicon.ico') {
|
if (pathname === '/' || pathname === '/favicon.ico') {
|
||||||
return false;
|
return { code: 200, message: '允许访问根路径' };
|
||||||
}
|
}
|
||||||
// 放开首页
|
// 放开首页
|
||||||
if (pathname.startsWith('/root/home') || pathname === '/root/cli') {
|
if (pathname.startsWith('/root/home') || pathname === '/root/cli/docs/') {
|
||||||
return false;
|
return { code: 200, message: '允许访问首页' };
|
||||||
}
|
}
|
||||||
// 放开api, 以 /api, /v1, /client, /serve 开头的请求
|
// 放开api, 以 /api, /v1, /client, /serve 开头的请求
|
||||||
const openApiPaths = ['/api', '/v1', '/client', '/serve'];
|
const openApiPaths = ['/api', '/v1', '/client', '/serve', '/proxy'];
|
||||||
for (const openPath of openApiPaths) {
|
for (const openPath of openApiPaths) {
|
||||||
if (pathname.startsWith(openPath)) {
|
if (pathname.startsWith(openPath)) {
|
||||||
return false;
|
return { code: 200, message: '允许访问API' };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (share === 'public') {
|
if (share === 'public') {
|
||||||
return false;
|
return { code: 200, message: '公开模式允许访问' };
|
||||||
}
|
}
|
||||||
const { token } = await getToken(req)
|
const { token } = await getToken(req)
|
||||||
if (!token) {
|
if (!token) {
|
||||||
// no token 转到登录页面
|
// no token 转到登录页面
|
||||||
res.writeHead(302, { Location: `/root/home/` });
|
res.writeHead(302, { Location: `/root/home/` });
|
||||||
res.end();
|
res.end();
|
||||||
return false;
|
return { code: 500, message: '未登录' };
|
||||||
}
|
}
|
||||||
const tokenUser = await getTokenUserCache(token);
|
const tokenUser = await getTokenUserCache(token);
|
||||||
|
console.log('authFilter tokenUser', tokenUser, token);
|
||||||
if (share === 'protected' && tokenUser?.code === 200) {
|
if (share === 'protected' && tokenUser?.code === 200) {
|
||||||
return false;
|
return { code: 200, message: '受保护模式已登录允许访问' };
|
||||||
}
|
}
|
||||||
if (share === 'private') {
|
if (share === 'private') {
|
||||||
if (tokenUser?.code === 200) {
|
if (tokenUser?.code === 200) {
|
||||||
const username = tokenUser?.data?.username;
|
const username = tokenUser?.data?.username;
|
||||||
if (admins.includes(username)) {
|
if (admins.includes(username)) {
|
||||||
return false;
|
return { code: 200, message: '私有模式管理员允许访问' };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return { code: 500, message: '没有权限访问' };
|
||||||
}
|
}
|
||||||
export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResponse) => {
|
export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResponse) => {
|
||||||
const _assistantConfig = assistantConfig.getCacheAssistantConfig();
|
const _assistantConfig = assistantConfig.getCacheAssistantConfig();
|
||||||
@@ -123,10 +124,18 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp
|
|||||||
// res.setHeader('Access-Control-Allow-Origin', '*');
|
// res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
// res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
// res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
||||||
// res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
|
// res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
|
||||||
|
if (apiBackendProxy.s3?.id) {
|
||||||
|
const storage = _assistantConfig?.storage || []
|
||||||
|
const storageConfig = storage.find((item) => item.id === apiBackendProxy.s3?.id);
|
||||||
|
apiBackendProxy.s3 = {
|
||||||
|
...storageConfig,
|
||||||
|
...apiBackendProxy.s3,
|
||||||
|
}
|
||||||
|
}
|
||||||
return proxy(req, res, {
|
return proxy(req, res, {
|
||||||
path: apiBackendProxy.path,
|
path: apiBackendProxy.path,
|
||||||
target: apiBackendProxy.target,
|
target: apiBackendProxy.target,
|
||||||
...apiBackendProxy
|
...apiBackendProxy,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
logger.debug('proxyRoute handle by router', { url: req.url }, noAdmin);
|
logger.debug('proxyRoute handle by router', { url: req.url }, noAdmin);
|
||||||
@@ -172,7 +181,8 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const filter = await authFilter(req, res);
|
const filter = await authFilter(req, res);
|
||||||
if (filter) {
|
if (filter.code !== 200) {
|
||||||
|
console.log('auth filter deny', filter);
|
||||||
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
||||||
return res.end(renderNoAuthAndLogin('Not Authorized Proxy'));
|
return res.end(renderNoAuthAndLogin('Not Authorized Proxy'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ let proxy = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const basename = isDev ? undefined : `${pkgs.basename}`;
|
const basename = isDev ? undefined : `${pkgs.basename}`;
|
||||||
|
console.log('Astro Config Basename:', basename);
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
base: basename,
|
base: basename,
|
||||||
integrations: [
|
integrations: [
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"pub": "envision deploy ./dist -k cli -v 0.0.3 -u -y y",
|
"pub": "envision deploy ./dist -k cli -v 0.0.4 -u -y y",
|
||||||
"slide:dev": "slidev --open slides/index.md",
|
"slide:dev": "slidev --open slides/index.md",
|
||||||
"slide:build": "slidev build slides/index.md --base /root/cli-slide/",
|
"slide:build": "slidev build slides/index.md --base /root/cli-slide/",
|
||||||
"slide:pub": "envision deploy ./slides/dist -k cli-slide -v 0.0.3 -u",
|
"slide:pub": "envision deploy ./slides/dist -k cli-slide -v 0.0.4 -u",
|
||||||
"ui": "pnpm dlx shadcn@latest add "
|
"ui": "pnpm dlx shadcn@latest add "
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
@@ -21,23 +21,23 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^4.3.13",
|
"@astrojs/mdx": "^4.3.13",
|
||||||
"@astrojs/react": "^4.4.2",
|
"@astrojs/react": "^4.4.2",
|
||||||
"@astrojs/sitemap": "^3.6.0",
|
"@astrojs/sitemap": "^3.7.0",
|
||||||
"@astrojs/vue": "^5.1.3",
|
"@astrojs/vue": "^5.1.4",
|
||||||
"@kevisual/api": "^0.0.5",
|
"@kevisual/api": "^0.0.17",
|
||||||
"@kevisual/context": "^0.0.4",
|
"@kevisual/context": "^0.0.4",
|
||||||
"@kevisual/kv-code": "^0.0.4",
|
"@kevisual/kv-code": "^0.0.4",
|
||||||
"@kevisual/query": "^0.0.33",
|
"@kevisual/query": "^0.0.35",
|
||||||
"@kevisual/query-login": "^0.0.7",
|
"@kevisual/query-login": "^0.0.7",
|
||||||
"@kevisual/registry": "^0.0.1",
|
"@kevisual/registry": "^0.0.1",
|
||||||
"@radix-ui/react-slot": "^1.2.4",
|
"@radix-ui/react-slot": "^1.2.4",
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"@uiw/react-md-editor": "^4.0.11",
|
"@uiw/react-md-editor": "^4.0.11",
|
||||||
"antd": "^6.1.1",
|
"antd": "^6.2.0",
|
||||||
"astro": "^5.16.6",
|
"astro": "^5.16.11",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"es-toolkit": "^1.43.0",
|
"es-toolkit": "^1.44.0",
|
||||||
"github-markdown-css": "^5.8.1",
|
"github-markdown-css": "^5.8.1",
|
||||||
"highlight.js": "^11.11.1",
|
"highlight.js": "^11.11.1",
|
||||||
"lucide-react": "^0.562.0",
|
"lucide-react": "^0.562.0",
|
||||||
@@ -49,20 +49,20 @@
|
|||||||
"react-toastify": "^11.0.5",
|
"react-toastify": "^11.0.5",
|
||||||
"tailwind-merge": "^3.4.0",
|
"tailwind-merge": "^3.4.0",
|
||||||
"vue": "^3.5.26",
|
"vue": "^3.5.26",
|
||||||
"zustand": "^5.0.9"
|
"zustand": "^5.0.10"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@kevisual/types": "^0.0.10",
|
"@kevisual/types": "^0.0.11",
|
||||||
"@types/react": "^19.2.7",
|
"@types/react": "^19.2.8",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"tailwindcss": "^4.1.18",
|
"tailwindcss": "^4.1.18",
|
||||||
"tw-animate-css": "^1.4.0"
|
"tw-animate-css": "^1.4.0"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.26.1",
|
"packageManager": "pnpm@10.28.0",
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
"@tailwindcss/oxide",
|
"@tailwindcss/oxide",
|
||||||
"esbuild",
|
"esbuild",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { query, queryLogin } from '@/modules/query';
|
import { clientQuery, queryLogin } from '@/modules/query';
|
||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
type SettingState = {
|
type SettingState = {
|
||||||
@@ -12,7 +12,7 @@ export const useStore = create<SettingState>((set => ({
|
|||||||
username: undefined,
|
username: undefined,
|
||||||
config: undefined,
|
config: undefined,
|
||||||
initAdmin: async () => {
|
initAdmin: async () => {
|
||||||
const res = await query.post({
|
const res = await clientQuery.post({
|
||||||
path: 'config'
|
path: 'config'
|
||||||
})
|
})
|
||||||
console.log('initAdmin', res);
|
console.log('initAdmin', res);
|
||||||
@@ -25,7 +25,7 @@ export const useStore = create<SettingState>((set => ({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
login: async (username: string, password: string) => {
|
login: async (username: string, password: string) => {
|
||||||
const res = await query.post({
|
const res = await clientQuery.post({
|
||||||
path: 'admin',
|
path: 'admin',
|
||||||
key: 'login',
|
key: 'login',
|
||||||
username,
|
username,
|
||||||
@@ -40,7 +40,7 @@ export const useStore = create<SettingState>((set => ({
|
|||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
saveConfig: async (config: any) => {
|
saveConfig: async (config: any) => {
|
||||||
const res = await query.post({
|
const res = await clientQuery.post({
|
||||||
path: 'config',
|
path: 'config',
|
||||||
key: 'set',
|
key: 'set',
|
||||||
data: config
|
data: config
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ export const query = new QueryClient({
|
|||||||
url: getUrl()
|
url: getUrl()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const clientQuery = new QueryClient({
|
||||||
|
url: '/client/router'
|
||||||
|
});
|
||||||
|
|
||||||
export const remoteQuery = new Query({
|
export const remoteQuery = new Query({
|
||||||
url: '/api/router'
|
url: '/api/router'
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ import Html from '@/components/html.astro';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-grid">
|
<div class="card-grid">
|
||||||
<a href="./docs/" class="card">
|
<a href={"/root/cli/docs/"} class="card">
|
||||||
<div class="card-icon">📚</div>
|
<div class="card-icon">📚</div>
|
||||||
<h2>文档中心</h2>
|
<h2>文档中心</h2>
|
||||||
<p>查看完整的使用文档和API参考</p>
|
<p>查看完整的使用文档和API参考</p>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="./settings/" class="card">
|
<a href={"/root/cli/settings/"} class="card">
|
||||||
<div class="card-icon">⚙️</div>
|
<div class="card-icon">⚙️</div>
|
||||||
<h2>设置中心</h2>
|
<h2>设置中心</h2>
|
||||||
<p>配置和管理您的应用设置</p>
|
<p>配置和管理您的应用设置</p>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@kevisual/cli",
|
"name": "@kevisual/cli",
|
||||||
"version": "0.0.85",
|
"version": "0.0.87",
|
||||||
"description": "envision 命令行工具",
|
"description": "envision 命令行工具",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"basename": "/root/cli",
|
"basename": "/root/cli",
|
||||||
@@ -44,20 +44,18 @@
|
|||||||
"@inquirer/prompts": "^8.2.0",
|
"@inquirer/prompts": "^8.2.0",
|
||||||
"@kevisual/app": "^0.0.2",
|
"@kevisual/app": "^0.0.2",
|
||||||
"@kevisual/context": "^0.0.4",
|
"@kevisual/context": "^0.0.4",
|
||||||
"@kevisual/hot-api": "^0.0.3",
|
|
||||||
"@kevisual/use-config": "^1.0.28",
|
"@kevisual/use-config": "^1.0.28",
|
||||||
|
|
||||||
"@types/busboy": "^1.5.4",
|
"@types/busboy": "^1.5.4",
|
||||||
"busboy": "^1.6.0",
|
"busboy": "^1.6.0",
|
||||||
"eventemitter3": "^5.0.1",
|
"eventemitter3": "^5.0.1",
|
||||||
"lowdb": "^7.0.1",
|
"lowdb": "^7.0.1",
|
||||||
"lru-cache": "^11.2.4",
|
"lru-cache": "^11.2.4",
|
||||||
"micromatch": "^4.0.8",
|
"micromatch": "^4.0.8",
|
||||||
"pm2": "^6.0.14",
|
|
||||||
"semver": "^7.7.3",
|
"semver": "^7.7.3",
|
||||||
"unstorage": "^1.17.4"
|
"unstorage": "^1.17.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"pm2": "^6.0.14",
|
||||||
"@kevisual/dts": "^0.0.3",
|
"@kevisual/dts": "^0.0.3",
|
||||||
"@kevisual/load": "^0.0.6",
|
"@kevisual/load": "^0.0.6",
|
||||||
"@kevisual/logger": "^0.0.4",
|
"@kevisual/logger": "^0.0.4",
|
||||||
|
|||||||
2264
pnpm-lock.yaml
generated
2264
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1 +1,5 @@
|
|||||||
# 一个简单的cli工具
|
# 一个简单的cli工具
|
||||||
|
|
||||||
|
```
|
||||||
|
npm i @kevisual/cli -g --registry=https://npm.cnb.cool/kevisual/registry/-/packages/
|
||||||
|
```
|
||||||
@@ -111,6 +111,7 @@ const command = new Command('deploy')
|
|||||||
}
|
}
|
||||||
const uploadDirectory = isDirectory ? directory : path.dirname(directory);
|
const uploadDirectory = isDirectory ? directory : path.dirname(directory);
|
||||||
const res = await uploadFiles(_relativeFiles, uploadDirectory, { key, version, username: org, noCheckAppFiles: !noCheck, directory: options.directory });
|
const res = await uploadFiles(_relativeFiles, uploadDirectory, { key, version, username: org, noCheckAppFiles: !noCheck, directory: options.directory });
|
||||||
|
logger.debug('upload res', res);
|
||||||
if (res?.code === 200) {
|
if (res?.code === 200) {
|
||||||
res.data?.upload?.map?.((d) => {
|
res.data?.upload?.map?.((d) => {
|
||||||
console.log(chalk.green('uploaded file', d?.name, d?.path));
|
console.log(chalk.green('uploaded file', d?.name, d?.path));
|
||||||
@@ -119,6 +120,7 @@ const command = new Command('deploy')
|
|||||||
key: key,
|
key: key,
|
||||||
version: version,
|
version: version,
|
||||||
});
|
});
|
||||||
|
logger.debug('queryAppVersion res', res2);
|
||||||
if (res2.code !== 200) {
|
if (res2.code !== 200) {
|
||||||
console.error(chalk.red('查询应用版本失败'), res2.message, key);
|
console.error(chalk.red('查询应用版本失败'), res2.message, key);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
import { useKey } from '@kevisual/use-config';
|
||||||
|
|
||||||
export const envisionPath = path.join(os.homedir(), '.config', 'envision');
|
export const envisionPath = path.join(os.homedir(), '.config', 'envision');
|
||||||
const configPath = path.join(os.homedir(), '.config', 'envision', 'config.json');
|
const configPath = path.join(os.homedir(), '.config', 'envision', 'config.json');
|
||||||
@@ -37,5 +38,8 @@ export const writeConfig = (config: Record<string, any>) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getEnvToken = () => {
|
export const getEnvToken = () => {
|
||||||
return process.env.KEVISUAL_TOKEN || '';
|
const envTokne = useKey('KEVISUAL_TOKEN') || '';
|
||||||
|
console.log('getEnvToken', envTokne);
|
||||||
|
// return envTokne;
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { logger } from '@/module/logger.ts';
|
||||||
import { query } from '@/module/query.ts';
|
import { query } from '@/module/query.ts';
|
||||||
import { DataOpts } from '@kevisual/query';
|
import { DataOpts } from '@kevisual/query';
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ export const queryApp = async (params: QueryAppParams, opts?: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const queryAppVersion = async (params: { key?: string; version?: string; id?: string }, opts?: DataOpts) => {
|
export const queryAppVersion = async (params: { key?: string; version?: string; id?: string }, opts?: DataOpts) => {
|
||||||
|
logger.debug('queryAppVersion params', params, query.url);
|
||||||
return await query.post(
|
return await query.post(
|
||||||
{
|
{
|
||||||
path: 'app',
|
path: 'app',
|
||||||
|
|||||||
Reference in New Issue
Block a user