@musnows/scriverse 0.5.6 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +25 -3
- package/dist/app.js.map +1 -1
- package/dist/database.js +14 -0
- package/dist/database.js.map +1 -1
- package/dist/public/app.js +91 -16
- package/dist/public/index.html +13 -5
- package/dist/public/relationship-graph.js +80 -22
- package/dist/public/styles.css +39 -15
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/app.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import express from "express";
|
|
2
|
+
import JSZip from "jszip";
|
|
2
3
|
import multer from "multer";
|
|
3
4
|
import mammoth from "mammoth";
|
|
4
5
|
import { randomUUID } from "node:crypto";
|
|
@@ -6,6 +7,7 @@ import { dirname, extname, join } from "node:path";
|
|
|
6
7
|
import { existsSync, mkdtempSync, mkdirSync, readFileSync, rmSync } from "node:fs";
|
|
7
8
|
import { rm } from "node:fs/promises";
|
|
8
9
|
import { tmpdir } from "node:os";
|
|
10
|
+
import { pipeline } from "node:stream/promises";
|
|
9
11
|
import { z, ZodError } from "zod";
|
|
10
12
|
import { AttachmentStorage } from "./attachment-storage.js";
|
|
11
13
|
import { AiManager } from "./ai.js";
|
|
@@ -1855,15 +1857,29 @@ export function createRuntime(options) {
|
|
|
1855
1857
|
const query = parse(z.string().trim().min(1).max(500), request.query.q);
|
|
1856
1858
|
data(response, store.search(request.params.workId, query));
|
|
1857
1859
|
});
|
|
1858
|
-
app.get("/api/works/:workId/export", (request, response) => {
|
|
1860
|
+
app.get("/api/works/:workId/export", async (request, response) => {
|
|
1859
1861
|
const format = parse(z.enum(["json", "txt", "markdown"]), request.query.format ?? "json");
|
|
1860
1862
|
if (format === "json") {
|
|
1861
1863
|
response.setHeader("Content-Disposition", `attachment; filename=novel-${request.params.workId}.json`);
|
|
1862
1864
|
data(response, store.exportWork(request.params.workId));
|
|
1863
1865
|
return;
|
|
1864
1866
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
+
if (format === "markdown") {
|
|
1868
|
+
const exportName = `novel-${request.params.workId}`;
|
|
1869
|
+
const archive = new JSZip();
|
|
1870
|
+
archive.file(`${exportName}.md`, store.exportText(request.params.workId, format));
|
|
1871
|
+
response.type("application/zip");
|
|
1872
|
+
response.setHeader("Content-Disposition", `attachment; filename=${exportName}.zip`);
|
|
1873
|
+
await pipeline(archive.generateNodeStream({
|
|
1874
|
+
type: "nodebuffer",
|
|
1875
|
+
streamFiles: true,
|
|
1876
|
+
compression: "DEFLATE",
|
|
1877
|
+
compressionOptions: { level: 6 }
|
|
1878
|
+
}), response);
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1881
|
+
response.type("text/plain");
|
|
1882
|
+
response.setHeader("Content-Disposition", `attachment; filename=novel-${request.params.workId}.txt`);
|
|
1867
1883
|
response.send(store.exportText(request.params.workId, format));
|
|
1868
1884
|
});
|
|
1869
1885
|
app.get("/api/works/:workId/audit-logs", (request, response) => {
|
|
@@ -1929,6 +1945,12 @@ export function createRuntime(options) {
|
|
|
1929
1945
|
app.use((_request, _response, next) => next(new AppError(404, "ROUTE_NOT_FOUND", "请求的接口不存在")));
|
|
1930
1946
|
app.use((error, request, response, _next) => {
|
|
1931
1947
|
const commonFields = { method: request.method, path: sanitizeRequestPath(request.path), error: sanitizeError(error) };
|
|
1948
|
+
if (response.headersSent || response.destroyed) {
|
|
1949
|
+
logger.warn("http.request.response_stream_failed", commonFields);
|
|
1950
|
+
if (!response.destroyed)
|
|
1951
|
+
response.destroy(error instanceof Error ? error : undefined);
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1932
1954
|
if (error instanceof ZodError) {
|
|
1933
1955
|
logger.warn("http.request.validation_failed", { ...commonFields, issuePaths: error.issues.map((issue) => issue.path.join(".")) });
|
|
1934
1956
|
response.status(400).json({
|