add solid

This commit is contained in:
Aman Varshney
2025-05-05 09:51:33 +05:30
parent e9f63be765
commit 4f89b8bc15
41 changed files with 1362 additions and 207 deletions

View File

@@ -17,13 +17,15 @@ export async function getAddonsChoice(
const hasCompatiblePwaFrontend =
frontends?.includes("react-router") ||
frontends?.includes("tanstack-router");
frontends?.includes("tanstack-router") ||
frontends?.includes("solid");
const hasCompatibleTauriFrontend =
frontends?.includes("react-router") ||
frontends?.includes("tanstack-router") ||
frontends?.includes("nuxt") ||
frontends?.includes("svelte");
frontends?.includes("svelte") ||
frontends?.includes("solid");
const allPossibleOptions: AddonOption[] = [
{

View File

@@ -16,6 +16,7 @@ export async function getApiChoice(
const includesNuxt = frontend?.includes("nuxt");
const includesSvelte = frontend?.includes("svelte");
const includesSolid = frontend?.includes("solid");
let apiOptions = [
{
@@ -30,13 +31,13 @@ export async function getApiChoice(
},
];
if (includesNuxt || includesSvelte) {
if (includesNuxt || includesSvelte || includesSolid) {
apiOptions = [
{
value: "orpc" as const,
label: "oRPC",
hint: `End-to-end type-safe APIs (Required for ${
includesNuxt ? "Nuxt" : "Svelte"
includesNuxt ? "Nuxt" : includesSvelte ? "Svelte" : "Solid"
} frontend)`,
},
];
@@ -45,7 +46,10 @@ export async function getApiChoice(
const apiType = await select<ProjectApi>({
message: "Select API type",
options: apiOptions,
initialValue: includesNuxt || includesSvelte ? "orpc" : DEFAULT_CONFIG.api,
initialValue:
includesNuxt || includesSvelte || includesSolid
? "orpc"
: DEFAULT_CONFIG.api,
});
if (isCancel(apiType)) {
@@ -53,7 +57,7 @@ export async function getApiChoice(
process.exit(0);
}
if ((includesNuxt || includesSvelte) && apiType !== "orpc") {
if ((includesNuxt || includesSvelte || includesSolid) && apiType !== "orpc") {
return "orpc";
}

View File

@@ -1,43 +1,62 @@
import { cancel, isCancel, select } from "@clack/prompts";
import pc from "picocolors";
import { DEFAULT_CONFIG } from "../constants";
import type { ProjectBackend } from "../types";
import type { ProjectBackend, ProjectFrontend } from "../types";
export async function getBackendFrameworkChoice(
backendFramework?: ProjectBackend,
frontends?: ProjectFrontend[],
): Promise<ProjectBackend> {
if (backendFramework !== undefined) return backendFramework;
const hasIncompatibleFrontend = frontends?.some(
(f) => f === "nuxt" || f === "solid",
);
const backendOptions: Array<{
value: ProjectBackend;
label: string;
hint: string;
}> = [
{
value: "hono" as const,
label: "Hono",
hint: "Lightweight, ultrafast web framework",
},
{
value: "next" as const,
label: "Next.js",
hint: "Full-stack framework with API routes",
},
{
value: "express" as const,
label: "Express",
hint: "Fast, unopinionated, minimalist web framework for Node.js",
},
{
value: "elysia" as const,
label: "Elysia",
hint: "Ergonomic web framework for building backend servers",
},
];
if (!hasIncompatibleFrontend) {
backendOptions.push({
value: "convex" as const,
label: "Convex",
hint: "Reactive backend-as-a-service platform",
});
}
let initialValue = DEFAULT_CONFIG.backend;
if (hasIncompatibleFrontend && initialValue === "convex") {
initialValue = "hono";
}
const response = await select<ProjectBackend>({
message: "Select backend framework",
options: [
{
value: "hono",
label: "Hono",
hint: "Lightweight, ultrafast web framework",
},
{
value: "next",
label: "Next.js",
hint: "Full-stack framework with API routes",
},
{
value: "express",
label: "Express",
hint: "Fast, unopinionated, minimalist web framework for Node.js",
},
{
value: "elysia",
label: "Elysia",
hint: "Ergonomic web framework for building backend servers",
},
{
value: "convex",
label: "Convex",
hint: "Reactive backend-as-a-service platform",
},
],
initialValue: DEFAULT_CONFIG.backend,
options: backendOptions,
initialValue,
});
if (isCancel(response)) {

View File

@@ -53,8 +53,10 @@ export async function gatherConfig(
projectName: async () => {
return getProjectName(flags.projectName);
},
frontend: () => getFrontendChoice(flags.frontend),
backend: () => getBackendFrameworkChoice(flags.backend),
frontend: ({ results }) =>
getFrontendChoice(flags.frontend, flags.backend),
backend: ({ results }) =>
getBackendFrameworkChoice(flags.backend, results.frontend),
runtime: ({ results }) =>
getRuntimeChoice(flags.runtime, results.backend),
database: ({ results }) =>

View File

@@ -37,6 +37,7 @@ export async function getExamplesChoice(
"next",
"nuxt",
"svelte",
"solid",
].includes(f),
) ?? false;
const noFrontendSelected = !frontends || frontends.length === 0;
@@ -52,7 +53,7 @@ export async function getExamplesChoice(
},
];
if (backend !== "elysia") {
if (backend !== "elysia" && !frontends?.includes("solid")) {
options.push({
value: "ai" as const,
label: "AI Chat",

View File

@@ -1,10 +1,11 @@
import { cancel, isCancel, multiselect, select } from "@clack/prompts";
import pc from "picocolors";
import { DEFAULT_CONFIG } from "../constants";
import type { ProjectFrontend } from "../types";
import type { ProjectBackend, ProjectFrontend } from "../types";
export async function getFrontendChoice(
frontendOptions?: ProjectFrontend[],
backend?: ProjectBackend,
): Promise<ProjectFrontend[]> {
if (frontendOptions !== undefined) return frontendOptions;
@@ -23,17 +24,7 @@ export async function getFrontendChoice(
},
],
required: false,
initialValues: DEFAULT_CONFIG.frontend.some(
(f) =>
f === "tanstack-router" ||
f === "react-router" ||
f === "tanstack-start" ||
f === "next" ||
f === "nuxt" ||
f === "svelte",
)
? ["web"]
: [],
initialValues: ["web"],
});
if (isCancel(frontendTypes)) {
@@ -44,50 +35,55 @@ export async function getFrontendChoice(
const result: ProjectFrontend[] = [];
if (frontendTypes.includes("web")) {
const allWebOptions = [
{
value: "tanstack-router" as const,
label: "TanStack Router",
hint: "Modern and scalable routing for React Applications",
},
{
value: "react-router" as const,
label: "React Router",
hint: "A userobsessed, standardsfocused, multistrategy router",
},
{
value: "next" as const,
label: "Next.js",
hint: "The React Framework for the Web",
},
{
value: "nuxt" as const,
label: "Nuxt",
hint: "The Progressive Web Framework for Vue.js",
},
{
value: "svelte" as const,
label: "Svelte",
hint: "web development for the rest of us",
},
{
value: "solid" as const,
label: "Solid",
hint: "Simple and performant reactivity for building user interfaces",
},
{
value: "tanstack-start" as const,
label: "TanStack Start (beta)",
hint: "SSR, Server Functions, API Routes and more with TanStack Router",
},
];
const webOptions = allWebOptions.filter((option) => {
if (backend === "convex") {
return option.value !== "nuxt" && option.value !== "solid";
}
return true;
});
const webFramework = await select<ProjectFrontend>({
message: "Choose frontend framework",
options: [
{
value: "tanstack-router",
label: "TanStack Router",
hint: "Modern and scalable routing for React Applications",
},
{
value: "react-router",
label: "React Router",
hint: "A userobsessed, standardsfocused, multistrategy router",
},
{
value: "next",
label: "Next.js",
hint: "The React Framework for the Web",
},
{
value: "nuxt",
label: "Nuxt",
hint: "The Progressive Web Framework for Vue.js",
},
{
value: "svelte",
label: "Svelte",
hint: "web development for the rest of us",
},
{
value: "tanstack-start",
label: "TanStack Start (beta)",
hint: "SSR, Server Functions, API Routes and more with TanStack Router",
},
],
initialValue:
DEFAULT_CONFIG.frontend.find(
(f) =>
f === "tanstack-router" ||
f === "react-router" ||
f === "tanstack-start" ||
f === "next" ||
f === "nuxt" ||
f === "svelte",
) || "tanstack-router",
options: webOptions,
initialValue: DEFAULT_CONFIG.frontend[0],
});
if (isCancel(webFramework)) {