@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
package/README.md CHANGED
@@ -22,6 +22,8 @@ npm i -D @kensio/yulin
22
22
  - [ACM](https://yulinsim.dev/services/acm/ "Simulated ACM docs")
23
23
  - [API Gateway HTTP APIs](https://yulinsim.dev/services/apigatewayv2/ "Simulated API Gateway HTTP API docs")
24
24
  - [API Gateway REST APIs](https://yulinsim.dev/services/apigateway/ "Simulated API Gateway REST API docs")
25
+ - [Athena](https://yulinsim.dev/services/athena/ "Simulated Amazon Athena docs")
26
+ - [Bedrock](https://yulinsim.dev/services/bedrock/ "Simulated Amazon Bedrock docs")
25
27
  - [CloudFormation](https://yulinsim.dev/services/cloudformation/ "Simulated CloudFormation docs")
26
28
  - [CloudFront](https://yulinsim.dev/services/cloudfront/ "Simulated CloudFront docs")
27
29
  - [CloudWatch metrics](https://yulinsim.dev/services/cloudwatch/ "Simulated CloudWatch metrics docs")
@@ -29,12 +31,16 @@ npm i -D @kensio/yulin
29
31
  - [DynamoDB](https://yulinsim.dev/services/dynamodb/ "Simulated DynamoDB docs")
30
32
  - [ECR](https://yulinsim.dev/services/ecr/ "Simulated ECR docs")
31
33
  - [ECS](https://yulinsim.dev/services/ecs/ "Simulated ECS docs")
34
+ - [Elastic Load Balancing](https://yulinsim.dev/services/elbv2/ "Simulated Application Load Balancer docs")
32
35
  - [EventBridge](https://yulinsim.dev/services/eventbridge/ "Simulated EventBridge docs")
33
36
  - [Glue](https://yulinsim.dev/services/glue/ "Simulated Glue Data Catalog docs")
34
37
  - [IAM](https://yulinsim.dev/services/iam/ "Simulated IAM docs")
38
+ - [Kinesis Data Firehose](https://yulinsim.dev/services/firehose/ "Simulated Kinesis Data Firehose docs")
39
+ - [Kinesis Data Streams](https://yulinsim.dev/services/kinesis/ "Simulated Kinesis Data Streams docs")
35
40
  - [KMS](https://yulinsim.dev/services/kms/ "Simulated KMS docs")
36
41
  - [Lambda](https://yulinsim.dev/services/lambda/ "Simulated Lambda docs")
37
42
  - [CloudWatch Logs](https://yulinsim.dev/services/logs/ "Simulated CloudWatch Logs docs")
43
+ - [Organizations](https://yulinsim.dev/services/organizations/ "Simulated Organizations service control policies docs")
38
44
  - [Personalize](https://yulinsim.dev/services/personalize/ "Simulated Amazon Personalize docs")
39
45
  - [Rekognition](https://yulinsim.dev/services/rekognition/ "Simulated Rekognition docs")
40
46
  - [Route53](https://yulinsim.dev/services/route53/ "Simulated Route53 docs")
@@ -54,10 +60,17 @@ npm i -D @kensio/yulin
54
60
  - [AI skill](https://yulinsim.dev/ai-skill/ "Yulin AI skill docs")
55
61
  - [The AWS CLI](https://yulinsim.dev/cli/ "The AWS CLI against simulated AWS docs")
56
62
  - [AWS SDK interception](https://yulinsim.dev/sdk/ "Simulated AWS SDK docs")
63
+ - [Event factories](https://yulinsim.dev/factories/ "Test factories for AWS event shapes docs")
64
+ - [Linting CloudFront Functions JS2](https://yulinsim.dev/lint/ "CloudFront Functions JS2 lint config docs")
65
+ - [Non-AWS dependencies](https://yulinsim.dev/non-aws-dependencies/ "Dependencies Yulin does not simulate docs")
57
66
  - [Serving on localhost](https://yulinsim.dev/serve/ "Serving simulated AWS on localhost docs")
58
67
  - [Simulated time](https://yulinsim.dev/time/ "Simulated time docs")
59
68
  - [Terraform](https://yulinsim.dev/terraform/ "Deploying Terraform into simulated AWS docs")
60
69
 
70
+ Every page listed above also ships inside the package as markdown, documenting the version
71
+ installed. `node_modules/@kensio/yulin/llms.txt` indexes them, and a coding agent with no network
72
+ reach can read them from there.
73
+
61
74
  ## Usage
62
75
 
63
76
  ### Intercept AWS SDK clients
@@ -2,7 +2,7 @@
2
2
  "jsPlugins": [
3
3
  {
4
4
  "name": "cff-js2",
5
- "specifier": "../lint/cff-js2-oxlint-plugin.js"
5
+ "specifier": "./dist/config/lint/cff-js2-oxlint-plugin.js"
6
6
  }
7
7
  ],
8
8
  "overrides": [
@@ -1,11 +1,12 @@
1
1
  import { cffJs2LintRules, cffJs2PluginName, } from "../lint/index.js";
2
2
  /**
3
- * Where the built plugin sits, relative to the built config that names it.
3
+ * Where the built plugin sits, relative to the published config that names it.
4
4
  *
5
5
  * Oxlint resolves a plugin specifier against the config file's own location,
6
- * so this path is the one inside `dist/`, not the one in the source tree.
6
+ * and the config is written to the package root, so this path goes down into
7
+ * `dist/` rather than across the source tree.
7
8
  */
8
- const pluginSpecifier = "../lint/cff-js2-oxlint-plugin.js";
9
+ const pluginSpecifier = "./dist/config/lint/cff-js2-oxlint-plugin.js";
9
10
  /**
10
11
  * Oxlint's half of the CloudFront Functions JS2 lint setup.
11
12
  *
@@ -40,6 +40,11 @@ export declare class SimSdkModuleClientInterceptor {
40
40
  *
41
41
  * Reflect.construct with the incoming new target preserves subclassing and
42
42
  * instanceof against the real class.
43
+ *
44
+ * The class's own static methods are wrapped as well, so a client built by
45
+ * a static factory such as `DynamoDBDocumentClient.from` is patched too.
46
+ * Such a factory constructs from the class binding it closes over rather
47
+ * than through this proxy, so the construct trap never sees it.
43
48
  */
44
49
  private wrapClientClass;
45
50
  /**
@@ -1,4 +1,5 @@
1
1
  import { installSendPatch } from "../send-patch.js";
2
+ import { SimSdkStaticClientFactories } from "./sim-sdk-static-client-factory.js";
2
3
  /**
3
4
  * Intercepts the SDK client classes exported by an AWS SDK package module.
4
5
  *
@@ -56,16 +57,29 @@ export class SimSdkModuleClientInterceptor {
56
57
  *
57
58
  * Reflect.construct with the incoming new target preserves subclassing and
58
59
  * instanceof against the real class.
60
+ *
61
+ * The class's own static methods are wrapped as well, so a client built by
62
+ * a static factory such as `DynamoDBDocumentClient.from` is patched too.
63
+ * Such a factory constructs from the class binding it closes over rather
64
+ * than through this proxy, so the construct trap never sees it.
59
65
  */
60
66
  wrapClientClass(clientClass) {
61
67
  const sendHandler = this.sendHandler;
62
68
  const configureArguments = (constructorArguments) => this.regionDefaultedArguments(constructorArguments);
69
+ const staticFactories = new SimSdkStaticClientFactories(sendHandler);
63
70
  return new Proxy(clientClass, {
64
71
  construct(target, constructorArguments, newTarget) {
65
72
  const instance = Reflect.construct(target, configureArguments(constructorArguments), newTarget);
66
73
  installSendPatch(instance, sendHandler);
67
74
  return instance;
68
75
  },
76
+ get(target, property, receiver) {
77
+ const value = Reflect.get(target, property, receiver);
78
+ if (typeof value !== "function" || !Object.hasOwn(target, property)) {
79
+ return value;
80
+ }
81
+ return staticFactories.wrap(value);
82
+ },
69
83
  });
70
84
  }
71
85
  /**
@@ -0,0 +1,26 @@
1
+ import { type SimSdkSendHandler } from "../send-patch.js";
2
+ /**
3
+ * The wrapped static methods of one intercepted SDK client class.
4
+ *
5
+ * A static factory such as `DynamoDBDocumentClient.from` constructs from the
6
+ * class binding it closes over rather than through the class the calling code
7
+ * holds, so the client it builds is never seen by the interception's construct
8
+ * trap. Wrapping the method send-patches that client on the way back out.
9
+ *
10
+ * Each method is wrapped once, so the class keeps handing out the same
11
+ * function for the same static.
12
+ */
13
+ export declare class SimSdkStaticClientFactories {
14
+ private readonly sendHandler;
15
+ private readonly wrappers;
16
+ constructor(sendHandler: SimSdkSendHandler);
17
+ /**
18
+ * The patching wrapper for one static method.
19
+ */
20
+ wrap(method: object): unknown;
21
+ /**
22
+ * A Proxy rather than a plain function keeps the method's own identity
23
+ * surface, such as its name, length and any properties hung off it.
24
+ */
25
+ private wrapMethod;
26
+ }
@@ -0,0 +1,59 @@
1
+ import { hasSendPatch, installSendPatch, } from "../send-patch.js";
2
+ /**
3
+ * The wrapped static methods of one intercepted SDK client class.
4
+ *
5
+ * A static factory such as `DynamoDBDocumentClient.from` constructs from the
6
+ * class binding it closes over rather than through the class the calling code
7
+ * holds, so the client it builds is never seen by the interception's construct
8
+ * trap. Wrapping the method send-patches that client on the way back out.
9
+ *
10
+ * Each method is wrapped once, so the class keeps handing out the same
11
+ * function for the same static.
12
+ */
13
+ export class SimSdkStaticClientFactories {
14
+ sendHandler;
15
+ wrappers = new WeakMap();
16
+ constructor(sendHandler) {
17
+ this.sendHandler = sendHandler;
18
+ }
19
+ /**
20
+ * The patching wrapper for one static method.
21
+ */
22
+ wrap(method) {
23
+ const wrapped = this.wrappers.get(method) ?? this.wrapMethod(method);
24
+ this.wrappers.set(method, wrapped);
25
+ return wrapped;
26
+ }
27
+ /**
28
+ * A Proxy rather than a plain function keeps the method's own identity
29
+ * surface, such as its name, length and any properties hung off it.
30
+ */
31
+ wrapMethod(method) {
32
+ const sendHandler = this.sendHandler;
33
+ return new Proxy(method, {
34
+ apply(target, thisArgument, callArguments) {
35
+ const result = Reflect.apply(target, thisArgument, callArguments);
36
+ if (isUnpatchedClient(result)) {
37
+ installSendPatch(result, sendHandler);
38
+ }
39
+ return result;
40
+ },
41
+ });
42
+ }
43
+ }
44
+ /**
45
+ * Whether a static method's return value is a client still to be patched.
46
+ *
47
+ * A factory building through the intercepted class itself has already been
48
+ * patched by the construct trap, so patching again is skipped rather than
49
+ * rejected as a double interception.
50
+ */
51
+ function isUnpatchedClient(value) {
52
+ if (typeof value !== "object" || value === null) {
53
+ return false;
54
+ }
55
+ if (typeof value.send !== "function") {
56
+ return false;
57
+ }
58
+ return !hasSendPatch(value);
59
+ }
@@ -29,3 +29,11 @@ export interface SimSdkSendPatch {
29
29
  * inherited send resolves again.
30
30
  */
31
31
  export declare function installSendPatch(target: object, handler: SimSdkSendHandler): SimSdkSendPatch;
32
+ /**
33
+ * Whether a simulated send patch is currently installed on a target.
34
+ *
35
+ * Only an own patched send counts, which is the property installSendPatch
36
+ * writes, so an instance inheriting a patched send from a patched prototype
37
+ * reports false.
38
+ */
39
+ export declare function hasSendPatch(target: object): boolean;
@@ -50,6 +50,17 @@ export function installSendPatch(target, handler) {
50
50
  },
51
51
  };
52
52
  }
53
+ /**
54
+ * Whether a simulated send patch is currently installed on a target.
55
+ *
56
+ * Only an own patched send counts, which is the property installSendPatch
57
+ * writes, so an instance inheriting a patched send from a patched prototype
58
+ * reports false.
59
+ */
60
+ export function hasSendPatch(target) {
61
+ const send = Object.getOwnPropertyDescriptor(target, "send")?.value;
62
+ return typeof send === "function" && installedSends.has(send);
63
+ }
53
64
  /**
54
65
  * Name a patch target for diagnostics: the client's class name for instances
55
66
  * and prototypes alike, when it has one.
@@ -1,4 +1,4 @@
1
- import type { SimAwsCaller, SimAwsPrincipal, SimCredentialCaller } from "./sim-aws-caller.js";
1
+ import type { SimAwsCaller, SimAwsDefaultCaller, SimAwsPrincipal, SimCredentialCaller } from "./sim-aws-caller.js";
2
2
  import type { SimIamCredentialIdentity } from "../../iam/credential/sim-aws-credentials.js";
3
3
  export interface SimAwsCredentialIdentityResolver {
4
4
  resolveCredentials(credentials: SimCredentialCaller["credentials"], now?: Date): SimIamCredentialIdentity;
@@ -17,19 +17,41 @@ export interface SimAwsResolvedCaller {
17
17
  readonly accountId?: string | undefined;
18
18
  readonly service?: string | undefined;
19
19
  }
20
+ /**
21
+ * What resolving a caller needs beyond the caller itself.
22
+ */
23
+ export interface SimAwsCallerResolverProperties {
24
+ /**
25
+ * Authenticates a caller that presents credentials.
26
+ */
27
+ readonly credentialIdentityResolver?: SimAwsCredentialIdentityResolver | undefined;
28
+ /**
29
+ * The caller a request naming none of its own is attributed to.
30
+ *
31
+ * A simulation sets this to say who its unattributed calls come from. It is
32
+ * consulted ahead of the operation default. A simulation that names no
33
+ * default caller keeps the Account root fallback.
34
+ */
35
+ readonly defaultCaller?: SimAwsDefaultCaller | undefined;
36
+ }
20
37
  /**
21
38
  * Resolves caller input at a simulated AWS operation boundary.
22
39
  *
23
- * An omitted caller resolves to the supplied operation default. Explicit
24
- * anonymity is preserved. Credential callers are authenticated before a
25
- * resolved caller is returned, and a caller already resolved elsewhere is
26
- * taken as it stands.
40
+ * An omitted caller resolves to the simulation's default caller, and to the
41
+ * supplied operation default where there is none. Explicit anonymity is
42
+ * preserved. Credential callers are authenticated before a resolved caller is
43
+ * returned, and a caller already resolved elsewhere is taken as it stands.
27
44
  */
28
45
  export declare class SimAwsCallerResolver {
29
46
  private readonly credentialIdentityResolver?;
30
- constructor(credentialIdentityResolver?: SimAwsCredentialIdentityResolver);
47
+ private readonly defaultCaller?;
48
+ constructor(properties?: SimAwsCallerResolverProperties);
31
49
  /**
32
50
  * Resolve and normalize a simulated AWS caller.
51
+ *
52
+ * The request's own caller is used where it has one. A request without one
53
+ * falls back to the simulation's default caller, and then to the operation
54
+ * default the call site supplies.
33
55
  */
34
56
  resolve(caller: SimAwsCaller | undefined, defaultPrincipal: SimAwsPrincipal): SimAwsResolvedCaller;
35
57
  private normalized;
@@ -2,29 +2,36 @@ import { assertDefined } from "../../../util/type-guard/defined.js";
2
2
  /**
3
3
  * Resolves caller input at a simulated AWS operation boundary.
4
4
  *
5
- * An omitted caller resolves to the supplied operation default. Explicit
6
- * anonymity is preserved. Credential callers are authenticated before a
7
- * resolved caller is returned, and a caller already resolved elsewhere is
8
- * taken as it stands.
5
+ * An omitted caller resolves to the simulation's default caller, and to the
6
+ * supplied operation default where there is none. Explicit anonymity is
7
+ * preserved. Credential callers are authenticated before a resolved caller is
8
+ * returned, and a caller already resolved elsewhere is taken as it stands.
9
9
  */
10
10
  export class SimAwsCallerResolver {
11
11
  credentialIdentityResolver;
12
- constructor(credentialIdentityResolver) {
13
- this.credentialIdentityResolver = credentialIdentityResolver;
12
+ defaultCaller;
13
+ constructor(properties = {}) {
14
+ this.credentialIdentityResolver = properties.credentialIdentityResolver;
15
+ this.defaultCaller = properties.defaultCaller;
14
16
  }
15
17
  /**
16
18
  * Resolve and normalize a simulated AWS caller.
19
+ *
20
+ * The request's own caller is used where it has one. A request without one
21
+ * falls back to the simulation's default caller, and then to the operation
22
+ * default the call site supplies.
17
23
  */
18
24
  resolve(caller, defaultPrincipal) {
19
- if (caller?.kind === "resolved") {
20
- return this.normalized(caller.principal, caller.identityPolicyPrincipal);
25
+ const stated = caller ?? this.defaultCaller;
26
+ if (stated?.kind === "resolved") {
27
+ return this.normalized(stated.principal, stated.identityPolicyPrincipal);
21
28
  }
22
- if (caller?.kind === "credentials") {
29
+ if (stated?.kind === "credentials") {
23
30
  assertDefined(this.credentialIdentityResolver, "Simulated credential callers require an IAM credential resolver");
24
- const identity = this.credentialIdentityResolver.resolveCredentials(caller.credentials);
31
+ const identity = this.credentialIdentityResolver.resolveCredentials(stated.credentials);
25
32
  return this.normalized(identity.principal, identity.identityPolicyPrincipal);
26
33
  }
27
- const principal = caller ?? defaultPrincipal;
34
+ const principal = stated ?? defaultPrincipal;
28
35
  return this.normalized(principal, principal);
29
36
  }
30
37
  normalized(principal, identityPolicyPrincipal) {
@@ -52,3 +52,12 @@ export interface SimResolvedCaller {
52
52
  * Caller accepted by simulated AWS service operations.
53
53
  */
54
54
  export type SimAwsCaller = SimAwsPrincipal | SimCredentialCaller | SimResolvedCaller;
55
+ /**
56
+ * Caller a simulation attributes a request that names none of its own to.
57
+ *
58
+ * A principal, or a caller something else has already resolved. Credentials
59
+ * are left out because the Account that issued a key is the only thing able to
60
+ * authenticate it, while a default is held for a whole simulation. A key from
61
+ * one Account would fail wherever another Account decided the request.
62
+ */
63
+ export type SimAwsDefaultCaller = SimAwsPrincipal | SimResolvedCaller;
@@ -0,0 +1,19 @@
1
+ import type { SimAwsPrincipal, SimResolvedCaller } from "./sim-aws-caller.js";
2
+ import { type SimAwsResolvedCaller } from "./sim-aws-caller-resolver.js";
3
+ /**
4
+ * State an already-resolved caller as the caller of another request.
5
+ *
6
+ * A resolver answers with a SimAwsResolvedCaller, and a service that goes on
7
+ * to ask IAM about the same caller has to pass one back in. Both principals
8
+ * travel together, so an assumed-role session keeps the Role its policies come
9
+ * from instead of arriving as a session ARN that owns none.
10
+ */
11
+ export declare function simAwsCallerFor(caller: SimAwsResolvedCaller): SimResolvedCaller;
12
+ /**
13
+ * Resolve a principal that needs nothing authenticated.
14
+ *
15
+ * A service principal, or an ARN something else has already established, is
16
+ * its own answer. This is the short way to the SimAwsResolvedCaller that an
17
+ * authorization boundary asks for.
18
+ */
19
+ export declare function simAwsResolvedCallerOf(principal: SimAwsPrincipal): SimAwsResolvedCaller;
@@ -0,0 +1,26 @@
1
+ import { SimAwsCallerResolver, } from "./sim-aws-caller-resolver.js";
2
+ /**
3
+ * State an already-resolved caller as the caller of another request.
4
+ *
5
+ * A resolver answers with a SimAwsResolvedCaller, and a service that goes on
6
+ * to ask IAM about the same caller has to pass one back in. Both principals
7
+ * travel together, so an assumed-role session keeps the Role its policies come
8
+ * from instead of arriving as a session ARN that owns none.
9
+ */
10
+ export function simAwsCallerFor(caller) {
11
+ return {
12
+ kind: "resolved",
13
+ principal: caller.principal,
14
+ identityPolicyPrincipal: caller.identityPolicyPrincipal,
15
+ };
16
+ }
17
+ /**
18
+ * Resolve a principal that needs nothing authenticated.
19
+ *
20
+ * A service principal, or an ARN something else has already established, is
21
+ * its own answer. This is the short way to the SimAwsResolvedCaller that an
22
+ * authorization boundary asks for.
23
+ */
24
+ export function simAwsResolvedCallerOf(principal) {
25
+ return new SimAwsCallerResolver().resolve(principal, principal);
26
+ }
@@ -1,6 +1,7 @@
1
1
  import type { BackgroundCompleter, BackgroundScheduler } from "../../../util/background/background.js";
2
2
  import type { SimAwsAccountRegionContainer } from "../sim-aws-account-region-scope.js";
3
3
  import type { SimAws } from "../sim-aws.js";
4
+ import type { SimAwsDefaultCaller } from "../caller/sim-aws-caller.js";
4
5
  import { SimCloudFormation } from "../../cloudformation/index.js";
5
6
  import { SimCloudWatch } from "../../cloudwatch/index.js";
6
7
  import { SimCognitoIdentityProvider } from "../../cognito/index.js";
@@ -30,6 +31,10 @@ interface SimAwsAccountRegionServiceBuilderProperties {
30
31
  readonly lambdaUrlRegistry: SimLambdaUrlRegistry;
31
32
  readonly accountServices: SimAwsAccountServiceCache;
32
33
  readonly messageLog: SimAwsMessageLog;
34
+ /**
35
+ * The caller this simulation attributes a request naming none to.
36
+ */
37
+ readonly defaultCaller?: SimAwsDefaultCaller | undefined;
33
38
  }
34
39
  /**
35
40
  * Builder for simulated AWS services scoped to one Account and Region.
@@ -61,6 +66,7 @@ export declare class SimAwsAccountRegionServiceBuilder {
61
66
  private readonly lambdaUrlRegistry;
62
67
  private readonly accountServices;
63
68
  private readonly messageLog;
69
+ private readonly defaultCaller?;
64
70
  constructor(properties: SimAwsAccountRegionServiceBuilderProperties);
65
71
  /** Create simulated ACM for an Account Region scope. */
66
72
  /** Create simulated CloudFormation for an Account Region scope. */
@@ -55,6 +55,7 @@ export class SimAwsAccountRegionServiceBuilder {
55
55
  lambdaUrlRegistry;
56
56
  accountServices;
57
57
  messageLog;
58
+ defaultCaller;
58
59
  constructor(properties) {
59
60
  this.simAws = properties.simAws;
60
61
  this.background = properties.background;
@@ -63,6 +64,7 @@ export class SimAwsAccountRegionServiceBuilder {
63
64
  this.lambdaUrlRegistry = properties.lambdaUrlRegistry;
64
65
  this.accountServices = properties.accountServices;
65
66
  this.messageLog = properties.messageLog;
67
+ this.defaultCaller = properties.defaultCaller;
66
68
  }
67
69
  /** Create simulated ACM for an Account Region scope. */
68
70
  /** Create simulated CloudFormation for an Account Region scope. */
@@ -269,6 +271,7 @@ export class SimAwsAccountRegionServiceBuilder {
269
271
  accountRegionScope: scope.accountRegionScope,
270
272
  background: this.background,
271
273
  iamResolver: this.iamRegistry,
274
+ defaultCaller: this.defaultCaller,
272
275
  });
273
276
  }
274
277
  /**
@@ -1,6 +1,7 @@
1
1
  import type { BackgroundCompleter, BackgroundScheduler } from "../../../util/background/background.js";
2
2
  import type { SimAwsAccountRegionContainer } from "../sim-aws-account-region-scope.js";
3
3
  import type { SimAws } from "../sim-aws.js";
4
+ import type { SimAwsDefaultCaller } from "../caller/sim-aws-caller.js";
4
5
  import type { SimAcmRegistry } from "../../acm/registry/sim-acm-registry.js";
5
6
  import type { SimCloudFrontRegistry } from "../../cloudfront/registry/sim-cloud-front-registry.js";
6
7
  import { SimCloudFront } from "../../cloudfront/sim-cloudfront.js";
@@ -25,6 +26,10 @@ interface SimAwsAccountServiceCacheProperties {
25
26
  readonly iamRegistry: SimIamRegistry;
26
27
  readonly accessKeyRegistry: SimIamAccessKeyRegistry;
27
28
  readonly scpResolver: SimIamServiceControlPolicyResolver;
29
+ /**
30
+ * The caller this simulation attributes a request naming none to.
31
+ */
32
+ readonly defaultCaller?: SimAwsDefaultCaller | undefined;
28
33
  }
29
34
  /**
30
35
  * Account-level cache for simulated AWS service instances.
@@ -55,6 +60,7 @@ export declare class SimAwsAccountServiceCache {
55
60
  private readonly iamRegistry;
56
61
  private readonly accessKeyRegistry;
57
62
  private readonly scpResolver;
63
+ private readonly defaultCaller?;
58
64
  private readonly route53Registry;
59
65
  private readonly kmsRegistry;
60
66
  private readonly serviceHosts;
@@ -38,6 +38,7 @@ export class SimAwsAccountServiceCache {
38
38
  iamRegistry;
39
39
  accessKeyRegistry;
40
40
  scpResolver;
41
+ defaultCaller;
41
42
  route53Registry;
42
43
  kmsRegistry;
43
44
  serviceHosts;
@@ -57,6 +58,7 @@ export class SimAwsAccountServiceCache {
57
58
  this.cloudFrontRegistry = properties.cloudFrontRegistry;
58
59
  this.iamRegistry = properties.iamRegistry;
59
60
  this.scpResolver = properties.scpResolver;
61
+ this.defaultCaller = properties.defaultCaller;
60
62
  this.accessKeyRegistry = properties.accessKeyRegistry;
61
63
  this.route53Registry = properties.route53Registry;
62
64
  this.kmsRegistry = properties.kmsRegistry;
@@ -114,6 +116,9 @@ export class SimAwsAccountServiceCache {
114
116
  // What the Account's organization allows it to do is decided outside
115
117
  // the Account, so IAM asks simulated Organizations about it.
116
118
  scpResolver: this.scpResolver,
119
+ // Who a request naming no caller comes from is decided for the
120
+ // whole simulation. Every Account in it applies the same default.
121
+ defaultCaller: this.defaultCaller,
117
122
  // Access keys are indexed simulation-wide as they are issued, so a
118
123
  // signed request naming only a key id can be traced to this Account.
119
124
  credentialRegistry: new SimIamCredentialRegistry({
@@ -1,6 +1,7 @@
1
1
  import type { BackgroundCompleter, BackgroundScheduler } from "../../../util/background/background.js";
2
2
  import type { SimAwsAccountRegionContainer } from "../sim-aws-account-region-scope.js";
3
3
  import type { SimAws } from "../sim-aws.js";
4
+ import type { SimAwsDefaultCaller } from "../caller/sim-aws-caller.js";
4
5
  import type { SimAcm } from "../../acm/sim-acm.js";
5
6
  import type { SimApiGateway } from "../../apigateway/index.js";
6
7
  import type { SimApiGatewayV2 } from "../../apigatewayv2/index.js";
@@ -45,6 +46,10 @@ import { SimAwsMessageLog } from "../message/sim-aws-message-log.js";
45
46
  interface SimAwsServiceFactoryProperties {
46
47
  readonly simAws: SimAws;
47
48
  readonly background: BackgroundScheduler & BackgroundCompleter;
49
+ /**
50
+ * The caller this simulation attributes a call naming none to.
51
+ */
52
+ readonly defaultCaller?: SimAwsDefaultCaller | undefined;
48
53
  }
49
54
  /**
50
55
  * Factory for simulated AWS services used by one SimAws instance.
@@ -104,10 +104,16 @@ export class SimAwsServiceFactory {
104
104
  iamRegistry: this.iamRegistry,
105
105
  accessKeyRegistry: this.requestAuth.accessKeyRegistry,
106
106
  scpResolver: this.organizations,
107
+ // Simulated IAM applies this wherever a request names no caller of its
108
+ // own, in place of the Account root it would otherwise be decided as.
109
+ defaultCaller: properties.defaultCaller,
107
110
  });
108
111
  this.accountRegionServices = new SimAwsAccountRegionServiceBuilder({
109
112
  simAws: properties.simAws,
110
113
  background: properties.background,
114
+ // STS reports and evaluates the same default. An unattributed
115
+ // GetCallerIdentity answers with the principal everything else uses.
116
+ defaultCaller: properties.defaultCaller,
111
117
  registries: this.registries,
112
118
  iamRegistry: this.iamRegistry,
113
119
  lambdaUrlRegistry: this.lambdaUrlRegistry,
@@ -2,6 +2,7 @@ import type { BackgroundCompleter, BackgroundScheduler } from "../../util/backgr
2
2
  import type { SimClock } from "../../util/clock/sim-clock.js";
3
3
  import type { SimIamSigV4ExpectedScope } from "../iam/sigv4/sim-iam-sigv4-expected-scope.js";
4
4
  import type { SimAwsAccountId } from "./sim-aws-account.js";
5
+ import type { SimAwsDefaultCaller } from "./caller/sim-aws-caller.js";
5
6
  import type { AwsRegionName } from "./sim-aws-region.js";
6
7
  /**
7
8
  * Everything caller resolution needs besides the request itself.
@@ -28,6 +29,20 @@ export interface SimAwsProperties {
28
29
  */
29
30
  readonly defaultAccountId?: SimAwsAccountId | string;
30
31
  readonly defaultRegionName?: AwsRegionName;
32
+ /**
33
+ * The principal this simulation attributes a call naming no caller to.
34
+ *
35
+ * Every simulated operation takes a `caller`, and one is set for a
36
+ * deployment through `deployTemplate` and `deployCdkOut`. This says who the
37
+ * calls that name none are, such as the role an operator reads the account
38
+ * through. An explicit caller always wins, as does the ambient caller of a
39
+ * `runAs` block.
40
+ *
41
+ * Left out, a call naming no caller is decided as the root principal of the
42
+ * Account it reaches. A service control policy denying that root then denies
43
+ * the call. That is the reason to name a default.
44
+ */
45
+ readonly defaultCaller?: SimAwsDefaultCaller;
31
46
  readonly background?: BackgroundScheduler & BackgroundCompleter;
32
47
  /**
33
48
  * Clock this simulation's timestamps start from, defaulting to the real
@@ -34,7 +34,7 @@ export class SimAws extends SimAwsServiceAccessors {
34
34
  requestAuthentication;
35
35
  constructor(properties = {}) {
36
36
  super();
37
- const { defaultAccountId = DEFAULT_SIM_AWS_ACCOUNT_ID, defaultRegionName = DEFAULT_SIM_AWS_REGION_NAME, clock, background: suppliedBackground, } = properties;
37
+ const { defaultAccountId = DEFAULT_SIM_AWS_ACCOUNT_ID, defaultRegionName = DEFAULT_SIM_AWS_REGION_NAME, clock, defaultCaller, background: suppliedBackground, } = properties;
38
38
  const timekeeping = new SimAwsTimekeeping({
39
39
  clock,
40
40
  background: suppliedBackground,
@@ -47,6 +47,7 @@ export class SimAws extends SimAwsServiceAccessors {
47
47
  this.serviceFactory = new SimAwsServiceFactory({
48
48
  simAws: this,
49
49
  background,
50
+ defaultCaller,
50
51
  });
51
52
  this.iamRegistry = this.serviceFactory.iamRegistry;
52
53
  this.scopes = new SimAwsScopeRegistry({ simAws: this });
@@ -45,10 +45,13 @@ export declare class SimCfnResourcePropertyResolver {
45
45
  * {@link SimCfnTemplateValueResolver}. If no Parameters are available, an empty
46
46
  * Parameter resolver is used so Resource Refs can still resolve.
47
47
  *
48
- * Resolution itself is synchronous, and the awaiting happens around it. A
49
- * dynamic reference naming a service that has to be waited on resolves to a
50
- * marker while the properties resolve, and the values replace the markers
51
- * here.
48
+ * Resolution itself is synchronous, and the awaiting happens around it.
49
+ * Properties holding a dynamic reference are resolved twice: the first pass
50
+ * reads the references and leaves them as the template wrote them, and the
51
+ * second finds the answers waiting, so an intrinsic function reading a
52
+ * reference's value gets the value rather than a marker. A reference the
53
+ * first pass never reached resolves to a marker instead, and the values
54
+ * replace the markers here.
52
55
  *
53
56
  * Resource Refs are read from the creation context. If a referenced Resource
54
57
  * is unexpectedly absent, the Ref is preserved as `{ Ref: logicalId }` rather
@@ -61,6 +64,10 @@ export declare class SimCfnResourcePropertyResolver {
61
64
  * Absent where the caller has no simulation to read from, which is how the
62
65
  * resolver is used on its own in tests. A reference then stays in the
63
66
  * property as the template wrote it.
67
+ *
68
+ * The principal the operation runs as goes with the simulation, so a
69
+ * reference is read as the deployment's own caller rather than as the
70
+ * Account root.
64
71
  */
65
72
  private dynamicReferences;
66
73
  }