@zenstackhq/runtime 2.4.0 → 2.5.0
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/browser/index.js +3 -2
- package/browser/index.js.map +1 -1
- package/browser/index.mjs +3 -2
- package/browser/index.mjs.map +1 -1
- package/constants.d.ts +1 -1
- package/constants.js +1 -1
- package/constants.js.map +1 -1
- package/edge.d.ts +1 -7
- package/edge.js +1 -7
- package/edge.js.map +1 -1
- package/enhance-edge.d.ts +1 -0
- package/enhance-edge.js +10 -0
- package/enhancements/edge/create-enhancement.d.ts +37 -0
- package/enhancements/{create-enhancement.js → edge/create-enhancement.js} +2 -2
- package/enhancements/edge/create-enhancement.js.map +1 -0
- package/enhancements/{default-auth.d.ts → edge/default-auth.d.ts} +2 -1
- package/enhancements/{default-auth.js → edge/default-auth.js} +1 -1
- package/enhancements/edge/default-auth.js.map +1 -0
- package/enhancements/{delegate.d.ts → edge/delegate.d.ts} +1 -1
- package/enhancements/{delegate.js → edge/delegate.js} +16 -3
- package/enhancements/edge/delegate.js.map +1 -0
- package/enhancements/{index.d.ts → edge/index.d.ts} +1 -1
- package/enhancements/{index.js → edge/index.js} +1 -1
- package/enhancements/edge/index.js.map +1 -0
- package/enhancements/edge/logger.js.map +1 -0
- package/enhancements/{omit.js → edge/omit.js} +33 -3
- package/enhancements/edge/omit.js.map +1 -0
- package/enhancements/{password.js → edge/password.js} +2 -2
- package/enhancements/edge/password.js.map +1 -0
- package/enhancements/edge/policy/check-utils.d.ts +5 -0
- package/enhancements/edge/policy/check-utils.js +20 -0
- package/enhancements/edge/policy/check-utils.js.map +1 -0
- package/enhancements/{policy → edge/policy}/handler.d.ts +24 -9
- package/enhancements/{policy → edge/policy}/handler.js +67 -91
- package/enhancements/edge/policy/handler.js.map +1 -0
- package/enhancements/{policy → edge/policy}/index.d.ts +2 -1
- package/enhancements/{policy → edge/policy}/index.js +2 -2
- package/enhancements/edge/policy/index.js.map +1 -0
- package/enhancements/{policy → edge/policy}/policy-utils.d.ts +5 -5
- package/enhancements/{policy → edge/policy}/policy-utils.js +27 -21
- package/enhancements/edge/policy/policy-utils.js.map +1 -0
- package/enhancements/{promise.d.ts → edge/promise.d.ts} +1 -1
- package/enhancements/{promise.js → edge/promise.js} +1 -1
- package/enhancements/edge/promise.js.map +1 -0
- package/enhancements/{proxy.d.ts → edge/proxy.d.ts} +26 -9
- package/enhancements/{proxy.js → edge/proxy.js} +31 -7
- package/enhancements/edge/proxy.js.map +1 -0
- package/enhancements/{query-utils.d.ts → edge/query-utils.d.ts} +2 -2
- package/enhancements/{query-utils.js → edge/query-utils.js} +3 -4
- package/enhancements/edge/query-utils.js.map +1 -0
- package/enhancements/{types.d.ts → edge/types.d.ts} +5 -12
- package/enhancements/{types.js.map → edge/types.js.map} +1 -1
- package/enhancements/{utils.d.ts → edge/utils.d.ts} +2 -2
- package/enhancements/{utils.js → edge/utils.js} +2 -2
- package/enhancements/edge/utils.js.map +1 -0
- package/enhancements/{where-visitor.d.ts → edge/where-visitor.d.ts} +1 -1
- package/enhancements/{where-visitor.js → edge/where-visitor.js} +1 -1
- package/enhancements/edge/where-visitor.js.map +1 -0
- package/enhancements/node/create-enhancement.d.ts +37 -0
- package/enhancements/node/create-enhancement.js +79 -0
- package/enhancements/node/create-enhancement.js.map +1 -0
- package/enhancements/node/default-auth.d.ts +8 -0
- package/enhancements/node/default-auth.js +129 -0
- package/enhancements/node/default-auth.js.map +1 -0
- package/enhancements/node/delegate.d.ts +69 -0
- package/enhancements/node/delegate.js +1006 -0
- package/enhancements/node/delegate.js.map +1 -0
- package/enhancements/node/index.d.ts +4 -0
- package/enhancements/node/index.js +21 -0
- package/enhancements/node/index.js.map +1 -0
- package/enhancements/node/logger.d.ts +29 -0
- package/enhancements/node/logger.js +65 -0
- package/enhancements/node/logger.js.map +1 -0
- package/enhancements/node/omit.d.ts +7 -0
- package/enhancements/node/omit.js +93 -0
- package/enhancements/node/omit.js.map +1 -0
- package/enhancements/node/password.d.ts +7 -0
- package/enhancements/node/password.js +65 -0
- package/enhancements/node/password.js.map +1 -0
- package/enhancements/node/policy/check-utils.d.ts +5 -0
- package/enhancements/node/policy/check-utils.js +87 -0
- package/enhancements/node/policy/check-utils.js.map +1 -0
- package/enhancements/node/policy/constraint-solver.js.map +1 -0
- package/enhancements/node/policy/handler.d.ts +94 -0
- package/enhancements/node/policy/handler.js +1357 -0
- package/enhancements/node/policy/handler.js.map +1 -0
- package/enhancements/node/policy/index.d.ts +13 -0
- package/enhancements/node/policy/index.js +42 -0
- package/enhancements/node/policy/index.js.map +1 -0
- package/enhancements/node/policy/policy-utils.d.ts +184 -0
- package/enhancements/node/policy/policy-utils.js +1296 -0
- package/enhancements/node/policy/policy-utils.js.map +1 -0
- package/enhancements/node/promise.d.ts +15 -0
- package/enhancements/node/promise.js +99 -0
- package/enhancements/node/promise.js.map +1 -0
- package/enhancements/node/proxy.d.ts +118 -0
- package/enhancements/node/proxy.js +267 -0
- package/enhancements/node/proxy.js.map +1 -0
- package/enhancements/node/query-utils.d.ts +38 -0
- package/enhancements/node/query-utils.js +185 -0
- package/enhancements/node/query-utils.js.map +1 -0
- package/enhancements/node/types.d.ts +224 -0
- package/enhancements/node/types.js +3 -0
- package/enhancements/node/types.js.map +1 -0
- package/enhancements/node/utils.d.ts +11 -0
- package/enhancements/node/utils.js +49 -0
- package/enhancements/node/utils.js.map +1 -0
- package/enhancements/node/where-visitor.d.ts +32 -0
- package/enhancements/node/where-visitor.js +86 -0
- package/enhancements/node/where-visitor.js.map +1 -0
- package/index.d.ts +2 -2
- package/index.js +2 -2
- package/index.js.map +1 -1
- package/package.json +14 -6
- package/types.d.ts +62 -0
- package/enhancements/create-enhancement.d.ts +0 -78
- package/enhancements/create-enhancement.js.map +0 -1
- package/enhancements/default-auth.js.map +0 -1
- package/enhancements/delegate.js.map +0 -1
- package/enhancements/index.js.map +0 -1
- package/enhancements/logger.js.map +0 -1
- package/enhancements/omit.js.map +0 -1
- package/enhancements/password.js.map +0 -1
- package/enhancements/policy/constraint-solver.js.map +0 -1
- package/enhancements/policy/handler.js.map +0 -1
- package/enhancements/policy/index.js.map +0 -1
- package/enhancements/policy/policy-utils.js.map +0 -1
- package/enhancements/promise.js.map +0 -1
- package/enhancements/proxy.js.map +0 -1
- package/enhancements/query-utils.js.map +0 -1
- package/enhancements/utils.js.map +0 -1
- package/enhancements/where-visitor.js.map +0 -1
- /package/enhancements/{logger.d.ts → edge/logger.d.ts} +0 -0
- /package/enhancements/{logger.js → edge/logger.js} +0 -0
- /package/enhancements/{omit.d.ts → edge/omit.d.ts} +0 -0
- /package/enhancements/{password.d.ts → edge/password.d.ts} +0 -0
- /package/enhancements/{types.js → edge/types.js} +0 -0
- /package/enhancements/{policy → node/policy}/constraint-solver.d.ts +0 -0
- /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
|