# Airhorn Cloud Native Notifications Library Source Index: https://airhorn.org/llms.txt ## Documentation ### Getting Started Guide URL: https://airhorn.org/docs/ [![tests](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml/badge.svg)](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml) [![codecov](https://codecov.io/gh/jaredwray/airhorn/branch/main/graph/badge.svg?token=4OJEEB67Q5)](https://codecov.io/gh/jaredwray/airhorn) [![license](https://img.shields.io/github/license/jaredwray/airhorn)](https://github.com/jaredwray/airhorn/blob/master/LICENSE) [![npm](https://img.shields.io/npm/dm/airhorn)](https://npmjs.com/package/airhorn) [![npm](https://img.shields.io/npm/v/airhorn)](https://npmjs.com/package/airhorn) # Cloud Native Notifications Library Airhorn makes it easy to send SMS, SMTP, Webhooks, and mobile push notifications easily using templates through your standard cloud providers. We focused on making it cloud native by default (using cloud services). # Features - Supports multiple notification types: SMS, Email, Mobile Push, Webhooks - A unified API for all notification types using the `send()` method. - Powerful **Hooks system** via [Hookified](https://hookified.org) (`BeforeSend`, `AfterSend`) for intercepting and modifying messages using `onHook` with `IHook` objects. - Event Emitting built in by default for extendability and observability. - Send Strategy (Round Robin, Fail Over, All) Choose the best delivery method for each notification. - Built in Webhook support for sending notifications to external services. - Built in support for retries and error handling on sends. - Advanced caching on template compilation and execution. - Load a template from a file for easy GitOps based workflows. - Many supported providers such as Twilio (with Sendgrid), AWS, and Google Cloud. - Robust (6+ template formats) templating via [ecto](https://github.com/jaredwray/ecto) - Easily build your own provider with minimal effort via `AirhornProvider` interface. - Statistics tracking for send successes, failures, and execution times (instance only). - ESM and Typescript based supporting Nodejs 20+ - Maintained on a regular basis with updates and improvements. # Getting Started To get started with Airhorn, you can install the package via npm: ```bash npm install airhorn @airhornjs/twilio ``` ```typescript import { Airhorn, AirhornProviderType } from "airhorn"; import { AirhornTwilio } from "@airhornjs/twilio"; const providers = [ new AirhornTwilio({ accountSid: "your_account_sid", authToken: "your_auth_token" }), ]; const airhorn = new Airhorn({ providers }); // this will give you twilio and webhook (built in) support. Now lets create a template and send it! const template = { from: "+12223334444", content: "Hey <%= name %> this is a test message from Airhorn", templateEngine: "ejs", } const data = { name: "John" }; await airhorn.send("+1234567890", template, data, AirhornProviderType.SMS); ``` Check out the documentation and providers to learn more! # Packages | Package | Description | Documentation | |---------|-------------|---------------| | [`airhorn`](packages/airhorn) | Core library with unified send API and webhook support | [README](packages/airhorn/README.md) | | [`@airhornjs/twilio`](packages/twilio) | Twilio provider for SMS and Email (SendGrid) | [README](packages/twilio/README.md) | | [`@airhornjs/aws`](packages/aws) | AWS provider for SMS (SNS), Email (SES), and Push (SNS) | [README](packages/aws/README.md) | | [`@airhornjs/azure`](packages/azure) | Azure provider for SMS, Email, and Push | [README](packages/azure/README.md) | # Providers We currently support multiple providers and you can easily add more by following the `AirhornProvider` interface. Here are the supported providers: We currently support `twilio`, `aws`, and `azure` with thier offerings. Here is a chart showing what functionality is in each: | Provider | SMS | Email | Push | Webhook | |----------|-----|-------|------|---------| | (built in `airhorn`) | ❌ | ❌ | ❌ | ✅ | | `@airhornjs/twilio` | ✅ | ✅ | ❌ | ❌ | | `@airhornjs/aws` | ✅ | ✅ | ✅ | ❌ | | `@airhornjs/azure` | ✅ | ✅ | ✅ | ❌ | Note: We used to support firebase because of mobile push but it made more sense to focus on `aws` and `azure` because it is more comprehensive. # How to Contribute Now that you've set up your workspace, you're ready to contribute changes to the `airhorn` repository you can refer to the [CONTRIBUTING](CONTRIBUTING.md) guide. If you have any questions please feel free to ask by creating an issue and label it `question`. # Licensing and Copyright This project is [MIT License © Jared Wray](LICENSE) ### airhorn URL: https://airhorn.org/docs/airhorn/ [![tests](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml/badge.svg)](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml) [![codecov](https://codecov.io/gh/jaredwray/airhorn/branch/main/graph/badge.svg?token=4OJEEB67Q5)](https://codecov.io/gh/jaredwray/airhorn) [![license](https://img.shields.io/github/license/jaredwray/airhorn)](https://github.com/jaredwray/airhorn/blob/master/LICENSE) [![npm](https://img.shields.io/npm/dm/airhorn)](https://npmjs.com/package/airhorn) [![npm](https://img.shields.io/npm/v/airhorn)](https://npmjs.com/package/airhorn) # Cloud Native Notifications `Airhorn` simplifies the process of notifications by using templates to send messages across various providers with a common easy to use interface. - Supports multiple notification types: SMS, Email, Mobile Push, Webhooks - A unified API for all notification types using the `send()` method. - Hooks and Emitting built in by default for extendability and observability. - Send Strategy (Round Robin, Fail Over, All) Choose the best delivery method for each notification. - Built in Webhook support for sending notifications to external services. - Built in support for retries and error handling on sends. - Advanced caching on template compilation and execution. - Load a template from a file for easy GitOps based workflows. - Many supported providers such as Twilio (with Sendgrid), AWS, and Google Cloud. - Robust (6+ template formats) templating via [ecto](https://github.com/jaredwray/ecto) - Easily build your own provider with minimal effort via `AirhornProvider` interface. - Statistics tracking for send successes, failures, and execution times (instance only). - ESM and Typescript based supporting Nodejs 20+ - Maintained on a regular basis with updates and improvements. # Table of Contents - [Getting Started](#getting-started) - [Airhorn Options](#airhorn-options) - [Using Send Helper Methods](#using-send-helper-methods) - [Airhorn Send Response](#airhorn-send-response) - [Send Strategies](#send-strategies) - [Airhorn API](#airhorn-api) - [Constructor](#constructor) - [Properties](#properties) - [.cache](#cache) - [.sendStrategy](#sendstrategy) - [.throwOnErrors](#throwonerrors) - [.statistics](#statistics-1) - [.providers](#providers) - [Methods](#methods) - [.send()](#send) - [.sendAll()](#sendall) - [.sendFailOver()](#sendfailover) - [.sendRoundRobin()](#sendroundrobin) - [.sendSMS()](#sendsms) - [.sendEmail()](#sendemail) - [.sendMobilePush()](#sendmobilepush) - [.sendWebhook()](#sendwebhook) - [.loadTemplate()](#loadtemplate) - [.addProvider()](#addprovider) - [.addProviders()](#addproviders) - [.getProvidersByType()](#getprovidersbytype) - [.generateMessage()](#generatemessage) - [Using Webhooks](#using-webhooks) - [Statistics](#statistics) - [Hooks](#hooks) - [Emitting Events](#emitting-events) - [Load Template Helper](#load-template-helper) - [Migration to v6](#migration-to-v6) - [Core Supported Providers](#core-supported-providers) - [Third Party Providers](#third-party-providers) - [Creating a Provider](#creating-a-provider) - [How to Contribute](#how-to-contribute) - [Licensing and Copyright](#licensing-and-copyright) # Getting Started To get started with Airhorn, you can install it via npm: ```bash npm install airhorn ``` Once installed, this gives you the main send functionality and built in webhook support. You can use it in your project like so: ```typescript import { Airhorn, AirhornProviderType } from "airhorn"; const airhorn = new Airhorn(); const template = { from: "https://mywebhookdomain.com", content: "Hey <%= name %> this is a test message from Airhorn", templateEngine: "ejs", } const data = { name: "John" }; await airhorn.send("https://mockhttp.org/post", template, data, AirhornProviderType.WEBHOOK); ``` Now lets configure the Airhorn instance with your preferred providers such as `Twilio` for SMS and `SendGrid` for Email. ```bash npm install airhorn @airhornjs/twilio ``` ```typescript import { Airhorn, AirhornProviderType } from "airhorn"; import { AirhornTwilio } from "@airhornjs/twilio"; const providers = [ new AirhornTwilio({ accountSid: "your_account_sid", authToken: "your_auth_token" }), ]; const airhorn = new Airhorn({ providers }); // this will give you twilio and webhook (built in) support. Now lets create a template and send it! const template = { from: "+12223334444", content: "Hey <%= name %> this is a test message from Airhorn", templateEngine: "ejs", } const data = { name: "John" }; await airhorn.send("+1234567890", template, data, AirhornProviderType.SMS); ``` To learn about the available providers and their capabilities, check the [Providers](#core-supported-providers) section. # Airhorn Options Airhorn provides a variety of options to customize its behavior. You can configure these options when creating an instance of the `Airhorn` class: ```typescript import { Airhorn, AirhornSendStrategy } from "airhorn"; const airhorn = new Airhorn({ sendStrategy: AirhornSendStrategy.RoundRobin }); ``` Here is the `AirhornOptions` type: ```typescript export type AirhornOptions = { /** * Whether to enable caching. * @default true */ cache?: boolean | Cacheable | CacheableOptions; /** * Whether to collect statistics. * @default false */ statistics?: boolean; /** * The providers to add to the Airhorn instance. AirhornWebhook is added by default unless `useWebhookProvider` is set to false. */ providers?: Array; /** * Whether to use the built-in webhook provider. * @default true */ useWebhookProvider?: boolean; /** * The retry strategy to use when sending messages. * @default 0 */ retryStrategy?: AirhornRetryStrategy; /** * The timeout to use when sending messages. * @default 100 */ timeout?: number; /** * The send strategy to use when sending messages. * @default AirhornSendStrategy.RoundRobin */ sendStrategy?: AirhornSendStrategy; /** * Whether to throw an error if sending fails. By default we use emitting for errors. * Delegates to hookified's `throwOnEmitError` and `throwOnHookError`. * @default false */ throwOnErrors?: boolean; }; ``` # Using Send Helper Methods Airhorn provides helper methods for common tasks. For example, you can use the `sendSMS` method to send SMS messages easily: ```typescript import { Airhorn } from "airhorn"; import { AirhornTwilio } from "@airhornjs/twilio"; const providers = [ new AirhornTwilio({ accountSid: "your_account_sid", authToken: "your_auth_token" }), ]; const airhorn = new Airhorn({ providers }); const template = { from: "+12223334444", content: "Hey <%= name %> this is a test message from Airhorn", templateEngine: "ejs", } const data = { name: "John" }; await airhorn.sendSMS("+1234567890", template, data); ``` All helper methods accept an optional `AirhornSendOptions` parameter to override the send strategy per call: ```typescript import { Airhorn, AirhornSendStrategy } from "airhorn"; import { AirhornTwilio } from "@airhornjs/twilio"; const airhorn = new Airhorn({ providers: [ new AirhornTwilio({ accountSid: "sid_1", authToken: "token_1" }), new AirhornTwilio({ accountSid: "sid_2", authToken: "token_2" }), ] }); const template = { from: "+12223334444", content: "Hey <%= name %> this is a test message from Airhorn", templateEngine: "ejs", } const data = { name: "John" }; // Send SMS using fail-over strategy await airhorn.sendSMS("+1234567890", template, data, { sendStrategy: AirhornSendStrategy.FailOver }); ``` Here are the following helper methods available: - `sendSMS`: Sends an SMS message. - `sendEmail`: Sends an email message. - `sendMobilePush`: Sends a mobile push notification. - `sendWebhook`: Sends a webhook notification. - `sendAll`: Sends to all providers simultaneously. - `sendFailOver`: Tries providers in order until one succeeds. - `sendRoundRobin`: Cycles through providers round-robin. # Airhorn Send Response The `send` method returns an `AirhornSendResult` object that contains information about the send operation. Here is the structure of the `AirhornSendResult` type: ```typescript export type AirhornSendResult = { /** * The providers that were used to send the message. */ providers: Array; /** * The message that was sent. */ message?: AirhornProviderMessage; /** * Whether the message was sent successfully. */ success: boolean; /** * The response from the provider. */ // biome-ignore lint/suspicious/noExplicitAny: expected response: any; /** * The number of times the message was retried. */ retries: number; /** * The errors that occurred while sending the message. */ errors: Array; /** * The time taken to execute the send operation. */ executionTime: number; }; ``` # Send Strategies Airhorn supports multiple send strategies to control how notifications are delivered. The `send()` method dispatches to the appropriate strategy method based on the configured `sendStrategy` (default: `RoundRobin`). You can also call each strategy method directly. - **Round Robin** (`sendRoundRobin`): Cycles through providers, selecting the next one on each call. _(Default)_ - **Fail Over** (`sendFailOver`): Tries each provider in order until one succeeds. - **All** (`sendAll`): Sends the notification to all providers simultaneously. You can configure the default send strategy when creating the Airhorn instance: ```typescript import { Airhorn, AirhornSendStrategy } from "airhorn"; const airhorn = new Airhorn({ sendStrategy: AirhornSendStrategy.RoundRobin }); ``` Or call a strategy method directly: ## `sendAll` Sends a notification to all providers simultaneously. Succeeds if at least one provider succeeds. ```typescript import { Airhorn, AirhornSendType } from "airhorn"; const airhorn = new Airhorn(); const template = { from: "https://mywebhookdomain.com", content: "Hey <%= name %> this is a notification from Airhorn", templateEngine: "ejs", } const data = { name: "John" }; const result = await airhorn.sendAll("https://mockhttp.org/post", template, data, AirhornSendType.Webhook); ``` ## `sendFailOver` Tries each provider in order until one succeeds. If the first provider fails, it moves to the next. ```typescript import { Airhorn, AirhornSendType } from "airhorn"; const airhorn = new Airhorn(); const template = { from: "https://mywebhookdomain.com", content: "Hey <%= name %> this is a notification from Airhorn", templateEngine: "ejs", } const data = { name: "John" }; const result = await airhorn.sendFailOver("https://mockhttp.org/post", template, data, AirhornSendType.Webhook); ``` ## `sendRoundRobin` Cycles through providers, selecting the next one on each call. This is the default strategy. ```typescript import { Airhorn, AirhornSendType } from "airhorn"; const airhorn = new Airhorn(); const template = { from: "https://mywebhookdomain.com", content: "Hey <%= name %> this is a notification from Airhorn", templateEngine: "ejs", } const data = { name: "John" }; const result = await airhorn.sendRoundRobin("https://mockhttp.org/post", template, data, AirhornSendType.Webhook); ``` # Airhorn API ## Constructor ### `new Airhorn(options?: AirhornOptions)` Creates a new Airhorn instance. See [Airhorn Options](#airhorn-options) for available configuration options. ## Properties ### `.cache` Gets/sets the cache instance which is based on `cacheable`. ### `.sendStrategy` Gets/sets the send strategy (`RoundRobin`, `FailOver`, or `All`). ### `.throwOnErrors` Gets/sets the throw on errors flag. Delegates to hookified's `throwOnEmitError` and `throwOnHookError`. ### `.statistics` Access the statistics instance. See [Statistics](#statistics) to learn more. ### `.providers` Gets/sets the list of configured providers. ## Methods ### `.send()` Dispatches to the appropriate strategy method based on the configured `sendStrategy`. ### `.sendAll()` Sends to all providers simultaneously. Succeeds if at least one provider succeeds. ### `.sendFailOver()` Tries providers in order until one succeeds. ### `.sendRoundRobin()` Cycles through providers round-robin. This is the default strategy. ### `.sendSMS()` Sends an SMS message using the configured SMS providers. ### `.sendEmail()` Sends an email message using the configured email providers. ### `.sendMobilePush()` Sends a mobile push notification using the configured push providers. ### `.sendWebhook()` Sends a webhook notification using the built-in webhook provider. ### `.loadTemplate()` Loads a template from the file system. See [Load Template Helper](#load-template-helper) to learn more. ### `.addProvider()` Adds a single provider to the Airhorn instance. ### `.addProviders()` Adds multiple providers to the Airhorn instance. ### `.getProvidersByType()` Gets the list of providers filtered by type (SMS, Email, Push, Webhook). ### `.generateMessage()` Generates a message from a template and data using the configured template engine. # Using Webhooks Webhooks is built into Airhorn as a default provider and can be used to send notifications to external services. To use the built in webhooks just create an instance of the `Airhorn` class and call the `send` or `sendWebhook` method. An example using the `send` method (recommended): ```typescript import { Airhorn, AirhornProviderType } from "airhorn"; const template = { from: "+12223334444", to: "+1234567890", content: "Hey <%= name %> this is a test message from Airhorn", templateEngine: "ejs", } const data = { name: "John" }; await airhorn.send("https://mockhttp.org/post", template, data, AirhornProviderType.WEBHOOK); ``` To send using the helper function `sendWebhook`: ```typescript import { Airhorn } from "airhorn"; const airhorn = new Airhorn(); const template = { from: "+12223334444", to: "+1234567890", content: "Hey <%= name %> this is a test message from Airhorn", templateEngine: "ejs", } const data = { name: "John" }; await airhorn.sendWebhook("https://mockhttp.org/post", template, data); ``` # Statistics Airhorn provides built-in statistics to help you monitor the performance of your notifications. You can access the statistics instance through the `.statistics` property: ```typescript import { Airhorn } from "airhorn"; const airhorn = new Airhorn({ statistics: true }); // Now you can use the stats object to get information about sent notifications console.log(`Total Sends: ${airhorn.statistics.totalSends}`); console.log(`Total Successful Sends: ${airhorn.statistics.totalSendSuccesses}`); console.log(`Total Failed Sends: ${airhorn.statistics.totalSendFailures}`); // execution time statistics console.log(`Total Execution Time: ${airhorn.statistics.totalExecutionTime} ms`); console.log(`Average Execution Time: ${airhorn.statistics.averageExecutionTime} ms`); console.log(`Minimum Execution Time: ${airhorn.statistics.minimumExecutionTime} ms`); console.log(`Maximum Execution Time: ${airhorn.statistics.maxExecutionTime} ms`); // execution time data Array console.log(`All Execution Times: ${airhorn.statistics.executionTimes}`); console.log(`Slowest Execution Times: ${airhorn.statistics.slowestExecutionTimes}`); console.log(`Fastest Execution Times: ${airhorn.statistics.fastestExecutionTimes}`); ``` By default, Airhorn statistics are disabled. You can enable them by setting the `statistics` option to `true` when creating the Airhorn instance. If you want to enable it after the Airhorn instance is created do the following: ```typescript import { Airhorn } from "airhorn"; const airhorn = new Airhorn(); airhorn.statistics.enable(); ``` To reset the statistics, you can call the `reset` method: ```typescript import { Airhorn } from "airhorn"; const airhorn = new Airhorn(); airhorn.statistics.reset(); ``` # Hooks Airhorn extends [Hookified](https://hookified.org) and provides two built-in hooks for intercepting the send pipeline: - `before:Send` (`AirhornHook.BeforeSend`) — Called before a message is sent. Receives `{ message, options }`. - `after:Send` (`AirhornHook.AfterSend`) — Called after a message is sent. Receives `{ result }`. ## Registering Hooks with `onHook` You can register hooks using the `onHook` method. It supports both a simple `(event, handler)` signature and the `IHook` object format (recommended): ```typescript import { Airhorn, AirhornHook } from "airhorn"; import type { IHook } from "hookified"; const airhorn = new Airhorn(); airhorn.onHook({ event: AirhornHook.BeforeSend, handler: async ({ message, options }) => { message.content = `[PREFIX] ${message.content}`; }, }); // IHook object with an id and OnHookOptions for positioning airhorn.onHook( { id: 'hook-after-send-1', event: AirhornHook.AfterSend, handler: async ({ result }) => { console.log("Send result:", result.success); }, }, { position: "Top" }, ); ``` ## Modifying Messages with BeforeSend The `BeforeSend` hook receives the message object by reference, so you can modify it before it is sent: ```typescript import { Airhorn, AirhornHook, AirhornSendType } from "airhorn"; const airhorn = new Airhorn(); airhorn.onHook(AirhornHook.BeforeSend, async ({ message }) => { // Redirect the message message.to = "https://new-endpoint.example.com/webhook"; // Modify content message.content = `[MODIFIED] ${message.content}`; }); const template = { from: "sender@example.com", content: "Hello <%= name %>!", templateEngine: "ejs", }; await airhorn.send("https://original.example.com/webhook", template, { name: "World" }, AirhornSendType.Webhook); ``` ## Inspecting Results with AfterSend The `AfterSend` hook is called after the send completes (even on failure): ```typescript import { Airhorn, AirhornHook } from "airhorn"; const airhorn = new Airhorn(); airhorn.onHook(AirhornHook.AfterSend, async ({ result }) => { if (result.success) { console.log("Message sent successfully"); } else { console.error("Send failed with errors:", result.errors); } }); ``` ## Managing Hooks by ID Using `IHook` objects with an `id` allows you to look up or remove hooks later: ```typescript import { Airhorn, AirhornHook } from "airhorn"; const airhorn = new Airhorn(); // Register with an id airhorn.onHook({ id: "logging-hook", event: AirhornHook.BeforeSend, handler: async ({ message }) => { console.log("Sending:", message); }, }); // Look up by id const hook = airhorn.getHook("logging-hook"); // Remove by id airhorn.removeHookById("logging-hook"); ``` # Emitting Events Airhorn provides event emitting by default with the following events: - `error`: Emitted when there is an error. - `send.success`: Emitted when a notification is successfully sent. - `send.failure`: Emitted when a notification fails to send. You can listen for these events using the `on` method: ```typescript import { Airhorn, AirhornEvent, type AirhornSendResult } from "airhorn"; const airhorn = new Airhorn(); airhorn.on(AirhornEvent.SendSuccess, (data: AirhornSendResult) => { console.log(`Notification sent successfully: ${data}`); }); airhorn.on(AirhornEvent.SendFailure, (data: AirhornSendResult) => { console.error(`Failed to send notification: ${data}`); }); ``` # Load Template Helper In previous versions of `Airhon` we used the file system to load all the templates into a store that was used by the instance. Now, we offer an easy method to just load it from a markdown file if you want from anywhere on the file system. Here is an example of how to use the `loadTemplate` helper method: ```typescript import { Airhorn } from "airhorn"; const airhorn = new Airhorn(); const template = await airhorn.loadTemplate("path/to/template.md"); // now you can send with that template await airhorn.send("https://mockhttp.org/post", template, data, AirhornProviderType.WEBHOOK); ``` An example of the `markdown` format is located at `./packages/airhorn/test/fixtures`. # Core Supported Providers We currently support `twilio`, `aws`, and `azure` with thier offerings. Here is a chart showing what functionality is in each: | Provider | SMS | Email | Push | Webhook | |----------|-----|-------|------|---------| | (built in `airhorn`) | ❌ | ❌ | ❌ | ✅ | | `@airhornjs/twilio` | ✅ | ✅ | ❌ | ❌ | | `@airhornjs/aws` | ✅ | ✅ | ✅ | ❌ | | `@airhornjs/azure` | ✅ | ✅ | ✅ | ❌ | Note: We used to support firebase because of mobile push but it made more sense to focus on `aws` and `azure` because it is more comprehensive. # Third Party Providers If you have built a provider library let us know! We are more than happy to list it here! # Creating a Provider To create a provider you can extend the `AirhornProvider` interface and implement the required methods for your specific provider. ```typescript import { AirhornProvider } from "airhorn"; class MyCustomProvider implements AirhornProvider { // Implement required methods } ``` Once implemented, you can use your custom provider just like any other provider in Airhorn. ```typescript import { Airhorn, AirhornProvider } from "airhorn"; class MyCustomProvider implements AirhornProvider { // Implement required methods } const airhorn = new Airhorn({ providers: [new MyCustomProvider()] }); ``` Use one of the built in providers as a reference such as `@airhornjs/twilio`. # Migration to v6 Airhorn v6 upgrades to [Hookified v2](https://hookified.org), which introduces breaking changes to the hooks API. If you were using hooks in v5, you will need to update your code. ## Breaking Changes ### `addHook` renamed to `onHook` The `addHook` method has been renamed to `onHook`. The `onHook` method also now supports `IHook` objects and `OnHookOptions` for hook positioning and ID management: ```typescript // v5 airhorn.addHook("before:Send", async (data) => {}); // v6 — simple signature (drop-in replacement) airhorn.onHook("before:Send", async (data) => {}); // v6 — IHook object (recommended) airhorn.onHook({ id: "my-hook", event: "before:Send", handler: async (data) => {}, }); ``` ### `removeHook` now accepts `IHook` objects The `removeHook` method signature has changed to accept `IHook` objects and now returns the removed hook: ```typescript // v5 airhorn.removeHook("before:Send", handler); // v6 const removed = airhorn.removeHook({ event: "before:Send", handler }); ``` You can also remove hooks by ID: ```typescript airhorn.removeHookById("my-hook"); ``` ### `getHooks` returns `IHook[]` instead of functions If you were calling `getHooks()`, it now returns `IHook[]` objects instead of raw handler functions: ```typescript // v5 — returns Function[] const hooks = airhorn.getHooks("before:Send"); // v6 — returns IHook[] with { id, event, handler } const hooks = airhorn.getHooks("before:Send"); hooks.forEach((hook) => console.log(hook.handler)); ``` ### `throwOnErrors` now delegates to hookified The `throwOnErrors` option still works the same way from a user perspective, but internally it now delegates to hookified's `throwOnEmitError` and `throwOnHookError` properties. The private `handleError` method has been removed — error throwing is handled by hookified automatically when `throwOnErrors` is set to `true`. ### Hookified constructor option renames These are handled internally by Airhorn, but if you were extending the class: | v5 | v6 | |----|----| | `throwHookErrors` | `throwOnHookError` | | `logger` | `eventLogger` | ## Migration Checklist - [ ] Replace all `addHook()` calls with `onHook()` - [ ] Update `removeHook()` calls to use `IHook` objects - [ ] Update code that reads `getHooks()` results to handle `IHook[]` - [ ] If extending Airhorn, rename `throwHookErrors` to `throwOnHookError` in `super()` calls # How to Contribute Now that you've set up your workspace, you're ready to contribute changes to the `airhorn` repository you can refer to the [CONTRIBUTING](../../CONTRIBUTING.md) guide. If you have any questions please feel free to ask by creating an issue and label it `question`. # Licensing and Copyright This project is [MIT License © Jared Wray](LICENSE) ### @airhornjs/aws URL: https://airhorn.org/docs/aws/ --- [![tests](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml/badge.svg)](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml) [![codecov](https://codecov.io/gh/jaredwray/airhorn/branch/main/graph/badge.svg?token=4OJEEB67Q5)](https://codecov.io/gh/jaredwray/airhorn) [![license](https://img.shields.io/github/license/jaredwray/airhorn)](https://github.com/jaredwray/airhorn/blob/master/LICENSE) [![npm](https://img.shields.io/npm/dm/@airhornjs/aws)](https://npmjs.com/package/@airhornjs/aws) [![npm](https://img.shields.io/npm/v/@airhornjs/aws)](https://npmjs.com/package/@airhornjs/aws) # @airhornjs/aws AWS SNS and SES provider for Airhorn. ## Installation ```bash npm install airhorn @airhornjs/aws ``` ## Features - SMS sending via Amazon SNS (Simple Notification Service) - Email sending via Amazon SES (Simple Email Service) - Automatic error handling and retry support - Integration with Airhorn's notification system - Support for AWS credentials from environment variables or explicit configuration ## Usage ### SMS with Amazon SNS ```typescript import { Airhorn } from 'airhorn'; import { AirhornAws } from '@airhornjs/aws'; // Create AWS provider for SMS const awsProvider = new AirhornAws({ region: 'us-east-1', accessKeyId: 'your-access-key', // Optional, uses AWS SDK credential chain secretAccessKey: 'your-secret-key', // Optional, uses AWS SDK credential chain }); // Create Airhorn instance with AWS provider const airhorn = new Airhorn({ providers: [awsProvider], }); // Send SMS const message = { from: '+1234567890', // Your sender ID or phone number content: 'Hello John!, your order #12345 has been shipped!', type: AirhornSendType.SMS, }; const result = await airhorn.send( '+0987654321', // to message, ); ``` ### Email with Amazon SES ```typescript import { Airhorn } from 'airhorn'; import { AirhornAws } from '@airhornjs/aws'; // Create AWS provider with SES support const awsProvider = new AirhornAws({ region: 'us-east-1', accessKeyId: 'your-access-key', // Optional secretAccessKey: 'your-secret-key', // Optional }); // Create Airhorn instance const airhorn = new Airhorn({ providers: [awsProvider], }); const data = { orderId: '656565', customerName: 'John', }; // Send Email const template = { from: 'sender@example.com', // Must be verified in SES subject: 'Order <%= orderId %> Confirmation', content: '

