@chat-js/cli 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/index.js +1163 -959
  2. package/package.json +1 -1
  3. package/templates/chat-app/app/(auth)/device-login/page.tsx +37 -0
  4. package/templates/chat-app/app/(auth)/login/page.tsx +26 -2
  5. package/templates/chat-app/app/(auth)/register/page.tsx +0 -12
  6. package/templates/chat-app/app/(chat)/api/chat/filter-reasoning-parts.ts +1 -1
  7. package/templates/chat-app/app/(chat)/api/chat/route.ts +13 -5
  8. package/templates/chat-app/app/(chat)/layout.tsx +4 -1
  9. package/templates/chat-app/app/api/trpc/[trpc]/route.ts +1 -0
  10. package/templates/chat-app/app/globals.css +9 -9
  11. package/templates/chat-app/app/layout.tsx +4 -2
  12. package/templates/chat-app/biome.jsonc +3 -3
  13. package/templates/chat-app/chat.config.ts +144 -141
  14. package/templates/chat-app/components/ai-elements/prompt-input.tsx +1 -1
  15. package/templates/chat-app/components/anonymous-session-init.tsx +10 -6
  16. package/templates/chat-app/components/artifact-actions.tsx +81 -18
  17. package/templates/chat-app/components/artifact-panel.tsx +142 -41
  18. package/templates/chat-app/components/attachment-list.tsx +1 -1
  19. package/templates/chat-app/components/{social-auth-providers.tsx → auth-providers.tsx} +49 -4
  20. package/templates/chat-app/components/chat/chat-welcome.tsx +3 -3
  21. package/templates/chat-app/components/chat-menu-items.tsx +1 -1
  22. package/templates/chat-app/components/chat-sync.tsx +3 -8
  23. package/templates/chat-app/components/console.tsx +9 -9
  24. package/templates/chat-app/components/context-usage.tsx +2 -2
  25. package/templates/chat-app/components/create-artifact.tsx +15 -5
  26. package/templates/chat-app/components/data-stream-handler.tsx +57 -16
  27. package/templates/chat-app/components/device-login-page.tsx +191 -0
  28. package/templates/chat-app/components/diffview.tsx +8 -2
  29. package/templates/chat-app/components/electron-auth-handler.tsx +184 -0
  30. package/templates/chat-app/components/electron-auth-ui.tsx +121 -0
  31. package/templates/chat-app/components/favicon-group.tsx +1 -1
  32. package/templates/chat-app/components/feedback-actions.tsx +1 -1
  33. package/templates/chat-app/components/greeting.tsx +1 -1
  34. package/templates/chat-app/components/interactive-chart-impl.tsx +3 -4
  35. package/templates/chat-app/components/interactive-charts.tsx +1 -1
  36. package/templates/chat-app/components/login-form.tsx +52 -10
  37. package/templates/chat-app/components/message-editor.tsx +4 -5
  38. package/templates/chat-app/components/model-selector.tsx +661 -655
  39. package/templates/chat-app/components/multimodal-input.tsx +13 -10
  40. package/templates/chat-app/components/parallel-response-cards.tsx +53 -35
  41. package/templates/chat-app/components/part/code-execution.tsx +8 -2
  42. package/templates/chat-app/components/part/document-common.tsx +1 -1
  43. package/templates/chat-app/components/part/document-preview.tsx +5 -5
  44. package/templates/chat-app/components/part/retrieve-url.tsx +12 -12
  45. package/templates/chat-app/components/part/text-message-part.tsx +13 -9
  46. package/templates/chat-app/components/project-chat-item.tsx +1 -1
  47. package/templates/chat-app/components/project-menu-items.tsx +1 -1
  48. package/templates/chat-app/components/research-task.tsx +1 -1
  49. package/templates/chat-app/components/research-tasks.tsx +1 -1
  50. package/templates/chat-app/components/retry-button.tsx +1 -1
  51. package/templates/chat-app/components/sandbox.tsx +1 -1
  52. package/templates/chat-app/components/sheet-editor.tsx +7 -7
  53. package/templates/chat-app/components/sidebar-chats-list.tsx +1 -1
  54. package/templates/chat-app/components/sidebar-toggle.tsx +15 -2
  55. package/templates/chat-app/components/sidebar-top-row.tsx +27 -12
  56. package/templates/chat-app/components/sidebar-user-nav.tsx +10 -1
  57. package/templates/chat-app/components/signup-form.tsx +49 -10
  58. package/templates/chat-app/components/sources.tsx +4 -4
  59. package/templates/chat-app/components/text-editor.tsx +5 -2
  60. package/templates/chat-app/components/toolbar.tsx +3 -3
  61. package/templates/chat-app/components/ui/sidebar.tsx +0 -1
  62. package/templates/chat-app/components/upgrade-cta/limit-display.tsx +1 -1
  63. package/templates/chat-app/components/user-message.tsx +135 -134
  64. package/templates/chat-app/electron.d.ts +41 -0
  65. package/templates/chat-app/evals/my-eval.eval.ts +3 -1
  66. package/templates/chat-app/hooks/use-artifact.tsx +13 -13
  67. package/templates/chat-app/lib/ai/gateways/provider-types.ts +19 -10
  68. package/templates/chat-app/lib/ai/stream-errors.test.ts +72 -0
  69. package/templates/chat-app/lib/ai/stream-errors.ts +94 -0
  70. package/templates/chat-app/lib/ai/tools/code-execution.javascript.ts +171 -0
  71. package/templates/chat-app/lib/ai/tools/code-execution.python.ts +336 -0
  72. package/templates/chat-app/lib/ai/tools/code-execution.shared.test.ts +71 -0
  73. package/templates/chat-app/lib/ai/tools/code-execution.shared.ts +59 -0
  74. package/templates/chat-app/lib/ai/tools/code-execution.ts +62 -391
  75. package/templates/chat-app/lib/ai/tools/code-execution.types.ts +24 -0
  76. package/templates/chat-app/lib/ai/tools/steps/multi-query-web-search.ts +3 -2
  77. package/templates/chat-app/lib/anonymous-session-client.ts +0 -3
  78. package/templates/chat-app/lib/artifacts/code/client.tsx +35 -5
  79. package/templates/chat-app/lib/artifacts/sheet/client.tsx +11 -3
  80. package/templates/chat-app/lib/auth-client.ts +23 -1
  81. package/templates/chat-app/lib/auth.ts +18 -1
  82. package/templates/chat-app/lib/blob.ts +1 -1
  83. package/templates/chat-app/lib/clone-messages.ts +1 -1
  84. package/templates/chat-app/lib/config-schema.ts +13 -1
  85. package/templates/chat-app/lib/constants.ts +3 -4
  86. package/templates/chat-app/lib/db/migrations/meta/0044_snapshot.json +42 -129
  87. package/templates/chat-app/lib/db/migrations/meta/_journal.json +1 -1
  88. package/templates/chat-app/lib/editor/config.ts +4 -4
  89. package/templates/chat-app/lib/electron-auth.ts +96 -0
  90. package/templates/chat-app/lib/env-schema.ts +33 -4
  91. package/templates/chat-app/lib/message-conversion.ts +1 -1
  92. package/templates/chat-app/lib/playwright-test-environment.ts +18 -0
  93. package/templates/chat-app/lib/social-auth.ts +5 -0
  94. package/templates/chat-app/lib/stores/hooks-threads.ts +2 -1
  95. package/templates/chat-app/lib/stores/with-threads.test.ts +1 -1
  96. package/templates/chat-app/lib/stores/with-threads.ts +5 -6
  97. package/templates/chat-app/lib/stores/with-tracing.ts +1 -1
  98. package/templates/chat-app/lib/thread-utils.ts +19 -21
  99. package/templates/chat-app/lib/utils/download-assets.ts +6 -7
  100. package/templates/chat-app/lib/utils/rate-limit.ts +9 -3
  101. package/templates/chat-app/package.json +20 -18
  102. package/templates/chat-app/playwright.config.ts +0 -19
  103. package/templates/chat-app/providers/chat-input-provider.tsx +1 -1
  104. package/templates/chat-app/proxy.ts +28 -3
  105. package/templates/chat-app/scripts/check-env.ts +10 -0
  106. package/templates/chat-app/trpc/server.tsx +7 -2
  107. package/templates/chat-app/tsconfig.json +2 -1
  108. package/templates/chat-app/vercel.json +0 -10
  109. package/templates/electron/CHANGELOG.md +7 -0
  110. package/templates/electron/README.md +54 -0
  111. package/templates/electron/entitlements.mac.plist +10 -0
  112. package/templates/electron/forge.config.ts +157 -0
  113. package/templates/electron/icon.png +0 -0
  114. package/templates/electron/package.json +53 -0
  115. package/templates/electron/scripts/generate-icons.test.js +37 -0
  116. package/templates/electron/scripts/generate-icons.ts +29 -0
  117. package/templates/electron/scripts/run-forge.cjs +28 -0
  118. package/templates/electron/scripts/write-branding.ts +18 -0
  119. package/templates/electron/src/config.ts +16 -0
  120. package/templates/electron/src/lib/auth-client.ts +64 -0
  121. package/templates/electron/src/main.ts +670 -0
  122. package/templates/electron/src/preload.d.ts +27 -0
  123. package/templates/electron/src/preload.ts +25 -0
  124. package/templates/electron/tsconfig.json +18 -0
