ocean-brain 0.3.4 → 0.4.0
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/package.json +5 -5
- package/scripts/postinstall-prisma.mjs +3 -2
- package/server/client/dist/assets/Calendar-CSXEuWmQ.js +25 -0
- package/server/client/dist/assets/Callout-Ap1OcxWN.js +1 -0
- package/server/client/dist/assets/Graph-C0Ax9qjI.js +1 -0
- package/server/client/dist/assets/{Image-ZxF459sC.js → Image-CSbcG-5a.js} +1 -1
- package/server/client/dist/assets/{Image.es-BQfyKc2-.js → Image.es-Fbe7aDDo.js} +1 -1
- package/server/client/dist/assets/{ModalActionRow-DyOb58KJ.js → ModalActionRow-DjI5b4bl.js} +1 -1
- package/server/client/dist/assets/Note-BY6WgYLq.js +1 -0
- package/server/client/dist/assets/Note-W4f6H9K0.css +1 -0
- package/server/client/dist/assets/Reminders-vRksvSQE.js +1 -0
- package/server/client/dist/assets/Search-Cq4tuiJO.js +1 -0
- package/server/client/dist/assets/{SurfaceCard-nZNf9lyE.js → SurfaceCard-Br6TjX5W.js} +1 -1
- package/server/client/dist/assets/Tag-ARDLA-Pb.js +1 -0
- package/server/client/dist/assets/TagNotes-CDGVrCJU.js +1 -0
- package/server/client/dist/assets/{Trash.es-BGoN5q9L.js → Trash.es-BfCEiL3-.js} +1 -1
- package/server/client/dist/assets/ViewNotes-ZBOQ1adH.js +1 -0
- package/server/client/dist/assets/Views-DQHPfdwM.js +1 -0
- package/server/client/dist/assets/{image.api-0mMkElZk.js → image.api-DGXlQ_Ca.js} +1 -1
- package/server/client/dist/assets/index-B28TO4FC.js +1 -0
- package/server/client/dist/assets/{index-DL7pUwq2.css → index-Bm9l_L20.css} +1 -1
- package/server/client/dist/assets/index-Bsx4P7EA.js +210 -0
- package/server/client/dist/assets/manage-image-Dg297A_h.js +1 -0
- package/server/client/dist/assets/manage-image-detail-hk6jWyiB.js +1 -0
- package/server/client/dist/assets/mcp-CSjmBjFR.js +1 -0
- package/server/client/dist/assets/{note-core-BCgMq5QA.js → note-core-GgFcksAF.js} +1 -1
- package/server/client/dist/assets/{note-vendor-BofYbzmZ.js → note-vendor-5N5mRkIT.js} +3 -3
- package/server/client/dist/assets/{placeholder-i-uNe71U.js → placeholder-Bmiowo28.js} +4 -4
- package/server/client/dist/assets/trash-CM7SbVtW.js +1 -0
- package/server/client/dist/assets/{useReminderMutate-tNMwwRnx.js → useReminderMutate-DsIvVpCQ.js} +2 -2
- package/server/client/dist/assets/view-dashboard-CP8nhfxQ.js +90 -0
- package/server/client/dist/index.html +4 -4
- package/server/dist/app.js +8 -84
- package/server/dist/app.js.map +1 -1
- package/server/dist/features/auth/http/api.js +43 -0
- package/server/dist/features/auth/http/api.js.map +1 -0
- package/server/dist/features/auth/http/login-page.js +28 -0
- package/server/dist/features/auth/http/login-page.js.map +1 -0
- package/server/dist/features/auth/http/pages.js +50 -0
- package/server/dist/features/auth/http/pages.js.map +1 -0
- package/server/dist/features/auth/service.js +94 -0
- package/server/dist/features/auth/service.js.map +1 -0
- package/server/dist/features/cache/graphql/cache.field.resolver.js +5 -0
- package/server/dist/features/cache/graphql/cache.field.resolver.js.map +1 -0
- package/server/dist/features/cache/graphql/cache.mutation.resolver.js +49 -0
- package/server/dist/features/cache/graphql/cache.mutation.resolver.js.map +1 -0
- package/server/dist/features/cache/graphql/cache.query.resolver.js +21 -0
- package/server/dist/features/cache/graphql/cache.query.resolver.js.map +1 -0
- package/server/dist/features/cache/graphql/cache.resolver.js +12 -0
- package/server/dist/features/cache/graphql/cache.resolver.js.map +1 -0
- package/server/dist/features/cache/graphql/cache.type-defs.js +32 -0
- package/server/dist/features/cache/graphql/cache.type-defs.js.map +1 -0
- package/server/dist/features/cache/graphql/index.js +21 -0
- package/server/dist/features/cache/graphql/index.js.map +1 -0
- package/server/dist/features/image/graphql/image.field.resolver.js +14 -0
- package/server/dist/features/image/graphql/image.field.resolver.js.map +1 -0
- package/server/dist/features/image/graphql/image.mutation.resolver.js +21 -0
- package/server/dist/features/image/graphql/image.mutation.resolver.js.map +1 -0
- package/server/dist/features/image/graphql/image.query.resolver.js +40 -0
- package/server/dist/features/image/graphql/image.query.resolver.js.map +1 -0
- package/server/dist/features/image/graphql/image.resolver.js +12 -0
- package/server/dist/features/image/graphql/image.resolver.js.map +1 -0
- package/server/dist/features/image/graphql/image.type-defs.js +31 -0
- package/server/dist/features/image/graphql/image.type-defs.js.map +1 -0
- package/server/dist/features/image/graphql/index.js +16 -0
- package/server/dist/features/image/graphql/index.js.map +1 -0
- package/server/dist/features/image/http/upload.js +48 -0
- package/server/dist/features/image/http/upload.js.map +1 -0
- package/server/dist/features/image/services/delete.js +52 -0
- package/server/dist/features/image/services/delete.js.map +1 -0
- package/server/dist/{modules/remote-image.js → features/image/services/remote-fetch.js} +1 -1
- package/server/dist/features/image/services/remote-fetch.js.map +1 -0
- package/server/dist/{modules/image-upload.js → features/image/services/upload.js} +4 -8
- package/server/dist/features/image/services/upload.js.map +1 -0
- package/server/dist/{views/mcp-admin.js → features/mcp-admin/http/handlers.js} +3 -3
- package/server/dist/features/mcp-admin/http/handlers.js.map +1 -0
- package/server/dist/{modules/mcp-admin.js → features/mcp-admin/service.js} +3 -3
- package/server/dist/features/mcp-admin/service.js.map +1 -0
- package/server/dist/features/note/graphql/index.js +8 -0
- package/server/dist/features/note/graphql/index.js.map +1 -0
- package/server/dist/features/note/graphql/note.field.resolver.js +12 -0
- package/server/dist/features/note/graphql/note.field.resolver.js.map +1 -0
- package/server/dist/features/note/graphql/note.graphql.shared.js +23 -0
- package/server/dist/features/note/graphql/note.graphql.shared.js.map +1 -0
- package/server/dist/features/note/graphql/note.mutation.resolver.js +140 -0
- package/server/dist/features/note/graphql/note.mutation.resolver.js.map +1 -0
- package/server/dist/features/note/graphql/note.query.resolver.js +382 -0
- package/server/dist/features/note/graphql/note.query.resolver.js.map +1 -0
- package/server/dist/features/note/graphql/note.resolver.js +14 -0
- package/server/dist/features/note/graphql/note.resolver.js.map +1 -0
- package/server/dist/features/note/graphql/note.type-defs.js +184 -0
- package/server/dist/features/note/graphql/note.type-defs.js.map +1 -0
- package/server/dist/{views/note.js → features/note/http/mcp.js} +27 -15
- package/server/dist/features/note/http/mcp.js.map +1 -0
- package/server/dist/{modules/note-authoring.js → features/note/services/authoring.js} +25 -7
- package/server/dist/features/note/services/authoring.js.map +1 -0
- package/server/dist/{modules/note-cleanup.js → features/note/services/cleanup.js} +14 -23
- package/server/dist/features/note/services/cleanup.js.map +1 -0
- package/server/dist/features/note/services/search-backfill.js +84 -0
- package/server/dist/features/note/services/search-backfill.js.map +1 -0
- package/server/dist/features/note/services/search.js +197 -0
- package/server/dist/features/note/services/search.js.map +1 -0
- package/server/dist/{modules/note-snapshot.js → features/note/services/snapshot.js} +51 -49
- package/server/dist/features/note/services/snapshot.js.map +1 -0
- package/server/dist/{modules/note-tag-filter.js → features/note/services/tag-filter.js} +2 -6
- package/server/dist/features/note/services/tag-filter.js.map +1 -0
- package/server/dist/{modules/note-trash.js → features/note/services/trash.js} +28 -23
- package/server/dist/features/note/services/trash.js.map +1 -0
- package/server/dist/features/placeholder/graphql/index.js +27 -0
- package/server/dist/features/placeholder/graphql/index.js.map +1 -0
- package/server/dist/features/placeholder/graphql/placeholder.field.resolver.js +5 -0
- package/server/dist/features/placeholder/graphql/placeholder.field.resolver.js.map +1 -0
- package/server/dist/features/placeholder/graphql/placeholder.mutation.resolver.js +72 -0
- package/server/dist/features/placeholder/graphql/placeholder.mutation.resolver.js.map +1 -0
- package/server/dist/features/placeholder/graphql/placeholder.query.resolver.js +36 -0
- package/server/dist/features/placeholder/graphql/placeholder.query.resolver.js.map +1 -0
- package/server/dist/features/placeholder/graphql/placeholder.resolver.js +12 -0
- package/server/dist/features/placeholder/graphql/placeholder.resolver.js.map +1 -0
- package/server/dist/features/placeholder/graphql/placeholder.type-defs.js +50 -0
- package/server/dist/features/placeholder/graphql/placeholder.type-defs.js.map +1 -0
- package/server/dist/features/reminder/graphql/index.js +27 -0
- package/server/dist/features/reminder/graphql/index.js.map +1 -0
- package/server/dist/features/reminder/graphql/reminder.field.resolver.js +10 -0
- package/server/dist/features/reminder/graphql/reminder.field.resolver.js.map +1 -0
- package/server/dist/features/reminder/graphql/reminder.mutation.resolver.js +59 -0
- package/server/dist/features/reminder/graphql/reminder.mutation.resolver.js.map +1 -0
- package/server/dist/features/reminder/graphql/reminder.query.resolver.js +79 -0
- package/server/dist/features/reminder/graphql/reminder.query.resolver.js.map +1 -0
- package/server/dist/features/reminder/graphql/reminder.resolver.js +12 -0
- package/server/dist/features/reminder/graphql/reminder.resolver.js.map +1 -0
- package/server/dist/features/reminder/graphql/reminder.type-defs.js +51 -0
- package/server/dist/features/reminder/graphql/reminder.type-defs.js.map +1 -0
- package/server/dist/features/tag/graphql/index.js +14 -0
- package/server/dist/features/tag/graphql/index.js.map +1 -0
- package/server/dist/features/tag/graphql/tag.field.resolver.js +10 -0
- package/server/dist/features/tag/graphql/tag.field.resolver.js.map +1 -0
- package/server/dist/features/tag/graphql/tag.mutation.resolver.js +15 -0
- package/server/dist/features/tag/graphql/tag.mutation.resolver.js.map +1 -0
- package/server/dist/features/tag/graphql/tag.query.resolver.js +26 -0
- package/server/dist/features/tag/graphql/tag.query.resolver.js.map +1 -0
- package/server/dist/features/tag/graphql/tag.resolver.js +12 -0
- package/server/dist/features/tag/graphql/tag.resolver.js.map +1 -0
- package/server/dist/features/tag/graphql/tag.type-defs.js +46 -0
- package/server/dist/features/tag/graphql/tag.type-defs.js.map +1 -0
- package/server/dist/{views/tag.js → features/tag/http/mcp.js} +3 -3
- package/server/dist/features/tag/http/mcp.js.map +1 -0
- package/server/dist/{modules/tag-organization.js → features/tag/services/organization.js} +38 -8
- package/server/dist/features/tag/services/organization.js.map +1 -0
- package/server/dist/features/view/graphql/index.js +11 -0
- package/server/dist/features/view/graphql/index.js.map +1 -0
- package/server/dist/features/view/graphql/view.mutation.resolver.js +53 -0
- package/server/dist/features/view/graphql/view.mutation.resolver.js.map +1 -0
- package/server/dist/features/view/graphql/view.query.resolver.js +29 -0
- package/server/dist/features/view/graphql/view.query.resolver.js.map +1 -0
- package/server/dist/features/view/graphql/view.resolver.js +10 -0
- package/server/dist/features/view/graphql/view.resolver.js.map +1 -0
- package/server/dist/features/view/graphql/view.type-defs.js +63 -0
- package/server/dist/features/view/graphql/view.type-defs.js.map +1 -0
- package/server/dist/features/view/services/workspace.js +432 -0
- package/server/dist/features/view/services/workspace.js.map +1 -0
- package/server/dist/main.js +14 -0
- package/server/dist/main.js.map +1 -1
- package/server/dist/modules/auth-guard.js +10 -9
- package/server/dist/modules/auth-guard.js.map +1 -1
- package/server/dist/modules/auth-mode.js +1 -3
- package/server/dist/modules/auth-mode.js.map +1 -1
- package/server/dist/modules/blocknote.js +8 -17
- package/server/dist/modules/blocknote.js.map +1 -1
- package/server/dist/modules/data-maintenance.js +75 -0
- package/server/dist/modules/data-maintenance.js.map +1 -0
- package/server/dist/modules/error-handler.js.map +1 -1
- package/server/dist/modules/logger.js +5 -23
- package/server/dist/modules/logger.js.map +1 -1
- package/server/dist/modules/mcp-auth.js +4 -5
- package/server/dist/modules/mcp-auth.js.map +1 -1
- package/server/dist/modules/mcp-token.js.map +1 -1
- package/server/dist/modules/prisma-runtime.js +2 -7
- package/server/dist/modules/prisma-runtime.js.map +1 -1
- package/server/dist/modules/recovery-retention.js +1 -1
- package/server/dist/modules/recovery-retention.js.map +1 -1
- package/server/dist/modules/server-events-handler.js +34 -0
- package/server/dist/modules/server-events-handler.js.map +1 -0
- package/server/dist/modules/server-events.js +32 -0
- package/server/dist/modules/server-events.js.map +1 -0
- package/server/dist/modules/use-async.js.map +1 -1
- package/server/dist/paths.js.map +1 -1
- package/server/dist/routes/api.js +34 -0
- package/server/dist/routes/api.js.map +1 -0
- package/server/dist/routes/auth-pages.js +11 -0
- package/server/dist/routes/auth-pages.js.map +1 -0
- package/server/dist/routes/client.js +27 -0
- package/server/dist/routes/client.js.map +1 -0
- package/server/dist/routes/graphql.js +33 -0
- package/server/dist/routes/graphql.js.map +1 -0
- package/server/dist/routes/index.js +11 -0
- package/server/dist/routes/index.js.map +1 -0
- package/server/dist/routes/mcp.js +30 -0
- package/server/dist/routes/mcp.js.map +1 -0
- package/server/dist/schema/index.js +11 -8
- package/server/dist/schema/index.js.map +1 -1
- package/server/dist/types/index.js.map +1 -1
- package/server/prisma/migrations/20260413143000_0014_tag_name_unique/migration.sql +32 -0
- package/server/prisma/migrations/20260414143000_0015_note_searchable_text/migration.sql +5 -0
- package/server/prisma/migrations/20260416090000_0016_view_workspace/migration.sql +50 -0
- package/server/prisma/schema.prisma +66 -12
- package/server/client/dist/assets/Calendar-Kjy1PX6L.js +0 -25
- package/server/client/dist/assets/Graph-Bl5K2qUw.js +0 -1
- package/server/client/dist/assets/Note-BfGma2Qc.css +0 -1
- package/server/client/dist/assets/Note-DN_ko2M3.js +0 -1
- package/server/client/dist/assets/Reminders-BK-Uv9Ps.js +0 -1
- package/server/client/dist/assets/Search-ClHeWvmI.js +0 -1
- package/server/client/dist/assets/Tag-Dph4V_kl.js +0 -1
- package/server/client/dist/assets/TagNotes-CxP5qHZj.js +0 -1
- package/server/client/dist/assets/index-6lIw6jYW.js +0 -1
- package/server/client/dist/assets/index-Ba2XPRI8.js +0 -205
- package/server/client/dist/assets/manage-image-Br_kKxbb.js +0 -1
- package/server/client/dist/assets/manage-image-detail-9DzqbiqI.js +0 -1
- package/server/client/dist/assets/mcp-C_So91eX.js +0 -1
- package/server/client/dist/assets/trash-Cg3nJ1m5.js +0 -1
- package/server/dist/modules/auth.js +0 -25
- package/server/dist/modules/auth.js.map +0 -1
- package/server/dist/modules/image-upload.js.map +0 -1
- package/server/dist/modules/mcp-admin.js.map +0 -1
- package/server/dist/modules/note-authoring.js.map +0 -1
- package/server/dist/modules/note-cleanup.js.map +0 -1
- package/server/dist/modules/note-snapshot.js.map +0 -1
- package/server/dist/modules/note-tag-filter.js.map +0 -1
- package/server/dist/modules/note-trash.js.map +0 -1
- package/server/dist/modules/remote-image.js.map +0 -1
- package/server/dist/modules/tag-organization.js.map +0 -1
- package/server/dist/schema/cache/index.js +0 -58
- package/server/dist/schema/cache/index.js.map +0 -1
- package/server/dist/schema/image/index.js +0 -88
- package/server/dist/schema/image/index.js.map +0 -1
- package/server/dist/schema/note/index.js +0 -582
- package/server/dist/schema/note/index.js.map +0 -1
- package/server/dist/schema/placeholder/index.js +0 -105
- package/server/dist/schema/placeholder/index.js.map +0 -1
- package/server/dist/schema/reminder/index.js +0 -161
- package/server/dist/schema/reminder/index.js.map +0 -1
- package/server/dist/schema/tag/index.js +0 -81
- package/server/dist/schema/tag/index.js.map +0 -1
- package/server/dist/urls.js +0 -9
- package/server/dist/urls.js.map +0 -1
- package/server/dist/views/auth.js +0 -305
- package/server/dist/views/auth.js.map +0 -1
- package/server/dist/views/image.js +0 -44
- package/server/dist/views/image.js.map +0 -1
- package/server/dist/views/index.js +0 -6
- package/server/dist/views/index.js.map +0 -1
- package/server/dist/views/mcp-admin.js.map +0 -1
- package/server/dist/views/note.js.map +0 -1
- package/server/dist/views/tag.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/features/note/graphql/index.ts"],"sourcesContent":["export { createAllNotesQueryResolver, noteResolvers } from './note.resolver.js';\nexport { noteTypeDefs } from './note.type-defs.js';\n"],"mappings":"AAAA,SAAS,6BAA6B,qBAAqB;AAC3D,SAAS,oBAAoB;","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import models from "../../../models.js";
|
|
2
|
+
const noteFieldResolvers = {
|
|
3
|
+
tags: async (note) => models.tag.findMany({ where: { notes: { some: { id: note.id } } } }),
|
|
4
|
+
contentAsMarkdown: async (note) => {
|
|
5
|
+
const { blocksToMarkdown } = await import("../../../modules/blocknote.js");
|
|
6
|
+
return blocksToMarkdown(note.content);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
noteFieldResolvers
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=note.field.resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/features/note/graphql/note.field.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport type { Note } from '~/models.js';\nimport models from '~/models.js';\n\ntype NoteFieldResolvers = NonNullable<IResolvers['Note']>;\n\nexport const noteFieldResolvers: NoteFieldResolvers = {\n tags: async (note: Note) => models.tag.findMany({ where: { notes: { some: { id: note.id } } } }),\n contentAsMarkdown: async (note: Note) => {\n const { blocksToMarkdown } = await import('~/modules/blocknote.js');\n return blocksToMarkdown(note.content);\n },\n};\n"],"mappings":"AAEA,OAAO,YAAY;AAIZ,MAAM,qBAAyC;AAAA,EAClD,MAAM,OAAO,SAAe,OAAO,IAAI,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC;AAAA,EAC/F,mBAAmB,OAAO,SAAe;AACrC,UAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,wBAAwB;AAClE,WAAO,iBAAiB,KAAK,OAAO;AAAA,EACxC;AACJ;","names":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const extractBlocksByType = (type, dataArray) => {
|
|
2
|
+
let result = [];
|
|
3
|
+
for (const data of dataArray) {
|
|
4
|
+
if (data.type === type) {
|
|
5
|
+
result.push(data);
|
|
6
|
+
}
|
|
7
|
+
if (data.children && data.children.length > 0) {
|
|
8
|
+
result = result.concat(extractBlocksByType(type, data.children));
|
|
9
|
+
}
|
|
10
|
+
if (data.content && data.content.length > 0) {
|
|
11
|
+
for (const contentItem of data.content) {
|
|
12
|
+
if (contentItem.type === type) {
|
|
13
|
+
result.push(contentItem);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
export {
|
|
21
|
+
extractBlocksByType
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=note.graphql.shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/features/note/graphql/note.graphql.shared.ts"],"sourcesContent":["interface BlockNote<T = unknown> {\n id: string;\n type: string;\n props: T;\n content?: BlockNote<T>[];\n children?: BlockNote<T>[];\n}\n\nexport const extractBlocksByType = <T>(type: string, dataArray: BlockNote[]): BlockNote<T>[] => {\n let result: BlockNote[] = [];\n\n for (const data of dataArray) {\n if (data.type === type) {\n result.push(data);\n }\n\n if (data.children && data.children.length > 0) {\n result = result.concat(extractBlocksByType(type, data.children));\n }\n\n if (data.content && data.content.length > 0) {\n for (const contentItem of data.content) {\n if (contentItem.type === type) {\n result.push(contentItem);\n }\n }\n }\n }\n\n return result as BlockNote<T>[];\n};\n"],"mappings":"AAQO,MAAM,sBAAsB,CAAI,MAAc,cAA2C;AAC5F,MAAI,SAAsB,CAAC;AAE3B,aAAW,QAAQ,WAAW;AAC1B,QAAI,KAAK,SAAS,MAAM;AACpB,aAAO,KAAK,IAAI;AAAA,IACpB;AAEA,QAAI,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAC3C,eAAS,OAAO,OAAO,oBAAoB,MAAM,KAAK,QAAQ,CAAC;AAAA,IACnE;AAEA,QAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AACzC,iBAAW,eAAe,KAAK,SAAS;AACpC,YAAI,YAAY,SAAS,MAAM;AAC3B,iBAAO,KAAK,WAAW;AAAA,QAC3B;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO;AACX;","names":[]}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { buildNoteSearchProjection } from "../../../features/note/services/search.js";
|
|
2
|
+
import {
|
|
3
|
+
captureNoteBaseline,
|
|
4
|
+
createSnapshotMetaFromUserAgent,
|
|
5
|
+
restoreNoteSnapshot
|
|
6
|
+
} from "../../../features/note/services/snapshot.js";
|
|
7
|
+
import { purgeTrashedNoteById, restoreTrashedNoteById, trashNoteById } from "../../../features/note/services/trash.js";
|
|
8
|
+
import models from "../../../models.js";
|
|
9
|
+
import { extractBlocksByType } from "./note.graphql.shared.js";
|
|
10
|
+
const PLACEHOLDER_PREFIX = "{%";
|
|
11
|
+
const PLACEHOLDER_SUFFIX = "%}";
|
|
12
|
+
const replacePlaceholders = async (content) => {
|
|
13
|
+
const placeholders = content.matchAll(new RegExp(`${PLACEHOLDER_PREFIX}([^}]+)${PLACEHOLDER_SUFFIX}`, "g"));
|
|
14
|
+
const resolvedPlaceholders = await models.placeholder.findMany({
|
|
15
|
+
select: {
|
|
16
|
+
template: true,
|
|
17
|
+
replacement: true
|
|
18
|
+
},
|
|
19
|
+
where: { template: { in: Array.from(new Set(Array.from(placeholders, (match) => match[1]))) } }
|
|
20
|
+
});
|
|
21
|
+
let replacedContent = content;
|
|
22
|
+
for (const placeholder of resolvedPlaceholders) {
|
|
23
|
+
replacedContent = replacedContent.replace(
|
|
24
|
+
new RegExp(`${PLACEHOLDER_PREFIX}${placeholder.template}${PLACEHOLDER_SUFFIX}`, "g"),
|
|
25
|
+
placeholder.replacement
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
return replacedContent;
|
|
29
|
+
};
|
|
30
|
+
const getRequestUserAgent = (req) => {
|
|
31
|
+
const userAgentHeader = req?.headers["user-agent"];
|
|
32
|
+
return Array.isArray(userAgentHeader) ? userAgentHeader[0] : userAgentHeader;
|
|
33
|
+
};
|
|
34
|
+
const noteMutationResolvers = {
|
|
35
|
+
createNote: async (_, { note }) => {
|
|
36
|
+
const replacedTitle = await replacePlaceholders(note.title);
|
|
37
|
+
const replacedContent = await replacePlaceholders(note.content);
|
|
38
|
+
const createdNote = await models.note.create({
|
|
39
|
+
data: {
|
|
40
|
+
title: replacedTitle,
|
|
41
|
+
content: replacedContent,
|
|
42
|
+
...buildNoteSearchProjection({
|
|
43
|
+
title: replacedTitle,
|
|
44
|
+
content: replacedContent
|
|
45
|
+
}),
|
|
46
|
+
...note.layout && { layout: note.layout }
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
if (!replacedContent) {
|
|
50
|
+
return createdNote;
|
|
51
|
+
}
|
|
52
|
+
const blocks = extractBlocksByType("tag", JSON.parse(replacedContent));
|
|
53
|
+
return models.note.update({
|
|
54
|
+
where: { id: createdNote.id },
|
|
55
|
+
data: { tags: { set: blocks.map((block) => ({ id: Number(block.props.id) })) } }
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
updateNote: async (_, {
|
|
59
|
+
id,
|
|
60
|
+
note,
|
|
61
|
+
editSessionId
|
|
62
|
+
}, context) => {
|
|
63
|
+
const existingNote = await models.note.findUnique({
|
|
64
|
+
where: { id: Number(id) },
|
|
65
|
+
select: {
|
|
66
|
+
title: true,
|
|
67
|
+
content: true
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
if (!existingNote) {
|
|
71
|
+
throw "NOT FOUND";
|
|
72
|
+
}
|
|
73
|
+
const blocks = note.content ? extractBlocksByType("tag", JSON.parse(note.content)) : [];
|
|
74
|
+
await captureNoteBaseline({
|
|
75
|
+
noteId: Number(id),
|
|
76
|
+
...editSessionId ? { editSessionId } : {},
|
|
77
|
+
meta: createSnapshotMetaFromUserAgent(getRequestUserAgent(context.req))
|
|
78
|
+
});
|
|
79
|
+
const nextTitle = note.title ?? existingNote.title;
|
|
80
|
+
const nextContent = note.content ?? existingNote.content;
|
|
81
|
+
return models.note.update({
|
|
82
|
+
where: { id: Number(id) },
|
|
83
|
+
data: {
|
|
84
|
+
...note,
|
|
85
|
+
...buildNoteSearchProjection({
|
|
86
|
+
title: nextTitle,
|
|
87
|
+
content: nextContent
|
|
88
|
+
}),
|
|
89
|
+
...note.content ? { tags: { set: blocks.map((block) => ({ id: Number(block.props.id) })) } } : {}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
deleteNote: async (_, { id }) => {
|
|
94
|
+
const trashedNote = await trashNoteById(Number(id));
|
|
95
|
+
if (!trashedNote) {
|
|
96
|
+
throw "NOT FOUND";
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
},
|
|
100
|
+
restoreNoteSnapshot: async (_, { id }, context) => {
|
|
101
|
+
const note = await restoreNoteSnapshot(Number(id), {
|
|
102
|
+
meta: createSnapshotMetaFromUserAgent(getRequestUserAgent(context.req))
|
|
103
|
+
});
|
|
104
|
+
if (!note) {
|
|
105
|
+
throw "NOT FOUND";
|
|
106
|
+
}
|
|
107
|
+
return note;
|
|
108
|
+
},
|
|
109
|
+
restoreTrashedNote: async (_, { id }) => {
|
|
110
|
+
const note = await restoreTrashedNoteById(Number(id));
|
|
111
|
+
if (!note) {
|
|
112
|
+
throw "NOT FOUND";
|
|
113
|
+
}
|
|
114
|
+
return note;
|
|
115
|
+
},
|
|
116
|
+
purgeTrashedNote: async (_, { id }) => {
|
|
117
|
+
const purgedNote = await purgeTrashedNoteById(Number(id));
|
|
118
|
+
if (!purgedNote) {
|
|
119
|
+
throw "NOT FOUND";
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
},
|
|
123
|
+
pinNote: (_, { id, pinned }) => models.note.update({
|
|
124
|
+
where: { id: Number(id) },
|
|
125
|
+
data: { pinned: Boolean(pinned) }
|
|
126
|
+
}),
|
|
127
|
+
reorderNotes: async (_, { notes }) => {
|
|
128
|
+
const updatePromises = notes.map(
|
|
129
|
+
({ id, order }) => models.note.update({
|
|
130
|
+
where: { id: Number(id) },
|
|
131
|
+
data: { order }
|
|
132
|
+
})
|
|
133
|
+
);
|
|
134
|
+
return Promise.all(updatePromises);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
export {
|
|
138
|
+
noteMutationResolvers
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=note.mutation.resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/features/note/graphql/note.mutation.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport type { Request } from 'express';\nimport { buildNoteSearchProjection } from '~/features/note/services/search.js';\nimport {\n captureNoteBaseline,\n createSnapshotMetaFromUserAgent,\n restoreNoteSnapshot,\n} from '~/features/note/services/snapshot.js';\nimport { purgeTrashedNoteById, restoreTrashedNoteById, trashNoteById } from '~/features/note/services/trash.js';\nimport models from '~/models.js';\nimport type { NoteInput } from '~/types/index.js';\nimport { extractBlocksByType } from './note.graphql.shared.js';\n\nconst PLACEHOLDER_PREFIX = '{%';\nconst PLACEHOLDER_SUFFIX = '%}';\n\nconst replacePlaceholders = async (content: string) => {\n const placeholders = content.matchAll(new RegExp(`${PLACEHOLDER_PREFIX}([^}]+)${PLACEHOLDER_SUFFIX}`, 'g'));\n const resolvedPlaceholders = await models.placeholder.findMany({\n select: {\n template: true,\n replacement: true,\n },\n where: { template: { in: Array.from(new Set(Array.from(placeholders, (match) => match[1]))) } },\n });\n\n let replacedContent = content;\n\n for (const placeholder of resolvedPlaceholders) {\n replacedContent = replacedContent.replace(\n new RegExp(`${PLACEHOLDER_PREFIX}${placeholder.template}${PLACEHOLDER_SUFFIX}`, 'g'),\n placeholder.replacement,\n );\n }\n\n return replacedContent;\n};\n\nconst getRequestUserAgent = (req?: Request) => {\n const userAgentHeader = req?.headers['user-agent'];\n return Array.isArray(userAgentHeader) ? userAgentHeader[0] : userAgentHeader;\n};\n\ntype NoteMutationResolvers = NonNullable<IResolvers['Mutation']>;\n\nexport const noteMutationResolvers: NoteMutationResolvers = {\n createNote: async (_, { note }: { note: NoteInput }) => {\n const replacedTitle = await replacePlaceholders(note.title);\n const replacedContent = await replacePlaceholders(note.content);\n const createdNote = await models.note.create({\n data: {\n title: replacedTitle,\n content: replacedContent,\n ...buildNoteSearchProjection({\n title: replacedTitle,\n content: replacedContent,\n }),\n ...(note.layout && { layout: note.layout }),\n },\n });\n\n if (!replacedContent) {\n return createdNote;\n }\n\n const blocks = extractBlocksByType<{ id: string }>('tag', JSON.parse(replacedContent));\n\n return models.note.update({\n where: { id: createdNote.id },\n data: { tags: { set: blocks.map((block) => ({ id: Number(block.props.id) })) } },\n });\n },\n updateNote: async (\n _,\n {\n id,\n note,\n editSessionId,\n }: {\n id: number;\n note: NoteInput;\n editSessionId?: string;\n },\n context: {\n req?: Request;\n },\n ) => {\n const existingNote = await models.note.findUnique({\n where: { id: Number(id) },\n select: {\n title: true,\n content: true,\n },\n });\n\n if (!existingNote) {\n throw 'NOT FOUND';\n }\n\n const blocks = note.content ? extractBlocksByType<{ id: string }>('tag', JSON.parse(note.content)) : [];\n\n await captureNoteBaseline({\n noteId: Number(id),\n ...(editSessionId ? { editSessionId } : {}),\n meta: createSnapshotMetaFromUserAgent(getRequestUserAgent(context.req)),\n });\n\n const nextTitle = note.title ?? existingNote.title;\n const nextContent = note.content ?? existingNote.content;\n\n return models.note.update({\n where: { id: Number(id) },\n data: {\n ...note,\n ...buildNoteSearchProjection({\n title: nextTitle,\n content: nextContent,\n }),\n ...(note.content ? { tags: { set: blocks.map((block) => ({ id: Number(block.props.id) })) } } : {}),\n },\n });\n },\n deleteNote: async (_, { id }: { id: string }) => {\n const trashedNote = await trashNoteById(Number(id));\n\n if (!trashedNote) {\n throw 'NOT FOUND';\n }\n\n return true;\n },\n restoreNoteSnapshot: async (\n _,\n { id }: { id: string },\n context: {\n req?: Request;\n },\n ) => {\n const note = await restoreNoteSnapshot(Number(id), {\n meta: createSnapshotMetaFromUserAgent(getRequestUserAgent(context.req)),\n });\n\n if (!note) {\n throw 'NOT FOUND';\n }\n\n return note;\n },\n restoreTrashedNote: async (_, { id }: { id: string }) => {\n const note = await restoreTrashedNoteById(Number(id));\n\n if (!note) {\n throw 'NOT FOUND';\n }\n\n return note;\n },\n purgeTrashedNote: async (_, { id }: { id: string }) => {\n const purgedNote = await purgeTrashedNoteById(Number(id));\n\n if (!purgedNote) {\n throw 'NOT FOUND';\n }\n\n return true;\n },\n pinNote: (_, { id, pinned }: { id: string; pinned: boolean }) =>\n models.note.update({\n where: { id: Number(id) },\n data: { pinned: Boolean(pinned) },\n }),\n reorderNotes: async (_, { notes }: { notes: Array<{ id: string; order: number }> }) => {\n const updatePromises = notes.map(({ id, order }) =>\n models.note.update({\n where: { id: Number(id) },\n data: { order },\n }),\n );\n\n return Promise.all(updatePromises);\n },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import { getNoteCleanupPreview, listNoteCleanupCandidates } from "../../../features/note/services/cleanup.js";
|
|
2
|
+
import {
|
|
3
|
+
filterNotesBySearchQuery,
|
|
4
|
+
NOTE_SEARCH_TEXT_SCHEMA_VERSION,
|
|
5
|
+
parseNoteSearchQuery
|
|
6
|
+
} from "../../../features/note/services/search.js";
|
|
7
|
+
import { listNoteSnapshots } from "../../../features/note/services/snapshot.js";
|
|
8
|
+
import {
|
|
9
|
+
buildNoteTagNamesWhere,
|
|
10
|
+
normalizeNoteTagNames
|
|
11
|
+
} from "../../../features/note/services/tag-filter.js";
|
|
12
|
+
import { listTrashedNotes } from "../../../features/note/services/trash.js";
|
|
13
|
+
import models from "../../../models.js";
|
|
14
|
+
import { runDataMaintenanceInBackground } from "../../../modules/data-maintenance.js";
|
|
15
|
+
import { extractBlocksByType } from "./note.graphql.shared.js";
|
|
16
|
+
const buildAllNotesOrderBy = (searchFilter) => {
|
|
17
|
+
const sortBy = searchFilter.sortBy || "updatedAt";
|
|
18
|
+
const sortOrder = searchFilter.sortOrder || "desc";
|
|
19
|
+
const pinnedFirst = searchFilter.pinnedFirst || false;
|
|
20
|
+
const orderBy = [];
|
|
21
|
+
if (pinnedFirst) {
|
|
22
|
+
orderBy.push({ pinned: "desc" });
|
|
23
|
+
}
|
|
24
|
+
if (sortBy === "createdAt") {
|
|
25
|
+
orderBy.push({ createdAt: sortOrder });
|
|
26
|
+
} else {
|
|
27
|
+
orderBy.push({ updatedAt: sortOrder });
|
|
28
|
+
}
|
|
29
|
+
return orderBy;
|
|
30
|
+
};
|
|
31
|
+
const buildAllNotesSearchWhere = (searchFilter) => {
|
|
32
|
+
const parsedQuery = parseNoteSearchQuery(searchFilter.query);
|
|
33
|
+
if (!parsedQuery.hasFilters) {
|
|
34
|
+
return void 0;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
AND: [
|
|
38
|
+
{ searchableTextVersion: NOTE_SEARCH_TEXT_SCHEMA_VERSION },
|
|
39
|
+
...parsedQuery.included.map((keyword) => ({ searchableText: { contains: keyword } })),
|
|
40
|
+
...parsedQuery.excluded.map((keyword) => ({ NOT: { searchableText: { contains: keyword } } }))
|
|
41
|
+
]
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
const buildAllNotesStaleCandidateWhere = (searchFilter) => {
|
|
45
|
+
const parsedQuery = parseNoteSearchQuery(searchFilter.query);
|
|
46
|
+
return {
|
|
47
|
+
AND: [
|
|
48
|
+
{ searchableTextVersion: { not: NOTE_SEARCH_TEXT_SCHEMA_VERSION } },
|
|
49
|
+
...parsedQuery.included.map((keyword) => ({
|
|
50
|
+
OR: [{ title: { contains: keyword } }, { content: { contains: keyword } }]
|
|
51
|
+
}))
|
|
52
|
+
]
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
const compareNotesForSearch = (left, right, searchFilter) => {
|
|
56
|
+
if (searchFilter.pinnedFirst && left.pinned !== right.pinned) {
|
|
57
|
+
return left.pinned ? -1 : 1;
|
|
58
|
+
}
|
|
59
|
+
const sortBy = searchFilter.sortBy || "updatedAt";
|
|
60
|
+
const sortOrder = searchFilter.sortOrder || "desc";
|
|
61
|
+
const leftValue = sortBy === "createdAt" ? left.createdAt.getTime() : left.updatedAt.getTime();
|
|
62
|
+
const rightValue = sortBy === "createdAt" ? right.createdAt.getTime() : right.updatedAt.getTime();
|
|
63
|
+
if (leftValue === rightValue) {
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
return sortOrder === "asc" ? leftValue - rightValue : rightValue - leftValue;
|
|
67
|
+
};
|
|
68
|
+
const mergeSortedNotesForSearch = (left, right, searchFilter) => {
|
|
69
|
+
const merged = [];
|
|
70
|
+
let leftIndex = 0;
|
|
71
|
+
let rightIndex = 0;
|
|
72
|
+
while (leftIndex < left.length && rightIndex < right.length) {
|
|
73
|
+
if (compareNotesForSearch(left[leftIndex], right[rightIndex], searchFilter) <= 0) {
|
|
74
|
+
merged.push(left[leftIndex]);
|
|
75
|
+
leftIndex += 1;
|
|
76
|
+
} else {
|
|
77
|
+
merged.push(right[rightIndex]);
|
|
78
|
+
rightIndex += 1;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
while (leftIndex < left.length) {
|
|
82
|
+
merged.push(left[leftIndex]);
|
|
83
|
+
leftIndex += 1;
|
|
84
|
+
}
|
|
85
|
+
while (rightIndex < right.length) {
|
|
86
|
+
merged.push(right[rightIndex]);
|
|
87
|
+
rightIndex += 1;
|
|
88
|
+
}
|
|
89
|
+
return merged;
|
|
90
|
+
};
|
|
91
|
+
const createAllNotesQueryResolver = (deps = {
|
|
92
|
+
countNotes: ({ where }) => models.note.count({ where }),
|
|
93
|
+
findNotes: ({ orderBy, where, take, skip }) => models.note.findMany({
|
|
94
|
+
orderBy,
|
|
95
|
+
where,
|
|
96
|
+
take,
|
|
97
|
+
skip
|
|
98
|
+
}),
|
|
99
|
+
triggerSearchBackfill: () => {
|
|
100
|
+
void runDataMaintenanceInBackground();
|
|
101
|
+
}
|
|
102
|
+
}) => {
|
|
103
|
+
return async (_, {
|
|
104
|
+
searchFilter,
|
|
105
|
+
pagination
|
|
106
|
+
}) => {
|
|
107
|
+
const orderBy = buildAllNotesOrderBy(searchFilter);
|
|
108
|
+
const limit = Number(pagination.limit);
|
|
109
|
+
const offset = Number(pagination.offset);
|
|
110
|
+
const where = buildAllNotesSearchWhere(searchFilter);
|
|
111
|
+
if (!where) {
|
|
112
|
+
const [notes, totalCount] = await Promise.all([
|
|
113
|
+
deps.findNotes({
|
|
114
|
+
orderBy,
|
|
115
|
+
take: limit,
|
|
116
|
+
skip: offset
|
|
117
|
+
}),
|
|
118
|
+
deps.countNotes({})
|
|
119
|
+
]);
|
|
120
|
+
return {
|
|
121
|
+
totalCount,
|
|
122
|
+
notes
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const staleCandidateNotes = await deps.findNotes({
|
|
126
|
+
orderBy,
|
|
127
|
+
where: buildAllNotesStaleCandidateWhere(searchFilter)
|
|
128
|
+
});
|
|
129
|
+
if (staleCandidateNotes.length === 0) {
|
|
130
|
+
const [notes, totalCount] = await Promise.all([
|
|
131
|
+
deps.findNotes({
|
|
132
|
+
orderBy,
|
|
133
|
+
where,
|
|
134
|
+
take: limit,
|
|
135
|
+
skip: offset
|
|
136
|
+
}),
|
|
137
|
+
deps.countNotes({ where })
|
|
138
|
+
]);
|
|
139
|
+
return {
|
|
140
|
+
totalCount,
|
|
141
|
+
notes
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
deps.triggerSearchBackfill();
|
|
145
|
+
const parsedQuery = parseNoteSearchQuery(searchFilter.query);
|
|
146
|
+
const staleNotes = filterNotesBySearchQuery(staleCandidateNotes, parsedQuery);
|
|
147
|
+
if (staleNotes.length === 0) {
|
|
148
|
+
const [notes, totalCount] = await Promise.all([
|
|
149
|
+
deps.findNotes({
|
|
150
|
+
orderBy,
|
|
151
|
+
where,
|
|
152
|
+
take: limit,
|
|
153
|
+
skip: offset
|
|
154
|
+
}),
|
|
155
|
+
deps.countNotes({ where })
|
|
156
|
+
]);
|
|
157
|
+
return {
|
|
158
|
+
totalCount,
|
|
159
|
+
notes
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const [freshNotesPrefix, freshTotalCount] = await Promise.all([
|
|
163
|
+
deps.findNotes({
|
|
164
|
+
orderBy,
|
|
165
|
+
where,
|
|
166
|
+
take: offset + limit
|
|
167
|
+
}),
|
|
168
|
+
deps.countNotes({ where })
|
|
169
|
+
]);
|
|
170
|
+
const mergedNotes = mergeSortedNotesForSearch(freshNotesPrefix, staleNotes, searchFilter);
|
|
171
|
+
return {
|
|
172
|
+
totalCount: freshTotalCount + staleNotes.length,
|
|
173
|
+
notes: mergedNotes.slice(offset, offset + limit)
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
const noteQueryResolvers = {
|
|
178
|
+
allNotes: createAllNotesQueryResolver(),
|
|
179
|
+
notesInDateRange: async (_, {
|
|
180
|
+
dateRange
|
|
181
|
+
}) => {
|
|
182
|
+
const where = {
|
|
183
|
+
OR: [
|
|
184
|
+
{
|
|
185
|
+
updatedAt: {
|
|
186
|
+
gte: new Date(dateRange.start),
|
|
187
|
+
lte: new Date(dateRange.end)
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
createdAt: {
|
|
192
|
+
gte: new Date(dateRange.start),
|
|
193
|
+
lte: new Date(dateRange.end)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
]
|
|
197
|
+
};
|
|
198
|
+
return models.note.findMany({
|
|
199
|
+
orderBy: { createdAt: "asc" },
|
|
200
|
+
where
|
|
201
|
+
});
|
|
202
|
+
},
|
|
203
|
+
tagNotes: async (_, {
|
|
204
|
+
searchFilter,
|
|
205
|
+
pagination
|
|
206
|
+
}) => {
|
|
207
|
+
const where = { tags: { some: { id: Number(searchFilter.query) } } };
|
|
208
|
+
const notes = models.note.findMany({
|
|
209
|
+
orderBy: { updatedAt: "desc" },
|
|
210
|
+
where,
|
|
211
|
+
take: Number(pagination.limit),
|
|
212
|
+
skip: Number(pagination.offset)
|
|
213
|
+
});
|
|
214
|
+
return {
|
|
215
|
+
totalCount: models.note.count({ where }),
|
|
216
|
+
notes
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
notesByTagNames: async (_, {
|
|
220
|
+
tagNames,
|
|
221
|
+
mode,
|
|
222
|
+
pagination
|
|
223
|
+
}) => {
|
|
224
|
+
const normalizedTagNames = normalizeNoteTagNames(tagNames);
|
|
225
|
+
if (normalizedTagNames.length === 0) {
|
|
226
|
+
return {
|
|
227
|
+
totalCount: 0,
|
|
228
|
+
notes: []
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
const where = buildNoteTagNamesWhere(normalizedTagNames, mode);
|
|
232
|
+
const notes = models.note.findMany({
|
|
233
|
+
orderBy: { updatedAt: "desc" },
|
|
234
|
+
where,
|
|
235
|
+
take: Number(pagination.limit),
|
|
236
|
+
skip: Number(pagination.offset)
|
|
237
|
+
});
|
|
238
|
+
return {
|
|
239
|
+
totalCount: models.note.count({ where }),
|
|
240
|
+
notes
|
|
241
|
+
};
|
|
242
|
+
},
|
|
243
|
+
pinnedNotes: async () => models.note.findMany({
|
|
244
|
+
orderBy: [{ order: "asc" }, { updatedAt: "desc" }],
|
|
245
|
+
where: { pinned: true }
|
|
246
|
+
}),
|
|
247
|
+
imageNotes: async (_, { src }) => models.note.findMany({
|
|
248
|
+
orderBy: { updatedAt: "desc" },
|
|
249
|
+
where: { content: { contains: src } }
|
|
250
|
+
}),
|
|
251
|
+
backReferences: async (_, { id }) => {
|
|
252
|
+
return models.note.findMany({
|
|
253
|
+
orderBy: [{ pinned: "desc" }, { updatedAt: "desc" }],
|
|
254
|
+
where: { content: { contains: `reference","props":{"id":"${id}"` } }
|
|
255
|
+
});
|
|
256
|
+
},
|
|
257
|
+
note: async (_, { id }) => {
|
|
258
|
+
const note = await models.note.findUnique({ where: { id: Number(id) } });
|
|
259
|
+
if (!note) {
|
|
260
|
+
throw "NOT FOUND";
|
|
261
|
+
}
|
|
262
|
+
if (!note.content) {
|
|
263
|
+
return note;
|
|
264
|
+
}
|
|
265
|
+
const blocks = extractBlocksByType("reference", JSON.parse(note.content));
|
|
266
|
+
if (blocks.length === 0) {
|
|
267
|
+
return note;
|
|
268
|
+
}
|
|
269
|
+
const referenceIds = blocks.map((block) => Number(block.props.id));
|
|
270
|
+
const references = await models.note.findMany({ where: { id: { in: referenceIds } } });
|
|
271
|
+
const newContent = references.reduce((content, referenceNote) => {
|
|
272
|
+
const reference = blocks.find((block) => Number(block.props.id) === referenceNote.id);
|
|
273
|
+
if (reference && reference.props.title !== referenceNote.title) {
|
|
274
|
+
return content.replace(
|
|
275
|
+
`reference","props":{"id":"${reference.props.id}","title":"${reference.props.title}"`,
|
|
276
|
+
`reference","props":{"id":"${referenceNote.id}","title":"${referenceNote.title}"`
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
return content;
|
|
280
|
+
}, note.content);
|
|
281
|
+
if (newContent === note.content) {
|
|
282
|
+
return note;
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
JSON.parse(newContent);
|
|
286
|
+
return await models.note.update({
|
|
287
|
+
where: { id: note.id },
|
|
288
|
+
data: { content: newContent }
|
|
289
|
+
});
|
|
290
|
+
} catch {
|
|
291
|
+
return note;
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
noteCleanupCandidates: async (_, {
|
|
295
|
+
query,
|
|
296
|
+
pagination = {
|
|
297
|
+
limit: 20,
|
|
298
|
+
offset: 0
|
|
299
|
+
}
|
|
300
|
+
}) => {
|
|
301
|
+
const result = await listNoteCleanupCandidates({
|
|
302
|
+
keywords: query ? query.split(/[,\s]+/).map((keyword) => keyword.trim()).filter(Boolean) : void 0,
|
|
303
|
+
limit: Number(pagination.limit),
|
|
304
|
+
offset: Number(pagination.offset)
|
|
305
|
+
});
|
|
306
|
+
return result.notes;
|
|
307
|
+
},
|
|
308
|
+
noteCleanupPreview: async (_, { id }) => {
|
|
309
|
+
return getNoteCleanupPreview(Number(id));
|
|
310
|
+
},
|
|
311
|
+
noteSnapshots: async (_, {
|
|
312
|
+
id,
|
|
313
|
+
limit = 5
|
|
314
|
+
}) => {
|
|
315
|
+
return listNoteSnapshots(Number(id), Number(limit));
|
|
316
|
+
},
|
|
317
|
+
trashedNotes: async (_, {
|
|
318
|
+
pagination = {
|
|
319
|
+
limit: 25,
|
|
320
|
+
offset: 0
|
|
321
|
+
}
|
|
322
|
+
}) => {
|
|
323
|
+
return listTrashedNotes({
|
|
324
|
+
limit: Number(pagination.limit),
|
|
325
|
+
offset: Number(pagination.offset)
|
|
326
|
+
});
|
|
327
|
+
},
|
|
328
|
+
noteGraph: async () => {
|
|
329
|
+
const notes = await models.note.findMany({
|
|
330
|
+
select: {
|
|
331
|
+
id: true,
|
|
332
|
+
title: true,
|
|
333
|
+
content: true
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
const nodes = [];
|
|
337
|
+
const links = [];
|
|
338
|
+
const connectionCount = {};
|
|
339
|
+
const linkSet = /* @__PURE__ */ new Set();
|
|
340
|
+
for (const note of notes) {
|
|
341
|
+
if (!note.content) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
try {
|
|
345
|
+
const blocks = extractBlocksByType("reference", JSON.parse(note.content));
|
|
346
|
+
for (const block of blocks) {
|
|
347
|
+
const targetId = block.props.id;
|
|
348
|
+
if (targetId && String(note.id) !== targetId) {
|
|
349
|
+
const linkKey = `${note.id}-${targetId}`;
|
|
350
|
+
const reverseLinkKey = `${targetId}-${note.id}`;
|
|
351
|
+
if (!linkSet.has(linkKey) && !linkSet.has(reverseLinkKey)) {
|
|
352
|
+
linkSet.add(linkKey);
|
|
353
|
+
links.push({
|
|
354
|
+
source: String(note.id),
|
|
355
|
+
target: targetId
|
|
356
|
+
});
|
|
357
|
+
connectionCount[String(note.id)] = (connectionCount[String(note.id)] || 0) + 1;
|
|
358
|
+
connectionCount[targetId] = (connectionCount[targetId] || 0) + 1;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
} catch {
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
for (const note of notes) {
|
|
366
|
+
nodes.push({
|
|
367
|
+
id: String(note.id),
|
|
368
|
+
title: note.title || "Untitled",
|
|
369
|
+
connections: connectionCount[String(note.id)] || 0
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
nodes,
|
|
374
|
+
links
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
export {
|
|
379
|
+
createAllNotesQueryResolver,
|
|
380
|
+
noteQueryResolvers
|
|
381
|
+
};
|
|
382
|
+
//# sourceMappingURL=note.query.resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/features/note/graphql/note.query.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport { getNoteCleanupPreview, listNoteCleanupCandidates } from '~/features/note/services/cleanup.js';\nimport {\n filterNotesBySearchQuery,\n NOTE_SEARCH_TEXT_SCHEMA_VERSION,\n parseNoteSearchQuery,\n} from '~/features/note/services/search.js';\nimport { listNoteSnapshots } from '~/features/note/services/snapshot.js';\nimport {\n buildNoteTagNamesWhere,\n type NoteTagMatchMode,\n normalizeNoteTagNames,\n} from '~/features/note/services/tag-filter.js';\nimport { listTrashedNotes } from '~/features/note/services/trash.js';\nimport type { Note, Prisma } from '~/models.js';\nimport models from '~/models.js';\nimport { runDataMaintenanceInBackground } from '~/modules/data-maintenance.js';\nimport type { Pagination, SearchFilter } from '~/types/index.js';\nimport { extractBlocksByType } from './note.graphql.shared.js';\n\ninterface AllNotesResolverDeps {\n countNotes: (args: { where?: Prisma.NoteWhereInput }) => Promise<number>;\n findNotes: (args: {\n orderBy: Prisma.NoteOrderByWithRelationInput[];\n where?: Prisma.NoteWhereInput;\n take?: number;\n skip?: number;\n }) => Promise<Note[]>;\n triggerSearchBackfill: () => void;\n}\n\nconst buildAllNotesOrderBy = (searchFilter: SearchFilter) => {\n const sortBy = searchFilter.sortBy || 'updatedAt';\n const sortOrder = searchFilter.sortOrder || 'desc';\n const pinnedFirst = searchFilter.pinnedFirst || false;\n const orderBy: Prisma.NoteOrderByWithRelationInput[] = [];\n\n if (pinnedFirst) {\n orderBy.push({ pinned: 'desc' });\n }\n\n if (sortBy === 'createdAt') {\n orderBy.push({ createdAt: sortOrder as 'asc' | 'desc' });\n } else {\n orderBy.push({ updatedAt: sortOrder as 'asc' | 'desc' });\n }\n\n return orderBy;\n};\n\nconst buildAllNotesSearchWhere = (searchFilter: SearchFilter) => {\n const parsedQuery = parseNoteSearchQuery(searchFilter.query);\n\n if (!parsedQuery.hasFilters) {\n return undefined;\n }\n\n return {\n AND: [\n { searchableTextVersion: NOTE_SEARCH_TEXT_SCHEMA_VERSION },\n ...parsedQuery.included.map((keyword) => ({ searchableText: { contains: keyword } })),\n ...parsedQuery.excluded.map((keyword) => ({ NOT: { searchableText: { contains: keyword } } })),\n ],\n } satisfies Prisma.NoteWhereInput;\n};\n\nconst buildAllNotesStaleCandidateWhere = (searchFilter: SearchFilter) => {\n const parsedQuery = parseNoteSearchQuery(searchFilter.query);\n\n return {\n AND: [\n { searchableTextVersion: { not: NOTE_SEARCH_TEXT_SCHEMA_VERSION } },\n ...parsedQuery.included.map((keyword) => ({\n OR: [{ title: { contains: keyword } }, { content: { contains: keyword } }],\n })),\n ],\n } satisfies Prisma.NoteWhereInput;\n};\n\nconst compareNotesForSearch = (left: Note, right: Note, searchFilter: SearchFilter) => {\n if (searchFilter.pinnedFirst && left.pinned !== right.pinned) {\n return left.pinned ? -1 : 1;\n }\n\n const sortBy = searchFilter.sortBy || 'updatedAt';\n const sortOrder = searchFilter.sortOrder || 'desc';\n const leftValue = sortBy === 'createdAt' ? left.createdAt.getTime() : left.updatedAt.getTime();\n const rightValue = sortBy === 'createdAt' ? right.createdAt.getTime() : right.updatedAt.getTime();\n\n if (leftValue === rightValue) {\n return 0;\n }\n\n return sortOrder === 'asc' ? leftValue - rightValue : rightValue - leftValue;\n};\n\nconst mergeSortedNotesForSearch = (left: Note[], right: Note[], searchFilter: SearchFilter) => {\n const merged: Note[] = [];\n let leftIndex = 0;\n let rightIndex = 0;\n\n while (leftIndex < left.length && rightIndex < right.length) {\n if (compareNotesForSearch(left[leftIndex], right[rightIndex], searchFilter) <= 0) {\n merged.push(left[leftIndex]);\n leftIndex += 1;\n } else {\n merged.push(right[rightIndex]);\n rightIndex += 1;\n }\n }\n\n while (leftIndex < left.length) {\n merged.push(left[leftIndex]);\n leftIndex += 1;\n }\n\n while (rightIndex < right.length) {\n merged.push(right[rightIndex]);\n rightIndex += 1;\n }\n\n return merged;\n};\n\nexport const createAllNotesQueryResolver = (\n deps: AllNotesResolverDeps = {\n countNotes: ({ where }) => models.note.count({ where }),\n findNotes: ({ orderBy, where, take, skip }) =>\n models.note.findMany({\n orderBy,\n where,\n take,\n skip,\n }),\n triggerSearchBackfill: () => {\n void runDataMaintenanceInBackground();\n },\n },\n) => {\n return async (\n _: unknown,\n {\n searchFilter,\n pagination,\n }: {\n searchFilter: SearchFilter;\n pagination: Pagination;\n },\n ) => {\n const orderBy = buildAllNotesOrderBy(searchFilter);\n const limit = Number(pagination.limit);\n const offset = Number(pagination.offset);\n const where = buildAllNotesSearchWhere(searchFilter);\n\n if (!where) {\n const [notes, totalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n take: limit,\n skip: offset,\n }),\n deps.countNotes({}),\n ]);\n\n return {\n totalCount,\n notes,\n };\n }\n\n const staleCandidateNotes = await deps.findNotes({\n orderBy,\n where: buildAllNotesStaleCandidateWhere(searchFilter),\n });\n\n if (staleCandidateNotes.length === 0) {\n const [notes, totalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n where,\n take: limit,\n skip: offset,\n }),\n deps.countNotes({ where }),\n ]);\n\n return {\n totalCount,\n notes,\n };\n }\n\n deps.triggerSearchBackfill();\n\n const parsedQuery = parseNoteSearchQuery(searchFilter.query);\n const staleNotes = filterNotesBySearchQuery(staleCandidateNotes, parsedQuery);\n\n if (staleNotes.length === 0) {\n const [notes, totalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n where,\n take: limit,\n skip: offset,\n }),\n deps.countNotes({ where }),\n ]);\n\n return {\n totalCount,\n notes,\n };\n }\n\n const [freshNotesPrefix, freshTotalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n where,\n take: offset + limit,\n }),\n deps.countNotes({ where }),\n ]);\n\n const mergedNotes = mergeSortedNotesForSearch(freshNotesPrefix, staleNotes, searchFilter);\n\n return {\n totalCount: freshTotalCount + staleNotes.length,\n notes: mergedNotes.slice(offset, offset + limit),\n };\n };\n};\n\ntype NoteQueryResolvers = NonNullable<IResolvers['Query']>;\n\nexport const noteQueryResolvers: NoteQueryResolvers = {\n allNotes: createAllNotesQueryResolver(),\n notesInDateRange: async (\n _,\n {\n dateRange,\n }: {\n dateRange: {\n start: string;\n end: string;\n };\n },\n ) => {\n const where: Prisma.NoteWhereInput = {\n OR: [\n {\n updatedAt: {\n gte: new Date(dateRange.start),\n lte: new Date(dateRange.end),\n },\n },\n {\n createdAt: {\n gte: new Date(dateRange.start),\n lte: new Date(dateRange.end),\n },\n },\n ],\n };\n\n return models.note.findMany({\n orderBy: { createdAt: 'asc' },\n where,\n });\n },\n tagNotes: async (\n _,\n {\n searchFilter,\n pagination,\n }: {\n searchFilter: SearchFilter;\n pagination: Pagination;\n },\n ) => {\n const where: Prisma.NoteWhereInput = { tags: { some: { id: Number(searchFilter.query) } } };\n const notes = models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where,\n take: Number(pagination.limit),\n skip: Number(pagination.offset),\n });\n\n return {\n totalCount: models.note.count({ where }),\n notes,\n };\n },\n notesByTagNames: async (\n _,\n {\n tagNames,\n mode,\n pagination,\n }: {\n tagNames: string[];\n mode: NoteTagMatchMode;\n pagination: Pagination;\n },\n ) => {\n const normalizedTagNames = normalizeNoteTagNames(tagNames);\n\n if (normalizedTagNames.length === 0) {\n return {\n totalCount: 0,\n notes: [],\n };\n }\n\n const where = buildNoteTagNamesWhere(normalizedTagNames, mode);\n const notes = models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where,\n take: Number(pagination.limit),\n skip: Number(pagination.offset),\n });\n\n return {\n totalCount: models.note.count({ where }),\n notes,\n };\n },\n pinnedNotes: async () =>\n models.note.findMany({\n orderBy: [{ order: 'asc' }, { updatedAt: 'desc' }],\n where: { pinned: true },\n }),\n imageNotes: async (_, { src }: { src: string }) =>\n models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where: { content: { contains: src } },\n }),\n backReferences: async (_, { id }: { id: string }) => {\n return models.note.findMany({\n orderBy: [{ pinned: 'desc' }, { updatedAt: 'desc' }],\n where: { content: { contains: `reference\",\"props\":{\"id\":\"${id}\"` } },\n });\n },\n note: async (_, { id }: { id: string }) => {\n const note = await models.note.findUnique({ where: { id: Number(id) } });\n\n if (!note) {\n throw 'NOT FOUND';\n }\n\n if (!note.content) {\n return note;\n }\n\n const blocks = extractBlocksByType<{\n id: string;\n title: string;\n }>('reference', JSON.parse(note.content));\n\n if (blocks.length === 0) {\n return note;\n }\n\n const referenceIds = blocks.map((block) => Number(block.props.id));\n const references = await models.note.findMany({ where: { id: { in: referenceIds } } });\n const newContent = references.reduce<string>((content, referenceNote: Note) => {\n const reference = blocks.find((block) => Number(block.props.id) === referenceNote.id);\n\n if (reference && reference.props.title !== referenceNote.title) {\n return content.replace(\n `reference\",\"props\":{\"id\":\"${reference.props.id}\",\"title\":\"${reference.props.title}\"`,\n `reference\",\"props\":{\"id\":\"${referenceNote.id}\",\"title\":\"${referenceNote.title}\"`,\n );\n }\n\n return content;\n }, note.content);\n\n if (newContent === note.content) {\n return note;\n }\n\n try {\n JSON.parse(newContent);\n\n return await models.note.update({\n where: { id: note.id },\n data: { content: newContent },\n });\n } catch {\n // Keep the stored content unchanged if the synchronized payload becomes invalid.\n return note;\n }\n },\n noteCleanupCandidates: async (\n _,\n {\n query,\n pagination = {\n limit: 20,\n offset: 0,\n },\n }: {\n query?: string;\n pagination: Pagination;\n },\n ) => {\n const result = await listNoteCleanupCandidates({\n keywords: query\n ? query\n .split(/[,\\s]+/)\n .map((keyword) => keyword.trim())\n .filter(Boolean)\n : undefined,\n limit: Number(pagination.limit),\n offset: Number(pagination.offset),\n });\n\n return result.notes;\n },\n noteCleanupPreview: async (_, { id }: { id: string }) => {\n return getNoteCleanupPreview(Number(id));\n },\n noteSnapshots: async (\n _,\n {\n id,\n limit = 5,\n }: {\n id: string;\n limit?: number;\n },\n ) => {\n return listNoteSnapshots(Number(id), Number(limit));\n },\n trashedNotes: async (\n _,\n {\n pagination = {\n limit: 25,\n offset: 0,\n },\n }: {\n pagination: Pagination;\n },\n ) => {\n return listTrashedNotes({\n limit: Number(pagination.limit),\n offset: Number(pagination.offset),\n });\n },\n noteGraph: async () => {\n const notes = await models.note.findMany({\n select: {\n id: true,\n title: true,\n content: true,\n },\n });\n\n const nodes: Array<{ id: string; title: string; connections: number }> = [];\n const links: Array<{ source: string; target: string }> = [];\n const connectionCount: Record<string, number> = {};\n const linkSet = new Set<string>();\n\n for (const note of notes) {\n if (!note.content) {\n continue;\n }\n\n try {\n const blocks = extractBlocksByType<{ id: string }>('reference', JSON.parse(note.content));\n\n for (const block of blocks) {\n const targetId = block.props.id;\n\n if (targetId && String(note.id) !== targetId) {\n const linkKey = `${note.id}-${targetId}`;\n const reverseLinkKey = `${targetId}-${note.id}`;\n\n if (!linkSet.has(linkKey) && !linkSet.has(reverseLinkKey)) {\n linkSet.add(linkKey);\n links.push({\n source: String(note.id),\n target: targetId,\n });\n connectionCount[String(note.id)] = (connectionCount[String(note.id)] || 0) + 1;\n connectionCount[targetId] = (connectionCount[targetId] || 0) + 1;\n }\n }\n }\n } catch {\n // Skip notes with invalid JSON content\n }\n }\n\n for (const note of notes) {\n nodes.push({\n id: String(note.id),\n title: note.title || 'Untitled',\n connections: connectionCount[String(note.id)] || 0,\n });\n }\n\n return {\n nodes,\n links,\n };\n },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { noteFieldResolvers } from "./note.field.resolver.js";
|
|
2
|
+
import { noteMutationResolvers } from "./note.mutation.resolver.js";
|
|
3
|
+
import { noteQueryResolvers } from "./note.query.resolver.js";
|
|
4
|
+
import { createAllNotesQueryResolver as createAllNotesQueryResolver2 } from "./note.query.resolver.js";
|
|
5
|
+
const noteResolvers = {
|
|
6
|
+
Query: noteQueryResolvers,
|
|
7
|
+
Mutation: noteMutationResolvers,
|
|
8
|
+
Note: noteFieldResolvers
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
createAllNotesQueryResolver2 as createAllNotesQueryResolver,
|
|
12
|
+
noteResolvers
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=note.resolver.js.map
|