Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Remix #1313

Closed
justinfarrelldev opened this issue Aug 9, 2024 · 7 comments · Fixed by #1866 or #1830
Closed

Support for Remix #1313

justinfarrelldev opened this issue Aug 9, 2024 · 7 comments · Fixed by #1866 or #1830
Assignees

Comments

@justinfarrelldev
Copy link

Hello, I see that this project has Next.js support, however it is unclear whether Remix support is in the works or works out-of-the-box for the Next.js package. Are there perhaps any plans to include Remix (or, I guess since it is being merged with React Router, React Router) support?

Thank you, and I love this project so far! I can tell this will be extremely useful when I develop APIs in the future.

@davidmytton
Copy link
Contributor

davidmytton commented Aug 9, 2024

Hi @justinfarrelldev! We don't have official Remix support yet, but Arcjet will work and we know of several people using it without any issues. However, support depends on which Remix adapter you're using - Arcjet will work with the default Remix server (which uses Express) and also with Node or Vercel.

I just tested using our Node SDK in a Remix loader function and it worked correctly. There is a type-mismatch warning when you pass the request parameter into aj.project() but you can ignore it.

This uses https://github.com/sergiodxa/remix-utils#getclientipaddress to get the IP address, which is installed with:

npm install remix-utils is-ip

Then you can manually construct the request props with the IP included:

import arcjet, { tokenBucket } from "@arcjet/node";
import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
import { getClientIPAddress } from "remix-utils/get-client-ip-address";

const aj = arcjet({
  key: process.env.ARCJET_KEY!, // Get your site key from https://app.arcjet.com
  characteristics: ["userId"], // track requests by a custom user ID
  rules: [
    // Create a token bucket rate limit. Other algorithms are supported.
    tokenBucket({
      mode: "LIVE", // will block requests. Use "DRY_RUN" to log only
      refillRate: 5, // refill 5 tokens per interval
      interval: 10, // refill every 10 seconds
      capacity: 10, // bucket maximum capacity of 10 tokens
    }),
  ],
});

export async function loader({
  request,
}: LoaderFunctionArgs) {
  // Construct an object with Arcjet request details
  const path = new URL(request.url || "", `http://${request.headers.get("host")}`);
  const details = {
    ip: getClientIPAddress(request),
    method: request.method,
    host: request.headers.get("host"),
    url: path.pathname,
    headers: request.headers,
  };

  const userId = "user123"; // Replace with your authenticated user ID
  const decision = await aj.protect(details, { userId, requested: 5 }); // Deduct 5 tokens from the bucket
  console.log("Arcjet decision", decision);

  if (decision.isDenied()) {
    throw new Response("Too many requests", {
      status: 429,
    });
  } else {
    return null;
  }
}

...

If you create a custom express server for Remix, then you can also put Arcjet in there e.g. for running Shield on every request as middleware. See #1313 (comment)

@justinfarrelldev
Copy link
Author

Hi @justinfarrelldev! We don't have official Remix support yet, but Arcjet will work and we know of several people using it without any issues. However, support depends on which Remix adapter you're using - Arcjet will work with the default Remix server (which uses Express) and also with Node or Vercel.

I just tested using our Node SDK in a Remix loader function and it worked correctly. There is a type-mismatch warning when you pass the request parameter into aj.project() but you can ignore it.

import arcjet, { tokenBucket } from "@arcjet/node";
import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/node";

const aj = arcjet({
  key: process.env.ARCJET_KEY!, // Get your site key from https://app.arcjet.com
  characteristics: ["userId"], // track requests by a custom user ID
  rules: [
    // Create a token bucket rate limit. Other algorithms are supported.
    tokenBucket({
      mode: "LIVE", // will block requests. Use "DRY_RUN" to log only
      refillRate: 5, // refill 5 tokens per interval
      interval: 10, // refill every 10 seconds
      capacity: 10, // bucket maximum capacity of 10 tokens
    }),
  ],
});

