@alevnyacow/nzmt 0.16.16 β†’ 0.16.18

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.
Files changed (2) hide show
  1. package/README.md +59 -84
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -4,34 +4,32 @@
4
4
  ![NPM License](https://img.shields.io/npm/l/%40alevnyacow%2Fnzmt)
5
5
  ![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/%40alevnyacow/nzmt)
6
6
 
7
- # TL;DR πŸ•°
7
+ Scaffold full-stack modules in Next.js in seconds with Next **Zod Modules Toolkit (NZMT)**.
8
8
 
9
- Scaffold production-ready server modules in Next.js with a single CLI command, which also generates ready-to-use React Queries. Modules work seamlessly with Server Actions out of the box.
9
+ Get **a DDD-inspired architecture with a contract-first approach** β€” and Server Actions working out of the box.
10
10
 
11
- # What and Why
11
+ **API, services, stores, entities, validation, and React Query hooks β€” all generated for you.** No framework. No lock-in. Just production-ready Next.js.
12
12
 
13
- Next Zod Modules Toolkit.
13
+ # πŸ‘€ How it works
14
14
 
15
- Next.js tools you actually missed + a scaffolder for server logic & client queries. **Not a framework.** Full-stack, batteries included. ⚑
15
+ - initialize NZMT once
16
+ - run the scaffolder (e.g. `npx nzmt crud-api user`)
17
+ - tweak a few files
18
+ - get ready-to-use React Query hooks and a backend usable via Server Actions
16
19
 
17
- - β˜• Keep using plain Next.js β€” just faster and cleaner.
18
- - πŸ§™ Focus on your domain logic without drowning in full-blown DDD.
19
- - ✨ DI, handy API controllers and a bunch of other cool things aimed at improving your DX out of the box.
20
- - πŸͺ„ Services, controllers, client queries, and other programmer stuff appear at the snap of a finger.
21
-
22
- # Quick start with Prisma
20
+ # 🎬 Quick start with Prisma
23
21
 
24
22
  Assuming you have a Next.js project with a generated Prisma client, and configured `@tanstack/react-query`:
25
23
 
26
- ## Setup phase
24
+ ## βš™οΈ Setup
27
25
 
28
- 1. Install NZMT with peer dependencies:
26
+ ### 1. Install
29
27
 
30
28
  ```bash
31
29
  npm i inversify zod reflect-metadata @alevnyacow/nzmt
32
30
  ```
33
31
 
34
- 2. Enable decorators in tsconfig.json
32
+ ### 2. Enable decorators in tsconfig.json
35
33
 
36
34
  ```ts
37
35
  {
@@ -42,26 +40,25 @@ npm i inversify zod reflect-metadata @alevnyacow/nzmt
42
40
  }
43
41
  ```
44
42
 
45
- 3. Initialize NZMT with the absolute Prisma client path as a parameter
43
+ ### 3. Initialize
46
44
 
47
45
  ```bash
48
46
  npx nzmt init prismaClientPath:@/generated/prisma/client
49
47
  ```
50
48
 
51
- This command generates:
49
+ This command takes absolute path to your Prisma client as input and generates:
52
50
 
53
51
  - `nzmt.config.json` file
54
- - DI infrastructure boilerplate
55
- - Prisma Client instance injected in DI
56
- - Some infrastructure helpers also already injected in DI
52
+ - DI setup
53
+ - infrastructure helpers
57
54
 
58
- 4. Import and set up the necessary Prisma adapter in scaffolded `/server/infrastructure/prisma/client.ts` file.
55
+ ### 4. Plug Prisma adapter
59
56
 
60
- ## Example 1. CRUD for `User` entity with React queries and Server Actions
57
+ Edit scaffolded `/server/infrastructure/prisma/client.ts` file
61
58
 
62
- Assuming you have `User` prisma schema.
59
+ ## πŸ” Making full-stack CRUD for `User` entity with React queries and Server Actions
63
60
 
64
- 1. Run NZMT scaffolder:
61
+ Assuming you have `User` prisma schema.
65
62
 
66
63
  ```bash
67
64
  npx nzmt crud-api user
@@ -78,41 +75,37 @@ This command generates:
78
75
 
79
76
  Everything is wired automatically via DI β€” no manual setup needed.
80
77
 
81
- 2. Describe your entity in scaffolded `/shared/entities/user/user.entity.ts` file (static `schema` field).
82
-
83
- 3. Tweak `UserStore` schemas if needed in scaffolded `/server/stores/users/user.store.ts` file.
78
+ Then tweak a few files:
84
79
 
85
- 4. Describe how your `UserStore` contracts map to your `Prisma` client contracts in scaffolded `server/stores/users/user.store.prisma.ts` file (`mappers` object is already there for you with all types and functions, just implement them).
80
+ - `/shared/entities/user/user.entity.ts` β†’ entity schema
81
+ - `/server/stores/users/user.store.ts` β†’ store schemas (if default schemas do not fit your needs)
82
+ - `/server/stores/users/user.store.prisma.ts` β†’ map `UserStore` contracts to Prisma client contracts
86
83
 
87
- So, after one CLI command and few tweaks you can use your React query hooks or Server actions. πŸͺ„
84
+ πŸ‘‰ One command + few tweaks β†’ ready-to-use React Query hooks & Server Actions backend.
88
85
 
89
- ### How to use React query hooks
86
+ ## βš›οΈ Using scaffolded React query hooks
90
87
 
91
88
  ```
92
89
  Schema: Client β†’ React Query β†’ API β†’ Controller β†’ Service β†’ Store β†’ DB
93
90
  ```
94
91
 
95
- Everything is already scaffolded and grouped in handy namespace for you, just import it and use! ✨
96
-
97
- Even invalidations are working out of the box (though you can modify scaffolded queries any way you want).
98
-
99
92
  ```tsx
100
93
  'use client'
101
94
 
102
95
  import { UserQueries } from "@/client/shared/queries/user";
103
96
 
104
- export default function Home() {
97
+ export default function () {
105
98
  const { mutate: addUser } = UserQueries.usePOST()
106
99
  const { data, isFetching } = UserQueries.useGET({ query: {} })
107
100
 
108
- const addColinZeal = () => {
109
- addUser({ body: { payload: { name: 'Colin Zeal' } } })
101
+ const addRandomUser = () => {
102
+ addUser({ body: { payload: { name: `${Math.random()}` } } })
110
103
  }
111
104
 
112
105
  return (
113
106
  <div>
114
- <button onClick={addColinZeal}>
115
- Add Mr. Zeal
107
+ <button onClick={addRandomUser}>
108
+ New random user
116
109
  </button>
117
110
 
118
111
  {isFetching ? 'Loading users...' : JSON.stringify(data)}
@@ -122,14 +115,12 @@ export default function Home() {
122
115
 
123
116
  ```
124
117
 
125
- ### How to use server modules as server actions
118
+ ## πŸ”Ό Using scaffolded Service methods as Next server actions
126
119
 
127
120
  ```
128
121
  Schema: Server Action β†’ Service β†’ Store β†’ DB
129
122
  ```
130
123
 
131
- Just get required instances from DI and use methods. That's all. ✨
132
-
133
124
  ```tsx
134
125
  'use server'
135
126
 
@@ -144,71 +135,55 @@ export default async function() {
144
135
  */
145
136
  const userService = fromDI<UserService>('UserService')
146
137
 
147
- const driver8 = await userService.getDetails({
148
- filter: { id: 'driver-8' }
138
+ const user1 = await userService.getDetails({
139
+ filter: { id: 'user-1-id' }
149
140
  })
150
141
 
151
- return <div>
152
- Take a break, {JSON.stringify(driver8)}
153
- {JSON.stringify(driver8)}, take a break
154
- </div>
142
+ return <div>{JSON.stringify(user1)}</div>
155
143
  }
156
144
  ```
157
145
 
158
- # Common questions
146
+ # ❓ FAQ
159
147
 
160
- ## Can I tweak scaffolded files?
148
+ ## What does DDD-inspired mean?
149
+
150
+ NZMT puts your business domain first. Entities drive the architecture, so backend and frontend stay consistent, and all layers are generated from your entity contracts and schemas.
161
151
 
162
- Yes β€” everything is fully editable, including configuration. Think of NZMT as a shadcn-style approach for full-stack: scaffold first, then fully own the code.
152
+ ## What does contract-first mean?
163
153
 
164
- If you need to tweak something, NZMT won’t get in your way. Your changes are preserved on subsequent generations. For example, if you modify a generated query and regenerate later, your edits stay intact.
154
+ The behavior of all server modules in NZMT is governed by Zod schemas. Function signatures and entity contracts are derived from these schemas. There is also automatic runtime validation to ensure that all data β€” function arguments and entity models β€” conform to their schemas.
165
155
 
166
- NZMT is designed for a plug-and-play experience β€” everything works out of the box. At the same time, it’s just a set of helpers to turn Zod schemas into service, store, and controller contracts, with a powerful scaffolder. No magic here β€” all code is yours to modify.
156
+ ## Can I tweak scaffolded files?
157
+
158
+ Yes β€” everything is fully editable, including configuration. Think of NZMT as a shadcn-style approach for full-stack: scaffold first, then fully own the code. Moreover, your changes are preserved on subsequent generations. For example, if you modify a generated query and regenerate later, your edits stay intact.
167
159
 
168
160
  ## Do I really need to understand DI and other fancy concepts to use NZMT?
169
161
 
170
- No. NZMT provides you safe and intuitive facade above `inversifyjs` and automatically registers dependencies. To get an instance you just use `fromDI` function with strongly typed keys in any place of your server code like this:
162
+ No. NZMT handles dependency injection (DI) for you using `inversifyjs`. You don’t need to set it up manually.
163
+ To get an instance of a service anywhere in your server code, just use:
171
164
 
172
165
  ```tsx
166
+ import { fromDI } from '@/server/di'
167
+
173
168
  const userService = fromDI<UserService>('UserService')
174
169
  ```
175
170
 
176
- ## Why data layer modules are called `Stores` and not `Repositories`?
177
-
178
- Good design is impossible without precise terminology. The definition of a "Repository" can vary depending on the terminology used. It’s frustrating when you’ve spent your whole life writing repositories, and then some smart aleck comes along and accuses you of having been writing, say, Data Access Objects all this time! In general, a "Repository" is simply a pattern for working with data. Often, what we really need isn’t a specific pattern, but a properly separated abstraction layer for data handling, which we can then adapt to our needs. That’s exactly why the names of the modules used for the Data Layer in NZMT are kept as abstract as possible, without tying them to any specific data-handling pattern.
179
-
180
- This approach wasn’t invented here; it has already proven successful, for example, in Go.
181
-
182
- ## Why not just use plain Next.js?
171
+ Here, `fromDI` is strongly typed β€” your IDE will give autocomplete automatically.
183
172
 
184
- You can.
185
-
186
- NZMT removes the repetitive parts:
187
- - validation
188
- - API wiring
189
- - client queries
190
- - service layer
191
- - data layer
192
-
193
- So you can focus on your logic while NZMT handles boring tech stuff like folder structure and contracts.
173
+ ## Why data layer modules are called `Stores` and not `Repositories`?
194
174
 
195
- P.S. In general, you remain within plain Next.js.
175
+ A β€œRepository” is a specific design pattern for managing data. NZMT prefers Stores β€” a simple, flexible abstraction for your data layer that can adapt to your needs regardless of the specific pattern. This approach helps to keep your code simple, and it has been successfully used in other languages, like Go.
196
176
 
197
177
  ## Why not use Nest or tRPC?
198
178
 
199
- Still you can use whatever you want, God bless you.
200
-
201
- `NZMT` sits between `tRPC` and `NestJS`:
202
-
203
- - from tRPC β€” type safety and DX
204
- - from NestJS β€” structure and layering, but more DDD-inspired
179
+ `NZMT` combines the best of both worlds in one package while staying in plain Next.js:
205
180
 
206
- But:
207
- - no framework lock-in
208
- - no magic runtime
209
- - full control over your code
210
- - power of react-query for client-server requests
211
- - no new layers of client-server interaction
181
+ - From tRPC β€” type safety and developer experience
182
+ - From NestJS β€” structured architecture (but more DDD-inspired) with intuitive DI
212
183
 
213
- Just better Next.js.
184
+ Plus:
214
185
 
186
+ - No framework lock-in
187
+ - No magic runtime
188
+ - Full control over your code
189
+ - No extra client-server layers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alevnyacow/nzmt",
3
- "version": "0.16.16",
3
+ "version": "0.16.18",
4
4
  "description": "Next Zod Modules Toolkit",
5
5
  "keywords": ["next", "full-stack", "server", "backend", "cli", "scaffolder", "zod", "rest", "contract programming", "react-query", "ddd", "domain-driven"],
6
6
  "repository": {