Skip to content
Open
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
23 changes: 9 additions & 14 deletions src/commands/auth/auth.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import inquirer from 'inquirer';
import createCommand from '../createCommand.js';
import pluginConfigFile from './plugins/config.json';

import allPlugins from './plugins/index.js';
import { ICommand } from 'types/ICommand.js';
import { log } from 'utils/logger.js';
import { log, logFailure } from 'utils/logger.js';
import { selectOption } from 'utils/inquirer/prompts.js';
import colors from 'picocolors';

/**
Expand All @@ -21,18 +21,13 @@ const auth: ICommand = createCommand({
{ name: 'Other - I will set up auth myself', value: 'other' },
];
try {
const answers = await inquirer.prompt([
{
type: 'list',
name: 'auth',
message: 'Choose an authentication option for your project:',
choices: authOptions.map((auth) => auth.name),
},
]);

const selectedOption = authOptions.find((auth) => auth.name === answers.auth);
const selectedOption = await selectOption({
message: 'Choose an authentication option for your project:',
options: authOptions,
name: 'auth',
invalidMessage: 'Invalid auth selection.',
});
if (!selectedOption) {
console.error('Invalid auth selection.');
return;
}
const { cyan } = colors;
Expand All @@ -45,7 +40,7 @@ const auth: ICommand = createCommand({
break;
}
} catch (error) {
console.error('Failed to add auth:', error);
logFailure('Failed to add auth', error);
}
},
});
Expand Down
20 changes: 3 additions & 17 deletions src/commands/auth/plugins/kinde.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import inquirer from 'inquirer';
import colors from 'picocolors';
import { Plugin } from 'types/plugin.js';
import { NPM } from 'utils/package-manager.js';
import templateCopyTransfer from 'utils/template-copy-transfer.js';
import { log, LogLevel, LogColor } from 'utils/logger.js';
import { askOpenPage } from 'utils/inquirer/ask-open-page.js';
import { confirmPrompt } from 'utils/inquirer/prompts.js';
import checkEnvVars from 'utils/env/check-env-vars.js';

/**
Expand Down Expand Up @@ -32,14 +32,7 @@ const kinde: Plugin = {
steps.forEach((step, index) => {
log(`${index + 1}. ${step}`);
});
await inquirer.prompt([
{
type: 'confirm',
name: 'continue',
message: 'Continue to next steps?',
default: true,
},
]);
await confirmPrompt('Continue to next steps?');
log(
`Under ${bold('Quick start')}, a few steps have already been completed for you on behalf of this CLI:`,
undefined,
Expand All @@ -62,14 +55,7 @@ const kinde: Plugin = {
'KINDE_POST_LOGIN_REDIRECT_URL',
];
while (!finishedEnv) {
await inquirer.prompt([
{
type: 'confirm',
name: 'done',
message: 'Done?',
default: true,
},
]);
await confirmPrompt('Done?');

if (checkEnvVars(requiredEnvVars)) {
log('Auth is now set up. It was that easy! 🎉', LogLevel.success, undefined, true);
Expand Down
33 changes: 10 additions & 23 deletions src/commands/database/database.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import inquirer from 'inquirer';
import createCommand from '../createCommand.js';
import pluginConfigFile from './plugins/config.json';
import allPlugins from './plugins/index.js';
import { PluginRegistry } from 'types/plugin.js';
import { ICommand } from 'types/ICommand.js';
import { selectOption } from 'utils/inquirer/prompts.js';
import { logFailure } from 'utils/logger.js';

/**
* Adds a database to the project by prompting the user to select a database option.
Expand All @@ -22,24 +23,18 @@ const addDatabase: ICommand = createCommand({
*/
];
try {
const answers = await inquirer.prompt([
{
type: 'list',
name: 'database',
message: 'Choose a database for your project:',
choices: dbOptions.map((db) => db.name),
},
]);

const selectedOption = dbOptions.find((db) => db.name === answers.database);
const selectedOption = await selectOption({
message: 'Choose a database for your project:',
options: dbOptions,
name: 'database',
invalidMessage: 'Invalid database selection.',
});
if (!selectedOption) {
console.error('Invalid database selection.');
return;
}
// console.log(`Setting up ${selectedOption.name} for your project...`);
await setupDatabase(selectedOption.value, context.plugins);
} catch (error) {
console.error('Failed to add database:', error);
logFailure('Failed to add database', error);
}
},
});
Expand All @@ -62,15 +57,7 @@ async function setupDatabase(database: string, plugins: PluginRegistry) {
// break;
*/
}
if (pluginsToInstall.length > 0) {
// try {
// console.log(`Installing ${packageToInstall} in ${projectPath}...`);
// // NPM.install(packageToInstall);
// console.log(`${packageToInstall} installed successfully.`);
// } catch (error) {
// console.error(`Error installing ${packageToInstall}:`, error);
// }
} else {
if (pluginsToInstall.length === 0) {
console.log('No database package specified for installation.');
}
}
Expand Down
46 changes: 15 additions & 31 deletions src/commands/database/plugins/mongoose.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import inquirer from 'inquirer';
import { Plugin } from 'types/plugin.js';
import { NPM } from 'utils/package-manager.js';
import writeToEnv from 'utils/env/write-to-env.js';
import { log, LogColor, LogLevel } from 'utils/logger.js';
import { log, logFailure, LogColor, LogLevel } from 'utils/logger.js';
import templateCopyTransfer from 'utils/template-copy-transfer.js';
import { askOpenPage } from 'utils/inquirer/ask-open-page.js';
import { promptRequiredInput } from 'utils/inquirer/prompts.js';

