@xtr-dev/payload-automation 0.0.8 → 0.0.10

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 CHANGED
@@ -27,20 +27,40 @@ yarn add @xtr-dev/payload-automation
27
27
 
28
28
  ```typescript
29
29
  import { buildConfig } from 'payload'
30
- import { payloadAutomation } from '@xtr-dev/payload-automation'
30
+ import { workflowsPlugin } from '@xtr-dev/payload-automation/server'
31
31
 
32
32
  export default buildConfig({
33
33
  // ... your config
34
34
  plugins: [
35
- payloadAutomation({
36
- collections: ['posts', 'users'], // Collections to monitor
37
- globals: ['settings'], // Globals to monitor
35
+ workflowsPlugin({
36
+ collectionTriggers: {
37
+ posts: true, // Enable all CRUD triggers for posts
38
+ users: {
39
+ create: true, // Only enable create trigger for users
40
+ update: true
41
+ }
42
+ },
38
43
  enabled: true,
39
44
  }),
40
45
  ],
41
46
  })
42
47
  ```
43
48
 
49
+ ## Import Structure
50
+
51
+ The plugin uses separate exports to avoid bundling server-side code in client bundles:
52
+
53
+ ```typescript
54
+ // Server-side plugin and functions
55
+ import { workflowsPlugin } from '@xtr-dev/payload-automation/server'
56
+
57
+ // Client-side components
58
+ import { TriggerWorkflowButton } from '@xtr-dev/payload-automation/client'
59
+
60
+ // Types only (safe for both server and client)
61
+ import type { WorkflowsPluginConfig } from '@xtr-dev/payload-automation'
62
+ ```
63
+
44
64
  ## Step Types
45
65
 
46
66
  - **HTTP Request** - Make external API calls
@@ -0,0 +1,5 @@
1
+ export { triggerCustomWorkflow, triggerWorkflowById } from '../core/trigger-custom-workflow.js';
2
+ export { WorkflowExecutor } from '../core/workflow-executor.js';
3
+ export { workflowsPlugin } from '../plugin/index.js';
4
+ export { createDocumentHandler, deleteDocumentHandler, httpStepHandler, readDocumentHandler, sendEmailHandler, updateDocumentHandler } from '../steps/index.js';
5
+ export { CreateDocumentStepTask, DeleteDocumentStepTask, HttpRequestStepTask, ReadDocumentStepTask, SendEmailStepTask, UpdateDocumentStepTask } from '../steps/index.js';
@@ -0,0 +1,11 @@
1
+ // Server-side only exports - should never be bundled for client
2
+ // These contain Node.js dependencies and should only be used server-side
3
+ export { triggerCustomWorkflow, triggerWorkflowById } from '../core/trigger-custom-workflow.js';
4
+ export { WorkflowExecutor } from '../core/workflow-executor.js';
5
+ export { workflowsPlugin } from '../plugin/index.js';
6
+ // Export all step handlers (server-side only)
7
+ export { createDocumentHandler, deleteDocumentHandler, httpStepHandler, readDocumentHandler, sendEmailHandler, updateDocumentHandler } from '../steps/index.js';
8
+ // Export step tasks configurations (server-side only)
9
+ export { CreateDocumentStepTask, DeleteDocumentStepTask, HttpRequestStepTask, ReadDocumentStepTask, SendEmailStepTask, UpdateDocumentStepTask } from '../steps/index.js';
10
+
11
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exports/server.ts"],"sourcesContent":["// Server-side only exports - should never be bundled for client\n// These contain Node.js dependencies and should only be used server-side\n\nexport { triggerCustomWorkflow, triggerWorkflowById } from '../core/trigger-custom-workflow.js'\nexport { WorkflowExecutor } from '../core/workflow-executor.js'\nexport { workflowsPlugin } from '../plugin/index.js'\n\n// Export all step handlers (server-side only)\nexport {\n createDocumentHandler,\n deleteDocumentHandler,\n httpStepHandler,\n readDocumentHandler,\n sendEmailHandler,\n updateDocumentHandler\n} from '../steps/index.js'\n\n// Export step tasks configurations (server-side only)\nexport {\n CreateDocumentStepTask,\n DeleteDocumentStepTask,\n HttpRequestStepTask,\n ReadDocumentStepTask,\n SendEmailStepTask,\n UpdateDocumentStepTask\n} from '../steps/index.js'"],"names":["triggerCustomWorkflow","triggerWorkflowById","WorkflowExecutor","workflowsPlugin","createDocumentHandler","deleteDocumentHandler","httpStepHandler","readDocumentHandler","sendEmailHandler","updateDocumentHandler","CreateDocumentStepTask","DeleteDocumentStepTask","HttpRequestStepTask","ReadDocumentStepTask","SendEmailStepTask","UpdateDocumentStepTask"],"mappings":"AAAA,gEAAgE;AAChE,yEAAyE;AAEzE,SAASA,qBAAqB,EAAEC,mBAAmB,QAAQ,qCAAoC;AAC/F,SAASC,gBAAgB,QAAQ,+BAA8B;AAC/D,SAASC,eAAe,QAAQ,qBAAoB;AAEpD,8CAA8C;AAC9C,SACEC,qBAAqB,EACrBC,qBAAqB,EACrBC,eAAe,EACfC,mBAAmB,EACnBC,gBAAgB,EAChBC,qBAAqB,QAChB,oBAAmB;AAE1B,sDAAsD;AACtD,SACEC,sBAAsB,EACtBC,sBAAsB,EACtBC,mBAAmB,EACnBC,oBAAoB,EACpBC,iBAAiB,EACjBC,sBAAsB,QACjB,oBAAmB"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,3 @@
1
- export { triggerCustomWorkflow, triggerWorkflowById } from './core/trigger-custom-workflow.js';
2
1
  export type { CustomTriggerOptions, TriggerResult } from './core/trigger-custom-workflow.js';
3
- export { WorkflowExecutor } from './core/workflow-executor.js';
4
2
  export type { ExecutionContext, Workflow, WorkflowStep, WorkflowTrigger } from './core/workflow-executor.js';
5
3
  export type { WorkflowsPluginConfig } from './plugin/config-types.js';
