@appxdigital/appx-core 0.1.100 → 0.1.102
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/dist/common/interceptors/prisma.interceptor.d.ts.map +1 -1
- package/dist/common/interceptors/prisma.interceptor.js +49 -39
- package/dist/common/utils/error-handler.d.ts.map +1 -1
- package/dist/common/utils/error-handler.js +2 -1
- package/dist/prisma/prisma.service.d.ts +4 -0
- package/dist/prisma/prisma.service.d.ts.map +1 -1
- package/dist/prisma/prisma.service.js +14 -8
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prisma.interceptor.d.ts","sourceRoot":"","sources":["../../../src/common/interceptors/prisma.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,gBAAgB,EAAc,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,
|
|
1
|
+
{"version":3,"file":"prisma.interceptor.d.ts","sourceRoot":"","sources":["../../../src/common/interceptors/prisma.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,gBAAgB,EAAc,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,EAAoB,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AACvC,OAAO,EAAC,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAG7C,OAAO,EAAC,UAAU,EAAa,MAAM,MAAM,CAAC;AAK5C,qBACa,iBAAkB,YAAW,eAAe;IAIjD,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,aAAa;IALzB,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;gBAG1B,aAAa,EAAE,aAAa,EACrC,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,aAAa;IAKxC,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC;CAoE3E"}
|
|
@@ -33,48 +33,58 @@ let PrismaInterceptor = class PrismaInterceptor {
|
|
|
33
33
|
: context.switchToHttp().getRequest(); // HTTP context
|
|
34
34
|
// Attach expose_models metadata if needed
|
|
35
35
|
const permissionMetadata = this.reflector.get(permission_decorator_1.PERMISSION_METADATA_KEY, context.getHandler()) || {};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
36
|
+
return new rxjs_1.Observable((observer) => {
|
|
37
|
+
prisma_service_1.CorePrismaContext.run({
|
|
38
|
+
exposedModels: permissionMetadata['expose_models'] || [],
|
|
39
|
+
}, () => {
|
|
40
|
+
const useTransaction = this.reflector.get('useTransaction', context.getHandler()) ?? this.defaultUseTransaction === 'true';
|
|
41
|
+
if (useTransaction) {
|
|
42
|
+
this.prismaService
|
|
43
|
+
.$transaction(async (transactionClient) => {
|
|
44
|
+
nestjs_request_context_1.RequestContext.currentContext.req.prisma = transactionClient;
|
|
45
|
+
await new Promise((resolve, reject) => {
|
|
46
|
+
next
|
|
47
|
+
.handle()
|
|
48
|
+
.pipe((0, operators_1.tap)(() => { }), (0, operators_1.catchError)((err) => {
|
|
49
|
+
const handledError = (0, error_handler_1.handleError)(err);
|
|
50
|
+
reject(handledError);
|
|
51
|
+
return (0, rxjs_1.throwError)(() => handledError);
|
|
52
|
+
}))
|
|
53
|
+
.subscribe({
|
|
54
|
+
next: (result) => observer.next(result),
|
|
55
|
+
complete: () => {
|
|
56
|
+
delete nestjs_request_context_1.RequestContext.currentContext.req.prisma;
|
|
57
|
+
observer.complete();
|
|
58
|
+
resolve(null);
|
|
59
|
+
},
|
|
60
|
+
error: (err) => {
|
|
61
|
+
delete nestjs_request_context_1.RequestContext.currentContext.req.prisma;
|
|
62
|
+
observer.error(err);
|
|
63
|
+
reject(err);
|
|
64
|
+
},
|
|
65
|
+
});
|
|
64
66
|
});
|
|
67
|
+
})
|
|
68
|
+
.catch((err) => {
|
|
69
|
+
delete nestjs_request_context_1.RequestContext.currentContext.req.prisma;
|
|
70
|
+
observer.error(err);
|
|
65
71
|
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
next.handle().pipe((0, operators_1.tap)(() => { }), (0, operators_1.catchError)((error) => {
|
|
75
|
+
return (0, rxjs_1.throwError)(() => (0, error_handler_1.handleError)(error));
|
|
76
|
+
})).subscribe({
|
|
77
|
+
next: (result) => observer.next(result),
|
|
78
|
+
complete: () => {
|
|
79
|
+
observer.complete();
|
|
80
|
+
},
|
|
81
|
+
error: (err) => {
|
|
82
|
+
observer.error(err);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
71
86
|
});
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
return next.handle().pipe((0, operators_1.tap)(() => { }), (0, operators_1.catchError)((error) => {
|
|
75
|
-
return (0, rxjs_1.throwError)(() => (0, error_handler_1.handleError)(error));
|
|
76
|
-
}));
|
|
77
|
-
}
|
|
87
|
+
});
|
|
78
88
|
}
|
|
79
89
|
};
|
|
80
90
|
exports.PrismaInterceptor = PrismaInterceptor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/common/utils/error-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/common/utils/error-handler.ts"],"names":[],"mappings":"AAKA,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,CAqC7C"}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.handleError = handleError;
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
5
|
const multer_1 = require("multer");
|
|
6
|
+
const logger = new common_1.Logger();
|
|
6
7
|
function handleError(error) {
|
|
7
8
|
// If it's already an HttpException, just rethrow it
|
|
8
9
|
if (error instanceof common_1.HttpException)
|
|
@@ -34,6 +35,6 @@ function handleError(error) {
|
|
|
34
35
|
throw new common_1.InternalServerErrorException('A Prisma database error occurred.', error.message);
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
logger.error(error);
|
|
38
39
|
throw new common_1.InternalServerErrorException(error.message || 'An unknown error occurred.');
|
|
39
40
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Prisma, PrismaClient } from '@prisma/client';
|
|
2
2
|
import { PermissionsConfigType } from '../common/config/permissionsConfigTypes';
|
|
3
3
|
import type { PrismaClient as RuntimeClient } from '.prisma/client';
|
|
4
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
5
|
+
export declare const CorePrismaContext: AsyncLocalStorage<{
|
|
6
|
+
exposedModels: string[];
|
|
7
|
+
}>;
|
|
4
8
|
type ModelKey = keyof RuntimeClient;
|
|
5
9
|
/** Extra options available on every model method */
|
|
6
10
|
export type CorePrismaOptions = {
|
|
@@ -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;
|
|
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;AAElE,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAEnD,eAAO,MAAM,iBAAiB;mBACX,MAAM,EAAE;EACvB,CAAC;AAEL,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;IAWjE,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;IAqDX;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAqC1B,IAAI,2BAA2B,QAM9B;IAED;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,oBAAoB;IA8K5B;;;;;;;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;QAC3B,UAAU,EAAE,OAAO,CAAA;KACtB;IAmBD,gBAAgB,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAgBzF"}
|
|
@@ -12,10 +12,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.PrismaService = void 0;
|
|
15
|
+
exports.PrismaService = exports.CorePrismaContext = void 0;
|
|
16
16
|
const common_1 = require("@nestjs/common");
|
|
17
17
|
const client_1 = require("@prisma/client");
|
|
18
18
|
const nestjs_request_context_1 = require("nestjs-request-context");
|
|
19
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
20
|
+
exports.CorePrismaContext = new node_async_hooks_1.AsyncLocalStorage();
|
|
19
21
|
let PrismaService = class PrismaService {
|
|
20
22
|
constructor(prismaClient, permissionsConfig) {
|
|
21
23
|
this.permissionsConfig = permissionsConfig;
|
|
@@ -31,10 +33,13 @@ let PrismaService = class PrismaService {
|
|
|
31
33
|
* Exposes the specified models for the duration of the callback execution.
|
|
32
34
|
*/
|
|
33
35
|
withExposedModels(models, callback) {
|
|
34
|
-
const previous =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
const previous = exports.CorePrismaContext.getStore()?.exposedModels || [];
|
|
37
|
+
return new Promise(async (resolve, reject) => {
|
|
38
|
+
exports.CorePrismaContext.run({
|
|
39
|
+
exposedModels: [...new Set([...previous, ...models.map(m => m.toLowerCase())])],
|
|
40
|
+
}, () => {
|
|
41
|
+
callback().then(resolve).catch(reject);
|
|
42
|
+
});
|
|
38
43
|
});
|
|
39
44
|
}
|
|
40
45
|
debug(msg, type = 'log') {
|
|
@@ -242,7 +247,8 @@ let PrismaService = class PrismaService {
|
|
|
242
247
|
const permissions = permissionsConfig[normalizedName]?.[userRole];
|
|
243
248
|
let actionPermissions;
|
|
244
249
|
// If model is exposed, permissions is ALL
|
|
245
|
-
|
|
250
|
+
const exposedModels = (exports.CorePrismaContext.getStore()?.exposedModels || []).map((m) => m.toLowerCase());
|
|
251
|
+
if (exposedModels.includes(modelName.toLowerCase())) {
|
|
246
252
|
actionPermissions = 'ALL';
|
|
247
253
|
}
|
|
248
254
|
else {
|
|
@@ -271,7 +277,7 @@ let PrismaService = class PrismaService {
|
|
|
271
277
|
// findFirst permissions for related model
|
|
272
278
|
const relatedPermissions = this.selectPermission(permissionsConfig[relation.model.toLowerCase()]?.[userRole] || {}, 'findFirst', relation.model, userRole);
|
|
273
279
|
// If model is exposed, do not apply conditions
|
|
274
|
-
if (
|
|
280
|
+
if (exposedModels.includes(relation.model.toLowerCase())) {
|
|
275
281
|
this.debug(`Related model '${relation.model}' is exposed via @Permission() decorator. Skipping conditions for action '${String(action)}' on role ${userRole}.`);
|
|
276
282
|
continue;
|
|
277
283
|
}
|
|
@@ -355,7 +361,7 @@ let PrismaService = class PrismaService {
|
|
|
355
361
|
}
|
|
356
362
|
}
|
|
357
363
|
// If model is exposed, do not apply conditions
|
|
358
|
-
if (
|
|
364
|
+
if (exposedModels.includes(modelName.toLowerCase())) {
|
|
359
365
|
this.debug(`Model '${modelName}' is exposed via @Permission() decorator. Skipping conditions for action '${String(action)}' on role ${userRole}.`);
|
|
360
366
|
return args;
|
|
361
367
|
}
|
package/package.json
CHANGED