Hello <%= customerName %>

Your order #<%= orderId %> has been confirmed!

', }; const result = await airhorn.send( 'recipient@example.com', // to template, data, AirhornSendType.Email ); ``` ### Both SMS and Email By default, the provider supports both SMS and email notifications: ```typescript const provider = new AirhornAws({ region: 'us-east-1', // AWS credentials can be provided explicitly or loaded from environment accessKeyId: 'your-access-key', secretAccessKey: 'your-secret-key', sessionToken: 'your-session-token', // Optional for temporary credentials }); // Provider capabilities will include both 'sms' and 'email' by default console.log(provider.capabilities); // ['sms', 'email'] ``` ### Custom Capabilities You can specify which services to enable using the `capabilities` option: ```typescript // SMS only const smsProvider = new AirhornAws({ region: 'us-east-1', capabilities: [AirhornSendType.SMS], }); // Email only const emailProvider = new AirhornAws({ region: 'us-east-1', capabilities: [AirhornSendType.Email], }); // Both (explicit) const bothProvider = new AirhornAws({ region: 'us-east-1', capabilities: [AirhornSendType.SMS, AirhornSendType.Email], }); ``` ### Push Notifications to Mobile Devices (iOS/Android) Amazon SNS can send push notifications to mobile devices through platform application endpoints. Here's how to send notifications to Apple (APNs) and Android (FCM/GCM) devices: ```typescript import { Airhorn } from 'airhorn'; import { AirhornAws } from '@airhornjs/aws'; const awsProvider = new AirhornAws({ region: 'us-east-1', capabilities: [AirhornSendType.SMS], // SNS handles mobile push }); const airhorn = new Airhorn({ providers: [awsProvider], }); const data = { orderId: '12345', }; // Send to iOS device via APNs const template = { from: 'YourApp', // Sender ID content: JSON.stringify({ aps: { alert: { title: 'New Order', body: 'You have a new order #<%= orderId %>', }, badge: 1, sound: 'default', }, // Custom data orderId: '12345', }), }; // Send to Apple device endpoint ARN await airhorn.send( 'arn:aws:sns:us-east-1:123456789012:endpoint/APNS/YourApp/abc123', // iOS endpoint ARN template, AirhornSendType.MobilePush, { MessageStructure: 'json', // Required for platform-specific payloads MessageAttributes: { 'AWS.SNS.MOBILE.APNS.PUSH_TYPE': { DataType: 'String', StringValue: 'alert', // or 'background' }, }, }, ); ``` **Note**: Before sending push notifications, you need to: 1. Create platform applications in SNS for APNs/FCM 2. Register device tokens and create platform endpoints 3. Optionally create SNS topics for broadcasting 4. Configure proper IAM permissions for SNS platform endpoints ## Configuration ### AirhornAwsOptions - `region` (required): AWS region (e.g., 'us-east-1', 'eu-west-1') - `accessKeyId` (optional): AWS access key ID (uses AWS SDK credential chain if not provided) - `secretAccessKey` (optional): AWS secret access key (uses AWS SDK credential chain if not provided) - `sessionToken` (optional): AWS session token for temporary credentials - `capabilities` (optional): Array of `AirhornSendType` values to specify which services to enable (defaults to both SMS and Email) ## Additional Options You can pass additional provider-specific options as the second parameter to the send method: ### Amazon SNS Options ```typescript await airhorn.send(to, message, { smsType: 'Promotional', // or 'Transactional' (default) maxPrice: '0.50', // Maximum price in USD // ... other SNS PublishCommand options }); ``` ### Amazon SES Options ```typescript await airhorn.send(to, message, { ccAddresses: ['cc@example.com'], bccAddresses: ['bcc@example.com'], replyToAddresses: ['reply@example.com'], returnPath: 'bounces@example.com', configurationSetName: 'my-configuration-set', tags: [ { Name: 'campaign', Value: 'summer-sale' }, { Name: 'customer', Value: 'vip' } ], // ... other SES SendEmailCommand options }); ``` ## Prerequisites ### AWS Credentials The AWS SDK will automatically look for credentials in the following order: 1. Credentials passed explicitly in `AirhornAwsOptions` 2. Environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`) 3. Shared credentials file (`~/.aws/credentials`) 4. IAM role (when running on EC2, ECS, Lambda, etc.) ### Amazon SNS Setup 1. Ensure your AWS account has SNS permissions 2. Configure SMS settings in SNS console if needed 3. Note that SMS capabilities and pricing vary by region ### Amazon SES Setup 1. Verify your sender email address or domain in SES 2. Request production access (SES starts in sandbox mode) 3. Configure any necessary SES settings (configuration sets, etc.) ## IAM Permissions Minimum required IAM permissions: ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sns:Publish" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "ses:SendEmail" ], "Resource": "*" } ] } ``` # How to Contribute Now that you've set up your workspace, you're ready to contribute changes to the `airhorn` repository you can refer to the [CONTRIBUTING](CONTRIBUTING.md) guide. If you have any questions please feel free to ask by creating an issue and label it `question`. # Licensing and Copyright This project is [MIT License © Jared Wray](LICENSE) ### @airhornjs/azure URL: https://airhorn.org/docs/azure/ --- [![tests](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml/badge.svg)](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml) [![codecov](https://codecov.io/gh/jaredwray/airhorn/branch/main/graph/badge.svg?token=4OJEEB67Q5)](https://codecov.io/gh/jaredwray/airhorn) [![license](https://img.shields.io/github/license/jaredwray/airhorn)](https://github.com/jaredwray/airhorn/blob/master/LICENSE) [![npm](https://img.shields.io/npm/dm/@airhornjs/azure)](https://npmjs.com/package/@airhornjs/azure) [![npm](https://img.shields.io/npm/v/@airhornjs/azure)](https://npmjs.com/package/@airhornjs/azure) # @airhornjs/azure Azure Communication Services and Notification Hubs provider for Airhorn. ## Installation ```bash npm install airhorn @airhornjs/azure ``` ## Features - SMS sending via Azure Communication Services - Email sending via Azure Communication Services - Mobile push notifications to iOS and Android devices via Azure Notification Hubs - Automatic error handling and retry support - Integration with Airhorn's notification system - Support for multiple connection strings ## Usage ### SMS with Azure Communication Services ```typescript import { Airhorn } from 'airhorn'; import { AirhornAzure } from '@airhornjs/azure'; // Create Azure provider for SMS const azureProvider = new AirhornAzure({ connectionString: 'endpoint=https://your-service.communication.azure.com/;accesskey=your-key', }); // Create Airhorn instance with Azure provider const airhorn = new Airhorn({ providers: [azureProvider], }); const data = { orderId: '12345', customerName: 'John', }; // Send SMS const template = { from: '+1234567890', // Your sender phone number (must be provisioned in Azure) content: 'Hello <%= customerName %>!, your order #<%= orderId %> has been shipped!', type: AirhornSendType.SMS, }; const result = await airhorn.send( '+0987654321', // to template, data, AirhornSendType.SMS ); ``` ### Email with Azure Communication Services ```typescript import { Airhorn } from 'airhorn'; import { AirhornAzure } from '@airhornjs/azure'; // Create Azure provider with email support const azureProvider = new AirhornAzure({ connectionString: 'endpoint=https://your-service.communication.azure.com/;accesskey=your-key', }); // Create Airhorn instance const airhorn = new Airhorn({ providers: [azureProvider], }); const data = { orderId: '656565', customerName: 'John', }; // Send Email const template = { from: 'DoNotReply@yourdomain.com', // Must be verified domain in Azure subject: 'Order Confirmation: <%= orderId %>', content: 'Hi <%= customerName %>, your order #<%= orderId %> has been confirmed!', }; const result = await airhorn.send( 'recipient@example.com', // to template, data, AirhornSendType.Email ); ``` ### Mobile Push Notifications with Azure Notification Hubs ```typescript import { Airhorn } from 'airhorn'; import { AirhornAzure } from '@airhornjs/azure'; const azureProvider = new AirhornAzure({ notificationHubConnectionString: 'Endpoint=sb://your-namespace.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=your-key', notificationHubName: 'your-hub-name', }); const airhorn = new Airhorn({ providers: [azureProvider], }); const data = { orderId: '12345', customerName: 'John', }; // Send to iOS device via APNs const template = { from: 'YourApp', content: JSON.stringify({ aps: { alert: { title: 'New Order', body: 'Hi <%= customerName %>You have a new order #<%= orderId %>', }, badge: 1, sound: 'default', }, // Custom data orderId: '12345', }), }; // Send using tag expression await airhorn.send( 'user:john-doe', // Tag expression template, data, AirhornSendType.MobilePush, { platform: 'apple', tags: 'user:john-doe && ios', }, ); ``` ### Custom Capabilities You can specify which services to enable using the `capabilities` option: ```typescript // SMS only const smsProvider = new AirhornAzure({ connectionString: 'your-connection-string', capabilities: [AirhornSendType.SMS], }); // Email only const emailProvider = new AirhornAzure({ connectionString: 'your-connection-string', capabilities: [AirhornSendType.Email], }); // Mobile Push only const pushProvider = new AirhornAzure({ notificationHubConnectionString: 'your-hub-connection-string', notificationHubName: 'your-hub-name', capabilities: [AirhornSendType.MobilePush], }); // All capabilities (explicit) const allProvider = new AirhornAzure({ connectionString: 'your-communication-services-connection-string', notificationHubConnectionString: 'your-hub-connection-string', notificationHubName: 'your-hub-name', capabilities: [AirhornSendType.SMS, AirhornSendType.Email, AirhornSendType.MobilePush], }); ``` ## Configuration ### AirhornAzureOptions - `connectionString` (optional): Azure Communication Services connection string (used for both SMS and Email if specific strings not provided) - `emailConnectionString` (optional): Specific connection string for Email service - `smsConnectionString` (optional): Specific connection string for SMS service - `notificationHubConnectionString` (optional): Azure Notification Hub connection string - `notificationHubName` (optional): Azure Notification Hub name - `capabilities` (optional): Array of `AirhornSendType` values to specify which services to enable (defaults to SMS, MobilePush, and Email) ## Additional Options ### SMS Options ```typescript await airhorn.send(to, message, { // Additional SMS options from Azure Communication Services deliveryReportTimeoutInSeconds: 300, tag: 'custom-tag', }); ``` ## Prerequisites ### Azure Communication Services 1. Create an Azure Communication Services resource in Azure Portal 2. Get your connection string from the resource 3. For SMS: Provision a phone number through the Azure Portal 4. For Email: Verify your sending domain ### Azure Notification Hubs 1. Create a Notification Hub namespace and hub in Azure Portal 2. Configure platform credentials (APNs for iOS, FCM for Android) 3. Get your connection string and hub name 4. Implement device registration in your mobile apps ## Azure RBAC Permissions Minimum required permissions for the service principal or managed identity: ### For Communication Services: - `Azure Communication Services Contributor` role - Or specific permissions: - `Microsoft.Communication/CommunicationServices/read` - `Microsoft.Communication/CommunicationServices/write` ### For Notification Hubs: - `Azure Notification Hubs Contributor` role - Or specific permissions: - `Microsoft.NotificationHubs/Namespaces/NotificationHubs/read` - `Microsoft.NotificationHubs/Namespaces/NotificationHubs/write` ## Testing ```bash pnpm test ``` # How to Contribute Now that you've set up your workspace, you're ready to contribute changes to the `airhorn` repository you can refer to the [CONTRIBUTING](CONTRIBUTING.md) guide. If you have any questions please feel free to ask by creating an issue and label it `question`. # Licensing and Copyright This project is [MIT License © Jared Wray](LICENSE) ### @airhornjs/twilio URL: https://airhorn.org/docs/twilio/ --- [![tests](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml/badge.svg)](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml) [![codecov](https://codecov.io/gh/jaredwray/airhorn/branch/main/graph/badge.svg?token=4OJEEB67Q5)](https://codecov.io/gh/jaredwray/airhorn) [![license](https://img.shields.io/github/license/jaredwray/airhorn)](https://github.com/jaredwray/airhorn/blob/master/LICENSE) [![npm](https://img.shields.io/npm/dm/@airhornjs/twilio)](https://npmjs.com/package/@airhornjs/twilio) [![npm](https://img.shields.io/npm/v/@airhornjs/twilio)](https://npmjs.com/package/@airhornjs/twilio) # @airhornjs/twilio Twilio SMS and SendGrid Email provider for the Airhorn notification system. ## Installation ```bash npm install airhorn @airhornjs/twilio ``` ## Features - SMS sending via Twilio API - Email sending via SendGrid API - Automatic error handling and retry support - Integration with Airhorn's notification system ## Usage ### SMS with Twilio ```typescript import { Airhorn } from 'airhorn'; import { AirhornTwilio } from '@airhornjs/twilio'; // Create Twilio provider for SMS only const twilioProvider = new AirhornTwilio({ accountSid: 'your-account-sid', authToken: 'your-auth-token', }); // Create Airhorn instance with Twilio provider const airhorn = new Airhorn({ providers: [twilioProvider], }); // Send SMS const message = { from: '+1234567890', content: 'Hello John!, your order #12345 has been shipped!', type: AirhornProviderType.SMS, }; const result = await airhorn.send( '+0987654321', // to message, ); ``` ### Email with SendGrid ```typescript import { Airhorn } from 'airhorn'; import { TwilioProvider } from '@airhornjs/twilio'; // Create Twilio provider with SendGrid support const twilioProvider = new TwilioProvider({ accountSid: 'your-account-sid', authToken: 'your-auth-token', sendGridApiKey: 'your-sendgrid-api-key', // Enables email support }); // Create Airhorn instance const airhorn = new Airhorn({ providers: [twilioProvider], }); // Send Email const message = { from: 'sender@example.com', subject: 'Order Confirmation', content: '

