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