@teispace/next-maker 1.15.1 → 1.16.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 +20 -0
- package/README.md +420 -281
- package/dist/index.js +400 -164
- package/dist/index.js.map +4 -4
- package/dist/src/commands/app.d.ts.map +1 -1
- package/dist/src/commands/doctor.d.ts +3 -0
- package/dist/src/commands/doctor.d.ts.map +1 -0
- package/dist/src/commands/env.d.ts +3 -0
- package/dist/src/commands/env.d.ts.map +1 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/layout.d.ts +3 -0
- package/dist/src/commands/layout.d.ts.map +1 -0
- package/dist/src/commands/provider.d.ts +3 -0
- package/dist/src/commands/provider.d.ts.map +1 -0
- package/dist/src/commands/remove.d.ts +3 -0
- package/dist/src/commands/remove.d.ts.map +1 -0
- package/dist/src/commands/setup.d.ts.map +1 -1
- package/dist/src/generators/index.d.ts +4 -0
- package/dist/src/generators/index.d.ts.map +1 -1
- package/dist/src/generators/layout.generator.d.ts +22 -0
- package/dist/src/generators/layout.generator.d.ts.map +1 -0
- package/dist/src/generators/provider.generator.d.ts +14 -0
- package/dist/src/generators/provider.generator.d.ts.map +1 -0
- package/dist/src/generators/templates/layout.template.d.ts +13 -0
- package/dist/src/generators/templates/layout.template.d.ts.map +1 -0
- package/dist/src/generators/templates/provider.template.d.ts +12 -0
- package/dist/src/generators/templates/provider.template.d.ts.map +1 -0
- package/dist/src/manifests/bundle-analyzer.manifest.d.ts +3 -0
- package/dist/src/manifests/bundle-analyzer.manifest.d.ts.map +1 -0
- package/dist/src/manifests/commitizen.manifest.d.ts +3 -0
- package/dist/src/manifests/commitizen.manifest.d.ts.map +1 -0
- package/dist/src/manifests/dark-theme.manifest.d.ts +3 -0
- package/dist/src/manifests/dark-theme.manifest.d.ts.map +1 -0
- package/dist/src/manifests/http-client.manifest.d.ts +3 -0
- package/dist/src/manifests/http-client.manifest.d.ts.map +1 -0
- package/dist/src/manifests/i18n.manifest.d.ts +3 -0
- package/dist/src/manifests/i18n.manifest.d.ts.map +1 -0
- package/dist/src/manifests/index.d.ts +23 -0
- package/dist/src/manifests/index.d.ts.map +1 -0
- package/dist/src/manifests/react-compiler.manifest.d.ts +3 -0
- package/dist/src/manifests/react-compiler.manifest.d.ts.map +1 -0
- package/dist/src/manifests/redux.manifest.d.ts +9 -0
- package/dist/src/manifests/redux.manifest.d.ts.map +1 -0
- package/dist/src/manifests/runner.d.ts +37 -0
- package/dist/src/manifests/runner.d.ts.map +1 -0
- package/dist/src/manifests/security-headers.manifest.d.ts +3 -0
- package/dist/src/manifests/security-headers.manifest.d.ts.map +1 -0
- package/dist/src/manifests/tests.manifest.d.ts +3 -0
- package/dist/src/manifests/tests.manifest.d.ts.map +1 -0
- package/dist/src/manifests/types.d.ts +119 -0
- package/dist/src/manifests/types.d.ts.map +1 -0
- package/dist/src/manifests/validate-scripts.manifest.d.ts +3 -0
- package/dist/src/manifests/validate-scripts.manifest.d.ts.map +1 -0
- package/dist/src/modifiers/env-var.modifier.d.ts +60 -0
- package/dist/src/modifiers/env-var.modifier.d.ts.map +1 -0
- package/dist/src/modifiers/index.d.ts +2 -0
- package/dist/src/modifiers/index.d.ts.map +1 -1
- package/dist/src/modifiers/root-provider.modifier.d.ts +26 -0
- package/dist/src/modifiers/root-provider.modifier.d.ts.map +1 -0
- package/dist/src/services/setup/commitizen/index.d.ts +3 -0
- package/dist/src/services/setup/commitizen/index.d.ts.map +1 -0
- package/dist/src/services/setup/commitizen/package-modifier.d.ts +17 -0
- package/dist/src/services/setup/commitizen/package-modifier.d.ts.map +1 -0
- package/dist/src/services/setup/security-headers/headers.d.ts +29 -0
- package/dist/src/services/setup/security-headers/headers.d.ts.map +1 -0
- package/dist/src/services/setup/security-headers/index.d.ts +3 -0
- package/dist/src/services/setup/security-headers/index.d.ts.map +1 -0
- package/dist/src/services/setup/validate-scripts/index.d.ts +4 -0
- package/dist/src/services/setup/validate-scripts/index.d.ts.map +1 -0
- package/dist/src/services/setup/validate-scripts/package-modifier.d.ts +19 -0
- package/dist/src/services/setup/validate-scripts/package-modifier.d.ts.map +1 -0
- package/dist/src/services/setup/validate-scripts/scripts.d.ts +12 -0
- package/dist/src/services/setup/validate-scripts/scripts.d.ts.map +1 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,151 +1,283 @@
|
|
|
1
1
|
# @teispace/next-maker
|
|
2
2
|
|
|
3
|
-
A CLI that scaffolds Next.js 16+ applications (TypeScript, Tailwind v4, Biome, Pino, Zod, Redux Toolkit, next-intl, Vitest) and co-generates feature-based architecture — pages, components, hooks, Redux slices, API services, locales, and tests.
|
|
3
|
+
A CLI that scaffolds Next.js 16+ applications (TypeScript, Tailwind v4, Biome, Pino, Zod, Redux Toolkit, next-intl, Vitest) and co-generates feature-based architecture — pages, layouts, components, hooks, Redux slices, API services, locales, providers, env vars, and tests. Ships a manifest-driven `doctor` and `remove` for ongoing maintenance.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
### Using npx (Recommended)
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npx @teispace/next-maker <command> [
|
|
10
|
+
npx @teispace/next-maker <command> [args] [options]
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
### Global Installation
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npm install -g @teispace/next-maker
|
|
17
|
-
next-maker <command> [
|
|
17
|
+
next-maker <command> [args] [options]
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Commands at a glance
|
|
23
|
+
|
|
24
|
+
| Category | Command | Purpose |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| Lifecycle | `init [name]` | Create a new Next.js application |
|
|
27
|
+
| Lifecycle | `setup [options]` | Add features to an existing project (retrofit) |
|
|
28
|
+
| Lifecycle | `doctor [options]` | Diagnose drift against known feature manifests |
|
|
29
|
+
| Lifecycle | `remove <feature>` | Reverse a feature install (uses the manifest) |
|
|
30
|
+
| Routing | `page <name>` | Generate a page/route |
|
|
31
|
+
| Routing | `layout <segment>` | Generate a nested layout.tsx |
|
|
32
|
+
| UI | `component <name>` | Shared component with auto-wired barrel exports |
|
|
33
|
+
| State | `feature <name>` | Full feature module (DDD) |
|
|
34
|
+
| State | `slice <name>` | Redux Toolkit slice (auto-registers in rootReducer) |
|
|
35
|
+
| State | `service <name>` | API service (axios/fetch, optional CRUD) |
|
|
36
|
+
| State | `provider <name>` | Context provider with RootProvider auto-wiring |
|
|
37
|
+
| Config | `env <NAME>` | Add an env var (schema + .env.example + .env) |
|
|
38
|
+
| Config | `locale [code]` | Add a new language/locale |
|
|
39
|
+
| Code | `hook <name>` | Custom React hook |
|
|
40
|
+
| Code | `test <file>` | Sibling test stub for a component/hook/slice |
|
|
41
|
+
|
|
42
|
+
Run `npx @teispace/next-maker <command> --help` for the full option list of any command.
|
|
21
43
|
|
|
22
|
-
|
|
44
|
+
---
|
|
23
45
|
|
|
24
|
-
|
|
46
|
+
## Lifecycle commands
|
|
47
|
+
|
|
48
|
+
### `init` — Create a New App
|
|
25
49
|
|
|
26
50
|
```bash
|
|
27
51
|
npx @teispace/next-maker init [project-name]
|
|
28
52
|
```
|
|
29
53
|
|
|
30
|
-
|
|
54
|
+
The starter at [`teispace/nextjs-starter`](https://github.com/teispace/nextjs-starter) is cloned via `degit` and trimmed to match your prompt answers. The `cleanup` step strips opted-out features so the generated project compiles end-to-end on first install.
|
|
31
55
|
|
|
32
|
-
|
|
56
|
+
**Interactive prompts:**
|
|
33
57
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- **Testing** (Vitest + React Testing Library)
|
|
41
|
-
- **React Compiler** (stable — on by default)
|
|
42
|
-
- **Bundle Analyzer** (@next/bundle-analyzer — off by default)
|
|
43
|
-
- **Community Files** (CODE_OF_CONDUCT, CONTRIBUTING, etc.)
|
|
44
|
-
- **Docker** support
|
|
45
|
-
- **CI/CD** configuration
|
|
46
|
-
- **Pre-commit hooks** (Husky)
|
|
58
|
+
| Section | Prompts |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| Identity | project name, description, author, version, support email, package manager, GitHub repo / issues / homepage |
|
|
61
|
+
| Architecture | HTTP client (axios / fetch / both / none), dark mode, Redux Toolkit, i18n, testing, React Compiler, Bundle Analyzer |
|
|
62
|
+
| Tooling | community files (CODE_OF_CONDUCT, CONTRIBUTING, SECURITY), README, Docker, CI/CD, pre-commit hooks (Husky/Commitlint/Lint-staged), Commitizen, copy `.env.example` → `.env` |
|
|
63
|
+
| Templates | keep GitHub issue/PR templates? include `react-secure-storage`? |
|
|
47
64
|
|
|
48
|
-
**
|
|
65
|
+
**Always shipped:**
|
|
49
66
|
|
|
50
67
|
- Next.js 16+ with App Router
|
|
51
68
|
- TypeScript (strict mode)
|
|
52
69
|
- Tailwind CSS v4
|
|
53
|
-
- Biome (single-tool lint + format
|
|
70
|
+
- Biome (single-tool lint + format)
|
|
54
71
|
- Pino structured logger with redaction
|
|
55
|
-
- Zod-validated env schema
|
|
72
|
+
- Zod-validated env schema in `src/lib/env/`
|
|
56
73
|
- Feature-based DDD architecture
|
|
57
|
-
- Result-based HTTP clients (
|
|
74
|
+
- Result-based HTTP clients (when enabled)
|
|
75
|
+
- Hardened security headers in `next.config.ts`
|
|
76
|
+
- `scripts/sync-env.ts` and `scripts/check-deprecated.ts` (used by the `validate` chain)
|
|
58
77
|
|
|
59
78
|
---
|
|
60
79
|
|
|
61
|
-
###
|
|
80
|
+
### `setup` — Retrofit a feature
|
|
62
81
|
|
|
63
|
-
Add
|
|
82
|
+
Add a feature to an existing project (one that wasn't generated by `init`, or one created before a feature existed).
|
|
64
83
|
|
|
65
84
|
```bash
|
|
66
85
|
npx @teispace/next-maker setup [options]
|
|
67
86
|
```
|
|
68
87
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
88
|
+
| Flag | What it does |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| `--http-client` | Adds the axios and/or fetch Result-based clients under `src/lib/utils/http/` |
|
|
91
|
+
| `--dark-theme` | Installs `@teispace/next-themes` and adds `CustomThemeProvider` |
|
|
92
|
+
| `--redux` | Redux Toolkit + `react-redux` + `redux-persist`, `StoreProvider`, `src/store` |
|
|
93
|
+
| `--i18n` | `next-intl` + `[locale]` routing + `proxy.ts` + `RootProvider` wiring |
|
|
94
|
+
| `--tests` | Vitest + React Testing Library + jsdom + `test/test-utils.tsx` |
|
|
95
|
+
| `--react-compiler` | `reactCompiler: true` in `next.config.ts` + `babel-plugin-react-compiler` |
|
|
96
|
+
| `--bundle-analyzer` | Wraps the default export with `withBundleAnalyzer` and adds the `analyze` script |
|
|
97
|
+
| `--security-headers` | Injects the hardened headers block into `next.config.ts` (DNS prefetch, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, X-XSS-Protection) |
|
|
98
|
+
| `--validate-scripts` | Drops in `scripts/sync-env.ts` + `scripts/check-deprecated.ts` and wires `env:sync`, `check:deprecated`, `type-check`, and the `validate` chain (PM-aware) |
|
|
99
|
+
| `--commitizen` | Writes `.czrc`, adds `commit` script, installs `commitizen` + `cz-conventional-changelog` |
|
|
78
100
|
|
|
79
|
-
|
|
101
|
+
Run `setup` without flags for an interactive picker.
|
|
80
102
|
|
|
81
103
|
```bash
|
|
82
|
-
# Interactive
|
|
104
|
+
# Interactive
|
|
83
105
|
npx @teispace/next-maker setup
|
|
84
106
|
|
|
85
|
-
#
|
|
86
|
-
npx @teispace/next-maker setup --http-client
|
|
87
|
-
npx @teispace/next-maker setup --dark-theme
|
|
107
|
+
# Specific feature
|
|
88
108
|
npx @teispace/next-maker setup --redux
|
|
89
|
-
npx @teispace/next-maker setup --
|
|
90
|
-
npx @teispace/next-maker setup --
|
|
91
|
-
npx @teispace/next-maker setup --react-compiler
|
|
92
|
-
npx @teispace/next-maker setup --bundle-analyzer
|
|
109
|
+
npx @teispace/next-maker setup --security-headers
|
|
110
|
+
npx @teispace/next-maker setup --validate-scripts
|
|
93
111
|
```
|
|
94
112
|
|
|
113
|
+
Every `setup` operation is **idempotent** — re-running is a no-op on already-installed parts and a fix-up on missing parts.
|
|
114
|
+
|
|
95
115
|
---
|
|
96
116
|
|
|
97
|
-
###
|
|
117
|
+
### `doctor` — Drift detection
|
|
98
118
|
|
|
99
|
-
|
|
119
|
+
`doctor` walks every feature manifest, asks "is this installed?" and (if yes) "are all of its parts present?". Drift is reported per feature.
|
|
100
120
|
|
|
101
121
|
```bash
|
|
102
|
-
npx @teispace/next-maker
|
|
122
|
+
npx @teispace/next-maker doctor [options]
|
|
103
123
|
```
|
|
104
124
|
|
|
105
|
-
|
|
125
|
+
| Flag | Behaviour |
|
|
126
|
+
| --- | --- |
|
|
127
|
+
| `--fix` | Re-runs `apply()` for every drifted feature (idempotent — safe to retry) |
|
|
128
|
+
| `--feature <id>` | Only check one manifest (e.g. `redux`, `security-headers`) |
|
|
129
|
+
| `--json` | Machine-readable output for CI |
|
|
106
130
|
|
|
107
|
-
|
|
108
|
-
- `--loading` - Generate `loading.tsx`
|
|
109
|
-
- `--error` - Generate `error.tsx`
|
|
131
|
+
Exit code is `0` on a clean report and `1` when drift is found — `next-maker doctor --json` makes a useful CI gate.
|
|
110
132
|
|
|
111
|
-
|
|
133
|
+
```bash
|
|
134
|
+
# Human report
|
|
135
|
+
npx @teispace/next-maker doctor
|
|
112
136
|
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
|
|
137
|
+
# Fix everything that drifted
|
|
138
|
+
npx @teispace/next-maker doctor --fix
|
|
139
|
+
|
|
140
|
+
# CI
|
|
141
|
+
npx @teispace/next-maker doctor --json > health.json
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Sample output:**
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
🩺 Project Doctor
|
|
148
|
+
|
|
149
|
+
✓ Security Headers
|
|
150
|
+
! Validation Scripts (2 issues)
|
|
151
|
+
• missing file: scripts/sync-env.ts
|
|
152
|
+
• missing script: validate
|
|
153
|
+
— Redux Toolkit (not installed)
|
|
154
|
+
✓ Internationalization
|
|
155
|
+
|
|
156
|
+
1 clean, 1 drifted, 1 not installed
|
|
157
|
+
|
|
158
|
+
Run with --fix to re-apply drifted features.
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Manifests live under `src/manifests/`; each one declares the files, packages, scripts, and code blocks the feature consists of. Adding a manifest for a new feature is a single file — `doctor` and `remove` automatically pick it up.
|
|
117
162
|
|
|
118
|
-
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### `remove` — Reverse an install
|
|
166
|
+
|
|
167
|
+
Symmetric to `setup`. Uses the feature manifest to compute the reversal: deletes generated files, strips code blocks (when a `removePattern` is recorded), removes scripts, uninstalls packages.
|
|
119
168
|
|
|
120
169
|
```bash
|
|
121
|
-
|
|
122
|
-
|
|
170
|
+
npx @teispace/next-maker remove <feature> [options]
|
|
171
|
+
```
|
|
123
172
|
|
|
124
|
-
|
|
125
|
-
|
|
173
|
+
| Flag | Behaviour |
|
|
174
|
+
| --- | --- |
|
|
175
|
+
| `--dry-run` | Print the planned changes without writing |
|
|
176
|
+
| `-y, --yes` | Skip the confirmation prompt |
|
|
177
|
+
|
|
178
|
+
Anything the manifest can't safely undo (e.g. unwrapping an outer JSX wrap with multiple sibling providers) is reported as `manual cleanup` rather than guessed.
|
|
179
|
+
|
|
180
|
+
`remove` will **never recursively delete a directory that may hold user-authored content** — `src/app/[locale]/` (your pages), `src/i18n/` (your translations), `src/store/` (your slices), `src/lib/utils/http/` (your service code), and `test/` (your helpers) are flagged in the manifest with `containsUserContent: true` and surface as manual-cleanup with a hint. Move what you want to keep, then `rm -rf` the rest by hand.
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Preview the effect
|
|
184
|
+
npx @teispace/next-maker remove redux --dry-run
|
|
126
185
|
|
|
127
|
-
#
|
|
186
|
+
# Apply with confirmation
|
|
187
|
+
npx @teispace/next-maker remove security-headers
|
|
188
|
+
|
|
189
|
+
# Non-interactive
|
|
190
|
+
npx @teispace/next-maker remove validate-scripts --yes
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Sample plan:**
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
🗑 Remove Validation Scripts
|
|
197
|
+
|
|
198
|
+
Planned changes:
|
|
199
|
+
- delete file: scripts/sync-env.ts
|
|
200
|
+
- delete file: scripts/check-deprecated.ts
|
|
201
|
+
- remove script: env:sync
|
|
202
|
+
- remove script: check:deprecated
|
|
203
|
+
- remove script: validate
|
|
204
|
+
- uninstall: tsx
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Code generators
|
|
210
|
+
|
|
211
|
+
### `page` — Generate a page/route
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
npx @teispace/next-maker page <name> [options]
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
| Flag | Effect |
|
|
218
|
+
| --- | --- |
|
|
219
|
+
| `--dynamic <param>` | Dynamic segment (e.g. `--dynamic id` produces `[id]/page.tsx`) |
|
|
220
|
+
| `--loading` | Generate `loading.tsx` |
|
|
221
|
+
| `--error` | Generate `error.tsx` |
|
|
222
|
+
|
|
223
|
+
**What it does:**
|
|
224
|
+
|
|
225
|
+
- Writes `page.tsx` under `src/app/[locale]/<name>/` (i18n) or `src/app/<name>/`
|
|
226
|
+
- When i18n is detected: `generateMetadata`, `setRequestLocale`, `getTranslations`
|
|
227
|
+
- Registers route in `src/lib/config/app-paths.ts`
|
|
228
|
+
- Adds translation namespace to `en.json`
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
npx @teispace/next-maker page about
|
|
232
|
+
npx @teispace/next-maker page dashboard --loading --error
|
|
128
233
|
npx @teispace/next-maker page products --dynamic id --loading --error
|
|
129
234
|
```
|
|
130
235
|
|
|
131
236
|
---
|
|
132
237
|
|
|
133
|
-
###
|
|
238
|
+
### `layout` — Generate a nested layout
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
npx @teispace/next-maker layout <segment> [options]
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
| Flag | Effect |
|
|
245
|
+
| --- | --- |
|
|
246
|
+
| `--group` | Wraps the segment in parens for a route group, e.g. `(marketing)` |
|
|
247
|
+
| `--at <path>` | Places the layout under a nested path (kebab-case, slash-separated) |
|
|
248
|
+
| `--no-locale` | Skip the locale wrapper even when i18n is detected |
|
|
134
249
|
|
|
135
|
-
|
|
250
|
+
When i18n is detected the generated layout consumes `params: Promise<{ locale: string }>` and calls `setRequestLocale`. Otherwise it's a plain `({ children }) => <>{children}</>` shell.
|
|
136
251
|
|
|
137
252
|
```bash
|
|
138
|
-
|
|
253
|
+
# /[locale]/dashboard/layout.tsx
|
|
254
|
+
npx @teispace/next-maker layout dashboard
|
|
255
|
+
|
|
256
|
+
# Route group: /[locale]/(marketing)/layout.tsx
|
|
257
|
+
npx @teispace/next-maker layout marketing --group
|
|
258
|
+
|
|
259
|
+
# Nested: /[locale]/dashboard/settings/preferences/layout.tsx
|
|
260
|
+
npx @teispace/next-maker layout preferences --at dashboard/settings
|
|
139
261
|
```
|
|
140
262
|
|
|
141
|
-
|
|
263
|
+
Refuses to overwrite an existing `layout.tsx` — explicit error rather than silent loss.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### `component` — Shared component
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
npx @teispace/next-maker component <name> [options]
|
|
271
|
+
```
|
|
142
272
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
273
|
+
| Flag | Effect |
|
|
274
|
+
| --- | --- |
|
|
275
|
+
| `--client` | Adds `'use client'` directive |
|
|
276
|
+
| `--i18n` | Imports `useTranslations` |
|
|
277
|
+
| `--feature <path>` | Generate inside a feature directory |
|
|
278
|
+
| `--test` / `--no-test` | Co-generate a sibling `*.test.tsx` (default: on when Vitest is installed) |
|
|
147
279
|
|
|
148
|
-
**Generated structure
|
|
280
|
+
**Generated structure:**
|
|
149
281
|
|
|
150
282
|
```
|
|
151
283
|
src/components/common/MyButton/
|
|
@@ -155,347 +287,338 @@ src/components/common/MyButton/
|
|
|
155
287
|
|
|
156
288
|
Auto-updates `src/components/common/index.ts` and `src/components/index.ts`.
|
|
157
289
|
|
|
158
|
-
**Examples:**
|
|
159
|
-
|
|
160
290
|
```bash
|
|
161
|
-
# Shared component
|
|
162
291
|
npx @teispace/next-maker component data-table --client
|
|
163
|
-
|
|
164
|
-
# Component with i18n
|
|
165
292
|
npx @teispace/next-maker component nav-bar --client --i18n
|
|
166
|
-
|
|
167
|
-
# Feature-specific component
|
|
168
293
|
npx @teispace/next-maker component user-card --client --feature src/features/auth
|
|
169
294
|
```
|
|
170
295
|
|
|
171
296
|
---
|
|
172
297
|
|
|
173
|
-
###
|
|
174
|
-
|
|
175
|
-
Create a complete feature module following Domain-Driven Design principles.
|
|
298
|
+
### `feature` — Full feature module
|
|
176
299
|
|
|
177
300
|
```bash
|
|
178
301
|
npx @teispace/next-maker feature <name> [options]
|
|
179
302
|
```
|
|
180
303
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
304
|
+
| Flag | Effect |
|
|
305
|
+
| --- | --- |
|
|
306
|
+
| `--store <type>` | Generate Redux store: `persist` or `no-persist` |
|
|
307
|
+
| `--skip-store` | Skip Redux store |
|
|
308
|
+
| `--service <client>` | API service: `axios` or `fetch` |
|
|
309
|
+
| `--skip-service` | Skip API service |
|
|
310
|
+
| `--path <path>` | Custom path (default `src/features`) |
|
|
188
311
|
|
|
189
312
|
**Generated structure:**
|
|
190
313
|
|
|
191
314
|
```
|
|
192
315
|
src/features/user-dashboard/
|
|
193
|
-
├── components/
|
|
194
|
-
|
|
195
|
-
├──
|
|
196
|
-
|
|
197
|
-
├──
|
|
198
|
-
│ └── user-dashboard.types.ts
|
|
199
|
-
├── store/ (optional)
|
|
200
|
-
│ ├── user-dashboard.slice.ts
|
|
201
|
-
│ ├── user-dashboard.selectors.ts
|
|
202
|
-
│ ├── persist.ts (optional)
|
|
203
|
-
│ └── index.ts
|
|
204
|
-
├── services/ (optional)
|
|
205
|
-
│ └── user-dashboard.service.ts
|
|
316
|
+
├── components/UserDashboard.tsx
|
|
317
|
+
├── hooks/useUserDashboard.ts
|
|
318
|
+
├── types/user-dashboard.types.ts
|
|
319
|
+
├── store/ (optional)
|
|
320
|
+
├── services/ (optional)
|
|
206
321
|
└── index.ts
|
|
207
322
|
```
|
|
208
323
|
|
|
209
|
-
**Examples:**
|
|
210
|
-
|
|
211
324
|
```bash
|
|
212
|
-
# Full feature with Redux and API service
|
|
213
325
|
npx @teispace/next-maker feature user-profile --store persist --service axios
|
|
214
|
-
|
|
215
|
-
# Feature with Redux only
|
|
216
326
|
npx @teispace/next-maker feature shopping-cart --store no-persist --skip-service
|
|
217
|
-
|
|
218
|
-
# Feature in custom location
|
|
219
327
|
npx @teispace/next-maker feature auth --store persist --service fetch --path src/modules
|
|
220
328
|
```
|
|
221
329
|
|
|
222
330
|
---
|
|
223
331
|
|
|
224
|
-
###
|
|
225
|
-
|
|
226
|
-
Create a Redux Toolkit slice with persistence support.
|
|
332
|
+
### `slice` — Redux slice
|
|
227
333
|
|
|
228
334
|
```bash
|
|
229
335
|
npx @teispace/next-maker slice <name> [options]
|
|
230
336
|
```
|
|
231
337
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
- `--test` / `--no-test` - Co-generate a sibling `*.slice.test.ts` (default: on when tests are installed)
|
|
338
|
+
| Flag | Effect |
|
|
339
|
+
| --- | --- |
|
|
340
|
+
| `--persist` / `--no-persist` | Toggle redux-persist for this slice |
|
|
341
|
+
| `--path <path>` | Custom path (default: new feature) |
|
|
342
|
+
| `--test` / `--no-test` | Co-generate `*.slice.test.ts` (default: on when Vitest is installed) |
|
|
238
343
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
**Examples:**
|
|
344
|
+
Auto-registers in `rootReducer` with correct imports and persist config.
|
|
242
345
|
|
|
243
346
|
```bash
|
|
244
|
-
# Create new feature with slice
|
|
245
347
|
npx @teispace/next-maker slice auth --persist
|
|
246
|
-
|
|
247
|
-
# Add slice to existing feature
|
|
248
348
|
npx @teispace/next-maker slice user-settings --path features/auth/store
|
|
249
349
|
```
|
|
250
350
|
|
|
251
351
|
---
|
|
252
352
|
|
|
253
|
-
###
|
|
254
|
-
|
|
255
|
-
Create an API service with HTTP client integration. Supports both simple and full CRUD generation.
|
|
353
|
+
### `service` — API service
|
|
256
354
|
|
|
257
355
|
```bash
|
|
258
356
|
npx @teispace/next-maker service <name> [options]
|
|
259
357
|
```
|
|
260
358
|
|
|
261
|
-
|
|
359
|
+
| Flag | Effect |
|
|
360
|
+
| --- | --- |
|
|
361
|
+
| `--axios` / `--fetch` | Pick the HTTP client |
|
|
362
|
+
| `--crud` | Generate full CRUD (`getAll`, `getById`, `create`, `update`, `delete`) |
|
|
363
|
+
| `--path <path>` | Custom path |
|
|
262
364
|
|
|
263
|
-
|
|
264
|
-
- `--fetch` - Use FetchClient
|
|
265
|
-
- `--crud` - Generate full CRUD service (getAll, getById, create, update, delete)
|
|
266
|
-
- `--path <path>` - Custom path (default: create new feature)
|
|
365
|
+
CRUD mode also generates `<Name>Summary` (list view) and `<Name>Detail` (detail view) types, `Create<Name>Dto`, `Update<Name>Dto`, and registers the endpoints in `app-apis.ts`.
|
|
267
366
|
|
|
268
|
-
|
|
367
|
+
```bash
|
|
368
|
+
npx @teispace/next-maker service payment --axios
|
|
369
|
+
npx @teispace/next-maker service users --fetch --crud
|
|
370
|
+
npx @teispace/next-maker service orders --axios --crud --path features/products/services
|
|
371
|
+
```
|
|
269
372
|
|
|
270
|
-
|
|
271
|
-
- `<Name>Summary` type for list responses (cards, tables) and `<Name>Detail` type for single-item responses (detail pages)
|
|
272
|
-
- DTO types: `Create<Name>Dto`, `Update<Name>Dto`
|
|
273
|
-
- Full API config with dynamic routes (`getById(id)`, `update(id)`, `delete(id)`)
|
|
373
|
+
---
|
|
274
374
|
|
|
275
|
-
|
|
375
|
+
### `provider` — Context provider
|
|
276
376
|
|
|
277
377
|
```bash
|
|
278
|
-
|
|
279
|
-
|
|
378
|
+
npx @teispace/next-maker provider <name>
|
|
379
|
+
```
|
|
280
380
|
|
|
281
|
-
|
|
282
|
-
npx @teispace/next-maker service users --fetch --crud
|
|
381
|
+
Generates `src/providers/<Name>Provider.tsx` with:
|
|
283
382
|
|
|
284
|
-
|
|
285
|
-
|
|
383
|
+
- `'use client'` directive
|
|
384
|
+
- `createContext` + typed context value
|
|
385
|
+
- `useX()` hook with non-null guard
|
|
386
|
+
- `<XProvider>` component memoising the value with `useMemo`
|
|
387
|
+
|
|
388
|
+
Then **two-tier auto-wiring**:
|
|
389
|
+
|
|
390
|
+
1. Locates `RootProvider.tsx` — canonical path first (`src/providers/RootProvider.tsx`), heuristic scan as fallback (looks for the deepest `{children}` chain in `src/providers/*.tsx`).
|
|
391
|
+
2. Wraps `{children}` with `<XProvider>` inside that chain, preserving indentation.
|
|
392
|
+
3. Updates `src/providers/index.ts` barrel (re-exports kept sorted).
|
|
393
|
+
|
|
394
|
+
If no candidate is found, the generator prints the snippet to wire manually rather than failing silently.
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
npx @teispace/next-maker provider auth # → AuthProvider, useAuth
|
|
398
|
+
npx @teispace/next-maker provider session # → SessionProvider, useSession
|
|
399
|
+
npx @teispace/next-maker provider analytics-provider # already-suffixed names work
|
|
286
400
|
```
|
|
287
401
|
|
|
402
|
+
The wrap is **idempotent** — running twice is a no-op.
|
|
403
|
+
|
|
288
404
|
---
|
|
289
405
|
|
|
290
|
-
###
|
|
406
|
+
### `env` — Declare an env var
|
|
291
407
|
|
|
292
|
-
|
|
408
|
+
Adds a new variable across the four files the starter keeps in sync, atomically and idempotently:
|
|
409
|
+
|
|
410
|
+
1. `src/lib/env/schema.ts` — Zod entry with the right wrapper (`preprocess(emptyStringToUndefined, …)` for non-enum types)
|
|
411
|
+
2. `.env.example` — `KEY=` placeholder with optional description comment and `# -public` marker
|
|
412
|
+
3. `.env` — `KEY=<default>` line when the file exists
|
|
293
413
|
|
|
294
414
|
```bash
|
|
295
|
-
npx @teispace/next-maker
|
|
415
|
+
npx @teispace/next-maker env <NAME> [options]
|
|
296
416
|
```
|
|
297
417
|
|
|
298
|
-
|
|
418
|
+
| Flag | Effect |
|
|
419
|
+
| --- | --- |
|
|
420
|
+
| `--type <type>` | `string` (default), `url`, `number`, `boolean`, `enum` |
|
|
421
|
+
| `--required` | Skips `.optional()` and `.default()` |
|
|
422
|
+
| `--default <value>` | Adds `.default(value)` (mutually exclusive with `--required`) |
|
|
423
|
+
| `--public` | Auto-prefixes `NEXT_PUBLIC_` if missing and tags `.env.example` with `# -public` |
|
|
424
|
+
| `--describe <text>` | Adds `.describe()` and a comment line in `.env.example` |
|
|
425
|
+
| `--enum <list>` | Comma-separated values, required when `--type=enum` |
|
|
299
426
|
|
|
300
|
-
|
|
427
|
+
```bash
|
|
428
|
+
# Optional URL
|
|
429
|
+
npx @teispace/next-maker env SENTRY_DSN --type url --describe "Sentry endpoint"
|
|
301
430
|
|
|
302
|
-
|
|
431
|
+
# Public default
|
|
432
|
+
npx @teispace/next-maker env API_URL --type url --public --default "http://localhost:3000"
|
|
433
|
+
|
|
434
|
+
# Required string (no default, no .optional)
|
|
435
|
+
npx @teispace/next-maker env DATABASE_URL --type url --required
|
|
303
436
|
|
|
304
|
-
|
|
305
|
-
-
|
|
306
|
-
|
|
437
|
+
# Enum
|
|
438
|
+
npx @teispace/next-maker env LOG_LEVEL --type enum --enum debug,info,warn,error --default info
|
|
439
|
+
|
|
440
|
+
# Coerced number
|
|
441
|
+
npx @teispace/next-maker env PORT --type number --default 3000
|
|
442
|
+
```
|
|
307
443
|
|
|
308
|
-
|
|
444
|
+
The generator quote-escapes defaults and descriptions, mirrors the starter's house style, and is fully covered by tests against the `schema.ts`/`.env.example`/`.env` shapes.
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
### `locale` — Add a locale
|
|
309
449
|
|
|
310
450
|
```bash
|
|
311
|
-
|
|
312
|
-
|
|
451
|
+
npx @teispace/next-maker locale [code] [options]
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
| Flag | Effect |
|
|
455
|
+
| --- | --- |
|
|
456
|
+
| `--copy-translations` | Copy English translations as the starting point |
|
|
313
457
|
|
|
314
|
-
|
|
458
|
+
Creates `src/i18n/translations/<code>.json`, updates `SupportedLocale`, and adds the entry to `src/lib/config/app-locales.ts` (name, flag, country).
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
npx @teispace/next-maker locale es
|
|
315
462
|
npx @teispace/next-maker locale fr --copy-translations
|
|
316
463
|
```
|
|
317
464
|
|
|
318
465
|
---
|
|
319
466
|
|
|
320
|
-
###
|
|
321
|
-
|
|
322
|
-
Create a custom React hook with loading/error state boilerplate.
|
|
467
|
+
### `hook` — Custom React hook
|
|
323
468
|
|
|
324
469
|
```bash
|
|
325
470
|
npx @teispace/next-maker hook <name> [options]
|
|
326
471
|
```
|
|
327
472
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
**Examples:**
|
|
473
|
+
| Flag | Effect |
|
|
474
|
+
| --- | --- |
|
|
475
|
+
| `--client` | Add `'use client'` directive (default true) |
|
|
476
|
+
| `--feature <path>` | Generate inside a feature directory |
|
|
477
|
+
| `--test` / `--no-test` | Co-generate `*.test.ts` |
|
|
335
478
|
|
|
336
479
|
```bash
|
|
337
|
-
# Shared hook in src/hooks/
|
|
338
480
|
npx @teispace/next-maker hook auth-session
|
|
339
|
-
|
|
340
|
-
# Hook inside a feature
|
|
341
481
|
npx @teispace/next-maker hook user-profile --feature src/features/auth
|
|
342
482
|
```
|
|
343
483
|
|
|
344
484
|
---
|
|
345
485
|
|
|
346
|
-
###
|
|
486
|
+
### `test` — Retrofit a sibling test
|
|
347
487
|
|
|
348
|
-
|
|
488
|
+
Adds a `*.test.{ts,tsx}` next to existing code that pre-dates the `--test` flag.
|
|
349
489
|
|
|
350
490
|
```bash
|
|
351
491
|
npx @teispace/next-maker test <file> [options]
|
|
352
492
|
```
|
|
353
493
|
|
|
354
|
-
|
|
494
|
+
| Flag | Effect |
|
|
495
|
+
| --- | --- |
|
|
496
|
+
| `--kind <kind>` | Override inferred kind: `component` / `hook` / `slice` |
|
|
497
|
+
| `--force` | Overwrite an existing test file |
|
|
355
498
|
|
|
356
|
-
|
|
357
|
-
- `--force` - Overwrite an existing test file
|
|
499
|
+
Inference rules:
|
|
358
500
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
- `*.slice.ts` → slice reducer test
|
|
362
|
-
- `use*.ts` / content starts with `export function useX` → hook test (`renderHook`)
|
|
501
|
+
- `*.slice.ts` → reducer test
|
|
502
|
+
- `use*.ts` (or content starting with `export function useX`) → hook test (`renderHook`)
|
|
363
503
|
- `*.tsx` → component test (`renderWithProviders`)
|
|
364
504
|
|
|
365
|
-
The generated file imports `renderWithProviders` / `TestProviders` from `test/test-utils` using a path resolved relative to the source file, so tests work whether they're under `src/features/*/components/`, `src/hooks/`, or anywhere else in the tree.
|
|
366
|
-
|
|
367
|
-
**Examples:**
|
|
368
|
-
|
|
369
505
|
```bash
|
|
370
506
|
npx @teispace/next-maker test src/features/auth/components/LoginForm.tsx
|
|
371
|
-
npx @teispace/next-maker test src/features/auth/hooks/useLogin.ts
|
|
372
507
|
npx @teispace/next-maker test src/features/auth/store/auth.slice.ts
|
|
373
508
|
npx @teispace/next-maker test src/hooks/use-debounce.ts --kind hook --force
|
|
374
509
|
```
|
|
375
510
|
|
|
376
|
-
Requires
|
|
511
|
+
Requires `setup --tests` first.
|
|
377
512
|
|
|
378
513
|
---
|
|
379
514
|
|
|
380
|
-
##
|
|
515
|
+
## End-to-end examples
|
|
381
516
|
|
|
382
|
-
### Quick
|
|
517
|
+
### Quick start
|
|
383
518
|
|
|
384
519
|
```bash
|
|
385
|
-
# Create a new Next.js app with interactive setup
|
|
386
520
|
npx @teispace/next-maker init my-project
|
|
387
521
|
cd my-project
|
|
388
522
|
|
|
389
|
-
#
|
|
523
|
+
# Routes & layouts
|
|
390
524
|
npx @teispace/next-maker page dashboard --loading --error
|
|
391
|
-
npx @teispace/next-maker
|
|
525
|
+
npx @teispace/next-maker layout dashboard
|
|
526
|
+
npx @teispace/next-maker page products --dynamic id --loading --error
|
|
392
527
|
|
|
393
|
-
#
|
|
528
|
+
# State + data
|
|
394
529
|
npx @teispace/next-maker feature users --store persist --service fetch
|
|
395
530
|
npx @teispace/next-maker service users --fetch --crud --path features/users/services
|
|
396
531
|
|
|
397
|
-
#
|
|
532
|
+
# Providers & env
|
|
533
|
+
npx @teispace/next-maker provider auth
|
|
534
|
+
npx @teispace/next-maker env SENTRY_DSN --type url --describe "Sentry endpoint"
|
|
535
|
+
|
|
536
|
+
# i18n
|
|
398
537
|
npx @teispace/next-maker locale es
|
|
399
538
|
|
|
400
|
-
#
|
|
539
|
+
# Health check before commit
|
|
540
|
+
npx @teispace/next-maker doctor
|
|
541
|
+
|
|
401
542
|
npm run dev
|
|
402
543
|
```
|
|
403
544
|
|
|
404
|
-
### Feature-
|
|
545
|
+
### Feature-driven workflow
|
|
405
546
|
|
|
406
547
|
```bash
|
|
407
|
-
# E-commerce example
|
|
408
548
|
npx @teispace/next-maker feature products --store persist --service axios
|
|
409
549
|
npx @teispace/next-maker service products --axios --crud --path features/products/services
|
|
410
550
|
npx @teispace/next-maker page products --dynamic id --loading --error
|
|
411
551
|
npx @teispace/next-maker component product-card --client --feature src/features/products
|
|
552
|
+
npx @teispace/next-maker layout products
|
|
412
553
|
|
|
413
554
|
npx @teispace/next-maker feature cart --store persist --skip-service
|
|
414
555
|
npx @teispace/next-maker page checkout --loading --error
|
|
415
556
|
```
|
|
416
557
|
|
|
417
|
-
###
|
|
558
|
+
### Maintenance — re-applying drifted features
|
|
418
559
|
|
|
419
560
|
```bash
|
|
420
|
-
|
|
421
|
-
npx @teispace/next-maker
|
|
422
|
-
npx @teispace/next-maker component --help
|
|
423
|
-
npx @teispace/next-maker locale --help
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
---
|
|
427
|
-
|
|
428
|
-
## Key Features
|
|
429
|
-
|
|
430
|
-
### Pages with Full Locale Support
|
|
431
|
-
|
|
432
|
-
Auto-generates `generateMetadata`, `setRequestLocale`, typed Props, SEO metadata, and translation namespace. Supports dynamic routes with `--dynamic`.
|
|
433
|
-
|
|
434
|
-
### Shared Components with Auto-Wiring
|
|
435
|
-
|
|
436
|
-
Creates component in `src/components/common/<Name>/` and auto-updates all barrel exports so you can immediately `import { MyComponent } from '@/components'`.
|
|
561
|
+
# What's drifted?
|
|
562
|
+
npx @teispace/next-maker doctor
|
|
437
563
|
|
|
438
|
-
|
|
564
|
+
# Fix in place
|
|
565
|
+
npx @teispace/next-maker doctor --fix
|
|
439
566
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
One command adds a new language: translation file, type update, and config entry. No manual file editing.
|
|
445
|
-
|
|
446
|
-
### Feature-First Architecture
|
|
447
|
-
|
|
448
|
-
All generators follow a feature-based DDD approach, organizing code by business domain rather than technical layers.
|
|
567
|
+
# Pull a feature out cleanly
|
|
568
|
+
npx @teispace/next-maker remove i18n --dry-run
|
|
569
|
+
npx @teispace/next-maker remove i18n
|
|
570
|
+
```
|
|
449
571
|
|
|
450
|
-
|
|
572
|
+
---
|
|
451
573
|
|
|
452
|
-
|
|
574
|
+
## Architecture
|
|
453
575
|
|
|
454
|
-
###
|
|
576
|
+
### Layers
|
|
455
577
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
578
|
+
```
|
|
579
|
+
src/
|
|
580
|
+
├── commands/ # Commander definitions (one file per CLI command)
|
|
581
|
+
├── prompts/ # Enquirer flows (one per command needing interactivity)
|
|
582
|
+
├── generators/ # generate<X>(): writes files for a single artifact
|
|
583
|
+
│ └── templates/ # Pure string-template functions (testable in isolation)
|
|
584
|
+
├── modifiers/ # Pure functions that surgically edit existing files
|
|
585
|
+
├── pipelines/ # PipelineStep[] composers for multi-step generators
|
|
586
|
+
├── services/setup/ # Retrofit installers, one per feature
|
|
587
|
+
├── manifests/ # Declarative feature footprints (drives doctor + remove)
|
|
588
|
+
├── detection/ # "Is feature X installed?" detectors
|
|
589
|
+
├── core/ # File I/O + package-manager helpers (yarn/npm/pnpm/bun)
|
|
590
|
+
└── config/ # PROJECT_PATHS, PACKAGES, spinner, output, error handlers
|
|
591
|
+
```
|
|
459
592
|
|
|
460
|
-
###
|
|
593
|
+
### The manifest pattern
|
|
461
594
|
|
|
462
|
-
|
|
595
|
+
Each feature has a manifest in `src/manifests/<feature>.manifest.ts` describing:
|
|
463
596
|
|
|
464
|
-
|
|
597
|
+
- **detect** — high-level "is this installed?"
|
|
598
|
+
- **files** — paths the feature owns (with `generated: true/false` to control deletion safety)
|
|
599
|
+
- **packages** — runtime/dev dependencies
|
|
600
|
+
- **scripts** — `package.json` script entries (with optional exact-value match)
|
|
601
|
+
- **injections** — code blocks in shared files (with `presence` and optional `removePattern`)
|
|
602
|
+
- **apply** — the existing `setup<X>()` function (for `setup` and `doctor --fix`)
|
|
603
|
+
- **remove** — optional custom remover (defaults to the generic reverser)
|
|
465
604
|
|
|
466
|
-
|
|
467
|
-
- Prevents duplicate generation
|
|
468
|
-
- Validates naming conventions (kebab-case)
|
|
605
|
+
The manifest registry is consumed by:
|
|
469
606
|
|
|
470
|
-
|
|
607
|
+
- `setup` — calls `apply()` directly
|
|
608
|
+
- `doctor` — walks every manifest, reports drift via `checkManifest`
|
|
609
|
+
- `remove` — runs `reverseManifest` (or a custom `remove`) and prints the plan
|
|
471
610
|
|
|
472
|
-
|
|
473
|
-
- Component tests use `renderWithProviders` and forward `messages: {}` / `preloadedState: {}` based on detected i18n / Redux.
|
|
474
|
-
- Hook tests use `renderHook`; wrap with `TestProviders` when a Redux store is detected and the hook lives inside a feature.
|
|
475
|
-
- Slice tests exercise the reducer directly (`setLoading`, `setError`, `resetState`, initial-state invariants) — no providers needed.
|
|
476
|
-
- Standalone `test <file>` retrofits tests onto existing code, inferring kind from filename (`*.slice.ts`, `use*.ts`, `*.tsx`) and source content.
|
|
477
|
-
- Import paths to `test/test-utils` are resolved relative to the source file, so co-generated tests compile no matter how deep in the tree they live.
|
|
611
|
+
Adding a manifest for a new feature is a single file. The CLI commands don't need to know about it.
|
|
478
612
|
|
|
479
|
-
|
|
613
|
+
### Modifier conventions
|
|
480
614
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
| ------------------ | -------------------------------------------------------- |
|
|
485
|
-
| `init [name]` | Create a new Next.js application |
|
|
486
|
-
| `setup` | Add features to an existing project |
|
|
487
|
-
| `page <name>` | Generate a new page/route |
|
|
488
|
-
| `component <name>` | Generate a shared component (optional sibling test) |
|
|
489
|
-
| `feature <name>` | Generate a feature module |
|
|
490
|
-
| `slice <name>` | Generate a Redux slice (optional sibling test) |
|
|
491
|
-
| `service <name>` | Generate an API service |
|
|
492
|
-
| `locale [code]` | Add a new locale/language |
|
|
493
|
-
| `hook <name>` | Generate a custom React hook (optional sibling test) |
|
|
494
|
-
| `test <file>` | Generate a sibling test for a component/hook/slice |
|
|
615
|
+
- **Pure transformation modules** (e.g. `headers.ts`, `package-modifier.ts`, `env-var.modifier.ts`) take strings or JSON and return strings or JSON. No filesystem.
|
|
616
|
+
- **Thin async wrappers** (`index.ts` per setup service, the modifier orchestrators) handle I/O and spinners.
|
|
617
|
+
- **Idempotency** is required: re-running anything is a no-op when the target state is already reached. This is what makes `doctor --fix` safe.
|
|
495
618
|
|
|
496
619
|
---
|
|
497
620
|
|
|
498
|
-
## Project
|
|
621
|
+
## Project structure (generated app)
|
|
499
622
|
|
|
500
623
|
The full shape of a scaffolded app (branches marked `(opt)` are stripped when the matching prompt is declined during `init`):
|
|
501
624
|
|
|
@@ -526,11 +649,11 @@ my-project/
|
|
|
526
649
|
│ │ ├── common/ # Shared UI (auto-wired barrel exports)
|
|
527
650
|
│ │ └── index.ts
|
|
528
651
|
│ ├── providers/
|
|
529
|
-
│ │ ├── RootProvider.tsx # Composes Store → Theme → Intl
|
|
652
|
+
│ │ ├── RootProvider.tsx # Composes Store → Theme → Intl → custom
|
|
530
653
|
│ │ ├── StoreProvider.tsx # (opt, redux) useRef + PersistGate
|
|
531
654
|
│ │ ├── CustomThemeProvider.tsx # (opt, dark-mode) @teispace/next-themes
|
|
532
|
-
│ │ └── index.ts
|
|
533
|
-
│ ├── store/ # (opt, redux) makeStore, rootReducer, typed hooks
|
|
655
|
+
│ │ └── index.ts # Barrel — `next-maker provider <name>` keeps it sorted
|
|
656
|
+
│ ├── store/ # (opt, redux) makeStore, rootReducer, typed hooks
|
|
534
657
|
│ ├── services/
|
|
535
658
|
│ │ ├── api/ # API service barrel
|
|
536
659
|
│ │ └── storage/ # react-secure-storage wrapper
|
|
@@ -558,11 +681,12 @@ my-project/
|
|
|
558
681
|
│ └── check-deprecated.ts # fails build if @deprecated APIs are referenced
|
|
559
682
|
├── public/
|
|
560
683
|
├── biome.json # single-tool lint + format
|
|
561
|
-
├── next.config.ts # headers, reactCompiler (opt), bundleAnalyzer (opt), withNextIntl (opt, i18n)
|
|
684
|
+
├── next.config.ts # security headers, reactCompiler (opt), bundleAnalyzer (opt), withNextIntl (opt, i18n)
|
|
562
685
|
├── vitest.config.ts # (opt, tests)
|
|
563
686
|
├── postcss.config.mjs # @tailwindcss/postcss
|
|
564
687
|
├── tsconfig.json
|
|
565
688
|
├── .env.example
|
|
689
|
+
├── .czrc # (opt, commitizen)
|
|
566
690
|
├── .husky/ # (opt, pre-commit hooks)
|
|
567
691
|
├── .lintstagedrc.mjs # (opt, pre-commit hooks) runs `biome check --write`
|
|
568
692
|
├── commitlint.config.mjs # (opt, pre-commit hooks)
|
|
@@ -573,19 +697,15 @@ my-project/
|
|
|
573
697
|
└── package.json
|
|
574
698
|
```
|
|
575
699
|
|
|
576
|
-
Features that have first-class opt-out prompts during `init`: `httpClient`, `darkMode`, `redux`, `i18n`, `tests`, `reactCompiler`, `bundleAnalyzer`, `docker`, `ci`, `preCommitHooks`, `commitizen`, `communityFiles`, `readme`. Each has a matching `setup --<feature>`
|
|
700
|
+
Features that have first-class opt-out prompts during `init`: `httpClient`, `darkMode`, `redux`, `i18n`, `tests`, `reactCompiler`, `bundleAnalyzer`, `docker`, `ci`, `preCommitHooks`, `commitizen`, `communityFiles`, `readme`, `copyEnv`. Each opt-out has a matching `setup --<feature>` to re-add later. `doctor` and `remove` cover the whole installed footprint via manifests.
|
|
577
701
|
|
|
578
702
|
---
|
|
579
703
|
|
|
580
704
|
## Tech Stack
|
|
581
705
|
|
|
582
|
-
**CLI:**
|
|
583
|
-
|
|
584
|
-
- TypeScript, esbuild, Commander.js, Enquirer, Vitest
|
|
585
|
-
|
|
586
|
-
**Generated Apps:**
|
|
706
|
+
**CLI:** TypeScript, esbuild, Commander.js, Enquirer, Vitest, degit.
|
|
587
707
|
|
|
588
|
-
|
|
708
|
+
**Generated apps:** Next.js 16+, TypeScript, Tailwind CSS v4, Biome, Pino, Zod, Redux Toolkit, `@teispace/next-themes`, next-intl, Axios, Vitest + RTL, React Compiler.
|
|
589
709
|
|
|
590
710
|
---
|
|
591
711
|
|
|
@@ -596,37 +716,56 @@ Features that have first-class opt-out prompts during `init`: `httpClient`, `dar
|
|
|
596
716
|
```bash
|
|
597
717
|
git clone <repository-url>
|
|
598
718
|
cd npm-packages/packages/next-maker
|
|
599
|
-
|
|
719
|
+
yarn install
|
|
600
720
|
```
|
|
601
721
|
|
|
602
722
|
### Build
|
|
603
723
|
|
|
604
724
|
```bash
|
|
605
|
-
|
|
725
|
+
yarn build # esbuild bundle + tsc --emitDeclarationOnly
|
|
606
726
|
```
|
|
607
727
|
|
|
608
728
|
### Test
|
|
609
729
|
|
|
610
730
|
```bash
|
|
611
|
-
|
|
612
|
-
|
|
731
|
+
yarn test # one-shot
|
|
732
|
+
yarn test:watch
|
|
613
733
|
```
|
|
614
734
|
|
|
615
|
-
|
|
735
|
+
The test suite covers every modifier, generator template, and manifest runner with deterministic string/JSON inputs. Generators that touch the filesystem are tested against `os.tmpdir()` directories.
|
|
736
|
+
|
|
737
|
+
### Smoke-test the built CLI
|
|
616
738
|
|
|
617
739
|
```bash
|
|
618
740
|
node dist/index.js init test-project
|
|
619
741
|
cd test-project
|
|
742
|
+
|
|
743
|
+
# Generators
|
|
620
744
|
node ../dist/index.js page dashboard --loading --error
|
|
621
|
-
node ../dist/index.js
|
|
622
|
-
node ../dist/index.js
|
|
623
|
-
node ../dist/index.js
|
|
624
|
-
node ../dist/index.js
|
|
745
|
+
node ../dist/index.js layout dashboard
|
|
746
|
+
node ../dist/index.js component sidebar --client
|
|
747
|
+
node ../dist/index.js hook debounce
|
|
748
|
+
node ../dist/index.js provider auth
|
|
749
|
+
node ../dist/index.js slice filters --persist
|
|
750
|
+
node ../dist/index.js feature users --store persist --service axios
|
|
625
751
|
node ../dist/index.js service users --fetch --crud
|
|
626
|
-
node ../dist/index.js
|
|
752
|
+
node ../dist/index.js env SENTRY_DSN --type url --describe "Sentry"
|
|
627
753
|
node ../dist/index.js locale es
|
|
754
|
+
node ../dist/index.js test src/hooks/useDebounce.ts --force
|
|
755
|
+
|
|
756
|
+
# Maintenance
|
|
757
|
+
node ../dist/index.js doctor
|
|
758
|
+
node ../dist/index.js remove redux --dry-run
|
|
628
759
|
```
|
|
629
760
|
|
|
761
|
+
### Adding a new feature manifest
|
|
762
|
+
|
|
763
|
+
1. Drop a file under `src/manifests/<feature>.manifest.ts` exporting a `FeatureManifest`.
|
|
764
|
+
2. Append it to the `MANIFESTS` array in `src/manifests/index.ts`.
|
|
765
|
+
3. (Optional) Add a `setup --<feature>` flag if you want a flag-based retrofit.
|
|
766
|
+
|
|
767
|
+
`doctor` and `remove` will pick it up automatically.
|
|
768
|
+
|
|
630
769
|
---
|
|
631
770
|
|
|
632
771
|
## License
|
|
@@ -637,11 +776,11 @@ MIT
|
|
|
637
776
|
|
|
638
777
|
## Contributing
|
|
639
778
|
|
|
640
|
-
Contributions are welcome
|
|
779
|
+
Contributions are welcome. Please open a PR.
|
|
641
780
|
|
|
642
781
|
1. Fork the repository
|
|
643
782
|
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
644
|
-
3. Commit your changes (`git commit -m '
|
|
783
|
+
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
|
|
645
784
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
646
785
|
5. Open a Pull Request
|
|
647
786
|
|