Skip to content

Commit bc12d09

Browse files
authored
React router 7 (#297)
* upgrade to react-router * fix for cloudflare * migrate to react-router * replace symbols with a string key * rollback to symbol and fix type error
1 parent d5d67db commit bc12d09

File tree

10 files changed

+3217
-2113
lines changed

10 files changed

+3217
-2113
lines changed

package-lock.json

Lines changed: 3159 additions & 2052 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,18 @@
6969
"test": "vitest"
7070
},
7171
"dependencies": {
72-
"@remix-run/server-runtime": "^2.6.0",
73-
"hono": "^4.0.0",
72+
"react-router": "^7.0.1",
73+
"hono": "^4.6.11",
7474
"pretty-cache-header": "^1.0.0"
7575
},
7676
"peerDependencies": {
77-
"@remix-run/cloudflare": "^2.0.0",
77+
"@react-router/cloudflare": "^7.0.1",
7878
"i18next": "^23.0.0",
79-
"remix-i18next": "^6.0.0",
79+
"remix-i18next": "^7.0.0",
8080
"zod": "^3.0.0"
8181
},
8282
"peerDependenciesMeta": {
83-
"@remix-run/cloudflare": {
83+
"@react-router/cloudflare": {
8484
"optional": true
8585
},
8686
"i18next": {
@@ -94,14 +94,14 @@
9494
}
9595
},
9696
"devDependencies": {
97-
"@cloudflare/workers-types": "^4.20240314.0",
98-
"@edge-runtime/vm": "^3.1.7",
99-
"@remix-run/cloudflare": "^2.5.0",
100-
"@remix-run/node": "^2.8.1",
97+
"@cloudflare/workers-types": "^4.20241112.0",
98+
"@edge-runtime/vm": "^4.0.4",
99+
"@react-router/cloudflare": "^7.0.1",
100+
"@react-router/node": "^7.0.1",
101101
"@types/node": "^20.11.28",
102102
"@typescript-eslint/eslint-plugin": "^7.2.0",
103103
"@typescript-eslint/parser": "^7.2.0",
104-
"@vitest/coverage-v8": "^1.4.0",
104+
"@vitest/coverage-v8": "^2.1.5",
105105
"eslint": "^8.57.0",
106106
"eslint-config-prettier": "^9.1.0",
107107
"eslint-import-resolver-typescript": "^3.6.1",
@@ -113,11 +113,11 @@
113113
"eslint-plugin-unicorn": "^53.0.0",
114114
"i18next": "^23.10.1",
115115
"prettier": "^3.2.4",
116-
"remix-i18next": "^6.0.0",
117-
"typescript": "^5.3.3",
118-
"vite": "^5.1.6",
119-
"vite-tsconfig-paths": "^4.3.2",
120-
"vitest": "^1.4.0",
116+
"remix-i18next": "^7.0.0",
117+
"typescript": "^5.7.2",
118+
"vite": "^5.4.11",
119+
"vite-tsconfig-paths": "^5.1.3",
120+
"vitest": "^2.1.5",
121121
"zod": "^3.22.4"
122122
}
123123
}

src/cloudflare.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import type { Context } from "hono";
22

3+
import { createWorkersKVSessionStorage } from "@react-router/cloudflare";
4+
import { createMiddleware } from "hono/factory";
5+
import { cacheHeader } from "pretty-cache-header";
36
import {
47
CookieOptions,
58
SessionData,
6-
createWorkersKVSessionStorage,
79
createCookieSessionStorage,
8-
} from "@remix-run/cloudflare";
9-
import { createMiddleware } from "hono/factory";
10-
import { cacheHeader } from "pretty-cache-header";
10+
} from "react-router";
1111

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

src/handler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import type { AppLoadContext, ServerBuild } from "@remix-run/server-runtime";
21
import type { Context } from "hono";
2+
import type { AppLoadContext, ServerBuild } from "react-router";
33

4-
import { createRequestHandler } from "@remix-run/server-runtime";
54
import { createMiddleware } from "hono/factory";
5+
import { createRequestHandler } from "react-router";
66

77
export interface RemixMiddlewareOptions {
88
build: ServerBuild;
@@ -25,4 +25,4 @@ export function remix({
2525
});
2626
}
2727

28-
export { createRequestHandler } from "@remix-run/server-runtime";
28+
export { createRequestHandler } from "react-router";

src/i18next.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import type { Context } from "hono";
22
import type { RemixI18NextOption } from "remix-i18next/server";
33

44
import { createMiddleware } from "hono/factory";
5-
import { Namespace, TFunction } from "i18next";
5+
import { FlatNamespace, TFunction } from "i18next";
66
import { RemixI18Next } from "remix-i18next/server";
77

8-
const i18nSymbol = Symbol();
9-
const LocaleSymbol = Symbol();
10-
const TSymbol = Symbol();
8+
const i18nSymbol = Symbol().toString();
9+
const LocaleSymbol = Symbol().toString();
10+
const TSymbol = Symbol().toString();
1111

