@zenstackhq/runtime 2.4.1 → 2.5.1

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 (139) hide show
  1. package/browser/index.js +3 -2
  2. package/browser/index.js.map +1 -1
  3. package/browser/index.mjs +3 -2
  4. package/browser/index.mjs.map +1 -1
  5. package/constants.d.ts +1 -1
  6. package/constants.js +1 -1
  7. package/constants.js.map +1 -1
  8. package/edge.d.ts +1 -7
  9. package/edge.js +1 -7
  10. package/edge.js.map +1 -1
  11. package/enhance-edge.d.ts +1 -0
  12. package/enhance-edge.js +10 -0
  13. package/enhancements/edge/create-enhancement.d.ts +37 -0
  14. package/enhancements/{create-enhancement.js → edge/create-enhancement.js} +2 -2
  15. package/enhancements/edge/create-enhancement.js.map +1 -0
  16. package/enhancements/{default-auth.d.ts → edge/default-auth.d.ts} +2 -1
  17. package/enhancements/{default-auth.js → edge/default-auth.js} +1 -1
  18. package/enhancements/edge/default-auth.js.map +1 -0
  19. package/enhancements/{delegate.d.ts → edge/delegate.d.ts} +1 -1
  20. package/enhancements/{delegate.js → edge/delegate.js} +16 -3
  21. package/enhancements/edge/delegate.js.map +1 -0
  22. package/enhancements/{index.d.ts → edge/index.d.ts} +1 -1
  23. package/enhancements/{index.js → edge/index.js} +1 -1
  24. package/enhancements/edge/index.js.map +1 -0
  25. package/enhancements/edge/logger.js.map +1 -0
  26. package/enhancements/{omit.js → edge/omit.js} +33 -3
  27. package/enhancements/edge/omit.js.map +1 -0
  28. package/enhancements/{password.js → edge/password.js} +2 -2
  29. package/enhancements/edge/password.js.map +1 -0
  30. package/enhancements/edge/policy/check-utils.d.ts +5 -0
  31. package/enhancements/edge/policy/check-utils.js +20 -0
  32. package/enhancements/edge/policy/check-utils.js.map +1 -0
  33. package/enhancements/{policy → edge/policy}/handler.d.ts +24 -9
  34. package/enhancements/{policy → edge/policy}/handler.js +67 -91
  35. package/enhancements/edge/policy/handler.js.map +1 -0
  36. package/enhancements/{policy → edge/policy}/index.d.ts +2 -1
  37. package/enhancements/{policy → edge/policy}/index.js +2 -2
  38. package/enhancements/edge/policy/index.js.map +1 -0
  39. package/enhancements/{policy → edge/policy}/policy-utils.d.ts +5 -5
  40. package/enhancements/{policy → edge/policy}/policy-utils.js +27 -21
  41. package/enhancements/edge/policy/policy-utils.js.map +1 -0
  42. package/enhancements/{promise.d.ts → edge/promise.d.ts} +1 -1
  43. package/enhancements/{promise.js → edge/promise.js} +1 -1
  44. package/enhancements/edge/promise.js.map +1 -0
  45. package/enhancements/{proxy.d.ts → edge/proxy.d.ts} +26 -9
  46. package/enhancements/{proxy.js → edge/proxy.js} +31 -7
  47. package/enhancements/edge/proxy.js.map +1 -0
  48. package/enhancements/{query-utils.d.ts → edge/query-utils.d.ts} +2 -2
  49. package/enhancements/{query-utils.js → edge/query-utils.js} +3 -4
  50. package/enhancements/edge/query-utils.js.map +1 -0
  51. package/enhancements/{types.d.ts → edge/types.d.ts} +5 -12
  52. package/enhancements/{types.js.map → edge/types.js.map} +1 -1
  53. package/enhancements/{utils.d.ts → edge/utils.d.ts} +2 -2
  54. package/enhancements/{utils.js → edge/utils.js} +2 -2
  55. package/enhancements/edge/utils.js.map +1 -0
  56. package/enhancements/{where-visitor.d.ts → edge/where-visitor.d.ts} +1 -1
  57. package/enhancements/{where-visitor.js → edge/where-visitor.js} +1 -1
  58. package/enhancements/edge/where-visitor.js.map +1 -0
  59. package/enhancements/node/create-enhancement.d.ts +37 -0
  60. package/enhancements/node/create-enhancement.js +79 -0
  61. package/enhancements/node/create-enhancement.js.map +1 -0
  62. package/enhancements/node/default-auth.d.ts +8 -0
  63. package/enhancements/node/default-auth.js +129 -0
  64. package/enhancements/node/default-auth.js.map +1 -0
  65. package/enhancements/node/delegate.d.ts +69 -0
  66. package/enhancements/node/delegate.js +1006 -0
  67. package/enhancements/node/delegate.js.map +1 -0
  68. package/enhancements/node/index.d.ts +4 -0
  69. package/enhancements/node/index.js +21 -0
  70. package/enhancements/node/index.js.map +1 -0
  71. package/enhancements/node/logger.d.ts +29 -0
  72. package/enhancements/node/logger.js +65 -0
  73. package/enhancements/node/logger.js.map +1 -0
  74. package/enhancements/node/omit.d.ts +7 -0
  75. package/enhancements/node/omit.js +93 -0
  76. package/enhancements/node/omit.js.map +1 -0
  77. package/enhancements/node/password.d.ts +7 -0
  78. package/enhancements/node/password.js +65 -0
  79. package/enhancements/node/password.js.map +1 -0
  80. package/enhancements/node/policy/check-utils.d.ts +5 -0
  81. package/enhancements/node/policy/check-utils.js +87 -0
  82. package/enhancements/node/policy/check-utils.js.map +1 -0
  83. package/enhancements/node/policy/constraint-solver.js.map +1 -0
  84. package/enhancements/node/policy/handler.d.ts +94 -0
  85. package/enhancements/node/policy/handler.js +1357 -0
  86. package/enhancements/node/policy/handler.js.map +1 -0
  87. package/enhancements/node/policy/index.d.ts +13 -0
  88. package/enhancements/node/policy/index.js +42 -0
  89. package/enhancements/node/policy/index.js.map +1 -0
  90. package/enhancements/node/policy/policy-utils.d.ts +184 -0
  91. package/enhancements/node/policy/policy-utils.js +1296 -0
  92. package/enhancements/node/policy/policy-utils.js.map +1 -0
  93. package/enhancements/node/promise.d.ts +15 -0
  94. package/enhancements/node/promise.js +99 -0
  95. package/enhancements/node/promise.js.map +1 -0
  96. package/enhancements/node/proxy.d.ts +118 -0
  97. package/enhancements/node/proxy.js +267 -0
  98. package/enhancements/node/proxy.js.map +1 -0
  99. package/enhancements/node/query-utils.d.ts +38 -0
  100. package/enhancements/node/query-utils.js +185 -0
  101. package/enhancements/node/query-utils.js.map +1 -0
  102. package/enhancements/node/types.d.ts +224 -0
  103. package/enhancements/node/types.js +3 -0
  104. package/enhancements/node/types.js.map +1 -0
  105. package/enhancements/node/utils.d.ts +11 -0
  106. package/enhancements/node/utils.js +49 -0
  107. package/enhancements/node/utils.js.map +1 -0
  108. package/enhancements/node/where-visitor.d.ts +32 -0
  109. package/enhancements/node/where-visitor.js +86 -0
  110. package/enhancements/node/where-visitor.js.map +1 -0
  111. package/index.d.ts +2 -2
  112. package/index.js +2 -2
  113. package/index.js.map +1 -1
  114. package/package.json +14 -6
  115. package/types.d.ts +62 -0
  116. package/enhancements/create-enhancement.d.ts +0 -78
  117. package/enhancements/create-enhancement.js.map +0 -1
  118. package/enhancements/default-auth.js.map +0 -1
  119. package/enhancements/delegate.js.map +0 -1
  120. package/enhancements/index.js.map +0 -1
  121. package/enhancements/logger.js.map +0 -1
  122. package/enhancements/omit.js.map +0 -1
  123. package/enhancements/password.js.map +0 -1
  124. package/enhancements/policy/constraint-solver.js.map +0 -1
  125. package/enhancements/policy/handler.js.map +0 -1
  126. package/enhancements/policy/index.js.map +0 -1
  127. package/enhancements/policy/policy-utils.js.map +0 -1
  128. package/enhancements/promise.js.map +0 -1
  129. package/enhancements/proxy.js.map +0 -1
  130. package/enhancements/query-utils.js.map +0 -1
  131. package/enhancements/utils.js.map +0 -1
  132. package/enhancements/where-visitor.js.map +0 -1
  133. /package/enhancements/{logger.d.ts → edge/logger.d.ts} +0 -0
  134. /package/enhancements/{logger.js → edge/logger.js} +0 -0
  135. /package/enhancements/{omit.d.ts → edge/omit.d.ts} +0 -0
  136. /package/enhancements/{password.d.ts → edge/password.d.ts} +0 -0
  137. /package/enhancements/{types.js → edge/types.js} +0 -0
  138. /package/enhancements/{policy → node/policy}/constraint-solver.d.ts +0 -0
  139. /package/enhancements/{policy → node/policy}/constraint-solver.js +0 -0
