fix: handle file upload status correctly, add serverless machine type
This commit is contained in:
parent
dc5ae7a7b1
commit
850d8473ad
@ -51,7 +51,8 @@ def post_prompt(json_data):
|
|||||||
if "client_id" in json_data:
|
if "client_id" in json_data:
|
||||||
extra_data["client_id"] = json_data["client_id"]
|
extra_data["client_id"] = json_data["client_id"]
|
||||||
if valid[0]:
|
if valid[0]:
|
||||||
prompt_id = str(uuid.uuid4())
|
# if the prompt id is provided
|
||||||
|
prompt_id = json_data.get("prompt_id") or str(uuid.uuid4())
|
||||||
outputs_to_execute = valid[2]
|
outputs_to_execute = valid[2]
|
||||||
prompt_server.prompt_queue.put(
|
prompt_server.prompt_queue.put(
|
||||||
(number, prompt_id, prompt, extra_data, outputs_to_execute)
|
(number, prompt_id, prompt, extra_data, outputs_to_execute)
|
||||||
@ -80,13 +81,17 @@ async def comfy_deploy_run(request):
|
|||||||
|
|
||||||
workflow_api = data.get("workflow_api")
|
workflow_api = data.get("workflow_api")
|
||||||
|
|
||||||
|
# The prompt id generated from comfy deploy, can be None
|
||||||
|
prompt_id = data.get("prompt_id")
|
||||||
|
|
||||||
for key in workflow_api:
|
for key in workflow_api:
|
||||||
if 'inputs' in workflow_api[key] and 'seed' in workflow_api[key]['inputs']:
|
if 'inputs' in workflow_api[key] and 'seed' in workflow_api[key]['inputs']:
|
||||||
workflow_api[key]['inputs']['seed'] = randomSeed()
|
workflow_api[key]['inputs']['seed'] = randomSeed()
|
||||||
|
|
||||||
prompt = {
|
prompt = {
|
||||||
"prompt": workflow_api,
|
"prompt": workflow_api,
|
||||||
"client_id": "comfy_deploy_instance" #api.client_id
|
"client_id": "comfy_deploy_instance", #api.client_id
|
||||||
|
"prompt_id": prompt_id
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -136,6 +141,19 @@ async def websocket_handler(request):
|
|||||||
sockets.pop(sid, None)
|
sockets.pop(sid, None)
|
||||||
return ws
|
return ws
|
||||||
|
|
||||||
|
@server.PromptServer.instance.routes.get('/comfyui-deploy/check-status')
|
||||||
|
async def comfy_deploy_check_status(request):
|
||||||
|
prompt_server = server.PromptServer.instance
|
||||||
|
prompt_id = request.rel_url.query.get('prompt_id', None)
|
||||||
|
if prompt_id in prompt_metadata:
|
||||||
|
return web.json_response({
|
||||||
|
"status": prompt_metadata[prompt_id]['status'].value
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
return web.json_response({
|
||||||
|
"message": "prompt_id not found"
|
||||||
|
})
|
||||||
|
|
||||||
async def send(event, data, sid=None):
|
async def send(event, data, sid=None):
|
||||||
try:
|
try:
|
||||||
if sid:
|
if sid:
|
||||||
@ -168,7 +186,7 @@ async def send_json_override(self, event, data, sid=None):
|
|||||||
update_run(prompt_id, Status.RUNNING)
|
update_run(prompt_id, Status.RUNNING)
|
||||||
|
|
||||||
# the last executing event is none, then the workflow is finished
|
# the last executing event is none, then the workflow is finished
|
||||||
if event == 'executing' and data.get('node') is None:
|
if event == 'executing' and data.get('node') is None and not have_pending_upload(prompt_id):
|
||||||
update_run(prompt_id, Status.SUCCESS)
|
update_run(prompt_id, Status.SUCCESS)
|
||||||
|
|
||||||
if event == 'execution_error':
|
if event == 'execution_error':
|
||||||
@ -176,7 +194,7 @@ async def send_json_override(self, event, data, sid=None):
|
|||||||
asyncio.create_task(update_run_with_output(prompt_id, data))
|
asyncio.create_task(update_run_with_output(prompt_id, data))
|
||||||
|
|
||||||
if event == 'executed' and 'node' in data and 'output' in data:
|
if event == 'executed' and 'node' in data and 'output' in data:
|
||||||
asyncio.create_task(update_run_with_output(prompt_id, data.get('output')))
|
asyncio.create_task(update_run_with_output(prompt_id, data.get('output'), node_id=data.get('node')))
|
||||||
# update_run_with_output(prompt_id, data.get('output'))
|
# update_run_with_output(prompt_id, data.get('output'))
|
||||||
|
|
||||||
|
|
||||||
@ -185,6 +203,7 @@ class Status(Enum):
|
|||||||
RUNNING = "running"
|
RUNNING = "running"
|
||||||
SUCCESS = "success"
|
SUCCESS = "success"
|
||||||
FAILED = "failed"
|
FAILED = "failed"
|
||||||
|
UPLOADING = "uploading"
|
||||||
|
|
||||||
def update_run(prompt_id, status: Status):
|
def update_run(prompt_id, status: Status):
|
||||||
if prompt_id not in prompt_metadata:
|
if prompt_id not in prompt_metadata:
|
||||||
@ -260,7 +279,47 @@ async def upload_file(prompt_id, filename, subfolder=None, content_type="image/p
|
|||||||
response = requests.put(ok.get("url"), headers=headers, data=data)
|
response = requests.put(ok.get("url"), headers=headers, data=data)
|
||||||
print("upload file response", response.status_code)
|
print("upload file response", response.status_code)
|
||||||
|
|
||||||
async def update_run_with_output(prompt_id, data):
|
def have_pending_upload(prompt_id):
|
||||||
|
if 'uploading_nodes' in prompt_metadata[prompt_id] and len(prompt_metadata[prompt_id]['uploading_nodes']) > 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def update_file_status(prompt_id, data, uploading, have_error=False, node_id=None):
|
||||||
|
if 'uploading_nodes' not in prompt_metadata[prompt_id]:
|
||||||
|
prompt_metadata[prompt_id]['uploading_nodes'] = set()
|
||||||
|
|
||||||
|
if node_id is not None:
|
||||||
|
if uploading:
|
||||||
|
prompt_metadata[prompt_id]['uploading_nodes'].add(node_id)
|
||||||
|
else:
|
||||||
|
prompt_metadata[prompt_id]['uploading_nodes'].discard(node_id)
|
||||||
|
|
||||||
|
# print(prompt_metadata[prompt_id])
|
||||||
|
# Update the remote status
|
||||||
|
|
||||||
|
if have_error:
|
||||||
|
update_run(prompt_id, Status.FAILED)
|
||||||
|
await send("failed", {
|
||||||
|
"prompt_id": prompt_id,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
|
||||||
|
# if there are still nodes that are uploading, then we set the status to uploading
|
||||||
|
if uploading and have_pending_upload(prompt_id):
|
||||||
|
if prompt_metadata[prompt_id]['status'] != Status.UPLOADING:
|
||||||
|
update_run(prompt_id, Status.UPLOADING)
|
||||||
|
await send("uploading", {
|
||||||
|
"prompt_id": prompt_id,
|
||||||
|
})
|
||||||
|
|
||||||
|
# if there are no nodes that are uploading, then we set the status to success
|
||||||
|
elif not uploading:
|
||||||
|
update_run(prompt_id, Status.SUCCESS)
|
||||||
|
await send("success", {
|
||||||
|
"prompt_id": prompt_id,
|
||||||
|
})
|
||||||
|
|
||||||
|
async def update_run_with_output(prompt_id, data, node_id=None):
|
||||||
if prompt_id in prompt_metadata:
|
if prompt_id in prompt_metadata:
|
||||||
status_endpoint = prompt_metadata[prompt_id]['status_endpoint']
|
status_endpoint = prompt_metadata[prompt_id]['status_endpoint']
|
||||||
|
|
||||||
@ -270,6 +329,13 @@ async def update_run_with_output(prompt_id, data):
|
|||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
have_upload = 'images' in data or 'files' in data
|
||||||
|
|
||||||
|
print("have_upload", have_upload)
|
||||||
|
|
||||||
|
if have_upload:
|
||||||
|
await update_file_status(prompt_id, data, True, node_id=node_id)
|
||||||
|
|
||||||
images = data.get('images', [])
|
images = data.get('images', [])
|
||||||
for image in images:
|
for image in images:
|
||||||
await upload_file(prompt_id, image.get("filename"), subfolder=image.get("subfolder"), type=image.get("type"), content_type=image.get("content_type", "image/png"))
|
await upload_file(prompt_id, image.get("filename"), subfolder=image.get("subfolder"), type=image.get("type"), content_type=image.get("content_type", "image/png"))
|
||||||
@ -278,6 +344,9 @@ async def update_run_with_output(prompt_id, data):
|
|||||||
for file in files:
|
for file in files:
|
||||||
await upload_file(prompt_id, file.get("filename"), subfolder=file.get("subfolder"), type=file.get("type"), content_type=image.get("content_type", "image/png"))
|
await upload_file(prompt_id, file.get("filename"), subfolder=file.get("subfolder"), type=file.get("type"), content_type=image.get("content_type", "image/png"))
|
||||||
|
|
||||||
|
if have_upload:
|
||||||
|
await update_file_status(prompt_id, data, False, node_id=node_id)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_type = type(e).__name__
|
error_type = type(e).__name__
|
||||||
stack_trace = traceback.format_exc().strip()
|
stack_trace = traceback.format_exc().strip()
|
||||||
@ -291,6 +360,7 @@ async def update_run_with_output(prompt_id, data):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await update_file_status(prompt_id, data, False, have_error=True)
|
||||||
print(body)
|
print(body)
|
||||||
print(f"Error occurred while uploading file: {e}")
|
print(f"Error occurred while uploading file: {e}")
|
||||||
|
|
||||||
|
BIN
web/bun.lockb
BIN
web/bun.lockb
Binary file not shown.
7
web/drizzle/0014_short_sunfire.sql
Normal file
7
web/drizzle/0014_short_sunfire.sql
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TYPE "machine_type" AS ENUM('classic', 'runpod-serverless');
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "comfyui_deploy"."machines" ADD COLUMN "type" "machine_type" DEFAULT 'classic' NOT NULL;
|
1
web/drizzle/0015_simple_killmonger.sql
Normal file
1
web/drizzle/0015_simple_killmonger.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "comfyui_deploy"."machines" ADD COLUMN "auth_token" text;
|
657
web/drizzle/meta/0014_snapshot.json
Normal file
657
web/drizzle/meta/0014_snapshot.json
Normal file
@ -0,0 +1,657 @@
|
|||||||
|
{
|
||||||
|
"id": "f29ccb7c-8e75-403f-bef6-60758f9db7c7",
|
||||||
|
"prevId": "61c93b0c-9eae-46b9-bed9-26ef9eed4d19",
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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": "no action",
|
||||||
|
"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": {}
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "machine_type",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "'classic'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"machine_type": {
|
||||||
|
"name": "machine_type",
|
||||||
|
"values": {
|
||||||
|
"classic": "classic",
|
||||||
|
"runpod-serverless": "runpod-serverless"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workflow_run_origin": {
|
||||||
|
"name": "workflow_run_origin",
|
||||||
|
"values": {
|
||||||
|
"manual": "manual",
|
||||||
|
"api": "api"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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": {}
|
||||||
|
}
|
||||||
|
}
|
663
web/drizzle/meta/0015_snapshot.json
Normal file
663
web/drizzle/meta/0015_snapshot.json
Normal file
@ -0,0 +1,663 @@
|
|||||||
|
{
|
||||||
|
"id": "92bef822-0089-48aa-8f43-5bba40cdce2e",
|
||||||
|
"prevId": "f29ccb7c-8e75-403f-bef6-60758f9db7c7",
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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": "no action",
|
||||||
|
"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": {}
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"machine_type": {
|
||||||
|
"name": "machine_type",
|
||||||
|
"values": {
|
||||||
|
"classic": "classic",
|
||||||
|
"runpod-serverless": "runpod-serverless"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workflow_run_origin": {
|
||||||
|
"name": "workflow_run_origin",
|
||||||
|
"values": {
|
||||||
|
"manual": "manual",
|
||||||
|
"api": "api"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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": {}
|
||||||
|
}
|
||||||
|
}
|
@ -99,6 +99,20 @@
|
|||||||
"when": 1703338425429,
|
"when": 1703338425429,
|
||||||
"tag": "0013_stormy_starbolt",
|
"tag": "0013_stormy_starbolt",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 14,
|
||||||
|
"version": "5",
|
||||||
|
"when": 1703403388113,
|
||||||
|
"tag": "0014_short_sunfire",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 15,
|
||||||
|
"version": "5",
|
||||||
|
"when": 1703409502387,
|
||||||
|
"tag": "0015_simple_killmonger",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -42,6 +42,7 @@
|
|||||||
"date-fns": "^3.0.5",
|
"date-fns": "^3.0.5",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"drizzle-orm": "^0.29.1",
|
"drizzle-orm": "^0.29.1",
|
||||||
|
"drizzle-zod": "^0.5.1",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"lucide-react": "^0.294.0",
|
"lucide-react": "^0.294.0",
|
||||||
"nanoid": "^5.0.4",
|
"nanoid": "^5.0.4",
|
||||||
|
123
web/src/components/InsertModal.tsx
Normal file
123
web/src/components/InsertModal.tsx
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { LoadingIcon } from "./LoadingIcon";
|
||||||
|
import { callServerPromise } from "@/components/callServerPromise";
|
||||||
|
import AutoForm, { AutoFormSubmit } from "@/components/ui/auto-form";
|
||||||
|
import type { FieldConfig } from "@/components/ui/auto-form/types";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import * as React from "react";
|
||||||
|
import type { UnknownKeysParam, ZodObject, ZodRawShape, z } from "zod";
|
||||||
|
|
||||||
|
export function InsertModal<
|
||||||
|
K extends ZodRawShape,
|
||||||
|
Y extends UnknownKeysParam,
|
||||||
|
Z extends ZodObject<K, Y>
|
||||||
|
>(props: {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
serverAction: (data: z.infer<Z>) => Promise<unknown>;
|
||||||
|
formSchema: Z;
|
||||||
|
fieldConfig?: FieldConfig<z.infer<Z>>;
|
||||||
|
}) {
|
||||||
|
const [open, setOpen] = React.useState(false);
|
||||||
|
const [isLoading, setIsLoading] = React.useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={setOpen}>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button variant="default" className="">
|
||||||
|
{props.title}
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="sm:max-w-[425px]">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>{props.title}</DialogTitle>
|
||||||
|
<DialogDescription>{props.description}</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<AutoForm
|
||||||
|
fieldConfig={props.fieldConfig}
|
||||||
|
formSchema={props.formSchema}
|
||||||
|
onSubmit={async (data) => {
|
||||||
|
setIsLoading(true);
|
||||||
|
await callServerPromise(props.serverAction(data));
|
||||||
|
setIsLoading(false);
|
||||||
|
setOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<AutoFormSubmit>
|
||||||
|
Save Changes
|
||||||
|
<span className="ml-2">{isLoading && <LoadingIcon />}</span>
|
||||||
|
</AutoFormSubmit>
|
||||||
|
</div>
|
||||||
|
</AutoForm>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function UpdateModal<
|
||||||
|
K extends ZodRawShape,
|
||||||
|
Y extends UnknownKeysParam,
|
||||||
|
Z extends ZodObject<K, Y>
|
||||||
|
>(props: {
|
||||||
|
open: boolean;
|
||||||
|
setOpen: (open: boolean) => void;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
data: z.infer<Z>;
|
||||||
|
serverAction: (
|
||||||
|
data: z.infer<Z> & {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
) => Promise<unknown>;
|
||||||
|
formSchema: Z;
|
||||||
|
fieldConfig?: FieldConfig<z.infer<Z>>;
|
||||||
|
}) {
|
||||||
|
// const [open, setOpen] = React.useState(false);
|
||||||
|
const [isLoading, setIsLoading] = React.useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={props.open} onOpenChange={props.setOpen}>
|
||||||
|
{/* <DialogTrigger asChild>
|
||||||
|
<DropdownMenuItem>{props.title}</DropdownMenuItem>
|
||||||
|
</DialogTrigger> */}
|
||||||
|
<DialogContent className="sm:max-w-[425px]">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>{props.title}</DialogTitle>
|
||||||
|
<DialogDescription>{props.description}</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<AutoForm
|
||||||
|
fieldConfig={props.fieldConfig}
|
||||||
|
formSchema={props.formSchema}
|
||||||
|
onSubmit={async (data) => {
|
||||||
|
setIsLoading(true);
|
||||||
|
await callServerPromise(
|
||||||
|
props.serverAction({
|
||||||
|
...data,
|
||||||
|
id: props.data.id,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
setIsLoading(false);
|
||||||
|
props.setOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<AutoFormSubmit>
|
||||||
|
Save Changes
|
||||||
|
<span className="ml-2">{isLoading && <LoadingIcon />}</span>
|
||||||
|
</AutoFormSubmit>
|
||||||
|
</div>
|
||||||
|
</AutoForm>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
@ -5,7 +5,7 @@ import { StatusBadge } from "@/components/StatusBadge";
|
|||||||
import { TableCell } from "@/components/ui/table";
|
import { TableCell } from "@/components/ui/table";
|
||||||
import { type findAllRuns } from "@/server/findAllRuns";
|
import { type findAllRuns } from "@/server/findAllRuns";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
export function LiveStatus({
|
export function LiveStatus({
|
||||||
run,
|
run,
|
||||||
@ -16,23 +16,30 @@ export function LiveStatus({
|
|||||||
(state) =>
|
(state) =>
|
||||||
state.data
|
state.data
|
||||||
.filter((x) => x.id === run.id)
|
.filter((x) => x.id === run.id)
|
||||||
.sort((a, b) => b.timestamp - a.timestamp)?.[0],
|
.sort((a, b) => b.timestamp - a.timestamp)?.[0]
|
||||||
);
|
);
|
||||||
|
|
||||||
let status = run.status;
|
let status = run.status;
|
||||||
|
|
||||||
// const [view, setView] = useState<any>();
|
// const [view, setView] = useState<any>();
|
||||||
if (data?.json.event == "executing" && data.json.data.node == undefined) {
|
// if (data?.json.event == "executing" && data.json.data.node == undefined) {
|
||||||
status = "success";
|
// status = "success";
|
||||||
} else if (data?.json.event == "executing") {
|
// } else
|
||||||
|
if (data?.json.event == "executing") {
|
||||||
status = "running";
|
status = "running";
|
||||||
|
} else if (data?.json.event == "uploading") {
|
||||||
|
status = "uploading";
|
||||||
|
} else if (data?.json.event == "success") {
|
||||||
|
status = "success";
|
||||||
|
} else if (data?.json.event == "failed") {
|
||||||
|
status = "failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.json.event === "outputs_uploaded") {
|
if (data?.json.event === "outputs_uploaded") {
|
||||||
router.refresh()
|
router.refresh();
|
||||||
}
|
}
|
||||||
}, [data?.json.event]);
|
}, [data?.json.event]);
|
||||||
|
|
||||||
|
@ -1,28 +1,11 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { getRelativeTime } from "../lib/getRelativeTime";
|
import { getRelativeTime } from "../lib/getRelativeTime";
|
||||||
import { LoadingIcon } from "./LoadingIcon";
|
import { InsertModal, UpdateModal } from "./InsertModal";
|
||||||
import { callServerPromise } from "./callServerPromise";
|
import { callServerPromise } from "./callServerPromise";
|
||||||
import {
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
Form,
|
|
||||||
} from "./ui/form";
|
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogDescription,
|
|
||||||
DialogFooter,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
} from "@/components/ui/dialog";
|
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
@ -39,14 +22,15 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import type { MachineType } from "@/db/schema";
|
import { type MachineType } from "@/db/schema";
|
||||||
|
import { addMachineSchema } from "@/server/addMachineSchema";
|
||||||
import {
|
import {
|
||||||
addMachine,
|
addMachine,
|
||||||
deleteMachine,
|
deleteMachine,
|
||||||
disableMachine,
|
disableMachine,
|
||||||
enableMachine,
|
enableMachine,
|
||||||
|
updateMachine,
|
||||||
} from "@/server/curdMachine";
|
} from "@/server/curdMachine";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import type {
|
import type {
|
||||||
ColumnDef,
|
ColumnDef,
|
||||||
ColumnFiltersState,
|
ColumnFiltersState,
|
||||||
@ -63,8 +47,7 @@ import {
|
|||||||
} from "@tanstack/react-table";
|
} from "@tanstack/react-table";
|
||||||
import { ArrowUpDown, MoreHorizontal } from "lucide-react";
|
import { ArrowUpDown, MoreHorizontal } from "lucide-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useState } from "react";
|
||||||
import { z } from "zod";
|
|
||||||
|
|
||||||
export type Machine = MachineType;
|
export type Machine = MachineType;
|
||||||
|
|
||||||
@ -127,6 +110,13 @@ export const columns: ColumnDef<Machine>[] = [
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "type",
|
||||||
|
header: () => <div className="text-left">Type</div>,
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return <div className="text-left font-medium">{row.original.type}</div>;
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
accessorKey: "date",
|
accessorKey: "date",
|
||||||
sortingFn: "datetime",
|
sortingFn: "datetime",
|
||||||
@ -154,6 +144,7 @@ export const columns: ColumnDef<Machine>[] = [
|
|||||||
enableHiding: false,
|
enableHiding: false,
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const machine = row.original;
|
const machine = row.original;
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
@ -191,10 +182,33 @@ export const columns: ColumnDef<Machine>[] = [
|
|||||||
Disable Machine
|
Disable Machine
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
{/* <DropdownMenuSeparator />
|
<DropdownMenuItem onClick={() => setOpen(true)}>
|
||||||
<DropdownMenuItem>View customer</DropdownMenuItem>
|
Edit
|
||||||
<DropdownMenuItem>View payment details</DropdownMenuItem> */}
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
|
<UpdateModal
|
||||||
|
fieldConfig={{
|
||||||
|
name: {
|
||||||
|
inputProps: { defaultValue: machine.name },
|
||||||
|
},
|
||||||
|
endpoint: {
|
||||||
|
inputProps: { defaultValue: machine.endpoint },
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
inputProps: { defaultValue: machine.type },
|
||||||
|
},
|
||||||
|
auth_token: {
|
||||||
|
inputProps: { defaultValue: machine.auth_token ?? "" },
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
data={machine}
|
||||||
|
open={open}
|
||||||
|
setOpen={setOpen}
|
||||||
|
title="Edit"
|
||||||
|
description="Edit machines"
|
||||||
|
serverAction={updateMachine}
|
||||||
|
formSchema={addMachineSchema}
|
||||||
|
/>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -241,33 +255,12 @@ export function MachineList({ data }: { data: Machine[] }) {
|
|||||||
className="max-w-sm"
|
className="max-w-sm"
|
||||||
/>
|
/>
|
||||||
<div className="ml-auto flex gap-2">
|
<div className="ml-auto flex gap-2">
|
||||||
<AddMachinesDialog />
|
<InsertModal
|
||||||
{/* <DropdownMenu>
|
title="Add Machine"
|
||||||
<DropdownMenuTrigger asChild>
|
description="Add Comfyui machines to your account."
|
||||||
<Button variant="outline" className="">
|
serverAction={addMachine}
|
||||||
Columns <ChevronDown className="ml-2 h-4 w-4" />
|
formSchema={addMachineSchema}
|
||||||
</Button>
|
/>
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
{table
|
|
||||||
.getAllColumns()
|
|
||||||
.filter((column) => column.getCanHide())
|
|
||||||
.map((column) => {
|
|
||||||
return (
|
|
||||||
<DropdownMenuCheckboxItem
|
|
||||||
key={column.id}
|
|
||||||
className="capitalize"
|
|
||||||
checked={column.getIsVisible()}
|
|
||||||
onCheckedChange={(value) =>
|
|
||||||
column.toggleVisibility(!!value)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{column.id}
|
|
||||||
</DropdownMenuCheckboxItem>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu> */}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="rounded-md border overflow-x-auto w-full">
|
<div className="rounded-md border overflow-x-auto w-full">
|
||||||
@ -347,95 +340,3 @@ export function MachineList({ data }: { data: Machine[] }) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
name: z.string().min(1),
|
|
||||||
endpoint: z.string().min(1),
|
|
||||||
});
|
|
||||||
|
|
||||||
function AddMachinesDialog() {
|
|
||||||
const [open, setOpen] = React.useState(false);
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
name: "My Local Machine",
|
|
||||||
endpoint: "http://127.0.0.1:8188",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog open={open} onOpenChange={setOpen}>
|
|
||||||
<DialogTrigger asChild>
|
|
||||||
<Button variant="default" className="">
|
|
||||||
Add Machines
|
|
||||||
</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent className="sm:max-w-[425px]">
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={form.handleSubmit(async (data) => {
|
|
||||||
await addMachine(data.name, data.endpoint);
|
|
||||||
// await new Promise(resolve => setTimeout(resolve, 3000));
|
|
||||||
setOpen(false);
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>Add Machines</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
Add Comfyui machines to your account.
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<div className="grid gap-4 py-4">
|
|
||||||
{/* <div className="grid grid-cols-4 items-center gap-4"> */}
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>Name</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
{/* <FormDescription>
|
|
||||||
This is your public display name.
|
|
||||||
</FormDescription> */}
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="endpoint"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>Endpoint</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
{/* <FormDescription>
|
|
||||||
This is your public display name.
|
|
||||||
</FormDescription> */}
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<DialogFooter>
|
|
||||||
<AddWorkflowButton pending={form.formState.isSubmitting} />
|
|
||||||
</DialogFooter>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddWorkflowButton({ pending }: { pending: boolean }) {
|
|
||||||
// const { pending } = useFormStatus();
|
|
||||||
return (
|
|
||||||
<Button type="submit" disabled={pending}>
|
|
||||||
Save changes {pending && <LoadingIcon />}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
@ -62,7 +62,9 @@ export function MachinesWSMain(props: {
|
|||||||
<div className="flex flex-col gap-2 mt-4">
|
<div className="flex flex-col gap-2 mt-4">
|
||||||
Machine Status
|
Machine Status
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
{props.machines.map((x) => (
|
{props.machines
|
||||||
|
.filter((x) => x.type === "classic")
|
||||||
|
.map((x) => (
|
||||||
<MachineWS key={x.id} machine={x} />
|
<MachineWS key={x.id} machine={x} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@ -112,13 +114,14 @@ function MachineWS({
|
|||||||
if (!lastMessage?.data) return;
|
if (!lastMessage?.data) return;
|
||||||
|
|
||||||
const message = JSON.parse(lastMessage.data);
|
const message = JSON.parse(lastMessage.data);
|
||||||
console.log(message.event, message);
|
// console.log(message.event, message);
|
||||||
|
|
||||||
if (message.data.sid) {
|
if (message.data.sid) {
|
||||||
setSid(message.data.sid);
|
setSid(message.data.sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.data?.prompt_id) {
|
if (message.data?.prompt_id) {
|
||||||
|
console.log(message.event, message);
|
||||||
addData(message.data.prompt_id, message);
|
addData(message.data.prompt_id, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
import * as z from "zod";
|
|
||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { FieldConfig, FieldConfigItem } from "../types";
|
|
||||||
import {
|
import {
|
||||||
Accordion,
|
Accordion,
|
||||||
AccordionContent,
|
AccordionContent,
|
||||||
AccordionItem,
|
AccordionItem,
|
||||||
AccordionTrigger,
|
AccordionTrigger,
|
||||||
} from "../../accordion";
|
} from "../../accordion";
|
||||||
|
import { FormField } from "../../form";
|
||||||
|
import { DEFAULT_ZOD_HANDLERS, INPUT_COMPONENTS } from "../config";
|
||||||
|
import type { FieldConfig, FieldConfigItem } from "../types";
|
||||||
import {
|
import {
|
||||||
beautifyObjectName,
|
beautifyObjectName,
|
||||||
getBaseSchema,
|
getBaseSchema,
|
||||||
getBaseType,
|
getBaseType,
|
||||||
zodToHtmlInputProps,
|
zodToHtmlInputProps,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
import { FormField } from "../../form";
|
|
||||||
import { DEFAULT_ZOD_HANDLERS, INPUT_COMPONENTS } from "../config";
|
|
||||||
import AutoFormArray from "./array";
|
import AutoFormArray from "./array";
|
||||||
|
import type { useForm } from "react-hook-form";
|
||||||
|
import type * as z from "zod";
|
||||||
|
|
||||||
function DefaultParent({ children }: { children: React.ReactNode }) {
|
function DefaultParent({ children }: { children: React.ReactNode }) {
|
||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AutoFormObject<
|
export default function AutoFormObject<
|
||||||
SchemaType extends z.ZodObject<any, any>,
|
SchemaType extends z.ZodObject<any, any>
|
||||||
>({
|
>({
|
||||||
schema,
|
schema,
|
||||||
form,
|
form,
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { Form } from "../form";
|
|
||||||
import { DefaultValues, useForm } from "react-hook-form";
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { Button } from "../button";
|
import { Button } from "../button";
|
||||||
|
import { Form } from "../form";
|
||||||
|
import type { FieldConfig } from "./types";
|
||||||
|
import type { ZodObjectOrWrapped } from "./utils";
|
||||||
|
import { getDefaultValues, getObjectFormSchema } from "./utils";
|
||||||
|
import AutoFormObject from "@/components/ui/auto-form/fields/object";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { FieldConfig } from "./types";
|
import type { DefaultValues } from "react-hook-form";
|
||||||
import {
|
import { useForm } from "react-hook-form";
|
||||||
ZodObjectOrWrapped,
|
import type { z } from "zod";
|
||||||
getDefaultValues,
|
|
||||||
getObjectFormSchema,
|
|
||||||
} from "./utils";
|
|
||||||
import AutoFormObject from "./fields/object";
|
|
||||||
|
|
||||||
export function AutoFormSubmit({ children }: { children?: React.ReactNode }) {
|
export function AutoFormSubmit({ children }: { children?: React.ReactNode }) {
|
||||||
return <Button type="submit">{children ?? "Submit"}</Button>;
|
return <Button type="submit">{children ?? "Submit"}</Button>;
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
pgEnum,
|
pgEnum,
|
||||||
boolean,
|
boolean,
|
||||||
} from "drizzle-orm/pg-core";
|
} from "drizzle-orm/pg-core";
|
||||||
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
export const dbSchema = pgSchema("comfyui_deploy");
|
export const dbSchema = pgSchema("comfyui_deploy");
|
||||||
@ -100,6 +101,11 @@ export const workflowRunOrigin = pgEnum("workflow_run_origin", [
|
|||||||
"api",
|
"api",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
export const machinesType = pgEnum("machine_type", [
|
||||||
|
"classic",
|
||||||
|
"runpod-serverless",
|
||||||
|
]);
|
||||||
|
|
||||||
// We still want to keep the workflow run record.
|
// We still want to keep the workflow run record.
|
||||||
export const workflowRunsTable = dbSchema.table("workflow_runs", {
|
export const workflowRunsTable = dbSchema.table("workflow_runs", {
|
||||||
id: uuid("id").primaryKey().defaultRandom().notNull(),
|
id: uuid("id").primaryKey().defaultRandom().notNull(),
|
||||||
@ -178,6 +184,14 @@ export const machinesTable = dbSchema.table("machines", {
|
|||||||
created_at: timestamp("created_at").defaultNow().notNull(),
|
created_at: timestamp("created_at").defaultNow().notNull(),
|
||||||
updated_at: timestamp("updated_at").defaultNow().notNull(),
|
updated_at: timestamp("updated_at").defaultNow().notNull(),
|
||||||
disabled: boolean("disabled").default(false).notNull(),
|
disabled: boolean("disabled").default(false).notNull(),
|
||||||
|
auth_token: text("auth_token"),
|
||||||
|
type: machinesType("type").notNull().default("classic"),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const insertMachineSchema = createInsertSchema(machinesTable, {
|
||||||
|
name: (schema) => schema.name.default("My Machine"),
|
||||||
|
endpoint: (schema) => schema.endpoint.default("http://127.0.0.1:8188"),
|
||||||
|
type: (schema) => schema.type.default("classic"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const deploymentsTable = dbSchema.table("deployments", {
|
export const deploymentsTable = dbSchema.table("deployments", {
|
||||||
|
8
web/src/server/addMachineSchema.ts
Normal file
8
web/src/server/addMachineSchema.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { insertMachineSchema } from "@/db/schema";
|
||||||
|
|
||||||
|
export const addMachineSchema = insertMachineSchema.pick({
|
||||||
|
name: true,
|
||||||
|
endpoint: true,
|
||||||
|
type: true,
|
||||||
|
auth_token: true,
|
||||||
|
});
|
@ -7,6 +7,7 @@ import { ComfyAPI_Run } from "@/types/ComfyAPI_Run";
|
|||||||
import { and, eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import { revalidatePath } from "next/cache";
|
import { revalidatePath } from "next/cache";
|
||||||
import "server-only";
|
import "server-only";
|
||||||
|
import { v4 } from "uuid";
|
||||||
|
|
||||||
export const createRun = withServerPromise(
|
export const createRun = withServerPromise(
|
||||||
async (
|
async (
|
||||||
@ -37,8 +38,6 @@ export const createRun = withServerPromise(
|
|||||||
throw new Error("Workflow version not found");
|
throw new Error("Workflow version not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const comfyui_endpoint = `${machine.endpoint}/comfyui-deploy/run`;
|
|
||||||
|
|
||||||
const workflow_api = workflow_version_data.workflow_api;
|
const workflow_api = workflow_version_data.workflow_api;
|
||||||
|
|
||||||
// Replace the inputs
|
// Replace the inputs
|
||||||
@ -52,33 +51,57 @@ export const createRun = withServerPromise(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const body = {
|
let prompt_id: string | undefined = undefined;
|
||||||
|
const shareData = {
|
||||||
workflow_api: workflow_api,
|
workflow_api: workflow_api,
|
||||||
status_endpoint: `${origin}/api/update-run`,
|
status_endpoint: `${origin}/api/update-run`,
|
||||||
file_upload_endpoint: `${origin}/api/file-upload`,
|
file_upload_endpoint: `${origin}/api/file-upload`,
|
||||||
};
|
};
|
||||||
// console.log(body);
|
|
||||||
const bodyJson = JSON.stringify(body);
|
|
||||||
// console.log(bodyJson);
|
|
||||||
|
|
||||||
// Sending to comfyui
|
switch (machine.type) {
|
||||||
const _result = await fetch(comfyui_endpoint, {
|
case "runpod-serverless":
|
||||||
|
prompt_id = v4();
|
||||||
|
const data = {
|
||||||
|
input: {
|
||||||
|
...shareData,
|
||||||
|
prompt_id: prompt_id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(data);
|
||||||
|
const __result = await fetch(`${machine.endpoint}/run`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: bodyJson,
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer ${machine.auth_token}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
cache: "no-store",
|
cache: "no-store",
|
||||||
});
|
});
|
||||||
|
console.log(__result);
|
||||||
if (!_result.ok) {
|
if (!__result.ok)
|
||||||
|
throw new Error(`Error creating run, ${__result.statusText}`);
|
||||||
|
console.log(data, __result);
|
||||||
|
break;
|
||||||
|
case "classic":
|
||||||
|
const body = shareData;
|
||||||
|
const comfyui_endpoint = `${machine.endpoint}/comfyui-deploy/run`;
|
||||||
|
const _result = await fetch(comfyui_endpoint, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
cache: "no-store",
|
||||||
|
});
|
||||||
|
if (!_result.ok)
|
||||||
throw new Error(`Error creating run, ${_result.statusText}`);
|
throw new Error(`Error creating run, ${_result.statusText}`);
|
||||||
}
|
|
||||||
|
|
||||||
const result = await ComfyAPI_Run.parseAsync(await _result.json());
|
const result = await ComfyAPI_Run.parseAsync(await _result.json());
|
||||||
|
prompt_id = result.prompt_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Add to our db
|
// Add to our db
|
||||||
const workflow_run = await db
|
const workflow_run = await db
|
||||||
.insert(workflowRunsTable)
|
.insert(workflowRunsTable)
|
||||||
.values({
|
.values({
|
||||||
id: result.prompt_id,
|
id: prompt_id,
|
||||||
workflow_id: workflow_version_data.workflow_id,
|
workflow_id: workflow_version_data.workflow_id,
|
||||||
workflow_version_id: workflow_version_data.id,
|
workflow_version_id: workflow_version_data.id,
|
||||||
workflow_inputs: inputs,
|
workflow_inputs: inputs,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
|
import type { addMachineSchema } from "./addMachineSchema";
|
||||||
import { withServerPromise } from "./withServerPromise";
|
import { withServerPromise } from "./withServerPromise";
|
||||||
import { db } from "@/db/db";
|
import { db } from "@/db/db";
|
||||||
import { machinesTable } from "@/db/schema";
|
import { machinesTable } from "@/db/schema";
|
||||||
@ -7,6 +8,7 @@ import { auth } from "@clerk/nextjs";
|
|||||||
import { and, eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import { revalidatePath } from "next/cache";
|
import { revalidatePath } from "next/cache";
|
||||||
import "server-only";
|
import "server-only";
|
||||||
|
import type { z } from "zod";
|
||||||
|
|
||||||
export async function getMachines() {
|
export async function getMachines() {
|
||||||
const { userId } = auth();
|
const { userId } = auth();
|
||||||
@ -20,17 +22,36 @@ export async function getMachines() {
|
|||||||
return machines;
|
return machines;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addMachine(name: string, endpoint: string) {
|
export const addMachine = withServerPromise(
|
||||||
|
async ({ name, endpoint, type }: z.infer<typeof addMachineSchema>) => {
|
||||||
const { userId } = auth();
|
const { userId } = auth();
|
||||||
if (!userId) throw new Error("No user id");
|
if (!userId) return { error: "No user id" };
|
||||||
console.log(name, endpoint);
|
console.log(name, endpoint);
|
||||||
await db.insert(machinesTable).values({
|
await db.insert(machinesTable).values({
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
name,
|
name,
|
||||||
endpoint,
|
endpoint,
|
||||||
|
type,
|
||||||
});
|
});
|
||||||
revalidatePath("/machines");
|
revalidatePath("/machines");
|
||||||
|
return { message: "Machine Added" };
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const updateMachine = withServerPromise(
|
||||||
|
async ({
|
||||||
|
id,
|
||||||
|
...data
|
||||||
|
}: z.infer<typeof addMachineSchema> & {
|
||||||
|
id: string;
|
||||||
|
}) => {
|
||||||
|
const { userId } = auth();
|
||||||
|
if (!userId) return { error: "No user id" };
|
||||||
|
await db.update(machinesTable).set(data).where(eq(machinesTable.id, id));
|
||||||
|
revalidatePath("/machines");
|
||||||
|
return { message: "Machine Updated" };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export const deleteMachine = withServerPromise(
|
export const deleteMachine = withServerPromise(
|
||||||
async (machine_id: string): Promise<{ message: string }> => {
|
async (machine_id: string): Promise<{ message: string }> => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user