@xtr-dev/payload-automation 0.0.42 → 0.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +221 -49
  2. package/dist/collections/Steps.d.ts +6 -0
  3. package/dist/collections/Steps.js +166 -0
  4. package/dist/collections/Steps.js.map +1 -0
  5. package/dist/collections/Triggers.d.ts +7 -0
  6. package/dist/collections/Triggers.js +224 -0
  7. package/dist/collections/Triggers.js.map +1 -0
  8. package/dist/collections/Workflow.d.ts +5 -2
  9. package/dist/collections/Workflow.js +179 -39
  10. package/dist/collections/Workflow.js.map +1 -1
  11. package/dist/collections/WorkflowRuns.d.ts +4 -0
  12. package/dist/collections/WorkflowRuns.js +219 -24
  13. package/dist/collections/WorkflowRuns.js.map +1 -1
  14. package/dist/components/WorkflowBuilder/WorkflowBuilder.js.map +1 -1
  15. package/dist/core/expression-engine.d.ts +58 -0
  16. package/dist/core/expression-engine.js +191 -0
  17. package/dist/core/expression-engine.js.map +1 -0
  18. package/dist/core/workflow-executor.d.ts +70 -56
  19. package/dist/core/workflow-executor.js +354 -677
  20. package/dist/core/workflow-executor.js.map +1 -1
  21. package/dist/exports/client.js +1 -3
  22. package/dist/exports/client.js.map +1 -1
  23. package/dist/exports/views.js +2 -4
  24. package/dist/exports/views.js.map +1 -1
  25. package/dist/fields/parameter.js +8 -3
  26. package/dist/fields/parameter.js.map +1 -1
  27. package/dist/index.d.ts +3 -2
  28. package/dist/index.js +1 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/plugin/config-types.d.ts +43 -5
  31. package/dist/plugin/config-types.js +3 -1
  32. package/dist/plugin/config-types.js.map +1 -1
  33. package/dist/plugin/index.d.ts +1 -1
  34. package/dist/plugin/index.js +82 -28
  35. package/dist/plugin/index.js.map +1 -1
  36. package/dist/plugin/trigger-hook.d.ts +13 -0
  37. package/dist/plugin/trigger-hook.js +184 -0
  38. package/dist/plugin/trigger-hook.js.map +1 -0
  39. package/dist/steps/create-step.d.ts +66 -0
  40. package/dist/steps/create-step.js +59 -0
  41. package/dist/steps/create-step.js.map +1 -0
  42. package/dist/steps/index.d.ts +2 -0
  43. package/dist/steps/index.js +3 -0
  44. package/dist/steps/index.js.map +1 -1
  45. package/dist/steps/read-document-handler.js +1 -1
  46. package/dist/steps/read-document-handler.js.map +1 -1
  47. package/dist/steps/update-document-handler.js +1 -1
  48. package/dist/steps/update-document-handler.js.map +1 -1
  49. package/dist/triggers/hook-options.d.ts +34 -0
  50. package/dist/triggers/hook-options.js +158 -0
  51. package/dist/triggers/hook-options.js.map +1 -0
  52. package/dist/triggers/index.d.ts +2 -2
  53. package/dist/triggers/index.js +1 -2
  54. package/dist/triggers/index.js.map +1 -1
  55. package/dist/types/index.d.ts +8 -0
  56. package/dist/types/index.js +4 -5
  57. package/dist/types/index.js.map +1 -1
  58. package/dist/utils/validation.d.ts +64 -0
  59. package/dist/utils/validation.js +107 -0
  60. package/dist/utils/validation.js.map +1 -0
  61. package/package.json +2 -1
  62. package/dist/plugin/collection-hook.d.ts +0 -1
  63. package/dist/plugin/collection-hook.js +0 -92
  64. package/dist/plugin/collection-hook.js.map +0 -1
  65. package/dist/plugin/global-hook.d.ts +0 -1
  66. package/dist/plugin/global-hook.js +0 -83
  67. package/dist/plugin/global-hook.js.map +0 -1
  68. package/dist/triggers/collection-trigger.d.ts +0 -2
  69. package/dist/triggers/collection-trigger.js +0 -36
  70. package/dist/triggers/collection-trigger.js.map +0 -1
  71. package/dist/triggers/global-trigger.d.ts +0 -2
  72. package/dist/triggers/global-trigger.js +0 -29
  73. package/dist/triggers/global-trigger.js.map +0 -1
  74. package/dist/triggers/types.d.ts +0 -5
  75. package/dist/triggers/types.js +0 -3
  76. package/dist/triggers/types.js.map +0 -1