@@ -0,0 +1,1006 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DelegateProxyHandler = void 0;
16
+ exports.withDelegate = withDelegate;
17
+ /* eslint-disable @typescript-eslint/no-explicit-any */
18
+ const deepmerge_1 = __importDefault(require("deepmerge"));
19
+ const is_plain_object_1 = require("is-plain-object");
20
+ const lower_case_first_1 = require("lower-case-first");
21
+ const constants_1 = require("../../constants");
22
+ const cross_1 = require("../../cross");
23
+ const logger_1 = require("./logger");
24
+ const proxy_1 = require("./proxy");
25
+ const query_utils_1 = require("./query-utils");
26
+ const utils_1 = require("./utils");
27
+ function withDelegate(prisma, options) {
28
+ return (0, proxy_1.makeProxy)(prisma, options.modelMeta, (_prisma, model) => new DelegateProxyHandler(_prisma, model, options), 'delegate');
29
+ }
30
+ class DelegateProxyHandler extends proxy_1.DefaultPrismaProxyHandler {
31
+ constructor(prisma, model, options) {
32
+ super(prisma, model, options);
33
+ this.logger = new logger_1.Logger(prisma);
34
+ this.queryUtils = new query_utils_1.QueryUtils(prisma, this.options);
35
+ }
36
+ // #region find
37
+ findFirst(args) {
38
+ return this.doFind(this.prisma, this.model, 'findFirst', args);
39
+ }
40
+ findFirstOrThrow(args) {
41
+ return this.doFind(this.prisma, this.model, 'findFirstOrThrow', args);
42
+ }
43
+ findUnique(args) {
44
+ return this.doFind(this.prisma, this.model, 'findUnique', args);
45
+ }
46
+ findUniqueOrThrow(args) {
47
+ return this.doFind(this.prisma, this.model, 'findUniqueOrThrow', args);
48
+ }
49
+ findMany(args) {
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ return this.doFind(this.prisma, this.model, 'findMany', args);
52
+ });
53
+ }
54
+ doFind(db, model, method, args) {
55
+ const _superIndex = name => super[name];
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ if (!this.involvesDelegateModel(model)) {
58
+ return _superIndex(method).call(this, args);
59
+ }
60
+ args = args ? (0, cross_1.clone)(args) : {};
61
+ this.injectWhereHierarchy(model, args === null || args === void 0 ? void 0 : args.where);
62
+ this.injectSelectIncludeHierarchy(model, args);
63
+ if (args.orderBy) {
64
+ // `orderBy` may contain fields from base types
65
+ this.injectWhereHierarchy(this.model, args.orderBy);
66
+ }
67
+ if (this.options.logPrismaQuery) {
68
+ this.logger.info(`[delegate] \`${method}\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
69
+ }
70
+ const entity = yield db[model][method](args);
71
+ if (Array.isArray(entity)) {
72
+ return entity.map((item) => this.assembleHierarchy(model, item));
73
+ }
74
+ else {
75
+ return this.assembleHierarchy(model, entity);
76
+ }
77
+ });
78
+ }
79
+ injectWhereHierarchy(model, where) {
80
+ if (!where || !(0, is_plain_object_1.isPlainObject)(where)) {
81
+ return;
82
+ }
83
+ Object.entries(where).forEach(([field, value]) => {
84
+ if (['AND', 'OR', 'NOT'].includes(field)) {
85
+ // recurse into logical group
86
+ (0, cross_1.enumerate)(value).forEach((item) => this.injectWhereHierarchy(model, item));
87
+ return;
88
+ }
89
+ const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);
90
+ if (!(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom)) {
91
+ // not an inherited field, inject and continue
92
+ if (fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.isDataModel) {
93
+ this.injectWhereHierarchy(fieldInfo.type, value);
94
+ }
95
+ return;
96
+ }
97
+ let base = this.getBaseModel(model);
98
+ let target = where;
99
+ while (base) {
100
+ const baseRelationName = this.makeAuxRelationName(base);
101
+ // prepare base layer where
102
+ let thisLayer;
103
+ if (target[baseRelationName]) {
104
+ thisLayer = target[baseRelationName];
105
+ }
106
+ else {
107
+ thisLayer = target[baseRelationName] = {};
108
+ }
109
+ if (base.name === fieldInfo.inheritedFrom) {
110
+ if (fieldInfo.isDataModel) {
111
+ this.injectWhereHierarchy(base.name, value);
112
+ }
113
+ thisLayer[field] = value;
114
+ delete where[field];
115
+ break;
116
+ }
117
+ else {
118
+ target = thisLayer;
119
+ base = this.getBaseModel(base.name);
120
+ }
121
+ }
122
+ });
123
+ }
124
+ injectSelectIncludeHierarchy(model, args) {
125
+ if (!args || typeof args !== 'object') {
126
+ return;
127
+ }
128
+ for (const kind of ['select', 'include']) {
129
+ if (args[kind] && typeof args[kind] === 'object') {
130
+ for (const [field, value] of Object.entries(args[kind])) {
131
+ const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);
132
+ if (!fieldInfo) {
133
+ continue;
134
+ }
135
+ if (this.isDelegateOrDescendantOfDelegate(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.type) && value) {
136
+ // delegate model, recursively inject hierarchy
137
+ if (args[kind][field]) {
138
+ if (args[kind][field] === true) {
139
+ // make sure the payload is an object
140
+ args[kind][field] = {};
141
+ }
142
+ this.injectSelectIncludeHierarchy(fieldInfo.type, args[kind][field]);
143
+ }
144
+ }
145
+ if (value !== undefined) {
146
+ if (value === null || value === void 0 ? void 0 : value.orderBy) {
147
+ // `orderBy` may contain fields from base types
148
+ this.injectWhereHierarchy(fieldInfo.type, value.orderBy);
149
+ }
150
+ if (this.injectBaseFieldSelect(model, field, value, args, kind)) {
151
+ delete args[kind][field];
152
+ }
153
+ else if (fieldInfo.isDataModel) {
154
+ let nextValue = value;
155
+ if (nextValue === true) {
156
+ // make sure the payload is an object
157
+ args[kind][field] = nextValue = {};
158
+ }
159
+ this.injectSelectIncludeHierarchy(fieldInfo.type, nextValue);
160
+ }
161
+ }
162
+ }
163
+ }
164
+ }
165
+ if (!args.select) {
166
+ // include base models upwards
167
+ this.injectBaseIncludeRecursively(model, args);
168
+ // include sub models downwards
169
+ this.injectConcreteIncludeRecursively(model, args);
170
+ }
171
+ }
172
+ buildSelectIncludeHierarchy(model, args) {
173
+ args = (0, cross_1.clone)(args);
174
+ const selectInclude = this.extractSelectInclude(args) || {};
175
+ if (selectInclude.select && typeof selectInclude.select === 'object') {
176
+ Object.entries(selectInclude.select).forEach(([field, value]) => {
177
+ if (value) {
178
+ if (this.injectBaseFieldSelect(model, field, value, selectInclude, 'select')) {
179
+ delete selectInclude.select[field];
180
+ }
181
+ }
182
+ });
183
+ }
184
+ else if (selectInclude.include && typeof selectInclude.include === 'object') {
185
+ Object.entries(selectInclude.include).forEach(([field, value]) => {
186
+ if (value) {
187
+ if (this.injectBaseFieldSelect(model, field, value, selectInclude, 'include')) {
188
+ delete selectInclude.include[field];
189
+ }
190
+ }
191
+ });
192
+ }
193
+ if (!selectInclude.select) {
194
+ this.injectBaseIncludeRecursively(model, selectInclude);
195
+ this.injectConcreteIncludeRecursively(model, selectInclude);
196
+ }
197
+ return selectInclude;
198
+ }
199
+ injectBaseFieldSelect(model, field, value, selectInclude, context) {
200
+ const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);
201
+ if (!(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom)) {
202
+ return false;
203
+ }
204
+ let base = this.getBaseModel(model);
205
+ let target = selectInclude;
206
+ while (base) {
207
+ const baseRelationName = this.makeAuxRelationName(base);
208
+ // prepare base layer select/include
209
+ // let selectOrInclude = 'select';
210
+ let thisLayer;
211
+ if (target.include) {
212
+ // selectOrInclude = 'include';
213
+ thisLayer = target.include;
214
+ }
215
+ else if (target.select) {
216
+ // selectOrInclude = 'select';
217
+ thisLayer = target.select;
218
+ }
219
+ else {
220
+ // selectInclude = 'include';
221
+ thisLayer = target.select = {};
222
+ }
223
+ if (base.name === fieldInfo.inheritedFrom) {
224
+ if (!thisLayer[baseRelationName]) {
225
+ thisLayer[baseRelationName] = { [context]: {} };
226
+ }
227
+ thisLayer[baseRelationName][context][field] = value;
228
+ break;
229
+ }
230
+ else {
231
+ if (!thisLayer[baseRelationName]) {
232
+ thisLayer[baseRelationName] = { select: {} };
233
+ }
234
+ target = thisLayer[baseRelationName];
235
+ base = this.getBaseModel(base.name);
236
+ }
237
+ }
238
+ return true;
239
+ }
240
+ injectBaseIncludeRecursively(model, selectInclude) {
241
+ const base = this.getBaseModel(model);
242
+ if (!base) {
243
+ return;
244
+ }
245
+ const baseRelationName = this.makeAuxRelationName(base);
246
+ if (selectInclude.select) {
247
+ selectInclude.include = Object.assign({ [baseRelationName]: {} }, selectInclude.select);
248
+ delete selectInclude.select;
249
+ }
250
+ else {
251
+ selectInclude.include = Object.assign({ [baseRelationName]: {} }, selectInclude.include);
252
+ }
253
+ this.injectBaseIncludeRecursively(base.name, selectInclude.include[baseRelationName]);
254
+ }
255
+ injectConcreteIncludeRecursively(model, selectInclude) {
256
+ const modelInfo = (0, cross_1.getModelInfo)(this.options.modelMeta, model);
257
+ if (!modelInfo) {
258
+ return;
259
+ }
260
+ // get sub models of this model
261
+ const subModels = Object.values(this.options.modelMeta.models).filter((m) => { var _a; return (_a = m.baseTypes) === null || _a === void 0 ? void 0 : _a.includes(modelInfo.name); });
262
+ for (const subModel of subModels) {
263
+ // include sub model relation field
264
+ const subRelationName = this.makeAuxRelationName(subModel);
265
+ if (selectInclude.select) {
266
+ selectInclude.include = Object.assign({ [subRelationName]: {} }, selectInclude.select);
267
+ delete selectInclude.select;
268
+ }
269
+ else {
270
+ selectInclude.include = Object.assign({ [subRelationName]: {} }, selectInclude.include);
271
+ }
272
+ this.injectConcreteIncludeRecursively(subModel.name, selectInclude.include[subRelationName]);
273
+ }
274
+ }
275
+ // #endregion
276
+ // #region create
277
+ create(args) {
278
+ const _super = Object.create(null, {
279
+ create: { get: () => super.create }
280
+ });
281
+ return __awaiter(this, void 0, void 0, function* () {
282
+ if (!args) {
283
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
284
+ }
285
+ if (!args.data) {
286
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'data field is required in query argument');
287
+ }
288
+ if ((0, cross_1.isDelegateModel)(this.options.modelMeta, this.model)) {
289
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `Model "${this.model}" is a delegate and cannot be created directly`);
290
+ }
291
+ if (!this.involvesDelegateModel(this.model)) {
292
+ return _super.create.call(this, args);
293
+ }
294
+ return this.doCreate(this.prisma, this.model, args);
295
+ });
296
+ }
297
+ createMany(args) {
298
+ if (!args) {
299
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
300
+ }
301
+ if (!args.data) {
302
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'data field is required in query argument');
303
+ }
304
+ if (!this.involvesDelegateModel(this.model)) {
305
+ return super.createMany(args);
306
+ }
307
+ if (this.isDelegateOrDescendantOfDelegate(this.model) && args.skipDuplicates) {
308
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, '`createMany` with `skipDuplicates` set to true is not supported for delegated models');
309
+ }
310
+ // `createMany` doesn't support nested create, which is needed for creating entities
311
+ // inheriting a delegate base, so we need to convert it to a regular `create` here.
312
+ // Note that the main difference is `create` doesn't support `skipDuplicates` as
313
+ // `createMany` does.
314
+ return this.queryUtils.transaction(this.prisma, (tx) => __awaiter(this, void 0, void 0, function* () {
315
+ const r = yield Promise.all((0, cross_1.enumerate)(args.data).map((item) => __awaiter(this, void 0, void 0, function* () {
316
+ return this.doCreate(tx, this.model, { data: item });
317
+ })));
318
+ return { count: r.length };
319
+ }));
320
+ }
321
+ createManyAndReturn(args) {
322
+ if (!args) {
323
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
324
+ }
325
+ if (!args.data) {
326
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'data field is required in query argument');
327
+ }
328
+ if (!this.involvesDelegateModel(this.model)) {
329
+ return super.createManyAndReturn(args);
330
+ }
331
+ if (this.isDelegateOrDescendantOfDelegate(this.model) && args.skipDuplicates) {
332
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, '`createManyAndReturn` with `skipDuplicates` set to true is not supported for delegated models');
333
+ }
334
+ // `createManyAndReturn` doesn't support nested create, which is needed for creating entities
335
+ // inheriting a delegate base, so we need to convert it to a regular `create` here.
336
+ // Note that the main difference is `create` doesn't support `skipDuplicates` as
337
+ // `createManyAndReturn` does.
338
+ return this.queryUtils.transaction(this.prisma, (tx) => __awaiter(this, void 0, void 0, function* () {
339
+ const r = yield Promise.all((0, cross_1.enumerate)(args.data).map((item) => __awaiter(this, void 0, void 0, function* () {
340
+ return this.doCreate(tx, this.model, { data: item, select: args.select });
341
+ })));
342
+ return r;
343
+ }));
344
+ }
345
+ doCreate(db, model, args) {
346
+ return __awaiter(this, void 0, void 0, function* () {
347
+ args = (0, cross_1.clone)(args);
348
+ yield this.injectCreateHierarchy(model, args);
349
+ this.injectSelectIncludeHierarchy(model, args);
350
+ if (this.options.logPrismaQuery) {
351
+ this.logger.info(`[delegate] \`create\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
352
+ }
353
+ const result = yield db[model].create(args);
354
+ return this.assembleHierarchy(model, result);
355
+ });
356
+ }
357
+ injectCreateHierarchy(model, args) {
358
+ return __awaiter(this, void 0, void 0, function* () {
359
+ const visitor = new cross_1.NestedWriteVisitor(this.options.modelMeta, {
360
+ create: (model, args, _context) => {
361
+ this.doProcessCreatePayload(model, args);
362
+ },
363
+ createMany: (model, args, context) => {
364
+ // `createMany` doesn't support nested create, which is needed for creating entities
365
+ // inheriting a delegate base, so we need to convert it to a regular `create` here.
366
+ // Note that the main difference is `create` doesn't support `skipDuplicates` as
367
+ // `createMany` does.
368
+ var _a;
369
+ if (this.isDelegateOrDescendantOfDelegate(model)) {
370
+ if (args.skipDuplicates) {
371
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, '`createMany` with `skipDuplicates` set to true is not supported for delegated models');
372
+ }
373
+ // convert to regular `create`
374
+ let createPayload = (_a = context.parent.create) !== null && _a !== void 0 ? _a : [];
375
+ if (!Array.isArray(createPayload)) {
376
+ createPayload = [createPayload];
377
+ }
378
+ for (const item of (0, cross_1.enumerate)(args.data)) {
379
+ this.doProcessCreatePayload(model, item);
380
+ createPayload.push(item);
381
+ }
382
+ context.parent.create = createPayload;
383
+ delete context.parent['createMany'];
384
+ }
385
+ },
386
+ });
387
+ yield visitor.visit(model, 'create', args);
388
+ });
389
+ }
390
+ doProcessCreatePayload(model, args) {
391
+ if (!args) {
392
+ return;
393
+ }
394
+ this.ensureBaseCreateHierarchy(model, args);
395
+ for (const [field, value] of Object.entries(args)) {
396
+ const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);
397
+ if (fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom) {
398
+ this.injectBaseFieldData(model, fieldInfo, value, args, 'create');
399
+ delete args[field];
400
+ }
401
+ }
402
+ }
403
+ // ensure the full nested "create" structure is created for base types
404
+ ensureBaseCreateHierarchy(model, args) {
405
+ let curr = args;
406
+ let base = this.getBaseModel(model);
407
+ let sub = this.getModelInfo(model);
408
+ while (base) {
409
+ const baseRelationName = this.makeAuxRelationName(base);
410
+ if (!curr[baseRelationName]) {
411
+ curr[baseRelationName] = {};
412
+ }
413
+ if (!curr[baseRelationName].create) {
414
+ curr[baseRelationName].create = {};
415
+ if (base.discriminator) {
416
+ // set discriminator field
417
+ curr[baseRelationName].create[base.discriminator] = sub.name;
418
+ }
419
+ }
420
+ // Look for base id field assignments in the current level, and push
421
+ // them down to the base level
422
+ for (const idField of (0, cross_1.getIdFields)(this.options.modelMeta, base.name)) {
423
+ if (curr[idField.name] !== undefined) {
424
+ curr[baseRelationName].create[idField.name] = curr[idField.name];
425
+ delete curr[idField.name];
426
+ }
427
+ }
428
+ curr = curr[baseRelationName].create;
429
+ sub = base;
430
+ base = this.getBaseModel(base.name);
431
+ }
432
+ }
433
+ // inject field data that belongs to base type into proper nesting structure
434
+ injectBaseFieldData(model, fieldInfo, value, args, mode) {
435
+ let base = this.getBaseModel(model);
436
+ let curr = args;
437
+ while (base) {
438
+ if (base.discriminator === fieldInfo.name) {
439
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `fields "${fieldInfo.name}" is a discriminator and cannot be set directly`);
440
+ }
441
+ const baseRelationName = this.makeAuxRelationName(base);
442
+ if (!curr[baseRelationName]) {
443
+ curr[baseRelationName] = {};
444
+ }
445
+ if (!curr[baseRelationName][mode]) {
446
+ curr[baseRelationName][mode] = {};
447
+ }
448
+ curr = curr[baseRelationName][mode];
449
+ if (fieldInfo.inheritedFrom === base.name) {
450
+ curr[fieldInfo.name] = value;
451
+ break;
452
+ }
453
+ base = this.getBaseModel(base.name);
454
+ }
455
+ }
456
+ // #endregion
457
+ // #region update
458
+ update(args) {
459
+ if (!args) {
460
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
461
+ }
462
+ if (!args.data) {
463
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'data field is required in query argument');
464
+ }
465
+ if (!this.involvesDelegateModel(this.model)) {
466
+ return super.update(args);
467
+ }
468
+ return this.queryUtils.transaction(this.prisma, (tx) => this.doUpdate(tx, this.model, args));
469
+ }
470
+ updateMany(args) {
471
+ const _super = Object.create(null, {
472
+ updateMany: { get: () => super.updateMany }
473
+ });
474
+ return __awaiter(this, void 0, void 0, function* () {
475
+ if (!args) {
476
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
477
+ }
478
+ if (!args.data) {
479
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'data field is required in query argument');
480
+ }
481
+ if (!this.involvesDelegateModel(this.model)) {
482
+ return _super.updateMany.call(this, args);
483
+ }
484
+ const simpleUpdateMany = Object.keys(args.data).every((key) => {
485
+ // check if the `data` clause involves base fields
486
+ const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, this.model, key);
487
+ return !(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom);
488
+ });
489
+ return this.queryUtils.transaction(this.prisma, (tx) => this.doUpdateMany(tx, this.model, args, simpleUpdateMany));
490
+ });
491
+ }
492
+ upsert(args) {
493
+ const _super = Object.create(null, {
494
+ upsert: { get: () => super.upsert }
495
+ });
496
+ return __awaiter(this, void 0, void 0, function* () {
497
+ if (!args) {
498
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
499
+ }
500
+ if (!args.where) {
501
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'where field is required in query argument');
502
+ }
503
+ if ((0, cross_1.isDelegateModel)(this.options.modelMeta, this.model)) {
504
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `Model "${this.model}" is a delegate and doesn't support upsert`);
505
+ }
506
+ if (!this.involvesDelegateModel(this.model)) {
507
+ return _super.upsert.call(this, args);
508
+ }
509
+ args = (0, cross_1.clone)(args);
510
+ this.injectWhereHierarchy(this.model, args === null || args === void 0 ? void 0 : args.where);
511
+ this.injectSelectIncludeHierarchy(this.model, args);
512
+ if (args.create) {
513
+ this.doProcessCreatePayload(this.model, args.create);
514
+ }
515
+ if (args.update) {
516
+ this.doProcessUpdatePayload(this.model, args.update);
517
+ }
518
+ if (this.options.logPrismaQuery) {
519
+ this.logger.info(`[delegate] \`upsert\` ${this.getModelName(this.model)}: ${(0, utils_1.formatObject)(args)}`);
520
+ }
521
+ const result = yield this.prisma[this.model].upsert(args);
522
+ return this.assembleHierarchy(this.model, result);
523
+ });
524
+ }
525
+ doUpdate(db, model, args) {
526
+ return __awaiter(this, void 0, void 0, function* () {
527
+ args = (0, cross_1.clone)(args);
528
+ yield this.injectUpdateHierarchy(db, model, args);
529
+ this.injectSelectIncludeHierarchy(model, args);
530
+ if (this.options.logPrismaQuery) {
531
+ this.logger.info(`[delegate] \`update\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
532
+ }
533
+ const result = yield db[model].update(args);
534
+ return this.assembleHierarchy(model, result);
535
+ });
536
+ }
537
+ doUpdateMany(db, model, args, simpleUpdateMany) {
538
+ return __awaiter(this, void 0, void 0, function* () {
539
+ if (simpleUpdateMany) {
540
+ // do a direct `updateMany`
541
+ args = (0, cross_1.clone)(args);
542
+ yield this.injectUpdateHierarchy(db, model, args);
543
+ if (this.options.logPrismaQuery) {
544
+ this.logger.info(`[delegate] \`updateMany\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
545
+ }
546
+ return db[model].updateMany(args);
547
+ }
548
+ else {
549
+ // translate to plain `update` for nested write into base fields
550
+ const findArgs = {
551
+ where: (0, cross_1.clone)(args.where),
552
+ select: this.queryUtils.makeIdSelection(model),
553
+ };
554
+ yield this.injectUpdateHierarchy(db, model, findArgs);
555
+ if (this.options.logPrismaQuery) {
556
+ this.logger.info(`[delegate] \`updateMany\` find candidates: ${this.getModelName(model)}: ${(0, utils_1.formatObject)(findArgs)}`);
557
+ }
558
+ const entities = yield db[model].findMany(findArgs);
559
+ const updatePayload = { data: (0, cross_1.clone)(args.data), select: this.queryUtils.makeIdSelection(model) };
560
+ yield this.injectUpdateHierarchy(db, model, updatePayload);
561
+ const result = yield Promise.all(entities.map((entity) => {
562
+ const updateArgs = Object.assign({ where: entity }, updatePayload);
563
+ if (this.options.logPrismaQuery) {
564
+ this.logger.info(`[delegate] \`updateMany\` update: ${this.getModelName(model)}: ${(0, utils_1.formatObject)(updateArgs)}`);
565
+ }
566
+ return db[model].update(updateArgs);
567
+ }));
568
+ return { count: result.length };
569
+ }
570
+ });
571
+ }
572
+ injectUpdateHierarchy(db, model, args) {
573
+ return __awaiter(this, void 0, void 0, function* () {
574
+ const visitor = new cross_1.NestedWriteVisitor(this.options.modelMeta, {
575
+ update: (model, args, _context) => {
576
+ this.injectWhereHierarchy(model, args === null || args === void 0 ? void 0 : args.where);
577
+ this.doProcessUpdatePayload(model, args === null || args === void 0 ? void 0 : args.data);
578
+ },
579
+ updateMany: (model, args, context) => __awaiter(this, void 0, void 0, function* () {
580
+ let simpleUpdateMany = Object.keys(args.data).every((key) => {
581
+ // check if the `data` clause involves base fields
582
+ const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, key);
583
+ return !(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom);
584
+ });
585
+ if (simpleUpdateMany) {
586
+ // check if the `where` clause involves base fields
587
+ simpleUpdateMany = Object.keys(args.where || {}).every((key) => {
588
+ const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, key);
589
+ return !(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom);
590
+ });
591
+ }
592
+ if (simpleUpdateMany) {
593
+ this.injectWhereHierarchy(model, args === null || args === void 0 ? void 0 : args.where);
594
+ this.doProcessUpdatePayload(model, args === null || args === void 0 ? void 0 : args.data);
595
+ }
596
+ else {
597
+ const where = this.queryUtils.buildReversedQuery(context, false, false);
598
+ yield this.queryUtils.transaction(db, (tx) => __awaiter(this, void 0, void 0, function* () {
599
+ yield this.doUpdateMany(tx, model, Object.assign(Object.assign({}, args), { where }), simpleUpdateMany);
600
+ }));
601
+ delete context.parent['updateMany'];
602
+ }
603
+ }),
604
+ upsert: (model, args, _context) => {
605
+ this.injectWhereHierarchy(model, args === null || args === void 0 ? void 0 : args.where);
606
+ if (args.create) {
607
+ this.doProcessCreatePayload(model, args === null || args === void 0 ? void 0 : args.create);
608
+ }
609
+ if (args.update) {
610
+ this.doProcessUpdatePayload(model, args === null || args === void 0 ? void 0 : args.update);
611
+ }
612
+ },
613
+ create: (model, args, _context) => {
614
+ if ((0, cross_1.isDelegateModel)(this.options.modelMeta, model)) {
615
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `Model "${model}" is a delegate and cannot be created directly`);
616
+ }
617
+ this.doProcessCreatePayload(model, args);
618
+ },
619
+ createMany: (model, args, _context) => {
620
+ if (args.skipDuplicates) {
621
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, '`createMany` with `skipDuplicates` set to true is not supported for delegated models');
622
+ }
623
+ for (const item of (0, cross_1.enumerate)(args === null || args === void 0 ? void 0 : args.data)) {
624
+ this.doProcessCreatePayload(model, item);
625
+ }
626
+ },
627
+ connect: (model, args, _context) => {
628
+ this.injectWhereHierarchy(model, args);
629
+ },
630
+ connectOrCreate: (model, args, _context) => {
631
+ this.injectWhereHierarchy(model, args.where);
632
+ if (args.create) {
633
+ this.doProcessCreatePayload(model, args.create);
634
+ }
635
+ },
636
+ disconnect: (model, args, _context) => {
637
+ this.injectWhereHierarchy(model, args);
638
+ },
639
+ set: (model, args, _context) => {
640
+ this.injectWhereHierarchy(model, args);
641
+ },
642
+ delete: (model, _args, context) => __awaiter(this, void 0, void 0, function* () {
643
+ const where = this.queryUtils.buildReversedQuery(context, false, false);
644
+ yield this.queryUtils.transaction(db, (tx) => __awaiter(this, void 0, void 0, function* () {
645
+ yield this.doDelete(tx, model, { where });
646
+ }));
647
+ delete context.parent['delete'];
648
+ }),
649
+ deleteMany: (model, _args, context) => __awaiter(this, void 0, void 0, function* () {
650
+ const where = this.queryUtils.buildReversedQuery(context, false, false);
651
+ yield this.queryUtils.transaction(db, (tx) => __awaiter(this, void 0, void 0, function* () {
652
+ yield this.doDeleteMany(tx, model, where);
653
+ }));
654
+ delete context.parent['deleteMany'];
655
+ }),
656
+ });
657
+ yield visitor.visit(model, 'update', args);
658
+ });
659
+ }
660
+ doProcessUpdatePayload(model, data) {
661
+ if (!data) {
662
+ return;
663
+ }
664
+ for (const [field, value] of Object.entries(data)) {
665
+ const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);
666
+ if (fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom) {
667
+ this.injectBaseFieldData(model, fieldInfo, value, data, 'update');
668
+ delete data[field];
669
+ }
670
+ }
671
+ }
672
+ // #endregion
673
+ // #region delete
674
+ delete(args) {
675
+ if (!args) {
676
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
677
+ }
678
+ if (!this.involvesDelegateModel(this.model)) {
679
+ return super.delete(args);
680
+ }
681
+ return this.queryUtils.transaction(this.prisma, (tx) => __awaiter(this, void 0, void 0, function* () {
682
+ const selectInclude = this.buildSelectIncludeHierarchy(this.model, args);
683
+ // make sure id fields are selected
684
+ const idFields = this.getIdFields(this.model);
685
+ for (const idField of idFields) {
686
+ if ((selectInclude === null || selectInclude === void 0 ? void 0 : selectInclude.select) && !(idField.name in selectInclude.select)) {
687
+ selectInclude.select[idField.name] = true;
688
+ }
689
+ }
690
+ const deleteArgs = Object.assign(Object.assign({}, (0, cross_1.clone)(args)), selectInclude);
691
+ return this.doDelete(tx, this.model, deleteArgs);
692
+ }));
693
+ }
694
+ deleteMany(args) {
695
+ if (!this.involvesDelegateModel(this.model)) {
696
+ return super.deleteMany(args);
697
+ }
698
+ return this.queryUtils.transaction(this.prisma, (tx) => this.doDeleteMany(tx, this.model, args === null || args === void 0 ? void 0 : args.where));
699
+ }
700
+ doDeleteMany(db, model, where) {
701
+ return __awaiter(this, void 0, void 0, function* () {
702
+ // query existing entities with id
703
+ const idSelection = this.queryUtils.makeIdSelection(model);
704
+ const findArgs = { where: (0, cross_1.clone)(where), select: idSelection };
705
+ this.injectWhereHierarchy(model, findArgs.where);
706
+ if (this.options.logPrismaQuery) {
707
+ this.logger.info(`[delegate] \`deleteMany\` find candidates: ${this.getModelName(model)}: ${(0, utils_1.formatObject)(findArgs)}`);
708
+ }
709
+ const entities = yield db[model].findMany(findArgs);
710
+ // recursively delete base entities (they all have the same id values)
711
+ yield Promise.all(entities.map((entity) => this.doDelete(db, model, { where: entity })));
712
+ return { count: entities.length };
713
+ });
714
+ }
715
+ deleteBaseRecursively(db, model, idValues) {
716
+ return __awaiter(this, void 0, void 0, function* () {
717
+ let base = this.getBaseModel(model);
718
+ while (base) {
719
+ yield db[base.name].delete({ where: idValues });
720
+ base = this.getBaseModel(base.name);
721
+ }
722
+ });
723
+ }
724
+ doDelete(db, model, args) {
725
+ return __awaiter(this, void 0, void 0, function* () {
726
+ this.injectWhereHierarchy(model, args.where);
727
+ if (this.options.logPrismaQuery) {
728
+ this.logger.info(`[delegate] \`delete\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
729
+ }
730
+ const result = yield db[model].delete(args);
731
+ const idValues = this.queryUtils.getEntityIds(model, result);
732
+ // recursively delete base entities (they all have the same id values)
733
+ yield this.deleteBaseRecursively(db, model, idValues);
734
+ return this.assembleHierarchy(model, result);
735
+ });
736
+ }
737
+ // #endregion
738
+ // #region aggregation
739
+ aggregate(args) {
740
+ if (!args) {
741
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
742
+ }
743
+ if (!this.involvesDelegateModel(this.model)) {
744
+ return super.aggregate(args);
745
+ }
746
+ // check if any aggregation operator is using fields from base
747
+ this.checkAggregationArgs('aggregate', args);
748
+ args = (0, cross_1.clone)(args);
749
+ if (args.cursor) {
750
+ this.injectWhereHierarchy(this.model, args.cursor);
751
+ }
752
+ if (args.orderBy) {
753
+ this.injectWhereHierarchy(this.model, args.orderBy);
754
+ }
755
+ if (args.where) {
756
+ this.injectWhereHierarchy(this.model, args.where);
757
+ }
758
+ if (this.options.logPrismaQuery) {
759
+ this.logger.info(`[delegate] \`aggregate\` ${this.getModelName(this.model)}: ${(0, utils_1.formatObject)(args)}`);
760
+ }
761
+ return super.aggregate(args);
762
+ }
763
+ count(args) {
764
+ if (!this.involvesDelegateModel(this.model)) {
765
+ return super.count(args);
766
+ }
767
+ // check if count select is using fields from base
768
+ this.checkAggregationArgs('count', args);
769
+ args = (0, cross_1.clone)(args);
770
+ if (args === null || args === void 0 ? void 0 : args.cursor) {
771
+ this.injectWhereHierarchy(this.model, args.cursor);
772
+ }
773
+ if (args === null || args === void 0 ? void 0 : args.where) {
774
+ this.injectWhereHierarchy(this.model, args.where);
775
+ }
776
+ if (this.options.logPrismaQuery) {
777
+ this.logger.info(`[delegate] \`count\` ${this.getModelName(this.model)}: ${(0, utils_1.formatObject)(args)}`);
778
+ }
779
+ return super.count(args);
780
+ }
781
+ groupBy(args) {
782
+ if (!args) {
783
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
784
+ }
785
+ if (!this.involvesDelegateModel(this.model)) {
786
+ return super.groupBy(args);
787
+ }
788
+ // check if count select is using fields from base
789
+ this.checkAggregationArgs('groupBy', args);
790
+ if (args.by) {
791
+ for (const by of (0, cross_1.enumerate)(args.by)) {
792
+ const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, this.model, by);
793
+ if (fieldInfo && fieldInfo.inheritedFrom) {
794
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `groupBy with fields from base type is not supported yet: "${by}"`);
795
+ }
796
+ }
797
+ }
798
+ args = (0, cross_1.clone)(args);
799
+ if (args.where) {
800
+ this.injectWhereHierarchy(this.model, args.where);
801
+ }
802
+ if (this.options.logPrismaQuery) {
803
+ this.logger.info(`[delegate] \`groupBy\` ${this.getModelName(this.model)}: ${(0, utils_1.formatObject)(args)}`);
804
+ }
805
+ return super.groupBy(args);
806
+ }
807
+ checkAggregationArgs(operation, args) {
808
+ if (!args) {
809
+ return;
810
+ }
811
+ for (const op of ['_count', '_sum', '_avg', '_min', '_max', 'select', 'having']) {
812
+ if (args[op] && typeof args[op] === 'object') {
813
+ for (const field of Object.keys(args[op])) {
814
+ const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, this.model, field);
815
+ if (fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom) {
816
+ throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `${operation} with fields from base type is not supported yet: "${field}"`);
817
+ }
818
+ }
819
+ }
820
+ }
821
+ }
822
+ // #endregion
823
+ // #region utils
824
+ extractSelectInclude(args) {
825
+ if (!args) {
826
+ return undefined;
827
+ }
828
+ args = (0, cross_1.clone)(args);
829
+ return 'select' in args
830
+ ? { select: args['select'] }
831
+ : 'include' in args
832
+ ? { include: args['include'] }
833
+ : undefined;
834
+ }
835
+ makeAuxRelationName(model) {
836
+ var _a;
837
+ const name = `${constants_1.DELEGATE_AUX_RELATION_PREFIX}_${(0, lower_case_first_1.lowerCaseFirst)(model.name)}`;
838
+ // make sure we look up into short name map to see if it's truncated
839
+ const shortName = (_a = this.options.modelMeta.shortNameMap) === null || _a === void 0 ? void 0 : _a[name];
840
+ return shortName !== null && shortName !== void 0 ? shortName : name;
841
+ }
842
+ getModelName(model) {
843
+ const info = (0, cross_1.getModelInfo)(this.options.modelMeta, model, true);
844
+ return info.name;
845
+ }
846
+ getIdFields(model) {
847
+ const idFields = (0, cross_1.getIdFields)(this.options.modelMeta, model);
848
+ if (idFields && idFields.length > 0) {
849
+ return idFields;
850
+ }
851
+ const base = this.getBaseModel(model);
852
+ return base ? this.getIdFields(base.name) : [];
853
+ }
854
+ getModelInfo(model) {
855
+ return (0, cross_1.getModelInfo)(this.options.modelMeta, model, true);
856
+ }
857
+ getBaseModel(model) {
858
+ const baseNames = (0, cross_1.getModelInfo)(this.options.modelMeta, model, true).baseTypes;
859
+ if (!baseNames) {
860
+ return undefined;
861
+ }
862
+ if (baseNames.length > 1) {
863
+ throw new Error('Multi-inheritance is not supported');
864
+ }
865
+ return this.options.modelMeta.models[(0, lower_case_first_1.lowerCaseFirst)(baseNames[0])];
866
+ }
867
+ involvesDelegateModel(model, visited) {
868
+ if (this.isDelegateOrDescendantOfDelegate(model)) {
869
+ return true;
870
+ }
871
+ visited = visited !== null && visited !== void 0 ? visited : new Set();
872
+ if (visited.has(model)) {
873
+ return false;
874
+ }
875
+ visited.add(model);
876
+ const modelInfo = (0, cross_1.getModelInfo)(this.options.modelMeta, model, true);
877
+ return Object.values(modelInfo.fields).some((field) => field.isDataModel && this.involvesDelegateModel(field.type, visited));
878
+ }
879
+ isDelegateOrDescendantOfDelegate(model) {
880
+ var _a;
881
+ if ((0, cross_1.isDelegateModel)(this.options.modelMeta, model)) {
882
+ return true;
883
+ }
884
+ const baseTypes = (_a = (0, cross_1.getModelInfo)(this.options.modelMeta, model)) === null || _a === void 0 ? void 0 : _a.baseTypes;
885
+ return !!(baseTypes &&
886
+ baseTypes.length > 0 &&
887
+ baseTypes.some((base) => this.isDelegateOrDescendantOfDelegate(base)));
888
+ }
889
+ assembleHierarchy(model, entity) {
890
+ if (!entity || typeof entity !== 'object') {
891
+ return entity;
892
+ }
893
+ const upMerged = this.assembleUp(model, entity);
894
+ const downMerged = this.assembleDown(model, entity);
895
+ // https://www.npmjs.com/package/deepmerge#arraymerge-example-combine-arrays
896
+ const combineMerge = (target, source, options) => {
897
+ const destination = target.slice();
898
+ source.forEach((item, index) => {
899
+ if (typeof destination[index] === 'undefined') {
900
+ destination[index] = options.cloneUnlessOtherwiseSpecified(item, options);
901
+ }
902
+ else if (options.isMergeableObject(item)) {
903
+ destination[index] = (0, deepmerge_1.default)(target[index], item, options);
904
+ }
905
+ else if (target.indexOf(item) === -1) {
906
+ destination.push(item);
907
+ }
908
+ });
909
+ return destination;
910
+ };
911
+ const result = (0, deepmerge_1.default)(upMerged, downMerged, {
912
+ arrayMerge: combineMerge,
913
+ isMergeableObject: (v) => (0, is_plain_object_1.isPlainObject)(v) || Array.isArray(v), // avoid messing with Decimal, Date, etc.
914
+ });
915
+ return result;
916
+ }
917
+ assembleUp(model, entity) {
918
+ if (!entity) {
919
+ return entity;
920
+ }
921
+ const result = {};
922
+ const base = this.getBaseModel(model);
923
+ if (base) {
924
+ // merge base fields
925
+ const baseRelationName = this.makeAuxRelationName(base);
926
+ const baseData = entity[baseRelationName];
927
+ if (baseData && typeof baseData === 'object') {
928
+ const baseAssembled = this.assembleUp(base.name, baseData);
929
+ Object.assign(result, baseAssembled);
930
+ }
931
+ }
932
+ const modelInfo = (0, cross_1.getModelInfo)(this.options.modelMeta, model, true);
933
+ for (const [key, value] of Object.entries(entity)) {
934
+ if (key.startsWith(constants_1.DELEGATE_AUX_RELATION_PREFIX)) {
935
+ continue;
936
+ }
937
+ const field = modelInfo.fields[key];
938
+ if (!field) {
939
+ // not a field, could be `_count`, `_sum`, etc.
940
+ result[key] = value;
941
+ continue;
942
+ }
943
+ if (field.inheritedFrom) {
944
+ // already merged from base
945
+ continue;
946
+ }
947
+ if (field.isDataModel) {
948
+ if (Array.isArray(value)) {
949
+ result[field.name] = value.map((item) => this.assembleUp(field.type, item));
950
+ }
951
+ else {
952
+ result[field.name] = this.assembleUp(field.type, value);
953
+ }
954
+ }
955
+ else {
956
+ result[field.name] = value;
957
+ }
958
+ }
959
+ return result;
960
+ }
961
+ assembleDown(model, entity) {
962
+ if (!entity) {
963
+ return entity;
964
+ }
965
+ const result = {};
966
+ const modelInfo = (0, cross_1.getModelInfo)(this.options.modelMeta, model, true);
967
+ if (modelInfo.discriminator) {
968
+ // model is a delegate, merge sub model fields
969
+ const subModelName = entity[modelInfo.discriminator];
970
+ if (subModelName) {
971
+ const subModel = (0, cross_1.getModelInfo)(this.options.modelMeta, subModelName, true);
972
+ const subRelationName = this.makeAuxRelationName(subModel);
973
+ const subData = entity[subRelationName];
974
+ if (subData && typeof subData === 'object') {
975
+ const subAssembled = this.assembleDown(subModel.name, subData);
976
+ Object.assign(result, subAssembled);
977
+ }
978
+ }
979
+ }
980
+ for (const [key, value] of Object.entries(entity)) {
981
+ if (key.startsWith(constants_1.DELEGATE_AUX_RELATION_PREFIX)) {
982
+ continue;
983
+ }
984
+ const field = modelInfo.fields[key];
985
+ if (!field) {
986
+ // not a field, could be `_count`, `_sum`, etc.
987
+ result[key] = value;
988
+ continue;
989
+ }
990
+ if (field.isDataModel) {
991
+ if (Array.isArray(value)) {
992
+ result[field.name] = value.map((item) => this.assembleDown(field.type, item));
993
+ }
994
+ else {
995
+ result[field.name] = this.assembleDown(field.type, value);
996
+ }
997
+ }
998
+ else {
999
+ result[field.name] = value;
1000
+ }
1001
+ }
1002
+ return result;
1003
+ }
1004
+ }
1005
+ exports.DelegateProxyHandler = DelegateProxyHandler;
1006
+ //# sourceMappingURL=delegate.js.map