@kensio/yulin 1.21.26 → 1.21.27

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 (74) hide show
  1. package/dist/service/eventbridge/bus/sim-event-bus-name.d.ts +4 -0
  2. package/dist/service/eventbridge/bus/sim-event-bus-name.js +17 -12
  3. package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-creator.js +8 -1
  4. package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.d.ts +5 -0
  5. package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.js +14 -1
  6. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-creator.js +2 -0
  7. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-target-delivery.d.ts +15 -0
  8. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-target-delivery.js +53 -0
  9. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-targets.d.ts +4 -0
  10. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-targets.js +7 -3
  11. package/dist/service/eventbridge/command/authorize/sim-event-bridge-authorizer.d.ts +5 -0
  12. package/dist/service/eventbridge/command/authorize/sim-event-bridge-authorizer.js +7 -0
  13. package/dist/service/eventbridge/command/bus/sim-event-bridge-create-event-bus.d.ts +7 -1
  14. package/dist/service/eventbridge/command/bus/sim-event-bridge-create-event-bus.js +7 -1
  15. package/dist/service/eventbridge/command/bus/sim-event-bridge-partner-bus.d.ts +24 -0
  16. package/dist/service/eventbridge/command/bus/sim-event-bridge-partner-bus.js +44 -0
  17. package/dist/service/eventbridge/command/bus/sim-event-bridge-unsimulated-bus-input.js +0 -5
  18. package/dist/service/eventbridge/command/put-events/sim-event-bridge-authorized-entries.js +8 -0
  19. package/dist/service/eventbridge/command/sim-event-bridge-command.types.d.ts +1 -0
  20. package/dist/service/eventbridge/command/sim-event-bridge-commands.d.ts +6 -0
  21. package/dist/service/eventbridge/command/sim-event-bridge-commands.js +19 -1
  22. package/dist/service/eventbridge/command/source/sim-event-bridge-describe-event-source.d.ts +35 -0
  23. package/dist/service/eventbridge/command/source/sim-event-bridge-describe-event-source.js +46 -0
  24. package/dist/service/eventbridge/command/source/sim-event-bridge-put-partner-events.d.ts +41 -0
  25. package/dist/service/eventbridge/command/source/sim-event-bridge-put-partner-events.js +82 -0
  26. package/dist/service/eventbridge/command/source/source.command.d.ts +59 -0
  27. package/dist/service/eventbridge/command/source/source.command.js +1 -0
  28. package/dist/service/eventbridge/command/target/sim-event-bridge-target-commands.js +2 -0
  29. package/dist/service/eventbridge/command/target/sim-event-bridge-unsimulated-target-input.js +2 -12
  30. package/dist/service/eventbridge/command/target/target.command.d.ts +8 -5
  31. package/dist/service/eventbridge/delivery/sim-aws-event-bridge-delivery-targets.d.ts +6 -1
  32. package/dist/service/eventbridge/delivery/sim-aws-event-bridge-delivery-targets.js +16 -0
  33. package/dist/service/eventbridge/delivery/sim-event-bridge-dead-letter-attributes.d.ts +9 -0
  34. package/dist/service/eventbridge/delivery/sim-event-bridge-dead-letter-attributes.js +47 -0
  35. package/dist/service/eventbridge/delivery/sim-event-bridge-dead-letter-queue.d.ts +24 -0
  36. package/dist/service/eventbridge/delivery/sim-event-bridge-dead-letter-queue.js +28 -0
  37. package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-attempt.d.ts +41 -0
  38. package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-attempt.js +97 -0
  39. package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-queue.js +7 -37
  40. package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-retries.test-support.d.ts +25 -0
  41. package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-retries.test-support.js +60 -0
  42. package/dist/service/eventbridge/delivery/sim-event-bridge-delivery.d.ts +22 -0
  43. package/dist/service/eventbridge/delivery/sim-event-bridge-failing-targets.test-support.d.ts +23 -0
  44. package/dist/service/eventbridge/delivery/sim-event-bridge-failing-targets.test-support.js +28 -0
  45. package/dist/service/eventbridge/delivery/sim-event-bridge-no-delivery-targets.d.ts +5 -1
  46. package/dist/service/eventbridge/delivery/sim-event-bridge-no-delivery-targets.js +9 -0
  47. package/dist/service/eventbridge/delivery/sim-event-bridge-queue-message.d.ts +28 -0
  48. package/dist/service/eventbridge/delivery/sim-event-bridge-queue-message.js +45 -0
  49. package/dist/service/eventbridge/delivery/sim-event-bridge-target-delivery.d.ts +4 -1
  50. package/dist/service/eventbridge/delivery/sim-event-bridge-target-delivery.js +19 -14
  51. package/dist/service/eventbridge/index.d.ts +2 -0
  52. package/dist/service/eventbridge/index.js +2 -0
  53. package/dist/service/eventbridge/routing/sim-event-bridge-router.js +1 -0
  54. package/dist/service/eventbridge/sdk/sim-event-bridge-sdk-command-router.js +4 -0
  55. package/dist/service/eventbridge/sim-event-bridge-inspection.d.ts +10 -0
  56. package/dist/service/eventbridge/sim-event-bridge-inspection.js +9 -0
  57. package/dist/service/eventbridge/sim-event-bridge-partners.d.ts +38 -0
  58. package/dist/service/eventbridge/sim-event-bridge-partners.js +43 -0
  59. package/dist/service/eventbridge/sim-event-bridge.d.ts +12 -12
  60. package/dist/service/eventbridge/sim-event-bridge.js +14 -11
  61. package/dist/service/eventbridge/source/sim-partner-event-source-name.d.ts +28 -0
  62. package/dist/service/eventbridge/source/sim-partner-event-source-name.js +62 -0
  63. package/dist/service/eventbridge/source/sim-partner-event-source-store.d.ts +18 -0
  64. package/dist/service/eventbridge/source/sim-partner-event-source-store.js +29 -0
  65. package/dist/service/eventbridge/source/sim-partner-event-source.d.ts +46 -0
  66. package/dist/service/eventbridge/source/sim-partner-event-source.js +43 -0
  67. package/dist/service/eventbridge/target/sim-event-target-dead-letter-config.d.ts +28 -0
  68. package/dist/service/eventbridge/target/sim-event-target-dead-letter-config.js +42 -0
  69. package/dist/service/eventbridge/target/sim-event-target-retry-policy.d.ts +28 -0
  70. package/dist/service/eventbridge/target/sim-event-target-retry-policy.js +53 -0
  71. package/dist/service/eventbridge/target/sim-event-target.d.ts +17 -0
  72. package/dist/service/eventbridge/target/sim-event-target.js +19 -0
  73. package/docs/services/eventbridge/README.md +223 -6
  74. package/package.json +1 -1
