Blame Raw
· · · 103 lines (3.5 KB)
0 contributors
1import fs from 'node:fs';
2import path from 'node:path';
3
4import express from 'express';
5import sanitize from 'sanitize-filename';
6import { sync as writeFileAtomicSync } from 'write-file-atomic';
7
8import { getDefaultPresetFile, getDefaultPresets } from './content-manager.js';
9
10/**
11 * Gets the folder and extension for the preset settings based on the API source ID.
12 * @param {string} apiId API source ID
13 * @param {import('../users.js').UserDirectoryList} directories User directories
14 * @returns {{folder: string?, extension: string?}} Object containing the folder and extension for the preset settings
15 */
16function getPresetSettingsByAPI(apiId, directories) {
17 switch (apiId) {
18 case 'kobold':
19 case 'koboldhorde':
20 return { folder: directories.koboldAI_Settings, extension: '.json' };
21 case 'novel':
22 return { folder: directories.novelAI_Settings, extension: '.json' };
23 case 'textgenerationwebui':
24 return { folder: directories.textGen_Settings, extension: '.json' };
25 case 'openai':
26 return { folder: directories.openAI_Settings, extension: '.json' };
27 case 'instruct':
28 return { folder: directories.instruct, extension: '.json' };
29 case 'context':
30 return { folder: directories.context, extension: '.json' };
31 case 'sysprompt':
32 return { folder: directories.sysprompt, extension: '.json' };
33 case 'reasoning':
34 return { folder: directories.reasoning, extension: '.json' };
35 default:
36 return { folder: null, extension: null };
37 }
38}
39
40export const router = express.Router();
41
42router.post('/save', function (request, response) {
43 const name = sanitize(request.body.name);
44 if (!request.body.preset || !name) {
45 return response.sendStatus(400);
46 }
47
48 const settings = getPresetSettingsByAPI(request.body.apiId, request.user.directories);
49 const filename = name + settings.extension;
50
51 if (!settings.folder) {
52 return response.sendStatus(400);
53 }
54
55 const fullpath = path.join(settings.folder, filename);
56 writeFileAtomicSync(fullpath, JSON.stringify(request.body.preset, null, 4), 'utf-8');
57 return response.send({ name });
58});
59
60router.post('/delete', function (request, response) {
61 const name = sanitize(request.body.name);
62 if (!name) {
63 return response.sendStatus(400);
64 }
65
66 const settings = getPresetSettingsByAPI(request.body.apiId, request.user.directories);
67 const filename = name + settings.extension;
68
69 if (!settings.folder) {
70 return response.sendStatus(400);
71 }
72
73 const fullpath = path.join(settings.folder, filename);
74
75 if (fs.existsSync(fullpath)) {
76 fs.unlinkSync(fullpath);
77 return response.sendStatus(200);
78 } else {
79 return response.sendStatus(404);
80 }
81});
82
83router.post('/restore', function (request, response) {
84 try {
85 const settings = getPresetSettingsByAPI(request.body.apiId, request.user.directories);
86 const name = sanitize(request.body.name);
87 const defaultPresets = getDefaultPresets(request.user.directories);
88
89 const defaultPreset = defaultPresets.find(p => p.name === name && p.folder === settings.folder);
90
91 const result = { isDefault: false, preset: {} };
92
93 if (defaultPreset) {
94 result.isDefault = true;
95 result.preset = getDefaultPresetFile(defaultPreset.filename) || {};
96 }
97
98 return response.send(result);
99 } catch (error) {
100 console.error(error);
101 return response.sendStatus(500);
102 }
103});