Skip to content

Commit 314b82a

Browse files
dodok8claude
andcommitted
Add SolidStart option to fedify init
Add SolidStart as a web framework option in the `fedify init` command, allowing users to scaffold new Fedify+SolidStart projects. All boilerplate files (app config, middleware, routes, entry points) are provided as templates since no suitable degit template exists for SolidStart. The lookup test skips the solidstart+deno combination because Deno's `links` feature does not populate `node_modules/`, which Vite (used by vinxi) requires for SSR module resolution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f07b076 commit 314b82a

10 files changed

Lines changed: 160 additions & 9 deletions

File tree

packages/init/src/const.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const WEB_FRAMEWORK = [
99
"elysia",
1010
"astro",
1111
"express",
12+
"solidstart",
1213
] as const;
1314

1415
/** All supported message queue backend identifiers. */
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineConfig } from "@solidjs/start/config";
2+
3+
export default defineConfig({
4+
middleware: "src/middleware/index.ts",
5+
server: {
6+
preset: "node-server",
7+
},
8+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Router } from "@solidjs/router";
2+
import { FileRoutes } from "@solidjs/start/router";
3+
import { Suspense } from "solid-js";
4+
5+
export default function App() {
6+
return (
7+
<Router root={(props) => <Suspense>{props.children}</Suspense>}>
8+
<FileRoutes />
9+
</Router>
10+
);
11+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// @refresh reload
2+
import { mount, StartClient } from "@solidjs/start/client";
3+
4+
mount(() => <StartClient />, document.getElementById("app")!);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @refresh reload
2+
import { createHandler, StartServer } from "@solidjs/start/server";
3+
4+
export default createHandler(() => (
5+
<StartServer
6+
document={({ assets, children, scripts }) => (
7+
<html lang="en">
8+
<head>
9+
<meta charset="utf-8" />
10+
<meta name="viewport" content="width=device-width, initial-scale=1" />
11+
{assets}
12+
</head>
13+
<body>
14+
<div id="app">{children}</div>
15+
{scripts}
16+
</body>
17+
</html>
18+
)}
19+
/>
20+
));
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { fedifyMiddleware } from "@fedify/solidstart";
2+
import federation from "../federation.ts";
3+
4+
export default fedifyMiddleware(federation, (_event) => undefined);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export default function Home() {
2+
return (
3+
<main>
4+
<h1>Fedify + SolidStart</h1>
5+
<p>
6+
Try: <code>fedify lookup http://localhost:3000/users/john</code>
7+
</p>
8+
</main>
9+
);
10+
}

packages/init/src/test/lookup.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ const HANDLE = "john";
2020
const STARTUP_TIMEOUT = 30000; // 30 seconds
2121
const CWD = process.cwd();
2222
const BANNED_WFS: WebFramework[] = ["next"];
23+
const BANNED_COMBOS: [WebFramework, PackageManager][] = [
24+
["solidstart", "deno"],
25+
];
2326

2427
/**
2528
* Run servers for all generated apps and test them with the lookup command.
@@ -56,16 +59,21 @@ function filterWebFrameworks(
5659
dirs.map((dir) => dir.split(sep).slice(-4, -3)[0] as WebFramework),
5760
);
5861
const hasBanned = BANNED_WFS.filter((wf) => wfs.has(wf));
59-
if (isEmpty(hasBanned)) {
60-
return dirs;
62+
if (!isEmpty(hasBanned)) {
63+
const bannedLabels = hasBanned.map((wf) => webFrameworks[wf]["label"]);
64+
printErrorMessage`\n${
65+
values(bannedLabels)
66+
} is not supported in lookup test yet.`;
6167
}
62-
const bannedLabels = hasBanned.map((wf) => webFrameworks[wf]["label"]);
63-
printErrorMessage`\n${
64-
values(bannedLabels)
65-
} is not supported in lookup test yet.`;
66-
return dirs.filter((dir) =>
67-
!BANNED_WFS.includes(dir.split(sep).slice(-4, -3)[0] as WebFramework)
68-
);
68+
return dirs.filter((dir) => {
69+
const [wf, pm] = dir.split(sep).slice(-4, -2) as
70+
[WebFramework, PackageManager];
71+
if (BANNED_WFS.includes(wf)) return false;
72+
if (BANNED_COMBOS.some(([bwf, bpm]) => bwf === wf && bpm === pm)) {
73+
return false;
74+
}
75+
return true;
76+
});
6977
}
7078

7179
/**

packages/init/src/webframeworks/mod.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import express from "./express.ts";
55
import hono from "./hono.ts";
66
import next from "./next.ts";
77
import nitro from "./nitro.ts";
8+
import solidstart from "./solidstart.ts";
89

910
/**
1011
* Registry of all supported web framework configurations.
@@ -20,6 +21,7 @@ const webFrameworks: WebFrameworks = {
2021
hono,
2122
next,
2223
nitro,
24+
solidstart,
2325
} as const;
2426

2527
export default webFrameworks;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { PACKAGE_MANAGER } from "../const.ts";
2+
import { PACKAGE_VERSION, readTemplate } from "../lib.ts";
3+
import type { WebFrameworkDescription } from "../types.ts";
4+
import { defaultDenoDependencies, defaultDevDependencies } from "./const.ts";
5+
import { getInstruction } from "./utils.ts";
6+
7+
const solidstartDescription: WebFrameworkDescription = {
8+
label: "SolidStart",
9+
packageManagers: PACKAGE_MANAGER,
10+
defaultPort: 3000,
11+
init: ({ packageManager: pm }) => ({
12+
dependencies: pm === "deno"
13+
? {
14+
...defaultDenoDependencies,
15+
"@solidjs/router": "npm:@solidjs/router@^0.15.4",
16+
"@solidjs/start": "npm:@solidjs/start@^1.3.2",
17+
"solid-js": "npm:solid-js@^1.9.11",
18+
vinxi: "npm:vinxi@^0.5.11",
19+
"@fedify/solidstart": PACKAGE_VERSION,
20+
}
21+
: {
22+
"@solidjs/router": "^0.15.4",
23+
"@solidjs/start": "^1.3.2",
24+
"solid-js": "^1.9.11",
25+
vinxi: "^0.5.11",
26+
"@fedify/solidstart": PACKAGE_VERSION,
27+
},
28+
devDependencies: {
29+
...defaultDevDependencies,
30+
...(pm !== "deno"
31+
? { typescript: "^5.9.3", "@types/node": "^22.17.0" }
32+
: {}),
33+
},
34+
federationFile: "src/federation.ts",
35+
loggingFile: "src/logging.ts",
36+
files: {
37+
"app.config.ts": readTemplate("solidstart/app.config.ts"),
38+
"src/app.tsx": readTemplate("solidstart/src/app.tsx"),
39+
"src/entry-client.tsx": readTemplate("solidstart/src/entry-client.tsx"),
40+
"src/entry-server.tsx": readTemplate("solidstart/src/entry-server.tsx"),
41+
"src/routes/index.tsx": readTemplate("solidstart/src/routes/index.tsx"),
42+
"src/middleware/index.ts": readTemplate(
43+
"solidstart/src/middleware/index.ts",
44+
),
45+
...(pm !== "deno"
46+
? { "eslint.config.ts": readTemplate("defaults/eslint.config.ts") }
47+
: {}),
48+
},
49+
compilerOptions: pm === "deno" ? undefined : {
50+
target: "ESNext",
51+
module: "ESNext",
52+
moduleResolution: "Bundler",
53+
allowSyntheticDefaultImports: true,
54+
esModuleInterop: true,
55+
jsx: "preserve",
56+
jsxImportSource: "solid-js",
57+
strict: true,
58+
noEmit: true,
59+
skipLibCheck: true,
60+
},
61+
tasks: {
62+
dev: pm === "deno"
63+
? "deno run -A npm:vinxi dev"
64+
: pm === "bun"
65+
? "bunx vinxi dev"
66+
: "vinxi dev",
67+
build: pm === "deno"
68+
? "deno run -A npm:vinxi build"
69+
: pm === "bun"
70+
? "bunx vinxi build"
71+
: "vinxi build",
72+
start: pm === "deno"
73+
? "deno run -A npm:vinxi start"
74+
: pm === "bun"
75+
? "bunx vinxi start"
76+
: "vinxi start",
77+
...(pm !== "deno" ? { lint: "eslint ." } : {}),
78+
},
79+
instruction: getInstruction(pm, 3000),
80+
}),
81+
};
82+
83+
export default solidstartDescription;

0 commit comments

Comments
 (0)