create-next-mui 0.1.2 → 0.1.4
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 +149 -54
- package/{next-mui-template-ts → next-mui-templates/base-js}/package-lock.json +39 -5
- package/{next-mui-template-js → next-mui-templates/base-js}/package.json +1 -1
- package/{next-mui-template-js → next-mui-templates/base-ts}/package-lock.json +37 -3
- package/{next-mui-template-ts → next-mui-templates/base-ts}/package.json +1 -1
- package/package.json +2 -4
- package/src/index.js +249 -60
- /package/{next-mui-template-js → next-mui-templates/base-js}/.vscode/settings.json +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/.vscode/typescript.code-snippets +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/eslint.config.mjs +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/jsconfig.json +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/next.config.js +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/public/mui.svg +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/public/next.svg +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/public/vercel.svg +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/app/favicon.ico +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/app/globals.css +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/app/layout.jsx +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/app/page.jsx +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/config-global.js +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/lib/router-link/index.js +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/sections/home/view.jsx +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/core/colors.json +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/core/components/button.js +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/core/components/card.js +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/core/components/index.js +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/core/palette.js +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/core/typography.js +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/create-theme.js +0 -0
- /package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/theme-provider.jsx +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/.vscode/settings.json +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/.vscode/typescript.code-snippets +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/eslint.config.mjs +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/next.config.ts +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/public/mui.svg +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/public/next.svg +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/public/vercel.svg +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/app/favicon.ico +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/app/globals.css +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/app/layout.tsx +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/app/page.tsx +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/config-global.ts +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/lib/router-link/index.ts +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/sections/home/view.tsx +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/core/colors.json +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/core/components/button.ts +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/core/components/card.ts +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/core/components/index.ts +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/core/palette.ts +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/core/typography.ts +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/create-theme.ts +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/theme-provider.tsx +0 -0
- /package/{next-mui-template-ts → next-mui-templates/base-ts}/tsconfig.json +0 -0
package/README.md
CHANGED
|
@@ -1,122 +1,217 @@
|
|
|
1
|
-
<img width="1420"
|
|
1
|
+
<img width="1420" alt="CREATE-NEXT-MUI-BANNER" src="https://github.com/user-attachments/assets/11e72fc8-6b6d-40c4-97a1-c05f7b943e02" />
|
|
2
2
|
|
|
3
|
-
# create-next-mui
|
|
3
|
+
# create-next-mui
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/create-next-mui)
|
|
6
|
-
[](https://nextjs.org/)
|
|
7
|
+
[](https://mui.com/)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Scaffold a production-ready **Next.js + Material UI** application in seconds.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The generated project comes preconfigured with:
|
|
12
|
+
|
|
13
|
+
- ⚡ Next.js App Router
|
|
14
|
+
- 🎨 Material UI
|
|
15
|
+
- 📦 TypeScript or JavaScript templates
|
|
16
|
+
- 🧹 ESLint Flat Config
|
|
17
|
+
- 📁 Scalable project structure
|
|
18
|
+
|
|
19
|
+
No global installation required.
|
|
12
20
|
|
|
13
21
|
---
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
# Quick Start
|
|
24
|
+
|
|
25
|
+
Create a new project:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx create-next-mui my-app
|
|
29
|
+
```
|
|
16
30
|
|
|
17
|
-
|
|
31
|
+
or
|
|
18
32
|
|
|
19
33
|
```bash
|
|
20
|
-
|
|
34
|
+
npm init next-mui
|
|
35
|
+
```
|
|
21
36
|
|
|
22
|
-
|
|
37
|
+
If no project name is provided, the CLI will guide you through the setup interactively.
|
|
23
38
|
|
|
39
|
+
```bash
|
|
24
40
|
npx create-next-mui
|
|
41
|
+
```
|
|
25
42
|
|
|
26
|
-
|
|
43
|
+
---
|
|
27
44
|
|
|
28
|
-
|
|
45
|
+
# Non-interactive Mode
|
|
46
|
+
|
|
47
|
+
Use the `--yes` (or `-y`) flag to skip prompts and accept the default configuration.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx create-next-mui my-app --yes
|
|
29
51
|
```
|
|
30
52
|
|
|
31
|
-
|
|
53
|
+
This will automatically:
|
|
32
54
|
|
|
33
|
-
|
|
55
|
+
- use the provided project name
|
|
56
|
+
- select the **TypeScript** template
|
|
57
|
+
- generate the project without prompting
|
|
34
58
|
|
|
35
|
-
|
|
59
|
+
This is especially useful for:
|
|
36
60
|
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
- **📦 Pure & Lightweight:** Zero bloat. Template files are automatically stripped of development artifacts (`node_modules`, caches) before build deployment.
|
|
61
|
+
- CI/CD pipelines
|
|
62
|
+
- automation scripts
|
|
63
|
+
- testing
|
|
64
|
+
- quick project generation
|
|
42
65
|
|
|
43
66
|
---
|
|
44
67
|
|
|
45
|
-
|
|
68
|
+
# Interactive Setup
|
|
69
|
+
|
|
70
|
+
Without `--yes`, the CLI walks you through the available options.
|
|
46
71
|
|
|
47
|
-
|
|
72
|
+
Current prompts include:
|
|
48
73
|
|
|
49
|
-
|
|
50
|
-
|
|
74
|
+
- Project name
|
|
75
|
+
- Language selection
|
|
76
|
+
- TypeScript (recommended)
|
|
77
|
+
- JavaScript
|
|
78
|
+
- Features
|
|
79
|
+
- Zustand
|
|
80
|
+
- React Query ( TanStack Query )
|
|
51
81
|
|
|
52
82
|
---
|
|
53
83
|
|
|
54
|
-
|
|
84
|
+
# Available Templates
|
|
85
|
+
|
|
86
|
+
## TypeScript
|
|
87
|
+
|
|
88
|
+
Recommended for most projects.
|
|
89
|
+
|
|
90
|
+
Includes:
|
|
91
|
+
|
|
92
|
+
- TypeScript
|
|
93
|
+
- strict type checking
|
|
94
|
+
- MUI theme typings
|
|
95
|
+
- ESLint Flat Config
|
|
96
|
+
|
|
97
|
+
## JavaScript
|
|
98
|
+
|
|
99
|
+
For developers who prefer JavaScript.
|
|
55
100
|
|
|
56
|
-
|
|
101
|
+
Includes:
|
|
102
|
+
|
|
103
|
+
- modern JavaScript
|
|
104
|
+
- Material UI
|
|
105
|
+
- ESLint Flat Config
|
|
106
|
+
|
|
107
|
+
## Features
|
|
108
|
+
|
|
109
|
+
- Zustand
|
|
110
|
+
- React Query ( TanStack Query )
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
# Generated Project Structure
|
|
57
115
|
|
|
58
116
|
```text
|
|
59
|
-
my-
|
|
117
|
+
my-app/
|
|
60
118
|
├── src/
|
|
61
119
|
│ ├── app/
|
|
62
|
-
│
|
|
63
|
-
│ │ └── page.js/ts # Pre-built home view utilizing responsive MUI layouts
|
|
64
|
-
│ ├── components/ # Reusable global presentation components
|
|
120
|
+
│ ├── components/
|
|
65
121
|
│ └── theme/
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
├── eslint.config.mjs # Elite natural line-length linting layout
|
|
69
|
-
├── next.config.js # Configured optimization vectors
|
|
122
|
+
├── eslint.config.mjs
|
|
123
|
+
├── next.config.js
|
|
70
124
|
├── package.json
|
|
71
125
|
└── README.md
|
|
72
|
-
|
|
73
126
|
```
|
|
74
127
|
|
|
75
128
|
---
|
|
76
129
|
|
|
77
|
-
|
|
130
|
+
# What's Included
|
|
78
131
|
|
|
79
|
-
|
|
132
|
+
Every generated project comes configured with:
|
|
80
133
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
134
|
+
- Next.js App Router
|
|
135
|
+
- Material UI
|
|
136
|
+
- Theme Provider
|
|
137
|
+
- Emotion integration
|
|
138
|
+
- ESLint v9 Flat Config
|
|
139
|
+
- eslint-plugin-perfectionist
|
|
140
|
+
- eslint-plugin-unused-imports
|
|
141
|
+
- organized project structure
|
|
86
142
|
|
|
87
|
-
|
|
143
|
+
Development artifacts such as `node_modules`, `.next`, and build caches are excluded from generated projects.
|
|
88
144
|
|
|
89
145
|
---
|
|
90
146
|
|
|
91
|
-
|
|
147
|
+
# Getting Started
|
|
92
148
|
|
|
93
|
-
|
|
149
|
+
After scaffolding:
|
|
94
150
|
|
|
95
151
|
```bash
|
|
96
|
-
|
|
152
|
+
cd my-app
|
|
97
153
|
npm install
|
|
154
|
+
npm run dev
|
|
155
|
+
```
|
|
98
156
|
|
|
99
|
-
|
|
157
|
+
Useful scripts:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
100
160
|
npm run dev
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Start the development server.
|
|
101
164
|
|
|
102
|
-
|
|
165
|
+
```bash
|
|
103
166
|
npm run lint
|
|
167
|
+
```
|
|
104
168
|
|
|
105
|
-
|
|
169
|
+
Run ESLint.
|
|
170
|
+
|
|
171
|
+
```bash
|
|
106
172
|
npm run build
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Create a production build.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
# CLI Reference
|
|
107
180
|
|
|
181
|
+
## Create a project
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
npx create-next-mui my-app
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Interactive mode
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
npx create-next-mui
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Accept defaults
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
npx create-next-mui my-app --yes
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
or
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
npx create-next-mui my-app -y
|
|
108
203
|
```
|
|
109
204
|
|
|
110
205
|
---
|
|
111
206
|
|
|
112
|
-
|
|
207
|
+
# Contributing
|
|
113
208
|
|
|
114
|
-
Issues and pull requests are
|
|
209
|
+
Issues and pull requests are welcome.
|
|
115
210
|
|
|
116
|
-
|
|
211
|
+
If you'd like to improve the templates or add new features, feel free to open an issue or submit a PR.
|
|
117
212
|
|
|
118
213
|
---
|
|
119
214
|
|
|
120
|
-
|
|
215
|
+
# License
|
|
121
216
|
|
|
122
|
-
|
|
217
|
+
MIT
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "next-mui
|
|
2
|
+
"name": "create-next-mui",
|
|
3
3
|
"version": "0.0.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
|
-
"name": "next-mui
|
|
8
|
+
"name": "create-next-mui",
|
|
9
9
|
"version": "0.0.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@emotion/react": "^11.14.0",
|
|
@@ -276,9 +276,9 @@
|
|
|
276
276
|
}
|
|
277
277
|
},
|
|
278
278
|
"node_modules/@emnapi/wasi-threads": {
|
|
279
|
-
"version": "1.2.
|
|
280
|
-
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.
|
|
281
|
-
"integrity": "sha512-
|
|
279
|
+
"version": "1.2.2",
|
|
280
|
+
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
|
|
281
|
+
"integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
|
|
282
282
|
"dev": true,
|
|
283
283
|
"license": "MIT",
|
|
284
284
|
"optional": true,
|
|
@@ -2312,6 +2312,40 @@
|
|
|
2312
2312
|
"node": ">=14.0.0"
|
|
2313
2313
|
}
|
|
2314
2314
|
},
|
|
2315
|
+
"node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/core": {
|
|
2316
|
+
"version": "1.10.0",
|
|
2317
|
+
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
|
2318
|
+
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
|
|
2319
|
+
"dev": true,
|
|
2320
|
+
"license": "MIT",
|
|
2321
|
+
"optional": true,
|
|
2322
|
+
"dependencies": {
|
|
2323
|
+
"@emnapi/wasi-threads": "1.2.1",
|
|
2324
|
+
"tslib": "^2.4.0"
|
|
2325
|
+
}
|
|
2326
|
+
},
|
|
2327
|
+
"node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": {
|
|
2328
|
+
"version": "1.10.0",
|
|
2329
|
+
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
|
|
2330
|
+
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
|
|
2331
|
+
"dev": true,
|
|
2332
|
+
"license": "MIT",
|
|
2333
|
+
"optional": true,
|
|
2334
|
+
"dependencies": {
|
|
2335
|
+
"tslib": "^2.4.0"
|
|
2336
|
+
}
|
|
2337
|
+
},
|
|
2338
|
+
"node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
|
|
2339
|
+
"version": "1.2.1",
|
|
2340
|
+
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
|
2341
|
+
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
|
|
2342
|
+
"dev": true,
|
|
2343
|
+
"license": "MIT",
|
|
2344
|
+
"optional": true,
|
|
2345
|
+
"dependencies": {
|
|
2346
|
+
"tslib": "^2.4.0"
|
|
2347
|
+
}
|
|
2348
|
+
},
|
|
2315
2349
|
"node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
|
|
2316
2350
|
"version": "1.12.2",
|
|
2317
2351
|
"resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz",
|
|
@@ -276,9 +276,9 @@
|
|
|
276
276
|
}
|
|
277
277
|
},
|
|
278
278
|
"node_modules/@emnapi/wasi-threads": {
|
|
279
|
-
"version": "1.2.
|
|
280
|
-
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.
|
|
281
|
-
"integrity": "sha512-
|
|
279
|
+
"version": "1.2.2",
|
|
280
|
+
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
|
|
281
|
+
"integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
|
|
282
282
|
"dev": true,
|
|
283
283
|
"license": "MIT",
|
|
284
284
|
"optional": true,
|
|
@@ -2312,6 +2312,40 @@
|
|
|
2312
2312
|
"node": ">=14.0.0"
|
|
2313
2313
|
}
|
|
2314
2314
|
},
|
|
2315
|
+
"node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/core": {
|
|
2316
|
+
"version": "1.10.0",
|
|
2317
|
+
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
|
2318
|
+
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
|
|
2319
|
+
"dev": true,
|
|
2320
|
+
"license": "MIT",
|
|
2321
|
+
"optional": true,
|
|
2322
|
+
"dependencies": {
|
|
2323
|
+
"@emnapi/wasi-threads": "1.2.1",
|
|
2324
|
+
"tslib": "^2.4.0"
|
|
2325
|
+
}
|
|
2326
|
+
},
|
|
2327
|
+
"node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": {
|
|
2328
|
+
"version": "1.10.0",
|
|
2329
|
+
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
|
|
2330
|
+
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
|
|
2331
|
+
"dev": true,
|
|
2332
|
+
"license": "MIT",
|
|
2333
|
+
"optional": true,
|
|
2334
|
+
"dependencies": {
|
|
2335
|
+
"tslib": "^2.4.0"
|
|
2336
|
+
}
|
|
2337
|
+
},
|
|
2338
|
+
"node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
|
|
2339
|
+
"version": "1.2.1",
|
|
2340
|
+
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
|
2341
|
+
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
|
|
2342
|
+
"dev": true,
|
|
2343
|
+
"license": "MIT",
|
|
2344
|
+
"optional": true,
|
|
2345
|
+
"dependencies": {
|
|
2346
|
+
"tslib": "^2.4.0"
|
|
2347
|
+
}
|
|
2348
|
+
},
|
|
2315
2349
|
"node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
|
|
2316
2350
|
"version": "1.12.2",
|
|
2317
2351
|
"resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-next-mui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "spin up your nextjs project with mui setup",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nextjs",
|
|
@@ -23,8 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
25
|
"src",
|
|
26
|
-
"next-mui-
|
|
27
|
-
"next-mui-template-js"
|
|
26
|
+
"next-mui-templates"
|
|
28
27
|
],
|
|
29
28
|
"main": "index.js",
|
|
30
29
|
"scripts": {
|
|
@@ -32,7 +31,6 @@
|
|
|
32
31
|
},
|
|
33
32
|
"dependencies": {
|
|
34
33
|
"@clack/prompts": "^1.5.0",
|
|
35
|
-
"degit": "^3.3.2",
|
|
36
34
|
"picocolors": "^1.1.1"
|
|
37
35
|
}
|
|
38
36
|
}
|
package/src/index.js
CHANGED
|
@@ -6,11 +6,15 @@ import fs from "node:fs/promises";
|
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
|
|
9
|
-
//
|
|
9
|
+
// ----------------------------------------------------------------------
|
|
10
|
+
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = path.dirname(__filename);
|
|
12
13
|
|
|
13
14
|
const args = process.argv.slice(2);
|
|
15
|
+
const command = args[0];
|
|
16
|
+
const featureName = args[1];
|
|
17
|
+
|
|
14
18
|
const positionalArgs = args.filter(
|
|
15
19
|
(arg) => !["--yes", "-y", "--js"].includes(arg),
|
|
16
20
|
);
|
|
@@ -23,6 +27,38 @@ const hasJsFlag = args.includes("--js");
|
|
|
23
27
|
|
|
24
28
|
const DEFAULT_LANGUAGE = hasJsFlag ? "js" : "ts";
|
|
25
29
|
|
|
30
|
+
// ----------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
const LANG = [
|
|
33
|
+
{
|
|
34
|
+
value: "ts",
|
|
35
|
+
label: "TypeScript (Recommended)",
|
|
36
|
+
hint: "Strict typings, clean architecture",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
value: "js",
|
|
40
|
+
label: "JavaScript",
|
|
41
|
+
hint: "Vanilla JS configuration",
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const FEATURES = [
|
|
46
|
+
{
|
|
47
|
+
value: "react-query",
|
|
48
|
+
label: "React Query",
|
|
49
|
+
hint: "TanStack Query configuration",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
value: "zustand",
|
|
53
|
+
label: "Zustand",
|
|
54
|
+
hint: "Lightweight global state management",
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
// ----------------------------------------------------------------------
|
|
59
|
+
// Helper Functions
|
|
60
|
+
// ----------------------------------------------------------------------
|
|
61
|
+
|
|
26
62
|
function validateProjectName(value) {
|
|
27
63
|
if (value.length === 0) return "Project name is required!";
|
|
28
64
|
|
|
@@ -39,36 +75,192 @@ function getPackageName(projectName, targetProjectDir) {
|
|
|
39
75
|
}
|
|
40
76
|
|
|
41
77
|
async function updateProjectName(targetProjectDir, packageName) {
|
|
42
|
-
const
|
|
78
|
+
const filePath = path.join(targetProjectDir, "package.json");
|
|
79
|
+
try {
|
|
80
|
+
const content = await fs.readFile(filePath, "utf8");
|
|
81
|
+
const json = JSON.parse(content);
|
|
82
|
+
json.name = packageName;
|
|
43
83
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
84
|
+
if (json.packages?.[""]?.name) {
|
|
85
|
+
json.packages[""].name = packageName;
|
|
86
|
+
}
|
|
87
|
+
await fs.writeFile(filePath, `${JSON.stringify(json, null, 2)}\n`);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error.code === "ENOENT") return;
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function mergePackageJson(targetProjectDir, manifest) {
|
|
95
|
+
const filePath = path.join(targetProjectDir, "package.json");
|
|
96
|
+
try {
|
|
97
|
+
const content = await fs.readFile(filePath, "utf8");
|
|
98
|
+
const json = JSON.parse(content);
|
|
47
99
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
100
|
+
json.dependencies = {
|
|
101
|
+
...json.dependencies,
|
|
102
|
+
...(manifest.dependencies || {}),
|
|
103
|
+
};
|
|
51
104
|
|
|
52
|
-
|
|
105
|
+
json.devDependencies = {
|
|
106
|
+
...json.devDependencies,
|
|
107
|
+
...(manifest.devDependencies || {}),
|
|
108
|
+
};
|
|
53
109
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
110
|
+
await fs.writeFile(filePath, `${JSON.stringify(json, null, 2)}\n`);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
if (error.code === "ENOENT") return;
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function injectProviderToLayout(targetProjectDir, manifest, language) {
|
|
118
|
+
const ext = language === "ts" ? "tsx" : "jsx";
|
|
119
|
+
const layoutPath = path.join(targetProjectDir, "src", "app", `layout.${ext}`);
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
let content = await fs.readFile(layoutPath, "utf8");
|
|
57
123
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
124
|
+
// 1. Inject the Import Line safely below the last import
|
|
125
|
+
if (manifest.importLine && !content.includes(manifest.importLine)) {
|
|
126
|
+
const lines = content.split("\n");
|
|
127
|
+
const lastImportIndex = lines.findLastIndex((line) =>
|
|
128
|
+
line.trim().startsWith("import"),
|
|
129
|
+
);
|
|
61
130
|
|
|
62
|
-
|
|
131
|
+
if (lastImportIndex !== -1) {
|
|
132
|
+
lines.splice(lastImportIndex + 1, 0, manifest.importLine);
|
|
133
|
+
content = lines.join("\n");
|
|
134
|
+
} else {
|
|
135
|
+
content = `${manifest.importLine}\n${content}`;
|
|
63
136
|
}
|
|
64
|
-
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// 2. Wrap {children} dynamically
|
|
140
|
+
if (manifest.expression) {
|
|
141
|
+
const openTag = manifest.expression.open;
|
|
142
|
+
const closeTag = manifest.expression.close;
|
|
143
|
+
|
|
144
|
+
if (!content.includes(openTag)) {
|
|
145
|
+
content = content.replace(
|
|
146
|
+
/(\>\s*)\{\s*children\s*\}(\s*\<)/,
|
|
147
|
+
`$1${openTag} {children} ${closeTag}$2`,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
await fs.writeFile(layoutPath, content, "utf8");
|
|
153
|
+
} catch (error) {
|
|
154
|
+
if (error.code === "ENOENT") return;
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function applyFeature(feature, targetProjectDir, language) {
|
|
160
|
+
const featureDir = path.resolve(
|
|
161
|
+
__dirname,
|
|
162
|
+
"..",
|
|
163
|
+
"next-mui-features",
|
|
164
|
+
feature,
|
|
65
165
|
);
|
|
166
|
+
const manifestPath = path.join(featureDir, "manifest.json");
|
|
167
|
+
const ext = language == "ts" ? "tsx" : "jsx";
|
|
168
|
+
|
|
169
|
+
let manifest = {};
|
|
170
|
+
try {
|
|
171
|
+
const manifestContent = await fs.readFile(manifestPath, "utf8");
|
|
172
|
+
manifest = JSON.parse(manifestContent);
|
|
173
|
+
} catch {
|
|
174
|
+
// Fail-safe if manifest is missing or malformed
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 1. Copy feature-specific files from the language subdirectory
|
|
179
|
+
if (manifest.files) {
|
|
180
|
+
for (const file of manifest.files) {
|
|
181
|
+
const srcPath = path.resolve(featureDir, language, `${file.src}.${ext}`);
|
|
182
|
+
const destPath = path.resolve(targetProjectDir, `${file.dest}.${ext}`);
|
|
183
|
+
|
|
184
|
+
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
|
185
|
+
await fs.copyFile(srcPath, destPath);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 2. Merge dependencies into package.json
|
|
190
|
+
await mergePackageJson(targetProjectDir, manifest);
|
|
191
|
+
|
|
192
|
+
// 3. Perform dynamic layout file nesting
|
|
193
|
+
await injectProviderToLayout(targetProjectDir, manifest, language);
|
|
66
194
|
}
|
|
67
195
|
|
|
196
|
+
// ----------------------------------------------------------------------
|
|
197
|
+
// Main Execution Control Loop
|
|
198
|
+
// ----------------------------------------------------------------------
|
|
199
|
+
|
|
68
200
|
async function main() {
|
|
69
201
|
console.clear();
|
|
202
|
+
|
|
70
203
|
p.intro(color.bgBlue(color.white(" create-next-mui ")));
|
|
71
204
|
|
|
205
|
+
// ----------------------------------------------------------------------
|
|
206
|
+
// Add Feature Command Pipeline
|
|
207
|
+
// ----------------------------------------------------------------------
|
|
208
|
+
|
|
209
|
+
if (command === "add") {
|
|
210
|
+
if (!featureName) {
|
|
211
|
+
p.cancel(
|
|
212
|
+
"Please specify a feature.\n\nExample:\ncreate-next-mui add react-query",
|
|
213
|
+
);
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (!FEATURES.some((f) => f.value === featureName)) {
|
|
218
|
+
p.cancel(`Unknown feature "${featureName}".`);
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const projectRoot = process.cwd();
|
|
223
|
+
|
|
224
|
+
// Verify package.json exists in target execution environment
|
|
225
|
+
try {
|
|
226
|
+
await fs.access(path.join(projectRoot, "package.json"));
|
|
227
|
+
} catch {
|
|
228
|
+
p.cancel(
|
|
229
|
+
"No package.json found.\nRun this command inside a Next.js project.",
|
|
230
|
+
);
|
|
231
|
+
process.exit(1);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Auto-detect layout flavor via tsconfig existence
|
|
235
|
+
let language = "js";
|
|
236
|
+
try {
|
|
237
|
+
await fs.access(path.join(projectRoot, "tsconfig.json"));
|
|
238
|
+
language = "ts";
|
|
239
|
+
} catch {
|
|
240
|
+
// Keep fallback as js configuration
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const spinner = p.spinner();
|
|
244
|
+
spinner.start(`Installing ${featureName}...`);
|
|
245
|
+
|
|
246
|
+
try {
|
|
247
|
+
await applyFeature(featureName, projectRoot, language);
|
|
248
|
+
|
|
249
|
+
spinner.stop(color.green(`${featureName} installed successfully.`));
|
|
250
|
+
p.note(`${color.cyan("npm install")}`, "Next Step");
|
|
251
|
+
p.outro(`✨ ${featureName} added successfully!`);
|
|
252
|
+
return;
|
|
253
|
+
} catch (error) {
|
|
254
|
+
spinner.stop(color.red("Failed to install feature."));
|
|
255
|
+
p.note(error.message, "Error");
|
|
256
|
+
process.exit(1);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// ----------------------------------------------------------------------
|
|
261
|
+
// Interactive Fresh Workspace Scaffolding Pipeline
|
|
262
|
+
// ----------------------------------------------------------------------
|
|
263
|
+
|
|
72
264
|
const projectNameError = hasInitialProjectName
|
|
73
265
|
? validateProjectName(PROJECT_NAME)
|
|
74
266
|
: undefined;
|
|
@@ -88,23 +280,22 @@ async function main() {
|
|
|
88
280
|
placeholder: "my-next-mui-app (or '.' for current directory)",
|
|
89
281
|
validate: validateProjectName,
|
|
90
282
|
}),
|
|
283
|
+
|
|
91
284
|
language: () =>
|
|
92
285
|
hasYesFlag
|
|
93
286
|
? Promise.resolve(DEFAULT_LANGUAGE)
|
|
94
287
|
: p.select({
|
|
95
288
|
message: "Choose your language flavor:",
|
|
96
|
-
options:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
},
|
|
107
|
-
],
|
|
289
|
+
options: LANG,
|
|
290
|
+
}),
|
|
291
|
+
|
|
292
|
+
features: () =>
|
|
293
|
+
hasYesFlag
|
|
294
|
+
? Promise.resolve([])
|
|
295
|
+
: p.multiselect({
|
|
296
|
+
message: "Select optional features:",
|
|
297
|
+
required: false,
|
|
298
|
+
options: FEATURES,
|
|
108
299
|
}),
|
|
109
300
|
},
|
|
110
301
|
{
|
|
@@ -115,71 +306,69 @@ async function main() {
|
|
|
115
306
|
},
|
|
116
307
|
);
|
|
117
308
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
309
|
+
const baseTemplateDir = path.resolve(
|
|
310
|
+
__dirname,
|
|
311
|
+
"..",
|
|
312
|
+
"next-mui-templates",
|
|
313
|
+
`base-${project.language}`,
|
|
314
|
+
);
|
|
122
315
|
|
|
123
|
-
// Define destination paths (where the user is running the command)
|
|
124
316
|
const targetProjectDir = path.resolve(process.cwd(), project.name);
|
|
125
317
|
const packageName = getPackageName(project.name, targetProjectDir);
|
|
126
318
|
|
|
127
|
-
// If targeting current directory, make sure it's clean
|
|
128
319
|
if (project.name === ".") {
|
|
129
320
|
try {
|
|
130
|
-
const
|
|
131
|
-
if (
|
|
321
|
+
const files = await fs.readdir(targetProjectDir);
|
|
322
|
+
if (files.length > 0) {
|
|
132
323
|
p.log.error(
|
|
133
324
|
color.red(
|
|
134
|
-
"The current directory is not empty! Please clear it or specify
|
|
325
|
+
"The current directory is not empty! Please clear it or specify another project name.",
|
|
135
326
|
),
|
|
136
327
|
);
|
|
137
328
|
process.exit(1);
|
|
138
329
|
}
|
|
139
|
-
} catch
|
|
140
|
-
// If the directory reading fails completely, we exit safely
|
|
330
|
+
} catch {
|
|
141
331
|
process.exit(1);
|
|
142
332
|
}
|
|
143
333
|
}
|
|
144
334
|
|
|
145
335
|
const s = p.spinner();
|
|
146
|
-
s.start("
|
|
336
|
+
s.start("Scaffolding your Next.js + MUI workspace...");
|
|
147
337
|
|
|
148
338
|
try {
|
|
149
|
-
//
|
|
150
|
-
await fs.cp(
|
|
339
|
+
// 1. Unpack base layout system
|
|
340
|
+
await fs.cp(baseTemplateDir, targetProjectDir, {
|
|
151
341
|
recursive: true,
|
|
152
342
|
filter: (src) => {
|
|
153
|
-
const
|
|
154
|
-
return (
|
|
155
|
-
targetName !== "node_modules" &&
|
|
156
|
-
targetName !== ".next" &&
|
|
157
|
-
targetName !== "out" &&
|
|
158
|
-
targetName !== "build"
|
|
159
|
-
);
|
|
343
|
+
const name = path.basename(src);
|
|
344
|
+
return !["node_modules", ".next", "out", "build"].includes(name);
|
|
160
345
|
},
|
|
161
346
|
});
|
|
347
|
+
|
|
348
|
+
// 2. Map and loop over chosen features sequentially
|
|
349
|
+
for (const feature of project.features) {
|
|
350
|
+
await applyFeature(feature, targetProjectDir, project.language);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// 3. Finalize package.json configuration naming
|
|
162
354
|
await updateProjectName(targetProjectDir, packageName);
|
|
163
355
|
|
|
164
356
|
s.stop(color.green("Workspace scaffolded successfully!"));
|
|
165
357
|
} catch (error) {
|
|
166
|
-
s.stop(color.red("Failed to
|
|
167
|
-
p.note(color.yellow(
|
|
358
|
+
s.stop(color.red("Failed to scaffold workspace."));
|
|
359
|
+
p.note(color.yellow(error.message), "Troubleshooting");
|
|
168
360
|
process.exit(1);
|
|
169
361
|
}
|
|
170
362
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const cdInstruction = isCurrentDir
|
|
174
|
-
? ""
|
|
175
|
-
: `${color.cyan(`cd ${project.name}`)}\n`;
|
|
363
|
+
const cd =
|
|
364
|
+
project.name === "." ? "" : `${color.cyan(`cd ${project.name}`)}\n`;
|
|
176
365
|
|
|
177
366
|
p.note(
|
|
178
|
-
`${
|
|
179
|
-
"Next Steps
|
|
367
|
+
`${cd}${color.cyan("npm install")}\n${color.cyan("npm run dev")}`,
|
|
368
|
+
"Next Steps",
|
|
180
369
|
);
|
|
181
370
|
|
|
182
|
-
p.outro(
|
|
371
|
+
p.outro("✨ Build clean and fast with create-next-mui!");
|
|
183
372
|
}
|
|
184
373
|
|
|
185
374
|
main().catch(console.error);
|
|
File without changes
|
/package/{next-mui-template-js → next-mui-templates/base-js}/.vscode/typescript.code-snippets
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/core/components/button.js
RENAMED
|
File without changes
|
/package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/core/components/card.js
RENAMED
|
File without changes
|
/package/{next-mui-template-js → next-mui-templates/base-js}/src/theme/core/components/index.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{next-mui-template-ts → next-mui-templates/base-ts}/.vscode/typescript.code-snippets
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/core/components/button.ts
RENAMED
|
File without changes
|
/package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/core/components/card.ts
RENAMED
|
File without changes
|
/package/{next-mui-template-ts → next-mui-templates/base-ts}/src/theme/core/components/index.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|