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