@onlineapps/cookbook-core 2.1.5 → 2.1.7
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 -3
- package/schemas/cookbook.schema.json +211 -74
- package/schemas/cookbook.v2.schema.json +728 -0
- package/src/parser/cookbookValidatorV2.js +32 -26
package/package.json
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlineapps/cookbook-core",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.7",
|
|
4
4
|
"description": "Core cookbook parsing and validation - lightweight foundation for workflow definitions",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"prepublishOnly": "../../../scripts/pre-publish-compatibility-check.sh",
|
|
8
|
-
"postpublish": "../../../scripts/update-manifest-from-npm.sh && ../../../scripts/update-all-services.sh",
|
|
9
7
|
"test": "jest",
|
|
10
8
|
"test:watch": "jest --watch",
|
|
11
9
|
"test:coverage": "jest --coverage",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$comment": "COOKBOOK V2 FORMAT - V1 IS BANNED! steps MUST be object keyed by step_id, NOT array!",
|
|
4
3
|
"type": "object",
|
|
5
4
|
"required": ["steps", "version"],
|
|
6
5
|
"additionalProperties": true,
|
|
@@ -11,8 +10,8 @@
|
|
|
11
10
|
},
|
|
12
11
|
"version": {
|
|
13
12
|
"type": "string",
|
|
14
|
-
"pattern": "
|
|
15
|
-
"description": "Semantic version
|
|
13
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
14
|
+
"description": "Semantic version of the cookbook schema"
|
|
16
15
|
},
|
|
17
16
|
"description": {
|
|
18
17
|
"type": "string"
|
|
@@ -35,25 +34,50 @@
|
|
|
35
34
|
},
|
|
36
35
|
"metadata": {
|
|
37
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
|
+
},
|
|
38
67
|
"additionalProperties": true
|
|
39
68
|
},
|
|
40
69
|
"steps": {
|
|
41
|
-
"type": "
|
|
42
|
-
"
|
|
43
|
-
"
|
|
70
|
+
"type": "array",
|
|
71
|
+
"minItems": 1,
|
|
72
|
+
"items": {
|
|
44
73
|
"$ref": "#/definitions/Step"
|
|
45
|
-
}
|
|
46
|
-
"description": "V2: Object keyed by step_id (NOT array!)"
|
|
47
|
-
},
|
|
48
|
-
"delivery": {
|
|
49
|
-
"type": "object",
|
|
50
|
-
"description": "Delivery configuration for workflow results"
|
|
74
|
+
}
|
|
51
75
|
}
|
|
52
76
|
},
|
|
53
77
|
"definitions": {
|
|
54
78
|
"Step": {
|
|
55
79
|
"type": "object",
|
|
56
|
-
"required": ["
|
|
80
|
+
"required": ["id", "type"],
|
|
57
81
|
"oneOf": [
|
|
58
82
|
{ "$ref": "#/definitions/TaskStep" },
|
|
59
83
|
{ "$ref": "#/definitions/ForeachStep" },
|
|
@@ -66,14 +90,12 @@
|
|
|
66
90
|
},
|
|
67
91
|
"TaskStep": {
|
|
68
92
|
"type": "object",
|
|
69
|
-
"required": ["
|
|
93
|
+
"required": ["id", "type", "service"],
|
|
70
94
|
"additionalProperties": true,
|
|
71
95
|
"properties": {
|
|
72
|
-
"
|
|
96
|
+
"id": {
|
|
73
97
|
"type": "string",
|
|
74
|
-
"minLength": 1
|
|
75
|
-
"pattern": "^[a-zA-Z0-9_]+$",
|
|
76
|
-
"description": "V2: step_id (snake_case, must match object key)"
|
|
98
|
+
"minLength": 1
|
|
77
99
|
},
|
|
78
100
|
"type": {
|
|
79
101
|
"type": "string",
|
|
@@ -87,6 +109,14 @@
|
|
|
87
109
|
"type": "string",
|
|
88
110
|
"minLength": 1
|
|
89
111
|
},
|
|
112
|
+
"action": {
|
|
113
|
+
"type": "string",
|
|
114
|
+
"enum": ["GET", "POST", "PUT", "DELETE", "PATCH"]
|
|
115
|
+
},
|
|
116
|
+
"endpoint": {
|
|
117
|
+
"type": "string",
|
|
118
|
+
"minLength": 1
|
|
119
|
+
},
|
|
90
120
|
"operation": {
|
|
91
121
|
"type": "string",
|
|
92
122
|
"minLength": 1,
|
|
@@ -94,15 +124,20 @@
|
|
|
94
124
|
},
|
|
95
125
|
"input": {
|
|
96
126
|
"type": "object",
|
|
97
|
-
"additionalProperties": true
|
|
127
|
+
"additionalProperties": true,
|
|
128
|
+
"description": "Optional input mapping - supports all JSON types"
|
|
98
129
|
},
|
|
99
130
|
"output": {
|
|
100
131
|
"type": "object",
|
|
101
|
-
"additionalProperties": true
|
|
132
|
+
"additionalProperties": true,
|
|
133
|
+
"description": "Optional output mapping - supports all JSON types"
|
|
102
134
|
},
|
|
103
135
|
"depends_on": {
|
|
104
136
|
"type": "array",
|
|
105
|
-
"items": {
|
|
137
|
+
"items": {
|
|
138
|
+
"type": "string",
|
|
139
|
+
"minLength": 1
|
|
140
|
+
}
|
|
106
141
|
},
|
|
107
142
|
"retry": {
|
|
108
143
|
"$ref": "#/definitions/Retry"
|
|
@@ -115,91 +150,130 @@
|
|
|
115
150
|
"$ref": "#/definitions/ErrorHandler"
|
|
116
151
|
},
|
|
117
152
|
"condition": {
|
|
118
|
-
"type": "string"
|
|
119
|
-
|
|
120
|
-
"expect": {
|
|
121
|
-
"type": "object",
|
|
122
|
-
"description": "Expected output for testing"
|
|
153
|
+
"type": "string",
|
|
154
|
+
"description": "JSONPath expression that must evaluate to true for step to execute"
|
|
123
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"
|
|
124
168
|
}
|
|
125
169
|
},
|
|
126
170
|
"ForeachStep": {
|
|
127
171
|
"type": "object",
|
|
128
|
-
"required": ["
|
|
172
|
+
"required": ["id", "type", "iterator", "body"],
|
|
129
173
|
"additionalProperties": true,
|
|
130
174
|
"properties": {
|
|
131
|
-
"
|
|
175
|
+
"id": {
|
|
132
176
|
"type": "string",
|
|
133
|
-
"minLength": 1
|
|
134
|
-
"pattern": "^[a-zA-Z0-9_]+$"
|
|
177
|
+
"minLength": 1
|
|
135
178
|
},
|
|
136
179
|
"type": {
|
|
137
180
|
"type": "string",
|
|
138
181
|
"const": "foreach"
|
|
139
182
|
},
|
|
183
|
+
"name": {
|
|
184
|
+
"type": "string",
|
|
185
|
+
"minLength": 1
|
|
186
|
+
},
|
|
140
187
|
"iterator": {
|
|
141
188
|
"type": "string",
|
|
142
189
|
"minLength": 1
|
|
143
190
|
},
|
|
144
191
|
"body": {
|
|
145
|
-
"type": "
|
|
146
|
-
"
|
|
147
|
-
"
|
|
192
|
+
"type": "array",
|
|
193
|
+
"minItems": 1,
|
|
194
|
+
"items": {
|
|
148
195
|
"$ref": "#/definitions/Step"
|
|
149
196
|
}
|
|
197
|
+
},
|
|
198
|
+
"output": {
|
|
199
|
+
"type": "object",
|
|
200
|
+
"additionalProperties": true,
|
|
201
|
+
"description": "Optional output collection mapping"
|
|
150
202
|
}
|
|
151
203
|
}
|
|
152
204
|
},
|
|
153
205
|
"ForkJoinStep": {
|
|
154
206
|
"type": "object",
|
|
155
|
-
"required": ["
|
|
207
|
+
"required": ["id", "type", "branches", "join"],
|
|
156
208
|
"additionalProperties": true,
|
|
157
209
|
"properties": {
|
|
158
|
-
"
|
|
210
|
+
"id": {
|
|
159
211
|
"type": "string",
|
|
160
|
-
"minLength": 1
|
|
161
|
-
"pattern": "^[a-zA-Z0-9_]+$"
|
|
212
|
+
"minLength": 1
|
|
162
213
|
},
|
|
163
214
|
"type": {
|
|
164
215
|
"type": "string",
|
|
165
216
|
"const": "fork_join"
|
|
166
217
|
},
|
|
218
|
+
"name": {
|
|
219
|
+
"type": "string",
|
|
220
|
+
"minLength": 1
|
|
221
|
+
},
|
|
167
222
|
"branches": {
|
|
168
|
-
"type": "
|
|
169
|
-
"
|
|
170
|
-
"
|
|
223
|
+
"type": "array",
|
|
224
|
+
"minItems": 1,
|
|
225
|
+
"items": {
|
|
171
226
|
"$ref": "#/definitions/Step"
|
|
172
227
|
}
|
|
173
228
|
},
|
|
174
229
|
"join": {
|
|
175
230
|
"type": "object",
|
|
176
231
|
"required": ["strategy"],
|
|
232
|
+
"additionalProperties": false,
|
|
177
233
|
"properties": {
|
|
178
234
|
"strategy": {
|
|
179
235
|
"type": "string",
|
|
180
|
-
"enum": ["merge", "first", "last", "all", "custom"]
|
|
236
|
+
"enum": ["merge", "first", "last", "all", "custom"],
|
|
237
|
+
"description": "How to combine branch results"
|
|
181
238
|
},
|
|
182
239
|
"output": {
|
|
183
|
-
"type": "object"
|
|
240
|
+
"type": "object",
|
|
241
|
+
"additionalProperties": true,
|
|
242
|
+
"description": "Optional output mapping for joined results"
|
|
184
243
|
}
|
|
185
244
|
}
|
|
186
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"
|
|
187
258
|
}
|
|
188
259
|
},
|
|
189
260
|
"SwitchStep": {
|
|
190
261
|
"type": "object",
|
|
191
|
-
"required": ["
|
|
262
|
+
"required": ["id", "type", "expression", "cases", "default"],
|
|
192
263
|
"additionalProperties": true,
|
|
193
264
|
"properties": {
|
|
194
|
-
"
|
|
265
|
+
"id": {
|
|
195
266
|
"type": "string",
|
|
196
|
-
"minLength": 1
|
|
197
|
-
"pattern": "^[a-zA-Z0-9_]+$"
|
|
267
|
+
"minLength": 1
|
|
198
268
|
},
|
|
199
269
|
"type": {
|
|
200
270
|
"type": "string",
|
|
201
271
|
"const": "switch"
|
|
202
272
|
},
|
|
273
|
+
"name": {
|
|
274
|
+
"type": "string",
|
|
275
|
+
"minLength": 1
|
|
276
|
+
},
|
|
203
277
|
"expression": {
|
|
204
278
|
"type": "string",
|
|
205
279
|
"minLength": 1
|
|
@@ -213,82 +287,138 @@
|
|
|
213
287
|
},
|
|
214
288
|
"default": {
|
|
215
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"
|
|
216
304
|
}
|
|
217
305
|
}
|
|
218
306
|
},
|
|
219
307
|
"SubWorkflowStep": {
|
|
220
308
|
"type": "object",
|
|
221
|
-
"required": ["
|
|
309
|
+
"required": ["id", "type", "steps"],
|
|
222
310
|
"additionalProperties": true,
|
|
223
311
|
"properties": {
|
|
224
|
-
"
|
|
312
|
+
"id": {
|
|
225
313
|
"type": "string",
|
|
226
|
-
"minLength": 1
|
|
227
|
-
"pattern": "^[a-zA-Z0-9_]+$"
|
|
314
|
+
"minLength": 1
|
|
228
315
|
},
|
|
229
316
|
"type": {
|
|
230
317
|
"type": "string",
|
|
231
318
|
"const": "sub_workflow"
|
|
232
319
|
},
|
|
320
|
+
"name": {
|
|
321
|
+
"type": "string",
|
|
322
|
+
"minLength": 1
|
|
323
|
+
},
|
|
233
324
|
"input": {
|
|
234
|
-
"type": "object"
|
|
325
|
+
"type": "object",
|
|
326
|
+
"additionalProperties": true,
|
|
327
|
+
"description": "Optional input for sub-workflow - supports all JSON types"
|
|
235
328
|
},
|
|
236
329
|
"steps": {
|
|
237
|
-
"type": "
|
|
238
|
-
"
|
|
239
|
-
"
|
|
330
|
+
"type": "array",
|
|
331
|
+
"minItems": 1,
|
|
332
|
+
"items": {
|
|
240
333
|
"$ref": "#/definitions/Step"
|
|
241
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"
|
|
242
347
|
}
|
|
243
348
|
}
|
|
244
349
|
},
|
|
245
350
|
"WaitStep": {
|
|
246
351
|
"type": "object",
|
|
247
|
-
"required": ["
|
|
352
|
+
"required": ["id", "type", "durationMs"],
|
|
248
353
|
"additionalProperties": true,
|
|
249
354
|
"properties": {
|
|
250
|
-
"
|
|
355
|
+
"id": {
|
|
251
356
|
"type": "string",
|
|
252
|
-
"minLength": 1
|
|
253
|
-
"pattern": "^[a-zA-Z0-9_]+$"
|
|
357
|
+
"minLength": 1
|
|
254
358
|
},
|
|
255
359
|
"type": {
|
|
256
360
|
"type": "string",
|
|
257
361
|
"const": "wait"
|
|
258
362
|
},
|
|
363
|
+
"name": {
|
|
364
|
+
"type": "string",
|
|
365
|
+
"minLength": 1
|
|
366
|
+
},
|
|
259
367
|
"durationMs": {
|
|
260
368
|
"type": "integer",
|
|
261
369
|
"minimum": 0
|
|
370
|
+
},
|
|
371
|
+
"condition": {
|
|
372
|
+
"type": "string",
|
|
373
|
+
"description": "JSONPath expression for conditional execution"
|
|
262
374
|
}
|
|
263
375
|
}
|
|
264
376
|
},
|
|
265
377
|
"DispatchStep": {
|
|
266
378
|
"type": "object",
|
|
267
|
-
"required": ["
|
|
379
|
+
"required": ["id", "type", "method", "target"],
|
|
268
380
|
"additionalProperties": true,
|
|
269
381
|
"properties": {
|
|
270
|
-
"
|
|
382
|
+
"id": {
|
|
271
383
|
"type": "string",
|
|
272
|
-
"minLength": 1
|
|
273
|
-
"pattern": "^[a-zA-Z0-9_]+$"
|
|
384
|
+
"minLength": 1
|
|
274
385
|
},
|
|
275
386
|
"type": {
|
|
276
387
|
"type": "string",
|
|
277
388
|
"const": "dispatch"
|
|
278
389
|
},
|
|
390
|
+
"name": {
|
|
391
|
+
"type": "string",
|
|
392
|
+
"minLength": 1
|
|
393
|
+
},
|
|
279
394
|
"method": {
|
|
280
395
|
"type": "string",
|
|
281
|
-
"enum": ["webhook", "http", "grpc", "kafka", "sqs", "custom"]
|
|
396
|
+
"enum": ["webhook", "http", "grpc", "kafka", "sqs", "custom"],
|
|
397
|
+
"description": "Dispatch method to use"
|
|
282
398
|
},
|
|
283
399
|
"target": {
|
|
284
400
|
"type": "string",
|
|
285
401
|
"format": "uri"
|
|
286
402
|
},
|
|
287
403
|
"input": {
|
|
288
|
-
"type": "object"
|
|
404
|
+
"type": "object",
|
|
405
|
+
"additionalProperties": true,
|
|
406
|
+
"description": "Optional dispatch payload - supports all JSON types"
|
|
289
407
|
},
|
|
290
408
|
"retry": {
|
|
291
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"
|
|
292
422
|
}
|
|
293
423
|
}
|
|
294
424
|
},
|
|
@@ -308,38 +438,45 @@
|
|
|
308
438
|
"backoffMultiplier": {
|
|
309
439
|
"type": "number",
|
|
310
440
|
"minimum": 1.0,
|
|
311
|
-
"maximum": 5.0
|
|
441
|
+
"maximum": 5.0,
|
|
442
|
+
"description": "Exponential backoff multiplier"
|
|
312
443
|
}
|
|
313
444
|
}
|
|
314
445
|
},
|
|
315
446
|
"ErrorHandler": {
|
|
316
447
|
"type": "object",
|
|
317
|
-
"required": ["strategy"],
|
|
318
448
|
"additionalProperties": false,
|
|
319
449
|
"properties": {
|
|
320
450
|
"strategy": {
|
|
321
451
|
"type": "string",
|
|
322
|
-
"enum": ["retry", "fail", "continue", "compensate", "fallback"]
|
|
452
|
+
"enum": ["retry", "fail", "continue", "compensate", "fallback"],
|
|
453
|
+
"description": "How to handle errors"
|
|
323
454
|
},
|
|
324
455
|
"retries": {
|
|
325
456
|
"type": "integer",
|
|
326
457
|
"minimum": 0,
|
|
327
|
-
"maximum": 10
|
|
458
|
+
"maximum": 10,
|
|
459
|
+
"description": "Number of retries before applying strategy"
|
|
328
460
|
},
|
|
329
461
|
"retryDelayMs": {
|
|
330
462
|
"type": "integer",
|
|
331
|
-
"minimum": 0
|
|
463
|
+
"minimum": 0,
|
|
464
|
+
"description": "Delay between retries"
|
|
332
465
|
},
|
|
333
466
|
"fallbackStep": {
|
|
334
|
-
"type": "string"
|
|
467
|
+
"type": "string",
|
|
468
|
+
"description": "Step ID to execute as fallback"
|
|
335
469
|
},
|
|
336
470
|
"compensationStep": {
|
|
337
|
-
"type": "string"
|
|
471
|
+
"type": "string",
|
|
472
|
+
"description": "Step ID to execute for compensation/rollback"
|
|
338
473
|
},
|
|
339
474
|
"errorOutput": {
|
|
340
|
-
"type": "string"
|
|
475
|
+
"type": "string",
|
|
476
|
+
"description": "JSONPath to store error details"
|
|
341
477
|
}
|
|
342
|
-
}
|
|
478
|
+
},
|
|
479
|
+
"required": ["strategy"]
|
|
343
480
|
}
|
|
344
481
|
}
|
|
345
|
-
}
|
|
482
|
+
}
|
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://onlineapps.com/schemas/cookbook/v2.1.0/cookbook.schema.json",
|
|
4
|
+
"title": "Cookbook Workflow Schema v2.1",
|
|
5
|
+
"description": "Schema for defining workflow orchestration with snake_case convention",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["version", "steps"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"version": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"pattern": "^2\\.\\d+\\.\\d+$",
|
|
13
|
+
"description": "Schema version (must start with 2.x.x)"
|
|
14
|
+
},
|
|
15
|
+
"name": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "Human-readable workflow name"
|
|
18
|
+
},
|
|
19
|
+
"description": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Workflow description"
|
|
22
|
+
},
|
|
23
|
+
"config": {
|
|
24
|
+
"$ref": "#/definitions/Config",
|
|
25
|
+
"description": "Global configuration and defaults"
|
|
26
|
+
},
|
|
27
|
+
"api_input": {
|
|
28
|
+
"type": "object",
|
|
29
|
+
"description": "Expected input parameters for the workflow",
|
|
30
|
+
"additionalProperties": true
|
|
31
|
+
},
|
|
32
|
+
"steps": {
|
|
33
|
+
"type": "array",
|
|
34
|
+
"minItems": 1,
|
|
35
|
+
"items": {
|
|
36
|
+
"$ref": "#/definitions/Step"
|
|
37
|
+
},
|
|
38
|
+
"description": "Array of workflow steps"
|
|
39
|
+
},
|
|
40
|
+
"delivery": {
|
|
41
|
+
"$ref": "#/definitions/DeliveryConfig",
|
|
42
|
+
"description": "Delivery strategy and destinations for workflow output"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"definitions": {
|
|
46
|
+
"Config": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"additionalProperties": false,
|
|
49
|
+
"properties": {
|
|
50
|
+
"default_timeout_ms": {
|
|
51
|
+
"type": "integer",
|
|
52
|
+
"minimum": 1,
|
|
53
|
+
"description": "Default timeout for all steps in milliseconds"
|
|
54
|
+
},
|
|
55
|
+
"default_retry": {
|
|
56
|
+
"$ref": "#/definitions/RetryConfig",
|
|
57
|
+
"description": "Default retry configuration for all steps"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"Step": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"required": ["step_id", "type"],
|
|
64
|
+
"oneOf": [
|
|
65
|
+
{ "$ref": "#/definitions/TaskStep" },
|
|
66
|
+
{ "$ref": "#/definitions/ForeachStep" },
|
|
67
|
+
{ "$ref": "#/definitions/ForkJoinStep" },
|
|
68
|
+
{ "$ref": "#/definitions/SwitchStep" },
|
|
69
|
+
{ "$ref": "#/definitions/SubWorkflowStep" },
|
|
70
|
+
{ "$ref": "#/definitions/WaitStep" },
|
|
71
|
+
{ "$ref": "#/definitions/DispatchStep" }
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
"TaskStep": {
|
|
75
|
+
"type": "object",
|
|
76
|
+
"required": ["step_id", "type", "service", "operation"],
|
|
77
|
+
"additionalProperties": false,
|
|
78
|
+
"properties": {
|
|
79
|
+
"step_id": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"pattern": "^[a-zA-Z0-9_]+$",
|
|
82
|
+
"description": "Unique identifier for the step"
|
|
83
|
+
},
|
|
84
|
+
"type": {
|
|
85
|
+
"const": "task",
|
|
86
|
+
"description": "Step type"
|
|
87
|
+
},
|
|
88
|
+
"name": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"description": "Human-readable step name"
|
|
91
|
+
},
|
|
92
|
+
"service": {
|
|
93
|
+
"type": "string",
|
|
94
|
+
"pattern": "^[a-z0-9-]+$",
|
|
95
|
+
"description": "Target microservice name"
|
|
96
|
+
},
|
|
97
|
+
"operation": {
|
|
98
|
+
"type": "string",
|
|
99
|
+
"description": "Operation ID from OpenAPI spec (required for task steps)"
|
|
100
|
+
},
|
|
101
|
+
"input": {
|
|
102
|
+
"type": "object",
|
|
103
|
+
"additionalProperties": true,
|
|
104
|
+
"description": "Input parameters for the operation"
|
|
105
|
+
},
|
|
106
|
+
"output": {
|
|
107
|
+
"type": "object",
|
|
108
|
+
"additionalProperties": true,
|
|
109
|
+
"description": "Output mapping to workflow context"
|
|
110
|
+
},
|
|
111
|
+
"timeout_ms": {
|
|
112
|
+
"type": "integer",
|
|
113
|
+
"minimum": 1,
|
|
114
|
+
"description": "Timeout in milliseconds (overrides default)"
|
|
115
|
+
},
|
|
116
|
+
"retry": {
|
|
117
|
+
"$ref": "#/definitions/RetryConfig",
|
|
118
|
+
"description": "Retry configuration (overrides default)"
|
|
119
|
+
},
|
|
120
|
+
"on_error": {
|
|
121
|
+
"$ref": "#/definitions/ErrorHandler",
|
|
122
|
+
"description": "Error handling configuration"
|
|
123
|
+
},
|
|
124
|
+
"compensate": {
|
|
125
|
+
"$ref": "#/definitions/CompensationStep",
|
|
126
|
+
"description": "Rollback/compensation configuration"
|
|
127
|
+
},
|
|
128
|
+
"depends_on": {
|
|
129
|
+
"type": "array",
|
|
130
|
+
"items": {
|
|
131
|
+
"type": "string"
|
|
132
|
+
},
|
|
133
|
+
"description": "Array of step_ids this step depends on"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"ForeachStep": {
|
|
138
|
+
"type": "object",
|
|
139
|
+
"required": ["step_id", "type", "iterator", "steps"],
|
|
140
|
+
"additionalProperties": false,
|
|
141
|
+
"properties": {
|
|
142
|
+
"step_id": {
|
|
143
|
+
"type": "string",
|
|
144
|
+
"pattern": "^[a-zA-Z0-9_]+$"
|
|
145
|
+
},
|
|
146
|
+
"type": {
|
|
147
|
+
"const": "foreach"
|
|
148
|
+
},
|
|
149
|
+
"name": {
|
|
150
|
+
"type": "string"
|
|
151
|
+
},
|
|
152
|
+
"iterator": {
|
|
153
|
+
"type": "string",
|
|
154
|
+
"pattern": "^\\$\\{.+\\}$",
|
|
155
|
+
"description": "Reference to array to iterate over"
|
|
156
|
+
},
|
|
157
|
+
"steps": {
|
|
158
|
+
"type": "array",
|
|
159
|
+
"minItems": 1,
|
|
160
|
+
"items": {
|
|
161
|
+
"$ref": "#/definitions/Step"
|
|
162
|
+
},
|
|
163
|
+
"description": "Steps to execute for each item"
|
|
164
|
+
},
|
|
165
|
+
"output": {
|
|
166
|
+
"type": "object",
|
|
167
|
+
"additionalProperties": true,
|
|
168
|
+
"description": "How to aggregate results"
|
|
169
|
+
},
|
|
170
|
+
"max_concurrency": {
|
|
171
|
+
"type": "integer",
|
|
172
|
+
"minimum": 1,
|
|
173
|
+
"description": "Maximum parallel executions"
|
|
174
|
+
},
|
|
175
|
+
"on_error": {
|
|
176
|
+
"$ref": "#/definitions/ErrorHandler"
|
|
177
|
+
},
|
|
178
|
+
"depends_on": {
|
|
179
|
+
"type": "array",
|
|
180
|
+
"items": {
|
|
181
|
+
"type": "string"
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"ForkJoinStep": {
|
|
187
|
+
"type": "object",
|
|
188
|
+
"required": ["step_id", "type", "branches", "join"],
|
|
189
|
+
"additionalProperties": false,
|
|
190
|
+
"properties": {
|
|
191
|
+
"step_id": {
|
|
192
|
+
"type": "string",
|
|
193
|
+
"pattern": "^[a-zA-Z0-9_]+$"
|
|
194
|
+
},
|
|
195
|
+
"type": {
|
|
196
|
+
"const": "fork_join"
|
|
197
|
+
},
|
|
198
|
+
"name": {
|
|
199
|
+
"type": "string"
|
|
200
|
+
},
|
|
201
|
+
"branches": {
|
|
202
|
+
"type": "array",
|
|
203
|
+
"minItems": 2,
|
|
204
|
+
"items": {
|
|
205
|
+
"type": "object",
|
|
206
|
+
"required": ["branch_id", "steps"],
|
|
207
|
+
"properties": {
|
|
208
|
+
"branch_id": {
|
|
209
|
+
"type": "string"
|
|
210
|
+
},
|
|
211
|
+
"steps": {
|
|
212
|
+
"type": "array",
|
|
213
|
+
"minItems": 1,
|
|
214
|
+
"items": {
|
|
215
|
+
"$ref": "#/definitions/Step"
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
"description": "Parallel branches to execute"
|
|
221
|
+
},
|
|
222
|
+
"join": {
|
|
223
|
+
"type": "object",
|
|
224
|
+
"required": ["strategy"],
|
|
225
|
+
"properties": {
|
|
226
|
+
"strategy": {
|
|
227
|
+
"enum": ["all", "first", "race", "merge"],
|
|
228
|
+
"description": "How to join branch results"
|
|
229
|
+
},
|
|
230
|
+
"timeout_ms": {
|
|
231
|
+
"type": "integer",
|
|
232
|
+
"minimum": 1
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"output": {
|
|
237
|
+
"type": "object",
|
|
238
|
+
"additionalProperties": true
|
|
239
|
+
},
|
|
240
|
+
"on_error": {
|
|
241
|
+
"$ref": "#/definitions/ErrorHandler"
|
|
242
|
+
},
|
|
243
|
+
"depends_on": {
|
|
244
|
+
"type": "array",
|
|
245
|
+
"items": {
|
|
246
|
+
"type": "string"
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
"SwitchStep": {
|
|
252
|
+
"type": "object",
|
|
253
|
+
"required": ["step_id", "type", "expression", "cases", "default"],
|
|
254
|
+
"additionalProperties": false,
|
|
255
|
+
"properties": {
|
|
256
|
+
"step_id": {
|
|
257
|
+
"type": "string",
|
|
258
|
+
"pattern": "^[a-zA-Z0-9_]+$"
|
|
259
|
+
},
|
|
260
|
+
"type": {
|
|
261
|
+
"const": "switch"
|
|
262
|
+
},
|
|
263
|
+
"name": {
|
|
264
|
+
"type": "string"
|
|
265
|
+
},
|
|
266
|
+
"expression": {
|
|
267
|
+
"type": "string",
|
|
268
|
+
"pattern": "^\\$\\{.+\\}$",
|
|
269
|
+
"description": "Expression to evaluate for switch"
|
|
270
|
+
},
|
|
271
|
+
"cases": {
|
|
272
|
+
"type": "object",
|
|
273
|
+
"additionalProperties": {
|
|
274
|
+
"type": "object",
|
|
275
|
+
"required": ["steps"],
|
|
276
|
+
"properties": {
|
|
277
|
+
"steps": {
|
|
278
|
+
"type": "array",
|
|
279
|
+
"minItems": 1,
|
|
280
|
+
"items": {
|
|
281
|
+
"$ref": "#/definitions/Step"
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
"description": "Case branches"
|
|
287
|
+
},
|
|
288
|
+
"default": {
|
|
289
|
+
"type": "object",
|
|
290
|
+
"required": ["steps"],
|
|
291
|
+
"properties": {
|
|
292
|
+
"steps": {
|
|
293
|
+
"type": "array",
|
|
294
|
+
"minItems": 1,
|
|
295
|
+
"items": {
|
|
296
|
+
"$ref": "#/definitions/Step"
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
"description": "Default branch (required)"
|
|
301
|
+
},
|
|
302
|
+
"on_error": {
|
|
303
|
+
"$ref": "#/definitions/ErrorHandler"
|
|
304
|
+
},
|
|
305
|
+
"depends_on": {
|
|
306
|
+
"type": "array",
|
|
307
|
+
"items": {
|
|
308
|
+
"type": "string"
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
"SubWorkflowStep": {
|
|
314
|
+
"type": "object",
|
|
315
|
+
"required": ["step_id", "type", "workflow_id"],
|
|
316
|
+
"additionalProperties": false,
|
|
317
|
+
"properties": {
|
|
318
|
+
"step_id": {
|
|
319
|
+
"type": "string",
|
|
320
|
+
"pattern": "^[a-zA-Z0-9_]+$"
|
|
321
|
+
},
|
|
322
|
+
"type": {
|
|
323
|
+
"const": "sub_workflow"
|
|
324
|
+
},
|
|
325
|
+
"name": {
|
|
326
|
+
"type": "string"
|
|
327
|
+
},
|
|
328
|
+
"workflow_id": {
|
|
329
|
+
"type": "string",
|
|
330
|
+
"description": "ID of workflow to execute"
|
|
331
|
+
},
|
|
332
|
+
"parameters": {
|
|
333
|
+
"type": "object",
|
|
334
|
+
"additionalProperties": true,
|
|
335
|
+
"description": "Parameters to pass to sub-workflow"
|
|
336
|
+
},
|
|
337
|
+
"output": {
|
|
338
|
+
"type": "object",
|
|
339
|
+
"additionalProperties": true
|
|
340
|
+
},
|
|
341
|
+
"timeout_ms": {
|
|
342
|
+
"type": "integer",
|
|
343
|
+
"minimum": 1
|
|
344
|
+
},
|
|
345
|
+
"on_error": {
|
|
346
|
+
"$ref": "#/definitions/ErrorHandler"
|
|
347
|
+
},
|
|
348
|
+
"depends_on": {
|
|
349
|
+
"type": "array",
|
|
350
|
+
"items": {
|
|
351
|
+
"type": "string"
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
"WaitStep": {
|
|
357
|
+
"type": "object",
|
|
358
|
+
"required": ["step_id", "type", "duration_ms"],
|
|
359
|
+
"additionalProperties": false,
|
|
360
|
+
"properties": {
|
|
361
|
+
"step_id": {
|
|
362
|
+
"type": "string",
|
|
363
|
+
"pattern": "^[a-zA-Z0-9_]+$"
|
|
364
|
+
},
|
|
365
|
+
"type": {
|
|
366
|
+
"const": "wait"
|
|
367
|
+
},
|
|
368
|
+
"name": {
|
|
369
|
+
"type": "string"
|
|
370
|
+
},
|
|
371
|
+
"duration_ms": {
|
|
372
|
+
"type": "integer",
|
|
373
|
+
"minimum": 1,
|
|
374
|
+
"description": "Wait duration in milliseconds"
|
|
375
|
+
},
|
|
376
|
+
"message": {
|
|
377
|
+
"type": "string",
|
|
378
|
+
"description": "Optional message explaining the wait"
|
|
379
|
+
},
|
|
380
|
+
"depends_on": {
|
|
381
|
+
"type": "array",
|
|
382
|
+
"items": {
|
|
383
|
+
"type": "string"
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
"DispatchStep": {
|
|
389
|
+
"type": "object",
|
|
390
|
+
"required": ["step_id", "type", "method", "target"],
|
|
391
|
+
"additionalProperties": false,
|
|
392
|
+
"properties": {
|
|
393
|
+
"step_id": {
|
|
394
|
+
"type": "string",
|
|
395
|
+
"pattern": "^[a-zA-Z0-9_]+$"
|
|
396
|
+
},
|
|
397
|
+
"type": {
|
|
398
|
+
"const": "dispatch"
|
|
399
|
+
},
|
|
400
|
+
"name": {
|
|
401
|
+
"type": "string"
|
|
402
|
+
},
|
|
403
|
+
"method": {
|
|
404
|
+
"enum": ["webhook", "http", "grpc", "kafka", "sqs"],
|
|
405
|
+
"description": "Dispatch method"
|
|
406
|
+
},
|
|
407
|
+
"target": {
|
|
408
|
+
"type": "string",
|
|
409
|
+
"description": "Target URL or address"
|
|
410
|
+
},
|
|
411
|
+
"input": {
|
|
412
|
+
"type": "object",
|
|
413
|
+
"additionalProperties": true
|
|
414
|
+
},
|
|
415
|
+
"headers": {
|
|
416
|
+
"type": "object",
|
|
417
|
+
"additionalProperties": {
|
|
418
|
+
"type": "string"
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
"timeout_ms": {
|
|
422
|
+
"type": "integer",
|
|
423
|
+
"minimum": 1
|
|
424
|
+
},
|
|
425
|
+
"retry": {
|
|
426
|
+
"$ref": "#/definitions/RetryConfig"
|
|
427
|
+
},
|
|
428
|
+
"on_error": {
|
|
429
|
+
"$ref": "#/definitions/ErrorHandler"
|
|
430
|
+
},
|
|
431
|
+
"depends_on": {
|
|
432
|
+
"type": "array",
|
|
433
|
+
"items": {
|
|
434
|
+
"type": "string"
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
},
|
|
439
|
+
"RetryConfig": {
|
|
440
|
+
"type": "object",
|
|
441
|
+
"additionalProperties": false,
|
|
442
|
+
"properties": {
|
|
443
|
+
"max_attempts": {
|
|
444
|
+
"type": "integer",
|
|
445
|
+
"minimum": 1,
|
|
446
|
+
"description": "Maximum retry attempts"
|
|
447
|
+
},
|
|
448
|
+
"delay_ms": {
|
|
449
|
+
"type": "integer",
|
|
450
|
+
"minimum": 0,
|
|
451
|
+
"description": "Delay between retries in milliseconds"
|
|
452
|
+
},
|
|
453
|
+
"backoff": {
|
|
454
|
+
"enum": ["linear", "exponential"],
|
|
455
|
+
"description": "Backoff strategy"
|
|
456
|
+
},
|
|
457
|
+
"max_delay_ms": {
|
|
458
|
+
"type": "integer",
|
|
459
|
+
"minimum": 1,
|
|
460
|
+
"description": "Maximum delay for exponential backoff"
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
"ErrorHandler": {
|
|
465
|
+
"type": "object",
|
|
466
|
+
"additionalProperties": false,
|
|
467
|
+
"properties": {
|
|
468
|
+
"strategy": {
|
|
469
|
+
"enum": ["retry", "fail", "continue", "compensate"],
|
|
470
|
+
"description": "Error handling strategy"
|
|
471
|
+
},
|
|
472
|
+
"retry": {
|
|
473
|
+
"$ref": "#/definitions/RetryConfig"
|
|
474
|
+
},
|
|
475
|
+
"catch": {
|
|
476
|
+
"type": "array",
|
|
477
|
+
"items": {
|
|
478
|
+
"type": "object",
|
|
479
|
+
"required": ["error_type", "handler_step"],
|
|
480
|
+
"properties": {
|
|
481
|
+
"error_type": {
|
|
482
|
+
"type": "string",
|
|
483
|
+
"description": "Type of error to catch"
|
|
484
|
+
},
|
|
485
|
+
"handler_step": {
|
|
486
|
+
"type": "string",
|
|
487
|
+
"description": "Step to execute on this error"
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
"description": "Specific error handlers"
|
|
492
|
+
},
|
|
493
|
+
"finally": {
|
|
494
|
+
"type": "string",
|
|
495
|
+
"description": "Step to always execute"
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
},
|
|
499
|
+
"CompensationStep": {
|
|
500
|
+
"type": "object",
|
|
501
|
+
"required": ["step_id", "service", "operation"],
|
|
502
|
+
"additionalProperties": false,
|
|
503
|
+
"properties": {
|
|
504
|
+
"step_id": {
|
|
505
|
+
"type": "string",
|
|
506
|
+
"pattern": "^[a-zA-Z0-9_]+$",
|
|
507
|
+
"description": "ID for compensation step"
|
|
508
|
+
},
|
|
509
|
+
"service": {
|
|
510
|
+
"type": "string",
|
|
511
|
+
"pattern": "^[a-z0-9-]+$"
|
|
512
|
+
},
|
|
513
|
+
"operation": {
|
|
514
|
+
"type": "string"
|
|
515
|
+
},
|
|
516
|
+
"input": {
|
|
517
|
+
"type": "object",
|
|
518
|
+
"additionalProperties": true
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
},
|
|
522
|
+
"DeliveryConfig": {
|
|
523
|
+
"type": "object",
|
|
524
|
+
"required": ["handler"],
|
|
525
|
+
"additionalProperties": false,
|
|
526
|
+
"properties": {
|
|
527
|
+
"handler": {
|
|
528
|
+
"enum": ["dispatcher", "service_step", "none"],
|
|
529
|
+
"description": "Delivery handler selection"
|
|
530
|
+
},
|
|
531
|
+
"allow_skip": {
|
|
532
|
+
"type": "boolean",
|
|
533
|
+
"default": false,
|
|
534
|
+
"description": "Allow dispatcher to skip delivery without failing workflow"
|
|
535
|
+
},
|
|
536
|
+
"delivery_step": {
|
|
537
|
+
"type": "string",
|
|
538
|
+
"pattern": "^[a-zA-Z0-9_]+$",
|
|
539
|
+
"description": "Step ID that performs delivery when handler=service_step"
|
|
540
|
+
},
|
|
541
|
+
"destinations": {
|
|
542
|
+
"type": "array",
|
|
543
|
+
"items": {
|
|
544
|
+
"$ref": "#/definitions/DeliveryDestination"
|
|
545
|
+
},
|
|
546
|
+
"default": []
|
|
547
|
+
},
|
|
548
|
+
"output": {
|
|
549
|
+
"$ref": "#/definitions/DeliveryOutput"
|
|
550
|
+
}
|
|
551
|
+
},
|
|
552
|
+
"allOf": [
|
|
553
|
+
{
|
|
554
|
+
"if": {
|
|
555
|
+
"properties": {
|
|
556
|
+
"handler": { "const": "dispatcher" }
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
"then": {
|
|
560
|
+
"required": ["destinations", "output"],
|
|
561
|
+
"properties": {
|
|
562
|
+
"destinations": {
|
|
563
|
+
"minItems": 1
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
"if": {
|
|
570
|
+
"properties": {
|
|
571
|
+
"handler": { "const": "service_step" }
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
"then": {
|
|
575
|
+
"required": ["delivery_step", "output"]
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
]
|
|
579
|
+
},
|
|
580
|
+
"DeliveryDestination": {
|
|
581
|
+
"type": "object",
|
|
582
|
+
"required": ["type"],
|
|
583
|
+
"properties": {
|
|
584
|
+
"type": {
|
|
585
|
+
"enum": ["webhook", "websocket", "public_url"],
|
|
586
|
+
"description": "Delivery channel type"
|
|
587
|
+
},
|
|
588
|
+
"name": {
|
|
589
|
+
"type": "string",
|
|
590
|
+
"pattern": "^[a-zA-Z0-9._-]+$",
|
|
591
|
+
"description": "Optional identifier for monitoring"
|
|
592
|
+
},
|
|
593
|
+
"enabled": {
|
|
594
|
+
"type": "boolean",
|
|
595
|
+
"default": true
|
|
596
|
+
},
|
|
597
|
+
"retry": {
|
|
598
|
+
"$ref": "#/definitions/RetryConfig"
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
"allOf": [
|
|
602
|
+
{
|
|
603
|
+
"if": {
|
|
604
|
+
"properties": {
|
|
605
|
+
"type": { "const": "webhook" }
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
"then": {
|
|
609
|
+
"$ref": "#/definitions/DeliveryWebhookOptions"
|
|
610
|
+
}
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
"if": {
|
|
614
|
+
"properties": {
|
|
615
|
+
"type": { "const": "websocket" }
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
"then": {
|
|
619
|
+
"$ref": "#/definitions/DeliveryWebsocketOptions"
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
"if": {
|
|
624
|
+
"properties": {
|
|
625
|
+
"type": { "const": "public_url" }
|
|
626
|
+
}
|
|
627
|
+
},
|
|
628
|
+
"then": {
|
|
629
|
+
"$ref": "#/definitions/DeliveryPublicUrlOptions"
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
]
|
|
633
|
+
},
|
|
634
|
+
"DeliveryWebhookOptions": {
|
|
635
|
+
"type": "object",
|
|
636
|
+
"required": ["url", "method"],
|
|
637
|
+
"properties": {
|
|
638
|
+
"url": {
|
|
639
|
+
"type": "string",
|
|
640
|
+
"format": "uri",
|
|
641
|
+
"description": "Target webhook URL"
|
|
642
|
+
},
|
|
643
|
+
"method": {
|
|
644
|
+
"type": "string",
|
|
645
|
+
"enum": ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
|
646
|
+
},
|
|
647
|
+
"headers": {
|
|
648
|
+
"type": "object",
|
|
649
|
+
"additionalProperties": {
|
|
650
|
+
"type": "string"
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
"body_template": {
|
|
654
|
+
"type": ["object", "array"],
|
|
655
|
+
"description": "Optional custom payload template"
|
|
656
|
+
},
|
|
657
|
+
"timeout_ms": {
|
|
658
|
+
"type": "integer",
|
|
659
|
+
"minimum": 100,
|
|
660
|
+
"description": "Request timeout"
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
},
|
|
664
|
+
"DeliveryWebsocketOptions": {
|
|
665
|
+
"type": "object",
|
|
666
|
+
"properties": {
|
|
667
|
+
"client_id": {
|
|
668
|
+
"type": "string",
|
|
669
|
+
"description": "Client session identifier"
|
|
670
|
+
},
|
|
671
|
+
"tenant_id": {
|
|
672
|
+
"type": "string",
|
|
673
|
+
"description": "Tenant/topic identifier"
|
|
674
|
+
},
|
|
675
|
+
"events": {
|
|
676
|
+
"type": "array",
|
|
677
|
+
"items": {
|
|
678
|
+
"type": "string"
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
},
|
|
682
|
+
"anyOf": [
|
|
683
|
+
{ "required": ["client_id"] },
|
|
684
|
+
{ "required": ["tenant_id"] }
|
|
685
|
+
]
|
|
686
|
+
},
|
|
687
|
+
"DeliveryPublicUrlOptions": {
|
|
688
|
+
"type": "object",
|
|
689
|
+
"required": ["path"],
|
|
690
|
+
"properties": {
|
|
691
|
+
"path": {
|
|
692
|
+
"type": "string",
|
|
693
|
+
"pattern": "^[a-zA-Z0-9._\\-/\\${}]+$",
|
|
694
|
+
"description": "Storage key / relative path"
|
|
695
|
+
},
|
|
696
|
+
"ttl_seconds": {
|
|
697
|
+
"type": "integer",
|
|
698
|
+
"minimum": 60,
|
|
699
|
+
"description": "Time to live for generated URL"
|
|
700
|
+
},
|
|
701
|
+
"access": {
|
|
702
|
+
"type": "string",
|
|
703
|
+
"enum": ["public", "signed"],
|
|
704
|
+
"default": "signed"
|
|
705
|
+
},
|
|
706
|
+
"max_downloads": {
|
|
707
|
+
"type": "integer",
|
|
708
|
+
"minimum": 1
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
"DeliveryOutput": {
|
|
713
|
+
"type": "object",
|
|
714
|
+
"propertyNames": {
|
|
715
|
+
"pattern": "^[a-zA-Z0-9_]+$"
|
|
716
|
+
},
|
|
717
|
+
"additionalProperties": {
|
|
718
|
+
"type": [
|
|
719
|
+
"string",
|
|
720
|
+
"number",
|
|
721
|
+
"boolean",
|
|
722
|
+
"object",
|
|
723
|
+
"array"
|
|
724
|
+
]
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
@@ -29,18 +29,19 @@ class CookbookValidationError extends Error {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Load
|
|
32
|
+
* Load schema file with version detection
|
|
33
33
|
*/
|
|
34
34
|
function loadSchema(version = '2.0') {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
35
|
+
const schemaMap = {
|
|
36
|
+
'1.0': 'cookbook.schema.json', // Legacy v1.0 schema
|
|
37
|
+
'2.0': 'cookbook.v2.schema.json' // New v2.0 schema with snake_case
|
|
38
|
+
};
|
|
39
39
|
|
|
40
|
-
const
|
|
40
|
+
const filename = schemaMap[version.split('.')[0] + '.0'] || schemaMap['2.0'];
|
|
41
|
+
const schemaPath = path.join(__dirname, '../../schemas', filename);
|
|
41
42
|
|
|
42
43
|
if (!fs.existsSync(schemaPath)) {
|
|
43
|
-
throw new CookbookValidationError(
|
|
44
|
+
throw new CookbookValidationError(`Schema file not found: ${filename}`);
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
return JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
|
|
@@ -248,48 +249,53 @@ function validateSemantics(cookbook, version) {
|
|
|
248
249
|
stepIds.add(stepId);
|
|
249
250
|
}
|
|
250
251
|
|
|
251
|
-
// Check nested steps
|
|
252
|
-
if (step.steps
|
|
253
|
-
|
|
254
|
-
checkStep(nested, `${path}.steps
|
|
252
|
+
// Check nested steps
|
|
253
|
+
if (step.steps) {
|
|
254
|
+
step.steps.forEach((nested, idx) =>
|
|
255
|
+
checkStep(nested, `${path}.steps[${idx}]`)
|
|
255
256
|
);
|
|
256
257
|
}
|
|
257
|
-
if (step.body
|
|
258
|
-
|
|
259
|
-
checkStep(nested, `${path}.body
|
|
258
|
+
if (step.body) {
|
|
259
|
+
step.body.forEach((nested, idx) =>
|
|
260
|
+
checkStep(nested, `${path}.body[${idx}]`)
|
|
260
261
|
);
|
|
261
262
|
}
|
|
262
|
-
if (step.branches
|
|
263
|
-
|
|
264
|
-
|
|
263
|
+
if (step.branches) {
|
|
264
|
+
step.branches.forEach((branch, idx) => {
|
|
265
|
+
if (branch.steps) {
|
|
266
|
+
branch.steps.forEach((nested, jdx) =>
|
|
267
|
+
checkStep(nested, `${path}.branches[${idx}].steps[${jdx}]`)
|
|
268
|
+
);
|
|
269
|
+
}
|
|
265
270
|
});
|
|
266
271
|
}
|
|
267
272
|
if (step.cases) {
|
|
268
273
|
Object.keys(step.cases).forEach(caseKey => {
|
|
269
274
|
const caseVal = step.cases[caseKey];
|
|
270
|
-
|
|
275
|
+
if (caseVal.steps) {
|
|
276
|
+
caseVal.steps.forEach((nested, idx) =>
|
|
277
|
+
checkStep(nested, `${path}.cases.${caseKey}.steps[${idx}]`)
|
|
278
|
+
);
|
|
279
|
+
}
|
|
271
280
|
});
|
|
272
281
|
}
|
|
273
282
|
}
|
|
274
283
|
|
|
275
|
-
// Check all steps
|
|
284
|
+
// Check all steps
|
|
276
285
|
if (cookbook.steps) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
Object.entries(cookbook.steps).forEach(([stepKey, step]) =>
|
|
281
|
-
checkStep(step, `steps.${stepKey}`)
|
|
286
|
+
cookbook.steps.forEach((step, idx) =>
|
|
287
|
+
checkStep(step, `steps[${idx}]`)
|
|
282
288
|
);
|
|
283
289
|
}
|
|
284
290
|
|
|
285
291
|
// Check dependencies exist
|
|
286
292
|
if (version === '2.0' && cookbook.steps) {
|
|
287
|
-
|
|
293
|
+
cookbook.steps.forEach((step, idx) => {
|
|
288
294
|
if (step.depends_on) {
|
|
289
295
|
step.depends_on.forEach(dep => {
|
|
290
296
|
if (!stepIds.has(dep)) {
|
|
291
297
|
throw new CookbookValidationError(
|
|
292
|
-
`Step
|
|
298
|
+
`Step ${idx} depends on non-existent step_id '${dep}'`
|
|
293
299
|
);
|
|
294
300
|
}
|
|
295
301
|
});
|