From f1f48ab199427bac64e49b09bc01d6ce09b9ee96 Mon Sep 17 00:00:00 2001 From: Atila Fassina Date: Sun, 15 Mar 2026 01:03:49 +0100 Subject: [PATCH] add support for v2 CLI flag --- packages/create/src/create-start.ts | 19 +++++---- packages/create/src/index.ts | 59 ++++++++++++++++++++------ packages/create/src/utils/constants.ts | 44 +++++++++++++++---- 3 files changed, 91 insertions(+), 31 deletions(-) diff --git a/packages/create/src/create-start.ts b/packages/create/src/create-start.ts index cde6000..90c3fc1 100644 --- a/packages/create/src/create-start.ts +++ b/packages/create/src/create-start.ts @@ -2,35 +2,36 @@ import { downloadRepo, GithubFetcher } from "@begit/core"; import { join } from "path"; import { writeFileSync } from "fs"; import { handleTSConversion } from "./utils/ts-conversion"; -import { GIT_IGNORE, StartTemplate } from "./utils/constants"; +import { GIT_IGNORE, StartTemplate, StartTemplateV2 } from "./utils/constants"; export type CreateStartArgs = { - template: StartTemplate; + template: StartTemplate | StartTemplateV2; destination: string; }; -export const createStartTS = ({ template, destination }: CreateStartArgs) => { +export const createStartTS = ({ template, destination }: CreateStartArgs, v2?: boolean) => { + const subdir = v2 ? `solid-start/v2/${template}` : `solid-start/${template}`; return downloadRepo( { - repo: { owner: "solidjs", name: "templates", subdir: `solid-start/${template}` }, + repo: { owner: "solidjs", name: "templates", subdir }, dest: destination, }, GithubFetcher, ); }; -export const createStartJS = async ({ template, destination }: CreateStartArgs) => { +export const createStartJS = async ({ template, destination }: CreateStartArgs, v2?: boolean) => { // Create typescript project in `/.project` // then transpile this to javascript and clean up const tempDir = join(destination, ".project"); - await createStartTS({ template, destination: tempDir }); + await createStartTS({ template, destination: tempDir }, v2); await handleTSConversion(tempDir, destination); // Add .gitignore writeFileSync(join(destination, ".gitignore"), GIT_IGNORE); }; -export const createStart = (args: CreateStartArgs, transpile?: boolean) => { +export const createStart = (args: CreateStartArgs, transpile?: boolean, v2?: boolean) => { if (transpile) { - return createStartJS(args); + return createStartJS(args, v2); } - return createStartTS(args); + return createStartTS(args, v2); }; diff --git a/packages/create/src/index.ts b/packages/create/src/index.ts index 525d048..fad16b6 100644 --- a/packages/create/src/index.ts +++ b/packages/create/src/index.ts @@ -3,13 +3,7 @@ import { createVanilla } from "./create-vanilla"; import * as p from "@clack/prompts"; import { cancelable, spinnerify } from "@solid-cli/utils/ui"; import { createStart } from "./create-start"; -import { - getTemplatesList, - GIT_IGNORE, - isValidTemplate, - PROJECT_TYPES, - ProjectType, -} from "./utils/constants"; +import { getTemplatesList, GIT_IGNORE, isValidTemplate, PROJECT_TYPES, ProjectType } from "./utils/constants"; import { detectPackageManager } from "@solid-cli/utils/package-manager"; import { existsSync, writeFileSync } from "node:fs"; import { join } from "node:path"; @@ -53,6 +47,11 @@ export const createSolid = (version: string) => alias: "s", description: "Create a SolidStart project", }, + "v2": { + type: "boolean", + required: false, + description: "Create a SolidStart v2 project", + }, "library": { type: "boolean", required: false, @@ -87,12 +86,19 @@ export const createSolid = (version: string) => vanilla, ts, js, + v2, }, }) { // Show prompts for any unknown arguments let projectName = projectNamePositional ?? projectNameOptional; let template = templatePositional ?? templateOptional; - let projectType: ProjectType | undefined = solidstart ? "start" : (vanilla ? "vanilla" : (library ? "library" : undefined)); + let projectType: ProjectType | undefined = solidstart + ? "start" + : vanilla + ? "vanilla" + : library + ? "library" + : undefined; // False if user has selected ts, true if they have selected js, and undefined if they've done neither let useJS = ts ? !ts : js ? js : undefined; projectName ??= await cancelable( @@ -108,10 +114,30 @@ export const createSolid = (version: string) => })), }), ); + if (!projectType) return; + + let useV2: string | undefined; + if (projectType === "start") { + useV2 = v2 + ? "v2" + : await cancelable( + p.select({ + message: "Which version of SolidStart?", + initialValue: "v2", + options: [ + { value: "v2", label: "v2 (pre-release, recommended)" }, + { value: "v1", label: "v1 (stable)" }, + ], + }), + ); + } + const isV2 = useV2 === "v2"; + // Don't offer javascript if `projectType` is library useJS ??= projectType === "library" ? false : !(await cancelable(p.confirm({ message: "Use Typescript?" }))); - const template_opts = getTemplatesList(projectType); + if (!projectType) return; + const template_opts = getTemplatesList(projectType, isV2); template ??= await cancelable( p.select({ message: "Which template would you like to use?", @@ -122,13 +148,15 @@ export const createSolid = (version: string) => }), ); + if (!template) return; + // Need to transpile if the user wants Jabascript, but their selected template isn't Javascript const transpileToJS = useJS && !template.startsWith("js"); - if (projectType === "start" && isValidTemplate("start", template)) { + if (projectType === "start" && isValidTemplate("start", template, isV2)) { await spinnerify({ startText: "Creating project", finishText: "Project created 🎉", - fn: () => createStart({ template, destination: projectName }, transpileToJS), + fn: () => createStart({ template, destination: projectName }, transpileToJS, isV2), }); } else if (projectType === "library" && isValidTemplate("library", template)) { await spinnerify({ @@ -142,8 +170,7 @@ export const createSolid = (version: string) => finishText: "Project created 🎉", fn: () => createVanilla({ template, destination: projectName }, transpileToJS), }); - } - else { + } else { p.log.error(`Template ${template} is not valid for project type ${projectType}`); process.exit(0); } @@ -154,7 +181,11 @@ export const createSolid = (version: string) => if (existsSync(readmePath)) { const contents = (await readFile(readmePath)).toString(); if (!contents.includes("This project was created with the [Solid CLI]")) - await writeFile(readmePath, contents + "\n## This project was created with the [Solid CLI](https://github.com/solidjs-community/solid-cli)\n") + await writeFile( + readmePath, + contents + + "\n## This project was created with the [Solid CLI](https://github.com/solidjs-community/solid-cli)\n", + ); } // Next steps.. const pM = detectPackageManager(); diff --git a/packages/create/src/utils/constants.ts b/packages/create/src/utils/constants.ts index b886591..4d49568 100644 --- a/packages/create/src/utils/constants.ts +++ b/packages/create/src/utils/constants.ts @@ -83,6 +83,24 @@ const START_TEMPLATES = [ export type StartTemplate = (typeof START_TEMPLATES)[number]; +const START_TEMPLATES_V2 = [ + "basic", + "bare", + "hackernews", + "notes", + "with-auth", + "with-drizzle", + "with-mdx", + "with-prisma", + "with-solid-styled", + "with-tailwindcss", + "with-trpc", + "with-unocss", + "with-vitest", +] as const satisfies string[]; + +export type StartTemplateV2 = (typeof START_TEMPLATES_V2)[number]; + /**Supported Library Templates */ export const LIBRARY_TEMPLATES = ["solid-lib-starter"] as const satisfies string[]; export type LibraryTemplate = (typeof LIBRARY_TEMPLATES)[number]; @@ -94,12 +112,18 @@ export type ProjectType = (typeof PROJECT_TYPES)[number]; * Fetches the template list for the project type given * @param projectType type of project */ -export function getTemplatesList(projectType: "vanilla"): StartTemplate[]; -export function getTemplatesList(projectType: "start"): VanillaTemplate[]; -export function getTemplatesList(projectType: "library"): VanillaTemplate[]; -export function getTemplatesList(projectType: ProjectType): VanillaTemplate[] | StartTemplate[] | LibraryTemplate[]; -export function getTemplatesList(projectType: ProjectType) { +export function getTemplatesList(projectType: "vanilla", v2?: boolean): VanillaTemplate[]; +export function getTemplatesList(projectType: "start", v2?: boolean): StartTemplate[] | StartTemplateV2[]; +export function getTemplatesList(projectType: "library", v2?: boolean): LibraryTemplate[]; +export function getTemplatesList( + projectType: ProjectType, + v2?: boolean, +): VanillaTemplate[] | StartTemplate[] | StartTemplateV2[] | LibraryTemplate[]; +export function getTemplatesList(projectType: ProjectType, v2?: boolean) { if (projectType === "start") { + if (v2) { + return START_TEMPLATES_V2 as unknown as StartTemplateV2[]; + } return START_TEMPLATES as StartTemplate[]; } else if (projectType === "library") { return LIBRARY_TEMPLATES as LibraryTemplate[]; @@ -114,9 +138,13 @@ export function getTemplatesList(projectType: ProjectType) { * @returns the template string if it is valid, undefined if not */ export function isValidTemplate(type: "vanilla", maybe_template: string): maybe_template is VanillaTemplate; -export function isValidTemplate(type: "start", maybe_template: string): maybe_template is StartTemplate; +export function isValidTemplate( + type: "start", + maybe_template: string, + v2?: boolean, +): maybe_template is StartTemplate | StartTemplateV2; export function isValidTemplate(type: "library", maybe_template: string): maybe_template is LibraryTemplate; -export function isValidTemplate(type: ProjectType, maybe_template: string) { - const templates = getTemplatesList(type); +export function isValidTemplate(type: ProjectType, maybe_template: string, v2?: boolean) { + const templates = getTemplatesList(type, v2); return templates.find((t) => t === maybe_template) !== undefined; }