@rws-framework/db 4.1.4 → 4.1.6
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.
|
@@ -222,7 +222,7 @@ class RWSModel {
|
|
|
222
222
|
if (entryExists) {
|
|
223
223
|
await this.preUpdate();
|
|
224
224
|
const pk = ModelUtils_1.ModelUtils.findPrimaryKeyFields(this.constructor);
|
|
225
|
-
updatedModelData = await this.dbService.update(data, this.getCollection(), pk);
|
|
225
|
+
updatedModelData = await this.dbService.update(data, this.getCollection(), pk, this.constructor);
|
|
226
226
|
await this._asyncFill(updatedModelData);
|
|
227
227
|
await this.postUpdate();
|
|
228
228
|
}
|
|
@@ -23,7 +23,7 @@ declare class DBService {
|
|
|
23
23
|
cloneDatabase(source: string, target: string): Promise<void>;
|
|
24
24
|
watchCollection(collectionName: string, preRun: () => void): Promise<any>;
|
|
25
25
|
insert(data: any, collection: string, isTimeSeries?: boolean): Promise<any>;
|
|
26
|
-
update(data: any, collection: string, pk: string | string[]): Promise<IModel>;
|
|
26
|
+
update(data: any, collection: string, pk: string | string[], modelClass?: any): Promise<IModel>;
|
|
27
27
|
findOneBy(collection: string, conditions: any, fields?: string[] | null, ordering?: OrderByType, prismaOptions?: any): Promise<IModel | null>;
|
|
28
28
|
delete(collection: string, conditions: any): Promise<void>;
|
|
29
29
|
findBy(collection: string, conditions: any, fields?: string[] | null, ordering?: OrderByType, pagination?: IPaginationParams, prismaOptions?: any): Promise<IModel[]>;
|
|
@@ -35,6 +35,11 @@ declare class DBService {
|
|
|
35
35
|
count<T = any>(opModel: OpModelType<T>, where?: {
|
|
36
36
|
[k: string]: any;
|
|
37
37
|
}): Promise<number>;
|
|
38
|
+
/**
|
|
39
|
+
* Convert foreign key fields to Prisma relation syntax
|
|
40
|
+
* Dynamically reads relation metadata from model decorators
|
|
41
|
+
*/
|
|
42
|
+
private convertForeignKeysToRelations;
|
|
38
43
|
getPrismaClient(): PrismaClient;
|
|
39
44
|
}
|
|
40
45
|
export { DBService, IDBClientCreate };
|
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
@@ -101,7 +134,7 @@ class DBService {
|
|
|
101
134
|
result = await prismaCollection.create({ data });
|
|
102
135
|
return await this.findOneBy(collection, { id: result.id });
|
|
103
136
|
}
|
|
104
|
-
async update(data, collection, pk) {
|
|
137
|
+
async update(data, collection, pk, modelClass) {
|
|
105
138
|
const prismaCollection = this.getCollectionHandler(collection);
|
|
106
139
|
const where = {};
|
|
107
140
|
if (Array.isArray(pk)) {
|
|
@@ -120,9 +153,11 @@ class DBService {
|
|
|
120
153
|
delete data[cKey];
|
|
121
154
|
}
|
|
122
155
|
}
|
|
156
|
+
// Convert foreign key fields to Prisma relation syntax
|
|
157
|
+
const processedData = await this.convertForeignKeysToRelations(data, modelClass);
|
|
123
158
|
await prismaCollection.update({
|
|
124
159
|
where,
|
|
125
|
-
data:
|
|
160
|
+
data: processedData,
|
|
126
161
|
});
|
|
127
162
|
return await this.findOneBy(collection, where);
|
|
128
163
|
}
|
|
@@ -244,6 +279,57 @@ class DBService {
|
|
|
244
279
|
async count(opModel, where = {}) {
|
|
245
280
|
return await this.getCollectionHandler(opModel._collection).count({ where });
|
|
246
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* Convert foreign key fields to Prisma relation syntax
|
|
284
|
+
* Dynamically reads relation metadata from model decorators
|
|
285
|
+
*/
|
|
286
|
+
async convertForeignKeysToRelations(data, modelClass) {
|
|
287
|
+
const processedData = { ...data };
|
|
288
|
+
let relationMappings = {};
|
|
289
|
+
// If model class is provided, dynamically build relation mappings from metadata
|
|
290
|
+
if (modelClass) {
|
|
291
|
+
try {
|
|
292
|
+
const { ModelUtils } = await Promise.resolve().then(() => __importStar(require('../models/utils/ModelUtils')));
|
|
293
|
+
const modelAnnotations = await ModelUtils.getModelAnnotations(modelClass);
|
|
294
|
+
// Build relation mappings from the model's relation metadata
|
|
295
|
+
Object.keys(modelAnnotations).forEach(propertyKey => {
|
|
296
|
+
const annotation = modelAnnotations[propertyKey];
|
|
297
|
+
if (annotation.annotationType === 'Relation') {
|
|
298
|
+
const metadata = annotation.metadata;
|
|
299
|
+
const relationField = metadata.relationField;
|
|
300
|
+
const relationName = metadata.relationName || propertyKey;
|
|
301
|
+
if (relationField) {
|
|
302
|
+
relationMappings[relationField] = relationName;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
console.warn('Failed to read model relation metadata, falling back to static mappings:', error);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// Fallback to static mappings if no model class provided or metadata extraction fails
|
|
312
|
+
if (Object.keys(relationMappings).length === 0) {
|
|
313
|
+
relationMappings = {};
|
|
314
|
+
}
|
|
315
|
+
// Convert foreign key fields to relation syntax
|
|
316
|
+
Object.keys(processedData).forEach(key => {
|
|
317
|
+
if (key.endsWith('_id') && relationMappings[key]) {
|
|
318
|
+
const relationField = relationMappings[key];
|
|
319
|
+
const value = processedData[key];
|
|
320
|
+
// Remove the foreign key field
|
|
321
|
+
delete processedData[key];
|
|
322
|
+
// Add the relation field with proper Prisma syntax
|
|
323
|
+
if (value === null || value === undefined) {
|
|
324
|
+
processedData[relationField] = { disconnect: true };
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
processedData[relationField] = { connect: { id: value } };
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
return processedData;
|
|
332
|
+
}
|
|
247
333
|
getPrismaClient() {
|
|
248
334
|
if (!this.client || !this.connected) {
|
|
249
335
|
this.connectToDB();
|
package/package.json
CHANGED
|
@@ -279,7 +279,7 @@ class RWSModel<T> implements IModel {
|
|
|
279
279
|
|
|
280
280
|
const pk = ModelUtils.findPrimaryKeyFields(this.constructor as OpModelType<any>);
|
|
281
281
|
|
|
282
|
-
updatedModelData = await this.dbService.update(data, this.getCollection(), pk);
|
|
282
|
+
updatedModelData = await this.dbService.update(data, this.getCollection(), pk, this.constructor);
|
|
283
283
|
|
|
284
284
|
await this._asyncFill(updatedModelData);
|
|
285
285
|
await this.postUpdate();
|
|
@@ -138,7 +138,7 @@ class DBService {
|
|
|
138
138
|
return await this.findOneBy(collection, { id: result.id });
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
async update(data: any, collection: string, pk: string | string[]): Promise<IModel>
|
|
141
|
+
async update(data: any, collection: string, pk: string | string[], modelClass?: any): Promise<IModel>
|
|
142
142
|
{
|
|
143
143
|
|
|
144
144
|
const prismaCollection = this.getCollectionHandler(collection);
|
|
@@ -162,9 +162,12 @@ class DBService {
|
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
// Convert foreign key fields to Prisma relation syntax
|
|
166
|
+
const processedData = await this.convertForeignKeysToRelations(data, modelClass);
|
|
167
|
+
|
|
165
168
|
await prismaCollection.update({
|
|
166
169
|
where,
|
|
167
|
-
data:
|
|
170
|
+
data: processedData,
|
|
168
171
|
});
|
|
169
172
|
|
|
170
173
|
|
|
@@ -332,6 +335,65 @@ class DBService {
|
|
|
332
335
|
return await this.getCollectionHandler(opModel._collection).count({where});
|
|
333
336
|
}
|
|
334
337
|
|
|
338
|
+
/**
|
|
339
|
+
* Convert foreign key fields to Prisma relation syntax
|
|
340
|
+
* Dynamically reads relation metadata from model decorators
|
|
341
|
+
*/
|
|
342
|
+
private async convertForeignKeysToRelations(data: any, modelClass?: any): Promise<any> {
|
|
343
|
+
const processedData = { ...data };
|
|
344
|
+
let relationMappings: { [key: string]: string } = {};
|
|
345
|
+
|
|
346
|
+
// If model class is provided, dynamically build relation mappings from metadata
|
|
347
|
+
if (modelClass) {
|
|
348
|
+
try {
|
|
349
|
+
const { ModelUtils } = await import('../models/utils/ModelUtils');
|
|
350
|
+
const modelAnnotations = await ModelUtils.getModelAnnotations(modelClass);
|
|
351
|
+
|
|
352
|
+
// Build relation mappings from the model's relation metadata
|
|
353
|
+
Object.keys(modelAnnotations).forEach(propertyKey => {
|
|
354
|
+
const annotation = modelAnnotations[propertyKey];
|
|
355
|
+
if (annotation.annotationType === 'Relation') {
|
|
356
|
+
const metadata = annotation.metadata;
|
|
357
|
+
const relationField = metadata.relationField;
|
|
358
|
+
const relationName = metadata.relationName || propertyKey;
|
|
359
|
+
|
|
360
|
+
if (relationField) {
|
|
361
|
+
relationMappings[relationField] = relationName;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
} catch (error) {
|
|
366
|
+
console.warn('Failed to read model relation metadata, falling back to static mappings:', error);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Fallback to static mappings if no model class provided or metadata extraction fails
|
|
371
|
+
if (Object.keys(relationMappings).length === 0) {
|
|
372
|
+
relationMappings = {
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Convert foreign key fields to relation syntax
|
|
377
|
+
Object.keys(processedData).forEach(key => {
|
|
378
|
+
if (key.endsWith('_id') && relationMappings[key]) {
|
|
379
|
+
const relationField = relationMappings[key];
|
|
380
|
+
const value = processedData[key];
|
|
381
|
+
|
|
382
|
+
// Remove the foreign key field
|
|
383
|
+
delete processedData[key];
|
|
384
|
+
|
|
385
|
+
// Add the relation field with proper Prisma syntax
|
|
386
|
+
if (value === null || value === undefined) {
|
|
387
|
+
processedData[relationField] = { disconnect: true };
|
|
388
|
+
} else {
|
|
389
|
+
processedData[relationField] = { connect: { id: value } };
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
return processedData;
|
|
395
|
+
}
|
|
396
|
+
|
|
335
397
|
public getPrismaClient(): PrismaClient
|
|
336
398
|
{
|
|
337
399
|
if(!this.client || !this.connected){
|