@@ -0,0 +1,60 @@
1
+ import { BackgroundTasks } from "../../../util/background/background.js";
2
+ import { SimClockControl } from "../../../util/clock/sim-clock-control.js";
3
+ import { SimControllableClock } from "../../../util/clock/sim-controllable-clock.js";
4
+ import { SimFixedClock } from "../../../util/clock/sim-clock.js";
5
+ import { SimEventBridge } from "../sim-event-bridge.js";
6
+ import { SimEventBridgeFailingTargets, } from "./sim-event-bridge-failing-targets.test-support.js";
7
+ const startedAt = new Date("2026-10-07T09:00:00.000Z");
8
+ /**
9
+ * A simulated EventBridge whose targets fail as the options say.
10
+ */
11
+ export function retrySimulation(options) {
12
+ const clock = new SimControllableClock({
13
+ base: new SimFixedClock(startedAt),
14
+ });
15
+ const background = new BackgroundTasks({ clock });
16
+ const targets = new SimEventBridgeFailingTargets(clock, options);
17
+ return {
18
+ eventBridge: new SimEventBridge({ background, deliveryTargets: targets }),
19
+ clock: new SimClockControl({ clock, background }),
20
+ attempts: targets.attempts,
21
+ deadLetters: targets.deadLetters,
22
+ };
23
+ }
24
+ /**
25
+ * Add a rule with one target carrying the given retry policy and a
26
+ * dead-letter queue, and put one matching event.
27
+ */
28
+ export async function putOrder(simulation, target) {
29
+ const { eventBridge } = simulation;
30
+ await eventBridge.putRule({
31
+ input: {
32
+ Name: "orders",
33
+ EventPattern: JSON.stringify({ source: ["orders.service"] }),
34
+ },
35
+ });
36
+ await eventBridge.putTargets({
37
+ input: {
38
+ Rule: "orders",
39
+ Targets: [
40
+ {
41
+ Id: "fulfilment",
42
+ Arn: "arn:aws:sqs:us-east-1:888888888888:fulfilment",
43
+ ...target,
44
+ },
45
+ ],
46
+ },
47
+ });
48
+ await eventBridge.putEvents({
49
+ input: {
50
+ Entries: [
51
+ {
52
+ Source: "orders.service",
53
+ DetailType: "OrderPlaced",
54
+ Detail: JSON.stringify({ orderId: "order-1" }),
55
+ },
56
+ ],
57
+ },
58
+ });
59
+ await simulation.clock.advanceBy({ milliseconds: 0 });
60
+ }
@@ -37,6 +37,28 @@ export interface SimEventBridgeDeliveryTargets {
37
37
  * EventBridge.
38
38
  */
39
39
  deliver(request: SimEventBridgeDeliveryRequest): Promise<void>;
40
+ /**
41
+ * Send an event EventBridge gave up delivering to its target's dead-letter
42
+ * queue, refusing if the queue does not admit EventBridge.
43
+ */
44
+ deadLetter(request: SimEventBridgeDeadLetterRequest): Promise<void>;
45
+ }
46
+ /**
47
+ * Which of a target's retry limits ran out, as the dead-letter message's
48
+ * `EXHAUSTED_RETRY_CONDITION` names it.
49
+ */
50
+ export type SimEventBridgeExhaustedRetryCondition = "MaximumEventAgeInSeconds" | "MaximumRetryAttempts";
51
+ /**
52
+ * One event on its way to a target's dead-letter queue, and why.
53
+ *
54
+ * A failure EventBridge does not retry, such as a target that is missing or
55
+ * refuses EventBridge, carries no exhausted condition.
56
+ */
57
+ export interface SimEventBridgeDeadLetterRequest {
58
+ readonly delivery: SimEventBridgeDeliveryRequest;
59
+ readonly error: unknown;
60
+ readonly retryAttempts: number;
61
+ readonly exhaustedCondition: SimEventBridgeExhaustedRetryCondition | undefined;
40
62
  }
