@xtr-dev/payload-automation 0.0.21 → 0.0.23

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 (44) hide show
  1. package/README.md +73 -2
  2. package/dist/collections/Workflow.js +19 -7
  3. package/dist/collections/Workflow.js.map +1 -1
  4. package/dist/collections/WorkflowRuns.js +14 -7
  5. package/dist/collections/WorkflowRuns.js.map +1 -1
  6. package/dist/components/StatusCell.d.ts +6 -0
  7. package/dist/components/StatusCell.js +75 -0
  8. package/dist/components/StatusCell.js.map +1 -0
  9. package/dist/components/WorkflowExecutionStatus.d.ts +6 -0
  10. package/dist/components/WorkflowExecutionStatus.js +287 -0
  11. package/dist/components/WorkflowExecutionStatus.js.map +1 -0
  12. package/dist/core/workflow-executor.d.ts +32 -0
  13. package/dist/core/workflow-executor.js +162 -7
  14. package/dist/core/workflow-executor.js.map +1 -1
  15. package/dist/exports/client.d.ts +2 -0
  16. package/dist/exports/client.js +4 -1
  17. package/dist/exports/client.js.map +1 -1
  18. package/dist/plugin/index.js +131 -42
  19. package/dist/plugin/index.js.map +1 -1
  20. package/dist/plugin/init-step-tasks.js +15 -1
  21. package/dist/plugin/init-step-tasks.js.map +1 -1
  22. package/dist/steps/create-document.js +1 -1
  23. package/dist/steps/create-document.js.map +1 -1
  24. package/dist/steps/delete-document.js +2 -2
  25. package/dist/steps/delete-document.js.map +1 -1
  26. package/dist/steps/http-request-handler.js +229 -10
  27. package/dist/steps/http-request-handler.js.map +1 -1
  28. package/dist/steps/http-request.d.ts +147 -4
  29. package/dist/steps/http-request.js +189 -3
  30. package/dist/steps/http-request.js.map +1 -1
  31. package/dist/steps/read-document.js +2 -2
  32. package/dist/steps/read-document.js.map +1 -1
  33. package/dist/steps/send-email.js +5 -5
  34. package/dist/steps/send-email.js.map +1 -1
  35. package/dist/steps/update-document.js +2 -2
  36. package/dist/steps/update-document.js.map +1 -1
  37. package/dist/test/create-document-step.test.js +378 -0
  38. package/dist/test/create-document-step.test.js.map +1 -0
  39. package/dist/test/http-request-step.test.js +361 -0
  40. package/dist/test/http-request-step.test.js.map +1 -0
  41. package/dist/test/workflow-executor.test.js +530 -0
  42. package/dist/test/workflow-executor.test.js.map +1 -0
  43. package/package.json +4 -1
  44. package/dist/test/basic.test.d.ts +0 -1
@@ -2,7 +2,21 @@ export function initStepTasks(pluginOptions, payload, logger) {
2
2
  logger.info({
3
3
  stepCount: pluginOptions.steps.length,
4
4
  steps: pluginOptions.steps.map((s)=>s.slug)
5
- }, 'Initializing step tasks');
5
+ }, 'Step tasks were registered during config phase');
6
+ // Verify that the tasks are available in the job system
7
+ const availableTasks = payload.config.jobs?.tasks?.map((t)=>t.slug) || [];
8
+ const pluginTasks = pluginOptions.steps.map((s)=>s.slug);
9
+ pluginTasks.forEach((taskSlug)=>{
10
+ if (availableTasks.includes(taskSlug)) {
11
+ logger.info({
12
+ taskSlug
13
+ }, 'Step task confirmed available in job system');
14
+ } else {
15
+ logger.error({
16
+ taskSlug
17
+ }, 'Step task not found in job system - this will cause execution failures');
18
+ }
19
+ });
6
20
  }
7
21
 
8
22
  //# sourceMappingURL=init-step-tasks.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugin/init-step-tasks.ts"],"sourcesContent":["import type {Payload} from \"payload\"\nimport type {Logger} from \"pino\"\n\nimport type {WorkflowsPluginConfig} from \"./config-types.js\"\n\nexport function initStepTasks<T extends string>(pluginOptions: WorkflowsPluginConfig<T>, payload: Payload, logger: Payload['logger']) {\n logger.info({ stepCount: pluginOptions.steps.length, steps: pluginOptions.steps.map(s => s.slug) }, 'Initializing step tasks')\n\n}\n"],"names":["initStepTasks","pluginOptions","payload","logger","info","stepCount","steps","length","map","s","slug"],"mappings":"AAKA,OAAO,SAASA,cAAgCC,aAAuC,EAAEC,OAAgB,EAAEC,MAAyB;IAClIA,OAAOC,IAAI,CAAC;QAAEC,WAAWJ,cAAcK,KAAK,CAACC,MAAM;QAAED,OAAOL,cAAcK,KAAK,CAACE,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI;IAAE,GAAG;AAEtG"}
