next-porto-cli
Version:
A cli for next.js to scaffold your application using porto architecture
135 lines (134 loc) • 5.31 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable node/no-extraneous-import */
require("module-alias/register");
const Listr = require("listr");
const execa_1 = require("@esm2cjs/execa");
const path = require("node:path");
const filesystem = require("@helpers/filesystem");
const core_1 = require("@oclif/core");
const config_1 = require("@generators/config");
const path_1 = require("@helpers/path");
const index_1 = require("@generators/index");
class Project extends core_1.Command {
/**
* Initialize Tasks
* @param _args project name argument
* @param _flags check for typescript flag
* @returns new Listr Object
*/
initTaskList(_args, _flags) {
return new Listr([
{
title: 'File checks...',
task: async (_ctx) => {
const projectDirExists = filesystem.fileExist(path.resolve('.', _args.projectName));
const emptyDir = await filesystem.isEmptyDir(path.resolve('.', _args.projectName));
// * check if the project directory exists & no empty
if (projectDirExists && !emptyDir) {
if (!(_flags === null || _flags === void 0 ? void 0 : _flags.force)) {
// * file check context set to false
_ctx.fileChecks = false;
throw new Error(`Directory "${_args.projectName}" already exists & not empty.`);
}
// * force delete directory
filesystem.forceDelete(path.resolve('.', _args.projectName));
// * file check context set to true
_ctx.fileChecks = true;
}
// * file check context set to true (default)
_ctx.fileChecks = true;
},
},
{
title: 'Initialize Next.js...',
task: async (_ctx, _task) => {
const execArgs = [
'create-next-app@latest',
_args.projectName,
];
// * add typescript support
if (_flags === null || _flags === void 0 ? void 0 : _flags.typescript) {
execArgs.push('--typescript');
}
return (0, execa_1.execa)('npx', execArgs)
.then(async () => {
_ctx.nextInit = true;
})
.catch(() => {
_ctx.nextInit = false;
_task.skip(_task.output);
});
},
enabled: ctx => ctx.fileChecks === true,
},
{
title: 'Scaffolding your app...',
task: async (_ctx, _task) => {
const shipPaths = (0, path_1.shipScaffolding)(_args.projectName);
// * generate ship paths
await (0, index_1.generateFromPaths)(shipPaths);
// * generate a default conatiners directory
await index_1.containerGenerator.appcontainersGenerator(path.resolve((0, path_1.getBasePath)(_args.projectName), 'src', 'Containers'));
_ctx.scaffolding = true;
},
enabled: ctx => ctx.nextInit === true,
},
{
title: 'Finishing up...',
task: async (_ctx) => {
await (0, config_1.generateConfig)(path.resolve((0, path_1.getBasePath)(_args.projectName)));
},
enabled: _ctx => _ctx.scaffolding === true,
},
]);
}
/**
* * Run the command (create:project)
* @returns void
*/
async run() {
// *
const { flags, args } = await this.parse(Project);
if (typeof args.projectName === 'undefined') {
// * initiate manual prompt
const projectName = await core_1.CliUx.ux.prompt('Enter the project name', {
required: true,
});
// * set args new value for project name
args.projectName = projectName;
}
// * initiate the tasks
Project.tasks = this.initTaskList(args, flags);
// * run the task list
await Project.tasks.run().catch(error => this.error(error.message));
}
}
exports.default = Project;
// * disable variable argument validation
Project.strict = false;
// *
Project.description = 'Create a Next.js application with porto architechture.';
// * arguments
Project.args = [
{
name: 'projectName',
required: false,
description: 'The name of the directory where the application will be installed.',
},
];
// * flags
Project.flags = {
typescript: core_1.Flags.boolean({
char: 't',
description: 'Enable typescript support.',
default: false,
required: false,
}),
force: core_1.Flags.boolean({
char: 'f',
description: 'Force create a project on existing directory.',
default: false,
required: false,
}),
};