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

routes.ts: Add routes-option-adapter package #10127

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion integration/helpers/node-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
},
"devDependencies": {
"@remix-run/dev": "workspace:*",
"@remix-run/route-config": "workspace:*",
"@remix-run/fs-routes": "workspace:*",
"@remix-run/route-config": "workspace:*",
"@remix-run/routes-option-adapter": "workspace:*",
"@vanilla-extract/css": "^1.10.0",
"@vanilla-extract/vite-plugin": "^3.9.2",
"@types/react": "^18.2.20",
Expand Down
38 changes: 33 additions & 5 deletions integration/vite-fs-routes-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,22 @@ test.describe("fs-routes", () => {
"app/routes.ts": js`
import { type RouteConfig } from "@remix-run/route-config";
import { flatRoutes } from "@remix-run/fs-routes";

export const routes: RouteConfig = flatRoutes({
rootDirectory: "fs-routes",
ignoredRouteFiles: ["**/ignored-route.*"],
});
import { routesOptionAdapter } from "@remix-run/routes-option-adapter";

export const routes: RouteConfig = [
...await flatRoutes({
rootDirectory: "fs-routes",
ignoredRouteFiles: ["**/ignored-route.*"],
}),

// Ensure back compat layer works
...await routesOptionAdapter(async (defineRoutes) => {
// Ensure async routes work
return defineRoutes((route) => {
route("/routes/option/adapter/route", "routes-option-adapter-route.tsx")
});
})
];
`,
"app/root.tsx": js`
import { Links, Meta, Outlet, Scripts } from "@remix-run/react";
Expand Down Expand Up @@ -81,6 +92,12 @@ test.describe("fs-routes", () => {
}
`,

"app/routes-option-adapter-route.tsx": js`
export default function () {
return <h2>Routes Option Adapter Route</h2>;
}
`,

"app/fs-routes/.dotfile": `
DOTFILE SHOULD BE IGNORED
`,
Expand Down Expand Up @@ -176,6 +193,17 @@ test.describe("fs-routes", () => {
</div>`);
});

test("renders matching routes (routes option adapter)", async ({
page,
}) => {
let app = new PlaywrightFixture(appFixture, page);
await app.goto("/routes/option/adapter/route");
expect(await app.getHtml("#content")).toBe(`<div id="content">
<h1>Root</h1>
<h2>Routes Option Adapter Route</h2>
</div>`);
});

test("renders matching routes (route with escaped leading dot)", async ({
page,
}) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { route } from "@remix-run/route-config";

import { routeManifestToRouteConfig } from "../manifest";
import { type RouteConfig, routeManifestToRouteConfig } from "../config/routes";

const clean = (obj: any) => cleanUndefined(cleanIds(obj));

Expand Down Expand Up @@ -43,14 +41,27 @@ describe("routeManifestToRouteConfig", () => {
caseSensitive: true,
},
});
let routeConfig = [
route("/", "routes/home.js"),
route("inbox", "routes/inbox.js", [
route("/", "routes/inbox/index.js", { index: true }),
route(":messageId", "routes/inbox/$messageId.js", {
caseSensitive: true,
}),
]),
let routeConfig: RouteConfig = [
{
path: "/",
file: "routes/home.js",
},
{
path: "inbox",
file: "routes/inbox.js",
children: [
{
path: "/",
file: "routes/inbox/index.js",
index: true,
},
{
path: ":messageId",
file: "routes/inbox/$messageId.js",
caseSensitive: true,
},
],
},
];

expect(clean(routeManifestConfig)).toEqual(clean(routeConfig));
Expand Down
39 changes: 39 additions & 0 deletions packages/remix-dev/config/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,45 @@ export interface RouteManifest {
[routeId: string]: RouteManifestEntry;
}

export function routeManifestToRouteConfig(
routeManifest: RouteManifest,
rootId = "root"
): RouteConfigEntry[] {
let routeConfigById: {
[id: string]: Omit<RouteConfigEntry, "id"> &
Required<Pick<RouteConfigEntry, "id">>;
} = {};

for (let id in routeManifest) {
let route = routeManifest[id];
routeConfigById[id] = {
id: route.id,
file: route.file,
path: route.path,
index: route.index,
caseSensitive: route.caseSensitive,
};
}

let routeConfig: RouteConfigEntry[] = [];

for (let id in routeConfigById) {
let route = routeConfigById[id];
let parentId = routeManifest[route.id].parentId;
if (parentId === rootId) {
routeConfig.push(route);
} else {
let parentRoute = parentId && routeConfigById[parentId];
if (parentRoute) {
parentRoute.children = parentRoute.children || [];
parentRoute.children.push(route);
}
}
}

return routeConfig;
}

/**
* Configuration for an individual route, for use within `routes.ts`. As a
* convenience, route config entries can be created with the {@link route},
Expand Down
9 changes: 8 additions & 1 deletion packages/remix-dev/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@ export * as cli from "./cli/index";

export type { Manifest as AssetsManifest } from "./manifest";
export type {
DefineRoutesFunction as UNSAFE_DefineRoutesFunction,
RouteManifest as UNSAFE_RouteManifest,
RouteManifestEntry as UNSAFE_RouteManifestEntry,
RouteConfig as UNSAFE_RouteConfig,
RouteConfigEntry as UNSAFE_RouteConfigEntry,
} from "./config/routes";
export { getRouteConfigAppDirectory as UNSAFE_getRouteConfigAppDirectory } from "./config/routes";
export {
defineRoutes as UNSAFE_defineRoutes,
routeManifestToRouteConfig as UNSAFE_routeManifestToRouteConfig,
getRouteConfigAppDirectory as UNSAFE_getRouteConfigAppDirectory,
} from "./config/routes";
export { getDependenciesToBundle } from "./dependencies";
export type {
BuildManifest,
Expand Down
5 changes: 4 additions & 1 deletion packages/remix-fs-routes/flatRoutes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import fs from "node:fs";
import path from "node:path";
import { makeRe } from "minimatch";
import type {
UNSAFE_RouteManifest as RouteManifest,
UNSAFE_RouteManifestEntry as RouteManifestEntry,
} from "@remix-run/dev";

import type { RouteManifest, RouteManifestEntry } from "./manifest";
import { normalizeSlashes } from "./normalizeSlashes";

export const routeModuleExts = [".js", ".jsx", ".ts", ".tsx", ".md", ".mdx"];
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-fs-routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import fs from "node:fs";
import path from "node:path";
import { UNSAFE_routeManifestToRouteConfig as routeManifestToRouteConfig } from "@remix-run/dev";
import {
type RouteConfigEntry,
getAppDirectory,
} from "@remix-run/route-config";

import { routeManifestToRouteConfig } from "./manifest";
import { flatRoutes as flatRoutesImpl } from "./flatRoutes";
import { normalizeSlashes } from "./normalizeSlashes";

Expand Down
53 changes: 0 additions & 53 deletions packages/remix-fs-routes/manifest.ts

This file was deleted.

4 changes: 3 additions & 1 deletion packages/remix-fs-routes/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@remix-run/fs-routes",
"version": "2.13.1",
"description": "Config-based file system routing conventions for Remix",
"description": "Config-based file system routing conventions, for use within routes.ts",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
},
Expand All @@ -27,10 +27,12 @@
"minimatch": "^9.0.0"
},
"devDependencies": {
"@remix-run/dev": "workspace:*",
"@remix-run/route-config": "workspace:*",
"typescript": "^5.1.6"
},
"peerDependencies": {
"@remix-run/dev": "workspace:*",
"@remix-run/route-config": "workspace:*",
"typescript": "^5.1.0"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/remix-route-config/package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "@remix-run/route-config",
"version": "2.13.1",
"description": "Config-based routing for Remix",
"description": "Config-based routing utilities, for use within routes.ts",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/remix-run/remix",
"directory": "packages/remix-fs-routes"
"directory": "packages/remix-route-config"
},
"license": "MIT",
"main": "dist/index.js",
Expand Down
13 changes: 13 additions & 0 deletions packages/remix-routes-option-adapter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Welcome to Remix!

[Remix](https://remix.run) is a web framework that helps you build better websites with React.

To get started, open a new shell and run:

```sh
npx create-remix@latest
```

Then follow the prompts you see in your terminal.

For more information about Remix, [visit remix.run](https://remix.run)!
24 changes: 24 additions & 0 deletions packages/remix-routes-option-adapter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
type UNSAFE_DefineRoutesFunction as DefineRoutesFunction,
UNSAFE_defineRoutes as defineRoutes,
UNSAFE_routeManifestToRouteConfig as routeManifestToRouteConfig,
} from "@remix-run/dev";
import { type RouteConfigEntry } from "@remix-run/route-config";

export type { DefineRoutesFunction };

/**
* Adapter for [Remix's `routes` config
* option](https://remix.run/docs/en/v2/file-conventions/vite-config#routes),
* for use within `routes.ts`.
*/
export async function routesOptionAdapter(
routes: (
defineRoutes: DefineRoutesFunction
) =>
| ReturnType<DefineRoutesFunction>
| Promise<ReturnType<DefineRoutesFunction>>
): Promise<RouteConfigEntry[]> {
let routeManifest = await routes(defineRoutes);
return routeManifestToRouteConfig(routeManifest);
}
53 changes: 53 additions & 0 deletions packages/remix-routes-option-adapter/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "@remix-run/routes-option-adapter",
"version": "2.13.1",
"description": "Adapter for Remix's \"routes\" config option, for use within routes.ts",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/remix-run/remix",
"directory": "packages/remix-routes-option-adapter"
},
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"scripts": {
"tsc": "tsc"
},
"dependencies": {
"minimatch": "^9.0.0"
},
"devDependencies": {
"@remix-run/dev": "workspace:*",
"@remix-run/route-config": "workspace:*",
"typescript": "^5.1.6"
},
"peerDependencies": {
"@remix-run/dev": "workspace:*",
"@remix-run/route-config": "workspace:*",
"typescript": "^5.1.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
},
"engines": {
"node": ">=18.0.0"
},
"files": [
"dist/",
"CHANGELOG.md",
"LICENSE.md",
"README.md"
]
}
Loading