mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2025-05-02 17:07:13 +00:00
Merge pull request from GHSA-xmj6-g32r-fc5q
* remove support for import export anythingllm data * remove unused imports remove unused dep update lockfile --------- Co-authored-by: timothycarambat <rambat1010@gmail.com>
This commit is contained in:
parent
56fa17caf2
commit
08d33cfd8f
10 changed files with 3 additions and 584 deletions
|
@ -34,9 +34,6 @@ const GeneralEmbeddingPreference = lazy(
|
|||
const GeneralVectorDatabase = lazy(
|
||||
() => import("@/pages/GeneralSettings/VectorDatabase")
|
||||
);
|
||||
const GeneralExportImport = lazy(
|
||||
() => import("@/pages/GeneralSettings/ExportImport")
|
||||
);
|
||||
const GeneralSecurity = lazy(() => import("@/pages/GeneralSettings/Security"));
|
||||
const DataConnectors = lazy(
|
||||
() => import("@/pages/GeneralSettings/DataConnectors")
|
||||
|
@ -74,10 +71,6 @@ export default function App() {
|
|||
element={<AdminRoute Component={GeneralVectorDatabase} />}
|
||||
/>
|
||||
{/* Manager */}
|
||||
<Route
|
||||
path="/settings/export-import"
|
||||
element={<ManagerRoute Component={GeneralExportImport} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/security"
|
||||
element={<ManagerRoute Component={GeneralSecurity} />}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import React, { useEffect, useRef, useState } from "react";
|
||||
// import IndexCount from "../Sidebar/IndexCount";
|
||||
// import LLMStatus from "../Sidebar/LLMStatus";
|
||||
import paths from "@/utils/paths";
|
||||
import useLogo from "@/hooks/useLogo";
|
||||
import {
|
||||
|
@ -14,10 +12,8 @@ import {
|
|||
Key,
|
||||
ChatText,
|
||||
Database,
|
||||
DownloadSimple,
|
||||
Lock,
|
||||
GithubLogo,
|
||||
DotsThree,
|
||||
House,
|
||||
X,
|
||||
List,
|
||||
|
@ -135,12 +131,6 @@ export default function SettingsSidebar() {
|
|||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Option
|
||||
href={paths.settings.exportImport()}
|
||||
btnText="Export or Import"
|
||||
icon={<DownloadSimple className="h-5 w-5 flex-shrink-0" />}
|
||||
/>
|
||||
<Option
|
||||
href={paths.settings.security()}
|
||||
btnText="Security"
|
||||
|
@ -328,11 +318,6 @@ export function SidebarMobileHeader() {
|
|||
/>
|
||||
</>
|
||||
)}
|
||||
<Option
|
||||
href={paths.settings.exportImport()}
|
||||
btnText="Export or Import"
|
||||
icon={<DownloadSimple className="h-5 w-5 flex-shrink-0" />}
|
||||
/>
|
||||
<Option
|
||||
href={paths.settings.security()}
|
||||
btnText="Security"
|
||||
|
|
|
@ -160,31 +160,6 @@ const System = {
|
|||
return false;
|
||||
});
|
||||
},
|
||||
dataExport: async () => {
|
||||
return await fetch(`${API_BASE}/system/data-export`, {
|
||||
method: "GET",
|
||||
headers: baseHeaders(),
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((res) => res)
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
return { filename: null, error: e.message };
|
||||
});
|
||||
},
|
||||
importData: async (formData) => {
|
||||
return await fetch(`${API_BASE}/system/data-import`, {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
headers: baseHeaders(),
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((res) => res)
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
return { success: false, error: e.message };
|
||||
});
|
||||
},
|
||||
uploadPfp: async function (formData) {
|
||||
return await fetch(`${API_BASE}/system/upload-pfp`, {
|
||||
method: "POST",
|
||||
|
|
|
@ -1,226 +0,0 @@
|
|||
import { useRef, useState } from "react";
|
||||
import Sidebar, { SidebarMobileHeader } from "@/components/SettingsSidebar";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import showToast from "@/utils/toast";
|
||||
import { CloudArrowUp, DownloadSimple } from "@phosphor-icons/react";
|
||||
import System from "@/models/system";
|
||||
import { API_BASE } from "@/utils/constants";
|
||||
import paths from "@/utils/paths";
|
||||
|
||||
export default function GeneralExportImport() {
|
||||
const hostname = window?.location?.hostname;
|
||||
const isHosted = hostname.includes(".useanything.com");
|
||||
|
||||
if (isHosted) {
|
||||
return (
|
||||
<div className="w-screen h-screen overflow-hidden bg-sidebar flex">
|
||||
{!isMobile && <Sidebar />}
|
||||
<div
|
||||
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
||||
className="transition-all duration-500 relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[26px] bg-main-gradient w-full h-full overflow-y-scroll border-4 border-accent"
|
||||
>
|
||||
{isMobile && <SidebarMobileHeader />}
|
||||
<div className="flex flex-col w-full px-1 md:px-20 md:py-12 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="items-center flex gap-x-4">
|
||||
<p className="text-2xl font-semibold text-white">
|
||||
Export or Import
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full items-center justify-center flex flex-col gap-y-4">
|
||||
<p className="text-lg font-base text-white text-opacity-60">
|
||||
This feature is temporarily disabled for hosted AnythingLLM
|
||||
instances.
|
||||
</p>
|
||||
<a
|
||||
href={`${paths.mailToMintplex()}?Subject=Import/Export disabled on hosted AnythingLLM.`}
|
||||
className="text-blue-300 hover:underline"
|
||||
>
|
||||
Contact Mintplex Labs Inc.
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-screen h-screen overflow-hidden bg-sidebar flex">
|
||||
{!isMobile && <Sidebar />}
|
||||
<div
|
||||
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
||||
className="transition-all duration-500 relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[26px] bg-main-gradient w-full h-full overflow-y-scroll border-4 border-accent"
|
||||
>
|
||||
{isMobile && <SidebarMobileHeader />}
|
||||
<div className="flex flex-col w-full px-1 md:px-20 md:py-12 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="items-center flex gap-x-4">
|
||||
<p className="text-2xl font-semibold text-white">
|
||||
Export or Import
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-sm font-base text-white text-opacity-60">
|
||||
Have multiple AnythingLLM instances or simply want to backup or
|
||||
re-import data from another instance? You can do so here.
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-white text-sm font-medium py-4">
|
||||
This will not automatically sync your vector database embeddings.
|
||||
</div>
|
||||
<ImportData />
|
||||
<ExportData />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ImportData() {
|
||||
const inputRef = useRef(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [file, setFile] = useState(null);
|
||||
const [result, setResult] = useState(null);
|
||||
|
||||
const startInput = () => inputRef?.current?.click();
|
||||
const handleUpload = async (e) => {
|
||||
setLoading(true);
|
||||
e.preventDefault();
|
||||
setFile(null);
|
||||
setResult(null);
|
||||
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) {
|
||||
showToast("Invalid file upload", "error");
|
||||
return false;
|
||||
}
|
||||
|
||||
setFile(file);
|
||||
setLoading(true);
|
||||
const formData = new FormData();
|
||||
formData.append("file", file, file.name);
|
||||
const { success, error } = await System.importData(formData);
|
||||
if (!success) {
|
||||
showToast(`Failed to import data: ${error}`, "error");
|
||||
} else {
|
||||
setResult(true);
|
||||
showToast(`Successfully imported ${file.name}`, "success");
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
setFile(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={startInput}
|
||||
className="max-w-[600px] py-4 bg-zinc-900/50 rounded-2xl border-2 border-dashed border-white border-opacity-60 justify-center items-center inline-flex transition-all duration-300 hover:opacity-60 cursor-pointer"
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
{loading ? (
|
||||
<div className="flex items-center justify-center gap-2 animate-pulse">
|
||||
<div className="text-white text-opacity-80 text-sm font-semibold py-1">
|
||||
Importing
|
||||
</div>
|
||||
<div className="h-4 w-4 animate-spin rounded-full border-2 border-solid border-white border-t-transparent " />
|
||||
</div>
|
||||
) : !!result ? (
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<CloudArrowUp className="w-8 h-8 text-green-400" />
|
||||
<div className="text-green-400 text-opacity-80 text-sm font-semibold py-1">
|
||||
Import Successful
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<input
|
||||
ref={inputRef}
|
||||
onChange={handleUpload}
|
||||
name="import"
|
||||
type="file"
|
||||
multiple="false"
|
||||
accept=".zip"
|
||||
hidden={true}
|
||||
/>
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<CloudArrowUp className="w-8 h-8 text-white/80" />
|
||||
<div className="text-white text-opacity-80 text-sm font-semibold py-1">
|
||||
Import AnythingLLM Data
|
||||
</div>
|
||||
<div className="text-white text-opacity-60 text-xs font-medium py-1">
|
||||
This must be an export from an AnythingLLM instance.
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ExportData() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [result, setResult] = useState(null);
|
||||
|
||||
const exportData = async function () {
|
||||
setLoading(true);
|
||||
const { filename, error } = await System.dataExport();
|
||||
setLoading(false);
|
||||
|
||||
if (!filename) {
|
||||
showToast(`Failed to export data: ${error}`, "error");
|
||||
} else {
|
||||
setResult(filename);
|
||||
const link = document.createElement("a");
|
||||
link.href = `${API_BASE}/system/data-exports/${filename}`;
|
||||
link.target = "_blank";
|
||||
document.body.appendChild(link);
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<button
|
||||
onClick={exportData}
|
||||
className="transition-all max-w-[600px] bg-white rounded-lg justify-center items-center my-8 text-zinc-900 border-transparent border-2 cursor-not-allowed animate-pulse"
|
||||
>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<div className="duration-300 text-center text-sm font-bold py-3">
|
||||
Exporting
|
||||
</div>
|
||||
<div className="h-4 w-4 animate-spin rounded-full border-2 border-solid border-zinc-900 border-t-transparent " />
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
if (!!result) {
|
||||
return (
|
||||
<a
|
||||
target="_blank"
|
||||
href={`${API_BASE}/system/data-exports/${result}`}
|
||||
className="transition-all max-w-[600px] bg-green-100 hover:bg-zinc-900/50 hover:text-white hover:border-white rounded-lg justify-center items-center my-8 text-zinc-900 border-transparent border-2 cursor-pointer"
|
||||
>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<div className="duration-300 text-center text-sm font-bold py-3">
|
||||
Download Data Export
|
||||
</div>
|
||||
<DownloadSimple className="w-6 h-6" />
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={exportData}
|
||||
className="transition-all max-w-[600px] bg-white rounded-lg justify-center items-center my-8 cursor-pointer text-zinc-900 border-transparent border-2 hover:bg-zinc-900/50 hover:text-white hover:border-white"
|
||||
>
|
||||
<div className="duration-300 text-center text-sm font-bold py-3">
|
||||
Export AnythingLLM Data
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
|
@ -56,9 +56,6 @@ export default {
|
|||
return `/workspace/${slug}`;
|
||||
},
|
||||
},
|
||||
exports: () => {
|
||||
return `${API_BASE.replace("/api", "")}/system/data-exports`;
|
||||
},
|
||||
apiDocs: () => {
|
||||
return `${API_BASE}/docs`;
|
||||
},
|
||||
|
@ -87,9 +84,6 @@ export default {
|
|||
vectorDatabase: () => {
|
||||
return "/settings/vector-database";
|
||||
},
|
||||
exportImport: () => {
|
||||
return "/settings/export-import";
|
||||
},
|
||||
security: () => {
|
||||
return "/settings/security";
|
||||
},
|
||||
|
|
|
@ -2,7 +2,6 @@ process.env.NODE_ENV === "development"
|
|||
? require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` })
|
||||
: require("dotenv").config();
|
||||
const { viewLocalFiles, normalizePath } = require("../utils/files");
|
||||
const { exportData, unpackAndOverwriteImport } = require("../utils/files/data");
|
||||
const {
|
||||
checkProcessorAlive,
|
||||
acceptedFileTypes,
|
||||
|
@ -389,55 +388,6 @@ function systemEndpoints(app) {
|
|||
}
|
||||
});
|
||||
|
||||
app.get(
|
||||
"/system/data-export",
|
||||
[validatedRequest, flexUserRoleValid],
|
||||
async (_, response) => {
|
||||
try {
|
||||
const { filename, error } = await exportData();
|
||||
response.status(200).json({ filename, error });
|
||||
} catch (e) {
|
||||
console.log(e.message, e);
|
||||
response.sendStatus(500).end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.get("/system/data-exports/:filename", (request, response) => {
|
||||
const exportLocation = __dirname + "/../storage/exports/";
|
||||
const sanitized = normalizePath(request.params.filename);
|
||||
const finalDestination = path.join(exportLocation, sanitized);
|
||||
|
||||
if (!fs.existsSync(finalDestination)) {
|
||||
response.status(404).json({
|
||||
error: 404,
|
||||
msg: `File ${request.params.filename} does not exist in exports.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
response.download(finalDestination, request.params.filename, (err) => {
|
||||
if (err) {
|
||||
response.send({
|
||||
error: err,
|
||||
msg: "Problem downloading the file",
|
||||
});
|
||||
}
|
||||
// delete on download because endpoint is not authenticated.
|
||||
fs.rmSync(finalDestination);
|
||||
});
|
||||
});
|
||||
|
||||
app.post(
|
||||
"/system/data-import",
|
||||
handleImports.single("file"),
|
||||
async function (request, response) {
|
||||
const { originalname } = request.file;
|
||||
const { success, error } = await unpackAndOverwriteImport(originalname);
|
||||
response.status(200).json({ success, error });
|
||||
}
|
||||
);
|
||||
|
||||
app.get("/system/logo", async function (request, response) {
|
||||
try {
|
||||
const defaultFilename = getDefaultFilename();
|
||||
|
|
|
@ -4,7 +4,6 @@ process.env.NODE_ENV === "development"
|
|||
|
||||
const express = require("express");
|
||||
const bodyParser = require("body-parser");
|
||||
const serveIndex = require("serve-index");
|
||||
const cors = require("cors");
|
||||
const path = require("path");
|
||||
const { reqBody } = require("./utils/http");
|
||||
|
@ -85,11 +84,6 @@ if (process.env.NODE_ENV !== "development") {
|
|||
});
|
||||
}
|
||||
|
||||
app.use(
|
||||
"/system/data-exports",
|
||||
serveIndex(__dirname + "/storage/exports", { icons: true })
|
||||
);
|
||||
|
||||
app.all("*", function (_, response) {
|
||||
response.sendStatus(404);
|
||||
});
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
"pinecone-client": "^1.1.0",
|
||||
"posthog-node": "^3.1.1",
|
||||
"prisma": "^5.3.1",
|
||||
"serve-index": "^1.9.1",
|
||||
"slugify": "^1.6.6",
|
||||
"sqlite": "^4.2.1",
|
||||
"sqlite3": "^5.1.6",
|
||||
|
|
|
@ -1,197 +0,0 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { v4 } = require("uuid");
|
||||
|
||||
async function exportData() {
|
||||
const uid = `anythingllm-export-${new Date()
|
||||
.toJSON()
|
||||
.slice(0, 10)}-${new Date().toJSON().slice(11, 19)}`;
|
||||
const folder =
|
||||
process.env.NODE_ENV === "development"
|
||||
? path.resolve(__dirname, `../../storage/exports/${uid}`)
|
||||
: path.resolve(process.env.STORAGE_DIR, `exports/${uid}`);
|
||||
const storageBase =
|
||||
process.env.NODE_ENV === "development"
|
||||
? path.resolve(__dirname, `../../storage`)
|
||||
: path.resolve(process.env.STORAGE_DIR);
|
||||
|
||||
try {
|
||||
fs.mkdirSync(folder, { recursive: true });
|
||||
if (fs.existsSync(path.resolve(storageBase, `documents`))) {
|
||||
console.log("\x1b[34m[EXPORTING DATA]\x1b[0m Copying documents!");
|
||||
fs.cpSync(
|
||||
path.resolve(storageBase, `documents`),
|
||||
path.resolve(folder, "documents"),
|
||||
{ recursive: true }
|
||||
);
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.resolve(storageBase, `lancedb`))) {
|
||||
console.log("\x1b[34m[EXPORTING DATA]\x1b[0m Copying LanceDB data!");
|
||||
fs.cpSync(
|
||||
path.resolve(storageBase, `lancedb`),
|
||||
path.resolve(folder, "lancedb"),
|
||||
{ recursive: true }
|
||||
);
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.resolve(storageBase, `vector-cache`))) {
|
||||
console.log("\x1b[34m[EXPORTING DATA]\x1b[0m Copying vector cache!");
|
||||
fs.cpSync(
|
||||
path.resolve(storageBase, `vector-cache`),
|
||||
path.resolve(folder, "vector-cache"),
|
||||
{ recursive: true }
|
||||
);
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.resolve(storageBase, `anythingllm.db`))) {
|
||||
console.log(
|
||||
"\x1b[34m[EXPORTING DATA]\x1b[0m Copying anythingllm database!"
|
||||
);
|
||||
fs.cpSync(
|
||||
path.resolve(storageBase, `anythingllm.db`),
|
||||
path.resolve(folder, "anythingllm.db")
|
||||
);
|
||||
}
|
||||
|
||||
await zipDirectory(folder, path.resolve(folder, `../${uid}.zip`));
|
||||
fs.rmSync(folder, { recursive: true, force: true });
|
||||
return { filename: `${uid}.zip`, error: null };
|
||||
} catch (e) {
|
||||
// If anything goes wrong - abort and clean up
|
||||
console.error(e);
|
||||
if (fs.existsSync(folder))
|
||||
fs.rmSync(folder, { recursive: true, force: true });
|
||||
return { filename: null, error: e.message };
|
||||
}
|
||||
}
|
||||
|
||||
async function unpackAndOverwriteImport(importFilename) {
|
||||
const importFilepath =
|
||||
process.env.NODE_ENV === "development"
|
||||
? path.resolve(__dirname, `../../storage/imports/${importFilename}`)
|
||||
: path.resolve(process.env.STORAGE_DIR, `imports/${importFilename}`);
|
||||
if (!fs.existsSync(importFilepath))
|
||||
return { success: false, error: "Import file does not exist." };
|
||||
|
||||
const uid = v4();
|
||||
const outDir =
|
||||
process.env.NODE_ENV === "development"
|
||||
? path.resolve(__dirname, `../../storage/imports/${uid}`)
|
||||
: path.resolve(process.env.STORAGE_DIR, `imports/${uid}`);
|
||||
|
||||
const storageBase =
|
||||
process.env.NODE_ENV === "development"
|
||||
? path.resolve(__dirname, `../../storage`)
|
||||
: path.resolve(process.env.STORAGE_DIR);
|
||||
|
||||
try {
|
||||
console.log(
|
||||
"\x1b[34m[EXTRACTING DATA]\x1b[0m Extracting data from zip into storage!"
|
||||
);
|
||||
const unzipProc = await unzipDirectory(importFilepath, outDir);
|
||||
if (!unzipProc.success) return unzipProc;
|
||||
|
||||
if (fs.existsSync(path.resolve(outDir, `documents`))) {
|
||||
console.log(
|
||||
"\x1b[34m[OVERWRITE & IMPORT DATA]\x1b[0m Importing documents!"
|
||||
);
|
||||
if (fs.existsSync(path.resolve(storageBase, `documents`)))
|
||||
fs.rmSync(path.resolve(storageBase, `documents`), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
fs.cpSync(
|
||||
path.resolve(outDir, `documents`),
|
||||
path.resolve(storageBase, "documents"),
|
||||
{ recursive: true }
|
||||
);
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.resolve(outDir, `lancedb`))) {
|
||||
console.log(
|
||||
"\x1b[34m[OVERWRITE & IMPORT DATA]\x1b[0m Importing LanceDb!"
|
||||
);
|
||||
if (fs.existsSync(path.resolve(storageBase, `lancedb`)))
|
||||
fs.rmSync(path.resolve(storageBase, `lancedb`), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
fs.cpSync(
|
||||
path.resolve(outDir, `lancedb`),
|
||||
path.resolve(storageBase, "lancedb"),
|
||||
{ recursive: true }
|
||||
);
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.resolve(outDir, `vector-cache`))) {
|
||||
console.log(
|
||||
"\x1b[34m[OVERWRITE & IMPORT DATA]\x1b[0m Importing Vector Cache!"
|
||||
);
|
||||
if (fs.existsSync(path.resolve(storageBase, `vector-cache`)))
|
||||
fs.rmSync(path.resolve(storageBase, `vector-cache`), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
fs.cpSync(
|
||||
path.resolve(outDir, `vector-cache`),
|
||||
path.resolve(storageBase, "vector-cache"),
|
||||
{ recursive: true }
|
||||
);
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.resolve(outDir, `anythingllm.db`))) {
|
||||
console.log(
|
||||
"\x1b[34m[OVERWRITE & IMPORT DATA]\x1b[0m Importing AnythingLLM DB!"
|
||||
);
|
||||
if (fs.existsSync(path.resolve(storageBase, `anythingllm.db`)))
|
||||
fs.rmSync(path.resolve(storageBase, `anythingllm.db`), { force: true });
|
||||
fs.cpSync(
|
||||
path.resolve(outDir, `anythingllm.db`),
|
||||
path.resolve(storageBase, "anythingllm.db")
|
||||
);
|
||||
}
|
||||
|
||||
fs.rmSync(outDir, { recursive: true, force: true });
|
||||
fs.rmSync(importFilepath, { force: true });
|
||||
return { success: true, error: null };
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
if (fs.existsSync(outDir))
|
||||
fs.rmSync(outDir, { recursive: true, force: true });
|
||||
if (fs.existsSync(importFilepath)) fs.rmSync(importFilepath);
|
||||
return { success: false, error: e.message };
|
||||
}
|
||||
}
|
||||
|
||||
function zipDirectory(sourceDir, outPath) {
|
||||
const archiver = require("archiver");
|
||||
const archive = archiver("zip", { zlib: { level: 9 } });
|
||||
const stream = fs.createWriteStream(outPath);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
archive
|
||||
.directory(sourceDir, false)
|
||||
.on("error", (err) => reject(err))
|
||||
.pipe(stream);
|
||||
|
||||
stream.on("close", () => resolve());
|
||||
archive.finalize();
|
||||
});
|
||||
}
|
||||
|
||||
async function unzipDirectory(sourcePath, outDir) {
|
||||
const extract = require("extract-zip");
|
||||
try {
|
||||
await extract(sourcePath, { dir: outDir });
|
||||
return { success: true, error: null };
|
||||
} catch (e) {
|
||||
console.error("unzipToDirectory", e);
|
||||
return { success: false, error: e.message };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
exportData,
|
||||
unpackAndOverwriteImport,
|
||||
};
|
|
@ -891,7 +891,7 @@ abort-controller@^3.0.0:
|
|||
dependencies:
|
||||
event-target-shim "^5.0.0"
|
||||
|
||||
accepts@~1.3.4, accepts@~1.3.8:
|
||||
accepts@~1.3.8:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
||||
integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
|
||||
|
@ -1226,11 +1226,6 @@ base64-js@^1.3.0, base64-js@^1.3.1, base64-js@^1.5.1:
|
|||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
batch@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
|
||||
integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==
|
||||
|
||||
bcrypt@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-5.1.0.tgz#bbb27665dbc400480a524d8991ac7434e8529e17"
|
||||
|
@ -1855,11 +1850,6 @@ depd@2.0.0, depd@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
|
||||
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
|
||||
|
||||
depd@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||
integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
|
||||
|
||||
deprecation@^2.0.0, deprecation@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
|
||||
|
@ -2895,16 +2885,6 @@ http-errors@2.0.0:
|
|||
statuses "2.0.1"
|
||||
toidentifier "1.0.1"
|
||||
|
||||
http-errors@~1.6.2:
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
|
||||
integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==
|
||||
dependencies:
|
||||
depd "~1.1.2"
|
||||
inherits "2.0.3"
|
||||
setprototypeof "1.1.0"
|
||||
statuses ">= 1.4.0 < 2"
|
||||
|
||||
http-proxy-agent@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"
|
||||
|
@ -3003,11 +2983,6 @@ inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
|
|||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
inherits@2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
|
||||
|
||||
ini@~1.3.0:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||
|
@ -3725,7 +3700,7 @@ mime-db@1.52.0:
|
|||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||
|
||||
mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34:
|
||||
mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34:
|
||||
version "2.1.35"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
||||
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||
|
@ -4341,7 +4316,7 @@ parent-module@^1.0.0:
|
|||
dependencies:
|
||||
callsites "^3.0.0"
|
||||
|
||||
parseurl@~1.3.2, parseurl@~1.3.3:
|
||||
parseurl@~1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
|
||||
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
|
||||
|
@ -4835,19 +4810,6 @@ send@0.18.0:
|
|||
range-parser "~1.2.1"
|
||||
statuses "2.0.1"
|
||||
|
||||
serve-index@^1.9.1:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
|
||||
integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==
|
||||
dependencies:
|
||||
accepts "~1.3.4"
|
||||
batch "0.6.1"
|
||||
debug "2.6.9"
|
||||
escape-html "~1.0.3"
|
||||
http-errors "~1.6.2"
|
||||
mime-types "~2.1.17"
|
||||
parseurl "~1.3.2"
|
||||
|
||||
serve-static@1.15.0:
|
||||
version "1.15.0"
|
||||
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
|
||||
|
@ -4882,11 +4844,6 @@ set-function-name@^2.0.0, set-function-name@^2.0.1:
|
|||
functions-have-names "^1.2.3"
|
||||
has-property-descriptors "^1.0.0"
|
||||
|
||||
setprototypeof@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
|
||||
integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
|
||||
|
||||
setprototypeof@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
|
||||
|
@ -5029,11 +4986,6 @@ statuses@2.0.1:
|
|||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
|
||||
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
|
||||
|
||||
"statuses@>= 1.4.0 < 2":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
|
||||
|
||||
stdin-discarder@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/stdin-discarder/-/stdin-discarder-0.1.0.tgz#22b3e400393a8e28ebf53f9958f3880622efde21"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue