Skip to content

Commit

Permalink
React router 7 (#297)
Browse files Browse the repository at this point in the history
* upgrade to react-router

* fix for cloudflare

* migrate to react-router

* replace symbols with a string key

* rollback to symbol and fix type error
  • Loading branch information
rphlmr authored Dec 5, 2024
1 parent d5d67db commit bc12d09
Show file tree
Hide file tree
Showing 10 changed files with 3,217 additions and 2,113 deletions.
5,211 changes: 3,159 additions & 2,052 deletions package-lock.json

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,18 @@
"test": "vitest"
},
"dependencies": {
"@remix-run/server-runtime": "^2.6.0",
"hono": "^4.0.0",
"react-router": "^7.0.1",
"hono": "^4.6.11",
"pretty-cache-header": "^1.0.0"
},
"peerDependencies": {
"@remix-run/cloudflare": "^2.0.0",
"@react-router/cloudflare": "^7.0.1",
"i18next": "^23.0.0",
"remix-i18next": "^6.0.0",
"remix-i18next": "^7.0.0",
"zod": "^3.0.0"
},
"peerDependenciesMeta": {
"@remix-run/cloudflare": {
"@react-router/cloudflare": {
"optional": true
},
"i18next": {
Expand All @@ -94,14 +94,14 @@
}
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20240314.0",
"@edge-runtime/vm": "^3.1.7",
"@remix-run/cloudflare": "^2.5.0",
"@remix-run/node": "^2.8.1",
"@cloudflare/workers-types": "^4.20241112.0",
"@edge-runtime/vm": "^4.0.4",
"@react-router/cloudflare": "^7.0.1",
"@react-router/node": "^7.0.1",
"@types/node": "^20.11.28",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitest/coverage-v8": "^1.4.0",
"@vitest/coverage-v8": "^2.1.5",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
Expand All @@ -113,11 +113,11 @@
"eslint-plugin-unicorn": "^53.0.0",
"i18next": "^23.10.1",
"prettier": "^3.2.4",
"remix-i18next": "^6.0.0",
"typescript": "^5.3.3",
"vite": "^5.1.6",
"vite-tsconfig-paths": "^4.3.2",
"vitest": "^1.4.0",
"remix-i18next": "^7.0.0",
"typescript": "^5.7.2",
"vite": "^5.4.11",
"vite-tsconfig-paths": "^5.1.3",
"vitest": "^2.1.5",
"zod": "^3.22.4"
}
}
8 changes: 4 additions & 4 deletions src/cloudflare.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { Context } from "hono";

import { createWorkersKVSessionStorage } from "@react-router/cloudflare";
import { createMiddleware } from "hono/factory";
import { cacheHeader } from "pretty-cache-header";
import {
CookieOptions,
SessionData,
createWorkersKVSessionStorage,
createCookieSessionStorage,
} from "@remix-run/cloudflare";
import { createMiddleware } from "hono/factory";
import { cacheHeader } from "pretty-cache-header";
} from "react-router";

import { session } from "./session.js";

Expand Down
6 changes: 3 additions & 3 deletions src/handler.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { AppLoadContext, ServerBuild } from "@remix-run/server-runtime";
import type { Context } from "hono";
import type { AppLoadContext, ServerBuild } from "react-router";

import { createRequestHandler } from "@remix-run/server-runtime";
import { createMiddleware } from "hono/factory";
import { createRequestHandler } from "react-router";

export interface RemixMiddlewareOptions {
build: ServerBuild;
Expand All @@ -25,4 +25,4 @@ export function remix({
});
}

export { createRequestHandler } from "@remix-run/server-runtime";
export { createRequestHandler } from "react-router";
15 changes: 7 additions & 8 deletions src/i18next.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import type { Context } from "hono";
import type { RemixI18NextOption } from "remix-i18next/server";

import { createMiddleware } from "hono/factory";
import { Namespace, TFunction } from "i18next";
import { FlatNamespace, TFunction } from "i18next";
import { RemixI18Next } from "remix-i18next/server";

const i18nSymbol = Symbol();
const LocaleSymbol = Symbol();
const TSymbol = Symbol();
const i18nSymbol = Symbol().toString();
const LocaleSymbol = Symbol().toString();
const TSymbol = Symbol().toString();

