1
1
![ Node CI] ( https://github.com/serverlessworkflow/sdk-typescript/workflows/Node%20CI/badge.svg ) [ ![ Gitpod ready-to-code] ( https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod )] ( https://gitpod.io/#https://github.com/serverlessworkflow/sdk-typescript )
2
2
3
+ - [ Serverless Workflow Specification - TypeScript SDK] ( #serverless-workflow-specification---typescript-sdk )
4
+ - [ Status] ( #status )
5
+ - [ SDK Structure] ( #sdk-structure )
6
+ - [ Types and Interfaces] ( #types-and-interfaces )
7
+ - [ Classes] ( #classes )
8
+ - [ Fluent Builders] ( #fluent-builders )
9
+ - [ Validation Function] ( #validation-function )
10
+ - [ Other tools] ( #other-tools )
11
+ - [ Getting Started] ( #getting-started )
12
+ - [ Installation] ( #installation )
13
+ - [ Usage] ( #usage )
14
+ - [ Create a Workflow Definition from YAML or JSON] ( #create-a-workflow-definition-from-yaml-or-json )
15
+ - [ Create a Workflow Definition by Casting an Object] ( #create-a-workflow-definition-by-casting-an-object )
16
+ - [ Create a Workflow Definition Using a Class Constructor] ( #create-a-workflow-definition-using-a-class-constructor )
17
+ - [ Create a Workflow Definition Using the Builder API] ( #create-a-workflow-definition-using-the-builder-api )
18
+ - [ Serialize a Workflow Definition to YAML or JSON] ( #serialize-a-workflow-definition-to-yaml-or-json )
19
+ - [ Validate Workflow Definitions] ( #validate-workflow-definitions )
20
+ - [ Generate a directed graph] ( #generate-a-directed-graph )
21
+ - [ Generate a MermaidJS flowchart] ( #generate-a-mermaidjs-flowchart )
22
+ - [ Building Locally] ( #building-locally )
23
+
3
24
# Serverless Workflow Specification - TypeScript SDK
4
25
5
26
This SDK provides a TypeScript API for working with the [ Serverless Workflow Specification] ( https://github.com/serverlessworkflow/specification ) .
@@ -14,7 +35,7 @@ The npm [`@serverlessworkflow/sdk`](https://www.npmjs.com/package/@serverlesswor
14
35
15
36
| Latest Releases | Conformance to Spec Version |
16
37
| :---: | :---: |
17
- | [ v1.0.0. \* ] ( https://github.com/serverlessworkflow/sdk-typescript/releases/ ) | [ v1.0.0] ( https://github.com/serverlessworkflow/specification ) |
38
+ | [ v1.0.\* ] ( https://github.com/serverlessworkflow/sdk-typescript/releases/ ) | [ v1.0.0] ( https://github.com/serverlessworkflow/specification ) |
18
39
19
40
> [ !WARNING]
20
41
> Previous versions of the SDK were published with a typo in the scope:
@@ -56,6 +77,9 @@ The SDK includes a validation function to check if objects conform to the expect
56
77
57
78
The ` validate ` function is directly exported and can be used as ` validate('Workflow', workflowObject) ` .
58
79
80
+ ### Other Tools
81
+ The SDK also ships tools to build directed graph and MermaidJS flowcharts from a workflow.
82
+
59
83
## Getting Started
60
84
61
85
### Installation
86
110
set:
87
111
variable: 'my first workflow'
88
112
` ;
89
- const workflowDefinition = Classes .Workflow .deserialize (text );
113
+ const workflow = Classes .Workflow .deserialize (text );
90
114
```
91
115
92
116
#### Create a Workflow Definition by Casting an Object
@@ -96,7 +120,7 @@ You can type-cast an object to match the structure of a workflow definition:
96
120
import { Classes , Specification , validate } from ' @serverlessworkflow/sdk' ;
97
121
98
122
// Simply cast an object:
99
- const workflowDefinition = {
123
+ const workflow = {
100
124
document: {
101
125
dsl: ' 1.0.0' ,
102
126
name: ' test' ,
@@ -116,9 +140,9 @@ const workflowDefinition = {
116
140
117
141
// Validate it
118
142
try {
119
- validate (' Workflow' , workflowDefinition );
143
+ validate (' Workflow' , workflow );
120
144
// Serialize it
121
- const definitionTxt = Classes .Workflow .serialize (workflowDefinition );
145
+ const definitionTxt = Classes .Workflow .serialize (workflow );
122
146
}
123
147
catch (ex ) {
124
148
// Invalid workflow definition
@@ -132,7 +156,7 @@ You can create a workflow definition by calling a constructor:
132
156
import { Classes , validate } from ' @serverlessworkflow/sdk' ;
133
157
134
158
// Simply use the constructor
135
- const workflowDefinition = new Classes .Workflow ({
159
+ const workflow = new Classes .Workflow ({
136
160
document: {
137
161
dsl: ' 1.0.0' ,
138
162
name: ' test' ,
@@ -149,7 +173,7 @@ const workflowDefinition = new Classes.Workflow({
149
173
},
150
174
*/ ],
151
175
});
152
- workflowDefinition .do .push ({
176
+ workflow .do .push ({
153
177
step1: new Classes .SetTask ({
154
178
set: {
155
179
variable: ' my first workflow' ,
@@ -159,9 +183,9 @@ workflowDefinition.do.push({
159
183
160
184
// Validate it
161
185
try {
162
- workflowDefinition .validate ();
186
+ workflow .validate ();
163
187
// Serialize it
164
- const definitionTxt = workflowDefinition .serialize ();
188
+ const definitionTxt = workflow .serialize ();
165
189
}
166
190
catch (ex ) {
167
191
// Invalid workflow definition
@@ -174,7 +198,7 @@ You can use the fluent API to build a validated and normalized workflow definiti
174
198
``` typescript
175
199
import { documentBuilder , setTaskBuilder , taskListBuilder , workflowBuilder } from ' @serverlessworkflow/sdk' ;
176
200
177
- const workflowDefinition = workflowBuilder (/* workflowDefinitionObject */ )
201
+ const workflow = workflowBuilder (/* workflowObject */ )
178
202
.document (
179
203
documentBuilder ()
180
204
.dsl (' 1.0.0' )
@@ -206,12 +230,12 @@ You can serialize a workflow definition either by using its `serialize` method i
206
230
``` typescript
207
231
import { Classes } from ' @serverlessworkflow/sdk' ;
208
232
209
- // const workflowDefinition = <Your preferred method>;
210
- if (workflowDefinition instanceof Classes .Workflow ) {
211
- const yaml = workflowDefinition .serialize (/* 'yaml' | 'json' */ );
233
+ // const workflow = <Your preferred method>;
234
+ if (workflow instanceof Classes .Workflow ) {
235
+ const yaml = workflow .serialize (/* 'yaml' | 'json' */ );
212
236
}
213
237
else {
214
- const json = Classes .Workflow .serialize (workflowDefinition , ' json' );
238
+ const json = Classes .Workflow .serialize (workflow , ' json' );
215
239
}
216
240
```
217
241
> [ !NOTE]
@@ -223,20 +247,114 @@ Validation can be achieved in two ways: via the `validate` function or the insta
223
247
``` typescript
224
248
import { Classes , validate } from ' @serverlessworkflow/sdk' ;
225
249
226
- // const workflowDefinition = <Your preferred method>;
250
+ const workflow = /* <Your preferred method> */ ;
227
251
try {
228
- if (workflowDefinition instanceof Classes .Workflow ) {
229
- workflowDefinition .validate ();
252
+ if (workflow instanceof Classes .Workflow ) {
253
+ workflow .validate ();
230
254
}
231
255
else {
232
- validate (' Workflow' , workflowDefinition );
256
+ validate (' Workflow' , workflow );
233
257
}
234
258
}
235
259
catch (ex ) {
236
260
// Workflow definition is invalid
237
261
}
238
262
```
239
263
264
+ #### Generate a directed graph
265
+ A [ directed graph] ( https://en.wikipedia.org/wiki/Directed_graph ) of a workflow can be generated using the ` buildGraph ` function, or alternatives:
266
+ - Workflow instance ` .toGraph(); `
267
+ - Static ` Classes.Workflow.toGraph(workflow) `
268
+
269
+ ``` typescript
270
+ import { buildGraph } from ' @serverlessworkflow/sdk' ;
271
+
272
+ const workflow = {
273
+ document: {
274
+ dsl: ' 1.0.0' ,
275
+ name: ' using-plain-object' ,
276
+ version: ' 1.0.0' ,
277
+ namespace: ' default' ,
278
+ },
279
+ do: [
280
+ {
281
+ step1: {
282
+ set: {
283
+ variable: ' my first workflow' ,
284
+ },
285
+ },
286
+ },
287
+ ],
288
+ };
289
+ const graph = buildGraph (workflow );
290
+ // const workflow = new Classes.Workflow({...}); const graph = workflow.toGraph();
291
+ // const graph = Classes.Workflow.toGraph(workflow);
292
+ /* {
293
+ id: 'root',
294
+ type: 'root',
295
+ label: undefined,
296
+ parent: null,
297
+ nodes: [...], // length 3 - root entry node, step1 node, root exit node
298
+ edges: [...], // length 2 - entry to step1, step1 to exit
299
+ entryNode: {...}, // root entry node
300
+ exitNode: {...} // root exit node
301
+ }*/
302
+ ```
303
+
304
+ #### Generate a MermaidJS flowchart
305
+ Generating a [ MermaidJS] ( https://mermaid.js.org/ ) flowchart can be achieved in two ways: using the ` convertToMermaidCode ` , the legacy ` MermaidDiagram ` class, or alternatives:
306
+ - Workflow instance ` .toMermaidCode(); `
307
+ - Static ` Classes.Workflow.toMermaidCode(workflow) `
308
+
309
+ ``` typescript
310
+ import { convertToMermaidCode , MermaidDiagram } from ' @serverlessworkflow/sdk' ;
311
+
312
+ const workflow = {
313
+ document: {
314
+ dsl: ' 1.0.0' ,
315
+ name: ' using-plain-object' ,
316
+ version: ' 1.0.0' ,
317
+ namespace: ' default' ,
318
+ },
319
+ do: [
320
+ {
321
+ step1: {
322
+ set: {
323
+ variable: ' my first workflow' ,
324
+ },
325
+ },
326
+ },
327
+ ],
328
+ };
329
+ const mermaidCode = convertToMermaidCode (workflow ) /* or */ ;
330
+ // const mermaidCode = new MermaidDiagram(workflow).sourceCode();
331
+ // const workflow = new Classes.Workflow({...}); const mermaidCode = workflow.toMermaidCode();
332
+ // const mermaidCode = Classes.Workflow.toMermaidCode(workflow);
333
+ /*
334
+ flowchart TD
335
+ root-entry-node(( ))
336
+ root-exit-node((( )))
337
+ /do/0/step1["step1"]
338
+ /do/0/step1 --> root-exit-node
339
+ root-entry-node --> /do/0/step1
340
+
341
+
342
+ classDef hidden display: none;
343
+ */
344
+ ```
345
+
346
+ ``` mermaid
347
+ flowchart TD
348
+ root-entry-node(( ))
349
+ root-exit-node((( )))
350
+ /do/0/step1["step1"]
351
+ /do/0/step1 --> root-exit-node
352
+ root-entry-node --> /do/0/step1
353
+
354
+
355
+ classDef hidden display: none;
356
+ ```
357
+
240
358
### Building Locally
241
359
242
360
To build the project and run tests locally, use the following commands:
0 commit comments