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
3 changes: 2 additions & 1 deletion src/commands/COMMAND_TEMPLATE/TEMPLATE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import pluginConfigFile from './plugins/config.json';

import allPlugins from './plugins/index.js';
import { ICommand } from 'types/ICommand.js';
import { requirePlugin } from 'utils/install-plugins.js';

/**
* TEMPLATE
Expand All @@ -16,7 +17,7 @@ const COMMAND_NAME: ICommand = createCommand({
const plugins = context.plugins;

// Add stuff here, like inquirer prompts or other logic
plugins.prettier.install({});
await requirePlugin(plugins, 'prettier').install({});
},
});

Expand Down
51 changes: 26 additions & 25 deletions src/commands/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ 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 { withContext } from 'utils/errors.js';
import { requirePlugin } from 'utils/install-plugins.js';
import colors from 'picocolors';

/**
Expand All @@ -20,32 +22,31 @@ const auth: ICommand = createCommand({
{ name: 'Kinde (Recommended) https://kinde.com/', value: 'kinde' },
{ 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 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);
if (!selectedOption) {
console.error('Invalid auth selection.');
return;
}
const { cyan } = colors;
log(`Setting up ${cyan(selectedOption.name)} for your project...`);
switch (selectedOption.value) {
case 'kinde':
plugins.kinde.install({});
break;
case 'other':
break;
}
} catch (error) {
console.error('Failed to add auth:', error);
const selectedOption = authOptions.find((auth) => auth.name === answers.auth);
if (!selectedOption) {
throw new Error(`Invalid auth selection: ${answers.auth}`);
}
const { cyan } = colors;
log(`Setting up ${cyan(selectedOption.name)} for your project...`);
switch (selectedOption.value) {
case 'kinde':
try {
await requirePlugin(plugins, 'kinde').install({});
} catch (error) {
throw withContext('Failed to set up Kinde auth', error);
}
break;
case 'other':
break;
}
},
});
Expand Down
8 changes: 6 additions & 2 deletions src/commands/auth/plugins/kinde.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const kinde: Plugin = {
'KINDE_POST_LOGIN_REDIRECT_URL',
];
while (!finishedEnv) {
await inquirer.prompt([
const answers = await inquirer.prompt([
{
type: 'confirm',
name: 'done',
Expand All @@ -71,10 +71,14 @@ const kinde: Plugin = {
},
]);

if (!answers.done) {
log('Finish adding the env variables above, then run next-quick auth again.', LogLevel.warn);
return;
}

if (checkEnvVars(requiredEnvVars)) {
log('Auth is now set up. It was that easy! 🎉', LogLevel.success, undefined, true);
finishedEnv = true;
break;
}
}
},
Expand Down
3 changes: 2 additions & 1 deletion src/commands/createCommand.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ICommand } from 'types/ICommand.js';
import { PluginRegistry, PluginConfigFile } from 'types/plugin.js';
import { readConfig } from 'utils/read-config-file.js';
import { log, LogLevel } from 'utils/logger.js';

export default function createCommand(config: {
requiresProjectInitialized: boolean;
Expand All @@ -20,7 +21,7 @@ export default function createCommand(config: {
const config = readConfig();

if (!config) {
console.error('Project is not initialized.');
log('Project is not initialized. Run next-quick init first.', LogLevel.error);
process.exit(1);
}
}
Expand Down
42 changes: 22 additions & 20 deletions src/commands/database/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ 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 { withContext } from 'utils/errors.js';
import { requirePlugin } from 'utils/install-plugins.js';
import { log } from 'utils/logger.js';

/**
* Adds a database to the project by prompting the user to select a database option.
Expand All @@ -21,26 +24,21 @@ const addDatabase: ICommand = createCommand({
// { name: 'PostgreSQL', value: 'postgresql' },
*/
];
try {
const answers = await inquirer.prompt([
{
type: 'list',
name: 'database',
message: 'Choose a database for your project:',
choices: dbOptions.map((db) => db.name),
},
]);
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);
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);
const selectedOption = dbOptions.find((db) => db.name === answers.database);
if (!selectedOption) {
throw new Error(`Invalid database selection: ${answers.database}`);
}
// console.log(`Setting up ${selectedOption.name} for your project...`);
await setupDatabase(selectedOption.value, context.plugins);
},
});

