@alevnyacow/nzmt 0.22.8 → 0.23.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/README.md +35 -28
- package/bin/cli.js +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -145,34 +145,35 @@ export default async function Page() {
|
|
|
145
145
|
| `npx nzmt s <name>` | **s**ervice |`i:UserStore,Logger` will automatically inject `UserStore` and `Logger`. E.g. `npx nzmt s shop i:UserStore,ProductStore` will create `ShopService` with already injected `UserStore` and `ProductStore`|
|
|
146
146
|
| `npx nzmt c <name>` | **c**ontroller |`i:UserService` will automatically inject `UserService`. `Logger` and `Guards` are injected by default regardless of `i:` option|
|
|
147
147
|
|
|
148
|
+
Here’s a shorter, simpler version in English:
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
148
152
|
# How to implement your own methods
|
|
149
153
|
|
|
150
|
-
##
|
|
154
|
+
## Zod schemas (module contracts)
|
|
155
|
+
|
|
156
|
+
Server method contracts are defined with Zod schemas in files like `user.controller.metadata.ts` or `product.service.metadata.ts`.
|
|
157
|
+
|
|
158
|
+
They:
|
|
151
159
|
|
|
152
|
-
|
|
160
|
+
- validate data at runtime
|
|
161
|
+
- can be reused across layers (no separate DTOs needed)
|
|
162
|
+
- automatically infer types (no manual TypeScript work)
|
|
153
163
|
|
|
154
164
|
```ts
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
createdDate: true
|
|
160
|
-
}),
|
|
161
|
-
response: z.object({
|
|
162
|
-
user: User.schema,
|
|
165
|
+
orderDetails: {
|
|
166
|
+
payload: Order.schema.pick({ name: true, createdDate: true }),
|
|
167
|
+
response: z.object({
|
|
168
|
+
user: User.schema,
|
|
163
169
|
products: z.array(Product.schema.omit({ price: true }))
|
|
164
170
|
})
|
|
165
171
|
}
|
|
166
|
-
// ...some service metadata schemas
|
|
167
172
|
```
|
|
168
173
|
|
|
169
|
-
**All types and keys are infered, no need to worry about TypeScript.**
|
|
170
|
-
|
|
171
174
|
## Services
|
|
172
175
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
1. **Describe it in metadata schemas** using Zod (`service-name.service.metadata.ts`):
|
|
176
|
+
1. **Define method in metadata** (`*.service.metadata.ts`):
|
|
176
177
|
|
|
177
178
|
```ts
|
|
178
179
|
foo: {
|
|
@@ -181,7 +182,7 @@ foo: {
|
|
|
181
182
|
}
|
|
182
183
|
```
|
|
183
184
|
|
|
184
|
-
2. **Implement it in
|
|
185
|
+
2. **Implement it in service** (`*.service.ts`):
|
|
185
186
|
|
|
186
187
|
```ts
|
|
187
188
|
// 'foo' string is strongly-typed, don't worry
|
|
@@ -193,9 +194,9 @@ foo = this.methods('foo', async ({ requestString }) => {
|
|
|
193
194
|
|
|
194
195
|
## Controllers
|
|
195
196
|
|
|
196
|
-
Same idea
|
|
197
|
+
Same idea, but metadata uses optional `query`, optional `body`, and `response`.
|
|
197
198
|
|
|
198
|
-
1. **Metadata** (
|
|
199
|
+
1. **Metadata** (`*.controller.metadata.ts`):
|
|
199
200
|
|
|
200
201
|
```ts
|
|
201
202
|
POST: {
|
|
@@ -205,30 +206,36 @@ POST: {
|
|
|
205
206
|
}
|
|
206
207
|
```
|
|
207
208
|
|
|
208
|
-
2. **Implementation** (
|
|
209
|
+
2. **Implementation** (`*.controller.ts`):
|
|
209
210
|
|
|
210
211
|
```ts
|
|
211
|
-
// `query` and `body` are merged into a single payload
|
|
212
212
|
POST = this.endpoints('POST', async ({ id, delta }) => {
|
|
213
213
|
return { success: true }
|
|
214
214
|
})
|
|
215
215
|
```
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
`query` + `body` are merged into one object in implementation.
|
|
218
|
+
|
|
219
|
+
## Usage in Next.js
|
|
220
|
+
|
|
221
|
+
Controllers can be used directly as API routes:
|
|
218
222
|
|
|
219
223
|
```ts
|
|
220
224
|
// api/user-controller/route.ts
|
|
221
|
-
import { fromDI } from '@/server/di'
|
|
222
|
-
import type { UserController } from '@/server/controllers/user'
|
|
223
|
-
|
|
224
225
|
const controller = fromDI<UserController>('UserController')
|
|
225
226
|
|
|
226
227
|
export const GET = controller.GET
|
|
227
|
-
export const PUT = controller.PUT
|
|
228
|
-
export const PATCH = controller.PATCH
|
|
229
|
-
export const DELETE = controller.DELETE
|
|
230
228
|
```
|
|
231
229
|
|
|
230
|
+
And servers can be used directlt as Server Actions:
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
export default async function() {
|
|
234
|
+
const service = fromDI<UserService>('UserService')
|
|
235
|
+
const users = await service.getList({ filter: {} })
|
|
236
|
+
// ...
|
|
237
|
+
}
|
|
238
|
+
```
|
|
232
239
|
|
|
233
240
|
# FAQ
|
|
234
241
|
|
package/bin/cli.js
CHANGED
|
@@ -788,10 +788,10 @@ function generateProvider(lowerCase, upperCase) {
|
|
|
788
788
|
|
|
789
789
|
// Base
|
|
790
790
|
fs.writeFileSync(path.resolve(folder, `${entityName}.provider.ts`), [
|
|
791
|
-
`import { Module } from '@alevnyacow/nzmt'
|
|
791
|
+
`import { Module } from '@alevnyacow/nzmt',`,
|
|
792
792
|
'',
|
|
793
793
|
`export const ${lowerCase}ProviderMetadata = {`,
|
|
794
|
-
`\tname: '${upperCase}Provider'
|
|
794
|
+
`\tname: '${upperCase}Provider',`,
|
|
795
795
|
`\tschemas: {}`,
|
|
796
796
|
`} satisfies Module.Metadata`,
|
|
797
797
|
``,
|
|
@@ -816,7 +816,7 @@ function generateProvider(lowerCase, upperCase) {
|
|
|
816
816
|
`import { ${upperCase}Provider } from './${entityName}.provider'`,
|
|
817
817
|
'',
|
|
818
818
|
`export class ${upperCase}${providerType}Provider extends ${upperCase}Provider {`,
|
|
819
|
-
`\
|
|
819
|
+
`\t`,
|
|
820
820
|
`}`
|
|
821
821
|
].join('\n'))
|
|
822
822
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alevnyacow/nzmt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Next Zod Modules Toolkit",
|
|
5
|
-
"keywords": ["next", "full-stack", "server", "backend", "cli", "
|
|
5
|
+
"keywords": ["next", "full-stack", "server", "backend", "cli", "scaffolding", "zod", "rest", "contract programming", "contract-first", "react-query", "ddd", "domain-driven"],
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/alevnyacow/nzmt.git"
|