// MongoDB with Mongoose ORM
const mongoose: Plugin = {
Expand All @@ -24,20 +24,11 @@ const mongoose: Plugin = {
LogColor.cyan,
true
);
const resUrl = await inquirer.prompt([
{
type: 'input',
name: 'url',
message: 'Enter your MongoDB connection URL:',
validate: (input) => {
if (input.length === 0) {
return 'MongoDB connection URL cannot be empty.';
}
return true;
},
},
]);
let url = resUrl.url;
let url = await promptRequiredInput({
message: 'Enter your MongoDB connection URL:',
emptyMessage: 'MongoDB connection URL cannot be empty.',
name: 'url',
});
// If "<password>" is in the URL, replace it with the actual password by prompting the user
if (url.includes('<password>')) {
log(
Expand All @@ -46,20 +37,13 @@ const mongoose: Plugin = {
LogColor.cyan,
true
);
const resPw = await inquirer.prompt([
{
type: 'password',
name: 'password',
message: 'Enter your database user password:',
validate: (input) => {
if (input.length === 0) {
return 'Database user password cannot be empty.';
}
return true;
},
},
]);
url = url.replace('<password>', resPw.password);
const password = await promptRequiredInput({
message: 'Enter your database user password:',
emptyMessage: 'Database user password cannot be empty.',
name: 'password',
password: true,
});
url = url.replace('<password>', password);
}
// Add the MONDODB_URL to the user's .env.local file
writeToEnv('MONGODB_URL', url);
Expand All @@ -73,7 +57,7 @@ const mongoose: Plugin = {
true
);
} catch (error) {
console.error('Failed to set up database for project:', error);
logFailure('Failed to set up database for project', error);
}
},
};
Expand Down
41 changes: 16 additions & 25 deletions src/commands/deploy/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import inquirer from 'inquirer';
import { validateGitHubStatus } from 'utils/git/check-git.js';
import { ICommand } from 'types/ICommand.js';
import createCommand from '../createCommand.js';
import allPlugins from './plugins/index.js';
import pluginConfigFile from './plugins/config.json';
import { askOpenPage } from 'utils/inquirer/ask-open-page.js';
import { selectOption } from 'utils/inquirer/prompts.js';
import { logFailure } from 'utils/logger.js';

