create-revo 1.2.7 → 2.0.1

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.
Files changed (52) hide show
  1. package/README.md +40 -19
  2. package/cli.js +251 -42
  3. package/package.json +8 -3
  4. package/template-nextjs/README.md +36 -0
  5. package/template-nextjs/eslint.config.mjs +25 -0
  6. package/template-nextjs/next.config.ts +7 -0
  7. package/template-nextjs/package-lock.json +6182 -0
  8. package/template-nextjs/package.json +28 -0
  9. package/template-nextjs/postcss.config.mjs +5 -0
  10. package/template-nextjs/public/revo.png +0 -0
  11. package/template-nextjs/src/app/favicon.ico +0 -0
  12. package/template-nextjs/src/app/globals.css +21 -0
  13. package/template-nextjs/src/app/layout.tsx +34 -0
  14. package/template-nextjs/src/app/page.tsx +24 -0
  15. package/template-nextjs/tsconfig.json +27 -0
  16. package/template-reactjs/README.md +28 -0
  17. package/{template → template-reactjs}/index.html +1 -1
  18. package/template-reactjs/public/favicon.ico +0 -0
  19. package/template-reactjs/src/App.tsx +23 -0
  20. package/template-reactjs/src/assets/revo.png +0 -0
  21. package/template-reactjs/src/components/dltme +0 -0
  22. package/test/README.md +36 -0
  23. package/test/eslint.config.mjs +25 -0
  24. package/test/next.config.ts +7 -0
  25. package/test/package-lock.json +6182 -0
  26. package/test/package.json +28 -0
  27. package/test/postcss.config.mjs +5 -0
  28. package/test/public/revo.png +0 -0
  29. package/test/src/app/components/dltme +0 -0
  30. package/test/src/app/favicon.ico +0 -0
  31. package/test/src/app/globals.css +21 -0
  32. package/test/src/app/layout.tsx +34 -0
  33. package/test/src/app/page.tsx +24 -0
  34. package/test/tsconfig.json +27 -0
  35. package/template/README.md +0 -1
  36. package/template/public/revo.svg +0 -7
  37. package/template/src/App.tsx +0 -20
  38. package/template/src/assets/revo.svg +0 -19
  39. package/template/src/assets/revo2.svg +0 -7
  40. /package/{template/src → template-nextjs/src/app}/components/dltme +0 -0
  41. /package/{template → template-reactjs}/eslint.config.js +0 -0
  42. /package/{template → template-reactjs}/package-lock.json +0 -0
  43. /package/{template → template-reactjs}/package.json +0 -0
  44. /package/{template → template-reactjs}/postcss.config.js +0 -0
  45. /package/{template → template-reactjs}/src/index.css +0 -0
  46. /package/{template → template-reactjs}/src/main.tsx +0 -0
  47. /package/{template → template-reactjs}/src/vite-env.d.ts +0 -0
  48. /package/{template → template-reactjs}/tailwind.config.js +0 -0
  49. /package/{template → template-reactjs}/tsconfig.app.json +0 -0
  50. /package/{template → template-reactjs}/tsconfig.json +0 -0
  51. /package/{template → template-reactjs}/tsconfig.node.json +0 -0
  52. /package/{template → template-reactjs}/vite.config.ts +0 -0
package/README.md CHANGED
@@ -1,24 +1,35 @@
1
- # Revo - Fast & Efficient React Project Setup
1
+ # Revo - Fast & Efficient React & Next.js Project Setup
2
2
 
3
- **Revo** is a custom React project setup tool built on top of Vite. Its designed to streamline your workflow by providing a clean project structure, pre-configured with **Tailwind CSS** and **Framer Motion**, so you can focus on building amazing applications.
3
+ **Revo** is a modern project setup tool that supports both **React** and **Next.js** projects. It's designed to streamline your workflow by providing clean project structures, pre-configured with **TypeScript** and **Tailwind CSS**, so you can focus on building amazing applications.
4
4
 
5
5
  ---
6
6
 
7
7
  ## 🚀 Features
8
8
 
9
- - **Powered by Vite**: Enjoy blazing-fast builds and an optimized development experience.
10
- - **Tailwind CSS**: Fully configured for utility-first styling right out of the box.
11
- - **Framer Motion**: Pre-installed for creating stunning animations with ease.
12
- - **Better Project Layout**: Thoughtfully organized file structure to keep your code clean and maintainable.
9
+ - **Two Framework Options**: Choose between React (Vite) or Next.js
10
+ - **TypeScript Ready**: Pre-configured TypeScript for type safety
11
+ - **Tailwind CSS**: Fully configured for utility-first styling right out of the box
12
+ - **Latest Dependencies**: Always uses the latest versions of all packages
13
+ - **Interactive Setup**: Simple CLI with progress indicators
14
+ - **Clean Project Structure**: Thoughtfully organized file structure for maintainable code
13
15
 
