@kensio/yulin 1.21.23 → 1.21.25

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 (103) hide show
  1. package/dist/service/dynamodb/command/authorize/sim-dynamodb-authorizer.d.ts +19 -1
  2. package/dist/service/dynamodb/command/authorize/sim-dynamodb-authorizer.js +21 -3
  3. package/dist/service/dynamodb/command/authorize/sim-dynamodb-reached.d.ts +6 -3
  4. package/dist/service/dynamodb/command/query/sim-dynamodb-query.js +3 -1
  5. package/dist/service/dynamodb/command/scan/sim-dynamodb-scan.js +3 -1
  6. package/dist/service/dynamodb/command/table/sim-dynamodb-table-reach.d.ts +4 -0
  7. package/dist/service/dynamodb/command/table/sim-dynamodb-table-reach.js +1 -0
  8. package/dist/service/dynamodb/table/sim-dynamodb-table-arn.d.ts +13 -0
  9. package/dist/service/dynamodb/table/sim-dynamodb-table-arn.js +20 -0
  10. package/dist/service/wafv2/association/sim-aws-waf-protected-resources.js +4 -0
  11. package/dist/service/wafv2/association/sim-waf-associations.d.ts +6 -0
  12. package/dist/service/wafv2/association/sim-waf-associations.js +17 -0
  13. package/dist/service/wafv2/association/sim-waf-protected-resource.d.ts +13 -8
  14. package/dist/service/wafv2/association/sim-waf-protected-resource.js +23 -23
  15. package/dist/service/wafv2/association/sim-waf-protected-resources.d.ts +11 -6
  16. package/dist/service/wafv2/association/sim-waf-protected-resources.js +10 -7
  17. package/dist/service/wafv2/association/sim-waf-unsimulated-resource.d.ts +33 -0
  18. package/dist/service/wafv2/association/sim-waf-unsimulated-resource.js +66 -0
  19. package/dist/service/wafv2/cfn/association/sim-cfn-waf-association-creator.js +5 -0
  20. package/dist/service/wafv2/cfn/ip-set/sim-cfn-waf-ip-set-config.js +1 -0
  21. package/dist/service/wafv2/cfn/ip-set/sim-cfn-waf-ip-set-creator.js +2 -0
  22. package/dist/service/wafv2/cfn/regex-pattern-set/sim-cfn-waf-regex-set-config.js +1 -0
  23. package/dist/service/wafv2/cfn/regex-pattern-set/sim-cfn-waf-regex-set-creator.js +2 -0
  24. package/dist/service/wafv2/cfn/sim-cfn-waf-resource-config.d.ts +4 -0
  25. package/dist/service/wafv2/cfn/sim-cfn-waf-resource-config.js +10 -0
  26. package/dist/service/wafv2/cfn/sim-cfn-waf-unsimulated.d.ts +10 -0
  27. package/dist/service/wafv2/cfn/sim-cfn-waf-unsimulated.js +12 -0
  28. package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-web-acl-config.d.ts +1 -13
  29. package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-web-acl-config.js +8 -21
  30. package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-web-acl-creator.d.ts +4 -9
  31. package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-web-acl-creator.js +7 -15
  32. package/dist/service/wafv2/command/association/sim-wafv2-association-commands.js +2 -1
  33. package/dist/service/wafv2/command/association/sim-wafv2-association-input.d.ts +10 -2
  34. package/dist/service/wafv2/command/association/sim-wafv2-association-input.js +25 -13
  35. package/dist/service/wafv2/command/ip-set/sim-wafv2-ip-set-commands.d.ts +3 -3
  36. package/dist/service/wafv2/command/ip-set/sim-wafv2-ip-set-commands.js +5 -5
  37. package/dist/service/wafv2/command/managed-rule-group/sim-wafv2-managed-rule-group-commands.js +4 -4
  38. package/dist/service/wafv2/command/regex-pattern-set/sim-wafv2-regex-pattern-set-commands.js +2 -2
  39. package/dist/service/wafv2/command/sim-wafv2-input.d.ts +0 -7
  40. package/dist/service/wafv2/command/sim-wafv2-input.js +1 -13
  41. package/dist/service/wafv2/command/web-acl/sim-waf-web-acl-output.js +1 -0
  42. package/dist/service/wafv2/command/web-acl/sim-wafv2-unsimulated-web-acl-input.d.ts +9 -12
  43. package/dist/service/wafv2/command/web-acl/sim-wafv2-unsimulated-web-acl-input.js +27 -28
  44. package/dist/service/wafv2/command/web-acl/sim-wafv2-web-acl-commands.d.ts +3 -3
  45. package/dist/service/wafv2/command/web-acl/sim-wafv2-web-acl-commands.js +6 -6
  46. package/dist/service/wafv2/command/web-acl/web-acl.command.d.ts +6 -0
  47. package/dist/service/wafv2/index.d.ts +3 -0
  48. package/dist/service/wafv2/index.js +1 -0
  49. package/dist/service/wafv2/managed/group/sim-waf-bot-control.d.ts +27 -0
  50. package/dist/service/wafv2/managed/group/sim-waf-bot-control.js +68 -0
  51. package/dist/service/wafv2/managed/group/sim-waf-ip-reputation.d.ts +18 -0
  52. package/dist/service/wafv2/managed/group/sim-waf-ip-reputation.js +51 -0
  53. package/dist/service/wafv2/managed/sim-waf-bot-declaration.d.ts +35 -0
  54. package/dist/service/wafv2/managed/sim-waf-bot-declaration.js +42 -0
  55. package/dist/service/wafv2/managed/sim-waf-managed-declaration.d.ts +35 -0
  56. package/dist/service/wafv2/managed/sim-waf-managed-declaration.js +30 -0
  57. package/dist/service/wafv2/managed/sim-waf-managed-group-configs.d.ts +11 -0
  58. package/dist/service/wafv2/managed/sim-waf-managed-group-configs.js +42 -0
  59. package/dist/service/wafv2/managed/sim-waf-managed-group-input.d.ts +5 -4
  60. package/dist/service/wafv2/managed/sim-waf-managed-group-input.js +7 -9
  61. package/dist/service/wafv2/managed/sim-waf-managed-group-statement.js +16 -14
  62. package/dist/service/wafv2/managed/sim-waf-managed-group.type.d.ts +2 -2
  63. package/dist/service/wafv2/managed/sim-waf-managed-rule-actions.d.ts +30 -0
  64. package/dist/service/wafv2/managed/sim-waf-managed-rule-actions.js +26 -0
  65. package/dist/service/wafv2/managed/sim-waf-managed-rule-groups.d.ts +5 -3
  66. package/dist/service/wafv2/managed/sim-waf-managed-rule-groups.js +10 -3
  67. package/dist/service/wafv2/managed/sim-waf-managed-rule.type.d.ts +11 -2
  68. package/dist/service/wafv2/managed/sim-waf-managed-rules.d.ts +14 -9
  69. package/dist/service/wafv2/managed/sim-waf-managed-rules.js +15 -5
  70. package/dist/service/wafv2/resource/sim-waf-resource.d.ts +10 -0
  71. package/dist/service/wafv2/resource/sim-waf-resource.js +12 -0
  72. package/dist/service/wafv2/resource/sim-waf-unsimulated-part.d.ts +24 -0
  73. package/dist/service/wafv2/resource/sim-waf-unsimulated-part.js +8 -0
  74. package/dist/service/wafv2/sim-wafv2.d.ts +12 -12
  75. package/dist/service/wafv2/sim-wafv2.fixture.d.ts +19 -1
  76. package/dist/service/wafv2/sim-wafv2.fixture.js +29 -0
  77. package/dist/service/wafv2/sim-wafv2.js +25 -23
  78. package/dist/service/wafv2/statement/sim-waf-field-to-match.type.d.ts +2 -2
  79. package/dist/service/wafv2/statement/sim-waf-rule-refusals.d.ts +6 -4
  80. package/dist/service/wafv2/statement/sim-waf-rule-refusals.js +7 -6
  81. package/dist/service/wafv2/statement/sim-waf-statement.d.ts +3 -3
  82. package/dist/service/wafv2/statement/sim-waf-statement.js +3 -3
  83. package/dist/service/wafv2/statement/sim-waf-statement.type.d.ts +3 -3
  84. package/dist/service/wafv2/statement/sim-waf-unsimulated-statement.js +1 -1
  85. package/dist/service/wafv2/web-acl/sim-waf-association-config.d.ts +14 -7
  86. package/dist/service/wafv2/web-acl/sim-waf-association-config.js +17 -27
  87. package/dist/service/wafv2/web-acl/sim-waf-rule.d.ts +15 -3
  88. package/dist/service/wafv2/web-acl/sim-waf-rule.js +46 -10
  89. package/dist/service/wafv2/web-acl/sim-waf-statement-capacity.d.ts +4 -4
  90. package/dist/service/wafv2/web-acl/sim-waf-statement-capacity.js +4 -4
  91. package/dist/service/wafv2/web-acl/sim-waf-unsimulated-body-limit.d.ts +6 -0
  92. package/dist/service/wafv2/web-acl/sim-waf-unsimulated-body-limit.js +23 -0
  93. package/dist/service/wafv2/web-acl/sim-waf-web-acl-capacity.js +2 -2
  94. package/dist/service/wafv2/web-acl/sim-waf-web-acl-configuration.d.ts +5 -0
  95. package/dist/service/wafv2/web-acl/sim-waf-web-acl.d.ts +11 -2
  96. package/dist/service/wafv2/web-acl/sim-waf-web-acl.js +20 -1
  97. package/docs/services/dynamodb/README.md +26 -0
  98. package/docs/services/wafv2/README.md +243 -51
  99. package/package.json +3 -3
  100. package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-evaluatable-rules.d.ts +0 -15
  101. package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-evaluatable-rules.js +0 -21
  102. package/dist/service/wafv2/web-acl/sim-waf-unevaluatable-rules.d.ts +0 -25
  103. package/dist/service/wafv2/web-acl/sim-waf-unevaluatable-rules.js +0 -33
