173 lines
7.4 KiB
JavaScript
173 lines
7.4 KiB
JavaScript
(function() {
|
|
const extensionName = "Amily-Databin";
|
|
const apiBaseUrl = `/api/plugins/${extensionName}`;
|
|
|
|
// ----------------------------------------------------------------
|
|
// Private Helper Functions
|
|
// ----------------------------------------------------------------
|
|
|
|
/**
|
|
* Retrieves the current context from SillyTavern and maps it to the expected object name.
|
|
* This function attempts to get context dynamically from SillyTavern's global objects.
|
|
*/
|
|
function _getDynamicObjectName(source) {
|
|
const { SillyTavern } = window;
|
|
let context = null;
|
|
if (SillyTavern && typeof SillyTavern.getContext === 'function') {
|
|
context = SillyTavern.getContext();
|
|
} else {
|
|
console.error(`[${extensionName}] window.SillyTavern.getContext() not found. Dynamic context resolution is not possible.`);
|
|
return null;
|
|
}
|
|
|
|
if (!context) {
|
|
console.error(`[${extensionName}] SillyTavern context is null or undefined.`);
|
|
return null;
|
|
}
|
|
|
|
let resolvedObjectName = null;
|
|
|
|
switch (source) {
|
|
case AmilyDatabin.SourceType.CHAT_LOG:
|
|
resolvedObjectName = context.chatId;
|
|
break;
|
|
case AmilyDatabin.SourceType.CHARACTER_CARD:
|
|
resolvedObjectName = context.characterId;
|
|
break;
|
|
case AmilyDatabin.SourceType.WORLD_BOOK:
|
|
// From the provided getContext() structure, there is no direct 'current world book name' key.
|
|
// The user must provide objName for WORLD_BOOK type, or implement custom logic to detect it.
|
|
console.warn(`[${extensionName}] 'WORLD_BOOK' type's object name cannot be automatically resolved from SillyTavern.getContext(). Please provide 'objName' explicitly.`);
|
|
break;
|
|
default:
|
|
console.error(`[${extensionName}] Unknown source type for dynamic resolution: ${source}`);
|
|
return null;
|
|
}
|
|
|
|
if (!resolvedObjectName) {
|
|
console.warn(`[${extensionName}] Could not dynamically resolve object name for source type ${source}. Context key might be missing or not active.`);
|
|
}
|
|
return resolvedObjectName;
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
// Public API Method Implementations
|
|
// ----------------------------------------------------------------
|
|
|
|
async function initialize() {
|
|
try {
|
|
const response = await fetch(`${apiBaseUrl}/sourcetype`);
|
|
if (!response.ok) throw new Error(`Failed to fetch source types: ${response.status}`);
|
|
this.SourceType = await response.json(); // 'this' refers to AmilyDatabin object
|
|
console.log(`[${extensionName}] Client initialized with source types:`, this.SourceType);
|
|
} catch (error) {
|
|
console.error(`[${extensionName}] Initialization failed:`, error);
|
|
}
|
|
}
|
|
|
|
async function getData(source, fileName, objName = null) {
|
|
const objectName = objName ?? _getDynamicObjectName(source);
|
|
if (!objectName) {
|
|
console.error(`[${extensionName}] 'objName' could not be resolved for getData (Source: ${source}, File: ${fileName}).`);
|
|
return null;
|
|
}
|
|
try {
|
|
const queryParams = new URLSearchParams({ source, objName: objectName, file: fileName });
|
|
const response = await fetch(`${apiBaseUrl}/data?${queryParams.toString()}`);
|
|
if (response.status === 404) return null;
|
|
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error(`[${extensionName}] getData failed (Source: ${source}, ObjName: ${objectName}, File: ${fileName}):`, error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function saveData(source, fileName, fileContent, objName = null) {
|
|
const objectName = objName ?? _getDynamicObjectName(source);
|
|
if (!objectName) {
|
|
console.error(`[${extensionName}] 'objName' could not be resolved for saveData (Source: ${source}, File: ${fileName}).`);
|
|
return false;
|
|
}
|
|
try {
|
|
const response = await fetch(`${apiBaseUrl}/data`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ source, objName: objectName, file: fileName, data: fileContent }),
|
|
});
|
|
if (!response.ok) {
|
|
const errorText = await response.text();
|
|
throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
|
|
}
|
|
console.log(`[${extensionName}] Data saved to: ${source}/${objectName}/${fileName}`);
|
|
return true;
|
|
} catch (error) {
|
|
console.error(`[${extensionName}] saveData failed (Source: ${source}, ObjName: ${objectName}, File: ${fileName}):`, error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function deleteData(source, fileName, objName = null) {
|
|
const objectName = objName ?? _getDynamicObjectName(source);
|
|
if (!objectName) {
|
|
console.error(`[${extensionName}] 'objName' could not be resolved for deleteData (Source: ${source}, File: ${fileName}).`);
|
|
return false;
|
|
}
|
|
try {
|
|
const queryParams = new URLSearchParams({ source, objName: objectName, file: fileName });
|
|
const response = await fetch(`${apiBaseUrl}/data?${queryParams.toString()}`, { method: 'DELETE' });
|
|
if (!response.ok) {
|
|
const errorText = await response.text();
|
|
throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
|
|
}
|
|
console.log(`[${extensionName}] Data deleted from: ${source}/${objectName}/${fileName}`);
|
|
return true;
|
|
} catch (error) {
|
|
console.error(`[${extensionName}] deleteData failed (Source: ${source}, ObjName: ${objectName}, File: ${fileName}):`, error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
// Debug Methods
|
|
// ----------------------------------------------------------------
|
|
|
|
function getDebugInstance() {
|
|
console.log(`[${extensionName}] AmilyDatabin Instance:`, AmilyDatabin);
|
|
return AmilyDatabin;
|
|
}
|
|
|
|
function getDebugChatId() {
|
|
const chatId = _getDynamicObjectName(AmilyDatabin.SourceType.CHAT_LOG);
|
|
console.log(`[${extensionName}] Current Chat ID (Debug):`, chatId);
|
|
return chatId;
|
|
}
|
|
|
|
function getDebugCardId() {
|
|
const cardId = _getDynamicObjectName(AmilyDatabin.SourceType.CHARACTER_CARD);
|
|
console.log(`[${extensionName}] Current Character Card ID (Debug):`, cardId);
|
|
return cardId;
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
// Global Object Definition
|
|
// ----------------------------------------------------------------
|
|
|
|
const AmilyDatabin = {
|
|
SourceType: {},
|
|
initialize,
|
|
getData,
|
|
saveData,
|
|
deleteData,
|
|
// Debug methods
|
|
getDebugInstance,
|
|
getDebugChatId,
|
|
getDebugCardId
|
|
};
|
|
|
|
window.AmilyDatabin = AmilyDatabin;
|
|
|
|
// Automatically initialize the module.
|
|
window.AmilyDatabin.initialize.bind(window.AmilyDatabin)();
|
|
|
|
})(); |