Manage extensions via the assets plugin

This commit is contained in:
Cohee 2023-10-08 23:20:01 +03:00
parent 4f80085fa3
commit 54d52a2986
4 changed files with 73 additions and 39 deletions

View File

@ -143,7 +143,7 @@ import {
onlyUnique,
} from "./scripts/utils.js";
import { extension_settings, getContext, loadExtensionSettings, processExtensionHelpers, registerExtensionHelper, runGenerationInterceptors, saveMetadataDebounced } from "./scripts/extensions.js";
import { extension_settings, getContext, installExtension, loadExtensionSettings, processExtensionHelpers, registerExtensionHelper, runGenerationInterceptors, saveMetadataDebounced } from "./scripts/extensions.js";
import { COMMENT_NAME_DEFAULT, executeSlashCommands, getSlashCommandsHelp, registerSlashCommand } from "./scripts/slash-commands.js";
import {
tag_map,
@ -8898,25 +8898,7 @@ jQuery(async function () {
}
const url = input.trim();
console.debug('Extension import started', url);
const request = await fetch('/api/extensions/install', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({ url }),
});
if (!request.ok) {
toastr.info(request.statusText, 'Extension import failed');
console.error('Extension import failed', request.status, request.statusText);
return;
}
const response = await request.json();
toastr.success(`Extension "${response.display_name}" by ${response.author} (version ${response.version}) has been imported successfully!`, 'Extension import successful');
console.debug(`Extension "${response.display_name}" has been imported successfully at ${response.extensionPath}`);
await loadExtensionSettings(settings);
eventSource.emit(event_types.EXTENSION_SETTINGS_LOADED);
await installExtension(url);
});

View File

@ -11,7 +11,7 @@ export {
ModuleWorkerWrapper,
};
let extensionNames = [];
export let extensionNames = [];
let manifests = {};
const defaultUrl = "http://localhost:5100";
@ -639,23 +639,26 @@ async function onDeleteClick() {
// use callPopup to create a popup for the user to confirm before delete
const confirmation = await callPopup(`Are you sure you want to delete ${extensionName}?`, 'delete_extension');
if (confirmation) {
try {
const response = await fetch('/api/extensions/delete', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({ extensionName })
});
} catch (error) {
console.error('Error:', error);
}
toastr.success(`Extension ${extensionName} deleted`);
showExtensionsDetails();
// reload the page to remove the extension from the list
location.reload();
await deleteExtension(extensionName);
}
};
export async function deleteExtension(extensionName) {
try {
const response = await fetch('/api/extensions/delete', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({ extensionName })
});
} catch (error) {
console.error('Error:', error);
}
toastr.success(`Extension ${extensionName} deleted`);
showExtensionsDetails();
// reload the page to remove the extension from the list
location.reload();
}
/**
* Fetches the version details of a specific extension.
@ -680,7 +683,32 @@ async function getExtensionVersion(extensionName) {
}
}
/**
* Installs a third-party extension via the API.
* @param {string} url Extension repository URL
* @returns {Promise<void>}
*/
export async function installExtension(url) {
console.debug('Extension import started', url);
const request = await fetch('/api/extensions/install', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({ url }),
});
if (!request.ok) {
toastr.info(request.statusText, 'Extension import failed');
console.error('Extension import failed', request.status, request.statusText);
return;
}
const response = await request.json();
toastr.success(`Extension "${response.display_name}" by ${response.author} (version ${response.version}) has been imported successfully!`, 'Extension import successful');
console.debug(`Extension "${response.display_name}" has been imported successfully at ${response.extensionPath}`);
await loadExtensionSettings({});
eventSource.emit(event_types.EXTENSION_SETTINGS_LOADED);
}
async function loadExtensionSettings(settings) {
if (settings.extension_settings) {

View File

@ -5,6 +5,7 @@ TODO:
//const DEBUG_TONY_SAMA_FORK_MODE = false
import { getRequestHeaders, callPopup } from "../../../script.js";
import { deleteExtension, extensionNames, installExtension } from "../../extensions.js";
export { MODULE_NAME };
const MODULE_NAME = 'Assets';
@ -116,9 +117,13 @@ function downloadAssetsList(url) {
console.debug(DEBUG_PREFIX, "Created element for BGM", asset["id"])
const displayName = DOMPurify.sanitize(asset["name"] || asset["id"]);
const description = DOMPurify.sanitize(asset["description"] || "");
$(`<i></i>`)
.append(element)
.append(`<span>${asset["id"]}</span>`)
.append(`<span>${displayName}</span>`)
.append(`<span>${description}</span>`)
.appendTo(assetTypeMenu);
}
assetTypeMenu.appendTo("#assets_menu");
@ -136,7 +141,14 @@ function downloadAssetsList(url) {
}
function isAssetInstalled(assetType, filename) {
for (const i of currentAssets[assetType]) {
let assetList = currentAssets[assetType];
if (assetType == 'extension') {
const thirdPartyMarker = "third-party/";
assetList = extensionNames.filter(x => x.startsWith(thirdPartyMarker)).map(x => x.replace(thirdPartyMarker, ''));
}
for (const i of assetList) {
//console.debug(DEBUG_PREFIX,i,filename)
if (i.includes(filename))
return true;
@ -149,6 +161,13 @@ async function installAsset(url, assetType, filename) {
console.debug(DEBUG_PREFIX, "Downloading ", url);
const category = assetType;
try {
if (category === 'extension') {
console.debug(DEBUG_PREFIX, "Installing extension ", url)
await installExtension(url);
console.debug(DEBUG_PREFIX, "Extension installed.")
return;
}
const body = { url, category, filename };
const result = await fetch('/api/assets/download', {
method: 'POST',
@ -170,6 +189,12 @@ async function deleteAsset(assetType, filename) {
console.debug(DEBUG_PREFIX, "Deleting ", assetType, filename);
const category = assetType;
try {
if (category === 'extension') {
console.debug(DEBUG_PREFIX, "Deleting extension ", filename)
await deleteExtension(filename);
console.debug(DEBUG_PREFIX, "Extension deleted.")
}
const body = { category, filename };
const result = await fetch('/api/assets/delete', {
method: 'POST',

View File

@ -19,6 +19,7 @@
align-items: center;
justify-content: left;
padding: 5px;
font-style: normal;
}
.assets-list-div i span{
@ -34,7 +35,7 @@
border-radius: 2px;
cursor: pointer;
}
.asset-download-button:active {
background: #007a63;
}
@ -75,5 +76,3 @@ to {
transform: rotate(1turn);
}
}