14
16
  ---
15
17
 
16
18
  ## 📦 What You Get
17
19
 
18
- 1. **Pre-configured Tailwind CSS** for styling.
19
- 2. **Framer Motion** set up for animations.
20
- 3. **Optimized Vite setup** for fast development and builds.
21
- 4. A clean project directory structure:
20
+ ### React Template (Vite)
21
+ 1. **React 18** with TypeScript
22
+ 2. **Vite** for lightning-fast development
23
+ 3. **Tailwind CSS** for styling
24
+ 4. **ESLint** for code quality
25
+ 5. **Motion** for animations
26
+
27
+ ### Next.js Template
28
+ 1. **Next.js 15** with App Router
29
+ 2. **TypeScript** for type safety
30
+ 3. **Tailwind CSS** for styling
31
+ 4. **ESLint** for code quality
32
+ 5. **Optimized** for production
22
33
 
23
34
  ---
24
35
 
@@ -28,21 +39,29 @@
28
39
  Make sure you have Node.js (>=14.x) and npm/yarn installed.
29
40
 
30
41
  ### Create a New Project
31
- Run the following command to create a new project:
32
42
 
43
+ **Option 1: With project name**
44
+ ```bash
45
+ npx create-revo my-awesome-project
33
46
  ```
34
- npx create-revo [project-name]
47
+
48
+ **Option 2: Interactive mode (will prompt for project name)**
49
+ ```bash
50
+ npx create-revo
35
51
  ```
36
52
 
37
- ### Navigate to Your Project
53
+ ### Choose Your Template
54
+ You'll be prompted to choose between:
55
+ 1. **React.js** - Vite + TypeScript + Tailwind CSS
56
+ 2. **Next.js** - App Router + TypeScript + Tailwind CSS
38
57
 
39
- ```
58
+ ### Navigate to Your Project
59
+ ```bash
40
60
  cd [project-name]
41
61
  ```
42
62
 
43
63
  ### Install Dependencies
44
-
45
- ```
64
+ ```bash
46
65
  npm install
47
66
  ```
48
67
 
@@ -84,6 +103,8 @@ Happy coding with Revo! 🎉
84
103
 
85
104
  Revo is built on top of amazing open-source tools. A big shoutout to:
86
105
 
