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.
- package/CHANGELOG.md +156 -0
- package/README.md +1 -1
- package/dist/chunk-5J6TNMJG.js +1 -0
- package/dist/chunk-6UXAINJQ.js +1 -0
- package/dist/chunk-7WFHHPX4.js +1 -0
- package/dist/chunk-BNX2SV7E.js +1 -0
- package/dist/chunk-CYVALTSI.js +218 -0
- package/dist/chunk-DMHGXYVW.js +14 -0
- package/dist/chunk-HB2H2PVI.js +42 -0
- package/dist/chunk-IEOZJAW2.js +1 -0
- package/dist/chunk-KFTXS23Q.js +1 -0
- package/dist/chunk-NI6U7PHC.js +76 -0
- package/dist/chunk-PRVESNIO.js +1 -0
- package/dist/chunk-QRG4O4PE.js +2 -0
- package/dist/chunk-R5GS6TJS.js +1 -0
- package/dist/client/index.js +160 -13725
- package/dist/condition-CFAA7UDI.js +1 -0
- package/dist/database-query-OHFQUPLV.js +1 -0
- package/dist/handler-NWAMWKXW.js +1 -0
- package/dist/http-request-EHJHOTNA.js +1 -0
- package/dist/loop-5LPVY452.js +1 -0
- package/dist/merge-HYBHX22D.js +1 -0
- package/dist/next/index.d.ts +9 -0
- package/dist/next/index.js +1 -84
- package/dist/plugins/index.js +1 -54
- package/dist/server/api/index.d.ts +30 -1
- package/dist/server/api/index.js +18 -2360
- package/dist/server/index.js +1 -60
- package/dist/switch-ZPVREROE.js +1 -0
- package/drizzle.config.ts +9 -0
- package/package.json +27 -2
- package/src/plugins/types.ts +31 -0
- package/src/server/db/schema.ts +228 -0
- package/src/server/lib/utils/id.ts +26 -0
- package/dist/chunk-3XFDIK7H.js +0 -251
- package/dist/chunk-5H76TY4T.js +0 -51
- package/dist/chunk-5YYA34YV.js +0 -96
- package/dist/chunk-C7GDB4KC.js +0 -550
- package/dist/chunk-CKE7ETZL.js +0 -169
- package/dist/chunk-EMCA7GLF.js +0 -1305
- package/dist/chunk-J72T2LRL.js +0 -66
- package/dist/chunk-JUV5RBYM.js +0 -105
- package/dist/chunk-O3I2INCD.js +0 -71
- package/dist/chunk-OQHML4II.js +0 -36
- package/dist/chunk-PEVVELQ6.js +0 -438
- package/dist/condition-VHC4KYLI.js +0 -29
- package/dist/database-query-BYPF5CDB.js +0 -99
- package/dist/http-request-4OT32ZXA.js +0 -76
- package/dist/loop-S5H7DSCB.js +0 -47
- package/dist/merge-X5JAIZSZ.js +0 -107
- package/dist/style-prefixed.css +0 -5167
- 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](
|
|
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};
|