From 113ea1d0ec786a08682cd8ee3299b7ef3daedf43 Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 11:24:22 -0700 Subject: [PATCH 01/16] JSON.parse wants a string --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index f4e5b2246..7fef8f2c0 100644 --- a/server.js +++ b/server.js @@ -4181,7 +4181,7 @@ function migrateSecrets() { try { let modified = false; const fileContents = fs.readFileSync(SETTINGS_FILE, 'utf8'); - const settings = JSON.parse(fileContents); + const settings = JSON.parse(fileContents.toString()); const oaiKey = settings?.api_key_openai; const hordeKey = settings?.horde_settings?.api_key; const novelKey = settings?.api_key_novel; From 3feeaaa09f77f1896d11c7b908459129b5c4292c Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 11:32:13 -0700 Subject: [PATCH 02/16] listen requires a number, `URL` port is string wtf --- server.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index 7fef8f2c0..85fcfd69d 100644 --- a/server.js +++ b/server.js @@ -4053,23 +4053,24 @@ if (listen && !config.whitelistMode && !config.basicAuthMode) { } } -if (true === cliArguments.ssl) +if (true === cliArguments.ssl) { https.createServer( { cert: fs.readFileSync(cliArguments.certPath), key: fs.readFileSync(cliArguments.keyPath) }, app) .listen( - tavernUrl.port || 443, + Number(tavernUrl.port) || 443, tavernUrl.hostname, setupTasks ); -else +} else { http.createServer(app).listen( - tavernUrl.port || 80, + Number(tavernUrl.port) || 80, tavernUrl.hostname, setupTasks ); +} async function convertWebp() { const files = fs.readdirSync(directories.characters).filter(e => e.endsWith(".webp")); From cd8027aeea2d4032b9d3d343dfdf51c0aa77d226 Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 11:34:45 -0700 Subject: [PATCH 03/16] fixes 7 errs. see yargs typescript docs. test plz --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 85fcfd69d..34d6b9432 100644 --- a/server.js +++ b/server.js @@ -113,7 +113,7 @@ const cliArguments = yargs(hideBin(process.argv)) type: 'string', default: 'certs/privkey.pem', describe: 'Path to your private key file.' - }).argv; + }).parseSync(); // change all relative paths const directory = process['pkg'] ? path.dirname(process.execPath) : __dirname; From aa901883d2c69dd6ec96227cb26b944b2d406f00 Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 11:39:51 -0700 Subject: [PATCH 04/16] node v18 type-checker hates this, ignore it --- server.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index 34d6b9432..0fd6da679 100644 --- a/server.js +++ b/server.js @@ -91,10 +91,8 @@ function createDefaultFiles() { } const net = require("net"); -// work around a node v20 bug: https://github.com/nodejs/node/issues/47822#issuecomment-1564708870 -if (net.setDefaultAutoSelectFamily) { - net.setDefaultAutoSelectFamily(false); -} +// @ts-ignore work around a node v20 bug: https://github.com/nodejs/node/issues/47822#issuecomment-1564708870 +if (net.setDefaultAutoSelectFamily) net.setDefaultAutoSelectFamily(false); const cliArguments = yargs(hideBin(process.argv)) .option('disableCsrf', { From 8211e67ed73d90dac3d9584fac2b7aac2e013c45 Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 12:10:51 -0700 Subject: [PATCH 05/16] generateToken requires req to set cookie --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 0fd6da679..40b509de4 100644 --- a/server.js +++ b/server.js @@ -365,7 +365,7 @@ if (cliArguments.disableCsrf === false) { app.get("/csrf-token", (req, res) => { res.json({ - "token": generateToken(res) + "token": generateToken(res, req) }); }); From ab9594fe62e5a4e539f3e687fc4a07f84afa7190 Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 12:13:36 -0700 Subject: [PATCH 06/16] handle missing user agent case --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 40b509de4..2847201fb 100644 --- a/server.js +++ b/server.js @@ -468,7 +468,7 @@ app.get("/notes/*", function (request, response) { app.get('/deviceinfo', function (request, response) { const userAgent = request.header('user-agent'); const deviceDetector = new DeviceDetector(); - const deviceInfo = deviceDetector.parse(userAgent); + const deviceInfo = deviceDetector.parse(userAgent || ""); return response.send(deviceInfo); }); app.get('/version', function (_, response) { From 691e9ee754f5e6ec42ba919cf28e67bf29d25fe8 Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 12:14:02 -0700 Subject: [PATCH 07/16] this default param does not exist --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 2847201fb..0b98fb1a4 100644 --- a/server.js +++ b/server.js @@ -477,7 +477,7 @@ app.get('/version', function (_, response) { }) //**************Kobold api -app.post("/generate", jsonParser, async function (request, response_generate = response) { +app.post("/generate", jsonParser, async function (request, response_generate) { if (!request.body) return response_generate.sendStatus(400); const request_prompt = request.body.prompt; From f7576750fce223202993d832aafbac7f55bf0dd8 Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 12:19:34 -0700 Subject: [PATCH 08/16] handle undefined X-Streaming-URL --- server.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server.js b/server.js index 0b98fb1a4..2748d4b2c 100644 --- a/server.js +++ b/server.js @@ -621,6 +621,10 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r }); if (request.header('X-Response-Streaming')) { + const streamingUrlHeader = request.header('X-Streaming-URL'); + if (streamingUrlHeader === undefined) return response_generate.sendStatus(400); + const streamingUrl = streamingUrlHeader.replace("localhost", "127.0.0.1"); + response_generate.writeHead(200, { 'Content-Type': 'text/plain;charset=utf-8', 'Transfer-Encoding': 'chunked', @@ -628,7 +632,6 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r }); async function* readWebsocket() { - const streamingUrl = request.header('X-Streaming-URL').replace("localhost", "127.0.0.1"); const websocket = new WebSocket(streamingUrl); websocket.on('open', async function () { From c1b76b5f483f2eefe8805693a4822d1a6d8bcc97 Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 12:23:48 -0700 Subject: [PATCH 09/16] resolve can only return one thing at a time --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 2748d4b2c..d831e3ccf 100644 --- a/server.js +++ b/server.js @@ -662,7 +662,7 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r websocket.once('error', reject); websocket.once('message', (data, isBinary) => { websocket.removeListener('error', reject); - resolve(data, isBinary); + resolve(data); }); }); } catch (err) { From 49aff85472032b861ee14361abb05c207c8f143a Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 12:25:25 -0700 Subject: [PATCH 10/16] handle bad read of raw data --- server.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server.js b/server.js index d831e3ccf..7168c0d4e 100644 --- a/server.js +++ b/server.js @@ -1100,6 +1100,8 @@ app.post("/renamecharacter", jsonParser, async function (request, response) { try { // Read old file, replace name int it const rawOldData = await charaRead(oldAvatarPath); + if (rawOldData === false || rawOldData === undefined) throw new Error("Failed to read character file"); + const oldData = getCharaCardV2(json5.parse(rawOldData)); _.set(oldData, 'data.name', newName); _.set(oldData, 'name', newName); From 8db38f3f8d3d1f96f9138c9d0766706328a50b5b Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 12:26:28 -0700 Subject: [PATCH 11/16] we require(json) in our code like animals --- jsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jsconfig.json b/jsconfig.json index 790faa9d6..652e04b1c 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -7,7 +7,8 @@ "strictFunctionTypes": true, "checkJs": true, "allowUmdGlobalAccess": true, - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true }, "exclude": [ "node_modules", From 77c9744878fd9aca9af2d154f3d81f56990407a5 Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 12:38:10 -0700 Subject: [PATCH 12/16] make more readable & make types happy --- server.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/server.js b/server.js index 7168c0d4e..bb860eee5 100644 --- a/server.js +++ b/server.js @@ -962,13 +962,12 @@ function charaFormatData(data) { // This is supposed to save all the foreign keys that ST doesn't care about const char = tryParse(data.json_data) || {}; - // This function uses _.cond() to create a series of conditional checks that return the desired output based on the input data. - // It checks if data.alternate_greetings is an array, a string, or neither, and acts accordingly. - const getAlternateGreetings = data => _.cond([ - [d => Array.isArray(d.alternate_greetings), d => d.alternate_greetings], - [d => typeof d.alternate_greetings === 'string', d => [d.alternate_greetings]], - [_.stubTrue, _.constant([])] - ])(data); + // Checks if data.alternate_greetings is an array, a string, or neither, and acts accordingly. (expected to be an array of strings) + const getAlternateGreetings = data => data.map(d => { + if (Array.isArray(d.alternate_greetings)) return d.alternate_greetings + if (typeof d.alternate_greetings === 'string') return [d.alternate_greetings] + return [] + }) // Spec V1 fields _.set(char, 'name', data.ch_name); From 2e3ddd16d50fd77b2101b4d89855d5f9aa539b6c Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 12:49:07 -0700 Subject: [PATCH 13/16] fix ambiguous args for typechecker --- server.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server.js b/server.js index bb860eee5..3631a5c9f 100644 --- a/server.js +++ b/server.js @@ -1248,6 +1248,10 @@ app.post("/deletecharacter", jsonParser, async function (request, response) { return response.sendStatus(200); }); +/** + * @param {express.Response | undefined} response + * @param {{file_name: string} | string} mes + */ async function charaWrite(img_url, data, target_img, response = undefined, mes = 'ok', crop = undefined) { try { // Read the image, resize, and save it as a PNG into the buffer From 9dfe42a7c320400391eb4cbe0e70fa9eaa47ac39 Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 12:58:43 -0700 Subject: [PATCH 14/16] convert to async and fix types --- server.js | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/server.js b/server.js index 3631a5c9f..d27081530 100644 --- a/server.js +++ b/server.js @@ -1189,26 +1189,22 @@ app.post("/editcharacterattribute", jsonParser, async function (request, respons try { const avatarPath = path.join(charactersPath, request.body.avatar_url); - charaRead(avatarPath).then((char) => { - char = JSON.parse(char); - //check if the field exists - if (char[request.body.field] === undefined && char.data[request.body.field] === undefined) { - console.error('Error: invalid field.'); - response.status(400).send('Error: invalid field.'); - return; - } - char[request.body.field] = request.body.value; - char.data[request.body.field] = request.body.value; - char = JSON.stringify(char); - return { char }; - }).then(({ char }) => { - charaWrite(avatarPath, char, (request.body.avatar_url).replace('.png', ''), response, 'Character saved'); - }).catch((err) => { - console.error('An error occured, character edit invalidated.', err); - }); - } - catch { - console.error('An error occured, character edit invalidated.'); + let charJSON = await charaRead(avatarPath); + if (typeof charJSON !== 'string') throw new Error("Failed to read character file"); + + let char = JSON.parse(charJSON) + //check if the field exists + if (char[request.body.field] === undefined && char.data[request.body.field] === undefined) { + console.error('Error: invalid field.'); + response.status(400).send('Error: invalid field.'); + return; + } + char[request.body.field] = request.body.value; + char.data[request.body.field] = request.body.value; + let newCharJSON = JSON.stringify(char); + await charaWrite(avatarPath, newCharJSON, (request.body.avatar_url).replace('.png', ''), response, 'Character saved'); + } catch (err) { + console.error('An error occured, character edit invalidated.', err); } }); From 326c7d8841847e0be8d087e4418b65a4938893eb Mon Sep 17 00:00:00 2001 From: RealBeepMcJeep Date: Wed, 30 Aug 2023 13:03:01 -0700 Subject: [PATCH 15/16] input not an arr, it is an arr or string or other --- server.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index d27081530..d217c39d5 100644 --- a/server.js +++ b/server.js @@ -963,11 +963,11 @@ function charaFormatData(data) { const char = tryParse(data.json_data) || {}; // Checks if data.alternate_greetings is an array, a string, or neither, and acts accordingly. (expected to be an array of strings) - const getAlternateGreetings = data => data.map(d => { - if (Array.isArray(d.alternate_greetings)) return d.alternate_greetings - if (typeof d.alternate_greetings === 'string') return [d.alternate_greetings] + const getAlternateGreetings = data => { + if (Array.isArray(data.alternate_greetings)) return data.alternate_greetings + if (typeof data.alternate_greetings === 'string') return [data.alternate_greetings] return [] - }) + } // Spec V1 fields _.set(char, 'name', data.ch_name); From 7f99ae5705f74d2f12cf5abf67e98b07aa6abbf5 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Thu, 31 Aug 2023 00:21:29 +0300 Subject: [PATCH 16/16] Revert unnecessary string cast --- server.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server.js b/server.js index d217c39d5..a97e624d4 100644 --- a/server.js +++ b/server.js @@ -1100,7 +1100,7 @@ app.post("/renamecharacter", jsonParser, async function (request, response) { // Read old file, replace name int it const rawOldData = await charaRead(oldAvatarPath); if (rawOldData === false || rawOldData === undefined) throw new Error("Failed to read character file"); - + const oldData = getCharaCardV2(json5.parse(rawOldData)); _.set(oldData, 'data.name', newName); _.set(oldData, 'name', newName); @@ -1245,7 +1245,7 @@ app.post("/deletecharacter", jsonParser, async function (request, response) { }); /** - * @param {express.Response | undefined} response + * @param {express.Response | undefined} response * @param {{file_name: string} | string} mes */ async function charaWrite(img_url, data, target_img, response = undefined, mes = 'ok', crop = undefined) { @@ -4184,7 +4184,7 @@ function migrateSecrets() { try { let modified = false; const fileContents = fs.readFileSync(SETTINGS_FILE, 'utf8'); - const settings = JSON.parse(fileContents.toString()); + const settings = JSON.parse(fileContents); const oaiKey = settings?.api_key_openai; const hordeKey = settings?.horde_settings?.api_key; const novelKey = settings?.api_key_novel;