Can view from web UI XML definition of domains

This commit is contained in:
Pierre HUBERT 2023-12-08 18:14:01 +01:00
parent 74b77be013
commit 82447a0018
13 changed files with 632 additions and 135 deletions

View File

@ -99,6 +99,20 @@ impl Handler<GetDomainXMLReq> for LibVirtActor {
}
}
#[derive(Message)]
#[rtype(result = "anyhow::Result<String>")]
pub struct GetSourceDomainXMLReq(pub XMLUuid);
impl Handler<GetSourceDomainXMLReq> for LibVirtActor {
type Result = anyhow::Result<String>;
fn handle(&mut self, msg: GetSourceDomainXMLReq, _ctx: &mut Self::Context) -> Self::Result {
log::debug!("Get domain source XML:\n{}", msg.0.as_string());
let domain = Domain::lookup_by_uuid_string(&self.m, &msg.0.as_string())?;
Ok(domain.get_xml_desc(VIR_DOMAIN_XML_SECURE)?)
}
}
#[derive(Message)]
#[rtype(result = "anyhow::Result<XMLUuid>")]
pub struct DefineDomainReq(pub DomainXML);

View File

@ -73,6 +73,21 @@ pub async fn get_single(client: LibVirtReq, id: web::Path<SingleVMUUidReq>) -> H
}))
}
/// Get the XML configuration of a VM
pub async fn get_single_src_def(client: LibVirtReq, id: web::Path<SingleVMUUidReq>) -> HttpResult {
let info = match client.get_single_domain_xml(id.uid).await {
Ok(i) => i,
Err(e) => {
log::error!("Failed to get domain source XML! {e}");
return Ok(HttpResponse::InternalServerError().json(e.to_string()));
}
};
Ok(HttpResponse::Ok()
.content_type("application/xml")
.body(info))
}
/// Update a VM information
pub async fn update(
client: LibVirtReq,

View File

@ -28,6 +28,13 @@ impl LibVirtClient {
self.0.send(libvirt_actor::GetDomainXMLReq(id)).await?
}
/// Get the source XML configuration of a single domain
pub async fn get_single_domain_xml(&self, id: XMLUuid) -> anyhow::Result<String> {
self.0
.send(libvirt_actor::GetSourceDomainXMLReq(id))
.await?
}
/// Update a domain
pub async fn update_domain(&self, xml: DomainXML) -> anyhow::Result<XMLUuid> {
self.0.send(libvirt_actor::DefineDomainReq(xml)).await?

View File

@ -153,6 +153,10 @@ async fn main() -> std::io::Result<()> {
.route("/api/vm/create", web::post().to(vm_controller::create))
.route("/api/vm/list", web::get().to(vm_controller::list_all))
.route("/api/vm/{uid}", web::get().to(vm_controller::get_single))
.route(
"/api/vm/{uid}/src",
web::get().to(vm_controller::get_single_src_def),
)
.route(
"/api/vm/{uid}/autostart",
web::get().to(vm_controller::get_autostart),

View File

@ -25,19 +25,21 @@
"@types/node": "^16.18.48",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"@types/react-syntax-highlighter": "^15.5.11",
"@types/uuid": "^9.0.5",
"filesize": "^10.0.12",
"humanize-duration": "^3.29.0",
"mui-file-input": "^3.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-imask": "^7.1.3",
"react-router-dom": "^6.15.0",
"react-scripts": "5.0.1",
"react-syntax-highlighter": "^15.5.0",
"react-vnc": "^1.0.0",
"typescript": "^4.9.5",
"uuid": "^9.0.1",
"web-vitals": "^2.1.4"
"web-vitals": "^2.1.4",
"xml-formatter": "^3.6.0"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@ -1972,19 +1974,6 @@
"node": ">=6.9.0"
}
},
"node_modules/@babel/runtime-corejs3": {
"version": "7.23.5",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.5.tgz",
"integrity": "sha512-7+ziVclejQTLYhXl+Oi1f6gTGD1XDCeLa4R472TNGQxb08zbEJ0OdNoh5Piz+57Ltmui6xR88BXR4gS3/Toslw==",
"license": "MIT",
"dependencies": {
"core-js-pure": "^3.30.2",
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz",
@ -4558,6 +4547,15 @@
"@types/node": "*"
}
},
"node_modules/@types/hast": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz",
"integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==",
"license": "MIT",
"dependencies": {
"@types/unist": "^2"
}
},
"node_modules/@types/html-minifier-terser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@ -4687,6 +4685,15 @@
"@types/react": "*"
}
},
"node_modules/@types/react-syntax-highlighter": {
"version": "15.5.11",
"resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.11.tgz",
"integrity": "sha512-ZqIJl+Pg8kD+47kxUjvrlElrraSUrYa4h0dauY/U/FTUuprSCqvUj+9PNQNQzVc6AJgIWUUxn87/gqsMHNbRjw==",
"license": "MIT",
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/react-transition-group": {
"version": "4.4.6",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz",
@ -4771,6 +4778,12 @@
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz",
"integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g=="
},
"node_modules/@types/unist": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
"integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==",
"license": "MIT"
},
"node_modules/@types/uuid": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.5.tgz",
@ -6234,6 +6247,36 @@
"node": ">=10"
}
},
"node_modules/character-entities": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
"integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/character-entities-legacy": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
"integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/character-reference-invalid": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
"integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/check-types": {
"version": "11.2.2",
"resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz",
@ -6401,6 +6444,16 @@
"node": ">= 0.8"
}
},
"node_modules/comma-separated-tokens": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
"integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/commander": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
@ -8579,6 +8632,19 @@
"reusify": "^1.0.4"
}
},
"node_modules/fault": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
"integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
"license": "MIT",
"dependencies": {
"format": "^0.2.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/faye-websocket": {
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
@ -8954,6 +9020,14 @@
"node": ">= 6"
}
},
"node_modules/format": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
"integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==",
"engines": {
"node": ">=0.4.x"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@ -9347,6 +9421,33 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hast-util-parse-selector": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
"integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hastscript": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
"integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
"license": "MIT",
"dependencies": {
"@types/hast": "^2.0.0",
"comma-separated-tokens": "^1.0.0",
"hast-util-parse-selector": "^2.0.0",
"property-information": "^5.0.0",
"space-separated-tokens": "^1.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@ -9355,6 +9456,15 @@
"he": "bin/he"
}
},
"node_modules/highlight.js": {
"version": "10.7.3",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
"integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
"license": "BSD-3-Clause",
"engines": {
"node": "*"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -9655,18 +9765,6 @@
"node": ">= 4"
}
},
"node_modules/imask": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/imask/-/imask-7.1.3.tgz",
"integrity": "sha512-jZCqTI5Jgukhl2ff+znBQd8BiHOTlnFYCIgggzHYDdoJsHmSSWr1BaejcYBxsjy4ZIs8Rm0HhbOxQcobcdESRQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime-corejs3": "^7.22.6"
},
"engines": {
"npm": ">=4.0.0"
}
},
"node_modules/immer": {
"version": "9.0.21",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
@ -9781,6 +9879,30 @@
"node": ">= 10"
}
},
"node_modules/is-alphabetical": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
"integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/is-alphanumerical": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
"integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
"license": "MIT",
"dependencies": {
"is-alphabetical": "^1.0.0",
"is-decimal": "^1.0.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@ -9901,6 +10023,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-decimal": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
"integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/is-docker": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
@ -9975,6 +10107,16 @@
"node": ">=0.10.0"
}
},
"node_modules/is-hexadecimal": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
"integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/is-map": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
@ -12613,6 +12755,20 @@
"tslib": "^2.0.3"
}
},
"node_modules/lowlight": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
"integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
"license": "MIT",
"dependencies": {
"fault": "^1.0.0",
"highlight.js": "~10.7.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@ -13354,6 +13510,24 @@
"node": ">=6"
}
},
"node_modules/parse-entities": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
"integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
"license": "MIT",
"dependencies": {
"character-entities": "^1.0.0",
"character-entities-legacy": "^1.0.0",
"character-reference-invalid": "^1.0.0",
"is-alphanumerical": "^1.0.0",
"is-decimal": "^1.0.0",
"is-hexadecimal": "^1.0.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@ -14829,6 +15003,15 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/prismjs": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -14869,6 +15052,19 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/property-information": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
"integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
"license": "MIT",
"dependencies": {
"xtend": "^4.0.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -15180,22 +15376,6 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
},
"node_modules/react-imask": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/react-imask/-/react-imask-7.1.3.tgz",
"integrity": "sha512-anCnzdkqpDzNwe7ot76kQSvmnz4Sw7AW/QFjjLh3B87HVNv9e2oHC+1m9hQKSIui2Tqm7w68ooMgDFsCQlDMyg==",
"license": "MIT",
"dependencies": {
"imask": "^7.1.3",
"prop-types": "^15.8.1"
},
"engines": {
"npm": ">=4.0.0"
},
"peerDependencies": {
"react": ">=0.14.0"
}
},
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@ -15311,6 +15491,22 @@
}
}
},
"node_modules/react-syntax-highlighter": {
"version": "15.5.0",
"resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz",
"integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.3.1",
"highlight.js": "^10.4.1",
"lowlight": "^1.17.0",
"prismjs": "^1.27.0",
"refractor": "^3.6.0"
},
"peerDependencies": {
"react": ">= 0.14.0"
}
},
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
@ -15410,6 +15606,30 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/refractor": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
"integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
"license": "MIT",
"dependencies": {
"hastscript": "^6.0.0",
"parse-entities": "^2.0.0",
"prismjs": "~1.27.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/refractor/node_modules/prismjs": {
"version": "1.27.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
"integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -16223,6 +16443,16 @@
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"deprecated": "Please use @jridgewell/sourcemap-codec instead"
},
"node_modules/space-separated-tokens": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
"integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/spdy": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
@ -18249,16 +18479,46 @@
}
}
},
"node_modules/xml-formatter": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-3.6.0.tgz",
"integrity": "sha512-Wic80ENNLF/5mLcc82hVLmoOWQlLDJtVv+N1/hkP4hBuVXPLKrXo92/4V23QYPKfUxvCU6Y2AcdpHCIA/xexFw==",
"license": "MIT",
"dependencies": {
"xml-parser-xo": "^4.1.0"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/xml-name-validator": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
},
"node_modules/xml-parser-xo": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-4.1.1.tgz",
"integrity": "sha512-Ggf2y90+Y6e9IK5hoPuembVHJ03PhDSdhldEmgzbihzu9k0XBo0sfcFxaSi4W1PlUSSI1ok+MJ0JCXUn+U4Ilw==",
"license": "MIT",
"engines": {
"node": ">= 14"
}
},
"node_modules/xmlchars": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"license": "MIT",
"engines": {
"node": ">=0.4"
}
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@ -19592,15 +19852,6 @@
"regenerator-runtime": "^0.14.0"
}
},
"@babel/runtime-corejs3": {
"version": "7.23.5",
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.5.tgz",
"integrity": "sha512-7+ziVclejQTLYhXl+Oi1f6gTGD1XDCeLa4R472TNGQxb08zbEJ0OdNoh5Piz+57Ltmui6xR88BXR4gS3/Toslw==",
"requires": {
"core-js-pure": "^3.30.2",
"regenerator-runtime": "^0.14.0"
}
},
"@babel/template": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz",
@ -21337,6 +21588,14 @@
"@types/node": "*"
}
},
"@types/hast": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.8.tgz",
"integrity": "sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==",
"requires": {
"@types/unist": "^2"
}
},
"@types/html-minifier-terser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@ -21466,6 +21725,14 @@
"@types/react": "*"
}
},
"@types/react-syntax-highlighter": {
"version": "15.5.11",
"resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.11.tgz",
"integrity": "sha512-ZqIJl+Pg8kD+47kxUjvrlElrraSUrYa4h0dauY/U/FTUuprSCqvUj+9PNQNQzVc6AJgIWUUxn87/gqsMHNbRjw==",
"requires": {
"@types/react": "*"
}
},
"@types/react-transition-group": {
"version": "4.4.6",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz",
@ -21550,6 +21817,11 @@
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz",
"integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g=="
},
"@types/unist": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
"integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="
},
"@types/uuid": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.5.tgz",
@ -22612,6 +22884,21 @@
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="
},
"character-entities": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
"integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw=="
},
"character-entities-legacy": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
"integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA=="
},
"character-reference-invalid": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
"integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg=="
},
"check-types": {
"version": "11.2.2",
"resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz",
@ -22738,6 +23025,11 @@
"delayed-stream": "~1.0.0"
}
},
"comma-separated-tokens": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
"integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw=="
},
"commander": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
@ -24339,6 +24631,14 @@
"reusify": "^1.0.4"
}
},
"fault": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
"integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
"requires": {
"format": "^0.2.0"
}
},
"faye-websocket": {
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
@ -24605,6 +24905,11 @@
"mime-types": "^2.1.12"
}
},
"format": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
"integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww=="
},
"forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@ -24872,11 +25177,33 @@
"has-symbols": "^1.0.2"
}
},
"hast-util-parse-selector": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
"integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ=="
},
"hastscript": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
"integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
"requires": {
"@types/hast": "^2.0.0",
"comma-separated-tokens": "^1.0.0",
"hast-util-parse-selector": "^2.0.0",
"property-information": "^5.0.0",
"space-separated-tokens": "^1.0.0"
}
},
"he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
},
"highlight.js": {
"version": "10.7.3",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
"integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="
},
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -25102,14 +25429,6 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ=="
},
"imask": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/imask/-/imask-7.1.3.tgz",
"integrity": "sha512-jZCqTI5Jgukhl2ff+znBQd8BiHOTlnFYCIgggzHYDdoJsHmSSWr1BaejcYBxsjy4ZIs8Rm0HhbOxQcobcdESRQ==",
"requires": {
"@babel/runtime-corejs3": "^7.22.6"
}
},
"immer": {
"version": "9.0.21",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
@ -25189,6 +25508,20 @@
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz",
"integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ=="
},
"is-alphabetical": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
"integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg=="
},
"is-alphanumerical": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
"integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
"requires": {
"is-alphabetical": "^1.0.0",
"is-decimal": "^1.0.0"
}
},
"is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@ -25267,6 +25600,11 @@
"has-tostringtag": "^1.0.0"
}
},
"is-decimal": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
"integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw=="
},
"is-docker": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
@ -25311,6 +25649,11 @@
"is-extglob": "^2.1.1"
}
},
"is-hexadecimal": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
"integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw=="
},
"is-map": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
@ -27237,6 +27580,15 @@
"tslib": "^2.0.3"
}
},
"lowlight": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
"integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
"requires": {
"fault": "^1.0.0",
"highlight.js": "~10.7.0"
}
},
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@ -27757,6 +28109,19 @@
"callsites": "^3.0.0"
}
},
"parse-entities": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
"integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
"requires": {
"character-entities": "^1.0.0",
"character-entities-legacy": "^1.0.0",
"character-reference-invalid": "^1.0.0",
"is-alphanumerical": "^1.0.0",
"is-decimal": "^1.0.0",
"is-hexadecimal": "^1.0.0"
}
},
"parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@ -28630,6 +28995,11 @@
}
}
},
"prismjs": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -28669,6 +29039,14 @@
}
}
},
"property-information": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
"integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
"requires": {
"xtend": "^4.0.0"
}
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -28898,15 +29276,6 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
},
"react-imask": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/react-imask/-/react-imask-7.1.3.tgz",
"integrity": "sha512-anCnzdkqpDzNwe7ot76kQSvmnz4Sw7AW/QFjjLh3B87HVNv9e2oHC+1m9hQKSIui2Tqm7w68ooMgDFsCQlDMyg==",
"requires": {
"imask": "^7.1.3",
"prop-types": "^15.8.1"
}
},
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@ -28989,6 +29358,18 @@
"workbox-webpack-plugin": "^6.4.1"
}
},
"react-syntax-highlighter": {
"version": "15.5.0",
"resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz",
"integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==",
"requires": {
"@babel/runtime": "^7.3.1",
"highlight.js": "^10.4.1",
"lowlight": "^1.17.0",
"prismjs": "^1.27.0",
"refractor": "^3.6.0"
}
},
"react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
@ -29062,6 +29443,23 @@
"which-builtin-type": "^1.1.3"
}
},
"refractor": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
"integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
"requires": {
"hastscript": "^6.0.0",
"parse-entities": "^2.0.0",
"prismjs": "~1.27.0"
},
"dependencies": {
"prismjs": {
"version": "1.27.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
"integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA=="
}
}
},
"regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -29651,6 +30049,11 @@
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
},
"space-separated-tokens": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
"integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA=="
},
"spdy": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
@ -31178,16 +31581,34 @@
"integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
"requires": {}
},
"xml-formatter": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-3.6.0.tgz",
"integrity": "sha512-Wic80ENNLF/5mLcc82hVLmoOWQlLDJtVv+N1/hkP4hBuVXPLKrXo92/4V23QYPKfUxvCU6Y2AcdpHCIA/xexFw==",
"requires": {
"xml-parser-xo": "^4.1.0"
}
},
"xml-name-validator": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
},
"xml-parser-xo": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-4.1.1.tgz",
"integrity": "sha512-Ggf2y90+Y6e9IK5hoPuembVHJ03PhDSdhldEmgzbihzu9k0XBo0sfcFxaSi4W1PlUSSI1ok+MJ0JCXUn+U4Ilw=="
},
"xmlchars": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
},
"y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View File

