@flow-as-code/core 0.1.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/LICENSE +202 -0
- package/README.md +30 -0
- package/SPEC.md +92 -0
- package/dist/actions.d.ts +87 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +204 -0
- package/dist/actions.js.map +1 -0
- package/dist/aws.d.ts +27 -0
- package/dist/aws.d.ts.map +1 -0
- package/dist/aws.js +32 -0
- package/dist/aws.js.map +1 -0
- package/dist/blocks.d.ts +287 -0
- package/dist/blocks.d.ts.map +1 -0
- package/dist/blocks.js +352 -0
- package/dist/blocks.js.map +1 -0
- package/dist/codegen.d.ts +21 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/codegen.js +1027 -0
- package/dist/codegen.js.map +1 -0
- package/dist/export.d.ts +256 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +799 -0
- package/dist/export.js.map +1 -0
- package/dist/flow.d.ts +41 -0
- package/dist/flow.d.ts.map +1 -0
- package/dist/flow.js +85 -0
- package/dist/flow.js.map +1 -0
- package/dist/flowdoc.d.ts +111 -0
- package/dist/flowdoc.d.ts.map +1 -0
- package/dist/flowdoc.js +139 -0
- package/dist/flowdoc.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.d.ts +11 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +49 -0
- package/dist/layout.js.map +1 -0
- package/dist/lint/engine.d.ts +16 -0
- package/dist/lint/engine.d.ts.map +1 -0
- package/dist/lint/engine.js +37 -0
- package/dist/lint/engine.js.map +1 -0
- package/dist/lint/graph.d.ts +34 -0
- package/dist/lint/graph.d.ts.map +1 -0
- package/dist/lint/graph.js +79 -0
- package/dist/lint/graph.js.map +1 -0
- package/dist/lint/index.d.ts +7 -0
- package/dist/lint/index.d.ts.map +1 -0
- package/dist/lint/index.js +5 -0
- package/dist/lint/index.js.map +1 -0
- package/dist/lint/reporters.d.ts +6 -0
- package/dist/lint/reporters.d.ts.map +1 -0
- package/dist/lint/reporters.js +30 -0
- package/dist/lint/reporters.js.map +1 -0
- package/dist/lint/rules/action-allowed-in-flow-type.d.ts +11 -0
- package/dist/lint/rules/action-allowed-in-flow-type.d.ts.map +1 -0
- package/dist/lint/rules/action-allowed-in-flow-type.js +32 -0
- package/dist/lint/rules/action-allowed-in-flow-type.js.map +1 -0
- package/dist/lint/rules/action-count.d.ts +16 -0
- package/dist/lint/rules/action-count.d.ts.map +1 -0
- package/dist/lint/rules/action-count.js +32 -0
- package/dist/lint/rules/action-count.js.map +1 -0
- package/dist/lint/rules/error-branches.d.ts +10 -0
- package/dist/lint/rules/error-branches.d.ts.map +1 -0
- package/dist/lint/rules/error-branches.js +39 -0
- package/dist/lint/rules/error-branches.js.map +1 -0
- package/dist/lint/rules/index.d.ts +17 -0
- package/dist/lint/rules/index.d.ts.map +1 -0
- package/dist/lint/rules/index.js +36 -0
- package/dist/lint/rules/index.js.map +1 -0
- package/dist/lint/rules/module-depth-5.d.ts +14 -0
- package/dist/lint/rules/module-depth-5.d.ts.map +1 -0
- package/dist/lint/rules/module-depth-5.js +67 -0
- package/dist/lint/rules/module-depth-5.js.map +1 -0
- package/dist/lint/rules/no-literal-arn.d.ts +21 -0
- package/dist/lint/rules/no-literal-arn.d.ts.map +1 -0
- package/dist/lint/rules/no-literal-arn.js +58 -0
- package/dist/lint/rules/no-literal-arn.js.map +1 -0
- package/dist/lint/rules/no-unresolved-token.d.ts +8 -0
- package/dist/lint/rules/no-unresolved-token.d.ts.map +1 -0
- package/dist/lint/rules/no-unresolved-token.js +71 -0
- package/dist/lint/rules/no-unresolved-token.js.map +1 -0
- package/dist/lint/rules/prompt-length-3000.d.ts +16 -0
- package/dist/lint/rules/prompt-length-3000.d.ts.map +1 -0
- package/dist/lint/rules/prompt-length-3000.js +61 -0
- package/dist/lint/rules/prompt-length-3000.js.map +1 -0
- package/dist/lint/rules/reachable-blocks.d.ts +7 -0
- package/dist/lint/rules/reachable-blocks.d.ts.map +1 -0
- package/dist/lint/rules/reachable-blocks.js +45 -0
- package/dist/lint/rules/reachable-blocks.js.map +1 -0
- package/dist/lint/rules/recording-consent-before-record.d.ts +3 -0
- package/dist/lint/rules/recording-consent-before-record.d.ts.map +1 -0
- package/dist/lint/rules/recording-consent-before-record.js +87 -0
- package/dist/lint/rules/recording-consent-before-record.js.map +1 -0
- package/dist/lint/rules/terminal-blocks.d.ts +8 -0
- package/dist/lint/rules/terminal-blocks.d.ts.map +1 -0
- package/dist/lint/rules/terminal-blocks.js +40 -0
- package/dist/lint/rules/terminal-blocks.js.map +1 -0
- package/dist/lint/rules/unique-names.d.ts +7 -0
- package/dist/lint/rules/unique-names.d.ts.map +1 -0
- package/dist/lint/rules/unique-names.js +40 -0
- package/dist/lint/rules/unique-names.js.map +1 -0
- package/dist/lint/types.d.ts +30 -0
- package/dist/lint/types.d.ts.map +1 -0
- package/dist/lint/types.js +11 -0
- package/dist/lint/types.js.map +1 -0
- package/dist/materialize.d.ts +31 -0
- package/dist/materialize.d.ts.map +1 -0
- package/dist/materialize.js +192 -0
- package/dist/materialize.js.map +1 -0
- package/dist/package-names.d.ts +11 -0
- package/dist/package-names.d.ts.map +1 -0
- package/dist/package-names.js +25 -0
- package/dist/package-names.js.map +1 -0
- package/dist/refs.d.ts +35 -0
- package/dist/refs.d.ts.map +1 -0
- package/dist/refs.js +69 -0
- package/dist/refs.js.map +1 -0
- package/dist/serialize.d.ts +13 -0
- package/dist/serialize.d.ts.map +1 -0
- package/dist/serialize.js +86 -0
- package/dist/serialize.js.map +1 -0
- package/dist/simulate.d.ts +446 -0
- package/dist/simulate.d.ts.map +1 -0
- package/dist/simulate.js +1115 -0
- package/dist/simulate.js.map +1 -0
- package/dist/synth.d.ts +25 -0
- package/dist/synth.d.ts.map +1 -0
- package/dist/synth.js +93 -0
- package/dist/synth.js.map +1 -0
- package/package.json +73 -0
- package/src/actions.ts +221 -0
- package/src/aws.ts +55 -0
- package/src/blocks.ts +619 -0
- package/src/codegen.ts +1144 -0
- package/src/export.ts +1190 -0
- package/src/flow.ts +108 -0
- package/src/flowdoc.ts +261 -0
- package/src/index.ts +31 -0
- package/src/layout.ts +54 -0
- package/src/lint/engine.ts +56 -0
- package/src/lint/graph.ts +86 -0
- package/src/lint/index.ts +10 -0
- package/src/lint/reporters.ts +44 -0
- package/src/lint/rules/action-allowed-in-flow-type.ts +32 -0
- package/src/lint/rules/action-count.ts +35 -0
- package/src/lint/rules/error-branches.ts +45 -0
- package/src/lint/rules/index.ts +53 -0
- package/src/lint/rules/module-depth-5.ts +70 -0
- package/src/lint/rules/no-literal-arn.ts +64 -0
- package/src/lint/rules/no-unresolved-token.ts +80 -0
- package/src/lint/rules/prompt-length-3000.ts +66 -0
- package/src/lint/rules/reachable-blocks.ts +50 -0
- package/src/lint/rules/recording-consent-before-record.ts +90 -0
- package/src/lint/rules/terminal-blocks.ts +45 -0
- package/src/lint/rules/unique-names.ts +44 -0
- package/src/lint/types.ts +43 -0
- package/src/materialize.ts +230 -0
- package/src/package-names.ts +26 -0
- package/src/refs.ts +93 -0
- package/src/serialize.ts +97 -0
- package/src/simulate.ts +1610 -0
- package/src/synth.ts +110 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { assertFlowDoc } from "../flowdoc.js";
|
|
2
|
+
import { allRules } from "./rules/index.js";
|
|
3
|
+
const order = (a, b) => a.doc.localeCompare(b.doc) ||
|
|
4
|
+
a.rule.localeCompare(b.rule) ||
|
|
5
|
+
(a.blockId ?? "").localeCompare(b.blockId ?? "") ||
|
|
6
|
+
a.message.localeCompare(b.message);
|
|
7
|
+
/**
|
|
8
|
+
* Runs every rule over every document. Findings are sorted so output is stable
|
|
9
|
+
* regardless of rule execution order.
|
|
10
|
+
*/
|
|
11
|
+
export function lint(input, options = {}) {
|
|
12
|
+
const docs = Array.isArray(input) ? input : [input];
|
|
13
|
+
// Rules read doc.content.Actions and doc.name directly. A malformed document
|
|
14
|
+
// used to surface as a TypeError from whichever rule happened to run first,
|
|
15
|
+
// which named neither lint nor the document.
|
|
16
|
+
for (const doc of docs)
|
|
17
|
+
assertFlowDoc(doc, "lint");
|
|
18
|
+
const disabled = new Set(options.disable ?? []);
|
|
19
|
+
const rules = (options.rules ?? allRules).filter((r) => !disabled.has(r.id));
|
|
20
|
+
const findings = [];
|
|
21
|
+
for (const doc of docs) {
|
|
22
|
+
for (const rule of rules) {
|
|
23
|
+
rule.check({
|
|
24
|
+
doc,
|
|
25
|
+
all: docs,
|
|
26
|
+
report: (f) => findings.push({ ...f, rule: rule.id, doc: doc.name }),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return findings.sort(order);
|
|
31
|
+
}
|
|
32
|
+
/** True when any finding would block a studio save. */
|
|
33
|
+
export function hasBlockingFindings(findings, rules = allRules) {
|
|
34
|
+
const hard = new Set(rules.filter((r) => r.hard).map((r) => r.id));
|
|
35
|
+
return findings.some((f) => hard.has(f.rule));
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/lint/engine.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAU5C,MAAM,KAAK,GAAG,CAAC,CAAU,EAAE,CAAU,EAAU,EAAE,CAC/C,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1B,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5B,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;IAChD,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAErC;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAC,KAAmC,EAAE,UAAuB,EAAE;IACjF,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAgB,CAAC,CAAC;IAC/D,6EAA6E;IAC7E,4EAA4E;IAC5E,6CAA6C;IAC7C,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAE7E,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC;gBACT,GAAG;gBACH,GAAG,EAAE,IAAI;gBACT,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;aACrE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,mBAAmB,CACjC,QAA4B,EAC5B,QAAyB,QAAQ;IAEjC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { FlowAction, FlowDoc } from "../flowdoc.js";
|
|
2
|
+
export declare function transitionTargets(action: FlowAction): string[];
|
|
3
|
+
export declare function isTerminal(action: FlowAction): boolean;
|
|
4
|
+
export declare function actionsById(doc: FlowDoc): Map<string, FlowAction>;
|
|
5
|
+
/** Identifiers reachable from StartAction. */
|
|
6
|
+
export declare function reachable(doc: FlowDoc): Set<string>;
|
|
7
|
+
/** Walks every string in a value, yielding [jsonPath, value] pairs. */
|
|
8
|
+
export declare function walkStrings(value: unknown, path?: string): [string, string][];
|
|
9
|
+
/**
|
|
10
|
+
* Every authored string in an action, with the path it sits at, for attributing
|
|
11
|
+
* a finding to a block.
|
|
12
|
+
*
|
|
13
|
+
* Transitions are included, not just Parameters. A condition operand is
|
|
14
|
+
* authored content like any other, and scanning only Parameters left a literal
|
|
15
|
+
* ARN or a malformed token in `Transitions.Conditions[n].Condition.Operands`
|
|
16
|
+
* completely undetected. Identifiers appearing here cannot produce false
|
|
17
|
+
* positives: Connect forbids ":" in an Identifier, so a NextAction can never
|
|
18
|
+
* look like an ARN or a token.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Authored strings that belong to the document rather than to any one action:
|
|
22
|
+
* today that is `content.Metadata`.
|
|
23
|
+
*
|
|
24
|
+
* materialize carries Metadata into deployable output and resolves tokens in
|
|
25
|
+
* it, so it is authored content by any reasonable reading, but nothing scanned
|
|
26
|
+
* it. A literal ARN placed there passed every gate and reached both deploy
|
|
27
|
+
* paths, including @flow-as-code/cdk, which refuses the identical ARN in Parameters.
|
|
28
|
+
*/
|
|
29
|
+
export declare function documentStrings(doc: FlowDoc): [string, string][];
|
|
30
|
+
export declare function findingsForActions(doc: FlowDoc): {
|
|
31
|
+
action: FlowAction;
|
|
32
|
+
strings: [string, string][];
|
|
33
|
+
}[];
|
|
34
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/lint/graph.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAEzD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,EAAE,CAO9D;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAEtD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAEjE;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAanD;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,SAAK,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CASzE;AAED;;;;;;;;;;GAUG;AACH;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAGhE;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,GACX;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;CAAE,EAAE,CAKvD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
// Shared traversal helpers. Browser-safe: no Node builtins.
|
|
6
|
+
export function transitionTargets(action) {
|
|
7
|
+
const t = action.Transitions;
|
|
8
|
+
return [
|
|
9
|
+
...(t.NextAction === undefined ? [] : [t.NextAction]),
|
|
10
|
+
...(t.Errors ?? []).map((e) => e.NextAction),
|
|
11
|
+
...(t.Conditions ?? []).map((c) => c.NextAction),
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
export function isTerminal(action) {
|
|
15
|
+
return Object.keys(action.Transitions).length === 0;
|
|
16
|
+
}
|
|
17
|
+
export function actionsById(doc) {
|
|
18
|
+
return new Map(doc.content.Actions.map((a) => [a.Identifier, a]));
|
|
19
|
+
}
|
|
20
|
+
/** Identifiers reachable from StartAction. */
|
|
21
|
+
export function reachable(doc) {
|
|
22
|
+
const byId = actionsById(doc);
|
|
23
|
+
const seen = new Set();
|
|
24
|
+
const queue = [doc.content.StartAction];
|
|
25
|
+
while (queue.length > 0) {
|
|
26
|
+
const id = queue.shift();
|
|
27
|
+
if (seen.has(id))
|
|
28
|
+
continue;
|
|
29
|
+
const action = byId.get(id);
|
|
30
|
+
if (action === undefined)
|
|
31
|
+
continue;
|
|
32
|
+
seen.add(id);
|
|
33
|
+
queue.push(...transitionTargets(action));
|
|
34
|
+
}
|
|
35
|
+
return seen;
|
|
36
|
+
}
|
|
37
|
+
/** Walks every string in a value, yielding [jsonPath, value] pairs. */
|
|
38
|
+
export function walkStrings(value, path = "") {
|
|
39
|
+
if (typeof value === "string")
|
|
40
|
+
return [[path, value]];
|
|
41
|
+
if (Array.isArray(value))
|
|
42
|
+
return value.flatMap((v, i) => walkStrings(v, `${path}[${i}]`));
|
|
43
|
+
if (value !== null && typeof value === "object") {
|
|
44
|
+
return Object.entries(value).flatMap(([k, v]) => walkStrings(v, path === "" ? k : `${path}.${k}`));
|
|
45
|
+
}
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Every authored string in an action, with the path it sits at, for attributing
|
|
50
|
+
* a finding to a block.
|
|
51
|
+
*
|
|
52
|
+
* Transitions are included, not just Parameters. A condition operand is
|
|
53
|
+
* authored content like any other, and scanning only Parameters left a literal
|
|
54
|
+
* ARN or a malformed token in `Transitions.Conditions[n].Condition.Operands`
|
|
55
|
+
* completely undetected. Identifiers appearing here cannot produce false
|
|
56
|
+
* positives: Connect forbids ":" in an Identifier, so a NextAction can never
|
|
57
|
+
* look like an ARN or a token.
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* Authored strings that belong to the document rather than to any one action:
|
|
61
|
+
* today that is `content.Metadata`.
|
|
62
|
+
*
|
|
63
|
+
* materialize carries Metadata into deployable output and resolves tokens in
|
|
64
|
+
* it, so it is authored content by any reasonable reading, but nothing scanned
|
|
65
|
+
* it. A literal ARN placed there passed every gate and reached both deploy
|
|
66
|
+
* paths, including @flow-as-code/cdk, which refuses the identical ARN in Parameters.
|
|
67
|
+
*/
|
|
68
|
+
export function documentStrings(doc) {
|
|
69
|
+
if (doc.content.Metadata === undefined)
|
|
70
|
+
return [];
|
|
71
|
+
return walkStrings(doc.content.Metadata, "content.Metadata");
|
|
72
|
+
}
|
|
73
|
+
export function findingsForActions(doc) {
|
|
74
|
+
return doc.content.Actions.map((action) => ({
|
|
75
|
+
action,
|
|
76
|
+
strings: [...walkStrings(action.Parameters), ...walkStrings(action.Transitions, "Transitions")],
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/lint/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { Finding, Rule, RuleContext, Severity } from "./types.js";
|
|
2
|
+
export { lint, hasBlockingFindings } from "./engine.js";
|
|
3
|
+
export type { LintOptions } from "./engine.js";
|
|
4
|
+
export { toJson, toText } from "./reporters.js";
|
|
5
|
+
export { allRules, ruleById } from "./rules/index.js";
|
|
6
|
+
export { NO_LITERAL_ARN, literalArnMessage, literalArnPaths } from "./rules/index.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lint/index.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { lint, hasBlockingFindings } from "./engine.js";
|
|
2
|
+
export { toJson, toText } from "./reporters.js";
|
|
3
|
+
export { allRules, ruleById } from "./rules/index.js";
|
|
4
|
+
export { NO_LITERAL_ARN, literalArnMessage, literalArnPaths } from "./rules/index.js";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lint/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Finding } from "./types.js";
|
|
2
|
+
/** Machine-readable. Stable shape; the CLI's --format json emits this. */
|
|
3
|
+
export declare function toJson(findings: readonly Finding[]): string;
|
|
4
|
+
/** Human-readable, one finding per line, grouped by document. */
|
|
5
|
+
export declare function toText(findings: readonly Finding[]): string;
|
|
6
|
+
//# sourceMappingURL=reporters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporters.d.ts","sourceRoot":"","sources":["../../src/lint/reporters.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,0EAA0E;AAC1E,wBAAgB,MAAM,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAY3D;AAED,iEAAiE;AACjE,wBAAgB,MAAM,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAqB3D"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Machine-readable. Stable shape; the CLI's --format json emits this. */
|
|
2
|
+
export function toJson(findings) {
|
|
3
|
+
const errors = findings.filter((f) => f.severity === "error").length;
|
|
4
|
+
return (JSON.stringify({
|
|
5
|
+
summary: { total: findings.length, errors, warnings: findings.length - errors },
|
|
6
|
+
findings,
|
|
7
|
+
}, null, 2) + "\n");
|
|
8
|
+
}
|
|
9
|
+
/** Human-readable, one finding per line, grouped by document. */
|
|
10
|
+
export function toText(findings) {
|
|
11
|
+
if (findings.length === 0)
|
|
12
|
+
return "No findings.\n";
|
|
13
|
+
const lines = [];
|
|
14
|
+
let current = "";
|
|
15
|
+
for (const f of findings) {
|
|
16
|
+
if (f.doc !== current) {
|
|
17
|
+
if (current !== "")
|
|
18
|
+
lines.push("");
|
|
19
|
+
lines.push(f.doc);
|
|
20
|
+
current = f.doc;
|
|
21
|
+
}
|
|
22
|
+
const where = f.blockId === undefined ? "" : ` (${f.blockId})`;
|
|
23
|
+
lines.push(` ${f.severity}${where}: ${f.message} [${f.rule}]`);
|
|
24
|
+
}
|
|
25
|
+
const errors = findings.filter((f) => f.severity === "error").length;
|
|
26
|
+
lines.push("");
|
|
27
|
+
lines.push(`${findings.length} finding(s): ${errors} error(s), ${findings.length - errors} warning(s).`);
|
|
28
|
+
return lines.join("\n") + "\n";
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=reporters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporters.js","sourceRoot":"","sources":["../../src/lint/reporters.ts"],"names":[],"mappings":"AAMA,0EAA0E;AAC1E,MAAM,UAAU,MAAM,CAAC,QAA4B;IACjD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IACrE,OAAO,CACL,IAAI,CAAC,SAAS,CACZ;QACE,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,GAAG,MAAM,EAAE;QAC/E,QAAQ;KACT,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,MAAM,CAAC,QAA4B;IACjD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,gBAAgB,CAAC;IAEnD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACtB,IAAI,OAAO,KAAK,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAClB,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC;QAClB,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC;QAC/D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,KAAK,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IACrE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACR,GAAG,QAAQ,CAAC,MAAM,gBAAgB,MAAM,cAAc,QAAQ,CAAC,MAAM,GAAG,MAAM,cAAc,CAC7F,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Rule } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Almost every Connect action documents a Restrictions section naming the flow
|
|
4
|
+
* types it is legal in. Deploying a flow that violates one fails at create time
|
|
5
|
+
* with a message that does not say which block is at fault.
|
|
6
|
+
*
|
|
7
|
+
* Added 2026-08-31 from the A00b reference; not one of the original nine rules
|
|
8
|
+
* in SPEC.md. Restrictions live in actions.ts, sourced per action page.
|
|
9
|
+
*/
|
|
10
|
+
export declare const actionAllowedInFlowType: Rule;
|
|
11
|
+
//# sourceMappingURL=action-allowed-in-flow-type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-allowed-in-flow-type.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/action-allowed-in-flow-type.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,EAAE,IAgBrC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { FLOW_TYPE_RESTRICTIONS } from "../../actions.js";
|
|
6
|
+
/**
|
|
7
|
+
* Almost every Connect action documents a Restrictions section naming the flow
|
|
8
|
+
* types it is legal in. Deploying a flow that violates one fails at create time
|
|
9
|
+
* with a message that does not say which block is at fault.
|
|
10
|
+
*
|
|
11
|
+
* Added 2026-08-31 from the A00b reference; not one of the original nine rules
|
|
12
|
+
* in SPEC.md. Restrictions live in actions.ts, sourced per action page.
|
|
13
|
+
*/
|
|
14
|
+
export const actionAllowedInFlowType = {
|
|
15
|
+
id: "action-allowed-in-flow-type",
|
|
16
|
+
description: "Each action must be legal in the flow type that contains it.",
|
|
17
|
+
check({ doc, report }) {
|
|
18
|
+
for (const action of doc.content.Actions) {
|
|
19
|
+
const allowed = FLOW_TYPE_RESTRICTIONS[action.Type];
|
|
20
|
+
if (allowed === undefined)
|
|
21
|
+
continue;
|
|
22
|
+
if (!allowed.includes(doc.connectType)) {
|
|
23
|
+
report({
|
|
24
|
+
severity: "error",
|
|
25
|
+
blockId: action.Identifier,
|
|
26
|
+
message: `${action.Type} is not allowed in a ${doc.connectType} flow. Allowed: ${allowed.join(", ")}.`,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=action-allowed-in-flow-type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-allowed-in-flow-type.js","sourceRoot":"","sources":["../../../src/lint/rules/action-allowed-in-flow-type.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAG1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAS;IAC3C,EAAE,EAAE,6BAA6B;IACjC,WAAW,EAAE,8DAA8D;IAC3E,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE;QACnB,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACpD,IAAI,OAAO,KAAK,SAAS;gBAAE,SAAS;YACpC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;gBACvC,MAAM,CAAC;oBACL,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,MAAM,CAAC,UAAU;oBAC1B,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,wBAAwB,GAAG,CAAC,WAAW,mBAAmB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;iBACvG,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Rule } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* "No more than 250 Actions per flow."
|
|
4
|
+
* https://docs.aws.amazon.com/connect/latest/devguide/flow-language-example.html
|
|
5
|
+
* (transcribed in conformance/flow-language/actions.md, document envelope).
|
|
6
|
+
*
|
|
7
|
+
* The FlowDoc schema says maxItems 250, but nothing on the authoring path runs
|
|
8
|
+
* the schema: render, codegen, materialization, and both emitters read the
|
|
9
|
+
* document straight. `Flow.add` refuses the 251st block, so a flow built with
|
|
10
|
+
* the builder cannot exceed the limit, but a FlowDoc that arrives any other way
|
|
11
|
+
* (hand-edited, exported from an instance, produced by another tool) reached
|
|
12
|
+
* emit with no complaint and failed at deploy time with a Connect error that
|
|
13
|
+
* names no block. This rule is the check on the FlowDoc path.
|
|
14
|
+
*/
|
|
15
|
+
export declare const actionCount: Rule;
|
|
16
|
+
//# sourceMappingURL=action-count.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-count.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/action-count.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,EAAE,IAczB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { MAX_ACTIONS_PER_FLOW } from "../../flowdoc.js";
|
|
6
|
+
/**
|
|
7
|
+
* "No more than 250 Actions per flow."
|
|
8
|
+
* https://docs.aws.amazon.com/connect/latest/devguide/flow-language-example.html
|
|
9
|
+
* (transcribed in conformance/flow-language/actions.md, document envelope).
|
|
10
|
+
*
|
|
11
|
+
* The FlowDoc schema says maxItems 250, but nothing on the authoring path runs
|
|
12
|
+
* the schema: render, codegen, materialization, and both emitters read the
|
|
13
|
+
* document straight. `Flow.add` refuses the 251st block, so a flow built with
|
|
14
|
+
* the builder cannot exceed the limit, but a FlowDoc that arrives any other way
|
|
15
|
+
* (hand-edited, exported from an instance, produced by another tool) reached
|
|
16
|
+
* emit with no complaint and failed at deploy time with a Connect error that
|
|
17
|
+
* names no block. This rule is the check on the FlowDoc path.
|
|
18
|
+
*/
|
|
19
|
+
export const actionCount = {
|
|
20
|
+
id: "action-count",
|
|
21
|
+
description: `A flow holds no more than ${String(MAX_ACTIONS_PER_FLOW)} actions.`,
|
|
22
|
+
check({ doc, report }) {
|
|
23
|
+
const count = doc.content.Actions.length;
|
|
24
|
+
if (count > MAX_ACTIONS_PER_FLOW) {
|
|
25
|
+
report({
|
|
26
|
+
severity: "error",
|
|
27
|
+
message: `Flow has ${String(count)} actions; Connect allows at most ${String(MAX_ACTIONS_PER_FLOW)}.`,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=action-count.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-count.js","sourceRoot":"","sources":["../../../src/lint/rules/action-count.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGxD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,EAAE,EAAE,cAAc;IAClB,WAAW,EAAE,6BAA6B,MAAM,CAAC,oBAAoB,CAAC,WAAW;IACjF,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE;QACnB,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;QACzC,IAAI,KAAK,GAAG,oBAAoB,EAAE,CAAC;YACjC,MAAM,CAAC;gBACL,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,YAAY,MAAM,CAAC,KAAK,CAAC,oCAAoC,MAAM,CAC1E,oBAAoB,CACrB,GAAG;aACL,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Rule } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The backstop for the type-level enforcement in the builder. It catches what
|
|
4
|
+
* types cannot: hand-edited FlowDocs, exported flows, and studio edits.
|
|
5
|
+
*
|
|
6
|
+
* Only modeled actions are checked. We cannot know an unmodeled action's error
|
|
7
|
+
* set, and some documented actions genuinely have none.
|
|
8
|
+
*/
|
|
9
|
+
export declare const errorBranches: Rule;
|
|
10
|
+
//# sourceMappingURL=error-branches.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-branches.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/error-branches.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAIxC;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,IAsB3B,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { ActionType, NO_MATCHING_CONDITION, NO_MATCHING_ERROR, TERMINAL_ACTIONS, } from "../../actions.js";
|
|
6
|
+
import { isTerminal } from "../graph.js";
|
|
7
|
+
const MODELED = new Set(Object.values(ActionType));
|
|
8
|
+
/**
|
|
9
|
+
* The backstop for the type-level enforcement in the builder. It catches what
|
|
10
|
+
* types cannot: hand-edited FlowDocs, exported flows, and studio edits.
|
|
11
|
+
*
|
|
12
|
+
* Only modeled actions are checked. We cannot know an unmodeled action's error
|
|
13
|
+
* set, and some documented actions genuinely have none.
|
|
14
|
+
*/
|
|
15
|
+
export const errorBranches = {
|
|
16
|
+
id: "error-branches",
|
|
17
|
+
description: "Every non-terminal modeled action must wire its catch-all error branch.",
|
|
18
|
+
check({ doc, report }) {
|
|
19
|
+
for (const action of doc.content.Actions) {
|
|
20
|
+
if (isTerminal(action))
|
|
21
|
+
continue;
|
|
22
|
+
if (!MODELED.has(action.Type))
|
|
23
|
+
continue;
|
|
24
|
+
if (TERMINAL_ACTIONS.includes(action.Type))
|
|
25
|
+
continue;
|
|
26
|
+
// Compare is the one modeled action that fails with NoMatchingCondition.
|
|
27
|
+
const expected = action.Type === ActionType.Compare ? NO_MATCHING_CONDITION : NO_MATCHING_ERROR;
|
|
28
|
+
const wired = (action.Transitions.Errors ?? []).some((e) => e.ErrorType === expected);
|
|
29
|
+
if (!wired) {
|
|
30
|
+
report({
|
|
31
|
+
severity: "error",
|
|
32
|
+
blockId: action.Identifier,
|
|
33
|
+
message: `${action.Type} does not wire its "${expected}" branch.`,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=error-branches.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-branches.js","sourceRoot":"","sources":["../../../src/lint/rules/error-branches.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAS;IACjC,EAAE,EAAE,gBAAgB;IACpB,WAAW,EAAE,yEAAyE;IACtF,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE;QACnB,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACzC,IAAI,UAAU,CAAC,MAAM,CAAC;gBAAE,SAAS;YACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,SAAS;YACxC,IAAI,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,SAAS;YAErD,yEAAyE;YACzE,MAAM,QAAQ,GACZ,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,iBAAiB,CAAC;YACjF,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC;YACtF,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC;oBACL,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,MAAM,CAAC,UAAU;oBAC1B,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,uBAAuB,QAAQ,WAAW;iBAClE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { actionAllowedInFlowType } from "./action-allowed-in-flow-type.js";
|
|
2
|
+
import { actionCount } from "./action-count.js";
|
|
3
|
+
import { errorBranches } from "./error-branches.js";
|
|
4
|
+
import { moduleDepth5 } from "./module-depth-5.js";
|
|
5
|
+
import { noLiteralArn } from "./no-literal-arn.js";
|
|
6
|
+
import { noUnresolvedToken } from "./no-unresolved-token.js";
|
|
7
|
+
import { promptLength3000 } from "./prompt-length-3000.js";
|
|
8
|
+
import { reachableBlocks } from "./reachable-blocks.js";
|
|
9
|
+
import { recordingConsentBeforeRecord } from "./recording-consent-before-record.js";
|
|
10
|
+
import { terminalBlocks } from "./terminal-blocks.js";
|
|
11
|
+
import { uniqueNames } from "./unique-names.js";
|
|
12
|
+
import type { Rule } from "../types.js";
|
|
13
|
+
export declare const allRules: readonly Rule[];
|
|
14
|
+
export declare function ruleById(id: string): Rule | undefined;
|
|
15
|
+
export { NO_LITERAL_ARN, literalArnMessage, literalArnPaths } from "./no-literal-arn.js";
|
|
16
|
+
export { actionAllowedInFlowType, actionCount, errorBranches, moduleDepth5, noLiteralArn, noUnresolvedToken, promptLength3000, reachableBlocks, recordingConsentBeforeRecord, terminalBlocks, uniqueNames, };
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,eAAO,MAAM,QAAQ,EAAE,SAAS,IAAI,EAYnC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAErD;AAED,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EACL,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,4BAA4B,EAC5B,cAAc,EACd,WAAW,GACZ,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
// Rule registry. Ids are stable and never renamed: the conformance fixtures,
|
|
6
|
+
// the CLI, the studio, and the future Go provider all key off them.
|
|
7
|
+
import { actionAllowedInFlowType } from "./action-allowed-in-flow-type.js";
|
|
8
|
+
import { actionCount } from "./action-count.js";
|
|
9
|
+
import { errorBranches } from "./error-branches.js";
|
|
10
|
+
import { moduleDepth5 } from "./module-depth-5.js";
|
|
11
|
+
import { noLiteralArn } from "./no-literal-arn.js";
|
|
12
|
+
import { noUnresolvedToken } from "./no-unresolved-token.js";
|
|
13
|
+
import { promptLength3000 } from "./prompt-length-3000.js";
|
|
14
|
+
import { reachableBlocks } from "./reachable-blocks.js";
|
|
15
|
+
import { recordingConsentBeforeRecord } from "./recording-consent-before-record.js";
|
|
16
|
+
import { terminalBlocks } from "./terminal-blocks.js";
|
|
17
|
+
import { uniqueNames } from "./unique-names.js";
|
|
18
|
+
export const allRules = [
|
|
19
|
+
noLiteralArn,
|
|
20
|
+
noUnresolvedToken,
|
|
21
|
+
reachableBlocks,
|
|
22
|
+
errorBranches,
|
|
23
|
+
terminalBlocks,
|
|
24
|
+
moduleDepth5,
|
|
25
|
+
promptLength3000,
|
|
26
|
+
recordingConsentBeforeRecord,
|
|
27
|
+
uniqueNames,
|
|
28
|
+
actionAllowedInFlowType,
|
|
29
|
+
actionCount,
|
|
30
|
+
];
|
|
31
|
+
export function ruleById(id) {
|
|
32
|
+
return allRules.find((r) => r.id === id);
|
|
33
|
+
}
|
|
34
|
+
export { NO_LITERAL_ARN, literalArnMessage, literalArnPaths } from "./no-literal-arn.js";
|
|
35
|
+
export { actionAllowedInFlowType, actionCount, errorBranches, moduleDepth5, noLiteralArn, noUnresolvedToken, promptLength3000, reachableBlocks, recordingConsentBeforeRecord, terminalBlocks, uniqueNames, };
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lint/rules/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,6EAA6E;AAC7E,oEAAoE;AAEpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,MAAM,CAAC,MAAM,QAAQ,GAAoB;IACvC,YAAY;IACZ,iBAAiB;IACjB,eAAe;IACf,aAAa;IACb,cAAc;IACd,YAAY;IACZ,gBAAgB;IAChB,4BAA4B;IAC5B,WAAW;IACX,uBAAuB;IACvB,WAAW;CACZ,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,EAAU;IACjC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EACL,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,4BAA4B,EAC5B,cAAc,EACd,WAAW,GACZ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Rule } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* "You can invoke modules within other modules, supporting up to five levels of
|
|
4
|
+
* nesting with a stack limit to prevent recursive invocations."
|
|
5
|
+
* https://docs.aws.amazon.com/connect/latest/adminguide/contact-flow-modules.html
|
|
6
|
+
*/
|
|
7
|
+
export declare const MAX_MODULE_DEPTH = 5;
|
|
8
|
+
/**
|
|
9
|
+
* Depth is only computable across a set: a document alone cannot know what the
|
|
10
|
+
* modules it invokes go on to invoke. Linting a single document therefore
|
|
11
|
+
* reports nothing here, which is correct rather than a false pass.
|
|
12
|
+
*/
|
|
13
|
+
export declare const moduleDepth5: Rule;
|
|
14
|
+
//# sourceMappingURL=module-depth-5.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-depth-5.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/module-depth-5.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAclC;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,IAoC1B,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The flow-as-code Authors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { ActionType } from "../../actions.js";
|
|
6
|
+
import { parseToken } from "../../refs.js";
|
|
7
|
+
/**
|
|
8
|
+
* "You can invoke modules within other modules, supporting up to five levels of
|
|
9
|
+
* nesting with a stack limit to prevent recursive invocations."
|
|
10
|
+
* https://docs.aws.amazon.com/connect/latest/adminguide/contact-flow-modules.html
|
|
11
|
+
*/
|
|
12
|
+
export const MAX_MODULE_DEPTH = 5;
|
|
13
|
+
function invokedModules(doc) {
|
|
14
|
+
const names = [];
|
|
15
|
+
for (const action of doc.content.Actions) {
|
|
16
|
+
if (action.Type !== ActionType.InvokeFlowModule)
|
|
17
|
+
continue;
|
|
18
|
+
const id = action.Parameters.FlowModuleId;
|
|
19
|
+
if (typeof id !== "string")
|
|
20
|
+
continue;
|
|
21
|
+
const ref = parseToken(id);
|
|
22
|
+
if (ref?.type === "module")
|
|
23
|
+
names.push(ref.name);
|
|
24
|
+
}
|
|
25
|
+
return names;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Depth is only computable across a set: a document alone cannot know what the
|
|
29
|
+
* modules it invokes go on to invoke. Linting a single document therefore
|
|
30
|
+
* reports nothing here, which is correct rather than a false pass.
|
|
31
|
+
*/
|
|
32
|
+
export const moduleDepth5 = {
|
|
33
|
+
id: "module-depth-5",
|
|
34
|
+
description: "Flow module invocation must not nest more than five levels deep, and must not recurse.",
|
|
35
|
+
check({ doc, all, report }) {
|
|
36
|
+
// Depth is measured from an entry point. Walking from every document would
|
|
37
|
+
// report the same violation once per document in the chain, so only flows
|
|
38
|
+
// start a walk. A module unreachable from any flow is dead code, which is
|
|
39
|
+
// reachable-blocks territory rather than this rule's.
|
|
40
|
+
if (doc.kind !== "flow")
|
|
41
|
+
return;
|
|
42
|
+
const modules = new Map(all.filter((d) => d.kind === "module").map((d) => [d.name, d]));
|
|
43
|
+
const walk = (current, depth, stack) => {
|
|
44
|
+
for (const name of invokedModules(current)) {
|
|
45
|
+
if (stack.includes(name)) {
|
|
46
|
+
report({
|
|
47
|
+
severity: "error",
|
|
48
|
+
message: `Recursive module invocation: ${[...stack, name].join(" -> ")}.`,
|
|
49
|
+
});
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (depth + 1 > MAX_MODULE_DEPTH) {
|
|
53
|
+
report({
|
|
54
|
+
severity: "error",
|
|
55
|
+
message: `Module nesting reaches depth ${depth + 1} via ${[...stack, name].join(" -> ")}; Connect allows ${MAX_MODULE_DEPTH}.`,
|
|
56
|
+
});
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const next = modules.get(name);
|
|
60
|
+
if (next !== undefined)
|
|
61
|
+
walk(next, depth + 1, [...stack, name]);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
walk(doc, 0, [doc.name]);
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=module-depth-5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-depth-5.js","sourceRoot":"","sources":["../../../src/lint/rules/module-depth-5.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,SAAS,cAAc,CAAC,GAAY;IAClC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACzC,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,gBAAgB;YAAE,SAAS;QAC1D,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC;QAC1C,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,SAAS;QACrC,MAAM,GAAG,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;QAC3B,IAAI,GAAG,EAAE,IAAI,KAAK,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,EAAE,EAAE,gBAAgB;IACpB,WAAW,EACT,wFAAwF;IAC1F,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE;QACxB,2EAA2E;QAC3E,0EAA0E;QAC1E,0EAA0E;QAC1E,sDAAsD;QACtD,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO;QAEhC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAExF,MAAM,IAAI,GAAG,CAAC,OAAgB,EAAE,KAAa,EAAE,KAAe,EAAQ,EAAE;YACtE,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzB,MAAM,CAAC;wBACL,QAAQ,EAAE,OAAO;wBACjB,OAAO,EAAE,gCAAgC,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG;qBAC1E,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBACD,IAAI,KAAK,GAAG,CAAC,GAAG,gBAAgB,EAAE,CAAC;oBACjC,MAAM,CAAC;wBACL,QAAQ,EAAE,OAAO;wBACjB,OAAO,EAAE,gCAAgC,KAAK,GAAG,CAAC,QAAQ,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,gBAAgB,GAAG;qBAC/H,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBACD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC/B,IAAI,IAAI,KAAK,SAAS;oBAAE,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;YAClE,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3B,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Rule } from "../types.js";
|
|
2
|
+
/** This rule's id, for tools that report the violation before lint can run. */
|
|
3
|
+
export declare const NO_LITERAL_ARN = "no-literal-arn";
|
|
4
|
+
/** The sentence every literal-ARN report ends with. */
|
|
5
|
+
export declare function literalArnMessage(path: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Paths of every string holding a literal ARN in an arbitrary JSON value.
|
|
8
|
+
*
|
|
9
|
+
* Takes `unknown` rather than a FlowDoc on purpose: the CLI runs this over a
|
|
10
|
+
* document the schema has already rejected, because the schema's own pattern
|
|
11
|
+
* errors describe that one mistake several times over and never name the rule.
|
|
12
|
+
* See packages/cli/src/docs.ts.
|
|
13
|
+
*/
|
|
14
|
+
export declare function literalArnPaths(value: unknown): string[];
|
|
15
|
+
/**
|
|
16
|
+
* References are tokens, never literal ARNs. A literal ARN pins a flow to one
|
|
17
|
+
* account, region, and instance, which is the whole thing this tooling exists
|
|
18
|
+
* to avoid.
|
|
19
|
+
*/
|
|
20
|
+
export declare const noLiteralArn: Rule;
|
|
21
|
+
//# sourceMappingURL=no-literal-arn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-literal-arn.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/no-literal-arn.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAIxC,+EAA+E;AAC/E,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAIxD;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,IA2B1B,CAAC"}
|