@kensio/yulin 1.20.14 → 1.20.16

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 (154) hide show
  1. package/README.md +13 -0
  2. package/{dist/config/oxlint/cffjs2.oxlintrc.json → cffjs2.oxlintrc.json} +1 -1
  3. package/dist/config/oxlint/cffjs2.oxlint.config.js +4 -3
  4. package/dist/sdk/module/sim-sdk-module-client-interceptor.d.ts +5 -0
  5. package/dist/sdk/module/sim-sdk-module-client-interceptor.js +14 -0
  6. package/dist/sdk/module/sim-sdk-static-client-factory.d.ts +26 -0
  7. package/dist/sdk/module/sim-sdk-static-client-factory.js +59 -0
  8. package/dist/sdk/send-patch.d.ts +8 -0
  9. package/dist/sdk/send-patch.js +11 -0
  10. package/dist/service/aws/caller/sim-aws-caller-resolver.d.ts +28 -6
  11. package/dist/service/aws/caller/sim-aws-caller-resolver.js +18 -11
  12. package/dist/service/aws/caller/sim-aws-caller.d.ts +9 -0
  13. package/dist/service/aws/caller/sim-aws-resolved-caller.d.ts +19 -0
  14. package/dist/service/aws/caller/sim-aws-resolved-caller.js +26 -0
  15. package/dist/service/aws/factory/sim-aws-account-region-service-builder.d.ts +6 -0
  16. package/dist/service/aws/factory/sim-aws-account-region-service-builder.js +3 -0
  17. package/dist/service/aws/factory/sim-aws-account-service-cache.d.ts +6 -0
  18. package/dist/service/aws/factory/sim-aws-account-service-cache.js +5 -0
  19. package/dist/service/aws/factory/sim-aws-service-factory.d.ts +5 -0
  20. package/dist/service/aws/factory/sim-aws-service-factory.js +6 -0
  21. package/dist/service/aws/sim-aws-properties.d.ts +15 -0
  22. package/dist/service/aws/sim-aws.js +2 -1
  23. package/dist/service/cloudformation/resource/resolve/property/sim-cfn-resource-property-resolver.d.ts +11 -4
  24. package/dist/service/cloudformation/resource/resolve/property/sim-cfn-resource-property-resolver.js +21 -8
  25. package/dist/service/cloudformation/resource/sim-cfn-resource.type.d.ts +9 -0
  26. package/dist/service/cloudformation/template/dynamic/make-sim-cfn-dynamic-references.d.ts +2 -0
  27. package/dist/service/cloudformation/template/dynamic/make-sim-cfn-dynamic-references.js +2 -2
  28. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-resolvers.d.ts +10 -0
  29. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-resolvers.js +4 -3
  30. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-scan.d.ts +11 -0
  31. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-scan.js +21 -0
  32. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-references.d.ts +24 -2
  33. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-references.js +50 -11
  34. package/dist/service/cloudformation/template/dynamic/sim-cfn-prefetched-dynamic-references.d.ts +42 -0
  35. package/dist/service/cloudformation/template/dynamic/sim-cfn-prefetched-dynamic-references.js +80 -0
  36. package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-failures.d.ts +16 -0
  37. package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-failures.js +19 -0
  38. package/dist/service/iam/authorize/context/sim-iam-auth-z-caller-context-builder.d.ts +30 -7
  39. package/dist/service/iam/authorize/context/sim-iam-auth-z-caller-context-builder.js +20 -11
  40. package/dist/service/iam/authorize/context/sim-iam-auth-z-context-builder.d.ts +2 -1
  41. package/dist/service/iam/authorize/context/sim-iam-auth-z-context-builder.js +5 -1
  42. package/dist/service/iam/authorize/match/sim-iam-policy-principal-matcher.d.ts +10 -0
  43. package/dist/service/iam/authorize/match/sim-iam-policy-principal-matcher.js +15 -3
  44. package/dist/service/iam/authorize/sim-iam-account-auth-z.d.ts +11 -4
  45. package/dist/service/iam/authorize/sim-iam-account-auth-z.js +5 -3
  46. package/dist/service/iam/authorize/sim-iam-authorizer.d.ts +2 -1
  47. package/dist/service/iam/authorize/sim-iam-authorizer.js +1 -0
  48. package/dist/service/iam/command/policy/create-policy/create-policy-input-resolver.js +4 -1
  49. package/dist/service/iam/command/policy/put-role-policy/put-role-policy.handler.js +5 -1
  50. package/dist/service/iam/command/policy/put-user-policy/put-user-policy.handler.js +5 -1
  51. package/dist/service/iam/policy/parse/sim-iam-document-parser.d.ts +4 -1
  52. package/dist/service/iam/policy/parse/sim-iam-document-parser.js +13 -15
  53. package/dist/service/iam/policy/sim-iam-statement-label.d.ts +28 -0
  54. package/dist/service/iam/policy/sim-iam-statement-label.js +17 -0
  55. package/dist/service/iam/policy/sim-iam-statement-strings.d.ts +11 -0
  56. package/dist/service/iam/policy/sim-iam-statement-strings.js +27 -0
  57. package/dist/service/iam/role/sim-iam-role-with-policy.factory.d.ts +9 -0
  58. package/dist/service/iam/role/sim-iam-role-with-policy.factory.js +4 -2
  59. package/dist/service/iam/sim-iam-account-parts.d.ts +8 -0
  60. package/dist/service/iam/sim-iam-account-parts.js +1 -0
  61. package/dist/service/iam/validate/sim-iam-policy-document-validator.d.ts +9 -2
  62. package/dist/service/iam/validate/sim-iam-policy-document-validator.js +37 -19
  63. package/dist/service/lambda/function/code/sim-lambda-vm-zip-function.factory.d.ts +7 -0
  64. package/dist/service/lambda/function/code/sim-lambda-vm-zip-function.factory.js +1 -0
  65. package/dist/service/lambda/function/code/vm/sdk/sim-lambda-provided-sdk-module.d.ts +19 -0
  66. package/dist/service/lambda/function/code/vm/sdk/sim-lambda-provided-sdk-module.js +78 -0
  67. package/dist/service/lambda/function/code/vm/sdk/sim-lambda-sdk-packages-not-installed.error.d.ts +15 -0
  68. package/dist/service/lambda/function/code/vm/sdk/sim-lambda-sdk-packages-not-installed.error.js +27 -0
  69. package/dist/service/lambda/function/code/vm/sdk/sim-lambda-vm-sdk-module-provider.d.ts +9 -0
  70. package/dist/service/lambda/function/code/vm/sdk/sim-sdk-lambda-vm-module-provider.d.ts +10 -0
  71. package/dist/service/lambda/function/code/vm/sdk/sim-sdk-lambda-vm-module-provider.js +28 -34
  72. package/dist/service/lambda/function/code/vm/sim-lambda-host-modules.d.ts +15 -0
  73. package/dist/service/lambda/function/code/vm/sim-lambda-host-modules.js +31 -0
  74. package/dist/service/lambda/function/code/vm/sim-lambda-vm-module-resolver.d.ts +7 -0
  75. package/dist/service/lambda/function/code/vm/sim-lambda-vm-module-resolver.js +15 -0
  76. package/dist/service/lambda/function/code/vm/sim-lambda-vm-modules.js +5 -4
  77. package/dist/service/s3/command/put-bucket-policy/put-bucket-policy.handler.js +4 -1
  78. package/dist/service/scheduler/delivery/sim-scheduler-delivery-failures.d.ts +16 -0
  79. package/dist/service/scheduler/delivery/sim-scheduler-delivery-failures.js +19 -0
  80. package/dist/service/scheduler/index.d.ts +1 -1
  81. package/dist/service/scheduler/index.js +1 -1
  82. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-dynamic-reference-resolver.d.ts +13 -15
  83. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-dynamic-reference-resolver.js +22 -43
  84. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-stand-in.d.ts +9 -0
  85. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-stand-in.js +14 -0
  86. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-value.d.ts +12 -0
  87. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-value.js +29 -0
  88. package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-dynamic-reference-resolver.d.ts +22 -6
  89. package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-dynamic-reference-resolver.js +39 -24
  90. package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-secure-dynamic-reference-resolver.d.ts +10 -5
  91. package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-secure-dynamic-reference-resolver.js +10 -8
  92. package/dist/service/ssm/sim-ssm.d.ts +10 -2
  93. package/dist/service/ssm/sim-ssm.js +12 -4
  94. package/dist/service/sts/auth-z/assume-role-auth-z-coordinator.d.ts +9 -2
  95. package/dist/service/sts/auth-z/assume-role-auth-z-coordinator.js +2 -2
  96. package/dist/service/sts/auth-z/assume-role-source-account-auth-z.d.ts +10 -4
  97. package/dist/service/sts/auth-z/assume-role-source-account-auth-z.js +8 -7
  98. package/dist/service/sts/auth-z/assume-role-target-auth-z.d.ts +2 -2
  99. package/dist/service/sts/auth-z/assume-role-trust-policy-authorizer.d.ts +6 -2
  100. package/dist/service/sts/auth-z/assume-role-trust-policy-authorizer.js +14 -11
  101. package/dist/service/sts/command/assume-role/assume-role.handler.d.ts +5 -1
  102. package/dist/service/sts/command/assume-role/assume-role.handler.js +5 -2
  103. package/dist/service/sts/command/get-caller-identity/get-caller-identity.handler.d.ts +5 -1
  104. package/dist/service/sts/command/get-caller-identity/get-caller-identity.handler.js +4 -1
  105. package/dist/service/sts/service-role/sim-service-role.js +5 -1
  106. package/dist/service/sts/sim-sts.d.ts +9 -1
  107. package/dist/service/sts/sim-sts.js +4 -0
  108. package/docs/README.md +54 -0
  109. package/docs/ai-skill/README.md +69 -0
  110. package/docs/cli/README.md +284 -0
  111. package/docs/factories/README.md +140 -0
  112. package/docs/lint/README.md +176 -0
  113. package/docs/non-aws-dependencies/README.md +261 -0
  114. package/docs/sdk/README.md +272 -0
  115. package/docs/serve/README.md +1126 -0
  116. package/docs/services/acm/README.md +823 -0
  117. package/docs/services/apigateway/README.md +1919 -0
  118. package/docs/services/apigatewayv2/README.md +2678 -0
  119. package/docs/services/athena/README.md +1044 -0
  120. package/docs/services/bedrock/README.md +350 -0
  121. package/docs/services/cloudformation/README.md +3440 -0
  122. package/docs/services/cloudfront/README.md +2874 -0
  123. package/docs/services/cloudwatch/README.md +420 -0
  124. package/docs/services/cognito/README.md +4923 -0
  125. package/docs/services/dynamodb/README.md +3784 -0
  126. package/docs/services/ecr/README.md +302 -0
  127. package/docs/services/ecs/README.md +2010 -0
  128. package/docs/services/elbv2/README.md +1897 -0
  129. package/docs/services/eventbridge/README.md +1110 -0
  130. package/docs/services/firehose/README.md +805 -0
  131. package/docs/services/glue/README.md +501 -0
  132. package/docs/services/iam/README.md +1283 -0
  133. package/docs/services/kinesis/README.md +454 -0
  134. package/docs/services/kms/README.md +659 -0
  135. package/docs/services/lambda/README.md +3645 -0
  136. package/docs/services/logs/README.md +868 -0
  137. package/docs/services/organizations/README.md +574 -0
  138. package/docs/services/personalize/README.md +835 -0
  139. package/docs/services/rekognition/README.md +1070 -0
  140. package/docs/services/route53/README.md +1783 -0
  141. package/docs/services/s3/README.md +3024 -0
  142. package/docs/services/scheduler/README.md +806 -0
  143. package/docs/services/secretsmanager/README.md +667 -0
  144. package/docs/services/ses/README.md +1011 -0
  145. package/docs/services/sns/README.md +1904 -0
  146. package/docs/services/sqs/README.md +1185 -0
  147. package/docs/services/ssm/README.md +1072 -0
  148. package/docs/services/stepfunctions/README.md +1332 -0
  149. package/docs/services/sts/README.md +245 -0
  150. package/docs/services/wafv2/README.md +1378 -0
  151. package/docs/terraform/README.md +248 -0
  152. package/docs/time/README.md +284 -0
  153. package/llms.txt +59 -0
  154. package/package.json +9 -5
