aboutsummaryrefslogtreecommitdiff
path: root/apps/web
diff options
context:
space:
mode:
authorDhravya Shah <[email protected]>2024-08-27 11:54:00 -0700
committerDhravya Shah <[email protected]>2024-08-27 11:54:00 -0700
commitba3a7b6a80a57a58446752bb3c14586322dfa22e (patch)
treeeb418fe49604c985737a4896d5d34b7c97b33219 /apps/web
parentfix: editor build issue (diff)
downloadsupermemory-ba3a7b6a80a57a58446752bb3c14586322dfa22e.tar.xz
supermemory-ba3a7b6a80a57a58446752bb3c14586322dfa22e.zip
fix: all build errors
Diffstat (limited to 'apps/web')
-rw-r--r--apps/web/.npmrc3
-rw-r--r--apps/web/components/editor/advanced-editor.tsx4
-rw-r--r--apps/web/components/editor/emoji/emojiList.tsx22
-rw-r--r--apps/web/components/editor/emoji/suggestion.ts39
-rw-r--r--apps/web/components/editor/extensions.ts1
-rw-r--r--apps/web/components/editor/generative/ai-completion-command.tsx11
-rw-r--r--apps/web/components/editor/generative/ai-selector-commands.tsx7
-rw-r--r--apps/web/components/editor/generative/ai-selector.tsx10
-rw-r--r--apps/web/components/editor/generative/generative-menu-switch.tsx3
-rw-r--r--apps/web/components/editor/selectors/align-selector.tsx12
-rw-r--r--apps/web/components/editor/selectors/link-selector.tsx1
-rw-r--r--apps/web/components/editor/selectors/node-selector.tsx14
-rw-r--r--apps/web/components/editor/slash-command.tsx4
-rw-r--r--apps/web/package.json5
-rw-r--r--apps/web/server/auth.ts9
15 files changed, 94 insertions, 51 deletions
diff --git a/apps/web/.npmrc b/apps/web/.npmrc
index e69de29b..6bd2d21e 100644
--- a/apps/web/.npmrc
+++ b/apps/web/.npmrc
@@ -0,0 +1,3 @@
+registry=https://registry.npmjs.org/
+@tiptap-pro:registry=https://registry.tiptap.dev/
+//registry.tiptap.dev/:_authToken=RUrFuwyOUC+su14NeR40c/tH08IhV83hWCOO+IjAgBBDUg943oteBAREqXQyNzAl \ No newline at end of file
diff --git a/apps/web/components/editor/advanced-editor.tsx b/apps/web/components/editor/advanced-editor.tsx
index 5da44245..b5e74b5d 100644
--- a/apps/web/components/editor/advanced-editor.tsx
+++ b/apps/web/components/editor/advanced-editor.tsx
@@ -54,7 +54,7 @@ const TailwindAdvancedEditor = memo(
slashCommand,
TableOfContents.configure({
getIndex: getHierarchicalIndexes,
- onUpdate(content) {
+ onUpdate(content: tContent[]) {
console.log(content);
setItems(content);
},
@@ -96,7 +96,7 @@ const TailwindAdvancedEditor = memo(
{suggestionItems.map((item) => (
<EditorCommandItem
value={item.title}
- onCommand={(val) => item.command(val)}
+ onCommand={(val) => item?.command?.(val)}
className="flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:bg-[#21303D] group aria-selected:bg-[#21303D]"
key={item.title}
>
diff --git a/apps/web/components/editor/emoji/emojiList.tsx b/apps/web/components/editor/emoji/emojiList.tsx
index c5f734c9..42cef01a 100644
--- a/apps/web/components/editor/emoji/emojiList.tsx
+++ b/apps/web/components/editor/emoji/emojiList.tsx
@@ -5,10 +5,24 @@ import React, {
useState,
} from "react";
-export const EmojiList = forwardRef((props, ref) => {
+interface EmojiItem {
+ name: string;
+ emoji: string;
+ fallbackImage?: string;
+}
+
+interface EmojiListProps {
+ items: EmojiItem[];
+ command: (item: { name: string }) => void;
+}
+
+export const EmojiList = forwardRef<
+ { onKeyDown: (x: { event: KeyboardEvent }) => boolean },
+ EmojiListProps
+>((props, ref) => {
const [selectedIndex, setSelectedIndex] = useState(0);
- const selectItem = (index) => {
+ const selectItem = (index: number) => {
const item = props.items[index];
if (item) {
props.command({ name: item.name });
@@ -34,7 +48,7 @@ export const EmojiList = forwardRef((props, ref) => {
useImperativeHandle(
ref,
() => ({
- onKeyDown: (x) => {
+ onKeyDown: (x: { event: KeyboardEvent }) => {
if (x.event.key === "ArrowUp") {
upHandler();
return true;
@@ -58,7 +72,7 @@ export const EmojiList = forwardRef((props, ref) => {
{props.items.map((item, index) => (
<button
className={`flex items-center gap-1 w-full text-left ${
- index === selectedIndex && "bg-[#21303D] text-[#369DFD]"
+ index === selectedIndex ? "bg-[#21303D] text-[#369DFD]" : ""
}`}
key={index}
onClick={() => selectItem(index)}
diff --git a/apps/web/components/editor/emoji/suggestion.ts b/apps/web/components/editor/emoji/suggestion.ts
index 91c1cc51..c2c44b45 100644
--- a/apps/web/components/editor/emoji/suggestion.ts
+++ b/apps/web/components/editor/emoji/suggestion.ts
@@ -1,16 +1,28 @@
import { ReactRenderer } from "@tiptap/react";
-import tippy from "tippy.js";
+import tippy, { Instance as TippyInstance } from "tippy.js";
import { EmojiList } from "./emojiList";
+import { Editor } from "@tiptap/core";
+
+interface EmojiItem {
+ shortcodes: string[];
+ tags: string[];
+}
+
+interface SuggestionProps {
+ editor: Editor;
+ clientRect: () => DOMRect;
+ event: KeyboardEvent;
+}
export default {
- items: ({ editor, query }) => {
- return editor.storage.emoji.emojis
+ items: ({ editor, query }: { editor: Editor; query: string }) => {
+ return (editor.storage.emoji.emojis as EmojiItem[])
.filter(({ shortcodes, tags }) => {
return (
- shortcodes.find((shortcode) =>
+ shortcodes.find((shortcode: string) =>
shortcode.startsWith(query.toLowerCase()),
- ) || tags.find((tag) => tag.startsWith(query.toLowerCase()))
+ ) || tags.find((tag: string) => tag.startsWith(query.toLowerCase()))
);
})
.slice(0, 5);
@@ -19,11 +31,11 @@ export default {
allowSpaces: false,
render: () => {
- let component;
- let popup;
+ let component: ReactRenderer;
+ let popup: TippyInstance[];
return {
- onStart: (props) => {
+ onStart: (props: SuggestionProps) => {
component = new ReactRenderer(EmojiList, {
props,
editor: props.editor,
@@ -40,27 +52,28 @@ export default {
});
},
- onUpdate(props) {
+ onUpdate(props: SuggestionProps) {
component.updateProps(props);
- popup[0].setProps({
+ popup[0]?.setProps({
getReferenceClientRect: props.clientRect,
});
},
- onKeyDown(props) {
+ onKeyDown(props: SuggestionProps) {
if (props.event.key === "Escape") {
- popup[0].hide();
+ popup[0]?.hide();
component.destroy();
return true;
}
+ // @ts-ignore
return component.ref?.onKeyDown(props);
},
onExit() {
- popup[0].destroy();
+ popup[0]?.destroy();
component.destroy();
},
};
diff --git a/apps/web/components/editor/extensions.ts b/apps/web/components/editor/extensions.ts
index bc226a2d..1b1bf8ed 100644
--- a/apps/web/components/editor/extensions.ts
+++ b/apps/web/components/editor/extensions.ts
@@ -141,6 +141,7 @@ const textAlign = TextAlign.configure({
const emojis = Emoji.configure({
emojis: gitHubEmojis,
enableEmoticons: true,
+ // @ts-ignore
suggestion,
});
diff --git a/apps/web/components/editor/generative/ai-completion-command.tsx b/apps/web/components/editor/generative/ai-completion-command.tsx
index f235fffa..7fb64a0b 100644
--- a/apps/web/components/editor/generative/ai-completion-command.tsx
+++ b/apps/web/components/editor/generative/ai-completion-command.tsx
@@ -17,10 +17,12 @@ const AICompletionCommands = ({
className="gap-2 px-4"
value="replace"
onSelect={() => {
- const selection = editor.view.state.selection;
+ const selection = editor?.view.state.selection;
+
+ if (!selection) return;
editor
- .chain()
+ ?.chain()
.focus()
.insertContentAt(
{
@@ -39,9 +41,10 @@ const AICompletionCommands = ({
className="gap-2 px-4"
value="insert"
onSelect={() => {
- const selection = editor.view.state.selection;
+ const selection = editor?.view.state.selection;
+ if (!selection) return;
editor
- .chain()
+ ?.chain()
.focus()
.insertContentAt(selection.to + 1, completion)
.run();
diff --git a/apps/web/components/editor/generative/ai-selector-commands.tsx b/apps/web/components/editor/generative/ai-selector-commands.tsx
index eef135f2..ee7386c0 100644
--- a/apps/web/components/editor/generative/ai-selector-commands.tsx
+++ b/apps/web/components/editor/generative/ai-selector-commands.tsx
@@ -46,9 +46,9 @@ const AISelectorCommands = ({ onSelect }: AISelectorCommandsProps) => {
{options.map((option) => (
<CommandItem
onSelect={(value) => {
- const slice = editor.state.selection.content();
- const text = editor.storage.markdown.serializer.serialize(
- slice.content,
+ const slice = editor?.state.selection.content();
+ const text = editor?.storage.markdown.serializer.serialize(
+ slice?.content,
);
onSelect(text, value);
}}
@@ -65,6 +65,7 @@ const AISelectorCommands = ({ onSelect }: AISelectorCommandsProps) => {
<CommandGroup heading="Use AI to do more">
<CommandItem
onSelect={() => {
+ if (!editor) return;
const pos = editor.state.selection.from;
const text = getPrevText(editor, pos);
diff --git a/apps/web/components/editor/generative/ai-selector.tsx b/apps/web/components/editor/generative/ai-selector.tsx
index 48eb224e..62d381a1 100644
--- a/apps/web/components/editor/generative/ai-selector.tsx
+++ b/apps/web/components/editor/generative/ai-selector.tsx
@@ -75,7 +75,7 @@ export function AISelector({ onOpenChange }: AISelectorProps) {
? "Tell AI what to do next"
: "Ask AI to edit or generate..."
}
- onFocus={() => addAIHighlight(editor)}
+ onFocus={() => addAIHighlight(editor!)}
/>
<Button
size="icon"
@@ -86,9 +86,9 @@ export function AISelector({ onOpenChange }: AISelectorProps) {
body: { option: "zap", command: inputValue },
}).then(() => setInputValue(""));
- const slice = editor.state.selection.content();
- const text = editor.storage.markdown.serializer.serialize(
- slice.content,
+ const slice = editor?.state.selection.content();
+ const text = editor?.storage.markdown.serializer.serialize(
+ slice?.content,
);
complete(text, {
@@ -102,7 +102,7 @@ export function AISelector({ onOpenChange }: AISelectorProps) {
{hasCompletion ? (
<AICompletionCommands
onDiscard={() => {
- editor.chain().unsetHighlight().focus().run();
+ editor?.chain().unsetHighlight().focus().run();
onOpenChange(false);
}}
completion={completion}
diff --git a/apps/web/components/editor/generative/generative-menu-switch.tsx b/apps/web/components/editor/generative/generative-menu-switch.tsx
index 61d8d9df..9c581475 100644
--- a/apps/web/components/editor/generative/generative-menu-switch.tsx
+++ b/apps/web/components/editor/generative/generative-menu-switch.tsx
@@ -19,6 +19,7 @@ const GenerativeMenuSwitch = ({
const { editor } = useEditor();
useEffect(() => {
+ if (!editor) return;
if (!open) removeAIHighlight(editor);
}, [open]);
return (
@@ -27,7 +28,7 @@ const GenerativeMenuSwitch = ({
placement: open ? "bottom-start" : "top",
onHidden: () => {
onOpenChange(false);
- editor.chain().unsetHighlight().run();
+ editor?.chain().unsetHighlight().run();
},
}}
className="flex w-fit max-w-[90vw] overflow-hidden rounded-md bg-[#1F2428] shadow-xl"
diff --git a/apps/web/components/editor/selectors/align-selector.tsx b/apps/web/components/editor/selectors/align-selector.tsx
index 3002fbd2..99c9a1ba 100644
--- a/apps/web/components/editor/selectors/align-selector.tsx
+++ b/apps/web/components/editor/selectors/align-selector.tsx
@@ -1,4 +1,4 @@
-import { Check, ChevronDown, LucideIcon } from "lucide-react";
+import { Check, ChevronDown } from "lucide-react";
import { EditorBubbleItem, useEditor } from "novel";
import { Button } from "../ui/button";
@@ -7,8 +7,12 @@ import { Popover } from "@radix-ui/react-popover";
export type SelectorItem = {
name: string;
- command: (editor: ReturnType<typeof useEditor>["editor"]) => void;
- isActive: (editor: ReturnType<typeof useEditor>["editor"]) => boolean;
+ command: (
+ editor: NonNullable<ReturnType<typeof useEditor>["editor"]>,
+ ) => void;
+ isActive: (
+ editor: NonNullable<ReturnType<typeof useEditor>["editor"]>,
+ ) => boolean;
};
const items: SelectorItem[] = [
@@ -67,7 +71,7 @@ export const AlignSelector = ({ open, onOpenChange }: AlignSelectorProps) => {
{items.map((item) => (
<EditorBubbleItem
key={item.name}
- onSelect={(editor) => {
+ onSelect={() => {
item.command(editor);
onOpenChange(false);
}}
diff --git a/apps/web/components/editor/selectors/link-selector.tsx b/apps/web/components/editor/selectors/link-selector.tsx
index 7a573dc4..046b4756 100644
--- a/apps/web/components/editor/selectors/link-selector.tsx
+++ b/apps/web/components/editor/selectors/link-selector.tsx
@@ -102,6 +102,7 @@ export const LinkSelector = ({ open, onOpenChange }: LinkSelectorProps) => {
className="flex h-8 border-0 items-center rounded-sm p-1 text-red-600 hover:text-red-600 hover:bg-red-950"
onClick={() => {
editor.chain().focus().unsetLink().run();
+ if (!inputRef.current) return;
inputRef.current.value = "";
onOpenChange(false);
}}
diff --git a/apps/web/components/editor/selectors/node-selector.tsx b/apps/web/components/editor/selectors/node-selector.tsx
index 46c6eb01..dcd7ca76 100644
--- a/apps/web/components/editor/selectors/node-selector.tsx
+++ b/apps/web/components/editor/selectors/node-selector.tsx
@@ -20,8 +20,12 @@ import { Popover } from "@radix-ui/react-popover";
export type SelectorItem = {
name: string;
icon: LucideIcon;
- command: (editor: ReturnType<typeof useEditor>["editor"]) => void;
- isActive: (editor: ReturnType<typeof useEditor>["editor"]) => boolean;
+ command: (
+ editor: NonNullable<ReturnType<typeof useEditor>["editor"]>,
+ ) => void;
+ isActive: (
+ editor: NonNullable<ReturnType<typeof useEditor>["editor"]>,
+ ) => boolean;
};
const items: SelectorItem[] = [
@@ -126,8 +130,10 @@ export const NodeSelector = ({ open, onOpenChange }: NodeSelectorProps) => {
<EditorBubbleItem
key={item.name}
onSelect={(editor) => {
- item.command(editor);
- onOpenChange(false);
+ if (editor) {
+ item.command(editor);
+ onOpenChange(false);
+ }
}}
className="flex border-0 group cursor-pointer items-center justify-between rounded-sm px-2 py-1 text-sm hover:bg-[#21303D]"
>
diff --git a/apps/web/components/editor/slash-command.tsx b/apps/web/components/editor/slash-command.tsx
index 8ec32475..b3eb0d73 100644
--- a/apps/web/components/editor/slash-command.tsx
+++ b/apps/web/components/editor/slash-command.tsx
@@ -156,7 +156,7 @@ export const suggestionItems = createSuggestionItems([
/^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|v\/)?)([\w\-]+)(\S+)?$/,
);
- if (ytregex.test(videoLink)) {
+ if (videoLink && ytregex.test(videoLink)) {
editor
.chain()
.focus()
@@ -183,7 +183,7 @@ export const suggestionItems = createSuggestionItems([
/^https?:\/\/(www\.)?x\.com\/([a-zA-Z0-9_]{1,15})(\/status\/(\d+))?(\/\S*)?$/,
);
- if (tweetRegex.test(tweetLink)) {
+ if (tweetLink && tweetRegex.test(tweetLink)) {
editor
.chain()
.focus()
diff --git a/apps/web/package.json b/apps/web/package.json
index 71445ce5..f01b2d5f 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -22,11 +22,12 @@
"@radix-ui/react-slot": "^1.1.0",
"@sentry/nextjs": "^8.26.0",
"@tiptap-pro/extension-emoji": "^2.10.11",
- "@tiptap-pro/extension-table-of-contents": "^2.10.11",
+ "@tiptap-pro/extension-table-of-contents": "^2.11.1",
+ "@tiptap/core": "^2.6.6",
"@tiptap/extension-text-align": "^2.6.4",
"@tiptap/extension-typography": "^2.6.4",
"@tiptap/pm": "^2.6.4",
- "@tiptap/react": "^2.6.4",
+ "@tiptap/react": "^2.6.6",
"ai": "^3.3.7",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
diff --git a/apps/web/server/auth.ts b/apps/web/server/auth.ts
index 645989fa..690213fe 100644
--- a/apps/web/server/auth.ts
+++ b/apps/web/server/auth.ts
@@ -1,4 +1,4 @@
-import NextAuth, { NextAuthResult } from "next-auth";
+import NextAuth from "next-auth";
import Google from "next-auth/providers/google";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import { db } from "./db";
@@ -12,12 +12,7 @@ export const {
} = NextAuth({
secret: process.env.BACKEND_SECURITY_KEY,
trustHost: true,
- adapter: DrizzleAdapter(db, {
- usersTable: users,
- accountsTable: accounts,
- sessionsTable: sessions,
- verificationTokensTable: verificationTokens,
- }),
+ adapter: DrizzleAdapter(db),
providers: [
Google({
clientId: process.env.GOOGLE_CLIENT_ID,