Skip to content
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
19 changes: 10 additions & 9 deletions packages/create/src/create-start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<destination>/.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);
};
59 changes: 45 additions & 14 deletions packages/create/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand All @@ -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?",
Expand All @@ -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({
Expand All @@ -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);
}
Expand All @@ -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();
Expand Down
44 changes: 36 additions & 8 deletions packages/create/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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[];
Expand All @@ -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;
}
Loading