ocean-brain 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/dist/mcp.js +151 -37
  2. package/package.json +5 -5
  3. package/scripts/postinstall-prisma.mjs +3 -2
  4. package/server/client/dist/assets/Calendar-CSXEuWmQ.js +25 -0
  5. package/server/client/dist/assets/Callout-Ap1OcxWN.js +1 -0
  6. package/server/client/dist/assets/Graph-C0Ax9qjI.js +1 -0
  7. package/server/client/dist/assets/{Image-ZxF459sC.js → Image-CSbcG-5a.js} +1 -1
  8. package/server/client/dist/assets/{Image.es-CFTbON7k.js → Image.es-Fbe7aDDo.js} +1 -1
  9. package/server/client/dist/assets/{ModalActionRow-Hg6MY61u.js → ModalActionRow-DjI5b4bl.js} +1 -1
  10. package/server/client/dist/assets/Note-BY6WgYLq.js +1 -0
  11. package/server/client/dist/assets/Note-W4f6H9K0.css +1 -0
  12. package/server/client/dist/assets/Reminders-vRksvSQE.js +1 -0
  13. package/server/client/dist/assets/Search-Cq4tuiJO.js +1 -0
  14. package/server/client/dist/assets/{SurfaceCard-BV6y4bCo.js → SurfaceCard-Br6TjX5W.js} +1 -1
  15. package/server/client/dist/assets/Tag-ARDLA-Pb.js +1 -0
  16. package/server/client/dist/assets/TagNotes-CDGVrCJU.js +1 -0
  17. package/server/client/dist/assets/{Trash.es-CPtRLE0y.js → Trash.es-BfCEiL3-.js} +1 -1
  18. package/server/client/dist/assets/ViewNotes-ZBOQ1adH.js +1 -0
  19. package/server/client/dist/assets/Views-DQHPfdwM.js +1 -0
  20. package/server/client/dist/assets/{image.api-Dsrx9S-G.js → image.api-DGXlQ_Ca.js} +1 -1
  21. package/server/client/dist/assets/index-B28TO4FC.js +1 -0
  22. package/server/client/dist/assets/{index-CD2bFEqK.css → index-Bm9l_L20.css} +1 -1
  23. package/server/client/dist/assets/index-Bsx4P7EA.js +210 -0
  24. package/server/client/dist/assets/manage-image-Dg297A_h.js +1 -0
  25. package/server/client/dist/assets/manage-image-detail-hk6jWyiB.js +1 -0
  26. package/server/client/dist/assets/mcp-CSjmBjFR.js +1 -0
  27. package/server/client/dist/assets/{note-core-BCgMq5QA.js → note-core-GgFcksAF.js} +1 -1
  28. package/server/client/dist/assets/{note-vendor-BofYbzmZ.js → note-vendor-5N5mRkIT.js} +3 -3
  29. package/server/client/dist/assets/{placeholder-MNsco0AT.js → placeholder-Bmiowo28.js} +4 -4
  30. package/server/client/dist/assets/trash-CM7SbVtW.js +1 -0
  31. package/server/client/dist/assets/{useReminderMutate-yJak8FzP.js → useReminderMutate-DsIvVpCQ.js} +2 -2
  32. package/server/client/dist/assets/view-dashboard-CP8nhfxQ.js +90 -0
  33. package/server/client/dist/index.html +4 -4
  34. package/server/dist/app.js +8 -84
  35. package/server/dist/app.js.map +1 -1
  36. package/server/dist/features/auth/http/api.js +43 -0
  37. package/server/dist/features/auth/http/api.js.map +1 -0
  38. package/server/dist/features/auth/http/login-page.js +28 -0
  39. package/server/dist/features/auth/http/login-page.js.map +1 -0
  40. package/server/dist/features/auth/http/pages.js +50 -0
  41. package/server/dist/features/auth/http/pages.js.map +1 -0
  42. package/server/dist/features/auth/service.js +94 -0
  43. package/server/dist/features/auth/service.js.map +1 -0
  44. package/server/dist/features/cache/graphql/cache.field.resolver.js +5 -0
  45. package/server/dist/features/cache/graphql/cache.field.resolver.js.map +1 -0
  46. package/server/dist/features/cache/graphql/cache.mutation.resolver.js +49 -0
  47. package/server/dist/features/cache/graphql/cache.mutation.resolver.js.map +1 -0
  48. package/server/dist/features/cache/graphql/cache.query.resolver.js +21 -0
  49. package/server/dist/features/cache/graphql/cache.query.resolver.js.map +1 -0
  50. package/server/dist/features/cache/graphql/cache.resolver.js +12 -0
  51. package/server/dist/features/cache/graphql/cache.resolver.js.map +1 -0
  52. package/server/dist/features/cache/graphql/cache.type-defs.js +32 -0
  53. package/server/dist/features/cache/graphql/cache.type-defs.js.map +1 -0
  54. package/server/dist/features/cache/graphql/index.js +21 -0
  55. package/server/dist/features/cache/graphql/index.js.map +1 -0
  56. package/server/dist/features/image/graphql/image.field.resolver.js +14 -0
  57. package/server/dist/features/image/graphql/image.field.resolver.js.map +1 -0
  58. package/server/dist/features/image/graphql/image.mutation.resolver.js +21 -0
  59. package/server/dist/features/image/graphql/image.mutation.resolver.js.map +1 -0
  60. package/server/dist/features/image/graphql/image.query.resolver.js +40 -0
  61. package/server/dist/features/image/graphql/image.query.resolver.js.map +1 -0
  62. package/server/dist/features/image/graphql/image.resolver.js +12 -0
  63. package/server/dist/features/image/graphql/image.resolver.js.map +1 -0
  64. package/server/dist/features/image/graphql/image.type-defs.js +31 -0
  65. package/server/dist/features/image/graphql/image.type-defs.js.map +1 -0
  66. package/server/dist/features/image/graphql/index.js +16 -0
  67. package/server/dist/features/image/graphql/index.js.map +1 -0
  68. package/server/dist/features/image/http/upload.js +48 -0
  69. package/server/dist/features/image/http/upload.js.map +1 -0
  70. package/server/dist/features/image/services/delete.js +52 -0
  71. package/server/dist/features/image/services/delete.js.map +1 -0
  72. package/server/dist/{modules/remote-image.js → features/image/services/remote-fetch.js} +1 -1
  73. package/server/dist/features/image/services/remote-fetch.js.map +1 -0
  74. package/server/dist/{modules/image-upload.js → features/image/services/upload.js} +4 -8
  75. package/server/dist/features/image/services/upload.js.map +1 -0
  76. package/server/dist/{views/mcp-admin.js → features/mcp-admin/http/handlers.js} +3 -3
  77. package/server/dist/features/mcp-admin/http/handlers.js.map +1 -0
  78. package/server/dist/{modules/mcp-admin.js → features/mcp-admin/service.js} +3 -3
  79. package/server/dist/features/mcp-admin/service.js.map +1 -0
  80. package/server/dist/features/note/graphql/index.js +8 -0
  81. package/server/dist/features/note/graphql/index.js.map +1 -0
  82. package/server/dist/features/note/graphql/note.field.resolver.js +12 -0
  83. package/server/dist/features/note/graphql/note.field.resolver.js.map +1 -0
  84. package/server/dist/features/note/graphql/note.graphql.shared.js +23 -0
  85. package/server/dist/features/note/graphql/note.graphql.shared.js.map +1 -0
  86. package/server/dist/features/note/graphql/note.mutation.resolver.js +140 -0
  87. package/server/dist/features/note/graphql/note.mutation.resolver.js.map +1 -0
  88. package/server/dist/features/note/graphql/note.query.resolver.js +382 -0
  89. package/server/dist/features/note/graphql/note.query.resolver.js.map +1 -0
  90. package/server/dist/features/note/graphql/note.resolver.js +14 -0
  91. package/server/dist/features/note/graphql/note.resolver.js.map +1 -0
  92. package/server/dist/features/note/graphql/note.type-defs.js +184 -0
  93. package/server/dist/features/note/graphql/note.type-defs.js.map +1 -0
  94. package/server/dist/{views/note.js → features/note/http/mcp.js} +27 -15
  95. package/server/dist/features/note/http/mcp.js.map +1 -0
  96. package/server/dist/{modules/note-authoring.js → features/note/services/authoring.js} +25 -7
  97. package/server/dist/features/note/services/authoring.js.map +1 -0
  98. package/server/dist/{modules/note-cleanup.js → features/note/services/cleanup.js} +14 -23
  99. package/server/dist/features/note/services/cleanup.js.map +1 -0
  100. package/server/dist/features/note/services/search-backfill.js +84 -0
  101. package/server/dist/features/note/services/search-backfill.js.map +1 -0
  102. package/server/dist/features/note/services/search.js +197 -0
  103. package/server/dist/features/note/services/search.js.map +1 -0
  104. package/server/dist/{modules/note-snapshot.js → features/note/services/snapshot.js} +51 -49
  105. package/server/dist/features/note/services/snapshot.js.map +1 -0
  106. package/server/dist/features/note/services/tag-filter.js +18 -0
  107. package/server/dist/features/note/services/tag-filter.js.map +1 -0
  108. package/server/dist/{modules/note-trash.js → features/note/services/trash.js} +28 -23
  109. package/server/dist/features/note/services/trash.js.map +1 -0
  110. package/server/dist/features/placeholder/graphql/index.js +27 -0
  111. package/server/dist/features/placeholder/graphql/index.js.map +1 -0
  112. package/server/dist/features/placeholder/graphql/placeholder.field.resolver.js +5 -0
  113. package/server/dist/features/placeholder/graphql/placeholder.field.resolver.js.map +1 -0
  114. package/server/dist/features/placeholder/graphql/placeholder.mutation.resolver.js +72 -0
  115. package/server/dist/features/placeholder/graphql/placeholder.mutation.resolver.js.map +1 -0
  116. package/server/dist/features/placeholder/graphql/placeholder.query.resolver.js +36 -0
  117. package/server/dist/features/placeholder/graphql/placeholder.query.resolver.js.map +1 -0
  118. package/server/dist/features/placeholder/graphql/placeholder.resolver.js +12 -0
  119. package/server/dist/features/placeholder/graphql/placeholder.resolver.js.map +1 -0
  120. package/server/dist/features/placeholder/graphql/placeholder.type-defs.js +50 -0
  121. package/server/dist/features/placeholder/graphql/placeholder.type-defs.js.map +1 -0
  122. package/server/dist/features/reminder/graphql/index.js +27 -0
  123. package/server/dist/features/reminder/graphql/index.js.map +1 -0
  124. package/server/dist/features/reminder/graphql/reminder.field.resolver.js +10 -0
  125. package/server/dist/features/reminder/graphql/reminder.field.resolver.js.map +1 -0
  126. package/server/dist/features/reminder/graphql/reminder.mutation.resolver.js +59 -0
  127. package/server/dist/features/reminder/graphql/reminder.mutation.resolver.js.map +1 -0
  128. package/server/dist/features/reminder/graphql/reminder.query.resolver.js +79 -0
  129. package/server/dist/features/reminder/graphql/reminder.query.resolver.js.map +1 -0
  130. package/server/dist/features/reminder/graphql/reminder.resolver.js +12 -0
  131. package/server/dist/features/reminder/graphql/reminder.resolver.js.map +1 -0
  132. package/server/dist/features/reminder/graphql/reminder.type-defs.js +51 -0
  133. package/server/dist/features/reminder/graphql/reminder.type-defs.js.map +1 -0
  134. package/server/dist/features/tag/graphql/index.js +14 -0
  135. package/server/dist/features/tag/graphql/index.js.map +1 -0
  136. package/server/dist/features/tag/graphql/tag.field.resolver.js +10 -0
  137. package/server/dist/features/tag/graphql/tag.field.resolver.js.map +1 -0
  138. package/server/dist/features/tag/graphql/tag.mutation.resolver.js +15 -0
  139. package/server/dist/features/tag/graphql/tag.mutation.resolver.js.map +1 -0
  140. package/server/dist/features/tag/graphql/tag.query.resolver.js +26 -0
  141. package/server/dist/features/tag/graphql/tag.query.resolver.js.map +1 -0
  142. package/server/dist/features/tag/graphql/tag.resolver.js +12 -0
  143. package/server/dist/features/tag/graphql/tag.resolver.js.map +1 -0
  144. package/server/dist/features/tag/graphql/tag.type-defs.js +46 -0
  145. package/server/dist/features/tag/graphql/tag.type-defs.js.map +1 -0
  146. package/server/dist/{views/tag.js → features/tag/http/mcp.js} +3 -3
  147. package/server/dist/features/tag/http/mcp.js.map +1 -0
  148. package/server/dist/{modules/tag-organization.js → features/tag/services/organization.js} +38 -8
  149. package/server/dist/features/tag/services/organization.js.map +1 -0
  150. package/server/dist/features/view/graphql/index.js +11 -0
  151. package/server/dist/features/view/graphql/index.js.map +1 -0
  152. package/server/dist/features/view/graphql/view.mutation.resolver.js +53 -0
  153. package/server/dist/features/view/graphql/view.mutation.resolver.js.map +1 -0
  154. package/server/dist/features/view/graphql/view.query.resolver.js +29 -0
  155. package/server/dist/features/view/graphql/view.query.resolver.js.map +1 -0
  156. package/server/dist/features/view/graphql/view.resolver.js +10 -0
  157. package/server/dist/features/view/graphql/view.resolver.js.map +1 -0
  158. package/server/dist/features/view/graphql/view.type-defs.js +63 -0
  159. package/server/dist/features/view/graphql/view.type-defs.js.map +1 -0
  160. package/server/dist/features/view/services/workspace.js +432 -0
  161. package/server/dist/features/view/services/workspace.js.map +1 -0
  162. package/server/dist/main.js +14 -0
  163. package/server/dist/main.js.map +1 -1
  164. package/server/dist/modules/auth-guard.js +10 -9
  165. package/server/dist/modules/auth-guard.js.map +1 -1
  166. package/server/dist/modules/auth-mode.js +1 -3
  167. package/server/dist/modules/auth-mode.js.map +1 -1
  168. package/server/dist/modules/blocknote.js +96 -33
  169. package/server/dist/modules/blocknote.js.map +1 -1
  170. package/server/dist/modules/data-maintenance.js +75 -0
  171. package/server/dist/modules/data-maintenance.js.map +1 -0
  172. package/server/dist/modules/error-handler.js.map +1 -1
  173. package/server/dist/modules/logger.js +5 -23
  174. package/server/dist/modules/logger.js.map +1 -1
  175. package/server/dist/modules/mcp-auth.js +4 -5
  176. package/server/dist/modules/mcp-auth.js.map +1 -1
  177. package/server/dist/modules/mcp-token.js.map +1 -1
  178. package/server/dist/modules/prisma-runtime.js +2 -7
  179. package/server/dist/modules/prisma-runtime.js.map +1 -1
  180. package/server/dist/modules/recovery-retention.js +1 -1
  181. package/server/dist/modules/recovery-retention.js.map +1 -1
  182. package/server/dist/modules/server-events-handler.js +34 -0
  183. package/server/dist/modules/server-events-handler.js.map +1 -0
  184. package/server/dist/modules/server-events.js +32 -0
  185. package/server/dist/modules/server-events.js.map +1 -0
  186. package/server/dist/modules/use-async.js.map +1 -1
  187. package/server/dist/paths.js.map +1 -1
  188. package/server/dist/routes/api.js +34 -0
  189. package/server/dist/routes/api.js.map +1 -0
  190. package/server/dist/routes/auth-pages.js +11 -0
  191. package/server/dist/routes/auth-pages.js.map +1 -0
  192. package/server/dist/routes/client.js +27 -0
  193. package/server/dist/routes/client.js.map +1 -0
  194. package/server/dist/routes/graphql.js +33 -0
  195. package/server/dist/routes/graphql.js.map +1 -0
  196. package/server/dist/routes/index.js +11 -0
  197. package/server/dist/routes/index.js.map +1 -0
  198. package/server/dist/routes/mcp.js +30 -0
  199. package/server/dist/routes/mcp.js.map +1 -0
  200. package/server/dist/schema/index.js +11 -8
  201. package/server/dist/schema/index.js.map +1 -1
  202. package/server/dist/types/index.js.map +1 -1
  203. package/server/prisma/migrations/20260413143000_0014_tag_name_unique/migration.sql +32 -0
  204. package/server/prisma/migrations/20260414143000_0015_note_searchable_text/migration.sql +5 -0
  205. package/server/prisma/migrations/20260416090000_0016_view_workspace/migration.sql +50 -0
  206. package/server/prisma/schema.prisma +66 -12
  207. package/server/client/dist/assets/Calendar-DyXzs5M3.js +0 -25
  208. package/server/client/dist/assets/Graph-C8K4PJOn.js +0 -1
  209. package/server/client/dist/assets/Note-BbgZvrC3.js +0 -1
  210. package/server/client/dist/assets/Note-PEevDKBh.css +0 -1
  211. package/server/client/dist/assets/Reminders-jFhljND4.js +0 -1
  212. package/server/client/dist/assets/Search-X6QIR_m2.js +0 -1
  213. package/server/client/dist/assets/Tag-Ba2Dw4gH.js +0 -1
  214. package/server/client/dist/assets/TagNotes-BRJv6sDI.js +0 -1
  215. package/server/client/dist/assets/index-BglnLSet.js +0 -205
  216. package/server/client/dist/assets/index-DpqKngJz.js +0 -1
  217. package/server/client/dist/assets/manage-image-C6Y_0M5H.js +0 -1
  218. package/server/client/dist/assets/manage-image-detail-Dv3xofpe.js +0 -1
  219. package/server/client/dist/assets/mcp-BijQkpfY.js +0 -1
  220. package/server/client/dist/assets/trash-CiFJm_PK.js +0 -1
  221. package/server/dist/modules/auth.js +0 -25
  222. package/server/dist/modules/auth.js.map +0 -1
  223. package/server/dist/modules/image-upload.js.map +0 -1
  224. package/server/dist/modules/mcp-admin.js.map +0 -1
  225. package/server/dist/modules/note-authoring.js.map +0 -1
  226. package/server/dist/modules/note-cleanup.js.map +0 -1
  227. package/server/dist/modules/note-snapshot.js.map +0 -1
  228. package/server/dist/modules/note-trash.js.map +0 -1
  229. package/server/dist/modules/remote-image.js.map +0 -1
  230. package/server/dist/modules/tag-organization.js.map +0 -1
  231. package/server/dist/schema/cache/index.js +0 -58
  232. package/server/dist/schema/cache/index.js.map +0 -1
  233. package/server/dist/schema/image/index.js +0 -88
  234. package/server/dist/schema/image/index.js.map +0 -1
  235. package/server/dist/schema/note/index.js +0 -551
  236. package/server/dist/schema/note/index.js.map +0 -1
  237. package/server/dist/schema/placeholder/index.js +0 -105
  238. package/server/dist/schema/placeholder/index.js.map +0 -1
  239. package/server/dist/schema/reminder/index.js +0 -161
  240. package/server/dist/schema/reminder/index.js.map +0 -1
  241. package/server/dist/schema/tag/index.js +0 -81
  242. package/server/dist/schema/tag/index.js.map +0 -1
  243. package/server/dist/urls.js +0 -9
  244. package/server/dist/urls.js.map +0 -1
  245. package/server/dist/views/auth.js +0 -305
  246. package/server/dist/views/auth.js.map +0 -1
  247. package/server/dist/views/image.js +0 -44
  248. package/server/dist/views/image.js.map +0 -1
  249. package/server/dist/views/index.js +0 -6
  250. package/server/dist/views/index.js.map +0 -1
  251. package/server/dist/views/mcp-admin.js.map +0 -1
  252. package/server/dist/views/note.js.map +0 -1
  253. package/server/dist/views/tag.js.map +0 -1