41
63
  /**
42
64
  * What a target's policy is asked about, as IAM condition values.
@@ -0,0 +1,23 @@
1
+ import type { SimClock } from "../../../util/clock/sim-clock.js";
2
+ import type { SimEventBridgeDeadLetterRequest, SimEventBridgeDeliveryTargets } from "./sim-event-bridge-delivery.js";
3
+ /**
4
+ * How a set of failing targets behaves.
5
+ */
6
+ export interface SimEventBridgeFailingTargetsOptions {
7
+ readonly succeedsOnAttempt?: number;
8
+ readonly error?: Error;
9
+ readonly deadLetterRefused?: boolean;
10
+ }
11
+ /**
12
+ * Targets that fail with an error until a given attempt, and whose
13
+ * dead-letter queue takes or refuses what it is sent, keeping both.
14
+ */
15
+ export declare class SimEventBridgeFailingTargets implements SimEventBridgeDeliveryTargets {
16
+ private readonly clock;
17
+ private readonly options;
18
+ readonly attempts: Date[];
19
+ readonly deadLetters: SimEventBridgeDeadLetterRequest[];
20
+ constructor(clock: SimClock, options: SimEventBridgeFailingTargetsOptions);
21
+ deliver(): Promise<void>;
22
+ deadLetter(request: SimEventBridgeDeadLetterRequest): Promise<void>;
23
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Targets that fail with an error until a given attempt, and whose
3
+ * dead-letter queue takes or refuses what it is sent, keeping both.
4
+ */
5
+ export class SimEventBridgeFailingTargets {
6
+ clock;
7
+ options;
8
+ attempts = [];
9
+ deadLetters = [];
10
+ constructor(clock, options) {
11
+ this.clock = clock;
12
+ this.options = options;
13
+ }
14
+ deliver() {
15
+ this.attempts.push(this.clock.now());
16
+ if (this.attempts.length === this.options.succeedsOnAttempt) {
17
+ return Promise.resolve();
18
+ }
19
+ return Promise.reject(this.options.error ?? new Error("fulfilment is unavailable"));
20
+ }
21
+ deadLetter(request) {
22
+ if (this.options.deadLetterRefused === true) {
23
+ return Promise.reject(new Error("dead-letter queue refused"));
24
+ }
25
+ this.deadLetters.push(request);
26
+ return Promise.resolve();
27
+ }
28
+ }
@@ -1,4 +1,4 @@
1
- import type { SimEventBridgeDeliveryRequest, SimEventBridgeDeliveryTargets } from "./sim-event-bridge-delivery.js";
1
+ import type { SimEventBridgeDeadLetterRequest, SimEventBridgeDeliveryRequest, SimEventBridgeDeliveryTargets } from "./sim-event-bridge-delivery.js";
2
2
  /**
3
3
  * The targets of a simulated EventBridge built on its own, which are none.
4
4
  *
@@ -13,4 +13,8 @@ export declare class SimEventBridgeNoDeliveryTargets implements SimEventBridgeDe
13
13
  * Refuse the delivery, saying why there was nowhere to make it.
14
14
  */
15
15
  deliver(request: SimEventBridgeDeliveryRequest): Promise<void>;
16
+ /**
17
+ * Refuse the dead letter, saying why there was nowhere to send it.
18
+ */
19
+ deadLetter(request: SimEventBridgeDeadLetterRequest): Promise<void>;
16
20
  }
@@ -17,4 +17,13 @@ export class SimEventBridgeNoDeliveryTargets {
17
17
  `${request.target.arn.value} was not reached. Reach EventBridge ` +
18
18
  `through SimAws for a rule that delivers.`));
19
19
  }
20
+ /**
21
+ * Refuse the dead letter, saying why there was nowhere to send it.
22
+ */
23
+ deadLetter(request) {
24
+ return Promise.reject(new SimEventBridgeTargetNotFound(`This simulated EventBridge has no queues to send dead letters to, ` +
25
+ `so the dead-letter queue of target ${request.delivery.target.id} ` +
26
+ `was not reached. Reach EventBridge through SimAws for a ` +
27
+ `dead-letter queue that receives.`));
28
+ }
20
29
  }
