-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspec.html
More file actions
3262 lines (3244 loc) · 199 KB
/
Copy pathspec.html
File metadata and controls
3262 lines (3244 loc) · 199 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<html>
<head>
<meta name="generator" content="Hugo 0.144.2">
<title>Amazon States Language</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<style>
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
background: #eee;
color: #424242;
margin: 0 auto;
max-width: 1000px;
}
code {
font-family: Consolas, Monaco, Lucida Console, Courier New;
color: #dd2233;
}
.new {
background: #aea;
padding: 10px 9px 10px 9px;
}
th {
background: #cef;
}
td {
background: #eee;
}
td.empty {
background: #fbb;
}
td.blank {
background: #eee;
}
td.field {
background: #cef;
}
td.required {
background: #cfe;
}
td.allowed {
background: #cfe;
}
span.notfinal {
color: #f00;
font-size: 120%;
font-weight: bold;
}
pre {
margin: 5px;
padding: 15px;
background: #f4f4f4;
}
h1 {
margin-top: 60px;
}
li {
margin-top: 1rem;
}
</style>
</head>
<body>
<h1 id="amazon-states-language">Amazon States Language</h1>
<p>This document describes a <a href="https://tools.ietf.org/html/rfc8259" title="RFC 8259" rel="noopener noreferrer" target="_blank">JSON</a>-based
language used to describe state machines declaratively. The state machines thus
defined may be executed by software. In this document, the software is referred
to as "the interpreter".</p>
<p>Copyright © 2016-2024 Amazon.com Inc. or Affiliates.</p>
<p>Permission is hereby granted, free of charge, to any person obtaining a
copy of this specification and associated documentation files (the
"specification"), to use, copy, publish, and/or distribute, the
Specification subject to the following conditions:</p>
<p>The preceding copyright notice and this permission notice shall be included
in all copies of the Specification.</p>
<p>You may not modify, merge, sublicense, and/or sell copies of the
Specification.</p>
<p>THE SPECIFICATION IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SPECIFICATION OR THE USE OR OTHER DEALINGS IN THE SPECIFICATION.</p>
<p>Any sample code included in the Specification, unless otherwise
specified, is licensed under the Apache License, Version 2.0.</p>
<h2>Table of Contents</h2>
<nav id="TableOfContents">
<ul>
<li><a href="#structure-of-a-state-machine">Structure of a State Machine</a>
<ul>
<li><a href="#example">Example: Hello World</a></li>
<li><a href="#toplevelfields">Top-level fields</a></li>
</ul>
</li>
<li><a href="#concepts">Concepts</a>
<ul>
<li><a href="#states-fields">States</a></li>
<li><a href="#transition">Transitions</a></li>
<li><a href="#timestamps">Timestamps</a></li>
<li><a href="#data">Data</a></li>
<li><a href="#context-object">The Context Object</a></li>
<li><a href="#query-language">Query Languages</a></li>
<li><a href="#state-machine-variables">State Machine Variables</a></li>
</ul>
</li>
<li><a href="#jsonata-concepts">JSONata Concepts</a>
<ul>
<li><a href="#expressions">Expressions</a></li>
<li><a href="#reserved-states-variable-with-jsonata">Reserved "states" Variable with JSONata</a></li>
<li><a href="#input-and-output-processing-with-jsonata">Input and Output Processing with JSONata</a></li>
<li><a href="#jsonata-evaluation">JSONata Evaluation</a></li>
<li><a href="#jsonata-runtime-errors">JSONata Runtime Errors</a></li>
<li><a href="#jsonata-restrictions">JSONata Restrictions</a></li>
</ul>
</li>
<li><a href="#jsonpath-concepts">JSONPath Concepts</a>
<ul>
<li><a href="#path">Paths</a></li>
<li><a href="#ref-paths">Reference Paths</a></li>
<li><a href="#payload-template">Payload Template</a></li>
<li><a href="#intrinsic-functions">Intrinsic Functions</a></li>
<li><a href="#reserved-states-variable-with-jsonpath">Reserved "states" Variable with JSONPath</a></li>
<li><a href="#filters">Input and Output Processing with JSONPath</a></li>
</ul>
</li>
<li><a href="#error-handling">Error Handling</a>
<ul>
<li><a href="#errors">Errors</a></li>
<li><a href="#retrying-after-error">Retrying after error</a></li>
<li><a href="#fallback-states">Fallback states</a></li>
</ul>
</li>
<li><a href="#state-types">State Types</a>
<ul>
<li><a href="#state-type-table-jsonata">Table of State Types and Fields (JSONata)</a></li>
<li><a href="#state-type-table-jsonpath">Table of State Types and Fields (JSONPath)</a></li>
<li><a href="#pass-state">Pass State</a></li>
<li><a href="#task-state">Task State</a></li>
<li><a href="#choice-state">Choice State</a></li>
<li><a href="#wait-state">Wait State</a></li>
<li><a href="#succeed-state">Succeed State</a></li>
<li><a href="#fail-state">Fail State</a></li>
<li><a href="#parallel-state">Parallel State</a></li>
<li><a href="#map-state">Map State</a></li>
</ul>
</li>
<li><a href="#appendices">Appendices</a>
<ul>
<li><a href="#appendix-a">Appendix A: Predefined Error Codes</a></li>
<li><a href="#appendix-b">Appendix B: List of JSONPath Intrinsic Functions</a></li>
</ul>
</li>
<li><a href="#document-history">Document History</a>
<ul>
<li><a href="#november-22-2024">November 22, 2024</a></li>
<li><a href="#september-7-2023">September 7, 2023</a></li>
<li><a href="#2022-12-01">December 1, 2022</a></li>
<li><a href="#2022-11-18">November 18, 2022</a></li>
<li><a href="#2022-08-31">August 31, 2022</a></li>
<li><a href="#2020-08-11">August 11, 2020</a></li>
</ul>
</li>
</ul>
</nav>
<h2 id="structure-of-a-state-machine">Structure of a State Machine</h2>
<p>A State Machine is represented by a <a href="https://tools.ietf.org/html/rfc8259#section-4" title="RFC 8259 JSON Object" rel="noopener noreferrer" target="_blank">JSON
Object</a>.</p>
<h3 id="example">Example: Hello World</h3>
<p>The operation of a state machine is specified by states, which are
represented by JSON objects, fields in the top-level "States" object. In
this example, there is one state named "Hello World".</p>
<pre tabindex="0"><code class="language-statemachine" data-lang="statemachine">{
"Comment": "A simple minimal example of the States language",
"StartAt": "Hello World",
"States": {
"Hello World": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloWorld",
"End": true
}
}
}
</code></pre><p>When this state machine is launched, the interpreter begins execution by
identifying the Start State. It executes that state, and then checks to
see if the state is marked as an End State. If the state is an End State, the interpreter
terminates the machine and returns its result. If the state is not an End State, the
interpreter looks for a "Next" field, or a "Default" field in a Choice
State, to determine which state to execute
next; it repeats this process until the machine reaches a <a href="#terminal-state">Terminal
State</a> (Succeed, Fail, or an End State) or a runtime
error occurs.</p>
<p>In this example, the machine contains a single state named "Hello
World". Because "Hello World" is a Task State, the interpreter tries to
execute it. Examining the value of the "Resource" field shows that it
points to a Lambda function, so the interpreter attempts to invoke that
function. Assuming the Lambda function executes successfully, the
machine will terminate successfully.</p>
<h3 id="toplevelfields">Top-level fields</h3>
<p>A State Machine MUST have an object field named "States", whose fields
represent the states.</p>
<p>A State Machine MUST have a string field named "StartAt", whose value
MUST match exactly the name of one of the "States" fields. The interpreter
starts executing the machine at the named state.</p>
<p>A State Machine MAY have a string field named "QueryLanguage", which
provides the name of the <em>query language</em> used in the machine. A
query language is a language used to query, transform, or create JSON data. The
States Language supports JSONPath and JSONata, and if omitted, the
default value of "QueryLanguage" is "JSONPath". This document refers
to the value of the top-level "QueryLanguage" field as the "state
machine's query language".</p>
<p>A State Machine MAY have a string field named "Comment", to hold a
human-readable comment or description of the machine.</p>
<p>A State Machine MAY have a string field named "Version", which gives the
version of the States Language used in the machine. This document
describes version 1.0, and if omitted, the default value of "Version" is
"1.0".</p>
<p>A State Machine MAY have an integer field named "TimeoutSeconds". If
provided, it provides the maximum number of seconds the machine is
allowed to execute. If the machine executes longer than the specified time, then
the interpreter fails the machine with a <code>States.Timeout</code> <a href="#error-names">Error
Name</a>.</p>
<h2 id="concepts">Concepts</h2>
<h3 id="states-fields">States</h3>
<p>States describe tasks (units of work), or specify flow control (for
example, a Choice State) and are represented as fields of the
top-level "States" object. The state name is the JSON field name. The
state name MUST be unique within the scope of the entire state
machine, and its length MUST BE less than or equal to 80 Unicode
characters.</p>
<p>The following shows an example state definition:</p>
<pre tabindex="0"><code class="language-state" data-lang="state">"HelloWorld": {
"Type": "Task",
"QueryLanguage": "JSONPath",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloWorld",
"Next": "NextState",
"Comment": "Executes the HelloWorld Lambda function"
}
</code></pre><p>Note that:</p>
<ol>
<li>
<p>All states MUST have a "Type" field. This document refers to the
values of this field as a state’s <em>type</em>, and to a state such as the
one in the previous example as a Task State.</p>
</li>
<li>
<p>Any state MAY have a "Comment" field, to hold a human-readable
comment or description.</p>
</li>
<li>
<p>Any state MAY have a "QueryLanguage" field to override the state
machine's query language as specified in the top-level
"QueryLanguage" field. This document refers to the value of a
state's "QueryLanguage" field (or the state machine's query
language if not provided) as a "state's query language", and to a
state such as the one in the previous example as a JSONPath Task
State.</p>
</li>
<li>
<p>Most state types require additional fields as specified in this
document.</p>
</li>
<li>
<span id="terminal-state">Any state except for Choice, Succeed, and
Fail MAY have a field named "End" whose value MUST be a boolean. The term
"Terminal State" means a state with <code>{ "End": true }</code>, or a state with
<code>{ "Type": "Succeed" }</code>, or a state with <code>{ "Type": "Fail" }</code>.</span>
</li>
</ol>
<h3 id="transition">Transitions</h3>
<p>Transitions link states together, defining the control flow for the
state machine. After executing a non-terminal state, the interpreter
follows a transition to the next state. For most state types,
transitions are unconditional and specified through the state's "Next"
field.</p>
<p>All non-terminal states MUST have a "Next" field, except for the Choice
State. The value of the "Next" field MUST exactly and case-sensitively
match the name of another state.</p>
<p>States can have multiple incoming transitions from other states.</p>
<h3 id="timestamps">Timestamps</h3>
<p>The Choice and Wait States deal with JSON field values which represent
timestamps. These are strings which MUST conform to the
<a href="https://www.ietf.org/rfc/rfc3339.txt" title="RFC 3339" rel="noopener noreferrer" target="_blank">RFC3339</a> profile of ISO 8601,
with the further restrictions that an uppercase "T" character MUST be
used to separate date and time, and an uppercase "Z" character MUST be
present in the absence of a numeric time zone offset, for example
"2016-03-14T01:59:00Z".</p>
<h3 id="data">Data</h3>
<p>The interpreter passes data between states to perform calculations or to
dynamically control the state machine’s flow. All such data MUST be
expressed in JSON. This document uses the term "JSON text" as defined
in <a href="https://tools.ietf.org/html/rfc8259#section-2" title="RFC 8259 JSON Text" rel="noopener noreferrer" target="_blank">RFC 8259</a>
to refer to
data expressed in JSON.</p>
<p>When a state machine is started, the caller can provide an initial JSON
text as input, which is
passed to the machine's start state as input. If no input is provided,
the default is an empty JSON object, <code>{}</code>. As each state is executed, it
receives a JSON text as input and can produce arbitrary output, which
MUST be a JSON text. When two states are linked by a transition, the
output from the first state is passed as input to the second state. The
output from the machine's terminal state is treated as its output.</p>
<p>For example, consider a simple state machine that adds two numbers
together:</p>
<pre tabindex="0"><code class="language-statemachine" data-lang="statemachine">{
"StartAt": "Add",
"States": {
"Add": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:Add",
"End": true
}
}
}
</code></pre><p>Suppose the "Add" Lambda function is defined as:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">const</span> <span class="nx">handler</span> <span class="o">=</span> <span class="kr">async</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">event</span><span class="p">.</span><span class="nx">val1</span> <span class="o">+</span> <span class="nx">event</span><span class="p">.</span><span class="nx">val2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>Then if this state machine was started with the input
<code>{ "val1": 3, "val2": 4 }</code>, then the output would be the JSON text
consisting of the number <code>7</code>.</p>
<p>The usual constraints applying to JSON-encoded data apply. In
particular, note that:</p>
<ol>
<li>
<p>Numbers in JSON generally conform to JavaScript semantics, typically
corresponding to double-precision IEEE-854 values. For this and
other interoperability concerns, see <a href="https://tools.ietf.org/html/rfc8259" title="RFC 8259" rel="noopener noreferrer" target="_blank">RFC
8259</a>.</p>
</li>
<li>
<p>Standalone quote-delimited (") strings, booleans, and numbers are valid JSON
texts.</p>
</li>
</ol>
<h3 id="context-object">The Context Object</h3>
<p>The interpreter can provide information to an executing state machine
about the execution and other implementation details. This is delivered
in the form of a JSON object called the "Context Object". This version
of the States Language specification does not specify any contents of
the Context Object.</p>
<h3 id="query-language">Query Languages</h3>
<p>A query language is a language used to query, transform, or create JSON
text. A state machine's query language defaults to JSONPath.
The interpreter MUST support
<a href="https://github.com/jayway/JsonPath" title="JSONPath" rel="noopener noreferrer" target="_blank">JSONPath</a> and
<a href="https://jsonata.org/" title="JSONata" rel="noopener noreferrer" target="_blank">JSONata</a>, and MAY support others.</p>
<p>A state machine specifies its query language in the
<a href="#toplevelfields">top-level "QueryLanguage" field</a>, which overrides the default and sets the
query language for every state in the state machine. For example:</p>
<pre tabindex="0"><code class="language-statemachine" data-lang="statemachine">{
"QueryLanguage": "JSONata",
"StartAt": "Hello World",
"States": {
"Hello World": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloWorld",
"End": true
}
}
}
</code></pre><p>A state MAY have a "QueryLanguage" field to override the default. For
example:</p>
<pre tabindex="0"><code class="language-statemachine" data-lang="statemachine">{
"QueryLanguage": "JSONPath",
"StartAt": "JSONPath state",
"States": {
"JSONPath state": {
"Type": "Pass",
"Parameters": {
"total.$": "$.transaction.total"
},
"Next": "JSONata state"
},
"JSONata state": {
"Type": "Pass",
"QueryLanguage": "JSONata",
"Output": {
"total": "{% $states.input.transaction.total %}"
},
"End": true
}
}
}
</code></pre><p>The "JSONPath state" does not have a "QueryLanguage" field, so it
defaults to "JSONPath" as specified in the top-level "QueryLanguage" field. This state
contains a "Parameters" field which is specific to JSONPath, and which
contains JSONPath features and syntax.</p>
<p>The "JSONata state" has its own "QueryLanguage" field set to
"JSONata", so it overrides the state machine's
query language. This state contains an "Output" field which is
specific to JSONata, and which contains JSONata features and syntax.</p>
<p>If a Map or Parallel State has a "QueryLanguage" field, the default
query language for each state inside the Map's "ItemProcessor" or the
Parallel's "Branches" fields is the state machine's query language,
and is independent of the Map or Parallel State's query language.</p>
<p>The interpreter MAY restrict specific combinations of the top-level
"QueryLanguage" field and a state's "QueryLanguage" field.</p>
<p>This document describes the names, syntax, and semantics of fields
specific to JSONPath or JSONata. See
<a href="#jsonpath-concepts">JSONPath Concepts</a> and
<a href="#jsonata-concepts">JSONata Concepts</a> for details.</p>
<h3 id="state-machine-variables">State Machine Variables</h3>
<p>A state machine variable is a named JSON value. Instead of passing data
between states, a state can store data in a variable and reference it
in a later state.</p>
<p>Each variable name, whose length MUST BE less than or equal to 80
Unicode characters, MUST follow the rules for Unicode Identifiers as
described in
<a href="https://unicode.org/reports/tr31" title="Unicode Standard Annex 31" rel="noopener noreferrer" target="_blank">Unicode Standard Annex #31</a>. The
first character of a variable name MUST be a Unicode ID_Start
character, and the second and subsequent characters MUST be Unicode
ID_Continue characters.</p>
<p>This document uses the term "state machine variable" to describe a variable
assigned in a state using the <a href="#assigning-variables">"Assign" field</a>.
Some query languages, such as JSONata, support variable assignment
inside an expression, but a variable assigned inside an expression
does not affect the value of any state machine variable. The only
way a state can assign a value to a state machine variable is with the
"Assign" field.</p>
<p>Any state except Succeed and Fail MAY assign a value to one or more
state machine variables, and any state MAY reference the value of any
variable that has a value on state entry. All references to a state
machine variable in a state refer to the same value, which is the
value it had at state entry, as described in the
<a href="#variable-scope">Variable Scope section</a>.</p>
<p>This specification defines one reserved variable called "states" whose
value depends on the query language. A state MUST NOT assign a value
to "states".</p>
<p>In a JSONPath state, the "ResultPath" field MUST NOT reference a
variable.</p>
<h4 id="assigning-variables">Assigning State Machine Variables</h4>
<p>Any state except Succeed and Fail MAY have an "Assign" field at the
state's top level. Any Choice Rule in a
Choice State, and any Catcher in a Task, Map, or Parallel state, MAY
have an "Assign" field. An "Assign" field can
assign a value to one or more variables. The value of an "Assign"
field MUST be a JSON object; it has no required fields. The name of
each top-level field in the object names a variable to assign, and the
field's value provides its new value.</p>
<p>For example:</p>
<pre tabindex="0"><code class="language-state" data-lang="state">"FirstState": {
"Type": "Pass",
"Assign": {
"make": "Infiniti",
"model": "G35",
"year": 2006
},
"Next": "SecondState"
}
</code></pre><p>In this example, the state assigns <code>"Infiniti"</code> to the variable <code>make</code>,
<code>"G35"</code> to <code>model</code>, and <code>2006</code> to <code>year</code>. Any state that executes
after "FirstState" can reference these variables using a syntax that
depends on the query language. For JSONPath and JSONata, variables
are referenced by prepending the variable name with a "$", as in
<code>$make</code>, <code>$model</code>, and <code>$year</code>. In this example, the state uses
JSONata syntax to output a string that includes all three variable
values.</p>
<pre tabindex="0"><code class="language-state" data-lang="state">"SecondState": {
"Type": "Pass",
"QueryLanguage": "JSONata",
"Output": "{% $year & ' ' & $make & ' ' & $model %}",
"Next": "ThirdState"
}
</code></pre><p>In this example, the output of "SecondState" would be <code>"2006 Infiniti G35"</code>.</p>
<p>Any variable referenced in an "Assign" field sees its current value as
it was when the state was entered, and each variable's new value only takes
effect in the next state. For example:</p>
<pre tabindex="0"><code class="language-state" data-lang="state">"Assigning": {
"Type": "Pass",
"QueryLanguage": "JSONata",
"Assign": {
"x": 42,
"newOrOld": "{% $x %}"
},
"Next": "Referencing"
}
</code></pre><p>If variable <code>x</code> had the value <code>5</code> on state entry, the interpreter will
assign <code>42</code> to <code>x</code>, and <code>5</code> to <code>newOrOld</code>. The JSONata string for
<code>newOrOld</code> references <code>$x</code>, but the interpreter evaluates the
expression using the current value of <code>x</code>, which is <code>5</code>. The new
value of <code>x</code> (<code>42</code>) will only take effect in the next state.</p>
<h4 id="variable-scope">Variable Scope</h4>
<p>The interpreter places each variable into a state-machine-local scope,
which this document simply refers to as a <em>scope</em>. A
state-machine-local scope includes all states inside a "States" field,
not including states inside Parallel or Map states in that scope. For
example, the states inside a Map state's "States" field are in a
separate, inner scope from the Map state's scope. A variable exists
in a scope if any state in the scope assigns a value to it. A state
MAY reference the value of any variable in its scope that has a value on
state entry.</p>
<p>The interpreter maintains separate variable values for each
scope, including for each Parallel branch and Map
iteration. In a Parallel state, a state in one branch MUST NOT
reference any variable assigned in another branch. In a Map state, a
state in one iteration MUST NOT reference any variable assigned in
another iteration.</p>
<p>The interpreter MAY allow states in inner scopes to reference
variables from outer scopes. However, states in inner scopes MUST NOT
assign to a variable with the same name as a variable in an outer
scope. Put another way, the names of outer-scoped and inner-scoped
variables MUST be unique. For example:</p>
<pre tabindex="0"><code class="language-statemachine" data-lang="statemachine">{
"QueryLanguage": "JSONata",
"StartAt": "Get Greeting",
"States": {
"Get Greeting": {
"Type": "Pass",
"Assign": {
"outer": "hello"
},
"Next": "Greet Everyone"
},
"Greet Everyone": {
"Type": "Map",
"ItemProcessor": {
"StartAt": "Begin",
"States": {
"Begin": {
"Type": "Pass",
"Assign": {
"inner": "world",
"hi": "{% $outer %}"
},
"Next": "End"
},
"End": {
"Type": "Succeed",
"Output": "{% $hi %}"
}
}
},
"Assign": {
"outer": 2
},
"Next": "Goodbye"
},
"Goodbye": {
"Type": "Succeed",
"Output": "{% $outer %}"
}
}
}
</code></pre><p>In this example, variable <code>outer</code> is in the outer scope because it is
assigned in a state inside the top-level "States" field, and variables
<code>inner</code> and <code>hi</code> are in the inner scope because they are assigned in a
state inside the inner "States" field. The "Get Greeting" and "Greet
Everyone" states can both assign to <code>outer</code> because they are in the
same outer scope. State "Begin" can reference <code>outer</code>, but since it
is in the inner scope, it cannot assign it.</p>
<p>State "End" will output the string <code>hello</code>, and state "Goodbye" will
output the number <code>2</code>.</p>
<p>When a Parallel branch or Map iteration completes, its
variables go out of scope and are no longer accessible. Parallel
branches and Map iterations can return results to the outer scope
through the state output of one of its terminal states.</p>
<h2 id="jsonata-concepts">JSONata Concepts</h2>
<p>When a state's query language is JSONata, the interpreter supports
fields and syntax for querying and transforming data using JSONata.
For information about JSONPath, see
<a href="#jsonpath-concepts">JSONPath Concepts</a>.</p>
<h3 id="expressions">Expressions</h3>
<p>A JSONata expression can query, select, transform, and create JSON
data.</p>
<p>In the States Language, JSONata expressions are written inside strings
that start with <code>{%</code> and end with <code>%}</code>. The syntax of the text inside
the <code>{%</code> and <code>%}</code> delimiters is that of
<a href="https://jsonata.org/" title="JSONata" rel="noopener noreferrer" target="_blank">JSONata</a>. In JSONata,
any name that starts with "$" is a variable, so the value of <code>"{% $year %}"</code> is the current value of the <code>year</code> variable.
This document refers to <code>{% %}</code>-delimited JSONata expressions as
JSONata strings. When the interpreter evaluates a JSONata string, the
result is that of the JSONata expression inside the string.</p>
<p>JSONata has a built-in function library which JSONata expressions can
call, for example <code>"{% $sum($order.total) %}"</code>.
The interpreter MAY define other auxiliary JSONata functions and
values, and MAY restrict the use of built-in functions.</p>
<p>JSONata expressions can define their own functions, as with the
<code>$product</code> function in this calculation of 5 factorial:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">"{% ($product := function($x, $y) {$x * $y}; $reduce([1..5], $product)) %}"</span><span class="err">`</span>
</span></span></code></pre></div><p>A variable assigned inside a JSONata expression does not affect the
value of any state machine variable. Put another way, the only way to
assign a value to a state machine variable is with the "Assign" field.</p>
<h3 id="reserved-states-variable-with-jsonata">Reserved "states" Variable with JSONata</h3>
<p>The States Language reserves one variable called "states". When the
query language is JSONata, the "states" variable is defined as a JSON
object containing fields defined by the interpreter as it executes
each state. A state MUST NOT assign a value to "states".</p>
<p>The "states" variable is a JSON object containing these fields:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"input"</span><span class="p">:</span> <span class="c1">// The state input
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="s2">"result"</span><span class="p">:</span> <span class="c1">// The state's result
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="s2">"errorOutput"</span><span class="p">:</span> <span class="c1">// The Error Output in a Catch
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="s2">"context"</span><span class="p">:</span> <span class="c1">// The Context Object
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span></code></pre></div><p><code>$states.input</code> refers to the state input, and <code>$states.context</code>
refers to the <a href="#context-object">Context Object</a>, both of which can be
referenced in any field that accepts JSONata.</p>
<p><code>$states.result</code> refers to the result that a Task, Map, or Parallel
state returns, and can be referenced in the state's top-level "Output" and "Assign"
fields.</p>
<p><code>$states.errorOutput</code> refers to the <a href="#error-output">Error Output</a> the
interpreter generates when a Task, Map, or Parallel state reports an
error, and can be referenced in a Catcher's "Output" and "Assign" fields.</p>
<p>For example:</p>
<pre tabindex="0"><code class="language-state" data-lang="state">"My Task": {
"Type": "Task",
"QueryLanguage": "JSONata",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloWorld",
"Output": {
"customer": "{% $states.input.customer %}",
"resultStatus": "{% $states.result.status %}",
"elapsedTime": "{% $states.context.ElapsedTime %}"
},
"Catch": [
{
"ErrorEquals": ["States.ALL"],
"Output": {
"errorDetails": "{% $states.errorOutput %}",
"input": "{% $states.input %}"
},
"Next": "Handle Error"
}
],
"End": true
}
</code></pre><p>If the HelloWorld function succeeds, the state will output the JSON
object specified by the state's top-level "Output" field, containing the value
of the <code>customer</code> field from the state input, the <code>status</code> field from
the result of executing the HelloWorld function, and the <code>ElapsedTime</code>
field from the interpreter-defined Context Object.</p>
<p>If the HelloWorld function reports an error, the state will output the
JSON object specified by the Catcher's "Output" field,
which has an "errorDetails" field whose value is the Error Output, and an
"input" field whose value is the state input. See
<a href="#error-handling">Error Handling</a> for
details.</p>
<h3 id="input-and-output-processing-with-jsonata">Input and Output Processing with JSONata</h3>
<p>As described earlier, data is passed between states as JSON texts. A
state may need to control the format and content of the data it passes
to the external code of a Task State or the branches of a Parallel
State, or of the data it passes on as output. Fields named
"Arguments" and "Output" exist to support this.</p>
<p>Any state except Fail MAY have "Output".</p>
<p>Task and Parallel States MAY have "Arguments".</p>
<h4 id="arguments-and-output">Using Arguments and Output</h4>
<p>In this discussion, "state input" means the JSON text that is the
input to a state, "arguments" means the result of evaluating the
"Arguments" field, "result" means the JSON text that a state
generates, for example from external code invoked by a Task State, or
the combined result of the branches in a Parallel or Map State, and
"state output" means the final state output after processing the
result with the "Output" field.</p>
<p>The interpreter dispatches data as input to tasks to do
useful work, and receives output back from them. A common requirement
is to reshape input data to meet the format expectations of
tasks, and similarly to reshape the output coming back.</p>
<p>In the Task and Parallel States, the input to tasks is the value
of the "Arguments" field, and the result can be reshaped with the
"Output" field.</p>
<ol>
<li>
<p>The value of "Arguments" MUST be a JSON text, or a JSONata string
that evaluates to a JSON text. If the "Arguments" field is
provided, its result becomes the arguments to the external code
invoked by a Task State, or the branches of a Parallel
State. If not provided, the arguments are the state input.
"Arguments" MAY reference <code>$states.input</code> and <code>$states.context</code>,
but MUST NOT reference <code>$states.result</code> or <code>$states.errorOutput</code>.</p>
</li>
<li>
<p>The value of "Output" MUST be a JSON text, or a JSONata string
that evaluates to a JSON text. If the "Output" field is provided,
its result becomes the state output, which serves as the state
input for the next state. If not provided, the state output is
the result in a Task, Map, and Parallel State, or the state input
in all other states. In all states, "Output" MAY reference
<code>$states.input</code> and <code>$states.context</code>. In Task, Map, and Parallel
States, the state's top-level "Output" field MAY reference <code>$states.result</code>,
and the Catcher's "Output" field MAY reference <code>$states.errorOutput</code>.</p>
</li>
</ol>
<h4 id="using-assign">Using Assign</h4>
<p>The value of an "Assign" field MUST be a JSON object; it has no
required fields. The name of each top-level field in the object names
a variable to assign, and the field's value provides its new value.</p>
<p>If an "Assign" field is provided, the interpreter first evaluates the
new value for each variable, and then performs the assignments. Any
variable referenced in an "Assign" field sees its current value as it
was when the state was entered, and each variable's new value only takes
effect in the next state.</p>
<p>In all states, "Assign" MAY reference <code>$states.input</code> and
<code>$states.context</code>. In Task, Map, and Parallel States, the state's top-level "Assign"
field MAY reference <code>$states.result</code>, and the Catcher's "Assign" field
MAY reference <code>$states.errorOutput</code>.</p>
<h3 id="jsonata-evaluation">JSONata Evaluation</h3>
<p>In any field that accepts JSONata, if its
value, or any value nested inside a JSON object or array, is a JSONata
string, the interpreter evaluates the JSONata expression and then
replaces it with the result.</p>
<p>For example, suppose a state assigns these variables:</p>
<pre tabindex="0"><code class="language-state" data-lang="state">"GetSampleData": {
"Type": "Pass",
"Assign": {
"student": {
"name": "Scotland",
"course": [
{ "grade": 34 },
{ "grade": 99 },
{ "grade": 76 },
{ "grade": 96 }
]
},
"class": {
"teacher": "Bert"
},
"two": "the number 2"
},
"Next": "A Task"
}
</code></pre><p>And the next state references the variables in its "Arguments" and
"Output" fields:</p>
<pre tabindex="0"><code class="language-state" data-lang="state">"A Task": {
"Type": "Task",
"QueryLanguage": "JSONata",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:DoTheTask",
"Arguments": {
"student": "{% $student.name %}",
"classInfo": {
"teacher": "{% $class.teacher %}"
},
"values": [ 1, "{% $two %}", "three" ]
},
"Output": "{% { 'avg': $average($student.course.grade), 'num': $count($student.course) } %}",
"Next": "Process the result"
}
</code></pre><p>In this case, the "Arguments" field specifies a JSON object that
contains JSONata strings for some of its fields and array items,
and the "Output" field specifies a single JSONata string to create
the entire value. In other words, JSONata can be used to calculate
the entire value of a field, or individual parts of it.</p>
<p>The interpreter will first evaluate the JSONata expressions inside the
"Arguments" object including field values and array items, and send
the resulting object to the DoTheTask function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"student"</span><span class="p">:</span> <span class="s2">"Scotland"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"classInfo"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"teacher"</span><span class="p">:</span> <span class="s2">"Bert"</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"values"</span><span class="p">:</span> <span class="p">[</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">"the number 2"</span><span class="p">,</span> <span class="s2">"three"</span> <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>After DoTheTask returns, the interpreter will evaluate the "Output"
field and return this JSON object:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"avg"</span><span class="p">:</span> <span class="mf">76.25</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"num"</span><span class="p">:</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="jsonata-runtime-errors">JSONata Runtime Errors</h3>
<p>A JSONata expression can fail for different reasons. For example:</p>
<p>A JSONata expression may cause a type error, for example <code>"{% $x + $y %}"</code> if <code>$x</code> or <code>$y</code> is not a number.</p>
<p>A JSONata expression may evaluate to a type the field will not
accept, for example <code>"TimeoutSeconds": "{% $name %}"</code> in a Task State if <code>$name</code> is a
string, because TimeoutSeconds requires a number.</p>
<p>A JSONata expression may evaluate to a value the field will not
accept, for example <code>"ToleratedFailurePercentage": "{% $negative %}"</code> if
<code>$negative</code> evaluates to a negative number, because
ToleratedFailurePercentage requires a number between zero and 100.</p>
<p>A JSONata expression may fail to return a result, for example <code>"{% $data.thisFieldDoesNotExist %}"</code>, which is an error because JSON
cannot represent an undefined value.</p>
<p>In each case, the interpreter will throw
"States.QueryEvaluationError". Task, Map, and Parallel states MAY use
a Retrier to retry on the error, and a Catcher to catch
the error. See <a href="#error-handling">Error Handling</a> for details.</p>
<h3 id="jsonata-restrictions">JSONata Restrictions</h3>
<p>The States Language places some restrictions on JSONata expressions.</p>
<p>Unrestricted JSONata expressions can reference an implicitly-supplied
"input document" using unqualified field names and two built-in
variables called "$" and "$$". The States Language does not
implicitly provide an input document, so JSONata expressions cannot
use "$", "$$", or unqualified field names to reference it. Instead, a
JSONata expression MUST reference data through state machine variables.</p>
<p>The variable "$" or an unqualified field name at the top level of a
JSONata expression, for example <code>$</code>, <code>$.total</code>, or <code>total</code>, refers to the
input document, but "$" or an unqualified field name nested inside an
expression, for example <code>$order[$.total > 10]</code> or <code>$order[total > 10]</code>,
refers to the contextual value at that point in the evaluation. In
the States Language, a JSONata expression MUST NOT reference "$" or
unqualified field names at the top level, but MAY reference "$" or
unqualified field names nested inside an expression.</p>
<p>Since the variable "$$" always refers to the entire input document, a
JSONata expression MUST NOT reference "$$".</p>
<h2 id="jsonpath-concepts">JSONPath Concepts</h2>
<p>When a state sets the query language to JSONPath, the interpreter
supports fields and syntax for querying data using JSONPath paths.
For information about JSONata, see
<a href="#jsonata-concepts">JSONata Concepts</a>.</p>
<h3 id="path">Paths</h3>
<p>A Path is a string, beginning with "$", used to identify components
within a JSON text. The syntax is that of
<a href="https://github.com/jayway/JsonPath" title="JSONPath" rel="noopener noreferrer" target="_blank">JSONPath</a>.</p>
<p>When a Path begins with "$$", two dollar signs, this signals that it
is intended to identify content within the Context Object. The first
dollar sign is stripped, and the remaining text, which begins with a
dollar sign, is interpreted as the JSONPath applying to the Context
Object.</p>
<h3 id="ref-paths">Reference Paths</h3>
<p>A Reference Path is a Path with syntax limited in such a way that it can
only identify a single node in a JSON structure: the operators "@", ",",
":", and "?" are not supported - all Reference Paths MUST be unambiguous
references to a single value, array, or object (subtree).</p>
<p>For example, if state input data contained the values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"foo"</span><span class="p">:</span> <span class="mi">123</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"bar"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"car"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"cdr"</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Then the following Reference Paths would return:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">$.foo => 123
</span></span><span class="line"><span class="cl">$.bar => ["a", "b", "c"]
</span></span><span class="line"><span class="cl">$.car.cdr => true
</span></span></code></pre></div><p>Paths and Reference Paths are used by certain states, as specified later
in this document, to control the flow of a state machine or to configure
a state's settings or options.</p>
<p>Here are some examples of acceptable Reference Path syntax:</p>
<pre tabindex="0"><code class="language-nocheck" data-lang="nocheck">$.store.book
$.store\.book
$.\stor\e.boo\k
$.store.book.title
$.foo.\.bar
$.foo\@bar.baz\[\[.\?pretty
$.&Ж中.\uD800\uDF46
$.ledgers.branch[0].pending.count
$.ledgers.branch[0]
$.ledgers[0][22][315].foo
$['store']['book']
$['store'][0]['book']
</code></pre><h3 id="payload-template">Payload Template</h3>
<p>The interpreter dispatches data as input to tasks to do
useful work, and receives output back from them. A common requirement
is to reshape input data to meet the format expectations of tasks,
and similarly to reshape the output coming back. A JSON object structure
called a Payload Template is provided for this purpose.</p>
<p>In the Task, Map, Parallel, and Pass States, the Payload Template is the
value of a field named "Parameters". In the Task, Map, and Parallel
States, there is another Payload Template which is the value of a field
named "ResultSelector".</p>
<p>A Payload Template MUST be a JSON object; it has no required fields. The
interpreter processes the Payload Template as described in this section;
the result of that processing is called the payload.</p>
<p>To illustrate by example, the Task State has a field named "Parameters"
whose value is a Payload Template. Consider the following Task State:</p>
<pre tabindex="0"><code class="language-state" data-lang="state">"X": {
"Type": "Task",
"Resource": "arn:aws:states:us-east-1:123456789012:task:X",
"Next": "Y",
"Parameters": {
"first": 88,
"second": 99
}
}
</code></pre><p>In this case, the payload is the object with "first" and "second" fields
whose values are respectively 88 and 99. No processing needs to be
performed and the payload is identical to the Payload Template.</p>
<p>Values from the Payload Template’s input and the Context Object can be
inserted into the payload with a combination of a field-naming
convention, Paths and Intrinsic Functions.</p>
<p>If any field within the Payload Template (however deeply nested) has a
name ending with the characters ".$", its value is transformed
according to the following rules and the field is renamed to strip the ".$"
suffix.</p>
<p>If the field value begins with only one "$", the value MUST be a Path.
In this case, the Path is applied to the Payload Template’s input and is
the new field value.</p>
<p>If the field value begins with "$$", the first dollar sign is stripped
and the remainder MUST be a Path. In this case, the Path is applied to
the Context Object and is the new field value.</p>
<p>If the field value does not begin with "$", it MUST be an Intrinsic
Function (<a href="#intrinsic-functions">see Intrinsic Functions</a>). The interpreter invokes the Intrinsic Function and
the result is the new field value.</p>
<p>If the path is legal but cannot be applied successfully, the interpreter
fails the machine execution with an Error Name of
"States.ParameterPathFailure". If the Intrinsic Function fails during
evaluation, the interpreter fails the machine execution with an Error
Name of "States.IntrinsicFailure".</p>
<p>A JSON object MUST NOT have duplicate field names after fields ending
with the characters ".$" are renamed to strip the ".$" suffix.</p>
<pre tabindex="0"><code class="language-state" data-lang="state">"X": {
"Type": "Task",
"Resource": "arn:aws:states:us-east-1:123456789012:task:X",
"Next": "Y",
"Parameters": {
"flagged": true,
"parts": {
"first.$": "$.vals[0]",
"last3.$": "$.vals[-3:]"
},
"weekday.$": "$$.DayOfWeek",
"formattedOutput.$": "States.Format('Today is {}', $$.DayOfWeek)"
}
}
</code></pre><p>Suppose that the input to the P is as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"flagged"</span><span class="p">:</span> <span class="mi">7</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"vals"</span><span class="p">:</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">50</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Further, suppose that the Context Object is as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"DayOfWeek"</span><span class="p">:</span> <span class="s2">"TUESDAY"</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>In this case, the effective input to the code identified in the
"Resource" field would be as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"flagged"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"parts"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"first"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"last3"</span><span class="p">:</span> <span class="p">[</span><span class="mi">30</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">50</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"weekday"</span><span class="p">:</span> <span class="s2">"TUESDAY"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"formattedOutput"</span><span class="p">:</span> <span class="s2">"Today is TUESDAY"</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="intrinsic-functions">Intrinsic Functions</h3>
<p>The States Language provides a small number of "Intrinsic Functions", constructs
which look like functions in programming languages and can be used to help
Payload Templates process the data going to and from Task Resources. See
<a href="#appendix-b">Appendix B</a> for a full list of
Intrinsic Functions</p>
<p>Here is an example of an Intrinsic Function named "States.Format"
being used to prepare data:</p>
<pre tabindex="0"><code class="language-state" data-lang="state">"X": {
"Type": "Task",
"Resource": "arn:aws:states:us-east-1:123456789012:task:X",
"Next": "Y",
"Parameters": {
"greeting.$": "States.Format('Welcome to {} {}\\'s playlist.', $.firstName, $.lastName)"
}
}
</code></pre><ol>
<li>
<p>An Intrinsic Function MUST be a string.</p>
</li>
<li>
<p>The Intrinsic Function MUST begin with an Intrinsic Function name.
An Intrinsic Function name MUST contain only the characters A
through Z, a through z, 0 through 9, ".", and "_".</p>
<p>All Intrinsic Functions defined by this specification have names
that begin with "States.". The interpreter MAY define its
own Intrinsic Functions whose names MUST NOT begin with "States.".</p>
</li>
<li>
<p>The Intrinsic Function name MUST be followed immediately by a list
of zero or more arguments, enclosed by "(" and ")", and separated by
commas.</p>
</li>
<li>
<p>Intrinsic Function arguments may be strings enclosed by apostrophe
(<code>'</code>) characters, numbers, null, Paths, or nested Intrinsic
Functions.</p>
</li>
<li>
<p>The value of a string, number or null argument is the argument
itself. The value of an argument which is a Path is the result of
applying it to the input of the Payload Template. The value of an
argument which is an Intrinsic Function is the result of the
function invocation."</p>
<p>Note that in the previous example, the first argument of
<code>States.Format</code> could have been a Path that yielded the formatting
template string.</p>
</li>
<li>
<p>The following characters are reserved for all Intrinsic Functions
and MUST be escaped: ' { } \</p>
<p>If any of the reserved characters needs to appear as part of the
value without serving as a reserved character, it MUST be escaped
with a backslash.</p>
<p>If the character "\ needs to appear as part of the value without
serving as an escape character, it MUST be escaped with a backslash.</p>
<p>The literal string <code>\'</code> represents <code>'</code>.<br>
The literal string <code>\{</code> represents <code>{</code>.<br>
The literal string <code>\}</code> represents <code>}</code>.<br>
The literal string <code>\\</code> represents <code>\</code>.</p>
<p>In JSON, all backslashes contained in a string literal value must be
escaped with another backslash, therefore, the preceding sequences will equate to:</p>
<p>The escaped string <code>\\'</code> represents <code>'</code>.<br>