npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@cazoo/events

v5.0.4

Published

Raise Cazoo business events

Downloads

132

Readme

@cazoo/events

Used for raising and parsing Cazoo business events. Abstracts away EventBridge, which we are using as an event bus.

Basic Usage

EventClient.publish Validates and publish an event. It will fail with a validation exception if the event is not valid.

import { EventClient, DoNotValidator, parse } from '@cazoo/events';

export const someHandler = async (ev, context) => {
  const { name, payload } = parse(ev);
  const registryARN = proces.env.SCHEMA_REGISTRY_ARN;

  /* Implement your Lambda logic here */

  // Raise a new event on the shared EventBridge event bus.
  const validator = new DynamicSchemaValidator(registryARN);
  const client = new EventClient({ context, validator });
  const event = {
    name: "orderPlaced",
    payload: { foo: 'bar' }
  };
  await client.publish(event)
}

Targeting a custom event bus

It's possible to use an Environment Variable CAZOO_EVENTS_TARGET_EVENT_BUS to use a custom event bus, you can also manually use a custom event bus using the information below.

If eventBusName parameter is not provided, the default event bus is targeted, instead.

const client = new EventClient({
  context: myContext,
  eventBusName: "custom-event-bus"
});

Validating target event bus

If you wish to provide a custom event bus as your target, you can also optionally validate the existence of the event bus by using the eventBusValidation boolean as shown below:

const client = new EventClient({
  context: myContext,
  eventBusName: "custom-event-bus",
  eventBusValidation: true
})

IAM Permissions

If you want to use event bus validation, then you will need the events:DescribeEventBus IAM permission on your Lambda.

Note: If eventBusValidation is set, then the eventBusName parameter or the environment variable CAZOO_EVENTS_TARGET_EVENT_BUS must be provided, else an error will throw

Configuring the event bridge client

You can provide your own config for the event bridge client the library uses.

const client = new EventClient({
  context: myContext,
  clientConfig: { endpoint: 'http://localhost:3213' }
});

Runtime validation

We now have support for runtime validation of events via the EventClient class. This class will dynamically fetch schemas from the Eventbridge Schema Registry and validate messages before they are raised.

// We use the ARN of the schema registry to look up event schemas
const registryArn = process.env.CAZOO_EVENT_REGISTRY_ARN || 
  "arn:aws:schemas:eu-west-1:571578941547:registry/cazoo-events"

const validator = new DynamicSchemaValidator(registryArn)
// We create a client passing a validator and the lambda context
const client = new EventClient({
  context,
  validator,
});

try {
  const result = await client.publish({
    name: "deliveryCancelled",
    payload: {
      orderNumber: "abc-123"
    }
  });
} catch (e) {
  console.log(e.message);
  console.log(JSON.stringify(e.errors, null, 2))
}
/* Yields the following error

data must NOT have additional properties, data must have required property 'order_number'
[
  {
    "keyword": "additionalProperties",
    "instancePath": "",
    "schemaPath": "#/additionalProperties",
    "params": {
      "additionalProperty": "orderNumber"
    },
    "message": "must NOT have additional properties"
  },
  {
    "keyword": "required",
    "dataPath": "",
    "instancePath": "#/required",
    "params": {
      "missingProperty": "order_number"
    },
    "message": "must have required property 'order_number'"
  }
]
*/

NOT RECOMMENDED

You can also explicitly disable validation with the DoNotValidator.

const validator = new DoNotValidator()
const client = new EventClient({ context, validator });
// This won't throw
const result = await client.publish({
  name: "anyOldRubbish",
  payload: {
    foo: "bar"
  }
});

XRAY

If you'd like to enable xray tracing you can just pass it as part of the eventClient configuration:

const client = new EventClient({ context, validator, config: { xrayEnabled: true } });

Also add the xray dependency to your package.json aws-xray-sdk@3 and make sure you add the required permission to your lambda from the latest AWS documentation https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html.

IAM Permissions

Your lambda will require the following IAM permissions to validate schemas.

Serverless

iamRoleStatements:
  - Effect: Allow
    Action: 
      - schemas:DescribeSchema
    Resource: 
      - arn:aws:schemas:${AWS::Region}:${AWS::AccountId}:schema/REGISTRY_NAME/SCHEMA_NAME
      - ...

Terraform

variable "account_id" {}
variable "region" {}
variable "registry_name" {}
variable "schema_name {}

data "aws_iam_policy_document" "allow_describe_schema" {
  statement {
    sid = "AllowDescribeSchema"

    actions = [
      "schemas:DescribeSchema"
    ]

    resources = [
      "arn:aws:schemas:${var.region}:${var.account_id}:schema/${var.registry_name}/${var.schema_name}",
      ...
    ]
  }
}

resource "aws_iam_policy" "allow_describe_schema" {
  name   = "allow-describe-schema"
  path   = "/"
  policy = data.aws_iam_policy_document.allow_describe_schema.json
}

# attach the policy to your lambda role.
resource "aws_iam_role_policy_attachment" "attach_allow_describe_schema" {
  role       = aws_iam_role.lambda_execution_role.name
  policy_arn = aws_iam_policy.allow_describe_schema.arn
}