@alevnyacow/nzmt 0.1.14 → 0.2.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/bin/cli.js +152 -35
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -4,12 +4,7 @@ import path from "path";
|
|
|
4
4
|
|
|
5
5
|
var args = process.argv.slice(2);
|
|
6
6
|
|
|
7
|
-
var [command, entityName, options
|
|
8
|
-
|
|
9
|
-
function getImportName(str) {
|
|
10
|
-
const match = str.match(/import\s*{\s*([^}]+)\s*}/);
|
|
11
|
-
return match ? match[1].trim() : null;
|
|
12
|
-
}
|
|
7
|
+
var [command, entityName, ...options] = args;
|
|
13
8
|
|
|
14
9
|
function camelizeVariants(str) {
|
|
15
10
|
if (!str.includes('-')) {
|
|
@@ -74,24 +69,19 @@ function createDefaultConfig() {
|
|
|
74
69
|
|
|
75
70
|
fs.writeFileSync(path.resolve(projectRoot, 'nzmt.config.json'), JSON.stringify({
|
|
76
71
|
paths: {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
72
|
+
di: './src/server/di',
|
|
73
|
+
stores: './src/server/stores',
|
|
74
|
+
services: './src/server/services',
|
|
75
|
+
providers: './src/server/providers',
|
|
76
|
+
controllers: './src/server/controllers',
|
|
81
77
|
entities: './src/shared/entities',
|
|
82
|
-
queries: './src/client/shared/queries'
|
|
83
|
-
di: './src/backend/dependency-injection'
|
|
84
|
-
},
|
|
85
|
-
dependencyInjection: {
|
|
86
|
-
inversifyjs: {
|
|
87
|
-
storeTokensImport: "import { DIStores } from '@/backend/di'"
|
|
88
|
-
}
|
|
78
|
+
queries: './src/client/shared/queries'
|
|
89
79
|
},
|
|
90
80
|
store: {
|
|
91
81
|
prisma: {
|
|
92
82
|
import: [
|
|
93
|
-
"import { prisma } from '@/
|
|
94
|
-
"import type { Prisma } from '@/
|
|
83
|
+
"import { prisma } from '@/server/infrastructure/prisma'",
|
|
84
|
+
"import type { Prisma } from '@/server/generated-prisma/client'",
|
|
95
85
|
]
|
|
96
86
|
},
|
|
97
87
|
}
|
|
@@ -100,8 +90,135 @@ function createDefaultConfig() {
|
|
|
100
90
|
|
|
101
91
|
}
|
|
102
92
|
|
|
93
|
+
function initDI() {
|
|
94
|
+
const config = loadConfig()
|
|
95
|
+
const diPath = config?.paths?.di
|
|
96
|
+
|
|
97
|
+
const folder = path.resolve(process.cwd(), diPath)
|
|
98
|
+
fs.mkdirSync(folder, { recursive: true })
|
|
99
|
+
|
|
100
|
+
// Entries
|
|
101
|
+
fs.writeFileSync(path.resolve(folder, `entries.di.ts`), [
|
|
102
|
+
"import type { BindInWhenOnFluentSyntax } from 'inversify'",
|
|
103
|
+
"type DIEntries = Record<",
|
|
104
|
+
"\tstring,",
|
|
105
|
+
"\t| (new (...args: any[]) => any)",
|
|
106
|
+
"\t| Record<'test' | 'dev' | 'prod',",
|
|
107
|
+
"\t\t| [new (...args: any[]) => any, (x: BindInWhenOnFluentSyntax<unknown>) => any]",
|
|
108
|
+
"\t\t| (new (...args: any[]) => any)",
|
|
109
|
+
"\t>",
|
|
110
|
+
">",
|
|
111
|
+
"",
|
|
112
|
+
"export const diEntries = {",
|
|
113
|
+
"\t// Stores",
|
|
114
|
+
"\t// Providers",
|
|
115
|
+
"\t// Services",
|
|
116
|
+
"\t// Controllers",
|
|
117
|
+
"\t// Other",
|
|
118
|
+
"} satisfies DIEntries",
|
|
119
|
+
"",
|
|
120
|
+
"export type DITokens = keyof typeof diEntries",
|
|
121
|
+
].join('\n'))
|
|
122
|
+
|
|
123
|
+
// Containers
|
|
124
|
+
fs.writeFileSync(path.resolve(folder, `container.dev.di.ts`), [
|
|
125
|
+
"import { Container } from 'inversify'",
|
|
126
|
+
"import { diEntries } from './entries.di'",
|
|
127
|
+
"",
|
|
128
|
+
"const container = new Container()",
|
|
129
|
+
"",
|
|
130
|
+
"for (const rule in diEntries) {",
|
|
131
|
+
"\tconst ruleContentRaw = diEntries[rule as keyof typeof diEntries]",
|
|
132
|
+
"\tconst ruleContent =",
|
|
133
|
+
"\t\ttypeof ruleContentRaw === 'object'",
|
|
134
|
+
"\t\t\t? ruleContentRaw.dev",
|
|
135
|
+
"\t\t\t: ruleContentRaw",
|
|
136
|
+
"\tif (Array.isArray(ruleContent)) {",
|
|
137
|
+
"\t\tconst [Entry, builder] = ruleContent",
|
|
138
|
+
"\t\tbuilder(container.bind(rule).to(Entry))",
|
|
139
|
+
"\t\tcontinue",
|
|
140
|
+
"\t}",
|
|
141
|
+
"\tcontainer.bind(rule).to(ruleContent)",
|
|
142
|
+
"}",
|
|
143
|
+
"",
|
|
144
|
+
"export { container as devContainer }"
|
|
145
|
+
].join('\n'))
|
|
146
|
+
|
|
147
|
+
fs.writeFileSync(path.resolve(folder, `container.test.di.ts`), [
|
|
148
|
+
"import { Container } from 'inversify'",
|
|
149
|
+
"import { diEntries } from './entries.di'",
|
|
150
|
+
"",
|
|
151
|
+
"const container = new Container()",
|
|
152
|
+
"",
|
|
153
|
+
"for (const rule in diEntries) {",
|
|
154
|
+
"\tconst ruleContentRaw = diEntries[rule as keyof typeof diEntries]",
|
|
155
|
+
"\tconst ruleContent =",
|
|
156
|
+
"\t\ttypeof ruleContentRaw === 'object'",
|
|
157
|
+
"\t\t\t? ruleContentRaw.test",
|
|
158
|
+
"\t\t\t: ruleContentRaw",
|
|
159
|
+
"\tif (Array.isArray(ruleContent)) {",
|
|
160
|
+
"\t\tconst [Entry, builder] = ruleContent",
|
|
161
|
+
"\t\tbuilder(container.bind(rule).to(Entry))",
|
|
162
|
+
"\t\tcontinue",
|
|
163
|
+
"\t}",
|
|
164
|
+
"\tcontainer.bind(rule).to(ruleContent)",
|
|
165
|
+
"}",
|
|
166
|
+
"",
|
|
167
|
+
"export { container as testContainer }"
|
|
168
|
+
].join('\n'))
|
|
169
|
+
|
|
170
|
+
fs.writeFileSync(path.resolve(folder, `container.prod.di.ts`), [
|
|
171
|
+
"import { Container } from 'inversify'",
|
|
172
|
+
"import { diEntries } from './entries.di'",
|
|
173
|
+
"",
|
|
174
|
+
"const container = new Container()",
|
|
175
|
+
"",
|
|
176
|
+
"for (const rule in diEntries) {",
|
|
177
|
+
"\tconst ruleContentRaw = diEntries[rule as keyof typeof diEntries]",
|
|
178
|
+
"\tconst ruleContent =",
|
|
179
|
+
"\t\ttypeof ruleContentRaw === 'object'",
|
|
180
|
+
"\t\t\t? ruleContentRaw.prod",
|
|
181
|
+
"\t\t\t: ruleContentRaw",
|
|
182
|
+
"\tif (Array.isArray(ruleContent)) {",
|
|
183
|
+
"\t\tconst [Entry, builder] = ruleContent",
|
|
184
|
+
"\t\tbuilder(container.bind(rule).to(Entry))",
|
|
185
|
+
"\t\tcontinue",
|
|
186
|
+
"\t}",
|
|
187
|
+
"\tcontainer.bind(rule).to(ruleContent)",
|
|
188
|
+
"}",
|
|
189
|
+
"",
|
|
190
|
+
"export { container as prodContainer }"
|
|
191
|
+
].join('\n'))
|
|
192
|
+
|
|
193
|
+
// Index
|
|
194
|
+
fs.writeFileSync(path.resolve(folder, `index.ts`), [
|
|
195
|
+
"import 'reflect-metadata'",
|
|
196
|
+
"import { devContainer } from './container.dev.di'",
|
|
197
|
+
"import { prodContainer } from './container.prod.di'",
|
|
198
|
+
"import { testContainer } from './container.test.di'",
|
|
199
|
+
"import type { DITokens } from './entries.di'",
|
|
200
|
+
"",
|
|
201
|
+
"const getActiveContainer = () => {",
|
|
202
|
+
"\tconst environment = process.env.NODE_ENV",
|
|
203
|
+
"\tif (environment === 'test') {",
|
|
204
|
+
"\t\treturn testContainer",
|
|
205
|
+
"\t}",
|
|
206
|
+
"\tif (environment === 'development') {",
|
|
207
|
+
"\t\treturn devContainer",
|
|
208
|
+
"\t}",
|
|
209
|
+
"\treturn prodContainer",
|
|
210
|
+
"}",
|
|
211
|
+
"",
|
|
212
|
+
"export const fromDI = <Result>(key: DITokens) => {",
|
|
213
|
+
"\tconst container = getActiveContainer()",
|
|
214
|
+
"\treturn container.get<Result>(key)",
|
|
215
|
+
"}"
|
|
216
|
+
].join('\n'))
|
|
217
|
+
};
|
|
218
|
+
|
|
103
219
|
if (command === 'init') {
|
|
104
220
|
createDefaultConfig()
|
|
221
|
+
initDI()
|
|
105
222
|
process.exit(0)
|
|
106
223
|
}
|
|
107
224
|
|
|
@@ -141,13 +258,13 @@ function generateStores(lowerCase, upperCase) {
|
|
|
141
258
|
// RAM
|
|
142
259
|
|
|
143
260
|
fs.writeFileSync(path.resolve(folder, `${entityName}.store.ram.ts`), [
|
|
144
|
-
|
|
261
|
+
"import { injectable } from 'inversify'",
|
|
145
262
|
"import { Store } from '@alevnyacow/nzmt'",
|
|
146
263
|
`import { type ${upperCase}Store, ${lowerCase}StoreMetadata } from './${entityName}.store'`,
|
|
147
264
|
"",
|
|
148
265
|
`const CRUDInRAM = Store.InRAM(${lowerCase}StoreMetadata)`,
|
|
149
266
|
"",
|
|
150
|
-
|
|
267
|
+
"@injectable()",
|
|
151
268
|
`export class ${upperCase}RAMStore extends CRUDInRAM implements ${upperCase}Store {`,
|
|
152
269
|
"\t",
|
|
153
270
|
"}"
|
|
@@ -157,7 +274,7 @@ function generateStores(lowerCase, upperCase) {
|
|
|
157
274
|
|
|
158
275
|
fs.writeFileSync(path.resolve(folder, `${entityName}.store.prisma.ts`), [
|
|
159
276
|
...config?.store?.prisma?.import ?? [],
|
|
160
|
-
|
|
277
|
+
"import { injectable } from 'inversify'",
|
|
161
278
|
"import { Store } from '@alevnyacow/nzmt'",
|
|
162
279
|
`import { type ${upperCase}Store, ${lowerCase}StoreMetadata } from './${entityName}.store'`,
|
|
163
280
|
"",
|
|
@@ -196,7 +313,7 @@ function generateStores(lowerCase, upperCase) {
|
|
|
196
313
|
"\t}",
|
|
197
314
|
"}",
|
|
198
315
|
"",
|
|
199
|
-
|
|
316
|
+
"@injectable()",
|
|
200
317
|
`export class ${upperCase}PrismaStore implements ${upperCase}Store {`,
|
|
201
318
|
`\tprivate method = Store.methods(${lowerCase}StoreMetadata);`,
|
|
202
319
|
"",
|
|
@@ -391,50 +508,50 @@ function generateService(lowerCase, upperCase, withCrud) {
|
|
|
391
508
|
|
|
392
509
|
if (withCrud) {
|
|
393
510
|
fs.writeFileSync(path.resolve(folder, `${entityName}.service.ts`), [
|
|
394
|
-
|
|
395
|
-
config?.
|
|
511
|
+
"import { injectable, inject } from 'inversify'",
|
|
512
|
+
`import { DITokens } from '${config?.paths?.di?.replace('./src', '@')}'`,
|
|
396
513
|
`import type { ${upperCase}Store } from '${config?.paths?.stores?.replace('./src', '@')}/${entityName}'`,
|
|
397
514
|
`import { ${lowerCase}ServiceMetadata } from './${entityName}.service.metadata'`,
|
|
398
515
|
"import { Module } from '@alevnyacow/nzmt'",
|
|
399
|
-
|
|
516
|
+
"@injectable()",
|
|
400
517
|
`export class ${upperCase}Service {`,
|
|
401
518
|
`\tconstructor(`,
|
|
402
|
-
|
|
403
|
-
`\t\tprivate readonly ${lowerCase}
|
|
519
|
+
`\t\t@inject('${upperCase}Store' satisfies DITokens)`,
|
|
520
|
+
`\t\tprivate readonly ${lowerCase}Store: ${upperCase}Store`,
|
|
404
521
|
'\t) { }',
|
|
405
522
|
'\t',
|
|
406
523
|
`\tprivate method = Module.methods(${lowerCase}ServiceMetadata)`,
|
|
407
524
|
'\t',
|
|
408
|
-
`\tcreate = this.method('create', this.${lowerCase}
|
|
525
|
+
`\tcreate = this.method('create', this.${lowerCase}Store.create);`,
|
|
409
526
|
'\t',
|
|
410
527
|
`\tgetSpecific = this.method('getSpecific', async (x) => {`,
|
|
411
|
-
`\t\tconst item = await
|
|
528
|
+
`\t\tconst item = await ${lowerCase}Store.details(x);`,
|
|
412
529
|
`\t\treturn { item };`,
|
|
413
530
|
`\t})`,
|
|
414
531
|
`\t`,
|
|
415
532
|
`\tgetList = this.method('getList', async (x) => {`,
|
|
416
|
-
`\t\tconst items = await
|
|
533
|
+
`\t\tconst items = await ${lowerCase}Store.list(x);`,
|
|
417
534
|
`\t\treturn { items };`,
|
|
418
535
|
`\t})`,
|
|
419
536
|
`\t`,
|
|
420
537
|
`\tupdateOne = this.method('updateOne', async (x) => {`,
|
|
421
|
-
`\t\tawait
|
|
538
|
+
`\t\tawait ${lowerCase}Store.updateOne(x);`,
|
|
422
539
|
`\t\treturn {};`,
|
|
423
540
|
`\t})`,
|
|
424
541
|
`\t`,
|
|
425
542
|
`\tdeleteOne = this.method('deleteOne', async (x) => {`,
|
|
426
|
-
`\t\tawait
|
|
543
|
+
`\t\tawait ${lowerCase}Store.deleteOne(x);`,
|
|
427
544
|
`\t\treturn {};`,
|
|
428
545
|
`\t})`,
|
|
429
546
|
"}"
|
|
430
547
|
].filter(x => typeof x === 'string').join('\n'))
|
|
431
548
|
} else {
|
|
432
549
|
fs.writeFileSync(path.resolve(folder, `${entityName}.service.ts`), [
|
|
433
|
-
|
|
550
|
+
"import { injectable } from 'inversify'",
|
|
434
551
|
`import { ${lowerCase}ServiceMetadata } from './${entityName}.service.metadata'`,
|
|
435
552
|
"import { Module } from '@alevnyacow/nzmt'",
|
|
436
553
|
"",
|
|
437
|
-
|
|
554
|
+
"@injectable()",
|
|
438
555
|
`export class ${upperCase}Service {`,
|
|
439
556
|
`\tprivate methods = Module.methods(${lowerCase}ServiceMetadata)`,
|
|
440
557
|
"}"
|