sfn-diagram 0.6.0 → 1.0.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.
- package/README.md +291 -25
- package/dist/aws.cjs +52 -0
- package/dist/aws.d.cts +36 -0
- package/dist/aws.d.ts +36 -0
- package/dist/aws.js +51 -0
- package/dist/cfn.cjs +207 -0
- package/dist/cfn.d.cts +102 -0
- package/dist/cfn.d.ts +102 -0
- package/dist/cfn.js +206 -0
- package/dist/cli.js +607 -34
- package/dist/index.cjs +768 -46
- package/dist/index.d.cts +645 -698
- package/dist/index.d.ts +645 -698
- package/dist/index.js +764 -47
- package/dist/png.cjs +139 -9
- package/dist/png.d.cts +132 -102
- package/dist/png.d.ts +132 -102
- package/dist/png.js +139 -9
- package/package.json +48 -7
package/README.md
CHANGED
|
@@ -8,11 +8,62 @@ Generate beautiful, interactive diagrams from AWS Step Functions ASL (Amazon Sta
|
|
|
8
8
|
|
|
9
9
|
**▶ [Try it in the live playground](https://yusufaf.github.io/sfn-diagram/)** — paste any ASL definition and preview the diagram instantly, no install required.
|
|
10
10
|
|
|
11
|
+
## What it looks like
|
|
12
|
+
|
|
13
|
+
Give it an ASL definition like this order-processing workflow ([`examples/order-processing.asl.json`](examples/order-processing.asl.json)):
|
|
14
|
+
|
|
15
|
+
```jsonc
|
|
16
|
+
{
|
|
17
|
+
"StartAt": "ValidateOrder",
|
|
18
|
+
"States": {
|
|
19
|
+
"ValidateOrder": { "Type": "Pass", "Next": "CheckStock" },
|
|
20
|
+
"CheckStock": {
|
|
21
|
+
"Type": "Choice",
|
|
22
|
+
"Choices": [{ "Variable": "$.inStock", "BooleanEquals": true, "Next": "ChargePayment" }],
|
|
23
|
+
"Default": "CancelOrder"
|
|
24
|
+
},
|
|
25
|
+
"ChargePayment": { "Type": "Task", "Resource": "arn:aws:lambda:...:charge-payment", "Next": "ShipOrder" },
|
|
26
|
+
"ShipOrder": { "Type": "Task", "Resource": "arn:aws:lambda:...:ship-order", "Next": "OrderComplete" },
|
|
27
|
+
"CancelOrder": { "Type": "Fail", "Error": "OutOfStock" },
|
|
28
|
+
"OrderComplete": { "Type": "Succeed" }
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
…and `generateMermaid` turns it into a diagram GitHub renders inline (the same code also drives SVG and PNG output):
|
|
34
|
+
|
|
35
|
+
```mermaid
|
|
36
|
+
stateDiagram-v2
|
|
37
|
+
|
|
38
|
+
[*] --> ValidateOrder
|
|
39
|
+
ValidateOrder --> CheckStock
|
|
40
|
+
CheckStock --> ChargePayment: $.inStock == true
|
|
41
|
+
CheckStock --> CancelOrder: Default
|
|
42
|
+
ChargePayment --> ShipOrder
|
|
43
|
+
ShipOrder --> OrderComplete
|
|
44
|
+
|
|
45
|
+
CancelOrder --> [*]
|
|
46
|
+
OrderComplete --> [*]
|
|
47
|
+
|
|
48
|
+
classDef successState fill:#e8f5e8,stroke:#4caf50,stroke-width:3px
|
|
49
|
+
classDef failState fill:#ffebee,stroke:#f44336,stroke-width:3px
|
|
50
|
+
classDef choiceState fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
|
|
51
|
+
classDef taskState fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
|
|
52
|
+
|
|
53
|
+
class CheckStock choiceState
|
|
54
|
+
class ChargePayment taskState
|
|
55
|
+
class ShipOrder taskState
|
|
56
|
+
class CancelOrder failState
|
|
57
|
+
class OrderComplete successState
|
|
58
|
+
```
|
|
59
|
+
|
|
11
60
|
## Features
|
|
12
61
|
|
|
13
62
|
- **Multiple Output Formats**: SVG (D3.js), Mermaid syntax, and PNG
|
|
14
63
|
- **Automatic Layout**: Smart graph positioning using Dagre layout engine
|
|
15
|
-
- **Full ASL Support**: All state types (Pass, Task, Choice, Wait, Succeed, Fail, Parallel, Map), both JSONPath and JSONata query languages
|
|
64
|
+
- **Full ASL Support**: All state types (Pass, Task, Choice, Wait, Succeed, Fail, Parallel, Map), both JSONPath and JSONata query languages, plus `Catch`/`Retry` rendering
|
|
65
|
+
- **Visual Diffing**: Compare two definitions and highlight added / modified / removed states — drives the PR-preview GitHub Action
|
|
66
|
+
- **Execution Overlays**: Paint a real execution's history onto the diagram — succeeded/failed/caught/not-reached states, the taken path, and per-state duration & retry counts
|
|
16
67
|
- **Customizable Themes**: AWS light/dark themes plus custom theme support
|
|
17
68
|
- **Flexible Layouts**: Top-bottom, left-right, right-left, bottom-top
|
|
18
69
|
- **Type-Safe**: Full TypeScript support with comprehensive type definitions
|
|
@@ -44,6 +95,10 @@ browser (`node-html-to-image`) and Node's filesystem respectively. Because `node
|
|
|
44
95
|
is an **optional peer dependency**, install it alongside `sfn-diagram` when you need PNG output;
|
|
45
96
|
`exportPng` throws an actionable error if it is missing.
|
|
46
97
|
|
|
98
|
+
**Node versions:** the package requires **Node >= 20**. PNG export additionally requires
|
|
99
|
+
**Node >= 22.12.0**, the floor set by `node-html-to-image` v6 — SVG, Mermaid, and HTML
|
|
100
|
+
output are unaffected and keep working on Node 20.
|
|
101
|
+
|
|
47
102
|
```ts
|
|
48
103
|
// Works in Node, browser, and edge:
|
|
49
104
|
import { generateSvg } from 'sfn-diagram';
|
|
@@ -62,7 +117,11 @@ npx sfn-diagram state.asl.json --format mermaid > diagram.mmd
|
|
|
62
117
|
cat state.asl.json | npx sfn-diagram - --format svg
|
|
63
118
|
```
|
|
64
119
|
|
|
65
|
-
Flags: `--format <svg|mermaid|png>`, `-o/--output <path>`, `--theme <light|dark>`, `--layout <TB|LR|RL|BT>`, `-h/--help`, `-v/--version`.
|
|
120
|
+
Flags: `--format <svg|mermaid|png|html>`, `-o/--output <path>`, `--theme <light|dark>`, `--layout <TB|LR|RL|BT>`, `--hide-catch`, `--resolve-cfn`, `--resource <logicalId>`, `-h/--help`, `-v/--version`.
|
|
121
|
+
|
|
122
|
+
CloudFormation/SAM/CDK templates work as input too — see [Extracting ASL from a CDK/CloudFormation template](#extracting-asl-from-a-cdkcloudformation-template).
|
|
123
|
+
|
|
124
|
+
> **`--format png` needs the optional `node-html-to-image` peer.** It is not installed by default. With `npx`, run `npx --package sfn-diagram --package node-html-to-image sfn-diagram …`; in a project, `npm install node-html-to-image`. Without it the CLI exits with an actionable error. Or skip the install entirely with the [Docker image](#docker), which bundles Chromium.
|
|
66
125
|
|
|
67
126
|
## Docker
|
|
68
127
|
|
|
@@ -222,6 +281,154 @@ const { svg } = generateFromAwsResponse({
|
|
|
222
281
|
});
|
|
223
282
|
```
|
|
224
283
|
|
|
284
|
+
### Extracting ASL from a CDK/CloudFormation template
|
|
285
|
+
|
|
286
|
+
`cdk synth` emits a state machine whose `DefinitionString` is an `Fn::Join` full
|
|
287
|
+
of intrinsics, not plain ASL. The `sfn-diagram/cfn` subpath flattens it:
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import { extractAslFromTemplate } from 'sfn-diagram/cfn';
|
|
291
|
+
import { generateMermaid } from 'sfn-diagram';
|
|
292
|
+
|
|
293
|
+
const { aslDefinition, warnings } = extractAslFromTemplate({ template: cdkSynthJson });
|
|
294
|
+
const { code } = generateMermaid({ aslDefinition });
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Both JSON and YAML templates are supported (CloudFormation short-form tags like
|
|
298
|
+
`!Sub` / `!GetAtt` included), and `DefinitionSubstitutions` are applied. When a
|
|
299
|
+
template contains more than one state machine, pass `resourceId` to pick one.
|
|
300
|
+
|
|
301
|
+
CLI (JSON templates auto-detect; use `--resolve-cfn` for YAML):
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
cdk synth > template.json
|
|
305
|
+
npx sfn-diagram template.json --format mermaid
|
|
306
|
+
npx sfn-diagram template.yaml --resolve-cfn --resource MyMachine --format svg -o out.svg
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Intrinsics that don't affect the flow become readable placeholders
|
|
310
|
+
(`${AWS::Partition}`, `<Ref:LogicalId>`). External `DefinitionUri` definitions
|
|
311
|
+
are not supported — pass a template with an inline definition.
|
|
312
|
+
|
|
313
|
+
### generateMermaidDiff(params) / generateDiff(params)
|
|
314
|
+
|
|
315
|
+
Compare two ASL definitions and highlight what changed. `generateMermaidDiff` returns Mermaid code (renders inline on GitHub); `generateDiff` returns the same comparison as an SVG. Added states are green, modified yellow, removed red — and both return a `metadata` change summary (`added`, `modified`, `removed`, `unchanged`). The comparison is order-insensitive, so reordering a state's properties is **not** flagged as a change.
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
import { generateMermaidDiff } from 'sfn-diagram';
|
|
319
|
+
|
|
320
|
+
const { code, metadata } = generateMermaidDiff({
|
|
321
|
+
before: baseAsl, // old (base) ASL definition, object or JSON string
|
|
322
|
+
after: headAsl, // new (head) ASL definition, object or JSON string
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
metadata; // { added: [...], modified: [...], removed: [...], unchanged: [...], stateCount, edgeCount }
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
For the order-processing workflow above, adding a `FraudCheck` step, bumping `ChargePayment`'s resource, and dropping `CancelOrder` renders like this:
|
|
329
|
+
|
|
330
|
+
```mermaid
|
|
331
|
+
stateDiagram-v2
|
|
332
|
+
|
|
333
|
+
[*] --> ValidateOrder
|
|
334
|
+
ValidateOrder --> CheckStock
|
|
335
|
+
CheckStock --> ChargePayment: $.inStock == true
|
|
336
|
+
CheckStock --> OrderComplete: Default
|
|
337
|
+
ChargePayment --> FraudCheck
|
|
338
|
+
FraudCheck --> ShipOrder
|
|
339
|
+
ShipOrder --> OrderComplete
|
|
340
|
+
|
|
341
|
+
OrderComplete --> [*]
|
|
342
|
+
CancelOrder --> [*]
|
|
343
|
+
|
|
344
|
+
classDef diffAdded fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px
|
|
345
|
+
classDef diffModified fill:#fff9c4,stroke:#f57f17,stroke-width:2px
|
|
346
|
+
classDef diffRemoved fill:#ffcdd2,stroke:#c62828,stroke-width:2px
|
|
347
|
+
|
|
348
|
+
class FraudCheck diffAdded
|
|
349
|
+
class CheckStock diffModified
|
|
350
|
+
class ChargePayment diffModified
|
|
351
|
+
class CancelOrder diffRemoved
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
> This is exactly what the [GitHub Action](#github-action) posts on pull requests that touch ASL files.
|
|
355
|
+
|
|
356
|
+
### generateExecution(params) / generateMermaidExecution(params)
|
|
357
|
+
|
|
358
|
+
Overlay a **real execution** onto the diagram. Where the diff shows how a definition
|
|
359
|
+
_changed_, the execution overlay shows what one _run_ actually did: which path it took,
|
|
360
|
+
which states succeeded (green), failed (red), were caught and recovered (orange), or were
|
|
361
|
+
never reached (grey) — plus per-state duration and retry counts.
|
|
362
|
+
|
|
363
|
+
Pass the ASL definition plus the execution's history. `history` accepts the events array
|
|
364
|
+
from `GetExecutionHistory`, the raw command output, or a JSON string of either — so the
|
|
365
|
+
core stays credential-free and runs in the browser.
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
import { generateExecution, generateMermaidExecution } from 'sfn-diagram';
|
|
369
|
+
|
|
370
|
+
// history: events from `aws stepfunctions get-execution-history`, or the SDK response
|
|
371
|
+
const { svg, metadata } = generateExecution({ aslDefinition: asl, history });
|
|
372
|
+
|
|
373
|
+
metadata;
|
|
374
|
+
// { succeeded: [...], failed: [...], caught: [...], notReached: [...], running: [...],
|
|
375
|
+
// takenEdgeCount, executionStatus, nodeCount, edgeCount }
|
|
376
|
+
|
|
377
|
+
// Mermaid variant (states coloured + duration/retry annotations in labels):
|
|
378
|
+
const { code } = generateMermaidExecution({ aslDefinition: asl, history });
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
> **Note:** Mermaid `stateDiagram-v2` cannot style individual transitions, so taken-path
|
|
382
|
+
> emphasis in Mermaid is expressed through node colours and label annotations. The SVG
|
|
383
|
+
> overlay additionally dims the transitions the run did not take.
|
|
384
|
+
|
|
385
|
+
Need just the data (no rendering)? `parseExecutionHistory({ events })` returns the pure
|
|
386
|
+
`ExecutionOverlay` model — per-state status, attempts, duration, and the taken edges — for
|
|
387
|
+
building your own UI.
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
import { parseExecutionHistory } from 'sfn-diagram';
|
|
391
|
+
|
|
392
|
+
const overlay = parseExecutionHistory({ events });
|
|
393
|
+
overlay.states['ProcessOrder']; // { status: 'succeeded', attempts: 1, durationMs: 1250 }
|
|
394
|
+
overlay.takenEdges; // [{ from: 'ValidateOrder', to: 'ProcessOrder' }, ...]
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Fetching history from AWS (Node) — use the `sfn-diagram/aws` helper, which paginates `GetExecutionHistory` for you:
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
import { SFNClient } from '@aws-sdk/client-sfn';
|
|
401
|
+
import { fetchExecutionHistory } from 'sfn-diagram/aws';
|
|
402
|
+
|
|
403
|
+
const client = new SFNClient({ region: 'us-east-1' });
|
|
404
|
+
const events = await fetchExecutionHistory({ client, executionArn });
|
|
405
|
+
|
|
406
|
+
const { svg } = generateExecution({ aslDefinition: asl, history: events });
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
`sfn-diagram/aws` is a Node-only subpath. `@aws-sdk/client-sfn` is an **optional peer dependency** — install it yourself (`npm i @aws-sdk/client-sfn`); the core `sfn-diagram` package stays dependency-free and browser-safe.
|
|
410
|
+
|
|
411
|
+
<details>
|
|
412
|
+
<summary>Prefer to paginate yourself? The manual loop:</summary>
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
import { SFNClient, GetExecutionHistoryCommand } from '@aws-sdk/client-sfn';
|
|
416
|
+
|
|
417
|
+
const client = new SFNClient({ region: 'us-east-1' });
|
|
418
|
+
const events = [];
|
|
419
|
+
let nextToken;
|
|
420
|
+
do {
|
|
421
|
+
const page = await client.send(
|
|
422
|
+
new GetExecutionHistoryCommand({ executionArn, nextToken, maxResults: 1000 }),
|
|
423
|
+
);
|
|
424
|
+
events.push(...(page.events ?? []));
|
|
425
|
+
nextToken = page.nextToken;
|
|
426
|
+
} while (nextToken);
|
|
427
|
+
|
|
428
|
+
const { svg } = generateExecution({ aslDefinition: asl, history: events });
|
|
429
|
+
```
|
|
430
|
+
</details>
|
|
431
|
+
|
|
225
432
|
### SfnDiagramGenerator Class
|
|
226
433
|
|
|
227
434
|
Reusable generator that holds diagram options once and applies them to every call. Configure options via the constructor or the fluent `setOptions()` method; pass the `aslDefinition` per generation.
|
|
@@ -259,23 +466,34 @@ const mermaidResult = generator.generateMermaid({ aslDefinition: asl });
|
|
|
259
466
|
- `'dark'` - AWS dark theme
|
|
260
467
|
|
|
261
468
|
**Custom theme:**
|
|
469
|
+
|
|
470
|
+
A `CustomTheme` sets the background, per-state-type fill/stroke colours, edge colours, and typography. Pass it anywhere a theme is accepted.
|
|
471
|
+
|
|
262
472
|
```typescript
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
473
|
+
import type { CustomTheme } from 'sfn-diagram';
|
|
474
|
+
|
|
475
|
+
const customTheme: CustomTheme = {
|
|
476
|
+
background: '#ffffff',
|
|
477
|
+
edgeColors: {
|
|
478
|
+
choice: '#7b1fa2',
|
|
479
|
+
default: '#607d8b',
|
|
480
|
+
error: '#f44336',
|
|
481
|
+
normal: '#232f3e',
|
|
482
|
+
retry: '#f9a825', // optional; falls back to `error` when omitted
|
|
483
|
+
},
|
|
268
484
|
fontFamily: 'Arial, sans-serif',
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
485
|
+
fontSize: 14,
|
|
486
|
+
nodeColors: {
|
|
487
|
+
Pass: { fill: '#e8f5e9', stroke: '#4caf50' },
|
|
488
|
+
Task: { fill: '#e3f2fd', stroke: '#2196f3' },
|
|
489
|
+
Choice: { fill: '#fff3e0', stroke: '#ff9800' },
|
|
490
|
+
Wait: { fill: '#f3e5f5', stroke: '#9c27b0' },
|
|
491
|
+
Succeed: { fill: '#e8f5e9', stroke: '#4caf50' },
|
|
492
|
+
Fail: { fill: '#ffebee', stroke: '#f44336' },
|
|
493
|
+
Parallel: { fill: '#e0f7fa', stroke: '#00bcd4' },
|
|
494
|
+
Map: { fill: '#e8eaf6', stroke: '#3f51b5' },
|
|
495
|
+
},
|
|
496
|
+
textColor: '#232f3e',
|
|
279
497
|
};
|
|
280
498
|
|
|
281
499
|
generateSvg({ aslDefinition: asl, theme: customTheme });
|
|
@@ -294,6 +512,29 @@ generateSvg({ aslDefinition: asl, theme: customTheme });
|
|
|
294
512
|
- `'straight'` - Direct straight lines
|
|
295
513
|
- `'orthogonal'` - Right-angled paths
|
|
296
514
|
|
|
515
|
+
### Large diagrams
|
|
516
|
+
|
|
517
|
+
Big, branchy state machines are hard to read as a static image. A few options help:
|
|
518
|
+
|
|
519
|
+
- **`--format html`** (or `generateHtml()`) — a self-contained interactive viewer
|
|
520
|
+
(drag to pan, wheel to zoom, fit/reset toolbar). No external dependencies, opens
|
|
521
|
+
offline straight from `file://`.
|
|
522
|
+
```bash
|
|
523
|
+
npx sfn-diagram state.asl.json --format html -o diagram.html
|
|
524
|
+
```
|
|
525
|
+
> **Known limitation:** if you also pass `showIcons: true`, the embedded SVG
|
|
526
|
+
> references AWS service icons hosted on a jsDelivr CDN (see
|
|
527
|
+
> [AWS Service Icons](#aws-service-icons) below), so the HTML is no longer fully
|
|
528
|
+
> offline — icons won't load without network access.
|
|
529
|
+
- **`--hide-catch`** (or `catchHandling: 'hide'`) — drop per-state error-handler
|
|
530
|
+
(`Catch`) branches so the happy path stands out. A handler that's also reachable
|
|
531
|
+
via the happy path is kept.
|
|
532
|
+
```bash
|
|
533
|
+
npx sfn-diagram state.asl.json --hide-catch --format svg -o diagram.svg
|
|
534
|
+
```
|
|
535
|
+
- **`--layout LR`** (or `layout: 'LR'`) — the default `TB` layout makes catch-heavy
|
|
536
|
+
or deeply branching machines extremely tall; `LR` reads better for wide graphs.
|
|
537
|
+
|
|
297
538
|
### AWS Service Icons
|
|
298
539
|
|
|
299
540
|
Display AWS service icons on Task state nodes to improve diagram readability and quickly identify which AWS services are being used.
|
|
@@ -531,7 +772,7 @@ pnpm install
|
|
|
531
772
|
pnpm dev
|
|
532
773
|
```
|
|
533
774
|
|
|
534
|
-
Paste any ASL JSON, switch themes, and see the SVG diagram update instantly — no install required beyond the dev server.
|
|
775
|
+
Paste any ASL JSON, switch themes, and see the SVG diagram update instantly — no install required beyond the dev server. Switch **Mode** to _Execution overlay_ to paste an execution history alongside the definition and watch the run's path light up.
|
|
535
776
|
|
|
536
777
|
### VS Code Extension
|
|
537
778
|
|
|
@@ -547,28 +788,53 @@ code --install-extension vscode-sfn-diagram-*.vsix
|
|
|
547
788
|
|
|
548
789
|
**Usage:** Open any `.json` or `.asl` file and run **Step Functions: Preview Step Functions Diagram** from the command palette, or click the diagram icon in the editor title bar.
|
|
549
790
|
|
|
791
|
+
### React Component
|
|
792
|
+
|
|
793
|
+
Render diagrams in a React app with the [`sfn-diagram-react`](packages/sfn-diagram-react/) package. It wraps `generateSvg`/`generateMermaid` in a component with the same platform-agnostic core, so it works in any React renderer.
|
|
794
|
+
|
|
795
|
+
```tsx
|
|
796
|
+
import { SfnDiagram } from 'sfn-diagram-react';
|
|
797
|
+
|
|
798
|
+
<SfnDiagram
|
|
799
|
+
definition={asl} // ASL object or JSON string
|
|
800
|
+
format="svg" // 'svg' (default) | 'mermaid'
|
|
801
|
+
theme="dark" // 'light' | 'dark' | CustomTheme
|
|
802
|
+
layout="LR" // 'TB' | 'LR' | 'RL' | 'BT'
|
|
803
|
+
history={history} // optional: renders an execution overlay
|
|
804
|
+
onError={(err) => console.error(err)}
|
|
805
|
+
/>
|
|
806
|
+
```
|
|
807
|
+
|
|
550
808
|
### GitHub Action
|
|
551
809
|
|
|
552
|
-
|
|
810
|
+
Comment a Step Functions diagram on every pull request that touches an ASL file. For **changed** files the comment highlights the diff — added states green, modified yellow, removed red — plus a summary table of what changed; **new** and **deleted** files get a plain diagram. Everything is Mermaid, so it renders inline in the PR with no image hosting. The comment is upserted (updated in place) on each push.
|
|
811
|
+
|
|
812
|
+
Available on the [GitHub Marketplace](https://github.com/marketplace/actions/step-functions-diagram-preview) as [`yusufaf/sfn-diagram-action`](https://github.com/yusufaf/sfn-diagram-action) — pin the moving major tag `@v1`. (Source lives here in [`packages/github-action-sfn-diagram/`](packages/github-action-sfn-diagram/); the Marketplace repo is generated from it.)
|
|
553
813
|
|
|
554
814
|
```yaml
|
|
555
815
|
# .github/workflows/sfn-preview.yml
|
|
556
816
|
name: Step Functions Preview
|
|
557
817
|
on:
|
|
558
818
|
pull_request:
|
|
559
|
-
paths: ['**/*.asl.json']
|
|
819
|
+
paths: ['**/*.asl.json', '**/*.asl']
|
|
820
|
+
|
|
821
|
+
permissions:
|
|
822
|
+
contents: read
|
|
823
|
+
pull-requests: write # required to post the comment
|
|
560
824
|
|
|
561
825
|
jobs:
|
|
562
826
|
preview:
|
|
563
827
|
runs-on: ubuntu-latest
|
|
564
828
|
steps:
|
|
565
|
-
- uses: actions/checkout@
|
|
566
|
-
with: { fetch-depth: 0 }
|
|
567
|
-
- uses:
|
|
568
|
-
with:
|
|
569
|
-
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
829
|
+
- uses: actions/checkout@v5
|
|
830
|
+
with: { fetch-depth: 0 } # needed to diff base vs head
|
|
831
|
+
- uses: yusufaf/sfn-diagram-action@v1
|
|
570
832
|
```
|
|
571
833
|
|
|
834
|
+
Inputs: `github-token` (defaults to `${{ github.token }}`), `asl-glob` (comma-separated globs, default `**/*.asl.json,**/*.asl`), `comment-tag` (marker used to find/update the comment, default `sfn-diagram-preview`).
|
|
835
|
+
|
|
836
|
+
Optionally overlay a real run: set `execution-mode` (`latest` or `latest-failed`) and `state-machine-arn` to append the most recent (or most recent failed) execution as a Mermaid overlay beneath the diff. This is opt-in (`off` by default), needs AWS credentials (`states:ListExecutions` + `states:GetExecutionHistory`), and applies when exactly one ASL file changed — see the [action README](packages/github-action-sfn-diagram/README.marketplace.md) for a full workflow.
|
|
837
|
+
|
|
572
838
|
## Contributing
|
|
573
839
|
|
|
574
840
|
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
package/dist/aws.cjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let _aws_sdk_client_sfn = require("@aws-sdk/client-sfn");
|
|
3
|
+
//#region src/aws.ts
|
|
4
|
+
/**
|
|
5
|
+
* @module
|
|
6
|
+
*
|
|
7
|
+
* Node-only AWS convenience helpers for `sfn-diagram` (the `sfn-diagram/aws` subpath).
|
|
8
|
+
*
|
|
9
|
+
* This subpath (`sfn-diagram/aws`) is isolated from the core entry so that
|
|
10
|
+
* importing `sfn-diagram` never pulls in `@aws-sdk/client-sfn`, keeping the core
|
|
11
|
+
* dependency-free and browser-safe. `@aws-sdk/client-sfn` is an optional peer
|
|
12
|
+
* dependency — install it yourself to use these helpers.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Fetches the complete history of a Step Functions execution, paginating through
|
|
16
|
+
* every `GetExecutionHistory` page so callers don't have to hand-roll the
|
|
17
|
+
* `nextToken` loop.
|
|
18
|
+
*
|
|
19
|
+
* The returned `HistoryEvent[]` can be passed straight to `parseExecutionHistory`,
|
|
20
|
+
* `generateExecution`, or `generateMermaidExecution` from `sfn-diagram`.
|
|
21
|
+
*
|
|
22
|
+
* @param params - The SFN client, execution ARN, and optional page size.
|
|
23
|
+
* @returns All history events for the execution, in chronological order.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { SFNClient } from '@aws-sdk/client-sfn';
|
|
28
|
+
* import { fetchExecutionHistory } from 'sfn-diagram/aws';
|
|
29
|
+
* import { generateExecution } from 'sfn-diagram';
|
|
30
|
+
*
|
|
31
|
+
* const client = new SFNClient({ region: 'us-east-1' });
|
|
32
|
+
* const events = await fetchExecutionHistory({ client, executionArn });
|
|
33
|
+
* const { svg } = generateExecution({ aslDefinition: asl, history: events });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
async function fetchExecutionHistory(params) {
|
|
37
|
+
const { client, executionArn, maxResults = 1e3 } = params;
|
|
38
|
+
const events = [];
|
|
39
|
+
let nextToken;
|
|
40
|
+
do {
|
|
41
|
+
const page = await client.send(new _aws_sdk_client_sfn.GetExecutionHistoryCommand({
|
|
42
|
+
executionArn,
|
|
43
|
+
maxResults,
|
|
44
|
+
nextToken
|
|
45
|
+
}));
|
|
46
|
+
events.push(...page.events ?? []);
|
|
47
|
+
nextToken = page.nextToken;
|
|
48
|
+
} while (nextToken);
|
|
49
|
+
return events;
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
exports.fetchExecutionHistory = fetchExecutionHistory;
|
package/dist/aws.d.cts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { HistoryEvent, SFNClient } from "@aws-sdk/client-sfn";
|
|
2
|
+
|
|
3
|
+
//#region src/aws.d.ts
|
|
4
|
+
interface FetchExecutionHistoryParams {
|
|
5
|
+
/** A caller-constructed SFN client (with the caller's credentials/region). */
|
|
6
|
+
client: SFNClient;
|
|
7
|
+
/** ARN of the execution whose history should be fetched. */
|
|
8
|
+
executionArn: string;
|
|
9
|
+
/** Page size passed to `GetExecutionHistory`. Defaults to 1000 (the AWS max). */
|
|
10
|
+
maxResults?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Fetches the complete history of a Step Functions execution, paginating through
|
|
14
|
+
* every `GetExecutionHistory` page so callers don't have to hand-roll the
|
|
15
|
+
* `nextToken` loop.
|
|
16
|
+
*
|
|
17
|
+
* The returned `HistoryEvent[]` can be passed straight to `parseExecutionHistory`,
|
|
18
|
+
* `generateExecution`, or `generateMermaidExecution` from `sfn-diagram`.
|
|
19
|
+
*
|
|
20
|
+
* @param params - The SFN client, execution ARN, and optional page size.
|
|
21
|
+
* @returns All history events for the execution, in chronological order.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { SFNClient } from '@aws-sdk/client-sfn';
|
|
26
|
+
* import { fetchExecutionHistory } from 'sfn-diagram/aws';
|
|
27
|
+
* import { generateExecution } from 'sfn-diagram';
|
|
28
|
+
*
|
|
29
|
+
* const client = new SFNClient({ region: 'us-east-1' });
|
|
30
|
+
* const events = await fetchExecutionHistory({ client, executionArn });
|
|
31
|
+
* const { svg } = generateExecution({ aslDefinition: asl, history: events });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare function fetchExecutionHistory(params: FetchExecutionHistoryParams): Promise<HistoryEvent[]>;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { FetchExecutionHistoryParams, fetchExecutionHistory };
|
package/dist/aws.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { HistoryEvent, SFNClient } from "@aws-sdk/client-sfn";
|
|
2
|
+
|
|
3
|
+
//#region src/aws.d.ts
|
|
4
|
+
interface FetchExecutionHistoryParams {
|
|
5
|
+
/** A caller-constructed SFN client (with the caller's credentials/region). */
|
|
6
|
+
client: SFNClient;
|
|
7
|
+
/** ARN of the execution whose history should be fetched. */
|
|
8
|
+
executionArn: string;
|
|
9
|
+
/** Page size passed to `GetExecutionHistory`. Defaults to 1000 (the AWS max). */
|
|
10
|
+
maxResults?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Fetches the complete history of a Step Functions execution, paginating through
|
|
14
|
+
* every `GetExecutionHistory` page so callers don't have to hand-roll the
|
|
15
|
+
* `nextToken` loop.
|
|
16
|
+
*
|
|
17
|
+
* The returned `HistoryEvent[]` can be passed straight to `parseExecutionHistory`,
|
|
18
|
+
* `generateExecution`, or `generateMermaidExecution` from `sfn-diagram`.
|
|
19
|
+
*
|
|
20
|
+
* @param params - The SFN client, execution ARN, and optional page size.
|
|
21
|
+
* @returns All history events for the execution, in chronological order.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { SFNClient } from '@aws-sdk/client-sfn';
|
|
26
|
+
* import { fetchExecutionHistory } from 'sfn-diagram/aws';
|
|
27
|
+
* import { generateExecution } from 'sfn-diagram';
|
|
28
|
+
*
|
|
29
|
+
* const client = new SFNClient({ region: 'us-east-1' });
|
|
30
|
+
* const events = await fetchExecutionHistory({ client, executionArn });
|
|
31
|
+
* const { svg } = generateExecution({ aslDefinition: asl, history: events });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare function fetchExecutionHistory(params: FetchExecutionHistoryParams): Promise<HistoryEvent[]>;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { FetchExecutionHistoryParams, fetchExecutionHistory };
|
package/dist/aws.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { GetExecutionHistoryCommand } from "@aws-sdk/client-sfn";
|
|
2
|
+
//#region src/aws.ts
|
|
3
|
+
/**
|
|
4
|
+
* @module
|
|
5
|
+
*
|
|
6
|
+
* Node-only AWS convenience helpers for `sfn-diagram` (the `sfn-diagram/aws` subpath).
|
|
7
|
+
*
|
|
8
|
+
* This subpath (`sfn-diagram/aws`) is isolated from the core entry so that
|
|
9
|
+
* importing `sfn-diagram` never pulls in `@aws-sdk/client-sfn`, keeping the core
|
|
10
|
+
* dependency-free and browser-safe. `@aws-sdk/client-sfn` is an optional peer
|
|
11
|
+
* dependency — install it yourself to use these helpers.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Fetches the complete history of a Step Functions execution, paginating through
|
|
15
|
+
* every `GetExecutionHistory` page so callers don't have to hand-roll the
|
|
16
|
+
* `nextToken` loop.
|
|
17
|
+
*
|
|
18
|
+
* The returned `HistoryEvent[]` can be passed straight to `parseExecutionHistory`,
|
|
19
|
+
* `generateExecution`, or `generateMermaidExecution` from `sfn-diagram`.
|
|
20
|
+
*
|
|
21
|
+
* @param params - The SFN client, execution ARN, and optional page size.
|
|
22
|
+
* @returns All history events for the execution, in chronological order.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { SFNClient } from '@aws-sdk/client-sfn';
|
|
27
|
+
* import { fetchExecutionHistory } from 'sfn-diagram/aws';
|
|
28
|
+
* import { generateExecution } from 'sfn-diagram';
|
|
29
|
+
*
|
|
30
|
+
* const client = new SFNClient({ region: 'us-east-1' });
|
|
31
|
+
* const events = await fetchExecutionHistory({ client, executionArn });
|
|
32
|
+
* const { svg } = generateExecution({ aslDefinition: asl, history: events });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
async function fetchExecutionHistory(params) {
|
|
36
|
+
const { client, executionArn, maxResults = 1e3 } = params;
|
|
37
|
+
const events = [];
|
|
38
|
+
let nextToken;
|
|
39
|
+
do {
|
|
40
|
+
const page = await client.send(new GetExecutionHistoryCommand({
|
|
41
|
+
executionArn,
|
|
42
|
+
maxResults,
|
|
43
|
+
nextToken
|
|
44
|
+
}));
|
|
45
|
+
events.push(...page.events ?? []);
|
|
46
|
+
nextToken = page.nextToken;
|
|
47
|
+
} while (nextToken);
|
|
48
|
+
return events;
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { fetchExecutionHistory };
|