mirror of
https://github.com/karakeep-app/karakeep.git
synced 2025-12-12 20:35:52 +01:00
[chore] Linting and formating tweaking
This commit is contained in:
18
.eslintrc.js
18
.eslintrc.js
@@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
@@ -9,20 +10,23 @@ module.exports = {
|
||||
"plugin:react/recommended",
|
||||
"plugin:react-hooks/recommended",
|
||||
"plugin:@next/next/recommended",
|
||||
"plugin:tailwindcss/recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"next",
|
||||
"prettier",
|
||||
],
|
||||
plugins: ["tailwindcss", "@typescript-eslint"],
|
||||
parserOptions: {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
},
|
||||
ignorePatterns: ["postcss.config.js"],
|
||||
rules: {
|
||||
"no-redeclare": "off",
|
||||
"@next/next/no-html-link-for-pages": "off",
|
||||
"no-undef": "off",
|
||||
"react/jsx-no-undef": "off",
|
||||
"no-unused-vars": [
|
||||
"tailwindcss/no-custom-classname": "off",
|
||||
"tailwindcss/migration-from-tailwind-2": "off",
|
||||
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
varsIgnorePattern: "^_",
|
||||
@@ -30,4 +34,10 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["*.ts", "*.tsx"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
{}
|
||||
{
|
||||
"plugins": ["prettier-plugin-tailwindcss"]
|
||||
}
|
||||
|
||||
5
Makefile
5
Makefile
@@ -1,7 +1,10 @@
|
||||
MAKEFLAGS += --always-make
|
||||
|
||||
format:
|
||||
yarn prettier . --write && yarn exec 'eslint .'
|
||||
yarn prettier . --write
|
||||
|
||||
lint:
|
||||
yarn eslint .
|
||||
|
||||
prisma:
|
||||
cd packages/db; \
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
"es-errors": "^1.3.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-next": "14.1.0",
|
||||
"eslint-plugin-tailwindcss": "^3.14.2",
|
||||
"install": "^0.13.0",
|
||||
"prettier": "3.2.5",
|
||||
"prettier-plugin-tailwindcss": "^0.5.11",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"packageManager": "yarn@4.1.0"
|
||||
|
||||
@@ -29,7 +29,7 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
const bookmark = await bookmarkLink(linkRequest.data.url, session.user.id);
|
||||
|
||||
let response: ZBookmark = { ...bookmark };
|
||||
const response: ZBookmark = { ...bookmark };
|
||||
return NextResponse.json(response, { status: 201 });
|
||||
}
|
||||
|
||||
@@ -42,6 +42,6 @@ export async function GET() {
|
||||
|
||||
const bookmarks = await getBookmarks(session.user.id);
|
||||
|
||||
let response: ZGetBookmarksResponse = { bookmarks };
|
||||
const response: ZGetBookmarksResponse = { bookmarks };
|
||||
return NextResponse.json(response);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function AddLink() {
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit, onError)}>
|
||||
<div className="py-4 container flex w-full items-center space-x-2">
|
||||
<div className="container flex w-full items-center space-x-2 py-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="url"
|
||||
|
||||
@@ -20,7 +20,7 @@ export default async function BookmarksGrid() {
|
||||
const bookmarks = await getBookmarks(session.user.id);
|
||||
|
||||
return (
|
||||
<div className="container grid gap-4 grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
|
||||
<div className="container grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
|
||||
{bookmarks.map((b) => renderBookmark(b))}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -26,7 +26,7 @@ export function LinkOptions({ linkId }: { linkId: string }) {
|
||||
const router = useRouter();
|
||||
|
||||
const unbookmarkLink = async () => {
|
||||
let [_, error] = await APIClient.deleteBookmark(linkId);
|
||||
const [_, error] = await APIClient.deleteBookmark(linkId);
|
||||
|
||||
if (error) {
|
||||
toast({
|
||||
@@ -51,7 +51,7 @@ export function LinkOptions({ linkId }: { linkId: string }) {
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-fit">
|
||||
<DropdownMenuItem className="text-destructive" onClick={unbookmarkLink}>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
<Trash2 className="mr-2 size-4" />
|
||||
<span>Delete</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
@@ -66,7 +66,7 @@ export default function LinkCard({ bookmark }: { bookmark: ZBookmark }) {
|
||||
return (
|
||||
<ImageCard
|
||||
className={
|
||||
"bg-gray-50 duration-300 ease-in border border-grey-100 hover:transition-all hover:border-blue-300"
|
||||
"border-grey-100 border bg-gray-50 duration-300 ease-in hover:border-blue-300 hover:transition-all"
|
||||
}
|
||||
image={link?.imageUrl ?? undefined}
|
||||
>
|
||||
@@ -75,7 +75,7 @@ export default function LinkCard({ bookmark }: { bookmark: ZBookmark }) {
|
||||
{link?.title ?? parsedUrl.host}
|
||||
</Link>
|
||||
</ImageCardTitle>
|
||||
<ImageCardBody className="py-2 overflow-clip">
|
||||
<ImageCardBody className="overflow-clip py-2">
|
||||
{bookmark.tags.map((t) => (
|
||||
<Badge
|
||||
variant="default"
|
||||
|
||||
@@ -31,14 +31,14 @@ export default async function Sidebar() {
|
||||
}
|
||||
|
||||
return (
|
||||
<aside className="flex flex-col h-full w-60 border-r p-4">
|
||||
<div className="flex px-1 mb-5 items-center rounded-lg text-slate-900">
|
||||
<aside className="flex h-full w-60 flex-col border-r p-4">
|
||||
<div className="mb-5 flex items-center rounded-lg px-1 text-slate-900">
|
||||
<Brain />
|
||||
<span className="ml-2 text-base font-semibold">Remember</span>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
<ul className="space-y-2 mt-5 text-sm font-medium">
|
||||
<ul className="mt-5 space-y-2 text-sm font-medium">
|
||||
<SidebarItem logo={<Home />} name="Home" path="#" />
|
||||
<SidebarItem logo={<Star />} name="Favourites" path="#" />
|
||||
<SidebarItem logo={<Archive />} name="Archived" path="#" />
|
||||
@@ -47,7 +47,7 @@ export default async function Sidebar() {
|
||||
</div>
|
||||
<div className="mt-auto flex justify-between">
|
||||
<div className="my-auto"> {session.user.name} </div>
|
||||
<Button variant="ghost" className="h-10 w-30">
|
||||
<Button variant="ghost" className="h-10">
|
||||
<MoreHorizontal />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import Sidebar from "@/app/dashboard/components/Sidebar";
|
||||
|
||||
export default async function Dashboard() {
|
||||
return (
|
||||
<div className="flex w-screen h-screen">
|
||||
<div className="flex h-screen w-screen">
|
||||
<div className="flex-none">
|
||||
<Sidebar />
|
||||
</div>
|
||||
|
||||
@@ -4,16 +4,16 @@ import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const badgeVariants = cva(
|
||||
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
"focus:ring-ring inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
||||
"bg-primary text-primary-foreground hover:bg-primary/80 border-transparent",
|
||||
secondary:
|
||||
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
"bg-secondary text-secondary-foreground hover:bg-secondary/80 border-transparent",
|
||||
destructive:
|
||||
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
||||
"bg-destructive text-destructive-foreground hover:bg-destructive/80 border-transparent",
|
||||
outline: "text-foreground",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
||||
"ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
@@ -13,7 +13,7 @@ const buttonVariants = cva(
|
||||
destructive:
|
||||
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
||||
outline:
|
||||
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
||||
"border-input bg-background hover:bg-accent hover:text-accent-foreground border",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
@@ -23,7 +23,7 @@ const buttonVariants = cva(
|
||||
default: "h-10 px-4 py-2",
|
||||
sm: "h-9 rounded-md px-3",
|
||||
lg: "h-11 rounded-md px-8",
|
||||
icon: "h-10 w-10",
|
||||
icon: "size-10",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
||||
@@ -9,7 +9,7 @@ const Card = React.forwardRef<
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
||||
"bg-card text-card-foreground rounded-lg border shadow-sm",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -50,7 +50,7 @@ const CardDescription = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<p
|
||||
ref={ref}
|
||||
className={cn("text-sm text-muted-foreground", className)}
|
||||
className={cn("text-muted-foreground text-sm", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -27,14 +27,14 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
|
||||
"focus:bg-accent data-[state=open]:bg-accent flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronRight className="ml-auto h-4 w-4" />
|
||||
<ChevronRight className="ml-auto size-4" />
|
||||
</DropdownMenuPrimitive.SubTrigger>
|
||||
));
|
||||
DropdownMenuSubTrigger.displayName =
|
||||
@@ -47,7 +47,7 @@ const DropdownMenuSubContent = React.forwardRef<
|
||||
<DropdownMenuPrimitive.SubContent
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -65,7 +65,7 @@ const DropdownMenuContent = React.forwardRef<
|
||||
ref={ref}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-md",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -83,7 +83,7 @@ const DropdownMenuItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
@@ -99,15 +99,15 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
{...props}
|
||||
>
|
||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<span className="absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<Check className="h-4 w-4" />
|
||||
<Check className="size-4" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
@@ -123,14 +123,14 @@ const DropdownMenuRadioItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<span className="absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<Circle className="h-2 w-2 fill-current" />
|
||||
<Circle className="size-2 fill-current" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
@@ -162,7 +162,7 @@ const DropdownMenuSeparator = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Separator
|
||||
ref={ref}
|
||||
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
||||
className={cn("bg-muted -mx-1 my-1 h-px", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -134,7 +134,7 @@ const FormDescription = React.forwardRef<
|
||||
<p
|
||||
ref={ref}
|
||||
id={formDescriptionId}
|
||||
className={cn("text-sm text-muted-foreground", className)}
|
||||
className={cn("text-muted-foreground text-sm", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -156,7 +156,7 @@ const FormMessage = React.forwardRef<
|
||||
<p
|
||||
ref={ref}
|
||||
id={formMessageId}
|
||||
className={cn("text-sm font-medium text-destructive", className)}
|
||||
className={cn("text-destructive text-sm font-medium", className)}
|
||||
{...props}
|
||||
>
|
||||
{body}
|
||||
|
||||
@@ -10,7 +10,7 @@ export function ImageCard({
|
||||
}: React.HTMLAttributes<HTMLDivElement> & { image?: string }) {
|
||||
return (
|
||||
<div
|
||||
className={cn("h-96 rounded-lg overflow-hidden shadow-md", className)}
|
||||
className={cn("h-96 overflow-hidden rounded-lg shadow-md", className)}
|
||||
{...props}
|
||||
>
|
||||
<div
|
||||
@@ -19,7 +19,7 @@ export function ImageCard({
|
||||
backgroundImage: image ? `url(${image})` : undefined,
|
||||
}}
|
||||
></div>
|
||||
<div className="flex flex-col h-2/5 p-2">{children}</div>
|
||||
<div className="flex h-2/5 flex-col p-2">{children}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -30,7 +30,7 @@ export function ImageCardTitle({
|
||||
}: React.HTMLAttributes<HTMLDivElement>) {
|
||||
return (
|
||||
<div
|
||||
className={cn("order-first flex-none font-bold text-lg", className)}
|
||||
className={cn("order-first flex-none text-lg font-bold", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -42,7 +42,7 @@ export function ImageCardBody({
|
||||
}: React.HTMLAttributes<HTMLDivElement>) {
|
||||
return (
|
||||
<div
|
||||
className={cn("grow order-1 font-bold text-lg", className)}
|
||||
className={cn("order-1 grow text-lg font-bold", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
|
||||
@@ -23,13 +23,13 @@ const ToastViewport = React.forwardRef<
|
||||
ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
|
||||
|
||||
const toastVariants = cva(
|
||||
"group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "border bg-background text-foreground",
|
||||
default: "bg-background text-foreground border",
|
||||
destructive:
|
||||
"destructive group border-destructive bg-destructive text-destructive-foreground",
|
||||
"destructive border-destructive bg-destructive text-destructive-foreground group",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
@@ -60,7 +60,7 @@ const ToastAction = React.forwardRef<
|
||||
<ToastPrimitives.Action
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
|
||||
"ring-offset-background hover:bg-secondary focus:ring-ring group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -75,13 +75,13 @@ const ToastClose = React.forwardRef<
|
||||
<ToastPrimitives.Close
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",
|
||||
"text-foreground/50 hover:text-foreground absolute right-2 top-2 rounded-md p-1 opacity-0 transition-opacity focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",
|
||||
className,
|
||||
)}
|
||||
toast-close=""
|
||||
{...props}
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
<X className="size-4" />
|
||||
</ToastPrimitives.Close>
|
||||
));
|
||||
ToastClose.displayName = ToastPrimitives.Close.displayName;
|
||||
|
||||
@@ -39,7 +39,7 @@ async function doRequest<T>(
|
||||
return [undefined, undefined] as const;
|
||||
}
|
||||
|
||||
let parsed = respSchema.safeParse(await res.json());
|
||||
const parsed = respSchema.safeParse(await res.json());
|
||||
if (!parsed.success) {
|
||||
return [
|
||||
undefined,
|
||||
@@ -48,7 +48,7 @@ async function doRequest<T>(
|
||||
}
|
||||
|
||||
return [parsed.data, undefined] as const;
|
||||
} catch (error: any) {
|
||||
} catch (error) {
|
||||
return [
|
||||
undefined,
|
||||
{ message: `Failed to execute fetch request: ${error}` },
|
||||
|
||||
@@ -4,7 +4,7 @@ import AuthentikProvider from "next-auth/providers/authentik";
|
||||
import serverConfig from "@/lib/config";
|
||||
import prisma from "@remember/db";
|
||||
|
||||
let providers = [];
|
||||
const providers = [];
|
||||
|
||||
if (serverConfig.auth.authentik) {
|
||||
providers.push(AuthentikProvider(serverConfig.auth.authentik));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
function buildAuthentikConfig() {
|
||||
let { AUTHENTIK_ID, AUTHENTIK_SECRET, AUTHENTIK_ISSUER } = process.env;
|
||||
const { AUTHENTIK_ID, AUTHENTIK_SECRET, AUTHENTIK_ISSUER } = process.env;
|
||||
|
||||
if (!AUTHENTIK_ID || !AUTHENTIK_SECRET || !AUTHENTIK_ISSUER) {
|
||||
return undefined;
|
||||
|
||||
@@ -10,12 +10,18 @@ import prisma from "@remember/db";
|
||||
|
||||
import metascraper from "metascraper";
|
||||
|
||||
import metascraperDescription from "metascraper-description";
|
||||
import metascraperImage from "metascraper-image";
|
||||
import metascraperLogo from "metascraper-logo-favicon";
|
||||
import metascraperTitle from "metascraper-title";
|
||||
import metascraperUrl from "metascraper-url";
|
||||
|
||||
const metascraperParser = metascraper([
|
||||
require("metascraper-description")(),
|
||||
require("metascraper-image")(),
|
||||
require("metascraper-logo-favicon")(),
|
||||
require("metascraper-title")(),
|
||||
require("metascraper-url")(),
|
||||
metascraperDescription(),
|
||||
metascraperImage(),
|
||||
metascraperLogo(),
|
||||
metascraperTitle(),
|
||||
metascraperUrl(),
|
||||
]);
|
||||
|
||||
export default async function runCrawler(job: Job<ZCrawlLinkRequest, void>) {
|
||||
|
||||
@@ -46,7 +46,7 @@ async function inferTags(jobId: string, link: BookmarkedLink, openai: OpenAI) {
|
||||
response_format: { type: "json_object" },
|
||||
});
|
||||
|
||||
let response = chatCompletion.choices[0].message.content;
|
||||
const response = chatCompletion.choices[0].message.content;
|
||||
if (!response) {
|
||||
throw new Error(`[openai][${jobId}] Got no message content from OpenAI`);
|
||||
}
|
||||
@@ -89,10 +89,10 @@ async function createTags(tags: string[], userId: string) {
|
||||
|
||||
const existingTagSet = new Set<string>(existingTags.map((t) => t.name));
|
||||
|
||||
let newTags = tags.filter((t) => !existingTagSet.has(t));
|
||||
const newTags = tags.filter((t) => !existingTagSet.has(t));
|
||||
|
||||
// TODO: Prisma doesn't support createMany in Sqlite
|
||||
let newTagObjects = await Promise.all(
|
||||
const newTagObjects = await Promise.all(
|
||||
newTags.map((t) => {
|
||||
return prisma.bookmarkTags.create({
|
||||
data: {
|
||||
|
||||
70
yarn.lock
70
yarn.lock
@@ -2931,6 +2931,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-plugin-tailwindcss@npm:^3.14.2":
|
||||
version: 3.14.2
|
||||
resolution: "eslint-plugin-tailwindcss@npm:3.14.2"
|
||||
dependencies:
|
||||
fast-glob: "npm:^3.2.5"
|
||||
postcss: "npm:^8.4.4"
|
||||
peerDependencies:
|
||||
tailwindcss: ^3.4.0
|
||||
checksum: 10c0/fbe7d12ff7696b281f7ef5810c49ef276dbc115205437ae0e2a16fa607e7da15029127a8ab855b1616cb58308ed16b812ead2fecd3fa28770b0f6feadbe27cd6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-scope@npm:^7.2.2":
|
||||
version: 7.2.2
|
||||
resolution: "eslint-scope@npm:7.2.2"
|
||||
@@ -3060,7 +3072,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.1":
|
||||
"fast-glob@npm:^3.2.5, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.1":
|
||||
version: 3.3.2
|
||||
resolution: "fast-glob@npm:3.3.2"
|
||||
dependencies:
|
||||
@@ -5389,7 +5401,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"postcss@npm:^8, postcss@npm:^8.4.23":
|
||||
"postcss@npm:^8, postcss@npm:^8.4.23, postcss@npm:^8.4.4":
|
||||
version: 8.4.35
|
||||
resolution: "postcss@npm:8.4.35"
|
||||
dependencies:
|
||||
@@ -5425,6 +5437,57 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier-plugin-tailwindcss@npm:^0.5.11":
|
||||
version: 0.5.11
|
||||
resolution: "prettier-plugin-tailwindcss@npm:0.5.11"
|
||||
peerDependencies:
|
||||
"@ianvs/prettier-plugin-sort-imports": "*"
|
||||
"@prettier/plugin-pug": "*"
|
||||
"@shopify/prettier-plugin-liquid": "*"
|
||||
"@trivago/prettier-plugin-sort-imports": "*"
|
||||
prettier: ^3.0
|
||||
prettier-plugin-astro: "*"
|
||||
prettier-plugin-css-order: "*"
|
||||
prettier-plugin-import-sort: "*"
|
||||
prettier-plugin-jsdoc: "*"
|
||||
prettier-plugin-marko: "*"
|
||||
prettier-plugin-organize-attributes: "*"
|
||||
prettier-plugin-organize-imports: "*"
|
||||
prettier-plugin-style-order: "*"
|
||||
prettier-plugin-svelte: "*"
|
||||
peerDependenciesMeta:
|
||||
"@ianvs/prettier-plugin-sort-imports":
|
||||
optional: true
|
||||
"@prettier/plugin-pug":
|
||||
optional: true
|
||||
"@shopify/prettier-plugin-liquid":
|
||||
optional: true
|
||||
"@trivago/prettier-plugin-sort-imports":
|
||||
optional: true
|
||||
prettier-plugin-astro:
|
||||
optional: true
|
||||
prettier-plugin-css-order:
|
||||
optional: true
|
||||
prettier-plugin-import-sort:
|
||||
optional: true
|
||||
prettier-plugin-jsdoc:
|
||||
optional: true
|
||||
prettier-plugin-marko:
|
||||
optional: true
|
||||
prettier-plugin-organize-attributes:
|
||||
optional: true
|
||||
prettier-plugin-organize-imports:
|
||||
optional: true
|
||||
prettier-plugin-style-order:
|
||||
optional: true
|
||||
prettier-plugin-svelte:
|
||||
optional: true
|
||||
prettier-plugin-twig-melody:
|
||||
optional: true
|
||||
checksum: 10c0/46e095d2a4298820a75a7b36022e8f2bcd1658a289f2ab11e4b9d4b6075272fee003d9959d084dcb33d5d669daf275e978d9a9aed35efe5eb9e77e70070b47f6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:3.2.5, prettier@npm:^3.2.5":
|
||||
version: 3.2.5
|
||||
resolution: "prettier@npm:3.2.5"
|
||||
@@ -5736,7 +5799,10 @@ __metadata:
|
||||
eslint-config-prettier: "npm:^9.1.0"
|
||||
eslint-plugin-react: "npm:^7.33.2"
|
||||
eslint-plugin-react-hooks: "npm:^4.6.0"
|
||||
eslint-plugin-tailwindcss: "npm:^3.14.2"
|
||||
install: "npm:^0.13.0"
|
||||
prettier: "npm:3.2.5"
|
||||
prettier-plugin-tailwindcss: "npm:^0.5.11"
|
||||
typescript: "npm:^5"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
Reference in New Issue
Block a user