mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-08-28 05:25:33 +00:00
fix: all build errors
This commit is contained in:
parent
75a6e137b1
commit
ba3a7b6a80
16 changed files with 255 additions and 60 deletions
|
|
@ -0,0 +1,3 @@
|
|||
registry=https://registry.npmjs.org/
|
||||
@tiptap-pro:registry=https://registry.tiptap.dev/
|
||||
//registry.tiptap.dev/:_authToken=RUrFuwyOUC+su14NeR40c/tH08IhV83hWCOO+IjAgBBDUg943oteBAREqXQyNzAl
|
||||
|
|
@ -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}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ const textAlign = TextAlign.configure({
|
|||
const emojis = Emoji.configure({
|
||||
emojis: gitHubEmojis,
|
||||
enableEmoticons: true,
|
||||
// @ts-ignore
|
||||
suggestion,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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]"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
170
pnpm-lock.yaml
generated
170
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue