@zenstackhq/runtime 1.0.0-beta.20 → 1.0.0-beta.21

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/constants.d.ts CHANGED
@@ -2,18 +2,6 @@
2
2
  * Default length of password hash salt (used by bcryptjs to hash password)
3
3
  */
4
4
  export declare const DEFAULT_PASSWORD_SALT_LENGTH = 12;
5
- /**
6
- * Auxiliary database field for supporting policy check for nested writes
7
- */
8
- export declare const TRANSACTION_FIELD_NAME = "zenstack_transaction";
9
- /**
10
- * Auxiliary database field for building up policy check queries
11
- */
12
- export declare const GUARD_FIELD_NAME = "zenstack_guard";
13
- /**
14
- * All Auxiliary fields.
15
- */
16
- export declare const AUXILIARY_FIELDS: string[];
17
5
  /**
18
6
  * Reasons for a CRUD operation to fail
19
7
  */
package/constants.js CHANGED
@@ -1,22 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HAS_FIELD_LEVEL_POLICY_FLAG = exports.FIELD_LEVEL_UPDATE_GUARD_PREFIX = exports.FIELD_LEVEL_READ_CHECKER_SELECTOR = exports.FIELD_LEVEL_READ_CHECKER_PREFIX = exports.PRE_UPDATE_VALUE_SELECTOR = exports.PRISMA_MINIMUM_VERSION = exports.PRISMA_PROXY_ENHANCER = exports.PRISMA_TX_FLAG = exports.PrismaErrorCode = exports.CrudFailureReason = exports.AUXILIARY_FIELDS = exports.GUARD_FIELD_NAME = exports.TRANSACTION_FIELD_NAME = exports.DEFAULT_PASSWORD_SALT_LENGTH = void 0;
3
+ exports.HAS_FIELD_LEVEL_POLICY_FLAG = exports.FIELD_LEVEL_UPDATE_GUARD_PREFIX = exports.FIELD_LEVEL_READ_CHECKER_SELECTOR = exports.FIELD_LEVEL_READ_CHECKER_PREFIX = exports.PRE_UPDATE_VALUE_SELECTOR = exports.PRISMA_MINIMUM_VERSION = exports.PRISMA_PROXY_ENHANCER = exports.PRISMA_TX_FLAG = exports.PrismaErrorCode = exports.CrudFailureReason = exports.DEFAULT_PASSWORD_SALT_LENGTH = void 0;
4
4
  /**
5
5
  * Default length of password hash salt (used by bcryptjs to hash password)
6
6
  */
7
7
  exports.DEFAULT_PASSWORD_SALT_LENGTH = 12;
8
- /**
9
- * Auxiliary database field for supporting policy check for nested writes
10
- */
11
- exports.TRANSACTION_FIELD_NAME = 'zenstack_transaction';
12
- /**
13
- * Auxiliary database field for building up policy check queries
14
- */
15
- exports.GUARD_FIELD_NAME = 'zenstack_guard';
16
- /**
17
- * All Auxiliary fields.
18
- */
19
- exports.AUXILIARY_FIELDS = [exports.TRANSACTION_FIELD_NAME, exports.GUARD_FIELD_NAME];
20
8
  /**
21
9
  * Reasons for a CRUD operation to fail
22
10
  */
