diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 31dbc48fb..bfdc8c48b 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -24,14 +24,14 @@ jobs: - name: Install Nixpacks if: matrix.job == 'test' run: | - export NIXPACKS_VERSION=1.39.0 + export NIXPACKS_VERSION=1.41.0 curl -sSL https://nixpacks.com/install.sh | bash echo "Nixpacks installed $NIXPACKS_VERSION" - + - name: Install Railpack if: matrix.job == 'test' run: | - export RAILPACK_VERSION=0.15.0 + export RAILPACK_VERSION=0.15.4 curl -sSL https://railpack.com/install.sh | bash echo "Railpack installed $RAILPACK_VERSION" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 38a36345e..4c1f832db 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -148,7 +148,7 @@ curl -sSL https://railpack.com/install.sh | sh ```bash # Install Buildpacks -curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.35.0/pack-v0.35.0-linux.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack +curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.39.1/pack-v0.39.1-linux.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack ``` ## Pull Request diff --git a/Dockerfile b/Dockerfile index ae8c997f8..5d7bb6770 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,18 +51,18 @@ RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh --ver # Install Nixpacks and tsx # | VERBOSE=1 VERSION=1.21.0 bash -ARG NIXPACKS_VERSION=1.39.0 +ARG NIXPACKS_VERSION=1.41.0 RUN curl -sSL https://nixpacks.com/install.sh -o install.sh \ && chmod +x install.sh \ && ./install.sh \ && pnpm install -g tsx # Install Railpack -ARG RAILPACK_VERSION=0.2.2 +ARG RAILPACK_VERSION=0.15.4 RUN curl -sSL https://railpack.com/install.sh | bash # Install buildpacks -COPY --from=buildpacksio/pack:0.35.0 /usr/local/bin/pack /usr/local/bin/pack +COPY --from=buildpacksio/pack:0.39.1 /usr/local/bin/pack /usr/local/bin/pack EXPOSE 3000 CMD [ "pnpm", "start" ] diff --git a/Dockerfile.cloud b/Dockerfile.cloud index ee42cd2bd..a0de32021 100644 --- a/Dockerfile.cloud +++ b/Dockerfile.cloud @@ -60,4 +60,4 @@ RUN curl https://rclone.org/install.sh | bash RUN pnpm install -g tsx EXPOSE 3000 -CMD [ "pnpm", "start" ] \ No newline at end of file +CMD [ "pnpm", "start" ] diff --git a/Dockerfile.schedule b/Dockerfile.schedule index ecb125e09..88f38b17f 100644 --- a/Dockerfile.schedule +++ b/Dockerfile.schedule @@ -35,4 +35,4 @@ COPY --from=build /prod/schedules/dist ./dist COPY --from=build /prod/schedules/package.json ./package.json COPY --from=build /prod/schedules/node_modules ./node_modules -CMD HOSTNAME=0.0.0.0 && pnpm start \ No newline at end of file +CMD HOSTNAME=0.0.0.0 && pnpm start diff --git a/Dockerfile.server b/Dockerfile.server index ea6b372e8..8526bc406 100644 --- a/Dockerfile.server +++ b/Dockerfile.server @@ -35,4 +35,4 @@ COPY --from=build /prod/api/dist ./dist COPY --from=build /prod/api/package.json ./package.json COPY --from=build /prod/api/node_modules ./node_modules -CMD HOSTNAME=0.0.0.0 && pnpm start \ No newline at end of file +CMD HOSTNAME=0.0.0.0 && pnpm start diff --git a/README.md b/README.md index 23fcd0c9d..e97735597 100644 --- a/README.md +++ b/README.md @@ -68,53 +68,21 @@ For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com). [Github Sponsors](https://github.com/sponsors/Siumauricio) - +## Sponsors - - -### Hero Sponsors 🎖 - -
- Hostinger - LX Aer - - - - - - -
- - - - - -### Premium Supporters 🥇 - -
- Supafort.com - agentdock.ai -
- - - - - -### Elite Contributors 🥈 - -
- AmericanCloud - Tolgee -
- -### Supporting Members 🥉 - -
- - Cloudblast.io - - Synexa -
+| Sponsor | Logo | Supporter Level | +|---------|:----:|----------------| +| [Hostinger](https://www.hostinger.com/vps-hosting?ref=dokploy) | Hostinger | 🎖 Hero Sponsor | +| [LX Aer](https://www.lxaer.com/?ref=dokploy) | LX Aer | 🎖 Hero Sponsor | +| [LinkDR](https://linkdr.com/?ref=dokploy) | LinkDR | 🎖 Hero Sponsor | +| [LambdaTest](https://www.lambdatest.com/?utm_source=dokploy&utm_medium=sponsor) | LambdaTest | 🎖 Hero Sponsor | +| [Awesome Tools](https://awesome.tools/) | Awesome Tools | 🎖 Hero Sponsor | +| [Supafort](https://supafort.com/?ref=dokploy) | Supafort.com | 🥇 Premium Supporter | +| [Agentdock](https://agentdock.ai/?ref=dokploy) | agentdock.ai | 🥇 Premium Supporter | +| [AmericanCloud](https://americancloud.com/?ref=dokploy) | AmericanCloud | 🥈 Elite Contributor | +| [Tolgee](https://tolgee.io/?utm_source=github_dokploy&utm_medium=banner&utm_campaign=dokploy) | Tolgee | 🥈 Elite Contributor | +| [Cloudblast](https://cloudblast.io/?ref=dokploy) | Cloudblast.io | 🥉 Supporting Member | +| [Synexa](https://synexa.ai/?ref=dokploy) | Synexa | 🥉 Supporting Member | ### Community Backers 🤝 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/api/src/schema.ts b/apps/api/src/schema.ts index 5a4355956..e2f37cd1c 100644 --- a/apps/api/src/schema.ts +++ b/apps/api/src/schema.ts @@ -25,7 +25,7 @@ export const deployJobSchema = z.discriminatedUnion("applicationType", [ titleLog: z.string().optional(), descriptionLog: z.string().optional(), server: z.boolean().optional(), - type: z.enum(["deploy"]), + type: z.enum(["deploy", "redeploy"]), applicationType: z.literal("application-preview"), serverId: z.string().min(1), }), diff --git a/apps/api/src/utils.ts b/apps/api/src/utils.ts index 0d0b574fc..13708006a 100644 --- a/apps/api/src/utils.ts +++ b/apps/api/src/utils.ts @@ -4,6 +4,7 @@ import { deployPreviewApplication, rebuildApplication, rebuildCompose, + rebuildPreviewApplication, updateApplicationStatus, updateCompose, updatePreviewDeployment, @@ -54,7 +55,14 @@ export const deploy = async (job: DeployJob) => { previewStatus: "running", }); if (job.server) { - if (job.type === "deploy") { + if (job.type === "redeploy") { + await rebuildPreviewApplication({ + applicationId: job.applicationId, + titleLog: job.titleLog || "Rebuild Preview Deployment", + descriptionLog: job.descriptionLog || "", + previewDeploymentId: job.previewDeploymentId, + }); + } else if (job.type === "deploy") { await deployPreviewApplication({ applicationId: job.applicationId, titleLog: job.titleLog || "Preview Deployment", diff --git a/apps/dokploy/__test__/drop/drop.test.ts b/apps/dokploy/__test__/drop/drop.test.ts index 1c0a446a3..a67d866bf 100644 --- a/apps/dokploy/__test__/drop/drop.test.ts +++ b/apps/dokploy/__test__/drop/drop.test.ts @@ -25,7 +25,7 @@ if (typeof window === "undefined") { } const baseApp: ApplicationNested = { - railpackVersion: "0.2.2", + railpackVersion: "0.15.4", applicationId: "", previewLabels: [], createEnvFile: true, diff --git a/apps/dokploy/__test__/env/stack-environment.test.ts b/apps/dokploy/__test__/env/stack-environment.test.ts new file mode 100644 index 000000000..13f5adb53 --- /dev/null +++ b/apps/dokploy/__test__/env/stack-environment.test.ts @@ -0,0 +1,184 @@ +import { getEnviromentVariablesObject } from "@dokploy/server/index"; +import { describe, expect, it } from "vitest"; + +const projectEnv = ` +ENVIRONMENT=staging +DATABASE_URL=postgres://postgres:postgres@localhost:5432/project_db +PORT=3000 +`; + +const environmentEnv = ` +NODE_ENV=development +API_URL=https://api.dev.example.com +REDIS_URL=redis://localhost:6379 +DATABASE_NAME=dev_database +SECRET_KEY=env-secret-123 +`; + +describe("getEnviromentVariablesObject with environment variables (Stack compose)", () => { + it("resolves environment variables correctly for Stack compose", () => { + const serviceEnv = ` +FOO=\${{environment.NODE_ENV}} +BAR=\${{environment.API_URL}} +BAZ=test +`; + + const result = getEnviromentVariablesObject( + serviceEnv, + projectEnv, + environmentEnv, + ); + + expect(result).toEqual({ + FOO: "development", + BAR: "https://api.dev.example.com", + BAZ: "test", + }); + }); + + it("resolves both project and environment variables for Stack compose", () => { + const serviceEnv = ` +ENVIRONMENT=\${{project.ENVIRONMENT}} +NODE_ENV=\${{environment.NODE_ENV}} +API_URL=\${{environment.API_URL}} +DATABASE_URL=\${{project.DATABASE_URL}} +SERVICE_PORT=4000 +`; + + const result = getEnviromentVariablesObject( + serviceEnv, + projectEnv, + environmentEnv, + ); + + expect(result).toEqual({ + ENVIRONMENT: "staging", + NODE_ENV: "development", + API_URL: "https://api.dev.example.com", + DATABASE_URL: "postgres://postgres:postgres@localhost:5432/project_db", + SERVICE_PORT: "4000", + }); + }); + + it("handles multiple environment references in single value for Stack compose", () => { + const multiRefEnv = ` +HOST=localhost +PORT=5432 +USERNAME=postgres +PASSWORD=secret123 +`; + + const serviceEnv = ` +DATABASE_URL=postgresql://\${{environment.USERNAME}}:\${{environment.PASSWORD}}@\${{environment.HOST}}:\${{environment.PORT}}/mydb +`; + + const result = getEnviromentVariablesObject(serviceEnv, "", multiRefEnv); + + expect(result).toEqual({ + DATABASE_URL: "postgresql://postgres:secret123@localhost:5432/mydb", + }); + }); + + it("throws error for undefined environment variables in Stack compose", () => { + const serviceWithUndefined = ` +UNDEFINED_VAR=\${{environment.UNDEFINED_VAR}} +`; + + expect(() => + getEnviromentVariablesObject(serviceWithUndefined, "", environmentEnv), + ).toThrow("Invalid environment variable: environment.UNDEFINED_VAR"); + }); + + it("allows service variables to override environment variables in Stack compose", () => { + const serviceOverrideEnv = ` +NODE_ENV=production +API_URL=\${{environment.API_URL}} +`; + + const result = getEnviromentVariablesObject( + serviceOverrideEnv, + "", + environmentEnv, + ); + + expect(result).toEqual({ + NODE_ENV: "production", + API_URL: "https://api.dev.example.com", + }); + }); + + it("resolves complex references with project, environment, and service variables for Stack compose", () => { + const complexServiceEnv = ` +FULL_DATABASE_URL=\${{project.DATABASE_URL}}/\${{environment.DATABASE_NAME}} +API_ENDPOINT=\${{environment.API_URL}}/\${{project.ENVIRONMENT}}/api +SERVICE_NAME=my-service +COMPLEX_VAR=\${{SERVICE_NAME}}-\${{environment.NODE_ENV}}-\${{project.ENVIRONMENT}} +`; + + const result = getEnviromentVariablesObject( + complexServiceEnv, + projectEnv, + environmentEnv, + ); + + expect(result).toEqual({ + FULL_DATABASE_URL: + "postgres://postgres:postgres@localhost:5432/project_db/dev_database", + API_ENDPOINT: "https://api.dev.example.com/staging/api", + SERVICE_NAME: "my-service", + COMPLEX_VAR: "my-service-development-staging", + }); + }); + + it("maintains precedence: service > environment > project in Stack compose", () => { + const conflictingProjectEnv = ` +NODE_ENV=production-project +API_URL=https://project.api.com +DATABASE_NAME=project_db +`; + + const conflictingEnvironmentEnv = ` +NODE_ENV=development-environment +API_URL=https://environment.api.com +DATABASE_NAME=env_db +`; + + const serviceWithConflicts = ` +NODE_ENV=service-override +PROJECT_ENV=\${{project.NODE_ENV}} +ENV_VAR=\${{environment.API_URL}} +DB_NAME=\${{environment.DATABASE_NAME}} +`; + + const result = getEnviromentVariablesObject( + serviceWithConflicts, + conflictingProjectEnv, + conflictingEnvironmentEnv, + ); + + expect(result).toEqual({ + NODE_ENV: "service-override", + PROJECT_ENV: "production-project", + ENV_VAR: "https://environment.api.com", + DB_NAME: "env_db", + }); + }); + + it("handles empty environment variables in Stack compose", () => { + const serviceWithEmpty = ` +SERVICE_VAR=test +PROJECT_VAR=\${{project.ENVIRONMENT}} +`; + + const result = getEnviromentVariablesObject( + serviceWithEmpty, + projectEnv, + "", + ); + + expect(result).toEqual({ + SERVICE_VAR: "test", + PROJECT_VAR: "staging", + }); + }); +}); diff --git a/apps/dokploy/__test__/traefik/traefik.test.ts b/apps/dokploy/__test__/traefik/traefik.test.ts index 8e678413c..6d8aac7e1 100644 --- a/apps/dokploy/__test__/traefik/traefik.test.ts +++ b/apps/dokploy/__test__/traefik/traefik.test.ts @@ -3,7 +3,7 @@ import { createRouterConfig } from "@dokploy/server"; import { expect, test } from "vitest"; const baseApp: ApplicationNested = { - railpackVersion: "0.2.2", + railpackVersion: "0.15.4", rollbackActive: false, applicationId: "", previewLabels: [], diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx index 739bd87a5..ee427feca 100644 --- a/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx @@ -1,205 +1,106 @@ -import { zodResolver } from "@hookform/resolvers/zod"; -import { HelpCircle, Settings } from "lucide-react"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; +import { Settings } from "lucide-react"; +import { useState } from "react"; import { AlertBlock } from "@/components/shared/alert-block"; -import { CodeEditor } from "@/components/shared/code-editor"; 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 { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; -import { api } from "@/utils/api"; +import { cn } from "@/lib/utils"; +import { + EndpointSpecForm, + HealthCheckForm, + LabelsForm, + ModeForm, + PlacementForm, + RestartPolicyForm, + RollbackConfigForm, + StopGracePeriodForm, + UpdateConfigForm, +} from "./swarm-forms"; -const HealthCheckSwarmSchema = z - .object({ - Test: z.array(z.string()).optional(), - Interval: z.number().optional(), - Timeout: z.number().optional(), - StartPeriod: z.number().optional(), - Retries: z.number().optional(), - }) - .strict(); - -const RestartPolicySwarmSchema = z - .object({ - Condition: z.string().optional(), - Delay: z.number().optional(), - MaxAttempts: z.number().optional(), - Window: z.number().optional(), - }) - .strict(); - -const PreferenceSchema = z - .object({ - Spread: z.object({ - SpreadDescriptor: z.string(), - }), - }) - .strict(); - -const PlatformSchema = z - .object({ - Architecture: z.string(), - OS: z.string(), - }) - .strict(); - -const PlacementSwarmSchema = z - .object({ - Constraints: z.array(z.string()).optional(), - Preferences: z.array(PreferenceSchema).optional(), - MaxReplicas: z.number().optional(), - Platforms: z.array(PlatformSchema).optional(), - }) - .strict(); - -const UpdateConfigSwarmSchema = z - .object({ - Parallelism: z.number(), - Delay: z.number().optional(), - FailureAction: z.string().optional(), - Monitor: z.number().optional(), - MaxFailureRatio: z.number().optional(), - Order: z.string(), - }) - .strict(); - -const ReplicatedSchema = z - .object({ - Replicas: z.number().optional(), - }) - .strict(); - -const ReplicatedJobSchema = z - .object({ - MaxConcurrent: z.number().optional(), - TotalCompletions: z.number().optional(), - }) - .strict(); - -const ServiceModeSwarmSchema = z - .object({ - Replicated: ReplicatedSchema.optional(), - Global: z.object({}).optional(), - ReplicatedJob: ReplicatedJobSchema.optional(), - GlobalJob: z.object({}).optional(), - }) - .strict(); - -const NetworkSwarmSchema = z.array( - z - .object({ - Target: z.string().optional(), - Aliases: z.array(z.string()).optional(), - DriverOpts: z.object({}).optional(), - }) - .strict(), -); - -const LabelsSwarmSchema = z.record(z.string()); - -const EndpointPortConfigSwarmSchema = z - .object({ - Protocol: z.string().optional(), - TargetPort: z.number().optional(), - PublishedPort: z.number().optional(), - PublishMode: z.string().optional(), - }) - .strict(); - -const EndpointSpecSwarmSchema = z - .object({ - Mode: z.string().optional(), - Ports: z.array(EndpointPortConfigSwarmSchema).optional(), - }) - .strict(); - -const createStringToJSONSchema = (schema: z.ZodTypeAny) => { - return z - .string() - .transform((str, ctx) => { - if (str === null || str === "") { - return null; - } - try { - return JSON.parse(str); - } catch { - ctx.addIssue({ code: "custom", message: "Invalid JSON format" }); - return z.NEVER; - } - }) - .superRefine((data, ctx) => { - if (data === null) { - return; - } - - if (Object.keys(data).length === 0) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Object cannot be empty", - }); - return; - } - - const parseResult = schema.safeParse(data); - if (!parseResult.success) { - for (const error of parseResult.error.issues) { - const path = error.path.join("."); - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: `${path} ${error.message}`, - }); - } - } - }); +type MenuItem = { + id: string; + label: string; + description: string; + docDescription: string; }; -const addSwarmSettings = z.object({ - healthCheckSwarm: createStringToJSONSchema(HealthCheckSwarmSchema).nullable(), - restartPolicySwarm: createStringToJSONSchema( - RestartPolicySwarmSchema, - ).nullable(), - placementSwarm: createStringToJSONSchema(PlacementSwarmSchema).nullable(), - updateConfigSwarm: createStringToJSONSchema( - UpdateConfigSwarmSchema, - ).nullable(), - rollbackConfigSwarm: createStringToJSONSchema( - UpdateConfigSwarmSchema, - ).nullable(), - modeSwarm: createStringToJSONSchema(ServiceModeSwarmSchema).nullable(), - labelsSwarm: createStringToJSONSchema(LabelsSwarmSchema).nullable(), - networkSwarm: createStringToJSONSchema(NetworkSwarmSchema).nullable(), - stopGracePeriodSwarm: z.bigint().nullable(), - endpointSpecSwarm: createStringToJSONSchema( - EndpointSpecSwarmSchema, - ).nullable(), -}); - -type AddSwarmSettings = z.infer; +const menuItems: MenuItem[] = [ + { + id: "health-check", + label: "Health Check", + description: "Configure health check settings", + docDescription: + "Configure HEALTHCHECK to test a container's health. Determines if a container is healthy by running a command inside the container. Test, Interval, Timeout, StartPeriod, and Retries control health monitoring.", + }, + { + id: "restart-policy", + label: "Restart Policy", + description: "Configure restart policy", + docDescription: + "Configure the restart policy for containers in the service. Condition (none, on-failure, any), Delay (nanoseconds between restarts), MaxAttempts, and Window control restart behavior.", + }, + { + id: "placement", + label: "Placement", + description: "Configure placement constraints", + docDescription: + "Control which nodes service tasks can be scheduled on. Constraints (node.id==xyz), Preferences (spread.node.labels.zone), MaxReplicas, and Platforms specify task placement rules.", + }, + { + id: "update-config", + label: "Update Config", + description: "Configure update strategy", + docDescription: + "Configure how the service should be updated. Parallelism (tasks updated simultaneously), Delay, FailureAction (pause, continue, rollback), Monitor, MaxFailureRatio, and Order (stop-first, start-first) control updates.", + }, + { + id: "rollback-config", + label: "Rollback Config", + description: "Configure rollback strategy", + docDescription: + "Configure automated rollback on update failure. Uses same parameters as UpdateConfig: Parallelism, Delay, FailureAction, Monitor, MaxFailureRatio, and Order.", + }, + { + id: "mode", + label: "Mode", + description: "Configure service mode", + docDescription: + "Set service mode to either 'Replicated' with a specified number of tasks (Replicas), or 'Global' (one task per node).", + }, + { + id: "labels", + label: "Labels", + description: "Configure service labels", + docDescription: + "Add metadata to services using labels. Labels are key-value pairs (e.g., com.example.foo=bar) for organizing and filtering services.", + }, + { + id: "stop-grace-period", + label: "Stop Grace Period", + description: "Configure stop grace period", + docDescription: + "Time to wait before forcefully killing a container. Specified in nanoseconds (e.g., 10000000000 = 10 seconds). Allows containers to shutdown gracefully.", + }, + { + id: "endpoint-spec", + label: "Endpoint Spec", + description: "Configure endpoint specification", + docDescription: + "Configure endpoint mode for service discovery. Mode 'vip' (virtual IP - default) uses a single virtual IP. Mode 'dnsrr' (DNS round-robin) returns DNS entries for all tasks.", + }, +]; const hasStopGracePeriodSwarm = ( value: unknown, @@ -214,137 +115,23 @@ interface Props { } export const AddSwarmSettings = ({ id, type }: Props) => { - const queryMap = { - postgres: () => - api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), - redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), - mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), - mariadb: () => - api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), - application: () => - api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), - mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), - }; - const { data, refetch } = queryMap[type] - ? queryMap[type]() - : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); - - const mutationMap = { - postgres: () => api.postgres.update.useMutation(), - redis: () => api.redis.update.useMutation(), - mysql: () => api.mysql.update.useMutation(), - mariadb: () => api.mariadb.update.useMutation(), - application: () => api.application.update.useMutation(), - mongo: () => api.mongo.update.useMutation(), - }; - - const { mutateAsync, isError, error, isLoading } = mutationMap[type] - ? mutationMap[type]() - : api.mongo.update.useMutation(); - - const form = useForm({ - defaultValues: { - healthCheckSwarm: null, - restartPolicySwarm: null, - placementSwarm: null, - updateConfigSwarm: null, - rollbackConfigSwarm: null, - modeSwarm: null, - labelsSwarm: null, - networkSwarm: null, - stopGracePeriodSwarm: null, - endpointSpecSwarm: null, - }, - resolver: zodResolver(addSwarmSettings), - }); - - useEffect(() => { - if (data) { - const stopGracePeriodValue = hasStopGracePeriodSwarm(data) - ? data.stopGracePeriodSwarm - : null; - const normalizedStopGracePeriod = - stopGracePeriodValue === null || stopGracePeriodValue === undefined - ? null - : typeof stopGracePeriodValue === "bigint" - ? stopGracePeriodValue - : BigInt(stopGracePeriodValue); - form.reset({ - healthCheckSwarm: data.healthCheckSwarm - ? JSON.stringify(data.healthCheckSwarm, null, 2) - : null, - restartPolicySwarm: data.restartPolicySwarm - ? JSON.stringify(data.restartPolicySwarm, null, 2) - : null, - placementSwarm: data.placementSwarm - ? JSON.stringify(data.placementSwarm, null, 2) - : null, - updateConfigSwarm: data.updateConfigSwarm - ? JSON.stringify(data.updateConfigSwarm, null, 2) - : null, - rollbackConfigSwarm: data.rollbackConfigSwarm - ? JSON.stringify(data.rollbackConfigSwarm, null, 2) - : null, - modeSwarm: data.modeSwarm - ? JSON.stringify(data.modeSwarm, null, 2) - : null, - labelsSwarm: data.labelsSwarm - ? JSON.stringify(data.labelsSwarm, null, 2) - : null, - networkSwarm: data.networkSwarm - ? JSON.stringify(data.networkSwarm, null, 2) - : null, - stopGracePeriodSwarm: normalizedStopGracePeriod, - endpointSpecSwarm: data.endpointSpecSwarm - ? JSON.stringify(data.endpointSpecSwarm, null, 2) - : null, - }); - } - }, [form, form.reset, data]); - - const onSubmit = async (data: AddSwarmSettings) => { - await mutateAsync({ - applicationId: id || "", - postgresId: id || "", - redisId: id || "", - mysqlId: id || "", - mariadbId: id || "", - mongoId: id || "", - healthCheckSwarm: data.healthCheckSwarm, - restartPolicySwarm: data.restartPolicySwarm, - placementSwarm: data.placementSwarm, - updateConfigSwarm: data.updateConfigSwarm, - rollbackConfigSwarm: data.rollbackConfigSwarm, - modeSwarm: data.modeSwarm, - labelsSwarm: data.labelsSwarm, - networkSwarm: data.networkSwarm, - stopGracePeriodSwarm: data.stopGracePeriodSwarm ?? null, - endpointSpecSwarm: data.endpointSpecSwarm, - }) - .then(async () => { - toast.success("Swarm settings updated"); - refetch(); - }) - .catch(() => { - toast.error("Error updating the swarm settings"); - }); - }; + const [activeMenu, setActiveMenu] = useState("health-check"); + const [open, setOpen] = useState(false); return ( - + - + Swarm Settings - Update certain settings using a json object. + Configure swarm settings for your service. - {isError && {error?.message}}
Changing settings such as placements may cause the logs/monitoring, @@ -352,596 +139,66 @@ export const AddSwarmSettings = ({ id, type }: Props) => {
-
- - ( - - Health Check - - - - - Check the interface - - - - + {/* Left Column - Menu */} +
+ +
- - - -
-										
-									
-
- )} - /> - - ( - - Restart Policy - - - - - Check the interface - - - - - -
-														{`{
-	Condition?: string | undefined;
-	Delay?: number | undefined;
-	MaxAttempts?: number | undefined;
-	Window?: number | undefined;
-}`}
-													
-
-
-
-
- - - - -
-										
-									
-
- )} - /> - - ( - - Placement - - - - - Check the interface - - - - - -
-														{`{
-	Constraints?: string[] | undefined;
-	Preferences?: Array<{ Spread: { SpreadDescriptor: string } }> | undefined;
-	MaxReplicas?: number | undefined;
-	Platforms?:
-		| Array<{
-				Architecture: string;
-				OS: string;
-		  }>
-		| undefined;
-}`}
-													
-
-
-
-
- - - - -
-										
-									
-
- )} - /> - - ( - - Update Config - - - - - Check the interface - - - - - -
-														{`{
-	Parallelism?: number;
-	Delay?: number | undefined;
-	FailureAction?: string | undefined;
-	Monitor?: number | undefined;
-	MaxFailureRatio?: number | undefined;
-	Order: string;
-}`}
-													
-
-
-
-
- - - - -
-										
-									
-
- )} - /> - - ( - - Rollback Config - - - - - Check the interface - - - - - -
-														{`{
-	Parallelism?: number;
-	Delay?: number | undefined;
-	FailureAction?: string | undefined;
-	Monitor?: number | undefined;
-	MaxFailureRatio?: number | undefined;
-	Order: string;
-}`}
-													
-
-
-
-
- - - - -
-										
-									
-
- )} - /> - - ( - - Mode - - - - - Check the interface - - - - - -
-														{`{
-	Replicated?: { Replicas?: number | undefined } | undefined;
-	Global?: {} | undefined;
-	ReplicatedJob?:
-		| {
-				MaxConcurrent?: number | undefined;
-				TotalCompletions?: number | undefined;
-		  }
-		| undefined;
-	GlobalJob?: {} | undefined;
-}`}
-													
-
-
-
-
- - - - -
-										
-									
-
- )} - /> - ( - - Network - - - - - Check the interface - - - - - -
-														{`[
-  {
-	"Target" : string | undefined;
-	"Aliases" : string[] | undefined;
-	"DriverOpts" : { [key: string]: string } | undefined;
-  }
-]`}
-													
-
-
-
-
- - - -
-										
-									
-
- )} - /> - ( - - Labels - - - - - Check the interface - - - - - -
-														{`{
-	[name: string]: string;
-}`}
-													
-
-
-
-
- - - -
-										
-									
-
- )} - /> - ( - - Stop Grace Period (nanoseconds) - - - - - Duration in nanoseconds - - - - - -
-														{`Enter duration in nanoseconds:
-														• 30000000000 - 30 seconds
-														• 120000000000 - 2 minutes  
-														• 3600000000000 - 1 hour
-														• 0 - no grace period`}
-													
-
-
-
-
- - - field.onChange( - e.target.value ? BigInt(e.target.value) : null, - ) - } - /> - -
-										
-									
-
- )} - /> - ( - - Endpoint Spec - - - - - Check the interface - - - - - -
-														{`{
-	Mode?: string | undefined;
-	Ports?: Array<{
-		Protocol?: string | undefined;
-		TargetPort?: number | undefined;
-		PublishedPort?: number | undefined;
-		PublishMode?: string | undefined;
-	}> | undefined;
-}`}
-													
-
-
-
-
- - - - -
-										
-									
-
- )} - /> - - - - - + {/* Right Column - Form */} +
+ {activeMenu === "health-check" && ( + + )} + {activeMenu === "restart-policy" && ( + + )} + {activeMenu === "placement" && ( + + )} + {activeMenu === "update-config" && ( + + )} + {activeMenu === "rollback-config" && ( + + )} + {activeMenu === "mode" && } + {activeMenu === "labels" && } + {activeMenu === "stop-grace-period" && ( + + )} + {activeMenu === "endpoint-spec" && ( + + )} +
+
); diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/endpoint-spec-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/endpoint-spec-form.tsx new file mode 100644 index 000000000..7ee31e5b6 --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/endpoint-spec-form.tsx @@ -0,0 +1,154 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { api } from "@/utils/api"; + +export const endpointSpecFormSchema = z.object({ + Mode: z.string().optional(), +}); + +interface EndpointSpecFormProps { + id: string; + type: "postgres" | "mariadb" | "mongo" | "mysql" | "redis" | "application"; +} + +export const EndpointSpecForm = ({ id, type }: EndpointSpecFormProps) => { + const [isLoading, setIsLoading] = useState(false); + + const queryMap = { + postgres: () => + api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), + redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), + mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), + mariadb: () => + api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), + application: () => + api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), + mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), + }; + const { data, refetch } = queryMap[type] + ? queryMap[type]() + : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); + + const mutationMap = { + postgres: () => api.postgres.update.useMutation(), + redis: () => api.redis.update.useMutation(), + mysql: () => api.mysql.update.useMutation(), + mariadb: () => api.mariadb.update.useMutation(), + application: () => api.application.update.useMutation(), + mongo: () => api.mongo.update.useMutation(), + }; + + const { mutateAsync } = mutationMap[type] + ? mutationMap[type]() + : api.mongo.update.useMutation(); + + const form = useForm({ + resolver: zodResolver(endpointSpecFormSchema), + defaultValues: { + Mode: undefined, + }, + }); + + useEffect(() => { + if (data?.endpointSpecSwarm) { + const es = data.endpointSpecSwarm; + form.reset({ + Mode: es.Mode, + }); + } + }, [data, form]); + + const onSubmit = async (formData: z.infer) => { + setIsLoading(true); + try { + // Check if all values are empty, if so, send null to clear the database + const hasAnyValue = + formData.Mode !== undefined && + formData.Mode !== null && + formData.Mode !== ""; + + await mutateAsync({ + applicationId: id || "", + postgresId: id || "", + redisId: id || "", + mysqlId: id || "", + mariadbId: id || "", + mongoId: id || "", + endpointSpecSwarm: hasAnyValue ? formData : null, + }); + + toast.success("Endpoint spec updated successfully"); + refetch(); + } catch { + toast.error("Error updating endpoint spec"); + } finally { + setIsLoading(false); + } + }; + + return ( +
+ + ( + + Mode + Endpoint mode (vip or dnsrr) + + + + )} + /> + +
+ + +
+ + + ); +}; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/health-check-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/health-check-form.tsx new file mode 100644 index 000000000..b2fc49ef3 --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/health-check-form.tsx @@ -0,0 +1,267 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { api } from "@/utils/api"; + +export const healthCheckFormSchema = z.object({ + Test: z.array(z.string()).optional(), + Interval: z.coerce.number().optional(), + Timeout: z.coerce.number().optional(), + StartPeriod: z.coerce.number().optional(), + Retries: z.coerce.number().optional(), +}); + +interface HealthCheckFormProps { + id: string; + type: "postgres" | "mariadb" | "mongo" | "mysql" | "redis" | "application"; +} + +export const HealthCheckForm = ({ id, type }: HealthCheckFormProps) => { + const [isLoading, setIsLoading] = useState(false); + const [testCommands, setTestCommands] = useState([]); + + const queryMap = { + postgres: () => + api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), + redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), + mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), + mariadb: () => + api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), + application: () => + api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), + mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), + }; + const { data, refetch } = queryMap[type] + ? queryMap[type]() + : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); + + const mutationMap = { + postgres: () => api.postgres.update.useMutation(), + redis: () => api.redis.update.useMutation(), + mysql: () => api.mysql.update.useMutation(), + mariadb: () => api.mariadb.update.useMutation(), + application: () => api.application.update.useMutation(), + mongo: () => api.mongo.update.useMutation(), + }; + + const { mutateAsync } = mutationMap[type] + ? mutationMap[type]() + : api.mongo.update.useMutation(); + + const form = useForm({ + resolver: zodResolver(healthCheckFormSchema), + defaultValues: { + Test: [], + Interval: undefined, + Timeout: undefined, + StartPeriod: undefined, + Retries: undefined, + }, + }); + + useEffect(() => { + if (data?.healthCheckSwarm) { + const hc = data.healthCheckSwarm; + form.reset({ + Test: hc.Test || [], + Interval: hc.Interval, + Timeout: hc.Timeout, + StartPeriod: hc.StartPeriod, + Retries: hc.Retries, + }); + setTestCommands(hc.Test || []); + } + }, [data, form]); + + const onSubmit = async (formData: z.infer) => { + setIsLoading(true); + try { + // Check if all values are empty, if so, send null to clear the database + const hasAnyValue = + (formData.Test && formData.Test.length > 0) || + formData.Interval !== undefined || + formData.Timeout !== undefined || + formData.StartPeriod !== undefined || + formData.Retries !== undefined; + + await mutateAsync({ + applicationId: id || "", + postgresId: id || "", + redisId: id || "", + mysqlId: id || "", + mariadbId: id || "", + mongoId: id || "", + healthCheckSwarm: hasAnyValue ? formData : null, + }); + + toast.success("Health check updated successfully"); + refetch(); + } catch { + toast.error("Error updating health check"); + } finally { + setIsLoading(false); + } + }; + + const addTestCommand = () => { + setTestCommands([...testCommands, ""]); + }; + + const updateTestCommand = (index: number, value: string) => { + const newCommands = [...testCommands]; + newCommands[index] = value; + setTestCommands(newCommands); + }; + + const removeTestCommand = (index: number) => { + setTestCommands(testCommands.filter((_, i) => i !== index)); + }; + + return ( +
+ +
+ Test Commands + + Command to run for health check (e.g., ["CMD-SHELL", "curl -f + http://localhost:3000/health"]) + +
+ {testCommands.map((cmd, index) => ( +
+ updateTestCommand(index, e.target.value)} + placeholder={ + index === 0 + ? "CMD-SHELL" + : "curl -f http://localhost:3000/health" + } + /> + +
+ ))} + +
+
+ + ( + + Interval (nanoseconds) + + Time between health checks (e.g., 10000000000 for 10 seconds) + + + + + + + )} + /> + + ( + + Timeout (nanoseconds) + + Maximum time to wait for health check response + + + + + + + )} + /> + + ( + + Start Period (nanoseconds) + + Initial grace period before health checks begin + + + + + + + )} + /> + + ( + + Retries + + Number of consecutive failures needed to consider container + unhealthy + + + + + + + )} + /> + +
+ + +
+ + + ); +}; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/index.ts b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/index.ts new file mode 100644 index 000000000..ebd00abcd --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/index.ts @@ -0,0 +1,10 @@ +export { HealthCheckForm } from "./health-check-form"; +export { RestartPolicyForm } from "./restart-policy-form"; +export { PlacementForm } from "./placement-form"; +export { UpdateConfigForm } from "./update-config-form"; +export { RollbackConfigForm } from "./rollback-config-form"; +export { ModeForm } from "./mode-form"; +export { LabelsForm } from "./labels-form"; +export { StopGracePeriodForm } from "./stop-grace-period-form"; +export { EndpointSpecForm } from "./endpoint-spec-form"; +export { filterEmptyValues, hasValues } from "./utils"; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/labels-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/labels-form.tsx new file mode 100644 index 000000000..d1681dcd0 --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/labels-form.tsx @@ -0,0 +1,200 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect, useState } from "react"; +import { useFieldArray, useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { api } from "@/utils/api"; + +export const labelsFormSchema = z.object({ + labels: z + .array( + z.object({ + key: z.string(), + value: z.string(), + }), + ) + .optional(), +}); + +interface LabelsFormProps { + id: string; + type: "postgres" | "mariadb" | "mongo" | "mysql" | "redis" | "application"; +} + +export const LabelsForm = ({ id, type }: LabelsFormProps) => { + const [isLoading, setIsLoading] = useState(false); + + const queryMap = { + postgres: () => + api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), + redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), + mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), + mariadb: () => + api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), + application: () => + api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), + mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), + }; + const { data, refetch } = queryMap[type] + ? queryMap[type]() + : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); + + const mutationMap = { + postgres: () => api.postgres.update.useMutation(), + redis: () => api.redis.update.useMutation(), + mysql: () => api.mysql.update.useMutation(), + mariadb: () => api.mariadb.update.useMutation(), + application: () => api.application.update.useMutation(), + mongo: () => api.mongo.update.useMutation(), + }; + + const { mutateAsync } = mutationMap[type] + ? mutationMap[type]() + : api.mongo.update.useMutation(); + + const form = useForm({ + resolver: zodResolver(labelsFormSchema), + defaultValues: { + labels: [], + }, + }); + + const { fields, append, remove } = useFieldArray({ + control: form.control, + name: "labels", + }); + + useEffect(() => { + if (data?.labelsSwarm && typeof data.labelsSwarm === "object") { + const labelEntries = Object.entries(data.labelsSwarm).map( + ([key, value]) => ({ + key, + value: value as string, + }), + ); + form.reset({ labels: labelEntries }); + } + }, [data, form]); + + const onSubmit = async (formData: z.infer) => { + setIsLoading(true); + try { + const labelsObject = + formData.labels?.reduce( + (acc, { key, value }) => { + if (key && value) { + acc[key] = value; + } + return acc; + }, + {} as Record, + ) || {}; + + // If no labels, send null to clear the database + const labelsToSend = + Object.keys(labelsObject).length > 0 ? labelsObject : null; + + await mutateAsync({ + applicationId: id || "", + postgresId: id || "", + redisId: id || "", + mysqlId: id || "", + mariadbId: id || "", + mongoId: id || "", + labelsSwarm: labelsToSend, + }); + + toast.success("Labels updated successfully"); + refetch(); + } catch { + toast.error("Error updating labels"); + } finally { + setIsLoading(false); + } + }; + + return ( +
+ +
+ Labels + + Add key-value labels to your service + +
+ {fields.map((field, index) => ( +
+ ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + +
+ ))} + +
+
+ +
+ + +
+
+ + ); +}; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/mode-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/mode-form.tsx new file mode 100644 index 000000000..839f5d519 --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/mode-form.tsx @@ -0,0 +1,195 @@ +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { api } from "@/utils/api"; + +interface ModeFormProps { + id: string; + type: "postgres" | "mariadb" | "mongo" | "mysql" | "redis" | "application"; +} + +export const ModeForm = ({ id, type }: ModeFormProps) => { + const [isLoading, setIsLoading] = useState(false); + + const queryMap = { + postgres: () => + api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), + redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), + mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), + mariadb: () => + api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), + application: () => + api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), + mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), + }; + const { data, refetch } = queryMap[type] + ? queryMap[type]() + : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); + + const mutationMap = { + postgres: () => api.postgres.update.useMutation(), + redis: () => api.redis.update.useMutation(), + mysql: () => api.mysql.update.useMutation(), + mariadb: () => api.mariadb.update.useMutation(), + application: () => api.application.update.useMutation(), + mongo: () => api.mongo.update.useMutation(), + }; + + const { mutateAsync } = mutationMap[type] + ? mutationMap[type]() + : api.mongo.update.useMutation(); + + const form = useForm({ + defaultValues: { + type: undefined, + Replicas: undefined, + }, + }); + + const modeType = form.watch("type"); + + useEffect(() => { + if (data?.modeSwarm) { + const mode = data.modeSwarm; + if (mode.Replicated) { + form.reset({ + type: "Replicated", + Replicas: mode.Replicated.Replicas, + }); + } else if (mode.Global) { + form.reset({ + type: "Global", + Replicas: undefined, + }); + } + } + }, [data, form]); + + const onSubmit = async (formData: any) => { + setIsLoading(true); + try { + // If no type is selected, send null to clear the database + if (!formData.type) { + await mutateAsync({ + applicationId: id || "", + postgresId: id || "", + redisId: id || "", + mysqlId: id || "", + mariadbId: id || "", + mongoId: id || "", + modeSwarm: null, + }); + toast.success("Mode updated successfully"); + refetch(); + setIsLoading(false); + return; + } + + const modeData = + formData.type === "Replicated" + ? { Replicated: { Replicas: formData.Replicas } } + : { Global: {} }; + + await mutateAsync({ + applicationId: id || "", + postgresId: id || "", + redisId: id || "", + mysqlId: id || "", + mariadbId: id || "", + mongoId: id || "", + modeSwarm: modeData, + }); + + toast.success("Mode updated successfully"); + refetch(); + } catch { + toast.error("Error updating mode"); + } finally { + setIsLoading(false); + } + }; + + return ( +
+ + ( + + Mode Type + + Choose between replicated or global service mode + + + + + )} + /> + + {modeType === "Replicated" && ( + ( + + Replicas + Number of replicas to run + + + + + + )} + /> + )} + +
+ + +
+ + + ); +}; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/placement-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/placement-form.tsx new file mode 100644 index 000000000..b0c354513 --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/placement-form.tsx @@ -0,0 +1,342 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { api } from "@/utils/api"; + +const PreferenceSchema = z.object({ + Spread: z.object({ + SpreadDescriptor: z.string(), + }), +}); + +const PlatformSchema = z.object({ + Architecture: z.string(), + OS: z.string(), +}); + +export const placementFormSchema = z.object({ + Constraints: z.array(z.string()).optional(), + Preferences: z.array(PreferenceSchema).optional(), + MaxReplicas: z.coerce.number().optional(), + Platforms: z.array(PlatformSchema).optional(), +}); + +interface PlacementFormProps { + id: string; + type: "postgres" | "mariadb" | "mongo" | "mysql" | "redis" | "application"; +} + +export const PlacementForm = ({ id, type }: PlacementFormProps) => { + const [isLoading, setIsLoading] = useState(false); + + const queryMap = { + postgres: () => + api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), + redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), + mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), + mariadb: () => + api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), + application: () => + api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), + mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), + }; + const { data, refetch } = queryMap[type] + ? queryMap[type]() + : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); + + const mutationMap = { + postgres: () => api.postgres.update.useMutation(), + redis: () => api.redis.update.useMutation(), + mysql: () => api.mysql.update.useMutation(), + mariadb: () => api.mariadb.update.useMutation(), + application: () => api.application.update.useMutation(), + mongo: () => api.mongo.update.useMutation(), + }; + + const { mutateAsync } = mutationMap[type] + ? mutationMap[type]() + : api.mongo.update.useMutation(); + + const form = useForm({ + resolver: zodResolver(placementFormSchema), + defaultValues: { + Constraints: [], + Preferences: [], + MaxReplicas: undefined, + Platforms: [], + }, + }); + + const constraints = form.watch("Constraints") || []; + const preferences = form.watch("Preferences") || []; + const platforms = form.watch("Platforms") || []; + + useEffect(() => { + if (data?.placementSwarm) { + const placement = data.placementSwarm; + form.reset({ + Constraints: placement.Constraints || [], + Preferences: + placement.Preferences?.map((p: any) => ({ + SpreadDescriptor: p.Spread?.SpreadDescriptor || "", + })) || [], + MaxReplicas: placement.MaxReplicas, + Platforms: placement.Platforms || [], + }); + } + }, [data, form]); + + const onSubmit = async (formData: z.infer) => { + setIsLoading(true); + try { + // Check if all values are empty, if so, send null to clear the database + const hasAnyValue = + (formData.Constraints && formData.Constraints.length > 0) || + (formData.Preferences && formData.Preferences.length > 0) || + (formData.Platforms && formData.Platforms.length > 0) || + formData.MaxReplicas !== undefined; + + await mutateAsync({ + applicationId: id || "", + postgresId: id || "", + redisId: id || "", + mysqlId: id || "", + mariadbId: id || "", + mongoId: id || "", + placementSwarm: hasAnyValue ? formData : null, + }); + + toast.success("Placement updated successfully"); + refetch(); + } catch { + toast.error("Error updating placement"); + } finally { + setIsLoading(false); + } + }; + + const addConstraint = () => { + form.setValue("Constraints", [...constraints, ""]); + }; + + const updateConstraint = (index: number, value: string) => { + const newConstraints = [...constraints]; + newConstraints[index] = value; + form.setValue("Constraints", newConstraints); + }; + + const removeConstraint = (index: number) => { + form.setValue( + "Constraints", + constraints.filter((_: string, i: number) => i !== index), + ); + }; + + const addPreference = () => { + form.setValue("Preferences", [...preferences, { SpreadDescriptor: "" }]); + }; + + const updatePreference = (index: number, value: string) => { + const newPreferences = [...preferences]; + if (newPreferences[index]) { + newPreferences[index].SpreadDescriptor = value; + form.setValue("Preferences", newPreferences); + } + }; + + const removePreference = (index: number) => { + form.setValue( + "Preferences", + preferences.filter((_: any, i: number) => i !== index), + ); + }; + + const addPlatform = () => { + form.setValue("Platforms", [...platforms, { Architecture: "", OS: "" }]); + }; + + const updatePlatform = ( + index: number, + field: "Architecture" | "OS", + value: string, + ) => { + const newPlatforms = [...platforms]; + if (newPlatforms[index]) { + newPlatforms[index][field] = value; + form.setValue("Platforms", newPlatforms); + } + }; + + const removePlatform = (index: number) => { + form.setValue( + "Platforms", + platforms.filter((_: any, i: number) => i !== index), + ); + }; + + return ( +
+ +
+ Constraints + + Placement constraints (e.g., "node.role==manager") + +
+ {constraints.map((constraint: string, index: number) => ( +
+ updateConstraint(index, e.target.value)} + placeholder="node.role==manager" + /> + +
+ ))} + +
+
+ +
+ Preferences + + Spread preferences for task distribution (e.g., + "node.labels.region") + +
+ {preferences.map((pref: any, index: number) => ( +
+ updatePreference(index, e.target.value)} + placeholder="node.labels.region" + /> + +
+ ))} + +
+
+ + ( + + Max Replicas + + Maximum number of replicas per node + + + + + + + )} + /> + +
+ Platforms + + Target platforms for task scheduling + +
+ {platforms.map((platform: any, index: number) => ( +
+ + updatePlatform(index, "Architecture", e.target.value) + } + placeholder="amd64" + /> + updatePlatform(index, "OS", e.target.value)} + placeholder="linux" + /> + +
+ ))} + +
+
+ +
+ + +
+ + + ); +}; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/restart-policy-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/restart-policy-form.tsx new file mode 100644 index 000000000..b7fb649be --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/restart-policy-form.tsx @@ -0,0 +1,219 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { api } from "@/utils/api"; + +export const restartPolicyFormSchema = z.object({ + Condition: z.string().optional(), + Delay: z.coerce.number().optional(), + MaxAttempts: z.coerce.number().optional(), + Window: z.coerce.number().optional(), +}); + +interface RestartPolicyFormProps { + id: string; + type: "postgres" | "mariadb" | "mongo" | "mysql" | "redis" | "application"; +} + +export const RestartPolicyForm = ({ id, type }: RestartPolicyFormProps) => { + const [isLoading, setIsLoading] = useState(false); + + const queryMap = { + postgres: () => + api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), + redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), + mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), + mariadb: () => + api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), + application: () => + api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), + mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), + }; + const { data, refetch } = queryMap[type] + ? queryMap[type]() + : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); + + const mutationMap = { + postgres: () => api.postgres.update.useMutation(), + redis: () => api.redis.update.useMutation(), + mysql: () => api.mysql.update.useMutation(), + mariadb: () => api.mariadb.update.useMutation(), + application: () => api.application.update.useMutation(), + mongo: () => api.mongo.update.useMutation(), + }; + + const { mutateAsync } = mutationMap[type] + ? mutationMap[type]() + : api.mongo.update.useMutation(); + + const form = useForm({ + resolver: zodResolver(restartPolicyFormSchema), + defaultValues: { + Condition: undefined, + Delay: undefined, + MaxAttempts: undefined, + Window: undefined, + }, + }); + + useEffect(() => { + if (data?.restartPolicySwarm) { + form.reset({ + Condition: data.restartPolicySwarm.Condition, + Delay: data.restartPolicySwarm.Delay, + MaxAttempts: data.restartPolicySwarm.MaxAttempts, + Window: data.restartPolicySwarm.Window, + }); + } + }, [data, form]); + + const onSubmit = async ( + formData: z.infer, + ) => { + setIsLoading(true); + try { + // Check if all values are empty, if so, send null to clear the database + const hasAnyValue = Object.values(formData).some( + (value) => value !== undefined && value !== null && value !== "", + ); + + await mutateAsync({ + applicationId: id || "", + postgresId: id || "", + redisId: id || "", + mysqlId: id || "", + mariadbId: id || "", + mongoId: id || "", + restartPolicySwarm: hasAnyValue ? formData : null, + }); + + toast.success("Restart policy updated successfully"); + refetch(); + } catch { + toast.error("Error updating restart policy"); + } finally { + setIsLoading(false); + } + }; + + return ( +
+ + ( + + Condition + When to restart the container + + + + )} + /> + + ( + + Delay (nanoseconds) + + Wait time between restart attempts + + + + + + + )} + /> + + ( + + Max Attempts + + Maximum number of restart attempts + + + + + + + )} + /> + + ( + + Window (nanoseconds) + + Time window to evaluate restart policy + + + + + + + )} + /> + +
+ + +
+ + + ); +}; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/rollback-config-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/rollback-config-form.tsx new file mode 100644 index 000000000..d53215348 --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/rollback-config-form.tsx @@ -0,0 +1,257 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { api } from "@/utils/api"; + +export const rollbackConfigFormSchema = z.object({ + Parallelism: z.coerce.number().optional(), + Delay: z.coerce.number().optional(), + FailureAction: z.string().optional(), + Monitor: z.coerce.number().optional(), + MaxFailureRatio: z.coerce.number().optional(), + Order: z.string().optional(), +}); + +interface RollbackConfigFormProps { + id: string; + type: "postgres" | "mariadb" | "mongo" | "mysql" | "redis" | "application"; +} + +export const RollbackConfigForm = ({ id, type }: RollbackConfigFormProps) => { + const [isLoading, setIsLoading] = useState(false); + + const queryMap = { + postgres: () => + api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), + redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), + mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), + mariadb: () => + api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), + application: () => + api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), + mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), + }; + const { data, refetch } = queryMap[type] + ? queryMap[type]() + : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); + + const mutationMap = { + postgres: () => api.postgres.update.useMutation(), + redis: () => api.redis.update.useMutation(), + mysql: () => api.mysql.update.useMutation(), + mariadb: () => api.mariadb.update.useMutation(), + application: () => api.application.update.useMutation(), + mongo: () => api.mongo.update.useMutation(), + }; + + const { mutateAsync } = mutationMap[type] + ? mutationMap[type]() + : api.mongo.update.useMutation(); + + const form = useForm({ + resolver: zodResolver(rollbackConfigFormSchema), + defaultValues: { + Parallelism: undefined, + Delay: undefined, + FailureAction: undefined, + Monitor: undefined, + MaxFailureRatio: undefined, + Order: undefined, + }, + }); + + useEffect(() => { + if (data?.rollbackConfigSwarm) { + form.reset(data.rollbackConfigSwarm); + } + }, [data, form]); + + const onSubmit = async ( + formData: z.infer, + ) => { + setIsLoading(true); + try { + // Check if all values are empty, if so, send null to clear the database + const hasAnyValue = Object.values(formData).some( + (value) => value !== undefined && value !== null && value !== "", + ); + + await mutateAsync({ + applicationId: id || "", + postgresId: id || "", + redisId: id || "", + mysqlId: id || "", + mariadbId: id || "", + mongoId: id || "", + rollbackConfigSwarm: (hasAnyValue ? formData : null) as any, + }); + + toast.success("Rollback config updated successfully"); + refetch(); + } catch { + toast.error("Error updating rollback config"); + } finally { + setIsLoading(false); + } + }; + + return ( +
+ + ( + + Parallelism + + Number of tasks to rollback simultaneously + + + + + + + )} + /> + + ( + + Delay (nanoseconds) + Delay between task rollbacks + + + + + + )} + /> + + ( + + Failure Action + Action on rollback failure + + + + )} + /> + + ( + + Monitor (nanoseconds) + + Duration to monitor for failure after rollback + + + + + + + )} + /> + + ( + + Max Failure Ratio + + Maximum failure ratio tolerated (0-1) + + + + + + + )} + /> + + ( + + Order + Rollback order strategy + + + + )} + /> + +
+ + +
+ + + ); +}; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx new file mode 100644 index 000000000..a324da31b --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx @@ -0,0 +1,158 @@ +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { api } from "@/utils/api"; + +const hasStopGracePeriodSwarm = ( + value: unknown, +): value is { stopGracePeriodSwarm: bigint | number | string | null } => + typeof value === "object" && + value !== null && + "stopGracePeriodSwarm" in value; + +interface StopGracePeriodFormProps { + id: string; + type: "postgres" | "mariadb" | "mongo" | "mysql" | "redis" | "application"; +} + +export const StopGracePeriodForm = ({ id, type }: StopGracePeriodFormProps) => { + const [isLoading, setIsLoading] = useState(false); + + const queryMap = { + postgres: () => + api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), + redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), + mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), + mariadb: () => + api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), + application: () => + api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), + mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), + }; + const { data, refetch } = queryMap[type] + ? queryMap[type]() + : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); + + const mutationMap = { + postgres: () => api.postgres.update.useMutation(), + redis: () => api.redis.update.useMutation(), + mysql: () => api.mysql.update.useMutation(), + mariadb: () => api.mariadb.update.useMutation(), + application: () => api.application.update.useMutation(), + mongo: () => api.mongo.update.useMutation(), + }; + + const { mutateAsync } = mutationMap[type] + ? mutationMap[type]() + : api.mongo.update.useMutation(); + + const form = useForm({ + defaultValues: { + value: null as bigint | null, + }, + }); + + useEffect(() => { + if (hasStopGracePeriodSwarm(data)) { + const value = data.stopGracePeriodSwarm; + const normalizedValue = + value === null || value === undefined + ? null + : typeof value === "bigint" + ? value + : BigInt(value); + form.reset({ + value: normalizedValue, + }); + } + }, [data, form]); + + const onSubmit = async (formData: any) => { + setIsLoading(true); + try { + await mutateAsync({ + applicationId: id || "", + postgresId: id || "", + redisId: id || "", + mysqlId: id || "", + mariadbId: id || "", + mongoId: id || "", + stopGracePeriodSwarm: formData.value, + }); + + toast.success("Stop grace period updated successfully"); + refetch(); + } catch { + toast.error("Error updating stop grace period"); + } finally { + setIsLoading(false); + } + }; + + return ( +
+ + ( + + Stop Grace Period (nanoseconds) + + Time to wait before forcefully killing the container +
+ Examples: 30000000000 (30s), 120000000000 (2m) +
+ + + field.onChange( + e.target.value ? BigInt(e.target.value) : null, + ) + } + /> + + +
+ )} + /> + +
+ + +
+ + + ); +}; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/update-config-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/update-config-form.tsx new file mode 100644 index 000000000..4119c41f8 --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/update-config-form.tsx @@ -0,0 +1,264 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { api } from "@/utils/api"; + +export const updateConfigFormSchema = z.object({ + Parallelism: z.coerce.number().optional(), + Delay: z.coerce.number().optional(), + FailureAction: z.string().optional(), + Monitor: z.coerce.number().optional(), + MaxFailureRatio: z.coerce.number().optional(), + Order: z.string().optional(), +}); + +interface UpdateConfigFormProps { + id: string; + type: "postgres" | "mariadb" | "mongo" | "mysql" | "redis" | "application"; +} + +export const UpdateConfigForm = ({ id, type }: UpdateConfigFormProps) => { + const [isLoading, setIsLoading] = useState(false); + + const queryMap = { + postgres: () => + api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }), + redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }), + mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }), + mariadb: () => + api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }), + application: () => + api.application.one.useQuery({ applicationId: id }, { enabled: !!id }), + mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }), + }; + const { data, refetch } = queryMap[type] + ? queryMap[type]() + : api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }); + + const mutationMap = { + postgres: () => api.postgres.update.useMutation(), + redis: () => api.redis.update.useMutation(), + mysql: () => api.mysql.update.useMutation(), + mariadb: () => api.mariadb.update.useMutation(), + application: () => api.application.update.useMutation(), + mongo: () => api.mongo.update.useMutation(), + }; + + const { mutateAsync } = mutationMap[type] + ? mutationMap[type]() + : api.mongo.update.useMutation(); + + const form = useForm({ + resolver: zodResolver(updateConfigFormSchema), + defaultValues: { + Parallelism: undefined, + Delay: undefined, + FailureAction: undefined, + Monitor: undefined, + MaxFailureRatio: undefined, + Order: undefined, + }, + }); + + useEffect(() => { + if (data?.updateConfigSwarm) { + const config = data.updateConfigSwarm; + form.reset({ + Parallelism: config.Parallelism, + Delay: config.Delay, + FailureAction: config.FailureAction, + Monitor: config.Monitor, + MaxFailureRatio: config.MaxFailureRatio, + Order: config.Order, + }); + } + }, [data, form]); + + const onSubmit = async (formData: z.infer) => { + setIsLoading(true); + try { + // Check if all values are empty, if so, send null to clear the database + const hasAnyValue = Object.values(formData).some( + (value) => value !== undefined && value !== null && value !== "", + ); + + await mutateAsync({ + applicationId: id || "", + postgresId: id || "", + redisId: id || "", + mysqlId: id || "", + mariadbId: id || "", + mongoId: id || "", + updateConfigSwarm: (hasAnyValue ? formData : null) as any, + }); + + toast.success("Update config updated successfully"); + refetch(); + } catch { + toast.error("Error updating update config"); + } finally { + setIsLoading(false); + } + }; + + return ( +
+ + ( + + Parallelism + + Number of tasks to update simultaneously + + + + + + + )} + /> + + ( + + Delay (nanoseconds) + Delay between task updates + + + + + + )} + /> + + ( + + Failure Action + Action on update failure + + + + )} + /> + + ( + + Monitor (nanoseconds) + + Duration to monitor for failure after update + + + + + + + )} + /> + + ( + + Max Failure Ratio + + Maximum failure ratio tolerated (0-1) + + + + + + + )} + /> + + ( + + Order + Update order strategy + + + + )} + /> + +
+ + +
+ + + ); +}; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/utils.ts b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/utils.ts new file mode 100644 index 000000000..58793c02e --- /dev/null +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/utils.ts @@ -0,0 +1,31 @@ +/** + * Filters out undefined, null, and empty string values from form data + * Only returns fields that have actual values + */ +export const filterEmptyValues = ( + formData: Record, +): Record => { + return Object.entries(formData).reduce( + (acc, [key, value]) => { + // Keep arrays even if empty (they might be intentionally cleared) + if (Array.isArray(value)) { + if (value.length > 0) { + acc[key] = value; + } + } + // For other values, filter out undefined, null, and empty strings + else if (value !== undefined && value !== null && value !== "") { + acc[key] = value; + } + return acc; + }, + {} as Record, + ); +}; + +/** + * Checks if filtered data has any values to save + */ +export const hasValues = (data: Record): boolean => { + return Object.keys(data).length > 0; +}; diff --git a/apps/dokploy/components/dashboard/application/build/show.tsx b/apps/dokploy/components/dashboard/application/build/show.tsx index 1a0ed386d..7f92157f2 100644 --- a/apps/dokploy/components/dashboard/application/build/show.tsx +++ b/apps/dokploy/components/dashboard/application/build/show.tsx @@ -1,6 +1,6 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { Cog } from "lucide-react"; -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { z } from "zod"; @@ -20,8 +20,39 @@ import { } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; import { api } from "@/utils/api"; +// Railpack versions from https://github.com/railwayapp/railpack/releases +export const RAILPACK_VERSIONS = [ + "0.15.4", + "0.15.3", + "0.15.2", + "0.15.1", + "0.15.0", + "0.14.0", + "0.13.0", + "0.12.0", + "0.11.0", + "0.10.0", + "0.9.2", + "0.9.1", + "0.9.0", + "0.8.0", + "0.7.0", + "0.6.0", + "0.5.0", + "0.4.0", + "0.3.0", + "0.2.2", +] as const; + export enum BuildType { dockerfile = "dockerfile", heroku_buildpacks = "heroku_buildpacks", @@ -65,7 +96,7 @@ const mySchema = z.discriminatedUnion("buildType", [ }), z.object({ buildType: z.literal(BuildType.railpack), - railpackVersion: z.string().nullable().default("0.2.2"), + railpackVersion: z.string().nullable().default("0.15.4"), }), z.object({ buildType: z.literal(BuildType.static), @@ -152,6 +183,8 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => { }); const buildType = form.watch("buildType"); + const railpackVersion = form.watch("railpackVersion"); + const [isManualRailpackVersion, setIsManualRailpackVersion] = useState(false); useEffect(() => { if (data) { @@ -163,9 +196,22 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => { }; form.reset(resetData(typedData)); + + // Check if railpack version is manual (not in the predefined list) + if ( + data.railpackVersion && + !RAILPACK_VERSIONS.includes(data.railpackVersion as any) + ) { + setIsManualRailpackVersion(true); + } } }, [data, form]); + // Hide builder section when Docker provider is selected + if (data?.sourceType === "docker") { + return null; + } + const onSubmit = async (data: AddTemplate) => { await mutateAsync({ applicationId, @@ -186,7 +232,7 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => { data.buildType === BuildType.static ? data.isStaticSpa : null, railpackVersion: data.buildType === BuildType.railpack - ? data.railpackVersion || "0.2.2" + ? data.railpackVersion || "0.15.4" : null, }) .then(async () => { @@ -403,23 +449,88 @@ export const ShowBuildChooseForm = ({ applicationId }: Props) => { /> )} {buildType === BuildType.railpack && ( - ( - - Railpack Version - - - - - - )} - /> + <> + ( + + Railpack Version + + {isManualRailpackVersion ? ( +
+ + +
+ ) : ( + + )} +
+ + Select a Railpack version or choose manual to enter a + custom version.{" "} + + View releases + + + +
+ )} + /> + )}
@@ -364,6 +365,7 @@ export const ShowDeployments = ({ onClick={() => { setActiveLog(deployment); }} + className="w-full sm:w-auto" > View @@ -405,6 +407,7 @@ export const ShowDeployments = ({ variant="secondary" size="sm" isLoading={isRollingBack} + className="w-full sm:w-auto" > Rollback 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 { mutateAsync: deletePreviewDeployment, isLoading } = api.previewDeployment.delete.useMutation(); + const { mutateAsync: redeployPreviewDeployment } = + api.previewDeployment.redeploy.useMutation(); + const { data: previewDeployments, refetch: refetchPreviewDeployments, @@ -46,6 +57,8 @@ export const ShowPreviewDeployments = ({ applicationId }: Props) => { { applicationId }, { enabled: !!applicationId, + refetchInterval: (data) => + data?.some((d) => d.previewStatus === "running") ? 2000 : false, }, ); @@ -193,6 +206,58 @@ export const ShowPreviewDeployments = ({ applicationId }: Props) => { + { + await redeployPreviewDeployment({ + previewDeploymentId: + deployment.previewDeploymentId, + }) + .then(() => { + toast.success( + "Preview deployment rebuild started", + ); + refetchPreviewDeployments(); + }) + .catch(() => { + toast.error( + "Error rebuilding preview deployment", + ); + }); + }} + > + + + { 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 && ( { type="password" placeholder="******************" autoComplete="one-time-code" + enablePasswordGenerator={true} {...field} /> @@ -578,6 +579,7 @@ export const AddDatabase = ({ environmentId, projectName }: Props) => { diff --git a/apps/dokploy/components/dashboard/projects/show.tsx b/apps/dokploy/components/dashboard/projects/show.tsx index eb1ff5ab6..740c75d8f 100644 --- a/apps/dokploy/components/dashboard/projects/show.tsx +++ b/apps/dokploy/components/dashboard/projects/show.tsx @@ -420,7 +420,7 @@ export const ShowProjects = () => { ) : null} - +
@@ -428,7 +428,7 @@ export const ShowProjects = () => {
- + {project.description} diff --git a/apps/dokploy/components/dashboard/settings/billing/show-billing-invoices.tsx b/apps/dokploy/components/dashboard/settings/billing/show-billing-invoices.tsx new file mode 100644 index 000000000..67c15ee63 --- /dev/null +++ b/apps/dokploy/components/dashboard/settings/billing/show-billing-invoices.tsx @@ -0,0 +1,74 @@ +import { CreditCard, FileText } from "lucide-react"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { cn } from "@/lib/utils"; +import { ShowInvoices } from "./show-invoices"; + +const navigationItems = [ + { + name: "Subscription", + href: "/dashboard/settings/billing", + icon: CreditCard, + }, + { + name: "Invoices", + href: "/dashboard/settings/invoices", + icon: FileText, + }, +]; + +export const ShowBillingInvoices = () => { + 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/components/shared/toggle-visibility-input.tsx b/apps/dokploy/components/shared/toggle-visibility-input.tsx index aea173fbc..660fd753a 100644 --- a/apps/dokploy/components/shared/toggle-visibility-input.tsx +++ b/apps/dokploy/components/shared/toggle-visibility-input.tsx @@ -10,7 +10,7 @@ export const ToggleVisibilityInput = ({ ...props }: InputProps) => { return (
- + )} - + +
)}
{errorMessage && ( diff --git a/apps/dokploy/drizzle/0057_damp_prism.sql b/apps/dokploy/drizzle/0057_damp_prism.sql deleted file mode 100644 index 363c2a9f4..000000000 --- a/apps/dokploy/drizzle/0057_damp_prism.sql +++ /dev/null @@ -1,16 +0,0 @@ -CREATE TABLE IF NOT EXISTS "ai" ( - "aiId" text PRIMARY KEY NOT NULL, - "name" text NOT NULL, - "apiUrl" text NOT NULL, - "apiKey" text NOT NULL, - "model" text NOT NULL, - "isEnabled" boolean DEFAULT true NOT NULL, - "adminId" text NOT NULL, - "createdAt" text NOT NULL -); ---> statement-breakpoint -DO $$ BEGIN - ALTER TABLE "ai" ADD CONSTRAINT "ai_adminId_admin_adminId_fk" FOREIGN KEY ("adminId") REFERENCES "public"."admin"("adminId") ON DELETE cascade ON UPDATE no action; -EXCEPTION - WHEN duplicate_object THEN null; -END $$; diff --git a/apps/dokploy/drizzle/0134_strong_hercules.sql b/apps/dokploy/drizzle/0134_strong_hercules.sql new file mode 100644 index 000000000..badb79d48 --- /dev/null +++ b/apps/dokploy/drizzle/0134_strong_hercules.sql @@ -0,0 +1 @@ +ALTER TABLE "application" ALTER COLUMN "railpackVersion" SET DEFAULT '0.15.4'; \ No newline at end of file diff --git a/apps/dokploy/drizzle/meta/0134_snapshot.json b/apps/dokploy/drizzle/meta/0134_snapshot.json new file mode 100644 index 000000000..6a3f7fbd7 --- /dev/null +++ b/apps/dokploy/drizzle/meta/0134_snapshot.json @@ -0,0 +1,6968 @@ +{ + "id": "e3db98b3-00ba-4ee2-8143-639bccb258f2", + "prevId": "b5cddb89-e0bc-42fd-8994-6609f672ee0c", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is2FAEnabled": { + "name": "is2FAEnabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "resetPasswordToken": { + "name": "resetPasswordToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resetPasswordExpiresAt": { + "name": "resetPasswordExpiresAt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmationToken": { + "name": "confirmationToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmationExpiresAt": { + "name": "confirmationExpiresAt", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.apikey": { + "name": "apikey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refill_interval": { + "name": "refill_interval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refill_amount": { + "name": "refill_amount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_refill_at": { + "name": "last_refill_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "rate_limit_enabled": { + "name": "rate_limit_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "rate_limit_time_window": { + "name": "rate_limit_time_window", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rate_limit_max": { + "name": "rate_limit_max", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_request": { + "name": "last_request", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "apikey_user_id_user_id_fk": { + "name": "apikey_user_id_user_id_fk", + "tableFrom": "apikey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invitation": { + "name": "invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "inviter_id": { + "name": "inviter_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "invitation_organization_id_organization_id_fk": { + "name": "invitation_organization_id_organization_id_fk", + "tableFrom": "invitation", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "invitation_inviter_id_user_id_fk": { + "name": "invitation_inviter_id_user_id_fk", + "tableFrom": "invitation", + "tableTo": "user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.member": { + "name": "member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canCreateProjects": { + "name": "canCreateProjects", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canAccessToSSHKeys": { + "name": "canAccessToSSHKeys", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canCreateServices": { + "name": "canCreateServices", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canDeleteProjects": { + "name": "canDeleteProjects", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canDeleteServices": { + "name": "canDeleteServices", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canAccessToDocker": { + "name": "canAccessToDocker", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canAccessToAPI": { + "name": "canAccessToAPI", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canAccessToGitProviders": { + "name": "canAccessToGitProviders", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canAccessToTraefikFiles": { + "name": "canAccessToTraefikFiles", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canDeleteEnvironments": { + "name": "canDeleteEnvironments", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "canCreateEnvironments": { + "name": "canCreateEnvironments", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "accesedProjects": { + "name": "accesedProjects", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "ARRAY[]::text[]" + }, + "accessedEnvironments": { + "name": "accessedEnvironments", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "ARRAY[]::text[]" + }, + "accesedServices": { + "name": "accesedServices", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "ARRAY[]::text[]" + } + }, + "indexes": {}, + "foreignKeys": { + "member_organization_id_organization_id_fk": { + "name": "member_organization_id_organization_id_fk", + "tableFrom": "member", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "member_user_id_user_id_fk": { + "name": "member_user_id_user_id_fk", + "tableFrom": "member", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization": { + "name": "organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owner_id": { + "name": "owner_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "organization_owner_id_user_id_fk": { + "name": "organization_owner_id_user_id_fk", + "tableFrom": "organization", + "tableTo": "user", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "organization_slug_unique": { + "name": "organization_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.two_factor": { + "name": "two_factor", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "secret": { + "name": "secret", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "backup_codes": { + "name": "backup_codes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "two_factor_user_id_user_id_fk": { + "name": "two_factor_user_id_user_id_fk", + "tableFrom": "two_factor", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ai": { + "name": "ai", + "schema": "", + "columns": { + "aiId": { + "name": "aiId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "apiUrl": { + "name": "apiUrl", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "apiKey": { + "name": "apiKey", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "isEnabled": { + "name": "isEnabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "organizationId": { + "name": "organizationId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "ai_organizationId_organization_id_fk": { + "name": "ai_organizationId_organization_id_fk", + "tableFrom": "ai", + "tableTo": "organization", + "columnsFrom": [ + "organizationId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.application": { + "name": "application", + "schema": "", + "columns": { + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previewEnv": { + "name": "previewEnv", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "watchPaths": { + "name": "watchPaths", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "previewBuildArgs": { + "name": "previewBuildArgs", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previewBuildSecrets": { + "name": "previewBuildSecrets", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previewLabels": { + "name": "previewLabels", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "previewWildcard": { + "name": "previewWildcard", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previewPort": { + "name": "previewPort", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 3000 + }, + "previewHttps": { + "name": "previewHttps", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "previewPath": { + "name": "previewPath", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "certificateType": { + "name": "certificateType", + "type": "certificateType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'none'" + }, + "previewCustomCertResolver": { + "name": "previewCustomCertResolver", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previewLimit": { + "name": "previewLimit", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 3 + }, + "isPreviewDeploymentsActive": { + "name": "isPreviewDeploymentsActive", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "previewRequireCollaboratorPermissions": { + "name": "previewRequireCollaboratorPermissions", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rollbackActive": { + "name": "rollbackActive", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "buildArgs": { + "name": "buildArgs", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "buildSecrets": { + "name": "buildSecrets", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "subtitle": { + "name": "subtitle", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "args": { + "name": "args", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "refreshToken": { + "name": "refreshToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sourceType": { + "name": "sourceType", + "type": "sourceType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "cleanCache": { + "name": "cleanCache", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "repository": { + "name": "repository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owner": { + "name": "owner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "buildPath": { + "name": "buildPath", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "triggerType": { + "name": "triggerType", + "type": "triggerType", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'push'" + }, + "autoDeploy": { + "name": "autoDeploy", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "gitlabProjectId": { + "name": "gitlabProjectId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "gitlabRepository": { + "name": "gitlabRepository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabOwner": { + "name": "gitlabOwner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabBranch": { + "name": "gitlabBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabBuildPath": { + "name": "gitlabBuildPath", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "gitlabPathNamespace": { + "name": "gitlabPathNamespace", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "giteaRepository": { + "name": "giteaRepository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "giteaOwner": { + "name": "giteaOwner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "giteaBranch": { + "name": "giteaBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "giteaBuildPath": { + "name": "giteaBuildPath", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "bitbucketRepository": { + "name": "bitbucketRepository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketOwner": { + "name": "bitbucketOwner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketBranch": { + "name": "bitbucketBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketBuildPath": { + "name": "bitbucketBuildPath", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "registryUrl": { + "name": "registryUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitUrl": { + "name": "customGitUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitBranch": { + "name": "customGitBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitBuildPath": { + "name": "customGitBuildPath", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitSSHKeyId": { + "name": "customGitSSHKeyId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enableSubmodules": { + "name": "enableSubmodules", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "dockerfile": { + "name": "dockerfile", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dockerContextPath": { + "name": "dockerContextPath", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dockerBuildStage": { + "name": "dockerBuildStage", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dropBuildPath": { + "name": "dropBuildPath", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "healthCheckSwarm": { + "name": "healthCheckSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "restartPolicySwarm": { + "name": "restartPolicySwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "placementSwarm": { + "name": "placementSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "updateConfigSwarm": { + "name": "updateConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "rollbackConfigSwarm": { + "name": "rollbackConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "modeSwarm": { + "name": "modeSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "labelsSwarm": { + "name": "labelsSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "networkSwarm": { + "name": "networkSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "stopGracePeriodSwarm": { + "name": "stopGracePeriodSwarm", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "endpointSpecSwarm": { + "name": "endpointSpecSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "replicas": { + "name": "replicas", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "buildType": { + "name": "buildType", + "type": "buildType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'nixpacks'" + }, + "railpackVersion": { + "name": "railpackVersion", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'0.15.4'" + }, + "herokuVersion": { + "name": "herokuVersion", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'24'" + }, + "publishDirectory": { + "name": "publishDirectory", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "isStaticSpa": { + "name": "isStaticSpa", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "createEnvFile": { + "name": "createEnvFile", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "registryId": { + "name": "registryId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rollbackRegistryId": { + "name": "rollbackRegistryId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "environmentId": { + "name": "environmentId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "githubId": { + "name": "githubId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabId": { + "name": "gitlabId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "giteaId": { + "name": "giteaId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketId": { + "name": "bitbucketId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "buildServerId": { + "name": "buildServerId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "buildRegistryId": { + "name": "buildRegistryId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "application_customGitSSHKeyId_ssh-key_sshKeyId_fk": { + "name": "application_customGitSSHKeyId_ssh-key_sshKeyId_fk", + "tableFrom": "application", + "tableTo": "ssh-key", + "columnsFrom": [ + "customGitSSHKeyId" + ], + "columnsTo": [ + "sshKeyId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_registryId_registry_registryId_fk": { + "name": "application_registryId_registry_registryId_fk", + "tableFrom": "application", + "tableTo": "registry", + "columnsFrom": [ + "registryId" + ], + "columnsTo": [ + "registryId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_rollbackRegistryId_registry_registryId_fk": { + "name": "application_rollbackRegistryId_registry_registryId_fk", + "tableFrom": "application", + "tableTo": "registry", + "columnsFrom": [ + "rollbackRegistryId" + ], + "columnsTo": [ + "registryId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_environmentId_environment_environmentId_fk": { + "name": "application_environmentId_environment_environmentId_fk", + "tableFrom": "application", + "tableTo": "environment", + "columnsFrom": [ + "environmentId" + ], + "columnsTo": [ + "environmentId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "application_githubId_github_githubId_fk": { + "name": "application_githubId_github_githubId_fk", + "tableFrom": "application", + "tableTo": "github", + "columnsFrom": [ + "githubId" + ], + "columnsTo": [ + "githubId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_gitlabId_gitlab_gitlabId_fk": { + "name": "application_gitlabId_gitlab_gitlabId_fk", + "tableFrom": "application", + "tableTo": "gitlab", + "columnsFrom": [ + "gitlabId" + ], + "columnsTo": [ + "gitlabId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_giteaId_gitea_giteaId_fk": { + "name": "application_giteaId_gitea_giteaId_fk", + "tableFrom": "application", + "tableTo": "gitea", + "columnsFrom": [ + "giteaId" + ], + "columnsTo": [ + "giteaId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_bitbucketId_bitbucket_bitbucketId_fk": { + "name": "application_bitbucketId_bitbucket_bitbucketId_fk", + "tableFrom": "application", + "tableTo": "bitbucket", + "columnsFrom": [ + "bitbucketId" + ], + "columnsTo": [ + "bitbucketId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_serverId_server_serverId_fk": { + "name": "application_serverId_server_serverId_fk", + "tableFrom": "application", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "application_buildServerId_server_serverId_fk": { + "name": "application_buildServerId_server_serverId_fk", + "tableFrom": "application", + "tableTo": "server", + "columnsFrom": [ + "buildServerId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "application_buildRegistryId_registry_registryId_fk": { + "name": "application_buildRegistryId_registry_registryId_fk", + "tableFrom": "application", + "tableTo": "registry", + "columnsFrom": [ + "buildRegistryId" + ], + "columnsTo": [ + "registryId" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "application_appName_unique": { + "name": "application_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.backup": { + "name": "backup", + "schema": "", + "columns": { + "backupId": { + "name": "backupId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "schedule": { + "name": "schedule", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "database": { + "name": "database", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serviceName": { + "name": "serviceName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "destinationId": { + "name": "destinationId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "keepLatestCount": { + "name": "keepLatestCount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "backupType": { + "name": "backupType", + "type": "backupType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'database'" + }, + "databaseType": { + "name": "databaseType", + "type": "databaseType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postgresId": { + "name": "postgresId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mariadbId": { + "name": "mariadbId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mysqlId": { + "name": "mysqlId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mongoId": { + "name": "mongoId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "backup_destinationId_destination_destinationId_fk": { + "name": "backup_destinationId_destination_destinationId_fk", + "tableFrom": "backup", + "tableTo": "destination", + "columnsFrom": [ + "destinationId" + ], + "columnsTo": [ + "destinationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "backup_composeId_compose_composeId_fk": { + "name": "backup_composeId_compose_composeId_fk", + "tableFrom": "backup", + "tableTo": "compose", + "columnsFrom": [ + "composeId" + ], + "columnsTo": [ + "composeId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "backup_postgresId_postgres_postgresId_fk": { + "name": "backup_postgresId_postgres_postgresId_fk", + "tableFrom": "backup", + "tableTo": "postgres", + "columnsFrom": [ + "postgresId" + ], + "columnsTo": [ + "postgresId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "backup_mariadbId_mariadb_mariadbId_fk": { + "name": "backup_mariadbId_mariadb_mariadbId_fk", + "tableFrom": "backup", + "tableTo": "mariadb", + "columnsFrom": [ + "mariadbId" + ], + "columnsTo": [ + "mariadbId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "backup_mysqlId_mysql_mysqlId_fk": { + "name": "backup_mysqlId_mysql_mysqlId_fk", + "tableFrom": "backup", + "tableTo": "mysql", + "columnsFrom": [ + "mysqlId" + ], + "columnsTo": [ + "mysqlId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "backup_mongoId_mongo_mongoId_fk": { + "name": "backup_mongoId_mongo_mongoId_fk", + "tableFrom": "backup", + "tableTo": "mongo", + "columnsFrom": [ + "mongoId" + ], + "columnsTo": [ + "mongoId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "backup_userId_user_id_fk": { + "name": "backup_userId_user_id_fk", + "tableFrom": "backup", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "backup_appName_unique": { + "name": "backup_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.bitbucket": { + "name": "bitbucket", + "schema": "", + "columns": { + "bitbucketId": { + "name": "bitbucketId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "bitbucketUsername": { + "name": "bitbucketUsername", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketEmail": { + "name": "bitbucketEmail", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "appPassword": { + "name": "appPassword", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "apiToken": { + "name": "apiToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketWorkspaceName": { + "name": "bitbucketWorkspaceName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitProviderId": { + "name": "gitProviderId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "bitbucket_gitProviderId_git_provider_gitProviderId_fk": { + "name": "bitbucket_gitProviderId_git_provider_gitProviderId_fk", + "tableFrom": "bitbucket", + "tableTo": "git_provider", + "columnsFrom": [ + "gitProviderId" + ], + "columnsTo": [ + "gitProviderId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.certificate": { + "name": "certificate", + "schema": "", + "columns": { + "certificateId": { + "name": "certificateId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "certificateData": { + "name": "certificateData", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "privateKey": { + "name": "privateKey", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "certificatePath": { + "name": "certificatePath", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "autoRenew": { + "name": "autoRenew", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "organizationId": { + "name": "organizationId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "certificate_organizationId_organization_id_fk": { + "name": "certificate_organizationId_organization_id_fk", + "tableFrom": "certificate", + "tableTo": "organization", + "columnsFrom": [ + "organizationId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "certificate_serverId_server_serverId_fk": { + "name": "certificate_serverId_server_serverId_fk", + "tableFrom": "certificate", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "certificate_certificatePath_unique": { + "name": "certificate_certificatePath_unique", + "nullsNotDistinct": false, + "columns": [ + "certificatePath" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.compose": { + "name": "compose", + "schema": "", + "columns": { + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "composeFile": { + "name": "composeFile", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "refreshToken": { + "name": "refreshToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sourceType": { + "name": "sourceType", + "type": "sourceTypeCompose", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "composeType": { + "name": "composeType", + "type": "composeType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'docker-compose'" + }, + "repository": { + "name": "repository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owner": { + "name": "owner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "autoDeploy": { + "name": "autoDeploy", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "gitlabProjectId": { + "name": "gitlabProjectId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "gitlabRepository": { + "name": "gitlabRepository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabOwner": { + "name": "gitlabOwner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabBranch": { + "name": "gitlabBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabPathNamespace": { + "name": "gitlabPathNamespace", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketRepository": { + "name": "bitbucketRepository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketOwner": { + "name": "bitbucketOwner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketBranch": { + "name": "bitbucketBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "giteaRepository": { + "name": "giteaRepository", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "giteaOwner": { + "name": "giteaOwner", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "giteaBranch": { + "name": "giteaBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitUrl": { + "name": "customGitUrl", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitBranch": { + "name": "customGitBranch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customGitSSHKeyId": { + "name": "customGitSSHKeyId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "enableSubmodules": { + "name": "enableSubmodules", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "composePath": { + "name": "composePath", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'./docker-compose.yml'" + }, + "suffix": { + "name": "suffix", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "randomize": { + "name": "randomize", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "isolatedDeployment": { + "name": "isolatedDeployment", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "isolatedDeploymentsVolume": { + "name": "isolatedDeploymentsVolume", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "triggerType": { + "name": "triggerType", + "type": "triggerType", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'push'" + }, + "composeStatus": { + "name": "composeStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "environmentId": { + "name": "environmentId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "watchPaths": { + "name": "watchPaths", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "githubId": { + "name": "githubId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitlabId": { + "name": "gitlabId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bitbucketId": { + "name": "bitbucketId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "giteaId": { + "name": "giteaId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "compose_customGitSSHKeyId_ssh-key_sshKeyId_fk": { + "name": "compose_customGitSSHKeyId_ssh-key_sshKeyId_fk", + "tableFrom": "compose", + "tableTo": "ssh-key", + "columnsFrom": [ + "customGitSSHKeyId" + ], + "columnsTo": [ + "sshKeyId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "compose_environmentId_environment_environmentId_fk": { + "name": "compose_environmentId_environment_environmentId_fk", + "tableFrom": "compose", + "tableTo": "environment", + "columnsFrom": [ + "environmentId" + ], + "columnsTo": [ + "environmentId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "compose_githubId_github_githubId_fk": { + "name": "compose_githubId_github_githubId_fk", + "tableFrom": "compose", + "tableTo": "github", + "columnsFrom": [ + "githubId" + ], + "columnsTo": [ + "githubId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "compose_gitlabId_gitlab_gitlabId_fk": { + "name": "compose_gitlabId_gitlab_gitlabId_fk", + "tableFrom": "compose", + "tableTo": "gitlab", + "columnsFrom": [ + "gitlabId" + ], + "columnsTo": [ + "gitlabId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "compose_bitbucketId_bitbucket_bitbucketId_fk": { + "name": "compose_bitbucketId_bitbucket_bitbucketId_fk", + "tableFrom": "compose", + "tableTo": "bitbucket", + "columnsFrom": [ + "bitbucketId" + ], + "columnsTo": [ + "bitbucketId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "compose_giteaId_gitea_giteaId_fk": { + "name": "compose_giteaId_gitea_giteaId_fk", + "tableFrom": "compose", + "tableTo": "gitea", + "columnsFrom": [ + "giteaId" + ], + "columnsTo": [ + "giteaId" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "compose_serverId_server_serverId_fk": { + "name": "compose_serverId_server_serverId_fk", + "tableFrom": "compose", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.deployment": { + "name": "deployment", + "schema": "", + "columns": { + "deploymentId": { + "name": "deploymentId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "deploymentStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'running'" + }, + "logPath": { + "name": "logPath", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pid": { + "name": "pid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "isPreviewDeployment": { + "name": "isPreviewDeployment", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "previewDeploymentId": { + "name": "previewDeploymentId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "startedAt": { + "name": "startedAt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "finishedAt": { + "name": "finishedAt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "errorMessage": { + "name": "errorMessage", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduleId": { + "name": "scheduleId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "backupId": { + "name": "backupId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rollbackId": { + "name": "rollbackId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "volumeBackupId": { + "name": "volumeBackupId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "buildServerId": { + "name": "buildServerId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "deployment_applicationId_application_applicationId_fk": { + "name": "deployment_applicationId_application_applicationId_fk", + "tableFrom": "deployment", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_composeId_compose_composeId_fk": { + "name": "deployment_composeId_compose_composeId_fk", + "tableFrom": "deployment", + "tableTo": "compose", + "columnsFrom": [ + "composeId" + ], + "columnsTo": [ + "composeId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_serverId_server_serverId_fk": { + "name": "deployment_serverId_server_serverId_fk", + "tableFrom": "deployment", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk": { + "name": "deployment_previewDeploymentId_preview_deployments_previewDeploymentId_fk", + "tableFrom": "deployment", + "tableTo": "preview_deployments", + "columnsFrom": [ + "previewDeploymentId" + ], + "columnsTo": [ + "previewDeploymentId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_scheduleId_schedule_scheduleId_fk": { + "name": "deployment_scheduleId_schedule_scheduleId_fk", + "tableFrom": "deployment", + "tableTo": "schedule", + "columnsFrom": [ + "scheduleId" + ], + "columnsTo": [ + "scheduleId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_backupId_backup_backupId_fk": { + "name": "deployment_backupId_backup_backupId_fk", + "tableFrom": "deployment", + "tableTo": "backup", + "columnsFrom": [ + "backupId" + ], + "columnsTo": [ + "backupId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_rollbackId_rollback_rollbackId_fk": { + "name": "deployment_rollbackId_rollback_rollbackId_fk", + "tableFrom": "deployment", + "tableTo": "rollback", + "columnsFrom": [ + "rollbackId" + ], + "columnsTo": [ + "rollbackId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_volumeBackupId_volume_backup_volumeBackupId_fk": { + "name": "deployment_volumeBackupId_volume_backup_volumeBackupId_fk", + "tableFrom": "deployment", + "tableTo": "volume_backup", + "columnsFrom": [ + "volumeBackupId" + ], + "columnsTo": [ + "volumeBackupId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployment_buildServerId_server_serverId_fk": { + "name": "deployment_buildServerId_server_serverId_fk", + "tableFrom": "deployment", + "tableTo": "server", + "columnsFrom": [ + "buildServerId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.destination": { + "name": "destination", + "schema": "", + "columns": { + "destinationId": { + "name": "destinationId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accessKey": { + "name": "accessKey", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "secretAccessKey": { + "name": "secretAccessKey", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bucket": { + "name": "bucket", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "region": { + "name": "region", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "endpoint": { + "name": "endpoint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organizationId": { + "name": "organizationId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "destination_organizationId_organization_id_fk": { + "name": "destination_organizationId_organization_id_fk", + "tableFrom": "destination", + "tableTo": "organization", + "columnsFrom": [ + "organizationId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.domain": { + "name": "domain", + "schema": "", + "columns": { + "domainId": { + "name": "domainId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "host": { + "name": "host", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "https": { + "name": "https", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 3000 + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "serviceName": { + "name": "serviceName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "domainType": { + "name": "domainType", + "type": "domainType", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'application'" + }, + "uniqueConfigKey": { + "name": "uniqueConfigKey", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customCertResolver": { + "name": "customCertResolver", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previewDeploymentId": { + "name": "previewDeploymentId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "certificateType": { + "name": "certificateType", + "type": "certificateType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'none'" + }, + "internalPath": { + "name": "internalPath", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'/'" + }, + "stripPath": { + "name": "stripPath", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "domain_composeId_compose_composeId_fk": { + "name": "domain_composeId_compose_composeId_fk", + "tableFrom": "domain", + "tableTo": "compose", + "columnsFrom": [ + "composeId" + ], + "columnsTo": [ + "composeId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "domain_applicationId_application_applicationId_fk": { + "name": "domain_applicationId_application_applicationId_fk", + "tableFrom": "domain", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk": { + "name": "domain_previewDeploymentId_preview_deployments_previewDeploymentId_fk", + "tableFrom": "domain", + "tableTo": "preview_deployments", + "columnsFrom": [ + "previewDeploymentId" + ], + "columnsTo": [ + "previewDeploymentId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.environment": { + "name": "environment", + "schema": "", + "columns": { + "environmentId": { + "name": "environmentId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "projectId": { + "name": "projectId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "isDefault": { + "name": "isDefault", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "environment_projectId_project_projectId_fk": { + "name": "environment_projectId_project_projectId_fk", + "tableFrom": "environment", + "tableTo": "project", + "columnsFrom": [ + "projectId" + ], + "columnsTo": [ + "projectId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.git_provider": { + "name": "git_provider", + "schema": "", + "columns": { + "gitProviderId": { + "name": "gitProviderId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "providerType": { + "name": "providerType", + "type": "gitProviderType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'github'" + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organizationId": { + "name": "organizationId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "git_provider_organizationId_organization_id_fk": { + "name": "git_provider_organizationId_organization_id_fk", + "tableFrom": "git_provider", + "tableTo": "organization", + "columnsFrom": [ + "organizationId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "git_provider_userId_user_id_fk": { + "name": "git_provider_userId_user_id_fk", + "tableFrom": "git_provider", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.gitea": { + "name": "gitea", + "schema": "", + "columns": { + "giteaId": { + "name": "giteaId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "giteaUrl": { + "name": "giteaUrl", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'https://gitea.com'" + }, + "redirect_uri": { + "name": "redirect_uri", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_secret": { + "name": "client_secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitProviderId": { + "name": "gitProviderId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'repo,repo:status,read:user,read:org'" + }, + "last_authenticated_at": { + "name": "last_authenticated_at", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "gitea_gitProviderId_git_provider_gitProviderId_fk": { + "name": "gitea_gitProviderId_git_provider_gitProviderId_fk", + "tableFrom": "gitea", + "tableTo": "git_provider", + "columnsFrom": [ + "gitProviderId" + ], + "columnsTo": [ + "gitProviderId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.github": { + "name": "github", + "schema": "", + "columns": { + "githubId": { + "name": "githubId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "githubAppName": { + "name": "githubAppName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "githubAppId": { + "name": "githubAppId", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "githubClientId": { + "name": "githubClientId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "githubClientSecret": { + "name": "githubClientSecret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "githubInstallationId": { + "name": "githubInstallationId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "githubPrivateKey": { + "name": "githubPrivateKey", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "githubWebhookSecret": { + "name": "githubWebhookSecret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gitProviderId": { + "name": "gitProviderId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "github_gitProviderId_git_provider_gitProviderId_fk": { + "name": "github_gitProviderId_git_provider_gitProviderId_fk", + "tableFrom": "github", + "tableTo": "git_provider", + "columnsFrom": [ + "gitProviderId" + ], + "columnsTo": [ + "gitProviderId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.gitlab": { + "name": "gitlab", + "schema": "", + "columns": { + "gitlabId": { + "name": "gitlabId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "gitlabUrl": { + "name": "gitlabUrl", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'https://gitlab.com'" + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "redirect_uri": { + "name": "redirect_uri", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "secret": { + "name": "secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "group_name": { + "name": "group_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "gitProviderId": { + "name": "gitProviderId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "gitlab_gitProviderId_git_provider_gitProviderId_fk": { + "name": "gitlab_gitProviderId_git_provider_gitProviderId_fk", + "tableFrom": "gitlab", + "tableTo": "git_provider", + "columnsFrom": [ + "gitProviderId" + ], + "columnsTo": [ + "gitProviderId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mariadb": { + "name": "mariadb", + "schema": "", + "columns": { + "mariadbId": { + "name": "mariadbId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "databaseName": { + "name": "databaseName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databaseUser": { + "name": "databaseUser", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databasePassword": { + "name": "databasePassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rootPassword": { + "name": "rootPassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "args": { + "name": "args", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "externalPort": { + "name": "externalPort", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "healthCheckSwarm": { + "name": "healthCheckSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "restartPolicySwarm": { + "name": "restartPolicySwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "placementSwarm": { + "name": "placementSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "updateConfigSwarm": { + "name": "updateConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "rollbackConfigSwarm": { + "name": "rollbackConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "modeSwarm": { + "name": "modeSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "labelsSwarm": { + "name": "labelsSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "networkSwarm": { + "name": "networkSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "stopGracePeriodSwarm": { + "name": "stopGracePeriodSwarm", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "endpointSpecSwarm": { + "name": "endpointSpecSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "replicas": { + "name": "replicas", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environmentId": { + "name": "environmentId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "mariadb_environmentId_environment_environmentId_fk": { + "name": "mariadb_environmentId_environment_environmentId_fk", + "tableFrom": "mariadb", + "tableTo": "environment", + "columnsFrom": [ + "environmentId" + ], + "columnsTo": [ + "environmentId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mariadb_serverId_server_serverId_fk": { + "name": "mariadb_serverId_server_serverId_fk", + "tableFrom": "mariadb", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "mariadb_appName_unique": { + "name": "mariadb_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mongo": { + "name": "mongo", + "schema": "", + "columns": { + "mongoId": { + "name": "mongoId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "databaseUser": { + "name": "databaseUser", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databasePassword": { + "name": "databasePassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "args": { + "name": "args", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "externalPort": { + "name": "externalPort", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "healthCheckSwarm": { + "name": "healthCheckSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "restartPolicySwarm": { + "name": "restartPolicySwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "placementSwarm": { + "name": "placementSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "updateConfigSwarm": { + "name": "updateConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "rollbackConfigSwarm": { + "name": "rollbackConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "modeSwarm": { + "name": "modeSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "labelsSwarm": { + "name": "labelsSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "networkSwarm": { + "name": "networkSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "stopGracePeriodSwarm": { + "name": "stopGracePeriodSwarm", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "endpointSpecSwarm": { + "name": "endpointSpecSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "replicas": { + "name": "replicas", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environmentId": { + "name": "environmentId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "replicaSets": { + "name": "replicaSets", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "mongo_environmentId_environment_environmentId_fk": { + "name": "mongo_environmentId_environment_environmentId_fk", + "tableFrom": "mongo", + "tableTo": "environment", + "columnsFrom": [ + "environmentId" + ], + "columnsTo": [ + "environmentId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mongo_serverId_server_serverId_fk": { + "name": "mongo_serverId_server_serverId_fk", + "tableFrom": "mongo", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "mongo_appName_unique": { + "name": "mongo_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mount": { + "name": "mount", + "schema": "", + "columns": { + "mountId": { + "name": "mountId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "type": { + "name": "type", + "type": "mountType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "hostPath": { + "name": "hostPath", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "volumeName": { + "name": "volumeName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filePath": { + "name": "filePath", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serviceType": { + "name": "serviceType", + "type": "serviceType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'application'" + }, + "mountPath": { + "name": "mountPath", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postgresId": { + "name": "postgresId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mariadbId": { + "name": "mariadbId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mongoId": { + "name": "mongoId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mysqlId": { + "name": "mysqlId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "redisId": { + "name": "redisId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "mount_applicationId_application_applicationId_fk": { + "name": "mount_applicationId_application_applicationId_fk", + "tableFrom": "mount", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_postgresId_postgres_postgresId_fk": { + "name": "mount_postgresId_postgres_postgresId_fk", + "tableFrom": "mount", + "tableTo": "postgres", + "columnsFrom": [ + "postgresId" + ], + "columnsTo": [ + "postgresId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_mariadbId_mariadb_mariadbId_fk": { + "name": "mount_mariadbId_mariadb_mariadbId_fk", + "tableFrom": "mount", + "tableTo": "mariadb", + "columnsFrom": [ + "mariadbId" + ], + "columnsTo": [ + "mariadbId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_mongoId_mongo_mongoId_fk": { + "name": "mount_mongoId_mongo_mongoId_fk", + "tableFrom": "mount", + "tableTo": "mongo", + "columnsFrom": [ + "mongoId" + ], + "columnsTo": [ + "mongoId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_mysqlId_mysql_mysqlId_fk": { + "name": "mount_mysqlId_mysql_mysqlId_fk", + "tableFrom": "mount", + "tableTo": "mysql", + "columnsFrom": [ + "mysqlId" + ], + "columnsTo": [ + "mysqlId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_redisId_redis_redisId_fk": { + "name": "mount_redisId_redis_redisId_fk", + "tableFrom": "mount", + "tableTo": "redis", + "columnsFrom": [ + "redisId" + ], + "columnsTo": [ + "redisId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mount_composeId_compose_composeId_fk": { + "name": "mount_composeId_compose_composeId_fk", + "tableFrom": "mount", + "tableTo": "compose", + "columnsFrom": [ + "composeId" + ], + "columnsTo": [ + "composeId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mysql": { + "name": "mysql", + "schema": "", + "columns": { + "mysqlId": { + "name": "mysqlId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "databaseName": { + "name": "databaseName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databaseUser": { + "name": "databaseUser", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databasePassword": { + "name": "databasePassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rootPassword": { + "name": "rootPassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "args": { + "name": "args", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "externalPort": { + "name": "externalPort", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "healthCheckSwarm": { + "name": "healthCheckSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "restartPolicySwarm": { + "name": "restartPolicySwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "placementSwarm": { + "name": "placementSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "updateConfigSwarm": { + "name": "updateConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "rollbackConfigSwarm": { + "name": "rollbackConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "modeSwarm": { + "name": "modeSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "labelsSwarm": { + "name": "labelsSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "networkSwarm": { + "name": "networkSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "stopGracePeriodSwarm": { + "name": "stopGracePeriodSwarm", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "endpointSpecSwarm": { + "name": "endpointSpecSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "replicas": { + "name": "replicas", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environmentId": { + "name": "environmentId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "mysql_environmentId_environment_environmentId_fk": { + "name": "mysql_environmentId_environment_environmentId_fk", + "tableFrom": "mysql", + "tableTo": "environment", + "columnsFrom": [ + "environmentId" + ], + "columnsTo": [ + "environmentId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "mysql_serverId_server_serverId_fk": { + "name": "mysql_serverId_server_serverId_fk", + "tableFrom": "mysql", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "mysql_appName_unique": { + "name": "mysql_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.custom": { + "name": "custom", + "schema": "", + "columns": { + "customId": { + "name": "customId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "endpoint": { + "name": "endpoint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "headers": { + "name": "headers", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.discord": { + "name": "discord", + "schema": "", + "columns": { + "discordId": { + "name": "discordId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "webhookUrl": { + "name": "webhookUrl", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "decoration": { + "name": "decoration", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email": { + "name": "email", + "schema": "", + "columns": { + "emailId": { + "name": "emailId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "smtpServer": { + "name": "smtpServer", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "smtpPort": { + "name": "smtpPort", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "fromAddress": { + "name": "fromAddress", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "toAddress": { + "name": "toAddress", + "type": "text[]", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.gotify": { + "name": "gotify", + "schema": "", + "columns": { + "gotifyId": { + "name": "gotifyId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "serverUrl": { + "name": "serverUrl", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appToken": { + "name": "appToken", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "priority": { + "name": "priority", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 5 + }, + "decoration": { + "name": "decoration", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.lark": { + "name": "lark", + "schema": "", + "columns": { + "larkId": { + "name": "larkId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "webhookUrl": { + "name": "webhookUrl", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notification": { + "name": "notification", + "schema": "", + "columns": { + "notificationId": { + "name": "notificationId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appDeploy": { + "name": "appDeploy", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "appBuildError": { + "name": "appBuildError", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "databaseBackup": { + "name": "databaseBackup", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "volumeBackup": { + "name": "volumeBackup", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "dokployRestart": { + "name": "dokployRestart", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "dockerCleanup": { + "name": "dockerCleanup", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "serverThreshold": { + "name": "serverThreshold", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "notificationType": { + "name": "notificationType", + "type": "notificationType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slackId": { + "name": "slackId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "telegramId": { + "name": "telegramId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "discordId": { + "name": "discordId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "emailId": { + "name": "emailId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "gotifyId": { + "name": "gotifyId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ntfyId": { + "name": "ntfyId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customId": { + "name": "customId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "larkId": { + "name": "larkId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organizationId": { + "name": "organizationId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "notification_slackId_slack_slackId_fk": { + "name": "notification_slackId_slack_slackId_fk", + "tableFrom": "notification", + "tableTo": "slack", + "columnsFrom": [ + "slackId" + ], + "columnsTo": [ + "slackId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_telegramId_telegram_telegramId_fk": { + "name": "notification_telegramId_telegram_telegramId_fk", + "tableFrom": "notification", + "tableTo": "telegram", + "columnsFrom": [ + "telegramId" + ], + "columnsTo": [ + "telegramId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_discordId_discord_discordId_fk": { + "name": "notification_discordId_discord_discordId_fk", + "tableFrom": "notification", + "tableTo": "discord", + "columnsFrom": [ + "discordId" + ], + "columnsTo": [ + "discordId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_emailId_email_emailId_fk": { + "name": "notification_emailId_email_emailId_fk", + "tableFrom": "notification", + "tableTo": "email", + "columnsFrom": [ + "emailId" + ], + "columnsTo": [ + "emailId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_gotifyId_gotify_gotifyId_fk": { + "name": "notification_gotifyId_gotify_gotifyId_fk", + "tableFrom": "notification", + "tableTo": "gotify", + "columnsFrom": [ + "gotifyId" + ], + "columnsTo": [ + "gotifyId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_ntfyId_ntfy_ntfyId_fk": { + "name": "notification_ntfyId_ntfy_ntfyId_fk", + "tableFrom": "notification", + "tableTo": "ntfy", + "columnsFrom": [ + "ntfyId" + ], + "columnsTo": [ + "ntfyId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_customId_custom_customId_fk": { + "name": "notification_customId_custom_customId_fk", + "tableFrom": "notification", + "tableTo": "custom", + "columnsFrom": [ + "customId" + ], + "columnsTo": [ + "customId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_larkId_lark_larkId_fk": { + "name": "notification_larkId_lark_larkId_fk", + "tableFrom": "notification", + "tableTo": "lark", + "columnsFrom": [ + "larkId" + ], + "columnsTo": [ + "larkId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_organizationId_organization_id_fk": { + "name": "notification_organizationId_organization_id_fk", + "tableFrom": "notification", + "tableTo": "organization", + "columnsFrom": [ + "organizationId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ntfy": { + "name": "ntfy", + "schema": "", + "columns": { + "ntfyId": { + "name": "ntfyId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "serverUrl": { + "name": "serverUrl", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "topic": { + "name": "topic", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "accessToken": { + "name": "accessToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "priority": { + "name": "priority", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 3 + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.slack": { + "name": "slack", + "schema": "", + "columns": { + "slackId": { + "name": "slackId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "webhookUrl": { + "name": "webhookUrl", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "channel": { + "name": "channel", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.telegram": { + "name": "telegram", + "schema": "", + "columns": { + "telegramId": { + "name": "telegramId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "botToken": { + "name": "botToken", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "chatId": { + "name": "chatId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "messageThreadId": { + "name": "messageThreadId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.port": { + "name": "port", + "schema": "", + "columns": { + "portId": { + "name": "portId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "publishedPort": { + "name": "publishedPort", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "publishMode": { + "name": "publishMode", + "type": "publishModeType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'host'" + }, + "targetPort": { + "name": "targetPort", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "protocol": { + "name": "protocol", + "type": "protocolType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "port_applicationId_application_applicationId_fk": { + "name": "port_applicationId_application_applicationId_fk", + "tableFrom": "port", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.postgres": { + "name": "postgres", + "schema": "", + "columns": { + "postgresId": { + "name": "postgresId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databaseName": { + "name": "databaseName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databaseUser": { + "name": "databaseUser", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "databasePassword": { + "name": "databasePassword", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "args": { + "name": "args", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "externalPort": { + "name": "externalPort", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "healthCheckSwarm": { + "name": "healthCheckSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "restartPolicySwarm": { + "name": "restartPolicySwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "placementSwarm": { + "name": "placementSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "updateConfigSwarm": { + "name": "updateConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "rollbackConfigSwarm": { + "name": "rollbackConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "modeSwarm": { + "name": "modeSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "labelsSwarm": { + "name": "labelsSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "networkSwarm": { + "name": "networkSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "stopGracePeriodSwarm": { + "name": "stopGracePeriodSwarm", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "endpointSpecSwarm": { + "name": "endpointSpecSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "replicas": { + "name": "replicas", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environmentId": { + "name": "environmentId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "postgres_environmentId_environment_environmentId_fk": { + "name": "postgres_environmentId_environment_environmentId_fk", + "tableFrom": "postgres", + "tableTo": "environment", + "columnsFrom": [ + "environmentId" + ], + "columnsTo": [ + "environmentId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "postgres_serverId_server_serverId_fk": { + "name": "postgres_serverId_server_serverId_fk", + "tableFrom": "postgres", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "postgres_appName_unique": { + "name": "postgres_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.preview_deployments": { + "name": "preview_deployments", + "schema": "", + "columns": { + "previewDeploymentId": { + "name": "previewDeploymentId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pullRequestId": { + "name": "pullRequestId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pullRequestNumber": { + "name": "pullRequestNumber", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pullRequestURL": { + "name": "pullRequestURL", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pullRequestTitle": { + "name": "pullRequestTitle", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pullRequestCommentId": { + "name": "pullRequestCommentId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "previewStatus": { + "name": "previewStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domainId": { + "name": "domainId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "preview_deployments_applicationId_application_applicationId_fk": { + "name": "preview_deployments_applicationId_application_applicationId_fk", + "tableFrom": "preview_deployments", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "preview_deployments_domainId_domain_domainId_fk": { + "name": "preview_deployments_domainId_domain_domainId_fk", + "tableFrom": "preview_deployments", + "tableTo": "domain", + "columnsFrom": [ + "domainId" + ], + "columnsTo": [ + "domainId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "preview_deployments_appName_unique": { + "name": "preview_deployments_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.project": { + "name": "project", + "schema": "", + "columns": { + "projectId": { + "name": "projectId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organizationId": { + "name": "organizationId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + } + }, + "indexes": {}, + "foreignKeys": { + "project_organizationId_organization_id_fk": { + "name": "project_organizationId_organization_id_fk", + "tableFrom": "project", + "tableTo": "organization", + "columnsFrom": [ + "organizationId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.redirect": { + "name": "redirect", + "schema": "", + "columns": { + "redirectId": { + "name": "redirectId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "regex": { + "name": "regex", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "replacement": { + "name": "replacement", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "permanent": { + "name": "permanent", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "uniqueConfigKey": { + "name": "uniqueConfigKey", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "redirect_applicationId_application_applicationId_fk": { + "name": "redirect_applicationId_application_applicationId_fk", + "tableFrom": "redirect", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.redis": { + "name": "redis", + "schema": "", + "columns": { + "redisId": { + "name": "redisId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dockerImage": { + "name": "dockerImage", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "args": { + "name": "args", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "env": { + "name": "env", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryReservation": { + "name": "memoryReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "memoryLimit": { + "name": "memoryLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuReservation": { + "name": "cpuReservation", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cpuLimit": { + "name": "cpuLimit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "externalPort": { + "name": "externalPort", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applicationStatus": { + "name": "applicationStatus", + "type": "applicationStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'idle'" + }, + "healthCheckSwarm": { + "name": "healthCheckSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "restartPolicySwarm": { + "name": "restartPolicySwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "placementSwarm": { + "name": "placementSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "updateConfigSwarm": { + "name": "updateConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "rollbackConfigSwarm": { + "name": "rollbackConfigSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "modeSwarm": { + "name": "modeSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "labelsSwarm": { + "name": "labelsSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "networkSwarm": { + "name": "networkSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "stopGracePeriodSwarm": { + "name": "stopGracePeriodSwarm", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "endpointSpecSwarm": { + "name": "endpointSpecSwarm", + "type": "json", + "primaryKey": false, + "notNull": false + }, + "replicas": { + "name": "replicas", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "environmentId": { + "name": "environmentId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "redis_environmentId_environment_environmentId_fk": { + "name": "redis_environmentId_environment_environmentId_fk", + "tableFrom": "redis", + "tableTo": "environment", + "columnsFrom": [ + "environmentId" + ], + "columnsTo": [ + "environmentId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "redis_serverId_server_serverId_fk": { + "name": "redis_serverId_server_serverId_fk", + "tableFrom": "redis", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "redis_appName_unique": { + "name": "redis_appName_unique", + "nullsNotDistinct": false, + "columns": [ + "appName" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.registry": { + "name": "registry", + "schema": "", + "columns": { + "registryId": { + "name": "registryId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "registryName": { + "name": "registryName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "imagePrefix": { + "name": "imagePrefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "registryUrl": { + "name": "registryUrl", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "selfHosted": { + "name": "selfHosted", + "type": "RegistryType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'cloud'" + }, + "organizationId": { + "name": "organizationId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "registry_organizationId_organization_id_fk": { + "name": "registry_organizationId_organization_id_fk", + "tableFrom": "registry", + "tableTo": "organization", + "columnsFrom": [ + "organizationId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.rollback": { + "name": "rollback", + "schema": "", + "columns": { + "rollbackId": { + "name": "rollbackId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "deploymentId": { + "name": "deploymentId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "fullContext": { + "name": "fullContext", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "rollback_deploymentId_deployment_deploymentId_fk": { + "name": "rollback_deploymentId_deployment_deploymentId_fk", + "tableFrom": "rollback", + "tableTo": "deployment", + "columnsFrom": [ + "deploymentId" + ], + "columnsTo": [ + "deploymentId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.schedule": { + "name": "schedule", + "schema": "", + "columns": { + "scheduleId": { + "name": "scheduleId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cronExpression": { + "name": "cronExpression", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serviceName": { + "name": "serviceName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "shellType": { + "name": "shellType", + "type": "shellType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'bash'" + }, + "scheduleType": { + "name": "scheduleType", + "type": "scheduleType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'application'" + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "script": { + "name": "script", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "timezone": { + "name": "timezone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "schedule_applicationId_application_applicationId_fk": { + "name": "schedule_applicationId_application_applicationId_fk", + "tableFrom": "schedule", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "schedule_composeId_compose_composeId_fk": { + "name": "schedule_composeId_compose_composeId_fk", + "tableFrom": "schedule", + "tableTo": "compose", + "columnsFrom": [ + "composeId" + ], + "columnsTo": [ + "composeId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "schedule_serverId_server_serverId_fk": { + "name": "schedule_serverId_server_serverId_fk", + "tableFrom": "schedule", + "tableTo": "server", + "columnsFrom": [ + "serverId" + ], + "columnsTo": [ + "serverId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "schedule_userId_user_id_fk": { + "name": "schedule_userId_user_id_fk", + "tableFrom": "schedule", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.security": { + "name": "security", + "schema": "", + "columns": { + "securityId": { + "name": "securityId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "security_applicationId_application_applicationId_fk": { + "name": "security_applicationId_application_applicationId_fk", + "tableFrom": "security", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "security_username_applicationId_unique": { + "name": "security_username_applicationId_unique", + "nullsNotDistinct": false, + "columns": [ + "username", + "applicationId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.server": { + "name": "server", + "schema": "", + "columns": { + "serverId": { + "name": "serverId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ipAddress": { + "name": "ipAddress", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'root'" + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enableDockerCleanup": { + "name": "enableDockerCleanup", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organizationId": { + "name": "organizationId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverStatus": { + "name": "serverStatus", + "type": "serverStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "serverType": { + "name": "serverType", + "type": "serverType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'deploy'" + }, + "command": { + "name": "command", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "sshKeyId": { + "name": "sshKeyId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metricsConfig": { + "name": "metricsConfig", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{\"server\":{\"type\":\"Remote\",\"refreshRate\":60,\"port\":4500,\"token\":\"\",\"urlCallback\":\"\",\"cronJob\":\"\",\"retentionDays\":2,\"thresholds\":{\"cpu\":0,\"memory\":0}},\"containers\":{\"refreshRate\":60,\"services\":{\"include\":[],\"exclude\":[]}}}'::jsonb" + } + }, + "indexes": {}, + "foreignKeys": { + "server_organizationId_organization_id_fk": { + "name": "server_organizationId_organization_id_fk", + "tableFrom": "server", + "tableTo": "organization", + "columnsFrom": [ + "organizationId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "server_sshKeyId_ssh-key_sshKeyId_fk": { + "name": "server_sshKeyId_ssh-key_sshKeyId_fk", + "tableFrom": "server", + "tableTo": "ssh-key", + "columnsFrom": [ + "sshKeyId" + ], + "columnsTo": [ + "sshKeyId" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session_temp": { + "name": "session_temp", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "session_temp_user_id_user_id_fk": { + "name": "session_temp_user_id_user_id_fk", + "tableFrom": "session_temp", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_temp_token_unique": { + "name": "session_temp_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ssh-key": { + "name": "ssh-key", + "schema": "", + "columns": { + "sshKeyId": { + "name": "sshKeyId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "privateKey": { + "name": "privateKey", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "publicKey": { + "name": "publicKey", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "lastUsedAt": { + "name": "lastUsedAt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organizationId": { + "name": "organizationId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "ssh-key_organizationId_organization_id_fk": { + "name": "ssh-key_organizationId_organization_id_fk", + "tableFrom": "ssh-key", + "tableTo": "organization", + "columnsFrom": [ + "organizationId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "firstName": { + "name": "firstName", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "lastName": { + "name": "lastName", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "isRegistered": { + "name": "isRegistered", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "expirationDate": { + "name": "expirationDate", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "two_factor_enabled": { + "name": "two_factor_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'user'" + }, + "enablePaidFeatures": { + "name": "enablePaidFeatures", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "allowImpersonation": { + "name": "allowImpersonation", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "stripeCustomerId": { + "name": "stripeCustomerId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripeSubscriptionId": { + "name": "stripeSubscriptionId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serversQuantity": { + "name": "serversQuantity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.volume_backup": { + "name": "volume_backup", + "schema": "", + "columns": { + "volumeBackupId": { + "name": "volumeBackupId", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "volumeName": { + "name": "volumeName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serviceType": { + "name": "serviceType", + "type": "serviceType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'application'" + }, + "appName": { + "name": "appName", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serviceName": { + "name": "serviceName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "turnOff": { + "name": "turnOff", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "cronExpression": { + "name": "cronExpression", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "keepLatestCount": { + "name": "keepLatestCount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "applicationId": { + "name": "applicationId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postgresId": { + "name": "postgresId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mariadbId": { + "name": "mariadbId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mongoId": { + "name": "mongoId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mysqlId": { + "name": "mysqlId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "redisId": { + "name": "redisId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "composeId": { + "name": "composeId", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "destinationId": { + "name": "destinationId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "volume_backup_applicationId_application_applicationId_fk": { + "name": "volume_backup_applicationId_application_applicationId_fk", + "tableFrom": "volume_backup", + "tableTo": "application", + "columnsFrom": [ + "applicationId" + ], + "columnsTo": [ + "applicationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "volume_backup_postgresId_postgres_postgresId_fk": { + "name": "volume_backup_postgresId_postgres_postgresId_fk", + "tableFrom": "volume_backup", + "tableTo": "postgres", + "columnsFrom": [ + "postgresId" + ], + "columnsTo": [ + "postgresId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "volume_backup_mariadbId_mariadb_mariadbId_fk": { + "name": "volume_backup_mariadbId_mariadb_mariadbId_fk", + "tableFrom": "volume_backup", + "tableTo": "mariadb", + "columnsFrom": [ + "mariadbId" + ], + "columnsTo": [ + "mariadbId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "volume_backup_mongoId_mongo_mongoId_fk": { + "name": "volume_backup_mongoId_mongo_mongoId_fk", + "tableFrom": "volume_backup", + "tableTo": "mongo", + "columnsFrom": [ + "mongoId" + ], + "columnsTo": [ + "mongoId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "volume_backup_mysqlId_mysql_mysqlId_fk": { + "name": "volume_backup_mysqlId_mysql_mysqlId_fk", + "tableFrom": "volume_backup", + "tableTo": "mysql", + "columnsFrom": [ + "mysqlId" + ], + "columnsTo": [ + "mysqlId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "volume_backup_redisId_redis_redisId_fk": { + "name": "volume_backup_redisId_redis_redisId_fk", + "tableFrom": "volume_backup", + "tableTo": "redis", + "columnsFrom": [ + "redisId" + ], + "columnsTo": [ + "redisId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "volume_backup_composeId_compose_composeId_fk": { + "name": "volume_backup_composeId_compose_composeId_fk", + "tableFrom": "volume_backup", + "tableTo": "compose", + "columnsFrom": [ + "composeId" + ], + "columnsTo": [ + "composeId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "volume_backup_destinationId_destination_destinationId_fk": { + "name": "volume_backup_destinationId_destination_destinationId_fk", + "tableFrom": "volume_backup", + "tableTo": "destination", + "columnsFrom": [ + "destinationId" + ], + "columnsTo": [ + "destinationId" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webServerSettings": { + "name": "webServerSettings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "serverIp": { + "name": "serverIp", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "certificateType": { + "name": "certificateType", + "type": "certificateType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'none'" + }, + "https": { + "name": "https", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "host": { + "name": "host", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "letsEncryptEmail": { + "name": "letsEncryptEmail", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sshPrivateKey": { + "name": "sshPrivateKey", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enableDockerCleanup": { + "name": "enableDockerCleanup", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "logCleanupCron": { + "name": "logCleanupCron", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'0 0 * * *'" + }, + "metricsConfig": { + "name": "metricsConfig", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{\"server\":{\"type\":\"Dokploy\",\"refreshRate\":60,\"port\":4500,\"token\":\"\",\"retentionDays\":2,\"cronJob\":\"\",\"urlCallback\":\"\",\"thresholds\":{\"cpu\":0,\"memory\":0}},\"containers\":{\"refreshRate\":60,\"services\":{\"include\":[],\"exclude\":[]}}}'::jsonb" + }, + "cleanupCacheApplications": { + "name": "cleanupCacheApplications", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "cleanupCacheOnPreviews": { + "name": "cleanupCacheOnPreviews", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "cleanupCacheOnCompose": { + "name": "cleanupCacheOnCompose", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.buildType": { + "name": "buildType", + "schema": "public", + "values": [ + "dockerfile", + "heroku_buildpacks", + "paketo_buildpacks", + "nixpacks", + "static", + "railpack" + ] + }, + "public.sourceType": { + "name": "sourceType", + "schema": "public", + "values": [ + "docker", + "git", + "github", + "gitlab", + "bitbucket", + "gitea", + "drop" + ] + }, + "public.backupType": { + "name": "backupType", + "schema": "public", + "values": [ + "database", + "compose" + ] + }, + "public.databaseType": { + "name": "databaseType", + "schema": "public", + "values": [ + "postgres", + "mariadb", + "mysql", + "mongo", + "web-server" + ] + }, + "public.composeType": { + "name": "composeType", + "schema": "public", + "values": [ + "docker-compose", + "stack" + ] + }, + "public.sourceTypeCompose": { + "name": "sourceTypeCompose", + "schema": "public", + "values": [ + "git", + "github", + "gitlab", + "bitbucket", + "gitea", + "raw" + ] + }, + "public.deploymentStatus": { + "name": "deploymentStatus", + "schema": "public", + "values": [ + "running", + "done", + "error", + "cancelled" + ] + }, + "public.domainType": { + "name": "domainType", + "schema": "public", + "values": [ + "compose", + "application", + "preview" + ] + }, + "public.gitProviderType": { + "name": "gitProviderType", + "schema": "public", + "values": [ + "github", + "gitlab", + "bitbucket", + "gitea" + ] + }, + "public.mountType": { + "name": "mountType", + "schema": "public", + "values": [ + "bind", + "volume", + "file" + ] + }, + "public.serviceType": { + "name": "serviceType", + "schema": "public", + "values": [ + "application", + "postgres", + "mysql", + "mariadb", + "mongo", + "redis", + "compose" + ] + }, + "public.notificationType": { + "name": "notificationType", + "schema": "public", + "values": [ + "slack", + "telegram", + "discord", + "email", + "gotify", + "ntfy", + "custom", + "lark" + ] + }, + "public.protocolType": { + "name": "protocolType", + "schema": "public", + "values": [ + "tcp", + "udp" + ] + }, + "public.publishModeType": { + "name": "publishModeType", + "schema": "public", + "values": [ + "ingress", + "host" + ] + }, + "public.RegistryType": { + "name": "RegistryType", + "schema": "public", + "values": [ + "selfHosted", + "cloud" + ] + }, + "public.scheduleType": { + "name": "scheduleType", + "schema": "public", + "values": [ + "application", + "compose", + "server", + "dokploy-server" + ] + }, + "public.shellType": { + "name": "shellType", + "schema": "public", + "values": [ + "bash", + "sh" + ] + }, + "public.serverStatus": { + "name": "serverStatus", + "schema": "public", + "values": [ + "active", + "inactive" + ] + }, + "public.serverType": { + "name": "serverType", + "schema": "public", + "values": [ + "deploy", + "build" + ] + }, + "public.applicationStatus": { + "name": "applicationStatus", + "schema": "public", + "values": [ + "idle", + "running", + "done", + "error" + ] + }, + "public.certificateType": { + "name": "certificateType", + "schema": "public", + "values": [ + "letsencrypt", + "none", + "custom" + ] + }, + "public.triggerType": { + "name": "triggerType", + "schema": "public", + "values": [ + "push", + "tag" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/apps/dokploy/drizzle/meta/_journal.json b/apps/dokploy/drizzle/meta/_journal.json index bd6c62c46..3f67c5d17 100644 --- a/apps/dokploy/drizzle/meta/_journal.json +++ b/apps/dokploy/drizzle/meta/_journal.json @@ -939,6 +939,13 @@ "when": 1766301478005, "tag": "0133_striped_the_order", "breakpoints": true + }, + { + "idx": 134, + "version": "7", + "when": 1767871040249, + "tag": "0134_strong_hercules", + "breakpoints": true } ] } \ No newline at end of file diff --git a/apps/dokploy/lib/password-utils.ts b/apps/dokploy/lib/password-utils.ts new file mode 100644 index 000000000..b95fd290f --- /dev/null +++ b/apps/dokploy/lib/password-utils.ts @@ -0,0 +1,38 @@ +const DEFAULT_PASSWORD_LENGTH = 20; +const DEFAULT_PASSWORD_CHARSET = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +export const generateRandomPassword = ( + length: number = DEFAULT_PASSWORD_LENGTH, + charset: string = DEFAULT_PASSWORD_CHARSET, +) => { + const safeLength = + Number.isFinite(length) && length > 0 + ? Math.floor(length) + : DEFAULT_PASSWORD_LENGTH; + + if (safeLength <= 0 || charset.length === 0) { + return ""; + } + + const cryptoApi = + typeof globalThis !== "undefined" ? globalThis.crypto : undefined; + + if (!cryptoApi?.getRandomValues) { + let fallback = ""; + for (let i = 0; i < safeLength; i += 1) { + fallback += charset[Math.floor(Math.random() * charset.length)]; + } + return fallback; + } + + const values = new Uint32Array(safeLength); + cryptoApi.getRandomValues(values); + + let result = ""; + for (const value of values) { + result += charset[value % charset.length]; + } + + return result; +}; diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json index c8bb95056..7fe165a42 100644 --- a/apps/dokploy/package.json +++ b/apps/dokploy/package.json @@ -1,6 +1,6 @@ { "name": "dokploy", - "version": "v0.26.3", + "version": "v0.26.5", "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", @@ -196,10 +196,5 @@ "*": [ "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true" ] - }, - "commitlint": { - "extends": [ - "@commitlint/config-conventional" - ] } } diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx index 33b037e5f..af901311e 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx @@ -909,7 +909,9 @@ const EnvironmentPage = ( - {(auth?.role === "owner" || auth?.canCreateServices) && ( + {(auth?.role === "owner" || + auth?.role === "admin" || + auth?.canCreateServices) && ( {(auth?.role === "owner" || + auth?.role === "admin" || auth?.canDeleteServices) && ( <> - {(auth?.role === "owner" || auth?.canDeleteServices) && ( + {(auth?.role === "owner" || + auth?.role === "admin" || + auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx index 56b4b5d0c..1d6902c59 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx @@ -97,6 +97,7 @@ const Service = ( { name: "Projects", href: "/dashboard/projects" }, { name: data?.environment?.project?.name || "", + href: `/dashboard/project/${projectId}/environment/${environmentId}`, }, { name: data?.environment?.name || "", @@ -182,7 +183,9 @@ const Service = (
- {(auth?.role === "owner" || auth?.canDeleteServices) && ( + {(auth?.role === "owner" || + auth?.role === "admin" || + auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx index d47fbd14d..0a1e8501d 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx @@ -79,6 +79,7 @@ const Mariadb = ( { name: "Projects", href: "/dashboard/projects" }, { name: data?.environment?.project?.name || "", + href: `/dashboard/project/${projectId}/environment/${environmentId}`, }, { name: data?.environment?.name || "", @@ -156,7 +157,9 @@ const Mariadb = (
- {(auth?.role === "owner" || auth?.canDeleteServices) && ( + {(auth?.role === "owner" || + auth?.role === "admin" || + auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx index 660315d5a..bae83cb2b 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx @@ -78,6 +78,7 @@ const Mongo = ( { name: "Projects", href: "/dashboard/projects" }, { name: data?.environment?.project?.name || "", + href: `/dashboard/project/${projectId}/environment/${environmentId}`, }, { name: data?.environment?.name || "", @@ -155,7 +156,9 @@ const Mongo = (
- {(auth?.role === "owner" || auth?.canDeleteServices) && ( + {(auth?.role === "owner" || + auth?.role === "admin" || + auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx index 7f4cc791c..ba2b9d8a0 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx @@ -77,6 +77,7 @@ const MySql = ( { name: "Projects", href: "/dashboard/projects" }, { name: data?.environment?.project?.name || "", + href: `/dashboard/project/${projectId}/environment/${environmentId}`, }, { name: data?.environment?.name || "", @@ -156,7 +157,9 @@ const MySql = (
- {(auth?.role === "owner" || auth?.canDeleteServices) && ( + {(auth?.role === "owner" || + auth?.role === "admin" || + auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx index a34f7b7ee..1d90e3e13 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx @@ -77,6 +77,7 @@ const Postgresql = ( { name: "Projects", href: "/dashboard/projects" }, { name: data?.environment?.project?.name || "", + href: `/dashboard/project/${projectId}/environment/${environmentId}`, }, { name: data?.environment?.name || "", @@ -154,7 +155,9 @@ const Postgresql = (
- {(auth?.role === "owner" || auth?.canDeleteServices) && ( + {(auth?.role === "owner" || + auth?.role === "admin" || + auth?.canDeleteServices) && ( )}
diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx index 72a513fba..47eb82a74 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx @@ -77,6 +77,7 @@ const Redis = ( { name: "Projects", href: "/dashboard/projects" }, { name: data?.environment?.project?.name || "", + href: `/dashboard/project/${projectId}/environment/${environmentId}`, }, { name: data?.environment?.name || "", @@ -154,7 +155,9 @@ const Redis = (
- {(auth?.role === "owner" || auth?.canDeleteServices) && ( + {(auth?.role === "owner" || + auth?.role === "admin" || + auth?.canDeleteServices) && ( )}
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/preview-deployment.ts b/apps/dokploy/server/api/routers/preview-deployment.ts index 49b781101..0c325a9c6 100644 --- a/apps/dokploy/server/api/routers/preview-deployment.ts +++ b/apps/dokploy/server/api/routers/preview-deployment.ts @@ -2,11 +2,15 @@ import { findApplicationById, findPreviewDeploymentById, findPreviewDeploymentsByApplicationId, + IS_CLOUD, removePreviewDeployment, } from "@dokploy/server"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; import { apiFindAllByApplication } from "@/server/db/schema"; +import type { DeploymentJob } from "@/server/queues/queue-types"; +import { myQueue } from "@/server/queues/queueSetup"; +import { deploy } from "@/server/utils/deploy"; import { createTRPCRouter, protectedProcedure } from "../trpc"; export const previewDeploymentRouter = createTRPCRouter({ @@ -60,4 +64,55 @@ export const previewDeploymentRouter = createTRPCRouter({ } return previewDeployment; }), + redeploy: protectedProcedure + .input( + z.object({ + previewDeploymentId: z.string(), + title: z.string().optional(), + description: z.string().optional(), + }), + ) + .mutation(async ({ input, ctx }) => { + const previewDeployment = await findPreviewDeploymentById( + input.previewDeploymentId, + ); + if ( + previewDeployment.application.environment.project.organizationId !== + ctx.session.activeOrganizationId + ) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "You are not authorized to redeploy this preview deployment", + }); + } + const application = await findApplicationById( + previewDeployment.applicationId, + ); + const jobData: DeploymentJob = { + applicationId: previewDeployment.applicationId, + titleLog: input.title || "Rebuild Preview Deployment", + descriptionLog: input.description || "", + type: "redeploy", + applicationType: "application-preview", + previewDeploymentId: input.previewDeploymentId, + server: !!application.serverId, + }; + + if (IS_CLOUD && application.serverId) { + jobData.serverId = application.serverId; + deploy(jobData).catch((error) => { + console.error("Background deployment failed:", error); + }); + return true; + } + await myQueue.add( + "deployments", + { ...jobData }, + { + removeOnComplete: true, + removeOnFail: true, + }, + ); + return true; + }), }); 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..be1e94d4a 100644 --- a/apps/dokploy/server/api/routers/stripe.ts +++ b/apps/dokploy/server/api/routers/stripe.ts @@ -75,9 +75,9 @@ export const stripeRouter = createTRPCRouter({ const session = await stripe.checkout.sessions.create({ mode: "subscription", line_items: items, - ...(stripeCustomerId && { - customer: stripeCustomerId, - }), + ...(stripeCustomerId + ? { customer: stripeCustomerId } + : { customer_email: owner.email }), metadata: { adminId: owner.id, }, @@ -128,4 +128,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/dokploy/server/queues/deployments-queue.ts b/apps/dokploy/server/queues/deployments-queue.ts index 4c117e7e3..0474b63e2 100644 --- a/apps/dokploy/server/queues/deployments-queue.ts +++ b/apps/dokploy/server/queues/deployments-queue.ts @@ -4,6 +4,7 @@ import { deployPreviewApplication, rebuildApplication, rebuildCompose, + rebuildPreviewApplication, updateApplicationStatus, updateCompose, updatePreviewDeployment, @@ -54,7 +55,14 @@ export const deploymentWorker = new Worker( previewStatus: "running", }); - if (job.data.type === "deploy") { + if (job.data.type === "redeploy") { + await rebuildPreviewApplication({ + applicationId: job.data.applicationId, + titleLog: job.data.titleLog, + descriptionLog: job.data.descriptionLog, + previewDeploymentId: job.data.previewDeploymentId, + }); + } else if (job.data.type === "deploy") { await deployPreviewApplication({ applicationId: job.data.applicationId, titleLog: job.data.titleLog, diff --git a/apps/dokploy/server/queues/queue-types.ts b/apps/dokploy/server/queues/queue-types.ts index ef8df6943..1000725ad 100644 --- a/apps/dokploy/server/queues/queue-types.ts +++ b/apps/dokploy/server/queues/queue-types.ts @@ -22,7 +22,7 @@ type DeployJob = titleLog: string; descriptionLog: string; server?: boolean; - type: "deploy"; + type: "deploy" | "redeploy"; applicationType: "application-preview"; previewDeploymentId: string; serverId?: string; 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/lefthook.yml b/lefthook.yml deleted file mode 100644 index 3f5a6d09f..000000000 --- a/lefthook.yml +++ /dev/null @@ -1,45 +0,0 @@ -# EXAMPLE USAGE: -# -# Refer for explanation to following link: -# https://github.com/evilmartians/lefthook/blob/master/docs/configuration.md -# -# pre-push: -# commands: -# packages-audit: -# tags: frontend security -# run: yarn audit -# gems-audit: -# tags: backend security -# run: bundle audit -# -# pre-commit: -# parallel: true -# commands: -# eslint: -# glob: "*.{js,ts,jsx,tsx}" -# run: yarn eslint {staged_files} -# rubocop: -# tags: backend style -# glob: "*.rb" -# exclude: '(^|/)(application|routes)\.rb$' -# run: bundle exec rubocop --force-exclusion {all_files} -# govet: -# tags: backend style -# files: git ls-files -m -# glob: "*.go" -# run: go vet {files} -# scripts: -# "hello.js": -# runner: node -# "any.go": -# runner: go run - -commit-msg: - commands: - commitlint: - # run: "npx commitlint --edit $1" - -pre-commit: - commands: - check: - # run: "pnpm check" diff --git a/package.json b/package.json index 1f59cc661..9a920c59c 100644 --- a/package.json +++ b/package.json @@ -24,12 +24,9 @@ }, "devDependencies": { "@biomejs/biome": "2.1.1", - "@commitlint/cli": "^19.8.1", - "@commitlint/config-conventional": "^19.8.1", "@types/node": "^18.19.104", "dotenv": "16.4.5", "esbuild": "0.20.2", - "lefthook": "1.8.4", "lint-staged": "^15.5.2", "tsx": "4.16.2" }, @@ -43,11 +40,6 @@ "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true" ] }, - "commitlint": { - "extends": [ - "@commitlint/config-conventional" - ] - }, "resolutions": { "@types/react": "18.3.5", "@types/react-dom": "18.3.0" diff --git a/packages/server/package.json b/packages/server/package.json index 9ce60fcf7..820300b15 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", @@ -111,4 +111,4 @@ "node": "^20.16.0", "pnpm": ">=9.12.0" } -} \ No newline at end of file +} diff --git a/packages/server/schema.dbml b/packages/server/schema.dbml index ef1814c00..0fe7c05e8 100644 --- a/packages/server/schema.dbml +++ b/packages/server/schema.dbml @@ -277,7 +277,7 @@ table application { replicas integer [not null, default: 1] applicationStatus applicationStatus [not null, default: 'idle'] buildType buildType [not null, default: 'nixpacks'] - railpackVersion text [default: '0.2.2'] + railpackVersion text [default: '0.15.4'] herokuVersion text [default: '24'] publishDirectory text isStaticSpa boolean diff --git a/packages/server/src/db/schema/application.ts b/packages/server/src/db/schema/application.ts index 787ec55b3..90ce58403 100644 --- a/packages/server/src/db/schema/application.ts +++ b/packages/server/src/db/schema/application.ts @@ -177,7 +177,7 @@ export const applications = pgTable("application", { .notNull() .default("idle"), buildType: buildType("buildType").notNull().default("nixpacks"), - railpackVersion: text("railpackVersion").default("0.2.2"), + railpackVersion: text("railpackVersion").default("0.15.4"), herokuVersion: text("herokuVersion").default("24"), publishDirectory: text("publishDirectory"), isStaticSpa: boolean("isStaticSpa"), diff --git a/packages/server/src/lib/auth.ts b/packages/server/src/lib/auth.ts index d4379e4be..d952e1f6a 100644 --- a/packages/server/src/lib/auth.ts +++ b/packages/server/src/lib/auth.ts @@ -45,6 +45,12 @@ const { handler, api } = betterAuth({ return [ ...(settings?.serverIp ? [`http://${settings?.serverIp}:3000`] : []), ...(settings?.host ? [`https://${settings?.host}`] : []), + ...(process.env.NODE_ENV === "development" + ? [ + "http://localhost:3000", + "https://absolutely-handy-falcon.ngrok-free.app", + ] + : []), ]; }, }), diff --git a/packages/server/src/services/application.ts b/packages/server/src/services/application.ts index 61a77ae5a..335ffbf77 100644 --- a/packages/server/src/services/application.ts +++ b/packages/server/src/services/application.ts @@ -452,6 +452,137 @@ export const deployPreviewApplication = async ({ return true; }; +export const rebuildPreviewApplication = async ({ + applicationId, + titleLog = "Rebuild Preview Deployment", + descriptionLog = "", + previewDeploymentId, +}: { + applicationId: string; + titleLog: string; + descriptionLog: string; + previewDeploymentId: string; +}) => { + const application = await findApplicationById(applicationId); + const previewDeployment = + await findPreviewDeploymentById(previewDeploymentId); + + const deployment = await createDeploymentPreview({ + title: titleLog, + description: descriptionLog, + previewDeploymentId: previewDeploymentId, + }); + + const previewDomain = getDomainHost(previewDeployment?.domain as Domain); + const issueParams = { + owner: application?.owner || "", + repository: application?.repository || "", + issue_number: previewDeployment.pullRequestNumber, + comment_id: Number.parseInt(previewDeployment.pullRequestCommentId), + githubId: application?.githubId || "", + }; + + try { + const commentExists = await issueCommentExists({ + ...issueParams, + }); + if (!commentExists) { + const result = await createPreviewDeploymentComment({ + ...issueParams, + previewDomain, + appName: previewDeployment.appName, + githubId: application?.githubId || "", + previewDeploymentId, + }); + + if (!result) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Pull request comment not found", + }); + } + + issueParams.comment_id = Number.parseInt(result?.pullRequestCommentId); + } + + const buildingComment = getIssueComment( + application.name, + "running", + previewDomain, + ); + await updateIssueComment({ + ...issueParams, + body: `### Dokploy Preview Deployment\n\n${buildingComment}`, + }); + + // Set application properties for preview deployment + application.appName = previewDeployment.appName; + application.env = `${application.previewEnv}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain?.host}`; + application.buildArgs = `${application.previewBuildArgs}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain?.host}`; + application.buildSecrets = `${application.previewBuildSecrets}\nDOKPLOY_DEPLOY_URL=${previewDeployment?.domain?.host}`; + application.rollbackActive = false; + application.buildRegistry = null; + application.rollbackRegistry = null; + application.registry = null; + + const serverId = application.serverId; + let command = "set -e;"; + // Only rebuild, don't clone repository + command += await getBuildCommand(application); + const commandWithLog = `(${command}) >> ${deployment.logPath} 2>&1`; + if (serverId) { + await execAsyncRemote(serverId, commandWithLog); + } else { + await execAsync(commandWithLog); + } + await mechanizeDockerContainer(application); + + const successComment = getIssueComment( + application.name, + "success", + previewDomain, + ); + await updateIssueComment({ + ...issueParams, + body: `### Dokploy Preview Deployment\n\n${successComment}`, + }); + await updateDeploymentStatus(deployment.deploymentId, "done"); + await updatePreviewDeployment(previewDeploymentId, { + previewStatus: "done", + }); + } catch (error) { + let command = ""; + + // Only log details for non-ExecError errors + if (!(error instanceof ExecError)) { + const message = error instanceof Error ? error.message : String(error); + const encodedMessage = encodeBase64(message); + command += `echo "${encodedMessage}" | base64 -d >> "${deployment.logPath}";`; + } + + command += `echo "\nError occurred ❌, check the logs for details." >> ${deployment.logPath};`; + const serverId = application.buildServerId || application.serverId; + if (serverId) { + await execAsyncRemote(serverId, command); + } else { + await execAsync(command); + } + + const comment = getIssueComment(application.name, "error", previewDomain); + await updateIssueComment({ + ...issueParams, + body: `### Dokploy Preview Deployment\n\n${comment}`, + }); + await updateDeploymentStatus(deployment.deploymentId, "error"); + await updatePreviewDeployment(previewDeploymentId, { + previewStatus: "error", + }); + throw error; + } + + return true; +}; + export const getApplicationStats = async (appName: string) => { if (appName === "dokploy") { return await getAdvancedStats(appName); diff --git a/packages/server/src/services/domain.ts b/packages/server/src/services/domain.ts index e9a21c1f7..b2e15ed91 100644 --- a/packages/server/src/services/domain.ts +++ b/packages/server/src/services/domain.ts @@ -1,9 +1,9 @@ import dns from "node:dns"; import { promisify } from "node:util"; import { db } from "@dokploy/server/db"; +import { getWebServerSettings } from "@dokploy/server/services/web-server-settings"; import { generateRandomDomain } from "@dokploy/server/templates"; import { manageDomain } from "@dokploy/server/utils/traefik/domain"; -import { getWebServerSettings } from "@dokploy/server/services/web-server-settings"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; import { type apiCreateDomain, domains } from "../db/schema"; 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/packages/server/src/setup/server-setup.ts b/packages/server/src/setup/server-setup.ts index 54e740583..32e5e4a7e 100644 --- a/packages/server/src/setup/server-setup.ts +++ b/packages/server/src/setup/server-setup.ts @@ -1,10 +1,14 @@ import path from "node:path"; -import { paths } from "@dokploy/server/constants"; +import { IS_CLOUD, paths } from "@dokploy/server/constants"; +import { getDokployUrl } from "@dokploy/server/services/admin"; import { createServerDeployment, updateDeploymentStatus, } from "@dokploy/server/services/deployment"; -import { findServerById } from "@dokploy/server/services/server"; +import { + findServerById, + updateServerById, +} from "@dokploy/server/services/server"; import { getDefaultMiddlewares, getDefaultServerTraefikConfig, @@ -16,6 +20,15 @@ import { import slug from "slugify"; import { Client } from "ssh2"; import { recreateDirectory } from "../utils/filesystem/directory"; +import { setupMonitoring } from "./monitoring-setup"; + +const generateToken = () => { + const array = new Uint8Array(64); + crypto.getRandomValues(array); + return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join( + "", + ); +}; export const slugify = (text: string | undefined) => { if (!text) { @@ -59,6 +72,29 @@ export const serverSetup = async ( ); await installRequirements(serverId, onData); + if (IS_CLOUD) { + onData?.("\nConfiguring Monitoring: 🔄\n"); + + const baseUrl = await getDokployUrl(); + const token = generateToken(); + const urlCallback = `${baseUrl}/api/trpc/notification.receiveNotification`; + + // Update server with monitoring configuration + await updateServerById(serverId, { + metricsConfig: { + server: { + ...server.metricsConfig.server, + token: token, + urlCallback: urlCallback, + }, + containers: server.metricsConfig.containers, + }, + }); + + await setupMonitoring(serverId); + onData?.("\nMonitoring Configured: ✅\n"); + } + await updateDeploymentStatus(deployment.deploymentId, "done"); onData?.("\nSetup Server: ✅\n"); @@ -629,7 +665,7 @@ const installNixpacks = () => ` if command_exists nixpacks; then echo "Nixpacks already installed ✅" else - export NIXPACKS_VERSION=1.39.0 + export NIXPACKS_VERSION=1.41.0 bash -c "$(curl -fsSL https://nixpacks.com/install.sh)" echo "Nixpacks version $NIXPACKS_VERSION installed ✅" fi @@ -639,7 +675,7 @@ const installRailpack = () => ` if command_exists railpack; then echo "Railpack already installed ✅" else - export RAILPACK_VERSION=0.2.2 + export RAILPACK_VERSION=0.15.4 bash -c "$(curl -fsSL https://railpack.com/install.sh)" echo "Railpack version $RAILPACK_VERSION installed ✅" fi @@ -653,8 +689,8 @@ const installBuildpacks = () => ` if command_exists pack; then echo "Buildpacks already installed ✅" else - BUILDPACKS_VERSION=0.35.0 - curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.35.0/pack-v$BUILDPACKS_VERSION-linux$SUFFIX.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack + BUILDPACKS_VERSION=0.39.1 + curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.39.1/pack-v$BUILDPACKS_VERSION-linux$SUFFIX.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack echo "Buildpacks version $BUILDPACKS_VERSION installed ✅" fi `; diff --git a/packages/server/src/utils/ai/select-ai-provider.ts b/packages/server/src/utils/ai/select-ai-provider.ts index 1967ff834..8b3173137 100644 --- a/packages/server/src/utils/ai/select-ai-provider.ts +++ b/packages/server/src/utils/ai/select-ai-provider.ts @@ -71,8 +71,9 @@ export function selectAIProvider(config: { apiUrl: string; apiKey: string }) { return createOpenAICompatible({ name: "gemini", baseURL: config.apiUrl, - queryParams: { key: config.apiKey }, - headers: {}, + headers: { + Authorization: `Bearer ${config.apiKey}`, + }, }); case "custom": return createOpenAICompatible({ diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index 5a0184a3d..5eede59d5 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -134,6 +134,7 @@ const getExportEnvCommand = (compose: ComposeNested) => { const envVars = getEnviromentVariablesObject( compose.env, compose.environment.project.env, + compose.environment.env, ); const exports = Object.entries(envVars) .map(([key, value]) => `${key}=${quote([value])}`) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0c06df37..d5fc7f074 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,12 +15,6 @@ importers: '@biomejs/biome': specifier: 2.1.1 version: 2.1.1 - '@commitlint/cli': - specifier: ^19.8.1 - version: 19.8.1(@types/node@18.19.104)(typescript@5.8.3) - '@commitlint/config-conventional': - specifier: ^19.8.1 - version: 19.8.1 '@types/node': specifier: ^18.19.104 version: 18.19.104 @@ -30,9 +24,6 @@ importers: esbuild: specifier: 0.20.2 version: 0.20.2 - lefthook: - specifier: 1.8.4 - version: 1.8.4 lint-staged: specifier: ^15.5.2 version: 15.5.2 @@ -51,9 +42,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 +301,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 +349,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 +388,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 +476,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 +666,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 +690,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 +711,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 +769,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 @@ -882,14 +870,6 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - '@babel/runtime-corejs3@7.27.3': resolution: {integrity: sha512-ZYcgrwb+dkWNcDlsTe4fH1CMdqMDSJ5lWFd1by8Si2pI54XcQjte/+ViIPqAk7EAWisaUxvQ89grv+bNX2x8zg==} engines: {node: '>=6.9.0'} @@ -1005,75 +985,6 @@ packages: '@codemirror/view@6.36.8': resolution: {integrity: sha512-yoRo4f+FdnD01fFt4XpfpMCcCAo9QvZOtbrXExn4SqzH32YC6LgzqxfLZw/r6Ge65xyY03mK/UfUqrVw1gFiFg==} - '@commitlint/cli@19.8.1': - resolution: {integrity: sha512-LXUdNIkspyxrlV6VDHWBmCZRtkEVRpBKxi2Gtw3J54cGWhLCTouVD/Q6ZSaSvd2YaDObWK8mDjrz3TIKtaQMAA==} - engines: {node: '>=v18'} - hasBin: true - - '@commitlint/config-conventional@19.8.1': - resolution: {integrity: sha512-/AZHJL6F6B/G959CsMAzrPKKZjeEiAVifRyEwXxcT6qtqbPwGw+iQxmNS+Bu+i09OCtdNRW6pNpBvgPrtMr9EQ==} - engines: {node: '>=v18'} - - '@commitlint/config-validator@19.8.1': - resolution: {integrity: sha512-0jvJ4u+eqGPBIzzSdqKNX1rvdbSU1lPNYlfQQRIFnBgLy26BtC0cFnr7c/AyuzExMxWsMOte6MkTi9I3SQ3iGQ==} - engines: {node: '>=v18'} - - '@commitlint/ensure@19.8.1': - resolution: {integrity: sha512-mXDnlJdvDzSObafjYrOSvZBwkD01cqB4gbnnFuVyNpGUM5ijwU/r/6uqUmBXAAOKRfyEjpkGVZxaDsCVnHAgyw==} - engines: {node: '>=v18'} - - '@commitlint/execute-rule@19.8.1': - resolution: {integrity: sha512-YfJyIqIKWI64Mgvn/sE7FXvVMQER/Cd+s3hZke6cI1xgNT/f6ZAz5heND0QtffH+KbcqAwXDEE1/5niYayYaQA==} - engines: {node: '>=v18'} - - '@commitlint/format@19.8.1': - resolution: {integrity: sha512-kSJj34Rp10ItP+Eh9oCItiuN/HwGQMXBnIRk69jdOwEW9llW9FlyqcWYbHPSGofmjsqeoxa38UaEA5tsbm2JWw==} - engines: {node: '>=v18'} - - '@commitlint/is-ignored@19.8.1': - resolution: {integrity: sha512-AceOhEhekBUQ5dzrVhDDsbMaY5LqtN8s1mqSnT2Kz1ERvVZkNihrs3Sfk1Je/rxRNbXYFzKZSHaPsEJJDJV8dg==} - engines: {node: '>=v18'} - - '@commitlint/lint@19.8.1': - resolution: {integrity: sha512-52PFbsl+1EvMuokZXLRlOsdcLHf10isTPlWwoY1FQIidTsTvjKXVXYb7AvtpWkDzRO2ZsqIgPK7bI98x8LRUEw==} - engines: {node: '>=v18'} - - '@commitlint/load@19.8.1': - resolution: {integrity: sha512-9V99EKG3u7z+FEoe4ikgq7YGRCSukAcvmKQuTtUyiYPnOd9a2/H9Ak1J9nJA1HChRQp9OA/sIKPugGS+FK/k1A==} - engines: {node: '>=v18'} - - '@commitlint/message@19.8.1': - resolution: {integrity: sha512-+PMLQvjRXiU+Ae0Wc+p99EoGEutzSXFVwQfa3jRNUZLNW5odZAyseb92OSBTKCu+9gGZiJASt76Cj3dLTtcTdg==} - engines: {node: '>=v18'} - - '@commitlint/parse@19.8.1': - resolution: {integrity: sha512-mmAHYcMBmAgJDKWdkjIGq50X4yB0pSGpxyOODwYmoexxxiUCy5JJT99t1+PEMK7KtsCtzuWYIAXYAiKR+k+/Jw==} - engines: {node: '>=v18'} - - '@commitlint/read@19.8.1': - resolution: {integrity: sha512-03Jbjb1MqluaVXKHKRuGhcKWtSgh3Jizqy2lJCRbRrnWpcM06MYm8th59Xcns8EqBYvo0Xqb+2DoZFlga97uXQ==} - engines: {node: '>=v18'} - - '@commitlint/resolve-extends@19.8.1': - resolution: {integrity: sha512-GM0mAhFk49I+T/5UCYns5ayGStkTt4XFFrjjf0L4S26xoMTSkdCf9ZRO8en1kuopC4isDFuEm7ZOm/WRVeElVg==} - engines: {node: '>=v18'} - - '@commitlint/rules@19.8.1': - resolution: {integrity: sha512-Hnlhd9DyvGiGwjfjfToMi1dsnw1EXKGJNLTcsuGORHz6SS9swRgkBsou33MQ2n51/boIDrbsg4tIBbRpEWK2kw==} - engines: {node: '>=v18'} - - '@commitlint/to-lines@19.8.1': - resolution: {integrity: sha512-98Mm5inzbWTKuZQr2aW4SReY6WUukdWXuZhrqf1QdKPZBCCsXuG87c+iP0bwtD6DBnmVVQjgp4whoHRVixyPBg==} - engines: {node: '>=v18'} - - '@commitlint/top-level@19.8.1': - resolution: {integrity: sha512-Ph8IN1IOHPSDhURCSXBz44+CIu+60duFwRsg6HqaISFHQHbmBtxVw4ZrFNIYUzEP7WwrNPxa2/5qJ//NK1FGcw==} - engines: {node: '>=v18'} - - '@commitlint/types@19.8.1': - resolution: {integrity: sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw==} - engines: {node: '>=v18'} - '@dokploy/trpc-openapi@0.0.4': resolution: {integrity: sha512-a7VKunKu9arq57bP9MPH7ikJuKfT5SILnNy70vMqf1stm5IrqMG3Y7CIFprFe0DZiw3bwjue0KpETIATBftN6w==} peerDependencies: @@ -1951,11 +1862,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==} @@ -3940,9 +3846,6 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - '@types/conventional-commits-parser@5.0.1': - resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} - '@types/d3-array@3.2.1': resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} @@ -4060,6 +3963,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==} @@ -4157,10 +4063,6 @@ packages: '@xterm/xterm@5.5.0': resolution: {integrity: sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==} - JSONStream@1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} - hasBin: true - abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -4220,9 +4122,6 @@ packages: peerDependencies: zod: ^3.25.76 || ^4 - ajv@8.17.1: - resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -4285,9 +4184,6 @@ packages: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} - array-ify@1.0.0: - resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} @@ -4302,9 +4198,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==} @@ -4431,10 +4324,6 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - camelcase-css@2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} @@ -4603,9 +4492,6 @@ packages: resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} - compare-func@2.0.0: - resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -4622,19 +4508,6 @@ packages: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} - conventional-changelog-angular@7.0.0: - resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} - engines: {node: '>=16'} - - conventional-changelog-conventionalcommits@7.0.2: - resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} - engines: {node: '>=16'} - - conventional-commits-parser@5.0.0: - resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} - engines: {node: '>=16'} - hasBin: true - cookie-es@1.2.2: resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} @@ -4651,23 +4524,6 @@ packages: core-js@3.42.0: resolution: {integrity: sha512-Sz4PP4ZA+Rq4II21qkNqOEDTDrCvcANId3xpIgB34NDkWc3UduWj2dqEtN9yZIq8Dk3HyPI33x9sqqU5C8sr0g==} - cosmiconfig-typescript-loader@6.1.0: - resolution: {integrity: sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==} - engines: {node: '>=v18'} - peerDependencies: - '@types/node': '*' - cosmiconfig: '>=9' - typescript: '>=5' - - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true - cpu-features@0.0.10: resolution: {integrity: sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==} engines: {node: '>=10.0.0'} @@ -4750,10 +4606,6 @@ packages: resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} engines: {node: '>=12'} - dargs@8.1.0: - resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} - engines: {node: '>=12'} - date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} @@ -4897,10 +4749,6 @@ packages: domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - dot-prop@5.3.0: - resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} - engines: {node: '>=8'} - dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} @@ -5044,10 +4892,6 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - env-paths@3.0.0: resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -5056,9 +4900,6 @@ packages: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -5154,9 +4995,6 @@ packages: fast-deep-equal@2.0.1: resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-equals@5.2.2: resolution: {integrity: sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==} engines: {node: '>=6.0.0'} @@ -5175,9 +5013,6 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.0.6: - resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} - fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -5192,10 +5027,6 @@ packages: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} - find-up@7.0.0: - resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} - engines: {node: '>=18'} - follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} @@ -5305,11 +5136,6 @@ packages: get-tsconfig@4.10.1: resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} - git-raw-commits@4.0.0: - resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} - engines: {node: '>=16'} - hasBin: true - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -5326,10 +5152,6 @@ packages: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported - global-directory@4.0.1: - resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} - engines: {node: '>=18'} - globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -5389,9 +5211,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==} @@ -5469,16 +5288,9 @@ packages: resolution: {integrity: sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==} engines: {node: '>=0.10.0'} - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - import-in-the-middle@1.14.2: resolution: {integrity: sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==} - import-meta-resolve@4.1.0: - resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} - indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} @@ -5501,10 +5313,6 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - ini@4.1.1: - resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - inline-style-parser@0.2.4: resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} @@ -5580,9 +5388,6 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -5634,10 +5439,6 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-obj@2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} - is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} @@ -5650,10 +5451,6 @@ packages: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-text-path@2.0.0: - resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} - engines: {node: '>=8'} - is-what@4.1.16: resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} engines: {node: '>=12.13'} @@ -5672,10 +5469,6 @@ packages: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} - hasBin: true - jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} @@ -5714,22 +5507,12 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-schema@0.4.0: resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - jsonparse@1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} - jsonwebtoken@9.0.2: resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} engines: {node: '>=12', npm: '>=6'} @@ -5792,60 +5575,6 @@ packages: leac@0.6.0: resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==} - lefthook-darwin-arm64@1.8.4: - resolution: {integrity: sha512-OS5MsU0gvd8LYSpuQCHtmDUqwNrJ/LjCO0LGC1wNepY4OkuVl9DfX+rQ506CVUQYZiGVcwy2/qPOOBjNzA5+wQ==} - cpu: [arm64] - os: [darwin] - - lefthook-darwin-x64@1.8.4: - resolution: {integrity: sha512-QLRsqK9aTMRcVW8qz4pzI2OWnGCEcaEPJlIiFjwstYsS+wfkooxOS0UkfVMjy+QoGgEcki+cxF/FoY7lE7DDtw==} - cpu: [x64] - os: [darwin] - - lefthook-freebsd-arm64@1.8.4: - resolution: {integrity: sha512-chnQ1m/Cmn9c0sLdk5HL2SToE5LBJv5uQMdH1IGRRcw+nEqWqrMnDXvM75caiJAyjmUGvPH3czKTJDzTFV1E+A==} - cpu: [arm64] - os: [freebsd] - - lefthook-freebsd-x64@1.8.4: - resolution: {integrity: sha512-KQi+WBUdnGLnK0rHOR58kbMH5TDVN1ZjZLu66Pv9FCG7Y7shR1qtaTXu+wmxdRhMvaLeQIXRsUEPjNRC66yMmA==} - cpu: [x64] - os: [freebsd] - - lefthook-linux-arm64@1.8.4: - resolution: {integrity: sha512-CXNcqIskLwTwQARidGdFqmNxpvOU3jsWPK4KA7pq2+QmlWJ64w98ebMvNBoUmRUCXqzmUm7Udf/jpfz2fobewQ==} - cpu: [arm64] - os: [linux] - - lefthook-linux-x64@1.8.4: - resolution: {integrity: sha512-pVNITkFBxUCEtamWSM/res2Gd48+m9YKbNyIBndAuZVC5pKV5aGKZy2DNq6PWUPYiUDPx+7hoAtCJg/tlAiqhw==} - cpu: [x64] - os: [linux] - - lefthook-openbsd-arm64@1.8.4: - resolution: {integrity: sha512-l+i/Dg5X36kYzhpMGSPE3rMbWy1KSytbLB9lY1PmxYb6LRH6iQTYIoxvLabVUwSBPSq8HtIFa50+bvC5+scfVA==} - cpu: [arm64] - os: [openbsd] - - lefthook-openbsd-x64@1.8.4: - resolution: {integrity: sha512-CqhDDPPX8oHzMLgNi/Reba823DRzj+eMNWQ8axvSiIG+zmG1w20xZH5QSs/mD3tjrND90yfDd90mWMt181qPyA==} - cpu: [x64] - os: [openbsd] - - lefthook-windows-arm64@1.8.4: - resolution: {integrity: sha512-dvpvorICmVjmw29Aiczg7DcaSzkd86bEBomiGq4UsAEk3+7ExLrlWJDLFsI6xLjMKmTxy+F7eXb2uDtuFC1N4g==} - cpu: [arm64] - os: [win32] - - lefthook-windows-x64@1.8.4: - resolution: {integrity: sha512-e+y8Jt4/7PnoplhOuK48twjGVJEsU4T3J5kxD4mWfl6Cbit0YSn4bme9nW41eqCqTUqOm+ky29XlfnPHFX5ZNA==} - cpu: [x64] - os: [win32] - - lefthook@1.8.4: - resolution: {integrity: sha512-XNyMaTWNRuADOaocYiHidgNkNDz8SCekpdNJ7lqceFcBT2zjumnb28/o7IMaNROpLBZdQkLkJXSeaQWGqn3kog==} - hasBin: true - lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -5870,10 +5599,6 @@ packages: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} - locate-path@7.2.0: - resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -5910,30 +5635,12 @@ packages: lodash.isstring@4.0.1: resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} - lodash.kebabcase@4.1.1: - resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash.mergewith@4.6.2: - resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} - lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - lodash.snakecase@4.1.1: - resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} - - lodash.startcase@4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - - lodash.uniq@4.5.0: - resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} - - lodash.upperfirst@4.3.1: - resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} - lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -6029,10 +5736,6 @@ packages: resolution: {integrity: sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==} engines: {node: '>= 4.0.0'} - meow@12.1.1: - resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} - engines: {node: '>=16.10'} - merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} @@ -6426,9 +6129,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'} @@ -6437,10 +6137,6 @@ packages: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} - p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - p-limit@5.0.0: resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} engines: {node: '>=18'} @@ -6449,10 +6145,6 @@ packages: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} - p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -6460,20 +6152,12 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - parse-entities@2.0.0: resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - parseley@0.12.1: resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==} @@ -6485,10 +6169,6 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -6993,10 +6673,6 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - require-in-the-middle@7.5.2: resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} engines: {node: '>=8.6.0'} @@ -7013,14 +6689,6 @@ packages: resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -7087,11 +6755,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'} @@ -7373,10 +7036,6 @@ packages: temporal-spec@0.2.4: resolution: {integrity: sha512-lDMFv4nKQrSjlkHKAlHVqKrBG4DyFfa9F74cmBZ3Iy3ed8yvWnlWSIdi4IKfSqwmazAohBNwiN64qGx4y5Q3IQ==} - text-extensions@2.4.0: - resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} - engines: {node: '>=8'} - theming@3.3.0: resolution: {integrity: sha512-u6l4qTJRDaWZsqa8JugaNt7Xd8PPl9+gonZaIe28vAhqgHMIG/DOyFPqiKN/gQLQYj05tHv+YQdNILL4zoiAVA==} engines: {node: '>=8'} @@ -7399,9 +7058,6 @@ packages: thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -7411,9 +7067,6 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@1.0.1: - resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} - tinypool@0.8.4: resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} engines: {node: '>=14.0.0'} @@ -7546,10 +7199,6 @@ packages: resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} engines: {node: '>=18.17'} - unicorn-magic@0.1.0: - resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} - engines: {node: '>=18'} - unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -7933,14 +7582,6 @@ snapshots: '@alloc/quick-lru@5.2.0': {} - '@babel/code-frame@7.27.1': - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/helper-validator-identifier@7.27.1': {} - '@babel/runtime-corejs3@7.27.3': dependencies: core-js-pure: 3.42.0 @@ -8077,116 +7718,6 @@ snapshots: style-mod: 4.1.2 w3c-keyname: 2.2.8 - '@commitlint/cli@19.8.1(@types/node@18.19.104)(typescript@5.8.3)': - dependencies: - '@commitlint/format': 19.8.1 - '@commitlint/lint': 19.8.1 - '@commitlint/load': 19.8.1(@types/node@18.19.104)(typescript@5.8.3) - '@commitlint/read': 19.8.1 - '@commitlint/types': 19.8.1 - tinyexec: 1.0.1 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - typescript - - '@commitlint/config-conventional@19.8.1': - dependencies: - '@commitlint/types': 19.8.1 - conventional-changelog-conventionalcommits: 7.0.2 - - '@commitlint/config-validator@19.8.1': - dependencies: - '@commitlint/types': 19.8.1 - ajv: 8.17.1 - - '@commitlint/ensure@19.8.1': - dependencies: - '@commitlint/types': 19.8.1 - lodash.camelcase: 4.3.0 - lodash.kebabcase: 4.1.1 - lodash.snakecase: 4.1.1 - lodash.startcase: 4.4.0 - lodash.upperfirst: 4.3.1 - - '@commitlint/execute-rule@19.8.1': {} - - '@commitlint/format@19.8.1': - dependencies: - '@commitlint/types': 19.8.1 - chalk: 5.4.1 - - '@commitlint/is-ignored@19.8.1': - dependencies: - '@commitlint/types': 19.8.1 - semver: 7.7.2 - - '@commitlint/lint@19.8.1': - dependencies: - '@commitlint/is-ignored': 19.8.1 - '@commitlint/parse': 19.8.1 - '@commitlint/rules': 19.8.1 - '@commitlint/types': 19.8.1 - - '@commitlint/load@19.8.1(@types/node@18.19.104)(typescript@5.8.3)': - dependencies: - '@commitlint/config-validator': 19.8.1 - '@commitlint/execute-rule': 19.8.1 - '@commitlint/resolve-extends': 19.8.1 - '@commitlint/types': 19.8.1 - chalk: 5.4.1 - cosmiconfig: 9.0.0(typescript@5.8.3) - cosmiconfig-typescript-loader: 6.1.0(@types/node@18.19.104)(cosmiconfig@9.0.0(typescript@5.8.3))(typescript@5.8.3) - lodash.isplainobject: 4.0.6 - lodash.merge: 4.6.2 - lodash.uniq: 4.5.0 - transitivePeerDependencies: - - '@types/node' - - typescript - - '@commitlint/message@19.8.1': {} - - '@commitlint/parse@19.8.1': - dependencies: - '@commitlint/types': 19.8.1 - conventional-changelog-angular: 7.0.0 - conventional-commits-parser: 5.0.0 - - '@commitlint/read@19.8.1': - dependencies: - '@commitlint/top-level': 19.8.1 - '@commitlint/types': 19.8.1 - git-raw-commits: 4.0.0 - minimist: 1.2.8 - tinyexec: 1.0.1 - - '@commitlint/resolve-extends@19.8.1': - dependencies: - '@commitlint/config-validator': 19.8.1 - '@commitlint/types': 19.8.1 - global-directory: 4.0.1 - import-meta-resolve: 4.1.0 - lodash.mergewith: 4.6.2 - resolve-from: 5.0.0 - - '@commitlint/rules@19.8.1': - dependencies: - '@commitlint/ensure': 19.8.1 - '@commitlint/message': 19.8.1 - '@commitlint/to-lines': 19.8.1 - '@commitlint/types': 19.8.1 - - '@commitlint/to-lines@19.8.1': {} - - '@commitlint/top-level@19.8.1': - dependencies: - find-up: 7.0.0 - - '@commitlint/types@19.8.1': - dependencies: - '@types/conventional-commits-parser': 5.0.1 - chalk: 5.4.1 - '@dokploy/trpc-openapi@0.0.4(@trpc/server@10.45.2)(@types/node@18.19.104)(zod@3.25.32)': dependencies: '@trpc/server': 10.45.2 @@ -8736,7 +8267,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 +8293,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 +8853,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 +9054,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 +9199,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': {} @@ -11278,10 +10804,6 @@ snapshots: dependencies: '@types/node': 20.17.51 - '@types/conventional-commits-parser@5.0.1': - dependencies: - '@types/node': 20.17.51 - '@types/d3-array@3.2.1': {} '@types/d3-color@3.1.3': {} @@ -11421,6 +10943,8 @@ snapshots: dependencies: '@types/node': 20.17.51 + '@types/semver@7.7.1': {} + '@types/shell-quote@1.7.5': {} '@types/shimmer@1.2.0': {} @@ -11535,11 +11059,6 @@ snapshots: '@xterm/xterm@5.5.0': {} - JSONStream@1.3.5: - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 - abbrev@1.1.1: {} abbrev@2.0.0: {} @@ -11600,13 +11119,6 @@ snapshots: '@opentelemetry/api': 1.9.0 zod: 3.25.32 - ajv@8.17.1: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - ansi-align@3.0.1: dependencies: string-width: 4.2.3 @@ -11657,8 +11169,6 @@ snapshots: dependencies: tslib: 2.8.1 - array-ify@1.0.0: {} - array-union@2.1.0: {} asn1@0.2.6: @@ -11673,8 +11183,6 @@ snapshots: assertion-error@1.1.0: {} - async-await-queue@2.1.4: {} - asynckit@0.4.0: {} atomic-sleep@1.0.0: {} @@ -11820,7 +11328,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: @@ -11852,8 +11360,6 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 - callsites@3.1.0: {} - camelcase-css@2.0.1: {} camelcase@5.3.1: {} @@ -12012,11 +11518,6 @@ snapshots: commander@9.5.0: {} - compare-func@2.0.0: - dependencies: - array-ify: 1.0.0 - dot-prop: 5.3.0 - concat-map@0.0.1: {} confbox@0.1.8: {} @@ -12032,21 +11533,6 @@ snapshots: dependencies: safe-buffer: 5.2.1 - conventional-changelog-angular@7.0.0: - dependencies: - compare-func: 2.0.0 - - conventional-changelog-conventionalcommits@7.0.2: - dependencies: - compare-func: 2.0.0 - - conventional-commits-parser@5.0.0: - dependencies: - JSONStream: 1.3.5 - is-text-path: 2.0.0 - meow: 12.1.1 - split2: 4.2.0 - cookie-es@1.2.2: {} copy-anything@3.0.5: @@ -12061,22 +11547,6 @@ snapshots: core-js@3.42.0: {} - cosmiconfig-typescript-loader@6.1.0(@types/node@18.19.104)(cosmiconfig@9.0.0(typescript@5.8.3))(typescript@5.8.3): - dependencies: - '@types/node': 18.19.104 - cosmiconfig: 9.0.0(typescript@5.8.3) - jiti: 2.4.2 - typescript: 5.8.3 - - cosmiconfig@9.0.0(typescript@5.8.3): - dependencies: - env-paths: 2.2.1 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - parse-json: 5.2.0 - optionalDependencies: - typescript: 5.8.3 - cpu-features@0.0.10: dependencies: buildcheck: 0.0.6 @@ -12160,8 +11630,6 @@ snapshots: d3-timer@3.0.1: {} - dargs@8.1.0: {} - date-fns@3.6.0: {} dateformat@4.6.3: {} @@ -12285,10 +11753,6 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 - dot-prop@5.3.0: - dependencies: - is-obj: 2.0.0 - dotenv@16.4.5: {} drange@1.1.1: {} @@ -12336,7 +11800,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: {} @@ -12352,16 +11816,10 @@ snapshots: entities@4.5.0: {} - env-paths@2.2.1: {} - env-paths@3.0.0: {} environment@1.1.0: {} - error-ex@1.3.2: - dependencies: - is-arrayish: 0.2.1 - es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -12533,8 +11991,6 @@ snapshots: fast-deep-equal@2.0.1: {} - fast-deep-equal@3.1.3: {} - fast-equals@5.2.2: {} fast-glob@3.3.3: @@ -12551,8 +12007,6 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-uri@3.0.6: {} - fastq@1.19.1: dependencies: reusify: 1.1.0 @@ -12570,12 +12024,6 @@ snapshots: locate-path: 5.0.0 path-exists: 4.0.0 - find-up@7.0.0: - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - unicorn-magic: 0.1.0 - follow-redirects@1.15.9: {} foreground-child@3.3.1: @@ -12650,7 +12098,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: @@ -12692,12 +12140,6 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - git-raw-commits@4.0.0: - dependencies: - dargs: 8.1.0 - meow: 12.1.1 - split2: 4.2.0 - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -12724,10 +12166,6 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 - global-directory@4.0.1: - dependencies: - ini: 4.1.1 - globby@11.1.0: dependencies: array-union: 2.1.0 @@ -12824,8 +12262,6 @@ snapshots: help-me@5.0.0: {} - hi-base32@0.5.1: {} - highlight.js@10.7.3: {} highlightjs-vue@1.0.0: {} @@ -12908,11 +12344,6 @@ snapshots: immutable@3.8.2: {} - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - import-in-the-middle@1.14.2: dependencies: acorn: 8.14.1 @@ -12920,8 +12351,6 @@ snapshots: cjs-module-lexer: 1.4.3 module-details-from-path: 1.0.4 - import-meta-resolve@4.1.0: {} - indent-string@4.0.0: {} indent-string@5.0.0: {} @@ -12937,8 +12366,6 @@ snapshots: ini@1.3.8: {} - ini@4.1.1: {} - inline-style-parser@0.2.4: {} inngest@3.40.1(h3@1.15.3)(hono@4.7.10)(next@16.0.10(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(typescript@5.8.3): @@ -13017,8 +12444,6 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 - is-arrayish@0.2.1: {} - is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -13057,18 +12482,12 @@ snapshots: is-number@7.0.0: {} - is-obj@2.0.0: {} - is-plain-obj@4.1.0: {} is-stream@2.0.1: {} is-stream@3.0.0: {} - is-text-path@2.0.0: - dependencies: - text-extensions: 2.4.0 - is-what@4.1.16: {} isexe@2.0.0: {} @@ -13083,8 +12502,6 @@ snapshots: jiti@1.21.7: {} - jiti@2.4.2: {} - jose@5.10.0: {} joycon@3.1.1: {} @@ -13117,16 +12534,10 @@ snapshots: json-buffer@3.0.1: {} - json-parse-even-better-errors@2.3.1: {} - - json-schema-traverse@1.0.0: {} - json-schema@0.4.0: {} json-stringify-safe@5.0.1: {} - jsonparse@1.3.1: {} - jsonwebtoken@9.0.2: dependencies: jws: 3.2.2 @@ -13138,7 +12549,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: @@ -13251,49 +12662,6 @@ snapshots: leac@0.6.0: {} - lefthook-darwin-arm64@1.8.4: - optional: true - - lefthook-darwin-x64@1.8.4: - optional: true - - lefthook-freebsd-arm64@1.8.4: - optional: true - - lefthook-freebsd-x64@1.8.4: - optional: true - - lefthook-linux-arm64@1.8.4: - optional: true - - lefthook-linux-x64@1.8.4: - optional: true - - lefthook-openbsd-arm64@1.8.4: - optional: true - - lefthook-openbsd-x64@1.8.4: - optional: true - - lefthook-windows-arm64@1.8.4: - optional: true - - lefthook-windows-x64@1.8.4: - optional: true - - lefthook@1.8.4: - optionalDependencies: - lefthook-darwin-arm64: 1.8.4 - lefthook-darwin-x64: 1.8.4 - lefthook-freebsd-arm64: 1.8.4 - lefthook-freebsd-x64: 1.8.4 - lefthook-linux-arm64: 1.8.4 - lefthook-linux-x64: 1.8.4 - lefthook-openbsd-arm64: 1.8.4 - lefthook-openbsd-x64: 1.8.4 - lefthook-windows-arm64: 1.8.4 - lefthook-windows-x64: 1.8.4 - lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} @@ -13331,10 +12699,6 @@ snapshots: dependencies: p-locate: 4.1.0 - locate-path@7.2.0: - dependencies: - p-locate: 6.0.0 - lodash.camelcase@4.3.0: {} lodash.castarray@4.4.0: {} @@ -13359,22 +12723,10 @@ snapshots: lodash.isstring@4.0.1: {} - lodash.kebabcase@4.1.1: {} - lodash.merge@4.6.2: {} - lodash.mergewith@4.6.2: {} - lodash.once@4.1.1: {} - lodash.snakecase@4.1.1: {} - - lodash.startcase@4.4.0: {} - - lodash.uniq@4.5.0: {} - - lodash.upperfirst@4.3.1: {} - lodash@4.17.21: {} log-update@6.1.0: @@ -13529,8 +12881,6 @@ snapshots: tree-dump: 1.0.3(tslib@2.8.1) tslib: 2.8.1 - meow@12.1.1: {} - merge-descriptors@1.0.3: {} merge-stream@2.0.0: {} @@ -13962,20 +13312,12 @@ 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: dependencies: p-try: 2.2.0 - p-limit@4.0.0: - dependencies: - yocto-queue: 1.2.1 - p-limit@5.0.0: dependencies: yocto-queue: 1.2.1 @@ -13984,18 +13326,10 @@ snapshots: dependencies: p-limit: 2.3.0 - p-locate@6.0.0: - dependencies: - p-limit: 4.0.0 - p-try@2.2.0: {} package-json-from-dist@1.0.1: {} - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - parse-entities@2.0.0: dependencies: character-entities: 1.2.4 @@ -14015,13 +13349,6 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 - parse-json@5.2.0: - dependencies: - '@babel/code-frame': 7.27.1 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - parseley@0.12.1: dependencies: leac: 0.6.0 @@ -14031,8 +13358,6 @@ snapshots: path-exists@4.0.0: {} - path-exists@5.0.0: {} - path-is-absolute@1.0.1: {} path-key@3.1.1: {} @@ -14575,8 +13900,6 @@ snapshots: require-directory@2.1.1: {} - require-from-string@2.0.2: {} - require-in-the-middle@7.5.2: dependencies: debug: 4.4.1 @@ -14593,10 +13916,6 @@ snapshots: resolve-alpn@1.2.1: {} - resolve-from@4.0.0: {} - - resolve-from@5.0.0: {} - resolve-pkg-maps@1.0.0: {} resolve@1.22.10: @@ -14674,10 +13993,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: {} @@ -15054,8 +14370,6 @@ snapshots: temporal-spec@0.2.4: {} - text-extensions@2.4.0: {} - theming@3.3.0(react@18.2.0): dependencies: hoist-non-react-statics: 3.3.2 @@ -15080,16 +14394,12 @@ snapshots: dependencies: real-require: 0.2.0 - through@2.3.8: {} - tiny-invariant@1.3.3: {} tiny-warning@1.0.3: {} tinybench@2.9.0: {} - tinyexec@1.0.1: {} - tinypool@0.8.4: {} tinyspy@2.2.1: {} @@ -15193,8 +14503,6 @@ snapshots: undici@6.21.3: {} - unicorn-magic@0.1.0: {} - unified@11.0.5: dependencies: '@types/unist': 3.0.3 diff --git a/schema.dbml b/schema.dbml index 5823a8ff3..d0845f3ed 100644 --- a/schema.dbml +++ b/schema.dbml @@ -276,7 +276,7 @@ table application { replicas integer [not null, default: 1] applicationStatus applicationStatus [not null, default: 'idle'] buildType buildType [not null, default: 'nixpacks'] - railpackVersion text [default: '0.2.2'] + railpackVersion text [default: '0.15.4'] herokuVersion text [default: '24'] publishDirectory text isStaticSpa boolean