Enabled importing and exporting of entire AnythingLLM instance data (#146)

* WIP on imports

* undo nodismiss for testing

* remove old keys modal screen
add helper text on import complete

* return default setting modal to keys
This commit is contained in:
Timothy Carambat 2023-07-14 17:32:30 -07:00 committed by GitHub
parent 5b2c5cac08
commit 6d651db6d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 803 additions and 304 deletions

View File

@ -1,289 +0,0 @@
import React, { useState, useEffect } from "react";
import { AlertCircle, Loader, X } from "react-feather";
import System from "../../models/system";
const noop = () => false;
export default function KeysModal({ hideModal = noop }) {
const [loading, setLoading] = useState(true);
const [settings, setSettings] = useState({});
useEffect(() => {
async function fetchKeys() {
const settings = await System.keys();
setSettings(settings);
setLoading(false);
}
fetchKeys();
}, []);
return (
<div className="fixed top-0 left-0 right-0 z-50 w-full p-4 overflow-x-hidden overflow-y-auto md:inset-0 h-[calc(100%-1rem)] h-full bg-black bg-opacity-50 flex items-center justify-center">
<div
className="flex fixed top-0 left-0 right-0 w-full h-full"
onClick={hideModal}
/>
<div className="relative w-full max-w-2xl max-h-full">
<div className="relative bg-white rounded-lg shadow dark:bg-stone-700">
<div className="flex items-start justify-between p-4 border-b rounded-t dark:border-gray-600">
<h3 className="text-xl font-semibold text-gray-900 dark:text-white">
System Settings
</h3>
<button
onClick={hideModal}
type="button"
className="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white"
data-modal-hide="staticModal"
>
<X className="text-gray-300 text-lg" />
</button>
</div>
<div className="p-6 space-y-6 flex h-full w-full">
{loading ? (
<div className="w-full h-full flex items-center justify-center">
<p className="text-gray-800 dark:text-gray-200 text-base">
loading system settings
</p>
</div>
) : (
<div className="w-full flex flex-col gap-y-4">
<div className="bg-orange-300 p-4 rounded-lg border border-orange-600 text-orange-700 w-full items-center flex gap-x-2">
<AlertCircle className="h-8 w-8" />
<p className="text-sm md:text-base ">
Ensure all fields are green before attempting to use
AnythingLLM or it may not function as expected!
</p>
</div>
<ShowKey
name="OpenAI API Key"
env="OpenAiKey"
value={settings?.OpenAiKey ? "*".repeat(20) : ""}
valid={settings?.OpenAiKey}
allowDebug={settings?.CanDebug}
/>
<ShowKey
name="OpenAI Model for chats"
env="OpenAiModelPref"
value={settings?.OpenAiModelPref}
valid={!!settings?.OpenAiModelPref}
allowDebug={settings?.CanDebug}
/>
<div className="h-[2px] w-full bg-gray-200 dark:bg-stone-600" />
<ShowKey
name="Vector DB Choice"
env="VectorDB"
value={settings?.VectorDB}
valid={!!settings?.VectorDB}
allowDebug={settings?.CanDebug}
/>
{settings?.VectorDB === "pinecone" && (
<>
<ShowKey
name="Pinecone DB API Key"
env="PineConeKey"
value={settings?.PineConeKey ? "*".repeat(20) : ""}
valid={!!settings?.PineConeKey}
allowDebug={settings?.CanDebug}
/>
<ShowKey
name="Pinecone DB Environment"
env="PineConeEnvironment"
value={settings?.PineConeEnvironment}
valid={!!settings?.PineConeEnvironment}
allowDebug={settings?.CanDebug}
/>
<ShowKey
name="Pinecone DB Index"
env="PineConeIndex"
value={settings?.PineConeIndex}
valid={!!settings?.PineConeIndex}
allowDebug={settings?.CanDebug}
/>
</>
)}
{settings?.VectorDB === "chroma" && (
<>
<ShowKey
name="Chroma Endpoint"
env="ChromaEndpoint"
value={settings?.ChromaEndpoint}
valid={!!settings?.ChromaEndpoint}
allowDebug={settings?.CanDebug}
/>
</>
)}
</div>
)}
</div>
<div className="flex items-center p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600">
<button
onClick={hideModal}
type="button"
className="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600"
>
Close
</button>
</div>
</div>
</div>
</div>
);
}
function ShowKey({ name, env, value, valid, allowDebug = true }) {
const [isValid, setIsValid] = useState(valid);
const [debug, setDebug] = useState(false);
const [saving, setSaving] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
setSaving(true);
const data = {};
const form = new FormData(e.target);
for (var [key, value] of form.entries()) data[key] = value;
const { newValues, error } = await System.updateSystem(data);
if (!!error) {
alert(error);
setSaving(false);
setIsValid(false);
return;
}
setSaving(false);
setDebug(false);
setIsValid(true);
};
if (!isValid) {
return (
<form onSubmit={handleSubmit}>
<div>
<label
htmlFor="error"
className="block mb-2 text-sm font-medium text-red-700 dark:text-red-500"
>
{name}
</label>
<input
type="text"
id="error"
name={env}
disabled={!debug}
className="bg-red-50 border border-red-500 text-red-900 placeholder-red-700 text-sm rounded-lg focus:ring-red-500 dark:bg-gray-700 focus:border-red-500 block w-full p-2.5 dark:text-red-500 dark:placeholder-red-500 dark:border-red-500"
placeholder={name}
defaultValue={value}
required={true}
autoComplete="off"
/>
<div className="flex items-center justify-between">
<p className="mt-2 text-sm text-red-600 dark:text-red-500">
Need setup in .env file.
</p>
{allowDebug && (
<>
{debug ? (
<div className="flex items-center gap-x-2 mt-2">
{saving ? (
<>
<Loader className="animate-spin h-4 w-4 text-slate-300 dark:text-slate-500" />
</>
) : (
<>
<button
type="button"
onClick={() => setDebug(false)}
className="text-xs text-slate-300 dark:text-slate-500"
>
Cancel
</button>
<button
type="submit"
className="text-xs text-blue-300 dark:text-blue-500"
>
Save
</button>
</>
)}
</div>
) : (
<button
type="button"
onClick={() => setDebug(true)}
className="mt-2 text-xs text-slate-300 dark:text-slate-500"
>
Debug
</button>
)}
</>
)}
</div>
</div>
</form>
);
}
return (
<form onSubmit={handleSubmit}>
<div className="mb-6">
<label
htmlFor="success"
className="block mb-2 text-sm font-medium text-gray-800 dark:text-slate-200"
>
{name}
</label>
<input
type="text"
id="success"
name={env}
disabled={!debug}
className="border border-white text-green-900 dark:text-green-400 placeholder-green-700 dark:placeholder-green-500 text-sm rounded-lg focus:ring-green-500 focus:border-green-500 block w-full p-2.5 dark:bg-gray-700 dark:border-green-500"
defaultValue={value}
required={true}
autoComplete="off"
/>
{allowDebug && (
<div className="flex items-center justify-end">
{debug ? (
<div className="flex items-center gap-x-2 mt-2">
{saving ? (
<>
<Loader className="animate-spin h-4 w-4 text-slate-300 dark:text-slate-500" />
</>
) : (
<>
<button
onClick={() => setDebug(false)}
className="text-xs text-slate-300 dark:text-slate-500"
>
Cancel
</button>
<button className="text-xs text-blue-300 dark:text-blue-500">
Save
</button>
</>
)}
</div>
) : (
<button
onClick={() => setDebug(true)}
className="mt-2 text-xs text-slate-300 dark:text-slate-500"
>
Debug
</button>
)}
</div>
)}
</div>
</form>
);
}
export function useKeysModal() {
const [showing, setShowing] = useState(false);
const showModal = () => {
setShowing(true);
};
const hideModal = () => {
setShowing(false);
};
return { showing, showModal, hideModal };
}