@@ -6,7 +6,7 @@ import {
6
6
  type ConsoleOutput,
7
7
  type ConsoleOutputContent,
8
8
  } from "@/components/console";
9
- import { Artifact } from "@/components/create-artifact";
9
+ import { Artifact, type ArtifactMetadata } from "@/components/create-artifact";
10
10
  import { config } from "@/lib/config";
11
11
  import { generateUUID, getLanguageFromFileName } from "@/lib/utils";
12
12
 
@@ -56,12 +56,36 @@ function detectRequiredHandlers(code: string): string[] {
56
56
  return handlers;
57
57
  }
58
58
 
59
- interface Metadata {
59
+ export interface CodeArtifactMetadata {
60
60
  language: string;
61
61
  outputs: ConsoleOutput[];
62
62
  }
63
63
 
64
- export const codeArtifact = new Artifact<"code", Metadata>({
64
+ export function isCodeArtifactMetadata(
65
+ metadata: ArtifactMetadata
66
+ ): metadata is CodeArtifactMetadata {
67
+ return (
68
+ metadata !== null &&
69
+ typeof metadata === "object" &&
70
+ "language" in metadata &&
71
+ typeof metadata.language === "string" &&
72
+ "outputs" in metadata &&
73
+ Array.isArray(metadata.outputs)
74
+ );
75
+ }
76
+
77
+ export function getCodeArtifactMetadata(
78
+ metadata: ArtifactMetadata
79
+ ): CodeArtifactMetadata {
80
+ return isCodeArtifactMetadata(metadata)
81
+ ? metadata
82
+ : {
83
+ language: "python",
84
+ outputs: [],
85
+ };
86
+ }
87
+
88
+ export const codeArtifact = new Artifact<"code", CodeArtifactMetadata>({
65
89
  kind: "code",
66
90
  description:
67
91
  "Useful for code generation; Code execution is only available for Python code.",
@@ -184,14 +208,20 @@ export const codeArtifact = new Artifact<"code", Metadata>({
184
208
  },
185
209
  ],
186
210
  }));
187
- } catch (error: any) {
211
+ } catch (error: unknown) {
188
212
  setMetadata((metadata) => ({
189
213
  ...metadata,
190
214
  outputs: [
191
215
  ...metadata.outputs.filter((output) => output.id !== runId),
192
216
  {
193
217
  id: runId,
194
- contents: [{ type: "text", value: error.message }],
218
+ contents: [
219
+ {
220
+ type: "text",
221
+ value:
222
+ error instanceof Error ? error.message : String(error),
223
+ },
224
+ ],
195
225
  status: "failed",
196
226
  },
197
227
  ],
@@ -1,13 +1,21 @@
1
1
  import { Copy, LineChart, Redo2, Sparkles, Undo2 } from "lucide-react";
2
2
  import { parse, unparse } from "papaparse";
3
3
  import { toast } from "sonner";
4
- import { Artifact } from "@/components/create-artifact";
4
+ import { Artifact, type ArtifactMetadata } from "@/components/create-artifact";
5
5
  import { SpreadsheetEditor } from "@/components/sheet-editor";
6
6
  import { config } from "@/lib/config";
7
7
 
8
- type Metadata = any;
8
+ export type SheetArtifactMetadata = Record<string, unknown>;
9
9
 
10
- export const sheetArtifact = new Artifact<"sheet", Metadata>({
10
+ export function getSheetArtifactMetadata(
11
+ metadata: ArtifactMetadata
12
+ ): SheetArtifactMetadata {
13
+ return metadata && typeof metadata === "object"
14
+ ? Object.fromEntries(Object.entries(metadata))
15
+ : {};
16
+ }
17
+
18
+ export const sheetArtifact = new Artifact<"sheet", SheetArtifactMetadata>({
11
19
  kind: "sheet",
12
20
  description: "Useful for working with spreadsheets",
13
21
  initialize: async () => {
@@ -1,10 +1,32 @@
1
+ import { electronProxyClient } from "@better-auth/electron/proxy";
1
2
  import { nextCookies } from "better-auth/next-js";
2
3
  import { createAuthClient } from "better-auth/react";
4
+ import { config } from "@/lib/config";
5
+ import {
6
+ ELECTRON_APP_SCHEME,
7
+ ELECTRON_AUTH_CALLBACK_PATH,
8
+ ELECTRON_AUTH_CLIENT_ID,
9
+ ELECTRON_AUTH_COOKIE_PREFIX,
10
+ } from "@/lib/electron-auth";
3
11
 
4
12
  // Better Auth auto-detects the base URL from window.location.origin on client
5
13
  // and uses relative URLs for SSR, so we don't need to specify baseURL
6
14
  const authClient = createAuthClient({
7
- plugins: [nextCookies()],
15
+ plugins: [
16
+ nextCookies(),
17
+ ...(config.desktopApp.enabled
18
+ ? [
19
+ electronProxyClient({
20
+ callbackPath: ELECTRON_AUTH_CALLBACK_PATH,
21
+ clientID: ELECTRON_AUTH_CLIENT_ID,
22
+ cookiePrefix: ELECTRON_AUTH_COOKIE_PREFIX,
23
+ protocol: {
24
+ scheme: ELECTRON_APP_SCHEME,
25
+ },
26
+ }),
27
+ ]
28
+ : []),
29
+ ],
8
30
  });
9
31
 
10
32
  export default authClient;
@@ -1,3 +1,4 @@
1
+ import { electron } from "@better-auth/electron";
1
2
  import { betterAuth } from "better-auth";
2
3
  import { drizzleAdapter } from "better-auth/adapters/drizzle";
3
4
  import { nextCookies } from "better-auth/next-js";
@@ -5,6 +6,11 @@ import { env } from "@/lib/env";
5
6
  import { config } from "./config";
6
7
  import { db } from "./db/client";
7
8
  import { schema } from "./db/schema";
9
+ import {
10
+ ELECTRON_AUTH_CLIENT_ID,
11
+ ELECTRON_AUTH_COOKIE_PREFIX,
12
+ ELECTRON_TRUSTED_ORIGINS,
13
+ } from "./electron-auth";
8
14
 
9
15
  export const auth = betterAuth({
10
16
  database: drizzleAdapter(db, {
@@ -16,6 +22,7 @@ export const auth = betterAuth({
16
22
  // Vercel URL for preview branches
17
23
  ...(env.VERCEL_URL ? [`https://${env.VERCEL_URL}`] : []),
18
24
  config.appUrl,
25
+ ...(config.desktopApp.enabled ? ELECTRON_TRUSTED_ORIGINS : []),
19
26
  ],
20
27
  secret: env.AUTH_SECRET,
21
28
 
@@ -60,7 +67,17 @@ export const auth = betterAuth({
60
67
 
61
68
  return { google, github, vercel } as const;
62
69
  })(),
63
- plugins: [nextCookies()],
70
+ plugins: [
71
+ nextCookies(),
72
+ ...(config.desktopApp.enabled
73
+ ? [
74
+ electron({
75
+ clientID: ELECTRON_AUTH_CLIENT_ID,
76
+ cookiePrefix: ELECTRON_AUTH_COOKIE_PREFIX,
77
+ }),
78
+ ]
79
+ : []),
80
+ ],
64
81
  });
65
82
 
66
83
  // Infer session type from the auth instance for type safety
@@ -67,7 +67,7 @@ export function extractFilenameFromUrl(url: string): string | null {
67
67
 
68
68
  // Remove the prefix if it exists in the URL
69
69
  if (filename.startsWith(BLOB_FILE_PREFIX)) {
70
- return filename.substring(BLOB_FILE_PREFIX.length);
70
+ return filename.slice(BLOB_FILE_PREFIX.length);
71
71
  }
72
72
 
73
73
  return filename;
@@ -334,7 +334,7 @@ export function cloneMessagesWithDocuments<
334
334
  messageId: string;
335
335
  userId: string;
336
336
  title: string;
337
- kind: any;
337
+ kind: unknown;
338
338
  content: string | null;
339
339
  createdAt: Date;
340
340
  },
@@ -254,6 +254,16 @@ export const authenticationConfigSchema = z
254
254
  vercel: false,
255
255
  });
256
256
 
257
+ export const desktopAppConfigSchema = z
258
+ .object({
259
+ enabled: z
260
+ .boolean()
261
+ .describe("Enable Electron desktop auth/runtime integration"),
262
+ })
263
+ .default({
264
+ enabled: false,
265
+ });
266
+
257
267
  export const configSchema = z.object({
258
268
  appPrefix: z.string().default("chatjs"),
259
269
  appName: z.string().default("My AI Chat"),
@@ -326,6 +336,8 @@ export const configSchema = z.object({
326
336
 
327
337
  authentication: authenticationConfigSchema,
328
338
 
339
+ desktopApp: desktopAppConfigSchema,
340
+
329
341
  ai: aiConfigSchema,
330
342
 
331
343
  anonymous: anonymousConfigSchema,
@@ -341,6 +353,7 @@ export type AnonymousConfig = z.infer<typeof anonymousConfigSchema>;
341
353
  export type AttachmentsConfig = z.infer<typeof attachmentsConfigSchema>;
342
354
  export type FeaturesConfig = z.infer<typeof featuresConfigSchema>;
343
355
  export type AuthenticationConfig = z.infer<typeof authenticationConfigSchema>;
356
+ export type DesktopAppConfig = z.infer<typeof desktopAppConfigSchema>;
344
357
 
345
358
  // Gateway-aware input types: model IDs narrowed per gateway for autocomplete
346
359
  type ZodConfigInput = z.input<typeof configSchema>;
@@ -389,7 +402,6 @@ interface AiToolsInputFor<G extends GatewayType> {
389
402
  }
390
403
 
391
404
  // Only gateway is required; everything else is an override on top of GATEWAY_MODEL_DEFAULTS
392
- // biome-ignore lint/style/useConsistentTypeDefinitions: type is used intentionally here
393
405
  type AiInputFor<G extends GatewayType> = {
394
406
  gateway: G;
395
407
  providerOrder?: AiShape["providerOrder"];
@@ -1,11 +1,10 @@
1
1
  import { config } from "@/lib/config";
2
+ import { isPlaywrightTestEnvironment as getIsPlaywrightTestEnvironment } from "@/lib/playwright-test-environment";
2
3
 
3
4
  const _isProductionEnvironment = process.env.NODE_ENV === "production";
4
5
 
5
- const _isTestEnvironment = Boolean(
6
- process.env.PLAYWRIGHT_TEST_BASE_URL ||
7
- process.env.PLAYWRIGHT ||
8
- process.env.CI_PLAYWRIGHT
6
+ export const isPlaywrightTestEnvironment = getIsPlaywrightTestEnvironment(
7
+ process.env
9
8
  );
10
9
 
11
10
  export const BLOB_FILE_PREFIX = `${config.appPrefix}/files/`;
@@ -94,12 +94,8 @@
94
94
  "name": "account_user_id_user_id_fk",
95
95
  "tableFrom": "account",
96
96
  "tableTo": "user",
97
- "columnsFrom": [
98
- "user_id"
99
- ],
100
- "columnsTo": [
101
- "id"
102
- ],
97
+ "columnsFrom": ["user_id"],
98
+ "columnsTo": ["id"],
103
99
  "onDelete": "cascade",
104
100
  "onUpdate": "no action"
105
101
  }
@@ -173,12 +169,8 @@
173
169
  "name": "Chat_userId_user_id_fk",
174
170
  "tableFrom": "Chat",
175
171
  "tableTo": "user",
176
- "columnsFrom": [
177
- "userId"
178
- ],
179
- "columnsTo": [
180
- "id"
181
- ],
172
+ "columnsFrom": ["userId"],
173
+ "columnsTo": ["id"],
182
174
  "onDelete": "no action",
183
175
  "onUpdate": "no action"
184
176
  },
@@ -186,12 +178,8 @@
186
178
  "name": "Chat_projectId_Project_id_fk",
187
179
  "tableFrom": "Chat",
188
180
  "tableTo": "Project",
189
- "columnsFrom": [
190
- "projectId"
191
- ],
192
- "columnsTo": [
193
- "id"
194
- ],
181
+ "columnsFrom": ["projectId"],
182
+ "columnsTo": ["id"],
195
183
  "onDelete": "set null",
196
184
  "onUpdate": "no action"
197
185
  }
@@ -273,12 +261,8 @@
273
261
  "name": "Document_userId_user_id_fk",
274
262
  "tableFrom": "Document",
275
263
  "tableTo": "user",
276
- "columnsFrom": [
277
- "userId"
278
- ],
279
- "columnsTo": [
280
- "id"
281
- ],
264
+ "columnsFrom": ["userId"],
265
+ "columnsTo": ["id"],
282
266
  "onDelete": "no action",
283
267
  "onUpdate": "no action"
284
268
  },
@@ -286,12 +270,8 @@
286
270
  "name": "Document_messageId_Message_id_fk",
287
271
  "tableFrom": "Document",
288
272
  "tableTo": "Message",
289
- "columnsFrom": [
290
- "messageId"
291
- ],
292
- "columnsTo": [
293
- "id"
294
- ],
273
+ "columnsFrom": ["messageId"],
274
+ "columnsTo": ["id"],
295
275
  "onDelete": "cascade",
296
276
  "onUpdate": "no action"
297
277
  }
@@ -299,10 +279,7 @@
299
279
  "compositePrimaryKeys": {
300
280
  "Document_id_createdAt_pk": {
301
281
  "name": "Document_id_createdAt_pk",
302
- "columns": [
303
- "id",
304
- "createdAt"
305
- ]
282
+ "columns": ["id", "createdAt"]
306
283
  }
307
284
  },
308
285
  "uniqueConstraints": {},
@@ -450,12 +427,8 @@
450
427
  "name": "McpConnector_userId_user_id_fk",
451
428
  "tableFrom": "McpConnector",
452
429
  "tableTo": "user",
453
- "columnsFrom": [
454
- "userId"
455
- ],
456
- "columnsTo": [
457
- "id"
458
- ],
430
+ "columnsFrom": ["userId"],
431
+ "columnsTo": ["id"],
459
432
  "onDelete": "cascade",
460
433
  "onUpdate": "no action"
461
434
  }
@@ -565,12 +538,8 @@
565
538
  "name": "McpOAuthSession_mcpConnectorId_McpConnector_id_fk",
566
539
  "tableFrom": "McpOAuthSession",
567
540
  "tableTo": "McpConnector",
568
- "columnsFrom": [
569
- "mcpConnectorId"
570
- ],
571
- "columnsTo": [
572
- "id"
573
- ],
541
+ "columnsFrom": ["mcpConnectorId"],
542
+ "columnsTo": ["id"],
574
543
  "onDelete": "cascade",
575
544
  "onUpdate": "no action"
576
545
  }
@@ -580,9 +549,7 @@
580
549
  "McpOAuthSession_state_unique": {
581
550
  "name": "McpOAuthSession_state_unique",
582
551
  "nullsNotDistinct": false,
583
- "columns": [
584
- "state"
585
- ]
552
+ "columns": ["state"]
586
553
  }
587
554
  },
588
555
  "policies": {},
@@ -692,12 +659,8 @@
692
659
  "name": "Message_chatId_Chat_id_fk",
693
660
  "tableFrom": "Message",
694
661
  "tableTo": "Chat",
695
- "columnsFrom": [
696
- "chatId"
697
- ],
698
- "columnsTo": [
699
- "id"
700
- ],
662
+ "columnsFrom": ["chatId"],
663
+ "columnsTo": ["id"],
701
664
  "onDelete": "cascade",
702
665
  "onUpdate": "no action"
703
666
  }
@@ -915,12 +878,8 @@
915
878
  "name": "Part_messageId_Message_id_fk",
916
879
  "tableFrom": "Part",
917
880
  "tableTo": "Message",
918
- "columnsFrom": [
919
- "messageId"
920
- ],
921
- "columnsTo": [
922
- "id"
923
- ],
881
+ "columnsFrom": ["messageId"],
882
+ "columnsTo": ["id"],
924
883
  "onDelete": "cascade",
925
884
  "onUpdate": "no action"
926
885
  }
@@ -1041,12 +1000,8 @@
1041
1000
  "name": "Project_userId_user_id_fk",
1042
1001
  "tableFrom": "Project",
1043
1002
  "tableTo": "user",
1044
- "columnsFrom": [
1045
- "userId"
1046
- ],
1047
- "columnsTo": [
1048
- "id"
1049
- ],
1003
+ "columnsFrom": ["userId"],
1004
+ "columnsTo": ["id"],
1050
1005
  "onDelete": "cascade",
1051
1006
  "onUpdate": "no action"
1052
1007
  }
@@ -1117,12 +1072,8 @@
1117
1072
  "name": "session_user_id_user_id_fk",
1118
1073
  "tableFrom": "session",
1119
1074
  "tableTo": "user",
1120
- "columnsFrom": [
1121
- "user_id"
1122
- ],
1123
- "columnsTo": [
1124
- "id"
1125
- ],
1075
+ "columnsFrom": ["user_id"],
1076
+ "columnsTo": ["id"],
1126
1077
  "onDelete": "cascade",
1127
1078
  "onUpdate": "no action"
1128
1079
  }
@@ -1132,9 +1083,7 @@
1132
1083
  "session_token_unique": {
1133
1084
  "name": "session_token_unique",
1134
1085
  "nullsNotDistinct": false,
1135
- "columns": [
1136
- "token"
1137
- ]
1086
+ "columns": ["token"]
1138
1087
  }
1139
1088
  },
1140
1089
  "policies": {},
@@ -1208,12 +1157,8 @@
1208
1157
  "name": "Suggestion_userId_user_id_fk",
1209
1158
  "tableFrom": "Suggestion",
1210
1159
  "tableTo": "user",
1211
- "columnsFrom": [
1212
- "userId"
1213
- ],
1214
- "columnsTo": [
1215
- "id"
1216
- ],
1160
+ "columnsFrom": ["userId"],
1161
+ "columnsTo": ["id"],
1217
1162
  "onDelete": "no action",
1218
1163
  "onUpdate": "no action"
1219
1164
  },
@@ -1221,14 +1166,8 @@
1221
1166
  "name": "Suggestion_documentId_documentCreatedAt_Document_id_createdAt_fk",
1222
1167
  "tableFrom": "Suggestion",
1223
1168
  "tableTo": "Document",
1224
- "columnsFrom": [
1225
- "documentId",
1226
- "documentCreatedAt"
1227
- ],
1228
- "columnsTo": [
1229
- "id",
1230
- "createdAt"
1231
- ],
1169
+ "columnsFrom": ["documentId", "documentCreatedAt"],
1170
+ "columnsTo": ["id", "createdAt"],
1232
1171
  "onDelete": "no action",
1233
1172
  "onUpdate": "no action"
1234
1173
  }
@@ -1236,9 +1175,7 @@
1236
1175
  "compositePrimaryKeys": {
1237
1176
  "Suggestion_id_pk": {
1238
1177
  "name": "Suggestion_id_pk",
1239
- "columns": [
1240
- "id"
1241
- ]
1178
+ "columns": ["id"]
1242
1179
  }
1243
1180
  },
1244
1181
  "uniqueConstraints": {},
@@ -1303,9 +1240,7 @@
1303
1240
  "user_email_unique": {
1304
1241
  "name": "user_email_unique",
1305
1242
  "nullsNotDistinct": false,
1306
- "columns": [
1307
- "email"
1308
- ]
1243
+ "columns": ["email"]
1309
1244
  }
1310
1245
  },
1311
1246
  "policies": {},
@@ -1336,12 +1271,8 @@
1336
1271
  "name": "UserCredit_userId_user_id_fk",
1337
1272
  "tableFrom": "UserCredit",
1338
1273
  "tableTo": "user",
1339
- "columnsFrom": [
1340
- "userId"
1341
- ],
1342
- "columnsTo": [
1343
- "id"
1344
- ],
1274
+ "columnsFrom": ["userId"],
1275
+ "columnsTo": ["id"],
1345
1276
  "onDelete": "cascade",
1346
1277
  "onUpdate": "no action"
1347
1278
  }
