nsarrazin commited on
Commit
399bebf
·
1 Parent(s): 5ad620b

refactor: move delete conv & title edit to new api

Browse files
src/lib/server/api/routes/groups/conversations.ts CHANGED
@@ -3,7 +3,7 @@ import { authPlugin } from "$api/authPlugin";
3
  import { collections } from "$lib/server/database";
4
  import { ObjectId } from "mongodb";
5
  import { authCondition } from "$lib/server/auth";
6
- import { models } from "$lib/server/models";
7
  import { convertLegacyConversation } from "$lib/utils/tree/convertLegacyConversation";
8
  import type { Conversation } from "$lib/types/Conversation";
9
 
@@ -321,7 +321,7 @@ export const conversationGroup = new Elysia().use(authPlugin).group("/conversati
321
  },
322
  (app) => {
323
  return app
324
- .derive(async ({ locals, params, error }) => {
325
  let conversation;
326
  let shared = false;
327
 
@@ -334,14 +334,14 @@ export const conversationGroup = new Elysia().use(authPlugin).group("/conversati
334
  shared = true;
335
 
336
  if (!conversation) {
337
- return error(404, "Conversation not found");
338
  }
339
  } else {
340
  // todo: add validation on params.id
341
  try {
342
  new ObjectId(params.id);
343
  } catch {
344
- return error(400, "Invalid conversation ID format");
345
  }
346
  conversation = await collections.conversations.findOne({
347
  _id: new ObjectId(params.id),
@@ -355,13 +355,12 @@ export const conversationGroup = new Elysia().use(authPlugin).group("/conversati
355
  })) !== 0;
356
 
357
  if (conversationExists) {
358
- return error(
359
- 403,
360
  "You don't have access to this conversation. If someone gave you this link, ask them to use the 'share' feature instead."
361
  );
362
  }
363
 
364
- return error(404, "Conversation not found.");
365
  }
366
  }
367
 
@@ -397,8 +396,17 @@ export const conversationGroup = new Elysia().use(authPlugin).group("/conversati
397
  // todo: post new message
398
  throw new Error("Not implemented");
399
  })
400
- .delete("", () => {
401
- throw new Error("Not implemented");
 
 
 
 
 
 
 
 
 
402
  })
403
  .get("/output/:sha256", () => {
404
  // todo: get output
@@ -411,7 +419,44 @@ export const conversationGroup = new Elysia().use(authPlugin).group("/conversati
411
  .post("/stop-generating", () => {
412
  // todo: stop generating
413
  throw new Error("Not implemented");
414
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  }
416
  );
417
  });
 
3
  import { collections } from "$lib/server/database";
4
  import { ObjectId } from "mongodb";
5
  import { authCondition } from "$lib/server/auth";
6
+ import { models, validModelIdSchema } from "$lib/server/models";
7
  import { convertLegacyConversation } from "$lib/utils/tree/convertLegacyConversation";
8
  import type { Conversation } from "$lib/types/Conversation";
9
 
 
321
  },
322
  (app) => {
323
  return app
324
+ .derive(async ({ locals, params }) => {
325
  let conversation;
326
  let shared = false;
327
 
 
334
  shared = true;
335
 
336
  if (!conversation) {
337
+ throw new Error("Conversation not found");
338
  }
339
  } else {
340
  // todo: add validation on params.id
341
  try {
342
  new ObjectId(params.id);
343
  } catch {
344
+ throw new Error("Invalid conversation ID format");
345
  }
346
  conversation = await collections.conversations.findOne({
347
  _id: new ObjectId(params.id),
 
355
  })) !== 0;
356
 
357
  if (conversationExists) {
358
+ throw new Error(
 
359
  "You don't have access to this conversation. If someone gave you this link, ask them to use the 'share' feature instead."
360
  );
361
  }
362
 
363
+ throw new Error("Conversation not found.");
364
  }
365
  }
366
 
 
396
  // todo: post new message
397
  throw new Error("Not implemented");
398
  })
399
+ .delete("", async ({ locals, params }) => {
400
+ const res = await collections.conversations.deleteOne({
401
+ _id: new ObjectId(params.id),
402
+ ...authCondition(locals),
403
+ });
404
+
405
+ if (res.deletedCount === 0) {
406
+ throw new Error("Conversation not found");
407
+ }
408
+
409
+ return { success: true };
410
  })