View File

@ -0,0 +1,214 @@
import React, { useState, useEffect, useRef } from "react";
import { AlertCircle, CheckCircle, Download, Loader, X } from "react-feather";
import System from "../../../../models/system";
import { API_BASE } from "../../../../utils/constants";
import paths from "../../../../utils/paths";
const noop = () => false;
export default function ExportOrImportData({ hideModal = noop }) {
return (
<div className="relative w-full max-w-2xl max-h-full">
<div className="relative bg-white rounded-lg shadow dark:bg-stone-700">
<div className="flex flex-col items-start justify-between px-6 py-4">
<p className="text-gray-800 dark:text-stone-200 text-base ">
Have multiple AnythingLLM instances or simply want to backup or
re-import data from another instance? You can do so here.
<br />
<i>
This will not automatically sync your vector database embeddings!
</i>
</p>
<a
className="text-gray-400 dark:text-stone-500 my-2 text-xs"
href={paths.exports()}
target="_blank"
>
View previous exports &rarr;
</a>
</div>
<div className="px-6 pb-6 space-y-6 flex h-full w-full">
<div className="flex flex-col w-full gap-y-2">
<ExportData />
<div className="h-[1px] bg-slate-400 dark:bg-stone-600 w-full my-2" />
<ImportData />
</div>
</div>
<div className="flex items-center p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600">
<button
onClick={hideModal}
type="button"
className="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600"
>
Close
</button>
</div>
</div>
</div>
);
}
function ExportData() {
const [loading, setLoading] = useState(false);
const [result, setResult] = useState(null);
const [error, setError] = useState(null);
const exportData = async function () {
setLoading(true);
const { filename, error } = await System.dataExport();
setLoading(false);
if (!filename) {
setError(error);
} else {
setResult(filename);
const link = document.createElement("a");
link.href = `${API_BASE}/system/data-exports/${filename}`;
link.target = "_blank";
document.body.appendChild(link);
link.click();
}
};
if (loading) {
return (
<div className="w-full flex flex-col gap-y-1 items-center px-6 py-4 border border-gray-200 rounded-lg dark:border-gray-600 bg-slate-200 group animate-pulse">
<p className="text-gray-800 text-lg">Exporting....</p>
<p className="text-gray-800 text-sm italic">
A download will start automatically.
</p>
</div>
);
}
if (error) {
return (
<button
type="button"
onClick={() => setError(null)}
className="w-full flex flex-col gap-y-1 items-center px-6 py-4 border border-red-200 rounded-lg dark:border-red-600 bg-red-200 group"
>
<p className="text-red-800 text-sm">{error}</p>
</button>
);
}
if (!!result) {
return (
<a
target="_blank"
href={`${API_BASE}/system/data-exports/${result}`}
className="w-full flex gap-1 justify-center items-center px-6 py-4 border border-green-200 rounded-lg dark:border-green-600 bg-green-200 group"
>
<Download className="h-4 w-4 text-green-800 " />
<p className="text-green-800 text-sm">Download Data Export</p>
</a>
);
}
return (
<button
onClick={exportData}
type="button"
className="w-full flex justify-center px-6 py-4 border border-gray-200 rounded-lg dark:border-gray-600 hover:bg-slate-200 group"
>
<p className="text-gray-800 dark:text-stone-200 group-hover:text-gray-800 text-lg">
Export AnythingLLM data
</p>
</button>
);
}
function ImportData() {
const inputRef = useRef(null);
const [loading, setLoading] = useState(false);
const [file, setFile] = useState(null);
const [result, setResult] = useState(null);
const [error, setError] = useState(null);
const startInput = () => inputRef?.current?.click();
const handleUpload = async (e) => {
e.preventDefault();
setError(null);
setFile(null);
setResult(null);
const file = e.target.files?.[0];
if (!file) {
setError("Invalid file upload");
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) {
setError(error);
} else {
setResult(true);
}
setLoading(false);
setFile(null);
};
if (loading) {
return (
<div className="w-full flex flex-col gap-y-1 items-center px-6 py-4 border border-gray-200 rounded-lg dark:border-gray-600 bg-slate-200 group animate-pulse">
<p className="text-gray-800 text-lg">Importing....</p>
<p className="text-gray-800 text-sm italic">{file.name}</p>
</div>
);
}
if (error) {
return (
<button
type="button"
onClick={() => setError(null)}
className="w-full flex flex-col gap-y-1 items-center px-6 py-4 border border-red-200 rounded-lg dark:border-red-600 bg-red-200 group"
>
<p className="text-red-800 text-sm">{error}</p>
</button>
);
}
if (!!result) {
return (
<div className="w-full flex flex-col gap-y-1 gap-1 justify-center items-center px-6 py-4 border border-green-200 rounded-lg dark:border-green-600 bg-green-200 group">
<div className="flex items-center gap-x-1">
<CheckCircle className="h-4 w-4 text-green-800 " />
<p className="text-green-800 text-sm">
Import was completed successfully
</p>
</div>
<p className="text-green-800 text-xs italic">please reload the page to see the results of the import.</p>
</div>
);
}
return (
<>
<input
ref={inputRef}
onChange={handleUpload}
name="import"
type="file"
multiple="false"
accept=".zip"
hidden={true}
/>
<button
type="button"
onClick={startInput}
className="w-full flex flex-col gap-y-1 items-center px-6 py-4 border border-gray-200 rounded-lg dark:border-gray-600 hover:bg-slate-200 group"
>
<p className="text-gray-800 dark:text-stone-200 group-hover:text-gray-800 text-lg">
Import AnythingLLM data
</p>
<p className="text-gray-800 dark:text-stone-200 group-hover:text-gray-800 text-xs italic">
this must be an export from an AnythingLLM instance.
</p>
</button>
</>
);
}

