create-revo 2.0.2 → 2.0.4

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 (43) hide show
  1. package/cli.js +18 -44
  2. package/package.json +1 -1
  3. package/template-nextjs/next.config.ts +1 -0
  4. package/template-nextjs/package-lock.json +12 -1
  5. package/template-nextjs/package.json +2 -1
  6. package/template-nextjs/src/app/page.tsx +24 -18
  7. package/template-reactjs/package-lock.json +17 -6
  8. package/template-reactjs/package.json +2 -1
  9. package/template-reactjs/src/App.tsx +24 -15
  10. package/test/README.md +28 -36
  11. package/test/eslint.config.js +28 -0
  12. package/test/index.html +19 -0
  13. package/test/package-lock.json +2353 -4380
  14. package/test/package.json +20 -14
  15. package/test/postcss.config.js +6 -0
  16. package/test/public/favicon.ico +0 -0
  17. package/test/src/App.tsx +34 -0
  18. package/test/src/assets/revo.svg +4 -0
  19. package/test/src/index.css +17 -0
  20. package/test/src/main.tsx +15 -0
  21. package/test/src/vite-env.d.ts +1 -0
  22. package/test/tailwind.config.js +11 -0
  23. package/test/tsconfig.app.json +24 -0
  24. package/test/tsconfig.json +5 -25
  25. package/test/tsconfig.node.json +24 -0
  26. package/test/vite.config.ts +10 -0
  27. package/test2/README.md +36 -0
  28. package/{test → test2}/next.config.ts +1 -0
  29. package/test2/package-lock.json +6193 -0
  30. package/test2/package.json +29 -0
  31. package/test2/public/revo.svg +4 -0
  32. package/test2/src/app/components/dltme +0 -0
  33. package/test2/src/app/favicon.ico +0 -0
  34. package/test2/src/app/page.tsx +32 -0
  35. package/test2/tsconfig.json +27 -0
  36. package/test/public/revo.png +0 -0
  37. package/test/src/app/favicon.ico +0 -0
  38. package/test/src/app/page.tsx +0 -24
  39. /package/test/src/{app/components → components}/dltme +0 -0
  40. /package/{test → test2}/eslint.config.mjs +0 -0
  41. /package/{test → test2}/postcss.config.mjs +0 -0
  42. /package/{test → test2}/src/app/globals.css +0 -0
  43. /package/{test → test2}/src/app/layout.tsx +0 -0
package/cli.js CHANGED
@@ -64,50 +64,26 @@ function replacePlaceholders(content, placeholderValues) {
64
64
  return content;
65
65
  }
66
66
 
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
67
  function copyTemplateFiles(templateType, projectName, targetDir) {
82
68
  const templateDir = path.join(__dirname, `template-${templateType}`);
83
69
 
84
- // Check if template directory exists
85
70
  if (!fs.existsSync(templateDir)) {
86
71
  console.error(`Template directory 'template-${templateType}' not found!`);
87
72
  process.exit(1);
88
73
  }
89
74
 
90
- console.log("\nSetting up project...");
75
+ console.log("\nSetting up project...\n");
91
76
 
92
- // Step 1: Create directory
93
- updateProgress(10, "Creating project directory...");
94
77
  fs.mkdirSync(targetDir, { recursive: true });
95
78
 
96
- // Step 2: Copy template files
97
- updateProgress(30, "Copying template files...");
98
79
  copyRecursive(templateDir, targetDir);
99
80
 
100
- // Step 3: Replace placeholders
101
- updateProgress(60, "Configuring project files...");
102
- replacePlaceholdersInDirectory(targetDir, { projectName });
81
+ replacePlaceholdersInDirectory(targetDir, {
82
+ projectName
83
+ });
103
84
 
104
- // Step 4: Create .gitignore file
105
- updateProgress(80, "Creating .gitignore file...");
106
85
  createGitignoreFile(targetDir);
107
86
 
108
- // Step 5: Finalizing
109
- updateProgress(100, "Project setup complete!");
110
- console.log(""); // New line after progress
111
87
  }
112
88
 