@@ -1,6 +1,7 @@
1
1
  import { SimCfnParameters } from "../../../parameters/sim-cfn-parameters.js";
2
2
  import { SimCfnTemplateValueResolver } from "../../../template/value/sim-cfn-template-value-resolver.js";
3
3
  import { makeSimCfnDynamicReferences } from "../../../template/dynamic/make-sim-cfn-dynamic-references.js";
4
+ import { hasSimCfnDynamicReferenceIn } from "../../../template/dynamic/sim-cfn-dynamic-reference-scan.js";
4
5
  /**
5
6
  * Resolves CloudFormation Resource Properties immediately before Resource
6
7
  * creation.
@@ -36,10 +37,13 @@ export class SimCfnResourcePropertyResolver {
36
37
  * {@link SimCfnTemplateValueResolver}. If no Parameters are available, an empty
37
38
  * Parameter resolver is used so Resource Refs can still resolve.
38
39
  *
39
- * Resolution itself is synchronous, and the awaiting happens around it. A
40
- * dynamic reference naming a service that has to be waited on resolves to a
41
- * marker while the properties resolve, and the values replace the markers
42
- * here.
40
+ * Resolution itself is synchronous, and the awaiting happens around it.
41
+ * Properties holding a dynamic reference are resolved twice: the first pass
42
+ * reads the references and leaves them as the template wrote them, and the
43
+ * second finds the answers waiting, so an intrinsic function reading a
44
+ * reference's value gets the value rather than a marker. A reference the
45
+ * first pass never reached resolves to a marker instead, and the values
46
+ * replace the markers here.
43
47
  *
44
48
  * Resource Refs are read from the creation context. If a referenced Resource
45
49
  * is unexpectedly absent, the Ref is preserved as `{ Ref: logicalId }` rather
@@ -72,11 +76,15 @@ export class SimCfnResourcePropertyResolver {
72
76
  },
73
77
  },
74
78
  });
75
- const resolved = resolver.resolveRecord(properties);
76
79
  if (dynamicReferences === undefined) {
77
- return resolved;
80
+ return resolver.resolveRecord(properties);
78
81
  }
79
- return await dynamicReferences.settle(resolved);
82
+ if (hasSimCfnDynamicReferenceIn(properties)) {
83
+ await dynamicReferences.prefetch(() => {
84
+ resolver.resolveRecord(properties);
85
+ });
86
+ }
87
+ return await dynamicReferences.settle(resolver.resolveRecord(properties));
80
88
  }
81
89
  /**
82
90
  * The services answering this Resource's dynamic references.
@@ -84,14 +92,19 @@ export class SimCfnResourcePropertyResolver {
84
92
  * Absent where the caller has no simulation to read from, which is how the
85
93
  * resolver is used on its own in tests. A reference then stays in the
86
94
  * property as the template wrote it.
95
+ *
96
+ * The principal the operation runs as goes with the simulation, so a
97
+ * reference is read as the deployment's own caller rather than as the
98
+ * Account root.
87
99
  */