Expand All @@ -49,7 +47,11 @@ async function setupDatabase(database: string, plugins: PluginRegistry) {
switch (database) {
case 'mongodb':
pluginsToInstall.push('mongoose');
plugins.mongoose.install({});
try {
await requirePlugin(plugins, 'mongoose').install({});
} catch (error) {
throw withContext('Failed to set up MongoDB', error);
}
break;
case 'other':
break;
Expand All @@ -71,7 +73,7 @@ async function setupDatabase(database: string, plugins: PluginRegistry) {
// console.error(`Error installing ${packageToInstall}:`, error);
// }
} else {
console.log('No database package specified for installation.');
log('No database package specified for installation.');
}
}

Expand Down
90 changes: 39 additions & 51 deletions src/commands/database/plugins/mongoose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,72 +9,60 @@ import { askOpenPage } from 'utils/inquirer/ask-open-page.js';
// MongoDB with Mongoose ORM
const mongoose: Plugin = {
install: async () => {
try {
NPM.install('mongoose');
NPM.install('mongoose');

// Prompt user to go to mongoDB website to set up project
await askOpenPage(
'Log in to MongoDB to connect your project',
'https://www.mongodb.com/cloud/atlas/register'
);
// Prompt user for & add to url .env
// Prompt user to go to mongoDB website to set up project
await askOpenPage('Log in to MongoDB to connect your project', 'https://www.mongodb.com/cloud/atlas/register');
// Prompt user for & add to url .env
log(
'Log in to your MongoDB Atlas account and copy the connection string, which can be found under:\n“Connect” > “Connecting with MongoDB for VS Code.”',
undefined,
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;
// If "<password>" is in the URL, replace it with the actual password by prompting the user
if (url.includes('<password>')) {
log(
'Log in to your MongoDB Atlas account and copy the connection string, which can be found under:\n“Connect” > “Connecting with MongoDB for VS Code.”',
'Please enter the password for your MongoDB database user. You can find this on the left navigation bar:\n“Security” > “Database Access.”',
undefined,
LogColor.cyan,
true
);
const resUrl = await inquirer.prompt([
const resPw = await inquirer.prompt([
{
type: 'input',
name: 'url',
message: 'Enter your MongoDB connection URL:',
type: 'password',
name: 'password',
message: 'Enter your database user password:',
validate: (input) => {
if (input.length === 0) {
return 'MongoDB connection URL cannot be empty.';
return 'Database user password cannot be empty.';
}
return true;
},
},
]);
let url = resUrl.url;
// If "<password>" is in the URL, replace it with the actual password by prompting the user
if (url.includes('<password>')) {
log(
'Please enter the password for your MongoDB database user. You can find this on the left navigation bar:\n“Security” > “Database Access.”',
undefined,
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);
}
// Add the MONDODB_URL to the user's .env.local file
writeToEnv('MONGODB_URL', url);
await templateCopyTransfer('plugins/mongoose', 'src');
NPM.installDev('swr');

log(
'Test the database connection at http://localhost:3000/test-database',
LogLevel.success,
undefined,
true
);
} catch (error) {
console.error('Failed to set up database for project:', error);
url = url.replace('<password>', resPw.password);
}
// Add the MONDODB_URL to the user's .env.local file
writeToEnv('MONGODB_URL', url);
await templateCopyTransfer('plugins/mongoose', 'src');
NPM.installDev('swr');

log('Test the database connection at http://localhost:3000/test-database', LogLevel.success, undefined, true);
},
};

Expand Down
40 changes: 15 additions & 25 deletions src/commands/deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,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);
});
const answers = await inquirer.prompt([
{
type: 'list',
name: 'target',
message: 'Choose your deployment target:',
choices: deploymentOptions.map((option) => option.name),
},
]);

const selectedOption = deploymentOptions.find((option) => option.name === answers.target);
if (!selectedOption) {
throw new Error(`Unknown deployment target: ${answers.target}`);
}
await validateGitHubStatus();
await askOpenPage(`Log in to ${selectedOption.name} to deploy your project`, selectedOption.url);
},
});

Expand Down
Loading