@teispace/next-maker 1.15.0 → 1.16.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/CHANGELOG.md +19 -0
- package/README.md +418 -281
- package/dist/index.js +372 -136
- package/dist/index.js.map +4 -4
- 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 +105 -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,281 @@
|
|
|
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** (experimental — 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
|
+
```bash
|
|
181
|
+
# Preview the effect
|
|
182
|
+
npx @teispace/next-maker remove redux --dry-run
|
|
183
|
+
|
|
184
|
+
# Apply with confirmation
|
|
185
|
+
npx @teispace/next-maker remove security-headers
|
|
186
|
+
|
|
187
|
+
# Non-interactive
|
|
188
|
+
npx @teispace/next-maker remove validate-scripts --yes
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Sample plan:**
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
🗑 Remove Validation Scripts
|
|
195
|
+
|
|
196
|
+
Planned changes:
|
|
197
|
+
- delete file: scripts/sync-env.ts
|
|
198
|
+
- delete file: scripts/check-deprecated.ts
|
|
199
|
+
- remove script: env:sync
|
|
200
|
+
- remove script: check:deprecated
|
|
201
|
+
- remove script: validate
|
|
202
|
+
- uninstall: tsx
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
126
206
|
|
|
127
|
-
|
|
207
|
+
## Code generators
|
|
208
|
+
|
|
209
|
+
### `page` — Generate a page/route
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
npx @teispace/next-maker page <name> [options]
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
| Flag | Effect |
|
|
216
|
+
| --- | --- |
|
|
217
|
+
| `--dynamic <param>` | Dynamic segment (e.g. `--dynamic id` produces `[id]/page.tsx`) |
|
|
218
|
+
| `--loading` | Generate `loading.tsx` |
|
|
219
|
+
| `--error` | Generate `error.tsx` |
|
|
220
|
+
|
|
221
|
+
**What it does:**
|
|
222
|
+
|
|
223
|
+
- Writes `page.tsx` under `src/app/[locale]/<name>/` (i18n) or `src/app/<name>/`
|
|
224
|
+
- When i18n is detected: `generateMetadata`, `setRequestLocale`, `getTranslations`
|
|
225
|
+
- Registers route in `src/lib/config/app-paths.ts`
|
|
226
|
+
- Adds translation namespace to `en.json`
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
npx @teispace/next-maker page about
|
|
230
|
+
npx @teispace/next-maker page dashboard --loading --error
|
|
128
231
|
npx @teispace/next-maker page products --dynamic id --loading --error
|
|
129
232
|
```
|
|
130
233
|
|
|
131
234
|
---
|
|
132
235
|
|
|
133
|
-
###
|
|
236
|
+
### `layout` — Generate a nested layout
|
|
134
237
|
|
|
135
|
-
|
|
238
|
+
```bash
|
|
239
|
+
npx @teispace/next-maker layout <segment> [options]
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
| Flag | Effect |
|
|
243
|
+
| --- | --- |
|
|
244
|
+
| `--group` | Wraps the segment in parens for a route group, e.g. `(marketing)` |
|
|
245
|
+
| `--at <path>` | Places the layout under a nested path (kebab-case, slash-separated) |
|
|
246
|
+
| `--no-locale` | Skip the locale wrapper even when i18n is detected |
|
|
247
|
+
|
|
248
|
+
When i18n is detected the generated layout consumes `params: Promise<{ locale: string }>` and calls `setRequestLocale`. Otherwise it's a plain `({ children }) => <>{children}</>` shell.
|
|
136
249
|
|
|
137
250
|
```bash
|
|
138
|
-
|
|
251
|
+
# /[locale]/dashboard/layout.tsx
|
|
252
|
+
npx @teispace/next-maker layout dashboard
|
|
253
|
+
|
|
254
|
+
# Route group: /[locale]/(marketing)/layout.tsx
|
|
255
|
+
npx @teispace/next-maker layout marketing --group
|
|
256
|
+
|
|
257
|
+
# Nested: /[locale]/dashboard/settings/preferences/layout.tsx
|
|
258
|
+
npx @teispace/next-maker layout preferences --at dashboard/settings
|
|
139
259
|
```
|
|
140
260
|
|
|
141
|
-
|
|
261
|
+
Refuses to overwrite an existing `layout.tsx` — explicit error rather than silent loss.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### `component` — Shared component
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
npx @teispace/next-maker component <name> [options]
|
|
269
|
+
```
|
|
142
270
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
271
|
+
| Flag | Effect |
|
|
272
|
+
| --- | --- |
|
|
273
|
+
| `--client` | Adds `'use client'` directive |
|
|
274
|
+
| `--i18n` | Imports `useTranslations` |
|
|
275
|
+
| `--feature <path>` | Generate inside a feature directory |
|
|
276
|
+
| `--test` / `--no-test` | Co-generate a sibling `*.test.tsx` (default: on when Vitest is installed) |
|
|
147
277
|
|
|
148
|
-
**Generated structure
|
|
278
|
+
**Generated structure:**
|
|
149
279
|
|
|
150
280
|
```
|
|
151
281
|
src/components/common/MyButton/
|
|
@@ -155,347 +285,338 @@ src/components/common/MyButton/
|
|
|
155
285
|
|
|
156
286
|
Auto-updates `src/components/common/index.ts` and `src/components/index.ts`.
|
|
157
287
|
|
|
158
|
-
**Examples:**
|
|
159
|
-
|
|
160
288
|
```bash
|
|
161
|
-
# Shared component
|
|
162
289
|
npx @teispace/next-maker component data-table --client
|
|
163
|
-
|
|
164
|
-
# Component with i18n
|
|
165
290
|
npx @teispace/next-maker component nav-bar --client --i18n
|
|
166
|
-
|
|
167
|
-
# Feature-specific component
|
|
168
291
|
npx @teispace/next-maker component user-card --client --feature src/features/auth
|
|
169
292
|
```
|
|
170
293
|
|
|
171
294
|
---
|
|
172
295
|
|
|
173
|
-
###
|
|
174
|
-
|
|
175
|
-
Create a complete feature module following Domain-Driven Design principles.
|
|
296
|
+
### `feature` — Full feature module
|
|
176
297
|
|
|
177
298
|
```bash
|
|
178
299
|
npx @teispace/next-maker feature <name> [options]
|
|
179
300
|
```
|
|
180
301
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
302
|
+
| Flag | Effect |
|
|
303
|
+
| --- | --- |
|
|
304
|
+
| `--store <type>` | Generate Redux store: `persist` or `no-persist` |
|
|
305
|
+
| `--skip-store` | Skip Redux store |
|
|
306
|
+
| `--service <client>` | API service: `axios` or `fetch` |
|
|
307
|
+
| `--skip-service` | Skip API service |
|
|
308
|
+
| `--path <path>` | Custom path (default `src/features`) |
|
|
188
309
|
|
|
189
310
|
**Generated structure:**
|
|
190
311
|
|
|
191
312
|
```
|
|
192
313
|
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
|
|
314
|
+
├── components/UserDashboard.tsx
|
|
315
|
+
├── hooks/useUserDashboard.ts
|
|
316
|
+
├── types/user-dashboard.types.ts
|
|
317
|
+
├── store/ (optional)
|
|
318
|
+
├── services/ (optional)
|
|
206
319
|
└── index.ts
|
|
207
320
|
```
|
|
208
321
|
|
|
209
|
-
**Examples:**
|
|
210
|
-
|
|
211
322
|
```bash
|
|
212
|
-
# Full feature with Redux and API service
|
|
213
323
|
npx @teispace/next-maker feature user-profile --store persist --service axios
|
|
214
|
-
|
|
215
|
-
# Feature with Redux only
|
|
216
324
|
npx @teispace/next-maker feature shopping-cart --store no-persist --skip-service
|
|
217
|
-
|
|
218
|
-
# Feature in custom location
|
|
219
325
|
npx @teispace/next-maker feature auth --store persist --service fetch --path src/modules
|
|
220
326
|
```
|
|
221
327
|
|
|
222
328
|
---
|
|
223
329
|
|
|
224
|
-
###
|
|
225
|
-
|
|
226
|
-
Create a Redux Toolkit slice with persistence support.
|
|
330
|
+
### `slice` — Redux slice
|
|
227
331
|
|
|
228
332
|
```bash
|
|
229
333
|
npx @teispace/next-maker slice <name> [options]
|
|
230
334
|
```
|
|
231
335
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
- `--test` / `--no-test` - Co-generate a sibling `*.slice.test.ts` (default: on when tests are installed)
|
|
238
|
-
|
|
239
|
-
**Auto-registers in rootReducer** with correct imports.
|
|
336
|
+
| Flag | Effect |
|
|
337
|
+
| --- | --- |
|
|
338
|
+
| `--persist` / `--no-persist` | Toggle redux-persist for this slice |
|
|
339
|
+
| `--path <path>` | Custom path (default: new feature) |
|
|
340
|
+
| `--test` / `--no-test` | Co-generate `*.slice.test.ts` (default: on when Vitest is installed) |
|
|
240
341
|
|
|
241
|
-
|
|
342
|
+
Auto-registers in `rootReducer` with correct imports and persist config.
|
|
242
343
|
|
|
243
344
|
```bash
|
|
244
|
-
# Create new feature with slice
|
|
245
345
|
npx @teispace/next-maker slice auth --persist
|
|
246
|
-
|
|
247
|
-
# Add slice to existing feature
|
|
248
346
|
npx @teispace/next-maker slice user-settings --path features/auth/store
|
|
249
347
|
```
|
|
250
348
|
|
|
251
349
|
---
|
|
252
350
|
|
|
253
|
-
###
|
|
254
|
-
|
|
255
|
-
Create an API service with HTTP client integration. Supports both simple and full CRUD generation.
|
|
351
|
+
### `service` — API service
|
|
256
352
|
|
|
257
353
|
```bash
|
|
258
354
|
npx @teispace/next-maker service <name> [options]
|
|
259
355
|
```
|
|
260
356
|
|
|
261
|
-
|
|
357
|
+
| Flag | Effect |
|
|
358
|
+
| --- | --- |
|
|
359
|
+
| `--axios` / `--fetch` | Pick the HTTP client |
|
|
360
|
+
| `--crud` | Generate full CRUD (`getAll`, `getById`, `create`, `update`, `delete`) |
|
|
361
|
+
| `--path <path>` | Custom path |
|
|
262
362
|
|
|
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)
|
|
363
|
+
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
364
|
|
|
268
|
-
|
|
365
|
+
```bash
|
|
366
|
+
npx @teispace/next-maker service payment --axios
|
|
367
|
+
npx @teispace/next-maker service users --fetch --crud
|
|
368
|
+
npx @teispace/next-maker service orders --axios --crud --path features/products/services
|
|
369
|
+
```
|
|
269
370
|
|
|
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)`)
|
|
371
|
+
---
|
|
274
372
|
|
|
275
|
-
|
|
373
|
+
### `provider` — Context provider
|
|
276
374
|
|
|
277
375
|
```bash
|
|
278
|
-
|
|
279
|
-
|
|
376
|
+
npx @teispace/next-maker provider <name>
|
|
377
|
+
```
|
|
280
378
|
|
|
281
|
-
|
|
282
|
-
npx @teispace/next-maker service users --fetch --crud
|
|
379
|
+
Generates `src/providers/<Name>Provider.tsx` with:
|
|
283
380
|
|
|
284
|
-
|
|
285
|
-
|
|
381
|
+
- `'use client'` directive
|
|
382
|
+
- `createContext` + typed context value
|
|
383
|
+
- `useX()` hook with non-null guard
|
|
384
|
+
- `<XProvider>` component memoising the value with `useMemo`
|
|
385
|
+
|
|
386
|
+
Then **two-tier auto-wiring**:
|
|
387
|
+
|
|
388
|
+
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`).
|
|
389
|
+
2. Wraps `{children}` with `<XProvider>` inside that chain, preserving indentation.
|
|
390
|
+
3. Updates `src/providers/index.ts` barrel (re-exports kept sorted).
|
|
391
|
+
|
|
392
|
+
If no candidate is found, the generator prints the snippet to wire manually rather than failing silently.
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
npx @teispace/next-maker provider auth # → AuthProvider, useAuth
|
|
396
|
+
npx @teispace/next-maker provider session # → SessionProvider, useSession
|
|
397
|
+
npx @teispace/next-maker provider analytics-provider # already-suffixed names work
|
|
286
398
|
```
|
|
287
399
|
|
|
400
|
+
The wrap is **idempotent** — running twice is a no-op.
|
|
401
|
+
|
|
288
402
|
---
|
|
289
403
|
|
|
290
|
-
###
|
|
404
|
+
### `env` — Declare an env var
|
|
405
|
+
|
|
406
|
+
Adds a new variable across the four files the starter keeps in sync, atomically and idempotently:
|
|
291
407
|
|
|
292
|
-
|
|
408
|
+
1. `src/lib/env/schema.ts` — Zod entry with the right wrapper (`preprocess(emptyStringToUndefined, …)` for non-enum types)
|
|
409
|
+
2. `.env.example` — `KEY=` placeholder with optional description comment and `# -public` marker
|
|
410
|
+
3. `.env` — `KEY=<default>` line when the file exists
|
|
293
411
|
|
|
294
412
|
```bash
|
|
295
|
-
npx @teispace/next-maker
|
|
413
|
+
npx @teispace/next-maker env <NAME> [options]
|
|
296
414
|
```
|
|
297
415
|
|
|
298
|
-
|
|
416
|
+
| Flag | Effect |
|
|
417
|
+
| --- | --- |
|
|
418
|
+
| `--type <type>` | `string` (default), `url`, `number`, `boolean`, `enum` |
|
|
419
|
+
| `--required` | Skips `.optional()` and `.default()` |
|
|
420
|
+
| `--default <value>` | Adds `.default(value)` (mutually exclusive with `--required`) |
|
|
421
|
+
| `--public` | Auto-prefixes `NEXT_PUBLIC_` if missing and tags `.env.example` with `# -public` |
|
|
422
|
+
| `--describe <text>` | Adds `.describe()` and a comment line in `.env.example` |
|
|
423
|
+
| `--enum <list>` | Comma-separated values, required when `--type=enum` |
|
|
299
424
|
|
|
300
|
-
|
|
425
|
+
```bash
|
|
426
|
+
# Optional URL
|
|
427
|
+
npx @teispace/next-maker env SENTRY_DSN --type url --describe "Sentry endpoint"
|
|
301
428
|
|
|
302
|
-
|
|
429
|
+
# Public default
|
|
430
|
+
npx @teispace/next-maker env API_URL --type url --public --default "http://localhost:3000"
|
|
431
|
+
|
|
432
|
+
# Required string (no default, no .optional)
|
|
433
|
+
npx @teispace/next-maker env DATABASE_URL --type url --required
|
|
434
|
+
|
|
435
|
+
# Enum
|
|
436
|
+
npx @teispace/next-maker env LOG_LEVEL --type enum --enum debug,info,warn,error --default info
|
|
437
|
+
|
|
438
|
+
# Coerced number
|
|
439
|
+
npx @teispace/next-maker env PORT --type number --default 3000
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
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.
|
|
303
443
|
|
|
304
|
-
|
|
305
|
-
- Updates `SupportedLocale` type in `src/types/i18n.ts`
|
|
306
|
-
- Adds entry to `src/lib/config/app-locales.ts` with name, flag, country
|
|
444
|
+
---
|
|
307
445
|
|
|
308
|
-
|
|
446
|
+
### `locale` — Add a locale
|
|
309
447
|
|
|
310
448
|
```bash
|
|
311
|
-
|
|
312
|
-
|
|
449
|
+
npx @teispace/next-maker locale [code] [options]
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
| Flag | Effect |
|
|
453
|
+
| --- | --- |
|
|
454
|
+
| `--copy-translations` | Copy English translations as the starting point |
|
|
313
455
|
|
|
314
|
-
|
|
456
|
+
Creates `src/i18n/translations/<code>.json`, updates `SupportedLocale`, and adds the entry to `src/lib/config/app-locales.ts` (name, flag, country).
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
npx @teispace/next-maker locale es
|
|
315
460
|
npx @teispace/next-maker locale fr --copy-translations
|
|
316
461
|
```
|
|
317
462
|
|
|
318
463
|
---
|
|
319
464
|
|
|
320
|
-
###
|
|
321
|
-
|
|
322
|
-
Create a custom React hook with loading/error state boilerplate.
|
|
465
|
+
### `hook` — Custom React hook
|
|
323
466
|
|
|
324
467
|
```bash
|
|
325
468
|
npx @teispace/next-maker hook <name> [options]
|
|
326
469
|
```
|
|
327
470
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
**Examples:**
|
|
471
|
+
| Flag | Effect |
|
|
472
|
+
| --- | --- |
|
|
473
|
+
| `--client` | Add `'use client'` directive (default true) |
|
|
474
|
+
| `--feature <path>` | Generate inside a feature directory |
|
|
475
|
+
| `--test` / `--no-test` | Co-generate `*.test.ts` |
|
|
335
476
|
|
|
336
477
|
```bash
|
|
337
|
-
# Shared hook in src/hooks/
|
|
338
478
|
npx @teispace/next-maker hook auth-session
|
|
339
|
-
|
|
340
|
-
# Hook inside a feature
|
|
341
479
|
npx @teispace/next-maker hook user-profile --feature src/features/auth
|
|
342
480
|
```
|
|
343
481
|
|
|
344
482
|
---
|
|
345
483
|
|
|
346
|
-
###
|
|
484
|
+
### `test` — Retrofit a sibling test
|
|
347
485
|
|
|
348
|
-
|
|
486
|
+
Adds a `*.test.{ts,tsx}` next to existing code that pre-dates the `--test` flag.
|
|
349
487
|
|
|
350
488
|
```bash
|
|
351
489
|
npx @teispace/next-maker test <file> [options]
|
|
352
490
|
```
|
|
353
491
|
|
|
354
|
-
|
|
492
|
+
| Flag | Effect |
|
|
493
|
+
| --- | --- |
|
|
494
|
+
| `--kind <kind>` | Override inferred kind: `component` / `hook` / `slice` |
|
|
495
|
+
| `--force` | Overwrite an existing test file |
|
|
355
496
|
|
|
356
|
-
|
|
357
|
-
- `--force` - Overwrite an existing test file
|
|
497
|
+
Inference rules:
|
|
358
498
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
- `*.slice.ts` → slice reducer test
|
|
362
|
-
- `use*.ts` / content starts with `export function useX` → hook test (`renderHook`)
|
|
499
|
+
- `*.slice.ts` → reducer test
|
|
500
|
+
- `use*.ts` (or content starting with `export function useX`) → hook test (`renderHook`)
|
|
363
501
|
- `*.tsx` → component test (`renderWithProviders`)
|
|
364
502
|
|
|
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
503
|
```bash
|
|
370
504
|
npx @teispace/next-maker test src/features/auth/components/LoginForm.tsx
|
|
371
|
-
npx @teispace/next-maker test src/features/auth/hooks/useLogin.ts
|
|
372
505
|
npx @teispace/next-maker test src/features/auth/store/auth.slice.ts
|
|
373
506
|
npx @teispace/next-maker test src/hooks/use-debounce.ts --kind hook --force
|
|
374
507
|
```
|
|
375
508
|
|
|
376
|
-
Requires
|
|
509
|
+
Requires `setup --tests` first.
|
|
377
510
|
|
|
378
511
|
---
|
|
379
512
|
|
|
380
|
-
##
|
|
513
|
+
## End-to-end examples
|
|
381
514
|
|
|
382
|
-
### Quick
|
|
515
|
+
### Quick start
|
|
383
516
|
|
|
384
517
|
```bash
|
|
385
|
-
# Create a new Next.js app with interactive setup
|
|
386
518
|
npx @teispace/next-maker init my-project
|
|
387
519
|
cd my-project
|
|
388
520
|
|
|
389
|
-
#
|
|
521
|
+
# Routes & layouts
|
|
390
522
|
npx @teispace/next-maker page dashboard --loading --error
|
|
391
|
-
npx @teispace/next-maker
|
|
523
|
+
npx @teispace/next-maker layout dashboard
|
|
524
|
+
npx @teispace/next-maker page products --dynamic id --loading --error
|
|
392
525
|
|
|
393
|
-
#
|
|
526
|
+
# State + data
|
|
394
527
|
npx @teispace/next-maker feature users --store persist --service fetch
|
|
395
528
|
npx @teispace/next-maker service users --fetch --crud --path features/users/services
|
|
396
529
|
|
|
397
|
-
#
|
|
530
|
+
# Providers & env
|
|
531
|
+
npx @teispace/next-maker provider auth
|
|
532
|
+
npx @teispace/next-maker env SENTRY_DSN --type url --describe "Sentry endpoint"
|
|
533
|
+
|
|
534
|
+
# i18n
|
|
398
535
|
npx @teispace/next-maker locale es
|
|
399
536
|
|
|
400
|
-
#
|
|
537
|
+
# Health check before commit
|
|
538
|
+
npx @teispace/next-maker doctor
|
|
539
|
+
|
|
401
540
|
npm run dev
|
|
402
541
|
```
|
|
403
542
|
|
|
404
|
-
### Feature-
|
|
543
|
+
### Feature-driven workflow
|
|
405
544
|
|
|
406
545
|
```bash
|
|
407
|
-
# E-commerce example
|
|
408
546
|
npx @teispace/next-maker feature products --store persist --service axios
|
|
409
547
|
npx @teispace/next-maker service products --axios --crud --path features/products/services
|
|
410
548
|
npx @teispace/next-maker page products --dynamic id --loading --error
|
|
411
549
|
npx @teispace/next-maker component product-card --client --feature src/features/products
|
|
550
|
+
npx @teispace/next-maker layout products
|
|
412
551
|
|
|
413
552
|
npx @teispace/next-maker feature cart --store persist --skip-service
|
|
414
553
|
npx @teispace/next-maker page checkout --loading --error
|
|
415
554
|
```
|
|
416
555
|
|
|
417
|
-
###
|
|
556
|
+
### Maintenance — re-applying drifted features
|
|
418
557
|
|
|
419
558
|
```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'`.
|
|
559
|
+
# What's drifted?
|
|
560
|
+
npx @teispace/next-maker doctor
|
|
437
561
|
|
|
438
|
-
|
|
562
|
+
# Fix in place
|
|
563
|
+
npx @teispace/next-maker doctor --fix
|
|
439
564
|
|
|
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.
|
|
565
|
+
# Pull a feature out cleanly
|
|
566
|
+
npx @teispace/next-maker remove i18n --dry-run
|
|
567
|
+
npx @teispace/next-maker remove i18n
|
|
568
|
+
```
|
|
449
569
|
|
|
450
|
-
|
|
570
|
+
---
|
|
451
571
|
|
|
452
|
-
|
|
572
|
+
## Architecture
|
|
453
573
|
|
|
454
|
-
###
|
|
574
|
+
### Layers
|
|
455
575
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
576
|
+
```
|
|
577
|
+
src/
|
|
578
|
+
├── commands/ # Commander definitions (one file per CLI command)
|
|
579
|
+
├── prompts/ # Enquirer flows (one per command needing interactivity)
|
|
580
|
+
├── generators/ # generate<X>(): writes files for a single artifact
|
|
581
|
+
│ └── templates/ # Pure string-template functions (testable in isolation)
|
|
582
|
+
├── modifiers/ # Pure functions that surgically edit existing files
|
|
583
|
+
├── pipelines/ # PipelineStep[] composers for multi-step generators
|
|
584
|
+
├── services/setup/ # Retrofit installers, one per feature
|
|
585
|
+
├── manifests/ # Declarative feature footprints (drives doctor + remove)
|
|
586
|
+
├── detection/ # "Is feature X installed?" detectors
|
|
587
|
+
├── core/ # File I/O + package-manager helpers (yarn/npm/pnpm/bun)
|
|
588
|
+
└── config/ # PROJECT_PATHS, PACKAGES, spinner, output, error handlers
|
|
589
|
+
```
|
|
459
590
|
|
|
460
|
-
###
|
|
591
|
+
### The manifest pattern
|
|
461
592
|
|
|
462
|
-
|
|
593
|
+
Each feature has a manifest in `src/manifests/<feature>.manifest.ts` describing:
|
|
463
594
|
|
|
464
|
-
|
|
595
|
+
- **detect** — high-level "is this installed?"
|
|
596
|
+
- **files** — paths the feature owns (with `generated: true/false` to control deletion safety)
|
|
597
|
+
- **packages** — runtime/dev dependencies
|
|
598
|
+
- **scripts** — `package.json` script entries (with optional exact-value match)
|
|
599
|
+
- **injections** — code blocks in shared files (with `presence` and optional `removePattern`)
|
|
600
|
+
- **apply** — the existing `setup<X>()` function (for `setup` and `doctor --fix`)
|
|
601
|
+
- **remove** — optional custom remover (defaults to the generic reverser)
|
|
465
602
|
|
|
466
|
-
|
|
467
|
-
- Prevents duplicate generation
|
|
468
|
-
- Validates naming conventions (kebab-case)
|
|
603
|
+
The manifest registry is consumed by:
|
|
469
604
|
|
|
470
|
-
|
|
605
|
+
- `setup` — calls `apply()` directly
|
|
606
|
+
- `doctor` — walks every manifest, reports drift via `checkManifest`
|
|
607
|
+
- `remove` — runs `reverseManifest` (or a custom `remove`) and prints the plan
|
|
471
608
|
|
|
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.
|
|
609
|
+
Adding a manifest for a new feature is a single file. The CLI commands don't need to know about it.
|
|
478
610
|
|
|
479
|
-
|
|
611
|
+
### Modifier conventions
|
|
480
612
|
|
|
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 |
|
|
613
|
+
- **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.
|
|
614
|
+
- **Thin async wrappers** (`index.ts` per setup service, the modifier orchestrators) handle I/O and spinners.
|
|
615
|
+
- **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
616
|
|
|
496
617
|
---
|
|
497
618
|
|
|
498
|
-
## Project
|
|
619
|
+
## Project structure (generated app)
|
|
499
620
|
|
|
500
621
|
The full shape of a scaffolded app (branches marked `(opt)` are stripped when the matching prompt is declined during `init`):
|
|
501
622
|
|
|
@@ -526,11 +647,11 @@ my-project/
|
|
|
526
647
|
│ │ ├── common/ # Shared UI (auto-wired barrel exports)
|
|
527
648
|
│ │ └── index.ts
|
|
528
649
|
│ ├── providers/
|
|
529
|
-
│ │ ├── RootProvider.tsx # Composes Store → Theme → Intl
|
|
650
|
+
│ │ ├── RootProvider.tsx # Composes Store → Theme → Intl → custom
|
|
530
651
|
│ │ ├── StoreProvider.tsx # (opt, redux) useRef + PersistGate
|
|
531
652
|
│ │ ├── CustomThemeProvider.tsx # (opt, dark-mode) @teispace/next-themes
|
|
532
|
-
│ │ └── index.ts
|
|
533
|
-
│ ├── store/ # (opt, redux) makeStore, rootReducer, typed hooks
|
|
653
|
+
│ │ └── index.ts # Barrel — `next-maker provider <name>` keeps it sorted
|
|
654
|
+
│ ├── store/ # (opt, redux) makeStore, rootReducer, typed hooks
|
|
534
655
|
│ ├── services/
|
|
535
656
|
│ │ ├── api/ # API service barrel
|
|
536
657
|
│ │ └── storage/ # react-secure-storage wrapper
|
|
@@ -558,11 +679,12 @@ my-project/
|
|
|
558
679
|
│ └── check-deprecated.ts # fails build if @deprecated APIs are referenced
|
|
559
680
|
├── public/
|
|
560
681
|
├── biome.json # single-tool lint + format
|
|
561
|
-
├── next.config.ts # headers, reactCompiler (opt), bundleAnalyzer (opt), withNextIntl (opt, i18n)
|
|
682
|
+
├── next.config.ts # security headers, reactCompiler (opt), bundleAnalyzer (opt), withNextIntl (opt, i18n)
|
|
562
683
|
├── vitest.config.ts # (opt, tests)
|
|
563
684
|
├── postcss.config.mjs # @tailwindcss/postcss
|
|
564
685
|
├── tsconfig.json
|
|
565
686
|
├── .env.example
|
|
687
|
+
├── .czrc # (opt, commitizen)
|
|
566
688
|
├── .husky/ # (opt, pre-commit hooks)
|
|
567
689
|
├── .lintstagedrc.mjs # (opt, pre-commit hooks) runs `biome check --write`
|
|
568
690
|
├── commitlint.config.mjs # (opt, pre-commit hooks)
|
|
@@ -573,19 +695,15 @@ my-project/
|
|
|
573
695
|
└── package.json
|
|
574
696
|
```
|
|
575
697
|
|
|
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>`
|
|
698
|
+
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
699
|
|
|
578
700
|
---
|
|
579
701
|
|
|
580
702
|
## Tech Stack
|
|
581
703
|
|
|
582
|
-
**CLI:**
|
|
583
|
-
|
|
584
|
-
- TypeScript, esbuild, Commander.js, Enquirer, Vitest
|
|
585
|
-
|
|
586
|
-
**Generated Apps:**
|
|
704
|
+
**CLI:** TypeScript, esbuild, Commander.js, Enquirer, Vitest, degit.
|
|
587
705
|
|
|
588
|
-
|
|
706
|
+
**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
707
|
|
|
590
708
|
---
|
|
591
709
|
|
|
@@ -596,37 +714,56 @@ Features that have first-class opt-out prompts during `init`: `httpClient`, `dar
|
|
|
596
714
|
```bash
|
|
597
715
|
git clone <repository-url>
|
|
598
716
|
cd npm-packages/packages/next-maker
|
|
599
|
-
|
|
717
|
+
yarn install
|
|
600
718
|
```
|
|
601
719
|
|
|
602
720
|
### Build
|
|
603
721
|
|
|
604
722
|
```bash
|
|
605
|
-
|
|
723
|
+
yarn build # esbuild bundle + tsc --emitDeclarationOnly
|
|
606
724
|
```
|
|
607
725
|
|
|
608
726
|
### Test
|
|
609
727
|
|
|
610
728
|
```bash
|
|
611
|
-
|
|
612
|
-
|
|
729
|
+
yarn test # one-shot
|
|
730
|
+
yarn test:watch
|
|
613
731
|
```
|
|
614
732
|
|
|
615
|
-
|
|
733
|
+
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.
|
|
734
|
+
|
|
735
|
+
### Smoke-test the built CLI
|
|
616
736
|
|
|
617
737
|
```bash
|
|
618
738
|
node dist/index.js init test-project
|
|
619
739
|
cd test-project
|
|
740
|
+
|
|
741
|
+
# Generators
|
|
620
742
|
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
|
|
743
|
+
node ../dist/index.js layout dashboard
|
|
744
|
+
node ../dist/index.js component sidebar --client
|
|
745
|
+
node ../dist/index.js hook debounce
|
|
746
|
+
node ../dist/index.js provider auth
|
|
747
|
+
node ../dist/index.js slice filters --persist
|
|
748
|
+
node ../dist/index.js feature users --store persist --service axios
|
|
625
749
|
node ../dist/index.js service users --fetch --crud
|
|
626
|
-
node ../dist/index.js
|
|
750
|
+
node ../dist/index.js env SENTRY_DSN --type url --describe "Sentry"
|
|
627
751
|
node ../dist/index.js locale es
|
|
752
|
+
node ../dist/index.js test src/hooks/useDebounce.ts --force
|
|
753
|
+
|
|
754
|
+
# Maintenance
|
|
755
|
+
node ../dist/index.js doctor
|
|
756
|
+
node ../dist/index.js remove redux --dry-run
|
|
628
757
|
```
|
|
629
758
|
|
|
759
|
+
### Adding a new feature manifest
|
|
760
|
+
|
|
761
|
+
1. Drop a file under `src/manifests/<feature>.manifest.ts` exporting a `FeatureManifest`.
|
|
762
|
+
2. Append it to the `MANIFESTS` array in `src/manifests/index.ts`.
|
|
763
|
+
3. (Optional) Add a `setup --<feature>` flag if you want a flag-based retrofit.
|
|
764
|
+
|
|
765
|
+
`doctor` and `remove` will pick it up automatically.
|
|
766
|
+
|
|
630
767
|
---
|
|
631
768
|
|
|
632
769
|
## License
|
|
@@ -637,11 +774,11 @@ MIT
|
|
|
637
774
|
|
|
638
775
|
## Contributing
|
|
639
776
|
|
|
640
|
-
Contributions are welcome
|
|
777
|
+
Contributions are welcome. Please open a PR.
|
|
641
778
|
|
|
642
779
|
1. Fork the repository
|
|
643
780
|
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
644
|
-
3. Commit your changes (`git commit -m '
|
|
781
|
+
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
|
|
645
782
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
646
783
|
5. Open a Pull Request
|
|
647
784
|
|