View File

@ -1,9 +1,11 @@
import React, { useState } from "react";
import { Key, X } from "react-feather";
import { Archive, Cloud, Key, X } from "react-feather";
import SystemKeys from "./Keys";
import ExportOrImportData from "./ExportImport";
const TABS = {
keys: SystemKeys,
exportimport: ExportOrImportData,
};
const noop = () => false;
@ -53,6 +55,13 @@ function SettingTabs({ selectedTab, changeTab }) {
icon={<Key className="h-4 w-4 flex-shrink-0" />}
onClick={changeTab}
/>
<SettingTab
active={selectedTab === "exportimport"}
displayName="Export or Import"
tabName="exportimport"
icon={<Archive className="h-4 w-4 flex-shrink-0" />}
onClick={changeTab}
/>
</ul>
</div>
);

View File

@ -185,11 +185,10 @@ export function SidebarMobileHeader() {
className={`z-99 fixed top-0 left-0 transition-all duration-500 w-[100vw] h-[100vh]`}
>
<div
className={`${
showBgOverlay
className={`${showBgOverlay
? "transition-all opacity-1"
: "transition-none opacity-0"
} duration-500 fixed top-0 left-0 bg-black-900 bg-opacity-75 w-screen h-screen`}
} duration-500 fixed top-0 left-0 bg-black-900 bg-opacity-75 w-screen h-screen`}
onClick={() => setShowSidebar(false)}
/>
<div

View File

@ -98,6 +98,31 @@ 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 };
});
},
};
export default System;