@@ -23,14 +23,23 @@ export type SimWafManagedDetector = (parts: SimWafManagedRequestParts) => boolea
23
23
  /**
24
24
  * One rule of an AWS managed rule group.
25
25
  *
26
- * Every rule in the three simulated groups blocks by default, so the action is
27
- * not carried here. A rule with no detector is a declared-only rule.
26
+ * A rule blocks by default unless it says it counts. A rule with no detector
27
+ * is a declared-only rule.
28
28
  */
29
29
  export interface SimWafManagedRuleDefinition {
30
30
  /** The rule name, as AWS names it and as an override names it. */
31
31
  readonly name: string;
32
32
  /** The label this rule adds, within its group's namespace. */
33
33
  readonly label: string;
34
+ /**
35
+ * The labels the rule adds beside its own, within its group's namespace.
36
+ *
37
+ * A Bot Control rule labels the bot category or the signal it found as well
38
+ * as itself.
39
+ */
40
+ readonly labels?: readonly string[] | undefined;
41
+ /** Whether the rule counts by default where most rules block. */
42
+ readonly counts?: boolean | undefined;
34
43
  readonly tier: SimWafManagedRuleTier;
35
44
  readonly detects?: SimWafManagedDetector | undefined;
36
45
  }
@@ -1,13 +1,8 @@
1
1
  import type { SimWafInspectedRequest } from "../evaluate/sim-waf-inspected-request.js";
