@alevnyacow/nzmt 0.0.8 → 0.0.10

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/bin/cli.js +236 -0
  2. package/package.json +4 -1
package/bin/cli.js ADDED
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs";
3
+ import path from "path";
4
+
5
+ var args = process.argv.slice(2);
6
+
7
+ var [command, entityName] = args;
8
+
9
+ function findProjectRoot(startDir = process.cwd()) {
10
+ let dir = startDir;
11
+ while (dir !== path.parse(dir).root) {
12
+ if (fs.existsSync(path.join(dir, "package.json"))) {
13
+ return dir;
14
+ }
15
+ dir = path.dirname(dir);
16
+ }
17
+ return null;
18
+ }
19
+
20
+ function loadConfig() {
21
+ const projectRoot = findProjectRoot();
22
+ if (!projectRoot) {
23
+ return null;
24
+ }
25
+
26
+ const configPath = path.join(projectRoot, "nzmt.config.json");
27
+
28
+ if (!fs.existsSync(configPath)) {
29
+ return null;
30
+ }
31
+
32
+ try {
33
+ const rawData = fs.readFileSync(configPath, "utf-8");
34
+ const config = JSON.parse(rawData);
35
+ return config;
36
+ } catch (err) {
37
+ throw err;
38
+ }
39
+ }
40
+
41
+ const config = loadConfig();
42
+
43
+ if (!config && command === 'init-config') {
44
+ const projectRoot = findProjectRoot()
45
+ if (!projectRoot) {
46
+ throw 'No package.json was found'
47
+ }
48
+
49
+ fs.writeFileSync(path.resolve(projectRoot, 'nzmt.config.json'), JSON.stringify({
50
+ paths: {
51
+ prismaImport: [
52
+ "import { prisma } from '@/backend/infrastructure/prisma'",
53
+ "import type { Prisma } from '@/backend/generated-prisma/client'",
54
+ ],
55
+ stores: './backend/stores',
56
+ services: './backend/services',
57
+ providers: './backend/providers',
58
+ controllers: './backend/controllers'
59
+ }
60
+ }, null, '\t'))
61
+
62
+ return 0;
63
+ }
64
+
65
+ function camelizeVariants(str) {
66
+ const words = str.split("-");
67
+
68
+ const lowerCamel = words
69
+ .map((word, index) =>
70
+ index === 0 ? word.toLowerCase() : word[0].toUpperCase() + word.slice(1).toLowerCase()
71
+ )
72
+ .join("");
73
+
74
+ const upperCamel = words
75
+ .map(word => word[0].toUpperCase() + word.slice(1).toLowerCase())
76
+ .join("");
77
+
78
+ return [lowerCamel, upperCamel];
79
+ }
80
+
81
+
82
+ var [lowerCase, upperCase] = camelizeVariants(entityName)
83
+
84
+ if (command === 'store') {
85
+ const folder = config ? path.resolve(process.cwd(), config?.paths?.stores) : path.resolve(process.cwd(), entityName);
86
+
87
+ fs.mkdirSync(folder, { recursive: true })
88
+
89
+ // Contract
90
+
91
+ fs.writeFileSync(path.resolve(folder, `${entityName}.store.ts`), [
92
+ "import z from 'zod'",
93
+ "import { Store } from '@alevnyacow/nzmt'",
94
+ "",
95
+ `export const ${lowerCase}StoreMetadata = {`,
96
+ "\tmodels: {",
97
+ "\t\tlist: z.object({ }),",
98
+ "\t\tdetails: z.object({ }),",
99
+ "\t},",
100
+ "",
101
+ "\tsearchPayload: {",
102
+ "\t\tlist: z.object({ }),",
103
+ "\t\tspecific: z.object({ }),",
104
+ "\t},",
105
+ "",
106
+ "\tactionsPayload: {",
107
+ "\t\tcreate: z.object({ }),",
108
+ "\t\tupdate: z.object({ }),",
109
+ "\t},",
110
+ "",
111
+ `\tname: '${upperCase}Store'`,
112
+ "} satisfies Store.Metadata",
113
+ "",
114
+ `export type ${upperCase}Store = Store.Contract<typeof ${lowerCase}StoreMetadata>`
115
+ ].join('\n'))
116
+
117
+ // RAM
118
+
119
+ fs.writeFileSync(path.resolve(folder, `${entityName}.store.ram.ts`), [
120
+ "import { Store } from '@alevnyacow/nzmt'",
121
+ `import { type ${upperCase}Store, ${lowerCase}StoreMetadata } from './${entityName}.store'`,
122
+ "",
123
+ `const CRUDInRAM = Store.InRAM(${lowerCase}StoreMetadata)`,
124
+ "",
125
+ `export class ${upperCase}RAMStore extends CRUDInRAM implements ${upperCase}Store {`,
126
+ "\t",
127
+ "}"
128
+ ].join('\n'))
129
+
130
+ // Prisma
131
+
132
+ fs.writeFileSync(path.resolve(folder, `${entityName}.store.prisma.ts`), [
133
+ ...config?.paths?.['prismaImport'] ?? [],
134
+ "import { Store } from '@alevnyacow/nzmt'",
135
+ `import { type ${upperCase}Store, ${lowerCase}StoreMetadata } from './${entityName}.store'`,
136
+ "",
137
+ `type Types = Store.Types<${upperCase}Store>`,
138
+ "",
139
+ "const mappers = {",
140
+ `\ttoFindOnePayload: (source: Types['findOnePayload']): Prisma.${upperCase}WhereUniqueInput => {`,
141
+ "\t\treturn {",
142
+ "\t\t\t",
143
+ "\t\t};",
144
+ "\t},",
145
+ `\ttoFindListPayload: (source: Types['findListPayload']): Prisma.${upperCase}WhereInput => {`,
146
+ "\t\treturn {",
147
+ "\t\t\t",
148
+ "\t\t};",
149
+ "\t},",
150
+ `\ttoListModel: (source: Prisma.${upperCase}GetPayload<{}>): Types['listModel'] => {`,
151
+ "\t\treturn {",
152
+ "\t\t\t",
153
+ "\t\t};",
154
+ "\t},",
155
+ `\ttoDetails: (source: Prisma.${upperCase}GetPayload<{ include: { } }>): Types['details'] => {`,
156
+ "\t\treturn {",
157
+ "\t\t\t",
158
+ "\t\t};",
159
+ "\t},",
160
+ `\ttoCreatePayload: (source: Types['createPayload']): Prisma.${upperCase}CreateInput => {`,
161
+ "\t\treturn {",
162
+ "\t\t\t",
163
+ "\t\t};",
164
+ "\t},",
165
+ `\ttoUpdatePayload: (source: Types['updatePayload']): Prisma.${upperCase}UpdateInput => {`,
166
+ "\t\treturn {",
167
+ "\t\t\t",
168
+ "\t\t};",
169
+ "\t}",
170
+ "}",
171
+ "",
172
+ `export class ${upperCase}PrismaStore implements ${upperCase}Store {`,
173
+ `\tprivate method = Store.methods(${lowerCase}StoreMetadata);`,
174
+ "",
175
+ "\tlist = this.method('list', async ({ filter, pagination: { pageSize, zeroBasedIndex } = { pageSize: 1000, zeroBasedIndex: 0 }}) => {",
176
+ `\t\tconst list = await prisma.${lowerCase}.findMany({`,
177
+ "\t\t\twhere: mappers.toFindListPayload(filter),",
178
+ "\t\t\tskip: zeroBasedIndex * pageSize,",
179
+ "\t\t\ttake: pageSize",
180
+ "\t\t})",
181
+ "\t\t",
182
+ "\t\treturn list.map(mappers.toListModel)",
183
+ "\t});",
184
+ "",
185
+ "\tdetails = this.method('details', async ({ filter }) => {",
186
+ `\t\tconst details = await prisma.${lowerCase}.findUnique({`,
187
+ "\t\t\twhere: mappers.toFindOnePayload(filter),",
188
+ "\t\t\tinclude: {}",
189
+ "\t\t})",
190
+ "",
191
+ "\t\tif (!details) {",
192
+ "\t\t\treturn null",
193
+ "\t\t}",
194
+ "",
195
+ "\t\treturn mappers.toDetails(details)",
196
+ "\t});",
197
+ "",
198
+ "\tcreate = this.method('create', async ({ payload }) => {",
199
+ `\t\tconst { id } = await prisma.${lowerCase}.create({`,
200
+ "\t\t\tdata: mappers.toCreatePayload(payload),",
201
+ "\t\t\tselect: { id: true }",
202
+ "\t\t})",
203
+ "",
204
+ "\t\treturn { id }",
205
+ "\t});",
206
+ "",
207
+ "\tupdateOne = this.method('updateOne', async ({ filter, payload }) => {",
208
+ "\t\ttry {",
209
+ `\t\t\tawait prisma.${lowerCase}.update({`,
210
+ "\t\t\t\twhere: mappers.toFindOnePayload(filter),",
211
+ "\t\t\t\tdata: mappers.toUpdatePayload(payload),",
212
+ "\t\t\t})",
213
+ "",
214
+ "\t\t\treturn { success: true }",
215
+ "\t\t}",
216
+ "\t\tcatch {",
217
+ "\t\t\treturn { success: false }",
218
+ "\t\t}",
219
+ "\t});",
220
+ "",
221
+ "\tdeleteOne = this.method('deleteOne', async ({ filter }) => {",
222
+ "\t\ttry {",
223
+ `\t\t\tawait prisma.${lowerCase}.delete({`,
224
+ "\t\t\t\twhere: mappers.toFindOnePayload(filter),",
225
+ "\t\t\t})",
226
+ "",
227
+ "\t\t\treturn { success: true }",
228
+ "\t\t}",
229
+ "\t\tcatch {",
230
+ "\t\t\treturn { success: false }",
231
+ "\t\t}",
232
+ "\t});",
233
+ "};"
234
+ ].join('\n'))
235
+ }
236
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alevnyacow/nzmt",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "description": "Next Zod Modules Toolkit",
5
5
  "type": "module",
6
6
  "exports": {
@@ -10,6 +10,9 @@
10
10
  "require": "./dist/index.cjs"
11
11
  }
12
12
  },
13
+ "bin": {
14
+ "cli": "./bin/cli.js"
15
+ },
13
16
  "main": "./dist/index.cjs",
14
17
  "types": "./dist/index.d.ts",
15
18
  "files": [