diff --git a/web/drizzle/0032_shallow_vermin.sql b/web/drizzle/0032_shallow_vermin.sql
new file mode 100644
index 0000000..88e48f3
--- /dev/null
+++ b/web/drizzle/0032_shallow_vermin.sql
@@ -0,0 +1,2 @@
+ALTER TABLE "comfyui_deploy"."deployments" ADD COLUMN "share_slug" text;--> statement-breakpoint
+ALTER TABLE "comfyui_deploy"."deployments" ADD CONSTRAINT "deployments_share_slug_unique" UNIQUE("share_slug");
\ No newline at end of file
diff --git a/web/drizzle/meta/0032_snapshot.json b/web/drizzle/meta/0032_snapshot.json
new file mode 100644
index 0000000..a470ac9
--- /dev/null
+++ b/web/drizzle/meta/0032_snapshot.json
@@ -0,0 +1,776 @@
+{
+ "id": "1425ee00-66fb-4541-8da7-19b217944545",
+ "prevId": "1ca4fdb7-c0c4-4c39-8b47-f40282293da0",
+ "version": "5",
+ "dialect": "pg",
+ "tables": {
+ "api_keys": {
+ "name": "api_keys",
+ "schema": "comfyui_deploy",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "org_id": {
+ "name": "org_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked": {
+ "name": "revoked",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "api_keys_user_id_users_id_fk": {
+ "name": "api_keys_user_id_users_id_fk",
+ "tableFrom": "api_keys",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "api_keys_key_unique": {
+ "name": "api_keys_key_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "key"
+ ]
+ }
+ }
+ },
+ "deployments": {
+ "name": "deployments",
+ "schema": "comfyui_deploy",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "org_id": {
+ "name": "org_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workflow_version_id": {
+ "name": "workflow_version_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "machine_id": {
+ "name": "machine_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "share_slug": {
+ "name": "share_slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "showcase_media": {
+ "name": "showcase_media",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "environment": {
+ "name": "environment",
+ "type": "deployment_environment",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "deployments_user_id_users_id_fk": {
+ "name": "deployments_user_id_users_id_fk",
+ "tableFrom": "deployments",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "deployments_workflow_version_id_workflow_versions_id_fk": {
+ "name": "deployments_workflow_version_id_workflow_versions_id_fk",
+ "tableFrom": "deployments",
+ "tableTo": "workflow_versions",
+ "columnsFrom": [
+ "workflow_version_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "deployments_workflow_id_workflows_id_fk": {
+ "name": "deployments_workflow_id_workflows_id_fk",
+ "tableFrom": "deployments",
+ "tableTo": "workflows",
+ "columnsFrom": [
+ "workflow_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "deployments_machine_id_machines_id_fk": {
+ "name": "deployments_machine_id_machines_id_fk",
+ "tableFrom": "deployments",
+ "tableTo": "machines",
+ "columnsFrom": [
+ "machine_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "deployments_share_slug_unique": {
+ "name": "deployments_share_slug_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "share_slug"
+ ]
+ }
+ }
+ },
+ "machines": {
+ "name": "machines",
+ "schema": "comfyui_deploy",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "org_id": {
+ "name": "org_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "endpoint": {
+ "name": "endpoint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "disabled": {
+ "name": "disabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "auth_token": {
+ "name": "auth_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "machine_type",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'classic'"
+ },
+ "status": {
+ "name": "status",
+ "type": "machine_status",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'ready'"
+ },
+ "snapshot": {
+ "name": "snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "models": {
+ "name": "models",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gpu": {
+ "name": "gpu",
+ "type": "machine_gpu",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "build_machine_instance_id": {
+ "name": "build_machine_instance_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "build_log": {
+ "name": "build_log",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "machines_user_id_users_id_fk": {
+ "name": "machines_user_id_users_id_fk",
+ "tableFrom": "machines",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "users": {
+ "name": "users",
+ "schema": "comfyui_deploy",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "workflow_run_outputs": {
+ "name": "workflow_run_outputs",
+ "schema": "comfyui_deploy",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "data": {
+ "name": "data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "workflow_run_outputs_run_id_workflow_runs_id_fk": {
+ "name": "workflow_run_outputs_run_id_workflow_runs_id_fk",
+ "tableFrom": "workflow_run_outputs",
+ "tableTo": "workflow_runs",
+ "columnsFrom": [
+ "run_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "workflow_runs": {
+ "name": "workflow_runs",
+ "schema": "comfyui_deploy",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "workflow_version_id": {
+ "name": "workflow_version_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workflow_inputs": {
+ "name": "workflow_inputs",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "machine_id": {
+ "name": "machine_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin": {
+ "name": "origin",
+ "type": "workflow_run_origin",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'api'"
+ },
+ "status": {
+ "name": "status",
+ "type": "workflow_run_status",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not-started'"
+ },
+ "ended_at": {
+ "name": "ended_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "workflow_runs_workflow_version_id_workflow_versions_id_fk": {
+ "name": "workflow_runs_workflow_version_id_workflow_versions_id_fk",
+ "tableFrom": "workflow_runs",
+ "tableTo": "workflow_versions",
+ "columnsFrom": [
+ "workflow_version_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "workflow_runs_workflow_id_workflows_id_fk": {
+ "name": "workflow_runs_workflow_id_workflows_id_fk",
+ "tableFrom": "workflow_runs",
+ "tableTo": "workflows",
+ "columnsFrom": [
+ "workflow_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_runs_machine_id_machines_id_fk": {
+ "name": "workflow_runs_machine_id_machines_id_fk",
+ "tableFrom": "workflow_runs",
+ "tableTo": "machines",
+ "columnsFrom": [
+ "machine_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "workflows": {
+ "name": "workflows",
+ "schema": "comfyui_deploy",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "org_id": {
+ "name": "org_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "workflows_user_id_users_id_fk": {
+ "name": "workflows_user_id_users_id_fk",
+ "tableFrom": "workflows",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "workflow_versions": {
+ "name": "workflow_versions",
+ "schema": "comfyui_deploy",
+ "columns": {
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "workflow": {
+ "name": "workflow",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workflow_api": {
+ "name": "workflow_api",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "snapshot": {
+ "name": "snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "workflow_versions_workflow_id_workflows_id_fk": {
+ "name": "workflow_versions_workflow_id_workflows_id_fk",
+ "tableFrom": "workflow_versions",
+ "tableTo": "workflows",
+ "columnsFrom": [
+ "workflow_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ }
+ },
+ "enums": {
+ "deployment_environment": {
+ "name": "deployment_environment",
+ "values": {
+ "staging": "staging",
+ "production": "production",
+ "public-share": "public-share"
+ }
+ },
+ "machine_gpu": {
+ "name": "machine_gpu",
+ "values": {
+ "T4": "T4",
+ "A10G": "A10G",
+ "A100": "A100"
+ }
+ },
+ "machine_status": {
+ "name": "machine_status",
+ "values": {
+ "ready": "ready",
+ "building": "building",
+ "error": "error"
+ }
+ },
+ "machine_type": {
+ "name": "machine_type",
+ "values": {
+ "classic": "classic",
+ "runpod-serverless": "runpod-serverless",
+ "modal-serverless": "modal-serverless",
+ "comfy-deploy-serverless": "comfy-deploy-serverless"
+ }
+ },
+ "workflow_run_origin": {
+ "name": "workflow_run_origin",
+ "values": {
+ "manual": "manual",
+ "api": "api",
+ "public-share": "public-share"
+ }
+ },
+ "workflow_run_status": {
+ "name": "workflow_run_status",
+ "values": {
+ "not-started": "not-started",
+ "running": "running",
+ "uploading": "uploading",
+ "success": "success",
+ "failed": "failed"
+ }
+ }
+ },
+ "schemas": {
+ "comfyui_deploy": "comfyui_deploy"
+ },
+ "_meta": {
+ "schemas": {},
+ "tables": {},
+ "columns": {}
+ }
+}
\ No newline at end of file
diff --git a/web/drizzle/meta/_journal.json b/web/drizzle/meta/_journal.json
index 360bc49..a262f43 100644
--- a/web/drizzle/meta/_journal.json
+++ b/web/drizzle/meta/_journal.json
@@ -225,6 +225,13 @@
"when": 1705763980972,
"tag": "0031_fast_lyja",
"breakpoints": true
+ },
+ {
+ "idx": 32,
+ "version": "5",
+ "when": 1705806921697,
+ "tag": "0032_shallow_vermin",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/web/src/app/(app)/share/[share_id]/page.tsx b/web/src/app/(app)/share/[share_id]/page.tsx
index e49922d..c7cfb5b 100644
--- a/web/src/app/(app)/share/[share_id]/page.tsx
+++ b/web/src/app/(app)/share/[share_id]/page.tsx
@@ -2,11 +2,11 @@ import { ButtonActionMenu } from "@/components/ButtonActionLoader";
import { RunWorkflowInline } from "@/components/RunWorkflowInline";
import { PublicRunOutputs } from "@/components/VersionSelect";
import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
} from "@/components/ui/card";
import { db } from "@/db/db";
import { usersTable } from "@/db/schema";
@@ -14,9 +14,9 @@ import { getInputsFromWorkflow } from "@/lib/getInputsFromWorkflow";
import { getRelativeTime } from "@/lib/getRelativeTime";
import { setInitialUserData } from "@/lib/setInitialUserData";
import {
- cloneMachine,
- cloneWorkflow,
- findSharedDeployment,
+ cloneMachine,
+ cloneWorkflow,
+ findSharedDeployment,
} from "@/server/curdDeploments";
import { auth, clerkClient } from "@clerk/nextjs/server";
import { eq } from "drizzle-orm";
@@ -25,89 +25,87 @@ import { redirect } from "next/navigation";
export const maxDuration = 300; // 5 minutes
export default async function Page({
- params,
+ params,
}: {
- params: { share_id: string };
+ params: { share_id: string };
}) {
- const { userId } = await auth();
+ const { userId } = await auth();
- // If there is user, check if the user data is present
- if (userId) {
- const user = await db.query.usersTable.findFirst({
- where: eq(usersTable.id, userId),
- });
+ // If there is user, check if the user data is present
+ if (userId) {
+ const user = await db.query.usersTable.findFirst({
+ where: eq(usersTable.id, userId),
+ });
- if (!user) {
- await setInitialUserData(userId);
- }
- }
+ if (!user) {
+ await setInitialUserData(userId);
+ }
+ }
- const sharedDeployment = await findSharedDeployment(params.share_id);
+ const sharedDeployment = await findSharedDeployment(params.share_id);
- if (!sharedDeployment) return redirect("/");
+ if (!sharedDeployment) return redirect("/");
- const userName = sharedDeployment.workflow.org_id
- ? await clerkClient.organizations
- .getOrganization({
- organizationId: sharedDeployment.workflow.org_id,
- })
- .then((x) => x.name)
- : sharedDeployment.user.name;
+ const userName = sharedDeployment.workflow.org_id
+ ? await clerkClient.organizations
+ .getOrganization({
+ organizationId: sharedDeployment.workflow.org_id,
+ })
+ .then((x) => x.name)
+ : sharedDeployment.user.name;
- const inputs = getInputsFromWorkflow(sharedDeployment.version);
+ const inputs = getInputsFromWorkflow(sharedDeployment.version);
- return (
-
-
-
-
-
- {userName}
- {" / "}
- {sharedDeployment.workflow.name}
-
+ return (
+
+
+
+
+
+ {userName}
+ {" / "}
+ {sharedDeployment.workflow.name}
+
-
-
-
- {getRelativeTime(sharedDeployment?.updated_at)}
-
-
+
+
+
+ {getRelativeTime(sharedDeployment?.updated_at)}
+
+
-
-
- {sharedDeployment?.description && (
- <>{sharedDeployment?.description}>
- )}
-
-
-
-
-
-
- Run outputs
-
+
+
+ {sharedDeployment?.description && sharedDeployment?.description}
+
+
+
+
+
+
+ Run outputs
+
-
-
-
-
-
- );
+
+
+
+
+
+ );
}
diff --git a/web/src/app/(app)/workflows/[workflow_id]/@workflow/page.tsx b/web/src/app/(app)/workflows/[workflow_id]/@workflow/page.tsx
index c3c7904..620b2b4 100644
--- a/web/src/app/(app)/workflows/[workflow_id]/@workflow/page.tsx
+++ b/web/src/app/(app)/workflows/[workflow_id]/@workflow/page.tsx
@@ -1,13 +1,13 @@
+import { CreateShareButton } from "@/components/CreateShareButton";
import { MachinesWSMain } from "@/components/MachinesWS";
import { VersionDetails } from "@/components/VersionDetails";
import {
- CopyWorkflowVersion,
- CreateDeploymentButton,
- CreateShareButton,
- MachineSelect,
- RunWorkflowButton,
- VersionSelect,
- ViewWorkflowDetailsButton,
+ CopyWorkflowVersion,
+ CreateDeploymentButton,
+ MachineSelect,
+ RunWorkflowButton,
+ VersionSelect,
+ ViewWorkflowDetailsButton,
} from "@/components/VersionSelect";
import {
Card,
diff --git a/web/src/components/ButtonActionLoader.tsx b/web/src/components/ButtonActionLoader.tsx
index 9f517d4..568e87d 100644
--- a/web/src/components/ButtonActionLoader.tsx
+++ b/web/src/components/ButtonActionLoader.tsx
@@ -4,10 +4,10 @@ import { LoadingIcon } from "@/components/LoadingIcon";
import { callServerPromise } from "@/components/callServerPromise";
import { Button } from "@/components/ui/button";
import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger,
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useAuth, useClerk } from "@clerk/nextjs";
import { MoreVertical } from "lucide-react";
@@ -15,74 +15,80 @@ import { useRouter } from "next/navigation";
import { useState } from "react";
export function ButtonAction({
- action,
- children,
- ...rest
+ action,
+ children,
+ routerAction = "back",
+ ...rest
}: {
- action: () => Promise;
- children: React.ReactNode;
+ action: () => Promise;
+ routerAction?: "refresh" | "back";
+ children: React.ReactNode;
}) {
- const [pending, setPending] = useState(false);
- const router = useRouter();
+ const [pending, setPending] = useState(false);
+ const router = useRouter();
- return (
-
+ );
}
export function ButtonActionMenu(props: {
- title?: string;
- actions: {
- title: string;
- action: () => Promise;
- }[];
+ title?: string;
+ actions: {
+ title: string;
+ action: () => Promise;
+ }[];
}) {
- const user = useAuth();
- const [isLoading, setIsLoading] = useState(false);
- const clerk = useClerk();
+ const user = useAuth();
+ const [isLoading, setIsLoading] = useState(false);
+ const clerk = useClerk();
- return (
-
-
-
- {props.title}
- {isLoading ? : }
-
-
-
- {props.actions.map((action) => (
- {
- if (!user.isSignedIn) {
- clerk.openSignIn({
- redirectUrl: window.location.href,
- });
- return;
- }
+ return (
+
+
+
+ {props.title}
+ {isLoading ? : }
+
+
+
+ {props.actions.map((action) => (
+ {
+ if (!user.isSignedIn) {
+ clerk.openSignIn({
+ redirectUrl: window.location.href,
+ });
+ return;
+ }
- setIsLoading(true);
- await callServerPromise(action.action());
- setIsLoading(false);
- }}
- >
- {action.title}
-
- ))}
-
-
- );
+ setIsLoading(true);
+ await callServerPromise(action.action());
+ setIsLoading(false);
+ }}
+ >
+ {action.title}
+
+ ))}
+
+
+ );
}
diff --git a/web/src/components/CreateShareButton.tsx b/web/src/components/CreateShareButton.tsx
new file mode 100644
index 0000000..8447887
--- /dev/null
+++ b/web/src/components/CreateShareButton.tsx
@@ -0,0 +1,66 @@
+"use client";
+import { LoadingIcon } from "@/components/LoadingIcon";
+import { Button } from "@/components/ui/button";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu";
+import { createDeployments } from "@/server/curdDeploments";
+import type { getMachines } from "@/server/curdMachine";
+import type { findFirstTableWithVersion } from "@/server/findFirstTableWithVersion";
+import { Share } from "lucide-react";
+import { parseAsInteger, useQueryState } from "next-usequerystate";
+import { useState } from "react";
+import { useSelectedMachine } from "./VersionSelect";
+import { callServerPromise } from "./callServerPromise";
+
+export function CreateShareButton({
+ workflow,
+ machines,
+}: {
+ workflow: Awaited>;
+ machines: Awaited>;
+}) {
+ const [version] = useQueryState("version", {
+ defaultValue: workflow?.versions[0].version ?? 1,
+ ...parseAsInteger,
+ });
+ const [machine] = useSelectedMachine(machines);
+
+ const [isLoading, setIsLoading] = useState(false);
+ const workflow_version_id = workflow?.versions.find(
+ (x) => x.version === version,
+ )?.id;
+
+ return (
+
+
+
+ Share {isLoading ? : }
+
+
+
+ {
+ if (!workflow_version_id) return;
+
+ setIsLoading(true);
+ await callServerPromise(
+ createDeployments(
+ workflow.id,
+ workflow_version_id,
+ machine,
+ "public-share",
+ ),
+ );
+ setIsLoading(false);
+ }}
+ >
+ Public
+
+
+
+ );
+}
diff --git a/web/src/components/DeploymentDisplay.tsx b/web/src/components/DeploymentDisplay.tsx
index 631fbce..87be9a2 100644
--- a/web/src/components/DeploymentDisplay.tsx
+++ b/web/src/components/DeploymentDisplay.tsx
@@ -1,18 +1,18 @@
-import { DeploymentRow, SharePageDeploymentRow } from "./DeploymentRow";
import { CodeBlock } from "@/components/CodeBlock";
import {
- Dialog,
- DialogContent,
- DialogDescription,
- DialogHeader,
- DialogTitle,
- DialogTrigger,
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
} from "@/components/ui/dialog";
import { ScrollArea } from "@/components/ui/scroll-area";
import { TableRow } from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { getInputsFromWorkflow } from "@/lib/getInputsFromWorkflow";
import type { findAllDeployments } from "@/server/findAllRuns";
+import { DeploymentRow, SharePageDeploymentRow } from "./DeploymentRow";
const curlTemplate = `
curl --request POST \
@@ -83,144 +83,145 @@ const run = await client.getRun(run_id);
`;
export function DeploymentDisplay({
- deployment,
- domain,
+ deployment,
+ domain,
}: {
- deployment: Awaited>[0];
- domain: string;
+ deployment: Awaited>[0];
+ domain: string;
}) {
- const workflowInput = getInputsFromWorkflow(deployment.version);
+ const workflowInput = getInputsFromWorkflow(deployment.version);
- if (deployment.environment == "public-share") {
- return ;
- }
+ if (deployment.environment === "public-share") {
+ return ;
+ }
- return (
-
- );
+ return (
+
+ );
}
function formatCode(
- codeTemplate: string,
- deployment: Awaited>[0],
- domain: string,
- inputs?: ReturnType,
- inputsTabs?: number
+ codeTemplate: string,
+ deployment: Awaited>[0],
+ domain: string,
+ inputs?: ReturnType,
+ inputsTabs?: number,
) {
- if (inputs && inputs.length > 0) {
- codeTemplate = codeTemplate.replace(
- "inputs: {}",
- `inputs: ${JSON.stringify(
- Object.fromEntries(
- inputs.map((x) => {
- return [x?.input_id, ""];
- })
- ),
- null,
- 2
- )
- .split("\n")
- .map((line, index) => (index === 0 ? line : ` ${line}`)) // Add two spaces indentation except for the first line
- .join("\n")}`
- );
- } else {
- codeTemplate = codeTemplate.replace(
- `
+ if (inputs && inputs.length > 0) {
+ codeTemplate = codeTemplate.replace(
+ "inputs: {}",
+ `inputs: ${JSON.stringify(
+ Object.fromEntries(
+ inputs.map((x) => {
+ return [x?.input_id, ""];
+ }),
+ ),
+ null,
+ 2,
+ )
+ .split("\n")
+ .map((line, index) => (index === 0 ? line : ` ${line}`)) // Add two spaces indentation except for the first line
+ .join("\n")}`,
+ );
+ } else {
+ codeTemplate = codeTemplate.replace(
+ `
inputs: {}`,
- ""
- );
- }
- return codeTemplate
- .replace("", `${domain ?? "http://localhost:3000"}/api/run`)
- .replace("", deployment.id)
- .replace("", domain ?? "http://localhost:3000");
+ "",
+ );
+ }
+ return codeTemplate
+ .replace("", `${domain ?? "http://localhost:3000"}/api/run`)
+ .replace("", deployment.id)
+ .replace("", domain ?? "http://localhost:3000");
}
diff --git a/web/src/components/DeploymentRow.tsx b/web/src/components/DeploymentRow.tsx
index 13a06ed..2c35fa2 100644
--- a/web/src/components/DeploymentRow.tsx
+++ b/web/src/components/DeploymentRow.tsx
@@ -6,55 +6,57 @@ import type { findAllDeployments } from "@/server/findAllRuns";
import { useRouter } from "next/navigation";
export function SharePageDeploymentRow({
- deployment,
+ deployment,
}: {
- deployment: Awaited>[0];
+ deployment: Awaited>[0];
}) {
- const router = useRouter();
- return (
- {
- if (deployment.environment == "public-share") {
- router.push(`/share/${deployment.id}/settings`);
- }
- }}
- >
-
- {deployment.environment}
-
-
- {deployment.version?.version}
-
-
- {deployment.machine?.name}
-
-
- {getRelativeTime(deployment.updated_at)}
-
-
- );
+ const router = useRouter();
+ return (
+ {
+ if (deployment.environment === "public-share") {
+ router.push(
+ `/share/${deployment.share_slug ?? deployment.id}/settings`,
+ );
+ }
+ }}
+ >
+
+ {deployment.environment}
+
+
+ {deployment.version?.version}
+
+
+ {deployment.machine?.name}
+
+
+ {getRelativeTime(deployment.updated_at)}
+
+
+ );
}
export function DeploymentRow({
- deployment,
+ deployment,
}: {
- deployment: Awaited>[0];
+ deployment: Awaited>[0];
}) {
- return (
- <>
-
- {deployment.environment}
-
-
- {deployment.version?.version}
-
-
- {deployment.machine?.name}
-
-
- {getRelativeTime(deployment.updated_at)}
-
- >
- );
+ return (
+ <>
+
+ {deployment.environment}
+
+
+ {deployment.version?.version}
+
+
+ {deployment.machine?.name}
+
+
+ {getRelativeTime(deployment.updated_at)}
+
+ >
+ );
}
diff --git a/web/src/components/SharePageSettings.tsx b/web/src/components/SharePageSettings.tsx
index d43d9d9..f1f246a 100644
--- a/web/src/components/SharePageSettings.tsx
+++ b/web/src/components/SharePageSettings.tsx
@@ -58,13 +58,14 @@ export function SharePageSettings({
type="button"
>
Remove
-
+
View Share Page
diff --git a/web/src/components/VersionSelect.tsx b/web/src/components/VersionSelect.tsx
index 0f391b6..96edf18 100644
--- a/web/src/components/VersionSelect.tsx
+++ b/web/src/components/VersionSelect.tsx
@@ -1,8 +1,5 @@
"use client";
-import { workflowVersionInputsToZod } from "../lib/workflowVersionInputsToZod";
-import { callServerPromise } from "./callServerPromise";
-import fetcher from "./fetcher";
import { LoadingIcon } from "@/components/LoadingIcon";
import AutoForm, { AutoFormSubmit } from "@/components/ui/auto-form";
import { Badge } from "@/components/ui/badge";
@@ -44,20 +41,16 @@ import { checkStatus, createRun } from "@/server/createRun";
import { createDeployments } from "@/server/curdDeploments";
import type { getMachines } from "@/server/curdMachine";
import type { findFirstTableWithVersion } from "@/server/findFirstTableWithVersion";
-import {
- Copy,
- ExternalLink,
- Info,
- MoreVertical,
- Play,
- Share,
-} from "lucide-react";
+import { Copy, ExternalLink, Info, MoreVertical, Play } from "lucide-react";
import { parseAsInteger, useQueryState } from "next-usequerystate";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import useSWR from "swr";
import type { z } from "zod";
import { create } from "zustand";
+import { workflowVersionInputsToZod } from "../lib/workflowVersionInputsToZod";
+import { callServerPromise } from "./callServerPromise";
+import fetcher from "./fetcher";
export function VersionSelect({
workflow,
@@ -122,12 +115,14 @@ export function MachineSelect({
);
}
-function useSelectedMachine(machines: Awaited>) {
- const a = useQueryState("machine", {
- defaultValue: machines?.[0]?.id ?? "",
- });
+export function useSelectedMachine(
+ machines: Awaited>,
+) {
+ const a = useQueryState("machine", {
+ defaultValue: machines?.[0]?.id ?? "",
+ });
- return a;
+ return a;
}
type PublicRunStore = {
@@ -373,55 +368,6 @@ export function CreateDeploymentButton({
);
}
-export function CreateShareButton({
- workflow,
- machines,
-}: {
- workflow: Awaited>;
- machines: Awaited>;
-}) {
- const [version] = useQueryState("version", {
- defaultValue: workflow?.versions[0].version ?? 1,
- ...parseAsInteger,
- });
- const [machine] = useSelectedMachine(machines);
-
- const [isLoading, setIsLoading] = useState(false);
- const workflow_version_id = workflow?.versions.find(
- (x) => x.version === version
- )?.id;
-
- return (
-
-
-
- Share {isLoading ? : }
-
-
-
- {
- if (!workflow_version_id) return;
-
- setIsLoading(true);
- await callServerPromise(
- createDeployments(
- workflow.id,
- workflow_version_id,
- machine,
- "public-share"
- )
- );
- setIsLoading(false);
- }}
- >
- Public
-
-
-
- );
-}
-
export function CopyWorkflowVersion({
workflow,
}: {
diff --git a/web/src/db/schema.ts b/web/src/db/schema.ts
index 783717c..20372ff 100644
--- a/web/src/db/schema.ts
+++ b/web/src/db/schema.ts
@@ -257,30 +257,31 @@ export const showcaseMediaNullable = z
.nullable();
export const deploymentsTable = dbSchema.table("deployments", {
- id: uuid("id").primaryKey().defaultRandom().notNull(),
- user_id: text("user_id")
- .references(() => usersTable.id, {
- onDelete: "cascade",
- })
- .notNull(),
- org_id: text("org_id"),
- workflow_version_id: uuid("workflow_version_id")
- .notNull()
- .references(() => workflowVersionTable.id),
- workflow_id: uuid("workflow_id")
- .notNull()
- .references(() => workflowTable.id, {
- onDelete: "cascade",
- }),
- machine_id: uuid("machine_id")
- .notNull()
- .references(() => machinesTable.id),
- description: text("description"),
- showcase_media:
- jsonb("showcase_media").$type>(),
- environment: deploymentEnvironment("environment").notNull(),
- created_at: timestamp("created_at").defaultNow().notNull(),
- updated_at: timestamp("updated_at").defaultNow().notNull(),
+ id: uuid("id").primaryKey().defaultRandom().notNull(),
+ user_id: text("user_id")
+ .references(() => usersTable.id, {
+ onDelete: "cascade",
+ })
+ .notNull(),
+ org_id: text("org_id"),
+ workflow_version_id: uuid("workflow_version_id")
+ .notNull()
+ .references(() => workflowVersionTable.id),
+ workflow_id: uuid("workflow_id")
+ .notNull()
+ .references(() => workflowTable.id, {
+ onDelete: "cascade",
+ }),
+ machine_id: uuid("machine_id")
+ .notNull()
+ .references(() => machinesTable.id),
+ share_slug: text("share_slug").unique(),
+ description: text("description"),
+ showcase_media:
+ jsonb("showcase_media").$type>(),
+ environment: deploymentEnvironment("environment").notNull(),
+ created_at: timestamp("created_at").defaultNow().notNull(),
+ updated_at: timestamp("updated_at").defaultNow().notNull(),
});
export const publicShareDeployment = z.object({
diff --git a/web/src/server/curdDeploments.ts b/web/src/server/curdDeploments.ts
index 85270cf..9ea5190 100644
--- a/web/src/server/curdDeploments.ts
+++ b/web/src/server/curdDeploments.ts
@@ -7,247 +7,279 @@ import { createNewWorkflow } from "@/server/createNewWorkflow";
import { addCustomMachine } from "@/server/curdMachine";
import { withServerPromise } from "@/server/withServerPromise";
import { auth } from "@clerk/nextjs";
-import { and, eq, isNull } from "drizzle-orm";
+import { clerkClient } from "@clerk/nextjs/server";
+import slugify from "@sindresorhus/slugify";
+import { and, eq, isNull, or } from "drizzle-orm";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import "server-only";
+import { validate as isValidUUID } from "uuid";
import type { z } from "zod";
-
export async function createDeployments(
- workflow_id: string,
- version_id: string,
- machine_id: string,
- environment: DeploymentType["environment"]
+ workflow_id: string,
+ version_id: string,
+ machine_id: string,
+ environment: DeploymentType["environment"],
) {
- const { userId, orgId } = auth();
- if (!userId) throw new Error("No user id");
+ const { userId, orgId } = auth();
+ if (!userId) throw new Error("No user id");
- if (!machine_id) {
- throw new Error("No machine id provided");
- }
+ if (!machine_id) {
+ throw new Error("No machine id provided");
+ }
- // Same environment and same workflow
- const existingDeployment = await db.query.deploymentsTable.findFirst({
- where: and(
- eq(deploymentsTable.workflow_id, workflow_id),
- eq(deploymentsTable.environment, environment)
- ),
- });
+ // Same environment and same workflow
+ const existingDeployment = await db.query.deploymentsTable.findFirst({
+ where: and(
+ eq(deploymentsTable.workflow_id, workflow_id),
+ eq(deploymentsTable.environment, environment),
+ ),
+ });
- if (existingDeployment) {
- await db
- .update(deploymentsTable)
- .set({
- workflow_id,
- workflow_version_id: version_id,
- machine_id,
- org_id: orgId,
- })
- .where(eq(deploymentsTable.id, existingDeployment.id));
- } else {
- await db.insert(deploymentsTable).values({
- user_id: userId,
- workflow_id,
- workflow_version_id: version_id,
- machine_id,
- environment,
- org_id: orgId,
- });
- }
- revalidatePath(`/${workflow_id}`);
- return {
- message: `Successfully created deployment for ${environment}`,
- };
+ if (existingDeployment) {
+ await db
+ .update(deploymentsTable)
+ .set({
+ workflow_id,
+ workflow_version_id: version_id,
+ machine_id,
+ org_id: orgId,
+ })
+ .where(eq(deploymentsTable.id, existingDeployment.id));
+ } else {
+ const workflow = await db.query.workflowTable.findFirst({
+ where: eq(workflowTable.id, workflow_id),
+ with: {
+ user: {
+ columns: {
+ name: true,
+ },
+ },
+ },
+ });
+
+ if (!workflow) throw new Error("No workflow found");
+
+ const userName = workflow.org_id
+ ? await clerkClient.organizations
+ .getOrganization({
+ organizationId: workflow.org_id,
+ })
+ .then((x) => x.name)
+ : workflow.user.name;
+
+ await db.insert(deploymentsTable).values({
+ user_id: userId,
+ workflow_id,
+ workflow_version_id: version_id,
+ machine_id,
+ environment,
+ org_id: orgId,
+ share_slug: slugify(`${userName} ${workflow.name}`),
+ });
+ }
+ revalidatePath(`/${workflow_id}`);
+ return {
+ message: `Successfully created deployment for ${environment}`,
+ };
}
export async function findAllDeployments() {
- const { userId, orgId } = auth();
- if (!userId) throw new Error("No user id");
+ const { userId, orgId } = auth();
+ if (!userId) throw new Error("No user id");
- const deployments = await db.query.workflowTable.findMany({
- where: and(
- orgId
- ? eq(workflowTable.org_id, orgId)
- : and(eq(workflowTable.user_id, userId), isNull(workflowTable.org_id))
- ),
- columns: {
- name: true,
- },
- with: {
- deployments: {
- columns: {
- environment: true,
- },
- with: {
- version: {
- columns: {
- id: true,
- snapshot: true,
- },
- },
- },
- },
- },
- });
+ const deployments = await db.query.workflowTable.findMany({
+ where: and(
+ orgId
+ ? eq(workflowTable.org_id, orgId)
+ : and(eq(workflowTable.user_id, userId), isNull(workflowTable.org_id)),
+ ),
+ columns: {
+ name: true,
+ },
+ with: {
+ deployments: {
+ columns: {
+ environment: true,
+ },
+ with: {
+ version: {
+ columns: {
+ id: true,
+ snapshot: true,
+ },
+ },
+ },
+ },
+ },
+ });
- return deployments;
+ return deployments;
}
export async function findSharedDeployment(workflow_id: string) {
- const deploymentData = await db.query.deploymentsTable.findFirst({
- where: and(
- eq(deploymentsTable.environment, "public-share"),
- eq(deploymentsTable.id, workflow_id)
- ),
- with: {
- user: true,
- machine: true,
- workflow: {
- columns: {
- name: true,
- org_id: true,
- user_id: true,
- },
- },
- version: true,
- },
- });
+ const deploymentData = await db.query.deploymentsTable.findFirst({
+ where: and(
+ eq(deploymentsTable.environment, "public-share"),
+ isValidUUID(workflow_id)
+ ? eq(deploymentsTable.id, workflow_id)
+ : eq(deploymentsTable.share_slug, workflow_id),
+ ),
+ with: {
+ user: true,
+ machine: true,
+ workflow: {
+ columns: {
+ name: true,
+ org_id: true,
+ user_id: true,
+ },
+ },
+ version: true,
+ },
+ });
- return deploymentData;
+ return deploymentData;
}
export const removePublicShareDeployment = withServerPromise(
- async (deployment_id: string) => {
- await db
- .delete(deploymentsTable)
- .where(
- and(
- eq(deploymentsTable.environment, "public-share"),
- eq(deploymentsTable.id, deployment_id)
- )
- );
- }
+ async (deployment_id: string) => {
+ const [removed] = await db
+ .delete(deploymentsTable)
+ .where(
+ and(
+ eq(deploymentsTable.environment, "public-share"),
+ eq(deploymentsTable.id, deployment_id),
+ ),
+ ).returning();
+
+ // revalidatePath(
+ // `/workflows/${removed.workflow_id}`
+ // )
+ },
);
export const cloneWorkflow = withServerPromise(
- async (deployment_id: string) => {
- const deployment = await db.query.deploymentsTable.findFirst({
- where: and(
- eq(deploymentsTable.environment, "public-share"),
- eq(deploymentsTable.id, deployment_id)
- ),
- with: {
- version: true,
- workflow: true,
- },
- });
+ async (deployment_id: string) => {
+ const deployment = await db.query.deploymentsTable.findFirst({
+ where: and(
+ eq(deploymentsTable.environment, "public-share"),
+ eq(deploymentsTable.id, deployment_id),
+ ),
+ with: {
+ version: true,
+ workflow: true,
+ },
+ });
- if (!deployment) throw new Error("No deployment found");
+ if (!deployment) throw new Error("No deployment found");
- const { userId, orgId } = auth();
+ const { userId, orgId } = auth();
- if (!userId) throw new Error("No user id");
+ if (!userId) throw new Error("No user id");
- await createNewWorkflow({
- user_id: userId,
- org_id: orgId,
- workflow_name: `${deployment.workflow.name} (Cloned)`,
- workflowData: {
- workflow: deployment.version.workflow,
- workflow_api: deployment?.version.workflow_api,
- snapshot: deployment?.version.snapshot,
- },
- });
+ await createNewWorkflow({
+ user_id: userId,
+ org_id: orgId,
+ workflow_name: `${deployment.workflow.name} (Cloned)`,
+ workflowData: {
+ workflow: deployment.version.workflow,
+ workflow_api: deployment?.version.workflow_api,
+ snapshot: deployment?.version.snapshot,
+ },
+ });
- redirect(`/workflows/${deployment.workflow.id}`);
+ redirect(`/workflows/${deployment.workflow.id}`);
- return {
- message: "Successfully cloned workflow",
- };
- }
+ return {
+ message: "Successfully cloned workflow",
+ };
+ },
);
export const cloneMachine = withServerPromise(async (deployment_id: string) => {
- const deployment = await db.query.deploymentsTable.findFirst({
- where: and(
- eq(deploymentsTable.environment, "public-share"),
- eq(deploymentsTable.id, deployment_id)
- ),
- with: {
- machine: true,
- },
- });
+ const deployment = await db.query.deploymentsTable.findFirst({
+ where: and(
+ eq(deploymentsTable.environment, "public-share"),
+ eq(deploymentsTable.id, deployment_id),
+ ),
+ with: {
+ machine: true,
+ },
+ });
- if (!deployment) throw new Error("No deployment found");
- if (deployment.machine.type !== "comfy-deploy-serverless")
- throw new Error("Can only clone comfy-deploy-serverlesss");
+ if (!deployment) throw new Error("No deployment found");
+ if (deployment.machine.type !== "comfy-deploy-serverless")
+ throw new Error("Can only clone comfy-deploy-serverlesss");
- const { userId, orgId } = auth();
+ const { userId, orgId } = auth();
- if (!userId) throw new Error("No user id");
+ if (!userId) throw new Error("No user id");
- await addCustomMachine({
- gpu: deployment.machine.gpu,
- models: deployment.machine.models,
- snapshot: deployment.machine.snapshot,
- name: `${deployment.machine.name} (Cloned)`,
- type: "comfy-deploy-serverless",
- });
+ await addCustomMachine({
+ gpu: deployment.machine.gpu,
+ models: deployment.machine.models,
+ snapshot: deployment.machine.snapshot,
+ name: `${deployment.machine.name} (Cloned)`,
+ type: "comfy-deploy-serverless",
+ });
- return {
- message: "Successfully cloned workflow",
- };
+ return {
+ message: "Successfully cloned workflow",
+ };
});
export async function findUserShareDeployment(share_id: string) {
- const { userId, orgId } = auth();
+ const { userId, orgId } = auth();
- if (!userId) throw new Error("No user id");
+ if (!userId) throw new Error("No user id");
- const [deployment] = await db
- .select()
- .from(deploymentsTable)
- .where(
- and(
- eq(deploymentsTable.id, share_id),
- eq(deploymentsTable.environment, "public-share"),
- orgId
- ? eq(deploymentsTable.org_id, orgId)
- : and(
- eq(deploymentsTable.user_id, userId),
- isNull(deploymentsTable.org_id)
- )
- )
- );
+ const [deployment] = await db
+ .select()
+ .from(deploymentsTable)
+ .where(
+ and(
+ isValidUUID(share_id)
+ ? eq(deploymentsTable.id, share_id)
+ : eq(deploymentsTable.share_slug, share_id),
+ eq(deploymentsTable.environment, "public-share"),
+ orgId
+ ? eq(deploymentsTable.org_id, orgId)
+ : and(
+ eq(deploymentsTable.user_id, userId),
+ isNull(deploymentsTable.org_id),
+ ),
+ ),
+ );
- if (!deployment) throw new Error("No deployment found");
+ if (!deployment) throw new Error("No deployment found");
- return deployment;
+ return deployment;
}
export const updateSharePageInfo = withServerPromise(
- async ({
- id,
- ...data
- }: z.infer & {
- id: string;
- }) => {
- const { userId } = auth();
- if (!userId) return { error: "No user id" };
+ async ({
+ id,
+ ...data
+ }: z.infer & {
+ id: string;
+ }) => {
+ const { userId } = auth();
+ if (!userId) return { error: "No user id" };
- console.log(data);
+ console.log(data);
- const [deployment] = await db
- .update(deploymentsTable)
- .set(data)
- .where(
- and(
- eq(deploymentsTable.environment, "public-share"),
- eq(deploymentsTable.id, id)
- )
- )
- .returning();
+ const [deployment] = await db
+ .update(deploymentsTable)
+ .set(data)
+ .where(
+ and(
+ eq(deploymentsTable.environment, "public-share"),
+ eq(deploymentsTable.id, id),
+ ),
+ )
+ .returning();
- return { message: "Info Updated" };
- }
+ return { message: "Info Updated" };
+ },
);