create-quapp 1.0.1 → 1.0.20

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 (2) hide show
  1. package/index.js +61 -45
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -4,14 +4,13 @@ import { execSync } from 'child_process';
4
4
  import fs from 'fs';
5
5
  import path from 'path';
6
6
  import { fileURLToPath } from 'url';
7
- import readline from 'readline';
8
7
  import { createRequire } from 'module';
9
8
  const require = createRequire(import.meta.url);
10
9
 
11
10
  const degit = (await import('degit')).default;
12
11
  const prompts = (await import('prompts')).default;
13
12
 
14
- // Terminal Colors
13
+ // ========== Terminal Colors ==========
15
14
  const red = (text) => `\x1b[31m${text}\x1b[0m`;
16
15
  const green = (text) => `\x1b[32m${text}\x1b[0m`;
17
16
  const yellow = (text) => `\x1b[33m${text}\x1b[0m`;
@@ -20,13 +19,7 @@ const boldBlue = (text) => `\x1b[1m\x1b[34m${text}\x1b[0m`;
20
19
 
21
20
  const colorize = (text, fn) => (process.argv.includes('--no-color') ? text : fn(text));
22
21
 
23
- // Ctrl+C handler
24
- process.on('SIGINT', () => {
25
- cleanupInput();
26
- console.log(red('\n Setup canceled (Ctrl+C).\n'));
27
- process.exit(0);
28
- });
29
-
22
+ // ========== Escape + Ctrl+C Handling ==========
30
23
  function setupEscapeHandler() {
31
24
  if (process.stdin.isTTY) {
32
25
  process.stdin.setRawMode(true);
@@ -51,7 +44,22 @@ function cleanupInput() {
51
44
  process.stdin.removeListener('data', handleKeyPress);
52
45
  }
53
46
 
54
- // Core fs helper replacements for fs-extra
47
+ process.on('SIGINT', () => {
48
+ cleanupInput();
49
+ console.log(red('\n Setup canceled (Ctrl+C).\n'));
50
+ process.exit(0);
51
+ });
52
+
53
+ // ========== Helper Functions ==========
54
+ function isGitAvailable() {
55
+ try {
56
+ execSync('git --version', { stdio: 'ignore' });
57
+ return true;
58
+ } catch {
59
+ return false;
60
+ }
61
+ }
62
+
55
63
  function removeDir(dirPath) {
56
64
  if (fs.existsSync(dirPath)) {
57
65
  fs.rmSync(dirPath, { recursive: true, force: true });
@@ -72,6 +80,7 @@ function copyRecursiveSync(src, dest) {
72
80
  }
73
81
  }
74
82
 
83
+ // ========== Script Starts Here ==========
75
84
  const __filename = fileURLToPath(import.meta.url);
76
85
  const __dirname = path.dirname(__filename);
77
86
 
@@ -79,18 +88,17 @@ const args = process.argv.slice(2);
79
88
  let providedName = args[0];
80
89
  let templateFlagIndex = args.indexOf('--template');
81
90
  let templateArg = templateFlagIndex !== -1 ? args[templateFlagIndex + 1] : null;
91
+
82
92
  const force = args.includes('--force');
83
- const noColor = args.includes('--no-color');
84
93
  const autoGit = args.includes('--git');
85
94
  const autoInstall = args.includes('--install');
86
95
 
96
+ setupEscapeHandler();
97
+
98
+ // ========== Ask Project Name ==========
87
99
  const askProjectName = async () => {
88
- if (providedName) {
89
- return providedName;
90
- }
91
- console.log('\n');
92
- console.log(boldBlue(' Welcome to Quapp Setup!'));
93
- console.log('\n');
100
+ if (providedName) return providedName;
101
+ console.log('\n' + boldBlue(' Welcome to Quapp Setup!\n'));
94
102
  const response = await prompts({
95
103
  type: 'text',
96
104
  name: 'projectName',
@@ -105,8 +113,7 @@ const askProjectName = async () => {
105
113
  return response.projectName.trim();
106
114
  };
107
115
 
108
- setupEscapeHandler();
109
-
116
+ // ========== Main Async Flow ==========
110
117
  try {
111
118
  const projectName = await askProjectName();
112
119
 
@@ -116,9 +123,9 @@ try {
116
123
  vanilla: ['vanilla-js', 'vanilla-ts'],
117
124
  };
118
125
 
119
- console.log('\n');
126
+ // Ask for framework + template
120
127
  if (!templateArg || !Object.values(allTemplates).flat().includes(templateArg)) {
121
- const frameworkChoice = await prompts({
128
+ const { framework } = await prompts({
122
129
  type: 'select',
123
130
  name: 'framework',
124
131
  message: 'Choose a framework:',
@@ -129,44 +136,46 @@ try {
129
136
  ],
130
137
  });
131
138
 
132
- if (!frameworkChoice.framework) {
139
+ if (!framework) {
133
140
  console.log(red('\n Setup canceled.\n'));
134
141
  process.exit(0);
135
142
  }
136
143
 
137
- console.log('\n');
138
-
139
- const response = await prompts({
144
+ const { template } = await prompts({
140
145
  type: 'select',
141
146
  name: 'template',
142
- message: `Choose a ${frameworkChoice.framework} template:`,
143
- choices: allTemplates[frameworkChoice.framework].map((item) => ({
144
- title: item,
145
- value: item,
146
- })),
147
+ message: `Choose a ${framework} template:`,
148
+ choices: allTemplates[framework].map((item) => ({ title: item, value: item })),
147
149
  });
148
150
 
149
- if (!response.template) {
151
+ if (!template) {
150
152
  console.log(red('\n Setup canceled.\n'));
151
153
  process.exit(0);
152
154
  }
153
155
 
154
- templateArg = response.template;
156
+ templateArg = template;
155
157
  }
156
158
 
157
159
  console.log('\n' + colorize(' Creating a new Quapp project...\n', green));
158
-
159
160
  const projectDir = path.join(process.cwd(), projectName);
160
161
  const templateRepo = `Quapp-Store/Quapp/packages/templates/${templateArg}`;
161
162
 
163
+ // ========== Template Cloning ==========
162
164
  try {
163
165
  const emitter = degit(templateRepo, { cache: false, force });
164
166
  await emitter.clone(projectDir);
165
167
  } catch (err) {
168
+ if(err.message.includes('could not find commit hash for HEAD')) {
169
+ console.error(red(`Git not Avilable! Please install Git to use this command.`));
170
+ // giving link to the download Git
171
+ console.error(yellow(`You can download Git from: https://git-scm.com/download`));
172
+ process.exit(1);
173
+ }
166
174
  console.error(red(' Error creating project:'), err.message);
167
175
  process.exit(1);
168
176
  }
169
177
 
178
+ // ========== Update package.json ==========
170
179
  const packageJsonPath = path.join(projectDir, 'package.json');
171
180
  if (fs.existsSync(packageJsonPath)) {
172
181
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
@@ -177,25 +186,33 @@ try {
177
186
  process.exit(1);
178
187
  }
179
188
 
189
+ // ========== Git Setup ==========
180
190
  let gitInit = autoGit;
181
191
  if (!autoGit) {
192
+ const gitMessage = isGitAvailable()
193
+ ? 'Do you want to initialize a Git repository?'
194
+ : 'Git is not installed. Skipping Git setup.';
182
195
  const gitResponse = await prompts({
183
- type: 'confirm',
196
+ type: isGitAvailable() ? 'confirm' : null,
184
197
  name: 'gitInit',
185
- message: 'Do you want to initialize a Git repository?',
198
+ message: gitMessage,
199
+ initial: false,
186
200
  });
187
- gitInit = gitResponse.gitInit;
201
+ gitInit = isGitAvailable() && gitResponse.gitInit;
188
202
  }
189
203
 
190
204
  if (gitInit) {
191
205
  try {
192
206
  execSync('git init', { cwd: projectDir });
193
207
  console.log(blue(' Initialized empty Git repository.'));
194
- } catch (err) {
195
- console.log(yellow(' Git not found. Skipping Git init.'));
208
+ } catch {
209
+ console.log(red(' Failed to initialize Git repository.'));
196
210
  }
211
+ } else if (!isGitAvailable()) {
212
+ console.log(yellow(' Git is not installed. Skipping Git initialization.'));
197
213
  }
198
214
 
215
+ // ========== Dependency Install ==========
199
216
  let doInstall = autoInstall;
200
217
  if (!autoInstall) {
201
218
  const installResponse = await prompts({
@@ -211,17 +228,16 @@ try {
211
228
  try {
212
229
  execSync('npm install', { cwd: projectDir, stdio: 'inherit' });
213
230
  execSync('npm install qrcode-terminal', { cwd: projectDir, stdio: 'ignore' });
214
- } catch (err) {
215
- console.log(yellow(' NPM not found or installation failed. Please install dependencies manually.'));
231
+ } catch {
232
+ console.log(red(' Dependency installation failed. Please run it manually.'));
216
233
  }
217
234
  }
218
235
 
219
- console.log('\n');
236
+ // ========== Done ==========
237
+ console.log('\n' + yellow(`Now run the following commands:\n`));
220
238
  console.log(boldBlue(` cd ${projectName}`));
221
- if (!doInstall) {
222
- console.log(boldBlue(' npm install'));
223
- }
224
- console.log(boldBlue(' npm quapp serve or quapp serve\n'));
239
+ if (!doInstall) console.log(boldBlue(' npm install'));
240
+ console.log(boldBlue(' npm run dev\n'));
225
241
 
226
242
  cleanupInput();
227
243
  setTimeout(() => process.exit(0), 100);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-quapp",
3
- "version": "1.0.1",
3
+ "version": "1.0.20",
4
4
  "description": "Quapp Development tool of the future",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -11,7 +11,7 @@
11
11
  "test": "echo \"Error: no test specified\" && exit 1"
12
12
  },
13
13
  "author": "Quapp",
14
- "license": "ISC",
14
+ "license": "MIT",
15
15
  "dependencies": {
16
16
  "degit": "^2.8.4",
17
17
  "prompts": "^2.4.2"