87
- - [Vite](https://vitejs.dev/) - The lightning-fast frontend build tool.
88
- - [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework for rapid UI development.
89
- - [Framer Motion](https://www.framer.com/motion/) - The library for creating smooth and delightful animations.
106
+ - [React](https://react.dev/) - The library for building user interfaces
107
+ - [Next.js](https://nextjs.org/) - The React framework for production
108
+ - [Vite](https://vitejs.dev/) - The lightning-fast frontend build tool
109
+ - [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework for rapid UI development
110
+ - [TypeScript](https://www.typescriptlang.org/) - Typed JavaScript at any scale
package/cli.js CHANGED
@@ -3,18 +3,58 @@
3
3
  import fs from "fs";
4
4
  import path from "path";
5
5
  import { fileURLToPath } from "url";
6
+ import readline from "readline";
6
7
 
7
8
  const __filename = fileURLToPath(import.meta.url);
8
9
  const __dirname = path.dirname(__filename);
9
10
 
10
11
  const projectName = process.argv[2];
11
12
 
12
- if (!projectName) {
13
- console.error("Please provide a project name: npx create-revo [project-name]");
14
- process.exit(1);
13
+ function askProjectName() {
14
+ return new Promise((resolve) => {
15
+ const rl = readline.createInterface({
16
+ input: process.stdin,
17
+ output: process.stdout
18
+ });
19
+
20
+ rl.question('Enter project name: ', (answer) => {
21
+ rl.close();
22
+ resolve(answer.trim());
23
+ });
24
+ });
15
25
  }
16
26
 
17
- const targetDir = path.join(process.cwd(), projectName);
27
+ function askTemplateChoice() {
28
+ return new Promise((resolve) => {
29
+ const rl = readline.createInterface({
30
+ input: process.stdin,
31
+ output: process.stdout
32
+ });
33
+
34
+ console.log('\nChoose your template:');
35
+ console.log('1. React.js + Typescript + TailwindCSS + Vite');
36
+ console.log('2. Next.js + Typescript + TailwindCSS');
37
+
38
+ const askQuestion = () => {
39
+ rl.question('Enter your choice (1 or 2): ', (answer) => {
40
+ const choice = answer.trim().toLowerCase();
41
+
42
+ if (choice === '1' || choice === 'react' || choice === 'reactjs') {
43
+ rl.close();
44
+ resolve('reactjs');
45
+ } else if (choice === '2' || choice === 'next' || choice === 'nextjs') {
46
+ rl.close();
47
+ resolve('nextjs');
48
+ } else {
49
+ console.log('Invalid choice. Please enter 1 or 2.');
50
+ askQuestion();
51
+ }
52
+ });
53
+ };
54
+
55
+ askQuestion();
56
+ });
57
+ }
18
58
 
19
59
  function replacePlaceholders(content, placeholderValues) {
20
60
  Object.keys(placeholderValues).forEach((key) => {
@@ -24,24 +64,124 @@ function replacePlaceholders(content, placeholderValues) {
24
64
  return content;
25
65
  }
26
66
 
27
- function copyTemplateFiles() {
28
- const templateDir = path.join(__dirname, "template");
67
+ function updateProgress(percentage, message) {
68
+ const barLength = 20;
69
+ const filledLength = Math.round((percentage / 100) * barLength);
70
+ const bar = '█'.repeat(filledLength) + '░'.repeat(barLength - filledLength);
71
+
72
+ // Clear the current line and move cursor to beginning
73
+ process.stdout.write('\r\x1b[K');
74
+ process.stdout.write(`[${bar}] ${percentage}% - ${message}`);
75
+
76
+ if (percentage === 100) {
77
+ process.stdout.write('\n');
78
+ }
79
+ }
80
+
81
+ function copyTemplateFiles(templateType, projectName, targetDir) {
82
+ const templateDir = path.join(__dirname, `template-${templateType}`);
83
+
84
+ // Check if template directory exists
85
+ if (!fs.existsSync(templateDir)) {
86
+ console.error(`Template directory 'template-${templateType}' not found!`);
87
+ process.exit(1);
88
+ }
29
89
 
90
+ console.log("\nSetting up project...");
91
+
92
+ // Step 1: Create directory
93
+ updateProgress(10, "Creating project directory...");
30
94
  fs.mkdirSync(targetDir, { recursive: true });
31
95
 
96
+ // Step 2: Copy template files
97
+ updateProgress(30, "Copying template files...");
32
98
  copyRecursive(templateDir, targetDir);
33
99
 
100
+ // Step 3: Replace placeholders
101
+ updateProgress(60, "Configuring project files...");
34
102
  replacePlaceholdersInDirectory(targetDir, { projectName });
103
+
104
+ // Step 4: Create .gitignore file
105
+ updateProgress(80, "Creating .gitignore file...");
106
+ createGitignoreFile(targetDir);
107
+
108
+ // Step 5: Finalizing
109
+ updateProgress(100, "Project setup complete!");
110
+ console.log(""); // New line after progress
111
+ }
112
+
113
+ function createGitignoreFile(projectDir) {
114
+ const gitignoreContent = `# dependencies
115
+ /node_modules
116
+ /.pnp
117
+ .pnp.*
118
+ .yarn/*
119
+ !.yarn/patches
120
+ !.yarn/plugins
121
+ !.yarn/releases
122
+ !.yarn/versions
123
+
124
+ # testing
125
+ /coverage
126
+
127
+ # next.js
128
+ /.next/
129
+ /out/
130
+
131
+ # production
132
+ /build
133
+
134
+ # misc
135
+ .DS_Store
136
+ *.pem
137
+
138
+ # debug
139
+ npm-debug.log*
140
+ yarn-debug.log*
141
+ yarn-error.log*
142
+ .pnpm-debug.log*
143
+
144
+ # env files (can opt-in for committing if needed)
145
+ .env*
146
+
147
+ # vercel
148
+ .vercel
149
+
150
+ # typescript
151
+ *.tsbuildinfo
152
+ next-env.d.ts
153
+ `;
154
+
155
+ try {
156
+ const gitignorePath = path.join(projectDir, '.gitignore');
157
+ fs.writeFileSync(gitignorePath, gitignoreContent);
158
+ } catch (error) {
159
+ //
160
+ }
35
161
  }
36
162
 
37
163
  function copyRecursive(source, target) {
38
- if (fs.statSync(source).isDirectory()) {
39
- fs.mkdirSync(target, { recursive: true });
40
- fs.readdirSync(source).forEach((file) => {
41
- copyRecursive(path.join(source, file), path.join(target, file));
42
- });
43
- } else {
44
- fs.copyFileSync(source, target);
164
+ try {
165
+ if (fs.statSync(source).isDirectory()) {
166
+ fs.mkdirSync(target, { recursive: true });
167
+ const files = fs.readdirSync(source);
168
+
169
+ for (const file of files) {
170
+ // Skip node_modules and other system directories
171
+ if (file === 'node_modules' || file === '.git' || file === 'dist' || file === 'build' || file === '.next') {
172
+ continue;
173
+ }
174
+
175
+ const sourcePath = path.join(source, file);
176
+ const targetPath = path.join(target, file);
177
+ copyRecursive(sourcePath, targetPath);
178
+ }
179
+ } else {
180
+ fs.copyFileSync(source, target);
181
+ }
182
+ } catch (error) {
183
+ console.error(`Error copying ${source} to ${target}:`, error.message);
184
+ throw error;
45
185
  }
46
186
  }
47
187
 
@@ -53,40 +193,109 @@ function sanitizeProjectName(name) {
53
193
  }
54
194
 
55
195
  function replacePlaceholdersInDirectory(directory, placeholderValues) {
196
+ try {
197
+ const sanitizedProjectName = sanitizeProjectName(placeholderValues.projectName);
198
+ const files = fs.readdirSync(directory);
56
199
 
57
- const sanitizedProjectName = sanitizeProjectName(placeholderValues.projectName);
200
+ for (const file of files) {
201
+ const filePath = path.join(directory, file);
202
+
203
+ // Skip node_modules and other system directories
204
+ if (file === 'node_modules' || file === '.git' || file === 'dist' || file === 'build' || file === '.next') {
205
+ continue;
206
+ }
207
+
208
+ if (fs.statSync(filePath).isDirectory()) {
209
+ replacePlaceholdersInDirectory(filePath, placeholderValues);
210
+ } else {
211
+ let content = fs.readFileSync(filePath, "utf8");
58
212
 
59
- fs.readdirSync(directory).forEach((file) => {
60
- const filePath = path.join(directory, file);
61
- if (fs.statSync(filePath).isDirectory()) {
62
- replacePlaceholdersInDirectory(filePath, placeholderValues);
63
- } else {
64
- let content = fs.readFileSync(filePath, "utf8");
213
+ if (file === "package.json" || file === "package-lock.json") {
214
+ try {
215
+ const jsonContent = JSON.parse(content);
216
+ jsonContent.name = sanitizedProjectName;
217
+
218
+ // Update all dependencies to latest versions
219
+ if (jsonContent.dependencies) {
220
+ Object.keys(jsonContent.dependencies).forEach(dep => {
221
+ jsonContent.dependencies[dep] = "latest";
222
+ });
223
+ }
224
+ if (jsonContent.devDependencies) {
225
+ Object.keys(jsonContent.devDependencies).forEach(dep => {
226
+ jsonContent.devDependencies[dep] = "latest";
227
+ });
228
+ }
229
+
230
+ content = JSON.stringify(jsonContent, null, 2);
231
+ } catch (jsonError) {
232
+ console.warn(`Warning: Could not parse JSON in ${filePath}:`, jsonError.message);
233
+ // Fallback to string replacement
234
+ content = content.replace(/\{\{projectName\}\}/g, sanitizedProjectName);
235
+ }
236
+ } else if (file === "index.html" || file.endsWith(".html")) {
237
+ // Replace project name in HTML title and meta tags
238
+ content = content.replace(/\{\{projectName\}\}/g, placeholderValues.projectName);
239
+ // Also replace common placeholders like "Revo" with project name
240
+ content = content.replace(/Revo/g, placeholderValues.projectName);
241
+ } else if (file.endsWith(".tsx") || file.endsWith(".ts") || file.endsWith(".jsx") || file.endsWith(".js")) {
242
+ // Replace project name in React/Next.js files
243
+ content = content.replace(/\{\{projectName\}\}/g, placeholderValues.projectName);
244
+ // Replace common placeholders
245
+ content = content.replace(/Create Next App/g, placeholderValues.projectName);
246
+ content = content.replace(/Generated by create next app/g, `Generated by ${placeholderValues.projectName}`);
247
+ } else {
248
+ // Use the optimized replacePlaceholders function for other files
249
+ content = replacePlaceholders(content, placeholderValues);
250
+ }
65
251
 
66
- if (file === "package.json" || file === "package-lock.json") {
67
- const jsonContent = JSON.parse(content);
68
- jsonContent.name = sanitizedProjectName;
69
- content = JSON.stringify(jsonContent, null, 2);
70
- } else {
71
- Object.keys(placeholderValues).forEach((key) => {
72
- const placeholder = `{{${key}}}`;
73
- content = content.replace(new RegExp(placeholder, "g"), placeholderValues[key]);
74
- });
252
+ fs.writeFileSync(filePath, content);
75
253
  }
76
-
77
- fs.writeFileSync(filePath, content);
78
254
  }
79
- });
255
+ } catch (error) {
256
+ console.error(`Error processing directory ${directory}:`, error.message);
257
+ throw error;
258
+ }
80
259
  }
81
260
 
82
- try {
83
- console.log("Setting up project...");
84
- copyTemplateFiles();
85
- console.log(`Project created at ${targetDir}`);
86
- process.chdir(targetDir);
87
- console.log("Project setup complete!");
88
- console.log("Run npm install and you are set.");
89
- } catch (error) {
90
- console.error("Error creating project:", error);
91
- process.exit(1);
261
+ async function main() {
262
+ try {
263
+ let finalProjectName = projectName;
264
+
265
+ // If no project name provided, ask for it
266
+ if (!finalProjectName) {
267
+ finalProjectName = await askProjectName();
268
+ }
269
+
270
+ // Validate project name
271
+ if (!/^[a-zA-Z0-9-_~]+$/.test(finalProjectName)) {
272
+ console.error("Project name can only contain letters, numbers, hyphens, underscores, and tildes");
273
+ process.exit(1);
274
+ }
275
+
276
+ const finalTargetDir = path.join(process.cwd(), finalProjectName);
277
+
278
+ // Check if target directory already exists
279
+ if (fs.existsSync(finalTargetDir)) {
280
+ console.error(`Directory '${finalProjectName}' already exists! Please choose a different name.`);
281
+ process.exit(1);
282
+ }
283
+
284
+ // Ask user to choose template
285
+ const templateType = await askTemplateChoice();
286
+
287
+ copyTemplateFiles(templateType, finalProjectName, finalTargetDir);
288
+
289
+ console.log(`Project created successfully at ${finalTargetDir}`);
290
+ process.chdir(finalTargetDir);
291
+
292
+ console.log("\nNext steps:");
293
+ console.log("1. Run: npm install");
294
+ console.log("2. Run: npm run dev");
295
+ } catch (error) {
296
+ console.error("Error creating project:", error.message);
297
+ process.exit(1);
298
+ }
92
299
  }
300
+
301
+ main();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-revo",
3
- "version": "1.2.7",
4
- "description": "React Project Setup Tool built on Vite",
3
+ "version": "2.0.1",
4
+ "description": "Project setup tool for ReactJS and NextJS",
5
5
  "main": "cli.js",
6
6
  "bin": {
7
7
  "create-revo": "./cli.js"
@@ -12,9 +12,14 @@
12
12
  "keywords": [
13
13
  "build",
14
14
  "tool",
15
- "bread",
16
15
  "react",
16
+ "nextjs",
17
+ "next.js",
18
+ "typescript",
19
+ "tailwind",
20
+ "vite",
17
21
  "project",
22
+ "template",
18
23
  "maybetarun"
19
24
  ],
20
25
  "author": "Tarun Gupta",
@@ -0,0 +1,36 @@
1
+ This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-revo`](https://www.npmjs.com/package/create-revo) for {{projectName}}.
2
+
3
+ ## Getting Started
4
+
5
+ First, run the development server:
6
+
7
+ ```bash
8
+ npm run dev
9
+ # or
10
+ yarn dev
11
+ # or
12
+ pnpm dev
13
+ # or
14
+ bun dev
15
+ ```
16
+
17
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18
+
19
+ You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20
+
21
+ This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22
+
23
+ ## Learn More
24
+
25
+ To learn more about Next.js, take a look at the following resources:
26
+
27
+ - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28
+ - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29
+
30
+ You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31
+
32
+ ## Deploy on Vercel
33
+
34
+ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35
+
36
+ Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
@@ -0,0 +1,25 @@
1
+ import { dirname } from "path";
2
+ import { fileURLToPath } from "url";
3
+ import { FlatCompat } from "@eslint/eslintrc";
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+
8
+ const compat = new FlatCompat({
9
+ baseDirectory: __dirname,
10
+ });
11
+
12
+ const eslintConfig = [
13
+ ...compat.extends("next/core-web-vitals", "next/typescript"),
14
+ {
15
+ ignores: [
16
+ "node_modules/**",
17
+ ".next/**",
18
+ "out/**",
19
+ "build/**",
20
+ "next-env.d.ts",
21
+ ],
22
+ },
23
+ ];
24
+
25
+ export default eslintConfig;
@@ -0,0 +1,7 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ /* config options here */
5
+ };
6
+
7
+ export default nextConfig;