export function i18next(options: RemixI18NextOption | RemixI18Next) {
return createMiddleware(async (c, next) => {
Expand Down Expand Up @@ -46,10 +46,9 @@ i18next.getLocale = function getLocale(c: Context) {
return locale;
};

i18next.getFixedT = function getFixedT<Ns extends Namespace = "translation">(
c: Context,
{ namespace }: { namespace?: Ns } = {},
) {
i18next.getFixedT = function getFixedT<
Ns extends FlatNamespace = "translation",
>(c: Context, { namespace }: { namespace?: Ns } = {}) {
// If `namespace` is set, we return a new `t` function that is bound to the
// given namespace. Otherwise, we return the default `t` function.
if (namespace) {
Expand Down
28 changes: 14 additions & 14 deletions src/session.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import type {
Session,
SessionData,
SessionStorage,
} from "@remix-run/server-runtime";
import type { Context } from "hono";
import type { Session, SessionData, SessionStorage } from "react-router";

import { createMiddleware } from "hono/factory";

const sessionStorageSymbol = Symbol();
const sessionSymbol = Symbol();
type Env = {
Variables: Record<symbol, unknown>;
};

const sessionStorageKey = Symbol();
const sessionKey = Symbol();

export function session<Data = SessionData, FlashData = Data>(options: {
autoCommit?: boolean;
createSessionStorage(c: Context): SessionStorage<Data, FlashData>;
}) {
return createMiddleware(async (c, next) => {
return createMiddleware<Env>(async (c, next) => {
let sessionStorage = options.createSessionStorage(c);

c.set(sessionStorageSymbol, sessionStorage);
c.set(sessionStorageKey, sessionStorage);

// If autoCommit is disabled, we just create the SessionStorage and make it
// available with c.get(sessionStorageSymbol), then call next() and
Expand All @@ -32,7 +32,7 @@ export function session<Data = SessionData, FlashData = Data>(options: {
);

// And make it available with c.get(sessionSymbol).
c.set(sessionSymbol, session);
c.set(sessionKey, session);

// Then we call next() to let the rest of the middlewares run.
await next();
Expand All @@ -45,19 +45,19 @@ export function session<Data = SessionData, FlashData = Data>(options: {
}

export function getSessionStorage<Data = SessionData, FlashData = Data>(
c: Context,
c: Context<Env>,
): SessionStorage<Data, FlashData> {
let sessionStorage = c.get(sessionStorageSymbol);
let sessionStorage = c.get(sessionStorageKey);
if (!sessionStorage) {
throw new Error("A session middleware was not set.");
}
return sessionStorage as SessionStorage<Data, FlashData>;
}

export function getSession<Data = SessionData, FlashData = Data>(
c: Context,
c: Context<Env>,
): Session<Data, FlashData> {
let session = c.get(sessionSymbol);
let session = c.get(sessionKey);
if (!session) {
throw new Error("A session middleware was not set.");
}
Expand Down
12 changes: 7 additions & 5 deletions test/cloudflare.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import {
createCookieSessionStorage,
createWorkersKVSessionStorage,
} from "@remix-run/cloudflare";
import { createWorkersKVSessionStorage } from "@react-router/cloudflare";
import { Context } from "hono";
import { createMiddleware } from "hono/factory";
import { createCookieSessionStorage } from "react-router";
import { describe, test, expect, vi, beforeEach, afterAll } from "vitest";

import {
Expand All @@ -13,9 +11,13 @@ import {
} from "../src/cloudflare";
import { session } from "../src/session";

vi.mock("@remix-run/cloudflare", () => {
vi.mock("@react-router/cloudflare", () => {
return {
createWorkersKVSessionStorage: vi.fn(),
};
});
vi.mock("react-router", () => {
return {
createCookieSessionStorage: vi.fn(),
};
});
Expand Down
9 changes: 2 additions & 7 deletions test/handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ServerBuild } from "@remix-run/server-runtime";
import type { ServerBuild } from "react-router";

import { Hono } from "hono";
import { describe, test, expect, vi, beforeEach, afterAll } from "vitest";
Expand Down Expand Up @@ -29,11 +29,7 @@ const build = {
default: () => new Response("body"),
},
},
future: {
v3_fetcherPersist: true,
v3_relativeSplatPath: true,
v3_throwAbortReason: true,
},
future: {},
publicPath: "/",
routes: {
root: {
Expand All @@ -45,7 +41,6 @@ const build = {
},
},
isSpaMode: false,
mode: "production",
} satisfies ServerBuild;

describe(remix.name, () => {
Expand Down
4 changes: 2 additions & 2 deletions test/session.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createCookieSessionStorage } from "@remix-run/cloudflare";
import { Context } from "hono";
import { createCookieSessionStorage } from "react-router";
import { describe, test, expect, vi, beforeEach, afterAll } from "vitest";

import { getSession, getSessionStorage, session } from "../src/session";

vi.mock("@remix-run/node", () => {
vi.mock("@react-router/node", () => {
return {
createCookieSessionStorage: vi.fn(),
};
Expand Down
7 changes: 4 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
{
"compilerOptions": {
"lib": ["ES2019"],
"lib": ["ES2020"],
"esModuleInterop": true,
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "ES2019",
"target": "ES2020",
"strict": true,
"skipLibCheck": true,
"declaration": true,
"types": ["@cloudflare/workers-types"],
"baseUrl": ".", // This must be specified if "paths" is specified
"paths": {
"remix-hono/cloudflare": ["./build/cloudflare"] // relative to "baseUrl"
}
},
"exclude": ["node_modules"],
"include": ["src/**/*.ts", "@cloudflare/workers-types"]
"include": ["src/**/*.ts"]
}

0 comments on commit bc12d09

Please sign in to comment.