sfn-diagram 0.7.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 CHANGED
@@ -95,6 +95,10 @@ browser (`node-html-to-image`) and Node's filesystem respectively. Because `node
95
95
  is an **optional peer dependency**, install it alongside `sfn-diagram` when you need PNG output;
96
96
  `exportPng` throws an actionable error if it is missing.
97
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
+
98
102
  ```ts
99
103
  // Works in Node, browser, and edge:
100
104
  import { generateSvg } from 'sfn-diagram';
@@ -113,7 +117,11 @@ npx sfn-diagram state.asl.json --format mermaid > diagram.mmd
113
117
  cat state.asl.json | npx sfn-diagram - --format svg
114
118
  ```
115
119
 
116
- 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.
117
125
 
118
126
  ## Docker
119
127
 
@@ -273,6 +281,35 @@ const { svg } = generateFromAwsResponse({
273
281
  });
274
282
  ```
275
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
+
276
313
  ### generateMermaidDiff(params) / generateDiff(params)
277
314
 
278
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.
@@ -475,6 +512,29 @@ generateSvg({ aslDefinition: asl, theme: customTheme });
475
512
  - `'straight'` - Direct straight lines
476
513
  - `'orthogonal'` - Right-angled paths
477
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
+
478
538
  ### AWS Service Icons
479
539
 
480
540
  Display AWS service icons on Task state nodes to improve diagram readability and quickly identify which AWS services are being used.
package/dist/aws.cjs CHANGED
@@ -2,7 +2,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let _aws_sdk_client_sfn = require("@aws-sdk/client-sfn");
3
3
  //#region src/aws.ts
4
4
  /**
5
- * Node-only AWS convenience helpers for `sfn-diagram`.
5
+ * @module
6
+ *
7
+ * Node-only AWS convenience helpers for `sfn-diagram` (the `sfn-diagram/aws` subpath).
6
8
  *
7
9
  * This subpath (`sfn-diagram/aws`) is isolated from the core entry so that
8
10
  * importing `sfn-diagram` never pulls in `@aws-sdk/client-sfn`, keeping the core
package/dist/aws.d.cts CHANGED
@@ -10,27 +10,27 @@ interface FetchExecutionHistoryParams {
10
10
  maxResults?: number;
11
11
  }
12
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
- */
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
34
  declare function fetchExecutionHistory(params: FetchExecutionHistoryParams): Promise<HistoryEvent[]>;
35
35
  //#endregion
36
36
  export { FetchExecutionHistoryParams, fetchExecutionHistory };
package/dist/aws.d.ts CHANGED
@@ -10,27 +10,27 @@ interface FetchExecutionHistoryParams {
10
10
  maxResults?: number;
11
11
  }
12
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
- */
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
34
  declare function fetchExecutionHistory(params: FetchExecutionHistoryParams): Promise<HistoryEvent[]>;
35
35
  //#endregion
36
36
  export { FetchExecutionHistoryParams, fetchExecutionHistory };
package/dist/aws.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { GetExecutionHistoryCommand } from "@aws-sdk/client-sfn";
2
2
  //#region src/aws.ts
3
3
  /**
4
- * Node-only AWS convenience helpers for `sfn-diagram`.
4
+ * @module
5
+ *
6
+ * Node-only AWS convenience helpers for `sfn-diagram` (the `sfn-diagram/aws` subpath).
5
7
  *
6
8
  * This subpath (`sfn-diagram/aws`) is isolated from the core entry so that
7
9
  * importing `sfn-diagram` never pulls in `@aws-sdk/client-sfn`, keeping the core
package/dist/cfn.cjs ADDED
@@ -0,0 +1,207 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let yaml = require("yaml");
3
+ //#region src/cfn/intrinsics.ts
4
+ function isPseudoParam(name) {
5
+ return name.startsWith("AWS::");
6
+ }
7
+ function substitute(template, substitutions) {
8
+ return template.replace(/\$\{([^}]+)\}/g, (match, name) => {
9
+ if (isPseudoParam(name)) return match;
10
+ if (name in substitutions) return substitutions[name];
11
+ return match;
12
+ });
13
+ }
14
+ /**
15
+ * Replaces every CloudFormation intrinsic in a parsed template value with a
16
+ * readable placeholder string, so the result can be parsed as ASL.
17
+ *
18
+ * `Fn::Join` is concatenated, `Fn::Sub` variables are filled from the
19
+ * substitutions map, `Ref`/`Fn::GetAtt` become `<Ref:Id>` / `<Res.Attr>`, and
20
+ * pseudo-parameters stay as `${AWS::Partition}`-style tokens. Anything else is
21
+ * stubbed as `<Fn::Name>` and reported in `warnings`.
22
+ *
23
+ * @param params - The value to resolve plus optional DefinitionSubstitutions.
24
+ * @returns The resolved value and any non-fatal warnings.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const { value } = resolveIntrinsics({ value: { Ref: 'AWS::Partition' } });
29
+ * // value === '${AWS::Partition}'
30
+ * ```
31
+ */
32
+ function resolveIntrinsics(params) {
33
+ const { substitutions = {}, value } = params;
34
+ const warnings = [];
35
+ function walk(current) {
36
+ if (Array.isArray(current)) return current.map(walk);
37
+ if (current === null || typeof current !== "object") return current;
38
+ const objectKeys = Object.keys(current);
39
+ if (objectKeys.length === 1) {
40
+ const key = objectKeys[0];
41
+ const inner = current[key];
42
+ if (key === "Ref" && typeof inner === "string") return isPseudoParam(inner) ? `\${${inner}}` : `<Ref:${inner}>`;
43
+ if (key === "Fn::GetAtt") return `<${(Array.isArray(inner) ? inner : String(inner).split(".")).join(".")}>`;
44
+ if (key === "Fn::Join") {
45
+ const [delimiter, parts] = inner;
46
+ return parts.map((part) => String(walk(part))).join(delimiter);
47
+ }
48
+ if (key === "Fn::Sub") {
49
+ if (typeof inner === "string") return substitute(inner, substitutions);
50
+ if (Array.isArray(inner)) {
51
+ const [subTemplate, localMap] = inner;
52
+ const localResolved = { ...substitutions };
53
+ for (const localKey of Object.keys(localMap)) localResolved[localKey] = String(walk(localMap[localKey]));
54
+ return substitute(subTemplate, localResolved);
55
+ }
56
+ }
57
+ if (key.startsWith("Fn::")) {
58
+ warnings.push(`Unresolved intrinsic ${key} replaced with placeholder`);
59
+ return `<${key}>`;
60
+ }
61
+ }
62
+ const output = {};
63
+ for (const key of objectKeys) output[key] = walk(current[key]);
64
+ return output;
65
+ }
66
+ return {
67
+ value: walk(value),
68
+ warnings
69
+ };
70
+ }
71
+ //#endregion
72
+ //#region src/cfn/templateParser.ts
73
+ /**
74
+ * CloudFormation short-form YAML tags, mapped to the JSON long form the rest of
75
+ * the pipeline understands. `!Ref x` becomes `{ Ref: 'x' }`; every `Fn::*` tag
76
+ * becomes `{ 'Fn::Name': value }`.
77
+ */
78
+ const CFN_TAG_NAMES = [
79
+ "Ref",
80
+ "Base64",
81
+ "Cidr",
82
+ "FindInMap",
83
+ "GetAtt",
84
+ "GetAZs",
85
+ "ImportValue",
86
+ "Join",
87
+ "Select",
88
+ "Split",
89
+ "Sub",
90
+ "Transform",
91
+ "And",
92
+ "Equals",
93
+ "If",
94
+ "Not",
95
+ "Or",
96
+ "Condition"
97
+ ];
98
+ function longFormKey(tagName) {
99
+ return tagName === "Ref" || tagName === "Condition" ? tagName : `Fn::${tagName}`;
100
+ }
101
+ function buildCfnTags() {
102
+ const tags = [];
103
+ for (const tagName of CFN_TAG_NAMES) {
104
+ const toLongForm = (value) => {
105
+ if (tagName === "GetAtt" && typeof value === "string") return { "Fn::GetAtt": value.split(".") };
106
+ return { [longFormKey(tagName)]: value };
107
+ };
108
+ tags.push({
109
+ identify: () => false,
110
+ resolve: (value) => toLongForm(value),
111
+ tag: `!${tagName}`
112
+ });
113
+ tags.push({
114
+ collection: "seq",
115
+ identify: () => false,
116
+ resolve: (value) => toLongForm(value.toJSON()),
117
+ tag: `!${tagName}`
118
+ });
119
+ tags.push({
120
+ collection: "map",
121
+ identify: () => false,
122
+ resolve: (value) => toLongForm(value.toJSON()),
123
+ tag: `!${tagName}`
124
+ });
125
+ }
126
+ return tags;
127
+ }
128
+ const CFN_TAGS = buildCfnTags();
129
+ function looksLikeJson(text) {
130
+ return text.trimStart().startsWith("{");
131
+ }
132
+ /**
133
+ * Parses a CloudFormation/SAM/CDK template into a plain object.
134
+ *
135
+ * JSON is parsed with `JSON.parse`; YAML is parsed with CloudFormation
136
+ * short-form intrinsic tags normalized to their JSON long form, so downstream
137
+ * code only has to understand `{ Ref: ... }` / `{ 'Fn::Sub': ... }` shapes.
138
+ *
139
+ * @param params - Template source and optional explicit format.
140
+ * @returns The parsed template object.
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * const template = parseTemplate({ template: yamlSource, format: 'yaml' });
145
+ * ```
146
+ */
147
+ function parseTemplate(params) {
148
+ const { format = "auto", template } = params;
149
+ if (typeof template !== "string") return template;
150
+ if (format === "json" || format === "auto" && looksLikeJson(template)) return JSON.parse(template);
151
+ return (0, yaml.parse)(template, { customTags: CFN_TAGS });
152
+ }
153
+ //#endregion
154
+ //#region src/cfn/extract.ts
155
+ const STATE_MACHINE_TYPE = "AWS::StepFunctions::StateMachine";
156
+ function findStateMachineIds(resources) {
157
+ return Object.keys(resources).filter((logicalId) => resources[logicalId]?.Type === STATE_MACHINE_TYPE);
158
+ }
159
+ /**
160
+ * Recovers a renderable ASL definition from a CloudFormation/SAM/CDK template.
161
+ *
162
+ * Locates the `AWS::StepFunctions::StateMachine` resource (disambiguated with
163
+ * `resourceId` when the template has more than one), flattens the intrinsics in
164
+ * its `DefinitionString`/`Definition`, applies `DefinitionSubstitutions`, and
165
+ * parses the result as ASL.
166
+ *
167
+ * @param params - Template source, optional format, optional resource id.
168
+ * @returns The extracted ASL definition, the logical id used, and any warnings.
169
+ * @throws If no state machine is found, the choice is ambiguous, or the
170
+ * definition is external (`DefinitionUri`).
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * const { aslDefinition } = extractAslFromTemplate({ template: cdkSynthJson });
175
+ * ```
176
+ */
177
+ function extractAslFromTemplate(params) {
178
+ const { format = "auto", resourceId, template } = params;
179
+ const resources = parseTemplate({
180
+ format,
181
+ template
182
+ }).Resources ?? {};
183
+ const machineIds = findStateMachineIds(resources);
184
+ if (machineIds.length === 0) throw new Error(`Template contains no ${STATE_MACHINE_TYPE} resource.`);
185
+ let chosenId;
186
+ if (resourceId) {
187
+ if (!machineIds.includes(resourceId)) throw new Error(`Resource '${resourceId}' is not an ${STATE_MACHINE_TYPE}. Found: ${machineIds.join(", ")}.`);
188
+ chosenId = resourceId;
189
+ } else if (machineIds.length === 1) chosenId = machineIds[0];
190
+ else throw new Error(`Template has multiple state machines (${machineIds.join(", ")}). Pass resourceId (or --resource) to choose one.`);
191
+ const properties = resources[chosenId].Properties ?? {};
192
+ if ("DefinitionUri" in properties && !("DefinitionString" in properties) && !("Definition" in properties)) throw new Error(`State machine '${chosenId}' uses an external DefinitionUri, which is not supported. Pass a template with an inline DefinitionString or Definition.`);
193
+ const substitutions = properties.DefinitionSubstitutions ?? {};
194
+ const rawDefinition = properties.DefinitionString ?? properties.Definition;
195
+ if (rawDefinition === void 0) throw new Error(`State machine '${chosenId}' has no DefinitionString or Definition.`);
196
+ const { value: resolved, warnings } = resolveIntrinsics({
197
+ substitutions,
198
+ value: rawDefinition
199
+ });
200
+ return {
201
+ aslDefinition: typeof resolved === "string" ? JSON.parse(resolved) : resolved,
202
+ resourceId: chosenId,
203
+ warnings
204
+ };
205
+ }
206
+ //#endregion
207
+ exports.extractAslFromTemplate = extractAslFromTemplate;
package/dist/cfn.d.cts ADDED
@@ -0,0 +1,102 @@
1
+ //#region src/types/index.d.ts
2
+ /** The set of Amazon States Language state types a state machine can contain. */
3
+ type StateType = "Pass" | "Task" | "Choice" | "Wait" | "Succeed" | "Fail" | "Parallel" | "Map";
4
+ /** An ASL `Catch` handler: routes matching errors to a fallback state. */
5
+ interface CatchBlock {
6
+ ErrorEquals: string[];
7
+ Next?: string;
8
+ ResultPath?: string;
9
+ }
10
+ /** An ASL `Retry` policy: re-attempts a state on matching errors with backoff. */
11
+ interface RetryBlock {
12
+ BackoffRate?: number;
13
+ ErrorEquals: string[];
14
+ IntervalSeconds?: number;
15
+ MaxAttempts?: number;
16
+ }
17
+ /** A single rule in a Choice state: a condition plus the `Next` state to take when it matches. */
18
+ interface ChoiceRule {
19
+ BooleanEquals?: boolean;
20
+ Next: string;
21
+ NumericEquals?: number;
22
+ StringEquals?: string;
23
+ Variable?: string;
24
+ [key: string]: any;
25
+ }
26
+ /** A single state within an ASL definition, covering fields for every state type. */
27
+ interface AslState {
28
+ Assign?: Record<string, any>;
29
+ Branches?: AslDefinition[];
30
+ Catch?: CatchBlock[];
31
+ Cause?: string;
32
+ Choices?: ChoiceRule[];
33
+ Comment?: string;
34
+ Default?: string;
35
+ End?: boolean;
36
+ Error?: string;
37
+ ItemProcessor?: AslDefinition;
38
+ Iterator?: AslDefinition;
39
+ Next?: string;
40
+ Output?: any;
41
+ Parameters?: Record<string, any>;
42
+ QueryLanguage?: "JSONata" | "JSONPath";
43
+ Resource?: string;
44
+ Result?: any;
45
+ ResultPath?: string;
46
+ Retry?: RetryBlock[];
47
+ Seconds?: number | string;
48
+ SecondsPath?: string;
49
+ Timestamp?: string;
50
+ TimestampPath?: string;
51
+ Type: StateType;
52
+ }
53
+ /** A complete Amazon States Language state machine definition. */
54
+ interface AslDefinition {
55
+ Comment?: string;
56
+ QueryLanguage?: "JSONata" | "JSONPath";
57
+ StartAt: string;
58
+ States: Record<string, AslState>;
59
+ TimeoutSeconds?: number;
60
+ Version?: string;
61
+ }
62
+ /** Parameters for `extractAslFromTemplate` (from the `sfn-diagram/cfn` subpath). */
63
+ interface ExtractAslFromTemplateParams {
64
+ /** Input format. 'auto' (default) sniffs JSON vs YAML. */
65
+ format?: "auto" | "json" | "yaml";
66
+ /** Logical id of the state machine to extract when the template has more than one. */
67
+ resourceId?: string;
68
+ /** Raw template string (JSON or YAML) or an already-parsed template object. */
69
+ template: string | Record<string, unknown>;
70
+ }
71
+ /** Result of extracting an ASL definition from a CloudFormation/SAM template. */
72
+ interface ExtractAslResult {
73
+ /** The recovered ASL definition, ready for generateSvg/generateMermaid/etc. */
74
+ aslDefinition: AslDefinition;
75
+ /** Logical id of the state machine that was extracted. */
76
+ resourceId: string;
77
+ /** Non-fatal notes (e.g. unresolved intrinsics replaced with placeholders). */
78
+ warnings: string[];
79
+ }
80
+ //#endregion
81
+ //#region src/cfn/extract.d.ts
82
+ /**
83
+ * Recovers a renderable ASL definition from a CloudFormation/SAM/CDK template.
84
+ *
85
+ * Locates the `AWS::StepFunctions::StateMachine` resource (disambiguated with
86
+ * `resourceId` when the template has more than one), flattens the intrinsics in
87
+ * its `DefinitionString`/`Definition`, applies `DefinitionSubstitutions`, and
88
+ * parses the result as ASL.
89
+ *
90
+ * @param params - Template source, optional format, optional resource id.
91
+ * @returns The extracted ASL definition, the logical id used, and any warnings.
92
+ * @throws If no state machine is found, the choice is ambiguous, or the
93
+ * definition is external (`DefinitionUri`).
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const { aslDefinition } = extractAslFromTemplate({ template: cdkSynthJson });
98
+ * ```
99
+ */
100
+ declare function extractAslFromTemplate(params: ExtractAslFromTemplateParams): ExtractAslResult;
101
+ //#endregion
102
+ export { type ExtractAslFromTemplateParams, type ExtractAslResult, extractAslFromTemplate };
package/dist/cfn.d.ts ADDED
@@ -0,0 +1,102 @@
1
+ //#region src/types/index.d.ts
2
+ /** The set of Amazon States Language state types a state machine can contain. */
3
+ type StateType = "Pass" | "Task" | "Choice" | "Wait" | "Succeed" | "Fail" | "Parallel" | "Map";
4
+ /** An ASL `Catch` handler: routes matching errors to a fallback state. */
5
+ interface CatchBlock {
6
+ ErrorEquals: string[];
7
+ Next?: string;
8
+ ResultPath?: string;
9
+ }
10
+ /** An ASL `Retry` policy: re-attempts a state on matching errors with backoff. */
11
+ interface RetryBlock {
12
+ BackoffRate?: number;
13
+ ErrorEquals: string[];
14
+ IntervalSeconds?: number;
15
+ MaxAttempts?: number;
16
+ }
17
+ /** A single rule in a Choice state: a condition plus the `Next` state to take when it matches. */
18
+ interface ChoiceRule {
19
+ BooleanEquals?: boolean;
20
+ Next: string;
21
+ NumericEquals?: number;
22
+ StringEquals?: string;
23
+ Variable?: string;
24
+ [key: string]: any;
25
+ }
26
+ /** A single state within an ASL definition, covering fields for every state type. */
27
+ interface AslState {
28
+ Assign?: Record<string, any>;
29
+ Branches?: AslDefinition[];
30
+ Catch?: CatchBlock[];
31
+ Cause?: string;
32
+ Choices?: ChoiceRule[];
33
+ Comment?: string;
34
+ Default?: string;
35
+ End?: boolean;
36
+ Error?: string;
37
+ ItemProcessor?: AslDefinition;
38
+ Iterator?: AslDefinition;
39
+ Next?: string;
40
+ Output?: any;
41
+ Parameters?: Record<string, any>;
42
+ QueryLanguage?: "JSONata" | "JSONPath";
43
+ Resource?: string;
44
+ Result?: any;
45
+ ResultPath?: string;
46
+ Retry?: RetryBlock[];
47
+ Seconds?: number | string;
48
+ SecondsPath?: string;
49
+ Timestamp?: string;
50
+ TimestampPath?: string;
51
+ Type: StateType;
52
+ }
53
+ /** A complete Amazon States Language state machine definition. */
54
+ interface AslDefinition {
55
+ Comment?: string;
56
+ QueryLanguage?: "JSONata" | "JSONPath";
57
+ StartAt: string;
58
+ States: Record<string, AslState>;
59
+ TimeoutSeconds?: number;
60
+ Version?: string;
61
+ }
62
+ /** Parameters for `extractAslFromTemplate` (from the `sfn-diagram/cfn` subpath). */
63
+ interface ExtractAslFromTemplateParams {
64
+ /** Input format. 'auto' (default) sniffs JSON vs YAML. */
65
+ format?: "auto" | "json" | "yaml";
66
+ /** Logical id of the state machine to extract when the template has more than one. */
67
+ resourceId?: string;
68
+ /** Raw template string (JSON or YAML) or an already-parsed template object. */
69
+ template: string | Record<string, unknown>;
70
+ }
71
+ /** Result of extracting an ASL definition from a CloudFormation/SAM template. */
72
+ interface ExtractAslResult {
73
+ /** The recovered ASL definition, ready for generateSvg/generateMermaid/etc. */
74
+ aslDefinition: AslDefinition;
75
+ /** Logical id of the state machine that was extracted. */
76
+ resourceId: string;
77
+ /** Non-fatal notes (e.g. unresolved intrinsics replaced with placeholders). */
78
+ warnings: string[];
79
+ }
80
+ //#endregion
81
+ //#region src/cfn/extract.d.ts
82
+ /**
83
+ * Recovers a renderable ASL definition from a CloudFormation/SAM/CDK template.
84
+ *
85
+ * Locates the `AWS::StepFunctions::StateMachine` resource (disambiguated with
86
+ * `resourceId` when the template has more than one), flattens the intrinsics in
87
+ * its `DefinitionString`/`Definition`, applies `DefinitionSubstitutions`, and
88
+ * parses the result as ASL.
89
+ *
90
+ * @param params - Template source, optional format, optional resource id.
91
+ * @returns The extracted ASL definition, the logical id used, and any warnings.
92
+ * @throws If no state machine is found, the choice is ambiguous, or the
93
+ * definition is external (`DefinitionUri`).
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const { aslDefinition } = extractAslFromTemplate({ template: cdkSynthJson });
98
+ * ```
99
+ */
100
+ declare function extractAslFromTemplate(params: ExtractAslFromTemplateParams): ExtractAslResult;
101
+ //#endregion
102
+ export { type ExtractAslFromTemplateParams, type ExtractAslResult, extractAslFromTemplate };