next-workflow-builder 0.7.1 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/chunk-3YVRTDK2.js +1 -0
- package/dist/chunk-CI7FTYZR.js +42 -0
- package/dist/chunk-VUDOAZ3W.js +14 -0
- package/dist/chunk-WT4BSMUD.js +1 -0
- package/dist/client/index.d.ts +12 -2
- package/dist/client/index.js +36 -17
- package/dist/handler-67JKCHM5.js +1 -0
- package/dist/run-workflow-VFZV5YLI.js +1 -0
- package/dist/run-workflows-in-sequence-3APONBOX.js +1 -0
- package/dist/server/api/index.js +2 -2
- package/dist/styles.css +29 -0
- package/package.json +1 -1
- package/dist/chunk-DMHGXYVW.js +0 -14
- package/dist/chunk-QMJQ5NK5.js +0 -42
- package/dist/handler-YTQRRHEK.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# next-workflow-builder
|
|
2
2
|
|
|
3
|
+
## 0.7.4
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- Add `canvas` prop to `Layout` for configuring the workflow canvas
|
|
8
|
+
- `canvas.snapToGrid` — enable/disable snap-to-grid alignment (default: `true`)
|
|
9
|
+
- `canvas.edgeStyle` — set edge rendering style: `"smoothstep"` or `"bezier"` (default: `"smoothstep"`)
|
|
10
|
+
- Export `LayoutProps`, `CanvasOptions`, and `EdgeStyle` types from `next-workflow-builder/client`
|
|
11
|
+
|
|
12
|
+
### Improvements
|
|
13
|
+
|
|
14
|
+
- Default canvas to snap-to-grid for more precise node placement
|
|
15
|
+
- Default edge style to smooth step for cleaner, more angular connections
|
|
16
|
+
|
|
17
|
+
## 0.7.3
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
- Add built-in **Run Workflow** action — execute another workflow internally and wait for it to complete, bypassing HTTP entirely. Returns the sub-workflow's output for use in downstream nodes via `{{RunWorkflow.output}}`
|
|
22
|
+
- Add built-in **Run Workflows in Sequence** action — execute an ordered list of workflows one after another. Supports a "continue on failure" option and returns per-workflow results with pass/fail summary
|
|
23
|
+
- Add compound node rendering for Run Workflows in Sequence — the canvas node visually expands to show each child workflow as a numbered row with per-child status indicators (pending/success/error) after execution completes
|
|
24
|
+
- Each sub-workflow execution creates its own execution record, visible individually in the Runs tab
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
- Fix **Loop** node only processing the first item — the executor now re-invokes the Loop step with an incremented `currentBatchIndex` after each iteration and re-executes all downstream nodes per batch until `hasMore` is false. Cancellation is checked between iterations
|
|
29
|
+
|
|
30
|
+
## 0.7.2
|
|
31
|
+
|
|
32
|
+
### Bug Fixes
|
|
33
|
+
|
|
34
|
+
- Fix cron-triggered workflows producing "No steps recorded" on Vercel — `executeWorkflowBackground` is now awaited in the cron handler so Vercel keeps the serverless function alive until completion (consumers must set `maxDuration` on their catch-all API route)
|
|
35
|
+
|
|
3
36
|
## 0.7.1
|
|
4
37
|
|
|
5
38
|
### Features
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var l=[{value:"string",label:"String"},{value:"number",label:"Number"},{value:"boolean",label:"Boolean"},{value:"datetime",label:"Date & Time"}],u={string:[{value:"exists",label:"exists",unary:!0},{value:"doesNotExist",label:"does not exist",unary:!0},{value:"isEmpty",label:"is empty",unary:!0},{value:"isNotEmpty",label:"is not empty",unary:!0},{value:"equals",label:"equals",unary:!1},{value:"notEquals",label:"does not equal",unary:!1},{value:"contains",label:"contains",unary:!1},{value:"doesNotContain",label:"does not contain",unary:!1},{value:"startsWith",label:"starts with",unary:!1},{value:"doesNotStartWith",label:"does not start with",unary:!1},{value:"endsWith",label:"ends with",unary:!1},{value:"doesNotEndWith",label:"does not end with",unary:!1},{value:"matchesRegex",label:"matches regex",unary:!1},{value:"doesNotMatchRegex",label:"does not match regex",unary:!1}],number:[{value:"equals",label:"equals",unary:!1},{value:"notEquals",label:"does not equal",unary:!1},{value:"greaterThan",label:"greater than",unary:!1},{value:"lessThan",label:"less than",unary:!1},{value:"greaterThanOrEqual",label:"greater than or equal",unary:!1},{value:"lessThanOrEqual",label:"less than or equal",unary:!1}],boolean:[{value:"isTrue",label:"is true",unary:!0},{value:"isFalse",label:"is false",unary:!0},{value:"exists",label:"exists",unary:!0},{value:"doesNotExist",label:"does not exist",unary:!0}],datetime:[{value:"isBefore",label:"is before",unary:!1},{value:"isAfter",label:"is after",unary:!1},{value:"equals",label:"equals",unary:!1}]};function o(n,s,t,r){switch(s){case"exists":return t!=null;case"doesNotExist":return t==null;case"isEmpty":return t==null||String(t)==="";case"isNotEmpty":return t!=null&&String(t)!=="";case"isTrue":return!!t;case"isFalse":return!t}switch(n){case"string":{let e=String(t??""),a=String(r??"");switch(s){case"equals":return e===a;case"notEquals":return e!==a;case"contains":return e.includes(a);case"doesNotContain":return!e.includes(a);case"startsWith":return e.startsWith(a);case"doesNotStartWith":return!e.startsWith(a);case"endsWith":return e.endsWith(a);case"doesNotEndWith":return!e.endsWith(a);case"matchesRegex":try{return new RegExp(a).test(e)}catch{return!1}case"doesNotMatchRegex":try{return!new RegExp(a).test(e)}catch{return!1}}break}case"number":{let e=Number(t),a=Number(r);if(Number.isNaN(e)||Number.isNaN(a))return!1;switch(s){case"equals":return e===a;case"notEquals":return e!==a;case"greaterThan":return e>a;case"lessThan":return e<a;case"greaterThanOrEqual":return e>=a;case"lessThanOrEqual":return e<=a}break}case"boolean":break;case"datetime":{let e=new Date(t).getTime(),a=new Date(r).getTime();if(Number.isNaN(e)||Number.isNaN(a))return!1;switch(s){case"isBefore":return e<a;case"isAfter":return e>a;case"equals":return e===a}break}}return console.warn(`[Condition] Unknown operator "${s}" for data type "${n}"`),!1}export{l as a,u as b,o as c};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import{a as k}from"./chunk-WT4BSMUD.js";import{j as l}from"./chunk-VUDOAZ3W.js";import{a as m,b as w}from"./chunk-IEOZJAW2.js";import{l as d,m as p}from"./chunk-BNX2SV7E.js";import{r as f,t as u}from"./chunk-QRG4O4PE.js";import{k as c,o as g}from"./chunk-5J6TNMJG.js";async function b(e){let r=m();if(r.getUser)return r.getUser(e);let t=await w.api.getSession({headers:e.headers});return t?.user?{id:t.user.id,email:t.user.email??void 0,name:t.user.name??void 0}:null}import{eq as x}from"drizzle-orm";import{readdir as h,readFile as R}from"fs/promises";import{join as y}from"path";var T={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization"};function _(e){let t=new URL(e.url).pathname,n="/api/workflow-builder/",s=t.indexOf(n);if(s===-1){let i=t.indexOf("/api/");return i===-1?[]:t.slice(i+5).split("/").filter(Boolean)}return t.slice(s+n.length).split("/").filter(Boolean)}function q(e,r){return new Request(r,{method:e.method,headers:e.headers,body:e.body,duplex:"half"})}async function D(e,r,t,n,s){try{await k({nodes:t,edges:n,triggerInput:s,executionId:e,workflowId:r})}catch(o){console.error("[Workflow Execute] Error during execution:",o),await g.update(c).set({status:"error",error:o instanceof Error?o.message:"Unknown error",completedAt:new Date}).where(x(c.id,e))}}function S(e){let r={updatedAt:new Date};return e.name!==void 0&&(r.name=e.name),e.description!==void 0&&(r.description=e.description),e.nodes!==void 0&&(r.nodes=e.nodes),e.edges!==void 0&&(r.edges=e.edges),e.visibility!==void 0&&(r.visibility=e.visibility),r}function B(e){return e.map(r=>{let t={...r};if(t.data&&typeof t.data=="object"&&t.data!==null){let n={...t.data};if(n.config&&typeof n.config=="object"&&n.config!==null){let{integrationId:s,...o}=n.config;n.config=o}t.data=n}return t})}async function A(e,r=e){let t={},n=await h(e,{withFileTypes:!0});for(let s of n){let o=y(e,s.name);if(s.isDirectory()){let i=await A(o,r);Object.assign(t,i)}else if(s.isFile()){let i=await R(o,"utf-8"),a=o.substring(r.length+1);t[a]=i}}return t}function z(e){let r={},n=`${e.name.replace(d,"").split(p).map((i,a)=>a===0?i.toLowerCase():i.charAt(0).toUpperCase()+i.slice(1).toLowerCase()).join("")||"execute"}Workflow`,s=l(e.name,e.nodes,e.edges,{functionName:n}),o=N(e.name);return r[`workflows/${o}.ts`]=s,r[`app/api/workflows/${o}/route.ts`]=`import { start } from 'workflow/api';
|
|
2
|
+
import { ${n} } from '@/workflows/${o}';
|
|
3
|
+
import { NextResponse } from 'next/server';
|
|
4
|
+
|
|
5
|
+
export async function POST(request: Request) {
|
|
6
|
+
try {
|
|
7
|
+
const body = await request.json();
|
|
8
|
+
|
|
9
|
+
// Start the workflow execution
|
|
10
|
+
await start(${n}, [body]);
|
|
11
|
+
|
|
12
|
+
return NextResponse.json({
|
|
13
|
+
success: true,
|
|
14
|
+
message: 'Workflow started successfully',
|
|
15
|
+
});
|
|
16
|
+
} catch (error) {
|
|
17
|
+
return NextResponse.json(
|
|
18
|
+
{
|
|
19
|
+
success: false,
|
|
20
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
21
|
+
},
|
|
22
|
+
{ status: 500 }
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
`,r["app/page.tsx"]=`export default function Home() {
|
|
27
|
+
return (
|
|
28
|
+
<main className="p-8">
|
|
29
|
+
<h1 className="text-2xl font-bold mb-4">Workflow: ${e.name}</h1>
|
|
30
|
+
<p className="mb-4 text-gray-600">API endpoint:</p>
|
|
31
|
+
<ul className="list-disc pl-6 space-y-2">
|
|
32
|
+
<li>
|
|
33
|
+
<a href="/api/workflows/${o}" className="text-blue-600 hover:underline">
|
|
34
|
+
/api/workflows/${o}
|
|
35
|
+
</a>
|
|
36
|
+
</li>
|
|
37
|
+
</ul>
|
|
38
|
+
</main>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
`,r}function H(e){let r=e.filter(t=>t.data.type==="action").map(t=>t.data.config?.actionType).filter(Boolean);return f(r)}function V(){let e=["# Add your environment variables here"];e.push(""),e.push("# For database integrations"),e.push("DATABASE_URL=your_database_url");let r=u(),t={};for(let n of r){let s=n.name.split("_")[0];t[s]||(t[s]=[]),t[s].push(n)}for(let[n,s]of Object.entries(t)){e.push(`# For ${n.charAt(0)+n.slice(1).toLowerCase()} integration`);for(let o of s)e.push(`${o.name}=your_${o.name.toLowerCase()}`);e.push("")}return e.join(`
|
|
42
|
+
`)}function N(e){return e.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}export{b as a,T as b,_ as c,q as d,D as e,S as f,B as g,A as h,z as i,H as j,V as k,N as l};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import{m as E,w as L}from"./chunk-QRG4O4PE.js";var F=/\{\{([^}]+)\}\}/g,q=/\s+/,xt=/[^a-zA-Z0-9]/g,It=/^([^[]+)\[(\d+)\]$/,Wt=/^[a-zA-Z_$][a-zA-Z0-9_$]*$/,J=/^[0-9]/;function Et(a){let f=new Set;if(!a||typeof a!="string")return f;let p;for(;(p=F.exec(a))!==null;){let l=p[1].trim();if(l.startsWith("@")){let w=l.substring(1),$=w.indexOf(":");if($!==-1){let y=w.substring(0,$);f.add(y)}}else if(l.startsWith("$")){let $=l.substring(1).split(".");$.length>0&&f.add($[0])}}return f}function Rt(a){let f=new Set;if(typeof a=="string"){let p=Et(a);for(let l of p)f.add(l)}return f}function Q(a){let f=new Set;for(let p of a){if(p.data.type!=="action")continue;let l=p.data.config||{};for(let w of Object.values(l)){let $=Rt(w);for(let y of $)f.add(y)}}return f}function Lt(a){let f=new Map;for(let p of a){let l=f.get(p.source)||[];l.push(p.target),f.set(p.source,l)}return f}function jt(a,f){let p=new Set(f.map(l=>l.target));return a.filter(l=>l.data.type==="trigger"&&!p.has(l.id))}function R(a){return a.split(".").map(f=>{let p=It.exec(f);return p?`.${p[1]}[${p[2]}]`:`.${f}`}).join("")}function v(a,f){return`${(a||f||"result").split(q).map((w,$)=>{let y=w.replace(xt,"");return y?$===0?y.toLowerCase():y.charAt(0).toUpperCase()+y.slice(1).toLowerCase():""}).filter(w=>w.length>0).join("")}Result`}function j(a){return a.replace(/\u00a0/g," ").replace(/[\u2000-\u200B\u2028\u2029]/g," ")}function Vt(a){return a?a.replace(/\\/g,"\\\\").replace(/`/g,"\\`"):""}function zt(a){return a.replace(/[^a-zA-Z0-9]/g,"_").replace(J,"_$&").replace(/_+/g,"_")}function Bt(a){let f=a.split(q).filter(l=>l.length>0).map((l,w)=>{let $=l.replace(/[^a-zA-Z0-9]/g,"");return $?w===0?$.toLowerCase():$.charAt(0).toUpperCase()+$.slice(1).toLowerCase():""}).filter(l=>l.length>0).join("");return!f||f.length===0?"unnamedStep":`${f.replace(J,"_$&")}Step`}function Gt(a){return a.replace(/[^a-zA-Z0-9]/g,"_")}function O(a){return a===null?"null":a===void 0?"undefined":typeof a=="string"?JSON.stringify(a):typeof a=="number"||typeof a=="boolean"?String(a):Array.isArray(a)?`[${a.map(p=>O(p)).join(", ")}]`:typeof a=="object"?`{${Object.entries(a).map(([p,l])=>`${Wt.test(p)?p:JSON.stringify(p)}: ${O(l)}`).join(", ")}}`:String(a)}var Ot={"Database Query":{functionName:"databaseQueryStep",importPath:"./steps/database-query-step"},"HTTP Request":{functionName:"httpRequestStep",importPath:"./steps/http-request-step"},Condition:{functionName:"conditionStep",importPath:"./steps/condition-step"}};function S(a){let f=Ot[a];if(f)return f;let p=E(a);return p?{functionName:p.stepFunction,importPath:`./steps/${p.stepImportPath}-step`}:{functionName:"unknownStep",importPath:"./steps/unknown-step"}}var H=/^(\s*)(const\s+\w+\s*=\s*)(.*)$/;function Ft(a,f,p={}){let{functionName:l="executeWorkflow"}=p,w=Q(a),$=new Set,y=new Map(a.map(s=>[s.id,s])),k=new Map;for(let s of f){let t=k.get(s.source)||[];t.push(s.target),k.set(s.source,t)}let Z=new Set(f.map(s=>s.target)),M=a.filter(s=>s.data.type==="trigger"&&!Z.has(s.id)),Y=M.some(s=>w.has(s.id)),b=[],P=new Set,X=Y?`export async function ${l}<TInput>(input: TInput) {`:`export async function ${l}() {`;b.push(X),b.push(' "use workflow";'),b.push("");let x=new Map,V=new Set;for(let s of a){let t;if(s.data.type==="action"){let r=s.data.config?.actionType,e=s.data.label||"",n=v(e,r);t=n;let o=1;for(;V.has(t);)t=`${n}${o}`,o+=1;V.add(t)}else t="input";x.set(s.id,t)}function K(s,t){let r=s.substring(1),e=r.indexOf(":");if(e===-1)return t;let n=r.substring(0,e),o=r.substring(e+1),i=o.indexOf("."),c=i!==-1?o.substring(i+1):"",g=x.get(n);if(!g)return t;if(!c)return`\${${g}}`;let u=R(c);return`\${${g}${u}}`}function tt(s,t){let e=s.substring(1).split("."),n=e[0],o=e.slice(1).join("."),i=x.get(n);if(!i)return t;if(!o)return`\${${i}}`;let c=R(o);return`\${${i}${c}}`}function et(s,t){let r=s.substring(1),e=r.indexOf(":");if(e===-1)return t;let n=r.substring(0,e),o=r.substring(e+1),i=o.indexOf("."),c=i!==-1?o.substring(i+1):"",g=x.get(n);if(!g)return t;if(!c)return g;let u=R(c);return`${g}${u}`}function nt(s,t){let e=s.substring(1).split("."),n=e[0],o=e.slice(1).join("."),i=x.get(n);if(!i)return t;if(!o)return i;let c=R(o);return`${i}${c}`}function C(s){return!s||typeof s!="string"?s:s.replace(F,(t,r)=>{let e=r.trim();return e.startsWith("@")?K(e,t):e.startsWith("$")?tt(e,t):t})}function z(s){if(!s||typeof s!="string")return s;let r=j(s).replace(F,(e,n)=>{let o=n.trim();return o.startsWith("@")?et(o,e):o.startsWith("$")?nt(o,e):e});return j(r)}function st(s,t,r){let e=S("Send Email");$.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.emailTo||"user@example.com",i=n.emailSubject||"Notification",c=n.emailBody||"No content",g=C(o),u=C(i),d=C(c),m=D=>D.includes("${"),h=D=>D.replace(/\$\{/g,"$${"),N=m(g)?`\`${h(g).replace(/`/g,"\\`")}\``:`'${o.replace(/'/g,"\\'")}'`,T=m(u)?`\`${h(u).replace(/`/g,"\\`")}\``:`'${i.replace(/'/g,"\\'")}'`,W=m(d)?`\`${h(d).replace(/`/g,"\\`")}\``:`'${c.replace(/'/g,"\\'")}'`;return[`${t}const ${r} = await ${e.functionName}({`,`${t} emailTo: ${N},`,`${t} emailSubject: ${T},`,`${t} emailBody: ${W},`,`${t}});`]}function rt(s,t,r){let e=S("Create Ticket");$.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.ticketTitle||"New Ticket",i=n.ticketDescription||"",c=C(o),g=C(i),u=N=>N.includes("${"),d=N=>N.replace(/\$\{/g,"$${"),m=u(c)?`\`${d(c).replace(/`/g,"\\`")}\``:`'${o.replace(/'/g,"\\'")}'`,h=u(g)?`\`${d(g).replace(/`/g,"\\`")}\``:`'${i.replace(/'/g,"\\'")}'`;return[`${t}const ${r} = await ${e.functionName}({`,`${t} ticketTitle: ${m},`,`${t} ticketDescription: ${h},`,`${t}});`]}function ot(s,t,r){let e=S("Database Query");$.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.dbQuery||"",i=n.dataSource||"",c=n.dbTable||n.tableName||"your_table",g=[`${t}const ${r} = await ${e.functionName}({`];if(i?g.push(`${t} dataSource: { name: "${i}" },`):g.push(`${t} dataSource: {},`),o){let u=C(o),h=u.includes("${")?`\`${(N=>N.replace(/\$\{/g,"$${"))(u).replace(/`/g,"\\`")}\``:`\`${o.replace(/`/g,"\\`")}\``;g.push(`${t} query: ${h},`)}else g.push(`${t} query: "${c}",`);return g.push(`${t}});`),g}function it(s,t,r){let e=S("HTTP Request");$.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.endpoint||"https://api.example.com/endpoint",i=n.httpMethod||"POST";return[`${t}const ${r} = await ${e.functionName}({`,`${t} url: '${o}',`,`${t} method: '${i}',`,`${t} body: {},`,`${t}});`]}function at(s){if(!s)return null;try{let t=JSON.parse(s),r=Array.isArray(t)?t.map(e=>{let{id:n,...o}=e;return o}):t;return O(r)}catch{return null}}function ct(s){let t=C(s),r=t.includes("${"),e=n=>n.replace(/\$\{/g,"$${");return r?`\`${e(t).replace(/`/g,"\\`")}\``:`\`${s.replace(/`/g,"\\`")}\``}function gt(s,t,r){let e=S("Generate Text");$.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.aiPrompt||"Generate a summary",i=n.aiModel||"meta/llama-4-scout",c=n.aiFormat||"text",g=n.aiSchema,u=ct(o),d=[`${t}// Generate text using AI`,`${t}const ${r} = await ${e.functionName}({`,`${t} model: "${i}",`,`${t} prompt: ${u},`];if(c==="object"){d.push(`${t} format: "object",`);let m=at(g);m&&d.push(`${t} schema: ${m},`)}return d.push(`${t}});`),d}function ut(s,t,r){$.add("import { experimental_generateImage as generateImage } from 'ai';");let e=s.data.config?.imagePrompt||"A beautiful landscape",n=s.data.config?.imageModel||"google/imagen-4.0-generate";return[`${t}// Generate image using AI`,`${t}const ${r} = await generateImage({`,`${t} model: "${n}",`,`${t} prompt: \`${e}\`,`,`${t} size: "1024x1024",`,`${t}});`]}function ft(s,t,r){let e=S("Send Slack Message");$.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.slackChannel||"#general",i=n.slackMessage||"Message content",c=C(o),g=C(i),u=N=>N.includes("${"),d=N=>N.replace(/\$\{/g,"$${"),m=u(c)?`\`${d(c).replace(/`/g,"\\`")}\``:`"${o}"`,h=u(g)?`\`${d(g).replace(/`/g,"\\`")}\``:`"${i}"`;return[`${t}const ${r} = await ${e.functionName}({`,`${t} slackChannel: ${m},`,`${t} slackMessage: ${h},`,`${t}});`]}function A(s){let t=C(s),r=t.includes("${"),e=t.replace(/\$\{/g,"$${").replace(/`/g,"\\`");return r?`\`${e}\``:`\`${s.replace(/`/g,"\\`")}\``}function pt(s,t,r){let e=s.data.config?.actionType,n=S(e);$.add(`import { ${n.functionName} } from '${n.importPath}';`);let o=s.data.config||{},i=o.url||"",c=o.query||"",g=o.limit?Number(o.limit):void 0,u=[`${t}const ${r} = await ${n.functionName}({`];return i&&u.push(`${t} url: ${A(i)},`),c&&u.push(`${t} query: ${A(c)},`),g&&u.push(`${t} limit: ${g},`),u.push(`${t}});`),u}function lt(s,t,r){let e=S("Create Chat");$.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.message||"",i=n.system||"",c=[`${t}const ${r} = await ${e.functionName}({`,`${t} message: ${A(o)},`];return i&&c.push(`${t} system: ${A(i)},`),c.push(`${t}});`),c}function $t(s,t,r){let e=S("Send Message");$.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.chatId||"",i=n.message||"";return[`${t}const ${r} = await ${e.functionName}({`,`${t} chatId: ${A(o)},`,`${t} message: ${A(i)},`,`${t}});`]}function B(s,t,r,e){let o={"template-input":()=>`${r} ${e}: ${A(String(t))},`,"template-textarea":()=>`${r} ${e}: ${A(String(t))},`,number:()=>`${r} ${e}: ${t},`,select:()=>`${r} ${e}: "${t}",`,"schema-builder":()=>`${r} ${e}: ${JSON.stringify(t)},`}[s];return o?o():`${r} ${e}: "${t}",`}function mt(s,t,r,e){let n=E(t);if(!n)return null;let o=S(t);$.add(`import { ${o.functionName} } from '${o.importPath}';`);let i=s.data.config||{},c=L(n.configFields),g=[];for(let d of c){let m=i[d.key];m==null||m===""||g.push(B(d.type,m,r,d.key))}let u=[];return g.length>0?(u.push(`${r}const ${e} = await ${o.functionName}({`),u.push(...g),u.push(`${r}});`)):u.push(`${r}const ${e} = await ${o.functionName}({});`),u}function dt(s,t,r,e){let n=s.data.config?.actionType,o=s.data.label||n||"Unknown Action",i=[`${r}// Action: ${o}`];s.data.description&&i.push(`${r}// ${s.data.description}`);let c=w.has(t);function g(h){let N=H.exec(h);if(N){let[,T,,W]=N;return`${T}${W}`}return h}function u(h){let N=H.exec(h);if(N){let[,T,,W]=N;return`${T}void ${W}`}return h}function d(h){let N=[];for(let T of h)T.includes("await")?N.push(g(T)):T.trim().startsWith("const")&&T.includes("{")?N.push(u(T)):N.push(T);return N}let m=h=>c?h:d(h);if(n==="Generate Text")i.push(...m(gt(s,r,e)));else if(n==="Generate Image")i.push(...m(ut(s,r,e)));else if(n==="Send Email")i.push(...m(st(s,r,e)));else if(n==="Send Slack Message")i.push(...m(ft(s,r,e)));else if(n==="Create Ticket")i.push(...m(rt(s,r,e)));else if(n==="Scrape"||n==="Search")i.push(...m(pt(s,r,e)));else if(n==="Create Chat")i.push(...m(lt(s,r,e)));else if(n==="Send Message")i.push(...m($t(s,r,e)));else if(n==="Database Query")i.push(...m(ot(s,r,e)));else if(n==="HTTP Request")i.push(...m(it(s,r,e)));else{let h=mt(s,n,r,e);h?i.push(...m(h)):c?(i.push(`${r}// TODO: Implement action type "${n}"`),i.push(`${r}const ${e} = { status: 'pending', actionType: "${n}" };`)):(i.push(`${r}// TODO: Implement action type "${n}"`),i.push(`${r}void ({ status: 'pending', actionType: "${n}" });`))}return i}function ht(s,t,r){let e=[`${r}// Condition: ${s.data.label}`];s.data.description&&e.push(`${r}// ${s.data.description}`);let n=s.data.config?.condition,o=k.get(t)||[];if(o.length>0){let i=o[0],c=o[1],g=n?z(n):"true";if(e.push(`${r}if (${g}) {`),i){let u=_(i,`${r} `);e.push(...u)}if(c){e.push(`${r}} else {`);let u=_(c,`${r} `);e.push(...u)}e.push(`${r}}`)}return e}function Nt(s,t){let r=k.get(s)||[];return{lines:G(r,t),wasSkipped:!0}}function wt(s,t,r,e){let n=[];return s.data.config?.actionType==="Condition"?(n.push(...ht(s,t,e)),n):(n.push(...dt(s,t,e,r)),n)}function I(s,t,r){if(r.has(s))return[];r.add(s);let e=y.get(s);if(!e)return[];let n=[];if(e.data.type==="action")if(e.data.config?.actionType==="Condition")n.push(...yt(e,s,t,r));else{n.push(...Tt(e,t));let i=k.get(s)||[];i.length>0&&(n.push(""),n.push(...St(i,t,r)))}return n}function yt(s,t,r,e){let n=[`${r}// Condition: ${s.data.label}`],o=s.data.config?.condition,i=k.get(t)||[];if(i.length>0){let c=o?z(o):"true";n.push(`${r}if (${c}) {`),i[0]&&n.push(...I(i[0],`${r} `,e)),i[1]&&(n.push(`${r}} else {`),n.push(...I(i[1],`${r} `,e))),n.push(`${r}}`)}return n}function Tt(s,t){let r=s.data.config?.actionType,e=s.data.label||r||"Unknown Action",n=S(r),o=Pt(s,`${t} `);$.add(`import { ${n.functionName} } from '${n.importPath}';`);let i=[`${t}// ${e}`];return o.length>0?(i.push(`${t}await ${n.functionName}({`),i.push(...o),i.push(`${t}});`)):i.push(`${t}await ${n.functionName}({});`),i}function St(s,t,r){let e=s.filter(o=>!r.has(o));if(e.length===0)return[];if(e.length===1)return I(e[0],t,r);let n=[`${t}await Promise.all([`];for(let o=0;o<e.length;o++){let i=e[o],g=o===e.length-1?"":",",u=new Set(r),d=I(i,`${t} `,u);d.length>0&&(n.push(`${t} (async () => {`),n.push(...d),n.push(`${t} })()${g}`))}return n.push(`${t}]);`),n}function Ct(s,t,r){let e=new Set(P);e.delete(s);let n=I(s,`${t} `,e),o=r?"":",";return n.length===0?[]:[`${t} (async () => {`,...n,`${t} })()${o}`]}function G(s,t){if(s.length===0)return[];let r=s.filter(n=>!P.has(n)&&y.get(n)?.data.type==="action");if(r.length===0)return[];if(r.length===1){let n=new Set(P);return P.add(r[0]),I(r[0],t,n)}for(let n of r)P.add(n);let e=[`${t}await Promise.all([`];for(let n=0;n<r.length;n++)e.push(...Ct(r[n],t,n===r.length-1));return e.push(`${t}]);`),e}function At(s,t,r){let e=E(t);if(!e)return[];let n=[];for(let o of L(e.configFields)){let i=s[o.key];i==null||i===""||n.push(B(o.type,i,r,o.key))}return n}let kt=new Set(["actionType","integrationId"]);function bt(s,t){let r=[];for(let[e,n]of Object.entries(s))kt.has(e)||n===void 0||n===null||(typeof n=="string"?r.push(`${t}${e}: ${A(n)},`):typeof n=="number"||typeof n=="boolean"?r.push(`${t}${e}: ${n},`):r.push(`${t}${e}: ${JSON.stringify(n)},`));return r}function Pt(s,t){let r=s.data.config?.actionType,e=s.data.config||{},n=At(e,r,t);return n.length>0?n:bt(e,t)}function U(s,t,r){let e=k.get(s)||[],n=[...t];return t.length>0&&e.length>0&&n.push(""),n.push(...G(e,r)),n}function _(s,t=" "){if(P.has(s))return[`${t}// Already processed: ${s}`];P.add(s);let r=y.get(s);if(!r)return[];let e=x.get(s)||`${r.data.type}_${s.replace(/-/g,"_")}`,n=[];switch(r.data.type){case"trigger":{let{lines:o,wasSkipped:i}=Nt(s,t);return i?o:U(s,o,t)}case"action":{let o=wt(r,s,e,t);if(r.data.config?.actionType==="Condition")return o;n=o;break}default:n.push(`${t}// Unknown node type: ${r.data.type}`);break}return U(s,n,t)}if(M.length===0)b.push(" // No trigger nodes found");else for(let s of M){let t=_(s.id," ");b.push(...t)}return b.push("}"),{code:`${Array.from($).join(`
|
|
2
|
+
`)}
|
|
3
|
+
|
|
4
|
+
${b.join(`
|
|
5
|
+
`)}
|
|
6
|
+
`,functionName:l,imports:Array.from($)}}function Qt(a,f,p,l={}){let{code:w}=Ft(f,p,l);return`/**
|
|
7
|
+
* Generated Workflow: ${a}
|
|
8
|
+
*
|
|
9
|
+
* This file was automatically generated from a workflow definition.
|
|
10
|
+
* DO NOT EDIT MANUALLY - regenerate from the workflow editor instead.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
${w}
|
|
14
|
+
`}export{It as a,Q as b,Lt as c,jt as d,Vt as e,zt as f,Bt as g,Gt as h,Ft as i,Qt as j};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as L}from"./chunk-3YVRTDK2.js";import{b as A}from"./chunk-6UXAINJQ.js";import{k as _,o as v,p as q,q as z}from"./chunk-5J6TNMJG.js";import{eq as Q}from"drizzle-orm";import"server-only";function J(n){return{success:!0,data:n.triggerData}}async function D(n){"use step";return n._workflowComplete?(await q(n._workflowComplete),{success:!0,data:{}}):z(n,()=>Promise.resolve(J(n)))}D.maxRetries=0;var M={"Database Query":{importer:()=>import("./database-query-OHFQUPLV.js"),stepFunction:"databaseQueryStep"},"HTTP Request":{importer:()=>import("./http-request-EHJHOTNA.js"),stepFunction:"httpRequestStep"},Condition:{importer:()=>import("./condition-CFAA7UDI.js"),stepFunction:"conditionStep"},Loop:{importer:()=>import("./loop-5LPVY452.js"),stepFunction:"loopStep"},Switch:{importer:()=>import("./switch-ZPVREROE.js"),stepFunction:"switchStep"},Merge:{importer:()=>import("./merge-HYBHX22D.js"),stepFunction:"mergeStep"},"Run Workflow":{importer:()=>import("./run-workflow-VFZV5YLI.js"),stepFunction:"runWorkflowStep"},"Run Workflows in Sequence":{importer:()=>import("./run-workflows-in-sequence-3APONBOX.js"),stepFunction:"runWorkflowsInSequenceStep"}};function $(n,w){if(n===void 0||n==="")return;let p=/\{\{@([^:]+):([^}]+)\}\}/g,d=[...n.matchAll(p)];if(d.length===0)return n;function s(y,o){let a=y.replace(/[^a-zA-Z0-9]/g,"_"),i=w[a];if(!i)return;let f=o.indexOf(".");if(f===-1)return i.data;if(i.data===null||i.data===void 0)return;let k=o.substring(f+1).split("."),c=i.data,N=k[0];c&&typeof c=="object"&&"success"in c&&"data"in c&&N!=="success"&&N!=="data"&&N!=="error"&&!(N in c)&&(c=c.data);for(let C of k)if(c&&typeof c=="object")c=c[C];else return;return c}return d.length===1&&d[0][0]===n?s(d[0][1],d[0][2]):n.replace(p,(y,o,a)=>{let i=s(o,a);return i==null?"":typeof i=="object"?JSON.stringify(i):String(i)})}function H(n,w){let p=n.dataType||"string",d=n.operator,s=n.leftValue,y=n.rightValue,o=$(s,w),a=$(y,w);return console.log("[Condition] Evaluating:",{dataType:p,operator:d,leftResolved:o,rightResolved:a}),{result:L(p,d,o,a),resolvedValues:{leftValue:o,rightValue:a}}}async function B(n){let{actionType:w,config:p,outputs:d,context:s}=n,y={...p,_context:s};if(w==="Condition"){let f=M.Condition,x=await f.importer(),{result:k,resolvedValues:c}=H(p,d);return console.log("[Condition] Final result:",k),await x[f.stepFunction]({condition:k,dataType:p.dataType,operator:p.operator,leftValue:c.leftValue,rightValue:c.rightValue,_context:s})}let o=M[w];if(o){let x=(await o.importer())[o.stepFunction];return await x(y)}let{getStepImporter:a}=await import("virtual:workflow-builder-step-registry"),i=a(w);if(i){let x=(await i.importer())[i.stepFunction];return x?await x(y):{success:!1,error:`Step function "${i.stepFunction}" not found in module for action "${w}". Check that the plugin exports the correct function name.`}}return{success:!1,error:`Unknown action type: "${w}". This action is not registered in the plugin system. Available system actions: ${Object.keys(M).join(", ")}.`}}function U(n,w){let p={};for(let[d,s]of Object.entries(n))if(typeof s=="string"){let y=s,o=/\{\{@([^:]+):([^}]+)\}\}/g;y=y.replace(o,(a,i,f)=>{let x=i.replace(/[^a-zA-Z0-9]/g,"_"),k=w[x];if(!k)return a;let c=f.indexOf(".");if(c===-1){let e=k.data;return e==null?"":typeof e=="object"?JSON.stringify(e):String(e)}if(k.data===null||k.data===void 0)return"";let C=f.substring(c+1).split("."),l=k.data,b=C[0];l&&typeof l=="object"&&"success"in l&&"data"in l&&b!=="success"&&b!=="data"&&b!=="error"&&!(b in l)&&(l=l.data);for(let e of C)if(l&&typeof l=="object")l=l[e];else return"";return l==null?"":typeof l=="object"?JSON.stringify(l):String(l)}),p[d]=y}else p[d]=s;return p}async function se(n){"use workflow";console.log("[Workflow Executor] Starting workflow execution");let{nodes:w,edges:p,triggerInput:d={},executionId:s,workflowId:y}=n;console.log("[Workflow Executor] Input:",{nodeCount:w.length,edgeCount:p.length,hasExecutionId:!!s,workflowId:y||"none"});let o={},a={},i=new Map(w.map(e=>[e.id,e])),f=new Map,x=new Map;for(let e of p){let u=f.get(e.source)||[];u.push(e.target),f.set(e.source,u);let t=x.get(e.target)||[];t.push(e.source),x.set(e.target,t)}let k=new Set(p.map(e=>e.target)),c=w.filter(e=>e.data.type==="trigger"&&!k.has(e.id));console.log("[Workflow Executor] Found",c.length,"trigger nodes");let{getActionLabel:N}=await import("virtual:workflow-builder-step-registry");function C(e){if(e.data.label)return e.data.label;if(e.data.type==="action"){let u=e.data.config?.actionType;if(u){let t=N(u);if(t)return t}return"Action"}return e.data.type==="trigger"?e.data.config?.triggerType||"Trigger":e.data.type}async function l(){return s?(await v.query.workflowExecutions.findFirst({where:Q(_.id,s),columns:{status:!0}}))?.status==="cancelled":!1}async function b(e,u=new Set){if(console.log("[Workflow Executor] Executing node:",e),await l()){console.log("[Workflow Executor] Execution cancelled, stopping");return}if(u.has(e)){console.log("[Workflow Executor] Node already visited, skipping");return}u.add(e);let t=i.get(e);if(!t){console.log("[Workflow Executor] Node not found:",e);return}if(t.data.enabled===!1){console.log("[Workflow Executor] Skipping disabled node:",e);let r=e.replace(/[^a-zA-Z0-9]/g,"_");o[r]={label:t.data.label||e,data:null};let F=f.get(e)||[];await Promise.all(F.map(h=>b(h,u)));return}try{let r;if(t.data.type==="trigger"){console.log("[Workflow Executor] Executing trigger node");let h=t.data.config||{},W=h.triggerType,g={triggered:!0,timestamp:Date.now()};if(W==="Webhook"&&h.webhookMockRequest&&(!d||Object.keys(d).length===0))try{let T=JSON.parse(h.webhookMockRequest);g={...g,...T},console.log("[Workflow Executor] Using webhook mock request data:",T)}catch(T){console.error("[Workflow Executor] Failed to parse webhook mock request:",T)}else d&&Object.keys(d).length>0&&(g={...g,...d});let m={executionId:s,nodeId:t.id,nodeName:C(t),nodeType:t.data.type},E=await D({triggerData:g,_context:m});r={success:E.success,data:E.data}}else if(t.data.type==="action"){let h=t.data.config||{},W=h.actionType;if(console.log("[Workflow Executor] Executing action node:",W),!W){r={success:!1,error:`Action node "${t.data.label||t.id}" has no action type configured`},a[e]=r;return}let g=U(h,o),m={executionId:s,nodeId:t.id,nodeName:C(t),nodeType:W},E={},T=x.get(e)||[];for(let P of T){let O=P.replace(/[^a-zA-Z0-9]/g,"_"),I=o[O];if(I?.data&&typeof I.data=="object"){let S=I.data;"success"in S&&"data"in S&&S.data&&typeof S.data=="object"&&(S=S.data);for(let[j,Z]of Object.entries(S))j!=="success"&&j!=="error"&&(E[j]=Z)}}console.log("[Workflow Executor] Calling executeActionStep");let R=await B({actionType:W,config:{...E,...g},outputs:o,context:m});if(console.log("[Workflow Executor] Step result received:",{hasResult:!!R,resultType:typeof R}),R&&typeof R=="object"&&"success"in R&&R.success===!1){let P=R,O=typeof P.error=="string"?P.error:P.error?.message||`Step "${W}" in node "${t.data.label||t.id}" failed without a specific error message.`;console.error(`[Workflow Executor] Step "${W}" failed:`,O),r={success:!1,error:O}}else r={success:!0,data:R}}else console.log("[Workflow Executor] Unknown node type:",t.data.type),r={success:!1,error:`Unknown node type "${t.data.type}" in node "${t.data.label||t.id}". Expected "trigger" or "action".`};a[e]=r;let F=e.replace(/[^a-zA-Z0-9]/g,"_");if(o[F]={label:t.data.label||e,data:r.data},console.log("[Workflow Executor] Node execution completed:",{nodeId:e,success:r.success}),r.success){let h=t.data.type==="action"&&t.data.config?.actionType==="Condition",W=t.data.type==="action"&&t.data.config?.actionType==="Loop";if(h){let g=r.data?.condition;if(console.log("[Workflow Executor] Condition node result:",g),g===!0){let m=f.get(e)||[];console.log("[Workflow Executor] Condition is true, executing",m.length,"next nodes in parallel"),await Promise.all(m.map(E=>b(E,u)))}else console.log("[Workflow Executor] Condition is false, skipping next nodes")}else if(W){let g=f.get(e)||[],m=r.data;if(m&&g.length>0){let E=new Set(u),T=0;for(;;){console.log("[Workflow Executor] Loop iteration",T,"- batchIndex:",m.currentBatchIndex,"hasMore:",m.hasMore);let R=new Set(E);if(await Promise.all(g.map(j=>b(j,R))),!m.hasMore)break;if(await l()){console.log("[Workflow Executor] Loop cancelled between iterations");break}let V=m.currentBatchIndex+1,P=t.data.config||{},O=U(P,o),I={executionId:s,nodeId:t.id,nodeName:C(t),nodeType:"Loop"},S=await B({actionType:"Loop",config:{...O,currentBatchIndex:V},outputs:o,context:I});o[F]={label:t.data.label||e,data:S},a[e]={success:!0,data:S},m=S,T++}}else g.length>0&&await Promise.all(g.map(E=>b(E,u)))}else{let g=f.get(e)||[];console.log("[Workflow Executor] Executing",g.length,"next nodes in parallel"),await Promise.all(g.map(m=>b(m,u)))}}}catch(r){console.error("[Workflow Executor] Error executing node:",e,r);let h={success:!1,error:await A(r)};a[e]=h}}try{console.log("[Workflow Executor] Starting execution from trigger nodes");let e=Date.now();await Promise.all(c.map(r=>b(r.id)));let u=Object.values(a).every(r=>r.success),t=Date.now()-e;if(console.log("[Workflow Executor] Workflow execution completed:",{success:u,resultCount:Object.keys(a).length,duration:t}),s&&!await l())try{await D({triggerData:{},_workflowComplete:{executionId:s,status:u?"success":"error",output:Object.values(a).at(-1)?.data,error:Object.values(a).find(r=>!r.success)?.error,startTime:e}}),console.log("[Workflow Executor] Updated execution record")}catch(r){console.error("[Workflow Executor] Failed to update execution record:",r)}return{success:u,results:a,outputs:o}}catch(e){console.error("[Workflow Executor] Fatal error during workflow execution:",e);let u=await A(e);if(s)try{await D({triggerData:{},_workflowComplete:{executionId:s,status:"error",error:u,startTime:Date.now()}})}catch(t){console.error("[Workflow Executor] Failed to log error:",t)}return{success:!1,results:a,outputs:o,error:u}}}export{se as a};
|
package/dist/client/index.d.ts
CHANGED
|
@@ -8,7 +8,17 @@ type Props = {
|
|
|
8
8
|
};
|
|
9
9
|
declare const WorkflowEditor: ({ workflowId }: Props) => react_jsx_runtime.JSX.Element;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
type EdgeStyle = "smoothstep" | "bezier";
|
|
12
|
+
type CanvasOptions = {
|
|
13
|
+
snapToGrid?: boolean;
|
|
14
|
+
edgeStyle?: EdgeStyle;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type LayoutProps = Omit<AuthUIProviderProps, "authClient"> & {
|
|
18
|
+
/** Canvas configuration options */
|
|
19
|
+
canvas?: CanvasOptions;
|
|
20
|
+
};
|
|
21
|
+
declare const Layout: (props: LayoutProps) => react_jsx_runtime.JSX.Element;
|
|
12
22
|
|
|
13
23
|
/**
|
|
14
24
|
* AI Gateway Managed Keys Configuration
|
|
@@ -29,4 +39,4 @@ declare function isAiGatewayManagedKeysEnabled(): boolean;
|
|
|
29
39
|
*/
|
|
30
40
|
declare function isAiGatewayManagedKeysEnabledClient(): boolean;
|
|
31
41
|
|
|
32
|
-
export { Layout, WorkflowEditor, WorkflowPage, isAiGatewayManagedKeysEnabled, isAiGatewayManagedKeysEnabledClient };
|
|
42
|
+
export { type CanvasOptions, type EdgeStyle, Layout, type LayoutProps, WorkflowEditor, WorkflowPage, isAiGatewayManagedKeysEnabled, isAiGatewayManagedKeysEnabledClient };
|