@xtr-dev/payload-automation 0.0.35 → 0.0.37
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/README.md +61 -0
- package/dist/collections/Workflow.js +30 -305
- package/dist/collections/Workflow.js.map +1 -1
- package/dist/components/ErrorDisplay.js +3 -3
- package/dist/components/ErrorDisplay.js.map +1 -1
- package/dist/core/workflow-executor.d.ts +33 -85
- package/dist/core/workflow-executor.js +136 -229
- package/dist/core/workflow-executor.js.map +1 -1
- package/dist/exports/client.d.ts +0 -2
- package/dist/exports/client.js +1 -3
- package/dist/exports/client.js.map +1 -1
- package/dist/fields/parameter.d.ts +4 -0
- package/dist/fields/parameter.js +32 -0
- package/dist/fields/parameter.js.map +1 -0
- package/dist/plugin/collection-hook.d.ts +1 -0
- package/dist/plugin/collection-hook.js +58 -0
- package/dist/plugin/collection-hook.js.map +1 -0
- package/dist/plugin/config-types.d.ts +14 -17
- package/dist/plugin/config-types.js.map +1 -1
- package/dist/plugin/global-hook.d.ts +1 -0
- package/dist/plugin/global-hook.js +83 -0
- package/dist/plugin/global-hook.js.map +1 -0
- package/dist/plugin/index.js +83 -206
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/logger.js +23 -7
- package/dist/plugin/logger.js.map +1 -1
- package/dist/test/workflow-executor.test.js +2 -2
- package/dist/test/workflow-executor.test.js.map +1 -1
- package/dist/triggers/collection-trigger.d.ts +2 -0
- package/dist/triggers/collection-trigger.js +36 -0
- package/dist/triggers/collection-trigger.js.map +1 -0
- package/dist/triggers/global-trigger.d.ts +2 -0
- package/dist/triggers/global-trigger.js +29 -0
- package/dist/triggers/global-trigger.js.map +1 -0
- package/dist/triggers/index.d.ts +2 -0
- package/dist/triggers/index.js +4 -0
- package/dist/triggers/index.js.map +1 -0
- package/dist/triggers/types.d.ts +5 -0
- package/dist/triggers/types.js +3 -0
- package/dist/triggers/types.js.map +1 -0
- package/package.json +1 -1
- package/dist/components/TriggerWorkflowButton.d.ts +0 -7
- package/dist/components/TriggerWorkflowButton.js +0 -46
- package/dist/components/TriggerWorkflowButton.js.map +0 -1
- package/dist/components/WorkflowExecutionStatus.d.ts +0 -6
- package/dist/components/WorkflowExecutionStatus.js +0 -287
- package/dist/components/WorkflowExecutionStatus.js.map +0 -1
- package/dist/exports/helpers.d.ts +0 -25
- package/dist/exports/helpers.js +0 -28
- package/dist/exports/helpers.js.map +0 -1
- package/dist/plugin/cron-scheduler.d.ts +0 -32
- package/dist/plugin/cron-scheduler.js +0 -537
- package/dist/plugin/cron-scheduler.js.map +0 -1
- package/dist/plugin/init-collection-hooks.d.ts +0 -4
- package/dist/plugin/init-collection-hooks.js +0 -100
- package/dist/plugin/init-collection-hooks.js.map +0 -1
- package/dist/plugin/init-global-hooks.d.ts +0 -3
- package/dist/plugin/init-global-hooks.js +0 -83
- package/dist/plugin/init-global-hooks.js.map +0 -1
- package/dist/plugin/init-step-tasks.d.ts +0 -3
- package/dist/plugin/init-step-tasks.js +0 -22
- package/dist/plugin/init-step-tasks.js.map +0 -1
- package/dist/plugin/init-webhook.d.ts +0 -2
- package/dist/plugin/init-webhook.js +0 -163
- package/dist/plugin/init-webhook.js.map +0 -1
- package/dist/plugin/init-workflow-hooks.d.ts +0 -6
- package/dist/plugin/init-workflow-hooks.js +0 -46
- package/dist/plugin/init-workflow-hooks.js.map +0 -1
- package/dist/utils/trigger-helpers.d.ts +0 -60
- package/dist/utils/trigger-helpers.js +0 -130
- package/dist/utils/trigger-helpers.js.map +0 -1
- package/dist/utils/trigger-presets.d.ts +0 -24
- package/dist/utils/trigger-presets.js +0 -177
- package/dist/utils/trigger-presets.js.map +0 -1
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ A comprehensive workflow automation plugin for PayloadCMS 3.x that enables visua
|
|
|
9
9
|
- 🔄 **Visual Workflow Builder** - Create complex workflows with drag-and-drop interface
|
|
10
10
|
- ⚡ **Parallel Execution** - Smart dependency resolution for optimal performance
|
|
11
11
|
- 🎯 **Multiple Triggers** - Collection hooks, webhooks, manual execution
|
|
12
|
+
- ⏰ **Scheduled Workflows** - Use webhook triggers with external cron services
|
|
12
13
|
- 📊 **Execution Tracking** - Complete history and monitoring of workflow runs
|
|
13
14
|
- 🔧 **Extensible Steps** - HTTP requests, document CRUD, email notifications
|
|
14
15
|
- 🔍 **JSONPath Integration** - Dynamic data interpolation and transformation
|
|
@@ -155,6 +156,66 @@ Use JSONPath to access workflow data:
|
|
|
155
156
|
- Node.js ^18.20.2 || >=20.9.0
|
|
156
157
|
- pnpm ^9 || ^10
|
|
157
158
|
|
|
159
|
+
## Environment Variables
|
|
160
|
+
|
|
161
|
+
Control plugin logging with these environment variables:
|
|
162
|
+
|
|
163
|
+
### `PAYLOAD_AUTOMATION_LOG_LEVEL`
|
|
164
|
+
Controls both configuration-time and runtime logging.
|
|
165
|
+
- **Values**: `silent`, `error`, `warn`, `info`, `debug`, `trace`
|
|
166
|
+
- **Default**: `warn`
|
|
167
|
+
- **Example**: `PAYLOAD_AUTOMATION_LOG_LEVEL=debug`
|
|
168
|
+
|
|
169
|
+
### `PAYLOAD_AUTOMATION_CONFIG_LOG_LEVEL` (optional)
|
|
170
|
+
Override log level specifically for configuration-time logs (plugin setup).
|
|
171
|
+
- **Values**: Same as above
|
|
172
|
+
- **Default**: Falls back to `PAYLOAD_AUTOMATION_LOG_LEVEL` or `warn`
|
|
173
|
+
- **Example**: `PAYLOAD_AUTOMATION_CONFIG_LOG_LEVEL=silent`
|
|
174
|
+
|
|
175
|
+
### Production Usage
|
|
176
|
+
For production, keep the default (`warn`) or use `error` or `silent`:
|
|
177
|
+
```bash
|
|
178
|
+
PAYLOAD_AUTOMATION_LOG_LEVEL=error npm start
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Development Usage
|
|
182
|
+
For debugging, use `debug` or `info`:
|
|
183
|
+
```bash
|
|
184
|
+
PAYLOAD_AUTOMATION_LOG_LEVEL=debug npm run dev
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Scheduled Workflows
|
|
188
|
+
|
|
189
|
+
For scheduled workflows, use **webhook triggers** with external cron services instead of built-in cron triggers:
|
|
190
|
+
|
|
191
|
+
### GitHub Actions (Free)
|
|
192
|
+
```yaml
|
|
193
|
+
# .github/workflows/daily-report.yml
|
|
194
|
+
on:
|
|
195
|
+
schedule:
|
|
196
|
+
- cron: '0 9 * * *' # Daily at 9 AM UTC
|
|
197
|
+
jobs:
|
|
198
|
+
trigger-workflow:
|
|
199
|
+
runs-on: ubuntu-latest
|
|
200
|
+
steps:
|
|
201
|
+
- run: curl -X POST https://your-app.com/api/workflows-webhook/daily-report
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Vercel Cron (Serverless)
|
|
205
|
+
```js
|
|
206
|
+
// api/cron/daily.js
|
|
207
|
+
export default async function handler(req, res) {
|
|
208
|
+
await fetch('https://your-app.com/api/workflows-webhook/daily-report', {
|
|
209
|
+
method: 'POST',
|
|
210
|
+
headers: { 'Content-Type': 'application/json' },
|
|
211
|
+
body: JSON.stringify({ source: 'vercel-cron' })
|
|
212
|
+
});
|
|
213
|
+
res.status(200).json({ success: true });
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Benefits**: Better reliability, proper process isolation, easier debugging, and leverages existing infrastructure.
|
|
218
|
+
|
|
158
219
|
## Documentation
|
|
159
220
|
|
|
160
221
|
Full documentation coming soon. For now, explore the development environment in the repository for examples and patterns.
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { parameter } from "../fields/parameter.js";
|
|
2
|
+
import { collectionTrigger, globalTrigger } from "../triggers/index.js";
|
|
3
|
+
export const createWorkflowCollection = (options)=>{
|
|
4
|
+
const steps = options.steps || [];
|
|
5
|
+
const triggers = (options.triggers || []).map((t)=>t(options)).concat(collectionTrigger(options), globalTrigger(options));
|
|
6
|
+
return {
|
|
2
7
|
slug: 'workflows',
|
|
3
8
|
access: {
|
|
4
9
|
create: ()=>true,
|
|
@@ -31,16 +36,6 @@ export const createWorkflowCollection = ({ collectionTriggers, steps, triggers }
|
|
|
31
36
|
description: 'Optional description of what this workflow does'
|
|
32
37
|
}
|
|
33
38
|
},
|
|
34
|
-
{
|
|
35
|
-
name: 'executionStatus',
|
|
36
|
-
type: 'ui',
|
|
37
|
-
admin: {
|
|
38
|
-
components: {
|
|
39
|
-
Field: '@xtr-dev/payload-automation/client#WorkflowExecutionStatus'
|
|
40
|
-
},
|
|
41
|
-
condition: (data)=>!!data?.id // Only show for existing workflows
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
39
|
{
|
|
45
40
|
name: 'triggers',
|
|
46
41
|
type: 'array',
|
|
@@ -49,11 +44,7 @@ export const createWorkflowCollection = ({ collectionTriggers, steps, triggers }
|
|
|
49
44
|
name: 'type',
|
|
50
45
|
type: 'select',
|
|
51
46
|
options: [
|
|
52
|
-
|
|
53
|
-
'webhook-trigger',
|
|
54
|
-
'global-trigger',
|
|
55
|
-
'cron-trigger',
|
|
56
|
-
...(triggers || []).map((t)=>t.slug)
|
|
47
|
+
...triggers.map((t)=>t.slug)
|
|
57
48
|
]
|
|
58
49
|
},
|
|
59
50
|
{
|
|
@@ -64,244 +55,8 @@ export const createWorkflowCollection = ({ collectionTriggers, steps, triggers }
|
|
|
64
55
|
},
|
|
65
56
|
defaultValue: {}
|
|
66
57
|
},
|
|
67
|
-
// Virtual fields for
|
|
68
|
-
|
|
69
|
-
name: '__builtin_collectionSlug',
|
|
70
|
-
type: 'select',
|
|
71
|
-
admin: {
|
|
72
|
-
condition: (_, siblingData)=>siblingData?.type === 'collection-trigger',
|
|
73
|
-
description: 'Collection that triggers the workflow'
|
|
74
|
-
},
|
|
75
|
-
hooks: {
|
|
76
|
-
afterRead: [
|
|
77
|
-
({ siblingData })=>{
|
|
78
|
-
return siblingData?.parameters?.collectionSlug || undefined;
|
|
79
|
-
}
|
|
80
|
-
],
|
|
81
|
-
beforeChange: [
|
|
82
|
-
({ siblingData, value })=>{
|
|
83
|
-
if (!siblingData.parameters) {
|
|
84
|
-
siblingData.parameters = {};
|
|
85
|
-
}
|
|
86
|
-
siblingData.parameters.collectionSlug = value;
|
|
87
|
-
return undefined // Virtual field, don't store directly
|
|
88
|
-
;
|
|
89
|
-
}
|
|
90
|
-
]
|
|
91
|
-
},
|
|
92
|
-
options: Object.keys(collectionTriggers || {}),
|
|
93
|
-
virtual: true
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
name: '__builtin_operation',
|
|
97
|
-
type: 'select',
|
|
98
|
-
admin: {
|
|
99
|
-
condition: (_, siblingData)=>siblingData?.type === 'collection-trigger',
|
|
100
|
-
description: 'Collection operation that triggers the workflow'
|
|
101
|
-
},
|
|
102
|
-
hooks: {
|
|
103
|
-
afterRead: [
|
|
104
|
-
({ siblingData })=>{
|
|
105
|
-
return siblingData?.parameters?.operation || undefined;
|
|
106
|
-
}
|
|
107
|
-
],
|
|
108
|
-
beforeChange: [
|
|
109
|
-
({ siblingData, value })=>{
|
|
110
|
-
if (!siblingData.parameters) {
|
|
111
|
-
siblingData.parameters = {};
|
|
112
|
-
}
|
|
113
|
-
siblingData.parameters.operation = value;
|
|
114
|
-
return undefined // Virtual field, don't store directly
|
|
115
|
-
;
|
|
116
|
-
}
|
|
117
|
-
]
|
|
118
|
-
},
|
|
119
|
-
options: [
|
|
120
|
-
'create',
|
|
121
|
-
'delete',
|
|
122
|
-
'read',
|
|
123
|
-
'update'
|
|
124
|
-
],
|
|
125
|
-
virtual: true
|
|
126
|
-
},
|
|
127
|
-
// Virtual fields for webhook trigger
|
|
128
|
-
{
|
|
129
|
-
name: '__builtin_webhookPath',
|
|
130
|
-
type: 'text',
|
|
131
|
-
admin: {
|
|
132
|
-
condition: (_, siblingData)=>siblingData?.type === 'webhook-trigger',
|
|
133
|
-
description: 'URL path for the webhook (e.g., "my-webhook"). Full URL will be /api/workflows-webhook/my-webhook'
|
|
134
|
-
},
|
|
135
|
-
hooks: {
|
|
136
|
-
afterRead: [
|
|
137
|
-
({ siblingData })=>{
|
|
138
|
-
return siblingData?.parameters?.webhookPath || undefined;
|
|
139
|
-
}
|
|
140
|
-
],
|
|
141
|
-
beforeChange: [
|
|
142
|
-
({ siblingData, value })=>{
|
|
143
|
-
if (!siblingData.parameters) {
|
|
144
|
-
siblingData.parameters = {};
|
|
145
|
-
}
|
|
146
|
-
siblingData.parameters.webhookPath = value;
|
|
147
|
-
return undefined // Virtual field, don't store directly
|
|
148
|
-
;
|
|
149
|
-
}
|
|
150
|
-
]
|
|
151
|
-
},
|
|
152
|
-
validate: (value, { siblingData })=>{
|
|
153
|
-
if (siblingData?.type === 'webhook-trigger' && !value && !siblingData?.parameters?.webhookPath) {
|
|
154
|
-
return 'Webhook path is required for webhook triggers';
|
|
155
|
-
}
|
|
156
|
-
return true;
|
|
157
|
-
},
|
|
158
|
-
virtual: true
|
|
159
|
-
},
|
|
160
|
-
// Virtual fields for global trigger
|
|
161
|
-
{
|
|
162
|
-
name: '__builtin_global',
|
|
163
|
-
type: 'select',
|
|
164
|
-
admin: {
|
|
165
|
-
condition: (_, siblingData)=>siblingData?.type === 'global-trigger',
|
|
166
|
-
description: 'Global that triggers the workflow'
|
|
167
|
-
},
|
|
168
|
-
hooks: {
|
|
169
|
-
afterRead: [
|
|
170
|
-
({ siblingData })=>{
|
|
171
|
-
return siblingData?.parameters?.global || undefined;
|
|
172
|
-
}
|
|
173
|
-
],
|
|
174
|
-
beforeChange: [
|
|
175
|
-
({ siblingData, value })=>{
|
|
176
|
-
if (!siblingData.parameters) {
|
|
177
|
-
siblingData.parameters = {};
|
|
178
|
-
}
|
|
179
|
-
siblingData.parameters.global = value;
|
|
180
|
-
return undefined // Virtual field, don't store directly
|
|
181
|
-
;
|
|
182
|
-
}
|
|
183
|
-
]
|
|
184
|
-
},
|
|
185
|
-
options: [],
|
|
186
|
-
virtual: true
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
name: '__builtin_globalOperation',
|
|
190
|
-
type: 'select',
|
|
191
|
-
admin: {
|
|
192
|
-
condition: (_, siblingData)=>siblingData?.type === 'global-trigger',
|
|
193
|
-
description: 'Global operation that triggers the workflow'
|
|
194
|
-
},
|
|
195
|
-
hooks: {
|
|
196
|
-
afterRead: [
|
|
197
|
-
({ siblingData })=>{
|
|
198
|
-
return siblingData?.parameters?.globalOperation || undefined;
|
|
199
|
-
}
|
|
200
|
-
],
|
|
201
|
-
beforeChange: [
|
|
202
|
-
({ siblingData, value })=>{
|
|
203
|
-
if (!siblingData.parameters) {
|
|
204
|
-
siblingData.parameters = {};
|
|
205
|
-
}
|
|
206
|
-
siblingData.parameters.globalOperation = value;
|
|
207
|
-
return undefined // Virtual field, don't store directly
|
|
208
|
-
;
|
|
209
|
-
}
|
|
210
|
-
]
|
|
211
|
-
},
|
|
212
|
-
options: [
|
|
213
|
-
'update'
|
|
214
|
-
],
|
|
215
|
-
virtual: true
|
|
216
|
-
},
|
|
217
|
-
// Virtual fields for cron trigger
|
|
218
|
-
{
|
|
219
|
-
name: '__builtin_cronExpression',
|
|
220
|
-
type: 'text',
|
|
221
|
-
admin: {
|
|
222
|
-
condition: (_, siblingData)=>siblingData?.type === 'cron-trigger',
|
|
223
|
-
description: 'Cron expression for scheduled execution (e.g., "0 0 * * *" for daily at midnight)',
|
|
224
|
-
placeholder: '0 0 * * *'
|
|
225
|
-
},
|
|
226
|
-
hooks: {
|
|
227
|
-
afterRead: [
|
|
228
|
-
({ siblingData })=>{
|
|
229
|
-
return siblingData?.parameters?.cronExpression || undefined;
|
|
230
|
-
}
|
|
231
|
-
],
|
|
232
|
-
beforeChange: [
|
|
233
|
-
({ siblingData, value })=>{
|
|
234
|
-
if (!siblingData.parameters) {
|
|
235
|
-
siblingData.parameters = {};
|
|
236
|
-
}
|
|
237
|
-
siblingData.parameters.cronExpression = value;
|
|
238
|
-
return undefined // Virtual field, don't store directly
|
|
239
|
-
;
|
|
240
|
-
}
|
|
241
|
-
]
|
|
242
|
-
},
|
|
243
|
-
validate: (value, { siblingData })=>{
|
|
244
|
-
const cronValue = value || siblingData?.parameters?.cronExpression;
|
|
245
|
-
if (siblingData?.type === 'cron-trigger' && !cronValue) {
|
|
246
|
-
return 'Cron expression is required for cron triggers';
|
|
247
|
-
}
|
|
248
|
-
// Validate cron expression format if provided
|
|
249
|
-
if (siblingData?.type === 'cron-trigger' && cronValue) {
|
|
250
|
-
// Basic format validation - should be 5 parts separated by spaces
|
|
251
|
-
const cronParts = cronValue.trim().split(/\s+/);
|
|
252
|
-
if (cronParts.length !== 5) {
|
|
253
|
-
return 'Invalid cron expression format. Expected 5 parts: "minute hour day month weekday" (e.g., "0 9 * * 1")';
|
|
254
|
-
}
|
|
255
|
-
// Additional validation could use node-cron but we avoid dynamic imports here
|
|
256
|
-
// The main validation happens at runtime in the cron scheduler
|
|
257
|
-
}
|
|
258
|
-
return true;
|
|
259
|
-
},
|
|
260
|
-
virtual: true
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
name: '__builtin_timezone',
|
|
264
|
-
type: 'text',
|
|
265
|
-
admin: {
|
|
266
|
-
condition: (_, siblingData)=>siblingData?.type === 'cron-trigger',
|
|
267
|
-
description: 'Timezone for cron execution (e.g., "America/New_York", "Europe/London"). Defaults to UTC.',
|
|
268
|
-
placeholder: 'UTC'
|
|
269
|
-
},
|
|
270
|
-
defaultValue: 'UTC',
|
|
271
|
-
hooks: {
|
|
272
|
-
afterRead: [
|
|
273
|
-
({ siblingData })=>{
|
|
274
|
-
return siblingData?.parameters?.timezone || 'UTC';
|
|
275
|
-
}
|
|
276
|
-
],
|
|
277
|
-
beforeChange: [
|
|
278
|
-
({ siblingData, value })=>{
|
|
279
|
-
if (!siblingData.parameters) {
|
|
280
|
-
siblingData.parameters = {};
|
|
281
|
-
}
|
|
282
|
-
siblingData.parameters.timezone = value || 'UTC';
|
|
283
|
-
return undefined // Virtual field, don't store directly
|
|
284
|
-
;
|
|
285
|
-
}
|
|
286
|
-
]
|
|
287
|
-
},
|
|
288
|
-
validate: (value, { siblingData })=>{
|
|
289
|
-
const tzValue = value || siblingData?.parameters?.timezone;
|
|
290
|
-
if (siblingData?.type === 'cron-trigger' && tzValue) {
|
|
291
|
-
try {
|
|
292
|
-
// Test if timezone is valid by trying to create a date with it
|
|
293
|
-
new Intl.DateTimeFormat('en', {
|
|
294
|
-
timeZone: tzValue
|
|
295
|
-
});
|
|
296
|
-
return true;
|
|
297
|
-
} catch {
|
|
298
|
-
return `Invalid timezone: ${tzValue}. Please use a valid IANA timezone identifier (e.g., "America/New_York", "Europe/London")`;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
return true;
|
|
302
|
-
},
|
|
303
|
-
virtual: true
|
|
304
|
-
},
|
|
58
|
+
// Virtual fields for custom triggers
|
|
59
|
+
...triggers.flatMap((t)=>(t.parameters || []).map((p)=>parameter(t.slug, p))),
|
|
305
60
|
{
|
|
306
61
|
name: 'condition',
|
|
307
62
|
type: 'text',
|
|
@@ -309,11 +64,7 @@ export const createWorkflowCollection = ({ collectionTriggers, steps, triggers }
|
|
|
309
64
|
description: 'JSONPath expression that must evaluate to true for this trigger to execute the workflow (e.g., "$.trigger.doc.status == \'published\'")'
|
|
310
65
|
},
|
|
311
66
|
required: false
|
|
312
|
-
}
|
|
313
|
-
// Virtual fields for custom triggers
|
|
314
|
-
// Note: Custom trigger fields from trigger-helpers already have unique names
|
|
315
|
-
// We just need to pass them through without modification
|
|
316
|
-
...(triggers || []).flatMap((t)=>t.inputs || [])
|
|
67
|
+
}
|
|
317
68
|
]
|
|
318
69
|
},
|
|
319
70
|
{
|
|
@@ -321,52 +72,25 @@ export const createWorkflowCollection = ({ collectionTriggers, steps, triggers }
|
|
|
321
72
|
type: 'array',
|
|
322
73
|
fields: [
|
|
323
74
|
{
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
name: 'step',
|
|
328
|
-
type: 'select',
|
|
329
|
-
options: steps.map((t)=>t.slug)
|
|
330
|
-
},
|
|
331
|
-
{
|
|
332
|
-
name: 'name',
|
|
333
|
-
type: 'text'
|
|
334
|
-
}
|
|
335
|
-
]
|
|
75
|
+
name: 'name',
|
|
76
|
+
type: 'text',
|
|
77
|
+
defaultValue: 'Unnamed Step'
|
|
336
78
|
},
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
afterRead: [
|
|
353
|
-
...field.hooks?.afterRead || [],
|
|
354
|
-
({ siblingData })=>{
|
|
355
|
-
// Read from step input data using original field name
|
|
356
|
-
return siblingData?.[originalName] || field.defaultValue;
|
|
357
|
-
}
|
|
358
|
-
],
|
|
359
|
-
beforeChange: [
|
|
360
|
-
...field.hooks?.beforeChange || [],
|
|
361
|
-
({ siblingData, value })=>{
|
|
362
|
-
// Store in step data using original field name
|
|
363
|
-
siblingData[originalName] = value;
|
|
364
|
-
return undefined; // Don't store the prefixed field
|
|
365
|
-
}
|
|
366
|
-
]
|
|
367
|
-
};
|
|
368
|
-
return resultField;
|
|
369
|
-
})),
|
|
79
|
+
{
|
|
80
|
+
name: 'type',
|
|
81
|
+
type: 'select',
|
|
82
|
+
options: steps.map((t)=>t.slug)
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'parameters',
|
|
86
|
+
type: 'json',
|
|
87
|
+
admin: {
|
|
88
|
+
hidden: true
|
|
89
|
+
},
|
|
90
|
+
defaultValue: {}
|
|
91
|
+
},
|
|
92
|
+
// Virtual fields for custom triggers
|
|
93
|
+
...steps.flatMap((step)=>(step.inputSchema || []).map((s)=>parameter(step.slug, s))),
|
|
370
94
|
{
|
|
371
95
|
name: 'dependencies',
|
|
372
96
|
type: 'text',
|
|
@@ -393,6 +117,7 @@ export const createWorkflowCollection = ({ collectionTriggers, steps, triggers }
|
|
|
393
117
|
},
|
|
394
118
|
maxPerDoc: 10
|
|
395
119
|
}
|
|
396
|
-
}
|
|
120
|
+
};
|
|
121
|
+
};
|
|
397
122
|
|
|
398
123
|
//# sourceMappingURL=Workflow.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/collections/Workflow.ts"],"sourcesContent":["import type {CollectionConfig, Field} from 'payload'\n\nimport type {WorkflowsPluginConfig} from \"../plugin/config-types.js\"\n\nexport const createWorkflowCollection: <T extends string>(options: WorkflowsPluginConfig<T>) => CollectionConfig = ({\n collectionTriggers,\n steps,\n triggers\n }) => ({\n slug: 'workflows',\n access: {\n create: () => true,\n delete: () => true,\n read: () => true,\n update: () => true,\n },\n admin: {\n defaultColumns: ['name', 'updatedAt'],\n description: 'Create and manage automated 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 the workflow',\n },\n required: true,\n },\n {\n name: 'description',\n type: 'textarea',\n admin: {\n description: 'Optional description of what this workflow does',\n },\n },\n {\n name: 'executionStatus',\n type: 'ui',\n admin: {\n components: {\n Field: '@xtr-dev/payload-automation/client#WorkflowExecutionStatus'\n },\n condition: (data) => !!data?.id // Only show for existing workflows\n }\n },\n {\n name: 'triggers',\n type: 'array',\n fields: [\n {\n name: 'type',\n type: 'select',\n options: [\n 'collection-trigger',\n 'webhook-trigger',\n 'global-trigger',\n 'cron-trigger',\n ...(triggers || []).map(t => t.slug)\n ]\n },\n {\n name: 'parameters',\n type: 'json',\n admin: {\n hidden: true,\n },\n defaultValue: {}\n },\n // Virtual fields for collection trigger\n {\n name: '__builtin_collectionSlug',\n type: 'select',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'collection-trigger',\n description: 'Collection that triggers the workflow',\n },\n hooks: {\n afterRead: [\n ({ siblingData }) => {\n return siblingData?.parameters?.collectionSlug || undefined\n }\n ],\n beforeChange: [\n ({ siblingData, value }) => {\n if (!siblingData.parameters) {siblingData.parameters = {}}\n siblingData.parameters.collectionSlug = value\n return undefined // Virtual field, don't store directly\n }\n ]\n },\n options: Object.keys(collectionTriggers || {}),\n virtual: true,\n },\n {\n name: '__builtin_operation',\n type: 'select',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'collection-trigger',\n description: 'Collection operation that triggers the workflow',\n },\n hooks: {\n afterRead: [\n ({ siblingData }) => {\n return siblingData?.parameters?.operation || undefined\n }\n ],\n beforeChange: [\n ({ siblingData, value }) => {\n if (!siblingData.parameters) {siblingData.parameters = {}}\n siblingData.parameters.operation = value\n return undefined // Virtual field, don't store directly\n }\n ]\n },\n options: [\n 'create',\n 'delete',\n 'read',\n 'update',\n ],\n virtual: true,\n },\n // Virtual fields for webhook trigger\n {\n name: '__builtin_webhookPath',\n type: 'text',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'webhook-trigger',\n description: 'URL path for the webhook (e.g., \"my-webhook\"). Full URL will be /api/workflows-webhook/my-webhook',\n },\n hooks: {\n afterRead: [\n ({ siblingData }) => {\n return siblingData?.parameters?.webhookPath || undefined\n }\n ],\n beforeChange: [\n ({ siblingData, value }) => {\n if (!siblingData.parameters) {siblingData.parameters = {}}\n siblingData.parameters.webhookPath = value\n return undefined // Virtual field, don't store directly\n }\n ]\n },\n validate: (value: any, {siblingData}: any) => {\n if (siblingData?.type === 'webhook-trigger' && !value && !siblingData?.parameters?.webhookPath) {\n return 'Webhook path is required for webhook triggers'\n }\n return true\n },\n virtual: true,\n },\n // Virtual fields for global trigger\n {\n name: '__builtin_global',\n type: 'select',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'global-trigger',\n description: 'Global that triggers the workflow',\n },\n hooks: {\n afterRead: [\n ({ siblingData }) => {\n return siblingData?.parameters?.global || undefined\n }\n ],\n beforeChange: [\n ({ siblingData, value }) => {\n if (!siblingData.parameters) {siblingData.parameters = {}}\n siblingData.parameters.global = value\n return undefined // Virtual field, don't store directly\n }\n ]\n },\n options: [], // Will be populated dynamically based on available globals\n virtual: true,\n },\n {\n name: '__builtin_globalOperation',\n type: 'select',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'global-trigger',\n description: 'Global operation that triggers the workflow',\n },\n hooks: {\n afterRead: [\n ({ siblingData }) => {\n return siblingData?.parameters?.globalOperation || undefined\n }\n ],\n beforeChange: [\n ({ siblingData, value }) => {\n if (!siblingData.parameters) {siblingData.parameters = {}}\n siblingData.parameters.globalOperation = value\n return undefined // Virtual field, don't store directly\n }\n ]\n },\n options: [\n 'update'\n ],\n virtual: true,\n },\n // Virtual fields for cron trigger\n {\n name: '__builtin_cronExpression',\n type: 'text',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'cron-trigger',\n description: 'Cron expression for scheduled execution (e.g., \"0 0 * * *\" for daily at midnight)',\n placeholder: '0 0 * * *'\n },\n hooks: {\n afterRead: [\n ({ siblingData }) => {\n return siblingData?.parameters?.cronExpression || undefined\n }\n ],\n beforeChange: [\n ({ siblingData, value }) => {\n if (!siblingData.parameters) {siblingData.parameters = {}}\n siblingData.parameters.cronExpression = value\n return undefined // Virtual field, don't store directly\n }\n ]\n },\n validate: (value: any, {siblingData}: any) => {\n const cronValue = value || siblingData?.parameters?.cronExpression\n if (siblingData?.type === 'cron-trigger' && !cronValue) {\n return 'Cron expression is required for cron triggers'\n }\n\n // Validate cron expression format if provided\n if (siblingData?.type === 'cron-trigger' && cronValue) {\n // Basic format validation - should be 5 parts separated by spaces\n const cronParts = cronValue.trim().split(/\\s+/)\n if (cronParts.length !== 5) {\n return 'Invalid cron expression format. Expected 5 parts: \"minute hour day month weekday\" (e.g., \"0 9 * * 1\")'\n }\n\n // Additional validation could use node-cron but we avoid dynamic imports here\n // The main validation happens at runtime in the cron scheduler\n }\n\n return true\n },\n virtual: true,\n },\n {\n name: '__builtin_timezone',\n type: 'text',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'cron-trigger',\n description: 'Timezone for cron execution (e.g., \"America/New_York\", \"Europe/London\"). Defaults to UTC.',\n placeholder: 'UTC'\n },\n defaultValue: 'UTC',\n hooks: {\n afterRead: [\n ({ siblingData }) => {\n return siblingData?.parameters?.timezone || 'UTC'\n }\n ],\n beforeChange: [\n ({ siblingData, value }) => {\n if (!siblingData.parameters) {siblingData.parameters = {}}\n siblingData.parameters.timezone = value || 'UTC'\n return undefined // Virtual field, don't store directly\n }\n ]\n },\n validate: (value: any, {siblingData}: any) => {\n const tzValue = value || siblingData?.parameters?.timezone\n if (siblingData?.type === 'cron-trigger' && tzValue) {\n try {\n // Test if timezone is valid by trying to create a date with it\n new Intl.DateTimeFormat('en', {timeZone: tzValue})\n return true\n } catch {\n return `Invalid timezone: ${tzValue}. Please use a valid IANA timezone identifier (e.g., \"America/New_York\", \"Europe/London\")`\n }\n }\n return true\n },\n virtual: true,\n },\n {\n name: 'condition',\n type: 'text',\n admin: {\n description: 'JSONPath expression that must evaluate to true for this trigger to execute the workflow (e.g., \"$.trigger.doc.status == \\'published\\'\")'\n },\n required: false\n },\n // Virtual fields for custom triggers\n // Note: Custom trigger fields from trigger-helpers already have unique names\n // We just need to pass them through without modification\n ...(triggers || []).flatMap(t => (t.inputs || []))\n ]\n },\n {\n name: 'steps',\n type: 'array',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'step',\n type: 'select',\n options: steps.map(t => t.slug)\n },\n {\n name: 'name',\n type: 'text',\n }\n ]\n },\n ...(steps || []).flatMap(step => (step.inputSchema || []).map(field => {\n const originalName = (field as any).name;\n const resultField: any = {\n ...field,\n // Prefix field name with step slug to avoid conflicts\n name: `__step_${step.slug}_${originalName}`,\n admin: {\n ...(field.admin || {}),\n condition: (...args: any[]) => args[1]?.step === step.slug && (\n (field.admin as any)?.condition ?\n (field.admin as any).condition.call(this, ...args) :\n true\n ),\n },\n virtual: true,\n };\n\n // Add hooks to store/retrieve from the step's input data\n resultField.hooks = {\n ...((field as any).hooks || {}),\n afterRead: [\n ...(((field as any).hooks)?.afterRead || []),\n ({ siblingData }: any) => {\n // Read from step input data using original field name\n return siblingData?.[originalName] || (field as any).defaultValue;\n }\n ],\n beforeChange: [\n ...(((field as any).hooks)?.beforeChange || []),\n ({ siblingData, value }: any) => {\n // Store in step data using original field name\n siblingData[originalName] = value;\n return undefined; // Don't store the prefixed field\n }\n ]\n };\n\n return resultField as Field;\n })),\n {\n name: 'dependencies',\n type: 'text',\n admin: {\n description: 'Step names that must complete before this step can run'\n },\n hasMany: true,\n required: false\n },\n {\n name: 'condition',\n type: 'text',\n admin: {\n description: 'JSONPath expression that must evaluate to true for this step to execute (e.g., \"$.trigger.doc.status == \\'published\\'\")'\n },\n required: false\n },\n ],\n }\n ],\n versions: {\n drafts: {\n autosave: false,\n },\n maxPerDoc: 10,\n },\n})\n"],"names":["createWorkflowCollection","collectionTriggers","steps","triggers","slug","access","create","delete","read","update","admin","defaultColumns","description","group","useAsTitle","fields","name","type","required","components","Field","condition","data","id","options","map","t","hidden","defaultValue","_","siblingData","hooks","afterRead","parameters","collectionSlug","undefined","beforeChange","value","Object","keys","virtual","operation","webhookPath","validate","global","globalOperation","placeholder","cronExpression","cronValue","cronParts","trim","split","length","timezone","tzValue","Intl","DateTimeFormat","timeZone","flatMap","inputs","step","inputSchema","field","originalName","resultField","args","call","hasMany","versions","drafts","autosave","maxPerDoc"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/collections/Workflow.ts"],"sourcesContent":["import type {CollectionConfig} from 'payload'\n\nimport type {WorkflowsPluginConfig} from \"../plugin/config-types.js\"\n\nimport {parameter} from \"../fields/parameter.js\"\nimport {collectionTrigger, globalTrigger} from \"../triggers/index.js\"\n\nexport const createWorkflowCollection: <T extends string>(options: WorkflowsPluginConfig<T>) => CollectionConfig = (options) => {\n const steps = options.steps || []\n const triggers = (options.triggers || []).map(t => t(options)).concat(collectionTrigger(options), globalTrigger(options))\n return {\n slug: 'workflows',\n access: {\n create: () => true,\n delete: () => true,\n read: () => true,\n update: () => true,\n },\n admin: {\n defaultColumns: ['name', 'updatedAt'],\n description: 'Create and manage automated 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 the workflow',\n },\n required: true,\n },\n {\n name: 'description',\n type: 'textarea',\n admin: {\n description: 'Optional description of what this workflow does',\n },\n },\n {\n name: 'triggers',\n type: 'array',\n fields: [\n {\n name: 'type',\n type: 'select',\n options: [\n ...triggers.map(t => t.slug)\n ]\n },\n {\n name: 'parameters',\n type: 'json',\n admin: {\n hidden: true,\n },\n defaultValue: {}\n },\n // Virtual fields for custom triggers\n ...triggers.flatMap(t => (t.parameters || []).map(p => parameter(t.slug, p as any))),\n {\n name: 'condition',\n type: 'text',\n admin: {\n description: 'JSONPath expression that must evaluate to true for this trigger to execute the workflow (e.g., \"$.trigger.doc.status == \\'published\\'\")'\n },\n required: false\n },\n ]\n },\n {\n name: 'steps',\n type: 'array',\n fields: [\n {\n name: 'name',\n type: 'text',\n defaultValue: 'Unnamed Step'\n },\n {\n name: 'type',\n type: 'select',\n options: steps.map(t => t.slug)\n },\n {\n name: 'parameters',\n type: 'json',\n admin: {\n hidden: true,\n },\n defaultValue: {}\n },\n // Virtual fields for custom triggers\n ...steps.flatMap(step => (step.inputSchema || []).map(s => parameter(step.slug, s as any))),\n {\n name: 'dependencies',\n type: 'text',\n admin: {\n description: 'Step names that must complete before this step can run'\n },\n hasMany: true,\n required: false\n },\n {\n name: 'condition',\n type: 'text',\n admin: {\n description: 'JSONPath expression that must evaluate to true for this step to execute (e.g., \"$.trigger.doc.status == \\'published\\'\")'\n },\n required: false\n },\n ],\n }\n ],\n versions: {\n drafts: {\n autosave: false,\n },\n maxPerDoc: 10,\n },\n }\n}\n"],"names":["parameter","collectionTrigger","globalTrigger","createWorkflowCollection","options","steps","triggers","map","t","concat","slug","access","create","delete","read","update","admin","defaultColumns","description","group","useAsTitle","fields","name","type","required","hidden","defaultValue","flatMap","parameters","p","step","inputSchema","s","hasMany","versions","drafts","autosave","maxPerDoc"],"mappings":"AAIA,SAAQA,SAAS,QAAO,yBAAwB;AAChD,SAAQC,iBAAiB,EAAEC,aAAa,QAAO,uBAAsB;AAErE,OAAO,MAAMC,2BAAsG,CAACC;IAClH,MAAMC,QAAQD,QAAQC,KAAK,IAAI,EAAE;IACjC,MAAMC,WAAW,AAACF,CAAAA,QAAQE,QAAQ,IAAI,EAAE,AAAD,EAAGC,GAAG,CAACC,CAAAA,IAAKA,EAAEJ,UAAUK,MAAM,CAACR,kBAAkBG,UAAUF,cAAcE;IAChH,OAAO;QACLM,MAAM;QACNC,QAAQ;YACNC,QAAQ,IAAM;YACdC,QAAQ,IAAM;YACdC,MAAM,IAAM;YACZC,QAAQ,IAAM;QAChB;QACAC,OAAO;YACLC,gBAAgB;gBAAC;gBAAQ;aAAY;YACrCC,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;gBACNF,QAAQ;oBACN;wBACEC,MAAM;wBACNC,MAAM;wBACNnB,SAAS;+BACJE,SAASC,GAAG,CAACC,CAAAA,IAAKA,EAAEE,IAAI;yBAC5B;oBACH;oBACA;wBACEY,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLS,QAAQ;wBACV;wBACAC,cAAc,CAAC;oBACjB;oBACA,qCAAqC;uBAClCpB,SAASqB,OAAO,CAACnB,CAAAA,IAAK,AAACA,CAAAA,EAAEoB,UAAU,IAAI,EAAE,AAAD,EAAGrB,GAAG,CAACsB,CAAAA,IAAK7B,UAAUQ,EAAEE,IAAI,EAAEmB;oBACzE;wBACEP,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;wBACf;wBACAM,UAAU;oBACZ;iBACD;YACH;YACA;gBACEF,MAAM;gBACNC,MAAM;gBACNF,QAAQ;oBACN;wBACEC,MAAM;wBACNC,MAAM;wBACNG,cAAc;oBAChB;oBACA;wBACEJ,MAAM;wBACNC,MAAM;wBACNnB,SAASC,MAAME,GAAG,CAACC,CAAAA,IAAKA,EAAEE,IAAI;oBAChC;oBACA;wBACEY,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLS,QAAQ;wBACV;wBACAC,cAAc,CAAC;oBACjB;oBACA,qCAAqC;uBAClCrB,MAAMsB,OAAO,CAACG,CAAAA,OAAQ,AAACA,CAAAA,KAAKC,WAAW,IAAI,EAAE,AAAD,EAAGxB,GAAG,CAACyB,CAAAA,IAAKhC,UAAU8B,KAAKpB,IAAI,EAAEsB;oBAChF;wBACEV,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;wBACf;wBACAe,SAAS;wBACTT,UAAU;oBACZ;oBACA;wBACEF,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;wBACf;wBACAM,UAAU;oBACZ;iBACD;YACH;SACD;QACDU,UAAU;YACRC,QAAQ;gBACNC,UAAU;YACZ;YACAC,WAAW;QACb;IACF;AACF,EAAC"}
|
|
@@ -170,9 +170,9 @@ export const ErrorDisplay = ({ value, onChange, readOnly = false })=>{
|
|
|
170
170
|
marginBottom: expanded ? '12px' : '0'
|
|
171
171
|
},
|
|
172
172
|
children: /*#__PURE__*/ _jsxs(Button, {
|
|
173
|
+
buttonStyle: "secondary",
|
|
173
174
|
onClick: ()=>setExpanded(!expanded),
|
|
174
175
|
size: "small",
|
|
175
|
-
buttonStyle: "secondary",
|
|
176
176
|
children: [
|
|
177
177
|
expanded ? 'Hide' : 'Show',
|
|
178
178
|
" Technical Details"
|
|
@@ -294,11 +294,11 @@ export const ErrorDisplay = ({ value, onChange, readOnly = false })=>{
|
|
|
294
294
|
]
|
|
295
295
|
}),
|
|
296
296
|
!readOnly && onChange && /*#__PURE__*/ _jsx("textarea", {
|
|
297
|
-
value: value,
|
|
298
297
|
onChange: (e)=>onChange(e.target.value),
|
|
299
298
|
style: {
|
|
300
299
|
display: 'none'
|
|
301
|
-
}
|
|
300
|
+
},
|
|
301
|
+
value: value
|
|
302
302
|
})
|
|
303
303
|
]
|
|
304
304
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ErrorDisplay.tsx"],"sourcesContent":["'use client'\n\nimport React, { useState } from 'react'\nimport { Button } from '@payloadcms/ui'\n\ninterface ErrorDisplayProps {\n value?: string\n onChange?: (value: string) => void\n readOnly?: boolean\n path?: string\n}\n\nexport const ErrorDisplay: React.FC<ErrorDisplayProps> = ({ \n value, \n onChange, \n readOnly = false \n}) => {\n const [expanded, setExpanded] = useState(false)\n\n if (!value) {\n return null\n }\n\n // Parse common error patterns\n const parseError = (error: string) => {\n // Check for different error types and provide user-friendly messages\n if (error.includes('Request timeout')) {\n return {\n type: 'timeout',\n title: 'Request Timeout',\n message: 'The HTTP request took too long to complete. Consider increasing the timeout value or checking the target server.',\n technical: error\n }\n }\n \n if (error.includes('Network error') || error.includes('fetch')) {\n return {\n type: 'network',\n title: 'Network Error',\n message: 'Unable to connect to the target server. Please check the URL and network connectivity.',\n technical: error\n }\n }\n \n if (error.includes('Hook execution failed')) {\n return {\n type: 'hook',\n title: 'Workflow Hook Failed',\n message: 'The workflow trigger hook encountered an error. This may be due to PayloadCMS initialization issues.',\n technical: error\n }\n }\n \n if (error.includes('Executor not available')) {\n return {\n type: 'executor',\n title: 'Workflow Engine Unavailable',\n message: 'The workflow execution engine is not properly initialized. Try restarting the server.',\n technical: error\n }\n }\n \n if (error.includes('Collection slug is required') || error.includes('Document data is required')) {\n return {\n type: 'validation',\n title: 'Invalid Input Data',\n message: 'Required fields are missing from the workflow step configuration. Please check your step inputs.',\n technical: error\n }\n }\n \n if (error.includes('status') && error.includes('4')) {\n return {\n type: 'client',\n title: 'Client Error (4xx)',\n message: 'The request was rejected by the server. Check your API credentials and request format.',\n technical: error\n }\n }\n \n if (error.includes('status') && error.includes('5')) {\n return {\n type: 'server',\n title: 'Server Error (5xx)',\n message: 'The target server encountered an error. This is usually temporary - try again later.',\n technical: error\n }\n }\n\n // Generic error\n return {\n type: 'generic',\n title: 'Workflow Error',\n message: 'An error occurred during workflow execution. See technical details below.',\n technical: error\n }\n }\n\n const errorInfo = parseError(value)\n\n const getErrorIcon = (type: string) => {\n switch (type) {\n case 'timeout': return '⏰'\n case 'network': return '🌐'\n case 'hook': return '🔗'\n case 'executor': return '⚙️'\n case 'validation': return '📋'\n case 'client': return '🚫'\n case 'server': return '🔥'\n default: return '❗'\n }\n }\n\n const getErrorColor = (type: string) => {\n switch (type) {\n case 'timeout': return '#F59E0B'\n case 'network': return '#EF4444'\n case 'hook': return '#8B5CF6'\n case 'executor': return '#6B7280'\n case 'validation': return '#F59E0B'\n case 'client': return '#EF4444'\n case 'server': return '#DC2626'\n default: return '#EF4444'\n }\n }\n\n const errorColor = getErrorColor(errorInfo.type)\n\n return (\n <div style={{ \n border: `2px solid ${errorColor}30`,\n borderRadius: '8px',\n backgroundColor: `${errorColor}08`,\n padding: '16px',\n marginTop: '8px'\n }}>\n {/* Error Header */}\n <div style={{ \n display: 'flex', \n alignItems: 'center', \n gap: '12px',\n marginBottom: '12px'\n }}>\n <span style={{ fontSize: '24px' }}>\n {getErrorIcon(errorInfo.type)}\n </span>\n <div>\n <h4 style={{ \n margin: 0, \n color: errorColor,\n fontSize: '16px',\n fontWeight: '600'\n }}>\n {errorInfo.title}\n </h4>\n <p style={{ \n margin: '4px 0 0 0',\n color: '#6B7280',\n fontSize: '14px',\n lineHeight: '1.4'\n }}>\n {errorInfo.message}\n </p>\n </div>\n </div>\n\n {/* Technical Details Toggle */}\n <div>\n <div style={{ marginBottom: expanded ? '12px' : '0' }}>\n <Button\n onClick={() => setExpanded(!expanded)}\n size=\"small\"\n buttonStyle=\"secondary\"\n >\n {expanded ? 'Hide' : 'Show'} Technical Details\n </Button>\n </div>\n \n {expanded && (\n <div style={{\n backgroundColor: '#F8F9FA',\n border: '1px solid #E5E7EB',\n borderRadius: '6px',\n padding: '12px',\n fontFamily: 'monospace',\n fontSize: '13px',\n color: '#374151',\n whiteSpace: 'pre-wrap',\n overflowX: 'auto'\n }}>\n {errorInfo.technical}\n </div>\n )}\n </div>\n\n {/* Quick Actions */}\n <div style={{ \n marginTop: '12px',\n padding: '12px',\n backgroundColor: `${errorColor}10`,\n borderRadius: '6px',\n fontSize: '13px'\n }}>\n <strong>💡 Quick fixes:</strong>\n <ul style={{ margin: '8px 0 0 0', paddingLeft: '20px' }}>\n {errorInfo.type === 'timeout' && (\n <>\n <li>Increase the timeout value in step configuration</li>\n <li>Check if the target server is responding slowly</li>\n </>\n )}\n {errorInfo.type === 'network' && (\n <>\n <li>Verify the URL is correct and accessible</li>\n <li>Check firewall and network connectivity</li>\n </>\n )}\n {errorInfo.type === 'hook' && (\n <>\n <li>Restart the PayloadCMS server</li>\n <li>Check server logs for initialization errors</li>\n </>\n )}\n {errorInfo.type === 'executor' && (\n <>\n <li>Restart the PayloadCMS application</li>\n <li>Verify the automation plugin is properly configured</li>\n </>\n )}\n {errorInfo.type === 'validation' && (\n <>\n <li>Check all required fields are filled in the workflow step</li>\n <li>Verify JSONPath expressions in step inputs</li>\n </>\n )}\n {(errorInfo.type === 'client' || errorInfo.type === 'server') && (\n <>\n <li>Check API credentials and permissions</li>\n <li>Verify the request format matches API expectations</li>\n <li>Try the request manually to test the endpoint</li>\n </>\n )}\n {errorInfo.type === 'generic' && (\n <>\n <li>Check the workflow configuration</li>\n <li>Review server logs for more details</li>\n <li>Try running the workflow again</li>\n </>\n )}\n </ul>\n </div>\n\n {/* Hidden textarea for editing if needed */}\n {!readOnly && onChange && (\n <textarea\n value={value}\n onChange={(e) => onChange(e.target.value)}\n style={{ display: 'none' }}\n />\n )}\n </div>\n )\n}"],"names":["React","useState","Button","ErrorDisplay","value","onChange","readOnly","expanded","setExpanded","parseError","error","includes","type","title","message","technical","errorInfo","getErrorIcon","getErrorColor","errorColor","div","style","border","borderRadius","backgroundColor","padding","marginTop","display","alignItems","gap","marginBottom","span","fontSize","h4","margin","color","fontWeight","p","lineHeight","onClick","size","buttonStyle","fontFamily","whiteSpace","overflowX","strong","ul","paddingLeft","li","textarea","e","target"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/ErrorDisplay.tsx"],"sourcesContent":["'use client'\n\nimport React, { useState } from 'react'\nimport { Button } from '@payloadcms/ui'\n\ninterface ErrorDisplayProps {\n value?: string\n onChange?: (value: string) => void\n readOnly?: boolean\n path?: string\n}\n\nexport const ErrorDisplay: React.FC<ErrorDisplayProps> = ({\n value,\n onChange,\n readOnly = false\n}) => {\n const [expanded, setExpanded] = useState(false)\n\n if (!value) {\n return null\n }\n\n // Parse common error patterns\n const parseError = (error: string) => {\n // Check for different error types and provide user-friendly messages\n if (error.includes('Request timeout')) {\n return {\n type: 'timeout',\n title: 'Request Timeout',\n message: 'The HTTP request took too long to complete. Consider increasing the timeout value or checking the target server.',\n technical: error\n }\n }\n\n if (error.includes('Network error') || error.includes('fetch')) {\n return {\n type: 'network',\n title: 'Network Error',\n message: 'Unable to connect to the target server. Please check the URL and network connectivity.',\n technical: error\n }\n }\n\n if (error.includes('Hook execution failed')) {\n return {\n type: 'hook',\n title: 'Workflow Hook Failed',\n message: 'The workflow trigger hook encountered an error. This may be due to PayloadCMS initialization issues.',\n technical: error\n }\n }\n\n if (error.includes('Executor not available')) {\n return {\n type: 'executor',\n title: 'Workflow Engine Unavailable',\n message: 'The workflow execution engine is not properly initialized. Try restarting the server.',\n technical: error\n }\n }\n\n if (error.includes('Collection slug is required') || error.includes('Document data is required')) {\n return {\n type: 'validation',\n title: 'Invalid Input Data',\n message: 'Required fields are missing from the workflow step configuration. Please check your step inputs.',\n technical: error\n }\n }\n\n if (error.includes('status') && error.includes('4')) {\n return {\n type: 'client',\n title: 'Client Error (4xx)',\n message: 'The request was rejected by the server. Check your API credentials and request format.',\n technical: error\n }\n }\n\n if (error.includes('status') && error.includes('5')) {\n return {\n type: 'server',\n title: 'Server Error (5xx)',\n message: 'The target server encountered an error. This is usually temporary - try again later.',\n technical: error\n }\n }\n\n // Generic error\n return {\n type: 'generic',\n title: 'Workflow Error',\n message: 'An error occurred during workflow execution. See technical details below.',\n technical: error\n }\n }\n\n const errorInfo = parseError(value)\n\n const getErrorIcon = (type: string) => {\n switch (type) {\n case 'timeout': return '⏰'\n case 'network': return '🌐'\n case 'hook': return '🔗'\n case 'executor': return '⚙️'\n case 'validation': return '📋'\n case 'client': return '🚫'\n case 'server': return '🔥'\n default: return '❗'\n }\n }\n\n const getErrorColor = (type: string) => {\n switch (type) {\n case 'timeout': return '#F59E0B'\n case 'network': return '#EF4444'\n case 'hook': return '#8B5CF6'\n case 'executor': return '#6B7280'\n case 'validation': return '#F59E0B'\n case 'client': return '#EF4444'\n case 'server': return '#DC2626'\n default: return '#EF4444'\n }\n }\n\n const errorColor = getErrorColor(errorInfo.type)\n\n return (\n <div style={{\n border: `2px solid ${errorColor}30`,\n borderRadius: '8px',\n backgroundColor: `${errorColor}08`,\n padding: '16px',\n marginTop: '8px'\n }}>\n {/* Error Header */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n marginBottom: '12px'\n }}>\n <span style={{ fontSize: '24px' }}>\n {getErrorIcon(errorInfo.type)}\n </span>\n <div>\n <h4 style={{\n margin: 0,\n color: errorColor,\n fontSize: '16px',\n fontWeight: '600'\n }}>\n {errorInfo.title}\n </h4>\n <p style={{\n margin: '4px 0 0 0',\n color: '#6B7280',\n fontSize: '14px',\n lineHeight: '1.4'\n }}>\n {errorInfo.message}\n </p>\n </div>\n </div>\n\n {/* Technical Details Toggle */}\n <div>\n <div style={{ marginBottom: expanded ? '12px' : '0' }}>\n <Button\n buttonStyle=\"secondary\"\n onClick={() => setExpanded(!expanded)}\n size=\"small\"\n >\n {expanded ? 'Hide' : 'Show'} Technical Details\n </Button>\n </div>\n\n {expanded && (\n <div style={{\n backgroundColor: '#F8F9FA',\n border: '1px solid #E5E7EB',\n borderRadius: '6px',\n padding: '12px',\n fontFamily: 'monospace',\n fontSize: '13px',\n color: '#374151',\n whiteSpace: 'pre-wrap',\n overflowX: 'auto'\n }}>\n {errorInfo.technical}\n </div>\n )}\n </div>\n\n {/* Quick Actions */}\n <div style={{\n marginTop: '12px',\n padding: '12px',\n backgroundColor: `${errorColor}10`,\n borderRadius: '6px',\n fontSize: '13px'\n }}>\n <strong>💡 Quick fixes:</strong>\n <ul style={{ margin: '8px 0 0 0', paddingLeft: '20px' }}>\n {errorInfo.type === 'timeout' && (\n <>\n <li>Increase the timeout value in step configuration</li>\n <li>Check if the target server is responding slowly</li>\n </>\n )}\n {errorInfo.type === 'network' && (\n <>\n <li>Verify the URL is correct and accessible</li>\n <li>Check firewall and network connectivity</li>\n </>\n )}\n {errorInfo.type === 'hook' && (\n <>\n <li>Restart the PayloadCMS server</li>\n <li>Check server logs for initialization errors</li>\n </>\n )}\n {errorInfo.type === 'executor' && (\n <>\n <li>Restart the PayloadCMS application</li>\n <li>Verify the automation plugin is properly configured</li>\n </>\n )}\n {errorInfo.type === 'validation' && (\n <>\n <li>Check all required fields are filled in the workflow step</li>\n <li>Verify JSONPath expressions in step inputs</li>\n </>\n )}\n {(errorInfo.type === 'client' || errorInfo.type === 'server') && (\n <>\n <li>Check API credentials and permissions</li>\n <li>Verify the request format matches API expectations</li>\n <li>Try the request manually to test the endpoint</li>\n </>\n )}\n {errorInfo.type === 'generic' && (\n <>\n <li>Check the workflow configuration</li>\n <li>Review server logs for more details</li>\n <li>Try running the workflow again</li>\n </>\n )}\n </ul>\n </div>\n\n {/* Hidden textarea for editing if needed */}\n {!readOnly && onChange && (\n <textarea\n onChange={(e) => onChange(e.target.value)}\n style={{ display: 'none' }}\n value={value}\n />\n )}\n </div>\n )\n}\n"],"names":["React","useState","Button","ErrorDisplay","value","onChange","readOnly","expanded","setExpanded","parseError","error","includes","type","title","message","technical","errorInfo","getErrorIcon","getErrorColor","errorColor","div","style","border","borderRadius","backgroundColor","padding","marginTop","display","alignItems","gap","marginBottom","span","fontSize","h4","margin","color","fontWeight","p","lineHeight","buttonStyle","onClick","size","fontFamily","whiteSpace","overflowX","strong","ul","paddingLeft","li","textarea","e","target"],"mappings":"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"}
|