ocean-brain 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/dist/mcp.js +660 -31
  2. package/package.json +2 -1
  3. package/server/client/dist/assets/{Calendar-DI0PhQTq.js → Calendar-BytW4PeT.js} +1 -1
  4. package/server/client/dist/assets/Callout-9sJgGNRb.js +1 -0
  5. package/server/client/dist/assets/Graph-o5u-NzrA.js +1 -0
  6. package/server/client/dist/assets/{Image-DlJ4MDo3.js → Image-DxWhlIDG.js} +1 -1
  7. package/server/client/dist/assets/{Image.es-COwqkQuh.js → Image.es-B0LL3pb7.js} +1 -1
  8. package/server/client/dist/assets/Note-CYoYzZNu.js +21 -0
  9. package/server/client/dist/assets/{Plus.es-KeV96R_e.js → Plus.es-DpxzgRtY.js} +1 -1
  10. package/server/client/dist/assets/Reminders-DAepTZg1.js +1 -0
  11. package/server/client/dist/assets/Search-6KH7An44.js +1 -0
  12. package/server/client/dist/assets/{SurfaceCard-CHjcCuqZ.js → SurfaceCard-EMs50xSF.js} +1 -1
  13. package/server/client/dist/assets/Tag-C89j8x56.js +1 -0
  14. package/server/client/dist/assets/TagNotes-BTbu-f6v.js +1 -0
  15. package/server/client/dist/assets/{Trash.es-BqRTZPrI.js → Trash.es-C5x35NKF.js} +1 -1
  16. package/server/client/dist/assets/ViewNotes-DPEuki3y.js +1 -0
  17. package/server/client/dist/assets/Views-BGkuNhVd.js +1 -0
  18. package/server/client/dist/assets/{image.api-CMdQbCyN.js → image.api-DRhRQ0Gf.js} +1 -1
  19. package/server/client/dist/assets/{index-D2gRB1ig.css → index-Cd81UxEh.css} +1 -1
  20. package/server/client/dist/assets/index-DYlYUrjH.js +327 -0
  21. package/server/client/dist/assets/index-DswSFFMb.js +1 -0
  22. package/server/client/dist/assets/manage-image-C6sHhWnI.js +1 -0
  23. package/server/client/dist/assets/manage-image-detail-CJkfybR9.js +1 -0
  24. package/server/client/dist/assets/{mcp-DqGLZv90.js → mcp-piouFDNm.js} +1 -1
  25. package/server/client/dist/assets/note-core-Z6kqulGB.js +180 -0
  26. package/server/client/dist/assets/note-vendor-i1M2FSI2.js +54 -0
  27. package/server/client/dist/assets/{placeholder-BXLtvdtN.js → placeholder-DGz3CHej.js} +4 -4
  28. package/server/client/dist/assets/properties-CM4khczg.js +1 -0
  29. package/server/client/dist/assets/trash-C2lItz-b.js +1 -0
  30. package/server/client/dist/assets/{useReminderMutate-v1EXqM90.js → useReminderMutate-DHjDDHKg.js} +1 -1
  31. package/server/client/dist/assets/view-dashboard-C17WsdL7.js +99 -0
  32. package/server/client/dist/index.html +4 -4
  33. package/server/dist/features/note/graphql/note.field.resolver.js +16 -1
  34. package/server/dist/features/note/graphql/note.field.resolver.js.map +1 -1
  35. package/server/dist/features/note/graphql/note.mutation.resolver.js +192 -36
  36. package/server/dist/features/note/graphql/note.mutation.resolver.js.map +1 -1
  37. package/server/dist/features/note/graphql/note.query.resolver.js +88 -76
  38. package/server/dist/features/note/graphql/note.query.resolver.js.map +1 -1
  39. package/server/dist/features/note/graphql/note.resolver.js +3 -2
  40. package/server/dist/features/note/graphql/note.resolver.js.map +1 -1
  41. package/server/dist/features/note/graphql/note.type-defs.js +104 -1
  42. package/server/dist/features/note/graphql/note.type-defs.js.map +1 -1
  43. package/server/dist/features/note/http/mcp.js +394 -1
  44. package/server/dist/features/note/http/mcp.js.map +1 -1
  45. package/server/dist/features/note/services/cleanup.js +4 -3
  46. package/server/dist/features/note/services/cleanup.js.map +1 -1
  47. package/server/dist/features/note/services/content-blocks.js +113 -0
  48. package/server/dist/features/note/services/content-blocks.js.map +1 -0
  49. package/server/dist/features/note/services/markdown-intent-write.js +478 -0
  50. package/server/dist/features/note/services/markdown-intent-write.js.map +1 -0
  51. package/server/dist/features/note/services/markdown-patch.js +601 -0
  52. package/server/dist/features/note/services/markdown-patch.js.map +1 -0
  53. package/server/dist/features/note/services/properties.js +874 -0
  54. package/server/dist/features/note/services/properties.js.map +1 -0
  55. package/server/dist/features/note/services/search.js +10 -29
  56. package/server/dist/features/note/services/search.js.map +1 -1
  57. package/server/dist/features/note/services/snapshot.js +260 -18
  58. package/server/dist/features/note/services/snapshot.js.map +1 -1
  59. package/server/dist/features/note/services/trash.js +70 -2
  60. package/server/dist/features/note/services/trash.js.map +1 -1
  61. package/server/dist/features/note/services/write-conflict.js +87 -0
  62. package/server/dist/features/note/services/write-conflict.js.map +1 -0
  63. package/server/dist/features/note/services/write.js +121 -0
  64. package/server/dist/features/note/services/write.js.map +1 -0
  65. package/server/dist/features/view/graphql/view.query.resolver.js +31 -1
  66. package/server/dist/features/view/graphql/view.query.resolver.js.map +1 -1
  67. package/server/dist/features/view/graphql/view.type-defs.js +57 -1
  68. package/server/dist/features/view/graphql/view.type-defs.js.map +1 -1
  69. package/server/dist/features/view/services/workspace.js +367 -43
  70. package/server/dist/features/view/services/workspace.js.map +1 -1
  71. package/server/dist/modules/blocknote-tree.js +41 -0
  72. package/server/dist/modules/blocknote-tree.js.map +1 -0
  73. package/server/dist/modules/blocknote.js +47 -2
  74. package/server/dist/modules/blocknote.js.map +1 -1
  75. package/server/dist/modules/error-handler.js +7 -4
  76. package/server/dist/modules/error-handler.js.map +1 -1
  77. package/server/dist/modules/recovery-retention.js +2 -2
  78. package/server/dist/modules/recovery-retention.js.map +1 -1
  79. package/server/dist/routes/mcp.js +21 -1
  80. package/server/dist/routes/mcp.js.map +1 -1
  81. package/server/prisma/migrations/20260527073000_0017_note_properties/migration.sql +105 -0
  82. package/server/prisma/migrations/20260531073000_0018_view_query/migration.sql +3 -0
  83. package/server/prisma/schema.prisma +226 -130
  84. package/server/client/dist/assets/Callout-BAqbXI0L.js +0 -1
  85. package/server/client/dist/assets/Graph-Dhuog4tc.js +0 -1
  86. package/server/client/dist/assets/Note-ChUWU3Su.js +0 -21
  87. package/server/client/dist/assets/Reminders-D7MCTNxb.js +0 -1
  88. package/server/client/dist/assets/Search-B-fwTr5y.js +0 -1
  89. package/server/client/dist/assets/Tag-BbV2z-Db.js +0 -1
  90. package/server/client/dist/assets/TagNotes-2HKF09Jm.js +0 -1
  91. package/server/client/dist/assets/ViewNotes-TfM3Uzbp.js +0 -1
  92. package/server/client/dist/assets/Views-CUwtnfa8.js +0 -1
  93. package/server/client/dist/assets/index-B4l2UvuC.js +0 -232
  94. package/server/client/dist/assets/index-zhxZjg7V.js +0 -1
  95. package/server/client/dist/assets/manage-image-DdXb5Bkj.js +0 -1
  96. package/server/client/dist/assets/manage-image-detail-CrrXCQIX.js +0 -1
  97. package/server/client/dist/assets/note-core-GgFcksAF.js +0 -178
  98. package/server/client/dist/assets/note-vendor-B0t5F04o.js +0 -54
  99. package/server/client/dist/assets/trash-3eUAjFRh.js +0 -1
  100. package/server/client/dist/assets/view-dashboard-T6gmohr-.js +0 -90
  101. package/server/dist/features/note/graphql/note.graphql.shared.js +0 -23
  102. package/server/dist/features/note/graphql/note.graphql.shared.js.map +0 -1