2
2
  import { type SimWafManagedRuleReport } from "./sim-waf-managed-rule-report.js";
3
3
  import type { SimWafManagedRuleTier } from "./sim-waf-managed-rule.type.js";
4
- /**
5
- * The managed rules a test says claim a request.
6
- */
7
- export interface SimWafManagedMatchDeclaration {
8
- /** The rules that claim the request, by the name AWS gives them. */
9
- readonly matches: readonly string[];
10
- }
4
+ import { type SimWafDeclared, type SimWafManagedMatchDeclaration } from "./sim-waf-managed-declaration.js";
5
+ export type { SimWafDeclared, SimWafManagedMatchDeclaration, } from "./sim-waf-managed-declaration.js";
11
6
  /**
12
7
  * The managed rule matches this simulated WAFv2 answers with, and what it
13
8
  * covers of each rule.
@@ -24,6 +19,15 @@ export interface SimWafManagedMatchDeclaration {
24
19
  * });
25
20
  * ```
26
21
  *
22
+ * Bot Control is declared by the bot rather than the rule, since a verified
23
+ * bot is labelled and matches no rule:
24
+ *
25
+ * ```typescript
26
+ * simAws.wafV2().managedRules().onRequest("/search", {
27
+ * bot: { category: "search_engine", name: "googlebot", verified: true },
28
+ * });
29
+ * ```
30
+ *
27
31
  * A declared match is a match, and everything after it is what the group would
28
32
  * have done anyway: the rule adds its label, an action override applies to it,
29
33
  * and the group blocks by that rule.
@@ -39,9 +43,10 @@ export declare class SimWafManagedRules {
39
43
  */
40
44
  onRequest(uriPath: string, declaration: SimWafManagedMatchDeclaration): void;
41
45
  /**
42
- * The rules declared to claim one request.
46
+ * What a test declared about one request: the rules that claim it, and the
47
+ * labels a group adds to it whatever its rules decide.
43
48
  */
44
- declaredMatches(request: SimWafInspectedRequest): ReadonlySet<string>;
49
+ declared(request: SimWafInspectedRequest): SimWafDeclared;
45
50
  /**
46
51
  * What this simulation covers of one managed rule.
47
52
  */
@@ -1,7 +1,7 @@
1
1
  import { SimWafDeclarationError } from "../error/sim-wafv2.error.js";
2
2
  import { findSimWafManagedRule, } from "./sim-waf-managed-rule-groups.js";
3
3
  import { simWafManagedRuleReports, } from "./sim-waf-managed-rule-report.js";
4
- const noMatches = new Set();
4
+ import { simWafNothingDeclared, simWafReadDeclaration, } from "./sim-waf-managed-declaration.js";
5
5
  /**
6
6
  * The managed rule matches this simulated WAFv2 answers with, and what it
7
7
  * covers of each rule.
@@ -18,6 +18,15 @@ const noMatches = new Set();
18
18
  * });
19
19
  * ```
20
20
  *
21
+ * Bot Control is declared by the bot rather than the rule, since a verified
22
+ * bot is labelled and matches no rule:
23
+ *
24
+ * ```typescript
25
+ * simAws.wafV2().managedRules().onRequest("/search", {
26
+ * bot: { category: "search_engine", name: "googlebot", verified: true },
27
+ * });
28
+ * ```
29
+ *
21
30
  * A declared match is a match, and everything after it is what the group would
22
31
  * have done anyway: the rule adds its label, an action override applies to it,
23
32
  * and the group blocks by that rule.
@@ -36,13 +45,14 @@ export class SimWafManagedRules {
36
45
  throw new SimWafDeclarationError("A declared managed rule match needs the URI path of the request it " +
37
46
  "is declared for");
38
47
  }
39
- this.#byUriPath.set(uriPath, new Set(declaration.matches.map((name) => this.requiredRule(name).rule.name)));
48
+ this.#byUriPath.set(uriPath, simWafReadDeclaration(declaration, (name) => this.requiredRule(name).rule.name));
40
49
  }
41
50
  /**
42
- * The rules declared to claim one request.
51
+ * What a test declared about one request: the rules that claim it, and the
52
+ * labels a group adds to it whatever its rules decide.
43
53
  */