export async function loader({
  request,
}: LoaderFunctionArgs) {
  const userId = "user123"; // Replace with your authenticated user ID
  const decision = await aj.protect(request, { userId, requested: 5 }); // Deduct 5 tokens from the bucket
  console.log("Arcjet decision", decision);

  if (decision.isDenied()) {
    throw new Response("Too many requests", {
      status: 429,
    });
  } else {
    return null;
  }
}

...

If you create a custom express server for Remix, then you can also put Arcjet in there e.g. for running Shield on every request. We have an example with a generic Express server at https://github.com/arcjet/arcjet-js/blob/main/examples/nodejs-express-rl/index.js

Awesome, thank you so much for the extremely thorough reply! I'll definitely give it a go 😁

@davidmytton
Copy link
Contributor

On testing this in production, Remix doesn't actually provide the IP - when you use Arcjet locally it's using a local IP.

From the discussion at remix-run/remix#2413 the suggestion is to use a utility from https://github.com/sergiodxa/remix-utils#getclientipaddress to get the IP address. We'll look at how we can do this for you in our official SDK, but for now I've adjusted the above code sample (#1313 (comment)) to use it.

@davidmytton
Copy link
Contributor

To provide an example using Remix + Express middleware, you can use this server.js from the Remix quick start with Arcjet added:

import arcjet, { shield } from "@arcjet/node";
import { createRequestHandler } from "@remix-run/express";
import express from "express";

// notice that the result of `remix vite:build` is "just a module"
import * as build from "./build/server/index.js";

const aj = arcjet({
    // Get your site key from https://app.arcjet.com and set it as an environment
    // variable rather than hard coding.
    key: process.env.ARCJET_KEY,
    rules: [
        // Protect against common attacks with Arcjet Shield
        shield({
            mode: "LIVE", // will block requests. Use "DRY_RUN" to log only
        }),
    ],
});

const app = express();
app.use(express.static("build/client"));

app.use(async (req, res, next) => {
    const decision = await aj.protect(req);

    if (decision.isDenied()) {
        res.writeHead(403, { "Content-Type": "application/json" });
        res.end(JSON.stringify({ error: "Forbidden" }));
    } else {
        next()
    }
})

// and your app is "just a request handler"
app.all("*", createRequestHandler({ build }));

app.listen(3000, () => {
    console.log("App listening on http://localhost:3000");
});

Running it requires you set ARCJET_ENV and ARCJET_KEY locally, which you can do in a .env file:

# This file is for local development
# In production, only set the ARCJET_KEY
ARCJET_ENV=development
# Get your site key from https://app.arcjet.com
ARCJET_KEY=KEYHERE

Starting it can be done with these scripts in package.json

"scripts": {
    "build": "remix vite:build",
    "dev": "node --env-file .env ./server.js",
    "start": "cross-env NODE_ENV=production node ./server.js"
  },

Then you can use Remix normally.

@blaine-arcjet
Copy link
Contributor

I was just looking into what it will take to support remix and I noticed @davidmytton suggested the remix-utils package, which is actually just a worse version of our @arcjet/ip package since it only reads from headers.

While we can depend upon our @arcjet/ip package, I'd prefer if we could get the connecting IP from the connection so we might need to have a more involved setup for the SDK.

@blaine-arcjet blaine-arcjet self-assigned this Sep 27, 2024
@blaine-arcjet
Copy link
Contributor

My current thoughts are that we'll provide an API that users assign to getLoadContext that attaches the IP from Express/Deno/etc and then we access the context via the argument passed to loader or action handlers.

@blaine-arcjet
Copy link
Contributor

I just submitted remix-run/remix#10042 to add Deno's ServeHandlerInfo to the getLoadContext function. We will need this if we want to support Remix via Deno.serve

@trunk-io trunk-io bot closed this as completed in #1866 Oct 15, 2024
trunk-io bot pushed a commit that referenced this issue Oct 15, 2024
This adds a Remix adapter.