1212
export function i18next(options: RemixI18NextOption | RemixI18Next) {
1313
return createMiddleware(async (c, next) => {
@@ -46,10 +46,9 @@ i18next.getLocale = function getLocale(c: Context) {
4646
return locale;
4747
};
4848

49-
i18next.getFixedT = function getFixedT<Ns extends Namespace = "translation">(
50-
c: Context,
51-
{ namespace }: { namespace?: Ns } = {},
52-
) {
49+
i18next.getFixedT = function getFixedT<
50+
Ns extends FlatNamespace = "translation",
51+
>(c: Context, { namespace }: { namespace?: Ns } = {}) {
5352
// If `namespace` is set, we return a new `t` function that is bound to the
5453
// given namespace. Otherwise, we return the default `t` function.
5554
if (namespace) {

src/session.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
import type {
2-
Session,
3-
SessionData,
4-
SessionStorage,
5-
} from "@remix-run/server-runtime";
61
import type { Context } from "hono";
2+
import type { Session, SessionData, SessionStorage } from "react-router";
73

84
import { createMiddleware } from "hono/factory";
95

10-
const sessionStorageSymbol = Symbol();
11-
const sessionSymbol = Symbol();
6+
type Env = {
7+
Variables: Record<symbol, unknown>;
8+
};
9+
10+
const sessionStorageKey = Symbol();
11+
const sessionKey = Symbol();
1212

1313
export function session<Data = SessionData, FlashData = Data>(options: {
1414
autoCommit?: boolean;
1515
createSessionStorage(c: Context): SessionStorage<Data, FlashData>;
1616
}) {
17-
return createMiddleware(async (c, next) => {
17+
return createMiddleware<Env>(async (c, next) => {
1818
let sessionStorage = options.createSessionStorage(c);
1919

20-
c.set(sessionStorageSymbol, sessionStorage);
20+
c.set(sessionStorageKey, sessionStorage);
2121

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

3434
// And make it available with c.get(sessionSymbol).
35-
c.set(sessionSymbol, session);
35+
c.set(sessionKey, session);
3636

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

4747
export function getSessionStorage<Data = SessionData, FlashData = Data>(
48-
c: Context,
48+
c: Context<Env>,
4949
): SessionStorage<Data, FlashData> {
50-
let sessionStorage = c.get(sessionStorageSymbol);
50+
let sessionStorage = c.get(sessionStorageKey);
5151
if (!sessionStorage) {
5252
throw new Error("A session middleware was not set.");
5353
}
5454
return sessionStorage as SessionStorage<Data, FlashData>;
5555
}
5656

5757
export function getSession<Data = SessionData, FlashData = Data>(
58-
c: Context,
58+
c: Context<Env>,
5959
): Session<Data, FlashData> {
60-
let session = c.get(sessionSymbol);
60+
let session = c.get(sessionKey);
6161
if (!session) {
6262
throw new Error("A session middleware was not set.");
6363
}

test/cloudflare.test.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import {
2-
createCookieSessionStorage,
3-
createWorkersKVSessionStorage,
4-
} from "@remix-run/cloudflare";
1+
import { createWorkersKVSessionStorage } from "@react-router/cloudflare";
52
import { Context } from "hono";
63
import { createMiddleware } from "hono/factory";
4+
import { createCookieSessionStorage } from "react-router";
75
import { describe, test, expect, vi, beforeEach, afterAll } from "vitest";
86

97
import {
@@ -13,9 +11,13 @@ import {
1311
} from "../src/cloudflare";
1412
import { session } from "../src/session";
1513

16-
vi.mock("@remix-run/cloudflare", () => {
14+
vi.mock("@react-router/cloudflare", () => {
1715
return {
1816
createWorkersKVSessionStorage: vi.fn(),
17+
};
18+
});
19+
vi.mock("react-router", () => {
20+
return {
1921
createCookieSessionStorage: vi.fn(),
2022
};
2123
});

test/handler.test.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ServerBuild } from "@remix-run/server-runtime";
1+
import type { ServerBuild } from "react-router";
22

33
import { Hono } from "hono";
44
import { describe, test, expect, vi, beforeEach, afterAll } from "vitest";
@@ -29,11 +29,7 @@ const build = {
2929
default: () => new Response("body"),
3030
},
3131
},
32-
future: {
33-
v3_fetcherPersist: true,
34-
v3_relativeSplatPath: true,
35-
v3_throwAbortReason: true,
36-
},
32+
future: {},
3733
publicPath: "/",
3834
routes: {
3935
root: {
@@ -45,7 +41,6 @@ const build = {
4541
},
4642
},
4743
isSpaMode: false,
48-
mode: "production",
4944
} satisfies ServerBuild;
5045

5146
describe(remix.name, () => {

test/session.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { createCookieSessionStorage } from "@remix-run/cloudflare";
21
import { Context } from "hono";
2+
import { createCookieSessionStorage } from "react-router";
33
import { describe, test, expect, vi, beforeEach, afterAll } from "vitest";
44

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

7-
vi.mock("@remix-run/node", () => {
7+
vi.mock("@react-router/node", () => {
88
return {
99
createCookieSessionStorage: vi.fn(),
1010
};

tsconfig.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
{
22
"compilerOptions": {
3-
"lib": ["ES2019"],
3+
"lib": ["ES2020"],
44
"esModuleInterop": true,
55
"module": "NodeNext",
66
"moduleResolution": "NodeNext",
7-
"target": "ES2019",
7+
"target": "ES2020",
88
"strict": true,
99
"skipLibCheck": true,
1010
"declaration": true,
11+
"types": ["@cloudflare/workers-types"],
1112
"baseUrl": ".", // This must be specified if "paths" is specified
1213
"paths": {
1314
"remix-hono/cloudflare": ["./build/cloudflare"] // relative to "baseUrl"
1415
}
1516
},
1617
"exclude": ["node_modules"],
17-
"include": ["src/**/*.ts", "@cloudflare/workers-types"]
18+
"include": ["src/**/*.ts"]
1819
}

0 commit comments

Comments
 (0)