next-workflow-builder 0.4.7 → 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 -13668
- 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 -2648
- 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-J72T2LRL.js +0 -66
- package/dist/chunk-JUV5RBYM.js +0 -105
- package/dist/chunk-MIBRBQIJ.js +0 -1162
- 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/dist/server/index.js
CHANGED
|
@@ -1,60 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
generateWorkflowMetadata
|
|
3
|
-
} from "../chunk-J72T2LRL.js";
|
|
4
|
-
import {
|
|
5
|
-
discoverPlugins
|
|
6
|
-
} from "../chunk-C7GDB4KC.js";
|
|
7
|
-
import {
|
|
8
|
-
auth
|
|
9
|
-
} from "../chunk-JUV5RBYM.js";
|
|
10
|
-
import {
|
|
11
|
-
getErrorMessageAsync
|
|
12
|
-
} from "../chunk-5YYA34YV.js";
|
|
13
|
-
import "../chunk-OQHML4II.js";
|
|
14
|
-
import {
|
|
15
|
-
fetchCredentials
|
|
16
|
-
} from "../chunk-5H76TY4T.js";
|
|
17
|
-
import {
|
|
18
|
-
decrypt,
|
|
19
|
-
encrypt
|
|
20
|
-
} from "../chunk-CKE7ETZL.js";
|
|
21
|
-
import "../chunk-3XFDIK7H.js";
|
|
22
|
-
import {
|
|
23
|
-
getErrorMessage
|
|
24
|
-
} from "../chunk-O3I2INCD.js";
|
|
25
|
-
import {
|
|
26
|
-
accounts,
|
|
27
|
-
apiKeys,
|
|
28
|
-
db,
|
|
29
|
-
generateId,
|
|
30
|
-
integrations,
|
|
31
|
-
sessions,
|
|
32
|
-
users,
|
|
33
|
-
verifications,
|
|
34
|
-
withStepLogging,
|
|
35
|
-
workflowExecutionLogs,
|
|
36
|
-
workflowExecutions,
|
|
37
|
-
workflowExecutionsRelations
|
|
38
|
-
} from "../chunk-PEVVELQ6.js";
|
|
39
|
-
export {
|
|
40
|
-
accounts,
|
|
41
|
-
apiKeys,
|
|
42
|
-
auth,
|
|
43
|
-
db,
|
|
44
|
-
decrypt,
|
|
45
|
-
discoverPlugins,
|
|
46
|
-
encrypt,
|
|
47
|
-
fetchCredentials,
|
|
48
|
-
generateId,
|
|
49
|
-
generateWorkflowMetadata,
|
|
50
|
-
getErrorMessage,
|
|
51
|
-
getErrorMessageAsync,
|
|
52
|
-
integrations,
|
|
53
|
-
sessions,
|
|
54
|
-
users,
|
|
55
|
-
verifications,
|
|
56
|
-
withStepLogging,
|
|
57
|
-
workflowExecutionLogs,
|
|
58
|
-
workflowExecutions,
|
|
59
|
-
workflowExecutionsRelations
|
|
60
|
-
};
|
|
1
|
+
import{a as q}from"../chunk-R5GS6TJS.js";import{a as b}from"../chunk-CYVALTSI.js";import{b as t}from"../chunk-IEOZJAW2.js";import{b as a}from"../chunk-6UXAINJQ.js";import"../chunk-BNX2SV7E.js";import{a as p}from"../chunk-PRVESNIO.js";import{a as n,b as o}from"../chunk-KFTXS23Q.js";import"../chunk-QRG4O4PE.js";import{a as r}from"../chunk-7WFHHPX4.js";import{a as c,b as d,c as e,d as f,e as g,j as h,k as i,l as j,m as k,n as l,o as m,q as s}from"../chunk-5J6TNMJG.js";export{f as accounts,k as apiKeys,t as auth,m as db,o as decrypt,b as discoverPlugins,n as encrypt,p as fetchCredentials,c as generateId,q as generateWorkflowMetadata,r as getErrorMessage,a as getErrorMessageAsync,h as integrations,e as sessions,d as users,g as verifications,s as withStepLogging,j as workflowExecutionLogs,i as workflowExecutions,l as workflowExecutionsRelations};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./chunk-R5GS6TJS.js";import"./chunk-CYVALTSI.js";import"./chunk-IEOZJAW2.js";import"./chunk-6UXAINJQ.js";import"./chunk-BNX2SV7E.js";import"./chunk-PRVESNIO.js";import"./chunk-KFTXS23Q.js";import"./chunk-QRG4O4PE.js";import"./chunk-7WFHHPX4.js";import{q as i}from"./chunk-5J6TNMJG.js";import"server-only";function s(t){let u=[];for(let e=0;e<4;e++){let o=t[`routeName${e}`],n=t[`routeCondition${e}`],r=t[`routeCaseValue${e}`];u.push({name:o||`Route ${e+1}`,condition:n,caseValue:r})}return u}function a(t){let u=t.mode||"rules",e=s(t);if(u==="rules"){for(let o=0;o<e.length;o++)if(e[o].condition===!0)return{matchedRouteIndex:o,matchedRouteName:e[o].name,isDefault:!1}}else{let o=String(t.switchValue??"");for(let n=0;n<e.length;n++)if(e[n].caseValue!==void 0&&String(e[n].caseValue)===o)return{matchedRouteIndex:n,matchedRouteName:e[n].name,isDefault:!1}}return{matchedRouteIndex:-1,matchedRouteName:"Default",isDefault:!0}}async function c(t){"use step";return i(t,()=>Promise.resolve(a(t)))}c.maxRetries=0;export{c as switchStep};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** @type {import("drizzle-kit").Config} */
|
|
2
|
+
export default {
|
|
3
|
+
schema: "node_modules/next-workflow-builder/src/server/db/schema.ts",
|
|
4
|
+
out: "./drizzle",
|
|
5
|
+
dialect: "postgresql",
|
|
6
|
+
dbCredentials: {
|
|
7
|
+
url: process.env.DATABASE_URL || "postgres://localhost:5432/workflow",
|
|
8
|
+
},
|
|
9
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-workflow-builder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Next.js plugin for Workflow Builder",
|
|
6
6
|
"repository": "https://github.com/emulienfou/next-workflow-builder",
|
|
@@ -46,12 +46,37 @@
|
|
|
46
46
|
"bin": {
|
|
47
47
|
"nwb": "src/scripts/nwb.ts"
|
|
48
48
|
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"nextjs",
|
|
51
|
+
"workflow",
|
|
52
|
+
"workflow-builder",
|
|
53
|
+
"react",
|
|
54
|
+
"drag-and-drop",
|
|
55
|
+
"react-flow",
|
|
56
|
+
"automation",
|
|
57
|
+
"mcp",
|
|
58
|
+
"model-context-protocol",
|
|
59
|
+
"ai",
|
|
60
|
+
"plugins",
|
|
61
|
+
"better-auth",
|
|
62
|
+
"drizzle",
|
|
63
|
+
"visual-editor",
|
|
64
|
+
"low-code",
|
|
65
|
+
"no-code"
|
|
66
|
+
],
|
|
49
67
|
"files": [
|
|
50
|
-
"dist"
|
|
68
|
+
"dist",
|
|
69
|
+
"drizzle.config.ts",
|
|
70
|
+
"src/server/db/schema.ts",
|
|
71
|
+
"src/server/lib/utils/id.ts",
|
|
72
|
+
"src/plugins/types.ts",
|
|
73
|
+
"README.md",
|
|
74
|
+
"CHANGELOG.md"
|
|
51
75
|
],
|
|
52
76
|
"dependencies": {
|
|
53
77
|
"@daveyplate/better-auth-ui": "^3.3.15",
|
|
54
78
|
"@inquirer/prompts": "^8.0.1",
|
|
79
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
55
80
|
"@monaco-editor/react": "^4.7.0",
|
|
56
81
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
57
82
|
"@radix-ui/react-collapsible": "^1.1.12",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Integration type union - plugins + system integrations
|
|
2
|
+
export type IntegrationType =
|
|
3
|
+
| "database"
|
|
4
|
+
| "loop"
|
|
5
|
+
| "switch"
|
|
6
|
+
| string;
|
|
7
|
+
|
|
8
|
+
// Generic config type - plugins define their own keys via formFields[].configKey
|
|
9
|
+
export type IntegrationConfig = Record<string, string | undefined>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Output Display Config (serializable subset for built-in types only)
|
|
13
|
+
*/
|
|
14
|
+
export type SerializableOutputDisplayConfig = {
|
|
15
|
+
type: "image" | "video" | "url";
|
|
16
|
+
field: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/** Analysis result type for step file parsing */
|
|
20
|
+
export type StepFileAnalysis = {
|
|
21
|
+
hasExportCore: boolean;
|
|
22
|
+
integrationType: string | null;
|
|
23
|
+
coreFunction: {
|
|
24
|
+
name: string;
|
|
25
|
+
params: string;
|
|
26
|
+
returnType: string;
|
|
27
|
+
body: string;
|
|
28
|
+
} | null;
|
|
29
|
+
inputTypes: string[];
|
|
30
|
+
imports: string[];
|
|
31
|
+
};
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { relations } from "drizzle-orm";
|
|
2
|
+
import { boolean, jsonb, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
|
3
|
+
import { generateId } from "../lib/utils/id";
|
|
4
|
+
import type { IntegrationType } from "../../plugins/types";
|
|
5
|
+
|
|
6
|
+
// Better Auth tables
|
|
7
|
+
export const users = pgTable("users", {
|
|
8
|
+
id: text("id").primaryKey(),
|
|
9
|
+
name: text("name"),
|
|
10
|
+
email: text("email").unique(),
|
|
11
|
+
emailVerified: boolean("email_verified").notNull().default(false),
|
|
12
|
+
image: text("image"),
|
|
13
|
+
createdAt: timestamp("created_at").notNull(),
|
|
14
|
+
updatedAt: timestamp("updated_at").notNull(),
|
|
15
|
+
// Anonymous user tracking
|
|
16
|
+
isAnonymous: boolean("is_anonymous").default(false),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export const sessions = pgTable("sessions", {
|
|
20
|
+
id: text("id").primaryKey(),
|
|
21
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
22
|
+
token: text("token").notNull().unique(),
|
|
23
|
+
createdAt: timestamp("created_at").notNull(),
|
|
24
|
+
updatedAt: timestamp("updated_at").notNull(),
|
|
25
|
+
ipAddress: text("ip_address"),
|
|
26
|
+
userAgent: text("user_agent"),
|
|
27
|
+
userId: text("user_id")
|
|
28
|
+
.notNull()
|
|
29
|
+
.references(() => users.id),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const accounts = pgTable("accounts", {
|
|
33
|
+
id: text("id").primaryKey(),
|
|
34
|
+
accountId: text("account_id").notNull(),
|
|
35
|
+
providerId: text("provider_id").notNull(),
|
|
36
|
+
userId: text("user_id")
|
|
37
|
+
.notNull()
|
|
38
|
+
.references(() => users.id),
|
|
39
|
+
accessToken: text("access_token"),
|
|
40
|
+
refreshToken: text("refresh_token"),
|
|
41
|
+
idToken: text("id_token"),
|
|
42
|
+
accessTokenExpiresAt: timestamp("access_token_expires_at"),
|
|
43
|
+
refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
|
|
44
|
+
scope: text("scope"),
|
|
45
|
+
password: text("password"),
|
|
46
|
+
createdAt: timestamp("created_at").notNull(),
|
|
47
|
+
updatedAt: timestamp("updated_at").notNull(),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const verifications = pgTable("verifications", {
|
|
51
|
+
id: text("id").primaryKey(),
|
|
52
|
+
identifier: text("identifier").notNull(),
|
|
53
|
+
value: text("value").notNull(),
|
|
54
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
55
|
+
createdAt: timestamp("created_at"),
|
|
56
|
+
updatedAt: timestamp("updated_at"),
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Better Auth MCP OAuth tables
|
|
60
|
+
export const oauthApplication = pgTable("oauth_application", {
|
|
61
|
+
id: text("id").primaryKey(),
|
|
62
|
+
name: text("name"),
|
|
63
|
+
icon: text("icon"),
|
|
64
|
+
metadata: text("metadata"),
|
|
65
|
+
clientId: text("client_id").notNull().unique(),
|
|
66
|
+
clientSecret: text("client_secret"),
|
|
67
|
+
redirectUrls: text("redirect_urls").notNull(),
|
|
68
|
+
type: text("type").notNull(),
|
|
69
|
+
disabled: boolean("disabled").default(false),
|
|
70
|
+
authenticationScheme: text("authentication_scheme"),
|
|
71
|
+
userId: text("user_id").references(() => users.id, { onDelete: "cascade" }),
|
|
72
|
+
createdAt: timestamp("created_at").notNull(),
|
|
73
|
+
updatedAt: timestamp("updated_at").notNull(),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export const oauthAccessToken = pgTable("oauth_access_token", {
|
|
77
|
+
id: text("id").primaryKey(),
|
|
78
|
+
accessToken: text("access_token").notNull().unique(),
|
|
79
|
+
refreshToken: text("refresh_token").notNull().unique(),
|
|
80
|
+
accessTokenExpiresAt: timestamp("access_token_expires_at").notNull(),
|
|
81
|
+
refreshTokenExpiresAt: timestamp("refresh_token_expires_at").notNull(),
|
|
82
|
+
clientId: text("client_id").notNull().references(() => oauthApplication.clientId, { onDelete: "cascade" }),
|
|
83
|
+
userId: text("user_id").references(() => users.id, { onDelete: "cascade" }),
|
|
84
|
+
scopes: text("scopes").notNull(),
|
|
85
|
+
createdAt: timestamp("created_at").notNull(),
|
|
86
|
+
updatedAt: timestamp("updated_at").notNull(),
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
export const oauthConsent = pgTable("oauth_consent", {
|
|
90
|
+
id: text("id").primaryKey(),
|
|
91
|
+
clientId: text("client_id").notNull().references(() => oauthApplication.clientId, { onDelete: "cascade" }),
|
|
92
|
+
userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
93
|
+
scopes: text("scopes").notNull(),
|
|
94
|
+
createdAt: timestamp("created_at").notNull(),
|
|
95
|
+
updatedAt: timestamp("updated_at").notNull(),
|
|
96
|
+
consentGiven: boolean("consent_given").notNull().default(false),
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Workflow visibility type
|
|
100
|
+
export type WorkflowVisibility = "private" | "public";
|
|
101
|
+
|
|
102
|
+
// Workflows table with user association
|
|
103
|
+
export const workflows = pgTable("workflows", {
|
|
104
|
+
id: text("id")
|
|
105
|
+
.primaryKey()
|
|
106
|
+
.$defaultFn(() => generateId()),
|
|
107
|
+
name: text("name").notNull(),
|
|
108
|
+
description: text("description"),
|
|
109
|
+
userId: text("user_id")
|
|
110
|
+
.notNull()
|
|
111
|
+
.references(() => users.id),
|
|
112
|
+
// biome-ignore lint/suspicious/noExplicitAny: JSONB type - structure validated at application level
|
|
113
|
+
nodes: jsonb("nodes").notNull().$type<any[]>(),
|
|
114
|
+
// biome-ignore lint/suspicious/noExplicitAny: JSONB type - structure validated at application level
|
|
115
|
+
edges: jsonb("edges").notNull().$type<any[]>(),
|
|
116
|
+
visibility: text("visibility")
|
|
117
|
+
.notNull()
|
|
118
|
+
.default("private")
|
|
119
|
+
.$type<WorkflowVisibility>(),
|
|
120
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
121
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Integrations table for storing user credentials
|
|
125
|
+
export const integrations = pgTable("integrations", {
|
|
126
|
+
id: text("id")
|
|
127
|
+
.primaryKey()
|
|
128
|
+
.$defaultFn(() => generateId()),
|
|
129
|
+
userId: text("user_id")
|
|
130
|
+
.notNull()
|
|
131
|
+
.references(() => users.id),
|
|
132
|
+
name: text("name").notNull(),
|
|
133
|
+
type: text("type").notNull().$type<IntegrationType>(),
|
|
134
|
+
// biome-ignore lint/suspicious/noExplicitAny: JSONB type - encrypted credentials stored as JSON
|
|
135
|
+
config: jsonb("config").notNull().$type<any>(),
|
|
136
|
+
// Whether this integration was created via OAuth (managed by app) vs manual entry
|
|
137
|
+
isManaged: boolean("is_managed").default(false),
|
|
138
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
139
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Workflow executions table to track workflow runs
|
|
143
|
+
export const workflowExecutions = pgTable("workflow_executions", {
|
|
144
|
+
id: text("id")
|
|
145
|
+
.primaryKey()
|
|
146
|
+
.$defaultFn(() => generateId()),
|
|
147
|
+
workflowId: text("workflow_id")
|
|
148
|
+
.notNull()
|
|
149
|
+
.references(() => workflows.id),
|
|
150
|
+
userId: text("user_id")
|
|
151
|
+
.notNull()
|
|
152
|
+
.references(() => users.id),
|
|
153
|
+
status: text("status")
|
|
154
|
+
.notNull()
|
|
155
|
+
.$type<"pending" | "running" | "success" | "error" | "cancelled">(),
|
|
156
|
+
// biome-ignore lint/suspicious/noExplicitAny: JSONB type - structure validated at application level
|
|
157
|
+
input: jsonb("input").$type<Record<string, any>>(),
|
|
158
|
+
// biome-ignore lint/suspicious/noExplicitAny: JSONB type - structure validated at application level
|
|
159
|
+
output: jsonb("output").$type<any>(),
|
|
160
|
+
error: text("error"),
|
|
161
|
+
startedAt: timestamp("started_at").notNull().defaultNow(),
|
|
162
|
+
completedAt: timestamp("completed_at"),
|
|
163
|
+
duration: text("duration"), // Duration in milliseconds
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Workflow execution logs to track individual node executions
|
|
167
|
+
export const workflowExecutionLogs = pgTable("workflow_execution_logs", {
|
|
168
|
+
id: text("id")
|
|
169
|
+
.primaryKey()
|
|
170
|
+
.$defaultFn(() => generateId()),
|
|
171
|
+
executionId: text("execution_id")
|
|
172
|
+
.notNull()
|
|
173
|
+
.references(() => workflowExecutions.id),
|
|
174
|
+
nodeId: text("node_id").notNull(),
|
|
175
|
+
nodeName: text("node_name").notNull(),
|
|
176
|
+
nodeType: text("node_type").notNull(),
|
|
177
|
+
status: text("status")
|
|
178
|
+
.notNull()
|
|
179
|
+
.$type<"pending" | "running" | "success" | "error">(),
|
|
180
|
+
// biome-ignore lint/suspicious/noExplicitAny: JSONB type - structure validated at application level
|
|
181
|
+
input: jsonb("input").$type<any>(),
|
|
182
|
+
// biome-ignore lint/suspicious/noExplicitAny: JSONB type - structure validated at application level
|
|
183
|
+
output: jsonb("output").$type<any>(),
|
|
184
|
+
error: text("error"),
|
|
185
|
+
startedAt: timestamp("started_at").notNull().defaultNow(),
|
|
186
|
+
completedAt: timestamp("completed_at"),
|
|
187
|
+
duration: text("duration"), // Duration in milliseconds
|
|
188
|
+
timestamp: timestamp("timestamp").notNull().defaultNow(),
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// API Keys table for webhook authentication
|
|
192
|
+
export const apiKeys = pgTable("api_keys", {
|
|
193
|
+
id: text("id")
|
|
194
|
+
.primaryKey()
|
|
195
|
+
.$defaultFn(() => generateId()),
|
|
196
|
+
userId: text("user_id")
|
|
197
|
+
.notNull()
|
|
198
|
+
.references(() => users.id),
|
|
199
|
+
name: text("name"), // Optional label for the API key
|
|
200
|
+
keyHash: text("key_hash").notNull(), // Store hashed version of the key
|
|
201
|
+
keyPrefix: text("key_prefix").notNull(), // Store first few chars for display (e.g., "wf_abc...")
|
|
202
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
203
|
+
lastUsedAt: timestamp("last_used_at"),
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Relations
|
|
207
|
+
export const workflowExecutionsRelations = relations(
|
|
208
|
+
workflowExecutions,
|
|
209
|
+
({ one }) => ({
|
|
210
|
+
workflow: one(workflows, {
|
|
211
|
+
fields: [workflowExecutions.workflowId],
|
|
212
|
+
references: [workflows.id],
|
|
213
|
+
}),
|
|
214
|
+
}),
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
export type User = typeof users.$inferSelect;
|
|
218
|
+
export type Session = typeof sessions.$inferSelect;
|
|
219
|
+
export type Workflow = typeof workflows.$inferSelect;
|
|
220
|
+
export type NewWorkflow = typeof workflows.$inferInsert;
|
|
221
|
+
export type Integration = typeof integrations.$inferSelect;
|
|
222
|
+
export type NewIntegration = typeof integrations.$inferInsert;
|
|
223
|
+
export type WorkflowExecution = typeof workflowExecutions.$inferSelect;
|
|
224
|
+
export type NewWorkflowExecution = typeof workflowExecutions.$inferInsert;
|
|
225
|
+
export type WorkflowExecutionLog = typeof workflowExecutionLogs.$inferSelect;
|
|
226
|
+
export type NewWorkflowExecutionLog = typeof workflowExecutionLogs.$inferInsert;
|
|
227
|
+
export type ApiKey = typeof apiKeys.$inferSelect;
|
|
228
|
+
export type NewApiKey = typeof apiKeys.$inferInsert;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { webcrypto } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
const ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
4
|
+
const ID_LENGTH = 21;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generate a random ID string of the specified length.
|
|
8
|
+
* Similar to nanoid package
|
|
9
|
+
*/
|
|
10
|
+
export function generateId(): string {
|
|
11
|
+
const mask = 63; // smallest bitmask >= 35 (2^6 - 1)
|
|
12
|
+
const bytes = webcrypto.getRandomValues(new Uint8Array(ID_LENGTH * 2)); // extra bytes for rejections
|
|
13
|
+
let id = "";
|
|
14
|
+
let cursor = 0;
|
|
15
|
+
while (id.length < ID_LENGTH) {
|
|
16
|
+
const val = bytes[cursor++] & mask;
|
|
17
|
+
if (val < ALPHABET.length) {
|
|
18
|
+
id += ALPHABET[val];
|
|
19
|
+
}
|
|
20
|
+
if (cursor >= bytes.length) {
|
|
21
|
+
webcrypto.getRandomValues(bytes);
|
|
22
|
+
cursor = 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return id;
|
|
26
|
+
}
|
package/dist/chunk-3XFDIK7H.js
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
// src/plugins/index.ts
|
|
2
|
-
var integrationRegistry = /* @__PURE__ */ new Map();
|
|
3
|
-
var codegenTemplateRegistry = /* @__PURE__ */ new Map();
|
|
4
|
-
var outputDisplayConfigRegistry = /* @__PURE__ */ new Map();
|
|
5
|
-
function registerCodegenTemplates(templates) {
|
|
6
|
-
for (const [actionId, template] of Object.entries(templates)) {
|
|
7
|
-
codegenTemplateRegistry.set(actionId, template);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
function getCodegenTemplate(actionId) {
|
|
11
|
-
return codegenTemplateRegistry.get(actionId);
|
|
12
|
-
}
|
|
13
|
-
function registerOutputDisplayConfigs(configs) {
|
|
14
|
-
for (const [actionId, config] of Object.entries(configs)) {
|
|
15
|
-
outputDisplayConfigRegistry.set(actionId, config);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function getOutputDisplayConfig(actionId) {
|
|
19
|
-
return outputDisplayConfigRegistry.get(actionId);
|
|
20
|
-
}
|
|
21
|
-
function computeActionId(integrationType, actionSlug) {
|
|
22
|
-
return `${integrationType}/${actionSlug}`;
|
|
23
|
-
}
|
|
24
|
-
function parseActionId(actionId) {
|
|
25
|
-
if (!actionId || typeof actionId !== "string") {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
const parts = actionId.split("/");
|
|
29
|
-
if (parts.length !== 2) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
return { integration: parts[0], slug: parts[1] };
|
|
33
|
-
}
|
|
34
|
-
function registerIntegration(plugin) {
|
|
35
|
-
integrationRegistry.set(plugin.type, plugin);
|
|
36
|
-
}
|
|
37
|
-
function getIntegration(type) {
|
|
38
|
-
return integrationRegistry.get(type);
|
|
39
|
-
}
|
|
40
|
-
function getAllIntegrations() {
|
|
41
|
-
return Array.from(integrationRegistry.values());
|
|
42
|
-
}
|
|
43
|
-
function getIntegrationTypes() {
|
|
44
|
-
return Array.from(integrationRegistry.keys());
|
|
45
|
-
}
|
|
46
|
-
function getAllActions() {
|
|
47
|
-
const actions = [];
|
|
48
|
-
for (const plugin of integrationRegistry.values()) {
|
|
49
|
-
for (const action of plugin.actions) {
|
|
50
|
-
actions.push({
|
|
51
|
-
...action,
|
|
52
|
-
id: computeActionId(plugin.type, action.slug),
|
|
53
|
-
integration: plugin.type
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return actions;
|
|
58
|
-
}
|
|
59
|
-
function getActionsByCategory() {
|
|
60
|
-
const categories = {};
|
|
61
|
-
for (const plugin of integrationRegistry.values()) {
|
|
62
|
-
for (const action of plugin.actions) {
|
|
63
|
-
if (!categories[action.category]) {
|
|
64
|
-
categories[action.category] = [];
|
|
65
|
-
}
|
|
66
|
-
categories[action.category].push({
|
|
67
|
-
...action,
|
|
68
|
-
id: computeActionId(plugin.type, action.slug),
|
|
69
|
-
integration: plugin.type
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return categories;
|
|
74
|
-
}
|
|
75
|
-
function findActionById(actionId) {
|
|
76
|
-
if (!actionId) {
|
|
77
|
-
return void 0;
|
|
78
|
-
}
|
|
79
|
-
const parsed = parseActionId(actionId);
|
|
80
|
-
if (parsed) {
|
|
81
|
-
const plugin = integrationRegistry.get(parsed.integration);
|
|
82
|
-
if (plugin) {
|
|
83
|
-
const action = plugin.actions.find((a) => a.slug === parsed.slug);
|
|
84
|
-
if (action) {
|
|
85
|
-
return {
|
|
86
|
-
...action,
|
|
87
|
-
id: actionId,
|
|
88
|
-
integration: plugin.type
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
for (const plugin of integrationRegistry.values()) {
|
|
94
|
-
const action = plugin.actions.find((a) => a.label === actionId);
|
|
95
|
-
if (action) {
|
|
96
|
-
return {
|
|
97
|
-
...action,
|
|
98
|
-
id: computeActionId(plugin.type, action.slug),
|
|
99
|
-
integration: plugin.type
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return void 0;
|
|
104
|
-
}
|
|
105
|
-
function getIntegrationLabels() {
|
|
106
|
-
const labels = {};
|
|
107
|
-
for (const plugin of integrationRegistry.values()) {
|
|
108
|
-
labels[plugin.type] = plugin.label;
|
|
109
|
-
}
|
|
110
|
-
return labels;
|
|
111
|
-
}
|
|
112
|
-
function getIntegrationDescriptions() {
|
|
113
|
-
const descriptions = {};
|
|
114
|
-
for (const plugin of integrationRegistry.values()) {
|
|
115
|
-
descriptions[plugin.type] = plugin.description;
|
|
116
|
-
}
|
|
117
|
-
return descriptions;
|
|
118
|
-
}
|
|
119
|
-
function getSortedIntegrationTypes() {
|
|
120
|
-
return Array.from(integrationRegistry.keys()).sort();
|
|
121
|
-
}
|
|
122
|
-
function getAllDependencies() {
|
|
123
|
-
const deps = {};
|
|
124
|
-
for (const plugin of integrationRegistry.values()) {
|
|
125
|
-
if (plugin.dependencies) {
|
|
126
|
-
Object.assign(deps, plugin.dependencies);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return deps;
|
|
130
|
-
}
|
|
131
|
-
function getDependenciesForActions(actionIds) {
|
|
132
|
-
const deps = {};
|
|
133
|
-
const integrations = /* @__PURE__ */ new Set();
|
|
134
|
-
for (const actionId of actionIds) {
|
|
135
|
-
const action = findActionById(actionId);
|
|
136
|
-
if (action) {
|
|
137
|
-
integrations.add(action.integration);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
for (const integrationType of integrations) {
|
|
141
|
-
const plugin = integrationRegistry.get(integrationType);
|
|
142
|
-
if (plugin?.dependencies) {
|
|
143
|
-
Object.assign(deps, plugin.dependencies);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return deps;
|
|
147
|
-
}
|
|
148
|
-
function getPluginEnvVars(plugin) {
|
|
149
|
-
const envVars = [];
|
|
150
|
-
for (const field of plugin.formFields) {
|
|
151
|
-
if (field.envVar) {
|
|
152
|
-
envVars.push({
|
|
153
|
-
name: field.envVar,
|
|
154
|
-
description: field.helpText || field.label
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return envVars;
|
|
159
|
-
}
|
|
160
|
-
function getAllEnvVars() {
|
|
161
|
-
const envVars = [];
|
|
162
|
-
for (const plugin of integrationRegistry.values()) {
|
|
163
|
-
envVars.push(...getPluginEnvVars(plugin));
|
|
164
|
-
}
|
|
165
|
-
return envVars;
|
|
166
|
-
}
|
|
167
|
-
function getCredentialMapping(plugin, config) {
|
|
168
|
-
const creds = {};
|
|
169
|
-
for (const field of plugin.formFields) {
|
|
170
|
-
if (field.envVar && config[field.configKey]) {
|
|
171
|
-
creds[field.envVar] = String(config[field.configKey]);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return creds;
|
|
175
|
-
}
|
|
176
|
-
function isFieldGroup(field) {
|
|
177
|
-
return field.type === "group";
|
|
178
|
-
}
|
|
179
|
-
function flattenConfigFields(fields) {
|
|
180
|
-
const result = [];
|
|
181
|
-
for (const field of fields) {
|
|
182
|
-
if (isFieldGroup(field)) {
|
|
183
|
-
result.push(...field.fields);
|
|
184
|
-
} else {
|
|
185
|
-
result.push(field);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
return result;
|
|
189
|
-
}
|
|
190
|
-
function generateAIActionPrompts() {
|
|
191
|
-
const lines = [];
|
|
192
|
-
for (const plugin of integrationRegistry.values()) {
|
|
193
|
-
for (const action of plugin.actions) {
|
|
194
|
-
const fullId = computeActionId(plugin.type, action.slug);
|
|
195
|
-
const exampleConfig = {
|
|
196
|
-
actionType: fullId
|
|
197
|
-
};
|
|
198
|
-
const flatFields = flattenConfigFields(action.configFields);
|
|
199
|
-
for (const field of flatFields) {
|
|
200
|
-
if (field.showWhen) continue;
|
|
201
|
-
if (field.example !== void 0) {
|
|
202
|
-
exampleConfig[field.key] = field.example;
|
|
203
|
-
} else if (field.defaultValue !== void 0) {
|
|
204
|
-
exampleConfig[field.key] = field.defaultValue;
|
|
205
|
-
} else if (field.type === "number") {
|
|
206
|
-
exampleConfig[field.key] = 10;
|
|
207
|
-
} else if (field.type === "select" && field.options?.[0]) {
|
|
208
|
-
exampleConfig[field.key] = field.options[0].value;
|
|
209
|
-
} else {
|
|
210
|
-
exampleConfig[field.key] = `Your ${field.label.toLowerCase()}`;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
lines.push(
|
|
214
|
-
`- ${action.label} (${fullId}): ${JSON.stringify(exampleConfig)}`
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
return lines.join("\n");
|
|
219
|
-
}
|
|
220
|
-
function integrationRequiresCredentials(type) {
|
|
221
|
-
const plugin = integrationRegistry.get(type);
|
|
222
|
-
return !!plugin && plugin.formFields.length > 0;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
export {
|
|
226
|
-
registerCodegenTemplates,
|
|
227
|
-
getCodegenTemplate,
|
|
228
|
-
registerOutputDisplayConfigs,
|
|
229
|
-
getOutputDisplayConfig,
|
|
230
|
-
computeActionId,
|
|
231
|
-
parseActionId,
|
|
232
|
-
registerIntegration,
|
|
233
|
-
getIntegration,
|
|
234
|
-
getAllIntegrations,
|
|
235
|
-
getIntegrationTypes,
|
|
236
|
-
getAllActions,
|
|
237
|
-
getActionsByCategory,
|
|
238
|
-
findActionById,
|
|
239
|
-
getIntegrationLabels,
|
|
240
|
-
getIntegrationDescriptions,
|
|
241
|
-
getSortedIntegrationTypes,
|
|
242
|
-
getAllDependencies,
|
|
243
|
-
getDependenciesForActions,
|
|
244
|
-
getPluginEnvVars,
|
|
245
|
-
getAllEnvVars,
|
|
246
|
-
getCredentialMapping,
|
|
247
|
-
isFieldGroup,
|
|
248
|
-
flattenConfigFields,
|
|
249
|
-
generateAIActionPrompts,
|
|
250
|
-
integrationRequiresCredentials
|
|
251
|
-
};
|