ocean-brain 0.7.5 → 0.8.1
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/index.js +3 -3
- package/dist/mcp.js +180 -736
- package/package.json +6 -2
- package/server/client/dist/assets/ArrowRight.es-CbA8ey6a.js +1 -0
- package/server/client/dist/assets/{Calendar-Bc2zJueR.js → Calendar-CgWgr1BV.js} +2 -2
- package/server/client/dist/assets/Callout-DKruIT0f.js +1 -0
- package/server/client/dist/assets/Copy.es-DFbgpaNJ.js +1 -0
- package/server/client/dist/assets/Graph-kCltGRlY.js +1 -0
- package/server/client/dist/assets/{Image-DxWhlIDG.js → Image-7W0DZwMo.js} +1 -1
- package/server/client/dist/assets/Image.es-5pXLx9TU.js +1 -0
- package/server/client/dist/assets/Note-BW6Np_5g.js +20 -0
- package/server/client/dist/assets/Plus.es-B0sg64VJ.js +1 -0
- package/server/client/dist/assets/Reminders-C10fHQcl.js +1 -0
- package/server/client/dist/assets/Search-tf2nV4v0.js +1 -0
- package/server/client/dist/assets/{SurfaceCard-CkAVMLPs.js → SurfaceCard-pydtvHfu.js} +1 -1
- package/server/client/dist/assets/Tag-uCoYbISy.js +1 -0
- package/server/client/dist/assets/TagNotes-CqOcQiRw.js +1 -0
- package/server/client/dist/assets/Trash.es-w32Goxfa.js +1 -0
- package/server/client/dist/assets/ViewNotes-slPXXoOY.js +1 -0
- package/server/client/dist/assets/ViewSectionDialog-brTrsF6G.js +102 -0
- package/server/client/dist/assets/Views-B_wsb-XJ.js +1 -0
- package/server/client/dist/assets/{graph-vendor-CUxe67Lr.js → graph-vendor-BAF95C0g.js} +2 -2
- package/server/client/dist/assets/image.api-CYsjXiMr.js +17 -0
- package/server/client/dist/assets/index-BR05aSXr.js +342 -0
- package/server/client/dist/assets/{index-D3BfroIT.js → index-D83QbOcw.js} +1 -1
- package/server/client/dist/assets/{index-C5BGzDgt.css → index-DPI6YoDt.css} +1 -1
- package/server/client/dist/assets/manage-image-BYIhWu56.js +1 -0
- package/server/client/dist/assets/{manage-image-detail-C8Q7K7I3.js → manage-image-detail-6KgmQvbN.js} +1 -1
- package/server/client/dist/assets/mcp-Dd98N9Hq.js +4 -0
- package/server/client/dist/assets/mcp-admin-adapter-DOgBsYpl.js +1 -0
- package/server/client/dist/assets/note-core-CMGUaW1v.js +176 -0
- package/server/client/dist/assets/note-vendor-Hoz9Q4-4.js +54 -0
- package/server/client/dist/assets/{placeholder-Cr_nI8UI.js → placeholder-siHGg9aK.js} +4 -4
- package/server/client/dist/assets/{properties-CvYWJWUM.js → properties-CyVRKgcT.js} +1 -1
- package/server/client/dist/assets/tag.api-CwmC8crB.js +21 -0
- package/server/client/dist/assets/trash-wojQBK9Z.js +1 -0
- package/server/client/dist/assets/{useReminderMutate-CDmIEwsw.js → useReminderMutate-DuVKxpBh.js} +1 -1
- package/server/client/dist/index.html +5 -5
- package/server/dist/app.js +0 -1
- package/server/dist/features/auth/http/api.js +0 -1
- package/server/dist/features/auth/http/login-page.js +272 -5
- package/server/dist/features/auth/http/pages.js +20 -3
- package/server/dist/features/auth/service.js +3 -2
- package/server/dist/features/cache/graphql/cache.field.resolver.js +0 -1
- package/server/dist/features/cache/graphql/cache.mutation.resolver.js +0 -1
- package/server/dist/features/cache/graphql/cache.query.resolver.js +0 -1
- package/server/dist/features/cache/graphql/cache.resolver.js +0 -1
- package/server/dist/features/cache/graphql/cache.type-defs.js +0 -1
- package/server/dist/features/cache/graphql/index.js +0 -1
- package/server/dist/features/image/graphql/image.field.resolver.js +0 -1
- package/server/dist/features/image/graphql/image.mutation.resolver.js +0 -1
- package/server/dist/features/image/graphql/image.query.resolver.js +0 -1
- package/server/dist/features/image/graphql/image.resolver.js +0 -1
- package/server/dist/features/image/graphql/image.type-defs.js +0 -1
- package/server/dist/features/image/graphql/index.js +0 -1
- package/server/dist/features/image/http/upload.js +34 -24
- package/server/dist/features/image/services/delete.js +0 -1
- package/server/dist/features/image/services/upload.js +0 -1
- package/server/dist/features/image/services/validation.js +110 -0
- package/server/dist/features/mcp-admin/http/handlers.js +11 -4
- package/server/dist/features/mcp-admin/service.js +0 -1
- package/server/dist/features/note/graphql/index.js +0 -1
- package/server/dist/features/note/graphql/note.field.resolver.js +0 -1
- package/server/dist/features/note/graphql/note.mutation.resolver.js +0 -1
- package/server/dist/features/note/graphql/note.query.resolver.js +0 -1
- package/server/dist/features/note/graphql/note.resolver.js +0 -1
- package/server/dist/features/note/graphql/note.type-defs.js +0 -1
- package/server/dist/features/note/http/mcp.js +8 -44
- package/server/dist/features/note/services/authoring.js +0 -1
- package/server/dist/features/note/services/cleanup.js +2 -3
- package/server/dist/features/note/services/content-blocks.js +0 -1
- package/server/dist/features/note/services/markdown-intent-write.js +11 -44
- package/server/dist/features/note/services/markdown-patch.js +4 -124
- package/server/dist/features/note/services/properties.js +0 -1
- package/server/dist/features/note/services/search-backfill.js +0 -1
- package/server/dist/features/note/services/search.js +0 -1
- package/server/dist/features/note/services/snapshot.js +0 -1
- package/server/dist/features/note/services/tag-filter.js +0 -1
- package/server/dist/features/note/services/trash.js +0 -1
- package/server/dist/features/note/services/write-conflict.js +0 -1
- package/server/dist/features/note/services/write.js +13 -14
- package/server/dist/features/placeholder/graphql/index.js +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.field.resolver.js +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.mutation.resolver.js +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.query.resolver.js +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.resolver.js +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.type-defs.js +0 -1
- package/server/dist/features/reminder/graphql/index.js +0 -1
- package/server/dist/features/reminder/graphql/reminder.field.resolver.js +0 -1
- package/server/dist/features/reminder/graphql/reminder.mutation.resolver.js +0 -1
- package/server/dist/features/reminder/graphql/reminder.query.resolver.js +0 -1
- package/server/dist/features/reminder/graphql/reminder.resolver.js +0 -1
- package/server/dist/features/reminder/graphql/reminder.type-defs.js +0 -1
- package/server/dist/features/tag/graphql/index.js +0 -1
- package/server/dist/features/tag/graphql/tag.field.resolver.js +0 -1
- package/server/dist/features/tag/graphql/tag.mutation.resolver.js +0 -1
- package/server/dist/features/tag/graphql/tag.query.resolver.js +16 -2
- package/server/dist/features/tag/graphql/tag.resolver.js +0 -1
- package/server/dist/features/tag/graphql/tag.type-defs.js +2 -1
- package/server/dist/features/tag/http/mcp.js +0 -1
- package/server/dist/features/tag/services/organization.js +0 -1
- package/server/dist/features/view/graphql/index.js +0 -1
- package/server/dist/features/view/graphql/view.mutation.resolver.js +0 -1
- package/server/dist/features/view/graphql/view.query.resolver.js +0 -1
- package/server/dist/features/view/graphql/view.resolver.js +0 -1
- package/server/dist/features/view/graphql/view.type-defs.js +0 -1
- package/server/dist/features/view/services/workspace.js +0 -1
- package/server/dist/main.js +0 -1
- package/server/dist/models.js +0 -1
- package/server/dist/modules/app-version.js +104 -0
- package/server/dist/modules/auth-guard.js +0 -1
- package/server/dist/modules/auth-mode.js +0 -1
- package/server/dist/modules/auth-redirect.js +0 -1
- package/server/dist/modules/blocknote-markdown-editor.js +53 -0
- package/server/dist/modules/blocknote-tree.js +0 -1
- package/server/dist/modules/blocknote.js +10 -4
- package/server/dist/modules/data-maintenance.js +0 -1
- package/server/dist/modules/error-handler.js +0 -1
- package/server/dist/modules/graphql.js +0 -1
- package/server/dist/modules/logger.js +0 -1
- package/server/dist/modules/mcp-auth.js +62 -2
- package/server/dist/modules/mcp-token.js +0 -1
- package/server/dist/modules/prisma-runtime.js +0 -1
- package/server/dist/modules/rate-limit.js +0 -1
- package/server/dist/modules/recovery-retention.js +0 -1
- package/server/dist/modules/server-events-handler.js +0 -1
- package/server/dist/modules/server-events.js +0 -1
- package/server/dist/modules/session-store.js +0 -1
- package/server/dist/modules/use-async.js +0 -1
- package/server/dist/paths.js +1 -1
- package/server/dist/routes/api.js +2 -9
- package/server/dist/routes/auth-pages.js +0 -1
- package/server/dist/routes/client.js +51 -2
- package/server/dist/routes/graphql.js +0 -1
- package/server/dist/routes/index.js +0 -1
- package/server/dist/routes/mcp.js +0 -1
- package/server/dist/schema/index.js +0 -1
- package/server/dist/start.js +0 -1
- package/server/dist/types/index.js +0 -1
- package/server/dist/types/input.js +0 -1
- package/server/client/dist/assets/Callout-B4kA_Cvr.js +0 -1
- package/server/client/dist/assets/Graph-uq5jfJgt.js +0 -1
- package/server/client/dist/assets/Image.es-BpAOJjJT.js +0 -1
- package/server/client/dist/assets/Note-Bo8ZYRP-.js +0 -22
- package/server/client/dist/assets/Plus.es-Dc_js8AC.js +0 -1
- package/server/client/dist/assets/Reminders-lj7Equld.js +0 -1
- package/server/client/dist/assets/Search-1wcRO5--.js +0 -1
- package/server/client/dist/assets/Tag-CeygwFfv.js +0 -1
- package/server/client/dist/assets/TagNotes-B8DqItxw.js +0 -1
- package/server/client/dist/assets/Trash.es-OuQVb_SX.js +0 -1
- package/server/client/dist/assets/ViewNotes-BH7PbdOD.js +0 -1
- package/server/client/dist/assets/ViewSectionTableRenderer-BJwhd5be.js +0 -102
- package/server/client/dist/assets/Views-eYFtsdFj.js +0 -1
- package/server/client/dist/assets/image.api-C0eYGCeH.js +0 -17
- package/server/client/dist/assets/index-jIfkRdY_.js +0 -361
- package/server/client/dist/assets/manage-image-C0YwkLIP.js +0 -1
- package/server/client/dist/assets/mcp-DHHhTLC8.js +0 -1
- package/server/client/dist/assets/note-core-Z6kqulGB.js +0 -180
- package/server/client/dist/assets/note-vendor-i1M2FSI2.js +0 -54
- package/server/client/dist/assets/trash-DA27aW7L.js +0 -1
- package/server/client/dist/fonts/Pretendard-Bold.woff +0 -0
- package/server/client/dist/fonts/Pretendard-Regular.woff +0 -0
- package/server/dist/app.js.map +0 -1
- package/server/dist/features/auth/http/api.js.map +0 -1
- package/server/dist/features/auth/http/login-page.js.map +0 -1
- package/server/dist/features/auth/http/pages.js.map +0 -1
- package/server/dist/features/auth/service.js.map +0 -1
- package/server/dist/features/cache/graphql/cache.field.resolver.js.map +0 -1
- package/server/dist/features/cache/graphql/cache.mutation.resolver.js.map +0 -1
- package/server/dist/features/cache/graphql/cache.query.resolver.js.map +0 -1
- package/server/dist/features/cache/graphql/cache.resolver.js.map +0 -1
- package/server/dist/features/cache/graphql/cache.type-defs.js.map +0 -1
- package/server/dist/features/cache/graphql/index.js.map +0 -1
- package/server/dist/features/image/graphql/image.field.resolver.js.map +0 -1
- package/server/dist/features/image/graphql/image.mutation.resolver.js.map +0 -1
- package/server/dist/features/image/graphql/image.query.resolver.js.map +0 -1
- package/server/dist/features/image/graphql/image.resolver.js.map +0 -1
- package/server/dist/features/image/graphql/image.type-defs.js.map +0 -1
- package/server/dist/features/image/graphql/index.js.map +0 -1
- package/server/dist/features/image/http/upload.js.map +0 -1
- package/server/dist/features/image/services/delete.js.map +0 -1
- package/server/dist/features/image/services/remote-fetch.js +0 -176
- package/server/dist/features/image/services/remote-fetch.js.map +0 -1
- package/server/dist/features/image/services/upload.js.map +0 -1
- package/server/dist/features/mcp-admin/http/handlers.js.map +0 -1
- package/server/dist/features/mcp-admin/service.js.map +0 -1
- package/server/dist/features/note/graphql/index.js.map +0 -1
- package/server/dist/features/note/graphql/note.field.resolver.js.map +0 -1
- package/server/dist/features/note/graphql/note.mutation.resolver.js.map +0 -1
- package/server/dist/features/note/graphql/note.query.resolver.js.map +0 -1
- package/server/dist/features/note/graphql/note.resolver.js.map +0 -1
- package/server/dist/features/note/graphql/note.type-defs.js.map +0 -1
- package/server/dist/features/note/http/mcp.js.map +0 -1
- package/server/dist/features/note/services/authoring.js.map +0 -1
- package/server/dist/features/note/services/cleanup.js.map +0 -1
- package/server/dist/features/note/services/content-blocks.js.map +0 -1
- package/server/dist/features/note/services/markdown-intent-write.js.map +0 -1
- package/server/dist/features/note/services/markdown-patch.js.map +0 -1
- package/server/dist/features/note/services/properties.js.map +0 -1
- package/server/dist/features/note/services/search-backfill.js.map +0 -1
- package/server/dist/features/note/services/search.js.map +0 -1
- package/server/dist/features/note/services/snapshot.js.map +0 -1
- package/server/dist/features/note/services/tag-filter.js.map +0 -1
- package/server/dist/features/note/services/trash.js.map +0 -1
- package/server/dist/features/note/services/write-conflict.js.map +0 -1
- package/server/dist/features/note/services/write.js.map +0 -1
- package/server/dist/features/placeholder/graphql/index.js.map +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.field.resolver.js.map +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.mutation.resolver.js.map +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.query.resolver.js.map +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.resolver.js.map +0 -1
- package/server/dist/features/placeholder/graphql/placeholder.type-defs.js.map +0 -1
- package/server/dist/features/reminder/graphql/index.js.map +0 -1
- package/server/dist/features/reminder/graphql/reminder.field.resolver.js.map +0 -1
- package/server/dist/features/reminder/graphql/reminder.mutation.resolver.js.map +0 -1
- package/server/dist/features/reminder/graphql/reminder.query.resolver.js.map +0 -1
- package/server/dist/features/reminder/graphql/reminder.resolver.js.map +0 -1
- package/server/dist/features/reminder/graphql/reminder.type-defs.js.map +0 -1
- package/server/dist/features/tag/graphql/index.js.map +0 -1
- package/server/dist/features/tag/graphql/tag.field.resolver.js.map +0 -1
- package/server/dist/features/tag/graphql/tag.mutation.resolver.js.map +0 -1
- package/server/dist/features/tag/graphql/tag.query.resolver.js.map +0 -1
- package/server/dist/features/tag/graphql/tag.resolver.js.map +0 -1
- package/server/dist/features/tag/graphql/tag.type-defs.js.map +0 -1
- package/server/dist/features/tag/http/mcp.js.map +0 -1
- package/server/dist/features/tag/services/organization.js.map +0 -1
- package/server/dist/features/view/graphql/index.js.map +0 -1
- package/server/dist/features/view/graphql/view.mutation.resolver.js.map +0 -1
- package/server/dist/features/view/graphql/view.query.resolver.js.map +0 -1
- package/server/dist/features/view/graphql/view.resolver.js.map +0 -1
- package/server/dist/features/view/graphql/view.type-defs.js.map +0 -1
- package/server/dist/features/view/services/workspace.js.map +0 -1
- package/server/dist/main.js.map +0 -1
- package/server/dist/models.js.map +0 -1
- package/server/dist/modules/auth-guard.js.map +0 -1
- package/server/dist/modules/auth-mode.js.map +0 -1
- package/server/dist/modules/auth-redirect.js.map +0 -1
- package/server/dist/modules/blocknote-tree.js.map +0 -1
- package/server/dist/modules/blocknote.js.map +0 -1
- package/server/dist/modules/data-maintenance.js.map +0 -1
- package/server/dist/modules/error-handler.js.map +0 -1
- package/server/dist/modules/graphql.js.map +0 -1
- package/server/dist/modules/logger.js.map +0 -1
- package/server/dist/modules/mcp-auth.js.map +0 -1
- package/server/dist/modules/mcp-token.js.map +0 -1
- package/server/dist/modules/prisma-runtime.js.map +0 -1
- package/server/dist/modules/rate-limit.js.map +0 -1
- package/server/dist/modules/recovery-retention.js.map +0 -1
- package/server/dist/modules/server-events-handler.js.map +0 -1
- package/server/dist/modules/server-events.js.map +0 -1
- package/server/dist/modules/session-store.js.map +0 -1
- package/server/dist/modules/use-async.js.map +0 -1
- package/server/dist/paths.js.map +0 -1
- package/server/dist/routes/api.js.map +0 -1
- package/server/dist/routes/auth-pages.js.map +0 -1
- package/server/dist/routes/client.js.map +0 -1
- package/server/dist/routes/graphql.js.map +0 -1
- package/server/dist/routes/index.js.map +0 -1
- package/server/dist/routes/mcp.js.map +0 -1
- package/server/dist/schema/index.js.map +0 -1
- package/server/dist/start.js.map +0 -1
- package/server/dist/types/index.js.map +0 -1
- package/server/dist/types/input.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/note/services/snapshot.ts"],"sourcesContent":["import { FILE_HEADERS_ONLY, formatPatch, structuredPatch } from 'diff';\nimport { ensureTagByName } from '~/features/tag/services/organization.js';\nimport models, { type NoteLayout, type PropertyValueType } from '~/models.js';\nimport { blocksToMarkdown, extractTagIdsFromContentJson } from '~/modules/blocknote.js';\nimport { type BlockNoteTreeNode, parseBlockNoteContent, walkBlockNoteTree } from '~/modules/blocknote-tree.js';\nimport {\n createRetentionCutoff,\n RECOVERY_CLEANUP_BATCH_LIMIT,\n SNAPSHOT_MAX_PER_NOTE,\n SNAPSHOT_RETENTION_DAYS,\n} from '~/modules/recovery-retention.js';\nimport { calculateMarkdownSha256 } from './markdown-patch.js';\nimport { buildNoteSearchProjection, extractVisibleSearchTextFromContent } from './search.js';\n\nconst SNAPSHOT_CONTENT_PREVIEW_MAX_LENGTH = 240;\n\ninterface NoteRecord {\n id: number;\n title: string;\n content: string;\n pinned: boolean;\n order: number;\n layout: NoteLayout;\n updatedAt?: Date;\n properties?: SnapshotNoteProperty[];\n}\n\ninterface SnapshotNoteProperty {\n key: string;\n name: string;\n valueType: PropertyValueType;\n textValue?: string | null;\n textValueNormalized?: string | null;\n numberValue?: number | null;\n dateValue?: Date | string | null;\n boolValue?: boolean | null;\n optionValue?: string | null;\n optionLabel?: string | null;\n optionColor?: string | null;\n}\n\ninterface NoteSnapshotRecord {\n id: number;\n noteId: number;\n title: string;\n payload: string;\n editSessionId: string | null;\n meta: string | null;\n createdAt: Date;\n}\n\ninterface NoteSnapshotDeps {\n findNoteById: (id: number) => Promise<NoteRecord | null>;\n findSnapshotByEditSessionId: (noteId: number, editSessionId: string) => Promise<NoteSnapshotRecord | null>;\n findLatestSnapshot: (noteId: number) => Promise<NoteSnapshotRecord | null>;\n createSnapshot: (input: {\n noteId: number;\n title: string;\n payload: string;\n editSessionId?: string;\n meta?: string;\n }) => Promise<NoteSnapshotRecord>;\n listSnapshots: (noteId: number, limit: number) => Promise<NoteSnapshotRecord[]>;\n findSnapshotById: (id: number) => Promise<NoteSnapshotRecord | null>;\n findNextSnapshot?: (snapshot: NoteSnapshotRecord) => Promise<NoteSnapshotRecord | null>;\n findPreviousSnapshot?: (snapshot: NoteSnapshotRecord) => Promise<NoteSnapshotRecord | null>;\n purgeExpiredSnapshots: (before: Date, limit: number) => Promise<number>;\n trimOverflowSnapshots: (noteId: number, keep: number, limit: number) => Promise<number>;\n resolveRestoredTags?: (content: string) => Promise<ResolvedRestoredSnapshotTags | null>;\n updateNote: (\n id: number,\n input: {\n title: string;\n content: string;\n pinned: boolean;\n order: number;\n layout: NoteLayout;\n tagIds?: number[];\n properties?: SnapshotNoteProperty[];\n },\n ) => Promise<NoteRecord>;\n}\n\nexport interface NoteSnapshotMeta {\n entrypoint?: 'web' | 'mobile' | 'mcp';\n label?: string;\n}\n\ninterface NoteSnapshotPayload {\n title: string;\n content: string;\n pinned: boolean;\n order: number;\n layout: NoteLayout;\n properties?: SnapshotNoteProperty[];\n}\n\ninterface TagRecord {\n id: number;\n name: string;\n}\n\ninterface ResolvedRestoredSnapshotTags {\n content: string;\n tagIds: number[];\n}\n\ninterface ResolveRestoredSnapshotTagsDeps {\n ensureTagByName: (name: string) => Promise<TagRecord>;\n findTagsByIds: (ids: number[]) => Promise<TagRecord[]>;\n}\n\nexport interface NoteSnapshotSummary {\n id: string;\n title: string;\n createdAt: string;\n meta: NoteSnapshotMeta;\n contentPreview: string;\n contentAsMarkdown?: string;\n payload?: string;\n}\n\nexport type NoteSnapshotDiffTarget = 'next' | 'previous' | 'current';\n\nexport interface NoteSnapshotDiffEndpoint {\n kind: 'snapshot' | 'current_note';\n id: string;\n title: string;\n createdAt?: string;\n updatedAt?: string;\n meta?: NoteSnapshotMeta;\n}\n\nexport interface NoteSnapshotDiffResult {\n noteId: string;\n mode: 'snapshot_to_snapshot' | 'snapshot_to_current';\n before: NoteSnapshotDiffEndpoint;\n after: NoteSnapshotDiffEndpoint;\n diff: {\n markdown: string;\n changedLineCount: number;\n changedCharCount: number;\n beforeMarkdownSha256: string;\n afterMarkdownSha256: string;\n };\n}\n\nconst parseMeta = (value?: string | null): NoteSnapshotMeta => {\n if (!value) {\n return {};\n }\n\n try {\n const parsed = JSON.parse(value) as NoteSnapshotMeta;\n return {\n ...(parsed.entrypoint ? { entrypoint: parsed.entrypoint } : {}),\n ...(parsed.label ? { label: parsed.label } : {}),\n };\n } catch {\n return {};\n }\n};\n\nconst readSnapshotContent = (payload: string) => {\n try {\n return parsePayload(payload).content;\n } catch {\n return '';\n }\n};\n\nconst readSnapshotTitle = (payload: string, fallback: string) => {\n try {\n return parsePayload(payload).title;\n } catch {\n return fallback;\n }\n};\n\nconst buildSnapshotContentPreview = (content: string) => {\n const preview = extractVisibleSearchTextFromContent(content);\n\n if (preview.length <= SNAPSHOT_CONTENT_PREVIEW_MAX_LENGTH) {\n return preview;\n }\n\n return `${preview.slice(0, SNAPSHOT_CONTENT_PREVIEW_MAX_LENGTH).trimEnd()}...`;\n};\n\nconst serializeSnapshot = (snapshot: NoteSnapshotRecord): NoteSnapshotSummary => ({\n id: String(snapshot.id),\n title: snapshot.title,\n contentPreview: buildSnapshotContentPreview(readSnapshotContent(snapshot.payload)),\n createdAt: snapshot.createdAt.toISOString(),\n meta: parseMeta(snapshot.meta),\n payload: snapshot.payload,\n});\n\nconst serializePayload = (note: NoteRecord): string => {\n const payload: NoteSnapshotPayload = {\n title: note.title,\n content: note.content,\n pinned: note.pinned,\n order: note.order,\n layout: note.layout,\n ...(note.properties\n ? {\n properties: note.properties.map((property) => ({\n ...property,\n ...(property.dateValue instanceof Date ? { dateValue: property.dateValue.toISOString() } : {}),\n })),\n }\n : {}),\n };\n\n return JSON.stringify(payload);\n};\n\nconst hasSameSnapshotPayload = (snapshot: NoteSnapshotRecord | null, payload: string) => {\n return snapshot?.payload === payload;\n};\n\nconst parsePayload = (payload: string): NoteSnapshotPayload => {\n const parsed = JSON.parse(payload) as Partial<NoteSnapshotPayload>;\n\n if (\n typeof parsed.title !== 'string' ||\n typeof parsed.content !== 'string' ||\n typeof parsed.pinned !== 'boolean' ||\n typeof parsed.order !== 'number' ||\n (parsed.layout !== 'narrow' && parsed.layout !== 'wide' && parsed.layout !== 'full')\n ) {\n throw new Error('INVALID_NOTE_SNAPSHOT_PAYLOAD');\n }\n\n return parsed as NoteSnapshotPayload;\n};\n\nconst extractRestoredTagIds = (content: string): number[] | null => {\n try {\n return extractTagIdsFromContentJson(content)\n .map(normalizeRestoredTagId)\n .filter((id): id is number => id !== null);\n } catch {\n return null;\n }\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null;\n};\n\nconst normalizeRestoredTagId = (value: unknown) => {\n if (value === undefined || value === null) {\n return null;\n }\n\n const normalized = typeof value === 'string' ? value.trim() : value;\n\n if (normalized === '') {\n return null;\n }\n\n const numericId = Number(normalized);\n return Number.isSafeInteger(numericId) && numericId > 0 ? numericId : null;\n};\n\nconst normalizeRestoredTagName = (value: unknown) => {\n if (typeof value !== 'string') {\n return null;\n }\n\n const normalized = value.trim();\n return normalized ? normalized : null;\n};\n\nexport const resolveRestoredSnapshotTags = async (\n content: string,\n deps: ResolveRestoredSnapshotTagsDeps,\n): Promise<ResolvedRestoredSnapshotTags | null> => {\n const parsed = parseBlockNoteContent(content);\n\n if (!parsed) {\n return null;\n }\n\n const tagRefs: Array<{\n id: number | null;\n name: string | null;\n node: BlockNoteTreeNode;\n props: Record<string, unknown>;\n }> = [];\n\n walkBlockNoteTree(parsed, (node) => {\n if (node.type !== 'tag' || !isRecord(node.props)) {\n return;\n }\n\n tagRefs.push({\n id: normalizeRestoredTagId(node.props.id),\n name: normalizeRestoredTagName(node.props.tag),\n node,\n props: node.props,\n });\n });\n\n if (tagRefs.length === 0) {\n return { content, tagIds: [] };\n }\n\n const candidateIds = Array.from(new Set(tagRefs.map((tag) => tag.id).filter((id): id is number => id !== null)));\n const existingTags = candidateIds.length > 0 ? await deps.findTagsByIds(candidateIds) : [];\n const existingTagIds = new Set(existingTags.map((tag) => tag.id));\n const tagIds = new Set<number>();\n let contentChanged = false;\n\n for (const tagRef of tagRefs) {\n if (tagRef.id !== null && existingTagIds.has(tagRef.id)) {\n tagIds.add(tagRef.id);\n continue;\n }\n\n if (!tagRef.name) {\n continue;\n }\n\n try {\n const resolvedTag = await deps.ensureTagByName(tagRef.name);\n tagRef.node.props = {\n ...tagRef.props,\n id: String(resolvedTag.id),\n tag: resolvedTag.name,\n };\n tagIds.add(resolvedTag.id);\n contentChanged = true;\n } catch {\n continue;\n }\n }\n\n return {\n content: contentChanged ? JSON.stringify(parsed) : content,\n tagIds: [...tagIds],\n };\n};\n\nexport const renderNoteSnapshotContentAsMarkdown = async (payload: string) => {\n try {\n const snapshotPayload = parsePayload(payload);\n return blocksToMarkdown(snapshotPayload.content);\n } catch {\n return '';\n }\n};\n\nconst renderNoteRecordContentAsMarkdown = async (note: NoteRecord) => {\n try {\n return blocksToMarkdown(note.content);\n } catch {\n return '';\n }\n};\n\nconst createSnapshotMarkdownDiff = (beforeMarkdown: string, afterMarkdown: string, contextLines: number | null = 3) => {\n const patch = structuredPatch('before.md', 'after.md', beforeMarkdown, afterMarkdown, undefined, undefined, {\n context: contextLines === null ? Number.MAX_SAFE_INTEGER : contextLines,\n });\n const changedLines = patch.hunks.flatMap((hunk) =>\n hunk.lines.filter((line) => (line.startsWith('+') && !line.startsWith('+++')) || line.startsWith('-')),\n );\n\n return {\n markdown: formatPatch(patch, FILE_HEADERS_ONLY).trimEnd(),\n changedLineCount: changedLines.length,\n changedCharCount: changedLines.reduce((total, line) => total + line.slice(1).length, 0),\n };\n};\n\nconst snapshotToDiffEndpoint = (snapshot: NoteSnapshotRecord): NoteSnapshotDiffEndpoint => ({\n kind: 'snapshot',\n id: String(snapshot.id),\n title: readSnapshotTitle(snapshot.payload, snapshot.title),\n createdAt: snapshot.createdAt.toISOString(),\n meta: parseMeta(snapshot.meta),\n});\n\nconst noteToDiffEndpoint = (note: NoteRecord): NoteSnapshotDiffEndpoint => ({\n kind: 'current_note',\n id: String(note.id),\n title: note.title,\n ...(note.updatedAt ? { updatedAt: note.updatedAt.toISOString() } : {}),\n});\n\nconst buildSnapshotDiff = async ({\n beforeSnapshot,\n afterSnapshot,\n afterNote,\n contextLines,\n}: {\n beforeSnapshot: NoteSnapshotRecord;\n afterSnapshot?: NoteSnapshotRecord;\n afterNote?: NoteRecord;\n contextLines?: number | null;\n}): Promise<NoteSnapshotDiffResult | null> => {\n if (!afterSnapshot && !afterNote) {\n return null;\n }\n\n const beforeMarkdown = await renderNoteSnapshotContentAsMarkdown(beforeSnapshot.payload);\n const afterMarkdown = afterSnapshot\n ? await renderNoteSnapshotContentAsMarkdown(afterSnapshot.payload)\n : afterNote\n ? await renderNoteRecordContentAsMarkdown(afterNote)\n : '';\n const diff = createSnapshotMarkdownDiff(beforeMarkdown, afterMarkdown, contextLines ?? 3);\n\n return {\n noteId: String(beforeSnapshot.noteId),\n mode: afterSnapshot ? 'snapshot_to_snapshot' : 'snapshot_to_current',\n before: snapshotToDiffEndpoint(beforeSnapshot),\n after: afterSnapshot ? snapshotToDiffEndpoint(afterSnapshot) : noteToDiffEndpoint(afterNote as NoteRecord),\n diff: {\n markdown: diff.markdown,\n changedLineCount: diff.changedLineCount,\n changedCharCount: diff.changedCharCount,\n beforeMarkdownSha256: calculateMarkdownSha256(beforeMarkdown),\n afterMarkdownSha256: calculateMarkdownSha256(afterMarkdown),\n },\n };\n};\n\nconst serializeSnapshotWithContent = async (snapshot: NoteSnapshotRecord): Promise<NoteSnapshotSummary> => {\n const contentAsMarkdown = await renderNoteSnapshotContentAsMarkdown(snapshot.payload);\n\n return {\n ...serializeSnapshot(snapshot),\n contentAsMarkdown,\n };\n};\n\nexport const createSnapshotMetaFromUserAgent = (userAgent?: string | null): string | undefined => {\n const normalized = userAgent?.toLowerCase() ?? '';\n const isMobile = /iphone|ipad|android|mobile/.test(normalized);\n\n return JSON.stringify({\n entrypoint: isMobile ? 'mobile' : 'web',\n label: isMobile ? 'Mobile browser' : 'Web browser',\n } satisfies NoteSnapshotMeta);\n};\n\nexport const MCP_SNAPSHOT_META = JSON.stringify({\n entrypoint: 'mcp',\n label: 'MCP',\n} satisfies NoteSnapshotMeta);\n\nconst defaultPurgeExpiredSnapshots = async (before: Date, limit: number) => {\n const expiredSnapshots = await models.noteSnapshot.findMany({\n where: { createdAt: { lt: before } },\n orderBy: { createdAt: 'asc' },\n take: limit,\n select: { id: true },\n });\n\n if (expiredSnapshots.length === 0) {\n return 0;\n }\n\n const deleted = await models.noteSnapshot.deleteMany({\n where: { id: { in: expiredSnapshots.map((snapshot) => snapshot.id) } },\n });\n\n return deleted.count;\n};\n\nconst defaultTrimOverflowSnapshots = async (noteId: number, keep: number, limit: number) => {\n const overflowSnapshots = await models.noteSnapshot.findMany({\n where: { noteId },\n orderBy: [{ createdAt: 'desc' }, { id: 'desc' }],\n skip: keep,\n take: limit,\n select: { id: true },\n });\n\n if (overflowSnapshots.length === 0) {\n return 0;\n }\n\n const deleted = await models.noteSnapshot.deleteMany({\n where: { id: { in: overflowSnapshots.map((snapshot) => snapshot.id) } },\n });\n\n return deleted.count;\n};\n\nexport const createNoteSnapshotService = (deps: NoteSnapshotDeps) => ({\n captureBaseline: async (input: {\n noteId: number;\n editSessionId?: string;\n meta?: string;\n baseline?: NoteRecord;\n force?: boolean;\n }) => {\n await deps.purgeExpiredSnapshots(createRetentionCutoff(SNAPSHOT_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n\n const existing =\n input.editSessionId && !input.force\n ? await deps.findSnapshotByEditSessionId(input.noteId, input.editSessionId)\n : null;\n\n if (existing) {\n return serializeSnapshot(existing);\n }\n\n const note = input.baseline ?? (await deps.findNoteById(input.noteId));\n\n if (!note) {\n return null;\n }\n\n const payload = serializePayload(note);\n const latestSnapshot = await deps.findLatestSnapshot(note.id);\n\n if (latestSnapshot && hasSameSnapshotPayload(latestSnapshot, payload)) {\n return serializeSnapshot(latestSnapshot);\n }\n\n const snapshot = await deps.createSnapshot({\n noteId: note.id,\n title: note.title,\n payload,\n ...(input.editSessionId && !input.force ? { editSessionId: input.editSessionId } : {}),\n ...(input.meta ? { meta: input.meta } : {}),\n });\n\n await deps.trimOverflowSnapshots(note.id, SNAPSHOT_MAX_PER_NOTE, RECOVERY_CLEANUP_BATCH_LIMIT);\n\n return serializeSnapshot(snapshot);\n },\n\n listSnapshots: async (noteId: number, limit = SNAPSHOT_MAX_PER_NOTE) => {\n await deps.purgeExpiredSnapshots(createRetentionCutoff(SNAPSHOT_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n await deps.trimOverflowSnapshots(noteId, SNAPSHOT_MAX_PER_NOTE, RECOVERY_CLEANUP_BATCH_LIMIT);\n const snapshots = await deps.listSnapshots(noteId, limit);\n return snapshots.map(serializeSnapshot);\n },\n\n getSnapshot: async (snapshotId: number) => {\n await deps.purgeExpiredSnapshots(createRetentionCutoff(SNAPSHOT_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n const snapshot = await deps.findSnapshotById(snapshotId);\n\n if (!snapshot) {\n return null;\n }\n\n return serializeSnapshotWithContent(snapshot);\n },\n\n diffSnapshot: async (\n snapshotId: number,\n options: {\n compareToSnapshotId?: number;\n target?: NoteSnapshotDiffTarget;\n contextLines?: number | null;\n } = {},\n ) => {\n await deps.purgeExpiredSnapshots(createRetentionCutoff(SNAPSHOT_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n const snapshot = await deps.findSnapshotById(snapshotId);\n\n if (!snapshot) {\n return null;\n }\n\n if (options.compareToSnapshotId !== undefined) {\n const comparedSnapshot = await deps.findSnapshotById(options.compareToSnapshotId);\n\n if (!comparedSnapshot || comparedSnapshot.noteId !== snapshot.noteId) {\n return null;\n }\n\n return buildSnapshotDiff({\n beforeSnapshot: snapshot,\n afterSnapshot: comparedSnapshot,\n contextLines: options.contextLines,\n });\n }\n\n if (options.target === 'previous') {\n const previousSnapshot = deps.findPreviousSnapshot ? await deps.findPreviousSnapshot(snapshot) : null;\n\n if (!previousSnapshot) {\n return null;\n }\n\n return buildSnapshotDiff({\n beforeSnapshot: previousSnapshot,\n afterSnapshot: snapshot,\n contextLines: options.contextLines,\n });\n }\n\n if (options.target === 'current') {\n const note = await deps.findNoteById(snapshot.noteId);\n\n if (!note) {\n return null;\n }\n\n return buildSnapshotDiff({\n beforeSnapshot: snapshot,\n afterNote: note,\n contextLines: options.contextLines,\n });\n }\n\n const nextSnapshot = deps.findNextSnapshot ? await deps.findNextSnapshot(snapshot) : null;\n\n if (nextSnapshot) {\n return buildSnapshotDiff({\n beforeSnapshot: snapshot,\n afterSnapshot: nextSnapshot,\n contextLines: options.contextLines,\n });\n }\n\n const note = await deps.findNoteById(snapshot.noteId);\n\n if (!note) {\n return null;\n }\n\n return buildSnapshotDiff({\n beforeSnapshot: snapshot,\n afterNote: note,\n contextLines: options.contextLines,\n });\n },\n\n restoreSnapshot: async (snapshotId: number, options?: { meta?: string }) => {\n await deps.purgeExpiredSnapshots(createRetentionCutoff(SNAPSHOT_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n\n const snapshot = await deps.findSnapshotById(snapshotId);\n\n if (!snapshot) {\n return null;\n }\n\n const note = await deps.findNoteById(snapshot.noteId);\n\n if (!note) {\n return null;\n }\n\n const payload = parsePayload(snapshot.payload);\n const resolvedTags = deps.resolveRestoredTags\n ? await deps.resolveRestoredTags(payload.content)\n : extractRestoredTagIds(payload.content);\n const restoredPayload =\n resolvedTags && !Array.isArray(resolvedTags)\n ? {\n ...payload,\n content: resolvedTags.content,\n }\n : payload;\n const restoredTagIds = Array.isArray(resolvedTags) ? resolvedTags : resolvedTags?.tagIds;\n\n const currentPayload = serializePayload(note);\n const latestSnapshot = await deps.findLatestSnapshot(note.id);\n\n if (!hasSameSnapshotPayload(latestSnapshot, currentPayload)) {\n await deps.createSnapshot({\n noteId: note.id,\n title: note.title,\n payload: currentPayload,\n ...(options?.meta ? { meta: options.meta } : {}),\n });\n }\n\n const restoredNote = await deps.updateNote(snapshot.noteId, {\n ...restoredPayload,\n ...(restoredTagIds !== undefined ? { tagIds: restoredTagIds } : {}),\n });\n\n await deps.trimOverflowSnapshots(note.id, SNAPSHOT_MAX_PER_NOTE, RECOVERY_CLEANUP_BATCH_LIMIT);\n\n return restoredNote;\n },\n});\n\nexport const defaultNoteSnapshotService = createNoteSnapshotService({\n findNoteById: async (id) => {\n const note = await models.note.findUnique({\n where: { id },\n include: {\n properties: {\n include: { definition: true, option: true },\n },\n },\n });\n\n if (!note) {\n return null;\n }\n\n return {\n ...note,\n properties: note.properties.map((property) => ({\n key: property.definition.key,\n name: property.definition.name,\n valueType: property.definition.valueType,\n textValue: property.textValue,\n textValueNormalized: property.textValueNormalized,\n numberValue: property.numberValue,\n dateValue: property.dateValue,\n boolValue: property.boolValue,\n optionValue: property.option?.value ?? null,\n optionLabel: property.option?.label ?? null,\n optionColor: property.option?.color ?? null,\n })),\n };\n },\n findSnapshotByEditSessionId: async (noteId, editSessionId) => {\n return models.noteSnapshot.findFirst({\n where: {\n noteId,\n editSessionId,\n },\n });\n },\n findLatestSnapshot: async (noteId) => {\n return models.noteSnapshot.findFirst({\n where: { noteId },\n orderBy: [{ createdAt: 'desc' }, { id: 'desc' }],\n });\n },\n createSnapshot: async (input) => {\n return models.noteSnapshot.create({\n data: {\n noteId: input.noteId,\n title: input.title,\n payload: input.payload,\n ...(input.editSessionId ? { editSessionId: input.editSessionId } : {}),\n ...(input.meta ? { meta: input.meta } : {}),\n },\n });\n },\n purgeExpiredSnapshots: defaultPurgeExpiredSnapshots,\n trimOverflowSnapshots: defaultTrimOverflowSnapshots,\n resolveRestoredTags: async (content) => {\n return resolveRestoredSnapshotTags(content, {\n ensureTagByName: async (name) => {\n const result = await ensureTagByName(name);\n return {\n id: Number(result.tag.id),\n name: result.tag.name,\n };\n },\n findTagsByIds: async (ids) => {\n return models.tag.findMany({\n where: { id: { in: ids } },\n select: {\n id: true,\n name: true,\n },\n });\n },\n });\n },\n listSnapshots: async (noteId, limit) => {\n return models.noteSnapshot.findMany({\n where: { noteId },\n orderBy: [{ createdAt: 'desc' }, { id: 'desc' }],\n take: limit,\n });\n },\n findSnapshotById: async (id) => {\n return models.noteSnapshot.findUnique({ where: { id } });\n },\n findNextSnapshot: async (snapshot) => {\n return models.noteSnapshot.findFirst({\n where: {\n noteId: snapshot.noteId,\n OR: [\n { createdAt: { gt: snapshot.createdAt } },\n {\n createdAt: snapshot.createdAt,\n id: { gt: snapshot.id },\n },\n ],\n },\n orderBy: [{ createdAt: 'asc' }, { id: 'asc' }],\n });\n },\n findPreviousSnapshot: async (snapshot) => {\n return models.noteSnapshot.findFirst({\n where: {\n noteId: snapshot.noteId,\n OR: [\n { createdAt: { lt: snapshot.createdAt } },\n {\n createdAt: snapshot.createdAt,\n id: { lt: snapshot.id },\n },\n ],\n },\n orderBy: [{ createdAt: 'desc' }, { id: 'desc' }],\n });\n },\n updateNote: async (id, input) => {\n const { tagIds, properties, ...noteInput } = input;\n\n return models.$transaction(async (tx) => {\n const note = await tx.note.update({\n where: { id },\n data: {\n ...noteInput,\n ...buildNoteSearchProjection({\n title: noteInput.title,\n content: noteInput.content,\n }),\n ...(tagIds !== undefined ? { tags: { set: tagIds.map((tagId) => ({ id: tagId })) } } : {}),\n },\n });\n\n if (properties !== undefined) {\n await tx.noteProperty.deleteMany({ where: { noteId: id } });\n\n for (const property of properties) {\n const definition = await tx.propertyDefinition.upsert({\n where: { key: property.key },\n create: {\n key: property.key,\n name: property.name,\n valueType: property.valueType,\n },\n update: {\n name: property.name,\n valueType: property.valueType,\n },\n });\n\n const option =\n property.valueType === 'select' && property.optionValue\n ? await tx.propertyOption.upsert({\n where: {\n propertyDefinitionId_value: {\n propertyDefinitionId: definition.id,\n value: property.optionValue,\n },\n },\n create: {\n propertyDefinitionId: definition.id,\n value: property.optionValue,\n label: property.optionLabel ?? property.optionValue,\n color: property.optionColor ?? null,\n },\n update: {\n label: property.optionLabel ?? property.optionValue,\n color: property.optionColor ?? null,\n },\n })\n : null;\n\n await tx.noteProperty.create({\n data: {\n noteId: id,\n propertyDefinitionId: definition.id,\n optionId: option?.id ?? null,\n textValue: property.textValue ?? null,\n textValueNormalized: property.textValueNormalized ?? null,\n numberValue: property.numberValue ?? null,\n dateValue: property.dateValue ? new Date(property.dateValue) : null,\n boolValue: property.boolValue ?? null,\n },\n });\n }\n }\n\n return note;\n });\n },\n});\n\nexport const captureNoteBaseline = async (input: {\n noteId: number;\n editSessionId?: string;\n meta?: string;\n baseline?: NoteRecord;\n force?: boolean;\n}) => {\n return defaultNoteSnapshotService.captureBaseline(input);\n};\n\nexport const listNoteSnapshots = async (noteId: number, limit?: number) => {\n return defaultNoteSnapshotService.listSnapshots(noteId, limit);\n};\n\nexport const getNoteSnapshot = async (snapshotId: number) => {\n return defaultNoteSnapshotService.getSnapshot(snapshotId);\n};\n\nexport const diffNoteSnapshot = async (\n snapshotId: number,\n options?: {\n compareToSnapshotId?: number;\n target?: NoteSnapshotDiffTarget;\n contextLines?: number | null;\n },\n) => {\n return defaultNoteSnapshotService.diffSnapshot(snapshotId, options);\n};\n\nexport const restoreNoteSnapshot = async (snapshotId: number, options?: { meta?: string }) => {\n return defaultNoteSnapshotService.restoreSnapshot(snapshotId, options);\n};\n\nexport const purgeExpiredNoteSnapshots = async () => {\n return defaultPurgeExpiredSnapshots(createRetentionCutoff(SNAPSHOT_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n};\n"],"mappings":"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","names":["note"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/note/services/tag-filter.ts"],"sourcesContent":["import type { Prisma } from '~/models.js';\n\nexport type NoteTagMatchMode = 'and' | 'or';\n\nexport const normalizeNoteTagNames = (tagNames: string[]) => {\n return Array.from(new Set(tagNames.map((tagName) => tagName.trim()).filter(Boolean)));\n};\n\nexport const buildNoteTagNamesWhere = (tagNames: string[], mode: NoteTagMatchMode): Prisma.NoteWhereInput => {\n const normalizedTagNames = normalizeNoteTagNames(tagNames);\n\n if (normalizedTagNames.length === 0) {\n return { id: -1 };\n }\n\n if (mode === 'or') {\n return { tags: { some: { name: { in: normalizedTagNames } } } };\n }\n\n return { AND: normalizedTagNames.map((tagName) => ({ tags: { some: { name: tagName } } })) };\n};\n"],"mappings":"AAIO,MAAM,wBAAwB,CAAC,aAAuB;AACzD,SAAO,MAAM,KAAK,IAAI,IAAI,SAAS,IAAI,CAAC,YAAY,QAAQ,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AACxF;AAEO,MAAM,yBAAyB,CAAC,UAAoB,SAAkD;AACzG,QAAM,qBAAqB,sBAAsB,QAAQ;AAEzD,MAAI,mBAAmB,WAAW,GAAG;AACjC,WAAO,EAAE,IAAI,GAAG;AAAA,EACpB;AAEA,MAAI,SAAS,MAAM;AACf,WAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,mBAAmB,EAAE,EAAE,EAAE;AAAA,EAClE;AAEA,SAAO,EAAE,KAAK,mBAAmB,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,EAAE,EAAE,EAAE;AAC/F;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/note/services/trash.ts"],"sourcesContent":["import models, { type NoteLayout, type PropertyValueType, type ReminderPriority } from '~/models.js';\nimport {\n createRetentionCutoff,\n RECOVERY_CLEANUP_BATCH_LIMIT,\n TRASH_RETENTION_DAYS,\n} from '~/modules/recovery-retention.js';\nimport { buildNoteSearchProjection, extractVisibleSearchTextFromContent } from './search.js';\n\nconst TRASHED_NOTE_CONTENT_PREVIEW_MAX_LENGTH = 240;\n\ninterface LiveTagRecord {\n id: number;\n name: string;\n}\n\ninterface LiveReminderRecord {\n id: number;\n reminderDate: Date;\n completed: boolean;\n priority: ReminderPriority;\n content: string | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface LiveNoteRecord {\n id: number;\n title: string;\n content: string;\n createdAt: Date;\n updatedAt: Date;\n pinned: boolean;\n order: number;\n layout: NoteLayout;\n tags: LiveTagRecord[];\n reminders: LiveReminderRecord[];\n properties?: LivePropertyRecord[];\n}\n\ninterface LivePropertyRecord {\n id: number;\n textValue: string | null;\n textValueNormalized: string | null;\n numberValue: number | null;\n dateValue: Date | null;\n boolValue: boolean | null;\n option: { value: string; label: string; color: string | null } | null;\n createdAt: Date;\n updatedAt: Date;\n definition: {\n key: string;\n name: string;\n valueType: PropertyValueType;\n };\n}\n\ninterface RestoredNoteRecord {\n id: number;\n title: string;\n content: string;\n createdAt: Date;\n updatedAt: Date;\n pinned: boolean;\n order: number;\n layout: NoteLayout;\n}\n\ninterface DeletedTagRecord {\n name: string;\n}\n\ninterface DeletedReminderRecord {\n originalId: number | null;\n reminderDate: Date;\n completed: boolean;\n priority: ReminderPriority;\n content: string | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface DeletedNoteRecord {\n id: number;\n title: string;\n content: string;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date;\n pinned: boolean;\n order: number;\n layout: NoteLayout;\n tags: DeletedTagRecord[];\n reminders: DeletedReminderRecord[];\n properties?: DeletedPropertyRecord[];\n}\n\ninterface DeletedPropertyRecord {\n key: string;\n name: string;\n valueType: PropertyValueType;\n textValue: string | null;\n textValueNormalized: string | null;\n numberValue: number | null;\n dateValue: Date | null;\n boolValue: boolean | null;\n optionValue: string | null;\n optionLabel: string | null;\n optionColor: string | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface BlockNoteNode {\n type: string;\n props?: Record<string, unknown>;\n content?: BlockNoteNode[];\n children?: BlockNoteNode[];\n}\n\nexport interface TrashedNoteSummary {\n id: string;\n title: string;\n createdAt: string;\n updatedAt: string;\n deletedAt: string;\n contentPreview: string;\n pinned: boolean;\n order: number;\n layout: NoteLayout;\n tagNames: string[];\n}\n\nexport interface TrashedNotesResult {\n totalCount: number;\n notes: TrashedNoteSummary[];\n}\n\nexport interface TrashedNoteDetail extends TrashedNoteSummary {\n contentAsMarkdown: string;\n}\n\nexport class NoteRestoreConflictError extends Error {\n constructor(message = 'A live note with the same id already exists.') {\n super(message);\n this.name = 'NoteRestoreConflictError';\n }\n}\n\ninterface NoteTrashServiceDeps {\n countDeletedNotes: () => Promise<number>;\n findDeletedNote: (id: number) => Promise<DeletedNoteRecord | null>;\n findLiveNote: (id: number) => Promise<LiveNoteRecord | null>;\n listDeletedNotes: (skip: number, take: number) => Promise<DeletedNoteRecord[]>;\n liveNoteExists: (id: number) => Promise<boolean>;\n moveNoteToTrash: (note: LiveNoteRecord) => Promise<DeletedNoteRecord>;\n purgeDeletedNote: (note: DeletedNoteRecord) => Promise<void>;\n purgeExpiredDeletedNotes: (before: Date, limit: number) => Promise<number>;\n restoreDeletedNote: (note: DeletedNoteRecord) => Promise<RestoredNoteRecord>;\n}\n\nconst buildTrashedNoteContentPreview = (content: string) => {\n const text = extractVisibleSearchTextFromContent(content);\n\n if (text.length <= TRASHED_NOTE_CONTENT_PREVIEW_MAX_LENGTH) {\n return text;\n }\n\n return `${text.slice(0, TRASHED_NOTE_CONTENT_PREVIEW_MAX_LENGTH).trimEnd()}…`;\n};\n\nconst serializeTrashedNote = (note: DeletedNoteRecord): TrashedNoteSummary => {\n return {\n id: String(note.id),\n title: note.title,\n createdAt: note.createdAt.toISOString(),\n updatedAt: note.updatedAt.toISOString(),\n deletedAt: note.deletedAt.toISOString(),\n contentPreview: buildTrashedNoteContentPreview(note.content),\n pinned: note.pinned,\n order: note.order,\n layout: note.layout,\n tagNames: note.tags.map((tag) => tag.name),\n };\n};\n\nconst restoreTagIdsInContent = (content: string, tagIdByName: Map<string, number>) => {\n const rewriteNodes = (nodes: BlockNoteNode[]): BlockNoteNode[] => {\n return nodes.map((node) => ({\n ...node,\n content: node.content?.map((contentNode) => {\n if (contentNode.type !== 'tag') {\n return contentNode;\n }\n\n const tagName = typeof contentNode.props?.tag === 'string' ? contentNode.props.tag : null;\n const restoredTagId = tagName ? tagIdByName.get(tagName) : null;\n\n if (!restoredTagId) {\n return contentNode;\n }\n\n return {\n ...contentNode,\n props: {\n ...contentNode.props,\n id: String(restoredTagId),\n },\n };\n }),\n children: node.children ? rewriteNodes(node.children) : node.children,\n }));\n };\n\n try {\n const parsed = JSON.parse(content) as BlockNoteNode[];\n return JSON.stringify(rewriteNodes(parsed));\n } catch {\n return content;\n }\n};\n\nexport const createNoteTrashService = (deps: NoteTrashServiceDeps) => ({\n listTrashedNotes: async (input?: { limit?: number; offset?: number }): Promise<TrashedNotesResult> => {\n await deps.purgeExpiredDeletedNotes(createRetentionCutoff(TRASH_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n\n const limit = Math.max(1, Number(input?.limit ?? 25));\n const offset = Math.max(0, Number(input?.offset ?? 0));\n const [totalCount, notes] = await Promise.all([deps.countDeletedNotes(), deps.listDeletedNotes(offset, limit)]);\n\n return {\n totalCount,\n notes: notes.map(serializeTrashedNote),\n };\n },\n\n trashNoteById: async (id: number): Promise<TrashedNoteSummary | null> => {\n await deps.purgeExpiredDeletedNotes(createRetentionCutoff(TRASH_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n\n const note = await deps.findLiveNote(id);\n\n if (!note) {\n return null;\n }\n\n const trashedNote = await deps.moveNoteToTrash(note);\n return serializeTrashedNote(trashedNote);\n },\n\n getNoteById: async (id: number): Promise<TrashedNoteDetail | null> => {\n await deps.purgeExpiredDeletedNotes(createRetentionCutoff(TRASH_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n\n const deletedNote = await deps.findDeletedNote(id);\n\n if (!deletedNote) {\n return null;\n }\n\n const { blocksToMarkdown } = await import('~/modules/blocknote.js');\n\n return {\n ...serializeTrashedNote(deletedNote),\n contentAsMarkdown: await blocksToMarkdown(deletedNote.content),\n };\n },\n\n restoreNoteById: async (id: number) => {\n await deps.purgeExpiredDeletedNotes(createRetentionCutoff(TRASH_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n\n const deletedNote = await deps.findDeletedNote(id);\n\n if (!deletedNote) {\n return null;\n }\n\n if (await deps.liveNoteExists(id)) {\n throw new NoteRestoreConflictError();\n }\n\n return deps.restoreDeletedNote(deletedNote);\n },\n\n purgeNoteById: async (id: number): Promise<TrashedNoteSummary | null> => {\n await deps.purgeExpiredDeletedNotes(createRetentionCutoff(TRASH_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n\n const deletedNote = await deps.findDeletedNote(id);\n\n if (!deletedNote) {\n return null;\n }\n\n const summary = serializeTrashedNote(deletedNote);\n await deps.purgeDeletedNote(deletedNote);\n return summary;\n },\n});\n\nconst includeDeletedNote = {\n reminders: { orderBy: { reminderDate: 'asc' as const } },\n tags: { orderBy: { name: 'asc' as const } },\n properties: { orderBy: { key: 'asc' as const } },\n};\n\nconst defaultPurgeExpiredDeletedNotes = async (before: Date, limit: number) => {\n const expiredNotes = await models.deletedNote.findMany({\n where: { deletedAt: { lt: before } },\n orderBy: { deletedAt: 'asc' },\n take: limit,\n select: { id: true },\n });\n\n if (expiredNotes.length === 0) {\n return 0;\n }\n\n const deleted = await models.deletedNote.deleteMany({ where: { id: { in: expiredNotes.map((note) => note.id) } } });\n\n return deleted.count;\n};\n\nconst noteTrashService = createNoteTrashService({\n countDeletedNotes: async () => models.deletedNote.count(),\n findDeletedNote: async (id) => {\n return models.deletedNote.findUnique({\n where: { id },\n include: includeDeletedNote,\n });\n },\n findLiveNote: async (id) => {\n return models.note.findUnique({\n where: { id },\n include: {\n reminders: { orderBy: { reminderDate: 'asc' } },\n tags: { orderBy: { name: 'asc' } },\n properties: {\n orderBy: { definition: { key: 'asc' } },\n include: { definition: true, option: true },\n },\n },\n });\n },\n listDeletedNotes: async (skip, take) => {\n return models.deletedNote.findMany({\n skip,\n take,\n orderBy: { deletedAt: 'desc' },\n include: includeDeletedNote,\n });\n },\n liveNoteExists: async (id) => {\n const note = await models.note.findUnique({\n where: { id },\n select: { id: true },\n });\n return Boolean(note);\n },\n purgeExpiredDeletedNotes: defaultPurgeExpiredDeletedNotes,\n purgeDeletedNote: async (deletedNote) => {\n await models.deletedNote.delete({ where: { id: deletedNote.id } });\n },\n moveNoteToTrash: async (note) => {\n return models.$transaction(async (tx) => {\n await tx.deletedNote.create({\n data: {\n id: note.id,\n title: note.title,\n content: note.content,\n createdAt: note.createdAt,\n updatedAt: note.updatedAt,\n pinned: note.pinned,\n order: note.order,\n layout: note.layout,\n tags: { create: note.tags.map((tag) => ({ name: tag.name })) },\n reminders: {\n create: note.reminders.map((reminder) => ({\n originalId: reminder.id,\n reminderDate: reminder.reminderDate,\n completed: reminder.completed,\n priority: reminder.priority,\n content: reminder.content,\n createdAt: reminder.createdAt,\n updatedAt: reminder.updatedAt,\n })),\n },\n properties: {\n create: (note.properties ?? []).map((property) => ({\n key: property.definition.key,\n name: property.definition.name,\n valueType: property.definition.valueType,\n textValue: property.textValue,\n textValueNormalized: property.textValueNormalized,\n numberValue: property.numberValue,\n dateValue: property.dateValue,\n boolValue: property.boolValue,\n optionValue: property.option?.value ?? null,\n optionLabel: property.option?.label ?? null,\n optionColor: property.option?.color ?? null,\n createdAt: property.createdAt,\n updatedAt: property.updatedAt,\n })),\n },\n },\n });\n\n await tx.note.delete({ where: { id: note.id } });\n\n if (note.tags.length > 0) {\n await tx.tag.deleteMany({\n where: {\n id: { in: note.tags.map((tag) => tag.id) },\n notes: { none: {} },\n },\n });\n }\n\n return tx.deletedNote.findUniqueOrThrow({\n where: { id: note.id },\n include: includeDeletedNote,\n });\n });\n },\n restoreDeletedNote: async (deletedNote) => {\n return models.$transaction(async (tx) => {\n const tagNames = Array.from(new Set(deletedNote.tags.map((tag) => tag.name).filter(Boolean)));\n\n if (tagNames.length > 0) {\n const existingTags = await tx.tag.findMany({\n where: { name: { in: tagNames } },\n select: { name: true },\n });\n const existingTagNames = new Set(existingTags.map((tag) => tag.name));\n const missingTagNames = tagNames.filter((tagName) => !existingTagNames.has(tagName));\n\n for (const tagName of missingTagNames) {\n await tx.tag.create({ data: { name: tagName } });\n }\n }\n\n const restoreTagIds =\n tagNames.length > 0\n ? await tx.tag.findMany({\n where: { name: { in: tagNames } },\n select: {\n id: true,\n name: true,\n },\n })\n : [];\n\n const restoredContent =\n restoreTagIds.length > 0\n ? restoreTagIdsInContent(\n deletedNote.content,\n new Map(restoreTagIds.map((tag) => [tag.name, tag.id])),\n )\n : deletedNote.content;\n\n const note = await tx.note.create({\n data: {\n id: deletedNote.id,\n title: deletedNote.title,\n content: restoredContent,\n ...buildNoteSearchProjection({\n title: deletedNote.title,\n content: restoredContent,\n }),\n createdAt: deletedNote.createdAt,\n updatedAt: deletedNote.updatedAt,\n pinned: deletedNote.pinned,\n order: deletedNote.order,\n layout: deletedNote.layout,\n ...(restoreTagIds.length > 0\n ? { tags: { connect: restoreTagIds.map((tag) => ({ id: tag.id })) } }\n : {}),\n ...(deletedNote.reminders.length > 0\n ? {\n reminders: {\n create: deletedNote.reminders.map((reminder) => ({\n reminderDate: reminder.reminderDate,\n completed: reminder.completed,\n priority: reminder.priority,\n content: reminder.content,\n createdAt: reminder.createdAt,\n updatedAt: reminder.updatedAt,\n })),\n },\n }\n : {}),\n },\n });\n\n for (const property of deletedNote.properties ?? []) {\n const definition = await tx.propertyDefinition.upsert({\n where: { key: property.key },\n create: {\n key: property.key,\n name: property.name,\n valueType: property.valueType,\n },\n update: {\n name: property.name,\n valueType: property.valueType,\n },\n });\n\n const option =\n property.valueType === 'select' && property.optionValue\n ? await tx.propertyOption.upsert({\n where: {\n propertyDefinitionId_value: {\n propertyDefinitionId: definition.id,\n value: property.optionValue,\n },\n },\n create: {\n propertyDefinitionId: definition.id,\n value: property.optionValue,\n label: property.optionLabel ?? property.optionValue,\n color: property.optionColor,\n },\n update: {\n label: property.optionLabel ?? property.optionValue,\n color: property.optionColor,\n },\n })\n : null;\n\n await tx.noteProperty.create({\n data: {\n noteId: note.id,\n propertyDefinitionId: definition.id,\n optionId: option?.id ?? null,\n textValue: property.textValue,\n textValueNormalized: property.textValueNormalized,\n numberValue: property.numberValue,\n dateValue: property.dateValue,\n boolValue: property.boolValue,\n createdAt: property.createdAt,\n updatedAt: property.updatedAt,\n },\n });\n }\n\n await tx.deletedNote.delete({ where: { id: deletedNote.id } });\n\n return note;\n });\n },\n});\n\nexport const listTrashedNotes = noteTrashService.listTrashedNotes;\nexport const getTrashedNoteById = noteTrashService.getNoteById;\nexport const trashNoteById = noteTrashService.trashNoteById;\nexport const restoreTrashedNoteById = noteTrashService.restoreNoteById;\nexport const purgeTrashedNoteById = noteTrashService.purgeNoteById;\nexport const purgeExpiredTrashedNotes = async () => {\n return defaultPurgeExpiredDeletedNotes(createRetentionCutoff(TRASH_RETENTION_DAYS), RECOVERY_CLEANUP_BATCH_LIMIT);\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/note/services/write-conflict.ts"],"sourcesContent":["export const NOTE_UPDATE_CONFLICT_CODE = 'NOTE_UPDATE_CONFLICT';\nexport const INVALID_NOTE_VERSION_CODE = 'INVALID_NOTE_VERSION';\nexport const MISSING_NOTE_VERSION_CODE = 'MISSING_NOTE_VERSION';\n\nexport class InvalidNoteVersionError extends Error {\n code = INVALID_NOTE_VERSION_CODE;\n\n constructor() {\n super('Invalid note version.');\n this.name = 'InvalidNoteVersionError';\n }\n}\n\nexport class MissingNoteVersionError extends Error {\n code = MISSING_NOTE_VERSION_CODE;\n\n constructor() {\n super('Expected note update time is required for this write.');\n this.name = 'MissingNoteVersionError';\n }\n}\n\nexport class NoteVersionConflictError extends Error {\n code = NOTE_UPDATE_CONFLICT_CODE;\n currentUpdatedAt: string;\n expectedUpdatedAt: string;\n\n constructor(input: { currentUpdatedAt: string | number; expectedUpdatedAt: string | number }) {\n super('This note changed elsewhere. Reload the latest version before saving.');\n this.name = 'NoteVersionConflictError';\n this.currentUpdatedAt = String(input.currentUpdatedAt);\n this.expectedUpdatedAt = String(input.expectedUpdatedAt);\n }\n}\n\nexport const parseNoteVersion = (value?: string | null) => {\n if (value === undefined || value === null || value === '') {\n return null;\n }\n\n const timestamp = /^\\d+$/.test(value) ? Number(value) : Date.parse(value);\n\n if (!Number.isFinite(timestamp)) {\n throw new InvalidNoteVersionError();\n }\n\n return timestamp;\n};\n\nexport const createNoteVersionConflictError = ({\n expectedUpdatedAt,\n currentUpdatedAt,\n}: {\n expectedUpdatedAt: string | number;\n currentUpdatedAt: string | number;\n}) => {\n return new NoteVersionConflictError({\n expectedUpdatedAt,\n currentUpdatedAt,\n });\n};\n\nexport const assertExpectedNoteVersion = ({\n expectedUpdatedAt,\n currentUpdatedAt,\n}: {\n expectedUpdatedAt?: string | null;\n currentUpdatedAt: Date;\n}) => {\n const expectedTimestamp = parseNoteVersion(expectedUpdatedAt);\n\n if (expectedTimestamp === null) {\n return;\n }\n\n const currentTimestamp = currentUpdatedAt.getTime();\n\n if (expectedTimestamp !== currentTimestamp) {\n throw createNoteVersionConflictError({\n expectedUpdatedAt: expectedTimestamp,\n currentUpdatedAt: currentTimestamp,\n });\n }\n};\n\nexport const isNoteVersionConflictError = (error: unknown): error is NoteVersionConflictError => {\n return error instanceof NoteVersionConflictError;\n};\n\nexport const isInvalidNoteVersionError = (error: unknown): error is InvalidNoteVersionError => {\n return error instanceof InvalidNoteVersionError;\n};\n\nexport const isMissingNoteVersionError = (error: unknown): error is MissingNoteVersionError => {\n return error instanceof MissingNoteVersionError;\n};\n"],"mappings":"AAAO,MAAM,4BAA4B;AAClC,MAAM,4BAA4B;AAClC,MAAM,4BAA4B;AAElC,MAAM,gCAAgC,MAAM;AAAA,EAC/C,OAAO;AAAA,EAEP,cAAc;AACV,UAAM,uBAAuB;AAC7B,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,MAAM,gCAAgC,MAAM;AAAA,EAC/C,OAAO;AAAA,EAEP,cAAc;AACV,UAAM,uDAAuD;AAC7D,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,MAAM,iCAAiC,MAAM;AAAA,EAChD,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EAEA,YAAY,OAAkF;AAC1F,UAAM,uEAAuE;AAC7E,SAAK,OAAO;AACZ,SAAK,mBAAmB,OAAO,MAAM,gBAAgB;AACrD,SAAK,oBAAoB,OAAO,MAAM,iBAAiB;AAAA,EAC3D;AACJ;AAEO,MAAM,mBAAmB,CAAC,UAA0B;AACvD,MAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AACvD,WAAO;AAAA,EACX;AAEA,QAAM,YAAY,QAAQ,KAAK,KAAK,IAAI,OAAO,KAAK,IAAI,KAAK,MAAM,KAAK;AAExE,MAAI,CAAC,OAAO,SAAS,SAAS,GAAG;AAC7B,UAAM,IAAI,wBAAwB;AAAA,EACtC;AAEA,SAAO;AACX;AAEO,MAAM,iCAAiC,CAAC;AAAA,EAC3C;AAAA,EACA;AACJ,MAGM;AACF,SAAO,IAAI,yBAAyB;AAAA,IAChC;AAAA,IACA;AAAA,EACJ,CAAC;AACL;AAEO,MAAM,4BAA4B,CAAC;AAAA,EACtC;AAAA,EACA;AACJ,MAGM;AACF,QAAM,oBAAoB,iBAAiB,iBAAiB;AAE5D,MAAI,sBAAsB,MAAM;AAC5B;AAAA,EACJ;AAEA,QAAM,mBAAmB,iBAAiB,QAAQ;AAElD,MAAI,sBAAsB,kBAAkB;AACxC,UAAM,+BAA+B;AAAA,MACjC,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,IACtB,CAAC;AAAA,EACL;AACJ;AAEO,MAAM,6BAA6B,CAAC,UAAsD;AAC7F,SAAO,iBAAiB;AAC5B;AAEO,MAAM,4BAA4B,CAAC,UAAqD;AAC3F,SAAO,iBAAiB;AAC5B;AAEO,MAAM,4BAA4B,CAAC,UAAqD;AAC3F,SAAO,iBAAiB;AAC5B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/note/services/write.ts"],"sourcesContent":["import models, { type NoteLayout, Prisma } from '~/models.js';\nimport { buildNoteSearchProjection } from './search.js';\nimport { captureNoteBaseline } from './snapshot.js';\nimport { createNoteVersionConflictError, MissingNoteVersionError, parseNoteVersion } from './write-conflict.js';\n\nexport interface NoteWriteRecord {\n id: number;\n title: string;\n content: string;\n layout: NoteLayout;\n createdAt: Date;\n updatedAt: Date;\n pinned: boolean;\n order: number;\n}\n\ntype NoteWriteData = {\n title?: string;\n content?: string;\n layout?: NoteLayout;\n tagIds?: number[];\n};\n\ninterface UpdateNoteWithVersionGuardInput {\n id: number;\n data: NoteWriteData;\n editSessionId?: string;\n expectedUpdatedAt?: string;\n snapshotMeta?: string;\n force?: boolean;\n}\n\nexport interface GuardedNoteWriteResult {\n note: NoteWriteRecord;\n snapshot: unknown;\n}\n\ninterface NoteWriteDeps {\n findNoteForWrite: (\n id: number,\n ) => Promise<Pick<NoteWriteRecord, 'title' | 'content' | 'updatedAt' | 'pinned' | 'order' | 'layout'> | null>;\n findNoteVersion: (id: number) => Promise<Pick<NoteWriteRecord, 'updatedAt'> | null>;\n captureBaseline: (input: {\n noteId: number;\n editSessionId?: string;\n meta?: string;\n baseline: Pick<NoteWriteRecord, 'id' | 'title' | 'content' | 'pinned' | 'order' | 'layout'>;\n force?: boolean;\n }) => Promise<unknown>;\n updateNote: (input: {\n where: {\n id: number;\n updatedAt?: Date;\n };\n data: {\n title?: string;\n content?: string;\n layout?: NoteLayout;\n searchableText: string;\n searchableTextVersion: number;\n tags?: {\n set: Array<{ id: number }>;\n };\n };\n }) => Promise<NoteWriteRecord>;\n isRecordNotFoundError: (error: unknown) => boolean;\n}\n\nconst isRecordNotFoundError = (error: unknown) => {\n return error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2025';\n};\n\nexport const createNoteWriteService = (deps: NoteWriteDeps) => {\n const updateNoteWithVersionGuardAndSnapshot = async ({\n id,\n data,\n editSessionId,\n expectedUpdatedAt,\n snapshotMeta,\n force = false,\n }: UpdateNoteWithVersionGuardInput): Promise<GuardedNoteWriteResult | null> => {\n const existingNote = await deps.findNoteForWrite(id);\n\n if (!existingNote) {\n return null;\n }\n\n const expectedTimestamp = parseNoteVersion(expectedUpdatedAt);\n\n if (expectedTimestamp === null && !force) {\n throw new MissingNoteVersionError();\n }\n\n const nextTitle = data.title ?? existingNote.title;\n const nextContent = data.content ?? existingNote.content;\n const where = force\n ? { id }\n : { id, updatedAt: new Date(expectedTimestamp ?? existingNote.updatedAt.getTime()) };\n\n try {\n const updatedNote = await deps.updateNote({\n where,\n data: {\n ...(data.title !== undefined ? { title: data.title } : {}),\n ...(data.content !== undefined ? { content: data.content } : {}),\n ...(data.layout !== undefined ? { layout: data.layout } : {}),\n ...buildNoteSearchProjection({\n title: nextTitle,\n content: nextContent,\n }),\n ...(data.tagIds ? { tags: { set: data.tagIds.map((tagId) => ({ id: tagId })) } } : {}),\n },\n });\n\n const snapshot = await deps.captureBaseline({\n noteId: id,\n baseline: {\n id,\n title: existingNote.title,\n content: existingNote.content,\n pinned: existingNote.pinned,\n order: existingNote.order,\n layout: existingNote.layout,\n },\n ...(editSessionId && !force ? { editSessionId } : {}),\n ...(snapshotMeta ? { meta: snapshotMeta } : {}),\n ...(force ? { force: true } : {}),\n });\n\n return {\n note: updatedNote,\n snapshot,\n };\n } catch (error) {\n if (deps.isRecordNotFoundError(error)) {\n const currentNote = await deps.findNoteVersion(id);\n\n if (!currentNote) {\n return null;\n }\n\n if (expectedTimestamp === null || currentNote.updatedAt.getTime() === expectedTimestamp) {\n throw error;\n }\n\n throw createNoteVersionConflictError({\n expectedUpdatedAt: expectedTimestamp,\n currentUpdatedAt: currentNote.updatedAt.getTime(),\n });\n }\n\n throw error;\n }\n };\n\n return {\n updateNoteWithVersionGuard: async (input: UpdateNoteWithVersionGuardInput): Promise<NoteWriteRecord | null> => {\n const result = await updateNoteWithVersionGuardAndSnapshot(input);\n return result?.note ?? null;\n },\n updateNoteWithVersionGuardAndSnapshot,\n };\n};\n\nconst defaultNoteWriteService = createNoteWriteService({\n findNoteForWrite: (id) =>\n models.note.findUnique({\n where: { id },\n select: {\n title: true,\n content: true,\n updatedAt: true,\n pinned: true,\n order: true,\n layout: true,\n },\n }),\n findNoteVersion: (id) =>\n models.note.findUnique({\n where: { id },\n select: {\n updatedAt: true,\n },\n }),\n captureBaseline: captureNoteBaseline,\n updateNote: ({ where, data }) =>\n models.note.update({\n where,\n data,\n }),\n isRecordNotFoundError,\n});\n\nexport const updateNoteWithVersionGuard = async (input: UpdateNoteWithVersionGuardInput) => {\n return defaultNoteWriteService.updateNoteWithVersionGuard(input);\n};\n\nexport const updateNoteWithVersionGuardAndSnapshot = async (input: UpdateNoteWithVersionGuardInput) => {\n return defaultNoteWriteService.updateNoteWithVersionGuardAndSnapshot(input);\n};\n"],"mappings":"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","names":["updateNoteWithVersionGuardAndSnapshot"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/placeholder/graphql/index.ts"],"sourcesContent":["export { placeholderFieldResolvers } from './placeholder.field.resolver.js';\nexport {\n createCreatePlaceholderMutationResolver,\n createDeletePlaceholderMutationResolver,\n createUpdatePlaceholderMutationResolver,\n placeholderMutationResolvers,\n} from './placeholder.mutation.resolver.js';\nexport {\n createAllPlaceholdersQueryResolver,\n createPlaceholderQueryResolver,\n placeholderQueryResolvers,\n} from './placeholder.query.resolver.js';\nexport { placeholderResolvers } from './placeholder.resolver.js';\nexport { placeholderTypeDefs } from './placeholder.type-defs.js';\n"],"mappings":"AAAA,SAAS,iCAAiC;AAC1C;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AACP;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,OACG;AACP,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/placeholder/graphql/placeholder.field.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\n\ntype PlaceholderFieldResolvers = NonNullable<IResolvers['Placeholder']>;\n\nexport const placeholderFieldResolvers: PlaceholderFieldResolvers = {};\n"],"mappings":"AAIO,MAAM,4BAAuD,CAAC;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/placeholder/graphql/placeholder.mutation.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport models from '~/models.js';\n\ntype PlaceholderMutationResolvers = NonNullable<IResolvers['Mutation']>;\ntype PlaceholderRecord = Awaited<ReturnType<typeof models.placeholder.findFirst>>;\n\ninterface CreatePlaceholderArgs {\n name: string;\n template: string;\n replacement?: string;\n}\n\ninterface UpdatePlaceholderArgs {\n id: string | number;\n name?: string;\n template?: string;\n replacement?: string;\n}\n\ninterface PlaceholderMutationDeps {\n createPlaceholder: (input: CreatePlaceholderArgs) => Promise<unknown>;\n deletePlaceholder: (id: number) => Promise<void>;\n findPlaceholderById: (id: number) => Promise<PlaceholderRecord>;\n updatePlaceholder: (input: { id: number; name?: string; template?: string; replacement?: string }) => Promise<void>;\n}\n\nexport const createCreatePlaceholderMutationResolver = (\n deps: Pick<PlaceholderMutationDeps, 'createPlaceholder'> = {\n createPlaceholder: async (input) =>\n models.placeholder.create({\n data: {\n name: input.name,\n template: input.template,\n replacement: input.replacement as string,\n },\n }),\n },\n) => {\n return async (_: unknown, { name, template, replacement }: CreatePlaceholderArgs) => {\n return deps.createPlaceholder({\n name,\n template,\n replacement,\n });\n };\n};\n\nexport const createUpdatePlaceholderMutationResolver = (\n deps: Pick<PlaceholderMutationDeps, 'findPlaceholderById' | 'updatePlaceholder'> = {\n findPlaceholderById: async (id) => models.placeholder.findFirst({ where: { id } }),\n updatePlaceholder: async (input) => {\n await models.placeholder.update({\n where: { id: input.id },\n data: {\n name: input.name,\n template: input.template,\n replacement: input.replacement,\n },\n });\n },\n },\n) => {\n return async (_: unknown, { id, name, template, replacement }: UpdatePlaceholderArgs) => {\n const placeholder = await deps.findPlaceholderById(Number(id));\n\n if (!placeholder) {\n throw new Error('Placeholder not found');\n }\n\n await deps.updatePlaceholder({\n id: Number(id),\n name,\n template,\n replacement,\n });\n\n return placeholder;\n };\n};\n\nexport const createDeletePlaceholderMutationResolver = (\n deps: Pick<PlaceholderMutationDeps, 'findPlaceholderById' | 'deletePlaceholder'> = {\n findPlaceholderById: async (id) => models.placeholder.findFirst({ where: { id } }),\n deletePlaceholder: async (id) => {\n await models.placeholder.delete({ where: { id } });\n },\n },\n) => {\n return async (_: unknown, { id }: { id: string | number }) => {\n const placeholder = await deps.findPlaceholderById(Number(id));\n\n if (!placeholder) {\n return false;\n }\n\n await deps.deletePlaceholder(Number(id));\n return true;\n };\n};\n\nexport const placeholderMutationResolvers: PlaceholderMutationResolvers = {\n createPlaceholder: createCreatePlaceholderMutationResolver(),\n updatePlaceholder: createUpdatePlaceholderMutationResolver(),\n deletePlaceholder: createDeletePlaceholderMutationResolver(),\n};\n"],"mappings":"AACA,OAAO,YAAY;AAyBZ,MAAM,0CAA0C,CACnD,OAA2D;AAAA,EACvD,mBAAmB,OAAO,UACtB,OAAO,YAAY,OAAO;AAAA,IACtB,MAAM;AAAA,MACF,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM;AAAA,MAChB,aAAa,MAAM;AAAA,IACvB;AAAA,EACJ,CAAC;AACT,MACC;AACD,SAAO,OAAO,GAAY,EAAE,MAAM,UAAU,YAAY,MAA6B;AACjF,WAAO,KAAK,kBAAkB;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,IACJ,CAAC;AAAA,EACL;AACJ;AAEO,MAAM,0CAA0C,CACnD,OAAmF;AAAA,EAC/E,qBAAqB,OAAO,OAAO,OAAO,YAAY,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAAA,EACjF,mBAAmB,OAAO,UAAU;AAChC,UAAM,OAAO,YAAY,OAAO;AAAA,MAC5B,OAAO,EAAE,IAAI,MAAM,GAAG;AAAA,MACtB,MAAM;AAAA,QACF,MAAM,MAAM;AAAA,QACZ,UAAU,MAAM;AAAA,QAChB,aAAa,MAAM;AAAA,MACvB;AAAA,IACJ,CAAC;AAAA,EACL;AACJ,MACC;AACD,SAAO,OAAO,GAAY,EAAE,IAAI,MAAM,UAAU,YAAY,MAA6B;AACrF,UAAM,cAAc,MAAM,KAAK,oBAAoB,OAAO,EAAE,CAAC;AAE7D,QAAI,CAAC,aAAa;AACd,YAAM,IAAI,MAAM,uBAAuB;AAAA,IAC3C;AAEA,UAAM,KAAK,kBAAkB;AAAA,MACzB,IAAI,OAAO,EAAE;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACJ,CAAC;AAED,WAAO;AAAA,EACX;AACJ;AAEO,MAAM,0CAA0C,CACnD,OAAmF;AAAA,EAC/E,qBAAqB,OAAO,OAAO,OAAO,YAAY,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAAA,EACjF,mBAAmB,OAAO,OAAO;AAC7B,UAAM,OAAO,YAAY,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAAA,EACrD;AACJ,MACC;AACD,SAAO,OAAO,GAAY,EAAE,GAAG,MAA+B;AAC1D,UAAM,cAAc,MAAM,KAAK,oBAAoB,OAAO,EAAE,CAAC;AAE7D,QAAI,CAAC,aAAa;AACd,aAAO;AAAA,IACX;AAEA,UAAM,KAAK,kBAAkB,OAAO,EAAE,CAAC;AACvC,WAAO;AAAA,EACX;AACJ;AAEO,MAAM,+BAA6D;AAAA,EACtE,mBAAmB,wCAAwC;AAAA,EAC3D,mBAAmB,wCAAwC;AAAA,EAC3D,mBAAmB,wCAAwC;AAC/D;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/placeholder/graphql/placeholder.query.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport models from '~/models.js';\nimport type { Pagination, SearchFilter } from '~/types/index.js';\n\ntype PlaceholderQueryResolvers = NonNullable<IResolvers['Query']>;\n\ninterface PlaceholderQueryDeps {\n countPlaceholders: () => Promise<number>;\n findPlaceholderById: (id: number) => Promise<unknown>;\n findPlaceholders: (input: {\n where?: { name: { contains: string } };\n take?: number;\n skip?: number;\n }) => Promise<unknown[]>;\n}\n\nexport const createAllPlaceholdersQueryResolver = (\n deps: PlaceholderQueryDeps = {\n countPlaceholders: async () => models.placeholder.count(),\n findPlaceholderById: async (id) => models.placeholder.findFirst({ where: { id } }),\n findPlaceholders: async (input) => models.placeholder.findMany(input),\n },\n) => {\n return async (\n _: unknown,\n { searchFilter, pagination }: { searchFilter?: SearchFilter; pagination?: Pagination },\n ) => {\n const placeholders = await deps.findPlaceholders({\n where: searchFilter?.query ? { name: { contains: searchFilter.query } } : undefined,\n take: pagination?.limit,\n skip: pagination?.offset,\n });\n\n const totalCount = await deps.countPlaceholders();\n\n return {\n totalCount,\n placeholders,\n };\n };\n};\n\nexport const createPlaceholderQueryResolver = (\n deps: Pick<PlaceholderQueryDeps, 'findPlaceholderById'> = {\n findPlaceholderById: async (id) => models.placeholder.findFirst({ where: { id } }),\n },\n) => {\n return async (_: unknown, { id }: { id: string | number }) => {\n return deps.findPlaceholderById(Number(id));\n };\n};\n\nexport const placeholderQueryResolvers: PlaceholderQueryResolvers = {\n allPlaceholders: createAllPlaceholdersQueryResolver(),\n placeholder: createPlaceholderQueryResolver(),\n};\n"],"mappings":"AACA,OAAO,YAAY;AAeZ,MAAM,qCAAqC,CAC9C,OAA6B;AAAA,EACzB,mBAAmB,YAAY,OAAO,YAAY,MAAM;AAAA,EACxD,qBAAqB,OAAO,OAAO,OAAO,YAAY,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAAA,EACjF,kBAAkB,OAAO,UAAU,OAAO,YAAY,SAAS,KAAK;AACxE,MACC;AACD,SAAO,OACH,GACA,EAAE,cAAc,WAAW,MAC1B;AACD,UAAM,eAAe,MAAM,KAAK,iBAAiB;AAAA,MAC7C,OAAO,cAAc,QAAQ,EAAE,MAAM,EAAE,UAAU,aAAa,MAAM,EAAE,IAAI;AAAA,MAC1E,MAAM,YAAY;AAAA,MAClB,MAAM,YAAY;AAAA,IACtB,CAAC;AAED,UAAM,aAAa,MAAM,KAAK,kBAAkB;AAEhD,WAAO;AAAA,MACH;AAAA,MACA;AAAA,IACJ;AAAA,EACJ;AACJ;AAEO,MAAM,iCAAiC,CAC1C,OAA0D;AAAA,EACtD,qBAAqB,OAAO,OAAO,OAAO,YAAY,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AACrF,MACC;AACD,SAAO,OAAO,GAAY,EAAE,GAAG,MAA+B;AAC1D,WAAO,KAAK,oBAAoB,OAAO,EAAE,CAAC;AAAA,EAC9C;AACJ;AAEO,MAAM,4BAAuD;AAAA,EAChE,iBAAiB,mCAAmC;AAAA,EACpD,aAAa,+BAA+B;AAChD;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/placeholder/graphql/placeholder.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport { placeholderFieldResolvers } from './placeholder.field.resolver.js';\nimport { placeholderMutationResolvers } from './placeholder.mutation.resolver.js';\nimport { placeholderQueryResolvers } from './placeholder.query.resolver.js';\n\nexport const placeholderResolvers: IResolvers = {\n Query: placeholderQueryResolvers,\n Mutation: placeholderMutationResolvers,\n Placeholder: placeholderFieldResolvers,\n};\n"],"mappings":"AACA,SAAS,iCAAiC;AAC1C,SAAS,oCAAoC;AAC7C,SAAS,iCAAiC;AAEnC,MAAM,uBAAmC;AAAA,EAC5C,OAAO;AAAA,EACP,UAAU;AAAA,EACV,aAAa;AACjB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/placeholder/graphql/placeholder.type-defs.ts"],"sourcesContent":["import { gql } from '~/modules/graphql.js';\n\nexport const placeholderType = gql`\n input PaginationInput {\n limit: Int!\n offset: Int!\n }\n\n input SearchFilterInput {\n query: String!\n }\n\n type Placeholder {\n id: ID!\n name: String!\n template: String!\n replacement: String!\n createdAt: String!\n updatedAt: String!\n }\n\n type Placeholders {\n totalCount: Int!\n placeholders: [Placeholder!]!\n }\n`;\n\nexport const placeholderQuery = gql`\n type Query {\n allPlaceholders(searchFilter: SearchFilterInput, pagination: PaginationInput): Placeholders!\n placeholder(id: ID!): Placeholder\n }\n`;\n\nexport const placeholderMutation = gql`\n type Mutation {\n createPlaceholder(name: String!, template: String!, replacement: String): Placeholder!\n updatePlaceholder(id: ID!, name: String, template: String, replacement: String): Placeholder!\n deletePlaceholder(id: ID!): Boolean!\n }\n`;\n\nexport const placeholderTypeDefs = `\n ${placeholderType}\n ${placeholderQuery}\n ${placeholderMutation}\n`;\n"],"mappings":"AAAA,SAAS,WAAW;AAEb,MAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBxB,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAOzB,MAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ5B,MAAM,sBAAsB;AAAA,MAC7B,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,mBAAmB;AAAA;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/reminder/graphql/index.ts"],"sourcesContent":["export { reminderFieldResolvers } from './reminder.field.resolver.js';\nexport {\n createCreateReminderMutationResolver,\n createDeleteReminderMutationResolver,\n createUpdateReminderMutationResolver,\n reminderMutationResolvers,\n} from './reminder.mutation.resolver.js';\nexport {\n createNoteRemindersQueryResolver,\n createUpcomingRemindersQueryResolver,\n reminderQueryResolvers,\n} from './reminder.query.resolver.js';\nexport { reminderResolvers } from './reminder.resolver.js';\nexport { reminderTypeDefs } from './reminder.type-defs.js';\n"],"mappings":"AAAA,SAAS,8BAA8B;AACvC;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AACP;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,OACG;AACP,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/reminder/graphql/reminder.field.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport models from '~/models.js';\n\ntype ReminderFieldResolvers = NonNullable<IResolvers['Reminder']>;\n\nexport const reminderFieldResolvers: ReminderFieldResolvers = {\n note: async (reminder: { noteId: number }) => {\n return models.note.findUnique({ where: { id: reminder.noteId } });\n },\n};\n"],"mappings":"AACA,OAAO,YAAY;AAIZ,MAAM,yBAAiD;AAAA,EAC1D,MAAM,OAAO,aAAiC;AAC1C,WAAO,OAAO,KAAK,WAAW,EAAE,OAAO,EAAE,IAAI,SAAS,OAAO,EAAE,CAAC;AAAA,EACpE;AACJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/reminder/graphql/reminder.mutation.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport type { Reminder } from '~/models.js';\nimport models from '~/models.js';\n\ntype ReminderPriority = 'low' | 'medium' | 'high';\n\ninterface ReminderCreateInput {\n noteId: string;\n reminderDate: string;\n priority?: ReminderPriority;\n content?: string;\n}\n\ninterface ReminderUpdateInput {\n id: string;\n reminderDate?: string;\n completed?: boolean;\n priority?: ReminderPriority;\n content?: string;\n}\n\ninterface ReminderMutationDeps {\n createReminder: (data: {\n noteId: number;\n reminderDate: Date;\n completed: boolean;\n priority: ReminderPriority;\n content?: string;\n }) => Promise<unknown>;\n updateReminder: (id: number, data: Partial<Reminder>) => Promise<unknown>;\n deleteReminder: (id: number) => Promise<void>;\n}\n\nexport const createCreateReminderMutationResolver = (\n deps: Pick<ReminderMutationDeps, 'createReminder'> = {\n createReminder: async (data) => models.reminder.create({ data }),\n },\n) => {\n return async (_: unknown, input: ReminderCreateInput) => {\n return deps.createReminder({\n noteId: Number(input.noteId),\n reminderDate: new Date(input.reminderDate),\n completed: false,\n priority: input.priority || 'medium',\n content: input.content,\n });\n };\n};\n\nexport const createUpdateReminderMutationResolver = (\n deps: Pick<ReminderMutationDeps, 'updateReminder'> = {\n updateReminder: async (id, data) =>\n models.reminder.update({\n where: { id },\n data,\n }),\n },\n) => {\n return async (_: unknown, input: ReminderUpdateInput) => {\n const data: Partial<Reminder> = {};\n\n if (input.reminderDate) {\n data.reminderDate = new Date(input.reminderDate);\n }\n\n if (input.completed !== undefined) {\n data.completed = input.completed;\n }\n\n if (input.priority) {\n data.priority = input.priority;\n }\n\n if (input.content !== undefined) {\n data.content = input.content;\n }\n\n return deps.updateReminder(Number(input.id), data);\n };\n};\n\nexport const createDeleteReminderMutationResolver = (\n deps: Pick<ReminderMutationDeps, 'deleteReminder'> = {\n deleteReminder: async (id) => {\n await models.reminder.delete({ where: { id } });\n },\n },\n) => {\n return async (_: unknown, { id }: { id: string }) => {\n await deps.deleteReminder(Number(id));\n return true;\n };\n};\n\ntype ReminderMutationResolvers = NonNullable<IResolvers['Mutation']>;\n\nexport const reminderMutationResolvers: ReminderMutationResolvers = {\n createReminder: createCreateReminderMutationResolver(),\n updateReminder: createUpdateReminderMutationResolver(),\n deleteReminder: createDeleteReminderMutationResolver(),\n};\n"],"mappings":"AAEA,OAAO,YAAY;AA+BZ,MAAM,uCAAuC,CAChD,OAAqD;AAAA,EACjD,gBAAgB,OAAO,SAAS,OAAO,SAAS,OAAO,EAAE,KAAK,CAAC;AACnE,MACC;AACD,SAAO,OAAO,GAAY,UAA+B;AACrD,WAAO,KAAK,eAAe;AAAA,MACvB,QAAQ,OAAO,MAAM,MAAM;AAAA,MAC3B,cAAc,IAAI,KAAK,MAAM,YAAY;AAAA,MACzC,WAAW;AAAA,MACX,UAAU,MAAM,YAAY;AAAA,MAC5B,SAAS,MAAM;AAAA,IACnB,CAAC;AAAA,EACL;AACJ;AAEO,MAAM,uCAAuC,CAChD,OAAqD;AAAA,EACjD,gBAAgB,OAAO,IAAI,SACvB,OAAO,SAAS,OAAO;AAAA,IACnB,OAAO,EAAE,GAAG;AAAA,IACZ;AAAA,EACJ,CAAC;AACT,MACC;AACD,SAAO,OAAO,GAAY,UAA+B;AACrD,UAAM,OAA0B,CAAC;AAEjC,QAAI,MAAM,cAAc;AACpB,WAAK,eAAe,IAAI,KAAK,MAAM,YAAY;AAAA,IACnD;AAEA,QAAI,MAAM,cAAc,QAAW;AAC/B,WAAK,YAAY,MAAM;AAAA,IAC3B;AAEA,QAAI,MAAM,UAAU;AAChB,WAAK,WAAW,MAAM;AAAA,IAC1B;AAEA,QAAI,MAAM,YAAY,QAAW;AAC7B,WAAK,UAAU,MAAM;AAAA,IACzB;AAEA,WAAO,KAAK,eAAe,OAAO,MAAM,EAAE,GAAG,IAAI;AAAA,EACrD;AACJ;AAEO,MAAM,uCAAuC,CAChD,OAAqD;AAAA,EACjD,gBAAgB,OAAO,OAAO;AAC1B,UAAM,OAAO,SAAS,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAAA,EAClD;AACJ,MACC;AACD,SAAO,OAAO,GAAY,EAAE,GAAG,MAAsB;AACjD,UAAM,KAAK,eAAe,OAAO,EAAE,CAAC;AACpC,WAAO;AAAA,EACX;AACJ;AAIO,MAAM,4BAAuD;AAAA,EAChE,gBAAgB,qCAAqC;AAAA,EACrD,gBAAgB,qCAAqC;AAAA,EACrD,gBAAgB,qCAAqC;AACzD;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/reminder/graphql/reminder.query.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport models from '~/models.js';\nimport type { Pagination } from '~/types/index.js';\n\ninterface ReminderListDeps {\n countReminders: (where: object) => Promise<number>;\n findReminders: (args: {\n where: object;\n orderBy: { reminderDate: 'asc' };\n take?: number;\n skip?: number;\n include?: { note: true };\n }) => Promise<unknown[]>;\n}\n\ntype NoteRemindersResolverDeps = ReminderListDeps;\ntype UpcomingRemindersResolverDeps = ReminderListDeps;\n\nexport const createNoteRemindersQueryResolver = (\n deps: NoteRemindersResolverDeps = {\n countReminders: async (where) => models.reminder.count({ where }),\n findReminders: async (args) => models.reminder.findMany(args),\n },\n) => {\n return async (\n _: unknown,\n {\n noteId,\n pagination = {\n limit: 10,\n offset: 0,\n },\n }: {\n noteId: string;\n pagination: Pagination;\n },\n ) => {\n const where = { noteId: Number(noteId) };\n const [totalCount, reminders] = await Promise.all([\n deps.countReminders(where),\n deps.findReminders({\n where,\n orderBy: { reminderDate: 'asc' },\n take: Number(pagination.limit),\n skip: Number(pagination.offset),\n }),\n ]);\n\n return {\n totalCount,\n reminders,\n };\n };\n};\n\nexport const createUpcomingRemindersQueryResolver = (\n deps: UpcomingRemindersResolverDeps = {\n countReminders: async (where) => models.reminder.count({ where }),\n findReminders: async (args) => models.reminder.findMany(args),\n },\n) => {\n return async (\n _: unknown,\n {\n pagination = {\n limit: 10,\n offset: 0,\n },\n }: {\n pagination: Pagination;\n },\n ) => {\n const where = { completed: false };\n const [totalCount, reminders] = await Promise.all([\n deps.countReminders(where),\n deps.findReminders({\n where,\n orderBy: { reminderDate: 'asc' },\n take: Number(pagination.limit),\n skip: Number(pagination.offset),\n include: { note: true },\n }),\n ]);\n\n return {\n totalCount,\n reminders,\n };\n };\n};\n\ntype ReminderQueryResolvers = NonNullable<IResolvers['Query']>;\n\nexport const reminderQueryResolvers: ReminderQueryResolvers = {\n noteReminders: createNoteRemindersQueryResolver(),\n upcomingReminders: createUpcomingRemindersQueryResolver(),\n remindersInDateRange: async (\n _,\n {\n dateRange,\n }: {\n dateRange: {\n start: string;\n end: string;\n };\n },\n ) => {\n return models.reminder.findMany({\n where: {\n reminderDate: {\n gte: new Date(dateRange.start),\n lt: new Date(dateRange.end),\n },\n },\n orderBy: { reminderDate: 'asc' },\n include: { note: true },\n });\n },\n};\n"],"mappings":"AACA,OAAO,YAAY;AAiBZ,MAAM,mCAAmC,CAC5C,OAAkC;AAAA,EAC9B,gBAAgB,OAAO,UAAU,OAAO,SAAS,MAAM,EAAE,MAAM,CAAC;AAAA,EAChE,eAAe,OAAO,SAAS,OAAO,SAAS,SAAS,IAAI;AAChE,MACC;AACD,SAAO,OACH,GACA;AAAA,IACI;AAAA,IACA,aAAa;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,IACZ;AAAA,EACJ,MAIC;AACD,UAAM,QAAQ,EAAE,QAAQ,OAAO,MAAM,EAAE;AACvC,UAAM,CAAC,YAAY,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC9C,KAAK,eAAe,KAAK;AAAA,MACzB,KAAK,cAAc;AAAA,QACf;AAAA,QACA,SAAS,EAAE,cAAc,MAAM;AAAA,QAC/B,MAAM,OAAO,WAAW,KAAK;AAAA,QAC7B,MAAM,OAAO,WAAW,MAAM;AAAA,MAClC,CAAC;AAAA,IACL,CAAC;AAED,WAAO;AAAA,MACH;AAAA,MACA;AAAA,IACJ;AAAA,EACJ;AACJ;AAEO,MAAM,uCAAuC,CAChD,OAAsC;AAAA,EAClC,gBAAgB,OAAO,UAAU,OAAO,SAAS,MAAM,EAAE,MAAM,CAAC;AAAA,EAChE,eAAe,OAAO,SAAS,OAAO,SAAS,SAAS,IAAI;AAChE,MACC;AACD,SAAO,OACH,GACA;AAAA,IACI,aAAa;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,IACZ;AAAA,EACJ,MAGC;AACD,UAAM,QAAQ,EAAE,WAAW,MAAM;AACjC,UAAM,CAAC,YAAY,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC9C,KAAK,eAAe,KAAK;AAAA,MACzB,KAAK,cAAc;AAAA,QACf;AAAA,QACA,SAAS,EAAE,cAAc,MAAM;AAAA,QAC/B,MAAM,OAAO,WAAW,KAAK;AAAA,QAC7B,MAAM,OAAO,WAAW,MAAM;AAAA,QAC9B,SAAS,EAAE,MAAM,KAAK;AAAA,MAC1B,CAAC;AAAA,IACL,CAAC;AAED,WAAO;AAAA,MACH;AAAA,MACA;AAAA,IACJ;AAAA,EACJ;AACJ;AAIO,MAAM,yBAAiD;AAAA,EAC1D,eAAe,iCAAiC;AAAA,EAChD,mBAAmB,qCAAqC;AAAA,EACxD,sBAAsB,OAClB,GACA;AAAA,IACI;AAAA,EACJ,MAMC;AACD,WAAO,OAAO,SAAS,SAAS;AAAA,MAC5B,OAAO;AAAA,QACH,cAAc;AAAA,UACV,KAAK,IAAI,KAAK,UAAU,KAAK;AAAA,UAC7B,IAAI,IAAI,KAAK,UAAU,GAAG;AAAA,QAC9B;AAAA,MACJ;AAAA,MACA,SAAS,EAAE,cAAc,MAAM;AAAA,MAC/B,SAAS,EAAE,MAAM,KAAK;AAAA,IAC1B,CAAC;AAAA,EACL;AACJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/reminder/graphql/reminder.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport { reminderFieldResolvers } from './reminder.field.resolver.js';\nimport { reminderMutationResolvers } from './reminder.mutation.resolver.js';\nimport { reminderQueryResolvers } from './reminder.query.resolver.js';\n\nexport const reminderResolvers: IResolvers = {\n Query: reminderQueryResolvers,\n Mutation: reminderMutationResolvers,\n Reminder: reminderFieldResolvers,\n};\n"],"mappings":"AACA,SAAS,8BAA8B;AACvC,SAAS,iCAAiC;AAC1C,SAAS,8BAA8B;AAEhC,MAAM,oBAAgC;AAAA,EACzC,OAAO;AAAA,EACP,UAAU;AAAA,EACV,UAAU;AACd;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/reminder/graphql/reminder.type-defs.ts"],"sourcesContent":["import { gql } from '~/modules/graphql.js';\n\nexport const reminderType = gql`\n enum ReminderPriority {\n low\n medium\n high\n }\n\n type Reminder {\n id: ID!\n noteId: Int!\n reminderDate: String!\n completed: Boolean!\n priority: ReminderPriority\n content: String\n createdAt: String!\n updatedAt: String!\n note: Note\n }\n\n type Reminders {\n totalCount: Int!\n reminders: [Reminder!]!\n }\n`;\n\nexport const reminderQuery = gql`\n extend type Query {\n noteReminders(noteId: ID!, pagination: PaginationInput): Reminders!\n upcomingReminders(pagination: PaginationInput): Reminders!\n remindersInDateRange(dateRange: DateRangeInput): [Reminder!]!\n }\n`;\n\nexport const reminderMutation = gql`\n extend type Mutation {\n createReminder(noteId: ID!, reminderDate: String!, priority: ReminderPriority, content: String): Reminder!\n updateReminder(id: ID!, reminderDate: String, completed: Boolean, priority: ReminderPriority, content: String): Reminder!\n deleteReminder(id: ID!): Boolean!\n }\n`;\n\nexport const reminderTypeDefs = `\n ${reminderType}\n ${reminderQuery}\n ${reminderMutation}\n`;\n"],"mappings":"AAAA,SAAS,WAAW;AAEb,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBrB,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQtB,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQzB,MAAM,mBAAmB;AAAA,MAC1B,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,gBAAgB;AAAA;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/tag/graphql/index.ts"],"sourcesContent":["export { tagFieldResolvers } from './tag.field.resolver.js';\nexport { createTagMutationResolver, tagMutationResolvers } from './tag.mutation.resolver.js';\nexport { tagQueryResolvers } from './tag.query.resolver.js';\nexport { tagResolvers } from './tag.resolver.js';\nexport { tagTypeDefs } from './tag.type-defs.js';\n"],"mappings":"AAAA,SAAS,yBAAyB;AAClC,SAAS,2BAA2B,4BAA4B;AAChE,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/tag/graphql/tag.field.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport type { Tag } from '~/models.js';\nimport models from '~/models.js';\n\ntype TagReferenceCountSource =\n | Pick<Tag, 'id'>\n | {\n id: string;\n };\n\ntype TagFieldResolvers = NonNullable<IResolvers['Tag']>;\n\nexport const tagFieldResolvers: TagFieldResolvers = {\n referenceCount: async (tag: TagReferenceCountSource) => {\n return models.note.count({ where: { tags: { some: { id: Number(tag.id) } } } });\n },\n};\n"],"mappings":"AAEA,OAAO,YAAY;AAUZ,MAAM,oBAAuC;AAAA,EAChD,gBAAgB,OAAO,QAAiC;AACpD,WAAO,OAAO,KAAK,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAAA,EAClF;AACJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/tag/graphql/tag.mutation.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport { ensureTagByName } from '~/features/tag/services/organization.js';\n\nexport const createTagMutationResolver = (ensureTag = ensureTagByName) => {\n return async (_: unknown, { name }: { name: string }) => {\n const result = await ensureTag(name);\n\n return result.tag;\n };\n};\n\ntype TagMutationResolvers = NonNullable<IResolvers['Mutation']>;\n\nexport const tagMutationResolvers: TagMutationResolvers = {\n createTag: createTagMutationResolver(),\n};\n"],"mappings":"AACA,SAAS,uBAAuB;AAEzB,MAAM,4BAA4B,CAAC,YAAY,oBAAoB;AACtE,SAAO,OAAO,GAAY,EAAE,KAAK,MAAwB;AACrD,UAAM,SAAS,MAAM,UAAU,IAAI;AAEnC,WAAO,OAAO;AAAA,EAClB;AACJ;AAIO,MAAM,uBAA6C;AAAA,EACtD,WAAW,0BAA0B;AACzC;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/tag/graphql/tag.query.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport type { Prisma } from '~/models.js';\nimport models from '~/models.js';\nimport type { Pagination, SearchFilter } from '~/types/index.js';\n\ntype TagQueryResolvers = NonNullable<IResolvers['Query']>;\n\nexport const tagQueryResolvers: TagQueryResolvers = {\n allTags: async (\n _,\n {\n searchFilter,\n pagination,\n }: {\n searchFilter: SearchFilter;\n pagination: Pagination;\n },\n ) => {\n const where: Prisma.TagWhereInput = {\n name: { contains: searchFilter.query },\n NOT: { notes: { none: {} } },\n };\n const tags = models.tag.findMany({\n skip: pagination.offset,\n take: pagination.limit,\n where,\n orderBy: { notes: { _count: 'desc' } },\n });\n\n return {\n totalCount: await models.tag.count({ where }),\n tags: await tags,\n };\n },\n};\n"],"mappings":"AAEA,OAAO,YAAY;AAKZ,MAAM,oBAAuC;AAAA,EAChD,SAAS,OACL,GACA;AAAA,IACI;AAAA,IACA;AAAA,EACJ,MAIC;AACD,UAAM,QAA8B;AAAA,MAChC,MAAM,EAAE,UAAU,aAAa,MAAM;AAAA,MACrC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE;AAAA,IAC/B;AACA,UAAM,OAAO,OAAO,IAAI,SAAS;AAAA,MAC7B,MAAM,WAAW;AAAA,MACjB,MAAM,WAAW;AAAA,MACjB;AAAA,MACA,SAAS,EAAE,OAAO,EAAE,QAAQ,OAAO,EAAE;AAAA,IACzC,CAAC;AAED,WAAO;AAAA,MACH,YAAY,MAAM,OAAO,IAAI,MAAM,EAAE,MAAM,CAAC;AAAA,MAC5C,MAAM,MAAM;AAAA,IAChB;AAAA,EACJ;AACJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/tag/graphql/tag.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport { tagFieldResolvers } from './tag.field.resolver.js';\nimport { tagMutationResolvers } from './tag.mutation.resolver.js';\nimport { tagQueryResolvers } from './tag.query.resolver.js';\n\nexport const tagResolvers: IResolvers = {\n Query: tagQueryResolvers,\n Mutation: tagMutationResolvers,\n Tag: tagFieldResolvers,\n};\n"],"mappings":"AACA,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,yBAAyB;AAE3B,MAAM,eAA2B;AAAA,EACpC,OAAO;AAAA,EACP,UAAU;AAAA,EACV,KAAK;AACT;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/tag/graphql/tag.type-defs.ts"],"sourcesContent":["import { gql } from '~/modules/graphql.js';\n\nexport const tagType = gql`\n input PaginationInput {\n limit: Int!\n offset: Int!\n }\n\n input SearchFilterInput {\n query: String!\n }\n\n type Tag {\n id: ID!\n name: String!\n createdAt: String!\n updatedAt: String!\n referenceCount: Int!\n }\n\n type Tags {\n totalCount: Int!\n tags: [Tag!]!\n }\n`;\n\nexport const tagQuery = gql`\n type Query {\n allTags(searchFilter: SearchFilterInput, pagination: PaginationInput): Tags!\n }\n`;\n\nexport const tagMutation = gql`\n type Mutation {\n createTag(name: String!): Tag!\n }\n`;\n\nexport const tagTypeDefs = `\n ${tagType}\n ${tagQuery}\n ${tagMutation}\n`;\n"],"mappings":"AAAA,SAAS,WAAW;AAEb,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBhB,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAMjB,MAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAMpB,MAAM,cAAc;AAAA,MACrB,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,WAAW;AAAA;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/tag/http/mcp.ts"],"sourcesContent":["import { ensureTagByName, InvalidTagNameError } from '~/features/tag/services/organization.js';\nimport { createAppError } from '~/modules/error-handler.js';\nimport type { Controller } from '~/types/index.js';\n\nexport const createMcpCreateTagHandler = (ensureTag = ensureTagByName): Controller => {\n return async (req, res) => {\n const name = req.body?.name;\n\n if (typeof name !== 'string') {\n throw createAppError(400, 'INVALID_TAG_NAME', 'A tag name is required.');\n }\n\n try {\n const result = await ensureTag(name);\n res.status(200).json(result).end();\n } catch (error) {\n if (error instanceof InvalidTagNameError) {\n throw createAppError(400, 'INVALID_TAG_NAME', error.message);\n }\n\n throw error;\n }\n };\n};\n"],"mappings":"AAAA,SAAS,iBAAiB,2BAA2B;AACrD,SAAS,sBAAsB;AAGxB,MAAM,4BAA4B,CAAC,YAAY,oBAAgC;AAClF,SAAO,OAAO,KAAK,QAAQ;AACvB,UAAM,OAAO,IAAI,MAAM;AAEvB,QAAI,OAAO,SAAS,UAAU;AAC1B,YAAM,eAAe,KAAK,oBAAoB,yBAAyB;AAAA,IAC3E;AAEA,QAAI;AACA,YAAM,SAAS,MAAM,UAAU,IAAI;AACnC,UAAI,OAAO,GAAG,EAAE,KAAK,MAAM,EAAE,IAAI;AAAA,IACrC,SAAS,OAAO;AACZ,UAAI,iBAAiB,qBAAqB;AACtC,cAAM,eAAe,KAAK,oBAAoB,MAAM,OAAO;AAAA,MAC/D;AAEA,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/tag/services/organization.ts"],"sourcesContent":["import models from '~/models.js';\n\ninterface TagRecord {\n id: number;\n name: string;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface TagOrganizationDeps {\n createTag: (name: string) => Promise<TagRecord>;\n findTagByName: (name: string) => Promise<TagRecord | null>;\n}\n\nexport interface TagOrganizationResult {\n created: boolean;\n normalizedName: string;\n tag: {\n id: string;\n name: string;\n createdAt: string;\n updatedAt: string;\n };\n}\n\nexport class InvalidTagNameError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'InvalidTagNameError';\n }\n}\n\nexport const normalizeTagName = (name: string) => {\n const trimmedName = name.trim();\n\n if (!trimmedName) {\n throw new InvalidTagNameError('A tag name is required.');\n }\n\n const normalizedName = trimmedName.startsWith('@') ? trimmedName : `@${trimmedName}`;\n\n if (normalizedName === '@' || /\\s/.test(normalizedName.slice(1))) {\n throw new InvalidTagNameError('Tag names must be a single token like @project.');\n }\n\n return normalizedName;\n};\n\nconst serializeTag = (tag: TagRecord) => ({\n id: String(tag.id),\n name: tag.name,\n createdAt: tag.createdAt.toISOString(),\n updatedAt: tag.updatedAt.toISOString(),\n});\n\nconst isTagNameUniqueConflict = (error: unknown) => {\n if (typeof error !== 'object' || error === null || !('code' in error)) {\n return false;\n }\n\n if (error.code !== 'P2002') {\n return false;\n }\n\n if (!('meta' in error) || typeof error.meta !== 'object' || error.meta === null) {\n return true;\n }\n\n const rawTarget = 'target' in error.meta ? error.meta.target : null;\n const targets = Array.isArray(rawTarget)\n ? rawTarget.filter((value): value is string => typeof value === 'string')\n : typeof rawTarget === 'string'\n ? [rawTarget]\n : [];\n\n return targets.length === 0 || targets.includes('name');\n};\n\nexport const createTagOrganizationService = (deps: TagOrganizationDeps) => {\n return {\n ensureTag: async (name: string): Promise<TagOrganizationResult> => {\n const normalizedName = normalizeTagName(name);\n const existingTag = await deps.findTagByName(normalizedName);\n\n if (existingTag) {\n return {\n created: false,\n normalizedName,\n tag: serializeTag(existingTag),\n };\n }\n\n let createdTag: TagRecord;\n\n try {\n createdTag = await deps.createTag(normalizedName);\n } catch (error) {\n if (!isTagNameUniqueConflict(error)) {\n throw error;\n }\n\n const conflictedTag = await deps.findTagByName(normalizedName);\n\n if (!conflictedTag) {\n throw error;\n }\n\n return {\n created: false,\n normalizedName,\n tag: serializeTag(conflictedTag),\n };\n }\n\n return {\n created: true,\n normalizedName,\n tag: serializeTag(createdTag),\n };\n },\n };\n};\n\nconst defaultTagOrganizationService = createTagOrganizationService({\n createTag: async (name) => {\n return models.tag.create({ data: { name } });\n },\n findTagByName: async (name) => {\n return models.tag.findFirst({\n where: { name },\n orderBy: { createdAt: 'asc' },\n });\n },\n});\n\nexport const ensureTagByName = async (name: string) => {\n return defaultTagOrganizationService.ensureTag(name);\n};\n"],"mappings":"AAAA,OAAO,YAAY;AAyBZ,MAAM,4BAA4B,MAAM;AAAA,EAC3C,YAAY,SAAiB;AACzB,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,MAAM,mBAAmB,CAAC,SAAiB;AAC9C,QAAM,cAAc,KAAK,KAAK;AAE9B,MAAI,CAAC,aAAa;AACd,UAAM,IAAI,oBAAoB,yBAAyB;AAAA,EAC3D;AAEA,QAAM,iBAAiB,YAAY,WAAW,GAAG,IAAI,cAAc,IAAI,WAAW;AAElF,MAAI,mBAAmB,OAAO,KAAK,KAAK,eAAe,MAAM,CAAC,CAAC,GAAG;AAC9D,UAAM,IAAI,oBAAoB,iDAAiD;AAAA,EACnF;AAEA,SAAO;AACX;AAEA,MAAM,eAAe,CAAC,SAAoB;AAAA,EACtC,IAAI,OAAO,IAAI,EAAE;AAAA,EACjB,MAAM,IAAI;AAAA,EACV,WAAW,IAAI,UAAU,YAAY;AAAA,EACrC,WAAW,IAAI,UAAU,YAAY;AACzC;AAEA,MAAM,0BAA0B,CAAC,UAAmB;AAChD,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,EAAE,UAAU,QAAQ;AACnE,WAAO;AAAA,EACX;AAEA,MAAI,MAAM,SAAS,SAAS;AACxB,WAAO;AAAA,EACX;AAEA,MAAI,EAAE,UAAU,UAAU,OAAO,MAAM,SAAS,YAAY,MAAM,SAAS,MAAM;AAC7E,WAAO;AAAA,EACX;AAEA,QAAM,YAAY,YAAY,MAAM,OAAO,MAAM,KAAK,SAAS;AAC/D,QAAM,UAAU,MAAM,QAAQ,SAAS,IACjC,UAAU,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,IACtE,OAAO,cAAc,WACnB,CAAC,SAAS,IACV,CAAC;AAET,SAAO,QAAQ,WAAW,KAAK,QAAQ,SAAS,MAAM;AAC1D;AAEO,MAAM,+BAA+B,CAAC,SAA8B;AACvE,SAAO;AAAA,IACH,WAAW,OAAO,SAAiD;AAC/D,YAAM,iBAAiB,iBAAiB,IAAI;AAC5C,YAAM,cAAc,MAAM,KAAK,cAAc,cAAc;AAE3D,UAAI,aAAa;AACb,eAAO;AAAA,UACH,SAAS;AAAA,UACT;AAAA,UACA,KAAK,aAAa,WAAW;AAAA,QACjC;AAAA,MACJ;AAEA,UAAI;AAEJ,UAAI;AACA,qBAAa,MAAM,KAAK,UAAU,cAAc;AAAA,MACpD,SAAS,OAAO;AACZ,YAAI,CAAC,wBAAwB,KAAK,GAAG;AACjC,gBAAM;AAAA,QACV;AAEA,cAAM,gBAAgB,MAAM,KAAK,cAAc,cAAc;AAE7D,YAAI,CAAC,eAAe;AAChB,gBAAM;AAAA,QACV;AAEA,eAAO;AAAA,UACH,SAAS;AAAA,UACT;AAAA,UACA,KAAK,aAAa,aAAa;AAAA,QACnC;AAAA,MACJ;AAEA,aAAO;AAAA,QACH,SAAS;AAAA,QACT;AAAA,QACA,KAAK,aAAa,UAAU;AAAA,MAChC;AAAA,IACJ;AAAA,EACJ;AACJ;AAEA,MAAM,gCAAgC,6BAA6B;AAAA,EAC/D,WAAW,OAAO,SAAS;AACvB,WAAO,OAAO,IAAI,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAAA,EAC/C;AAAA,EACA,eAAe,OAAO,SAAS;AAC3B,WAAO,OAAO,IAAI,UAAU;AAAA,MACxB,OAAO,EAAE,KAAK;AAAA,MACd,SAAS,EAAE,WAAW,MAAM;AAAA,IAChC,CAAC;AAAA,EACL;AACJ,CAAC;AAEM,MAAM,kBAAkB,OAAO,SAAiB;AACnD,SAAO,8BAA8B,UAAU,IAAI;AACvD;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/view/graphql/index.ts"],"sourcesContent":["export { viewMutationResolvers } from './view.mutation.resolver.js';\nexport { viewQueryResolvers } from './view.query.resolver.js';\nexport { viewResolvers } from './view.resolver.js';\nexport { viewTypeDefs } from './view.type-defs.js';\n"],"mappings":"AAAA,SAAS,6BAA6B;AACtC,SAAS,0BAA0B;AACnC,SAAS,qBAAqB;AAC9B,SAAS,oBAAoB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/view/graphql/view.mutation.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport {\n createViewSection,\n createViewTab,\n deleteViewSection,\n deleteViewTab,\n reorderViewSections,\n reorderViewTabs,\n setActiveViewTab,\n updateViewSection,\n updateViewTab,\n type ViewSectionInput,\n} from '~/features/view/services/workspace.js';\n\ntype ViewMutationResolvers = NonNullable<IResolvers['Mutation']>;\n\nexport const viewMutationResolvers: ViewMutationResolvers = {\n createViewTab: async (_, { title }: { title: string }) => {\n return createViewTab(title);\n },\n updateViewTab: async (_, { id, title }: { id: string; title: string }) => {\n return updateViewTab(id, title);\n },\n deleteViewTab: async (_, { id }: { id: string }) => {\n return deleteViewTab(id);\n },\n setActiveViewTab: async (_, { id }: { id: string }) => {\n return setActiveViewTab(id);\n },\n reorderViewTabs: async (_, { tabIds }: { tabIds: string[] }) => {\n return reorderViewTabs(tabIds);\n },\n createViewSection: async (\n _,\n {\n tabId,\n input,\n }: {\n tabId: string;\n input: ViewSectionInput;\n },\n ) => {\n return createViewSection(tabId, input);\n },\n updateViewSection: async (\n _,\n {\n id,\n input,\n }: {\n id: string;\n input: ViewSectionInput;\n },\n ) => {\n return updateViewSection(id, input);\n },\n deleteViewSection: async (_, { id }: { id: string }) => {\n return deleteViewSection(id);\n },\n reorderViewSections: async (\n _,\n {\n tabId,\n sectionIds,\n }: {\n tabId: string;\n sectionIds: string[];\n },\n ) => {\n return reorderViewSections(tabId, sectionIds);\n },\n};\n"],"mappings":"AACA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEG;AAIA,MAAM,wBAA+C;AAAA,EACxD,eAAe,OAAO,GAAG,EAAE,MAAM,MAAyB;AACtD,WAAO,cAAc,KAAK;AAAA,EAC9B;AAAA,EACA,eAAe,OAAO,GAAG,EAAE,IAAI,MAAM,MAAqC;AACtE,WAAO,cAAc,IAAI,KAAK;AAAA,EAClC;AAAA,EACA,eAAe,OAAO,GAAG,EAAE,GAAG,MAAsB;AAChD,WAAO,cAAc,EAAE;AAAA,EAC3B;AAAA,EACA,kBAAkB,OAAO,GAAG,EAAE,GAAG,MAAsB;AACnD,WAAO,iBAAiB,EAAE;AAAA,EAC9B;AAAA,EACA,iBAAiB,OAAO,GAAG,EAAE,OAAO,MAA4B;AAC5D,WAAO,gBAAgB,MAAM;AAAA,EACjC;AAAA,EACA,mBAAmB,OACf,GACA;AAAA,IACI;AAAA,IACA;AAAA,EACJ,MAIC;AACD,WAAO,kBAAkB,OAAO,KAAK;AAAA,EACzC;AAAA,EACA,mBAAmB,OACf,GACA;AAAA,IACI;AAAA,IACA;AAAA,EACJ,MAIC;AACD,WAAO,kBAAkB,IAAI,KAAK;AAAA,EACtC;AAAA,EACA,mBAAmB,OAAO,GAAG,EAAE,GAAG,MAAsB;AACpD,WAAO,kBAAkB,EAAE;AAAA,EAC/B;AAAA,EACA,qBAAqB,OACjB,GACA;AAAA,IACI;AAAA,IACA;AAAA,EACJ,MAIC;AACD,WAAO,oBAAoB,OAAO,UAAU;AAAA,EAChD;AACJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/view/graphql/view.query.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport { GraphQLError } from 'graphql';\nimport { InvalidNotePropertyInputError } from '~/features/note/services/properties.js';\nimport {\n getNotesByProperties,\n getViewSectionById,\n getViewSectionNotes,\n getViewWorkspace,\n type ViewNotesQueryInput,\n} from '~/features/view/services/workspace.js';\nimport type { Pagination } from '~/types/index.js';\n\ntype ViewQueryResolvers = NonNullable<IResolvers['Query']>;\n\nexport const viewQueryResolvers: ViewQueryResolvers = {\n viewWorkspace: async () => {\n return getViewWorkspace();\n },\n viewSection: async (_, { id }: { id: string }) => {\n return getViewSectionById(id);\n },\n viewSectionNotes: async (\n _,\n {\n id,\n pagination = {\n limit: 25,\n offset: 0,\n },\n }: {\n id: string;\n pagination: Pagination;\n },\n ) => {\n const sectionNotes = await getViewSectionNotes(id, {\n limit: Number(pagination.limit),\n offset: Number(pagination.offset),\n });\n\n if (!sectionNotes) {\n throw 'NOT FOUND';\n }\n\n return sectionNotes;\n },\n notesByProperties: async (\n _,\n {\n input,\n pagination = {\n limit: 20,\n offset: 0,\n },\n }: {\n input: ViewNotesQueryInput;\n pagination: Pagination;\n },\n ) => {\n try {\n return await getNotesByProperties(input, {\n limit: Number(pagination.limit),\n offset: Number(pagination.offset),\n });\n } catch (error) {\n if (error instanceof InvalidNotePropertyInputError) {\n throw new GraphQLError(error.message, {\n extensions: {\n code: 'INVALID_NOTE_PROPERTY_INPUT',\n },\n });\n }\n\n throw error;\n }\n },\n};\n"],"mappings":"AACA,SAAS,oBAAoB;AAC7B,SAAS,qCAAqC;AAC9C;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEG;AAKA,MAAM,qBAAyC;AAAA,EAClD,eAAe,YAAY;AACvB,WAAO,iBAAiB;AAAA,EAC5B;AAAA,EACA,aAAa,OAAO,GAAG,EAAE,GAAG,MAAsB;AAC9C,WAAO,mBAAmB,EAAE;AAAA,EAChC;AAAA,EACA,kBAAkB,OACd,GACA;AAAA,IACI;AAAA,IACA,aAAa;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,IACZ;AAAA,EACJ,MAIC;AACD,UAAM,eAAe,MAAM,oBAAoB,IAAI;AAAA,MAC/C,OAAO,OAAO,WAAW,KAAK;AAAA,MAC9B,QAAQ,OAAO,WAAW,MAAM;AAAA,IACpC,CAAC;AAED,QAAI,CAAC,cAAc;AACf,YAAM;AAAA,IACV;AAEA,WAAO;AAAA,EACX;AAAA,EACA,mBAAmB,OACf,GACA;AAAA,IACI;AAAA,IACA,aAAa;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,IACZ;AAAA,EACJ,MAIC;AACD,QAAI;AACA,aAAO,MAAM,qBAAqB,OAAO;AAAA,QACrC,OAAO,OAAO,WAAW,KAAK;AAAA,QAC9B,QAAQ,OAAO,WAAW,MAAM;AAAA,MACpC,CAAC;AAAA,IACL,SAAS,OAAO;AACZ,UAAI,iBAAiB,+BAA+B;AAChD,cAAM,IAAI,aAAa,MAAM,SAAS;AAAA,UAClC,YAAY;AAAA,YACR,MAAM;AAAA,UACV;AAAA,QACJ,CAAC;AAAA,MACL;AAEA,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/view/graphql/view.resolver.ts"],"sourcesContent":["import { viewMutationResolvers } from './view.mutation.resolver.js';\nimport { viewQueryResolvers } from './view.query.resolver.js';\n\nexport const viewResolvers = {\n Query: viewQueryResolvers,\n Mutation: viewMutationResolvers,\n};\n"],"mappings":"AAAA,SAAS,6BAA6B;AACtC,SAAS,0BAA0B;AAE5B,MAAM,gBAAgB;AAAA,EACzB,OAAO;AAAA,EACP,UAAU;AACd;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/view/graphql/view.type-defs.ts"],"sourcesContent":["import { gql } from '~/modules/graphql.js';\n\nexport const viewType = gql`\n type ViewWorkspace {\n activeTabId: ID\n tabs: [ViewTab!]!\n }\n\n type ViewTab {\n id: ID!\n title: String!\n order: Int!\n sections: [ViewSection!]!\n }\n\n type ViewSection {\n id: ID!\n tabId: ID!\n title: String!\n displayType: ViewDisplayType!\n displayOptions: ViewDisplayOptions!\n tagNames: [String!]!\n mode: TagMatchMode!\n propertyFilters: [ViewPropertyFilter!]!\n sortBy: ViewSortBy!\n sortOrder: ViewSortOrder!\n limit: Int!\n order: Int!\n }\n\n type ViewPropertyFilter {\n key: String!\n name: String!\n valueType: NotePropertyValueType!\n operator: ViewPropertyFilterOperator!\n value: String\n }\n\n type ViewDisplayOptions {\n tableColumns: [ViewTableColumn!]!\n }\n\n enum ViewDisplayType {\n list\n table\n calendar\n }\n\n enum ViewTableColumn {\n title\n tags\n properties\n createdAt\n updatedAt\n }\n\n enum ViewPropertyFilterOperator {\n equals\n notEquals\n contains\n notContains\n before\n after\n exists\n notExists\n }\n\n enum ViewSortBy {\n updatedAt\n createdAt\n title\n }\n\n enum ViewSortOrder {\n asc\n desc\n }\n\n input ViewPropertyFilterInput {\n key: String!\n valueType: NotePropertyValueType!\n operator: ViewPropertyFilterOperator!\n value: String\n }\n\n input ViewDisplayOptionsInput {\n tableColumns: [ViewTableColumn!]\n }\n\n input ViewSectionInput {\n title: String\n displayType: ViewDisplayType\n displayOptions: ViewDisplayOptionsInput\n tagNames: [String!]\n mode: TagMatchMode\n propertyFilters: [ViewPropertyFilterInput!]\n sortBy: ViewSortBy\n sortOrder: ViewSortOrder\n limit: Int\n }\n\n input NotesByPropertiesInput {\n tagNames: [String!]\n mode: TagMatchMode\n propertyFilters: [ViewPropertyFilterInput!]!\n sortBy: ViewSortBy\n sortOrder: ViewSortOrder\n }\n`;\n\nexport const viewQuery = gql`\n type Query {\n viewWorkspace: ViewWorkspace!\n viewSection(id: ID!): ViewSection\n viewSectionNotes(id: ID!, pagination: PaginationInput): Notes!\n notesByProperties(input: NotesByPropertiesInput!, pagination: PaginationInput): Notes!\n }\n`;\n\nexport const viewMutation = gql`\n type Mutation {\n createViewTab(title: String!): ViewTab!\n updateViewTab(id: ID!, title: String!): ViewTab!\n deleteViewTab(id: ID!): Boolean!\n setActiveViewTab(id: ID!): ViewWorkspace!\n reorderViewTabs(tabIds: [ID!]!): [ViewTab!]!\n createViewSection(tabId: ID!, input: ViewSectionInput!): ViewSection!\n updateViewSection(id: ID!, input: ViewSectionInput!): ViewSection!\n deleteViewSection(id: ID!): Boolean!\n reorderViewSections(tabId: ID!, sectionIds: [ID!]!): [ViewSection!]!\n }\n`;\n\nexport const viewTypeDefs = `\n ${viewType}\n ${viewQuery}\n ${viewMutation}\n`;\n"],"mappings":"AAAA,SAAS,WAAW;AAEb,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4GjB,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASlB,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcrB,MAAM,eAAe;AAAA,MACtB,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/features/view/services/workspace.ts"],"sourcesContent":["import type { Note, Prisma, PropertyValueType } from '@prisma/client';\nimport {\n InvalidNotePropertyInputError,\n normalizePropertyKey,\n normalizeUrlValue,\n} from '~/features/note/services/properties.js';\nimport { buildNoteTagNamesWhere, type NoteTagMatchMode } from '~/features/note/services/tag-filter.js';\nimport models from '~/models.js';\n\nexport type ViewTagMatchMode = NoteTagMatchMode;\nexport type ViewDisplayType = 'list' | 'table' | 'calendar';\nexport type ViewTableColumn = 'title' | 'tags' | 'properties' | 'createdAt' | 'updatedAt';\nexport type ViewPropertyFilterOperator =\n | 'equals'\n | 'notEquals'\n | 'contains'\n | 'notContains'\n | 'before'\n | 'after'\n | 'exists'\n | 'notExists';\nexport type ViewSortBy = 'updatedAt' | 'createdAt' | 'title';\nexport type ViewSortOrder = 'asc' | 'desc';\n\nexport interface ViewDisplayOptionsRecord {\n tableColumns: ViewTableColumn[];\n}\n\nexport interface ViewPropertyFilterRecord {\n key: string;\n name: string;\n valueType: PropertyValueType;\n operator: ViewPropertyFilterOperator;\n value: string | null;\n}\n\nexport interface ViewSectionRecord {\n id: string;\n tabId: string;\n title: string;\n displayType: ViewDisplayType;\n displayOptions: ViewDisplayOptionsRecord;\n tagNames: string[];\n mode: ViewTagMatchMode;\n propertyFilters: ViewPropertyFilterRecord[];\n sortBy: ViewSortBy;\n sortOrder: ViewSortOrder;\n limit: number;\n order: number;\n}\n\nexport interface ViewTabRecord {\n id: string;\n title: string;\n order: number;\n sections: ViewSectionRecord[];\n}\n\nexport interface ViewWorkspaceRecord {\n activeTabId: string | null;\n tabs: ViewTabRecord[];\n}\n\nexport interface ViewSectionInput {\n title?: string;\n displayType?: ViewDisplayType;\n displayOptions?: ViewDisplayOptionsInput | null;\n tagNames?: string[] | null;\n mode?: ViewTagMatchMode;\n propertyFilters?: ViewPropertyFilterInput[] | null;\n sortBy?: ViewSortBy;\n sortOrder?: ViewSortOrder;\n limit?: number;\n}\n\nexport interface ViewNotesQueryInput {\n tagNames?: string[] | null;\n mode?: ViewTagMatchMode;\n propertyFilters?: ViewPropertyFilterInput[] | null;\n sortBy?: ViewSortBy;\n sortOrder?: ViewSortOrder;\n}\n\nexport interface ViewNotesQueryRecord {\n tagNames: string[];\n mode: ViewTagMatchMode;\n propertyFilters: ViewPropertyFilterRecord[];\n sortBy: ViewSortBy;\n sortOrder: ViewSortOrder;\n}\n\nexport interface ViewPropertyFilterInput {\n key: string;\n operator: ViewPropertyFilterOperator;\n value?: string | null;\n valueType?: PropertyValueType | null;\n}\n\nexport interface ViewDisplayOptionsInput {\n tableColumns?: ViewTableColumn[] | null;\n}\n\nexport interface ViewSectionNotesResult {\n totalCount: number;\n notes: Note[];\n}\n\nconst VIEW_WORKSPACE_ID = 1;\n\nexport const DEFAULT_VIEW_SECTION_LIMIT = 5;\nexport const MIN_VIEW_SECTION_LIMIT = 1;\nexport const MAX_VIEW_SECTION_LIMIT = 20;\nexport const DEFAULT_VIEW_NOTES_QUERY_LIMIT = 20;\nexport const MAX_VIEW_NOTES_QUERY_LIMIT = 50;\nconst MAX_VIEW_PROPERTY_FILTERS = 10;\nconst DEFAULT_VIEW_DISPLAY_TYPE: ViewDisplayType = 'list';\nconst DEFAULT_VIEW_SORT_BY: ViewSortBy = 'updatedAt';\nconst DEFAULT_VIEW_SORT_ORDER: ViewSortOrder = 'desc';\nconst DEFAULT_VIEW_TABLE_COLUMNS: ViewTableColumn[] = ['title', 'tags', 'properties', 'createdAt', 'updatedAt'];\n\ntype ViewDbClient = typeof models | Prisma.TransactionClient;\n\nconst orderedViewSectionTagsInclude = {\n tags: {\n orderBy: [{ order: 'asc' }, { createdAt: 'asc' }],\n },\n} satisfies Prisma.ViewSectionInclude;\n\nconst orderedViewTabSectionsInclude = {\n sections: {\n orderBy: [{ order: 'asc' }, { createdAt: 'asc' }],\n include: orderedViewSectionTagsInclude,\n },\n} satisfies Prisma.ViewTabInclude;\n\ntype DbViewSection = Prisma.ViewSectionGetPayload<{\n include: typeof orderedViewSectionTagsInclude;\n}>;\n\ntype DbViewTab = Prisma.ViewTabGetPayload<{\n include: typeof orderedViewTabSectionsInclude;\n}>;\n\nconst normalizeTagName = (value: string) => {\n const trimmedValue = value.trim();\n\n if (!trimmedValue) {\n return '';\n }\n\n if (trimmedValue.startsWith('@')) {\n return trimmedValue;\n }\n\n if (trimmedValue.startsWith('#')) {\n return `@${trimmedValue.slice(1)}`;\n }\n\n return `@${trimmedValue}`;\n};\n\nexport const normalizeViewTagNames = (values: string[]) => {\n const normalizedTagNames = values.flatMap((value) => value.split(','));\n\n return Array.from(new Set(normalizedTagNames.map(normalizeTagName).filter(Boolean)));\n};\n\ninterface StoredViewQuery {\n propertyFilters?: ViewPropertyFilterRecord[];\n sortBy?: ViewSortBy;\n sortOrder?: ViewSortOrder;\n displayOptions?: Partial<ViewDisplayOptionsRecord>;\n}\n\ninterface ParsedStoredViewQuery {\n propertyFilters: ViewPropertyFilterRecord[];\n sortBy: ViewSortBy;\n sortOrder: ViewSortOrder;\n displayOptions: ViewDisplayOptionsRecord;\n}\n\nconst isViewPropertyFilterOperator = (value: unknown): value is ViewPropertyFilterOperator => {\n return (\n value === 'equals' ||\n value === 'notEquals' ||\n value === 'contains' ||\n value === 'notContains' ||\n value === 'before' ||\n value === 'after' ||\n value === 'exists' ||\n value === 'notExists'\n );\n};\n\nconst isPropertyValueType = (value: unknown): value is PropertyValueType => {\n return (\n value === 'text' ||\n value === 'url' ||\n value === 'number' ||\n value === 'date' ||\n value === 'boolean' ||\n value === 'select'\n );\n};\n\nconst isViewTableColumn = (value: unknown): value is ViewTableColumn => {\n return (\n value === 'title' ||\n value === 'tags' ||\n value === 'properties' ||\n value === 'createdAt' ||\n value === 'updatedAt'\n );\n};\n\nconst normalizeViewDisplayType = (value: ViewDisplayType | undefined): ViewDisplayType => {\n if (value === 'table' || value === 'calendar') {\n return value;\n }\n\n return DEFAULT_VIEW_DISPLAY_TYPE;\n};\n\nconst normalizeViewSortBy = (value: ViewSortBy | undefined): ViewSortBy => {\n return value === 'createdAt' || value === 'title' ? value : DEFAULT_VIEW_SORT_BY;\n};\n\nconst normalizeViewSortOrder = (value: ViewSortOrder | undefined): ViewSortOrder => {\n return value === 'asc' ? 'asc' : DEFAULT_VIEW_SORT_ORDER;\n};\n\nexport const normalizeViewTableColumns = (columns: ViewTableColumn[] | null | undefined): ViewTableColumn[] => {\n const normalizedColumns = (columns ?? []).filter(isViewTableColumn);\n const uniqueColumns = Array.from(new Set(normalizedColumns));\n\n if (uniqueColumns.length === 0) {\n return [...DEFAULT_VIEW_TABLE_COLUMNS];\n }\n\n return uniqueColumns.includes('title') ? uniqueColumns : ['title' as const, ...uniqueColumns];\n};\n\nexport const normalizeViewDisplayOptions = (\n options: ViewDisplayOptionsInput | Partial<ViewDisplayOptionsRecord> | null | undefined,\n): ViewDisplayOptionsRecord => {\n return {\n tableColumns: normalizeViewTableColumns(options?.tableColumns),\n };\n};\n\nconst normalizeFilterValue = ({\n value,\n valueType,\n operator,\n}: {\n value?: string | null;\n valueType: PropertyValueType;\n operator: ViewPropertyFilterOperator;\n}) => {\n if (operator === 'exists' || operator === 'notExists') {\n return null;\n }\n\n const normalizedValue = String(value ?? '').trim();\n\n if (!normalizedValue) {\n throw new InvalidNotePropertyInputError('Property filter value is required.');\n }\n\n if (valueType === 'number' && !Number.isFinite(Number(normalizedValue))) {\n throw new InvalidNotePropertyInputError('Number property filter value must be finite.');\n }\n\n if (valueType === 'boolean' && normalizedValue !== 'true' && normalizedValue !== 'false') {\n throw new InvalidNotePropertyInputError('Boolean property filter value must be true or false.');\n }\n\n if (valueType === 'date') {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(normalizedValue)) {\n throw new InvalidNotePropertyInputError('Date property filter values must use YYYY-MM-DD.');\n }\n\n const date = new Date(`${normalizedValue}T00:00:00.000Z`);\n\n if (Number.isNaN(date.getTime()) || date.toISOString().slice(0, 10) !== normalizedValue) {\n throw new InvalidNotePropertyInputError('Date property filter value is invalid.');\n }\n }\n\n if ((operator === 'before' || operator === 'after') && valueType !== 'date' && valueType !== 'number') {\n throw new InvalidNotePropertyInputError('Before and after filters require date or number properties.');\n }\n\n if ((operator === 'contains' || operator === 'notContains') && valueType !== 'text' && valueType !== 'url') {\n throw new InvalidNotePropertyInputError('Contains filters require text or url properties.');\n }\n\n if (valueType === 'url' && operator !== 'contains' && operator !== 'notContains') {\n return normalizeUrlValue(normalizedValue);\n }\n\n return normalizedValue;\n};\n\nexport const normalizeViewPropertyFilters = (filters: ViewPropertyFilterInput[] | null | undefined) => {\n const normalizedFilters = filters ?? [];\n\n if (normalizedFilters.length > MAX_VIEW_PROPERTY_FILTERS) {\n throw new InvalidNotePropertyInputError(`A view can have up to ${MAX_VIEW_PROPERTY_FILTERS} property filters.`);\n }\n\n return normalizedFilters\n .map((filter): ViewPropertyFilterRecord | null => {\n const key = normalizePropertyKey(filter.key);\n const valueType = filter.valueType;\n const operator = filter.operator;\n\n if (!isPropertyValueType(valueType)) {\n throw new InvalidNotePropertyInputError('Property filter value type is required.');\n }\n\n if (!isViewPropertyFilterOperator(operator)) {\n throw new InvalidNotePropertyInputError('Property filter operator is invalid.');\n }\n\n const storedName = (filter as { name?: unknown }).name;\n const name = typeof storedName === 'string' && storedName.trim() ? storedName.trim() : key;\n\n return {\n key,\n name,\n valueType,\n operator,\n value: normalizeFilterValue({\n value: filter.value,\n valueType,\n operator,\n }),\n };\n })\n .filter((filter): filter is ViewPropertyFilterRecord => filter !== null);\n};\n\nconst parseStoredViewQuery = (value: string | null): ParsedStoredViewQuery => {\n if (!value) {\n return {\n propertyFilters: [],\n sortBy: DEFAULT_VIEW_SORT_BY,\n sortOrder: DEFAULT_VIEW_SORT_ORDER,\n displayOptions: normalizeViewDisplayOptions(null),\n };\n }\n\n try {\n const parsed = JSON.parse(value) as Partial<StoredViewQuery>;\n\n return {\n propertyFilters: normalizeViewPropertyFilters(parsed.propertyFilters ?? []),\n sortBy: normalizeViewSortBy(parsed.sortBy),\n sortOrder: normalizeViewSortOrder(parsed.sortOrder),\n displayOptions: normalizeViewDisplayOptions(parsed.displayOptions),\n };\n } catch {\n return {\n propertyFilters: [],\n sortBy: DEFAULT_VIEW_SORT_BY,\n sortOrder: DEFAULT_VIEW_SORT_ORDER,\n displayOptions: normalizeViewDisplayOptions(null),\n };\n }\n};\n\nconst serializeStoredViewQuery = ({ propertyFilters, sortBy, sortOrder, displayOptions }: ParsedStoredViewQuery) => {\n return JSON.stringify({\n propertyFilters,\n sortBy,\n sortOrder,\n displayOptions,\n });\n};\n\nexport const clampViewSectionLimit = (value: number | undefined) => {\n const numericValue = typeof value === 'number' ? value : Number.NaN;\n\n if (!Number.isInteger(numericValue)) {\n return DEFAULT_VIEW_SECTION_LIMIT;\n }\n\n return Math.min(MAX_VIEW_SECTION_LIMIT, Math.max(MIN_VIEW_SECTION_LIMIT, numericValue));\n};\n\nexport const normalizeViewTabTitle = (title: string) => {\n const trimmedTitle = title.trim();\n\n return trimmedTitle || 'Untitled View';\n};\n\nconst buildDefaultSectionTitle = (tagNames: string[], propertyFilters: ViewPropertyFilterRecord[]) => {\n if (tagNames.length > 0) {\n return tagNames.slice(0, 2).join(' + ');\n }\n\n if (propertyFilters.length > 0) {\n return propertyFilters\n .slice(0, 2)\n .map((filter) => filter.name)\n .join(' + ');\n }\n\n return 'All notes';\n};\n\nexport const normalizeViewSectionInput = (input: ViewSectionInput) => {\n const tagNames = normalizeViewTagNames(input.tagNames ?? []);\n const propertyFilters = normalizeViewPropertyFilters(input.propertyFilters);\n const trimmedTitle = input.title?.trim() ?? '';\n const sortBy = normalizeViewSortBy(input.sortBy);\n const sortOrder = normalizeViewSortOrder(input.sortOrder);\n const displayOptions = normalizeViewDisplayOptions(input.displayOptions);\n\n return {\n title: trimmedTitle || buildDefaultSectionTitle(tagNames, propertyFilters),\n displayType: normalizeViewDisplayType(input.displayType),\n displayOptions,\n tagNames,\n mode: input.mode === 'or' ? 'or' : 'and',\n propertyFilters,\n sortBy,\n sortOrder,\n limit: clampViewSectionLimit(input.limit),\n } satisfies {\n title: string;\n displayType: ViewDisplayType;\n displayOptions: ViewDisplayOptionsRecord;\n tagNames: string[];\n mode: ViewTagMatchMode;\n propertyFilters: ViewPropertyFilterRecord[];\n sortBy: ViewSortBy;\n sortOrder: ViewSortOrder;\n limit: number;\n };\n};\n\nexport const normalizeViewNotesQueryInput = (input: ViewNotesQueryInput): ViewNotesQueryRecord => {\n return {\n tagNames: normalizeViewTagNames(input.tagNames ?? []),\n mode: input.mode === 'or' ? 'or' : 'and',\n propertyFilters: normalizeViewPropertyFilters(input.propertyFilters),\n sortBy: normalizeViewSortBy(input.sortBy),\n sortOrder: normalizeViewSortOrder(input.sortOrder),\n };\n};\n\nexport const normalizeViewNotesPagination = (pagination?: { limit?: number; offset?: number }) => {\n const numericLimit = Number(pagination?.limit ?? DEFAULT_VIEW_NOTES_QUERY_LIMIT);\n const limit = Number.isInteger(numericLimit)\n ? Math.min(MAX_VIEW_NOTES_QUERY_LIMIT, Math.max(1, numericLimit))\n : DEFAULT_VIEW_NOTES_QUERY_LIMIT;\n const numericOffset = Number(pagination?.offset ?? 0);\n const offset = Number.isInteger(numericOffset) ? Math.max(0, numericOffset) : 0;\n\n return { limit, offset };\n};\n\nexport const pickNextActiveViewTabId = (tabIds: number[], deletedTabId: number, currentActiveTabId: number | null) => {\n const remainingTabIds = tabIds.filter((tabId) => tabId !== deletedTabId);\n\n if (remainingTabIds.length === 0) {\n return null;\n }\n\n if (currentActiveTabId !== deletedTabId) {\n return currentActiveTabId;\n }\n\n return remainingTabIds[0] ?? null;\n};\n\nconst ensureValidReorderIds = (currentIds: number[], nextIds: number[]) => {\n if (currentIds.length !== nextIds.length) {\n throw new Error('Reorder payload must include every item exactly once.');\n }\n\n const currentIdSet = new Set(currentIds);\n const nextIdSet = new Set(nextIds);\n\n if (currentIdSet.size !== currentIds.length || nextIdSet.size !== nextIds.length) {\n throw new Error('Reorder payload contains duplicate ids.');\n }\n\n for (const id of currentIdSet) {\n if (!nextIdSet.has(id)) {\n throw new Error('Reorder payload must match the current item set.');\n }\n }\n};\n\nconst parseViewId = (id: string) => {\n const numericId = Number(id);\n\n if (!Number.isInteger(numericId) || numericId <= 0) {\n throw new Error('A valid id is required.');\n }\n\n return numericId;\n};\n\nconst serializeViewSection = (section: DbViewSection): ViewSectionRecord => {\n const query = parseStoredViewQuery(section.query);\n\n return {\n id: String(section.id),\n tabId: String(section.tabId),\n title: section.title,\n displayType: normalizeViewDisplayType(section.displayType as ViewDisplayType),\n displayOptions: query.displayOptions,\n tagNames: section.tags.map((tag) => tag.name),\n mode: section.mode as ViewTagMatchMode,\n propertyFilters: query.propertyFilters,\n sortBy: query.sortBy,\n sortOrder: query.sortOrder,\n limit: section.limit,\n order: section.order,\n };\n};\n\nconst serializeViewTab = (tab: DbViewTab): ViewTabRecord => ({\n id: String(tab.id),\n title: tab.title,\n order: tab.order,\n sections: tab.sections.map(serializeViewSection),\n});\n\nconst getOrderedViewTabs = async (db: ViewDbClient) => {\n return db.viewTab.findMany({\n orderBy: [{ order: 'asc' }, { createdAt: 'asc' }],\n include: orderedViewTabSectionsInclude,\n });\n};\n\nconst ensureViewWorkspace = async (db: ViewDbClient) => {\n return db.viewWorkspace.upsert({\n where: { id: VIEW_WORKSPACE_ID },\n update: {},\n create: { id: VIEW_WORKSPACE_ID },\n });\n};\n\nconst readViewWorkspace = async (db: ViewDbClient): Promise<ViewWorkspaceRecord> => {\n const [workspace, tabs] = await Promise.all([ensureViewWorkspace(db), getOrderedViewTabs(db)]);\n\n const activeTabId =\n workspace.activeTabId !== null && tabs.some((tab) => tab.id === workspace.activeTabId)\n ? String(workspace.activeTabId)\n : tabs[0]\n ? String(tabs[0].id)\n : null;\n\n return {\n activeTabId,\n tabs: tabs.map(serializeViewTab),\n };\n};\n\nconst readViewSection = async (db: ViewDbClient, id: number): Promise<ViewSectionRecord | null> => {\n const section = await db.viewSection.findUnique({\n where: { id },\n include: orderedViewSectionTagsInclude,\n });\n\n return section ? serializeViewSection(section) : null;\n};\n\nexport const hydratePropertyFilters = async (\n db: ViewDbClient,\n filters: ViewPropertyFilterRecord[],\n options: { validateSelectOptions?: boolean } = {},\n) => {\n if (filters.length === 0) {\n return [];\n }\n\n const definitions = await db.propertyDefinition.findMany({\n where: { key: { in: filters.map((filter) => filter.key) } },\n select: {\n key: true,\n name: true,\n valueType: true,\n options: {\n select: {\n value: true,\n },\n },\n },\n });\n const definitionByKey = new Map(definitions.map((definition) => [definition.key, definition]));\n\n return filters.map((filter) => {\n const definition = definitionByKey.get(filter.key);\n\n if (!definition) {\n throw new InvalidNotePropertyInputError(`Property ${filter.key} is not defined.`);\n }\n\n if (definition.valueType !== filter.valueType) {\n throw new InvalidNotePropertyInputError(`Property ${filter.key} uses ${definition.valueType} values.`);\n }\n\n if (\n options.validateSelectOptions &&\n filter.valueType === 'select' &&\n filter.operator !== 'exists' &&\n filter.operator !== 'notExists'\n ) {\n const optionValue = normalizeSelectFilterValue(filter.value ?? '');\n\n if (!definition.options.some((option) => option.value === optionValue)) {\n throw new InvalidNotePropertyInputError(`Property ${filter.key} option ${optionValue} is not defined.`);\n }\n }\n\n return {\n ...filter,\n name: definition.name,\n };\n });\n};\n\nconst buildStoredViewQuery = async (db: ViewDbClient, section: ReturnType<typeof normalizeViewSectionInput>) => {\n const propertyFilters = await hydratePropertyFilters(db, section.propertyFilters, { validateSelectOptions: true });\n\n return serializeStoredViewQuery({\n propertyFilters,\n sortBy: section.sortBy,\n sortOrder: section.sortOrder,\n displayOptions: section.displayOptions,\n });\n};\n\nconst getNextTabOrder = async (db: ViewDbClient) => {\n const lastTab = await db.viewTab.findFirst({\n orderBy: [{ order: 'desc' }, { createdAt: 'desc' }],\n select: { order: true },\n });\n\n return lastTab ? lastTab.order + 1 : 0;\n};\n\nconst getNextSectionOrder = async (db: ViewDbClient, tabId: number) => {\n const lastSection = await db.viewSection.findFirst({\n where: { tabId },\n orderBy: [{ order: 'desc' }, { createdAt: 'desc' }],\n select: { order: true },\n });\n\n return lastSection ? lastSection.order + 1 : 0;\n};\n\nconst resequenceViewTabs = async (db: ViewDbClient) => {\n const tabs = await db.viewTab.findMany({\n orderBy: [{ order: 'asc' }, { createdAt: 'asc' }],\n select: { id: true },\n });\n\n await Promise.all(\n tabs.map((tab, index) =>\n db.viewTab.update({\n where: { id: tab.id },\n data: { order: index },\n }),\n ),\n );\n};\n\nconst resequenceViewSections = async (db: ViewDbClient, tabId: number) => {\n const sections = await db.viewSection.findMany({\n where: { tabId },\n orderBy: [{ order: 'asc' }, { createdAt: 'asc' }],\n select: { id: true },\n });\n\n await Promise.all(\n sections.map((section, index) =>\n db.viewSection.update({\n where: { id: section.id },\n data: { order: index },\n }),\n ),\n );\n};\n\nexport const getViewWorkspace = async () => {\n return readViewWorkspace(models);\n};\n\nexport const getViewSectionById = async (id: string) => {\n return readViewSection(models, parseViewId(id));\n};\n\nconst normalizeSelectFilterValue = (value: string) => {\n return value.trim().toLowerCase().replace(/\\s+/g, '-');\n};\n\nconst buildPropertyFilterValueWhere = (filter: ViewPropertyFilterRecord): Prisma.NotePropertyWhereInput => {\n switch (filter.valueType) {\n case 'number': {\n const numberValue = Number(filter.value);\n\n if (filter.operator === 'before') {\n return { numberValue: { lt: numberValue } };\n }\n\n if (filter.operator === 'after') {\n return { numberValue: { gt: numberValue } };\n }\n\n if (filter.operator === 'notEquals') {\n return { numberValue: { not: numberValue } };\n }\n\n return { numberValue };\n }\n case 'date': {\n const dateValue = new Date(`${filter.value}T00:00:00.000Z`);\n\n if (filter.operator === 'before') {\n return { dateValue: { lt: dateValue } };\n }\n\n if (filter.operator === 'after') {\n return { dateValue: { gt: dateValue } };\n }\n\n if (filter.operator === 'notEquals') {\n return { dateValue: { not: dateValue } };\n }\n\n return { dateValue };\n }\n case 'boolean': {\n if (filter.operator === 'notEquals') {\n return { boolValue: { not: filter.value === 'true' } };\n }\n\n return { boolValue: filter.value === 'true' };\n }\n case 'select':\n if (filter.operator === 'notEquals') {\n return { option: { is: { value: { not: normalizeSelectFilterValue(filter.value ?? '') } } } };\n }\n\n return { option: { is: { value: normalizeSelectFilterValue(filter.value ?? '') } } };\n case 'url':\n case 'text':\n default: {\n const textValue = filter.value?.toLowerCase() ?? '';\n\n if (filter.operator === 'notEquals') {\n return { textValueNormalized: { not: textValue } };\n }\n\n if (filter.operator === 'contains') {\n return { textValueNormalized: { contains: textValue } };\n }\n\n if (filter.operator === 'notContains') {\n return { textValueNormalized: { not: { contains: textValue } } };\n }\n\n return { textValueNormalized: textValue };\n }\n }\n};\n\nexport const buildPropertyFilterWhere = (filter: ViewPropertyFilterRecord): Prisma.NoteWhereInput => {\n const definitionWhere = {\n definition: {\n is: {\n key: filter.key,\n },\n },\n } satisfies Prisma.NotePropertyWhereInput;\n\n if (filter.operator === 'notExists') {\n return {\n properties: {\n none: definitionWhere,\n },\n };\n }\n\n if (filter.operator === 'exists') {\n return {\n properties: {\n some: definitionWhere,\n },\n };\n }\n\n return {\n properties: {\n some: {\n ...definitionWhere,\n ...buildPropertyFilterValueWhere(filter),\n },\n },\n };\n};\n\nexport const buildViewNotesWhere = (\n query: Pick<ViewNotesQueryRecord, 'tagNames' | 'mode' | 'propertyFilters'>,\n): Prisma.NoteWhereInput => {\n const clauses: Prisma.NoteWhereInput[] = [];\n\n if (query.tagNames.length > 0) {\n clauses.push(buildNoteTagNamesWhere(query.tagNames, query.mode as NoteTagMatchMode));\n }\n\n for (const filter of query.propertyFilters) {\n clauses.push(buildPropertyFilterWhere(filter));\n }\n\n if (clauses.length === 0) {\n return {};\n }\n\n return { AND: clauses };\n};\n\nexport const buildViewSectionWhere = (section: ViewSectionRecord): Prisma.NoteWhereInput => {\n return buildViewNotesWhere(section);\n};\n\nconst buildViewNotesOrderBy = (\n query: Pick<ViewNotesQueryRecord, 'sortBy' | 'sortOrder'>,\n): Prisma.NoteOrderByWithRelationInput[] => {\n return [{ [query.sortBy]: query.sortOrder }, { id: 'asc' }];\n};\n\nconst buildViewSectionOrderBy = (section: ViewSectionRecord): Prisma.NoteOrderByWithRelationInput[] => {\n return buildViewNotesOrderBy(section);\n};\n\nexport const getViewSectionNotes = async (\n id: string,\n pagination: {\n limit: number;\n offset: number;\n },\n): Promise<ViewSectionNotesResult | null> => {\n const section = await models.viewSection.findUnique({\n where: { id: parseViewId(id) },\n include: orderedViewSectionTagsInclude,\n });\n\n if (!section) {\n return null;\n }\n\n const serializedSection = serializeViewSection(section);\n const where = buildViewSectionWhere(serializedSection);\n\n const [totalCount, notes] = await Promise.all([\n models.note.count({ where }),\n models.note.findMany({\n orderBy: buildViewSectionOrderBy(serializedSection),\n where,\n take: Number(pagination.limit),\n skip: Number(pagination.offset),\n }),\n ]);\n\n return {\n totalCount,\n notes,\n };\n};\n\nexport const getNotesByPropertiesWithDb = async (\n db: ViewDbClient,\n input: ViewNotesQueryInput,\n pagination?: {\n limit?: number;\n offset?: number;\n },\n): Promise<ViewSectionNotesResult> => {\n const normalizedQuery = normalizeViewNotesQueryInput(input);\n\n if (normalizedQuery.propertyFilters.length === 0) {\n throw new InvalidNotePropertyInputError('At least one property filter is required.');\n }\n\n const query = {\n ...normalizedQuery,\n propertyFilters: await hydratePropertyFilters(db, normalizedQuery.propertyFilters, {\n validateSelectOptions: true,\n }),\n };\n const normalizedPagination = normalizeViewNotesPagination(pagination);\n const where = buildViewNotesWhere(query);\n\n const [totalCount, notes] = await Promise.all([\n db.note.count({ where }),\n db.note.findMany({\n orderBy: buildViewNotesOrderBy(query),\n where,\n take: normalizedPagination.limit,\n skip: normalizedPagination.offset,\n }),\n ]);\n\n return {\n totalCount,\n notes,\n };\n};\n\nexport const getNotesByProperties = async (\n input: ViewNotesQueryInput,\n pagination?: {\n limit?: number;\n offset?: number;\n },\n): Promise<ViewSectionNotesResult> => {\n return getNotesByPropertiesWithDb(models, input, pagination);\n};\n\nexport const createViewTab = async (title: string) => {\n return models.$transaction(async (tx) => {\n const workspace = await ensureViewWorkspace(tx);\n const nextTabOrder = await getNextTabOrder(tx);\n const createdTab = await tx.viewTab.create({\n data: {\n title: normalizeViewTabTitle(title),\n order: nextTabOrder,\n },\n include: orderedViewTabSectionsInclude,\n });\n\n if (workspace.activeTabId === null) {\n await tx.viewWorkspace.update({\n where: { id: VIEW_WORKSPACE_ID },\n data: { activeTabId: createdTab.id },\n });\n }\n\n return serializeViewTab(createdTab);\n });\n};\n\nexport const updateViewTab = async (id: string, title: string) => {\n const updatedTab = await models.viewTab.update({\n where: { id: parseViewId(id) },\n data: {\n title: normalizeViewTabTitle(title),\n },\n include: orderedViewTabSectionsInclude,\n });\n\n return serializeViewTab(updatedTab);\n};\n\nexport const deleteViewTab = async (id: string) => {\n const tabId = parseViewId(id);\n\n return models.$transaction(async (tx) => {\n const workspace = await ensureViewWorkspace(tx);\n const tabs = await tx.viewTab.findMany({\n orderBy: [{ order: 'asc' }, { createdAt: 'asc' }],\n select: { id: true },\n });\n\n if (!tabs.some((tab) => tab.id === tabId)) {\n return false;\n }\n\n await tx.viewTab.delete({ where: { id: tabId } });\n await resequenceViewTabs(tx);\n\n const nextActiveTabId = pickNextActiveViewTabId(\n tabs.map((tab) => tab.id),\n tabId,\n workspace.activeTabId,\n );\n\n await tx.viewWorkspace.update({\n where: { id: VIEW_WORKSPACE_ID },\n data: { activeTabId: nextActiveTabId },\n });\n\n return true;\n });\n};\n\nexport const setActiveViewTab = async (id: string) => {\n const tabId = parseViewId(id);\n\n return models.$transaction(async (tx) => {\n const workspace = await ensureViewWorkspace(tx);\n const tab = await tx.viewTab.findUnique({\n where: { id: tabId },\n select: { id: true },\n });\n\n if (!tab) {\n throw new Error('View tab not found.');\n }\n\n await tx.viewWorkspace.update({\n where: { id: workspace.id },\n data: { activeTabId: tabId },\n });\n\n return readViewWorkspace(tx);\n });\n};\n\nexport const reorderViewTabs = async (tabIds: string[]) => {\n const nextTabIds = tabIds.map(parseViewId);\n\n return models.$transaction(async (tx) => {\n const tabs = await tx.viewTab.findMany({\n orderBy: [{ order: 'asc' }, { createdAt: 'asc' }],\n select: { id: true },\n });\n const currentTabIds = tabs.map((tab) => tab.id);\n\n ensureValidReorderIds(currentTabIds, nextTabIds);\n\n await Promise.all(\n nextTabIds.map((tabId, index) =>\n tx.viewTab.update({\n where: { id: tabId },\n data: { order: index },\n }),\n ),\n );\n\n const reorderedTabs = await getOrderedViewTabs(tx);\n return reorderedTabs.map(serializeViewTab);\n });\n};\n\nexport const createViewSection = async (tabId: string, input: ViewSectionInput) => {\n const numericTabId = parseViewId(tabId);\n const nextSection = normalizeViewSectionInput(input);\n\n return models.$transaction(async (tx) => {\n const tab = await tx.viewTab.findUnique({\n where: { id: numericTabId },\n select: { id: true },\n });\n\n if (!tab) {\n throw new Error('View tab not found.');\n }\n\n const nextSectionOrder = await getNextSectionOrder(tx, numericTabId);\n const query = await buildStoredViewQuery(tx, nextSection);\n\n const createdSection = await tx.viewSection.create({\n data: {\n tabId: numericTabId,\n title: nextSection.title,\n displayType: nextSection.displayType,\n query,\n mode: nextSection.mode,\n limit: nextSection.limit,\n order: nextSectionOrder,\n tags: {\n create: nextSection.tagNames.map((tagName, index) => ({\n name: tagName,\n order: index,\n })),\n },\n },\n include: orderedViewSectionTagsInclude,\n });\n\n return serializeViewSection(createdSection);\n });\n};\n\nexport const updateViewSection = async (id: string, input: ViewSectionInput) => {\n const sectionId = parseViewId(id);\n const nextSection = normalizeViewSectionInput(input);\n\n return models.$transaction(async (tx) => {\n const query = await buildStoredViewQuery(tx, nextSection);\n\n const updatedSection = await tx.viewSection.update({\n where: { id: sectionId },\n data: {\n title: nextSection.title,\n displayType: nextSection.displayType,\n query,\n mode: nextSection.mode,\n limit: nextSection.limit,\n tags: {\n deleteMany: {},\n create: nextSection.tagNames.map((tagName, index) => ({\n name: tagName,\n order: index,\n })),\n },\n },\n include: orderedViewSectionTagsInclude,\n });\n\n return serializeViewSection(updatedSection);\n });\n};\n\nexport const deleteViewSection = async (id: string) => {\n const sectionId = parseViewId(id);\n\n return models.$transaction(async (tx) => {\n const section = await tx.viewSection.findUnique({\n where: { id: sectionId },\n select: { id: true, tabId: true },\n });\n\n if (!section) {\n return false;\n }\n\n await tx.viewSection.delete({\n where: { id: sectionId },\n });\n await resequenceViewSections(tx, section.tabId);\n\n return true;\n });\n};\n\nexport const reorderViewSections = async (tabId: string, sectionIds: string[]) => {\n const numericTabId = parseViewId(tabId);\n const nextSectionIds = sectionIds.map(parseViewId);\n\n return models.$transaction(async (tx) => {\n const sections = await tx.viewSection.findMany({\n where: { tabId: numericTabId },\n orderBy: [{ order: 'asc' }, { createdAt: 'asc' }],\n select: { id: true },\n });\n const currentSectionIds = sections.map((section) => section.id);\n\n ensureValidReorderIds(currentSectionIds, nextSectionIds);\n\n await Promise.all(\n nextSectionIds.map((sectionId, index) =>\n tx.viewSection.update({\n where: { id: sectionId },\n data: { order: index },\n }),\n ),\n );\n\n const reorderedSections = await tx.viewSection.findMany({\n where: { tabId: numericTabId },\n orderBy: [{ order: 'asc' }, { createdAt: 'asc' }],\n include: orderedViewSectionTagsInclude,\n });\n\n return reorderedSections.map(serializeViewSection);\n });\n};\n"],"mappings":"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","names":[]}
|
package/server/dist/main.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/main.ts"],"sourcesContent":["import { createApp } from './app.js';\nimport { logAuthConfig, resolveAuthConfig } from './modules/auth-mode.js';\nimport { startDataMaintenanceScheduler } from './modules/data-maintenance.js';\n\nconst PORT = Number(process.env.PORT || 6683);\nconst HOST = process.env.HOST || '0.0.0.0';\n\ntry {\n const authConfig = resolveAuthConfig(process.env);\n\n logAuthConfig(authConfig);\n\n const app = createApp(authConfig);\n\n app.listen(PORT, HOST, () => {\n process.stdout.write(`http server listen on ${HOST}:${PORT} (auth: ${authConfig.mode})\\n`);\n\n startDataMaintenanceScheduler({\n onResults: (results) => {\n for (const result of results) {\n process.stdout.write(`[maintenance] Reconciled ${result.processedCount} rows for ${result.key}\\n`);\n }\n },\n onError: (error) => {\n const message = error instanceof Error ? error.message : 'Unknown data maintenance error';\n process.stderr.write(`[maintenance] Background run failed: ${message}\\n`);\n },\n });\n });\n} catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown auth configuration error';\n process.stderr.write(`[auth] Startup failed: ${message}\\n`);\n process.exit(1);\n}\n"],"mappings":"AAAA,SAAS,iBAAiB;AAC1B,SAAS,eAAe,yBAAyB;AACjD,SAAS,qCAAqC;AAE9C,MAAM,OAAO,OAAO,QAAQ,IAAI,QAAQ,IAAI;AAC5C,MAAM,OAAO,QAAQ,IAAI,QAAQ;AAEjC,IAAI;AACA,QAAM,aAAa,kBAAkB,QAAQ,GAAG;AAEhD,gBAAc,UAAU;AAExB,QAAM,MAAM,UAAU,UAAU;AAEhC,MAAI,OAAO,MAAM,MAAM,MAAM;AACzB,YAAQ,OAAO,MAAM,yBAAyB,IAAI,IAAI,IAAI,WAAW,WAAW,IAAI;AAAA,CAAK;AAEzF,kCAA8B;AAAA,MAC1B,WAAW,CAAC,YAAY;AACpB,mBAAW,UAAU,SAAS;AAC1B,kBAAQ,OAAO,MAAM,4BAA4B,OAAO,cAAc,aAAa,OAAO,GAAG;AAAA,CAAI;AAAA,QACrG;AAAA,MACJ;AAAA,MACA,SAAS,CAAC,UAAU;AAChB,cAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,gBAAQ,OAAO,MAAM,wCAAwC,OAAO;AAAA,CAAI;AAAA,MAC5E;AAAA,IACJ,CAAC;AAAA,EACL,CAAC;AACL,SAAS,OAAO;AACZ,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,UAAQ,OAAO,MAAM,0BAA0B,OAAO;AAAA,CAAI;AAC1D,UAAQ,KAAK,CAAC;AAClB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/models.ts"],"sourcesContent":["import { PrismaClient } from '@prisma/client';\n\nconst prisma = new PrismaClient();\n\nexport default prisma;\nexport * from '@prisma/client';\n"],"mappings":"AAAA,SAAS,oBAAoB;AAE7B,MAAM,SAAS,IAAI,aAAa;AAEhC,IAAO,iBAAQ;AACf,cAAc;","names":[]}
|