@xtr-dev/payload-automation 0.0.1 → 0.0.2

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.
@@ -57,8 +57,8 @@ import { getConfigLogger } from './logger.js';
57
57
  return {
58
58
  output: {
59
59
  executedAt: new Date().toISOString(),
60
- status: 'skipped',
61
60
  reason: 'Condition not met',
61
+ status: 'skipped',
62
62
  workflowId
63
63
  },
64
64
  state: 'succeeded'
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugin/cron-scheduler.ts"],"sourcesContent":["import type {Config, Payload, TaskConfig} from 'payload'\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 status: 'skipped',\n reason: 'Condition not met',\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","status","reason","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 * 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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"}
@@ -38,7 +38,7 @@ export function initWebhookEndpoint(config, webhookPrefix = 'webhook') {
38
38
  status: 404
39
39
  });
40
40
  }
41
- // Create workflow executor for this request
41
+ // Create a workflow executor for this request
42
42
  const logger = initializeLogger(req.payload);
43
43
  const executor = new WorkflowExecutor(req.payload, logger);
44
44
  const executionPromises = workflows.docs.map(async (workflow)=>{
@@ -68,9 +68,9 @@ export function initWebhookEndpoint(config, webhookPrefix = 'webhook') {
68
68
  workflowName: workflow.name
69
69
  }, 'Webhook trigger condition not met, skipping workflow');
70
70
  return {
71
+ reason: 'Condition not met',
71
72
  status: 'skipped',
72
- workflowId: workflow.id,
73
- reason: 'Condition not met'
73
+ workflowId: workflow.id
74
74
  };
75
75
  }