Hello John

Your order #656565 has been confirmed!

', type: AirhornProviderType.Email, }; const result = await airhorn.send( 'recipient@example.com', // to message, ); ``` ### Both SMS and Email When configured with both Twilio and SendGrid credentials, the provider supports both SMS and email notifications: ```typescript const provider = new TwilioProvider({ // Twilio SMS configuration accountSid: 'your-account-sid', authToken: 'your-auth-token', // SendGrid Email configuration sendGridApiKey: 'your-sendgrid-api-key', // Optional Twilio configuration region: 'sydney', edge: 'sydney', }); // Provider capabilities will include both 'sms' and 'email' console.log(provider.capabilities); // ['sms', 'email'] ``` ## Configuration ### AirhornTwilioOptions - `accountSid` (required): Your Twilio Account SID - `authToken` (required): Your Twilio Auth Token - `sendGridApiKey` (optional): Your SendGrid API key (enables email support) - `region` (optional): Twilio region - `edge` (optional): Twilio edge location ## Additional Options You can pass additional provider-specific options as the second parameter to the send method: ### Twilio SMS Options ```typescript await airhorn.send(to, message, { statusCallback: 'https://example.com/callback', maxPrice: '0.50', validityPeriod: 14400, // ... other Twilio message options }); ``` ### SendGrid Email Options ```typescript await airhorn.send(to, message, { replyTo: 'reply@example.com', categories: ['transactional', 'order-confirmation'], trackingSettings: { clickTracking: { enable: true }, openTracking: { enable: true }, }, // ... other SendGrid mail options }); ``` # How to Contribute Now that you've set up your workspace, you're ready to contribute changes to the `airhorn` repository you can refer to the [CONTRIBUTING](CONTRIBUTING.md) guide. If you have any questions please feel free to ask by creating an issue and label it `question`. # Licensing and Copyright This project is [MIT License © Jared Wray](LICENSE) ## API Reference URL: https://airhorn.org/api - Not available. ## Changelog URL: https://airhorn.org/changelog ### v6.0.1 URL: https://airhorn.org/changelog/v6-0-1 Date: April 7, 2026 Tag: Release ## What's Changed * mono - feat: updating readme by @jaredwray in [https://github.com/jaredwray/airhorn/pull/565](https://github.com/jaredwray/airhorn/pull/565) * mono - chore: upgrading biome, vitest, and types by @jaredwray in [https://github.com/jaredwray/airhorn/pull/566](https://github.com/jaredwray/airhorn/pull/566) * airhorn - chore: upgrading cacheable by @jaredwray in [https://github.com/jaredwray/airhorn/pull/567](https://github.com/jaredwray/airhorn/pull/567) * airhorn - chore: upgrading writr by @jaredwray in [https://github.com/jaredwray/airhorn/pull/568](https://github.com/jaredwray/airhorn/pull/568) * aws - chore: upgrading the aws-sdk by @jaredwray in [https://github.com/jaredwray/airhorn/pull/569](https://github.com/jaredwray/airhorn/pull/569) * twilio - chore: upgrading twilio by @jaredwray in [https://github.com/jaredwray/airhorn/pull/570](https://github.com/jaredwray/airhorn/pull/570) * airhorn - chore: upgrading hookified by @jaredwray in [https://github.com/jaredwray/airhorn/pull/571](https://github.com/jaredwray/airhorn/pull/571) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v6.0.0...v6.0.1](https://github.com/jaredwray/airhorn/compare/v6.0.0...v6.0.1) ### v6.0.0 URL: https://airhorn.org/changelog/v6-0-0 Date: March 8, 2026 Tag: Release ## What's Changed * mono - chore: upgrading biome, types, and rimraf to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/559](https://github.com/jaredwray/airhorn/pull/559) * airhorn - chore: upgrading cacheable to 2.3.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/560](https://github.com/jaredwray/airhorn/pull/560) * airhorn - chore: upgrading ecto to 4.8.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/561](https://github.com/jaredwray/airhorn/pull/561) * airhorn - chore: upgrading writr to 5.0.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/562](https://github.com/jaredwray/airhorn/pull/562) * aws - chore: upgrading aws-sdk to 3.1003.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/563](https://github.com/jaredwray/airhorn/pull/563) * airhorn - feat: (breaking) migrating to hookified v2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/564](https://github.com/jaredwray/airhorn/pull/564) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v5.2.0...v6.0.0](https://github.com/jaredwray/airhorn/compare/v5.2.0...v6.0.0) ### v5.2.0 URL: https://airhorn.org/changelog/v5-2-0 Date: February 6, 2026 Tag: Release ## What's Changed * feat: Adding AGENTS.md and upgrading to Nodejs 24 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/555](https://github.com/jaredwray/airhorn/pull/555) * chore: upgrading docula to 0.40.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/556](https://github.com/jaredwray/airhorn/pull/556) * mono - chore: upgrading rimraf on packages by @jaredwray in [https://github.com/jaredwray/airhorn/pull/557](https://github.com/jaredwray/airhorn/pull/557) * feat: send strategies by @jaredwray in [https://github.com/jaredwray/airhorn/pull/558](https://github.com/jaredwray/airhorn/pull/558) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v5.1.2...v5.2.0](https://github.com/jaredwray/airhorn/compare/v5.1.2...v5.2.0) ### v5.1.2 URL: https://airhorn.org/changelog/v5-1-2 Date: January 6, 2026 Tag: Release ## What's Changed * mono - chore: upgrading docula to 0.31.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/543](https://github.com/jaredwray/airhorn/pull/543) * mono - chore: upgrading vitest to 4.0.16 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/544](https://github.com/jaredwray/airhorn/pull/544) * mono - chore: upgrading @biomejs/biome to 2.3.11 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/545](https://github.com/jaredwray/airhorn/pull/545) * airhorn - chore: upgrading vitest to 4.0.16 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/546](https://github.com/jaredwray/airhorn/pull/546) * airhorn - chore: upgrading cacheable to 2.3.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/547](https://github.com/jaredwray/airhorn/pull/547) * airhorn - chore: upgrading hookified to 1.14.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/548](https://github.com/jaredwray/airhorn/pull/548) * airhorn - chore: upgrading ecto to 4.8.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/549](https://github.com/jaredwray/airhorn/pull/549) * aws - chore: upgrading vitest to 4.0.16 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/550](https://github.com/jaredwray/airhorn/pull/550) * aws - chore: upgrading aws-sdk to 3.962.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/551](https://github.com/jaredwray/airhorn/pull/551) * azure - chore: upgrading vitest to 4.0.16 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/552](https://github.com/jaredwray/airhorn/pull/552) * twilio - chore: upgrading vitest to 4.0.16 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/553](https://github.com/jaredwray/airhorn/pull/553) * twilio - chore: upgrading twilio to 5.11.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/554](https://github.com/jaredwray/airhorn/pull/554) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v5.1.1...v5.1.2](https://github.com/jaredwray/airhorn/compare/v5.1.1...v5.1.2) ### v5.1.1 URL: https://airhorn.org/changelog/v5-1-1 Date: December 6, 2025 Tag: Release ## What's Changed * chore: upgrading @biomejs/biome to 2.3.8 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/538](https://github.com/jaredwray/airhorn/pull/538) * chore: upgrading tsup to 8.5.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/539](https://github.com/jaredwray/airhorn/pull/539) * chore: upgrading tsup to 8.5.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/540](https://github.com/jaredwray/airhorn/pull/540) * chore: upgrading tsup to 8.5.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/541](https://github.com/jaredwray/airhorn/pull/541) * chore: upgrading tsup to 8.5.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/542](https://github.com/jaredwray/airhorn/pull/542) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v5.1.0...v5.1.1](https://github.com/jaredwray/airhorn/compare/v5.1.0...v5.1.1) ### v5.1.0 URL: https://airhorn.org/changelog/v5-1-0 Date: November 6, 2025 Tag: Release ## What's Changed * airhorn - chore: removing minify as it causes debugging issues by @jaredwray in [https://github.com/jaredwray/airhorn/pull/517](https://github.com/jaredwray/airhorn/pull/517) * mono - chore: upgrading vitest to 4.0.7 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/518](https://github.com/jaredwray/airhorn/pull/518) * mono - chore: upgrading docula to 0.31.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/519](https://github.com/jaredwray/airhorn/pull/519) * mono - chore: upgrading @biomejs/biome to 2.3.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/520](https://github.com/jaredwray/airhorn/pull/520) * airhorn - chore: upgrading writr to 5.0.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/521](https://github.com/jaredwray/airhorn/pull/521) * airhorn - chore: upgrading vitest to 4.0.7 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/522](https://github.com/jaredwray/airhorn/pull/522) * airhorn - chore: upgrading @biomejs/biome to 2.3.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/523](https://github.com/jaredwray/airhorn/pull/523) * airhorn - chore: upgrading hookified to 1.12.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/524](https://github.com/jaredwray/airhorn/pull/524) * airhorn - chore: upgrading ecto to 4.7.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/525](https://github.com/jaredwray/airhorn/pull/525) * airhorn - chore: upgrading cacheable to 2.1.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/526](https://github.com/jaredwray/airhorn/pull/526) * aws - chrore: upgrading vitest to 4.0.7 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/527](https://github.com/jaredwray/airhorn/pull/527) * aws - chore: upgrading @biomejs/biome to 2.3.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/528](https://github.com/jaredwray/airhorn/pull/528) * aws - chore: upgrading @aws-sdk to 3.925.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/529](https://github.com/jaredwray/airhorn/pull/529) * azure - chore: upgrading vitest to 4.0.7 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/530](https://github.com/jaredwray/airhorn/pull/530) * azure - chore: upgrading @biomejs/biome to 2.3.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/531](https://github.com/jaredwray/airhorn/pull/531) * azure - chore: upgrading azure modules to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/532](https://github.com/jaredwray/airhorn/pull/532) * twilio - chore: upgrading vitest to 4.0.7 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/533](https://github.com/jaredwray/airhorn/pull/533) * twilio - chore: upgrading @biomejs/biome to 2.3.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/534](https://github.com/jaredwray/airhorn/pull/534) * twilio - chore: upgrading twilio to 5.10.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/535](https://github.com/jaredwray/airhorn/pull/535) * mono - fix: standardizing Licensing and Contribute by @jaredwray in [https://github.com/jaredwray/airhorn/pull/536](https://github.com/jaredwray/airhorn/pull/536) * airhorn - feat: adding in hooks on before and after send by @jaredwray in [https://github.com/jaredwray/airhorn/pull/537](https://github.com/jaredwray/airhorn/pull/537) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v5.0.12...v5.1.0](https://github.com/jaredwray/airhorn/compare/v5.0.12...v5.1.0) ### v5.0.12 URL: https://airhorn.org/changelog/v5-0-12 Date: October 6, 2025 Tag: Release ## What's Changed * mono - chore: upgrading typescript to 5.9.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/503](https://github.com/jaredwray/airhorn/pull/503) * mono - chore: upgrading docula to 0.30.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/504](https://github.com/jaredwray/airhorn/pull/504) * mono - chore: upgrading biome to 2.2.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/505](https://github.com/jaredwray/airhorn/pull/505) * airhorn - chore: upgrading biome to 2.2.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/506](https://github.com/jaredwray/airhorn/pull/506) * airhorn - chore: upgrading hookified to 1.12.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/507](https://github.com/jaredwray/airhorn/pull/507) * airhorn - chore: upgrading writr to 4.5.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/508](https://github.com/jaredwray/airhorn/pull/508) * aws - chore: upgrading typescript to 5.9.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/509](https://github.com/jaredwray/airhorn/pull/509) * aws - chore: upgrading biome to 2.2.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/510](https://github.com/jaredwray/airhorn/pull/510) * aws - chore: upgradking @aws-sdk to 3.901.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/511](https://github.com/jaredwray/airhorn/pull/511) * azure - chore: upgrading biome to 2.2.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/512](https://github.com/jaredwray/airhorn/pull/512) * twilio - chore: upgrading twilio to 5.10.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/513](https://github.com/jaredwray/airhorn/pull/513) * twilio - chore: upgrading @sendgrid/mail to 8.1.6 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/514](https://github.com/jaredwray/airhorn/pull/514) * twilio - chore: upgrading biome to 2.2.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/515](https://github.com/jaredwray/airhorn/pull/515) * airhorn - chore: adding in minification by @jaredwray in [https://github.com/jaredwray/airhorn/pull/516](https://github.com/jaredwray/airhorn/pull/516) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v5.0.11...v5.0.12](https://github.com/jaredwray/airhorn/compare/v5.0.11...v5.0.12) ### v5.0.11 URL: https://airhorn.org/changelog/v5-0-11 Date: September 6, 2025 Tag: Release ## What's Changed * mono - fix: moving to @airhornjs org by @jaredwray in [https://github.com/jaredwray/airhorn/pull/491](https://github.com/jaredwray/airhorn/pull/491) * mono - fix: updating documentation to @airhornjs by @jaredwray in [https://github.com/jaredwray/airhorn/pull/492](https://github.com/jaredwray/airhorn/pull/492) * mono - chore: upgrading @biomejs/biome to 2.2.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/493](https://github.com/jaredwray/airhorn/pull/493) * mono - fix: moving packages to build in prepublishOnly by @jaredwray in [https://github.com/jaredwray/airhorn/pull/502](https://github.com/jaredwray/airhorn/pull/502) * airhorn - chore: upgrading writr to 4.5.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/494](https://github.com/jaredwray/airhorn/pull/494) * airhorn - chore: upgrading @biomejs/biome to 2.2.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/495](https://github.com/jaredwray/airhorn/pull/495) * airhorn - feat: adding in CacheableOptions for cache by @jaredwray in [https://github.com/jaredwray/airhorn/pull/501](https://github.com/jaredwray/airhorn/pull/501) * aws - chore: upgrading @biomejs/biome to 2.2.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/496](https://github.com/jaredwray/airhorn/pull/496) * aws - chore: upgrading @aws-sdk to 3.883.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/497](https://github.com/jaredwray/airhorn/pull/497) * azure - chore: upgrading @biomejs/biome to 2.2.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/498](https://github.com/jaredwray/airhorn/pull/498) * twilio - chore: upgrading twiliot to 5.9.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/499](https://github.com/jaredwray/airhorn/pull/499) * twilio - chore: upgrading @biomejs/biome to 2.2.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/500](https://github.com/jaredwray/airhorn/pull/500) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v5.0.0...v5.0.2](https://github.com/jaredwray/airhorn/compare/v5.0.0...v5.0.2) ### v5.0.0 URL: https://airhorn.org/changelog/v5-0-0 Date: August 26, 2025 Tag: Release ## What's Changed * fix: removing unused variable on webhook tests by @jaredwray in [https://github.com/jaredwray/airhorn/pull/478](https://github.com/jaredwray/airhorn/pull/478) * V5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/479](https://github.com/jaredwray/airhorn/pull/479) * mono - fix: updating package.json to work with tsx by @jaredwray in [https://github.com/jaredwray/airhorn/pull/480](https://github.com/jaredwray/airhorn/pull/480) * aws - feat: adding in @airhorn/aws provider by @jaredwray in [https://github.com/jaredwray/airhorn/pull/481](https://github.com/jaredwray/airhorn/pull/481) * aws - feat: adding in mobile push by @jaredwray in [https://github.com/jaredwray/airhorn/pull/482](https://github.com/jaredwray/airhorn/pull/482) * azure - feat: adding @airhorn/azure provider by @jaredwray in [https://github.com/jaredwray/airhorn/pull/483](https://github.com/jaredwray/airhorn/pull/483) * airhorn - fix: making it so we are using ecto caching on templates by @jaredwray in [https://github.com/jaredwray/airhorn/pull/484](https://github.com/jaredwray/airhorn/pull/484) * airhorn - fix: removing unused properties by @jaredwray in [https://github.com/jaredwray/airhorn/pull/485](https://github.com/jaredwray/airhorn/pull/485) * airhon - fix: removing timeout as an unused variable by @jaredwray in [https://github.com/jaredwray/airhorn/pull/486](https://github.com/jaredwray/airhorn/pull/486) * mono - fix: build features should just work by @jaredwray in [https://github.com/jaredwray/airhorn/pull/487](https://github.com/jaredwray/airhorn/pull/487) * airhorn - fix: readme documentation to be more accurate by @jaredwray in [https://github.com/jaredwray/airhorn/pull/488](https://github.com/jaredwray/airhorn/pull/488) * site - feat: updating to handle docs by @jaredwray in [https://github.com/jaredwray/airhorn/pull/489](https://github.com/jaredwray/airhorn/pull/489) * airhorn - fix: formatting by @jaredwray in [https://github.com/jaredwray/airhorn/pull/490](https://github.com/jaredwray/airhorn/pull/490) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.1.9...v5.0.0](https://github.com/jaredwray/airhorn/compare/v4.1.9...v5.0.0) ### v4.1.9 URL: https://airhorn.org/changelog/v4-1-9 Date: August 6, 2025 Tag: Release ## What's Changed * chore: migrating to @biomejs/biome for lint and formatting by @jaredwray in [https://github.com/jaredwray/airhorn/pull/469](https://github.com/jaredwray/airhorn/pull/469) * chore: upgrading typescript to 5.9.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/470](https://github.com/jaredwray/airhorn/pull/470) * chore: upgrading twilio to 5.8.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/471](https://github.com/jaredwray/airhorn/pull/471) * chore: upgrading mongodb to 6.18.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/472](https://github.com/jaredwray/airhorn/pull/472) * chore: upgrading ecto to 4.4.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/473](https://github.com/jaredwray/airhorn/pull/473) * chore: upgrading docula to 0.13.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/474](https://github.com/jaredwray/airhorn/pull/474) * chore: upgrading cacheable to 1.10.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/475](https://github.com/jaredwray/airhorn/pull/475) * chore: upgrading axios to 1.11.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/476](https://github.com/jaredwray/airhorn/pull/476) * chore: upgrading aws-sdk to 3.859.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/477](https://github.com/jaredwray/airhorn/pull/477) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.1.8...v4.1.9](https://github.com/jaredwray/airhorn/compare/v4.1.8...v4.1.9) ### v4.1.8 URL: https://airhorn.org/changelog/v4-1-8 Date: July 8, 2025 Tag: Release ## What's Changed * fix: updating contributing guidelines to use pnpm by @jaredwray in [https://github.com/jaredwray/airhorn/pull/460](https://github.com/jaredwray/airhorn/pull/460) * chore: upgrading xo to 1.1.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/461](https://github.com/jaredwray/airhorn/pull/461) * chore: upgrading vitest to 3.2.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/462](https://github.com/jaredwray/airhorn/pull/462) * chore: upgrading twilio to 5.7.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/463](https://github.com/jaredwray/airhorn/pull/463) * chore: upgrading ecto to 4.3.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/464](https://github.com/jaredwray/airhorn/pull/464) * chore: upgrading docula to 0.13.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/465](https://github.com/jaredwray/airhorn/pull/465) * chore: upgrading cacheable to 1.10.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/466](https://github.com/jaredwray/airhorn/pull/466) * chore: upgrading axios to 1.10.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/467](https://github.com/jaredwray/airhorn/pull/467) * chore: upgrading aws-sdk to 3.840.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/468](https://github.com/jaredwray/airhorn/pull/468) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.1.7...v4.1.8](https://github.com/jaredwray/airhorn/compare/v4.1.7...v4.1.8) ### v4.1.7 URL: https://airhorn.org/changelog/v4-1-7 Date: June 6, 2025 Tag: Release ## What's Changed * chore: updating github actions to use permissions by @jaredwray in [https://github.com/jaredwray/airhorn/pull/450](https://github.com/jaredwray/airhorn/pull/450) * chore: upgrading xo to 1.0.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/451](https://github.com/jaredwray/airhorn/pull/451) * chore: upgrading vitest to 3.2.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/452](https://github.com/jaredwray/airhorn/pull/452) * chore: upgrading twilio to 5.7.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/453](https://github.com/jaredwray/airhorn/pull/453) * chore: upgrading tsup to 8.5.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/454](https://github.com/jaredwray/airhorn/pull/454) * chore: upgrading mongodb to 6.17.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/455](https://github.com/jaredwray/airhorn/pull/455) * chore: upgrading firebase-admin to 13.4.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/456](https://github.com/jaredwray/airhorn/pull/456) * chore: upgrading ecto to 4.2.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/457](https://github.com/jaredwray/airhorn/pull/457) * chore: upgrading docula to 0.12.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/458](https://github.com/jaredwray/airhorn/pull/458) * chore: upgrading aws-sdk to 3.825.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/459](https://github.com/jaredwray/airhorn/pull/459) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.1.6...v4.1.7](https://github.com/jaredwray/airhorn/compare/v4.1.6...v4.1.7) ### v4.1.6 URL: https://airhorn.org/changelog/v4-1-6 Date: May 6, 2025 Tag: Release ## What's Changed * chore: upgrading vitest to 3.1.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/440](https://github.com/jaredwray/airhorn/pull/440) * chore: upgrading twilio to 5.6.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/441](https://github.com/jaredwray/airhorn/pull/441) * chore: upgrading mongodb to 6.16.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/442](https://github.com/jaredwray/airhorn/pull/442) * chore: upgrading firebase-admin to 13.3.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/443](https://github.com/jaredwray/airhorn/pull/443) * chore: upgrading ecto to 4.2.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/444](https://github.com/jaredwray/airhorn/pull/444) * chore: upgrading docula to 0.11.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/445](https://github.com/jaredwray/airhorn/pull/445) * chore: upgrading cacheable to 1.9.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/446](https://github.com/jaredwray/airhorn/pull/446) * chore: upgrading axios to 1.9.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/447](https://github.com/jaredwray/airhorn/pull/447) * chore: upgrading @sendgrid/mail to 8.1.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/448](https://github.com/jaredwray/airhorn/pull/448) * chore: upgrading aws-sdk to 3.804.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/449](https://github.com/jaredwray/airhorn/pull/449) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.1.5...v4.1.6](https://github.com/jaredwray/airhorn/compare/v4.1.5...v4.1.6) ### v4.1.5 URL: https://airhorn.org/changelog/v4-1-5 Date: April 6, 2025 Tag: Release ## What's Changed * chore: upgrading typescript to 5.8.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/431](https://github.com/jaredwray/airhorn/pull/431) * chore: upgrading vitest to 3.1.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/432](https://github.com/jaredwray/airhorn/pull/432) * chore: upgrading twilio to 5.5.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/433](https://github.com/jaredwray/airhorn/pull/433) * chore: upgrading mongodb to 6.15.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/434](https://github.com/jaredwray/airhorn/pull/434) * chore: upgrading ecto to 4.2.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/435](https://github.com/jaredwray/airhorn/pull/435) * chore: upgrading docula to 0.11.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/436](https://github.com/jaredwray/airhorn/pull/436) * chore: upgrading cacheable to 1.8.10 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/437](https://github.com/jaredwray/airhorn/pull/437) * chore: upgrading axios to 1.8.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/438](https://github.com/jaredwray/airhorn/pull/438) * chore: upgrading aws-sdk to 3.782.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/439](https://github.com/jaredwray/airhorn/pull/439) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.1.4...v4.1.5](https://github.com/jaredwray/airhorn/compare/v4.1.4...v4.1.5) ### v4.1.4 URL: https://airhorn.org/changelog/v4-1-4 Date: March 6, 2025 Tag: Release ## What's Changed * chore: upgrading typescript and tsup to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/422](https://github.com/jaredwray/airhorn/pull/422) * chore: upgrading vitest to 3.0.8 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/423](https://github.com/jaredwray/airhorn/pull/423) * chore: upgrading twilio to 5.4.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/424](https://github.com/jaredwray/airhorn/pull/424) * chore: upgrading mongodb to 6.14.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/425](https://github.com/jaredwray/airhorn/pull/425) * chore: upgrading firebase-admin to 13.2.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/426](https://github.com/jaredwray/airhorn/pull/426) * chore: upgrading docula to 0.10.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/427](https://github.com/jaredwray/airhorn/pull/427) * chore: upgrading cacheable to 1.8.9 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/428](https://github.com/jaredwray/airhorn/pull/428) * chore: upgrading axios to 1.8.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/429](https://github.com/jaredwray/airhorn/pull/429) * chore: upgrading aws-sdk to 3.758.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/430](https://github.com/jaredwray/airhorn/pull/430) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.1.3...v4.1.4](https://github.com/jaredwray/airhorn/compare/v4.1.3...v4.1.4) ### v4.1.3 URL: https://airhorn.org/changelog/v4-1-3 Date: February 6, 2025 Tag: Release ## What's Changed * chore: upgrading vitest to 3.0.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/414](https://github.com/jaredwray/airhorn/pull/414) * chore: upgrading typescript and tsup to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/415](https://github.com/jaredwray/airhorn/pull/415) * chore: upgrading twilio to 5.4.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/416](https://github.com/jaredwray/airhorn/pull/416) * chore: upgrading mongodb to 6.13.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/417](https://github.com/jaredwray/airhorn/pull/417) * chore: upgrading ecto to 4.2.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/418](https://github.com/jaredwray/airhorn/pull/418) * chore: upgrading docula to 0.10.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/419](https://github.com/jaredwray/airhorn/pull/419) * chore: upgrading cacheable to 1.8.8 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/420](https://github.com/jaredwray/airhorn/pull/420) * chore: upgrading aws sdk to 3.741.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/421](https://github.com/jaredwray/airhorn/pull/421) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.1.2...v4.1.3](https://github.com/jaredwray/airhorn/compare/v4.1.2...v4.1.3) ### v4.1.2 URL: https://airhorn.org/changelog/v4-1-2 Date: January 5, 2025 Tag: Release ## What's Changed * chore: updating all workflows to use pnpm by @jaredwray in [https://github.com/jaredwray/airhorn/pull/405](https://github.com/jaredwray/airhorn/pull/405) * chore: upgrading twilio to 5.4.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/406](https://github.com/jaredwray/airhorn/pull/406) * chore: upgrading mongodb to 6.12.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/407](https://github.com/jaredwray/airhorn/pull/407) * chore: upgrading firebase-admin to 13.0.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/408](https://github.com/jaredwray/airhorn/pull/408) * chore: upgrading ecto to 4.1.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/409](https://github.com/jaredwray/airhorn/pull/409) * chore: upgrading docula to 0.9.6 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/410](https://github.com/jaredwray/airhorn/pull/410) * chore: upgrading cacheable to 1.8.7 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/411](https://github.com/jaredwray/airhorn/pull/411) * chore: upgrading aws-sdk to 3.721.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/412](https://github.com/jaredwray/airhorn/pull/412) * feat: adding in jsDoc by @jaredwray in [https://github.com/jaredwray/airhorn/pull/413](https://github.com/jaredwray/airhorn/pull/413) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.1.1...v4.1.2](https://github.com/jaredwray/airhorn/compare/v4.1.1...v4.1.2) ### v4.1.1 URL: https://airhorn.org/changelog/v4-1-1 Date: December 6, 2024 Tag: Release ## What's Changed * upgrading xo to 0.60.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/395](https://github.com/jaredwray/airhorn/pull/395) * upgrading vitest to 2.1.8 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/396](https://github.com/jaredwray/airhorn/pull/396) * upgrading twilio to 5.3.7 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/397](https://github.com/jaredwray/airhorn/pull/397) * upgrading ecto to 4.1.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/398](https://github.com/jaredwray/airhorn/pull/398) * upgrading axios to 1.7.9 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/399](https://github.com/jaredwray/airhorn/pull/399) * fixing object curly spacing to xo fix by @jaredwray in [https://github.com/jaredwray/airhorn/pull/400](https://github.com/jaredwray/airhorn/pull/400) * fixing linting on parameter properties by @jaredwray in [https://github.com/jaredwray/airhorn/pull/401](https://github.com/jaredwray/airhorn/pull/401) * removing typescript-eslint/no-unsafe-call as not needed by @jaredwray in [https://github.com/jaredwray/airhorn/pull/402](https://github.com/jaredwray/airhorn/pull/402) * removing global typescript-eslint/no-unsafe-assignment on lint by @jaredwray in [https://github.com/jaredwray/airhorn/pull/403](https://github.com/jaredwray/airhorn/pull/403) * removing global lint rules that do nothing by @jaredwray in [https://github.com/jaredwray/airhorn/pull/404](https://github.com/jaredwray/airhorn/pull/404) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.1.0...v4.1.1](https://github.com/jaredwray/airhorn/compare/v4.1.0...v4.1.1) ### v4.1.0 URL: https://airhorn.org/changelog/v4-1-0 Date: November 29, 2024 Tag: Release ## What's Changed * moving to mockhttp.org for testing webhooks by @jaredwray in [https://github.com/jaredwray/airhorn/pull/380](https://github.com/jaredwray/airhorn/pull/380) * updating typescript and packing modules to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/381](https://github.com/jaredwray/airhorn/pull/381) * upgrading vitest to 2.1.6 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/382](https://github.com/jaredwray/airhorn/pull/382) * upgrading docula to 0.9.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/383](https://github.com/jaredwray/airhorn/pull/383) * upgrading twilio to 5.3.6 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/384](https://github.com/jaredwray/airhorn/pull/384) * upgrading mongodb to 6.11.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/385](https://github.com/jaredwray/airhorn/pull/385) * upgrading cacheable to 1.8.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/386](https://github.com/jaredwray/airhorn/pull/386) * upgrading axios to 1.7.8 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/387](https://github.com/jaredwray/airhorn/pull/387) * upgrading @sendgrid/mail to 8.1.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/388](https://github.com/jaredwray/airhorn/pull/388) * upgrading firebase-admin to 13.0.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/389](https://github.com/jaredwray/airhorn/pull/389) * upgrading aws-sdk to 3.699.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/390](https://github.com/jaredwray/airhorn/pull/390) * moving to createAirhorn with templates being loaded by @jaredwray in [https://github.com/jaredwray/airhorn/pull/391](https://github.com/jaredwray/airhorn/pull/391) * migration to template service with providers by @jaredwray in [https://github.com/jaredwray/airhorn/pull/392](https://github.com/jaredwray/airhorn/pull/392) * upgrading @types/node to 22.10.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/393](https://github.com/jaredwray/airhorn/pull/393) * updating the readme and adding in by @jaredwray in [https://github.com/jaredwray/airhorn/pull/394](https://github.com/jaredwray/airhorn/pull/394) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v4.0.0...v4.1.0](https://github.com/jaredwray/airhorn/compare/v4.0.0...v4.1.0) ### v4.0.0 URL: https://airhorn.org/changelog/v4-0-0 Date: November 22, 2024 Tag: Release ## What's Changed * Updating licensing and copyright and docula by @jaredwray in [https://github.com/jaredwray/airhorn/pull/374](https://github.com/jaredwray/airhorn/pull/374) * upgrading docula to 0.9.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/375](https://github.com/jaredwray/airhorn/pull/375) * Removing queue and logger by @jaredwray in [https://github.com/jaredwray/airhorn/pull/376](https://github.com/jaredwray/airhorn/pull/376) * removing horizontal logo as not needed by @jaredwray in [https://github.com/jaredwray/airhorn/pull/377](https://github.com/jaredwray/airhorn/pull/377) * fixing docula issue by @jaredwray in [https://github.com/jaredwray/airhorn/pull/378](https://github.com/jaredwray/airhorn/pull/378) * Moving to in memory template for library with file system loading by @jaredwray in [https://github.com/jaredwray/airhorn/pull/379](https://github.com/jaredwray/airhorn/pull/379) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v3.1.0...v4.0.0](https://github.com/jaredwray/airhorn/compare/v3.1.0...v4.0.0) ### v3.1.0 URL: https://airhorn.org/changelog/v3-1-0 Date: October 6, 2024 Tag: Release ## What's Changed * upgrading xo to 0.59.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/326](https://github.com/jaredwray/airhorn/pull/326) * upgrading wepback and typescript to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/327](https://github.com/jaredwray/airhorn/pull/327) * removing winston for standard logging by @jaredwray in [https://github.com/jaredwray/airhorn/pull/328](https://github.com/jaredwray/airhorn/pull/328) * migrating to nodejs 20 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/329](https://github.com/jaredwray/airhorn/pull/329) * upgrading vitest to 2.0.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/330](https://github.com/jaredwray/airhorn/pull/330) * upgrading rimraf to 6.0.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/331](https://github.com/jaredwray/airhorn/pull/331) * upgrading firebase-admin to 12.3.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/332](https://github.com/jaredwray/airhorn/pull/332) * upgrading ecto to 3.0.8 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/333](https://github.com/jaredwray/airhorn/pull/333) * upgrading axios to 1.7.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/334](https://github.com/jaredwray/airhorn/pull/334) * upgrading docula to 0.7.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/335](https://github.com/jaredwray/airhorn/pull/335) * upgrading aws-sdk to 3.623.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/336](https://github.com/jaredwray/airhorn/pull/336) * upgrading firebase-admin to 12.3.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/337](https://github.com/jaredwray/airhorn/pull/337) * upgrading aws-sdk to 3.629.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/338](https://github.com/jaredwray/airhorn/pull/338) * Adding in airhorn store by @jaredwray in [https://github.com/jaredwray/airhorn/pull/339](https://github.com/jaredwray/airhorn/pull/339) * updating workflows and dist locations by @jaredwray in [https://github.com/jaredwray/airhorn/pull/340](https://github.com/jaredwray/airhorn/pull/340) * upgrading docula to 0.8.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/341](https://github.com/jaredwray/airhorn/pull/341) * upgrading axios to 1.7.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/342](https://github.com/jaredwray/airhorn/pull/342) * upgrading aws-sdk to 3.631.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/343](https://github.com/jaredwray/airhorn/pull/343) * moving ProviderType to AirhornProviderType by @jaredwray in [https://github.com/jaredwray/airhorn/pull/344](https://github.com/jaredwray/airhorn/pull/344) * Airhorn store with notifications and subscriptions by @jaredwray in [https://github.com/jaredwray/airhorn/pull/345](https://github.com/jaredwray/airhorn/pull/345) * upgrading docula to 0.9.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/346](https://github.com/jaredwray/airhorn/pull/346) * upgrading axios to 1.7.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/347](https://github.com/jaredwray/airhorn/pull/347) * upgrading firebase-admin to 12.4.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/348](https://github.com/jaredwray/airhorn/pull/348) * fixing logo spacing and sizing by @jaredwray in [https://github.com/jaredwray/airhorn/pull/349](https://github.com/jaredwray/airhorn/pull/349) * airhorn store crud methods for subscription and notification by @jaredwray in [https://github.com/jaredwray/airhorn/pull/350](https://github.com/jaredwray/airhorn/pull/350) * updating store file paths by @jaredwray in [https://github.com/jaredwray/airhorn/pull/351](https://github.com/jaredwray/airhorn/pull/351) * breaking out files for better organization by @jaredwray in [https://github.com/jaredwray/airhorn/pull/352](https://github.com/jaredwray/airhorn/pull/352) * Airhorn queue by @jaredwray in [https://github.com/jaredwray/airhorn/pull/353](https://github.com/jaredwray/airhorn/pull/353) * upgrading twilio to 5.2.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/354](https://github.com/jaredwray/airhorn/pull/354) * upgrading ecto to 4.0.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/355](https://github.com/jaredwray/airhorn/pull/355) * upgrading axios to 1.7.7 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/356](https://github.com/jaredwray/airhorn/pull/356) * upgrading aws-sdk to 3.637.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/357](https://github.com/jaredwray/airhorn/pull/357) * fixing webhook to use local only by @jaredwray in [https://github.com/jaredwray/airhorn/pull/358](https://github.com/jaredwray/airhorn/pull/358) * removing env and dotenv requirement by @jaredwray in [https://github.com/jaredwray/airhorn/pull/359](https://github.com/jaredwray/airhorn/pull/359) * moving to AirhornOptions type by @jaredwray in [https://github.com/jaredwray/airhorn/pull/360](https://github.com/jaredwray/airhorn/pull/360) * airhorn subscription functions and store by @jaredwray in [https://github.com/jaredwray/airhorn/pull/361](https://github.com/jaredwray/airhorn/pull/361) * google pub/sub updates and fixes by @jaredwray in [https://github.com/jaredwray/airhorn/pull/362](https://github.com/jaredwray/airhorn/pull/362) * moving to cjs and esm via tsup by @jaredwray in [https://github.com/jaredwray/airhorn/pull/363](https://github.com/jaredwray/airhorn/pull/363) * removing google pubsub and adding nodejs 22 testing by @jaredwray in [https://github.com/jaredwray/airhorn/pull/364](https://github.com/jaredwray/airhorn/pull/364) * upgrading vitest, typescript, and tsup to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/365](https://github.com/jaredwray/airhorn/pull/365) * upgrading twilio to 5.3.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/366](https://github.com/jaredwray/airhorn/pull/366) * upgrading mongodb to 6.9.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/367](https://github.com/jaredwray/airhorn/pull/367) * upgrading docula to 0.9.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/368](https://github.com/jaredwray/airhorn/pull/368) * upgrading ecto to 4.1.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/369](https://github.com/jaredwray/airhorn/pull/369) * upgrading vitest to 2.1.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/370](https://github.com/jaredwray/airhorn/pull/370) * Upgrading twilio to 5.3.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/371](https://github.com/jaredwray/airhorn/pull/371) * upgrading firebase-admin to 12.6.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/372](https://github.com/jaredwray/airhorn/pull/372) * upgrading aws-sdk to 3.665.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/373](https://github.com/jaredwray/airhorn/pull/373) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v3.0.4...v3.1.0](https://github.com/jaredwray/airhorn/compare/v3.0.4...v3.1.0) ### v3.0.4 URL: https://airhorn.org/changelog/v3-0-4 Date: July 7, 2024 Tag: Release ## What's Changed * upgrading typescript webpack and types to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/318](https://github.com/jaredwray/airhorn/pull/318) * upgrading twilio to 5.2.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/319](https://github.com/jaredwray/airhorn/pull/319) * upgrading rimraf to 5.0.8 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/320](https://github.com/jaredwray/airhorn/pull/320) * upgrading firebase-admin to 12.2.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/321](https://github.com/jaredwray/airhorn/pull/321) * upgrading ecto to 3.0.6 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/322](https://github.com/jaredwray/airhorn/pull/322) * upgrading aws sdk to 3.609.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/324](https://github.com/jaredwray/airhorn/pull/324) * updating github actions with workflow_dispatch by @jaredwray in [https://github.com/jaredwray/airhorn/pull/325](https://github.com/jaredwray/airhorn/pull/325) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v3.0.3...v3.0.4](https://github.com/jaredwray/airhorn/compare/v3.0.3...v3.0.4) ### v3.0.3 URL: https://airhorn.org/changelog/v3-0-3 Date: June 6, 2024 Tag: Release ## What's Changed * upgrading twilio to 5.1.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/311](https://github.com/jaredwray/airhorn/pull/311) * removing eslint and modules by @jaredwray in [https://github.com/jaredwray/airhorn/pull/312](https://github.com/jaredwray/airhorn/pull/312) * upgrading firebase-admin to 12.1.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/313](https://github.com/jaredwray/airhorn/pull/313) * upgrading ecto to 3.0.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/314](https://github.com/jaredwray/airhorn/pull/314) * upgrading docula to 0.5.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/315](https://github.com/jaredwray/airhorn/pull/315) * upgrading axios to 1.7.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/316](https://github.com/jaredwray/airhorn/pull/316) * upgrading aws-sdk to 3.590.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/317](https://github.com/jaredwray/airhorn/pull/317) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v3.0.2...v3.0.3](https://github.com/jaredwray/airhorn/compare/v3.0.2...v3.0.3) ### v3.0.2 URL: https://airhorn.org/changelog/v3-0-2 Date: May 6, 2024 Tag: Release ## What's Changed * upgrading vitest to 1.6.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/302](https://github.com/jaredwray/airhorn/pull/302) * upgrading typescript to 5.4.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/304](https://github.com/jaredwray/airhorn/pull/304) * upgrading @typescript-eslint/eslint-plugin and modules to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/305](https://github.com/jaredwray/airhorn/pull/305) * upgrading twilio to 5.0.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/306](https://github.com/jaredwray/airhorn/pull/306) * upgrading firebase-admin to 12.1.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/307](https://github.com/jaredwray/airhorn/pull/307) * upgrading ecto to 3.0.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/308](https://github.com/jaredwray/airhorn/pull/308) * upgrading docula to 0.5.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/309](https://github.com/jaredwray/airhorn/pull/309) * upgrading aws-sdk to 3.569.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/310](https://github.com/jaredwray/airhorn/pull/310) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v3.0.1...v3.0.2](https://github.com/jaredwray/airhorn/compare/v3.0.1...v3.0.2) ### v3.0.1 URL: https://airhorn.org/changelog/v3-0-1 Date: April 6, 2024 Tag: Release ## What's Changed * updating setup node actions to v3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/291](https://github.com/jaredwray/airhorn/pull/291) * upgrading xo to 0.58.0 and eslint to 9.0.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/292](https://github.com/jaredwray/airhorn/pull/292) * upgrading winston to 3.13.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/293](https://github.com/jaredwray/airhorn/pull/293) * upgrading webpack, typescript, and @types/node to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/294](https://github.com/jaredwray/airhorn/pull/294) * upgrading vitest to 1.4.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/295](https://github.com/jaredwray/airhorn/pull/295) * upgrading twilio to 5.0.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/296](https://github.com/jaredwray/airhorn/pull/296) * upgrading ecto to 3.0.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/297](https://github.com/jaredwray/airhorn/pull/297) * upgrading docula to 0.5.2 and site to be deployed to airhorn.org by @jaredwray in [https://github.com/jaredwray/airhorn/pull/298](https://github.com/jaredwray/airhorn/pull/298) * upgrading axios to 1.6.8 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/299](https://github.com/jaredwray/airhorn/pull/299) * upgrading @sendgrid/mail to 8.1.3 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/300](https://github.com/jaredwray/airhorn/pull/300) * upgrading aws sdk to 3.549.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/301](https://github.com/jaredwray/airhorn/pull/301) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v3.0.0...v3.0.1](https://github.com/jaredwray/airhorn/compare/v3.0.0...v3.0.1) ### v3.0.0 URL: https://airhorn.org/changelog/v3-0-0 Date: March 7, 2024 Tag: Release # Migration to ESM and Nodejs 18+ Support This as a major upgrade moving the library to nodejs 18 and also ESM. ## What's Changed * Migrating to ESM (adding in npm, vitest, and nodejs version 18+ support) by @jaredwray in [https://github.com/jaredwray/airhorn/pull/285](https://github.com/jaredwray/airhorn/pull/285) * upgrading webpack, typescript, and winston to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/286](https://github.com/jaredwray/airhorn/pull/286) * upgrading twilio to 4.23.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/287](https://github.com/jaredwray/airhorn/pull/287) * upgrading @sendgrid/mail to 8.1.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/288](https://github.com/jaredwray/airhorn/pull/288) * upgrading aws-sdk to 3.525.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/289](https://github.com/jaredwray/airhorn/pull/289) * upgrading eslint to 8.57.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/290](https://github.com/jaredwray/airhorn/pull/290) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v2.0.6...v3.0.0](https://github.com/jaredwray/airhorn/compare/v2.0.6...v3.0.0) ### v2.0.6 URL: https://airhorn.org/changelog/v2-0-6 Date: February 8, 2024 Tag: Release ## What's Changed * Deploy airhorn.org by @jaredwray in [https://github.com/jaredwray/airhorn/pull/282](https://github.com/jaredwray/airhorn/pull/282) * upgrading ecto to 2.4.2 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/283](https://github.com/jaredwray/airhorn/pull/283) * upgrading aws-sdk to 3.509.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/284](https://github.com/jaredwray/airhorn/pull/284) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v2.0.5...v2.0.6](https://github.com/jaredwray/airhorn/compare/v2.0.5...v2.0.6) ### v2.0.5 URL: https://airhorn.org/changelog/v2-0-5 Date: February 6, 2024 Tag: Release ## What's Changed * Upgrading xo to 0.57.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/275](https://github.com/jaredwray/airhorn/pull/275) * upgrading ts-jest to 29.1.2 and webpack to 5.90.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/276](https://github.com/jaredwray/airhorn/pull/276) * upgrading dotenv to 16.4.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/277](https://github.com/jaredwray/airhorn/pull/277) * upgrading twilio to 4.21.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/278](https://github.com/jaredwray/airhorn/pull/278) * upgrading axios to 1.6.7 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/279](https://github.com/jaredwray/airhorn/pull/279) * upgrading ecto to 2.4.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/280](https://github.com/jaredwray/airhorn/pull/280) * upgrading awssdk to 3.507.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/281](https://github.com/jaredwray/airhorn/pull/281) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v2.0.4...v2.0.5](https://github.com/jaredwray/airhorn/compare/v2.0.4...v2.0.5) ### v2.0.4 URL: https://airhorn.org/changelog/v2-0-4 Date: January 6, 2024 Tag: Release ## What's Changed * upgrading eslint to 8.56.0 and modules to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/269](https://github.com/jaredwray/airhorn/pull/269) * upgrading twilio to 4.20.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/270](https://github.com/jaredwray/airhorn/pull/270) * upgrading ecto to 2.2.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/271](https://github.com/jaredwray/airhorn/pull/271) * upgrading axios to 1.6.5 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/272](https://github.com/jaredwray/airhorn/pull/272) * upgrading @aws-sdk modules to 3.485.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/273](https://github.com/jaredwray/airhorn/pull/273) * upgrading firebase-admin to 12.0.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/274](https://github.com/jaredwray/airhorn/pull/274) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v2.0.3...v2.0.4](https://github.com/jaredwray/airhorn/compare/v2.0.3...v2.0.4) ### v2.0.3 URL: https://airhorn.org/changelog/v2-0-3 Date: December 6, 2023 Tag: Release ## What's Changed * migrating to axios from got by @jaredwray in [https://github.com/jaredwray/airhorn/pull/261](https://github.com/jaredwray/airhorn/pull/261) * upgrading twilio and sendgrid to latest versions by @jaredwray in [https://github.com/jaredwray/airhorn/pull/262](https://github.com/jaredwray/airhorn/pull/262) * upgrading fs-extra to 11.2.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/263](https://github.com/jaredwray/airhorn/pull/263) * upgrading eslint and typescript to latest by @jaredwray in [https://github.com/jaredwray/airhorn/pull/264](https://github.com/jaredwray/airhorn/pull/264) * upgrading firebase-admin to 11.11.1 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/265](https://github.com/jaredwray/airhorn/pull/265) * upgrading ecto to 2.2.4 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/266](https://github.com/jaredwray/airhorn/pull/266) * upgrading aws-sdk to 3.465.0 by @jaredwray in [https://github.com/jaredwray/airhorn/pull/267](https://github.com/jaredwray/airhorn/pull/267) * fixing package scripts to be more compatible by @jaredwray in [https://github.com/jaredwray/airhorn/pull/268](https://github.com/jaredwray/airhorn/pull/268) **Full Changelog**: [https://github.com/jaredwray/airhorn/compare/v2.0.2...v2.0.3](https://github.com/jaredwray/airhorn/compare/v2.0.2...v2.0.3)