@particle-academy/fancy-conformance 0.22.1 → 0.24.0
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.
|
@@ -0,0 +1,1334 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../schema/case-table.schema.json",
|
|
3
|
+
"suite": "flow/run-diagnostics",
|
|
4
|
+
"cases": [
|
|
5
|
+
{
|
|
6
|
+
"id": "0001-branch-routes-on-an-unresolved-path",
|
|
7
|
+
"title": "A branch whose whole-expression condition resolves to nothing warns, naming the path and the port it took.",
|
|
8
|
+
"since": "0.24.0",
|
|
9
|
+
"tags": [
|
|
10
|
+
"routing",
|
|
11
|
+
"branch",
|
|
12
|
+
"warns"
|
|
13
|
+
],
|
|
14
|
+
"input": {
|
|
15
|
+
"schema": {
|
|
16
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
17
|
+
"version": 1,
|
|
18
|
+
"graph": {
|
|
19
|
+
"nodes": [
|
|
20
|
+
{
|
|
21
|
+
"id": "t",
|
|
22
|
+
"kind": "manual_trigger",
|
|
23
|
+
"position": {
|
|
24
|
+
"x": 0,
|
|
25
|
+
"y": 0
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "b",
|
|
30
|
+
"kind": "branch",
|
|
31
|
+
"position": {
|
|
32
|
+
"x": 0,
|
|
33
|
+
"y": 0
|
|
34
|
+
},
|
|
35
|
+
"config": {
|
|
36
|
+
"condition": "{{ $json.urgent }}"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "yes",
|
|
41
|
+
"kind": "log",
|
|
42
|
+
"position": {
|
|
43
|
+
"x": 0,
|
|
44
|
+
"y": 0
|
|
45
|
+
},
|
|
46
|
+
"config": {
|
|
47
|
+
"message": "true side"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "no",
|
|
52
|
+
"kind": "log",
|
|
53
|
+
"position": {
|
|
54
|
+
"x": 0,
|
|
55
|
+
"y": 0
|
|
56
|
+
},
|
|
57
|
+
"config": {
|
|
58
|
+
"message": "false side"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"edges": [
|
|
63
|
+
{
|
|
64
|
+
"id": "e1",
|
|
65
|
+
"source": "t",
|
|
66
|
+
"target": "b"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "e2",
|
|
70
|
+
"source": "b",
|
|
71
|
+
"target": "yes",
|
|
72
|
+
"sourceHandle": "true"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"id": "e3",
|
|
76
|
+
"source": "b",
|
|
77
|
+
"target": "no",
|
|
78
|
+
"sourceHandle": "false"
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"initialInputs": {
|
|
84
|
+
"t": {
|
|
85
|
+
"other": true
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"expected": [
|
|
90
|
+
{
|
|
91
|
+
"nodeId": "b",
|
|
92
|
+
"message": "Node b took the \"false\" port because `condition` resolved to NOTHING — the path $json.urgent names no field on this node's inputs. That is not the same as a false condition: the route was decided by an absent value rather than by the data.",
|
|
93
|
+
"detail": {
|
|
94
|
+
"node": "b",
|
|
95
|
+
"configKey": "condition",
|
|
96
|
+
"path": "$json.urgent",
|
|
97
|
+
"tookPort": "false"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
"notes": "The failure flabs found: a correct triage graph whose urgency check named a field that did not resolve, so every request, including one reporting total payment failure, was routed as non-urgent. Routing is unchanged -- it still takes `false` -- and the warning supplies the reason."
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"id": "0002-branch-condition-legitimately-false",
|
|
105
|
+
"title": "A condition that resolves to false is silent: most branches ever run take false honestly.",
|
|
106
|
+
"since": "0.24.0",
|
|
107
|
+
"tags": [
|
|
108
|
+
"routing",
|
|
109
|
+
"branch",
|
|
110
|
+
"silent"
|
|
111
|
+
],
|
|
112
|
+
"input": {
|
|
113
|
+
"schema": {
|
|
114
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
115
|
+
"version": 1,
|
|
116
|
+
"graph": {
|
|
117
|
+
"nodes": [
|
|
118
|
+
{
|
|
119
|
+
"id": "t",
|
|
120
|
+
"kind": "manual_trigger",
|
|
121
|
+
"position": {
|
|
122
|
+
"x": 0,
|
|
123
|
+
"y": 0
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"id": "b",
|
|
128
|
+
"kind": "branch",
|
|
129
|
+
"position": {
|
|
130
|
+
"x": 0,
|
|
131
|
+
"y": 0
|
|
132
|
+
},
|
|
133
|
+
"config": {
|
|
134
|
+
"condition": "{{ $json.urgent }}"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "yes",
|
|
139
|
+
"kind": "log",
|
|
140
|
+
"position": {
|
|
141
|
+
"x": 0,
|
|
142
|
+
"y": 0
|
|
143
|
+
},
|
|
144
|
+
"config": {
|
|
145
|
+
"message": "true side"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"id": "no",
|
|
150
|
+
"kind": "log",
|
|
151
|
+
"position": {
|
|
152
|
+
"x": 0,
|
|
153
|
+
"y": 0
|
|
154
|
+
},
|
|
155
|
+
"config": {
|
|
156
|
+
"message": "false side"
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
],
|
|
160
|
+
"edges": [
|
|
161
|
+
{
|
|
162
|
+
"id": "e1",
|
|
163
|
+
"source": "t",
|
|
164
|
+
"target": "b"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"id": "e2",
|
|
168
|
+
"source": "b",
|
|
169
|
+
"target": "yes",
|
|
170
|
+
"sourceHandle": "true"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"id": "e3",
|
|
174
|
+
"source": "b",
|
|
175
|
+
"target": "no",
|
|
176
|
+
"sourceHandle": "false"
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
"initialInputs": {
|
|
182
|
+
"t": {
|
|
183
|
+
"urgent": false
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
"expected": [],
|
|
188
|
+
"notes": "The discipline row. A warning that fires on ordinary branching is noise, and noise is how a real warning stops being read."
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"id": "0003-branch-condition-resolves-to-null",
|
|
192
|
+
"title": "A key that exists holding null is RESOLVED, and is silent.",
|
|
193
|
+
"since": "0.24.0",
|
|
194
|
+
"tags": [
|
|
195
|
+
"routing",
|
|
196
|
+
"branch",
|
|
197
|
+
"silent",
|
|
198
|
+
"absent-vs-null"
|
|
199
|
+
],
|
|
200
|
+
"input": {
|
|
201
|
+
"schema": {
|
|
202
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
203
|
+
"version": 1,
|
|
204
|
+
"graph": {
|
|
205
|
+
"nodes": [
|
|
206
|
+
{
|
|
207
|
+
"id": "t",
|
|
208
|
+
"kind": "manual_trigger",
|
|
209
|
+
"position": {
|
|
210
|
+
"x": 0,
|
|
211
|
+
"y": 0
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"id": "b",
|
|
216
|
+
"kind": "branch",
|
|
217
|
+
"position": {
|
|
218
|
+
"x": 0,
|
|
219
|
+
"y": 0
|
|
220
|
+
},
|
|
221
|
+
"config": {
|
|
222
|
+
"condition": "{{ $json.urgent }}"
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"id": "yes",
|
|
227
|
+
"kind": "log",
|
|
228
|
+
"position": {
|
|
229
|
+
"x": 0,
|
|
230
|
+
"y": 0
|
|
231
|
+
},
|
|
232
|
+
"config": {
|
|
233
|
+
"message": "true side"
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"id": "no",
|
|
238
|
+
"kind": "log",
|
|
239
|
+
"position": {
|
|
240
|
+
"x": 0,
|
|
241
|
+
"y": 0
|
|
242
|
+
},
|
|
243
|
+
"config": {
|
|
244
|
+
"message": "false side"
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
],
|
|
248
|
+
"edges": [
|
|
249
|
+
{
|
|
250
|
+
"id": "e1",
|
|
251
|
+
"source": "t",
|
|
252
|
+
"target": "b"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"id": "e2",
|
|
256
|
+
"source": "b",
|
|
257
|
+
"target": "yes",
|
|
258
|
+
"sourceHandle": "true"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"id": "e3",
|
|
262
|
+
"source": "b",
|
|
263
|
+
"target": "no",
|
|
264
|
+
"sourceHandle": "false"
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
"initialInputs": {
|
|
270
|
+
"t": {
|
|
271
|
+
"urgent": null
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
"expected": [],
|
|
276
|
+
"notes": "Absent and null are different answers. An implementation that tests the resolved VALUE for null instead of asking whether the path resolved warns here, and that is the collapse this whole table exists to prevent."
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"id": "0004-branch-condition-mixes-text-and-an-expression",
|
|
280
|
+
"title": "A condition that mixes literal text with an unresolved expression is interpolation, not routing, and is silent.",
|
|
281
|
+
"since": "0.24.0",
|
|
282
|
+
"tags": [
|
|
283
|
+
"routing",
|
|
284
|
+
"branch",
|
|
285
|
+
"silent"
|
|
286
|
+
],
|
|
287
|
+
"input": {
|
|
288
|
+
"schema": {
|
|
289
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
290
|
+
"version": 1,
|
|
291
|
+
"graph": {
|
|
292
|
+
"nodes": [
|
|
293
|
+
{
|
|
294
|
+
"id": "t",
|
|
295
|
+
"kind": "manual_trigger",
|
|
296
|
+
"position": {
|
|
297
|
+
"x": 0,
|
|
298
|
+
"y": 0
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"id": "b",
|
|
303
|
+
"kind": "branch",
|
|
304
|
+
"position": {
|
|
305
|
+
"x": 0,
|
|
306
|
+
"y": 0
|
|
307
|
+
},
|
|
308
|
+
"config": {
|
|
309
|
+
"condition": "urgent is {{ $json.nope }}"
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"id": "yes",
|
|
314
|
+
"kind": "log",
|
|
315
|
+
"position": {
|
|
316
|
+
"x": 0,
|
|
317
|
+
"y": 0
|
|
318
|
+
},
|
|
319
|
+
"config": {
|
|
320
|
+
"message": "true side"
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"id": "no",
|
|
325
|
+
"kind": "log",
|
|
326
|
+
"position": {
|
|
327
|
+
"x": 0,
|
|
328
|
+
"y": 0
|
|
329
|
+
},
|
|
330
|
+
"config": {
|
|
331
|
+
"message": "false side"
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
],
|
|
335
|
+
"edges": [
|
|
336
|
+
{
|
|
337
|
+
"id": "e1",
|
|
338
|
+
"source": "t",
|
|
339
|
+
"target": "b"
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
"id": "e2",
|
|
343
|
+
"source": "b",
|
|
344
|
+
"target": "yes",
|
|
345
|
+
"sourceHandle": "true"
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"id": "e3",
|
|
349
|
+
"source": "b",
|
|
350
|
+
"target": "no",
|
|
351
|
+
"sourceHandle": "false"
|
|
352
|
+
}
|
|
353
|
+
]
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
"initialInputs": {
|
|
357
|
+
"t": {
|
|
358
|
+
"x": 1
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
"expected": []
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
"id": "0005-adjacent-references-are-not-one-missing-path",
|
|
366
|
+
"title": "`{{ a }}{{ b }}` is two references, never one path spanning `}}{{`, so even when neither resolves it is not reported as a missing field.",
|
|
367
|
+
"since": "0.24.0",
|
|
368
|
+
"tags": [
|
|
369
|
+
"routing",
|
|
370
|
+
"branch",
|
|
371
|
+
"silent"
|
|
372
|
+
],
|
|
373
|
+
"input": {
|
|
374
|
+
"schema": {
|
|
375
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
376
|
+
"version": 1,
|
|
377
|
+
"graph": {
|
|
378
|
+
"nodes": [
|
|
379
|
+
{
|
|
380
|
+
"id": "t",
|
|
381
|
+
"kind": "manual_trigger",
|
|
382
|
+
"position": {
|
|
383
|
+
"x": 0,
|
|
384
|
+
"y": 0
|
|
385
|
+
}
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"id": "b",
|
|
389
|
+
"kind": "branch",
|
|
390
|
+
"position": {
|
|
391
|
+
"x": 0,
|
|
392
|
+
"y": 0
|
|
393
|
+
},
|
|
394
|
+
"config": {
|
|
395
|
+
"condition": "{{ $json.a }}{{ $json.b }}"
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
"id": "yes",
|
|
400
|
+
"kind": "log",
|
|
401
|
+
"position": {
|
|
402
|
+
"x": 0,
|
|
403
|
+
"y": 0
|
|
404
|
+
},
|
|
405
|
+
"config": {
|
|
406
|
+
"message": "true side"
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
"id": "no",
|
|
411
|
+
"kind": "log",
|
|
412
|
+
"position": {
|
|
413
|
+
"x": 0,
|
|
414
|
+
"y": 0
|
|
415
|
+
},
|
|
416
|
+
"config": {
|
|
417
|
+
"message": "false side"
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
],
|
|
421
|
+
"edges": [
|
|
422
|
+
{
|
|
423
|
+
"id": "e1",
|
|
424
|
+
"source": "t",
|
|
425
|
+
"target": "b"
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
"id": "e2",
|
|
429
|
+
"source": "b",
|
|
430
|
+
"target": "yes",
|
|
431
|
+
"sourceHandle": "true"
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
"id": "e3",
|
|
435
|
+
"source": "b",
|
|
436
|
+
"target": "no",
|
|
437
|
+
"sourceHandle": "false"
|
|
438
|
+
}
|
|
439
|
+
]
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
"initialInputs": {
|
|
443
|
+
"t": {
|
|
444
|
+
"x": 1
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
},
|
|
448
|
+
"expected": [],
|
|
449
|
+
"notes": "Before fancy-flow-php#16 the whole-string branch read this as ONE path, `$json.a }}{{ $json.b`. A diagnostic built on that reading would name a field no graph could have."
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"id": "0006-switch-routes-on-an-unresolved-value",
|
|
453
|
+
"title": "A switch_case whose value resolves to nothing warns that it fell to `default`, naming `value` as the config key.",
|
|
454
|
+
"since": "0.24.0",
|
|
455
|
+
"tags": [
|
|
456
|
+
"routing",
|
|
457
|
+
"switch_case",
|
|
458
|
+
"warns"
|
|
459
|
+
],
|
|
460
|
+
"input": {
|
|
461
|
+
"schema": {
|
|
462
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
463
|
+
"version": 1,
|
|
464
|
+
"graph": {
|
|
465
|
+
"nodes": [
|
|
466
|
+
{
|
|
467
|
+
"id": "t",
|
|
468
|
+
"kind": "manual_trigger",
|
|
469
|
+
"position": {
|
|
470
|
+
"x": 0,
|
|
471
|
+
"y": 0
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
"id": "s",
|
|
476
|
+
"kind": "switch_case",
|
|
477
|
+
"position": {
|
|
478
|
+
"x": 0,
|
|
479
|
+
"y": 0
|
|
480
|
+
},
|
|
481
|
+
"config": {
|
|
482
|
+
"value": "{{ $json.lane }}",
|
|
483
|
+
"cases": {
|
|
484
|
+
"billing": "case_a"
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
"id": "to_case_a",
|
|
490
|
+
"kind": "log",
|
|
491
|
+
"position": {
|
|
492
|
+
"x": 0,
|
|
493
|
+
"y": 0
|
|
494
|
+
},
|
|
495
|
+
"config": {
|
|
496
|
+
"message": "case_a"
|
|
497
|
+
}
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"id": "to_default",
|
|
501
|
+
"kind": "log",
|
|
502
|
+
"position": {
|
|
503
|
+
"x": 0,
|
|
504
|
+
"y": 0
|
|
505
|
+
},
|
|
506
|
+
"config": {
|
|
507
|
+
"message": "default"
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
],
|
|
511
|
+
"edges": [
|
|
512
|
+
{
|
|
513
|
+
"id": "e1",
|
|
514
|
+
"source": "t",
|
|
515
|
+
"target": "s"
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
"id": "e2",
|
|
519
|
+
"source": "s",
|
|
520
|
+
"target": "to_case_a",
|
|
521
|
+
"sourceHandle": "case_a"
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
"id": "e3",
|
|
525
|
+
"source": "s",
|
|
526
|
+
"target": "to_default",
|
|
527
|
+
"sourceHandle": "default"
|
|
528
|
+
}
|
|
529
|
+
]
|
|
530
|
+
}
|
|
531
|
+
},
|
|
532
|
+
"initialInputs": {
|
|
533
|
+
"t": {
|
|
534
|
+
"something_else": "billing"
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
"expected": [
|
|
539
|
+
{
|
|
540
|
+
"nodeId": "s",
|
|
541
|
+
"message": "Node s took the \"default\" port because `value` resolved to NOTHING — the path $json.lane names no field on this node's inputs. That is not the same as a false condition: the route was decided by an absent value rather than by the data.",
|
|
542
|
+
"detail": {
|
|
543
|
+
"node": "s",
|
|
544
|
+
"configKey": "value",
|
|
545
|
+
"path": "$json.lane",
|
|
546
|
+
"tookPort": "default"
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
]
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
"id": "0007-switch-value-matches-no-case",
|
|
553
|
+
"title": "A switch_case value that resolves but matches no case is what `default` is FOR, and is silent.",
|
|
554
|
+
"since": "0.24.0",
|
|
555
|
+
"tags": [
|
|
556
|
+
"routing",
|
|
557
|
+
"switch_case",
|
|
558
|
+
"silent"
|
|
559
|
+
],
|
|
560
|
+
"input": {
|
|
561
|
+
"schema": {
|
|
562
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
563
|
+
"version": 1,
|
|
564
|
+
"graph": {
|
|
565
|
+
"nodes": [
|
|
566
|
+
{
|
|
567
|
+
"id": "t",
|
|
568
|
+
"kind": "manual_trigger",
|
|
569
|
+
"position": {
|
|
570
|
+
"x": 0,
|
|
571
|
+
"y": 0
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
"id": "s",
|
|
576
|
+
"kind": "switch_case",
|
|
577
|
+
"position": {
|
|
578
|
+
"x": 0,
|
|
579
|
+
"y": 0
|
|
580
|
+
},
|
|
581
|
+
"config": {
|
|
582
|
+
"value": "{{ $json.lane }}",
|
|
583
|
+
"cases": {
|
|
584
|
+
"billing": "case_a"
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
"id": "to_case_a",
|
|
590
|
+
"kind": "log",
|
|
591
|
+
"position": {
|
|
592
|
+
"x": 0,
|
|
593
|
+
"y": 0
|
|
594
|
+
},
|
|
595
|
+
"config": {
|
|
596
|
+
"message": "case_a"
|
|
597
|
+
}
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
"id": "to_default",
|
|
601
|
+
"kind": "log",
|
|
602
|
+
"position": {
|
|
603
|
+
"x": 0,
|
|
604
|
+
"y": 0
|
|
605
|
+
},
|
|
606
|
+
"config": {
|
|
607
|
+
"message": "default"
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
],
|
|
611
|
+
"edges": [
|
|
612
|
+
{
|
|
613
|
+
"id": "e1",
|
|
614
|
+
"source": "t",
|
|
615
|
+
"target": "s"
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
"id": "e2",
|
|
619
|
+
"source": "s",
|
|
620
|
+
"target": "to_case_a",
|
|
621
|
+
"sourceHandle": "case_a"
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
"id": "e3",
|
|
625
|
+
"source": "s",
|
|
626
|
+
"target": "to_default",
|
|
627
|
+
"sourceHandle": "default"
|
|
628
|
+
}
|
|
629
|
+
]
|
|
630
|
+
}
|
|
631
|
+
},
|
|
632
|
+
"initialInputs": {
|
|
633
|
+
"t": {
|
|
634
|
+
"lane": "unmapped"
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
},
|
|
638
|
+
"expected": []
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
"id": "0008-edge-names-a-port-its-source-never-publishes",
|
|
642
|
+
"title": "An edge whose sourceHandle names no port of a node that completed warns: edge id first, the consequence, what is available, and the remedy.",
|
|
643
|
+
"since": "0.24.0",
|
|
644
|
+
"tags": [
|
|
645
|
+
"undelivered-edge",
|
|
646
|
+
"warns"
|
|
647
|
+
],
|
|
648
|
+
"input": {
|
|
649
|
+
"schema": {
|
|
650
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
651
|
+
"version": 1,
|
|
652
|
+
"graph": {
|
|
653
|
+
"nodes": [
|
|
654
|
+
{
|
|
655
|
+
"id": "t",
|
|
656
|
+
"kind": "manual_trigger",
|
|
657
|
+
"position": {
|
|
658
|
+
"x": 0,
|
|
659
|
+
"y": 0
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
"id": "tf",
|
|
664
|
+
"kind": "transform",
|
|
665
|
+
"position": {
|
|
666
|
+
"x": 0,
|
|
667
|
+
"y": 0
|
|
668
|
+
},
|
|
669
|
+
"config": {
|
|
670
|
+
"expression": "{{ $json.name }}"
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
"id": "o",
|
|
675
|
+
"kind": "output",
|
|
676
|
+
"position": {
|
|
677
|
+
"x": 0,
|
|
678
|
+
"y": 0
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
],
|
|
682
|
+
"edges": [
|
|
683
|
+
{
|
|
684
|
+
"id": "e1",
|
|
685
|
+
"source": "t",
|
|
686
|
+
"target": "tf"
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
"id": "e2",
|
|
690
|
+
"source": "tf",
|
|
691
|
+
"target": "o",
|
|
692
|
+
"sourceHandle": "result"
|
|
693
|
+
}
|
|
694
|
+
]
|
|
695
|
+
}
|
|
696
|
+
},
|
|
697
|
+
"initialInputs": {
|
|
698
|
+
"t": {
|
|
699
|
+
"name": "Ada"
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
},
|
|
703
|
+
"expected": [
|
|
704
|
+
{
|
|
705
|
+
"nodeId": "o",
|
|
706
|
+
"message": "Edge e2 reads port \"result\" from node tf, which never publishes it — nothing would reach o at run time. Available: out. Leave sourceHandle off to read the node's output.",
|
|
707
|
+
"detail": {
|
|
708
|
+
"edge": "e2",
|
|
709
|
+
"source": "tf",
|
|
710
|
+
"sourceHandle": "result"
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
],
|
|
714
|
+
"notes": "The warning is reported against the TARGET node, which is the one that will never receive anything. Its only inbound edge is the bad one, so it is skipped -- the silent shape."
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
"id": "0009-untaken-branch-port-is-ordinary",
|
|
718
|
+
"title": "The edge leaving the branch port that was NOT taken binds nothing, and is silent: that is ordinary branching.",
|
|
719
|
+
"since": "0.24.0",
|
|
720
|
+
"tags": [
|
|
721
|
+
"undelivered-edge",
|
|
722
|
+
"silent"
|
|
723
|
+
],
|
|
724
|
+
"input": {
|
|
725
|
+
"schema": {
|
|
726
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
727
|
+
"version": 1,
|
|
728
|
+
"graph": {
|
|
729
|
+
"nodes": [
|
|
730
|
+
{
|
|
731
|
+
"id": "t",
|
|
732
|
+
"kind": "manual_trigger",
|
|
733
|
+
"position": {
|
|
734
|
+
"x": 0,
|
|
735
|
+
"y": 0
|
|
736
|
+
}
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
"id": "b",
|
|
740
|
+
"kind": "branch",
|
|
741
|
+
"position": {
|
|
742
|
+
"x": 0,
|
|
743
|
+
"y": 0
|
|
744
|
+
},
|
|
745
|
+
"config": {
|
|
746
|
+
"condition": "{{ $json.urgent }}"
|
|
747
|
+
}
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
"id": "yes",
|
|
751
|
+
"kind": "log",
|
|
752
|
+
"position": {
|
|
753
|
+
"x": 0,
|
|
754
|
+
"y": 0
|
|
755
|
+
},
|
|
756
|
+
"config": {
|
|
757
|
+
"message": "true side"
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
"id": "no",
|
|
762
|
+
"kind": "log",
|
|
763
|
+
"position": {
|
|
764
|
+
"x": 0,
|
|
765
|
+
"y": 0
|
|
766
|
+
},
|
|
767
|
+
"config": {
|
|
768
|
+
"message": "false side"
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
],
|
|
772
|
+
"edges": [
|
|
773
|
+
{
|
|
774
|
+
"id": "e1",
|
|
775
|
+
"source": "t",
|
|
776
|
+
"target": "b"
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
"id": "e2",
|
|
780
|
+
"source": "b",
|
|
781
|
+
"target": "yes",
|
|
782
|
+
"sourceHandle": "true"
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
"id": "e3",
|
|
786
|
+
"source": "b",
|
|
787
|
+
"target": "no",
|
|
788
|
+
"sourceHandle": "false"
|
|
789
|
+
}
|
|
790
|
+
]
|
|
791
|
+
}
|
|
792
|
+
},
|
|
793
|
+
"initialInputs": {
|
|
794
|
+
"t": {
|
|
795
|
+
"urgent": true
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
},
|
|
799
|
+
"expected": [],
|
|
800
|
+
"notes": "Asking 'did the source publish this port?' cannot tell an untaken branch from an impossible handle -- both are absent. The rule asks whether the port is POSSIBLE for the node."
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
"id": "0010-inverted-switch-cases-map",
|
|
804
|
+
"title": "A switch_case whose cases map is inverted (port => value) warns once per edge naming a port the node can never publish.",
|
|
805
|
+
"since": "0.24.0",
|
|
806
|
+
"tags": [
|
|
807
|
+
"undelivered-edge",
|
|
808
|
+
"switch_case",
|
|
809
|
+
"warns"
|
|
810
|
+
],
|
|
811
|
+
"input": {
|
|
812
|
+
"schema": {
|
|
813
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
814
|
+
"version": 1,
|
|
815
|
+
"graph": {
|
|
816
|
+
"nodes": [
|
|
817
|
+
{
|
|
818
|
+
"id": "t",
|
|
819
|
+
"kind": "manual_trigger",
|
|
820
|
+
"position": {
|
|
821
|
+
"x": 0,
|
|
822
|
+
"y": 0
|
|
823
|
+
}
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
"id": "s",
|
|
827
|
+
"kind": "switch_case",
|
|
828
|
+
"position": {
|
|
829
|
+
"x": 0,
|
|
830
|
+
"y": 0
|
|
831
|
+
},
|
|
832
|
+
"config": {
|
|
833
|
+
"value": "{{ $json.kind }}",
|
|
834
|
+
"cases": {
|
|
835
|
+
"case_a": "a",
|
|
836
|
+
"case_b": "b"
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
},
|
|
840
|
+
{
|
|
841
|
+
"id": "to_case_a",
|
|
842
|
+
"kind": "log",
|
|
843
|
+
"position": {
|
|
844
|
+
"x": 0,
|
|
845
|
+
"y": 0
|
|
846
|
+
},
|
|
847
|
+
"config": {
|
|
848
|
+
"message": "case_a"
|
|
849
|
+
}
|
|
850
|
+
},
|
|
851
|
+
{
|
|
852
|
+
"id": "to_case_b",
|
|
853
|
+
"kind": "log",
|
|
854
|
+
"position": {
|
|
855
|
+
"x": 0,
|
|
856
|
+
"y": 0
|
|
857
|
+
},
|
|
858
|
+
"config": {
|
|
859
|
+
"message": "case_b"
|
|
860
|
+
}
|
|
861
|
+
},
|
|
862
|
+
{
|
|
863
|
+
"id": "to_default",
|
|
864
|
+
"kind": "log",
|
|
865
|
+
"position": {
|
|
866
|
+
"x": 0,
|
|
867
|
+
"y": 0
|
|
868
|
+
},
|
|
869
|
+
"config": {
|
|
870
|
+
"message": "default"
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
],
|
|
874
|
+
"edges": [
|
|
875
|
+
{
|
|
876
|
+
"id": "e1",
|
|
877
|
+
"source": "t",
|
|
878
|
+
"target": "s"
|
|
879
|
+
},
|
|
880
|
+
{
|
|
881
|
+
"id": "e2",
|
|
882
|
+
"source": "s",
|
|
883
|
+
"target": "to_case_a",
|
|
884
|
+
"sourceHandle": "case_a"
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
"id": "e3",
|
|
888
|
+
"source": "s",
|
|
889
|
+
"target": "to_case_b",
|
|
890
|
+
"sourceHandle": "case_b"
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
"id": "e4",
|
|
894
|
+
"source": "s",
|
|
895
|
+
"target": "to_default",
|
|
896
|
+
"sourceHandle": "default"
|
|
897
|
+
}
|
|
898
|
+
]
|
|
899
|
+
}
|
|
900
|
+
},
|
|
901
|
+
"initialInputs": {
|
|
902
|
+
"t": {
|
|
903
|
+
"kind": "a"
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
},
|
|
907
|
+
"expected": [
|
|
908
|
+
{
|
|
909
|
+
"nodeId": "to_case_a",
|
|
910
|
+
"message": "Edge e2 reads port \"case_a\" from node s, which never publishes it — nothing would reach to_case_a at run time. Available: default. Leave sourceHandle off to read the node's output.",
|
|
911
|
+
"detail": {
|
|
912
|
+
"edge": "e2",
|
|
913
|
+
"source": "s",
|
|
914
|
+
"sourceHandle": "case_a"
|
|
915
|
+
}
|
|
916
|
+
},
|
|
917
|
+
{
|
|
918
|
+
"nodeId": "to_case_b",
|
|
919
|
+
"message": "Edge e3 reads port \"case_b\" from node s, which never publishes it — nothing would reach to_case_b at run time. Available: default. Leave sourceHandle off to read the node's output.",
|
|
920
|
+
"detail": {
|
|
921
|
+
"edge": "e3",
|
|
922
|
+
"source": "s",
|
|
923
|
+
"sourceHandle": "case_b"
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
],
|
|
927
|
+
"notes": "Measured, not imagined: the flabs smart-routing reference graph had exactly this inversion. PHP warned about the dead edge at once; the Node, Python and Rust engines ran the same graph and said nothing (fancy-flow#17). `cases` maps VALUE => PORT, so the possible ports here are `a`, `b` and `default`."
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
"id": "0011-configured-third-case-is-a-real-port",
|
|
931
|
+
"title": "A port derived from a switch_case's own cases config is possible, so an edge from it is silent even when the run did not take it.",
|
|
932
|
+
"since": "0.24.0",
|
|
933
|
+
"tags": [
|
|
934
|
+
"undelivered-edge",
|
|
935
|
+
"switch_case",
|
|
936
|
+
"silent",
|
|
937
|
+
"config-derived-ports"
|
|
938
|
+
],
|
|
939
|
+
"input": {
|
|
940
|
+
"schema": {
|
|
941
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
942
|
+
"version": 1,
|
|
943
|
+
"graph": {
|
|
944
|
+
"nodes": [
|
|
945
|
+
{
|
|
946
|
+
"id": "t",
|
|
947
|
+
"kind": "manual_trigger",
|
|
948
|
+
"position": {
|
|
949
|
+
"x": 0,
|
|
950
|
+
"y": 0
|
|
951
|
+
}
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
"id": "s",
|
|
955
|
+
"kind": "switch_case",
|
|
956
|
+
"position": {
|
|
957
|
+
"x": 0,
|
|
958
|
+
"y": 0
|
|
959
|
+
},
|
|
960
|
+
"config": {
|
|
961
|
+
"value": "{{ $json.kind }}",
|
|
962
|
+
"cases": {
|
|
963
|
+
"a": "case_a",
|
|
964
|
+
"b": "case_b",
|
|
965
|
+
"c": "case_c"
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
"id": "to_case_a",
|
|
971
|
+
"kind": "log",
|
|
972
|
+
"position": {
|
|
973
|
+
"x": 0,
|
|
974
|
+
"y": 0
|
|
975
|
+
},
|
|
976
|
+
"config": {
|
|
977
|
+
"message": "case_a"
|
|
978
|
+
}
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
"id": "to_case_b",
|
|
982
|
+
"kind": "log",
|
|
983
|
+
"position": {
|
|
984
|
+
"x": 0,
|
|
985
|
+
"y": 0
|
|
986
|
+
},
|
|
987
|
+
"config": {
|
|
988
|
+
"message": "case_b"
|
|
989
|
+
}
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
"id": "to_case_c",
|
|
993
|
+
"kind": "log",
|
|
994
|
+
"position": {
|
|
995
|
+
"x": 0,
|
|
996
|
+
"y": 0
|
|
997
|
+
},
|
|
998
|
+
"config": {
|
|
999
|
+
"message": "case_c"
|
|
1000
|
+
}
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
"id": "to_default",
|
|
1004
|
+
"kind": "log",
|
|
1005
|
+
"position": {
|
|
1006
|
+
"x": 0,
|
|
1007
|
+
"y": 0
|
|
1008
|
+
},
|
|
1009
|
+
"config": {
|
|
1010
|
+
"message": "default"
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
],
|
|
1014
|
+
"edges": [
|
|
1015
|
+
{
|
|
1016
|
+
"id": "e1",
|
|
1017
|
+
"source": "t",
|
|
1018
|
+
"target": "s"
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
"id": "e2",
|
|
1022
|
+
"source": "s",
|
|
1023
|
+
"target": "to_case_a",
|
|
1024
|
+
"sourceHandle": "case_a"
|
|
1025
|
+
},
|
|
1026
|
+
{
|
|
1027
|
+
"id": "e3",
|
|
1028
|
+
"source": "s",
|
|
1029
|
+
"target": "to_case_b",
|
|
1030
|
+
"sourceHandle": "case_b"
|
|
1031
|
+
},
|
|
1032
|
+
{
|
|
1033
|
+
"id": "e4",
|
|
1034
|
+
"source": "s",
|
|
1035
|
+
"target": "to_case_c",
|
|
1036
|
+
"sourceHandle": "case_c"
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
"id": "e5",
|
|
1040
|
+
"source": "s",
|
|
1041
|
+
"target": "to_default",
|
|
1042
|
+
"sourceHandle": "default"
|
|
1043
|
+
}
|
|
1044
|
+
]
|
|
1045
|
+
}
|
|
1046
|
+
},
|
|
1047
|
+
"initialInputs": {
|
|
1048
|
+
"t": {
|
|
1049
|
+
"kind": "a"
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
},
|
|
1053
|
+
"expected": [],
|
|
1054
|
+
"notes": "The kind's static declaration lists only case_a, case_b and default. An engine that reads that instead of the node's cases reports case_c as impossible -- which is exactly what the authoring tools had invited an agent to build, and flabs caught it."
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
"id": "0012-handle-names-a-field-not-a-port",
|
|
1058
|
+
"title": "When the bad handle is a FIELD the source emits, the warning says so and shows how to read the field.",
|
|
1059
|
+
"since": "0.24.0",
|
|
1060
|
+
"tags": [
|
|
1061
|
+
"undelivered-edge",
|
|
1062
|
+
"near-miss",
|
|
1063
|
+
"warns"
|
|
1064
|
+
],
|
|
1065
|
+
"input": {
|
|
1066
|
+
"schema": {
|
|
1067
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
1068
|
+
"version": 1,
|
|
1069
|
+
"graph": {
|
|
1070
|
+
"nodes": [
|
|
1071
|
+
{
|
|
1072
|
+
"id": "t",
|
|
1073
|
+
"kind": "manual_trigger",
|
|
1074
|
+
"position": {
|
|
1075
|
+
"x": 0,
|
|
1076
|
+
"y": 0
|
|
1077
|
+
}
|
|
1078
|
+
},
|
|
1079
|
+
{
|
|
1080
|
+
"id": "fe",
|
|
1081
|
+
"kind": "for_each",
|
|
1082
|
+
"position": {
|
|
1083
|
+
"x": 0,
|
|
1084
|
+
"y": 0
|
|
1085
|
+
},
|
|
1086
|
+
"config": {
|
|
1087
|
+
"source": "{{ $json.items }}"
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
"id": "o",
|
|
1092
|
+
"kind": "output",
|
|
1093
|
+
"position": {
|
|
1094
|
+
"x": 0,
|
|
1095
|
+
"y": 0
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
],
|
|
1099
|
+
"edges": [
|
|
1100
|
+
{
|
|
1101
|
+
"id": "e1",
|
|
1102
|
+
"source": "t",
|
|
1103
|
+
"target": "fe"
|
|
1104
|
+
},
|
|
1105
|
+
{
|
|
1106
|
+
"id": "e2",
|
|
1107
|
+
"source": "fe",
|
|
1108
|
+
"target": "o",
|
|
1109
|
+
"sourceHandle": "count"
|
|
1110
|
+
}
|
|
1111
|
+
]
|
|
1112
|
+
}
|
|
1113
|
+
},
|
|
1114
|
+
"initialInputs": {
|
|
1115
|
+
"t": {
|
|
1116
|
+
"items": [
|
|
1117
|
+
1,
|
|
1118
|
+
2
|
|
1119
|
+
]
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
},
|
|
1123
|
+
"expected": [
|
|
1124
|
+
{
|
|
1125
|
+
"nodeId": "o",
|
|
1126
|
+
"message": "Edge e2 reads port \"count\" from node fe, which never publishes it — nothing would reach o at run time. Available: item, done. Note: \"count\" is a FIELD this node emits, not a port — read it downstream as {{ in.count }} rather than naming it as a source handle. Leave sourceHandle off to read the node's output.",
|
|
1127
|
+
"detail": {
|
|
1128
|
+
"edge": "e2",
|
|
1129
|
+
"source": "fe",
|
|
1130
|
+
"sourceHandle": "count"
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
],
|
|
1134
|
+
"notes": "`count` is in for_each's declared output shape. Nearly every occurrence is an agent reaching for a field name where a port belongs, and naming that turns a correction into an explanation."
|
|
1135
|
+
},
|
|
1136
|
+
{
|
|
1137
|
+
"id": "0013-bad-edge-beside-a-live-one",
|
|
1138
|
+
"title": "A bad edge into a node that ALSO has a live inbound edge still warns, although the node runs.",
|
|
1139
|
+
"since": "0.24.0",
|
|
1140
|
+
"tags": [
|
|
1141
|
+
"undelivered-edge",
|
|
1142
|
+
"merge",
|
|
1143
|
+
"warns"
|
|
1144
|
+
],
|
|
1145
|
+
"input": {
|
|
1146
|
+
"schema": {
|
|
1147
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
1148
|
+
"version": 1,
|
|
1149
|
+
"graph": {
|
|
1150
|
+
"nodes": [
|
|
1151
|
+
{
|
|
1152
|
+
"id": "t",
|
|
1153
|
+
"kind": "manual_trigger",
|
|
1154
|
+
"position": {
|
|
1155
|
+
"x": 0,
|
|
1156
|
+
"y": 0
|
|
1157
|
+
}
|
|
1158
|
+
},
|
|
1159
|
+
{
|
|
1160
|
+
"id": "a",
|
|
1161
|
+
"kind": "transform",
|
|
1162
|
+
"position": {
|
|
1163
|
+
"x": 0,
|
|
1164
|
+
"y": 0
|
|
1165
|
+
},
|
|
1166
|
+
"config": {
|
|
1167
|
+
"expression": "{{ $json.name }}"
|
|
1168
|
+
}
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
"id": "b",
|
|
1172
|
+
"kind": "transform",
|
|
1173
|
+
"position": {
|
|
1174
|
+
"x": 0,
|
|
1175
|
+
"y": 0
|
|
1176
|
+
},
|
|
1177
|
+
"config": {
|
|
1178
|
+
"expression": "{{ $json.name }}"
|
|
1179
|
+
}
|
|
1180
|
+
},
|
|
1181
|
+
{
|
|
1182
|
+
"id": "m",
|
|
1183
|
+
"kind": "merge",
|
|
1184
|
+
"position": {
|
|
1185
|
+
"x": 0,
|
|
1186
|
+
"y": 0
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
],
|
|
1190
|
+
"edges": [
|
|
1191
|
+
{
|
|
1192
|
+
"id": "e1",
|
|
1193
|
+
"source": "t",
|
|
1194
|
+
"target": "a"
|
|
1195
|
+
},
|
|
1196
|
+
{
|
|
1197
|
+
"id": "e2",
|
|
1198
|
+
"source": "t",
|
|
1199
|
+
"target": "b"
|
|
1200
|
+
},
|
|
1201
|
+
{
|
|
1202
|
+
"id": "e3",
|
|
1203
|
+
"source": "a",
|
|
1204
|
+
"target": "m"
|
|
1205
|
+
},
|
|
1206
|
+
{
|
|
1207
|
+
"id": "e4",
|
|
1208
|
+
"source": "b",
|
|
1209
|
+
"target": "m",
|
|
1210
|
+
"sourceHandle": "nope"
|
|
1211
|
+
}
|
|
1212
|
+
]
|
|
1213
|
+
}
|
|
1214
|
+
},
|
|
1215
|
+
"initialInputs": {
|
|
1216
|
+
"t": {
|
|
1217
|
+
"name": "Ada"
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
},
|
|
1221
|
+
"expected": [
|
|
1222
|
+
{
|
|
1223
|
+
"nodeId": "m",
|
|
1224
|
+
"message": "Edge e4 reads port \"nope\" from node b, which never publishes it — nothing would reach m at run time. Available: out. Leave sourceHandle off to read the node's output.",
|
|
1225
|
+
"detail": {
|
|
1226
|
+
"edge": "e4",
|
|
1227
|
+
"source": "b",
|
|
1228
|
+
"sourceHandle": "nope"
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
],
|
|
1232
|
+
"notes": "The more misleading of the two silent shapes: the node runs with that input simply missing, so a downstream template is entirely correct and renders empty. A consumer misdiagnosed two filed issues off the back of it."
|
|
1233
|
+
},
|
|
1234
|
+
{
|
|
1235
|
+
"id": "0014-source-that-never-ran-is-not-judged",
|
|
1236
|
+
"title": "An edge out of a node that was skipped is silent, whatever its handle: only a source that COMPLETED can be said to never publish a port.",
|
|
1237
|
+
"since": "0.24.0",
|
|
1238
|
+
"tags": [
|
|
1239
|
+
"undelivered-edge",
|
|
1240
|
+
"silent"
|
|
1241
|
+
],
|
|
1242
|
+
"input": {
|
|
1243
|
+
"schema": {
|
|
1244
|
+
"$schema": "https://particle.academy/schemas/workflow/v1.json",
|
|
1245
|
+
"version": 1,
|
|
1246
|
+
"graph": {
|
|
1247
|
+
"nodes": [
|
|
1248
|
+
{
|
|
1249
|
+
"id": "t",
|
|
1250
|
+
"kind": "manual_trigger",
|
|
1251
|
+
"position": {
|
|
1252
|
+
"x": 0,
|
|
1253
|
+
"y": 0
|
|
1254
|
+
}
|
|
1255
|
+
},
|
|
1256
|
+
{
|
|
1257
|
+
"id": "b",
|
|
1258
|
+
"kind": "branch",
|
|
1259
|
+
"position": {
|
|
1260
|
+
"x": 0,
|
|
1261
|
+
"y": 0
|
|
1262
|
+
},
|
|
1263
|
+
"config": {
|
|
1264
|
+
"condition": "{{ $json.urgent }}"
|
|
1265
|
+
}
|
|
1266
|
+
},
|
|
1267
|
+
{
|
|
1268
|
+
"id": "yes",
|
|
1269
|
+
"kind": "log",
|
|
1270
|
+
"position": {
|
|
1271
|
+
"x": 0,
|
|
1272
|
+
"y": 0
|
|
1273
|
+
},
|
|
1274
|
+
"config": {
|
|
1275
|
+
"message": "true side"
|
|
1276
|
+
}
|
|
1277
|
+
},
|
|
1278
|
+
{
|
|
1279
|
+
"id": "skipped",
|
|
1280
|
+
"kind": "transform",
|
|
1281
|
+
"position": {
|
|
1282
|
+
"x": 0,
|
|
1283
|
+
"y": 0
|
|
1284
|
+
},
|
|
1285
|
+
"config": {
|
|
1286
|
+
"expression": "{{ $json.urgent }}"
|
|
1287
|
+
}
|
|
1288
|
+
},
|
|
1289
|
+
{
|
|
1290
|
+
"id": "after",
|
|
1291
|
+
"kind": "output",
|
|
1292
|
+
"position": {
|
|
1293
|
+
"x": 0,
|
|
1294
|
+
"y": 0
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
],
|
|
1298
|
+
"edges": [
|
|
1299
|
+
{
|
|
1300
|
+
"id": "e1",
|
|
1301
|
+
"source": "t",
|
|
1302
|
+
"target": "b"
|
|
1303
|
+
},
|
|
1304
|
+
{
|
|
1305
|
+
"id": "e2",
|
|
1306
|
+
"source": "b",
|
|
1307
|
+
"target": "yes",
|
|
1308
|
+
"sourceHandle": "true"
|
|
1309
|
+
},
|
|
1310
|
+
{
|
|
1311
|
+
"id": "e3",
|
|
1312
|
+
"source": "b",
|
|
1313
|
+
"target": "skipped",
|
|
1314
|
+
"sourceHandle": "false"
|
|
1315
|
+
},
|
|
1316
|
+
{
|
|
1317
|
+
"id": "e4",
|
|
1318
|
+
"source": "skipped",
|
|
1319
|
+
"target": "after",
|
|
1320
|
+
"sourceHandle": "nope"
|
|
1321
|
+
}
|
|
1322
|
+
]
|
|
1323
|
+
}
|
|
1324
|
+
},
|
|
1325
|
+
"initialInputs": {
|
|
1326
|
+
"t": {
|
|
1327
|
+
"urgent": true
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
},
|
|
1331
|
+
"expected": []
|
|
1332
|
+
}
|
|
1333
|
+
]
|
|
1334
|
+
}
|