@@ -1411,12 +1342,8 @@
1411
1342
  "name": "UserModelPreference_userId_user_id_fk",
1412
1343
  "tableFrom": "UserModelPreference",
1413
1344
  "tableTo": "user",
1414
- "columnsFrom": [
1415
- "userId"
1416
- ],
1417
- "columnsTo": [
1418
- "id"
1419
- ],
1345
+ "columnsFrom": ["userId"],
1346
+ "columnsTo": ["id"],
1420
1347
  "onDelete": "cascade",
1421
1348
  "onUpdate": "no action"
1422
1349
  }
@@ -1424,10 +1351,7 @@
1424
1351
  "compositePrimaryKeys": {
1425
1352
  "UserModelPreference_userId_modelId_pk": {
1426
1353
  "name": "UserModelPreference_userId_modelId_pk",
1427
- "columns": [
1428
- "userId",
1429
- "modelId"
1430
- ]
1354
+ "columns": ["userId", "modelId"]
1431
1355
  }
1432
1356
  },
1433
1357
  "uniqueConstraints": {},
@@ -1515,12 +1439,8 @@
1515
1439
  "name": "Vote_chatId_Chat_id_fk",
1516
1440
  "tableFrom": "Vote",
1517
1441
  "tableTo": "Chat",
1518
- "columnsFrom": [
1519
- "chatId"
1520
- ],
1521
- "columnsTo": [
1522
- "id"
1523
- ],
1442
+ "columnsFrom": ["chatId"],
1443
+ "columnsTo": ["id"],
1524
1444
  "onDelete": "cascade",
