@codefast/cli 0.3.1-canary.4 โ†’ 0.3.1-canary.6

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
@@ -1,13 +1,455 @@
1
1
  #!/usr/bin/env node
2
2
  import * as __WEBPACK_EXTERNAL_MODULE_commander__ from "commander";
3
- import * as __WEBPACK_EXTERNAL_MODULE_glob__ from "glob";
3
+ import * as __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__ from "node:fs";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
5
+ import * as __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__ from "node:child_process";
6
+ import * as __WEBPACK_EXTERNAL_MODULE_node_readline_91c31510__ from "node:readline";
7
+ import * as __WEBPACK_EXTERNAL_MODULE_glob__ from "glob";
5
8
  import * as __WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__ from "ts-morph";
6
9
  import * as __WEBPACK_EXTERNAL_MODULE_lodash_es_18c59938__ from "lodash-es";
7
- import * as __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__ from "node:fs";
8
10
  import * as __WEBPACK_EXTERNAL_MODULE_zod__ from "zod";
9
- import * as __WEBPACK_EXTERNAL_MODULE_chalk__ from "chalk";
10
11
  import * as __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__ from "node:url";
12
+ const rl = __WEBPACK_EXTERNAL_MODULE_node_readline_91c31510__["default"].createInterface({
13
+ input: process.stdin,
14
+ output: process.stdout
15
+ });
16
+ function utils_prompt(question) {
17
+ return new Promise((resolve)=>{
18
+ rl.question(question, (answer)=>{
19
+ resolve(answer.trim());
20
+ });
21
+ });
22
+ }
23
+ function runCommand(command) {
24
+ (0, __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__.execSync)(command, {
25
+ stdio: "inherit"
26
+ });
27
+ }
28
+ function writeConfigFile(filePath, content) {
29
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(filePath, content);
30
+ console.log(`๐Ÿ“ Created ${filePath}`);
31
+ }
32
+ function validateProjectName(name) {
33
+ if (!name || /^\s*$/.test(name)) return {
34
+ valid: false,
35
+ error: "Project name cannot be empty or contain only whitespace."
36
+ };
37
+ if (name.length > 100) return {
38
+ valid: false,
39
+ error: "Project name is too long (maximum 100 characters)."
40
+ };
41
+ const npmNameRegex = /^[a-z0-9-~][a-z0-9-._~]*$/;
42
+ if (!npmNameRegex.test(name)) return {
43
+ valid: false,
44
+ error: "Project name must be URL-friendly (letters, numbers, hyphens, underscores, dots; no @ or scoped packages)."
45
+ };
46
+ if ("." === name || ".." === name) return {
47
+ valid: false,
48
+ error: "Project name cannot be '.' or '..'."
49
+ };
50
+ const reservedNames = /^(?<reserved>CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i;
51
+ if (reservedNames.test(name)) return {
52
+ valid: false,
53
+ error: `Project name "${name}" is a reserved system name.`
54
+ };
55
+ const fullPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].resolve(process.cwd(), name);
56
+ if (__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(fullPath)) return {
57
+ valid: false,
58
+ error: `A directory named "${name}" already exists.`
59
+ };
60
+ try {
61
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].accessSync(process.cwd(), __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].constants.W_OK);
62
+ } catch {
63
+ return {
64
+ valid: false,
65
+ error: "Cannot create project: No write permission in current directory."
66
+ };
67
+ }
68
+ return {
69
+ valid: true
70
+ };
71
+ }
72
+ async function getValidProjectName(initialName, attempts = 0, maxAttempts = 3) {
73
+ const projectName = initialName ?? await utils_prompt("Enter project name: ");
74
+ const validation = validateProjectName(projectName);
75
+ if (validation.valid) return projectName;
76
+ if (attempts >= maxAttempts - 1) throw new Error(`โŒ Exceeded maximum attempts to enter a valid project name.`);
77
+ console.error(`โŒ ${validation.error} (${maxAttempts - attempts - 1} attempts remaining)`);
78
+ return getValidProjectName(void 0, attempts + 1, maxAttempts);
79
+ }
80
+ async function checkExistingProject(projectNameArg) {
81
+ const packageJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(process.cwd(), "package.json");
82
+ const packageJsonExists = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(packageJsonPath);
83
+ if (packageJsonExists) {
84
+ console.log(`โš ๏ธ A package.json file has been detected in the current directory.`);
85
+ const confirm = await utils_prompt("Do you want to continue configuring this existing project? [Y/n]: ");
86
+ if ("" === confirm || "y" === confirm.toLowerCase()) {
87
+ const packageJson = JSON.parse(__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(packageJsonPath, "utf8"));
88
+ const projectName = packageJson.name ?? await getValidProjectName(projectNameArg);
89
+ return {
90
+ projectName,
91
+ packageJsonExists
92
+ };
93
+ }
94
+ console.log("Aborting...");
95
+ throw new Error("User aborted the operation.");
96
+ }
97
+ const projectName = await getValidProjectName(projectNameArg);
98
+ return {
99
+ projectName,
100
+ packageJsonExists
101
+ };
102
+ }
103
+ const MAIN_DEPENDENCIES = [
104
+ "@codefast/ui",
105
+ "@codefast/hooks"
106
+ ];
107
+ const DEV_DEPENDENCIES = {
108
+ commitLint: [
109
+ "@commitlint/cli",
110
+ "@commitlint/config-conventional",
111
+ "@commitlint/types"
112
+ ],
113
+ gitTools: [
114
+ "simple-git-hooks"
115
+ ],
116
+ formatting: [
117
+ "prettier",
118
+ "prettier-plugin-packagejson",
119
+ "prettier-plugin-tailwindcss",
120
+ "lint-staged"
121
+ ],
122
+ linting: [
123
+ "@codefast/eslint-config"
124
+ ]
125
+ };
126
+ const PACKAGES_TO_REMOVE = [
127
+ "@eslint/eslintrc"
128
+ ];
129
+ const configGroups = {
130
+ linting: [
131
+ {
132
+ path: "commitlint.config.mjs",
133
+ content: `/**
134
+ * @see https://commitlint.js.org/reference/configuration.html
135
+ * @type {import('@commitlint/types').UserConfig}
136
+ */
137
+ const config = {
138
+ extends: ["@commitlint/config-conventional"],
139
+ rules: {
140
+ "body-max-line-length": [2, "always", 350],
141
+ },
142
+ };
143
+ export default config;
144
+ `,
145
+ description: "Commitlint configuration"
146
+ },
147
+ {
148
+ path: "eslint.config.mjs",
149
+ content: `import { config } from "@codefast/eslint-config/next";
150
+ /**
151
+ * @see https://eslint.org/docs/latest/use/configure/configuration-files
152
+ * @type {import('eslint').Linter.Config[]}
153
+ */
154
+ const eslintConfig = [...config];
155
+ export default eslintConfig;
156
+ `,
157
+ description: "ESLint configuration for the project"
158
+ },
159
+ {
160
+ path: "lint-staged.config.mjs",
161
+ content: `import { relative } from "node:path";
162
+ /**
163
+ * Builds an ESLint command with the given filenames.
164
+ *
165
+ * @param {string[]} filenames - An array of filenames to be passed to the
166
+ * ESLint command.
167
+ * @returns {string} - The generated ESLint command.
168
+ */
169
+ function buildEslintCommand(filenames) {
170
+ return \`next lint --fix --max-warnings 0 --file \${filenames.map((file) => relative(import.meta.dirname, file)).
171
+ join(" --file ")}\`;
172
+ }
173
+ /**
174
+ * @see https://www.npmjs.com/package/lint-staged
175
+ * @type {import('lint-staged').Configuration}
176
+ */
177
+ const config = {
178
+ "*.{js,mjs,jsx,ts,tsx}": [buildEslintCommand, "prettier --list-different --write"],
179
+ "*.{json,css,md,mdx}": ["prettier --list-different --write"],
180
+ };
181
+ export default config;
182
+ `,
183
+ description: "Configure lint-staged for pre-commit checks"
184
+ }
185
+ ],
186
+ formatting: [
187
+ {
188
+ path: "prettier.config.mjs",
189
+ content: `/**
190
+ * @see https://prettier.io/docs/en/configuration.html
191
+ * @type {import('prettier').Config}
192
+ */
193
+ const config = {
194
+ plugins: ["prettier-plugin-packagejson", "prettier-plugin-tailwindcss"],
195
+ printWidth: 100,
196
+ tailwindAttributes: ["classNames"],
197
+ tailwindFunctions: ["tv"],
198
+ };
199
+ export default config;
200
+ `,
201
+ description: "Prettier configuration for source code formatting"
202
+ }
203
+ ],
204
+ styles: [
205
+ {
206
+ path: "src/lib/fonts.ts",
207
+ content: `import { cn } from "@codefast/ui";
208
+ import { Geist, Geist_Mono as GeistMono } from "next/font/google";
209
+ const fontGeistSans = Geist({
210
+ subsets: ["latin"],
211
+ variable: "--font-geist-sans",
212
+ });
213
+ const fontGeistMono = GeistMono({
214
+ subsets: ["latin"],
215
+ variable: "--font-geist-mono",
216
+ });
217
+ export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
218
+ `,
219
+ description: "Font configuration for the application"
220
+ },
221
+ {
222
+ path: "src/app/globals.css",
223
+ content: `@import "tailwindcss";
224
+ @import "@codefast/ui/styles.css";
225
+ @source '../../node_modules/@codefast/ui';
226
+ @custom-variant dark (&:where(.dark, .dark *));
227
+ @layer base {
228
+ :root {
229
+ --font-sans: var(--font-geist-sans);
230
+ --font-mono: var(--font-geist-mono);
231
+ --input: var(--color-neutral-200);
232
+ --border: var(--color-neutral-200);
233
+ --ring: var(--color-neutral-400);
234
+ --background: var(--color-white);
235
+ --foreground: var(--color-neutral-950);
236
+ --primary: var(--color-sky-500);
237
+ --primary-foreground: var(--color-neutral-50);
238
+ --secondary: var(--color-neutral-100);
239
+ --secondary-foreground: var(--color-neutral-900);
240
+ --destructive: var(--color-red-600);
241
+ --accent: var(--color-neutral-100);
242
+ --accent-foreground: var(--color-neutral-900);
243
+ --muted: var(--color-neutral-100);
244
+ --muted-foreground: var(--color-neutral-500);
245
+ --popover: var(--color-white);
246
+ --popover-foreground: var(--color-neutral-950);
247
+ --popover-overlay: --alpha(var(--color-neutral-900) / 20%);
248
+ --card: var(--color-white);
249
+ --card-foreground: var(--color-neutral-950);
250
+ --sidebar: var(--color-neutral-50);
251
+ --sidebar-foreground: var(--color-neutral-950);
252
+ --sidebar-primary: var(--color-sky-500);
253
+ --sidebar-primary-foreground: var(--color-neutral-50);
254
+ --sidebar-accent: var(--color-neutral-100);
255
+ --sidebar-accent-foreground: var(--color-neutral-900);
256
+ --sidebar-border: var(--color-neutral-200);
257
+ --sidebar-ring: var(--color-neutral-400);
258
+ --chart-1: var(--color-orange-600);
259
+ --chart-2: var(--color-teal-600);
260
+ --chart-3: var(--color-cyan-600);
261
+ --chart-4: var(--color-amber-600);
262
+ --chart-5: var(--color-amber-500);
263
+ }
264
+ @variant dark {
265
+ --input: var(--color-neutral-700);
266
+ --border: --alpha(var(--color-neutral-700) / 50%);
267
+ --ring: var(--color-neutral-500);
268
+ --background: var(--color-neutral-950);
269
+ --foreground: var(--color-neutral-50);
270
+ --primary: var(--color-sky-700);
271
+ --primary-foreground: var(--color-neutral-50);
272
+ --secondary: var(--color-neutral-800);
273
+ --secondary-foreground: var(--color-neutral-50);
274
+ --destructive: var(--color-red-400);
275
+ --accent: var(--color-neutral-700);
276
+ --accent-foreground: var(--color-neutral-50);
277
+ --muted: var(--color-neutral-800);
278
+ --muted-foreground: var(--color-neutral-400);
279
+ --popover: var(--color-neutral-800);
280
+ --popover-foreground: var(--color-neutral-50);
281
+ --popover-overlay: --alpha(var(--color-neutral-900) / 80%);
282
+ --card: var(--color-neutral-900);
283
+ --card-foreground: var(--color-neutral-50);
284
+ --sidebar: var(--color-neutral-900);
285
+ --sidebar-foreground: var(--color-neutral-50);
286
+ --sidebar-primary: var(--color-sky-700);
287
+ --sidebar-primary-foreground: var(--color-neutral-50);
288
+ --sidebar-accent: var(--color-neutral-800);
289
+ --sidebar-accent-foreground: var(--color-neutral-50);
290
+ --sidebar-border: var(--color-neutral-800);
291
+ --sidebar-ring: var(--color-neutral-600);
292
+ --chart-1: var(--color-blue-700);
293
+ --chart-2: var(--color-emerald-500);
294
+ --chart-3: var(--color-amber-500);
295
+ --chart-4: var(--color-purple-500);
296
+ --chart-5: var(--color-rose-500);
297
+ }
298
+ }
299
+ `,
300
+ description: "Global CSS variables for the application"
301
+ }
302
+ ]
303
+ };
304
+ function updatePostcssConfig(projectDir) {
305
+ const postcssConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "postcss.config.mjs");
306
+ if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(postcssConfigPath)) return void console.warn(`โš ๏ธ postcss.config.mjs not found, skipping update.`);
307
+ let content = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(postcssConfigPath, "utf8");
308
+ const typeComment = `/** @type {import('postcss-load-config').Config} */\n`;
309
+ if (content.includes(typeComment)) console.log(`๐Ÿ“ postcss.config.mjs already contains type comment, no changes made.`);
310
+ else {
311
+ content = content.replace("const config = {", `${typeComment}const config = {`);
312
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(postcssConfigPath, content);
313
+ console.log(`๐Ÿ“ Updated postcss.config.mjs with type comment.`);
314
+ }
315
+ }
316
+ function updateLayoutFile(projectDir) {
317
+ const layoutPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "src/app/layout.tsx");
318
+ if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(layoutPath)) return void console.warn(`โš ๏ธ src/app/layout.tsx not found, skipping update.`);
319
+ let content = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(layoutPath, "utf8");
320
+ 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.`);
321
+ const newImports = `import type { Metadata } from "next";
322
+
323
+ import { cn } from "@codefast/ui";
324
+
325
+ import { fontVariables } from "@/lib/fonts";
326
+ import "@/app/globals.css";`;
327
+ content = content.replaceAll(/import\s+{[^}]+}\s+from\s+["']next\/font\/google["'];\s*/g, "");
328
+ content = content.replace(/const\s+geistSans\s*=[^;]+;\s*const\s+geistMono\s*=[^;]+;\s*/, "");
329
+ content = content.replace(/import\s+type\s+{[^}]+}\s+from\s+["']next["'];\s*import\s+["']\.\/globals\.css["'];\s*/, newImports);
330
+ const htmlRegex = /<html\s+lang="en"\s*>/;
331
+ const newHtml = '<html className={cn(fontVariables, "antialiased")} lang="en">';
332
+ content = content.replace(htmlRegex, newHtml);
333
+ const bodyRegex = /<body\s+className={`[^`]*`}\s*>/;
334
+ const newBody = "<body>";
335
+ content = content.replace(bodyRegex, newBody);
336
+ try {
337
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(layoutPath, content);
338
+ console.log(`๐Ÿ“ Updated src/app/layout.tsx to use fontVariables in html tag and removed className from body`);
339
+ } catch (error) {
340
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
341
+ console.warn(`โš ๏ธ Failed to update src/app/layout.tsx: ${errorMessage}`);
342
+ }
343
+ }
344
+ function updatePackageJson(projectDir) {
345
+ const packageJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, "package.json");
346
+ const packageJson = JSON.parse(__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(packageJsonPath, "utf8"));
347
+ packageJson.scripts = {
348
+ ...packageJson.scripts,
349
+ format: 'prettier --write "**/*.{js,mjs,jsx,ts,tsx,json,css,md,mdx}"',
350
+ "format:check": 'prettier --check "**/*.{js,mjs,jsx,ts,tsx,json,css,md,mdx}"',
351
+ "lint:check": "next lint --max-warnings 0"
352
+ };
353
+ packageJson["simple-git-hooks"] = {
354
+ "pre-commit": "pnpm lint-staged",
355
+ "commit-msg": "pnpm commitlint --edit"
356
+ };
357
+ __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
358
+ console.log(`๐Ÿ“ Updated package.json`);
359
+ }
360
+ function createConfigFiles(projectDir) {
361
+ console.log(`\n๐Ÿ“ Creating configuration files...`);
362
+ for (const [category, configs] of Object.entries(configGroups)){
363
+ console.log(`\n๐Ÿ“‚ Setting up ${category} configurations:`);
364
+ for (const { path: filePath, content, description } of configs){
365
+ const fullPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectDir, filePath);
366
+ const dir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(fullPath);
367
+ if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(dir)) __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].mkdirSync(dir, {
368
+ recursive: true
369
+ });
370
+ writeConfigFile(fullPath, content);
371
+ if (description) console.log(` โ„น๏ธ ${filePath}: ${description}`);
372
+ }
373
+ }
374
+ }
375
+ function installDependencies() {
376
+ console.log(`\n๐Ÿ“š Installing dependencies...`);
377
+ if (MAIN_DEPENDENCIES.length > 0) runCommand(`pnpm add ${MAIN_DEPENDENCIES.join(" ")}`);
378
+ const allDevDependencies = Object.values(DEV_DEPENDENCIES).flat().join(" ");
379
+ if (allDevDependencies) runCommand(`pnpm add -D ${allDevDependencies}`);
380
+ }
381
+ function cleanupPackages() {
382
+ console.log(`\n๐Ÿงน Cleaning up unnecessary packages...`);
383
+ const packageJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__.join(process.cwd(), "package.json");
384
+ if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.existsSync(packageJsonPath)) return void console.warn(`โš ๏ธ package.json not found, skipping cleanup.`);
385
+ let packageJson;
386
+ try {
387
+ packageJson = JSON.parse(__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.readFileSync(packageJsonPath, "utf8"));
388
+ } catch (error) {
389
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
390
+ console.warn(`โš ๏ธ Error reading package.json: ${errorMessage}, skipping cleanup.`);
391
+ return;
392
+ }
393
+ const dependencies = packageJson.dependencies ?? {};
394
+ const devDependencies = packageJson.devDependencies ?? {};
395
+ const packagesToRemove = PACKAGES_TO_REMOVE.filter((pkg)=>pkg in dependencies || pkg in devDependencies);
396
+ if (packagesToRemove.length > 0) runCommand(`pnpm remove ${packagesToRemove.join(" ")}`);
397
+ else console.log(`โ„น๏ธ No unnecessary packages found in package.json to remove.`);
398
+ }
399
+ function checkEnvironment() {
400
+ try {
401
+ (0, __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__.execSync)("pnpm --version", {
402
+ stdio: "ignore"
403
+ });
404
+ } catch {
405
+ console.error(`โŒ PNPM chฦฐa ฤ‘ฦฐแปฃc cร i ฤ‘แบทt. Vui lรฒng cร i ฤ‘แบทt PNPM trฦฐแป›c.`);
406
+ process.exit(1);
407
+ }
408
+ }
409
+ function createNextProject(projectName) {
410
+ console.log(`๐Ÿ“ฆ Creating Next.js project...`);
411
+ const flags = '--ts --tailwind --eslint --app --turbo --use-pnpm --src-dir --turbopack --import-alias "@/*"';
412
+ runCommand(`npx create-next-app@latest ${projectName} ${flags}`);
413
+ }
414
+ function createProjectCommand(program) {
415
+ program.command("create-project [name]").description("Create a new Next.js project with recommended setup").action(async (projectNameArg)=>{
416
+ try {
417
+ checkEnvironment();
418
+ const { projectName, packageJsonExists } = await checkExistingProject(projectNameArg);
419
+ if (!packageJsonExists) {
420
+ console.log(`\n๐Ÿš€ Starting project creation for ${projectName}...\n`);
421
+ createNextProject(projectName);
422
+ process.chdir(projectName);
423
+ console.log(`๐Ÿ“‚ Moved to ${projectName}`);
424
+ }
425
+ updateLayoutFile(process.cwd());
426
+ updatePostcssConfig(process.cwd());
427
+ installDependencies();
428
+ cleanupPackages();
429
+ createConfigFiles(process.cwd());
430
+ updatePackageJson(process.cwd());
431
+ console.log(`\n๐Ÿ”„ Activating git hooks...`);
432
+ runCommand("pnpm simple-git-hooks");
433
+ console.log(`\n๐Ÿ“ Formatting files with Prettier...`);
434
+ runCommand("pnpm format");
435
+ console.log(`\nโœ… Project ${packageJsonExists ? "configured" : "created"} successfully!`);
436
+ console.log(`- Project: ${projectName}`);
437
+ console.log("- Next.js with TypeScript");
438
+ console.log("- TailwindCSS and @codefast/ui");
439
+ console.log("- ESLint, Prettier, Commitlint, and Git Hooks");
440
+ console.log("- Lint-staged for pre-commit checks");
441
+ console.log(`\n๐Ÿ“ Project directory: ${process.cwd()}`);
442
+ console.log(`\n๐Ÿš€ To start development:`);
443
+ console.log(`cd ${projectName} && pnpm dev`);
444
+ } catch (error) {
445
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
446
+ console.error(`\nโŒ An error occurred: ${errorMessage}`);
447
+ process.exit(1);
448
+ } finally{
449
+ rl.close();
450
+ }
451
+ });
452
+ }
11
453
  function makeRegexPrefixesToRemove(prefixes) {
12
454
  const prefixPattern = prefixes.join("|");
13
455
  return new RegExp(`^.?\\/?(?:${prefixPattern})\\/(.*)$`);
@@ -254,120 +696,92 @@ async function findAllPackages(config) {
254
696
  ignore: DEFAULT_IGNORE_PATTERN
255
697
  });
