ocean-brain 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ocean-brain might be problematic. Click here for more details.

Files changed (66) hide show
  1. package/dist/index.js +41 -0
  2. package/package.json +32 -0
  3. package/server/client/dist/assets/index-BBmw_0Bo.css +1 -0
  4. package/server/client/dist/assets/index-TKn2sngc.js +393 -0
  5. package/server/client/dist/assets/module-RjUF93sV.js +716 -0
  6. package/server/client/dist/assets/native-48B9X9Wg.js +1 -0
  7. package/server/client/dist/assets/note-core-DTIu0anW.js +178 -0
  8. package/server/client/dist/assets/note-vendor-DhbUD4OO.js +54 -0
  9. package/server/client/dist/fonts/Pretendard-Bold.woff +0 -0
  10. package/server/client/dist/fonts/Pretendard-Bold.woff2 +0 -0
  11. package/server/client/dist/fonts/Pretendard-Regular.woff +0 -0
  12. package/server/client/dist/fonts/Pretendard-Regular.woff2 +0 -0
  13. package/server/client/dist/icon.png +0 -0
  14. package/server/client/dist/index.html +19 -0
  15. package/server/dist/app.js +18 -0
  16. package/server/dist/app.js.map +1 -0
  17. package/server/dist/main.js +5 -0
  18. package/server/dist/main.js.map +1 -0
  19. package/server/dist/models.js +8 -0
  20. package/server/dist/models.js.map +1 -0
  21. package/server/dist/modules/auth.js +16 -0
  22. package/server/dist/modules/auth.js.map +1 -0
  23. package/server/dist/modules/graphql.js +7 -0
  24. package/server/dist/modules/graphql.js.map +1 -0
  25. package/server/dist/modules/logger.js +72 -0
  26. package/server/dist/modules/logger.js.map +1 -0
  27. package/server/dist/modules/use-async.js +13 -0
  28. package/server/dist/modules/use-async.js.map +1 -0
  29. package/server/dist/paths.js +14 -0
  30. package/server/dist/paths.js.map +1 -0
  31. package/server/dist/schema/cache/index.js +58 -0
  32. package/server/dist/schema/cache/index.js.map +1 -0
  33. package/server/dist/schema/image/index.js +88 -0
  34. package/server/dist/schema/image/index.js.map +1 -0
  35. package/server/dist/schema/index.js +30 -0
  36. package/server/dist/schema/index.js.map +1 -0
  37. package/server/dist/schema/note/index.js +400 -0
  38. package/server/dist/schema/note/index.js.map +1 -0
  39. package/server/dist/schema/placeholder/index.js +105 -0
  40. package/server/dist/schema/placeholder/index.js.map +1 -0
  41. package/server/dist/schema/reminder/index.js +161 -0
  42. package/server/dist/schema/reminder/index.js.map +1 -0
  43. package/server/dist/schema/tag/index.js +81 -0
  44. package/server/dist/schema/tag/index.js.map +1 -0
  45. package/server/dist/types/index.js +2 -0
  46. package/server/dist/types/index.js.map +1 -0
  47. package/server/dist/types/input.js +1 -0
  48. package/server/dist/types/input.js.map +1 -0
  49. package/server/dist/urls.js +8 -0
  50. package/server/dist/urls.js.map +1 -0
  51. package/server/dist/views/image.js +101 -0
  52. package/server/dist/views/image.js.map +1 -0
  53. package/server/dist/views/index.js +2 -0
  54. package/server/dist/views/index.js.map +1 -0
  55. package/server/prisma/migrations/20230521193126_0000/migration.sql +24 -0
  56. package/server/prisma/migrations/20240317022222_0001/migration.sql +8 -0
  57. package/server/prisma/migrations/20240317094153_0002/migration.sql +8 -0
  58. package/server/prisma/migrations/20240318110450_0003/migration.sql +21 -0
  59. package/server/prisma/migrations/20240414044922_0004/migration.sql +15 -0
  60. package/server/prisma/migrations/20241115130540_0005/migration.sql +25 -0
  61. package/server/prisma/migrations/20250416124833_0006/migration.sql +29 -0
  62. package/server/prisma/migrations/20250711131318_0007/migration.sql +12 -0
  63. package/server/prisma/migrations/20251024192500_0008/migration.sql +2 -0
  64. package/server/prisma/migrations/20251026050237_0009/migration.sql +18 -0
  65. package/server/prisma/migrations/migration_lock.toml +3 -0
  66. package/server/prisma/schema.prisma +78 -0
