@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.
Files changed (164) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +30 -0
  3. package/SPEC.md +92 -0
  4. package/dist/actions.d.ts +87 -0
  5. package/dist/actions.d.ts.map +1 -0
  6. package/dist/actions.js +204 -0
  7. package/dist/actions.js.map +1 -0
  8. package/dist/aws.d.ts +27 -0
  9. package/dist/aws.d.ts.map +1 -0
  10. package/dist/aws.js +32 -0
  11. package/dist/aws.js.map +1 -0
  12. package/dist/blocks.d.ts +287 -0
  13. package/dist/blocks.d.ts.map +1 -0
  14. package/dist/blocks.js +352 -0
  15. package/dist/blocks.js.map +1 -0
  16. package/dist/codegen.d.ts +21 -0
  17. package/dist/codegen.d.ts.map +1 -0
  18. package/dist/codegen.js +1027 -0
  19. package/dist/codegen.js.map +1 -0
  20. package/dist/export.d.ts +256 -0
  21. package/dist/export.d.ts.map +1 -0
  22. package/dist/export.js +799 -0
  23. package/dist/export.js.map +1 -0
  24. package/dist/flow.d.ts +41 -0
  25. package/dist/flow.d.ts.map +1 -0
  26. package/dist/flow.js +85 -0
  27. package/dist/flow.js.map +1 -0
  28. package/dist/flowdoc.d.ts +111 -0
  29. package/dist/flowdoc.d.ts.map +1 -0
  30. package/dist/flowdoc.js +139 -0
  31. package/dist/flowdoc.js.map +1 -0
  32. package/dist/index.d.ts +16 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +26 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/layout.d.ts +11 -0
  37. package/dist/layout.d.ts.map +1 -0
  38. package/dist/layout.js +49 -0
  39. package/dist/layout.js.map +1 -0
  40. package/dist/lint/engine.d.ts +16 -0
  41. package/dist/lint/engine.d.ts.map +1 -0
  42. package/dist/lint/engine.js +37 -0
  43. package/dist/lint/engine.js.map +1 -0
  44. package/dist/lint/graph.d.ts +34 -0
  45. package/dist/lint/graph.d.ts.map +1 -0
  46. package/dist/lint/graph.js +79 -0
  47. package/dist/lint/graph.js.map +1 -0
  48. package/dist/lint/index.d.ts +7 -0
  49. package/dist/lint/index.d.ts.map +1 -0
  50. package/dist/lint/index.js +5 -0
  51. package/dist/lint/index.js.map +1 -0
  52. package/dist/lint/reporters.d.ts +6 -0
  53. package/dist/lint/reporters.d.ts.map +1 -0
  54. package/dist/lint/reporters.js +30 -0
  55. package/dist/lint/reporters.js.map +1 -0
  56. package/dist/lint/rules/action-allowed-in-flow-type.d.ts +11 -0
  57. package/dist/lint/rules/action-allowed-in-flow-type.d.ts.map +1 -0
  58. package/dist/lint/rules/action-allowed-in-flow-type.js +32 -0
  59. package/dist/lint/rules/action-allowed-in-flow-type.js.map +1 -0
  60. package/dist/lint/rules/action-count.d.ts +16 -0
  61. package/dist/lint/rules/action-count.d.ts.map +1 -0
  62. package/dist/lint/rules/action-count.js +32 -0
  63. package/dist/lint/rules/action-count.js.map +1 -0
  64. package/dist/lint/rules/error-branches.d.ts +10 -0
  65. package/dist/lint/rules/error-branches.d.ts.map +1 -0
  66. package/dist/lint/rules/error-branches.js +39 -0
  67. package/dist/lint/rules/error-branches.js.map +1 -0
  68. package/dist/lint/rules/index.d.ts +17 -0
  69. package/dist/lint/rules/index.d.ts.map +1 -0
  70. package/dist/lint/rules/index.js +36 -0
  71. package/dist/lint/rules/index.js.map +1 -0
  72. package/dist/lint/rules/module-depth-5.d.ts +14 -0
  73. package/dist/lint/rules/module-depth-5.d.ts.map +1 -0
  74. package/dist/lint/rules/module-depth-5.js +67 -0
  75. package/dist/lint/rules/module-depth-5.js.map +1 -0
  76. package/dist/lint/rules/no-literal-arn.d.ts +21 -0
  77. package/dist/lint/rules/no-literal-arn.d.ts.map +1 -0
  78. package/dist/lint/rules/no-literal-arn.js +58 -0
  79. package/dist/lint/rules/no-literal-arn.js.map +1 -0
  80. package/dist/lint/rules/no-unresolved-token.d.ts +8 -0
  81. package/dist/lint/rules/no-unresolved-token.d.ts.map +1 -0
  82. package/dist/lint/rules/no-unresolved-token.js +71 -0
  83. package/dist/lint/rules/no-unresolved-token.js.map +1 -0
  84. package/dist/lint/rules/prompt-length-3000.d.ts +16 -0
  85. package/dist/lint/rules/prompt-length-3000.d.ts.map +1 -0
  86. package/dist/lint/rules/prompt-length-3000.js +61 -0
  87. package/dist/lint/rules/prompt-length-3000.js.map +1 -0
  88. package/dist/lint/rules/reachable-blocks.d.ts +7 -0
  89. package/dist/lint/rules/reachable-blocks.d.ts.map +1 -0
  90. package/dist/lint/rules/reachable-blocks.js +45 -0
  91. package/dist/lint/rules/reachable-blocks.js.map +1 -0
  92. package/dist/lint/rules/recording-consent-before-record.d.ts +3 -0
  93. package/dist/lint/rules/recording-consent-before-record.d.ts.map +1 -0
  94. package/dist/lint/rules/recording-consent-before-record.js +87 -0
  95. package/dist/lint/rules/recording-consent-before-record.js.map +1 -0
  96. package/dist/lint/rules/terminal-blocks.d.ts +8 -0
  97. package/dist/lint/rules/terminal-blocks.d.ts.map +1 -0
  98. package/dist/lint/rules/terminal-blocks.js +40 -0
  99. package/dist/lint/rules/terminal-blocks.js.map +1 -0
  100. package/dist/lint/rules/unique-names.d.ts +7 -0
  101. package/dist/lint/rules/unique-names.d.ts.map +1 -0
  102. package/dist/lint/rules/unique-names.js +40 -0
  103. package/dist/lint/rules/unique-names.js.map +1 -0
  104. package/dist/lint/types.d.ts +30 -0
  105. package/dist/lint/types.d.ts.map +1 -0
  106. package/dist/lint/types.js +11 -0
  107. package/dist/lint/types.js.map +1 -0
  108. package/dist/materialize.d.ts +31 -0
  109. package/dist/materialize.d.ts.map +1 -0
  110. package/dist/materialize.js +192 -0
  111. package/dist/materialize.js.map +1 -0
  112. package/dist/package-names.d.ts +11 -0
  113. package/dist/package-names.d.ts.map +1 -0
  114. package/dist/package-names.js +25 -0
  115. package/dist/package-names.js.map +1 -0
  116. package/dist/refs.d.ts +35 -0
  117. package/dist/refs.d.ts.map +1 -0
  118. package/dist/refs.js +69 -0
  119. package/dist/refs.js.map +1 -0
  120. package/dist/serialize.d.ts +13 -0
  121. package/dist/serialize.d.ts.map +1 -0
  122. package/dist/serialize.js +86 -0
  123. package/dist/serialize.js.map +1 -0
  124. package/dist/simulate.d.ts +446 -0
  125. package/dist/simulate.d.ts.map +1 -0
  126. package/dist/simulate.js +1115 -0
  127. package/dist/simulate.js.map +1 -0
  128. package/dist/synth.d.ts +25 -0
  129. package/dist/synth.d.ts.map +1 -0
  130. package/dist/synth.js +93 -0
  131. package/dist/synth.js.map +1 -0
  132. package/package.json +73 -0
  133. package/src/actions.ts +221 -0
  134. package/src/aws.ts +55 -0
  135. package/src/blocks.ts +619 -0
  136. package/src/codegen.ts +1144 -0
  137. package/src/export.ts +1190 -0
  138. package/src/flow.ts +108 -0
  139. package/src/flowdoc.ts +261 -0
  140. package/src/index.ts +31 -0
  141. package/src/layout.ts +54 -0
  142. package/src/lint/engine.ts +56 -0
  143. package/src/lint/graph.ts +86 -0
  144. package/src/lint/index.ts +10 -0
  145. package/src/lint/reporters.ts +44 -0
  146. package/src/lint/rules/action-allowed-in-flow-type.ts +32 -0
  147. package/src/lint/rules/action-count.ts +35 -0
  148. package/src/lint/rules/error-branches.ts +45 -0
  149. package/src/lint/rules/index.ts +53 -0
  150. package/src/lint/rules/module-depth-5.ts +70 -0
  151. package/src/lint/rules/no-literal-arn.ts +64 -0
  152. package/src/lint/rules/no-unresolved-token.ts +80 -0
  153. package/src/lint/rules/prompt-length-3000.ts +66 -0
  154. package/src/lint/rules/reachable-blocks.ts +50 -0
  155. package/src/lint/rules/recording-consent-before-record.ts +90 -0
  156. package/src/lint/rules/terminal-blocks.ts +45 -0
  157. package/src/lint/rules/unique-names.ts +44 -0
  158. package/src/lint/types.ts +43 -0
  159. package/src/materialize.ts +230 -0
  160. package/src/package-names.ts +26 -0
  161. package/src/refs.ts +93 -0
  162. package/src/serialize.ts +97 -0
  163. package/src/simulate.ts +1610 -0
  164. package/src/synth.ts +110 -0
