cli: organize file structure

This commit is contained in:
Aman Varshney
2025-05-26 00:13:08 +05:30
parent b9c9690e61
commit 1e9c6b2210
40 changed files with 900 additions and 928 deletions

View File

@@ -4,9 +4,12 @@ import consola from "consola";
import { execa } from "execa";
import fs from "fs-extra";
import pc from "picocolors";
import type { ProjectConfig } from "../types";
import { commandExists } from "../utils/command-exists";
import { type EnvVariable, addEnvVariablesToFile } from "./env-setup";
import type { ProjectConfig } from "../../types";
import { commandExists } from "../../utils/command-exists";
import {
type EnvVariable,
addEnvVariablesToFile,
} from "../project-generation/env-setup";
type MongoDBConfig = {
connectionString: string;

View File

@@ -4,9 +4,12 @@ import { consola } from "consola";
import { execa } from "execa";
import fs from "fs-extra";
import pc from "picocolors";
import type { ProjectPackageManager } from "../types";
import { getPackageExecutionCommand } from "../utils/get-package-execution-command";
import { type EnvVariable, addEnvVariablesToFile } from "./env-setup";
import type { PackageManager } from "../../types";
import { getPackageExecutionCommand } from "../../utils/get-package-execution-command";
import {
type EnvVariable,
addEnvVariablesToFile,
} from "../project-generation/env-setup";
type NeonConfig = {
connectionString: string;
@@ -31,7 +34,7 @@ const NEON_REGIONS: NeonRegion[] = [
];
async function executeNeonCommand(
packageManager: ProjectPackageManager,
packageManager: PackageManager,
commandArgsString: string,
spinnerText?: string,
) {
@@ -52,7 +55,7 @@ async function executeNeonCommand(
}
}
async function isNeonAuthenticated(packageManager: ProjectPackageManager) {
async function isNeonAuthenticated(packageManager: PackageManager) {
try {
const commandArgsString = "neonctl projects list";
const result = await executeNeonCommand(packageManager, commandArgsString);
@@ -65,7 +68,7 @@ async function isNeonAuthenticated(packageManager: ProjectPackageManager) {
}
}
async function authenticateWithNeon(packageManager: ProjectPackageManager) {
async function authenticateWithNeon(packageManager: PackageManager) {
try {
await executeNeonCommand(
packageManager,
@@ -82,7 +85,7 @@ async function authenticateWithNeon(packageManager: ProjectPackageManager) {
async function createNeonProject(
projectName: string,
regionId: string,
packageManager: ProjectPackageManager,
packageManager: PackageManager,
) {
try {
const commandArgsString = `neonctl projects create --name ${projectName} --region-id ${regionId} --output json`;
@@ -146,7 +149,7 @@ function displayManualSetupInstructions() {
DATABASE_URL="your_connection_string"`);
}
import type { ProjectConfig } from "../types";
import type { ProjectConfig } from "../../types";
export async function setupNeonPostgres(config: ProjectConfig): Promise<void> {
const { packageManager, projectDir } = config;

View File

@@ -4,10 +4,13 @@ import { consola } from "consola";
import { execa } from "execa";
import fs from "fs-extra";
import pc from "picocolors";
import type { ProjectPackageManager } from "../types";
import { addPackageDependency } from "../utils/add-package-deps";
import { getPackageExecutionCommand } from "../utils/get-package-execution-command";
import { type EnvVariable, addEnvVariablesToFile } from "./env-setup";
import type { PackageManager } from "../../types";
import { addPackageDependency } from "../../utils/add-package-deps";
import { getPackageExecutionCommand } from "../../utils/get-package-execution-command";
import {
type EnvVariable,
addEnvVariablesToFile,
} from "../project-generation/env-setup";
type PrismaConfig = {
databaseUrl: string;
@@ -15,7 +18,7 @@ type PrismaConfig = {
async function initPrismaDatabase(
serverDir: string,
packageManager: ProjectPackageManager,
packageManager: PackageManager,
): Promise<PrismaConfig | null> {
const s = spinner();
try {
@@ -141,7 +144,7 @@ export default prisma;
}
}
import type { ProjectConfig } from "../types";
import type { ProjectConfig } from "../../types";
export async function setupPrismaPostgres(config: ProjectConfig) {
const { packageManager, projectDir } = config;

View File

@@ -4,9 +4,12 @@ import { consola } from "consola";
import { type ExecaError, execa } from "execa";
import fs from "fs-extra";
import pc from "picocolors";
import type { ProjectConfig, ProjectPackageManager } from "../types";
import { getPackageExecutionCommand } from "../utils/get-package-execution-command";
import { type EnvVariable, addEnvVariablesToFile } from "./env-setup";
import type { PackageManager, ProjectConfig } from "../../types";
import { getPackageExecutionCommand } from "../../utils/get-package-execution-command";
import {
type EnvVariable,
addEnvVariablesToFile,
} from "../project-generation/env-setup";
async function writeSupabaseEnvFile(
projectDir: string,
@@ -50,7 +53,7 @@ function extractDbUrl(output: string): string | null {
async function initializeSupabase(
serverDir: string,
packageManager: ProjectPackageManager,
packageManager: PackageManager,
): Promise<boolean> {
log.info("Initializing Supabase project...");
try {
@@ -86,7 +89,7 @@ async function initializeSupabase(
async function startSupabase(
serverDir: string,
packageManager: ProjectPackageManager,
packageManager: PackageManager,
): Promise<string | null> {
log.info("Starting Supabase services (this may take a moment)...");
const supabaseStartCommand = getPackageExecutionCommand(

View File

@@ -12,8 +12,12 @@ import {
import consola from "consola";
import { $ } from "execa";
import pc from "picocolors";
import { commandExists } from "../utils/command-exists";
import { type EnvVariable, addEnvVariablesToFile } from "./env-setup";
import type { ProjectConfig } from "../../types";
import { commandExists } from "../../utils/command-exists";
import {
type EnvVariable,
addEnvVariablesToFile,
} from "../project-generation/env-setup";
type TursoConfig = {
dbUrl: string;
@@ -202,8 +206,6 @@ DATABASE_URL=your_database_url
DATABASE_AUTH_TOKEN=your_auth_token`);
}
import type { ProjectConfig } from "../types";
export async function setupTurso(config: ProjectConfig): Promise<void> {
const { orm, projectDir } = config;
const _isDrizzle = orm === "drizzle";

View File

@@ -1,19 +1,19 @@
import { cancel, log } from "@clack/prompts";
import fs from "fs-extra";
import pc from "picocolors";
import type { ProjectConfig } from "../types";
import { setupAddons } from "./addons-setup";
import { setupApi } from "./api-setup";
import { setupAuth } from "./auth-setup";
import { setupBackendDependencies } from "./backend-framework-setup";
import type { ProjectConfig } from "../../types";
import { setupAddons } from "../setup/addons-setup";
import { setupApi } from "../setup/api-setup";
import { setupAuth } from "../setup/auth-setup";
import { setupBackendDependencies } from "../setup/backend-setup";
import { setupDatabase } from "../setup/db-setup";
import { setupExamples } from "../setup/examples-setup";
import { setupRuntime } from "../setup/runtime-setup";
import { createReadme } from "./create-readme";
import { setupDatabase } from "./db-setup";
import { setupEnvironmentVariables } from "./env-setup";
import { setupExamples } from "./examples-setup";
import { installDependencies } from "./install-dependencies";
import { displayPostInstallInstructions } from "./post-installation";
import { initializeGit, updatePackageConfigurations } from "./project-config";
import { setupRuntime } from "./runtime-setup";
import {
copyBaseTemplate,
handleExtras,

View File

@@ -2,14 +2,14 @@ import path from "node:path";
import consola from "consola";
import fs from "fs-extra";
import type {
ProjectAddons,
ProjectApi,
API,
Addons,
Database,
Frontend,
ORM,
ProjectConfig,
ProjectDatabase,
ProjectFrontend,
ProjectOrm,
ProjectRuntime,
} from "../types";
Runtime,
} from "../../types";
export async function createReadme(projectDir: string, options: ProjectConfig) {
const readmePath = path.join(projectDir, "README.md");
@@ -206,14 +206,14 @@ ${generateScriptsList(
}
function generateFeaturesList(
database: ProjectDatabase,
database: Database,
auth: boolean,
addons: ProjectAddons[],
orm: ProjectOrm,
runtime: ProjectRuntime,
frontend: ProjectFrontend[],
addons: Addons[],
orm: ORM,
runtime: Runtime,
frontend: Frontend[],
backend: string,
api: ProjectApi,
api: API,
): string {
const isConvex = backend === "convex";
const hasTanstackRouter = frontend.includes("tanstack-router");
@@ -332,10 +332,10 @@ function generateFeaturesList(
}
function generateDatabaseSetup(
database: ProjectDatabase,
database: Database,
auth: boolean,
packageManagerRunCmd: string,
orm: ProjectOrm,
orm: ORM,
): string {
if (database === "none") {
return "";
@@ -405,11 +405,11 @@ ${packageManagerRunCmd} db:push
function generateScriptsList(
packageManagerRunCmd: string,
database: ProjectDatabase,
orm: ProjectOrm,
database: Database,
orm: ORM,
_auth: boolean,
hasNative: boolean,
addons: ProjectAddons[],
addons: Addons[],
backend: string,
): string {
const isConvex = backend === "convex";

View File

@@ -1,7 +1,7 @@
import path from "node:path";
import fs from "fs-extra";
import type { ProjectConfig } from "../types";
import { generateAuthSecret } from "./auth-setup";
import type { ProjectConfig } from "../../types";
import { generateAuthSecret } from "../setup/auth-setup";
export interface EnvVariable {
key: string;

View File

@@ -2,7 +2,7 @@ import { log, spinner } from "@clack/prompts";
import consola from "consola";
import { $ } from "execa";
import pc from "picocolors";
import type { ProjectAddons, ProjectPackageManager } from "../types";
import type { Addons, PackageManager } from "../../types";
export async function installDependencies({
projectDir,
@@ -10,8 +10,8 @@ export async function installDependencies({
addons = [],
}: {
projectDir: string;
packageManager: ProjectPackageManager;
addons?: ProjectAddons[];
packageManager: PackageManager;
addons?: Addons[];
}) {
const s = spinner();
@@ -38,7 +38,7 @@ export async function installDependencies({
async function runBiomeCheck(
projectDir: string,
packageManager: ProjectPackageManager,
packageManager: PackageManager,
) {
const s = spinner();

View File

@@ -1,9 +1,9 @@
import { consola } from "consola";
import pc from "picocolors";
import type { ProjectDatabase, ProjectOrm, ProjectRuntime } from "../types";
import { getPackageExecutionCommand } from "../utils/get-package-execution-command";
import type { Database, ORM, Runtime } from "../../types";
import { getPackageExecutionCommand } from "../../utils/get-package-execution-command";
import type { ProjectConfig } from "../types";
import type { ProjectConfig } from "../../types";
export function displayPostInstallInstructions(
config: ProjectConfig & { depsInstalled: boolean },
@@ -157,10 +157,10 @@ function getLintingInstructions(runCmd?: string): string {
}
function getDatabaseInstructions(
database: ProjectDatabase,
orm?: ProjectOrm,
database: Database,
orm?: ORM,
runCmd?: string,
runtime?: ProjectRuntime,
runtime?: Runtime,
): string {
const instructions = [];

View File

@@ -3,7 +3,7 @@ import { log } from "@clack/prompts";
import { $, execa } from "execa";
import fs from "fs-extra";
import pc from "picocolors";
import type { ProjectConfig } from "../types";
import type { ProjectConfig } from "../../types";
export async function updatePackageConfigurations(
projectDir: string,

View File

@@ -1,9 +1,9 @@
import path from "node:path";
import fs from "fs-extra";
import { globby } from "globby";
import { PKG_ROOT } from "../constants";
import type { ProjectConfig } from "../types";
import { processTemplate } from "../utils/template-processor";
import { PKG_ROOT } from "../../constants";
import type { ProjectConfig } from "../../types";
import { processTemplate } from "../../utils/template-processor";
async function processAndCopyFiles(
sourcePattern: string | string[],

View File

@@ -1,11 +1,11 @@
import path from "node:path";
import fs from "fs-extra";
import type { ProjectFrontend } from "../types";
import { addPackageDependency } from "../utils/add-package-deps";
import type { Frontend } from "../../types";
import { addPackageDependency } from "../../utils/add-package-deps";
import { setupStarlight } from "./starlight-setup";
import { setupTauri } from "./tauri-setup";
import type { ProjectConfig } from "../types";
import type { ProjectConfig } from "../../types";
export async function setupAddons(config: ProjectConfig) {
const { addons, frontend, projectDir } = config;
@@ -49,10 +49,7 @@ export async function setupAddons(config: ProjectConfig) {
}
}
function getWebAppDir(
projectDir: string,
frontends: ProjectFrontend[],
): string {
function getWebAppDir(projectDir: string, frontends: Frontend[]): string {
if (
frontends.some((f) =>
["react-router", "tanstack-router", "nuxt", "svelte", "solid"].includes(
@@ -109,7 +106,7 @@ async function setupHusky(projectDir: string) {
}
}
async function setupPwa(projectDir: string, frontends: ProjectFrontend[]) {
async function setupPwa(projectDir: string, frontends: Frontend[]) {
const isCompatibleFrontend = frontends.some((f) =>
["react-router", "tanstack-router", "solid"].includes(f),
);

View File

@@ -1,8 +1,8 @@
import path from "node:path";
import fs from "fs-extra";
import type { AvailableDependencies } from "../constants";
import type { ProjectConfig, ProjectFrontend } from "../types";
import { addPackageDependency } from "../utils/add-package-deps";
import type { AvailableDependencies } from "../../constants";
import type { Frontend, ProjectConfig } from "../../types";
import { addPackageDependency } from "../../utils/add-package-deps";
export async function setupApi(config: ProjectConfig): Promise<void> {
const { api, projectName, frontend, backend, packageManager, projectDir } =
@@ -120,7 +120,7 @@ export async function setupApi(config: ProjectConfig): Promise<void> {
}
}
const reactBasedFrontends: ProjectFrontend[] = [
const reactBasedFrontends: Frontend[] = [
"react-router",
"tanstack-router",
"tanstack-start",

View File

@@ -2,8 +2,8 @@ import path from "node:path";
import consola from "consola";
import fs from "fs-extra";
import pc from "picocolors";
import type { ProjectConfig } from "../types";
import { addPackageDependency } from "../utils/add-package-deps";
import type { ProjectConfig } from "../../types";
import { addPackageDependency } from "../../utils/add-package-deps";
export async function setupAuth(config: ProjectConfig): Promise<void> {
const { auth, frontend, backend, projectDir } = config;

View File

@@ -1,8 +1,8 @@
import path from "node:path";
import type { AvailableDependencies } from "../constants";
import { addPackageDependency } from "../utils/add-package-deps";
import type { AvailableDependencies } from "../../constants";
import { addPackageDependency } from "../../utils/add-package-deps";
import type { ProjectConfig } from "../types";
import type { ProjectConfig } from "../../types";
export async function setupBackendDependencies(
config: ProjectConfig,

View File

@@ -3,15 +3,15 @@ import { spinner } from "@clack/prompts";
import consola from "consola";
import fs from "fs-extra";
import pc from "picocolors";
import { addPackageDependency } from "../utils/add-package-deps";
import { setupMongoDBAtlas } from "./mongodb-atlas-setup";
import { setupPrismaPostgres } from "./prisma-postgres-setup";
import { setupSupabase } from "./supabase-setup";
import { setupTurso } from "./turso-setup";
import { addPackageDependency } from "../../utils/add-package-deps";
import { setupMongoDBAtlas } from "../database-providers/mongodb-atlas-setup";
import { setupPrismaPostgres } from "../database-providers/prisma-postgres-setup";
import { setupSupabase } from "../database-providers/supabase-setup";
import { setupTurso } from "../database-providers/turso-setup";
import { setupNeonPostgres } from "./neon-setup";
import { setupNeonPostgres } from "../database-providers/neon-setup";
import type { ProjectConfig } from "../types";
import type { ProjectConfig } from "../../types";
export async function setupDatabase(config: ProjectConfig): Promise<void> {
const { database, orm, dbSetup, backend, projectDir } = config;

View File

@@ -1,8 +1,8 @@
import path from "node:path";
import fs from "fs-extra";
import type { AvailableDependencies } from "../constants";
import type { ProjectConfig } from "../types";
import { addPackageDependency } from "../utils/add-package-deps";
import type { AvailableDependencies } from "../../constants";
import type { ProjectConfig } from "../../types";
import { addPackageDependency } from "../../utils/add-package-deps";
export async function setupExamples(config: ProjectConfig): Promise<void> {
const { examples, frontend, backend, projectDir } = config;

View File

@@ -1,7 +1,7 @@
import path from "node:path";
import fs from "fs-extra";
import type { ProjectBackend, ProjectConfig } from "../types";
import { addPackageDependency } from "../utils/add-package-deps";
import type { Backend, ProjectConfig } from "../../types";
import { addPackageDependency } from "../../utils/add-package-deps";
export async function setupRuntime(config: ProjectConfig): Promise<void> {
const { runtime, backend, projectDir } = config;
@@ -25,7 +25,7 @@ export async function setupRuntime(config: ProjectConfig): Promise<void> {
async function setupBunRuntime(
serverDir: string,
_backend: ProjectBackend,
_backend: Backend,
): Promise<void> {
const packageJsonPath = path.join(serverDir, "package.json");
if (!(await fs.pathExists(packageJsonPath))) return;
@@ -48,7 +48,7 @@ async function setupBunRuntime(
async function setupNodeRuntime(
serverDir: string,
backend: ProjectBackend,
backend: Backend,
): Promise<void> {
const packageJsonPath = path.join(serverDir, "package.json");
if (!(await fs.pathExists(packageJsonPath))) return;

View File

@@ -3,8 +3,8 @@ import { spinner } from "@clack/prompts";
import consola from "consola";
import { execa } from "execa";
import pc from "picocolors";
import type { ProjectConfig } from "../types";
import { getPackageExecutionCommand } from "../utils/get-package-execution-command";
import type { ProjectConfig } from "../../types";
import { getPackageExecutionCommand } from "../../utils/get-package-execution-command";
export async function setupStarlight(config: ProjectConfig): Promise<void> {
const { packageManager, projectDir } = config;

View File

@@ -4,10 +4,10 @@ import { consola } from "consola";
import { execa } from "execa";
import fs from "fs-extra";
import pc from "picocolors";
import { addPackageDependency } from "../utils/add-package-deps";
import { getPackageExecutionCommand } from "../utils/get-package-execution-command";
import { addPackageDependency } from "../../utils/add-package-deps";
import { getPackageExecutionCommand } from "../../utils/get-package-execution-command";
import type { ProjectConfig } from "../types";
import type { ProjectConfig } from "../../types";
export async function setupTauri(config: ProjectConfig): Promise<void> {
const { packageManager, frontend, projectDir } = config;