next-workflow-builder 0.5.0 → 0.7.0

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +156 -0
  2. package/README.md +1 -1
  3. package/dist/chunk-5J6TNMJG.js +1 -0
  4. package/dist/chunk-6UXAINJQ.js +1 -0
  5. package/dist/chunk-7WFHHPX4.js +1 -0
  6. package/dist/chunk-BNX2SV7E.js +1 -0
  7. package/dist/chunk-CYVALTSI.js +218 -0
  8. package/dist/chunk-DMHGXYVW.js +14 -0
  9. package/dist/chunk-HB2H2PVI.js +42 -0
  10. package/dist/chunk-IEOZJAW2.js +1 -0
  11. package/dist/chunk-KFTXS23Q.js +1 -0
  12. package/dist/chunk-NI6U7PHC.js +76 -0
  13. package/dist/chunk-PRVESNIO.js +1 -0
  14. package/dist/chunk-QRG4O4PE.js +2 -0
  15. package/dist/chunk-R5GS6TJS.js +1 -0
  16. package/dist/client/index.js +160 -13725
  17. package/dist/condition-CFAA7UDI.js +1 -0
  18. package/dist/database-query-OHFQUPLV.js +1 -0
  19. package/dist/handler-NWAMWKXW.js +1 -0
  20. package/dist/http-request-EHJHOTNA.js +1 -0
  21. package/dist/loop-5LPVY452.js +1 -0
  22. package/dist/merge-HYBHX22D.js +1 -0
  23. package/dist/next/index.d.ts +9 -0
  24. package/dist/next/index.js +1 -84
  25. package/dist/plugins/index.js +1 -54
  26. package/dist/server/api/index.d.ts +30 -1
  27. package/dist/server/api/index.js +18 -2360
  28. package/dist/server/index.js +1 -60
  29. package/dist/switch-ZPVREROE.js +1 -0
  30. package/drizzle.config.ts +9 -0
  31. package/package.json +27 -2
  32. package/src/plugins/types.ts +31 -0
  33. package/src/server/db/schema.ts +228 -0
  34. package/src/server/lib/utils/id.ts +26 -0
  35. package/dist/chunk-3XFDIK7H.js +0 -251
  36. package/dist/chunk-5H76TY4T.js +0 -51
  37. package/dist/chunk-5YYA34YV.js +0 -96
  38. package/dist/chunk-C7GDB4KC.js +0 -550
  39. package/dist/chunk-CKE7ETZL.js +0 -169
  40. package/dist/chunk-EMCA7GLF.js +0 -1305
  41. package/dist/chunk-J72T2LRL.js +0 -66
  42. package/dist/chunk-JUV5RBYM.js +0 -105
  43. package/dist/chunk-O3I2INCD.js +0 -71
  44. package/dist/chunk-OQHML4II.js +0 -36
  45. package/dist/chunk-PEVVELQ6.js +0 -438
  46. package/dist/condition-VHC4KYLI.js +0 -29
  47. package/dist/database-query-BYPF5CDB.js +0 -99
  48. package/dist/http-request-4OT32ZXA.js +0 -76
  49. package/dist/loop-S5H7DSCB.js +0 -47
  50. package/dist/merge-X5JAIZSZ.js +0 -107
  51. package/dist/style-prefixed.css +0 -5167
  52. package/dist/switch-WZBVDWWR.js +0 -68