@@ -0,0 +1,28 @@
1
+ import type { SimAwsAccountRegionContainer } from "../../aws/sim-aws-account-region-scope.js";
2
+ import { type SimEventBridgeDeliverySource } from "./sim-event-bridge-delivery.js";
3
+ /**
4
+ * One SQS message attribute, as SendMessage takes it.
5
+ */
6
+ export interface SimEventBridgeStringAttribute {
7
+ readonly DataType: string;
8
+ readonly StringValue: string;
9
+ }
10
+ /**
11
+ * One message EventBridge sends to a queue, and the queue it is for.
12
+ */
13
+ export interface SimEventBridgeQueueMessage {
14
+ readonly queueName: string;
15
+ readonly queueArn: string;
16
+ readonly body: string;
17
+ readonly attributes?: Readonly<Record<string, SimEventBridgeStringAttribute>>;
18
+ readonly source: SimEventBridgeDeliverySource;
19
+ }
20
+ /**
21
+ * Send a message to a queue as EventBridge, if the queue admits it for the
22
+ * rule.
23
+ *
24
+ * A target queue and a dead-letter queue are reached the same way. Both are
25
+ * sent to as `events.amazonaws.com`, and both need the queue policy to admit
26
+ * that principal for the rule.
27
+ */
28
+ export declare function sendEventBridgeQueueMessage(scope: SimAwsAccountRegionContainer, message: SimEventBridgeQueueMessage): Promise<void>;
@@ -0,0 +1,45 @@
1
+ import { simScopeIamAuthZ } from "../../iam/authorize/sim-iam-region-auth-z.js";
2
+ import { SimSqsServiceSendAuthorizer } from "../../sqs/command/authorize/sim-sqs-service-send-authorizer.js";
3
+ import { SimEventBridgeDeliveryNotPermitted, SimEventBridgeTargetNotFound, } from "../error/sim-event-bridge-delivery.error.js";
4
+ import { simEventBridgeServicePrincipal, } from "./sim-event-bridge-delivery.js";
5
+ /**
6
+ * Send a message to a queue as EventBridge, if the queue admits it for the
7
+ * rule.
8
+ *
9
+ * A target queue and a dead-letter queue are reached the same way. Both are
10
+ * sent to as `events.amazonaws.com`, and both need the queue policy to admit
11
+ * that principal for the rule.
12
+ */
13
+ export async function sendEventBridgeQueueMessage(scope, message) {
14
+ const { queueArn, source } = message;
15
+ const queue = scope.sqs().findQueue(message.queueName);
16
+ if (queue === undefined) {
17
+ throw new SimEventBridgeTargetNotFound(`${queueArn} is not a simulated SQS queue.`);
18
+ }
19
+ const decision = new SimSqsServiceSendAuthorizer({
20
+ iam: simScopeIamAuthZ(scope),
21
+ }).authorize({
22
+ queue,
23
+ servicePrincipal: simEventBridgeServicePrincipal,
24
+ ...source,
25
+ });
26
+ if (decision.isDenied) {
27
+ throw new SimEventBridgeDeliveryNotPermitted(`The queue policy of ${queueArn} does not allow ` +
28
+ `${simEventBridgeServicePrincipal} to send to it for ` +
29
+ `${source.sourceArn}. Grant sqs:SendMessage with the queue's ` +
30
+ `Policy attribute.`);
31
+ }
32
+ // Sent through the ordinary SendMessage path, so a delivered event is the
33
+ // same thing an SDK caller would have sent, and is authorized again on the
34
+ // way in.
35
+ await scope.sqs().sendMessage({
36
+ input: {
37
+ QueueUrl: queue.arn.url,
38
+ MessageBody: message.body,
39
+ MessageAttributes: message.attributes,
40
+ },
41
+ }, {
42
+ caller: { kind: "service", service: simEventBridgeServicePrincipal },
43
+ ...source,
44
+ });
45
+ }
@@ -1,10 +1,12 @@
1
+ import type { BackgroundScheduler } from "../../../util/background/background.js";
1
2
  import type { SimEventBridgeDeliveryRequest, SimEventBridgeDeliveryTargets } from "./sim-event-bridge-delivery.js";
2
3
  import type { SimEventBridgeDeliveryFailure } from "./sim-event-bridge-delivery-failures.js";
3
4
  interface SimEventBridgeTargetDeliveryProperties {
4
5
  readonly endpoints: SimEventBridgeDeliveryTargets;
6
+ readonly background: BackgroundScheduler;
5
7
  }
6
8
  /**
7
- * Makes one delivery and keeps whatever went wrong.
9
+ * Makes one delivery, with its retries, and keeps whatever went wrong.
8
10
  *
9
11
  * A failure is recorded rather than thrown, because these run as background
10
12
  * tasks and one left rejected would fail an unrelated
@@ -14,6 +16,7 @@ interface SimEventBridgeTargetDeliveryProperties {
14
16
  */
