@xtr-dev/payload-automation 0.0.42 → 0.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +221 -49
- package/dist/collections/Steps.d.ts +6 -0
- package/dist/collections/Steps.js +166 -0
- package/dist/collections/Steps.js.map +1 -0
- package/dist/collections/Triggers.d.ts +7 -0
- package/dist/collections/Triggers.js +224 -0
- package/dist/collections/Triggers.js.map +1 -0
- package/dist/collections/Workflow.d.ts +5 -2
- package/dist/collections/Workflow.js +179 -39
- package/dist/collections/Workflow.js.map +1 -1
- package/dist/collections/WorkflowRuns.d.ts +4 -0
- package/dist/collections/WorkflowRuns.js +219 -24
- package/dist/collections/WorkflowRuns.js.map +1 -1
- package/dist/components/WorkflowBuilder/WorkflowBuilder.js.map +1 -1
- package/dist/core/expression-engine.d.ts +58 -0
- package/dist/core/expression-engine.js +191 -0
- package/dist/core/expression-engine.js.map +1 -0
- package/dist/core/workflow-executor.d.ts +70 -56
- package/dist/core/workflow-executor.js +354 -677
- package/dist/core/workflow-executor.js.map +1 -1
- package/dist/exports/client.js +1 -3
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/views.js +2 -4
- package/dist/exports/views.js.map +1 -1
- package/dist/fields/parameter.js +8 -3
- package/dist/fields/parameter.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin/config-types.d.ts +43 -5
- package/dist/plugin/config-types.js +3 -1
- package/dist/plugin/config-types.js.map +1 -1
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.js +82 -28
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/trigger-hook.d.ts +13 -0
- package/dist/plugin/trigger-hook.js +184 -0
- package/dist/plugin/trigger-hook.js.map +1 -0
- package/dist/steps/create-step.d.ts +66 -0
- package/dist/steps/create-step.js +59 -0
- package/dist/steps/create-step.js.map +1 -0
- package/dist/steps/index.d.ts +2 -0
- package/dist/steps/index.js +3 -0
- package/dist/steps/index.js.map +1 -1
- package/dist/steps/read-document-handler.js +1 -1
- package/dist/steps/read-document-handler.js.map +1 -1
- package/dist/steps/update-document-handler.js +1 -1
- package/dist/steps/update-document-handler.js.map +1 -1
- package/dist/triggers/hook-options.d.ts +34 -0
- package/dist/triggers/hook-options.js +158 -0
- package/dist/triggers/hook-options.js.map +1 -0
- package/dist/triggers/index.d.ts +2 -2
- package/dist/triggers/index.js +1 -2
- package/dist/triggers/index.js.map +1 -1
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.js +4 -5
- package/dist/types/index.js.map +1 -1
- package/dist/utils/validation.d.ts +64 -0
- package/dist/utils/validation.js +107 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +2 -1
- package/dist/plugin/collection-hook.d.ts +0 -1
- package/dist/plugin/collection-hook.js +0 -92
- package/dist/plugin/collection-hook.js.map +0 -1
- package/dist/plugin/global-hook.d.ts +0 -1
- package/dist/plugin/global-hook.js +0 -83
- package/dist/plugin/global-hook.js.map +0 -1
- package/dist/triggers/collection-trigger.d.ts +0 -2
- package/dist/triggers/collection-trigger.js +0 -36
- package/dist/triggers/collection-trigger.js.map +0 -1
- package/dist/triggers/global-trigger.d.ts +0 -2
- package/dist/triggers/global-trigger.js +0 -29
- package/dist/triggers/global-trigger.js.map +0 -1
- package/dist/triggers/types.d.ts +0 -5
- package/dist/triggers/types.js +0 -3
- package/dist/triggers/types.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/workflow-executor.ts"],"sourcesContent":["import type { Payload, PayloadRequest } from 'payload'\n\n// We need to reference the generated types dynamically since they're not available at build time\n// Using generic types and casting where necessary\nexport type PayloadWorkflow = {\n id: number\n name: string\n description?: null | string\n triggers?: Array<{\n type?: null | string\n condition?: null | string\n parameters?: {\n collectionSlug?: null | string\n operation?: null | string\n global?: null | string\n globalOperation?: null | string\n [key: string]: unknown\n } | null\n [key: string]: unknown\n }> | null\n steps?: Array<{\n type?: null | string\n name?: null | string\n input?: unknown\n dependencies?: null | string[]\n condition?: null | string\n [key: string]: unknown\n }> | null\n [key: string]: unknown\n}\n\nimport Handlebars from 'handlebars'\n\n// Helper type to extract workflow step data from the generated types\nexport type WorkflowStep = {\n name: string // Ensure name is always present for our execution logic\n} & NonNullable<PayloadWorkflow['steps']>[0]\n\n// Helper type to extract workflow trigger data from the generated types\nexport type WorkflowTrigger = {\n type: string // Ensure type is always present for our execution logic\n} & NonNullable<PayloadWorkflow['triggers']>[0]\n\nexport interface ExecutionContext {\n steps: Record<string, any>\n trigger: Record<string, any>\n}\n\nexport class WorkflowExecutor {\n constructor(\n private payload: Payload,\n private logger: Payload['logger']\n ) {}\n\n /**\n * Convert string values to appropriate types based on common patterns\n */\n private convertValueType(value: unknown, key: string): unknown {\n if (typeof value !== 'string') {\n return value\n }\n\n // Type conversion patterns based on field names and values\n const numericFields = ['timeout', 'retries', 'delay', 'port', 'limit', 'offset', 'count', 'max', 'min']\n const booleanFields = ['enabled', 'required', 'active', 'success', 'failed', 'complete']\n\n // Convert numeric fields\n if (numericFields.some(field => key.toLowerCase().includes(field))) {\n const numValue = Number(value)\n if (!isNaN(numValue)) {\n this.logger.debug({\n key,\n originalValue: value,\n convertedValue: numValue\n }, 'Auto-converted field to number')\n return numValue\n }\n }\n\n // Convert boolean fields\n if (booleanFields.some(field => key.toLowerCase().includes(field))) {\n if (value === 'true') return true\n if (value === 'false') return false\n }\n\n // Try to parse as number if it looks numeric\n if (/^\\d+$/.test(value)) {\n const numValue = parseInt(value, 10)\n this.logger.debug({\n key,\n originalValue: value,\n convertedValue: numValue\n }, 'Auto-converted numeric string to number')\n return numValue\n }\n\n // Try to parse as float if it looks like a decimal\n if (/^\\d+\\.\\d+$/.test(value)) {\n const floatValue = parseFloat(value)\n this.logger.debug({\n key,\n originalValue: value,\n convertedValue: floatValue\n }, 'Auto-converted decimal string to number')\n return floatValue\n }\n\n // Return as string if no conversion applies\n return value\n }\n\n /**\n * Classifies error types based on error messages\n */\n private classifyErrorType(errorMessage: string): string {\n if (errorMessage.includes('timeout') || errorMessage.includes('ETIMEDOUT')) {\n return 'timeout'\n }\n if (errorMessage.includes('ENOTFOUND') || errorMessage.includes('getaddrinfo')) {\n return 'dns'\n }\n if (errorMessage.includes('ECONNREFUSED') || errorMessage.includes('ECONNRESET')) {\n return 'connection'\n }\n if (errorMessage.includes('network') || errorMessage.includes('fetch')) {\n return 'network'\n }\n return 'unknown'\n }\n\n /**\n * Evaluate a step condition using JSONPath\n */\n private evaluateStepCondition(condition: string, context: ExecutionContext): boolean {\n return this.evaluateCondition(condition, context)\n }\n\n /**\n * Execute a single workflow step\n */\n private async executeStep(\n step: WorkflowStep,\n stepIndex: number,\n context: ExecutionContext,\n req: PayloadRequest,\n workflowRunId?: number | string\n ): Promise<void> {\n const stepName = step.name || 'step-' + stepIndex\n\n this.logger.info({\n hasStep: 'step' in step,\n step: JSON.stringify(step),\n stepName\n }, 'Executing step')\n\n // Check step condition if present\n if (step.condition) {\n this.logger.debug({\n condition: step.condition,\n stepName,\n availableSteps: Object.keys(context.steps),\n completedSteps: Object.entries(context.steps)\n .filter(([_, s]) => s.state === 'succeeded')\n .map(([name]) => name),\n triggerType: context.trigger?.type\n }, 'Evaluating step condition')\n\n const conditionMet = this.evaluateStepCondition(step.condition, context)\n\n if (!conditionMet) {\n this.logger.info({\n condition: step.condition,\n stepName,\n contextSnapshot: JSON.stringify({\n stepOutputs: Object.entries(context.steps).reduce((acc, [name, step]) => {\n acc[name] = { state: step.state, hasOutput: !!step.output }\n return acc\n }, {} as Record<string, any>),\n triggerData: context.trigger?.data ? 'present' : 'absent'\n })\n }, 'Step condition not met, skipping')\n\n // Mark step as completed but skipped\n context.steps[stepName] = {\n error: undefined,\n input: undefined,\n output: { reason: 'Condition not met', skipped: true },\n state: 'succeeded'\n }\n\n // Update workflow run context if needed\n if (workflowRunId) {\n await this.updateWorkflowRunContext(workflowRunId, context, req)\n }\n\n return\n }\n\n this.logger.info({\n condition: step.condition,\n stepName,\n contextSnapshot: JSON.stringify({\n stepOutputs: Object.entries(context.steps).reduce((acc, [name, step]) => {\n acc[name] = { state: step.state, hasOutput: !!step.output }\n return acc\n }, {} as Record<string, any>),\n triggerData: context.trigger?.data ? 'present' : 'absent'\n })\n }, 'Step condition met, proceeding with execution')\n }\n\n // Initialize step context\n context.steps[stepName] = {\n error: undefined,\n input: undefined,\n output: undefined,\n state: 'running',\n _startTime: Date.now() // Track execution start time for independent duration tracking\n }\n\n // Move taskSlug declaration outside try block so it's accessible in catch\n const taskSlug = step.type as string\n\n try {\n // Get input configuration from the step\n const inputConfig = (step.input as Record<string, unknown>) || {}\n\n // Resolve input data using Handlebars templates\n const resolvedInput = this.resolveStepInput(inputConfig, context, taskSlug)\n context.steps[stepName].input = resolvedInput\n\n if (!taskSlug) {\n throw new Error(`Step ${stepName} is missing a task type`)\n }\n\n this.logger.info({\n hasInput: !!resolvedInput,\n hasReq: !!req,\n stepName,\n taskSlug\n }, 'Queueing task')\n\n const job = await this.payload.jobs.queue({\n input: resolvedInput,\n req,\n task: taskSlug\n })\n\n // Run the specific job immediately and wait for completion\n this.logger.info({ jobId: job.id }, 'Running job immediately using runByID')\n const runResults = await this.payload.jobs.runByID({\n id: job.id,\n req\n })\n\n this.logger.info({\n jobId: job.id,\n runResult: runResults,\n hasResult: !!runResults\n }, 'Job run completed')\n\n // Give a small delay to ensure job is fully processed\n await new Promise(resolve => setTimeout(resolve, 100))\n\n // Get the job result\n const completedJob = await this.payload.findByID({\n id: job.id,\n collection: 'payload-jobs',\n req\n })\n\n this.logger.info({\n jobId: job.id,\n totalTried: completedJob.totalTried,\n hasError: completedJob.hasError,\n taskStatus: completedJob.taskStatus ? Object.keys(completedJob.taskStatus) : 'null'\n }, 'Retrieved job results')\n\n const taskStatus = completedJob.taskStatus?.[completedJob.taskSlug]?.[completedJob.totalTried]\n const isComplete = taskStatus?.complete === true\n const hasError = completedJob.hasError || !isComplete\n\n // Extract error information from job if available\n let errorMessage: string | undefined\n if (hasError) {\n // Try to get error from the latest log entry\n if (completedJob.log && completedJob.log.length > 0) {\n const latestLog = completedJob.log[completedJob.log.length - 1]\n errorMessage = latestLog.error?.message || latestLog.error\n }\n\n // Fallback to top-level error\n if (!errorMessage && completedJob.error) {\n errorMessage = completedJob.error.message || completedJob.error\n }\n\n // Try to get error from task output if available\n if (!errorMessage && taskStatus?.output?.error) {\n errorMessage = taskStatus.output.error\n }\n\n // Check if task handler returned with state='failed'\n if (!errorMessage && taskStatus?.state === 'failed') {\n errorMessage = 'Task handler returned a failed state'\n // Try to get more specific error from output\n if (taskStatus.output?.error) {\n errorMessage = taskStatus.output.error\n }\n }\n\n // Check for network errors in the job data\n if (!errorMessage && completedJob.result) {\n const result = completedJob.result\n if (result.error) {\n errorMessage = result.error\n }\n }\n\n // Final fallback to generic message with more detail\n if (!errorMessage) {\n const jobDetails = {\n taskSlug,\n hasError: completedJob.hasError,\n taskStatus: taskStatus?.complete,\n totalTried: completedJob.totalTried\n }\n errorMessage = `Task ${taskSlug} failed without detailed error information. Job details: ${JSON.stringify(jobDetails)}`\n }\n }\n\n const result: {\n error: string | undefined\n output: unknown\n state: 'failed' | 'succeeded'\n } = {\n error: errorMessage,\n output: taskStatus?.output || {},\n state: isComplete ? 'succeeded' : 'failed'\n }\n\n // Store the output and error\n context.steps[stepName].output = result.output\n context.steps[stepName].state = result.state\n if (result.error) {\n context.steps[stepName].error = result.error\n }\n\n // Independent execution tracking (not dependent on PayloadCMS task status)\n context.steps[stepName].executionInfo = {\n completed: true, // Step execution completed (regardless of success/failure)\n success: result.state === 'succeeded',\n executedAt: new Date().toISOString(),\n duration: Date.now() - (context.steps[stepName]._startTime || Date.now())\n }\n\n // For failed steps, try to extract detailed error information from the job logs\n // This approach is more reliable than external storage and persists with the workflow\n if (result.state === 'failed') {\n const errorDetails = this.extractErrorDetailsFromJob(completedJob, context.steps[stepName], stepName)\n if (errorDetails) {\n context.steps[stepName].errorDetails = errorDetails\n\n this.logger.info({\n stepName,\n errorType: errorDetails.errorType,\n duration: errorDetails.duration,\n attempts: errorDetails.attempts\n }, 'Extracted detailed error information for failed step')\n }\n }\n\n this.logger.debug({context}, 'Step execution context')\n\n if (result.state !== 'succeeded') {\n throw new Error(result.error || `Step ${stepName} failed`)\n }\n\n this.logger.info({\n output: result.output,\n stepName\n }, 'Step completed')\n\n // Update workflow run with current step results if workflowRunId is provided\n if (workflowRunId) {\n await this.updateWorkflowRunContext(workflowRunId, context, req)\n }\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n context.steps[stepName].state = 'failed'\n context.steps[stepName].error = errorMessage\n\n // Independent execution tracking for failed steps\n context.steps[stepName].executionInfo = {\n completed: true, // Execution attempted and completed (even if it failed)\n success: false,\n executedAt: new Date().toISOString(),\n duration: Date.now() - (context.steps[stepName]._startTime || Date.now()),\n failureReason: errorMessage\n }\n\n this.logger.error({\n error: errorMessage,\n input: context.steps[stepName].input,\n stepName,\n taskSlug\n }, 'Step execution failed')\n\n // Update workflow run with current step results if workflowRunId is provided\n if (workflowRunId) {\n try {\n await this.updateWorkflowRunContext(workflowRunId, context, req)\n } catch (updateError) {\n this.logger.error({\n error: updateError instanceof Error ? updateError.message : 'Unknown error',\n stepName\n }, 'Failed to update workflow run context after step failure')\n }\n }\n\n throw error\n }\n }\n\n /**\n * Extracts detailed error information from job logs and input\n */\n private extractErrorDetailsFromJob(job: any, stepContext: any, stepName: string) {\n try {\n // Get error information from multiple sources\n const input = stepContext.input || {}\n const logs = job.log || []\n const latestLog = logs[logs.length - 1]\n\n // Extract error message from job error or log\n const errorMessage = job.error?.message || latestLog?.error?.message || 'Unknown error'\n\n // For timeout scenarios, check if it's a timeout based on duration and timeout setting\n let errorType = this.classifyErrorType(errorMessage)\n\n // Special handling for HTTP timeouts - if task failed and duration exceeds timeout, it's likely a timeout\n if (errorType === 'unknown' && input.timeout && stepContext.executionInfo?.duration) {\n const timeoutMs = parseInt(input.timeout) || 30000\n const actualDuration = stepContext.executionInfo.duration\n\n // If execution duration is close to or exceeds timeout, classify as timeout\n if (actualDuration >= (timeoutMs * 0.9)) { // 90% of timeout threshold\n errorType = 'timeout'\n this.logger.debug({\n timeoutMs,\n actualDuration,\n stepName\n }, 'Classified error as timeout based on duration analysis')\n }\n }\n\n // Calculate duration from execution info if available\n const duration = stepContext.executionInfo?.duration || 0\n\n // Extract attempt count from logs\n const attempts = job.totalTried || 1\n\n return {\n stepId: `${stepName}-${Date.now()}`,\n errorType,\n duration,\n attempts,\n finalError: errorMessage,\n context: {\n url: input.url,\n method: input.method,\n timeout: input.timeout,\n statusCode: latestLog?.output?.status,\n headers: input.headers\n },\n timestamp: new Date().toISOString()\n }\n } catch (error) {\n this.logger.warn({\n error: error instanceof Error ? error.message : 'Unknown error',\n stepName\n }, 'Failed to extract error details from job')\n return null\n }\n }\n\n\n /**\n * Resolve step execution order based on dependencies\n */\n private resolveExecutionOrder(steps: WorkflowStep[]): WorkflowStep[][] {\n const stepMap = new Map<string, WorkflowStep>()\n const dependencyGraph = new Map<string, string[]>()\n const indegree = new Map<string, number>()\n\n // Build the step map and dependency graph\n for (const step of steps) {\n const stepName = step.name || `step-${steps.indexOf(step)}`\n const dependencies = step.dependencies || []\n\n stepMap.set(stepName, { ...step, name: stepName, dependencies })\n dependencyGraph.set(stepName, dependencies)\n indegree.set(stepName, dependencies.length)\n }\n\n // Topological sort to determine execution batches\n const executionBatches: WorkflowStep[][] = []\n const processed = new Set<string>()\n\n while (processed.size < steps.length) {\n const currentBatch: WorkflowStep[] = []\n\n // Find all steps with no remaining dependencies\n for (const [stepName, inDegree] of indegree.entries()) {\n if (inDegree === 0 && !processed.has(stepName)) {\n const step = stepMap.get(stepName)\n if (step) {\n currentBatch.push(step)\n }\n }\n }\n\n if (currentBatch.length === 0) {\n throw new Error('Circular dependency detected in workflow steps')\n }\n\n executionBatches.push(currentBatch)\n\n // Update indegrees for next iteration\n for (const step of currentBatch) {\n processed.add(step.name)\n\n // Reduce indegree for steps that depend on completed steps\n for (const [otherStepName, dependencies] of dependencyGraph.entries()) {\n if (dependencies.includes(step.name) && !processed.has(otherStepName)) {\n indegree.set(otherStepName, (indegree.get(otherStepName) || 0) - 1)\n }\n }\n }\n }\n\n return executionBatches\n }\n\n\n /**\n * Resolve step input using Handlebars templates with automatic type conversion\n */\n private resolveStepInput(config: Record<string, unknown>, context: ExecutionContext, stepType?: string): Record<string, unknown> {\n const resolved: Record<string, unknown> = {}\n\n this.logger.debug({\n configKeys: Object.keys(config),\n contextSteps: Object.keys(context.steps),\n triggerType: context.trigger?.type,\n stepType\n }, 'Starting step input resolution with Handlebars')\n\n for (const [key, value] of Object.entries(config)) {\n if (typeof value === 'string') {\n // Check if the string contains Handlebars templates\n if (value.includes('{{') && value.includes('}}')) {\n this.logger.debug({\n key,\n template: value,\n availableSteps: Object.keys(context.steps),\n hasTriggerData: !!context.trigger?.data,\n hasTriggerDoc: !!context.trigger?.doc\n }, 'Processing Handlebars template')\n\n try {\n const template = Handlebars.compile(value)\n const result = template(context)\n\n this.logger.debug({\n key,\n template: value,\n result: JSON.stringify(result).substring(0, 200),\n resultType: typeof result\n }, 'Handlebars template resolved successfully')\n\n resolved[key] = this.convertValueType(result, key)\n } catch (error) {\n this.logger.warn({\n error: error instanceof Error ? error.message : 'Unknown error',\n key,\n template: value,\n contextSnapshot: JSON.stringify(context).substring(0, 500)\n }, 'Failed to resolve Handlebars template')\n resolved[key] = value // Keep original value if resolution fails\n }\n } else {\n // Regular string, apply type conversion\n resolved[key] = this.convertValueType(value, key)\n }\n } else if (typeof value === 'object' && value !== null) {\n // Recursively resolve nested objects\n this.logger.debug({\n key,\n nestedKeys: Object.keys(value as Record<string, unknown>)\n }, 'Recursively resolving nested object')\n\n resolved[key] = this.resolveStepInput(value as Record<string, unknown>, context, stepType)\n } else {\n // Keep literal values as-is\n resolved[key] = value\n }\n }\n\n this.logger.debug({\n resolvedKeys: Object.keys(resolved),\n originalKeys: Object.keys(config)\n }, 'Step input resolution completed')\n\n return resolved\n }\n\n /**\n * Safely serialize an object, handling circular references and non-serializable values\n */\n private safeSerialize(obj: unknown): unknown {\n const seen = new WeakSet()\n\n const serialize = (value: unknown): unknown => {\n if (value === null || typeof value !== 'object') {\n return value\n }\n\n if (seen.has(value)) {\n return '[Circular Reference]'\n }\n\n seen.add(value)\n\n if (Array.isArray(value)) {\n return value.map(serialize)\n }\n\n const result: Record<string, unknown> = {}\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n try {\n // Skip non-serializable properties that are likely internal database objects\n if (key === 'table' || key === 'schema' || key === '_' || key === '__') {\n continue\n }\n result[key] = serialize(val)\n } catch {\n // Skip properties that can't be accessed or serialized\n result[key] = '[Non-serializable]'\n }\n }\n\n return result\n }\n\n return serialize(obj)\n }\n\n /**\n * Update workflow run with current context\n */\n private async updateWorkflowRunContext(\n workflowRunId: number | string,\n context: ExecutionContext,\n req: PayloadRequest\n ): Promise<void> {\n const serializeContext = () => ({\n steps: this.safeSerialize(context.steps),\n trigger: {\n type: context.trigger.type,\n collection: context.trigger.collection,\n data: this.safeSerialize(context.trigger.data),\n doc: this.safeSerialize(context.trigger.doc),\n operation: context.trigger.operation,\n previousDoc: this.safeSerialize(context.trigger.previousDoc),\n triggeredAt: context.trigger.triggeredAt,\n user: context.trigger.req?.user\n }\n })\n\n await this.payload.update({\n id: workflowRunId,\n collection: 'workflow-runs',\n data: {\n context: serializeContext()\n },\n req\n })\n }\n\n /**\n * Evaluate a condition using Handlebars templates and comparison operators\n */\n public evaluateCondition(condition: string, context: ExecutionContext): boolean {\n this.logger.debug({\n condition,\n contextKeys: Object.keys(context),\n triggerType: context.trigger?.type,\n triggerData: context.trigger?.data,\n triggerDoc: context.trigger?.doc ? 'present' : 'absent'\n }, 'Starting condition evaluation')\n\n try {\n // Check if this is a comparison expression\n const comparisonMatch = condition.match(/^(.+?)\\s*(==|!=|>|<|>=|<=)\\s*(.+)$/)\n\n if (comparisonMatch) {\n const [, leftExpr, operator, rightExpr] = comparisonMatch\n\n // Evaluate left side (could be Handlebars template or JSONPath)\n const leftValue = this.resolveConditionValue(leftExpr.trim(), context)\n\n // Evaluate right side (could be Handlebars template, JSONPath, or literal)\n const rightValue = this.resolveConditionValue(rightExpr.trim(), context)\n\n this.logger.debug({\n condition,\n leftExpr: leftExpr.trim(),\n leftValue,\n operator,\n rightExpr: rightExpr.trim(),\n rightValue,\n leftType: typeof leftValue,\n rightType: typeof rightValue\n }, 'Evaluating comparison condition')\n\n // Perform comparison\n let result: boolean\n switch (operator) {\n case '!=':\n result = leftValue !== rightValue\n break\n case '<':\n result = Number(leftValue) < Number(rightValue)\n break\n case '<=':\n result = Number(leftValue) <= Number(rightValue)\n break\n case '==':\n result = leftValue === rightValue\n break\n case '>':\n result = Number(leftValue) > Number(rightValue)\n break\n case '>=':\n result = Number(leftValue) >= Number(rightValue)\n break\n default:\n throw new Error(`Unknown comparison operator: ${operator}`)\n }\n\n this.logger.debug({\n condition,\n result,\n leftValue,\n rightValue,\n operator\n }, 'Comparison condition evaluation completed')\n\n return result\n } else {\n // Treat as template or JSONPath boolean evaluation\n const result = this.resolveConditionValue(condition, context)\n\n this.logger.debug({\n condition,\n result,\n resultType: Array.isArray(result) ? 'array' : typeof result,\n resultLength: Array.isArray(result) ? result.length : undefined\n }, 'Boolean evaluation result')\n\n // Handle different result types\n let finalResult: boolean\n if (Array.isArray(result)) {\n finalResult = result.length > 0 && Boolean(result[0])\n } else {\n finalResult = Boolean(result)\n }\n\n this.logger.debug({\n condition,\n finalResult,\n originalResult: result\n }, 'Boolean condition evaluation completed')\n\n return finalResult\n }\n } catch (error) {\n this.logger.warn({\n condition,\n error: error instanceof Error ? error.message : 'Unknown error',\n errorStack: error instanceof Error ? error.stack : undefined\n }, 'Failed to evaluate condition')\n\n // If condition evaluation fails, assume false\n return false\n }\n }\n\n /**\n * Resolve a condition value using Handlebars templates or JSONPath\n */\n private resolveConditionValue(expr: string, context: ExecutionContext): any {\n // Handle string literals\n if ((expr.startsWith('\"') && expr.endsWith('\"')) || (expr.startsWith(\"'\") && expr.endsWith(\"'\"))) {\n return expr.slice(1, -1) // Remove quotes\n }\n\n // Handle boolean literals\n if (expr === 'true') {return true}\n if (expr === 'false') {return false}\n\n // Handle number literals\n if (/^-?\\d+(?:\\.\\d+)?$/.test(expr)) {\n return Number(expr)\n }\n\n // Handle Handlebars templates\n if (expr.includes('{{') && expr.includes('}}')) {\n try {\n const template = Handlebars.compile(expr)\n return template(context)\n } catch (error) {\n this.logger.warn({\n error: error instanceof Error ? error.message : 'Unknown error',\n expr\n }, 'Failed to resolve Handlebars condition')\n return false\n }\n }\n\n\n // Return as string if nothing else matches\n return expr\n }\n\n /**\n * Execute a workflow with the given context\n */\n async execute(workflow: PayloadWorkflow, context: ExecutionContext, req: PayloadRequest): Promise<void> {\n this.logger.info({\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Starting workflow execution')\n\n const serializeContext = () => ({\n steps: this.safeSerialize(context.steps),\n trigger: {\n type: context.trigger.type,\n collection: context.trigger.collection,\n data: this.safeSerialize(context.trigger.data),\n doc: this.safeSerialize(context.trigger.doc),\n operation: context.trigger.operation,\n previousDoc: this.safeSerialize(context.trigger.previousDoc),\n triggeredAt: context.trigger.triggeredAt,\n user: context.trigger.req?.user\n }\n })\n\n this.logger.info({\n workflowId: workflow.id,\n workflowName: workflow.name,\n contextSummary: {\n triggerType: context.trigger.type,\n triggerCollection: context.trigger.collection,\n triggerOperation: context.trigger.operation,\n hasDoc: !!context.trigger.doc,\n userEmail: context.trigger.req?.user?.email\n }\n }, 'About to create workflow run record')\n\n // Create a workflow run record\n let workflowRun;\n try {\n workflowRun = await this.payload.create({\n collection: 'workflow-runs',\n data: {\n context: serializeContext(),\n startedAt: new Date().toISOString(),\n status: 'running',\n triggeredBy: context.trigger.req?.user?.email || 'system',\n workflow: workflow.id,\n workflowVersion: 1 // Default version since generated type doesn't have _version field\n },\n req\n })\n\n this.logger.info({\n workflowRunId: workflowRun.id,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Workflow run record created successfully')\n } catch (error) {\n this.logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n errorStack: error instanceof Error ? error.stack : undefined,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Failed to create workflow run record')\n throw error\n }\n\n try {\n // Resolve execution order based on dependencies\n const executionBatches = this.resolveExecutionOrder(workflow.steps as WorkflowStep[] || [])\n\n this.logger.info({\n batchSizes: executionBatches.map(batch => batch.length),\n totalBatches: executionBatches.length\n }, 'Resolved step execution order')\n\n // Execute each batch in sequence, but steps within each batch in parallel\n for (let batchIndex = 0; batchIndex < executionBatches.length; batchIndex++) {\n const batch = executionBatches[batchIndex]\n\n this.logger.info({\n batchIndex,\n stepCount: batch.length,\n stepNames: batch.map(s => s.name)\n }, 'Executing batch')\n\n // Execute all steps in this batch in parallel\n const batchPromises = batch.map((step, stepIndex) =>\n this.executeStep(step, stepIndex, context, req, workflowRun.id)\n )\n\n // Wait for all steps in the current batch to complete\n await Promise.all(batchPromises)\n\n this.logger.info({\n batchIndex,\n stepCount: batch.length\n }, 'Batch completed')\n }\n\n // Update workflow run as completed\n await this.payload.update({\n id: workflowRun.id,\n collection: 'workflow-runs',\n data: {\n completedAt: new Date().toISOString(),\n context: serializeContext(),\n status: 'completed'\n },\n req\n })\n\n this.logger.info({\n runId: workflowRun.id,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Workflow execution completed')\n\n } catch (error) {\n // Update workflow run as failed\n await this.payload.update({\n id: workflowRun.id,\n collection: 'workflow-runs',\n data: {\n completedAt: new Date().toISOString(),\n context: serializeContext(),\n error: error instanceof Error ? error.message : 'Unknown error',\n status: 'failed'\n },\n req\n })\n\n this.logger.error({\n error: error instanceof Error ? error.message : 'Unknown error',\n runId: workflowRun.id,\n workflowId: workflow.id,\n workflowName: workflow.name\n }, 'Workflow execution failed')\n\n throw error\n }\n }\n}\n"],"names":["Handlebars","WorkflowExecutor","payload","logger","convertValueType","value","key","numericFields","booleanFields","some","field","toLowerCase","includes","numValue","Number","isNaN","debug","originalValue","convertedValue","test","parseInt","floatValue","parseFloat","classifyErrorType","errorMessage","evaluateStepCondition","condition","context","evaluateCondition","executeStep","step","stepIndex","req","workflowRunId","stepName","name","info","hasStep","JSON","stringify","availableSteps","Object","keys","steps","completedSteps","entries","filter","_","s","state","map","triggerType","trigger","type","conditionMet","contextSnapshot","stepOutputs","reduce","acc","hasOutput","output","triggerData","data","error","undefined","input","reason","skipped","updateWorkflowRunContext","_startTime","Date","now","taskSlug","inputConfig","resolvedInput","resolveStepInput","Error","hasInput","hasReq","job","jobs","queue","task","jobId","id","runResults","runByID","runResult","hasResult","Promise","resolve","setTimeout","completedJob","findByID","collection","totalTried","hasError","taskStatus","isComplete","complete","log","length","latestLog","message","result","jobDetails","executionInfo","completed","success","executedAt","toISOString","duration","errorDetails","extractErrorDetailsFromJob","errorType","attempts","failureReason","updateError","stepContext","logs","timeout","timeoutMs","actualDuration","stepId","finalError","url","method","statusCode","status","headers","timestamp","warn","resolveExecutionOrder","stepMap","Map","dependencyGraph","indegree","indexOf","dependencies","set","executionBatches","processed","Set","size","currentBatch","inDegree","has","get","push","add","otherStepName","config","stepType","resolved","configKeys","contextSteps","template","hasTriggerData","hasTriggerDoc","doc","compile","substring","resultType","nestedKeys","resolvedKeys","originalKeys","safeSerialize","obj","seen","WeakSet","serialize","Array","isArray","val","serializeContext","operation","previousDoc","triggeredAt","user","update","contextKeys","triggerDoc","comparisonMatch","match","leftExpr","operator","rightExpr","leftValue","resolveConditionValue","trim","rightValue","leftType","rightType","resultLength","finalResult","Boolean","originalResult","errorStack","stack","expr","startsWith","endsWith","slice","execute","workflow","workflowId","workflowName","contextSummary","triggerCollection","triggerOperation","hasDoc","userEmail","email","workflowRun","create","startedAt","triggeredBy","workflowVersion","batchSizes","batch","totalBatches","batchIndex","stepCount","stepNames","batchPromises","all","completedAt","runId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/workflow-executor.ts"],"sourcesContent":["import type { Payload, PayloadRequest } from 'payload'\n\nimport {\n evaluateCondition as evalCondition,\n resolveStepInput as resolveInput,\n type ExpressionContext\n} from './expression-engine.js'\n\n/**\n * Type for workflow data from the refactored collection\n */\nexport type PayloadWorkflow = {\n id: number | string\n name: string\n description?: string | null\n enabled?: boolean\n triggers?: Array<any> | null\n steps?: Array<{\n id?: string\n step: any\n stepName?: string | null\n inputOverrides?: Record<string, unknown> | null\n condition?: string | null\n dependencies?: Array<{ stepIndex: number }> | null\n position?: { x: number; y: number } | null\n }> | null\n errorHandling?: 'stop' | 'continue' | 'retry' | null\n maxRetries?: number | null\n retryDelay?: number | null\n timeout?: number | null\n [key: string]: unknown\n}\n\n/**\n * Type for a resolved workflow step (with base step data merged)\n */\nexport type ResolvedStep = {\n stepIndex: number\n stepId: string | number\n stepName: string\n stepType: string\n config: Record<string, unknown>\n condition?: string | null\n dependencies: number[]\n retryOnFailure?: boolean\n maxRetries?: number\n retryDelay?: number\n}\n\nexport interface ExecutionContext {\n steps: Record<string, any>\n trigger: Record<string, any>\n}\n\nexport interface StepResult {\n step?: string | number\n stepName: string\n stepIndex: number\n status: 'pending' | 'running' | 'succeeded' | 'failed' | 'skipped'\n startedAt?: string\n completedAt?: string\n duration?: number\n input?: Record<string, unknown>\n output?: Record<string, unknown>\n error?: string\n retryCount?: number\n}\n\n/**\n * Workflow context stored on jobs created by workflow execution.\n * Uses relationship IDs that link to the respective collections.\n */\nexport interface WorkflowJobMeta {\n automationWorkflowId: string | number\n automationWorkflowRunId: string | number\n automationTriggerId?: string | number\n}\n\nexport class WorkflowExecutor {\n constructor(\n private payload: Payload,\n private logger: Payload['logger']\n ) {}\n\n /**\n * Resolve workflow steps by loading base step configurations and merging with overrides\n */\n private async resolveWorkflowSteps(workflow: PayloadWorkflow): Promise<ResolvedStep[]> {\n const resolvedSteps: ResolvedStep[] = []\n\n if (!workflow.steps || workflow.steps.length === 0) {\n return resolvedSteps\n }\n\n for (let i = 0; i < workflow.steps.length; i++) {\n const workflowStep = workflow.steps[i]\n\n let baseStep: any\n if (typeof workflowStep.step === 'object' && workflowStep.step !== null) {\n baseStep = workflowStep.step\n } else {\n try {\n baseStep = await this.payload.findByID({\n collection: 'automation-steps',\n id: workflowStep.step,\n depth: 0\n })\n } catch (error) {\n this.logger.error({\n stepId: workflowStep.step,\n stepIndex: i,\n error: error instanceof Error ? error.message : 'Unknown error'\n }, 'Failed to load step configuration')\n throw new Error(`Failed to load step ${workflowStep.step}: ${error instanceof Error ? error.message : 'Unknown error'}`)\n }\n }\n\n const baseConfig = (baseStep.config as Record<string, unknown>) || {}\n const overrides = (workflowStep.inputOverrides as Record<string, unknown>) || {}\n const mergedConfig = { ...baseConfig, ...overrides }\n\n const dependencies = (workflowStep.dependencies || []).map(d => d.stepIndex)\n\n resolvedSteps.push({\n stepIndex: i,\n stepId: baseStep.id,\n stepName: workflowStep.stepName || baseStep.name || `step-${i}`,\n stepType: baseStep.type as string,\n config: mergedConfig,\n condition: workflowStep.condition,\n dependencies,\n retryOnFailure: baseStep.retryOnFailure,\n maxRetries: baseStep.maxRetries || workflow.maxRetries || 3,\n retryDelay: baseStep.retryDelay || workflow.retryDelay || 1000\n })\n }\n\n return resolvedSteps\n }\n\n /**\n * Resolve step execution order based on dependencies\n */\n private resolveExecutionOrder(steps: ResolvedStep[]): ResolvedStep[][] {\n const indegree = new Map<number, number>()\n const dependents = new Map<number, number[]>()\n\n for (const step of steps) {\n indegree.set(step.stepIndex, step.dependencies.length)\n dependents.set(step.stepIndex, [])\n }\n\n for (const step of steps) {\n for (const depIndex of step.dependencies) {\n const deps = dependents.get(depIndex) || []\n deps.push(step.stepIndex)\n dependents.set(depIndex, deps)\n }\n }\n\n const executionBatches: ResolvedStep[][] = []\n const processed = new Set<number>()\n\n while (processed.size < steps.length) {\n const currentBatch: ResolvedStep[] = []\n\n for (const step of steps) {\n if (!processed.has(step.stepIndex) && indegree.get(step.stepIndex) === 0) {\n currentBatch.push(step)\n }\n }\n\n if (currentBatch.length === 0) {\n throw new Error('Circular dependency detected in workflow steps')\n }\n\n executionBatches.push(currentBatch)\n\n for (const step of currentBatch) {\n processed.add(step.stepIndex)\n for (const depIndex of dependents.get(step.stepIndex) || []) {\n indegree.set(depIndex, (indegree.get(depIndex) || 1) - 1)\n }\n }\n }\n\n return executionBatches\n }\n\n /**\n * Execute a single workflow step\n */\n private async executeStep(\n step: ResolvedStep,\n context: ExecutionContext,\n req: PayloadRequest,\n stepResults: StepResult[],\n jobMeta: WorkflowJobMeta\n ): Promise<StepResult> {\n const result: StepResult = {\n step: step.stepId,\n stepName: step.stepName,\n stepIndex: step.stepIndex,\n status: 'running',\n startedAt: new Date().toISOString(),\n retryCount: 0\n }\n\n this.logger.info({\n stepName: step.stepName,\n stepType: step.stepType,\n stepIndex: step.stepIndex\n }, 'Executing step')\n\n // Check step condition if present\n if (step.condition) {\n const conditionMet = await this.evaluateCondition(step.condition, context)\n if (!conditionMet) {\n this.logger.info({\n stepName: step.stepName,\n condition: step.condition\n }, 'Step condition not met, skipping')\n\n result.status = 'skipped'\n result.completedAt = new Date().toISOString()\n result.output = { reason: 'Condition not met', skipped: true }\n\n context.steps[step.stepName] = {\n state: 'skipped',\n output: result.output\n }\n\n return result\n }\n }\n\n // Resolve input using JSONata expressions\n const resolvedInput = await this.resolveStepInput(step.config, context)\n result.input = resolvedInput\n\n context.steps[step.stepName] = {\n state: 'running',\n input: resolvedInput\n }\n\n try {\n const job = await this.payload.jobs.queue({\n input: resolvedInput,\n req,\n task: step.stepType,\n })\n\n // Update the job with automation context fields\n // This allows tracking which workflow run triggered this job\n await this.payload.update({\n collection: 'payload-jobs',\n id: job.id,\n data: {\n automationWorkflow: jobMeta.automationWorkflowId,\n automationWorkflowRun: jobMeta.automationWorkflowRunId,\n automationTrigger: jobMeta.automationTriggerId,\n automationStepName: step.stepName,\n },\n req,\n })\n\n // Run the job and capture the result directly from runByID\n // This is important because PayloadCMS may delete jobs on completion (deleteJobOnComplete: true by default)\n const runResult = await this.payload.jobs.runByID({\n id: job.id,\n req\n })\n\n // Check the job status from the run result\n // runByID returns { jobStatus: { [jobId]: { status: 'success' | 'error' | ... } }, ... }\n const jobStatus = (runResult as any)?.jobStatus?.[job.id]\n const jobSucceeded = jobStatus?.status === 'success'\n\n if (jobSucceeded) {\n // Job completed successfully - try to get output from the job if it still exists\n // Note: Job may have been deleted if deleteJobOnComplete is true\n let output: Record<string, unknown> = {}\n try {\n const completedJob = await this.payload.findByID({\n id: job.id,\n collection: 'payload-jobs',\n req\n })\n const taskStatus = completedJob.taskStatus?.[completedJob.taskSlug]?.[completedJob.totalTried]\n output = taskStatus?.output || {}\n } catch {\n // Job was deleted after completion - this is expected behavior with deleteJobOnComplete: true\n // The job succeeded, so we proceed without the output\n this.logger.debug({ stepName: step.stepName }, 'Job was deleted after successful completion (deleteJobOnComplete)')\n }\n\n result.status = 'succeeded'\n result.output = output\n result.completedAt = new Date().toISOString()\n result.duration = new Date(result.completedAt).getTime() - new Date(result.startedAt!).getTime()\n } else {\n // Job failed - try to get error details from the job\n let errorMessage = 'Task failed'\n try {\n const completedJob = await this.payload.findByID({\n id: job.id,\n collection: 'payload-jobs',\n req\n })\n const taskStatus = completedJob.taskStatus?.[completedJob.taskSlug]?.[completedJob.totalTried]\n if (completedJob.log && completedJob.log.length > 0) {\n const latestLog = completedJob.log[completedJob.log.length - 1]\n errorMessage = latestLog.error?.message || latestLog.error || errorMessage\n }\n if (taskStatus?.output?.errorMessage) {\n errorMessage = taskStatus.output.errorMessage\n }\n } catch {\n // Job may have been deleted - use the job status from run result\n errorMessage = `Task failed with status: ${jobStatus?.status || 'unknown'}`\n }\n throw new Error(errorMessage)\n }\n\n context.steps[step.stepName] = {\n state: 'succeeded',\n input: resolvedInput,\n output: result.output\n }\n\n this.logger.info({\n stepName: step.stepName,\n duration: result.duration\n }, 'Step completed successfully')\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n result.status = 'failed'\n result.error = errorMessage\n result.completedAt = new Date().toISOString()\n result.duration = new Date(result.completedAt).getTime() - new Date(result.startedAt!).getTime()\n\n context.steps[step.stepName] = {\n state: 'failed',\n input: resolvedInput,\n error: errorMessage\n }\n\n this.logger.error({\n stepName: step.stepName,\n error: errorMessage\n }, 'Step execution failed')\n\n throw error\n }\n\n return result\n }\n\n /**\n * Resolve step input using JSONata expressions\n */\n private async resolveStepInput(\n config: Record<string, unknown>,\n context: ExecutionContext\n ): Promise<Record<string, unknown>> {\n try {\n return await resolveInput(config, context as ExpressionContext, { timeout: 5000 })\n } catch (error) {\n this.logger.warn({\n error: error instanceof Error ? error.message : 'Unknown error'\n }, 'Failed to resolve step input, using raw config')\n return config\n }\n }\n\n /**\n * Evaluate a condition using JSONata\n */\n public async evaluateCondition(condition: string, context: ExecutionContext): Promise<boolean> {\n try {\n return await evalCondition(condition, context as ExpressionContext, { timeout: 5000 })\n } catch (error) {\n this.logger.warn({\n condition,\n error: error instanceof Error ? error.message : 'Unknown error'\n }, 'Failed to evaluate condition')\n return false\n }\n }\n\n /**\n * Safely serialize an object for storage\n */\n private safeSerialize(obj: unknown): unknown {\n const seen = new WeakSet()\n\n // Keys to completely exclude from serialization\n const excludeKeys = new Set([\n 'table',\n 'schema',\n '_',\n '__',\n 'payload', // Exclude payload instance (contains entire config)\n 'res', // Exclude response object\n 'transactionID',\n 'i18n',\n 'fallbackLocale',\n ])\n\n // For req object, only keep these useful debugging properties\n const reqAllowedKeys = new Set([\n 'payloadAPI', // 'local', 'REST', or 'GraphQL'\n 'locale',\n 'user', // authenticated user\n 'method', // HTTP method\n 'url', // request URL\n ])\n\n const serialize = (value: unknown, parentKey?: string): unknown => {\n if (value === null || typeof value !== 'object') {\n return value\n }\n if (seen.has(value)) {\n return '[Circular Reference]'\n }\n seen.add(value)\n\n if (Array.isArray(value)) {\n return value.map((v) => serialize(v))\n }\n\n const result: Record<string, unknown> = {}\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n try {\n if (excludeKeys.has(key)) {\n continue\n }\n // Special handling for req object - only include allowed keys\n if (parentKey === 'req' && !reqAllowedKeys.has(key)) {\n continue\n }\n result[key] = serialize(val, key)\n } catch {\n result[key] = '[Non-serializable]'\n }\n }\n return result\n }\n\n return serialize(obj)\n }\n\n /**\n * Execute a workflow with the given context\n */\n async execute(\n workflow: PayloadWorkflow,\n context: ExecutionContext,\n req: PayloadRequest,\n firedTrigger?: any\n ): Promise<void> {\n this.logger.info({\n workflowId: workflow.id,\n workflowName: workflow.name,\n triggerId: firedTrigger?.id,\n triggerName: firedTrigger?.name\n }, 'Starting workflow execution')\n\n const resolvedSteps = await this.resolveWorkflowSteps(workflow)\n const stepResults: StepResult[] = []\n\n for (const step of resolvedSteps) {\n stepResults.push({\n step: step.stepId,\n stepName: step.stepName,\n stepIndex: step.stepIndex,\n status: 'pending'\n })\n }\n\n const workflowRun = await this.payload.create({\n collection: 'workflow-runs',\n data: {\n workflow: workflow.id,\n workflowVersion: 1,\n firedTrigger: firedTrigger?.id,\n triggerData: this.safeSerialize(context.trigger),\n status: 'running',\n startedAt: new Date().toISOString(),\n triggeredBy: context.trigger.req?.user?.email || 'system',\n stepResults,\n context: this.safeSerialize(context),\n inputs: this.safeSerialize(context.trigger),\n logs: [{\n timestamp: new Date().toISOString(),\n level: 'info',\n message: 'Workflow execution started'\n }]\n },\n req\n })\n\n this.logger.info({\n workflowRunId: workflowRun.id,\n workflowId: workflow.id\n }, 'Workflow run record created')\n\n // Create job metadata for tracking workflow context in payload-jobs\n const jobMeta: WorkflowJobMeta = {\n automationWorkflowId: workflow.id,\n automationWorkflowRunId: workflowRun.id,\n automationTriggerId: firedTrigger?.id,\n }\n\n try {\n const executionBatches = this.resolveExecutionOrder(resolvedSteps)\n\n this.logger.info({\n batchCount: executionBatches.length,\n batchSizes: executionBatches.map(b => b.length)\n }, 'Resolved step execution order')\n\n for (let batchIndex = 0; batchIndex < executionBatches.length; batchIndex++) {\n const batch = executionBatches[batchIndex]\n\n this.logger.info({\n batchIndex,\n stepCount: batch.length,\n stepNames: batch.map(s => s.stepName)\n }, 'Executing batch')\n\n const batchPromises = batch.map(async (step) => {\n try {\n const result = await this.executeStep(step, context, req, stepResults, jobMeta)\n const idx = stepResults.findIndex(r => r.stepIndex === step.stepIndex)\n if (idx !== -1) {\n stepResults[idx] = result\n }\n return result\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n const idx = stepResults.findIndex(r => r.stepIndex === step.stepIndex)\n if (idx !== -1) {\n stepResults[idx] = {\n ...stepResults[idx],\n status: 'failed',\n error: errorMessage,\n completedAt: new Date().toISOString()\n }\n }\n\n if (workflow.errorHandling === 'stop') {\n throw error\n }\n this.logger.warn({\n stepName: step.stepName,\n error: errorMessage\n }, 'Step failed but continuing due to error handling setting')\n }\n })\n\n await Promise.all(batchPromises)\n\n await this.payload.update({\n id: workflowRun.id,\n collection: 'workflow-runs',\n data: {\n stepResults,\n context: this.safeSerialize(context)\n },\n req\n })\n }\n\n const outputs: Record<string, unknown> = {}\n for (const result of stepResults) {\n if (result.status === 'succeeded' && result.output) {\n outputs[result.stepName] = result.output\n }\n }\n\n await this.payload.update({\n id: workflowRun.id,\n collection: 'workflow-runs',\n data: {\n status: 'completed',\n completedAt: new Date().toISOString(),\n stepResults,\n context: this.safeSerialize(context),\n outputs,\n logs: [\n ...(workflowRun.logs || []),\n {\n timestamp: new Date().toISOString(),\n level: 'info',\n message: 'Workflow execution completed successfully'\n }\n ]\n },\n req\n })\n\n this.logger.info({\n workflowRunId: workflowRun.id,\n workflowId: workflow.id\n }, 'Workflow execution completed')\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n\n await this.payload.update({\n id: workflowRun.id,\n collection: 'workflow-runs',\n data: {\n status: 'failed',\n completedAt: new Date().toISOString(),\n stepResults,\n context: this.safeSerialize(context),\n error: errorMessage,\n logs: [\n ...(workflowRun.logs || []),\n {\n timestamp: new Date().toISOString(),\n level: 'error',\n message: `Workflow execution failed: ${errorMessage}`\n }\n ]\n },\n req\n })\n\n this.logger.error({\n workflowRunId: workflowRun.id,\n workflowId: workflow.id,\n error: errorMessage\n }, 'Workflow execution failed')\n\n throw error\n }\n }\n}\n"],"names":["evaluateCondition","evalCondition","resolveStepInput","resolveInput","WorkflowExecutor","payload","logger","resolveWorkflowSteps","workflow","resolvedSteps","steps","length","i","workflowStep","baseStep","step","findByID","collection","id","depth","error","stepId","stepIndex","Error","message","baseConfig","config","overrides","inputOverrides","mergedConfig","dependencies","map","d","push","stepName","name","stepType","type","condition","retryOnFailure","maxRetries","retryDelay","resolveExecutionOrder","indegree","Map","dependents","set","depIndex","deps","get","executionBatches","processed","Set","size","currentBatch","has","add","executeStep","context","req","stepResults","jobMeta","result","status","startedAt","Date","toISOString","retryCount","info","conditionMet","completedAt","output","reason","skipped","state","resolvedInput","input","job","jobs","queue","task","update","data","automationWorkflow","automationWorkflowId","automationWorkflowRun","automationWorkflowRunId","automationTrigger","automationTriggerId","automationStepName","runResult","runByID","jobStatus","jobSucceeded","completedJob","taskStatus","taskSlug","totalTried","debug","duration","getTime","errorMessage","log","latestLog","timeout","warn","safeSerialize","obj","seen","WeakSet","excludeKeys","reqAllowedKeys","serialize","value","parentKey","Array","isArray","v","key","val","Object","entries","execute","firedTrigger","workflowId","workflowName","triggerId","triggerName","workflowRun","create","workflowVersion","triggerData","trigger","triggeredBy","user","email","inputs","logs","timestamp","level","workflowRunId","batchCount","batchSizes","b","batchIndex","batch","stepCount","stepNames","s","batchPromises","idx","findIndex","r","errorHandling","Promise","all","outputs"],"mappings":"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"}
|
package/dist/exports/client.js
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
// These are separated to avoid CSS import errors during Node.js type generation
|
|
3
3
|
export { StatusCell } from '../components/StatusCell.js';
|
|
4
4
|
export { ErrorDisplay } from '../components/ErrorDisplay.js';
|
|
5
|
-
export { ReadOnlyBanner } from '../components/ReadOnlyBanner.js';
|
|
6
|
-
// export { default as WorkflowDashboard } from '../components/WorkflowDashboard/index.js'
|
|
7
|
-
// export { default as WorkflowBuilder } from '../components/WorkflowBuilder/index.js'
|
|
5
|
+
export { ReadOnlyBanner } from '../components/ReadOnlyBanner.js';
|
|
8
6
|
|
|
9
7
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["// Client-side components that may have CSS imports or PayloadCMS UI dependencies\n// These are separated to avoid CSS import errors during Node.js type generation\n\nexport { StatusCell } from '../components/StatusCell.js'\nexport { ErrorDisplay } from '../components/ErrorDisplay.js'\nexport { ReadOnlyBanner } from '../components/ReadOnlyBanner.js'\n
|
|
1
|
+
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["// Client-side components that may have CSS imports or PayloadCMS UI dependencies\n// These are separated to avoid CSS import errors during Node.js type generation\n\nexport { StatusCell } from '../components/StatusCell.js'\nexport { ErrorDisplay } from '../components/ErrorDisplay.js'\nexport { ReadOnlyBanner } from '../components/ReadOnlyBanner.js'\n"],"names":["StatusCell","ErrorDisplay","ReadOnlyBanner"],"mappings":"AAAA,iFAAiF;AACjF,gFAAgF;AAEhF,SAASA,UAAU,QAAQ,8BAA6B;AACxD,SAASC,YAAY,QAAQ,gCAA+B;AAC5D,SAASC,cAAc,QAAQ,kCAAiC"}
|
package/dist/exports/views.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
// View exports for workflow plugin
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// export { default as WorkflowBuilder } from '../components/WorkflowBuilder/index.js'
|
|
5
|
-
// export { default as WorkflowStepsField } from '../components/WorkflowStepsField/index.js'
|
|
2
|
+
// Admin panel views and full-featured components
|
|
3
|
+
// Note: WorkflowTestRunner and related components are planned for future implementation
|
|
6
4
|
|
|
7
5
|
//# sourceMappingURL=views.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/views.ts"],"sourcesContent":["// View exports for workflow plugin\n//
|
|
1
|
+
{"version":3,"sources":["../../src/exports/views.ts"],"sourcesContent":["// View exports for workflow plugin\n// Admin panel views and full-featured components\n\n// Note: WorkflowTestRunner and related components are planned for future implementation\n"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,iDAAiD;AAEjD,wFAAwF"}
|
package/dist/fields/parameter.js
CHANGED
|
@@ -17,10 +17,15 @@ export const parameter = (slug, field)=>({
|
|
|
17
17
|
],
|
|
18
18
|
beforeChange: [
|
|
19
19
|
({ siblingData, value })=>{
|
|
20
|
-
if
|
|
21
|
-
|
|
20
|
+
// Only set the parameter if the virtual field has a defined value.
|
|
21
|
+
// This preserves directly-passed parameters (e.g., from seeding) when
|
|
22
|
+
// the virtual field is not used.
|
|
23
|
+
if (value !== undefined) {
|
|
24
|
+
if (!siblingData.parameters) {
|
|
25
|
+
siblingData.parameters = {};
|
|
26
|
+
}
|
|
27
|
+
siblingData.parameters[field.name] = value;
|
|
22
28
|
}
|
|
23
|
-
siblingData.parameters[field.name] = value;
|
|
24
29
|
return undefined // Virtual field, don't store directly
|
|
25
30
|
;
|
|
26
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/parameter.ts"],"sourcesContent":["import type {Field} from \"payload\"\n\n\nexport const parameter = (slug: string, field: {name: string} & Field): Field => ({\n ...field,\n name: 'parameter' + field.name.replace(/^\\w/, c => c.toUpperCase()) + Math.random().toString().replace(/\\D/g, ''),\n admin: {\n ...(field.admin as unknown || {}),\n condition: (_, siblingData, __) => {\n const previous = field.admin?.condition?.call(null, _, siblingData, __)\n return (previous === undefined || previous) && (siblingData?.type === slug)\n },\n },\n hooks: {\n afterRead: [\n ({ siblingData }) => {\n const parameters = siblingData?.parameters || {}\n return parameters[field.name]\n }\n ],\n beforeChange: [\n ({ siblingData, value }) => {\n if (!siblingData.parameters) {\n
|
|
1
|
+
{"version":3,"sources":["../../src/fields/parameter.ts"],"sourcesContent":["import type {Field} from \"payload\"\n\n\nexport const parameter = (slug: string, field: {name: string} & Field): Field => ({\n ...field,\n name: 'parameter' + field.name.replace(/^\\w/, c => c.toUpperCase()) + Math.random().toString().replace(/\\D/g, ''),\n admin: {\n ...(field.admin as unknown || {}),\n condition: (_, siblingData, __) => {\n const previous = field.admin?.condition?.call(null, _, siblingData, __)\n return (previous === undefined || previous) && (siblingData?.type === slug)\n },\n },\n hooks: {\n afterRead: [\n ({ siblingData }) => {\n const parameters = siblingData?.parameters || {}\n return parameters[field.name]\n }\n ],\n beforeChange: [\n ({ siblingData, value }) => {\n // Only set the parameter if the virtual field has a defined value.\n // This preserves directly-passed parameters (e.g., from seeding) when\n // the virtual field is not used.\n if (value !== undefined) {\n if (!siblingData.parameters) {\n siblingData.parameters = {}\n }\n siblingData.parameters[field.name] = value\n }\n return undefined // Virtual field, don't store directly\n }\n ]\n },\n virtual: true,\n} as Field)\n"],"names":["parameter","slug","field","name","replace","c","toUpperCase","Math","random","toString","admin","condition","_","siblingData","__","previous","call","undefined","type","hooks","afterRead","parameters","beforeChange","value","virtual"],"mappings":"AAGA,OAAO,MAAMA,YAAY,CAACC,MAAcC,QAA0C,CAAA;QAChF,GAAGA,KAAK;QACRC,MAAM,cAAcD,MAAMC,IAAI,CAACC,OAAO,CAAC,OAAOC,CAAAA,IAAKA,EAAEC,WAAW,MAAMC,KAAKC,MAAM,GAAGC,QAAQ,GAAGL,OAAO,CAAC,OAAO;QAC9GM,OAAO;YACL,GAAIR,MAAMQ,KAAK,IAAe,CAAC,CAAC;YAChCC,WAAW,CAACC,GAAGC,aAAaC;gBAC1B,MAAMC,WAAWb,MAAMQ,KAAK,EAAEC,WAAWK,KAAK,MAAMJ,GAAGC,aAAaC;gBACpE,OAAO,AAACC,CAAAA,aAAaE,aAAaF,QAAO,KAAOF,aAAaK,SAASjB;YACxE;QACF;QACAkB,OAAO;YACLC,WAAW;gBACT,CAAC,EAAEP,WAAW,EAAE;oBACd,MAAMQ,aAAaR,aAAaQ,cAAc,CAAC;oBAC/C,OAAOA,UAAU,CAACnB,MAAMC,IAAI,CAAC;gBAC/B;aACD;YACDmB,cAAc;gBACZ,CAAC,EAAET,WAAW,EAAEU,KAAK,EAAE;oBACrB,mEAAmE;oBACnE,sEAAsE;oBACtE,iCAAiC;oBACjC,IAAIA,UAAUN,WAAW;wBACvB,IAAI,CAACJ,YAAYQ,UAAU,EAAE;4BAC3BR,YAAYQ,UAAU,GAAG,CAAC;wBAC5B;wBACAR,YAAYQ,UAAU,CAACnB,MAAMC,IAAI,CAAC,GAAGoB;oBACvC;oBACA,OAAON,UAAU,sCAAsC;;gBACzD;aACD;QACH;QACAO,SAAS;IACX,CAAA,EAAW"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export type { PayloadWorkflow as Workflow,
|
|
2
|
-
export type { CustomTriggerOptions, ExecutionContext, TriggerResult,
|
|
1
|
+
export type { PayloadWorkflow as Workflow, ResolvedStep, StepResult, WorkflowJobMeta } from './core/workflow-executor.js';
|
|
2
|
+
export type { CustomTriggerOptions, ExecutionContext, TriggerResult, SeedWorkflow, WorkflowLoggingConfig } from './types/index.js';
|
|
3
|
+
export type { WorkflowsPluginConfig } from './plugin/config-types.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Main export contains only types and client-safe utilities
|
|
2
2
|
// Server-side functions are exported via '@xtr-dev/payload-automation/server'
|
|
3
|
-
//
|
|
3
|
+
// Re-export the full plugin config type from server exports
|
|
4
4
|
export { }; // Server-side functions are NOT re-exported here to avoid bundling issues
|
|
5
5
|
// Import server-side functions from the /server export instead
|
|
6
6
|
// Server functions and plugin should be imported from '/server':
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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\nexport type {\n PayloadWorkflow as Workflow,\n
|
|
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\nexport type {\n PayloadWorkflow as Workflow,\n ResolvedStep,\n StepResult,\n WorkflowJobMeta\n} from './core/workflow-executor.js'\n\n// Pure types only - completely safe for client bundling\nexport type {\n CustomTriggerOptions,\n ExecutionContext,\n TriggerResult,\n SeedWorkflow,\n WorkflowLoggingConfig\n} from './types/index.js'\n\n// Re-export the full plugin config type from server exports\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;AAkB9E,4DAA4D;AAC5D,WAAqE,CAErE,0EAA0E;CAC1E,+DAA+D;CAE/D,iEAAiE;CACjE,uEAAuE;CACvE,mDAAmD;CACnD,6EAA6E"}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import type { CollectionConfig, GlobalConfig, TaskConfig } from "payload";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Trigger definition for custom trigger configurations.
|
|
4
|
+
*/
|
|
5
|
+
export interface Trigger {
|
|
6
|
+
slug: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
parameters?: Array<{
|
|
9
|
+
name: string;
|
|
10
|
+
type: string;
|
|
11
|
+
required?: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
3
14
|
export type TriggerConfig = (config: WorkflowsPluginConfig) => Trigger;
|
|
4
15
|
export type SeedWorkflow = {
|
|
5
16
|
slug: string;
|
|
@@ -18,19 +29,46 @@ export type SeedWorkflow = {
|
|
|
18
29
|
condition?: string;
|
|
19
30
|
}>;
|
|
20
31
|
};
|
|
21
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Plugin configuration for the workflows automation plugin.
|
|
34
|
+
*/
|
|
35
|
+
export type WorkflowsPluginConfig<TCollection extends string = string, TGlobal extends string = string> = {
|
|
36
|
+
/**
|
|
37
|
+
* Whether the plugin is enabled. Defaults to true.
|
|
38
|
+
*/
|
|
39
|
+
enabled?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Collection triggers configuration.
|
|
42
|
+
* Keys are collection slugs, values configure which hooks to listen to.
|
|
43
|
+
* Set to `true` to enable all default hooks (afterChange, afterDelete, afterRead).
|
|
44
|
+
*/
|
|
22
45
|
collectionTriggers?: {
|
|
23
|
-
[key in
|
|
46
|
+
[key in TCollection]?: {
|
|
24
47
|
[key in keyof CollectionConfig['hooks']]?: true;
|
|
25
48
|
} | true;
|
|
26
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Global triggers configuration.
|
|
52
|
+
* Keys are global slugs, values configure which hooks to listen to.
|
|
53
|
+
* Set to `true` to enable all default hooks (afterChange, afterRead).
|
|
54
|
+
*/
|
|
27
55
|
globalTriggers?: {
|
|
28
56
|
[key in TGlobal]?: {
|
|
29
57
|
[key in keyof GlobalConfig['hooks']]?: true;
|
|
30
58
|
} | true;
|
|
31
59
|
};
|
|
32
|
-
|
|
33
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Step task configurations.
|
|
62
|
+
* These are the step types available for use in workflows.
|
|
63
|
+
*/
|
|
34
64
|
steps: TaskConfig<string>[];
|
|
65
|
+
/**
|
|
66
|
+
* Seed workflows to create on plugin initialization.
|
|
67
|
+
* These workflows are read-only and serve as templates.
|
|
68
|
+
*/
|
|
69
|
+
seedWorkflows?: SeedWorkflow[];
|
|
70
|
+
/**
|
|
71
|
+
* Custom trigger configurations.
|
|
72
|
+
*/
|
|
35
73
|
triggers?: TriggerConfig[];
|
|
36
74
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/plugin/config-types.ts"],"sourcesContent":["import type {CollectionConfig, GlobalConfig, TaskConfig} from \"payload\"\n\
|
|
1
|
+
{"version":3,"sources":["../../src/plugin/config-types.ts"],"sourcesContent":["import type {CollectionConfig, GlobalConfig, TaskConfig} from \"payload\"\n\n/**\n * Trigger definition for custom trigger configurations.\n */\nexport interface Trigger {\n slug: string\n label?: string\n parameters?: Array<{\n name: string\n type: string\n required?: boolean\n }>\n}\n\nexport type TriggerConfig = (config: WorkflowsPluginConfig) => Trigger\n\nexport type SeedWorkflow = {\n slug: string\n name: string\n description?: string\n triggers: Array<{\n type: string\n parameters?: Record<string, any>\n condition?: string\n }>\n steps: Array<{\n name: string\n type: string\n input?: Record<string, any>\n dependencies?: string[]\n condition?: string\n }>\n}\n\n/**\n * Plugin configuration for the workflows automation plugin.\n */\nexport type WorkflowsPluginConfig<\n TCollection extends string = string,\n TGlobal extends string = string\n> = {\n /**\n * Whether the plugin is enabled. Defaults to true.\n */\n enabled?: boolean\n\n /**\n * Collection triggers configuration.\n * Keys are collection slugs, values configure which hooks to listen to.\n * Set to `true` to enable all default hooks (afterChange, afterDelete, afterRead).\n */\n collectionTriggers?: {\n [key in TCollection]?: {\n [key in keyof CollectionConfig['hooks']]?: true\n } | true\n }\n\n /**\n * Global triggers configuration.\n * Keys are global slugs, values configure which hooks to listen to.\n * Set to `true` to enable all default hooks (afterChange, afterRead).\n */\n globalTriggers?: {\n [key in TGlobal]?: {\n [key in keyof GlobalConfig['hooks']]?: true\n } | true\n }\n\n /**\n * Step task configurations.\n * These are the step types available for use in workflows.\n */\n steps: TaskConfig<string>[]\n\n /**\n * Seed workflows to create on plugin initialization.\n * These workflows are read-only and serve as templates.\n */\n seedWorkflows?: SeedWorkflow[]\n\n /**\n * Custom trigger configurations.\n */\n triggers?: TriggerConfig[]\n}"],"names":[],"mappings":"AAmCA;;CAEC,GACD,WA+CC"}
|
package/dist/plugin/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Config } from 'payload';
|
|
2
|
-
import type { WorkflowsPluginConfig } from
|
|
2
|
+
import type { WorkflowsPluginConfig } from './config-types.js';
|
|
3
3
|
export { getLogger } from './logger.js';
|
|
4
4
|
export declare const workflowsPlugin: <TSlug extends string>(pluginOptions: WorkflowsPluginConfig<TSlug>) => (config: Config) => Config;
|