upgrade to next 15 (#151)
This commit is contained in:
@@ -9,27 +9,27 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.1.3",
|
||||
"@heroicons/react": "^2.2.0",
|
||||
"@unsend/email-editor": "workspace:*",
|
||||
"@unsend/ui": "workspace:*",
|
||||
"date-fns": "^3.6.0",
|
||||
"framer-motion": "^11.0.24",
|
||||
"lucide-react": "^0.359.0",
|
||||
"next": "14.2.25",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
"date-fns": "^4.1.0",
|
||||
"framer-motion": "^12.9.2",
|
||||
"lucide-react": "^0.503.0",
|
||||
"next": "15.3.1",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"@types/node": "^22.15.2",
|
||||
"@types/react": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.2",
|
||||
"@unsend/eslint-config": "workspace:*",
|
||||
"@unsend/tailwind-config": "workspace:*",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.1.4",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"typescript": "^5"
|
||||
"autoprefixer": "^10.4.21",
|
||||
"eslint": "^9.25.1",
|
||||
"eslint-config-next": "15.3.1",
|
||||
"postcss": "^8.5.3",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
@@ -12,18 +12,17 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@types/dotenv": "^8.2.0",
|
||||
"@types/mailparser": "^3.4.4",
|
||||
"@types/mailparser": "^3.4.5",
|
||||
"@types/smtp-server": "^3.5.10",
|
||||
"dotenv": "^16.4.5",
|
||||
"mailparser": "^3.7.1",
|
||||
"nodemailer": "^6.9.14",
|
||||
"smtp-server": "^3.13.4"
|
||||
"dotenv": "^16.5.0",
|
||||
"mailparser": "^3.7.2",
|
||||
"nodemailer": "^6.10.1",
|
||||
"smtp-server": "^3.13.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.1.0",
|
||||
"@types/nodemailer": "^6.4.15",
|
||||
"tsup": "^8.0.2",
|
||||
"typescript": "^5.5.4"
|
||||
"@types/node": "^22.15.2",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"tsup": "^8.4.0",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
2
apps/web/next-env.d.ts
vendored
2
apps/web/next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
|
@@ -9,7 +9,6 @@ const config = {
|
||||
output: process.env.DOCKER_OUTPUT ? "standalone" : undefined,
|
||||
experimental: {
|
||||
instrumentationHook: true,
|
||||
esmExternals: "loose",
|
||||
serverComponentsExternalPackages: ["bullmq"],
|
||||
},
|
||||
images: {
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3000",
|
||||
"dev": "next dev -p 3000 --turbopack",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint . --max-warnings 0",
|
||||
@@ -17,74 +17,77 @@
|
||||
"db:migrate-reset": "prisma migrate reset"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/prisma-adapter": "^1.4.0",
|
||||
"@aws-sdk/client-s3": "^3.637.0",
|
||||
"@aws-sdk/client-sesv2": "^3.535.0",
|
||||
"@aws-sdk/client-sns": "^3.540.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.637.0",
|
||||
"@hono/swagger-ui": "^0.2.1",
|
||||
"@hono/zod-openapi": "^0.10.0",
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
"@auth/prisma-adapter": "^2.9.0",
|
||||
"@aws-sdk/client-s3": "^3.797.0",
|
||||
"@aws-sdk/client-sesv2": "^3.797.0",
|
||||
"@aws-sdk/client-sns": "^3.797.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.797.0",
|
||||
"@hono/swagger-ui": "^0.5.1",
|
||||
"@hono/zod-openapi": "^0.19.5",
|
||||
"@hookform/resolvers": "^5.0.1",
|
||||
"@isaacs/ttlcache": "^1.4.1",
|
||||
"@prisma/client": "^6.3.1",
|
||||
"@t3-oss/env-nextjs": "^0.9.2",
|
||||
"@tanstack/react-query": "^5.25.0",
|
||||
"@trpc/client": "next",
|
||||
"@trpc/next": "next",
|
||||
"@trpc/react-query": "next",
|
||||
"@trpc/server": "next",
|
||||
"@prisma/client": "^6.6.0",
|
||||
"@t3-oss/env-nextjs": "^0.13.0",
|
||||
"@tanstack/react-query": "^5.74.4",
|
||||
"@trpc/client": "^11.1.1",
|
||||
"@trpc/next": "^11.1.1",
|
||||
"@trpc/react-query": "^11.1.1",
|
||||
"@trpc/server": "^11.1.1",
|
||||
"@unsend/email-editor": "workspace:*",
|
||||
"@unsend/ui": "workspace:*",
|
||||
"bullmq": "^5.41.0",
|
||||
"chrono-node": "^2.7.6",
|
||||
"date-fns": "^3.6.0",
|
||||
"emoji-picker-react": "^4.12.0",
|
||||
"framer-motion": "^11.0.24",
|
||||
"hono": "^4.2.2",
|
||||
"bullmq": "^5.51.1",
|
||||
"chrono-node": "^2.8.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"emoji-picker-react": "^4.12.2",
|
||||
"framer-motion": "^12.9.2",
|
||||
"hono": "^4.7.7",
|
||||
"html-to-text": "^9.0.5",
|
||||
"ioredis": "^5.4.1",
|
||||
"lucide-react": "^0.359.0",
|
||||
"mime-types": "^2.1.35",
|
||||
"nanoid": "^5.0.7",
|
||||
"next": "^14.2.25",
|
||||
"next-auth": "^4.24.6",
|
||||
"pnpm": "^8.15.5",
|
||||
"prisma": "^6.3.1",
|
||||
"query-string": "^9.0.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hook-form": "^7.51.3",
|
||||
"recharts": "^2.12.5",
|
||||
"ioredis": "^5.6.1",
|
||||
"lucide-react": "^0.503.0",
|
||||
"mime-types": "^3.0.1",
|
||||
"nanoid": "^5.1.5",
|
||||
"next": "^15.3.1",
|
||||
"next-auth": "^4.24.11",
|
||||
"pnpm": "^10.9.0",
|
||||
"prisma": "^6.6.0",
|
||||
"query-string": "^9.1.1",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-hook-form": "^7.56.1",
|
||||
"recharts": "^2.15.3",
|
||||
"server-only": "^0.0.1",
|
||||
"stripe": "^17.6.0",
|
||||
"superjson": "^2.2.1",
|
||||
"tldts": "^6.1.16",
|
||||
"ua-parser-js": "^1.0.38",
|
||||
"stripe": "^18.0.0",
|
||||
"superjson": "^2.2.2",
|
||||
"tldts": "^7.0.4",
|
||||
"ua-parser-js": "^2.0.3",
|
||||
"unsend": "workspace:*",
|
||||
"use-debounce": "^10.0.2",
|
||||
"zod": "^3.22.4"
|
||||
"use-debounce": "^10.0.4",
|
||||
"zod": "^3.24.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/eslint-plugin-next": "^14.2.2",
|
||||
"@types/eslint": "^8.56.2",
|
||||
"@next/eslint-plugin-next": "^15.3.1",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@types/html-to-text": "^9.0.4",
|
||||
"@types/mime-types": "^2.1.4",
|
||||
"@types/node": "^20.11.20",
|
||||
"@types/react": "^18.2.57",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"@types/node": "^22.15.2",
|
||||
"@types/react": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.2",
|
||||
"@types/ua-parser-js": "^0.7.39",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
||||
"@typescript-eslint/parser": "^7.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.31.0",
|
||||
"@typescript-eslint/parser": "^8.31.0",
|
||||
"@unsend/eslint-config": "workspace:*",
|
||||
"@unsend/tailwind-config": "workspace:*",
|
||||
"@unsend/typescript-config": "workspace:*",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "^14.1.3",
|
||||
"postcss": "^8.4.34",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-tailwindcss": "^0.5.11",
|
||||
"eslint": "^9.25.1",
|
||||
"eslint-config-next": "^15.3.1",
|
||||
"postcss": "^8.5.3",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.4.2"
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"overrides": {
|
||||
"react-is": "^19.0.0-rc-69d4b800-20241021"
|
||||
},
|
||||
"ct3aMetadata": {
|
||||
"initVersion": "7.30.0"
|
||||
|
@@ -5,7 +5,7 @@ import { Spinner } from "@unsend/ui/src/spinner";
|
||||
import { Button } from "@unsend/ui/src/button";
|
||||
import { Input } from "@unsend/ui/src/input";
|
||||
import { Editor } from "@unsend/email-editor";
|
||||
import { useState } from "react";
|
||||
import { use, useState } from "react";
|
||||
import { Campaign } from "@prisma/client";
|
||||
import {
|
||||
Select,
|
||||
@@ -51,16 +51,18 @@ const IMAGE_SIZE_LIMIT = 10 * 1024 * 1024;
|
||||
export default function EditCampaignPage({
|
||||
params,
|
||||
}: {
|
||||
params: { campaignId: string };
|
||||
params: Promise<{ campaignId: string }>;
|
||||
}) {
|
||||
const { campaignId } = use(params);
|
||||
|
||||
const {
|
||||
data: campaign,
|
||||
isLoading,
|
||||
error,
|
||||
} = api.campaign.getCampaign.useQuery(
|
||||
{ campaignId: params.campaignId },
|
||||
{ campaignId },
|
||||
{
|
||||
enabled: !!params.campaignId,
|
||||
enabled: !!campaignId,
|
||||
}
|
||||
);
|
||||
|
||||
|
@@ -12,16 +12,17 @@ import Link from "next/link";
|
||||
|
||||
import Spinner from "@unsend/ui/src/spinner";
|
||||
import { api } from "~/trpc/react";
|
||||
import { Separator } from "@unsend/ui/src/separator";
|
||||
import { ExternalLinkIcon } from "lucide-react";
|
||||
import { use } from "react";
|
||||
|
||||
export default function CampaignDetailsPage({
|
||||
params,
|
||||
}: {
|
||||
params: { campaignId: string };
|
||||
params: Promise<{ campaignId: string }>;
|
||||
}) {
|
||||
const { campaignId } = use(params);
|
||||
|
||||
const { data: campaign, isLoading } = api.campaign.getCampaign.useQuery({
|
||||
campaignId: params.campaignId,
|
||||
campaignId: campaignId,
|
||||
});
|
||||
|
||||
if (isLoading) {
|
||||
|
@@ -22,16 +22,18 @@ import {
|
||||
} from "@unsend/ui/src/popover";
|
||||
import { Button } from "@unsend/ui/src/button";
|
||||
import { useTheme } from "@unsend/ui";
|
||||
import { use } from "react";
|
||||
|
||||
export default function ContactsPage({
|
||||
params,
|
||||
}: {
|
||||
params: { contactBookId: string };
|
||||
params: Promise<{ contactBookId: string }>;
|
||||
}) {
|
||||
const { contactBookId } = use(params);
|
||||
const { theme } = useTheme();
|
||||
|
||||
const contactBookDetailQuery = api.contacts.getContactBookDetails.useQuery({
|
||||
contactBookId: params.contactBookId,
|
||||
contactBookId: contactBookId,
|
||||
});
|
||||
|
||||
const utils = api.useUtils();
|
||||
@@ -41,7 +43,7 @@ export default function ContactsPage({
|
||||
await utils.contacts.getContactBookDetails.cancel();
|
||||
utils.contacts.getContactBookDetails.setData(
|
||||
{
|
||||
contactBookId: params.contactBookId,
|
||||
contactBookId: contactBookId,
|
||||
},
|
||||
(old) => {
|
||||
if (!old) return old;
|
||||
@@ -54,7 +56,7 @@ export default function ContactsPage({
|
||||
},
|
||||
onSettled: () => {
|
||||
utils.contacts.getContactBookDetails.invalidate({
|
||||
contactBookId: params.contactBookId,
|
||||
contactBookId: contactBookId,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -93,7 +95,7 @@ export default function ContactsPage({
|
||||
// Handle emoji selection here
|
||||
// You might want to update the contactBook's emoji
|
||||
updateContactBookMutation.mutate({
|
||||
contactBookId: params.contactBookId,
|
||||
contactBookId: contactBookId,
|
||||
emoji: emojiObject.emoji,
|
||||
});
|
||||
}}
|
||||
@@ -118,7 +120,7 @@ export default function ContactsPage({
|
||||
</Breadcrumb>
|
||||
</div>
|
||||
<div className="flex gap-4">
|
||||
<AddContact contactBookId={params.contactBookId} />
|
||||
<AddContact contactBookId={contactBookId} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-16">
|
||||
@@ -153,7 +155,7 @@ export default function ContactsPage({
|
||||
Contact book ID
|
||||
</div>
|
||||
<TextWithCopyButton
|
||||
value={params.contactBookId}
|
||||
value={contactBookId}
|
||||
alwaysShowCopy
|
||||
className="text-sm w-[130px] overflow-hidden text-ellipsis font-mono"
|
||||
/>
|
||||
@@ -194,7 +196,7 @@ export default function ContactsPage({
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-16">
|
||||
<ContactList contactBookId={params.contactBookId} />
|
||||
<ContactList contactBookId={contactBookId} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -34,6 +34,7 @@ export default function ContactBooksList() {
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 ">
|
||||
{contactBooksQuery.data?.map((contactBook) => (
|
||||
<motion.div
|
||||
key={contactBook.id}
|
||||
whileHover={{ scale: 1.02 }}
|
||||
transition={{ type: "spring", stiffness: 200, damping: 10 }}
|
||||
whileTap={{ scale: 0.99 }}
|
||||
|
@@ -20,7 +20,7 @@ import {
|
||||
TableRow,
|
||||
} from "@unsend/ui/src/table";
|
||||
import { TextWithCopyButton } from "@unsend/ui/src/text-with-copy";
|
||||
import React from "react";
|
||||
import React, { use } from "react";
|
||||
import { Switch } from "@unsend/ui/src/switch";
|
||||
import DeleteDomain from "./delete-domain";
|
||||
import SendTestMail from "./send-test-mail";
|
||||
@@ -31,11 +31,13 @@ import { toast } from "@unsend/ui/src/toaster";
|
||||
export default function DomainItemPage({
|
||||
params,
|
||||
}: {
|
||||
params: { domainId: string };
|
||||
params: Promise<{ domainId: string }>;
|
||||
}) {
|
||||
const { domainId } = use(params);
|
||||
|
||||
const domainQuery = api.domain.getDomain.useQuery(
|
||||
{
|
||||
id: Number(params.domainId),
|
||||
id: Number(domainId),
|
||||
},
|
||||
{
|
||||
refetchInterval: (q) => (q?.state.data?.isVerifying ? 10000 : false),
|
||||
@@ -47,7 +49,7 @@ export default function DomainItemPage({
|
||||
|
||||
const handleVerify = () => {
|
||||
verifyQuery.mutate(
|
||||
{ id: Number(params.domainId) },
|
||||
{ id: Number(domainId) },
|
||||
{
|
||||
onSettled: () => {
|
||||
domainQuery.refetch();
|
||||
|
@@ -41,6 +41,7 @@ import { Input } from "@unsend/ui/src/input";
|
||||
import { DEFAULT_QUERY_LIMIT } from "~/lib/constants";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import { useState } from "react";
|
||||
import { SheetTitle, SheetDescription } from "@unsend/ui/src/sheet";
|
||||
|
||||
/* Stupid hydrating error. And I so stupid to understand the stupid NextJS docs */
|
||||
const DynamicSheetWithNoSSR = dynamic(
|
||||
@@ -122,7 +123,7 @@ export default function EmailsList() {
|
||||
<SelectItem value="All ApiKey">All ApiKey</SelectItem>
|
||||
{apiKeysQuery &&
|
||||
apiKeysQuery.map((apikey) => (
|
||||
<SelectItem value={apikey.id.toString()}>
|
||||
<SelectItem key={apikey.id} value={apikey.id.toString()}>
|
||||
{apikey.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
@@ -143,7 +144,7 @@ export default function EmailsList() {
|
||||
</SelectItem>
|
||||
{domainsQuery &&
|
||||
domainsQuery.map((domain) => (
|
||||
<SelectItem value={domain.id.toString()}>
|
||||
<SelectItem key={domain.id} value={domain.id.toString()}>
|
||||
{domain.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
@@ -173,7 +174,7 @@ export default function EmailsList() {
|
||||
"DELIVERY_DELAYED",
|
||||
"COMPLAINED",
|
||||
]).map((status) => (
|
||||
<SelectItem value={status} className=" capitalize">
|
||||
<SelectItem key={status} value={status} className=" capitalize">
|
||||
{status.toLowerCase().replace("_", " ")}
|
||||
</SelectItem>
|
||||
))}
|
||||
@@ -266,6 +267,10 @@ export default function EmailsList() {
|
||||
onOpenChange={handleSheetChange}
|
||||
>
|
||||
<DynamicSheetContentWithNoSSR className=" sm:max-w-3xl">
|
||||
<SheetTitle className="sr-only">Email Details</SheetTitle>
|
||||
<SheetDescription className="sr-only">
|
||||
Detailed view of the selected email.
|
||||
</SheetDescription>
|
||||
{selectedEmail ? <EmailDetails emailId={selectedEmail} /> : null}
|
||||
</DynamicSheetContentWithNoSSR>
|
||||
</DynamicSheetWithNoSSR>
|
||||
|
@@ -11,22 +11,24 @@ import { useDebouncedCallback } from "use-debounce";
|
||||
import { formatDistanceToNow } from "date-fns";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
import { use } from "react";
|
||||
const IMAGE_SIZE_LIMIT = 10 * 1024 * 1024;
|
||||
|
||||
export default function EditTemplatePage({
|
||||
params,
|
||||
}: {
|
||||
params: { templateId: string };
|
||||
params: Promise<{ templateId: string }>;
|
||||
}) {
|
||||
const { templateId } = use(params);
|
||||
|
||||
const {
|
||||
data: template,
|
||||
isLoading,
|
||||
error,
|
||||
} = api.template.getTemplate.useQuery(
|
||||
{ templateId: params.templateId },
|
||||
{ templateId: templateId },
|
||||
{
|
||||
enabled: !!params.templateId,
|
||||
enabled: !!templateId,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -75,7 +77,6 @@ function TemplateEditor({
|
||||
});
|
||||
const getUploadUrl = api.template.generateImagePresignedUrl.useMutation();
|
||||
|
||||
|
||||
function updateEditorContent() {
|
||||
updateTemplateMutation.mutate({
|
||||
templateId: template.id,
|
||||
@@ -195,7 +196,6 @@ function TemplateEditor({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className=" rounded-lg bg-gray-50 w-[700px] mx-auto p-10">
|
||||
<div className="w-[600px] mx-auto">
|
||||
<Editor
|
||||
|
@@ -27,7 +27,7 @@ const allowedEvents: Stripe.Event.Type[] = [
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const body = await req.text();
|
||||
const signature = headers().get("Stripe-Signature");
|
||||
const signature = (await headers()).get("Stripe-Signature");
|
||||
|
||||
if (!signature) {
|
||||
console.error("No signature");
|
||||
|
@@ -24,9 +24,9 @@ export default async function RootLayout({
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<body className={`font-sans ${inter.variable} app`}>
|
||||
<ThemeProvider attribute="class" defaultTheme="light">
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
<Toaster />
|
||||
<TRPCReactProvider>{children}</TRPCReactProvider>
|
||||
</ThemeProvider>
|
||||
|
@@ -6,10 +6,12 @@ export const dynamic = "force-dynamic";
|
||||
async function UnsubscribePage({
|
||||
searchParams,
|
||||
}: {
|
||||
searchParams: { [key: string]: string | string[] | undefined };
|
||||
searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
|
||||
}) {
|
||||
const id = searchParams.id as string;
|
||||
const hash = searchParams.hash as string;
|
||||
const params = await searchParams;
|
||||
|
||||
const id = params.id as string;
|
||||
const hash = params.hash as string;
|
||||
|
||||
if (!id || !hash) {
|
||||
return (
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { Context } from "hono";
|
||||
import { HTTPException } from "hono/http-exception";
|
||||
import { StatusCode } from "hono/utils/http-status";
|
||||
import { StatusCode, ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { z } from "zod";
|
||||
|
||||
const ErrorCode = z.enum([
|
||||
@@ -14,7 +14,7 @@ const ErrorCode = z.enum([
|
||||
"METHOD_NOT_ALLOWED",
|
||||
]);
|
||||
|
||||
function codeToStatus(code: z.infer<typeof ErrorCode>): StatusCode {
|
||||
function codeToStatus(code: z.infer<typeof ErrorCode>): ContentfulStatusCode {
|
||||
switch (code) {
|
||||
case "BAD_REQUEST":
|
||||
return 400;
|
||||
|
@@ -10,8 +10,8 @@ import { createTRPCContext } from "~/server/api/trpc";
|
||||
* This wraps the `createTRPCContext` helper and provides the required context for the tRPC API when
|
||||
* handling a tRPC call from a React Server Component.
|
||||
*/
|
||||
const createContext = cache(() => {
|
||||
const heads = new Headers(headers());
|
||||
const createContext = cache(async () => {
|
||||
const heads = new Headers(await headers());
|
||||
heads.set("x-trpc-source", "rsc");
|
||||
|
||||
return createTRPCContext({
|
||||
|
@@ -7,6 +7,5 @@ export default {
|
||||
content: [
|
||||
"./src/**/*.tsx",
|
||||
`${path.join(require.resolve("@unsend/ui"), "..")}/**/*.{ts,tsx}`,
|
||||
`${path.join(require.resolve("@unsend/email-editor"), "..")}/**/*.{ts,tsx}`,
|
||||
],
|
||||
} satisfies Config;
|
||||
|
@@ -30,15 +30,15 @@
|
||||
"devDependencies": {
|
||||
"@unsend/eslint-config": "workspace:*",
|
||||
"@unsend/typescript-config": "workspace:*",
|
||||
"dotenv-cli": "^7.4.1",
|
||||
"mintlify": "4.0.494",
|
||||
"prettier": "^3.2.5"
|
||||
"dotenv-cli": "^8.0.0",
|
||||
"mintlify": "4.0.510",
|
||||
"prettier": "^3.5.3"
|
||||
},
|
||||
"packageManager": "pnpm@8.9.0",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"dependencies": {
|
||||
"turbo": "^1.12.5"
|
||||
"turbo": "^2.5.2"
|
||||
}
|
||||
}
|
@@ -8,6 +8,8 @@
|
||||
"src"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"clean": "rm -rf dist",
|
||||
"lint": "eslint . --max-warnings 0",
|
||||
"lint:fix": "eslint . --fix"
|
||||
@@ -16,46 +18,47 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/eslint": "^9.6.0",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@types/react": "^19.1.2",
|
||||
"@unsend/eslint-config": "workspace:*",
|
||||
"@unsend/tailwind-config": "workspace:*",
|
||||
"@unsend/typescript-config": "workspace:*",
|
||||
"@unsend/ui": "workspace:*",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-tailwindcss": "^0.6.5",
|
||||
"react": "^18.3.1",
|
||||
"tailwindcss": "^3.4.4",
|
||||
"tsup": "^8.0.2"
|
||||
"postcss": "^8.5.3",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"react": "^19.1.0",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"tsup": "^8.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.3.1"
|
||||
"react": "^19.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tiptap/core": "^2.4.0",
|
||||
"@tiptap/extension-code-block": "^2.4.0",
|
||||
"@tiptap/extension-color": "^2.4.0",
|
||||
"@tiptap/extension-heading": "^2.4.0",
|
||||
"@tiptap/extension-image": "^2.6.4",
|
||||
"@tiptap/extension-link": "^2.4.0",
|
||||
"@tiptap/extension-paragraph": "^2.4.0",
|
||||
"@tiptap/extension-placeholder": "^2.4.0",
|
||||
"@tiptap/extension-task-item": "^2.4.0",
|
||||
"@tiptap/extension-task-list": "^2.4.0",
|
||||
"@tiptap/extension-text-align": "^2.4.0",
|
||||
"@tiptap/extension-text-style": "^2.4.0",
|
||||
"@tiptap/extension-underline": "^2.4.0",
|
||||
"@tiptap/pm": "^2.4.0",
|
||||
"@tiptap/react": "^2.4.0",
|
||||
"@tiptap/starter-kit": "^2.4.0",
|
||||
"@tiptap/suggestion": "^2.4.0",
|
||||
"eslint": "^9.9.1",
|
||||
"jsx-email": "^1.12.1",
|
||||
"lucide-react": "^0.359.0",
|
||||
"@tiptap/core": "^2.11.7",
|
||||
"@tiptap/extension-code-block": "^2.11.7",
|
||||
"@tiptap/extension-color": "^2.11.7",
|
||||
"@tiptap/extension-heading": "^2.11.7",
|
||||
"@tiptap/extension-image": "^2.11.7",
|
||||
"@tiptap/extension-link": "^2.11.7",
|
||||
"@tiptap/extension-paragraph": "^2.11.7",
|
||||
"@tiptap/extension-placeholder": "^2.11.7",
|
||||
"@tiptap/extension-task-item": "^2.11.7",
|
||||
"@tiptap/extension-task-list": "^2.11.7",
|
||||
"@tiptap/extension-text-align": "^2.11.7",
|
||||
"@tiptap/extension-text-style": "^2.11.7",
|
||||
"@tiptap/extension-underline": "^2.11.7",
|
||||
"@tiptap/pm": "^2.11.7",
|
||||
"@tiptap/react": "^2.11.7",
|
||||
"@tiptap/starter-kit": "^2.11.7",
|
||||
"@tiptap/suggestion": "^2.11.7",
|
||||
"eslint": "^9.25.1",
|
||||
"jsx-email": "^2.7.1",
|
||||
"lucide-react": "^0.503.0",
|
||||
"react-colorful": "^5.6.1",
|
||||
"shiki": "^3.3.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"tiptap-extension-global-drag-handle": "^0.1.10"
|
||||
"tiptap-extension-global-drag-handle": "^0.1.18"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
|
@@ -7,8 +7,7 @@ import {
|
||||
} from "@tiptap/pm/state";
|
||||
import { Fragment, Slice, Node } from "@tiptap/pm/model";
|
||||
|
||||
// @ts-ignore
|
||||
import { __serializeForClipboard, EditorView } from "@tiptap/pm/view";
|
||||
import { EditorView } from "@tiptap/pm/view";
|
||||
|
||||
export interface GlobalDragHandleOptions {
|
||||
/**
|
||||
@@ -167,7 +166,8 @@ export function DragHandlePlugin(
|
||||
}
|
||||
|
||||
const slice = view.state.selection.content();
|
||||
const { dom, text } = __serializeForClipboard(view, slice);
|
||||
console.log(slice, view);
|
||||
const { dom, text } = view.serializeForClipboard(slice);
|
||||
|
||||
event.dataTransfer.clearData();
|
||||
event.dataTransfer.setData("text/html", dom.innerHTML);
|
||||
|
@@ -8,13 +8,13 @@
|
||||
"react-internal.js"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@next/eslint-plugin-next": "^14.2.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
||||
"@typescript-eslint/parser": "^7.1.0",
|
||||
"@vercel/style-guide": "^5.2.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-turbo": "^1.12.4",
|
||||
"@next/eslint-plugin-next": "^15.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.31.0",
|
||||
"@typescript-eslint/parser": "^8.31.0",
|
||||
"@vercel/style-guide": "^6.0.0",
|
||||
"eslint-config-prettier": "^10.1.2",
|
||||
"eslint-config-turbo": "^2.5.2",
|
||||
"eslint-plugin-only-warn": "^1.1.0",
|
||||
"typescript": "^5.3.3"
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
@@ -16,16 +16,16 @@
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.12.12",
|
||||
"@types/react": "^18.3.2",
|
||||
"@types/node": "^22.15.2",
|
||||
"@types/react": "^19.1.2",
|
||||
"@unsend/eslint-config": "workspace:*",
|
||||
"@unsend/typescript-config": "workspace:*",
|
||||
"openapi-typescript": "^6.7.6",
|
||||
"tsup": "^8.0.2",
|
||||
"typescript": "^5.4.5"
|
||||
"openapi-typescript": "^7.6.1",
|
||||
"tsup": "^8.4.0",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-email/render": "^1.0.6",
|
||||
"react": "^18.3.1"
|
||||
"react": "^19.1.0"
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
@@ -13,9 +14,9 @@
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.24",
|
||||
"autoprefixer": "^10.4.18",
|
||||
"postcss": "^8.4.35",
|
||||
"@types/node": "^22.15.2",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"postcss": "^8.5.3",
|
||||
"tailwindcss": "^3.4.1"
|
||||
}
|
||||
}
|
@@ -12,51 +12,51 @@
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/eslint": "^8.56.5",
|
||||
"@types/node": "^20.11.24",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"@types/react-syntax-highlighter": "^15.5.11",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@types/node": "^22.15.2",
|
||||
"@types/react": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.2",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@unsend/eslint-config": "workspace:*",
|
||||
"@unsend/tailwind-config": "workspace:*",
|
||||
"@unsend/typescript-config": "workspace:*",
|
||||
"eslint": "^8.57.0",
|
||||
"postcss": "^8.4.36",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-tailwindcss": "^0.5.12",
|
||||
"react": "^18.2.0",
|
||||
"eslint": "^9.25.1",
|
||||
"postcss": "^8.5.3",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"react": "19.1.0",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.3.3"
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
"@radix-ui/react-accordion": "^1.2.0",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
||||
"@radix-ui/react-label": "^2.0.2",
|
||||
"@radix-ui/react-popover": "^1.1.1",
|
||||
"@radix-ui/react-progress": "^1.1.2",
|
||||
"@radix-ui/react-select": "^2.0.0",
|
||||
"@radix-ui/react-separator": "^1.0.3",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@radix-ui/react-switch": "^1.0.3",
|
||||
"@radix-ui/react-tabs": "^1.0.4",
|
||||
"@radix-ui/react-tooltip": "^1.1.2",
|
||||
"@hookform/resolvers": "^5.0.1",
|
||||
"@radix-ui/react-accordion": "^1.2.8",
|
||||
"@radix-ui/react-dialog": "^1.1.11",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.12",
|
||||
"@radix-ui/react-label": "^2.1.4",
|
||||
"@radix-ui/react-popover": "^1.1.11",
|
||||
"@radix-ui/react-progress": "^1.1.4",
|
||||
"@radix-ui/react-select": "^2.2.2",
|
||||
"@radix-ui/react-separator": "^1.1.4",
|
||||
"@radix-ui/react-slot": "^1.2.0",
|
||||
"@radix-ui/react-switch": "^1.2.2",
|
||||
"@radix-ui/react-tabs": "^1.1.9",
|
||||
"@radix-ui/react-tooltip": "^1.2.4",
|
||||
"add": "^2.0.6",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.0",
|
||||
"cmdk": "^1.0.0",
|
||||
"framer-motion": "^11.0.24",
|
||||
"input-otp": "^1.2.4",
|
||||
"lucide-react": "^0.359.0",
|
||||
"next-themes": "^0.3.0",
|
||||
"pnpm": "^8.15.5",
|
||||
"react-hook-form": "^7.51.3",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"recharts": "^2.12.5",
|
||||
"sonner": "^1.4.41",
|
||||
"tailwind-merge": "^2.2.2",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.1.1",
|
||||
"framer-motion": "^12.9.2",
|
||||
"input-otp": "^1.4.2",
|
||||
"lucide-react": "^0.503.0",
|
||||
"next-themes": "^0.4.6",
|
||||
"pnpm": "^10.9.0",
|
||||
"react-hook-form": "^7.56.1",
|
||||
"react-syntax-highlighter": "^15.6.1",
|
||||
"recharts": "^2.15.3",
|
||||
"sonner": "^2.0.3",
|
||||
"tailwind-merge": "^3.2.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"zod": "^3.22.4"
|
||||
"zod": "^3.24.3"
|
||||
}
|
||||
}
|
@@ -34,7 +34,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronRight className="ml-auto h-4 w-4" />
|
||||
<ChevronRight className="ml-auto" />
|
||||
</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",
|
||||
"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 origin-[--radix-dropdown-menu-content-transform-origin]",
|
||||
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",
|
||||
"z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-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 origin-[--radix-dropdown-menu-content-transform-origin]",
|
||||
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",
|
||||
"relative flex cursor-default select-none items-center gap-2 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 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
||||
inset && "pl-8",
|
||||
className
|
||||
)}
|
||||
|
15242
pnpm-lock.yaml
generated
15242
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -3,10 +3,7 @@
|
||||
"globalDependencies": [
|
||||
"**/.env.*local"
|
||||
],
|
||||
"globalDotEnv": [
|
||||
".env"
|
||||
],
|
||||
"pipeline": {
|
||||
"tasks": {
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
@@ -48,9 +45,6 @@
|
||||
"dev": {
|
||||
"cache": false,
|
||||
"persistent": true,
|
||||
"dotEnv": [
|
||||
".env"
|
||||
],
|
||||
"dependsOn": [
|
||||
"db:generate"
|
||||
]
|
||||
|
Reference in New Issue
Block a user