@musnows/scriverse 0.3.6 → 0.3.8
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/ai.js +59 -0
- package/dist/ai.js.map +1 -1
- package/dist/app.js +136 -35
- package/dist/app.js.map +1 -1
- package/dist/http-logging.js +2 -2
- package/dist/http-logging.js.map +1 -1
- package/dist/logger.js +2 -2
- package/dist/logger.js.map +1 -1
- package/dist/pagination.js +42 -0
- package/dist/pagination.js.map +1 -0
- package/dist/public/analysis-types.d.ts +8 -0
- package/dist/public/analysis-types.js +53 -0
- package/dist/public/app.js +235 -77
- package/dist/public/index.html +37 -8
- package/dist/public/markdown.js +35 -1
- package/dist/public/page-route.js +12 -0
- package/dist/public/styles.css +65 -22
- package/dist/security.js +41 -4
- package/dist/security.js.map +1 -1
- package/dist/store.js +303 -0
- package/dist/store.js.map +1 -1
- package/dist/user-auth.js +30 -0
- package/dist/user-auth.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
package/dist/app.js
CHANGED
|
@@ -16,6 +16,7 @@ import { TASK_TYPES } from "./domain.js";
|
|
|
16
16
|
import { AppError } from "./errors.js";
|
|
17
17
|
import { applyImportFileHints, parseNovelText } from "./parser.js";
|
|
18
18
|
import { Store, versionedEntityTypes } from "./store.js";
|
|
19
|
+
import { parsePagination } from "./pagination.js";
|
|
19
20
|
import { normalizeUploadFileName } from "./utils.js";
|
|
20
21
|
import { assertSafeAiEndpoint, createApiRateLimitMiddleware, createAuthenticationRateLimitMiddleware, createBasicAuthMiddleware, createSameOriginMiddleware, createSecurityHeadersMiddleware } from "./security.js";
|
|
21
22
|
import { ImageCaptchaService } from "./image-captcha.js";
|
|
@@ -474,8 +475,15 @@ export function createRuntime(options) {
|
|
|
474
475
|
});
|
|
475
476
|
data(response, result);
|
|
476
477
|
});
|
|
477
|
-
app.get("/api/users", (
|
|
478
|
-
|
|
478
|
+
app.get("/api/users", (request, response) => {
|
|
479
|
+
const pagination = parsePagination(request.query);
|
|
480
|
+
data(response, pagination ? auth.listUsersPage(pagination) : auth.listUsers());
|
|
481
|
+
});
|
|
482
|
+
app.get("/api/users/directory", (request, response) => {
|
|
483
|
+
const pagination = parsePagination(request.query);
|
|
484
|
+
const query = String(request.query.q ?? "");
|
|
485
|
+
data(response, pagination ? auth.directoryPage(query, pagination) : auth.directory(query));
|
|
486
|
+
});
|
|
479
487
|
app.get("/api/user-avatars/:userId", (request, response) => {
|
|
480
488
|
const avatar = auth.getAvatar(request.params.userId);
|
|
481
489
|
response.setHeader("Content-Type", avatar.mimeType);
|
|
@@ -491,7 +499,10 @@ export function createRuntime(options) {
|
|
|
491
499
|
store.audit(null, "user.updated", "user", updated.userId, { role: updated.role, status: updated.status });
|
|
492
500
|
data(response, updated);
|
|
493
501
|
});
|
|
494
|
-
app.get("/api/works", (
|
|
502
|
+
app.get("/api/works", (request, response) => {
|
|
503
|
+
const pagination = parsePagination(request.query);
|
|
504
|
+
data(response, pagination ? store.listWorksPage(pagination) : store.listWorks());
|
|
505
|
+
});
|
|
495
506
|
app.post("/api/works", (request, response) => data(response, store.createWork(parse(workSchema, request.body)), 201));
|
|
496
507
|
app.post("/api/works/import", upload.single("file"), async (request, response) => {
|
|
497
508
|
if (!request.file)
|
|
@@ -512,8 +523,14 @@ export function createRuntime(options) {
|
|
|
512
523
|
});
|
|
513
524
|
data(response, store.createImportedWork(input, originalFileName, extension.slice(1), parsedNovel), 201);
|
|
514
525
|
});
|
|
515
|
-
app.get("/api/works/:workId", (request, response) =>
|
|
516
|
-
|
|
526
|
+
app.get("/api/works/:workId", (request, response) => {
|
|
527
|
+
const pagination = parsePagination(request.query);
|
|
528
|
+
data(response, pagination ? store.getWorkDirectoryPage(request.params.workId, pagination) : store.getWorkDirectory(request.params.workId));
|
|
529
|
+
});
|
|
530
|
+
app.get("/api/works/:workId/members", (request, response) => {
|
|
531
|
+
const pagination = parsePagination(request.query);
|
|
532
|
+
data(response, pagination ? auth.listMembersPage(request.params.workId, pagination) : auth.listMembers(request.params.workId));
|
|
533
|
+
});
|
|
517
534
|
app.post("/api/works/:workId/members", (request, response) => {
|
|
518
535
|
if (!request.authUser)
|
|
519
536
|
throw new AppError(401, "AUTH_REQUIRED", "请先登录");
|
|
@@ -563,7 +580,10 @@ export function createRuntime(options) {
|
|
|
563
580
|
store.deleteWorkCover(request.params.workId);
|
|
564
581
|
noContent(response);
|
|
565
582
|
});
|
|
566
|
-
app.get("/api/works/:workId/file-versions", (request, response) =>
|
|
583
|
+
app.get("/api/works/:workId/file-versions", (request, response) => {
|
|
584
|
+
const pagination = parsePagination(request.query);
|
|
585
|
+
data(response, pagination ? store.listFileVersionsPage(request.params.workId, pagination) : store.listFileVersions(request.params.workId));
|
|
586
|
+
});
|
|
567
587
|
app.post("/api/works/:workId/file-versions/:fileVersionId/restore", (request, response) => {
|
|
568
588
|
data(response, store.restoreFileVersion(request.params.workId, request.params.fileVersionId));
|
|
569
589
|
});
|
|
@@ -608,8 +628,14 @@ export function createRuntime(options) {
|
|
|
608
628
|
store.deleteChapter(request.params.chapterId);
|
|
609
629
|
noContent(response);
|
|
610
630
|
});
|
|
611
|
-
app.get("/api/chapters/:chapterId/versions", (request, response) =>
|
|
612
|
-
|
|
631
|
+
app.get("/api/chapters/:chapterId/versions", (request, response) => {
|
|
632
|
+
const pagination = parsePagination(request.query);
|
|
633
|
+
data(response, pagination ? store.listChapterVersionsPage(request.params.chapterId, pagination) : store.listChapterVersions(request.params.chapterId));
|
|
634
|
+
});
|
|
635
|
+
app.get("/api/chapters/:chapterId/insights", (request, response) => {
|
|
636
|
+
const pagination = parsePagination(request.query);
|
|
637
|
+
data(response, pagination ? store.listChapterInsightsPage(request.params.chapterId, pagination) : store.listChapterInsights(request.params.chapterId));
|
|
638
|
+
});
|
|
613
639
|
app.post("/api/chapters/:chapterId/restore", (request, response) => {
|
|
614
640
|
const input = parse(z.object({ versionNo: z.number().int().positive() }), request.body);
|
|
615
641
|
data(response, store.restoreChapter(request.params.chapterId, input.versionNo));
|
|
@@ -618,7 +644,10 @@ export function createRuntime(options) {
|
|
|
618
644
|
const input = parse(z.object({ volumeId: identifier, sortOrder: z.number().int().min(0) }), request.body);
|
|
619
645
|
data(response, store.moveChapter(request.params.chapterId, input));
|
|
620
646
|
});
|
|
621
|
-
app.get("/api/works/:workId/outlines", (request, response) =>
|
|
647
|
+
app.get("/api/works/:workId/outlines", (request, response) => {
|
|
648
|
+
const pagination = parsePagination(request.query);
|
|
649
|
+
data(response, pagination ? store.listChapterOutlinesPage(request.params.workId, pagination) : store.listChapterOutlines(request.params.workId));
|
|
650
|
+
});
|
|
622
651
|
app.get("/api/chapters/:chapterId/outline", (request, response) => data(response, store.getChapterOutline(request.params.chapterId)));
|
|
623
652
|
app.put("/api/chapters/:chapterId/outline", (request, response) => {
|
|
624
653
|
const { changeNote, ...input } = parse(chapterOutlineSchema.extend({ changeNote: changeNoteSchema }), request.body);
|
|
@@ -633,7 +662,10 @@ export function createRuntime(options) {
|
|
|
633
662
|
status: z.enum(["all", "unresolved", "resolved"]).default("all"),
|
|
634
663
|
currentChapterId: identifier.optional()
|
|
635
664
|
}), request.query);
|
|
636
|
-
|
|
665
|
+
const pagination = parsePagination(request.query);
|
|
666
|
+
data(response, pagination
|
|
667
|
+
? store.listForeshadowsPage(request.params.workId, pagination, query.status, query.currentChapterId)
|
|
668
|
+
: store.listForeshadows(request.params.workId, query.status, query.currentChapterId));
|
|
637
669
|
});
|
|
638
670
|
app.post("/api/works/:workId/foreshadows", (request, response) => {
|
|
639
671
|
data(response, store.createForeshadow(request.params.workId, parse(foreshadowSchema, request.body)), 201);
|
|
@@ -657,7 +689,10 @@ export function createRuntime(options) {
|
|
|
657
689
|
store.deleteForeshadowOccurrence(request.params.occurrenceId);
|
|
658
690
|
noContent(response);
|
|
659
691
|
});
|
|
660
|
-
app.get("/api/works/:workId/settings", (request, response) =>
|
|
692
|
+
app.get("/api/works/:workId/settings", (request, response) => {
|
|
693
|
+
const pagination = parsePagination(request.query);
|
|
694
|
+
data(response, pagination ? store.listSettingsPage(request.params.workId, pagination) : store.listSettings(request.params.workId));
|
|
695
|
+
});
|
|
661
696
|
app.post("/api/works/:workId/settings", (request, response) => data(response, store.createSetting(request.params.workId, parse(settingSchema, request.body)), 201));
|
|
662
697
|
app.get("/api/settings/:settingId", (request, response) => data(response, store.getSetting(request.params.settingId)));
|
|
663
698
|
app.patch("/api/settings/:settingId", (request, response) => {
|
|
@@ -673,7 +708,10 @@ export function createRuntime(options) {
|
|
|
673
708
|
includeSections: z.enum(["true", "false"]).default("false"),
|
|
674
709
|
includeMerged: z.enum(["0", "1"]).default("0")
|
|
675
710
|
}), request.query);
|
|
676
|
-
|
|
711
|
+
const pagination = parsePagination(request.query);
|
|
712
|
+
data(response, pagination
|
|
713
|
+
? store.listCharactersPage(request.params.workId, pagination, includeSections === "true", includeMerged === "1")
|
|
714
|
+
: store.listCharacters(request.params.workId, includeSections === "true", includeMerged === "1"));
|
|
677
715
|
});
|
|
678
716
|
app.post("/api/works/:workId/characters", (request, response) => data(response, store.createCharacter(request.params.workId, parse(characterSchema, request.body)), 201));
|
|
679
717
|
app.get("/api/characters/:characterId", (request, response) => data(response, store.getCharacter(request.params.characterId)));
|
|
@@ -681,7 +719,10 @@ export function createRuntime(options) {
|
|
|
681
719
|
const { changeNote, ...input } = parse(characterUpdateSchema, request.body);
|
|
682
720
|
data(response, store.updateCharacter(request.params.characterId, input, "manual", null, changeNote));
|
|
683
721
|
});
|
|
684
|
-
app.get("/api/characters/:characterId/versions", (request, response) =>
|
|
722
|
+
app.get("/api/characters/:characterId/versions", (request, response) => {
|
|
723
|
+
const pagination = parsePagination(request.query);
|
|
724
|
+
data(response, pagination ? store.listCharacterVersionsPage(request.params.characterId, pagination) : store.listCharacterVersions(request.params.characterId));
|
|
725
|
+
});
|
|
685
726
|
app.post("/api/characters/:characterId/restore", (request, response) => {
|
|
686
727
|
const input = parse(z.object({ versionNo: z.number().int().positive() }), request.body);
|
|
687
728
|
data(response, store.restoreCharacter(request.params.characterId, input.versionNo));
|
|
@@ -691,7 +732,10 @@ export function createRuntime(options) {
|
|
|
691
732
|
noContent(response);
|
|
692
733
|
});
|
|
693
734
|
app.get("/api/characters/:characterId/sections", (request, response) => {
|
|
694
|
-
|
|
735
|
+
const pagination = parsePagination(request.query);
|
|
736
|
+
data(response, pagination
|
|
737
|
+
? store.listCharacterProfileSectionsPage(request.params.characterId, pagination)
|
|
738
|
+
: store.listCharacterProfileSections(request.params.characterId));
|
|
695
739
|
});
|
|
696
740
|
app.post("/api/characters/:characterId/sections", (request, response) => {
|
|
697
741
|
data(response, store.createCharacterProfileSection(request.params.characterId, parse(characterProfileSectionSchema, request.body)), 201);
|
|
@@ -708,14 +752,18 @@ export function createRuntime(options) {
|
|
|
708
752
|
noContent(response);
|
|
709
753
|
});
|
|
710
754
|
app.get("/api/character-sections/:sectionId/versions", (request, response) => {
|
|
711
|
-
|
|
755
|
+
const pagination = parsePagination(request.query);
|
|
756
|
+
data(response, pagination
|
|
757
|
+
? store.listCharacterProfileSectionVersionsPage(request.params.sectionId, pagination)
|
|
758
|
+
: store.listCharacterProfileSectionVersions(request.params.sectionId));
|
|
712
759
|
});
|
|
713
760
|
app.post("/api/character-sections/:sectionId/restore", (request, response) => {
|
|
714
761
|
const input = parse(z.object({ versionNo: z.number().int().positive() }).strict(), request.body);
|
|
715
762
|
data(response, store.restoreCharacterProfileSection(request.params.sectionId, input.versionNo));
|
|
716
763
|
});
|
|
717
764
|
app.get("/api/works/:workId/attachments", (request, response) => {
|
|
718
|
-
|
|
765
|
+
const pagination = parsePagination(request.query);
|
|
766
|
+
data(response, pagination ? store.listAttachmentsPage(request.params.workId, pagination) : store.listAttachments(request.params.workId));
|
|
719
767
|
});
|
|
720
768
|
app.post("/api/works/:workId/attachments", attachmentUpload.single("file"), async (request, response) => {
|
|
721
769
|
if (!request.file)
|
|
@@ -758,7 +806,10 @@ export function createRuntime(options) {
|
|
|
758
806
|
await attachmentStorage.remove(deleted.storageKey);
|
|
759
807
|
noContent(response);
|
|
760
808
|
});
|
|
761
|
-
app.get("/api/works/:workId/races", (request, response) =>
|
|
809
|
+
app.get("/api/works/:workId/races", (request, response) => {
|
|
810
|
+
const pagination = parsePagination(request.query);
|
|
811
|
+
data(response, pagination ? store.listRacesPage(request.params.workId, pagination) : store.listRaces(request.params.workId));
|
|
812
|
+
});
|
|
762
813
|
app.post("/api/works/:workId/races", (request, response) => {
|
|
763
814
|
data(response, store.createRace(request.params.workId, parse(raceSchema, request.body)), 201);
|
|
764
815
|
});
|
|
@@ -771,7 +822,10 @@ export function createRuntime(options) {
|
|
|
771
822
|
store.deleteRace(request.params.raceId);
|
|
772
823
|
noContent(response);
|
|
773
824
|
});
|
|
774
|
-
app.get("/api/works/:workId/organizations", (request, response) =>
|
|
825
|
+
app.get("/api/works/:workId/organizations", (request, response) => {
|
|
826
|
+
const pagination = parsePagination(request.query);
|
|
827
|
+
data(response, pagination ? store.listOrganizationsPage(request.params.workId, pagination) : store.listOrganizations(request.params.workId));
|
|
828
|
+
});
|
|
775
829
|
app.post("/api/works/:workId/organizations", (request, response) => {
|
|
776
830
|
data(response, store.createOrganization(request.params.workId, parse(organizationSchema, request.body)), 201);
|
|
777
831
|
});
|
|
@@ -784,7 +838,10 @@ export function createRuntime(options) {
|
|
|
784
838
|
store.deleteOrganization(request.params.organizationId);
|
|
785
839
|
noContent(response);
|
|
786
840
|
});
|
|
787
|
-
app.get("/api/works/:workId/timeline-tracks", (request, response) =>
|
|
841
|
+
app.get("/api/works/:workId/timeline-tracks", (request, response) => {
|
|
842
|
+
const pagination = parsePagination(request.query);
|
|
843
|
+
data(response, pagination ? store.listTimelineTracksPage(request.params.workId, pagination) : store.listTimelineTracks(request.params.workId));
|
|
844
|
+
});
|
|
788
845
|
app.post("/api/works/:workId/timeline-tracks", (request, response) => data(response, store.createTimelineTrack(request.params.workId, parse(timelineTrackSchema, request.body)), 201));
|
|
789
846
|
app.get("/api/timeline-tracks/:trackId", (request, response) => data(response, store.getTimelineTrack(request.params.trackId)));
|
|
790
847
|
app.patch("/api/timeline-tracks/:trackId", (request, response) => {
|
|
@@ -795,7 +852,10 @@ export function createRuntime(options) {
|
|
|
795
852
|
store.deleteTimelineTrack(request.params.trackId);
|
|
796
853
|
noContent(response);
|
|
797
854
|
});
|
|
798
|
-
app.get("/api/works/:workId/timeline", (request, response) =>
|
|
855
|
+
app.get("/api/works/:workId/timeline", (request, response) => {
|
|
856
|
+
const pagination = parsePagination(request.query);
|
|
857
|
+
data(response, pagination ? store.listTimelineEventsPage(request.params.workId, pagination) : store.listTimelineEvents(request.params.workId));
|
|
858
|
+
});
|
|
799
859
|
app.post("/api/works/:workId/timeline", (request, response) => data(response, store.createTimelineEvent(request.params.workId, parse(timelineSchema, request.body)), 201));
|
|
800
860
|
app.post("/api/works/:workId/timeline/merge", (request, response) => {
|
|
801
861
|
const input = parse(z.object({
|
|
@@ -831,7 +891,10 @@ export function createRuntime(options) {
|
|
|
831
891
|
const confidence = request.query.minimumConfidence ? Number(request.query.minimumConfidence) : 0;
|
|
832
892
|
if (!Number.isFinite(confidence) || confidence < 0 || confidence > 1)
|
|
833
893
|
throw new AppError(400, "INVALID_CONFIDENCE", "置信度必须在 0 到 1 之间");
|
|
834
|
-
|
|
894
|
+
const pagination = parsePagination(request.query);
|
|
895
|
+
data(response, pagination
|
|
896
|
+
? store.listRelationshipsPage(request.params.workId, pagination, confidence)
|
|
897
|
+
: store.listRelationships(request.params.workId, confidence));
|
|
835
898
|
});
|
|
836
899
|
app.post("/api/works/:workId/relationships", (request, response) => data(response, store.createRelationship(request.params.workId, parse(relationshipSchema, request.body)), 201));
|
|
837
900
|
app.get("/api/relationships/:relationshipId", (request, response) => data(response, store.getRelationship(request.params.relationshipId)));
|
|
@@ -845,7 +908,10 @@ export function createRuntime(options) {
|
|
|
845
908
|
});
|
|
846
909
|
app.get("/api/entity-versions/:entityType/:entityId", (request, response) => {
|
|
847
910
|
const input = parse(z.object({ entityType: versionedEntityTypeSchema, entityId: identifier }), request.params);
|
|
848
|
-
|
|
911
|
+
const pagination = parsePagination(request.query);
|
|
912
|
+
data(response, pagination
|
|
913
|
+
? store.listEntityVersionsPage(input.entityType, input.entityId, pagination)
|
|
914
|
+
: store.listEntityVersions(input.entityType, input.entityId));
|
|
849
915
|
});
|
|
850
916
|
app.post("/api/entity-versions/:entityType/:entityId/restore", (request, response) => {
|
|
851
917
|
const params = parse(z.object({ entityType: versionedEntityTypeSchema, entityId: identifier }), request.params);
|
|
@@ -854,7 +920,8 @@ export function createRuntime(options) {
|
|
|
854
920
|
});
|
|
855
921
|
app.get("/api/works/:workId/reviews", (request, response) => {
|
|
856
922
|
const status = typeof request.query.status === "string" ? request.query.status : undefined;
|
|
857
|
-
|
|
923
|
+
const pagination = parsePagination(request.query);
|
|
924
|
+
data(response, pagination ? store.listReviewItemsPage(request.params.workId, pagination, status) : store.listReviewItems(request.params.workId, status));
|
|
858
925
|
});
|
|
859
926
|
app.post("/api/works/:workId/reviews", (request, response) => data(response, store.createReviewItem(request.params.workId, parse(reviewSchema, request.body)), 201));
|
|
860
927
|
app.patch("/api/reviews/:reviewId", (request, response) => data(response, store.updateReviewItem(request.params.reviewId, parse(reviewSchema.partial(), request.body))));
|
|
@@ -875,7 +942,10 @@ export function createRuntime(options) {
|
|
|
875
942
|
}
|
|
876
943
|
data(response, store.mergeCharacters({ reviewId: request.params.reviewId, ...input }));
|
|
877
944
|
});
|
|
878
|
-
app.get("/api/works/:workId/tasks", (request, response) =>
|
|
945
|
+
app.get("/api/works/:workId/tasks", (request, response) => {
|
|
946
|
+
const pagination = parsePagination(request.query);
|
|
947
|
+
data(response, pagination ? store.listTasksPage(request.params.workId, pagination) : store.listTasks(request.params.workId));
|
|
948
|
+
});
|
|
879
949
|
app.post("/api/works/:workId/tasks", (request, response) => {
|
|
880
950
|
const input = parse(z.object({ taskType: z.enum(["structure", "chapter-analysis", "character-extraction", "character-summary", "character-identity-audit", "timeline-analysis", "relationship-analysis", "worldview-analysis", "setting-extraction", "consistency-check", "report-update", "book-analysis"]), scope: jsonObject.optional() }), request.body);
|
|
881
951
|
data(response, store.createTask(request.params.workId, input), 201);
|
|
@@ -889,9 +959,15 @@ export function createRuntime(options) {
|
|
|
889
959
|
data(response, await ai.runTask(request.params.taskId, input.modelId));
|
|
890
960
|
});
|
|
891
961
|
app.post("/api/tasks/:taskId/cancel", (request, response) => data(response, ai.cancelTask(request.params.taskId)));
|
|
892
|
-
app.get("/api/platform/ai/providers", (
|
|
962
|
+
app.get("/api/platform/ai/providers", (request, response) => {
|
|
963
|
+
const pagination = parsePagination(request.query);
|
|
964
|
+
data(response, pagination ? ai.listProvidersPage(pagination) : ai.listProviders());
|
|
965
|
+
});
|
|
893
966
|
app.post("/api/platform/ai/providers", (request, response) => data(response, ai.createProvider(parse(providerSchema, request.body)), 201));
|
|
894
|
-
app.get("/api/platform/ai/models", (
|
|
967
|
+
app.get("/api/platform/ai/models", (request, response) => {
|
|
968
|
+
const pagination = parsePagination(request.query);
|
|
969
|
+
data(response, pagination ? ai.listPlatformModelsPage(pagination) : ai.listPlatformModels());
|
|
970
|
+
});
|
|
895
971
|
app.get("/api/platform/ai/settings", (_request, response) => data(response, store.getPlatformAiSettings()));
|
|
896
972
|
app.patch("/api/platform/ai/settings", (request, response) => data(response, store.updatePlatformAiSettings(parse(aiPromptSchema, request.body))));
|
|
897
973
|
app.get("/api/ui-settings", (_request, response) => data(response, store.getPlatformUiSettings()));
|
|
@@ -911,12 +987,18 @@ export function createRuntime(options) {
|
|
|
911
987
|
}
|
|
912
988
|
data(response, updated);
|
|
913
989
|
});
|
|
914
|
-
app.get("/api/works/:workId/ai-conversations", (request, response) =>
|
|
990
|
+
app.get("/api/works/:workId/ai-conversations", (request, response) => {
|
|
991
|
+
const pagination = parsePagination(request.query);
|
|
992
|
+
data(response, pagination ? store.listAiConversationsPage(request.params.workId, pagination) : store.listAiConversations(request.params.workId));
|
|
993
|
+
});
|
|
915
994
|
app.post("/api/works/:workId/ai-conversations", (request, response) => {
|
|
916
995
|
const input = parse(z.object({ title: z.string().max(200).optional() }), request.body ?? {});
|
|
917
996
|
data(response, store.createAiConversation(request.params.workId, input.title), 201);
|
|
918
997
|
});
|
|
919
|
-
app.get("/api/ai-conversations/:conversationId", (request, response) =>
|
|
998
|
+
app.get("/api/ai-conversations/:conversationId", (request, response) => {
|
|
999
|
+
const pagination = parsePagination(request.query);
|
|
1000
|
+
data(response, pagination ? store.getAiConversationPage(request.params.conversationId, pagination) : store.getAiConversation(request.params.conversationId));
|
|
1001
|
+
});
|
|
920
1002
|
app.post("/api/ai-conversations/:conversationId/fork", (request, response) => {
|
|
921
1003
|
const input = parse(z.object({ messageId: identifier, title: z.string().max(200).optional() }), request.body);
|
|
922
1004
|
data(response, store.forkAiConversation(request.params.conversationId, input.messageId, input.title), 201);
|
|
@@ -997,7 +1079,10 @@ export function createRuntime(options) {
|
|
|
997
1079
|
noContent(response);
|
|
998
1080
|
});
|
|
999
1081
|
app.post("/api/providers/:providerId/test", async (request, response) => data(response, await ai.testProvider(request.params.providerId)));
|
|
1000
|
-
app.get("/api/providers/:providerId/models", (request, response) =>
|
|
1082
|
+
app.get("/api/providers/:providerId/models", (request, response) => {
|
|
1083
|
+
const pagination = parsePagination(request.query);
|
|
1084
|
+
data(response, pagination ? ai.listModelsPage(request.params.providerId, pagination) : ai.listModels(request.params.providerId));
|
|
1085
|
+
});
|
|
1001
1086
|
app.post("/api/providers/:providerId/models", (request, response) => data(response, ai.createModel(request.params.providerId, parse(modelSchema, request.body)), 201));
|
|
1002
1087
|
app.get("/api/models/:modelId", (request, response) => data(response, ai.getModel(request.params.modelId)));
|
|
1003
1088
|
app.patch("/api/models/:modelId", (request, response) => data(response, ai.updateModel(request.params.modelId, parse(modelSchema.partial(), request.body))));
|
|
@@ -1005,8 +1090,14 @@ export function createRuntime(options) {
|
|
|
1005
1090
|
ai.deleteModel(request.params.modelId);
|
|
1006
1091
|
noContent(response);
|
|
1007
1092
|
});
|
|
1008
|
-
app.get("/api/works/:workId/models", (request, response) =>
|
|
1009
|
-
|
|
1093
|
+
app.get("/api/works/:workId/models", (request, response) => {
|
|
1094
|
+
const pagination = parsePagination(request.query);
|
|
1095
|
+
data(response, pagination ? ai.listWorkModelsPage(request.params.workId, pagination) : ai.listWorkModels(request.params.workId));
|
|
1096
|
+
});
|
|
1097
|
+
app.get("/api/works/:workId/task-defaults", (request, response) => {
|
|
1098
|
+
const pagination = parsePagination(request.query);
|
|
1099
|
+
data(response, pagination ? ai.listTaskDefaultsPage(request.params.workId, pagination) : ai.listTaskDefaults(request.params.workId));
|
|
1100
|
+
});
|
|
1010
1101
|
app.put("/api/works/:workId/task-defaults/:taskType", (request, response) => {
|
|
1011
1102
|
const taskType = parse(z.enum(TASK_TYPES), request.params.taskType);
|
|
1012
1103
|
const input = parse(z.object({ modelId: identifier }), request.body);
|
|
@@ -1014,7 +1105,8 @@ export function createRuntime(options) {
|
|
|
1014
1105
|
});
|
|
1015
1106
|
app.get("/api/works/:workId/suggestions", (request, response) => {
|
|
1016
1107
|
const status = typeof request.query.status === "string" ? request.query.status : undefined;
|
|
1017
|
-
|
|
1108
|
+
const pagination = parsePagination(request.query);
|
|
1109
|
+
data(response, pagination ? ai.listSuggestionsPage(request.params.workId, pagination, status) : ai.listSuggestions(request.params.workId, status));
|
|
1018
1110
|
});
|
|
1019
1111
|
app.post("/api/works/:workId/suggestions", async (request, response) => {
|
|
1020
1112
|
const input = parse(z.object({
|
|
@@ -1109,7 +1201,10 @@ export function createRuntime(options) {
|
|
|
1109
1201
|
});
|
|
1110
1202
|
app.get("/api/suggestions/:suggestionId", (request, response) => data(response, ai.getSuggestion(request.params.suggestionId)));
|
|
1111
1203
|
app.get("/api/suggestions/:suggestionId/guards", (request, response) => {
|
|
1112
|
-
|
|
1204
|
+
const pagination = parsePagination(request.query);
|
|
1205
|
+
data(response, pagination
|
|
1206
|
+
? store.listContinuationGuardsPage(request.params.suggestionId, pagination)
|
|
1207
|
+
: store.listContinuationGuards(request.params.suggestionId));
|
|
1113
1208
|
});
|
|
1114
1209
|
app.post("/api/suggestions/:suggestionId/guard", async (request, response) => {
|
|
1115
1210
|
const input = parse(z.object({ content: z.string().max(2_000_000).optional() }), request.body ?? {});
|
|
@@ -1120,7 +1215,10 @@ export function createRuntime(options) {
|
|
|
1120
1215
|
data(response, ai.acceptSuggestion(request.params.suggestionId, input.content));
|
|
1121
1216
|
});
|
|
1122
1217
|
app.post("/api/suggestions/:suggestionId/reject", (request, response) => data(response, ai.rejectSuggestion(request.params.suggestionId)));
|
|
1123
|
-
app.get("/api/works/:workId/ai-calls", (request, response) =>
|
|
1218
|
+
app.get("/api/works/:workId/ai-calls", (request, response) => {
|
|
1219
|
+
const pagination = parsePagination(request.query);
|
|
1220
|
+
data(response, pagination ? ai.listCallsPage(request.params.workId, pagination) : ai.listCalls(request.params.workId));
|
|
1221
|
+
});
|
|
1124
1222
|
app.get("/api/works/:workId/search", (request, response) => {
|
|
1125
1223
|
const query = parse(z.string().trim().min(1).max(500), request.query.q);
|
|
1126
1224
|
data(response, store.search(request.params.workId, query));
|
|
@@ -1136,7 +1234,10 @@ export function createRuntime(options) {
|
|
|
1136
1234
|
response.setHeader("Content-Disposition", `attachment; filename=novel-${request.params.workId}.${format === "markdown" ? "md" : "txt"}`);
|
|
1137
1235
|
response.send(store.exportText(request.params.workId, format));
|
|
1138
1236
|
});
|
|
1139
|
-
app.get("/api/works/:workId/audit-logs", (request, response) =>
|
|
1237
|
+
app.get("/api/works/:workId/audit-logs", (request, response) => {
|
|
1238
|
+
const pagination = parsePagination(request.query);
|
|
1239
|
+
data(response, pagination ? store.listAuditLogsPage(request.params.workId, pagination) : store.listAuditLogs(request.params.workId));
|
|
1240
|
+
});
|
|
1140
1241
|
if (options.serveUi ?? true) {
|
|
1141
1242
|
const publicPath = options.publicPath ?? join(process.cwd(), "src", "public");
|
|
1142
1243
|
// index.html 按登录态动态下发:未登录时注入 login-route 类,首帧直接渲染登录页;
|