We provide a special `getLoadContext` export which is demonstrated in the example application. It currently looks up the IP from an Express or Deno server, but we're waiting on remix-run/remix#10042 before their Deno plugin will provide the argument we need.

Closes #1313
trunk-io bot pushed a commit that referenced this issue Oct 23, 2024
Automatically generated with [Release Please](https://github.com/googleapis/release-please).
---


<details><summary>@arcjet/analyze: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/analyze-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* Return ERROR decision when fingerprint cannot be generated ([#1990](#1990))
* **analyze:** improve sensitive info string token accuracy ([#1962](#1962))
* Update Wasm with phone-number fix and tokenizer update ([#1854](#1854))

### 🚀 New Features

* **analyze:** improve sensitive info string token accuracy ([#1962](#1962)) ([abad1bd](abad1bd))


### 🪲 Bug Fixes

* Return ERROR decision when fingerprint cannot be generated ([#1990](#1990)) ([618a1ee](618a1ee)), closes [#1801](#1801)
* Update Wasm with phone-number fix and tokenizer update ([#1854](#1854)) ([f94f078](f94f078))


### 🧹 Miscellaneous Chores

* **analyze:** Regenerate Wasm with updated dependencies ([#2067](#2067)) ([f96994c](f96994c))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/protocol bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/body: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/body-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/body:** Synchronize arcjet-js versions


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/bun: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/bun-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018))

### 🚀 New Features

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018)) ([1704da8](1704da8)), closes [#1904](#1904)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/env bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/headers bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/ip bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/logger bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/protocol bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/transport bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * arcjet bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/decorate: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/decorate-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/decorate:** Synchronize arcjet-js versions


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/protocol bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/sprintf bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/deno: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/deno-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018))

### 🚀 New Features

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018)) ([1704da8](1704da8)), closes [#1904](#1904)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/env bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/headers bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/ip bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/logger bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/protocol bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/transport bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * arcjet bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/duration: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/duration-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/duration:** Synchronize arcjet-js versions


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/env: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/env-v1.0.0-alpha.28) (2024-10-23)


### 🚀 New Features

* **ip:** Add Vercel platform-specific IP header detection ([#2022](#2022)) ([d886c76](d886c76))


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/eslint-config: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/eslint-config-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/eslint-config:** Synchronize arcjet-js versions
</details>

<details><summary>@arcjet/headers: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/headers-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/headers:** Synchronize arcjet-js versions


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/ip: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/ip-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018))
* **ip:** Exit early if platform-specific headers are missing IP ([#2021](#2021))

### 🚀 New Features

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018)) ([1704da8](1704da8)), closes [#1904](#1904)
* **ip:** Add Vercel platform-specific IP header detection ([#2022](#2022)) ([d886c76](d886c76))


### 🪲 Bug Fixes

* **ip:** Exit early if platform-specific headers are missing IP ([#2021](#2021)) ([1a13d9c](1a13d9c))


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/logger: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/logger-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* Ensure performance metrics are scoped to same call ([#2019](#2019))

### 🪲 Bug Fixes

* Ensure performance metrics are scoped to same call ([#2019](#2019)) ([e9f869c](e9f869c)), closes [#1865](#1865)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/sprintf bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/nest: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/nest-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018))

### 🚀 New Features

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018)) ([1704da8](1704da8)), closes [#1904](#1904)


### 🪲 Bug Fixes

* **nestjs:** Lookup request from GraphQL context in ArcjetGuard ([#1857](#1857)) ([c0b2903](c0b2903)), closes [#1856](#1856)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/env bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/headers bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/ip bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/logger bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/protocol bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/transport bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/body bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * arcjet bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/next: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/next-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018))

### 🚀 New Features

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018)) ([1704da8](1704da8)), closes [#1904](#1904)
* **nextjs:** Support Next.js Server Actions ([#1991](#1991)) ([07e68dc](07e68dc)), closes [#1200](#1200)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/env bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/headers bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/ip bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/logger bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/protocol bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/transport bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * arcjet bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/node: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/node-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018))

### 🚀 New Features

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018)) ([1704da8](1704da8)), closes [#1904](#1904)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/env bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/headers bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/ip bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/logger bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/protocol bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/transport bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/body bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * arcjet bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/protocol: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/protocol-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* Ensure performance metrics are scoped to same call ([#2019](#2019))
* **protocol:** Remove received_at and decision fields from Report ([#1988](#1988))
* Remove `match` option from rate limit rules ([#1815](#1815))

### 🚀 New Features

* Add Remix adapter ([#1866](#1866)) ([32d6d41](32d6d41)), closes [#1313](#1313)
* Use `waitUntil` for Report call if available ([#1838](#1838)) ([2851021](2851021)), closes [#884](#884)


### 🪲 Bug Fixes

* Ensure performance metrics are scoped to same call ([#2019](#2019)) ([e9f869c](e9f869c)), closes [#1865](#1865)


### 🧹 Miscellaneous Chores

* **protocol:** Remove received_at and decision fields from Report ([#1988](#1988)) ([3da543e](3da543e))
* Remove `match` option from rate limit rules ([#1815](#1815)) ([853119d](853119d)), closes [#1810](#1810)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/redact: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/redact-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/redact:** Synchronize arcjet-js versions


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/redact-wasm bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/redact-wasm: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/redact-wasm-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* Return ERROR decision when fingerprint cannot be generated ([#1990](#1990))
* **analyze:** improve sensitive info string token accuracy ([#1962](#1962))
* Update Wasm with phone-number fix and tokenizer update ([#1854](#1854))

### 🚀 New Features

* **analyze:** improve sensitive info string token accuracy ([#1962](#1962)) ([abad1bd](abad1bd))


### 🪲 Bug Fixes

* Return ERROR decision when fingerprint cannot be generated ([#1990](#1990)) ([618a1ee](618a1ee)), closes [#1801](#1801)
* Update Wasm with phone-number fix and tokenizer update ([#1854](#1854)) ([f94f078](f94f078))


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/remix: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/remix-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018))

### 🚀 New Features

* Add Remix adapter ([#1866](#1866)) ([32d6d41](32d6d41)), closes [#1313](#1313)
* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018)) ([1704da8](1704da8)), closes [#1904](#1904)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/env bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/headers bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/ip bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/logger bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/protocol bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/transport bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * arcjet bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/rollup-config: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/rollup-config-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/rollup-config:** Synchronize arcjet-js versions


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/runtime: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/runtime-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/runtime:** Synchronize arcjet-js versions


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/sprintf: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/sprintf-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/sprintf:** Synchronize arcjet-js versions


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/sveltekit: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/sveltekit-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018))

### 🚀 New Features

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018)) ([1704da8](1704da8)), closes [#1904](#1904)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/env bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/headers bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/ip bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/logger bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/protocol bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/transport bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * arcjet bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/transport: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/transport-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/transport:** Synchronize arcjet-js versions


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>@arcjet/tsconfig: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](https://github.com/arcjet/arcjet-js/compare/v1.0.0-alpha.27...@arcjet/tsconfig-v1.0.0-alpha.28) (2024-10-23)


### 🧹 Miscellaneous Chores

* **@arcjet/tsconfig:** Synchronize arcjet-js versions
</details>

<details><summary>arcjet: 1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](v1.0.0-alpha.27...arcjet-v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* Ensure performance metrics are scoped to same call ([#2019](#2019))
* Return ERROR decision when fingerprint cannot be generated ([#1990](#1990))
* Remove `match` option from rate limit rules ([#1815](#1815))

### 🚀 New Features

* Use `waitUntil` for Report call if available ([#1838](#1838)) ([2851021](2851021)), closes [#884](#884)


### 🪲 Bug Fixes

* **arcjet:** Ensure performance measurements are 1-to-1 and always captured ([#1858](#1858)) ([4d29f9a](4d29f9a))
* Ensure performance metrics are scoped to same call ([#2019](#2019)) ([e9f869c](e9f869c)), closes [#1865](#1865)
* Return ERROR decision when fingerprint cannot be generated ([#1990](#1990)) ([618a1ee](618a1ee)), closes [#1801](#1801)


### 🧹 Miscellaneous Chores

* Remove `match` option from rate limit rules ([#1815](#1815)) ([853119d](853119d)), closes [#1810](#1810)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @arcjet/analyze bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/duration bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/headers bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/protocol bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/runtime bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
  * devDependencies
    * @arcjet/eslint-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/rollup-config bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
    * @arcjet/tsconfig bumped from 1.0.0-alpha.27 to 1.0.0-alpha.28
</details>

<details><summary>1.0.0-alpha.28</summary>

## [1.0.0-alpha.28](v1.0.0-alpha.27...v1.0.0-alpha.28) (2024-10-23)


### ⚠ BREAKING CHANGES

* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018))
* **ip:** Exit early if platform-specific headers are missing IP ([#2021](#2021))
* Ensure performance metrics are scoped to same call ([#2019](#2019))
* Return ERROR decision when fingerprint cannot be generated ([#1990](#1990))
* **protocol:** Remove received_at and decision fields from Report ([#1988](#1988))
* **analyze:** improve sensitive info string token accuracy ([#1962](#1962))
* Update Wasm with phone-number fix and tokenizer update ([#1854](#1854))
* Remove `match` option from rate limit rules ([#1815](#1815))

### 🚀 New Features

* Add Remix adapter ([#1866](#1866)) ([32d6d41](32d6d41)), closes [#1313](#1313)
* **analyze:** improve sensitive info string token accuracy ([#1962](#1962)) ([abad1bd](abad1bd))
* **ip:** Accept Request or IncomingMessage directly ([#2018](#2018)) ([1704da8](1704da8)), closes [#1904](#1904)
* **ip:** Add Vercel platform-specific IP header detection ([#2022](#2022)) ([d886c76](d886c76))
* **nextjs:** Support Next.js Server Actions ([#1991](#1991)) ([07e68dc](07e68dc)), closes [#1200](#1200)
* Use `waitUntil` for Report call if available ([#1838](#1838)) ([2851021](2851021)), closes [#884](#884)


### 🪲 Bug Fixes

* **arcjet:** Ensure performance measurements are 1-to-1 and always captured ([#1858](#1858)) ([4d29f9a](4d29f9a))
* Ensure performance metrics are scoped to same call ([#2019](#2019)) ([e9f869c](e9f869c)), closes [#1865](#1865)
* **ip:** Exit early if platform-specific headers are missing IP ([#2021](#2021)) ([1a13d9c](1a13d9c))
* **nestjs:** Lookup request from GraphQL context in ArcjetGuard ([#1857](#1857)) ([c0b2903](c0b2903)), closes [#1856](#1856)
* Return ERROR decision when fingerprint cannot be generated ([#1990](#1990)) ([618a1ee](618a1ee)), closes [#1801](#1801)
* Update Wasm with phone-number fix and tokenizer update ([#1854](#1854)) ([f94f078](f94f078))


### 🧹 Miscellaneous Chores

* Add README links for new adapters ([#1831](#1831)) ([81885d9](81885d9)), closes [#1813](#1813)
* **analyze:** Regenerate Wasm with updated dependencies ([#2067](#2067)) ([f96994c](f96994c))
* **examples:** Reorganize examples for clarity and decoupling from Next.js version ([#2017](#2017)) ([8568bf2](8568bf2))
* **examples:** Various cleanup ([#2066](#2066)) ([c626228](c626228))
* **protocol:** Remove received_at and decision fields from Report ([#1988](#1988)) ([3da543e](3da543e))
* Remove `match` option from rate limit rules ([#1815](#1815)) ([853119d](853119d)), closes [#1810](#1810)
</details>

---
This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants