diff --git a/.changeset/stupid-frogs-draw.md b/.changeset/stupid-frogs-draw.md
new file mode 100644
index 0000000..d4bd223
--- /dev/null
+++ b/.changeset/stupid-frogs-draw.md
@@ -0,0 +1,45 @@
+---
+"@mcansh/http-helmet": patch
+---
+
+adds support for remix middleware
+
+```ts
+import {
+ securityHeaders,
+ NONCE,
+ getCSPNonce,
+ setCSPNonce,
+} from "@mcansh/http-helmet/remix-middleware";
+import { createRouter } from "remix/fetch-router";
+import { asyncContext } from "@remix-run/async-context-middleware";
+
+let nonce = createNonce();
+setCSPNonce(nonce);
+
+let router = createRouter({
+ middleware: [
+ asyncContext(),
+ securityHeaders({
+ "Content-Security-Policy": {
+ "default-src": ["'self'"],
+ "script-src": ["'self'", NONCE(nonce)],
+ },
+ }),
+ ],
+});
+```
+
+// then in your controller you can get the nonce from the context and use it in your templates to add a nonce to your script tags
+
+```ts
+export const home = {
+ handler() {
+ let nonce = getCSPNonce();
+
+ return render(
+ ``,
+ );
+ },
+} satisfies BuildAction;
+```
diff --git a/packages/http-helmet/README.md b/packages/http-helmet/README.md
index bed3e51..33ad64a 100644
--- a/packages/http-helmet/README.md
+++ b/packages/http-helmet/README.md
@@ -11,15 +11,14 @@ npm i @mcansh/http-helmet
## Usage
-basic example using [`@mjackson/node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server)
+basic example using [`@remix-run/node-fetch-server`](https://github.com/remix-run/remix/tree/main/packages/node-fetch-server)
```js
import * as http from "node:http";
-import { createRequestListener } from "@mjackson/node-fetch-server";
+import { createRequestListener } from "@remix-run/node-fetch-server";
+import { html } from "@remix-run/html-template";
import { createNonce, createSecureHeaders } from "@mcansh/http-helmet";
-let html = String.raw;
-
let handler = (request) => {
let nonce = createNonce();
let headers = createSecureHeaders({
diff --git a/packages/http-helmet/package.json b/packages/http-helmet/package.json
index d78bc02..2766204 100644
--- a/packages/http-helmet/package.json
+++ b/packages/http-helmet/package.json
@@ -39,6 +39,10 @@
"import": "./dist/react.js",
"require": "./dist/react.cjs"
},
+ "./remix-middleware": {
+ "import": "./dist/remix-middleware.js",
+ "require": "./dist/remix-middleware.cjs"
+ },
"./package.json": "./package.json"
},
"files": [
@@ -51,10 +55,18 @@
"type-fest": "^4.41.0"
},
"peerDependencies": {
+ "@remix-run/fetch-router": ">=0.18.0",
+ "@remix-run/async-context-middleware": ">=0.2.0",
"react": ">=18.0.0 || >=19.0.0",
"react-dom": ">=18.0.0 || >=19.0.0"
},
"peerDependenciesMeta": {
+ "@remix-run/fetch-router": {
+ "optional": true
+ },
+ "@remix-run/async-context-middleware": {
+ "optional": true
+ },
"react": {
"optional": true
},
@@ -64,6 +76,8 @@
},
"devDependencies": {
"@arethetypeswrong/core": "catalog:",
+ "@remix-run/async-context-middleware": "^0.2.0",
+ "@remix-run/fetch-router": "^0.18.0",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
@@ -77,6 +91,7 @@
"publint": "catalog:",
"react": "^19.2.0",
"react-dom": "^19.2.0",
+ "remix": "3.0.0-alpha.4",
"tsdown": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
diff --git a/packages/http-helmet/src/remix.ts b/packages/http-helmet/src/remix.ts
new file mode 100644
index 0000000..c16cddc
--- /dev/null
+++ b/packages/http-helmet/src/remix.ts
@@ -0,0 +1,54 @@
+import { getContext } from "@remix-run/async-context-middleware";
+import type { Middleware } from "@remix-run/fetch-router";
+import { createContextKey } from "@remix-run/fetch-router";
+import type { CreateSecureHeaders } from "./index.ts";
+import { createSecureHeaders, mergeHeaders } from "./index.ts";
+
+export {
+ createNonce,
+ HASH,
+ mergeHeaders,
+ NONCE,
+ NONE,
+ REPORT_SAMPLE,
+ SELF,
+ STRICT_DYNAMIC,
+ UNSAFE_EVAL,
+ UNSAFE_HASHES,
+ UNSAFE_INLINE,
+ WASM_UNSAFE_EVAL,
+} from "./utils";
+
+let NONCE_KEY = createContextKey();
+
+export function getCSPNonce(): string {
+ return getContext().get(NONCE_KEY);
+}
+
+export function setCSPNonce(nonce: string): void {
+ getContext().set(NONCE_KEY, nonce);
+}
+
+type Context = Parameters[0];
+
+export type SecurityHeadersOptions = CreateSecureHeaders & {
+ skip?: (context: Context) => boolean | Promise;
+};
+
+export function securityHeaders({
+ skip,
+ ...options
+}: SecurityHeadersOptions): Middleware {
+ return async (context, next) => {
+ let response = await next();
+ if (skip?.(context)) return response;
+
+ let secureHeaders = createSecureHeaders(options);
+
+ return new Response(response.body, {
+ status: response.status,
+ statusText: response.statusText,
+ headers: mergeHeaders(response.headers, secureHeaders),
+ });
+ };
+}
diff --git a/packages/http-helmet/src/utils.ts b/packages/http-helmet/src/utils.ts
index a82e4b7..7a06a3f 100644
--- a/packages/http-helmet/src/utils.ts
+++ b/packages/http-helmet/src/utils.ts
@@ -37,7 +37,9 @@ function isObject(value: unknown) {
return value !== null && typeof value === "object";
}
-export function mergeHeaders(...sources: HeadersInit[]): Headers {
+export function mergeHeaders(
+ ...sources: [HeadersInit, ...Array]
+): Headers {
let result = new Headers();
for (let source of sources) {
diff --git a/packages/http-helmet/tsdown.config.ts b/packages/http-helmet/tsdown.config.ts
index 0479692..ff3971c 100755
--- a/packages/http-helmet/tsdown.config.ts
+++ b/packages/http-helmet/tsdown.config.ts
@@ -10,6 +10,7 @@ export default defineConfig({
entry: {
index: "./src/index.ts",
react: "./src/react.tsx",
+ "remix-middleware": "./src/remix.ts",
},
dts: true,
format: ["cjs", "esm"],
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8dc8356..d067260 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -279,6 +279,12 @@ importers:
'@arethetypeswrong/core':
specifier: 'catalog:'
version: 0.18.2
+ '@remix-run/async-context-middleware':
+ specifier: ^0.2.0
+ version: 0.2.0
+ '@remix-run/fetch-router':
+ specifier: ^0.18.0
+ version: 0.18.0
'@testing-library/dom':
specifier: ^10.4.0
version: 10.4.1
@@ -318,6 +324,9 @@ importers:
react-dom:
specifier: ^19.2.0
version: 19.2.0(react@19.2.0)
+ remix:
+ specifier: 3.0.0-alpha.4
+ version: 3.0.0-alpha.4
tsdown:
specifier: 'catalog:'
version: 0.12.9(@arethetypeswrong/core@0.18.2)(publint@0.3.15)(typescript@5.9.3)
@@ -1700,6 +1709,63 @@ packages:
peerDependencies:
react-router: 7.9.5
+ '@remix-run/async-context-middleware@0.2.0':
+ resolution: {integrity: sha512-ebnPM2OFM/BO3GSoRKs2i5+lgY/fIunzpL8/RhuEuP9a04cQYXMbEzbdae+qBHTgtsVdPrqeGr/lwlF5FNnQZA==}
+
+ '@remix-run/auth-middleware@0.1.0':
+ resolution: {integrity: sha512-QZlI4MyU8VTVI6WB4T4MWWqtbYrIUiiBG3mgdJUXjEYMBBoxVAkT/6rT3YErmhX+SVARP2zC46qzujrbYcQLCQ==}
+
+ '@remix-run/auth@0.1.0':
+ resolution: {integrity: sha512-TFsK40jymT7iZyGWOjoqlFFmILdDXy3jYBoI1mohjdqrp8SVWbm7htiSbdd+j8DGBUEbxMTvKcaVG0bPA1M8VA==}
+
+ '@remix-run/component@0.6.0':
+ resolution: {integrity: sha512-hmIUdPnBtONeOH8bbLuOVGSgFD/MAUNvpH0Xwgo27GByBIjQhOm25Tt9R04HQslDhHAzwNVnWeQkr3j9eyXYhQ==}
+
+ '@remix-run/compression-middleware@0.1.4':
+ resolution: {integrity: sha512-vE+d4a04Tq9fO5KBmNtMD5GKJEt6U++B1yufEdBMNe5ROBQkpPWSuKlhkRcZyoV8SPEI2HbkKMtQ8QXfGJR11g==}
+
+ '@remix-run/cookie@0.5.1':
+ resolution: {integrity: sha512-gbeZfVd1AKRlFj3IJWcIcR6zqVGz2XGJhR+mcqYiWnYt6KM8oUGtc82dsc4qZnWWA1f0nM4/He9wrU4GjB0pag==}
+
+ '@remix-run/cop-middleware@0.1.0':
+ resolution: {integrity: sha512-5rMNrBswTJJLPsu1nUfXubgVf7XBTRfPNfd/4QQHaXRdhXVWVxU9HbNJrOjd7iNbBWuZeaJxSdDepbQLnuBkTg==}
+
+ '@remix-run/cors-middleware@0.1.0':
+ resolution: {integrity: sha512-x5nyxDhWEOnznqetDhtj5WYoHrKpbiZ8K6BCGQ2+DFjLYHoyWCayciUNrqOVSIWc5XdV6KlKHcg1TyQvW/cS4w==}
+
+ '@remix-run/csrf-middleware@0.1.0':
+ resolution: {integrity: sha512-EZAV9UZrx3qdYu3ov9NgFVJchw6kOLYI2uRB+e3WBVW1phruHKc42EpdJIZ6fU0J9Of0Lfo4X4VTM7O1/u1cWw==}
+
+ '@remix-run/data-schema@0.2.0':
+ resolution: {integrity: sha512-bXgdWcWZS6TkbVO9Piwn035iw0LczfSTFrCW4Vd1k57x/4j3eWZwfHBr3lXdw5whefacs3m3pVZ8RUiu8NtBeA==}
+
+ '@remix-run/data-table-mysql@0.2.0':
+ resolution: {integrity: sha512-voTcYUjG12PWlrWIYSqoa+C3WK9Q6TVKPrqnvGKY9s6EVBil9e+glaP2JOM8BbzL0hGuKPifdbrDGfGpGitdQw==}
+ peerDependencies:
+ mysql2: ^3.15.3
+ peerDependenciesMeta:
+ mysql2:
+ optional: true
+
+ '@remix-run/data-table-postgres@0.2.0':
+ resolution: {integrity: sha512-03v+zpWL4lMJr34PZ76PWFpjIa4K6Uq3NLBqyvN4ojPpm6J7TGsFwPy6sInRm3HjoS4gPSCEmmQ7dUovWa58EA==}
+ peerDependencies:
+ pg: ^8.16.3
+ peerDependenciesMeta:
+ pg:
+ optional: true
+
+ '@remix-run/data-table-sqlite@0.2.0':
+ resolution: {integrity: sha512-TAQ0u8YnmO3WdnuZULPhc+fgZbKZZPutXiPLf8c9NDhXSC41FlcvfQHTKUxBPVhqdi9mhGiblHHNp6BsVu11dg==}
+ peerDependencies:
+ better-sqlite3: ^12.4.1
+ peerDependenciesMeta:
+ better-sqlite3:
+ optional: true
+
+ '@remix-run/data-table@0.2.0':
+ resolution: {integrity: sha512-6QbdlKER0F0rX3XkTHC7ZPBgu/dyGvvgrKRbraBD9iGHTE7AED1emo3/YWsDJUeFzy7INNJaUIpNm9jNcgL8Kg==}
+
'@remix-run/dev@2.17.2':
resolution: {integrity: sha512-gfc4Hu2Sysr+GyU/F12d2uvEfQwUwWvsOjBtiemhdN1xGOn1+FyYzlLl/aJ7AL9oYko8sDqOPyJCiApWJJGCCw==}
engines: {node: '>=18.0.0'}
@@ -1741,6 +1807,51 @@ packages:
typescript:
optional: true
+ '@remix-run/fetch-proxy@0.7.1':
+ resolution: {integrity: sha512-rPLfOpAaCXtm1dLI45uIPKERNbXbrh0P9AJc1sliz8pWd/McaFYjdr5KzB4QrFSfPvEt/Wmy6F2521qB1kK0ug==}
+
+ '@remix-run/fetch-router@0.18.0':
+ resolution: {integrity: sha512-9Z4JgLH9/jD8jiVvAY9LZR+VoZxPJOQ7pENTBJoSo91PZOkPXfCxQWhPhAwYCP8z+/0FV4ZWSg1DmPPoU2f0UQ==}
+
+ '@remix-run/file-storage-s3@0.1.0':
+ resolution: {integrity: sha512-r80An7nSFidK/0xn9O9/HxfUcgxVpM4kprnTGr6pGhKdgbaTCEtA+U5ETYGfeedFxhDcT+7ue+4Fv/VxeIvFwQ==}
+
+ '@remix-run/file-storage@0.13.3':
+ resolution: {integrity: sha512-HBDz9RRsFRvI6EoeasklxH/NleGy0QZBXBcA4gQBW8ueucop21TQI4wvGlhZmXcnJ3nP4RkhdF2Gff2/HD5eiA==}
+
+ '@remix-run/form-data-middleware@0.2.0':
+ resolution: {integrity: sha512-oaBcYvyP/U2GrDdFyQUh2pNCshvKwPFBoUup1Bz3NHnMzym4OkZJgaBi4o7HIJC33QudnqI7Mp7TW1pRg0CvIA==}
+
+ '@remix-run/form-data-parser@0.16.0':
+ resolution: {integrity: sha512-k4QCgCyPURpqe+9Rual1GBJ8Ab6ri82Clfh5ooxq03jKQ1TyQZT5xh+XP0R05+Bqg5bzAZl7r2BpmDEvfoRTWw==}
+
+ '@remix-run/fs@0.4.2':
+ resolution: {integrity: sha512-z3W2L+iUwgZ7i0S379SYQ8veOe2Weqs+JajmyTCqSVzbmMUniH3qQ6SAYr3FjbrKtLLWHN3SpK4XtFv57VzbLA==}
+
+ '@remix-run/headers@0.19.0':
+ resolution: {integrity: sha512-+62NbkXuXm9r/NdG6KfH9OCKofCWm8VjkrVPICiHKtRl8Gf2Vi6eFTN4mGgBlZRhd5mmEVRV4hTIn/JUSHDAOw==}
+
+ '@remix-run/html-template@0.3.0':
+ resolution: {integrity: sha512-aAMx68udtIk0fmCpCXHYscVeCDsRVEmEgh4XvtusPr3vkHu3jn4gx5oAxgsPXPdDmmD/d75SYyI0m/F+aLz5iQ==}
+
+ '@remix-run/lazy-file@5.0.2':
+ resolution: {integrity: sha512-52Bo5dTV+EDwrUMS3mjeR+Sly85aHeN3fnNTeaflqzlCMWJwr2pX+y6/3mTDtRdxmTWF1MGQAoeayzfPb4zZJg==}
+
+ '@remix-run/logger-middleware@0.1.4':
+ resolution: {integrity: sha512-gFDyYn8o5ddjQoEbrc8CK6PPq3lzrOX6BCqlvM+QVTMJ5/2aHgfMbQdXnWtbeiWJJrpODpABrSNfjLkHjaK4og==}
+
+ '@remix-run/method-override-middleware@0.1.5':
+ resolution: {integrity: sha512-HYQG6YR4l0rYMJ0MXth9SWfeSCwnqHIrWgMQpZHKS/MT7roX7EAfknrl9vzjQWsVfkwl6RrSD30SrLPONj3tsg==}
+
+ '@remix-run/mime@0.4.0':
+ resolution: {integrity: sha512-O6TcTL6CtuX82Q8BHqAere5O+0hYcrzSgY9whsDOBuqbW753Rczprs2jYw3qCDSo0kLxykW4ys3qgZcdgZ+chw==}
+
+ '@remix-run/multipart-parser@0.15.0':
+ resolution: {integrity: sha512-/Ugo6k2bN7gh7Ybyhe7R/NrkD075fHrEfVf17P+NNC9rlWHBQCOSyJ4V8n4wtoG8umeImagU/AuHuUuTwzvHww==}
+
+ '@remix-run/node-fetch-server@0.13.0':
+ resolution: {integrity: sha512-1EsNo0ZpgXu/90AWoRZf/oE3RVTUS80tiTUpt+hv5pjtAkw7icN4WskDwz/KdAw5ARbJLMhZBrO1NqThmy/McA==}
+
'@remix-run/node-fetch-server@0.9.0':
resolution: {integrity: sha512-SoLMv7dbH+njWzXnOY6fI08dFMI5+/dQ+vY3n8RnnbdG7MdJEgiP28Xj/xWlnRnED/aB6SFw56Zop+LbmaaKqA==}
@@ -1764,6 +1875,12 @@ packages:
typescript:
optional: true
+ '@remix-run/response@0.3.2':
+ resolution: {integrity: sha512-GkFqVq5E7Do6rMKTBjgoNyJlrsLrqYg+TDlCDrXoZ3v8O2RlSI14+bCF8lGQHy15DWX2pizVj6R0e6NmjcuLuA==}
+
+ '@remix-run/route-pattern@0.20.0':
+ resolution: {integrity: sha512-TEdJ5eFn40St26oyaRYGI1FWeXDvlEzkbvollM8Xit0qIuDFyFG03Okvvfc1s8KgR9sYULDPjxJIzk6xvIRR9A==}
+
'@remix-run/router@1.23.0':
resolution: {integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==}
engines: {node: '>=14.0.0'}
@@ -1782,6 +1899,29 @@ packages:
typescript:
optional: true
+ '@remix-run/session-middleware@0.2.0':
+ resolution: {integrity: sha512-kRAr0inELyXeOnUhlaM/eKIe9x1RZsOGbglb7Keb1+Lf6KxWxNMwv1ymmHBfae2ossjQTN/QUaABwQgX/uk3DQ==}
+
+ '@remix-run/session-storage-memcache@0.1.0':
+ resolution: {integrity: sha512-k853rpHncdTJUwdk0hqd+gZ2OONZLNdOUJBKdJB+MehxrVv1TtacDnA+Xs3kh+IVwUrsTmBhED+GHSUocMATUg==}
+
+ '@remix-run/session-storage-redis@0.1.0':
+ resolution: {integrity: sha512-MovUS1E98wDHP8zsESJGm3ySB7iiOhd+3usxyXXM2sbF9gIe6r1bdAXXirGIoC8AEq1v8IiFE5u5ipo7PX0UHQ==}
+ peerDependencies:
+ redis: ^5.10.0
+ peerDependenciesMeta:
+ redis:
+ optional: true
+
+ '@remix-run/session@0.4.1':
+ resolution: {integrity: sha512-Bm6aKYgutb/raHZ3laloz8g/Qu7f3CeK3o4gUVDMxtEiAdWCzJamwHoTpGOc5+g1Kuy7z85v4M6nGrF06MFDSg==}
+
+ '@remix-run/static-middleware@0.4.5':
+ resolution: {integrity: sha512-jxEbrQMDWcUgmv/2NSv4pahvaW3I4jxqZUMDQ7/VfkcgeJKLFk15vgp4BJ5vLDKKMvwVcgM0Ccbw4Y3Ev2zemA==}
+
+ '@remix-run/tar-parser@0.7.0':
+ resolution: {integrity: sha512-PW8JxEUzaGcnqxC5hBI8L9lK/Qz3oad6IGKZ+NExI3L7urVJUux+yCBrsme79DMBgS6hL+lgd/5LPFA5fSwF9A==}
+
'@remix-run/web-blob@3.1.0':
resolution: {integrity: sha512-owGzFLbqPH9PlKb8KvpNJ0NO74HWE2euAn61eEiyCXX/oteoVzTVSN8mpLgDjaxBf2btj5/nUllSUgpyd6IH6g==}
@@ -2022,6 +2162,9 @@ packages:
'@speed-highlight/core@1.2.8':
resolution: {integrity: sha512-IGytNtnUnPIobIbOq5Y6LIlqiHNX+vnToQIS7lj6L5819C+rA8TXRDkkG8vePsiBOGcoW9R6i+dp2YBUKdB09Q==}
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
'@tailwindcss/node@4.1.17':
resolution: {integrity: sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg==}
@@ -2163,6 +2306,9 @@ packages:
'@types/deep-eql@4.0.2':
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+ '@types/dom-navigation@1.0.7':
+ resolution: {integrity: sha512-Di4W+i2faYquHUnyWUg3bBQp5pTNvjDDA7mIYfD/1WlLgan6sKkeVjGbdL78K0CuNEk5Pfc/c0rfelwkz10mnQ==}
+
'@types/estree-jsx@1.0.5':
resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
@@ -2708,6 +2854,9 @@ packages:
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
engines: {node: '>= 0.4'}
+ aws4fetch@1.0.20:
+ resolution: {integrity: sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g==}
+
axe-core@4.11.0:
resolution: {integrity: sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==}
engines: {node: '>=4'}
@@ -3721,11 +3870,12 @@ packages:
glob@10.4.5:
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
hasBin: true
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
- deprecated: Glob versions prior to v9 are no longer supported
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
globals@13.24.0:
resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
@@ -5281,6 +5431,9 @@ packages:
remark-rehype@10.1.0:
resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==}
+ remix@3.0.0-alpha.4:
+ resolution: {integrity: sha512-fvYHPm8QbrbL09wmmddrnknyntB+fl4bLmpECpK32cOoJW3pMoMvESBB1qRAQe+yWgTexVjp5G3BGOmmtYOX0A==}
+
require-like@0.1.2:
resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==}
@@ -5684,6 +5837,7 @@ packages:
tar@6.2.1:
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
engines: {node: '>=10'}
+ deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
term-size@2.2.1:
resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
@@ -7565,6 +7719,66 @@ snapshots:
- supports-color
- typescript
+ '@remix-run/async-context-middleware@0.2.0':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+
+ '@remix-run/auth-middleware@0.1.0':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+ '@remix-run/session': 0.4.1
+
+ '@remix-run/auth@0.1.0':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+ '@remix-run/session': 0.4.1
+
+ '@remix-run/component@0.6.0':
+ dependencies:
+ '@types/dom-navigation': 1.0.7
+
+ '@remix-run/compression-middleware@0.1.4':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+ '@remix-run/mime': 0.4.0
+ '@remix-run/response': 0.3.2
+
+ '@remix-run/cookie@0.5.1':
+ dependencies:
+ '@remix-run/headers': 0.19.0
+
+ '@remix-run/cop-middleware@0.1.0':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+
+ '@remix-run/cors-middleware@0.1.0':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+ '@remix-run/headers': 0.19.0
+
+ '@remix-run/csrf-middleware@0.1.0':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+ '@remix-run/session': 0.4.1
+
+ '@remix-run/data-schema@0.2.0':
+ dependencies:
+ '@standard-schema/spec': 1.1.0
+
+ '@remix-run/data-table-mysql@0.2.0':
+ dependencies:
+ '@remix-run/data-table': 0.2.0
+
+ '@remix-run/data-table-postgres@0.2.0':
+ dependencies:
+ '@remix-run/data-table': 0.2.0
+
+ '@remix-run/data-table-sqlite@0.2.0':
+ dependencies:
+ '@remix-run/data-table': 0.2.0
+
+ '@remix-run/data-table@0.2.0': {}
+
'@remix-run/dev@2.17.2(@remix-run/react@2.17.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3))(@remix-run/serve@2.17.2(typescript@5.9.3))(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(typescript@5.9.3)(vite@6.3.6(@types/node@24.10.0)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.1))(wrangler@4.45.0)(yaml@2.8.1)':
dependencies:
'@babel/core': 7.28.5
@@ -7766,6 +7980,62 @@ snapshots:
optionalDependencies:
typescript: 5.9.3
+ '@remix-run/fetch-proxy@0.7.1':
+ dependencies:
+ '@remix-run/headers': 0.19.0
+
+ '@remix-run/fetch-router@0.18.0':
+ dependencies:
+ '@remix-run/route-pattern': 0.20.0
+
+ '@remix-run/file-storage-s3@0.1.0':
+ dependencies:
+ '@remix-run/file-storage': 0.13.3
+ aws4fetch: 1.0.20
+
+ '@remix-run/file-storage@0.13.3':
+ dependencies:
+ '@remix-run/fs': 0.4.2
+ '@remix-run/lazy-file': 5.0.2
+
+ '@remix-run/form-data-middleware@0.2.0':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+ '@remix-run/form-data-parser': 0.16.0
+
+ '@remix-run/form-data-parser@0.16.0':
+ dependencies:
+ '@remix-run/multipart-parser': 0.15.0
+
+ '@remix-run/fs@0.4.2':
+ dependencies:
+ '@remix-run/lazy-file': 5.0.2
+ '@remix-run/mime': 0.4.0
+
+ '@remix-run/headers@0.19.0': {}
+
+ '@remix-run/html-template@0.3.0': {}
+
+ '@remix-run/lazy-file@5.0.2':
+ dependencies:
+ '@remix-run/mime': 0.4.0
+
+ '@remix-run/logger-middleware@0.1.4':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+
+ '@remix-run/method-override-middleware@0.1.5':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+
+ '@remix-run/mime@0.4.0': {}
+
+ '@remix-run/multipart-parser@0.15.0':
+ dependencies:
+ '@remix-run/headers': 0.19.0
+
+ '@remix-run/node-fetch-server@0.13.0': {}
+
'@remix-run/node-fetch-server@0.9.0': {}
'@remix-run/node@2.17.2(typescript@5.9.3)':
@@ -7792,6 +8062,14 @@ snapshots:
optionalDependencies:
typescript: 5.9.3
+ '@remix-run/response@0.3.2':
+ dependencies:
+ '@remix-run/headers': 0.19.0
+ '@remix-run/html-template': 0.3.0
+ '@remix-run/mime': 0.4.0
+
+ '@remix-run/route-pattern@0.20.0': {}
+
'@remix-run/router@1.23.0': {}
'@remix-run/serve@2.17.2(typescript@5.9.3)':
@@ -7820,6 +8098,32 @@ snapshots:
optionalDependencies:
typescript: 5.9.3
+ '@remix-run/session-middleware@0.2.0':
+ dependencies:
+ '@remix-run/cookie': 0.5.1
+ '@remix-run/fetch-router': 0.18.0
+ '@remix-run/session': 0.4.1
+
+ '@remix-run/session-storage-memcache@0.1.0':
+ dependencies:
+ '@remix-run/session': 0.4.1
+
+ '@remix-run/session-storage-redis@0.1.0':
+ dependencies:
+ '@remix-run/session': 0.4.1
+
+ '@remix-run/session@0.4.1': {}
+
+ '@remix-run/static-middleware@0.4.5':
+ dependencies:
+ '@remix-run/fetch-router': 0.18.0
+ '@remix-run/fs': 0.4.2
+ '@remix-run/html-template': 0.3.0
+ '@remix-run/mime': 0.4.0
+ '@remix-run/response': 0.3.2
+
+ '@remix-run/tar-parser@0.7.0': {}
+
'@remix-run/web-blob@3.1.0':
dependencies:
'@remix-run/web-stream': 1.1.0
@@ -7988,6 +8292,8 @@ snapshots:
'@speed-highlight/core@1.2.8': {}
+ '@standard-schema/spec@1.1.0': {}
+
'@tailwindcss/node@4.1.17':
dependencies:
'@jridgewell/remapping': 2.3.5
@@ -8122,6 +8428,8 @@ snapshots:
'@types/deep-eql@4.0.2': {}
+ '@types/dom-navigation@1.0.7': {}
+
'@types/estree-jsx@1.0.5':
dependencies:
'@types/estree': 1.0.8
@@ -8749,6 +9057,8 @@ snapshots:
dependencies:
possible-typed-array-names: 1.1.0
+ aws4fetch@1.0.20: {}
+
axe-core@4.11.0: {}
axobject-query@4.1.0: {}
@@ -11813,6 +12123,51 @@ snapshots:
mdast-util-to-hast: 12.3.0
unified: 10.1.2
+ remix@3.0.0-alpha.4:
+ dependencies:
+ '@remix-run/async-context-middleware': 0.2.0
+ '@remix-run/auth': 0.1.0
+ '@remix-run/auth-middleware': 0.1.0
+ '@remix-run/component': 0.6.0
+ '@remix-run/compression-middleware': 0.1.4
+ '@remix-run/cookie': 0.5.1
+ '@remix-run/cop-middleware': 0.1.0
+ '@remix-run/cors-middleware': 0.1.0
+ '@remix-run/csrf-middleware': 0.1.0
+ '@remix-run/data-schema': 0.2.0
+ '@remix-run/data-table': 0.2.0
+ '@remix-run/data-table-mysql': 0.2.0
+ '@remix-run/data-table-postgres': 0.2.0
+ '@remix-run/data-table-sqlite': 0.2.0
+ '@remix-run/fetch-proxy': 0.7.1
+ '@remix-run/fetch-router': 0.18.0
+ '@remix-run/file-storage': 0.13.3
+ '@remix-run/file-storage-s3': 0.1.0
+ '@remix-run/form-data-middleware': 0.2.0
+ '@remix-run/form-data-parser': 0.16.0
+ '@remix-run/fs': 0.4.2
+ '@remix-run/headers': 0.19.0
+ '@remix-run/html-template': 0.3.0
+ '@remix-run/lazy-file': 5.0.2
+ '@remix-run/logger-middleware': 0.1.4
+ '@remix-run/method-override-middleware': 0.1.5
+ '@remix-run/mime': 0.4.0
+ '@remix-run/multipart-parser': 0.15.0
+ '@remix-run/node-fetch-server': 0.13.0
+ '@remix-run/response': 0.3.2
+ '@remix-run/route-pattern': 0.20.0
+ '@remix-run/session': 0.4.1
+ '@remix-run/session-middleware': 0.2.0
+ '@remix-run/session-storage-memcache': 0.1.0
+ '@remix-run/session-storage-redis': 0.1.0
+ '@remix-run/static-middleware': 0.4.5
+ '@remix-run/tar-parser': 0.7.0
+ transitivePeerDependencies:
+ - better-sqlite3
+ - mysql2
+ - pg
+ - redis
+
require-like@0.1.2: {}
requireindex@1.2.0: {}