@rws-framework/db 2.3.2 → 2.4.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 (92) hide show
  1. package/.bin/add-v.sh +9 -9
  2. package/.bin/emerge.sh +10 -10
  3. package/.eslintrc.json +53 -53
  4. package/README.md +404 -367
  5. package/dist/decorators/InverseRelation.d.ts +12 -12
  6. package/dist/decorators/InverseRelation.js +24 -24
  7. package/dist/decorators/InverseTimeSeries.d.ts +8 -8
  8. package/dist/decorators/InverseTimeSeries.js +13 -13
  9. package/dist/decorators/RWSCollection.d.ts +12 -12
  10. package/dist/decorators/RWSCollection.js +16 -16
  11. package/dist/decorators/Relation.d.ts +19 -19
  12. package/dist/decorators/Relation.js +26 -26
  13. package/dist/decorators/TrackType.d.ts +20 -20
  14. package/dist/decorators/TrackType.js +41 -41
  15. package/dist/decorators/index.d.ts +5 -5
  16. package/dist/decorators/index.js +14 -14
  17. package/dist/helper/DbHelper.d.ts +8 -8
  18. package/dist/helper/DbHelper.js +141 -141
  19. package/dist/helper/FieldsHelper.d.ts +4 -4
  20. package/dist/helper/FieldsHelper.js +35 -35
  21. package/dist/index.d.ts +12 -12
  22. package/dist/index.js +19 -19
  23. package/dist/models/TimeSeriesModel.d.ts +7 -7
  24. package/dist/models/TimeSeriesModel.js +33 -33
  25. package/dist/models/_model.d.ts +6 -6
  26. package/dist/models/_model.js +9 -9
  27. package/dist/models/core/RWSModel.d.ts +66 -66
  28. package/dist/models/core/RWSModel.js +400 -400
  29. package/dist/models/core/TimeSeriesModel.d.ts +1 -1
  30. package/dist/models/core/TimeSeriesModel.js +14 -14
  31. package/dist/models/index.d.ts +7 -7
  32. package/dist/models/index.js +8 -8
  33. package/dist/models/interfaces/IModel.d.ts +11 -11
  34. package/dist/models/interfaces/IModel.js +2 -2
  35. package/dist/models/interfaces/IRWSModelServices.d.ts +6 -6
  36. package/dist/models/interfaces/IRWSModelServices.js +2 -2
  37. package/dist/models/interfaces/OpModelType.d.ts +31 -31
  38. package/dist/models/interfaces/OpModelType.js +2 -2
  39. package/dist/models/types/RelationTypes.d.ts +24 -24
  40. package/dist/models/types/RelationTypes.js +2 -2
  41. package/dist/models/utils/ModelUtils.d.ts +10 -10
  42. package/dist/models/utils/ModelUtils.js +56 -56
  43. package/dist/models/utils/PaginationUtils.d.ts +5 -5
  44. package/dist/models/utils/PaginationUtils.js +32 -32
  45. package/dist/models/utils/RelationUtils.d.ts +14 -14
  46. package/dist/models/utils/RelationUtils.js +65 -65
  47. package/dist/models/utils/TimeSeriesUtils.d.ts +11 -11
  48. package/dist/models/utils/TimeSeriesUtils.js +35 -35
  49. package/dist/services/DBService.d.ts +37 -37
  50. package/dist/services/DBService.js +198 -198
  51. package/dist/types/DbConfigHandler.d.ts +9 -9
  52. package/dist/types/DbConfigHandler.js +2 -2
  53. package/dist/types/FindParams.d.ts +14 -14
  54. package/dist/types/FindParams.js +2 -2
  55. package/dist/types/IRWSModel.d.ts +3 -3
  56. package/dist/types/IRWSModel.js +2 -2
  57. package/dist/types/ITimeSeries.d.ts +6 -6
  58. package/dist/types/ITimeSeries.js +2 -2
  59. package/exec/console.js +110 -110
  60. package/exec/db.rws.webpack.config.js +168 -168
  61. package/exec/src/cli.ts +74 -73
  62. package/exec/tsconfig.json +32 -32
  63. package/exec/webpackFilters.js +17 -17
  64. package/package.json +36 -36
  65. package/src/decorators/InverseRelation.ts +36 -36
  66. package/src/decorators/InverseTimeSeries.ts +21 -21
  67. package/src/decorators/RWSCollection.ts +27 -27
  68. package/src/decorators/Relation.ts +47 -47
  69. package/src/decorators/TrackType.ts +69 -69
  70. package/src/decorators/index.ts +7 -7
  71. package/src/empty.js +0 -0
  72. package/src/helper/DbHelper.ts +177 -177
  73. package/src/helper/FieldsHelper.ts +34 -34
  74. package/src/index.ts +36 -36
  75. package/src/models/_model.ts +29 -29
  76. package/src/models/core/RWSModel.ts +520 -520
  77. package/src/models/core/TimeSeriesModel.ts +19 -19
  78. package/src/models/index.ts +20 -20
  79. package/src/models/interfaces/IModel.ts +12 -12
  80. package/src/models/interfaces/IRWSModelServices.ts +7 -7
  81. package/src/models/interfaces/OpModelType.ts +49 -49
  82. package/src/models/types/RelationTypes.ts +25 -25
  83. package/src/models/utils/ModelUtils.ts +65 -65
  84. package/src/models/utils/PaginationUtils.ts +42 -42
  85. package/src/models/utils/RelationUtils.ts +76 -76
  86. package/src/models/utils/TimeSeriesUtils.ts +38 -38
  87. package/src/services/DBService.ts +277 -277
  88. package/src/types/DbConfigHandler.ts +12 -11
  89. package/src/types/FindParams.ts +13 -13
  90. package/src/types/IRWSModel.ts +2 -2
  91. package/src/types/ITimeSeries.ts +5 -5
  92. package/tsconfig.json +22 -22