1
+ {"version":3,"sources":["../../src/plugin/init-step-tasks.ts"],"sourcesContent":["import type {Payload} from \"payload\"\nimport type {Logger} from \"pino\"\n\nimport type {WorkflowsPluginConfig} from \"./config-types.js\"\n\nexport function initStepTasks<T extends string>(pluginOptions: WorkflowsPluginConfig<T>, payload: Payload, logger: Payload['logger']) {\n logger.info({ stepCount: pluginOptions.steps.length, steps: pluginOptions.steps.map(s => s.slug) }, 'Step tasks were registered during config phase')\n\n // Verify that the tasks are available in the job system\n const availableTasks = payload.config.jobs?.tasks?.map(t => t.slug) || []\n const pluginTasks = pluginOptions.steps.map(s => s.slug)\n \n pluginTasks.forEach(taskSlug => {\n if (availableTasks.includes(taskSlug)) {\n logger.info({ taskSlug }, 'Step task confirmed available in job system')\n } else {\n logger.error({ taskSlug }, 'Step task not found in job system - this will cause execution failures')\n }\n })\n}\n"],"names":["initStepTasks","pluginOptions","payload","logger","info","stepCount","steps","length","map","s","slug","availableTasks","config","jobs","tasks","t","pluginTasks","forEach","taskSlug","includes","error"],"mappings":"AAKA,OAAO,SAASA,cAAgCC,aAAuC,EAAEC,OAAgB,EAAEC,MAAyB;IAClIA,OAAOC,IAAI,CAAC;QAAEC,WAAWJ,cAAcK,KAAK,CAACC,MAAM;QAAED,OAAOL,cAAcK,KAAK,CAACE,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI;IAAE,GAAG;IAEpG,wDAAwD;IACxD,MAAMC,iBAAiBT,QAAQU,MAAM,CAACC,IAAI,EAAEC,OAAON,IAAIO,CAAAA,IAAKA,EAAEL,IAAI,KAAK,EAAE;IACzE,MAAMM,cAAcf,cAAcK,KAAK,CAACE,GAAG,CAACC,CAAAA,IAAKA,EAAEC,IAAI;IAEvDM,YAAYC,OAAO,CAACC,CAAAA;QAClB,IAAIP,eAAeQ,QAAQ,CAACD,WAAW;YACrCf,OAAOC,IAAI,CAAC;gBAAEc;YAAS,GAAG;QAC5B,OAAO;YACLf,OAAOiB,KAAK,CAAC;gBAAEF;YAAS,GAAG;QAC7B;IACF;AACF"}
@@ -15,7 +15,7 @@ export const CreateDocumentStepTask = {
15
15
  name: 'data',
16
16
  type: 'json',
17
17
  admin: {
18
- description: 'The document data to create'
18
+ description: 'The document data to create. Use JSONPath to reference trigger data (e.g., {"title": "$.trigger.doc.title", "author": "$.trigger.doc.author"})'
19
19
  },
20
20
  required: true
21
21
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/steps/create-document.ts"],"sourcesContent":["import type { TaskConfig } from \"payload\"\n\nimport { createDocumentHandler } from \"./create-document-handler.js\"\n\nexport const CreateDocumentStepTask = {\n slug: 'create-document',\n handler: createDocumentHandler,\n inputSchema: [\n {\n name: 'collectionSlug',\n type: 'text',\n admin: {\n description: 'The collection slug to create a document in'\n },\n required: true\n },\n {\n name: 'data',\n type: 'json',\n admin: {\n description: 'The document data to create'\n },\n required: true\n },\n {\n name: 'draft',\n type: 'checkbox',\n admin: {\n description: 'Create as draft (if collection has drafts enabled)'\n }\n },\n {\n name: 'locale',\n type: 'text',\n admin: {\n description: 'Locale for the document (if localization is enabled)'\n }\n }\n ],\n outputSchema: [\n {\n name: 'doc',\n type: 'json',\n admin: {\n description: 'The created document'\n }\n },\n {\n name: 'id',\n type: 'text',\n admin: {\n description: 'The ID of the created document'\n }\n }\n ]\n} satisfies TaskConfig<'create-document'>"],"names":["createDocumentHandler","CreateDocumentStepTask","slug","handler","inputSchema","name","type","admin","description","required","outputSchema"],"mappings":"AAEA,SAASA,qBAAqB,QAAQ,+BAA8B;AAEpE,OAAO,MAAMC,yBAAyB;IACpCC,MAAM;IACNC,SAASH;IACTI,aAAa;QACX;YACEC,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;YACAC,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;YACAC,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;KACD;IACDE,cAAc;QACZ;YACEL,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;KACD;AACH,EAAyC"}
1
+ {"version":3,"sources":["../../src/steps/create-document.ts"],"sourcesContent":["import type { TaskConfig } from \"payload\"\n\nimport { createDocumentHandler } from \"./create-document-handler.js\"\n\nexport const CreateDocumentStepTask = {\n slug: 'create-document',\n handler: createDocumentHandler,\n inputSchema: [\n {\n name: 'collectionSlug',\n type: 'text',\n admin: {\n description: 'The collection slug to create a document in'\n },\n required: true\n },\n {\n name: 'data',\n type: 'json',\n admin: {\n description: 'The document data to create. Use JSONPath to reference trigger data (e.g., {\"title\": \"$.trigger.doc.title\", \"author\": \"$.trigger.doc.author\"})'\n },\n required: true\n },\n {\n name: 'draft',\n type: 'checkbox',\n admin: {\n description: 'Create as draft (if collection has drafts enabled)'\n }\n },\n {\n name: 'locale',\n type: 'text',\n admin: {\n description: 'Locale for the document (if localization is enabled)'\n }\n }\n ],\n outputSchema: [\n {\n name: 'doc',\n type: 'json',\n admin: {\n description: 'The created document'\n }\n },\n {\n name: 'id',\n type: 'text',\n admin: {\n description: 'The ID of the created document'\n }\n }\n ]\n} satisfies TaskConfig<'create-document'>"],"names":["createDocumentHandler","CreateDocumentStepTask","slug","handler","inputSchema","name","type","admin","description","required","outputSchema"],"mappings":"AAEA,SAASA,qBAAqB,QAAQ,+BAA8B;AAEpE,OAAO,MAAMC,yBAAyB;IACpCC,MAAM;IACNC,SAASH;IACTI,aAAa;QACX;YACEC,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;YACAC,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;YACAC,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;KACD;IACDE,cAAc;QACZ;YACEL,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;KACD;AACH,EAAyC"}
@@ -15,14 +15,14 @@ export const DeleteDocumentStepTask = {
15
15
  name: 'id',
16
16
  type: 'text',
17
17
  admin: {
18
- description: 'The ID of a specific document to delete (leave empty to delete multiple)'
18
+ description: 'The ID of a specific document to delete. Use JSONPath (e.g., "$.trigger.doc.id"). Leave empty to delete multiple.'
19
19
  }
20
20
  },