15
17
  export declare class SimEventBridgeTargetDelivery {
16
18
  private readonly endpoints;
19
+ private readonly background;
17
20
  private readonly failures;
18
21
  constructor(properties: SimEventBridgeTargetDeliveryProperties);
19
22
  /**
@@ -1,6 +1,7 @@
1
+ import { SimEventBridgeDeliveryAttempt } from "./sim-event-bridge-delivery-attempt.js";
1
2
  import { SimEventBridgeDeliveryFailures } from "./sim-event-bridge-delivery-failures.js";
2
3
  /**
3
- * Makes one delivery and keeps whatever went wrong.
4
+ * Makes one delivery, with its retries, and keeps whatever went wrong.
4
5
  *
5
6
  * A failure is recorded rather than thrown, because these run as background
6
7
  * tasks and one left rejected would fail an unrelated
@@ -10,9 +11,11 @@ import { SimEventBridgeDeliveryFailures } from "./sim-event-bridge-delivery-fail
10
11
  */
11
12
  export class SimEventBridgeTargetDelivery {
12
13
  endpoints;
14
+ background;
13
15
  failures = new SimEventBridgeDeliveryFailures();
14
16
  constructor(properties) {
15
17
  this.endpoints = properties.endpoints;
18
+ this.background = properties.background;
16
19
  }
17
20
  /**
18
21
  * Every delivery that could not be made.
@@ -24,18 +27,20 @@ export class SimEventBridgeTargetDelivery {
24
27
  * Send one event to one target.
25
28
  */
26
29
  async deliver(request) {
27
- try {
28
- await this.endpoints.deliver(request);
29
- }
30
- catch (error) {
31
- this.failures.record({
32
- ruleName: request.ruleName,
33
- ruleArn: request.ruleArn,
34
- targetId: request.target.id,
35
- targetArn: request.target.arn.value,
36
- eventId: request.event.id,
37
- error,
38
- });
39
- }
30
+ await new SimEventBridgeDeliveryAttempt({
31
+ request,
32
+ endpoints: this.endpoints,
33
+ background: this.background,
34
+ record: (error) => {
35
+ this.failures.record({
36
+ ruleName: request.ruleName,
37
+ ruleArn: request.ruleArn,
38
+ targetId: request.target.id,
39
+ targetArn: request.target.arn.value,
40
+ eventId: request.event.id,
41
+ error,
42
+ });
43
+ },
44
+ }).start();
40
45
  }
41
46
  }
@@ -12,4 +12,6 @@ export { SimEventRuleName } from "./rule/sim-event-rule-name.js";
12
12
  export { SimEventRuleState } from "./rule/sim-event-rule-state.js";
13
13
  export { SimEventPattern } from "./pattern/sim-event-pattern.js";
14
14
  export type { SimEventBusReceipt } from "./bus/sim-event-bus.js";
15
+ export { partnerEventSourceArn, SimPartnerEventSource, type SimPartnerEventSourceState, } from "./source/sim-partner-event-source.js";
16
+ export { isPartnerEventSourceName, SimPartnerEventSourceName, } from "./source/sim-partner-event-source-name.js";
15
17
  export { SimEventBridgeAccessDeniedException, SimEventBridgeError, SimEventBridgeInvalidEventPatternException, SimEventBridgeResourceAlreadyExistsException, SimEventBridgeResourceNotFoundException, SimEventBridgeUnsimulatedInputException, SimEventBridgeValidationException, } from "./error/sim-event-bridge.error.js";
@@ -10,4 +10,6 @@ export { eventRuleArn } from "./rule/sim-event-rule-arn.js";
10
10
  export { SimEventRuleName } from "./rule/sim-event-rule-name.js";
11
11
  export { SimEventRuleState } from "./rule/sim-event-rule-state.js";
12
12
  export { SimEventPattern } from "./pattern/sim-event-pattern.js";
13
+ export { partnerEventSourceArn, SimPartnerEventSource, } from "./source/sim-partner-event-source.js";
14
+ export { isPartnerEventSourceName, SimPartnerEventSourceName, } from "./source/sim-partner-event-source-name.js";
13
15
  export { SimEventBridgeAccessDeniedException, SimEventBridgeError, SimEventBridgeInvalidEventPatternException, SimEventBridgeResourceAlreadyExistsException, SimEventBridgeResourceNotFoundException, SimEventBridgeUnsimulatedInputException, SimEventBridgeValidationException, } from "./error/sim-event-bridge.error.js";
@@ -26,6 +26,7 @@ export class SimEventBridgeRouter {
26
26
  this.accountId = properties.accountId;
27
27
  this.delivery = new SimEventBridgeTargetDelivery({
28
28
  endpoints: properties.endpoints,
29
+ background: properties.background,
29
30
  });
30
31
  }
31
32
  /**
@@ -22,6 +22,10 @@ export class SimEventBridgeSdkCommandRouter {
22
22
  "ListEventBusesCommand",
23
23
  async (command, context) => await simEventBridge.listEventBuses(command, simSdkCallerOptions(context)),
24
24
  ],
25
+ [
26
+ "DescribeEventSourceCommand",
27
+ async (command, context) => await simEventBridge.describeEventSource(command, simSdkCallerOptions(context)),
28
+ ],
25
29
  [
26
30
  "PutEventsCommand",
27
31
  async (command, context) => await simEventBridge.putEvents(command, simSdkCallerOptions(context)),
@@ -1,4 +1,6 @@
1
1
  import type { SimEventBusStore } from "./bus/sim-event-bus-store.js";
2
+ import type { SimEventBridgeCommands } from "./command/sim-event-bridge-commands.js";
3
+ import type { SimEventBridgeDeliveryFailure } from "./delivery/sim-event-bridge-delivery-failures.js";
2
4
  import type { SimEventBusReceipt } from "./bus/sim-event-bus.js";
3
5
  import type { SimEventBus } from "./bus/sim-event-bus.js";
4
6
  import type { SimEventBridgeEvent } from "./event/sim-event-bridge-event.js";
@@ -20,6 +22,14 @@ export declare abstract class SimEventBridgeInspection {
20
22
  protected abstract readonly buses: SimEventBusStore;
21
23
  protected abstract readonly rules: SimEventRuleStore;
22
24
  protected abstract readonly targets: SimEventTargetStore;
25
+ protected abstract readonly commands: SimEventBridgeCommands;
26
+ /**
27
+ * Every event this scope's rules could not get to a target.
28
+ *
29
+ * Real EventBridge tells the caller nothing about a failed delivery, and
30
+ * neither does this. A target that is unexpectedly empty is explained here.
31
+ */
32
+ get deliveryFailures(): readonly SimEventBridgeDeliveryFailure[];
23
33
  /**
24
34
  * Find an event bus by name.
25
35
  *
@@ -10,6 +10,15 @@ import { defaultEventBusName } from "./bus/sim-event-bus-name.js";
10
10
  * job that happens to live on the same object.
11
11
  */
12
12
  export class SimEventBridgeInspection {
13
+ /**
14
+ * Every event this scope's rules could not get to a target.
15
+ *
16
+ * Real EventBridge tells the caller nothing about a failed delivery, and
17
+ * neither does this. A target that is unexpectedly empty is explained here.
18
+ */
19
+ get deliveryFailures() {
20
+ return this.commands.router.deliveryFailures;
21
+ }
13
22
  /**
14
23
  * Find an event bus by name.
15
24
  *
@@ -0,0 +1,38 @@
1
+ import type { BackgroundScheduler } from "../../util/background/background.js";
2
+ import type { SimAwsAccountRegionScope } from "../aws/sim-aws-account-region-scope.js";
3
+ import type { SimPutPartnerEventsCommand, SimPutPartnerEventsCommandOutput } from "./command/source/source.command.js";
4
+ import { SimEventBridgeInspection } from "./sim-event-bridge-inspection.js";
5
+ import { SimPartnerEventSource } from "./source/sim-partner-event-source.js";
6
+ import type { SimPartnerEventSourceStore } from "./source/sim-partner-event-source-store.js";
7
+ /**
8
+ * What a test does as a SaaS partner sending events to a simulated Account.
9
+ *
10
+ * A partner such as Stripe works from its own Account, which is outside the
11
+ * simulation. It creates a partner event source shared with the receiving
12
+ * Account, and puts events onto it. Both are simulator accessors here rather
13
+ * than SDK commands, because the receiving Account's own clients never send
14
+ * either request.
15
+ */
16
+ export declare abstract class SimEventBridgePartners extends SimEventBridgeInspection {
17
+ protected abstract readonly partnerSources: SimPartnerEventSourceStore;
18
+ protected abstract readonly background: BackgroundScheduler;
19
+ protected abstract readonly accountRegionScope: SimAwsAccountRegionScope;
20
+ /**
21
+ * Share a partner event source with this Account and Region, as the
22
+ * partner's CreatePartnerEventSource does.
23
+ *
24
+ * The source starts pending. Creating a bus with the same `Name` and
25
+ * `EventSourceName` activates it, and that bus then receives what
26
+ * `putPartnerEvents` sends.
27
+ */
28
+ addPartnerEventSource(name: string): SimPartnerEventSource;
29
+ /**
30
+ * Put events onto partner event buses as their partner would, taking the
31
+ * shape of the partner's PutPartnerEvents request.
32
+ *
33
+ * Each entry's `Source` has to name a source `addPartnerEventSource` shared
34
+ * with this scope. The event goes to the bus of the same name, or nowhere if
35
+ * that bus has not been created yet.
36
+ */
37
+ putPartnerEvents(command: SimPutPartnerEventsCommand): Promise<SimPutPartnerEventsCommandOutput>;
38
+ }
@@ -0,0 +1,43 @@
1
+ import { SimEventBridgeInspection } from "./sim-event-bridge-inspection.js";
2
+ import { SimPartnerEventSource } from "./source/sim-partner-event-source.js";
3
+ import { SimPartnerEventSourceName } from "./source/sim-partner-event-source-name.js";
4
+ /**
5
+ * What a test does as a SaaS partner sending events to a simulated Account.
6
+ *
7
+ * A partner such as Stripe works from its own Account, which is outside the
8
+ * simulation. It creates a partner event source shared with the receiving
9
+ * Account, and puts events onto it. Both are simulator accessors here rather
10
+ * than SDK commands, because the receiving Account's own clients never send
11
+ * either request.
12
+ */
13
+ export class SimEventBridgePartners extends SimEventBridgeInspection {
14
+ /**
15
+ * Share a partner event source with this Account and Region, as the
16
+ * partner's CreatePartnerEventSource does.
17
+ *
18
+ * The source starts pending. Creating a bus with the same `Name` and
19
+ * `EventSourceName` activates it, and that bus then receives what
20
+ * `putPartnerEvents` sends.
21
+ */
22
+ addPartnerEventSource(name) {
23
+ const source = new SimPartnerEventSource({
24
+ name: SimPartnerEventSourceName.of(name, "Name"),
25
+ accountRegionScope: this.accountRegionScope,
26
+ createdAt: this.background.now(),
27
+ });
28
+ this.partnerSources.add(source);
29
+ return source;
30
+ }
31
+ /**
32
+ * Put events onto partner event buses as their partner would, taking the
33
+ * shape of the partner's PutPartnerEvents request.
34
+ *
35
+ * Each entry's `Source` has to name a source `addPartnerEventSource` shared
36
+ * with this scope. The event goes to the bus of the same name, or nowhere if
37
+ * that bus has not been created yet.
38
+ */
39
+ async putPartnerEvents(command) {
40
+ await this.background.sequence();
41
+ return this.commands.putPartnerEvents.handle(command);
42
+ }
43
+ }
@@ -4,13 +4,14 @@ import type { SimAwsAccountRegionScope } from "../aws/sim-aws-account-region-sco
4
4
  import type { SimIamInterServiceAuthZ } from "../iam/authorize/sim-iam-inter-service-auth-z.js";
5
5
  import { SimEventBusStore } from "./bus/sim-event-bus-store.js";
6
6
  import type * as simEventBridgeCommands from "./command/sim-event-bridge-command.types.js";
7
+ import { SimEventBridgeCommands } from "./command/sim-event-bridge-commands.js";
7
8
  import type { SimEventBridgeRequestOptions } from "./command/sim-event-bridge-request-options.js";
8
9
  import { SimEventRuleStore } from "./rule/sim-event-rule-store.js";
9
10
  import { SimEventTargetStore } from "./target/sim-event-target-store.js";
10
11
  import type { SimEventBridgeDeliveryTargets } from "./delivery/sim-event-bridge-delivery.js";
11
- import type { SimEventBridgeDeliveryFailure } from "./delivery/sim-event-bridge-delivery-failures.js";
12
12
  import { SimEventBridgeCfnResourceFactory } from "./cfn/sim-event-bridge-cfn-resource-factory.js";
13
- import { SimEventBridgeInspection } from "./sim-event-bridge-inspection.js";
13
+ import { SimEventBridgePartners } from "./sim-event-bridge-partners.js";
14
+ import { SimPartnerEventSourceStore } from "./source/sim-partner-event-source-store.js";
14
15
  interface SimEventBridgeProperties {
15
16
  readonly accountRegionScope?: SimAwsAccountRegionScope;
16
17
  readonly iam?: SimIamInterServiceAuthZ;
@@ -36,22 +37,17 @@ interface SimEventBridgeProperties {
36
37
  * matches nothing is gone. A rule carrying a schedule instead fires on the
37
38
  * simulation's own clock, so advancing time is what sends its event.
38
39
  */
39
- export declare class SimEventBridge extends SimEventBridgeInspection {
40
+ export declare class SimEventBridge extends SimEventBridgePartners {
40
41
  protected readonly buses: SimEventBusStore;
41
42
  protected readonly rules: SimEventRuleStore;
42
43
  protected readonly targets: SimEventTargetStore;
43
- private readonly commands;
44
- private readonly background;
44
+ protected readonly partnerSources: SimPartnerEventSourceStore;
45
+ protected readonly commands: SimEventBridgeCommands;
46
+ protected readonly background: BackgroundScheduler;
47
+ protected readonly accountRegionScope: SimAwsAccountRegionScope;
45
48
  private readonly sdkRouter;
46
49
  private readonly cfnFactory;
47
50
  constructor(properties?: SimEventBridgeProperties);
48
- /**
49
- * Every event this scope's rules could not get to a target.
50
- *
51
- * Real EventBridge tells the caller nothing about a failed delivery, and
52
- * neither does this. A target that is unexpectedly empty is explained here.
53
- */
54
- get deliveryFailures(): readonly SimEventBridgeDeliveryFailure[];
55
51
  /**
56
52
  * Handle a CreateEventBus Command from the SDK.
57
53
  */
@@ -68,6 +64,10 @@ export declare class SimEventBridge extends SimEventBridgeInspection {
68
64
  * Handle a ListEventBuses Command from the SDK.
69
65
  */
70
66
  listEventBuses(command: simEventBridgeCommands.SimListEventBusesCommand, options?: SimEventBridgeRequestOptions): Promise<simEventBridgeCommands.SimListEventBusesCommandOutput>;
67
+ /**
68
+ * Handle a DescribeEventSource Command from the SDK.
69
+ */
70
+ describeEventSource(command: simEventBridgeCommands.SimDescribeEventSourceCommand, options?: SimEventBridgeRequestOptions): Promise<simEventBridgeCommands.SimDescribeEventSourceCommandOutput>;
71
71
  /**
72
72
  * Handle a PutEvents Command from the SDK.
73
73
  */
@@ -8,7 +8,8 @@ import { SimEventRuleStore } from "./rule/sim-event-rule-store.js";
8
8
  import { SimEventTargetStore } from "./target/sim-event-target-store.js";
9
9
  import { SimEventBridgeCfnResourceFactory } from "./cfn/sim-event-bridge-cfn-resource-factory.js";
10
10
  import { SimEventBridgeSdkCommandRouter } from "./sdk/sim-event-bridge-sdk-command-router.js";
11
- import { SimEventBridgeInspection } from "./sim-event-bridge-inspection.js";
11
+ import { SimEventBridgePartners } from "./sim-event-bridge-partners.js";
12
+ import { SimPartnerEventSourceStore } from "./source/sim-partner-event-source-store.js";
12
13
  /**
13
14
  * Simulated EventBridge. Handles SDK commands. Emulates AWS behaviour and
14
15
  * state.
@@ -22,12 +23,14 @@ import { SimEventBridgeInspection } from "./sim-event-bridge-inspection.js";
22
23
  * matches nothing is gone. A rule carrying a schedule instead fires on the
23
24
  * simulation's own clock, so advancing time is what sends its event.
24
25
  */
25
- export class SimEventBridge extends SimEventBridgeInspection {
26
+ export class SimEventBridge extends SimEventBridgePartners {
26
27
  buses;
27
28
  rules = new SimEventRuleStore();
28
29
  targets = new SimEventTargetStore();
30
+ partnerSources = new SimPartnerEventSourceStore();
29
31
  commands;
30
32
  background;
33
+ accountRegionScope;
31
34
  sdkRouter = new SimEventBridgeSdkCommandRouter(this);
32
35
  cfnFactory = new SimEventBridgeCfnResourceFactory({
33
36
  eventBridge: this,
@@ -37,26 +40,19 @@ export class SimEventBridge extends SimEventBridgeInspection {
37
40
  const { accountRegionScope = simAwsAccountRegionScopeFactory.make(), background = new BackgroundTasks(), } = properties;
38
41
  const iam = simIamInRegion(properties.iam, accountRegionScope.regionName);
39
42
  this.background = background;
43
+ this.accountRegionScope = accountRegionScope;
40
44
  this.buses = new SimEventBusStore(SimEventBus.default({ accountRegionScope, createdAt: background.now() }));
41
45
  this.commands = new SimEventBridgeCommands({
42
46
  buses: this.buses,
43
47
  rules: this.rules,
44
48
  targets: this.targets,
49
+ partnerSources: this.partnerSources,
45
50
  deliveryTargets: properties.deliveryTargets,
46
51
  iam,
47
52
  background,
48
53
  accountRegionScope,
49
54
  });
50
55
  }
51
- /**
52
- * Every event this scope's rules could not get to a target.
53
- *
54
- * Real EventBridge tells the caller nothing about a failed delivery, and
55
- * neither does this. A target that is unexpectedly empty is explained here.
56
- */
57
- get deliveryFailures() {
58
- return this.commands.router.deliveryFailures;
59
- }
60
56
  /**
61
57
  * Handle a CreateEventBus Command from the SDK.
62
58
  */
@@ -85,6 +81,13 @@ export class SimEventBridge extends SimEventBridgeInspection {
85
81
  await this.background.sequence();
86
82
  return this.commands.buses.listEventBuses(command, options);
87
83
  }
84
+ /**
85
+ * Handle a DescribeEventSource Command from the SDK.
86
+ */
87
+ async describeEventSource(command, options) {
88
+ await this.background.sequence();
89
+ return this.commands.eventSources.handle(command, options);
90
+ }
88
91
  /**
89
92
  * Handle a PutEvents Command from the SDK.
90
93
  */
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Whether a string has the shape of a partner event source name.
3
+ *
4
+ * A partner event bus takes the name of its source, so this is also the one
5
+ * shape of bus name that may carry a `/`.
6
+ */
7
+ export declare function isPartnerEventSourceName(value: string): boolean;
8
+ /**
9
+ * The name of one partner event source.
10
+ *
11
+ * A SaaS partner names the source when it creates it, in the form
12
+ * `aws.partner/<partner>/<name>`. The receiving Account never chooses the
13
+ * name. It creates a bus under the same one.
14
+ */
15
+ export declare class SimPartnerEventSourceName {
16
+ readonly value: string;
17
+ private constructor();
18
+ /**
19
+ * Read a partner event source name from request input, refusing one real
20
+ * EventBridge would refuse.
21
+ */
22
+ static of(value: string, parameterName: string): SimPartnerEventSourceName;
23
+ /**
24
+ * The partner that created the source, which is the segment after
25
+ * `aws.partner`.
26
+ */
27
+ get partner(): string;
28
+ }