create-next-rkk 1.0.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,2 +1,7 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ export declare function validateProjectName(name: string): {
3
+ valid: boolean;
4
+ reason?: string;
5
+ };
6
+ export declare function cleanupProjectDir(projectPath: string): void;
7
+ export declare function runCli(argv?: string[]): Promise<void>;
package/dist/index.js CHANGED
@@ -37,6 +37,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  return (mod && mod.__esModule) ? mod : { "default": mod };
38
38
  };
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.validateProjectName = validateProjectName;
41
+ exports.cleanupProjectDir = cleanupProjectDir;
42
+ exports.runCli = runCli;
40
43
  const commander_1 = require("commander");
41
44
  const inquirer_1 = __importDefault(require("inquirer"));
42
45
  const child_process_1 = require("child_process");
@@ -45,10 +48,31 @@ const path = __importStar(require("path"));
45
48
  const chalk_1 = __importDefault(require("chalk"));
46
49
  const ora_1 = __importDefault(require("ora"));
47
50
  const program = new commander_1.Command();
51
+ function validateProjectName(name) {
52
+ const trimmed = name.trim();
53
+ if (!trimmed) {
54
+ return { valid: false, reason: 'Project name cannot be empty.' };
55
+ }
56
+ if (!/^[a-zA-Z0-9._-]+$/.test(trimmed)) {
57
+ return {
58
+ valid: false,
59
+ reason: 'Project name can only contain letters, numbers, dot, underscore, and dash.',
60
+ };
61
+ }
62
+ if (/^(con|prn|aux|nul|com\d|lpt\d)$/i.test(trimmed)) {
63
+ return { valid: false, reason: 'Project name is reserved on Windows.' };
64
+ }
65
+ return { valid: true };
66
+ }
67
+ function cleanupProjectDir(projectPath) {
68
+ if (fs.existsSync(projectPath)) {
69
+ fs.rmSync(projectPath, { recursive: true, force: true });
70
+ }
71
+ }
48
72
  program
49
73
  .name('create-next-rkk')
50
74
  .description('Create a new Next.js app with rkk-next pre-configured')
51
- .version('1.0.0')
75
+ .version('2.0.0')
52
76
  .argument('[project-name]', 'name of your project')
53
77
  .action(async (projectName) => {
54
78
  console.log(chalk_1.default.bold.cyan('\nšŸš€ Create RKK Next.js App\n'));
@@ -84,7 +108,14 @@ program
84
108
  },
85
109
  ]);
86
110
  const targetDir = projectName || answers.projectName;
111
+ const validation = validateProjectName(targetDir);
112
+ if (!validation.valid) {
113
+ console.error(chalk_1.default.red(`\nInvalid project name: ${validation.reason}\n`));
114
+ process.exit(1);
115
+ }
87
116
  const projectPath = path.join(process.cwd(), targetDir);
117
+ let createdProject = false;
118
+ let activeStep = null;
88
119
  // Step 1: Create Next.js app
89
120
  const spinner = (0, ora_1.default)('Creating Next.js application...').start();
90
121
  try {
@@ -101,17 +132,20 @@ program
101
132
  '--import-alias', '@/*',
102
133
  '--no-git'
103
134
  ].join(' ');
135
+ activeStep = 'create-app';
104
136
  (0, child_process_1.execSync)(createNextAppCmd, {
105
137
  stdio: 'inherit',
106
138
  cwd: process.cwd()
107
139
  });
108
140
  spinner.succeed('Next.js application created!');
141
+ createdProject = true;
109
142
  // Verify directory exists
110
143
  if (!fs.existsSync(projectPath)) {
111
144
  throw new Error(`Project directory ${targetDir} was not created`);
112
145
  }
113
146
  // Step 2: Install rkk-next
114
147
  if (answers.installDeps) {
148
+ activeStep = 'install-rkk';
115
149
  spinner.start('Installing rkk-next...');
116
150
  (0, child_process_1.execSync)('npm install rkk-next', {
117
151
  stdio: 'inherit',
@@ -120,6 +154,7 @@ program
120
154
  spinner.succeed('rkk-next installed!');
121
155
  }
122
156
  // Step 3: Setup template files
157
+ activeStep = 'setup-templates';
123
158
  spinner.start('Setting up rkk-next configuration...');
124
159
  setupTemplateFiles(projectPath, answers.router, answers.typescript);
125
160
  spinner.succeed('Configuration complete!');
@@ -137,7 +172,18 @@ program
137
172
  }
138
173
  catch (error) {
139
174
  spinner.fail('Failed to create application');
175
+ const stepMessage = activeStep ? ` during ${activeStep}` : '';
140
176
  console.error(chalk_1.default.red('\nError:'), error.message);
177
+ if (createdProject) {
178
+ console.log(chalk_1.default.yellow(`\nAttempting rollback${stepMessage}...`));
179
+ try {
180
+ cleanupProjectDir(projectPath);
181
+ console.log(chalk_1.default.green('Rollback successful: cleaned up failed project directory.'));
182
+ }
183
+ catch (cleanupError) {
184
+ console.error(chalk_1.default.red('Rollback failed. Please remove the directory manually:'), projectPath, cleanupError?.message ? `(${cleanupError.message})` : '');
185
+ }
186
+ }
141
187
  process.exit(1);
142
188
  }
143
189
  });
@@ -248,4 +294,12 @@ module.exports = nextConfig;
248
294
  `;
249
295
  fs.writeFileSync(path.join(projectDir, 'next.config.js'), configContent);
250
296
  }
251
- program.parse(process.argv);
297
+ async function runCli(argv = process.argv) {
298
+ await program.parseAsync(argv);
299
+ }
300
+ if (require.main === module) {
301
+ runCli().catch((error) => {
302
+ console.error(chalk_1.default.red('\nUnexpected CLI failure:'), error?.message || error);
303
+ process.exit(1);
304
+ });
305
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-next-rkk",
3
- "version": "1.0.4",
3
+ "version": "2.0.0",
4
4
  "description": "CLI tool to create Next.js apps with rkk-next pre-configured",
5
5
  "author": "Rohit Kumar Kundu",
6
6
  "license": "MIT",
@@ -24,6 +24,8 @@
24
24
  "scripts": {
25
25
  "build": "tsc",
26
26
  "dev": "tsc --watch",
27
+ "test": "jest",
28
+ "test:watch": "jest --watch",
27
29
  "prepublishOnly": "npm run build"
28
30
  },
29
31
  "dependencies": {
@@ -33,8 +35,14 @@
33
35
  "ora": "^5.4.1"
34
36
  },
35
37
  "devDependencies": {
38
+ "@testing-library/jest-dom": "^6.9.1",
39
+ "@testing-library/react": "^14.3.1",
36
40
  "@types/inquirer": "^9.0.7",
41
+ "@types/jest": "^29.5.14",
37
42
  "@types/node": "^20.10.0",
43
+ "jest": "^29.7.0",
44
+ "jest-environment-jsdom": "^29.7.0",
45
+ "ts-jest": "^29.4.6",
38
46
  "typescript": "^5.3.3"
39
47
  },
40
48
  "keywords": [