@@ -1,10 +1,19 @@
1
1
  import { getNoteCleanupPreview, listNoteCleanupCandidates } from "../../../features/note/services/cleanup.js";
2
2
  import {
3
+ buildNoteGraph,
4
+ contentReferencesNote,
5
+ extractReferenceBlocksFromContent,
6
+ normalizeReferenceId,
7
+ syncReferenceTitlesInContent
8
+ } from "../../../features/note/services/content-blocks.js";
9
+ import { listNotePropertyKeys } from "../../../features/note/services/properties.js";
10
+ import {
11
+ buildNoteSearchProjection,
3
12
  filterNotesBySearchQuery,
4
13
  NOTE_SEARCH_TEXT_SCHEMA_VERSION,
5
14
  parseNoteSearchQuery
6
15
  } from "../../../features/note/services/search.js";
7
- import { listNoteSnapshots } from "../../../features/note/services/snapshot.js";
16
+ import { getNoteSnapshot, listNoteSnapshots } from "../../../features/note/services/snapshot.js";
8
17
  import {
9
18
  buildNoteTagNamesWhere,
10
19
  normalizeNoteTagNames
@@ -12,7 +21,6 @@ import {
12
21
  import { getTrashedNoteById, listTrashedNotes } from "../../../features/note/services/trash.js";
13
22
  import models from "../../../models.js";
14
23
  import { runDataMaintenanceInBackground } from "../../../modules/data-maintenance.js";
15
- import { extractBlocksByType } from "./note.graphql.shared.js";
16
24
  const buildAllNotesOrderBy = (searchFilter) => {
17
25
  const sortBy = searchFilter.sortBy || "updatedAt";
18
26
  const sortOrder = searchFilter.sortOrder || "desc";
@@ -88,6 +96,9 @@ const mergeSortedNotesForSearch = (left, right, searchFilter) => {
88
96
  }
89
97
  return merged;
90
98
  };
99
+ const isRecordNotFoundError = (error) => {
100
+ return typeof error === "object" && error !== null && "code" in error && error.code === "P2025";
101
+ };
91
102
  const createAllNotesQueryResolver = (deps = {
92
103
  countNotes: ({ where }) => models.note.count({ where }),
93
104
  findNotes: ({ orderBy, where, take, skip }) => models.note.findMany({
@@ -174,6 +185,33 @@ const createAllNotesQueryResolver = (deps = {
174
185
  };
175
186
  };
176
187
  };
188
+ const createBackReferencesQueryResolver = (deps = {
189
+ findCandidateNotes: (noteId) => models.note.findMany({
190
+ orderBy: [{ pinned: "desc" }, { updatedAt: "desc" }],
191
+ where: {
192
+ NOT: { id: noteId }
193
+ }
194
+ })
195
+ }) => {
196
+ return async (_, { id }) => {
197
+ const notes = await deps.findCandidateNotes(Number(id));
198
+ return notes.filter((note) => contentReferencesNote(note.content, id));
199
+ };
200
+ };
201
+ const createNoteGraphQueryResolver = (deps = {
202
+ findNotes: () => models.note.findMany({
203
+ select: {
204
+ id: true,
205
+ title: true,
206
+ content: true
207
+ }
208
+ })
209
+ }) => {
210
+ return async () => {
211
+ const notes = await deps.findNotes();
212
+ return buildNoteGraph(notes);
213
+ };
214
+ };
177
215
  const noteQueryResolvers = {
178
216
  allNotes: createAllNotesQueryResolver(),
179
217
  notesInDateRange: async (_, {
@@ -248,12 +286,7 @@ const noteQueryResolvers = {
248
286
  orderBy: { updatedAt: "desc" },
249
287
  where: { content: { contains: src } }
250
288
  }),
251
- backReferences: async (_, { id }) => {
252
- return models.note.findMany({
253
- orderBy: [{ pinned: "desc" }, { updatedAt: "desc" }],
254
- where: { content: { contains: `reference","props":{"id":"${id}"` } }
255
- });
256
- },
289
+ backReferences: createBackReferencesQueryResolver(),
257
290
  note: async (_, { id }) => {
258
291
  const note = await models.note.findUnique({ where: { id: Number(id) } });
259
292
  if (!note) {
@@ -262,33 +295,42 @@ const noteQueryResolvers = {
262
295
  if (!note.content) {
263
296
  return note;
264
297
  }
265
- const blocks = extractBlocksByType("reference", JSON.parse(note.content));
298
+ const blocks = extractReferenceBlocksFromContent(note.content);
266
299
  if (blocks.length === 0) {
267
300
  return note;
268
301
  }
269
- const referenceIds = blocks.map((block) => Number(block.props.id));
302
+ const referenceIds = Array.from(
303
+ new Set(
304
+ blocks.map((block) => normalizeReferenceId(block.props?.id)).filter((referenceId) => referenceId !== null).map(Number).filter(Number.isFinite)
305
+ )
306
+ );
270
307
  const references = await models.note.findMany({ where: { id: { in: referenceIds } } });
271
- const newContent = references.reduce((content, referenceNote) => {
272
- const reference = blocks.find((block) => Number(block.props.id) === referenceNote.id);
273
- if (reference && reference.props.title !== referenceNote.title) {
274
- return content.replace(
275
- `reference","props":{"id":"${reference.props.id}","title":"${reference.props.title}"`,
276
- `reference","props":{"id":"${referenceNote.id}","title":"${referenceNote.title}"`
277
- );
278
- }
279
- return content;
280
- }, note.content);
281
- if (newContent === note.content) {
308
+ const titlesById = new Map(
309
+ references.map((referenceNote) => [String(referenceNote.id), referenceNote.title])
310
+ );
311
+ const newContent = syncReferenceTitlesInContent(note.content, titlesById);
312
+ if (!newContent || newContent === note.content) {
282
313
  return note;
283
314
  }
284
315
  try {
285
- JSON.parse(newContent);
286
316
  return await models.note.update({
287
- where: { id: note.id },
288
- data: { content: newContent }
317
+ where: {
318
+ id: note.id,
319
+ updatedAt: note.updatedAt
320
+ },
321
+ data: {
322
+ content: newContent,
323
+ ...buildNoteSearchProjection({
324
+ title: note.title,
325
+ content: newContent
326
+ })
327
+ }
289
328
  });
290
- } catch {
291
- return note;
329
+ } catch (error) {
330
+ if (isRecordNotFoundError(error)) {
331
+ return note;
332
+ }
333
+ throw error;
292
334
  }
293
335
  },
294
336
  noteCleanupCandidates: async (_, {
@@ -310,10 +352,26 @@ const noteQueryResolvers = {
310
352
  },
311
353
  noteSnapshots: async (_, {
312
354
  id,
313
- limit = 5
355
+ limit = 10
314
356
  }) => {
315
357
  return listNoteSnapshots(Number(id), Number(limit));
316
358
  },
359
+ noteSnapshot: async (_, { id }) => {
360
+ return getNoteSnapshot(Number(id));
361
+ },
362
+ notePropertyKeys: async (_, {
363
+ query,
364
+ pagination = {
365
+ limit: 50,
366
+ offset: 0
367
+ }
368
+ }) => {
369
+ return listNotePropertyKeys({
370
+ query,
371
+ limit: Number(pagination.limit),
372
+ offset: Number(pagination.offset)
373
+ });
374
+ },
317
375
  trashedNote: async (_, { id }) => {
318
376
  return getTrashedNoteById(Number(id));
319
377
  },
@@ -328,58 +386,12 @@ const noteQueryResolvers = {
328
386
  offset: Number(pagination.offset)
329
387
  });
330
388
  },
331
- noteGraph: async () => {
332
- const notes = await models.note.findMany({
333
- select: {
334
- id: true,
335
- title: true,
336
- content: true
337
- }
338
- });
339
- const nodes = [];
340
- const links = [];
341
- const connectionCount = {};
342
- const linkSet = /* @__PURE__ */ new Set();
343
- for (const note of notes) {
344
- if (!note.content) {
345
- continue;
346
- }
347
- try {
348
- const blocks = extractBlocksByType("reference", JSON.parse(note.content));
349
- for (const block of blocks) {
350
- const targetId = block.props.id;
351
- if (targetId && String(note.id) !== targetId) {
352
- const linkKey = `${note.id}-${targetId}`;
353
- const reverseLinkKey = `${targetId}-${note.id}`;
354
- if (!linkSet.has(linkKey) && !linkSet.has(reverseLinkKey)) {
355
- linkSet.add(linkKey);
356
- links.push({
357
- source: String(note.id),
358
- target: targetId
359
- });
360
- connectionCount[String(note.id)] = (connectionCount[String(note.id)] || 0) + 1;
361
- connectionCount[targetId] = (connectionCount[targetId] || 0) + 1;
362
- }
363
- }
364
- }
365
- } catch {
366
- }
367
- }
368
- for (const note of notes) {
369
- nodes.push({
370
- id: String(note.id),
371
- title: note.title || "Untitled",
372
- connections: connectionCount[String(note.id)] || 0
373
- });
374
- }
375
- return {
376
- nodes,
377
- links
378
- };
379
- }
389
+ noteGraph: createNoteGraphQueryResolver()
380
390
  };
381
391
  export {
382
392
  createAllNotesQueryResolver,
393
+ createBackReferencesQueryResolver,
394
+ createNoteGraphQueryResolver,
383
395
  noteQueryResolvers
384
396
  };
385
397
  //# sourceMappingURL=note.query.resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/features/note/graphql/note.query.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport { getNoteCleanupPreview, listNoteCleanupCandidates } from '~/features/note/services/cleanup.js';\nimport {\n filterNotesBySearchQuery,\n NOTE_SEARCH_TEXT_SCHEMA_VERSION,\n parseNoteSearchQuery,\n} from '~/features/note/services/search.js';\nimport { listNoteSnapshots } from '~/features/note/services/snapshot.js';\nimport {\n buildNoteTagNamesWhere,\n type NoteTagMatchMode,\n normalizeNoteTagNames,\n} from '~/features/note/services/tag-filter.js';\nimport { getTrashedNoteById, listTrashedNotes } from '~/features/note/services/trash.js';\nimport type { Note, Prisma } from '~/models.js';\nimport models from '~/models.js';\nimport { runDataMaintenanceInBackground } from '~/modules/data-maintenance.js';\nimport type { Pagination, SearchFilter } from '~/types/index.js';\nimport { extractBlocksByType } from './note.graphql.shared.js';\n\ninterface AllNotesResolverDeps {\n countNotes: (args: { where?: Prisma.NoteWhereInput }) => Promise<number>;\n findNotes: (args: {\n orderBy: Prisma.NoteOrderByWithRelationInput[];\n where?: Prisma.NoteWhereInput;\n take?: number;\n skip?: number;\n }) => Promise<Note[]>;\n triggerSearchBackfill: () => void;\n}\n\nconst buildAllNotesOrderBy = (searchFilter: SearchFilter) => {\n const sortBy = searchFilter.sortBy || 'updatedAt';\n const sortOrder = searchFilter.sortOrder || 'desc';\n const pinnedFirst = searchFilter.pinnedFirst || false;\n const orderBy: Prisma.NoteOrderByWithRelationInput[] = [];\n\n if (pinnedFirst) {\n orderBy.push({ pinned: 'desc' });\n }\n\n if (sortBy === 'createdAt') {\n orderBy.push({ createdAt: sortOrder as 'asc' | 'desc' });\n } else {\n orderBy.push({ updatedAt: sortOrder as 'asc' | 'desc' });\n }\n\n return orderBy;\n};\n\nconst buildAllNotesSearchWhere = (searchFilter: SearchFilter) => {\n const parsedQuery = parseNoteSearchQuery(searchFilter.query);\n\n if (!parsedQuery.hasFilters) {\n return undefined;\n }\n\n return {\n AND: [\n { searchableTextVersion: NOTE_SEARCH_TEXT_SCHEMA_VERSION },\n ...parsedQuery.included.map((keyword) => ({ searchableText: { contains: keyword } })),\n ...parsedQuery.excluded.map((keyword) => ({ NOT: { searchableText: { contains: keyword } } })),\n ],\n } satisfies Prisma.NoteWhereInput;\n};\n\nconst buildAllNotesStaleCandidateWhere = (searchFilter: SearchFilter) => {\n const parsedQuery = parseNoteSearchQuery(searchFilter.query);\n\n return {\n AND: [\n { searchableTextVersion: { not: NOTE_SEARCH_TEXT_SCHEMA_VERSION } },\n ...parsedQuery.included.map((keyword) => ({\n OR: [{ title: { contains: keyword } }, { content: { contains: keyword } }],\n })),\n ],\n } satisfies Prisma.NoteWhereInput;\n};\n\nconst compareNotesForSearch = (left: Note, right: Note, searchFilter: SearchFilter) => {\n if (searchFilter.pinnedFirst && left.pinned !== right.pinned) {\n return left.pinned ? -1 : 1;\n }\n\n const sortBy = searchFilter.sortBy || 'updatedAt';\n const sortOrder = searchFilter.sortOrder || 'desc';\n const leftValue = sortBy === 'createdAt' ? left.createdAt.getTime() : left.updatedAt.getTime();\n const rightValue = sortBy === 'createdAt' ? right.createdAt.getTime() : right.updatedAt.getTime();\n\n if (leftValue === rightValue) {\n return 0;\n }\n\n return sortOrder === 'asc' ? leftValue - rightValue : rightValue - leftValue;\n};\n\nconst mergeSortedNotesForSearch = (left: Note[], right: Note[], searchFilter: SearchFilter) => {\n const merged: Note[] = [];\n let leftIndex = 0;\n let rightIndex = 0;\n\n while (leftIndex < left.length && rightIndex < right.length) {\n if (compareNotesForSearch(left[leftIndex], right[rightIndex], searchFilter) <= 0) {\n merged.push(left[leftIndex]);\n leftIndex += 1;\n } else {\n merged.push(right[rightIndex]);\n rightIndex += 1;\n }\n }\n\n while (leftIndex < left.length) {\n merged.push(left[leftIndex]);\n leftIndex += 1;\n }\n\n while (rightIndex < right.length) {\n merged.push(right[rightIndex]);\n rightIndex += 1;\n }\n\n return merged;\n};\n\nexport const createAllNotesQueryResolver = (\n deps: AllNotesResolverDeps = {\n countNotes: ({ where }) => models.note.count({ where }),\n findNotes: ({ orderBy, where, take, skip }) =>\n models.note.findMany({\n orderBy,\n where,\n take,\n skip,\n }),\n triggerSearchBackfill: () => {\n void runDataMaintenanceInBackground();\n },\n },\n) => {\n return async (\n _: unknown,\n {\n searchFilter,\n pagination,\n }: {\n searchFilter: SearchFilter;\n pagination: Pagination;\n },\n ) => {\n const orderBy = buildAllNotesOrderBy(searchFilter);\n const limit = Number(pagination.limit);\n const offset = Number(pagination.offset);\n const where = buildAllNotesSearchWhere(searchFilter);\n\n if (!where) {\n const [notes, totalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n take: limit,\n skip: offset,\n }),\n deps.countNotes({}),\n ]);\n\n return {\n totalCount,\n notes,\n };\n }\n\n const staleCandidateNotes = await deps.findNotes({\n orderBy,\n where: buildAllNotesStaleCandidateWhere(searchFilter),\n });\n\n if (staleCandidateNotes.length === 0) {\n const [notes, totalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n where,\n take: limit,\n skip: offset,\n }),\n deps.countNotes({ where }),\n ]);\n\n return {\n totalCount,\n notes,\n };\n }\n\n deps.triggerSearchBackfill();\n\n const parsedQuery = parseNoteSearchQuery(searchFilter.query);\n const staleNotes = filterNotesBySearchQuery(staleCandidateNotes, parsedQuery);\n\n if (staleNotes.length === 0) {\n const [notes, totalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n where,\n take: limit,\n skip: offset,\n }),\n deps.countNotes({ where }),\n ]);\n\n return {\n totalCount,\n notes,\n };\n }\n\n const [freshNotesPrefix, freshTotalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n where,\n take: offset + limit,\n }),\n deps.countNotes({ where }),\n ]);\n\n const mergedNotes = mergeSortedNotesForSearch(freshNotesPrefix, staleNotes, searchFilter);\n\n return {\n totalCount: freshTotalCount + staleNotes.length,\n notes: mergedNotes.slice(offset, offset + limit),\n };\n };\n};\n\ntype NoteQueryResolvers = NonNullable<IResolvers['Query']>;\n\nexport const noteQueryResolvers: NoteQueryResolvers = {\n allNotes: createAllNotesQueryResolver(),\n notesInDateRange: async (\n _,\n {\n dateRange,\n }: {\n dateRange: {\n start: string;\n end: string;\n };\n },\n ) => {\n const where: Prisma.NoteWhereInput = {\n OR: [\n {\n updatedAt: {\n gte: new Date(dateRange.start),\n lte: new Date(dateRange.end),\n },\n },\n {\n createdAt: {\n gte: new Date(dateRange.start),\n lte: new Date(dateRange.end),\n },\n },\n ],\n };\n\n return models.note.findMany({\n orderBy: { createdAt: 'asc' },\n where,\n });\n },\n tagNotes: async (\n _,\n {\n searchFilter,\n pagination,\n }: {\n searchFilter: SearchFilter;\n pagination: Pagination;\n },\n ) => {\n const where: Prisma.NoteWhereInput = { tags: { some: { id: Number(searchFilter.query) } } };\n const notes = models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where,\n take: Number(pagination.limit),\n skip: Number(pagination.offset),\n });\n\n return {\n totalCount: models.note.count({ where }),\n notes,\n };\n },\n notesByTagNames: async (\n _,\n {\n tagNames,\n mode,\n pagination,\n }: {\n tagNames: string[];\n mode: NoteTagMatchMode;\n pagination: Pagination;\n },\n ) => {\n const normalizedTagNames = normalizeNoteTagNames(tagNames);\n\n if (normalizedTagNames.length === 0) {\n return {\n totalCount: 0,\n notes: [],\n };\n }\n\n const where = buildNoteTagNamesWhere(normalizedTagNames, mode);\n const notes = models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where,\n take: Number(pagination.limit),\n skip: Number(pagination.offset),\n });\n\n return {\n totalCount: models.note.count({ where }),\n notes,\n };\n },\n pinnedNotes: async () =>\n models.note.findMany({\n orderBy: [{ order: 'asc' }, { updatedAt: 'desc' }],\n where: { pinned: true },\n }),\n imageNotes: async (_, { src }: { src: string }) =>\n models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where: { content: { contains: src } },\n }),\n backReferences: async (_, { id }: { id: string }) => {\n return models.note.findMany({\n orderBy: [{ pinned: 'desc' }, { updatedAt: 'desc' }],\n where: { content: { contains: `reference\",\"props\":{\"id\":\"${id}\"` } },\n });\n },\n note: async (_, { id }: { id: string }) => {\n const note = await models.note.findUnique({ where: { id: Number(id) } });\n\n if (!note) {\n throw 'NOT FOUND';\n }\n\n if (!note.content) {\n return note;\n }\n\n const blocks = extractBlocksByType<{\n id: string;\n title: string;\n }>('reference', JSON.parse(note.content));\n\n if (blocks.length === 0) {\n return note;\n }\n\n const referenceIds = blocks.map((block) => Number(block.props.id));\n const references = await models.note.findMany({ where: { id: { in: referenceIds } } });\n const newContent = references.reduce<string>((content, referenceNote: Note) => {\n const reference = blocks.find((block) => Number(block.props.id) === referenceNote.id);\n\n if (reference && reference.props.title !== referenceNote.title) {\n return content.replace(\n `reference\",\"props\":{\"id\":\"${reference.props.id}\",\"title\":\"${reference.props.title}\"`,\n `reference\",\"props\":{\"id\":\"${referenceNote.id}\",\"title\":\"${referenceNote.title}\"`,\n );\n }\n\n return content;\n }, note.content);\n\n if (newContent === note.content) {\n return note;\n }\n\n try {\n JSON.parse(newContent);\n\n return await models.note.update({\n where: { id: note.id },\n data: { content: newContent },\n });\n } catch {\n // Keep the stored content unchanged if the synchronized payload becomes invalid.\n return note;\n }\n },\n noteCleanupCandidates: async (\n _,\n {\n query,\n pagination = {\n limit: 20,\n offset: 0,\n },\n }: {\n query?: string;\n pagination: Pagination;\n },\n ) => {\n const result = await listNoteCleanupCandidates({\n keywords: query\n ? query\n .split(/[,\\s]+/)\n .map((keyword) => keyword.trim())\n .filter(Boolean)\n : undefined,\n limit: Number(pagination.limit),\n offset: Number(pagination.offset),\n });\n\n return result.notes;\n },\n noteCleanupPreview: async (_, { id }: { id: string }) => {\n return getNoteCleanupPreview(Number(id));\n },\n noteSnapshots: async (\n _,\n {\n id,\n limit = 5,\n }: {\n id: string;\n limit?: number;\n },\n ) => {\n return listNoteSnapshots(Number(id), Number(limit));\n },\n trashedNote: async (_, { id }: { id: string }) => {\n return getTrashedNoteById(Number(id));\n },\n trashedNotes: async (\n _,\n {\n pagination = {\n limit: 25,\n offset: 0,\n },\n }: {\n pagination: Pagination;\n },\n ) => {\n return listTrashedNotes({\n limit: Number(pagination.limit),\n offset: Number(pagination.offset),\n });\n },\n noteGraph: async () => {\n const notes = await models.note.findMany({\n select: {\n id: true,\n title: true,\n content: true,\n },\n });\n\n const nodes: Array<{ id: string; title: string; connections: number }> = [];\n const links: Array<{ source: string; target: string }> = [];\n const connectionCount: Record<string, number> = {};\n const linkSet = new Set<string>();\n\n for (const note of notes) {\n if (!note.content) {\n continue;\n }\n\n try {\n const blocks = extractBlocksByType<{ id: string }>('reference', JSON.parse(note.content));\n\n for (const block of blocks) {\n const targetId = block.props.id;\n\n if (targetId && String(note.id) !== targetId) {\n const linkKey = `${note.id}-${targetId}`;\n const reverseLinkKey = `${targetId}-${note.id}`;\n\n if (!linkSet.has(linkKey) && !linkSet.has(reverseLinkKey)) {\n linkSet.add(linkKey);\n links.push({\n source: String(note.id),\n target: targetId,\n });\n connectionCount[String(note.id)] = (connectionCount[String(note.id)] || 0) + 1;\n connectionCount[targetId] = (connectionCount[targetId] || 0) + 1;\n }\n }\n }\n } catch {\n // Skip notes with invalid JSON content\n }\n }\n\n for (const note of notes) {\n nodes.push({\n id: String(note.id),\n title: note.title || 'Untitled',\n connections: connectionCount[String(note.id)] || 0,\n });\n }\n\n return {\n nodes,\n links,\n };\n },\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/features/note/graphql/note.query.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport { getNoteCleanupPreview, listNoteCleanupCandidates } from '~/features/note/services/cleanup.js';\nimport {\n buildNoteGraph,\n contentReferencesNote,\n extractReferenceBlocksFromContent,\n normalizeReferenceId,\n syncReferenceTitlesInContent,\n} from '~/features/note/services/content-blocks.js';\nimport { listNotePropertyKeys } from '~/features/note/services/properties.js';\nimport {\n buildNoteSearchProjection,\n filterNotesBySearchQuery,\n NOTE_SEARCH_TEXT_SCHEMA_VERSION,\n parseNoteSearchQuery,\n} from '~/features/note/services/search.js';\nimport { getNoteSnapshot, listNoteSnapshots } from '~/features/note/services/snapshot.js';\nimport {\n buildNoteTagNamesWhere,\n type NoteTagMatchMode,\n normalizeNoteTagNames,\n} from '~/features/note/services/tag-filter.js';\nimport { getTrashedNoteById, listTrashedNotes } from '~/features/note/services/trash.js';\nimport type { Note, Prisma } from '~/models.js';\nimport models from '~/models.js';\nimport { runDataMaintenanceInBackground } from '~/modules/data-maintenance.js';\nimport type { Pagination, SearchFilter } from '~/types/index.js';\n\ninterface AllNotesResolverDeps {\n countNotes: (args: { where?: Prisma.NoteWhereInput }) => Promise<number>;\n findNotes: (args: {\n orderBy: Prisma.NoteOrderByWithRelationInput[];\n where?: Prisma.NoteWhereInput;\n take?: number;\n skip?: number;\n }) => Promise<Note[]>;\n triggerSearchBackfill: () => void;\n}\n\nconst buildAllNotesOrderBy = (searchFilter: SearchFilter) => {\n const sortBy = searchFilter.sortBy || 'updatedAt';\n const sortOrder = searchFilter.sortOrder || 'desc';\n const pinnedFirst = searchFilter.pinnedFirst || false;\n const orderBy: Prisma.NoteOrderByWithRelationInput[] = [];\n\n if (pinnedFirst) {\n orderBy.push({ pinned: 'desc' });\n }\n\n if (sortBy === 'createdAt') {\n orderBy.push({ createdAt: sortOrder as 'asc' | 'desc' });\n } else {\n orderBy.push({ updatedAt: sortOrder as 'asc' | 'desc' });\n }\n\n return orderBy;\n};\n\nconst buildAllNotesSearchWhere = (searchFilter: SearchFilter) => {\n const parsedQuery = parseNoteSearchQuery(searchFilter.query);\n\n if (!parsedQuery.hasFilters) {\n return undefined;\n }\n\n return {\n AND: [\n { searchableTextVersion: NOTE_SEARCH_TEXT_SCHEMA_VERSION },\n ...parsedQuery.included.map((keyword) => ({ searchableText: { contains: keyword } })),\n ...parsedQuery.excluded.map((keyword) => ({ NOT: { searchableText: { contains: keyword } } })),\n ],\n } satisfies Prisma.NoteWhereInput;\n};\n\nconst buildAllNotesStaleCandidateWhere = (searchFilter: SearchFilter) => {\n const parsedQuery = parseNoteSearchQuery(searchFilter.query);\n\n return {\n AND: [\n { searchableTextVersion: { not: NOTE_SEARCH_TEXT_SCHEMA_VERSION } },\n ...parsedQuery.included.map((keyword) => ({\n OR: [{ title: { contains: keyword } }, { content: { contains: keyword } }],\n })),\n ],\n } satisfies Prisma.NoteWhereInput;\n};\n\nconst compareNotesForSearch = (left: Note, right: Note, searchFilter: SearchFilter) => {\n if (searchFilter.pinnedFirst && left.pinned !== right.pinned) {\n return left.pinned ? -1 : 1;\n }\n\n const sortBy = searchFilter.sortBy || 'updatedAt';\n const sortOrder = searchFilter.sortOrder || 'desc';\n const leftValue = sortBy === 'createdAt' ? left.createdAt.getTime() : left.updatedAt.getTime();\n const rightValue = sortBy === 'createdAt' ? right.createdAt.getTime() : right.updatedAt.getTime();\n\n if (leftValue === rightValue) {\n return 0;\n }\n\n return sortOrder === 'asc' ? leftValue - rightValue : rightValue - leftValue;\n};\n\nconst mergeSortedNotesForSearch = (left: Note[], right: Note[], searchFilter: SearchFilter) => {\n const merged: Note[] = [];\n let leftIndex = 0;\n let rightIndex = 0;\n\n while (leftIndex < left.length && rightIndex < right.length) {\n if (compareNotesForSearch(left[leftIndex], right[rightIndex], searchFilter) <= 0) {\n merged.push(left[leftIndex]);\n leftIndex += 1;\n } else {\n merged.push(right[rightIndex]);\n rightIndex += 1;\n }\n }\n\n while (leftIndex < left.length) {\n merged.push(left[leftIndex]);\n leftIndex += 1;\n }\n\n while (rightIndex < right.length) {\n merged.push(right[rightIndex]);\n rightIndex += 1;\n }\n\n return merged;\n};\n\nconst isRecordNotFoundError = (error: unknown) => {\n return (\n typeof error === 'object' && error !== null && 'code' in error && (error as { code?: unknown }).code === 'P2025'\n );\n};\n\nexport const createAllNotesQueryResolver = (\n deps: AllNotesResolverDeps = {\n countNotes: ({ where }) => models.note.count({ where }),\n findNotes: ({ orderBy, where, take, skip }) =>\n models.note.findMany({\n orderBy,\n where,\n take,\n skip,\n }),\n triggerSearchBackfill: () => {\n void runDataMaintenanceInBackground();\n },\n },\n) => {\n return async (\n _: unknown,\n {\n searchFilter,\n pagination,\n }: {\n searchFilter: SearchFilter;\n pagination: Pagination;\n },\n ) => {\n const orderBy = buildAllNotesOrderBy(searchFilter);\n const limit = Number(pagination.limit);\n const offset = Number(pagination.offset);\n const where = buildAllNotesSearchWhere(searchFilter);\n\n if (!where) {\n const [notes, totalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n take: limit,\n skip: offset,\n }),\n deps.countNotes({}),\n ]);\n\n return {\n totalCount,\n notes,\n };\n }\n\n const staleCandidateNotes = await deps.findNotes({\n orderBy,\n where: buildAllNotesStaleCandidateWhere(searchFilter),\n });\n\n if (staleCandidateNotes.length === 0) {\n const [notes, totalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n where,\n take: limit,\n skip: offset,\n }),\n deps.countNotes({ where }),\n ]);\n\n return {\n totalCount,\n notes,\n };\n }\n\n deps.triggerSearchBackfill();\n\n const parsedQuery = parseNoteSearchQuery(searchFilter.query);\n const staleNotes = filterNotesBySearchQuery(staleCandidateNotes, parsedQuery);\n\n if (staleNotes.length === 0) {\n const [notes, totalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n where,\n take: limit,\n skip: offset,\n }),\n deps.countNotes({ where }),\n ]);\n\n return {\n totalCount,\n notes,\n };\n }\n\n const [freshNotesPrefix, freshTotalCount] = await Promise.all([\n deps.findNotes({\n orderBy,\n where,\n take: offset + limit,\n }),\n deps.countNotes({ where }),\n ]);\n\n const mergedNotes = mergeSortedNotesForSearch(freshNotesPrefix, staleNotes, searchFilter);\n\n return {\n totalCount: freshTotalCount + staleNotes.length,\n notes: mergedNotes.slice(offset, offset + limit),\n };\n };\n};\n\ntype NoteQueryResolvers = NonNullable<IResolvers['Query']>;\n\ninterface BackReferencesQueryResolverDeps {\n findCandidateNotes: (noteId: number) => Promise<Note[]>;\n}\n\nexport const createBackReferencesQueryResolver = (\n deps: BackReferencesQueryResolverDeps = {\n findCandidateNotes: (noteId) =>\n models.note.findMany({\n orderBy: [{ pinned: 'desc' }, { updatedAt: 'desc' }],\n where: {\n NOT: { id: noteId },\n },\n }),\n },\n) => {\n return async (_: unknown, { id }: { id: string }) => {\n const notes = await deps.findCandidateNotes(Number(id));\n\n return notes.filter((note) => contentReferencesNote(note.content, id));\n };\n};\n\ninterface NoteGraphQueryResolverDeps {\n findNotes: () => Promise<Array<Pick<Note, 'id' | 'title' | 'content'>>>;\n}\n\nexport const createNoteGraphQueryResolver = (\n deps: NoteGraphQueryResolverDeps = {\n findNotes: () =>\n models.note.findMany({\n select: {\n id: true,\n title: true,\n content: true,\n },\n }),\n },\n) => {\n return async () => {\n const notes = await deps.findNotes();\n\n return buildNoteGraph(notes);\n };\n};\n\nexport const noteQueryResolvers: NoteQueryResolvers = {\n allNotes: createAllNotesQueryResolver(),\n notesInDateRange: async (\n _,\n {\n dateRange,\n }: {\n dateRange: {\n start: string;\n end: string;\n };\n },\n ) => {\n const where: Prisma.NoteWhereInput = {\n OR: [\n {\n updatedAt: {\n gte: new Date(dateRange.start),\n lte: new Date(dateRange.end),\n },\n },\n {\n createdAt: {\n gte: new Date(dateRange.start),\n lte: new Date(dateRange.end),\n },\n },\n ],\n };\n\n return models.note.findMany({\n orderBy: { createdAt: 'asc' },\n where,\n });\n },\n tagNotes: async (\n _,\n {\n searchFilter,\n pagination,\n }: {\n searchFilter: SearchFilter;\n pagination: Pagination;\n },\n ) => {\n const where: Prisma.NoteWhereInput = { tags: { some: { id: Number(searchFilter.query) } } };\n const notes = models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where,\n take: Number(pagination.limit),\n skip: Number(pagination.offset),\n });\n\n return {\n totalCount: models.note.count({ where }),\n notes,\n };\n },\n notesByTagNames: async (\n _,\n {\n tagNames,\n mode,\n pagination,\n }: {\n tagNames: string[];\n mode: NoteTagMatchMode;\n pagination: Pagination;\n },\n ) => {\n const normalizedTagNames = normalizeNoteTagNames(tagNames);\n\n if (normalizedTagNames.length === 0) {\n return {\n totalCount: 0,\n notes: [],\n };\n }\n\n const where = buildNoteTagNamesWhere(normalizedTagNames, mode);\n const notes = models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where,\n take: Number(pagination.limit),\n skip: Number(pagination.offset),\n });\n\n return {\n totalCount: models.note.count({ where }),\n notes,\n };\n },\n pinnedNotes: async () =>\n models.note.findMany({\n orderBy: [{ order: 'asc' }, { updatedAt: 'desc' }],\n where: { pinned: true },\n }),\n imageNotes: async (_, { src }: { src: string }) =>\n models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where: { content: { contains: src } },\n }),\n backReferences: createBackReferencesQueryResolver(),\n note: async (_, { id }: { id: string }) => {\n const note = await models.note.findUnique({ where: { id: Number(id) } });\n\n if (!note) {\n throw 'NOT FOUND';\n }\n\n if (!note.content) {\n return note;\n }\n\n const blocks = extractReferenceBlocksFromContent(note.content);\n\n if (blocks.length === 0) {\n return note;\n }\n\n const referenceIds = Array.from(\n new Set(\n blocks\n .map((block) => normalizeReferenceId(block.props?.id))\n .filter((referenceId): referenceId is string => referenceId !== null)\n .map(Number)\n .filter(Number.isFinite),\n ),\n );\n const references = await models.note.findMany({ where: { id: { in: referenceIds } } });\n const titlesById = new Map(\n references.map((referenceNote: Note) => [String(referenceNote.id), referenceNote.title]),\n );\n const newContent = syncReferenceTitlesInContent(note.content, titlesById);\n\n if (!newContent || newContent === note.content) {\n return note;\n }\n\n try {\n return await models.note.update({\n where: {\n id: note.id,\n updatedAt: note.updatedAt,\n },\n data: {\n content: newContent,\n ...buildNoteSearchProjection({\n title: note.title,\n content: newContent,\n }),\n },\n });\n } catch (error) {\n if (isRecordNotFoundError(error)) {\n return note;\n }\n\n throw error;\n }\n },\n noteCleanupCandidates: async (\n _,\n {\n query,\n pagination = {\n limit: 20,\n offset: 0,\n },\n }: {\n query?: string;\n pagination: Pagination;\n },\n ) => {\n const result = await listNoteCleanupCandidates({\n keywords: query\n ? query\n .split(/[,\\s]+/)\n .map((keyword) => keyword.trim())\n .filter(Boolean)\n : undefined,\n limit: Number(pagination.limit),\n offset: Number(pagination.offset),\n });\n\n return result.notes;\n },\n noteCleanupPreview: async (_, { id }: { id: string }) => {\n return getNoteCleanupPreview(Number(id));\n },\n noteSnapshots: async (\n _,\n {\n id,\n limit = 10,\n }: {\n id: string;\n limit?: number;\n },\n ) => {\n return listNoteSnapshots(Number(id), Number(limit));\n },\n noteSnapshot: async (_, { id }: { id: string }) => {\n return getNoteSnapshot(Number(id));\n },\n notePropertyKeys: async (\n _,\n {\n query,\n pagination = {\n limit: 50,\n offset: 0,\n },\n }: {\n query?: string;\n pagination: Pagination;\n },\n ) => {\n return listNotePropertyKeys({\n query,\n limit: Number(pagination.limit),\n offset: Number(pagination.offset),\n });\n },\n trashedNote: async (_, { id }: { id: string }) => {\n return getTrashedNoteById(Number(id));\n },\n trashedNotes: async (\n _,\n {\n pagination = {\n limit: 25,\n offset: 0,\n },\n }: {\n pagination: Pagination;\n },\n ) => {\n return listTrashedNotes({\n limit: Number(pagination.limit),\n offset: Number(pagination.offset),\n });\n },\n noteGraph: createNoteGraphQueryResolver(),\n};\n"],"mappings":"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","names":[]}
@@ -1,11 +1,12 @@
1
- import { noteFieldResolvers } from "./note.field.resolver.js";
1
+ import { noteFieldResolvers, noteSnapshotFieldResolvers } from "./note.field.resolver.js";
2
2
  import { noteMutationResolvers } from "./note.mutation.resolver.js";
3
3
  import { noteQueryResolvers } from "./note.query.resolver.js";
4
4
  import { createAllNotesQueryResolver as createAllNotesQueryResolver2 } from "./note.query.resolver.js";
5
5
  const noteResolvers = {
6
6
  Query: noteQueryResolvers,
7
7
  Mutation: noteMutationResolvers,
8
- Note: noteFieldResolvers
8
+ Note: noteFieldResolvers,
9
+ NoteSnapshot: noteSnapshotFieldResolvers
9
10
  };
10
11
  export {
11
12
  createAllNotesQueryResolver2 as createAllNotesQueryResolver,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/features/note/graphql/note.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport { noteFieldResolvers } from './note.field.resolver.js';\nimport { noteMutationResolvers } from './note.mutation.resolver.js';\nimport { createAllNotesQueryResolver, noteQueryResolvers } from './note.query.resolver.js';\n\nexport { createAllNotesQueryResolver } from './note.query.resolver.js';\n\nexport const noteResolvers: IResolvers = {\n Query: noteQueryResolvers,\n Mutation: noteMutationResolvers,\n Note: noteFieldResolvers,\n};\n"],"mappings":"AACA,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAsC,0BAA0B;AAEhE,SAAS,+BAAAA,oCAAmC;AAErC,MAAM,gBAA4B;AAAA,EACrC,OAAO;AAAA,EACP,UAAU;AAAA,EACV,MAAM;AACV;","names":["createAllNotesQueryResolver"]}
1
+ {"version":3,"sources":["../../../../src/features/note/graphql/note.resolver.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport { noteFieldResolvers, noteSnapshotFieldResolvers } from './note.field.resolver.js';\nimport { noteMutationResolvers } from './note.mutation.resolver.js';\nimport { createAllNotesQueryResolver, noteQueryResolvers } from './note.query.resolver.js';\n\nexport { createAllNotesQueryResolver } from './note.query.resolver.js';\n\nexport const noteResolvers: IResolvers = {\n Query: noteQueryResolvers,\n Mutation: noteMutationResolvers,\n Note: noteFieldResolvers,\n NoteSnapshot: noteSnapshotFieldResolvers,\n};\n"],"mappings":"AACA,SAAS,oBAAoB,kCAAkC;AAC/D,SAAS,6BAA6B;AACtC,SAAsC,0BAA0B;AAEhE,SAAS,+BAAAA,oCAAmC;AAErC,MAAM,gBAA4B;AAAA,EACrC,OAAO;AAAA,EACP,UAAU;AAAA,EACV,MAAM;AAAA,EACN,cAAc;AAClB;","names":["createAllNotesQueryResolver"]}
@@ -28,12 +28,60 @@ const noteType = gql`
28
28
  or
29
29
  }
30
30
 
31
+ enum NotePropertyValueType {
32
+ text
33
+ url
34
+ number
35
+ date
36
+ boolean
37
+ select
38
+ }
39
+
31
40
  input NoteInput {
32
41
  title: String
33
42
  content: String
34
43
  layout: NoteLayout
35
44
  }
36
45
 
46
+ input NotePropertySetInput {
47
+ key: String!
48
+ name: String
49
+ value: String!
50
+ valueType: NotePropertyValueType!
51
+ }
52
+
53
+ input NotePropertyOptionInput {
54
+ label: String!
55
+ value: String
56
+ color: String
57
+ order: Int
58
+ }
59
+
60
+ input NotePropertyOptionUpdateInput {
61
+ id: ID
62
+ label: String!
63
+ value: String
64
+ color: String
65
+ order: Int
66
+ }
67
+
68
+ input NotePropertyDefinitionInput {
69
+ key: String!
70
+ name: String
71
+ valueType: NotePropertyValueType!
72
+ options: [NotePropertyOptionInput!]
73
+ }
74
+
75
+ input NotePropertyDefinitionUpdateInput {
76
+ name: String
77
+ options: [NotePropertyOptionUpdateInput!]
78
+ }
79
+
80
+ input NotePropertiesPatchInput {
81
+ set: [NotePropertySetInput!]
82
+ deleteKeys: [String!]
83
+ }
84
+
37
85
  input NoteOrderInput {
38
86
  id: ID!
39
87
  order: Int!
@@ -57,6 +105,47 @@ const noteType = gql`
57
105
  order: Int!
58
106
  layout: NoteLayout!
59
107
  tags: [Tag!]!
108
+ properties: [NoteProperty!]!
109
+ }
110
+
111
+ type NoteProperty {
112
+ key: String!
113
+ name: String!
114
+ value: String!
115
+ valueType: NotePropertyValueType!
116
+ createdAt: String!
117
+ option: NotePropertyOption
118
+ updatedAt: String!
119
+ }
120
+
121
+ type NotePropertyOption {
122
+ id: ID!
123
+ label: String!
124
+ value: String!
125
+ color: String
126
+ order: Int!
127
+ }
128
+
129
+ type NotePropertyKey {
130
+ key: String!
131
+ name: String!
132
+ valueType: NotePropertyValueType!
133
+ noteCount: Int!
134
+ options: [NotePropertyOption!]!
135
+ updatedAt: String!
136
+ }
137
+
138
+ type NotePropertyKeys {
139
+ totalCount: Int!
140
+ keys: [NotePropertyKey!]!
141
+ }
142
+
143
+ type NotePropertyDeleteResult {
144
+ key: String!
145
+ name: String!
146
+ valueType: NotePropertyValueType!
147
+ affectedNoteCount: Int!
148
+ deleted: Boolean!
60
149
  }
61
150
 
62
151
  type Notes {
@@ -104,6 +193,8 @@ const noteType = gql`
104
193
  type NoteSnapshot {
105
194
  id: ID!
106
195
  title: String!
196
+ contentPreview: String!
197
+ contentAsMarkdown: String!
107
198
  createdAt: String!
108
199
  meta: NoteSnapshotMeta!
109
200
  }
@@ -156,6 +247,8 @@ const noteQuery = gql`
156
247
  noteCleanupCandidates(query: String, pagination: PaginationInput): [NoteCleanupCandidate!]!
157
248
  noteCleanupPreview(id: ID!): NoteCleanupPreview
158
249
  noteSnapshots(id: ID!, limit: Int): [NoteSnapshot!]!
250
+ noteSnapshot(id: ID!): NoteSnapshot
251
+ notePropertyKeys(query: String, pagination: PaginationInput): NotePropertyKeys!
159
252
  trashedNote(id: ID!): DeletedNote
160
253
  trashedNotes(pagination: PaginationInput): DeletedNotes!
161
254
  noteGraph: NoteGraph!
@@ -164,11 +257,21 @@ const noteQuery = gql`
164
257
  const noteMutation = gql`
165
258
  type Mutation {
166
259
  createNote(note: NoteInput!): Note!
167
- updateNote(id: ID!, note: NoteInput!, editSessionId: String): Note!
260
+ updateNote(id: ID!, note: NoteInput!, editSessionId: String, expectedUpdatedAt: String, force: Boolean): Note!
168
261
  deleteNote(id: ID!): Boolean!
169
262
  restoreNoteSnapshot(id: ID!): Note!
170
263
  restoreTrashedNote(id: ID!): Note!
171
264
  purgeTrashedNote(id: ID!): Boolean!
265
+ createNotePropertyKey(input: NotePropertyDefinitionInput!): NotePropertyKey!
266
+ updateNotePropertyKey(key: String!, input: NotePropertyDefinitionUpdateInput!): NotePropertyKey!
267
+ deleteNotePropertyKey(key: String!, confirmImpact: Boolean): NotePropertyDeleteResult!
268
+ updateNoteProperties(
269
+ id: ID!
270
+ patch: NotePropertiesPatchInput!
271
+ editSessionId: String
272
+ expectedUpdatedAt: String!
273
+ force: Boolean
274
+ ): Note!
172
275
  pinNote(id: ID!, pinned: Boolean!): Note!
173
276
  reorderNotes(notes: [NoteOrderInput!]!): [Note!]!
174
277
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/features/note/graphql/note.type-defs.ts"],"sourcesContent":["import { gql } from '~/modules/graphql.js';\n\nexport const noteType = gql`\n input PaginationInput {\n limit: Int!\n offset: Int!\n }\n\n input SearchFilterInput {\n query: String!\n sortBy: String\n sortOrder: String\n pinnedFirst: Boolean\n }\n\n input DateRangeInput {\n start: String!\n end: String!\n }\n\n enum NoteLayout {\n narrow\n wide\n full\n }\n\n enum TagMatchMode {\n and\n or\n }\n\n input NoteInput {\n title: String\n content: String\n layout: NoteLayout\n }\n\n input NoteOrderInput {\n id: ID!\n order: Int!\n }\n\n type Tag {\n id: ID!\n name: String!\n createdAt: String!\n updatedAt: String!\n }\n\n type Note {\n id: ID!\n title: String!\n content: String!\n contentAsMarkdown: String!\n createdAt: String!\n updatedAt: String!\n pinned: Boolean!\n order: Int!\n layout: NoteLayout!\n tags: [Tag!]!\n }\n\n type Notes {\n totalCount: Int!\n notes: [Note!]!\n }\n\n type NoteCleanupBackReference {\n id: ID!\n title: String!\n }\n\n type NoteCleanupCandidate {\n id: ID!\n title: String!\n updatedAt: String!\n pinned: Boolean!\n tagNames: [String!]!\n reminderCount: Int!\n backReferenceCount: Int!\n matchedTerms: [String!]!\n reasons: [String!]!\n requiresForce: Boolean!\n forceReasons: [String!]!\n }\n\n type NoteCleanupPreview {\n id: ID!\n title: String!\n updatedAt: String!\n pinned: Boolean!\n tagNames: [String!]!\n reminderCount: Int!\n backReferences: [NoteCleanupBackReference!]!\n orphanedTagNames: [String!]!\n requiresForce: Boolean!\n forceReasons: [String!]!\n }\n\n type NoteSnapshotMeta {\n entrypoint: String\n label: String\n }\n\n type NoteSnapshot {\n id: ID!\n title: String!\n createdAt: String!\n meta: NoteSnapshotMeta!\n }\n\n type DeletedNote {\n id: ID!\n title: String!\n createdAt: String!\n updatedAt: String!\n deletedAt: String!\n contentPreview: String!\n contentAsMarkdown: String\n pinned: Boolean!\n order: Int!\n layout: NoteLayout!\n tagNames: [String!]!\n }\n\n type DeletedNotes {\n totalCount: Int!\n notes: [DeletedNote!]!\n }\n`;\n\nexport const noteQuery = gql`\n type GraphNode {\n id: ID!\n title: String!\n connections: Int!\n }\n\n type GraphLink {\n source: ID!\n target: ID!\n }\n\n type NoteGraph {\n nodes: [GraphNode!]!\n links: [GraphLink!]!\n }\n\n type Query {\n allNotes(searchFilter: SearchFilterInput, pagination: PaginationInput): Notes!\n tagNotes(searchFilter: SearchFilterInput, pagination: PaginationInput): Notes!\n notesByTagNames(tagNames: [String!]!, mode: TagMatchMode!, pagination: PaginationInput): Notes!\n notesInDateRange(dateRange: DateRangeInput): [Note!]!\n pinnedNotes: [Note!]!\n imageNotes(src: String!): [Note!]!\n backReferences(id: ID!): [Note]!\n note(id: ID!): Note!\n noteCleanupCandidates(query: String, pagination: PaginationInput): [NoteCleanupCandidate!]!\n noteCleanupPreview(id: ID!): NoteCleanupPreview\n noteSnapshots(id: ID!, limit: Int): [NoteSnapshot!]!\n trashedNote(id: ID!): DeletedNote\n trashedNotes(pagination: PaginationInput): DeletedNotes!\n noteGraph: NoteGraph!\n }\n`;\n\nexport const noteMutation = gql`\n type Mutation {\n createNote(note: NoteInput!): Note!\n updateNote(id: ID!, note: NoteInput!, editSessionId: String): Note!\n deleteNote(id: ID!): Boolean!\n restoreNoteSnapshot(id: ID!): Note!\n restoreTrashedNote(id: ID!): Note!\n purgeTrashedNote(id: ID!): Boolean!\n pinNote(id: ID!, pinned: Boolean!): Note!\n reorderNotes(notes: [NoteOrderInput!]!): [Note!]!\n }\n`;\n\nexport const noteTypeDefs = `\n ${noteType}\n ${noteQuery}\n ${noteMutation}\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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiIjB,MAAM,YAAY;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;AAmClB,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAarB,MAAM,eAAe;AAAA,MACtB,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../../../src/features/note/graphql/note.type-defs.ts"],"sourcesContent":["import { gql } from '~/modules/graphql.js';\n\nexport const noteType = gql`\n input PaginationInput {\n limit: Int!\n offset: Int!\n }\n\n input SearchFilterInput {\n query: String!\n sortBy: String\n sortOrder: String\n pinnedFirst: Boolean\n }\n\n input DateRangeInput {\n start: String!\n end: String!\n }\n\n enum NoteLayout {\n narrow\n wide\n full\n }\n\n enum TagMatchMode {\n and\n or\n }\n\n enum NotePropertyValueType {\n text\n url\n number\n date\n boolean\n select\n }\n\n input NoteInput {\n title: String\n content: String\n layout: NoteLayout\n }\n\n input NotePropertySetInput {\n key: String!\n name: String\n value: String!\n valueType: NotePropertyValueType!\n }\n\n input NotePropertyOptionInput {\n label: String!\n value: String\n color: String\n order: Int\n }\n\n input NotePropertyOptionUpdateInput {\n id: ID\n label: String!\n value: String\n color: String\n order: Int\n }\n\n input NotePropertyDefinitionInput {\n key: String!\n name: String\n valueType: NotePropertyValueType!\n options: [NotePropertyOptionInput!]\n }\n\n input NotePropertyDefinitionUpdateInput {\n name: String\n options: [NotePropertyOptionUpdateInput!]\n }\n\n input NotePropertiesPatchInput {\n set: [NotePropertySetInput!]\n deleteKeys: [String!]\n }\n\n input NoteOrderInput {\n id: ID!\n order: Int!\n }\n\n type Tag {\n id: ID!\n name: String!\n createdAt: String!\n updatedAt: String!\n }\n\n type Note {\n id: ID!\n title: String!\n content: String!\n contentAsMarkdown: String!\n createdAt: String!\n updatedAt: String!\n pinned: Boolean!\n order: Int!\n layout: NoteLayout!\n tags: [Tag!]!\n properties: [NoteProperty!]!\n }\n\n type NoteProperty {\n key: String!\n name: String!\n value: String!\n valueType: NotePropertyValueType!\n createdAt: String!\n option: NotePropertyOption\n updatedAt: String!\n }\n\n type NotePropertyOption {\n id: ID!\n label: String!\n value: String!\n color: String\n order: Int!\n }\n\n type NotePropertyKey {\n key: String!\n name: String!\n valueType: NotePropertyValueType!\n noteCount: Int!\n options: [NotePropertyOption!]!\n updatedAt: String!\n }\n\n type NotePropertyKeys {\n totalCount: Int!\n keys: [NotePropertyKey!]!\n }\n\n type NotePropertyDeleteResult {\n key: String!\n name: String!\n valueType: NotePropertyValueType!\n affectedNoteCount: Int!\n deleted: Boolean!\n }\n\n type Notes {\n totalCount: Int!\n notes: [Note!]!\n }\n\n type NoteCleanupBackReference {\n id: ID!\n title: String!\n }\n\n type NoteCleanupCandidate {\n id: ID!\n title: String!\n updatedAt: String!\n pinned: Boolean!\n tagNames: [String!]!\n reminderCount: Int!\n backReferenceCount: Int!\n matchedTerms: [String!]!\n reasons: [String!]!\n requiresForce: Boolean!\n forceReasons: [String!]!\n }\n\n type NoteCleanupPreview {\n id: ID!\n title: String!\n updatedAt: String!\n pinned: Boolean!\n tagNames: [String!]!\n reminderCount: Int!\n backReferences: [NoteCleanupBackReference!]!\n orphanedTagNames: [String!]!\n requiresForce: Boolean!\n forceReasons: [String!]!\n }\n\n type NoteSnapshotMeta {\n entrypoint: String\n label: String\n }\n\n type NoteSnapshot {\n id: ID!\n title: String!\n contentPreview: String!\n contentAsMarkdown: String!\n createdAt: String!\n meta: NoteSnapshotMeta!\n }\n\n type DeletedNote {\n id: ID!\n title: String!\n createdAt: String!\n updatedAt: String!\n deletedAt: String!\n contentPreview: String!\n contentAsMarkdown: String\n pinned: Boolean!\n order: Int!\n layout: NoteLayout!\n tagNames: [String!]!\n }\n\n type DeletedNotes {\n totalCount: Int!\n notes: [DeletedNote!]!\n }\n`;\n\nexport const noteQuery = gql`\n type GraphNode {\n id: ID!\n title: String!\n connections: Int!\n }\n\n type GraphLink {\n source: ID!\n target: ID!\n }\n\n type NoteGraph {\n nodes: [GraphNode!]!\n links: [GraphLink!]!\n }\n\n type Query {\n allNotes(searchFilter: SearchFilterInput, pagination: PaginationInput): Notes!\n tagNotes(searchFilter: SearchFilterInput, pagination: PaginationInput): Notes!\n notesByTagNames(tagNames: [String!]!, mode: TagMatchMode!, pagination: PaginationInput): Notes!\n notesInDateRange(dateRange: DateRangeInput): [Note!]!\n pinnedNotes: [Note!]!\n imageNotes(src: String!): [Note!]!\n backReferences(id: ID!): [Note]!\n note(id: ID!): Note!\n noteCleanupCandidates(query: String, pagination: PaginationInput): [NoteCleanupCandidate!]!\n noteCleanupPreview(id: ID!): NoteCleanupPreview\n noteSnapshots(id: ID!, limit: Int): [NoteSnapshot!]!\n noteSnapshot(id: ID!): NoteSnapshot\n notePropertyKeys(query: String, pagination: PaginationInput): NotePropertyKeys!\n trashedNote(id: ID!): DeletedNote\n trashedNotes(pagination: PaginationInput): DeletedNotes!\n noteGraph: NoteGraph!\n }\n`;\n\nexport const noteMutation = gql`\n type Mutation {\n createNote(note: NoteInput!): Note!\n updateNote(id: ID!, note: NoteInput!, editSessionId: String, expectedUpdatedAt: String, force: Boolean): Note!\n deleteNote(id: ID!): Boolean!\n restoreNoteSnapshot(id: ID!): Note!\n restoreTrashedNote(id: ID!): Note!\n purgeTrashedNote(id: ID!): Boolean!\n createNotePropertyKey(input: NotePropertyDefinitionInput!): NotePropertyKey!\n updateNotePropertyKey(key: String!, input: NotePropertyDefinitionUpdateInput!): NotePropertyKey!\n deleteNotePropertyKey(key: String!, confirmImpact: Boolean): NotePropertyDeleteResult!\n updateNoteProperties(\n id: ID!\n patch: NotePropertiesPatchInput!\n editSessionId: String\n expectedUpdatedAt: String!\n force: Boolean\n ): Note!\n pinNote(id: ID!, pinned: Boolean!): Note!\n reorderNotes(notes: [NoteOrderInput!]!): [Note!]!\n }\n`;\n\nexport const noteTypeDefs = `\n ${noteType}\n ${noteQuery}\n ${noteMutation}\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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4NjB,MAAM,YAAY;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;AAqClB,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBrB,MAAM,eAAe;AAAA,MACtB,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA;","names":[]}