create-nuxtus
Version:
npx command for generating a new Nuxtus boilerplate website.
221 lines (193 loc) • 6.22 kB
text/typescript
import * as fs from 'fs';
import * as path from 'path';
import {
ProjectType,
askOptions,
cleanUp,
updatePackageJson,
} from './lib/util.js';
import {
installDBDriver,
installDirectus,
installDirectusHook,
} from './lib/directus.js';
import { installLocaltunnel, installNuxt } from './lib/nuxt.js';
import { Credentials } from './lib/directus-init/create-db-credentials.js';
import chalk from 'chalk';
import commandExistsSync from 'command-exists';
import createEnv from './lib/directus-init/create-env.js';
import { databaseQuestions } from './lib/directus-init/questions.js';
import { execSync } from 'child_process';
import figlet from 'figlet';
import { getDriverForClient } from './lib/directus-init/drivers.js';
import inquirer from 'inquirer';
import ora from 'ora';
/************
* Some initial checks if we can run Nuxtus install script
*/
const currentNodeVersion = process.versions.node;
const semver = currentNodeVersion.split('.');
const major = Number(semver[0]);
if (major < 20) {
console.error(
chalk.red(
'You are running Node ' +
currentNodeVersion +
'.\n' +
'Create Nuxtus requires Node 20 or higher. \n' +
'Please update your version of Node.',
),
);
process.exit(1);
}
if (!commandExistsSync('git')) {
console.log(
chalk.red(
'Git is required to install Nuxtus. Please install Git and try again.',
),
);
process.exit(1);
}
if (process.argv.length < 3) {
console.log(chalk.red('You have to provide a name for your app.'));
console.log('For example :');
console.log(' npx create-nuxtus ' + chalk.bold('my-app'));
process.exit(1);
}
/****************************************************/
export declare type Options = {
dbType: string;
directusURL: string;
email: string;
password: string;
};
let options: Options = {
dbType: 'SQLite',
directusURL: 'http://localhost:8055',
email: 'admin@example.com',
password: 'password',
};
console.log(
chalk.green(figlet.textSync('nuxtus', { horizontalLayout: 'full' })),
);
const projectName = process.argv[2];
const currentPath = process.cwd();
const projectPath = path.join(currentPath, projectName);
const git_repo = 'https://github.com/nuxtus/nuxtus';
const branch = process.env.NUXTUS_BRANCH || 'main';
try {
fs.mkdirSync(projectPath);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
if (err.code === 'EEXIST') {
console.log(
chalk.red(
`The folder ${projectName} already exist in the current directory, please try another name.`,
),
);
} else {
console.log(chalk.red(err));
}
process.exit(1);
}
let dbClient;
let credentials: Credentials;
const rootPath = path.join(process.cwd(), projectName, 'server');
async function main(): Promise<void> {
try {
options = await askOptions();
dbClient = await getDriverForClient(options.dbType);
await installDBDriver(dbClient);
type QuestionFunction = (params: {
client: string;
filepath: string;
}) => unknown;
credentials = await inquirer.prompt(
(databaseQuestions[dbClient] as QuestionFunction[]).map(
(question: QuestionFunction) =>
question({ client: dbClient, filepath: rootPath }),
),
);
} catch (error) {
if (error.isTtyError) {
console.log(
chalk.red("Prompt couldn't be rendered in the current environment"),
);
} else {
// Something else went wrong
console.log(chalk.red(error));
}
}
console.log(''); // empty line between Directus questions and status messages
const nuxtusSpinner = ora('Downloading Nuxtus boilerplate...').start();
try {
execSync(`git clone --depth 1 -b ${branch} ${git_repo} ${projectPath}`, {
stdio: 'ignore',
});
nuxtusSpinner.succeed('Nuxtus boilerplate downloaded.');
process.chdir(projectPath);
} catch (error) {
nuxtusSpinner.fail(chalk.red(`Failed cloning Nuxtus repo: ${error}`));
process.exit();
}
const directusSpinner = ora('Installing Directus...').start();
const nuxtSpinner = ora('Installing Nuxt...').start();
const rmSpinner = ora('Optimising boilerplate...').start();
const directus = installDirectus()
.then(async () => {
// Replace "name": "server" in package.json with "name": ${packageName}
await updatePackageJson(projectName, ProjectType.Directus);
await createEnv(dbClient, credentials, rootPath, {
email: options.email,
password: options.password,
});
// Run the boilerplate install script here
execSync('cd server && npm run cli bootstrap', {
stdio: 'ignore',
});
await installDirectusHook();
directusSpinner.succeed('Directus installed.');
})
.catch((error) => {
directusSpinner.fail(`Failed installing Directus: ${error}`);
process.exit(1);
});
const nuxt = installNuxt(options.directusURL, options.email, options.password)
.then(() => {
updatePackageJson(projectName, ProjectType.Nuxt);
if (options.directusURL !== 'http://localhost:8055') {
installLocaltunnel();
}
nuxtSpinner.succeed('Nuxt installed.');
})
.catch((error) => {
nuxtSpinner.fail(chalk.red(`Failed installing Nuxt: ${error}`));
process.exit(1);
});
const cleanup = cleanUp(projectName)
.then(() => {
rmSpinner.succeed('Boilerplate customised.');
})
.catch((error) => {
rmSpinner.fail(chalk.red(`Failed removing unused files: ${error}`));
process.exit(1);
});
Promise.all([directus, nuxt, cleanup]).then(() => {
execSync(`npx rimraf ./templates`);
console.log('\n');
console.log(
chalk.green('🚀 Nuxtus site is ready for use!\n\n') +
chalk.white.bold('Directus\n') +
chalk.magenta.underline(`${options.directusURL}\n\n`) +
chalk.white.bold('Nuxtus\n') +
chalk.green.underline('http://localhost:3000\n\n') +
chalk.white(`cd ${projectName}` + '\nnpm start\n\n') +
chalk.green(
'For documentation see: ',
chalk.underline('https://docs.nuxtus.com\n'),
),
);
});
}
main();