411
  .get("/output/:sha256", () => {
412
  // todo: get output
 
419
  .post("/stop-generating", () => {
420
  // todo: stop generating
421
  throw new Error("Not implemented");
422
+ })
423
+ .patch(
424
+ "",
425
+ async ({ locals, params, body }) => {
426
+ if (body.model) {
427
+ if (!validModelIdSchema.safeParse(body.model).success) {
428
+ throw new Error("Invalid model ID");
429
+ }
430
+ }
431
+
432
+ const res = await collections.conversations.updateOne(
433
+ {
434
+ _id: new ObjectId(params.id),
435
+ ...authCondition(locals),
436
+ },
437
+ {
438
+ $set: body,
439
+ }
440
+ );
441
+
442
+ if (res.modifiedCount === 0) {
443
+ throw new Error("Conversation not found");
444
+ }
445
+
446
+ return { success: true };
447
+ },
448
+ {
449
+ body: t.Object({
450
+ title: t.Optional(
451
+ t.String({
452
+ minLength: 1,
453
+ maxLength: 100,
454
+ })
455
+ ),
456
+ model: t.Optional(t.String()),
457
+ }),
458
+ }
459
+ );
460
  }
461
  );
462
  });
src/routes/+layout.svelte CHANGED
@@ -22,12 +22,14 @@
22
  import OverloadedModal from "$lib/components/OverloadedModal.svelte";
23
  import Search from "$lib/components/chat/Search.svelte";
24
  import { setContext } from "svelte";
 
25
 
26
  let { data = $bindable(), children } = $props();
27
 
28
  setContext("publicConfig", data.publicConfig);
29
 
30
  const publicConfig = data.publicConfig;
 
31
 
32
  let conversations = $state(data.conversations);
33
  $effect(() => {
@@ -61,50 +63,35 @@
61
  }
62
 
63
  async function deleteConversation(id: string) {
64
- try {
65
- const res = await fetch(`${base}/conversation/${id}`, {
66
- method: "DELETE",
67
- headers: {
68
- "Content-Type": "application/json",
69
- },
 
 
 
 
 
 
 
 
70
  });
71
-
72
- if (!res.ok) {
73
- $error = "Error while deleting conversation, try again.";
74
- return;
75
- }
76
-
77
- conversations = conversations.filter((conv) => conv.id !== id);
78
-
79
- if ($page.params.id === id) {
80
- await goto(`${base}/`, { invalidateAll: true });
81
- }
82
- } catch (err) {
83
- console.error(err);
84
- $error = String(err);
85
- }
86
  }
87
 
88
  async function editConversationTitle(id: string, title: string) {
89
- try {
90
- const res = await fetch(`${base}/conversation/${id}`, {
91
- method: "PATCH",
92
- headers: {
93
- "Content-Type": "application/json",
94
- },
95
- body: JSON.stringify({ title }),
 
 
 
96
  });
97
-
98
- if (!res.ok) {
99
- $error = "Error while editing title, try again.";
100
- return;
101
- }
102
-
103
- conversations = conversations.map((conv) => (conv.id === id ? { ...conv, title } : conv));
104
- } catch (err) {
105
- console.error(err);
106
- $error = String(err);
107
- }
108
  }
109
 
110
  onDestroy(() => {
 
22
  import OverloadedModal from "$lib/components/OverloadedModal.svelte";
23
  import Search from "$lib/components/chat/Search.svelte";
24
  import { setContext } from "svelte";
25
+ import { handleResponse, useAPIClient } from "$lib/APIClient";
26
 
27
  let { data = $bindable(), children } = $props();
28
 
29
  setContext("publicConfig", data.publicConfig);
30
 
31
  const publicConfig = data.publicConfig;
32
+ const client = useAPIClient();
33
 
34
  let conversations = $state(data.conversations);
35
  $effect(() => {
 
63
  }
64
 
65
  async function deleteConversation(id: string) {
66
+ client
67
+ .conversations({ id })
68
+ .delete()
69
+ .then(handleResponse)
70
+ .then(async () => {
71
+ conversations = conversations.filter((conv) => conv.id !== id);
72
+
73
+ if ($page.params.id === id) {
74
+ await goto(`${base}/`, { invalidateAll: true });
75
+ }
76
+ })
77
+ .catch((err) => {
78
+ console.error(err);
79
+ $error = String(err);
80
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
 
83
  async function editConversationTitle(id: string, title: string) {
84
+ client
85
+ .conversations({ id })
86
+ .patch({ title })
87
+ .then(handleResponse)
88
+ .then(async () => {
89
+ conversations = conversations.map((conv) => (conv.id === id ? { ...conv, title } : conv));
90
+ })
91
+ .catch((err) => {
92
+ console.error(err);
93
+ $error = String(err);
94
  });
 
 
 
 
 
 
 
 
 
 
 
95
  }
96
 
97
  onDestroy(() => {