@@ -0,0 +1,32 @@
1
+ import { EventEmitter } from "node:events";
2
+ const SERVER_EVENT_CHANNEL = "server-event";
3
+ const serverEventEmitter = new EventEmitter();
4
+ serverEventEmitter.setMaxListeners(0);
5
+ let nextServerEventId = 1;
6
+ const emitServerEvent = (event) => {
7
+ const nextEvent = {
8
+ id: String(nextServerEventId++),
9
+ ...event
10
+ };
11
+ serverEventEmitter.emit(SERVER_EVENT_CHANNEL, nextEvent);
12
+ return nextEvent;
13
+ };
14
+ const subscribeServerEvents = (listener) => {
15
+ serverEventEmitter.on(SERVER_EVENT_CHANNEL, listener);
16
+ return () => {
17
+ serverEventEmitter.off(SERVER_EVENT_CHANNEL, listener);
18
+ };
19
+ };
20
+ const serializeServerEvent = (event) => {
21
+ return `id: ${event.id}
22
+ event: ${event.type}
23
+ data: ${JSON.stringify(event)}
24
+
25
+ `;
26
+ };
27
+ export {
28
+ emitServerEvent,
29
+ serializeServerEvent,
30
+ subscribeServerEvents
31
+ };
32
+ //# sourceMappingURL=server-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/modules/server-events.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\n\nexport type McpNoteServerEventType = 'mcp.note.created' | 'mcp.note.updated' | 'mcp.note.deleted';\n\ninterface BaseMcpNoteServerEvent {\n id: string;\n noteId: string;\n source: 'mcp';\n}\n\nexport interface McpNoteCreatedServerEvent extends BaseMcpNoteServerEvent {\n type: 'mcp.note.created';\n updatedAt: string;\n}\n\nexport interface McpNoteUpdatedServerEvent extends BaseMcpNoteServerEvent {\n type: 'mcp.note.updated';\n updatedAt: string;\n}\n\nexport interface McpNoteDeletedServerEvent extends BaseMcpNoteServerEvent {\n type: 'mcp.note.deleted';\n}\n\nexport type ServerEvent = McpNoteCreatedServerEvent | McpNoteUpdatedServerEvent | McpNoteDeletedServerEvent;\n\nexport type ServerEventInput =\n | Omit<McpNoteCreatedServerEvent, 'id'>\n | Omit<McpNoteUpdatedServerEvent, 'id'>\n | Omit<McpNoteDeletedServerEvent, 'id'>;\n\ntype ServerEventListener = (event: ServerEvent) => void;\n\nconst SERVER_EVENT_CHANNEL = 'server-event';\n\nconst serverEventEmitter = new EventEmitter();\n\nserverEventEmitter.setMaxListeners(0);\n\nlet nextServerEventId = 1;\n\nexport const emitServerEvent = (event: ServerEventInput) => {\n const nextEvent = {\n id: String(nextServerEventId++),\n ...event,\n } as ServerEvent;\n\n serverEventEmitter.emit(SERVER_EVENT_CHANNEL, nextEvent);\n\n return nextEvent;\n};\n\nexport const subscribeServerEvents = (listener: ServerEventListener) => {\n serverEventEmitter.on(SERVER_EVENT_CHANNEL, listener);\n\n return () => {\n serverEventEmitter.off(SERVER_EVENT_CHANNEL, listener);\n };\n};\n\nexport const serializeServerEvent = (event: ServerEvent) => {\n return `id: ${event.id}\\nevent: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`;\n};\n"],"mappings":"AAAA,SAAS,oBAAoB;AAiC7B,MAAM,uBAAuB;AAE7B,MAAM,qBAAqB,IAAI,aAAa;AAE5C,mBAAmB,gBAAgB,CAAC;AAEpC,IAAI,oBAAoB;AAEjB,MAAM,kBAAkB,CAAC,UAA4B;AACxD,QAAM,YAAY;AAAA,IACd,IAAI,OAAO,mBAAmB;AAAA,IAC9B,GAAG;AAAA,EACP;AAEA,qBAAmB,KAAK,sBAAsB,SAAS;AAEvD,SAAO;AACX;AAEO,MAAM,wBAAwB,CAAC,aAAkC;AACpE,qBAAmB,GAAG,sBAAsB,QAAQ;AAEpD,SAAO,MAAM;AACT,uBAAmB,IAAI,sBAAsB,QAAQ;AAAA,EACzD;AACJ;AAEO,MAAM,uBAAuB,CAAC,UAAuB;AACxD,SAAO,OAAO,MAAM,EAAE;AAAA,SAAY,MAAM,IAAI;AAAA,QAAW,KAAK,UAAU,KAAK,CAAC;AAAA;AAAA;AAChF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/modules/use-async.ts"],"sourcesContent":["import type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport type { Controller } from '~/types/index.js';\n\nexport default function useAsync(callback: Controller) {\n return function (req: Request, res: Response, next: NextFunction) {\n void Promise.resolve()\n .then(() => callback(req, res, next))\n .catch((error: unknown) => {\n next(error);\n });\n };\n}\n"],"mappings":"AAOe,SAAR,SAA0B,UAAsB;AACnD,SAAO,SAAU,KAAc,KAAe,MAAoB;AAC9D,SAAK,QAAQ,QAAQ,EAChB,KAAK,MAAM,SAAS,KAAK,KAAK,IAAI,CAAC,EACnC,MAAM,CAAC,UAAmB;AACvB,WAAK,KAAK;AAAA,IACd,CAAC;AAAA,EACT;AACJ;","names":[]}
1
+ {"version":3,"sources":["../../src/modules/use-async.ts"],"sourcesContent":["import type { NextFunction, Request, Response } from 'express';\nimport type { Controller } from '~/types/index.js';\n\nexport default function useAsync(callback: Controller) {\n return function (req: Request, res: Response, next: NextFunction) {\n void Promise.resolve()\n .then(() => callback(req, res, next))\n .catch((error: unknown) => {\n next(error);\n });\n };\n}\n"],"mappings":"AAGe,SAAR,SAA0B,UAAsB;AACnD,SAAO,SAAU,KAAc,KAAe,MAAoB;AAC9D,SAAK,QAAQ,QAAQ,EAChB,KAAK,MAAM,SAAS,KAAK,KAAK,IAAI,CAAC,EACnC,MAAM,CAAC,UAAmB;AACvB,WAAK,KAAK;AAAA,IACd,CAAC;AAAA,EACT;AACJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/paths.ts"],"sourcesContent":["import path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// 패키지 루트 (dist/paths.js 기준 상위)\nconst PACKAGE_ROOT = process.env.OCEAN_BRAIN_PACKAGE_ROOT\n || path.resolve(__dirname, '..');\n\n// 이미지 디렉토리 (별도 지정 가능, Docker에서 분리 볼륨용)\nconst IMAGE_DIR = process.env.OCEAN_BRAIN_IMAGE_DIR\n || path.resolve(process.env.OCEAN_BRAIN_DATA_DIR || '.', 'assets/images');\n\nexport const paths = {\n clientDist: path.resolve(PACKAGE_ROOT, 'client/dist'),\n clientIndex: path.resolve(PACKAGE_ROOT, 'client/dist/index.html'),\n imageDir: path.resolve(IMAGE_DIR)\n};\n"],"mappings":"AAAA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,MAAM,YAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAG7D,MAAM,eAAe,QAAQ,IAAI,4BAC1B,KAAK,QAAQ,WAAW,IAAI;AAGnC,MAAM,YAAY,QAAQ,IAAI,yBACvB,KAAK,QAAQ,QAAQ,IAAI,wBAAwB,KAAK,eAAe;AAErE,MAAM,QAAQ;AAAA,EACjB,YAAY,KAAK,QAAQ,cAAc,aAAa;AAAA,EACpD,aAAa,KAAK,QAAQ,cAAc,wBAAwB;AAAA,EAChE,UAAU,KAAK,QAAQ,SAAS;AACpC;","names":[]}
1
+ {"version":3,"sources":["../src/paths.ts"],"sourcesContent":["import path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// 패키지 루트 (dist/paths.js 기준 상위)\nconst PACKAGE_ROOT = process.env.OCEAN_BRAIN_PACKAGE_ROOT || path.resolve(__dirname, '..');\n\n// 이미지 디렉토리 (별도 지정 가능, Docker에서 분리 볼륨용)\nconst IMAGE_DIR =\n process.env.OCEAN_BRAIN_IMAGE_DIR || path.resolve(process.env.OCEAN_BRAIN_DATA_DIR || '.', 'assets/images');\n\nexport const paths = {\n clientDist: path.resolve(PACKAGE_ROOT, 'client/dist'),\n clientIndex: path.resolve(PACKAGE_ROOT, 'client/dist/index.html'),\n imageDir: path.resolve(IMAGE_DIR),\n};\n"],"mappings":"AAAA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,MAAM,YAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAG7D,MAAM,eAAe,QAAQ,IAAI,4BAA4B,KAAK,QAAQ,WAAW,IAAI;AAGzF,MAAM,YACF,QAAQ,IAAI,yBAAyB,KAAK,QAAQ,QAAQ,IAAI,wBAAwB,KAAK,eAAe;AAEvG,MAAM,QAAQ;AAAA,EACjB,YAAY,KAAK,QAAQ,cAAc,aAAa;AAAA,EACpD,aAAa,KAAK,QAAQ,cAAc,wBAAwB;AAAA,EAChE,UAAU,KAAK,QAAQ,SAAS;AACpC;","names":[]}
@@ -0,0 +1,34 @@
1
+ import { Router } from "express";
2
+ import { createLoginHandler, createLogoutHandler, createSessionStatusHandler } from "../features/auth/http/api.js";
3
+ import { createUploadImageFromSrcHandler, createUploadImageHandler } from "../features/image/http/upload.js";
4
+ import {
5
+ createMcpAdminRevokeTokenHandler,
6
+ createMcpAdminRotateTokenHandler,
7
+ createMcpAdminSetEnabledHandler,
8
+ createMcpAdminStatusHandler
9
+ } from "../features/mcp-admin/http/handlers.js";
10
+ import { requireSessionForWrite } from "../modules/auth-guard.js";
11
+ import { createServerEventsHandler } from "../modules/server-events-handler.js";
12
+ import useAsync from "../modules/use-async.js";
13
+ import { createMcpRouter } from "./mcp.js";
14
+ const createApiRouter = (authConfig, mcpAdminService) => Router().use("/mcp", createMcpRouter(authConfig, mcpAdminService)).post("/auth/login", useAsync(createLoginHandler(authConfig))).post("/auth/logout", useAsync(createLogoutHandler(authConfig))).get("/auth/session", useAsync(createSessionStatusHandler(authConfig))).get(
15
+ "/mcp-admin/status",
16
+ requireSessionForWrite(authConfig),
17
+ useAsync(createMcpAdminStatusHandler(mcpAdminService))
18
+ ).post(
19
+ "/mcp-admin/enabled",
20
+ requireSessionForWrite(authConfig),
21
+ useAsync(createMcpAdminSetEnabledHandler(mcpAdminService))
22
+ ).post(
23
+ "/mcp-admin/token/rotate",
24
+ requireSessionForWrite(authConfig),
25
+ useAsync(createMcpAdminRotateTokenHandler(mcpAdminService))
26
+ ).post(
27
+ "/mcp-admin/token/revoke",
28
+ requireSessionForWrite(authConfig),
29
+ useAsync(createMcpAdminRevokeTokenHandler(mcpAdminService))
30
+ ).post("/image", requireSessionForWrite(authConfig), useAsync(createUploadImageHandler())).post("/image-from-src", requireSessionForWrite(authConfig), useAsync(createUploadImageFromSrcHandler())).get("/events", requireSessionForWrite(authConfig), createServerEventsHandler());
31
+ export {
32
+ createApiRouter
33
+ };
34
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/routes/api.ts"],"sourcesContent":["import { Router } from 'express';\nimport { createLoginHandler, createLogoutHandler, createSessionStatusHandler } from '../features/auth/http/api.js';\nimport { createUploadImageFromSrcHandler, createUploadImageHandler } from '../features/image/http/upload.js';\nimport {\n createMcpAdminRevokeTokenHandler,\n createMcpAdminRotateTokenHandler,\n createMcpAdminSetEnabledHandler,\n createMcpAdminStatusHandler,\n} from '../features/mcp-admin/http/handlers.js';\nimport type { McpAdminService } from '../features/mcp-admin/service.js';\nimport { requireSessionForWrite } from '../modules/auth-guard.js';\nimport type { AuthConfig } from '../modules/auth-mode.js';\nimport { createServerEventsHandler } from '../modules/server-events-handler.js';\nimport useAsync from '../modules/use-async.js';\nimport { createMcpRouter } from './mcp.js';\n\ntype McpAdminApiService = Pick<\n McpAdminService,\n 'getStatus' | 'setEnabled' | 'rotateToken' | 'revokeActiveToken' | 'validatePresentedToken'\n>;\n\nexport const createApiRouter = (authConfig: AuthConfig, mcpAdminService: McpAdminApiService) =>\n Router()\n .use('/mcp', createMcpRouter(authConfig, mcpAdminService))\n .post('/auth/login', useAsync(createLoginHandler(authConfig)))\n .post('/auth/logout', useAsync(createLogoutHandler(authConfig)))\n .get('/auth/session', useAsync(createSessionStatusHandler(authConfig)))\n .get(\n '/mcp-admin/status',\n requireSessionForWrite(authConfig),\n useAsync(createMcpAdminStatusHandler(mcpAdminService)),\n )\n .post(\n '/mcp-admin/enabled',\n requireSessionForWrite(authConfig),\n useAsync(createMcpAdminSetEnabledHandler(mcpAdminService)),\n )\n .post(\n '/mcp-admin/token/rotate',\n requireSessionForWrite(authConfig),\n useAsync(createMcpAdminRotateTokenHandler(mcpAdminService)),\n )\n .post(\n '/mcp-admin/token/revoke',\n requireSessionForWrite(authConfig),\n useAsync(createMcpAdminRevokeTokenHandler(mcpAdminService)),\n )\n .post('/image', requireSessionForWrite(authConfig), useAsync(createUploadImageHandler()))\n .post('/image-from-src', requireSessionForWrite(authConfig), useAsync(createUploadImageFromSrcHandler()))\n .get('/events', requireSessionForWrite(authConfig), createServerEventsHandler());\n"],"mappings":"AAAA,SAAS,cAAc;AACvB,SAAS,oBAAoB,qBAAqB,kCAAkC;AACpF,SAAS,iCAAiC,gCAAgC;AAC1E;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AAEP,SAAS,8BAA8B;AAEvC,SAAS,iCAAiC;AAC1C,OAAO,cAAc;AACrB,SAAS,uBAAuB;AAOzB,MAAM,kBAAkB,CAAC,YAAwB,oBACpD,OAAO,EACF,IAAI,QAAQ,gBAAgB,YAAY,eAAe,CAAC,EACxD,KAAK,eAAe,SAAS,mBAAmB,UAAU,CAAC,CAAC,EAC5D,KAAK,gBAAgB,SAAS,oBAAoB,UAAU,CAAC,CAAC,EAC9D,IAAI,iBAAiB,SAAS,2BAA2B,UAAU,CAAC,CAAC,EACrE;AAAA,EACG;AAAA,EACA,uBAAuB,UAAU;AAAA,EACjC,SAAS,4BAA4B,eAAe,CAAC;AACzD,EACC;AAAA,EACG;AAAA,EACA,uBAAuB,UAAU;AAAA,EACjC,SAAS,gCAAgC,eAAe,CAAC;AAC7D,EACC;AAAA,EACG;AAAA,EACA,uBAAuB,UAAU;AAAA,EACjC,SAAS,iCAAiC,eAAe,CAAC;AAC9D,EACC;AAAA,EACG;AAAA,EACA,uBAAuB,UAAU;AAAA,EACjC,SAAS,iCAAiC,eAAe,CAAC;AAC9D,EACC,KAAK,UAAU,uBAAuB,UAAU,GAAG,SAAS,yBAAyB,CAAC,CAAC,EACvF,KAAK,mBAAmB,uBAAuB,UAAU,GAAG,SAAS,gCAAgC,CAAC,CAAC,EACvG,IAAI,WAAW,uBAAuB,UAAU,GAAG,0BAA0B,CAAC;","names":[]}
@@ -0,0 +1,11 @@
1
+ import { Router } from "express";
2
+ import {
3
+ createLoginPageHandler,
4
+ createLoginPageSubmitHandler,
5
+ createLogoutPageHandler
6
+ } from "../features/auth/http/pages.js";
7
+ const createAuthPagesRouter = (authConfig) => Router().get("/login", createLoginPageHandler(authConfig)).post("/login", createLoginPageSubmitHandler(authConfig)).post("/logout", createLogoutPageHandler(authConfig));
8
+ export {
9
+ createAuthPagesRouter
10
+ };
11
+ //# sourceMappingURL=auth-pages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/routes/auth-pages.ts"],"sourcesContent":["import { Router } from 'express';\nimport {\n createLoginPageHandler,\n createLoginPageSubmitHandler,\n createLogoutPageHandler,\n} from '../features/auth/http/pages.js';\nimport type { AuthConfig } from '../modules/auth-mode.js';\n\nexport const createAuthPagesRouter = (authConfig: AuthConfig) =>\n Router()\n .get('/login', createLoginPageHandler(authConfig))\n .post('/login', createLoginPageSubmitHandler(authConfig))\n .post('/logout', createLogoutPageHandler(authConfig));\n"],"mappings":"AAAA,SAAS,cAAc;AACvB;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,OACG;AAGA,MAAM,wBAAwB,CAAC,eAClC,OAAO,EACF,IAAI,UAAU,uBAAuB,UAAU,CAAC,EAChD,KAAK,UAAU,6BAA6B,UAAU,CAAC,EACvD,KAAK,WAAW,wBAAwB,UAAU,CAAC;","names":[]}
@@ -0,0 +1,27 @@
1
+ import express, { Router } from "express";
2
+ import path from "path";
3
+ import { isAuthenticatedRequest } from "../modules/auth-guard.js";
4
+ import { paths } from "../paths.js";
5
+ const shouldBlockClientRoute = (authConfig, requestPath, authenticated) => {
6
+ if (authConfig.mode !== "password" || authenticated) {
7
+ return false;
8
+ }
9
+ if (requestPath.startsWith("/api") || requestPath.startsWith("/graphql") || requestPath.startsWith("/auth")) {
10
+ return false;
11
+ }
12
+ return path.extname(requestPath) === "";
13
+ };
14
+ const createClientRouter = (authConfig) => Router().use("/assets/images", express.static(paths.imageDir)).use((req, res, next) => {
15
+ if (shouldBlockClientRoute(authConfig, req.path, isAuthenticatedRequest(req))) {
16
+ const redirectPath = encodeURIComponent(req.originalUrl || "/");
17
+ res.redirect(303, `/auth/login?next=${redirectPath}`);
18
+ return;
19
+ }
20
+ next();
21
+ }).use(express.static(paths.clientDist, { extensions: ["html"] })).get(/.*/, (_req, res) => {
22
+ res.sendFile(paths.clientIndex);
23
+ });
24
+ export {
25
+ createClientRouter
26
+ };
27
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/routes/client.ts"],"sourcesContent":["import express, { Router } from 'express';\nimport path from 'path';\nimport { isAuthenticatedRequest } from '../modules/auth-guard.js';\nimport type { AuthConfig } from '../modules/auth-mode.js';\nimport { paths } from '../paths.js';\n\nconst shouldBlockClientRoute = (authConfig: AuthConfig, requestPath: string, authenticated: boolean) => {\n if (authConfig.mode !== 'password' || authenticated) {\n return false;\n }\n\n if (requestPath.startsWith('/api') || requestPath.startsWith('/graphql') || requestPath.startsWith('/auth')) {\n return false;\n }\n\n return path.extname(requestPath) === '';\n};\n\nexport const createClientRouter = (authConfig: AuthConfig) =>\n Router()\n .use('/assets/images', express.static(paths.imageDir))\n .use((req, res, next) => {\n if (shouldBlockClientRoute(authConfig, req.path, isAuthenticatedRequest(req))) {\n const redirectPath = encodeURIComponent(req.originalUrl || '/');\n res.redirect(303, `/auth/login?next=${redirectPath}`);\n return;\n }\n\n next();\n })\n .use(express.static(paths.clientDist, { extensions: ['html'] }))\n .get(/.*/, (_req, res) => {\n res.sendFile(paths.clientIndex);\n });\n"],"mappings":"AAAA,OAAO,WAAW,cAAc;AAChC,OAAO,UAAU;AACjB,SAAS,8BAA8B;AAEvC,SAAS,aAAa;AAEtB,MAAM,yBAAyB,CAAC,YAAwB,aAAqB,kBAA2B;AACpG,MAAI,WAAW,SAAS,cAAc,eAAe;AACjD,WAAO;AAAA,EACX;AAEA,MAAI,YAAY,WAAW,MAAM,KAAK,YAAY,WAAW,UAAU,KAAK,YAAY,WAAW,OAAO,GAAG;AACzG,WAAO;AAAA,EACX;AAEA,SAAO,KAAK,QAAQ,WAAW,MAAM;AACzC;AAEO,MAAM,qBAAqB,CAAC,eAC/B,OAAO,EACF,IAAI,kBAAkB,QAAQ,OAAO,MAAM,QAAQ,CAAC,EACpD,IAAI,CAAC,KAAK,KAAK,SAAS;AACrB,MAAI,uBAAuB,YAAY,IAAI,MAAM,uBAAuB,GAAG,CAAC,GAAG;AAC3E,UAAM,eAAe,mBAAmB,IAAI,eAAe,GAAG;AAC9D,QAAI,SAAS,KAAK,oBAAoB,YAAY,EAAE;AACpD;AAAA,EACJ;AAEA,OAAK;AACT,CAAC,EACA,IAAI,QAAQ,OAAO,MAAM,YAAY,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAC9D,IAAI,MAAM,CAAC,MAAM,QAAQ;AACtB,MAAI,SAAS,MAAM,WAAW;AAClC,CAAC;","names":[]}
@@ -0,0 +1,33 @@
1
+ import { Router } from "express";
2
+ import { createHandler } from "graphql-http/lib/use/express";
3
+ import { isAuthenticatedRequest, requireSessionForGraphql } from "../modules/auth-guard.js";
4
+ import { createMcpAuthMiddleware, createReadOnlyMcpValidationRule } from "../modules/mcp-auth.js";
5
+ import schema from "../schema/index.js";
6
+ const createGraphqlContext = (authConfig) => (req) => ({
7
+ authMode: authConfig.mode,
8
+ isAuthenticated: isAuthenticatedRequest(req.raw),
9
+ req: req.raw,
10
+ res: req.context.res
11
+ });
12
+ const createGraphqlRouter = (authConfig, mcpAdminService) => Router().use(
13
+ "/mcp",
14
+ createMcpAuthMiddleware(authConfig, mcpAdminService),
15
+ createHandler({
16
+ schema,
17
+ context: createGraphqlContext(authConfig),
18
+ validationRules: (_req, _args, specifiedRules) => {
19
+ return [...specifiedRules, createReadOnlyMcpValidationRule()];
20
+ }
21
+ })
22
+ ).use(
23
+ "/",
24
+ requireSessionForGraphql(authConfig),
25
+ createHandler({
26
+ schema,
27
+ context: createGraphqlContext(authConfig)
28
+ })
29
+ );
30
+ export {
31
+ createGraphqlRouter
32
+ };
33
+ //# sourceMappingURL=graphql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/routes/graphql.ts"],"sourcesContent":["import { type Request, type Response, Router } from 'express';\nimport { createHandler } from 'graphql-http/lib/use/express';\nimport type { McpAdminService } from '../features/mcp-admin/service.js';\nimport { isAuthenticatedRequest, requireSessionForGraphql } from '../modules/auth-guard.js';\nimport type { AuthConfig } from '../modules/auth-mode.js';\nimport { createMcpAuthMiddleware, createReadOnlyMcpValidationRule } from '../modules/mcp-auth.js';\nimport schema from '../schema/index.js';\n\ntype McpGraphqlService = Pick<McpAdminService, 'getStatus' | 'validatePresentedToken'>;\ntype GraphqlRequestContext = { raw: Request; context: { res: Response } };\n\nconst createGraphqlContext = (authConfig: AuthConfig) => (req: GraphqlRequestContext) => ({\n authMode: authConfig.mode,\n isAuthenticated: isAuthenticatedRequest(req.raw),\n req: req.raw,\n res: req.context.res,\n});\n\nexport const createGraphqlRouter = (authConfig: AuthConfig, mcpAdminService: McpGraphqlService) =>\n Router()\n .use(\n '/mcp',\n createMcpAuthMiddleware(authConfig, mcpAdminService),\n createHandler({\n schema,\n context: createGraphqlContext(authConfig),\n validationRules: (_req, _args, specifiedRules) => {\n return [...specifiedRules, createReadOnlyMcpValidationRule()];\n },\n }),\n )\n .use(\n '/',\n requireSessionForGraphql(authConfig),\n createHandler({\n schema,\n context: createGraphqlContext(authConfig),\n }),\n );\n"],"mappings":"AAAA,SAAsC,cAAc;AACpD,SAAS,qBAAqB;AAE9B,SAAS,wBAAwB,gCAAgC;AAEjE,SAAS,yBAAyB,uCAAuC;AACzE,OAAO,YAAY;AAKnB,MAAM,uBAAuB,CAAC,eAA2B,CAAC,SAAgC;AAAA,EACtF,UAAU,WAAW;AAAA,EACrB,iBAAiB,uBAAuB,IAAI,GAAG;AAAA,EAC/C,KAAK,IAAI;AAAA,EACT,KAAK,IAAI,QAAQ;AACrB;AAEO,MAAM,sBAAsB,CAAC,YAAwB,oBACxD,OAAO,EACF;AAAA,EACG;AAAA,EACA,wBAAwB,YAAY,eAAe;AAAA,EACnD,cAAc;AAAA,IACV;AAAA,IACA,SAAS,qBAAqB,UAAU;AAAA,IACxC,iBAAiB,CAAC,MAAM,OAAO,mBAAmB;AAC9C,aAAO,CAAC,GAAG,gBAAgB,gCAAgC,CAAC;AAAA,IAChE;AAAA,EACJ,CAAC;AACL,EACC;AAAA,EACG;AAAA,EACA,yBAAyB,UAAU;AAAA,EACnC,cAAc;AAAA,IACV;AAAA,IACA,SAAS,qBAAqB,UAAU;AAAA,EAC5C,CAAC;AACL;","names":[]}
@@ -0,0 +1,11 @@
1
+ import { createApiRouter } from "./api.js";
2
+ import { createAuthPagesRouter } from "./auth-pages.js";
3
+ import { createClientRouter } from "./client.js";
4
+ import { createGraphqlRouter } from "./graphql.js";
5
+ export {
6
+ createApiRouter,
7
+ createAuthPagesRouter,
8
+ createClientRouter,
9
+ createGraphqlRouter
10
+ };
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/routes/index.ts"],"sourcesContent":["export { createApiRouter } from './api.js';\nexport { createAuthPagesRouter } from './auth-pages.js';\nexport { createClientRouter } from './client.js';\nexport { createGraphqlRouter } from './graphql.js';\n"],"mappings":"AAAA,SAAS,uBAAuB;AAChC,SAAS,6BAA6B;AACtC,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;","names":[]}
@@ -0,0 +1,30 @@
1
+ import { Router } from "express";
2
+ import {
3
+ createMcpCreateNoteHandler,
4
+ createMcpDeleteNoteHandler,
5
+ createMcpUpdateNoteHandler
6
+ } from "../features/note/http/mcp.js";
7
+ import { createMcpCreateTagHandler } from "../features/tag/http/mcp.js";
8
+ import { createMcpAuthMiddleware } from "../modules/mcp-auth.js";
9
+ import useAsync from "../modules/use-async.js";
10
+ const createMcpRouter = (authConfig, mcpAdminService) => Router().post(
11
+ "/notes/create",
12
+ createMcpAuthMiddleware(authConfig, mcpAdminService),
13
+ useAsync(createMcpCreateNoteHandler())
14
+ ).post(
15
+ "/notes/update",
16
+ createMcpAuthMiddleware(authConfig, mcpAdminService),
17
+ useAsync(createMcpUpdateNoteHandler())
18
+ ).post(
19
+ "/notes/delete",
20
+ createMcpAuthMiddleware(authConfig, mcpAdminService),
21
+ useAsync(createMcpDeleteNoteHandler())
22
+ ).post(
23
+ "/tags/create",
24
+ createMcpAuthMiddleware(authConfig, mcpAdminService),
25
+ useAsync(createMcpCreateTagHandler())
26
+ );
27
+ export {
28
+ createMcpRouter
29
+ };
30
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/routes/mcp.ts"],"sourcesContent":["import { Router } from 'express';\nimport type { McpAdminService } from '../features/mcp-admin/service.js';\nimport {\n createMcpCreateNoteHandler,\n createMcpDeleteNoteHandler,\n createMcpUpdateNoteHandler,\n} from '../features/note/http/mcp.js';\nimport { createMcpCreateTagHandler } from '../features/tag/http/mcp.js';\nimport type { AuthConfig } from '../modules/auth-mode.js';\nimport { createMcpAuthMiddleware } from '../modules/mcp-auth.js';\nimport useAsync from '../modules/use-async.js';\n\ntype McpRouteService = Pick<McpAdminService, 'getStatus' | 'validatePresentedToken'>;\n\nexport const createMcpRouter = (authConfig: AuthConfig, mcpAdminService: McpRouteService) =>\n Router()\n .post(\n '/notes/create',\n createMcpAuthMiddleware(authConfig, mcpAdminService),\n useAsync(createMcpCreateNoteHandler()),\n )\n .post(\n '/notes/update',\n createMcpAuthMiddleware(authConfig, mcpAdminService),\n useAsync(createMcpUpdateNoteHandler()),\n )\n .post(\n '/notes/delete',\n createMcpAuthMiddleware(authConfig, mcpAdminService),\n useAsync(createMcpDeleteNoteHandler()),\n )\n .post(\n '/tags/create',\n createMcpAuthMiddleware(authConfig, mcpAdminService),\n useAsync(createMcpCreateTagHandler()),\n );\n"],"mappings":"AAAA,SAAS,cAAc;AAEvB;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,OACG;AACP,SAAS,iCAAiC;AAE1C,SAAS,+BAA+B;AACxC,OAAO,cAAc;AAId,MAAM,kBAAkB,CAAC,YAAwB,oBACpD,OAAO,EACF;AAAA,EACG;AAAA,EACA,wBAAwB,YAAY,eAAe;AAAA,EACnD,SAAS,2BAA2B,CAAC;AACzC,EACC;AAAA,EACG;AAAA,EACA,wBAAwB,YAAY,eAAe;AAAA,EACnD,SAAS,2BAA2B,CAAC;AACzC,EACC;AAAA,EACG;AAAA,EACA,wBAAwB,YAAY,eAAe;AAAA,EACnD,SAAS,2BAA2B,CAAC;AACzC,EACC;AAAA,EACG;AAAA,EACA,wBAAwB,YAAY,eAAe;AAAA,EACnD,SAAS,0BAA0B,CAAC;AACxC;","names":[]}
@@ -1,10 +1,11 @@
1
1
  import { makeExecutableSchema } from "@graphql-tools/schema";