const deploymentOptions = [
{
Expand All @@ -25,31 +26,21 @@ const deploy: ICommand = createCommand({
plugins: allPlugins,
pluginConfigFile,
action: async () => {
inquirer
.prompt([
{
type: 'list',
name: 'target',
message: 'Choose your deployment target:',
choices: deploymentOptions.map((option) => option.name),
},
])
.then(async (answers) => {
try {
await validateGitHubStatus();
const selectedOption = deploymentOptions.find((option) => option.name === answers.target);
if (selectedOption)
await askOpenPage(
`Log in to ${selectedOption.name} to deploy your project`,
selectedOption.url
);
} catch (error) {
console.error('Failed to deploy project:', error);
}
})
.catch((error) => {
console.error('Failed to prompt:', error);
try {
const selectedOption = await selectOption({
message: 'Choose your deployment target:',
options: deploymentOptions,
name: 'target',
invalidMessage: 'Invalid deployment target selection.',
});
if (!selectedOption) {
return;
}
await validateGitHubStatus();
await askOpenPage(`Log in to ${selectedOption.name} to deploy your project`, selectedOption.url);
} catch (error) {
logFailure('Failed to deploy project', error);
}
},
});

Expand Down
71 changes: 30 additions & 41 deletions src/commands/init/init.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import fs from 'fs';
import path from 'path';
import inquirer from 'inquirer';
import { execSync } from 'child_process';
import { chdir } from 'process';
import installPlugins from 'utils/install-plugins.js';
import colors from 'picocolors';
Expand All @@ -10,7 +9,10 @@ import createCommand from '../createCommand.js';
import { ICommand } from 'types/ICommand.js';
import allPlugins from './plugins/index.js';
import pluginConfigFile from './plugins/config.json';
import { log, LogLevel, LogColor, command } from 'utils/logger.js';
import { log, logFailure, LogLevel, LogColor, command } from 'utils/logger.js';
import runCommand from 'utils/exec.js';
import { writeJsonFile } from 'utils/fs/json-file.js';
import writeProjectFile from 'utils/fs/write-project-file.js';

/**
* Initializes a new project by prompting the user for a project name and a GitHub template.
Expand All @@ -22,8 +24,8 @@ const initProject: ICommand = createCommand({
pluginConfigFile,
action: async (context) => {
const { cyan } = colors;
inquirer
.prompt([
try {
const answers = await inquirer.prompt([
{
type: 'input',
name: 'projectName',
Expand All @@ -40,56 +42,43 @@ const initProject: ICommand = createCommand({
return 'Project name must be all lowercase and can only include letters, numbers, underscores, and hyphens.';
},
},
])
.then(async (answers) => {
try {
const projectName = answers.projectName;
const projectPath = path.join(process.cwd(), projectName);
const configPath = path.join(projectPath, '.nextquickrc');
// const defaultConfig = { projectName, projectPath };
const defaultConfig = { projectName };
]);

if (!fs.existsSync(projectPath)) {
fs.mkdirSync(projectPath, { recursive: true });
}
const projectName = answers.projectName;
const projectPath = path.join(process.cwd(), projectName);
const configPath = path.join(projectPath, '.nextquickrc');
const defaultConfig = { projectName };

createNextApp(projectPath);
if (!fs.existsSync(projectPath)) {
fs.mkdirSync(projectPath, { recursive: true });
}

chdir(projectPath);
createNextApp(projectPath);

setupGitRepo(projectPath);
chdir(projectPath);

// Create an .env.local file
const envLocalPath = path.join(projectPath, '.env.local');
fs.writeFileSync(envLocalPath, '', 'utf-8');
setupGitRepo(projectPath);

installPlugins(context.plugins);
// Create an .env.local file
writeProjectFile('.env.local', '', { projectPath });

execSync('npm run prettier', { stdio: 'inherit' });
installPlugins(context.plugins);

fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');
log(
`Config file .nextquickrc created in ${configPath}`,
LogLevel.checkmark,
LogColor.cyan,
true,
true
);
log(`Project ${cyan(projectName)} initialized.`, LogLevel.checkmark);
log(`Run ${command(`cd ${projectName}`)} then run ${command('next-quick')} to view new commands.`);
} catch (error) {
console.error('Failed to initialize project:', error);
}
})
.catch((error) => {
console.error('Failed to prompt:', error);
});
runCommand('npm run prettier');

writeJsonFile(configPath, defaultConfig);
log(`Config file .nextquickrc created in ${configPath}`, LogLevel.checkmark, LogColor.cyan, true, true);
log(`Project ${cyan(projectName)} initialized.`, LogLevel.checkmark);
log(`Run ${command(`cd ${projectName}`)} then run ${command('next-quick')} to view new commands.`);
} catch (error) {
logFailure('Failed to initialize project', error);
}
},
});

function createNextApp(projectPath: string) {
const FLAGS = '--use-npm --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"';
execSync(`npx create-next-app@latest . ${FLAGS}`, { cwd: projectPath, stdio: 'inherit' });
runCommand(`npx create-next-app@latest . ${FLAGS}`, { cwd: projectPath });
}

export default initProject;
Loading