21
21
  {
22
22
  name: 'where',
23
23
  type: 'json',
24
24
  admin: {
25
- description: 'Query conditions to find documents to delete (used when ID is not provided)'
25
+ description: 'Query conditions to find documents to delete when ID is not provided. Use JSONPath in values (e.g., {"author": "$.trigger.doc.author"})'
26
26
  }
27
27
  }
28
28
  ],
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/steps/delete-document.ts"],"sourcesContent":["import type { TaskConfig } from \"payload\"\n\nimport { deleteDocumentHandler } from \"./delete-document-handler.js\"\n\nexport const DeleteDocumentStepTask = {\n slug: 'delete-document',\n handler: deleteDocumentHandler,\n inputSchema: [\n {\n name: 'collectionSlug',\n type: 'text',\n admin: {\n description: 'The collection slug to delete from'\n },\n required: true\n },\n {\n name: 'id',\n type: 'text',\n admin: {\n description: 'The ID of a specific document to delete (leave empty to delete multiple)'\n }\n },\n {\n name: 'where',\n type: 'json',\n admin: {\n description: 'Query conditions to find documents to delete (used when ID is not provided)'\n }\n }\n ],\n outputSchema: [\n {\n name: 'doc',\n type: 'json',\n admin: {\n description: 'The deleted document(s)'\n }\n },\n {\n name: 'deletedCount',\n type: 'number',\n admin: {\n description: 'Number of documents deleted'\n }\n }\n ]\n} satisfies TaskConfig<'delete-document'>"],"names":["deleteDocumentHandler","DeleteDocumentStepTask","slug","handler","inputSchema","name","type","admin","description","required","outputSchema"],"mappings":"AAEA,SAASA,qBAAqB,QAAQ,+BAA8B;AAEpE,OAAO,MAAMC,yBAAyB;IACpCC,MAAM;IACNC,SAASH;IACTI,aAAa;QACX;YACEC,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;YACAC,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;KACD;IACDE,cAAc;QACZ;YACEL,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;KACD;AACH,EAAyC"}
1
+ {"version":3,"sources":["../../src/steps/delete-document.ts"],"sourcesContent":["import type { TaskConfig } from \"payload\"\n\nimport { deleteDocumentHandler } from \"./delete-document-handler.js\"\n\nexport const DeleteDocumentStepTask = {\n slug: 'delete-document',\n handler: deleteDocumentHandler,\n inputSchema: [\n {\n name: 'collectionSlug',\n type: 'text',\n admin: {\n description: 'The collection slug to delete from'\n },\n required: true\n },\n {\n name: 'id',\n type: 'text',\n admin: {\n description: 'The ID of a specific document to delete. Use JSONPath (e.g., \"$.trigger.doc.id\"). Leave empty to delete multiple.'\n }\n },\n {\n name: 'where',\n type: 'json',\n admin: {\n description: 'Query conditions to find documents to delete when ID is not provided. Use JSONPath in values (e.g., {\"author\": \"$.trigger.doc.author\"})'\n }\n }\n ],\n outputSchema: [\n {\n name: 'doc',\n type: 'json',\n admin: {\n description: 'The deleted document(s)'\n }\n },\n {\n name: 'deletedCount',\n type: 'number',\n admin: {\n description: 'Number of documents deleted'\n }\n }\n ]\n} satisfies TaskConfig<'delete-document'>"],"names":["deleteDocumentHandler","DeleteDocumentStepTask","slug","handler","inputSchema","name","type","admin","description","required","outputSchema"],"mappings":"AAEA,SAASA,qBAAqB,QAAQ,+BAA8B;AAEpE,OAAO,MAAMC,yBAAyB;IACpCC,MAAM;IACNC,SAASH;IACTI,aAAa;QACX;YACEC,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;YACAC,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;KACD;IACDE,cAAc;QACZ;YACEL,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aAAa;YACf;QACF;KACD;AACH,EAAyC"}
@@ -1,14 +1,233 @@
1
- export const httpStepHandler = async ({ input })=>{
2
- if (!input) {
3
- throw new Error('No input provided');
1
+ export const httpStepHandler = async ({ input, req })=>{
2
+ const startTime = Date.now() // Move startTime to outer scope
3
+ ;
4
+ try {
5
+ if (!input || !input.url) {
6
+ return {
7
+ output: {
8
+ status: 0,
9
+ statusText: 'Invalid Input',
10
+ headers: {},
11
+ body: '',
12
+ data: null,
13
+ duration: 0,
14
+ error: 'URL is required for HTTP request'
15
+ },
16
+ state: 'failed'
17
+ };
18
+ }
19
+ const typedInput = input;
20
+ // Validate URL
21
+ try {
22
+ new URL(typedInput.url);
23
+ } catch (error) {
24
+ return {
25
+ output: {
26
+ status: 0,
27
+ statusText: 'Invalid URL',
28
+ headers: {},
29
+ body: '',
30
+ data: null,
31
+ duration: 0,
32
+ error: `Invalid URL: ${typedInput.url}`
33
+ },
34
+ state: 'failed'
35
+ };
36
+ }
37
+ // Prepare request options
38
+ const method = (typedInput.method || 'GET').toUpperCase();
39
+ const timeout = typedInput.timeout || 30000;
40
+ const headers = {
41
+ 'User-Agent': 'PayloadCMS-Automation/1.0',
42
+ ...typedInput.headers
43
+ };
44
+ // Handle authentication
45
+ if (typedInput.authentication) {
46
+ switch(typedInput.authentication.type){
47
+ case 'bearer':
48
+ if (typedInput.authentication.token) {
49
+ headers['Authorization'] = `Bearer ${typedInput.authentication.token}`;
50
+ }
51
+ break;
52
+ case 'basic':
53
+ if (typedInput.authentication.username && typedInput.authentication.password) {
54
+ const credentials = btoa(`${typedInput.authentication.username}:${typedInput.authentication.password}`);
55
+ headers['Authorization'] = `Basic ${credentials}`;
56
+ }
57
+ break;
58
+ case 'apikey':
59
+ if (typedInput.authentication.headerName && typedInput.authentication.headerValue) {
60
+ headers[typedInput.authentication.headerName] = typedInput.authentication.headerValue;
61
+ }
62
+ break;
63
+ }
64
+ }
65
+ // Prepare request body
66
+ let requestBody;
67
+ if ([
68
+ 'POST',
69
+ 'PUT',
70
+ 'PATCH'
71
+ ].includes(method) && typedInput.body) {
72
+ if (typeof typedInput.body === 'string') {
73
+ requestBody = typedInput.body;
74
+ } else {
75
+ requestBody = JSON.stringify(typedInput.body);
76
+ if (!headers['Content-Type']) {
77
+ headers['Content-Type'] = 'application/json';
78
+ }
79
+ }
80
+ }
81
+ // Create abort controller for timeout
82
+ const abortController = new AbortController();
83
+ const timeoutId = setTimeout(()=>abortController.abort(), timeout);
84
+ // Retry logic
85
+ const maxRetries = Math.min(Math.max(typedInput.retries || 0, 0), 5);
86
+ const retryDelay = Math.max(typedInput.retryDelay || 1000, 100);
87
+ let lastError = null;
88
+ for(let attempt = 0; attempt <= maxRetries; attempt++){
89
+ try {
90
+ // Add delay for retry attempts
91
+ if (attempt > 0) {
92
+ req?.payload?.logger?.info({
93
+ attempt: attempt + 1,
94
+ maxRetries: maxRetries + 1,
95
+ url: typedInput.url,
96
+ delay: retryDelay
97
+ }, 'HTTP request retry attempt');
98
+ await new Promise((resolve)=>setTimeout(resolve, retryDelay));
99
+ }
100
+ const response = await fetch(typedInput.url, {
101
+ method,
102
+ headers,
103
+ body: requestBody,
104
+ signal: abortController.signal
105
+ });
106
+ clearTimeout(timeoutId);
107
+ const duration = Date.now() - startTime;
108
+ // Parse response
109
+ const responseText = await response.text();
110
+ let parsedData = null;
111
+ try {
112
+ const contentType = response.headers.get('content-type') || '';
113
+ if (contentType.includes('application/json') || contentType.includes('text/json')) {
114
+ parsedData = JSON.parse(responseText);
115
+ }
116
+ } catch (parseError) {
117
+ // Not JSON, that's fine
118
+ }
119
+ // Convert headers to plain object
120
+ const responseHeaders = {};
121
+ response.headers.forEach((value, key)=>{
122
+ responseHeaders[key] = value;
123
+ });
124
+ const output = {
125
+ status: response.status,
126
+ statusText: response.statusText,
127
+ headers: responseHeaders,
128
+ body: responseText,
129
+ data: parsedData,
130
+ duration
131
+ };
132
+ req?.payload?.logger?.info({
133
+ url: typedInput.url,
134
+ method,
135
+ status: response.status,
136
+ duration,
137
+ attempt: attempt + 1
138
+ }, 'HTTP request completed');
139
+ return {
140
+ output,
141
+ // Always return 'succeeded' for completed HTTP requests, even with error status codes (4xx/5xx).
142
+ // This preserves error information in the output for workflow conditional logic.
143
+ // Only network errors, timeouts, and connection failures should result in 'failed' state.
144
+ // This design allows workflows to handle HTTP errors gracefully rather than failing completely.
145
+ state: 'succeeded'
146
+ };
147
+ } catch (error) {
148
+ lastError = error instanceof Error ? error : new Error('Unknown error');
149
+ // Handle specific error types
150
+ if (error instanceof Error) {
151
+ if (error.name === 'AbortError') {
152
+ lastError = new Error(`Request timeout after ${timeout}ms`);
153
+ } else if (error.message.includes('fetch')) {
154
+ lastError = new Error(`Network error: ${error.message}`);
155
+ }
156
+ }
157
+ req?.payload?.logger?.warn({
158
+ url: typedInput.url,
159
+ method,
160
+ attempt: attempt + 1,
161
+ maxRetries: maxRetries + 1,
162
+ error: lastError.message
163
+ }, 'HTTP request attempt failed');
164
+ // Don't retry on certain errors
165
+ if (lastError.message.includes('Invalid URL') || lastError.message.includes('TypeError') || attempt >= maxRetries) {
166
+ break;
167
+ }
168
+ }
169
+ }
170
+ clearTimeout(timeoutId);
171
+ const duration = Date.now() - startTime;
172
+ // All retries exhausted
173
+ const finalError = lastError || new Error('HTTP request failed');
174
+ req?.payload?.logger?.error({
175
+ url: typedInput.url,
176
+ method,
177
+ totalAttempts: maxRetries + 1,
178
+ duration,
179
+ error: finalError.message
180
+ }, 'HTTP request failed after all retries');
181
+ // Include detailed error information in the output
182
+ // Even though PayloadCMS will discard this for failed tasks,
183
+ // we include it here for potential future PayloadCMS improvements
184
+ const errorDetails = {
185
+ errorType: finalError.message.includes('timeout') ? 'timeout' : finalError.message.includes('ENOTFOUND') ? 'dns' : finalError.message.includes('ECONNREFUSED') ? 'connection' : 'network',
186
+ duration,
187
+ attempts: maxRetries + 1,
188
+ finalError: finalError.message,
189
+ context: {
190
+ url: typedInput.url,
191
+ method,
192
+ timeout: typedInput.timeout,
193
+ headers: typedInput.headers
194
+ }
195
+ };
196
+ // Return comprehensive output (PayloadCMS will discard it for failed state, but we try anyway)
197
+ return {
198
+ output: {
199
+ status: 0,
200
+ statusText: 'Request Failed',
201
+ headers: {},
202
+ body: '',
203
+ data: null,
204
+ duration,
205
+ error: finalError.message,
206
+ errorDetails
207
+ },
208
+ state: 'failed'
209
+ };
210
+ } catch (unexpectedError) {
211
+ // Handle any unexpected errors that weren't caught above
212
+ const error = unexpectedError instanceof Error ? unexpectedError : new Error('Unexpected error');
213
+ req?.payload?.logger?.error({
214
+ error: error.message,
215
+ stack: error.stack,
216
+ input: input?.url || 'unknown'
217
+ }, 'Unexpected error in HTTP request handler');
218
+ return {
219
+ output: {
220
+ status: 0,
221
+ statusText: 'Handler Error',
222
+ headers: {},
223
+ body: '',
224
+ data: null,
225
+ duration: Date.now() - startTime,
226
+ error: `HTTP request handler error: ${error.message}`
227
+ },
228
+ state: 'failed'
229
+ };
4
230
  }
5
- const response = await fetch(input.url);
6
- return {
7
- output: {
8
- response: await response.text()
9
- },
10
- state: response.ok ? 'succeeded' : undefined
11
- };
12
231
  };
13
232
 
14
233
  //# sourceMappingURL=http-request-handler.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/steps/http-request-handler.ts"],"sourcesContent":["import type {TaskHandler} from \"payload\"\n\nexport const httpStepHandler: TaskHandler<'http-request-step'> = async ({input}) => {\n if (!input) {\n throw new Error('No input provided')\n }\n const response = await fetch(input.url)\n return {\n output: {\n response: await response.text()\n },\n state: response.ok ? 'succeeded' : undefined\n }\n}\n"],"names":["httpStepHandler","input","Error","response","fetch","url","output","text","state","ok","undefined"],"mappings":"AAEA,OAAO,MAAMA,kBAAoD,OAAO,EAACC,KAAK,EAAC;IAC7E,IAAI,CAACA,OAAO;QACV,MAAM,IAAIC,MAAM;IAClB;IACA,MAAMC,WAAW,MAAMC,MAAMH,MAAMI,GAAG;IACtC,OAAO;QACLC,QAAQ;YACNH,UAAU,MAAMA,SAASI,IAAI;QAC/B;QACAC,OAAOL,SAASM,EAAE,GAAG,cAAcC;IACrC;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/steps/http-request-handler.ts"],"sourcesContent":["import type {TaskHandler} from \"payload\"\n\ninterface HttpRequestInput {\n url: string\n method?: string\n headers?: Record<string, string>\n body?: any\n timeout?: number\n authentication?: {\n type?: 'none' | 'bearer' | 'basic' | 'apikey'\n token?: string\n username?: string\n password?: string\n headerName?: string\n headerValue?: string\n }\n retries?: number\n retryDelay?: number\n}\n\nexport const httpStepHandler: TaskHandler<'http-request-step'> = async ({input, req}) => {\n const startTime = Date.now() // Move startTime to outer scope\n \n try {\n if (!input || !input.url) {\n return {\n output: {\n status: 0,\n statusText: 'Invalid Input',\n headers: {},\n body: '',\n data: null,\n duration: 0,\n error: 'URL is required for HTTP request'\n },\n state: 'failed'\n }\n }\n\n const typedInput = input as HttpRequestInput\n \n // Validate URL\n try {\n new URL(typedInput.url)\n } catch (error) {\n return {\n output: {\n status: 0,\n statusText: 'Invalid URL',\n headers: {},\n body: '',\n data: null,\n duration: 0,\n error: `Invalid URL: ${typedInput.url}`\n },\n state: 'failed'\n }\n }\n\n // Prepare request options\n const method = (typedInput.method || 'GET').toUpperCase()\n const timeout = typedInput.timeout || 30000\n const headers: Record<string, string> = {\n 'User-Agent': 'PayloadCMS-Automation/1.0',\n ...typedInput.headers\n }\n\n // Handle authentication\n if (typedInput.authentication) {\n switch (typedInput.authentication.type) {\n case 'bearer':\n if (typedInput.authentication.token) {\n headers['Authorization'] = `Bearer ${typedInput.authentication.token}`\n }\n break\n case 'basic':\n if (typedInput.authentication.username && typedInput.authentication.password) {\n const credentials = btoa(`${typedInput.authentication.username}:${typedInput.authentication.password}`)\n headers['Authorization'] = `Basic ${credentials}`\n }\n break\n case 'apikey':\n if (typedInput.authentication.headerName && typedInput.authentication.headerValue) {\n headers[typedInput.authentication.headerName] = typedInput.authentication.headerValue\n }\n break\n }\n }\n\n // Prepare request body\n let requestBody: string | undefined\n if (['POST', 'PUT', 'PATCH'].includes(method) && typedInput.body) {\n if (typeof typedInput.body === 'string') {\n requestBody = typedInput.body\n } else {\n requestBody = JSON.stringify(typedInput.body)\n if (!headers['Content-Type']) {\n headers['Content-Type'] = 'application/json'\n }\n }\n }\n\n // Create abort controller for timeout\n const abortController = new AbortController()\n const timeoutId = setTimeout(() => abortController.abort(), timeout)\n\n // Retry logic\n const maxRetries = Math.min(Math.max(typedInput.retries || 0, 0), 5)\n const retryDelay = Math.max(typedInput.retryDelay || 1000, 100)\n\n let lastError: Error | null = null\n \n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n // Add delay for retry attempts\n if (attempt > 0) {\n req?.payload?.logger?.info({\n attempt: attempt + 1,\n maxRetries: maxRetries + 1,\n url: typedInput.url,\n delay: retryDelay\n }, 'HTTP request retry attempt')\n \n await new Promise(resolve => setTimeout(resolve, retryDelay))\n }\n\n const response = await fetch(typedInput.url, {\n method,\n headers,\n body: requestBody,\n signal: abortController.signal\n })\n\n clearTimeout(timeoutId)\n const duration = Date.now() - startTime\n\n // Parse response\n const responseText = await response.text()\n let parsedData: any = null\n\n try {\n const contentType = response.headers.get('content-type') || ''\n if (contentType.includes('application/json') || contentType.includes('text/json')) {\n parsedData = JSON.parse(responseText)\n }\n } catch (parseError) {\n // Not JSON, that's fine\n }\n\n // Convert headers to plain object\n const responseHeaders: Record<string, string> = {}\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value\n })\n\n const output = {\n status: response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n body: responseText,\n data: parsedData,\n duration\n }\n\n req?.payload?.logger?.info({\n url: typedInput.url,\n method,\n status: response.status,\n duration,\n attempt: attempt + 1\n }, 'HTTP request completed')\n\n return {\n output,\n // Always return 'succeeded' for completed HTTP requests, even with error status codes (4xx/5xx).\n // This preserves error information in the output for workflow conditional logic.\n // Only network errors, timeouts, and connection failures should result in 'failed' state.\n // This design allows workflows to handle HTTP errors gracefully rather than failing completely.\n state: 'succeeded'\n }\n\n } catch (error) {\n lastError = error instanceof Error ? error : new Error('Unknown error')\n \n // Handle specific error types\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n lastError = new Error(`Request timeout after ${timeout}ms`)\n } else if (error.message.includes('fetch')) {\n lastError = new Error(`Network error: ${error.message}`)\n }\n }\n\n req?.payload?.logger?.warn({\n url: typedInput.url,\n method,\n attempt: attempt + 1,\n maxRetries: maxRetries + 1,\n error: lastError.message\n }, 'HTTP request attempt failed')\n\n // Don't retry on certain errors\n if (lastError.message.includes('Invalid URL') || \n lastError.message.includes('TypeError') ||\n attempt >= maxRetries) {\n break\n }\n }\n }\n\n clearTimeout(timeoutId)\n const duration = Date.now() - startTime\n\n // All retries exhausted\n const finalError = lastError || new Error('HTTP request failed')\n \n req?.payload?.logger?.error({\n url: typedInput.url,\n method,\n totalAttempts: maxRetries + 1,\n duration,\n error: finalError.message\n }, 'HTTP request failed after all retries')\n\n // Include detailed error information in the output\n // Even though PayloadCMS will discard this for failed tasks,\n // we include it here for potential future PayloadCMS improvements\n const errorDetails = {\n errorType: finalError.message.includes('timeout') ? 'timeout' : \n finalError.message.includes('ENOTFOUND') ? 'dns' :\n finalError.message.includes('ECONNREFUSED') ? 'connection' : 'network',\n duration,\n attempts: maxRetries + 1,\n finalError: finalError.message,\n context: {\n url: typedInput.url,\n method,\n timeout: typedInput.timeout,\n headers: typedInput.headers\n }\n }\n\n // Return comprehensive output (PayloadCMS will discard it for failed state, but we try anyway)\n return {\n output: {\n status: 0,\n statusText: 'Request Failed',\n headers: {},\n body: '',\n data: null,\n duration,\n error: finalError.message,\n errorDetails // Include detailed error info (will be discarded by PayloadCMS)\n },\n state: 'failed'\n }\n } catch (unexpectedError) {\n // Handle any unexpected errors that weren't caught above\n const error = unexpectedError instanceof Error ? unexpectedError : new Error('Unexpected error')\n \n req?.payload?.logger?.error({\n error: error.message,\n stack: error.stack,\n input: (input as any)?.url || 'unknown'\n }, 'Unexpected error in HTTP request handler')\n\n return {\n output: {\n status: 0,\n statusText: 'Handler Error',\n headers: {},\n body: '',\n data: null,\n duration: Date.now() - startTime,\n error: `HTTP request handler error: ${error.message}`\n },\n state: 'failed'\n }\n }\n}\n"],"names":["httpStepHandler","input","req","startTime","Date","now","url","output","status","statusText","headers","body","data","duration","error","state","typedInput","URL","method","toUpperCase","timeout","authentication","type","token","username","password","credentials","btoa","headerName","headerValue","requestBody","includes","JSON","stringify","abortController","AbortController","timeoutId","setTimeout","abort","maxRetries","Math","min","max","retries","retryDelay","lastError","attempt","payload","logger","info","delay","Promise","resolve","response","fetch","signal","clearTimeout","responseText","text","parsedData","contentType","get","parse","parseError","responseHeaders","forEach","value","key","Error","name","message","warn","finalError","totalAttempts","errorDetails","errorType","attempts","context","unexpectedError","stack"],"mappings":"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"}
@@ -1,12 +1,155 @@
1
1
  export declare const HttpRequestStepTask: {
2
2
  slug: "http-request-step";
3
3
  handler: import("payload").TaskHandler<"http-request-step">;
4
- inputSchema: {
4
+ inputSchema: ({
5
5
  name: string;
6
6
  type: "text";
7
- }[];
8
- outputSchema: {
7
+ admin: {
8
+ description: string;
9
+ condition?: undefined;
10
+ };
11
+ required: true;
12
+ options?: undefined;
13
+ defaultValue?: undefined;
14
+ fields?: undefined;
15
+ min?: undefined;
16
+ max?: undefined;
17
+ } | {
18
+ name: string;
19
+ type: "select";
20
+ options: {
21
+ label: string;
22
+ value: string;
23
+ }[];
24
+ defaultValue: string;
25
+ admin: {
26
+ description: string;
27
+ condition?: undefined;
28
+ };
29
+ required?: undefined;
30
+ fields?: undefined;
31
+ min?: undefined;
32
+ max?: undefined;
33
+ } | {
34
+ name: string;
35
+ type: "json";
36
+ admin: {
37
+ description: string;
38
+ condition?: undefined;
39
+ };
40
+ required?: undefined;
41
+ options?: undefined;
42
+ defaultValue?: undefined;
43
+ fields?: undefined;
44
+ min?: undefined;
45
+ max?: undefined;
46
+ } | {
47
+ name: string;
48
+ type: "json";
49
+ admin: {
50
+ condition: (_: Partial<any>, siblingData: Partial<any>) => boolean;
51
+ description: string;
52
+ };
53
+ required?: undefined;
54
+ options?: undefined;
55
+ defaultValue?: undefined;
56
+ fields?: undefined;
57
+ min?: undefined;
58
+ max?: undefined;
59
+ } | {
60
+ name: string;
61
+ type: "number";
62
+ defaultValue: number;
63
+ admin: {
64
+ description: string;
65
+ condition?: undefined;
66
+ };
67
+ required?: undefined;
68
+ options?: undefined;
69
+ fields?: undefined;
70
+ min?: undefined;
71
+ max?: undefined;
72
+ } | {
73
+ name: string;
74
+ type: "group";
75
+ fields: ({
76
+ name: string;
77
+ type: "select";
78
+ options: {
79
+ label: string;
80
+ value: string;
81
+ }[];
82
+ defaultValue: string;
83
+ admin: {
84
+ description: string;
85
+ condition?: undefined;
86
+ };
87
+ } | {
88
+ name: string;
89
+ type: "text";
90
+ admin: {
91
+ condition: (_: Partial<any>, siblingData: Partial<any>) => boolean;
92
+ description: string;
93
+ };
94
+ options?: undefined;
95
+ defaultValue?: undefined;
96
+ })[];
97
+ admin?: undefined;
98
+ required?: undefined;
99
+ options?: undefined;
100
+ defaultValue?: undefined;
101
+ min?: undefined;
102
+ max?: undefined;
103
+ } | {
104
+ name: string;
105
+ type: "number";
106
+ defaultValue: number;
107
+ min: number;
108
+ max: number;
109
+ admin: {
110
+ description: string;
111
+ condition?: undefined;
112
+ };
113
+ required?: undefined;
114
+ options?: undefined;
115
+ fields?: undefined;
116
+ } | {
117
+ name: string;
118
+ type: "number";
119
+ defaultValue: number;
120
+ admin: {
121
+ condition: (_: Partial<any>, siblingData: Partial<any>) => boolean;
122
+ description: string;
123
+ };
124
+ required?: undefined;
125
+ options?: undefined;
126
+ fields?: undefined;
127
+ min?: undefined;
128
+ max?: undefined;
129
+ })[];
130
+ outputSchema: ({
131
+ name: string;
132
+ type: "number";
133
+ admin: {
134
+ description: string;
135
+ };
136
+ } | {
137
+ name: string;
138
+ type: "text";
139
+ admin: {
140
+ description: string;
141
+ };
142
+ } | {
143
+ name: string;
144
+ type: "json";
145
+ admin: {
146
+ description: string;
147
+ };
148
+ } | {
9
149
  name: string;
10
150
  type: "textarea";
11
- }[];
151
+ admin: {
152
+ description: string;
153
+ };
154
+ })[];
12
155
  };