package/constants.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,4BAA4B,GAAG,EAAE,CAAC;AAE/C;;GAEG;AACU,QAAA,sBAAsB,GAAG,sBAAsB,CAAC;AAE7D;;GAEG;AACU,QAAA,gBAAgB,GAAG,gBAAgB,CAAC;AAEjD;;GAEG;AACU,QAAA,gBAAgB,GAAG,CAAC,8BAAsB,EAAE,wBAAgB,CAAC,CAAC;AAE3E;;GAEG;AACH,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IACzB;;OAEG;IACH,gEAA2C,CAAA;IAE3C;;OAEG;IACH,4EAAuD,CAAA;AAC3D,CAAC,EAVW,iBAAiB,GAAjB,yBAAiB,KAAjB,yBAAiB,QAU5B;AAED;;GAEG;AACH,IAAY,eAoBX;AApBD,WAAY,eAAe;IACvB;;OAEG;IACH,qDAAkC,CAAA;IAElC;;OAEG;IACH,+CAA4B,CAAA;IAE5B;;OAEG;IACH,gEAA6C,CAAA;IAE7C;;OAEG;IACH,uDAAoC,CAAA;AACxC,CAAC,EApBW,eAAe,GAAf,uBAAe,KAAf,uBAAe,QAoB1B;AAED;;GAEG;AACU,QAAA,cAAc,GAAG,gBAAgB,CAAC;AAE/C;;GAEG;AACU,QAAA,qBAAqB,GAAG,sBAAsB,CAAC;AAE5D;;GAEG;AACU,QAAA,sBAAsB,GAAG,OAAO,CAAC;AAE9C;;GAEG;AACU,QAAA,yBAAyB,GAAG,gBAAgB,CAAC;AAE1D;;GAEG;AACU,QAAA,+BAA+B,GAAG,iBAAiB,CAAC;AAEjE;;GAEG;AACU,QAAA,iCAAiC,GAAG,iBAAiB,CAAC;AAEnE;;GAEG;AACU,QAAA,+BAA+B,GAAG,mBAAmB,CAAC;AAEnE;;GAEG;AACU,QAAA,2BAA2B,GAAG,qBAAqB,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,4BAA4B,GAAG,EAAE,CAAC;AAE/C;;GAEG;AACH,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IACzB;;OAEG;IACH,gEAA2C,CAAA;IAE3C;;OAEG;IACH,4EAAuD,CAAA;AAC3D,CAAC,EAVW,iBAAiB,GAAjB,yBAAiB,KAAjB,yBAAiB,QAU5B;AAED;;GAEG;AACH,IAAY,eAoBX;AApBD,WAAY,eAAe;IACvB;;OAEG;IACH,qDAAkC,CAAA;IAElC;;OAEG;IACH,+CAA4B,CAAA;IAE5B;;OAEG;IACH,gEAA6C,CAAA;IAE7C;;OAEG;IACH,uDAAoC,CAAA;AACxC,CAAC,EApBW,eAAe,GAAf,uBAAe,KAAf,uBAAe,QAoB1B;AAED;;GAEG;AACU,QAAA,cAAc,GAAG,gBAAgB,CAAC;AAE/C;;GAEG;AACU,QAAA,qBAAqB,GAAG,sBAAsB,CAAC;AAE5D;;GAEG;AACU,QAAA,sBAAsB,GAAG,OAAO,CAAC;AAE9C;;GAEG;AACU,QAAA,yBAAyB,GAAG,gBAAgB,CAAC;AAE1D;;GAEG;AACU,QAAA,+BAA+B,GAAG,iBAAiB,CAAC;AAEjE;;GAEG;AACU,QAAA,iCAAiC,GAAG,iBAAiB,CAAC;AAEnE;;GAEG;AACU,QAAA,+BAA+B,GAAG,mBAAmB,CAAC;AAEnE;;GAEG;AACU,QAAA,2BAA2B,GAAG,qBAAqB,CAAC"}
@@ -9,18 +9,22 @@ export declare class PolicyProxyHandler<DbClient extends DbClientContract> imple
9
9
  private readonly policy;
10
10
  private readonly modelMeta;
11
11
  private readonly zodSchemas;
12
- private readonly model;
13
12
  private readonly user?;
14
13
  private readonly logPrismaQuery?;
15
14
  private readonly logger;
16
15
  private readonly utils;
16
+ private readonly model;
17
17
  constructor(prisma: DbClient, policy: PolicyDef, modelMeta: ModelMeta, zodSchemas: ZodSchemas | undefined, model: string, user?: AuthUser | undefined, logPrismaQuery?: boolean | undefined);
18
18
  private get modelClient();
19
19
  findUnique(args: any): Promise<unknown>;
20
20
  findUniqueOrThrow(args: any): Promise<unknown>;
