feat(plugin): update deployment flow
This commit is contained in:
parent
d6707295cc
commit
157b126fbf
@ -102,6 +102,12 @@ const ext = {
|
||||
* @typedef {import('../../../web/types/litegraph.js').LGraphNode} LGraphNode
|
||||
*/
|
||||
|
||||
function showError(title, message) {
|
||||
infoDialog.show(
|
||||
`<h3 style="margin: 0px; color: red;">${title}</h3><br><span>${message}</span> `,
|
||||
);
|
||||
}
|
||||
|
||||
function addButton() {
|
||||
const menu = document.querySelector(".comfy-menu");
|
||||
|
||||
@ -113,9 +119,46 @@ function addButton() {
|
||||
/** @type {LGraph} */
|
||||
const graph = app.graph;
|
||||
|
||||
const title = deploy.querySelector("#button-title")
|
||||
const snapshot = await fetch("/snapshot/get_current").then((x) => x.json());
|
||||
console.log(snapshot);
|
||||
|
||||
if (!snapshot) {
|
||||
showError(
|
||||
"Error when deploying",
|
||||
"Unable to generate snapshot, please install ComfyUI Manager",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const title = deploy.querySelector("#button-title");
|
||||
|
||||
let deployMeta = graph.findNodesByType("ComfyDeploy");
|
||||
|
||||
if (deployMeta.length == 0) {
|
||||
const text = await inputDialog.input(
|
||||
"Create your deployment",
|
||||
"Workflow name",
|
||||
);
|
||||
if (!text) return
|
||||
console.log(text);
|
||||
app.graph.beforeChange();
|
||||
var node = LiteGraph.createNode("ComfyDeploy");
|
||||
node.configure({
|
||||
widgets_values: [
|
||||
text
|
||||
]
|
||||
});
|
||||
node.pos = [0, 0];
|
||||
app.graph.add(node);
|
||||
app.graph.afterChange();
|
||||
deployMeta=[node]
|
||||
// return;
|
||||
// showError(
|
||||
// "Error when deploying",
|
||||
// "Unable to to find ComfyDeploy node, please add it first.",
|
||||
// );
|
||||
}
|
||||
|
||||
const deployMeta = graph.findNodesByType("ComfyDeploy");
|
||||
const deployMetaNode = deployMeta[0];
|
||||
|
||||
console.log(deployMetaNode);
|
||||
@ -132,10 +175,7 @@ function addButton() {
|
||||
// const endpoint = localStorage.getItem("endpoint") ?? "";
|
||||
// const apiKey = localStorage.getItem("apiKey");
|
||||
|
||||
const {
|
||||
endpoint,
|
||||
apiKey,
|
||||
} = getData();
|
||||
const { endpoint, apiKey } = getData();
|
||||
|
||||
if (!endpoint || !apiKey || apiKey === "" || endpoint === "") {
|
||||
configDialog.show();
|
||||
@ -152,7 +192,7 @@ function addButton() {
|
||||
endpoint = endpoint.slice(0, -1);
|
||||
}
|
||||
|
||||
const apiRoute = endpoint + "/api/upload"
|
||||
const apiRoute = endpoint + "/api/upload";
|
||||
// const userId = apiKey
|
||||
try {
|
||||
let data = await fetch(apiRoute, {
|
||||
@ -162,10 +202,11 @@ function addButton() {
|
||||
workflow_id,
|
||||
workflow: prompt.workflow,
|
||||
workflow_api: prompt.output,
|
||||
snapshot: snapshot,
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": "Bearer " + apiKey,
|
||||
Authorization: "Bearer " + apiKey,
|
||||
},
|
||||
});
|
||||
|
||||
@ -185,7 +226,7 @@ function addButton() {
|
||||
graph.change();
|
||||
|
||||
infoDialog.show(
|
||||
`<span style="color:green;">Deployed successfully!</span> <br/> <br/> Workflow ID: ${data.workflow_id} <br/> Workflow Name: ${workflow_name} <br/> Workflow Version: ${data.version}`,
|
||||
`<span style="color:green;">Deployed successfully!</span> <a style="color:white;" target="_blank" href=${endpoint}/workflows/${data.workflow_id}>View here -></a> <br/> <br/> Workflow ID: ${data.workflow_id} <br/> Workflow Name: ${workflow_name} <br/> Workflow Version: ${data.version} <br/>`,
|
||||
);
|
||||
|
||||
setTimeout(() => {
|
||||
@ -210,19 +251,18 @@ function addButton() {
|
||||
config.style.position = "absolute";
|
||||
config.style.right = "10px";
|
||||
config.style.top = "0px";
|
||||
|
||||
|
||||
// set aspect ratio to square
|
||||
config.style.width = "20px";
|
||||
config.src = "https://api.iconify.design/material-symbols-light:settings.svg?color=%23888888";
|
||||
config.src =
|
||||
"https://api.iconify.design/material-symbols-light:settings.svg?color=%23888888";
|
||||
config.onclick = (e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
configDialog.show();
|
||||
};
|
||||
|
||||
deploy.append(
|
||||
config
|
||||
)
|
||||
deploy.append(config);
|
||||
|
||||
deploy.style.order = "99";
|
||||
|
||||
@ -231,44 +271,113 @@ function addButton() {
|
||||
|
||||
app.registerExtension(ext);
|
||||
|
||||
|
||||
import { ComfyDialog, $el } from '../../scripts/ui.js';
|
||||
import { ComfyDialog, $el } from "../../scripts/ui.js";
|
||||
|
||||
export class InfoDialog extends ComfyDialog {
|
||||
constructor() {
|
||||
super();
|
||||
this.element.classList.add("comfy-normal-modal");
|
||||
}
|
||||
createButtons() {
|
||||
return [
|
||||
$el("button", {
|
||||
type: "button",
|
||||
textContent: "Close",
|
||||
onclick: () => this.close(),
|
||||
}),
|
||||
];
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
this.element.classList.add("comfy-normal-modal");
|
||||
this.element.style.paddingBottom = "20px";
|
||||
}
|
||||
createButtons() {
|
||||
return [
|
||||
$el("button", {
|
||||
type: "button",
|
||||
textContent: "Close",
|
||||
onclick: () => this.close(),
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
close() {
|
||||
this.element.style.display = "none";
|
||||
}
|
||||
close() {
|
||||
this.element.style.display = "none";
|
||||
}
|
||||
|
||||
show(html) {
|
||||
show(html) {
|
||||
this.textElement.style["white-space"] = "normal";
|
||||
this.textElement.style.color = "white";
|
||||
if (typeof html === "string") {
|
||||
this.textElement.innerHTML = html;
|
||||
} else {
|
||||
this.textElement.replaceChildren(html);
|
||||
}
|
||||
this.element.style.display = "flex";
|
||||
this.element.style.zIndex = 1001;
|
||||
}
|
||||
this.textElement.style.marginTop = "0px";
|
||||
if (typeof html === "string") {
|
||||
this.textElement.innerHTML = html;
|
||||
} else {
|
||||
this.textElement.replaceChildren(html);
|
||||
}
|
||||
this.element.style.display = "flex";
|
||||
this.element.style.zIndex = 1001;
|
||||
}
|
||||
}
|
||||
|
||||
export const infoDialog = new InfoDialog()
|
||||
export class InputDialog extends InfoDialog {
|
||||
callback = undefined;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
createButtons() {
|
||||
return [
|
||||
$el(
|
||||
"div",
|
||||
{
|
||||
type: "div",
|
||||
style: {
|
||||
display: "flex",
|
||||
gap: "6px",
|
||||
justifyContent: "flex-end",
|
||||
width: "100%",
|
||||
},
|
||||
},
|
||||
[
|
||||
$el("button", {
|
||||
type: "button",
|
||||
textContent: "Save",
|
||||
onclick: () => {
|
||||
const input = this.textElement.querySelector("#input").value;
|
||||
if (input.trim() === "") {
|
||||
showError("Input validation", "Input cannot be empty");
|
||||
} else {
|
||||
this.callback?.(input);
|
||||
this.close();
|
||||
this.textElement.querySelector("#input").value = "";
|
||||
}
|
||||
},
|
||||
}),
|
||||
$el("button", {
|
||||
type: "button",
|
||||
textContent: "Close",
|
||||
onclick: () => {
|
||||
this.callback?.(undefined);
|
||||
this.close()
|
||||
},
|
||||
}),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
input(title, message) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.callback = resolve;
|
||||
this.show(`
|
||||
<div style="width: 400px; display: flex; gap: 18px; flex-direction: column; overflow: unset">
|
||||
<h3 style="margin: 0px;">${title}</h3>
|
||||
<label>
|
||||
${message}
|
||||
<input id="input" style="margin-top: 8px; width: 100%; height:40px; padding: 0px 6px; box-sizing: border-box; outline-offset: -1px;">
|
||||
</label>
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const inputDialog = new InputDialog();
|
||||
|
||||
export const infoDialog = new InfoDialog();
|
||||
|
||||
function getData(environment) {
|
||||
const deployOption = environment || localStorage.getItem("comfy_deploy_env") || "cloud";
|
||||
const deployOption =
|
||||
environment || localStorage.getItem("comfy_deploy_env") || "cloud";
|
||||
const data = localStorage.getItem("comfy_deploy_env_data_" + deployOption);
|
||||
if (!data) {
|
||||
if (deployOption == "cloud")
|
||||
@ -276,7 +385,7 @@ function getData(environment) {
|
||||
endpoint: "https://www.comfydeploy.com",
|
||||
apiKey: "",
|
||||
};
|
||||
else
|
||||
else
|
||||
return {
|
||||
endpoint: "http://localhost:3000",
|
||||
apiKey: "",
|
||||
@ -289,12 +398,12 @@ function getData(environment) {
|
||||
}
|
||||
|
||||
export class ConfigDialog extends ComfyDialog {
|
||||
|
||||
container = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.element.classList.add("comfy-normal-modal");
|
||||
this.element.style.paddingBottom = "20px";
|
||||
|
||||
this.container = document.createElement("div");
|
||||
this.element.querySelector(".comfy-modal-content").prepend(this.container);
|
||||
@ -302,16 +411,18 @@ export class ConfigDialog extends ComfyDialog {
|
||||
|
||||
createButtons() {
|
||||
return [
|
||||
$el("div", {
|
||||
type: "div",
|
||||
style: {
|
||||
display: "flex",
|
||||
gap: "6px",
|
||||
justifyContent: "flex-end",
|
||||
width: "100%",
|
||||
$el(
|
||||
"div",
|
||||
{
|
||||
type: "div",
|
||||
style: {
|
||||
display: "flex",
|
||||
gap: "6px",
|
||||
justifyContent: "flex-end",
|
||||
width: "100%",
|
||||
},
|
||||
onclick: () => this.save(),
|
||||
},
|
||||
onclick: () => this.save(),
|
||||
},
|
||||
[
|
||||
$el("button", {
|
||||
type: "button",
|
||||
@ -322,8 +433,8 @@ export class ConfigDialog extends ComfyDialog {
|
||||
type: "button",
|
||||
textContent: "Close",
|
||||
onclick: () => this.close(),
|
||||
})
|
||||
]
|
||||
}),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
@ -341,8 +452,11 @@ export class ConfigDialog extends ComfyDialog {
|
||||
const data = {
|
||||
endpoint,
|
||||
apiKey,
|
||||
}
|
||||
localStorage.setItem("comfy_deploy_env_data_" + deployOption, JSON.stringify(data));
|
||||
};
|
||||
localStorage.setItem(
|
||||
"comfy_deploy_env_data_" + deployOption,
|
||||
JSON.stringify(data),
|
||||
);
|
||||
this.close();
|
||||
}
|
||||
|
||||
@ -350,39 +464,47 @@ export class ConfigDialog extends ComfyDialog {
|
||||
this.container.style.color = "white";
|
||||
|
||||
const data = getData();
|
||||
|
||||
|
||||
this.container.innerHTML = `
|
||||
<div style="width: 400px; display: flex; gap: 18px; flex-direction: column;">
|
||||
<h3 style="margin: 0px;">Comfy Deploy Config</h3>
|
||||
<label style="color: white; width: 100%;">
|
||||
<select id="deployOption" style="margin-top: 8px; width: 100%; height:30px;" >
|
||||
<option value="cloud" ${data.environment === 'cloud' ? 'selected' : ''}>Cloud</option>
|
||||
<option value="local" ${data.environment === 'local' ? 'selected' : ''}>Local</option>
|
||||
<select id="deployOption" style="margin: 8px 0px; width: 100%; height:30px; box-sizing: border-box;" >
|
||||
<option value="cloud" ${
|
||||
data.environment === "cloud" ? "selected" : ""
|
||||
}>Cloud</option>
|
||||
<option value="local" ${
|
||||
data.environment === "local" ? "selected" : ""
|
||||
}>Local</option>
|
||||
</select>
|
||||
</label>
|
||||
<label style="color: white; width: 100%;">
|
||||
Endpoint:
|
||||
<input id="endpoint" style="margin-top: 8px; width: 100%; height:30px;" type="text" value="${data.endpoint}">
|
||||
<input id="endpoint" style="margin-top: 8px; width: 100%; height:40px; box-sizing: border-box; padding: 0px 6px;" type="text" value="${
|
||||
data.endpoint
|
||||
}">
|
||||
</label>
|
||||
<label style="color: white;">
|
||||
API Key:
|
||||
<input id="apiKey" style="margin-top: 8px; width: 100%; height:30px;" type="password" value="${data.apiKey}">
|
||||
<input id="apiKey" style="margin-top: 8px; width: 100%; height:40px; box-sizing: border-box; padding: 0px 6px;" type="password" value="${
|
||||
data.apiKey
|
||||
}">
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const apiKeyInput = this.container.querySelector("#apiKey");
|
||||
apiKeyInput.addEventListener("paste", function(e) {
|
||||
apiKeyInput.addEventListener("paste", function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
const deployOption = this.container.querySelector("#deployOption");
|
||||
const container = this.container
|
||||
deployOption.addEventListener("change", function() {
|
||||
const container = this.container;
|
||||
deployOption.addEventListener("change", function () {
|
||||
const selectedOption = this.value;
|
||||
const data = getData(selectedOption);
|
||||
localStorage.setItem("comfy_deploy_env", selectedOption);
|
||||
|
||||
|
||||
container.querySelector("#endpoint").value = data.endpoint;
|
||||
container.querySelector("#apiKey").value = data.apiKey;
|
||||
});
|
||||
@ -392,4 +514,4 @@ export class ConfigDialog extends ComfyDialog {
|
||||
}
|
||||
}
|
||||
|
||||
export const configDialog = new ConfigDialog();
|
||||
export const configDialog = new ConfigDialog();
|
||||
|
1
web/drizzle/0022_petite_bishop.sql
Normal file
1
web/drizzle/0022_petite_bishop.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE "comfyui_deploy"."workflow_versions" ADD COLUMN "snapshot" jsonb;
|
710
web/drizzle/meta/0022_snapshot.json
Normal file
710
web/drizzle/meta/0022_snapshot.json
Normal file
@ -0,0 +1,710 @@
|
||||
{
|
||||
"id": "9153404d-9279-4f43-a61f-7f5efefc12b7",
|
||||
"prevId": "5893c5f8-4466-4b51-b9b7-24756c37dced",
|
||||
"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": "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": {}
|
||||
},
|
||||
"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
|
||||
},
|
||||
"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()"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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": {}
|
||||
}
|
||||
}
|
@ -155,6 +155,13 @@
|
||||
"when": 1704380757696,
|
||||
"tag": "0021_aromatic_sabra",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 22,
|
||||
"version": "5",
|
||||
"when": 1704453649633,
|
||||
"tag": "0022_petite_bishop",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { parseJWT } from "../../../../server/parseJWT";
|
||||
import { db } from "@/db/db";
|
||||
import {
|
||||
snapshotType,
|
||||
workflowAPIType,
|
||||
workflowTable,
|
||||
workflowType,
|
||||
@ -18,11 +19,11 @@ const corsHeaders = {
|
||||
};
|
||||
|
||||
const UploadRequest = z.object({
|
||||
// user_id: z.string(),
|
||||
workflow_id: z.string().optional(),
|
||||
workflow_name: z.string().optional(),
|
||||
workflow_name: z.string().min(1).optional(),
|
||||
workflow: workflowType,
|
||||
workflow_api: workflowAPIType,
|
||||
snapshot: snapshotType,
|
||||
});
|
||||
|
||||
export async function OPTIONS(request: Request) {
|
||||
@ -64,6 +65,7 @@ export async function POST(request: Request) {
|
||||
workflow_api,
|
||||
workflow_id: _workflow_id,
|
||||
workflow_name,
|
||||
snapshot,
|
||||
} = data;
|
||||
|
||||
let workflow_id = _workflow_id;
|
||||
@ -93,6 +95,7 @@ export async function POST(request: Request) {
|
||||
workflow,
|
||||
workflow_api,
|
||||
version: 1,
|
||||
snapshot: snapshot,
|
||||
})
|
||||
.returning();
|
||||
version = data[0].version;
|
||||
@ -105,6 +108,7 @@ export async function POST(request: Request) {
|
||||
workflow: workflow,
|
||||
workflow_api,
|
||||
// version: sql`${workflowVersionTable.version} + 1`,
|
||||
snapshot: snapshot,
|
||||
version: sql`(
|
||||
SELECT COALESCE(MAX(version), 0) + 1
|
||||
FROM ${workflowVersionTable}
|
||||
|
@ -69,6 +69,7 @@ export const workflowVersionTable = dbSchema.table("workflow_versions", {
|
||||
workflow: jsonb("workflow").$type<z.infer<typeof workflowType>>(),
|
||||
workflow_api: jsonb("workflow_api").$type<z.infer<typeof workflowAPIType>>(),
|
||||
version: integer("version").notNull(),
|
||||
snapshot: jsonb("snapshot").$type<z.infer<typeof snapshotType>>(),
|
||||
|
||||
created_at: timestamp("created_at").defaultNow().notNull(),
|
||||
updated_at: timestamp("updated_at").defaultNow().notNull(),
|
||||
@ -201,10 +202,21 @@ export const machinesTable = dbSchema.table("machines", {
|
||||
auth_token: text("auth_token"),
|
||||
type: machinesType("type").notNull().default("classic"),
|
||||
status: machinesStatus("status").notNull().default("ready"),
|
||||
snapshot: jsonb("snapshot").$type<any>(),
|
||||
snapshot: jsonb("snapshot").$type<z.infer<typeof snapshotType>>(),
|
||||
build_log: text("build_log"),
|
||||
});
|
||||
|
||||
export const snapshotType = z.object({
|
||||
comfyui: z.string(),
|
||||
git_custom_nodes: z.record(
|
||||
z.object({
|
||||
hash: z.string(),
|
||||
disabled: z.boolean(),
|
||||
})
|
||||
),
|
||||
file_custom_nodes: z.array(z.any()),
|
||||
});
|
||||
|
||||
export const insertMachineSchema = createInsertSchema(machinesTable, {
|
||||
name: (schema) => schema.name.default("My Machine"),
|
||||
endpoint: (schema) => schema.endpoint.default("http://127.0.0.1:8188"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user