113
89
  function createGitignoreFile(projectDir) {
@@ -167,7 +143,6 @@ function copyRecursive(source, target) {
167
143
  const files = fs.readdirSync(source);
168
144
 
169
145
  for (const file of files) {
170
- // Skip node_modules and other system directories
171
146
  if (file === 'node_modules' || file === '.git' || file === 'dist' || file === 'build' || file === '.next') {
172
147
  continue;
173
148
  }
@@ -200,7 +175,6 @@ function replacePlaceholdersInDirectory(directory, placeholderValues) {
200
175
  for (const file of files) {
201
176
  const filePath = path.join(directory, file);
202
177
 
203
- // Skip node_modules and other system directories
204
178
  if (file === 'node_modules' || file === '.git' || file === 'dist' || file === 'build' || file === '.next') {
205
179
  continue;
206
180
  }
@@ -215,7 +189,6 @@ function replacePlaceholdersInDirectory(directory, placeholderValues) {
215
189
  const jsonContent = JSON.parse(content);
216
190
  jsonContent.name = sanitizedProjectName;
217
191
 
218
- // Update all dependencies to latest versions
219
192
  if (jsonContent.dependencies) {
220
193
  Object.keys(jsonContent.dependencies).forEach(dep => {
221
194
  jsonContent.dependencies[dep] = "latest";
@@ -227,25 +200,27 @@ function replacePlaceholdersInDirectory(directory, placeholderValues) {
227
200
  });
228
201
  }
229
202
 
203
+ if (placeholderValues.scaffoldDurationMs) {
204
+ jsonContent.revoMetrics = {
205
+ scaffoldDurationMs: Number(placeholderValues.scaffoldDurationMs)
206
+ };
207
+ }
208
+
230
209
  content = JSON.stringify(jsonContent, null, 2);
231
210
  } catch (jsonError) {
232
211
  console.warn(`Warning: Could not parse JSON in ${filePath}:`, jsonError.message);
233
- // Fallback to string replacement
234
212
  content = content.replace(/\{\{projectName\}\}/g, sanitizedProjectName);
235
213
  }
236
214
  } else if (file === "index.html" || file.endsWith(".html")) {
237
- // Replace project name in HTML title and meta tags
238
215
  content = content.replace(/\{\{projectName\}\}/g, placeholderValues.projectName);
239
- // Also replace common placeholders like "Revo" with project name
240
216
  content = content.replace(/Revo/g, placeholderValues.projectName);
217
+ // removed scaffoldDurationMs placeholder handling
241
218
  } else if (file.endsWith(".tsx") || file.endsWith(".ts") || file.endsWith(".jsx") || file.endsWith(".js")) {
242
- // Replace project name in React/Next.js files
243
219
  content = content.replace(/\{\{projectName\}\}/g, placeholderValues.projectName);
244
- // Replace common placeholders
245
220
  content = content.replace(/Create Next App/g, placeholderValues.projectName);
246
221
  content = content.replace(/Generated by create next app/g, `Generated by ${placeholderValues.projectName}`);
222
+ // removed scaffoldDurationMs placeholder handling
247
223
  } else {
248
- // Use the optimized replacePlaceholders function for other files
249
224
  content = replacePlaceholders(content, placeholderValues);
250
225
  }
251
226
 
@@ -262,12 +237,10 @@ async function main() {
262
237
  try {
263
238
  let finalProjectName = projectName;
264
239
 
265
- // If no project name provided, ask for it
266
240
  if (!finalProjectName) {
267
241
  finalProjectName = await askProjectName();
268
242
  }
269
243
 
270
- // Validate project name
271
244
  if (!/^[a-zA-Z0-9-_~]+$/.test(finalProjectName)) {
272
245
  console.error("Project name can only contain letters, numbers, hyphens, underscores, and tildes");
273
246
  process.exit(1);
@@ -275,23 +248,24 @@ async function main() {
275
248
 
276
249
  const finalTargetDir = path.join(process.cwd(), finalProjectName);
277
250
 
278
- // Check if target directory already exists
279
251
  if (fs.existsSync(finalTargetDir)) {
280
252
  console.error(`Directory '${finalProjectName}' already exists! Please choose a different name.`);
281
253
  process.exit(1);
282
254
  }
283
255
 
284
- // Ask user to choose template
285
256
  const templateType = await askTemplateChoice();
286
257
 
258
+ const copyStartMs = Date.now();
287
259
  copyTemplateFiles(templateType, finalProjectName, finalTargetDir);
260
+ const copyDurationMs = Date.now() - copyStartMs;
288
261
 
289
- console.log(`Project created successfully at ${finalTargetDir}`);
262
+ console.log(`Time Taken - ${copyDurationMs}ms.`);
263
+ console.log(`\nProject created at ${finalTargetDir}`);
290
264
  process.chdir(finalTargetDir);
291
265
 
292
266
  console.log("\nNext steps:");
293
- console.log("1. Run: npm install");
294
- console.log("2. Run: npm run dev");
267
+ console.log("1. npm install");
268
+ console.log("2. npm run dev");
295
269
  } catch (error) {
296
270
  console.error("Error creating project:", error.message);
297
271
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-revo",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "Project setup tool for ReactJS and NextJS",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -2,6 +2,7 @@ import type { NextConfig } from "next";
2
2
 
3
3
  const nextConfig: NextConfig = {
4
4
  /* config options here */
5
+ transpilePackages: ["revoicons"],
5
6
  };
6
7
 
7
8
  export default nextConfig;
@@ -11,7 +11,8 @@
11
11
  "framer-motion": "^12.23.12",
12
12
  "next": "15.5.2",
13
13
  "react": "19.1.0",
14
- "react-dom": "19.1.0"
14
+ "react-dom": "19.1.0",
15
+ "revoicons": "^1.2.4"
15
16
  },
16
17
  "devDependencies": {
17
18
  "@eslint/eslintrc": "^3",
@@ -5218,6 +5219,16 @@
5218
5219
  "node": ">=0.10.0"
5219
5220
  }
5220
5221
  },
5222
+ "node_modules/revoicons": {
5223
+ "version": "1.2.4",
5224
+ "resolved": "https://registry.npmjs.org/revoicons/-/revoicons-1.2.4.tgz",
5225
+ "integrity": "sha512-a4918brM2qbMvs4B2hTaZ98nUI5Zc+xWazecsQLv46isEBbNLVl1eiuh9XerR3Wt2dzerTn+fTN5y4efISN8fQ==",
5226
+ "license": "MIT",
5227
+ "peerDependencies": {
5228
+ "react": ">=17 || >=18",
5229
+ "react-dom": ">=17 || >=18"
5230
+ }
5231
+ },
5221
5232
  "node_modules/run-parallel": {
5222
5233
  "version": "1.2.0",
5223
5234
  "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -12,7 +12,8 @@
12
12
  "framer-motion": "^12.23.12",
13
13
  "next": "15.5.2",
14
14
  "react": "19.1.0",
15
- "react-dom": "19.1.0"
15
+ "react-dom": "19.1.0",
16
+ "revoicons": "^1.2.4"
16
17
  },
17
18
  "devDependencies": {
18
19
  "@eslint/eslintrc": "^3",
@@ -1,25 +1,31 @@
1
- import Image from 'next/image';
1
+ import { Revo } from 'revoicons';
2
2
 
3
3
  export default function Home() {
4
4
  return (
5
- <div className="bg-[#EFF0EF] w-screen h-screen flex flex-col justify-center items-center select-none">
6
- <div className="flex flex-col items-center space-y-2">
7
- <div className="flex justify-center items-center space-x-4">
8
- <Image
9
- src="/revo.svg"
10
- alt="revo"
11
- width={128}
12
- height={128}
13
- className="w-32 h-32 md:w-32 md:h-32"
14
- priority
15
- />
16
- <h1 className="text-[#2D2A32] text-6xl md:text-[10rem] font-semibold leading-none -mt-10">
17
- revo
18
- </h1>
5
+ <div className="bg-white w-full h-screen flex flex-col">
6
+ <div className="h-[10vh] w-full border-b border-gray-400">
7
+ <div className="h-full w-full md:w-[70vw] mx-auto border-x border-gray-400" />
8
+ </div>
9
+ <div className="h-full w-full md:w-[70vw] mx-auto border-x border-gray-400 flex flex-col justify-center items-center relative overflow-hidden">
10
+ <div className="absolute inset-0 -z-0 bg-[linear-gradient(to_right,theme(colors.gray.100)_1px,transparent_1px),linear-gradient(to_bottom,theme(colors.gray.100)_1px,transparent_1px)] bg-[length:16px_16px]" />
11
+ <div className="flex flex-col items-center space-y-2 relative z-10">
12
+ <div className="flex justify-center items-center space-x-2 md:space-x-4">
13
+ <Revo size={128} className='hidden md:block'/>
14
+ <Revo size={64} className='block md:hidden'/>
15
+ <h1 className="text-black text-[5rem] md:text-[10rem] font-semibold leading-none -mt-6 md:-mt-12">
16
+ revo
17
+ </h1>
18
+ </div>
19
+ <p className="text-black text-sm md:text-lg uppercase text-center max-w-md">
20
+ your project is ready to go
21
+ </p>
22
+ <p className="text-black/80 text-xs tracking-wide">
23
+ setup in under 50ms
24
+ </p>
19
25
  </div>
20
- <p className="text-[#2D2A32] text-base md:text-lg uppercase text-center max-w-md">
21
- your project is ready to go
22
- </p>
26
+ </div>
27
+ <div className="h-[10vh] w-full border-t border-gray-400">
28
+ <div className="h-full w-full md:w-[70vw] mx-auto border-x border-gray-400" />
23
29
  </div>
24
30
  </div>
25
31
  );
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "name": "{{projectName}}",
3
- "version": "1.0.0",
3
+ "version": "0.0.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
- "name": "vite",
8
+ "name": "{{projectName}}",
9
9
  "version": "0.0.0",
10
10
  "dependencies": {
11
11
  "motion": "^11.11.15",
12
12
  "react": "^18.3.1",
13
13
  "react-dom": "^18.3.1",
14
- "react-router-dom": "^6.28.0"
14
+ "react-router-dom": "^6.28.0",
15
+ "revoicons": "^1.2.4"
15
16
  },
16
17
  "devDependencies": {
17
18
  "@eslint/js": "^9.13.0",
@@ -1768,9 +1769,9 @@
1768
1769
  }
1769
1770
  },
1770
1771
  "node_modules/caniuse-lite": {
1771
- "version": "1.0.30001680",
1772
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz",
1773
- "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==",
1772
+ "version": "1.0.30001741",
1773
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz",
1774
+ "integrity": "sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==",
1774
1775
  "dev": true,
1775
1776
  "funding": [
1776
1777
  {
@@ -3431,6 +3432,16 @@
3431
3432
  "node": ">=0.10.0"
3432
3433
  }
3433
3434
  },
3435
+ "node_modules/revoicons": {
3436
+ "version": "1.2.4",
3437
+ "resolved": "https://registry.npmjs.org/revoicons/-/revoicons-1.2.4.tgz",
3438
+ "integrity": "sha512-a4918brM2qbMvs4B2hTaZ98nUI5Zc+xWazecsQLv46isEBbNLVl1eiuh9XerR3Wt2dzerTn+fTN5y4efISN8fQ==",
3439
+ "license": "MIT",
3440
+ "peerDependencies": {
3441
+ "react": ">=17 || >=18",
3442
+ "react-dom": ">=17 || >=18"
3443
+ }
3444
+ },
3434
3445
  "node_modules/rollup": {
3435
3446
  "version": "4.26.0",
3436
3447
  "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz",
@@ -12,7 +12,8 @@
12
12
  "motion": "^11.11.15",
13
13
  "react": "^18.3.1",
14
14
  "react-dom": "^18.3.1",
15
- "react-router-dom": "^6.28.0"
15
+ "react-router-dom": "^6.28.0",
16
+ "revoicons": "^1.2.4"
16
17
  },
17
18
  "devDependencies": {
18
19
  "@eslint/js": "^9.13.0",
@@ -1,22 +1,31 @@
1
- import revo from './assets/revo.svg';
1
+ import { Revo } from 'revoicons';
2
2
 
3
3
  function App() {
4
4
  return (
5
- <div className="bg-[#EFF0EF] w-screen h-screen flex flex-col justify-center items-center select-none">
6
- <div className="flex flex-col items-center space-y-2">
7
- <div className="flex justify-center items-center space-x-4">
8
- <img
9
- src={revo}
10
- alt="revo"
11
- className="w-32 h-32 md:w-32 md:h-32"
12
- />
13
- <h1 className="text-[#2D2A32] text-6xl md:text-[10rem] font-semibold leading-none -mt-10">
14
- revo
15
- </h1>
5
+ <div className="bg-white w-full h-screen flex flex-col">
6
+ <div className="h-[10vh] w-full border-b border-gray-400">
7
+ <div className="h-full w-full md:w-[70vw] mx-auto border-x border-gray-400" />
8
+ </div>
9
+ <div className="h-full w-full md:w-[70vw] mx-auto border-x border-gray-400 flex flex-col justify-center items-center relative overflow-hidden">
10
+ <div className="absolute inset-0 -z-0 bg-[linear-gradient(to_right,theme(colors.gray.100)_1px,transparent_1px),linear-gradient(to_bottom,theme(colors.gray.100)_1px,transparent_1px)] bg-[length:16px_16px]" />
11
+ <div className="flex flex-col items-center space-y-2 relative z-10">
12
+ <div className="flex justify-center items-center space-x-2 md:space-x-4">
13
+ <Revo size={128} className='hidden md:block'/>
14
+ <Revo size={64} className='block md:hidden'/>
15
+ <h1 className="text-black text-[5rem] md:text-[10rem] font-semibold leading-none -mt-6 md:-mt-12">
16
+ revo
17
+ </h1>
18
+ </div>
19
+ <p className="text-black text-sm md:text-lg uppercase text-center max-w-md">
20
+ your project is ready to go
21
+ </p>
22
+ <p className="text-black/80 text-xs tracking-wide">
23
+ setup in under 50ms
24
+ </p>
16
25
  </div>
17
- <p className="text-[#2D2A32] text-base md:text-lg uppercase text-center max-w-md">
18
- your project is ready to go
19
- </p>
26
+ </div>
27
+ <div className="h-[10vh] w-full border-t border-gray-400">
28
+ <div className="h-full w-full md:w-[70vw] mx-auto border-x border-gray-400" />
20
29
  </div>
21
30
  </div>
22
31
  )
package/test/README.md CHANGED
@@ -1,36 +1,28 @@
1
- This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-revo`](https://www.npmjs.com/package/create-revo) for test.
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.
1
+ # test
2
+
3
+ This is a React project bootstrapped with [`create-revo`](https://www.npmjs.com/package/create-revo).
4
+
5
+ ## Getting Started
6
+
7
+ First, run the development server:
8
+
9
+ ```bash
10
+ npm run dev
11
+ ```
12
+
13
+ Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
14
+
15
+ ## Features
16
+
17
+ - Vite for fast development
18
+ - ⚛️ React 18 with TypeScript
19
+ - 🎨 Tailwind CSS for styling
20
+ - 🔧 ESLint for code quality
21
+ - 🚀 Motion for animations
22
+
23
+ ## Learn More
24
+
25
+ To learn more about React, take a look at the following resources:
26
+
27
+ - [React Documentation](https://react.dev) - learn about React features and API.
28
+ - [Vite Documentation](https://vitejs.dev) - learn about Vite features and configuration.
@@ -0,0 +1,28 @@
1
+ import js from '@eslint/js'
2
+ import globals from 'globals'
3
+ import reactHooks from 'eslint-plugin-react-hooks'
4
+ import reactRefresh from 'eslint-plugin-react-refresh'
5
+ import tseslint from 'typescript-eslint'
6
+
7
+ export default tseslint.config(
8
+ { ignores: ['dist'] },
9
+ {
10
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
11
+ files: ['**/*.{ts,tsx}'],
12
+ languageOptions: {
13
+ ecmaVersion: 2020,
14
+ globals: globals.browser,
15
+ },
16
+ plugins: {
17
+ 'react-hooks': reactHooks,
18
+ 'react-refresh': reactRefresh,
19
+ },
20
+ rules: {
21
+ ...reactHooks.configs.recommended.rules,
22
+ 'react-refresh/only-export-components': [
23
+ 'warn',
24
+ { allowConstantExport: true },
25
+ ],
26
+ },
27
+ },
28
+ )
@@ -0,0 +1,19 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/x-icon" href="/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>revo</title>
8
+ <meta name="author" content="Tarun Gupta" />
9
+ <!-- <meta name="keywords" content="" /> -->
10
+ <!-- <meta name="description" content=""/> -->
11
+ <!-- <meta property="og:image" content="" /> -->
12
+ <!-- <meta property="og:title" content="" /> -->
13
+ <!-- <meta property="og:description" content="" /> -->
14
+ </head>
15
+ <body>
16
+ <div id="root"></div>
17
+ <script type="module" src="/src/main.tsx"></script>
18
+ </body>
19
+ </html>