mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2024-12-31 00:08:08 +01:00
Adding LibreOffice conversion support (WIP)
This commit is contained in:
parent
c7dd18695d
commit
e625a415fd
150
README.md
150
README.md
@ -88,66 +88,136 @@ If you are interested in learning about this, take a look at the Example workflo
|
|||||||
|
|
||||||
Current functions of spdf and their progress in this repo.
|
Current functions of spdf and their progress in this repo.
|
||||||
|
|
||||||
|
#### Page Operations
|
||||||
| Status | Feature | Description |
|
| Status | Feature | Description |
|
||||||
| ------ | ------------------------ | ----------- |
|
| ------ | ------------------------ | ----------- |
|
||||||
| ✔️ | Merge | |
|
| 🚧A | Merge | |
|
||||||
| ✔️ | Split | |
|
| 🚧A | Split | |
|
||||||
| ✔️ | Rotate | |
|
| 🚧A | Organize | |
|
||||||
| ✔️ | Multi-Page-Layout | |
|
| 🚧S | Rotate | |
|
||||||
| ✔️ | Adjust page size/scale | |
|
| 🚧A | Remove Pages | |
|
||||||
| ✔️ | Organize | |
|
| 🚧A | Multi-Page Layout | |
|
||||||
| ✔️ | Change Metadata | |
|
| ❌ | Adjust page size/scale | |
|
||||||
| ✔️ | Auto Rename | |
|
| 🚧A | Auto Split Pages | |
|
||||||
| ❌ | Add Watermark | |
|
| ❌ | Adjust Colours/Contrast | |
|
||||||
|
| ❌ | Crop | |
|
||||||
|
| 🚧A | Extract Pages | |
|
||||||
| ❌ | PDF to Single large Page | |
|
| ❌ | PDF to Single large Page | |
|
||||||
| ❌ | Auto Redact | |
|
|
||||||
| ❌ | Remove Pages | |
|
|
||||||
|
|
||||||
| Status | Feature | Description |
|
|
||||||
| ------ | ------------------ | ----------- |
|
|
||||||
| ✔️ | Remove Blank Pages | |
|
|
||||||
| ✔️ | Auto Split Pages | |
|
|
||||||
|
|
||||||
| Status | Feature | Description |
|
#### Convert
|
||||||
| ------ | ------------ | ----------- |
|
| Status | Feature | Description |
|
||||||
| ❌ | Repair | |
|
| ------ | ------------------- | ----------- |
|
||||||
| ❌ | Compress | |
|
| ❌ | Image to PDF | |
|
||||||
| ❌ | Flatten | |
|
| 🚧S | Convert file to PDF | |
|
||||||
| ❌ | Compare/Diff | |
|
| ❌ | URL to PDF | |
|
||||||
| ❌ | Sanitize | |
|
| ❌ | HTML to PDF | |
|
||||||
| ❌ | Get info | |
|
| ❌ | Markdown to PDF | |
|
||||||
| ❌ | Show JS | |
|
| ❌ | PDF to Image | |
|
||||||
|
| ❌ | PDF to Word | |
|
||||||
|
| ❌ | PDF to Presentation | |
|
||||||
|
| ❌ | PDF to Text/RTF | |
|
||||||
|
| ❌ | PDF to HTML | |
|
||||||
|
| ❌ | PDF to PDF/A | |
|
||||||
|
|
||||||
|
#### Security
|
||||||
| Status | Feature | Description |
|
| Status | Feature | Description |
|
||||||
| ------ | --------------------- | ----------- |
|
| ------ | --------------------- | ----------- |
|
||||||
| ❌ | Sign | |
|
|
||||||
| ❌ | Sign with Certificate | |
|
|
||||||
| ❌ | Add Password | |
|
| ❌ | Add Password | |
|
||||||
| ❌ | Remove Password | |
|
| ❌ | Remove Password | |
|
||||||
| ❌ | Change Permissions | |
|
| ❌ | Change Permissions | |
|
||||||
|
| ❌ | Add Watermark | |
|
||||||
|
| ❌ | Sign with Certificate | |
|
||||||
|
| ❌ | Sanitize | |
|
||||||
|
| ❌ | Auto Redact | |
|
||||||
|
|
||||||
|
#### Miscellaneous
|
||||||
| Status | Feature | Description |
|
| Status | Feature | Description |
|
||||||
| ------ | --------------------------- | ----------- |
|
| ------ | --------------------------- | ----------- |
|
||||||
| ❌ | Image to PDF | |
|
|
||||||
| ❌ | Add image | |
|
|
||||||
| ❌ | Extract Images | |
|
|
||||||
| ❌ | PDF to Image | |
|
|
||||||
| ❌ | OCR | |
|
| ❌ | OCR | |
|
||||||
| ❌ | Detect/Split Scanned photos | |
|
| ❌ | Add image | |
|
||||||
|
| ❌ | Compress | |
|
||||||
|
| ❌ | Extract Images | |
|
||||||
|
| 🚧S | Change Metadata | |
|
||||||
|
| 🚧A | Detect/Split Scanned photos | |
|
||||||
|
| ❌ | Sign | |
|
||||||
|
| ❌ | Flatten | |
|
||||||
|
| ❌ | Repair | |
|
||||||
|
| 🚧A | Remove Blank Pages | |
|
||||||
|
| ❌ | Compare/Diff | |
|
||||||
|
| ❌ | Add Page Numbers | |
|
||||||
|
| ❌ | Auto Rename | |
|
||||||
|
| ❌ | Get info | |
|
||||||
|
| ❌ | Show JS | |
|
||||||
|
|
||||||
|
|
||||||
| Status | Feature | Description |
|
|
||||||
| ------ | ------------------------ | ----------- |
|
|
||||||
| ❌ | Convert file to PDF | |
|
|
||||||
| ❌ | PDF to Text/RTF | |
|
|
||||||
| ❌ | PDF to HTML | |
|
|
||||||
| ❌ | PDF to XML | |
|
|
||||||
| ❌ | URL to PDF | |
|
|
||||||
| ❌ | HTML to PDF | |
|
|
||||||
| ❌ | Markdown to PDF | |
|
|
||||||
|
|
||||||
|
|
||||||
✔️: Done, 🚧: Started Developement, ❌: Planned Feature
|
✔️: Done, 🚧: Started Developement, ❌: Planned Feature
|
||||||
|
A: Available in the internal API, S: Available on the node server, C: Available in the client
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
For initial instructions look at [CONTRIBUTE.md](./CONTRIBUTE.md)
|
For initial instructions look at [CONTRIBUTE.md](./CONTRIBUTE.md)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
///// CONVERT 2 pdf
|
||||||
|
file2pdf
|
||||||
|
url2pdf
|
||||||
|
html2pdf
|
||||||
|
md2pdf
|
||||||
|
image2pdf
|
||||||
|
|
||||||
|
///// CONVERT from pdf
|
||||||
|
pdf2image
|
||||||
|
flatten
|
||||||
|
pdf2pdf/a
|
||||||
|
pdf2word
|
||||||
|
pdf2presentation
|
||||||
|
pdf2rtf
|
||||||
|
pdf2html
|
||||||
|
pdf2xml
|
||||||
|
|
||||||
|
///// SINGLE
|
||||||
|
merge
|
||||||
|
rotate
|
||||||
|
crop
|
||||||
|
pageNumbers
|
||||||
|
colours/contrast
|
||||||
|
addPassword
|
||||||
|
removePassword
|
||||||
|
compress
|
||||||
|
changeMetadata
|
||||||
|
change Permissions
|
||||||
|
OCR
|
||||||
|
sanitise
|
||||||
|
repair
|
||||||
|
compare
|
||||||
|
extract images
|
||||||
|
signWith certificate
|
||||||
|
impose
|
||||||
|
adjust page size/scale
|
||||||
|
auto rename
|
||||||
|
getAllInfo
|
||||||
|
showJS
|
||||||
|
redact
|
||||||
|
pdf2singleLargePage
|
||||||
|
|
||||||
|
///// SPLITTING
|
||||||
|
split
|
||||||
|
auto split
|
||||||
|
detect/split scanned
|
||||||
|
|
||||||
|
///// REARRANGE
|
||||||
|
- organise pages (remove/re-arrange)
|
||||||
|
- removePages
|
||||||
|
- removeBlank
|
||||||
|
- extractPages
|
||||||
|
|
||||||
|
///// ADD OBJECTS
|
||||||
|
add image
|
||||||
|
add watermark
|
||||||
|
sign
|
||||||
|
*/
|
@ -17,13 +17,15 @@
|
|||||||
"i18next": "^23.6.0",
|
"i18next": "^23.6.0",
|
||||||
"i18next-browser-languagedetector": "^7.1.0",
|
"i18next-browser-languagedetector": "^7.1.0",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
|
"pdfjs-dist": "^4.0.189",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.9.1",
|
"react-bootstrap": "^2.9.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-i18next": "^13.3.1",
|
"react-i18next": "^13.3.1",
|
||||||
"react-icons": "^4.11.0",
|
"react-icons": "^4.11.0",
|
||||||
"react-router-bootstrap": "^0.26.2",
|
"react-router-bootstrap": "^0.26.2",
|
||||||
"react-router-dom": "^6.18.0"
|
"react-router-dom": "^6.18.0",
|
||||||
|
"vite-plugin-top-level-await": "^1.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "^1.5.0",
|
"@tauri-apps/cli": "^1.5.0",
|
||||||
|
22
client-tauri/src-tauri/Cargo.lock
generated
22
client-tauri/src-tauri/Cargo.lock
generated
@ -1711,6 +1711,16 @@ dependencies = [
|
|||||||
"windows-sys 0.42.0",
|
"windows-sys 0.42.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_pipe"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ae859aa07428ca9a929b936690f8b12dc5f11dd8c6992a18ca93919f28bc177"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "overload"
|
name = "overload"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -2436,6 +2446,16 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shared_child"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simd-adler32"
|
name = "simd-adler32"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
@ -2693,6 +2713,7 @@ dependencies = [
|
|||||||
"objc",
|
"objc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"open",
|
"open",
|
||||||
|
"os_pipe",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
@ -2703,6 +2724,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_repr",
|
"serde_repr",
|
||||||
"serialize-to-javascript",
|
"serialize-to-javascript",
|
||||||
|
"shared_child",
|
||||||
"state",
|
"state",
|
||||||
"tar",
|
"tar",
|
||||||
"tauri-macros",
|
"tauri-macros",
|
||||||
|
@ -13,7 +13,7 @@ edition = "2021"
|
|||||||
tauri-build = { version = "1.5", features = [] }
|
tauri-build = { version = "1.5", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "1.5", features = [ "fs-write-file", "fs-read-file", "dialog-save", "dialog-open", "shell-open"] }
|
tauri = { version = "1.5", features = [ "fs-remove-dir", "fs-create-dir", "shell-all", "fs-write-file", "fs-read-file", "dialog-save", "dialog-open"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
@ -14,8 +14,19 @@
|
|||||||
"allowlist": {
|
"allowlist": {
|
||||||
"all": false,
|
"all": false,
|
||||||
"shell": {
|
"shell": {
|
||||||
"all": false,
|
"all": true,
|
||||||
"open": true
|
"open": true,
|
||||||
|
"scope": [
|
||||||
|
{
|
||||||
|
"name": "libreoffice-version",
|
||||||
|
"cmd": "libreoffice",
|
||||||
|
"args": ["--version"]
|
||||||
|
},{
|
||||||
|
"name": "libreoffice-convert",
|
||||||
|
"cmd": "libreoffice",
|
||||||
|
"args": ["--headless","--convert-to",{ "validator": "\\S+" },{ "validator": "\\S+" },"--outdir",{ "validator": "\\S+" }]
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"all": false,
|
"all": false,
|
||||||
@ -31,8 +42,8 @@
|
|||||||
"writeFile": true,
|
"writeFile": true,
|
||||||
"readDir": false,
|
"readDir": false,
|
||||||
"copyFile": false,
|
"copyFile": false,
|
||||||
"createDir": false,
|
"createDir": true,
|
||||||
"removeDir": false,
|
"removeDir": true,
|
||||||
"removeFile": false,
|
"removeFile": false,
|
||||||
"renameFile": false,
|
"renameFile": false,
|
||||||
"exists": false
|
"exists": false
|
||||||
|
@ -4,6 +4,7 @@ import { Routes, Route, Outlet } from "react-router-dom";
|
|||||||
import Home from "./pages/Home";
|
import Home from "./pages/Home";
|
||||||
import About from "./pages/About";
|
import About from "./pages/About";
|
||||||
import Dashboard from "./pages/Dashboard";
|
import Dashboard from "./pages/Dashboard";
|
||||||
|
import ToPdf from "./pages/convert/ToPdf"
|
||||||
import NoMatch from "./pages/NoMatch";
|
import NoMatch from "./pages/NoMatch";
|
||||||
import NavBar from "./components/NavBar";
|
import NavBar from "./components/NavBar";
|
||||||
|
|
||||||
@ -38,6 +39,7 @@ export default function App() {
|
|||||||
<Route index element={<Home />} />
|
<Route index element={<Home />} />
|
||||||
<Route path="about" element={<About />} />
|
<Route path="about" element={<About />} />
|
||||||
<Route path="dashboard" element={<Dashboard />} />
|
<Route path="dashboard" element={<Dashboard />} />
|
||||||
|
<Route path="to-pdf" element={<ToPdf />} />
|
||||||
|
|
||||||
{/* Using path="*"" means "match anything", so this route
|
{/* Using path="*"" means "match anything", so this route
|
||||||
acts like a catch-all for URLs that we don't have explicit
|
acts like a catch-all for URLs that we don't have explicit
|
||||||
|
@ -86,7 +86,7 @@ function NavBar() {
|
|||||||
]},
|
]},
|
||||||
{displayText: t('navbar.convert'), icon: BsArrowLeftRight, sublist: [
|
{displayText: t('navbar.convert'), icon: BsArrowLeftRight, sublist: [
|
||||||
{ displayText: t('home.imageToPdf.title'), icon: BsFileEarmarkImage, dest: "/dashboard", tooltip: t('home.imageToPdf.desc') },
|
{ displayText: t('home.imageToPdf.title'), icon: BsFileEarmarkImage, dest: "/dashboard", tooltip: t('home.imageToPdf.desc') },
|
||||||
{ displayText: t('home.fileToPDF.title'), icon: BsFileEarmark, dest: "/nothing-here", tooltip: t('home.fileToPDF.desc') },
|
{ displayText: t('home.fileToPDF.title'), icon: BsFileEarmark, dest: "/to-pdf", tooltip: t('home.fileToPDF.desc') },
|
||||||
{ displayText: t('home.HTMLToPDF.title'), icon: BsFiletypeHtml, dest: "/nothing-here", tooltip: t('home.HTMLToPDF.desc') },
|
{ displayText: t('home.HTMLToPDF.title'), icon: BsFiletypeHtml, dest: "/nothing-here", tooltip: t('home.HTMLToPDF.desc') },
|
||||||
{ displayText: t('home.URLToPDF.title'), icon: BsLink, dest: "/nothing-here", tooltip: t('home.URLToPDF.desc') },
|
{ displayText: t('home.URLToPDF.title'), icon: BsLink, dest: "/nothing-here", tooltip: t('home.URLToPDF.desc') },
|
||||||
{ displayText: t('home.MarkdownToPDF.title'), icon: BsFiletypeMd, dest: "/nothing-here", tooltip: t('home.MarkdownToPDF.desc') },
|
{ displayText: t('home.MarkdownToPDF.title'), icon: BsFiletypeMd, dest: "/nothing-here", tooltip: t('home.MarkdownToPDF.desc') },
|
||||||
|
16
client-tauri/src/pages/convert/ToPdf.tsx
Normal file
16
client-tauri/src/pages/convert/ToPdf.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
import { isLibreOfficeInstalled } from "../../utils/libre-office-utils";
|
||||||
|
|
||||||
|
const hasLibreOffice = await isLibreOfficeInstalled();
|
||||||
|
console.log(hasLibreOffice)
|
||||||
|
|
||||||
|
function About() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>Convert to PDF</h2>
|
||||||
|
{"hasLibreOffice: "+hasLibreOffice}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default About;
|
46
client-tauri/src/utils/libre-office-utils.tsx
Normal file
46
client-tauri/src/utils/libre-office-utils.tsx
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
import { readBinaryFile, writeBinaryFile, removeDir, BaseDirectory } from '@tauri-apps/api/fs';
|
||||||
|
import { PdfFile, fromUint8Array } from '@stirling-pdf/shared-operations/wrappers/PdfFile'
|
||||||
|
import { runShell } from './tauri-wrapper';
|
||||||
|
|
||||||
|
export async function fileToPdf(byteArray: Uint8Array, filename: string): Promise<PdfFile> {
|
||||||
|
const randUuid = crypto.randomUUID();
|
||||||
|
const tempDir = "StirlingPDF/"+randUuid;
|
||||||
|
const srcFile = tempDir+"/"+filename;
|
||||||
|
|
||||||
|
await writeBinaryFile(srcFile, byteArray);
|
||||||
|
await writeBinaryFile(srcFile, new Uint8Array([]), { dir: BaseDirectory.Temp });
|
||||||
|
|
||||||
|
const messageList: string[] = [];
|
||||||
|
await runShell("libreoffice-convert", ["--headless","--convert-to","pdf",srcFile,"--outdir",tempDir], (message, stream) => {
|
||||||
|
if (stream === "stdout") {
|
||||||
|
messageList.push(message);
|
||||||
|
}
|
||||||
|
console.debug(`${stream}, ${randUuid}: ${message}`);
|
||||||
|
});
|
||||||
|
const lastMessage = messageList[messageList.length-1]
|
||||||
|
const outputFilePath = lastMessage.split(" -> ")[1].split(".pdf")[0]+".pdf";
|
||||||
|
const outputFilePathSplit = outputFilePath.toString().split("[\\/]")
|
||||||
|
const outputFileName = outputFilePathSplit[outputFilePathSplit.length-1];
|
||||||
|
const outputBytes = await readBinaryFile(outputFilePath);
|
||||||
|
|
||||||
|
await removeDir(tempDir);
|
||||||
|
|
||||||
|
return fromUint8Array(outputBytes, outputFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function isLibreOfficeInstalled() {
|
||||||
|
const messageList: string[] = [];
|
||||||
|
try {
|
||||||
|
await runShell("libreoffice-version", ["--version"], (message, stream) => {
|
||||||
|
if (stream === "stdout") {
|
||||||
|
messageList.push(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
console.log("messageList", messageList)
|
||||||
|
const result = messageList[0].match("LibreOffice ([0-9]+\.){4}.*");
|
||||||
|
return result ? true : false;
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import { open, save } from '@tauri-apps/api/dialog';
|
import { open, save } from '@tauri-apps/api/dialog';
|
||||||
import { readBinaryFile, writeBinaryFile } from '@tauri-apps/api/fs';
|
import { readBinaryFile, writeBinaryFile } from '@tauri-apps/api/fs';
|
||||||
|
import { Command } from '@tauri-apps/api/shell'
|
||||||
|
|
||||||
export type TauriBrowserFile = {
|
export type TauriBrowserFile = {
|
||||||
name: string,
|
name: string,
|
||||||
@ -52,7 +53,7 @@ export function openFiles(options: SelectFilesDialogOptions): Promise<TauriBrows
|
|||||||
selected = [selected];
|
selected = [selected];
|
||||||
}
|
}
|
||||||
|
|
||||||
const files:TauriBrowserFile[] = [];
|
const files: TauriBrowserFile[] = [];
|
||||||
for (const s of selected) {
|
for (const s of selected) {
|
||||||
const contents = await readBinaryFile(s);
|
const contents = await readBinaryFile(s);
|
||||||
const res = byteArrayToFile(contents, s);
|
const res = byteArrayToFile(contents, s);
|
||||||
@ -73,7 +74,7 @@ export function openFiles(options: SelectFilesDialogOptions): Promise<TauriBrows
|
|||||||
input.onchange = async () => {
|
input.onchange = async () => {
|
||||||
if (input.files && input.files.length) {
|
if (input.files && input.files.length) {
|
||||||
console.log("input.files", input.files)
|
console.log("input.files", input.files)
|
||||||
const files:TauriBrowserFile[] = [];
|
const files: TauriBrowserFile[] = [];
|
||||||
for (const f of input.files) {
|
for (const f of input.files) {
|
||||||
const contents = new Uint8Array(await f.arrayBuffer());
|
const contents = new Uint8Array(await f.arrayBuffer());
|
||||||
const res = byteArrayToFile(contents, f.name);
|
const res = byteArrayToFile(contents, f.name);
|
||||||
@ -138,4 +139,31 @@ export async function downloadFile(fileData: Uint8Array, options: DownloadFilesD
|
|||||||
downloadLink.click();
|
downloadLink.click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dont forget to whitelist the Command in src-tauri/tauri.conf.json! (tauri.allowlist.shell.scope)
|
||||||
|
* @param commandName The name of the command to run. Must be defined in tauri.allowlist.shell.scope[].name
|
||||||
|
* @param args The args to pass into the command
|
||||||
|
* @param callback A callback function that is called when output is logged
|
||||||
|
* @returns A log of all the outputs logged
|
||||||
|
*/
|
||||||
|
export function runShell(commandName: string, args: string[], callback: (message: any, stream:"stdout"|"stderr"|"error") => void): Promise<void> {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
|
||||||
|
const comm = new Command(commandName, args);
|
||||||
|
comm.on('close', data => {
|
||||||
|
if (data.code === 0) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject(new Error(`Command failed with exit code ${data.code} and signal ${data.signal}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
comm.on('error', error => callback(error, "error"));
|
||||||
|
comm.stdout.on('data', line => callback(line, "stdout"));
|
||||||
|
comm.stderr.on('data', line => callback(line, "stderr"));
|
||||||
|
|
||||||
|
const child = await comm.spawn();
|
||||||
|
console.debug(`Started child process with pid: ${child.pid}`)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
|
import topLevelAwait from "vite-plugin-top-level-await";
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig(async () => ({
|
export default defineConfig(async () => ({
|
||||||
plugins: [react()],
|
plugins: [
|
||||||
|
react(),
|
||||||
|
topLevelAwait({
|
||||||
|
// The export name of top-level await promise for each chunk module
|
||||||
|
promiseExportName: "__tla",
|
||||||
|
// The function to generate import names of top-level await promise in each chunk module
|
||||||
|
promiseImportName: i => `__tla_${i}`
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
|
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
|
||||||
//
|
//
|
||||||
|
299
package-lock.json
generated
299
package-lock.json
generated
@ -74,13 +74,15 @@
|
|||||||
"i18next": "^23.6.0",
|
"i18next": "^23.6.0",
|
||||||
"i18next-browser-languagedetector": "^7.1.0",
|
"i18next-browser-languagedetector": "^7.1.0",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
|
"pdfjs-dist": "^4.0.189",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.9.1",
|
"react-bootstrap": "^2.9.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-i18next": "^13.3.1",
|
"react-i18next": "^13.3.1",
|
||||||
"react-icons": "^4.11.0",
|
"react-icons": "^4.11.0",
|
||||||
"react-router-bootstrap": "^0.26.2",
|
"react-router-bootstrap": "^0.26.2",
|
||||||
"react-router-dom": "^6.18.0"
|
"react-router-dom": "^6.18.0",
|
||||||
|
"vite-plugin-top-level-await": "^1.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "^1.5.0",
|
"@tauri-apps/cli": "^1.5.0",
|
||||||
@ -2579,7 +2581,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@ -2595,7 +2596,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@ -2611,7 +2611,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
@ -2627,7 +2626,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
@ -2643,7 +2641,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
@ -2659,7 +2656,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
@ -2675,7 +2671,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
@ -2691,7 +2686,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@ -2707,7 +2701,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@ -2723,7 +2716,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@ -2739,7 +2731,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@ -2755,7 +2746,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"mips64el"
|
"mips64el"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@ -2771,7 +2761,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@ -2787,7 +2776,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@ -2803,7 +2791,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@ -2819,7 +2806,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
@ -2835,7 +2821,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"netbsd"
|
"netbsd"
|
||||||
@ -2851,7 +2836,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"openbsd"
|
"openbsd"
|
||||||
@ -2867,7 +2851,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"sunos"
|
"sunos"
|
||||||
@ -2883,7 +2866,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@ -2899,7 +2881,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@ -2915,7 +2896,6 @@
|
|||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
@ -3605,7 +3585,7 @@
|
|||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
|
||||||
"integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
|
"integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/set-array": "^1.0.1",
|
"@jridgewell/set-array": "^1.0.1",
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||||
@ -3619,7 +3599,7 @@
|
|||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
|
||||||
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
|
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
@ -3628,7 +3608,7 @@
|
|||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
|
||||||
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
|
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
@ -3637,7 +3617,7 @@
|
|||||||
"version": "0.3.5",
|
"version": "0.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
|
||||||
"integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
|
"integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/gen-mapping": "^0.3.0",
|
"@jridgewell/gen-mapping": "^0.3.0",
|
||||||
"@jridgewell/trace-mapping": "^0.3.9"
|
"@jridgewell/trace-mapping": "^0.3.9"
|
||||||
@ -3647,13 +3627,13 @@
|
|||||||
"version": "1.4.15",
|
"version": "1.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
|
||||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
|
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/trace-mapping": {
|
"node_modules/@jridgewell/trace-mapping": {
|
||||||
"version": "0.3.20",
|
"version": "0.3.20",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
|
||||||
"integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
|
"integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/resolve-uri": "^3.1.0",
|
"@jridgewell/resolve-uri": "^3.1.0",
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||||
@ -3833,6 +3813,22 @@
|
|||||||
"react": ">=16.14.0"
|
"react": ">=16.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@rollup/plugin-virtual": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"rollup": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@sideway/address": {
|
"node_modules/@sideway/address": {
|
||||||
"version": "4.1.4",
|
"version": "4.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
|
||||||
@ -3906,6 +3902,198 @@
|
|||||||
"sourcemap-codec": "^1.4.8"
|
"sourcemap-codec": "^1.4.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@swc/core": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-zwE3TLgoZwJfQygdv2SdCK9mRLYluwDOM53I+dT6Z5ZvrgVENmY3txvWDvduzkV+/8IuvrRbVezMpxcojadRdQ==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@swc/counter": "^0.1.1",
|
||||||
|
"@swc/types": "^0.1.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/swc"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@swc/core-darwin-arm64": "1.3.96",
|
||||||
|
"@swc/core-darwin-x64": "1.3.96",
|
||||||
|
"@swc/core-linux-arm-gnueabihf": "1.3.96",
|
||||||
|
"@swc/core-linux-arm64-gnu": "1.3.96",
|
||||||
|
"@swc/core-linux-arm64-musl": "1.3.96",
|
||||||
|
"@swc/core-linux-x64-gnu": "1.3.96",
|
||||||
|
"@swc/core-linux-x64-musl": "1.3.96",
|
||||||
|
"@swc/core-win32-arm64-msvc": "1.3.96",
|
||||||
|
"@swc/core-win32-ia32-msvc": "1.3.96",
|
||||||
|
"@swc/core-win32-x64-msvc": "1.3.96"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@swc/helpers": "^0.5.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@swc/helpers": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/core-darwin-arm64": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-8hzgXYVd85hfPh6mJ9yrG26rhgzCmcLO0h1TIl8U31hwmTbfZLzRitFQ/kqMJNbIBCwmNH1RU2QcJnL3d7f69A==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/core-darwin-x64": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-mFp9GFfuPg+43vlAdQZl0WZpZSE8sEzqL7sr/7Reul5McUHP0BaLsEzwjvD035ESfkY8GBZdLpMinblIbFNljQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/core-linux-arm-gnueabihf": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-8UEKkYJP4c8YzYIY/LlbSo8z5Obj4hqcv/fUTHiEePiGsOddgGf7AWjh56u7IoN/0uEmEro59nc1ChFXqXSGyg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/core-linux-arm64-gnu": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-c/IiJ0s1y3Ymm2BTpyC/xr6gOvoqAVETrivVXHq68xgNms95luSpbYQ28rqaZC8bQC8M5zdXpSc0T8DJu8RJGw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/core-linux-arm64-musl": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-i5/UTUwmJLri7zhtF6SAo/4QDQJDH2fhYJaBIUhrICmIkRO/ltURmpejqxsM/ye9Jqv5zG7VszMC0v/GYn/7BQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/core-linux-x64-gnu": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-USdaZu8lTIkm4Yf9cogct/j5eqtdZqTgcTib4I+NloUW0E/hySou3eSyp3V2UAA1qyuC72ld1otXuyKBna0YKQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/core-linux-x64-musl": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-QYErutd+G2SNaCinUVobfL7jWWjGTI0QEoQ6hqTp7PxCJS/dmKmj3C5ZkvxRYcq7XcZt7ovrYCTwPTHzt6lZBg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/core-win32-arm64-msvc": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-hjGvvAduA3Un2cZ9iNP4xvTXOO4jL3G9iakhFsgVhpkU73SGmK7+LN8ZVBEu4oq2SUcHO6caWvnZ881cxGuSpg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/core-win32-ia32-msvc": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-Far2hVFiwr+7VPCM2GxSmbh3ikTpM3pDombE+d69hkedvYHYZxtTF+2LTKl/sXtpbUnsoq7yV/32c9R/xaaWfw==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/core-win32-x64-msvc": {
|
||||||
|
"version": "1.3.96",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.96.tgz",
|
||||||
|
"integrity": "sha512-4VbSAniIu0ikLf5mBX81FsljnfqjoVGleEkCQv4+zRlyZtO3FHoDPkeLVoy6WRlj7tyrRcfUJ4mDdPkbfTO14g==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/counter": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw=="
|
||||||
|
},
|
||||||
"node_modules/@swc/helpers": {
|
"node_modules/@swc/helpers": {
|
||||||
"version": "0.5.3",
|
"version": "0.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz",
|
||||||
@ -3919,6 +4107,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@swc/types": {
|
||||||
|
"version": "0.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz",
|
||||||
|
"integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw=="
|
||||||
|
},
|
||||||
"node_modules/@swiftcarrot/color-fns": {
|
"node_modules/@swiftcarrot/color-fns": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@swiftcarrot/color-fns/-/color-fns-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@swiftcarrot/color-fns/-/color-fns-3.2.0.tgz",
|
||||||
@ -4281,7 +4474,7 @@
|
|||||||
"version": "18.18.7",
|
"version": "18.18.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.7.tgz",
|
||||||
"integrity": "sha512-bw+lEsxis6eqJYW8Ql6+yTqkE6RuFtsQPSe5JxXbqYRFQEER5aJA9a5UH9igqDWm3X4iLHIKOHlnAXLM4mi7uQ==",
|
"integrity": "sha512-bw+lEsxis6eqJYW8Ql6+yTqkE6RuFtsQPSe5JxXbqYRFQEER5aJA9a5UH9igqDWm3X4iLHIKOHlnAXLM4mi7uQ==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
}
|
}
|
||||||
@ -4749,7 +4942,7 @@
|
|||||||
"version": "8.10.0",
|
"version": "8.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
||||||
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
|
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@ -6751,7 +6944,6 @@
|
|||||||
"version": "0.18.20",
|
"version": "0.18.20",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
|
||||||
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
|
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
|
||||||
"dev": true,
|
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"esbuild": "bin/esbuild"
|
"esbuild": "bin/esbuild"
|
||||||
@ -10093,7 +10285,6 @@
|
|||||||
"version": "3.3.6",
|
"version": "3.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@ -10810,8 +11001,7 @@
|
|||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
@ -10862,7 +11052,6 @@
|
|||||||
"version": "8.4.31",
|
"version": "8.4.31",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
|
||||||
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
|
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@ -11639,7 +11828,6 @@
|
|||||||
"version": "3.29.4",
|
"version": "3.29.4",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
|
||||||
"integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
|
"integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
|
||||||
"dev": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"rollup": "dist/bin/rollup"
|
"rollup": "dist/bin/rollup"
|
||||||
},
|
},
|
||||||
@ -12042,7 +12230,7 @@
|
|||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@ -12051,7 +12239,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@ -12060,7 +12247,7 @@
|
|||||||
"version": "0.5.21",
|
"version": "0.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer-from": "^1.0.0",
|
"buffer-from": "^1.0.0",
|
||||||
"source-map": "^0.6.0"
|
"source-map": "^0.6.0"
|
||||||
@ -12476,7 +12663,7 @@
|
|||||||
"version": "5.22.0",
|
"version": "5.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.22.0.tgz",
|
||||||
"integrity": "sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw==",
|
"integrity": "sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/source-map": "^0.3.3",
|
"@jridgewell/source-map": "^0.3.3",
|
||||||
"acorn": "^8.8.2",
|
"acorn": "^8.8.2",
|
||||||
@ -12494,7 +12681,7 @@
|
|||||||
"version": "2.20.3",
|
"version": "2.20.3",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/text-table": {
|
"node_modules/text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
@ -13038,7 +13225,7 @@
|
|||||||
"version": "5.26.5",
|
"version": "5.26.5",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/unicode-canonical-property-names-ecmascript": {
|
"node_modules/unicode-canonical-property-names-ecmascript": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
@ -13242,7 +13429,6 @@
|
|||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
|
||||||
"integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==",
|
"integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.18.10",
|
"esbuild": "^0.18.10",
|
||||||
"postcss": "^8.4.27",
|
"postcss": "^8.4.27",
|
||||||
@ -13398,6 +13584,31 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vite-plugin-top-level-await": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-55M1h4NAwkrpxPNOJIBzKZFihqLUzIgnElLSmPNPMR2Fn9+JHKaNg3sVX1Fq+VgvuBksQYxiD3OnwQAUu7kaPQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@rollup/plugin-virtual": "^3.0.1",
|
||||||
|
"@swc/core": "^1.3.10",
|
||||||
|
"uuid": "^9.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vite": ">=2.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vite-plugin-top-level-await/node_modules/uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vitest": {
|
"node_modules/vitest": {
|
||||||
"version": "0.32.4",
|
"version": "0.32.4",
|
||||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.32.4.tgz",
|
"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.32.4.tgz",
|
||||||
|
@ -2,6 +2,7 @@ import express, { Request, Response } from 'express';
|
|||||||
|
|
||||||
//import workflow from './workflow-controller';
|
//import workflow from './workflow-controller';
|
||||||
import operations from './operations-controller';
|
import operations from './operations-controller';
|
||||||
|
import conversions from './conversions-controller';
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ router.get("/", (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.use("/operations", operations);
|
router.use("/operations", operations);
|
||||||
|
router.use("/conversions", conversions);
|
||||||
//router.use("/workflow", workflow);
|
//router.use("/workflow", workflow);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
27
server-node/src/routes/api/conversions-controller.ts
Normal file
27
server-node/src/routes/api/conversions-controller.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
import { respondWithPdfFile, response_mustHaveExactlyOneFile, response_dependencyNotConfigured } from '../../utils/endpoint-utils';
|
||||||
|
import { fileToPdf, isLibreOfficeInstalled } from '../../utils/libre-office-utils';
|
||||||
|
|
||||||
|
import express, { Request, Response } from 'express';
|
||||||
|
const router = express.Router();
|
||||||
|
import multer from 'multer';
|
||||||
|
const upload = multer();
|
||||||
|
import Joi from 'joi';
|
||||||
|
|
||||||
|
router.post('/file-to-pdf', upload.single("file"), async function(req: Request, res: Response) {
|
||||||
|
if (!req.file) {
|
||||||
|
response_mustHaveExactlyOneFile(res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isInstalled = await isLibreOfficeInstalled();
|
||||||
|
if (isInstalled) {
|
||||||
|
const outputFile = await fileToPdf(req.file.buffer, req.file.originalname);
|
||||||
|
respondWithPdfFile(res, outputFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
response_dependencyNotConfigured(res, "LibreOffice");
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
@ -2,14 +2,18 @@
|
|||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { PdfFile } from '@stirling-pdf/shared-operations/wrappers/PdfFile'
|
import { PdfFile } from '@stirling-pdf/shared-operations/wrappers/PdfFile'
|
||||||
|
|
||||||
|
export async function respondWithFile(res: Response, bytes: Uint8Array, name: string, mimeType: string): Promise<void> {
|
||||||
|
res.writeHead(200, {
|
||||||
|
'Content-Type': mimeType,
|
||||||
|
'Content-disposition': 'attachment;filename=' + name,
|
||||||
|
'Content-Length': bytes.length
|
||||||
|
});
|
||||||
|
res.end(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
export async function respondWithPdfFile(res: Response, file: PdfFile): Promise<void> {
|
export async function respondWithPdfFile(res: Response, file: PdfFile): Promise<void> {
|
||||||
const byteFile = await file.convertToByteArrayFile();
|
const byteFile = await file.convertToByteArrayFile();
|
||||||
res.writeHead(200, {
|
respondWithFile(res, byteFile.byteArray!, byteFile.filename, "application/pdf");
|
||||||
'Content-Type': "application/pdf",
|
|
||||||
'Content-disposition': 'attachment;filename=' + byteFile.filename,
|
|
||||||
'Content-Length': byteFile.byteArray?.length
|
|
||||||
});
|
|
||||||
res.end(byteFile.byteArray)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function response_mustHaveExactlyOneFile(res: Response): void {
|
export function response_mustHaveExactlyOneFile(res: Response): void {
|
||||||
@ -27,3 +31,12 @@ export function response_mustHaveExactlyOneFile(res: Response): void {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function response_dependencyNotConfigured(res: Response, dependencyName: string): void {
|
||||||
|
res.status(400).send([
|
||||||
|
{
|
||||||
|
"message": `${dependencyName} is not configured correctly on the server.`,
|
||||||
|
"type": "dependency_error",
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
99
server-node/src/utils/libre-office-utils.ts
Normal file
99
server-node/src/utils/libre-office-utils.ts
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import os from 'os';
|
||||||
|
import path from 'path';
|
||||||
|
import { exec, spawn } from 'child_process'
|
||||||
|
import { PdfFile, fromUint8Array } from '@stirling-pdf/shared-operations/wrappers/PdfFile'
|
||||||
|
|
||||||
|
export async function fileToPdf(byteArray: Uint8Array, filename: string): Promise<PdfFile> {
|
||||||
|
const parentDir = path.join(os.tmpdir(), "StirlingPDF");
|
||||||
|
fs.mkdirSync(parentDir, {recursive: true});
|
||||||
|
const tempDir = fs.mkdtempSync(parentDir+"/");
|
||||||
|
const srcFile = path.join(tempDir, filename);
|
||||||
|
const randFolderName = path.parse(tempDir).base;
|
||||||
|
|
||||||
|
await writeBytesToFile(srcFile, byteArray);
|
||||||
|
|
||||||
|
const messages = await runLibreOfficeCommand(randFolderName, ["--headless","--convert-to","pdf",srcFile,"--outdir",tempDir]);
|
||||||
|
const lastMessage = messages[messages.length-1]
|
||||||
|
const outputFilePath = lastMessage.split(" -> ")[1].split(".pdf")[0]+".pdf";
|
||||||
|
const outputFileName = path.parse(outputFilePath).base;
|
||||||
|
const outputBytes = await readBytesFromFile(outputFilePath);
|
||||||
|
|
||||||
|
fs.rmdirSync(tempDir);
|
||||||
|
|
||||||
|
return fromUint8Array(outputBytes, outputFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isLibreOfficeInstalled() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec("libreoffice --version", (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (stderr) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result = stdout.match("LibreOffice ([0-9]+\.){4}.*");
|
||||||
|
resolve(result ? true : false);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeBytesToFile(filePath: string, bytes: Uint8Array): Promise<void> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.writeFile(filePath, bytes, function(err) {
|
||||||
|
if(err) {
|
||||||
|
reject(err)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function readBytesFromFile(filePath: string): Promise<Uint8Array> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.readFile(filePath, (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
reject(new Error(`Error reading file: ${err.message}`));
|
||||||
|
} else {
|
||||||
|
const uint8Array = new Uint8Array(data);
|
||||||
|
resolve(uint8Array);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function runLibreOfficeCommand(idKey: string, args: string[]): Promise<string[]> {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
const messageList: string[] = [];
|
||||||
|
|
||||||
|
const process = spawn("libreoffice", args);
|
||||||
|
|
||||||
|
process.stdout.on('data', (data) => {
|
||||||
|
const dataStr = data.toString();
|
||||||
|
console.log(`Progress ${idKey}:`, dataStr);
|
||||||
|
messageList.push(dataStr);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.stderr.on('data', (data) => {
|
||||||
|
console.error(`stderr ${idKey}:`, data.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('exit', (code) => {
|
||||||
|
if (code === 0) {
|
||||||
|
resolve(messageList);
|
||||||
|
} else {
|
||||||
|
reject(new Error(`Command failed with exit code ${code}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('error', (err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
@ -1,6 +1,4 @@
|
|||||||
|
|
||||||
import { PDFDocument } from 'pdf-lib';
|
|
||||||
|
|
||||||
import { selectPages } from "./subDocumentFunctions";
|
import { selectPages } from "./subDocumentFunctions";
|
||||||
import { PdfFile } from '../wrappers/PdfFile';
|
import { PdfFile } from '../wrappers/PdfFile';
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
import { PDFDocument, ParseSpeeds } from 'pdf-lib';
|
|
||||||
import { PdfFile, fromPdfLib } from '../wrappers/PdfFile';
|
import { PdfFile, fromPdfLib } from '../wrappers/PdfFile';
|
||||||
|
|
||||||
export type Metadata = {
|
export type Metadata = {
|
||||||
|
Loading…
Reference in New Issue
Block a user