@codefast/cli 0.3.1-canary.4 → 0.3.1-canary.5
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/CHANGELOG.md +14 -0
- package/dist/index.cjs +412 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +411 -56
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @codefast/cli
|
|
2
2
|
|
|
3
|
+
## 0.3.1-canary.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`f5b9777`](https://github.com/codefastlabs/codefast/commit/f5b977794956920183e2b132633e61cac4be4fdb) Thanks [@thevuong](https://github.com/thevuong)! - feat(cli): skip Next.js project creation if package.json exists
|
|
8
|
+
|
|
9
|
+
- [`77ccc05`](https://github.com/codefastlabs/codefast/commit/77ccc0556a1da4ee934af56fe8aef66eec0e1cf0) Thanks [@thevuong](https://github.com/thevuong)! - feat: support optional values in change handlers
|
|
10
|
+
|
|
11
|
+
- [`876c1cb`](https://github.com/codefastlabs/codefast/commit/876c1cb7d7ff7691096da7cc19faa44ddcffea70) Thanks [@thevuong](https://github.com/thevuong)! - refactor(cli): remove logger utility and update logging usage
|
|
12
|
+
|
|
13
|
+
- [`9e7aa7c`](https://github.com/codefastlabs/codefast/commit/9e7aa7c40e8d68257fbcd62ddb8fc7e2f6fcc895) Thanks [@thevuong](https://github.com/thevuong)! - chore(dependencies): update dependencies to latest versions
|
|
14
|
+
|
|
15
|
+
- [`80bd1ad`](https://github.com/codefastlabs/codefast/commit/80bd1ad5282d489b2da9f84d373adc40a9b24dc2) Thanks [@thevuong](https://github.com/thevuong)! - feat(cli): add enhanced project creation command
|
|
16
|
+
|
|
3
17
|
## 0.3.1-canary.4
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -26,9 +26,393 @@ var __webpack_require__ = {};
|
|
|
26
26
|
})();
|
|
27
27
|
var __webpack_exports__ = {};
|
|
28
28
|
const external_commander_namespaceObject = require("commander");
|
|
29
|
-
const
|
|
29
|
+
const external_node_child_process_namespaceObject = require("node:child_process");
|
|
30
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
31
|
+
var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
|
|
30
32
|
const external_node_path_namespaceObject = require("node:path");
|
|
31
33
|
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
|
|
34
|
+
const external_node_readline_namespaceObject = require("node:readline");
|
|
35
|
+
const MAIN_DEPENDENCIES = [
|
|
36
|
+
"@codefast/ui",
|
|
37
|
+
"@codefast/hooks"
|
|
38
|
+
];
|
|
39
|
+
const DEV_DEPENDENCIES = {
|
|
40
|
+
commitLint: [
|
|
41
|
+
"@commitlint/cli",
|
|
42
|
+
"@commitlint/config-conventional",
|
|
43
|
+
"@commitlint/types"
|
|
44
|
+
],
|
|
45
|
+
gitTools: [
|
|
46
|
+
"simple-git-hooks"
|
|
47
|
+
],
|
|
48
|
+
formatting: [
|
|
49
|
+
"prettier",
|
|
50
|
+
"prettier-plugin-packagejson",
|
|
51
|
+
"prettier-plugin-tailwindcss",
|
|
52
|
+
"lint-staged"
|
|
53
|
+
],
|
|
54
|
+
linting: [
|
|
55
|
+
"@codefast/eslint-config"
|
|
56
|
+
]
|
|
57
|
+
};
|
|
58
|
+
const rl = external_node_readline_namespaceObject.createInterface({
|
|
59
|
+
input: process.stdin,
|
|
60
|
+
output: process.stdout
|
|
61
|
+
});
|
|
62
|
+
function create_project_prompt(question) {
|
|
63
|
+
return new Promise((resolve)=>{
|
|
64
|
+
rl.question(question, (answer)=>{
|
|
65
|
+
resolve(answer.trim());
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function checkEnvironment() {
|
|
70
|
+
try {
|
|
71
|
+
(0, external_node_child_process_namespaceObject.execSync)("pnpm --version", {
|
|
72
|
+
stdio: "ignore"
|
|
73
|
+
});
|
|
74
|
+
} catch {
|
|
75
|
+
console.error("❌ PNPM chưa được cài đặt. Vui lòng cài đặt PNPM trước.");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function validateProjectName(name) {
|
|
80
|
+
if (!name || /^\s*$/.test(name)) return {
|
|
81
|
+
valid: false,
|
|
82
|
+
error: "Project name cannot be empty or contain only whitespace."
|
|
83
|
+
};
|
|
84
|
+
if (name.length > 100) return {
|
|
85
|
+
valid: false,
|
|
86
|
+
error: "Project name is too long (maximum 100 characters)."
|
|
87
|
+
};
|
|
88
|
+
const npmNameRegex = /^[a-z0-9-~][a-z0-9-._~]*$/;
|
|
89
|
+
if (!npmNameRegex.test(name)) return {
|
|
90
|
+
valid: false,
|
|
91
|
+
error: "Project name must be URL-friendly (letters, numbers, hyphens, underscores, dots; no @ or scoped packages)."
|
|
92
|
+
};
|
|
93
|
+
if ("." === name || ".." === name) return {
|
|
94
|
+
valid: false,
|
|
95
|
+
error: "Project name cannot be '.' or '..'."
|
|
96
|
+
};
|
|
97
|
+
const reservedNames = /^(?<reserved>CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i;
|
|
98
|
+
if (reservedNames.test(name)) return {
|
|
99
|
+
valid: false,
|
|
100
|
+
error: `Project name "${name}" is a reserved system name.`
|
|
101
|
+
};
|
|
102
|
+
const fullPath = external_node_path_namespaceObject.resolve(process.cwd(), name);
|
|
103
|
+
if (external_node_fs_namespaceObject.existsSync(fullPath)) return {
|
|
104
|
+
valid: false,
|
|
105
|
+
error: `A directory named "${name}" already exists.`
|
|
106
|
+
};
|
|
107
|
+
try {
|
|
108
|
+
external_node_fs_namespaceObject.accessSync(process.cwd(), external_node_fs_namespaceObject.constants.W_OK);
|
|
109
|
+
} catch {
|
|
110
|
+
return {
|
|
111
|
+
valid: false,
|
|
112
|
+
error: "Cannot create project: No write permission in current directory."
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
valid: true
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
async function getValidProjectName(initialName, attempts = 0, maxAttempts = 3) {
|
|
120
|
+
const projectName = initialName ?? await create_project_prompt("Enter project name: ");
|
|
121
|
+
const validation = validateProjectName(projectName);
|
|
122
|
+
if (validation.valid) return projectName;
|
|
123
|
+
if (attempts >= maxAttempts - 1) throw new Error("❌ Exceeded maximum attempts to enter a valid project name.");
|
|
124
|
+
console.error(`❌ ${validation.error} (${maxAttempts - attempts - 1} attempts remaining)`);
|
|
125
|
+
return getValidProjectName(void 0, attempts + 1, maxAttempts);
|
|
126
|
+
}
|
|
127
|
+
function runCommand(command) {
|
|
128
|
+
(0, external_node_child_process_namespaceObject.execSync)(command, {
|
|
129
|
+
stdio: "inherit"
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function writeConfigFile(filePath, content) {
|
|
133
|
+
external_node_fs_namespaceObject.writeFileSync(filePath, content);
|
|
134
|
+
console.log(`📝 Created ${filePath}`);
|
|
135
|
+
}
|
|
136
|
+
function updatePostcssConfig(projectDir) {
|
|
137
|
+
const postcssConfigPath = external_node_path_namespaceObject.join(projectDir, "postcss.config.mjs");
|
|
138
|
+
if (!external_node_fs_namespaceObject.existsSync(postcssConfigPath)) return void console.warn("⚠️ postcss.config.mjs not found, skipping update.");
|
|
139
|
+
let content = external_node_fs_namespaceObject.readFileSync(postcssConfigPath, "utf8");
|
|
140
|
+
const typeComment = `/** @type {import('postcss-load-config').Config} */\n`;
|
|
141
|
+
if (content.includes(typeComment)) console.log("📝 postcss.config.mjs already contains type comment, no changes made.");
|
|
142
|
+
else {
|
|
143
|
+
content = content.replace("const config = {", `${typeComment}const config = {`);
|
|
144
|
+
external_node_fs_namespaceObject.writeFileSync(postcssConfigPath, content);
|
|
145
|
+
console.log("📝 Updated postcss.config.mjs with type comment.");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const configFiles = {
|
|
149
|
+
"commitlint.config.mjs": `/**
|
|
150
|
+
* @see https://commitlint.js.org/reference/configuration.html
|
|
151
|
+
* @type {import('@commitlint/types').UserConfig}
|
|
152
|
+
*/
|
|
153
|
+
const config = {
|
|
154
|
+
extends: ["@commitlint/config-conventional"],
|
|
155
|
+
rules: {
|
|
156
|
+
"body-max-line-length": [2, "always", 350],
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export default config;
|
|
161
|
+
`,
|
|
162
|
+
"prettier.config.mjs": `/**
|
|
163
|
+
* @see https://prettier.io/docs/en/configuration.html
|
|
164
|
+
* @type {import('prettier').Config}
|
|
165
|
+
*/
|
|
166
|
+
const config = {
|
|
167
|
+
plugins: ["prettier-plugin-packagejson", "prettier-plugin-tailwindcss"],
|
|
168
|
+
printWidth: 100,
|
|
169
|
+
tailwindAttributes: ["classNames"],
|
|
170
|
+
tailwindFunctions: ["tv"],
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export default config;
|
|
174
|
+
`,
|
|
175
|
+
"lint-staged.config.mjs": `import { relative } from "node:path";
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Builds an ESLint command with the given filenames.
|
|
179
|
+
*
|
|
180
|
+
* @param {string[]} filenames - An array of filenames to be passed to the
|
|
181
|
+
* ESLint command.
|
|
182
|
+
* @returns {string} - The generated ESLint command.
|
|
183
|
+
*/
|
|
184
|
+
function buildEslintCommand(filenames) {
|
|
185
|
+
return \`next lint --fix --max-warnings 0 --file \${filenames.map((file) => relative(import.meta.dirname, file)).
|
|
186
|
+
join(" --file ")}\`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @see https://www.npmjs.com/package/lint-staged
|
|
191
|
+
* @type {import('lint-staged').Configuration}
|
|
192
|
+
*/
|
|
193
|
+
const config = {
|
|
194
|
+
"*.{js,mjs,jsx,ts,tsx}": [buildEslintCommand, "prettier --list-different --write"],
|
|
195
|
+
"*.{json,css,md,mdx}": ["prettier --list-different --write"],
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
export default config;
|
|
199
|
+
`,
|
|
200
|
+
"eslint.config.mjs": `import { config } from "@codefast/eslint-config/next";
|
|
201
|
+
/**
|
|
202
|
+
* @see https://eslint.org/docs/latest/use/configure/configuration-files
|
|
203
|
+
* @type {import('eslint').Linter.Config[]}
|
|
204
|
+
*/
|
|
205
|
+
const eslintConfig = [...config];
|
|
206
|
+
|
|
207
|
+
export default eslintConfig;
|
|
208
|
+
`,
|
|
209
|
+
"src/lib/fonts.ts": `import { cn } from "@codefast/ui";
|
|
210
|
+
import { Geist, Geist_Mono as GeistMono } from "next/font/google";
|
|
211
|
+
|
|
212
|
+
const fontGeistSans = Geist({
|
|
213
|
+
subsets: ["latin"],
|
|
214
|
+
variable: "--font-geist-sans",
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const fontGeistMono = GeistMono({
|
|
218
|
+
subsets: ["latin"],
|
|
219
|
+
variable: "--font-geist-mono",
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
|
|
223
|
+
`,
|
|
224
|
+
"src/app/globals.css": `@import "tailwindcss";
|
|
225
|
+
|
|
226
|
+
@import "@codefast/ui/styles.css";
|
|
227
|
+
|
|
228
|
+
@source '../../node_modules/@codefast/ui';
|
|
229
|
+
|
|
230
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
231
|
+
|
|
232
|
+
@theme inline {
|
|
233
|
+
--font-sans: var(--font-geist-sans);
|
|
234
|
+
--font-mono: var(--font-geist-mono);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
@layer base {
|
|
238
|
+
:root {
|
|
239
|
+
--input: var(--color-neutral-200);
|
|
240
|
+
--border: var(--color-neutral-200);
|
|
241
|
+
|
|
242
|
+
--ring: var(--color-neutral-400);
|
|
243
|
+
|
|
244
|
+
--background: var(--color-white);
|
|
245
|
+
--foreground: var(--color-neutral-950);
|
|
246
|
+
|
|
247
|
+
--primary: var(--color-sky-500);
|
|
248
|
+
--primary-foreground: var(--color-neutral-50);
|
|
249
|
+
|
|
250
|
+
--secondary: var(--color-neutral-100);
|
|
251
|
+
--secondary-foreground: var(--color-neutral-900);
|
|
252
|
+
|
|
253
|
+
--destructive: var(--color-red-600);
|
|
254
|
+
|
|
255
|
+
--accent: var(--color-neutral-100);
|
|
256
|
+
--accent-foreground: var(--color-neutral-900);
|
|
257
|
+
|
|
258
|
+
--muted: var(--color-neutral-100);
|
|
259
|
+
--muted-foreground: var(--color-neutral-500);
|
|
260
|
+
|
|
261
|
+
--popover: var(--color-white);
|
|
262
|
+
--popover-foreground: var(--color-neutral-950);
|
|
263
|
+
--popover-overlay: --alpha(var(--color-neutral-900) / 20%);
|
|
264
|
+
|
|
265
|
+
--card: var(--color-white);
|
|
266
|
+
--card-foreground: var(--color-neutral-950);
|
|
267
|
+
|
|
268
|
+
--sidebar: var(--color-neutral-50);
|
|
269
|
+
--sidebar-foreground: var(--color-neutral-950);
|
|
270
|
+
|
|
271
|
+
--sidebar-primary: var(--color-sky-500);
|
|
272
|
+
--sidebar-primary-foreground: var(--color-neutral-50);
|
|
273
|
+
|
|
274
|
+
--sidebar-accent: var(--color-neutral-100);
|
|
275
|
+
--sidebar-accent-foreground: var(--color-neutral-900);
|
|
276
|
+
|
|
277
|
+
--sidebar-border: var(--color-neutral-200);
|
|
278
|
+
--sidebar-ring: var(--color-neutral-400);
|
|
279
|
+
|
|
280
|
+
--chart-1: var(--color-orange-600);
|
|
281
|
+
--chart-2: var(--color-teal-600);
|
|
282
|
+
--chart-3: var(--color-cyan-600);
|
|
283
|
+
--chart-4: var(--color-amber-600);
|
|
284
|
+
--chart-5: var(--color-amber-500);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
@variant dark {
|
|
288
|
+
--input: var(--color-neutral-700);
|
|
289
|
+
--border: --alpha(var(--color-neutral-700) / 50%);
|
|
290
|
+
|
|
291
|
+
--ring: var(--color-neutral-500);
|
|
292
|
+
|
|
293
|
+
--background: var(--color-neutral-950);
|
|
294
|
+
--foreground: var(--color-neutral-50);
|
|
295
|
+
|
|
296
|
+
--primary: var(--color-sky-700);
|
|
297
|
+
--primary-foreground: var(--color-neutral-50);
|
|
298
|
+
|
|
299
|
+
--secondary: var(--color-neutral-800);
|
|
300
|
+
--secondary-foreground: var(--color-neutral-50);
|
|
301
|
+
|
|
302
|
+
--destructive: var(--color-red-400);
|
|
303
|
+
|
|
304
|
+
--accent: var(--color-neutral-700);
|
|
305
|
+
--accent-foreground: var(--color-neutral-50);
|
|
306
|
+
|
|
307
|
+
--muted: var(--color-neutral-800);
|
|
308
|
+
--muted-foreground: var(--color-neutral-400);
|
|
309
|
+
|
|
310
|
+
--popover: var(--color-neutral-800);
|
|
311
|
+
--popover-foreground: var(--color-neutral-50);
|
|
312
|
+
--popover-overlay: --alpha(var(--color-neutral-900) / 80%);
|
|
313
|
+
|
|
314
|
+
--card: var(--color-neutral-900);
|
|
315
|
+
--card-foreground: var(--color-neutral-50);
|
|
316
|
+
|
|
317
|
+
--sidebar: var(--color-neutral-900);
|
|
318
|
+
--sidebar-foreground: var(--color-neutral-50);
|
|
319
|
+
|
|
320
|
+
--sidebar-primary: var(--color-sky-700);
|
|
321
|
+
--sidebar-primary-foreground: var(--color-neutral-50);
|
|
322
|
+
|
|
323
|
+
--sidebar-accent: var(--color-neutral-800);
|
|
324
|
+
--sidebar-accent-foreground: var(--color-neutral-50);
|
|
325
|
+
|
|
326
|
+
--sidebar-border: var(--color-neutral-800);
|
|
327
|
+
--sidebar-ring: var(--color-neutral-600);
|
|
328
|
+
|
|
329
|
+
--chart-1: var(--color-blue-700);
|
|
330
|
+
--chart-2: var(--color-emerald-500);
|
|
331
|
+
--chart-3: var(--color-amber-500);
|
|
332
|
+
--chart-4: var(--color-purple-500);
|
|
333
|
+
--chart-5: var(--color-rose-500);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
`
|
|
337
|
+
};
|
|
338
|
+
function updatePackageJson(projectDir) {
|
|
339
|
+
const packageJsonPath = external_node_path_namespaceObject.join(projectDir, "package.json");
|
|
340
|
+
const packageJson = JSON.parse(external_node_fs_namespaceObject.readFileSync(packageJsonPath, "utf8"));
|
|
341
|
+
packageJson.scripts = {
|
|
342
|
+
...packageJson.scripts,
|
|
343
|
+
format: 'prettier --write "**/*.{js,mjs,jsx,ts,tsx,json,css,md,mdx}"',
|
|
344
|
+
"format:check": 'prettier --check "**/*.{js,mjs,jsx,ts,tsx,json,css,md,mdx}"',
|
|
345
|
+
"lint:check": "next lint --max-warnings 0"
|
|
346
|
+
};
|
|
347
|
+
packageJson["simple-git-hooks"] = {
|
|
348
|
+
"pre-commit": "pnpm lint-staged",
|
|
349
|
+
"commit-msg": "pnpm commitlint --edit"
|
|
350
|
+
};
|
|
351
|
+
external_node_fs_namespaceObject.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
352
|
+
console.log("📝 Updated package.json");
|
|
353
|
+
}
|
|
354
|
+
function createNextProject(projectName) {
|
|
355
|
+
console.log("📦 Creating Next.js project...");
|
|
356
|
+
const flags = '--ts --tailwind --eslint --app --turbo --use-pnpm --src-dir --turbopack --import-alias "@/*"';
|
|
357
|
+
runCommand(`npx create-next-app@latest ${projectName} ${flags}`);
|
|
358
|
+
}
|
|
359
|
+
function installDependencies() {
|
|
360
|
+
console.log("📚 Installing dependencies...");
|
|
361
|
+
if (MAIN_DEPENDENCIES.length > 0) runCommand(`pnpm add ${MAIN_DEPENDENCIES.join(" ")}`);
|
|
362
|
+
const allDevDependencies = Object.values(DEV_DEPENDENCIES).flat().join(" ");
|
|
363
|
+
if (allDevDependencies) runCommand(`pnpm add -D ${allDevDependencies}`);
|
|
364
|
+
}
|
|
365
|
+
function createConfigFiles(projectDir) {
|
|
366
|
+
console.log(`\n📝 Creating configuration files...`);
|
|
367
|
+
for (const [filePath, content] of Object.entries(configFiles)){
|
|
368
|
+
const fullPath = external_node_path_namespaceObject.join(projectDir, filePath);
|
|
369
|
+
const dir = external_node_path_namespaceObject.dirname(fullPath);
|
|
370
|
+
if (!external_node_fs_namespaceObject.existsSync(dir)) external_node_fs_namespaceObject.mkdirSync(dir, {
|
|
371
|
+
recursive: true
|
|
372
|
+
});
|
|
373
|
+
writeConfigFile(fullPath, content);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function createProjectCommand(program) {
|
|
377
|
+
program.command("create-project [name]").description("Create a new Next.js project with recommended setup").action(async (projectNameArg)=>{
|
|
378
|
+
try {
|
|
379
|
+
checkEnvironment();
|
|
380
|
+
const projectName = await getValidProjectName(projectNameArg);
|
|
381
|
+
console.log(`\n🚀 Starting project creation for ${projectName}...\n`);
|
|
382
|
+
const packageJsonExists = external_node_fs_namespaceObject.existsSync(external_node_path_namespaceObject.join(process.cwd(), "package.json"));
|
|
383
|
+
if (packageJsonExists) console.log(`📦 A package.json file has been detected. Skipping the Next.js project creation step.`);
|
|
384
|
+
else {
|
|
385
|
+
createNextProject(projectName);
|
|
386
|
+
process.chdir(projectName);
|
|
387
|
+
console.log(`📂 Moved to ${projectName}`);
|
|
388
|
+
}
|
|
389
|
+
updatePostcssConfig(process.cwd());
|
|
390
|
+
installDependencies();
|
|
391
|
+
createConfigFiles(process.cwd());
|
|
392
|
+
updatePackageJson(process.cwd());
|
|
393
|
+
console.log(`\n🔄 Activating git hooks...`);
|
|
394
|
+
runCommand("pnpm simple-git-hooks");
|
|
395
|
+
console.log(`\n📝 Formatting files with Prettier...`);
|
|
396
|
+
runCommand("pnpm format");
|
|
397
|
+
console.log(`\n✅ Project created successfully!`);
|
|
398
|
+
console.log(`- Project: ${projectName}`);
|
|
399
|
+
console.log("- Next.js with TypeScript");
|
|
400
|
+
console.log("- TailwindCSS and @codefast/ui");
|
|
401
|
+
console.log("- ESLint, Prettier, Commitlint, and Git Hooks");
|
|
402
|
+
console.log("- Lint-staged for pre-commit checks");
|
|
403
|
+
console.log(`\n📁 Project directory: ${external_node_path_namespaceObject.resolve(process.cwd())}`);
|
|
404
|
+
console.log(`\n🚀 To start development:`);
|
|
405
|
+
console.log(`cd ${projectName} && pnpm dev`);
|
|
406
|
+
rl.close();
|
|
407
|
+
} catch (error) {
|
|
408
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
409
|
+
console.error(`\n❌ An error occurred: ${errorMessage}`);
|
|
410
|
+
rl.close();
|
|
411
|
+
process.exit(1);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
const external_glob_namespaceObject = require("glob");
|
|
32
416
|
const external_ts_morph_namespaceObject = require("ts-morph");
|
|
33
417
|
function makeRegexPrefixesToRemove(prefixes) {
|
|
34
418
|
const prefixPattern = prefixes.join("|");
|
|
@@ -85,8 +469,6 @@ function analyzeImports(indexFilePath, packageConfig) {
|
|
|
85
469
|
};
|
|
86
470
|
}
|
|
87
471
|
const external_lodash_es_namespaceObject = require("lodash-es");
|
|
88
|
-
const external_node_fs_namespaceObject = require("node:fs");
|
|
89
|
-
var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
|
|
90
472
|
const external_zod_namespaceObject = require("zod");
|
|
91
473
|
const PackageConfigSchema = external_zod_namespaceObject.z["interface"]({
|
|
92
474
|
cjsOutputPattern: external_zod_namespaceObject.z.string(),
|
|
@@ -280,122 +662,92 @@ async function findAllPackages(config) {
|
|
|
280
662
|
ignore: DEFAULT_IGNORE_PATTERN
|
|
281
663
|
});
|
|
282
664
|
}
|
|
283
|
-
function processPackage(packageJsonPath, options
|
|
665
|
+
function processPackage(packageJsonPath, options) {
|
|
284
666
|
const packageDir = external_node_path_default().dirname(packageJsonPath);
|
|
285
667
|
const packageJson = readPackageJson(packageJsonPath);
|
|
286
668
|
if (!packageJson) {
|
|
287
|
-
|
|
669
|
+
console.error(`Failed to read ${packageJsonPath}`);
|
|
288
670
|
return false;
|
|
289
671
|
}
|
|
290
672
|
const packageName = packageJson.name;
|
|
291
673
|
if (options.packageFilter && packageName !== options.packageFilter) {
|
|
292
|
-
|
|
674
|
+
console.debug(`Skipping ${packageName} (does not match filter)`);
|
|
293
675
|
return false;
|
|
294
676
|
}
|
|
295
|
-
|
|
677
|
+
console.info(`Processing package: ${packageName}`);
|
|
296
678
|
const config = getConfig(options.configPath);
|
|
297
679
|
const packageConfig = getPackageConfig(packageName, config);
|
|
298
680
|
const srcIndexPath = external_node_path_default().join(packageDir, packageConfig.srcIndexPath);
|
|
299
681
|
if (!fileExists(srcIndexPath)) {
|
|
300
|
-
|
|
682
|
+
console.error(`Source file not found at ${srcIndexPath}`);
|
|
301
683
|
return false;
|
|
302
684
|
}
|
|
303
|
-
|
|
685
|
+
console.info(`Analyzing imports from ${srcIndexPath}...`);
|
|
304
686
|
const { imports } = analyzeImports(srcIndexPath, packageConfig);
|
|
305
687
|
if (0 === imports.length) {
|
|
306
|
-
|
|
688
|
+
console.warn(`No imports found to analyze in ${packageName}`);
|
|
307
689
|
return false;
|
|
308
690
|
}
|
|
309
|
-
|
|
691
|
+
console.log(`Analysis complete. Found ${imports.length} subpath exports.`);
|
|
310
692
|
saveExportsAnalysis(packageDir, {
|
|
311
693
|
imports
|
|
312
694
|
});
|
|
313
695
|
const newExports = generateExports(packageName, imports, packageJson.exports, config);
|
|
314
696
|
const currentExportsCount = packageJson.exports ? Object.keys(packageJson.exports).length : 0;
|
|
315
697
|
const newExportsCount = Object.keys(newExports).length;
|
|
316
|
-
|
|
698
|
+
console.info(`Exports: ${currentExportsCount} -> ${newExportsCount}`);
|
|
317
699
|
if (options.dryRun) {
|
|
318
700
|
saveExportsPreview(packageDir, newExports);
|
|
319
|
-
|
|
320
|
-
|
|
701
|
+
console.warn("Saved exports preview to .exports-analysis");
|
|
702
|
+
console.warn(`Dry run: no changes saved for ${packageName}`);
|
|
321
703
|
return true;
|
|
322
704
|
}
|
|
323
|
-
if (backupPackageJson(packageJsonPath))
|
|
705
|
+
if (backupPackageJson(packageJsonPath)) console.log(`Backed up ${packageJsonPath}`);
|
|
324
706
|
const updatedPackageJson = {
|
|
325
707
|
...packageJson,
|
|
326
708
|
exports: newExports
|
|
327
709
|
};
|
|
328
710
|
if (savePackageJson(packageJsonPath, updatedPackageJson)) {
|
|
329
|
-
|
|
711
|
+
console.log(`Updated exports for ${packageName}`);
|
|
330
712
|
return true;
|
|
331
713
|
}
|
|
332
|
-
|
|
714
|
+
console.error(`Failed to update ${packageJsonPath}`);
|
|
333
715
|
return false;
|
|
334
716
|
}
|
|
335
|
-
async function processAllPackages(options
|
|
717
|
+
async function processAllPackages(options) {
|
|
336
718
|
try {
|
|
337
|
-
|
|
719
|
+
console.info("Searching for packages...");
|
|
338
720
|
const config = getConfig(options.configPath);
|
|
339
721
|
const packageJsonPaths = await findAllPackages(config);
|
|
340
|
-
if (0 === packageJsonPaths.length) return void
|
|
341
|
-
|
|
722
|
+
if (0 === packageJsonPaths.length) return void console.warn("No packages found.");
|
|
723
|
+
console.log(`Found ${packageJsonPaths.length} packages.`);
|
|
342
724
|
let successCount = 0;
|
|
343
725
|
let skipCount = 0;
|
|
344
726
|
let errorCount = 0;
|
|
345
727
|
for (const packageJsonPath of packageJsonPaths){
|
|
346
|
-
const result = processPackage(packageJsonPath, options
|
|
728
|
+
const result = processPackage(packageJsonPath, options);
|
|
347
729
|
if (result) successCount++;
|
|
348
730
|
else if (options.packageFilter) skipCount++;
|
|
349
731
|
else errorCount++;
|
|
350
732
|
}
|
|
351
|
-
|
|
352
|
-
|
|
733
|
+
console.log("Completed exports update.");
|
|
734
|
+
console.info(`Stats: ${successCount} succeeded, ${skipCount} skipped, ${errorCount} failed`);
|
|
353
735
|
} catch (error) {
|
|
354
|
-
|
|
736
|
+
console.error("Error processing packages:", error);
|
|
355
737
|
throw error;
|
|
356
738
|
}
|
|
357
739
|
}
|
|
358
|
-
const external_chalk_namespaceObject = require("chalk");
|
|
359
|
-
var external_chalk_default = /*#__PURE__*/ __webpack_require__.n(external_chalk_namespaceObject);
|
|
360
|
-
class Logger {
|
|
361
|
-
verbose;
|
|
362
|
-
constructor(options = {}){
|
|
363
|
-
this.verbose = options.verbose ?? false;
|
|
364
|
-
}
|
|
365
|
-
info(message, ...args) {
|
|
366
|
-
console.log(external_chalk_default().blue(message), ...args);
|
|
367
|
-
}
|
|
368
|
-
success(message, ...args) {
|
|
369
|
-
console.log(external_chalk_default().green(message), ...args);
|
|
370
|
-
}
|
|
371
|
-
warn(message, ...args) {
|
|
372
|
-
console.log(external_chalk_default().yellow(message), ...args);
|
|
373
|
-
}
|
|
374
|
-
error(message, ...args) {
|
|
375
|
-
console.error(external_chalk_default().red(message), ...args);
|
|
376
|
-
}
|
|
377
|
-
debug(message, ...args) {
|
|
378
|
-
if (this.verbose) console.log(external_chalk_default().gray(message), ...args);
|
|
379
|
-
}
|
|
380
|
-
table(data) {
|
|
381
|
-
console.table(data);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
740
|
function createUpdateExportsCommand(program) {
|
|
385
|
-
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("-
|
|
741
|
+
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)=>{
|
|
386
742
|
const processorOptions = {
|
|
387
743
|
packageFilter: options.package,
|
|
388
744
|
dryRun: Boolean(options.dryRun),
|
|
389
|
-
verbose: Boolean(options.verbose),
|
|
390
745
|
configPath: options.config
|
|
391
746
|
};
|
|
392
|
-
const logger = new Logger({
|
|
393
|
-
verbose: processorOptions.verbose
|
|
394
|
-
});
|
|
395
747
|
try {
|
|
396
|
-
await processAllPackages(processorOptions
|
|
748
|
+
await processAllPackages(processorOptions);
|
|
397
749
|
} catch (error) {
|
|
398
|
-
|
|
750
|
+
console.error("Error processing packages:", error);
|
|
399
751
|
process.exit(1);
|
|
400
752
|
}
|
|
401
753
|
});
|
|
@@ -414,7 +766,9 @@ function main() {
|
|
|
414
766
|
const program = new external_commander_namespaceObject.Command();
|
|
415
767
|
program.name("codefast").description("CodeFast CLI - A development toolkit for CodeFast.").version(getPackageVersion(), "-v, --version", "display CLI version");
|
|
416
768
|
createUpdateExportsCommand(program);
|
|
769
|
+
createProjectCommand(program);
|
|
417
770
|
program.action(()=>{
|
|
771
|
+
console.log('Use "codefast create-project" to create a new Next.js project.');
|
|
418
772
|
console.log('Use "codefast update-exports" to update exports.');
|
|
419
773
|
console.log('Run "codefast --help" to see all available commands.');
|
|
420
774
|
program.help();
|