package/README.md CHANGED
@@ -2,47 +2,48 @@
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/@xtr-dev%2Fpayload-automation.svg)](https://www.npmjs.com/package/@xtr-dev/payload-automation)
4
4
 
5
- A workflow automation plugin for PayloadCMS 3.x. Run steps in workflows triggered by document changes or webhooks.
5
+ A workflow automation plugin for PayloadCMS 3.x. Build visual workflows triggered by document changes, webhooks, or manual execution.
6
6
 
7
- ⚠️ **Pre-release Warning**: This package is currently in active development (v0.0.x). Breaking changes may occur before v1.0.0. Not recommended for production use.
7
+ > **Pre-release Warning**: This package is currently in active development (v0.0.x). Breaking changes may occur before v1.0.0.
8
8
 
9
9
  ## Features
10
10
 
11
- - 🔄 Visual workflow builder in PayloadCMS admin
12
- - Run workflows when documents are created/updated/deleted
13
- - 🎯 Trigger workflows via webhooks
14
- - 📊 Track workflow execution history
15
- - 🔧 HTTP requests, document operations, email sending
16
- - 🔗 Use data from previous steps in templates
11
+ - **Visual Workflow Builder** - Drag-and-drop workflow editor in PayloadCMS admin
12
+ - **Workflow Visualizer** - React component for displaying workflows with real-time execution status
13
+ - **Collection Triggers** - Run workflows when documents are created, updated, or deleted
14
+ - **Webhook Triggers** - Trigger workflows via HTTP endpoints
15
+ - **Step Dependencies** - Define execution order with parallel and sequential steps
16
+ - **Execution Tracking** - Full history with step-by-step results, duration, and logs
17
+ - **Built-in Steps** - HTTP requests, document CRUD, email sending
18
+ - **Custom Steps** - Create your own step types with the step factory
19
+ - **JSONata Expressions** - Powerful data transformation between steps
17
20
 
18
21
  ## Installation
19
22
 
20
23
  ```bash
21
- npm install @xtr-dev/payload-automation
22
- # or
23
24
  pnpm add @xtr-dev/payload-automation
24
25
  # or
25
- yarn add @xtr-dev/payload-automation
26
+ npm install @xtr-dev/payload-automation
26
27
  ```
27
28
 
28
29
  ## Quick Start
29
30
 
30
31
  ```typescript
31
32
  import { buildConfig } from 'payload'
32
- import { workflowsPlugin } from '@xtr-dev/payload-automation/server'
33
+ import { workflowsPlugin } from '@xtr-dev/payload-automation'
33
34
 
34
35
  export default buildConfig({
35
- // ... your config
36
36
  plugins: [
37
37
  workflowsPlugin({
38
+ enabled: true,
38
39
  collectionTriggers: {
39
- posts: true, // Enable all CRUD triggers for posts
40
- users: {
41
- create: true, // Only enable create trigger for users
42
- update: true
40
+ orders: true, // Enable all hooks for orders
41
+ users: {
42
+ afterChange: true, // Only specific hooks
43
43
  }
44
44
  },
45
- enabled: true,
45
+ // Register custom steps
46
+ steps: [myCustomStep],
46
47
  }),
47
48
  ],
48
49
  })
@@ -51,8 +52,8 @@ export default buildConfig({
51
52
  ## Imports
52
53
 
53
54
  ```typescript
54
- // Server plugin
55
- import { workflowsPlugin } from '@xtr-dev/payload-automation/server'
55
+ // Main plugin
56
+ import { workflowsPlugin } from '@xtr-dev/payload-automation'
56
57
 
57
58
  // Client components
58
59
  import { StatusCell, ErrorDisplay } from '@xtr-dev/payload-automation/client'
@@ -75,11 +76,12 @@ const exampleWorkflows: SeedWorkflow[] = [
75
76
  description: 'Send email when user is created',
76
77
  triggers: [
77
78
  {
78
- type: 'collection',
79
+ type: 'collection-hook',
79
80
  parameters: {
80
- collection: 'users',
81
- hook: 'afterCreate',
81
+ collectionSlug: 'users',
82
+ hook: 'afterChange',
82
83
  },
84
+ condition: 'trigger.operation = "create"',
83
85
  },
84
86
  ],
85
87
  steps: [
@@ -115,59 +117,229 @@ See [docs/SEEDING_WORKFLOWS.md](./docs/SEEDING_WORKFLOWS.md) for detailed docume
115
117
  ## Step Types
116
118
 
117
119
  ### HTTP Request
118
- Call external APIs. Supports GET, POST, PUT, DELETE, PATCH. Uses Bearer tokens, API keys, or basic auth.
120
+ Call external APIs with full configuration:
121
+
122
+ ```typescript
123
+ {
124
+ type: 'http-request-step',
125
+ config: {
126
+ url: 'https://api.example.com/webhook',
127
+ method: 'POST',
128
+ headers: { 'Content-Type': 'application/json' },
129
+ body: '{"orderId": "{{trigger.doc.id}}"}'
130
+ }
131
+ }
132
+ ```
119
133
 
120
- HTTP steps succeed even with 4xx/5xx status codes. Only network errors (timeouts, DNS failures) cause step failure. Check `{{steps.stepName.output.status}}` for error handling.
134
+ Supports GET, POST, PUT, DELETE, PATCH. Authentication via Bearer tokens, API keys, or basic auth.
121
135
 
122
136
  ### Document Operations
123
- - **Create Document** - Create PayloadCMS documents
137
+
138
+ - **Create Document** - Create new PayloadCMS documents
124
139
  - **Read Document** - Query documents with filters
125
- - **Update Document** - Modify existing documents
140
+ - **Update Document** - Modify existing documents
126
141
  - **Delete Document** - Remove documents
127
142
 
128
- ### Communication
129
- - **Send Email** - Send notifications via PayloadCMS email
143
+ ### Send Email
144
+ Send notifications via PayloadCMS email adapter:
145
+
146
+ ```typescript
147
+ {
148
+ type: 'send-email',
149
+ config: {
150
+ to: '{{trigger.doc.customer.email}}',
151
+ subject: 'Order Confirmed',
152
+ template: 'order-confirmation'
153
+ }
154
+ }
155
+ ```
156
+
157
+ ## Custom Steps
158
+
159
+ Create reusable step types with the `createStep` factory:
160
+
161
+ ```typescript
162
+ import { createStep } from '@xtr-dev/payload-automation/steps'
163
+
164
+ export const SlackNotificationStep = createStep({
165
+ slug: 'slack-notification',
166
+ label: 'Send Slack Message',
167
+
168
+ inputSchema: [
169
+ { name: 'channel', type: 'text', required: true },
170
+ { name: 'message', type: 'textarea', required: true },
171
+ ],
172
+
173
+ outputSchema: [
174
+ { name: 'messageId', type: 'text' },
175
+ { name: 'timestamp', type: 'text' },
176
+ ],
177
+
178
+ visual: {
179
+ icon: '💬',
180
+ color: '#4A154B',
181
+ },
182
+
183
+ validate: (input) => {
184
+ if (!input.channel?.startsWith('#')) {
185
+ throw new Error('Channel must start with #')
186
+ }
187
+ },
188
+
189
+ execute: async (input, req) => {
190
+ const response = await fetch('https://slack.com/api/chat.postMessage', {
191
+ method: 'POST',
192
+ headers: {
193
+ 'Authorization': `Bearer ${process.env.SLACK_TOKEN}`,
194
+ 'Content-Type': 'application/json',
195
+ },
196
+ body: JSON.stringify({
197
+ channel: input.channel,
198
+ text: input.message,
199
+ }),
200
+ })
201
+
202
+ const data = await response.json()
203
+ return {
204
+ messageId: data.message.ts,
205
+ timestamp: new Date().toISOString(),
206
+ }
207
+ },
208
+ })
209
+ ```
210
+
211
+ Register custom steps in the plugin config:
212
+
213
+ ```typescript
214
+ workflowsPlugin({
215
+ steps: [SlackNotificationStep],
216
+ })
217
+ ```
218
+
219
+ ## JSONata Expressions
220
+
221
+ Use `{{expression}}` syntax for dynamic values. [JSONata](https://jsonata.org) provides powerful data transformation.
222
+
223
+ ### Available Context
224
+
225
+ - `trigger.doc` - The document that triggered the workflow
226
+ - `trigger.type` - Trigger type ('collection' | 'global')
227
+ - `trigger.collection` - Collection slug for collection triggers
228
+ - `steps.<stepName>.output` - Output from a completed step
229
+ - `steps.<stepName>.state` - Step state ('succeeded' | 'failed' | 'pending' | 'skipped')
130
230
 
131
- ## Templates
231
+ ### Examples
132
232
 
133
- Use `{{}}` to insert data:
233
+ ```javascript
234
+ // Access trigger data
235
+ {{trigger.doc.id}}
236
+ {{trigger.doc.customer.email}}
134
237
 
135
- - `{{trigger.doc.id}}` - Data from the document that triggered the workflow
136
- - `{{steps.stepName.output}}` - Data from previous steps
238
+ // Use previous step output
239
+ {{steps.createOrder.output.id}}
240
+ {{steps.fetchUser.output.name}}
137
241
 
138
- Example:
139
- ```json
242
+ // Conditions (in step config)
243
+ {{trigger.doc.status = 'published'}}
244
+ {{trigger.doc.total > 100}}
245
+
246
+ // String transformation
247
+ {{$uppercase(trigger.doc.title)}}
248
+ {{$join(trigger.doc.tags, ', ')}}
249
+
250
+ // Object construction
140
251
  {
141
- "url": "https://api.example.com/posts/{{steps.createPost.output.id}}",
142
- "condition": "{{trigger.doc.status}} == 'published'"
252
+ "orderId": "{{trigger.doc.id}}",
253
+ "total": "{{$sum(trigger.doc.items.price)}}"
254
+ }
255
+ ```
256
+
257
+ ### Custom Functions
258
+
259
+ | Function | Description |
260
+ |----------|-------------|
261
+ | `$now()` | Current ISO timestamp |
262
+ | `$uuid()` | Generate UUID v4 |
263
+ | `$default(value, fallback)` | Return fallback if null |
264
+ | `$coalesce(a, b, ...)` | First non-null value |
265
+ | `$env('PUBLIC_*')` | Access PUBLIC_ env vars |
266
+
267
+ ## Execution Tracking
268
+
269
+ All workflow executions are stored in the `workflow-runs` collection with:
270
+
271
+ - Trigger data that initiated the run
272
+ - Step-by-step results with status and duration
273
+ - Execution logs with timestamps
274
+ - Total duration and final status
275
+
276
+ Query runs programmatically:
277
+
278
+ ```typescript
279
+ const runs = await payload.find({
280
+ collection: 'workflow-runs',
281
+ where: {
282
+ workflow: { equals: workflowId },
283
+ status: { equals: 'completed' },
284
+ },
285
+ sort: '-createdAt',
286
+ limit: 10,
287
+ })
288
+ ```
289
+
290
+ ## Plugin Configuration
291
+
292
+ ```typescript
293
+ interface WorkflowsPluginConfig {
294
+ // Enable/disable the plugin
295
+ enabled?: boolean
296
+
297
+ // Collection triggers
298
+ collectionTriggers?: {
299
+ [collectionSlug: string]: boolean | {
300
+ afterChange?: boolean
301
+ afterDelete?: boolean
302
+ afterRead?: boolean
303
+ // ... other hooks
304
+ }
305
+ }
306
+
307
+ // Global triggers
308
+ globalTriggers?: {
309
+ [globalSlug: string]: boolean | { /* hooks */ }
310
+ }
311
+
312
+ // Custom step definitions
313
+ steps?: StepDefinition[]
143
314
  }
144
315
  ```
145
316
 
146
317
  ## Requirements
147
318
 
148
- - PayloadCMS ^3.45.0
319
+ - PayloadCMS ^3.37.0
149
320
  - Node.js ^18.20.2 || >=20.9.0
150
- - pnpm ^9 || ^10
321
+ - React 18+ (for client components)
151
322
 
152
323
  ## Logging
153
324
 
154
- Set `PAYLOAD_AUTOMATION_LOG_LEVEL` to control logs:
155
- - `silent`, `error`, `warn` (default), `info`, `debug`, `trace`
325
+ Control log verbosity with `PAYLOAD_AUTOMATION_LOG_LEVEL`:
156
326
 
157
327
  ```bash
158
- PAYLOAD_AUTOMATION_LOG_LEVEL=debug npm run dev
328
+ PAYLOAD_AUTOMATION_LOG_LEVEL=debug pnpm dev
159
329
  ```
160
330
 
161
- ## Scheduled Workflows
331
+ Levels: `silent` | `error` | `warn` (default) | `info` | `debug` | `trace`
162
332
 
163
- Use webhook triggers with external cron services:
333
+ ## Collections
164
334
 
165
- ```bash
166
- # Call workflow webhook from cron
167
- curl -X POST https://your-app.com/api/workflows-webhook/daily-report
168
- ```
335
+ The plugin creates these collections:
169
336
 
170
- Built-in cron triggers were removed in v0.0.37+.
337
+ | Collection | Slug | Description |
338
+ |------------|------|-------------|
339
+ | Triggers | `automation-triggers` | Reusable trigger definitions |
340
+ | Steps | `automation-steps` | Step templates with configuration |
341
+ | Workflows | `workflows` | Workflow definitions |
342
+ | Workflow Runs | `workflow-runs` | Execution history |
171
343
 
172
344
  ## License
173
345
 
@@ -0,0 +1,6 @@
1
+ import type { CollectionConfig, TaskConfig } from 'payload';
2
+ /**
3
+ * Creates the automation-steps collection.
4
+ * Steps are reusable building blocks that can be used across multiple workflows.
5
+ */
6
+ export declare const createStepsCollection: (steps: TaskConfig<string>[]) => CollectionConfig;
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Creates the automation-steps collection.
3
+ * Steps are reusable building blocks that can be used across multiple workflows.
4
+ */ export const createStepsCollection = (steps)=>{
5
+ // Build step type options from registered steps
6
+ const stepTypeOptions = steps.map((step)=>({
7
+ label: step.label || step.slug,
8
+ value: step.slug
9
+ }));
10
+ return {
11
+ slug: 'automation-steps',
12
+ access: {
13
+ create: ()=>true,
14
+ delete: ()=>true,
15
+ read: ()=>true,
16
+ update: ()=>true
17
+ },
18
+ admin: {
19
+ defaultColumns: [
20
+ 'name',
21
+ 'type',
22
+ 'updatedAt'
23
+ ],
24
+ description: 'Reusable step templates that can be used across workflows.',
25
+ group: 'Automation',
26
+ useAsTitle: 'name'
27
+ },
28
+ fields: [
29
+ {
30
+ name: 'name',
31
+ type: 'text',
32
+ admin: {
33
+ description: 'Human-readable name for this step'
34
+ },
35
+ required: true
36
+ },
37
+ {
38
+ name: 'description',
39
+ type: 'textarea',
40
+ admin: {
41
+ description: 'Optional description of what this step does'
42
+ }
43
+ },
44
+ {
45
+ name: 'type',
46
+ type: 'select',
47
+ admin: {
48
+ description: 'The type of action this step performs'
49
+ },
50
+ options: stepTypeOptions,
51
+ required: true
52
+ },
53
+ // Step configuration
54
+ {
55
+ type: 'collapsible',
56
+ label: 'Configuration',
57
+ admin: {
58
+ initCollapsed: false
59
+ },
60
+ fields: [
61
+ {
62
+ name: 'config',
63
+ type: 'json',
64
+ admin: {
65
+ description: 'Step configuration in JSON format. String values can use JSONata expressions for dynamic data (e.g., "trigger.doc.id")'
66
+ },
67
+ defaultValue: {}
68
+ }
69
+ ]
70
+ },
71
+ // Visual properties for workflow builder
72
+ {
73
+ type: 'collapsible',
74
+ label: 'Appearance',
75
+ admin: {
76
+ initCollapsed: true
77
+ },
78
+ fields: [
79
+ {
80
+ name: 'color',
81
+ type: 'text',
82
+ admin: {
83
+ description: 'Color for the step node in the visual builder (hex code)',
84
+ placeholder: '#3b82f6'
85
+ },
86
+ defaultValue: '#3b82f6'
87
+ },
88
+ {
89
+ name: 'icon',
90
+ type: 'text',
91
+ admin: {
92
+ description: 'Icon name for the step (optional)'
93
+ }
94
+ }
95
+ ]
96
+ },
97
+ // Input validation schema (optional)
98
+ {
99
+ type: 'collapsible',
100
+ label: 'Advanced',
101
+ admin: {
102
+ initCollapsed: true
103
+ },
104
+ fields: [
105
+ {
106
+ name: 'inputValidation',
107
+ type: 'json',
108
+ admin: {
109
+ description: 'Optional JSON schema for validating step inputs'
110
+ }
111
+ },
112
+ {
113
+ name: 'retryOnFailure',
114
+ type: 'checkbox',
115
+ admin: {
116
+ description: 'Retry this step if it fails'
117
+ },
118
+ defaultValue: false
119
+ },
120
+ {
121
+ name: 'maxRetries',
122
+ type: 'number',
123
+ admin: {
124
+ condition: (_, siblingData)=>siblingData?.retryOnFailure === true,
125
+ description: 'Maximum number of retry attempts'
126
+ },
127
+ defaultValue: 3
128
+ },
129
+ {
130
+ name: 'retryDelay',
131
+ type: 'number',
132
+ admin: {
133
+ condition: (_, siblingData)=>siblingData?.retryOnFailure === true,
134
+ description: 'Delay between retries in milliseconds'
135
+ },
136
+ defaultValue: 1000
137
+ }
138
+ ]
139
+ },
140
+ // Usage tracking
141
+ {
142
+ name: 'usageCount',
143
+ type: 'number',
144
+ admin: {
145
+ description: 'Number of workflows using this step',
146
+ readOnly: true,
147
+ position: 'sidebar'
148
+ },
149
+ defaultValue: 0
150
+ }
151
+ ],
152
+ hooks: {
153
+ beforeChange: [
154
+ // Validate that type is selected
155
+ async ({ data, operation })=>{
156
+ if ((operation === 'create' || operation === 'update') && !data?.type) {
157
+ throw new Error('Step type is required');
158
+ }
159
+ return data;
160
+ }
161
+ ]
162
+ }
163
+ };
164
+ };
165
+
166
+ //# sourceMappingURL=Steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/collections/Steps.ts"],"sourcesContent":["import type { CollectionConfig, TaskConfig } from 'payload'\n\n/**\n * Creates the automation-steps collection.\n * Steps are reusable building blocks that can be used across multiple workflows.\n */\nexport const createStepsCollection = (\n steps: TaskConfig<string>[]\n): CollectionConfig => {\n // Build step type options from registered steps\n const stepTypeOptions = steps.map(step => ({\n label: step.label || step.slug,\n value: step.slug,\n }))\n\n return {\n slug: 'automation-steps',\n access: {\n create: () => true,\n delete: () => true,\n read: () => true,\n update: () => true,\n },\n admin: {\n defaultColumns: ['name', 'type', 'updatedAt'],\n description: 'Reusable step templates that can be used across workflows.',\n group: 'Automation',\n useAsTitle: 'name',\n },\n fields: [\n {\n name: 'name',\n type: 'text',\n admin: {\n description: 'Human-readable name for this step',\n },\n required: true,\n },\n {\n name: 'description',\n type: 'textarea',\n admin: {\n description: 'Optional description of what this step does',\n },\n },\n {\n name: 'type',\n type: 'select',\n admin: {\n description: 'The type of action this step performs',\n },\n options: stepTypeOptions,\n required: true,\n },\n // Step configuration\n {\n type: 'collapsible',\n label: 'Configuration',\n admin: {\n initCollapsed: false,\n },\n fields: [\n {\n name: 'config',\n type: 'json',\n admin: {\n description: 'Step configuration in JSON format. String values can use JSONata expressions for dynamic data (e.g., \"trigger.doc.id\")',\n },\n defaultValue: {},\n },\n ],\n },\n // Visual properties for workflow builder\n {\n type: 'collapsible',\n label: 'Appearance',\n admin: {\n initCollapsed: true,\n },\n fields: [\n {\n name: 'color',\n type: 'text',\n admin: {\n description: 'Color for the step node in the visual builder (hex code)',\n placeholder: '#3b82f6',\n },\n defaultValue: '#3b82f6',\n },\n {\n name: 'icon',\n type: 'text',\n admin: {\n description: 'Icon name for the step (optional)',\n },\n },\n ],\n },\n // Input validation schema (optional)\n {\n type: 'collapsible',\n label: 'Advanced',\n admin: {\n initCollapsed: true,\n },\n fields: [\n {\n name: 'inputValidation',\n type: 'json',\n admin: {\n description: 'Optional JSON schema for validating step inputs',\n },\n },\n {\n name: 'retryOnFailure',\n type: 'checkbox',\n admin: {\n description: 'Retry this step if it fails',\n },\n defaultValue: false,\n },\n {\n name: 'maxRetries',\n type: 'number',\n admin: {\n condition: (_, siblingData) => siblingData?.retryOnFailure === true,\n description: 'Maximum number of retry attempts',\n },\n defaultValue: 3,\n },\n {\n name: 'retryDelay',\n type: 'number',\n admin: {\n condition: (_, siblingData) => siblingData?.retryOnFailure === true,\n description: 'Delay between retries in milliseconds',\n },\n defaultValue: 1000,\n },\n ],\n },\n // Usage tracking\n {\n name: 'usageCount',\n type: 'number',\n admin: {\n description: 'Number of workflows using this step',\n readOnly: true,\n position: 'sidebar',\n },\n defaultValue: 0,\n },\n ],\n hooks: {\n beforeChange: [\n // Validate that type is selected\n async ({ data, operation }) => {\n if ((operation === 'create' || operation === 'update') && !data?.type) {\n throw new Error('Step type is required')\n }\n return data\n }\n ],\n },\n }\n}\n"],"names":["createStepsCollection","steps","stepTypeOptions","map","step","label","slug","value","access","create","delete","read","update","admin","defaultColumns","description","group","useAsTitle","fields","name","type","required","options","initCollapsed","defaultValue","placeholder","condition","_","siblingData","retryOnFailure","readOnly","position","hooks","beforeChange","data","operation","Error"],"mappings":"AAEA;;;CAGC,GACD,OAAO,MAAMA,wBAAwB,CACnCC;IAEA,gDAAgD;IAChD,MAAMC,kBAAkBD,MAAME,GAAG,CAACC,CAAAA,OAAS,CAAA;YACzCC,OAAOD,KAAKC,KAAK,IAAID,KAAKE,IAAI;YAC9BC,OAAOH,KAAKE,IAAI;QAClB,CAAA;IAEA,OAAO;QACLA,MAAM;QACNE,QAAQ;YACNC,QAAQ,IAAM;YACdC,QAAQ,IAAM;YACdC,MAAM,IAAM;YACZC,QAAQ,IAAM;QAChB;QACAC,OAAO;YACLC,gBAAgB;gBAAC;gBAAQ;gBAAQ;aAAY;YAC7CC,aAAa;YACbC,OAAO;YACPC,YAAY;QACd;QACAC,QAAQ;YACN;gBACEC,MAAM;gBACNC,MAAM;gBACNP,OAAO;oBACLE,aAAa;gBACf;gBACAM,UAAU;YACZ;YACA;gBACEF,MAAM;gBACNC,MAAM;gBACNP,OAAO;oBACLE,aAAa;gBACf;YACF;YACA;gBACEI,MAAM;gBACNC,MAAM;gBACNP,OAAO;oBACLE,aAAa;gBACf;gBACAO,SAASpB;gBACTmB,UAAU;YACZ;YACA,qBAAqB;YACrB;gBACED,MAAM;gBACNf,OAAO;gBACPQ,OAAO;oBACLU,eAAe;gBACjB;gBACAL,QAAQ;oBACN;wBACEC,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;wBACf;wBACAS,cAAc,CAAC;oBACjB;iBACD;YACH;YACA,yCAAyC;YACzC;gBACEJ,MAAM;gBACNf,OAAO;gBACPQ,OAAO;oBACLU,eAAe;gBACjB;gBACAL,QAAQ;oBACN;wBACEC,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;4BACbU,aAAa;wBACf;wBACAD,cAAc;oBAChB;oBACA;wBACEL,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;wBACf;oBACF;iBACD;YACH;YACA,qCAAqC;YACrC;gBACEK,MAAM;gBACNf,OAAO;gBACPQ,OAAO;oBACLU,eAAe;gBACjB;gBACAL,QAAQ;oBACN;wBACEC,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;wBACf;oBACF;oBACA;wBACEI,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;wBACf;wBACAS,cAAc;oBAChB;oBACA;wBACEL,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLa,WAAW,CAACC,GAAGC,cAAgBA,aAAaC,mBAAmB;4BAC/Dd,aAAa;wBACf;wBACAS,cAAc;oBAChB;oBACA;wBACEL,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLa,WAAW,CAACC,GAAGC,cAAgBA,aAAaC,mBAAmB;4BAC/Dd,aAAa;wBACf;wBACAS,cAAc;oBAChB;iBACD;YACH;YACA,iBAAiB;YACjB;gBACEL,MAAM;gBACNC,MAAM;gBACNP,OAAO;oBACLE,aAAa;oBACbe,UAAU;oBACVC,UAAU;gBACZ;gBACAP,cAAc;YAChB;SACD;QACDQ,OAAO;YACLC,cAAc;gBACZ,iCAAiC;gBACjC,OAAO,EAAEC,IAAI,EAAEC,SAAS,EAAE;oBACxB,IAAI,AAACA,CAAAA,cAAc,YAAYA,cAAc,QAAO,KAAM,CAACD,MAAMd,MAAM;wBACrE,MAAM,IAAIgB,MAAM;oBAClB;oBACA,OAAOF;gBACT;aACD;QACH;IACF;AACF,EAAC"}
@@ -0,0 +1,7 @@
1
+ import type { CollectionConfig } from 'payload';
2
+ import type { WorkflowsPluginConfig } from '../plugin/config-types.js';
3
+ /**
4
+ * Creates the automation-triggers collection.
5
+ * Triggers are reusable and can be shared across multiple workflows.
6
+ */
7
+ export declare const createTriggersCollection: <T extends string>(options: WorkflowsPluginConfig<T>) => CollectionConfig;