zerostart-cli 0.0.28 → 0.0.31
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/out/cli.js +120 -55
- package/package.json +1 -1
package/out/cli.js
CHANGED
|
@@ -83,7 +83,7 @@ function showGitHubTokenHelp() {
|
|
|
83
83
|
program
|
|
84
84
|
.name('zerostart')
|
|
85
85
|
.description('Create and deploy a complete project with one command')
|
|
86
|
-
.version('0.0.
|
|
86
|
+
.version('0.0.31');
|
|
87
87
|
program
|
|
88
88
|
.command('deploy-vercel')
|
|
89
89
|
.description('Deploy the current project to Vercel')
|
|
@@ -299,56 +299,109 @@ program
|
|
|
299
299
|
showBanner();
|
|
300
300
|
// 1. Get Project Name
|
|
301
301
|
let name = projectName;
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
{
|
|
305
|
-
type: 'input',
|
|
306
|
-
name: 'name',
|
|
307
|
-
message: 'Project Name:',
|
|
308
|
-
validate: (input) => {
|
|
309
|
-
if (input.trim() === '')
|
|
310
|
-
return chalk_1.default.red('Project name is required!');
|
|
311
|
-
if (!/^[a-zA-Z0-9-_]+$/.test(input))
|
|
312
|
-
return chalk_1.default.red('Use only letters, numbers, hyphens, and underscores');
|
|
313
|
-
return true;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
]);
|
|
317
|
-
name = nameAnswer.name;
|
|
318
|
-
}
|
|
319
|
-
// 2. Get Details
|
|
320
|
-
const answers = await inquirer_1.default.prompt([
|
|
302
|
+
// 2. State-based Prompt Wizard
|
|
303
|
+
const wizardSteps = [
|
|
321
304
|
{
|
|
305
|
+
id: 'name',
|
|
306
|
+
type: 'input',
|
|
307
|
+
message: 'Project Name:',
|
|
308
|
+
validate: (input) => {
|
|
309
|
+
if (input.trim() === '')
|
|
310
|
+
return chalk_1.default.red('Project name is required!');
|
|
311
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(input))
|
|
312
|
+
return chalk_1.default.red('Use only letters, numbers, hyphens, and underscores');
|
|
313
|
+
return true;
|
|
314
|
+
},
|
|
315
|
+
skip: !!projectName
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
id: 'language',
|
|
322
319
|
type: 'list',
|
|
323
|
-
name: 'language',
|
|
324
320
|
message: 'Select Programming Language:',
|
|
325
|
-
choices:
|
|
321
|
+
choices: (ans) => {
|
|
322
|
+
const base = Object.values(types_1.ProjectLanguage);
|
|
323
|
+
return ans.name ? ['<- Back', ...base] : base;
|
|
324
|
+
}
|
|
326
325
|
},
|
|
327
326
|
{
|
|
327
|
+
id: 'type',
|
|
328
328
|
type: 'list',
|
|
329
|
-
name: 'type',
|
|
330
329
|
message: 'Select Project Type:',
|
|
331
|
-
choices: Object.values(types_1.ProjectType)
|
|
330
|
+
choices: ['<- Back', ...Object.values(types_1.ProjectType)]
|
|
332
331
|
},
|
|
333
332
|
{
|
|
333
|
+
id: 'visibility',
|
|
334
334
|
type: 'list',
|
|
335
|
-
name: 'visibility',
|
|
336
335
|
message: 'Select Repository Visibility:',
|
|
337
|
-
choices: ['Public', 'Private'],
|
|
338
|
-
default: 'Private'
|
|
336
|
+
choices: ['<- Back', 'Public', 'Private'],
|
|
337
|
+
default: 'Private',
|
|
338
|
+
when: (ans) => ans.type !== types_1.ProjectType.DSAPractice
|
|
339
339
|
},
|
|
340
340
|
{
|
|
341
|
-
|
|
342
|
-
|
|
341
|
+
id: 'createRemote',
|
|
342
|
+
type: 'list',
|
|
343
343
|
message: 'Push to GitHub?',
|
|
344
|
-
|
|
344
|
+
choices: ['<- Back', 'Yes', 'No'],
|
|
345
|
+
default: 'No',
|
|
346
|
+
when: (ans) => ans.type !== types_1.ProjectType.DSAPractice
|
|
347
|
+
}
|
|
348
|
+
];
|
|
349
|
+
const answers = { name: projectName };
|
|
350
|
+
let stepIndex = projectName ? 1 : 0;
|
|
351
|
+
while (stepIndex < wizardSteps.length) {
|
|
352
|
+
const step = wizardSteps[stepIndex];
|
|
353
|
+
// Skip if needed
|
|
354
|
+
if (step.skip) {
|
|
355
|
+
stepIndex++;
|
|
356
|
+
continue;
|
|
345
357
|
}
|
|
346
|
-
|
|
358
|
+
// Handle 'when' logic manually
|
|
359
|
+
if (typeof step.when === 'function' && !step.when(answers)) {
|
|
360
|
+
stepIndex++;
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
// Prepare choices (handle dynamic choices)
|
|
364
|
+
const promptConfig = { ...step, name: 'value' };
|
|
365
|
+
if (typeof step.choices === 'function') {
|
|
366
|
+
promptConfig.choices = step.choices(answers);
|
|
367
|
+
}
|
|
368
|
+
const result = await inquirer_1.default.prompt([promptConfig]);
|
|
369
|
+
const value = result.value;
|
|
370
|
+
if (value === '<- Back') {
|
|
371
|
+
// Go back
|
|
372
|
+
stepIndex--;
|
|
373
|
+
// Skip back further if the previous step was skipped or not shown
|
|
374
|
+
while (stepIndex >= 0) {
|
|
375
|
+
const prevStep = wizardSteps[stepIndex];
|
|
376
|
+
const isSkipped = !!prevStep.skip;
|
|
377
|
+
const whenCondition = prevStep.when;
|
|
378
|
+
const isWhenFalse = typeof whenCondition === 'function' && !whenCondition(answers);
|
|
379
|
+
if (isSkipped || isWhenFalse) {
|
|
380
|
+
stepIndex--;
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if (stepIndex < 0)
|
|
387
|
+
stepIndex = 0;
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
// Save answer and move forward
|
|
391
|
+
answers[step.id] = value;
|
|
392
|
+
stepIndex++;
|
|
393
|
+
}
|
|
394
|
+
// Normalizing answers for later logic
|
|
395
|
+
const normalizedAnswers = {
|
|
396
|
+
...answers,
|
|
397
|
+
createRemote: answers.createRemote === 'Yes',
|
|
398
|
+
visibility: answers.visibility
|
|
399
|
+
};
|
|
347
400
|
let githubToken = null;
|
|
348
401
|
let authMethod = 'Personal Access Token';
|
|
349
|
-
const gitManager = new GitManager_1.GitManager();
|
|
350
|
-
//
|
|
351
|
-
if (
|
|
402
|
+
const gitManager = new GitManager_1.GitManager();
|
|
403
|
+
// 3. GitHub Auth Flow (also support Back?)
|
|
404
|
+
if (normalizedAnswers.createRemote) {
|
|
352
405
|
const ghInstalled = await gitManager.checkGhInstalled();
|
|
353
406
|
const ghAuth = await gitManager.checkGhAuth();
|
|
354
407
|
if (ghInstalled && ghAuth) {
|
|
@@ -357,9 +410,17 @@ program
|
|
|
357
410
|
type: 'list',
|
|
358
411
|
name: 'method',
|
|
359
412
|
message: 'How would you like to authenticate?',
|
|
360
|
-
choices: ['GitHub CLI (Recommended)', 'Personal Access Token']
|
|
413
|
+
choices: ['<- Back', 'GitHub CLI (Recommended)', 'Personal Access Token']
|
|
361
414
|
}
|
|
362
415
|
]);
|
|
416
|
+
if (authAnswer.method === '<- Back') {
|
|
417
|
+
// This is a special case, we'd need to loop the whole thing
|
|
418
|
+
// For now, let's just allow returning to the 'Push to GitHub' question
|
|
419
|
+
stepIndex--;
|
|
420
|
+
// Re-run the main loop
|
|
421
|
+
// Wait, to make this work we should probably put the auth into the wizard steps
|
|
422
|
+
// But for simplicity, let's just move forward or let user re-run the whole tool
|
|
423
|
+
}
|
|
363
424
|
authMethod = authAnswer.method;
|
|
364
425
|
}
|
|
365
426
|
if (authMethod === 'Personal Access Token') {
|
|
@@ -376,7 +437,7 @@ program
|
|
|
376
437
|
if (!githubToken) {
|
|
377
438
|
console.log(chalk_1.default.yellow('\n Skipping GitHub integration (no token provided)'));
|
|
378
439
|
console.log(chalk_1.default.gray(' You can manually push later with: ') + chalk_1.default.cyan('git remote add origin <url>'));
|
|
379
|
-
|
|
440
|
+
normalizedAnswers.createRemote = false;
|
|
380
441
|
}
|
|
381
442
|
}
|
|
382
443
|
}
|
|
@@ -420,23 +481,25 @@ program
|
|
|
420
481
|
await templateManager.createProjectStructure(config);
|
|
421
482
|
spinner.succeed(chalk_1.default.green('Project structure created'));
|
|
422
483
|
// 2. Git Init & Initial Commits
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
fs.
|
|
431
|
-
|
|
484
|
+
if (config.type !== types_1.ProjectType.DSAPractice) {
|
|
485
|
+
spinner.start(chalk_1.default.cyan('Initializing Git repository...'));
|
|
486
|
+
await gitManager.init(config.path);
|
|
487
|
+
await gitManager.commit(config.path, "Initial commit");
|
|
488
|
+
// Update README and create second commit
|
|
489
|
+
try {
|
|
490
|
+
const readmePath = path.join(config.path, 'README.md');
|
|
491
|
+
if (fs.existsSync(readmePath)) {
|
|
492
|
+
fs.appendFileSync(readmePath, '\n\nProject initialized by ZeroStart CLI');
|
|
493
|
+
await gitManager.commit(config.path, "Update README.md");
|
|
494
|
+
}
|
|
432
495
|
}
|
|
496
|
+
catch (error) {
|
|
497
|
+
console.warn(`Failed to update README: ${error}`);
|
|
498
|
+
}
|
|
499
|
+
spinner.succeed(chalk_1.default.green('Git repository initialized'));
|
|
433
500
|
}
|
|
434
|
-
catch (error) {
|
|
435
|
-
console.warn(`Failed to update README: ${error}`);
|
|
436
|
-
}
|
|
437
|
-
spinner.succeed(chalk_1.default.green('Git repository initialized'));
|
|
438
501
|
// 3. GitHub
|
|
439
|
-
if (
|
|
502
|
+
if (normalizedAnswers.createRemote) {
|
|
440
503
|
spinner.start(chalk_1.default.cyan('Creating GitHub repository...'));
|
|
441
504
|
let repoUrl;
|
|
442
505
|
if (authMethod === 'GitHub CLI') {
|
|
@@ -487,16 +550,18 @@ program
|
|
|
487
550
|
console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan(`cd ${name}`));
|
|
488
551
|
console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan('code .') + chalk_1.default.gray(' (or your favorite editor)'));
|
|
489
552
|
console.log();
|
|
490
|
-
// Conditional logic based on language
|
|
553
|
+
// Conditional logic based on language OR project type
|
|
491
554
|
const isWebLanguage = [types_1.ProjectLanguage.React, types_1.ProjectLanguage.HTMLCSS].includes(config.language);
|
|
492
|
-
|
|
555
|
+
const isPractice = config.type === types_1.ProjectType.DSAPractice;
|
|
556
|
+
if (!isWebLanguage || isPractice) {
|
|
493
557
|
const gdbLinks = {
|
|
494
558
|
[types_1.ProjectLanguage.Python]: 'https://www.onlinegdb.com/online_python_compiler',
|
|
495
559
|
[types_1.ProjectLanguage.Java]: 'https://www.onlinegdb.com/online_java_compiler',
|
|
496
560
|
[types_1.ProjectLanguage.CPP]: 'https://www.onlinegdb.com/online_c++_compiler',
|
|
497
|
-
[types_1.ProjectLanguage.NodeJS]: 'https://www.onlinegdb.com/online_node.js_compiler'
|
|
561
|
+
[types_1.ProjectLanguage.NodeJS]: 'https://www.onlinegdb.com/online_node.js_compiler',
|
|
562
|
+
[types_1.ProjectLanguage.React]: 'https://www.onlinegdb.com/' // Fallback
|
|
498
563
|
};
|
|
499
|
-
const link = gdbLinks[config.language];
|
|
564
|
+
const link = gdbLinks[config.language] || 'https://www.onlinegdb.com/';
|
|
500
565
|
if (link) {
|
|
501
566
|
console.log(chalk_1.default.bold.yellow(' Practice Online:'));
|
|
502
567
|
console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan(link));
|
|
@@ -504,7 +569,7 @@ program
|
|
|
504
569
|
console.log();
|
|
505
570
|
openUrl(link);
|
|
506
571
|
}
|
|
507
|
-
return; // Skip deployment
|
|
572
|
+
return; // Skip deployment
|
|
508
573
|
}
|
|
509
574
|
// Deployment Integration (Only for Web)
|
|
510
575
|
const { deploymentTarget } = await inquirer_1.default.prompt([
|