1525
1445
  "onUpdate": "no action"
1526
1446
  },
@@ -1528,12 +1448,8 @@
1528
1448
  "name": "Vote_messageId_Message_id_fk",
1529
1449
  "tableFrom": "Vote",
1530
1450
  "tableTo": "Message",
1531
- "columnsFrom": [
1532
- "messageId"
1533
- ],
1534
- "columnsTo": [
1535
- "id"
1536
- ],
1451
+ "columnsFrom": ["messageId"],
1452
+ "columnsTo": ["id"],
1537
1453
  "onDelete": "cascade",
1538
1454
  "onUpdate": "no action"
1539
1455
  }
@@ -1541,10 +1457,7 @@
1541
1457
  "compositePrimaryKeys": {
1542
1458
  "Vote_chatId_messageId_pk": {
1543
1459
  "name": "Vote_chatId_messageId_pk",
1544
- "columns": [
1545
- "chatId",
1546
- "messageId"
1547
- ]
1460
+ "columns": ["chatId", "messageId"]
1548
1461
  }
1549
1462
  },
1550
1463
  "uniqueConstraints": {},
@@ -1564,4 +1477,4 @@
1564
1477
  "schemas": {},
1565
1478
  "tables": {}
1566
1479
  }
1567
- }
1480
+ }
@@ -318,4 +318,4 @@
318
318
  "breakpoints": true