21
- findFirst(args: any): Promise<unknown>;
21
+ findFirst(args?: any): Promise<unknown>;
22
22
  findFirstOrThrow(args: any): Promise<unknown>;
23
- findMany(args: any): Promise<unknown[]>;
23
+ findMany(args?: any): Promise<unknown[]>;
24
+ private findWithFluentCallStubs;
25
+ private doFind;
26
+ private fluentCall;
27
+ private addFluentFunctions;
24
28
  create(args: any): Promise<any>;
25
29
  private doCreate;
26
30
  private hasNestedCreateOrConnect;
@@ -38,11 +42,13 @@ export declare class PolicyProxyHandler<DbClient extends DbClientContract> imple
38
42
  deleteMany(args: any): Promise<{
39
43
  count: number;
40
44
  }>;
41
- aggregate(args: any): Promise<unknown>;
42
- groupBy(args: any): Promise<unknown>;
43
- count(args: any): Promise<unknown>;
44
- subscribe(args: any): Promise<unknown>;
45
+ aggregate(args: any): Promise<any>;
46
+ groupBy(args: any): Promise<any>;
47
+ count(args: any): Promise<any>;
48
+ subscribe(args: any): Promise<any>;
45
49
  private get shouldLogQuery();
46
50
  private transaction;
47
51
  private runPostWriteChecks;
52
+ private makeHandler;
53
+ private requireBackLink;
48
54
  }
