create-morax 1.0.1 ā 1.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.
- package/dist/index.js +796 -33
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import
|
|
4
|
+
import pc16 from "picocolors";
|
|
5
5
|
|
|
6
6
|
// src/core/runner.ts
|
|
7
|
-
import
|
|
7
|
+
import path13 from "path";
|
|
8
|
+
import { spinner as spinner9 } from "@clack/prompts";
|
|
9
|
+
import pc15 from "picocolors";
|
|
8
10
|
|
|
9
11
|
// src/core/startcli.ts
|
|
10
12
|
import gradient from "gradient-string";
|
|
@@ -82,6 +84,7 @@ import { promisify } from "util";
|
|
|
82
84
|
import pc3 from "picocolors";
|
|
83
85
|
var execAsync = promisify(exec);
|
|
84
86
|
async function runCommand(command, options = {}) {
|
|
87
|
+
options.silent = true;
|
|
85
88
|
if (!options.silent) {
|
|
86
89
|
console.log(pc3.cyan(`> ${command}`));
|
|
87
90
|
}
|
|
@@ -285,13 +288,350 @@ Error details: ${error.message || error}`));
|
|
|
285
288
|
}
|
|
286
289
|
}
|
|
287
290
|
|
|
288
|
-
// src/tasks/
|
|
291
|
+
// src/tasks/eslint.ts
|
|
289
292
|
import { confirm as confirm2, spinner as spinner3 } from "@clack/prompts";
|
|
290
293
|
import pc6 from "picocolors";
|
|
291
294
|
import fsPromises4 from "fs/promises";
|
|
292
295
|
import path4 from "path";
|
|
293
|
-
async function
|
|
296
|
+
async function promptEslint() {
|
|
294
297
|
return await confirm2({
|
|
298
|
+
message: "Do you want to setup ESLint linting in packages/eslint?",
|
|
299
|
+
initialValue: true
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
async function setupEslint(projectPath) {
|
|
303
|
+
const eslintDir = path4.join(projectPath, "packages", "eslint");
|
|
304
|
+
await fsPromises4.mkdir(eslintDir, { recursive: true });
|
|
305
|
+
await runCommand("pnpm init", { cwd: eslintDir, silent: true });
|
|
306
|
+
const eslintPackagePath = path4.join(eslintDir, "package.json");
|
|
307
|
+
const eslintPackageRaw = await fsPromises4.readFile(eslintPackagePath, "utf8");
|
|
308
|
+
const eslintPkg = JSON.parse(eslintPackageRaw);
|
|
309
|
+
eslintPkg.name = "@config/eslint";
|
|
310
|
+
eslintPkg.version = "1.0.0";
|
|
311
|
+
eslintPkg.private = true;
|
|
312
|
+
eslintPkg.type = "module";
|
|
313
|
+
eslintPkg.main = "eslint.config.ts";
|
|
314
|
+
eslintPkg.exports = {
|
|
315
|
+
".": "./eslint.config.ts"
|
|
316
|
+
};
|
|
317
|
+
eslintPkg.scripts = {
|
|
318
|
+
lint: "eslint ."
|
|
319
|
+
};
|
|
320
|
+
delete eslintPkg.keywords;
|
|
321
|
+
delete eslintPkg.author;
|
|
322
|
+
delete eslintPkg.license;
|
|
323
|
+
await fsPromises4.writeFile(
|
|
324
|
+
eslintPackagePath,
|
|
325
|
+
JSON.stringify(eslintPkg, null, 2),
|
|
326
|
+
"utf8"
|
|
327
|
+
);
|
|
328
|
+
await runCommand(
|
|
329
|
+
"pnpm add -D eslint @eslint/js @eslint/json globals typescript-eslint",
|
|
330
|
+
{ cwd: eslintDir }
|
|
331
|
+
);
|
|
332
|
+
const eslintConfigContent = [
|
|
333
|
+
'import js from "@eslint/js";',
|
|
334
|
+
'import globals from "globals";',
|
|
335
|
+
'import tseslint from "typescript-eslint";',
|
|
336
|
+
'import eslintJson from "@eslint/json";',
|
|
337
|
+
"",
|
|
338
|
+
"export default tseslint.config(",
|
|
339
|
+
" {",
|
|
340
|
+
' ignores: ["**/dist/**", "**/node_modules/**"],',
|
|
341
|
+
" },",
|
|
342
|
+
" js.configs.recommended,",
|
|
343
|
+
" ...tseslint.configs.recommended,",
|
|
344
|
+
" {",
|
|
345
|
+
" languageOptions: {",
|
|
346
|
+
" globals: {",
|
|
347
|
+
" ...globals.node,",
|
|
348
|
+
" },",
|
|
349
|
+
" },",
|
|
350
|
+
" rules: {",
|
|
351
|
+
' "no-unused-vars": "off",',
|
|
352
|
+
' "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],',
|
|
353
|
+
" },",
|
|
354
|
+
" },",
|
|
355
|
+
" {",
|
|
356
|
+
' files: ["**/*.json"],',
|
|
357
|
+
' language: "json/json",',
|
|
358
|
+
" ...eslintJson.configs.recommended,",
|
|
359
|
+
" }",
|
|
360
|
+
");",
|
|
361
|
+
""
|
|
362
|
+
].join("\n");
|
|
363
|
+
await fsPromises4.writeFile(
|
|
364
|
+
path4.join(eslintDir, "eslint.config.ts"),
|
|
365
|
+
eslintConfigContent,
|
|
366
|
+
"utf8"
|
|
367
|
+
);
|
|
368
|
+
const rootPackagePath = path4.join(projectPath, "package.json");
|
|
369
|
+
const rootPackageContent = await fsPromises4.readFile(rootPackagePath, "utf8");
|
|
370
|
+
const rootPkg = JSON.parse(rootPackageContent);
|
|
371
|
+
rootPkg.scripts = {
|
|
372
|
+
...rootPkg.scripts || {},
|
|
373
|
+
lint: "pnpm --filter @config/eslint lint"
|
|
374
|
+
};
|
|
375
|
+
await fsPromises4.writeFile(
|
|
376
|
+
rootPackagePath,
|
|
377
|
+
JSON.stringify(rootPkg, null, 2),
|
|
378
|
+
"utf8"
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
async function runEslintSetup(projectPath) {
|
|
382
|
+
const packagesDir = path4.join(projectPath, "packages");
|
|
383
|
+
try {
|
|
384
|
+
await fsPromises4.access(packagesDir);
|
|
385
|
+
} catch {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
const eslintPrompt = await promptEslint();
|
|
389
|
+
handleCancel(eslintPrompt);
|
|
390
|
+
if (eslintPrompt) {
|
|
391
|
+
const s = spinner3();
|
|
392
|
+
console.log("\n");
|
|
393
|
+
s.start("Setting up modular ESLint in packages/eslint...");
|
|
394
|
+
try {
|
|
395
|
+
await setupEslint(projectPath);
|
|
396
|
+
s.stop(
|
|
397
|
+
pc6.green("\u2714 Success: Modular ESLint configured in packages/eslint")
|
|
398
|
+
);
|
|
399
|
+
} catch (error) {
|
|
400
|
+
s.stop(pc6.red("\u2716 Failed: ESLint setup failed"));
|
|
401
|
+
console.error(pc6.red(`
|
|
402
|
+
Error details: ${error.message || error}`));
|
|
403
|
+
process.exit(1);
|
|
404
|
+
}
|
|
405
|
+
console.log("\n");
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// src/tasks/typescript.ts
|
|
410
|
+
import { confirm as confirm3, spinner as spinner4 } from "@clack/prompts";
|
|
411
|
+
import pc7 from "picocolors";
|
|
412
|
+
import fsPromises5 from "fs/promises";
|
|
413
|
+
import path5 from "path";
|
|
414
|
+
async function promptTypescript() {
|
|
415
|
+
return await confirm3({
|
|
416
|
+
message: "Do you want to setup TypeScript config in packages/typescript?",
|
|
417
|
+
initialValue: true
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
async function setupTypescript(projectPath) {
|
|
421
|
+
const tsDir = path5.join(projectPath, "packages", "typescript");
|
|
422
|
+
await fsPromises5.mkdir(tsDir, { recursive: true });
|
|
423
|
+
await runCommand("pnpm init", { cwd: tsDir, silent: true });
|
|
424
|
+
const tsPackagePath = path5.join(tsDir, "package.json");
|
|
425
|
+
const tsPackageRaw = await fsPromises5.readFile(tsPackagePath, "utf8");
|
|
426
|
+
const tsPkg = JSON.parse(tsPackageRaw);
|
|
427
|
+
tsPkg.name = "@config/typescript";
|
|
428
|
+
tsPkg.version = "1.0.0";
|
|
429
|
+
tsPkg.private = true;
|
|
430
|
+
tsPkg.type = "module";
|
|
431
|
+
tsPkg.exports = {
|
|
432
|
+
"./tsconfig.json": "./tsconfig.json"
|
|
433
|
+
};
|
|
434
|
+
delete tsPkg.keywords;
|
|
435
|
+
delete tsPkg.author;
|
|
436
|
+
delete tsPkg.license;
|
|
437
|
+
delete tsPkg.main;
|
|
438
|
+
delete tsPkg.scripts;
|
|
439
|
+
await fsPromises5.writeFile(
|
|
440
|
+
tsPackagePath,
|
|
441
|
+
JSON.stringify(tsPkg, null, 2),
|
|
442
|
+
"utf8"
|
|
443
|
+
);
|
|
444
|
+
await runCommand(
|
|
445
|
+
"cd ../.. && pnpm add -D typescript -w && cd packages/typescript",
|
|
446
|
+
{ cwd: tsDir, silent: true }
|
|
447
|
+
);
|
|
448
|
+
await runCommand("npx tsc --init", { cwd: tsDir });
|
|
449
|
+
}
|
|
450
|
+
async function runTypescriptSetup(projectPath) {
|
|
451
|
+
const packagesDir = path5.join(projectPath, "packages");
|
|
452
|
+
try {
|
|
453
|
+
await fsPromises5.access(packagesDir);
|
|
454
|
+
} catch {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
const tsPrompt = await promptTypescript();
|
|
458
|
+
handleCancel(tsPrompt);
|
|
459
|
+
if (tsPrompt) {
|
|
460
|
+
const s = spinner4();
|
|
461
|
+
console.log("\n");
|
|
462
|
+
s.start("Setting up modular TypeScript config in packages/typescript...");
|
|
463
|
+
try {
|
|
464
|
+
await setupTypescript(projectPath);
|
|
465
|
+
s.stop(
|
|
466
|
+
pc7.green(
|
|
467
|
+
"\u2714 Success: Modular TypeScript config configured in packages/typescript"
|
|
468
|
+
)
|
|
469
|
+
);
|
|
470
|
+
} catch (error) {
|
|
471
|
+
s.stop(pc7.red("\u2716 Failed: TypeScript config setup failed"));
|
|
472
|
+
console.error(pc7.red(`
|
|
473
|
+
Error details: ${error.message || error}`));
|
|
474
|
+
process.exit(1);
|
|
475
|
+
}
|
|
476
|
+
console.log("\n");
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// src/tasks/server.ts
|
|
481
|
+
import { confirm as confirm4, spinner as spinner5 } from "@clack/prompts";
|
|
482
|
+
import pc8 from "picocolors";
|
|
483
|
+
import fsPromises6 from "fs/promises";
|
|
484
|
+
import path6 from "path";
|
|
485
|
+
async function promptServer() {
|
|
486
|
+
return await confirm4({
|
|
487
|
+
message: "Do you want to setup a basic Express backend in apps/server?",
|
|
488
|
+
initialValue: true
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
async function setupServer(projectPath) {
|
|
492
|
+
const serverDir = path6.join(projectPath, "apps", "server");
|
|
493
|
+
const srcDir = path6.join(serverDir, "src");
|
|
494
|
+
await fsPromises6.mkdir(srcDir, { recursive: true });
|
|
495
|
+
await runCommand("pnpm init", { cwd: serverDir, silent: true });
|
|
496
|
+
const serverPackagePath = path6.join(serverDir, "package.json");
|
|
497
|
+
const serverPackageRaw = await fsPromises6.readFile(serverPackagePath, "utf8");
|
|
498
|
+
const serverPkg = JSON.parse(serverPackageRaw);
|
|
499
|
+
const eslintDir = path6.join(projectPath, "packages", "eslint");
|
|
500
|
+
let hasEslint = false;
|
|
501
|
+
try {
|
|
502
|
+
await fsPromises6.access(eslintDir);
|
|
503
|
+
hasEslint = true;
|
|
504
|
+
} catch {
|
|
505
|
+
}
|
|
506
|
+
serverPkg.name = "server";
|
|
507
|
+
serverPkg.version = "1.0.0";
|
|
508
|
+
serverPkg.private = true;
|
|
509
|
+
serverPkg.type = "module";
|
|
510
|
+
serverPkg.main = "dist/index.js";
|
|
511
|
+
serverPkg.scripts = {
|
|
512
|
+
dev: "tsx watch src/index.ts",
|
|
513
|
+
build: "tsc",
|
|
514
|
+
start: "node dist/index.js"
|
|
515
|
+
};
|
|
516
|
+
serverPkg.devDependencies = {
|
|
517
|
+
"@config/typescript": "workspace:*"
|
|
518
|
+
};
|
|
519
|
+
if (hasEslint) {
|
|
520
|
+
serverPkg.devDependencies["@config/eslint"] = "workspace:*";
|
|
521
|
+
serverPkg.scripts["lint"] = "eslint .";
|
|
522
|
+
}
|
|
523
|
+
delete serverPkg.keywords;
|
|
524
|
+
delete serverPkg.author;
|
|
525
|
+
delete serverPkg.license;
|
|
526
|
+
await fsPromises6.writeFile(
|
|
527
|
+
serverPackagePath,
|
|
528
|
+
JSON.stringify(serverPkg, null, 2),
|
|
529
|
+
"utf8"
|
|
530
|
+
);
|
|
531
|
+
const tsconfigContent = {
|
|
532
|
+
extends: "@config/typescript/tsconfig.json",
|
|
533
|
+
compilerOptions: {
|
|
534
|
+
rootDir: "src",
|
|
535
|
+
outDir: "dist"
|
|
536
|
+
},
|
|
537
|
+
include: ["src/**/*"]
|
|
538
|
+
};
|
|
539
|
+
await fsPromises6.writeFile(
|
|
540
|
+
path6.join(serverDir, "tsconfig.json"),
|
|
541
|
+
JSON.stringify(tsconfigContent, null, 2),
|
|
542
|
+
"utf8"
|
|
543
|
+
);
|
|
544
|
+
if (hasEslint) {
|
|
545
|
+
const eslintConfigContent = [
|
|
546
|
+
"import baseConfig from '@config/eslint';",
|
|
547
|
+
"",
|
|
548
|
+
"export default [",
|
|
549
|
+
" ...baseConfig,",
|
|
550
|
+
" {",
|
|
551
|
+
" // Add server-specific overrides if necessary",
|
|
552
|
+
" },",
|
|
553
|
+
"];",
|
|
554
|
+
""
|
|
555
|
+
].join("\n");
|
|
556
|
+
await fsPromises6.writeFile(
|
|
557
|
+
path6.join(serverDir, "eslint.config.ts"),
|
|
558
|
+
eslintConfigContent,
|
|
559
|
+
"utf8"
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
await runCommand("pnpm add express cors", { cwd: serverDir, silent: false });
|
|
563
|
+
await runCommand("pnpm add -D @types/express @types/cors tsx typescript", {
|
|
564
|
+
cwd: serverDir,
|
|
565
|
+
silent: false
|
|
566
|
+
});
|
|
567
|
+
const indexTsContent = [
|
|
568
|
+
"import express from 'express';",
|
|
569
|
+
"import cors from 'cors';",
|
|
570
|
+
"",
|
|
571
|
+
"const app = express();",
|
|
572
|
+
"const port = process.env.PORT || 3001;",
|
|
573
|
+
"",
|
|
574
|
+
"// Enable CORS and parsing of JSON request bodies",
|
|
575
|
+
"app.use(cors());",
|
|
576
|
+
"app.use(express.json());",
|
|
577
|
+
"",
|
|
578
|
+
"// Root API health and welcome route",
|
|
579
|
+
"app.get('/api', (req, res) => {",
|
|
580
|
+
" res.json({",
|
|
581
|
+
" message: 'Welcome to the Morax High-Performance Backend API!',",
|
|
582
|
+
" timestamp: new Date().toISOString(),",
|
|
583
|
+
" status: 'healthy',",
|
|
584
|
+
" });",
|
|
585
|
+
"});",
|
|
586
|
+
"",
|
|
587
|
+
"app.listen(port, () => {",
|
|
588
|
+
" console.log(`\u{1F680} Server is running on http://localhost:${port}`);",
|
|
589
|
+
"});",
|
|
590
|
+
""
|
|
591
|
+
].join("\n");
|
|
592
|
+
await fsPromises6.writeFile(
|
|
593
|
+
path6.join(srcDir, "index.ts"),
|
|
594
|
+
indexTsContent,
|
|
595
|
+
"utf8"
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
async function runServerSetup(projectPath) {
|
|
599
|
+
const appsDir = path6.join(projectPath, "apps");
|
|
600
|
+
try {
|
|
601
|
+
await fsPromises6.access(appsDir);
|
|
602
|
+
} catch {
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
const serverPrompt = await promptServer();
|
|
606
|
+
handleCancel(serverPrompt);
|
|
607
|
+
if (serverPrompt) {
|
|
608
|
+
const s = spinner5();
|
|
609
|
+
console.log("\n");
|
|
610
|
+
s.start("Setting up modular Express backend in apps/server...");
|
|
611
|
+
try {
|
|
612
|
+
await setupServer(projectPath);
|
|
613
|
+
s.stop(
|
|
614
|
+
pc8.green(
|
|
615
|
+
"\u2714 Success: Modular Express backend configured in apps/server"
|
|
616
|
+
)
|
|
617
|
+
);
|
|
618
|
+
} catch (error) {
|
|
619
|
+
s.stop(pc8.red("\u2716 Failed: Express backend setup failed"));
|
|
620
|
+
console.error(pc8.red(`
|
|
621
|
+
Error details: ${error.message || error}`));
|
|
622
|
+
process.exit(1);
|
|
623
|
+
}
|
|
624
|
+
console.log("\n");
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// src/tasks/git.ts
|
|
629
|
+
import { confirm as confirm5, spinner as spinner6 } from "@clack/prompts";
|
|
630
|
+
import pc9 from "picocolors";
|
|
631
|
+
import fsPromises7 from "fs/promises";
|
|
632
|
+
import path7 from "path";
|
|
633
|
+
async function promptGit() {
|
|
634
|
+
return await confirm5({
|
|
295
635
|
message: "Do you want to initialize a local Git repository?",
|
|
296
636
|
initialValue: true
|
|
297
637
|
});
|
|
@@ -330,8 +670,8 @@ async function gitInit(projectPath) {
|
|
|
330
670
|
"Thumbs.db",
|
|
331
671
|
""
|
|
332
672
|
].join("\n");
|
|
333
|
-
await
|
|
334
|
-
|
|
673
|
+
await fsPromises7.writeFile(
|
|
674
|
+
path7.join(projectPath, ".gitignore"),
|
|
335
675
|
gitignore,
|
|
336
676
|
"utf8"
|
|
337
677
|
);
|
|
@@ -341,16 +681,16 @@ async function runGitSetup(projectPath) {
|
|
|
341
681
|
handleCancel(gitPrompt);
|
|
342
682
|
let gitInitialized = false;
|
|
343
683
|
if (gitPrompt) {
|
|
344
|
-
const s =
|
|
684
|
+
const s = spinner6();
|
|
345
685
|
console.log("\n");
|
|
346
686
|
s.start("Initializing Git repository...");
|
|
347
687
|
try {
|
|
348
688
|
await gitInit(projectPath);
|
|
349
|
-
s.stop(
|
|
689
|
+
s.stop(pc9.green("\u2714 Success: Git repository initialized"));
|
|
350
690
|
gitInitialized = true;
|
|
351
691
|
} catch (error) {
|
|
352
|
-
s.stop(
|
|
353
|
-
console.error(
|
|
692
|
+
s.stop(pc9.red("\u2716 Failed: Git initialization failed"));
|
|
693
|
+
console.error(pc9.red(`
|
|
354
694
|
Error details: ${error.message || error}`));
|
|
355
695
|
process.exit(1);
|
|
356
696
|
}
|
|
@@ -360,12 +700,12 @@ Error details: ${error.message || error}`));
|
|
|
360
700
|
}
|
|
361
701
|
|
|
362
702
|
// src/tasks/husky.ts
|
|
363
|
-
import { confirm as
|
|
364
|
-
import
|
|
365
|
-
import
|
|
366
|
-
import
|
|
703
|
+
import { confirm as confirm6, spinner as spinner7 } from "@clack/prompts";
|
|
704
|
+
import pc10 from "picocolors";
|
|
705
|
+
import fsPromises8 from "fs/promises";
|
|
706
|
+
import path8 from "path";
|
|
367
707
|
async function promptHusky() {
|
|
368
|
-
return await
|
|
708
|
+
return await confirm6({
|
|
369
709
|
message: "Do you want to setup Husky pre-commit hooks?",
|
|
370
710
|
initialValue: true
|
|
371
711
|
});
|
|
@@ -373,10 +713,10 @@ async function promptHusky() {
|
|
|
373
713
|
async function setupHusky(projectPath) {
|
|
374
714
|
await runCommand("pnpm add -D -E husky -w", { cwd: projectPath });
|
|
375
715
|
await runCommand("pnpm exec husky init", { cwd: projectPath });
|
|
376
|
-
const preCommitPath =
|
|
716
|
+
const preCommitPath = path8.join(projectPath, ".husky", "pre-commit");
|
|
377
717
|
let hookContent = "";
|
|
378
718
|
try {
|
|
379
|
-
hookContent = await
|
|
719
|
+
hookContent = await fsPromises8.readFile(preCommitPath, "utf8");
|
|
380
720
|
} catch {
|
|
381
721
|
hookContent = "pnpm test";
|
|
382
722
|
}
|
|
@@ -384,9 +724,9 @@ async function setupHusky(projectPath) {
|
|
|
384
724
|
if (!hookContent.includes("git add .")) {
|
|
385
725
|
hookContent = hookContent.trim() + "\ngit add .\n";
|
|
386
726
|
}
|
|
387
|
-
await
|
|
727
|
+
await fsPromises8.writeFile(preCommitPath, hookContent, "utf8");
|
|
388
728
|
try {
|
|
389
|
-
await
|
|
729
|
+
await fsPromises8.chmod(preCommitPath, 493);
|
|
390
730
|
} catch {
|
|
391
731
|
}
|
|
392
732
|
}
|
|
@@ -395,15 +735,15 @@ async function runHuskySetup(projectPath, gitInitialized) {
|
|
|
395
735
|
const huskyPrompt = await promptHusky();
|
|
396
736
|
handleCancel(huskyPrompt);
|
|
397
737
|
if (huskyPrompt) {
|
|
398
|
-
const s =
|
|
738
|
+
const s = spinner7();
|
|
399
739
|
console.log("\n");
|
|
400
740
|
s.start("Setting up Husky hooks...");
|
|
401
741
|
try {
|
|
402
742
|
await setupHusky(projectPath);
|
|
403
|
-
s.stop(
|
|
743
|
+
s.stop(pc10.green("\u2714 Success: Husky pre-commit hooks configured"));
|
|
404
744
|
} catch (error) {
|
|
405
|
-
s.stop(
|
|
406
|
-
console.error(
|
|
745
|
+
s.stop(pc10.red("\u2716 Failed: Husky setup failed"));
|
|
746
|
+
console.error(pc10.red(`
|
|
407
747
|
Error details: ${error.message || error}`));
|
|
408
748
|
process.exit(1);
|
|
409
749
|
}
|
|
@@ -412,19 +752,19 @@ Error details: ${error.message || error}`));
|
|
|
412
752
|
}
|
|
413
753
|
|
|
414
754
|
// src/core/endcli.ts
|
|
415
|
-
import
|
|
755
|
+
import pc11 from "picocolors";
|
|
416
756
|
import { outro } from "@clack/prompts";
|
|
417
757
|
import boxen2 from "boxen";
|
|
418
758
|
function endCli(name, projectPath) {
|
|
419
|
-
outro(
|
|
759
|
+
outro(pc11.yellow("Morax scaffolding completed successfully!"));
|
|
420
760
|
console.log(
|
|
421
761
|
boxen2(
|
|
422
|
-
`\u26A1 ${
|
|
423
|
-
Location: ${
|
|
762
|
+
`\u26A1 ${pc11.bold("Workspace ready:")} ${pc11.yellow(name)}
|
|
763
|
+
Location: ${pc11.cyan(projectPath)}
|
|
424
764
|
|
|
425
|
-
${
|
|
426
|
-
1. ${
|
|
427
|
-
2. ${
|
|
765
|
+
${pc11.bold("To start developing:")}
|
|
766
|
+
1. ${pc11.cyan(`cd ${name}`)}
|
|
767
|
+
2. ${pc11.cyan("pnpm dev")}
|
|
428
768
|
|
|
429
769
|
\u{1F4A1} Code formatting & git orchestration is fully active.`,
|
|
430
770
|
{
|
|
@@ -432,22 +772,445 @@ ${pc8.bold("To start developing:")}
|
|
|
432
772
|
margin: 0,
|
|
433
773
|
borderStyle: "round",
|
|
434
774
|
borderColor: "yellow",
|
|
435
|
-
title:
|
|
775
|
+
title: pc11.black(pc11.bold(" Setup Complete ")),
|
|
436
776
|
titleAlignment: "center"
|
|
437
777
|
}
|
|
438
778
|
)
|
|
439
779
|
);
|
|
440
780
|
}
|
|
441
781
|
|
|
782
|
+
// src/tasks/addreadme.ts
|
|
783
|
+
import fsPromises9 from "fs/promises";
|
|
784
|
+
import path9 from "path";
|
|
785
|
+
async function setupReadme(projectPath, workspaceName) {
|
|
786
|
+
const readmePath = path9.join(projectPath, "README.md");
|
|
787
|
+
const readmeContent = [
|
|
788
|
+
`# Morax `,
|
|
789
|
+
"",
|
|
790
|
+
"Welcome to your next-generation, high-performance monorepo workspace generated by **Morax**.",
|
|
791
|
+
"",
|
|
792
|
+
"## Workspace Structure",
|
|
793
|
+
"",
|
|
794
|
+
"- **`apps/`** \u2014 Frontend applications, backend servers, and user-facing services.",
|
|
795
|
+
"- **`packages/`** \u2014 Shared modules, TypeScript configurations, ESLint rule sets, and common utility libraries.",
|
|
796
|
+
"",
|
|
797
|
+
"## Key Commands",
|
|
798
|
+
"",
|
|
799
|
+
"Run the following commands from the root directory of your workspace:",
|
|
800
|
+
"",
|
|
801
|
+
"### Development",
|
|
802
|
+
"Start all dev servers and hot-reloading configurations concurrently:",
|
|
803
|
+
"```bash",
|
|
804
|
+
"pnpm dev",
|
|
805
|
+
"```",
|
|
806
|
+
"",
|
|
807
|
+
"### Linting",
|
|
808
|
+
"Run static analysis across all workspaces using your shared ESLint rules:",
|
|
809
|
+
"```bash",
|
|
810
|
+
"pnpm lint",
|
|
811
|
+
"```",
|
|
812
|
+
"",
|
|
813
|
+
"### Formatting",
|
|
814
|
+
"Automatically format all codebase files using Prettier:",
|
|
815
|
+
"```bash",
|
|
816
|
+
"pnpm format",
|
|
817
|
+
"```",
|
|
818
|
+
"",
|
|
819
|
+
"---",
|
|
820
|
+
"",
|
|
821
|
+
"*Generated with love by [Morax Scaffolder CLI](https://github.com/Elitedv/morax).*",
|
|
822
|
+
""
|
|
823
|
+
].join("\n");
|
|
824
|
+
await fsPromises9.writeFile(readmePath, readmeContent, "utf8");
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// src/core/web.ts
|
|
828
|
+
import { select } from "@clack/prompts";
|
|
829
|
+
|
|
830
|
+
// src/tasks/shadcn.ts
|
|
831
|
+
import { confirm as confirm7 } from "@clack/prompts";
|
|
832
|
+
import pc12 from "picocolors";
|
|
833
|
+
import fsPromises10 from "fs/promises";
|
|
834
|
+
import path10 from "path";
|
|
835
|
+
import { spawn } from "child_process";
|
|
836
|
+
async function promptShadcn() {
|
|
837
|
+
return await confirm7({
|
|
838
|
+
message: "Do you want to setup shadcn UI in your Next.js website (apps/web)?",
|
|
839
|
+
initialValue: true
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
function runInteractiveCommand(command, args, cwd) {
|
|
843
|
+
return new Promise((resolve, reject) => {
|
|
844
|
+
const child = spawn(command, args, {
|
|
845
|
+
cwd,
|
|
846
|
+
stdio: "inherit",
|
|
847
|
+
shell: true,
|
|
848
|
+
env: { ...process.env, NODE_NO_WARNINGS: "1" }
|
|
849
|
+
});
|
|
850
|
+
child.on("close", (code) => {
|
|
851
|
+
if (code === 0) {
|
|
852
|
+
resolve();
|
|
853
|
+
} else {
|
|
854
|
+
reject(new Error(`Command "${command} ${args.join(" ")}" exited with code ${code}`));
|
|
855
|
+
}
|
|
856
|
+
});
|
|
857
|
+
child.on("error", (err) => {
|
|
858
|
+
reject(err);
|
|
859
|
+
});
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
async function setupShadcn(projectPath) {
|
|
863
|
+
const webDir = path10.join(projectPath, "apps", "web");
|
|
864
|
+
console.log(pc12.cyan("\nStarting interactive shadcn UI initialization..."));
|
|
865
|
+
await runInteractiveCommand("pnpm", ["dlx", "shadcn@latest", "init", "--template", "next"], webDir);
|
|
866
|
+
}
|
|
867
|
+
async function runShadcnSetup(projectPath) {
|
|
868
|
+
const webDir = path10.join(projectPath, "apps", "web");
|
|
869
|
+
try {
|
|
870
|
+
await fsPromises10.access(webDir);
|
|
871
|
+
} catch {
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
const shadcnPrompt = await promptShadcn();
|
|
875
|
+
handleCancel(shadcnPrompt);
|
|
876
|
+
if (shadcnPrompt) {
|
|
877
|
+
try {
|
|
878
|
+
await setupShadcn(projectPath);
|
|
879
|
+
console.log(pc12.green("\n\u2714 Success: shadcn UI successfully initialized in apps/web\n"));
|
|
880
|
+
} catch (error) {
|
|
881
|
+
console.error(pc12.red(`
|
|
882
|
+
\u2716 Failed: shadcn UI setup failed`));
|
|
883
|
+
console.error(pc12.red(`Error details: ${error.message || error}
|
|
884
|
+
`));
|
|
885
|
+
process.exit(1);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
// src/tasks/nextjs.ts
|
|
891
|
+
import { confirm as confirm8 } from "@clack/prompts";
|
|
892
|
+
import pc13 from "picocolors";
|
|
893
|
+
import fsPromises11 from "fs/promises";
|
|
894
|
+
import path11 from "path";
|
|
895
|
+
import { spawn as spawn2 } from "child_process";
|
|
896
|
+
function runInteractiveCommand2(command, args, cwd) {
|
|
897
|
+
return new Promise((resolve, reject) => {
|
|
898
|
+
const child = spawn2(command, args, {
|
|
899
|
+
cwd,
|
|
900
|
+
stdio: "inherit",
|
|
901
|
+
shell: true,
|
|
902
|
+
env: { ...process.env, NODE_NO_WARNINGS: "1" }
|
|
903
|
+
});
|
|
904
|
+
child.on("close", (code) => {
|
|
905
|
+
if (code === 0) {
|
|
906
|
+
resolve();
|
|
907
|
+
} else {
|
|
908
|
+
reject(
|
|
909
|
+
new Error(
|
|
910
|
+
`Command "${command} ${args.join(" ")}" exited with code ${code}`
|
|
911
|
+
)
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
child.on("error", (err) => {
|
|
916
|
+
reject(err);
|
|
917
|
+
});
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
async function setupNextjs(projectPath) {
|
|
921
|
+
const appsDir = path11.join(projectPath, "apps");
|
|
922
|
+
const webDir = path11.join(appsDir, "web");
|
|
923
|
+
try {
|
|
924
|
+
await fsPromises11.rm(webDir, { recursive: true, force: true });
|
|
925
|
+
} catch {
|
|
926
|
+
}
|
|
927
|
+
console.log(pc13.cyan("\nStarting interactive Next.js application setup..."));
|
|
928
|
+
await runInteractiveCommand2(
|
|
929
|
+
"npx",
|
|
930
|
+
["create-next-app@latest", "web"],
|
|
931
|
+
appsDir
|
|
932
|
+
);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// src/tasks/react.ts
|
|
936
|
+
import pc14 from "picocolors";
|
|
937
|
+
import fsPromises12 from "fs/promises";
|
|
938
|
+
import path12 from "path";
|
|
939
|
+
import { spawn as spawn3 } from "child_process";
|
|
940
|
+
import { confirm as confirm9, spinner as spinner8, text as text2 } from "@clack/prompts";
|
|
941
|
+
function runInteractiveCommand3(command, args, cwd) {
|
|
942
|
+
return new Promise((resolve, reject) => {
|
|
943
|
+
const child = spawn3(command, args, {
|
|
944
|
+
cwd,
|
|
945
|
+
stdio: "inherit",
|
|
946
|
+
shell: true,
|
|
947
|
+
env: { ...process.env, NODE_NO_WARNINGS: "1" }
|
|
948
|
+
});
|
|
949
|
+
child.on("close", (code) => {
|
|
950
|
+
if (code === 0) {
|
|
951
|
+
resolve();
|
|
952
|
+
} else {
|
|
953
|
+
reject(
|
|
954
|
+
new Error(
|
|
955
|
+
`Command "${command} ${args.join(" ")}" exited with code ${code}`
|
|
956
|
+
)
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
});
|
|
960
|
+
child.on("error", (err) => {
|
|
961
|
+
reject(err);
|
|
962
|
+
});
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
async function setupReact(projectPath) {
|
|
966
|
+
const appsDir = path12.join(projectPath, "apps");
|
|
967
|
+
console.log(pc14.magentaBright("\n\u{1F537} IMPORTANT INSTRUCTIONS:"));
|
|
968
|
+
console.log(pc14.magentaBright("During the Vite interactive configuration prompts, please select:"));
|
|
969
|
+
console.log(pc14.magentaBright(` 1. Install & Start: Choose ${pc14.bold("No")} when asked "Install with npm/pnpm and start now?"`));
|
|
970
|
+
console.log(pc14.magentaBright("This allows Morax CLI to continue automatically configuring your workspace (ESLint, Prettier, Tailwind, packages, etc.)!"));
|
|
971
|
+
console.log(pc14.cyan("\nStarting interactive Vite React application setup..."));
|
|
972
|
+
let beforeDirs = [];
|
|
973
|
+
try {
|
|
974
|
+
beforeDirs = await fsPromises12.readdir(appsDir);
|
|
975
|
+
} catch {
|
|
976
|
+
}
|
|
977
|
+
try {
|
|
978
|
+
await runInteractiveCommand3(
|
|
979
|
+
"pnpm",
|
|
980
|
+
["create", "vite@latest"],
|
|
981
|
+
appsDir
|
|
982
|
+
);
|
|
983
|
+
let afterDirs = [];
|
|
984
|
+
try {
|
|
985
|
+
afterDirs = await fsPromises12.readdir(appsDir);
|
|
986
|
+
} catch {
|
|
987
|
+
}
|
|
988
|
+
const newDirs = afterDirs.filter((d) => !beforeDirs.includes(d));
|
|
989
|
+
let createdDirName = "web";
|
|
990
|
+
if (newDirs.length > 0) {
|
|
991
|
+
createdDirName = newDirs[0];
|
|
992
|
+
}
|
|
993
|
+
const webDir = path12.join(appsDir, createdDirName);
|
|
994
|
+
try {
|
|
995
|
+
await fsPromises12.access(webDir);
|
|
996
|
+
} catch {
|
|
997
|
+
throw new Error(`Vite React application directory "apps/${createdDirName}" was not found. Please ensure you complete the Vite installation.`);
|
|
998
|
+
}
|
|
999
|
+
console.log(
|
|
1000
|
+
pc14.green(`
|
|
1001
|
+
\u2714 Success: Vite React frontend configured in apps/${createdDirName}
|
|
1002
|
+
`)
|
|
1003
|
+
);
|
|
1004
|
+
const setupTailwindPrompt = await confirm9({
|
|
1005
|
+
message: "Do you want to install and configure Tailwind CSS v4?",
|
|
1006
|
+
initialValue: true
|
|
1007
|
+
});
|
|
1008
|
+
handleCancel(setupTailwindPrompt);
|
|
1009
|
+
const setupShadcnPrompt = await confirm9({
|
|
1010
|
+
message: `Do you want to setup shadcn UI in your Vite React website (apps/${createdDirName})?`,
|
|
1011
|
+
initialValue: true
|
|
1012
|
+
});
|
|
1013
|
+
handleCancel(setupShadcnPrompt);
|
|
1014
|
+
const needsTailwind = setupTailwindPrompt || setupShadcnPrompt;
|
|
1015
|
+
if (needsTailwind) {
|
|
1016
|
+
const s = spinner8();
|
|
1017
|
+
s.start("Installing Tailwind CSS v4, Vite integration, and Node types...");
|
|
1018
|
+
try {
|
|
1019
|
+
const pkgPath = path12.join(webDir, "package.json");
|
|
1020
|
+
try {
|
|
1021
|
+
const pkgRaw = await fsPromises12.readFile(pkgPath, "utf8");
|
|
1022
|
+
const pkg = JSON.parse(pkgRaw);
|
|
1023
|
+
pkg.dependencies = pkg.dependencies || {};
|
|
1024
|
+
pkg.devDependencies = pkg.devDependencies || {};
|
|
1025
|
+
pkg.dependencies["tailwindcss"] = "^4.0.0";
|
|
1026
|
+
pkg.devDependencies["@tailwindcss/vite"] = "^4.0.0";
|
|
1027
|
+
pkg.devDependencies["@types/node"] = "^20.11.0";
|
|
1028
|
+
await fsPromises12.writeFile(pkgPath, JSON.stringify(pkg, null, 2), "utf8");
|
|
1029
|
+
} catch {
|
|
1030
|
+
}
|
|
1031
|
+
await runCommand("pnpm install", { cwd: webDir, silent: true });
|
|
1032
|
+
s.message("Configuring Vite plugins and Tailwind CSS imports...");
|
|
1033
|
+
const viteConfigPath = path12.join(webDir, "vite.config.ts");
|
|
1034
|
+
try {
|
|
1035
|
+
let content = await fsPromises12.readFile(viteConfigPath, "utf8");
|
|
1036
|
+
if (!content.includes("@tailwindcss/vite")) {
|
|
1037
|
+
content = "import tailwindcss from '@tailwindcss/vite';\n" + content;
|
|
1038
|
+
if (content.includes("plugins: [react()]")) {
|
|
1039
|
+
content = content.replace("plugins: [react()]", "plugins: [react(), tailwindcss()]");
|
|
1040
|
+
} else if (content.includes("plugins: [react(),]")) {
|
|
1041
|
+
content = content.replace("plugins: [react(),]", "plugins: [react(), tailwindcss()]");
|
|
1042
|
+
} else {
|
|
1043
|
+
content = content.replace(/(plugins:\s*\[\s*react\(\),?\s*)(\])/g, "$1\n tailwindcss(),\n $2");
|
|
1044
|
+
}
|
|
1045
|
+
await fsPromises12.writeFile(viteConfigPath, content, "utf8");
|
|
1046
|
+
}
|
|
1047
|
+
} catch {
|
|
1048
|
+
}
|
|
1049
|
+
const indexCssPath = path12.join(webDir, "src", "index.css");
|
|
1050
|
+
try {
|
|
1051
|
+
await fsPromises12.writeFile(indexCssPath, '@import "tailwindcss";\n', "utf8");
|
|
1052
|
+
} catch {
|
|
1053
|
+
}
|
|
1054
|
+
s.stop(pc14.green("\u2714 Success: Tailwind CSS v4 configured successfully\n"));
|
|
1055
|
+
} catch (err) {
|
|
1056
|
+
s.stop(pc14.red("\u2716 Failed: Tailwind CSS v4 setup failed"));
|
|
1057
|
+
throw err;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
if (setupShadcnPrompt) {
|
|
1061
|
+
const s = spinner8();
|
|
1062
|
+
s.start("Configuring path aliases for shadcn UI preflight checks...");
|
|
1063
|
+
try {
|
|
1064
|
+
const tsconfigPaths = [
|
|
1065
|
+
path12.join(webDir, "tsconfig.json"),
|
|
1066
|
+
path12.join(webDir, "tsconfig.app.json")
|
|
1067
|
+
];
|
|
1068
|
+
for (const tsPath of tsconfigPaths) {
|
|
1069
|
+
try {
|
|
1070
|
+
let content = await fsPromises12.readFile(tsPath, "utf8");
|
|
1071
|
+
if (content.includes('"compilerOptions"')) {
|
|
1072
|
+
if (!content.includes('"paths"')) {
|
|
1073
|
+
content = content.replace(
|
|
1074
|
+
/("compilerOptions"\s*:\s*\{)/,
|
|
1075
|
+
`$1
|
|
1076
|
+
"baseUrl": ".",
|
|
1077
|
+
"paths": {
|
|
1078
|
+
"@/*": ["./src/*"]
|
|
1079
|
+
},`
|
|
1080
|
+
);
|
|
1081
|
+
await fsPromises12.writeFile(tsPath, content, "utf8");
|
|
1082
|
+
}
|
|
1083
|
+
} else {
|
|
1084
|
+
content = content.replace(
|
|
1085
|
+
/^(\s*\{)/,
|
|
1086
|
+
`$1
|
|
1087
|
+
"compilerOptions": {
|
|
1088
|
+
"baseUrl": ".",
|
|
1089
|
+
"paths": {
|
|
1090
|
+
"@/*": ["./src/*"]
|
|
1091
|
+
}
|
|
1092
|
+
},`
|
|
1093
|
+
);
|
|
1094
|
+
await fsPromises12.writeFile(tsPath, content, "utf8");
|
|
1095
|
+
}
|
|
1096
|
+
} catch {
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
const viteConfigPath = path12.join(webDir, "vite.config.ts");
|
|
1100
|
+
try {
|
|
1101
|
+
let content = await fsPromises12.readFile(viteConfigPath, "utf8");
|
|
1102
|
+
if (!content.includes("import path from 'path'")) {
|
|
1103
|
+
content = "import path from 'path';\n" + content;
|
|
1104
|
+
}
|
|
1105
|
+
if (!content.includes("resolve:")) {
|
|
1106
|
+
content = content.replace(
|
|
1107
|
+
/(plugins:\s*\[[^\]]*\]),?/,
|
|
1108
|
+
`$1,
|
|
1109
|
+
resolve: {
|
|
1110
|
+
alias: {
|
|
1111
|
+
"@": path.resolve(__dirname, "./src"),
|
|
1112
|
+
},
|
|
1113
|
+
}`
|
|
1114
|
+
);
|
|
1115
|
+
}
|
|
1116
|
+
await fsPromises12.writeFile(viteConfigPath, content, "utf8");
|
|
1117
|
+
} catch {
|
|
1118
|
+
}
|
|
1119
|
+
s.stop(pc14.green("\u2714 Success: Path aliases successfully configured\n"));
|
|
1120
|
+
} catch (err) {
|
|
1121
|
+
s.stop(pc14.red("\u2716 Failed: Path alias configuration failed"));
|
|
1122
|
+
throw err;
|
|
1123
|
+
}
|
|
1124
|
+
const hasPreset = await confirm9({
|
|
1125
|
+
message: "Do you have a custom shadcn UI preset code?",
|
|
1126
|
+
initialValue: false
|
|
1127
|
+
});
|
|
1128
|
+
handleCancel(hasPreset);
|
|
1129
|
+
let presetCode = "";
|
|
1130
|
+
if (hasPreset) {
|
|
1131
|
+
const enteredPreset = await text2({
|
|
1132
|
+
message: "Enter your custom shadcn UI preset code:",
|
|
1133
|
+
placeholder: "e.g. 123456",
|
|
1134
|
+
validate: (val) => {
|
|
1135
|
+
if (!val || !val.trim()) return "Preset code cannot be empty";
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
});
|
|
1139
|
+
handleCancel(enteredPreset);
|
|
1140
|
+
presetCode = enteredPreset.trim();
|
|
1141
|
+
}
|
|
1142
|
+
const args = ["dlx", "shadcn@latest", "init"];
|
|
1143
|
+
if (presetCode) {
|
|
1144
|
+
args.push("--preset", presetCode);
|
|
1145
|
+
}
|
|
1146
|
+
args.push("--template", "vite");
|
|
1147
|
+
console.log(pc14.cyan("\nStarting interactive shadcn UI initialization..."));
|
|
1148
|
+
await runInteractiveCommand3("pnpm", args, webDir);
|
|
1149
|
+
console.log(
|
|
1150
|
+
pc14.green(`
|
|
1151
|
+
\u2714 Success: shadcn UI successfully initialized in apps/${createdDirName}
|
|
1152
|
+
`)
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
} catch (error) {
|
|
1156
|
+
console.error(pc14.red(`
|
|
1157
|
+
\u2716 Failed: Vite React frontend setup failed`));
|
|
1158
|
+
console.error(pc14.red(`Error details: ${error.message || error}
|
|
1159
|
+
`));
|
|
1160
|
+
process.exit(1);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
// src/core/web.ts
|
|
1165
|
+
async function addweb(projectPath) {
|
|
1166
|
+
const framework = await select({
|
|
1167
|
+
message: "Which frontend website setup would you like to include in apps/web?",
|
|
1168
|
+
options: [
|
|
1169
|
+
{ value: "nextjs", label: "Next.js", hint: "The React Framework for the Web" },
|
|
1170
|
+
{ value: "react", label: "React (Vite)", hint: "Vite React Starter Template" },
|
|
1171
|
+
{ value: "skip", label: "Skip", hint: "Skip setting up a frontend website" }
|
|
1172
|
+
],
|
|
1173
|
+
initialValue: "nextjs"
|
|
1174
|
+
});
|
|
1175
|
+
handleCancel(framework);
|
|
1176
|
+
if (framework === "nextjs") {
|
|
1177
|
+
await setupNextjs(projectPath);
|
|
1178
|
+
await runShadcnSetup(projectPath);
|
|
1179
|
+
} else if (framework === "react") {
|
|
1180
|
+
await setupReact(projectPath);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
442
1184
|
// src/core/runner.ts
|
|
443
1185
|
async function runWorkspaceScaffolder() {
|
|
444
1186
|
startCli();
|
|
445
1187
|
const name = await promptWorkspaceName();
|
|
446
|
-
const projectPath =
|
|
1188
|
+
const projectPath = path13.join(process.cwd(), name);
|
|
447
1189
|
await makeDirectories(name, projectPath);
|
|
1190
|
+
await setupReadme(projectPath, name);
|
|
448
1191
|
const gitInitialized = await runGitSetup(projectPath);
|
|
449
1192
|
await runPrettierSetup(projectPath);
|
|
1193
|
+
await runEslintSetup(projectPath);
|
|
1194
|
+
await runTypescriptSetup(projectPath);
|
|
450
1195
|
await runHuskySetup(projectPath, gitInitialized);
|
|
1196
|
+
await runServerSetup(projectPath);
|
|
1197
|
+
await addweb(projectPath);
|
|
1198
|
+
const s = spinner9();
|
|
1199
|
+
console.log("\n");
|
|
1200
|
+
s.start("Running final workspace package installation...");
|
|
1201
|
+
try {
|
|
1202
|
+
await runCommand("pnpm install", { cwd: projectPath, silent: true });
|
|
1203
|
+
s.stop(
|
|
1204
|
+
pc15.green(
|
|
1205
|
+
"\u2714 Success: Workspace dependencies and symlinks configured successfully"
|
|
1206
|
+
)
|
|
1207
|
+
);
|
|
1208
|
+
} catch (error) {
|
|
1209
|
+
s.stop(pc15.red("\u2716 Warning: Final workspace installation failed"));
|
|
1210
|
+
console.error(pc15.red(`
|
|
1211
|
+
Error details: ${error.message || error}`));
|
|
1212
|
+
}
|
|
1213
|
+
console.log("\n");
|
|
451
1214
|
endCli(name, projectPath);
|
|
452
1215
|
}
|
|
453
1216
|
|
|
@@ -456,7 +1219,7 @@ async function main() {
|
|
|
456
1219
|
await runWorkspaceScaffolder();
|
|
457
1220
|
}
|
|
458
1221
|
main().catch((err) => {
|
|
459
|
-
console.error(
|
|
1222
|
+
console.error(pc16.red("Fatal Error during execution:"), err);
|
|
460
1223
|
process.exit(1);
|
|
461
1224
|
});
|
|
462
1225
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/runner.ts","../src/core/startcli.ts","../src/core/workspaceName.ts","../src/utils/isCancel.ts","../src/tasks/directories.ts","../src/tasks/workspace.ts","../src/utils/exec.ts","../src/tasks/prettier.ts","../src/tasks/git.ts","../src/tasks/husky.ts","../src/core/endcli.ts"],"sourcesContent":["import pc from 'picocolors';\nimport { runWorkspaceScaffolder } from './core/runner.js';\n\nasync function main() {\n await runWorkspaceScaffolder();\n}\n\nmain().catch((err) => {\n console.error(pc.red('Fatal Error during execution:'), err);\n process.exit(1);\n});\n","import path from 'path';\n\nimport { startCli } from './startcli.js';\nimport { promptWorkspaceName } from './workspaceName.js';\nimport { makeDirectories } from '../tasks/directories.js';\nimport { runPrettierSetup } from '../tasks/prettier.js';\nimport { runGitSetup } from '../tasks/git.js';\nimport { runHuskySetup } from '../tasks/husky.js';\nimport { endCli } from './endcli.js';\n\nexport async function runWorkspaceScaffolder() {\n // 1. Greet and display premium logo\n startCli();\n\n // 2. Prompt for Name (Optional, defaults to morax-workspace)\n const name = await promptWorkspaceName();\n const projectPath = path.join(process.cwd(), name);\n\n // 3. Prompt and execute directories and workspace config generation\n await makeDirectories(name, projectPath);\n\n // 4. Prompt and execute Git initialization\n const gitInitialized = await runGitSetup(projectPath);\n\n // 5. Prompt and execute Prettier setup\n await runPrettierSetup(projectPath);\n\n // 6. Prompt and execute Husky setup\n await runHuskySetup(projectPath, gitInitialized);\n\n // 7. Complete and show beautiful finish screen\n endCli(name, projectPath);\n}\n","import gradient from 'gradient-string';\nimport pc from 'picocolors';\nimport { intro } from '@clack/prompts';\nimport boxen from 'boxen';\n\nconst asciiArt = [\n 'āāāā āāāā āāāāāāā āāāāāāā āāāāāā āāā āāā',\n 'āāāāā āāāāā āāāāāāāāā āāāāāāāā āāāāāāāā āāāāāāāā',\n 'āāāāāāāāāāā āāā āāā āāāāāāāā āāāāāāāā āāāāāā ',\n 'āāāāāāāāāāā āāā āāā āāāāāāāā āāāāāāāā āāāāāā ',\n 'āāā āāā āāā āāāāāāāāā āāā āāā āāā āāā āāāā āāā',\n 'āāā āāā āāāāāāā āāā āāā āāā āāā āāā āāā',\n].join('\\n');\n\nexport function startCli() {\n console.clear();\n\n // Premium fiery orange-to-yellow brand gradient\n const moraxGradient = gradient(['#FF3E00', '#FF8C00', '#FFAE19']);\n\n console.log('\\n');\n console.log(moraxGradient(asciiArt));\n console.log('\\n');\n\n intro(pc.yellow('š Welcome to Morax ā The Next-Gen Workspace Scaffolder'));\n\n console.log(\n boxen(\n `ā” ${pc.bold('Morax')} automates the setup of modern ${pc.cyan('pnpm workspaces')}, linking internal shared configurations, UI packages, and framework apps concurrently.`,\n {\n padding: 1,\n margin: { top: 0, bottom: 1, left: 1, right: 1 },\n borderStyle: 'round',\n borderColor: 'yellow',\n },\n ),\n );\n}\n","import { text } from '@clack/prompts';\nimport handleCancel from '../utils/isCancel.js';\n\nexport async function promptWorkspaceName(): Promise<string> {\n const nameInput = await text({\n message: 'What is the name of your new monorepo workspace?',\n placeholder: 'morax-workspace',\n validate(value) {\n if (value && value.includes(' '))\n return 'Workspace name cannot contain spaces!';\n },\n });\n\n handleCancel(nameInput);\n\n // Fallback to morax-workspace if left blank\n return String(nameInput).trim() || 'morax-workspace';\n}\n","import { isCancel, cancel } from '@clack/prompts';\nimport pc from 'picocolors';\n\nexport default function handleCancel(input: any) {\n if (isCancel(input)) {\n cancel(pc.red('ā Morax cancelled.'));\n process.exit(0);\n }\n}\n","import { multiselect, spinner } from '@clack/prompts';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport { generateWorkspaceConfig } from './workspace.js';\n\nexport async function createDirectories(\n directories: ('apps' | 'packages')[],\n projectPath: string,\n) {\n for (const dir of directories) {\n const dirPath = path.join(projectPath, dir);\n await fsPromises.mkdir(dirPath, { recursive: true });\n await fsPromises.writeFile(\n path.join(dirPath, '.gitkeep'),\n `# Placeholder to ensure git tracks the empty ${dir}/ folder\\n`,\n 'utf8',\n );\n }\n}\n\nexport async function makeDirectories(name: string, projectPath: string) {\n const directories = await multiselect({\n message: 'Which directories do you want to include in your workspace?',\n options: [\n {\n value: 'apps',\n label: 'apps/*',\n hint: 'For frontend apps and backend services',\n },\n {\n value: 'packages',\n label: 'packages/*',\n hint: 'For shared components, configs, and utilities',\n },\n ],\n required: true,\n });\n\n handleCancel(directories);\n\n const s = spinner();\n console.log('\\n');\n s.start('Generating workspace configs...');\n try {\n await generateWorkspaceConfig(\n name,\n directories as ('apps' | 'packages')[],\n projectPath,\n );\n await createDirectories(\n directories as ('apps' | 'packages')[],\n projectPath,\n );\n s.stop(pc.green('ā Success: Generated Workspace Root & Folder Structures'));\n } catch (error: any) {\n s.stop(pc.red('ā Failed: Workspace generation failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n\n return directories;\n}\n","import fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function generateWorkspaceConfig(\n name: string,\n directories: ('apps' | 'packages')[],\n projectPath: string,\n) {\n // 1. Create target folder if it doesn't exist\n await fsPromises.mkdir(projectPath, { recursive: true });\n\n // 2. Generate pnpm-workspace.yaml based on user's selective input\n const workspaceYamlContent = [\n 'packages:',\n ...directories.map((dir) => ` - '${dir}/*'`),\n '',\n ].join('\\n');\n\n await fsPromises.writeFile(\n path.join(projectPath, 'pnpm-workspace.yaml'),\n workspaceYamlContent,\n 'utf8',\n );\n\n // 3. Generate Root package.json using pnpm init\n await runCommand('pnpm init', { cwd: projectPath, silent: true });\n\n // 4. Read, parse and customize the package.json\n const packageJsonPath = path.join(projectPath, 'package.json');\n const packageJsonRaw = await fsPromises.readFile(packageJsonPath, 'utf8');\n const pkg = JSON.parse(packageJsonRaw);\n\n pkg.name = name;\n pkg.description = 'High-performance monorepo workspace generated by Morax';\n pkg.private = true;\n pkg.packageManager = 'pnpm@9.15.4';\n pkg.workspaces = directories.map((dir) => `${dir}/*`);\n pkg.scripts = {\n dev: 'pnpm --filter morax-web dev',\n };\n\n // Remove entry points since workspace root is private and has no main entry\n delete pkg.main;\n\n await fsPromises.writeFile(\n packageJsonPath,\n JSON.stringify(pkg, null, 2),\n 'utf8',\n );\n}\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport pc from 'picocolors';\n\nconst execAsync = promisify(exec);\n\nexport interface RunCommandOptions {\n cwd?: string;\n silent?: boolean;\n}\n\n/**\n * Reusable helper to execute commands and print/return their outputs\n */\nexport async function runCommand(\n command: string,\n options: RunCommandOptions = {},\n) {\n if (!options.silent) {\n console.log(pc.cyan(`> ${command}`));\n }\n\n try {\n const { stdout, stderr } = await execAsync(command, {\n cwd: options.cwd,\n env: { ...process.env, NODE_NO_WARNINGS: '1' },\n });\n\n if (!options.silent) {\n if (stdout && stdout.trim()) {\n console.log(stdout.trim());\n }\n if (stderr && stderr.trim()) {\n console.log(pc.yellow(stderr.trim()));\n }\n }\n\n return { stdout, stderr };\n } catch (error: any) {\n if (!options.silent) {\n if (error.stdout && error.stdout.trim()) {\n console.log(error.stdout.trim());\n }\n if (error.stderr && error.stderr.trim()) {\n console.error(pc.red(error.stderr.trim()));\n }\n }\n throw error;\n }\n}\n","import { confirm, spinner } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function promptPrettier() {\n return await confirm({\n message: 'Do you want to setup Prettier code formatting?',\n initialValue: true,\n });\n}\n\nexport async function setupPrettier(projectPath: string) {\n // 1. Install Prettier dynamically with exact version at the workspace root\n await runCommand('pnpm add -D -E prettier -w', { cwd: projectPath });\n\n // 2. Create high-quality modern .prettierrc\n const prettierrc = {\n semi: true,\n singleQuote: true,\n tabWidth: 2,\n trailingComma: 'all',\n printWidth: 100,\n };\n\n await fsPromises.writeFile(\n path.join(projectPath, '.prettierrc'),\n JSON.stringify(prettierrc, null, 2),\n 'utf8',\n );\n\n // 3. Create comprehensive .prettierignore\n const prettierignore = [\n '# Dependencies',\n 'node_modules/',\n 'jspm_packages/',\n 'web_modules/',\n '',\n '# Build and outputs',\n 'dist/',\n 'build/',\n '.next/',\n 'out/',\n '.turbo/',\n '',\n '# Configuration locks',\n 'pnpm-lock.yaml',\n '',\n '# Environment files',\n '.env',\n '.env.*',\n '',\n ].join('\\n');\n\n await fsPromises.writeFile(\n path.join(projectPath, '.prettierignore'),\n prettierignore,\n 'utf8',\n );\n\n // 4. Inject format script to root package.json\n const rootPackagePath = path.join(projectPath, 'package.json');\n const rootPackageContent = await fsPromises.readFile(rootPackagePath, 'utf8');\n const pkg = JSON.parse(rootPackageContent);\n\n pkg.scripts = {\n ...(pkg.scripts || {}),\n format: 'prettier --write .',\n };\n\n await fsPromises.writeFile(\n rootPackagePath,\n JSON.stringify(pkg, null, 2),\n 'utf8',\n );\n\n // 5. Initial format execution to clean up generated files\n await runCommand('pnpm format', { cwd: projectPath });\n}\n\nexport async function runPrettierSetup(projectPath: string) {\n const prettierPrompt = await promptPrettier();\n\n handleCancel(prettierPrompt);\n\n if (prettierPrompt) {\n const s = spinner();\n console.log('\\n');\n s.start('Setting up Prettier auto-formatting...');\n try {\n await setupPrettier(projectPath);\n s.stop(pc.green('ā Success: Prettier formatting configured'));\n } catch (error: any) {\n s.stop(pc.red('ā Failed: Prettier setup failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n }\n}\n","import { confirm, spinner } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function promptGit() {\n return await confirm({\n message: 'Do you want to initialize a local Git repository?',\n initialValue: true,\n });\n}\n\nexport async function gitInit(projectPath: string) {\n // 1. Initialize empty git repository\n await runCommand('git init', { cwd: projectPath, silent: true });\n\n // 2. Create high-quality standard .gitignore\n const gitignore = [\n '# Dependency directories',\n 'node_modules/',\n 'jspm_packages/',\n 'web_modules/',\n '',\n '# Build and output outputs',\n 'dist/',\n 'build/',\n '.next/',\n 'out/',\n '.turbo/',\n '',\n '# Environments',\n '.env',\n '.env.local',\n '.env.development.local',\n '.env.test.local',\n '.env.production.local',\n '',\n '# Logs',\n 'npm-debug.log*',\n 'yarn-debug.log*',\n 'yarn-error.log*',\n 'pnpm-debug.log*',\n '*.log',\n '',\n '# OS Metadata',\n '.DS_Store',\n 'Thumbs.db',\n '',\n ].join('\\n');\n\n await fsPromises.writeFile(\n path.join(projectPath, '.gitignore'),\n gitignore,\n 'utf8',\n );\n}\n\nexport async function runGitSetup(projectPath: string): Promise<boolean> {\n const gitPrompt = await promptGit();\n\n handleCancel(gitPrompt);\n\n let gitInitialized = false;\n if (gitPrompt) {\n const s = spinner();\n console.log('\\n');\n s.start('Initializing Git repository...');\n try {\n await gitInit(projectPath);\n s.stop(pc.green('ā Success: Git repository initialized'));\n gitInitialized = true;\n } catch (error: any) {\n s.stop(pc.red('ā Failed: Git initialization failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n }\n return gitInitialized;\n}\n","import { confirm, spinner } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function promptHusky() {\n return await confirm({\n message: 'Do you want to setup Husky pre-commit hooks?',\n initialValue: true,\n });\n}\n\nexport async function setupHusky(projectPath: string) {\n // 1. Install Husky dynamically with exact version at the workspace root\n await runCommand('pnpm add -D -E husky -w', { cwd: projectPath });\n\n // 2. Initialize Husky using its official init generator\n await runCommand('pnpm exec husky init', { cwd: projectPath });\n\n // 3. Update the auto-generated .husky/pre-commit file to run format and stage files\n const preCommitPath = path.join(projectPath, '.husky', 'pre-commit');\n let hookContent = '';\n try {\n hookContent = await fsPromises.readFile(preCommitPath, 'utf8');\n } catch {\n hookContent = 'pnpm test'; // Default fallback\n }\n\n // Replace default test commands with formatting checks\n hookContent = hookContent.replace('pnpm test', 'pnpm format');\n\n // Append staging of newly formatted files\n if (!hookContent.includes('git add .')) {\n hookContent = hookContent.trim() + '\\ngit add .\\n';\n }\n\n await fsPromises.writeFile(preCommitPath, hookContent, 'utf8');\n\n try {\n await fsPromises.chmod(preCommitPath, 0o755);\n } catch {}\n}\n\nexport async function runHuskySetup(\n projectPath: string,\n gitInitialized: boolean,\n) {\n if (!gitInitialized) return;\n\n const huskyPrompt = await promptHusky();\n\n handleCancel(huskyPrompt);\n\n if (huskyPrompt) {\n const s = spinner();\n console.log('\\n');\n s.start('Setting up Husky hooks...');\n try {\n await setupHusky(projectPath);\n s.stop(pc.green('ā Success: Husky pre-commit hooks configured'));\n } catch (error: any) {\n s.stop(pc.red('ā Failed: Husky setup failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n }\n}\n","import pc from 'picocolors';\nimport { outro } from '@clack/prompts';\nimport boxen from 'boxen';\n\nexport function endCli(name: string, projectPath: string) {\n // Complete and show beautiful finish screen\n outro(pc.yellow('Morax scaffolding completed successfully!'));\n\n console.log(\n boxen(\n `ā” ${pc.bold('Workspace ready:')} ${pc.yellow(name)}\\n` +\n `Location: ${pc.cyan(projectPath)}\\n\\n` +\n `${pc.bold('To start developing:')}\\n` +\n ` 1. ${pc.cyan(`cd ${name}`)}\\n` +\n ` 2. ${pc.cyan('pnpm dev')}\\n\\n` +\n `š” Code formatting & git orchestration is fully active.`,\n {\n padding: 0,\n margin: 0,\n borderStyle: 'round',\n borderColor: 'yellow',\n title: pc.black(pc.bold(' Setup Complete ')),\n titleAlignment: 'center',\n },\n ),\n );\n}\n"],"mappings":";;;AAAA,OAAOA,SAAQ;;;ACAf,OAAOC,WAAU;;;ACAjB,OAAO,cAAc;AACrB,OAAO,QAAQ;AACf,SAAS,aAAa;AACtB,OAAO,WAAW;AAElB,IAAM,WAAW;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAEJ,SAAS,WAAW;AACzB,UAAQ,MAAM;AAGd,QAAM,gBAAgB,SAAS,CAAC,WAAW,WAAW,SAAS,CAAC;AAEhE,UAAQ,IAAI,IAAI;AAChB,UAAQ,IAAI,cAAc,QAAQ,CAAC;AACnC,UAAQ,IAAI,IAAI;AAEhB,QAAM,GAAG,OAAO,qEAAyD,CAAC;AAE1E,UAAQ;AAAA,IACN;AAAA,MACE,UAAK,GAAG,KAAK,OAAO,CAAC,kCAAkC,GAAG,KAAK,iBAAiB,CAAC;AAAA,MACjF;AAAA,QACE,SAAS;AAAA,QACT,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,EAAE;AAAA,QAC/C,aAAa;AAAA,QACb,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;;;ACrCA,SAAS,YAAY;;;ACArB,SAAS,UAAU,cAAc;AACjC,OAAOC,SAAQ;AAEA,SAAR,aAA8B,OAAY;AAC/C,MAAI,SAAS,KAAK,GAAG;AACnB,WAAOA,IAAG,IAAI,yBAAoB,CAAC;AACnC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;ADLA,eAAsB,sBAAuC;AAC3D,QAAM,YAAY,MAAM,KAAK;AAAA,IAC3B,SAAS;AAAA,IACT,aAAa;AAAA,IACb,SAAS,OAAO;AACd,UAAI,SAAS,MAAM,SAAS,GAAG;AAC7B,eAAO;AAAA,IACX;AAAA,EACF,CAAC;AAED,eAAa,SAAS;AAGtB,SAAO,OAAO,SAAS,EAAE,KAAK,KAAK;AACrC;;;AEjBA,SAAS,aAAa,eAAe;AACrC,OAAOC,iBAAgB;AACvB,OAAOC,WAAU;AACjB,OAAOC,SAAQ;;;ACHf,OAAO,gBAAgB;AACvB,OAAO,UAAU;;;ACDjB,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,OAAOC,SAAQ;AAEf,IAAM,YAAY,UAAU,IAAI;AAUhC,eAAsB,WACpB,SACA,UAA6B,CAAC,GAC9B;AACA,MAAI,CAAC,QAAQ,QAAQ;AACnB,YAAQ,IAAIA,IAAG,KAAK,KAAK,OAAO,EAAE,CAAC;AAAA,EACrC;AAEA,MAAI;AACF,UAAM,EAAE,QAAQ,OAAO,IAAI,MAAM,UAAU,SAAS;AAAA,MAClD,KAAK,QAAQ;AAAA,MACb,KAAK,EAAE,GAAG,QAAQ,KAAK,kBAAkB,IAAI;AAAA,IAC/C,CAAC;AAED,QAAI,CAAC,QAAQ,QAAQ;AACnB,UAAI,UAAU,OAAO,KAAK,GAAG;AAC3B,gBAAQ,IAAI,OAAO,KAAK,CAAC;AAAA,MAC3B;AACA,UAAI,UAAU,OAAO,KAAK,GAAG;AAC3B,gBAAQ,IAAIA,IAAG,OAAO,OAAO,KAAK,CAAC,CAAC;AAAA,MACtC;AAAA,IACF;AAEA,WAAO,EAAE,QAAQ,OAAO;AAAA,EAC1B,SAAS,OAAY;AACnB,QAAI,CAAC,QAAQ,QAAQ;AACnB,UAAI,MAAM,UAAU,MAAM,OAAO,KAAK,GAAG;AACvC,gBAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,MACjC;AACA,UAAI,MAAM,UAAU,MAAM,OAAO,KAAK,GAAG;AACvC,gBAAQ,MAAMA,IAAG,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,MAC3C;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;;;AD7CA,eAAsB,wBACpB,MACA,aACA,aACA;AAEA,QAAM,WAAW,MAAM,aAAa,EAAE,WAAW,KAAK,CAAC;AAGvD,QAAM,uBAAuB;AAAA,IAC3B;AAAA,IACA,GAAG,YAAY,IAAI,CAAC,QAAQ,QAAQ,GAAG,KAAK;AAAA,IAC5C;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,QAAM,WAAW;AAAA,IACf,KAAK,KAAK,aAAa,qBAAqB;AAAA,IAC5C;AAAA,IACA;AAAA,EACF;AAGA,QAAM,WAAW,aAAa,EAAE,KAAK,aAAa,QAAQ,KAAK,CAAC;AAGhE,QAAM,kBAAkB,KAAK,KAAK,aAAa,cAAc;AAC7D,QAAM,iBAAiB,MAAM,WAAW,SAAS,iBAAiB,MAAM;AACxE,QAAM,MAAM,KAAK,MAAM,cAAc;AAErC,MAAI,OAAO;AACX,MAAI,cAAc;AAClB,MAAI,UAAU;AACd,MAAI,iBAAiB;AACrB,MAAI,aAAa,YAAY,IAAI,CAAC,QAAQ,GAAG,GAAG,IAAI;AACpD,MAAI,UAAU;AAAA,IACZ,KAAK;AAAA,EACP;AAGA,SAAO,IAAI;AAEX,QAAM,WAAW;AAAA,IACf;AAAA,IACA,KAAK,UAAU,KAAK,MAAM,CAAC;AAAA,IAC3B;AAAA,EACF;AACF;;;AD3CA,eAAsB,kBACpB,aACA,aACA;AACA,aAAW,OAAO,aAAa;AAC7B,UAAM,UAAUC,MAAK,KAAK,aAAa,GAAG;AAC1C,UAAMC,YAAW,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AACnD,UAAMA,YAAW;AAAA,MACfD,MAAK,KAAK,SAAS,UAAU;AAAA,MAC7B,gDAAgD,GAAG;AAAA;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,gBAAgB,MAAc,aAAqB;AACvE,QAAM,cAAc,MAAM,YAAY;AAAA,IACpC,SAAS;AAAA,IACT,SAAS;AAAA,MACP;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,UAAU;AAAA,EACZ,CAAC;AAED,eAAa,WAAW;AAExB,QAAM,IAAI,QAAQ;AAClB,UAAQ,IAAI,IAAI;AAChB,IAAE,MAAM,iCAAiC;AACzC,MAAI;AACF,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,IACF;AACA,MAAE,KAAKE,IAAG,MAAM,8DAAyD,CAAC;AAAA,EAC5E,SAAS,OAAY;AACnB,MAAE,KAAKA,IAAG,IAAI,4CAAuC,CAAC;AACtD,YAAQ,MAAMA,IAAG,IAAI;AAAA,iBAAoB,MAAM,WAAW,KAAK,EAAE,CAAC;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,IAAI,IAAI;AAEhB,SAAO;AACT;;;AGhEA,SAAS,SAAS,WAAAC,gBAAe;AACjC,OAAOC,SAAQ;AAEf,OAAOC,iBAAgB;AACvB,OAAOC,WAAU;AAGjB,eAAsB,iBAAiB;AACrC,SAAO,MAAM,QAAQ;AAAA,IACnB,SAAS;AAAA,IACT,cAAc;AAAA,EAChB,CAAC;AACH;AAEA,eAAsB,cAAc,aAAqB;AAEvD,QAAM,WAAW,8BAA8B,EAAE,KAAK,YAAY,CAAC;AAGnE,QAAM,aAAa;AAAA,IACjB,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,eAAe;AAAA,IACf,YAAY;AAAA,EACd;AAEA,QAAMC,YAAW;AAAA,IACfC,MAAK,KAAK,aAAa,aAAa;AAAA,IACpC,KAAK,UAAU,YAAY,MAAM,CAAC;AAAA,IAClC;AAAA,EACF;AAGA,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,QAAMD,YAAW;AAAA,IACfC,MAAK,KAAK,aAAa,iBAAiB;AAAA,IACxC;AAAA,IACA;AAAA,EACF;AAGA,QAAM,kBAAkBA,MAAK,KAAK,aAAa,cAAc;AAC7D,QAAM,qBAAqB,MAAMD,YAAW,SAAS,iBAAiB,MAAM;AAC5E,QAAM,MAAM,KAAK,MAAM,kBAAkB;AAEzC,MAAI,UAAU;AAAA,IACZ,GAAI,IAAI,WAAW,CAAC;AAAA,IACpB,QAAQ;AAAA,EACV;AAEA,QAAMA,YAAW;AAAA,IACf;AAAA,IACA,KAAK,UAAU,KAAK,MAAM,CAAC;AAAA,IAC3B;AAAA,EACF;AAGA,QAAM,WAAW,eAAe,EAAE,KAAK,YAAY,CAAC;AACtD;AAEA,eAAsB,iBAAiB,aAAqB;AAC1D,QAAM,iBAAiB,MAAM,eAAe;AAE5C,eAAa,cAAc;AAE3B,MAAI,gBAAgB;AAClB,UAAM,IAAIE,SAAQ;AAClB,YAAQ,IAAI,IAAI;AAChB,MAAE,MAAM,wCAAwC;AAChD,QAAI;AACF,YAAM,cAAc,WAAW;AAC/B,QAAE,KAAKC,IAAG,MAAM,gDAA2C,CAAC;AAAA,IAC9D,SAAS,OAAY;AACnB,QAAE,KAAKA,IAAG,IAAI,sCAAiC,CAAC;AAChD,cAAQ,MAAMA,IAAG,IAAI;AAAA,iBAAoB,MAAM,WAAW,KAAK,EAAE,CAAC;AAClE,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,YAAQ,IAAI,IAAI;AAAA,EAClB;AACF;;;ACrGA,SAAS,WAAAC,UAAS,WAAAC,gBAAe;AACjC,OAAOC,SAAQ;AAEf,OAAOC,iBAAgB;AACvB,OAAOC,WAAU;AAGjB,eAAsB,YAAY;AAChC,SAAO,MAAMC,SAAQ;AAAA,IACnB,SAAS;AAAA,IACT,cAAc;AAAA,EAChB,CAAC;AACH;AAEA,eAAsB,QAAQ,aAAqB;AAEjD,QAAM,WAAW,YAAY,EAAE,KAAK,aAAa,QAAQ,KAAK,CAAC;AAG/D,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,QAAMC,YAAW;AAAA,IACfC,MAAK,KAAK,aAAa,YAAY;AAAA,IACnC;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,YAAY,aAAuC;AACvE,QAAM,YAAY,MAAM,UAAU;AAElC,eAAa,SAAS;AAEtB,MAAI,iBAAiB;AACrB,MAAI,WAAW;AACb,UAAM,IAAIC,SAAQ;AAClB,YAAQ,IAAI,IAAI;AAChB,MAAE,MAAM,gCAAgC;AACxC,QAAI;AACF,YAAM,QAAQ,WAAW;AACzB,QAAE,KAAKC,IAAG,MAAM,4CAAuC,CAAC;AACxD,uBAAiB;AAAA,IACnB,SAAS,OAAY;AACnB,QAAE,KAAKA,IAAG,IAAI,0CAAqC,CAAC;AACpD,cAAQ,MAAMA,IAAG,IAAI;AAAA,iBAAoB,MAAM,WAAW,KAAK,EAAE,CAAC;AAClE,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,YAAQ,IAAI,IAAI;AAAA,EAClB;AACA,SAAO;AACT;;;ACjFA,SAAS,WAAAC,UAAS,WAAAC,gBAAe;AACjC,OAAOC,SAAQ;AAEf,OAAOC,iBAAgB;AACvB,OAAOC,WAAU;AAGjB,eAAsB,cAAc;AAClC,SAAO,MAAMC,SAAQ;AAAA,IACnB,SAAS;AAAA,IACT,cAAc;AAAA,EAChB,CAAC;AACH;AAEA,eAAsB,WAAW,aAAqB;AAEpD,QAAM,WAAW,2BAA2B,EAAE,KAAK,YAAY,CAAC;AAGhE,QAAM,WAAW,wBAAwB,EAAE,KAAK,YAAY,CAAC;AAG7D,QAAM,gBAAgBC,MAAK,KAAK,aAAa,UAAU,YAAY;AACnE,MAAI,cAAc;AAClB,MAAI;AACF,kBAAc,MAAMC,YAAW,SAAS,eAAe,MAAM;AAAA,EAC/D,QAAQ;AACN,kBAAc;AAAA,EAChB;AAGA,gBAAc,YAAY,QAAQ,aAAa,aAAa;AAG5D,MAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,kBAAc,YAAY,KAAK,IAAI;AAAA,EACrC;AAEA,QAAMA,YAAW,UAAU,eAAe,aAAa,MAAM;AAE7D,MAAI;AACF,UAAMA,YAAW,MAAM,eAAe,GAAK;AAAA,EAC7C,QAAQ;AAAA,EAAC;AACX;AAEA,eAAsB,cACpB,aACA,gBACA;AACA,MAAI,CAAC,eAAgB;AAErB,QAAM,cAAc,MAAM,YAAY;AAEtC,eAAa,WAAW;AAExB,MAAI,aAAa;AACf,UAAM,IAAIC,SAAQ;AAClB,YAAQ,IAAI,IAAI;AAChB,MAAE,MAAM,2BAA2B;AACnC,QAAI;AACF,YAAM,WAAW,WAAW;AAC5B,QAAE,KAAKC,IAAG,MAAM,mDAA8C,CAAC;AAAA,IACjE,SAAS,OAAY;AACnB,QAAE,KAAKA,IAAG,IAAI,mCAA8B,CAAC;AAC7C,cAAQ,MAAMA,IAAG,IAAI;AAAA,iBAAoB,MAAM,WAAW,KAAK,EAAE,CAAC;AAClE,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,YAAQ,IAAI,IAAI;AAAA,EAClB;AACF;;;ACrEA,OAAOC,SAAQ;AACf,SAAS,aAAa;AACtB,OAAOC,YAAW;AAEX,SAAS,OAAO,MAAc,aAAqB;AAExD,QAAMD,IAAG,OAAO,2CAA2C,CAAC;AAE5D,UAAQ;AAAA,IACNC;AAAA,MACE,UAAKD,IAAG,KAAK,kBAAkB,CAAC,IAAIA,IAAG,OAAO,IAAI,CAAC;AAAA,YACpCA,IAAG,KAAK,WAAW,CAAC;AAAA;AAAA,EAC9BA,IAAG,KAAK,sBAAsB,CAAC;AAAA,MAC3BA,IAAG,KAAK,MAAM,IAAI,EAAE,CAAC;AAAA,MACrBA,IAAG,KAAK,UAAU,CAAC;AAAA;AAAA;AAAA,MAE5B;AAAA,QACE,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,aAAa;AAAA,QACb,OAAOA,IAAG,MAAMA,IAAG,KAAK,kBAAkB,CAAC;AAAA,QAC3C,gBAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;;;AVhBA,eAAsB,yBAAyB;AAE7C,WAAS;AAGT,QAAM,OAAO,MAAM,oBAAoB;AACvC,QAAM,cAAcE,MAAK,KAAK,QAAQ,IAAI,GAAG,IAAI;AAGjD,QAAM,gBAAgB,MAAM,WAAW;AAGvC,QAAM,iBAAiB,MAAM,YAAY,WAAW;AAGpD,QAAM,iBAAiB,WAAW;AAGlC,QAAM,cAAc,aAAa,cAAc;AAG/C,SAAO,MAAM,WAAW;AAC1B;;;AD7BA,eAAe,OAAO;AACpB,QAAM,uBAAuB;AAC/B;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAMC,IAAG,IAAI,+BAA+B,GAAG,GAAG;AAC1D,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["pc","path","pc","fsPromises","path","pc","pc","path","fsPromises","pc","spinner","pc","fsPromises","path","fsPromises","path","spinner","pc","confirm","spinner","pc","fsPromises","path","confirm","fsPromises","path","spinner","pc","confirm","spinner","pc","fsPromises","path","confirm","path","fsPromises","spinner","pc","pc","boxen","path","pc"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/runner.ts","../src/core/startcli.ts","../src/core/workspaceName.ts","../src/utils/isCancel.ts","../src/tasks/directories.ts","../src/tasks/workspace.ts","../src/utils/exec.ts","../src/tasks/prettier.ts","../src/tasks/eslint.ts","../src/tasks/typescript.ts","../src/tasks/server.ts","../src/tasks/git.ts","../src/tasks/husky.ts","../src/core/endcli.ts","../src/tasks/addreadme.ts","../src/core/web.ts","../src/tasks/shadcn.ts","../src/tasks/nextjs.ts","../src/tasks/react.ts"],"sourcesContent":["import pc from 'picocolors';\nimport { runWorkspaceScaffolder } from './core/runner.js';\n\nasync function main() {\n await runWorkspaceScaffolder();\n}\n\nmain().catch((err) => {\n console.error(pc.red('Fatal Error during execution:'), err);\n process.exit(1);\n});\n","import path from 'path';\nimport { spinner } from '@clack/prompts';\nimport pc from 'picocolors';\n\nimport { startCli } from './startcli.js';\nimport { promptWorkspaceName } from './workspaceName.js';\nimport { makeDirectories } from '../tasks/directories.js';\nimport { runPrettierSetup } from '../tasks/prettier.js';\nimport { runEslintSetup } from '../tasks/eslint.js';\nimport { runTypescriptSetup } from '../tasks/typescript.js';\nimport { runServerSetup } from '../tasks/server.js';\nimport { runGitSetup } from '../tasks/git.js';\nimport { runHuskySetup } from '../tasks/husky.js';\nimport { endCli } from './endcli.js';\nimport { runCommand } from '../utils/exec.js';\nimport { setupReadme } from '../tasks/addreadme.js';\nimport addNextjs from './web.js';\n\nexport async function runWorkspaceScaffolder() {\n // 1. Greet and display premium logo\n startCli();\n\n // 2. Prompt for Name (Optional, defaults to morax-workspace)\n const name = await promptWorkspaceName();\n const projectPath = path.join(process.cwd(), name);\n\n // 3. Prompt and execute directories and workspace config generation\n await makeDirectories(name, projectPath);\n\n // Add the root README silently immediately after directory creation\n await setupReadme(projectPath, name);\n\n // 4. Prompt and execute Git initialization\n const gitInitialized = await runGitSetup(projectPath);\n\n // 5. Prompt and execute Prettier setup\n await runPrettierSetup(projectPath);\n\n // 6. Prompt and execute ESLint setup\n await runEslintSetup(projectPath);\n\n // 7. Prompt and execute TypeScript setup\n await runTypescriptSetup(projectPath);\n\n // 8. Prompt and execute Husky setup\n await runHuskySetup(projectPath, gitInitialized);\n\n // 9. Prompt and execute Express Backend setup\n await runServerSetup(projectPath);\n\n // 10. Prompt and execute Next.js Frontend setup\n await addNextjs(projectPath);\n\n // 11. Run final pnpm install to resolve all workspace configurations and symlinks\n const s = spinner();\n console.log('\\n');\n s.start('Running final workspace package installation...');\n try {\n await runCommand('pnpm install', { cwd: projectPath, silent: true });\n s.stop(\n pc.green(\n 'ā Success: Workspace dependencies and symlinks configured successfully',\n ),\n );\n } catch (error: any) {\n s.stop(pc.red('ā Warning: Final workspace installation failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n }\n console.log('\\n');\n\n // 13. Complete and show beautiful finish screen\n endCli(name, projectPath);\n}\n","import gradient from 'gradient-string';\nimport pc from 'picocolors';\nimport { intro } from '@clack/prompts';\nimport boxen from 'boxen';\n\nconst asciiArt = [\n 'āāāā āāāā āāāāāāā āāāāāāā āāāāāā āāā āāā',\n 'āāāāā āāāāā āāāāāāāāā āāāāāāāā āāāāāāāā āāāāāāāā',\n 'āāāāāāāāāāā āāā āāā āāāāāāāā āāāāāāāā āāāāāā ',\n 'āāāāāāāāāāā āāā āāā āāāāāāāā āāāāāāāā āāāāāā ',\n 'āāā āāā āāā āāāāāāāāā āāā āāā āāā āāā āāāā āāā',\n 'āāā āāā āāāāāāā āāā āāā āāā āāā āāā āāā',\n].join('\\n');\n\nexport function startCli() {\n console.clear();\n\n // Premium fiery orange-to-yellow brand gradient\n const moraxGradient = gradient(['#FF3E00', '#FF8C00', '#FFAE19']);\n\n console.log('\\n');\n console.log(moraxGradient(asciiArt));\n console.log('\\n');\n\n intro(pc.yellow('š Welcome to Morax ā The Next-Gen Workspace Scaffolder'));\n\n console.log(\n boxen(\n `ā” ${pc.bold('Morax')} automates the setup of modern ${pc.cyan('pnpm workspaces')}, linking internal shared configurations, UI packages, and framework apps concurrently.`,\n {\n padding: 1,\n margin: { top: 0, bottom: 1, left: 1, right: 1 },\n borderStyle: 'round',\n borderColor: 'yellow',\n },\n ),\n );\n}\n","import { text } from '@clack/prompts';\nimport handleCancel from '../utils/isCancel.js';\n\nexport async function promptWorkspaceName(): Promise<string> {\n const nameInput = await text({\n message: 'What is the name of your new monorepo workspace?',\n placeholder: 'morax-workspace',\n validate(value) {\n if (value && value.includes(' '))\n return 'Workspace name cannot contain spaces!';\n },\n });\n\n handleCancel(nameInput);\n\n // Fallback to morax-workspace if left blank\n return String(nameInput).trim() || 'morax-workspace';\n}\n","import { isCancel, cancel } from '@clack/prompts';\nimport pc from 'picocolors';\n\nexport default function handleCancel(input: any) {\n if (isCancel(input)) {\n cancel(pc.red('ā Morax cancelled.'));\n process.exit(0);\n }\n}\n","import { multiselect, spinner } from '@clack/prompts';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport { generateWorkspaceConfig } from './workspace.js';\n\nexport async function createDirectories(\n directories: ('apps' | 'packages')[],\n projectPath: string,\n) {\n for (const dir of directories) {\n const dirPath = path.join(projectPath, dir);\n await fsPromises.mkdir(dirPath, { recursive: true });\n await fsPromises.writeFile(\n path.join(dirPath, '.gitkeep'),\n `# Placeholder to ensure git tracks the empty ${dir}/ folder\\n`,\n 'utf8',\n );\n }\n}\n\nexport async function makeDirectories(name: string, projectPath: string) {\n const directories = await multiselect({\n message: 'Which directories do you want to include in your workspace?',\n options: [\n {\n value: 'apps',\n label: 'apps/*',\n hint: 'For frontend apps and backend services',\n },\n {\n value: 'packages',\n label: 'packages/*',\n hint: 'For shared components, configs, and utilities',\n },\n ],\n required: true,\n });\n\n handleCancel(directories);\n\n const s = spinner();\n console.log('\\n');\n s.start('Generating workspace configs...');\n try {\n await generateWorkspaceConfig(\n name,\n directories as ('apps' | 'packages')[],\n projectPath,\n );\n await createDirectories(\n directories as ('apps' | 'packages')[],\n projectPath,\n );\n s.stop(pc.green('ā Success: Generated Workspace Root & Folder Structures'));\n } catch (error: any) {\n s.stop(pc.red('ā Failed: Workspace generation failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n\n return directories;\n}\n","import fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function generateWorkspaceConfig(\n name: string,\n directories: ('apps' | 'packages')[],\n projectPath: string,\n) {\n // 1. Create target folder if it doesn't exist\n await fsPromises.mkdir(projectPath, { recursive: true });\n\n // 2. Generate pnpm-workspace.yaml based on user's selective input\n const workspaceYamlContent = [\n 'packages:',\n ...directories.map((dir) => ` - '${dir}/*'`),\n '',\n ].join('\\n');\n\n await fsPromises.writeFile(\n path.join(projectPath, 'pnpm-workspace.yaml'),\n workspaceYamlContent,\n 'utf8',\n );\n\n // 3. Generate Root package.json using pnpm init\n await runCommand('pnpm init', { cwd: projectPath, silent: true });\n\n // 4. Read, parse and customize the package.json\n const packageJsonPath = path.join(projectPath, 'package.json');\n const packageJsonRaw = await fsPromises.readFile(packageJsonPath, 'utf8');\n const pkg = JSON.parse(packageJsonRaw);\n\n pkg.name = name;\n pkg.description = 'High-performance monorepo workspace generated by Morax';\n pkg.private = true;\n pkg.packageManager = 'pnpm@9.15.4';\n pkg.workspaces = directories.map((dir) => `${dir}/*`);\n pkg.scripts = {\n dev: 'pnpm --filter morax-web dev',\n };\n\n // Remove entry points since workspace root is private and has no main entry\n delete pkg.main;\n\n await fsPromises.writeFile(\n packageJsonPath,\n JSON.stringify(pkg, null, 2),\n 'utf8',\n );\n}\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport pc from 'picocolors';\n\nconst execAsync = promisify(exec);\n\nexport interface RunCommandOptions {\n cwd?: string;\n silent?: boolean;\n}\n\n/**\n * Reusable helper to execute commands and print/return their outputs\n */\nexport async function runCommand(\n command: string,\n options: RunCommandOptions = {},\n) {\n options.silent = true;\n\n if (!options.silent) {\n console.log(pc.cyan(`> ${command}`));\n }\n\n try {\n const { stdout, stderr } = await execAsync(command, {\n cwd: options.cwd,\n env: { ...process.env, NODE_NO_WARNINGS: '1' },\n });\n\n if (!options.silent) {\n if (stdout && stdout.trim()) {\n console.log(stdout.trim());\n }\n if (stderr && stderr.trim()) {\n console.log(pc.yellow(stderr.trim()));\n }\n }\n\n return { stdout, stderr };\n } catch (error: any) {\n if (!options.silent) {\n if (error.stdout && error.stdout.trim()) {\n console.log(error.stdout.trim());\n }\n if (error.stderr && error.stderr.trim()) {\n console.error(pc.red(error.stderr.trim()));\n }\n }\n throw error;\n }\n}\n","import { confirm, spinner } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function promptPrettier() {\n return await confirm({\n message: 'Do you want to setup Prettier code formatting?',\n initialValue: true,\n });\n}\n\nexport async function setupPrettier(projectPath: string) {\n // 1. Install Prettier dynamically with exact version at the workspace root\n await runCommand('pnpm add -D -E prettier -w', { cwd: projectPath });\n\n // 2. Create high-quality modern .prettierrc\n const prettierrc = {\n semi: true,\n singleQuote: true,\n tabWidth: 2,\n trailingComma: 'all',\n printWidth: 100,\n };\n\n await fsPromises.writeFile(\n path.join(projectPath, '.prettierrc'),\n JSON.stringify(prettierrc, null, 2),\n 'utf8',\n );\n\n // 3. Create comprehensive .prettierignore\n const prettierignore = [\n '# Dependencies',\n 'node_modules/',\n 'jspm_packages/',\n 'web_modules/',\n '',\n '# Build and outputs',\n 'dist/',\n 'build/',\n '.next/',\n 'out/',\n '.turbo/',\n '',\n '# Configuration locks',\n 'pnpm-lock.yaml',\n '',\n '# Environment files',\n '.env',\n '.env.*',\n '',\n ].join('\\n');\n\n await fsPromises.writeFile(\n path.join(projectPath, '.prettierignore'),\n prettierignore,\n 'utf8',\n );\n\n // 4. Inject format script to root package.json\n const rootPackagePath = path.join(projectPath, 'package.json');\n const rootPackageContent = await fsPromises.readFile(rootPackagePath, 'utf8');\n const pkg = JSON.parse(rootPackageContent);\n\n pkg.scripts = {\n ...(pkg.scripts || {}),\n format: 'prettier --write .',\n };\n\n await fsPromises.writeFile(\n rootPackagePath,\n JSON.stringify(pkg, null, 2),\n 'utf8',\n );\n\n // 5. Initial format execution to clean up generated files\n await runCommand('pnpm format', { cwd: projectPath });\n}\n\nexport async function runPrettierSetup(projectPath: string) {\n const prettierPrompt = await promptPrettier();\n\n handleCancel(prettierPrompt);\n\n if (prettierPrompt) {\n const s = spinner();\n console.log('\\n');\n s.start('Setting up Prettier auto-formatting...');\n try {\n await setupPrettier(projectPath);\n s.stop(pc.green('ā Success: Prettier formatting configured'));\n } catch (error: any) {\n s.stop(pc.red('ā Failed: Prettier setup failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n }\n}\n","import { confirm, spinner } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function promptEslint() {\n return await confirm({\n message: 'Do you want to setup ESLint linting in packages/eslint?',\n initialValue: true,\n });\n}\n\nexport async function setupEslint(projectPath: string) {\n const eslintDir = path.join(projectPath, 'packages', 'eslint');\n\n // 1. Create packages/eslint directory recursively\n await fsPromises.mkdir(eslintDir, { recursive: true });\n\n // 2. Initialize the package using pnpm init\n await runCommand('pnpm init', { cwd: eslintDir, silent: true });\n\n // 3. Customize the packages/eslint/package.json\n const eslintPackagePath = path.join(eslintDir, 'package.json');\n const eslintPackageRaw = await fsPromises.readFile(eslintPackagePath, 'utf8');\n const eslintPkg = JSON.parse(eslintPackageRaw);\n\n eslintPkg.name = '@config/eslint';\n eslintPkg.version = '1.0.0';\n eslintPkg.private = true;\n eslintPkg.type = 'module';\n eslintPkg.main = 'eslint.config.ts';\n eslintPkg.exports = {\n '.': './eslint.config.ts',\n };\n eslintPkg.scripts = {\n lint: 'eslint .',\n };\n\n // Remove defaults that are not needed\n delete eslintPkg.keywords;\n delete eslintPkg.author;\n delete eslintPkg.license;\n\n await fsPromises.writeFile(\n eslintPackagePath,\n JSON.stringify(eslintPkg, null, 2),\n 'utf8',\n );\n\n // 4. Run pnpm add -D dynamically to fetch and install only the latest packages\n await runCommand(\n 'pnpm add -D eslint @eslint/js @eslint/json globals typescript-eslint',\n { cwd: eslintDir },\n );\n\n // 5. Create Modern eslint.config.ts with Flat Config and @eslint/json support\n const eslintConfigContent = [\n 'import js from \"@eslint/js\";',\n 'import globals from \"globals\";',\n 'import tseslint from \"typescript-eslint\";',\n 'import eslintJson from \"@eslint/json\";',\n '',\n 'export default tseslint.config(',\n ' {',\n ' ignores: [\"**/dist/**\", \"**/node_modules/**\"],',\n ' },',\n ' js.configs.recommended,',\n ' ...tseslint.configs.recommended,',\n ' {',\n ' languageOptions: {',\n ' globals: {',\n ' ...globals.node,',\n ' },',\n ' },',\n ' rules: {',\n ' \"no-unused-vars\": \"off\",',\n ' \"@typescript-eslint/no-unused-vars\": [\"error\", { argsIgnorePattern: \"^_\" }],',\n ' },',\n ' },',\n ' {',\n ' files: [\"**/*.json\"],',\n ' language: \"json/json\",',\n ' ...eslintJson.configs.recommended,',\n ' }',\n ');',\n '',\n ].join('\\n');\n\n await fsPromises.writeFile(\n path.join(eslintDir, 'eslint.config.ts'),\n eslintConfigContent,\n 'utf8',\n );\n\n // 6. Inject lint script into root package.json\n const rootPackagePath = path.join(projectPath, 'package.json');\n const rootPackageContent = await fsPromises.readFile(rootPackagePath, 'utf8');\n const rootPkg = JSON.parse(rootPackageContent);\n\n rootPkg.scripts = {\n ...(rootPkg.scripts || {}),\n lint: 'pnpm --filter @config/eslint lint',\n };\n\n await fsPromises.writeFile(\n rootPackagePath,\n JSON.stringify(rootPkg, null, 2),\n 'utf8',\n );\n}\n\nexport async function runEslintSetup(projectPath: string) {\n // Ensure the packages folder option was generated/exists\n const packagesDir = path.join(projectPath, 'packages');\n try {\n await fsPromises.access(packagesDir);\n } catch {\n // If the packages folder was not scaffolded, we shouldn't attempt to setup ESLint there\n return;\n }\n\n const eslintPrompt = await promptEslint();\n\n handleCancel(eslintPrompt);\n\n if (eslintPrompt) {\n const s = spinner();\n console.log('\\n');\n s.start('Setting up modular ESLint in packages/eslint...');\n try {\n await setupEslint(projectPath);\n s.stop(\n pc.green('ā Success: Modular ESLint configured in packages/eslint'),\n );\n } catch (error: any) {\n s.stop(pc.red('ā Failed: ESLint setup failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n }\n}\n","import { confirm, spinner } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function promptTypescript() {\n return await confirm({\n message: 'Do you want to setup TypeScript config in packages/typescript?',\n initialValue: true,\n });\n}\n\nexport async function setupTypescript(projectPath: string) {\n const tsDir = path.join(projectPath, 'packages', 'typescript');\n\n // 1. Create packages/typescript directory recursively\n await fsPromises.mkdir(tsDir, { recursive: true });\n\n // 2. Initialize the package using pnpm init\n await runCommand('pnpm init', { cwd: tsDir, silent: true });\n\n // 3. Customize the packages/typescript/package.json\n const tsPackagePath = path.join(tsDir, 'package.json');\n const tsPackageRaw = await fsPromises.readFile(tsPackagePath, 'utf8');\n const tsPkg = JSON.parse(tsPackageRaw);\n\n tsPkg.name = '@config/typescript';\n tsPkg.version = '1.0.0';\n tsPkg.private = true;\n tsPkg.type = 'module';\n tsPkg.exports = {\n './tsconfig.json': './tsconfig.json',\n };\n\n // Remove defaults that are not needed\n delete tsPkg.keywords;\n delete tsPkg.author;\n delete tsPkg.license;\n delete tsPkg.main;\n delete tsPkg.scripts;\n\n await fsPromises.writeFile(\n tsPackagePath,\n JSON.stringify(tsPkg, null, 2),\n 'utf8',\n );\n\n // 4. Install typescript package dynamically as devDependency\n await runCommand(\n 'cd ../.. && pnpm add -D typescript -w && cd packages/typescript',\n { cwd: tsDir, silent: true },\n );\n\n // 5. Initialize tsconfig.json using npx tsc --init\n await runCommand('npx tsc --init', { cwd: tsDir });\n}\n\nexport async function runTypescriptSetup(projectPath: string) {\n // Ensure the packages folder option was generated/exists\n const packagesDir = path.join(projectPath, 'packages');\n try {\n await fsPromises.access(packagesDir);\n } catch {\n // If the packages folder was not scaffolded, we shouldn't attempt to setup TS config there\n return;\n }\n\n const tsPrompt = await promptTypescript();\n\n handleCancel(tsPrompt);\n\n if (tsPrompt) {\n const s = spinner();\n console.log('\\n');\n s.start('Setting up modular TypeScript config in packages/typescript...');\n try {\n await setupTypescript(projectPath);\n s.stop(\n pc.green(\n 'ā Success: Modular TypeScript config configured in packages/typescript',\n ),\n );\n } catch (error: any) {\n s.stop(pc.red('ā Failed: TypeScript config setup failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n }\n}\n","import { confirm, spinner } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function promptServer() {\n return await confirm({\n message: 'Do you want to setup a basic Express backend in apps/server?',\n initialValue: true,\n });\n}\n\nexport async function setupServer(projectPath: string) {\n const serverDir = path.join(projectPath, 'apps', 'server');\n const srcDir = path.join(serverDir, 'src');\n\n // 1. Create directory structure apps/server/src recursively\n await fsPromises.mkdir(srcDir, { recursive: true });\n\n // 2. Initialize package.json using pnpm init\n await runCommand('pnpm init', { cwd: serverDir, silent: true });\n\n // 3. Customize apps/server/package.json\n const serverPackagePath = path.join(serverDir, 'package.json');\n const serverPackageRaw = await fsPromises.readFile(serverPackagePath, 'utf8');\n const serverPkg = JSON.parse(serverPackageRaw);\n\n // Check if modular ESLint package exists in workspace packages\n const eslintDir = path.join(projectPath, 'packages', 'eslint');\n let hasEslint = false;\n try {\n await fsPromises.access(eslintDir);\n hasEslint = true;\n } catch {}\n\n serverPkg.name = 'server';\n serverPkg.version = '1.0.0';\n serverPkg.private = true;\n serverPkg.type = 'module';\n serverPkg.main = 'dist/index.js';\n serverPkg.scripts = {\n dev: 'tsx watch src/index.ts',\n build: 'tsc',\n start: 'node dist/index.js',\n };\n serverPkg.devDependencies = {\n '@config/typescript': 'workspace:*',\n };\n\n if (hasEslint) {\n serverPkg.devDependencies['@config/eslint'] = 'workspace:*';\n serverPkg.scripts['lint'] = 'eslint .';\n }\n\n // Remove defaults that are not needed\n delete serverPkg.keywords;\n delete serverPkg.author;\n delete serverPkg.license;\n\n await fsPromises.writeFile(\n serverPackagePath,\n JSON.stringify(serverPkg, null, 2),\n 'utf8',\n );\n\n // 4. Create tsconfig.json extending the base shared config\n const tsconfigContent = {\n extends: '@config/typescript/tsconfig.json',\n compilerOptions: {\n rootDir: 'src',\n outDir: 'dist',\n },\n include: ['src/**/*'],\n };\n\n await fsPromises.writeFile(\n path.join(serverDir, 'tsconfig.json'),\n JSON.stringify(tsconfigContent, null, 2),\n 'utf8',\n );\n\n // If ESLint exists, write the server's eslint.config.ts extending the base config\n if (hasEslint) {\n const eslintConfigContent = [\n \"import baseConfig from '@config/eslint';\",\n '',\n 'export default [',\n ' ...baseConfig,',\n ' {',\n ' // Add server-specific overrides if necessary',\n ' },',\n '];',\n '',\n ].join('\\n');\n\n await fsPromises.writeFile(\n path.join(serverDir, 'eslint.config.ts'),\n eslintConfigContent,\n 'utf8',\n );\n }\n\n // 5. Install dependencies dynamically using pnpm add (fetches latest)\n await runCommand('pnpm add express cors', { cwd: serverDir, silent: false });\n await runCommand('pnpm add -D @types/express @types/cors tsx typescript', {\n cwd: serverDir,\n silent: false,\n });\n\n // 6. Create src/index.ts with premium starter code using CORS and Express\n const indexTsContent = [\n \"import express from 'express';\",\n \"import cors from 'cors';\",\n '',\n 'const app = express();',\n 'const port = process.env.PORT || 3001;',\n '',\n '// Enable CORS and parsing of JSON request bodies',\n 'app.use(cors());',\n 'app.use(express.json());',\n '',\n '// Root API health and welcome route',\n \"app.get('/api', (req, res) => {\",\n ' res.json({',\n \" message: 'Welcome to the Morax High-Performance Backend API!',\",\n ' timestamp: new Date().toISOString(),',\n \" status: 'healthy',\",\n ' });',\n '});',\n '',\n 'app.listen(port, () => {',\n ' console.log(`š Server is running on http://localhost:${port}`);',\n '});',\n '',\n ].join('\\n');\n\n await fsPromises.writeFile(\n path.join(srcDir, 'index.ts'),\n indexTsContent,\n 'utf8',\n );\n}\n\nexport async function runServerSetup(projectPath: string) {\n // Ensure the apps folder option was generated/exists\n const appsDir = path.join(projectPath, 'apps');\n try {\n await fsPromises.access(appsDir);\n } catch {\n // If the apps folder was not scaffolded, we shouldn't attempt to setup Server there\n return;\n }\n\n const serverPrompt = await promptServer();\n\n handleCancel(serverPrompt);\n\n if (serverPrompt) {\n const s = spinner();\n console.log('\\n');\n s.start('Setting up modular Express backend in apps/server...');\n try {\n await setupServer(projectPath);\n s.stop(\n pc.green(\n 'ā Success: Modular Express backend configured in apps/server',\n ),\n );\n } catch (error: any) {\n s.stop(pc.red('ā Failed: Express backend setup failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n }\n}\n","import { confirm, spinner } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function promptGit() {\n return await confirm({\n message: 'Do you want to initialize a local Git repository?',\n initialValue: true,\n });\n}\n\nexport async function gitInit(projectPath: string) {\n // 1. Initialize empty git repository\n await runCommand('git init', { cwd: projectPath, silent: true });\n\n // 2. Create high-quality standard .gitignore\n const gitignore = [\n '# Dependency directories',\n 'node_modules/',\n 'jspm_packages/',\n 'web_modules/',\n '',\n '# Build and output outputs',\n 'dist/',\n 'build/',\n '.next/',\n 'out/',\n '.turbo/',\n '',\n '# Environments',\n '.env',\n '.env.local',\n '.env.development.local',\n '.env.test.local',\n '.env.production.local',\n '',\n '# Logs',\n 'npm-debug.log*',\n 'yarn-debug.log*',\n 'yarn-error.log*',\n 'pnpm-debug.log*',\n '*.log',\n '',\n '# OS Metadata',\n '.DS_Store',\n 'Thumbs.db',\n '',\n ].join('\\n');\n\n await fsPromises.writeFile(\n path.join(projectPath, '.gitignore'),\n gitignore,\n 'utf8',\n );\n}\n\nexport async function runGitSetup(projectPath: string): Promise<boolean> {\n const gitPrompt = await promptGit();\n\n handleCancel(gitPrompt);\n\n let gitInitialized = false;\n if (gitPrompt) {\n const s = spinner();\n console.log('\\n');\n s.start('Initializing Git repository...');\n try {\n await gitInit(projectPath);\n s.stop(pc.green('ā Success: Git repository initialized'));\n gitInitialized = true;\n } catch (error: any) {\n s.stop(pc.red('ā Failed: Git initialization failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n }\n return gitInitialized;\n}\n","import { confirm, spinner } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { runCommand } from '../utils/exec.js';\n\nexport async function promptHusky() {\n return await confirm({\n message: 'Do you want to setup Husky pre-commit hooks?',\n initialValue: true,\n });\n}\n\nexport async function setupHusky(projectPath: string) {\n // 1. Install Husky dynamically with exact version at the workspace root\n await runCommand('pnpm add -D -E husky -w', { cwd: projectPath });\n\n // 2. Initialize Husky using its official init generator\n await runCommand('pnpm exec husky init', { cwd: projectPath });\n\n // 3. Update the auto-generated .husky/pre-commit file to run format and stage files\n const preCommitPath = path.join(projectPath, '.husky', 'pre-commit');\n let hookContent = '';\n try {\n hookContent = await fsPromises.readFile(preCommitPath, 'utf8');\n } catch {\n hookContent = 'pnpm test'; // Default fallback\n }\n\n // Replace default test commands with formatting checks\n hookContent = hookContent.replace('pnpm test', 'pnpm format');\n\n // Append staging of newly formatted files\n if (!hookContent.includes('git add .')) {\n hookContent = hookContent.trim() + '\\ngit add .\\n';\n }\n\n await fsPromises.writeFile(preCommitPath, hookContent, 'utf8');\n\n try {\n await fsPromises.chmod(preCommitPath, 0o755);\n } catch {}\n}\n\nexport async function runHuskySetup(\n projectPath: string,\n gitInitialized: boolean,\n) {\n if (!gitInitialized) return;\n\n const huskyPrompt = await promptHusky();\n\n handleCancel(huskyPrompt);\n\n if (huskyPrompt) {\n const s = spinner();\n console.log('\\n');\n s.start('Setting up Husky hooks...');\n try {\n await setupHusky(projectPath);\n s.stop(pc.green('ā Success: Husky pre-commit hooks configured'));\n } catch (error: any) {\n s.stop(pc.red('ā Failed: Husky setup failed'));\n console.error(pc.red(`\\nError details: ${error.message || error}`));\n process.exit(1);\n }\n console.log('\\n');\n }\n}\n","import pc from 'picocolors';\nimport { outro } from '@clack/prompts';\nimport boxen from 'boxen';\n\nexport function endCli(name: string, projectPath: string) {\n // Complete and show beautiful finish screen\n outro(pc.yellow('Morax scaffolding completed successfully!'));\n\n console.log(\n boxen(\n `ā” ${pc.bold('Workspace ready:')} ${pc.yellow(name)}\\n` +\n `Location: ${pc.cyan(projectPath)}\\n\\n` +\n `${pc.bold('To start developing:')}\\n` +\n ` 1. ${pc.cyan(`cd ${name}`)}\\n` +\n ` 2. ${pc.cyan('pnpm dev')}\\n\\n` +\n `š” Code formatting & git orchestration is fully active.`,\n {\n padding: 0,\n margin: 0,\n borderStyle: 'round',\n borderColor: 'yellow',\n title: pc.black(pc.bold(' Setup Complete ')),\n titleAlignment: 'center',\n },\n ),\n );\n}\n","import fsPromises from 'fs/promises';\nimport path from 'path';\n\nexport async function setupReadme(projectPath: string, workspaceName: string) {\n const readmePath = path.join(projectPath, 'README.md');\n\n const readmeContent = [\n `# Morax `,\n '',\n 'Welcome to your next-generation, high-performance monorepo workspace generated by **Morax**.',\n '',\n '## Workspace Structure',\n '',\n '- **`apps/`** ā Frontend applications, backend servers, and user-facing services.',\n '- **`packages/`** ā Shared modules, TypeScript configurations, ESLint rule sets, and common utility libraries.',\n '',\n '## Key Commands',\n '',\n 'Run the following commands from the root directory of your workspace:',\n '',\n '### Development',\n 'Start all dev servers and hot-reloading configurations concurrently:',\n '```bash',\n 'pnpm dev',\n '```',\n '',\n '### Linting',\n 'Run static analysis across all workspaces using your shared ESLint rules:',\n '```bash',\n 'pnpm lint',\n '```',\n '',\n '### Formatting',\n 'Automatically format all codebase files using Prettier:',\n '```bash',\n 'pnpm format',\n '```',\n '',\n '---',\n '',\n '*Generated with love by [Morax Scaffolder CLI](https://github.com/Elitedv/morax).*',\n '',\n ].join('\\n');\n\n await fsPromises.writeFile(readmePath, readmeContent, 'utf8');\n}\n","import { select } from \"@clack/prompts\";\r\nimport handleCancel from \"../utils/isCancel.js\";\r\nimport { runShadcnSetup } from \"../tasks/shadcn.js\";\r\nimport { setupNextjs } from \"../tasks/nextjs.js\";\r\nimport { setupReact } from \"../tasks/react.js\";\r\n\r\nexport default async function addweb(projectPath: string) {\r\n const framework = await select({\r\n message: 'Which frontend website setup would you like to include in apps/web?',\r\n options: [\r\n { value: 'nextjs', label: 'Next.js', hint: 'The React Framework for the Web' },\r\n { value: 'react', label: 'React (Vite)', hint: 'Vite React Starter Template' },\r\n { value: 'skip', label: 'Skip', hint: 'Skip setting up a frontend website' },\r\n ],\r\n initialValue: 'nextjs',\r\n });\r\n\r\n handleCancel(framework);\r\n\r\n if (framework === 'nextjs') {\r\n await setupNextjs(projectPath);\r\n // Prompt and execute shadcn UI setup in next.js app\r\n await runShadcnSetup(projectPath);\r\n } else if (framework === 'react') {\r\n await setupReact(projectPath);\r\n }\r\n}","import { confirm } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { spawn } from 'child_process';\n\nexport async function promptShadcn() {\n return await confirm({\n message: 'Do you want to setup shadcn UI in your Next.js website (apps/web)?',\n initialValue: true,\n });\n}\n\nfunction runInteractiveCommand(\n command: string,\n args: string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: 'inherit',\n shell: true,\n env: { ...process.env, NODE_NO_WARNINGS: '1' },\n });\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`Command \"${command} ${args.join(' ')}\" exited with code ${code}`));\n }\n });\n\n child.on('error', (err) => {\n reject(err);\n });\n });\n}\n\nexport async function setupShadcn(projectPath: string) {\n const webDir = path.join(projectPath, 'apps', 'web');\n\n // Run pnpm dlx shadcn@latest init --template next interactively!\n console.log(pc.cyan('\\nStarting interactive shadcn UI initialization...'));\n await runInteractiveCommand('pnpm', ['dlx', 'shadcn@latest', 'init', '--template', 'next'], webDir);\n}\n\nexport async function runShadcnSetup(projectPath: string) {\n // Ensure the apps/web Next.js frontend actually exists\n const webDir = path.join(projectPath, 'apps', 'web');\n try {\n await fsPromises.access(webDir);\n } catch {\n // Next.js app was not generated, skip shadcn setup\n return;\n }\n\n const shadcnPrompt = await promptShadcn();\n\n handleCancel(shadcnPrompt);\n\n if (shadcnPrompt) {\n try {\n await setupShadcn(projectPath);\n console.log(pc.green('\\nā Success: shadcn UI successfully initialized in apps/web\\n'));\n } catch (error: any) {\n console.error(pc.red(`\\nā Failed: shadcn UI setup failed`));\n console.error(pc.red(`Error details: ${error.message || error}\\n`));\n process.exit(1);\n }\n }\n}\n","import { confirm } from '@clack/prompts';\nimport pc from 'picocolors';\nimport handleCancel from '../utils/isCancel.js';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { spawn } from 'child_process';\n\nexport async function promptNextjs() {\n return await confirm({\n message: 'Do you want to setup a Next.js frontend in apps/web?',\n initialValue: true,\n });\n}\n\nfunction runInteractiveCommand(\n command: string,\n args: string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: 'inherit',\n shell: true,\n env: { ...process.env, NODE_NO_WARNINGS: '1' },\n });\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(\n new Error(\n `Command \"${command} ${args.join(' ')}\" exited with code ${code}`,\n ),\n );\n }\n });\n\n child.on('error', (err) => {\n reject(err);\n });\n });\n}\n\nexport async function setupNextjs(projectPath: string) {\n const appsDir = path.join(projectPath, 'apps');\n const webDir = path.join(appsDir, 'web');\n\n // 1. Delete the existing apps/web directory if it contains placeholder files (.gitkeep)\n try {\n await fsPromises.rm(webDir, { recursive: true, force: true });\n } catch { }\n\n // 2. Run npx create-next-app@latest interactively!\n console.log(pc.cyan('\\nStarting interactive Next.js application setup...'));\n await runInteractiveCommand(\n 'npx',\n ['create-next-app@latest', 'web'],\n appsDir,\n );\n}\n\nexport async function runNextjsSetup(projectPath: string) {\n // Ensure the apps folder option was generated/exists\n const appsDir = path.join(projectPath, 'apps');\n try {\n await fsPromises.access(appsDir);\n } catch {\n // If the apps folder was not scaffolded, we shouldn't attempt to setup Web there\n return;\n }\n\n const webPrompt = await promptNextjs();\n\n handleCancel(webPrompt);\n\n if (webPrompt) {\n try {\n await setupNextjs(projectPath);\n console.log(\n pc.green('\\nā Success: Next.js frontend configured in apps/web\\n'),\n );\n } catch (error: any) {\n console.error(pc.red(`\\nā Failed: Next.js frontend setup failed`));\n console.error(pc.red(`Error details: ${error.message || error}\\n`));\n process.exit(1);\n }\n }\n}\n","import pc from 'picocolors';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport { spawn } from 'child_process';\nimport { confirm, spinner, text } from '@clack/prompts';\nimport handleCancel from '../utils/isCancel.js';\nimport { runCommand } from '../utils/exec.js';\n\nfunction runInteractiveCommand(\n command: string,\n args: string[],\n cwd: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: 'inherit',\n shell: true,\n env: { ...process.env, NODE_NO_WARNINGS: '1' },\n });\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(\n new Error(\n `Command \"${command} ${args.join(' ')}\" exited with code ${code}`,\n ),\n );\n }\n });\n\n child.on('error', (err) => {\n reject(err);\n });\n });\n}\n\nexport async function setupReact(projectPath: string) {\n const appsDir = path.join(projectPath, 'apps');\n\n // 1. Print important warnings to prevent blocking\n console.log(pc.magentaBright('\\nš· IMPORTANT INSTRUCTIONS:'));\n console.log(pc.magentaBright('During the Vite interactive configuration prompts, please select:'));\n console.log(pc.magentaBright(` 1. Install & Start: Choose ${pc.bold('No')} when asked \"Install with npm/pnpm and start now?\"`));\n console.log(pc.magentaBright('This allows Morax CLI to continue automatically configuring your workspace (ESLint, Prettier, Tailwind, packages, etc.)!'));\n\n // 2. Run pnpm create vite@latest interactively!\n console.log(pc.cyan('\\nStarting interactive Vite React application setup...'));\n\n // Get list of directories in appsDir before running Vite to auto-detect the chosen project name\n let beforeDirs: string[] = [];\n try {\n beforeDirs = await fsPromises.readdir(appsDir);\n } catch { }\n\n try {\n await runInteractiveCommand(\n 'pnpm',\n ['create', 'vite@latest'],\n appsDir,\n );\n\n // Get list of directories in appsDir after running Vite\n let afterDirs: string[] = [];\n try {\n afterDirs = await fsPromises.readdir(appsDir);\n } catch { }\n\n // Find the newly created folder\n const newDirs = afterDirs.filter((d) => !beforeDirs.includes(d));\n let createdDirName = 'web'; // fallback\n if (newDirs.length > 0) {\n createdDirName = newDirs[0];\n }\n const webDir = path.join(appsDir, createdDirName);\n\n // Verify directory exists\n try {\n await fsPromises.access(webDir);\n } catch {\n throw new Error(`Vite React application directory \"apps/${createdDirName}\" was not found. Please ensure you complete the Vite installation.`);\n }\n\n console.log(\n pc.green(`\\nā Success: Vite React frontend configured in apps/${createdDirName}\\n`),\n );\n\n // 3. Prompt for Tailwind CSS v4 and shadcn UI setup\n const setupTailwindPrompt = await confirm({\n message: 'Do you want to install and configure Tailwind CSS v4?',\n initialValue: true,\n });\n handleCancel(setupTailwindPrompt);\n\n const setupShadcnPrompt = await confirm({\n message: `Do you want to setup shadcn UI in your Vite React website (apps/${createdDirName})?`,\n initialValue: true,\n });\n handleCancel(setupShadcnPrompt);\n\n // Determine if Tailwind needs to be installed (shadcn UI requires Tailwind)\n const needsTailwind = setupTailwindPrompt || setupShadcnPrompt;\n\n if (needsTailwind) {\n const s = spinner();\n s.start('Installing Tailwind CSS v4, Vite integration, and Node types...');\n try {\n // 4. Inject dependencies directly into package.json\n const pkgPath = path.join(webDir, 'package.json');\n try {\n const pkgRaw = await fsPromises.readFile(pkgPath, 'utf8');\n const pkg = JSON.parse(pkgRaw);\n pkg.dependencies = pkg.dependencies || {};\n pkg.devDependencies = pkg.devDependencies || {};\n\n pkg.dependencies['tailwindcss'] = '^4.0.0';\n pkg.devDependencies['@tailwindcss/vite'] = '^4.0.0';\n pkg.devDependencies['@types/node'] = '^20.11.0';\n\n await fsPromises.writeFile(pkgPath, JSON.stringify(pkg, null, 2), 'utf8');\n } catch { }\n\n // Install packages via pnpm install\n await runCommand('pnpm install', { cwd: webDir, silent: true });\n\n s.message('Configuring Vite plugins and Tailwind CSS imports...');\n\n // 5. Configure the Vite plugin in vite.config.ts\n const viteConfigPath = path.join(webDir, 'vite.config.ts');\n try {\n let content = await fsPromises.readFile(viteConfigPath, 'utf8');\n if (!content.includes('@tailwindcss/vite')) {\n content = \"import tailwindcss from '@tailwindcss/vite';\\n\" + content;\n\n if (content.includes('plugins: [react()]')) {\n content = content.replace('plugins: [react()]', 'plugins: [react(), tailwindcss()]');\n } else if (content.includes('plugins: [react(),]')) {\n content = content.replace('plugins: [react(),]', 'plugins: [react(), tailwindcss()]');\n } else {\n // Use regex for multi-line or standard spacing\n content = content.replace(/(plugins:\\s*\\[\\s*react\\(\\),?\\s*)(\\])/g, '$1\\n tailwindcss(),\\n $2');\n }\n await fsPromises.writeFile(viteConfigPath, content, 'utf8');\n }\n } catch { }\n\n // 6. Overwrite src/index.css to import Tailwind CSS v4\n const indexCssPath = path.join(webDir, 'src', 'index.css');\n try {\n await fsPromises.writeFile(indexCssPath, '@import \"tailwindcss\";\\n', 'utf8');\n } catch { }\n\n s.stop(pc.green('ā Success: Tailwind CSS v4 configured successfully\\n'));\n } catch (err: any) {\n s.stop(pc.red('ā Failed: Tailwind CSS v4 setup failed'));\n throw err;\n }\n }\n\n if (setupShadcnPrompt) {\n // 7. Configure Path Aliases inside tsconfig / vite configs first as required by shadcn UI preflight\n const s = spinner();\n s.start('Configuring path aliases for shadcn UI preflight checks...');\n try {\n // tsconfig.json / tsconfig.app.json\n const tsconfigPaths = [\n path.join(webDir, 'tsconfig.json'),\n path.join(webDir, 'tsconfig.app.json'),\n ];\n for (const tsPath of tsconfigPaths) {\n try {\n let content = await fsPromises.readFile(tsPath, 'utf8');\n if (content.includes('\"compilerOptions\"')) {\n if (!content.includes('\"paths\"')) {\n content = content.replace(\n /(\"compilerOptions\"\\s*:\\s*\\{)/,\n `$1\\n \"baseUrl\": \".\",\\n \"paths\": {\\n \"@/*\": [\"./src/*\"]\\n },`\n );\n await fsPromises.writeFile(tsPath, content, 'utf8');\n }\n } else {\n content = content.replace(\n /^(\\s*\\{)/,\n `$1\\n \"compilerOptions\": {\\n \"baseUrl\": \".\",\\n \"paths\": {\\n \"@/*\": [\"./src/*\"]\\n }\\n },`\n );\n await fsPromises.writeFile(tsPath, content, 'utf8');\n }\n } catch { }\n }\n\n // vite.config.ts\n const viteConfigPath = path.join(webDir, 'vite.config.ts');\n try {\n let content = await fsPromises.readFile(viteConfigPath, 'utf8');\n if (!content.includes(\"import path from 'path'\")) {\n content = \"import path from 'path';\\n\" + content;\n }\n if (!content.includes('resolve:')) {\n content = content.replace(\n /(plugins:\\s*\\[[^\\]]*\\]),?/,\n `$1,\\n resolve: {\\n alias: {\\n \"@\": path.resolve(__dirname, \"./src\"),\\n },\\n }`\n );\n }\n await fsPromises.writeFile(viteConfigPath, content, 'utf8');\n } catch { }\n\n s.stop(pc.green('ā Success: Path aliases successfully configured\\n'));\n } catch (err: any) {\n s.stop(pc.red('ā Failed: Path alias configuration failed'));\n throw err;\n }\n\n // 8. Prompt for preset and initialize shadcn UI\n const hasPreset = await confirm({\n message: 'Do you have a custom shadcn UI preset code?',\n initialValue: false,\n });\n handleCancel(hasPreset);\n\n let presetCode = '';\n if (hasPreset) {\n const enteredPreset = await text({\n message: 'Enter your custom shadcn UI preset code:',\n placeholder: 'e.g. 123456',\n validate: (val) => {\n if (!val || !val.trim()) return 'Preset code cannot be empty';\n return;\n }\n });\n handleCancel(enteredPreset);\n presetCode = (enteredPreset as string).trim();\n }\n\n const args = ['dlx', 'shadcn@latest', 'init'];\n if (presetCode) {\n args.push('--preset', presetCode);\n }\n args.push('--template', 'vite');\n\n console.log(pc.cyan('\\nStarting interactive shadcn UI initialization...'));\n await runInteractiveCommand('pnpm', args, webDir);\n console.log(\n pc.green(`\\nā Success: shadcn UI successfully initialized in apps/${createdDirName}\\n`),\n );\n }\n\n } catch (error: any) {\n console.error(pc.red(`\\nā Failed: Vite React frontend setup failed`));\n console.error(pc.red(`Error details: ${error.message || error}\\n`));\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["pc","path","spinner","pc","pc","fsPromises","path","pc","pc","path","fsPromises","pc","spinner","pc","fsPromises","path","fsPromises","path","spinner","pc","confirm","spinner","pc","fsPromises","path","confirm","path","fsPromises","spinner","pc","confirm","spinner","pc","fsPromises","path","confirm","path","fsPromises","spinner","pc","confirm","spinner","pc","fsPromises","path","confirm","path","fsPromises","spinner","pc","confirm","spinner","pc","fsPromises","path","confirm","fsPromises","path","spinner","pc","confirm","spinner","pc","fsPromises","path","confirm","path","fsPromises","spinner","pc","pc","boxen","fsPromises","path","confirm","pc","fsPromises","path","confirm","pc","confirm","pc","fsPromises","path","spawn","runInteractiveCommand","spawn","path","fsPromises","pc","pc","fsPromises","path","spawn","confirm","spinner","text","runInteractiveCommand","spawn","path","pc","fsPromises","confirm","spinner","text","path","spinner","pc","pc"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-morax",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Ashutosh",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"dev": "npx tsx src/index.ts",
|
|
22
22
|
"build": "tsup",
|
|
23
23
|
"start": "node dist/index.js",
|
|
24
|
+
"pub": "npm publish",
|
|
24
25
|
"prepublishOnly": "node -e \"const fs = require('fs'); fs.renameSync('README.md', 'README.github.md'); fs.renameSync('README.npm.md', 'README.md')\"",
|
|
25
26
|
"postpublish": "node -e \"const fs = require('fs'); fs.renameSync('README.md', 'README.npm.md'); fs.renameSync('README.github.md', 'README.md')\""
|
|
26
27
|
},
|