319
319
  }
320
320
  ]
321
- }
321
+ }
@@ -8,8 +8,8 @@ import {
8
8
  type HeadingTagType,
9
9
  QuoteNode,
10
10
  } from "@lexical/rich-text";
11
- import type { LexicalEditor } from "lexical";
12
- import { $getSelection, $insertNodes } from "lexical";
11
+ import type { EditorState, LexicalEditor } from "lexical";
12
+ import { $getSelection, $insertNodes, type TextNode } from "lexical";
13
13
 
14
14
  // Create initial editor configuration
15
15
  export function createEditorConfig() {
@@ -37,7 +37,7 @@ function _createHeadingTransform(level: number) {
37
37
  export: null,
38
38
  importDOM: null,
39
39
  regExp: new RegExp(`^(#{1,${level}})\\s$`),
40
- replace: (_textNode: any) => {
40
+ replace: (_textNode: TextNode) => {
41
41
  const selection = $getSelection();
42
42
  if (selection) {
43
43
  const headingTag = `h${level}` as HeadingTagType;
@@ -56,7 +56,7 @@ export const handleEditorChange = ({
56
56
  editor,
57
57
  onSaveContent,
58
58
  }: {
59
- editorState: any;
59
+ editorState: EditorState;
60
60
  editor: LexicalEditor;
61
61
  onSaveContent: (updatedContent: string, debounce: boolean) => void;
62
62
  }) => {