@onlineapps/cookbook-core 2.1.7 → 2.1.9
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/package.json +1 -1
- package/schemas/cookbook.v2.schema.json +136 -519
- package/src/parser/cookbookValidator.js +3 -3
- package/src/parser/cookbookValidatorV2.js +26 -32
- package/src/schema.js +3 -3
- package/schemas/cookbook.schema.json +0 -482
|
@@ -35,11 +35,11 @@ const loadSchemaFile = (filename) => {
|
|
|
35
35
|
if (fs.existsSync(schemaPath)) {
|
|
36
36
|
return JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
|
|
37
37
|
}
|
|
38
|
-
// Fallback to default schema
|
|
39
|
-
return JSON.parse(fs.readFileSync(path.join(__dirname, '../../schemas/cookbook.schema.json'), 'utf-8'));
|
|
38
|
+
// Fallback to default v2 schema
|
|
39
|
+
return JSON.parse(fs.readFileSync(path.join(__dirname, '../../schemas/cookbook.v2.schema.json'), 'utf-8'));
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
const cookbookSchema = loadSchemaFile('cookbook.schema.json');
|
|
42
|
+
const cookbookSchema = loadSchemaFile('cookbook.v2.schema.json');
|
|
43
43
|
const strictSchema = loadSchemaFile('cookbook.strict.schema.json');
|
|
44
44
|
const relaxedSchema = loadSchemaFile('cookbook.relaxed.schema.json');
|
|
45
45
|
|
|
@@ -29,19 +29,18 @@ class CookbookValidationError extends Error {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Load schema
|
|
32
|
+
* Load V2 schema - V1 IS BANNED, only one schema exists
|
|
33
33
|
*/
|
|
34
34
|
function loadSchema(version = '2.0') {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
35
|
+
// V1 is BANNED - reject immediately
|
|
36
|
+
if (version.startsWith('1.')) {
|
|
37
|
+
throw new CookbookValidationError('V1 FORMAT BANNED! Use version 2.x.x');
|
|
38
|
+
}
|
|
39
39
|
|
|
40
|
-
const
|
|
41
|
-
const schemaPath = path.join(__dirname, '../../schemas', filename);
|
|
40
|
+
const schemaPath = path.join(__dirname, '../../schemas/cookbook.v2.schema.json');
|
|
42
41
|
|
|
43
42
|
if (!fs.existsSync(schemaPath)) {
|
|
44
|
-
throw new CookbookValidationError(
|
|
43
|
+
throw new CookbookValidationError('Schema file not found: cookbook.v2.schema.json');
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
return JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
|
|
@@ -249,53 +248,48 @@ function validateSemantics(cookbook, version) {
|
|
|
249
248
|
stepIds.add(stepId);
|
|
250
249
|
}
|
|
251
250
|
|
|
252
|
-
// Check nested steps
|
|
253
|
-
if (step.steps) {
|
|
254
|
-
step.steps.forEach((
|
|
255
|
-
checkStep(nested, `${path}.steps
|
|
251
|
+
// Check nested steps - V2: all nested steps are objects keyed by step_id
|
|
252
|
+
if (step.steps && typeof step.steps === 'object') {
|
|
253
|
+
Object.entries(step.steps).forEach(([nestedKey, nested]) =>
|
|
254
|
+
checkStep(nested, `${path}.steps.${nestedKey}`)
|
|
256
255
|
);
|
|
257
256
|
}
|
|
258
|
-
if (step.body) {
|
|
259
|
-
step.body.forEach((
|
|
260
|
-
checkStep(nested, `${path}.body
|
|
257
|
+
if (step.body && typeof step.body === 'object') {
|
|
258
|
+
Object.entries(step.body).forEach(([nestedKey, nested]) =>
|
|
259
|
+
checkStep(nested, `${path}.body.${nestedKey}`)
|
|
261
260
|
);
|
|
262
261
|
}
|
|
263
|
-
if (step.branches) {
|
|
264
|
-
step.branches.forEach((
|
|
265
|
-
|
|
266
|
-
branch.steps.forEach((nested, jdx) =>
|
|
267
|
-
checkStep(nested, `${path}.branches[${idx}].steps[${jdx}]`)
|
|
268
|
-
);
|
|
269
|
-
}
|
|
262
|
+
if (step.branches && typeof step.branches === 'object') {
|
|
263
|
+
Object.entries(step.branches).forEach(([branchKey, branch]) => {
|
|
264
|
+
checkStep(branch, `${path}.branches.${branchKey}`);
|
|
270
265
|
});
|
|
271
266
|
}
|
|
272
267
|
if (step.cases) {
|
|
273
268
|
Object.keys(step.cases).forEach(caseKey => {
|
|
274
269
|
const caseVal = step.cases[caseKey];
|
|
275
|
-
|
|
276
|
-
caseVal.steps.forEach((nested, idx) =>
|
|
277
|
-
checkStep(nested, `${path}.cases.${caseKey}.steps[${idx}]`)
|
|
278
|
-
);
|
|
279
|
-
}
|
|
270
|
+
checkStep(caseVal, `${path}.cases.${caseKey}`);
|
|
280
271
|
});
|
|
281
272
|
}
|
|
282
273
|
}
|
|
283
274
|
|
|
284
|
-
// Check all steps
|
|
275
|
+
// Check all steps - V2: steps is an OBJECT keyed by step_id, NOT an array
|
|
285
276
|
if (cookbook.steps) {
|
|
286
|
-
cookbook.steps
|
|
287
|
-
|
|
277
|
+
if (Array.isArray(cookbook.steps)) {
|
|
278
|
+
throw new CookbookValidationError('V1 FORMAT BANNED! steps must be an object keyed by step_id, not an array');
|
|
279
|
+
}
|
|
280
|
+
Object.entries(cookbook.steps).forEach(([stepKey, step]) =>
|
|
281
|
+
checkStep(step, `steps.${stepKey}`)
|
|
288
282
|
);
|
|
289
283
|
}
|
|
290
284
|
|
|
291
285
|
// Check dependencies exist
|
|
292
286
|
if (version === '2.0' && cookbook.steps) {
|
|
293
|
-
cookbook.steps.forEach((
|
|
287
|
+
Object.entries(cookbook.steps).forEach(([stepKey, step]) => {
|
|
294
288
|
if (step.depends_on) {
|
|
295
289
|
step.depends_on.forEach(dep => {
|
|
296
290
|
if (!stepIds.has(dep)) {
|
|
297
291
|
throw new CookbookValidationError(
|
|
298
|
-
`Step ${
|
|
292
|
+
`Step '${stepKey}' depends on non-existent step_id '${dep}'`
|
|
299
293
|
);
|
|
300
294
|
}
|
|
301
295
|
});
|
package/src/schema.js
CHANGED
|
@@ -22,15 +22,15 @@ function loadSchema(mode = 'default') {
|
|
|
22
22
|
schemaFile = 'cookbook.relaxed.schema.json';
|
|
23
23
|
break;
|
|
24
24
|
default:
|
|
25
|
-
schemaFile = 'cookbook.schema.json';
|
|
25
|
+
schemaFile = 'cookbook.v2.schema.json';
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const schemaPath = path.join(__dirname, '../schemas', schemaFile);
|
|
29
29
|
|
|
30
30
|
// Check if file exists
|
|
31
31
|
if (!fs.existsSync(schemaPath)) {
|
|
32
|
-
// Fall back to default schema
|
|
33
|
-
const defaultPath = path.join(__dirname, '../schemas/cookbook.schema.json');
|
|
32
|
+
// Fall back to default v2 schema
|
|
33
|
+
const defaultPath = path.join(__dirname, '../schemas/cookbook.v2.schema.json');
|
|
34
34
|
return JSON.parse(fs.readFileSync(defaultPath, 'utf-8'));
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -1,482 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"type": "object",
|
|
4
|
-
"required": ["steps", "version"],
|
|
5
|
-
"additionalProperties": true,
|
|
6
|
-
"properties": {
|
|
7
|
-
"name": {
|
|
8
|
-
"type": "string",
|
|
9
|
-
"minLength": 1
|
|
10
|
-
},
|
|
11
|
-
"version": {
|
|
12
|
-
"type": "string",
|
|
13
|
-
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
14
|
-
"description": "Semantic version of the cookbook schema"
|
|
15
|
-
},
|
|
16
|
-
"description": {
|
|
17
|
-
"type": "string"
|
|
18
|
-
},
|
|
19
|
-
"api_input": {
|
|
20
|
-
"type": "object"
|
|
21
|
-
},
|
|
22
|
-
"global_error_handler": {
|
|
23
|
-
"$ref": "#/definitions/ErrorHandler",
|
|
24
|
-
"description": "Default error handling for all steps"
|
|
25
|
-
},
|
|
26
|
-
"global_retry": {
|
|
27
|
-
"$ref": "#/definitions/Retry",
|
|
28
|
-
"description": "Default retry policy for all steps"
|
|
29
|
-
},
|
|
30
|
-
"global_timeout": {
|
|
31
|
-
"type": "integer",
|
|
32
|
-
"minimum": 1,
|
|
33
|
-
"description": "Maximum execution time for entire workflow in milliseconds"
|
|
34
|
-
},
|
|
35
|
-
"metadata": {
|
|
36
|
-
"type": "object",
|
|
37
|
-
"properties": {
|
|
38
|
-
"tags": {
|
|
39
|
-
"type": "array",
|
|
40
|
-
"items": {
|
|
41
|
-
"type": "string"
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
"priority": {
|
|
45
|
-
"type": "integer",
|
|
46
|
-
"minimum": 0,
|
|
47
|
-
"maximum": 10
|
|
48
|
-
},
|
|
49
|
-
"deprecated": {
|
|
50
|
-
"type": "boolean"
|
|
51
|
-
},
|
|
52
|
-
"deprecationMessage": {
|
|
53
|
-
"type": "string"
|
|
54
|
-
},
|
|
55
|
-
"author": {
|
|
56
|
-
"type": "string"
|
|
57
|
-
},
|
|
58
|
-
"created": {
|
|
59
|
-
"type": "string",
|
|
60
|
-
"format": "date-time"
|
|
61
|
-
},
|
|
62
|
-
"modified": {
|
|
63
|
-
"type": "string",
|
|
64
|
-
"format": "date-time"
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
"additionalProperties": true
|
|
68
|
-
},
|
|
69
|
-
"steps": {
|
|
70
|
-
"type": "array",
|
|
71
|
-
"minItems": 1,
|
|
72
|
-
"items": {
|
|
73
|
-
"$ref": "#/definitions/Step"
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
"definitions": {
|
|
78
|
-
"Step": {
|
|
79
|
-
"type": "object",
|
|
80
|
-
"required": ["id", "type"],
|
|
81
|
-
"oneOf": [
|
|
82
|
-
{ "$ref": "#/definitions/TaskStep" },
|
|
83
|
-
{ "$ref": "#/definitions/ForeachStep" },
|
|
84
|
-
{ "$ref": "#/definitions/ForkJoinStep" },
|
|
85
|
-
{ "$ref": "#/definitions/SwitchStep" },
|
|
86
|
-
{ "$ref": "#/definitions/SubWorkflowStep" },
|
|
87
|
-
{ "$ref": "#/definitions/WaitStep" },
|
|
88
|
-
{ "$ref": "#/definitions/DispatchStep" }
|
|
89
|
-
]
|
|
90
|
-
},
|
|
91
|
-
"TaskStep": {
|
|
92
|
-
"type": "object",
|
|
93
|
-
"required": ["id", "type", "service"],
|
|
94
|
-
"additionalProperties": true,
|
|
95
|
-
"properties": {
|
|
96
|
-
"id": {
|
|
97
|
-
"type": "string",
|
|
98
|
-
"minLength": 1
|
|
99
|
-
},
|
|
100
|
-
"type": {
|
|
101
|
-
"type": "string",
|
|
102
|
-
"const": "task"
|
|
103
|
-
},
|
|
104
|
-
"name": {
|
|
105
|
-
"type": "string",
|
|
106
|
-
"minLength": 1
|
|
107
|
-
},
|
|
108
|
-
"service": {
|
|
109
|
-
"type": "string",
|
|
110
|
-
"minLength": 1
|
|
111
|
-
},
|
|
112
|
-
"action": {
|
|
113
|
-
"type": "string",
|
|
114
|
-
"enum": ["GET", "POST", "PUT", "DELETE", "PATCH"]
|
|
115
|
-
},
|
|
116
|
-
"endpoint": {
|
|
117
|
-
"type": "string",
|
|
118
|
-
"minLength": 1
|
|
119
|
-
},
|
|
120
|
-
"operation": {
|
|
121
|
-
"type": "string",
|
|
122
|
-
"minLength": 1,
|
|
123
|
-
"description": "Operation identifier for the service to execute"
|
|
124
|
-
},
|
|
125
|
-
"input": {
|
|
126
|
-
"type": "object",
|
|
127
|
-
"additionalProperties": true,
|
|
128
|
-
"description": "Optional input mapping - supports all JSON types"
|
|
129
|
-
},
|
|
130
|
-
"output": {
|
|
131
|
-
"type": "object",
|
|
132
|
-
"additionalProperties": true,
|
|
133
|
-
"description": "Optional output mapping - supports all JSON types"
|
|
134
|
-
},
|
|
135
|
-
"depends_on": {
|
|
136
|
-
"type": "array",
|
|
137
|
-
"items": {
|
|
138
|
-
"type": "string",
|
|
139
|
-
"minLength": 1
|
|
140
|
-
}
|
|
141
|
-
},
|
|
142
|
-
"retry": {
|
|
143
|
-
"$ref": "#/definitions/Retry"
|
|
144
|
-
},
|
|
145
|
-
"timeoutMs": {
|
|
146
|
-
"type": "integer",
|
|
147
|
-
"minimum": 1
|
|
148
|
-
},
|
|
149
|
-
"on_error": {
|
|
150
|
-
"$ref": "#/definitions/ErrorHandler"
|
|
151
|
-
},
|
|
152
|
-
"condition": {
|
|
153
|
-
"type": "string",
|
|
154
|
-
"description": "JSONPath expression that must evaluate to true for step to execute"
|
|
155
|
-
}
|
|
156
|
-
},
|
|
157
|
-
"condition": {
|
|
158
|
-
"type": "string",
|
|
159
|
-
"description": "JSONPath expression for conditional execution"
|
|
160
|
-
},
|
|
161
|
-
"timeoutMs": {
|
|
162
|
-
"type": "integer",
|
|
163
|
-
"minimum": 1,
|
|
164
|
-
"description": "Timeout for entire foreach loop"
|
|
165
|
-
},
|
|
166
|
-
"on_error": {
|
|
167
|
-
"$ref": "#/definitions/ErrorHandler"
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
"ForeachStep": {
|
|
171
|
-
"type": "object",
|
|
172
|
-
"required": ["id", "type", "iterator", "body"],
|
|
173
|
-
"additionalProperties": true,
|
|
174
|
-
"properties": {
|
|
175
|
-
"id": {
|
|
176
|
-
"type": "string",
|
|
177
|
-
"minLength": 1
|
|
178
|
-
},
|
|
179
|
-
"type": {
|
|
180
|
-
"type": "string",
|
|
181
|
-
"const": "foreach"
|
|
182
|
-
},
|
|
183
|
-
"name": {
|
|
184
|
-
"type": "string",
|
|
185
|
-
"minLength": 1
|
|
186
|
-
},
|
|
187
|
-
"iterator": {
|
|
188
|
-
"type": "string",
|
|
189
|
-
"minLength": 1
|
|
190
|
-
},
|
|
191
|
-
"body": {
|
|
192
|
-
"type": "array",
|
|
193
|
-
"minItems": 1,
|
|
194
|
-
"items": {
|
|
195
|
-
"$ref": "#/definitions/Step"
|
|
196
|
-
}
|
|
197
|
-
},
|
|
198
|
-
"output": {
|
|
199
|
-
"type": "object",
|
|
200
|
-
"additionalProperties": true,
|
|
201
|
-
"description": "Optional output collection mapping"
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
"ForkJoinStep": {
|
|
206
|
-
"type": "object",
|
|
207
|
-
"required": ["id", "type", "branches", "join"],
|
|
208
|
-
"additionalProperties": true,
|
|
209
|
-
"properties": {
|
|
210
|
-
"id": {
|
|
211
|
-
"type": "string",
|
|
212
|
-
"minLength": 1
|
|
213
|
-
},
|
|
214
|
-
"type": {
|
|
215
|
-
"type": "string",
|
|
216
|
-
"const": "fork_join"
|
|
217
|
-
},
|
|
218
|
-
"name": {
|
|
219
|
-
"type": "string",
|
|
220
|
-
"minLength": 1
|
|
221
|
-
},
|
|
222
|
-
"branches": {
|
|
223
|
-
"type": "array",
|
|
224
|
-
"minItems": 1,
|
|
225
|
-
"items": {
|
|
226
|
-
"$ref": "#/definitions/Step"
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
"join": {
|
|
230
|
-
"type": "object",
|
|
231
|
-
"required": ["strategy"],
|
|
232
|
-
"additionalProperties": false,
|
|
233
|
-
"properties": {
|
|
234
|
-
"strategy": {
|
|
235
|
-
"type": "string",
|
|
236
|
-
"enum": ["merge", "first", "last", "all", "custom"],
|
|
237
|
-
"description": "How to combine branch results"
|
|
238
|
-
},
|
|
239
|
-
"output": {
|
|
240
|
-
"type": "object",
|
|
241
|
-
"additionalProperties": true,
|
|
242
|
-
"description": "Optional output mapping for joined results"
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
},
|
|
247
|
-
"condition": {
|
|
248
|
-
"type": "string",
|
|
249
|
-
"description": "JSONPath expression for conditional execution"
|
|
250
|
-
},
|
|
251
|
-
"timeoutMs": {
|
|
252
|
-
"type": "integer",
|
|
253
|
-
"minimum": 1,
|
|
254
|
-
"description": "Timeout for all branches"
|
|
255
|
-
},
|
|
256
|
-
"on_error": {
|
|
257
|
-
"$ref": "#/definitions/ErrorHandler"
|
|
258
|
-
}
|
|
259
|
-
},
|
|
260
|
-
"SwitchStep": {
|
|
261
|
-
"type": "object",
|
|
262
|
-
"required": ["id", "type", "expression", "cases", "default"],
|
|
263
|
-
"additionalProperties": true,
|
|
264
|
-
"properties": {
|
|
265
|
-
"id": {
|
|
266
|
-
"type": "string",
|
|
267
|
-
"minLength": 1
|
|
268
|
-
},
|
|
269
|
-
"type": {
|
|
270
|
-
"type": "string",
|
|
271
|
-
"const": "switch"
|
|
272
|
-
},
|
|
273
|
-
"name": {
|
|
274
|
-
"type": "string",
|
|
275
|
-
"minLength": 1
|
|
276
|
-
},
|
|
277
|
-
"expression": {
|
|
278
|
-
"type": "string",
|
|
279
|
-
"minLength": 1
|
|
280
|
-
},
|
|
281
|
-
"cases": {
|
|
282
|
-
"type": "object",
|
|
283
|
-
"minProperties": 1,
|
|
284
|
-
"additionalProperties": {
|
|
285
|
-
"$ref": "#/definitions/Step"
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
"default": {
|
|
289
|
-
"$ref": "#/definitions/Step"
|
|
290
|
-
},
|
|
291
|
-
"depends_on": {
|
|
292
|
-
"type": "array",
|
|
293
|
-
"items": {
|
|
294
|
-
"type": "string",
|
|
295
|
-
"minLength": 1
|
|
296
|
-
}
|
|
297
|
-
},
|
|
298
|
-
"condition": {
|
|
299
|
-
"type": "string",
|
|
300
|
-
"description": "JSONPath expression for conditional execution"
|
|
301
|
-
},
|
|
302
|
-
"on_error": {
|
|
303
|
-
"$ref": "#/definitions/ErrorHandler"
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
},
|
|
307
|
-
"SubWorkflowStep": {
|
|
308
|
-
"type": "object",
|
|
309
|
-
"required": ["id", "type", "steps"],
|
|
310
|
-
"additionalProperties": true,
|
|
311
|
-
"properties": {
|
|
312
|
-
"id": {
|
|
313
|
-
"type": "string",
|
|
314
|
-
"minLength": 1
|
|
315
|
-
},
|
|
316
|
-
"type": {
|
|
317
|
-
"type": "string",
|
|
318
|
-
"const": "sub_workflow"
|
|
319
|
-
},
|
|
320
|
-
"name": {
|
|
321
|
-
"type": "string",
|
|
322
|
-
"minLength": 1
|
|
323
|
-
},
|
|
324
|
-
"input": {
|
|
325
|
-
"type": "object",
|
|
326
|
-
"additionalProperties": true,
|
|
327
|
-
"description": "Optional input for sub-workflow - supports all JSON types"
|
|
328
|
-
},
|
|
329
|
-
"steps": {
|
|
330
|
-
"type": "array",
|
|
331
|
-
"minItems": 1,
|
|
332
|
-
"items": {
|
|
333
|
-
"$ref": "#/definitions/Step"
|
|
334
|
-
}
|
|
335
|
-
},
|
|
336
|
-
"condition": {
|
|
337
|
-
"type": "string",
|
|
338
|
-
"description": "JSONPath expression for conditional execution"
|
|
339
|
-
},
|
|
340
|
-
"timeoutMs": {
|
|
341
|
-
"type": "integer",
|
|
342
|
-
"minimum": 1,
|
|
343
|
-
"description": "Timeout for entire sub-workflow"
|
|
344
|
-
},
|
|
345
|
-
"on_error": {
|
|
346
|
-
"$ref": "#/definitions/ErrorHandler"
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
},
|
|
350
|
-
"WaitStep": {
|
|
351
|
-
"type": "object",
|
|
352
|
-
"required": ["id", "type", "durationMs"],
|
|
353
|
-
"additionalProperties": true,
|
|
354
|
-
"properties": {
|
|
355
|
-
"id": {
|
|
356
|
-
"type": "string",
|
|
357
|
-
"minLength": 1
|
|
358
|
-
},
|
|
359
|
-
"type": {
|
|
360
|
-
"type": "string",
|
|
361
|
-
"const": "wait"
|
|
362
|
-
},
|
|
363
|
-
"name": {
|
|
364
|
-
"type": "string",
|
|
365
|
-
"minLength": 1
|
|
366
|
-
},
|
|
367
|
-
"durationMs": {
|
|
368
|
-
"type": "integer",
|
|
369
|
-
"minimum": 0
|
|
370
|
-
},
|
|
371
|
-
"condition": {
|
|
372
|
-
"type": "string",
|
|
373
|
-
"description": "JSONPath expression for conditional execution"
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
},
|
|
377
|
-
"DispatchStep": {
|
|
378
|
-
"type": "object",
|
|
379
|
-
"required": ["id", "type", "method", "target"],
|
|
380
|
-
"additionalProperties": true,
|
|
381
|
-
"properties": {
|
|
382
|
-
"id": {
|
|
383
|
-
"type": "string",
|
|
384
|
-
"minLength": 1
|
|
385
|
-
},
|
|
386
|
-
"type": {
|
|
387
|
-
"type": "string",
|
|
388
|
-
"const": "dispatch"
|
|
389
|
-
},
|
|
390
|
-
"name": {
|
|
391
|
-
"type": "string",
|
|
392
|
-
"minLength": 1
|
|
393
|
-
},
|
|
394
|
-
"method": {
|
|
395
|
-
"type": "string",
|
|
396
|
-
"enum": ["webhook", "http", "grpc", "kafka", "sqs", "custom"],
|
|
397
|
-
"description": "Dispatch method to use"
|
|
398
|
-
},
|
|
399
|
-
"target": {
|
|
400
|
-
"type": "string",
|
|
401
|
-
"format": "uri"
|
|
402
|
-
},
|
|
403
|
-
"input": {
|
|
404
|
-
"type": "object",
|
|
405
|
-
"additionalProperties": true,
|
|
406
|
-
"description": "Optional dispatch payload - supports all JSON types"
|
|
407
|
-
},
|
|
408
|
-
"retry": {
|
|
409
|
-
"$ref": "#/definitions/Retry"
|
|
410
|
-
},
|
|
411
|
-
"condition": {
|
|
412
|
-
"type": "string",
|
|
413
|
-
"description": "JSONPath expression for conditional execution"
|
|
414
|
-
},
|
|
415
|
-
"timeoutMs": {
|
|
416
|
-
"type": "integer",
|
|
417
|
-
"minimum": 1,
|
|
418
|
-
"description": "Timeout for dispatch operation"
|
|
419
|
-
},
|
|
420
|
-
"on_error": {
|
|
421
|
-
"$ref": "#/definitions/ErrorHandler"
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
},
|
|
425
|
-
"Retry": {
|
|
426
|
-
"type": "object",
|
|
427
|
-
"required": ["maxAttempts", "delayMs"],
|
|
428
|
-
"additionalProperties": false,
|
|
429
|
-
"properties": {
|
|
430
|
-
"maxAttempts": {
|
|
431
|
-
"type": "integer",
|
|
432
|
-
"minimum": 1
|
|
433
|
-
},
|
|
434
|
-
"delayMs": {
|
|
435
|
-
"type": "integer",
|
|
436
|
-
"minimum": 0
|
|
437
|
-
},
|
|
438
|
-
"backoffMultiplier": {
|
|
439
|
-
"type": "number",
|
|
440
|
-
"minimum": 1.0,
|
|
441
|
-
"maximum": 5.0,
|
|
442
|
-
"description": "Exponential backoff multiplier"
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
},
|
|
446
|
-
"ErrorHandler": {
|
|
447
|
-
"type": "object",
|
|
448
|
-
"additionalProperties": false,
|
|
449
|
-
"properties": {
|
|
450
|
-
"strategy": {
|
|
451
|
-
"type": "string",
|
|
452
|
-
"enum": ["retry", "fail", "continue", "compensate", "fallback"],
|
|
453
|
-
"description": "How to handle errors"
|
|
454
|
-
},
|
|
455
|
-
"retries": {
|
|
456
|
-
"type": "integer",
|
|
457
|
-
"minimum": 0,
|
|
458
|
-
"maximum": 10,
|
|
459
|
-
"description": "Number of retries before applying strategy"
|
|
460
|
-
},
|
|
461
|
-
"retryDelayMs": {
|
|
462
|
-
"type": "integer",
|
|
463
|
-
"minimum": 0,
|
|
464
|
-
"description": "Delay between retries"
|
|
465
|
-
},
|
|
466
|
-
"fallbackStep": {
|
|
467
|
-
"type": "string",
|
|
468
|
-
"description": "Step ID to execute as fallback"
|
|
469
|
-
},
|
|
470
|
-
"compensationStep": {
|
|
471
|
-
"type": "string",
|
|
472
|
-
"description": "Step ID to execute for compensation/rollback"
|
|
473
|
-
},
|
|
474
|
-
"errorOutput": {
|
|
475
|
-
"type": "string",
|
|
476
|
-
"description": "JSONPath to store error details"
|
|
477
|
-
}
|
|
478
|
-
},
|
|
479
|
-
"required": ["strategy"]
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
}
|