@@ -22,6 +22,7 @@ var __rest = (this && this.__rest) || function (s, e) {
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.PolicyProxyHandler = void 0;
25
+ const lower_case_first_1 = require("lower-case-first");
25
26
  const upper_case_first_1 = require("upper-case-first");
26
27
  const zod_validation_error_1 = require("zod-validation-error");
27
28
  const constants_1 = require("../../constants");
@@ -31,6 +32,7 @@ const nested_write_vistor_1 = require("../nested-write-vistor");
31
32
  const utils_1 = require("../utils");
32
33
  const logger_1 = require("./logger");
33
34
  const policy_utils_1 = require("./policy-utils");
35
+ const promise_1 = require("./promise");
34
36
  /**
35
37
  * Prisma proxy handler for injecting access policy check.
36
38
  */
@@ -40,11 +42,11 @@ class PolicyProxyHandler {
40
42
  this.policy = policy;
41
43
  this.modelMeta = modelMeta;
42
44
  this.zodSchemas = zodSchemas;
43
- this.model = model;
44
45
  this.user = user;
45
46
  this.logPrismaQuery = logPrismaQuery;
46
47
  this.logger = new logger_1.Logger(prisma);
47
48
  this.utils = new policy_utils_1.PolicyUtil(this.prisma, this.modelMeta, this.policy, this.zodSchemas, this.user, this.shouldLogQuery);
49
+ this.model = (0, lower_case_first_1.lowerCaseFirst)(model);
48
50
  }
49
51
  get modelClient() {
50
52
  return this.prisma[this.model];
@@ -52,96 +54,111 @@ class PolicyProxyHandler {
52
54
  //#region Find
53
55
  // find operations behaves as if the entities that don't match access policies don't exist
54
56
  findUnique(args) {
55
- return __awaiter(this, void 0, void 0, function* () {
56
- if (!args) {
57
- throw (0, utils_1.prismaClientValidationError)(this.prisma, 'query argument is required');
58
- }
59
- if (!args.where) {
60
- throw (0, utils_1.prismaClientValidationError)(this.prisma, 'where field is required in query argument');
61
- }
62
- const origArgs = args;
63
- args = this.utils.clone(args);
64
- if (!(yield this.utils.injectForRead(this.prisma, this.model, args))) {
65
- return null;
66
- }
67
- this.utils.injectReadCheckSelect(this.model, args);
68
- if (this.shouldLogQuery) {
69
- this.logger.info(`[policy] \`findUnique\` ${this.model}:\n${(0, utils_1.formatObject)(args)}`);
70
- }
71
- const result = yield this.modelClient.findUnique(args);
72
- this.utils.postProcessForRead(result, this.model, origArgs);
73
- return result;
74
- });
57
+ if (!args) {
58
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, 'query argument is required');
59
+ }
60
+ if (!args.where) {
61
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, 'where field is required in query argument');
62
+ }
63
+ return this.findWithFluentCallStubs(args, 'findUnique', false, () => null);
75
64
  }
76
65
  findUniqueOrThrow(args) {
77
- return __awaiter(this, void 0, void 0, function* () {
78
- if (!args) {
79
- throw (0, utils_1.prismaClientValidationError)(this.prisma, 'query argument is required');
80
- }
81
- if (!args.where) {
82
- throw (0, utils_1.prismaClientValidationError)(this.prisma, 'where field is required in query argument');
83
- }
84
- const origArgs = args;
85
- args = this.utils.clone(args);
86
- if (!(yield this.utils.injectForRead(this.prisma, this.model, args))) {
87
- throw this.utils.notFound(this.model);
88
- }
89
- this.utils.injectReadCheckSelect(this.model, args);
90
- if (this.shouldLogQuery) {
91
- this.logger.info(`[policy] \`findUniqueOrThrow\` ${this.model}:\n${(0, utils_1.formatObject)(args)}`);
92
- }
93
- const result = yield this.modelClient.findUniqueOrThrow(args);
94
- this.utils.postProcessForRead(result, this.model, origArgs);
95
- return result;
66
+ if (!args) {
67
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, 'query argument is required');
68
+ }
69
+ if (!args.where) {
70
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, 'where field is required in query argument');
71
+ }
72
+ return this.findWithFluentCallStubs(args, 'findUniqueOrThrow', true, () => {
73
+ throw this.utils.notFound(this.model);
96
74
  });
97
75
  }
98
76
  findFirst(args) {
99
- return __awaiter(this, void 0, void 0, function* () {
100
- const origArgs = args;
101
- args = args ? this.utils.clone(args) : {};
102
- if (!(yield this.utils.injectForRead(this.prisma, this.model, args))) {
103
- return null;
104
- }
105
- this.utils.injectReadCheckSelect(this.model, args);
106
- if (this.shouldLogQuery) {
107
- this.logger.info(`[policy] \`findFirst\` ${this.model}:\n${(0, utils_1.formatObject)(args)}`);
108
- }
109
- const result = yield this.modelClient.findFirst(args);
110
- this.utils.postProcessForRead(result, this.model, origArgs);
111
- return result;
112
- });
77
+ return this.findWithFluentCallStubs(args, 'findFirst', false, () => null);
113
78
  }
114
79
  findFirstOrThrow(args) {
115
- return __awaiter(this, void 0, void 0, function* () {
116
- const origArgs = args;
117
- args = args ? this.utils.clone(args) : {};
118
- if (!(yield this.utils.injectForRead(this.prisma, this.model, args))) {
119
- throw this.utils.notFound(this.model);
120
- }
121
- this.utils.injectReadCheckSelect(this.model, args);
122
- if (this.shouldLogQuery) {
123
- this.logger.info(`[policy] \`findFirstOrThrow\` ${this.model}:\n${(0, utils_1.formatObject)(args)}`);
124
- }
125
- const result = yield this.modelClient.findFirstOrThrow(args);
126
- this.utils.postProcessForRead(result, this.model, origArgs);
127
- return result;
80
+ return this.findWithFluentCallStubs(args, 'findFirstOrThrow', true, () => {
81
+ throw this.utils.notFound(this.model);
128
82
  });
129
83
  }
130
84
  findMany(args) {
131
- return __awaiter(this, void 0, void 0, function* () {
132
- const origArgs = args;
133
- args = args ? this.utils.clone(args) : {};
134
- if (!(yield this.utils.injectForRead(this.prisma, this.model, args))) {
135
- return [];
85
+ return (0, promise_1.createDeferredPromise)(() => this.doFind(args, 'findMany', () => []));
86
+ }
87
+ // returns a promise for the given find operation, together with function stubs for fluent API calls
88
+ findWithFluentCallStubs(args, actionName, resolveRoot, handleRejection) {
89
+ // create a deferred promise so it's only evaluated when awaited or .then() is called
90
+ const result = (0, promise_1.createDeferredPromise)(() => this.doFind(args, actionName, handleRejection));
91
+ this.addFluentFunctions(result, this.model, args === null || args === void 0 ? void 0 : args.where, resolveRoot ? result : undefined);
92
+ return result;
93
+ }
94
+ doFind(args, actionName, handleRejection) {
95
+ const origArgs = args;
96
+ const _args = this.utils.clone(args);
97
+ if (!this.utils.injectForRead(this.prisma, this.model, _args)) {
98
+ return handleRejection();
99
+ }
100
+ this.utils.injectReadCheckSelect(this.model, _args);
101
+ if (this.shouldLogQuery) {
102
+ this.logger.info(`[policy] \`${actionName}\` ${this.model}:\n${(0, utils_1.formatObject)(_args)}`);
103
+ }
104
+ return new Promise((resolve, reject) => {
105
+ this.modelClient[actionName](_args).then((value) => {
106
+ this.utils.postProcessForRead(value, this.model, origArgs);
107
+ resolve(value);
108
+ }, (err) => reject(err));
109
+ });
110
+ }
111
+ // returns a fluent API call function
112
+ fluentCall(filter, fieldInfo, rootPromise) {
113
+ return (args) => {
114
+ args = this.utils.clone(args);
115
+ // combine the parent filter with the current one
116
+ const backLinkField = this.requireBackLink(fieldInfo);
117
+ const condition = backLinkField.isArray
118
+ ? { [backLinkField.name]: { some: filter } }
119
+ : { [backLinkField.name]: { is: filter } };
120
+ args.where = this.utils.and(args.where, condition);
121
+ const promise = (0, promise_1.createDeferredPromise)(() => {
122
+ // Promise for fetching
123
+ const fetchFluent = (resolve, reject) => {
124
+ const handler = this.makeHandler(fieldInfo.type);
125
+ if (fieldInfo.isArray) {
126
+ // fluent call stops here
127
+ handler.findMany(args).then((value) => resolve(value), (err) => reject(err));
128
+ }
129
+ else {
130
+ handler.findFirst(args).then((value) => resolve(value), (err) => reject(err));
131
+ }
132
+ };
133
+ return new Promise((resolve, reject) => {
134
+ if (rootPromise) {
135
+ // if a root promise exists, resolve it before fluent API call,
136
+ // so that fluent calls start with `findUniqueOrThrow` and `findFirstOrThrow`
137
+ // can throw error properly if the root promise is rejected
138
+ rootPromise.then(() => fetchFluent(resolve, reject), (err) => reject(err));
139
+ }
140
+ else {
141
+ fetchFluent(resolve, reject);
142
+ }
143
+ });
144
+ });
145
+ if (!fieldInfo.isArray) {
146
+ // prepare for a chained fluent API call
147
+ this.addFluentFunctions(promise, fieldInfo.type, args.where, rootPromise);
136
148
  }
137
- this.utils.injectReadCheckSelect(this.model, args);
138
- if (this.shouldLogQuery) {
139
- this.logger.info(`[policy] \`findMany\` ${this.model}:\n${(0, utils_1.formatObject)(args)}`);
149
+ return promise;
150
+ };
151
+ }
152
+ // add fluent API functions to the given promise
153
+ addFluentFunctions(promise, model, filter, rootPromise) {
154
+ const fields = this.utils.getModelFields(model);
155
+ if (fields) {
156
+ for (const [field, fieldInfo] of Object.entries(fields)) {
157
+ if (fieldInfo.isDataModel) {
158
+ promise[field] = this.fluentCall(filter, fieldInfo, rootPromise);
159
+ }
140
160
  }
141
- const result = yield this.modelClient.findMany(args);
142
- this.utils.postProcessForRead(result, this.model, origArgs);
143
- return result;
144
- });
161
+ }
145
162
  }
146
163
  //#endregion
147
164
  //#region Create
@@ -153,7 +170,7 @@ class PolicyProxyHandler {
153
170
  if (!args.data) {
154
171
  throw (0, utils_1.prismaClientValidationError)(this.prisma, 'data field is required in query argument');
155
172
  }
156
- yield this.utils.tryReject(this.prisma, this.model, 'create');
173
+ this.utils.tryReject(this.prisma, this.model, 'create');
157
174
  const origArgs = args;
158
175
  args = this.utils.clone(args);
159
176
  // static input policy check for top-level create data
@@ -517,7 +534,7 @@ class PolicyProxyHandler {
517
534
  let createData = args;
518
535
  if ((_a = context.field) === null || _a === void 0 ? void 0 : _a.backLink) {
519
536
  // handles the connection to upstream entity
520
- const reversedQuery = yield this.utils.buildReversedQuery(context);
537
+ const reversedQuery = this.utils.buildReversedQuery(context);
521
538
  if (reversedQuery[context.field.backLink]) {
522
539
  // the built reverse query contains a condition for the backlink field, build a "connect" with it
523
540
  createData = Object.assign(Object.assign({}, createData), { [context.field.backLink]: {
@@ -537,7 +554,7 @@ class PolicyProxyHandler {
537
554
  var _b;
538
555
  if ((_b = context.field) === null || _b === void 0 ? void 0 : _b.backLink) {
539
556
  // handles the connection to upstream entity
540
- const reversedQuery = yield this.utils.buildReversedQuery(context);
557
+ const reversedQuery = this.utils.buildReversedQuery(context);
541
558
  for (const item of (0, utils_1.enumerate)(args.data)) {
542
559
  Object.assign(item, reversedQuery);
543
560
  }
@@ -563,7 +580,7 @@ class PolicyProxyHandler {
563
580
  update: (model, args, context) => __awaiter(this, void 0, void 0, function* () {
564
581
  var _d;
565
582
  // build a unique query including upstream conditions
566
- const uniqueFilter = yield this.utils.buildReversedQuery(context);
583
+ const uniqueFilter = this.utils.buildReversedQuery(context);
567
584
  // handle not-found
568
585
  const existing = yield this.utils.checkExistence(db, model, uniqueFilter, true);
569
586
  // check if the update actually writes to this model
@@ -606,7 +623,7 @@ class PolicyProxyHandler {
606
623
  }),
607
624
  updateMany: (model, args, context) => __awaiter(this, void 0, void 0, function* () {
608
625
  // injects auth guard into where clause
609
- yield this.utils.injectAuthGuard(db, args, model, 'update');
626
+ this.utils.injectAuthGuard(db, args, model, 'update');
610
627
  // prepare for post-update check
611
628
  if (this.utils.hasAuthGuard(model, 'postUpdate') || this.utils.getZodSchema(model)) {
612
629
  let select = this.utils.makeIdSelection(model);
@@ -614,9 +631,9 @@ class PolicyProxyHandler {
614
631
  if (preValueSelect) {
615
632
  select = Object.assign(Object.assign({}, select), preValueSelect);
616
633
  }
617
- const reversedQuery = yield this.utils.buildReversedQuery(context);
634
+ const reversedQuery = this.utils.buildReversedQuery(context);
618
635
  const currentSetQuery = { select, where: reversedQuery };
619
- yield this.utils.injectAuthGuard(db, currentSetQuery, model, 'read');
636
+ this.utils.injectAuthGuard(db, currentSetQuery, model, 'read');
620
637
  if (this.shouldLogQuery) {
621
638
  this.logger.info(`[policy] \`findMany\` ${model}:\n${(0, utils_1.formatObject)(currentSetQuery)}`);
622
639
  }
@@ -647,7 +664,7 @@ class PolicyProxyHandler {
647
664
  }),
648
665
  upsert: (model, args, context) => __awaiter(this, void 0, void 0, function* () {
649
666
  // build a unique query including upstream conditions
650
- const uniqueFilter = yield this.utils.buildReversedQuery(context);
667
+ const uniqueFilter = this.utils.buildReversedQuery(context);
651
668
  // branch based on if the update target exists
652
669
  const existing = yield this.utils.checkExistence(db, model, uniqueFilter);
653
670
  if (existing) {
@@ -688,7 +705,7 @@ class PolicyProxyHandler {
688
705
  disconnect: (model, args, context) => __awaiter(this, void 0, void 0, function* () { return _connectDisconnect(model, args, context); }),
689
706
  set: (model, args, context) => __awaiter(this, void 0, void 0, function* () {
690
707
  // find the set of items to be replaced
691
- const reversedQuery = yield this.utils.buildReversedQuery(context);
708
+ const reversedQuery = this.utils.buildReversedQuery(context);
692
709
  const findCurrSetArgs = {
693
710
  select: this.utils.makeIdSelection(model),
694
711
  where: reversedQuery,
@@ -704,7 +721,7 @@ class PolicyProxyHandler {
704
721
  }),
705
722
  delete: (model, args, context) => __awaiter(this, void 0, void 0, function* () {
706
723
  // build a unique query including upstream conditions
707
- const uniqueFilter = yield this.utils.buildReversedQuery(context);
724
+ const uniqueFilter = this.utils.buildReversedQuery(context);
708
725
  // handle not-found
709
726
  yield this.utils.checkExistence(db, model, uniqueFilter, true);
710
727
  // check delete guard
@@ -737,9 +754,9 @@ class PolicyProxyHandler {
737
754
  if (!args.data) {
738
755
  throw (0, utils_1.prismaClientValidationError)(this.prisma, 'data field is required in query argument');
739
756
  }
740
- yield this.utils.tryReject(this.prisma, this.model, 'update');
757
+ this.utils.tryReject(this.prisma, this.model, 'update');
741
758
  args = this.utils.clone(args);
742
- yield this.utils.injectAuthGuard(this.prisma, args, this.model, 'update');
759
+ this.utils.injectAuthGuard(this.prisma, args, this.model, 'update');
743
760
  if (this.utils.hasAuthGuard(this.model, 'postUpdate') || this.utils.getZodSchema(this.model)) {
744
761
  // use a transaction to do post-update checks
745
762
  const postWriteChecks = [];
@@ -751,7 +768,7 @@ class PolicyProxyHandler {
751
768
  select = Object.assign(Object.assign({}, select), preValueSelect);
752
769
  }
753
770
  const currentSetQuery = { select, where: args.where };
754
- yield this.utils.injectAuthGuard(tx, currentSetQuery, this.model, 'read');
771
+ this.utils.injectAuthGuard(tx, currentSetQuery, this.model, 'read');
755
772
  if (this.shouldLogQuery) {
756
773
  this.logger.info(`[policy] \`findMany\` ${this.model}: ${(0, utils_1.formatObject)(currentSetQuery)}`);
757
774
  }
@@ -792,8 +809,8 @@ class PolicyProxyHandler {
792
809
  if (!args.update) {
793
810
  throw (0, utils_1.prismaClientValidationError)(this.prisma, 'update field is required in query argument');
794
811
  }
795
- yield this.utils.tryReject(this.prisma, this.model, 'create');
796
- yield this.utils.tryReject(this.prisma, this.model, 'update');
812
+ this.utils.tryReject(this.prisma, this.model, 'create');
813
+ this.utils.tryReject(this.prisma, this.model, 'update');
797
814
  args = this.utils.clone(args);
798
815
  // We can call the native "upsert" because we can't tell if an entity was created or updated
799
816
  // for doing post-write check accordingly. Instead, decompose it into create or update.
@@ -833,7 +850,7 @@ class PolicyProxyHandler {
833
850
  if (!args.where) {
834
851
  throw (0, utils_1.prismaClientValidationError)(this.prisma, 'where field is required in query argument');
835
852
  }
836
- yield this.utils.tryReject(this.prisma, this.model, 'delete');
853
+ this.utils.tryReject(this.prisma, this.model, 'delete');
837
854
  const { result, error } = yield this.transaction((tx) => __awaiter(this, void 0, void 0, function* () {
838
855
  // do a read-back before delete
839
856
  const r = yield this.utils.readBack(tx, this.model, 'delete', args, args.where);
@@ -860,10 +877,10 @@ class PolicyProxyHandler {
860
877
  }
861
878
  deleteMany(args) {
862
879
  return __awaiter(this, void 0, void 0, function* () {
863
- yield this.utils.tryReject(this.prisma, this.model, 'delete');
880
+ this.utils.tryReject(this.prisma, this.model, 'delete');
864
881
  // inject policy conditions
865
882
  args = args !== null && args !== void 0 ? args : {};
866
- yield this.utils.injectAuthGuard(this.prisma, args, this.model, 'delete');
883
+ this.utils.injectAuthGuard(this.prisma, args, this.model, 'delete');
867
884
  // conduct the deletion
868
885
  if (this.shouldLogQuery) {
869
886
  this.logger.info(`[policy] \`deleteMany\` ${this.model}:\n${(0, utils_1.formatObject)(args)}`);
@@ -880,7 +897,7 @@ class PolicyProxyHandler {
880
897
  }
881
898
  args = this.utils.clone(args);
882
899
  // inject policy conditions
883
- yield this.utils.injectAuthGuard(this.prisma, args, this.model, 'read');
900
+ this.utils.injectAuthGuard(this.prisma, args, this.model, 'read');
884
901
  if (this.shouldLogQuery) {
885
902
  this.logger.info(`[policy] \`aggregate\` ${this.model}:\n${(0, utils_1.formatObject)(args)}`);
886
903
  }
@@ -894,7 +911,7 @@ class PolicyProxyHandler {
894
911
  }
895
912
  args = this.utils.clone(args);
896
913
  // inject policy conditions
897
- yield this.utils.injectAuthGuard(this.prisma, args, this.model, 'read');
914
+ this.utils.injectAuthGuard(this.prisma, args, this.model, 'read');
898
915
  if (this.shouldLogQuery) {
899
916
  this.logger.info(`[policy] \`groupBy\` ${this.model}:\n${(0, utils_1.formatObject)(args)}`);
900
917
  }
@@ -905,7 +922,7 @@ class PolicyProxyHandler {
905
922
  return __awaiter(this, void 0, void 0, function* () {
906
923
  // inject policy conditions
907
924
  args = args ? this.utils.clone(args) : {};
908
- yield this.utils.injectAuthGuard(this.prisma, args, this.model, 'read');
925
+ this.utils.injectAuthGuard(this.prisma, args, this.model, 'read');
909
926
  if (this.shouldLogQuery) {
910
927
  this.logger.info(`[policy] \`count\` ${this.model}:\n${(0, utils_1.formatObject)(args)}`);
911
928
  }
@@ -975,6 +992,16 @@ class PolicyProxyHandler {
975
992
  yield Promise.all(postWriteChecks.map(({ model, operation, uniqueFilter, preValue }) => __awaiter(this, void 0, void 0, function* () { return this.utils.checkPolicyForUnique(model, uniqueFilter, operation, db, undefined, preValue); })));
976
993
  });
977
994
  }
995
+ makeHandler(model) {
996
+ return new PolicyProxyHandler(this.prisma, this.policy, this.modelMeta, this.zodSchemas, model, this.user, this.logPrismaQuery);
997
+ }
998
+ requireBackLink(fieldInfo) {
999
+ const backLinkField = fieldInfo.backLink && (0, model_meta_1.resolveField)(this.modelMeta, fieldInfo.type, fieldInfo.backLink);
1000
+ if (!backLinkField) {
1001
+ throw new Error('Missing back link for field: ' + fieldInfo.name);
1002
+ }
1003
+ return backLinkField;
1004
+ }
978
1005
  }
979
1006
  exports.PolicyProxyHandler = PolicyProxyHandler;
980
1007
  //# sourceMappingURL=handler.js.map