dont allow examples when api is none (#243)

This commit is contained in:
Aman Varshney
2025-05-10 22:28:05 +05:30
committed by GitHub
parent 2924b817a3
commit 6a339bca1f
12 changed files with 188 additions and 241 deletions

View File

@@ -399,12 +399,11 @@ function processAndValidateFlags(
config.api = options.api as ProjectApi;
if (options.api === "none") {
if (
options.backend &&
options.backend !== "convex" &&
options.backend !== "none"
options.examples &&
!(options.examples.length === 1 && options.examples[0] === "none")
) {
consola.fatal(
`'--api none' is only supported with '--backend convex' or '--backend none'. Please choose a different API setting or use '--backend convex' or '--backend none'.`,
"Cannot use '--examples' when '--api' is set to 'none'. Please remove the --examples flag or choose an API type.",
);
process.exit(1);
}
@@ -421,12 +420,6 @@ function processAndValidateFlags(
config.backend !== "convex" &&
config.backend !== "none"
) {
if (providedFlags.has("api") && options.api === "none") {
consola.fatal(
`'--api none' is only supported with '--backend convex' or '--backend none'. Please choose 'trpc', 'orpc', or remove the --api flag.`,
);
process.exit(1);
}
if (providedFlags.has("runtime") && options.runtime === "none") {
consola.fatal(
`'--runtime none' is only supported with '--backend convex' or '--backend none'. Please choose 'bun', 'node', or remove the --runtime flag.`,
@@ -782,26 +775,13 @@ function processAndValidateFlags(
consola.fatal(
`tRPC API is not supported with '${
includesNuxt ? "nuxt" : includesSvelte ? "svelte" : "solid"
}' frontend. Please use --api orpc or remove '${
}' frontend. Please use --api orpc or --api none or remove '${
includesNuxt ? "nuxt" : includesSvelte ? "svelte" : "solid"
}' from --frontend.`,
);
process.exit(1);
}
if (
(includesNuxt || includesSvelte || includesSolid) &&
effectiveApi !== "orpc" &&
(!options.api || (options.yes && options.api === "trpc"))
) {
if (config.api !== "none") {
config.api = "orpc";
log.info(
`Due to frontend selection, API has been set to 'orpc'. tRPC is not compatible with Nuxt, Svelte, or Solid Framework`,
);
}
}
if (config.addons && config.addons.length > 0) {
const webSpecificAddons = ["pwa", "tauri"];
const hasWebSpecificAddons = config.addons.some((addon) =>

View File

@@ -1,6 +1,5 @@
import { cancel, isCancel, select } from "@clack/prompts";
import pc from "picocolors";
import { DEFAULT_CONFIG } from "../constants";
import type { ProjectApi, ProjectBackend, ProjectFrontend } from "../types";
export async function getApiChoice(
@@ -29,6 +28,11 @@ export async function getApiChoice(
label: "oRPC",
hint: "End-to-end type-safe APIs that adhere to OpenAPI standards",
},
{
value: "none" as const,
label: "None",
hint: "No API layer (e.g. for full-stack frameworks like Next.js with Route Handlers)",
},
];
if (includesNuxt || includesSvelte || includesSolid) {
@@ -36,20 +40,22 @@ export async function getApiChoice(
{
value: "orpc" as const,
label: "oRPC",
hint: `End-to-end type-safe APIs (Required for ${
hint: `End-to-end type-safe APIs (Recommended for ${
includesNuxt ? "Nuxt" : includesSvelte ? "Svelte" : "Solid"
} frontend)`,
},
{
value: "none" as const,
label: "None",
hint: "No API layer",
},
];
}
const apiType = await select<ProjectApi>({
message: "Select API type",
options: apiOptions,
initialValue:
includesNuxt || includesSvelte || includesSolid
? "orpc"
: DEFAULT_CONFIG.api,
initialValue: apiOptions[0].value,
});
if (isCancel(apiType)) {
@@ -57,9 +63,5 @@ export async function getApiChoice(
process.exit(0);
}
if ((includesNuxt || includesSvelte || includesSolid) && apiType !== "orpc") {
return "orpc";
}
return apiType;
}

View File

@@ -77,6 +77,7 @@ export async function gatherConfig(
results.database,
results.frontend,
results.backend,
results.api,
),
dbSetup: ({ results }) =>
getDBSetupChoice(

View File

@@ -2,6 +2,7 @@ import { cancel, isCancel, multiselect } from "@clack/prompts";
import pc from "picocolors";
import { DEFAULT_CONFIG } from "../constants";
import type {
ProjectApi,
ProjectBackend,
ProjectDatabase,
ProjectExamples,
@@ -13,7 +14,11 @@ export async function getExamplesChoice(
database?: ProjectDatabase,
frontends?: ProjectFrontend[],
backend?: ProjectBackend,
api?: ProjectApi,
): Promise<ProjectExamples[]> {
if (api === "none") {
return [];
}
if (examples !== undefined) return examples;
if (backend === "convex") {

View File

@@ -3,12 +3,14 @@ import "dotenv/config";
import { RPCHandler } from "@orpc/server/fetch";
import { createContext } from "./lib/context";
import { appRouter } from "./routers/index";
{{#if auth}}
import { auth } from "./lib/auth";
{{/if}}
{{/if}}
{{#if (eq api "trpc")}}
import { trpcServer } from "@hono/trpc-server";
import { createContext } from "./lib/context";
import { appRouter } from "./routers/index";
{{/if}}
{{#if auth}}
import { auth } from "./lib/auth";
{{/if}}
import { Hono } from "hono";
import { cors } from "hono/cors";
@@ -18,13 +20,6 @@ import { streamText } from "ai";
import { google } from "@ai-sdk/google";
import { stream } from "hono/streaming";
{{/if}}
{{#if (eq api "trpc")}}
import { createContext } from "./lib/context";
import { appRouter } from "./routers/index";
{{#if auth}}
import { auth } from "./lib/auth";
{{/if}}
{{/if}}
const app = new Hono();

View File

@@ -21,9 +21,7 @@ export const appRouter = {
{{/if}}
};
export type AppRouter = typeof appRouter;
{{/if}}
{{#if (eq api "trpc")}}
{{else if (eq api "trpc")}}
import {
{{#if auth}}protectedProcedure, {{/if}}publicProcedure,
router,
@@ -49,4 +47,7 @@ export const appRouter = router({
{{/if}}
});
export type AppRouter = typeof appRouter;
{{else}}
export const appRouter = {};
export type AppRouter = typeof appRouter;
{{/if}}

View File

@@ -27,7 +27,7 @@ const healthCheck = useQuery($orpc.healthCheck.queryOptions())
<template>
<div class="container mx-auto max-w-3xl px-4 py-2">
<pre class="overflow-x-auto font-mono text-sm whitespace-pre-wrap">{{ TITLE_TEXT }}</pre>
<pre class="overflow-x-auto font-mono text-sm whitespace-pre-wrap">\{{ TITLE_TEXT }}</pre>
<div class="grid gap-6 mt-4">
{{#unless (eq api "none")}}
<section class="rounded-lg border p-4">
@@ -50,10 +50,10 @@ const healthCheck = useQuery($orpc.healthCheck.queryOptions())
Checking...
</template>
<template v-else-if="healthCheck.status.value === 'success'">
Connected ({{ healthCheck.data.value }})
Connected (\{{ healthCheck.data.value }})
</template>
<template v-else-if="healthCheck.status.value === 'error'">
Error: {{ healthCheck.error.value?.message || 'Failed to connect' }}
Error: \{{ healthCheck.error.value?.message || 'Failed to connect' }}
</template>
<template v-else>
Idle

View File

@@ -17,12 +17,12 @@
"babel-plugin-react-compiler": "^19.1.0-rc.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"fumadocs-core": "15.2.10",
"fumadocs-mdx": "11.6.1",
"fumadocs-ui": "15.2.10",
"lucide-react": "^0.503.0",
"fumadocs-core": "15.3.0",
"fumadocs-mdx": "11.6.3",
"fumadocs-ui": "15.3.0",
"lucide-react": "^0.509.0",
"motion": "^12.10.5",
"next": "15.3.1",
"next": "15.3.2",
"next-themes": "^0.4.6",
"nuqs": "^2.4.3",
"react": "^19.1.0",
@@ -32,15 +32,15 @@
"tailwind-merge": "^3.2.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.5",
"@tailwindcss/postcss": "^4.1.6",
"@types/mdx": "^2.0.13",
"@types/node": "22.14.1",
"@types/node": "22.15.17",
"@types/react": "^19.1.3",
"@types/react-dom": "^19.1.3",
"eslint": "^9.26.0",
"eslint-config-next": "15.3.1",
"eslint-config-next": "15.3.2",
"postcss": "^8.5.3",
"tailwindcss": "^4.1.5",
"tailwindcss": "^4.1.6",
"tw-animate-css": "^1.2.9",
"typescript": "^5.8.3"
}

View File

@@ -299,17 +299,8 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => {
message: "Runtime set to 'Bun' (None is only for Convex)",
});
}
if (nextStack.api === "none") {
notes.api.notes.push(
"API 'None' is only for Convex. Defaulting to 'tRPC'.",
);
notes.api.hasIssue = true;
nextStack.api = DEFAULT_STACK.api;
changed = true;
changes.push({
category: "api",
message: "API set to 'tRPC' (None is only for Convex)",
});
if (nextStack.api === "none" && (isConvex || isBackendNone)) {
} else if (nextStack.api === "none" && !(isConvex || isBackendNone)) {
}
if (nextStack.database === "none") {
@@ -1047,11 +1038,13 @@ const StackArchitect = () => {
}
if (catKey === "api") {
if (techId === "none" && !rules.isConvex) {
if (techId !== "none" && (rules.isConvex || rules.isBackendNone)) {
addRule(
category,
techId,
"Disabled: API 'None' is only available with Convex backend.",
rules.isConvex
? "Disabled: Convex backend requires API to be 'None'."
: "Disabled: No backend requires API to be 'None'.",
);
}
if (techId === "trpc" && rules.hasNuxtOrSvelteOrSolid) {

View File

@@ -15,6 +15,13 @@ export const TECH_OPTIONS = {
icon: "/icon/orpc.svg",
color: "from-indigo-400 to-indigo-600",
},
{
id: "none",
name: "No API",
description: "No API layer (API routes disabled)",
icon: "🚫",
color: "from-gray-400 to-gray-600",
},
],
frontend: [
{