diff --git a/apps/api/package.json b/apps/api/package.json index dfc2a355d..0f4b1044f 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -13,7 +13,6 @@ "@dokploy/server": "workspace:*", "@hono/node-server": "^1.14.3", "@hono/zod-validator": "0.3.0", - "@nerimity/mimiqueue": "1.2.3", "dotenv": "^16.4.5", "hono": "^4.7.10", "pino": "9.4.0", diff --git a/apps/dokploy/components/dashboard/application/general/generic/save-gitlab-provider.tsx b/apps/dokploy/components/dashboard/application/general/generic/save-gitlab-provider.tsx index d6f65caf3..6197fc49f 100644 --- a/apps/dokploy/components/dashboard/application/general/generic/save-gitlab-provider.tsx +++ b/apps/dokploy/components/dashboard/application/general/generic/save-gitlab-provider.tsx @@ -232,9 +232,9 @@ export const SaveGitlabProvider = ({ applicationId }: Props) => {
Repository - {field.value.owner && field.value.repo && ( + {field.value.gitlabPathNamespace && ( { const repository = form.watch("repository"); const gitlabId = form.watch("gitlabId"); + const gitlabUrl = useMemo(() => { + const url = gitlabProviders?.find( + (provider) => provider.gitlabId === gitlabId, + )?.gitlabUrl; + + const gitlabUrl = url?.replace(/\/$/, ""); + + return gitlabUrl || "https://gitlab.com"; + }, [gitlabId, gitlabProviders]); + const { data: repositories, isLoading: isLoadingRepositories, @@ -224,9 +234,9 @@ export const SaveGitlabProviderCompose = ({ composeId }: Props) => {
Repository - {field.value.owner && field.value.repo && ( + {field.value.gitlabPathNamespace && ( { + const router = useRouter(); + + return ( +
+ +
+ + + + Billing + + + Manage your subscription and invoices + + + + + +
+ +
+
+
+
+
+ ); +}; diff --git a/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx b/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx index ac211a1c5..1460244c1 100644 --- a/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx +++ b/apps/dokploy/components/dashboard/settings/billing/show-billing.tsx @@ -4,11 +4,13 @@ import { AlertTriangle, CheckIcon, CreditCard, + FileText, Loader2, MinusIcon, PlusIcon, } from "lucide-react"; import Link from "next/link"; +import { useRouter } from "next/router"; import { useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; @@ -37,7 +39,22 @@ export const calculatePrice = (count: number, isAnnual = false) => { if (count <= 1) return 4.5; return count * 3.5; }; + +const navigationItems = [ + { + name: "Subscription", + href: "/dashboard/settings/billing", + icon: CreditCard, + }, + { + name: "Invoices", + href: "/dashboard/settings/invoices", + icon: FileText, + }, +]; + export const ShowBilling = () => { + const router = useRouter(); const { data: servers } = api.server.count.useQuery(); const { data: admin } = api.user.get.useQuery(); const { data, isLoading } = api.stripe.getProducts.useQuery(); @@ -76,17 +93,41 @@ export const ShowBilling = () => { return (
- -
- + +
+ Billing - Manage your subscription + + Manage your subscription and invoices + - -
+ + + +
{ + if (!timestamp) return "-"; + return new Date(timestamp * 1000).toLocaleDateString("en-US", { + year: "numeric", + month: "short", + day: "numeric", + }); +}; + +const formatAmount = (amount: number, currency: string) => { + return new Intl.NumberFormat("en-US", { + style: "currency", + currency: currency.toUpperCase(), + }).format(amount / 100); +}; + +const getStatusBadge = (status: Stripe.Invoice.Status | null) => { + const statusConfig: Record< + Stripe.Invoice.Status, + { label: string; variant: "default" | "secondary" | "destructive" } + > = { + paid: { label: "Paid", variant: "default" }, + open: { label: "Open", variant: "secondary" }, + draft: { label: "Draft", variant: "secondary" }, + void: { label: "Void", variant: "destructive" }, + uncollectible: { label: "Uncollectible", variant: "destructive" }, + }; + + if (!status) { + return Unknown; + } + + const config = statusConfig[status] || { + label: status, + variant: "secondary" as const, + }; + + return {config.label}; +}; + +export const ShowInvoices = () => { + const { data: invoices, isLoading } = api.stripe.getInvoices.useQuery(); + + return ( +
+ {isLoading ? ( +
+ + Loading invoices... + + +
+ ) : invoices && invoices.length > 0 ? ( +
+ + + + Invoice + Date + Due Date + Amount + Status + Actions + + + + {invoices.map((invoice) => ( + + + {invoice.number || invoice.id.slice(0, 12)} + + {formatDate(invoice.created)} + {formatDate(invoice.dueDate)} + + {formatAmount(invoice.amountDue, invoice.currency)} + + {getStatusBadge(invoice.status)} + +
+ {invoice.hostedInvoiceUrl && ( + + )} + {invoice.invoicePdf && ( + + )} +
+
+
+ ))} +
+
+
+ ) : ( +
+ +

No invoices found

+

+ Your invoices will appear here once you have a subscription +

+
+ )} +
+ ); +}; diff --git a/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx b/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx index d88e9a3e4..13ff2d6e4 100644 --- a/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/setup-server.tsx @@ -22,7 +22,6 @@ import { DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; -import { DropdownMenuItem } from "@/components/ui/dropdown-menu"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; @@ -89,15 +88,15 @@ export const SetupServer = ({ serverId, asButton = false }: Props) => { ) : ( - { - e.preventDefault(); + size="sm" + onClick={() => { setIsOpen(true); }} > - Setup Server - + Setup Server + )} diff --git a/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx b/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx index 85e7f3ee7..92d6fc5c3 100644 --- a/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/show-servers.tsx @@ -6,9 +6,7 @@ import { Loader2, MoreHorizontal, Network, - Pencil, ServerIcon, - Settings, Terminal, Trash2, User, @@ -31,9 +29,7 @@ import { import { DropdownMenu, DropdownMenuContent, - DropdownMenuItem, DropdownMenuLabel, - DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { @@ -285,7 +281,32 @@ export const ShowServers = () => { {/* Compact Actions */} {isActive && ( -
+
+
+ + + + + +
+

+ Setup Server +

+

+ Configure and initialize your + server with Docker, Traefik, and + other essential services +

+
+
+
+
+ {server.sshKeyId && ( @@ -311,20 +332,6 @@ export const ShowServers = () => { )} - - -
- -
-
- -

Setup Server

-
-
-
diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json index c8bb95056..c33826adb 100644 --- a/apps/dokploy/package.json +++ b/apps/dokploy/package.json @@ -1,6 +1,6 @@ { "name": "dokploy", - "version": "v0.26.3", + "version": "v0.26.4", "private": true, "license": "Apache-2.0", "type": "module", @@ -109,7 +109,6 @@ "drizzle-orm": "^0.39.3", "drizzle-zod": "0.5.1", "fancy-ansi": "^0.1.3", - "hi-base32": "^0.5.1", "i18next": "^23.16.8", "input-otp": "^1.4.2", "js-cookie": "^3.0.5", @@ -126,7 +125,6 @@ "node-schedule": "2.1.1", "nodemailer": "6.9.14", "octokit": "3.1.2", - "otpauth": "^9.4.0", "pino": "9.4.0", "pino-pretty": "11.2.2", "postgres": "3.4.4", @@ -155,9 +153,11 @@ "xterm-addon-fit": "^0.8.0", "yaml": "2.8.1", "zod": "^3.25.32", - "zod-form-data": "^2.0.7" + "zod-form-data": "^2.0.7", + "semver": "7.7.3" }, "devDependencies": { + "@types/semver": "7.7.1", "@types/shell-quote": "^1.7.5", "@types/adm-zip": "^0.5.7", "@types/bcrypt": "5.0.2", diff --git a/apps/dokploy/pages/dashboard/settings/invoices.tsx b/apps/dokploy/pages/dashboard/settings/invoices.tsx new file mode 100644 index 000000000..a37c3607c --- /dev/null +++ b/apps/dokploy/pages/dashboard/settings/invoices.tsx @@ -0,0 +1,63 @@ +import { IS_CLOUD } from "@dokploy/server/constants"; +import { validateRequest } from "@dokploy/server/lib/auth"; +import { createServerSideHelpers } from "@trpc/react-query/server"; +import type { GetServerSidePropsContext } from "next"; +import type { ReactElement } from "react"; +import superjson from "superjson"; +import { ShowBillingInvoices } from "@/components/dashboard/settings/billing/show-billing-invoices"; +import { DashboardLayout } from "@/components/layouts/dashboard-layout"; +import { appRouter } from "@/server/api/root"; + +const Page = () => { + return ; +}; + +export default Page; + +Page.getLayout = (page: ReactElement) => { + return {page}; +}; +export async function getServerSideProps( + ctx: GetServerSidePropsContext<{ serviceId: string }>, +) { + if (!IS_CLOUD) { + return { + redirect: { + permanent: true, + destination: "/dashboard/projects", + }, + }; + } + const { req, res } = ctx; + const { user, session } = await validateRequest(req); + if (!user || user.role !== "owner") { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + + const helpers = createServerSideHelpers({ + router: appRouter, + ctx: { + req: req as any, + res: res as any, + db: null as any, + session: session as any, + user: user as any, + }, + transformer: superjson, + }); + + await helpers.user.get.prefetch(); + + await helpers.settings.isCloud.prefetch(); + + return { + props: { + trpcState: helpers.dehydrate(), + }, + }; +} diff --git a/apps/dokploy/server/api/routers/backup.ts b/apps/dokploy/server/api/routers/backup.ts index 68067f9df..600fa5f51 100644 --- a/apps/dokploy/server/api/routers/backup.ts +++ b/apps/dokploy/server/api/routers/backup.ts @@ -285,6 +285,7 @@ export const backupRouter = createTRPCRouter({ .mutation(async ({ input }) => { const backup = await findBackupById(input.backupId); await runWebServerBackup(backup); + await keepLatestNBackups(backup); return true; }), listBackupFiles: protectedProcedure diff --git a/apps/dokploy/server/api/routers/settings.ts b/apps/dokploy/server/api/routers/settings.ts index bd182527a..c9d21e515 100644 --- a/apps/dokploy/server/api/routers/settings.ts +++ b/apps/dokploy/server/api/routers/settings.ts @@ -88,7 +88,7 @@ export const settingsRouter = createTRPCRouter({ if (IS_CLOUD) { return true; } - await reloadDockerResource("dokploy"); + await reloadDockerResource("dokploy", undefined, packageInfo.version); return true; }), cleanRedis: adminProcedure.mutation(async () => { @@ -399,7 +399,7 @@ export const settingsRouter = createTRPCRouter({ return DEFAULT_UPDATE_DATA; } - return await getUpdateData(); + return await getUpdateData(packageInfo.version); }), updateServer: adminProcedure.mutation(async () => { if (IS_CLOUD) { diff --git a/apps/dokploy/server/api/routers/stripe.ts b/apps/dokploy/server/api/routers/stripe.ts index d2a000324..3354c3311 100644 --- a/apps/dokploy/server/api/routers/stripe.ts +++ b/apps/dokploy/server/api/routers/stripe.ts @@ -81,6 +81,7 @@ export const stripeRouter = createTRPCRouter({ metadata: { adminId: owner.id, }, + customer_email: owner.email, allow_promotion_codes: true, success_url: `${WEBSITE_URL}/dashboard/settings/servers?success=true`, cancel_url: `${WEBSITE_URL}/dashboard/settings/billing`, @@ -128,4 +129,39 @@ export const stripeRouter = createTRPCRouter({ return servers.length < user.serversQuantity; }), + + getInvoices: adminProcedure.query(async ({ ctx }) => { + const user = await findUserById(ctx.user.ownerId); + const stripeCustomerId = user.stripeCustomerId; + + if (!stripeCustomerId) { + return []; + } + + const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { + apiVersion: "2024-09-30.acacia", + }); + + try { + const invoices = await stripe.invoices.list({ + customer: stripeCustomerId, + limit: 100, + }); + + return invoices.data.map((invoice) => ({ + id: invoice.id, + number: invoice.number, + status: invoice.status, + amountDue: invoice.amount_due, + amountPaid: invoice.amount_paid, + currency: invoice.currency, + created: invoice.created, + dueDate: invoice.due_date, + hostedInvoiceUrl: invoice.hosted_invoice_url, + invoicePdf: invoice.invoice_pdf, + })); + } catch (_) { + return []; + } + }), }); diff --git a/apps/monitoring/database/containers.go b/apps/monitoring/database/containers.go index 568ad12e5..4e41f5fae 100644 --- a/apps/monitoring/database/containers.go +++ b/apps/monitoring/database/containers.go @@ -58,7 +58,7 @@ func (db *DB) GetLastNContainerMetrics(containerName string, limit int) ([]Conta WITH recent_metrics AS ( SELECT metrics_json FROM container_metrics - WHERE container_name LIKE ? || '%' + WHERE container_name = ? ORDER BY timestamp DESC LIMIT ? ) @@ -98,7 +98,7 @@ func (db *DB) GetAllMetricsContainer(containerName string) ([]ContainerMetric, e WITH recent_metrics AS ( SELECT metrics_json FROM container_metrics - WHERE container_name LIKE ? || '%' + WHERE container_name = ? ORDER BY timestamp DESC ) SELECT metrics_json FROM recent_metrics ORDER BY json_extract(metrics_json, '$.timestamp') ASC diff --git a/packages/server/package.json b/packages/server/package.json index 9ce60fcf7..5a7b0037e 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -57,7 +57,6 @@ "drizzle-dbml-generator": "0.10.0", "drizzle-orm": "^0.39.3", "drizzle-zod": "0.5.1", - "hi-base32": "^0.5.1", "yaml": "2.8.1", "lodash": "4.17.21", "micromatch": "4.0.8", @@ -67,7 +66,6 @@ "node-schedule": "2.1.1", "nodemailer": "6.9.14", "octokit": "3.1.2", - "otpauth": "^9.4.0", "pino": "9.4.0", "pino-pretty": "11.2.2", "postgres": "3.4.4", @@ -80,9 +78,11 @@ "ssh2": "1.15.0", "toml": "3.0.0", "ws": "8.16.0", - "zod": "^3.25.32" + "zod": "^3.25.32", + "semver": "7.7.3" }, "devDependencies": { + "@types/semver": "7.7.1", "@types/adm-zip": "^0.5.7", "@types/bcrypt": "5.0.2", "@types/dockerode": "3.3.23", diff --git a/packages/server/src/services/settings.ts b/packages/server/src/services/settings.ts index 277008bd3..4235376d9 100644 --- a/packages/server/src/services/settings.ts +++ b/packages/server/src/services/settings.ts @@ -5,12 +5,12 @@ import { execAsync, execAsyncRemote, } from "@dokploy/server/utils/process/execAsync"; +import semver from "semver"; import { initializeStandaloneTraefik, initializeTraefikService, type TraefikOptions, } from "../setup/traefik-setup"; - export interface IUpdateData { latestVersion: string | null; updateAvailable: boolean; @@ -55,56 +55,95 @@ export const getServiceImageDigest = async () => { }; /** Returns latest version number and information whether server update is available by comparing current image's digest against digest for provided image tag via Docker hub API. */ -export const getUpdateData = async (): Promise => { - let currentDigest: string; +export const getUpdateData = async ( + currentVersion: string, +): Promise => { try { - currentDigest = await getServiceImageDigest(); - } catch (error) { - // TODO: Docker versions 29.0.0 change the way to get the service image digest, so we need to update this in the future we upgrade to that version. - return DEFAULT_UPDATE_DATA; - } + const baseUrl = + "https://hub.docker.com/v2/repositories/dokploy/dokploy/tags"; + let url: string | null = `${baseUrl}?page_size=100`; + let allResults: { digest: string; name: string }[] = []; - const baseUrl = "https://hub.docker.com/v2/repositories/dokploy/dokploy/tags"; - let url: string | null = `${baseUrl}?page_size=100`; - let allResults: { digest: string; name: string }[] = []; - while (url) { - const response = await fetch(url, { - method: "GET", - headers: { "Content-Type": "application/json" }, - }); + // Fetch all tags from Docker Hub + while (url) { + const response = await fetch(url, { + method: "GET", + headers: { "Content-Type": "application/json" }, + }); - const data = (await response.json()) as { - next: string | null; - results: { digest: string; name: string }[]; - }; + const data = (await response.json()) as { + next: string | null; + results: { digest: string; name: string }[]; + }; - allResults = allResults.concat(data.results); - url = data?.next; - } + allResults = allResults.concat(data.results); + url = data?.next; + } - const imageTag = getDokployImageTag(); - const searchedDigest = allResults.find((t) => t.name === imageTag)?.digest; + const currentImageTag = getDokployImageTag(); - if (!searchedDigest) { - return DEFAULT_UPDATE_DATA; - } + // Special handling for canary and feature branches + // For development versions (canary/feature), don't perform update checks + // These are unstable versions that change frequently, and users on these + // branches are expected to manually manage updates + if (currentImageTag === "canary" || currentImageTag === "feature") { + const currentDigest = await getServiceImageDigest(); + const latestDigest = allResults.find( + (t) => t.name === currentImageTag, + )?.digest; + if (!latestDigest) { + return DEFAULT_UPDATE_DATA; + } + if (currentDigest !== latestDigest) { + return { + latestVersion: currentImageTag, + updateAvailable: true, + }; + } + return { + latestVersion: currentImageTag, + updateAvailable: false, + }; + } - if (imageTag === "latest") { - const versionedTag = allResults.find( - (t) => t.digest === searchedDigest && t.name.startsWith("v"), - ); + // For stable versions, use semver comparison + // Find the "latest" tag and get its digest + const latestTag = allResults.find((t) => t.name === "latest"); - if (!versionedTag) { + if (!latestTag) { return DEFAULT_UPDATE_DATA; } - const { name: latestVersion, digest } = versionedTag; - const updateAvailable = digest !== currentDigest; + // Find the versioned tag (v0.x.x) that has the same digest as "latest" + const latestVersionTag = allResults.find( + (t) => t.digest === latestTag.digest && t.name.startsWith("v"), + ); - return { latestVersion, updateAvailable }; + if (!latestVersionTag) { + return DEFAULT_UPDATE_DATA; + } + + const latestVersion = latestVersionTag.name; + + // Use semver to compare versions for stable releases + const cleanedCurrent = semver.clean(currentVersion); + const cleanedLatest = semver.clean(latestVersion); + + if (!cleanedCurrent || !cleanedLatest) { + return DEFAULT_UPDATE_DATA; + } + + // Check if the latest version is greater than the current version + const updateAvailable = semver.gt(cleanedLatest, cleanedCurrent); + + return { + latestVersion, + updateAvailable, + }; + } catch (error) { + console.error("Error fetching update data:", error); + return DEFAULT_UPDATE_DATA; } - const updateAvailable = searchedDigest !== currentDigest; - return { latestVersion: imageTag, updateAvailable }; }; interface TreeDataItem { @@ -254,11 +293,22 @@ fi`; export const reloadDockerResource = async ( resourceName: string, serverId?: string, + version?: string, ) => { const resourceType = await getDockerResourceType(resourceName, serverId); let command = ""; if (resourceType === "service") { - command = `docker service update --force ${resourceName}`; + if (resourceName === "dokploy") { + const currentImageTag = getDokployImageTag(); + let imageTag = version; + if (currentImageTag === "canary" || currentImageTag === "feature") { + imageTag = currentImageTag; + } + + command = `docker service update --force --image dokploy/dokploy:${imageTag} ${resourceName}`; + } else { + command = `docker service update --force ${resourceName}`; + } } else if (resourceType === "standalone") { command = `docker restart ${resourceName}`; } else { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0c06df37..cd5ef0a96 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,9 +51,6 @@ importers: '@hono/zod-validator': specifier: 0.3.0 version: 0.3.0(hono@4.7.10)(zod@3.25.32) - '@nerimity/mimiqueue': - specifier: 1.2.3 - version: 1.2.3(redis@4.7.0) dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -313,9 +310,6 @@ importers: fancy-ansi: specifier: ^0.1.3 version: 0.1.3 - hi-base32: - specifier: ^0.5.1 - version: 0.5.1 i18next: specifier: ^23.16.8 version: 23.16.8 @@ -364,9 +358,6 @@ importers: octokit: specifier: 3.1.2 version: 3.1.2 - otpauth: - specifier: ^9.4.0 - version: 9.4.0 pino: specifier: 9.4.0 version: 9.4.0 @@ -406,6 +397,9 @@ importers: recharts: specifier: ^2.15.3 version: 2.15.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + semver: + specifier: 7.7.3 + version: 7.7.3 shell-quote: specifier: ^1.8.1 version: 1.8.2 @@ -491,6 +485,9 @@ importers: '@types/react-dom': specifier: 18.3.0 version: 18.3.0 + '@types/semver': + specifier: 7.7.1 + version: 7.7.1 '@types/shell-quote': specifier: ^1.7.5 version: 1.7.5 @@ -678,9 +675,6 @@ importers: drizzle-zod: specifier: 0.5.1 version: 0.5.1(drizzle-orm@0.39.3(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(kysely@0.28.7)(postgres@3.4.4))(zod@3.25.32) - hi-base32: - specifier: ^0.5.1 - version: 0.5.1 lodash: specifier: 4.17.21 version: 4.17.21 @@ -705,9 +699,6 @@ importers: octokit: specifier: 3.1.2 version: 3.1.2 - otpauth: - specifier: ^9.4.0 - version: 9.4.0 pino: specifier: 9.4.0 version: 9.4.0 @@ -729,6 +720,9 @@ importers: react-dom: specifier: 18.2.0 version: 18.2.0(react@18.2.0) + semver: + specifier: 7.7.3 + version: 7.7.3 shell-quote: specifier: ^1.8.1 version: 1.8.2 @@ -784,6 +778,9 @@ importers: '@types/react-dom': specifier: 18.3.0 version: 18.3.0 + '@types/semver': + specifier: 7.7.1 + version: 7.7.1 '@types/shell-quote': specifier: ^1.7.5 version: 1.7.5 @@ -1951,11 +1948,6 @@ packages: cpu: [x64] os: [win32] - '@nerimity/mimiqueue@1.2.3': - resolution: {integrity: sha512-WPoGe417P+S0FLfl3psRBI5adcAWXb917vCF1qD2yGZ1ggBEnMH6UrUK464gzJEOpAlGt8BBbIp0tgCEazZ47A==} - peerDependencies: - redis: ^4.7.0 - '@next/env@16.0.10': resolution: {integrity: sha512-8tuaQkyDVgeONQ1MeT9Mkk8pQmZapMKFh5B+OrFUlG3rVmYTXcXlBetBgTurKXGaIZvkoqRT9JL5K3phXcgang==} @@ -4060,6 +4052,9 @@ packages: '@types/readable-stream@4.0.20': resolution: {integrity: sha512-eLgbR5KwUh8+6pngBDxS32MymdCsCHnGtwHTrC0GDorbc7NbcnkZAWptDLgZiRk9VRas+B6TyRgPDucq4zRs8g==} + '@types/semver@7.7.1': + resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + '@types/shell-quote@1.7.5': resolution: {integrity: sha512-+UE8GAGRPbJVQDdxi16dgadcBfQ+KG2vgZhV1+3A1XmHbmwcdwhCUwIdy+d3pAGrbvgRoVSjeI9vOWyq376Yzw==} @@ -4302,9 +4297,6 @@ packages: assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - async-await-queue@2.1.4: - resolution: {integrity: sha512-3DpDtxkKO0O/FPlWbk/CrbexjuSxWm1CH1bXlVNVyMBIkKHhT5D85gzHmGJokG3ibNGWQ7pHBmStxUW/z/0LYQ==} - asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -5389,9 +5381,6 @@ packages: help-me@5.0.0: resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} - hi-base32@0.5.1: - resolution: {integrity: sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==} - highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} @@ -6426,9 +6415,6 @@ packages: openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} - otpauth@9.4.0: - resolution: {integrity: sha512-fHIfzIG5RqCkK9cmV8WU+dPQr9/ebR5QOwGZn2JAr1RQF+lmAuLL2YdtdqvmBjNmgJlYk3KZ4a0XokaEhg1Jsw==} - p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} @@ -7087,11 +7073,6 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} @@ -8119,7 +8100,7 @@ snapshots: '@commitlint/is-ignored@19.8.1': dependencies: '@commitlint/types': 19.8.1 - semver: 7.7.2 + semver: 7.7.3 '@commitlint/lint@19.8.1': dependencies: @@ -8736,7 +8717,7 @@ snapshots: nopt: 5.0.0 npmlog: 5.0.1 rimraf: 3.0.2 - semver: 7.7.2 + semver: 7.7.3 tar: 6.2.1 transitivePeerDependencies: - encoding @@ -8762,11 +8743,6 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': optional: true - '@nerimity/mimiqueue@1.2.3(redis@4.7.0)': - dependencies: - async-await-queue: 2.1.4 - redis: 4.7.0 - '@next/env@16.0.10': {} '@next/swc-darwin-arm64@16.0.10': @@ -9327,7 +9303,7 @@ snapshots: '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.28.0 forwarded-parse: 2.1.2 - semver: 7.7.2 + semver: 7.7.3 transitivePeerDependencies: - supports-color @@ -9528,7 +9504,7 @@ snapshots: '@types/shimmer': 1.2.0 import-in-the-middle: 1.14.2 require-in-the-middle: 7.5.2 - semver: 7.7.2 + semver: 7.7.3 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -9673,7 +9649,7 @@ snapshots: '@opentelemetry/propagator-b3': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/propagator-jaeger': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) - semver: 7.7.2 + semver: 7.7.3 '@opentelemetry/semantic-conventions@1.28.0': {} @@ -11421,6 +11397,8 @@ snapshots: dependencies: '@types/node': 20.17.51 + '@types/semver@7.7.1': {} + '@types/shell-quote@1.7.5': {} '@types/shimmer@1.2.0': {} @@ -11673,8 +11651,6 @@ snapshots: assertion-error@1.1.0: {} - async-await-queue@2.1.4: {} - asynckit@0.4.0: {} atomic-sleep@1.0.0: {} @@ -11820,7 +11796,7 @@ snapshots: lodash: 4.17.21 msgpackr: 1.11.4 node-abort-controller: 3.1.1 - semver: 7.7.2 + semver: 7.7.3 tslib: 2.8.1 uuid: 9.0.1 transitivePeerDependencies: @@ -12336,7 +12312,7 @@ snapshots: '@one-ini/wasm': 0.1.1 commander: 10.0.1 minimatch: 9.0.1 - semver: 7.7.2 + semver: 7.7.3 electron-to-chromium@1.5.159: {} @@ -12650,7 +12626,7 @@ snapshots: '@petamoriken/float16': 3.9.2 debug: 4.4.1 env-paths: 3.0.0 - semver: 7.7.2 + semver: 7.7.3 shell-quote: 1.8.2 which: 4.0.0 transitivePeerDependencies: @@ -12824,8 +12800,6 @@ snapshots: help-me@5.0.0: {} - hi-base32@0.5.1: {} - highlight.js@10.7.3: {} highlightjs-vue@1.0.0: {} @@ -13138,7 +13112,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.7.2 + semver: 7.7.3 jss-plugin-camel-case@10.10.0: dependencies: @@ -13962,10 +13936,6 @@ snapshots: openapi-types@12.1.3: {} - otpauth@9.4.0: - dependencies: - '@noble/hashes': 1.7.1 - p-cancelable@3.0.0: {} p-limit@2.3.0: @@ -14674,10 +14644,7 @@ snapshots: semver@6.3.1: {} - semver@7.7.2: {} - - semver@7.7.3: - optional: true + semver@7.7.3: {} serialize-error-cjs@0.1.4: {}