package/CHANGELOG.md ADDED
@@ -0,0 +1,156 @@
1
+ # next-workflow-builder
2
+
3
+ ## 0.7.0
4
+
5
+ ### Features
6
+
7
+ - Add opt-in MCP (Model Context Protocol) server for AI agent integration
8
+ - Expose 10 MCP tools: list/get/create/update/delete/duplicate workflows, execute workflows, get execution status, list available actions, list integrations
9
+ - OAuth 2.1 authentication via better-auth's built-in `mcp` plugin with dynamic client registration (RFC 7591)
10
+ - Streamable HTTP transport at `/api/workflow-builder/mcp`
11
+ - New `mcp` config option in `nextWorkflowBuilder()` to enable the server
12
+ - New `anonymousAuth` config option to disable anonymous authentication (defaults to `true`)
13
+ - Export `oAuthDiscoveryHandler` and `oAuthResourceHandler` from `next-workflow-builder/api` for custom `.well-known` route setups
14
+ - Add cron endpoint (`/workflow/[workflowId]/cron`) for Vercel Cron-triggered scheduled workflow execution with `CRON_SECRET` bearer token auth
15
+ - Generate correct `vercel.json` cron config in code export — use the new cron endpoint path and pass `workflowId` when available
16
+ - Ship a bundled `drizzle.config.ts` so consumers can run `drizzle-kit generate --config=node_modules/next-workflow-builder/drizzle.config.ts` without maintaining their own config
17
+ - Publish `src/server/db/schema.ts` and its dependencies (`src/server/lib/utils/id.ts`, `src/plugins/types.ts`) so drizzle-kit can resolve the schema from the published package
18
+
19
+ ### Improvements
20
+
21
+ - Reduce published package size from 1.12 MB to ~664 KB by enabling JS minification and removing unused `style-prefixed.css`
22
+ - Include `README.md` and `CHANGELOG.md` in published package
23
+ - Add `keywords` to `package.json` for npm discoverability
24
+
25
+ ### Bug Fixes
26
+
27
+ - Fix MCP OAuth discovery for Claude Desktop and other MCP clients — use better-auth's `oAuthDiscoveryMetadata` and `oAuthProtectedResourceMetadata` helpers so root-level `.well-known` endpoints work with catch-all page routes
28
+ - Fix MCP OAuth login page default from `/sign-in` to `/auth/sign-in` where the `AuthView` component renders
29
+ - Fix MCP server requiring OAuth when anonymous auth is enabled — session-authenticated requests bypass OAuth, while unauthenticated requests receive the proper 401 for OAuth discovery
30
+ - Fix hydration mismatch in `UserMenu` when session resolves before React hydration completes
31
+ - Fix anonymous sign-in returning 404 when social providers are configured — anonymous plugin is now enabled by default regardless of configured providers
32
+ - Remove non-functional `beforeFiles` rewrites for `.well-known` OAuth routes — Next.js rewrites do not override optional catch-all `[[...slug]]` page routes
33
+ - Add explicit `.well-known` route files to demo app using exported handlers
34
+ - Fix `drizzle.config.ts` failing in consumer apps — remove TypeScript-specific syntax (`satisfies`, `import type`) and `dotenv` dependency that may not be installed
35
+
36
+ ## 0.5.0
37
+
38
+ ### Features
39
+
40
+ - Replace free-text JavaScript condition expressions with structured n8n-style condition builder
41
+ - Add data type selection (String, Number, Boolean, Date & Time) with type-specific operators
42
+ - Add 27 operators across 4 data types: string (14), number (6), boolean (4), datetime (3)
43
+ - Template variable support on both left and right value fields
44
+ - Unary operators (exists, is empty, is true, etc.) automatically hide the right value field
45
+ - Type-aware comparisons preserve raw values instead of stringifying everything
46
+
47
+ ### Breaking Changes
48
+
49
+ - Condition nodes now use `leftValue`, `dataType`, `operator`, `rightValue` config fields instead of a single `condition` expression field
50
+ - Removed `condition-validator.ts` — structured conditions don't execute arbitrary code
51
+
52
+ ## 0.4.7
53
+
54
+ ### Bug Fixes
55
+
56
+ - Inline `authOptions` and `databaseUrl` as build-time environment variables via Next.js `env` config. This eliminates the need for an `instrumentation.ts` file to re-set `__NWB_AUTH_OPTIONS` on Vercel serverless cold starts. Works for all auth providers (Vercel, Google, GitHub, etc.).
57
+
58
+ ## 0.4.6
59
+
60
+ ### Features
61
+
62
+ - Add `integrationRequiresCredentials` helper to check if an integration type requires credentials (has `formFields`). Plugins with no form fields don't need a connection.
63
+
64
+ ## 0.4.5
65
+
66
+ ### Bug Fixes
67
+
68
+ - Fix predecessor step output data not being passed to the next step's input. Steps now automatically receive output data from their predecessor nodes merged into their input (config values take precedence). Supports both standardized (`{ success, data: { ... } }`) and custom (`{ success, events: [...] }`) return formats.
69
+
70
+ ## 0.4.4
71
+
72
+ ### Bug Fixes
73
+
74
+ - Fix template variable resolution for custom plugin outputs that use non-standard return fields (e.g., `{ success: true, events: [...] }`). The auto-unwrap into `.data` now only applies when the requested field doesn't exist at the top level of the step result.
75
+
76
+ ## 0.4.3
77
+
78
+ ### Features
79
+
80
+ - Display Node ID in node details panel
81
+
82
+ ### Bug Fixes
83
+
84
+ - Fix Loop step failing when `items` arrives as a JSON string from template processing instead of an array
85
+
86
+ ## 0.4.2
87
+
88
+ ### Features
89
+
90
+ - Add optional `databaseUrl` config option to `nextWorkflowBuilder()` for overriding the database connection URL instead of relying on `process.env.DATABASE_URL`
91
+
92
+ ## 0.4.0
93
+
94
+ ### Bug Fixes
95
+
96
+ - Register Loop, Switch, and Merge as system actions in workflow executor, fixing "Unknown action type" errors when executing these built-in plugins
97
+
98
+ ## 0.3.1
99
+
100
+ ### Bug Fixes
101
+
102
+ - Ensure plugins directory exists during build to prevent missing directory errors
103
+
104
+ ## 0.3.0
105
+
106
+ ### Features
107
+
108
+ - Add new built-in Loop plugin for iterating over arrays with batch support
109
+ - Add new built-in Merge plugin for combining data from multiple inputs
110
+ - Add new built-in Switch plugin for rule-based and expression-based routing
111
+ - Refactor steps into internal/system plugin architecture
112
+
113
+ ### Bug Fixes
114
+
115
+ - Fix package metadata
116
+
117
+ ### Documentation
118
+
119
+ - Add documentation for built-in plugins
120
+
121
+ ## 0.2.0
122
+
123
+ ### Features
124
+
125
+ - Major package restructure as `next-workflow-builder` (#1)
126
+ - Add Better-Auth-UI package replacing custom auth dialog modal
127
+ - Add `nwb` CLI with build and dev scripts
128
+ - Replace jiti with virtual turbo reference modules for plugin imports
129
+ - Pass betterAuth options props in `nextWorkflowBuilder` and Layout props
130
+ - Move plugins to consumer app (`examples/demo`) with auto-discovery
131
+ - Move layout from package to consumer app for customization
132
+ - Add virtual module declarations for plugin and step registries
133
+ - Add code generation for plugin step imports
134
+
135
+ ### Bug Fixes
136
+
137
+ - Fix plugin import resolution
138
+ - Fix code generation for proper module exports
139
+ - Fix import paths and missing exports
140
+ - Fix missing metadata and README
141
+
142
+ ## 0.1.0
143
+
144
+ ### Features
145
+
146
+ - Initial release of `next-workflow-builder` package
147
+ - Visual workflow editor built with React Flow
148
+ - Node-based workflow execution engine with step handlers
149
+ - Plugin system with dynamic auto-generated registries
150
+ - Built-in plugins: Database Query, HTTP Request, Condition
151
+ - Authentication via Better Auth with anonymous sessions
152
+ - Workflow persistence with Drizzle ORM
153
+ - Template variable system for passing data between nodes
154
+ - Condition expression evaluation with security validation
155
+ - Workflow code export dialog
156
+ - Error logging for execution steps
package/README.md CHANGED
@@ -162,7 +162,7 @@ For full documentation including configuration, authentication, database setup,
162
162
 
163
163
  ## Changelog
164
164
 
165
- Full [Changelog](./CHANGELOG.md) file
165
+ Full [Changelog](https://github.com/emulienfou/next-workflow-builder/blob/main/packages/next-workflow-builder/README.md) file
166
166
 
167
167
  ## License
168
168
 
@@ -0,0 +1 @@
1
+ import{webcrypto as S}from"crypto";var A="0123456789abcdefghijklmnopqrstuvwxyz",h=21;function p(){let o=S.getRandomValues(new Uint8Array(h*2)),n="",a=0;for(;n.length<h;){let s=o[a++]&63;s<A.length&&(n+=A[s]),a>=o.length&&(S.getRandomValues(o),a=0)}return n}import{relations as U}from"drizzle-orm";import{boolean as m,jsonb as d,pgTable as u,text as t,timestamp as r}from"drizzle-orm/pg-core";var l=u("users",{id:t("id").primaryKey(),name:t("name"),email:t("email").unique(),emailVerified:m("email_verified").notNull().default(!1),image:t("image"),createdAt:r("created_at").notNull(),updatedAt:r("updated_at").notNull(),isAnonymous:m("is_anonymous").default(!1)}),E=u("sessions",{id:t("id").primaryKey(),expiresAt:r("expires_at").notNull(),token:t("token").notNull().unique(),createdAt:r("created_at").notNull(),updatedAt:r("updated_at").notNull(),ipAddress:t("ip_address"),userAgent:t("user_agent"),userId:t("user_id").notNull().references(()=>l.id)}),b=u("accounts",{id:t("id").primaryKey(),accountId:t("account_id").notNull(),providerId:t("provider_id").notNull(),userId:t("user_id").notNull().references(()=>l.id),accessToken:t("access_token"),refreshToken:t("refresh_token"),idToken:t("id_token"),accessTokenExpiresAt:r("access_token_expires_at"),refreshTokenExpiresAt:r("refresh_token_expires_at"),scope:t("scope"),password:t("password"),createdAt:r("created_at").notNull(),updatedAt:r("updated_at").notNull()}),D=u("verifications",{id:t("id").primaryKey(),identifier:t("identifier").notNull(),value:t("value").notNull(),expiresAt:r("expires_at").notNull(),createdAt:r("created_at"),updatedAt:r("updated_at")}),C=u("oauth_application",{id:t("id").primaryKey(),name:t("name"),icon:t("icon"),metadata:t("metadata"),clientId:t("client_id").notNull().unique(),clientSecret:t("client_secret"),redirectUrls:t("redirect_urls").notNull(),type:t("type").notNull(),disabled:m("disabled").default(!1),authenticationScheme:t("authentication_scheme"),userId:t("user_id").references(()=>l.id,{onDelete:"cascade"}),createdAt:r("created_at").notNull(),updatedAt:r("updated_at").notNull()}),se=u("oauth_access_token",{id:t("id").primaryKey(),accessToken:t("access_token").notNull().unique(),refreshToken:t("refresh_token").notNull().unique(),accessTokenExpiresAt:r("access_token_expires_at").notNull(),refreshTokenExpiresAt:r("refresh_token_expires_at").notNull(),clientId:t("client_id").notNull().references(()=>C.clientId,{onDelete:"cascade"}),userId:t("user_id").references(()=>l.id,{onDelete:"cascade"}),scopes:t("scopes").notNull(),createdAt:r("created_at").notNull(),updatedAt:r("updated_at").notNull()}),ie=u("oauth_consent",{id:t("id").primaryKey(),clientId:t("client_id").notNull().references(()=>C.clientId,{onDelete:"cascade"}),userId:t("user_id").notNull().references(()=>l.id,{onDelete:"cascade"}),scopes:t("scopes").notNull(),createdAt:r("created_at").notNull(),updatedAt:r("updated_at").notNull(),consentGiven:m("consent_given").notNull().default(!1)}),g=u("workflows",{id:t("id").primaryKey().$defaultFn(()=>p()),name:t("name").notNull(),description:t("description"),userId:t("user_id").notNull().references(()=>l.id),nodes:d("nodes").notNull().$type(),edges:d("edges").notNull().$type(),visibility:t("visibility").notNull().default("private").$type(),createdAt:r("created_at").notNull().defaultNow(),updatedAt:r("updated_at").notNull().defaultNow()}),v=u("integrations",{id:t("id").primaryKey().$defaultFn(()=>p()),userId:t("user_id").notNull().references(()=>l.id),name:t("name").notNull(),type:t("type").notNull().$type(),config:d("config").notNull().$type(),isManaged:m("is_managed").default(!1),createdAt:r("created_at").notNull().defaultNow(),updatedAt:r("updated_at").notNull().defaultNow()}),c=u("workflow_executions",{id:t("id").primaryKey().$defaultFn(()=>p()),workflowId:t("workflow_id").notNull().references(()=>g.id),userId:t("user_id").notNull().references(()=>l.id),status:t("status").notNull().$type(),input:d("input").$type(),output:d("output").$type(),error:t("error"),startedAt:r("started_at").notNull().defaultNow(),completedAt:r("completed_at"),duration:t("duration")}),f=u("workflow_execution_logs",{id:t("id").primaryKey().$defaultFn(()=>p()),executionId:t("execution_id").notNull().references(()=>c.id),nodeId:t("node_id").notNull(),nodeName:t("node_name").notNull(),nodeType:t("node_type").notNull(),status:t("status").notNull().$type(),input:d("input").$type(),output:d("output").$type(),error:t("error"),startedAt:r("started_at").notNull().defaultNow(),completedAt:r("completed_at"),duration:t("duration"),timestamp:r("timestamp").notNull().defaultNow()}),$=u("api_keys",{id:t("id").primaryKey().$defaultFn(()=>p()),userId:t("user_id").notNull().references(()=>l.id),name:t("name"),keyHash:t("key_hash").notNull(),keyPrefix:t("key_prefix").notNull(),createdAt:r("created_at").notNull().defaultNow(),lastUsedAt:r("last_used_at")}),R=U(c,({one:e})=>({workflow:e(g,{fields:[c.workflowId],references:[g.id]})}));import{drizzle as z}from"drizzle-orm/postgres-js";import L from"postgres";var H={users:l,sessions:E,accounts:b,verifications:D,workflows:g,workflowExecutions:c,workflowExecutionLogs:f,workflowExecutionsRelations:R,apiKeys:$,integrations:v},K=process.env.NWB_DATABASE_URL||process.env.DATABASE_URL||"postgres://localhost:5432/workflow",de=L(K,{max:1}),x=globalThis,W=x.queryClient??L(K,{max:10}),w=x.db??z(W,{schema:H});process.env.NODE_ENV!=="production"&&(x.queryClient=W,x.db=w);import"server-only";var B=new Set(["apiKey","api_key","apikey","key","password","passwd","pwd","secret","token","accessToken","access_token","refreshToken","refresh_token","privateKey","private_key","databaseUrl","database_url","connectionString","connection_string","fromEmail","from_email","authorization","auth","bearer","creditCard","credit_card","cardNumber","card_number","cvv","ssn","phoneNumber","phone_number","socialSecurity","social_security"]),M=[/api[_-]?key/i,/token/i,/secret/i,/password/i,/credential/i,/auth/i];function G(e){return B.has(e.toLowerCase())?!0:M.some(o=>o.test(e))}function J(e){if(!e||e.length===0)return"[REDACTED]";if(e.length<=4)return"****";let o=e.slice(-4);return`${"*".repeat(Math.min(8,e.length-4))}${o}`}function I(e,o=0){if(o>10||e==null||typeof e=="string"||typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(n=>I(n,o+1));if(typeof e=="object"){let n={};for(let[a,s]of Object.entries(e))G(a)?typeof s=="string"?n[a]=J(s):n[a]="[REDACTED]":n[a]=I(s,o+1);return n}return e}function k(e){if(e==null)return e;try{return I(e)}catch(o){return console.error("[Redact] Error redacting data:",o),"[REDACTION_ERROR]"}}import"server-only";import{eq as P}from"drizzle-orm";async function O(e){let[o]=await w.insert(f).values({executionId:e.executionId,nodeId:e.nodeId,nodeName:e.nodeName,nodeType:e.nodeType,status:"running",input:e.input,startedAt:new Date}).returning();return{logId:o.id,startTime:Date.now()}}async function q(e){let o=Date.now()-e.startTime;await w.update(f).set({status:e.status,output:e.output,error:e.error,completedAt:new Date,duration:o.toString()}).where(P(f.id,e.logId))}async function F(e){let o=Date.now()-e.startTime;await w.update(c).set({status:e.status,output:e.output,error:e.error,completedAt:new Date,duration:o.toString()}).where(P(c.id,e.executionId))}async function Y(e,o){if(!e?.executionId)return{logId:"",startTime:Date.now()};try{let n=k(o);return await O({executionId:e.executionId,nodeId:e.nodeId,nodeName:e.nodeName,nodeType:e.nodeType,input:n})}catch(n){return console.error("[stepHandler] Failed to log start:",n),{logId:"",startTime:Date.now()}}}async function N(e,o,n,a){if(e.logId)try{let s=k(n);await q({logId:e.logId,startTime:e.startTime,status:o,output:s,error:a})}catch(s){console.error("[stepHandler] Failed to log completion:",s)}}var Q=["_context","actionType","integrationId"];function X(e){let o={...e};for(let n of Q)delete o[n];return o}async function Z(e){try{let o=k(e.output);await F({executionId:e.executionId,status:e.status,output:o,error:e.error,startTime:e.startTime})}catch(o){console.error("[stepHandler] Failed to log workflow completion:",o)}}async function Ie(e,o){let n=e._context,a=X(e),s=await Y(n,a);try{let i=await o(),_=i&&typeof i=="object"&&"success"in i&&typeof i.success=="boolean";if(_&&i.success===!1){let y=i,T=typeof y.error=="string"?y.error:y.error?.message||"Step execution failed",V=y.error??{message:T};await N(s,"error",V,T)}else _?await N(s,"success",i.data??i):await N(s,"success",i);return n?._workflowComplete&&n.executionId&&await Z({executionId:n.executionId,...n._workflowComplete}),i}catch(i){let _=i instanceof Error?i.message:"Unknown error";throw await N(s,"error",void 0,_),i}}export{p as a,l as b,E as c,b as d,D as e,C as f,se as g,ie as h,g as i,v as j,c as k,f as l,$ as m,R as n,w as o,Z as p,Ie as q};
@@ -0,0 +1 @@
1
+ import{clsx as o}from"clsx";import{twMerge as i}from"tailwind-merge";function f(...e){return i(o(e))}function r(e){if(e==null)return"Unknown error";if(e instanceof Error)return e.cause&&e.cause instanceof Error?`${e.message}: ${e.cause.message}`:e.message;if(typeof e=="string")return e;if(typeof e=="object"){let t=e;if(typeof t.message=="string"&&t.message)return t.message;if(t.responseBody&&typeof t.responseBody=="object"){let n=t.responseBody;if(typeof n.error=="string")return n.error;if(n.error&&typeof n.error=="object"&&typeof n.error.message=="string")return n.error.message}if(typeof t.error=="string"&&t.error)return t.error;if(t.error&&typeof t.error=="object"){let n=t.error;if(typeof n.message=="string")return n.message}if(t.data&&typeof t.data=="object"){let n=t.data;if(typeof n.error=="string")return n.error;if(typeof n.message=="string")return n.message}if(typeof t.reason=="string"&&t.reason)return t.reason;if(typeof t.statusText=="string"&&t.statusText){let n=typeof t.status=="number"?` (${t.status})`:"";return`${t.statusText}${n}`}try{let n=JSON.stringify(e,null,0);if(n&&n!=="{}"&&n.length<500)return n}catch{}let s=Object.prototype.toString.call(e);if(s!=="[object Object]")return s}return"Unknown error"}async function c(e){if(e instanceof Promise)try{let t=await e;return r(t)}catch(t){return r(t)}if(e&&typeof e=="object"&&"then"in e&&typeof e.then=="function")try{let t=await e;return r(t)}catch(t){return r(t)}return r(e)}export{f as a,c as b};
@@ -0,0 +1 @@
1
+ function s(n){if(n==null)return"Unknown error";if(n instanceof Error)return n.cause&&n.cause instanceof Error?`${n.message}: ${n.cause.message}`:n.message;if(typeof n=="string")return n;if(typeof n=="object"){let e=n;if(typeof e.message=="string"&&e.message)return e.message;if(e.responseBody&&typeof e.responseBody=="object"){let t=e.responseBody;if(typeof t.error=="string")return t.error;if(t.error&&typeof t.error=="object"&&typeof t.error.message=="string")return t.error.message}if(typeof e.error=="string"&&e.error)return e.error;if(e.error&&typeof e.error=="object"){let t=e.error;if(typeof t.message=="string")return t.message}if(e.data&&typeof e.data=="object"){let t=e.data;if(typeof t.error=="string")return t.error;if(typeof t.message=="string")return t.message}if(typeof e.reason=="string"&&e.reason)return e.reason;if(typeof e.statusText=="string"&&e.statusText){let t=typeof e.status=="number"?` (${e.status})`:"";return`${e.statusText}${t}`}try{let t=JSON.stringify(n,null,0);if(t&&t!=="{}"&&t.length<500)return t}catch{}let r=Object.prototype.toString.call(n);if(r!=="[object Object]")return r}return"Unknown error"}export{s as a};
@@ -0,0 +1 @@
1
+ import{join as t}from"path";var s=process.cwd(),e=t(s,"plugins"),o=t(s,"lib"),r=t(e,"index.ts"),n=t(o,"types","integration.ts"),p=t(s,".gitignore"),c=t(o,"step-registry.ts"),T=t(o,"output-display-configs.ts"),_=t(o,"codegen-registry.ts"),I=["database"],x=/^\s*/,P=t(".","lib","next-boilerplate"),i=t(process.cwd(),"lib","codegen-templates"),R=/[^a-zA-Z0-9\s]/g,L=/\s+/,N=/export default `([\s\S]*)`/,S=process.env.NODE_ENV==="production";export{e as a,r as b,n as c,p as d,c as e,T as f,_ as g,I as h,x as i,P as j,i as k,R as l,L as m,N as n};
@@ -0,0 +1,218 @@
1
+ import{a as l,b as T,c as d,d as f,e as I,f as h,g as A,h as b,i as F}from"./chunk-BNX2SV7E.js";import{e as g,i as u,j as S}from"./chunk-QRG4O4PE.js";import{createJiti as P}from"jiti";import{existsSync as y,mkdirSync as w,readdirSync as $,readFileSync as x,statSync as C,writeFileSync as c}from"fs";import{dirname as v,join as E,relative as L}from"path";import p from"typescript";async function O(t){try{return await(await import("prettier")).format(t,{parser:"typescript"})}catch(e){return console.warn(" Warning: Failed to format generated code:",e),t}}var D=new Map;function R(t){let n=`/**
2
+ * Plugins Index (Auto-Generated)
3
+ *
4
+ * This file is automatically generated by scripts/discover-plugins.ts
5
+ * DO NOT EDIT MANUALLY - your changes will be overwritten!
6
+ *
7
+ * To add a new integration:
8
+ * 1. Create a new directory in plugins/ (e.g., plugins/my-integration/)
9
+ * 2. Add your plugin files (index.tsx, steps/, codegen/, etc.)
10
+ * 3. Run: pnpm discover-plugins (or it runs automatically on build)
11
+ *
12
+ * To remove an integration:
13
+ * 1. Delete the plugin directory
14
+ * 2. Run: pnpm discover-plugins (or it runs automatically on build)
15
+ */
16
+
17
+ // Side-effect imports: each plugin calls registerIntegration() on import
18
+ ${t.map(i=>`import "./${i}";`).join(`
19
+ `)||"// No plugins discovered"}
20
+
21
+ // Re-export registry utilities so consuming apps can import from "@/plugins"
22
+ export {
23
+ computeActionId,
24
+ findActionById,
25
+ flattenConfigFields,
26
+ generateAIActionPrompts,
27
+ getActionsByCategory,
28
+ getAllActions,
29
+ getAllDependencies,
30
+ getAllEnvVars,
31
+ getAllIntegrations,
32
+ getCredentialMapping,
33
+ getDependenciesForActions,
34
+ getIntegration,
35
+ getIntegrationLabels,
36
+ getIntegrationTypes,
37
+ getPluginEnvVars,
38
+ getSortedIntegrationTypes,
39
+ isFieldGroup,
40
+ parseActionId,
41
+ registerIntegration,
42
+ } from "next-workflow-builder/plugins";
43
+
44
+ export type {
45
+ ActionConfigField,
46
+ ActionConfigFieldBase,
47
+ ActionConfigFieldGroup,
48
+ ActionWithFullId,
49
+ IntegrationPlugin,
50
+ PluginAction,
51
+ } from "next-workflow-builder/plugins";
52
+ `;c(T,n,"utf-8")}async function N(){let t=v(d);y(t)||w(t,{recursive:!0});let n=[...S(),...b].sort(),i=n.map(o=>` | "${o}"`).join(`
53
+ `),r=`/**
54
+ * Integration Types (Auto-Generated)
55
+ *
56
+ * This file is automatically generated by scripts/discover-plugins.ts
57
+ * DO NOT EDIT MANUALLY - your changes will be overwritten!
58
+ *
59
+ * To add a new integration type:
60
+ * 1. Create a plugin in plugins/ directory, OR
61
+ * 2. Add a system integration to SYSTEM_INTEGRATION_TYPES in discover-plugins.ts
62
+ * 3. Run: pnpm discover-plugins
63
+ *
64
+ * Generated types: ${n.join(", ")}
65
+ */
66
+
67
+ // Integration type union - plugins + system integrations
68
+ export type IntegrationType =
69
+ ${i};
70
+
71
+ // Generic config type - plugins define their own keys via formFields[].configKey
72
+ export type IntegrationConfig = Record<string, string | undefined>;
73
+ `;c(d,r,"utf-8"),console.log(`Generated lib/types/integration.ts with ${n.length} type(s)`)}function _(){let t=Array.from(D.entries());if(t.length===0){console.log("No codegen templates generated");return}let e=t.map(([i,{template:r}])=>{let o=r.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"\\${");return` "${i}": \`${o}\`,`}).join(`
74
+
75
+ `),n=`/**
76
+ * Codegen Registry (Auto-Generated)
77
+ *
78
+ * This file is automatically generated by scripts/discover-plugins.ts
79
+ * DO NOT EDIT MANUALLY - your changes will be overwritten!
80
+ *
81
+ * Contains auto-generated codegen templates for steps with stepHandler.
82
+ * These templates are used when exporting workflows to standalone projects.
83
+ *
84
+ * Generated templates: ${t.length}
85
+ */
86
+
87
+ /**
88
+ * Auto-generated codegen templates
89
+ * Maps action IDs to their generated export code templates
90
+ */
91
+ export const AUTO_GENERATED_TEMPLATES: Record<string, string> = {
92
+ ${e}
93
+ };
94
+
95
+ /**
96
+ * Get the auto-generated codegen template for an action
97
+ */
98
+ export function getAutoGeneratedTemplate(actionId: string): string | undefined {
99
+ return AUTO_GENERATED_TEMPLATES[actionId];
100
+ }
101
+ `;c(A,n,"utf-8"),console.log(`Generated lib/codegen-registry.ts with ${t.length} template(s)`)}async function U(){let t=u(),e=[];for(let o of t)for(let s of o.actions){let a=g(o.type,s.slug);e.push({actionId:a,label:s.label,integration:o.type,stepImportPath:s.stepImportPath,stepFunction:s.stepFunction})}let n=e.flatMap(({actionId:o,integration:s,stepImportPath:a,stepFunction:m})=>[` "${o}": {
102
+ importer: () => import("@/plugins/${s}/steps/${a}"),
103
+ stepFunction: "${m}",
104
+ },`]).join(`
105
+ `),i=e.map(({actionId:o,label:s})=>` "${o}": "${s}",`).join(`
106
+ `),r=`/**
107
+ * Step Registry (Auto-Generated)
108
+ *
109
+ * This file is automatically generated by scripts/discover-plugins.ts
110
+ * DO NOT EDIT MANUALLY - your changes will be overwritten!
111
+ *
112
+ * This registry enables dynamic step imports that are statically analyzable
113
+ * by the bundler. Each action type maps to its step importer function.
114
+ *
115
+ * Generated entries: ${e.length}
116
+ */
117
+
118
+ // biome-ignore lint/suspicious/noExplicitAny: Dynamic step module types - step functions take any input
119
+ export type StepFunction = (input: any) => Promise<any>;
120
+
121
+ // Step modules may contain the step function plus other exports (types, constants, etc.)
122
+ // biome-ignore lint/suspicious/noExplicitAny: Dynamic module with mixed exports
123
+ export type StepModule = Record<string, any>;
124
+
125
+ export type StepImporter = {
126
+ importer: () => Promise<StepModule>;
127
+ stepFunction: string;
128
+ };
129
+
130
+ /**
131
+ * Plugin step importers - maps action types to their step import functions
132
+ * These imports are statically analyzable by the bundler
133
+ */
134
+ export const PLUGIN_STEP_IMPORTERS: Record<string, StepImporter> = {
135
+ ${n}
136
+ };
137
+
138
+ /**
139
+ * Action labels - maps action IDs to human-readable labels
140
+ * Used for displaying friendly names in the UI (e.g., Runs tab)
141
+ */
142
+ export const ACTION_LABELS: Record<string, string> = {
143
+ ${i}
144
+ };
145
+
146
+ /**
147
+ * Get a step importer for an action type
148
+ */
149
+ export function getStepImporter(actionType: string): StepImporter | undefined {
150
+ return PLUGIN_STEP_IMPORTERS[actionType];
151
+ }
152
+
153
+ /**
154
+ * Get the human-readable label for an action type
155
+ */
156
+ export function getActionLabel(actionType: string): string | undefined {
157
+ return ACTION_LABELS[actionType];
158
+ }
159
+ `;c(I,r,"utf-8"),console.log(`Generated lib/step-registry.ts with ${e.length} step(s)`)}async function M(){let t=u(),e=[];for(let r of t)for(let o of r.actions)o.outputConfig&&o.outputConfig.type!=="component"&&e.push({actionId:g(r.type,o.slug),type:o.outputConfig.type,field:o.outputConfig.field});let n=e.map(({actionId:r,type:o,field:s})=>` "${r}": { type: "${o}", field: "${s}" },`).join(`
160
+ `),i=`/**
161
+ * Output Display Configs (Auto-Generated)
162
+ *
163
+ * This file is automatically generated by scripts/discover-plugins.ts
164
+ * DO NOT EDIT MANUALLY - your changes will be overwritten!
165
+ *
166
+ * This file is CLIENT-SAFE and can be imported in client components.
167
+ * It maps action IDs to their output display configuration.
168
+ *
169
+ * Generated configs: ${e.length}
170
+ */
171
+
172
+ export type OutputDisplayConfig = {
173
+ type: "image" | "video" | "url";
174
+ field: string;
175
+ };
176
+
177
+ /**
178
+ * Output display configs - maps action IDs to their display configuration
179
+ * Used for rendering outputs in the workflow runs panel
180
+ */
181
+ export const OUTPUT_DISPLAY_CONFIGS: Record<string, OutputDisplayConfig> = {
182
+ ${n}
183
+ };
184
+
185
+ /**
186
+ * Get the output display config for an action type
187
+ */
188
+ export function getOutputDisplayConfig(actionType: string): OutputDisplayConfig | undefined {
189
+ return OUTPUT_DISPLAY_CONFIGS[actionType];
190
+ }
191
+ `;c(h,i,"utf-8"),console.log(`Generated lib/output-display-configs.ts with ${e.length} config(s)`)}function j(t,e){return!(t.startsWith("@/")||t.startsWith(".")||e.includes("server-only"))}function W(t,e){if(!(t.name&&t.body))return null;let n=t.parameters.map(o=>e.slice(o.pos,o.end).trim()).join(", "),i=t.type?e.slice(t.type.pos,t.type.end).trim():"Promise<unknown>",r=e.slice(t.body.pos,t.body.end).trim();return{name:t.name.text,params:n,returnType:i,body:r}}function Y(){return{hasExportCore:!1,integrationType:null,coreFunction:null,inputTypes:[],imports:[]}}function k(t,e){if(!p.isIdentifier(t.name))return;let n=t.name.text,i=t.initializer;n==="_integrationType"&&i&&p.isStringLiteral(i)&&(e.integrationType=i.text)}function V(t,e){if(t.modifiers?.some(i=>i.kind===p.SyntaxKind.ExportKeyword))for(let i of t.declarationList.declarations)k(i,e)}function B(t){return t.endsWith("Result")||t.endsWith("Credentials")||t.endsWith("CoreInput")}function z(t,e,n){B(t.name.text)&&n.inputTypes.push(e.slice(t.pos,t.end).trim())}function H(t,e,n){let i=t.moduleSpecifier;if(!p.isStringLiteral(i))return;let r=e.slice(t.pos,t.end).trim();j(i.text,r)&&n.imports.push(r)}function K(t,e,n){if(p.isVariableStatement(t)){V(t,n);return}if(p.isTypeAliasDeclaration(t)){z(t,e,n);return}if(p.isImportDeclaration(t)){H(t,e,n);return}p.isFunctionDeclaration(t)&&t.name?.text==="stepHandler"&&(n.hasExportCore=!0,n.coreFunction=W(t,e))}function J(t){let e=Y();if(!y(t))return e;let n=x(t,"utf-8"),i=p.createSourceFile(t,n,p.ScriptTarget.Latest,!0);return p.forEachChild(i,r=>{K(r,n,e)}),e}async function q(t,e){let n=J(t);if(!(n.hasExportCore&&n.coreFunction))return null;let{coreFunction:i,integrationType:r,inputTypes:o,imports:s}=n,a=i.body.trim();a.startsWith("{")&&(a=a.slice(1)),a.endsWith("}")&&(a=a.slice(0,-1)),a=a.trim();let m=i.params.split(",")[0].replace(F,"").split(":")[1]?.trim()||"unknown",G=`${s.join(`
192
+ `)}
193
+ import { fetchCredentials } from './lib/credential-helper';
194
+
195
+ function getErrorMessage(error: unknown): string {
196
+ if (error instanceof Error) return error.message;
197
+ return String(error);
198
+ }
199
+
200
+ ${o.join(`
201
+
202
+ `)}
203
+
204
+ export async function ${e}(input: ${m}): ${i.returnType} {
205
+ "use step";
206
+ const credentials = await fetchCredentials("${r||"unknown"}");
207
+ ${a}
208
+ }`;return await O(G)}async function Q(){let t=u();for(let e of t)for(let n of e.actions){let i=E(l,e.type,"steps",`${n.stepImportPath}.ts`),r=await q(i,n.stepFunction);if(r){let o=g(e.type,n.slug);D.set(o,{template:r,integrationType:e.type}),console.log(` Generated codegen template for ${o}`)}}}function X(){let t=`
209
+ # Auto-generated by discover-plugins`,n=[d,A,I,h,T].map(s=>L(process.cwd(),s)),i="";y(f)&&(i=x(f,"utf-8"));let r=new Set(i.split(`
210
+ `).map(s=>s.trim())),o=n.filter(s=>!r.has(s));if(o.length>0){let s="";i.length>0&&!i.endsWith(`
211
+ `)&&(s+=`
212
+ `),i.includes(t)||(s+=`${t}
213
+ `),s+=o.join(`
214
+ `)+`
215
+ `,c(f,i+s,"utf-8"),console.log(`Updated .gitignore with ${o.length} new file(s).`)}}async function rt(){console.log("Discovering plugins..."),y(l)||(w(l,{recursive:!0}),console.log("Created plugins/ directory"));let e=$(l).filter(n=>{if(n.startsWith("_")||n.startsWith(".")||n==="index.ts"||n==="registry.ts")return!1;let i=E(l,n);try{return C(i).isDirectory()}catch{return!1}}).sort();if(e.length===0)console.log("No plugins found in plugins/ directory");else{console.log(`Found ${e.length} plugin(s):`);for(let n of e)console.log(` - ${n}`)}if(X(),console.log("Generating plugins/index.ts..."),R(e),e.length>0){console.log(`Registering plugins...
216
+ `);let n=P(import.meta.url,{jsx:!0});for(let i of e)try{await n.import(E(l,i)),console.log(` Registered: ${i}`)}catch(r){console.warn(` Warning: Failed to import plugin ${i}:`,r)}}console.log("Generating lib/types/integration.ts..."),await N(),console.log("Generating lib/step-registry.ts..."),await U(),console.log("Generating lib/output-display-configs.ts..."),await M(),console.log(`
217
+ Processing step files for codegen templates...`),await Q(),console.log("Generating lib/codegen-registry.ts..."),_(),console.log(`Done! Plugin registry updated.
218
+ `)}export{rt as a};
@@ -0,0 +1,14 @@
1
+ import{m as I,w as M}from"./chunk-QRG4O4PE.js";var v=/\{\{([^}]+)\}\}/g,U=/\s+/,Pt=/[^a-zA-Z0-9]/g,Et=/^([^[]+)\[(\d+)\]$/,Wt=/^[a-zA-Z_$][a-zA-Z0-9_$]*$/,J=/^[0-9]/;function It(a){let l=new Set;if(!a||typeof a!="string")return l;let u;for(;(u=v.exec(a))!==null;){let d=u[1].trim();if(d.startsWith("@")){let g=d.substring(1),c=g.indexOf(":");if(c!==-1){let w=g.substring(0,c);l.add(w)}}else if(d.startsWith("$")){let c=d.substring(1).split(".");c.length>0&&l.add(c[0])}}return l}function Ot(a){let l=new Set;if(typeof a=="string"){let u=It(a);for(let d of u)l.add(d)}return l}function Q(a){let l=new Set;for(let u of a){if(u.data.type!=="action")continue;let d=u.data.config||{};for(let g of Object.values(d)){let c=Ot(g);for(let w of c)l.add(w)}}return l}function Mt(a){let l=new Map;for(let u of a){let d=l.get(u.source)||[];d.push(u.target),l.set(u.source,d)}return l}function _t(a,l){let u=new Set(l.map(d=>d.target));return a.filter(d=>d.data.type==="trigger"&&!u.has(d.id))}function O(a){return a.split(".").map(l=>{let u=Et.exec(l);return u?`.${u[1]}[${u[2]}]`:`.${l}`}).join("")}function H(a,l){return`${(a||l||"result").split(U).map((g,c)=>{let w=g.replace(Pt,"");return w?c===0?w.toLowerCase():w.charAt(0).toUpperCase()+w.slice(1).toLowerCase():""}).filter(g=>g.length>0).join("")}Result`}function _(a){return a.replace(/\u00a0/g," ").replace(/[\u2000-\u200B\u2028\u2029]/g," ")}function Lt(a){return a?a.replace(/\\/g,"\\\\").replace(/`/g,"\\`"):""}function jt(a){return a.replace(/[^a-zA-Z0-9]/g,"_").replace(J,"_$&").replace(/_+/g,"_")}function Bt(a){let l=a.split(U).filter(d=>d.length>0).map((d,g)=>{let c=d.replace(/[^a-zA-Z0-9]/g,"");return c?g===0?c.toLowerCase():c.charAt(0).toUpperCase()+c.slice(1).toLowerCase():""}).filter(d=>d.length>0).join("");return!l||l.length===0?"unnamedStep":`${l.replace(J,"_$&")}Step`}function zt(a){return a.replace(/[^a-zA-Z0-9]/g,"_")}function R(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(u=>R(u)).join(", ")}]`:typeof a=="object"?`{${Object.entries(a).map(([u,d])=>`${Wt.test(u)?u:JSON.stringify(u)}: ${R(d)}`).join(", ")}}`:String(a)}var Rt={"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 b(a){let l=Rt[a];if(l)return l;let u=I(a);return u?{functionName:u.stepFunction,importPath:`./steps/${u.stepImportPath}-step`}:{functionName:"unknownStep",importPath:"./steps/unknown-step"}}var Z=/^(\s*)(const\s+\w+\s*=\s*)(.*)$/;function vt(a,l,u={}){let{functionName:d="executeWorkflow"}=u,g=Q(a),c=new Set,w=new Map(a.map(s=>[s.id,s])),k=new Map;for(let s of l){let t=k.get(s.source)||[];t.push(s.target),k.set(s.source,t)}let Y=new Set(l.map(s=>s.target)),D=a.filter(s=>s.data.type==="trigger"&&!Y.has(s.id)),V=D.some(s=>g.has(s.id)),A=[],C=new Set,X=V?`export async function ${d}<TInput>(input: TInput) {`:`export async function ${d}() {`;A.push(X),A.push(' "use workflow";'),A.push("");let P=new Map,L=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=H(e,r);t=n;let o=1;for(;L.has(t);)t=`${n}${o}`,o+=1;L.add(t)}else t="input";P.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("."),f=i!==-1?o.substring(i+1):"",p=P.get(n);if(!p)return t;if(!f)return`\${${p}}`;let $=O(f);return`\${${p}${$}}`}function tt(s,t){let e=s.substring(1).split("."),n=e[0],o=e.slice(1).join("."),i=P.get(n);if(!i)return t;if(!o)return`\${${i}}`;let f=O(o);return`\${${i}${f}}`}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("."),f=i!==-1?o.substring(i+1):"",p=P.get(n);if(!p)return t;if(!f)return p;let $=O(f);return`${p}${$}`}function nt(s,t){let e=s.substring(1).split("."),n=e[0],o=e.slice(1).join("."),i=P.get(n);if(!i)return t;if(!o)return i;let f=O(o);return`${i}${f}`}function S(s){return!s||typeof s!="string"?s:s.replace(v,(t,r)=>{let e=r.trim();return e.startsWith("@")?K(e,t):e.startsWith("$")?tt(e,t):t})}function j(s){if(!s||typeof s!="string")return s;let r=_(s).replace(v,(e,n)=>{let o=n.trim();return o.startsWith("@")?et(o,e):o.startsWith("$")?nt(o,e):e});return _(r)}function st(s,t,r){let e=b("Send Email");c.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.emailTo||"user@example.com",i=n.emailSubject||"Notification",f=n.emailBody||"No content",p=S(o),$=S(i),h=S(f),m=q=>q.includes("${"),y=q=>q.replace(/\$\{/g,"$${"),N=m(p)?`\`${y(p).replace(/`/g,"\\`")}\``:`'${o.replace(/'/g,"\\'")}'`,T=m($)?`\`${y($).replace(/`/g,"\\`")}\``:`'${i.replace(/'/g,"\\'")}'`,W=m(h)?`\`${y(h).replace(/`/g,"\\`")}\``:`'${f.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=b("Create Ticket");c.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.ticketTitle||"New Ticket",i=n.ticketDescription||"",f=S(o),p=S(i),$=N=>N.includes("${"),h=N=>N.replace(/\$\{/g,"$${"),m=$(f)?`\`${h(f).replace(/`/g,"\\`")}\``:`'${o.replace(/'/g,"\\'")}'`,y=$(p)?`\`${h(p).replace(/`/g,"\\`")}\``:`'${i.replace(/'/g,"\\'")}'`;return[`${t}const ${r} = await ${e.functionName}({`,`${t} ticketTitle: ${m},`,`${t} ticketDescription: ${y},`,`${t}});`]}function ot(s,t,r){let e=b("Database Query");c.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.dbQuery||"",i=n.dataSource||"",f=n.dbTable||n.tableName||"your_table",p=[`${t}const ${r} = await ${e.functionName}({`];if(i?p.push(`${t} dataSource: { name: "${i}" },`):p.push(`${t} dataSource: {},`),o){let $=S(o),y=$.includes("${")?`\`${(N=>N.replace(/\$\{/g,"$${"))($).replace(/`/g,"\\`")}\``:`\`${o.replace(/`/g,"\\`")}\``;p.push(`${t} query: ${y},`)}else p.push(`${t} query: "${f}",`);return p.push(`${t}});`),p}function it(s,t,r){let e=b("HTTP Request");c.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 R(r)}catch{return null}}function ct(s){let t=S(s),r=t.includes("${"),e=n=>n.replace(/\$\{/g,"$${");return r?`\`${e(t).replace(/`/g,"\\`")}\``:`\`${s.replace(/`/g,"\\`")}\``}function ut(s,t,r){let e=b("Generate Text");c.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",f=n.aiFormat||"text",p=n.aiSchema,$=ct(o),h=[`${t}// Generate text using AI`,`${t}const ${r} = await ${e.functionName}({`,`${t} model: "${i}",`,`${t} prompt: ${$},`];if(f==="object"){h.push(`${t} format: "object",`);let m=at(p);m&&h.push(`${t} schema: ${m},`)}return h.push(`${t}});`),h}function lt(s,t,r){c.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 gt(s,t,r){let e=b("Send Slack Message");c.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.slackChannel||"#general",i=n.slackMessage||"Message content",f=S(o),p=S(i),$=N=>N.includes("${"),h=N=>N.replace(/\$\{/g,"$${"),m=$(f)?`\`${h(f).replace(/`/g,"\\`")}\``:`"${o}"`,y=$(p)?`\`${h(p).replace(/`/g,"\\`")}\``:`"${i}"`;return[`${t}const ${r} = await ${e.functionName}({`,`${t} slackChannel: ${m},`,`${t} slackMessage: ${y},`,`${t}});`]}function x(s){let t=S(s),r=t.includes("${"),e=t.replace(/\$\{/g,"$${").replace(/`/g,"\\`");return r?`\`${e}\``:`\`${s.replace(/`/g,"\\`")}\``}function ft(s,t,r){let e=s.data.config?.actionType,n=b(e);c.add(`import { ${n.functionName} } from '${n.importPath}';`);let o=s.data.config||{},i=o.url||"",f=o.query||"",p=o.limit?Number(o.limit):void 0,$=[`${t}const ${r} = await ${n.functionName}({`];return i&&$.push(`${t} url: ${x(i)},`),f&&$.push(`${t} query: ${x(f)},`),p&&$.push(`${t} limit: ${p},`),$.push(`${t}});`),$}function pt(s,t,r){let e=b("Create Chat");c.add(`import { ${e.functionName} } from '${e.importPath}';`);let n=s.data.config||{},o=n.message||"",i=n.system||"",f=[`${t}const ${r} = await ${e.functionName}({`,`${t} message: ${x(o)},`];return i&&f.push(`${t} system: ${x(i)},`),f.push(`${t}});`),f}function $t(s,t,r){let e=b("Send Message");c.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: ${x(o)},`,`${t} message: ${x(i)},`,`${t}});`]}function B(s,t,r,e){let o={"template-input":()=>`${r} ${e}: ${x(String(t))},`,"template-textarea":()=>`${r} ${e}: ${x(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 dt(s,t,r,e){let n=I(t);if(!n)return null;let o=b(t);c.add(`import { ${o.functionName} } from '${o.importPath}';`);let i=s.data.config||{},f=M(n.configFields),p=[];for(let h of f){let m=i[h.key];m==null||m===""||p.push(B(h.type,m,r,h.key))}let $=[];return p.length>0?($.push(`${r}const ${e} = await ${o.functionName}({`),$.push(...p),$.push(`${r}});`)):$.push(`${r}const ${e} = await ${o.functionName}({});`),$}function mt(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 f=g.has(t);function p(y){let N=Z.exec(y);if(N){let[,T,,W]=N;return`${T}${W}`}return y}function $(y){let N=Z.exec(y);if(N){let[,T,,W]=N;return`${T}void ${W}`}return y}function h(y){let N=[];for(let T of y)T.includes("await")?N.push(p(T)):T.trim().startsWith("const")&&T.includes("{")?N.push($(T)):N.push(T);return N}let m=y=>f?y:h(y);if(n==="Generate Text")i.push(...m(ut(s,r,e)));else if(n==="Generate Image")i.push(...m(lt(s,r,e)));else if(n==="Send Email")i.push(...m(st(s,r,e)));else if(n==="Send Slack Message")i.push(...m(gt(s,r,e)));else if(n==="Create Ticket")i.push(...m(rt(s,r,e)));else if(n==="Scrape"||n==="Search")i.push(...m(ft(s,r,e)));else if(n==="Create Chat")i.push(...m(pt(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 y=dt(s,n,r,e);y?i.push(...m(y)):f?(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],f=o[1],p=n?j(n):"true";if(e.push(`${r}if (${p}) {`),i){let $=F(i,`${r} `);e.push(...$)}if(f){e.push(`${r}} else {`);let $=F(f,`${r} `);e.push(...$)}e.push(`${r}}`)}return e}function yt(s,t){let r=k.get(s)||[];return{lines:z(r,t),wasSkipped:!0}}function Nt(s,t,r,e){let n=[];return s.data.config?.actionType==="Condition"?(n.push(...ht(s,t,e)),n):(n.push(...mt(s,t,e,r)),n)}function E(s,t,r){if(r.has(s))return[];r.add(s);let e=w.get(s);if(!e)return[];let n=[];if(e.data.type==="action")if(e.data.config?.actionType==="Condition")n.push(...wt(e,s,t,r));else{n.push(...Tt(e,t));let i=k.get(s)||[];i.length>0&&(n.push(""),n.push(...bt(i,t,r)))}return n}function wt(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 f=o?j(o):"true";n.push(`${r}if (${f}) {`),i[0]&&n.push(...E(i[0],`${r} `,e)),i[1]&&(n.push(`${r}} else {`),n.push(...E(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=b(r),o=Ct(s,`${t} `);c.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 bt(s,t,r){let e=s.filter(o=>!r.has(o));if(e.length===0)return[];if(e.length===1)return E(e[0],t,r);let n=[`${t}await Promise.all([`];for(let o=0;o<e.length;o++){let i=e[o],p=o===e.length-1?"":",",$=new Set(r),h=E(i,`${t} `,$);h.length>0&&(n.push(`${t} (async () => {`),n.push(...h),n.push(`${t} })()${p}`))}return n.push(`${t}]);`),n}function St(s,t,r){let e=new Set(C);e.delete(s);let n=E(s,`${t} `,e),o=r?"":",";return n.length===0?[]:[`${t} (async () => {`,...n,`${t} })()${o}`]}function z(s,t){if(s.length===0)return[];let r=s.filter(n=>!C.has(n)&&w.get(n)?.data.type==="action");if(r.length===0)return[];if(r.length===1){let n=new Set(C);return C.add(r[0]),E(r[0],t,n)}for(let n of r)C.add(n);let e=[`${t}await Promise.all([`];for(let n=0;n<r.length;n++)e.push(...St(r[n],t,n===r.length-1));return e.push(`${t}]);`),e}function xt(s,t,r){let e=I(t);if(!e)return[];let n=[];for(let o of M(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 At(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}: ${x(n)},`):typeof n=="number"||typeof n=="boolean"?r.push(`${t}${e}: ${n},`):r.push(`${t}${e}: ${JSON.stringify(n)},`));return r}function Ct(s,t){let r=s.data.config?.actionType,e=s.data.config||{},n=xt(e,r,t);return n.length>0?n:At(e,t)}function G(s,t,r){let e=k.get(s)||[],n=[...t];return t.length>0&&e.length>0&&n.push(""),n.push(...z(e,r)),n}function F(s,t=" "){if(C.has(s))return[`${t}// Already processed: ${s}`];C.add(s);let r=w.get(s);if(!r)return[];let e=P.get(s)||`${r.data.type}_${s.replace(/-/g,"_")}`,n=[];switch(r.data.type){case"trigger":{let{lines:o,wasSkipped:i}=yt(s,t);return i?o:G(s,o,t)}case"action":{let o=Nt(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 G(s,n,t)}if(D.length===0)A.push(" // No trigger nodes found");else for(let s of D){let t=F(s.id," ");A.push(...t)}return A.push("}"),{code:`${Array.from(c).join(`
2
+ `)}
3
+
4
+ ${A.join(`
5
+ `)}
6
+ `,functionName:d,imports:Array.from(c)}}function Qt(a,l,u,d={}){let{code:g}=vt(l,u,d);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
+ ${g}
14
+ `}var Zt=[{value:"string",label:"String"},{value:"number",label:"Number"},{value:"boolean",label:"Boolean"},{value:"datetime",label:"Date & Time"}],Yt={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 Vt(a,l,u,d){switch(l){case"exists":return u!=null;case"doesNotExist":return u==null;case"isEmpty":return u==null||String(u)==="";case"isNotEmpty":return u!=null&&String(u)!=="";case"isTrue":return!!u;case"isFalse":return!u}switch(a){case"string":{let g=String(u??""),c=String(d??"");switch(l){case"equals":return g===c;case"notEquals":return g!==c;case"contains":return g.includes(c);case"doesNotContain":return!g.includes(c);case"startsWith":return g.startsWith(c);case"doesNotStartWith":return!g.startsWith(c);case"endsWith":return g.endsWith(c);case"doesNotEndWith":return!g.endsWith(c);case"matchesRegex":try{return new RegExp(c).test(g)}catch{return!1}case"doesNotMatchRegex":try{return!new RegExp(c).test(g)}catch{return!1}}break}case"number":{let g=Number(u),c=Number(d);if(Number.isNaN(g)||Number.isNaN(c))return!1;switch(l){case"equals":return g===c;case"notEquals":return g!==c;case"greaterThan":return g>c;case"lessThan":return g<c;case"greaterThanOrEqual":return g>=c;case"lessThanOrEqual":return g<=c}break}case"boolean":break;case"datetime":{let g=new Date(u).getTime(),c=new Date(d).getTime();if(Number.isNaN(g)||Number.isNaN(c))return!1;switch(l){case"isBefore":return g<c;case"isAfter":return g>c;case"equals":return g===c}break}}return console.warn(`[Condition] Unknown operator "${l}" for data type "${a}"`),!1}export{Et as a,Q as b,Mt as c,_t as d,Lt as e,jt as f,Bt as g,zt as h,vt as i,Qt as j,Zt as k,Yt as l,Vt as m};
@@ -0,0 +1,42 @@
1
+ import{j as V,m as U}from"./chunk-DMHGXYVW.js";import{a as H,b as Z}from"./chunk-IEOZJAW2.js";import{b as F}from"./chunk-6UXAINJQ.js";import{l as L,m as M}from"./chunk-BNX2SV7E.js";import{r as $,t as D}from"./chunk-QRG4O4PE.js";import{k as I,o as z,p as q,q as B}from"./chunk-5J6TNMJG.js";async function le(e){let r=H();if(r.getUser)return r.getUser(e);let o=await Z.api.getSession({headers:e.headers});return o?.user?{id:o.user.id,email:o.user.email??void 0,name:o.user.name??void 0}:null}import{eq as te}from"drizzle-orm";import{readdir as oe,readFile as re}from"fs/promises";import{join as ne}from"path";import"server-only";function X(e){return{success:!0,data:e.triggerData}}async function A(e){"use step";return e._workflowComplete?(await q(e._workflowComplete),{success:!0,data:{}}):B(e,()=>Promise.resolve(X(e)))}A.maxRetries=0;var _={"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"}};function J(e,r){if(e===void 0||e==="")return;let o=/\{\{@([^:]+):([^}]+)\}\}/g,n=[...e.matchAll(o)];if(n.length===0)return e;function s(i,a){let u=i.replace(/[^a-zA-Z0-9]/g,"_"),f=r[u];if(!f)return;let w=a.indexOf(".");if(w===-1)return f.data;if(f.data===null||f.data===void 0)return;let x=a.substring(w+1).split("."),p=f.data,E=x[0];p&&typeof p=="object"&&"success"in p&&"data"in p&&E!=="success"&&E!=="data"&&E!=="error"&&!(E in p)&&(p=p.data);for(let b of x)if(p&&typeof p=="object")p=p[b];else return;return p}return n.length===1&&n[0][0]===e?s(n[0][1],n[0][2]):e.replace(o,(i,a,u)=>{let f=s(a,u);return f==null?"":typeof f=="object"?JSON.stringify(f):String(f)})}function Y(e,r){let o=e.dataType||"string",n=e.operator,s=e.leftValue,i=e.rightValue,a=J(s,r),u=J(i,r);return console.log("[Condition] Evaluating:",{dataType:o,operator:n,leftResolved:a,rightResolved:u}),{result:U(o,n,a,u),resolvedValues:{leftValue:a,rightValue:u}}}async function K(e){let{actionType:r,config:o,outputs:n,context:s}=e,i={...o,_context:s};if(r==="Condition"){let w=_.Condition,k=await w.importer(),{result:x,resolvedValues:p}=Y(o,n);return console.log("[Condition] Final result:",x),await k[w.stepFunction]({condition:x,dataType:o.dataType,operator:o.operator,leftValue:p.leftValue,rightValue:p.rightValue,_context:s})}let a=_[r];if(a){let k=(await a.importer())[a.stepFunction];return await k(i)}let{getStepImporter:u}=await import("virtual:workflow-builder-step-registry"),f=u(r);if(f){let k=(await f.importer())[f.stepFunction];return k?await k(i):{success:!1,error:`Step function "${f.stepFunction}" not found in module for action "${r}". Check that the plugin exports the correct function name.`}}return{success:!1,error:`Unknown action type: "${r}". This action is not registered in the plugin system. Available system actions: ${Object.keys(_).join(", ")}.`}}function ee(e,r){let o={};for(let[n,s]of Object.entries(e))if(typeof s=="string"){let i=s,a=/\{\{@([^:]+):([^}]+)\}\}/g;i=i.replace(a,(u,f,w)=>{let k=f.replace(/[^a-zA-Z0-9]/g,"_"),x=r[k];if(!x)return u;let p=w.indexOf(".");if(p===-1){let l=x.data;return l==null?"":typeof l=="object"?JSON.stringify(l):String(l)}if(x.data===null||x.data===void 0)return"";let b=w.substring(p+1).split("."),g=x.data,t=b[0];g&&typeof g=="object"&&"success"in g&&"data"in g&&t!=="success"&&t!=="data"&&t!=="error"&&!(t in g)&&(g=g.data);for(let l of b)if(g&&typeof g=="object")g=g[l];else return"";return g==null?"":typeof g=="object"?JSON.stringify(g):String(g)}),o[n]=i}else o[n]=s;return o}async function G(e){"use workflow";console.log("[Workflow Executor] Starting workflow execution");let{nodes:r,edges:o,triggerInput:n={},executionId:s,workflowId:i}=e;console.log("[Workflow Executor] Input:",{nodeCount:r.length,edgeCount:o.length,hasExecutionId:!!s,workflowId:i||"none"});let a={},u={},f=new Map(r.map(t=>[t.id,t])),w=new Map,k=new Map;for(let t of o){let l=w.get(t.source)||[];l.push(t.target),w.set(t.source,l);let c=k.get(t.target)||[];c.push(t.source),k.set(t.target,c)}let x=new Set(o.map(t=>t.target)),p=r.filter(t=>t.data.type==="trigger"&&!x.has(t.id));console.log("[Workflow Executor] Found",p.length,"trigger nodes");let{getActionLabel:E}=await import("virtual:workflow-builder-step-registry");function b(t){if(t.data.label)return t.data.label;if(t.data.type==="action"){let l=t.data.config?.actionType;if(l){let c=E(l);if(c)return c}return"Action"}return t.data.type==="trigger"?t.data.config?.triggerType||"Trigger":t.data.type}async function g(t,l=new Set){if(console.log("[Workflow Executor] Executing node:",t),l.has(t)){console.log("[Workflow Executor] Node already visited, skipping");return}l.add(t);let c=f.get(t);if(!c){console.log("[Workflow Executor] Node not found:",t);return}if(c.data.enabled===!1){console.log("[Workflow Executor] Skipping disabled node:",t);let d=t.replace(/[^a-zA-Z0-9]/g,"_");a[d]={label:c.data.label||t,data:null};let P=w.get(t)||[];await Promise.all(P.map(h=>g(h,l)));return}try{let d;if(c.data.type==="trigger"){console.log("[Workflow Executor] Executing trigger node");let h=c.data.config||{},m=h.triggerType,y={triggered:!0,timestamp:Date.now()};if(m==="Webhook"&&h.webhookMockRequest&&(!n||Object.keys(n).length===0))try{let N=JSON.parse(h.webhookMockRequest);y={...y,...N},console.log("[Workflow Executor] Using webhook mock request data:",N)}catch(N){console.error("[Workflow Executor] Failed to parse webhook mock request:",N)}else n&&Object.keys(n).length>0&&(y={...y,...n});let S={executionId:s,nodeId:c.id,nodeName:b(c),nodeType:c.data.type},T=await A({triggerData:y,_context:S});d={success:T.success,data:T.data}}else if(c.data.type==="action"){let h=c.data.config||{},m=h.actionType;if(console.log("[Workflow Executor] Executing action node:",m),!m){d={success:!1,error:`Action node "${c.data.label||c.id}" has no action type configured`},u[t]=d;return}let y=ee(h,a),S={executionId:s,nodeId:c.id,nodeName:b(c),nodeType:m},T={},N=k.get(t)||[];for(let C of N){let O=C.replace(/[^a-zA-Z0-9]/g,"_"),v=a[O];if(v?.data&&typeof v.data=="object"){let W=v.data;"success"in W&&"data"in W&&W.data&&typeof W.data=="object"&&(W=W.data);for(let[j,Q]of Object.entries(W))j!=="success"&&j!=="error"&&(T[j]=Q)}}console.log("[Workflow Executor] Calling executeActionStep");let R=await K({actionType:m,config:{...T,...y},outputs:a,context:S});if(console.log("[Workflow Executor] Step result received:",{hasResult:!!R,resultType:typeof R}),R&&typeof R=="object"&&"success"in R&&R.success===!1){let C=R,O=typeof C.error=="string"?C.error:C.error?.message||`Step "${m}" in node "${c.data.label||c.id}" failed without a specific error message.`;console.error(`[Workflow Executor] Step "${m}" failed:`,O),d={success:!1,error:O}}else d={success:!0,data:R}}else console.log("[Workflow Executor] Unknown node type:",c.data.type),d={success:!1,error:`Unknown node type "${c.data.type}" in node "${c.data.label||c.id}". Expected "trigger" or "action".`};u[t]=d;let P=t.replace(/[^a-zA-Z0-9]/g,"_");if(a[P]={label:c.data.label||t,data:d.data},console.log("[Workflow Executor] Node execution completed:",{nodeId:t,success:d.success}),d.success)if(c.data.type==="action"&&c.data.config?.actionType==="Condition"){let m=d.data?.condition;if(console.log("[Workflow Executor] Condition node result:",m),m===!0){let y=w.get(t)||[];console.log("[Workflow Executor] Condition is true, executing",y.length,"next nodes in parallel"),await Promise.all(y.map(S=>g(S,l)))}else console.log("[Workflow Executor] Condition is false, skipping next nodes")}else{let m=w.get(t)||[];console.log("[Workflow Executor] Executing",m.length,"next nodes in parallel"),await Promise.all(m.map(y=>g(y,l)))}}catch(d){console.error("[Workflow Executor] Error executing node:",t,d);let h={success:!1,error:await F(d)};u[t]=h}}try{console.log("[Workflow Executor] Starting execution from trigger nodes");let t=Date.now();await Promise.all(p.map(d=>g(d.id)));let l=Object.values(u).every(d=>d.success),c=Date.now()-t;if(console.log("[Workflow Executor] Workflow execution completed:",{success:l,resultCount:Object.keys(u).length,duration:c}),s)try{await A({triggerData:{},_workflowComplete:{executionId:s,status:l?"success":"error",output:Object.values(u).at(-1)?.data,error:Object.values(u).find(d=>!d.success)?.error,startTime:t}}),console.log("[Workflow Executor] Updated execution record")}catch(d){console.error("[Workflow Executor] Failed to update execution record:",d)}return{success:l,results:u,outputs:a}}catch(t){console.error("[Workflow Executor] Fatal error during workflow execution:",t);let l=await F(t);if(s)try{await A({triggerData:{},_workflowComplete:{executionId:s,status:"error",error:l,startTime:Date.now()}})}catch(c){console.error("[Workflow Executor] Failed to log error:",c)}return{success:!1,results:u,outputs:a,error:l}}}var Ce={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization"};function Ae(e){let o=new URL(e.url).pathname,n="/api/workflow-builder/",s=o.indexOf(n);if(s===-1){let a=o.indexOf("/api/");return a===-1?[]:o.slice(a+5).split("/").filter(Boolean)}return o.slice(s+n.length).split("/").filter(Boolean)}function Pe(e,r){return new Request(r,{method:e.method,headers:e.headers,body:e.body,duplex:"half"})}async function Oe(e,r,o,n,s){try{await G({nodes:o,edges:n,triggerInput:s,executionId:e,workflowId:r})}catch(i){console.error("[Workflow Execute] Error during execution:",i),await z.update(I).set({status:"error",error:i instanceof Error?i.message:"Unknown error",completedAt:new Date}).where(te(I.id,e))}}function ve(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 je(e){return e.map(r=>{let o={...r};if(o.data&&typeof o.data=="object"&&o.data!==null){let n={...o.data};if(n.config&&typeof n.config=="object"&&n.config!==null){let{integrationId:s,...i}=n.config;n.config=i}o.data=n}return o})}async function se(e,r=e){let o={},n=await oe(e,{withFileTypes:!0});for(let s of n){let i=ne(e,s.name);if(s.isDirectory()){let a=await se(i,r);Object.assign(o,a)}else if(s.isFile()){let a=await re(i,"utf-8"),u=i.substring(r.length+1);o[u]=a}}return o}function Fe(e){let r={},n=`${e.name.replace(L,"").split(M).map((a,u)=>u===0?a.toLowerCase():a.charAt(0).toUpperCase()+a.slice(1).toLowerCase()).join("")||"execute"}Workflow`,s=V(e.name,e.nodes,e.edges,{functionName:n}),i=ie(e.name);return r[`workflows/${i}.ts`]=s,r[`app/api/workflows/${i}/route.ts`]=`import { start } from 'workflow/api';
2
+ import { ${n} } from '@/workflows/${i}';
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/${i}" className="text-blue-600 hover:underline">
34
+ /api/workflows/${i}
35
+ </a>
36
+ </li>
37
+ </ul>
38
+ </main>
39
+ );
40
+ }
41
+ `,r}function Ie(e){let r=e.filter(o=>o.data.type==="action").map(o=>o.data.config?.actionType).filter(Boolean);return $(r)}function _e(){let e=["# Add your environment variables here"];e.push(""),e.push("# For database integrations"),e.push("DATABASE_URL=your_database_url");let r=D(),o={};for(let n of r){let s=n.name.split("_")[0];o[s]||(o[s]=[]),o[s].push(n)}for(let[n,s]of Object.entries(o)){e.push(`# For ${n.charAt(0)+n.slice(1).toLowerCase()} integration`);for(let i of s)e.push(`${i.name}=your_${i.name.toLowerCase()}`);e.push("")}return e.join(`
42
+ `)}function ie(e){return e.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}export{le as a,Ce as b,Ae as c,Pe as d,Oe as e,ve as f,je as g,se as h,Fe as i,Ie as j,_e as k,ie as l};
@@ -0,0 +1 @@
1
+ import{b as p,c as h,d as f,e as l,f as m,g as A,h as g,i as r,j as i,k as n,l as d,n as _,o as s}from"./chunk-5J6TNMJG.js";import{betterAuth as O}from"better-auth";import{drizzleAdapter as v}from"better-auth/adapters/drizzle";import{anonymous as B,mcp as w}from"better-auth/plugins";import{eq as u}from"drizzle-orm";function U(){let o=process.env.NWB_AUTH_OPTIONS?JSON.parse(process.env.NWB_AUTH_OPTIONS):void 0;return{hasRealProviders:Object.keys(o?.socialProviders??{})?.length>0,authOptions:o}}var L={user:p,session:h,account:f,verification:l,oauthApplication:m,oauthAccessToken:A,oauthConsent:g,workflows:r,workflowExecutions:n,workflowExecutionLogs:d,workflowExecutionsRelations:_};function P(){return process.env.BETTER_AUTH_URL?process.env.BETTER_AUTH_URL:process.env.NEXT_PUBLIC_APP_URL?process.env.NEXT_PUBLIC_APP_URL:process.env.VERCEL_URL?`https://${process.env.VERCEL_URL}`:"http://localhost:3000"}function R(){let o=U(),E=[...process.env.NWB_ANONYMOUS_AUTH!=="false"?[B({async onLinkAccount(a){let t=a.anonymousUser.user.id,e=a.newUser.user.id;console.log(`[Anonymous Migration] Migrating from user ${t} to ${e}`);try{await s.update(r).set({userId:e}).where(u(r.userId,t)),await s.update(n).set({userId:e}).where(u(n.userId,t)),await s.update(i).set({userId:e}).where(u(i.userId,t)),console.log(`[Anonymous Migration] Successfully migrated data from ${t} to ${e}`)}catch(c){throw console.error("[Anonymous Migration] Error migrating user data:",c),c}}})]:[],...process.env.NWB_MCP_ENABLED==="true"?[w({loginPage:process.env.NWB_MCP_LOGIN_PAGE||"/auth/sign-in"})]:[]];return O({baseURL:P(),database:v(s,{provider:"pg",schema:L}),...o.authOptions,plugins:[...E,...o.authOptions?.plugins??[]]})}var H=R();export{U as a,H as b};
@@ -0,0 +1 @@
1
+ import{j as r,o as g}from"./chunk-5J6TNMJG.js";import"server-only";import{and as c,eq as s,inArray as m}from"drizzle-orm";import{createCipheriv as h,createDecipheriv as w,randomBytes as x}from"crypto";var p="aes-256-gcm",v=16,u="INTEGRATION_ENCRYPTION_KEY";function I(){let t=process.env[u];if(!t)throw new Error(`${u} environment variable is required for encrypting integration credentials`);if(t.length!==64)throw new Error(`${u} must be a 64-character hex string (32 bytes)`);return Buffer.from(t,"hex")}function N(t){let n=I(),e=x(v),i=h(p,n,e),o=i.update(t,"utf8","hex");o+=i.final("hex");let a=i.getAuthTag();return`${e.toString("hex")}:${a.toString("hex")}:${o}`}function C(t){let n=I(),e=t.split(":");if(e.length!==3)throw new Error("Invalid encrypted data format");let i=Buffer.from(e[0],"hex"),o=Buffer.from(e[1],"hex"),a=e[2],d=w(p,n,i);d.setAuthTag(o);let l=d.update(a,"hex","utf8");return l+=d.final("utf8"),l}function y(t){return N(JSON.stringify(t))}function f(t){try{let n=C(t);return JSON.parse(n)}catch(n){return console.error("Failed to decrypt integration config:",n),{}}}async function b(t,n){let e=[s(r.userId,t)];return n&&e.push(s(r.type,n)),(await g.select().from(r).where(c(...e))).map(o=>({...o,config:f(o.config)}))}async function B(t,n){let e=await g.select().from(r).where(c(s(r.id,t),s(r.userId,n))).limit(1);return e.length===0?null:{...e[0],config:f(e[0].config)}}async function O(t){let n=await g.select().from(r).where(s(r.id,t)).limit(1);return n.length===0?null:{...n[0],config:f(n[0].config)}}async function R(t,n,e,i){let o=y(i),[a]=await g.insert(r).values({userId:t,name:n,type:e,config:o}).returning();return{...a,config:i}}async function S(t,n,e){let i={updatedAt:new Date};e.name!==void 0&&(i.name=e.name),e.config!==void 0&&(i.config=y(e.config));let[o]=await g.update(r).set(i).where(c(s(r.id,t),s(r.userId,n))).returning();return o?{...o,config:f(o.config)}:null}async function V(t,n){return(await g.delete(r).where(c(s(r.id,t),s(r.userId,n))).returning()).length>0}function T(t){let n=[];for(let e of t){let i=e.data?.config?.integrationId;i&&typeof i=="string"&&n.push(i)}return[...new Set(n)]}async function _(t,n){let e=T(t);if(e.length===0)return{valid:!0};let o=(await g.select({id:r.id,userId:r.userId}).from(r).where(m(r.id,e))).filter(a=>a.userId!==n).map(a=>a.id);return o.length>0?{valid:!1,invalidIds:o}:{valid:!0}}export{N as a,C as b,b as c,B as d,O as e,R as f,S as g,V as h,_ as i};