6
- export { workflowsPlugin } from './plugin/index.js';
7
- export { CreateDocumentStepTask, DeleteDocumentStepTask, HttpRequestStepTask, ReadDocumentStepTask, SendEmailStepTask, UpdateDocumentStepTask } from './steps/index.js';
package/dist/index.js CHANGED
@@ -1,8 +1,11 @@
1
- export { triggerCustomWorkflow, triggerWorkflowById } from './core/trigger-custom-workflow.js';
2
- export { WorkflowExecutor } from './core/workflow-executor.js';
3
- export { workflowsPlugin } from './plugin/index.js';
4
- // Export all step tasks
5
- export { CreateDocumentStepTask, DeleteDocumentStepTask, HttpRequestStepTask, ReadDocumentStepTask, SendEmailStepTask, UpdateDocumentStepTask } from './steps/index.js'; // UI components are exported via separate client export to avoid CSS import issues during type generation
6
- // Use: import { TriggerWorkflowButton } from '@xtr-dev/payload-automation/client'
1
+ // Main export contains only types and client-safe utilities
2
+ // Server-side functions are exported via '@xtr-dev/payload-automation/server'
3
+ // Types only - safe for client bundling
4
+ export { }; // Server-side functions are NOT re-exported here to avoid bundling issues
5
+ // Import server-side functions from the /server export instead
6
+ // Server functions and plugin should be imported from '/server':
7
+ // import { workflowsPlugin } from '@xtr-dev/payload-automation/server'
8
+ // UI components should be imported from '/client':
9
+ // import { TriggerWorkflowButton } from '@xtr-dev/payload-automation/client'
7
10
 
8
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { triggerCustomWorkflow, triggerWorkflowById } from './core/trigger-custom-workflow.js'\nexport type { CustomTriggerOptions, TriggerResult } from './core/trigger-custom-workflow.js'\nexport { WorkflowExecutor } from './core/workflow-executor.js'\nexport type { ExecutionContext, Workflow, WorkflowStep, WorkflowTrigger } from './core/workflow-executor.js'\nexport type { WorkflowsPluginConfig } from './plugin/config-types.js'\nexport { workflowsPlugin } from './plugin/index.js'\n\n// Export all step tasks\nexport {\n CreateDocumentStepTask,\n DeleteDocumentStepTask,\n HttpRequestStepTask,\n ReadDocumentStepTask,\n SendEmailStepTask,\n UpdateDocumentStepTask\n} from './steps/index.js'\n\n// UI components are exported via separate client export to avoid CSS import issues during type generation\n// Use: import { TriggerWorkflowButton } from '@xtr-dev/payload-automation/client'\n"],"names":["triggerCustomWorkflow","triggerWorkflowById","WorkflowExecutor","workflowsPlugin","CreateDocumentStepTask","DeleteDocumentStepTask","HttpRequestStepTask","ReadDocumentStepTask","SendEmailStepTask","UpdateDocumentStepTask"],"mappings":"AAAA,SAASA,qBAAqB,EAAEC,mBAAmB,QAAQ,oCAAmC;AAE9F,SAASC,gBAAgB,QAAQ,8BAA6B;AAG9D,SAASC,eAAe,QAAQ,oBAAmB;AAEnD,wBAAwB;AACxB,SACEC,sBAAsB,EACtBC,sBAAsB,EACtBC,mBAAmB,EACnBC,oBAAoB,EACpBC,iBAAiB,EACjBC,sBAAsB,QACjB,mBAAkB,CAEzB,0GAA0G;CAC1G,kFAAkF"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Main export contains only types and client-safe utilities\n// Server-side functions are exported via '@xtr-dev/payload-automation/server'\n\n// Types only - safe for client bundling\nexport type { CustomTriggerOptions, TriggerResult } from './core/trigger-custom-workflow.js'\nexport type { ExecutionContext, Workflow, WorkflowStep, WorkflowTrigger } from './core/workflow-executor.js'\nexport type { WorkflowsPluginConfig } from './plugin/config-types.js'\n\n// Server-side functions are NOT re-exported here to avoid bundling issues\n// Import server-side functions from the /server export instead\n\n// Server functions and plugin should be imported from '/server':\n// import { workflowsPlugin } from '@xtr-dev/payload-automation/server'\n// UI components should be imported from '/client':\n// import { TriggerWorkflowButton } from '@xtr-dev/payload-automation/client'\n"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,8EAA8E;AAE9E,wCAAwC;AAGxC,WAAqE,CAErE,0EAA0E;CAC1E,+DAA+D;CAE/D,iEAAiE;CACjE,uEAAuE;CACvE,mDAAmD;CACnD,6EAA6E"}
@@ -1,4 +1,4 @@
1
- import * as cron from 'node-cron';
1
+ import cron from 'node-cron';
2
2
  import { WorkflowExecutor } from '../core/workflow-executor.js';
3
3
  import { getConfigLogger } from './logger.js';
