@appxdigital/appx-core 0.1.97 → 0.1.99
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.
|
@@ -14,6 +14,7 @@ export declare class PrismaService {
|
|
|
14
14
|
prismaClient: PrismaClient;
|
|
15
15
|
constructor(prismaClient: PrismaClient, permissionsConfig: PermissionsConfigType);
|
|
16
16
|
debugQueries(enable: boolean): void;
|
|
17
|
+
withExposedModels(models: string[], callback: () => Promise<void>): Promise<void>;
|
|
17
18
|
private debug;
|
|
18
19
|
$transaction<T>(fn: (prisma: Prisma.TransactionClient) => Promise<T>): any;
|
|
19
20
|
proxyModels(): void;
|
|
@@ -90,6 +91,7 @@ export declare class PrismaService {
|
|
|
90
91
|
* @param modelName - The name of the model being queried.
|
|
91
92
|
* @param omitFields - A list of fields to omit based on the user's role.
|
|
92
93
|
* @param includeRelations - The relations to include in the query.
|
|
94
|
+
* @param defaultSelect - The select object provided in the query arguments.
|
|
93
95
|
* @param userRole - The role of the user making the request.
|
|
94
96
|
* @returns A `select` object for Prisma queries.
|
|
95
97
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prisma.service.d.ts","sourceRoot":"","sources":["../../src/prisma/prisma.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAE,YAAY,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,qBAAqB,EAAC,MAAM,yCAAyC,CAAC;AAE9E,OAAO,KAAK,EAAC,YAAY,IAAI,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAGlE,KAAK,QAAQ,GAAG,MAAM,aAAa,CAAC;AAEpC,oDAAoD;AACpD,MAAM,MAAM,iBAAiB,GAAG;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAGF,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,QAAQ,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,YAAY,GAAG,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAEtI,qBACa,aAAa;IAMY,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IALpE,OAAO,CAAC,YAAY,CAA2B;IAC/C,YAAY,EAAE,YAAY,CAAC;gBAGvB,YAAY,EAAE,YAAY,EACqB,iBAAiB,EAAE,qBAAqB;IAO3F,YAAY,CAAC,MAAM,EAAE,OAAO;
|
|
1
|
+
{"version":3,"file":"prisma.service.d.ts","sourceRoot":"","sources":["../../src/prisma/prisma.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAE,YAAY,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,qBAAqB,EAAC,MAAM,yCAAyC,CAAC;AAE9E,OAAO,KAAK,EAAC,YAAY,IAAI,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAGlE,KAAK,QAAQ,GAAG,MAAM,aAAa,CAAC;AAEpC,oDAAoD;AACpD,MAAM,MAAM,iBAAiB,GAAG;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAGF,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,QAAQ,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,YAAY,GAAG,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAEtI,qBACa,aAAa;IAMY,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IALpE,OAAO,CAAC,YAAY,CAA2B;IAC/C,YAAY,EAAE,YAAY,CAAC;gBAGvB,YAAY,EAAE,YAAY,EACqB,iBAAiB,EAAE,qBAAqB;IAO3F,YAAY,CAAC,MAAM,EAAE,OAAO;IAO5B,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC;IAQjE,OAAO,CAAC,KAAK;IAQb,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,iBAAiB,KAAK,OAAO,CAAC,CAAC,CAAC;IAIpE,WAAW;IAuDX;;;;OAIG;IACH,gBAAgB,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;IAYlE,IAAI,KAAK,IAAI,aAAa,CAUzB;IAED,IAAI,IAAI,IAAI,eAAe,CAAC,MAAM,CAAC,CAElC;IAED,IAAI,OAAO,IAAI,eAAe,CAAC,SAAS,CAAC,CAExC;IAED,IAAI,gBAAgB,QAEnB;IAED;;;OAGG;IACH,WAAW;IAoDX;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAqC1B,IAAI,2BAA2B,QAM9B;IAED;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,oBAAoB;IAmJ5B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAUvB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,iBAAiB;IA8EzB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,IAAI,GAAG;QAC5E,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC9B;IAkBD,gBAAgB,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAgBzF"}
|
|
@@ -27,6 +27,16 @@ let PrismaService = class PrismaService {
|
|
|
27
27
|
debugQueries(enable) {
|
|
28
28
|
nestjs_request_context_1.RequestContext.currentContext.req.corePrismaDebug = enable;
|
|
29
29
|
}
|
|
30
|
+
/*
|
|
31
|
+
* Exposes the specified models for the duration of the callback execution.
|
|
32
|
+
*/
|
|
33
|
+
withExposedModels(models, callback) {
|
|
34
|
+
const previous = nestjs_request_context_1.RequestContext.currentContext?.req.prismaExposedModels || [];
|
|
35
|
+
nestjs_request_context_1.RequestContext.currentContext.req.prismaExposedModels = [...new Set([...previous, ...models.map(m => m.toLowerCase())])];
|
|
36
|
+
return callback().finally(() => {
|
|
37
|
+
nestjs_request_context_1.RequestContext.currentContext.req.prismaExposedModels = previous;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
30
40
|
debug(msg, type = 'log') {
|
|
31
41
|
if (nestjs_request_context_1.RequestContext.currentContext?.req.corePrismaDebug) {
|
|
32
42
|
// Default for log, yellow for warn, red for error, blue for info
|
|
@@ -194,11 +204,11 @@ let PrismaService = class PrismaService {
|
|
|
194
204
|
}
|
|
195
205
|
else if (args.include) {
|
|
196
206
|
this.debug(`Found included model '${modelName}', generating select fields`);
|
|
197
|
-
args.select = this.buildSelectFields(modelName, omitFields, args.include, userRole);
|
|
207
|
+
args.select = this.buildSelectFields(modelName, omitFields, args.include, null, userRole);
|
|
198
208
|
delete args.include;
|
|
199
209
|
}
|
|
200
210
|
else {
|
|
201
|
-
args.select = this.buildSelectFields(modelName, omitFields, null, userRole);
|
|
211
|
+
args.select = this.buildSelectFields(modelName, omitFields, null, null, userRole);
|
|
202
212
|
}
|
|
203
213
|
return args;
|
|
204
214
|
}
|
|
@@ -249,11 +259,16 @@ let PrismaService = class PrismaService {
|
|
|
249
259
|
// If field is relation
|
|
250
260
|
let relation = this.getRelation(modelName, field);
|
|
251
261
|
if (!relation) {
|
|
262
|
+
if (field === '_count') {
|
|
263
|
+
// TODO implement filtering on _count
|
|
264
|
+
// args.select[field] = this.applyWhereConditions(modelName, userRole, args.select[field], user, action);
|
|
265
|
+
}
|
|
252
266
|
continue;
|
|
253
267
|
}
|
|
254
268
|
if (relation.relation === 'belongsTo') {
|
|
255
269
|
this.debug(`Found 1:1 / *:1 (belongsTo) relation to model '${relation.model}' from model '${modelName}' via field '${field}'. Filter will be applied to main conditions...`);
|
|
256
|
-
|
|
270
|
+
// findFirst permissions for related model
|
|
271
|
+
const relatedPermissions = this.selectPermission(permissionsConfig[relation.model.toLowerCase()]?.[userRole] || {}, 'findFirst', relation.model, userRole);
|
|
257
272
|
// If model is exposed, do not apply conditions
|
|
258
273
|
if (nestjs_request_context_1.RequestContext.currentContext?.req.prismaExposedModels?.map((m) => m.toLowerCase()).includes(relation.model.toLowerCase())) {
|
|
259
274
|
this.debug(`Related model '${relation.model}' is exposed via @Permission() decorator. Skipping conditions for action '${String(action)}' on role ${userRole}.`);
|
|
@@ -289,7 +304,11 @@ let PrismaService = class PrismaService {
|
|
|
289
304
|
},
|
|
290
305
|
})
|
|
291
306
|
*/
|
|
292
|
-
|
|
307
|
+
if (args.select[field] === true) {
|
|
308
|
+
args.select[field] = {};
|
|
309
|
+
}
|
|
310
|
+
// findMany permissions for related model
|
|
311
|
+
args.select[field].where = this.applyWhereConditions(relation.model, userRole, args.select[field], user, 'findMany').where;
|
|
293
312
|
delete args.select[field].select.where;
|
|
294
313
|
}
|
|
295
314
|
}
|
|
@@ -400,16 +419,30 @@ let PrismaService = class PrismaService {
|
|
|
400
419
|
* @param modelName - The name of the model being queried.
|
|
401
420
|
* @param omitFields - A list of fields to omit based on the user's role.
|
|
402
421
|
* @param includeRelations - The relations to include in the query.
|
|
422
|
+
* @param defaultSelect - The select object provided in the query arguments.
|
|
403
423
|
* @param userRole - The role of the user making the request.
|
|
404
424
|
* @returns A `select` object for Prisma queries.
|
|
405
425
|
*/
|
|
406
|
-
buildSelectFields(modelName, omitFields, includeRelations, userRole) {
|
|
426
|
+
buildSelectFields(modelName, omitFields, includeRelations, defaultSelect, userRole) {
|
|
407
427
|
const modelInfo = this.fieldConfigs[modelName.toLowerCase()];
|
|
408
428
|
if (!modelInfo) {
|
|
409
429
|
return {};
|
|
410
430
|
}
|
|
411
|
-
|
|
431
|
+
let { scalarFields, relationFields } = modelInfo;
|
|
412
432
|
const selectFields = {};
|
|
433
|
+
// If defaultSelect is provided, only include those fields
|
|
434
|
+
if (defaultSelect) {
|
|
435
|
+
// Use default select but separate scalar and relation fields. If not in any, consider relation
|
|
436
|
+
scalarFields = Object.keys(defaultSelect).filter((field) => modelInfo.scalarFields.includes(field));
|
|
437
|
+
relationFields = Object.keys(defaultSelect).filter((field) => !modelInfo.scalarFields.includes(field) || field === '_count').reduce((acc, field) => {
|
|
438
|
+
acc[field] = defaultSelect[field];
|
|
439
|
+
return acc;
|
|
440
|
+
}, {});
|
|
441
|
+
// Merge with includeRelations if any
|
|
442
|
+
if (Object.keys(relationFields).length > 0) {
|
|
443
|
+
includeRelations = { ...(includeRelations || {}), ...relationFields };
|
|
444
|
+
}
|
|
445
|
+
}
|
|
413
446
|
for (const field of scalarFields) {
|
|
414
447
|
if (!omitFields.includes(field)) {
|
|
415
448
|
selectFields[field] = true;
|
|
@@ -417,16 +450,27 @@ let PrismaService = class PrismaService {
|
|
|
417
450
|
}
|
|
418
451
|
if (includeRelations) {
|
|
419
452
|
for (const relationKey in includeRelations) {
|
|
420
|
-
if (!relationFields[relationKey])
|
|
453
|
+
if (!relationFields[relationKey] && relationKey !== '_count')
|
|
421
454
|
continue;
|
|
422
455
|
let includedArgs = includeRelations[relationKey];
|
|
423
456
|
if (includedArgs === true) {
|
|
424
457
|
includedArgs = {};
|
|
425
458
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
459
|
+
let relatedSelectFields = {};
|
|
460
|
+
if (relationKey === '_count') {
|
|
461
|
+
if (includedArgs.select) {
|
|
462
|
+
relatedSelectFields = includedArgs.select;
|
|
463
|
+
omitFields.forEach((field) => {
|
|
464
|
+
delete relatedSelectFields[field];
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
const relatedModelName = this.getRelation(modelName, relationKey, true).model;
|
|
470
|
+
this.debug(`Found relation to model '${relatedModelName}' from model '${modelName}' via field '${relationKey}'. Generating select fields...`);
|
|
471
|
+
const relatedModelOmitFields = this.getFieldsToOmit(relatedModelName, userRole);
|
|
472
|
+
relatedSelectFields = this.buildSelectFields(relatedModelName, relatedModelOmitFields, includedArgs.include || null, includedArgs.select || null, userRole);
|
|
473
|
+
}
|
|
430
474
|
if (Object.keys(relatedSelectFields).length > 0) {
|
|
431
475
|
selectFields[relationKey] = { select: relatedSelectFields };
|
|
432
476
|
}
|
package/package.json
CHANGED