@ -20,19 +20,21 @@
"@types/node": "^16.18.48",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"@types/react-syntax-highlighter": "^15.5.11",
"@types/uuid": "^9.0.5",
"filesize": "^10.0.12",
"humanize-duration": "^3.29.0",
"mui-file-input": "^3.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-imask": "^7.1.3",
"react-router-dom": "^6.15.0",
"react-scripts": "5.0.1",
"react-syntax-highlighter": "^15.5.0",
"react-vnc": "^1.0.0",
"typescript": "^4.9.5",
"uuid": "^9.0.1",
"web-vitals": "^2.1.4"
"web-vitals": "^2.1.4",
"xml-formatter": "^3.6.0"
},
"scripts": {
"start": "react-scripts start",

View File

@ -25,6 +25,7 @@ import { OIDCCbRoute } from "./routes/auth/OIDCCbRoute";
import { BaseAuthenticatedPage } from "./widgets/BaseAuthenticatedPage";
import { BaseLoginPage } from "./widgets/BaseLoginPage";
import { ViewNetworkRoute } from "./routes/ViewNetworkRoute";
import { VMXMLRoute } from "./routes/VMXMLRoute";
interface AuthContext {
signedIn: boolean;
@ -52,6 +53,7 @@ export function App() {
<Route path="vm/:uuid" element={<VMRoute />} />
<Route path="vm/:uuid/edit" element={<EditVMRoute />} />
<Route path="vm/:uuid/vnc" element={<VNCRoute />} />
<Route path="vm/:uuid/xml" element={<VMXMLRoute />} />
<Route path="net" element={<NetworksListRoute />} />
<Route path="net/new" element={<CreateNetworkRoute />} />

View File

@ -106,7 +106,14 @@ export class APIClient {
// JSON response
if (res.headers.get("content-type") === "application/json")
data = await res.json();
// Binary file
// Text / XML response
else if (
["application/xml", "text/plain"].includes(
res.headers.get("content-type") ?? ""
)
)
data = await res.text();
// Binary file, tracking download progress
else if (res.body !== null && args.downProgress) {
// Track download progress
const contentEncoding = res.headers.get("content-encoding");

View File

@ -113,6 +113,10 @@ export class VMInfo implements VMInfoInterface {
get VNCURL(): string {
return `/vm/${this.uuid}/vnc`;
}
get XMLURL(): string {
return `/vm/${this.uuid}/xml`;
}
}
export class VMApi {
@ -154,6 +158,18 @@ export class VMApi {
return new VMInfo(data);
}
/**
* Get the source XML configuration of a domain for debugging purposes
*/
static async GetSingleXML(uuid: string): Promise<string> {
return (
await APIClient.exec({
uri: `/vm/${uuid}/src`,
method: "GET",
})
).data;
}
/**
* Update the information about a single VM
*/

View File

@ -5,7 +5,10 @@ import { AsyncWidget } from "../widgets/AsyncWidget";
import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
import { VMDetails } from "../widgets/vms/VMDetails";
import { VMStatusWidget } from "../widgets/vms/VMStatusWidget";
import { Button } from "@mui/material";
import { Button, IconButton } from "@mui/material";
import Icon from "@mdi/react";
import { mdiXml } from "@mdi/js";
import { RouterLink } from "../widgets/RouterLink";
export function VMRoute(): React.ReactElement {
const { uuid } = useParams();
@ -35,9 +38,15 @@ function VMRouteBody(p: { vm: VMInfo }): React.ReactElement {
<VirtWebRouteContainer
label={`VM ${p.vm.name}`}
actions={
<span>
<span style={{ display: "inline-flex", alignItems: "center" }}>
<VMStatusWidget vm={p.vm} onChange={setState} />
<RouterLink to={p.vm.XMLURL}>
<IconButton size="small">
<Icon path={mdiXml} style={{ width: "1rem" }} />
</IconButton>
</RouterLink>
{(state === "Shutdown" || state === "Shutoff") && (
<Button
variant="contained"

View File

@ -0,0 +1,60 @@
import React from "react";
import { useParams } from "react-router-dom";
import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
import xml from "react-syntax-highlighter/dist/esm/languages/hljs/xml";
import { dracula } from "react-syntax-highlighter/dist/esm/styles/hljs";
import xmlFormat from "xml-formatter";
import { VMApi, VMInfo } from "../api/VMApi";
import { AsyncWidget } from "../widgets/AsyncWidget";
import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
import { IconButton } from "@mui/material";
import { RouterLink } from "../widgets/RouterLink";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
SyntaxHighlighter.registerLanguage("xml", xml);
export function VMXMLRoute(): React.ReactElement {
const { uuid } = useParams();
const [vm, setVM] = React.useState<VMInfo | undefined>();
const [src, setSrc] = React.useState<string | undefined>();
const load = async () => {
setVM(await VMApi.GetSingle(uuid!));
setSrc(await VMApi.GetSingleXML(uuid!));
};
return (
<AsyncWidget
loadKey={uuid}
load={load}
errMsg="Failed to load VM information!"
build={() => <XMLRouteInner vm={vm!} src={src!} />}
/>
);
}
function XMLRouteInner(p: { vm: VMInfo; src: string }): React.ReactElement {
const xml = xmlFormat(p.src);
return (
<VirtWebRouteContainer
label={`XML definition of ${p.vm.name}`}
actions={
<RouterLink to={p.vm.ViewURL}>
<IconButton>
<ArrowBackIcon />
</IconButton>
</RouterLink>
}
>
<SyntaxHighlighter
language="xml"
style={dracula}
customStyle={{ fontSize: "120%" }}
>
{xml}
</SyntaxHighlighter>
</VirtWebRouteContainer>
);
}

View File

@ -94,7 +94,7 @@ function VNCInner(p: { vm: VMInfo }): React.ReactElement {
return <p>Please wait, connecting to the machine...</p>;
return (
<div ref={vncRef}>
<div ref={vncRef} style={{ display: "flex" }}>
{/* Controls */}
<div>
<IconButton onClick={goBack}>

View File

@ -1,60 +0,0 @@
import { FormControl, Input, InputLabel } from "@mui/material";
import { TextInput } from "./TextInput";
import { IMaskInput } from "react-imask";
import React from "react";
interface CustomProps {
onChange: (event: { target: { name: string; value: string } }) => void;
name: string;
placeholder: string;
}
const TextMaskCustom = React.forwardRef<HTMLInputElement, CustomProps>(
function TextMaskCustom(props, ref) {
const { onChange, placeholder, ...other } = props;
return (
<IMaskInput
{...other}
mask={placeholder}
definitions={{
"#": /[1-9]/,
}}
inputRef={ref}
onAccept={(value: any) =>
onChange({ target: { name: props.name, value } })
}
overwrite
/>
);
}
);
export function TextMaskInput(p: {
label: string;
editable: boolean;
value?: string;
onValueChange?: (newVal: string | undefined) => void;
mask: string;
}): React.ReactElement {
const id = React.useRef(Math.random());
if (!p.editable) return <TextInput {...p} />;
return (
<FormControl variant="standard" fullWidth>
<InputLabel htmlFor={`mi-${id.current}`}>{p.label}</InputLabel>
<Input
fullWidth
value={p.value ?? ""}
onChange={(c) =>
p.onValueChange?.(
c.target.value.length === 0 ? undefined : c.target.value
)
}
id={`mi-${id.current}`}
inputComponent={TextMaskCustom as any}
placeholder={p.mask}
/>
</FormControl>
);
}