@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.
Files changed (2) hide show
  1. package/bin/cli.js +152 -35
  2. 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 = ''] = args;
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
- stores: './src/backend/stores',
78
- services: './src/backend/services',
79
- providers: './src/backend/providers',
80
- controllers: './src/backend/controllers',
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 '@/backend/infrastructure/prisma'",
94
- "import type { Prisma } from '@/backend/generated-prisma/client'",
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
- config?.dependencyInjection?.inversifyjs ? "import { injectable } from 'inversify'" : undefined,
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
- config?.dependencyInjection?.inversifyjs ? "@injectable()" : undefined,
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
- config?.dependencyInjection?.inversifyjs ? "import { injectable } from 'inversify'" : undefined,
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
- config?.dependencyInjection?.inversifyjs ? "@injectable()" : undefined,
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
- config?.dependencyInjection?.inversifyjs ? "import { injectable, inject } from 'inversify'" : undefined,
395
- config?.dependencyInjection?.inversifyjs?.storeTokensImport ?? undefined,
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
- config?.dependencyInjection?.inversifyjs ? "@injectable()" : undefined,
516
+ "@injectable()",
400
517
  `export class ${upperCase}Service {`,
401
518
  `\tconstructor(`,
402
- config?.dependencyInjection?.inversifyjs?.storeTokensImport ? `\t\t@inject(${getImportName(config?.dependencyInjection?.inversifyjs?.storeTokensImport)}.${lowerCase}s)` : undefined,
403
- `\t\tprivate readonly ${lowerCase}s: ${upperCase}Store`,
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}s.create);`,
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 this.${lowerCase}s.details(x);`,
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 this.${lowerCase}s.list(x);`,
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 this.${lowerCase}s.updateOne(x);`,
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 this.${lowerCase}s.deleteOne(x);`,
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
- config?.dependencyInjection?.inversifyjs ? "import { injectable } from 'inversify'" : undefined,
550
+ "import { injectable } from 'inversify'",
434
551
  `import { ${lowerCase}ServiceMetadata } from './${entityName}.service.metadata'`,
435
552
  "import { Module } from '@alevnyacow/nzmt'",
436
553
  "",
437
- config?.dependencyInjection === 'inversifyjs' ? "@injectable()" : undefined,
554
+ "@injectable()",
438
555
  `export class ${upperCase}Service {`,
439
556
  `\tprivate methods = Module.methods(${lowerCase}ServiceMetadata)`,
440
557
  "}"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alevnyacow/nzmt",
3
- "version": "0.1.14",
3
+ "version": "0.2.0",
4
4
  "description": "Next Zod Modules Toolkit",
5
5
  "repository": {
6
6
  "type": "git",