@codefast/cli 0.3.1-canary.10 → 0.3.1-canary.12

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 CHANGED
@@ -25,9 +25,38 @@ function runCommand(command) {
25
25
  stdio: "inherit"
26
26
  });
27
27
  }
28
- function writeConfigFile(filePath, content) {
29
- __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(filePath, content);
30
- console.log(`šŸ“ Created ${filePath}`);
28
+ const FileUtils = {
29
+ exists (filePath) {
30
+ return __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(filePath);
31
+ },
32
+ readFile (filePath) {
33
+ try {
34
+ return __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(filePath, "utf8");
35
+ } catch (error) {
36
+ throw new Error(`Failed to read file ${filePath}: ${getErrorMessage(error)}`);
37
+ }
38
+ },
39
+ writeFile (filePath, content) {
40
+ try {
41
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(filePath, content);
42
+ } catch (error) {
43
+ throw new Error(`Failed to write to file ${filePath}: ${getErrorMessage(error)}`);
44
+ }
45
+ },
46
+ writeConfigFile (filePath, content) {
47
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(filePath, content);
48
+ console.log(`šŸ“ Created ${filePath}`);
49
+ },
50
+ validatePath (filePath, filename) {
51
+ if (!this.exists(filePath)) {
52
+ console.warn(`āš ļø ${filename} not found, skipping update.`);
53
+ return false;
54
+ }
55
+ return true;
56
+ }
57
+ };
58
+ function getErrorMessage(error) {
59
+ return error instanceof Error ? error.message : "Unknown error occurred";
31
60
  }
32
61
  function validateProjectName(name) {
33
62
  if (!name || /^\s*$/.test(name)) return {
@@ -250,6 +279,24 @@ indent_style = tab
250
279
  indent_size = 4
251
280
  `,
252
281
  description: "Editor configuration for source code formatting"
282
+ },
283
+ {
284
+ path: ".prettierignore",
285
+ content: `# changesets
286
+ .changeset
287
+
288
+ # debug
289
+ npm-debug.log*
290
+ yarn-debug.log*
291
+ yarn-error.log*
292
+ .pnpm-debug.log*
293
+
294
+ # lock files
295
+ package-lock.json
296
+ yarn.lock
297
+ pnpm-lock.yaml
298
+ `,
299
+ description: ""
253
300
  }
254
301
  ],
255
302
  linting: [
@@ -273,6 +320,7 @@ export default config;
273
320
  {
274
321
  path: "eslint.config.mjs",
275
322
  content: `import { config } from "@codefast/eslint-config/next";
323
+
276
324
  /**
277
325
  * @see https://eslint.org/docs/latest/use/configure/configuration-files
278
326
  * @type {import('eslint').Linter.Config[]}
@@ -347,6 +395,7 @@ export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
347
395
  :root {
348
396
  --font-sans: var(--font-geist-sans);
349
397
  --font-mono: var(--font-geist-mono);
398
+
350
399
  --input: var(--color-neutral-200);
351
400
  --border: var(--color-neutral-200);
352
401
  --ring: var(--color-neutral-400);
@@ -380,6 +429,7 @@ export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
380
429
  --chart-4: var(--color-amber-600);
381
430
  --chart-5: var(--color-amber-500);
382
431
  }
432
+
383
433
  .dark {
384
434
  --input: var(--color-neutral-700);
385
435
  --border: --alpha(var(--color-neutral-700) / 50%);
@@ -420,68 +470,86 @@ export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
420
470
  }
421
471
  ]
422
472
  };
473
+ function updateFileIfNeeded(filePath, filename, checkFn, updateFn, successMessage, alreadyUpdatedMessage) {
474
+ if (!FileUtils.validatePath(filePath, filename)) return;
475
+ const content = FileUtils.readFile(filePath);
476
+ if (checkFn(content)) return void console.log(`šŸ“ ${alreadyUpdatedMessage}`);
477
+ try {
478
+ const updatedContent = updateFn(content);
479
+ FileUtils.writeFile(filePath, updatedContent);
480
+ console.log(`šŸ“ ${successMessage}`);
481
+ } catch (error) {
482
+ console.warn(`āš ļø Failed to update ${filename}: ${getErrorMessage(error)}`);
483
+ }
484
+ }
423
485
  function updatePostcssConfig(projectDir) {
424
486
  const postcssConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "postcss.config.mjs");
425
- if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(postcssConfigPath)) return void console.warn(`āš ļø postcss.config.mjs not found, skipping update.`);
426
- let content = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(postcssConfigPath, "utf8");
427
487
  const typeComment = `/** @type {import('postcss-load-config').Config} */\n`;
428
- if (content.includes(typeComment)) console.log(`šŸ“ postcss.config.mjs already contains type comment, no changes made.`);
429
- else {
430
- content = content.replace("const config = {", `${typeComment}const config = {`);
431
- __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(postcssConfigPath, content);
432
- console.log(`šŸ“ Updated postcss.config.mjs with type comment.`);
433
- }
488
+ updateFileIfNeeded(postcssConfigPath, "postcss.config.mjs", (content)=>content.includes(typeComment), (content)=>content.replace("const config = {", `${typeComment}const config = {`), "Updated postcss.config.mjs with type comment.", "postcss.config.mjs already contains type comment, no changes made.");
434
489
  }
435
490
  function updateLayoutFile(projectDir) {
436
491
  const layoutPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "src/app/layout.tsx");
437
- if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(layoutPath)) return void console.warn(`āš ļø src/app/layout.tsx not found, skipping update.`);
438
- let content = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(layoutPath, "utf8");
439
- if (content.includes('<html className={cn(fontVariables, "antialiased")} lang="en">')) return void console.log(`šŸ“ src/app/layout.tsx already uses fontVariables in html tag, no changes made.`);
440
- const newImports = `import type { Metadata } from "next";
441
-
492
+ const htmlTarget = '<html className={cn(fontVariables, "antialiased")} lang="en">';
493
+ updateFileIfNeeded(layoutPath, "src/app/layout.tsx", (content)=>content.includes(htmlTarget), (content)=>{
494
+ const newImports = `import type { Metadata } from "next";
495
+ import type { JSX, ReactNode } from "react";
442
496
  import { cn } from "@codefast/ui";
443
-
444
497
  import { fontVariables } from "@/lib/fonts";
445
498
  import "@/app/globals.css";`;
446
- content = content.replaceAll(/import\s+{[^}]+}\s+from\s+["']next\/font\/google["'];\s*/g, "");
447
- content = content.replace(/const\s+geistSans\s*=[^;]+;\s*const\s+geistMono\s*=[^;]+;\s*/, "");
448
- content = content.replace(/import\s+type\s+{[^}]+}\s+from\s+["']next["'];\s*import\s+["']\.\/globals\.css["'];\s*/, newImports);
449
- const htmlRegex = /<html\s+lang="en"\s*>/;
450
- const newHtml = '<html className={cn(fontVariables, "antialiased")} lang="en">';
451
- content = content.replace(htmlRegex, newHtml);
452
- const bodyRegex = /<body\s+className={`[^`]*`}\s*>/;
453
- const newBody = "<body>";
454
- content = content.replace(bodyRegex, newBody);
499
+ let result = content;
500
+ result = result.replaceAll(/import\s+{[^}]+}\s+from\s+["']next\/font\/google["'];\s*/g, "");
501
+ result = result.replace(/const\s+geistSans\s*=[^;]+;\s*const\s+geistMono\s*=[^;]+;\s*/, "");
502
+ result = result.replace(/import\s+type\s+{[^}]+}\s+from\s+["']next["'];\s*import\s+["']\.\/globals\.css["'];\s*/, newImports);
503
+ result = result.replace(/export default function RootLayout\({\s*children,\s*}\s*:\s*Readonly<{\s*children:\s*React\.ReactNode;\s*}>\)\s*{/, "export default function RootLayout({ children }: Readonly<{ children: ReactNode }>): JSX.Element {");
504
+ result = result.replace(/<html\s+lang="en"\s*>/, htmlTarget);
505
+ result = result.replace(/<body\s+className={`[^`]*`}\s*>/, "<body>");
506
+ return result;
507
+ }, "Updated src/app/layout.tsx to use fontVariables in html tag, removed className from body, modified ReactNode import, and added return type to RootLayout", "src/app/layout.tsx already uses fontVariables in html tag, no changes made.");
508
+ }
509
+ function updatePackageJson(projectDir) {
510
+ const packageJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "package.json");
511
+ if (!FileUtils.validatePath(packageJsonPath, "package.json")) return;
455
512
  try {
456
- __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(layoutPath, content);
457
- console.log(`šŸ“ Updated src/app/layout.tsx to use fontVariables in html tag and removed className from body`);
513
+ const packageJson = JSON.parse(FileUtils.readFile(packageJsonPath));
514
+ packageJson.scripts = {
515
+ ...packageJson.scripts,
516
+ "deploy:preview": "vercel deploy --archive=tgz",
517
+ "deploy:prod": "vercel deploy --archive=tgz --prod",
518
+ format: "prettier --write --ignore-unknown .",
519
+ "format:check": "prettier --check --ignore-unknown .",
520
+ lint: "next lint --fix --max-warnings 0",
521
+ "lint:check": "next lint --max-warnings 0",
522
+ "package:install": "pnpm install",
523
+ "package:outdated": "pnpm outdated",
524
+ "package:upgrade": "pnpm update --latest",
525
+ preview: "pnpm build && pnpm start"
526
+ };
527
+ packageJson["simple-git-hooks"] = {
528
+ "pre-commit": "pnpm lint-staged",
529
+ "commit-msg": "pnpm commitlint --edit"
530
+ };
531
+ FileUtils.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
532
+ console.log(`šŸ“ Updated package.json`);
458
533
  } catch (error) {
459
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
460
- console.warn(`āš ļø Failed to update src/app/layout.tsx: ${errorMessage}`);
534
+ console.warn(`āš ļø Failed to update package.json: ${getErrorMessage(error)}`);
461
535
  }
462
536
  }
463
- function updatePackageJson(projectDir) {
464
- const packageJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "package.json");
465
- const packageJson = JSON.parse(__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(packageJsonPath, "utf8"));
466
- packageJson.scripts = {
467
- ...packageJson.scripts,
468
- "deploy:preview": "vercel deploy --archive=tgz",
469
- "deploy:prod": "vercel deploy --archive=tgz --prod",
470
- format: "prettier --write --ignore-unknown",
471
- "format:check": "prettier --check --ignore-unknown",
472
- lint: "next lint --fix --max-warnings 0",
473
- "lint:check": "next lint --max-warnings 0",
474
- "package:install": "pnpm install",
475
- "package:outdated": "pnpm outdated",
476
- "package:upgrade": "pnpm update --latest",
477
- preview: "pnpm build && pnpm start"
478
- };
479
- packageJson["simple-git-hooks"] = {
480
- "pre-commit": "pnpm lint-staged",
481
- "commit-msg": "pnpm commitlint --edit"
482
- };
483
- __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
484
- console.log(`šŸ“ Updated package.json`);
537
+ function updateNextConfig(projectDir) {
538
+ const nextConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "next.config.ts");
539
+ const optimizePackagesConfig = 'optimizePackageImports: ["@codefast/ui"]';
540
+ updateFileIfNeeded(nextConfigPath, "next.config.ts", (content)=>content.includes(optimizePackagesConfig), (content)=>content.replace(/const nextConfig: NextConfig = \{/, `const nextConfig: NextConfig = {
541
+ experimental: {
542
+ optimizePackageImports: ["@codefast/ui"],
543
+ },`), "Updated next.config.ts with optimizePackageImports configuration.", "next.config.ts already contains optimizePackageImports configuration, no changes made.");
544
+ }
545
+ function updatePageFile(projectDir) {
546
+ const pagePath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "src/app/page.tsx");
547
+ updateFileIfNeeded(pagePath, "src/app/page.tsx", (content)=>content.includes("): JSX.Element"), (content)=>{
548
+ let result = content;
549
+ if (!result.includes("import type { JSX }")) result = result.includes("import type {") ? result.replace(/import type {(?<types>[^}]+)} from "react";/, 'import type {$1, JSX } from "react";') : result.includes("import {") ? result.replace(/import {/, 'import type { JSX } from "react";\n\nimport {') : `import type { JSX } from "react";\n\n${result}`;
550
+ result = result.replace(/export default function Home\(\) {/, "export default function Home(): JSX.Element {");
551
+ return result;
552
+ }, "Updated src/app/page.tsx to add JSX.Element return type to Home component", "src/app/page.tsx already has JSX.Element return type, no changes made.");
485
553
  }
486
554
  function createConfigFiles(projectDir) {
487
555
  console.log(`\nšŸ“ Creating configuration files...`);
@@ -490,10 +558,10 @@ function createConfigFiles(projectDir) {
490
558
  for (const { path: filePath, content, description } of configs){
491
559
  const fullPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, filePath);
492
560
  const dir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(fullPath);
493
- if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(dir)) __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].mkdirSync(dir, {
561
+ if (!FileUtils.exists(dir)) __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].mkdirSync(dir, {
494
562
  recursive: true
495
563
  });
496
- writeConfigFile(fullPath, content);
564
+ FileUtils.writeConfigFile(fullPath, content);
497
565
  if (description) console.log(` ā„¹ļø ${filePath}: ${description}`);
498
566
  }
499
567
  }
@@ -512,8 +580,7 @@ function cleanupPackages() {
512
580
  try {
513
581
  packageJson = JSON.parse(__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.readFileSync(packageJsonPath, "utf8"));
514
582
  } catch (error) {
515
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
516
- console.warn(`āš ļø Error reading package.json: ${errorMessage}, skipping cleanup.`);
583
+ console.warn(`āš ļø Error reading package.json: ${getErrorMessage(error)}, skipping cleanup.`);
517
584
  return;
518
585
  }
519
586
  const dependencies = packageJson.dependencies ?? {};
@@ -549,15 +616,19 @@ function createProjectCommand(program) {
549
616
  console.log(`šŸ“‚ Moved to ${projectName}`);
550
617
  }
551
618
  updateLayoutFile(process.cwd());
619
+ updatePageFile(process.cwd());
552
620
  updatePostcssConfig(process.cwd());
553
621
  installDependencies();
554
622
  cleanupPackages();
555
623
  createConfigFiles(process.cwd());
624
+ updateNextConfig(process.cwd());
556
625
  updatePackageJson(process.cwd());
557
626
  console.log(`\nšŸ”„ Activating git hooks...`);
558
627
  runCommand("pnpm simple-git-hooks");
559
628
  console.log(`\nšŸ“ Formatting files with Prettier...`);
560
629
  runCommand("pnpm format");
630
+ console.log(`\nšŸ” Running ESLint to check code style...`);
631
+ runCommand("pnpm lint");
561
632
  console.log(`\nāœ… Project ${packageJsonExists ? "configured" : "created"} successfully!`);
562
633
  console.log(`- Project: ${projectName}`);
563
634
  console.log("- Next.js with TypeScript");
@@ -568,8 +639,7 @@ function createProjectCommand(program) {
568
639
  console.log(`\nšŸš€ To start development:`);
569
640
  console.log(`cd ${projectName} && pnpm dev`);
570
641
  } catch (error) {
571
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
572
- console.error(`\nāŒ An error occurred: ${errorMessage}`);
642
+ console.error(`\nāŒ An error occurred: ${getErrorMessage(error)}`);
573
643
  process.exit(1);
574
644
  } finally{
575
645
  rl.close();
@@ -704,7 +774,7 @@ const EXPORTS_PREVIEW_FILE = "exports-preview.json";
704
774
  const EXPORTS_ANALYSIS_FILE = "exports-analysis.json";
705
775
  const ENCODING = "utf8";
706
776
  const JSON_INDENT = 2;
707
- const FileUtils = {
777
+ const file_utils_FileUtils = {
708
778
  exists (filePath) {
709
779
  return __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(filePath);
710
780
  },
@@ -742,19 +812,19 @@ const FileUtils = {
742
812
  }
743
813
  };
744
814
  function fileExists(filePath) {
745
- return FileUtils.exists(filePath);
815
+ return file_utils_FileUtils.exists(filePath);
746
816
  }
747
817
  function readPackageJson(filePath) {
748
- return FileUtils.readJsonFile(filePath);
818
+ return file_utils_FileUtils.readJsonFile(filePath);
749
819
  }
750
820
  function backupPackageJson(filePath) {
751
821
  try {
752
822
  const content = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(filePath, ENCODING);
753
823
  const dir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(filePath);
754
824
  const backupDir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(dir, EXPORTS_ANALYSIS_DIR);
755
- FileUtils.ensureDirectoryExists(backupDir);
825
+ file_utils_FileUtils.ensureDirectoryExists(backupDir);
756
826
  const baseName = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].basename(filePath);
757
- const backupPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(backupDir, FileUtils.createBackupFilename(baseName));
827
+ const backupPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(backupDir, file_utils_FileUtils.createBackupFilename(baseName));
758
828
  __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(backupPath, content, ENCODING);
759
829
  return true;
760
830
  } catch (error) {
@@ -763,11 +833,11 @@ function backupPackageJson(filePath) {
763
833
  }
764
834
  }
765
835
  function savePackageJson(filePath, content) {
766
- return FileUtils.writeJsonFile(filePath, content);
836
+ return file_utils_FileUtils.writeJsonFile(filePath, content);
767
837
  }
768
838
  function saveJsonToFile(packageDir, fileName, content) {
769
- const outputDir = FileUtils.getAnalysisDir(packageDir);
770
- FileUtils.writeJsonFile(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(outputDir, fileName), content);
839
+ const outputDir = file_utils_FileUtils.getAnalysisDir(packageDir);
840
+ file_utils_FileUtils.writeJsonFile(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(outputDir, fileName), content);
771
841
  }
772
842
  function saveExportsAnalysis(packageDir, analysis) {
773
843
  saveJsonToFile(packageDir, EXPORTS_ANALYSIS_FILE, analysis);
@@ -926,12 +996,6 @@ function main() {
926
996
  program.name("codefast").description("CodeFast CLI - A development toolkit for CodeFast.").version(getPackageVersion(), "-v, --version", "display CLI version");
927
997
  createUpdateExportsCommand(program);
928
998
  createProjectCommand(program);
929
- program.action(()=>{
930
- console.log('Use "codefast create-project" to create a new Next.js project.');
931
- console.log('Use "codefast update-exports" to update exports.');
932
- console.log('Run "codefast --help" to see all available commands.');
933
- program.help();
934
- });
935
999
  program.parse(process.argv);
936
1000
  }
937
1001
  main();