create-react-forge 1.0.0
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/README.md +109 -0
- package/dist/assembler/index.d.ts +100 -0
- package/dist/assembler/index.d.ts.map +1 -0
- package/dist/assembler/index.js +198 -0
- package/dist/assembler/index.js.map +1 -0
- package/dist/assembler/merger.d.ts +14 -0
- package/dist/assembler/merger.d.ts.map +1 -0
- package/dist/assembler/merger.js +58 -0
- package/dist/assembler/merger.js.map +1 -0
- package/dist/cli/index.d.ts +57 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +110 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/parser.d.ts +3 -0
- package/dist/cli/parser.d.ts.map +1 -0
- package/dist/cli/parser.js +50 -0
- package/dist/cli/parser.js.map +1 -0
- package/dist/cli/prompts.d.ts +24 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +126 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/config/builder.d.ts +42 -0
- package/dist/config/builder.d.ts.map +1 -0
- package/dist/config/builder.js +113 -0
- package/dist/config/builder.js.map +1 -0
- package/dist/config/defaults.d.ts +51 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +41 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/schema.d.ts +318 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +100 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/dependencies/resolver.d.ts +43 -0
- package/dist/dependencies/resolver.d.ts.map +1 -0
- package/dist/dependencies/resolver.js +117 -0
- package/dist/dependencies/resolver.js.map +1 -0
- package/dist/docs/architecture-generator.d.ts +3 -0
- package/dist/docs/architecture-generator.d.ts.map +1 -0
- package/dist/docs/architecture-generator.js +73 -0
- package/dist/docs/architecture-generator.js.map +1 -0
- package/dist/docs/index.d.ts +2 -0
- package/dist/docs/index.d.ts.map +1 -0
- package/dist/docs/index.js +2 -0
- package/dist/docs/index.js.map +1 -0
- package/dist/generator/index.d.ts +41 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +201 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle/index.d.ts +2 -0
- package/dist/lifecycle/index.d.ts.map +1 -0
- package/dist/lifecycle/index.js +2 -0
- package/dist/lifecycle/index.js.map +1 -0
- package/dist/lifecycle/installer.d.ts +2 -0
- package/dist/lifecycle/installer.d.ts.map +1 -0
- package/dist/lifecycle/installer.js +14 -0
- package/dist/lifecycle/installer.js.map +1 -0
- package/dist/plugins/index.d.ts +4 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +4 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/loader.d.ts +5 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +16 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/manager.d.ts +9 -0
- package/dist/plugins/manager.d.ts.map +1 -0
- package/dist/plugins/manager.js +41 -0
- package/dist/plugins/manager.js.map +1 -0
- package/dist/plugins/types.d.ts +17 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/templates/registry.d.ts +108 -0
- package/dist/templates/registry.d.ts.map +1 -0
- package/dist/templates/registry.js +238 -0
- package/dist/templates/registry.js.map +1 -0
- package/dist/templates/utils.d.ts +49 -0
- package/dist/templates/utils.d.ts.map +1 -0
- package/dist/templates/utils.js +103 -0
- package/dist/templates/utils.js.map +1 -0
- package/dist/testing/configurer.d.ts +29 -0
- package/dist/testing/configurer.d.ts.map +1 -0
- package/dist/testing/configurer.js +163 -0
- package/dist/testing/configurer.js.map +1 -0
- package/package.json +84 -0
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# react-scaffold
|
|
2
|
+
|
|
3
|
+
Production-ready React CLI scaffolder with first-class testing support, flexible runtimes (Vite/Next.js), and a composable template system based on [bulletproof-react](https://github.com/alan2207/bulletproof-react) architecture.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- đ **Vite & Next.js Support** â Choose your runtime
|
|
8
|
+
- đ§Ş **Testing as First-Class Citizen** â Vitest, Jest, React Testing Library, Playwright, Cypress
|
|
9
|
+
- đ¨ **Flexible Styling** â Tailwind CSS, CSS Modules, or plain CSS
|
|
10
|
+
- đŚ **State Management** â Zustand or Redux Toolkit
|
|
11
|
+
- đ **Data Fetching** â TanStack Query with DevTools
|
|
12
|
+
- đ **Feature-Based Architecture** â Scalable project structure
|
|
13
|
+
- ⥠**Zero Config** â Smart defaults, minimal prompts
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx create-react-forge
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or install globally:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g create-react-forge
|
|
25
|
+
create-react-forge
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## What You Get
|
|
29
|
+
|
|
30
|
+
A production-ready React project with:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
my-app/
|
|
34
|
+
âââ src/
|
|
35
|
+
â âââ app/ # App setup (providers, router)
|
|
36
|
+
â âââ components/ # Shared UI components
|
|
37
|
+
â âââ features/ # Feature-based modules
|
|
38
|
+
â âââ hooks/ # Custom hooks
|
|
39
|
+
â âââ lib/ # Utilities, API client
|
|
40
|
+
â âââ stores/ # State management
|
|
41
|
+
â âââ testing/ # Test utilities, mocks
|
|
42
|
+
â âââ types/ # TypeScript types
|
|
43
|
+
âââ tests/ # E2E tests
|
|
44
|
+
âââ [config files]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Configuration Options
|
|
48
|
+
|
|
49
|
+
| Option | Choices |
|
|
50
|
+
|--------|---------|
|
|
51
|
+
| **Runtime** | Vite, Next.js |
|
|
52
|
+
| **Language** | TypeScript, JavaScript |
|
|
53
|
+
| **Styling** | Tailwind, CSS Modules, CSS |
|
|
54
|
+
| **State** | Zustand, Redux, None |
|
|
55
|
+
| **Data Fetching** | TanStack Query, None |
|
|
56
|
+
| **Unit Testing** | Vitest, Jest |
|
|
57
|
+
| **E2E Testing** | Playwright, Cypress, None |
|
|
58
|
+
| **Package Manager** | npm, yarn, pnpm |
|
|
59
|
+
|
|
60
|
+
## Architecture
|
|
61
|
+
|
|
62
|
+
This project implements a modular, layered CLI architecture. Generated projects follow the [bulletproof-react](https://github.com/alan2207/bulletproof-react) patterns:
|
|
63
|
+
|
|
64
|
+
- Feature-based folder structure
|
|
65
|
+
- Co-located tests with features
|
|
66
|
+
- Centralized API client
|
|
67
|
+
- Type-safe throughout
|
|
68
|
+
|
|
69
|
+
See [ARCHITECTURE.md](./ARCHITECTURE.md) for detailed design documentation.
|
|
70
|
+
|
|
71
|
+
## Development
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Install dependencies
|
|
75
|
+
npm install
|
|
76
|
+
|
|
77
|
+
# Run CLI in dev mode
|
|
78
|
+
npm run dev
|
|
79
|
+
|
|
80
|
+
# Run tests
|
|
81
|
+
npm run test
|
|
82
|
+
npm run test:watch
|
|
83
|
+
|
|
84
|
+
# Build for production
|
|
85
|
+
npm run build
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Contributing
|
|
89
|
+
|
|
90
|
+
We welcome contributions! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
91
|
+
|
|
92
|
+
### Quick Contribution Steps
|
|
93
|
+
|
|
94
|
+
1. Fork the repository
|
|
95
|
+
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
96
|
+
3. Make your changes
|
|
97
|
+
4. Run tests: `npm run test`
|
|
98
|
+
5. Submit a pull request
|
|
99
|
+
|
|
100
|
+
## Related Projects
|
|
101
|
+
|
|
102
|
+
- [bulletproof-react](https://github.com/alan2207/bulletproof-react) â Architecture reference
|
|
103
|
+
- [Vite](https://vitejs.dev/) â Build tool
|
|
104
|
+
- [Next.js](https://nextjs.org/) â React framework
|
|
105
|
+
- [TanStack Query](https://tanstack.com/query) â Data fetching
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { ProjectConfig } from '../config/schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Manages assembly of generated project files
|
|
4
|
+
*/
|
|
5
|
+
export declare class ProjectAssembler {
|
|
6
|
+
private projectPath;
|
|
7
|
+
private config;
|
|
8
|
+
private fileMap;
|
|
9
|
+
private packageJson;
|
|
10
|
+
constructor(projectPath: string, config: ProjectConfig);
|
|
11
|
+
/**
|
|
12
|
+
* Create base package.json structure
|
|
13
|
+
*/
|
|
14
|
+
private createBasePackageJson;
|
|
15
|
+
/**
|
|
16
|
+
* Add a file to the project
|
|
17
|
+
*/
|
|
18
|
+
addFile(filePath: string, content: string): void;
|
|
19
|
+
/**
|
|
20
|
+
* Add multiple files from a Map
|
|
21
|
+
*/
|
|
22
|
+
addFiles(files: Map<string, string>): void;
|
|
23
|
+
/**
|
|
24
|
+
* Get all registered files
|
|
25
|
+
*/
|
|
26
|
+
getFiles(): Map<string, string>;
|
|
27
|
+
/**
|
|
28
|
+
* Add dependencies to package.json
|
|
29
|
+
*/
|
|
30
|
+
addDependencies(deps: Record<string, string>): void;
|
|
31
|
+
/**
|
|
32
|
+
* Add dev dependencies to package.json
|
|
33
|
+
*/
|
|
34
|
+
addDevDependencies(devDeps: Record<string, string>): void;
|
|
35
|
+
/**
|
|
36
|
+
* Add scripts to package.json
|
|
37
|
+
*/
|
|
38
|
+
addScripts(scripts: Record<string, string>): void;
|
|
39
|
+
/**
|
|
40
|
+
* Merge template dependencies and scripts
|
|
41
|
+
*/
|
|
42
|
+
mergeTemplateDeps(data: {
|
|
43
|
+
dependencies: Record<string, string>;
|
|
44
|
+
devDependencies: Record<string, string>;
|
|
45
|
+
scripts: Record<string, string>;
|
|
46
|
+
}): void;
|
|
47
|
+
/**
|
|
48
|
+
* Set package.json content
|
|
49
|
+
*/
|
|
50
|
+
setPackageJson(pkg: PackageJson): void;
|
|
51
|
+
/**
|
|
52
|
+
* Get package.json
|
|
53
|
+
*/
|
|
54
|
+
getPackageJson(): PackageJson;
|
|
55
|
+
/**
|
|
56
|
+
* Sort dependencies alphabetically
|
|
57
|
+
*/
|
|
58
|
+
private sortDependencies;
|
|
59
|
+
/**
|
|
60
|
+
* Finalize package.json with sorted dependencies
|
|
61
|
+
*/
|
|
62
|
+
private finalizePackageJson;
|
|
63
|
+
/**
|
|
64
|
+
* Create project directory
|
|
65
|
+
*/
|
|
66
|
+
createProjectDirectory(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Write a single file to disk
|
|
69
|
+
*/
|
|
70
|
+
private writeFile;
|
|
71
|
+
/**
|
|
72
|
+
* Write all files to disk
|
|
73
|
+
*/
|
|
74
|
+
writeFiles(): {
|
|
75
|
+
filesWritten: number;
|
|
76
|
+
errors: string[];
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Get configuration
|
|
80
|
+
*/
|
|
81
|
+
getConfig(): ProjectConfig;
|
|
82
|
+
/**
|
|
83
|
+
* Get project path
|
|
84
|
+
*/
|
|
85
|
+
getProjectPath(): string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Package.json structure
|
|
89
|
+
*/
|
|
90
|
+
export interface PackageJson {
|
|
91
|
+
name: string;
|
|
92
|
+
version: string;
|
|
93
|
+
private?: boolean;
|
|
94
|
+
type?: string;
|
|
95
|
+
scripts?: Record<string, string>;
|
|
96
|
+
dependencies?: Record<string, string>;
|
|
97
|
+
devDependencies?: Record<string, string>;
|
|
98
|
+
[key: string]: unknown;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assembler/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAyBzD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,WAAW,CAAc;gBAErB,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa;IAMtD;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAY7B;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAMhD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAM1C;;OAEG;IACH,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAI/B;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAOnD;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAOzD;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAOjD;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE;QACtB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACjC,GAAG,IAAI;IAMR;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAItC;;OAEG;IACH,cAAc,IAAI,WAAW;IAI7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAQ3B;;OAEG;IACH,sBAAsB,IAAI,IAAI;IAM9B;;OAEG;IACH,OAAO,CAAC,SAAS;IAiBjB;;OAEG;IACH,UAAU,IAAI;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IA4BxD;;OAEG;IACH,SAAS,IAAI,aAAa;IAI1B;;OAEG;IACH,cAAc,IAAI,MAAM;CAGzB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Template variable substitution patterns
|
|
5
|
+
*/
|
|
6
|
+
const TEMPLATE_VARIABLES = {
|
|
7
|
+
'{{PROJECT_NAME}}': (config) => config.name,
|
|
8
|
+
'{{PROJECT_DESCRIPTION}}': () => 'A production-ready React application',
|
|
9
|
+
'{{AUTHOR}}': () => '',
|
|
10
|
+
'{{LICENSE}}': () => 'MIT',
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Apply template variable substitution to content
|
|
14
|
+
*/
|
|
15
|
+
function applyTemplateVariables(content, config) {
|
|
16
|
+
let result = content;
|
|
17
|
+
for (const [pattern, getValue] of Object.entries(TEMPLATE_VARIABLES)) {
|
|
18
|
+
result = result.replaceAll(pattern, getValue(config));
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Manages assembly of generated project files
|
|
24
|
+
*/
|
|
25
|
+
export class ProjectAssembler {
|
|
26
|
+
constructor(projectPath, config) {
|
|
27
|
+
this.fileMap = new Map();
|
|
28
|
+
this.projectPath = projectPath;
|
|
29
|
+
this.config = config;
|
|
30
|
+
this.packageJson = this.createBasePackageJson();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create base package.json structure
|
|
34
|
+
*/
|
|
35
|
+
createBasePackageJson() {
|
|
36
|
+
return {
|
|
37
|
+
name: this.config.name,
|
|
38
|
+
version: '0.1.0',
|
|
39
|
+
private: true,
|
|
40
|
+
type: 'module',
|
|
41
|
+
scripts: {},
|
|
42
|
+
dependencies: {},
|
|
43
|
+
devDependencies: {},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Add a file to the project
|
|
48
|
+
*/
|
|
49
|
+
addFile(filePath, content) {
|
|
50
|
+
// Apply template variable substitution
|
|
51
|
+
const processedContent = applyTemplateVariables(content, this.config);
|
|
52
|
+
this.fileMap.set(filePath, processedContent);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Add multiple files from a Map
|
|
56
|
+
*/
|
|
57
|
+
addFiles(files) {
|
|
58
|
+
files.forEach((content, path) => {
|
|
59
|
+
this.addFile(path, content);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get all registered files
|
|
64
|
+
*/
|
|
65
|
+
getFiles() {
|
|
66
|
+
return new Map(this.fileMap);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Add dependencies to package.json
|
|
70
|
+
*/
|
|
71
|
+
addDependencies(deps) {
|
|
72
|
+
this.packageJson.dependencies = {
|
|
73
|
+
...this.packageJson.dependencies,
|
|
74
|
+
...deps,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Add dev dependencies to package.json
|
|
79
|
+
*/
|
|
80
|
+
addDevDependencies(devDeps) {
|
|
81
|
+
this.packageJson.devDependencies = {
|
|
82
|
+
...this.packageJson.devDependencies,
|
|
83
|
+
...devDeps,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Add scripts to package.json
|
|
88
|
+
*/
|
|
89
|
+
addScripts(scripts) {
|
|
90
|
+
this.packageJson.scripts = {
|
|
91
|
+
...this.packageJson.scripts,
|
|
92
|
+
...scripts,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Merge template dependencies and scripts
|
|
97
|
+
*/
|
|
98
|
+
mergeTemplateDeps(data) {
|
|
99
|
+
this.addDependencies(data.dependencies);
|
|
100
|
+
this.addDevDependencies(data.devDependencies);
|
|
101
|
+
this.addScripts(data.scripts);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Set package.json content
|
|
105
|
+
*/
|
|
106
|
+
setPackageJson(pkg) {
|
|
107
|
+
this.packageJson = { ...pkg };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get package.json
|
|
111
|
+
*/
|
|
112
|
+
getPackageJson() {
|
|
113
|
+
return this.packageJson;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Sort dependencies alphabetically
|
|
117
|
+
*/
|
|
118
|
+
sortDependencies(deps) {
|
|
119
|
+
return Object.fromEntries(Object.entries(deps).sort(([a], [b]) => a.localeCompare(b)));
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Finalize package.json with sorted dependencies
|
|
123
|
+
*/
|
|
124
|
+
finalizePackageJson() {
|
|
125
|
+
return {
|
|
126
|
+
...this.packageJson,
|
|
127
|
+
dependencies: this.sortDependencies(this.packageJson.dependencies || {}),
|
|
128
|
+
devDependencies: this.sortDependencies(this.packageJson.devDependencies || {}),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Create project directory
|
|
133
|
+
*/
|
|
134
|
+
createProjectDirectory() {
|
|
135
|
+
if (!existsSync(this.projectPath)) {
|
|
136
|
+
mkdirSync(this.projectPath, { recursive: true });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Write a single file to disk
|
|
141
|
+
*/
|
|
142
|
+
writeFile(relativePath, content) {
|
|
143
|
+
const fullPath = join(this.projectPath, relativePath);
|
|
144
|
+
const dir = dirname(fullPath);
|
|
145
|
+
if (!existsSync(dir)) {
|
|
146
|
+
mkdirSync(dir, { recursive: true });
|
|
147
|
+
}
|
|
148
|
+
// Handle binary files (marked with __BINARY__:)
|
|
149
|
+
if (content.startsWith('__BINARY__:')) {
|
|
150
|
+
const sourcePath = content.replace('__BINARY__:', '');
|
|
151
|
+
copyFileSync(sourcePath, fullPath);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
writeFileSync(fullPath, content, 'utf-8');
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Write all files to disk
|
|
159
|
+
*/
|
|
160
|
+
writeFiles() {
|
|
161
|
+
const errors = [];
|
|
162
|
+
let filesWritten = 0;
|
|
163
|
+
this.createProjectDirectory();
|
|
164
|
+
for (const [filePath, content] of this.fileMap.entries()) {
|
|
165
|
+
try {
|
|
166
|
+
this.writeFile(filePath, content);
|
|
167
|
+
filesWritten++;
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
errors.push(`Failed to write ${filePath}: ${error}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Write package.json
|
|
174
|
+
try {
|
|
175
|
+
const pkgPath = join(this.projectPath, 'package.json');
|
|
176
|
+
const finalPkg = this.finalizePackageJson();
|
|
177
|
+
writeFileSync(pkgPath, JSON.stringify(finalPkg, null, 2) + '\n', 'utf-8');
|
|
178
|
+
filesWritten++;
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
errors.push(`Failed to write package.json: ${error}`);
|
|
182
|
+
}
|
|
183
|
+
return { filesWritten, errors };
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get configuration
|
|
187
|
+
*/
|
|
188
|
+
getConfig() {
|
|
189
|
+
return this.config;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Get project path
|
|
193
|
+
*/
|
|
194
|
+
getProjectPath() {
|
|
195
|
+
return this.projectPath;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/assembler/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges configuration objects with smart strategies
|
|
3
|
+
*/
|
|
4
|
+
export declare class ConfigMerger {
|
|
5
|
+
/**
|
|
6
|
+
* Deep merge objects with array concatenation
|
|
7
|
+
*/
|
|
8
|
+
static merge(...objects: Record<string, unknown>[]): Record<string, unknown>;
|
|
9
|
+
/**
|
|
10
|
+
* Merge package.json files intelligently
|
|
11
|
+
*/
|
|
12
|
+
static mergePackageJson(...packages: Record<string, unknown>[]): Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=merger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merger.d.ts","sourceRoot":"","sources":["../../src/assembler/merger.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAM5E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,GAAG,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CA8CzF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import deepmerge from 'deepmerge';
|
|
2
|
+
/**
|
|
3
|
+
* Merges configuration objects with smart strategies
|
|
4
|
+
*/
|
|
5
|
+
export class ConfigMerger {
|
|
6
|
+
/**
|
|
7
|
+
* Deep merge objects with array concatenation
|
|
8
|
+
*/
|
|
9
|
+
static merge(...objects) {
|
|
10
|
+
return deepmerge.all(objects, {
|
|
11
|
+
arrayMerge: (target, source) => [...target, ...source],
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Merge package.json files intelligently
|
|
16
|
+
*/
|
|
17
|
+
static mergePackageJson(...packages) {
|
|
18
|
+
const merged = {};
|
|
19
|
+
for (const pkg of packages) {
|
|
20
|
+
// Regular merge for most fields
|
|
21
|
+
for (const [key, value] of Object.entries(pkg)) {
|
|
22
|
+
if (key === 'scripts') {
|
|
23
|
+
// Merge scripts by combining them
|
|
24
|
+
if (!merged.scripts) {
|
|
25
|
+
merged.scripts = {};
|
|
26
|
+
}
|
|
27
|
+
Object.assign(merged.scripts, value);
|
|
28
|
+
}
|
|
29
|
+
else if (key === 'dependencies' ||
|
|
30
|
+
key === 'devDependencies' ||
|
|
31
|
+
key === 'peerDependencies') {
|
|
32
|
+
// Merge dependencies, later versions win
|
|
33
|
+
if (!merged[key]) {
|
|
34
|
+
merged[key] = {};
|
|
35
|
+
}
|
|
36
|
+
Object.assign(merged[key], value);
|
|
37
|
+
}
|
|
38
|
+
else if (Array.isArray(value)) {
|
|
39
|
+
// Deduplicate arrays
|
|
40
|
+
if (!merged[key]) {
|
|
41
|
+
merged[key] = [];
|
|
42
|
+
}
|
|
43
|
+
merged[key] = Array.from(new Set([...merged[key], ...value]));
|
|
44
|
+
}
|
|
45
|
+
else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
46
|
+
// Deep merge objects
|
|
47
|
+
merged[key] = this.merge(merged[key], value);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// Primitive: later value wins
|
|
51
|
+
merged[key] = value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return merged;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=merger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merger.js","sourceRoot":"","sources":["../../src/assembler/merger.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC;;GAEG;AACH,MAAM,OAAO,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,GAAG,OAAkC;QAChD,OAAO,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE;YAC5B,UAAU,EAAE,CAAC,MAAiB,EAAE,MAAiB,EAAE,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC;SAC7E,CAA4B,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,GAAG,QAAmC;QAC5D,MAAM,MAAM,GAA4B,EAAE,CAAC;QAE3C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,gCAAgC;YAChC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;oBACtB,kCAAkC;oBAClC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;wBACpB,MAAM,CAAC,OAAO,GAAG,EAAE,CAAC;oBACtB,CAAC;oBACD,MAAM,CAAC,MAAM,CACX,MAAM,CAAC,OAAkC,EACzC,KAAgC,CACjC,CAAC;gBACJ,CAAC;qBAAM,IACL,GAAG,KAAK,cAAc;oBACtB,GAAG,KAAK,iBAAiB;oBACzB,GAAG,KAAK,kBAAkB,EAC1B,CAAC;oBACD,yCAAyC;oBACzC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;wBACjB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;oBACnB,CAAC;oBACD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAA4B,EAAE,KAAgC,CAAC,CAAC;gBAC1F,CAAC;qBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBAChC,qBAAqB;oBACrB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;wBACjB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;oBACnB,CAAC;oBACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAI,MAAM,CAAC,GAAG,CAAe,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC/E,CAAC;qBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBAChF,qBAAqB;oBACrB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CACtB,MAAM,CAAC,GAAG,CAA4B,EACtC,KAAgC,CACjC,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,8BAA8B;oBAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { PromptAnswers } from './prompts.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert prompt answers to ProjectConfig
|
|
4
|
+
*/
|
|
5
|
+
export declare function promptAnswersToConfig(answers: PromptAnswers): {
|
|
6
|
+
path: string;
|
|
7
|
+
name: string;
|
|
8
|
+
runtime: "vite" | "nextjs";
|
|
9
|
+
language: "javascript" | "typescript";
|
|
10
|
+
styling: {
|
|
11
|
+
solution: "css" | "tailwind" | "styled-components" | "css-modules";
|
|
12
|
+
};
|
|
13
|
+
stateManagement: "none" | "redux" | "zustand";
|
|
14
|
+
dataFetching: {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
library: "tanstack-query";
|
|
17
|
+
};
|
|
18
|
+
testing: {
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
unit: {
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
runner: "vitest" | "jest";
|
|
23
|
+
};
|
|
24
|
+
component: {
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
library: "testing-library";
|
|
27
|
+
};
|
|
28
|
+
e2e: {
|
|
29
|
+
enabled: boolean;
|
|
30
|
+
runner: "none" | "playwright" | "cypress";
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
linting: {
|
|
34
|
+
prettier: boolean;
|
|
35
|
+
};
|
|
36
|
+
packageManager: "npm" | "yarn" | "pnpm";
|
|
37
|
+
git: {
|
|
38
|
+
init: boolean;
|
|
39
|
+
initialCommit: boolean;
|
|
40
|
+
};
|
|
41
|
+
plugins: {
|
|
42
|
+
name: string;
|
|
43
|
+
config?: unknown;
|
|
44
|
+
}[];
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Validate user input
|
|
48
|
+
*/
|
|
49
|
+
export declare function validateProjectName(name: string): {
|
|
50
|
+
valid: boolean;
|
|
51
|
+
error?: string;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Main CLI entry point
|
|
55
|
+
*/
|
|
56
|
+
export declare function main(): Promise<void>;
|
|
57
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+B3D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAQpF;AAuBD;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA2C1C"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import { ConfigBuilder } from '../config/builder.js';
|
|
4
|
+
import { generateProject } from '../generator/index.js';
|
|
5
|
+
import { promptForProjectDetails } from './prompts.js';
|
|
6
|
+
/**
|
|
7
|
+
* Convert prompt answers to ProjectConfig
|
|
8
|
+
*/
|
|
9
|
+
export function promptAnswersToConfig(answers) {
|
|
10
|
+
const builder = new ConfigBuilder();
|
|
11
|
+
// Resolve project path to absolute path
|
|
12
|
+
const projectPath = resolve(process.cwd(), answers.projectPath);
|
|
13
|
+
builder
|
|
14
|
+
.setName(answers.projectName)
|
|
15
|
+
.setPath(projectPath)
|
|
16
|
+
.setRuntime(answers.runtime)
|
|
17
|
+
.setLanguage(answers.language)
|
|
18
|
+
.setStyling(answers.styling)
|
|
19
|
+
.setStateManagement(answers.stateManagement)
|
|
20
|
+
.setPackageManager(answers.packageManager)
|
|
21
|
+
.setGitInit(answers.git)
|
|
22
|
+
.setDataFetchingEnabled(answers.dataFetching);
|
|
23
|
+
if (answers.testing !== 'none') {
|
|
24
|
+
builder
|
|
25
|
+
.setTestingEnabled(true)
|
|
26
|
+
.setUnitTestRunner(answers.unitRunner)
|
|
27
|
+
.setE2ETestRunner(answers.e2eRunner);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
builder.setTestingEnabled(false);
|
|
31
|
+
}
|
|
32
|
+
if (!answers.git) {
|
|
33
|
+
builder.setGitInit(false);
|
|
34
|
+
}
|
|
35
|
+
return builder.build();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validate user input
|
|
39
|
+
*/
|
|
40
|
+
export function validateProjectName(name) {
|
|
41
|
+
if (!name) {
|
|
42
|
+
return { valid: false, error: 'Project name is required' };
|
|
43
|
+
}
|
|
44
|
+
if (!/^[a-z0-9-]+$/.test(name)) {
|
|
45
|
+
return { valid: false, error: 'Project name must be lowercase alphanumeric with hyphens' };
|
|
46
|
+
}
|
|
47
|
+
return { valid: true };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Display project summary
|
|
51
|
+
*/
|
|
52
|
+
function displayProjectSummary(config) {
|
|
53
|
+
console.log(chalk.cyan('\nđ Project Configuration:\n'));
|
|
54
|
+
console.log(chalk.gray(' Name: ') + chalk.white(config.name));
|
|
55
|
+
console.log(chalk.gray(' Path: ') + chalk.white(config.path));
|
|
56
|
+
console.log(chalk.gray(' Runtime: ') + chalk.white(config.runtime));
|
|
57
|
+
console.log(chalk.gray(' Language: ') + chalk.white(config.language));
|
|
58
|
+
console.log(chalk.gray(' Styling: ') + chalk.white(config.styling.solution));
|
|
59
|
+
console.log(chalk.gray(' State: ') + chalk.white(config.stateManagement || 'none'));
|
|
60
|
+
console.log(chalk.gray(' Data Fetching: ') + chalk.white(config.dataFetching.enabled ? 'TanStack Query' : 'none'));
|
|
61
|
+
console.log(chalk.gray(' Testing: ') + chalk.white(config.testing.enabled ? `${config.testing.unit?.runner}` : 'disabled'));
|
|
62
|
+
if (config.testing.enabled && config.testing.e2e?.enabled) {
|
|
63
|
+
console.log(chalk.gray(' E2E Testing: ') + chalk.white(config.testing.e2e.runner));
|
|
64
|
+
}
|
|
65
|
+
console.log(chalk.gray(' Package Manager: ') + chalk.white(config.packageManager));
|
|
66
|
+
console.log(chalk.gray(' Git: ') + chalk.white(config.git.init ? 'yes' : 'no'));
|
|
67
|
+
console.log();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Main CLI entry point
|
|
71
|
+
*/
|
|
72
|
+
export async function main() {
|
|
73
|
+
console.log(chalk.cyan.bold('\n âď¸ react-setup\n'));
|
|
74
|
+
console.log(chalk.gray(' Production-ready React scaffolder with first-class testing\n'));
|
|
75
|
+
try {
|
|
76
|
+
// Get user input
|
|
77
|
+
const answers = await promptForProjectDetails();
|
|
78
|
+
// Convert to config
|
|
79
|
+
const config = promptAnswersToConfig(answers);
|
|
80
|
+
// Validate
|
|
81
|
+
const validation = new ConfigBuilder(config).validate();
|
|
82
|
+
if (!validation.success) {
|
|
83
|
+
console.error(chalk.red('\nâ Configuration validation failed:'));
|
|
84
|
+
validation.errors?.forEach((error) => console.error(chalk.red(` ⢠${error}`)));
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
// Display summary
|
|
88
|
+
displayProjectSummary(config);
|
|
89
|
+
// Generate project
|
|
90
|
+
console.log(chalk.cyan('đ Creating project...\n'));
|
|
91
|
+
const result = await generateProject(config);
|
|
92
|
+
if (!result.success) {
|
|
93
|
+
console.error(chalk.red('\nâ Project generation failed:'));
|
|
94
|
+
result.errors.forEach((error) => console.error(chalk.red(` ⢠${error}`)));
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
if (result.warnings.length > 0) {
|
|
98
|
+
console.log(chalk.yellow('\nâ ď¸ Warnings:'));
|
|
99
|
+
result.warnings.forEach((warning) => console.log(chalk.yellow(` ⢠${warning}`)));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error instanceof Error && error.message === 'User force closed the prompt') {
|
|
104
|
+
console.log(chalk.yellow('\nâ Setup cancelled\n'));
|
|
105
|
+
process.exit(0);
|
|
106
|
+
}
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=index.js.map
|