View File

@ -1,3 +1,5 @@
import { API_BASE } from "./constants";
export default {
home: () => {
return "/";
@ -19,4 +21,7 @@ export default {
return `/workspace/${slug}`;
},
},
exports: () => {
return `${API_BASE.replace("/api", "")}/system/data-exports`;
},
};

2
server/.gitignore vendored
View File

@ -2,6 +2,8 @@
.env.development
storage/documents/*
storage/vector-cache/*.json
storage/exports
storage/imports
!storage/documents/DOCUMENTS.md
logs/server.log
*.db

View File

@ -3,6 +3,7 @@ process.env.NODE_ENV === "development"
: require("dotenv").config();
const { validateTablePragmas } = require("../utils/database");
const { viewLocalFiles } = require("../utils/files");
const { exportData, unpackAndOverwriteImport } = require("../utils/files/data");
const {
checkPythonAppAlive,
acceptedFileTypes,
@ -11,6 +12,8 @@ const { purgeDocument } = require("../utils/files/purgeDocument");
const { getVectorDbClass } = require("../utils/helpers");
const { updateENV } = require("../utils/helpers/updateENV");
const { reqBody, makeJWT } = require("../utils/http");
const { setupDataImports } = require("../utils/files/multer");
const { handleImports } = setupDataImports();
function systemEndpoints(app) {
if (!app) return;
@ -151,6 +154,39 @@ function systemEndpoints(app) {
response.sendStatus(500).end();
}
});
app.get("/system/data-export", 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 filePath =
__dirname + "/../storage/exports/" + request.params.filename;
response.download(filePath, request.params.filename, (err) => {
if (err) {
response.send({
error: err,
msg: "Problem downloading the file",
});
}
});
});
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 });
}
);
}
module.exports = { systemEndpoints };

View File

@ -4,6 +4,7 @@ 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 { validatedRequest } = require("./utils/middleware/validatedRequest");
@ -72,6 +73,11 @@ if (process.env.NODE_ENV !== "development") {
});
}
app.use(
"/system/data-exports",
serveIndex(__dirname + "/storage/exports", { icons: true })
);
app.all("*", function (_, response) {
response.sendStatus(404);
});

View File

@ -17,17 +17,20 @@
"dependencies": {
"@googleapis/youtube": "^9.0.0",
"@pinecone-database/pinecone": "^0.1.6",
"archiver": "^5.3.1",
"body-parser": "^1.20.2",
"chromadb": "^1.5.2",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"extract-zip": "^2.0.1",
"jsonwebtoken": "^8.5.1",
"langchain": "^0.0.90",
"moment": "^2.29.4",
"multer": "^1.4.5-lts.1",
"openai": "^3.2.1",
"pinecone-client": "^1.1.0",
"serve-index": "^1.9.1",
"slugify": "^1.6.6",
"sqlite": "^4.2.1",
"sqlite3": "^5.1.6",
@ -38,4 +41,4 @@
"nodemon": "^2.0.22",
"prettier": "^2.4.1"
}
}
}

197
server/utils/files/data.js Normal file
View File

@ -0,0 +1,197 @@
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,
};

View File

@ -20,6 +20,28 @@ function setupMulter() {
return { handleUploads: upload };
}
function setupDataImports() {
const multer = require("multer");
// Handle File uploads for auto-uploading.
const storage = multer.diskStorage({
destination: function (_, _, cb) {
const path = require("path");
const fs = require("fs");
const uploadOutput = path.resolve(__dirname, `../../storage/imports`);
fs.mkdirSync(uploadOutput, { recursive: true });
return cb(null, uploadOutput);
},
filename: function (_, file, cb) {
cb(null, file.originalname);
},
});
const upload = multer({
storage,
});
return { handleImports: upload };
}
module.exports = {
setupMulter,
setupDataImports,
};

View File

@ -96,6 +96,11 @@
resolved "https://registry.yarnpkg.com/@types/command-line-usage/-/command-line-usage-5.0.2.tgz#ba5e3f6ae5a2009d466679cc431b50635bf1a064"
integrity sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg==
"@types/node@*":
version "20.4.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9"
integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==
"@types/node@18.14.5":
version "18.14.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.5.tgz#4a13a6445862159303fc38586598a9396fc408b3"
@ -111,12 +116,19 @@
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d"
integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
"@types/yauzl@^2.9.1":
version "2.10.0"
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599"
integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==
dependencies:
"@types/node" "*"
abbrev@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
accepts@~1.3.8:
accepts@~1.3.4, 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==
@ -199,6 +211,35 @@ append-field@^1.0.0:
resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc"
integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==
archiver-utils@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2"
integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==
dependencies:
glob "^7.1.4"
graceful-fs "^4.2.0"
lazystream "^1.0.0"
lodash.defaults "^4.2.0"
lodash.difference "^4.5.0"
lodash.flatten "^4.4.0"
lodash.isplainobject "^4.0.6"
lodash.union "^4.6.0"
normalize-path "^3.0.0"
readable-stream "^2.0.0"
archiver@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.1.tgz#21e92811d6f09ecfce649fbefefe8c79e57cbbb6"
integrity sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==
dependencies:
archiver-utils "^2.1.0"
async "^3.2.3"
buffer-crc32 "^0.2.1"
readable-stream "^3.6.0"
readdir-glob "^1.0.0"
tar-stream "^2.2.0"
zip-stream "^4.1.0"
are-we-there-yet@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c"
@ -235,6 +276,11 @@ arrify@^2.0.0:
resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
async@^3.2.3:
version "3.2.4"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@ -252,11 +298,16 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64-js@^1.3.0, base64-js@^1.5.1:
base64-js@^1.3.0, base64-js@^1.3.1, base64-js@^1.5.1:
version "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==
bignumber.js@^9.0.0:
version "9.1.1"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6"
@ -272,6 +323,15 @@ binary-search@^1.3.5:
resolved "https://registry.yarnpkg.com/binary-search/-/binary-search-1.3.6.tgz#e32426016a0c5092f0f3598836a1c7da3560565c"
integrity sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==
bl@^4.0.3:
version "4.1.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
dependencies:
buffer "^5.5.0"
inherits "^2.0.4"
readable-stream "^3.4.0"
body-parser@1.20.1:
version "1.20.1"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
@ -316,6 +376,13 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
@ -323,6 +390,11 @@ braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
buffer-equal-constant-time@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
@ -333,6 +405,14 @@ buffer-from@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.1.13"
busboy@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
@ -460,6 +540,16 @@ command-line-usage@6.1.3:
table-layout "^1.0.2"
typical "^5.2.0"
compress-commons@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.1.tgz#df2a09a7ed17447642bad10a85cc9a19e5c42a7d"
integrity sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==
dependencies:
buffer-crc32 "^0.2.13"
crc32-stream "^4.0.2"
normalize-path "^3.0.0"
readable-stream "^3.6.0"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@ -515,6 +605,19 @@ cors@^2.8.5:
object-assign "^4"
vary "^1"
crc-32@^1.2.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff"
integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
crc32-stream@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.2.tgz#c922ad22b38395abe9d3870f02fa8134ed709007"
integrity sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==
dependencies:
crc-32 "^1.2.0"
readable-stream "^3.4.0"
cross-fetch@^3.1.5:
version "3.1.6"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.6.tgz#bae05aa31a4da760969756318feeee6e70f15d6c"
@ -529,7 +632,7 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
debug@4, debug@^4.1.0, debug@^4.3.3:
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.3:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@ -563,6 +666,11 @@ 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==
destroy@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
@ -607,6 +715,13 @@ encoding@^0.1.12:
dependencies:
iconv-lite "^0.6.2"
end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
dependencies:
once "^1.4.0"
env-paths@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
@ -684,11 +799,29 @@ extend@^3.0.2:
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extract-zip@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
dependencies:
debug "^4.1.1"
get-stream "^5.1.0"
yauzl "^2.10.0"
optionalDependencies:
"@types/yauzl" "^2.9.1"
fast-text-encoding@^1.0.0:
version "1.0.6"
resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz#0aa25f7f638222e3396d72bf936afcf1d42d6867"
integrity sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==
fd-slicer@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==
dependencies:
pend "~1.2.0"
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
@ -750,6 +883,11 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
fs-constants@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
@ -829,6 +967,13 @@ get-intrinsic@^1.0.2:
has-proto "^1.0.1"
has-symbols "^1.0.3"
get-stream@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
dependencies:
pump "^3.0.0"
glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@ -882,7 +1027,7 @@ googleapis-common@^6.0.3:
url-template "^2.0.8"
uuid "^9.0.0"
graceful-fs@^4.2.6:
graceful-fs@^4.2.0, graceful-fs@^4.2.6:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
@ -939,6 +1084,16 @@ 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"
@ -977,6 +1132,11 @@ iconv-lite@^0.6.2:
dependencies:
safer-buffer ">= 2.1.2 < 3.0.0"
ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
ignore-by-default@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
@ -1005,11 +1165,16 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3:
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
version "2.0.4"
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==
ip@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
@ -1175,11 +1340,33 @@ langchain@^0.0.90:
zod "^3.21.4"
zod-to-json-schema "^3.20.4"
lazystream@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638"
integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==
dependencies:
readable-stream "^2.0.5"
lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==
lodash.difference@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c"
integrity sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==
lodash.includes@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
@ -1215,6 +1402,11 @@ lodash.once@^4.0.0:
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
lodash.union@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@ -1271,7 +1463,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.24, mime-types@~2.1.34:
mime-types@^2.1.12, mime-types@~2.1.17, 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==
@ -1290,6 +1482,13 @@ minimatch@^3.1.1, minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
minimatch@^5.1.0:
version "5.1.6"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"
minimist@^1.2.6:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
@ -1555,7 +1754,7 @@ on-finished@2.4.1:
dependencies:
ee-first "1.1.1"
once@^1.3.0:
once@^1.3.0, once@^1.3.1, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
@ -1612,7 +1811,7 @@ pad-left@^2.1.0:
dependencies:
repeat-string "^1.5.4"
parseurl@~1.3.3:
parseurl@~1.3.2, 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==
@ -1627,6 +1826,11 @@ path-to-regexp@0.1.7:
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
picomatch@^2.0.4, picomatch@^2.2.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
@ -1675,6 +1879,14 @@ pstree.remy@^1.1.8:
resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
qs@6.11.0:
version "6.11.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
@ -1714,7 +1926,7 @@ raw-body@2.5.2:
iconv-lite "0.4.24"
unpipe "1.0.0"
readable-stream@^2.2.2:
readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2:
version "2.3.8"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
@ -1727,7 +1939,7 @@ readable-stream@^2.2.2:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^3.6.0:
readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
@ -1736,6 +1948,13 @@ readable-stream@^3.6.0:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
readdir-glob@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.3.tgz#c3d831f51f5e7bfa62fa2ffbe4b508c640f09584"
integrity sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==
dependencies:
minimatch "^5.1.0"
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
@ -1826,6 +2045,19 @@ 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"
@ -1841,6 +2073,11 @@ set-blocking@^2.0.0:
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
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"
@ -1922,6 +2159,11 @@ 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==
streamsearch@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
@ -1974,6 +2216,17 @@ table-layout@^1.0.2:
typical "^5.2.0"
wordwrapjs "^4.0.0"
tar-stream@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
dependencies:
bl "^4.0.3"
end-of-stream "^1.4.1"
fs-constants "^1.0.0"
inherits "^2.0.3"
readable-stream "^3.1.1"
tar@^6.0.2, tar@^6.1.11, tar@^6.1.2:
version "6.1.15"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69"
@ -2150,6 +2403,23 @@ yaml@^2.2.1:
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b"
integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==
yauzl@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
dependencies:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"
zip-stream@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.0.tgz#51dd326571544e36aa3f756430b313576dc8fc79"
integrity sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==
dependencies:
archiver-utils "^2.1.0"
compress-commons "^4.1.0"
readable-stream "^3.6.0"
zod-to-json-schema@^3.20.4:
version "3.21.1"
resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.21.1.tgz#a24b2737bf361fc516c92421eb59988b6e2fc046"