76
76
  logger.info({
@@ -136,7 +136,7 @@ export function initWebhookEndpoint(config, webhookPrefix = 'webhook') {
136
136
  method: 'post',
137
137
  path: `${normalizedPrefix}/:path`
138
138
  };
139
- // Check if webhook endpoint already exists to avoid duplicates
139
+ // Check if the webhook endpoint already exists to avoid duplicates
140
140
  const existingEndpoint = config.endpoints?.find((endpoint)=>endpoint.path === webhookEndpoint.path && endpoint.method === webhookEndpoint.method);
141
141
  if (!existingEndpoint) {
142
142
  // Combine existing endpoints with the webhook endpoint
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugin/init-webhook.ts"],"sourcesContent":["import type {Config, PayloadRequest} from 'payload'\n\nimport {type Workflow, WorkflowExecutor} from '../core/workflow-executor.js'\nimport {getConfigLogger, initializeLogger} from './logger.js'\n\nexport function initWebhookEndpoint(config: Config, webhookPrefix = 'webhook'): void {\n const logger = getConfigLogger()\n // Ensure the prefix starts with a slash\n const normalizedPrefix = webhookPrefix.startsWith('/') ? webhookPrefix : `/${webhookPrefix}`\n logger.debug(`Adding webhook endpoint to config with prefix: ${normalizedPrefix}`)\n logger.debug('Current config.endpoints length:', config.endpoints?.length || 0)\n\n // Define webhook endpoint\n const webhookEndpoint = {\n handler: async (req: PayloadRequest) => {\n const {path} = req.routeParams as { path: string }\n const webhookData = req.body || {}\n\n logger.debug('Webhook endpoint handler called, path: ' + path)\n\n try {\n // Find workflows with matching webhook triggers\n const workflows = await req.payload.find({\n collection: 'workflows',\n depth: 2,\n limit: 100,\n req,\n where: {\n 'triggers.type': {\n equals: 'webhook-trigger'\n },\n 'triggers.webhookPath': {\n equals: path\n }\n }\n })\n\n if (workflows.docs.length === 0) {\n return new Response(\n JSON.stringify({error: 'No workflows found for this webhook path'}),\n {\n headers: {'Content-Type': 'application/json'},\n status: 404\n }\n )\n }\n\n // Create workflow executor for this request\n const logger = initializeLogger(req.payload)\n const executor = new WorkflowExecutor(req.payload, logger)\n\n const executionPromises = workflows.docs.map(async (workflow) => {\n try {\n // Create execution context for the webhook trigger\n const context = {\n steps: {},\n trigger: {\n type: 'webhook',\n data: webhookData,\n headers: Object.fromEntries(req.headers?.entries() || []),\n path,\n req\n }\n }\n\n // Find the matching trigger and check its condition if present\n const triggers = workflow.triggers as Array<{\n condition?: string\n type: string\n webhookPath?: string\n }>\n\n const matchingTrigger = triggers?.find(trigger =>\n trigger.type === 'webhook-trigger' &&\n trigger.webhookPath === path\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 path,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Webhook trigger condition not met, skipping workflow')\n \n return { status: 'skipped', workflowId: workflow.id, reason: 'Condition not met' }\n }\n \n logger.info({\n condition: matchingTrigger.condition,\n path,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Webhook trigger condition met')\n }\n\n // Execute the workflow\n await executor.execute(workflow as Workflow, context, req)\n\n return { status: 'triggered', workflowId: workflow.id }\n } catch (error) {\n return {\n error: error instanceof Error ? error.message : 'Unknown error',\n status: 'failed',\n workflowId: workflow.id\n }\n }\n })\n\n const results = await Promise.allSettled(executionPromises)\n const resultsData = results.map((result, index) => {\n const baseResult = { workflowId: workflows.docs[index].id }\n if (result.status === 'fulfilled') {\n return { ...baseResult, ...result.value }\n } else {\n return { ...baseResult, error: result.reason, status: 'failed' }\n }\n })\n\n return new Response(\n JSON.stringify({\n message: `Triggered ${workflows.docs.length} workflow(s)`,\n results: resultsData\n }),\n {\n headers: { 'Content-Type': 'application/json' },\n status: 200\n }\n )\n\n } catch (error) {\n return new Response(\n JSON.stringify({\n details: error instanceof Error ? error.message : 'Unknown error',\n error: 'Failed to process webhook'\n }),\n {\n headers: { 'Content-Type': 'application/json' },\n status: 500\n }\n )\n }\n },\n method: 'post' as const,\n path: `${normalizedPrefix}/:path`\n }\n\n // Check if webhook endpoint already exists to avoid duplicates\n const existingEndpoint = config.endpoints?.find(endpoint => \n endpoint.path === webhookEndpoint.path && endpoint.method === webhookEndpoint.method\n )\n \n if (!existingEndpoint) {\n // Combine existing endpoints with the webhook endpoint\n config.endpoints = [...(config.endpoints || []), webhookEndpoint]\n logger.debug(`Webhook endpoint added at path: ${webhookEndpoint.path}`)\n logger.debug('New config.endpoints length:', config.endpoints.length)\n } else {\n logger.debug(`Webhook endpoint already exists at path: ${webhookEndpoint.path}`)\n }\n}\n"],"names":["WorkflowExecutor","getConfigLogger","initializeLogger","initWebhookEndpoint","config","webhookPrefix","logger","normalizedPrefix","startsWith","debug","endpoints","length","webhookEndpoint","handler","req","path","routeParams","webhookData","body","workflows","payload","find","collection","depth","limit","where","equals","docs","Response","JSON","stringify","error","headers","status","executor","executionPromises","map","workflow","context","steps","trigger","type","data","Object","fromEntries","entries","triggers","matchingTrigger","webhookPath","condition","conditionMet","evaluateCondition","info","workflowId","id","workflowName","name","reason","execute","Error","message","results","Promise","allSettled","resultsData","result","index","baseResult","value","details","method","existingEndpoint","endpoint"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/plugin/init-webhook.ts"],"sourcesContent":["import type {Config, PayloadRequest} from 'payload'\n\nimport {type Workflow, WorkflowExecutor} from '../core/workflow-executor.js'\nimport {getConfigLogger, initializeLogger} from './logger.js'\n\nexport function initWebhookEndpoint(config: Config, webhookPrefix = 'webhook'): void {\n const logger = getConfigLogger()\n // Ensure the prefix starts with a slash\n const normalizedPrefix = webhookPrefix.startsWith('/') ? webhookPrefix : `/${webhookPrefix}`\n logger.debug(`Adding webhook endpoint to config with prefix: ${normalizedPrefix}`)\n logger.debug('Current config.endpoints length:', config.endpoints?.length || 0)\n\n // Define webhook endpoint\n const webhookEndpoint = {\n handler: async (req: PayloadRequest) => {\n const {path} = req.routeParams as { path: string }\n const webhookData = req.body || {}\n\n logger.debug('Webhook endpoint handler called, path: ' + path)\n\n try {\n // Find workflows with matching webhook triggers\n const workflows = await req.payload.find({\n collection: 'workflows',\n depth: 2,\n limit: 100,\n req,\n where: {\n 'triggers.type': {\n equals: 'webhook-trigger'\n },\n 'triggers.webhookPath': {\n equals: path\n }\n }\n })\n\n if (workflows.docs.length === 0) {\n return new Response(\n JSON.stringify({error: 'No workflows found for this webhook path'}),\n {\n headers: {'Content-Type': 'application/json'},\n status: 404\n }\n )\n }\n\n // Create a workflow executor for this request\n const logger = initializeLogger(req.payload)\n const executor = new WorkflowExecutor(req.payload, logger)\n\n const executionPromises = workflows.docs.map(async (workflow) => {\n try {\n // Create execution context for the webhook trigger\n const context = {\n steps: {},\n trigger: {\n type: 'webhook',\n data: webhookData,\n headers: Object.fromEntries(req.headers?.entries() || []),\n path,\n req\n }\n }\n\n // Find the matching trigger and check its condition if present\n const triggers = workflow.triggers as Array<{\n condition?: string\n type: string\n webhookPath?: string\n }>\n\n const matchingTrigger = triggers?.find(trigger =>\n trigger.type === 'webhook-trigger' &&\n trigger.webhookPath === path\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 path,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Webhook trigger condition not met, skipping workflow')\n\n return { reason: 'Condition not met', status: 'skipped', workflowId: workflow.id }\n }\n\n logger.info({\n condition: matchingTrigger.condition,\n path,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Webhook trigger condition met')\n }\n\n // Execute the workflow\n await executor.execute(workflow as Workflow, context, req)\n\n return { status: 'triggered', workflowId: workflow.id }\n } catch (error) {\n return {\n error: error instanceof Error ? error.message : 'Unknown error',\n status: 'failed',\n workflowId: workflow.id\n }\n }\n })\n\n const results = await Promise.allSettled(executionPromises)\n const resultsData = results.map((result, index) => {\n const baseResult = { workflowId: workflows.docs[index].id }\n if (result.status === 'fulfilled') {\n return { ...baseResult, ...result.value }\n } else {\n return { ...baseResult, error: result.reason, status: 'failed' }\n }\n })\n\n return new Response(\n JSON.stringify({\n message: `Triggered ${workflows.docs.length} workflow(s)`,\n results: resultsData\n }),\n {\n headers: { 'Content-Type': 'application/json' },\n status: 200\n }\n )\n\n } catch (error) {\n return new Response(\n JSON.stringify({\n details: error instanceof Error ? error.message : 'Unknown error',\n error: 'Failed to process webhook'\n }),\n {\n headers: { 'Content-Type': 'application/json' },\n status: 500\n }\n )\n }\n },\n method: 'post' as const,\n path: `${normalizedPrefix}/:path`\n }\n\n // Check if the webhook endpoint already exists to avoid duplicates\n const existingEndpoint = config.endpoints?.find(endpoint =>\n endpoint.path === webhookEndpoint.path && endpoint.method === webhookEndpoint.method\n )\n\n if (!existingEndpoint) {\n // Combine existing endpoints with the webhook endpoint\n config.endpoints = [...(config.endpoints || []), webhookEndpoint]\n logger.debug(`Webhook endpoint added at path: ${webhookEndpoint.path}`)\n logger.debug('New config.endpoints length:', config.endpoints.length)\n } else {\n logger.debug(`Webhook endpoint already exists at path: ${webhookEndpoint.path}`)\n }\n}\n"],"names":["WorkflowExecutor","getConfigLogger","initializeLogger","initWebhookEndpoint","config","webhookPrefix","logger","normalizedPrefix","startsWith","debug","endpoints","length","webhookEndpoint","handler","req","path","routeParams","webhookData","body","workflows","payload","find","collection","depth","limit","where","equals","docs","Response","JSON","stringify","error","headers","status","executor","executionPromises","map","workflow","context","steps","trigger","type","data","Object","fromEntries","entries","triggers","matchingTrigger","webhookPath","condition","conditionMet","evaluateCondition","info","workflowId","id","workflowName","name","reason","execute","Error","message","results","Promise","allSettled","resultsData","result","index","baseResult","value","details","method","existingEndpoint","endpoint"],"mappings":"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"}
@@ -3,10 +3,10 @@ import type { Payload } from 'payload';
3
3
  * Get a logger for config-time use (before Payload initialization)
4
4
  */
5
5
  export declare function getConfigLogger(): {
6
- debug: (message: string, ...args: any[]) => void;
7
- error: (message: string, ...args: any[]) => void;
8
- info: (message: string, ...args: any[]) => void;
9
- warn: (message: string, ...args: any[]) => void;
6
+ debug: <T>(message: string, ...args: T[]) => void;
7
+ error: <T>(message: string, ...args: T[]) => void;
8
+ info: <T>(message: string, ...args: T[]) => void;
9
+ warn: <T>(message: string, ...args: T[]) => void;
10
10
  };
11
11
  /**
12
12
  * Initialize the plugin logger using Payload's Pino instance
@@ -5,17 +5,27 @@ let pluginLogger = null;
5
5
  * Uses console with plugin prefix since Payload logger isn't available yet
6
6
  */ const configLogger = {
7
7
  debug: (message, ...args)=>{
8
- if (process.env.NODE_ENV === 'development') {
9
- console.log(`[payload-automation] ${message}`, ...args);
8
+ if (!process.env.PAYLOAD_AUTOMATION_LOGGING) {
9
+ return;
10
10
  }
11
+ console.log(`[payload-automation] ${message}`, ...args);
11
12
  },
12
13
  error: (message, ...args)=>{
14
+ if (!process.env.PAYLOAD_AUTOMATION_LOGGING) {
15
+ return;
16
+ }
13
17
  console.error(`[payload-automation] ${message}`, ...args);
14
18
  },
15
19
  info: (message, ...args)=>{
20
+ if (!process.env.PAYLOAD_AUTOMATION_LOGGING) {
21
+ return;
22
+ }
16
23
  console.log(`[payload-automation] ${message}`, ...args);
17
24
  },
18
25
  warn: (message, ...args)=>{
26
+ if (!process.env.PAYLOAD_AUTOMATION_LOGGING) {
27
+ return;
28
+ }
19
29
  console.warn(`[payload-automation] ${message}`, ...args);
20
30
  }
21
31
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugin/logger.ts"],"sourcesContent":["import type { Payload } from 'payload'\n\n// Global logger instance - use Payload's logger type\nlet pluginLogger: Payload['logger'] | null = null\n\n/**\n * Simple config-time logger for use during plugin configuration\n * Uses console with plugin prefix since Payload logger isn't available yet\n */\nconst configLogger = {\n debug: (message: string, ...args: any[]) => {\n if (process.env.NODE_ENV === 'development') {\n console.log(`[payload-automation] ${message}`, ...args)\n }\n },\n error: (message: string, ...args: any[]) => {\n console.error(`[payload-automation] ${message}`, ...args)\n },\n info: (message: string, ...args: any[]) => {\n console.log(`[payload-automation] ${message}`, ...args)\n },\n warn: (message: string, ...args: any[]) => {\n console.warn(`[payload-automation] ${message}`, ...args)\n }\n}\n\n/**\n * Get a logger for config-time use (before Payload initialization)\n */\nexport function getConfigLogger() {\n return configLogger\n}\n\n/**\n * Initialize the plugin logger using Payload's Pino instance\n * This creates a child logger with plugin identification\n */\nexport function initializeLogger(payload: Payload): Payload['logger'] {\n // Create a child logger with plugin identification\n pluginLogger = payload.logger.child({\n plugin: '@xtr-dev/payload-automation'\n })\n return pluginLogger\n}\n\n/**\n * Get the plugin logger instance\n * Throws error if not initialized\n */\nexport function getLogger(): Payload['logger'] {\n if (!pluginLogger) {\n throw new Error('@xtr-dev/payload-automation: Logger not initialized. Make sure the plugin is properly configured.')\n }\n\n return pluginLogger\n}\n"],"names":["pluginLogger","configLogger","debug","message","args","process","env","NODE_ENV","console","log","error","info","warn","getConfigLogger","initializeLogger","payload","logger","child","plugin","getLogger","Error"],"mappings":"AAEA,qDAAqD;AACrD,IAAIA,eAAyC;AAE7C;;;CAGC,GACD,MAAMC,eAAe;IACnBC,OAAO,CAACC,SAAiB,GAAGC;QAC1B,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;YAC1CC,QAAQC,GAAG,CAAC,CAAC,qBAAqB,EAAEN,SAAS,KAAKC;QACpD;IACF;IACAM,OAAO,CAACP,SAAiB,GAAGC;QAC1BI,QAAQE,KAAK,CAAC,CAAC,qBAAqB,EAAEP,SAAS,KAAKC;IACtD;IACAO,MAAM,CAACR,SAAiB,GAAGC;QACzBI,QAAQC,GAAG,CAAC,CAAC,qBAAqB,EAAEN,SAAS,KAAKC;IACpD;IACAQ,MAAM,CAACT,SAAiB,GAAGC;QACzBI,QAAQI,IAAI,CAAC,CAAC,qBAAqB,EAAET,SAAS,KAAKC;IACrD;AACF;AAEA;;CAEC,GACD,OAAO,SAASS;IACd,OAAOZ;AACT;AAEA;;;CAGC,GACD,OAAO,SAASa,iBAAiBC,OAAgB;IAC/C,mDAAmD;IACnDf,eAAee,QAAQC,MAAM,CAACC,KAAK,CAAC;QAClCC,QAAQ;IACV;IACA,OAAOlB;AACT;AAEA;;;CAGC,GACD,OAAO,SAASmB;IACd,IAAI,CAACnB,cAAc;QACjB,MAAM,IAAIoB,MAAM;IAClB;IAEA,OAAOpB;AACT"}
1
+ {"version":3,"sources":["../../src/plugin/logger.ts"],"sourcesContent":["import type { Payload } from 'payload'\n\n// Global logger instance - use Payload's logger type\nlet pluginLogger: null | Payload['logger'] = null\n\n/**\n * Simple config-time logger for use during plugin configuration\n * Uses console with plugin prefix since Payload logger isn't available yet\n */\nconst configLogger = {\n debug: <T>(message: string, ...args: T[]) => {\n if (!process.env.PAYLOAD_AUTOMATION_LOGGING) {return}\n console.log(`[payload-automation] ${message}`, ...args)\n },\n error: <T>(message: string, ...args: T[]) => {\n if (!process.env.PAYLOAD_AUTOMATION_LOGGING) {return}\n console.error(`[payload-automation] ${message}`, ...args)\n },\n info: <T>(message: string, ...args: T[]) => {\n if (!process.env.PAYLOAD_AUTOMATION_LOGGING) {return}\n console.log(`[payload-automation] ${message}`, ...args)\n },\n warn: <T>(message: string, ...args: T[]) => {\n if (!process.env.PAYLOAD_AUTOMATION_LOGGING) {return}\n console.warn(`[payload-automation] ${message}`, ...args)\n }\n}\n\n/**\n * Get a logger for config-time use (before Payload initialization)\n */\nexport function getConfigLogger() {\n return configLogger\n}\n\n/**\n * Initialize the plugin logger using Payload's Pino instance\n * This creates a child logger with plugin identification\n */\nexport function initializeLogger(payload: Payload): Payload['logger'] {\n // Create a child logger with plugin identification\n pluginLogger = payload.logger.child({\n plugin: '@xtr-dev/payload-automation'\n })\n return pluginLogger\n}\n\n/**\n * Get the plugin logger instance\n * Throws error if not initialized\n */\nexport function getLogger(): Payload['logger'] {\n if (!pluginLogger) {\n throw new Error('@xtr-dev/payload-automation: Logger not initialized. Make sure the plugin is properly configured.')\n }\n\n return pluginLogger\n}\n"],"names":["pluginLogger","configLogger","debug","message","args","process","env","PAYLOAD_AUTOMATION_LOGGING","console","log","error","info","warn","getConfigLogger","initializeLogger","payload","logger","child","plugin","getLogger","Error"],"mappings":"AAEA,qDAAqD;AACrD,IAAIA,eAAyC;AAE7C;;;CAGC,GACD,MAAMC,eAAe;IACnBC,OAAO,CAAIC,SAAiB,GAAGC;QAC7B,IAAI,CAACC,QAAQC,GAAG,CAACC,0BAA0B,EAAE;YAAC;QAAM;QACpDC,QAAQC,GAAG,CAAC,CAAC,qBAAqB,EAAEN,SAAS,KAAKC;IACpD;IACAM,OAAO,CAAIP,SAAiB,GAAGC;QAC7B,IAAI,CAACC,QAAQC,GAAG,CAACC,0BAA0B,EAAE;YAAC;QAAM;QACpDC,QAAQE,KAAK,CAAC,CAAC,qBAAqB,EAAEP,SAAS,KAAKC;IACtD;IACAO,MAAM,CAAIR,SAAiB,GAAGC;QAC5B,IAAI,CAACC,QAAQC,GAAG,CAACC,0BAA0B,EAAE;YAAC;QAAM;QACpDC,QAAQC,GAAG,CAAC,CAAC,qBAAqB,EAAEN,SAAS,KAAKC;IACpD;IACAQ,MAAM,CAAIT,SAAiB,GAAGC;QAC5B,IAAI,CAACC,QAAQC,GAAG,CAACC,0BAA0B,EAAE;YAAC;QAAM;QACpDC,QAAQI,IAAI,CAAC,CAAC,qBAAqB,EAAET,SAAS,KAAKC;IACrD;AACF;AAEA;;CAEC,GACD,OAAO,SAASS;IACd,OAAOZ;AACT;AAEA;;;CAGC,GACD,OAAO,SAASa,iBAAiBC,OAAgB;IAC/C,mDAAmD;IACnDf,eAAee,QAAQC,MAAM,CAACC,KAAK,CAAC;QAClCC,QAAQ;IACV;IACA,OAAOlB;AACT;AAEA;;;CAGC,GACD,OAAO,SAASmB;IACd,IAAI,CAACnB,cAAc;QACjB,MAAM,IAAIoB,MAAM;IAClB;IAEA,OAAOpB;AACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xtr-dev/payload-automation",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
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",