Add /api/worldinfo/list endpoint

cdfe873984f66fc4623d96addb63908f16301b96

Cohee <18619528+Cohee1207@users.noreply.github.com>

2 files changed, +32 -1Showing whitespace changes
src/endpoints/chats.js+1 -1
@@ -409,7 +409,7 @@ export async function getChatInfo(pathToFile, additionalData = {}, isGroup = fal
409 rl.on('line', (line) => {409 rl.on('line', (line) => {
410 if (withMetadata && itemCounter === 0) {410 if (withMetadata && itemCounter === 0) {
411 const jsonData = tryParse(line);411 const jsonData = tryParse(line);
412 if (jsonData && _.isObject(jsonData.chat_metadata)) {412 if (jsonData && _.isObjectLike(jsonData.chat_metadata)) {
413 chatData.chat_metadata = jsonData.chat_metadata;413 chatData.chat_metadata = jsonData.chat_metadata;
414 }414 }
415 }415 }
src/endpoints/worldinfo.js+31 -0
@@ -3,7 +3,9 @@ import path from 'node:path';
33
4import express from 'express';4import express from 'express';
5import sanitize from 'sanitize-filename';5import sanitize from 'sanitize-filename';
6import _ from 'lodash';
6import { sync as writeFileAtomicSync } from 'write-file-atomic';7import { sync as writeFileAtomicSync } from 'write-file-atomic';
8import { tryParse } from '../util.js';
79
8/**10/**
9 * Reads a World Info file and returns its contents11 * Reads a World Info file and returns its contents
@@ -34,6 +36,35 @@ export function readWorldInfoFile(directories, worldInfoName, allowDummy) {
3436
35export const router = express.Router();37export const router = express.Router();
3638
39router.post('/list', async (request, response) => {
40 try {
41 const data = [];
42 const jsonFiles = (await fs.promises.readdir(request.user.directories.worlds, { withFileTypes: true }))
43 .filter((file) => file.isFile() && path.extname(file.name).toLowerCase() === '.json')
44 .sort((a, b) => a.name.localeCompare(b.name));
45
46 for (const file of jsonFiles) {
47 try {
48 const filePath = path.join(request.user.directories.worlds, file.name);
49 const fileContents = await fs.promises.readFile(filePath, 'utf8');
50 const fileExtensions = tryParse(fileContents)?.extensions || {};
51 const fileData = {
52 name: path.parse(file.name).name,
53 extensions: _.isObjectLike(fileExtensions) ? fileExtensions : {},
54 };
55 data.push(fileData);
56 } catch (err) {
57 console.warn(`Error reading or parsing World Info file ${file.name}:`, err);
58 }
59 }
60
61 return response.send(data);
62 } catch (err) {
63 console.error('Error reading World Info directory:', err);
64 return response.sendStatus(500);
65 }
66});
67
37router.post('/get', (request, response) => {68router.post('/get', (request, response) => {
38 if (!request.body?.name) {69 if (!request.body?.name) {
39 return response.sendStatus(400);70 return response.sendStatus(400);