4
4
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugin/cron-scheduler.ts"],"sourcesContent":["import type {Config, Payload, TaskConfig} from 'payload'\n\nimport * as cron from 'node-cron'\n\nimport {type Workflow, WorkflowExecutor} from '../core/workflow-executor.js'\nimport {getConfigLogger} from './logger.js'\n\n/**\n * Generate dynamic cron tasks for all workflows with cron triggers\n * This is called at config time to register all scheduled tasks\n */\nexport function generateCronTasks(config: Config): void {\n const logger = getConfigLogger()\n\n // Note: We can't query the database at config time, so we'll need a different approach\n // We'll create a single task that handles all cron-triggered workflows\n const cronTask: TaskConfig = {\n slug: 'workflow-cron-executor',\n handler: async ({ input, req }) => {\n const { cronExpression, timezone, workflowId } = input as {\n cronExpression?: string\n timezone?: string\n workflowId: string\n }\n\n const logger = req.payload.logger.child({ plugin: '@xtr-dev/payload-automation' })\n\n try {\n // Get the workflow\n const workflow = await req.payload.findByID({\n id: workflowId,\n collection: 'workflows',\n depth: 2,\n req\n })\n\n if (!workflow) {\n throw new Error(`Workflow ${workflowId} not found`)\n }\n\n // Create execution context for cron trigger\n const context = {\n steps: {},\n trigger: {\n type: 'cron',\n req,\n triggeredAt: new Date().toISOString()\n }\n }\n\n // Create executor\n const executor = new WorkflowExecutor(req.payload, logger)\n\n // Find the matching cron trigger and check its condition if present\n const triggers = workflow.triggers as Array<{\n condition?: string\n cronExpression?: string\n timezone?: string\n type: string\n }>\n\n const matchingTrigger = triggers?.find(trigger =>\n trigger.type === 'cron-trigger' &&\n trigger.cronExpression === cronExpression\n )\n\n // Check trigger condition if present\n if (matchingTrigger?.condition) {\n const conditionMet = executor.evaluateCondition(matchingTrigger.condition, context)\n\n if (!conditionMet) {\n logger.info({\n condition: matchingTrigger.condition,\n cronExpression,\n workflowId,\n workflowName: workflow.name\n }, 'Cron trigger condition not met, skipping workflow execution')\n\n // Re-queue for next execution but don't run workflow\n if (cronExpression) {\n void requeueCronJob(workflowId, cronExpression, timezone, req.payload, logger)\n }\n\n return {\n output: {\n executedAt: new Date().toISOString(),\n reason: 'Condition not met',\n status: 'skipped',\n workflowId\n },\n state: 'succeeded'\n }\n }\n\n logger.info({\n condition: matchingTrigger.condition,\n cronExpression,\n workflowId,\n workflowName: workflow.name\n }, 'Cron trigger condition met')\n }\n\n // Execute the workflow\n await executor.execute(workflow as Workflow, context, req)\n\n // Re-queue the job for the next scheduled execution if cronExpression is provided\n if (cronExpression) {\n void requeueCronJob(workflowId, cronExpression, timezone, req.payload, logger)\n }\n\n return {\n output: {\n executedAt: new Date().toISOString(),\n status: 'completed',\n workflowId\n },\n state: 'succeeded'\n }\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n }, 'Cron job execution failed')\n\n // Re-queue even on failure to ensure continuity (unless it's a validation error)\n if (cronExpression && !(error instanceof Error && error.message.includes('Invalid cron'))) {\n void requeueCronJob(workflowId, cronExpression, timezone, req.payload, logger)\n .catch((requeueError) => {\n logger.error({\n error: requeueError instanceof Error ? requeueError.message : 'Unknown error',\n workflowId\n }, 'Failed to re-queue cron job after execution failure')\n })\n }\n\n return {\n output: {\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n },\n state: 'failed'\n }\n }\n }\n }\n\n // Add the cron task to config if not already present\n if (!config.jobs) {\n config.jobs = { tasks: [] }\n }\n\n if (!config.jobs.tasks) {\n config.jobs.tasks = []\n }\n\n if (!config.jobs.tasks.find(task => task.slug === cronTask.slug)) {\n logger.debug(`Registering cron executor task: ${cronTask.slug}`)\n config.jobs.tasks.push(cronTask)\n } else {\n logger.debug(`Cron executor task ${cronTask.slug} already registered, skipping`)\n }\n}\n\n/**\n * Register cron jobs for workflows with cron triggers\n * This is called at runtime after PayloadCMS is initialized\n */\nexport async function registerCronJobs(payload: Payload, logger: Payload['logger']): Promise<void> {\n try {\n // Find all workflows with cron triggers\n const workflows = await payload.find({\n collection: 'workflows',\n depth: 0,\n limit: 1000,\n where: {\n 'triggers.type': {\n equals: 'cron-trigger'\n }\n }\n })\n\n logger.info(`Found ${workflows.docs.length} workflows with cron triggers`)\n\n for (const workflow of workflows.docs) {\n const triggers = workflow.triggers as Array<{\n cronExpression?: string\n timezone?: string\n type: string\n }>\n\n // Find all cron triggers for this workflow\n const cronTriggers = triggers?.filter(t => t.type === 'cron-trigger') || []\n\n for (const trigger of cronTriggers) {\n if (trigger.cronExpression) {\n try {\n // Validate cron expression before queueing\n if (!validateCronExpression(trigger.cronExpression)) {\n logger.error({\n cronExpression: trigger.cronExpression,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Invalid cron expression format')\n continue\n }\n\n // Validate timezone if provided\n if (trigger.timezone) {\n try {\n // Test if timezone is valid by trying to create a date with it\n new Intl.DateTimeFormat('en', { timeZone: trigger.timezone })\n } catch {\n logger.error({\n timezone: trigger.timezone,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Invalid timezone specified')\n continue\n }\n }\n\n // Calculate next execution time\n const nextExecution = getNextCronTime(trigger.cronExpression, trigger.timezone)\n\n // Queue the job\n await payload.jobs.queue({\n input: { cronExpression: trigger.cronExpression, timezone: trigger.timezone, workflowId: workflow.id },\n task: 'workflow-cron-executor',\n waitUntil: nextExecution\n })\n\n logger.info({\n cronExpression: trigger.cronExpression,\n nextExecution: nextExecution.toISOString(),\n timezone: trigger.timezone || 'UTC',\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Queued initial cron job for workflow')\n } catch (error) {\n logger.error({\n cronExpression: trigger.cronExpression,\n error: error instanceof Error ? error.message : 'Unknown error',\n timezone: trigger.timezone,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Failed to queue cron job')\n }\n } else {\n logger.warn({\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Cron trigger found but no cron expression specified')\n }\n }\n }\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error'\n }, 'Failed to register cron jobs')\n }\n}\n\n/**\n * Validate a cron expression\n */\nexport function validateCronExpression(cronExpression: string): boolean {\n return cron.validate(cronExpression)\n}\n\n/**\n * Calculate the next time a cron expression should run\n */\nfunction getNextCronTime(cronExpression: string, timezone?: string): Date {\n if (!validateCronExpression(cronExpression)) {\n throw new Error(`Invalid cron expression: ${cronExpression}`)\n }\n\n const now = new Date()\n const options: { timezone?: string } = timezone ? { timezone } : {}\n\n // Create a task to find the next execution time\n const task = cron.schedule(cronExpression, () => {}, {\n ...options\n })\n\n // Parse cron expression parts\n const cronParts = cronExpression.trim().split(/\\s+/)\n if (cronParts.length !== 5) {\n void task.destroy()\n throw new Error(`Invalid cron format: ${cronExpression}. Expected 5 parts.`)\n }\n\n const [minutePart, hourPart, dayPart, monthPart, weekdayPart] = cronParts\n\n // Calculate next execution with proper lookahead for any schedule frequency\n // Start from next minute and look ahead systematically\n let testTime = new Date(now.getTime() + 60 * 1000) // Start 1 minute from now\n testTime.setSeconds(0, 0) // Reset seconds and milliseconds\n\n // Maximum iterations to prevent infinite loops (covers ~2 years)\n const maxIterations = 2 * 365 * 24 * 60 // 2 years worth of minutes\n let iterations = 0\n\n while (iterations < maxIterations) {\n const minute = testTime.getMinutes()\n const hour = testTime.getHours()\n const dayOfMonth = testTime.getDate()\n const month = testTime.getMonth() + 1\n const dayOfWeek = testTime.getDay()\n\n if (matchesCronPart(minute, minutePart) &&\n matchesCronPart(hour, hourPart) &&\n matchesCronPart(dayOfMonth, dayPart) &&\n matchesCronPart(month, monthPart) &&\n matchesCronPart(dayOfWeek, weekdayPart)) {\n void task.destroy()\n return testTime\n }\n\n // Increment time intelligently based on cron pattern\n testTime = incrementTimeForCronPattern(testTime, cronParts)\n iterations++\n }\n\n void task.destroy()\n throw new Error(`Could not calculate next execution time for cron expression: ${cronExpression} within reasonable timeframe`)\n}\n\n/**\n * Intelligently increment time based on cron pattern to avoid unnecessary iterations\n */\nfunction incrementTimeForCronPattern(currentTime: Date, cronParts: string[]): Date {\n const [minutePart, hourPart, _dayPart, _monthPart, _weekdayPart] = cronParts\n const nextTime = new Date(currentTime)\n\n // If minute is specific (not wildcard), we can jump to next hour\n if (minutePart !== '*' && !minutePart.includes('/')) {\n const targetMinute = getNextValidCronValue(currentTime.getMinutes(), minutePart)\n if (targetMinute <= currentTime.getMinutes()) {\n // Move to next hour\n nextTime.setHours(nextTime.getHours() + 1, targetMinute, 0, 0)\n } else {\n nextTime.setMinutes(targetMinute, 0, 0)\n }\n return nextTime\n }\n\n // If hour is specific and we're past it, jump to next day\n if (hourPart !== '*' && !hourPart.includes('/')) {\n const targetHour = getNextValidCronValue(currentTime.getHours(), hourPart)\n if (targetHour <= currentTime.getHours()) {\n // Move to next day\n nextTime.setDate(nextTime.getDate() + 1)\n nextTime.setHours(targetHour, 0, 0, 0)\n } else {\n nextTime.setHours(targetHour, 0, 0, 0)\n }\n return nextTime\n }\n\n // Default: increment by 1 minute\n nextTime.setTime(nextTime.getTime() + 60 * 1000)\n return nextTime\n}\n\n/**\n * Get the next valid value for a cron part\n */\nfunction getNextValidCronValue(currentValue: number, cronPart: string): number {\n if (cronPart === '*') {return currentValue + 1}\n\n // Handle specific values and ranges\n const values = parseCronPart(cronPart)\n return values.find(v => v > currentValue) || values[0]\n}\n\n/**\n * Parse a cron part into an array of valid values\n */\nfunction parseCronPart(cronPart: string): number[] {\n if (cronPart === '*') {return []}\n\n const values: number[] = []\n\n // Handle comma-separated values\n if (cronPart.includes(',')) {\n cronPart.split(',').forEach(part => {\n values.push(...parseCronPart(part.trim()))\n })\n return values.sort((a, b) => a - b)\n }\n\n // Handle ranges\n if (cronPart.includes('-')) {\n const [start, end] = cronPart.split('-').map(n => parseInt(n, 10))\n for (let i = start; i <= end; i++) {\n values.push(i)\n }\n return values\n }\n\n // Handle step values\n if (cronPart.includes('/')) {\n const [range, step] = cronPart.split('/')\n const stepNum = parseInt(step, 10)\n\n if (range === '*') {\n // For wildcards with steps, return empty - handled elsewhere\n return []\n }\n\n const baseValues = parseCronPart(range)\n return baseValues.filter((_, index) => index % stepNum === 0)\n }\n\n // Single value\n values.push(parseInt(cronPart, 10))\n return values\n}\n\n/**\n * Check if a value matches a cron expression part\n */\nfunction matchesCronPart(value: number, cronPart: string): boolean {\n if (cronPart === '*') {return true}\n\n // Handle step values (e.g., */5)\n if (cronPart.includes('/')) {\n const [range, step] = cronPart.split('/')\n const stepNum = parseInt(step, 10)\n\n if (range === '*') {\n return value % stepNum === 0\n }\n }\n\n // Handle ranges (e.g., 1-5)\n if (cronPart.includes('-')) {\n const [start, end] = cronPart.split('-').map(n => parseInt(n, 10))\n return value >= start && value <= end\n }\n\n // Handle comma-separated values (e.g., 1,3,5)\n if (cronPart.includes(',')) {\n const values = cronPart.split(',').map(n => parseInt(n, 10))\n return values.includes(value)\n }\n\n // Handle single value\n const cronValue = parseInt(cronPart, 10)\n return value === cronValue\n}\n\n/**\n * Handle re-queueing of cron jobs after they execute\n * This ensures the job runs again at the next scheduled time\n */\nexport async function requeueCronJob(\n workflowId: string,\n cronExpression: string,\n timezone: string | undefined,\n payload: Payload,\n logger: Payload['logger']\n): Promise<void> {\n try {\n // Queue the job to run at the next scheduled time\n await payload.jobs.queue({\n input: { cronExpression, timezone, workflowId },\n task: 'workflow-cron-executor',\n waitUntil: getNextCronTime(cronExpression, timezone)\n })\n\n logger.debug({\n nextRun: getNextCronTime(cronExpression, timezone),\n timezone: timezone || 'UTC',\n workflowId\n }, 'Re-queued cron job')\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n }, 'Failed to re-queue cron job')\n }\n}\n\n/**\n * Register or update cron jobs for a specific workflow\n */\nexport async function updateWorkflowCronJobs(\n workflowId: string,\n payload: Payload,\n logger: Payload['logger']\n): Promise<void> {\n try {\n // First, cancel any existing cron jobs for this workflow\n cancelWorkflowCronJobs(workflowId, payload, logger)\n\n // Get the workflow\n const workflow = await payload.findByID({\n id: workflowId,\n collection: 'workflows',\n depth: 0\n })\n\n if (!workflow) {\n logger.warn({ workflowId }, 'Workflow not found for cron job update')\n return\n }\n\n const triggers = workflow.triggers as Array<{\n cronExpression?: string\n timezone?: string\n type: string\n }>\n\n // Find all cron triggers for this workflow\n const cronTriggers = triggers?.filter(t => t.type === 'cron-trigger') || []\n\n if (cronTriggers.length === 0) {\n logger.debug({ workflowId }, 'No cron triggers found for workflow')\n return\n }\n\n let scheduledJobs = 0\n\n for (const trigger of cronTriggers) {\n if (trigger.cronExpression) {\n try {\n // Validate cron expression before queueing\n if (!validateCronExpression(trigger.cronExpression)) {\n logger.error({\n cronExpression: trigger.cronExpression,\n workflowId,\n workflowName: workflow.name\n }, 'Invalid cron expression format')\n continue\n }\n\n // Validate timezone if provided\n if (trigger.timezone) {\n try {\n new Intl.DateTimeFormat('en', { timeZone: trigger.timezone })\n } catch {\n logger.error({\n timezone: trigger.timezone,\n workflowId,\n workflowName: workflow.name\n }, 'Invalid timezone specified')\n continue\n }\n }\n\n // Calculate next execution time\n const nextExecution = getNextCronTime(trigger.cronExpression, trigger.timezone)\n\n // Queue the job\n await payload.jobs.queue({\n input: { cronExpression: trigger.cronExpression, timezone: trigger.timezone, workflowId },\n task: 'workflow-cron-executor',\n waitUntil: nextExecution\n })\n\n scheduledJobs++\n\n logger.info({\n cronExpression: trigger.cronExpression,\n nextExecution: nextExecution.toISOString(),\n timezone: trigger.timezone || 'UTC',\n workflowId,\n workflowName: workflow.name\n }, 'Scheduled cron job for workflow')\n } catch (error) {\n logger.error({\n cronExpression: trigger.cronExpression,\n error: error instanceof Error ? error.message : 'Unknown error',\n timezone: trigger.timezone,\n workflowId,\n workflowName: workflow.name\n }, 'Failed to schedule cron job')\n }\n }\n }\n\n if (scheduledJobs > 0) {\n logger.info({ scheduledJobs, workflowId }, 'Updated cron jobs for workflow')\n }\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n }, 'Failed to update workflow cron jobs')\n }\n}\n\n/**\n * Cancel all cron jobs for a specific workflow\n */\nexport function cancelWorkflowCronJobs(\n workflowId: string,\n payload: Payload,\n logger: Payload['logger']\n): void {\n try {\n // Note: PayloadCMS job system doesn't have a built-in way to cancel specific jobs by input\n // This is a limitation we need to work around\n // For now, we log that we would cancel jobs for this workflow\n logger.debug({ workflowId }, 'Would cancel existing cron jobs for workflow (PayloadCMS limitation: cannot selectively cancel jobs)')\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n }, 'Failed to cancel workflow cron jobs')\n }\n}\n\n/**\n * Remove cron jobs for a deleted workflow\n */\nexport function removeWorkflowCronJobs(\n workflowId: string,\n payload: Payload,\n logger: Payload['logger']\n): void {\n try {\n cancelWorkflowCronJobs(workflowId, payload, logger)\n logger.info({ workflowId }, 'Removed cron jobs for deleted workflow')\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n }, 'Failed to remove workflow cron jobs')\n }\n}\n"],"names":["cron","WorkflowExecutor","getConfigLogger","generateCronTasks","config","logger","cronTask","slug","handler","input","req","cronExpression","timezone","workflowId","payload","child","plugin","workflow","findByID","id","collection","depth","Error","context","steps","trigger","type","triggeredAt","Date","toISOString","executor","triggers","matchingTrigger","find","condition","conditionMet","evaluateCondition","info","workflowName","name","requeueCronJob","output","executedAt","reason","status","state","execute","error","message","includes","catch","requeueError","jobs","tasks","task","debug","push","registerCronJobs","workflows","limit","where","equals","docs","length","cronTriggers","filter","t","validateCronExpression","Intl","DateTimeFormat","timeZone","nextExecution","getNextCronTime","queue","waitUntil","warn","validate","now","options","schedule","cronParts","trim","split","destroy","minutePart","hourPart","dayPart","monthPart","weekdayPart","testTime","getTime","setSeconds","maxIterations","iterations","minute","getMinutes","hour","getHours","dayOfMonth","getDate","month","getMonth","dayOfWeek","getDay","matchesCronPart","incrementTimeForCronPattern","currentTime","_dayPart","_monthPart","_weekdayPart","nextTime","targetMinute","getNextValidCronValue","setHours","setMinutes","targetHour","setDate","setTime","currentValue","cronPart","values","parseCronPart","v","forEach","part","sort","a","b","start","end","map","n","parseInt","i","range","step","stepNum","baseValues","_","index","value","cronValue","nextRun","updateWorkflowCronJobs","cancelWorkflowCronJobs","scheduledJobs","removeWorkflowCronJobs"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/plugin/cron-scheduler.ts"],"sourcesContent":["import type {Config, Payload, TaskConfig} from 'payload'\n\nimport cron from 'node-cron'\n\nimport {type Workflow, WorkflowExecutor} from '../core/workflow-executor.js'\nimport {getConfigLogger} from './logger.js'\n\n/**\n * Generate dynamic cron tasks for all workflows with cron triggers\n * This is called at config time to register all scheduled tasks\n */\nexport function generateCronTasks(config: Config): void {\n const logger = getConfigLogger()\n\n // Note: We can't query the database at config time, so we'll need a different approach\n // We'll create a single task that handles all cron-triggered workflows\n const cronTask: TaskConfig = {\n slug: 'workflow-cron-executor',\n handler: async ({ input, req }) => {\n const { cronExpression, timezone, workflowId } = input as {\n cronExpression?: string\n timezone?: string\n workflowId: string\n }\n\n const logger = req.payload.logger.child({ plugin: '@xtr-dev/payload-automation' })\n\n try {\n // Get the workflow\n const workflow = await req.payload.findByID({\n id: workflowId,\n collection: 'workflows',\n depth: 2,\n req\n })\n\n if (!workflow) {\n throw new Error(`Workflow ${workflowId} not found`)\n }\n\n // Create execution context for cron trigger\n const context = {\n steps: {},\n trigger: {\n type: 'cron',\n req,\n triggeredAt: new Date().toISOString()\n }\n }\n\n // Create executor\n const executor = new WorkflowExecutor(req.payload, logger)\n\n // Find the matching cron trigger and check its condition if present\n const triggers = workflow.triggers as Array<{\n condition?: string\n cronExpression?: string\n timezone?: string\n type: string\n }>\n\n const matchingTrigger = triggers?.find(trigger =>\n trigger.type === 'cron-trigger' &&\n trigger.cronExpression === cronExpression\n )\n\n // Check trigger condition if present\n if (matchingTrigger?.condition) {\n const conditionMet = executor.evaluateCondition(matchingTrigger.condition, context)\n\n if (!conditionMet) {\n logger.info({\n condition: matchingTrigger.condition,\n cronExpression,\n workflowId,\n workflowName: workflow.name\n }, 'Cron trigger condition not met, skipping workflow execution')\n\n // Re-queue for next execution but don't run workflow\n if (cronExpression) {\n void requeueCronJob(workflowId, cronExpression, timezone, req.payload, logger)\n }\n\n return {\n output: {\n executedAt: new Date().toISOString(),\n reason: 'Condition not met',\n status: 'skipped',\n workflowId\n },\n state: 'succeeded'\n }\n }\n\n logger.info({\n condition: matchingTrigger.condition,\n cronExpression,\n workflowId,\n workflowName: workflow.name\n }, 'Cron trigger condition met')\n }\n\n // Execute the workflow\n await executor.execute(workflow as Workflow, context, req)\n\n // Re-queue the job for the next scheduled execution if cronExpression is provided\n if (cronExpression) {\n void requeueCronJob(workflowId, cronExpression, timezone, req.payload, logger)\n }\n\n return {\n output: {\n executedAt: new Date().toISOString(),\n status: 'completed',\n workflowId\n },\n state: 'succeeded'\n }\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n }, 'Cron job execution failed')\n\n // Re-queue even on failure to ensure continuity (unless it's a validation error)\n if (cronExpression && !(error instanceof Error && error.message.includes('Invalid cron'))) {\n void requeueCronJob(workflowId, cronExpression, timezone, req.payload, logger)\n .catch((requeueError) => {\n logger.error({\n error: requeueError instanceof Error ? requeueError.message : 'Unknown error',\n workflowId\n }, 'Failed to re-queue cron job after execution failure')\n })\n }\n\n return {\n output: {\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n },\n state: 'failed'\n }\n }\n }\n }\n\n // Add the cron task to config if not already present\n if (!config.jobs) {\n config.jobs = { tasks: [] }\n }\n\n if (!config.jobs.tasks) {\n config.jobs.tasks = []\n }\n\n if (!config.jobs.tasks.find(task => task.slug === cronTask.slug)) {\n logger.debug(`Registering cron executor task: ${cronTask.slug}`)\n config.jobs.tasks.push(cronTask)\n } else {\n logger.debug(`Cron executor task ${cronTask.slug} already registered, skipping`)\n }\n}\n\n/**\n * Register cron jobs for workflows with cron triggers\n * This is called at runtime after PayloadCMS is initialized\n */\nexport async function registerCronJobs(payload: Payload, logger: Payload['logger']): Promise<void> {\n try {\n // Find all workflows with cron triggers\n const workflows = await payload.find({\n collection: 'workflows',\n depth: 0,\n limit: 1000,\n where: {\n 'triggers.type': {\n equals: 'cron-trigger'\n }\n }\n })\n\n logger.info(`Found ${workflows.docs.length} workflows with cron triggers`)\n\n for (const workflow of workflows.docs) {\n const triggers = workflow.triggers as Array<{\n cronExpression?: string\n timezone?: string\n type: string\n }>\n\n // Find all cron triggers for this workflow\n const cronTriggers = triggers?.filter(t => t.type === 'cron-trigger') || []\n\n for (const trigger of cronTriggers) {\n if (trigger.cronExpression) {\n try {\n // Validate cron expression before queueing\n if (!validateCronExpression(trigger.cronExpression)) {\n logger.error({\n cronExpression: trigger.cronExpression,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Invalid cron expression format')\n continue\n }\n\n // Validate timezone if provided\n if (trigger.timezone) {\n try {\n // Test if timezone is valid by trying to create a date with it\n new Intl.DateTimeFormat('en', { timeZone: trigger.timezone })\n } catch {\n logger.error({\n timezone: trigger.timezone,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Invalid timezone specified')\n continue\n }\n }\n\n // Calculate next execution time\n const nextExecution = getNextCronTime(trigger.cronExpression, trigger.timezone)\n\n // Queue the job\n await payload.jobs.queue({\n input: { cronExpression: trigger.cronExpression, timezone: trigger.timezone, workflowId: workflow.id },\n task: 'workflow-cron-executor',\n waitUntil: nextExecution\n })\n\n logger.info({\n cronExpression: trigger.cronExpression,\n nextExecution: nextExecution.toISOString(),\n timezone: trigger.timezone || 'UTC',\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Queued initial cron job for workflow')\n } catch (error) {\n logger.error({\n cronExpression: trigger.cronExpression,\n error: error instanceof Error ? error.message : 'Unknown error',\n timezone: trigger.timezone,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Failed to queue cron job')\n }\n } else {\n logger.warn({\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Cron trigger found but no cron expression specified')\n }\n }\n }\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error'\n }, 'Failed to register cron jobs')\n }\n}\n\n/**\n * Validate a cron expression\n */\nexport function validateCronExpression(cronExpression: string): boolean {\n return cron.validate(cronExpression)\n}\n\n/**\n * Calculate the next time a cron expression should run\n */\nfunction getNextCronTime(cronExpression: string, timezone?: string): Date {\n if (!validateCronExpression(cronExpression)) {\n throw new Error(`Invalid cron expression: ${cronExpression}`)\n }\n\n const now = new Date()\n const options: { timezone?: string } = timezone ? { timezone } : {}\n\n // Create a task to find the next execution time\n const task = cron.schedule(cronExpression, () => {}, {\n ...options\n })\n\n // Parse cron expression parts\n const cronParts = cronExpression.trim().split(/\\s+/)\n if (cronParts.length !== 5) {\n void task.destroy()\n throw new Error(`Invalid cron format: ${cronExpression}. Expected 5 parts.`)\n }\n\n const [minutePart, hourPart, dayPart, monthPart, weekdayPart] = cronParts\n\n // Calculate next execution with proper lookahead for any schedule frequency\n // Start from next minute and look ahead systematically\n let testTime = new Date(now.getTime() + 60 * 1000) // Start 1 minute from now\n testTime.setSeconds(0, 0) // Reset seconds and milliseconds\n\n // Maximum iterations to prevent infinite loops (covers ~2 years)\n const maxIterations = 2 * 365 * 24 * 60 // 2 years worth of minutes\n let iterations = 0\n\n while (iterations < maxIterations) {\n const minute = testTime.getMinutes()\n const hour = testTime.getHours()\n const dayOfMonth = testTime.getDate()\n const month = testTime.getMonth() + 1\n const dayOfWeek = testTime.getDay()\n\n if (matchesCronPart(minute, minutePart) &&\n matchesCronPart(hour, hourPart) &&\n matchesCronPart(dayOfMonth, dayPart) &&\n matchesCronPart(month, monthPart) &&\n matchesCronPart(dayOfWeek, weekdayPart)) {\n void task.destroy()\n return testTime\n }\n\n // Increment time intelligently based on cron pattern\n testTime = incrementTimeForCronPattern(testTime, cronParts)\n iterations++\n }\n\n void task.destroy()\n throw new Error(`Could not calculate next execution time for cron expression: ${cronExpression} within reasonable timeframe`)\n}\n\n/**\n * Intelligently increment time based on cron pattern to avoid unnecessary iterations\n */\nfunction incrementTimeForCronPattern(currentTime: Date, cronParts: string[]): Date {\n const [minutePart, hourPart, _dayPart, _monthPart, _weekdayPart] = cronParts\n const nextTime = new Date(currentTime)\n\n // If minute is specific (not wildcard), we can jump to next hour\n if (minutePart !== '*' && !minutePart.includes('/')) {\n const targetMinute = getNextValidCronValue(currentTime.getMinutes(), minutePart)\n if (targetMinute <= currentTime.getMinutes()) {\n // Move to next hour\n nextTime.setHours(nextTime.getHours() + 1, targetMinute, 0, 0)\n } else {\n nextTime.setMinutes(targetMinute, 0, 0)\n }\n return nextTime\n }\n\n // If hour is specific and we're past it, jump to next day\n if (hourPart !== '*' && !hourPart.includes('/')) {\n const targetHour = getNextValidCronValue(currentTime.getHours(), hourPart)\n if (targetHour <= currentTime.getHours()) {\n // Move to next day\n nextTime.setDate(nextTime.getDate() + 1)\n nextTime.setHours(targetHour, 0, 0, 0)\n } else {\n nextTime.setHours(targetHour, 0, 0, 0)\n }\n return nextTime\n }\n\n // Default: increment by 1 minute\n nextTime.setTime(nextTime.getTime() + 60 * 1000)\n return nextTime\n}\n\n/**\n * Get the next valid value for a cron part\n */\nfunction getNextValidCronValue(currentValue: number, cronPart: string): number {\n if (cronPart === '*') {return currentValue + 1}\n\n // Handle specific values and ranges\n const values = parseCronPart(cronPart)\n return values.find(v => v > currentValue) || values[0]\n}\n\n/**\n * Parse a cron part into an array of valid values\n */\nfunction parseCronPart(cronPart: string): number[] {\n if (cronPart === '*') {return []}\n\n const values: number[] = []\n\n // Handle comma-separated values\n if (cronPart.includes(',')) {\n cronPart.split(',').forEach(part => {\n values.push(...parseCronPart(part.trim()))\n })\n return values.sort((a, b) => a - b)\n }\n\n // Handle ranges\n if (cronPart.includes('-')) {\n const [start, end] = cronPart.split('-').map(n => parseInt(n, 10))\n for (let i = start; i <= end; i++) {\n values.push(i)\n }\n return values\n }\n\n // Handle step values\n if (cronPart.includes('/')) {\n const [range, step] = cronPart.split('/')\n const stepNum = parseInt(step, 10)\n\n if (range === '*') {\n // For wildcards with steps, return empty - handled elsewhere\n return []\n }\n\n const baseValues = parseCronPart(range)\n return baseValues.filter((_, index) => index % stepNum === 0)\n }\n\n // Single value\n values.push(parseInt(cronPart, 10))\n return values\n}\n\n/**\n * Check if a value matches a cron expression part\n */\nfunction matchesCronPart(value: number, cronPart: string): boolean {\n if (cronPart === '*') {return true}\n\n // Handle step values (e.g., */5)\n if (cronPart.includes('/')) {\n const [range, step] = cronPart.split('/')\n const stepNum = parseInt(step, 10)\n\n if (range === '*') {\n return value % stepNum === 0\n }\n }\n\n // Handle ranges (e.g., 1-5)\n if (cronPart.includes('-')) {\n const [start, end] = cronPart.split('-').map(n => parseInt(n, 10))\n return value >= start && value <= end\n }\n\n // Handle comma-separated values (e.g., 1,3,5)\n if (cronPart.includes(',')) {\n const values = cronPart.split(',').map(n => parseInt(n, 10))\n return values.includes(value)\n }\n\n // Handle single value\n const cronValue = parseInt(cronPart, 10)\n return value === cronValue\n}\n\n/**\n * Handle re-queueing of cron jobs after they execute\n * This ensures the job runs again at the next scheduled time\n */\nexport async function requeueCronJob(\n workflowId: string,\n cronExpression: string,\n timezone: string | undefined,\n payload: Payload,\n logger: Payload['logger']\n): Promise<void> {\n try {\n // Queue the job to run at the next scheduled time\n await payload.jobs.queue({\n input: { cronExpression, timezone, workflowId },\n task: 'workflow-cron-executor',\n waitUntil: getNextCronTime(cronExpression, timezone)\n })\n\n logger.debug({\n nextRun: getNextCronTime(cronExpression, timezone),\n timezone: timezone || 'UTC',\n workflowId\n }, 'Re-queued cron job')\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n }, 'Failed to re-queue cron job')\n }\n}\n\n/**\n * Register or update cron jobs for a specific workflow\n */\nexport async function updateWorkflowCronJobs(\n workflowId: string,\n payload: Payload,\n logger: Payload['logger']\n): Promise<void> {\n try {\n // First, cancel any existing cron jobs for this workflow\n cancelWorkflowCronJobs(workflowId, payload, logger)\n\n // Get the workflow\n const workflow = await payload.findByID({\n id: workflowId,\n collection: 'workflows',\n depth: 0\n })\n\n if (!workflow) {\n logger.warn({ workflowId }, 'Workflow not found for cron job update')\n return\n }\n\n const triggers = workflow.triggers as Array<{\n cronExpression?: string\n timezone?: string\n type: string\n }>\n\n // Find all cron triggers for this workflow\n const cronTriggers = triggers?.filter(t => t.type === 'cron-trigger') || []\n\n if (cronTriggers.length === 0) {\n logger.debug({ workflowId }, 'No cron triggers found for workflow')\n return\n }\n\n let scheduledJobs = 0\n\n for (const trigger of cronTriggers) {\n if (trigger.cronExpression) {\n try {\n // Validate cron expression before queueing\n if (!validateCronExpression(trigger.cronExpression)) {\n logger.error({\n cronExpression: trigger.cronExpression,\n workflowId,\n workflowName: workflow.name\n }, 'Invalid cron expression format')\n continue\n }\n\n // Validate timezone if provided\n if (trigger.timezone) {\n try {\n new Intl.DateTimeFormat('en', { timeZone: trigger.timezone })\n } catch {\n logger.error({\n timezone: trigger.timezone,\n workflowId,\n workflowName: workflow.name\n }, 'Invalid timezone specified')\n continue\n }\n }\n\n // Calculate next execution time\n const nextExecution = getNextCronTime(trigger.cronExpression, trigger.timezone)\n\n // Queue the job\n await payload.jobs.queue({\n input: { cronExpression: trigger.cronExpression, timezone: trigger.timezone, workflowId },\n task: 'workflow-cron-executor',\n waitUntil: nextExecution\n })\n\n scheduledJobs++\n\n logger.info({\n cronExpression: trigger.cronExpression,\n nextExecution: nextExecution.toISOString(),\n timezone: trigger.timezone || 'UTC',\n workflowId,\n workflowName: workflow.name\n }, 'Scheduled cron job for workflow')\n } catch (error) {\n logger.error({\n cronExpression: trigger.cronExpression,\n error: error instanceof Error ? error.message : 'Unknown error',\n timezone: trigger.timezone,\n workflowId,\n workflowName: workflow.name\n }, 'Failed to schedule cron job')\n }\n }\n }\n\n if (scheduledJobs > 0) {\n logger.info({ scheduledJobs, workflowId }, 'Updated cron jobs for workflow')\n }\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n }, 'Failed to update workflow cron jobs')\n }\n}\n\n/**\n * Cancel all cron jobs for a specific workflow\n */\nexport function cancelWorkflowCronJobs(\n workflowId: string,\n payload: Payload,\n logger: Payload['logger']\n): void {\n try {\n // Note: PayloadCMS job system doesn't have a built-in way to cancel specific jobs by input\n // This is a limitation we need to work around\n // For now, we log that we would cancel jobs for this workflow\n logger.debug({ workflowId }, 'Would cancel existing cron jobs for workflow (PayloadCMS limitation: cannot selectively cancel jobs)')\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n }, 'Failed to cancel workflow cron jobs')\n }\n}\n\n/**\n * Remove cron jobs for a deleted workflow\n */\nexport function removeWorkflowCronJobs(\n workflowId: string,\n payload: Payload,\n logger: Payload['logger']\n): void {\n try {\n cancelWorkflowCronJobs(workflowId, payload, logger)\n logger.info({ workflowId }, 'Removed cron jobs for deleted workflow')\n } catch (error) {\n logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n workflowId\n }, 'Failed to remove workflow cron jobs')\n }\n}\n"],"names":["cron","WorkflowExecutor","getConfigLogger","generateCronTasks","config","logger","cronTask","slug","handler","input","req","cronExpression","timezone","workflowId","payload","child","plugin","workflow","findByID","id","collection","depth","Error","context","steps","trigger","type","triggeredAt","Date","toISOString","executor","triggers","matchingTrigger","find","condition","conditionMet","evaluateCondition","info","workflowName","name","requeueCronJob","output","executedAt","reason","status","state","execute","error","message","includes","catch","requeueError","jobs","tasks","task","debug","push","registerCronJobs","workflows","limit","where","equals","docs","length","cronTriggers","filter","t","validateCronExpression","Intl","DateTimeFormat","timeZone","nextExecution","getNextCronTime","queue","waitUntil","warn","validate","now","options","schedule","cronParts","trim","split","destroy","minutePart","hourPart","dayPart","monthPart","weekdayPart","testTime","getTime","setSeconds","maxIterations","iterations","minute","getMinutes","hour","getHours","dayOfMonth","getDate","month","getMonth","dayOfWeek","getDay","matchesCronPart","incrementTimeForCronPattern","currentTime","_dayPart","_monthPart","_weekdayPart","nextTime","targetMinute","getNextValidCronValue","setHours","setMinutes","targetHour","setDate","setTime","currentValue","cronPart","values","parseCronPart","v","forEach","part","sort","a","b","start","end","map","n","parseInt","i","range","step","stepNum","baseValues","_","index","value","cronValue","nextRun","updateWorkflowCronJobs","cancelWorkflowCronJobs","scheduledJobs","removeWorkflowCronJobs"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ describe('PayloadCMS Automation Plugin', ()=>{
3
+ it('should export the plugin function from server export', async ()=>{
4
+ const { workflowsPlugin } = await import('../exports/server.js');
5
+ expect(workflowsPlugin).toBeDefined();
6
+ expect(typeof workflowsPlugin).toBe('function');
7
+ });
8
+ it('should have the correct package name', async ()=>{
9
+ // Basic test to ensure the plugin can be imported
10
+ expect(true).toBe(true);
11
+ });
12
+ });
13
+
14
+ //# sourceMappingURL=basic.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/test/basic.test.ts"],"sourcesContent":["import { describe, it, expect } from 'vitest'\n\ndescribe('PayloadCMS Automation Plugin', () => {\n it('should export the plugin function from server export', async () => {\n const { workflowsPlugin } = await import('../exports/server.js')\n expect(workflowsPlugin).toBeDefined()\n expect(typeof workflowsPlugin).toBe('function')\n })\n\n it('should have the correct package name', async () => {\n // Basic test to ensure the plugin can be imported\n expect(true).toBe(true)\n })\n})"],"names":["describe","it","expect","workflowsPlugin","toBeDefined","toBe"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,EAAE,EAAEC,MAAM,QAAQ,SAAQ;AAE7CF,SAAS,gCAAgC;IACvCC,GAAG,wDAAwD;QACzD,MAAM,EAAEE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC;QACzCD,OAAOC,iBAAiBC,WAAW;QACnCF,OAAO,OAAOC,iBAAiBE,IAAI,CAAC;IACtC;IAEAJ,GAAG,wCAAwC;QACzC,kDAAkD;QAClDC,OAAO,MAAMG,IAAI,CAAC;IACpB;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xtr-dev/payload-automation",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "description": "PayloadCMS Automation Plugin - Comprehensive workflow automation system with visual workflow building, execution tracking, and step types",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,10 +30,10 @@
30
30
  "types": "./dist/exports/views.d.ts",
31
31
  "default": "./dist/exports/views.js"
32
32
  },
33
- "./steps": {
34
- "import": "./dist/steps/index.js",
35
- "types": "./dist/steps/index.d.ts",
36
- "default": "./dist/steps/index.js"
33
+ "./server": {
34
+ "import": "./dist/exports/server.js",
35
+ "types": "./dist/exports/server.d.ts",
36
+ "default": "./dist/exports/server.js"
37
37
  }
38
38
  },
39
39
  "main": "dist/index.js",