package/README.md CHANGED
@@ -1,368 +1,405 @@
1
- # Models
2
-
3
- RWS models are converted to Prisma schemas and are wrapping around generated PrismaClient providing complete typing and better Relation handling + TimeSeries in future minor versions.
4
-
5
- ## Models index file
6
-
7
- ```typescript
8
- import ApiKey from "./ApiKey";
9
- import User from "./User";
10
-
11
- export const models = [ User, ApiKey];
12
- ```
13
- ## Example user model
14
-
15
- ```typescript
16
- import { TrackType, InverseRelation, RWSCollection, RWSModel } from '@rws-framework/db';
17
-
18
- import IUser from './interfaces/IUser';
19
- import 'reflect-metadata';
20
-
21
- import ApiKey from './ApiKey';
22
- import IApiKey from './interfaces/IApiKey';
23
-
24
- @RWSCollection('users', {
25
- relations: {
26
- transcriptions: true,
27
- apiKeys: true
28
- },
29
- ignored_keys: ['passwd']
30
- })
31
- class User extends RWSModel<User> implements IUser {
32
- @TrackType(String)
33
- username: string;
34
-
35
- @TrackType(String) // Can also handle Object and Number
36
- passwd: string;
37
-
38
- @TrackType(Boolean)
39
- active: boolean;
40
-
41
- @TrackType(Date, { required: true })
42
- created_at: Date;
43
-
44
- @TrackType(Date)
45
- updated_at: Date;
46
-
47
- /**
48
- * Every relation and inverse relation decorator
49
- * uses arrow function model passing
50
- **/
51
- @InverseRelation(() => ApiKey, () => User)
52
- apiKeys: IApiKey[];
53
-
54
- constructor(data?: IUser) {
55
- super(data);
56
-
57
- if(!this.created_at){
58
- this.created_at = new Date();
59
- }
60
- }
61
- }
62
-
63
- //Must export default for automated DI / build work.
64
- export default User;
65
- ```
66
-
67
- ## Relations
68
-
69
- ***Basic many to one relation***
70
- ```typescript
71
- import { RWSModel, TrackType, Relation } from '@rws-framework/db';
72
-
73
- import 'reflect-metadata';
74
- import User from './User';
75
- import IApiKey from './interfaces/IApiKey';
76
-
77
- class ApiKey extends RWSModel<ApiKey> implements IApiKey {
78
- static _RELATIONS = {
79
- user: true,
80
- };
81
-
82
- @Relation(() => User, true) // second attribute is required = false
83
- user: User;
84
-
85
- @TrackType(Object)
86
- keyval: string;
87
-
88
- @TrackType(Date, { required: true })
89
- created_at: Date;
90
-
91
- @TrackType(Date)
92
- updated_at: Date;
93
-
94
- static _collection = 'api_keys';
95
-
96
- constructor(data?: IApiKey) {
97
- super(data);
98
-
99
- if(!this.created_at){
100
- this.created_at = new Date();
101
- }
102
-
103
- this.updated_at = new Date();
104
- }
105
- }
106
-
107
- export default ApiKey;
108
- ```
109
-
110
- ***Relation decorator*** (many-to-one)
111
-
112
- ```typescript
113
- import 'reflect-metadata';
114
-
115
- import { RWSModel, OpModelType } from '@rws-framework/db';
116
-
117
- interface IRelationOpts {
118
- required?: boolean
119
- key?: string
120
- relationField?: string
121
- relatedToField?: string
122
- relatedTo: OpModelType<Model<any>>
123
- }
124
-
125
- function Relation(theModel: () => OpModelType<RWSModel<any>>, required: boolean = false, relationField: string = null, relatedToField: string = 'id') {
126
- return function(target: any, key: string) {
127
- // Store the promise in metadata immediately
128
- const metadataPromise = Promise.resolve().then(() => {
129
- const relatedTo = theModel();
130
- const metaOpts: IRelationOpts = {required, relatedTo, relatedToField};
131
- if(!relationField){
132
- metaOpts.relationField = relatedTo._collection + '_id';
133
- } else{
134
- metaOpts.relationField = relationField;
135
- }
136
- metaOpts.key = key;
137
- return metaOpts;
138
- });
139
-
140
- // Store both the promise and the key information
141
- Reflect.defineMetadata(`Relation:${key}`, {
142
- promise: metadataPromise,
143
- key
144
- }, target);
145
- };
146
- }
147
-
148
-
149
- export default Relation;
150
- export {IRelationOpts};
151
- ```
152
-
153
- ***Inverse relation decorator*** (one-to-many)
154
- ```typescript
155
- import 'reflect-metadata';
156
- import { RWSModel, OpModelType } from '@rws-framework/db';
157
-
158
- interface InverseRelationOpts{
159
- key: string,
160
- inversionModel: OpModelType<RWSModel<any>>,
161
- foreignKey: string
162
- }
163
-
164
- function InverseRelation(inversionModel: () => OpModelType<RWSModel<any>>, sourceModel: () => OpModelType<RWSModel<any>>, foreignKey: string = null) {
165
- return function(target: any, key: string) {
166
- // Store the promise in metadata immediately
167
- const metadataPromise = Promise.resolve().then(() => {
168
- const model = inversionModel();
169
- const source = sourceModel();
170
-
171
- const metaOpts: InverseRelationOpts = {
172
- key,
173
- inversionModel: model,
174
- foreignKey: foreignKey ? foreignKey : `${source._collection}_id`
175
- };
176
-
177
- return metaOpts;
178
- });
179
-
180
- // Store both the promise and the key information
181
- Reflect.defineMetadata(`InverseRelation:${key}`, {
182
- promise: metadataPromise,
183
- key
184
- }, target);
185
- };
186
- }
187
-
188
- export default InverseRelation;
189
- export {InverseRelationOpts};
190
- ```
191
-
192
-
193
- ## RWS Model to prisma conversion
194
-
195
- ### Init helper class
196
-
197
- **This needs to be run either from the package or CLI - it changes models to prisma schema and registers it.**
198
-
199
- *IDbConfigHandler* - An interface for config bag for DBService
200
-
201
- ```typescript
202
- import { OpModelType } from "../models/_model";
203
-
204
- export interface IDbConfigParams {
205
- mongo_url?: string;
206
- mongo_db?: string;
207
- db_models?: OpModelType<any>[]
208
- }
209
-
210
- export interface IDbConfigHandler {
211
- get<K extends keyof IDbConfigParams>(key: K): IDbConfigParams[K];
212
- }
213
- ```
214
-
215
- **Helper prisma install example**
216
-
217
- ```typescript
218
- class Config implements IDbConfigHandler {
219
- private data: IDbConfigParams = {
220
- db_models: [],
221
- mongo_db: null,
222
- mongo_url: null
223
- };
224
-
225
- private modelsDir: string;
226
- private cliExecRoot: string;
227
- private static _instance: Config = null;
228
-
229
- private constructor(){}
230
-
231
- static async getInstance(): Promise<Config>
232
- {
233
- if(!this._instance){
234
- this._instance = new Config();
235
- }
236
-
237
- await this._instance.fill();
238
-
239
- return this._instance;
240
- }
241
-
242
-
243
- async fill(): Promise<void>
244
- {
245
- this.data.mongo_url = args[0];
246
- this.data.mongo_db = args[1];
247
-
248
-
249
- this.modelsDir = args[2];
250
- this.cliExecRoot = args[3];
251
-
252
- this.data.db_models = (await import('@V/index')).default;
253
- }
254
-
255
- getModelsDir(): string
256
- {
257
- return this.modelsDir
258
- }
259
-
260
- getCliExecRoot(): string
261
- {
262
- return this.cliExecRoot
263
- }
264
-
265
- get<K extends keyof IDbConfigParams>(key: K): IDbConfigParams[K] {
266
- return this.data[key];
267
- }
268
- }
269
-
270
- async function main(): Promise<void>
271
- {
272
- console.log('INSTALL PRISMA');
273
- const cfg = await Config.getInstance();
274
- DbHelper.installPrisma(cfg, new DBService(cfg), false);
275
- }
276
- ```
277
-
278
- ### Init CLI
279
- Basic CLI command that executes **generateModelSections()** from conversion script is:
280
-
281
- **rws-db [DB_URL] [DB_NAME] [MODELS_DIRECTORY]**
282
-
283
- The exec file.
284
- ```
285
- /exec/src/console.js
286
- ```
287
-
288
- ```bash
289
- #npm
290
-
291
- npx rws-db "mongodb://user:pass@localhost:27017/databaseName?authSource=admin&replicaSet=rs0" databaseName src/models
292
- ```
293
-
294
- ```bash
295
- #yarn
296
-
297
- yarn rws-db "mongodb://user:pass@localhost:27017/databaseName?authSource=admin&replicaSet=rs0" databaseName src/models
298
- ```
299
-
300
- ```bash
301
- #bun
302
-
303
- bunx rws-db "mongodb://user:pass@localhost:27017/databaseName?authSource=admin&replicaSet=rs0" databaseName src/models
304
- ```
305
-
306
- Code for RWS to prisma conversion from "@rws-framework/server" package:
307
-
308
- ```typescript
309
- async function generateModelSections<T extends Model<T>>(model: OpModelType<T>): Promise<string> {
310
- let section = '';
311
- const modelMetadatas: Record<string, {annotationType: string, metadata: any}> = await Model.getModelAnnotations(model);
312
-
313
- const modelName: string = (model as any)._collection;
314
-
315
- section += `model ${modelName} {\n`;
316
- section += '\tid String @map("_id") @id @default(auto()) @db.ObjectId\n';
317
-
318
- for (const key in modelMetadatas) {
319
- const modelMetadata: IMetaOpts = modelMetadatas[key].metadata;
320
- const requiredString = modelMetadata.required ? '' : '?';
321
- const annotationType: string = modelMetadatas[key].annotationType;
322
-
323
- if(key === 'id'){
324
- continue;
325
- }
326
-
327
- if(annotationType === 'Relation'){
328
- const relatedModel = modelMetadata.relatedTo as OpModelType<T>;
329
- // Handle direct relation (many-to-one or one-to-one)
330
- section += `\t${key} ${relatedModel._collection}${requiredString} @relation("${modelName}_${relatedModel._collection}", fields: [${modelMetadata.relationField}], references: [${modelMetadata.relatedToField}], onDelete: Cascade)\n`;
331
- section += `\t${modelMetadata.relationField} String${requiredString} @db.ObjectId\n`;
332
- } else if (annotationType === 'InverseRelation'){
333
- // Handle inverse relation (one-to-many or one-to-one)
334
- section += `\t${key} ${modelMetadata.inversionModel._collection}[] @relation("${modelMetadata.inversionModel._collection}_${modelName}")\n`;
335
- } else if (annotationType === 'InverseTimeSeries'){
336
- section += `\t${key} String[] @db.ObjectId\n`;
337
- } else if (annotationType === 'TrackType'){
338
- const tags: string[] = modelMetadata.tags.map((item: string) => '@' + item);
339
- section += `\t${key} ${toConfigCase(modelMetadata)}${requiredString} ${tags.join(' ')}\n`;
340
- }
341
- }
342
-
343
- section += '}\n';
344
- return section;
345
- }
346
-
347
- function toConfigCase(modelType: any): string {
348
- const type = modelType.type;
349
- const input = type.name;
350
-
351
- if(input == 'Number'){
352
- return 'Int';
353
- }
354
-
355
- if(input == 'Object'){
356
- return 'Json';
357
- }
358
-
359
- if(input == 'Date'){
360
- return 'DateTime';
361
- }
362
-
363
-
364
- const firstChar = input.charAt(0).toUpperCase();
365
- const restOfString = input.slice(1);
366
- return firstChar + restOfString;
367
- }
1
+ # Models
2
+
3
+ RWS models are converted to Prisma schemas and are wrapping around generated PrismaClient providing complete typing and better Relation handling + TimeSeries in future minor versions.
4
+
5
+ ## Models index file
6
+
7
+ ```typescript
8
+ import ApiKey from "./ApiKey";
9
+ import User from "./User";
10
+
11
+ export const models = [ User, ApiKey];
12
+ ```
13
+ ## Example user model
14
+
15
+ ```typescript
16
+ import { TrackType, InverseRelation, RWSCollection, RWSModel } from '@rws-framework/db';
17
+
18
+ import IUser from './interfaces/IUser';
19
+ import 'reflect-metadata';
20
+
21
+ import ApiKey from './ApiKey';
22
+ import IApiKey from './interfaces/IApiKey';
23
+
24
+ @RWSCollection('users', {
25
+ relations: {
26
+ transcriptions: true,
27
+ apiKeys: true
28
+ },
29
+ ignored_keys: ['passwd']
30
+ })
31
+ class User extends RWSModel<User> implements IUser {
32
+ @TrackType(String)
33
+ username: string;
34
+
35
+ @TrackType(String) // Can also handle Object and Number
36
+ passwd: string;
37
+
38
+ @TrackType(Boolean)
39
+ active: boolean;
40
+
41
+ @TrackType(Date, { required: true })
42
+ created_at: Date;
43
+
44
+ @TrackType(Date)
45
+ updated_at: Date;
46
+
47
+ /**
48
+ * Every relation and inverse relation decorator
49
+ * uses arrow function model passing
50
+ **/
51
+ @InverseRelation(() => ApiKey, () => User)
52
+ apiKeys: IApiKey[];
53
+
54
+ constructor(data?: IUser) {
55
+ super(data);
56
+
57
+ if(!this.created_at){
58
+ this.created_at = new Date();
59
+ }
60
+ }
61
+ }
62
+
63
+ //Must export default for automated DI / build work.
64
+ export default User;
65
+ ```
66
+
67
+ ## Relations
68
+
69
+ ***Basic many to one relation***
70
+ ```typescript
71
+ import { RWSModel, TrackType, Relation } from '@rws-framework/db';
72
+
73
+ import 'reflect-metadata';
74
+ import User from './User';
75
+ import IApiKey from './interfaces/IApiKey';
76
+
77
+ class ApiKey extends RWSModel<ApiKey> implements IApiKey {
78
+ static _RELATIONS = {
79
+ user: true,
80
+ };
81
+
82
+ @Relation(() => User, true) // second attribute is required = false
83
+ user: User;
84
+
85
+ @TrackType(Object)
86
+ keyval: string;
87
+
88
+ @TrackType(Date, { required: true })
89
+ created_at: Date;
90
+
91
+ @TrackType(Date)
92
+ updated_at: Date;
93
+
94
+ static _collection = 'api_keys';
95
+
96
+ constructor(data?: IApiKey) {
97
+ super(data);
98
+
99
+ if(!this.created_at){
100
+ this.created_at = new Date();
101
+ }
102
+
103
+ this.updated_at = new Date();
104
+ }
105
+ }
106
+
107
+ export default ApiKey;
108
+ ```
109
+
110
+ ***Relation decorator*** (many-to-one)
111
+
112
+ ```typescript
113
+ import 'reflect-metadata';
114
+
115
+ import { RWSModel, OpModelType } from '@rws-framework/db';
116
+
117
+ interface IRelationOpts {
118
+ required?: boolean
119
+ key?: string
120
+ relationField?: string
121
+ relatedToField?: string
122
+ relatedTo: OpModelType<Model<any>>
123
+ }
124
+
125
+ function Relation(theModel: () => OpModelType<RWSModel<any>>, required: boolean = false, relationField: string = null, relatedToField: string = 'id') {
126
+ return function(target: any, key: string) {
127
+ // Store the promise in metadata immediately
128
+ const metadataPromise = Promise.resolve().then(() => {
129
+ const relatedTo = theModel();
130
+ const metaOpts: IRelationOpts = {required, relatedTo, relatedToField};
131
+ if(!relationField){
132
+ metaOpts.relationField = relatedTo._collection + '_id';
133
+ } else{
134
+ metaOpts.relationField = relationField;
135
+ }
136
+ metaOpts.key = key;
137
+ return metaOpts;
138
+ });
139
+
140
+ // Store both the promise and the key information
141
+ Reflect.defineMetadata(`Relation:${key}`, {
142
+ promise: metadataPromise,
143
+ key
144
+ }, target);
145
+ };
146
+ }
147
+
148
+
149
+ export default Relation;
150
+ export {IRelationOpts};
151
+ ```
152
+
153
+ ***Inverse relation decorator*** (one-to-many)
154
+ ```typescript
155
+ import 'reflect-metadata';
156
+ import { RWSModel, OpModelType } from '@rws-framework/db';
157
+
158
+ interface InverseRelationOpts{
159
+ key: string,
160
+ inversionModel: OpModelType<RWSModel<any>>,
161
+ foreignKey: string
162
+ }
163
+
164
+ function InverseRelation(inversionModel: () => OpModelType<RWSModel<any>>, sourceModel: () => OpModelType<RWSModel<any>>, foreignKey: string = null) {
165
+ return function(target: any, key: string) {
166
+ // Store the promise in metadata immediately
167
+ const metadataPromise = Promise.resolve().then(() => {
168
+ const model = inversionModel();
169
+ const source = sourceModel();
170
+
171
+ const metaOpts: InverseRelationOpts = {
172
+ key,
173
+ inversionModel: model,
174
+ foreignKey: foreignKey ? foreignKey : `${source._collection}_id`
175
+ };
176
+
177
+ return metaOpts;
178
+ });
179
+
180
+ // Store both the promise and the key information
181
+ Reflect.defineMetadata(`InverseRelation:${key}`, {
182
+ promise: metadataPromise,
183
+ key
184
+ }, target);
185
+ };
186
+ }
187
+
188
+ export default InverseRelation;
189
+ export {InverseRelationOpts};
190
+ ```
191
+
192
+
193
+ ## RWS Model to prisma conversion
194
+
195
+ ### Init helper class
196
+
197
+ **This needs to be run either from the package or CLI - it changes models to prisma schema and registers it.**
198
+
199
+ *IDbConfigHandler* - An interface for config bag for DBService
200
+
201
+ ```typescript
202
+ import { OpModelType } from "../models/_model";
203
+
204
+ export interface IDbConfigParams {
205
+ mongo_url?: string;
206
+ mongo_db?: string;
207
+ db_models?: OpModelType<any>[]
208
+ }
209
+
210
+ export interface IDbConfigHandler {
211
+ get<K extends keyof IDbConfigParams>(key: K): IDbConfigParams[K];
212
+ }
213
+ ```
214
+
215
+ **Helper prisma install example**
216
+
217
+ ```typescript
218
+ class Config implements IDbConfigHandler {
219
+ private data: IDbConfigParams = {
220
+ db_models: [],
221
+ db_name: null,
222
+ db_url: null,
223
+ db_type: null
224
+ };
225
+
226
+ private modelsDir: string;
227
+ private cliExecRoot: string;
228
+ private static _instance: Config = null;
229
+
230
+ private constructor(){}
231
+
232
+ static async getInstance(): Promise<Config>
233
+ {
234
+ if(!this._instance){
235
+ this._instance = new Config();
236
+ }
237
+
238
+ await this._instance.fill();
239
+
240
+ return this._instance;
241
+ }
242
+
243
+
244
+ async fill(): Promise<void>
245
+ {
246
+ this.data.db_url = args[0];
247
+ this.data.db_name = args[1];
248
+ this.data.db_type = args[2];
249
+
250
+
251
+ this.modelsDir = args[3];
252
+ this.cliExecRoot = args[4];
253
+ }
254
+
255
+ getModelsDir(): string
256
+ {
257
+ return this.modelsDir
258
+ }
259
+
260
+ getCliExecRoot(): string
261
+ {
262
+ return this.cliExecRoot
263
+ }
264
+
265
+ get<K extends keyof IDbConfigParams>(key: K): IDbConfigParams[K] {
266
+ return this.data[key];
267
+ }
268
+ }
269
+
270
+ async function main(): Promise<void>
271
+ {
272
+ console.log('INSTALL PRISMA');
273
+ const cfg = await Config.getInstance();
274
+ DbHelper.installPrisma(cfg, new DBService(cfg), false);
275
+ }
276
+ ```
277
+
278
+ ### Init CLI
279
+ Basic CLI command that executes **generateModelSections()** from conversion script is:
280
+
281
+ **rws-db [DB_URL] [DB_NAME] [MODELS_DIRECTORY]**
282
+
283
+ The exec file.
284
+ ```
285
+ /exec/src/console.js
286
+ ```
287
+
288
+ dbType can be any prisma db driver - mongodb by default
289
+
290
+ ```bash
291
+ #npm
292
+
293
+ npx rws-db "mongodb://user:pass@localhost:27017/databaseName?authSource=admin&replicaSet=rs0" databaseName dbType src/models
294
+ ```
295
+
296
+ ```bash
297
+ #yarn
298
+
299
+ yarn rws-db "mongodb://user:pass@localhost:27017/databaseName?authSource=admin&replicaSet=rs0" databaseName dbType src/models
300
+ ```
301
+
302
+ ```bash
303
+ #bun
304
+
305
+ bunx rws-db "mongodb://user:pass@localhost:27017/databaseName?authSource=admin&replicaSet=rs0" databaseName dbType src/models
306
+ ```
307
+
308
+ Code for RWS to prisma conversion from "@rws-framework/server" package:
309
+
310
+ ```typescript
311
+ static async generateModelSections(model: OpModelType<any>): Promise<string> {
312
+ let section = '';
313
+ const modelMetadatas: Record<string, {annotationType: string, metadata: any}> = await RWSModel.getModelAnnotations(model);
314
+
315
+ const modelName: string = (model as any)._collection;
316
+
317
+ section += `model ${modelName} {\n`;
318
+ section += '\tid String @map("_id") @id @default(auto()) @db.ObjectId\n';
319
+
320
+ for (const key in modelMetadatas) {
321
+ const modelMetadata = modelMetadatas[key].metadata;
322
+ let requiredString = modelMetadata.required ? '' : '?';
323
+ const annotationType: string = modelMetadatas[key].annotationType;
324
+
325
+ if(key === 'id'){
326
+ continue;
327
+ }
328
+
329
+
330
+ if(annotationType === 'Relation'){
331
+ const relationMeta = modelMetadata as IRelationOpts
332
+
333
+ const relatedModel = relationMeta.relatedTo as OpModelType<any>;
334
+ const isMany = relationMeta.many;
335
+ const cascadeOpts = [];
336
+
337
+ if (relationMeta.cascade?.onDelete) {
338
+ cascadeOpts.push(`onDelete: ${relationMeta.cascade.onDelete}`);
339
+ }
340
+
341
+ if (relationMeta.cascade?.onUpdate) {
342
+ cascadeOpts.push(`onUpdate: ${relationMeta.cascade.onUpdate}`);
343
+ }
344
+
345
+ if (isMany) {
346
+ // Handle many-to-many or one-to-many relation
347
+ section += `\t${key} ${relatedModel._collection}[] @relation("${modelName}_${relatedModel._collection}")\n`;
348
+ } else {
349
+ // Handle one-to-one or many-to-one relation
350
+ section += `\t${key} ${relatedModel._collection}${requiredString} @relation("${modelName}_${relatedModel._collection}", fields: [${modelMetadata.relationField}], references: [${modelMetadata.relatedToField || 'id'}], ${cascadeOpts.join(', ')})\n`;
351
+ section += `\t${modelMetadata.relationField} String${requiredString} @db.ObjectId\n`;
352
+ }
353
+ } else if (annotationType === 'InverseRelation'){
354
+ const relationMeta = modelMetadata as InverseRelationOpts;
355
+
356
+ // Handle inverse relation (one-to-many or one-to-one)
357
+ section += `\t${key} ${relationMeta.inversionModel._collection}[] @relation("${ relationMeta.relationName ? relationMeta.relationName : `${relationMeta.inversionModel._collection}_${modelName}`}")\n`;
358
+ } else if (annotationType === 'InverseTimeSeries'){
359
+ section += `\t${key} String[] @db.ObjectId\n`;
360
+ } else if (annotationType === 'TrackType'){
361
+ const tags: string[] = modelMetadata.tags.map((item: string) => '@' + item);
362
+
363
+ if(modelMetadata.isArray || modelMetadata.type.name === 'Array'){
364
+ requiredString = '';
365
+ }
366
+ section += `\t${key} ${DbHelper.toConfigCase(modelMetadata)}${requiredString} ${tags.join(' ')}\n`;
367
+ }
368
+ }
369
+
370
+ section += '}\n';
371
+ return section;
372
+ }
373
+
374
+ static toConfigCase(modelType: IMetaOpts): string {
375
+ const type = modelType.type;
376
+ let input = type.name;
377
+
378
+
379
+ if(input == 'Number'){
380
+ input = 'Int';
381
+ }
382
+
383
+ if(input == 'Object'){
384
+ input = 'Json';
385
+ }
386
+
387
+ if(input == 'Date'){
388
+ input = 'DateTime';
389
+ }
390
+
391
+ if(input == 'Array'){
392
+ input = 'Json[]';
393
+ }
394
+
395
+ const firstChar = input.charAt(0).toUpperCase();
396
+ const restOfString = input.slice(1);
397
+ let resultField = firstChar + restOfString;
398
+
399
+ if(modelType.isArray){
400
+ resultField += '[]';
401
+ }
402
+
403
+ return resultField;
404
+ }
368
405
  ```