create-quapp 1.0.2 → 1.0.23

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 +62 -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
 
@@ -114,11 +121,12 @@ try {
114
121
  react: ['react', 'react-ts', 'react+swc', 'react-ts+swc'],
115
122
  vue: ['vue', 'vue-ts'],
116
123
  vanilla: ['vanilla-js', 'vanilla-ts'],
124
+ solid: ['solid-js', 'solid-ts'],
117
125
  };
118
126
 
119
- console.log('\n');
127
+ // Ask for framework + template
120
128
  if (!templateArg || !Object.values(allTemplates).flat().includes(templateArg)) {
121
- const frameworkChoice = await prompts({
129
+ const { framework } = await prompts({
122
130
  type: 'select',
123
131
  name: 'framework',
124
132
  message: 'Choose a framework:',
@@ -126,47 +134,50 @@ try {
126
134
  { title: 'React', value: 'react' },
127
135
  { title: 'Vue', value: 'vue' },
128
136
  { title: 'Vanilla', value: 'vanilla' },
137
+ { title: 'Solid', value: 'solid' },
129
138
  ],
130
139
  });
131
140
 
132
- if (!frameworkChoice.framework) {
141
+ if (!framework) {
133
142
  console.log(red('\n Setup canceled.\n'));
134
143
  process.exit(0);
135
144
  }
136
145
 
137
- console.log('\n');
138
-
139
- const response = await prompts({
146
+ const { template } = await prompts({
140
147
  type: 'select',
141
148
  name: 'template',
142
- message: `Choose a ${frameworkChoice.framework} template:`,
143
- choices: allTemplates[frameworkChoice.framework].map((item) => ({
144
- title: item,
145
- value: item,
146
- })),
149
+ message: `Choose a ${framework} template:`,
150
+ choices: allTemplates[framework].map((item) => ({ title: item, value: item })),
147
151
  });
148
152
 
149
- if (!response.template) {
153
+ if (!template) {
150
154
  console.log(red('\n Setup canceled.\n'));
151
155
  process.exit(0);
152
156
  }
153
157
 
154
- templateArg = response.template;
158
+ templateArg = template;
155
159
  }
156
160
 
157
161
  console.log('\n' + colorize(' Creating a new Quapp project...\n', green));
158
-
159
162
  const projectDir = path.join(process.cwd(), projectName);
160
163
  const templateRepo = `Quapp-Store/Quapp/packages/templates/${templateArg}`;
161
164
 
165
+ // ========== Template Cloning ==========
162
166
  try {
163
167
  const emitter = degit(templateRepo, { cache: false, force });
164
168
  await emitter.clone(projectDir);
165
169
  } catch (err) {
170
+ if(err.message.includes('could not find commit hash for HEAD')) {
171
+ console.error(red(`Git not Avilable! Please install Git to use this command.`));
172
+ // giving link to the download Git
173
+ console.error(yellow(`You can download Git from: https://git-scm.com/download`));
174
+ process.exit(1);
175
+ }
166
176
  console.error(red(' Error creating project:'), err.message);
167
177
  process.exit(1);
168
178
  }
169
179
 
180
+ // ========== Update package.json ==========
170
181
  const packageJsonPath = path.join(projectDir, 'package.json');
171
182
  if (fs.existsSync(packageJsonPath)) {
172
183
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
@@ -177,25 +188,33 @@ try {
177
188
  process.exit(1);
178
189
  }
179
190
 
191
+ // ========== Git Setup ==========
180
192
  let gitInit = autoGit;
181
193
  if (!autoGit) {
194
+ const gitMessage = isGitAvailable()
195
+ ? 'Do you want to initialize a Git repository?'
196
+ : 'Git is not installed. Skipping Git setup.';
182
197
  const gitResponse = await prompts({
183
- type: 'confirm',
198
+ type: isGitAvailable() ? 'confirm' : null,
184
199
  name: 'gitInit',
185
- message: 'Do you want to initialize a Git repository?',
200
+ message: gitMessage,
201
+ initial: false,
186
202
  });
187
- gitInit = gitResponse.gitInit;
203
+ gitInit = isGitAvailable() && gitResponse.gitInit;
188
204
  }
189
205
 
190
206
  if (gitInit) {
191
207
  try {
192
208
  execSync('git init', { cwd: projectDir });
193
209
  console.log(blue(' Initialized empty Git repository.'));
194
- } catch (err) {
195
- console.log(yellow(' Git not found. Skipping Git init.'));
210
+ } catch {
211
+ console.log(red(' Failed to initialize Git repository.'));
196
212
  }
213
+ } else if (!isGitAvailable()) {
214
+ console.log(yellow(' Git is not installed. Skipping Git initialization.'));
197
215
  }
198
216
 
217
+ // ========== Dependency Install ==========
199
218
  let doInstall = autoInstall;
200
219
  if (!autoInstall) {
201
220
  const installResponse = await prompts({
@@ -211,17 +230,15 @@ try {
211
230
  try {
212
231
  execSync('npm install', { cwd: projectDir, stdio: 'inherit' });
213
232
  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.'));
233
+ } catch {
234
+ console.log(red(' Dependency installation failed. Please run it manually.'));
216
235
  }
217
236
  }
218
237
 
219
- console.log('\n');
220
- console.log(yellow(`Now run the following commands to start your project:\n\n`));
238
+ // ========== Done ==========
239
+ console.log('\n' + yellow(`Now run the following commands:\n`));
221
240
  console.log(boldBlue(` cd ${projectName}`));
222
- if (!doInstall) {
223
- console.log(boldBlue(' npm install'));
224
- }
241
+ if (!doInstall) console.log(boldBlue(' npm install'));
225
242
  console.log(boldBlue(' npm run dev\n'));
226
243
 
227
244
  cleanupInput();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-quapp",
3
- "version": "1.0.2",
3
+ "version": "1.0.23",
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"