@@ -0,0 +1,446 @@
1
+ import { type AwsCommandSender, type RateLimiterOptions } from "./aws.js";
2
+ /** The scenario authoring format version. Bumped with a migration and fixtures. */
3
+ export declare const SCENARIO_VERSION = "0.1";
4
+ /**
5
+ * Documented harness limits. None of these is a Service Quota: the Connect
6
+ * service quotas page has no row for test cases, executions, concurrency, or
7
+ * duration, so there is no quota code and no increase to request. They are
8
+ * feature behaviors documented in the admin guide.
9
+ * https://docs.aws.amazon.com/connect/latest/adminguide/testing-simulation-execute-test-cases.html
10
+ */
11
+ export declare const SIMULATE_LIMITS: {
12
+ /** "You can run up to 5 concurrent tests." */
13
+ readonly concurrentTests: 5;
14
+ /**
15
+ * "The system accepts up to 100 test executions in the queue including the
16
+ * five running tests." The 100 is the total in flight, not 100 queued behind
17
+ * 5 running, and exceeding it is rejected with ServiceQuotaExceededException
18
+ * (HTTP 402) from StartTestCaseExecution.
19
+ */
20
+ readonly queueCapacityIncludingRunning: 100;
21
+ /**
22
+ * "Each test simulation has a maximum duration of 5 minutes." The cap is a
23
+ * hard timeout that reports the execution as FAILED, not as a neutral stop,
24
+ * which is why every compiled scenario ends with a TestControl EndTest.
25
+ */
26
+ readonly maxDurationMs: 300000;
27
+ };
28
+ /**
29
+ * The channel is an ENTRY POINT property, not an input kind: the API enum is
30
+ * TestCaseEntryPointType = CHAT | VOICE_CALL. DTMF, speech, and typed text are
31
+ * all SendInstruction instructions within whichever channel the entry point
32
+ * selected. SPEC.md conflated the two axes and is corrected.
33
+ */
34
+ export type ScenarioChannel = "voice" | "chat";
35
+ export interface ScenarioEntryPoint {
36
+ channel: ScenarioChannel;
37
+ /**
38
+ * `${cdref:flow:...}`; resolved to the entry point's FlowId before
39
+ * CreateTestCase. The resource map may hold either the bare flow id or the
40
+ * contact-flow ARN: the API reference types FlowId as a string of up to 500
41
+ * characters, and CreateTestCase accepted both forms for VOICE_CALL and CHAT
42
+ * (verified 2026-09-01).
43
+ * https://docs.aws.amazon.com/connect/latest/APIReference/API_VoiceCallEntryPointParameters.html
44
+ * https://docs.aws.amazon.com/connect/latest/APIReference/API_ChatEntryPointParameters.html
45
+ */
46
+ flow: string;
47
+ /**
48
+ * Voice only. The simulated caller's number, E.164 (`\+[1-9]\d{1,14}`).
49
+ * Defaults to the fictional VOICE_SOURCE_DEFAULT. There is no destination
50
+ * number: the API's VoiceCallEntryPointParameters treats FlowId and
51
+ * DestinationPhoneNumber as alternatives ("Must specify either FlowId or
52
+ * phone numbers", verified 2026-09-01), and a scenario always names its flow.
53
+ */
54
+ sourcePhoneNumber?: string;
55
+ }
56
+ /**
57
+ * Assert operators, from the assertion action page minus `Exists`. The page
58
+ * lists `Exists` with "operand not required", and CreateTestCase rejects it
59
+ * with "Invalid operator parameter for AssertAction" whether or not an Operand
60
+ * is given, as it rejects every other spelling tried (verified 2026-09-01).
61
+ * `Equals` without an Operand is rejected and `TextContains` and
62
+ * `TextStartsWith` accept an empty one; the other operators were only sent
63
+ * with an Operand, so the compiler always emits one.
64
+ * https://docs.aws.amazon.com/connect/latest/devguide/testing-language-actions-assertion.html
65
+ */
66
+ export type AssertOperator = "Equals" | "TextStartsWith" | "TextEndsWith" | "TextContains" | "NumberGreaterThan" | "NumberGreaterOrEqualTo" | "NumberLessThan" | "NumberLessOrEqualTo";
67
+ /**
68
+ * One ordered step. Every `expect-*` step opens a new Observation; every other
69
+ * step becomes an Action on the Observation opened most recently.
70
+ */
71
+ export type ScenarioStep =
72
+ /** MessageReceived with MatchingCriteria Inclusion (contains) or Similarity. */
73
+ {
74
+ kind: "expect-prompt";
75
+ contains?: string;
76
+ similarTo?: string;
77
+ }
78
+ /** FlowActionStarted / InvokeLambdaFunction. SPEC called this an expectation; it is an event. */
79
+ | {
80
+ kind: "expect-lambda";
81
+ lambda: string;
82
+ }
83
+ /** FlowActionStarted / TransferContactToQueue. */
84
+ | {
85
+ kind: "expect-transfer";
86
+ queue: string;
87
+ }
88
+ /** FlowActionStarted / CheckHoursOfOperation. */
89
+ | {
90
+ kind: "expect-hours-check";
91
+ hours: string;
92
+ }
93
+ /** FlowActionStarted / ConnectParticipantWithLexBot. */
94
+ | {
95
+ kind: "expect-lex";
96
+ lex: string;
97
+ }
98
+ /** Assert on $.Queue.Name, the documented namespace example. */
99
+ | {
100
+ kind: "expect-queue";
101
+ name: string;
102
+ }
103
+ /** Assert on any namespace. "attribute set" from SPEC.md lands here. */
104
+ | {
105
+ kind: "assert";
106
+ path: string;
107
+ operator: AssertOperator;
108
+ value: string;
109
+ }
110
+ /** Voice only: CreateTestCase rejects DtmfInput under a CHAT entry point. */
111
+ | {
112
+ kind: "send-dtmf";
113
+ value: string;
114
+ } | {
115
+ kind: "send-speech";
116
+ text: string;
117
+ languageCode?: string;
118
+ } | {
119
+ kind: "send-text";
120
+ text: string;
121
+ } | {
122
+ kind: "disconnect";
123
+ };
124
+ export type SubstitutionActionType = "TransferContactToQueue" | "CheckHoursOfOperation" | "InvokeLambdaFunction";
125
+ /**
126
+ * The ActionParameters key that names the resource being overridden, per
127
+ * action type, and the ref type that resource has. CreateTestCase rejects an
128
+ * override whose ActionParameters is empty ("InvalidFlowActionParametersProblem",
129
+ * verified 2026-09-01), so the parameter is required rather than defaulted.
130
+ * QueueId and HoursOfOperationId are verified 2026-09-01 (both substitutions
131
+ * were accepted and executed). LambdaFunctionARN comes from the documented
132
+ * shape only and has not been sent to a live instance:
133
+ * https://docs.aws.amazon.com/connect/latest/devguide/testing-language-actions-override-system-behavior.html
134
+ */
135
+ export declare const SUBSTITUTION_PARAMETER: Readonly<Record<SubstitutionActionType, {
136
+ key: string;
137
+ refType: "queue" | "hours" | "lambda";
138
+ }>>;
139
+ /**
140
+ * Swaps a production resource for a test one at run time. AWS documents this
141
+ * as one of the two ways to keep a simulated contact away from a live agent.
142
+ * https://docs.aws.amazon.com/connect/latest/devguide/testing-language-actions-override-system-behavior.html
143
+ */
144
+ export interface ScenarioSubstitution {
145
+ actionType: SubstitutionActionType;
146
+ /**
147
+ * Names the resource the flow uses, as the `${cdref:...}` token under the key
148
+ * SUBSTITUTION_PARAMETER gives for the action type (QueueId,
149
+ * HoursOfOperationId, or LambdaFunctionARN). Every value in the map is a
150
+ * token: the compiler copies the map verbatim into Content, so anything else
151
+ * would put a literal into the test case. A token may resolve to a bare id or
152
+ * an ARN; both are accepted (verified 2026-09-01).
153
+ */
154
+ actionParameters: Record<string, string>;
155
+ /** `${cdref:...}` of the same ref type, for the resource to substitute in. */
156
+ substitute: string;
157
+ }
158
+ export interface Scenario {
159
+ scenario: typeof SCENARIO_VERSION;
160
+ /** Slug. Used as the Connect test case Name and as the JUnit testcase name. */
161
+ name: string;
162
+ description?: string;
163
+ entryPoint: ScenarioEntryPoint;
164
+ /** Initial contact attributes. Becomes the InitializationData JSON string. */
165
+ attributes?: Record<string, string>;
166
+ steps: ScenarioStep[];
167
+ substitutions?: ScenarioSubstitution[];
168
+ /**
169
+ * Append a TestControl EndTest action. Default true, and turning it off is a
170
+ * validation error for any scenario that expects a queue transfer: without an
171
+ * explicit end "the simulated contact might reach the agent queue and connect
172
+ * with a live agent as a contact", and the run costs a full 5 minutes and
173
+ * reports FAILED besides.
174
+ * https://docs.aws.amazon.com/connect/latest/adminguide/testing-simulation-execute-test-cases.html
175
+ */
176
+ endTest?: boolean;
177
+ }
178
+ export interface ScenarioFinding {
179
+ /** JSON-ish path into the scenario, e.g. `steps[2].value`. */
180
+ path: string;
181
+ message: string;
182
+ }
183
+ /** Validation failed. Every finding is reported at once, as lint and materialize do. */
184
+ export declare class ScenarioValidationError extends Error {
185
+ readonly findings: readonly ScenarioFinding[];
186
+ constructor(findings: readonly ScenarioFinding[]);
187
+ }
188
+ /**
189
+ * Every problem in one pass. Cross-field safety rules live here rather than in
190
+ * the JSON Schema, which cannot express them readably; the schema is the
191
+ * structural half of the same contract
192
+ * (conformance/schema/scenario-0.1.schema.json).
193
+ */
194
+ export declare function validateScenario(value: unknown): ScenarioFinding[];
195
+ /** Validates and narrows. Throws a ScenarioValidationError listing every problem. */
196
+ export declare function parseScenario(value: unknown): Scenario;
197
+ export interface TestEvent {
198
+ Identifier: string;
199
+ Type: "TestInitiated" | "TestCompleted" | "MessageReceived" | "FlowActionStarted";
200
+ Actor: "System";
201
+ Properties: Record<string, unknown>;
202
+ }
203
+ /**
204
+ * A Connect Testing language Action.
205
+ *
206
+ * The discriminator is `Type` and the payload lives in `Parameters`; an
207
+ * earlier version of this file emitted `ActionType` at the top level with the
208
+ * payload flattened beside it, which no AWS example shows. Verified against the
209
+ * worked example, which is the only place the full envelope appears:
210
+ * https://docs.aws.amazon.com/connect/latest/devguide/testing-language-example.html
211
+ *
212
+ * Note that SendInstruction and OverrideSystemBehavior repeat `ActionType`
213
+ * INSIDE Parameters while Assert does not. That asymmetry is what the example
214
+ * shows, so it is reproduced faithfully rather than normalized.
215
+ */
216
+ export type TestActionType = "SendInstruction" | "Assert" | "OverrideSystemBehavior" | "TestControl";
217
+ export interface TestAction {
218
+ Identifier: string;
219
+ Type: TestActionType;
220
+ Parameters: Record<string, unknown>;
221
+ Transitions: Record<string, unknown>;
222
+ }
223
+ export interface TestObservation {
224
+ Identifier: string;
225
+ Event: TestEvent;
226
+ Actions: TestAction[];
227
+ Transitions: {
228
+ NextObservations: string[];
229
+ };
230
+ }
231
+ export interface TestingLanguageDocument {
232
+ Version: "2019-10-30";
233
+ Metadata: Record<string, unknown>;
234
+ Observations: TestObservation[];
235
+ }
236
+ /**
237
+ * The CreateTestCase EntryPoint. The compiler never emits
238
+ * DestinationPhoneNumber (see ScenarioEntryPoint), so the type does not carry
239
+ * it.
240
+ * https://docs.aws.amazon.com/connect/latest/APIReference/API_TestCaseEntryPoint.html
241
+ */
242
+ export interface TestCaseEntryPoint {
243
+ Type: "VOICE_CALL" | "CHAT";
244
+ VoiceCallEntryPointParameters?: {
245
+ SourcePhoneNumber?: string;
246
+ FlowId: string;
247
+ };
248
+ ChatEntryPointParameters?: {
249
+ FlowId: string;
250
+ };
251
+ }
252
+ /** Everything CreateTestCase needs, with `${cdref:...}` tokens still in place. */
253
+ export interface CompiledScenario {
254
+ name: string;
255
+ description?: string;
256
+ entryPoint: TestCaseEntryPoint;
257
+ /**
258
+ * The InitializationData JSON string. Documented only as "Defines the initial
259
+ * custom attributes for your test" and "must be a valid JSON string"; no
260
+ * example or key list is published, so the shape was found by executing
261
+ * variants against a sandbox (verified 2026-09-01):
262
+ *
263
+ * - `{"Attributes": {...}, "SegmentAttributes": {}}` is the only shape that
264
+ * read the value back: an Assert on `$.Attributes.<key>` PASSED with it.
265
+ * - A flat `{"key": "value"}` map, and the wrappers `ContactData`,
266
+ * `ContactAttributes`, `CustomAttributes` and JSONPath keys, are accepted
267
+ * by CreateTestCase but the Assert read `$.Attributes.<key>` back empty.
268
+ * - The lowercase `attributes` wrapper is accepted; its one execution failed
269
+ * on an observation before the Assert ran, so nothing is known about the
270
+ * value it produces.
271
+ * - `{"Attributes": {...}}` WITHOUT `SegmentAttributes` is accepted. Of three
272
+ * executions, one stayed INITIATED for the whole 240 s wait, and two
273
+ * started the contact but failed on an observation before the Assert ran,
274
+ * so it is not known to read back either. Both keys are always emitted
275
+ * because the two-key shape is the one shown to work.
276
+ * https://docs.aws.amazon.com/connect/latest/APIReference/API_CreateTestCase.html
277
+ */
278
+ initializationData?: string;
279
+ content: TestingLanguageDocument;
280
+ }
281
+ /**
282
+ * Scenario in, Connect Testing language out. Deterministic: identifiers are
283
+ * positional, so the same scenario compiles to the same bytes every time.
284
+ */
285
+ export declare function compileScenario(scenario: Scenario): CompiledScenario;
286
+ /** Canonical JSON for the CreateTestCase Content string. Byte-stable. */
287
+ export declare function serializeTestContent(content: TestingLanguageDocument): string;
288
+ /**
289
+ * Replaces every token in a compiled scenario with its resolved value. Strict,
290
+ * and it reports every missing token at once, exactly as materializeWithMap
291
+ * does; it throws the same MaterializeError so callers handle one type.
292
+ */
293
+ export declare function resolveScenario(compiled: CompiledScenario, resourceMap: Record<string, string>): CompiledScenario;
294
+ /** TestCaseExecutionStatus, verbatim from the API. */
295
+ export type TestExecutionStatus = "INITIATED" | "IN_PROGRESS" | "PASSED" | "FAILED" | "STOPPED";
296
+ export interface CreateTestCaseInput {
297
+ name: string;
298
+ description?: string;
299
+ /** The Content string: the compiled and resolved Testing language document. */
300
+ content: string;
301
+ entryPoint: TestCaseEntryPoint;
302
+ initializationData?: string;
303
+ /** PUBLISHED, because only a published test case can be executed. */
304
+ status: "PUBLISHED" | "SAVED";
305
+ }
306
+ export interface ExecutionSummary {
307
+ status: TestExecutionStatus;
308
+ startTime?: string;
309
+ endTime?: string;
310
+ observations?: {
311
+ total?: number;
312
+ passed?: number;
313
+ failed?: number;
314
+ };
315
+ }
316
+ export interface ExecutionRecordSummary {
317
+ observationId?: string;
318
+ status?: "PASSED" | "FAILED" | "IN_PROGRESS" | "STOPPED";
319
+ timestamp?: string;
320
+ /**
321
+ * "The details of the executed record", documented only as a string. Treated
322
+ * as an opaque message payload; its schema is not published.
323
+ * https://docs.aws.amazon.com/connect/latest/APIReference/API_ListTestCaseExecutionRecords.html
324
+ */
325
+ record?: string;
326
+ }
327
+ /**
328
+ * The narrow seam the runner talks to. Every method maps one-to-one onto a
329
+ * TestCase operation, so a fake in a test and the SDK adapter are the same
330
+ * shape.
331
+ */
332
+ export interface FlowTestClient {
333
+ createTestCase(input: CreateTestCaseInput): Promise<{
334
+ testCaseId: string;
335
+ testCaseArn?: string;
336
+ }>;
337
+ startExecution(testCaseId: string, clientToken?: string): Promise<{
338
+ testCaseExecutionId: string;
339
+ status: TestExecutionStatus;
340
+ }>;
341
+ getExecutionSummary(testCaseId: string, executionId: string): Promise<ExecutionSummary>;
342
+ listExecutionRecords(testCaseId: string, executionId: string): Promise<ExecutionRecordSummary[]>;
343
+ stopExecution(testCaseId: string, executionId: string): Promise<void>;
344
+ deleteTestCase(testCaseId: string): Promise<void>;
345
+ }
346
+ export type ScenarioStatus = "PASSED" | "FAILED" | "TIMED_OUT" | "ERRORED" | "STOPPED";
347
+ export interface ScenarioResult {
348
+ name: string;
349
+ status: ScenarioStatus;
350
+ durationMs: number;
351
+ testCaseId?: string;
352
+ executionId?: string;
353
+ observations?: {
354
+ total: number;
355
+ passed: number;
356
+ failed: number;
357
+ };
358
+ message?: string;
359
+ details?: string[];
360
+ }
361
+ export interface SimulationRun {
362
+ startedAt: string;
363
+ finishedAt: string;
364
+ totals: {
365
+ total: number;
366
+ passed: number;
367
+ failed: number;
368
+ timedOut: number;
369
+ errored: number;
370
+ stopped: number;
371
+ };
372
+ results: ScenarioResult[];
373
+ }
374
+ export interface RunOptions {
375
+ /** Token to value, exactly as materializeWithMap takes. */
376
+ resourceMap: Record<string, string>;
377
+ /** At most SIMULATE_LIMITS.concurrentTests. */
378
+ concurrency?: number;
379
+ /**
380
+ * Admission ceiling on executions this runner keeps in flight. Defaults to
381
+ * the documented queue capacity, which INCLUDES the running tests.
382
+ */
383
+ maxInFlight?: number;
384
+ /** Per scenario. Capped at the documented 5 minutes. */
385
+ timeoutMs?: number;
386
+ /**
387
+ * Poll interval for GetTestCaseExecutionSummary. Connect's default quota is
388
+ * 2 rps per account per Region across all operations, so polling faster than
389
+ * this buys nothing but ThrottlingExceptions.
390
+ * https://docs.aws.amazon.com/connect/latest/adminguide/amazon-connect-service-limits.html#connect-api-quotas
391
+ */
392
+ pollIntervalMs?: number;
393
+ /** Delete each test case after its execution finishes. Default true. */
394
+ cleanup?: boolean;
395
+ /**
396
+ * Extra starts per scenario when the first does not take: a
397
+ * ServiceQuotaExceededException (HTTP 402) from StartTestCaseExecution, or an
398
+ * execution that Connect reports FAILED with INITIALIZATION_FAILURE before it
399
+ * observed anything. Default 3. Backoff is pollIntervalMs times the attempt.
400
+ */
401
+ startRetries?: number;
402
+ /** Injected for tests. */
403
+ now?: () => number;
404
+ /** Injected for tests. */
405
+ sleep?: (ms: number) => Promise<void>;
406
+ /** Idempotency token per scenario. Default: the scenario name. */
407
+ clientToken?: (scenario: Scenario, attempt: number) => string;
408
+ }
409
+ /**
410
+ * Creates, publishes, executes, polls, collects, and deletes one test case per
411
+ * scenario, within the documented limits. The whole lifecycle exists because
412
+ * StartTestCaseExecution runs a stored, published test case and there is no
413
+ * submit-and-run call.
414
+ */
415
+ export declare function runScenarios(scenarios: readonly Scenario[], client: FlowTestClient, options: RunOptions): Promise<SimulationRun>;
416
+ /** Deterministic JSON report. Fixed key order, two-space indent, trailing newline. */
417
+ export declare function jsonReport(run: SimulationRun): string;
418
+ export interface JUnitOptions {
419
+ /** Suite name and testcase classname. Default "flow-simulate". */
420
+ suiteName?: string;
421
+ }
422
+ /**
423
+ * JUnit XML, deterministic for the same run: fixed attribute order, three
424
+ * decimal places, results in the order the suite declared them.
425
+ */
426
+ export declare function junitReport(run: SimulationRun, options?: JUnitOptions): string;
427
+ /**
428
+ * Folds the server's per-problem findings into the error message. The JS SDK
429
+ * exposes them as `problemDetails: [{ message }]` on InvalidTestCaseException;
430
+ * the API reference names the field `Problems`. Without this the runner reports
431
+ * the bare "Invalid test case content " and nothing to act on.
432
+ * https://docs.aws.amazon.com/connect/latest/APIReference/API_CreateTestCase.html
433
+ */
434
+ export declare function describeTestCaseError(error: unknown): Error;
435
+ export interface ConnectTestClientOptions extends RateLimiterOptions {
436
+ /** An @aws-sdk/client-connect ConnectClient, or anything with `send`. */
437
+ connect: AwsCommandSender;
438
+ /** Instance id or instance ARN. */
439
+ instanceId: string;
440
+ }
441
+ /**
442
+ * FlowTestClient over the AWS SDK. Rate limiting and the response-field naming
443
+ * differences live here; the runner sees neither.
444
+ */
445
+ export declare function createConnectTestClient(options: ConnectTestClientOptions): FlowTestClient;
446
+ //# sourceMappingURL=simulate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulate.d.ts","sourceRoot":"","sources":["../src/simulate.ts"],"names":[],"mappings":"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"}