88
100
  dynamicReferences(context) {
89
- const { simAws } = context;
101
+ const { simAws, caller } = context;
90
102
  if (simAws === undefined || this.accountRegionScope === undefined) {
91
103
  return undefined;
92
104
  }
93
105
  return makeSimCfnDynamicReferences({
94
106
  simAws,
107
+ caller,
95
108
  accountRegionScope: this.accountRegionScope,
96
109
  propertyIgnorer: this.propertyIgnorer,
97
110
  resourceType: this.resourceType,
@@ -44,6 +44,15 @@ export interface SimCfnResourceResolveContext {
44
44
  * another service rather than from the template. A dynamic reference is one.
45
45
  */
46
46
  readonly simAws?: SimAws | undefined;
47
+ /**
48
+ * The principal the operation runs as, which a value read out of another
49
+ * service is authorized as. Real CloudFormation reads a dynamic reference
50
+ * under the Stack's execution role rather than as the Account root.
51
+ *
52
+ * Left out unless the deployment named one, which leaves each service to its
53
+ * own omitted-caller default of the Account root.
54
+ */
55
+ readonly caller?: SimAwsCaller | undefined;
47
56
  }
48
57
  export interface SimCloudFormationResourceCreateContext {
49
58
  readonly simAws: SimAws;
@@ -1,10 +1,12 @@
1
1
  import type { SimAws } from "../../../aws/sim-aws.js";
2
+ import type { SimAwsCaller } from "../../../aws/caller/sim-aws-caller.js";
2
3
  import type { SimAwsAccountRegionScope } from "../../../aws/sim-aws-account-region-scope.js";
3
4
  import type { SimCfnPropertyIgnorer } from "../../resource/ignore/sim-cfn-ignored-property.type.js";
4
5
  import { SimCfnDynamicReferences } from "./sim-cfn-dynamic-references.js";
5
6
  interface MakeSimCfnDynamicReferencesProperties {
6
7
  readonly simAws: SimAws;
7
8
  readonly accountRegionScope: SimAwsAccountRegionScope;
9
+ readonly caller?: SimAwsCaller | undefined;
8
10
  readonly propertyIgnorer?: SimCfnPropertyIgnorer | undefined;
9
11
  readonly resourceType?: string | undefined;
10
12
  }
@@ -4,7 +4,7 @@ import { simCfnDynamicReferenceResolvers } from "./sim-cfn-dynamic-reference-res
4
4
  * Build the dynamic reference resolvers for one Account and Region scope.
5
5
  */
6
6
  export function makeSimCfnDynamicReferences(properties) {
7
- const { simAws, accountRegionScope, propertyIgnorer, resourceType } = properties;
7
+ const { simAws, accountRegionScope, caller, propertyIgnorer, resourceType } = properties;
8
8
  const scopedAws = simAws.accountRegionScope(accountRegionScope.accountId, accountRegionScope.regionName);
9
9
  return new SimCfnDynamicReferences({
10
10
  propertyIgnorer,
@@ -13,7 +13,7 @@ export function makeSimCfnDynamicReferences(properties) {
13
13
  .entries()
14
14
  .map(([service, resolver]) => [
15
15
  service,
16
- resolver({ simAws, scopedAws }),
16
+ resolver({ simAws, scopedAws, caller }),
17
17
  ])),
18
18
  });
19
19
  }
@@ -1,4 +1,5 @@
1
1
  import type { SimAws } from "../../../aws/sim-aws.js";
2
+ import type { SimAwsCaller } from "../../../aws/caller/sim-aws-caller.js";
2
3
  import type { SimAwsAccountRegionContainer } from "../../../aws/sim-aws-account-region-scope.js";
3
4
  import type { SimCfnDynamicReferenceResolver } from "./sim-cfn-dynamic-reference.type.js";
4
5
  /**
@@ -12,6 +13,15 @@ import type { SimCfnDynamicReferenceResolver } from "./sim-cfn-dynamic-reference
12
13
  interface SimCfnDynamicReferenceSimulation {
13
14
  readonly simAws: SimAws;
14
15
  readonly scopedAws: SimAwsAccountRegionContainer;
16
+ /**
17
+ * The principal the deployment runs as, which the reference is read as. Real
18
+ * CloudFormation resolves a dynamic reference under the Stack's execution
19
+ * role, so a Stack deployed as a Role reads what that Role may read.
20
+ *
21
+ * Left out unless the deployment named one, which leaves each service to its
22
+ * own omitted-caller default of the Account root.
23
+ */
24
+ readonly caller?: SimAwsCaller | undefined;
15
25
  }
16
26
  /**
17
27
  * How one simulated service hands over its dynamic reference resolver, given
@@ -10,19 +10,20 @@ import { SimCfnSecretsManagerDynamicReferenceResolver } from "../../../secretsma
10
10
  export const simCfnDynamicReferenceResolvers = new Map([
11
11
  [
12
12
  "ssm",
13
- ({ scopedAws }) => scopedAws.ssm().cfnDynamicReferenceResolver(),
13
+ ({ scopedAws, caller }) => scopedAws.ssm().cfnDynamicReferenceResolver(caller),
14
14
  ],
15
15
  [
16
16
  "ssm-secure",
17
- ({ scopedAws }) => scopedAws.ssm().cfnSecureDynamicReferenceResolver(),
17
+ ({ scopedAws, caller }) => scopedAws.ssm().cfnSecureDynamicReferenceResolver(caller),
18
18
  ],
19
19
  [
20
20
  "secretsmanager",
21
- ({ simAws, scopedAws }) => new SimCfnSecretsManagerDynamicReferenceResolver({
21
+ ({ simAws, scopedAws, caller }) => new SimCfnSecretsManagerDynamicReferenceResolver({
22
22
  secretsManager: scopedAws.secretsManager(),
23
23
  secretsManagerIn: (scope) => simAws
24
24
  .accountRegionScope(scope.accountId, scope.regionName)
25
25
  .secretsManager(),
26
+ caller,
26
27
  }),
27
28
  ],
28
29
  ]);
@@ -1,3 +1,4 @@
1
+ import type { SimCfnTemplateValue } from "../value/sim-cfn-template-value.js";
1
2
  import type { SimCfnDynamicReference } from "./sim-cfn-dynamic-reference.type.js";
2
3
  /**
3
4
  * What a caller answers each reference with.
@@ -10,6 +11,16 @@ type SimCfnDynamicReferenceSubstitution = (reference: SimCfnDynamicReference) =>
10
11
  * Whether a string holds anything worth scanning.
11
12
  */
12
13
  export declare function hasSimCfnDynamicReference(text: string): boolean;
14
+ /**
15
+ * Whether anything in a template value was written as a dynamic reference.
16
+ *
17
+ * The opening is written literally in every template but a contrived one, so
18
+ * this answers whether a Resource's properties are worth reading references
19
+ * out of before they are resolved. A template building the opening itself,
20
+ * out of an `Fn::Join` over its characters, is answered no and reads its
21
+ * references while resolving instead.
22
+ */
23
+ export declare function hasSimCfnDynamicReferenceIn(value: SimCfnTemplateValue): boolean;
13
24
  /**
14
25
  * Replace every dynamic reference in a string with what the caller answers.
15
26
  *
@@ -17,6 +17,27 @@ const dynamicReferencePattern = /\{\{resolve:([A-Za-z][\w-]*):([^{}]*)\}\}/g;
17
17
  export function hasSimCfnDynamicReference(text) {
18
18
  return text.includes(dynamicReferenceOpening);
19
19
  }
20
+ /**
21
+ * Whether anything in a template value was written as a dynamic reference.
22
+ *
23
+ * The opening is written literally in every template but a contrived one, so
24
+ * this answers whether a Resource's properties are worth reading references
25
+ * out of before they are resolved. A template building the opening itself,
26
+ * out of an `Fn::Join` over its characters, is answered no and reads its
27
+ * references while resolving instead.
28
+ */
29
+ export function hasSimCfnDynamicReferenceIn(value) {
30
+ if (typeof value === "string") {
31
+ return hasSimCfnDynamicReference(value);
32
+ }
33
+ if (Array.isArray(value)) {
34
+ return value.some((entry) => hasSimCfnDynamicReferenceIn(entry));
35
+ }
36
+ if (value !== null && typeof value === "object") {
37
+ return Object.values(value).some((entry) => hasSimCfnDynamicReferenceIn(entry));
38
+ }
39
+ return false;
40
+ }
20
41
  /**
21
42
  * Replace every dynamic reference in a string with what the caller answers.
22
43
  *
@@ -19,15 +19,33 @@ interface SimCfnDynamicReferencesProperties {
19
19
  * what the ones this simulation has yet to implement do.
20
20
  *
21
21
  * One of these belongs to a single Resource's property resolution. That is
22
- * what lets it hold the references still being read. `substitute` runs while
23
- * the properties resolve, and `settle` finishes them afterwards.
22
+ * what lets it hold the references still being read. `prefetch` reads them
23
+ * ahead of resolution, `substitute` runs while the properties resolve, and
24
+ * `settle` finishes whatever the prefetch pass never reached.
24
25
  */
25
26
  export declare class SimCfnDynamicReferences {
26
27
  private readonly resolvers;
27
28
  private readonly propertyIgnorer;
28
29
  private readonly resourceType;
29
30
  private readonly awaited;
31
+ private readonly prefetched;
30
32
  constructor(properties: SimCfnDynamicReferencesProperties);
33
+ /**
34
+ * Read every reference the properties hold, before resolving them for real.
35
+ *
36
+ * A service that has to be waited on cannot answer during resolution, which
37
+ * is synchronous, so an `Fn::Split` over a reference would otherwise split
38
+ * something that is not the value yet. Resolving the properties twice is
39
+ * what avoids that: this pass leaves every reference as the template wrote
40
+ * it and only collects what the services answer, and the pass after it finds
41
+ * the answers already here.
42
+ *
43
+ * Nothing is recorded here and no failure escapes. A template this pass
44
+ * cannot resolve is resolved again straight afterwards, and that is the pass
45
+ * whose failure the Resource reports. A reference the pass never reached, or
46
+ * one whose service refused it, is left to `substitute` and `settle`.
47
+ */
48
+ prefetch(resolve: () => void): Promise<void>;
31
49
  /**
32
50
  * Replace every dynamic reference in a resolved string.
33
51
  *
@@ -44,6 +62,10 @@ export declare class SimCfnDynamicReferences {
44
62
  * whose properties name only services answering at once.
45
63
  */
46
64
  settle(properties: SimCfnTemplateValueRecord): Promise<SimCfnTemplateValueRecord>;
65
+ /**
66
+ * What one reference is replaced with, given the service answering it.
67
+ */
68
+ private substituted;
47
69
  /**
48
70
  * The value one reference resolved to.
49
71
  *
@@ -2,6 +2,7 @@ import { currentSimCfnValuePath } from "../value/sim-cfn-value-path.js";
2
2
  import { SimCfnAwaitedDynamicReferences } from "./sim-cfn-awaited-dynamic-references.js";
3
3
  import { fillSimCfnDynamicReferencePlaceholders } from "./sim-cfn-dynamic-reference-placeholder.js";
4
4
  import { substituteSimCfnDynamicReferences } from "./sim-cfn-dynamic-reference-scan.js";
5
+ import { SimCfnPrefetchedDynamicReferences } from "./sim-cfn-prefetched-dynamic-references.js";
5
6
  /**
6
7
  * The services a Stack's dynamic references are answered by.
7
8
  *
@@ -11,19 +12,39 @@ import { substituteSimCfnDynamicReferences } from "./sim-cfn-dynamic-reference-s
11
12
  * what the ones this simulation has yet to implement do.
12
13
  *
13
14
  * One of these belongs to a single Resource's property resolution. That is
14
- * what lets it hold the references still being read. `substitute` runs while
15
- * the properties resolve, and `settle` finishes them afterwards.
15
+ * what lets it hold the references still being read. `prefetch` reads them
16
+ * ahead of resolution, `substitute` runs while the properties resolve, and
17
+ * `settle` finishes whatever the prefetch pass never reached.
16
18
  */
17
19
  export class SimCfnDynamicReferences {
18
20
  resolvers;
19
21
  propertyIgnorer;
20
22
  resourceType;
21
23
  awaited = new SimCfnAwaitedDynamicReferences();
24
+ prefetched = new SimCfnPrefetchedDynamicReferences();
22
25
  constructor(properties) {
23
26
  this.resolvers = properties.resolvers;
24
27
  this.propertyIgnorer = properties.propertyIgnorer;
25
28
  this.resourceType = properties.resourceType;
26
29
  }
30
+ /**
31
+ * Read every reference the properties hold, before resolving them for real.
32
+ *
33
+ * A service that has to be waited on cannot answer during resolution, which
34
+ * is synchronous, so an `Fn::Split` over a reference would otherwise split
35
+ * something that is not the value yet. Resolving the properties twice is
36
+ * what avoids that: this pass leaves every reference as the template wrote
37
+ * it and only collects what the services answer, and the pass after it finds
38
+ * the answers already here.
39
+ *
40
+ * Nothing is recorded here and no failure escapes. A template this pass
41
+ * cannot resolve is resolved again straight afterwards, and that is the pass
42
+ * whose failure the Resource reports. A reference the pass never reached, or
43
+ * one whose service refused it, is left to `substitute` and `settle`.
44
+ */
45
+ async prefetch(resolve) {
46
+ await this.prefetched.read(resolve);
47
+ }
27
48
  /**
28
49
  * Replace every dynamic reference in a resolved string.
29
50
  *
@@ -37,15 +58,7 @@ export class SimCfnDynamicReferences {
37
58
  if (resolver === undefined) {
38
59
  return;
39
60
  }
40
- const path = currentSimCfnValuePath();
41
- const resolution = resolver.resolve(reference, {
42
- resourceType: this.resourceType,
43
- propertyPath: path,
44
- });
45
- if (resolution instanceof Promise) {
46
- return this.awaited.hold(resolution, path);
47
- }
48
- return this.answer(resolution, path);
61
+ return this.substituted(resolver, reference);
49
62
  });
50
63
  }
51
64
  /**
@@ -66,6 +79,32 @@ export class SimCfnDynamicReferences {
66
79
  ]));
67
80
  return fillSimCfnDynamicReferencePlaceholders(properties, values);
68
81
  }
82
+ /**
83
+ * What one reference is replaced with, given the service answering it.
84
+ */
85
+ substituted(resolver, reference) {
86
+ const path = currentSimCfnValuePath();
87
+ const key = `${path} ${reference.text}`;
88
+ const prefetched = this.prefetched.answerFor(key);
89
+ if (prefetched !== undefined) {
90
+ return this.answer(prefetched, path);
91
+ }
92
+ if (this.prefetched.isHeld(key)) {
93
+ return reference.text;
94
+ }
95
+ const resolution = resolver.resolve(reference, {
96
+ resourceType: this.resourceType,
97
+ propertyPath: path,
98
+ });
99
+ if (this.prefetched.isReading) {
100
+ this.prefetched.hold(key, resolution);
101
+ return reference.text;
102
+ }
103
+ if (resolution instanceof Promise) {
104
+ return this.awaited.hold(resolution, path);
105
+ }
106
+ return this.answer(resolution, path);
107
+ }
69
108
  /**
70
109
  * The value one reference resolved to.
71
110
  *
@@ -0,0 +1,42 @@
1
+ import type { SimCfnDynamicReferenceResolution } from "./sim-cfn-dynamic-reference.type.js";
2
+ /**
3
+ * The references of one property resolution that were read before it ran.
4
+ *
5
+ * A service that has to be waited on cannot answer while the properties
6
+ * resolve, because resolution is synchronous, so properties holding a
7
+ * reference are resolved twice. The first pass leaves every reference as the
8
+ * template wrote it and keeps what the services answer here. The second finds
9
+ * the answers waiting, so an `Fn::Split` over a reference splits the value
10
+ * rather than something standing in for it.
11
+ *
12
+ * A read that failed is not kept. The resolution pass asks its service again,
13
+ * and the failure reaches the Resource from there, which is what fails a
14
+ * Resource holding a reference the deployment may not read.
15
+ */
16
+ export declare class SimCfnPrefetchedDynamicReferences {
17
+ private readonly answers;
18
+ private reads;
19
+ /** Whether the pass running now is the one reading references ahead. */
20
+ get isReading(): boolean;
21
+ /**
22
+ * What one reference was already answered with, where it was.
23
+ */
24
+ answerFor(key: string): SimCfnDynamicReferenceResolution | undefined;
25
+ /**
26
+ * Whether the pass running now has already started reading one reference.
27
+ *
28
+ * A property holding the same reference twice would otherwise read it twice.
29
+ */
30
+ isHeld(key: string): boolean;
31
+ /**
32
+ * Keep one reference's answer for the resolution pass to use.
33
+ */
34
+ hold(key: string, resolution: SimCfnDynamicReferenceResolution | Promise<SimCfnDynamicReferenceResolution>): void;
35
+ /**
36
+ * Run one pass over the properties, keeping what its references answer.
37
+ *
38
+ * Nothing the pass throws escapes. The resolution pass after it resolves the
39
+ * same properties, and that is the pass whose failure the Resource reports.
40
+ */
41
+ read(pass: () => void): Promise<void>;
42
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * The references of one property resolution that were read before it ran.
3
+ *
4
+ * A service that has to be waited on cannot answer while the properties
5
+ * resolve, because resolution is synchronous, so properties holding a
6
+ * reference are resolved twice. The first pass leaves every reference as the
7
+ * template wrote it and keeps what the services answer here. The second finds
8
+ * the answers waiting, so an `Fn::Split` over a reference splits the value
9
+ * rather than something standing in for it.
10
+ *
11
+ * A read that failed is not kept. The resolution pass asks its service again,
12
+ * and the failure reaches the Resource from there, which is what fails a
13
+ * Resource holding a reference the deployment may not read.
14
+ */
15
+ export class SimCfnPrefetchedDynamicReferences {
16
+ answers = new Map();
17
+ reads;
18
+ /** Whether the pass running now is the one reading references ahead. */
19
+ get isReading() {
20
+ return this.reads !== undefined;
21
+ }
22
+ /**
23
+ * What one reference was already answered with, where it was.
24
+ */
25
+ answerFor(key) {
26
+ return this.answers.get(key);
27
+ }
28
+ /**
29
+ * Whether the pass running now has already started reading one reference.
30
+ *
31
+ * A property holding the same reference twice would otherwise read it twice.
32
+ */
33
+ isHeld(key) {
34
+ return this.reads?.has(key) === true;
35
+ }
36
+ /**
37
+ * Keep one reference's answer for the resolution pass to use.
38
+ */
39
+ hold(key, resolution) {
40
+ this.reads?.set(key, Promise.resolve(resolution));
41
+ }
42
+ /**
43
+ * Run one pass over the properties, keeping what its references answer.
44
+ *
45
+ * Nothing the pass throws escapes. The resolution pass after it resolves the
46
+ * same properties, and that is the pass whose failure the Resource reports.
47
+ */
48
+ async read(pass) {
49
+ const reads = new Map();
50
+ this.reads = reads;
51
+ try {
52
+ pass();
53
+ }
54
+ catch {
55
+ // The resolution pass after this one is the one that reports it.
56
+ }
57
+ finally {
58
+ this.reads = undefined;
59
+ }
60
+ const answers = await Promise.all(reads
61
+ .entries()
62
+ .map(async ([key, read]) => await prefetchedReference(key, read)));
63
+ for (const answer of answers) {
64
+ if (answer !== undefined) {
65
+ this.answers.set(answer.key, answer.resolution);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ /**
71
+ * What one read answered, or nothing where it failed.
72
+ */
73
+ async function prefetchedReference(key, read) {
74
+ try {
75
+ return { key, resolution: await read };
76
+ }
77
+ catch {
78
+ return undefined;
79
+ }
80
+ }
@@ -6,6 +6,13 @@ interface SimEventBridgeDeliveryFailureProperties {
6
6
  readonly eventId: string;
7
7
  readonly error: unknown;
8
8
  }
9
+ /**
10
+ * A failed delivery as it serialises. Every property the failure holds, plus
11
+ * the message the getter reads off the error.
12
+ */
13
+ export interface SimEventBridgeDeliveryFailureJson extends SimEventBridgeDeliveryFailureProperties {
14
+ readonly message: string;
15
+ }
9
16
  /**
10
17
  * One event a rule could not get to one of its targets.
11
18
  */
@@ -21,6 +28,15 @@ export declare class SimEventBridgeDeliveryFailure {
21
28
  * What went wrong, as a message.
22
29
  */
23
30
  get message(): string;
31
+ /**
32
+ * The failure as JSON.stringify renders it, message included.
33
+ *
34
+ * Serialising a failure is the first thing to reach for when a target
35
+ * received nothing. The message is a getter on the prototype and would be
36
+ * left out. An Error keeps its own message on a non-enumerable property and
37
+ * prints as `{}`.
38
+ */
39
+ toJSON(): SimEventBridgeDeliveryFailureJson;
24
40
  }
25
41
  /**
26
42
  * Every delivery one simulated EventBridge scope could not make.
@@ -25,6 +25,25 @@ export class SimEventBridgeDeliveryFailure {
25
25
  }
26
26
  return String(this.error);
27
27
  }
28
+ /**
29
+ * The failure as JSON.stringify renders it, message included.
30
+ *
31
+ * Serialising a failure is the first thing to reach for when a target
32
+ * received nothing. The message is a getter on the prototype and would be
33
+ * left out. An Error keeps its own message on a non-enumerable property and
34
+ * prints as `{}`.
35
+ */
36
+ toJSON() {
37
+ return {
38
+ ruleName: this.ruleName,
39
+ ruleArn: this.ruleArn,
40
+ targetId: this.targetId,
41
+ targetArn: this.targetArn,
42
+ eventId: this.eventId,
43
+ message: this.message,
44
+ error: this.error,
45
+ };
46
+ }
28
47
  }
29
48
  /**
30
49
  * Every delivery one simulated EventBridge scope could not make.
@@ -1,28 +1,51 @@
1
1
  import { type SimAwsCredentialIdentityResolver, type SimAwsResolvedCaller } from "../../../aws/caller/sim-aws-caller-resolver.js";
2
- import type { SimAwsCaller, SimAwsPrincipal } from "../../../aws/caller/sim-aws-caller.js";
2
+ import type { SimAwsCaller, SimAwsDefaultCaller, SimAwsPrincipal } from "../../../aws/caller/sim-aws-caller.js";
3
3
  import type { SimIamAuthZPolicySource } from "./sim-iam-auth-z-context.js";
4
4
  export interface SimIamAuthZCallerContext {
5
5
  readonly caller: SimAwsResolvedCaller;
6
6
  readonly rootPolicySources: readonly SimIamAuthZPolicySource[];
7
7
  }
8
+ /**
9
+ * What building a caller context needs beyond the request's own caller.
10
+ */
11
+ export interface SimIamAuthZCallerContextBuilderProperties {
12
+ /**
13
+ * The root principal of the Account deciding the request.
14
+ *
15
+ * This is both the last fallback for a request that names no caller and the
16
+ * principal holding the Account's intrinsic unrestricted access. The default
17
+ * caller stands apart from it. Naming a default says who an unattributed
18
+ * call comes from, and leaves the root's own access where AWS puts it.
19
+ */
20
+ readonly accountRootPrincipal: SimAwsPrincipal;
21
+ readonly credentialIdentityResolver: SimAwsCredentialIdentityResolver;
22
+ /**
23
+ * The caller this simulation attributes an unattributed request to.
24
+ */
25
+ readonly defaultCaller?: SimAwsDefaultCaller | undefined;
26
+ }
8
27
  /**
9
28
  * Resolves the caller and any policy sources implied by that caller.
10
29
  *
11
- * The configured default principal represents the simulated account root. It is
12
- * used only when the request omits a caller. An explicit anonymous caller does
13
- * not fall back to root.
30
+ * A request that omits a caller is decided as the simulation's default caller,
31
+ * and as the Account root where the simulation named none. An explicit
32
+ * anonymous caller falls back to neither.
14
33
  */
15
34
  export declare class SimIamAuthZCallerContextBuilder {
16
35
  private readonly callerResolver;
17
- private readonly defaultCallerPrincipal;
18
- constructor(defaultCallerPrincipal: SimAwsPrincipal, credentialIdentityResolver: SimAwsCredentialIdentityResolver);
36
+ private readonly accountRootPrincipal;
37
+ private readonly accountRootArn?;
38
+ constructor(properties: SimIamAuthZCallerContextBuilderProperties);
19
39
  /**
20
40
  * Resolve request caller data and add the simulated root policy when
21
41
  * applicable.
22
42
  */
23
43
  build(caller: SimAwsCaller | undefined): SimIamAuthZCallerContext;
24
44
  /**
25
- * Give the configured account-root principal unrestricted identity access.
45
+ * Give the Account's root principal unrestricted identity access.
46
+ *
47
+ * The comparison names the root principal explicitly, so a simulation with a
48
+ * default caller keeps this access on the root where AWS has it.
26
49
  */
27
50
  private rootPolicySources;
28
51
  }
@@ -2,34 +2,43 @@ import { SimAwsCallerResolver, } from "../../../aws/caller/sim-aws-caller-resolv
2
2
  /**
3
3
  * Resolves the caller and any policy sources implied by that caller.
4
4
  *
5
- * The configured default principal represents the simulated account root. It is
6
- * used only when the request omits a caller. An explicit anonymous caller does
7
- * not fall back to root.
5
+ * A request that omits a caller is decided as the simulation's default caller,
6
+ * and as the Account root where the simulation named none. An explicit
7
+ * anonymous caller falls back to neither.
8
8
  */
9
9
  export class SimIamAuthZCallerContextBuilder {
10
10
  callerResolver;
11
- defaultCallerPrincipal;
12
- constructor(defaultCallerPrincipal, credentialIdentityResolver) {
13
- this.defaultCallerPrincipal = defaultCallerPrincipal;
14
- this.callerResolver = new SimAwsCallerResolver(credentialIdentityResolver);
11
+ accountRootPrincipal;
12
+ accountRootArn;
13
+ constructor(properties) {
14
+ const root = properties.accountRootPrincipal;
15
+ this.accountRootPrincipal = root;
16
+ this.accountRootArn = root.kind === "arn" ? root.arn : undefined;
17
+ this.callerResolver = new SimAwsCallerResolver({
18
+ credentialIdentityResolver: properties.credentialIdentityResolver,
19
+ defaultCaller: properties.defaultCaller,
20
+ });
15
21
  }
16
22
  /**
17
23
  * Resolve request caller data and add the simulated root policy when
18
24
  * applicable.
19
25
  */
20
26
  build(caller) {
21
- const resolvedCaller = this.callerResolver.resolve(caller, this.defaultCallerPrincipal);
27
+ const resolvedCaller = this.callerResolver.resolve(caller, this.accountRootPrincipal);
22
28
  return {
23
29
  caller: resolvedCaller,
24
30
  rootPolicySources: this.rootPolicySources(resolvedCaller),
25
31
  };
26
32
  }
27
33
  /**
28
- * Give the configured account-root principal unrestricted identity access.
34
+ * Give the Account's root principal unrestricted identity access.
35
+ *
36
+ * The comparison names the root principal explicitly, so a simulation with a
37
+ * default caller keeps this access on the root where AWS has it.
29
38
  */
30
39
  rootPolicySources(caller) {
31
- const defaultCaller = this.callerResolver.resolve(this.defaultCallerPrincipal, this.defaultCallerPrincipal);
32
- if (defaultCaller.arn === undefined || caller.arn !== defaultCaller.arn) {
40
+ if (this.accountRootArn === undefined ||
41
+ caller.arn !== this.accountRootArn) {
33
42
  return [];
34
43
  }
35
44
  return [