44
- declaredMatches(request) {
45
- return this.#byUriPath.get(request.uriPath) ?? noMatches;
54
+ declared(request) {
55
+ return this.#byUriPath.get(request.uriPath) ?? simWafNothingDeclared;
46
56
  }
47
57
  /**
48
58
  * What this simulation covers of one managed rule.
@@ -1,6 +1,7 @@
1
1
  import type { SimAwsAccountRegionScope } from "../../aws/sim-aws-account-region-scope.js";
2
2
  import { type SimWafResourceKind } from "../sim-wafv2-arn.js";
3
3
  import type { SimWafScope } from "../scope/sim-waf-scope.js";
4
+ import { type SimWafUnsimulatedPart } from "./sim-waf-unsimulated-part.js";
4
5
  /**
5
6
  * What every WAFv2 resource reports about itself in a listing.
6
7
  */
@@ -16,6 +17,7 @@ export interface SimWafResourceProperties {
16
17
  readonly scope: SimWafScope;
17
18
  readonly accountRegionScope: SimAwsAccountRegionScope;
18
19
  readonly description?: string | undefined;
20
+ readonly tags?: readonly unknown[] | undefined;
19
21
  }
20
22
  /**
21
23
  * What a web ACL, an IP set and a regex pattern set have in common.
@@ -32,11 +34,19 @@ export declare abstract class SimWafResource {
32
34
  readonly scope: SimWafScope;
33
35
  readonly id: string;
34
36
  readonly arn: string;
37
+ /** The tags the resource was created with, held as they were written. */
38
+ readonly tags: readonly unknown[];
35
39
  protected constructor(kind: SimWafResourceKind, properties: SimWafResourceProperties);
36
40
  /**
37
41
  * What the resource was created or last updated with as its description.
38
42
  */
39
43
  get description(): string | undefined;
44
+ /**
45
+ * What this resource was written with and the simulation does not act on.
46
+ *
47
+ * A web ACL adds the rules and members it holds without evaluating.
48
+ */
49
+ get unsimulated(): readonly SimWafUnsimulatedPart[];
40
50
  /**
41
51
  * The token the next write to this resource has to present.
42
52
  */
@@ -1,6 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { SimWafOptimisticLockException } from "../error/sim-wafv2.error.js";
3
3
  import { simWafArn } from "../sim-wafv2-arn.js";
4
+ import { simWafTagsParts, } from "./sim-waf-unsimulated-part.js";
4
5
  /**
5
6
  * What a web ACL, an IP set and a regex pattern set have in common.
6
7
  *
@@ -15,12 +16,15 @@ export class SimWafResource {
15
16
  scope;
16
17
  id = randomUUID();
17
18
  arn;
19
+ /** The tags the resource was created with, held as they were written. */
20
+ tags;
18
21
  #description;
19
22
  #lockToken = randomUUID();
20
23
  constructor(kind, properties) {
21
24
  this.name = properties.name;
22
25
  this.scope = properties.scope;
23
26
  this.#description = properties.description;
27
+ this.tags = properties.tags ?? [];
24
28
  this.arn = simWafArn({
25
29
  accountRegionScope: properties.accountRegionScope,
26
30
  scope: properties.scope,
@@ -35,6 +39,14 @@ export class SimWafResource {
35
39
  get description() {
36
40
  return this.#description;
37
41
  }
42
+ /**
43
+ * What this resource was written with and the simulation does not act on.
44
+ *
45
+ * A web ACL adds the rules and members it holds without evaluating.
46
+ */
47
+ get unsimulated() {
48
+ return simWafTagsParts(this.tags);
49
+ }
38
50
  /**
39
51
  * The token the next write to this resource has to present.
40
52
  */
@@ -0,0 +1,24 @@
1
+ /**
2
+ * One part of a WAFv2 write this simulation holds and does not act on.
3
+ *
4
+ * A write carrying something Yulin does not simulate is accepted, and the read
5
+ * that follows returns it as written. What the simulation leaves out is
6
+ * reported here instead, so a test can find out how far the resource it wrote
7
+ * is from the one AWS would run.
8
+ */
9
+ export interface SimWafUnsimulatedPart {
10
+ /**
11
+ * Where the part sits in what was written.
12
+ *
13
+ * A rule is `Rules.<rule name>`, a web ACL member is its own name, and a body
14
+ * inspection limit is `AssociationConfig.RequestBody.<resource type>`. These
15
+ * are the names a CloudFormation Resource records them under.
16
+ */
17
+ readonly part: string;
18
+ /** Why the simulation does not act on it. */
19
+ readonly reason: string;
20
+ }
21
+ /**
22
+ * What a resource's tags leave out, which is nothing when it has none.
23
+ */
24
+ export declare function simWafTagsParts(tags: readonly unknown[]): readonly SimWafUnsimulatedPart[];
@@ -0,0 +1,8 @@
1
+ const tagsReason = "the tags are held and nothing reads them, since ListTagsForResource is " +
2
+ "not simulated";
3
+ /**
4
+ * What a resource's tags leave out, which is nothing when it has none.
5
+ */
6
+ export function simWafTagsParts(tags) {
7
+ return tags.length === 0 ? [] : [{ part: "Tags", reason: tagsReason }];
8
+ }
@@ -8,12 +8,11 @@ import type { SimWafIpSet } from "./ip-set/sim-waf-ip-set.js";
8
8
  import type { SimWafManagedRules } from "./managed/sim-waf-managed-rules.js";
9
9
  import type { SimWafRegexPatternSet } from "./regex-pattern-set/sim-waf-regex-pattern-set.js";
10
10
  import type { SimWafScope } from "./scope/sim-waf-scope.js";
11
+ import type { SimWafUnsimulatedPart } from "./resource/sim-waf-unsimulated-part.js";
11
12
  import { type SimWafV2Properties } from "./sim-wafv2-commands.js";
12
13
  import { SimWafCfnResourceFactory } from "./cfn/sim-waf-cfn-resource-factory.js";
13
14
  import { SimWafSets } from "./sim-wafv2-sets.js";
14
15
  import type { SimWafWebAcl } from "./web-acl/sim-waf-web-acl.js";
15
- import { type SimWafUnevaluatableRule } from "./web-acl/sim-waf-unevaluatable-rules.js";
16
- import type { SimWafWebAclWriteInput } from "./command/web-acl/web-acl.command.js";
17
16
  export type { SimWafEvaluationRequest } from "./evaluate/sim-waf-evaluation-request.js";
18
17
  /**
19
18
  * Simulated AWS WAFv2. Handles SDK commands. Emulates AWS behaviour and state.
@@ -71,6 +70,13 @@ export declare class SimWafV2 extends SimWafSets {
71
70
  * compiled against, since a reference carries the ARN and nothing else.
72
71
  */
73
72
  findRegexPatternSetByArn(regexPatternSetArn: string): SimWafRegexPatternSet | undefined;
73
+ /**
74
+ * What a web ACL holds and this simulation does not act on, each part with
75
+ * its reason: a rule that claims no request (`Rules.<rule name>`), a member
76
+ * such as `CaptchaConfig`, a body inspection limit, the tags, and an
77
+ * association nothing is evaluated through (`Association.<resource ARN>`).
78
+ */
79
+ unsimulatedParts(webAclArn: string): readonly SimWafUnsimulatedPart[];
74
80
  /**
75
81
  * Evaluate one HTTP request against a web ACL's rules.
76
82
  *
@@ -89,16 +95,6 @@ export declare class SimWafV2 extends SimWafSets {
89
95
  * nothing here, and `rules()` reports what is covered of each.
90
96
  */
91
97
  managedRules(): SimWafManagedRules;
92
- /**
93
- * The rules of a web ACL input this simulation cannot evaluate.
94
- *
95
- * The simulator's own accessor rather than a WAFv2 operation. `CreateWebACL`
96
- * refuses a web ACL carrying such a rule, because a web ACL that accepted
97
- * one would allow a request AWS blocks. A template is deployed rule by rule
98
- * instead, so the CloudFormation layer asks this first and leaves the rules
99
- * it names out of the web ACL it writes.
100
- */
101
- unevaluatableWebAclRules(input: SimWafWebAclWriteInput): readonly SimWafUnevaluatableRule[];
102
98
  /**
103
99
  * Handle a CreateWebACL Command from the SDK.
104
100
  */
@@ -147,4 +143,8 @@ export declare class SimWafV2 extends SimWafSets {
147
143
  * Get this service's SDK Command router for SDK client interception.
148
144
  */
149
145
  sdkCommandRouter(): SimSdkCommandRouter;
146
+ /**
147
+ * Find a web ACL by its ARN, refusing one that is not here.
148
+ */
149
+ private requireWebAcl;
150
150
  }
@@ -1,5 +1,6 @@
1
- import type { SimCreateWebAclCommandInput, SimWafSummaryOutput } from "./command/web-acl/web-acl.command.js";
1
+ import type { SimCreateWebAclCommandInput, SimWafSummaryOutput, SimWafWebAclOutput } from "./command/web-acl/web-acl.command.js";
2
2
  import type { SimWafDecision } from "./evaluate/sim-waf-decision.js";
3
+ import type { SimWafUnsimulatedPart } from "./resource/sim-waf-unsimulated-part.js";
3
4
  import type { SimWafStatementInput } from "./statement/sim-waf-statement.type.js";
4
5
  import type { SimWafRuleInput } from "./web-acl/sim-waf-rule.type.js";
5
6
  import type { SimWafV2 } from "./sim-wafv2.js";
@@ -47,3 +48,20 @@ export declare function simWafWebAclDecisions(simWaf: SimWafV2, rules: readonly
47
48
  * makes its requests with this.
48
49
  */
49
50
  export declare function simWafBrowserRequest(url: string, init?: RequestInit): Request;
51
+ /**
52
+ * A web ACL as GetWebACL reads it back, what the simulation says it left out
53
+ * of it, and what it decided about an ordinary request.
54
+ */
55
+ export interface SimWafHeld {
56
+ readonly webAcl: SimWafWebAclOutput;
57
+ readonly parts: readonly SimWafUnsimulatedPart[];
58
+ readonly blocked: boolean;
59
+ }
60
+ /**
61
+ * Create a web ACL, read it back, and put one request through it.
62
+ */
63
+ export declare function simWafHeldWebAcl(simWaf: SimWafV2, webAcl: Partial<SimCreateWebAclCommandInput>): Promise<SimWafHeld>;
64
+ /**
65
+ * The reason the simulation gives for leaving out one part.
66
+ */
67
+ export declare function simWafUnsimulatedReason(parts: readonly SimWafUnsimulatedPart[], part: string): string;
@@ -60,3 +60,32 @@ export function simWafBrowserRequest(url, init = {}) {
60
60
  return new Request(url, { ...init, headers });
61
61
  }
62
62
  const browserUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36";
63
+ /**
64
+ * Create a web ACL, read it back, and put one request through it.
65
+ */
66
+ export async function simWafHeldWebAcl(simWaf, webAcl) {
67
+ const created = await createSimWafWebAcl(simWaf, {
68
+ ...simWafCreateWebAclFactory.make(),
69
+ ...webAcl,
70
+ });
71
+ const read = await simWaf.getWebAcl({
72
+ input: { Name: created.Name, Scope: "REGIONAL", Id: created.Id },
73
+ });
74
+ assertDefined(read.WebACL, "Simulated WAFv2 read back no web ACL");
75
+ return {
76
+ webAcl: read.WebACL,
77
+ parts: simWaf.unsimulatedParts(created.ARN),
78
+ blocked: simWaf.evaluateRequest({
79
+ webAclArn: created.ARN,
80
+ request: new Request("https://example.com/search"),
81
+ }).action === "BLOCK",
82
+ };
83
+ }
84
+ /**
85
+ * The reason the simulation gives for leaving out one part.
86
+ */
87
+ export function simWafUnsimulatedReason(parts, part) {
88
+ const found = parts.find((candidate) => candidate.part === part);
89
+ assertDefined(found, `Simulated WAFv2 reported no unsimulated part ${part}`);
90
+ return found.reason;
91
+ }
@@ -4,7 +4,6 @@ import { SimWafSdkCommandRouter } from "./sdk/sim-wafv2-sdk-command-router.js";
4
4
  import { SimWafCommands, } from "./sim-wafv2-commands.js";
5
5
  import { SimWafCfnResourceFactory } from "./cfn/sim-waf-cfn-resource-factory.js";
6
6
  import { SimWafSets } from "./sim-wafv2-sets.js";
7
- import { unevaluatableSimWafRules, } from "./web-acl/sim-waf-unevaluatable-rules.js";
8
7
  /**
9
8
  * Simulated AWS WAFv2. Handles SDK commands. Emulates AWS behaviour and state.
10
9
  *
@@ -74,6 +73,19 @@ export class SimWafV2 extends SimWafSets {
74
73
  findRegexPatternSetByArn(regexPatternSetArn) {
75
74
  return this.commands.regexPatternSets.findByArn(regexPatternSetArn);
76
75
  }
76
+ /**
77
+ * What a web ACL holds and this simulation does not act on, each part with
78
+ * its reason: a rule that claims no request (`Rules.<rule name>`), a member
79
+ * such as `CaptchaConfig`, a body inspection limit, the tags, and an
80
+ * association nothing is evaluated through (`Association.<resource ARN>`).
81
+ */
82
+ unsimulatedParts(webAclArn) {
83
+ const webAcl = this.requireWebAcl(webAclArn);
84
+ return [
85
+ ...webAcl.unsimulated,
86
+ ...this.commands.associations.unsimulatedFor(webAcl),
87
+ ];
88
+ }
77
89
  /**
78
90
  * Evaluate one HTTP request against a web ACL's rules.
79
91
  *
@@ -84,11 +96,7 @@ export class SimWafV2 extends SimWafSets {
84
96
  * front of.
85
97
  */
86
98
  evaluateRequest(evaluation) {
87
- const webAcl = this.findWebAclByArn(evaluation.webAclArn);
88
- if (webAcl === undefined) {
89
- throw new SimWafNonexistentItemException(`AWS WAF couldn't perform the operation because your resource ` +
90
- `doesn't exist: web ACL ${evaluation.webAclArn}.`);
91
- }
99
+ const webAcl = this.requireWebAcl(evaluation.webAclArn);
92
100
  const limitBytes = webAcl.bodyInspectionLimitBytes(evaluation.resourceType);
93
101
  return webAcl.evaluate(simWafInspectedRequest(evaluation.request, evaluation.body, limitBytes));
94
102
  }
@@ -102,23 +110,6 @@ export class SimWafV2 extends SimWafSets {
102
110
  managedRules() {
103
111
  return this.commands.managedRules;
104
112
  }
105
- /**
106
- * The rules of a web ACL input this simulation cannot evaluate.
107
- *
108
- * The simulator's own accessor rather than a WAFv2 operation. `CreateWebACL`
109
- * refuses a web ACL carrying such a rule, because a web ACL that accepted
110
- * one would allow a request AWS blocks. A template is deployed rule by rule
111
- * instead, so the CloudFormation layer asks this first and leaves the rules
112
- * it names out of the web ACL it writes.
113
- */
114
- unevaluatableWebAclRules(input) {
115
- return unevaluatableSimWafRules(input.Rules, {
116
- regexPatternSets: this.commands.regexPatternSets,
117
- managedRules: this.commands.managedRules,
118
- clock: this.commands.background,
119
- customResponseBodies: input.CustomResponseBodies ?? {},
120
- });
121
- }
122
113
  /**
123
114
  * Handle a CreateWebACL Command from the SDK.
124
115
  */
@@ -201,4 +192,15 @@ export class SimWafV2 extends SimWafSets {
201
192
  sdkCommandRouter() {
202
193
  return this.#sdkRouter;
203
194
  }
195
+ /**
196
+ * Find a web ACL by its ARN, refusing one that is not here.
197
+ */
198
+ requireWebAcl(webAclArn) {
199
+ const webAcl = this.findWebAclByArn(webAclArn);
200
+ if (webAcl === undefined) {
201
+ throw new SimWafNonexistentItemException(`AWS WAF couldn't perform the operation because your resource ` +
202
+ `doesn't exist: web ACL ${webAclArn}.`);
203
+ }
204
+ return webAcl;
205
+ }
204
206
  }
@@ -4,8 +4,8 @@ import type { SimWafMatchPatternInput } from "./sim-waf-match-pattern.js";
4
4
  * shape.
5
5
  *
6
6
  * The members Yulin does not simulate are declared here rather than left out,
7
- * so a rule that names one is refused by name instead of being read as a rule
8
- * with no field at all.
7
+ * so a rule that names one is held and reported by name instead of being read
8
+ * as a rule with no field at all.
9
9
  */
10
10
  export interface SimWafFieldToMatchInput {
11
11
  readonly UriPath?: unknown;
@@ -1,10 +1,12 @@
1
1
  /**
2
- * Refuse something in a rule that real WAFv2 takes and this simulation does
2
+ * Stop compiling a rule at something real WAFv2 takes and this simulation does
3
3
  * not.
4
4
  *
5
- * Every refusal names the rule and what in it was refused, because a web ACL
6
- * is a list of rules that all look alike from the outside and the name is the
7
- * only thing that says which one to go and look at.
5
+ * `SimWafRule.compile` catches it and holds the rule unevaluated, with this
6
+ * message as the reason the web ACL reports. The message names the rule and
7
+ * what in it was left out, because a web ACL is a list of rules that all look
8
+ * alike from the outside and the name is the only thing that says which one to
9
+ * go and look at.
8
10
  */
9
11
  export declare function refuseSimWafRuleInput(ruleName: string, refused: string, reason: string): never;
10
12
  /**
@@ -1,16 +1,17 @@
1
1
  import { SimWafInvalidParameterException, SimWafUnsimulatedInputException, } from "../error/sim-wafv2.error.js";
2
2
  /**
3
- * Refuse something in a rule that real WAFv2 takes and this simulation does
3
+ * Stop compiling a rule at something real WAFv2 takes and this simulation does
4
4
  * not.
5
5
  *
6
- * Every refusal names the rule and what in it was refused, because a web ACL
7
- * is a list of rules that all look alike from the outside and the name is the
8
- * only thing that says which one to go and look at.
6
+ * `SimWafRule.compile` catches it and holds the rule unevaluated, with this
7
+ * message as the reason the web ACL reports. The message names the rule and
8
+ * what in it was left out, because a web ACL is a list of rules that all look
9
+ * alike from the outside and the name is the only thing that says which one to
10
+ * go and look at.
9
11
  */
10
12
  export function refuseSimWafRuleInput(ruleName, refused, reason) {
11
13
  throw new SimWafUnsimulatedInputException(`Rule ${ruleName} uses ${refused}, which Yulin does not simulate: ` +
12
- `${reason}. A web ACL that accepted a rule it cannot evaluate would ` +
13
- `allow a request AWS blocks.`);
14
+ `${reason}. The rule is held and claims no request.`);
14
15
  }
15
16
  /**
16
17
  * Refuse a rule real WAFv2 would refuse too.
@@ -19,8 +19,8 @@ export interface SimWafStatementScope {
19
19
  * Turn one statement into the matcher a rule evaluates a request with.
20
20
  *
21
21
  * Compiling happens when the web ACL is written rather than when a request
22
- * arrives, which is what lets `CreateWebACL` refuse a statement kind it cannot
23
- * evaluate. It also means a rule does no parsing per request: what a request
24
- * meets is a closure over what the rule already worked out.
22
+ * arrives, which is where a statement kind Yulin cannot evaluate is found and
23
+ * its rule held unevaluated. It also means a rule does no parsing per request:
24
+ * what a request meets is a closure over what the rule already worked out.
25
25
  */
26
26
  export declare function compileSimWafStatement(statement: SimWafStatementInput | undefined, scope: SimWafStatementScope): SimWafMatcher;
@@ -11,9 +11,9 @@ import { refuseUnsimulatedSimWafStatement } from "./sim-waf-unsimulated-statemen
11
11
  * Turn one statement into the matcher a rule evaluates a request with.
12
12
  *
13
13
  * Compiling happens when the web ACL is written rather than when a request
14
- * arrives, which is what lets `CreateWebACL` refuse a statement kind it cannot
15
- * evaluate. It also means a rule does no parsing per request: what a request
16
- * meets is a closure over what the rule already worked out.
14
+ * arrives, which is where a statement kind Yulin cannot evaluate is found and
15
+ * its rule held unevaluated. It also means a rule does no parsing per request:
16
+ * what a request meets is a closure over what the rule already worked out.
17
17
  */
18
18
  export function compileSimWafStatement(statement, scope) {
19
19
  const { ruleName } = scope;
@@ -16,9 +16,9 @@ export interface SimWafFieldStatementInput {
16
16
  /**
17
17
  * Minimal structural WAFv2 Statement.
18
18
  *
19
- * The kinds Yulin refuses are declared alongside the ones it evaluates, so a
20
- * rule that uses one is refused by name rather than read as a rule with no
21
- * statement in it.
19
+ * The kinds Yulin does not evaluate are declared alongside the ones it does,
20
+ * so a rule that uses one is held and reported by name rather than read as a
21
+ * rule with no statement in it.
22
22
  *
23
23
  * https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/wafv2/Interface/Statement/
24
24
  */
@@ -6,7 +6,7 @@ const undocumentedDetection = "AWS does not document the detection it runs, so a
6
6
  "agree with real WAF by coincidence or not at all";
7
7
  /**
8
8
  * The statement kinds real WAFv2 evaluates and this simulation does not, and
9
- * why each of them is refused rather than deferred.
9
+ * why a rule using one is held unevaluated.
10
10
  */
11
11
  const refusedStatements = new Map([
12
12
  ["IPSetReferenceStatement", oneClientAddress],
@@ -1,10 +1,11 @@
1
+ import type { SimWafUnsimulatedPart } from "../resource/sim-waf-unsimulated-part.js";
1
2
  /**
2
3
  * A resource type whose body inspection limit a web ACL can set.
3
4
  *
4
5
  * Real WAF keys `AssociationConfig.RequestBody` by resource type, and these
5
- * three are the ones a web ACL goes in front of here. `APP_RUNNER_SERVICE` and
6
- * `VERIFIED_ACCESS_INSTANCE` are keys AWS takes for resources this simulation
7
- * has no association for.
6
+ * three are the ones a request reaches a web ACL through here. `APP_RUNNER_SERVICE`
7
+ * and `VERIFIED_ACCESS_INSTANCE` are keys AWS takes for resources a web ACL
8
+ * can be associated with and no simulated request passes through.
8
9
  */
9
10
  export type SimWafBodyInspectionResourceType = "CLOUDFRONT" | "API_GATEWAY" | "COGNITO_USER_POOL";
10
11
  /**
@@ -12,8 +13,8 @@ export type SimWafBodyInspectionResourceType = "CLOUDFRONT" | "API_GATEWAY" | "C
12
13
  * `AssociationConfig`.
13
14
  *
14
15
  * CloudFront, API Gateway and Cognito all default to 16 KB. A load balancer
15
- * and an AppSync API are fixed at 8 KB, and a web ACL cannot be put in front
16
- * of either one here.
16
+ * and an AppSync API are fixed at 8 KB, and no simulated request reaches a web
17
+ * ACL through either one.
17
18
  */
18
19
  export declare const simWafBodyInspectionLimitBytes = 16384;
19
20
  /**
@@ -40,9 +41,15 @@ export declare class SimWafBodyInspectionLimits {
40
41
  private constructor();
41
42
  /**
42
43
  * Read the limits an `AssociationConfig` sets, refusing anything WAF would
43
- * refuse and anything this simulation cannot apply.
44
+ * refuse.
44
45
  */
45
46
  static read(input: SimWafAssociationConfigInput | undefined): SimWafBodyInspectionLimits;
47
+ /**
48
+ * The limits set for resource types no simulated request passes through.
49
+ *
50
+ * Each is checked as WAF checks it and held, and applies to nothing.
51
+ */
52
+ get unsimulated(): readonly SimWafUnsimulatedPart[];
46
53
  /**
47
54
  * How many bytes of a body a request reaching one resource type is inspected
48
55
  * for.
@@ -50,5 +57,5 @@ export declare class SimWafBodyInspectionLimits {
50
57
  * A request evaluated against a web ACL that no resource holds names no
51
58
  * resource type, and reads the default.
52
59
  */
53
- bytesFor(resourceType: SimWafBodyInspectionResourceType | undefined): number;
60
+ bytesFor(resourceType: string | undefined): number;
54
61
  }