@codefast/cli 0.3.1-canary.13 â 0.3.1-canary.14
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 +10 -0
- package/dist/index.cjs +1062 -667
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1067 -673
- package/dist/index.js.map +1 -1
- package/package.json +8 -6
package/dist/index.cjs
CHANGED
|
@@ -25,171 +25,117 @@ var __webpack_require__ = {};
|
|
|
25
25
|
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
26
26
|
})();
|
|
27
27
|
var __webpack_exports__ = {};
|
|
28
|
+
const external_inversify_namespaceObject = require("inversify");
|
|
28
29
|
const external_commander_namespaceObject = require("commander");
|
|
29
|
-
const
|
|
30
|
-
var
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
30
|
+
const external_node_process_namespaceObject = require("node:process");
|
|
31
|
+
var external_node_process_default = /*#__PURE__*/ __webpack_require__.n(external_node_process_namespaceObject);
|
|
32
|
+
const TYPES = {
|
|
33
|
+
ProjectRepository: Symbol.for("ProjectRepository"),
|
|
34
|
+
PackageRepository: Symbol.for("PackageRepository"),
|
|
35
|
+
FileSystemPort: Symbol.for("FileSystemPort"),
|
|
36
|
+
CommandExecutorPort: Symbol.for("CommandExecutorPort"),
|
|
37
|
+
PromptPort: Symbol.for("PromptPort"),
|
|
38
|
+
AnalysisPort: Symbol.for("AnalysisPort"),
|
|
39
|
+
PackageInfoService: Symbol.for("PackageInfoService"),
|
|
40
|
+
DependencyConfigService: Symbol.for("DependencyConfigService"),
|
|
41
|
+
ConfigService: Symbol.for("ConfigService"),
|
|
42
|
+
FileSystemUtility: Symbol.for("FileSystemUtility"),
|
|
43
|
+
CreateProjectUseCase: Symbol.for("CreateProjectUseCase"),
|
|
44
|
+
UpdateExportsUseCase: Symbol.for("UpdateExportsUseCase"),
|
|
45
|
+
CreateProjectCommand: Symbol.for("CreateProjectCommand"),
|
|
46
|
+
UpdateExportsCommand: Symbol.for("UpdateExportsCommand"),
|
|
47
|
+
CLIAdapter: Symbol.for("CLIAdapter")
|
|
48
|
+
};
|
|
49
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
50
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
51
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
52
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
53
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
46
54
|
}
|
|
47
|
-
function
|
|
48
|
-
(
|
|
49
|
-
stdio: "inherit"
|
|
50
|
-
});
|
|
55
|
+
function _ts_metadata(k, v) {
|
|
56
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
51
57
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} catch (error) {
|
|
67
|
-
throw new Error(`Failed to write to file ${filePath}: ${getErrorMessage(error)}`);
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
writeConfigFile (filePath, content) {
|
|
71
|
-
external_node_fs_default().writeFileSync(filePath, content);
|
|
72
|
-
console.log(`đ Created ${filePath}`);
|
|
73
|
-
},
|
|
74
|
-
validatePath (filePath, filename) {
|
|
75
|
-
if (!this.exists(filePath)) {
|
|
76
|
-
console.warn(`â ī¸ ${filename} not found, skipping update.`);
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
return true;
|
|
58
|
+
function _ts_param(paramIndex, decorator) {
|
|
59
|
+
return function(target, key) {
|
|
60
|
+
decorator(target, key, paramIndex);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
class CreateProjectCommand {
|
|
64
|
+
constructor(createProjectUseCase){
|
|
65
|
+
this.createProjectUseCase = createProjectUseCase;
|
|
66
|
+
}
|
|
67
|
+
getCommand() {
|
|
68
|
+
return new external_commander_namespaceObject.Command().name("create-project").description("Create a new Next.js project with TypeScript, TailwindCSS, and linting setup").argument("[project-name]", "Name of the project to create").action(async (projectName)=>{
|
|
69
|
+
await this.createProjectUseCase.execute(projectName);
|
|
70
|
+
external_node_process_default().exit(0);
|
|
71
|
+
});
|
|
80
72
|
}
|
|
81
|
-
};
|
|
82
|
-
function getErrorMessage(error) {
|
|
83
|
-
return error instanceof Error ? error.message : "Unknown error occurred";
|
|
84
73
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
valid: false,
|
|
106
|
-
error: `Project name "${name}" is a reserved system name.`
|
|
107
|
-
};
|
|
108
|
-
const fullPath = external_node_path_default().resolve(process.cwd(), name);
|
|
109
|
-
if (external_node_fs_default().existsSync(fullPath)) return {
|
|
110
|
-
valid: false,
|
|
111
|
-
error: `A directory named "${name}" already exists.`
|
|
74
|
+
CreateProjectCommand = _ts_decorate([
|
|
75
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
76
|
+
_ts_param(0, (0, external_inversify_namespaceObject.inject)(TYPES.CreateProjectUseCase)),
|
|
77
|
+
_ts_metadata("design:type", Function),
|
|
78
|
+
_ts_metadata("design:paramtypes", [
|
|
79
|
+
"undefined" == typeof CreateProjectUseCase ? Object : CreateProjectUseCase
|
|
80
|
+
])
|
|
81
|
+
], CreateProjectCommand);
|
|
82
|
+
function update_exports_command_ts_decorate(decorators, target, key, desc) {
|
|
83
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
84
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
85
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
86
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
87
|
+
}
|
|
88
|
+
function update_exports_command_ts_metadata(k, v) {
|
|
89
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
90
|
+
}
|
|
91
|
+
function update_exports_command_ts_param(paramIndex, decorator) {
|
|
92
|
+
return function(target, key) {
|
|
93
|
+
decorator(target, key, paramIndex);
|
|
112
94
|
};
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
95
|
+
}
|
|
96
|
+
class UpdateExportsCommand {
|
|
97
|
+
constructor(updateExportsUseCase){
|
|
98
|
+
this.updateExportsUseCase = updateExportsUseCase;
|
|
99
|
+
}
|
|
100
|
+
getCommand() {
|
|
101
|
+
return new external_commander_namespaceObject.Command().name("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)=>{
|
|
102
|
+
await this.updateExportsUseCase.execute({
|
|
103
|
+
packageFilter: options.package,
|
|
104
|
+
dryRun: Boolean(options.dryRun),
|
|
105
|
+
configPath: options.config
|
|
106
|
+
});
|
|
107
|
+
external_node_process_namespaceObject.exit(0);
|
|
108
|
+
});
|
|
120
109
|
}
|
|
121
|
-
return {
|
|
122
|
-
valid: true
|
|
123
|
-
};
|
|
124
110
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
111
|
+
UpdateExportsCommand = update_exports_command_ts_decorate([
|
|
112
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
113
|
+
update_exports_command_ts_param(0, (0, external_inversify_namespaceObject.inject)(TYPES.UpdateExportsUseCase)),
|
|
114
|
+
update_exports_command_ts_metadata("design:type", Function),
|
|
115
|
+
update_exports_command_ts_metadata("design:paramtypes", [
|
|
116
|
+
"undefined" == typeof UpdateExportsUseCase ? Object : UpdateExportsUseCase
|
|
117
|
+
])
|
|
118
|
+
], UpdateExportsCommand);
|
|
119
|
+
function handleError(error, defaultMessage) {
|
|
120
|
+
const message = error instanceof Error ? error.message : defaultMessage;
|
|
121
|
+
console.error(`\nâ ${message}`);
|
|
132
122
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
const confirm = await utils_prompt("Do you want to continue configuring this existing project? [Y/n]: ");
|
|
139
|
-
if ("" === confirm || "y" === confirm.toLowerCase()) {
|
|
140
|
-
const packageJson = JSON.parse(external_node_fs_default().readFileSync(packageJsonPath, "utf8"));
|
|
141
|
-
const projectName = packageJson.name ?? await getValidProjectName(projectNameArg);
|
|
142
|
-
return {
|
|
143
|
-
projectName,
|
|
144
|
-
packageJsonExists
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
console.log("Aborting...");
|
|
148
|
-
throw new Error("User aborted the operation.");
|
|
149
|
-
}
|
|
150
|
-
const projectName = await getValidProjectName(projectNameArg);
|
|
151
|
-
return {
|
|
152
|
-
projectName,
|
|
153
|
-
packageJsonExists
|
|
154
|
-
};
|
|
123
|
+
function config_service_ts_decorate(decorators, target, key, desc) {
|
|
124
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
125
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
126
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
127
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
155
128
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
commitLint: [
|
|
167
|
-
"@commitlint/cli",
|
|
168
|
-
"@commitlint/config-conventional",
|
|
169
|
-
"@commitlint/types"
|
|
170
|
-
],
|
|
171
|
-
gitTools: [
|
|
172
|
-
"simple-git-hooks"
|
|
173
|
-
],
|
|
174
|
-
formatting: [
|
|
175
|
-
"prettier",
|
|
176
|
-
"prettier-plugin-packagejson",
|
|
177
|
-
"prettier-plugin-tailwindcss",
|
|
178
|
-
"lint-staged"
|
|
179
|
-
],
|
|
180
|
-
linting: [
|
|
181
|
-
"@codefast/eslint-config"
|
|
182
|
-
]
|
|
183
|
-
};
|
|
184
|
-
const PACKAGES_TO_REMOVE = [
|
|
185
|
-
"@eslint/eslintrc",
|
|
186
|
-
"eslint-config-next"
|
|
187
|
-
];
|
|
188
|
-
const configGroups = {
|
|
189
|
-
deployment: [
|
|
190
|
-
{
|
|
191
|
-
path: ".vercelignore",
|
|
192
|
-
content: `#-------------------------------------------------------------------------------
|
|
129
|
+
class ConfigService {
|
|
130
|
+
getConfigGroups() {
|
|
131
|
+
return this.configGroups;
|
|
132
|
+
}
|
|
133
|
+
constructor(){
|
|
134
|
+
this.configGroups = {
|
|
135
|
+
deployment: [
|
|
136
|
+
{
|
|
137
|
+
path: ".vercelignore",
|
|
138
|
+
content: `#-------------------------------------------------------------------------------
|
|
193
139
|
# Dependencies and package managers
|
|
194
140
|
#-------------------------------------------------------------------------------
|
|
195
141
|
|
|
@@ -255,13 +201,13 @@ Thumbs.db
|
|
|
255
201
|
# Vercel deployment configuration
|
|
256
202
|
.vercel
|
|
257
203
|
`,
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
204
|
+
description: "Ignore files that should not be deployed to Vercel"
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
formatting: [
|
|
208
|
+
{
|
|
209
|
+
path: "prettier.config.mjs",
|
|
210
|
+
content: `/**
|
|
265
211
|
* @see https://prettier.io/docs/en/configuration.html
|
|
266
212
|
* @type {import('prettier').Config}
|
|
267
213
|
*/
|
|
@@ -274,11 +220,11 @@ const config = {
|
|
|
274
220
|
|
|
275
221
|
export default config;
|
|
276
222
|
`,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
223
|
+
description: "Prettier configuration for source code formatting"
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
path: ".editorconfig",
|
|
227
|
+
content: `# https://editorconfig.org
|
|
282
228
|
root = true
|
|
283
229
|
|
|
284
230
|
[*]
|
|
@@ -302,11 +248,11 @@ indent_style = tab
|
|
|
302
248
|
# Keep in sync with rustfmt
|
|
303
249
|
indent_size = 4
|
|
304
250
|
`,
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
251
|
+
description: "Editor configuration for source code formatting"
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
path: ".prettierignore",
|
|
255
|
+
content: `# changesets
|
|
310
256
|
.changeset
|
|
311
257
|
|
|
312
258
|
# debug
|
|
@@ -320,13 +266,13 @@ package-lock.json
|
|
|
320
266
|
yarn.lock
|
|
321
267
|
pnpm-lock.yaml
|
|
322
268
|
`,
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
269
|
+
description: ""
|
|
270
|
+
}
|
|
271
|
+
],
|
|
272
|
+
linting: [
|
|
273
|
+
{
|
|
274
|
+
path: "commitlint.config.mjs",
|
|
275
|
+
content: `/**
|
|
330
276
|
* @see https://commitlint.js.org/reference/configuration.html
|
|
331
277
|
* @type {import('@commitlint/types').UserConfig}
|
|
332
278
|
*/
|
|
@@ -334,16 +280,17 @@ const config = {
|
|
|
334
280
|
extends: ["@commitlint/config-conventional"],
|
|
335
281
|
rules: {
|
|
336
282
|
"body-max-line-length": [2, "always", 350],
|
|
283
|
+
"header-max-length": [2, "always", 150],
|
|
337
284
|
},
|
|
338
285
|
};
|
|
339
286
|
|
|
340
287
|
export default config;
|
|
341
288
|
`,
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
289
|
+
description: "Commitlint configuration"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
path: "eslint.config.mjs",
|
|
293
|
+
content: `import { config } from "@codefast/eslint-config/next";
|
|
347
294
|
|
|
348
295
|
/**
|
|
349
296
|
* @see https://eslint.org/docs/latest/use/configure/configuration-files
|
|
@@ -353,11 +300,11 @@ const eslintConfig = [...config];
|
|
|
353
300
|
|
|
354
301
|
export default eslintConfig;
|
|
355
302
|
`,
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
303
|
+
description: "ESLint configuration for the project"
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
path: "lint-staged.config.mjs",
|
|
307
|
+
content: `import { relative } from "node:path";
|
|
361
308
|
|
|
362
309
|
/**
|
|
363
310
|
* Builds an ESLint command with the given filenames.
|
|
@@ -382,13 +329,13 @@ const config = {
|
|
|
382
329
|
|
|
383
330
|
export default config;
|
|
384
331
|
`,
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
332
|
+
description: "Configure lint-staged for pre-commit checks"
|
|
333
|
+
}
|
|
334
|
+
],
|
|
335
|
+
styles: [
|
|
336
|
+
{
|
|
337
|
+
path: "src/lib/fonts.ts",
|
|
338
|
+
content: `import { cn } from "@codefast/ui";
|
|
392
339
|
import { Geist, Geist_Mono as GeistMono } from "next/font/google";
|
|
393
340
|
|
|
394
341
|
const fontGeistSans = Geist({
|
|
@@ -403,11 +350,11 @@ const fontGeistMono = GeistMono({
|
|
|
403
350
|
|
|
404
351
|
export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
|
|
405
352
|
`,
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
353
|
+
description: "Font configuration for the application"
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
path: "src/app/globals.css",
|
|
357
|
+
content: `@import "tailwindcss";
|
|
411
358
|
|
|
412
359
|
@import "@codefast/ui/styles.css";
|
|
413
360
|
|
|
@@ -490,539 +437,987 @@ export const fontVariables = cn(fontGeistSans.variable, fontGeistMono.variable);
|
|
|
490
437
|
}
|
|
491
438
|
}
|
|
492
439
|
`,
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
};
|
|
497
|
-
function updateFileIfNeeded(filePath, filename, checkFn, updateFn, successMessage, alreadyUpdatedMessage) {
|
|
498
|
-
if (!FileUtils.validatePath(filePath, filename)) return;
|
|
499
|
-
const content = FileUtils.readFile(filePath);
|
|
500
|
-
if (checkFn(content)) return void console.log(`đ ${alreadyUpdatedMessage}`);
|
|
501
|
-
try {
|
|
502
|
-
const updatedContent = updateFn(content);
|
|
503
|
-
FileUtils.writeFile(filePath, updatedContent);
|
|
504
|
-
console.log(`đ ${successMessage}`);
|
|
505
|
-
} catch (error) {
|
|
506
|
-
console.warn(`â ī¸ Failed to update ${filename}: ${getErrorMessage(error)}`);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
function updatePostcssConfig(projectDir) {
|
|
510
|
-
const postcssConfigPath = external_node_path_default().join(projectDir, "postcss.config.mjs");
|
|
511
|
-
const typeComment = `/** @type {import('postcss-load-config').Config} */\n`;
|
|
512
|
-
updateFileIfNeeded(postcssConfigPath, "postcss.config.mjs", (content)=>content.includes(typeComment), (content)=>content.replace("const config = {", `${typeComment}const config = {`), "Updated postcss.config.mjs with type comment.", "postcss.config.mjs already contains type comment, no changes made.");
|
|
513
|
-
}
|
|
514
|
-
function updateLayoutFile(projectDir) {
|
|
515
|
-
const layoutPath = external_node_path_default().join(projectDir, "src/app/layout.tsx");
|
|
516
|
-
const htmlTarget = '<html className={cn(fontVariables, "antialiased")} lang="en">';
|
|
517
|
-
updateFileIfNeeded(layoutPath, "src/app/layout.tsx", (content)=>content.includes(htmlTarget), (content)=>{
|
|
518
|
-
const newImports = `import type { Metadata } from "next";
|
|
519
|
-
import type { JSX, ReactNode } from "react";
|
|
520
|
-
import { cn } from "@codefast/ui";
|
|
521
|
-
import { fontVariables } from "@/lib/fonts";
|
|
522
|
-
import "@/app/globals.css";`;
|
|
523
|
-
let result = content;
|
|
524
|
-
result = result.replaceAll(/import\s+{[^}]+}\s+from\s+["']next\/font\/google["'];\s*/g, "");
|
|
525
|
-
result = result.replace(/const\s+geistSans\s*=[^;]+;\s*const\s+geistMono\s*=[^;]+;\s*/, "");
|
|
526
|
-
result = result.replace(/import\s+type\s+{[^}]+}\s+from\s+["']next["'];\s*import\s+["']\.\/globals\.css["'];\s*/, newImports);
|
|
527
|
-
result = result.replace(/export default function RootLayout\({\s*children,\s*}\s*:\s*Readonly<{\s*children:\s*React\.ReactNode;\s*}>\)\s*{/, "export default function RootLayout({ children }: Readonly<{ children: ReactNode }>): JSX.Element {");
|
|
528
|
-
result = result.replace(/<html\s+lang="en"\s*>/, htmlTarget);
|
|
529
|
-
result = result.replace(/<body\s+className={`[^`]*`}\s*>/, "<body>");
|
|
530
|
-
return result;
|
|
531
|
-
}, "Updated src/app/layout.tsx to use fontVariables in html tag, removed className from body, modified ReactNode import, and added return type to RootLayout", "src/app/layout.tsx already uses fontVariables in html tag, no changes made.");
|
|
532
|
-
}
|
|
533
|
-
function updatePackageJson(projectDir) {
|
|
534
|
-
const packageJsonPath = external_node_path_default().join(projectDir, "package.json");
|
|
535
|
-
if (!FileUtils.validatePath(packageJsonPath, "package.json")) return;
|
|
536
|
-
try {
|
|
537
|
-
const packageJson = JSON.parse(FileUtils.readFile(packageJsonPath));
|
|
538
|
-
packageJson.scripts = {
|
|
539
|
-
...packageJson.scripts,
|
|
540
|
-
"check-types": "tsc --noEmit",
|
|
541
|
-
"deploy:preview": "vercel deploy --archive=tgz",
|
|
542
|
-
"deploy:prod": "vercel deploy --archive=tgz --prod",
|
|
543
|
-
format: "prettier --write --ignore-unknown .",
|
|
544
|
-
"format:check": "prettier --check --ignore-unknown .",
|
|
545
|
-
lint: "next lint --fix --max-warnings 0",
|
|
546
|
-
"lint:check": "next lint --max-warnings 0",
|
|
547
|
-
"package:install": "pnpm install",
|
|
548
|
-
"package:outdated": "pnpm outdated",
|
|
549
|
-
"package:upgrade": "pnpm update --latest",
|
|
550
|
-
preview: "pnpm build && pnpm start"
|
|
551
|
-
};
|
|
552
|
-
packageJson["simple-git-hooks"] = {
|
|
553
|
-
"pre-commit": "pnpm lint-staged",
|
|
554
|
-
"commit-msg": "pnpm commitlint --edit"
|
|
440
|
+
description: "Global CSS variables for the application"
|
|
441
|
+
}
|
|
442
|
+
]
|
|
555
443
|
};
|
|
556
|
-
FileUtils.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
557
|
-
console.log(`đ Updated package.json`);
|
|
558
|
-
} catch (error) {
|
|
559
|
-
console.warn(`â ī¸ Failed to update package.json: ${getErrorMessage(error)}`);
|
|
560
444
|
}
|
|
561
445
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
446
|
+
ConfigService = config_service_ts_decorate([
|
|
447
|
+
(0, external_inversify_namespaceObject.injectable)()
|
|
448
|
+
], ConfigService);
|
|
449
|
+
function create_project_use_case_ts_decorate(decorators, target, key, desc) {
|
|
450
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
451
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
452
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
453
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
569
454
|
}
|
|
570
|
-
function
|
|
571
|
-
|
|
572
|
-
updateFileIfNeeded(pagePath, "src/app/page.tsx", (content)=>content.includes("): JSX.Element"), (content)=>{
|
|
573
|
-
let result = content;
|
|
574
|
-
if (!result.includes("import type { JSX }")) result = result.includes("import type {") ? result.replace(/import type {(?<types>[^}]+)} from "react";/, 'import type {$1, JSX } from "react";') : result.includes("import {") ? result.replace(/import {/, 'import type { JSX } from "react";\n\nimport {') : `import type { JSX } from "react";\n\n${result}`;
|
|
575
|
-
result = result.replace(/export default function Home\(\) {/, "export default function Home(): JSX.Element {");
|
|
576
|
-
return result;
|
|
577
|
-
}, "Updated src/app/page.tsx to add JSX.Element return type to Home component", "src/app/page.tsx already has JSX.Element return type, no changes made.");
|
|
455
|
+
function create_project_use_case_ts_metadata(k, v) {
|
|
456
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
578
457
|
}
|
|
579
|
-
function
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
458
|
+
function create_project_use_case_ts_param(paramIndex, decorator) {
|
|
459
|
+
return function(target, key) {
|
|
460
|
+
decorator(target, key, paramIndex);
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
class create_project_use_case_CreateProjectUseCase {
|
|
464
|
+
constructor(projectRepository, fileSystemPort, commandExecutorPort, promptPort, configService){
|
|
465
|
+
this.projectRepository = projectRepository;
|
|
466
|
+
this.fileSystemPort = fileSystemPort;
|
|
467
|
+
this.commandExecutorPort = commandExecutorPort;
|
|
468
|
+
this.promptPort = promptPort;
|
|
469
|
+
this.configService = configService;
|
|
470
|
+
}
|
|
471
|
+
async execute(projectName) {
|
|
472
|
+
try {
|
|
473
|
+
this.commandExecutorPort.checkEnvironment();
|
|
474
|
+
const project = await this.checkExistingProject(projectName);
|
|
475
|
+
const configGroups = this.configService.getConfigGroups();
|
|
476
|
+
this.createOrConfigureProject(project, configGroups);
|
|
477
|
+
this.displaySuccessMessage(project);
|
|
478
|
+
return project;
|
|
479
|
+
} catch (error) {
|
|
480
|
+
handleError(error, "Failed to create or configure project");
|
|
481
|
+
throw error;
|
|
482
|
+
} finally{
|
|
483
|
+
this.promptPort.close();
|
|
591
484
|
}
|
|
592
485
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
console.log(`\nđ Installing dependencies...`);
|
|
596
|
-
if (MAIN_DEPENDENCIES.length > 0) runCommand(`pnpm add ${MAIN_DEPENDENCIES.join(" ")}`);
|
|
597
|
-
const allDevDependencies = Object.values(DEV_DEPENDENCIES).flat().join(" ");
|
|
598
|
-
if (allDevDependencies) runCommand(`pnpm add -D ${allDevDependencies}`);
|
|
599
|
-
}
|
|
600
|
-
function cleanupPackages() {
|
|
601
|
-
console.log(`\nđ§š Cleaning up unnecessary packages...`);
|
|
602
|
-
const packageJsonPath = external_node_path_namespaceObject.join(process.cwd(), "package.json");
|
|
603
|
-
if (!external_node_fs_namespaceObject.existsSync(packageJsonPath)) return void console.warn(`â ī¸ package.json not found, skipping cleanup.`);
|
|
604
|
-
let packageJson;
|
|
605
|
-
try {
|
|
606
|
-
packageJson = JSON.parse(external_node_fs_namespaceObject.readFileSync(packageJsonPath, "utf8"));
|
|
607
|
-
} catch (error) {
|
|
608
|
-
console.warn(`â ī¸ Error reading package.json: ${getErrorMessage(error)}, skipping cleanup.`);
|
|
609
|
-
return;
|
|
610
|
-
}
|
|
611
|
-
const dependencies = packageJson.dependencies ?? {};
|
|
612
|
-
const devDependencies = packageJson.devDependencies ?? {};
|
|
613
|
-
const packagesToRemove = PACKAGES_TO_REMOVE.filter((pkg)=>pkg in dependencies || pkg in devDependencies);
|
|
614
|
-
if (packagesToRemove.length > 0) runCommand(`pnpm remove ${packagesToRemove.join(" ")}`);
|
|
615
|
-
else console.log(`âšī¸ No unnecessary packages found in package.json to remove.`);
|
|
616
|
-
}
|
|
617
|
-
function checkEnvironment() {
|
|
618
|
-
try {
|
|
619
|
-
(0, external_node_child_process_namespaceObject.execSync)("pnpm --version", {
|
|
620
|
-
stdio: "ignore"
|
|
621
|
-
});
|
|
622
|
-
} catch {
|
|
623
|
-
console.error(`â PNPM chưa ÄÆ°áģŖc cà i Äáēˇt. Vui lÃ˛ng cà i Äáēˇt PNPM trưáģc.`);
|
|
624
|
-
process.exit(1);
|
|
486
|
+
async checkExistingProject(projectNameArg) {
|
|
487
|
+
return await this.projectRepository.checkExistingProject(projectNameArg);
|
|
625
488
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
}
|
|
632
|
-
const createProjectCommand = new external_commander_namespaceObject.Command().name("create-project [name]").description("Create a new Next.js project with recommended setup").action(async (projectNameArg)=>{
|
|
633
|
-
try {
|
|
634
|
-
checkEnvironment();
|
|
635
|
-
const { projectName, packageJsonExists } = await checkExistingProject(projectNameArg);
|
|
636
|
-
if (!packageJsonExists) {
|
|
637
|
-
console.log(`\nđ Starting project creation for ${projectName}...\n`);
|
|
638
|
-
createNextProject(projectName);
|
|
639
|
-
process.chdir(projectName);
|
|
640
|
-
console.log(`đ Moved to ${projectName}`);
|
|
489
|
+
createOrConfigureProject(project, configGroups) {
|
|
490
|
+
if (!project.packageJsonExists) {
|
|
491
|
+
console.log(`\nđ Starting project creation for ${project.name}...\n`);
|
|
492
|
+
this.projectRepository.createNextProject(project.name);
|
|
493
|
+
process.chdir(project.name);
|
|
494
|
+
console.log(`đ Moved to ${project.name}`);
|
|
641
495
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
496
|
+
this.updateProjectFiles(project.directory);
|
|
497
|
+
this.commandExecutorPort.installDependencies();
|
|
498
|
+
this.commandExecutorPort.cleanupPackages();
|
|
499
|
+
this.fileSystemPort.createConfigFiles(project.directory, configGroups);
|
|
500
|
+
this.projectRepository.updateNextConfig(project.directory);
|
|
501
|
+
this.projectRepository.updatePackageJson(project.directory);
|
|
502
|
+
this.commandExecutorPort.enableGitHooks();
|
|
503
|
+
this.commandExecutorPort.runFormatter();
|
|
504
|
+
this.commandExecutorPort.runLinter();
|
|
505
|
+
}
|
|
506
|
+
updateProjectFiles(projectDir) {
|
|
507
|
+
this.projectRepository.updateLayoutFile(projectDir);
|
|
508
|
+
this.projectRepository.updatePageFile(projectDir);
|
|
509
|
+
this.projectRepository.updatePostcssConfig(projectDir);
|
|
510
|
+
}
|
|
511
|
+
displaySuccessMessage(project) {
|
|
512
|
+
console.log(`\nâ
Project ${project.packageJsonExists ? "configured" : "created"} successfully!`);
|
|
513
|
+
console.log(`- Project: ${project.name}`);
|
|
658
514
|
console.log("- Next.js with TypeScript");
|
|
659
515
|
console.log("- TailwindCSS and @codefast/ui");
|
|
660
516
|
console.log("- ESLint, Prettier, Commitlint, and Git Hooks");
|
|
661
517
|
console.log("- Lint-staged for pre-commit checks");
|
|
662
518
|
console.log(`\nđ Project directory: ${process.cwd()}`);
|
|
663
519
|
console.log(`\nđ To start development:`);
|
|
664
|
-
console.log(`cd ${
|
|
665
|
-
} catch (error) {
|
|
666
|
-
console.error(`\nâ An error occurred: ${getErrorMessage(error)}`);
|
|
667
|
-
process.exit(1);
|
|
668
|
-
} finally{
|
|
669
|
-
rl.close();
|
|
670
|
-
process.exit(0);
|
|
520
|
+
console.log(`${project.packageJsonExists ? `cd ${project.name} && ` : ""}pnpm dev`);
|
|
671
521
|
}
|
|
672
|
-
});
|
|
673
|
-
const external_glob_namespaceObject = require("glob");
|
|
674
|
-
const external_ts_morph_namespaceObject = require("ts-morph");
|
|
675
|
-
function makeRegexPrefixesToRemove(prefixes) {
|
|
676
|
-
const prefixPattern = prefixes.join("|");
|
|
677
|
-
return new RegExp(`^.?\\/?(?:${prefixPattern})\\/(.*)$`);
|
|
678
522
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
523
|
+
create_project_use_case_CreateProjectUseCase = create_project_use_case_ts_decorate([
|
|
524
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
525
|
+
create_project_use_case_ts_param(0, (0, external_inversify_namespaceObject.inject)(TYPES.ProjectRepository)),
|
|
526
|
+
create_project_use_case_ts_param(1, (0, external_inversify_namespaceObject.inject)(TYPES.FileSystemPort)),
|
|
527
|
+
create_project_use_case_ts_param(2, (0, external_inversify_namespaceObject.inject)(TYPES.CommandExecutorPort)),
|
|
528
|
+
create_project_use_case_ts_param(3, (0, external_inversify_namespaceObject.inject)(TYPES.PromptPort)),
|
|
529
|
+
create_project_use_case_ts_param(4, (0, external_inversify_namespaceObject.inject)(TYPES.ConfigService)),
|
|
530
|
+
create_project_use_case_ts_metadata("design:type", Function),
|
|
531
|
+
create_project_use_case_ts_metadata("design:paramtypes", [
|
|
532
|
+
"undefined" == typeof ProjectRepositoryInterface ? Object : ProjectRepositoryInterface,
|
|
533
|
+
"undefined" == typeof FileSystemPort ? Object : FileSystemPort,
|
|
534
|
+
"undefined" == typeof CommandExecutorPort ? Object : CommandExecutorPort,
|
|
535
|
+
"undefined" == typeof PromptPort ? Object : PromptPort,
|
|
536
|
+
void 0 === ConfigService ? Object : ConfigService
|
|
537
|
+
])
|
|
538
|
+
], create_project_use_case_CreateProjectUseCase);
|
|
539
|
+
function update_exports_use_case_ts_decorate(decorators, target, key, desc) {
|
|
540
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
541
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
542
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
543
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
687
544
|
}
|
|
688
|
-
function
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
545
|
+
function update_exports_use_case_ts_metadata(k, v) {
|
|
546
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
547
|
+
}
|
|
548
|
+
function update_exports_use_case_ts_param(paramIndex, decorator) {
|
|
549
|
+
return function(target, key) {
|
|
550
|
+
decorator(target, key, paramIndex);
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
class update_exports_use_case_UpdateExportsUseCase {
|
|
554
|
+
constructor(packageRepository){
|
|
555
|
+
this.packageRepository = packageRepository;
|
|
698
556
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
557
|
+
async execute(options) {
|
|
558
|
+
try {
|
|
559
|
+
console.info("âĸâ Searching for packages...");
|
|
560
|
+
const packageJsonPaths = await this.packageRepository.findAllPackages(options.configPath);
|
|
561
|
+
if (0 === packageJsonPaths.length) return void console.warn("No packages found.");
|
|
562
|
+
console.log(` Found ${packageJsonPaths.length} packages.`);
|
|
563
|
+
let successCount = 0;
|
|
564
|
+
let skipCount = 0;
|
|
565
|
+
let errorCount = 0;
|
|
566
|
+
for (const packageJsonPath of packageJsonPaths){
|
|
567
|
+
const result = this.packageRepository.processPackage(packageJsonPath, options);
|
|
568
|
+
if (result) successCount++;
|
|
569
|
+
else if (options.packageFilter) skipCount++;
|
|
570
|
+
else errorCount++;
|
|
571
|
+
}
|
|
572
|
+
console.log("âĸâ Completed exports update.\n");
|
|
573
|
+
console.info(`Stats: ${successCount} succeeded, ${skipCount} skipped, ${errorCount} failed`);
|
|
574
|
+
} catch (error) {
|
|
575
|
+
handleError(error, "Error processing packages");
|
|
576
|
+
throw error;
|
|
715
577
|
}
|
|
716
|
-
const name = parts.at(-1) ?? "";
|
|
717
|
-
const importPath = {
|
|
718
|
-
originalPath: moduleSpecifier,
|
|
719
|
-
directory,
|
|
720
|
-
name,
|
|
721
|
-
exportPath: processExportPath(moduleSpecifier, regexPattern)
|
|
722
|
-
};
|
|
723
|
-
imports.push(importPath);
|
|
724
578
|
}
|
|
725
|
-
|
|
726
|
-
|
|
579
|
+
}
|
|
580
|
+
update_exports_use_case_UpdateExportsUseCase = update_exports_use_case_ts_decorate([
|
|
581
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
582
|
+
update_exports_use_case_ts_param(0, (0, external_inversify_namespaceObject.inject)(TYPES.PackageRepository)),
|
|
583
|
+
update_exports_use_case_ts_metadata("design:type", Function),
|
|
584
|
+
update_exports_use_case_ts_metadata("design:paramtypes", [
|
|
585
|
+
"undefined" == typeof PackageRepository ? Object : PackageRepository
|
|
586
|
+
])
|
|
587
|
+
], update_exports_use_case_UpdateExportsUseCase);
|
|
588
|
+
function cli_adapter_ts_decorate(decorators, target, key, desc) {
|
|
589
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
590
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
591
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
592
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
593
|
+
}
|
|
594
|
+
function cli_adapter_ts_metadata(k, v) {
|
|
595
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
596
|
+
}
|
|
597
|
+
function cli_adapter_ts_param(paramIndex, decorator) {
|
|
598
|
+
return function(target, key) {
|
|
599
|
+
decorator(target, key, paramIndex);
|
|
727
600
|
};
|
|
728
601
|
}
|
|
729
|
-
|
|
602
|
+
class CLIAdapter {
|
|
603
|
+
constructor(createProjectCommand, updateExportsCommand, packageInfoService){
|
|
604
|
+
this.createProjectCommand = createProjectCommand;
|
|
605
|
+
this.updateExportsCommand = updateExportsCommand;
|
|
606
|
+
this.packageInfoService = packageInfoService;
|
|
607
|
+
}
|
|
608
|
+
initialize() {
|
|
609
|
+
const program = new external_commander_namespaceObject.Command();
|
|
610
|
+
program.name("codefast").description("CodeFast CLI - A development toolkit for CodeFast.").version(this.packageInfoService.getPackageVersion(), "-v, --version", "display CLI version").addCommand(this.createProjectCommand.getCommand()).addCommand(this.updateExportsCommand.getCommand()).parse(process.argv);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
CLIAdapter = cli_adapter_ts_decorate([
|
|
614
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
615
|
+
cli_adapter_ts_param(0, (0, external_inversify_namespaceObject.inject)(TYPES.CreateProjectCommand)),
|
|
616
|
+
cli_adapter_ts_param(1, (0, external_inversify_namespaceObject.inject)(TYPES.UpdateExportsCommand)),
|
|
617
|
+
cli_adapter_ts_param(2, (0, external_inversify_namespaceObject.inject)(TYPES.PackageInfoService)),
|
|
618
|
+
cli_adapter_ts_metadata("design:type", Function),
|
|
619
|
+
cli_adapter_ts_metadata("design:paramtypes", [
|
|
620
|
+
void 0 === CreateProjectCommand ? Object : CreateProjectCommand,
|
|
621
|
+
void 0 === UpdateExportsCommand ? Object : UpdateExportsCommand,
|
|
622
|
+
"undefined" == typeof PackageInfoServiceInterface ? Object : PackageInfoServiceInterface
|
|
623
|
+
])
|
|
624
|
+
], CLIAdapter);
|
|
625
|
+
const external_node_child_process_namespaceObject = require("node:child_process");
|
|
626
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
627
|
+
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
|
|
730
628
|
const external_zod_namespaceObject = require("zod");
|
|
731
|
-
const
|
|
732
|
-
cjsOutputPattern: external_zod_namespaceObject.z.string(),
|
|
733
|
-
esmOutputPattern: external_zod_namespaceObject.z.string(),
|
|
734
|
-
packageJsonPath: external_zod_namespaceObject.z.string(),
|
|
735
|
-
srcIndexPath: external_zod_namespaceObject.z.string(),
|
|
736
|
-
typesOutputCjsPattern: external_zod_namespaceObject.z.string(),
|
|
737
|
-
typesOutputPattern: external_zod_namespaceObject.z.string(),
|
|
738
|
-
|
|
629
|
+
const packageConfigSchema = external_zod_namespaceObject.z.object({
|
|
630
|
+
cjsOutputPattern: external_zod_namespaceObject.z.string().describe("Output pattern for CommonJS format, e.g., './dist/cjs/{dir}/{name}.cjs'"),
|
|
631
|
+
esmOutputPattern: external_zod_namespaceObject.z.string().describe("Output pattern for ESM format, e.g., './dist/esm/{dir}/{name}.js'"),
|
|
632
|
+
packageJsonPath: external_zod_namespaceObject.z.string().describe("Path to the package.json file, e.g., 'package.json'"),
|
|
633
|
+
srcIndexPath: external_zod_namespaceObject.z.string().describe("Path to the source index file, e.g., 'src/index.ts'"),
|
|
634
|
+
typesOutputCjsPattern: external_zod_namespaceObject.z.string().describe("Output pattern for CommonJS type declarations, e.g., './dist/types/{dir}/{name}.d.cts'"),
|
|
635
|
+
typesOutputPattern: external_zod_namespaceObject.z.string().describe("Output pattern for type declarations, e.g., './dist/types/{dir}/{name}.d.ts'"),
|
|
636
|
+
exportPathPrefixesToRemove: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()).optional().describe("Prefixes to remove from export paths, e.g., ['components']")
|
|
739
637
|
});
|
|
740
|
-
const
|
|
741
|
-
customPackageConfigs: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.string(),
|
|
742
|
-
defaultPackageConfig:
|
|
743
|
-
packagesGlob: external_zod_namespaceObject.z.string()
|
|
638
|
+
const scriptConfigSchema = external_zod_namespaceObject.z.object({
|
|
639
|
+
customPackageConfigs: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.string(), packageConfigSchema.partial()).describe("Custom configurations for specific packages"),
|
|
640
|
+
defaultPackageConfig: packageConfigSchema.describe("Default configuration applied to all packages unless overridden"),
|
|
641
|
+
packagesGlob: external_zod_namespaceObject.z.string().describe("Glob pattern to find package.json files, e.g., './packages/**/package.json'")
|
|
744
642
|
});
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
643
|
+
external_zod_namespaceObject.z.object({
|
|
644
|
+
directory: external_zod_namespaceObject.z.string().describe("Directory containing the import, e.g., 'components'"),
|
|
645
|
+
exportPath: external_zod_namespaceObject.z.string().describe("Resolved export path from the directory, e.g., './button'"),
|
|
646
|
+
name: external_zod_namespaceObject.z.string().describe("Name of the import, e.g., 'Button'"),
|
|
647
|
+
originalPath: external_zod_namespaceObject.z.string().describe("Original unresolved path, e.g., './components/button'")
|
|
648
|
+
});
|
|
649
|
+
const exportConfigSchema = external_zod_namespaceObject.z.object({
|
|
650
|
+
import: external_zod_namespaceObject.z.object({
|
|
651
|
+
default: external_zod_namespaceObject.z.string().describe("ESM default export path"),
|
|
652
|
+
types: external_zod_namespaceObject.z.string().describe("ESM types export path")
|
|
653
|
+
}),
|
|
654
|
+
require: external_zod_namespaceObject.z.object({
|
|
655
|
+
default: external_zod_namespaceObject.z.string().describe("CommonJS default export path"),
|
|
656
|
+
types: external_zod_namespaceObject.z.string().describe("CommonJS types export path")
|
|
657
|
+
})
|
|
658
|
+
});
|
|
659
|
+
const PackageExportsSchema = external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.string(), external_zod_namespaceObject.z.union([
|
|
660
|
+
exportConfigSchema,
|
|
661
|
+
external_zod_namespaceObject.z.string()
|
|
662
|
+
]));
|
|
663
|
+
const packageJsonSchema = external_zod_namespaceObject.z.object({
|
|
664
|
+
dependencies: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.string(), external_zod_namespaceObject.z.string()).optional().describe("List of runtime dependencies with their versions"),
|
|
665
|
+
devDependencies: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.string(), external_zod_namespaceObject.z.string()).optional().describe("List of development dependencies with their versions"),
|
|
666
|
+
exports: PackageExportsSchema.optional().describe("Export mappings for the package"),
|
|
667
|
+
name: external_zod_namespaceObject.z.string().describe("Name of the package"),
|
|
668
|
+
scripts: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.string(), external_zod_namespaceObject.z.string()).describe("Script commands defined for the package"),
|
|
669
|
+
"simple-git-hooks": external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.string(), external_zod_namespaceObject.z.string()).optional().describe("Git hooks configuration for the package"),
|
|
670
|
+
version: external_zod_namespaceObject.z.string().optional().describe("Version of the package")
|
|
671
|
+
}).catchall(external_zod_namespaceObject.z.unknown());
|
|
672
|
+
function node_command_executor_adapter_ts_decorate(decorators, target, key, desc) {
|
|
673
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
674
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
675
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
676
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
761
677
|
}
|
|
762
|
-
function
|
|
763
|
-
if (
|
|
764
|
-
const userConfig = loadConfigFile(configPath);
|
|
765
|
-
const config = (0, external_lodash_es_namespaceObject.merge)({}, defaultConfig, userConfig);
|
|
766
|
-
if (!configPath) cachedConfig = config;
|
|
767
|
-
return config;
|
|
678
|
+
function node_command_executor_adapter_ts_metadata(k, v) {
|
|
679
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
768
680
|
}
|
|
769
|
-
function
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
return {
|
|
773
|
-
...configObj.defaultPackageConfig,
|
|
774
|
-
...customConfig
|
|
681
|
+
function node_command_executor_adapter_ts_param(paramIndex, decorator) {
|
|
682
|
+
return function(target, key) {
|
|
683
|
+
decorator(target, key, paramIndex);
|
|
775
684
|
};
|
|
776
685
|
}
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
},
|
|
793
|
-
"@codefast/style-guide": {
|
|
794
|
-
exportPathPrefixesToRemove: [
|
|
795
|
-
"configs"
|
|
796
|
-
]
|
|
686
|
+
class NodeCommandExecutorAdapter {
|
|
687
|
+
constructor(fileSystemPort, dependencyConfigService){
|
|
688
|
+
this.fileSystemPort = fileSystemPort;
|
|
689
|
+
this.dependencyConfigService = dependencyConfigService;
|
|
690
|
+
}
|
|
691
|
+
runCommand(command) {
|
|
692
|
+
(0, external_node_child_process_namespaceObject.execSync)(command, {
|
|
693
|
+
stdio: "inherit"
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
checkEnvironment() {
|
|
697
|
+
try {
|
|
698
|
+
this.runCommand("pnpm --version");
|
|
699
|
+
} catch {
|
|
700
|
+
throw new Error("PNPM is not installed. Please install PNPM first.");
|
|
797
701
|
}
|
|
798
702
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
-
const
|
|
804
|
-
const
|
|
805
|
-
|
|
806
|
-
|
|
703
|
+
installDependencies() {
|
|
704
|
+
console.log(`\nđ Installing dependencies...`);
|
|
705
|
+
const mainDependencies = this.dependencyConfigService.getMainDependencies();
|
|
706
|
+
if (mainDependencies.length > 0) this.runCommand(`pnpm add ${mainDependencies.join(" ")}`);
|
|
707
|
+
const devDependencies = this.dependencyConfigService.getDevDependencies();
|
|
708
|
+
const allDevDependencies = Object.values(devDependencies).flat().join(" ");
|
|
709
|
+
if (allDevDependencies) this.runCommand(`pnpm add -D ${allDevDependencies}`);
|
|
710
|
+
}
|
|
711
|
+
cleanupPackages() {
|
|
712
|
+
console.log(`\nđ§š Cleaning up unnecessary packages...`);
|
|
713
|
+
const packageJsonPath = external_node_path_default().join(process.cwd(), "package.json");
|
|
714
|
+
if (!this.fileSystemPort.exists(packageJsonPath)) return void console.warn(`â ī¸ package.json not found, skipping cleanup.`);
|
|
715
|
+
let packageJson;
|
|
716
|
+
try {
|
|
717
|
+
packageJson = packageJsonSchema.parse(JSON.parse(this.fileSystemPort.readFile(packageJsonPath)));
|
|
718
|
+
} catch (error) {
|
|
719
|
+
console.warn(`â ī¸ Error reading package.json: ${error instanceof Error ? error.message : "Unknown error"}, skipping cleanup.`);
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
const dependencies = packageJson.dependencies ?? {};
|
|
723
|
+
const devDependencies = packageJson.devDependencies ?? {};
|
|
724
|
+
const packagesToRemove = this.dependencyConfigService.getPackagesToRemove().filter((pkg)=>pkg in dependencies || pkg in devDependencies);
|
|
725
|
+
if (packagesToRemove.length > 0) this.runCommand(`pnpm remove ${packagesToRemove.join(" ")}`);
|
|
726
|
+
else console.log(`âšī¸ No unnecessary packages found in package.json to remove.`);
|
|
727
|
+
}
|
|
728
|
+
enableGitHooks() {
|
|
729
|
+
console.log(`\nđ Activating git hooks...`);
|
|
730
|
+
this.runCommand("pnpm simple-git-hooks");
|
|
731
|
+
}
|
|
732
|
+
runFormatter() {
|
|
733
|
+
console.log(`\nđ Formatting files with Prettier...`);
|
|
734
|
+
this.runCommand("pnpm format");
|
|
735
|
+
}
|
|
736
|
+
runLinter() {
|
|
737
|
+
console.log(`\nđ Running ESLint to check code style...`);
|
|
738
|
+
this.runCommand("pnpm lint");
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
NodeCommandExecutorAdapter = node_command_executor_adapter_ts_decorate([
|
|
742
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
743
|
+
node_command_executor_adapter_ts_param(0, (0, external_inversify_namespaceObject.inject)(TYPES.FileSystemPort)),
|
|
744
|
+
node_command_executor_adapter_ts_param(1, (0, external_inversify_namespaceObject.inject)(TYPES.DependencyConfigService)),
|
|
745
|
+
node_command_executor_adapter_ts_metadata("design:type", Function),
|
|
746
|
+
node_command_executor_adapter_ts_metadata("design:paramtypes", [
|
|
747
|
+
"undefined" == typeof FileSystemPort ? Object : FileSystemPort,
|
|
748
|
+
"undefined" == typeof DependencyConfigServiceInterface ? Object : DependencyConfigServiceInterface
|
|
749
|
+
])
|
|
750
|
+
], NodeCommandExecutorAdapter);
|
|
751
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
752
|
+
var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
|
|
753
|
+
function node_file_system_adapter_ts_decorate(decorators, target, key, desc) {
|
|
754
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
755
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
756
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
757
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
758
|
+
}
|
|
759
|
+
class NodeFileSystemAdapter {
|
|
760
|
+
exists(filePath) {
|
|
807
761
|
return external_node_fs_default().existsSync(filePath);
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
},
|
|
814
|
-
readJsonFile (filePath) {
|
|
762
|
+
}
|
|
763
|
+
access(filePath) {
|
|
764
|
+
external_node_fs_default().accessSync(filePath, external_node_fs_default().constants.W_OK);
|
|
765
|
+
}
|
|
766
|
+
readFile(filePath) {
|
|
815
767
|
try {
|
|
816
|
-
|
|
817
|
-
return JSON.parse(content);
|
|
768
|
+
return external_node_fs_default().readFileSync(filePath, "utf8");
|
|
818
769
|
} catch (error) {
|
|
819
|
-
|
|
820
|
-
return null;
|
|
770
|
+
throw new Error(`Failed to read file ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
821
771
|
}
|
|
822
|
-
}
|
|
823
|
-
|
|
772
|
+
}
|
|
773
|
+
writeFile(filePath, content) {
|
|
824
774
|
try {
|
|
825
|
-
|
|
826
|
-
|
|
775
|
+
const dir = external_node_path_default().dirname(filePath);
|
|
776
|
+
this.createDirectory(dir);
|
|
777
|
+
external_node_fs_default().writeFileSync(filePath, content);
|
|
827
778
|
} catch (error) {
|
|
828
|
-
|
|
829
|
-
return false;
|
|
779
|
+
throw new Error(`Failed to write to file ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
830
780
|
}
|
|
831
|
-
},
|
|
832
|
-
getAnalysisDir (packageDir) {
|
|
833
|
-
const outputDir = external_node_path_default().join(packageDir, EXPORTS_ANALYSIS_DIR);
|
|
834
|
-
this.ensureDirectoryExists(outputDir);
|
|
835
|
-
return outputDir;
|
|
836
|
-
},
|
|
837
|
-
createBackupFilename (baseFilename) {
|
|
838
|
-
const timestamp = new Date().toISOString().replaceAll(/[:.]/g, "-");
|
|
839
|
-
return `${baseFilename}.backup.${timestamp}`;
|
|
840
781
|
}
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
782
|
+
createDirectory(dirPath) {
|
|
783
|
+
if (!this.exists(dirPath)) external_node_fs_default().mkdirSync(dirPath, {
|
|
784
|
+
recursive: true
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
writeConfigFile(filePath, content) {
|
|
788
|
+
this.writeFile(filePath, content);
|
|
789
|
+
console.log(`đ Created ${filePath}`);
|
|
790
|
+
}
|
|
791
|
+
createConfigFiles(projectDir, configGroups) {
|
|
792
|
+
console.log(`\nđ Creating configuration files...`);
|
|
793
|
+
for (const [category, configs] of Object.entries(configGroups)){
|
|
794
|
+
console.log(`\nđ Setting up ${category} configurations:`);
|
|
795
|
+
for (const config of configs){
|
|
796
|
+
const fullPath = external_node_path_default().join(projectDir, config.path);
|
|
797
|
+
this.writeConfigFile(fullPath, config.content);
|
|
798
|
+
if (config.description) console.log(`âšī¸ ${config.path}: ${config.description}`);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
NodeFileSystemAdapter = node_file_system_adapter_ts_decorate([
|
|
804
|
+
(0, external_inversify_namespaceObject.injectable)()
|
|
805
|
+
], NodeFileSystemAdapter);
|
|
806
|
+
const external_node_readline_namespaceObject = require("node:readline");
|
|
807
|
+
var external_node_readline_default = /*#__PURE__*/ __webpack_require__.n(external_node_readline_namespaceObject);
|
|
808
|
+
function node_prompt_adapter_ts_decorate(decorators, target, key, desc) {
|
|
809
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
810
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
811
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
812
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
844
813
|
}
|
|
845
|
-
function
|
|
846
|
-
return
|
|
814
|
+
function node_prompt_adapter_ts_metadata(k, v) {
|
|
815
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
847
816
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
817
|
+
class NodePromptAdapter {
|
|
818
|
+
constructor(){
|
|
819
|
+
this.rl = external_node_readline_default().createInterface({
|
|
820
|
+
input: process.stdin,
|
|
821
|
+
output: process.stdout
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
async prompt(message) {
|
|
825
|
+
return new Promise((resolve)=>{
|
|
826
|
+
this.rl.question(message, (answer)=>{
|
|
827
|
+
resolve(answer.trim());
|
|
828
|
+
});
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
close() {
|
|
832
|
+
this.rl.close();
|
|
861
833
|
}
|
|
862
834
|
}
|
|
863
|
-
|
|
864
|
-
|
|
835
|
+
NodePromptAdapter = node_prompt_adapter_ts_decorate([
|
|
836
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
837
|
+
node_prompt_adapter_ts_metadata("design:type", Function),
|
|
838
|
+
node_prompt_adapter_ts_metadata("design:paramtypes", [])
|
|
839
|
+
], NodePromptAdapter);
|
|
840
|
+
const external_ts_morph_namespaceObject = require("ts-morph");
|
|
841
|
+
function ts_morph_analysis_adapter_ts_decorate(decorators, target, key, desc) {
|
|
842
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
843
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
844
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
845
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
865
846
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
847
|
+
class TsMorphAnalysisAdapter {
|
|
848
|
+
analyzeImports(indexFilePath, packageConfig) {
|
|
849
|
+
const project = new external_ts_morph_namespaceObject.Project();
|
|
850
|
+
let sourceFile;
|
|
851
|
+
try {
|
|
852
|
+
sourceFile = project.addSourceFileAtPath(indexFilePath);
|
|
853
|
+
} catch (error) {
|
|
854
|
+
console.error(`Error loading source file at ${indexFilePath}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
855
|
+
return {
|
|
856
|
+
imports: []
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
const imports = [];
|
|
860
|
+
const prefixesToRemove = packageConfig.exportPathPrefixesToRemove ?? [];
|
|
861
|
+
const regexPattern = new RegExp(`^.?\\/?(?:${prefixesToRemove.join("|")})\\/(.*)$`);
|
|
862
|
+
for (const exportDecl of sourceFile.getExportDeclarations()){
|
|
863
|
+
let moduleSpecifier = exportDecl.getModuleSpecifierValue();
|
|
864
|
+
if (!moduleSpecifier) continue;
|
|
865
|
+
if (moduleSpecifier.startsWith("@/")) moduleSpecifier = `./${moduleSpecifier.slice(2)}`;
|
|
866
|
+
const isExternal = !moduleSpecifier.startsWith(".");
|
|
867
|
+
if (isExternal) continue;
|
|
868
|
+
const parts = moduleSpecifier.split("/").filter(Boolean);
|
|
869
|
+
if (parts.length < 2) continue;
|
|
870
|
+
let directory = parts.length <= 1 ? "." : parts.slice(0, -1).join("/");
|
|
871
|
+
if (directory.startsWith("./")) directory = directory.slice(2);
|
|
872
|
+
const name = parts.at(-1) ?? "";
|
|
873
|
+
const exportPath = this.processExportPath(moduleSpecifier, regexPattern);
|
|
874
|
+
imports.push({
|
|
875
|
+
originalPath: moduleSpecifier,
|
|
876
|
+
directory,
|
|
877
|
+
name,
|
|
878
|
+
exportPath
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
return {
|
|
882
|
+
imports
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
processExportPath(modulePath, regexPattern) {
|
|
886
|
+
const match = modulePath.match(regexPattern);
|
|
887
|
+
if (match) {
|
|
888
|
+
const remainingPath = match[1];
|
|
889
|
+
return remainingPath.startsWith("./") ? remainingPath : `./${remainingPath}`;
|
|
890
|
+
}
|
|
891
|
+
return modulePath;
|
|
892
|
+
}
|
|
869
893
|
}
|
|
870
|
-
|
|
871
|
-
|
|
894
|
+
TsMorphAnalysisAdapter = ts_morph_analysis_adapter_ts_decorate([
|
|
895
|
+
(0, external_inversify_namespaceObject.injectable)()
|
|
896
|
+
], TsMorphAnalysisAdapter);
|
|
897
|
+
const external_glob_namespaceObject = require("glob");
|
|
898
|
+
const external_lodash_es_namespaceObject = require("lodash-es");
|
|
899
|
+
function file_system_package_repository_ts_decorate(decorators, target, key, desc) {
|
|
900
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
901
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
902
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
903
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
872
904
|
}
|
|
873
|
-
function
|
|
874
|
-
|
|
905
|
+
function file_system_package_repository_ts_metadata(k, v) {
|
|
906
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
875
907
|
}
|
|
876
|
-
function
|
|
877
|
-
|
|
878
|
-
|
|
908
|
+
function file_system_package_repository_ts_param(paramIndex, decorator) {
|
|
909
|
+
return function(target, key) {
|
|
910
|
+
decorator(target, key, paramIndex);
|
|
911
|
+
};
|
|
879
912
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
913
|
+
class FileSystemPackageRepository {
|
|
914
|
+
constructor(fileSystemPort, analysisPort, fileSystemUtility){
|
|
915
|
+
this.fileSystemPort = fileSystemPort;
|
|
916
|
+
this.analysisPort = analysisPort;
|
|
917
|
+
this.fileSystemUtility = fileSystemUtility;
|
|
918
|
+
this.DEFAULT_IGNORE_PATTERN = [
|
|
919
|
+
"**/node_modules/**"
|
|
920
|
+
];
|
|
921
|
+
this.cachedConfig = null;
|
|
922
|
+
this.defaultConfig = {
|
|
923
|
+
packagesGlob: "./packages/**/package.json",
|
|
924
|
+
defaultPackageConfig: {
|
|
925
|
+
cjsOutputPattern: "./dist/cjs/{dir}/{name}.cjs",
|
|
926
|
+
esmOutputPattern: "./dist/esm/{dir}/{name}.js",
|
|
927
|
+
packageJsonPath: "package.json",
|
|
928
|
+
srcIndexPath: "src/index.ts",
|
|
929
|
+
typesOutputCjsPattern: "./dist/types/{dir}/{name}.d.ts",
|
|
930
|
+
typesOutputPattern: "./dist/types/{dir}/{name}.d.ts"
|
|
887
931
|
},
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
932
|
+
customPackageConfigs: {
|
|
933
|
+
"@codefast/ui": {
|
|
934
|
+
exportPathPrefixesToRemove: [
|
|
935
|
+
"components"
|
|
936
|
+
]
|
|
937
|
+
},
|
|
938
|
+
"@codefast/style-guide": {
|
|
939
|
+
exportPathPrefixesToRemove: [
|
|
940
|
+
"configs"
|
|
941
|
+
]
|
|
942
|
+
}
|
|
891
943
|
}
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
async findAllPackages(configPath) {
|
|
947
|
+
const config = this.getConfig(configPath);
|
|
948
|
+
return await (0, external_glob_namespaceObject.glob)(config.packagesGlob, {
|
|
949
|
+
ignore: this.DEFAULT_IGNORE_PATTERN
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
processPackage(packageJsonPath, options) {
|
|
953
|
+
const packageDir = external_node_path_default().dirname(packageJsonPath);
|
|
954
|
+
let packageJson;
|
|
955
|
+
try {
|
|
956
|
+
packageJson = JSON.parse(this.fileSystemPort.readFile(packageJsonPath));
|
|
957
|
+
} catch (error) {
|
|
958
|
+
console.error(`Failed to parse ${packageJsonPath}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
959
|
+
return false;
|
|
892
960
|
}
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
const
|
|
900
|
-
const
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
961
|
+
const packageName = packageJson.name;
|
|
962
|
+
if (options.packageFilter && packageName !== options.packageFilter) {
|
|
963
|
+
console.debug(`Skipping ${packageName} (does not match filter)`);
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
console.info(`âĸâ Processing package: ${packageName}`);
|
|
967
|
+
const config = this.getConfig(options.configPath);
|
|
968
|
+
const packageConfig = this.getPackageConfig(packageName, config);
|
|
969
|
+
const srcIndexPath = external_node_path_default().join(packageDir, packageConfig.srcIndexPath);
|
|
970
|
+
if (!this.fileSystemPort.exists(srcIndexPath)) {
|
|
971
|
+
console.error(`âš âī¸ Source file not found at ${srcIndexPath}`);
|
|
972
|
+
return false;
|
|
973
|
+
}
|
|
974
|
+
console.info(`âš Analyzing imports from ${srcIndexPath}...`);
|
|
975
|
+
const analysis = this.analyzeImports(srcIndexPath, packageConfig);
|
|
976
|
+
if (0 === analysis.imports.length) {
|
|
977
|
+
console.warn(`âš âī¸ No imports found to analyze in ${packageName}`);
|
|
978
|
+
return false;
|
|
979
|
+
}
|
|
980
|
+
console.log(`âš Analysis complete. Found ${analysis.imports.length} subpath exports.`);
|
|
981
|
+
this.saveExportsAnalysis(packageDir, analysis);
|
|
982
|
+
const newExports = this.generateExports(packageName, analysis.imports, packageJson.exports ?? {}, config);
|
|
983
|
+
const currentExportsCount = packageJson.exports ? Object.keys(packageJson.exports).length : 0;
|
|
984
|
+
const newExportsCount = Object.keys(newExports).length;
|
|
985
|
+
console.info(`âš Exports: ${currentExportsCount} -> ${newExportsCount}`);
|
|
986
|
+
if (options.dryRun) {
|
|
987
|
+
this.saveExportsPreview(packageDir, newExports);
|
|
988
|
+
console.warn(`âš Saved exports preview to .exports-analysis`);
|
|
989
|
+
console.warn(`âš Dry run: no changes saved for ${packageName}`);
|
|
990
|
+
return true;
|
|
991
|
+
}
|
|
992
|
+
this.fileSystemUtility.backupFile(packageJsonPath, ".exports-analysis");
|
|
993
|
+
console.log(`âš Backed up ${packageJsonPath}`);
|
|
994
|
+
const updatedPackageJson = {
|
|
995
|
+
...packageJson,
|
|
996
|
+
exports: newExports
|
|
997
|
+
};
|
|
998
|
+
this.fileSystemPort.writeFile(packageJsonPath, `${JSON.stringify(updatedPackageJson, null, 2)}\n`);
|
|
999
|
+
console.log(`âš Updated exports for ${packageName}`);
|
|
1000
|
+
return true;
|
|
1001
|
+
}
|
|
1002
|
+
analyzeImports(indexFilePath, packageConfig) {
|
|
1003
|
+
return this.analysisPort.analyzeImports(indexFilePath, packageConfig);
|
|
1004
|
+
}
|
|
1005
|
+
generateExports(packageName, imports, existingExports, config) {
|
|
1006
|
+
const packageConfig = this.getPackageConfig(packageName, config);
|
|
1007
|
+
const exports1 = {
|
|
1008
|
+
".": existingExports["."] ?? {
|
|
1009
|
+
import: {
|
|
1010
|
+
default: "./dist/esm/index.js",
|
|
1011
|
+
types: "./dist/types/index.d.ts"
|
|
1012
|
+
},
|
|
1013
|
+
require: {
|
|
1014
|
+
default: "./dist/cjs/index.cjs",
|
|
1015
|
+
types: "./dist/types/index.d.cts"
|
|
1016
|
+
}
|
|
909
1017
|
}
|
|
910
1018
|
};
|
|
1019
|
+
if (existingExports["./styles.css"]) exports1["./styles.css"] = existingExports["./styles.css"];
|
|
1020
|
+
for (const importPath of imports){
|
|
1021
|
+
const { directory, name, exportPath } = importPath;
|
|
1022
|
+
const esmOutput = this.formatOutputPath(packageConfig.esmOutputPattern, directory, name);
|
|
1023
|
+
const cjsOutput = this.formatOutputPath(packageConfig.cjsOutputPattern, directory, name);
|
|
1024
|
+
const typesOutput = this.formatOutputPath(packageConfig.typesOutputPattern, directory, name);
|
|
1025
|
+
const typesCjsOutput = this.formatOutputPath(packageConfig.typesOutputCjsPattern, directory, name);
|
|
1026
|
+
exports1[exportPath] = {
|
|
1027
|
+
import: {
|
|
1028
|
+
default: esmOutput,
|
|
1029
|
+
types: typesOutput
|
|
1030
|
+
},
|
|
1031
|
+
require: {
|
|
1032
|
+
default: cjsOutput,
|
|
1033
|
+
types: typesCjsOutput
|
|
1034
|
+
}
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
1037
|
+
return exports1;
|
|
1038
|
+
}
|
|
1039
|
+
getConfig(configPath) {
|
|
1040
|
+
if (this.cachedConfig && !configPath) return this.cachedConfig;
|
|
1041
|
+
const userConfig = this.loadConfigFile(configPath);
|
|
1042
|
+
const config = (0, external_lodash_es_namespaceObject.merge)({}, this.defaultConfig, userConfig);
|
|
1043
|
+
if (!configPath) this.cachedConfig = config;
|
|
1044
|
+
return config;
|
|
1045
|
+
}
|
|
1046
|
+
loadConfigFile(configPath) {
|
|
1047
|
+
if (!configPath) return {};
|
|
1048
|
+
try {
|
|
1049
|
+
const fullPath = external_node_path_default().resolve(configPath);
|
|
1050
|
+
if (!this.fileSystemPort.exists(fullPath)) {
|
|
1051
|
+
console.warn(`Configuration file not found at ${fullPath}`);
|
|
1052
|
+
return {};
|
|
1053
|
+
}
|
|
1054
|
+
const configContent = this.fileSystemPort.readFile(fullPath);
|
|
1055
|
+
return scriptConfigSchema.parse(JSON.parse(configContent));
|
|
1056
|
+
} catch (error) {
|
|
1057
|
+
console.error(`Error reading configuration file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1058
|
+
return {};
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
getPackageConfig(packageName, config) {
|
|
1062
|
+
const customConfig = config.customPackageConfigs[packageName] ?? {};
|
|
1063
|
+
return {
|
|
1064
|
+
...config.defaultPackageConfig,
|
|
1065
|
+
...customConfig
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
formatOutputPath(pattern, directory, name) {
|
|
1069
|
+
const dirPart = "." === directory ? "" : `${directory}/`;
|
|
1070
|
+
return pattern.replace("{dir}/", dirPart).replace("{dir}", directory).replace("{name}", name);
|
|
1071
|
+
}
|
|
1072
|
+
saveExportsAnalysis(packageDir, analysis) {
|
|
1073
|
+
const outputDir = external_node_path_default().join(packageDir, ".exports-analysis");
|
|
1074
|
+
this.fileSystemPort.createDirectory(outputDir);
|
|
1075
|
+
this.fileSystemPort.writeFile(external_node_path_default().join(outputDir, "exports-analysis.json"), JSON.stringify(analysis, null, 2));
|
|
1076
|
+
}
|
|
1077
|
+
saveExportsPreview(packageDir, exports1) {
|
|
1078
|
+
const outputDir = external_node_path_default().join(packageDir, ".exports-analysis");
|
|
1079
|
+
this.fileSystemPort.createDirectory(outputDir);
|
|
1080
|
+
this.fileSystemPort.writeFile(external_node_path_default().join(outputDir, "exports-preview.json"), JSON.stringify(exports1, null, 2));
|
|
911
1081
|
}
|
|
912
|
-
return exports1;
|
|
913
1082
|
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1083
|
+
FileSystemPackageRepository = file_system_package_repository_ts_decorate([
|
|
1084
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
1085
|
+
file_system_package_repository_ts_param(0, (0, external_inversify_namespaceObject.inject)(TYPES.FileSystemPort)),
|
|
1086
|
+
file_system_package_repository_ts_param(1, (0, external_inversify_namespaceObject.inject)(TYPES.AnalysisPort)),
|
|
1087
|
+
file_system_package_repository_ts_param(2, (0, external_inversify_namespaceObject.inject)(TYPES.FileSystemUtility)),
|
|
1088
|
+
file_system_package_repository_ts_metadata("design:type", Function),
|
|
1089
|
+
file_system_package_repository_ts_metadata("design:paramtypes", [
|
|
1090
|
+
"undefined" == typeof FileSystemPort ? Object : FileSystemPort,
|
|
1091
|
+
"undefined" == typeof AnalysisPort ? Object : AnalysisPort,
|
|
1092
|
+
"undefined" == typeof FileSystemUtility ? Object : FileSystemUtility
|
|
1093
|
+
])
|
|
1094
|
+
], FileSystemPackageRepository);
|
|
1095
|
+
const projectSchema = external_zod_namespaceObject.z.object({
|
|
1096
|
+
name: external_zod_namespaceObject.z.string().min(1, "Project name cannot be empty").max(100, "Project name is too long (maximum 100 characters)").regex(/^[a-z0-9-~][a-z0-9-._~]*$/, {
|
|
1097
|
+
message: "Project name must be URL-friendly (letters, numbers, hyphens, underscores, dots; no @ or scoped packages)"
|
|
1098
|
+
}).refine((name)=>"." !== name && ".." !== name, {
|
|
1099
|
+
message: "Project name cannot be '.' or '..'"
|
|
1100
|
+
}).refine((name)=>!/^(?<reserved>CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i.test(name), {
|
|
1101
|
+
message: "Project name is a reserved system name"
|
|
1102
|
+
}),
|
|
1103
|
+
directory: external_zod_namespaceObject.z.string().describe("Project directory path"),
|
|
1104
|
+
packageJsonExists: external_zod_namespaceObject.z.boolean().describe("Whether package.json exists in the project directory")
|
|
1105
|
+
});
|
|
1106
|
+
function file_system_project_repository_ts_decorate(decorators, target, key, desc) {
|
|
1107
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1108
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
1109
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1110
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
922
1111
|
}
|
|
923
|
-
function
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
}
|
|
930
|
-
const packageName = packageJson.name;
|
|
931
|
-
if (options.packageFilter && packageName !== options.packageFilter) {
|
|
932
|
-
console.debug(`Skipping ${packageName} (does not match filter)`);
|
|
933
|
-
return false;
|
|
934
|
-
}
|
|
935
|
-
console.info(`Processing package: ${packageName}`);
|
|
936
|
-
const config = getConfig(options.configPath);
|
|
937
|
-
const packageConfig = getPackageConfig(packageName, config);
|
|
938
|
-
const srcIndexPath = external_node_path_default().join(packageDir, packageConfig.srcIndexPath);
|
|
939
|
-
if (!fileExists(srcIndexPath)) {
|
|
940
|
-
console.error(`Source file not found at ${srcIndexPath}`);
|
|
941
|
-
return false;
|
|
942
|
-
}
|
|
943
|
-
console.info(`Analyzing imports from ${srcIndexPath}...`);
|
|
944
|
-
const { imports } = analyzeImports(srcIndexPath, packageConfig);
|
|
945
|
-
if (0 === imports.length) {
|
|
946
|
-
console.warn(`No imports found to analyze in ${packageName}`);
|
|
947
|
-
return false;
|
|
948
|
-
}
|
|
949
|
-
console.log(`Analysis complete. Found ${imports.length} subpath exports.`);
|
|
950
|
-
saveExportsAnalysis(packageDir, {
|
|
951
|
-
imports
|
|
952
|
-
});
|
|
953
|
-
const newExports = generateExports(packageName, imports, packageJson.exports, config);
|
|
954
|
-
const currentExportsCount = packageJson.exports ? Object.keys(packageJson.exports).length : 0;
|
|
955
|
-
const newExportsCount = Object.keys(newExports).length;
|
|
956
|
-
console.info(`Exports: ${currentExportsCount} -> ${newExportsCount}`);
|
|
957
|
-
if (options.dryRun) {
|
|
958
|
-
saveExportsPreview(packageDir, newExports);
|
|
959
|
-
console.warn("Saved exports preview to .exports-analysis");
|
|
960
|
-
console.warn(`Dry run: no changes saved for ${packageName}`);
|
|
961
|
-
return true;
|
|
962
|
-
}
|
|
963
|
-
if (backupPackageJson(packageJsonPath)) console.log(`Backed up ${packageJsonPath}`);
|
|
964
|
-
const updatedPackageJson = {
|
|
965
|
-
...packageJson,
|
|
966
|
-
exports: newExports
|
|
1112
|
+
function file_system_project_repository_ts_metadata(k, v) {
|
|
1113
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
1114
|
+
}
|
|
1115
|
+
function file_system_project_repository_ts_param(paramIndex, decorator) {
|
|
1116
|
+
return function(target, key) {
|
|
1117
|
+
decorator(target, key, paramIndex);
|
|
967
1118
|
};
|
|
968
|
-
if (savePackageJson(packageJsonPath, updatedPackageJson)) {
|
|
969
|
-
console.log(`Updated exports for ${packageName}`);
|
|
970
|
-
return true;
|
|
971
|
-
}
|
|
972
|
-
console.error(`Failed to update ${packageJsonPath}`);
|
|
973
|
-
return false;
|
|
974
1119
|
}
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
let
|
|
984
|
-
let
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1120
|
+
class FileSystemProjectRepository {
|
|
1121
|
+
constructor(fileSystemPort, commandExecutorPort, promptPort, fileSystemUtility){
|
|
1122
|
+
this.fileSystemPort = fileSystemPort;
|
|
1123
|
+
this.commandExecutorPort = commandExecutorPort;
|
|
1124
|
+
this.promptPort = promptPort;
|
|
1125
|
+
this.fileSystemUtility = fileSystemUtility;
|
|
1126
|
+
}
|
|
1127
|
+
async checkExistingProject(projectName) {
|
|
1128
|
+
let fullPath = process.cwd();
|
|
1129
|
+
let name = "";
|
|
1130
|
+
const packageJsonPath = external_node_path_default().join(process.cwd(), "package.json");
|
|
1131
|
+
const packageJsonExists = this.fileSystemPort.exists(packageJsonPath);
|
|
1132
|
+
if (packageJsonExists) {
|
|
1133
|
+
const result = packageJsonSchema.safeParse(JSON.parse(this.fileSystemPort.readFile(packageJsonPath)));
|
|
1134
|
+
if (result.success) name = result.data.name;
|
|
1135
|
+
} else {
|
|
1136
|
+
name = await this.getValidProjectName(projectName);
|
|
1137
|
+
fullPath = external_node_path_default().resolve(process.cwd(), name);
|
|
990
1138
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1139
|
+
return {
|
|
1140
|
+
name,
|
|
1141
|
+
directory: fullPath,
|
|
1142
|
+
packageJsonExists
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
createNextProject(projectName) {
|
|
1146
|
+
const flags = '--ts --tailwind --eslint --app --turbo --use-pnpm --src-dir --turbopack --import-alias "@/*"';
|
|
1147
|
+
this.commandExecutorPort.runCommand(`npx create-next-app@latest ${projectName} ${flags}`);
|
|
1148
|
+
}
|
|
1149
|
+
updateLayoutFile(projectDir) {
|
|
1150
|
+
const layoutPath = external_node_path_default().join(projectDir, "src", "app", "layout.tsx");
|
|
1151
|
+
const htmlTarget = '<html className={cn(fontVariables, "antialiased")} lang="en">';
|
|
1152
|
+
this.fileSystemUtility.updateFileIfNeeded(layoutPath, (content)=>content.includes(htmlTarget), (content)=>{
|
|
1153
|
+
const newImports = `import type { Metadata } from "next";
|
|
1154
|
+
import type { JSX, ReactNode } from "react";
|
|
1155
|
+
import { cn } from "@codefast/ui";
|
|
1156
|
+
import { fontVariables } from "@/lib/fonts";
|
|
1157
|
+
import "@/app/globals.css";`;
|
|
1158
|
+
let result = content;
|
|
1159
|
+
result = result.replaceAll(/import\s+{[^}]+}\s+from\s+["']next\/font\/google["'];\s*/g, "");
|
|
1160
|
+
result = result.replace(/const\s+geistSans\s*=[^;]+;\s*const\s+geistMono\s*=[^;]+;\s*/, "");
|
|
1161
|
+
result = result.replace(/import\s+type\s+{[^}]+}\s+from\s+["']next["'];\s*import\s+["']\.\/globals\.css["'];\s*/, newImports);
|
|
1162
|
+
result = result.replace(/export default function RootLayout\({\s*children,\s*}\s*:\s*Readonly<{\s*children:\s*React\.ReactNode;\s*}>\)\s*{/, "export default function RootLayout({ children }: Readonly<{ children: ReactNode }>): JSX.Element {");
|
|
1163
|
+
result = result.replace(/<html\s+lang="en"\s*>/, htmlTarget);
|
|
1164
|
+
result = result.replace(/<body\s+className={`[^`]*`}\s*>/, "<body>");
|
|
1165
|
+
return result;
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
updatePageFile(projectDir) {
|
|
1169
|
+
const pagePath = external_node_path_default().join(projectDir, "src", "app", "page.tsx");
|
|
1170
|
+
this.fileSystemUtility.updateFileIfNeeded(pagePath, (content)=>content.includes("): JSX.Element"), (content)=>{
|
|
1171
|
+
let result = content;
|
|
1172
|
+
if (!result.includes("import type { JSX }")) result = result.includes("import type {") ? result.replace(/import type {(?<types>[^}]+)} from "react";/, 'import type {$1, JSX } from "react";') : result.includes("import {") ? result.replace(/import {/, 'import type { JSX } from "react";\n\nimport {') : `import type { JSX } from "react";\n\n${result}`;
|
|
1173
|
+
result = result.replace(/export default function Home\(\) {/, "export default function Home(): JSX.Element {");
|
|
1174
|
+
return result;
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
updatePostcssConfig(projectDir) {
|
|
1178
|
+
const postcssConfigPath = external_node_path_default().join(projectDir, "postcss.config.mjs");
|
|
1179
|
+
const typeComment = `/** @type {import('postcss-load-config').Config} */\n`;
|
|
1180
|
+
this.fileSystemUtility.updateFileIfNeeded(postcssConfigPath, (content)=>content.includes(typeComment), (content)=>content.replace("const config = {", `${typeComment}const config = {`));
|
|
1181
|
+
}
|
|
1182
|
+
updateNextConfig(projectDir) {
|
|
1183
|
+
const nextConfigPath = external_node_path_default().join(projectDir, "next.config.ts");
|
|
1184
|
+
const optimizePackagesConfig = 'optimizePackageImports: ["@codefast/ui"]';
|
|
1185
|
+
this.fileSystemUtility.updateFileIfNeeded(nextConfigPath, (content)=>content.includes(optimizePackagesConfig), (content)=>content.replace(/const nextConfig: NextConfig = \{/, `const nextConfig: NextConfig = {
|
|
1186
|
+
experimental: {
|
|
1187
|
+
optimizePackageImports: ["@codefast/ui"],
|
|
1188
|
+
},`));
|
|
1189
|
+
}
|
|
1190
|
+
updatePackageJson(projectDir) {
|
|
1191
|
+
const packageJsonPath = external_node_path_default().join(projectDir, "package.json");
|
|
1192
|
+
if (!this.fileSystemPort.exists(packageJsonPath)) return void console.warn(`â ī¸ package.json not found, skipping update.`);
|
|
1193
|
+
let packageJson;
|
|
1194
|
+
try {
|
|
1195
|
+
packageJson = packageJsonSchema.parse(JSON.parse(this.fileSystemPort.readFile(packageJsonPath)));
|
|
1196
|
+
} catch {
|
|
1197
|
+
console.warn(`Failed to parse ${packageJsonPath}, skipping update.`);
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
packageJson.scripts = {
|
|
1201
|
+
...packageJson.scripts,
|
|
1202
|
+
"check-types": "tsc --noEmit",
|
|
1203
|
+
"deploy:preview": "vercel deploy --archive=tgz",
|
|
1204
|
+
"deploy:prod": "vercel deploy --archive=tgz --prod",
|
|
1205
|
+
format: "prettier --write --ignore-unknown .",
|
|
1206
|
+
"format:check": "prettier --check --ignore-unknown .",
|
|
1207
|
+
lint: "next lint --fix --max-warnings 0",
|
|
1208
|
+
"lint:check": "next lint --max-warnings 0",
|
|
1209
|
+
"package:install": "pnpm install",
|
|
1210
|
+
"package:outdated": "pnpm outdated",
|
|
1211
|
+
"package:upgrade": "pnpm update --latest",
|
|
1212
|
+
preview: "pnpm build && pnpm start"
|
|
1213
|
+
};
|
|
1214
|
+
packageJson["simple-git-hooks"] = {
|
|
1215
|
+
"pre-commit": "pnpm lint-staged",
|
|
1216
|
+
"commit-msg": "pnpm commitlint --edit"
|
|
1217
|
+
};
|
|
1218
|
+
this.fileSystemPort.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
1219
|
+
console.log(`đ Updated ${packageJsonPath}`);
|
|
1220
|
+
}
|
|
1221
|
+
async getValidProjectName(initialName, attempts = 0, maxAttempts = 3) {
|
|
1222
|
+
const projectName = initialName ?? await this.promptPort.prompt("Enter project name: ");
|
|
1223
|
+
const result = projectSchema.safeParse({
|
|
1224
|
+
name: projectName,
|
|
1225
|
+
directory: "",
|
|
1226
|
+
packageJsonExists: false
|
|
1227
|
+
});
|
|
1228
|
+
if (result.success) {
|
|
1229
|
+
const fullPath = external_node_path_default().resolve(process.cwd(), projectName);
|
|
1230
|
+
if (this.fileSystemPort.exists(fullPath)) throw new Error(`A directory named "${projectName}" already exists.`);
|
|
1231
|
+
try {
|
|
1232
|
+
this.fileSystemPort.access(process.cwd());
|
|
1233
|
+
} catch {
|
|
1234
|
+
throw new Error("Cannot create project: No write permission in current directory.");
|
|
1235
|
+
}
|
|
1236
|
+
return projectName;
|
|
1237
|
+
}
|
|
1238
|
+
if (attempts >= maxAttempts - 1) throw new Error("Exceeded maximum attempts to enter a valid project name.");
|
|
1239
|
+
console.error(`â ${result.error.message} (${maxAttempts - attempts - 1} attempts remaining)`);
|
|
1240
|
+
return this.getValidProjectName(void 0, attempts + 1, maxAttempts);
|
|
996
1241
|
}
|
|
997
1242
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1243
|
+
FileSystemProjectRepository = file_system_project_repository_ts_decorate([
|
|
1244
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
1245
|
+
file_system_project_repository_ts_param(0, (0, external_inversify_namespaceObject.inject)(TYPES.FileSystemPort)),
|
|
1246
|
+
file_system_project_repository_ts_param(1, (0, external_inversify_namespaceObject.inject)(TYPES.CommandExecutorPort)),
|
|
1247
|
+
file_system_project_repository_ts_param(2, (0, external_inversify_namespaceObject.inject)(TYPES.PromptPort)),
|
|
1248
|
+
file_system_project_repository_ts_param(3, (0, external_inversify_namespaceObject.inject)(TYPES.FileSystemUtility)),
|
|
1249
|
+
file_system_project_repository_ts_metadata("design:type", Function),
|
|
1250
|
+
file_system_project_repository_ts_metadata("design:paramtypes", [
|
|
1251
|
+
"undefined" == typeof FileSystemPort ? Object : FileSystemPort,
|
|
1252
|
+
"undefined" == typeof CommandExecutorPort ? Object : CommandExecutorPort,
|
|
1253
|
+
"undefined" == typeof PromptPort ? Object : PromptPort,
|
|
1254
|
+
"undefined" == typeof FileSystemUtility ? Object : FileSystemUtility
|
|
1255
|
+
])
|
|
1256
|
+
], FileSystemProjectRepository);
|
|
1257
|
+
function dependency_config_service_ts_decorate(decorators, target, key, desc) {
|
|
1258
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1259
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
1260
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1261
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1262
|
+
}
|
|
1263
|
+
class DependencyConfigService {
|
|
1264
|
+
getMainDependencies() {
|
|
1265
|
+
return this.MAIN_DEPENDENCIES;
|
|
1011
1266
|
}
|
|
1012
|
-
|
|
1267
|
+
getDevDependencies() {
|
|
1268
|
+
return this.DEV_DEPENDENCIES;
|
|
1269
|
+
}
|
|
1270
|
+
getPackagesToRemove() {
|
|
1271
|
+
return this.PACKAGES_TO_REMOVE;
|
|
1272
|
+
}
|
|
1273
|
+
constructor(){
|
|
1274
|
+
this.MAIN_DEPENDENCIES = [
|
|
1275
|
+
"@codefast/ui",
|
|
1276
|
+
"@codefast/hooks",
|
|
1277
|
+
"recharts",
|
|
1278
|
+
"react-hook-form",
|
|
1279
|
+
"next-themes",
|
|
1280
|
+
"date-fns",
|
|
1281
|
+
"lucide-react"
|
|
1282
|
+
];
|
|
1283
|
+
this.DEV_DEPENDENCIES = {
|
|
1284
|
+
commitLint: [
|
|
1285
|
+
"@commitlint/cli",
|
|
1286
|
+
"@commitlint/config-conventional",
|
|
1287
|
+
"@commitlint/types"
|
|
1288
|
+
],
|
|
1289
|
+
gitTools: [
|
|
1290
|
+
"simple-git-hooks"
|
|
1291
|
+
],
|
|
1292
|
+
formatting: [
|
|
1293
|
+
"prettier",
|
|
1294
|
+
"prettier-plugin-packagejson",
|
|
1295
|
+
"prettier-plugin-tailwindcss",
|
|
1296
|
+
"lint-staged"
|
|
1297
|
+
],
|
|
1298
|
+
linting: [
|
|
1299
|
+
"@codefast/eslint-config"
|
|
1300
|
+
]
|
|
1301
|
+
};
|
|
1302
|
+
this.PACKAGES_TO_REMOVE = [
|
|
1303
|
+
"@eslint/eslintrc",
|
|
1304
|
+
"eslint-config-next"
|
|
1305
|
+
];
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
DependencyConfigService = dependency_config_service_ts_decorate([
|
|
1309
|
+
(0, external_inversify_namespaceObject.injectable)()
|
|
1310
|
+
], DependencyConfigService);
|
|
1013
1311
|
const external_node_url_namespaceObject = require("node:url");
|
|
1014
|
-
function
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
return
|
|
1312
|
+
function node_package_info_service_ts_decorate(decorators, target, key, desc) {
|
|
1313
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1314
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
1315
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1316
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1317
|
+
}
|
|
1318
|
+
function node_package_info_service_ts_metadata(k, v) {
|
|
1319
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
1320
|
+
}
|
|
1321
|
+
function node_package_info_service_ts_param(paramIndex, decorator) {
|
|
1322
|
+
return function(target, key) {
|
|
1323
|
+
decorator(target, key, paramIndex);
|
|
1324
|
+
};
|
|
1019
1325
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1326
|
+
class NodePackageInfoService {
|
|
1327
|
+
constructor(fileSystemPort){
|
|
1328
|
+
this.fileSystemPort = fileSystemPort;
|
|
1329
|
+
}
|
|
1330
|
+
getPackageVersion() {
|
|
1331
|
+
try {
|
|
1332
|
+
const __filename1 = (0, external_node_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__);
|
|
1333
|
+
const __dirname = external_node_path_default().dirname(__filename1);
|
|
1334
|
+
const packageJsonPath = external_node_path_default().resolve(__dirname, "..", "package.json");
|
|
1335
|
+
const packageJsonResult = packageJsonSchema.parse(JSON.parse(this.fileSystemPort.readFile(packageJsonPath)));
|
|
1336
|
+
return packageJsonResult.version ?? "0.0.0";
|
|
1337
|
+
} catch (error) {
|
|
1338
|
+
console.warn(`Failed to read package version: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1339
|
+
return "unknown";
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
NodePackageInfoService = node_package_info_service_ts_decorate([
|
|
1344
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
1345
|
+
node_package_info_service_ts_param(0, (0, external_inversify_namespaceObject.inject)(TYPES.FileSystemPort)),
|
|
1346
|
+
node_package_info_service_ts_metadata("design:type", Function),
|
|
1347
|
+
node_package_info_service_ts_metadata("design:paramtypes", [
|
|
1348
|
+
"undefined" == typeof FileSystemPort ? Object : FileSystemPort
|
|
1349
|
+
])
|
|
1350
|
+
], NodePackageInfoService);
|
|
1351
|
+
function file_system_utility_ts_decorate(decorators, target, key, desc) {
|
|
1352
|
+
var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1353
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
1354
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1355
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1356
|
+
}
|
|
1357
|
+
function file_system_utility_ts_metadata(k, v) {
|
|
1358
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
1359
|
+
}
|
|
1360
|
+
function file_system_utility_ts_param(paramIndex, decorator) {
|
|
1361
|
+
return function(target, key) {
|
|
1362
|
+
decorator(target, key, paramIndex);
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
class file_system_utility_FileSystemUtility {
|
|
1366
|
+
constructor(fileSystemPort){
|
|
1367
|
+
this.fileSystemPort = fileSystemPort;
|
|
1368
|
+
}
|
|
1369
|
+
updateFileIfNeeded(filePath, checkFn, updateFn) {
|
|
1370
|
+
if (!this.fileSystemPort.exists(filePath)) return;
|
|
1371
|
+
const currentContent = this.fileSystemPort.readFile(filePath);
|
|
1372
|
+
if (checkFn(currentContent)) return void console.log(`âšī¸ ${filePath} is already up to date`);
|
|
1373
|
+
try {
|
|
1374
|
+
const updatedContent = updateFn(currentContent);
|
|
1375
|
+
this.fileSystemPort.writeFile(filePath, updatedContent);
|
|
1376
|
+
console.log(`đ Updated ${filePath}`);
|
|
1377
|
+
} catch (error) {
|
|
1378
|
+
console.warn(`â ī¸ Failed to update ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
backupFile(filePath, backupDir) {
|
|
1382
|
+
try {
|
|
1383
|
+
const content = this.fileSystemPort.readFile(filePath);
|
|
1384
|
+
const baseName = external_node_path_default().basename(filePath);
|
|
1385
|
+
const timestamp = new Date().toISOString().replaceAll(/[:.]/g, "-");
|
|
1386
|
+
const backupPath = external_node_path_default().join(external_node_path_default().dirname(filePath), backupDir, `${baseName}.backup.${timestamp}`);
|
|
1387
|
+
this.fileSystemPort.createDirectory(external_node_path_default().dirname(backupPath));
|
|
1388
|
+
this.fileSystemPort.writeFile(backupPath, content);
|
|
1389
|
+
} catch (error) {
|
|
1390
|
+
console.error(`Error backing up ${filePath}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1022
1393
|
}
|
|
1394
|
+
file_system_utility_FileSystemUtility = file_system_utility_ts_decorate([
|
|
1395
|
+
(0, external_inversify_namespaceObject.injectable)(),
|
|
1396
|
+
file_system_utility_ts_param(0, (0, external_inversify_namespaceObject.inject)(TYPES.FileSystemPort)),
|
|
1397
|
+
file_system_utility_ts_metadata("design:type", Function),
|
|
1398
|
+
file_system_utility_ts_metadata("design:paramtypes", [
|
|
1399
|
+
"undefined" == typeof FileSystemPort ? Object : FileSystemPort
|
|
1400
|
+
])
|
|
1401
|
+
], file_system_utility_FileSystemUtility);
|
|
1402
|
+
const container = new external_inversify_namespaceObject.Container();
|
|
1403
|
+
container.bind(TYPES.ProjectRepository).to(FileSystemProjectRepository).inSingletonScope();
|
|
1404
|
+
container.bind(TYPES.PackageRepository).to(FileSystemPackageRepository).inSingletonScope();
|
|
1405
|
+
container.bind(TYPES.PackageInfoService).to(NodePackageInfoService).inSingletonScope();
|
|
1406
|
+
container.bind(TYPES.DependencyConfigService).to(DependencyConfigService).inSingletonScope();
|
|
1407
|
+
container.bind(TYPES.ConfigService).to(ConfigService).inSingletonScope();
|
|
1408
|
+
container.bind(TYPES.FileSystemPort).to(NodeFileSystemAdapter).inSingletonScope();
|
|
1409
|
+
container.bind(TYPES.CommandExecutorPort).to(NodeCommandExecutorAdapter).inSingletonScope();
|
|
1410
|
+
container.bind(TYPES.PromptPort).to(NodePromptAdapter).inSingletonScope();
|
|
1411
|
+
container.bind(TYPES.AnalysisPort).to(TsMorphAnalysisAdapter).inSingletonScope();
|
|
1412
|
+
container.bind(TYPES.CreateProjectUseCase).to(create_project_use_case_CreateProjectUseCase).inSingletonScope();
|
|
1413
|
+
container.bind(TYPES.UpdateExportsUseCase).to(update_exports_use_case_UpdateExportsUseCase).inSingletonScope();
|
|
1414
|
+
container.bind(TYPES.CreateProjectCommand).to(CreateProjectCommand).inSingletonScope();
|
|
1415
|
+
container.bind(TYPES.UpdateExportsCommand).to(UpdateExportsCommand).inSingletonScope();
|
|
1416
|
+
container.bind(TYPES.CLIAdapter).to(CLIAdapter).inSingletonScope();
|
|
1417
|
+
container.bind(TYPES.FileSystemUtility).to(file_system_utility_FileSystemUtility).inSingletonScope();
|
|
1023
1418
|
function main() {
|
|
1024
|
-
const
|
|
1025
|
-
|
|
1419
|
+
const cliAdapter = container.get(TYPES.CLIAdapter);
|
|
1420
|
+
cliAdapter.initialize();
|
|
1026
1421
|
}
|
|
1027
1422
|
main();
|
|
1028
1423
|
for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|