diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dbb79c89..53b8452c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,10 +71,9 @@ Run the command that will spin up all the required services and files. pnpm run dokploy:setup ``` -Build the server package (If you make any changes after in the packages/server folder, you need to rebuild and run this command) - +Run this script ```bash -pnpm run server:build +pnpm run server:script ``` Now run the development server. diff --git a/Dockerfile b/Dockerfile index 74b70db0..bb5310f2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,7 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile # Deploy only the dokploy app ENV NODE_ENV=production +RUN pnpm --filter=@dokploy/server switch:prod RUN pnpm --filter=@dokploy/server build RUN pnpm --filter=./apps/dokploy run build diff --git a/Dockerfile.cloud b/Dockerfile.cloud index ee9d0ef9..255ac3ad 100644 --- a/Dockerfile.cloud +++ b/Dockerfile.cloud @@ -15,6 +15,7 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm --filter=@dokploy/server # Deploy only the dokploy app ENV NODE_ENV=production +RUN pnpm --filter=@dokploy/server switch:prod RUN pnpm --filter=@dokploy/server build RUN pnpm --filter=./apps/dokploy run build diff --git a/Dockerfile.schedule b/Dockerfile.schedule index 5eca3420..36f06aef 100644 --- a/Dockerfile.schedule +++ b/Dockerfile.schedule @@ -15,6 +15,7 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm --filter=@dokploy/server # Deploy only the dokploy app ENV NODE_ENV=production +RUN pnpm --filter=@dokploy/server switch:prod RUN pnpm --filter=@dokploy/server build RUN pnpm --filter=./apps/schedules run build diff --git a/Dockerfile.server b/Dockerfile.server index a25b22e5..9cf04b21 100644 --- a/Dockerfile.server +++ b/Dockerfile.server @@ -15,6 +15,7 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm --filter=@dokploy/server # Deploy only the dokploy app ENV NODE_ENV=production +RUN pnpm --filter=@dokploy/server switch:prod RUN pnpm --filter=@dokploy/server build RUN pnpm --filter=./apps/api run build diff --git a/apps/api/src/schema.ts b/apps/api/src/schema.ts index 4655f006..5f26e018 100644 --- a/apps/api/src/schema.ts +++ b/apps/api/src/schema.ts @@ -8,7 +8,7 @@ export const deployJobSchema = z.discriminatedUnion("applicationType", [ server: z.boolean().optional(), type: z.enum(["deploy", "redeploy"]), applicationType: z.literal("application"), - serverId: z.string(), + serverId: z.string().min(1), }), z.object({ composeId: z.string(), @@ -17,7 +17,7 @@ export const deployJobSchema = z.discriminatedUnion("applicationType", [ server: z.boolean().optional(), type: z.enum(["deploy", "redeploy"]), applicationType: z.literal("compose"), - serverId: z.string(), + serverId: z.string().min(1), }), ]); diff --git a/apps/api/src/utils.ts b/apps/api/src/utils.ts index 01b83a77..5d776a5c 100644 --- a/apps/api/src/utils.ts +++ b/apps/api/src/utils.ts @@ -9,7 +9,7 @@ import { rebuildRemoteCompose, updateApplicationStatus, updateCompose, -} from "@dokploy/server"; +} from "@dokploy/server/dist"; import type { DeployJob } from "./schema"; import type { LemonSqueezyLicenseResponse } from "./types"; diff --git a/apps/dokploy/__test__/drop/drop.test.test.ts b/apps/dokploy/__test__/drop/drop.test.test.ts index 92821fb5..c906c144 100644 --- a/apps/dokploy/__test__/drop/drop.test.test.ts +++ b/apps/dokploy/__test__/drop/drop.test.test.ts @@ -1,12 +1,23 @@ import fs from "node:fs/promises"; import path from "node:path"; -import { paths } from "@dokploy/server/dist/constants"; +import { paths } from "@dokploy/server/constants"; const { APPLICATIONS_PATH } = paths(); import type { ApplicationNested } from "@dokploy/server"; import { unzipDrop } from "@dokploy/server"; import AdmZip from "adm-zip"; import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; +vi.mock("@dokploy/server/constants", async (importOriginal) => { + const actual = await importOriginal(); + return { + // @ts-ignore + ...actual, + paths: () => ({ + APPLICATIONS_PATH: "./__test__/drop/zips/output", + }), + }; +}); + if (typeof window === "undefined") { const undici = require("undici"); globalThis.File = undici.File as any; @@ -82,16 +93,6 @@ const baseApp: ApplicationNested = { dockerContextPath: null, }; -vi.mock("@dokploy/server/dist/constants", async (importOriginal) => { - const actual = await importOriginal(); - return { - // @ts-ignore - ...actual, - paths: () => ({ - APPLICATIONS_PATH: "./__test__/drop/zips/output", - }), - }; -}); describe("unzipDrop using real zip files", () => { // const { APPLICATIONS_PATH } = paths(); beforeAll(async () => { diff --git a/apps/dokploy/__test__/traefik/server/update-server-config.test.ts b/apps/dokploy/__test__/traefik/server/update-server-config.test.ts index 8eb387cc..c966748a 100644 --- a/apps/dokploy/__test__/traefik/server/update-server-config.test.ts +++ b/apps/dokploy/__test__/traefik/server/update-server-config.test.ts @@ -24,6 +24,9 @@ const baseAdmin: Admin = { sshPrivateKey: null, enableDockerCleanup: false, enableLogRotation: false, + serversQuantity: 0, + stripeCustomerId: "", + stripeSubscriptionId: "", }; beforeEach(() => { diff --git a/apps/dokploy/__test__/vitest.config.ts b/apps/dokploy/__test__/vitest.config.ts index c11f6cef..14eabf69 100644 --- a/apps/dokploy/__test__/vitest.config.ts +++ b/apps/dokploy/__test__/vitest.config.ts @@ -1,13 +1,8 @@ +import path from "node:path"; import tsconfigPaths from "vite-tsconfig-paths"; import { defineConfig } from "vitest/config"; export default defineConfig({ - plugins: [ - tsconfigPaths({ - root: "./", - projects: ["tsconfig.json"], - }), - ], test: { include: ["__test__/**/*.test.ts"], // Incluir solo los archivos de test en el directorio __test__ exclude: ["**/node_modules/**", "**/dist/**", "**/.docker/**"], @@ -18,4 +13,12 @@ export default defineConfig({ NODE: "test", }, }, + resolve: { + alias: { + "@dokploy/server": path.resolve( + __dirname, + "../../../packages/server/src", + ), + }, + }, }); diff --git a/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx b/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx new file mode 100644 index 00000000..8156f7d8 --- /dev/null +++ b/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx @@ -0,0 +1,241 @@ +import { Button } from "@/components/ui/button"; +import { NumberInput } from "@/components/ui/input"; +import { Progress } from "@/components/ui/progress"; +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { cn } from "@/lib/utils"; +import { api } from "@/utils/api"; +import { loadStripe } from "@stripe/stripe-js"; +import clsx from "clsx"; +import { AlertTriangle, CheckIcon, MinusIcon, PlusIcon } from "lucide-react"; +import React, { useState } from "react"; + +const stripePromise = loadStripe( + "pk_test_51QAm7bF3cxQuHeOz0xg04o9teeyTbbNHQPJ5Tr98MlTEan9MzewT3gwh0jSWBNvrRWZ5vASoBgxUSF4gPWsJwATk00Ir2JZ0S1", +); + +export const calculatePrice = (count: number, isAnnual = false) => { + if (isAnnual) { + if (count <= 1) return 45.9; + return 35.7 * count; + } + if (count <= 1) return 4.5; + return count * 3.5; +}; +// 178.156.147.118 +export const ShowBilling = () => { + const { data: servers } = api.server.all.useQuery(undefined); + const { data: admin } = api.admin.one.useQuery(); + const { data } = api.stripe.getProducts.useQuery(); + const { mutateAsync: createCheckoutSession } = + api.stripe.createCheckoutSession.useMutation(); + + const { mutateAsync: createCustomerPortalSession } = + api.stripe.createCustomerPortalSession.useMutation(); + + const [serverQuantity, setServerQuantity] = useState(3); + const [isAnnual, setIsAnnual] = useState(false); + + const handleCheckout = async (productId: string) => { + const stripe = await stripePromise; + if (data && data.subscriptions.length === 0) { + createCheckoutSession({ + productId, + serverQuantity: serverQuantity, + isAnnual, + }).then(async (session) => { + await stripe?.redirectToCheckout({ + sessionId: session.sessionId, + }); + }); + } + }; + const products = data?.products.filter((product) => { + // @ts-ignore + const interval = product?.default_price?.recurring?.interval; + return isAnnual ? interval === "year" : interval === "month"; + }); + + const maxServers = admin?.serversQuantity ?? 1; + const percentage = ((servers?.length ?? 0) / maxServers) * 100; + const safePercentage = Math.min(percentage, 100); + + return ( +
+ setIsAnnual(e === "annual")} + > + + Monthly + Annual + + + {admin?.stripeSubscriptionId && ( +
+

Servers Plan

+

+ You have {servers?.length} server on your plan of{" "} + {admin?.serversQuantity} servers +

+
+ +
+ {admin && ( + <> + {admin.serversQuantity! <= servers?.length! && ( +
+ + + You have reached the maximum number of servers you can + create, please upgrade your plan to add more servers. + +
+ )} + + )} +
+ )} + {products?.map((product) => { + const featured = true; + return ( +
+
+ {isAnnual ? ( +
+

+ $ {calculatePrice(serverQuantity, isAnnual).toFixed(2)} USD +

+ | +

+ ${" "} + {(calculatePrice(serverQuantity, isAnnual) / 12).toFixed(2)}{" "} + / Month USD +

+
+ ) : ( +

+ $ {calculatePrice(serverQuantity, isAnnual).toFixed(2)} USD +

+ )} +

+ {product.name} +

+

+ {product.description} +

+ +
    + {[ + "All the features of Dokploy", + "Unlimited deployments", + "Self-hosted on your own infrastructure", + "Full access to all deployment features", + "Dokploy integration", + "Backups", + "All Incoming features", + ].map((feature) => ( +
  • + + {feature} +
  • + ))} +
+
+
+ + {serverQuantity} Servers + +
+ +
+ + { + setServerQuantity(e.target.value as unknown as number); + }} + /> + + +
+
0 + ? "justify-between" + : "justify-end", + "flex flex-row items-center gap-2 mt-4", + )} + > + {admin?.stripeCustomerId && ( + + )} + + {data?.subscriptions?.length === 0 && ( +
+ +
+ )} +
+
+
+
+ ); + })} +
+ ); +}; diff --git a/apps/dokploy/components/dashboard/settings/cluster/registry/add-self-docker-registry.tsx b/apps/dokploy/components/dashboard/settings/cluster/registry/add-self-docker-registry.tsx deleted file mode 100644 index fe5a0ca9..00000000 --- a/apps/dokploy/components/dashboard/settings/cluster/registry/add-self-docker-registry.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import { Button } from "@/components/ui/button"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog"; -import { - Form, - FormControl, - FormDescription, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; -import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { AlertTriangle, Container } from "lucide-react"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; - -const AddRegistrySchema = z.object({ - username: z - .string() - .min(1, { - message: "Username is required", - }) - .regex(/^[a-zA-Z0-9]+$/, { - message: "Username can only contain letters and numbers", - }), - password: z.string().min(1, { - message: "Password is required", - }), - registryUrl: z.string().min(1, { - message: "Registry URL is required", - }), -}); - -type AddRegistry = z.infer; - -export const AddSelfHostedRegistry = () => { - const utils = api.useUtils(); - const [isOpen, setIsOpen] = useState(false); - const { mutateAsync, error, isError, isLoading } = - api.registry.enableSelfHostedRegistry.useMutation(); - const router = useRouter(); - const form = useForm({ - defaultValues: { - username: "", - password: "", - registryUrl: "", - }, - resolver: zodResolver(AddRegistrySchema), - }); - - useEffect(() => { - form.reset({ - registryUrl: "", - username: "", - password: "", - }); - }, [form, form.reset, form.formState.isSubmitSuccessful]); - - const onSubmit = async (data: AddRegistry) => { - await mutateAsync({ - registryUrl: data.registryUrl, - username: data.username, - password: data.password, - }) - .then(async (data) => { - await utils.registry.all.invalidate(); - toast.success("Self Hosted Registry Created"); - setIsOpen(false); - }) - .catch(() => { - toast.error("Error to create a self hosted registry"); - }); - }; - - return ( - - - - - - - Add a self hosted registry - - Fill the next fields to add a self hosted registry. - - - {isError && ( -
- - - {error?.message} - -
- )} -
- -
- ( - - Username - - - - - - - )} - /> -
-
- ( - - Password - - - - - - - )} - /> -
-
- ( - - Registry URL - - - - - Point a DNS record to the VPS IP address. - - - - - )} - /> -
- - - -
- -
-
- ); -}; diff --git a/apps/dokploy/components/dashboard/settings/cluster/registry/show-registry.tsx b/apps/dokploy/components/dashboard/settings/cluster/registry/show-registry.tsx index 94c82c48..0522301f 100644 --- a/apps/dokploy/components/dashboard/settings/cluster/registry/show-registry.tsx +++ b/apps/dokploy/components/dashboard/settings/cluster/registry/show-registry.tsx @@ -8,7 +8,6 @@ import { import { api } from "@/utils/api"; import { Server } from "lucide-react"; import { AddRegistry } from "./add-docker-registry"; -import { AddSelfHostedRegistry } from "./add-self-docker-registry"; import { DeleteRegistry } from "./delete-registry"; import { UpdateDockerRegistry } from "./update-docker-registry"; @@ -31,8 +30,6 @@ export const ShowRegistry = () => {
{data && data?.length > 0 && ( <> - {!haveSelfHostedRegistry && } - )} @@ -47,7 +44,6 @@ export const ShowRegistry = () => {
-
diff --git a/apps/dokploy/components/dashboard/settings/destination/add-destination.tsx b/apps/dokploy/components/dashboard/settings/destination/add-destination.tsx index e8b42daf..b8718d3b 100644 --- a/apps/dokploy/components/dashboard/settings/destination/add-destination.tsx +++ b/apps/dokploy/components/dashboard/settings/destination/add-destination.tsx @@ -18,6 +18,16 @@ import { FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect } from "react"; @@ -32,12 +42,15 @@ const addDestination = z.object({ bucket: z.string(), region: z.string(), endpoint: z.string(), + serverId: z.string().optional(), }); type AddDestination = z.infer; export const AddDestination = () => { const utils = api.useUtils(); + const { data: servers } = api.server.withSSHKey.useQuery(); + const { data: isCloud } = api.settings.isCloud.useQuery(); const { mutateAsync, isError, error, isLoading } = api.destination.create.useMutation(); @@ -189,30 +202,106 @@ export const AddDestination = () => { /> - - + + ) : ( + + .then(async () => { + toast.success("Connection Success"); + }) + .catch(() => { + toast.error("Error to connect the provider"); + }); + }} + > + Test connection + + )} + + + ) : ( + + .then(async () => { + toast.success("Connection Success"); + }) + .catch(() => { + toast.error("Error to connect the provider"); + }); + }} + > + Test connection + + )} + diff --git a/apps/dokploy/components/dashboard/settings/notifications/add-notification.tsx b/apps/dokploy/components/dashboard/settings/notifications/add-notification.tsx index 05bbb272..eef73ded 100644 --- a/apps/dokploy/components/dashboard/settings/notifications/add-notification.tsx +++ b/apps/dokploy/components/dashboard/settings/notifications/add-notification.tsx @@ -109,7 +109,7 @@ export type NotificationSchema = z.infer; export const AddNotification = () => { const utils = api.useUtils(); const [visible, setVisible] = useState(false); - + const { data: isCloud } = api.settings.isCloud.useQuery(); const { mutateAsync: testSlackConnection, isLoading: isLoadingSlack } = api.notification.testSlackConnection.useMutation(); @@ -660,26 +660,28 @@ export const AddNotification = () => { )} /> - ( - -
- Dokploy Restart - - Trigger the action when a dokploy is restarted. - -
- - - -
- )} - /> + {!isCloud && ( + ( + +
+ Dokploy Restart + + Trigger the action when a dokploy is restarted. + +
+ + + +
+ )} + /> + )} diff --git a/apps/dokploy/components/dashboard/settings/notifications/update-notification.tsx b/apps/dokploy/components/dashboard/settings/notifications/update-notification.tsx index 00119d42..23fd02ee 100644 --- a/apps/dokploy/components/dashboard/settings/notifications/update-notification.tsx +++ b/apps/dokploy/components/dashboard/settings/notifications/update-notification.tsx @@ -63,7 +63,7 @@ export const UpdateNotification = ({ notificationId }: Props) => { const telegramMutation = api.notification.updateTelegram.useMutation(); const discordMutation = api.notification.updateDiscord.useMutation(); const emailMutation = api.notification.updateEmail.useMutation(); - + const { data: isCloud } = api.settings.isCloud.useQuery(); const form = useForm({ defaultValues: { type: "slack", @@ -618,27 +618,29 @@ export const UpdateNotification = ({ notificationId }: Props) => { )} /> - ( - -
- Dokploy Restart - - Trigger the action when a dokploy is restarted. - -
- - - -
- )} - /> + {!isCloud && ( + ( + +
+ Dokploy Restart + + Trigger the action when a dokploy is restarted. + +
+ + + +
+ )} + /> + )} diff --git a/apps/dokploy/components/dashboard/settings/servers/add-server.tsx b/apps/dokploy/components/dashboard/settings/servers/add-server.tsx index 8cb71167..b8413303 100644 --- a/apps/dokploy/components/dashboard/settings/servers/add-server.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/add-server.tsx @@ -31,6 +31,7 @@ import { Textarea } from "@/components/ui/textarea"; import { api } from "@/utils/api"; import { zodResolver } from "@hookform/resolvers/zod"; import { PlusIcon } from "lucide-react"; +import Link from "next/link"; import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; @@ -57,6 +58,9 @@ type Schema = z.infer; export const AddServer = () => { const utils = api.useUtils(); const [isOpen, setIsOpen] = useState(false); + const { data: canCreateMoreServers, refetch } = + api.stripe.canCreateMoreServers.useQuery(); + const { data: sshKeys } = api.sshKey.all.useQuery(); const { mutateAsync, error, isError } = api.server.create.useMutation(); const form = useForm({ @@ -82,6 +86,10 @@ export const AddServer = () => { }); }, [form, form.reset, form.formState.isSubmitSuccessful]); + useEffect(() => { + refetch(); + }, [isOpen]); + const onSubmit = async (data: Schema) => { await mutateAsync({ name: data.name, @@ -116,6 +124,14 @@ export const AddServer = () => { Add a server to deploy your applications remotely. + {!canCreateMoreServers && ( + + You cannot create more servers,{" "} + + Please upgrade your plan + + + )} {isError && {error?.message}}
{ + + + + + + + + ); +} + +Home.getLayout = (page: ReactElement) => { + return {page}; +}; +export async function getServerSideProps(context: GetServerSidePropsContext) { + if (!IS_CLOUD) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + const { token } = context.query; + + if (typeof token !== "string") { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + + const authR = await db?.query.auth.findFirst({ + where: eq(auth.resetPasswordToken, token), + }); + + if (!authR || authR?.resetPasswordExpiresAt === null) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + const isExpired = isBefore( + new Date(authR.resetPasswordExpiresAt), + new Date(), + ); + + if (isExpired) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + + return { + props: { + token: authR.resetPasswordToken, + }, + }; +} diff --git a/apps/dokploy/pages/send-reset-password.tsx b/apps/dokploy/pages/send-reset-password.tsx new file mode 100644 index 00000000..daac30e1 --- /dev/null +++ b/apps/dokploy/pages/send-reset-password.tsx @@ -0,0 +1,172 @@ +import { Login2FA } from "@/components/auth/login-2fa"; +import { OnboardingLayout } from "@/components/layouts/onboarding-layout"; +import { AlertBlock } from "@/components/shared/alert-block"; +import { Logo } from "@/components/shared/logo"; +import { Button } from "@/components/ui/button"; +import { + Card, + CardContent, + CardDescription, + CardTitle, +} from "@/components/ui/card"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { api } from "@/utils/api"; +import { IS_CLOUD } from "@dokploy/server"; +import { zodResolver } from "@hookform/resolvers/zod"; +import type { GetServerSidePropsContext } from "next"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import { type ReactElement, useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; + +const loginSchema = z.object({ + email: z + .string() + .min(1, { + message: "Email is required", + }) + .email({ + message: "Email must be a valid email", + }), +}); + +type Login = z.infer; + +type AuthResponse = { + is2FAEnabled: boolean; + authId: string; +}; + +export default function Home() { + const [temp, setTemp] = useState({ + is2FAEnabled: false, + authId: "", + }); + const { mutateAsync, isLoading, isError, error } = + api.auth.sendResetPasswordEmail.useMutation(); + const router = useRouter(); + const form = useForm({ + defaultValues: { + email: "", + }, + resolver: zodResolver(loginSchema), + }); + + useEffect(() => { + form.reset(); + }, [form, form.reset, form.formState.isSubmitSuccessful]); + + const onSubmit = async (values: Login) => { + await mutateAsync({ + email: values.email, + }) + .then((data) => { + toast.success("Email sent", { + duration: 2000, + }); + }) + .catch(() => { + toast.error("Error to send email", { + duration: 2000, + }); + }); + }; + return ( +
+
+ + + Dokploy + + Reset Password + + Enter your email to reset your password + + + +
+ + {isError && ( + + {error?.message} + + )} + {!temp.is2FAEnabled ? ( +
+ +
+ ( + + Email + + + + + + )} + /> + + +
+
+ + ) : ( + + )} + +
+
+ + Login + +
+
+
+ +
+
+ ); +} + +Home.getLayout = (page: ReactElement) => { + return {page}; +}; +export async function getServerSideProps(context: GetServerSidePropsContext) { + if (!IS_CLOUD) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + + return { + props: {}, + }; +} diff --git a/apps/dokploy/server/api/root.ts b/apps/dokploy/server/api/root.ts index ad08911d..1b67d350 100644 --- a/apps/dokploy/server/api/root.ts +++ b/apps/dokploy/server/api/root.ts @@ -29,6 +29,7 @@ import { securityRouter } from "./routers/security"; import { serverRouter } from "./routers/server"; import { settingsRouter } from "./routers/settings"; import { sshRouter } from "./routers/ssh-key"; +import { stripeRouter } from "./routers/stripe"; import { userRouter } from "./routers/user"; /** @@ -69,6 +70,7 @@ export const appRouter = createTRPCRouter({ gitlab: gitlabRouter, github: githubRouter, server: serverRouter, + stripe: stripeRouter, }); // export type definition of API diff --git a/apps/dokploy/server/api/routers/auth.ts b/apps/dokploy/server/api/routers/auth.ts index cddcdede..5315800e 100644 --- a/apps/dokploy/server/api/routers/auth.ts +++ b/apps/dokploy/server/api/routers/auth.ts @@ -7,6 +7,7 @@ import { apiUpdateAuthByAdmin, apiVerify2FA, apiVerifyLogin2FA, + auth, } from "@/server/db/schema"; import { IS_CLOUD, @@ -18,12 +19,17 @@ import { getUserByToken, lucia, luciaToken, + sendEmailNotification, updateAuthById, validateRequest, verify2FA, } from "@dokploy/server"; import { TRPCError } from "@trpc/server"; import * as bcrypt from "bcrypt"; +import { isBefore } from "date-fns"; +import { eq } from "drizzle-orm"; +import { nanoid } from "nanoid"; +import { z } from "zod"; import { db } from "../../db"; import { adminProcedure, @@ -233,4 +239,101 @@ export const authRouter = createTRPCRouter({ verifyToken: protectedProcedure.mutation(async () => { return true; }), + sendResetPasswordEmail: publicProcedure + .input( + z.object({ + email: z.string().min(1).email(), + }), + ) + .mutation(async ({ ctx, input }) => { + if (!IS_CLOUD) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "This feature is only available in the cloud version", + }); + } + const authR = await db.query.auth.findFirst({ + where: eq(auth.email, input.email), + }); + if (!authR) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "User not found", + }); + } + const token = nanoid(); + await updateAuthById(authR.id, { + resetPasswordToken: token, + // Make resetPassword in 24 hours + resetPasswordExpiresAt: new Date( + new Date().getTime() + 24 * 60 * 60 * 1000, + ).toISOString(), + }); + + const email = await sendEmailNotification( + { + fromAddress: process.env.SMTP_FROM_ADDRESS || "", + toAddresses: [authR.email], + smtpServer: process.env.SMTP_SERVER || "", + smtpPort: Number(process.env.SMTP_PORT), + username: process.env.SMTP_USERNAME || "", + password: process.env.SMTP_PASSWORD || "", + }, + "Reset Password", + ` + Reset your password by clicking the link below: + The link will expire in 24 hours. + + Reset Password + + + `, + ); + }), + + resetPassword: publicProcedure + .input( + z.object({ + resetPasswordToken: z.string().min(1), + password: z.string().min(1), + }), + ) + .mutation(async ({ ctx, input }) => { + if (!IS_CLOUD) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "This feature is only available in the cloud version", + }); + } + const authR = await db.query.auth.findFirst({ + where: eq(auth.resetPasswordToken, input.resetPasswordToken), + }); + + if (!authR || authR.resetPasswordExpiresAt === null) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Token not found", + }); + } + + const isExpired = isBefore( + new Date(authR.resetPasswordExpiresAt), + new Date(), + ); + + if (isExpired) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Token expired", + }); + } + + await updateAuthById(authR.id, { + resetPasswordExpiresAt: null, + resetPasswordToken: null, + password: bcrypt.hashSync(input.password, 10), + }); + + return true; + }), }); diff --git a/apps/dokploy/server/api/routers/backup.ts b/apps/dokploy/server/api/routers/backup.ts index 553b7685..c6ae38b6 100644 --- a/apps/dokploy/server/api/routers/backup.ts +++ b/apps/dokploy/server/api/routers/backup.ts @@ -14,6 +14,7 @@ import { findMongoByBackupId, findMySqlByBackupId, findPostgresByBackupId, + findServerById, removeBackupById, removeScheduleBackup, runMariadbBackup, @@ -36,6 +37,25 @@ export const backupRouter = createTRPCRouter({ const backup = await findBackupById(newBackup.backupId); if (IS_CLOUD && backup.enabled) { + const databaseType = backup.databaseType; + let serverId = ""; + if (databaseType === "postgres" && backup.postgres?.serverId) { + serverId = backup.postgres.serverId; + } else if (databaseType === "mysql" && backup.mysql?.serverId) { + serverId = backup.mysql.serverId; + } else if (databaseType === "mongo" && backup.mongo?.serverId) { + serverId = backup.mongo.serverId; + } else if (databaseType === "mariadb" && backup.mariadb?.serverId) { + serverId = backup.mariadb.serverId; + } + const server = await findServerById(serverId); + + if (server.serverStatus === "inactive") { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Server is inactive", + }); + } await schedule({ cronSchedule: backup.schedule, backupId: backup.backupId, diff --git a/apps/dokploy/server/api/routers/compose.ts b/apps/dokploy/server/api/routers/compose.ts index 21704f94..f50956b2 100644 --- a/apps/dokploy/server/api/routers/compose.ts +++ b/apps/dokploy/server/api/routers/compose.ts @@ -252,7 +252,6 @@ export const composeRouter = createTRPCRouter({ descriptionLog: "", server: !!compose.serverId, }; - console.log(jobData); if (IS_CLOUD && compose.serverId) { jobData.serverId = compose.serverId; diff --git a/apps/dokploy/server/api/routers/destination.ts b/apps/dokploy/server/api/routers/destination.ts index 7abc474d..e960b278 100644 --- a/apps/dokploy/server/api/routers/destination.ts +++ b/apps/dokploy/server/api/routers/destination.ts @@ -12,9 +12,10 @@ import { destinations, } from "@/server/db/schema"; import { + IS_CLOUD, createDestintation, execAsync, - findAdmin, + execAsyncRemote, findDestinationById, removeDestinationById, updateDestinationById, @@ -53,11 +54,26 @@ export const destinationRouter = createTRPCRouter({ ]; const rcloneDestination = `:s3:${bucket}`; const rcloneCommand = `rclone ls ${rcloneFlags.join(" ")} "${rcloneDestination}"`; - await execAsync(rcloneCommand); + + if (IS_CLOUD && !input.serverId) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Server not found", + }); + } + + if (IS_CLOUD) { + await execAsyncRemote(input.serverId || "", rcloneCommand); + } else { + await execAsync(rcloneCommand); + } } catch (error) { throw new TRPCError({ code: "BAD_REQUEST", - message: "Error to connect to bucket", + message: + error instanceof Error + ? error?.message + : "Error to connect to bucket", cause: error, }); } diff --git a/apps/dokploy/server/api/routers/mariadb.ts b/apps/dokploy/server/api/routers/mariadb.ts index 99de2e3b..6755d647 100644 --- a/apps/dokploy/server/api/routers/mariadb.ts +++ b/apps/dokploy/server/api/routers/mariadb.ts @@ -18,6 +18,7 @@ import { deployMariadb, findMariadbById, findProjectById, + findServerById, removeMariadbById, removeService, startService, @@ -151,6 +152,7 @@ export const mariadbRouter = createTRPCRouter({ message: "You are not authorized to deploy this mariadb", }); } + return deployMariadb(input.mariadbId); }), changeStatus: protectedProcedure diff --git a/apps/dokploy/server/api/routers/notification.ts b/apps/dokploy/server/api/routers/notification.ts index 18e4ceb3..170b7bf2 100644 --- a/apps/dokploy/server/api/routers/notification.ts +++ b/apps/dokploy/server/api/routers/notification.ts @@ -148,12 +148,6 @@ export const notificationRouter = createTRPCRouter({ .input(apiCreateDiscord) .mutation(async ({ input, ctx }) => { try { - // go to your discord server - // go to settings - // go to integrations - // add a new integration - // select webhook - // copy the webhook url return await createDiscordNotification(input, ctx.user.adminId); } catch (error) { throw new TRPCError({ diff --git a/apps/dokploy/server/api/routers/registry.ts b/apps/dokploy/server/api/routers/registry.ts index 4b3f4628..8ca4a8a0 100644 --- a/apps/dokploy/server/api/routers/registry.ts +++ b/apps/dokploy/server/api/routers/registry.ts @@ -1,6 +1,5 @@ import { apiCreateRegistry, - apiEnableSelfHostedRegistry, apiFindOneRegistry, apiRemoveRegistry, apiTestRegistry, @@ -13,8 +12,6 @@ import { execAsyncRemote, findAllRegistryByAdminId, findRegistryById, - initializeRegistry, - manageRegistry, removeRegistry, updateRegistry, } from "@dokploy/server"; @@ -84,6 +81,13 @@ export const registryRouter = createTRPCRouter({ try { const loginCommand = `echo ${input.password} | docker login ${input.registryUrl} --username ${input.username} --password-stdin`; + if (IS_CLOUD && !input.serverId) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Select a server to test the registry", + }); + } + if (input.serverId && input.serverId !== "none") { await execAsyncRemote(input.serverId, loginCommand); } else { @@ -96,34 +100,4 @@ export const registryRouter = createTRPCRouter({ return false; } }), - - enableSelfHostedRegistry: adminProcedure - .input(apiEnableSelfHostedRegistry) - .mutation(async ({ input, ctx }) => { - if (IS_CLOUD) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "Self Hosted Registry is not available in the cloud version", - }); - } - const selfHostedRegistry = await createRegistry( - { - ...input, - registryName: "Self Hosted Registry", - registryType: "selfHosted", - registryUrl: - process.env.NODE_ENV === "production" - ? input.registryUrl - : "dokploy-registry.docker.localhost", - imagePrefix: null, - serverId: undefined, - }, - ctx.user.adminId, - ); - - await manageRegistry(selfHostedRegistry); - await initializeRegistry(input.username, input.password); - - return selfHostedRegistry; - }), }); diff --git a/apps/dokploy/server/api/routers/server.ts b/apps/dokploy/server/api/routers/server.ts index 77221212..6caaa9c8 100644 --- a/apps/dokploy/server/api/routers/server.ts +++ b/apps/dokploy/server/api/routers/server.ts @@ -1,3 +1,4 @@ +import { updateServersBasedOnQuantity } from "@/pages/api/stripe/webhook"; import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc"; import { db } from "@/server/db"; import { @@ -15,15 +16,17 @@ import { server, } from "@/server/db/schema"; import { + IS_CLOUD, createServer, deleteServer, + findAdminById, findServerById, + findServersByAdminId, haveActiveServices, removeDeploymentsByServerId, serverSetup, updateServerById, } from "@dokploy/server"; -// import { serverSetup } from "@/server/setup/server-setup"; import { TRPCError } from "@trpc/server"; import { and, desc, eq, getTableColumns, isNotNull, sql } from "drizzle-orm"; @@ -32,6 +35,14 @@ export const serverRouter = createTRPCRouter({ .input(apiCreateServer) .mutation(async ({ ctx, input }) => { try { + const admin = await findAdminById(ctx.user.adminId); + const servers = await findServersByAdminId(admin.adminId); + if (IS_CLOUD && servers.length >= admin.serversQuantity) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: "You cannot create more servers", + }); + } const project = await createServer(input, ctx.user.adminId); return project; } catch (error) { @@ -77,13 +88,17 @@ export const serverRouter = createTRPCRouter({ return result; }), withSSHKey: protectedProcedure.query(async ({ ctx }) => { - return await db.query.server.findMany({ + const result = await db.query.server.findMany({ orderBy: desc(server.createdAt), - where: and( - isNotNull(server.sshKeyId), - eq(server.adminId, ctx.user.adminId), - ), + where: IS_CLOUD + ? and( + isNotNull(server.sshKeyId), + eq(server.adminId, ctx.user.adminId), + eq(server.serverStatus, "active"), + ) + : and(isNotNull(server.sshKeyId), eq(server.adminId, ctx.user.adminId)), }); + return result; }), setup: protectedProcedure .input(apiFindOneServer) @@ -125,6 +140,15 @@ export const serverRouter = createTRPCRouter({ await removeDeploymentsByServerId(currentServer); await deleteServer(input.serverId); + if (IS_CLOUD) { + const admin = await findAdminById(ctx.user.adminId); + + await updateServersBasedOnQuantity( + admin.adminId, + admin.serversQuantity, + ); + } + return currentServer; } catch (error) { throw error; @@ -141,6 +165,13 @@ export const serverRouter = createTRPCRouter({ message: "You are not authorized to update this server", }); } + + if (server.serverStatus === "inactive") { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Server is inactive", + }); + } const currentServer = await updateServerById(input.serverId, { ...input, }); diff --git a/apps/dokploy/server/api/routers/settings.ts b/apps/dokploy/server/api/routers/settings.ts index e1e63579..485e8c73 100644 --- a/apps/dokploy/server/api/routers/settings.ts +++ b/apps/dokploy/server/api/routers/settings.ts @@ -221,6 +221,13 @@ export const settingsRouter = createTRPCRouter({ } if (server.enableDockerCleanup) { + const server = await findServerById(input.serverId); + if (server.serverStatus === "inactive") { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Server is inactive", + }); + } if (IS_CLOUD) { await schedule({ cronSchedule: "0 0 * * *", @@ -503,7 +510,7 @@ export const settingsRouter = createTRPCRouter({ if (input?.serverId) { const result = await execAsyncRemote(input.serverId, command); stdout = result.stdout; - } else { + } else if (!IS_CLOUD) { const result = await execAsync( "docker service inspect --format='{{json .Endpoint.Ports}}' dokploy-traefik", ); @@ -635,7 +642,7 @@ export const settingsRouter = createTRPCRouter({ return true; }), - isCloud: adminProcedure.query(async () => { + isCloud: protectedProcedure.query(async () => { return IS_CLOUD; }), health: publicProcedure.query(async () => { diff --git a/apps/dokploy/server/api/routers/stripe.ts b/apps/dokploy/server/api/routers/stripe.ts new file mode 100644 index 00000000..f897e03f --- /dev/null +++ b/apps/dokploy/server/api/routers/stripe.ts @@ -0,0 +1,130 @@ +import { WEBSITE_URL, getStripeItems } from "@/server/utils/stripe"; +import { + IS_CLOUD, + findAdminById, + findServersByAdminId, + updateAdmin, +} from "@dokploy/server"; +import { TRPCError } from "@trpc/server"; +import Stripe from "stripe"; +import { z } from "zod"; +import { adminProcedure, createTRPCRouter } from "../trpc"; + +export const stripeRouter = createTRPCRouter({ + getProducts: adminProcedure.query(async ({ ctx }) => { + const admin = await findAdminById(ctx.user.adminId); + const stripeCustomerId = admin.stripeCustomerId; + + const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", { + apiVersion: "2024-09-30.acacia", + }); + + const products = await stripe.products.list({ + expand: ["data.default_price"], + active: true, + }); + + if (!stripeCustomerId) { + return { + products: products.data, + subscriptions: [], + }; + } + + const subscriptions = await stripe.subscriptions.list({ + customer: stripeCustomerId, + status: "active", + expand: ["data.items.data.price"], + }); + + return { + products: products.data, + subscriptions: subscriptions.data, + }; + }), + createCheckoutSession: adminProcedure + .input( + z.object({ + productId: z.string(), + serverQuantity: z.number().min(1), + isAnnual: z.boolean(), + }), + ) + .mutation(async ({ ctx, input }) => { + const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", { + apiVersion: "2024-09-30.acacia", + }); + + const items = getStripeItems(input.serverQuantity, input.isAnnual); + const admin = await findAdminById(ctx.user.adminId); + + let stripeCustomerId = admin.stripeCustomerId; + + if (stripeCustomerId) { + const customer = await stripe.customers.retrieve(stripeCustomerId); + + if (customer.deleted) { + await updateAdmin(admin.authId, { + stripeCustomerId: null, + }); + stripeCustomerId = null; + } + } + + const session = await stripe.checkout.sessions.create({ + mode: "subscription", + line_items: items, + ...(stripeCustomerId && { + customer: stripeCustomerId, + }), + metadata: { + adminId: admin.adminId, + }, + success_url: `${WEBSITE_URL}/dashboard/settings/billing`, + cancel_url: `${WEBSITE_URL}/dashboard/settings/billing`, + }); + + return { sessionId: session.id }; + }), + createCustomerPortalSession: adminProcedure.mutation( + async ({ ctx, input }) => { + const admin = await findAdminById(ctx.user.adminId); + + if (!admin.stripeCustomerId) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: "Stripe Customer ID not found", + }); + } + const stripeCustomerId = admin.stripeCustomerId; + + const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", { + apiVersion: "2024-09-30.acacia", + }); + + try { + const session = await stripe.billingPortal.sessions.create({ + customer: stripeCustomerId, + return_url: `${WEBSITE_URL}/dashboard/settings/billing`, + }); + + return { url: session.url }; + } catch (error) { + return { + url: "", + }; + } + }, + ), + + canCreateMoreServers: adminProcedure.query(async ({ ctx }) => { + const admin = await findAdminById(ctx.user.adminId); + const servers = await findServersByAdminId(admin.adminId); + + if (!IS_CLOUD) { + return true; + } + + return servers.length < admin.serversQuantity; + }), +}); diff --git a/apps/dokploy/server/db/schema/index.ts b/apps/dokploy/server/db/schema/index.ts index c501bf93..5739c7a2 100644 --- a/apps/dokploy/server/db/schema/index.ts +++ b/apps/dokploy/server/db/schema/index.ts @@ -1 +1 @@ -export * from "@dokploy/server/dist/db/schema"; +export * from "@dokploy/server/db/schema"; diff --git a/apps/dokploy/server/server.ts b/apps/dokploy/server/server.ts index ec60d9a9..b965cd7c 100644 --- a/apps/dokploy/server/server.ts +++ b/apps/dokploy/server/server.ts @@ -27,7 +27,7 @@ import { config({ path: ".env" }); const PORT = Number.parseInt(process.env.PORT || "3000", 10); const dev = process.env.NODE_ENV !== "production"; -const app = next({ dev }); +const app = next({ dev, turbopack: dev }); const handle = app.getRequestHandler(); void app.prepare().then(async () => { try { @@ -40,7 +40,9 @@ void app.prepare().then(async () => { setupDockerContainerLogsWebSocketServer(server); setupDockerContainerTerminalWebSocketServer(server); setupTerminalWebSocketServer(server); - setupDockerStatsMonitoringSocketServer(server); + if (!IS_CLOUD) { + setupDockerStatsMonitoringSocketServer(server); + } if (process.env.NODE_ENV === "production" && !IS_CLOUD) { setupDirectories(); diff --git a/apps/dokploy/server/utils/deploy.ts b/apps/dokploy/server/utils/deploy.ts index 2dc56921..f0e4cd78 100644 --- a/apps/dokploy/server/utils/deploy.ts +++ b/apps/dokploy/server/utils/deploy.ts @@ -1,7 +1,12 @@ +import { findServerById } from "@dokploy/server"; import type { DeploymentJob } from "../queues/deployments-queue"; export const deploy = async (jobData: DeploymentJob) => { try { + const server = await findServerById(jobData.serverId as string); + if (server.serverStatus === "inactive") { + throw new Error("Server is inactive"); + } const result = await fetch(`${process.env.SERVER_URL}/deploy`, { method: "POST", headers: { diff --git a/apps/dokploy/server/utils/stripe.ts b/apps/dokploy/server/utils/stripe.ts new file mode 100644 index 00000000..7044769d --- /dev/null +++ b/apps/dokploy/server/utils/stripe.ts @@ -0,0 +1,27 @@ +export const WEBSITE_URL = + process.env.NODE_ENV === "development" + ? "http://localhost:3000" + : "https://app.dokploy.com"; + +const BASE_PRICE_MONTHLY_ID = process.env.BASE_PRICE_MONTHLY_ID || ""; // $4.00 + +const BASE_ANNUAL_MONTHLY_ID = process.env.BASE_ANNUAL_MONTHLY_ID || ""; // $7.99 + +export const getStripeItems = (serverQuantity: number, isAnnual: boolean) => { + const items = []; + + if (isAnnual) { + items.push({ + price: BASE_ANNUAL_MONTHLY_ID, + quantity: serverQuantity, + }); + + return items; + } + items.push({ + price: BASE_PRICE_MONTHLY_ID, + quantity: serverQuantity, + }); + + return items; +}; diff --git a/apps/dokploy/setup.ts b/apps/dokploy/setup.ts index d22eba4c..e4192ada 100644 --- a/apps/dokploy/setup.ts +++ b/apps/dokploy/setup.ts @@ -3,15 +3,15 @@ import { createDefaultServerTraefikConfig, createDefaultTraefikConfig, initializeTraefik, -} from "@dokploy/server/dist/setup/traefik-setup"; +} from "@dokploy/server/setup/traefik-setup"; -import { setupDirectories } from "@dokploy/server/dist/setup/config-paths"; -import { initializePostgres } from "@dokploy/server/dist/setup/postgres-setup"; -import { initializeRedis } from "@dokploy/server/dist/setup/redis-setup"; +import { setupDirectories } from "@dokploy/server/setup/config-paths"; +import { initializePostgres } from "@dokploy/server/setup/postgres-setup"; +import { initializeRedis } from "@dokploy/server/setup/redis-setup"; import { initializeNetwork, initializeSwarm, -} from "@dokploy/server/dist/setup/setup"; +} from "@dokploy/server/setup/setup"; (async () => { try { setupDirectories(); diff --git a/apps/dokploy/tsconfig.json b/apps/dokploy/tsconfig.json index de7e8a04..e132180e 100644 --- a/apps/dokploy/tsconfig.json +++ b/apps/dokploy/tsconfig.json @@ -26,7 +26,8 @@ /* Path Aliases */ "baseUrl": ".", "paths": { - "@/*": ["./*"] + "@/*": ["./*"], + "@dokploy/server/*": ["../../packages/server/src/*"] } }, diff --git a/apps/dokploy/tsconfig.server.json b/apps/dokploy/tsconfig.server.json index a5cc7a30..6a8f562f 100644 --- a/apps/dokploy/tsconfig.server.json +++ b/apps/dokploy/tsconfig.server.json @@ -9,7 +9,8 @@ "moduleResolution": "Node", "baseUrl": ".", "paths": { - "@/*": ["./*"] + "@/*": ["./*"], + "@dokploy/server/*": ["../../packages/server/src/*"] } }, "include": ["next-env.d.ts", "./server/**/*"] diff --git a/apps/schedules/src/utils.ts b/apps/schedules/src/utils.ts index e29e6dc0..07cefeef 100644 --- a/apps/schedules/src/utils.ts +++ b/apps/schedules/src/utils.ts @@ -3,11 +3,12 @@ import { cleanUpSystemPrune, cleanUpUnusedImages, findBackupById, + findServerById, runMariadbBackup, runMongoBackup, runMySqlBackup, runPostgresBackup, -} from "@dokploy/server"; +} from "@dokploy/server/dist"; import { db } from "@dokploy/server/dist/db"; import { backups, server } from "@dokploy/server/dist/db/schema"; import { eq } from "drizzle-orm"; @@ -21,22 +22,47 @@ export const runJobs = async (job: QueueJob) => { const { backupId } = job; const backup = await findBackupById(backupId); const { databaseType, postgres, mysql, mongo, mariadb } = backup; + if (databaseType === "postgres" && postgres) { + const server = await findServerById(postgres.serverId as string); + if (server.serverStatus === "inactive") { + logger.info("Server is inactive"); + return; + } await runPostgresBackup(postgres, backup); } else if (databaseType === "mysql" && mysql) { + const server = await findServerById(mysql.serverId as string); + if (server.serverStatus === "inactive") { + logger.info("Server is inactive"); + return; + } await runMySqlBackup(mysql, backup); } else if (databaseType === "mongo" && mongo) { + const server = await findServerById(mongo.serverId as string); + if (server.serverStatus === "inactive") { + logger.info("Server is inactive"); + return; + } await runMongoBackup(mongo, backup); } else if (databaseType === "mariadb" && mariadb) { + const server = await findServerById(mariadb.serverId as string); + if (server.serverStatus === "inactive") { + logger.info("Server is inactive"); + return; + } await runMariadbBackup(mariadb, backup); } } if (job.type === "server") { const { serverId } = job; + const server = await findServerById(serverId); + if (server.serverStatus === "inactive") { + logger.info("Server is inactive"); + return; + } await cleanUpUnusedImages(serverId); await cleanUpDockerBuilder(serverId); await cleanUpSystemPrune(serverId); - // await sendDockerCleanupNotifications(); } } catch (error) { logger.error(error); diff --git a/apps/website/components/SlimLayout.tsx b/apps/website/components/SlimLayout.tsx index 68345e21..9c93ed9b 100644 --- a/apps/website/components/SlimLayout.tsx +++ b/apps/website/components/SlimLayout.tsx @@ -1,7 +1,5 @@ import { Link } from "@/i18n/routing"; import { useTranslations } from "next-intl"; -import { Footer } from "./Footer"; -import { Header } from "./Header"; export function SlimLayout() { const t = useTranslations("404"); @@ -16,6 +14,7 @@ export function SlimLayout() { {t("action")} + p{" "}

diff --git a/apps/website/components/pricing.tsx b/apps/website/components/pricing.tsx index f1cf5660..508e5eb2 100644 --- a/apps/website/components/pricing.tsx +++ b/apps/website/components/pricing.tsx @@ -1,13 +1,17 @@ "use client"; import clsx from "clsx"; +import { cn } from "@/lib/utils"; +import { MinusIcon, PlusIcon } from "lucide-react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { Container } from "./Container"; import { trackGAEvent } from "./analitycs"; -import { Button } from "./ui/button"; -import { Switch } from "./ui/switch"; +import { Badge } from "./ui/badge"; +import { Button, buttonVariants } from "./ui/button"; +import { NumberInput } from "./ui/input"; +import { Tabs, TabsList, TabsTrigger } from "./ui/tabs"; function SwirlyDoodle(props: React.ComponentPropsWithoutRef<"svg">) { return ( @@ -55,7 +59,14 @@ function CheckIcon({ ); } - +export const calculatePrice = (count: number, isAnnual = false) => { + if (isAnnual) { + if (count <= 1) return 45.9; + return 35.7 * count; + } + if (count <= 1) return 4.5; + return count * 3.5; +}; function Plan({ name, price, @@ -63,6 +74,7 @@ function Plan({ href, features, featured = false, + buttonText = "Get Started", }: { name: string; price: string; @@ -70,6 +82,7 @@ function Plan({ href: string; features: Array; featured?: boolean; + buttonText?: string; }) { const router = useRouter(); return ( @@ -116,23 +129,17 @@ function Plan({ }} className="rounded-full mt-8" > - Get started + {buttonText} - {/* */} ); } export function Pricing() { - const [monthly, setMonthly] = useState(false); + const router = useRouter(); + const [isAnnual, setIsAnnual] = useState(true); + const [serverQuantity, setServerQuantity] = useState(3); + const featured = true; return (
-
- setMonthly(e)} /> - {!monthly ? "Monthly" : "Yearly"} -
-
- - - {/* */} +
+ setIsAnnual(e === "annual")} + > + + Monthly + Annual + + +
+
+
+

+ Free +

+ | +

+ Open Source +

+
+ +

+ Dokploy Open Source +

+

+ Manager your own infrastructure installing dokploy ui in your + own server. +

+ +
    + {[ + "Complete Flexibility: Install Dokploy UI on your own infrastructure", + "Unlimited Deployments", + "Self-hosted Infrastructure", + "Community Support", + "Access to Core Features", + "Dokploy Integration", + "Basic Backups", + "Access to All Updates", + ].map((feature) => ( +
  • + + {feature} +
  • + ))} +
+
+
+ + Unlimited Servers + +
+
+
+
+
+ Recommended 🚀 +
+ {isAnnual ? ( +
+

+ $ {calculatePrice(serverQuantity, isAnnual).toFixed(2)}{" "} + USD +

+ | +

+ ${" "} + {(calculatePrice(serverQuantity, isAnnual) / 12).toFixed( + 2, + )}{" "} + / Month USD +

+
+ ) : ( +

+ $ {calculatePrice(serverQuantity, isAnnual).toFixed(2)} USD +

+ )} +

+ Dokploy Plan +

+

+ No need to manage Dokploy UI infrastructure, we take care of + it for you. +

+ +
    + {[ + "Managed Hosting: No need to manage your own servers", + "Priority Support", + "Future-Proof Features", + ].map((feature) => ( +
  • + + {feature} +
  • + ))} +
+
+
+ + {serverQuantity} Servers (You bring the servers) + +
+ +
+ + { + setServerQuantity(e.target.value as unknown as number); + }} + /> + + +
+
+
+ + Subscribe + +
+
+
+
+
@@ -212,48 +365,43 @@ export function Pricing() { const faqs = [ [ { - question: "How does Dokploy's free plan work?", + question: "How does Dokploy's Open Source plan work?", answer: - "The free plan allows you to self-host Dokploy on your own infrastructure with unlimited deployments and full access to all features.", + "You can host Dokploy UI on your own infrastructure and you will be responsible for the maintenance and updates.", }, { question: "Do I need to provide my own server for the managed plan?", answer: - "Yes, in the managed plan, you provide your own server, and we manage the Dokploy UI infrastructure for you.", + "Yes, in the managed plan, you provide your own server eg(Hetzner, Hostinger, AWS, ETC.) VPS, and we manage the Dokploy UI infrastructure for you.", }, { question: "What happens if I need more than one server?", answer: - "Each additional server costs $3.99/month and can be easily added to your account.", + "The first server costs $4.50/month, if you buy more than one it will be $3.50/month per server.", }, ], [ - { - question: "Can I use my custom domain with Dokploy?", - answer: - "Yes, custom domain support is available on all plans, including the free version.", - }, { question: "Is there a limit on the number of deployments?", answer: "No, there is no limit on the number of deployments in any of the plans.", }, { - question: "Do I have to manually configure Traefik?", + question: "What happens if I exceed my purchased server limit?", answer: - "Dokploy offers dynamic Traefik configuration out-of-the-box, so no manual setup is needed.", + "The most recently added servers will be deactivated. You won't be able to create services on inactive servers until they are reactivated.", + }, + { + question: "Do you offer a refunds?", + answer: + "We do not offer refunds. However, you can cancel your subscription at any time. Feel free to try our open-source version for free before making a purchase.", }, ], [ - { - question: "How do automated backups work?", - answer: - "Automated backups are included in the managed plan and are limited to database backups only.", - }, { question: "What kind of support do you offer?", answer: - "We offer community support for the free plan and priority support for paid plans.", + "We offer community support for the open source version and priority support for paid plans.", }, { question: "Is Dokploy open-source?", @@ -279,7 +427,7 @@ export function Faqs() { {"Frequently asked questions"}

- If you can’t find what you’re looking for, please submit an issue + If you can’t find what you’re looking for, please send us an email to:{" "} support@dokploy.com diff --git a/apps/website/components/ui/badge.tsx b/apps/website/components/ui/badge.tsx new file mode 100644 index 00000000..f38976c0 --- /dev/null +++ b/apps/website/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import { type VariantProps, cva } from "class-variance-authority"; +import type * as React from "react"; + +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", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +

+ ); +} + +export { Badge, badgeVariants }; diff --git a/apps/website/components/ui/input.tsx b/apps/website/components/ui/input.tsx new file mode 100644 index 00000000..8fe7ab28 --- /dev/null +++ b/apps/website/components/ui/input.tsx @@ -0,0 +1,69 @@ +import { cn } from "@/lib/utils"; +import * as React from "react"; + +export interface InputProps + extends React.InputHTMLAttributes { + errorMessage?: string; +} + +const Input = React.forwardRef( + ({ className, errorMessage, type, ...props }, ref) => { + return ( + <> + + {errorMessage && ( + + {errorMessage} + + )} + + ); + }, +); +Input.displayName = "Input"; + +const NumberInput = React.forwardRef( + ({ className, errorMessage, ...props }, ref) => { + return ( + { + const value = e.target.value; + if (value === "") { + props.onChange?.(e); + } else { + const number = Number.parseInt(value, 10); + if (!Number.isNaN(number)) { + const syntheticEvent = { + ...e, + target: { + ...e.target, + value: number, + }, + }; + props.onChange?.( + syntheticEvent as unknown as React.ChangeEvent, + ); + } + } + }} + /> + ); + }, +); +NumberInput.displayName = "NumberInput"; + +export { Input, NumberInput }; diff --git a/apps/website/components/ui/tabs.tsx b/apps/website/components/ui/tabs.tsx new file mode 100644 index 00000000..e54c215a --- /dev/null +++ b/apps/website/components/ui/tabs.tsx @@ -0,0 +1,53 @@ +import * as TabsPrimitive from "@radix-ui/react-tabs"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Tabs = TabsPrimitive.Root; + +const TabsList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +TabsList.displayName = TabsPrimitive.List.displayName; + +const TabsTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName; + +const TabsContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +TabsContent.displayName = TabsPrimitive.Content.displayName; + +export { Tabs, TabsList, TabsTrigger, TabsContent }; diff --git a/apps/website/locales/en.json b/apps/website/locales/en.json index d171e3c7..7c401706 100644 --- a/apps/website/locales/en.json +++ b/apps/website/locales/en.json @@ -24,9 +24,9 @@ "projectsDes": "Manage and organize all your projects in one place, keeping detailed track of progress and resource allocation.", "applications": "Applications & Databases", "applicationsDes": "Centralize control over your applications and databases for enhanced security and efficiency, simplifying access and management across your infrastructure.", - "compose": "compose", + "compose": "Compose", "composeDes": "Native Docker Compose support for manage complex applications and services with ease.", - "multinode": "multinode", + "multinode": "Multinode", "multinodeDes": "Scale applications to multiples nodes using docker swarm to manage the cluster.", "monitoring": "Monitoring", "monitoringDes": "Monitor your systems' performance and health in real time, ensuring continuous and uninterrupted operation.", diff --git a/apps/website/package.json b/apps/website/package.json index a36e3f96..ebd2d263 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -31,7 +31,8 @@ "tailwind-merge": "^2.2.2", "tailwindcss": "^3.4.1", "tailwindcss-animate": "^1.0.7", - "typescript": "5.1.6" + "typescript": "5.1.6", + "@radix-ui/react-tabs": "1.1.1" }, "devDependencies": { "@biomejs/biome": "1.7.0", diff --git a/package.json b/package.json index 192da5b7..0c70e899 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "dokploy:build": "pnpm --filter=dokploy run build", "dokploy:start": "pnpm --filter=dokploy run start", "test": "pnpm --filter=dokploy run test", + "server:script": "pnpm --filter=server run switch:dev", "server:dev": "pnpm --filter=server run dev", "server:build": "pnpm --filter=server run build", "docker:build:canary": "./apps/dokploy/docker/build.sh canary", diff --git a/packages/server/esbuild.config.ts b/packages/server/esbuild.config.ts index 6504492b..03e2cf5d 100644 --- a/packages/server/esbuild.config.ts +++ b/packages/server/esbuild.config.ts @@ -1,28 +1,28 @@ -// import { build } from "esbuild"; -// import alias from "esbuild-plugin-alias"; -// import path from "node:path"; -// import { fileURLToPath } from "node:url"; -// const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file -// const __dirname = path.dirname(__filename); +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { build } from "esbuild"; +import alias from "esbuild-plugin-alias"; +const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file +const __dirname = path.dirname(__filename); -// build({ -// entryPoints: ["./src/**/*.ts"], -// // outfile: "./dist/index.js", -// outdir: "./dist", -// bundle: true, -// minify: false, -// platform: "node", -// target: "esnext", -// format: "esm", -// plugins: [ -// alias({ -// "@/server": path.resolve(__dirname, "src"), -// }), -// ], -// packages: "external", -// // Opcional: si deseas emitir declaraciones de tipos con esbuild-plugin-dts -// }) -// .then(() => { -// console.log("Build successful"); -// }) -// .catch(() => process.exit(1)); +build({ + entryPoints: ["./src/**/*.ts"], + // outfile: "./dist/index.js", + outdir: "./dist", + bundle: true, + minify: false, + platform: "node", + target: "esnext", + format: "esm", + plugins: [ + alias({ + "@dokploy/server": path.resolve(__dirname, "src"), + }), + ], + packages: "external", + // Opcional: si deseas emitir declaraciones de tipos con esbuild-plugin-dts +}) + .then(() => { + console.log("Build successful"); + }) + .catch(() => process.exit(1)); diff --git a/packages/server/package.json b/packages/server/package.json index 153011b8..6772f035 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,14 +1,42 @@ { "name": "@dokploy/server", "version": "1.0.0", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "./src/index.ts", "type": "module", + "exports": { + ".": "./src/index.ts", + "./db": { + "import": "./src/db/index.ts", + "require": "./dist/db/index.cjs.js" + }, + "./setup/*": { + "import": "./src/setup/*.ts", + "require": "./dist/setup/index.cjs.js" + }, + "./constants": { + "import": "./src/constants/index.ts", + "require": "./dist/constants.cjs.js" + }, + "./dist": { + "import": "./dist/index.js", + "require": "./dist/index.cjs.js" + }, + "./dist/db": { + "import": "./dist/db/index.js", + "require": "./dist/db/*.cjs" + }, + "./dist/db/schema": { + "import": "./dist/db/schema/index.js", + "require": "./dist/db/schema/*.cjs" + } + }, "scripts": { "build": "rm -rf ./dist && tsc --project tsconfig.server.json && tsc-alias -p tsconfig.server.json", "build:types": "tsc --emitDeclarationOnly --experimenta-dts", + "switch:dev": "node scripts/switchToSrc.js", + "switch:prod": "node scripts/switchToDist.js", "dev": "rm -rf ./dist && pnpm esbuild && tsc --emitDeclarationOnly --outDir dist -p tsconfig.server.json", - "esbuild": "tsx ./esbuild.config.ts", + "esbuild": "tsx ./esbuild.config.ts && tsc --project tsconfig.server.json --emitDeclarationOnly ", "typecheck": "tsc --noEmit" }, "dependencies": { @@ -49,6 +77,7 @@ "ssh2": "1.15.0" }, "devDependencies": { + "esbuild-plugin-alias": "0.2.1", "tailwindcss": "^3.4.1", "tsx": "^4.7.1", "tsc-alias": "1.8.10", diff --git a/packages/server/scripts/switchToDist.js b/packages/server/scripts/switchToDist.js new file mode 100644 index 00000000..12f5625a --- /dev/null +++ b/packages/server/scripts/switchToDist.js @@ -0,0 +1,27 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const packagePath = path.resolve(__dirname, "../package.json"); +const pkg = JSON.parse(fs.readFileSync(packagePath, "utf-8")); + +pkg.exports = { + ".": { + import: "./dist/index.js", + require: "./dist/index.cjs.js", + }, + "./db": { + import: "./dist/db/index.js", + require: "./dist/db/index.cjs.js", + }, + "./*": { + import: "./dist/*", + require: "./dist/*.cjs", + }, +}; + +fs.writeFileSync(packagePath, JSON.stringify(pkg, null, 2)); +console.log("Switched exports to use dist for production"); diff --git a/packages/server/scripts/switchToSrc.js b/packages/server/scripts/switchToSrc.js new file mode 100644 index 00000000..9387cd15 --- /dev/null +++ b/packages/server/scripts/switchToSrc.js @@ -0,0 +1,45 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const packagePath = path.resolve(__dirname, "../package.json"); + +// Leer el archivo package.json +const pkg = JSON.parse(fs.readFileSync(packagePath, "utf-8")); + +// Modificar los exports +pkg.exports = { + ".": "./src/index.ts", + "./db": { + import: "./src/db/index.ts", + require: "./dist/db/index.cjs.js", + }, + "./setup/*": { + import: "./src/setup/*.ts", + require: "./dist/setup/index.cjs.js", + }, + "./constants": { + import: "./src/constants/index.ts", + require: "./dist/constants.cjs.js", + }, + "./dist": { + import: "./dist/index.js", + require: "./dist/index.cjs.js", + }, + + "./dist/db": { + import: "./dist/db/index.js", + require: "./dist/db/*.cjs", + }, + "./dist/db/schema": { + import: "./dist/db/schema/index.js", + require: "./dist/db/schema/*.cjs", + }, +}; + +// Guardar los cambios en package.json +fs.writeFileSync(packagePath, JSON.stringify(pkg, null, 2)); +console.log("Switched exports to use src for development"); diff --git a/packages/server/src/auth/auth.ts b/packages/server/src/auth/auth.ts index 7d26a6c3..868afac5 100644 --- a/packages/server/src/auth/auth.ts +++ b/packages/server/src/auth/auth.ts @@ -1,7 +1,7 @@ import { webcrypto } from "node:crypto"; import type { IncomingMessage, ServerResponse } from "node:http"; -import { findAdminByAuthId } from "@/server/services/admin"; -import { findUserByAuthId } from "@/server/services/user"; +import { findAdminByAuthId } from "@dokploy/server/services/admin"; +import { findUserByAuthId } from "@dokploy/server/services/user"; import { DrizzlePostgreSQLAdapter } from "@lucia-auth/adapter-drizzle"; import { TimeSpan } from "lucia"; import { Lucia } from "lucia/dist/core.js"; diff --git a/packages/server/src/db/schema/admin.ts b/packages/server/src/db/schema/admin.ts index 011f57ae..cce611c2 100644 --- a/packages/server/src/db/schema/admin.ts +++ b/packages/server/src/db/schema/admin.ts @@ -1,5 +1,5 @@ import { relations } from "drizzle-orm"; -import { boolean, pgTable, text } from "drizzle-orm/pg-core"; +import { boolean, integer, pgTable, text } from "drizzle-orm/pg-core"; import { createInsertSchema } from "drizzle-zod"; import { nanoid } from "nanoid"; import { z } from "zod"; @@ -28,6 +28,9 @@ export const admins = pgTable("admin", { createdAt: text("createdAt") .notNull() .$defaultFn(() => new Date().toISOString()), + stripeCustomerId: text("stripeCustomerId"), + stripeSubscriptionId: text("stripeSubscriptionId"), + serversQuantity: integer("serversQuantity").notNull().default(0), }); export const adminsRelations = relations(admins, ({ one, many }) => ({ diff --git a/packages/server/src/db/schema/auth.ts b/packages/server/src/db/schema/auth.ts index 3b719c37..e8deb3c0 100644 --- a/packages/server/src/db/schema/auth.ts +++ b/packages/server/src/db/schema/auth.ts @@ -48,6 +48,8 @@ export const auth = pgTable("auth", { createdAt: text("createdAt") .notNull() .$defaultFn(() => new Date().toISOString()), + resetPasswordToken: text("resetPasswordToken"), + resetPasswordExpiresAt: text("resetPasswordExpiresAt"), }); export const authRelations = relations(auth, ({ many }) => ({ diff --git a/packages/server/src/db/schema/destination.ts b/packages/server/src/db/schema/destination.ts index 962303f7..bd9c7762 100644 --- a/packages/server/src/db/schema/destination.ts +++ b/packages/server/src/db/schema/destination.ts @@ -53,7 +53,10 @@ export const apiCreateDestination = createSchema endpoint: true, secretAccessKey: true, }) - .required(); + .required() + .extend({ + serverId: z.string().optional(), + }); export const apiFindOneDestination = createSchema .pick({ @@ -77,4 +80,7 @@ export const apiUpdateDestination = createSchema secretAccessKey: true, destinationId: true, }) - .required(); + .required() + .extend({ + serverId: z.string().optional(), + }); diff --git a/packages/server/src/db/schema/server.ts b/packages/server/src/db/schema/server.ts index 016bfe22..a9875d5b 100644 --- a/packages/server/src/db/schema/server.ts +++ b/packages/server/src/db/schema/server.ts @@ -1,5 +1,5 @@ import { relations } from "drizzle-orm"; -import { boolean, integer, pgTable, text } from "drizzle-orm/pg-core"; +import { boolean, integer, pgEnum, pgTable, text } from "drizzle-orm/pg-core"; import { createInsertSchema } from "drizzle-zod"; import { nanoid } from "nanoid"; import { z } from "zod"; @@ -17,6 +17,8 @@ import { redis } from "./redis"; import { sshKeys } from "./ssh-key"; import { generateAppName } from "./utils"; +export const serverStatus = pgEnum("serverStatus", ["active", "inactive"]); + export const server = pgTable("server", { serverId: text("serverId") .notNull() @@ -37,6 +39,8 @@ export const server = pgTable("server", { adminId: text("adminId") .notNull() .references(() => admins.adminId, { onDelete: "cascade" }), + serverStatus: serverStatus("serverStatus").notNull().default("active"), + sshKeyId: text("sshKeyId").references(() => sshKeys.sshKeyId, { onDelete: "set null", }), diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 06f2bc87..abddc405 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -37,7 +37,6 @@ export * from "./services/application"; export * from "./setup/config-paths"; export * from "./setup/postgres-setup"; export * from "./setup/redis-setup"; -export * from "./setup/registry-setup"; export * from "./setup/server-setup"; export * from "./setup/setup"; export * from "./setup/traefik-setup"; @@ -97,7 +96,6 @@ export * from "./utils/traefik/domain"; export * from "./utils/traefik/file-types"; export * from "./utils/traefik/middleware"; export * from "./utils/traefik/redirect"; -export * from "./utils/traefik/registry"; export * from "./utils/traefik/security"; export * from "./utils/traefik/types"; export * from "./utils/traefik/web-server"; diff --git a/packages/server/src/services/admin.ts b/packages/server/src/services/admin.ts index 45088302..94bd92d9 100644 --- a/packages/server/src/services/admin.ts +++ b/packages/server/src/services/admin.ts @@ -1,11 +1,11 @@ import { randomBytes } from "node:crypto"; -import { db } from "@/server/db"; +import { db } from "@dokploy/server/db"; import { admins, type apiCreateUserInvitation, auth, users, -} from "@/server/db/schema"; +} from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import * as bcrypt from "bcrypt"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/services/application.ts b/packages/server/src/services/application.ts index 5f2cb391..ec0c0c2f 100644 --- a/packages/server/src/services/application.ts +++ b/packages/server/src/services/application.ts @@ -1,38 +1,41 @@ -import { docker } from "@/server/constants"; -import { db } from "@/server/db"; -import { type apiCreateApplication, applications } from "@/server/db/schema"; -import { generateAppName } from "@/server/db/schema"; -import { getAdvancedStats } from "@/server/monitoring/utilts"; -import { generatePassword } from "@/server/templates/utils"; +import { docker } from "@dokploy/server/constants"; +import { db } from "@dokploy/server/db"; +import { + type apiCreateApplication, + applications, +} from "@dokploy/server/db/schema"; +import { generateAppName } from "@dokploy/server/db/schema"; +import { getAdvancedStats } from "@dokploy/server/monitoring/utilts"; +import { generatePassword } from "@dokploy/server/templates/utils"; import { buildApplication, getBuildCommand, mechanizeDockerContainer, -} from "@/server/utils/builders"; -import { sendBuildErrorNotifications } from "@/server/utils/notifications/build-error"; -import { sendBuildSuccessNotifications } from "@/server/utils/notifications/build-success"; -import { execAsyncRemote } from "@/server/utils/process/execAsync"; +} from "@dokploy/server/utils/builders"; +import { sendBuildErrorNotifications } from "@dokploy/server/utils/notifications/build-error"; +import { sendBuildSuccessNotifications } from "@dokploy/server/utils/notifications/build-success"; +import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync"; import { cloneBitbucketRepository, getBitbucketCloneCommand, -} from "@/server/utils/providers/bitbucket"; +} from "@dokploy/server/utils/providers/bitbucket"; import { buildDocker, buildRemoteDocker, -} from "@/server/utils/providers/docker"; +} from "@dokploy/server/utils/providers/docker"; import { cloneGitRepository, getCustomGitCloneCommand, -} from "@/server/utils/providers/git"; +} from "@dokploy/server/utils/providers/git"; import { cloneGithubRepository, getGithubCloneCommand, -} from "@/server/utils/providers/github"; +} from "@dokploy/server/utils/providers/github"; import { cloneGitlabRepository, getGitlabCloneCommand, -} from "@/server/utils/providers/gitlab"; -import { createTraefikConfig } from "@/server/utils/traefik/application"; +} from "@dokploy/server/utils/providers/gitlab"; +import { createTraefikConfig } from "@dokploy/server/utils/traefik/application"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; import { encodeBase64 } from "../utils/docker/utils"; diff --git a/packages/server/src/services/auth.ts b/packages/server/src/services/auth.ts index 61bf7292..1357f0f5 100644 --- a/packages/server/src/services/auth.ts +++ b/packages/server/src/services/auth.ts @@ -1,13 +1,13 @@ import { randomBytes } from "node:crypto"; -import { db } from "@/server/db"; +import { db } from "@dokploy/server/db"; import { admins, type apiCreateAdmin, type apiCreateUser, auth, users, -} from "@/server/db/schema"; -import { getPublicIpWithFallback } from "@/server/wss/terminal"; +} from "@dokploy/server/db/schema"; +import { getPublicIpWithFallback } from "@dokploy/server/wss/terminal"; import { TRPCError } from "@trpc/server"; import * as bcrypt from "bcrypt"; import { eq } from "drizzle-orm"; @@ -45,7 +45,6 @@ export const createAdmin = async (input: typeof apiCreateAdmin._type) => { ...(!IS_CLOUD && { serverIp: await getPublicIpWithFallback(), }), - serverIp: await getPublicIpWithFallback(), }) .returning(); diff --git a/packages/server/src/services/backup.ts b/packages/server/src/services/backup.ts index 55b38c22..42cc378a 100644 --- a/packages/server/src/services/backup.ts +++ b/packages/server/src/services/backup.ts @@ -1,5 +1,5 @@ -import { db } from "@/server/db"; -import { type apiCreateBackup, backups } from "@/server/db/schema"; +import { db } from "@dokploy/server/db"; +import { type apiCreateBackup, backups } from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/services/bitbucket.ts b/packages/server/src/services/bitbucket.ts index 589837dd..34aa491f 100644 --- a/packages/server/src/services/bitbucket.ts +++ b/packages/server/src/services/bitbucket.ts @@ -1,10 +1,10 @@ -import { db } from "@/server/db"; +import { db } from "@dokploy/server/db"; import { type apiCreateBitbucket, type apiUpdateBitbucket, bitbucket, gitProvider, -} from "@/server/db/schema"; +} from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/services/certificate.ts b/packages/server/src/services/certificate.ts index 1fa48404..23177862 100644 --- a/packages/server/src/services/certificate.ts +++ b/packages/server/src/services/certificate.ts @@ -1,9 +1,12 @@ import fs from "node:fs"; import path from "node:path"; -import { paths } from "@/server/constants"; -import { db } from "@/server/db"; -import { type apiCreateCertificate, certificates } from "@/server/db/schema"; -import { removeDirectoryIfExistsContent } from "@/server/utils/filesystem/directory"; +import { paths } from "@dokploy/server/constants"; +import { db } from "@dokploy/server/db"; +import { + type apiCreateCertificate, + certificates, +} from "@dokploy/server/db/schema"; +import { removeDirectoryIfExistsContent } from "@dokploy/server/utils/filesystem/directory"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; import { dump } from "js-yaml"; diff --git a/packages/server/src/services/compose.ts b/packages/server/src/services/compose.ts index 20e6a1ed..61d7e5fc 100644 --- a/packages/server/src/services/compose.ts +++ b/packages/server/src/services/compose.ts @@ -1,44 +1,47 @@ import { join } from "node:path"; -import { paths } from "@/server/constants"; -import { db } from "@/server/db"; -import { type apiCreateCompose, compose } from "@/server/db/schema"; -import { generateAppName } from "@/server/db/schema"; -import { generatePassword } from "@/server/templates/utils"; +import { paths } from "@dokploy/server/constants"; +import { db } from "@dokploy/server/db"; +import { type apiCreateCompose, compose } from "@dokploy/server/db/schema"; +import { generateAppName } from "@dokploy/server/db/schema"; +import { generatePassword } from "@dokploy/server/templates/utils"; import { buildCompose, getBuildComposeCommand, -} from "@/server/utils/builders/compose"; -import { randomizeSpecificationFile } from "@/server/utils/docker/compose"; +} from "@dokploy/server/utils/builders/compose"; +import { randomizeSpecificationFile } from "@dokploy/server/utils/docker/compose"; import { cloneCompose, cloneComposeRemote, loadDockerCompose, loadDockerComposeRemote, -} from "@/server/utils/docker/domain"; -import type { ComposeSpecification } from "@/server/utils/docker/types"; -import { sendBuildErrorNotifications } from "@/server/utils/notifications/build-error"; -import { sendBuildSuccessNotifications } from "@/server/utils/notifications/build-success"; -import { execAsync, execAsyncRemote } from "@/server/utils/process/execAsync"; +} from "@dokploy/server/utils/docker/domain"; +import type { ComposeSpecification } from "@dokploy/server/utils/docker/types"; +import { sendBuildErrorNotifications } from "@dokploy/server/utils/notifications/build-error"; +import { sendBuildSuccessNotifications } from "@dokploy/server/utils/notifications/build-success"; +import { + execAsync, + execAsyncRemote, +} from "@dokploy/server/utils/process/execAsync"; import { cloneBitbucketRepository, getBitbucketCloneCommand, -} from "@/server/utils/providers/bitbucket"; +} from "@dokploy/server/utils/providers/bitbucket"; import { cloneGitRepository, getCustomGitCloneCommand, -} from "@/server/utils/providers/git"; +} from "@dokploy/server/utils/providers/git"; import { cloneGithubRepository, getGithubCloneCommand, -} from "@/server/utils/providers/github"; +} from "@dokploy/server/utils/providers/github"; import { cloneGitlabRepository, getGitlabCloneCommand, -} from "@/server/utils/providers/gitlab"; +} from "@dokploy/server/utils/providers/gitlab"; import { createComposeFile, getCreateComposeFileCommand, -} from "@/server/utils/providers/raw"; +} from "@dokploy/server/utils/providers/raw"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; import { encodeBase64 } from "../utils/docker/utils"; diff --git a/packages/server/src/services/deployment.ts b/packages/server/src/services/deployment.ts index 5ea39c57..5ae6d130 100644 --- a/packages/server/src/services/deployment.ts +++ b/packages/server/src/services/deployment.ts @@ -1,14 +1,14 @@ import { existsSync, promises as fsPromises } from "node:fs"; import path from "node:path"; -import { paths } from "@/server/constants"; -import { db } from "@/server/db"; +import { paths } from "@dokploy/server/constants"; +import { db } from "@dokploy/server/db"; import { type apiCreateDeployment, type apiCreateDeploymentCompose, type apiCreateDeploymentServer, deployments, -} from "@/server/db/schema"; -import { removeDirectoryIfExistsContent } from "@/server/utils/filesystem/directory"; +} from "@dokploy/server/db/schema"; +import { removeDirectoryIfExistsContent } from "@dokploy/server/utils/filesystem/directory"; import { TRPCError } from "@trpc/server"; import { format } from "date-fns"; import { desc, eq } from "drizzle-orm"; @@ -20,7 +20,7 @@ import { import { type Compose, findComposeById, updateCompose } from "./compose"; import { type Server, findServerById } from "./server"; -import { execAsyncRemote } from "@/server/utils/process/execAsync"; +import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync"; export type Deployment = typeof deployments.$inferSelect; diff --git a/packages/server/src/services/destination.ts b/packages/server/src/services/destination.ts index c814d0b5..892c9354 100644 --- a/packages/server/src/services/destination.ts +++ b/packages/server/src/services/destination.ts @@ -1,5 +1,8 @@ -import { db } from "@/server/db"; -import { type apiCreateDestination, destinations } from "@/server/db/schema"; +import { db } from "@dokploy/server/db"; +import { + type apiCreateDestination, + destinations, +} from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { and, eq } from "drizzle-orm"; diff --git a/packages/server/src/services/docker.ts b/packages/server/src/services/docker.ts index d611a11d..d5a40fe0 100644 --- a/packages/server/src/services/docker.ts +++ b/packages/server/src/services/docker.ts @@ -1,4 +1,7 @@ -import { execAsync, execAsyncRemote } from "@/server/utils/process/execAsync"; +import { + execAsync, + execAsyncRemote, +} from "@dokploy/server/utils/process/execAsync"; export const getContainers = async (serverId?: string | null) => { try { diff --git a/packages/server/src/services/domain.ts b/packages/server/src/services/domain.ts index d94cdc08..28dd3ba2 100644 --- a/packages/server/src/services/domain.ts +++ b/packages/server/src/services/domain.ts @@ -1,6 +1,6 @@ -import { db } from "@/server/db"; -import { generateRandomDomain } from "@/server/templates/utils"; -import { manageDomain } from "@/server/utils/traefik/domain"; +import { db } from "@dokploy/server/db"; +import { generateRandomDomain } from "@dokploy/server/templates/utils"; +import { manageDomain } from "@dokploy/server/utils/traefik/domain"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; import { type apiCreateDomain, domains } from "../db/schema"; diff --git a/packages/server/src/services/git-provider.ts b/packages/server/src/services/git-provider.ts index 25b455c4..dfcdaf10 100644 --- a/packages/server/src/services/git-provider.ts +++ b/packages/server/src/services/git-provider.ts @@ -1,5 +1,5 @@ -import { db } from "@/server/db"; -import { gitProvider } from "@/server/db/schema"; +import { db } from "@dokploy/server/db"; +import { gitProvider } from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/services/github.ts b/packages/server/src/services/github.ts index 110dc55e..a7317bc7 100644 --- a/packages/server/src/services/github.ts +++ b/packages/server/src/services/github.ts @@ -1,5 +1,9 @@ -import { db } from "@/server/db"; -import { type apiCreateGithub, gitProvider, github } from "@/server/db/schema"; +import { db } from "@dokploy/server/db"; +import { + type apiCreateGithub, + gitProvider, + github, +} from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/services/gitlab.ts b/packages/server/src/services/gitlab.ts index 53eb1083..673cf1f1 100644 --- a/packages/server/src/services/gitlab.ts +++ b/packages/server/src/services/gitlab.ts @@ -1,11 +1,11 @@ -import { db } from "@/server/db"; +import { db } from "@dokploy/server/db"; import { type apiCreateGitlab, type bitbucket, gitProvider, type github, gitlab, -} from "@/server/db/schema"; +} from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/services/mariadb.ts b/packages/server/src/services/mariadb.ts index 91cc7d73..645b5c65 100644 --- a/packages/server/src/services/mariadb.ts +++ b/packages/server/src/services/mariadb.ts @@ -1,14 +1,18 @@ -import { db } from "@/server/db"; -import { type apiCreateMariaDB, backups, mariadb } from "@/server/db/schema"; -import { generateAppName } from "@/server/db/schema"; -import { generatePassword } from "@/server/templates/utils"; -import { buildMariadb } from "@/server/utils/databases/mariadb"; -import { pullImage } from "@/server/utils/docker/utils"; +import { db } from "@dokploy/server/db"; +import { + type apiCreateMariaDB, + backups, + mariadb, +} from "@dokploy/server/db/schema"; +import { generateAppName } from "@dokploy/server/db/schema"; +import { generatePassword } from "@dokploy/server/templates/utils"; +import { buildMariadb } from "@dokploy/server/utils/databases/mariadb"; +import { pullImage } from "@dokploy/server/utils/docker/utils"; import { TRPCError } from "@trpc/server"; import { eq, getTableColumns } from "drizzle-orm"; import { validUniqueServerAppName } from "./project"; -import { execAsyncRemote } from "@/server/utils/process/execAsync"; +import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync"; export type Mariadb = typeof mariadb.$inferSelect; diff --git a/packages/server/src/services/mongo.ts b/packages/server/src/services/mongo.ts index 06b1cf58..1360372d 100644 --- a/packages/server/src/services/mongo.ts +++ b/packages/server/src/services/mongo.ts @@ -1,14 +1,14 @@ -import { db } from "@/server/db"; -import { type apiCreateMongo, backups, mongo } from "@/server/db/schema"; -import { generateAppName } from "@/server/db/schema"; -import { generatePassword } from "@/server/templates/utils"; -import { buildMongo } from "@/server/utils/databases/mongo"; -import { pullImage } from "@/server/utils/docker/utils"; +import { db } from "@dokploy/server/db"; +import { type apiCreateMongo, backups, mongo } from "@dokploy/server/db/schema"; +import { generateAppName } from "@dokploy/server/db/schema"; +import { generatePassword } from "@dokploy/server/templates/utils"; +import { buildMongo } from "@dokploy/server/utils/databases/mongo"; +import { pullImage } from "@dokploy/server/utils/docker/utils"; import { TRPCError } from "@trpc/server"; import { eq, getTableColumns } from "drizzle-orm"; import { validUniqueServerAppName } from "./project"; -import { execAsyncRemote } from "@/server/utils/process/execAsync"; +import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync"; export type Mongo = typeof mongo.$inferSelect; diff --git a/packages/server/src/services/mount.ts b/packages/server/src/services/mount.ts index 97528aa5..f5211599 100644 --- a/packages/server/src/services/mount.ts +++ b/packages/server/src/services/mount.ts @@ -1,14 +1,17 @@ import path from "node:path"; -import { paths } from "@/server/constants"; -import { db } from "@/server/db"; +import { paths } from "@dokploy/server/constants"; +import { db } from "@dokploy/server/db"; import { type ServiceType, type apiCreateMount, mounts, -} from "@/server/db/schema"; -import { createFile, getCreateFileCommand } from "@/server/utils/docker/utils"; -import { removeFileOrDirectory } from "@/server/utils/filesystem/directory"; -import { execAsyncRemote } from "@/server/utils/process/execAsync"; +} from "@dokploy/server/db/schema"; +import { + createFile, + getCreateFileCommand, +} from "@dokploy/server/utils/docker/utils"; +import { removeFileOrDirectory } from "@dokploy/server/utils/filesystem/directory"; +import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync"; import { TRPCError } from "@trpc/server"; import { type SQL, eq, sql } from "drizzle-orm"; diff --git a/packages/server/src/services/mysql.ts b/packages/server/src/services/mysql.ts index 7cae5801..ee9df820 100644 --- a/packages/server/src/services/mysql.ts +++ b/packages/server/src/services/mysql.ts @@ -1,14 +1,14 @@ -import { db } from "@/server/db"; -import { type apiCreateMySql, backups, mysql } from "@/server/db/schema"; -import { generateAppName } from "@/server/db/schema"; -import { generatePassword } from "@/server/templates/utils"; -import { buildMysql } from "@/server/utils/databases/mysql"; -import { pullImage } from "@/server/utils/docker/utils"; +import { db } from "@dokploy/server/db"; +import { type apiCreateMySql, backups, mysql } from "@dokploy/server/db/schema"; +import { generateAppName } from "@dokploy/server/db/schema"; +import { generatePassword } from "@dokploy/server/templates/utils"; +import { buildMysql } from "@dokploy/server/utils/databases/mysql"; +import { pullImage } from "@dokploy/server/utils/docker/utils"; import { TRPCError } from "@trpc/server"; import { eq, getTableColumns } from "drizzle-orm"; import { validUniqueServerAppName } from "./project"; -import { execAsyncRemote } from "@/server/utils/process/execAsync"; +import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync"; export type MySql = typeof mysql.$inferSelect; diff --git a/packages/server/src/services/notification.ts b/packages/server/src/services/notification.ts index a7d3a04a..22e1e0b5 100644 --- a/packages/server/src/services/notification.ts +++ b/packages/server/src/services/notification.ts @@ -1,4 +1,4 @@ -import { db } from "@/server/db"; +import { db } from "@dokploy/server/db"; import { type apiCreateDiscord, type apiCreateEmail, @@ -13,7 +13,7 @@ import { notifications, slack, telegram, -} from "@/server/db/schema"; +} from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/services/port.ts b/packages/server/src/services/port.ts index 19229a9c..1f66c014 100644 --- a/packages/server/src/services/port.ts +++ b/packages/server/src/services/port.ts @@ -1,5 +1,5 @@ -import { db } from "@/server/db"; -import { type apiCreatePort, ports } from "@/server/db/schema"; +import { db } from "@dokploy/server/db"; +import { type apiCreatePort, ports } from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/services/postgres.ts b/packages/server/src/services/postgres.ts index 3307141d..c94ddbbe 100644 --- a/packages/server/src/services/postgres.ts +++ b/packages/server/src/services/postgres.ts @@ -1,14 +1,18 @@ -import { db } from "@/server/db"; -import { type apiCreatePostgres, backups, postgres } from "@/server/db/schema"; -import { generateAppName } from "@/server/db/schema"; -import { generatePassword } from "@/server/templates/utils"; -import { buildPostgres } from "@/server/utils/databases/postgres"; -import { pullImage } from "@/server/utils/docker/utils"; +import { db } from "@dokploy/server/db"; +import { + type apiCreatePostgres, + backups, + postgres, +} from "@dokploy/server/db/schema"; +import { generateAppName } from "@dokploy/server/db/schema"; +import { generatePassword } from "@dokploy/server/templates/utils"; +import { buildPostgres } from "@dokploy/server/utils/databases/postgres"; +import { pullImage } from "@dokploy/server/utils/docker/utils"; import { TRPCError } from "@trpc/server"; import { eq, getTableColumns } from "drizzle-orm"; import { validUniqueServerAppName } from "./project"; -import { execAsyncRemote } from "@/server/utils/process/execAsync"; +import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync"; export type Postgres = typeof postgres.$inferSelect; diff --git a/packages/server/src/services/project.ts b/packages/server/src/services/project.ts index 902dd06b..47e8ac40 100644 --- a/packages/server/src/services/project.ts +++ b/packages/server/src/services/project.ts @@ -1,4 +1,4 @@ -import { db } from "@/server/db"; +import { db } from "@dokploy/server/db"; import { type apiCreateProject, applications, @@ -8,7 +8,7 @@ import { postgres, projects, redis, -} from "@/server/db/schema"; +} from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/services/redirect.ts b/packages/server/src/services/redirect.ts index 972603f2..5a8b1aff 100644 --- a/packages/server/src/services/redirect.ts +++ b/packages/server/src/services/redirect.ts @@ -1,10 +1,10 @@ -import { db } from "@/server/db"; -import { type apiCreateRedirect, redirects } from "@/server/db/schema"; +import { db } from "@dokploy/server/db"; +import { type apiCreateRedirect, redirects } from "@dokploy/server/db/schema"; import { createRedirectMiddleware, removeRedirectMiddleware, updateRedirectMiddleware, -} from "@/server/utils/traefik/redirect"; +} from "@dokploy/server/utils/traefik/redirect"; import { TRPCError } from "@trpc/server"; import { desc, eq } from "drizzle-orm"; import type { z } from "zod"; diff --git a/packages/server/src/services/redis.ts b/packages/server/src/services/redis.ts index 9d3471a7..7809de28 100644 --- a/packages/server/src/services/redis.ts +++ b/packages/server/src/services/redis.ts @@ -1,14 +1,14 @@ -import { db } from "@/server/db"; -import { type apiCreateRedis, redis } from "@/server/db/schema"; -import { generateAppName } from "@/server/db/schema"; -import { generatePassword } from "@/server/templates/utils"; -import { buildRedis } from "@/server/utils/databases/redis"; -import { pullImage } from "@/server/utils/docker/utils"; +import { db } from "@dokploy/server/db"; +import { type apiCreateRedis, redis } from "@dokploy/server/db/schema"; +import { generateAppName } from "@dokploy/server/db/schema"; +import { generatePassword } from "@dokploy/server/templates/utils"; +import { buildRedis } from "@dokploy/server/utils/databases/redis"; +import { pullImage } from "@dokploy/server/utils/docker/utils"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; import { validUniqueServerAppName } from "./project"; -import { execAsyncRemote } from "@/server/utils/process/execAsync"; +import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync"; export type Redis = typeof redis.$inferSelect; diff --git a/packages/server/src/services/registry.ts b/packages/server/src/services/registry.ts index d0b599e1..b03c11b9 100644 --- a/packages/server/src/services/registry.ts +++ b/packages/server/src/services/registry.ts @@ -1,14 +1,12 @@ -import { db } from "@/server/db"; -import { type apiCreateRegistry, registry } from "@/server/db/schema"; -import { initializeRegistry } from "@/server/setup/registry-setup"; -import { removeService } from "@/server/utils/docker/utils"; -import { execAsync, execAsyncRemote } from "@/server/utils/process/execAsync"; +import { db } from "@dokploy/server/db"; +import { type apiCreateRegistry, registry } from "@dokploy/server/db/schema"; import { - manageRegistry, - removeSelfHostedRegistry, -} from "@/server/utils/traefik/registry"; + execAsync, + execAsyncRemote, +} from "@dokploy/server/utils/process/execAsync"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; +import { IS_CLOUD } from "../constants"; export type Registry = typeof registry.$inferSelect; @@ -32,6 +30,13 @@ export const createRegistry = async ( message: "Error input: Inserting registry", }); } + + if (IS_CLOUD && !input.serverId && input.serverId !== "none") { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Select a server to add the registry", + }); + } const loginCommand = `echo ${input.password} | docker login ${input.registryUrl} --username ${input.username} --password-stdin`; if (input.serverId && input.serverId !== "none") { await execAsyncRemote(input.serverId, loginCommand); @@ -58,13 +63,10 @@ export const removeRegistry = async (registryId: string) => { }); } - if (response.registryType === "selfHosted") { - await removeSelfHostedRegistry(); - await removeService("dokploy-registry"); + if (!IS_CLOUD) { + await execAsync(`docker logout ${response.registryUrl}`); } - await execAsync(`docker logout ${response.registryUrl}`); - return response; } catch (error) { throw new TRPCError({ @@ -89,12 +91,19 @@ export const updateRegistry = async ( .returning() .then((res) => res[0]); - if (response?.registryType === "selfHosted") { - await manageRegistry(response); - await initializeRegistry(response.username, response.password); - } const loginCommand = `echo ${response?.password} | docker login ${response?.registryUrl} --username ${response?.username} --password-stdin`; + if ( + IS_CLOUD && + !registryData?.serverId && + registryData?.serverId !== "none" + ) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Select a server to add the registry", + }); + } + if (registryData?.serverId && registryData?.serverId !== "none") { await execAsyncRemote(registryData.serverId, loginCommand); } else if (response?.registryType === "cloud") { diff --git a/packages/server/src/services/security.ts b/packages/server/src/services/security.ts index 2da78e26..40a13bb0 100644 --- a/packages/server/src/services/security.ts +++ b/packages/server/src/services/security.ts @@ -1,9 +1,9 @@ -import { db } from "@/server/db"; -import { type apiCreateSecurity, security } from "@/server/db/schema"; +import { db } from "@dokploy/server/db"; +import { type apiCreateSecurity, security } from "@dokploy/server/db/schema"; import { createSecurityMiddleware, removeSecurityMiddleware, -} from "@/server/utils/traefik/security"; +} from "@dokploy/server/utils/traefik/security"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; import type { z } from "zod"; diff --git a/packages/server/src/services/server.ts b/packages/server/src/services/server.ts index 4cd79cdc..74ba5dd1 100644 --- a/packages/server/src/services/server.ts +++ b/packages/server/src/services/server.ts @@ -1,5 +1,5 @@ -import { db } from "@/server/db"; -import { type apiCreateServer, server } from "@/server/db/schema"; +import { db } from "@dokploy/server/db"; +import { type apiCreateServer, server } from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { desc, eq } from "drizzle-orm"; diff --git a/packages/server/src/services/settings.ts b/packages/server/src/services/settings.ts index eacfd8ca..8261843a 100644 --- a/packages/server/src/services/settings.ts +++ b/packages/server/src/services/settings.ts @@ -1,8 +1,8 @@ import { readdirSync } from "node:fs"; import { join } from "node:path"; -import { docker } from "@/server/constants"; -import { getServiceContainer } from "@/server/utils/docker/utils"; -import { execAsyncRemote } from "@/server/utils/process/execAsync"; +import { docker } from "@dokploy/server/constants"; +import { getServiceContainer } from "@dokploy/server/utils/docker/utils"; +import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync"; // import packageInfo from "../../../package.json"; const updateIsAvailable = async () => { diff --git a/packages/server/src/services/ssh-key.ts b/packages/server/src/services/ssh-key.ts index f44ec22d..2bf292c7 100644 --- a/packages/server/src/services/ssh-key.ts +++ b/packages/server/src/services/ssh-key.ts @@ -1,11 +1,11 @@ -import { db } from "@/server/db"; +import { db } from "@dokploy/server/db"; import { type apiCreateSshKey, type apiFindOneSshKey, type apiRemoveSshKey, type apiUpdateSshKey, sshKeys, -} from "@/server/db/schema"; +} from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/services/user.ts b/packages/server/src/services/user.ts index 87149cd3..1cfe1260 100644 --- a/packages/server/src/services/user.ts +++ b/packages/server/src/services/user.ts @@ -1,5 +1,5 @@ -import { db } from "@/server/db"; -import { users } from "@/server/db/schema"; +import { db } from "@dokploy/server/db"; +import { users } from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; diff --git a/packages/server/src/setup/registry-setup.ts b/packages/server/src/setup/registry-setup.ts deleted file mode 100644 index 3c4cc566..00000000 --- a/packages/server/src/setup/registry-setup.ts +++ /dev/null @@ -1,91 +0,0 @@ -import type { CreateServiceOptions } from "dockerode"; -import { docker, paths } from "../constants"; -import { generatePassword } from "../templates/utils"; -import { pullImage } from "../utils/docker/utils"; -import { execAsync } from "../utils/process/execAsync"; - -export const initializeRegistry = async ( - username: string, - password: string, -) => { - const { REGISTRY_PATH } = paths(); - const imageName = "registry:2.8.3"; - const containerName = "dokploy-registry"; - await generateRegistryPassword(username, password); - const randomPass = generatePassword(); - const settings: CreateServiceOptions = { - Name: containerName, - TaskTemplate: { - ContainerSpec: { - Image: imageName, - Env: [ - "REGISTRY_STORAGE_DELETE_ENABLED=true", - "REGISTRY_AUTH=htpasswd", - "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", - "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd", - `REGISTRY_HTTP_SECRET=${randomPass}`, - ], - Mounts: [ - { - Type: "bind", - Source: `${REGISTRY_PATH}/htpasswd`, - Target: "/auth/htpasswd", - ReadOnly: true, - }, - { - Type: "volume", - Source: "registry-data", - Target: "/var/lib/registry", - ReadOnly: false, - }, - ], - }, - Networks: [{ Target: "dokploy-network" }], - Placement: { - Constraints: ["node.role==manager"], - }, - }, - Mode: { - Replicated: { - Replicas: 1, - }, - }, - EndpointSpec: { - Ports: [ - { - TargetPort: 5000, - PublishedPort: 5000, - Protocol: "tcp", - PublishMode: "host", - }, - ], - }, - }; - try { - await pullImage(imageName); - - const service = docker.getService(containerName); - const inspect = await service.inspect(); - await service.update({ - version: Number.parseInt(inspect.Version.Index), - ...settings, - }); - console.log("Registry Started ✅"); - } catch (error) { - await docker.createService(settings); - console.log("Registry Not Found: Starting ✅"); - } -}; - -const generateRegistryPassword = async (username: string, password: string) => { - try { - const { REGISTRY_PATH } = paths(); - const command = `htpasswd -nbB ${username} "${password}" > ${REGISTRY_PATH}/htpasswd`; - const result = await execAsync(command); - console.log("Password generated ✅"); - return result.stdout.trim(); - } catch (error) { - console.error("Error generating password:", error); - return null; - } -}; diff --git a/packages/server/src/setup/server-setup.ts b/packages/server/src/setup/server-setup.ts index d3f6a539..efd70a0d 100644 --- a/packages/server/src/setup/server-setup.ts +++ b/packages/server/src/setup/server-setup.ts @@ -1,15 +1,15 @@ import { createWriteStream } from "node:fs"; import path from "node:path"; -import { paths } from "@/server/constants"; +import { paths } from "@dokploy/server/constants"; import { createServerDeployment, updateDeploymentStatus, -} from "@/server/services/deployment"; -import { findServerById } from "@/server/services/server"; +} from "@dokploy/server/services/deployment"; +import { findServerById } from "@dokploy/server/services/server"; import { getDefaultMiddlewares, getDefaultServerTraefikConfig, -} from "@/server/setup/traefik-setup"; +} from "@dokploy/server/setup/traefik-setup"; import { Client } from "ssh2"; import { recreateDirectory } from "../utils/filesystem/directory"; diff --git a/packages/server/src/templates/utils/index.ts b/packages/server/src/templates/utils/index.ts index 4d8df591..c4a199de 100644 --- a/packages/server/src/templates/utils/index.ts +++ b/packages/server/src/templates/utils/index.ts @@ -1,7 +1,7 @@ import { randomBytes } from "node:crypto"; import { readFile } from "node:fs/promises"; import { join } from "node:path"; -import type { Domain } from "@/server/services/domain"; +import type { Domain } from "@dokploy/server/services/domain"; export interface Schema { serverIp: string; diff --git a/packages/server/src/types/with.ts b/packages/server/src/types/with.ts index 2bd864cc..c4826f73 100644 --- a/packages/server/src/types/with.ts +++ b/packages/server/src/types/with.ts @@ -1,4 +1,4 @@ -import type * as schema from "@/server/db/schema"; +import type * as schema from "@dokploy/server/db/schema"; import type { BuildQueryResult, DBQueryConfig, diff --git a/packages/server/src/utils/access-log/handler.ts b/packages/server/src/utils/access-log/handler.ts index db5c7f20..33c10e51 100644 --- a/packages/server/src/utils/access-log/handler.ts +++ b/packages/server/src/utils/access-log/handler.ts @@ -1,5 +1,5 @@ -import { IS_CLOUD, paths } from "@/server/constants"; -import { updateAdmin } from "@/server/services/admin"; +import { IS_CLOUD, paths } from "@dokploy/server/constants"; +import { updateAdmin } from "@dokploy/server/services/admin"; import { type RotatingFileStream, createStream } from "rotating-file-stream"; import { db } from "../../db"; import { execAsync } from "../process/execAsync"; diff --git a/packages/server/src/utils/backups/index.ts b/packages/server/src/utils/backups/index.ts index 8d0c1bf3..b1619253 100644 --- a/packages/server/src/utils/backups/index.ts +++ b/packages/server/src/utils/backups/index.ts @@ -1,5 +1,5 @@ -import { findAdmin } from "@/server/services/admin"; -import { getAllServers } from "@/server/services/server"; +import { findAdmin } from "@dokploy/server/services/admin"; +import { getAllServers } from "@dokploy/server/services/server"; import { scheduleJob } from "node-schedule"; import { db } from "../../db/index"; import { diff --git a/packages/server/src/utils/backups/mariadb.ts b/packages/server/src/utils/backups/mariadb.ts index c4ab1fe3..b8621b28 100644 --- a/packages/server/src/utils/backups/mariadb.ts +++ b/packages/server/src/utils/backups/mariadb.ts @@ -1,7 +1,7 @@ import path from "node:path"; -import type { BackupSchedule } from "@/server/services/backup"; -import type { Mariadb } from "@/server/services/mariadb"; -import { findProjectById } from "@/server/services/project"; +import type { BackupSchedule } from "@dokploy/server/services/backup"; +import type { Mariadb } from "@dokploy/server/services/mariadb"; +import { findProjectById } from "@dokploy/server/services/project"; import { getRemoteServiceContainer, getServiceContainer, diff --git a/packages/server/src/utils/backups/mongo.ts b/packages/server/src/utils/backups/mongo.ts index 95dd9005..1a30fe14 100644 --- a/packages/server/src/utils/backups/mongo.ts +++ b/packages/server/src/utils/backups/mongo.ts @@ -1,7 +1,7 @@ import path from "node:path"; -import type { BackupSchedule } from "@/server/services/backup"; -import type { Mongo } from "@/server/services/mongo"; -import { findProjectById } from "@/server/services/project"; +import type { BackupSchedule } from "@dokploy/server/services/backup"; +import type { Mongo } from "@dokploy/server/services/mongo"; +import { findProjectById } from "@dokploy/server/services/project"; import { getRemoteServiceContainer, getServiceContainer, diff --git a/packages/server/src/utils/backups/mysql.ts b/packages/server/src/utils/backups/mysql.ts index 86d503e6..ea92ee84 100644 --- a/packages/server/src/utils/backups/mysql.ts +++ b/packages/server/src/utils/backups/mysql.ts @@ -1,8 +1,8 @@ import { unlink } from "node:fs/promises"; import path from "node:path"; -import type { BackupSchedule } from "@/server/services/backup"; -import type { MySql } from "@/server/services/mysql"; -import { findProjectById } from "@/server/services/project"; +import type { BackupSchedule } from "@dokploy/server/services/backup"; +import type { MySql } from "@dokploy/server/services/mysql"; +import { findProjectById } from "@dokploy/server/services/project"; import { getRemoteServiceContainer, getServiceContainer, diff --git a/packages/server/src/utils/backups/postgres.ts b/packages/server/src/utils/backups/postgres.ts index fd2dbbc8..fe3171d6 100644 --- a/packages/server/src/utils/backups/postgres.ts +++ b/packages/server/src/utils/backups/postgres.ts @@ -1,7 +1,7 @@ import path from "node:path"; -import type { BackupSchedule } from "@/server/services/backup"; -import type { Postgres } from "@/server/services/postgres"; -import { findProjectById } from "@/server/services/project"; +import type { BackupSchedule } from "@dokploy/server/services/backup"; +import type { Postgres } from "@dokploy/server/services/postgres"; +import { findProjectById } from "@dokploy/server/services/project"; import { getRemoteServiceContainer, getServiceContainer, diff --git a/packages/server/src/utils/backups/utils.ts b/packages/server/src/utils/backups/utils.ts index 8ecddd60..b9656ff2 100644 --- a/packages/server/src/utils/backups/utils.ts +++ b/packages/server/src/utils/backups/utils.ts @@ -1,5 +1,5 @@ -import type { BackupSchedule } from "@/server/services/backup"; -import type { Destination } from "@/server/services/destination"; +import type { BackupSchedule } from "@dokploy/server/services/backup"; +import type { Destination } from "@dokploy/server/services/destination"; import { scheduleJob, scheduledJobs } from "node-schedule"; import { runMariadbBackup } from "./mariadb"; import { runMongoBackup } from "./mongo"; diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index 47ec1520..7d3ce0ec 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -5,8 +5,8 @@ import { writeFileSync, } from "node:fs"; import { dirname, join } from "node:path"; -import { paths } from "@/server/constants"; -import type { InferResultType } from "@/server/types/with"; +import { paths } from "@dokploy/server/constants"; +import type { InferResultType } from "@dokploy/server/types/with"; import boxen from "boxen"; import { writeDomainsToCompose, diff --git a/packages/server/src/utils/builders/docker-file.ts b/packages/server/src/utils/builders/docker-file.ts index 0ee2f4b1..f8d4a929 100644 --- a/packages/server/src/utils/builders/docker-file.ts +++ b/packages/server/src/utils/builders/docker-file.ts @@ -1,5 +1,5 @@ import type { WriteStream } from "node:fs"; -import { prepareEnvironmentVariables } from "@/server/utils/docker/utils"; +import { prepareEnvironmentVariables } from "@dokploy/server/utils/docker/utils"; import type { ApplicationNested } from "."; import { getBuildAppDirectory, diff --git a/packages/server/src/utils/builders/drop.ts b/packages/server/src/utils/builders/drop.ts index 14307886..420cd7aa 100644 --- a/packages/server/src/utils/builders/drop.ts +++ b/packages/server/src/utils/builders/drop.ts @@ -1,8 +1,8 @@ import fs from "node:fs/promises"; import path, { join } from "node:path"; -import { paths } from "@/server/constants"; -import type { Application } from "@/server/services/application"; -import { findServerById } from "@/server/services/server"; +import { paths } from "@dokploy/server/constants"; +import type { Application } from "@dokploy/server/services/application"; +import { findServerById } from "@dokploy/server/services/server"; import AdmZip from "adm-zip"; import { Client, type SFTPWrapper } from "ssh2"; import { diff --git a/packages/server/src/utils/builders/index.ts b/packages/server/src/utils/builders/index.ts index 4f7262a8..cf155e45 100644 --- a/packages/server/src/utils/builders/index.ts +++ b/packages/server/src/utils/builders/index.ts @@ -1,5 +1,5 @@ import { createWriteStream } from "node:fs"; -import type { InferResultType } from "@/server/types/with"; +import type { InferResultType } from "@dokploy/server/types/with"; import type { CreateServiceOptions } from "dockerode"; import { uploadImage } from "../cluster/upload"; import { diff --git a/packages/server/src/utils/builders/nixpacks.ts b/packages/server/src/utils/builders/nixpacks.ts index bcc670d0..81e6f061 100644 --- a/packages/server/src/utils/builders/nixpacks.ts +++ b/packages/server/src/utils/builders/nixpacks.ts @@ -1,6 +1,9 @@ import { type WriteStream, existsSync, mkdirSync } from "node:fs"; import path from "node:path"; -import { buildStatic, getStaticCommand } from "@/server/utils/builders/static"; +import { + buildStatic, + getStaticCommand, +} from "@dokploy/server/utils/builders/static"; import { nanoid } from "nanoid"; import type { ApplicationNested } from "."; import { prepareEnvironmentVariables } from "../docker/utils"; diff --git a/packages/server/src/utils/builders/static.ts b/packages/server/src/utils/builders/static.ts index 2f3d4bc2..c46bdf2e 100644 --- a/packages/server/src/utils/builders/static.ts +++ b/packages/server/src/utils/builders/static.ts @@ -2,7 +2,7 @@ import type { WriteStream } from "node:fs"; import { buildCustomDocker, getDockerCommand, -} from "@/server/utils/builders/docker-file"; +} from "@dokploy/server/utils/builders/docker-file"; import type { ApplicationNested } from "."; import { createFile, getCreateFileCommand } from "../docker/utils"; import { getBuildAppDirectory } from "../filesystem/directory"; diff --git a/packages/server/src/utils/databases/mariadb.ts b/packages/server/src/utils/databases/mariadb.ts index 9465d47e..ab9a32a8 100644 --- a/packages/server/src/utils/databases/mariadb.ts +++ b/packages/server/src/utils/databases/mariadb.ts @@ -1,4 +1,4 @@ -import type { InferResultType } from "@/server/types/with"; +import type { InferResultType } from "@dokploy/server/types/with"; import type { CreateServiceOptions } from "dockerode"; import { calculateResources, diff --git a/packages/server/src/utils/databases/mongo.ts b/packages/server/src/utils/databases/mongo.ts index 6b02da86..352f7810 100644 --- a/packages/server/src/utils/databases/mongo.ts +++ b/packages/server/src/utils/databases/mongo.ts @@ -1,4 +1,4 @@ -import type { InferResultType } from "@/server/types/with"; +import type { InferResultType } from "@dokploy/server/types/with"; import type { CreateServiceOptions } from "dockerode"; import { calculateResources, diff --git a/packages/server/src/utils/databases/mysql.ts b/packages/server/src/utils/databases/mysql.ts index 3ad266b7..af625d20 100644 --- a/packages/server/src/utils/databases/mysql.ts +++ b/packages/server/src/utils/databases/mysql.ts @@ -1,4 +1,4 @@ -import type { InferResultType } from "@/server/types/with"; +import type { InferResultType } from "@dokploy/server/types/with"; import type { CreateServiceOptions } from "dockerode"; import { calculateResources, diff --git a/packages/server/src/utils/databases/postgres.ts b/packages/server/src/utils/databases/postgres.ts index f7984fbe..873ad4a5 100644 --- a/packages/server/src/utils/databases/postgres.ts +++ b/packages/server/src/utils/databases/postgres.ts @@ -1,4 +1,4 @@ -import type { InferResultType } from "@/server/types/with"; +import type { InferResultType } from "@dokploy/server/types/with"; import type { CreateServiceOptions } from "dockerode"; import { calculateResources, diff --git a/packages/server/src/utils/databases/redis.ts b/packages/server/src/utils/databases/redis.ts index 62d972a7..fc07bc01 100644 --- a/packages/server/src/utils/databases/redis.ts +++ b/packages/server/src/utils/databases/redis.ts @@ -1,4 +1,4 @@ -import type { InferResultType } from "@/server/types/with"; +import type { InferResultType } from "@dokploy/server/types/with"; import type { CreateServiceOptions } from "dockerode"; import { calculateResources, diff --git a/packages/server/src/utils/docker/compose.ts b/packages/server/src/utils/docker/compose.ts index 0a47c7d2..2cb909ab 100644 --- a/packages/server/src/utils/docker/compose.ts +++ b/packages/server/src/utils/docker/compose.ts @@ -1,5 +1,5 @@ import crypto from "node:crypto"; -import { findComposeById } from "@/server/services/compose"; +import { findComposeById } from "@dokploy/server/services/compose"; import { dump, load } from "js-yaml"; import { addSuffixToAllConfigs } from "./compose/configs"; import { addSuffixToAllNetworks } from "./compose/network"; diff --git a/packages/server/src/utils/docker/domain.ts b/packages/server/src/utils/docker/domain.ts index a2d1e617..28ede308 100644 --- a/packages/server/src/utils/docker/domain.ts +++ b/packages/server/src/utils/docker/domain.ts @@ -1,9 +1,9 @@ import fs, { existsSync, readFileSync } from "node:fs"; import { writeFile } from "node:fs/promises"; import { join } from "node:path"; -import { paths } from "@/server/constants"; -import type { Compose } from "@/server/services/compose"; -import type { Domain } from "@/server/services/domain"; +import { paths } from "@dokploy/server/constants"; +import type { Compose } from "@dokploy/server/services/compose"; +import type { Domain } from "@dokploy/server/services/domain"; import { dump, load } from "js-yaml"; import { execAsyncRemote } from "../process/execAsync"; import { diff --git a/packages/server/src/utils/docker/utils.ts b/packages/server/src/utils/docker/utils.ts index 3dcc27ac..60793d15 100644 --- a/packages/server/src/utils/docker/utils.ts +++ b/packages/server/src/utils/docker/utils.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import path from "node:path"; import type { Readable } from "node:stream"; -import { docker, paths } from "@/server/constants"; +import { docker, paths } from "@dokploy/server/constants"; import type { ContainerInfo, ResourceRequirements } from "dockerode"; import { parse } from "dotenv"; import type { ApplicationNested } from "../builders"; diff --git a/packages/server/src/utils/filesystem/directory.ts b/packages/server/src/utils/filesystem/directory.ts index 017c74e0..0a28cbac 100644 --- a/packages/server/src/utils/filesystem/directory.ts +++ b/packages/server/src/utils/filesystem/directory.ts @@ -1,7 +1,7 @@ import fs, { promises as fsPromises } from "node:fs"; import path from "node:path"; -import { paths } from "@/server/constants"; -import type { Application } from "@/server/services/application"; +import { paths } from "@dokploy/server/constants"; +import type { Application } from "@dokploy/server/services/application"; import { execAsync, execAsyncRemote } from "../process/execAsync"; export const recreateDirectory = async (pathFolder: string): Promise => { diff --git a/packages/server/src/utils/notifications/build-error.ts b/packages/server/src/utils/notifications/build-error.ts index f1a7f3fe..703367ec 100644 --- a/packages/server/src/utils/notifications/build-error.ts +++ b/packages/server/src/utils/notifications/build-error.ts @@ -1,6 +1,6 @@ -import { db } from "@/server/db"; -import { notifications } from "@/server/db/schema"; -import BuildFailedEmail from "@/server/emails/emails/build-failed"; +import { db } from "@dokploy/server/db"; +import { notifications } from "@dokploy/server/db/schema"; +import BuildFailedEmail from "@dokploy/server/emails/emails/build-failed"; import { renderAsync } from "@react-email/components"; import { eq } from "drizzle-orm"; import { diff --git a/packages/server/src/utils/notifications/build-success.ts b/packages/server/src/utils/notifications/build-success.ts index 4bc21086..55cbb33d 100644 --- a/packages/server/src/utils/notifications/build-success.ts +++ b/packages/server/src/utils/notifications/build-success.ts @@ -1,6 +1,6 @@ -import { db } from "@/server/db"; -import { notifications } from "@/server/db/schema"; -import BuildSuccessEmail from "@/server/emails/emails/build-success"; +import { db } from "@dokploy/server/db"; +import { notifications } from "@dokploy/server/db/schema"; +import BuildSuccessEmail from "@dokploy/server/emails/emails/build-success"; import { renderAsync } from "@react-email/components"; import { eq } from "drizzle-orm"; import { diff --git a/packages/server/src/utils/notifications/database-backup.ts b/packages/server/src/utils/notifications/database-backup.ts index f631e224..1b2a6909 100644 --- a/packages/server/src/utils/notifications/database-backup.ts +++ b/packages/server/src/utils/notifications/database-backup.ts @@ -1,6 +1,6 @@ -import { db } from "@/server/db"; -import { notifications } from "@/server/db/schema"; -import DatabaseBackupEmail from "@/server/emails/emails/database-backup"; +import { db } from "@dokploy/server/db"; +import { notifications } from "@dokploy/server/db/schema"; +import DatabaseBackupEmail from "@dokploy/server/emails/emails/database-backup"; import { renderAsync } from "@react-email/components"; import { eq } from "drizzle-orm"; import { diff --git a/packages/server/src/utils/notifications/docker-cleanup.ts b/packages/server/src/utils/notifications/docker-cleanup.ts index 6f0f4a6e..a42657bc 100644 --- a/packages/server/src/utils/notifications/docker-cleanup.ts +++ b/packages/server/src/utils/notifications/docker-cleanup.ts @@ -1,6 +1,6 @@ -import { db } from "@/server/db"; -import { notifications } from "@/server/db/schema"; -import DockerCleanupEmail from "@/server/emails/emails/docker-cleanup"; +import { db } from "@dokploy/server/db"; +import { notifications } from "@dokploy/server/db/schema"; +import DockerCleanupEmail from "@dokploy/server/emails/emails/docker-cleanup"; import { renderAsync } from "@react-email/components"; import { eq } from "drizzle-orm"; import { diff --git a/packages/server/src/utils/notifications/dokploy-restart.ts b/packages/server/src/utils/notifications/dokploy-restart.ts index cd986d55..33bc32f0 100644 --- a/packages/server/src/utils/notifications/dokploy-restart.ts +++ b/packages/server/src/utils/notifications/dokploy-restart.ts @@ -1,6 +1,6 @@ -import { db } from "@/server/db"; -import { notifications } from "@/server/db/schema"; -import DokployRestartEmail from "@/server/emails/emails/dokploy-restart"; +import { db } from "@dokploy/server/db"; +import { notifications } from "@dokploy/server/db/schema"; +import DokployRestartEmail from "@dokploy/server/emails/emails/dokploy-restart"; import { renderAsync } from "@react-email/components"; import { eq } from "drizzle-orm"; import { diff --git a/packages/server/src/utils/notifications/utils.ts b/packages/server/src/utils/notifications/utils.ts index 56cb08fd..8327c33d 100644 --- a/packages/server/src/utils/notifications/utils.ts +++ b/packages/server/src/utils/notifications/utils.ts @@ -1,4 +1,9 @@ -import type { discord, email, slack, telegram } from "@/server/db/schema"; +import type { + discord, + email, + slack, + telegram, +} from "@dokploy/server/db/schema"; import nodemailer from "nodemailer"; export const sendEmailNotification = async ( diff --git a/packages/server/src/utils/process/execAsync.ts b/packages/server/src/utils/process/execAsync.ts index 5711bcb2..0bd8f588 100644 --- a/packages/server/src/utils/process/execAsync.ts +++ b/packages/server/src/utils/process/execAsync.ts @@ -1,6 +1,6 @@ import { exec } from "node:child_process"; import util from "node:util"; -import { findServerById } from "@/server/services/server"; +import { findServerById } from "@dokploy/server/services/server"; import { Client } from "ssh2"; export const execAsync = util.promisify(exec); diff --git a/packages/server/src/utils/providers/bitbucket.ts b/packages/server/src/utils/providers/bitbucket.ts index bcf6ca6d..ff5c4b60 100644 --- a/packages/server/src/utils/providers/bitbucket.ts +++ b/packages/server/src/utils/providers/bitbucket.ts @@ -1,13 +1,13 @@ import { createWriteStream } from "node:fs"; import { join } from "node:path"; -import { paths } from "@/server/constants"; +import { paths } from "@dokploy/server/constants"; import type { apiBitbucketTestConnection, apiFindBitbucketBranches, -} from "@/server/db/schema"; -import { findBitbucketById } from "@/server/services/bitbucket"; -import type { Compose } from "@/server/services/compose"; -import type { InferResultType } from "@/server/types/with"; +} from "@dokploy/server/db/schema"; +import { findBitbucketById } from "@dokploy/server/services/bitbucket"; +import type { Compose } from "@dokploy/server/services/compose"; +import type { InferResultType } from "@dokploy/server/types/with"; import { TRPCError } from "@trpc/server"; import { recreateDirectory } from "../filesystem/directory"; import { execAsyncRemote } from "../process/execAsync"; diff --git a/packages/server/src/utils/providers/git.ts b/packages/server/src/utils/providers/git.ts index 8622879f..6d2e34ed 100644 --- a/packages/server/src/utils/providers/git.ts +++ b/packages/server/src/utils/providers/git.ts @@ -1,8 +1,11 @@ import { createWriteStream } from "node:fs"; import path, { join } from "node:path"; -import { paths } from "@/server/constants"; -import type { Compose } from "@/server/services/compose"; -import { findSSHKeyById, updateSSHKeyById } from "@/server/services/ssh-key"; +import { paths } from "@dokploy/server/constants"; +import type { Compose } from "@dokploy/server/services/compose"; +import { + findSSHKeyById, + updateSSHKeyById, +} from "@dokploy/server/services/ssh-key"; import { TRPCError } from "@trpc/server"; import { recreateDirectory } from "../filesystem/directory"; import { execAsync, execAsyncRemote } from "../process/execAsync"; @@ -55,8 +58,6 @@ export const cloneGitRepository = async ( await addHostToKnownHosts(customGitUrl); } await recreateDirectory(outputPath); - // const command = `GIT_SSH_COMMAND="ssh -i ${keyPath} -o UserKnownHostsFile=${knownHostsPath}" git clone --branch ${customGitBranch} --depth 1 ${customGitUrl} ${gitCopyPath} --progress`; - // const { stdout, stderr } = await execAsync(command); writeStream.write( `\nCloning Repo Custom ${customGitUrl} to ${outputPath}: ✅\n`, ); diff --git a/packages/server/src/utils/providers/github.ts b/packages/server/src/utils/providers/github.ts index 9062df85..61d5d30c 100644 --- a/packages/server/src/utils/providers/github.ts +++ b/packages/server/src/utils/providers/github.ts @@ -1,16 +1,16 @@ import { createWriteStream } from "node:fs"; import { join } from "node:path"; -import { paths } from "@/server/constants"; -import type { InferResultType } from "@/server/types/with"; +import { paths } from "@dokploy/server/constants"; +import type { InferResultType } from "@dokploy/server/types/with"; import { createAppAuth } from "@octokit/auth-app"; import { TRPCError } from "@trpc/server"; import { Octokit } from "octokit"; import { recreateDirectory } from "../filesystem/directory"; import { spawnAsync } from "../process/spawnAsync"; -import type { apiFindGithubBranches } from "@/server/db/schema"; -import type { Compose } from "@/server/services/compose"; -import { type Github, findGithubById } from "@/server/services/github"; +import type { apiFindGithubBranches } from "@dokploy/server/db/schema"; +import type { Compose } from "@dokploy/server/services/compose"; +import { type Github, findGithubById } from "@dokploy/server/services/github"; import { execAsyncRemote } from "../process/execAsync"; export const authGithub = (githubProvider: Github): Octokit => { diff --git a/packages/server/src/utils/providers/gitlab.ts b/packages/server/src/utils/providers/gitlab.ts index 34036167..38845af5 100644 --- a/packages/server/src/utils/providers/gitlab.ts +++ b/packages/server/src/utils/providers/gitlab.ts @@ -1,14 +1,14 @@ import { createWriteStream } from "node:fs"; import { join } from "node:path"; -import { paths } from "@/server/constants"; -import type { apiGitlabTestConnection } from "@/server/db/schema"; -import type { Compose } from "@/server/services/compose"; +import { paths } from "@dokploy/server/constants"; +import type { apiGitlabTestConnection } from "@dokploy/server/db/schema"; +import type { Compose } from "@dokploy/server/services/compose"; import { type Gitlab, findGitlabById, updateGitlab, -} from "@/server/services/gitlab"; -import type { InferResultType } from "@/server/types/with"; +} from "@dokploy/server/services/gitlab"; +import type { InferResultType } from "@dokploy/server/types/with"; import { TRPCError } from "@trpc/server"; import { recreateDirectory } from "../filesystem/directory"; import { execAsyncRemote } from "../process/execAsync"; diff --git a/packages/server/src/utils/providers/raw.ts b/packages/server/src/utils/providers/raw.ts index bf7c858b..34ba0012 100644 --- a/packages/server/src/utils/providers/raw.ts +++ b/packages/server/src/utils/providers/raw.ts @@ -1,8 +1,8 @@ import { createWriteStream } from "node:fs"; import { writeFile } from "node:fs/promises"; import { join } from "node:path"; -import { paths } from "@/server/constants"; -import type { Compose } from "@/server/services/compose"; +import { paths } from "@dokploy/server/constants"; +import type { Compose } from "@dokploy/server/services/compose"; import { encodeBase64 } from "../docker/utils"; import { recreateDirectory } from "../filesystem/directory"; import { execAsyncRemote } from "../process/execAsync"; diff --git a/packages/server/src/utils/servers/remote-docker.ts b/packages/server/src/utils/servers/remote-docker.ts index c129df83..27bad561 100644 --- a/packages/server/src/utils/servers/remote-docker.ts +++ b/packages/server/src/utils/servers/remote-docker.ts @@ -1,5 +1,5 @@ -import { docker } from "@/server/constants"; -import { findServerById } from "@/server/services/server"; +import { docker } from "@dokploy/server/constants"; +import { findServerById } from "@dokploy/server/services/server"; import Dockerode from "dockerode"; export const getRemoteDocker = async (serverId?: string | null) => { diff --git a/packages/server/src/utils/traefik/application.ts b/packages/server/src/utils/traefik/application.ts index 66c51cbf..4434d858 100644 --- a/packages/server/src/utils/traefik/application.ts +++ b/packages/server/src/utils/traefik/application.ts @@ -1,7 +1,7 @@ import fs, { writeFileSync } from "node:fs"; import path from "node:path"; -import { paths } from "@/server/constants"; -import type { Domain } from "@/server/services/domain"; +import { paths } from "@dokploy/server/constants"; +import type { Domain } from "@dokploy/server/services/domain"; import { dump, load } from "js-yaml"; import { encodeBase64 } from "../docker/utils"; import { execAsyncRemote } from "../process/execAsync"; diff --git a/packages/server/src/utils/traefik/domain.ts b/packages/server/src/utils/traefik/domain.ts index e0a865e7..a6c878e7 100644 --- a/packages/server/src/utils/traefik/domain.ts +++ b/packages/server/src/utils/traefik/domain.ts @@ -1,4 +1,4 @@ -import type { Domain } from "@/server/services/domain"; +import type { Domain } from "@dokploy/server/services/domain"; import type { ApplicationNested } from "../builders"; import { createServiceConfig, diff --git a/packages/server/src/utils/traefik/middleware.ts b/packages/server/src/utils/traefik/middleware.ts index df836051..60345f66 100644 --- a/packages/server/src/utils/traefik/middleware.ts +++ b/packages/server/src/utils/traefik/middleware.ts @@ -1,6 +1,6 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs"; import { join } from "node:path"; -import { paths } from "@/server/constants"; +import { paths } from "@dokploy/server/constants"; import { dump, load } from "js-yaml"; import type { ApplicationNested } from "../builders"; import { execAsyncRemote } from "../process/execAsync"; diff --git a/packages/server/src/utils/traefik/redirect.ts b/packages/server/src/utils/traefik/redirect.ts index 604dadc2..e9b5a94a 100644 --- a/packages/server/src/utils/traefik/redirect.ts +++ b/packages/server/src/utils/traefik/redirect.ts @@ -1,4 +1,4 @@ -import type { Redirect } from "@/server/services/redirect"; +import type { Redirect } from "@dokploy/server/services/redirect"; import type { ApplicationNested } from "../builders"; import { loadOrCreateConfig, diff --git a/packages/server/src/utils/traefik/registry.ts b/packages/server/src/utils/traefik/registry.ts deleted file mode 100644 index e857dd2d..00000000 --- a/packages/server/src/utils/traefik/registry.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; -import { join } from "node:path"; -import { paths } from "@/server/constants"; -import type { Registry } from "@/server/services/registry"; -import { dump, load } from "js-yaml"; -import { removeDirectoryIfExistsContent } from "../filesystem/directory"; -import type { FileConfig, HttpRouter } from "./file-types"; - -export const manageRegistry = async (registry: Registry) => { - const { REGISTRY_PATH } = paths(); - if (!existsSync(REGISTRY_PATH)) { - mkdirSync(REGISTRY_PATH, { recursive: true }); - } - - const appName = "dokploy-registry"; - const config: FileConfig = loadOrCreateConfig(); - - const serviceName = `${appName}-service`; - const routerName = `${appName}-router`; - - config.http = config.http || { routers: {}, services: {} }; - config.http.routers = config.http.routers || {}; - config.http.services = config.http.services || {}; - - config.http.routers[routerName] = await createRegistryRouterConfig(registry); - - config.http.services[serviceName] = { - loadBalancer: { - servers: [{ url: `http://${appName}:5000` }], - passHostHeader: true, - }, - }; - - const yamlConfig = dump(config); - const configFile = join(REGISTRY_PATH, "registry.yml"); - writeFileSync(configFile, yamlConfig); -}; - -export const removeSelfHostedRegistry = async () => { - const { REGISTRY_PATH } = paths(); - await removeDirectoryIfExistsContent(REGISTRY_PATH); -}; - -const createRegistryRouterConfig = async (registry: Registry) => { - const { registryUrl } = registry; - const routerConfig: HttpRouter = { - rule: `Host(\`${registryUrl}\`)`, - service: "dokploy-registry-service", - middlewares: ["redirect-to-https"], - entryPoints: [ - "web", - ...(process.env.NODE_ENV === "production" ? ["websecure"] : []), - ], - ...(process.env.NODE_ENV === "production" - ? { - tls: { certResolver: "letsencrypt" }, - } - : {}), - }; - - return routerConfig; -}; - -const loadOrCreateConfig = (): FileConfig => { - const { REGISTRY_PATH } = paths(); - const configPath = join(REGISTRY_PATH, "registry.yml"); - if (existsSync(configPath)) { - const yamlStr = readFileSync(configPath, "utf8"); - const parsedConfig = (load(yamlStr) as FileConfig) || { - http: { routers: {}, services: {} }, - }; - return parsedConfig; - } - return { http: { routers: {}, services: {} } }; -}; diff --git a/packages/server/src/utils/traefik/security.ts b/packages/server/src/utils/traefik/security.ts index ae0ff876..2ded8235 100644 --- a/packages/server/src/utils/traefik/security.ts +++ b/packages/server/src/utils/traefik/security.ts @@ -1,4 +1,4 @@ -import type { Security } from "@/server/services/security"; +import type { Security } from "@dokploy/server/services/security"; import * as bcrypt from "bcrypt"; import type { ApplicationNested } from "../builders"; import { diff --git a/packages/server/src/utils/traefik/web-server.ts b/packages/server/src/utils/traefik/web-server.ts index cd8f8d1a..0aa4d35d 100644 --- a/packages/server/src/utils/traefik/web-server.ts +++ b/packages/server/src/utils/traefik/web-server.ts @@ -1,7 +1,7 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs"; import { join } from "node:path"; -import { paths } from "@/server/constants"; -import type { Admin } from "@/server/services/admin"; +import { paths } from "@dokploy/server/constants"; +import type { Admin } from "@dokploy/server/services/admin"; import { dump, load } from "js-yaml"; import { loadOrCreateConfig, writeTraefikConfig } from "./application"; import type { FileConfig } from "./file-types"; diff --git a/packages/server/src/wss/docker-container-logs.ts b/packages/server/src/wss/docker-container-logs.ts index e01e82a7..e800fee9 100644 --- a/packages/server/src/wss/docker-container-logs.ts +++ b/packages/server/src/wss/docker-container-logs.ts @@ -1,5 +1,5 @@ import type http from "node:http"; -import { findServerById } from "@/server/services/server"; +import { findServerById } from "@dokploy/server/services/server"; import { spawn } from "node-pty"; import { Client } from "ssh2"; import { WebSocketServer } from "ws"; diff --git a/packages/server/src/wss/docker-container-terminal.ts b/packages/server/src/wss/docker-container-terminal.ts index 0a944df5..8b5b034e 100644 --- a/packages/server/src/wss/docker-container-terminal.ts +++ b/packages/server/src/wss/docker-container-terminal.ts @@ -1,5 +1,5 @@ import type http from "node:http"; -import { findServerById } from "@/server/services/server"; +import { findServerById } from "@dokploy/server/services/server"; import { spawn } from "node-pty"; import { Client } from "ssh2"; import { WebSocketServer } from "ws"; diff --git a/packages/server/src/wss/listen-deployment.ts b/packages/server/src/wss/listen-deployment.ts index 0ff633b5..d72c528b 100644 --- a/packages/server/src/wss/listen-deployment.ts +++ b/packages/server/src/wss/listen-deployment.ts @@ -1,6 +1,6 @@ import { spawn } from "node:child_process"; import type http from "node:http"; -import { findServerById } from "@/server/services/server"; +import { findServerById } from "@dokploy/server/services/server"; import { Client } from "ssh2"; import { WebSocketServer } from "ws"; import { validateWebSocketRequest } from "../auth/auth"; diff --git a/packages/server/src/wss/terminal.ts b/packages/server/src/wss/terminal.ts index 019efd43..562040d7 100644 --- a/packages/server/src/wss/terminal.ts +++ b/packages/server/src/wss/terminal.ts @@ -1,6 +1,6 @@ import type http from "node:http"; import path from "node:path"; -import { findServerById } from "@/server/services/server"; +import { findServerById } from "@dokploy/server/services/server"; import { spawn } from "node-pty"; import { publicIpv4, publicIpv6 } from "public-ip"; import { WebSocketServer } from "ws"; diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index 1f75de81..0eb9923a 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -12,7 +12,6 @@ "strict": true, "noUncheckedIndexedAccess": true, "checkJs": true, - /* Bundled projects */ "lib": ["dom", "dom.iterable", "ES2022"], "noEmit": true, @@ -20,16 +19,15 @@ "moduleResolution": "Bundler", "jsx": "preserve", "plugins": [{ "name": "next" }], - "incremental": true, "outDir": "./dist", /* Path Aliases */ "baseUrl": ".", "paths": { - "@/server/*": ["./src/*"] + "@dokploy/server/*": ["./src/*"] } }, - "include": ["next-env.d.ts", "./src/**/*.ts"], + "exclude": [ "tsup.ts", "node_modules", diff --git a/packages/server/tsconfig.server.json b/packages/server/tsconfig.server.json index 0de10162..7f349eb8 100644 --- a/packages/server/tsconfig.server.json +++ b/packages/server/tsconfig.server.json @@ -10,10 +10,9 @@ "moduleResolution": "Node", "rootDir": "./src", "baseUrl": ".", - "incremental": false, "jsx": "react-jsx", "paths": { - "@/server/*": ["src/*"] + "@dokploy/server/*": ["./src/*"] } }, "include": ["next-env.d.ts", "./src/**/*"], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11189f2f..d78af3e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -227,6 +227,9 @@ importers: '@radix-ui/react-tooltip': specifier: ^1.0.7 version: 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@stripe/stripe-js': + specifier: 4.8.0 + version: 4.8.0 '@tanstack/react-query': specifier: ^4.36.1 version: 4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -238,7 +241,7 @@ importers: version: 10.45.2(@trpc/server@10.45.2) '@trpc/next': specifier: ^10.43.6 - version: 10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@14.2.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@trpc/react-query': specifier: ^10.43.6 version: 10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -312,11 +315,11 @@ importers: specifier: '3' version: 3.3.7 next: - specifier: ^14.1.3 - version: 14.2.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^15.0.1 + version: 15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.2.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 0.2.1(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) node-pty: specifier: 1.0.0 version: 1.0.0 @@ -353,6 +356,9 @@ importers: ssh2: specifier: 1.15.0 version: 1.15.0 + stripe: + specifier: 17.2.0 + version: 17.2.0 superjson: specifier: ^2.2.1 version: 2.2.1 @@ -523,6 +529,9 @@ importers: '@radix-ui/react-switch': specifier: ^1.0.3 version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-tabs': + specifier: 1.1.1 + version: 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@types/node': specifier: 20.4.6 version: 20.4.6 @@ -747,6 +756,9 @@ importers: esbuild: specifier: 0.20.2 version: 0.20.2 + esbuild-plugin-alias: + specifier: 0.2.1 + version: 0.2.1 postcss: specifier: ^8.4.31 version: 8.4.40 @@ -1024,6 +1036,9 @@ packages: '@emnapi/runtime@0.45.0': resolution: {integrity: sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==} + '@emnapi/runtime@1.3.1': + resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + '@esbuild-kit/core-utils@3.3.2': resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} @@ -1672,6 +1687,111 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@ioredis/commands@1.2.0': resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} @@ -1799,6 +1919,9 @@ packages: '@next/env@14.2.5': resolution: {integrity: sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==} + '@next/env@15.0.1': + resolution: {integrity: sha512-lc4HeDUKO9gxxlM5G2knTRifqhsY6yYpwuHspBZdboZe0Gp+rZHBNNSIjmQKDJIdRXiXGyVnSD6gafrbQPvILQ==} + '@next/eslint-plugin-next@13.4.16': resolution: {integrity: sha512-QuFtQl+oSEEQb0HMYBdvBoUaTiMxbY3go/MFkF3zOnfY0t84+IbAX78cw8ZCfr6cA6UcTq3nMIlCrHwDC/moxg==} @@ -1814,6 +1937,12 @@ packages: cpu: [arm64] os: [darwin] + '@next/swc-darwin-arm64@15.0.1': + resolution: {integrity: sha512-C9k/Xv4sxkQRTA37Z6MzNq3Yb1BJMmSqjmwowoWEpbXTkAdfOwnoKOpAb71ItSzoA26yUTIo6ZhN8rKGu4ExQw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + '@next/swc-darwin-x64@14.2.2': resolution: {integrity: sha512-x7Afi/jt0ZBRUZHTi49yyej4o8znfIMHO4RvThuoc0P+uli8Jd99y5GKjxoYunPKsXL09xBXEM1+OQy2xEL0Ag==} engines: {node: '>= 10'} @@ -1826,6 +1955,12 @@ packages: cpu: [x64] os: [darwin] + '@next/swc-darwin-x64@15.0.1': + resolution: {integrity: sha512-uHl13HXOuq1G7ovWFxCACDJHTSDVbn/sbLv8V1p+7KIvTrYQ5HNoSmKBdYeEKRRCbEmd+OohOgg9YOp8Ux3MBg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + '@next/swc-linux-arm64-gnu@14.2.2': resolution: {integrity: sha512-zbfPtkk7L41ODMJwSp5VbmPozPmMMQrzAc0HAUomVeVIIwlDGs/UCqLJvLNDt4jpWgc21SjjyIn762lNGrMaUA==} engines: {node: '>= 10'} @@ -1838,6 +1973,12 @@ packages: cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-gnu@15.0.1': + resolution: {integrity: sha512-LvyhvxHOihFTEIbb35KxOc3q8w8G4xAAAH/AQnsYDEnOvwawjL2eawsB59AX02ki6LJdgDaHoTEnC54Gw+82xw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-arm64-musl@14.2.2': resolution: {integrity: sha512-wPbS3pI/JU16rm3XdLvvTmlsmm1nd+sBa2ohXgBZcShX4TgOjD4R+RqHKlI1cjo/jDZKXt6OxmcU0Iys0OC/yg==} engines: {node: '>= 10'} @@ -1850,6 +1991,12 @@ packages: cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-musl@15.0.1': + resolution: {integrity: sha512-vFmCGUFNyk/A5/BYcQNhAQqPIw01RJaK6dRO+ZEhz0DncoW+hJW1kZ8aH2UvTX27zPq3m85zN5waMSbZEmANcQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-x64-gnu@14.2.2': resolution: {integrity: sha512-NqWOHqqq8iC9tuHvZxjQ2tX+jWy2X9y8NX2mcB4sj2bIccuCxbIZrU/ThFPZZPauygajZuVQ6zediejQHwZHwQ==} engines: {node: '>= 10'} @@ -1862,6 +2009,12 @@ packages: cpu: [x64] os: [linux] + '@next/swc-linux-x64-gnu@15.0.1': + resolution: {integrity: sha512-5by7IYq0NCF8rouz6Qg9T97jYU68kaClHPfGpQG2lCZpSYHtSPQF1kjnqBTd34RIqPKMbCa4DqCufirgr8HM5w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-linux-x64-musl@14.2.2': resolution: {integrity: sha512-lGepHhwb9sGhCcU7999+iK1ZZT+6rrIoVg40MP7DZski9GIZP80wORSbt5kJzh9v2x2ev2lxC6VgwMQT0PcgTA==} engines: {node: '>= 10'} @@ -1874,6 +2027,12 @@ packages: cpu: [x64] os: [linux] + '@next/swc-linux-x64-musl@15.0.1': + resolution: {integrity: sha512-lmYr6H3JyDNBJLzklGXLfbehU3ay78a+b6UmBGlHls4xhDXBNZfgb0aI67sflrX+cGBnv1LgmWzFlYrAYxS1Qw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-win32-arm64-msvc@14.2.2': resolution: {integrity: sha512-TZSh/48SfcLEQ4rD25VVn2kdIgUWmMflRX3OiyPwGNXn3NiyPqhqei/BaqCYXViIQ+6QsG9R0C8LftMqy8JPMA==} engines: {node: '>= 10'} @@ -1886,6 +2045,12 @@ packages: cpu: [arm64] os: [win32] + '@next/swc-win32-arm64-msvc@15.0.1': + resolution: {integrity: sha512-DS8wQtl6diAj0eZTdH0sefykm4iXMbHT4MOvLwqZiIkeezKpkgPFcEdFlz3vKvXa2R/2UEgMh48z1nEpNhjeOQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + '@next/swc-win32-ia32-msvc@14.2.2': resolution: {integrity: sha512-M0tBVNMEBJN2ZNQWlcekMn6pvLria7Sa2Fai5znm7CCJz4pP3lrvlSxhKdkCerk0D9E0bqx5yAo3o2Q7RrD4gA==} engines: {node: '>= 10'} @@ -1910,6 +2075,12 @@ packages: cpu: [x64] os: [win32] + '@next/swc-win32-x64-msvc@15.0.1': + resolution: {integrity: sha512-4Ho2ggvDdMKlZ/0e9HNdZ9ngeaBwtc+2VS5oCeqrbXqOgutX6I4U2X/42VBw0o+M5evn4/7v3zKgGHo+9v/VjA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + '@noble/hashes@1.5.0': resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} engines: {node: ^14.21.3 || >=16} @@ -2423,6 +2594,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-context@1.1.1': + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + peerDependencies: + '@types/react': 18.3.5 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-dialog@1.0.0': resolution: {integrity: sha512-Yn9YU+QlHYLWwV1XfKiqnGVpWYWk6MeBVM6x/bcoyPvxgjQGoeT35482viLPctTMWoMw0PoHgqfSox7Ig+957Q==} peerDependencies: @@ -2712,6 +2892,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-presence@1.1.1': + resolution: {integrity: sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==} + peerDependencies: + '@types/react': 18.3.5 + '@types/react-dom': 18.3.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-primitive@1.0.0': resolution: {integrity: sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==} peerDependencies: @@ -2871,6 +3064,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-tabs@1.1.1': + resolution: {integrity: sha512-3GBUDmP2DvzmtYLMsHmpA1GtR46ZDZ+OreXM/N+kkQJOPIgytFWWTfDQmBQKBvaFS0Vno0FktdbVzN28KGrMdw==} + peerDependencies: + '@types/react': 18.3.5 + '@types/react-dom': 18.3.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-toggle@1.1.0': resolution: {integrity: sha512-gwoxaKZ0oJ4vIgzsfESBuSgJNdc0rv12VhHgcqN0TEJmmZixXG/2XpsLK8kzNWYcnaoRIEEQc0bEi3dIvdUpjw==} peerDependencies: @@ -3292,6 +3498,10 @@ packages: resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} + '@stripe/stripe-js@4.8.0': + resolution: {integrity: sha512-+4Cb0bVHlV4BJXxkJ3cCLSLuWxm3pXKtgcRacox146EuugjCzRRII5T5gUMgL4HpzrBLVwVxjKaZqntNWAXawQ==} + engines: {node: '>=12.16'} + '@swagger-api/apidom-ast@1.0.0-alpha.9': resolution: {integrity: sha512-SAOQrFSFwgDiI4QSIPDwAIJEb4Za+8bu45sNojgV3RMtCz+n4Agw66iqGsDib5YSI/Cg1h4AKFovT3iWdfGWfw==} @@ -3379,6 +3589,9 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@swc/helpers@0.5.13': + resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} + '@swc/helpers@0.5.5': resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} @@ -4277,10 +4490,17 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + color-support@1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -4885,6 +5105,9 @@ packages: es6-weak-map@2.0.3: resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + esbuild-plugin-alias@0.2.1: + resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} + esbuild-register@3.6.0: resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} peerDependencies: @@ -5625,6 +5848,9 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-async-function@2.0.0: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} @@ -6484,6 +6710,27 @@ packages: sass: optional: true + next@15.0.1: + resolution: {integrity: sha512-PSkFkr/w7UnFWm+EP8y/QpHrJXMqpZzAXpergB/EqLPOh4SGPJXv1wj4mslr2hUZBAS9pX7/9YLIdxTv6fwytw==} + engines: {node: '>=18.18.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-69d4b800-20241021 + react-dom: ^18.2.0 || 19.0.0-rc-69d4b800-20241021 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + node-abi@3.68.0: resolution: {integrity: sha512-7vbj10trelExNjFSBm5kTvZXXa7pZyKWx9RCKIyqe6I9Ev3IzGpQoqBP3a+cOdxY+pWj6VkP28n/2wWysBHD/A==} engines: {node: '>=10'} @@ -7416,6 +7663,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + serialize-error@8.1.0: resolution: {integrity: sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==} engines: {node: '>=10'} @@ -7441,6 +7693,10 @@ packages: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} hasBin: true + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -7476,6 +7732,9 @@ packages: simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -7641,6 +7900,10 @@ packages: strip-literal@2.1.0: resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + stripe@17.2.0: + resolution: {integrity: sha512-KuDplY9WrNKi07+uEFeguis/Mh+HC+hfEMy8P5snhQzCXUv01o+4KcIJ9auFxpv4Odp2R2krs9rZ9PhQl8+Sdw==} + engines: {node: '>=12.*'} + style-mod@4.1.2: resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==} @@ -7663,6 +7926,19 @@ packages: babel-plugin-macros: optional: true + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -8614,6 +8890,11 @@ snapshots: tslib: 2.6.3 optional: true + '@emnapi/runtime@1.3.1': + dependencies: + tslib: 2.6.3 + optional: true + '@esbuild-kit/core-utils@3.3.2': dependencies: esbuild: 0.18.20 @@ -9005,6 +9286,81 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.3.1 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + '@ioredis/commands@1.2.0': {} '@isaacs/cliui@8.0.2': @@ -9160,6 +9516,8 @@ snapshots: '@next/env@14.2.5': {} + '@next/env@15.0.1': {} + '@next/eslint-plugin-next@13.4.16': dependencies: glob: 7.1.7 @@ -9170,42 +9528,63 @@ snapshots: '@next/swc-darwin-arm64@14.2.5': optional: true + '@next/swc-darwin-arm64@15.0.1': + optional: true + '@next/swc-darwin-x64@14.2.2': optional: true '@next/swc-darwin-x64@14.2.5': optional: true + '@next/swc-darwin-x64@15.0.1': + optional: true + '@next/swc-linux-arm64-gnu@14.2.2': optional: true '@next/swc-linux-arm64-gnu@14.2.5': optional: true + '@next/swc-linux-arm64-gnu@15.0.1': + optional: true + '@next/swc-linux-arm64-musl@14.2.2': optional: true '@next/swc-linux-arm64-musl@14.2.5': optional: true + '@next/swc-linux-arm64-musl@15.0.1': + optional: true + '@next/swc-linux-x64-gnu@14.2.2': optional: true '@next/swc-linux-x64-gnu@14.2.5': optional: true + '@next/swc-linux-x64-gnu@15.0.1': + optional: true + '@next/swc-linux-x64-musl@14.2.2': optional: true '@next/swc-linux-x64-musl@14.2.5': optional: true + '@next/swc-linux-x64-musl@15.0.1': + optional: true + '@next/swc-win32-arm64-msvc@14.2.2': optional: true '@next/swc-win32-arm64-msvc@14.2.5': optional: true + '@next/swc-win32-arm64-msvc@15.0.1': + optional: true + '@next/swc-win32-ia32-msvc@14.2.2': optional: true @@ -9218,6 +9597,9 @@ snapshots: '@next/swc-win32-x64-msvc@14.2.5': optional: true + '@next/swc-win32-x64-msvc@15.0.1': + optional: true + '@noble/hashes@1.5.0': {} '@node-rs/argon2-android-arm-eabi@1.7.0': @@ -9778,6 +10160,12 @@ snapshots: optionalDependencies: '@types/react': 18.3.5 + '@radix-ui/react-context@1.1.1(@types/react@18.3.5)(react@18.2.0)': + dependencies: + react: 18.2.0 + optionalDependencies: + '@types/react': 18.3.5 + '@radix-ui/react-dialog@1.0.0(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.25.0 @@ -10259,6 +10647,16 @@ snapshots: '@types/react': 18.3.5 '@types/react-dom': 18.3.0 + '@radix-ui/react-presence@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.5)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.5)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.3.5 + '@types/react-dom': 18.3.0 + '@radix-ui/react-primitive@1.0.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.25.0 @@ -10521,6 +10919,22 @@ snapshots: '@types/react': 18.3.5 '@types/react-dom': 18.3.0 + '@radix-ui/react-tabs@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-context': 1.1.1(@types/react@18.3.5)(react@18.2.0) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.5)(react@18.2.0) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.5)(react@18.2.0) + '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.5)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.3.5 + '@types/react-dom': 18.3.0 + '@radix-ui/react-toggle@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@radix-ui/primitive': 1.1.0 @@ -10943,6 +11357,8 @@ snapshots: '@sindresorhus/merge-streams@2.3.0': {} + '@stripe/stripe-js@4.8.0': {} + '@swagger-api/apidom-ast@1.0.0-alpha.9': dependencies: '@babel/runtime-corejs3': 7.25.7 @@ -11277,6 +11693,10 @@ snapshots: '@swc/counter@0.1.3': {} + '@swc/helpers@0.5.13': + dependencies: + tslib: 2.6.3 + '@swc/helpers@0.5.5': dependencies: '@swc/counter': 0.1.3 @@ -11324,13 +11744,13 @@ snapshots: dependencies: '@trpc/server': 10.45.2 - '@trpc/next@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@14.2.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@trpc/next@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@tanstack/react-query': 4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@trpc/client': 10.45.2(@trpc/server@10.45.2) '@trpc/react-query': 10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@trpc/server': 10.45.2 - next: 14.2.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next: 15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -12317,8 +12737,20 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + optional: true + color-support@1.1.3: {} + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + colorette@2.0.20: {} combined-stream@1.0.8: @@ -12894,6 +13326,8 @@ snapshots: es6-iterator: 2.0.3 es6-symbol: 3.1.4 + esbuild-plugin-alias@0.2.1: {} + esbuild-register@3.6.0(esbuild@0.19.12): dependencies: debug: 4.3.7 @@ -13020,7 +13454,7 @@ snapshots: eslint: 8.45.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.45.0) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.45.0) eslint-plugin-react: 7.35.0(eslint@8.45.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.45.0) @@ -13044,7 +13478,7 @@ snapshots: enhanced-resolve: 5.17.1 eslint: 8.45.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.45.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-core-module: 2.15.0 @@ -13066,7 +13500,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.45.0))(eslint@8.45.0))(eslint@8.45.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.45.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.45.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -13928,6 +14362,9 @@ snapshots: is-arrayish@0.2.1: {} + is-arrayish@0.3.2: + optional: true + is-async-function@2.0.0: dependencies: has-tostringtag: 1.0.2 @@ -14967,9 +15404,9 @@ snapshots: react: 18.2.0 use-intl: 3.19.0(react@18.2.0) - next-themes@0.2.1(next@14.2.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + next-themes@0.2.1(next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: - next: 14.2.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next: 15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -15005,31 +15442,6 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@14.2.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0): - dependencies: - '@next/env': 14.2.5 - '@swc/helpers': 0.5.5 - busboy: 1.6.0 - caniuse-lite: 1.0.30001643 - graceful-fs: 4.2.11 - postcss: 8.4.31 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - styled-jsx: 5.1.1(react@18.2.0) - optionalDependencies: - '@next/swc-darwin-arm64': 14.2.5 - '@next/swc-darwin-x64': 14.2.5 - '@next/swc-linux-arm64-gnu': 14.2.5 - '@next/swc-linux-arm64-musl': 14.2.5 - '@next/swc-linux-x64-gnu': 14.2.5 - '@next/swc-linux-x64-musl': 14.2.5 - '@next/swc-win32-arm64-msvc': 14.2.5 - '@next/swc-win32-ia32-msvc': 14.2.5 - '@next/swc-win32-x64-msvc': 14.2.5 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@next/env': 14.2.5 @@ -15055,6 +15467,31 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@15.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@next/env': 15.0.1 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.13 + busboy: 1.6.0 + caniuse-lite: 1.0.30001643 + postcss: 8.4.31 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + styled-jsx: 5.1.6(react@18.2.0) + optionalDependencies: + '@next/swc-darwin-arm64': 15.0.1 + '@next/swc-darwin-x64': 15.0.1 + '@next/swc-linux-arm64-gnu': 15.0.1 + '@next/swc-linux-arm64-musl': 15.0.1 + '@next/swc-linux-x64-gnu': 15.0.1 + '@next/swc-linux-x64-musl': 15.0.1 + '@next/swc-win32-arm64-msvc': 15.0.1 + '@next/swc-win32-x64-msvc': 15.0.1 + sharp: 0.33.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + node-abi@3.68.0: dependencies: semver: 7.6.2 @@ -16060,6 +16497,9 @@ snapshots: semver@7.6.2: {} + semver@7.6.3: + optional: true + serialize-error@8.1.0: dependencies: type-fest: 0.20.2 @@ -16093,6 +16533,33 @@ snapshots: inherits: 2.0.4 safe-buffer: 5.2.1 + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.6.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -16129,6 +16596,11 @@ snapshots: simple-concat: 1.0.1 optional: true + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + optional: true + sisteransi@1.0.5: {} slash@3.0.0: {} @@ -16297,6 +16769,11 @@ snapshots: dependencies: js-tokens: 9.0.0 + stripe@17.2.0: + dependencies: + '@types/node': 20.14.10 + qs: 6.12.3 + style-mod@4.1.2: {} style-to-object@0.4.4: @@ -16317,6 +16794,11 @@ snapshots: client-only: 0.0.1 react: 18.3.1 + styled-jsx@5.1.6(react@18.2.0): + dependencies: + client-only: 0.0.1 + react: 18.2.0 + sucrase@3.35.0: dependencies: '@jridgewell/gen-mapping': 0.3.5