2
- import { noteResolvers, noteTypeDefs } from "./note/index.js";
3
- import { imageResolvers, imageTypeDefs } from "./image/index.js";
4
- import { tagResolvers, tagTypeDefs } from "./tag/index.js";
5
- import { placeholderResolvers, placeholderTypeDefs } from "./placeholder/index.js";
6
- import { cacheResolvers, cacheTypeDefs } from "./cache/index.js";
7
- import { reminderResolvers, reminderTypeDefs } from "./reminder/index.js";
2
+ import { cacheResolvers, cacheTypeDefs } from "../features/cache/graphql/index.js";
3
+ import { imageResolvers, imageTypeDefs } from "../features/image/graphql/index.js";
4
+ import { noteResolvers, noteTypeDefs } from "../features/note/graphql/index.js";
5
+ import { placeholderResolvers, placeholderTypeDefs } from "../features/placeholder/graphql/index.js";
6
+ import { reminderResolvers, reminderTypeDefs } from "../features/reminder/graphql/index.js";
7
+ import { tagResolvers, tagTypeDefs } from "../features/tag/graphql/index.js";
8
+ import { viewResolvers, viewTypeDefs } from "../features/view/graphql/index.js";
8
9
  const schema = makeExecutableSchema({
9
10
  typeDefs: [
10
11
  cacheTypeDefs,
@@ -12,7 +13,8 @@ const schema = makeExecutableSchema({
12
13
  imageTypeDefs,
13
14
  tagTypeDefs,
14
15
  placeholderTypeDefs,
15
- reminderTypeDefs
16
+ reminderTypeDefs,
17
+ viewTypeDefs
16
18
  ],
17
19
  resolvers: [
18
20
  cacheResolvers,
@@ -20,7 +22,8 @@ const schema = makeExecutableSchema({
20
22
  imageResolvers,
21
23
  tagResolvers,
22
24
  placeholderResolvers,
23
- reminderResolvers
25
+ reminderResolvers,
26
+ viewResolvers
24
27
  ]
25
28
  });
26
29
  var schema_default = schema;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/schema/index.ts"],"sourcesContent":["import { makeExecutableSchema } from '@graphql-tools/schema';\nimport { noteResolvers, noteTypeDefs } from './note/index.js';\nimport { imageResolvers, imageTypeDefs } from './image/index.js';\nimport { tagResolvers, tagTypeDefs } from './tag/index.js';\nimport { placeholderResolvers, placeholderTypeDefs } from './placeholder/index.js';\nimport { cacheResolvers, cacheTypeDefs } from './cache/index.js';\nimport { reminderResolvers, reminderTypeDefs } from './reminder/index.js';\n\nconst schema = makeExecutableSchema({\n typeDefs: [\n cacheTypeDefs,\n noteTypeDefs,\n imageTypeDefs,\n tagTypeDefs,\n placeholderTypeDefs,\n reminderTypeDefs\n ],\n resolvers: [\n cacheResolvers,\n noteResolvers,\n imageResolvers,\n tagResolvers,\n placeholderResolvers,\n reminderResolvers\n ]\n});\n\nexport default schema;\n"],"mappings":"AAAA,SAAS,4BAA4B;AACrC,SAAS,eAAe,oBAAoB;AAC5C,SAAS,gBAAgB,qBAAqB;AAC9C,SAAS,cAAc,mBAAmB;AAC1C,SAAS,sBAAsB,2BAA2B;AAC1D,SAAS,gBAAgB,qBAAqB;AAC9C,SAAS,mBAAmB,wBAAwB;AAEpD,MAAM,SAAS,qBAAqB;AAAA,EAChC,UAAU;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAAA,EACA,WAAW;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ,CAAC;AAED,IAAO,iBAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/schema/index.ts"],"sourcesContent":["import { makeExecutableSchema } from '@graphql-tools/schema';\nimport { cacheResolvers, cacheTypeDefs } from '../features/cache/graphql/index.js';\nimport { imageResolvers, imageTypeDefs } from '../features/image/graphql/index.js';\nimport { noteResolvers, noteTypeDefs } from '../features/note/graphql/index.js';\nimport { placeholderResolvers, placeholderTypeDefs } from '../features/placeholder/graphql/index.js';\nimport { reminderResolvers, reminderTypeDefs } from '../features/reminder/graphql/index.js';\nimport { tagResolvers, tagTypeDefs } from '../features/tag/graphql/index.js';\nimport { viewResolvers, viewTypeDefs } from '../features/view/graphql/index.js';\n\nconst schema = makeExecutableSchema({\n typeDefs: [\n cacheTypeDefs,\n noteTypeDefs,\n imageTypeDefs,\n tagTypeDefs,\n placeholderTypeDefs,\n reminderTypeDefs,\n viewTypeDefs,\n ],\n resolvers: [\n cacheResolvers,\n noteResolvers,\n imageResolvers,\n tagResolvers,\n placeholderResolvers,\n reminderResolvers,\n viewResolvers,\n ],\n});\n\nexport default schema;\n"],"mappings":"AAAA,SAAS,4BAA4B;AACrC,SAAS,gBAAgB,qBAAqB;AAC9C,SAAS,gBAAgB,qBAAqB;AAC9C,SAAS,eAAe,oBAAoB;AAC5C,SAAS,sBAAsB,2BAA2B;AAC1D,SAAS,mBAAmB,wBAAwB;AACpD,SAAS,cAAc,mBAAmB;AAC1C,SAAS,eAAe,oBAAoB;AAE5C,MAAM,SAAS,qBAAqB;AAAA,EAChC,UAAU;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAAA,EACA,WAAW;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ,CAAC;AAED,IAAO,iBAAQ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["import type { Request, Response, NextFunction } from 'express';\n\ndeclare module 'express-session' {\n interface SessionData {\n authenticated?: boolean;\n }\n}\n\nexport type Controller = (req: Request, res: Response, next?: NextFunction) => Promise<void>;\n\nexport * from './input.js';\n"],"mappings":"AAUA,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["import type { NextFunction, Request, Response } from 'express';\n\ndeclare module 'express-session' {\n interface SessionData {\n authenticated?: boolean;\n }\n}\n\nexport type Controller = (req: Request, res: Response, next?: NextFunction) => Promise<void>;\n\nexport * from './input.js';\n"],"mappings":"AAUA,cAAc;","names":[]}
@@ -0,0 +1,32 @@
1
+ CREATE TEMP TABLE "_TagDuplicateMap" AS
2
+ SELECT
3
+ duplicate."id" AS "duplicateId",
4
+ grouped."canonicalId" AS "canonicalId"
5
+ FROM "Tag" AS duplicate
6
+ JOIN (
7
+ SELECT
8
+ "name",
9
+ MIN("id") AS "canonicalId"
10
+ FROM "Tag"
11
+ GROUP BY "name"
12
+ ) AS grouped
13
+ ON grouped."name" = duplicate."name"
14
+ WHERE duplicate."id" <> grouped."canonicalId";
15
+
16
+ INSERT OR IGNORE INTO "_NoteToTag" ("A", "B")
17
+ SELECT
18
+ relation."A",
19
+ duplicateMap."canonicalId"
20
+ FROM "_NoteToTag" AS relation
21
+ JOIN "_TagDuplicateMap" AS duplicateMap
22
+ ON duplicateMap."duplicateId" = relation."B";
23
+
24
+ DELETE FROM "Tag"
25
+ WHERE "id" IN (
26
+ SELECT "duplicateId"
27
+ FROM "_TagDuplicateMap"
28
+ );
29
+
30
+ CREATE UNIQUE INDEX "Tag_name_key" ON "Tag"("name");
31
+
32
+ DROP TABLE "_TagDuplicateMap";
@@ -0,0 +1,5 @@
1
+ ALTER TABLE "Note"
2
+ ADD COLUMN "searchableText" TEXT NOT NULL DEFAULT '';
3
+
4
+ ALTER TABLE "Note"
5
+ ADD COLUMN "searchableTextVersion" INTEGER NOT NULL DEFAULT 0;
@@ -0,0 +1,50 @@
1
+ -- CreateTable
2
+ CREATE TABLE "ViewTab" (
3
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
+ "title" TEXT NOT NULL,
5
+ "order" INTEGER NOT NULL DEFAULT 0,
6
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
7
+ "updatedAt" DATETIME NOT NULL
8
+ );
9
+
10
+ -- CreateTable
11
+ CREATE TABLE "ViewWorkspace" (
12
+ "id" INTEGER NOT NULL PRIMARY KEY,
13
+ "activeTabId" INTEGER,
14
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
15
+ "updatedAt" DATETIME NOT NULL,
16
+ CONSTRAINT "ViewWorkspace_activeTabId_fkey" FOREIGN KEY ("activeTabId") REFERENCES "ViewTab" ("id") ON DELETE SET NULL ON UPDATE CASCADE
17
+ );
18
+
19
+ -- CreateTable
20
+ CREATE TABLE "ViewSection" (
21
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
22
+ "tabId" INTEGER NOT NULL,
23
+ "title" TEXT NOT NULL,
24
+ "mode" TEXT NOT NULL DEFAULT 'and',
25
+ "limit" INTEGER NOT NULL DEFAULT 5,
26
+ "order" INTEGER NOT NULL DEFAULT 0,
27
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
28
+ "updatedAt" DATETIME NOT NULL,
29
+ CONSTRAINT "ViewSection_tabId_fkey" FOREIGN KEY ("tabId") REFERENCES "ViewTab" ("id") ON DELETE CASCADE ON UPDATE CASCADE
30
+ );
31
+
32
+ -- CreateTable
33
+ CREATE TABLE "ViewSectionTag" (
34
+ "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
35
+ "sectionId" INTEGER NOT NULL,
36
+ "name" TEXT NOT NULL,
37
+ "order" INTEGER NOT NULL DEFAULT 0,
38
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
39
+ "updatedAt" DATETIME NOT NULL,
40
+ CONSTRAINT "ViewSectionTag_sectionId_fkey" FOREIGN KEY ("sectionId") REFERENCES "ViewSection" ("id") ON DELETE CASCADE ON UPDATE CASCADE
41
+ );
42
+
43
+ -- CreateIndex
44
+ CREATE INDEX "ViewTab_order_createdAt_idx" ON "ViewTab"("order", "createdAt");
45
+
46
+ -- CreateIndex
47
+ CREATE INDEX "ViewSection_tabId_order_createdAt_idx" ON "ViewSection"("tabId", "order", "createdAt");
48
+
49
+ -- CreateIndex
50
+ CREATE INDEX "ViewSectionTag_sectionId_order_createdAt_idx" ON "ViewSectionTag"("sectionId", "order", "createdAt");
@@ -26,17 +26,19 @@ model McpToken {
26
26
  }
27
27
 
28
28
  model Note {
29
- id Int @id @default(autoincrement())
30
- title String
31
- content String
32
- createdAt DateTime @default(now())
33
- updatedAt DateTime @updatedAt
34
- pinned Boolean @default(false)
35
- order Int @default(0)
36
- layout NoteLayout @default(wide)
37
- tags Tag[] @relation("NoteToTag")
38
- reminders Reminder[] @relation("NoteToReminder")
39
- snapshots NoteSnapshot[]
29
+ id Int @id @default(autoincrement())
30
+ title String
31
+ content String
32
+ searchableText String @default("")
33
+ searchableTextVersion Int @default(0)
34
+ createdAt DateTime @default(now())
35
+ updatedAt DateTime @updatedAt
36
+ pinned Boolean @default(false)
37
+ order Int @default(0)
38
+ layout NoteLayout @default(wide)
39
+ tags Tag[] @relation("NoteToTag")
40
+ reminders Reminder[] @relation("NoteToReminder")
41
+ snapshots NoteSnapshot[]
40
42
  }
41
43
 
42
44
  model NoteSnapshot {
@@ -103,7 +105,7 @@ model Image {
103
105
 
104
106
  model Tag {
105
107
  id Int @id @default(autoincrement())
106
- name String
108
+ name String @unique
107
109
  createdAt DateTime @default(now())
108
110
  updatedAt DateTime @updatedAt
109
111
  notes Note[] @relation("NoteToTag")
@@ -141,3 +143,55 @@ model Placeholder {
141
143
  createdAt DateTime @default(now())
142
144
  updatedAt DateTime @updatedAt
143
145
  }
146
+
147
+ model ViewWorkspace {
148
+ id Int @id
149
+ activeTabId Int?
150
+ activeTab ViewTab? @relation("ActiveViewTab", fields: [activeTabId], references: [id], onDelete: SetNull)
151
+ createdAt DateTime @default(now())
152
+ updatedAt DateTime @updatedAt
153
+ }
154
+
155
+ model ViewTab {
156
+ id Int @id @default(autoincrement())
157
+ title String
158
+ order Int @default(0)
159
+ createdAt DateTime @default(now())
160
+ updatedAt DateTime @updatedAt
161
+ sections ViewSection[]
162
+ activeWorkspaces ViewWorkspace[] @relation("ActiveViewTab")
163
+
164
+ @@index([order, createdAt])
165
+ }
166
+
167
+ model ViewSection {
168
+ id Int @id @default(autoincrement())
169
+ tabId Int
170
+ tab ViewTab @relation(fields: [tabId], references: [id], onDelete: Cascade)
171
+ title String
172
+ mode ViewTagMatchMode @default(and)
173
+ limit Int @default(5)
174
+ order Int @default(0)
175
+ createdAt DateTime @default(now())
176
+ updatedAt DateTime @updatedAt
177
+ tags ViewSectionTag[]
178
+
179
+ @@index([tabId, order, createdAt])
180
+ }
181
+
182
+ model ViewSectionTag {
183
+ id Int @id @default(autoincrement())
184
+ sectionId Int
185
+ section ViewSection @relation(fields: [sectionId], references: [id], onDelete: Cascade)
186
+ name String
187
+ order Int @default(0)
188
+ createdAt DateTime @default(now())
189
+ updatedAt DateTime @updatedAt
190
+
191
+ @@index([sectionId, order, createdAt])
192
+ }
193
+
194
+ enum ViewTagMatchMode {
195
+ and
196
+ or
197
+ }
@@ -1,25 +0,0 @@
1
- import{j as e}from"./note-vendor-BofYbzmZ.js";import{p as ae,T as b,L as se,N as re,c as Y,d as f,s as ne,a as oe,M as R,b as ie,S as le,e as U,B as Z,f as ce,g as de,u as P,q,h as Q,P as me,i as ue,j as he,C as ge}from"./index-BglnLSet.js";import{a as n}from"./graph-vendor-CUxe67Lr.js";import"./note-core-BCgMq5QA.js";const pe=new Map([["bold",n.createElement(n.Fragment,null,n.createElement("path",{d:"M108,84a16,16,0,1,1,16,16A16,16,0,0,1,108,84Zm128,44A108,108,0,1,1,128,20,108.12,108.12,0,0,1,236,128Zm-24,0a84,84,0,1,0-84,84A84.09,84.09,0,0,0,212,128Zm-72,36.68V132a20,20,0,0,0-20-20,12,12,0,0,0-4,23.32V168a20,20,0,0,0,20,20,12,12,0,0,0,4-23.32Z"}))],["duotone",n.createElement(n.Fragment,null,n.createElement("path",{d:"M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z",opacity:"0.2"}),n.createElement("path",{d:"M144,176a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176Zm88-48A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128ZM124,96a12,12,0,1,0-12-12A12,12,0,0,0,124,96Z"}))],["fill",n.createElement(n.Fragment,null,n.createElement("path",{d:"M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-4,48a12,12,0,1,1-12,12A12,12,0,0,1,124,72Zm12,112a16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40a8,8,0,0,1,0,16Z"}))],["light",n.createElement(n.Fragment,null,n.createElement("path",{d:"M142,176a6,6,0,0,1-6,6,14,14,0,0,1-14-14V128a2,2,0,0,0-2-2,6,6,0,0,1,0-12,14,14,0,0,1,14,14v40a2,2,0,0,0,2,2A6,6,0,0,1,142,176ZM124,94a10,10,0,1,0-10-10A10,10,0,0,0,124,94Zm106,34A102,102,0,1,1,128,26,102.12,102.12,0,0,1,230,128Zm-12,0a90,90,0,1,0-90,90A90.1,90.1,0,0,0,218,128Z"}))],["regular",n.createElement(n.Fragment,null,n.createElement("path",{d:"M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"}))],["thin",n.createElement(n.Fragment,null,n.createElement("path",{d:"M140,176a4,4,0,0,1-4,4,12,12,0,0,1-12-12V128a4,4,0,0,0-4-4,4,4,0,0,1,0-8,12,12,0,0,1,12,12v40a4,4,0,0,0,4,4A4,4,0,0,1,140,176ZM124,92a8,8,0,1,0-8-8A8,8,0,0,0,124,92Zm104,36A100,100,0,1,1,128,28,100.11,100.11,0,0,1,228,128Zm-8,0a92,92,0,1,0-92,92A92.1,92.1,0,0,0,220,128Z"}))]]),B=n.forwardRef((a,t)=>n.createElement(ae,{ref:t,...a,weights:pe}));B.displayName="InfoIcon";const xe=B,ye=({children:a,className:t=""})=>e.jsxs("div",{className:`flex items-start gap-2.5 rounded-[12px] border border-border-subtle bg-hover-subtle/50 px-4 py-3 ${t}`,children:[e.jsx(xe,{className:"mt-0.5 h-4 w-4 shrink-0 text-fg-tertiary"}),e.jsx(b,{as:"div",variant:"meta",weight:"medium",tone:"secondary",children:a})]}),fe=({day:a,cellClassName:t,dayNumberClassName:s,isCurrentMonth:l,items:i,overflowCount:c,onOpenOverflow:u})=>e.jsxs("div",{className:`min-h-[196px] rounded-[16px] border p-2.5 ${t}`.trim(),children:[e.jsx("div",{className:"mb-2.5 flex justify-end",children:e.jsx(b,{as:"span",variant:"label",className:`flex h-7 w-7 items-center justify-center rounded-[10px] ${s}`.trim(),children:a})}),l&&i.length>0?e.jsxs("div",{className:"flex flex-col gap-1.5",children:[i,c>0?e.jsxs("button",{type:"button",onClick:u,className:"focus-ring-soft w-full rounded-[10px] border border-dashed border-border-subtle/70 bg-subtle/70 py-1 text-center text-micro font-semibold text-fg-tertiary outline-none transition-colors hover:border-border-secondary/70 hover:bg-hover-subtle hover:text-fg-secondary",children:["+",c," more"]}):null]}):null]}),K=({params:a,toneClassName:t="",header:s,title:l,meta:i,titleClassName:c=""})=>e.jsx(se,{to:re,params:a,className:"focus-ring-soft group block rounded-[8px] outline-none",children:e.jsxs("div",{className:Y("flex items-start gap-1.5 rounded-[8px] px-1.5 py-1 transition-colors group-hover:bg-hover-subtle",t),children:[s?e.jsx("span",{className:"mt-[2px] flex h-4 w-4 shrink-0 items-center justify-center text-fg-tertiary",children:s}):e.jsx("span",{"aria-hidden":"true",className:"mt-[6px] h-1.5 w-1.5 shrink-0 rounded-full bg-fg-placeholder"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx(b,{as:"div",variant:"label",weight:"medium",tone:"secondary",className:Y("line-clamp-1",c),children:l}),i?e.jsx(b,{as:"div",variant:"micro",weight:"medium",tone:"tertiary",className:"mt-0.5",children:i}):null]})]})}),be=({note:a,type:t})=>e.jsx(K,{params:{id:a.id},header:e.jsx(ne,{size:12}),title:a.title,meta:f(Number(t==="create"?a.createdAt:a.updatedAt)).format("HH:mm")}),je=({reminder:a})=>e.jsx(K,{params:{id:String(a.note?.id??a.noteId)},header:e.jsx(oe,{size:12}),title:a.content||a.note?.title||"No title",titleClassName:a.completed?"line-through":"",meta:f(Number(a.reminderDate)).format("HH:mm")}),T=3,H=(a,t)=>a.map(s=>s.type==="note"?e.jsx(be,{note:s.item,type:t},`note-${s.item.id}`):e.jsx(je,{reminder:s.item},`reminder-${s.item.id}`)),ve=({year:a,month:t,day:s,isCurrentMonth:l,isSunday:i,isToday:c,isPast:u,notes:h,reminders:g,type:v})=>{const[M,N]=n.useState(!1),x=n.useMemo(()=>{const r=h.map(m=>({type:"note",item:m})),d=g.map(m=>({type:"reminder",item:m}));return u?[...r,...d]:[...d,...r]},[u,h,g]),D=x.length>T,C=n.useMemo(()=>H(x.slice(0,T),v),[x,v]),S=n.useMemo(()=>H(x,v),[x,v]),A=n.useCallback(()=>N(!0),[]),w=n.useCallback(()=>N(!1),[]),$=()=>l?c?"border-border-secondary/70 bg-[color:color-mix(in_srgb,var(--surface)_88%,var(--accent-soft-primary)_12%)]":"bg-surface border-border-subtle":"bg-muted/18 border-border-subtle/70",k=()=>c?"bg-cta text-fg-on-filled font-semibold":l?i?"text-fg-weekend font-bold":"text-fg-secondary font-bold":"text-fg-disabled opacity-55";return e.jsxs(e.Fragment,{children:[e.jsx(fe,{day:s,cellClassName:$(),dayNumberClassName:k(),isCurrentMonth:l,items:C,overflowCount:D?x.length-T:0,onOpenOverflow:A}),D&&e.jsxs(R,{isOpen:M,onClose:w,children:[e.jsx(R.Header,{title:`${a}/${String(t).padStart(2,"0")}/${String(s).padStart(2,"0")}`,onClose:w}),e.jsxs(R.Body,{children:[e.jsxs(R.Description,{className:"sr-only",children:["View all notes and reminders scheduled for day ",s,"."]}),e.jsx("div",{className:"flex max-h-[60vh] flex-col gap-2 overflow-y-auto",children:S})]})]})]})},Ne=n.memo(ve),Me=["January","February","March","April","May","June","July","August","September","October","November","December"],De=({month:a,year:t,type:s,onPrevMonth:l,onNextMonth:i,onToday:c,onTypeChange:u})=>e.jsxs("div",{className:"flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex flex-wrap items-end gap-x-2.5 gap-y-1",children:[e.jsx(b,{as:"h1",variant:"display",weight:"bold",tracking:"tighter",className:"text-2xl leading-none sm:text-[2.15rem]",children:Me[a-1]}),e.jsx(b,{as:"span",variant:"subheading",weight:"medium",tone:"secondary",tracking:"tight",className:"pb-0.5",children:t})]}),e.jsx(b,{as:"p",variant:"meta",weight:"medium",tone:"secondary",children:"Track note activity and reminders across the month"})]}),e.jsx("div",{className:"flex lg:justify-end",children:e.jsxs("div",{className:"surface-base inline-flex flex-wrap items-center gap-3 rounded-[16px] px-3.5 py-2.5",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{className:"h-4 w-4 shrink-0 text-fg-tertiary"}),e.jsx(b,{as:"span",variant:"label",weight:"medium",tone:"tertiary",children:"Note date"}),e.jsxs(le,{value:s,onValueChange:g=>u(g),variant:"ghost",size:"sm",children:[e.jsx(U,{value:"create",children:"Created"}),e.jsx(U,{value:"update",children:"Updated"})]})]}),e.jsx("div",{className:"h-5 w-px bg-divider"}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(Z,{variant:"ghost",size:"sm",onClick:c,children:"Today"}),e.jsx(Z,{variant:"ghost",size:"icon-sm",onClick:l,children:e.jsx(ce,{width:18,height:18})}),e.jsx(Z,{variant:"ghost",size:"icon-sm",onClick:i,children:e.jsx(de,{width:18,height:18})})]})]})})]}),we=`
2
- query NotesInDateRange($dateRange: DateRangeInput) {
3
- notesInDateRange(dateRange: $dateRange) {
4
- id
5
- title
6
- createdAt
7
- updatedAt
8
- }
9
- }
10
- `,Ee=`
11
- query RemindersInDateRange($dateRange: DateRangeInput) {
12
- remindersInDateRange(dateRange: $dateRange) {
13
- id
14
- noteId
15
- reminderDate
16
- completed
17
- priority
18
- content
19
- note {
20
- id
21
- title
22
- }
23
- }
24
- }
25
- `,Re=async a=>{const t=await Q(we,{dateRange:a});if(t.type==="error")throw t;return t.notesInDateRange},Ce=async a=>{const t=await Q(Ee,{dateRange:a});if(t.type==="error")throw t;return t.remindersInDateRange},Se=({year:a,month:t})=>{const s=`${a}-${String(t).padStart(2,"0")}-01`,l=t===12?1:t+1,c=`${t===12?a+1:a}-${String(l).padStart(2,"0")}-01`,u={start:s,end:c},h=P({queryKey:q.calendar.notesInDateRange(a,t),queryFn:()=>Re(u)}),g=P({queryKey:q.reminders.inDateRange(a,t),queryFn:()=>Ce(u)});return{notes:h.data??[],reminders:g.data??[],isLoading:h.isLoading||g.isLoading,isError:h.isError||g.isError}},Ae=["SUN","MON","TUE","WED","THU","FRI","SAT"],$e=[],ke=[],z=he(ge);function Le(){const a=z.useNavigate(),{year:t,month:s,type:l}=z.useSearch(),i=n.useRef(null),c=n.useRef(!1),u=n.useRef(0),h=n.useRef(0),g=n.useCallback(r=>{c.current=!0,u.current=r.pageX-(i.current?.offsetLeft??0),h.current=i.current?.scrollLeft??0,i.current&&(i.current.style.cursor="grabbing",i.current.style.userSelect="none")},[]),v=n.useCallback(r=>{if(!c.current||!i.current)return;r.preventDefault();const m=(r.pageX-i.current.offsetLeft-u.current)*1.2;i.current.scrollLeft=h.current-m},[]),M=n.useCallback(()=>{c.current=!1,i.current&&(i.current.style.cursor="grab",i.current.style.userSelect="")},[]),{notes:N,reminders:x,isLoading:D,isError:C}=Se({year:t,month:s}),S=n.useMemo(()=>{const r=f(),d=`${r.year()}-${r.month()+1}-${r.date()}`,m=new Map;for(const o of N){const y=l==="create"?f(Number(o.createdAt)):f(Number(o.updatedAt)),p=`${y.year()}-${y.month()+1}-${y.date()}`,j=m.get(p)||[];j.push(o),m.set(p,j)}const I=new Map;for(const o of x){const y=f(Number(o.reminderDate)),p=`${y.year()}-${y.month()+1}-${y.date()}`,j=I.get(p)||[];j.push(o),I.set(p,j)}const W=new Date(t,s-1,1),X=new Date(t,s,0),O=W.getDay(),L=X.getDate(),E=[],F=s===1?12:s-1,_=s===1?t-1:t,J=new Date(_,F,0).getDate();for(let o=O-1;o>=0;o--)E.push({day:J-o,isCurrentMonth:!1,year:_,month:F});for(let o=1;o<=L;o++)E.push({day:o,isCurrentMonth:!0,year:t,month:s});const V=(O+L)%7,G=V===0?0:7-V,ee=s===12?1:s+1,te=s===12?t+1:t;for(let o=1;o<=G;o++)E.push({day:o,isCurrentMonth:!1,year:te,month:ee});return E.map((o,y)=>{const p=`${o.year}-${o.month}-${o.day}`,j=f(`${o.year}-${String(o.month).padStart(2,"0")}-${String(o.day).padStart(2,"0")}`);return{key:p,year:o.year,month:o.month,day:o.day,isCurrentMonth:o.isCurrentMonth,isSunday:y%7===0,isToday:p===d,isPast:j.isBefore(r,"day"),notes:m.get(p)||$e,reminders:I.get(p)||ke}})},[t,s,N,x,l]),A=()=>{const r=s===1?12:s-1,d=s===1?t-1:t;a({search:m=>({...m,month:r,year:d})})},w=()=>{const r=s===12?1:s+1,d=s===12?t+1:t;a({search:m=>({...m,month:r,year:d})})},$=()=>{a({search:r=>({...r,month:f().month()+1,year:f().year()})})},k=r=>{r&&a({search:d=>({...d,type:r})})};return e.jsx(me,{title:"Calendar",variant:"none",children:C?e.jsx(ye,{children:"Failed to load calendar data. Please try again later."}):e.jsxs("div",{className:"surface-base",children:[e.jsx("div",{className:"border-b border-border-subtle/80 px-4 py-4 sm:px-5",children:e.jsx(De,{month:s,year:t,type:l,onPrevMonth:A,onNextMonth:w,onToday:$,onTypeChange:k})}),e.jsx("div",{ref:i,className:"cursor-grab overflow-x-auto px-4 pb-4 pt-3 sm:px-5",onMouseDown:g,onMouseMove:v,onMouseUp:M,onMouseLeave:M,children:e.jsxs("div",{className:"min-w-[1260px]",children:[e.jsx("div",{className:"mb-2.5 grid grid-cols-7 gap-1.5",children:Ae.map((r,d)=>e.jsx(b,{as:"div",variant:"label",weight:"semibold",tracking:"wider",transform:"uppercase",className:`py-2 text-center ${d===0?"text-fg-weekend":"text-fg-tertiary"}`,children:r},r))}),D?e.jsx("div",{className:"grid grid-cols-7 gap-1.5",children:Array.from({length:35}).map((r,d)=>e.jsx(ue,{height:180},d))}):e.jsx("div",{className:"grid grid-cols-7 gap-1.5",children:S.map(r=>e.jsx(Ne,{year:r.year,month:r.month,day:r.day,isCurrentMonth:r.isCurrentMonth,isSunday:r.isSunday,isToday:r.isToday,isPast:r.isPast,notes:r.notes,reminders:r.reminders,type:l},r.key))})]})})]})})}export{Le as default};
@@ -1 +0,0 @@
1
- import{j as t}from"./note-vendor-BofYbzmZ.js";import{a as i,F as _}from"./graph-vendor-CUxe67Lr.js";import{Q as U,P as C,n as Y,i as G,o as J,r as X,t as ee,v as ne,q as te,N as re,E as oe,T as N,w as se}from"./index-BglnLSet.js";import"./note-core-BCgMq5QA.js";const ae=s=>{let a=0;for(let r=0;r<s.length;r++)a+=s.charCodeAt(r);return a},ie={background:"#f4f6f8",nodeHub:"#2c2f36",nodeSelected:"#111318",nodeConnected:"#636b76",nodeDefault:["#d6dbe1","#c8ced6","#b7bec7","#a7afb9"],nodeDimmed:["rgba(214,219,225,0.28)","rgba(200,206,214,0.24)","rgba(183,190,199,0.24)","rgba(167,175,185,0.2)"],nodeHubDimmed:"rgba(44,47,54,0.16)",nodeStroke:"#eef1f4",nodeSelectedStroke:"#a6b0bc",labelBackground:"rgba(246,248,250,0.92)",labelText:"#222831",labelFontFamily:"Pretendard Variable, Pretendard, system-ui, sans-serif",linkIdle:"rgba(99, 107, 117, 0.34)",linkConnected:"#68717c",linkDimmed:"rgba(127, 136, 146, 0.12)",legendHub:"#2c2f36"},le={background:"#121316",nodeHub:"#d6dce3",nodeSelected:"#eef1f5",nodeConnected:"#9099a4",nodeDefault:["#343a43","#2d333c","#262c35","#20262f"],nodeDimmed:["rgba(52,58,67,0.28)","rgba(45,51,60,0.24)","rgba(38,44,53,0.22)","rgba(32,38,47,0.2)"],nodeHubDimmed:"rgba(214,220,227,0.16)",nodeStroke:"#171c23",nodeSelectedStroke:"#7f8a97",labelBackground:"rgba(16,18,22,0.9)",labelText:"#eef2f6",labelFontFamily:"Pretendard Variable, Pretendard, system-ui, sans-serif",linkIdle:"rgba(118, 127, 138, 0.42)",linkConnected:"#a2abb6",linkDimmed:"rgba(118, 127, 138, 0.1)",legendHub:"#d6dce3"};function D(s){return s==="dark"?le:ie}function de(s,a){const r=D(s),{connections:g,colorIndex:y,selectedNodeId:d,nodeId:b,isConnected:c}=a,h=d===b;return d!==null&&!h&&!c?g>3?r.nodeHubDimmed:r.nodeDimmed[y%r.nodeDimmed.length]:h?r.nodeSelected:c?r.nodeConnected:g>3?r.nodeHub:r.nodeDefault[y%r.nodeDefault.length]}function ce(s,a){const r=D(s);return a.selectedNodeId!==null&&!a.isConnected?r.linkDimmed:a.isConnected?r.linkConnected:r.linkIdle}function ue(s,a){const r=D(s);return`${a.emphasize?"700":"400"} ${a.fontSize}px ${r.labelFontFamily}`}function z(s){return s<=1?3.5:s<=3?4.5:s<=6?5.5:Math.min(7,5.5+Math.sqrt(s)*.5)}const fe=t.jsx(C,{title:"Knowledge Graph",description:t.jsx(G,{width:184,height:16,className:"rounded-full"}),children:t.jsx("div",{className:"flex h-[600px] items-center justify-center",children:t.jsx(G,{width:"100%",height:"100%"})})});function he(){const s=J(),a=i.useRef(null),r=i.useRef(null),[g,y]=i.useState({width:800,height:600}),[d,b]=i.useState(null),{theme:c}=X(e=>e),h=D(c),v=i.useRef(h);v.current=h;const{data:w}=ee({queryKey:te.notes.graph(),queryFn:async()=>{const e=await ne();if(e.type==="error")throw e;return e.noteGraph}}),l=i.useMemo(()=>{if(w.nodes.length===0)return null;const e=w.nodes.filter(o=>o.connections>0);if(e.length===0)return null;const n=new Set(e.map(o=>o.id));return{nodes:e,links:w.links.filter(o=>n.has(o.source)&&n.has(o.target))}},[w]);i.useEffect(()=>{if(!l)return;const e=()=>{if(!a.current)return;const n=a.current.getBoundingClientRect();y({width:n.width,height:Math.max(600,window.innerHeight-150)})};return e(),window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[l]),i.useEffect(()=>{if(!l||!r.current)return;const e=window.setTimeout(()=>{r.current?.zoomToFit(400,50)},500);return()=>window.clearTimeout(e)},[l]);const R=i.useRef(d);R.current=d;const B=i.useCallback(e=>{if(R.current===e.id){s({to:re,params:{id:e.id}});return}b(e.id)},[s]),L=i.useCallback(()=>{b(null)},[]),K=i.useCallback(e=>{a.current&&(a.current.style.cursor=e?"pointer":"default")},[]),I=i.useRef(!1),q=i.useCallback(()=>{I.current||(I.current=!0,r.current?.enableZoomInteraction(!1))},[]),A=i.useCallback(()=>{I.current=!1,r.current?.enableZoomInteraction(!0)},[]),E=i.useRef(new Map),O=i.useMemo(()=>{const e=new Map;if(l)for(const n of l.links)e.has(n.source)||e.set(n.source,new Set),e.has(n.target)||e.set(n.target,new Set),e.get(n.source)?.add(n.target),e.get(n.target)?.add(n.source);return e},[l]);E.current=O;const Z=i.useCallback((e,n,o)=>{const u=v.current,f=d,p=E.current,m=z(e.connections),x=e.x||0,S=e.y||0,k=f===e.id,T=f?p.get(f)?.has(e.id)??!1:!1,Q=f!==null&&!k&&!T,V=ae(e.id);if(n.beginPath(),n.arc(x,S,m,0,Math.PI*2),n.fillStyle=de(c,{connections:e.connections,colorIndex:V,selectedNodeId:f,nodeId:e.id,isConnected:T}),n.fill(),Q)return;n.strokeStyle=u.nodeStroke,n.lineWidth=(k?2:1)/o,n.stroke(),k&&(n.beginPath(),n.arc(x,S,m+2/o,0,Math.PI*2),n.strokeStyle=u.nodeSelectedStroke,n.lineWidth=1.5/o,n.stroke());const W=T&&e.connections>=4;if(k||W||o>2.5){const H=e.title||"Untitled",P=Math.max(10/o,2.5);n.font=ue(c,{fontSize:P,emphasize:k}),n.textAlign="center",n.textBaseline="top";const M=n.measureText(H).width,j=2/o,F=S+m+3/o;n.fillStyle=u.labelBackground,n.fillRect(x-M/2-j,F,M+j*2,P+j*2),n.fillStyle=u.labelText,n.fillText(H,x,F+j)}},[d,c]),$=i.useCallback((e,n,o)=>{const u=d,f=e.source,p=e.target,m=u?f.id===u||p.id===u:!1;n.beginPath(),n.moveTo(f.x||0,f.y||0),n.lineTo(p.x||0,p.y||0),n.strokeStyle=ce(c,{selectedNodeId:u,isConnected:m}),n.lineWidth=m?2/o:.5/o,n.stroke()},[d,c]);return l?t.jsx(C,{title:"Knowledge Graph",description:`${l.nodes.length} linked notes, ${l.links.length} connections`,children:t.jsxs("div",{ref:a,className:"surface-base graph-canvas relative overflow-hidden",style:{"--graph-bg":h.background},children:[d&&(()=>{const e=l.nodes.find(n=>n.id===d);return e?t.jsxs("div",{className:"surface-floating absolute top-3 left-3 z-10 flex items-center gap-2 px-3 py-2",children:[t.jsx(N,{as:"span",variant:"meta",weight:"semibold",truncate:!0,className:"max-w-48",children:e.title}),t.jsxs(N,{as:"span",variant:"label",tone:"tertiary",children:[e.connections," links"]}),t.jsx("button",{type:"button",onClick:()=>b(null),className:"focus-ring-soft ml-1 flex h-6 w-6 cursor-pointer items-center justify-center rounded-[8px] text-fg-tertiary transition-colors hover:bg-hover-subtle hover:text-fg-default","aria-label":"Deselect node",children:t.jsx(se,{className:"h-3.5 w-3.5"})})]}):null})(),t.jsxs("div",{className:"surface-floating absolute top-3 right-3 z-10 flex flex-col gap-1.5 px-3 py-2.5",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("span",{className:"legend-dot h-2.5 w-2.5 shrink-0 rounded-full",style:{"--legend-color":h.legendHub}}),t.jsx(N,{as:"span",variant:"label",weight:"medium",tone:"secondary",children:"Hub notes (4+ connections)"})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("span",{className:"legend-dot h-2.5 w-2.5 shrink-0 rounded-full",style:{"--legend-color":h.nodeConnected}}),t.jsx(N,{as:"span",variant:"label",weight:"medium",tone:"secondary",children:"Connected notes"})]})]}),t.jsx(_,{ref:r,graphData:l,width:g.width,height:g.height,nodeId:"id",nodeLabel:"",nodeCanvasObject:Z,nodePointerAreaPaint:(e,n,o)=>{o.beginPath(),o.arc(e.x||0,e.y||0,Math.max(z(e.connections)+4,10),0,2*Math.PI),o.fillStyle=n,o.fill()},linkCanvasObject:$,linkCanvasObjectMode:()=>"replace",linkDirectionalParticles:0,onNodeClick:B,onNodeHover:K,onBackgroundClick:L,onNodeDrag:q,onNodeDragEnd:A,warmupTicks:30,cooldownTicks:80,d3AlphaDecay:.05,d3VelocityDecay:.3,enableZoomInteraction:!0,enablePanInteraction:!0,minZoom:.3,maxZoom:5})]})}):t.jsx(C,{title:"Knowledge Graph",description:"0 linked notes, 0 connections",children:t.jsx(oe,{title:"No constellations yet",description:"Link your notes together and watch your own starry sky unfold"})})}function ke(){return t.jsx(U,{fallback:fe,errorTitle:"Failed to load graph",errorDescription:"Retry loading your linked note constellation",renderError:({error:s,retry:a})=>t.jsx(C,{title:"Knowledge Graph",children:t.jsx(Y,{title:"Failed to load graph",description:"Retry loading your linked note constellation",error:s,onRetry:a})}),children:t.jsx(he,{})})}export{ke as default};