@@ -0,0 +1,400 @@
1
+ import models from "../../models.js";
2
+ import { gql } from "../../modules/graphql.js";
3
+ const noteType = gql`
4
+ input PaginationInput {
5
+ limit: Int!
6
+ offset: Int!
7
+ }
8
+
9
+ input SearchFilterInput {
10
+ query: String!
11
+ sortBy: String
12
+ sortOrder: String
13
+ pinnedFirst: Boolean
14
+ }
15
+
16
+ input DateRangeInput {
17
+ start: String!
18
+ end: String!
19
+ }
20
+
21
+ enum NoteLayout {
22
+ narrow
23
+ wide
24
+ full
25
+ }
26
+
27
+ input NoteInput {
28
+ title: String
29
+ content: String
30
+ layout: NoteLayout
31
+ }
32
+
33
+ input NoteOrderInput {
34
+ id: ID!
35
+ order: Int!
36
+ }
37
+
38
+ type Tag {
39
+ id: ID!
40
+ name: String!
41
+ createdAt: String!
42
+ updatedAt: String!
43
+ }
44
+
45
+ type Note {
46
+ id: ID!
47
+ title: String!
48
+ content: String!
49
+ createdAt: String!
50
+ updatedAt: String!
51
+ pinned: Boolean!
52
+ order: Int!
53
+ layout: NoteLayout!
54
+ tags: [Tag!]!
55
+ }
56
+
57
+ type Notes {
58
+ totalCount: Int!
59
+ notes: [Note!]!
60
+ }
61
+ `;
62
+ const noteQuery = gql`
63
+ type GraphNode {
64
+ id: ID!
65
+ title: String!
66
+ connections: Int!
67
+ }
68
+
69
+ type GraphLink {
70
+ source: ID!
71
+ target: ID!
72
+ }
73
+
74
+ type NoteGraph {
75
+ nodes: [GraphNode!]!
76
+ links: [GraphLink!]!
77
+ }
78
+
79
+ type Query {
80
+ allNotes(searchFilter: SearchFilterInput, pagination: PaginationInput): Notes!
81
+ tagNotes(searchFilter: SearchFilterInput, pagination: PaginationInput): Notes!
82
+ notesInDateRange(dateRange: DateRangeInput): [Note!]!
83
+ pinnedNotes: [Note!]!
84
+ imageNotes(src: String!): [Note!]!
85
+ backReferences(id: ID!): [Note]!
86
+ note(id: ID!): Note!
87
+ noteGraph: NoteGraph!
88
+ }
89
+ `;
90
+ const noteMutation = gql`
91
+ type Mutation {
92
+ createNote(note: NoteInput!): Note!
93
+ updateNote(id: ID!, note: NoteInput!): Note!
94
+ deleteNote(id: ID!): Boolean!
95
+ pinNote(id: ID!, pinned: Boolean!): Note!
96
+ reorderNotes(notes: [NoteOrderInput!]!): [Note!]!
97
+ }
98
+ `;
99
+ const noteTypeDefs = `
100
+ ${noteType}
101
+ ${noteQuery}
102
+ ${noteMutation}
103
+ `;
104
+ const extractBlocksByType = (type, dataArray) => {
105
+ let result = [];
106
+ for (const data of dataArray) {
107
+ if (data.type === type) {
108
+ result.push(data);
109
+ }
110
+ if (data.children && data.children.length > 0) {
111
+ result = result.concat(extractBlocksByType(type, data.children));
112
+ }
113
+ if (data.content && data.content.length > 0) {
114
+ for (const contentItem of data.content) {
115
+ if (contentItem.type === type) {
116
+ result.push(contentItem);
117
+ }
118
+ }
119
+ }
120
+ }
121
+ return result;
122
+ };
123
+ const noteResolvers = {
124
+ Query: {
125
+ allNotes: async (_, {
126
+ searchFilter,
127
+ pagination
128
+ }) => {
129
+ const queryItems = searchFilter.query.split(" ");
130
+ const included = queryItems.filter((item) => !item.startsWith("-")).map((word) => `%${word}%`);
131
+ const excluded = queryItems.filter((item) => item.startsWith("-")).map((item) => item.slice(1)).map((word) => `%${word}%`);
132
+ const where = {
133
+ AND: [
134
+ ...included.map((keyword) => ({
135
+ OR: [
136
+ { title: { contains: keyword } },
137
+ { content: { contains: keyword } }
138
+ ]
139
+ })),
140
+ ...excluded.map((keyword) => ({
141
+ NOT: {
142
+ OR: [
143
+ { title: { contains: keyword } },
144
+ { content: { contains: keyword } }
145
+ ]
146
+ }
147
+ }))
148
+ ]
149
+ };
150
+ const sortBy = searchFilter.sortBy || "updatedAt";
151
+ const sortOrder = searchFilter.sortOrder || "desc";
152
+ const pinnedFirst = searchFilter.pinnedFirst || false;
153
+ const orderBy = [];
154
+ if (pinnedFirst) {
155
+ orderBy.push({ pinned: "desc" });
156
+ }
157
+ if (sortBy === "createdAt") {
158
+ orderBy.push({ createdAt: sortOrder });
159
+ } else {
160
+ orderBy.push({ updatedAt: sortOrder });
161
+ }
162
+ const $notes = models.note.findMany({
163
+ orderBy,
164
+ where,
165
+ take: Number(pagination.limit),
166
+ skip: Number(pagination.offset)
167
+ });
168
+ return {
169
+ totalCount: models.note.count({ where }),
170
+ notes: $notes
171
+ };
172
+ },
173
+ notesInDateRange: async (_, { dateRange }) => {
174
+ const where = {
175
+ OR: [
176
+ {
177
+ updatedAt: {
178
+ gte: new Date(dateRange.start),
179
+ lte: new Date(dateRange.end)
180
+ }
181
+ },
182
+ {
183
+ createdAt: {
184
+ gte: new Date(dateRange.start),
185
+ lte: new Date(dateRange.end)
186
+ }
187
+ }
188
+ ]
189
+ };
190
+ const $notes = await models.note.findMany({
191
+ orderBy: { createdAt: "asc" },
192
+ where
193
+ });
194
+ return $notes;
195
+ },
196
+ tagNotes: async (_, {
197
+ searchFilter,
198
+ pagination
199
+ }) => {
200
+ const where = { tags: { some: { id: Number(searchFilter.query) } } };
201
+ const $notes = models.note.findMany({
202
+ orderBy: { updatedAt: "desc" },
203
+ where,
204
+ take: Number(pagination.limit),
205
+ skip: Number(pagination.offset)
206
+ });
207
+ return {
208
+ totalCount: models.note.count({ where }),
209
+ notes: $notes
210
+ };
211
+ },
212
+ pinnedNotes: async () => models.note.findMany({
213
+ orderBy: [
214
+ { order: "asc" },
215
+ { updatedAt: "desc" }
216
+ ],
217
+ where: { pinned: true }
218
+ }),
219
+ imageNotes: async (_, { src }) => models.note.findMany({
220
+ orderBy: { updatedAt: "desc" },
221
+ where: { content: { contains: src } }
222
+ }),
223
+ backReferences: async (_, { id }) => {
224
+ return models.note.findMany({
225
+ orderBy: [
226
+ { pinned: "desc" },
227
+ { updatedAt: "desc" }
228
+ ],
229
+ where: { content: { contains: `reference","props":{"id":"${id}"` } }
230
+ });
231
+ },
232
+ note: async (_, { id }) => {
233
+ const $note = await models.note.findUnique({ where: { id: Number(id) } });
234
+ if (!$note) {
235
+ throw "NOT FOUND";
236
+ }
237
+ if ($note.content) {
238
+ const blocks = extractBlocksByType("reference", JSON.parse($note.content));
239
+ if (blocks.length > 0) {
240
+ const referenceIds = blocks.map((block) => Number(block.props.id));
241
+ const $references = await models.note.findMany({ where: { id: { in: referenceIds } } });
242
+ const newContent = $references.reduce((acc, $reference) => {
243
+ const reference = blocks.find((block) => Number(block.props.id) === $reference.id);
244
+ if (reference && reference.props.title !== $reference.title) {
245
+ return acc.replace(
246
+ `reference","props":{"id":"${reference.props.id}","title":"${reference.props.title}"`,
247
+ `reference","props":{"id":"${$reference.id}","title":"${$reference.title}"`
248
+ );
249
+ }
250
+ return acc;
251
+ }, $note.content);
252
+ if (newContent !== $note.content) {
253
+ try {
254
+ JSON.parse(newContent);
255
+ return await models.note.update({
256
+ where: { id: $note.id },
257
+ data: { content: newContent }
258
+ });
259
+ } catch (e) {
260
+ console.error(e);
261
+ }
262
+ }
263
+ }
264
+ }
265
+ return $note;
266
+ },
267
+ noteGraph: async () => {
268
+ const $notes = await models.note.findMany({
269
+ select: {
270
+ id: true,
271
+ title: true,
272
+ content: true
273
+ }
274
+ });
275
+ const nodes = [];
276
+ const links = [];
277
+ const connectionCount = {};
278
+ const linkSet = /* @__PURE__ */ new Set();
279
+ for (const $note of $notes) {
280
+ if ($note.content) {
281
+ try {
282
+ const blocks = extractBlocksByType("reference", JSON.parse($note.content));
283
+ for (const block of blocks) {
284
+ const targetId = block.props.id;
285
+ if (targetId && String($note.id) !== targetId) {
286
+ const linkKey = `${$note.id}-${targetId}`;
287
+ const reverseLinkKey = `${targetId}-${$note.id}`;
288
+ if (!linkSet.has(linkKey) && !linkSet.has(reverseLinkKey)) {
289
+ linkSet.add(linkKey);
290
+ links.push({
291
+ source: String($note.id),
292
+ target: targetId
293
+ });
294
+ connectionCount[String($note.id)] = (connectionCount[String($note.id)] || 0) + 1;
295
+ connectionCount[targetId] = (connectionCount[targetId] || 0) + 1;
296
+ }
297
+ }
298
+ }
299
+ } catch {
300
+ }
301
+ }
302
+ }
303
+ for (const $note of $notes) {
304
+ nodes.push({
305
+ id: String($note.id),
306
+ title: $note.title || "Untitled",
307
+ connections: connectionCount[String($note.id)] || 0
308
+ });
309
+ }
310
+ return {
311
+ nodes,
312
+ links
313
+ };
314
+ }
315
+ },
316
+ Mutation: {
317
+ createNote: async (_, { note }) => {
318
+ const PLACEHOLDER_PREFIX = "{%";
319
+ const PLACEHOLDER_SUFFIX = "%}";
320
+ const replacePlaceholder = async (content) => {
321
+ const placeholders = content.matchAll(new RegExp(`${PLACEHOLDER_PREFIX}([^}]+)${PLACEHOLDER_SUFFIX}`, "g"));
322
+ const $placeholders = await models.placeholder.findMany({
323
+ select: {
324
+ template: true,
325
+ replacement: true
326
+ },
327
+ where: { template: { in: Array.from(new Set(Array.from(placeholders, (p) => p[1]))) } }
328
+ });
329
+ for (const $placeholder of $placeholders) {
330
+ content = content.replace(new RegExp(`${PLACEHOLDER_PREFIX}${$placeholder.template}${PLACEHOLDER_SUFFIX}`, "g"), $placeholder.replacement);
331
+ }
332
+ return content;
333
+ };
334
+ const replacedTitle = await replacePlaceholder(note.title);
335
+ const replacedContent = await replacePlaceholder(note.content);
336
+ const $note = await models.note.create({
337
+ data: {
338
+ title: replacedTitle,
339
+ content: replacedContent,
340
+ ...note.layout && { layout: note.layout }
341
+ }
342
+ });
343
+ if (note.content) {
344
+ const blocks = extractBlocksByType(
345
+ "tag",
346
+ JSON.parse(note.content)
347
+ );
348
+ return await models.note.update({
349
+ where: { id: $note.id },
350
+ data: { tags: { set: blocks.map((block) => ({ id: Number(block.props.id) })) } }
351
+ });
352
+ }
353
+ return $note;
354
+ },
355
+ updateNote: async (_, { id, note }) => {
356
+ let blocks = [];
357
+ if (note.content) {
358
+ blocks = extractBlocksByType(
359
+ "tag",
360
+ JSON.parse(note.content)
361
+ );
362
+ }
363
+ const $note = await models.note.update({
364
+ where: { id: Number(id) },
365
+ data: {
366
+ ...note,
367
+ ...note.content ? { tags: { set: blocks.map((block) => ({ id: Number(block.props.id) })) } } : {}
368
+ }
369
+ });
370
+ return $note;
371
+ },
372
+ deleteNote: async (_, { id }) => {
373
+ await models.tag.deleteMany({ where: { notes: { none: {} } } });
374
+ await models.note.delete({ where: { id: Number(id) } });
375
+ return true;
376
+ },
377
+ pinNote: (_, { id, pinned }) => models.note.update({
378
+ where: { id: Number(id) },
379
+ data: { pinned: Boolean(pinned) }
380
+ }),
381
+ reorderNotes: async (_, { notes }) => {
382
+ const updatePromises = notes.map(
383
+ ({ id, order }) => models.note.update({
384
+ where: { id: Number(id) },
385
+ data: { order }
386
+ })
387
+ );
388
+ return await Promise.all(updatePromises);
389
+ }
390
+ },
391
+ Note: { tags: async (note) => await models.tag.findMany({ where: { notes: { some: { id: note.id } } } }) }
392
+ };
393
+ export {
394
+ noteMutation,
395
+ noteQuery,
396
+ noteResolvers,
397
+ noteType,
398
+ noteTypeDefs
399
+ };
400
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/schema/note/index.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\n\nimport models from '~/models.js';\nimport { gql } from '~/modules/graphql.js';\n\nimport type { Note, Prisma } from '~/models.js';\nimport type { Pagination, SearchFilter, NoteInput } from '~/types/index.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 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 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\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 notesInDateRange(dateRange: DateRangeInput): [Note!]!\n pinnedNotes: [Note!]!\n imageNotes(src: String!): [Note!]!\n backReferences(id: ID!): [Note]!\n note(id: ID!): Note!\n noteGraph: NoteGraph!\n }\n`;\n\nexport const noteMutation = gql`\n type Mutation {\n createNote(note: NoteInput!): Note!\n updateNote(id: ID!, note: NoteInput!): Note!\n deleteNote(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\ninterface BlockNote<T = unknown> {\n id: string;\n type: string;\n props: T;\n content?: BlockNote<T>[];\n children?: BlockNote<T>[];\n}\n\nconst extractBlocksByType = <T>(type: string, dataArray: BlockNote[]): BlockNote<T>[] => {\n let result: BlockNote[] = [];\n\n for (const data of dataArray) {\n if (data.type === type) {\n result.push(data);\n }\n\n if (data.children && data.children.length > 0) {\n result = result.concat(extractBlocksByType(type, data.children));\n }\n\n if (data.content && data.content.length > 0) {\n for (const contentItem of data.content) {\n if (contentItem.type === type) {\n result.push(contentItem);\n }\n }\n }\n }\n\n return result as unknown as BlockNote<T>[];\n};\n\nexport const noteResolvers: IResolvers = {\n Query: {\n allNotes: async (_, {\n searchFilter,\n pagination\n }: {\n searchFilter: SearchFilter;\n pagination: Pagination;\n }) => {\n const queryItems = searchFilter.query.split(' ');\n const included = queryItems\n .filter((item: string) => !item.startsWith('-'))\n .map((word: string) => `%${word}%`);\n const excluded = queryItems\n .filter((item: string) => item.startsWith('-'))\n .map((item: string) => item.slice(1))\n .map((word: string) => `%${word}%`);\n\n const where: Prisma.NoteWhereInput = {\n AND: [\n ...included.map((keyword: string) => ({\n OR: [\n { title: { contains: keyword } },\n { content: { contains: keyword } }\n ]\n })),\n ...excluded.map((keyword: string) => ({\n NOT: {\n OR: [\n { title: { contains: keyword } },\n { content: { contains: keyword } }\n ]\n }\n }))\n ]\n };\n\n const sortBy = searchFilter.sortBy || 'updatedAt';\n const sortOrder = searchFilter.sortOrder || 'desc';\n const pinnedFirst = searchFilter.pinnedFirst || false;\n\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 const $notes = models.note.findMany({\n orderBy,\n where,\n take: Number(pagination.limit),\n skip: Number(pagination.offset)\n });\n return {\n totalCount: models.note.count({ where }),\n notes: $notes\n };\n },\n notesInDateRange: async (_, { dateRange }: {\n dateRange: {\n start: string;\n end: string;\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 const $notes = await models.note.findMany({\n orderBy: { createdAt: 'asc' },\n where\n });\n\n return $notes;\n },\n tagNotes: async (_, {\n searchFilter,\n pagination\n }: {\n searchFilter: SearchFilter;\n pagination: Pagination;\n }) => {\n const where: Prisma.NoteWhereInput = { tags: { some: { id: Number(searchFilter.query) } } };\n\n const $notes = models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where,\n take: Number(pagination.limit),\n skip: Number(pagination.offset)\n });\n return {\n totalCount: models.note.count({ where }),\n notes: $notes\n };\n },\n pinnedNotes: async () => models.note.findMany({\n orderBy: [\n { order: 'asc' },\n { updatedAt: 'desc' }\n ],\n where: { pinned: true }\n }),\n imageNotes: async (_, { src }) => models.note.findMany({\n orderBy: { updatedAt: 'desc' },\n where: { content: { contains: src } }\n }),\n backReferences: async (_, { id }: Note) => {\n return models.note.findMany({\n orderBy: [\n { pinned: 'desc' },\n { updatedAt: 'desc' }\n ],\n where: { content: { contains: `reference\",\"props\":{\"id\":\"${id}\"` } }\n });\n },\n note: async (_, { id }: Note) => {\n const $note = await models.note.findUnique({ where: { id: Number(id) } });\n if (!$note) {\n throw 'NOT FOUND';\n }\n if ($note.content) {\n const blocks = extractBlocksByType<{\n id: string;\n title: string;\n }>('reference', JSON.parse($note.content));\n if (blocks.length > 0) {\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>((acc: string, $reference: Note) => {\n const reference = blocks.find(block => Number(block.props.id) === $reference.id);\n if (reference && reference.props.title !== $reference.title) {\n return acc.replace(\n `reference\",\"props\":{\"id\":\"${reference.props.id}\",\"title\":\"${reference.props.title}\"`,\n `reference\",\"props\":{\"id\":\"${$reference.id}\",\"title\":\"${$reference.title}\"`\n );\n }\n return acc;\n }, $note.content);\n if (newContent !== $note.content) {\n try {\n JSON.parse(newContent);\n return await models.note.update({\n where: { id: $note.id },\n data: { content: newContent }\n });\n } catch (e) {\n console.error(e);\n }\n }\n }\n }\n return $note;\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 // Extract all references from each note\n for (const $note of $notes) {\n if ($note.content) {\n try {\n const blocks = extractBlocksByType<{ id: string }>('reference', JSON.parse($note.content));\n for (const block of blocks) {\n const targetId = block.props.id;\n // Avoid self-references and duplicate links\n if (targetId && String($note.id) !== targetId) {\n const linkKey = `${$note.id}-${targetId}`;\n const reverseLinkKey = `${targetId}-${$note.id}`;\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 // Count connections for both nodes\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\n // Build nodes array with connection counts\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 Mutation: {\n createNote: async (_, { note }: { note: NoteInput }) => {\n const PLACEHOLDER_PREFIX = '{%';\n const PLACEHOLDER_SUFFIX = '%}';\n\n const replacePlaceholder = async (content: string) => {\n const placeholders = content.matchAll(new RegExp(`${PLACEHOLDER_PREFIX}([^}]+)${PLACEHOLDER_SUFFIX}`, 'g'));\n const $placeholders = await models.placeholder.findMany({\n select: {\n template: true,\n replacement: true\n },\n where: { template: { in: Array.from(new Set(Array.from(placeholders, p => p[1]))) } }\n });\n\n for (const $placeholder of $placeholders) {\n content = content.replace(new RegExp(`${PLACEHOLDER_PREFIX}${$placeholder.template}${PLACEHOLDER_SUFFIX}`, 'g'), $placeholder.replacement);\n }\n return content;\n };\n\n const replacedTitle = await replacePlaceholder(note.title);\n const replacedContent = await replacePlaceholder(note.content);\n\n const $note = await models.note.create({\n data: {\n title: replacedTitle,\n content: replacedContent,\n ...(note.layout && { layout: note.layout })\n }\n });\n if (note.content) {\n const blocks = extractBlocksByType<{ id: string }>(\n 'tag',\n JSON.parse(note.content)\n );\n\n return await models.note.update({\n where: { id: $note.id },\n data: { tags: { set: blocks.map(block => ({ id: Number(block.props.id) })) } }\n });\n }\n\n return $note;\n },\n updateNote: async (_, { id, note }: { id: number; note: NoteInput }) => {\n let blocks: BlockNote<{ id: string }>[] = [];\n\n if (note.content) {\n blocks = extractBlocksByType<{ id: string }>(\n 'tag',\n JSON.parse(note.content)\n );\n }\n\n const $note = await models.note.update({\n where: { id: Number(id) },\n data: {\n ...note,\n ...(note.content ? { tags: { set: blocks.map(block => ({ id: Number(block.props.id) })) } } : {})\n }\n });\n return $note;\n },\n deleteNote: async (_, { id }: Note) => {\n await models.tag.deleteMany({ where: { notes: { none: {} } } });\n await models.note.delete({ where: { id: Number(id) } });\n return true;\n },\n pinNote: (_, { id, pinned }: Note) => models.note.update({\n where: { id: Number(id) },\n data: { pinned: Boolean(pinned) }\n }),\n reorderNotes: async (_, { notes }: { notes: Array<{ id: string; order: number }> }) => {\n const updatePromises = notes.map(({ id, order }) =>\n models.note.update({\n where: { id: Number(id) },\n data: { order }\n })\n );\n return await Promise.all(updatePromises);\n }\n },\n Note: { tags: async (note: Note) => await models.tag.findMany({ where: { notes: { some: { id: note.id } } } }) }\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,105 @@
1
+ import models from "../../models.js";
2
+ import { gql } from "../../modules/graphql.js";
3
+ const placeholderType = gql`
4
+ input PaginationInput {
5
+ limit: Int!
6
+ offset: Int!
7
+ }
8
+
9
+ input SearchFilterInput {
10
+ query: String!
11
+ }
12
+
13
+ type Placeholder {
14
+ id: ID!
15
+ name: String!
16
+ template: String!
17
+ replacement: String!
18
+ createdAt: String!
19
+ updatedAt: String!
20
+ }
21
+
22
+ type Placeholders {
23
+ totalCount: Int!
24
+ placeholders: [Placeholder!]!
25
+ }
26
+ `;
27
+ const placeholderQuery = gql`
28
+ type Query {
29
+ allPlaceholders(searchFilter: SearchFilterInput, pagination: PaginationInput): Placeholders!
30
+ placeholder(id: ID!): Placeholder
31
+ }
32
+ `;
33
+ const placeholderMutation = gql`
34
+ type Mutation {
35
+ createPlaceholder(name: String!, template: String!, replacement: String): Placeholder!
36
+ updatePlaceholder(id: ID!, name: String, template: String, replacement: String): Placeholder!
37
+ deletePlaceholder(id: ID!): Boolean!
38
+ }
39
+ `;
40
+ const placeholderTypeDefs = `
41
+ ${placeholderType}
42
+ ${placeholderQuery}
43
+ ${placeholderMutation}
44
+ `;
45
+ const placeholderResolvers = {
46
+ Query: {
47
+ allPlaceholders: async (_, { searchFilter, pagination }) => {
48
+ const placeholders = await models.placeholder.findMany({
49
+ where: searchFilter?.query ? { name: { contains: searchFilter.query } } : void 0,
50
+ take: pagination?.limit,
51
+ skip: pagination?.offset
52
+ });
53
+ const totalCount = await models.placeholder.count();
54
+ return {
55
+ totalCount,
56
+ placeholders
57
+ };
58
+ },
59
+ placeholder: async (_, { id }) => {
60
+ return await models.placeholder.findFirst({ where: { id } });
61
+ }
62
+ },
63
+ Mutation: {
64
+ createPlaceholder: async (_, { name, template, replacement }) => {
65
+ return await models.placeholder.create({
66
+ data: {
67
+ name,
68
+ template,
69
+ replacement
70
+ }
71
+ });
72
+ },
73
+ updatePlaceholder: async (_, { id, name, template, replacement }) => {
74
+ const placeholder = await models.placeholder.findFirst({ where: { id } });
75
+ if (!placeholder) {
76
+ throw new Error("Placeholder not found");
77
+ }
78
+ await models.placeholder.update({
79
+ where: { id },
80
+ data: {
81
+ name,
82
+ template,
83
+ replacement
84
+ }
85
+ });
86
+ return placeholder;
87
+ },
88
+ deletePlaceholder: async (_, { id }) => {
89
+ const placeholder = await models.placeholder.findFirst({ where: { id: Number(id) } });
90
+ if (!placeholder) {
91
+ return false;
92
+ }
93
+ await models.placeholder.delete({ where: { id: Number(id) } });
94
+ return true;
95
+ }
96
+ }
97
+ };
98
+ export {
99
+ placeholderMutation,
100
+ placeholderQuery,
101
+ placeholderResolvers,
102
+ placeholderType,
103
+ placeholderTypeDefs
104
+ };
105
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/schema/placeholder/index.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\n\nimport models, { type Placeholder } from '~/models.js';\nimport { gql } from '~/modules/graphql.js';\nimport type { Pagination, SearchFilter } from '~/types/index.js';\n\nexport const placeholderType = gql`\n input PaginationInput {\n limit: Int!\n offset: Int!\n }\n\n input SearchFilterInput {\n query: String!\n }\n\n type Placeholder {\n id: ID!\n name: String!\n template: String!\n replacement: String!\n createdAt: String!\n updatedAt: String!\n }\n\n type Placeholders {\n totalCount: Int!\n placeholders: [Placeholder!]!\n }\n`;\n\nexport const placeholderQuery = gql`\n type Query {\n allPlaceholders(searchFilter: SearchFilterInput, pagination: PaginationInput): Placeholders!\n placeholder(id: ID!): Placeholder\n }\n`;\n\nexport const placeholderMutation = gql`\n type Mutation {\n createPlaceholder(name: String!, template: String!, replacement: String): Placeholder!\n updatePlaceholder(id: ID!, name: String, template: String, replacement: String): Placeholder!\n deletePlaceholder(id: ID!): Boolean!\n }\n`;\n\nexport const placeholderTypeDefs = `\n ${placeholderType}\n ${placeholderQuery}\n ${placeholderMutation}\n`;\n\nexport const placeholderResolvers: IResolvers = {\n Query: {\n allPlaceholders: async (_, { searchFilter, pagination }: { searchFilter?: SearchFilter; pagination?: Pagination }) => {\n const placeholders = await models.placeholder.findMany({\n where: searchFilter?.query ? { name: { contains: searchFilter.query } } : undefined,\n take: pagination?.limit,\n skip: pagination?.offset\n });\n\n const totalCount = await models.placeholder.count();\n\n return {\n totalCount,\n placeholders\n };\n },\n placeholder: async (_, { id }: { id: number }) => {\n return await models.placeholder.findFirst({ where: { id } });\n }\n },\n Mutation: {\n createPlaceholder: async (_, { name, template, replacement }: Placeholder) => {\n return await models.placeholder.create({\n data: {\n name,\n template,\n replacement\n }\n });\n },\n updatePlaceholder: async (_, { id, name, template, replacement }: Placeholder) => {\n const placeholder = await models.placeholder.findFirst({ where: { id } });\n if (!placeholder) {\n throw new Error('Placeholder not found');\n }\n\n await models.placeholder.update({\n where: { id },\n data: {\n name,\n template,\n replacement\n }\n });\n\n return placeholder;\n },\n deletePlaceholder: async (_, { id }: { id: number }) => {\n const placeholder = await models.placeholder.findFirst({ where: { id: Number(id) } });\n if (!placeholder) {\n return false;\n }\n\n await models.placeholder.delete({ where: { id: Number(id) } });\n return true;\n }\n }\n};\n"],"mappings":"AAEA,OAAO,YAAkC;AACzC,SAAS,WAAW;AAGb,MAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBxB,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAOzB,MAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ5B,MAAM,sBAAsB;AAAA,MAC7B,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,mBAAmB;AAAA;AAGlB,MAAM,uBAAmC;AAAA,EAC5C,OAAO;AAAA,IACH,iBAAiB,OAAO,GAAG,EAAE,cAAc,WAAW,MAAgE;AAClH,YAAM,eAAe,MAAM,OAAO,YAAY,SAAS;AAAA,QACnD,OAAO,cAAc,QAAQ,EAAE,MAAM,EAAE,UAAU,aAAa,MAAM,EAAE,IAAI;AAAA,QAC1E,MAAM,YAAY;AAAA,QAClB,MAAM,YAAY;AAAA,MACtB,CAAC;AAED,YAAM,aAAa,MAAM,OAAO,YAAY,MAAM;AAElD,aAAO;AAAA,QACH;AAAA,QACA;AAAA,MACJ;AAAA,IACJ;AAAA,IACA,aAAa,OAAO,GAAG,EAAE,GAAG,MAAsB;AAC9C,aAAO,MAAM,OAAO,YAAY,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAAA,IAC/D;AAAA,EACJ;AAAA,EACA,UAAU;AAAA,IACN,mBAAmB,OAAO,GAAG,EAAE,MAAM,UAAU,YAAY,MAAmB;AAC1E,aAAO,MAAM,OAAO,YAAY,OAAO;AAAA,QACnC,MAAM;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,QACJ;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,IACA,mBAAmB,OAAO,GAAG,EAAE,IAAI,MAAM,UAAU,YAAY,MAAmB;AAC9E,YAAM,cAAc,MAAM,OAAO,YAAY,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AACxE,UAAI,CAAC,aAAa;AACd,cAAM,IAAI,MAAM,uBAAuB;AAAA,MAC3C;AAEA,YAAM,OAAO,YAAY,OAAO;AAAA,QAC5B,OAAO,EAAE,GAAG;AAAA,QACZ,MAAM;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,QACJ;AAAA,MACJ,CAAC;AAED,aAAO;AAAA,IACX;AAAA,IACA,mBAAmB,OAAO,GAAG,EAAE,GAAG,MAAsB;AACpD,YAAM,cAAc,MAAM,OAAO,YAAY,UAAU,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC;AACpF,UAAI,CAAC,aAAa;AACd,eAAO;AAAA,MACX;AAEA,YAAM,OAAO,YAAY,OAAO,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC;AAC7D,aAAO;AAAA,IACX;AAAA,EACJ;AACJ;","names":[]}