@xtr-dev/payload-automation 0.0.36 → 0.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/collections/Workflow.js +30 -305
- package/dist/collections/Workflow.js.map +1 -1
- package/dist/components/ErrorDisplay.js +3 -3
- package/dist/components/ErrorDisplay.js.map +1 -1
- package/dist/core/workflow-executor.d.ts +33 -85
- package/dist/core/workflow-executor.js +136 -229
- package/dist/core/workflow-executor.js.map +1 -1
- package/dist/exports/client.d.ts +0 -2
- package/dist/exports/client.js +1 -3
- package/dist/exports/client.js.map +1 -1
- package/dist/fields/parameter.d.ts +4 -0
- package/dist/fields/parameter.js +32 -0
- package/dist/fields/parameter.js.map +1 -0
- package/dist/plugin/collection-hook.d.ts +1 -0
- package/dist/plugin/collection-hook.js +58 -0
- package/dist/plugin/collection-hook.js.map +1 -0
- package/dist/plugin/config-types.d.ts +14 -17
- package/dist/plugin/config-types.js.map +1 -1
- package/dist/plugin/global-hook.d.ts +1 -0
- package/dist/plugin/global-hook.js +83 -0
- package/dist/plugin/global-hook.js.map +1 -0
- package/dist/plugin/index.js +83 -197
- package/dist/plugin/index.js.map +1 -1
- package/dist/test/workflow-executor.test.js +2 -2
- package/dist/test/workflow-executor.test.js.map +1 -1
- package/dist/triggers/collection-trigger.d.ts +2 -0
- package/dist/triggers/collection-trigger.js +36 -0
- package/dist/triggers/collection-trigger.js.map +1 -0
- package/dist/triggers/global-trigger.d.ts +2 -0
- package/dist/triggers/global-trigger.js +29 -0
- package/dist/triggers/global-trigger.js.map +1 -0
- package/dist/triggers/index.d.ts +2 -0
- package/dist/triggers/index.js +4 -0
- package/dist/triggers/index.js.map +1 -0
- package/dist/triggers/types.d.ts +5 -0
- package/dist/triggers/types.js +3 -0
- package/dist/triggers/types.js.map +1 -0
- package/package.json +1 -1
- package/dist/components/TriggerWorkflowButton.d.ts +0 -7
- package/dist/components/TriggerWorkflowButton.js +0 -46
- package/dist/components/TriggerWorkflowButton.js.map +0 -1
- package/dist/components/WorkflowExecutionStatus.d.ts +0 -6
- package/dist/components/WorkflowExecutionStatus.js +0 -287
- package/dist/components/WorkflowExecutionStatus.js.map +0 -1
- package/dist/exports/helpers.d.ts +0 -25
- package/dist/exports/helpers.js +0 -28
- package/dist/exports/helpers.js.map +0 -1
- package/dist/plugin/cron-scheduler.d.ts +0 -32
- package/dist/plugin/cron-scheduler.js +0 -537
- package/dist/plugin/cron-scheduler.js.map +0 -1
- package/dist/plugin/init-collection-hooks.d.ts +0 -4
- package/dist/plugin/init-collection-hooks.js +0 -100
- package/dist/plugin/init-collection-hooks.js.map +0 -1
- package/dist/plugin/init-global-hooks.d.ts +0 -3
- package/dist/plugin/init-global-hooks.js +0 -83
- package/dist/plugin/init-global-hooks.js.map +0 -1
- package/dist/plugin/init-step-tasks.d.ts +0 -3
- package/dist/plugin/init-step-tasks.js +0 -22
- package/dist/plugin/init-step-tasks.js.map +0 -1
- package/dist/plugin/init-webhook.d.ts +0 -2
- package/dist/plugin/init-webhook.js +0 -158
- package/dist/plugin/init-webhook.js.map +0 -1
- package/dist/plugin/init-workflow-hooks.d.ts +0 -6
- package/dist/plugin/init-workflow-hooks.js +0 -46
- package/dist/plugin/init-workflow-hooks.js.map +0 -1
- package/dist/utils/trigger-helpers.d.ts +0 -60
- package/dist/utils/trigger-helpers.js +0 -130
- package/dist/utils/trigger-helpers.js.map +0 -1
- package/dist/utils/trigger-presets.d.ts +0 -24
- package/dist/utils/trigger-presets.js +0 -177
- package/dist/utils/trigger-presets.js.map +0 -1
package/dist/plugin/index.js
CHANGED
|
@@ -1,101 +1,9 @@
|
|
|
1
1
|
import { createWorkflowCollection } from '../collections/Workflow.js';
|
|
2
2
|
import { WorkflowRunsCollection } from '../collections/WorkflowRuns.js';
|
|
3
|
-
import { WorkflowExecutor } from '../core/workflow-executor.js';
|
|
4
|
-
import { generateCronTasks, registerCronJobs } from './cron-scheduler.js';
|
|
5
|
-
import { initGlobalHooks } from "./init-global-hooks.js";
|
|
6
|
-
import { initStepTasks } from "./init-step-tasks.js";
|
|
7
|
-
import { initWebhookEndpoint } from "./init-webhook.js";
|
|
8
|
-
import { initWorkflowHooks } from './init-workflow-hooks.js';
|
|
9
3
|
import { getConfigLogger, initializeLogger } from './logger.js';
|
|
4
|
+
import { createCollectionTriggerHook } from "./collection-hook.js";
|
|
5
|
+
import { createGlobalTriggerHook } from "./global-hook.js";
|
|
10
6
|
export { getLogger } from './logger.js';
|
|
11
|
-
const executorRegistry = {
|
|
12
|
-
executor: null,
|
|
13
|
-
isInitialized: false,
|
|
14
|
-
logger: null
|
|
15
|
-
};
|
|
16
|
-
const setWorkflowExecutor = (executor, logger)=>{
|
|
17
|
-
executorRegistry.executor = executor;
|
|
18
|
-
executorRegistry.logger = logger;
|
|
19
|
-
executorRegistry.isInitialized = true;
|
|
20
|
-
logger.info('Workflow executor initialized and registered successfully');
|
|
21
|
-
};
|
|
22
|
-
const getExecutorRegistry = ()=>{
|
|
23
|
-
return executorRegistry;
|
|
24
|
-
};
|
|
25
|
-
// Helper function to create failed workflow runs for tracking errors
|
|
26
|
-
const createFailedWorkflowRun = async (args, errorMessage, logger)=>{
|
|
27
|
-
try {
|
|
28
|
-
// Only create failed workflow runs if we have enough context
|
|
29
|
-
if (!args?.req?.payload || !args?.collection?.slug) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
// Find workflows that should have been triggered
|
|
33
|
-
const workflows = await args.req.payload.find({
|
|
34
|
-
collection: 'workflows',
|
|
35
|
-
limit: 10,
|
|
36
|
-
req: args.req,
|
|
37
|
-
where: {
|
|
38
|
-
'triggers.collectionSlug': {
|
|
39
|
-
equals: args.collection.slug
|
|
40
|
-
},
|
|
41
|
-
'triggers.operation': {
|
|
42
|
-
equals: args.operation
|
|
43
|
-
},
|
|
44
|
-
'triggers.type': {
|
|
45
|
-
equals: 'collection-trigger'
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
// Create failed workflow runs for each matching workflow
|
|
50
|
-
for (const workflow of workflows.docs){
|
|
51
|
-
await args.req.payload.create({
|
|
52
|
-
collection: 'workflow-runs',
|
|
53
|
-
data: {
|
|
54
|
-
completedAt: new Date().toISOString(),
|
|
55
|
-
context: {
|
|
56
|
-
steps: {},
|
|
57
|
-
trigger: {
|
|
58
|
-
type: 'collection',
|
|
59
|
-
collection: args.collection.slug,
|
|
60
|
-
doc: args.doc,
|
|
61
|
-
operation: args.operation,
|
|
62
|
-
previousDoc: args.previousDoc,
|
|
63
|
-
triggeredAt: new Date().toISOString()
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
error: `Hook execution failed: ${errorMessage}`,
|
|
67
|
-
inputs: {},
|
|
68
|
-
logs: [
|
|
69
|
-
{
|
|
70
|
-
level: 'error',
|
|
71
|
-
message: `Hook execution failed: ${errorMessage}`,
|
|
72
|
-
timestamp: new Date().toISOString()
|
|
73
|
-
}
|
|
74
|
-
],
|
|
75
|
-
outputs: {},
|
|
76
|
-
startedAt: new Date().toISOString(),
|
|
77
|
-
status: 'failed',
|
|
78
|
-
steps: [],
|
|
79
|
-
triggeredBy: args?.req?.user?.email || 'system',
|
|
80
|
-
workflow: workflow.id,
|
|
81
|
-
workflowVersion: 1
|
|
82
|
-
},
|
|
83
|
-
req: args.req
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
if (workflows.docs.length > 0) {
|
|
87
|
-
logger.info({
|
|
88
|
-
errorMessage,
|
|
89
|
-
workflowCount: workflows.docs.length
|
|
90
|
-
}, 'Created failed workflow runs for hook execution error');
|
|
91
|
-
}
|
|
92
|
-
} catch (error) {
|
|
93
|
-
// Don't let workflow run creation failures break the original operation
|
|
94
|
-
logger.warn({
|
|
95
|
-
error: error instanceof Error ? error.message : 'Unknown error'
|
|
96
|
-
}, 'Failed to create failed workflow run record');
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
7
|
const applyCollectionsConfig = (pluginOptions, config)=>{
|
|
100
8
|
// Add workflow collections
|
|
101
9
|
if (!config.collections) {
|
|
@@ -103,7 +11,6 @@ const applyCollectionsConfig = (pluginOptions, config)=>{
|
|
|
103
11
|
}
|
|
104
12
|
config.collections.push(createWorkflowCollection(pluginOptions), WorkflowRunsCollection);
|
|
105
13
|
};
|
|
106
|
-
// Removed config-phase hook registration - user collections don't exist during config phase
|
|
107
14
|
export const workflowsPlugin = (pluginOptions)=>(config)=>{
|
|
108
15
|
// If the plugin is disabled, return config unchanged
|
|
109
16
|
if (pluginOptions.enabled === false) {
|
|
@@ -114,14 +21,14 @@ export const workflowsPlugin = (pluginOptions)=>(config)=>{
|
|
|
114
21
|
// This is the ONLY time we can add hooks that will actually work
|
|
115
22
|
const logger = getConfigLogger();
|
|
116
23
|
if (config.collections && pluginOptions.collectionTriggers) {
|
|
117
|
-
for (const [
|
|
24
|
+
for (const [collectionSlug, triggerConfig] of Object.entries(pluginOptions.collectionTriggers)){
|
|
118
25
|
if (!triggerConfig) {
|
|
119
26
|
continue;
|
|
120
27
|
}
|
|
121
28
|
// Find the collection config that matches
|
|
122
|
-
const collectionIndex = config.collections.findIndex((c)=>c.slug ===
|
|
29
|
+
const collectionIndex = config.collections.findIndex((c)=>c.slug === collectionSlug);
|
|
123
30
|
if (collectionIndex === -1) {
|
|
124
|
-
logger.warn(`Collection '${
|
|
31
|
+
logger.warn(`Collection '${collectionSlug}' not found in config.collections`);
|
|
125
32
|
continue;
|
|
126
33
|
}
|
|
127
34
|
const collection = config.collections[collectionIndex];
|
|
@@ -129,84 +36,84 @@ export const workflowsPlugin = (pluginOptions)=>(config)=>{
|
|
|
129
36
|
if (!collection.hooks) {
|
|
130
37
|
collection.hooks = {};
|
|
131
38
|
}
|
|
132
|
-
|
|
133
|
-
|
|
39
|
+
// Determine which hooks to register based on config
|
|
40
|
+
const hooksToRegister = triggerConfig === true ? {
|
|
41
|
+
afterChange: true,
|
|
42
|
+
afterDelete: true,
|
|
43
|
+
afterRead: true
|
|
44
|
+
} : triggerConfig;
|
|
45
|
+
// Register each configured hook
|
|
46
|
+
Object.entries(hooksToRegister).forEach(([hookName, enabled])=>{
|
|
47
|
+
if (!enabled) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const hookKey = hookName;
|
|
51
|
+
// Initialize the hook array if needed
|
|
52
|
+
if (!collection.hooks[hookKey]) {
|
|
53
|
+
collection.hooks[hookKey] = [];
|
|
54
|
+
}
|
|
55
|
+
// Create the automation hook for this specific collection and hook type
|
|
56
|
+
const automationHook = createCollectionTriggerHook(collectionSlug, hookKey);
|
|
57
|
+
// Mark it for debugging
|
|
58
|
+
Object.defineProperty(automationHook, '__isAutomationHook', {
|
|
59
|
+
value: true,
|
|
60
|
+
enumerable: false
|
|
61
|
+
});
|
|
62
|
+
Object.defineProperty(automationHook, '__hookType', {
|
|
63
|
+
value: hookKey,
|
|
64
|
+
enumerable: false
|
|
65
|
+
});
|
|
66
|
+
collection.hooks[hookKey].push(automationHook);
|
|
67
|
+
logger.debug(`Registered ${hookKey} hook for collection '${collectionSlug}'`);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Handle global triggers similarly to collection triggers
|
|
72
|
+
if (config.globals && pluginOptions.globalTriggers) {
|
|
73
|
+
for (const [globalSlug, triggerConfig] of Object.entries(pluginOptions.globalTriggers)){
|
|
74
|
+
if (!triggerConfig) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
// Find the global config that matches
|
|
78
|
+
const globalIndex = config.globals.findIndex((g)=>g.slug === globalSlug);
|
|
79
|
+
if (globalIndex === -1) {
|
|
80
|
+
logger.warn(`Global '${globalSlug}' not found in config.globals`);
|
|
81
|
+
continue;
|
|
134
82
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const executor = new WorkflowExecutor(args.req.payload, logger);
|
|
155
|
-
setWorkflowExecutor(executor, logger);
|
|
156
|
-
logger.info('Lazy initialization successful');
|
|
157
|
-
} else {
|
|
158
|
-
logger.error('Cannot lazy initialize - no payload instance available');
|
|
159
|
-
await createFailedWorkflowRun(args, 'Workflow executor not initialized and lazy initialization failed - no payload instance', logger);
|
|
160
|
-
return undefined;
|
|
161
|
-
}
|
|
162
|
-
} catch (error) {
|
|
163
|
-
logger.error('Lazy initialization failed:', error);
|
|
164
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
165
|
-
await createFailedWorkflowRun(args, `Workflow executor lazy initialization failed: ${errorMessage}`, logger);
|
|
166
|
-
return undefined;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
// Re-check registry after potential lazy initialization
|
|
170
|
-
const updatedRegistry = getExecutorRegistry();
|
|
171
|
-
if (!updatedRegistry.executor) {
|
|
172
|
-
logger.error('Workflow executor is null despite being marked as initialized');
|
|
173
|
-
// Create a failed workflow run to track this issue
|
|
174
|
-
await createFailedWorkflowRun(args, 'Executor not available after initialization', logger);
|
|
175
|
-
return undefined;
|
|
176
|
-
}
|
|
177
|
-
logger.debug('Executing triggered workflows...');
|
|
178
|
-
await updatedRegistry.executor.executeTriggeredWorkflows(args.collection.slug, args.operation, args.doc, args.previousDoc, args.req);
|
|
179
|
-
logger.info({
|
|
180
|
-
collection: args?.collection?.slug,
|
|
181
|
-
docId: args?.doc?.id,
|
|
182
|
-
operation: args?.operation
|
|
183
|
-
}, 'Workflow execution completed successfully');
|
|
184
|
-
} catch (error) {
|
|
185
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
186
|
-
logger.error({
|
|
187
|
-
collection: args?.collection?.slug,
|
|
188
|
-
docId: args?.doc?.id,
|
|
189
|
-
error: errorMessage,
|
|
190
|
-
errorStack: error instanceof Error ? error.stack : undefined,
|
|
191
|
-
operation: args?.operation
|
|
192
|
-
}, 'Hook execution failed');
|
|
193
|
-
// Create a failed workflow run to track this error
|
|
194
|
-
try {
|
|
195
|
-
await createFailedWorkflowRun(args, errorMessage, logger);
|
|
196
|
-
} catch (createError) {
|
|
197
|
-
logger.error({
|
|
198
|
-
error: createError instanceof Error ? createError.message : 'Unknown error'
|
|
199
|
-
}, 'Failed to create workflow run for hook error');
|
|
200
|
-
}
|
|
201
|
-
// Don't throw to prevent breaking the original operation
|
|
83
|
+
const global = config.globals[globalIndex];
|
|
84
|
+
// Initialize hooks if needed
|
|
85
|
+
if (!global.hooks) {
|
|
86
|
+
global.hooks = {};
|
|
87
|
+
}
|
|
88
|
+
// Determine which hooks to register based on config
|
|
89
|
+
const hooksToRegister = triggerConfig === true ? {
|
|
90
|
+
afterChange: true,
|
|
91
|
+
afterRead: true
|
|
92
|
+
} : triggerConfig;
|
|
93
|
+
// Register each configured hook
|
|
94
|
+
Object.entries(hooksToRegister).forEach(([hookName, enabled])=>{
|
|
95
|
+
if (!enabled) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const hookKey = hookName;
|
|
99
|
+
// Initialize the hook array if needed
|
|
100
|
+
if (!global.hooks[hookKey]) {
|
|
101
|
+
global.hooks[hookKey] = [];
|
|
202
102
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
103
|
+
// Create the automation hook for this specific global and hook type
|
|
104
|
+
const automationHook = createGlobalTriggerHook(globalSlug, hookKey);
|
|
105
|
+
// Mark it for debugging
|
|
106
|
+
Object.defineProperty(automationHook, '__isAutomationHook', {
|
|
107
|
+
value: true,
|
|
108
|
+
enumerable: false
|
|
109
|
+
});
|
|
110
|
+
Object.defineProperty(automationHook, '__hookType', {
|
|
111
|
+
value: hookKey,
|
|
112
|
+
enumerable: false
|
|
113
|
+
});
|
|
114
|
+
global.hooks[hookKey].push(automationHook);
|
|
115
|
+
logger.debug(`Registered ${hookKey} hook for global '${globalSlug}'`);
|
|
207
116
|
});
|
|
208
|
-
// Add the hook to the collection config
|
|
209
|
-
collection.hooks.afterChange.push(automationHook);
|
|
210
117
|
}
|
|
211
118
|
}
|
|
212
119
|
if (!config.jobs) {
|
|
@@ -214,17 +121,12 @@ export const workflowsPlugin = (pluginOptions)=>(config)=>{
|
|
|
214
121
|
tasks: []
|
|
215
122
|
};
|
|
216
123
|
}
|
|
217
|
-
const configLogger = getConfigLogger();
|
|
218
|
-
// Generate cron tasks for workflows with cron triggers
|
|
219
|
-
generateCronTasks(config);
|
|
220
124
|
for (const step of pluginOptions.steps){
|
|
221
125
|
if (!config.jobs?.tasks?.find((task)=>task.slug === step.slug)) {
|
|
222
126
|
config.jobs?.tasks?.push(step);
|
|
223
127
|
}
|
|
224
128
|
}
|
|
225
|
-
//
|
|
226
|
-
initWebhookEndpoint(config, pluginOptions.webhookPrefix || 'webhook');
|
|
227
|
-
// Set up onInit to register collection hooks and initialize features
|
|
129
|
+
// Set up onInit to initialize features
|
|
228
130
|
const incomingOnInit = config.onInit;
|
|
229
131
|
config.onInit = async (payload)=>{
|
|
230
132
|
// Execute any existing onInit functions first
|
|
@@ -234,24 +136,8 @@ export const workflowsPlugin = (pluginOptions)=>(config)=>{
|
|
|
234
136
|
// Initialize the logger with the payload instance
|
|
235
137
|
const logger = initializeLogger(payload);
|
|
236
138
|
logger.info('Logger initialized with payload instance');
|
|
237
|
-
// Log
|
|
238
|
-
logger.info(`Plugin configuration: ${Object.keys(pluginOptions.collectionTriggers || {}).length} collection triggers, ${pluginOptions.steps?.length || 0} steps`);
|
|
239
|
-
// Create workflow executor instance
|
|
240
|
-
logger.debug('Creating workflow executor instance');
|
|
241
|
-
const executor = new WorkflowExecutor(payload, logger);
|
|
242
|
-
// Register executor with proper dependency injection
|
|
243
|
-
setWorkflowExecutor(executor, logger);
|
|
244
|
-
// Hooks are now registered during config phase - just log status
|
|
245
|
-
logger.info('Hooks were registered during config phase - executor now available');
|
|
246
|
-
logger.info('Initializing global hooks...');
|
|
247
|
-
initGlobalHooks(payload, logger, executor);
|
|
248
|
-
logger.info('Initializing workflow hooks...');
|
|
249
|
-
initWorkflowHooks(payload, logger);
|
|
250
|
-
logger.info('Initializing step tasks...');
|
|
251
|
-
initStepTasks(pluginOptions, payload, logger);
|
|
252
|
-
// Register cron jobs for workflows with cron triggers
|
|
253
|
-
logger.info('Registering cron jobs...');
|
|
254
|
-
await registerCronJobs(payload, logger);
|
|
139
|
+
// Log trigger configuration
|
|
140
|
+
logger.info(`Plugin configuration: ${Object.keys(pluginOptions.collectionTriggers || {}).length} collection triggers, ${Object.keys(pluginOptions.globalTriggers || {}).length} global triggers, ${pluginOptions.steps?.length || 0} steps`);
|
|
255
141
|
logger.info('Plugin initialized successfully - all hooks registered');
|
|
256
142
|
};
|
|
257
143
|
return config;
|
package/dist/plugin/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/plugin/index.ts"],"sourcesContent":["import type {Config} from 'payload'\n\nimport type {CollectionTriggerConfigCrud, WorkflowsPluginConfig} from \"./config-types.js\"\n\nimport {createWorkflowCollection} from '../collections/Workflow.js'\nimport {WorkflowRunsCollection} from '../collections/WorkflowRuns.js'\nimport {WorkflowExecutor} from '../core/workflow-executor.js'\nimport {generateCronTasks, registerCronJobs} from './cron-scheduler.js'\nimport {initCollectionHooks} from \"./init-collection-hooks.js\"\nimport {initGlobalHooks} from \"./init-global-hooks.js\"\nimport {initStepTasks} from \"./init-step-tasks.js\"\nimport {initWebhookEndpoint} from \"./init-webhook.js\"\nimport {initWorkflowHooks} from './init-workflow-hooks.js'\nimport {getConfigLogger, initializeLogger} from './logger.js'\n\nexport {getLogger} from './logger.js'\n\n// Improved executor registry with proper error handling and logging\ninterface ExecutorRegistry {\n executor: null | WorkflowExecutor\n isInitialized: boolean\n logger: any | null\n}\n\nconst executorRegistry: ExecutorRegistry = {\n executor: null,\n isInitialized: false,\n logger: null\n}\n\nconst setWorkflowExecutor = (executor: WorkflowExecutor, logger: any) => {\n executorRegistry.executor = executor\n executorRegistry.logger = logger\n executorRegistry.isInitialized = true\n\n logger.info('Workflow executor initialized and registered successfully')\n}\n\nconst getExecutorRegistry = (): ExecutorRegistry => {\n return executorRegistry\n}\n\n// Helper function to create failed workflow runs for tracking errors\nconst createFailedWorkflowRun = async (args: any, errorMessage: string, logger: any) => {\n try {\n // Only create failed workflow runs if we have enough context\n if (!args?.req?.payload || !args?.collection?.slug) {\n return\n }\n\n // Find workflows that should have been triggered\n const workflows = await args.req.payload.find({\n collection: 'workflows',\n limit: 10,\n req: args.req,\n where: {\n 'triggers.collectionSlug': {\n equals: args.collection.slug\n },\n 'triggers.operation': {\n equals: args.operation\n },\n 'triggers.type': {\n equals: 'collection-trigger'\n }\n }\n })\n\n // Create failed workflow runs for each matching workflow\n for (const workflow of workflows.docs) {\n await args.req.payload.create({\n collection: 'workflow-runs',\n data: {\n completedAt: new Date().toISOString(),\n context: {\n steps: {},\n trigger: {\n type: 'collection',\n collection: args.collection.slug,\n doc: args.doc,\n operation: args.operation,\n previousDoc: args.previousDoc,\n triggeredAt: new Date().toISOString()\n }\n },\n error: `Hook execution failed: ${errorMessage}`,\n inputs: {},\n logs: [{\n level: 'error',\n message: `Hook execution failed: ${errorMessage}`,\n timestamp: new Date().toISOString()\n }],\n outputs: {},\n startedAt: new Date().toISOString(),\n status: 'failed',\n steps: [],\n triggeredBy: args?.req?.user?.email || 'system',\n workflow: workflow.id,\n workflowVersion: 1\n },\n req: args.req\n })\n }\n\n if (workflows.docs.length > 0) {\n logger.info({\n errorMessage,\n workflowCount: workflows.docs.length\n }, 'Created failed workflow runs for hook execution error')\n }\n\n } catch (error) {\n // Don't let workflow run creation failures break the original operation\n logger.warn({\n error: error instanceof Error ? error.message : 'Unknown error'\n }, 'Failed to create failed workflow run record')\n }\n}\n\nconst applyCollectionsConfig = <T extends string>(pluginOptions: WorkflowsPluginConfig<T>, config: Config) => {\n // Add workflow collections\n if (!config.collections) {\n config.collections = []\n }\n\n config.collections.push(\n createWorkflowCollection(pluginOptions),\n WorkflowRunsCollection\n )\n}\n\n// Removed config-phase hook registration - user collections don't exist during config phase\n\n\nexport const workflowsPlugin =\n <TSlug extends string>(pluginOptions: WorkflowsPluginConfig<TSlug>) =>\n (config: Config): Config => {\n // If the plugin is disabled, return config unchanged\n if (pluginOptions.enabled === false) {\n return config\n }\n\n applyCollectionsConfig<TSlug>(pluginOptions, config)\n\n // CRITICAL: Modify existing collection configs BEFORE PayloadCMS processes them\n // This is the ONLY time we can add hooks that will actually work\n const logger = getConfigLogger()\n\n if (config.collections && pluginOptions.collectionTriggers) {\n for (const [triggerSlug, triggerConfig] of Object.entries(pluginOptions.collectionTriggers)) {\n if (!triggerConfig) {continue}\n\n // Find the collection config that matches\n const collectionIndex = config.collections.findIndex(c => c.slug === triggerSlug)\n if (collectionIndex === -1) {\n logger.warn(`Collection '${triggerSlug}' not found in config.collections`)\n continue\n }\n\n const collection = config.collections[collectionIndex]\n\n // Initialize hooks if needed\n if (!collection.hooks) {\n collection.hooks = {}\n }\n if (!collection.hooks.afterChange) {\n collection.hooks.afterChange = []\n }\n\n // Create a reliable hook function with proper dependency injection\n const automationHook = Object.assign(\n async function payloadAutomationHook(args: any) {\n const registry = getExecutorRegistry()\n\n // Use proper logger if available, fallback to args.req.payload.logger\n const logger = registry.logger || args?.req?.payload?.logger || console\n\n try {\n logger.info({\n collection: args?.collection?.slug,\n docId: args?.doc?.id,\n hookType: 'automation',\n operation: args?.operation\n }, 'Collection automation hook triggered')\n\n if (!registry.isInitialized) {\n logger.warn('Workflow executor not yet initialized, attempting lazy initialization')\n \n try {\n // Try to create executor if we have a payload instance\n if (args.req?.payload) {\n logger.info('Creating workflow executor via lazy initialization')\n const { WorkflowExecutor } = await import('../core/workflow-executor.js')\n const executor = new WorkflowExecutor(args.req.payload, logger)\n setWorkflowExecutor(executor, logger)\n logger.info('Lazy initialization successful')\n } else {\n logger.error('Cannot lazy initialize - no payload instance available')\n await createFailedWorkflowRun(args, 'Workflow executor not initialized and lazy initialization failed - no payload instance', logger)\n return undefined\n }\n } catch (error) {\n logger.error('Lazy initialization failed:', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n await createFailedWorkflowRun(args, `Workflow executor lazy initialization failed: ${errorMessage}`, logger)\n return undefined\n }\n }\n\n // Re-check registry after potential lazy initialization\n const updatedRegistry = getExecutorRegistry()\n if (!updatedRegistry.executor) {\n logger.error('Workflow executor is null despite being marked as initialized')\n // Create a failed workflow run to track this issue\n await createFailedWorkflowRun(args, 'Executor not available after initialization', logger)\n return undefined\n }\n\n logger.debug('Executing triggered workflows...')\n await updatedRegistry.executor.executeTriggeredWorkflows(\n args.collection.slug,\n args.operation,\n args.doc,\n args.previousDoc,\n args.req\n )\n\n logger.info({\n collection: args?.collection?.slug,\n docId: args?.doc?.id,\n operation: args?.operation\n }, 'Workflow execution completed successfully')\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n\n logger.error({\n collection: args?.collection?.slug,\n docId: args?.doc?.id,\n error: errorMessage,\n errorStack: error instanceof Error ? error.stack : undefined,\n operation: args?.operation\n }, 'Hook execution failed')\n\n // Create a failed workflow run to track this error\n try {\n await createFailedWorkflowRun(args, errorMessage, logger)\n } catch (createError) {\n logger.error({\n error: createError instanceof Error ? createError.message : 'Unknown error'\n }, 'Failed to create workflow run for hook error')\n }\n\n // Don't throw to prevent breaking the original operation\n }\n\n return undefined\n },\n {\n __isAutomationHook: true,\n __version: '0.0.22'\n }\n )\n\n // Add the hook to the collection config\n collection.hooks.afterChange.push(automationHook)\n }\n }\n\n if (!config.jobs) {\n config.jobs = {tasks: []}\n }\n\n const configLogger = getConfigLogger()\n\n // Generate cron tasks for workflows with cron triggers\n generateCronTasks(config)\n\n for (const step of pluginOptions.steps) {\n if (!config.jobs?.tasks?.find(task => task.slug === step.slug)) {\n config.jobs?.tasks?.push(step)\n }\n }\n\n // Initialize webhook endpoint\n initWebhookEndpoint(config, pluginOptions.webhookPrefix || 'webhook')\n\n // Set up onInit to register collection hooks and initialize features\n const incomingOnInit = config.onInit\n config.onInit = async (payload) => {\n\n // Execute any existing onInit functions first\n if (incomingOnInit) {\n await incomingOnInit(payload)\n }\n\n // Initialize the logger with the payload instance\n const logger = initializeLogger(payload)\n logger.info('Logger initialized with payload instance')\n\n // Log collection trigger configuration\n logger.info(`Plugin configuration: ${Object.keys(pluginOptions.collectionTriggers || {}).length} collection triggers, ${pluginOptions.steps?.length || 0} steps`)\n\n // Create workflow executor instance\n logger.debug('Creating workflow executor instance')\n const executor = new WorkflowExecutor(payload, logger)\n\n // Register executor with proper dependency injection\n setWorkflowExecutor(executor, logger)\n\n // Hooks are now registered during config phase - just log status\n logger.info('Hooks were registered during config phase - executor now available')\n\n logger.info('Initializing global hooks...')\n initGlobalHooks(payload, logger, executor)\n\n logger.info('Initializing workflow hooks...')\n initWorkflowHooks(payload, logger)\n\n logger.info('Initializing step tasks...')\n initStepTasks(pluginOptions, payload, logger)\n\n // Register cron jobs for workflows with cron triggers\n logger.info('Registering cron jobs...')\n await registerCronJobs(payload, logger)\n\n logger.info('Plugin initialized successfully - all hooks registered')\n }\n\n return config\n }\n"],"names":["createWorkflowCollection","WorkflowRunsCollection","WorkflowExecutor","generateCronTasks","registerCronJobs","initGlobalHooks","initStepTasks","initWebhookEndpoint","initWorkflowHooks","getConfigLogger","initializeLogger","getLogger","executorRegistry","executor","isInitialized","logger","setWorkflowExecutor","info","getExecutorRegistry","createFailedWorkflowRun","args","errorMessage","req","payload","collection","slug","workflows","find","limit","where","equals","operation","workflow","docs","create","data","completedAt","Date","toISOString","context","steps","trigger","type","doc","previousDoc","triggeredAt","error","inputs","logs","level","message","timestamp","outputs","startedAt","status","triggeredBy","user","email","id","workflowVersion","length","workflowCount","warn","Error","applyCollectionsConfig","pluginOptions","config","collections","push","workflowsPlugin","enabled","collectionTriggers","triggerSlug","triggerConfig","Object","entries","collectionIndex","findIndex","c","hooks","afterChange","automationHook","assign","payloadAutomationHook","registry","console","docId","hookType","undefined","String","updatedRegistry","debug","executeTriggeredWorkflows","errorStack","stack","createError","__isAutomationHook","__version","jobs","tasks","configLogger","step","task","webhookPrefix","incomingOnInit","onInit","keys"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/plugin/index.ts"],"sourcesContent":["import type {CollectionConfig, Config} from 'payload'\n\nimport type {WorkflowsPluginConfig} from \"./config-types.js\"\n\nimport {createWorkflowCollection} from '../collections/Workflow.js'\nimport {WorkflowRunsCollection} from '../collections/WorkflowRuns.js'\nimport {WorkflowExecutor} from '../core/workflow-executor.js'\nimport {getConfigLogger, initializeLogger} from './logger.js'\nimport {createCollectionTriggerHook} from \"./collection-hook.js\"\nimport {createGlobalTriggerHook} from \"./global-hook.js\"\n\nexport {getLogger} from './logger.js'\n\nconst applyCollectionsConfig = <T extends string>(pluginOptions: WorkflowsPluginConfig<T>, config: Config) => {\n // Add workflow collections\n if (!config.collections) {\n config.collections = []\n }\n\n config.collections.push(\n createWorkflowCollection(pluginOptions),\n WorkflowRunsCollection\n )\n}\n\ntype AnyHook =\n CollectionConfig['hooks'] extends infer H\n ? H extends Record<string, unknown>\n ? NonNullable<H[keyof H]> extends (infer U)[]\n ? U\n : never\n : never\n : never;\n\ntype HookArgs = Parameters<AnyHook>[0]\n\nexport const workflowsPlugin =\n <TSlug extends string>(pluginOptions: WorkflowsPluginConfig<TSlug>) =>\n (config: Config): Config => {\n // If the plugin is disabled, return config unchanged\n if (pluginOptions.enabled === false) {\n return config\n }\n\n applyCollectionsConfig<TSlug>(pluginOptions, config)\n\n // CRITICAL: Modify existing collection configs BEFORE PayloadCMS processes them\n // This is the ONLY time we can add hooks that will actually work\n const logger = getConfigLogger()\n\n if (config.collections && pluginOptions.collectionTriggers) {\n for (const [collectionSlug, triggerConfig] of Object.entries(pluginOptions.collectionTriggers)) {\n if (!triggerConfig) {\n continue\n }\n\n // Find the collection config that matches\n const collectionIndex = config.collections.findIndex(c => c.slug === collectionSlug)\n if (collectionIndex === -1) {\n logger.warn(`Collection '${collectionSlug}' not found in config.collections`)\n continue\n }\n\n const collection = config.collections[collectionIndex]\n\n // Initialize hooks if needed\n if (!collection.hooks) {\n collection.hooks = {}\n }\n\n // Determine which hooks to register based on config\n const hooksToRegister = triggerConfig === true\n ? {\n afterChange: true,\n afterDelete: true,\n afterRead: true,\n }\n : triggerConfig\n\n // Register each configured hook\n Object.entries(hooksToRegister).forEach(([hookName, enabled]) => {\n if (!enabled) {\n return\n }\n\n const hookKey = hookName as keyof typeof collection.hooks\n\n // Initialize the hook array if needed\n if (!collection.hooks![hookKey]) {\n collection.hooks![hookKey] = []\n }\n\n // Create the automation hook for this specific collection and hook type\n const automationHook = createCollectionTriggerHook(collectionSlug, hookKey)\n\n // Mark it for debugging\n Object.defineProperty(automationHook, '__isAutomationHook', {\n value: true,\n enumerable: false\n })\n Object.defineProperty(automationHook, '__hookType', {\n value: hookKey,\n enumerable: false\n })\n\n // Add the hook to the collection\n ;(collection.hooks![hookKey] as Array<unknown>).push(automationHook)\n\n logger.debug(`Registered ${hookKey} hook for collection '${collectionSlug}'`)\n })\n }\n }\n\n // Handle global triggers similarly to collection triggers\n if (config.globals && pluginOptions.globalTriggers) {\n for (const [globalSlug, triggerConfig] of Object.entries(pluginOptions.globalTriggers)) {\n if (!triggerConfig) {\n continue\n }\n\n // Find the global config that matches\n const globalIndex = config.globals.findIndex(g => g.slug === globalSlug)\n if (globalIndex === -1) {\n logger.warn(`Global '${globalSlug}' not found in config.globals`)\n continue\n }\n\n const global = config.globals[globalIndex]\n\n // Initialize hooks if needed\n if (!global.hooks) {\n global.hooks = {}\n }\n\n // Determine which hooks to register based on config\n const hooksToRegister = triggerConfig === true\n ? {\n afterChange: true,\n afterRead: true,\n }\n : triggerConfig\n\n // Register each configured hook\n Object.entries(hooksToRegister).forEach(([hookName, enabled]) => {\n if (!enabled) {\n return\n }\n\n const hookKey = hookName as keyof typeof global.hooks\n\n // Initialize the hook array if needed\n if (!global.hooks![hookKey]) {\n global.hooks![hookKey] = []\n }\n\n // Create the automation hook for this specific global and hook type\n const automationHook = createGlobalTriggerHook(globalSlug, hookKey)\n\n // Mark it for debugging\n Object.defineProperty(automationHook, '__isAutomationHook', {\n value: true,\n enumerable: false\n })\n Object.defineProperty(automationHook, '__hookType', {\n value: hookKey,\n enumerable: false\n })\n\n // Add the hook to the global\n ;(global.hooks![hookKey] as Array<unknown>).push(automationHook)\n\n logger.debug(`Registered ${hookKey} hook for global '${globalSlug}'`)\n })\n }\n }\n\n if (!config.jobs) {\n config.jobs = {tasks: []}\n }\n\n for (const step of pluginOptions.steps) {\n if (!config.jobs?.tasks?.find(task => task.slug === step.slug)) {\n config.jobs?.tasks?.push(step)\n }\n }\n\n\n // Set up onInit to initialize features\n const incomingOnInit = config.onInit\n config.onInit = async (payload) => {\n // Execute any existing onInit functions first\n if (incomingOnInit) {\n await incomingOnInit(payload)\n }\n\n // Initialize the logger with the payload instance\n const logger = initializeLogger(payload)\n logger.info('Logger initialized with payload instance')\n\n // Log trigger configuration\n logger.info(`Plugin configuration: ${Object.keys(pluginOptions.collectionTriggers || {}).length} collection triggers, ${Object.keys(pluginOptions.globalTriggers || {}).length} global triggers, ${pluginOptions.steps?.length || 0} steps`)\n\n logger.info('Plugin initialized successfully - all hooks registered')\n }\n\n return config\n }\n"],"names":["createWorkflowCollection","WorkflowRunsCollection","getConfigLogger","initializeLogger","createCollectionTriggerHook","createGlobalTriggerHook","getLogger","applyCollectionsConfig","pluginOptions","config","collections","push","workflowsPlugin","enabled","logger","collectionTriggers","collectionSlug","triggerConfig","Object","entries","collectionIndex","findIndex","c","slug","warn","collection","hooks","hooksToRegister","afterChange","afterDelete","afterRead","forEach","hookName","hookKey","automationHook","defineProperty","value","enumerable","debug","globals","globalTriggers","globalSlug","globalIndex","g","global","jobs","tasks","step","steps","find","task","incomingOnInit","onInit","payload","info","keys","length"],"mappings":"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"}
|
|
@@ -73,7 +73,7 @@ describe('WorkflowExecutor', ()=>{
|
|
|
73
73
|
describe('resolveStepInput', ()=>{
|
|
74
74
|
it('should resolve all JSONPath expressions in step config', ()=>{
|
|
75
75
|
const config = {
|
|
76
|
-
url: '$.trigger.
|
|
76
|
+
url: '$.trigger.data.url',
|
|
77
77
|
message: 'Static message',
|
|
78
78
|
data: {
|
|
79
79
|
id: '$.trigger.doc.id',
|
|
@@ -86,7 +86,7 @@ describe('WorkflowExecutor', ()=>{
|
|
|
86
86
|
id: 'doc-123',
|
|
87
87
|
title: 'Doc Title'
|
|
88
88
|
},
|
|
89
|
-
|
|
89
|
+
data: {
|
|
90
90
|
url: 'https://example.com/webhook'
|
|
91
91
|
}
|
|
92
92
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/test/workflow-executor.test.ts"],"sourcesContent":["import { describe, it, expect, beforeEach, vi } from 'vitest'\nimport { WorkflowExecutor } from '../core/workflow-executor.js'\nimport type { Payload } from 'payload'\n\ndescribe('WorkflowExecutor', () => {\n let mockPayload: Payload\n let mockLogger: any\n let executor: WorkflowExecutor\n\n beforeEach(() => {\n mockLogger = {\n info: vi.fn(),\n debug: vi.fn(),\n warn: vi.fn(),\n error: vi.fn()\n }\n\n mockPayload = {\n jobs: {\n queue: vi.fn().mockResolvedValue({ id: 'job-123' }),\n run: vi.fn().mockResolvedValue(undefined)\n },\n create: vi.fn(),\n update: vi.fn(),\n find: vi.fn()\n } as any\n\n executor = new WorkflowExecutor(mockPayload, mockLogger)\n })\n\n describe('resolveJSONPathValue', () => {\n it('should resolve simple JSONPath expressions', () => {\n const context = {\n trigger: {\n doc: { id: 'test-id', title: 'Test Title' }\n },\n steps: {}\n }\n\n const result = (executor as any).resolveJSONPathValue('$.trigger.doc.id', context)\n expect(result).toBe('test-id')\n })\n\n it('should resolve nested JSONPath expressions', () => {\n const context = {\n trigger: {\n doc: { \n id: 'test-id',\n nested: { value: 'nested-value' }\n }\n },\n steps: {}\n }\n\n const result = (executor as any).resolveJSONPathValue('$.trigger.doc.nested.value', context)\n expect(result).toBe('nested-value')\n })\n\n it('should return original value for non-JSONPath strings', () => {\n const context = { trigger: {}, steps: {} }\n const result = (executor as any).resolveJSONPathValue('plain-string', context)\n expect(result).toBe('plain-string')\n })\n\n it('should handle missing JSONPath gracefully', () => {\n const context = { trigger: {}, steps: {} }\n const result = (executor as any).resolveJSONPathValue('$.trigger.missing.field', context)\n expect(result).toBe('$.trigger.missing.field') // Should return original if resolution fails\n })\n })\n\n describe('resolveStepInput', () => {\n it('should resolve all JSONPath expressions in step config', () => {\n const config = {\n url: '$.trigger.webhook.url',\n message: 'Static message',\n data: {\n id: '$.trigger.doc.id',\n title: '$.trigger.doc.title'\n }\n }\n\n const context = {\n trigger: {\n doc: { id: 'doc-123', title: 'Doc Title' },\n webhook: { url: 'https://example.com/webhook' }\n },\n steps: {}\n }\n\n const result = (executor as any).resolveStepInput(config, context)\n \n expect(result).toEqual({\n url: 'https://example.com/webhook',\n message: 'Static message',\n data: {\n id: 'doc-123',\n title: 'Doc Title'\n }\n })\n })\n\n it('should handle arrays with JSONPath expressions', () => {\n const config = {\n items: ['$.trigger.doc.id', 'static-value', '$.trigger.doc.title']\n }\n\n const context = {\n trigger: {\n doc: { id: 'doc-123', title: 'Doc Title' }\n },\n steps: {}\n }\n\n const result = (executor as any).resolveStepInput(config, context)\n \n expect(result).toEqual({\n items: ['doc-123', 'static-value', 'Doc Title']\n })\n })\n })\n\n describe('resolveExecutionOrder', () => {\n it('should handle steps without dependencies', () => {\n const steps = [\n { name: 'step1', step: 'http-request' },\n { name: 'step2', step: 'create-document' },\n { name: 'step3', step: 'http-request' }\n ]\n\n const result = (executor as any).resolveExecutionOrder(steps)\n \n expect(result).toHaveLength(1) // All in one batch\n expect(result[0]).toHaveLength(3) // All steps in first batch\n })\n\n it('should handle steps with dependencies', () => {\n const steps = [\n { name: 'step1', step: 'http-request' },\n { name: 'step2', step: 'create-document', dependencies: ['step1'] },\n { name: 'step3', step: 'http-request', dependencies: ['step2'] }\n ]\n\n const result = (executor as any).resolveExecutionOrder(steps)\n \n expect(result).toHaveLength(3) // Three batches\n expect(result[0]).toHaveLength(1) // step1 first\n expect(result[1]).toHaveLength(1) // step2 second\n expect(result[2]).toHaveLength(1) // step3 third\n })\n\n it('should handle parallel execution with partial dependencies', () => {\n const steps = [\n { name: 'step1', step: 'http-request' },\n { name: 'step2', step: 'create-document' },\n { name: 'step3', step: 'http-request', dependencies: ['step1'] },\n { name: 'step4', step: 'create-document', dependencies: ['step1'] }\n ]\n\n const result = (executor as any).resolveExecutionOrder(steps)\n \n expect(result).toHaveLength(2) // Two batches\n expect(result[0]).toHaveLength(2) // step1 and step2 in parallel\n expect(result[1]).toHaveLength(2) // step3 and step4 in parallel\n })\n\n it('should detect circular dependencies', () => {\n const steps = [\n { name: 'step1', step: 'http-request', dependencies: ['step2'] },\n { name: 'step2', step: 'create-document', dependencies: ['step1'] }\n ]\n\n expect(() => {\n (executor as any).resolveExecutionOrder(steps)\n }).toThrow('Circular dependency detected')\n })\n })\n\n describe('evaluateCondition', () => {\n it('should evaluate simple equality conditions', () => {\n const context = {\n trigger: {\n doc: { status: 'published' }\n },\n steps: {}\n }\n\n const result = (executor as any).evaluateCondition('$.trigger.doc.status == \"published\"', context)\n expect(result).toBe(true)\n })\n\n it('should evaluate inequality conditions', () => {\n const context = {\n trigger: {\n doc: { count: 5 }\n },\n steps: {}\n }\n\n const result = (executor as any).evaluateCondition('$.trigger.doc.count > 3', context)\n expect(result).toBe(true)\n })\n\n it('should return false for invalid conditions', () => {\n const context = { trigger: {}, steps: {} }\n const result = (executor as any).evaluateCondition('invalid condition syntax', context)\n expect(result).toBe(false)\n })\n\n it('should handle missing context gracefully', () => {\n const context = { trigger: {}, steps: {} }\n const result = (executor as any).evaluateCondition('$.trigger.doc.status == \"published\"', context)\n expect(result).toBe(false) // Missing values should fail condition\n })\n })\n\n describe('safeSerialize', () => {\n it('should serialize simple objects', () => {\n const obj = { name: 'test', value: 123 }\n const result = (executor as any).safeSerialize(obj)\n expect(result).toBe('{\"name\":\"test\",\"value\":123}')\n })\n\n it('should handle circular references', () => {\n const obj: any = { name: 'test' }\n obj.self = obj // Create circular reference\n\n const result = (executor as any).safeSerialize(obj)\n expect(result).toContain('\"name\":\"test\"')\n expect(result).toContain('\"self\":\"[Circular]\"')\n })\n\n it('should handle undefined and null values', () => {\n const obj = { \n defined: 'value',\n undefined: undefined,\n null: null\n }\n \n const result = (executor as any).safeSerialize(obj)\n const parsed = JSON.parse(result)\n expect(parsed.defined).toBe('value')\n expect(parsed.null).toBe(null)\n expect(parsed).not.toHaveProperty('undefined') // undefined props are omitted\n })\n })\n\n describe('executeWorkflow', () => {\n it('should execute workflow with single step', async () => {\n const workflow = {\n id: 'test-workflow',\n steps: [\n {\n name: 'test-step',\n step: 'http-request-step',\n url: 'https://example.com',\n method: 'GET'\n }\n ]\n }\n \n const context = {\n trigger: { doc: { id: 'test-doc' } },\n steps: {}\n }\n\n // Mock step task\n const mockStepTask = {\n taskSlug: 'http-request-step',\n handler: vi.fn().mockResolvedValue({\n output: { status: 200, body: 'success' },\n state: 'succeeded'\n })\n }\n\n // Mock the step tasks registry\n const originalStepTasks = (executor as any).stepTasks\n ;(executor as any).stepTasks = [mockStepTask]\n\n const result = await (executor as any).executeWorkflow(workflow, context)\n\n expect(result.status).toBe('completed')\n expect(result.context.steps['test-step']).toBeDefined()\n expect(result.context.steps['test-step'].state).toBe('succeeded')\n expect(mockStepTask.handler).toHaveBeenCalledOnce()\n\n // Restore original step tasks\n ;(executor as any).stepTasks = originalStepTasks\n })\n\n it('should handle step execution failures', async () => {\n const workflow = {\n id: 'test-workflow',\n steps: [\n {\n name: 'failing-step',\n step: 'http-request-step',\n url: 'https://invalid-url',\n method: 'GET'\n }\n ]\n }\n \n const context = {\n trigger: { doc: { id: 'test-doc' } },\n steps: {}\n }\n\n // Mock failing step task\n const mockStepTask = {\n taskSlug: 'http-request-step',\n handler: vi.fn().mockRejectedValue(new Error('Network error'))\n }\n\n const originalStepTasks = (executor as any).stepTasks\n ;(executor as any).stepTasks = [mockStepTask]\n\n const result = await (executor as any).executeWorkflow(workflow, context)\n\n expect(result.status).toBe('failed')\n expect(result.error).toContain('Network error')\n expect(result.context.steps['failing-step']).toBeDefined()\n expect(result.context.steps['failing-step'].state).toBe('failed')\n\n ;(executor as any).stepTasks = originalStepTasks\n })\n\n it('should execute steps with dependencies in correct order', async () => {\n const workflow = {\n id: 'test-workflow',\n steps: [\n {\n name: 'step1',\n step: 'http-request-step',\n url: 'https://example.com/1',\n method: 'GET'\n },\n {\n name: 'step2',\n step: 'http-request-step',\n url: 'https://example.com/2',\n method: 'GET',\n dependencies: ['step1']\n },\n {\n name: 'step3',\n step: 'http-request-step',\n url: 'https://example.com/3',\n method: 'GET',\n dependencies: ['step1']\n }\n ]\n }\n \n const context = {\n trigger: { doc: { id: 'test-doc' } },\n steps: {}\n }\n\n const executionOrder: string[] = []\n const mockStepTask = {\n taskSlug: 'http-request-step',\n handler: vi.fn().mockImplementation(async ({ input }) => {\n executionOrder.push(input.stepName)\n return {\n output: { status: 200, body: 'success' },\n state: 'succeeded'\n }\n })\n }\n\n const originalStepTasks = (executor as any).stepTasks\n ;(executor as any).stepTasks = [mockStepTask]\n\n const result = await (executor as any).executeWorkflow(workflow, context)\n\n expect(result.status).toBe('completed')\n expect(executionOrder[0]).toBe('step1') // First step executed first\n expect(executionOrder.slice(1)).toContain('step2') // Dependent steps after\n expect(executionOrder.slice(1)).toContain('step3')\n\n ;(executor as any).stepTasks = originalStepTasks\n })\n })\n\n describe('findStepTask', () => {\n it('should find registered step task by slug', () => {\n const mockStepTask = {\n taskSlug: 'test-step',\n handler: vi.fn()\n }\n\n const originalStepTasks = (executor as any).stepTasks\n ;(executor as any).stepTasks = [mockStepTask]\n\n const result = (executor as any).findStepTask('test-step')\n expect(result).toBe(mockStepTask)\n\n ;(executor as any).stepTasks = originalStepTasks\n })\n\n it('should return undefined for unknown step type', () => {\n const result = (executor as any).findStepTask('unknown-step')\n expect(result).toBeUndefined()\n })\n })\n\n describe('validateStepConfiguration', () => {\n it('should validate step with required fields', () => {\n const step = {\n name: 'valid-step',\n step: 'http-request-step',\n url: 'https://example.com',\n method: 'GET'\n }\n\n expect(() => {\n (executor as any).validateStepConfiguration(step)\n }).not.toThrow()\n })\n\n it('should throw error for step without name', () => {\n const step = {\n step: 'http-request-step',\n url: 'https://example.com',\n method: 'GET'\n }\n\n expect(() => {\n (executor as any).validateStepConfiguration(step)\n }).toThrow('Step name is required')\n })\n\n it('should throw error for step without type', () => {\n const step = {\n name: 'test-step',\n url: 'https://example.com',\n method: 'GET'\n }\n\n expect(() => {\n (executor as any).validateStepConfiguration(step)\n }).toThrow('Step type is required')\n })\n })\n\n describe('createExecutionContext', () => {\n it('should create context with trigger data', () => {\n const triggerContext = {\n operation: 'create',\n doc: { id: 'test-id', title: 'Test Doc' },\n collection: 'posts'\n }\n\n const result = (executor as any).createExecutionContext(triggerContext)\n\n expect(result.trigger).toEqual(triggerContext)\n expect(result.steps).toEqual({})\n expect(result.metadata).toBeDefined()\n expect(result.metadata.startedAt).toBeDefined()\n })\n\n it('should include metadata in context', () => {\n const triggerContext = { doc: { id: 'test' } }\n const result = (executor as any).createExecutionContext(triggerContext)\n\n expect(result.metadata).toHaveProperty('startedAt')\n expect(result.metadata).toHaveProperty('executionId')\n expect(typeof result.metadata.executionId).toBe('string')\n })\n })\n})"],"names":["describe","it","expect","beforeEach","vi","WorkflowExecutor","mockPayload","mockLogger","executor","info","fn","debug","warn","error","jobs","queue","mockResolvedValue","id","run","undefined","create","update","find","context","trigger","doc","title","steps","result","resolveJSONPathValue","toBe","nested","value","config","url","message","data","webhook","resolveStepInput","toEqual","items","name","step","resolveExecutionOrder","toHaveLength","dependencies","toThrow","status","evaluateCondition","count","obj","safeSerialize","self","toContain","defined","null","parsed","JSON","parse","not","toHaveProperty","workflow","method","mockStepTask","taskSlug","handler","output","body","state","originalStepTasks","stepTasks","executeWorkflow","toBeDefined","toHaveBeenCalledOnce","mockRejectedValue","Error","executionOrder","mockImplementation","input","push","stepName","slice","findStepTask","toBeUndefined","validateStepConfiguration","triggerContext","operation","collection","createExecutionContext","metadata","startedAt","executionId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/test/workflow-executor.test.ts"],"sourcesContent":["import { describe, it, expect, beforeEach, vi } from 'vitest'\nimport { WorkflowExecutor } from '../core/workflow-executor.js'\nimport type { Payload } from 'payload'\n\ndescribe('WorkflowExecutor', () => {\n let mockPayload: Payload\n let mockLogger: any\n let executor: WorkflowExecutor\n\n beforeEach(() => {\n mockLogger = {\n info: vi.fn(),\n debug: vi.fn(),\n warn: vi.fn(),\n error: vi.fn()\n }\n\n mockPayload = {\n jobs: {\n queue: vi.fn().mockResolvedValue({ id: 'job-123' }),\n run: vi.fn().mockResolvedValue(undefined)\n },\n create: vi.fn(),\n update: vi.fn(),\n find: vi.fn()\n } as any\n\n executor = new WorkflowExecutor(mockPayload, mockLogger)\n })\n\n describe('resolveJSONPathValue', () => {\n it('should resolve simple JSONPath expressions', () => {\n const context = {\n trigger: {\n doc: { id: 'test-id', title: 'Test Title' }\n },\n steps: {}\n }\n\n const result = (executor as any).resolveJSONPathValue('$.trigger.doc.id', context)\n expect(result).toBe('test-id')\n })\n\n it('should resolve nested JSONPath expressions', () => {\n const context = {\n trigger: {\n doc: { \n id: 'test-id',\n nested: { value: 'nested-value' }\n }\n },\n steps: {}\n }\n\n const result = (executor as any).resolveJSONPathValue('$.trigger.doc.nested.value', context)\n expect(result).toBe('nested-value')\n })\n\n it('should return original value for non-JSONPath strings', () => {\n const context = { trigger: {}, steps: {} }\n const result = (executor as any).resolveJSONPathValue('plain-string', context)\n expect(result).toBe('plain-string')\n })\n\n it('should handle missing JSONPath gracefully', () => {\n const context = { trigger: {}, steps: {} }\n const result = (executor as any).resolveJSONPathValue('$.trigger.missing.field', context)\n expect(result).toBe('$.trigger.missing.field') // Should return original if resolution fails\n })\n })\n\n describe('resolveStepInput', () => {\n it('should resolve all JSONPath expressions in step config', () => {\n const config = {\n url: '$.trigger.data.url',\n message: 'Static message',\n data: {\n id: '$.trigger.doc.id',\n title: '$.trigger.doc.title'\n }\n }\n\n const context = {\n trigger: {\n doc: { id: 'doc-123', title: 'Doc Title' },\n data: { url: 'https://example.com/webhook' }\n },\n steps: {}\n }\n\n const result = (executor as any).resolveStepInput(config, context)\n \n expect(result).toEqual({\n url: 'https://example.com/webhook',\n message: 'Static message',\n data: {\n id: 'doc-123',\n title: 'Doc Title'\n }\n })\n })\n\n it('should handle arrays with JSONPath expressions', () => {\n const config = {\n items: ['$.trigger.doc.id', 'static-value', '$.trigger.doc.title']\n }\n\n const context = {\n trigger: {\n doc: { id: 'doc-123', title: 'Doc Title' }\n },\n steps: {}\n }\n\n const result = (executor as any).resolveStepInput(config, context)\n \n expect(result).toEqual({\n items: ['doc-123', 'static-value', 'Doc Title']\n })\n })\n })\n\n describe('resolveExecutionOrder', () => {\n it('should handle steps without dependencies', () => {\n const steps = [\n { name: 'step1', step: 'http-request' },\n { name: 'step2', step: 'create-document' },\n { name: 'step3', step: 'http-request' }\n ]\n\n const result = (executor as any).resolveExecutionOrder(steps)\n \n expect(result).toHaveLength(1) // All in one batch\n expect(result[0]).toHaveLength(3) // All steps in first batch\n })\n\n it('should handle steps with dependencies', () => {\n const steps = [\n { name: 'step1', step: 'http-request' },\n { name: 'step2', step: 'create-document', dependencies: ['step1'] },\n { name: 'step3', step: 'http-request', dependencies: ['step2'] }\n ]\n\n const result = (executor as any).resolveExecutionOrder(steps)\n \n expect(result).toHaveLength(3) // Three batches\n expect(result[0]).toHaveLength(1) // step1 first\n expect(result[1]).toHaveLength(1) // step2 second\n expect(result[2]).toHaveLength(1) // step3 third\n })\n\n it('should handle parallel execution with partial dependencies', () => {\n const steps = [\n { name: 'step1', step: 'http-request' },\n { name: 'step2', step: 'create-document' },\n { name: 'step3', step: 'http-request', dependencies: ['step1'] },\n { name: 'step4', step: 'create-document', dependencies: ['step1'] }\n ]\n\n const result = (executor as any).resolveExecutionOrder(steps)\n \n expect(result).toHaveLength(2) // Two batches\n expect(result[0]).toHaveLength(2) // step1 and step2 in parallel\n expect(result[1]).toHaveLength(2) // step3 and step4 in parallel\n })\n\n it('should detect circular dependencies', () => {\n const steps = [\n { name: 'step1', step: 'http-request', dependencies: ['step2'] },\n { name: 'step2', step: 'create-document', dependencies: ['step1'] }\n ]\n\n expect(() => {\n (executor as any).resolveExecutionOrder(steps)\n }).toThrow('Circular dependency detected')\n })\n })\n\n describe('evaluateCondition', () => {\n it('should evaluate simple equality conditions', () => {\n const context = {\n trigger: {\n doc: { status: 'published' }\n },\n steps: {}\n }\n\n const result = (executor as any).evaluateCondition('$.trigger.doc.status == \"published\"', context)\n expect(result).toBe(true)\n })\n\n it('should evaluate inequality conditions', () => {\n const context = {\n trigger: {\n doc: { count: 5 }\n },\n steps: {}\n }\n\n const result = (executor as any).evaluateCondition('$.trigger.doc.count > 3', context)\n expect(result).toBe(true)\n })\n\n it('should return false for invalid conditions', () => {\n const context = { trigger: {}, steps: {} }\n const result = (executor as any).evaluateCondition('invalid condition syntax', context)\n expect(result).toBe(false)\n })\n\n it('should handle missing context gracefully', () => {\n const context = { trigger: {}, steps: {} }\n const result = (executor as any).evaluateCondition('$.trigger.doc.status == \"published\"', context)\n expect(result).toBe(false) // Missing values should fail condition\n })\n })\n\n describe('safeSerialize', () => {\n it('should serialize simple objects', () => {\n const obj = { name: 'test', value: 123 }\n const result = (executor as any).safeSerialize(obj)\n expect(result).toBe('{\"name\":\"test\",\"value\":123}')\n })\n\n it('should handle circular references', () => {\n const obj: any = { name: 'test' }\n obj.self = obj // Create circular reference\n\n const result = (executor as any).safeSerialize(obj)\n expect(result).toContain('\"name\":\"test\"')\n expect(result).toContain('\"self\":\"[Circular]\"')\n })\n\n it('should handle undefined and null values', () => {\n const obj = { \n defined: 'value',\n undefined: undefined,\n null: null\n }\n \n const result = (executor as any).safeSerialize(obj)\n const parsed = JSON.parse(result)\n expect(parsed.defined).toBe('value')\n expect(parsed.null).toBe(null)\n expect(parsed).not.toHaveProperty('undefined') // undefined props are omitted\n })\n })\n\n describe('executeWorkflow', () => {\n it('should execute workflow with single step', async () => {\n const workflow = {\n id: 'test-workflow',\n steps: [\n {\n name: 'test-step',\n step: 'http-request-step',\n url: 'https://example.com',\n method: 'GET'\n }\n ]\n }\n \n const context = {\n trigger: { doc: { id: 'test-doc' } },\n steps: {}\n }\n\n // Mock step task\n const mockStepTask = {\n taskSlug: 'http-request-step',\n handler: vi.fn().mockResolvedValue({\n output: { status: 200, body: 'success' },\n state: 'succeeded'\n })\n }\n\n // Mock the step tasks registry\n const originalStepTasks = (executor as any).stepTasks\n ;(executor as any).stepTasks = [mockStepTask]\n\n const result = await (executor as any).executeWorkflow(workflow, context)\n\n expect(result.status).toBe('completed')\n expect(result.context.steps['test-step']).toBeDefined()\n expect(result.context.steps['test-step'].state).toBe('succeeded')\n expect(mockStepTask.handler).toHaveBeenCalledOnce()\n\n // Restore original step tasks\n ;(executor as any).stepTasks = originalStepTasks\n })\n\n it('should handle step execution failures', async () => {\n const workflow = {\n id: 'test-workflow',\n steps: [\n {\n name: 'failing-step',\n step: 'http-request-step',\n url: 'https://invalid-url',\n method: 'GET'\n }\n ]\n }\n \n const context = {\n trigger: { doc: { id: 'test-doc' } },\n steps: {}\n }\n\n // Mock failing step task\n const mockStepTask = {\n taskSlug: 'http-request-step',\n handler: vi.fn().mockRejectedValue(new Error('Network error'))\n }\n\n const originalStepTasks = (executor as any).stepTasks\n ;(executor as any).stepTasks = [mockStepTask]\n\n const result = await (executor as any).executeWorkflow(workflow, context)\n\n expect(result.status).toBe('failed')\n expect(result.error).toContain('Network error')\n expect(result.context.steps['failing-step']).toBeDefined()\n expect(result.context.steps['failing-step'].state).toBe('failed')\n\n ;(executor as any).stepTasks = originalStepTasks\n })\n\n it('should execute steps with dependencies in correct order', async () => {\n const workflow = {\n id: 'test-workflow',\n steps: [\n {\n name: 'step1',\n step: 'http-request-step',\n url: 'https://example.com/1',\n method: 'GET'\n },\n {\n name: 'step2',\n step: 'http-request-step',\n url: 'https://example.com/2',\n method: 'GET',\n dependencies: ['step1']\n },\n {\n name: 'step3',\n step: 'http-request-step',\n url: 'https://example.com/3',\n method: 'GET',\n dependencies: ['step1']\n }\n ]\n }\n \n const context = {\n trigger: { doc: { id: 'test-doc' } },\n steps: {}\n }\n\n const executionOrder: string[] = []\n const mockStepTask = {\n taskSlug: 'http-request-step',\n handler: vi.fn().mockImplementation(async ({ input }) => {\n executionOrder.push(input.stepName)\n return {\n output: { status: 200, body: 'success' },\n state: 'succeeded'\n }\n })\n }\n\n const originalStepTasks = (executor as any).stepTasks\n ;(executor as any).stepTasks = [mockStepTask]\n\n const result = await (executor as any).executeWorkflow(workflow, context)\n\n expect(result.status).toBe('completed')\n expect(executionOrder[0]).toBe('step1') // First step executed first\n expect(executionOrder.slice(1)).toContain('step2') // Dependent steps after\n expect(executionOrder.slice(1)).toContain('step3')\n\n ;(executor as any).stepTasks = originalStepTasks\n })\n })\n\n describe('findStepTask', () => {\n it('should find registered step task by slug', () => {\n const mockStepTask = {\n taskSlug: 'test-step',\n handler: vi.fn()\n }\n\n const originalStepTasks = (executor as any).stepTasks\n ;(executor as any).stepTasks = [mockStepTask]\n\n const result = (executor as any).findStepTask('test-step')\n expect(result).toBe(mockStepTask)\n\n ;(executor as any).stepTasks = originalStepTasks\n })\n\n it('should return undefined for unknown step type', () => {\n const result = (executor as any).findStepTask('unknown-step')\n expect(result).toBeUndefined()\n })\n })\n\n describe('validateStepConfiguration', () => {\n it('should validate step with required fields', () => {\n const step = {\n name: 'valid-step',\n step: 'http-request-step',\n url: 'https://example.com',\n method: 'GET'\n }\n\n expect(() => {\n (executor as any).validateStepConfiguration(step)\n }).not.toThrow()\n })\n\n it('should throw error for step without name', () => {\n const step = {\n step: 'http-request-step',\n url: 'https://example.com',\n method: 'GET'\n }\n\n expect(() => {\n (executor as any).validateStepConfiguration(step)\n }).toThrow('Step name is required')\n })\n\n it('should throw error for step without type', () => {\n const step = {\n name: 'test-step',\n url: 'https://example.com',\n method: 'GET'\n }\n\n expect(() => {\n (executor as any).validateStepConfiguration(step)\n }).toThrow('Step type is required')\n })\n })\n\n describe('createExecutionContext', () => {\n it('should create context with trigger data', () => {\n const triggerContext = {\n operation: 'create',\n doc: { id: 'test-id', title: 'Test Doc' },\n collection: 'posts'\n }\n\n const result = (executor as any).createExecutionContext(triggerContext)\n\n expect(result.trigger).toEqual(triggerContext)\n expect(result.steps).toEqual({})\n expect(result.metadata).toBeDefined()\n expect(result.metadata.startedAt).toBeDefined()\n })\n\n it('should include metadata in context', () => {\n const triggerContext = { doc: { id: 'test' } }\n const result = (executor as any).createExecutionContext(triggerContext)\n\n expect(result.metadata).toHaveProperty('startedAt')\n expect(result.metadata).toHaveProperty('executionId')\n expect(typeof result.metadata.executionId).toBe('string')\n })\n })\n})"],"names":["describe","it","expect","beforeEach","vi","WorkflowExecutor","mockPayload","mockLogger","executor","info","fn","debug","warn","error","jobs","queue","mockResolvedValue","id","run","undefined","create","update","find","context","trigger","doc","title","steps","result","resolveJSONPathValue","toBe","nested","value","config","url","message","data","resolveStepInput","toEqual","items","name","step","resolveExecutionOrder","toHaveLength","dependencies","toThrow","status","evaluateCondition","count","obj","safeSerialize","self","toContain","defined","null","parsed","JSON","parse","not","toHaveProperty","workflow","method","mockStepTask","taskSlug","handler","output","body","state","originalStepTasks","stepTasks","executeWorkflow","toBeDefined","toHaveBeenCalledOnce","mockRejectedValue","Error","executionOrder","mockImplementation","input","push","stepName","slice","findStepTask","toBeUndefined","validateStepConfiguration","triggerContext","operation","collection","createExecutionContext","metadata","startedAt","executionId"],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export const collectionTrigger = ({ collectionTriggers })=>({
|
|
2
|
+
slug: 'collection-hook',
|
|
3
|
+
parameters: [
|
|
4
|
+
{
|
|
5
|
+
name: 'collectionSlug',
|
|
6
|
+
type: 'select',
|
|
7
|
+
options: Object.keys(collectionTriggers || {})
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
name: 'hook',
|
|
11
|
+
type: 'select',
|
|
12
|
+
options: [
|
|
13
|
+
"afterChange",
|
|
14
|
+
"afterDelete",
|
|
15
|
+
"afterError",
|
|
16
|
+
"afterForgotPassword",
|
|
17
|
+
"afterLogin",
|
|
18
|
+
"afterLogout",
|
|
19
|
+
"afterMe",
|
|
20
|
+
"afterOperation",
|
|
21
|
+
"afterRead",
|
|
22
|
+
"afterRefresh",
|
|
23
|
+
"beforeChange",
|
|
24
|
+
"beforeDelete",
|
|
25
|
+
"beforeLogin",
|
|
26
|
+
"beforeOperation",
|
|
27
|
+
"beforeRead",
|
|
28
|
+
"beforeValidate",
|
|
29
|
+
"me",
|
|
30
|
+
"refresh"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=collection-trigger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/triggers/collection-trigger.ts"],"sourcesContent":["import type {TriggerConfig} from '../plugin/config-types.js'\n\nexport const collectionTrigger: TriggerConfig = ({collectionTriggers}) => ({\n slug: 'collection-hook',\n parameters: [\n {\n name: 'collectionSlug',\n type: 'select',\n options: Object.keys(collectionTriggers || {}),\n },\n {\n name: 'hook',\n type: 'select',\n options: [\n \"afterChange\",\n \"afterDelete\",\n \"afterError\",\n \"afterForgotPassword\",\n \"afterLogin\",\n \"afterLogout\",\n \"afterMe\",\n \"afterOperation\",\n \"afterRead\",\n \"afterRefresh\",\n \"beforeChange\",\n \"beforeDelete\",\n \"beforeLogin\",\n \"beforeOperation\",\n \"beforeRead\",\n \"beforeValidate\",\n \"me\",\n \"refresh\"\n ]\n }\n ]\n})\n"],"names":["collectionTrigger","collectionTriggers","slug","parameters","name","type","options","Object","keys"],"mappings":"AAEA,OAAO,MAAMA,oBAAmC,CAAC,EAACC,kBAAkB,EAAC,GAAM,CAAA;QACzEC,MAAM;QACNC,YAAY;YACV;gBACEC,MAAM;gBACNC,MAAM;gBACNC,SAASC,OAAOC,IAAI,CAACP,sBAAsB,CAAC;YAC9C;YACA;gBACEG,MAAM;gBACNC,MAAM;gBACNC,SAAS;oBACP;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA;iBACD;YACH;SACD;IACH,CAAA,EAAE"}
|