feat(core): Added core startup and debugging features
- Introduced the tauri-plugin-os, tauri-plugin-shell, and tauri-plugin-process plugins - Added the coreStart function to execute shell commands to start the core - Added the coreLog page and MainConsole component for debugging output - Introduced vue-web-terminal to implement a terminal interface - Removed the old Exe and Group modules and related code
This commit is contained in:
@@ -15,10 +15,14 @@
|
||||
"@tauri-apps/api": "^2",
|
||||
"@tauri-apps/plugin-fs": "~2",
|
||||
"@tauri-apps/plugin-opener": "^2",
|
||||
"@tauri-apps/plugin-os": "~2",
|
||||
"@tauri-apps/plugin-process": "~2",
|
||||
"@tauri-apps/plugin-shell": "~2",
|
||||
"@tauri-apps/plugin-sql": "~2",
|
||||
"vue": "^3.5.21",
|
||||
"vue-i18n": "^11.1.12",
|
||||
"vue-router": "^4.5.1",
|
||||
"vue-web-terminal": "^3.4.1",
|
||||
"vuetify": "^3.10.1",
|
||||
"zod": "^4.1.12"
|
||||
},
|
||||
|
||||
@@ -24,3 +24,6 @@ serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
tauri-plugin-sql = { version = "2", features = ["sqlite"] }
|
||||
tauri-plugin-fs = "2"
|
||||
tauri-plugin-os = "2"
|
||||
tauri-plugin-shell = "2"
|
||||
tauri-plugin-process = "2"
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
"sql:default",
|
||||
"sql:allow-execute",
|
||||
"fs:default",
|
||||
"os:default",
|
||||
"shell:default",
|
||||
"process:default",
|
||||
{
|
||||
"identifier": "fs:allow-write-text-file",
|
||||
"allow": [
|
||||
@@ -26,6 +29,28 @@
|
||||
"path": "$APPCONFIG/*"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"identifier": "fs:allow-exists",
|
||||
"allow": [
|
||||
{
|
||||
"path": "$APPCONFIG/*"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"identifier": "shell:allow-execute",
|
||||
"allow": [
|
||||
{
|
||||
"name": "exec-sh",
|
||||
"cmd": "sh",
|
||||
"args": [
|
||||
"-c",
|
||||
"echo 'Hello World!'"
|
||||
],
|
||||
"sidecar": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
enum Core{
|
||||
XRAY(String),
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
|
||||
pub struct Exe {
|
||||
path: PathBuf,
|
||||
args: Vec<String>,
|
||||
child: Arc<Mutex<Option<Child>>>,
|
||||
pub pid: Arc<Mutex<Option<u32>>>,
|
||||
}
|
||||
|
||||
impl Exe {
|
||||
pub fn new<P: Into<PathBuf>, S: Into<String>>(path: P, args: Vec<S>) -> Self {
|
||||
Self {
|
||||
path: path.into(),
|
||||
args: args.into_iter().map(|s| s.into()).collect(),
|
||||
child: Arc::new(Mutex::new(None)),
|
||||
pid: Arc::new(Mutex::new(None)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start<F, E, X>(
|
||||
&mut self,
|
||||
mut on_stdout: F,
|
||||
mut on_stderr: E,
|
||||
mut on_exit: X,
|
||||
) -> std::io::Result<()>
|
||||
where
|
||||
F: FnMut(String) + Send + 'static,
|
||||
E: FnMut(String) + Send + 'static,
|
||||
X: FnMut(i32) + Send + 'static,
|
||||
{
|
||||
let mut cmd = Command::new(&self.path);
|
||||
cmd.args(&self.args)
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped());
|
||||
|
||||
let mut child = cmd.spawn()?;
|
||||
|
||||
// ✅ 保存 PID
|
||||
let pid = child.id();
|
||||
{
|
||||
*self.pid.lock().unwrap() = Some(pid);
|
||||
}
|
||||
|
||||
// ✅ 异步读取 stdout
|
||||
if let Some(out) = child.stdout.take() {
|
||||
let mut reader = BufReader::new(out);
|
||||
let mut line = String::new();
|
||||
thread::spawn(move || {
|
||||
while let Ok(n) = reader.read_line(&mut line) {
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
on_stdout(line.clone());
|
||||
line.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(err) = child.stderr.take() {
|
||||
let mut reader = BufReader::new(err);
|
||||
let mut line = String::new();
|
||||
thread::spawn(move || {
|
||||
while let Ok(n) = reader.read_line(&mut line) {
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
on_stderr(line.clone());
|
||||
line.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let child_arc = self.child.clone();
|
||||
*child_arc.lock().unwrap() = Some(child);
|
||||
|
||||
let pid_clone = self.pid.clone();
|
||||
thread::spawn(move || {
|
||||
if let Some(mut c) = child_arc.lock().unwrap().take() {
|
||||
match c.wait() {
|
||||
Ok(status) => {
|
||||
let code = status.code().unwrap_or(-1);
|
||||
*pid_clone.lock().unwrap() = None;
|
||||
on_exit(code);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error waiting for process: {e}");
|
||||
*pid_clone.lock().unwrap() = None;
|
||||
on_exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn kill(&self) -> std::io::Result<()> {
|
||||
let mut guard = self.child.lock().unwrap();
|
||||
if let Some(child) = guard.as_mut() {
|
||||
child.kill()?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"No running process",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_alive(&self) -> bool {
|
||||
let mut guard = self.child.lock().unwrap();
|
||||
if let Some(child) = guard.as_mut() {
|
||||
match child.try_wait() {
|
||||
Ok(Some(_)) => false, // 已退出
|
||||
Ok(None) => true, // 仍在运行
|
||||
Err(_) => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_pid(&self) -> Option<u32> {
|
||||
*self.pid.lock().unwrap()
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#[tauri::command]
|
||||
pub fn add_group(
|
||||
group_name: String,
|
||||
group_subscribe_url: Option<String>,
|
||||
group_arguments: Option<String>,
|
||||
) {
|
||||
let message = match (&group_subscribe_url, &group_arguments) {
|
||||
(Some(url), Some(args)) => format!("add_group: {} {} {}", group_name, url, args),
|
||||
(Some(url), None) => format!("add_group: {} {}", group_name, url),
|
||||
(None, Some(args)) => format!("add_group: {} {}", group_name, args),
|
||||
(None, None) => format!("add_group: {}", group_name),
|
||||
};
|
||||
println!("{}", message);
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||
|
||||
use crate::group::add_group;
|
||||
use crate::spary::spary_switch;
|
||||
use tauri_plugin_sql::{Migration, MigrationKind};
|
||||
mod exe;
|
||||
mod group;
|
||||
mod spary;
|
||||
mod cores;
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
@@ -31,6 +27,9 @@ pub fn run() {
|
||||
}
|
||||
];
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_process::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_os::init())
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.plugin(
|
||||
tauri_plugin_sql::Builder::default()
|
||||
@@ -38,7 +37,7 @@ pub fn run() {
|
||||
.build(),
|
||||
)
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.invoke_handler(tauri::generate_handler![spary_switch, add_group])
|
||||
.invoke_handler(tauri::generate_handler![spary_switch])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
mod entity;
|
||||
|
||||
fn main() {
|
||||
spary_lib::run()
|
||||
}
|
||||
|
||||
1
src/components.d.ts
vendored
1
src/components.d.ts
vendored
@@ -11,6 +11,7 @@ declare module 'vue' {
|
||||
AddGroup: typeof import('./components/nodeEdit/addGroup.vue')['default']
|
||||
AddNode: typeof import('./components/nodeEdit/addNode.vue')['default']
|
||||
LanguageSwitcher: typeof import('./components/LanguageSwitcher.vue')['default']
|
||||
MainConsole: typeof import('./components/index/mainConsole.vue')['default']
|
||||
MainDrawer: typeof import('./components/index/mainDrawer.vue')['default']
|
||||
NodeList: typeof import('./components/nodeEdit/nodeList.vue')['default']
|
||||
NodesFloatButton: typeof import('./components/nodeEdit/nodesFloatButton.vue')['default']
|
||||
|
||||
27
src/components/index/mainConsole.vue
Normal file
27
src/components/index/mainConsole.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import { Message, Terminal } from 'vue-web-terminal';
|
||||
|
||||
const initLog: Message[] = [
|
||||
{
|
||||
content: 'Spary.S > '
|
||||
}
|
||||
]
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<terminal
|
||||
name="main-console"
|
||||
theme="dark"
|
||||
:show-header="false"
|
||||
:enable-default-command="false"
|
||||
cursor-style="block"
|
||||
context=""
|
||||
context-suffix=""
|
||||
:init-log="initLog"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -51,6 +51,12 @@ useI18n()
|
||||
<language-switcher/>
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
prepend-icon="mdi-bug"
|
||||
:title="$t('app.debug')"
|
||||
value="coreLog"
|
||||
@click="router.push('/coreLog')"
|
||||
></v-list-item>
|
||||
</v-list>
|
||||
</v-navigation-drawer>
|
||||
</template>
|
||||
|
||||
@@ -13,18 +13,20 @@
|
||||
<script setup lang="ts">
|
||||
import {ref} from "vue";
|
||||
import {invoke} from "@tauri-apps/api/core";
|
||||
import {genConfigFile, removeConfigFile} from "@/utils/bootArgs.ts";
|
||||
import {genConfigFile, removeConfigFile} from "@/utils/coreBootArgs.ts";
|
||||
import {coreStart} from "@/utils/coreBoot.ts";
|
||||
|
||||
const functionStatus = ref<String>("Off");
|
||||
|
||||
function toggleFunctionStatus() {
|
||||
async function toggleFunctionStatus() {
|
||||
functionStatus.value = functionStatus.value === "Off" ? "On" : "Off";
|
||||
spary_switch(functionStatus.value === "On")
|
||||
await spary_switch(functionStatus.value === "On")
|
||||
|
||||
if (functionStatus.value === "On") {
|
||||
genConfigFile()
|
||||
await genConfigFile()
|
||||
await coreStart()
|
||||
} else {
|
||||
removeConfigFile()
|
||||
await removeConfigFile()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"settings": "设置",
|
||||
"add": "添加",
|
||||
"group": "组",
|
||||
"node": "节点"
|
||||
"node": "节点",
|
||||
"debug": "调试"
|
||||
},
|
||||
"spary": {
|
||||
"functionStatus": {
|
||||
|
||||
@@ -15,9 +15,11 @@ import { createApp } from 'vue'
|
||||
|
||||
// Styles
|
||||
import 'unfonts.css'
|
||||
import {createTerminal} from "vue-web-terminal";
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
registerPlugins(app)
|
||||
app.use(createTerminal())
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
11
src/pages/coreLog.vue
Normal file
11
src/pages/coreLog.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main-console />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
5
src/typed-router.d.ts
vendored
5
src/typed-router.d.ts
vendored
@@ -21,6 +21,7 @@ declare module 'vue-router/auto-routes' {
|
||||
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
|
||||
'/addGroup': RouteRecordInfo<'/addGroup', '/addGroup', Record<never, never>, Record<never, never>>,
|
||||
'/addNode/[groupId]': RouteRecordInfo<'/addNode/[groupId]', '/addNode/:groupId', { groupId: ParamValue<true> }, { groupId: ParamValue<false> }>,
|
||||
'/coreLog': RouteRecordInfo<'/coreLog', '/coreLog', Record<never, never>, Record<never, never>>,
|
||||
'/nodes': RouteRecordInfo<'/nodes', '/nodes', Record<never, never>, Record<never, never>>,
|
||||
'/settings': RouteRecordInfo<'/settings', '/settings', Record<never, never>, Record<never, never>>,
|
||||
}
|
||||
@@ -48,6 +49,10 @@ declare module 'vue-router/auto-routes' {
|
||||
routes: '/addNode/[groupId]'
|
||||
views: never
|
||||
}
|
||||
'src/pages/coreLog.vue': {
|
||||
routes: '/coreLog'
|
||||
views: never
|
||||
}
|
||||
'src/pages/nodes.vue': {
|
||||
routes: '/nodes'
|
||||
views: never
|
||||
|
||||
9
src/utils/coreBoot.ts
Normal file
9
src/utils/coreBoot.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import {Command} from '@tauri-apps/plugin-shell';
|
||||
|
||||
export async function coreStart() {
|
||||
let result = await Command.create('exec-sh', [
|
||||
'-c',
|
||||
"echo 'Hello World!'",
|
||||
]).execute();
|
||||
console.log(result);
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
import {writeTextFile, BaseDirectory, remove} from '@tauri-apps/plugin-fs';
|
||||
import {writeTextFile, BaseDirectory, remove, exists} from '@tauri-apps/plugin-fs';
|
||||
export async function removeConfigFile(){
|
||||
try {
|
||||
const tokenExists = await exists('config.json', { baseDir: BaseDirectory.AppConfig });
|
||||
if (!tokenExists) {
|
||||
return;
|
||||
}
|
||||
await remove('config.json', { baseDir: BaseDirectory.AppConfig });
|
||||
} catch (error) {
|
||||
// ignore
|
||||
69
yarn.lock
69
yarn.lock
@@ -697,6 +697,27 @@
|
||||
dependencies:
|
||||
"@tauri-apps/api" "^2.8.0"
|
||||
|
||||
"@tauri-apps/plugin-os@~2":
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-os/-/plugin-os-2.3.1.tgz#2b773d03916fcc272dc23b502f945251bebe64f8"
|
||||
integrity sha512-ty5V8XDUIFbSnrk3zsFoP3kzN+vAufYzalJSlmrVhQTImIZa1aL1a03bOaP2vuBvfR+WDRC6NgV2xBl8G07d+w==
|
||||
dependencies:
|
||||
"@tauri-apps/api" "^2.8.0"
|
||||
|
||||
"@tauri-apps/plugin-process@~2":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-process/-/plugin-process-2.3.0.tgz#43cb71f655ab774314c17344b2948e84d5331f8f"
|
||||
integrity sha512-0DNj6u+9csODiV4seSxxRbnLpeGYdojlcctCuLOCgpH9X3+ckVZIEj6H7tRQ7zqWr7kSTEWnrxtAdBb0FbtrmQ==
|
||||
dependencies:
|
||||
"@tauri-apps/api" "^2.6.0"
|
||||
|
||||
"@tauri-apps/plugin-shell@~2":
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-shell/-/plugin-shell-2.3.1.tgz#e92fb07e7bcf48ba647e5c8ef78e2ea8b469db15"
|
||||
integrity sha512-jjs2WGDO/9z2pjNlydY/F5yYhNsscv99K5lCmU5uKjsVvQ3dRlDhhtVYoa4OLDmktLtQvgvbQjCFibMl6tgGfw==
|
||||
dependencies:
|
||||
"@tauri-apps/api" "^2.8.0"
|
||||
|
||||
"@tauri-apps/plugin-sql@~2":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.npmjs.org/@tauri-apps/plugin-sql/-/plugin-sql-2.3.0.tgz"
|
||||
@@ -1166,6 +1187,15 @@ clean-regexp@^1.0.0:
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
||||
clipboard@^2.0.4:
|
||||
version "2.0.11"
|
||||
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.11.tgz#62180360b97dd668b6b3a84ec226975762a70be5"
|
||||
integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==
|
||||
dependencies:
|
||||
good-listener "^1.2.2"
|
||||
select "^1.1.2"
|
||||
tiny-emitter "^2.0.0"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
|
||||
@@ -1246,6 +1276,11 @@ deep-is@^0.1.3:
|
||||
resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
|
||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||
|
||||
delegate@^3.1.2:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
|
||||
integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
|
||||
|
||||
detect-libc@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz"
|
||||
@@ -1703,6 +1738,13 @@ globals@^16.3.0, globals@^16.4.0:
|
||||
resolved "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz"
|
||||
integrity sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==
|
||||
|
||||
good-listener@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
|
||||
integrity sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==
|
||||
dependencies:
|
||||
delegate "^3.1.2"
|
||||
|
||||
graphemer@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz"
|
||||
@@ -2430,6 +2472,11 @@ scule@^1.3.0:
|
||||
resolved "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz"
|
||||
integrity sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==
|
||||
|
||||
select@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
|
||||
integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==
|
||||
|
||||
semver@^7.3.5, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3, semver@^7.7.2:
|
||||
version "7.7.3"
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz"
|
||||
@@ -2505,6 +2552,11 @@ sync-message-port@^1.0.0:
|
||||
dependencies:
|
||||
"@pkgr/core" "^0.2.9"
|
||||
|
||||
tiny-emitter@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
||||
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
|
||||
|
||||
tinyexec@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz"
|
||||
@@ -2725,6 +2777,13 @@ vue-i18n@^11.1.12:
|
||||
"@intlify/shared" "11.1.12"
|
||||
"@vue/devtools-api" "^6.5.0"
|
||||
|
||||
vue-json-viewer@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/vue-json-viewer/-/vue-json-viewer-3.0.4.tgz#c1d65515e57d4036defbbc18fa942d7fd5fb9a8b"
|
||||
integrity sha512-pnC080rTub6YjccthVSNQod2z9Sl5IUUq46srXtn6rxwhW8QM4rlYn+CTSLFKXWfw+N3xv77Cioxw7B4XUKIbQ==
|
||||
dependencies:
|
||||
clipboard "^2.0.4"
|
||||
|
||||
vue-router@^4.5.1:
|
||||
version "4.5.1"
|
||||
resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz"
|
||||
@@ -2740,7 +2799,15 @@ vue-tsc@^3.0.7:
|
||||
"@volar/typescript" "2.4.23"
|
||||
"@vue/language-core" "3.1.1"
|
||||
|
||||
vue@^3.5.21:
|
||||
vue-web-terminal@^3.4.1:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-web-terminal/-/vue-web-terminal-3.4.1.tgz#f62b33f5df5dc789e86509340286d94d2632d757"
|
||||
integrity sha512-+gU28qClqvIZQlzokcvDS2tbFpGfIJKIPc6dvLm2VYX110c6NOh7mV1YrcUESnaE5VQ9DgxqtIbr1YraEA/GRQ==
|
||||
dependencies:
|
||||
vue "^3.3.4"
|
||||
vue-json-viewer "^3.0.4"
|
||||
|
||||
vue@^3.3.4, vue@^3.5.21:
|
||||
version "3.5.22"
|
||||
resolved "https://registry.npmjs.org/vue/-/vue-3.5.22.tgz"
|
||||
integrity sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==
|
||||
|
||||
Reference in New Issue
Block a user