@alevnyacow/nzmt 0.16.15 β†’ 0.16.17

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 -82
  2. package/package.json +2 -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,39 +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! Even invalidations are working out of the box (though you can modify scaffolded queries any way you want)! ✨
96
-
97
92
  ```tsx
98
93
  'use client'
99
94
 
100
95
  import { UserQueries } from "@/client/shared/queries/user";
101
96
 
102
- export default function Home() {
97
+ export default function () {
103
98
  const { mutate: addUser } = UserQueries.usePOST()
104
99
  const { data, isFetching } = UserQueries.useGET({ query: {} })
105
100
 
106
- const addColinZeal = () => {
107
- addUser({ body: { payload: { name: 'Colin Zeal' } } })
101
+ const addRandomUser = () => {
102
+ addUser({ body: { payload: { name: `${Math.random()}` } } })
108
103
  }
109
104
 
110
105
  return (
111
106
  <div>
112
- <button onClick={addColinZeal}>
113
- Add Mr. Zeal
107
+ <button onClick={addRandomUser}>
108
+ New random user
114
109
  </button>
115
110
 
116
111
  {isFetching ? 'Loading users...' : JSON.stringify(data)}
@@ -120,14 +115,12 @@ export default function Home() {
120
115
 
121
116
  ```
122
117
 
123
- ### How to use server modules as server actions
118
+ ## πŸ”Ό Using scaffolded Service methods as Next server actions
124
119
 
125
120
  ```
126
121
  Schema: Server Action β†’ Service β†’ Store β†’ DB
127
122
  ```
128
123
 
129
- Just get required instances from DI and use methods. That's all. ✨
130
-
131
124
  ```tsx
132
125
  'use server'
133
126
 
@@ -142,71 +135,55 @@ export default async function() {
142
135
  */
143
136
  const userService = fromDI<UserService>('UserService')
144
137
 
145
- const driver8 = await userService.getDetails({
146
- filter: { id: 'driver-8' }
138
+ const user1 = await userService.getDetails({
139
+ filter: { id: 'user-1-id' }
147
140
  })
148
141
 
149
- return <div>
150
- Take a break, {JSON.stringify(driver8)}
151
- {JSON.stringify(driver8)}, take a break
152
- </div>
142
+ return <div>{JSON.stringify(user1)}</div>
153
143
  }
154
144
  ```
155
145
 
156
- # Common questions
146
+ # ❓ FAQ
157
147
 
158
- ## 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.
151
+
152
+ ## What does contract-first mean?
159
153
 
160
- 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.
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.
161
155
 
162
- 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.
156
+ ## Can I tweak scaffolded files?
163
157
 
164
- 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.
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.
165
159
 
166
160
  ## Do I really need to understand DI and other fancy concepts to use NZMT?
167
161
 
168
- 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:
169
164
 
170
165
  ```tsx
166
+ import { fromDI } from '@/server/di'
167
+
171
168
  const userService = fromDI<UserService>('UserService')
172
169
  ```
173
170
 
174
- ## Why data layer modules are called `Stores` and not `Repositories`?
175
-
176
- 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.
177
-
178
- This approach wasn’t invented here; it has already proven successful, for example, in Go.
179
-
180
- ## Why not just use plain Next.js?
171
+ Here, `fromDI` is strongly typed β€” your IDE will give autocomplete automatically.
181
172
 
182
- You can.
183
-
184
- NZMT removes the repetitive parts:
185
- - validation
186
- - API wiring
187
- - client queries
188
- - service layer
189
- - data layer
190
-
191
- 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`?
192
174
 
193
- 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.
194
176
 
195
177
  ## Why not use Nest or tRPC?
196
178
 
197
- Still you can use whatever you want, God bless you.
198
-
199
- `NZMT` sits between `tRPC` and `NestJS`:
200
-
201
- - from tRPC β€” type safety and DX
202
- - from NestJS β€” structure and layering, but more DDD-inspired
179
+ `NZMT` combines the best of both worlds while staying in plain Next.js:
203
180
 
204
- But:
205
- - no framework lock-in
206
- - no magic runtime
207
- - full control over your code
208
- - power of react-query for client-server requests
209
- - 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
210
183
 
211
- Just better Next.js.
184
+ Plus:
212
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,7 +1,8 @@
1
1
  {
2
2
  "name": "@alevnyacow/nzmt",
3
- "version": "0.16.15",
3
+ "version": "0.16.17",
4
4
  "description": "Next Zod Modules Toolkit",
5
+ "keywords": ["next", "full-stack", "server", "backend", "cli", "scaffolder", "zod", "rest", "contract programming", "react-query", "ddd", "domain-driven"],
5
6
  "repository": {
6
7
  "type": "git",
7
8
  "url": "https://github.com/alevnyacow/nzmt.git"