256
698
  }
257
- function processPackage(packageJsonPath, options, logger) {
699
+ function processPackage(packageJsonPath, options) {
258
700
  const packageDir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(packageJsonPath);
259
701
  const packageJson = readPackageJson(packageJsonPath);
260
702
  if (!packageJson) {
261
- logger.error(`Failed to read ${packageJsonPath}`);
703
+ console.error(`Failed to read ${packageJsonPath}`);
262
704
  return false;
263
705
  }
264
706
  const packageName = packageJson.name;
265
707
  if (options.packageFilter && packageName !== options.packageFilter) {
266
- logger.debug(`Skipping ${packageName} (does not match filter)`);
708
+ console.debug(`Skipping ${packageName} (does not match filter)`);
267
709
  return false;
268
710
  }
269
- logger.info(`\n๐Ÿ“ฆ Processing package: ${packageName}`);
711
+ console.info(`Processing package: ${packageName}`);
270
712
  const config = getConfig(options.configPath);
271
713
  const packageConfig = getPackageConfig(packageName, config);
272
714
  const srcIndexPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(packageDir, packageConfig.srcIndexPath);
273
715
  if (!fileExists(srcIndexPath)) {
274
- logger.error(`Source file not found at ${srcIndexPath}`);
716
+ console.error(`Source file not found at ${srcIndexPath}`);
275
717
  return false;
276
718
  }
277
- logger.info(`๐Ÿ” Analyzing imports from ${srcIndexPath}...`);
719
+ console.info(`Analyzing imports from ${srcIndexPath}...`);
278
720
  const { imports } = analyzeImports(srcIndexPath, packageConfig);
279
721
  if (0 === imports.length) {
280
- logger.warn(`No imports found to analyze in ${packageName}`);
722
+ console.warn(`No imports found to analyze in ${packageName}`);
281
723
  return false;
282
724
  }
283
- logger.success(`Analysis complete. Found ${imports.length} subpath exports.`);
725
+ console.log(`Analysis complete. Found ${imports.length} subpath exports.`);
284
726
  saveExportsAnalysis(packageDir, {
285
727
  imports
286
728
  });
287
729
  const newExports = generateExports(packageName, imports, packageJson.exports, config);
288
730
  const currentExportsCount = packageJson.exports ? Object.keys(packageJson.exports).length : 0;
289
731
  const newExportsCount = Object.keys(newExports).length;
290
- logger.info(`๐Ÿ“Š Exports: ${currentExportsCount} -> ${newExportsCount}`);
732
+ console.info(`Exports: ${currentExportsCount} -> ${newExportsCount}`);
291
733
  if (options.dryRun) {
292
734
  saveExportsPreview(packageDir, newExports);
293
- logger.warn(`๐Ÿงช ๐Ÿ“„ Saved exports preview to .exports-analysis`);
294
- logger.warn(`๐Ÿงช ๐Ÿšซ Dry run: no changes saved for ${packageName}`);
735
+ console.warn("Saved exports preview to .exports-analysis");
736
+ console.warn(`Dry run: no changes saved for ${packageName}`);
295
737
  return true;
296
738
  }
297
- if (backupPackageJson(packageJsonPath)) logger.success(`Backed up ${packageJsonPath}`);
739
+ if (backupPackageJson(packageJsonPath)) console.log(`Backed up ${packageJsonPath}`);
298
740
  const updatedPackageJson = {
299
741
  ...packageJson,
300
742
  exports: newExports
301
743
  };
302
744
  if (savePackageJson(packageJsonPath, updatedPackageJson)) {
303
- logger.success(`Updated exports for ${packageName}`);
745
+ console.log(`Updated exports for ${packageName}`);
304
746
  return true;
305
747
  }
306
- logger.error(`Failed to update ${packageJsonPath}`);
748
+ console.error(`Failed to update ${packageJsonPath}`);
307
749
  return false;
308
750
  }
309
- async function processAllPackages(options, logger) {
751
+ async function processAllPackages(options) {
310
752
  try {
311
- logger.info("๐Ÿ” Searching for packages...");
753
+ console.info("Searching for packages...");
312
754
  const config = getConfig(options.configPath);
313
755
  const packageJsonPaths = await findAllPackages(config);
314
- if (0 === packageJsonPaths.length) return void logger.warn("โš ๏ธ No packages found.");
315
- logger.success(`โœ… Found ${packageJsonPaths.length} packages.`);
756
+ if (0 === packageJsonPaths.length) return void console.warn("No packages found.");
757
+ console.log(`Found ${packageJsonPaths.length} packages.`);
316
758
  let successCount = 0;
317
759
  let skipCount = 0;
318
760
  let errorCount = 0;
319
761
  for (const packageJsonPath of packageJsonPaths){
320
- const result = processPackage(packageJsonPath, options, logger);
762
+ const result = processPackage(packageJsonPath, options);
321
763
  if (result) successCount++;
322
764
  else if (options.packageFilter) skipCount++;
323
765
  else errorCount++;
324
766
  }
325
- logger.success("\nโœ… Completed exports update.");
326
- logger.info(`๐Ÿ“Š Stats: ${successCount} succeeded, ${skipCount} skipped, ${errorCount} failed`);
767
+ console.log("Completed exports update.");
768
+ console.info(`Stats: ${successCount} succeeded, ${skipCount} skipped, ${errorCount} failed`);
327
769
  } catch (error) {
328
- logger.error("โŒ Error processing packages:", error);
770
+ console.error("Error processing packages:", error);
329
771
  throw error;
330
772
  }
331
773
  }
332
- class Logger {
333
- verbose;
334
- constructor(options = {}){
335
- this.verbose = options.verbose ?? false;
336
- }
337
- info(message, ...args) {
338
- console.log(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].blue(message), ...args);
339
- }
340
- success(message, ...args) {
341
- console.log(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].green(message), ...args);
342
- }
343
- warn(message, ...args) {
344
- console.log(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].yellow(message), ...args);
345
- }
346
- error(message, ...args) {
347
- console.error(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].red(message), ...args);
348
- }
349
- debug(message, ...args) {
350
- if (this.verbose) console.log(__WEBPACK_EXTERNAL_MODULE_chalk__["default"].gray(message), ...args);
351
- }
352
- table(data) {
353
- console.table(data);
354
- }
355
- }
356
774
  function createUpdateExportsCommand(program) {
357
- program.command("update-exports").description("Updates exports for all packages").option("-p, --package <package>", "Filter by package name").option("-d, --dry-run", "Run without making changes").option("-v, --verbose", "Show detailed output").option("-c, --config <path>", "Path to configuration file").action(async (options)=>{
775
+ program.command("update-exports").description("Updates exports for all packages").option("-p, --package <package>", "Filter by package name").option("-d, --dry-run", "Run without making changes").option("-c, --config <path>", "Path to configuration file").action(async (options)=>{
358
776
  const processorOptions = {
359
777
  packageFilter: options.package,
360
778
  dryRun: Boolean(options.dryRun),
361
- verbose: Boolean(options.verbose),
362
779
  configPath: options.config
363
780
  };
364
- const logger = new Logger({
365
- verbose: processorOptions.verbose
366
- });
367
781
  try {
368
- await processAllPackages(processorOptions, logger);
782
+ await processAllPackages(processorOptions);
369
783
  } catch (error) {
370
- logger.error("Error processing packages:", error);
784
+ console.error("Error processing packages:", error);
371
785
  process.exit(1);
372
786
  }
373
787
  });
@@ -385,7 +799,9 @@ function main() {
385
799
  const program = new __WEBPACK_EXTERNAL_MODULE_commander__.Command();
386
800
  program.name("codefast").description("CodeFast CLI - A development toolkit for CodeFast.").version(getPackageVersion(), "-v, --version", "display CLI version");
387
801
  createUpdateExportsCommand(program);
802
+ createProjectCommand(program);
388
803
  program.action(()=>{
804
+ console.log('Use "codefast create-project" to create a new Next.js project.');
389
805
  console.log('Use "codefast update-exports" to update exports.');
390
806
  console.log('Run "codefast --help" to see all available commands.');
391
807
  program.help();