@codefast/cli 0.3.1-canary.1 → 0.3.1-canary.11
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 +99 -1
- package/dist/index.cjs +1011 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +978 -0
- package/dist/index.js.map +1 -0
- package/package.json +19 -12
- package/.turbo/turbo-build.log +0 -12
- package/dist/cjs/commands/update-exports/analyze-imports.cjs +0 -92
- package/dist/cjs/commands/update-exports/analyze-imports.cjs.map +0 -1
- package/dist/cjs/commands/update-exports/command.cjs +0 -58
- package/dist/cjs/commands/update-exports/command.cjs.map +0 -1
- package/dist/cjs/commands/update-exports/config.cjs +0 -113
- package/dist/cjs/commands/update-exports/config.cjs.map +0 -1
- package/dist/cjs/commands/update-exports/file-utils.cjs +0 -144
- package/dist/cjs/commands/update-exports/file-utils.cjs.map +0 -1
- package/dist/cjs/commands/update-exports/generate-exports.cjs +0 -76
- package/dist/cjs/commands/update-exports/generate-exports.cjs.map +0 -1
- package/dist/cjs/commands/update-exports/index.cjs +0 -36
- package/dist/cjs/commands/update-exports/process-package.cjs +0 -143
- package/dist/cjs/commands/update-exports/process-package.cjs.map +0 -1
- package/dist/cjs/commands/update-exports/types.cjs +0 -55
- package/dist/cjs/commands/update-exports/types.cjs.map +0 -1
- package/dist/cjs/index.cjs +0 -46
- package/dist/cjs/index.cjs.map +0 -1
- package/dist/cjs/lib/logger.cjs +0 -72
- package/dist/cjs/lib/logger.cjs.map +0 -1
- package/dist/esm/commands/update-exports/analyze-imports.js +0 -58
- package/dist/esm/commands/update-exports/analyze-imports.js.map +0 -1
- package/dist/esm/commands/update-exports/command.js +0 -24
- package/dist/esm/commands/update-exports/command.js.map +0 -1
- package/dist/esm/commands/update-exports/config.js +0 -62
- package/dist/esm/commands/update-exports/config.js.map +0 -1
- package/dist/esm/commands/update-exports/file-utils.js +0 -81
- package/dist/esm/commands/update-exports/file-utils.js.map +0 -1
- package/dist/esm/commands/update-exports/generate-exports.js +0 -42
- package/dist/esm/commands/update-exports/generate-exports.js.map +0 -1
- package/dist/esm/commands/update-exports/index.js +0 -3
- package/dist/esm/commands/update-exports/process-package.js +0 -93
- package/dist/esm/commands/update-exports/process-package.js.map +0 -1
- package/dist/esm/commands/update-exports/types.js +0 -18
- package/dist/esm/commands/update-exports/types.js.map +0 -1
- package/dist/esm/index.js +0 -18
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/lib/logger.js +0 -28
- package/dist/esm/lib/logger.js.map +0 -1
- package/dist/types/src/commands/update-exports/analyze-imports.d.ts +0 -9
- package/dist/types/src/commands/update-exports/analyze-imports.d.ts.map +0 -1
- package/dist/types/src/commands/update-exports/command.d.ts +0 -7
- package/dist/types/src/commands/update-exports/command.d.ts.map +0 -1
- package/dist/types/src/commands/update-exports/config.d.ts +0 -16
- package/dist/types/src/commands/update-exports/config.d.ts.map +0 -1
- package/dist/types/src/commands/update-exports/file-utils.d.ts +0 -47
- package/dist/types/src/commands/update-exports/file-utils.d.ts.map +0 -1
- package/dist/types/src/commands/update-exports/generate-exports.d.ts +0 -11
- package/dist/types/src/commands/update-exports/generate-exports.d.ts.map +0 -1
- package/dist/types/src/commands/update-exports/index.d.ts +0 -2
- package/dist/types/src/commands/update-exports/index.d.ts.map +0 -1
- package/dist/types/src/commands/update-exports/process-package.d.ts +0 -23
- package/dist/types/src/commands/update-exports/process-package.d.ts.map +0 -1
- package/dist/types/src/commands/update-exports/types.d.ts +0 -83
- package/dist/types/src/commands/update-exports/types.d.ts.map +0 -1
- package/dist/types/src/index.d.ts +0 -3
- package/dist/types/src/index.d.ts.map +0 -1
- package/dist/types/src/lib/logger.d.ts +0 -15
- package/dist/types/src/lib/logger.d.ts.map +0 -1
- package/eslint.config.js +0 -18
- package/rslib.config.ts +0 -40
- package/src/commands/update-exports/analyze-imports.ts +0 -112
- package/src/commands/update-exports/command.ts +0 -38
- package/src/commands/update-exports/config.ts +0 -99
- package/src/commands/update-exports/file-utils.ts +0 -178
- package/src/commands/update-exports/generate-exports.ts +0 -74
- package/src/commands/update-exports/index.ts +0 -1
- package/src/commands/update-exports/process-package.ts +0 -164
- package/src/commands/update-exports/types.ts +0 -94
- package/src/index.ts +0 -28
- package/src/lib/logger.ts +0 -39
- package/tsconfig.build.json +0 -5
- package/tsconfig.json +0 -14
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1011 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
const __rslib_import_meta_url__ = /*#__PURE__*/ function() {
|
|
4
|
+
return 'undefined' == typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
|
|
5
|
+
}();
|
|
6
|
+
var __webpack_require__ = {};
|
|
7
|
+
(()=>{
|
|
8
|
+
__webpack_require__.n = (module)=>{
|
|
9
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
10
|
+
__webpack_require__.d(getter, {
|
|
11
|
+
a: getter
|
|
12
|
+
});
|
|
13
|
+
return getter;
|
|
14
|
+
};
|
|
15
|
+
})();
|
|
16
|
+
(()=>{
|
|
17
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
18
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: definition[key]
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
(()=>{
|
|
25
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
26
|
+
})();
|
|
27
|
+
var __webpack_exports__ = {};
|
|
28
|
+
const external_commander_namespaceObject = require("commander");
|
|
29
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
30
|
+
var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
|
|
31
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
32
|
+
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
|
|
33
|
+
const external_node_child_process_namespaceObject = require("node:child_process");
|
|
34
|
+
const external_node_readline_namespaceObject = require("node:readline");
|
|
35
|
+
var external_node_readline_default = /*#__PURE__*/ __webpack_require__.n(external_node_readline_namespaceObject);
|
|
36
|
+
const rl = external_node_readline_default().createInterface({
|
|
37
|
+
input: process.stdin,
|
|
38
|
+
output: process.stdout
|
|
39
|
+
});
|
|
40
|
+
function utils_prompt(question) {
|
|
41
|
+
return new Promise((resolve)=>{
|
|
42
|
+
rl.question(question, (answer)=>{
|
|
43
|
+
resolve(answer.trim());
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function runCommand(command) {
|
|
48
|
+
(0, external_node_child_process_namespaceObject.execSync)(command, {
|
|
49
|
+
stdio: "inherit"
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function writeConfigFile(filePath, content) {
|
|
53
|
+
external_node_fs_default().writeFileSync(filePath, content);
|
|
54
|
+
console.log(`📝 Created ${filePath}`);
|
|
55
|
+
}
|
|
56
|
+
function validateProjectName(name) {
|
|
57
|
+
if (!name || /^\s*$/.test(name)) return {
|
|
58
|
+
valid: false,
|
|
59
|
+
error: "Project name cannot be empty or contain only whitespace."
|
|
60
|
+
};
|
|
61
|
+
if (name.length > 100) return {
|
|
62
|
+
valid: false,
|
|
63
|
+
error: "Project name is too long (maximum 100 characters)."
|
|
64
|
+
};
|
|
65
|
+
const npmNameRegex = /^[a-z0-9-~][a-z0-9-._~]*$/;
|
|
66
|
+
if (!npmNameRegex.test(name)) return {
|
|
67
|
+
valid: false,
|
|
68
|
+
error: "Project name must be URL-friendly (letters, numbers, hyphens, underscores, dots; no @ or scoped packages)."
|
|
69
|
+
};
|
|
70
|
+
if ("." === name || ".." === name) return {
|
|
71
|
+
valid: false,
|
|
72
|
+
error: "Project name cannot be '.' or '..'."
|
|
73
|
+
};
|
|
74
|
+
const reservedNames = /^(?<reserved>CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i;
|
|
75
|
+
if (reservedNames.test(name)) return {
|
|
76
|
+
valid: false,
|
|
77
|
+
error: `Project name "${name}" is a reserved system name.`
|
|
78
|
+
};
|
|
79
|
+
const fullPath = external_node_path_default().resolve(process.cwd(), name);
|
|
80
|
+
if (external_node_fs_default().existsSync(fullPath)) return {
|
|
81
|
+
valid: false,
|
|
82
|
+
error: `A directory named "${name}" already exists.`
|
|
83
|
+
};
|
|
84
|
+
try {
|
|
85
|
+
external_node_fs_default().accessSync(process.cwd(), external_node_fs_default().constants.W_OK);
|
|
86
|
+
} catch {
|
|
87
|
+
return {
|
|
88
|
+
valid: false,
|
|
89
|
+
error: "Cannot create project: No write permission in current directory."
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
valid: true
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
async function getValidProjectName(initialName, attempts = 0, maxAttempts = 3) {
|
|
97
|
+
const projectName = initialName ?? await utils_prompt("Enter project name: ");
|
|
98
|
+
const validation = validateProjectName(projectName);
|
|
99
|
+
if (validation.valid) return projectName;
|
|
100
|
+
if (attempts >= maxAttempts - 1) throw new Error(`❌ Exceeded maximum attempts to enter a valid project name.`);
|
|
101
|
+
console.error(`❌ ${validation.error} (${maxAttempts - attempts - 1} attempts remaining)`);
|
|
102
|
+
return getValidProjectName(void 0, attempts + 1, maxAttempts);
|
|
103
|
+
}
|
|
104
|
+
async function checkExistingProject(projectNameArg) {
|
|
105
|
+
const packageJsonPath = external_node_path_default().join(process.cwd(), "package.json");
|
|
106
|
+
const packageJsonExists = external_node_fs_default().existsSync(packageJsonPath);
|
|
107
|
+
if (packageJsonExists) {
|
|
108
|
+
console.log(`⚠️ A package.json file has been detected in the current directory.`);
|
|
109
|
+
const confirm = await utils_prompt("Do you want to continue configuring this existing project? [Y/n]: ");
|
|
110
|
+
if ("" === confirm || "y" === confirm.toLowerCase()) {
|
|
111
|
+
const packageJson = JSON.parse(external_node_fs_default().readFileSync(packageJsonPath, "utf8"));
|
|
112
|
+
const projectName = packageJson.name ?? await getValidProjectName(projectNameArg);
|
|
113
|
+
return {
|
|
114
|
+
projectName,
|
|
115
|
+
packageJsonExists
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
console.log("Aborting...");
|
|
119
|
+
throw new Error("User aborted the operation.");
|
|
120
|
+
}
|
|
121
|
+
const projectName = await getValidProjectName(projectNameArg);
|
|
122
|
+
return {
|
|
123
|
+
projectName,
|
|
124
|
+
packageJsonExists
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const MAIN_DEPENDENCIES = [
|
|
128
|
+
"@codefast/ui",
|
|
129
|
+
"@codefast/hooks",
|
|
130
|
+
"recharts",
|
|
131
|
+
"react-hook-form",
|
|
132
|
+
"next-themes",
|
|
133
|
+
"date-fns",
|
|
134
|
+
"lucide-react"
|
|
135
|
+
];
|
|
136
|
+
const DEV_DEPENDENCIES = {
|
|
137
|
+
commitLint: [
|
|
138
|
+
"@commitlint/cli",
|
|
139
|
+
"@commitlint/config-conventional",
|
|
140
|
+
"@commitlint/types"
|
|
141
|
+
],
|
|
142
|
+
gitTools: [
|
|
143
|
+
"simple-git-hooks"
|
|
144
|
+
],
|
|
145
|
+
formatting: [
|
|
146
|
+
"prettier",
|
|
147
|
+
"prettier-plugin-packagejson",
|
|
148
|
+
"prettier-plugin-tailwindcss",
|
|
149
|
+
"lint-staged"
|
|
150
|
+
],
|
|
151
|
+
linting: [
|
|
152
|
+
"@codefast/eslint-config"
|
|
153
|
+
]
|
|
154
|
+
};
|
|
155
|
+
const PACKAGES_TO_REMOVE = [
|
|
156
|
+
"@eslint/eslintrc",
|
|
157
|
+
"eslint-config-next"
|
|
158
|
+
];
|
|
159
|
+
const configGroups = {
|
|
160
|
+
deployment: [
|
|
161
|
+
{
|
|
162
|
+
path: ".vercelignore",
|
|
163
|
+
content: `#-------------------------------------------------------------------------------
|
|
164
|
+
# Dependencies and package managers
|
|
165
|
+
#-------------------------------------------------------------------------------
|
|
166
|
+
|
|
167
|
+
# Node dependencies
|
|
168
|
+
node_modules
|
|
169
|
+
.pnpm-store
|
|
170
|
+
.yarn
|
|
171
|
+
|
|
172
|
+
#-------------------------------------------------------------------------------
|
|
173
|
+
# Development and environment
|
|
174
|
+
#-------------------------------------------------------------------------------
|
|
175
|
+
|
|
176
|
+
# Environment variables (except examples)
|
|
177
|
+
.env*
|
|
178
|
+
!.env.example
|
|
179
|
+
|
|
180
|
+
# Build artifacts
|
|
181
|
+
.next
|
|
182
|
+
build
|
|
183
|
+
dist
|
|
184
|
+
.git
|
|
185
|
+
.github
|
|
186
|
+
.turbo
|
|
187
|
+
.changeset
|
|
188
|
+
.eslintcache
|
|
189
|
+
|
|
190
|
+
# Debug logs
|
|
191
|
+
npm-debug.log*
|
|
192
|
+
yarn-debug.log*
|
|
193
|
+
|
|
194
|
+
#-------------------------------------------------------------------------------
|
|
195
|
+
# Testing
|
|
196
|
+
#-------------------------------------------------------------------------------
|
|
197
|
+
|
|
198
|
+
# Test coverage reports and config snapshots
|
|
199
|
+
coverage
|
|
200
|
+
*.test.*
|
|
201
|
+
*.e2e.*
|
|
202
|
+
|
|
203
|
+
#-------------------------------------------------------------------------------
|
|
204
|
+
# Editor and IDE configuration
|
|
205
|
+
#-------------------------------------------------------------------------------
|
|
206
|
+
|
|
207
|
+
# IDE project files
|
|
208
|
+
.idea
|
|
209
|
+
*.suo
|
|
210
|
+
*.ntvs*
|
|
211
|
+
*.njsproj
|
|
212
|
+
*.sln
|
|
213
|
+
|
|
214
|
+
#-------------------------------------------------------------------------------
|
|
215
|
+
# Operating system files
|
|
216
|
+
#-------------------------------------------------------------------------------
|
|
217
|
+
|
|
218
|
+
# System metadata files
|
|
219
|
+
.DS_Store
|
|
220
|
+
Thumbs.db
|
|
221
|
+
|
|
222
|
+
#-------------------------------------------------------------------------------
|
|
223
|
+
# Deployment
|
|
224
|
+
#-------------------------------------------------------------------------------
|
|
225
|
+
|
|
226
|
+
# Vercel deployment configuration
|
|
227
|
+
.vercel
|
|
228
|
+
`,
|
|
229
|
+
description: "Ignore files that should not be deployed to Vercel"
|
|
230
|
+
}
|
|
231
|
+
],
|
|
232
|
+
formatting: [
|
|
233
|
+
{
|
|
234
|
+
path: "prettier.config.mjs",
|
|
235
|
+
content: `/**
|
|
236
|
+
* @see https://prettier.io/docs/en/configuration.html
|
|
237
|
+
* @type {import('prettier').Config}
|
|
238
|
+
*/
|
|
239
|
+
const config = {
|
|
240
|
+
plugins: ["prettier-plugin-packagejson", "prettier-plugin-tailwindcss"],
|
|
241
|
+
printWidth: 100,
|
|
242
|
+
tailwindAttributes: ["classNames"],
|
|
243
|
+
tailwindFunctions: ["tv"],
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export default config;
|
|
247
|
+
`,
|
|
248
|
+
description: "Prettier configuration for source code formatting"
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
path: ".editorconfig",
|
|
252
|
+
content: `# https://editorconfig.org
|
|
253
|
+
root = true
|
|
254
|
+
|
|
255
|
+
[*]
|
|
256
|
+
charset = utf-8
|
|
257
|
+
insert_final_newline = true
|
|
258
|
+
|
|
259
|
+
end_of_line = lf
|
|
260
|
+
indent_style = space
|
|
261
|
+
indent_size = 2
|
|
262
|
+
max_line_length = 120
|
|
263
|
+
|
|
264
|
+
trim_trailing_whitespace = true
|
|
265
|
+
|
|
266
|
+
[Makefile]
|
|
267
|
+
indent_style = tab
|
|
268
|
+
|
|
269
|
+
[{go.mod,go.sum,*.go}]
|
|
270
|
+
indent_style = tab
|
|
271
|
+
|
|
272
|
+
[*.rs]
|
|
273
|
+
# Keep in sync with rustfmt
|
|
274
|
+
indent_size = 4
|
|
275
|
+
`,
|
|
276
|
+
description: "Editor configuration for source code formatting"
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
path: ".prettierignore",
|
|
280
|
+
content: `# changesets
|
|
281
|
+
.changeset
|
|
282
|
+
|
|
283
|
+
# debug
|
|
284
|
+
npm-debug.log*
|
|
285
|
+
yarn-debug.log*
|
|
286
|
+
yarn-error.log*
|
|
287
|
+
.pnpm-debug.log*
|
|
288
|
+
|
|
289
|
+
# lock files
|
|
290
|
+
package-lock.json
|
|
291
|
+
yarn.lock
|
|
292
|
+
pnpm-lock.yaml
|
|
293
|
+
src/app/globals.css
|
|
294
|
+
`,
|
|
295
|
+
description: ""
|
|
296
|
+
}
|
|
297
|
+
],
|
|
298
|
+
linting: [
|
|
299
|
+
{
|
|
300
|
+
path: "commitlint.config.mjs",
|
|
301
|
+
content: `/**
|
|
302
|
+
* @see https://commitlint.js.org/reference/configuration.html
|
|
303
|
+
* @type {import('@commitlint/types').UserConfig}
|
|
304
|
+
*/
|
|
305
|
+
const config = {
|
|
306
|
+
extends: ["@commitlint/config-conventional"],
|
|
307
|
+
rules: {
|
|
308
|
+
"body-max-line-length": [2, "always", 350],
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
export default config;
|
|
313
|
+
`,
|
|
314
|
+
description: "Commitlint configuration"
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
path: "eslint.config.mjs",
|
|
318
|
+
content: `import { config } from "@codefast/eslint-config/next";
|
|
319
|
+
/**
|
|
320
|
+
* @see https://eslint.org/docs/latest/use/configure/configuration-files
|
|
321
|
+
* @type {import('eslint').Linter.Config[]}
|
|
322
|
+
*/
|
|
323
|
+
const eslintConfig = [...config];
|
|
324
|
+
|
|
325
|
+
export default eslintConfig;
|
|
326
|
+
`,
|
|
327
|
+
description: "ESLint configuration for the project"
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
path: "lint-staged.config.mjs",
|
|
331
|
+
content: `import { relative } from "node:path";
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Builds an ESLint command with the given filenames.
|
|
335
|
+
*
|
|
336
|
+
* @param {string[]} filenames - An array of filenames to be passed to the
|
|
337
|
+
* ESLint command.
|
|
338
|
+
* @returns {string} - The generated ESLint command.
|
|
339
|
+
*/
|
|
340
|
+
function buildEslintCommand(filenames) {
|
|
341
|
+
return \`next lint --fix --max-warnings 0 --file \${filenames.map((file) => relative(import.meta.dirname, file)).
|
|
342
|
+
join(" --file ")}\`;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* @see https://www.npmjs.com/package/lint-staged
|
|
347
|
+
* @type {import('lint-staged').Configuration}
|
|
348
|
+
*/
|
|
349
|
+
const config = {
|
|
350
|
+
"*.{js,mjs,jsx,ts,tsx}": [buildEslintCommand, "prettier --list-different --write"],
|
|
351
|
+
"*.{json,css,md,mdx}": ["prettier --list-different --write"],
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
export default config;
|
|
355
|
+
`,
|
|
356
|
+
description: "Configure lint-staged for pre-commit checks"
|
|
357
|
+
}
|
|
358
|
+
],
|
|
359
|
+
styles: [
|
|
360
|
+
{
|
|
361
|
+
path: "src/lib/fonts.ts",
|
|
362
|
+
content: `import { cn } from "@codefast/ui";
|
|
363
|
+
import { Geist, Geist_Mono as GeistMono } from "next/font/google";
|
|
364
|
+
|
|
365
|
+
const fontGeistSans = Geist({
|
|
366
|
+
subsets: ["latin"],
|
|
367
|
+
variable: "--font-geist-sans",
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const fontGeistMono = GeistMono({
|
|
371
|
+
subsets: ["latin"],
|
|
372
|
+
variable: "--font-geist-mono",
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
|
|
376
|
+
`,
|
|
377
|
+
description: "Font configuration for the application"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
path: "src/app/globals.css",
|
|
381
|
+
content: `@import "tailwindcss";
|
|
382
|
+
|
|
383
|
+
@import "@codefast/ui/styles.css";
|
|
384
|
+
|
|
385
|
+
@source '../../node_modules/@codefast/ui';
|
|
386
|
+
|
|
387
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
388
|
+
|
|
389
|
+
@layer base {
|
|
390
|
+
:root {
|
|
391
|
+
--font-sans: var(--font-geist-sans);
|
|
392
|
+
--font-mono: var(--font-geist-mono);
|
|
393
|
+
--input: var(--color-neutral-200);
|
|
394
|
+
--border: var(--color-neutral-200);
|
|
395
|
+
--ring: var(--color-neutral-400);
|
|
396
|
+
--background: var(--color-white);
|
|
397
|
+
--foreground: var(--color-neutral-950);
|
|
398
|
+
--primary: var(--color-sky-500);
|
|
399
|
+
--primary-foreground: var(--color-neutral-50);
|
|
400
|
+
--secondary: var(--color-neutral-100);
|
|
401
|
+
--secondary-foreground: var(--color-neutral-900);
|
|
402
|
+
--destructive: var(--color-red-600);
|
|
403
|
+
--accent: var(--color-neutral-100);
|
|
404
|
+
--accent-foreground: var(--color-neutral-900);
|
|
405
|
+
--muted: var(--color-neutral-100);
|
|
406
|
+
--muted-foreground: var(--color-neutral-500);
|
|
407
|
+
--popover: var(--color-white);
|
|
408
|
+
--popover-foreground: var(--color-neutral-950);
|
|
409
|
+
--popover-overlay: --alpha(var(--color-neutral-900) / 20%);
|
|
410
|
+
--card: var(--color-white);
|
|
411
|
+
--card-foreground: var(--color-neutral-950);
|
|
412
|
+
--sidebar: var(--color-neutral-50);
|
|
413
|
+
--sidebar-foreground: var(--color-neutral-950);
|
|
414
|
+
--sidebar-primary: var(--color-sky-500);
|
|
415
|
+
--sidebar-primary-foreground: var(--color-neutral-50);
|
|
416
|
+
--sidebar-accent: var(--color-neutral-100);
|
|
417
|
+
--sidebar-accent-foreground: var(--color-neutral-900);
|
|
418
|
+
--sidebar-border: var(--color-neutral-200);
|
|
419
|
+
--sidebar-ring: var(--color-neutral-400);
|
|
420
|
+
--chart-1: var(--color-orange-600);
|
|
421
|
+
--chart-2: var(--color-teal-600);
|
|
422
|
+
--chart-3: var(--color-cyan-600);
|
|
423
|
+
--chart-4: var(--color-amber-600);
|
|
424
|
+
--chart-5: var(--color-amber-500);
|
|
425
|
+
}
|
|
426
|
+
.dark {
|
|
427
|
+
--input: var(--color-neutral-700);
|
|
428
|
+
--border: --alpha(var(--color-neutral-700) / 50%);
|
|
429
|
+
--ring: var(--color-neutral-500);
|
|
430
|
+
--background: var(--color-neutral-950);
|
|
431
|
+
--foreground: var(--color-neutral-50);
|
|
432
|
+
--primary: var(--color-sky-700);
|
|
433
|
+
--primary-foreground: var(--color-neutral-50);
|
|
434
|
+
--secondary: var(--color-neutral-800);
|
|
435
|
+
--secondary-foreground: var(--color-neutral-50);
|
|
436
|
+
--destructive: var(--color-red-400);
|
|
437
|
+
--accent: var(--color-neutral-700);
|
|
438
|
+
--accent-foreground: var(--color-neutral-50);
|
|
439
|
+
--muted: var(--color-neutral-800);
|
|
440
|
+
--muted-foreground: var(--color-neutral-400);
|
|
441
|
+
--popover: var(--color-neutral-800);
|
|
442
|
+
--popover-foreground: var(--color-neutral-50);
|
|
443
|
+
--popover-overlay: --alpha(var(--color-neutral-900) / 80%);
|
|
444
|
+
--card: var(--color-neutral-900);
|
|
445
|
+
--card-foreground: var(--color-neutral-50);
|
|
446
|
+
--sidebar: var(--color-neutral-900);
|
|
447
|
+
--sidebar-foreground: var(--color-neutral-50);
|
|
448
|
+
--sidebar-primary: var(--color-sky-700);
|
|
449
|
+
--sidebar-primary-foreground: var(--color-neutral-50);
|
|
450
|
+
--sidebar-accent: var(--color-neutral-800);
|
|
451
|
+
--sidebar-accent-foreground: var(--color-neutral-50);
|
|
452
|
+
--sidebar-border: var(--color-neutral-800);
|
|
453
|
+
--sidebar-ring: var(--color-neutral-600);
|
|
454
|
+
--chart-1: var(--color-blue-700);
|
|
455
|
+
--chart-2: var(--color-emerald-500);
|
|
456
|
+
--chart-3: var(--color-amber-500);
|
|
457
|
+
--chart-4: var(--color-purple-500);
|
|
458
|
+
--chart-5: var(--color-rose-500);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
`,
|
|
462
|
+
description: "Global CSS variables for the application"
|
|
463
|
+
}
|
|
464
|
+
]
|
|
465
|
+
};
|
|
466
|
+
function updatePostcssConfig(projectDir) {
|
|
467
|
+
const postcssConfigPath = external_node_path_default().join(projectDir, "postcss.config.mjs");
|
|
468
|
+
if (!external_node_fs_default().existsSync(postcssConfigPath)) return void console.warn(`⚠️ postcss.config.mjs not found, skipping update.`);
|
|
469
|
+
let content = external_node_fs_default().readFileSync(postcssConfigPath, "utf8");
|
|
470
|
+
const typeComment = `/** @type {import('postcss-load-config').Config} */\n`;
|
|
471
|
+
if (content.includes(typeComment)) console.log(`📝 postcss.config.mjs already contains type comment, no changes made.`);
|
|
472
|
+
else {
|
|
473
|
+
content = content.replace("const config = {", `${typeComment}const config = {`);
|
|
474
|
+
external_node_fs_default().writeFileSync(postcssConfigPath, content);
|
|
475
|
+
console.log(`📝 Updated postcss.config.mjs with type comment.`);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
function updateLayoutFile(projectDir) {
|
|
479
|
+
const layoutPath = external_node_path_default().join(projectDir, "src/app/layout.tsx");
|
|
480
|
+
if (!external_node_fs_default().existsSync(layoutPath)) return void console.warn(`⚠️ src/app/layout.tsx not found, skipping update.`);
|
|
481
|
+
let content = external_node_fs_default().readFileSync(layoutPath, "utf8");
|
|
482
|
+
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.`);
|
|
483
|
+
const newImports = `import type { Metadata } from "next";
|
|
484
|
+
|
|
485
|
+
import { cn } from "@codefast/ui";
|
|
486
|
+
|
|
487
|
+
import { fontVariables } from "@/lib/fonts";
|
|
488
|
+
import "@/app/globals.css";`;
|
|
489
|
+
content = content.replaceAll(/import\s+{[^}]+}\s+from\s+["']next\/font\/google["'];\s*/g, "");
|
|
490
|
+
content = content.replace(/const\s+geistSans\s*=[^;]+;\s*const\s+geistMono\s*=[^;]+;\s*/, "");
|
|
491
|
+
content = content.replace(/import\s+type\s+{[^}]+}\s+from\s+["']next["'];\s*import\s+["']\.\/globals\.css["'];\s*/, newImports);
|
|
492
|
+
const htmlRegex = /<html\s+lang="en"\s*>/;
|
|
493
|
+
const newHtml = '<html className={cn(fontVariables, "antialiased")} lang="en">';
|
|
494
|
+
content = content.replace(htmlRegex, newHtml);
|
|
495
|
+
const bodyRegex = /<body\s+className={`[^`]*`}\s*>/;
|
|
496
|
+
const newBody = "<body>";
|
|
497
|
+
content = content.replace(bodyRegex, newBody);
|
|
498
|
+
try {
|
|
499
|
+
external_node_fs_default().writeFileSync(layoutPath, content);
|
|
500
|
+
console.log(`📝 Updated src/app/layout.tsx to use fontVariables in html tag and removed className from body`);
|
|
501
|
+
} catch (error) {
|
|
502
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
503
|
+
console.warn(`⚠️ Failed to update src/app/layout.tsx: ${errorMessage}`);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
function updatePackageJson(projectDir) {
|
|
507
|
+
const packageJsonPath = external_node_path_default().join(projectDir, "package.json");
|
|
508
|
+
const packageJson = JSON.parse(external_node_fs_default().readFileSync(packageJsonPath, "utf8"));
|
|
509
|
+
packageJson.scripts = {
|
|
510
|
+
...packageJson.scripts,
|
|
511
|
+
"deploy:preview": "vercel deploy --archive=tgz",
|
|
512
|
+
"deploy:prod": "vercel deploy --archive=tgz --prod",
|
|
513
|
+
format: "prettier --write --ignore-unknown .",
|
|
514
|
+
"format:check": "prettier --check --ignore-unknown .",
|
|
515
|
+
lint: "next lint --fix --max-warnings 0",
|
|
516
|
+
"lint:check": "next lint --max-warnings 0",
|
|
517
|
+
"package:install": "pnpm install",
|
|
518
|
+
"package:outdated": "pnpm outdated",
|
|
519
|
+
"package:upgrade": "pnpm update --latest",
|
|
520
|
+
preview: "pnpm build && pnpm start"
|
|
521
|
+
};
|
|
522
|
+
packageJson["simple-git-hooks"] = {
|
|
523
|
+
"pre-commit": "pnpm lint-staged",
|
|
524
|
+
"commit-msg": "pnpm commitlint --edit"
|
|
525
|
+
};
|
|
526
|
+
external_node_fs_default().writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
527
|
+
console.log(`📝 Updated package.json`);
|
|
528
|
+
}
|
|
529
|
+
function updateNextConfig(projectDir) {
|
|
530
|
+
const nextConfigPath = external_node_path_default().join(projectDir, "next.config.ts");
|
|
531
|
+
if (!external_node_fs_default().existsSync(nextConfigPath)) return void console.warn(`⚠️ next.config.ts not found, skipping update.`);
|
|
532
|
+
let content = external_node_fs_default().readFileSync(nextConfigPath, "utf8");
|
|
533
|
+
if (content.includes('optimizePackageImports: ["@codefast/ui"]')) return void console.log(`📝 next.config.ts already contains optimizePackageImports configuration, no changes made.`);
|
|
534
|
+
const configPattern = /const nextConfig: NextConfig = \{/;
|
|
535
|
+
const experimentalConfig = `const nextConfig: NextConfig = {
|
|
536
|
+
experimental: {
|
|
537
|
+
optimizePackageImports: ["@codefast/ui"],
|
|
538
|
+
},`;
|
|
539
|
+
content = content.replace(configPattern, experimentalConfig);
|
|
540
|
+
try {
|
|
541
|
+
external_node_fs_default().writeFileSync(nextConfigPath, content);
|
|
542
|
+
console.log(`📝 Updated next.config.ts with optimizePackageImports configuration.`);
|
|
543
|
+
} catch (error) {
|
|
544
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
545
|
+
console.warn(`⚠️ Failed to update next.config.ts: ${errorMessage}`);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
function createConfigFiles(projectDir) {
|
|
549
|
+
console.log(`\n📝 Creating configuration files...`);
|
|
550
|
+
for (const [category, configs] of Object.entries(configGroups)){
|
|
551
|
+
console.log(`\n📂 Setting up ${category} configurations:`);
|
|
552
|
+
for (const { path: filePath, content, description } of configs){
|
|
553
|
+
const fullPath = external_node_path_default().join(projectDir, filePath);
|
|
554
|
+
const dir = external_node_path_default().dirname(fullPath);
|
|
555
|
+
if (!external_node_fs_default().existsSync(dir)) external_node_fs_default().mkdirSync(dir, {
|
|
556
|
+
recursive: true
|
|
557
|
+
});
|
|
558
|
+
writeConfigFile(fullPath, content);
|
|
559
|
+
if (description) console.log(` ℹ️ ${filePath}: ${description}`);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
function installDependencies() {
|
|
564
|
+
console.log(`\n📚 Installing dependencies...`);
|
|
565
|
+
if (MAIN_DEPENDENCIES.length > 0) runCommand(`pnpm add ${MAIN_DEPENDENCIES.join(" ")}`);
|
|
566
|
+
const allDevDependencies = Object.values(DEV_DEPENDENCIES).flat().join(" ");
|
|
567
|
+
if (allDevDependencies) runCommand(`pnpm add -D ${allDevDependencies}`);
|
|
568
|
+
}
|
|
569
|
+
function cleanupPackages() {
|
|
570
|
+
console.log(`\n🧹 Cleaning up unnecessary packages...`);
|
|
571
|
+
const packageJsonPath = external_node_path_namespaceObject.join(process.cwd(), "package.json");
|
|
572
|
+
if (!external_node_fs_namespaceObject.existsSync(packageJsonPath)) return void console.warn(`⚠️ package.json not found, skipping cleanup.`);
|
|
573
|
+
let packageJson;
|
|
574
|
+
try {
|
|
575
|
+
packageJson = JSON.parse(external_node_fs_namespaceObject.readFileSync(packageJsonPath, "utf8"));
|
|
576
|
+
} catch (error) {
|
|
577
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
578
|
+
console.warn(`⚠️ Error reading package.json: ${errorMessage}, skipping cleanup.`);
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
const dependencies = packageJson.dependencies ?? {};
|
|
582
|
+
const devDependencies = packageJson.devDependencies ?? {};
|
|
583
|
+
const packagesToRemove = PACKAGES_TO_REMOVE.filter((pkg)=>pkg in dependencies || pkg in devDependencies);
|
|
584
|
+
if (packagesToRemove.length > 0) runCommand(`pnpm remove ${packagesToRemove.join(" ")}`);
|
|
585
|
+
else console.log(`ℹ️ No unnecessary packages found in package.json to remove.`);
|
|
586
|
+
}
|
|
587
|
+
function checkEnvironment() {
|
|
588
|
+
try {
|
|
589
|
+
(0, external_node_child_process_namespaceObject.execSync)("pnpm --version", {
|
|
590
|
+
stdio: "ignore"
|
|
591
|
+
});
|
|
592
|
+
} catch {
|
|
593
|
+
console.error(`❌ PNPM chưa được cài đặt. Vui lòng cài đặt PNPM trước.`);
|
|
594
|
+
process.exit(1);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
function createNextProject(projectName) {
|
|
598
|
+
console.log(`📦 Creating Next.js project...`);
|
|
599
|
+
const flags = '--ts --tailwind --eslint --app --turbo --use-pnpm --src-dir --turbopack --import-alias "@/*"';
|
|
600
|
+
runCommand(`npx create-next-app@latest ${projectName} ${flags}`);
|
|
601
|
+
}
|
|
602
|
+
function createProjectCommand(program) {
|
|
603
|
+
program.command("create-project [name]").description("Create a new Next.js project with recommended setup").action(async (projectNameArg)=>{
|
|
604
|
+
try {
|
|
605
|
+
checkEnvironment();
|
|
606
|
+
const { projectName, packageJsonExists } = await checkExistingProject(projectNameArg);
|
|
607
|
+
if (!packageJsonExists) {
|
|
608
|
+
console.log(`\n🚀 Starting project creation for ${projectName}...\n`);
|
|
609
|
+
createNextProject(projectName);
|
|
610
|
+
process.chdir(projectName);
|
|
611
|
+
console.log(`📂 Moved to ${projectName}`);
|
|
612
|
+
}
|
|
613
|
+
updateLayoutFile(process.cwd());
|
|
614
|
+
updatePostcssConfig(process.cwd());
|
|
615
|
+
installDependencies();
|
|
616
|
+
cleanupPackages();
|
|
617
|
+
createConfigFiles(process.cwd());
|
|
618
|
+
updateNextConfig(process.cwd());
|
|
619
|
+
updatePackageJson(process.cwd());
|
|
620
|
+
console.log(`\n🔄 Activating git hooks...`);
|
|
621
|
+
runCommand("pnpm simple-git-hooks");
|
|
622
|
+
console.log(`\n📝 Formatting files with Prettier...`);
|
|
623
|
+
runCommand("pnpm format");
|
|
624
|
+
console.log(`\n✅ Project ${packageJsonExists ? "configured" : "created"} successfully!`);
|
|
625
|
+
console.log(`- Project: ${projectName}`);
|
|
626
|
+
console.log("- Next.js with TypeScript");
|
|
627
|
+
console.log("- TailwindCSS and @codefast/ui");
|
|
628
|
+
console.log("- ESLint, Prettier, Commitlint, and Git Hooks");
|
|
629
|
+
console.log("- Lint-staged for pre-commit checks");
|
|
630
|
+
console.log(`\n📁 Project directory: ${process.cwd()}`);
|
|
631
|
+
console.log(`\n🚀 To start development:`);
|
|
632
|
+
console.log(`cd ${projectName} && pnpm dev`);
|
|
633
|
+
} catch (error) {
|
|
634
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
635
|
+
console.error(`\n❌ An error occurred: ${errorMessage}`);
|
|
636
|
+
process.exit(1);
|
|
637
|
+
} finally{
|
|
638
|
+
rl.close();
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
const external_glob_namespaceObject = require("glob");
|
|
643
|
+
const external_ts_morph_namespaceObject = require("ts-morph");
|
|
644
|
+
function makeRegexPrefixesToRemove(prefixes) {
|
|
645
|
+
const prefixPattern = prefixes.join("|");
|
|
646
|
+
return new RegExp(`^.?\\/?(?:${prefixPattern})\\/(.*)$`);
|
|
647
|
+
}
|
|
648
|
+
function processExportPath(modulePath, regexPattern) {
|
|
649
|
+
let processedPath = modulePath;
|
|
650
|
+
const match = processedPath.match(regexPattern);
|
|
651
|
+
if (match) {
|
|
652
|
+
const remainingPath = match[1];
|
|
653
|
+
processedPath = remainingPath.startsWith("./") ? remainingPath : `./${remainingPath}`;
|
|
654
|
+
}
|
|
655
|
+
return processedPath;
|
|
656
|
+
}
|
|
657
|
+
function analyzeImports(indexFilePath, packageConfig) {
|
|
658
|
+
const project = new external_ts_morph_namespaceObject.Project();
|
|
659
|
+
let sourceFile;
|
|
660
|
+
try {
|
|
661
|
+
sourceFile = project.addSourceFileAtPath(indexFilePath);
|
|
662
|
+
} catch (error) {
|
|
663
|
+
console.error(`Error loading source file at ${indexFilePath}:`, error);
|
|
664
|
+
return {
|
|
665
|
+
imports: []
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
const imports = [];
|
|
669
|
+
const prefixesToRemove = packageConfig.exportPathPrefixesToRemove ?? [];
|
|
670
|
+
const regexPattern = makeRegexPrefixesToRemove(prefixesToRemove);
|
|
671
|
+
for (const exportDecl of sourceFile.getExportDeclarations()){
|
|
672
|
+
let moduleSpecifier = exportDecl.getModuleSpecifierValue();
|
|
673
|
+
if (!moduleSpecifier) continue;
|
|
674
|
+
if (moduleSpecifier.startsWith("@/")) moduleSpecifier = `./${moduleSpecifier.slice(2)}`;
|
|
675
|
+
const isExternal = !moduleSpecifier.startsWith(".");
|
|
676
|
+
if (isExternal) continue;
|
|
677
|
+
const parts = moduleSpecifier.split("/").filter(Boolean);
|
|
678
|
+
if (parts.length < 2) continue;
|
|
679
|
+
let directory;
|
|
680
|
+
if (parts.length <= 1) directory = ".";
|
|
681
|
+
else {
|
|
682
|
+
directory = parts.slice(0, -1).join("/");
|
|
683
|
+
if (directory.startsWith("./")) directory = directory.slice(2);
|
|
684
|
+
}
|
|
685
|
+
const name = parts.at(-1) ?? "";
|
|
686
|
+
const importPath = {
|
|
687
|
+
originalPath: moduleSpecifier,
|
|
688
|
+
directory,
|
|
689
|
+
name,
|
|
690
|
+
exportPath: processExportPath(moduleSpecifier, regexPattern)
|
|
691
|
+
};
|
|
692
|
+
imports.push(importPath);
|
|
693
|
+
}
|
|
694
|
+
return {
|
|
695
|
+
imports
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
const external_lodash_es_namespaceObject = require("lodash-es");
|
|
699
|
+
const external_zod_namespaceObject = require("zod");
|
|
700
|
+
const PackageConfigSchema = external_zod_namespaceObject.z["interface"]({
|
|
701
|
+
cjsOutputPattern: external_zod_namespaceObject.z.string(),
|
|
702
|
+
esmOutputPattern: external_zod_namespaceObject.z.string(),
|
|
703
|
+
packageJsonPath: external_zod_namespaceObject.z.string(),
|
|
704
|
+
srcIndexPath: external_zod_namespaceObject.z.string(),
|
|
705
|
+
typesOutputCjsPattern: external_zod_namespaceObject.z.string(),
|
|
706
|
+
typesOutputPattern: external_zod_namespaceObject.z.string(),
|
|
707
|
+
"exportPathPrefixesToRemove?": external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string())
|
|
708
|
+
});
|
|
709
|
+
const ScriptConfigSchema = external_zod_namespaceObject.z["interface"]({
|
|
710
|
+
customPackageConfigs: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.string(), PackageConfigSchema.partial()),
|
|
711
|
+
defaultPackageConfig: PackageConfigSchema,
|
|
712
|
+
packagesGlob: external_zod_namespaceObject.z.string()
|
|
713
|
+
});
|
|
714
|
+
let cachedConfig = null;
|
|
715
|
+
function loadConfigFile(configPath) {
|
|
716
|
+
if (!configPath) return {};
|
|
717
|
+
try {
|
|
718
|
+
const fullPath = external_node_path_default().resolve(configPath);
|
|
719
|
+
if (!external_node_fs_default().existsSync(fullPath)) {
|
|
720
|
+
console.warn(`Configuration file not found at ${fullPath}`);
|
|
721
|
+
return {};
|
|
722
|
+
}
|
|
723
|
+
const configContent = external_node_fs_default().readFileSync(fullPath, "utf8");
|
|
724
|
+
const config = JSON.parse(configContent);
|
|
725
|
+
return ScriptConfigSchema.parse(config);
|
|
726
|
+
} catch (error) {
|
|
727
|
+
console.error("Error reading configuration file:", error);
|
|
728
|
+
return {};
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
function getConfig(configPath) {
|
|
732
|
+
if (cachedConfig && !configPath) return cachedConfig;
|
|
733
|
+
const userConfig = loadConfigFile(configPath);
|
|
734
|
+
const config = (0, external_lodash_es_namespaceObject.merge)({}, defaultConfig, userConfig);
|
|
735
|
+
if (!configPath) cachedConfig = config;
|
|
736
|
+
return config;
|
|
737
|
+
}
|
|
738
|
+
function getPackageConfig(packageName, config) {
|
|
739
|
+
const configObj = config ?? getConfig();
|
|
740
|
+
const customConfig = configObj.customPackageConfigs[packageName] ?? {};
|
|
741
|
+
return {
|
|
742
|
+
...configObj.defaultPackageConfig,
|
|
743
|
+
...customConfig
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
const defaultConfig = {
|
|
747
|
+
packagesGlob: "./packages/**/package.json",
|
|
748
|
+
defaultPackageConfig: {
|
|
749
|
+
cjsOutputPattern: "./dist/cjs/{dir}/{name}.cjs",
|
|
750
|
+
esmOutputPattern: "./dist/esm/{dir}/{name}.js",
|
|
751
|
+
packageJsonPath: "package.json",
|
|
752
|
+
srcIndexPath: "src/index.ts",
|
|
753
|
+
typesOutputCjsPattern: "./dist/types/{dir}/{name}.d.ts",
|
|
754
|
+
typesOutputPattern: "./dist/types/{dir}/{name}.d.ts"
|
|
755
|
+
},
|
|
756
|
+
customPackageConfigs: {
|
|
757
|
+
"@codefast/ui": {
|
|
758
|
+
exportPathPrefixesToRemove: [
|
|
759
|
+
"components"
|
|
760
|
+
]
|
|
761
|
+
},
|
|
762
|
+
"@codefast/style-guide": {
|
|
763
|
+
exportPathPrefixesToRemove: [
|
|
764
|
+
"configs"
|
|
765
|
+
]
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
};
|
|
769
|
+
const EXPORTS_ANALYSIS_DIR = ".exports-analysis";
|
|
770
|
+
const EXPORTS_PREVIEW_FILE = "exports-preview.json";
|
|
771
|
+
const EXPORTS_ANALYSIS_FILE = "exports-analysis.json";
|
|
772
|
+
const ENCODING = "utf8";
|
|
773
|
+
const JSON_INDENT = 2;
|
|
774
|
+
const FileUtils = {
|
|
775
|
+
exists (filePath) {
|
|
776
|
+
return external_node_fs_default().existsSync(filePath);
|
|
777
|
+
},
|
|
778
|
+
ensureDirectoryExists (dirPath) {
|
|
779
|
+
if (!external_node_fs_default().existsSync(dirPath)) external_node_fs_default().mkdirSync(dirPath, {
|
|
780
|
+
recursive: true
|
|
781
|
+
});
|
|
782
|
+
},
|
|
783
|
+
readJsonFile (filePath) {
|
|
784
|
+
try {
|
|
785
|
+
const content = external_node_fs_default().readFileSync(filePath, ENCODING);
|
|
786
|
+
return JSON.parse(content);
|
|
787
|
+
} catch (error) {
|
|
788
|
+
console.error(`Error reading JSON file at ${filePath}:`, error);
|
|
789
|
+
return null;
|
|
790
|
+
}
|
|
791
|
+
},
|
|
792
|
+
writeJsonFile (filePath, content) {
|
|
793
|
+
try {
|
|
794
|
+
external_node_fs_default().writeFileSync(filePath, `${JSON.stringify(content, null, JSON_INDENT)}\n`, ENCODING);
|
|
795
|
+
return true;
|
|
796
|
+
} catch (error) {
|
|
797
|
+
console.error(`Error writing JSON file at ${filePath}:`, error);
|
|
798
|
+
return false;
|
|
799
|
+
}
|
|
800
|
+
},
|
|
801
|
+
getAnalysisDir (packageDir) {
|
|
802
|
+
const outputDir = external_node_path_default().join(packageDir, EXPORTS_ANALYSIS_DIR);
|
|
803
|
+
this.ensureDirectoryExists(outputDir);
|
|
804
|
+
return outputDir;
|
|
805
|
+
},
|
|
806
|
+
createBackupFilename (baseFilename) {
|
|
807
|
+
const timestamp = new Date().toISOString().replaceAll(/[:.]/g, "-");
|
|
808
|
+
return `${baseFilename}.backup.${timestamp}`;
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
function fileExists(filePath) {
|
|
812
|
+
return FileUtils.exists(filePath);
|
|
813
|
+
}
|
|
814
|
+
function readPackageJson(filePath) {
|
|
815
|
+
return FileUtils.readJsonFile(filePath);
|
|
816
|
+
}
|
|
817
|
+
function backupPackageJson(filePath) {
|
|
818
|
+
try {
|
|
819
|
+
const content = external_node_fs_default().readFileSync(filePath, ENCODING);
|
|
820
|
+
const dir = external_node_path_default().dirname(filePath);
|
|
821
|
+
const backupDir = external_node_path_default().join(dir, EXPORTS_ANALYSIS_DIR);
|
|
822
|
+
FileUtils.ensureDirectoryExists(backupDir);
|
|
823
|
+
const baseName = external_node_path_default().basename(filePath);
|
|
824
|
+
const backupPath = external_node_path_default().join(backupDir, FileUtils.createBackupFilename(baseName));
|
|
825
|
+
external_node_fs_default().writeFileSync(backupPath, content, ENCODING);
|
|
826
|
+
return true;
|
|
827
|
+
} catch (error) {
|
|
828
|
+
console.error(`Error backing up package.json at ${filePath}:`, error);
|
|
829
|
+
return false;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
function savePackageJson(filePath, content) {
|
|
833
|
+
return FileUtils.writeJsonFile(filePath, content);
|
|
834
|
+
}
|
|
835
|
+
function saveJsonToFile(packageDir, fileName, content) {
|
|
836
|
+
const outputDir = FileUtils.getAnalysisDir(packageDir);
|
|
837
|
+
FileUtils.writeJsonFile(external_node_path_default().join(outputDir, fileName), content);
|
|
838
|
+
}
|
|
839
|
+
function saveExportsAnalysis(packageDir, analysis) {
|
|
840
|
+
saveJsonToFile(packageDir, EXPORTS_ANALYSIS_FILE, analysis);
|
|
841
|
+
}
|
|
842
|
+
function saveExportsPreview(packageDir, exports1) {
|
|
843
|
+
saveJsonToFile(packageDir, EXPORTS_PREVIEW_FILE, exports1);
|
|
844
|
+
}
|
|
845
|
+
function formatOutputPath(pattern, directory, name) {
|
|
846
|
+
const dirPart = "." === directory ? "" : `${directory}/`;
|
|
847
|
+
return pattern.replace("{dir}/", dirPart).replace("{dir}", directory).replace("{name}", name);
|
|
848
|
+
}
|
|
849
|
+
function generateExports(packageName, imports, existingExports = {}, config) {
|
|
850
|
+
const packageConfig = getPackageConfig(packageName, config);
|
|
851
|
+
const exports1 = {
|
|
852
|
+
".": existingExports["."] ?? {
|
|
853
|
+
import: {
|
|
854
|
+
types: "./dist/types/index.d.ts",
|
|
855
|
+
default: "./dist/esm/index.js"
|
|
856
|
+
},
|
|
857
|
+
require: {
|
|
858
|
+
types: "./dist/types/index.d.cts",
|
|
859
|
+
default: "./dist/cjs/index.cjs"
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
};
|
|
863
|
+
if (existingExports["./styles.css"]) exports1["./styles.css"] = existingExports["./styles.css"];
|
|
864
|
+
for (const importPath of imports){
|
|
865
|
+
const { directory, name, exportPath } = importPath;
|
|
866
|
+
const esmOutput = formatOutputPath(packageConfig.esmOutputPattern, directory, name);
|
|
867
|
+
const cjsOutput = formatOutputPath(packageConfig.cjsOutputPattern, directory, name);
|
|
868
|
+
const typesOutput = formatOutputPath(packageConfig.typesOutputPattern, directory, name);
|
|
869
|
+
const typesCjsOutput = formatOutputPath(packageConfig.typesOutputCjsPattern, directory, name);
|
|
870
|
+
exports1[exportPath] = {
|
|
871
|
+
import: {
|
|
872
|
+
types: typesOutput,
|
|
873
|
+
default: esmOutput
|
|
874
|
+
},
|
|
875
|
+
require: {
|
|
876
|
+
types: typesCjsOutput,
|
|
877
|
+
default: cjsOutput
|
|
878
|
+
}
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
return exports1;
|
|
882
|
+
}
|
|
883
|
+
const DEFAULT_IGNORE_PATTERN = [
|
|
884
|
+
"**/node_modules/**"
|
|
885
|
+
];
|
|
886
|
+
async function findAllPackages(config) {
|
|
887
|
+
const configObj = config ?? getConfig();
|
|
888
|
+
return await (0, external_glob_namespaceObject.glob)(configObj.packagesGlob, {
|
|
889
|
+
ignore: DEFAULT_IGNORE_PATTERN
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
function processPackage(packageJsonPath, options) {
|
|
893
|
+
const packageDir = external_node_path_default().dirname(packageJsonPath);
|
|
894
|
+
const packageJson = readPackageJson(packageJsonPath);
|
|
895
|
+
if (!packageJson) {
|
|
896
|
+
console.error(`Failed to read ${packageJsonPath}`);
|
|
897
|
+
return false;
|
|
898
|
+
}
|
|
899
|
+
const packageName = packageJson.name;
|
|
900
|
+
if (options.packageFilter && packageName !== options.packageFilter) {
|
|
901
|
+
console.debug(`Skipping ${packageName} (does not match filter)`);
|
|
902
|
+
return false;
|
|
903
|
+
}
|
|
904
|
+
console.info(`Processing package: ${packageName}`);
|
|
905
|
+
const config = getConfig(options.configPath);
|
|
906
|
+
const packageConfig = getPackageConfig(packageName, config);
|
|
907
|
+
const srcIndexPath = external_node_path_default().join(packageDir, packageConfig.srcIndexPath);
|
|
908
|
+
if (!fileExists(srcIndexPath)) {
|
|
909
|
+
console.error(`Source file not found at ${srcIndexPath}`);
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
console.info(`Analyzing imports from ${srcIndexPath}...`);
|
|
913
|
+
const { imports } = analyzeImports(srcIndexPath, packageConfig);
|
|
914
|
+
if (0 === imports.length) {
|
|
915
|
+
console.warn(`No imports found to analyze in ${packageName}`);
|
|
916
|
+
return false;
|
|
917
|
+
}
|
|
918
|
+
console.log(`Analysis complete. Found ${imports.length} subpath exports.`);
|
|
919
|
+
saveExportsAnalysis(packageDir, {
|
|
920
|
+
imports
|
|
921
|
+
});
|
|
922
|
+
const newExports = generateExports(packageName, imports, packageJson.exports, config);
|
|
923
|
+
const currentExportsCount = packageJson.exports ? Object.keys(packageJson.exports).length : 0;
|
|
924
|
+
const newExportsCount = Object.keys(newExports).length;
|
|
925
|
+
console.info(`Exports: ${currentExportsCount} -> ${newExportsCount}`);
|
|
926
|
+
if (options.dryRun) {
|
|
927
|
+
saveExportsPreview(packageDir, newExports);
|
|
928
|
+
console.warn("Saved exports preview to .exports-analysis");
|
|
929
|
+
console.warn(`Dry run: no changes saved for ${packageName}`);
|
|
930
|
+
return true;
|
|
931
|
+
}
|
|
932
|
+
if (backupPackageJson(packageJsonPath)) console.log(`Backed up ${packageJsonPath}`);
|
|
933
|
+
const updatedPackageJson = {
|
|
934
|
+
...packageJson,
|
|
935
|
+
exports: newExports
|
|
936
|
+
};
|
|
937
|
+
if (savePackageJson(packageJsonPath, updatedPackageJson)) {
|
|
938
|
+
console.log(`Updated exports for ${packageName}`);
|
|
939
|
+
return true;
|
|
940
|
+
}
|
|
941
|
+
console.error(`Failed to update ${packageJsonPath}`);
|
|
942
|
+
return false;
|
|
943
|
+
}
|
|
944
|
+
async function processAllPackages(options) {
|
|
945
|
+
try {
|
|
946
|
+
console.info("Searching for packages...");
|
|
947
|
+
const config = getConfig(options.configPath);
|
|
948
|
+
const packageJsonPaths = await findAllPackages(config);
|
|
949
|
+
if (0 === packageJsonPaths.length) return void console.warn("No packages found.");
|
|
950
|
+
console.log(`Found ${packageJsonPaths.length} packages.`);
|
|
951
|
+
let successCount = 0;
|
|
952
|
+
let skipCount = 0;
|
|
953
|
+
let errorCount = 0;
|
|
954
|
+
for (const packageJsonPath of packageJsonPaths){
|
|
955
|
+
const result = processPackage(packageJsonPath, options);
|
|
956
|
+
if (result) successCount++;
|
|
957
|
+
else if (options.packageFilter) skipCount++;
|
|
958
|
+
else errorCount++;
|
|
959
|
+
}
|
|
960
|
+
console.log("Completed exports update.");
|
|
961
|
+
console.info(`Stats: ${successCount} succeeded, ${skipCount} skipped, ${errorCount} failed`);
|
|
962
|
+
} catch (error) {
|
|
963
|
+
console.error("Error processing packages:", error);
|
|
964
|
+
throw error;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
function createUpdateExportsCommand(program) {
|
|
968
|
+
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)=>{
|
|
969
|
+
const processorOptions = {
|
|
970
|
+
packageFilter: options.package,
|
|
971
|
+
dryRun: Boolean(options.dryRun),
|
|
972
|
+
configPath: options.config
|
|
973
|
+
};
|
|
974
|
+
try {
|
|
975
|
+
await processAllPackages(processorOptions);
|
|
976
|
+
} catch (error) {
|
|
977
|
+
console.error("Error processing packages:", error);
|
|
978
|
+
process.exit(1);
|
|
979
|
+
}
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
const external_node_url_namespaceObject = require("node:url");
|
|
983
|
+
function getPackageInfo() {
|
|
984
|
+
const __filename1 = (0, external_node_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__);
|
|
985
|
+
const __dirname = (0, external_node_path_namespaceObject.dirname)(__filename1);
|
|
986
|
+
const packageJsonPath = (0, external_node_path_namespaceObject.resolve)(__dirname, "../package.json");
|
|
987
|
+
return JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(packageJsonPath, "utf8"));
|
|
988
|
+
}
|
|
989
|
+
function getPackageVersion() {
|
|
990
|
+
return getPackageInfo().version;
|
|
991
|
+
}
|
|
992
|
+
function main() {
|
|
993
|
+
const program = new external_commander_namespaceObject.Command();
|
|
994
|
+
program.name("codefast").description("CodeFast CLI - A development toolkit for CodeFast.").version(getPackageVersion(), "-v, --version", "display CLI version");
|
|
995
|
+
createUpdateExportsCommand(program);
|
|
996
|
+
createProjectCommand(program);
|
|
997
|
+
program.action(()=>{
|
|
998
|
+
console.log('Use "codefast create-project" to create a new Next.js project.');
|
|
999
|
+
console.log('Use "codefast update-exports" to update exports.');
|
|
1000
|
+
console.log('Run "codefast --help" to see all available commands.');
|
|
1001
|
+
program.help();
|
|
1002
|
+
});
|
|
1003
|
+
program.parse(process.argv);
|
|
1004
|
+
}
|
|
1005
|
+
main();
|
|
1006
|
+
for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
1007
|
+
Object.defineProperty(exports, '__esModule', {
|
|
1008
|
+
value: true
|
|
1009
|
+
});
|
|
1010
|
+
|
|
1011
|
+
//# sourceMappingURL=index.cjs.map
|