UNPKG

@sodacore/create

Version:

Sodacore CLI project creation tool.

116 lines (115 loc) 4.2 kB
import { cancel, confirm, intro, isCancel, log, multiselect, outro, tasks, text } from '@clack/prompts'; import { inverse } from 'picocolors'; import { chdir, cwd, exit } from 'node:process'; import { resolve } from 'node:path'; import { mkdir, rm } from 'node:fs/promises'; import { $, file, write } from 'bun'; import { getFiles } from './files'; console.log(''); intro(inverse(' Create Sodacore ')); // Ask for the project name. const projectName = await text({ message: 'What is the project name?', defaultValue: 'sodacore-project', placeholder: 'sodacore-project', }); if (isCancel(projectName)) { cancel('Operation cancelled'); exit(0); } // Ask for the project path. const projectBasePath = await text({ message: 'What is the project path?', defaultValue: cwd(), placeholder: cwd(), }); if (isCancel(projectBasePath)) { cancel('Operation cancelled'); exit(0); } // Confirm the path. const isPathConfirmed = await confirm({ message: `Is the project path ${projectBasePath}/${projectName} correct?`, }); if (isCancel(isPathConfirmed)) { cancel('Operation cancelled'); exit(0); } // Define the project. const projectPath = `${projectBasePath}/${projectName}`; // What plugins should be installed? const plugins = await multiselect({ message: 'What plugins would you like to install? (Use space to select, enter to confirm)', options: [ { value: '@sodacore/http@alpha', label: 'HTTP' }, { value: '@sodacore/ws@alpha', label: 'WebSockets' }, { value: '@sodacore/prisma@alpha', label: 'Prisma' }, { value: '@sodacore/discord@alpha', label: 'Discord' }, ], }); if (isCancel(plugins)) { cancel('Operation cancelled'); exit(0); } // Add the base packages. const packages = ['@sodacore/di@alpha', '@sodacore/core@alpha']; packages.push(...plugins); // Run the tasks. await tasks([ { title: 'Initialising project folder', task: async () => { await mkdir(projectPath, { recursive: true }); chdir(projectPath); $.cwd(projectPath); await $ `bun init -y`.quiet(); await rm(resolve(projectPath, './index.ts')); await mkdir(resolve(projectPath, './src'), { recursive: true }); return 'Initialised project folder'; }, }, { title: 'Installing dependencies', task: async () => { chdir(projectPath); await $ `bun install ${{ raw: packages.join(' ') }}`.quiet(); return 'Dependencies installed'; }, }, { title: 'Creating template files', task: async () => { const files = getFiles(packages); const createdFiles = []; for (const file of files) { if (!packages.includes(file.package)) continue; const filePath = resolve(projectPath, file.path); await mkdir(resolve(projectPath, file.path.split('/').slice(0, -1).join('/')), { recursive: true }); await write(filePath, file.content); createdFiles.push(filePath); } return `Created ${createdFiles.length} files:\n${createdFiles.map(file => `- ${file}`).join('\n')}`; }, }, { title: 'Modifying files with context information.', task: async () => { // Load the JSON file. const packageJson = file(resolve(projectPath, './package.json')); if (!await packageJson.exists()) { cancel('Package.json not found.'); exit(1); } // Write the version and script. const packageMeta = await packageJson.json(); packageMeta.version = '0.0.0'; packageMeta.scripts = {}; packageMeta.scripts.dev = 'bun run ./src/main.ts'; await packageJson.write(JSON.stringify(packageMeta, null, '\t')); }, }, ]); // Log the outcome. log.success(`Created project at ${projectPath}\n\nRun \`cd ${projectPath}\` and \`bun run dev\` to get started the project.`); outro(`Done! Check out our docs at https://sodacore.dev for more information.`);