@zenstackhq/runtime 2.16.0 → 3.0.0-alpha.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/LICENSE +1 -1
- package/dist/client.cjs +6094 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +19 -0
- package/dist/client.d.ts +19 -0
- package/dist/client.js +6060 -0
- package/dist/client.js.map +1 -0
- package/dist/contract-DguafRNB.d.cts +1272 -0
- package/dist/contract-DguafRNB.d.ts +1272 -0
- package/dist/index.cjs +6088 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +6057 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/policy.cjs +2343 -0
- package/dist/plugins/policy.cjs.map +1 -0
- package/dist/plugins/policy.d.cts +24 -0
- package/dist/plugins/policy.d.ts +24 -0
- package/dist/plugins/policy.js +2307 -0
- package/dist/plugins/policy.js.map +1 -0
- package/dist/schema.cjs +110 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.cts +29 -0
- package/dist/schema.d.ts +29 -0
- package/dist/schema.js +85 -0
- package/dist/schema.js.map +1 -0
- package/dist/utils/pg-utils.cjs +39 -0
- package/dist/utils/pg-utils.cjs.map +1 -0
- package/dist/utils/pg-utils.d.cts +8 -0
- package/dist/utils/pg-utils.d.ts +8 -0
- package/dist/utils/pg-utils.js +16 -0
- package/dist/utils/pg-utils.js.map +1 -0
- package/{browser/index.js → dist/utils/sqlite-utils.cjs} +21 -37
- package/dist/utils/sqlite-utils.cjs.map +1 -0
- package/dist/utils/sqlite-utils.d.cts +8 -0
- package/dist/utils/sqlite-utils.d.ts +8 -0
- package/dist/utils/sqlite-utils.js +22 -0
- package/dist/utils/sqlite-utils.js.map +1 -0
- package/package.json +106 -117
- package/README.md +0 -5
- package/browser/index.d.mts +0 -13
- package/browser/index.d.ts +0 -13
- package/browser/index.js.map +0 -1
- package/browser/index.mjs +0 -33
- package/browser/index.mjs.map +0 -1
- package/constants.d.ts +0 -62
- package/constants.js +0 -76
- package/constants.js.map +0 -1
- package/cross/index.d.mts +0 -379
- package/cross/index.d.ts +0 -379
- package/cross/index.js +0 -923
- package/cross/index.js.map +0 -1
- package/cross/index.mjs +0 -881
- package/cross/index.mjs.map +0 -1
- package/edge.d.ts +0 -1
- package/edge.js +0 -18
- package/edge.js.map +0 -1
- package/encryption/index.d.ts +0 -25
- package/encryption/index.js +0 -74
- package/encryption/index.js.map +0 -1
- package/encryption/utils.d.ts +0 -9
- package/encryption/utils.js +0 -99
- package/encryption/utils.js.map +0 -1
- package/enhance-edge.d.ts +0 -1
- package/enhance-edge.js +0 -10
- package/enhance.d.ts +0 -1
- package/enhance.js +0 -10
- package/enhancements/edge/create-enhancement.d.ts +0 -42
- package/enhancements/edge/create-enhancement.js +0 -102
- package/enhancements/edge/create-enhancement.js.map +0 -1
- package/enhancements/edge/default-auth.d.ts +0 -8
- package/enhancements/edge/default-auth.js +0 -180
- package/enhancements/edge/default-auth.js.map +0 -1
- package/enhancements/edge/delegate.d.ts +0 -77
- package/enhancements/edge/delegate.js +0 -1293
- package/enhancements/edge/delegate.js.map +0 -1
- package/enhancements/edge/encryption.d.ts +0 -7
- package/enhancements/edge/encryption.js +0 -150
- package/enhancements/edge/encryption.js.map +0 -1
- package/enhancements/edge/index.d.ts +0 -4
- package/enhancements/edge/index.js +0 -21
- package/enhancements/edge/index.js.map +0 -1
- package/enhancements/edge/json-processor.d.ts +0 -7
- package/enhancements/edge/json-processor.js +0 -89
- package/enhancements/edge/json-processor.js.map +0 -1
- package/enhancements/edge/logger.d.ts +0 -29
- package/enhancements/edge/logger.js +0 -65
- package/enhancements/edge/logger.js.map +0 -1
- package/enhancements/edge/omit.d.ts +0 -7
- package/enhancements/edge/omit.js +0 -96
- package/enhancements/edge/omit.js.map +0 -1
- package/enhancements/edge/password.d.ts +0 -7
- package/enhancements/edge/password.js +0 -64
- package/enhancements/edge/password.js.map +0 -1
- package/enhancements/edge/policy/check-utils.d.ts +0 -5
- package/enhancements/edge/policy/check-utils.js +0 -20
- package/enhancements/edge/policy/check-utils.js.map +0 -1
- package/enhancements/edge/policy/handler.d.ts +0 -100
- package/enhancements/edge/policy/handler.js +0 -1440
- package/enhancements/edge/policy/handler.js.map +0 -1
- package/enhancements/edge/policy/index.d.ts +0 -19
- package/enhancements/edge/policy/index.js +0 -65
- package/enhancements/edge/policy/index.js.map +0 -1
- package/enhancements/edge/policy/policy-utils.d.ts +0 -181
- package/enhancements/edge/policy/policy-utils.js +0 -1356
- package/enhancements/edge/policy/policy-utils.js.map +0 -1
- package/enhancements/edge/promise.d.ts +0 -15
- package/enhancements/edge/promise.js +0 -99
- package/enhancements/edge/promise.js.map +0 -1
- package/enhancements/edge/proxy.d.ts +0 -120
- package/enhancements/edge/proxy.js +0 -287
- package/enhancements/edge/proxy.js.map +0 -1
- package/enhancements/edge/query-utils.d.ts +0 -53
- package/enhancements/edge/query-utils.js +0 -256
- package/enhancements/edge/query-utils.js.map +0 -1
- package/enhancements/edge/types.d.ts +0 -238
- package/enhancements/edge/types.js +0 -3
- package/enhancements/edge/types.js.map +0 -1
- package/enhancements/edge/utils.d.ts +0 -11
- package/enhancements/edge/utils.js +0 -49
- package/enhancements/edge/utils.js.map +0 -1
- package/enhancements/edge/where-visitor.d.ts +0 -32
- package/enhancements/edge/where-visitor.js +0 -86
- package/enhancements/edge/where-visitor.js.map +0 -1
- package/enhancements/node/create-enhancement.d.ts +0 -42
- package/enhancements/node/create-enhancement.js +0 -102
- package/enhancements/node/create-enhancement.js.map +0 -1
- package/enhancements/node/default-auth.d.ts +0 -8
- package/enhancements/node/default-auth.js +0 -180
- package/enhancements/node/default-auth.js.map +0 -1
- package/enhancements/node/delegate.d.ts +0 -77
- package/enhancements/node/delegate.js +0 -1293
- package/enhancements/node/delegate.js.map +0 -1
- package/enhancements/node/encryption.d.ts +0 -7
- package/enhancements/node/encryption.js +0 -150
- package/enhancements/node/encryption.js.map +0 -1
- package/enhancements/node/index.d.ts +0 -4
- package/enhancements/node/index.js +0 -21
- package/enhancements/node/index.js.map +0 -1
- package/enhancements/node/json-processor.d.ts +0 -7
- package/enhancements/node/json-processor.js +0 -89
- package/enhancements/node/json-processor.js.map +0 -1
- package/enhancements/node/logger.d.ts +0 -29
- package/enhancements/node/logger.js +0 -65
- package/enhancements/node/logger.js.map +0 -1
- package/enhancements/node/omit.d.ts +0 -7
- package/enhancements/node/omit.js +0 -96
- package/enhancements/node/omit.js.map +0 -1
- package/enhancements/node/password.d.ts +0 -7
- package/enhancements/node/password.js +0 -64
- package/enhancements/node/password.js.map +0 -1
- package/enhancements/node/policy/check-utils.d.ts +0 -5
- package/enhancements/node/policy/check-utils.js +0 -87
- package/enhancements/node/policy/check-utils.js.map +0 -1
- package/enhancements/node/policy/constraint-solver.d.ts +0 -27
- package/enhancements/node/policy/constraint-solver.js +0 -164
- package/enhancements/node/policy/constraint-solver.js.map +0 -1
- package/enhancements/node/policy/handler.d.ts +0 -100
- package/enhancements/node/policy/handler.js +0 -1440
- package/enhancements/node/policy/handler.js.map +0 -1
- package/enhancements/node/policy/index.d.ts +0 -19
- package/enhancements/node/policy/index.js +0 -65
- package/enhancements/node/policy/index.js.map +0 -1
- package/enhancements/node/policy/policy-utils.d.ts +0 -181
- package/enhancements/node/policy/policy-utils.js +0 -1356
- package/enhancements/node/policy/policy-utils.js.map +0 -1
- package/enhancements/node/promise.d.ts +0 -15
- package/enhancements/node/promise.js +0 -99
- package/enhancements/node/promise.js.map +0 -1
- package/enhancements/node/proxy.d.ts +0 -120
- package/enhancements/node/proxy.js +0 -287
- package/enhancements/node/proxy.js.map +0 -1
- package/enhancements/node/query-utils.d.ts +0 -53
- package/enhancements/node/query-utils.js +0 -256
- package/enhancements/node/query-utils.js.map +0 -1
- package/enhancements/node/types.d.ts +0 -238
- package/enhancements/node/types.js +0 -3
- package/enhancements/node/types.js.map +0 -1
- package/enhancements/node/utils.d.ts +0 -11
- package/enhancements/node/utils.js +0 -49
- package/enhancements/node/utils.js.map +0 -1
- package/enhancements/node/where-visitor.d.ts +0 -32
- package/enhancements/node/where-visitor.js +0 -86
- package/enhancements/node/where-visitor.js.map +0 -1
- package/error.d.ts +0 -11
- package/error.js +0 -22
- package/error.js.map +0 -1
- package/index.d.ts +0 -7
- package/index.js +0 -24
- package/index.js.map +0 -1
- package/local-helpers/index.d.ts +0 -6
- package/local-helpers/index.js +0 -23
- package/local-helpers/index.js.map +0 -1
- package/local-helpers/is-plain-object.d.ts +0 -1
- package/local-helpers/is-plain-object.js +0 -25
- package/local-helpers/is-plain-object.js.map +0 -1
- package/local-helpers/lower-case-first.d.ts +0 -1
- package/local-helpers/lower-case-first.js +0 -7
- package/local-helpers/lower-case-first.js.map +0 -1
- package/local-helpers/param-case.d.ts +0 -1
- package/local-helpers/param-case.js +0 -20
- package/local-helpers/param-case.js.map +0 -1
- package/local-helpers/sleep.d.ts +0 -1
- package/local-helpers/sleep.js +0 -9
- package/local-helpers/sleep.js.map +0 -1
- package/local-helpers/tiny-invariant.d.ts +0 -1
- package/local-helpers/tiny-invariant.js +0 -15
- package/local-helpers/tiny-invariant.js.map +0 -1
- package/local-helpers/upper-case-first.d.ts +0 -1
- package/local-helpers/upper-case-first.js +0 -7
- package/local-helpers/upper-case-first.js.map +0 -1
- package/model-meta.d.ts +0 -1
- package/model-meta.js +0 -10
- package/models.d.ts +0 -1
- package/models.js +0 -1
- package/types.d.ts +0 -200
- package/types.js +0 -4
- package/types.js.map +0 -1
- package/validation.d.ts +0 -24
- package/validation.js +0 -52
- package/validation.js.map +0 -1
- package/version.d.ts +0 -5
- package/version.js +0 -35
- package/version.js.map +0 -1
- package/zod/index.d.ts +0 -3
- package/zod/index.js +0 -5
- package/zod/input.d.ts +0 -1
- package/zod/input.js +0 -8
- package/zod/models.d.ts +0 -1
- package/zod/models.js +0 -8
- package/zod/objects.d.ts +0 -1
- package/zod/objects.js +0 -8
- package/zod-utils.d.ts +0 -12
- package/zod-utils.js +0 -97
- package/zod-utils.js.map +0 -1
|
@@ -1,1293 +0,0 @@
|
|
|
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 traverse_1 = __importDefault(require("traverse"));
|
|
20
|
-
const constants_1 = require("../../constants");
|
|
21
|
-
const cross_1 = require("../../cross");
|
|
22
|
-
const local_helpers_1 = require("../../local-helpers");
|
|
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, context) {
|
|
28
|
-
return (0, proxy_1.makeProxy)(prisma, options.modelMeta, (_prisma, model) => new DelegateProxyHandler(_prisma, model, options, context), 'delegate');
|
|
29
|
-
}
|
|
30
|
-
class DelegateProxyHandler extends proxy_1.DefaultPrismaProxyHandler {
|
|
31
|
-
constructor(prisma, model, options, context) {
|
|
32
|
-
super(prisma, model, options);
|
|
33
|
-
this.context = context;
|
|
34
|
-
this.logger = new logger_1.Logger(prisma);
|
|
35
|
-
this.queryUtils = new query_utils_1.QueryUtils(prisma, this.options);
|
|
36
|
-
}
|
|
37
|
-
// #region find
|
|
38
|
-
findFirst(args) {
|
|
39
|
-
return this.doFind(this.prisma, this.model, 'findFirst', args);
|
|
40
|
-
}
|
|
41
|
-
findFirstOrThrow(args) {
|
|
42
|
-
return this.doFind(this.prisma, this.model, 'findFirstOrThrow', args);
|
|
43
|
-
}
|
|
44
|
-
findUnique(args) {
|
|
45
|
-
return this.doFind(this.prisma, this.model, 'findUnique', args);
|
|
46
|
-
}
|
|
47
|
-
findUniqueOrThrow(args) {
|
|
48
|
-
return this.doFind(this.prisma, this.model, 'findUniqueOrThrow', args);
|
|
49
|
-
}
|
|
50
|
-
findMany(args) {
|
|
51
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
-
return this.doFind(this.prisma, this.model, 'findMany', args);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
doFind(db, model, method, args) {
|
|
56
|
-
const _superIndex = name => super[name];
|
|
57
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
-
if (!this.involvesDelegateModel(model)) {
|
|
59
|
-
return _superIndex(method).call(this, args);
|
|
60
|
-
}
|
|
61
|
-
args = args ? (0, cross_1.clone)(args) : {};
|
|
62
|
-
this.injectWhereHierarchy(model, args === null || args === void 0 ? void 0 : args.where);
|
|
63
|
-
yield this.injectSelectIncludeHierarchy(model, args);
|
|
64
|
-
// discriminator field is needed during post process to determine the
|
|
65
|
-
// actual concrete model type
|
|
66
|
-
this.ensureDiscriminatorSelection(model, args);
|
|
67
|
-
if (args.orderBy) {
|
|
68
|
-
// `orderBy` may contain fields from base types
|
|
69
|
-
(0, cross_1.enumerate)(args.orderBy).forEach((item) => this.injectWhereHierarchy(model, item));
|
|
70
|
-
}
|
|
71
|
-
if (this.options.logPrismaQuery) {
|
|
72
|
-
this.logger.info(`[delegate] \`${method}\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
|
|
73
|
-
}
|
|
74
|
-
const entity = yield db[model][method](args);
|
|
75
|
-
if (Array.isArray(entity)) {
|
|
76
|
-
return entity.map((item) => this.assembleHierarchy(model, item));
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
return this.assembleHierarchy(model, entity);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
ensureDiscriminatorSelection(model, args) {
|
|
84
|
-
const modelInfo = (0, cross_1.getModelInfo)(this.options.modelMeta, model);
|
|
85
|
-
if (!(modelInfo === null || modelInfo === void 0 ? void 0 : modelInfo.discriminator)) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
if (args.select && typeof args.select === 'object') {
|
|
89
|
-
args.select[modelInfo.discriminator] = true;
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
if (args.omit && typeof args.omit === 'object') {
|
|
93
|
-
args.omit[modelInfo.discriminator] = false;
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
injectWhereHierarchy(model, where) {
|
|
98
|
-
if (!where || !(0, local_helpers_1.isPlainObject)(where)) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
Object.entries(where).forEach(([field, value]) => {
|
|
102
|
-
if (['AND', 'OR', 'NOT'].includes(field)) {
|
|
103
|
-
// recurse into logical group
|
|
104
|
-
(0, cross_1.enumerate)(value).forEach((item) => this.injectWhereHierarchy(model, item));
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);
|
|
108
|
-
if (!(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom)) {
|
|
109
|
-
// not an inherited field, inject and continue
|
|
110
|
-
if (fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.isDataModel) {
|
|
111
|
-
this.injectWhereHierarchy(fieldInfo.type, value);
|
|
112
|
-
}
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
let base = this.getBaseModel(model);
|
|
116
|
-
let target = where;
|
|
117
|
-
while (base) {
|
|
118
|
-
const baseRelationName = this.makeAuxRelationName(base);
|
|
119
|
-
// prepare base layer where
|
|
120
|
-
let thisLayer;
|
|
121
|
-
if (target[baseRelationName]) {
|
|
122
|
-
thisLayer = target[baseRelationName];
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
thisLayer = target[baseRelationName] = {};
|
|
126
|
-
}
|
|
127
|
-
if (base.name === fieldInfo.inheritedFrom) {
|
|
128
|
-
if (fieldInfo.isDataModel) {
|
|
129
|
-
this.injectWhereHierarchy(base.name, value);
|
|
130
|
-
}
|
|
131
|
-
thisLayer[field] = value;
|
|
132
|
-
delete where[field];
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
target = thisLayer;
|
|
137
|
-
base = this.getBaseModel(base.name);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
injectSelectIncludeHierarchy(model, args) {
|
|
143
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
144
|
-
if (!args || typeof args !== 'object') {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
// there're two cases where we need to inject polymorphic base hierarchy for fields
|
|
148
|
-
// defined in base models
|
|
149
|
-
// 1. base fields mentioned in select/include clause
|
|
150
|
-
// { select: { fieldFromBase: true } } => { select: { delegate_aux_[Base]: { fieldFromBase: true } } }
|
|
151
|
-
// 2. base fields mentioned in _count select/include clause
|
|
152
|
-
// { select: { _count: { select: { fieldFromBase: true } } } } => { select: { delegate_aux_[Base]: { select: { _count: { select: { fieldFromBase: true } } } } } }
|
|
153
|
-
//
|
|
154
|
-
// Note that although structurally similar, we need to correctly deal with different injection location of the "delegate_aux" hierarchy
|
|
155
|
-
// selectors for the above two cases
|
|
156
|
-
const selectors = [
|
|
157
|
-
// regular select: { select: { field: true } }
|
|
158
|
-
(payload) => ({ data: payload.select, kind: 'select', isCount: false }),
|
|
159
|
-
// regular include: { include: { field: true } }
|
|
160
|
-
(payload) => ({ data: payload.include, kind: 'include', isCount: false }),
|
|
161
|
-
// select _count: { select: { _count: { select: { field: true } } } }
|
|
162
|
-
(payload) => {
|
|
163
|
-
var _a, _b;
|
|
164
|
-
return ({
|
|
165
|
-
data: (_b = (_a = payload.select) === null || _a === void 0 ? void 0 : _a._count) === null || _b === void 0 ? void 0 : _b.select,
|
|
166
|
-
kind: 'select',
|
|
167
|
-
isCount: true,
|
|
168
|
-
});
|
|
169
|
-
},
|
|
170
|
-
// include _count: { include: { _count: { select: { field: true } } } }
|
|
171
|
-
(payload) => {
|
|
172
|
-
var _a, _b;
|
|
173
|
-
return ({
|
|
174
|
-
data: (_b = (_a = payload.include) === null || _a === void 0 ? void 0 : _a._count) === null || _b === void 0 ? void 0 : _b.select,
|
|
175
|
-
kind: 'include',
|
|
176
|
-
isCount: true,
|
|
177
|
-
});
|
|
178
|
-
},
|
|
179
|
-
];
|
|
180
|
-
for (const selector of selectors) {
|
|
181
|
-
const { data, kind, isCount } = selector(args);
|
|
182
|
-
if (!data || typeof data !== 'object') {
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
for (const [field, value] of Object.entries(data)) {
|
|
186
|
-
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);
|
|
187
|
-
if (!fieldInfo) {
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
if (this.isDelegateOrDescendantOfDelegate(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.type) && value) {
|
|
191
|
-
// delegate model, recursively inject hierarchy
|
|
192
|
-
if (data[field]) {
|
|
193
|
-
if (data[field] === true) {
|
|
194
|
-
// make sure the payload is an object
|
|
195
|
-
data[field] = {};
|
|
196
|
-
}
|
|
197
|
-
yield this.injectSelectIncludeHierarchy(fieldInfo.type, data[field]);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
// refetch the field select/include value because it may have been
|
|
201
|
-
// updated during injection
|
|
202
|
-
const fieldValue = data[field];
|
|
203
|
-
if (fieldValue !== undefined) {
|
|
204
|
-
if (fieldValue.orderBy) {
|
|
205
|
-
// `orderBy` may contain fields from base types
|
|
206
|
-
(0, cross_1.enumerate)(fieldValue.orderBy).forEach((item) => this.injectWhereHierarchy(fieldInfo.type, item));
|
|
207
|
-
}
|
|
208
|
-
let injected = false;
|
|
209
|
-
if (!isCount) {
|
|
210
|
-
// regular select/include injection
|
|
211
|
-
injected = yield this.injectBaseFieldSelect(model, field, fieldValue, args, kind);
|
|
212
|
-
if (injected) {
|
|
213
|
-
// if injected, remove the field from the original payload
|
|
214
|
-
delete data[field];
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
// _count select/include injection, inject into an empty payload and then merge to the proper location
|
|
219
|
-
const injectTarget = { [kind]: {} };
|
|
220
|
-
injected = yield this.injectBaseFieldSelect(model, field, fieldValue, injectTarget, kind, true);
|
|
221
|
-
if (injected) {
|
|
222
|
-
// if injected, remove the field from the original payload
|
|
223
|
-
delete data[field];
|
|
224
|
-
if (Object.keys(data).length === 0) {
|
|
225
|
-
// if the original "_count" payload becomes empty, remove it
|
|
226
|
-
delete args[kind]['_count'];
|
|
227
|
-
}
|
|
228
|
-
// finally merge the injection into the original payload
|
|
229
|
-
const merged = (0, deepmerge_1.default)(args[kind], injectTarget[kind]);
|
|
230
|
-
args[kind] = merged;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
if (!injected && fieldInfo.isDataModel) {
|
|
234
|
-
let nextValue = fieldValue;
|
|
235
|
-
if (nextValue === true) {
|
|
236
|
-
// make sure the payload is an object
|
|
237
|
-
data[field] = nextValue = {};
|
|
238
|
-
}
|
|
239
|
-
yield this.injectSelectIncludeHierarchy(fieldInfo.type, nextValue);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
if (!args.select) {
|
|
245
|
-
// include base models upwards
|
|
246
|
-
this.injectBaseIncludeRecursively(model, args);
|
|
247
|
-
// include sub models downwards
|
|
248
|
-
yield this.injectConcreteIncludeRecursively(model, args);
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
buildSelectIncludeHierarchy(model_1, args_1) {
|
|
253
|
-
return __awaiter(this, arguments, void 0, function* (model, args, includeConcreteFields = true) {
|
|
254
|
-
args = (0, cross_1.clone)(args);
|
|
255
|
-
const selectInclude = this.extractSelectInclude(args) || {};
|
|
256
|
-
if (selectInclude.select && typeof selectInclude.select === 'object') {
|
|
257
|
-
Object.entries(selectInclude.select).forEach(([field, value]) => {
|
|
258
|
-
if (value) {
|
|
259
|
-
if (this.injectBaseFieldSelect(model, field, value, selectInclude, 'select')) {
|
|
260
|
-
delete selectInclude.select[field];
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
else if (selectInclude.include && typeof selectInclude.include === 'object') {
|
|
266
|
-
Object.entries(selectInclude.include).forEach(([field, value]) => {
|
|
267
|
-
if (value) {
|
|
268
|
-
if (this.injectBaseFieldSelect(model, field, value, selectInclude, 'include')) {
|
|
269
|
-
delete selectInclude.include[field];
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
if (!selectInclude.select) {
|
|
275
|
-
this.injectBaseIncludeRecursively(model, selectInclude);
|
|
276
|
-
if (includeConcreteFields) {
|
|
277
|
-
yield this.injectConcreteIncludeRecursively(model, selectInclude);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
return selectInclude;
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
injectBaseFieldSelect(model, field, value, selectInclude, context, forCount = false // if the injection is for a "{ _count: { select: { field: true } } }" payload
|
|
284
|
-
) {
|
|
285
|
-
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);
|
|
286
|
-
if (!(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom)) {
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
let base = this.getBaseModel(model);
|
|
290
|
-
let target = selectInclude;
|
|
291
|
-
while (base) {
|
|
292
|
-
const baseRelationName = this.makeAuxRelationName(base);
|
|
293
|
-
// prepare base layer select/include
|
|
294
|
-
let thisLayer;
|
|
295
|
-
if (target.include) {
|
|
296
|
-
thisLayer = target.include;
|
|
297
|
-
}
|
|
298
|
-
else if (target.select) {
|
|
299
|
-
thisLayer = target.select;
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
thisLayer = target.select = {};
|
|
303
|
-
}
|
|
304
|
-
if (base.name === fieldInfo.inheritedFrom) {
|
|
305
|
-
if (!thisLayer[baseRelationName]) {
|
|
306
|
-
thisLayer[baseRelationName] = { [context]: {} };
|
|
307
|
-
}
|
|
308
|
-
if (forCount) {
|
|
309
|
-
// { _count: { select: { field: true } } } => { delegate_aux_[Base]: { select: { _count: { select: { field: true } } } } }
|
|
310
|
-
if (!thisLayer[baseRelationName][context]['_count'] ||
|
|
311
|
-
typeof thisLayer[baseRelationName][context] !== 'object') {
|
|
312
|
-
thisLayer[baseRelationName][context]['_count'] = {};
|
|
313
|
-
}
|
|
314
|
-
thisLayer[baseRelationName][context]['_count'] = (0, deepmerge_1.default)(thisLayer[baseRelationName][context]['_count'], { select: { [field]: value } });
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
// { select: { field: true } } => { delegate_aux_[Base]: { select: { field: true } } }
|
|
318
|
-
thisLayer[baseRelationName][context][field] = value;
|
|
319
|
-
}
|
|
320
|
-
break;
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
if (!thisLayer[baseRelationName]) {
|
|
324
|
-
thisLayer[baseRelationName] = { select: {} };
|
|
325
|
-
}
|
|
326
|
-
target = thisLayer[baseRelationName];
|
|
327
|
-
base = this.getBaseModel(base.name);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
return true;
|
|
331
|
-
}
|
|
332
|
-
injectBaseIncludeRecursively(model, selectInclude) {
|
|
333
|
-
const base = this.getBaseModel(model);
|
|
334
|
-
if (!base) {
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
const baseRelationName = this.makeAuxRelationName(base);
|
|
338
|
-
if (selectInclude.select) {
|
|
339
|
-
selectInclude.include = Object.assign({ [baseRelationName]: {} }, selectInclude.select);
|
|
340
|
-
delete selectInclude.select;
|
|
341
|
-
}
|
|
342
|
-
else {
|
|
343
|
-
selectInclude.include = Object.assign({ [baseRelationName]: {} }, selectInclude.include);
|
|
344
|
-
}
|
|
345
|
-
this.injectBaseIncludeRecursively(base.name, selectInclude.include[baseRelationName]);
|
|
346
|
-
}
|
|
347
|
-
injectConcreteIncludeRecursively(model, selectInclude) {
|
|
348
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
349
|
-
const modelInfo = (0, cross_1.getModelInfo)(this.options.modelMeta, model);
|
|
350
|
-
if (!modelInfo) {
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
// get sub models of this model
|
|
354
|
-
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); });
|
|
355
|
-
for (const subModel of subModels) {
|
|
356
|
-
// include sub model relation field
|
|
357
|
-
const subRelationName = this.makeAuxRelationName(subModel);
|
|
358
|
-
// create a payload to include the sub model relation
|
|
359
|
-
const includePayload = yield this.createConcreteRelationIncludePayload(subModel.name);
|
|
360
|
-
if (selectInclude.select) {
|
|
361
|
-
selectInclude.include = Object.assign({ [subRelationName]: includePayload }, selectInclude.select);
|
|
362
|
-
delete selectInclude.select;
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
selectInclude.include = Object.assign({ [subRelationName]: includePayload }, selectInclude.include);
|
|
366
|
-
}
|
|
367
|
-
yield this.injectConcreteIncludeRecursively(subModel.name, selectInclude.include[subRelationName]);
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
createConcreteRelationIncludePayload(model) {
|
|
372
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
373
|
-
let result = {};
|
|
374
|
-
if (this.options.processIncludeRelationPayload) {
|
|
375
|
-
// use the callback in options to process the include payload, so enhancements
|
|
376
|
-
// like 'policy' can do extra work (e.g., inject policy rules)
|
|
377
|
-
// TODO: this causes both delegate base's policy rules and concrete model's rules to be injected,
|
|
378
|
-
// which is not wrong but redundant
|
|
379
|
-
yield this.options.processIncludeRelationPayload(this.prisma, model, result, this.options, this.context);
|
|
380
|
-
const properSelectIncludeHierarchy = yield this.buildSelectIncludeHierarchy(model, result, false);
|
|
381
|
-
result = Object.assign(Object.assign({}, result), properSelectIncludeHierarchy);
|
|
382
|
-
}
|
|
383
|
-
return result;
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
// #endregion
|
|
387
|
-
// #region create
|
|
388
|
-
create(args) {
|
|
389
|
-
const _super = Object.create(null, {
|
|
390
|
-
create: { get: () => super.create }
|
|
391
|
-
});
|
|
392
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
393
|
-
if (!args) {
|
|
394
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
|
|
395
|
-
}
|
|
396
|
-
if (!args.data) {
|
|
397
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'data field is required in query argument');
|
|
398
|
-
}
|
|
399
|
-
this.sanitizeMutationPayload(args.data);
|
|
400
|
-
if ((0, cross_1.isDelegateModel)(this.options.modelMeta, this.model)) {
|
|
401
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `Model "${this.model}" is a delegate and cannot be created directly`);
|
|
402
|
-
}
|
|
403
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
404
|
-
return _super.create.call(this, args);
|
|
405
|
-
}
|
|
406
|
-
return this.doCreate(this.prisma, this.model, args);
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
sanitizeMutationPayload(data) {
|
|
410
|
-
if (!data) {
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
const prisma = this.prisma;
|
|
414
|
-
const prismaModule = this.options.prismaModule;
|
|
415
|
-
(0, traverse_1.default)(data).forEach(function () {
|
|
416
|
-
var _a;
|
|
417
|
-
if ((_a = this.key) === null || _a === void 0 ? void 0 : _a.startsWith(constants_1.DELEGATE_AUX_RELATION_PREFIX)) {
|
|
418
|
-
throw (0, utils_1.prismaClientValidationError)(prisma, prismaModule, `Auxiliary relation field "${this.key}" cannot be set directly`);
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
createMany(args) {
|
|
423
|
-
if (!args) {
|
|
424
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
|
|
425
|
-
}
|
|
426
|
-
if (!args.data) {
|
|
427
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'data field is required in query argument');
|
|
428
|
-
}
|
|
429
|
-
this.sanitizeMutationPayload(args.data);
|
|
430
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
431
|
-
return super.createMany(args);
|
|
432
|
-
}
|
|
433
|
-
if (this.isDelegateOrDescendantOfDelegate(this.model) && args.skipDuplicates) {
|
|
434
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, '`createMany` with `skipDuplicates` set to true is not supported for delegated models');
|
|
435
|
-
}
|
|
436
|
-
// `createMany` doesn't support nested create, which is needed for creating entities
|
|
437
|
-
// inheriting a delegate base, so we need to convert it to a regular `create` here.
|
|
438
|
-
// Note that the main difference is `create` doesn't support `skipDuplicates` as
|
|
439
|
-
// `createMany` does.
|
|
440
|
-
return this.queryUtils.transaction(this.prisma, (tx) => __awaiter(this, void 0, void 0, function* () {
|
|
441
|
-
const r = yield Promise.all((0, cross_1.enumerate)(args.data).map((item) => __awaiter(this, void 0, void 0, function* () {
|
|
442
|
-
return this.doCreate(tx, this.model, { data: item });
|
|
443
|
-
})));
|
|
444
|
-
return { count: r.length };
|
|
445
|
-
}));
|
|
446
|
-
}
|
|
447
|
-
createManyAndReturn(args) {
|
|
448
|
-
if (!args) {
|
|
449
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
|
|
450
|
-
}
|
|
451
|
-
if (!args.data) {
|
|
452
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'data field is required in query argument');
|
|
453
|
-
}
|
|
454
|
-
this.sanitizeMutationPayload(args.data);
|
|
455
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
456
|
-
return super.createManyAndReturn(args);
|
|
457
|
-
}
|
|
458
|
-
if (this.isDelegateOrDescendantOfDelegate(this.model) && args.skipDuplicates) {
|
|
459
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, '`createManyAndReturn` with `skipDuplicates` set to true is not supported for delegated models');
|
|
460
|
-
}
|
|
461
|
-
// `createManyAndReturn` doesn't support nested create, which is needed for creating entities
|
|
462
|
-
// inheriting a delegate base, so we need to convert it to a regular `create` here.
|
|
463
|
-
// Note that the main difference is `create` doesn't support `skipDuplicates` as
|
|
464
|
-
// `createManyAndReturn` does.
|
|
465
|
-
return this.queryUtils.transaction(this.prisma, (tx) => __awaiter(this, void 0, void 0, function* () {
|
|
466
|
-
const r = yield Promise.all((0, cross_1.enumerate)(args.data).map((item) => __awaiter(this, void 0, void 0, function* () {
|
|
467
|
-
return this.doCreate(tx, this.model, { data: item, select: args.select });
|
|
468
|
-
})));
|
|
469
|
-
return r;
|
|
470
|
-
}));
|
|
471
|
-
}
|
|
472
|
-
doCreate(db, model, args) {
|
|
473
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
474
|
-
args = (0, cross_1.clone)(args);
|
|
475
|
-
yield this.injectCreateHierarchy(model, args);
|
|
476
|
-
yield this.injectSelectIncludeHierarchy(model, args);
|
|
477
|
-
if (this.options.logPrismaQuery) {
|
|
478
|
-
this.logger.info(`[delegate] \`create\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
|
|
479
|
-
}
|
|
480
|
-
const result = yield db[model].create(args);
|
|
481
|
-
return this.assembleHierarchy(model, result);
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
injectCreateHierarchy(model, args) {
|
|
485
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
486
|
-
const visitor = new cross_1.NestedWriteVisitor(this.options.modelMeta, {
|
|
487
|
-
create: (model, args, _context) => {
|
|
488
|
-
this.doProcessCreatePayload(model, args);
|
|
489
|
-
},
|
|
490
|
-
createMany: (model, args, context) => {
|
|
491
|
-
// `createMany` doesn't support nested create, which is needed for creating entities
|
|
492
|
-
// inheriting a delegate base, so we need to convert it to a regular `create` here.
|
|
493
|
-
// Note that the main difference is `create` doesn't support `skipDuplicates` as
|
|
494
|
-
// `createMany` does.
|
|
495
|
-
var _a;
|
|
496
|
-
if (this.isDelegateOrDescendantOfDelegate(model)) {
|
|
497
|
-
if (args.skipDuplicates) {
|
|
498
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, '`createMany` with `skipDuplicates` set to true is not supported for delegated models');
|
|
499
|
-
}
|
|
500
|
-
// convert to regular `create`
|
|
501
|
-
let createPayload = (_a = context.parent.create) !== null && _a !== void 0 ? _a : [];
|
|
502
|
-
if (!Array.isArray(createPayload)) {
|
|
503
|
-
createPayload = [createPayload];
|
|
504
|
-
}
|
|
505
|
-
for (const item of (0, cross_1.enumerate)(args.data)) {
|
|
506
|
-
this.doProcessCreatePayload(model, item);
|
|
507
|
-
createPayload.push(item);
|
|
508
|
-
}
|
|
509
|
-
context.parent.create = createPayload;
|
|
510
|
-
delete context.parent['createMany'];
|
|
511
|
-
}
|
|
512
|
-
},
|
|
513
|
-
});
|
|
514
|
-
yield visitor.visit(model, 'create', args);
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
doProcessCreatePayload(model, args) {
|
|
518
|
-
if (!args) {
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
this.ensureBaseCreateHierarchy(model, args);
|
|
522
|
-
for (const [field, value] of Object.entries(args)) {
|
|
523
|
-
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);
|
|
524
|
-
if (fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom) {
|
|
525
|
-
this.injectBaseFieldData(model, fieldInfo, value, args, 'create');
|
|
526
|
-
delete args[field];
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
// ensure the full nested "create" structure is created for base types
|
|
531
|
-
ensureBaseCreateHierarchy(model, args) {
|
|
532
|
-
let curr = args;
|
|
533
|
-
let base = this.getBaseModel(model);
|
|
534
|
-
let sub = this.getModelInfo(model);
|
|
535
|
-
const hasDelegateBase = !!base;
|
|
536
|
-
while (base) {
|
|
537
|
-
const baseRelationName = this.makeAuxRelationName(base);
|
|
538
|
-
if (!curr[baseRelationName]) {
|
|
539
|
-
curr[baseRelationName] = {};
|
|
540
|
-
}
|
|
541
|
-
if (!curr[baseRelationName].create) {
|
|
542
|
-
curr[baseRelationName].create = {};
|
|
543
|
-
if (base.discriminator) {
|
|
544
|
-
// set discriminator field
|
|
545
|
-
curr[baseRelationName].create[base.discriminator] = sub.name;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
// Look for base id field assignments in the current level, and push
|
|
549
|
-
// them down to the base level
|
|
550
|
-
for (const idField of (0, cross_1.getIdFields)(this.options.modelMeta, base.name)) {
|
|
551
|
-
if (curr[idField.name] !== undefined) {
|
|
552
|
-
curr[baseRelationName].create[idField.name] = curr[idField.name];
|
|
553
|
-
delete curr[idField.name];
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
curr = curr[baseRelationName].create;
|
|
557
|
-
sub = base;
|
|
558
|
-
base = this.getBaseModel(base.name);
|
|
559
|
-
}
|
|
560
|
-
if (hasDelegateBase) {
|
|
561
|
-
// A delegate base model creation is added, this can be incompatible if
|
|
562
|
-
// the user-provided payload assigns foreign keys directly, because Prisma
|
|
563
|
-
// doesn't permit mixed "checked" and "unchecked" fields in a payload.
|
|
564
|
-
//
|
|
565
|
-
// {
|
|
566
|
-
// delegate_aux_base: { ... },
|
|
567
|
-
// [fkField]: value // <- this is not compatible
|
|
568
|
-
// }
|
|
569
|
-
//
|
|
570
|
-
// We need to convert foreign key assignments to `connect`.
|
|
571
|
-
this.fkAssignmentToConnect(model, args);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
// convert foreign key assignments to `connect` payload
|
|
575
|
-
// e.g.: { authorId: value } -> { author: { connect: { id: value } } }
|
|
576
|
-
fkAssignmentToConnect(model, args) {
|
|
577
|
-
const keysToDelete = [];
|
|
578
|
-
for (const [key, value] of Object.entries(args)) {
|
|
579
|
-
if (value === undefined) {
|
|
580
|
-
continue;
|
|
581
|
-
}
|
|
582
|
-
const fieldInfo = this.queryUtils.getModelField(model, key);
|
|
583
|
-
if (!(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom) && // fields from delegate base are handled outside
|
|
584
|
-
(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.isForeignKey)) {
|
|
585
|
-
const relationInfo = this.queryUtils.getRelationForForeignKey(model, key);
|
|
586
|
-
if (relationInfo) {
|
|
587
|
-
// turn { [fk]: value } into { [relation]: { connect: { [id]: value } } }
|
|
588
|
-
const relationName = relationInfo.relation.name;
|
|
589
|
-
if (!args[relationName]) {
|
|
590
|
-
args[relationName] = {};
|
|
591
|
-
}
|
|
592
|
-
if (!args[relationName].connect) {
|
|
593
|
-
args[relationName].connect = {};
|
|
594
|
-
}
|
|
595
|
-
if (!(relationInfo.idField in args[relationName].connect)) {
|
|
596
|
-
args[relationName].connect[relationInfo.idField] = value;
|
|
597
|
-
keysToDelete.push(key);
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
keysToDelete.forEach((key) => delete args[key]);
|
|
603
|
-
}
|
|
604
|
-
// inject field data that belongs to base type into proper nesting structure
|
|
605
|
-
injectBaseFieldData(model, fieldInfo, value, args, mode) {
|
|
606
|
-
let base = this.getBaseModel(model);
|
|
607
|
-
let curr = args;
|
|
608
|
-
while (base) {
|
|
609
|
-
if (base.discriminator === fieldInfo.name) {
|
|
610
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `fields "${fieldInfo.name}" is a discriminator and cannot be set directly`);
|
|
611
|
-
}
|
|
612
|
-
const baseRelationName = this.makeAuxRelationName(base);
|
|
613
|
-
if (!curr[baseRelationName]) {
|
|
614
|
-
curr[baseRelationName] = {};
|
|
615
|
-
}
|
|
616
|
-
if (!curr[baseRelationName][mode]) {
|
|
617
|
-
curr[baseRelationName][mode] = {};
|
|
618
|
-
}
|
|
619
|
-
curr = curr[baseRelationName][mode];
|
|
620
|
-
if (fieldInfo.inheritedFrom === base.name) {
|
|
621
|
-
curr[fieldInfo.name] = value;
|
|
622
|
-
break;
|
|
623
|
-
}
|
|
624
|
-
base = this.getBaseModel(base.name);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
// #endregion
|
|
628
|
-
// #region update
|
|
629
|
-
update(args) {
|
|
630
|
-
if (!args) {
|
|
631
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
|
|
632
|
-
}
|
|
633
|
-
if (!args.data) {
|
|
634
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'data field is required in query argument');
|
|
635
|
-
}
|
|
636
|
-
this.sanitizeMutationPayload(args.data);
|
|
637
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
638
|
-
return super.update(args);
|
|
639
|
-
}
|
|
640
|
-
return this.queryUtils.transaction(this.prisma, (tx) => this.doUpdate(tx, this.model, args));
|
|
641
|
-
}
|
|
642
|
-
updateMany(args) {
|
|
643
|
-
const _super = Object.create(null, {
|
|
644
|
-
updateMany: { get: () => super.updateMany }
|
|
645
|
-
});
|
|
646
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
647
|
-
if (!args) {
|
|
648
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
|
|
649
|
-
}
|
|
650
|
-
if (!args.data) {
|
|
651
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'data field is required in query argument');
|
|
652
|
-
}
|
|
653
|
-
this.sanitizeMutationPayload(args.data);
|
|
654
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
655
|
-
return _super.updateMany.call(this, args);
|
|
656
|
-
}
|
|
657
|
-
let simpleUpdateMany = Object.keys(args.data).every((key) => {
|
|
658
|
-
// check if the `data` clause involves base fields
|
|
659
|
-
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, this.model, key);
|
|
660
|
-
return !(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom);
|
|
661
|
-
});
|
|
662
|
-
// check if there are any `@updatedAt` fields from delegate base models
|
|
663
|
-
if (simpleUpdateMany) {
|
|
664
|
-
if (this.getUpdatedAtFromDelegateBases(this.model).length > 0) {
|
|
665
|
-
simpleUpdateMany = false;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
return this.queryUtils.transaction(this.prisma, (tx) => this.doUpdateMany(tx, this.model, args, simpleUpdateMany));
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
upsert(args) {
|
|
672
|
-
const _super = Object.create(null, {
|
|
673
|
-
upsert: { get: () => super.upsert }
|
|
674
|
-
});
|
|
675
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
676
|
-
if (!args) {
|
|
677
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
|
|
678
|
-
}
|
|
679
|
-
if (!args.where) {
|
|
680
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'where field is required in query argument');
|
|
681
|
-
}
|
|
682
|
-
this.sanitizeMutationPayload(args.update);
|
|
683
|
-
this.sanitizeMutationPayload(args.create);
|
|
684
|
-
if ((0, cross_1.isDelegateModel)(this.options.modelMeta, this.model)) {
|
|
685
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `Model "${this.model}" is a delegate and doesn't support upsert`);
|
|
686
|
-
}
|
|
687
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
688
|
-
return _super.upsert.call(this, args);
|
|
689
|
-
}
|
|
690
|
-
args = (0, cross_1.clone)(args);
|
|
691
|
-
this.injectWhereHierarchy(this.model, args === null || args === void 0 ? void 0 : args.where);
|
|
692
|
-
yield this.injectSelectIncludeHierarchy(this.model, args);
|
|
693
|
-
if (args.create) {
|
|
694
|
-
this.doProcessCreatePayload(this.model, args.create);
|
|
695
|
-
}
|
|
696
|
-
if (args.update) {
|
|
697
|
-
this.doProcessUpdatePayload(this.model, args.update);
|
|
698
|
-
}
|
|
699
|
-
if (this.options.logPrismaQuery) {
|
|
700
|
-
this.logger.info(`[delegate] \`upsert\` ${this.getModelName(this.model)}: ${(0, utils_1.formatObject)(args)}`);
|
|
701
|
-
}
|
|
702
|
-
const result = yield this.prisma[this.model].upsert(args);
|
|
703
|
-
return this.assembleHierarchy(this.model, result);
|
|
704
|
-
});
|
|
705
|
-
}
|
|
706
|
-
doUpdate(db, model, args) {
|
|
707
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
708
|
-
args = (0, cross_1.clone)(args);
|
|
709
|
-
yield this.injectUpdateHierarchy(db, model, args);
|
|
710
|
-
yield this.injectSelectIncludeHierarchy(model, args);
|
|
711
|
-
if (this.options.logPrismaQuery) {
|
|
712
|
-
this.logger.info(`[delegate] \`update\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
|
|
713
|
-
}
|
|
714
|
-
const result = yield db[model].update(args);
|
|
715
|
-
return this.assembleHierarchy(model, result);
|
|
716
|
-
});
|
|
717
|
-
}
|
|
718
|
-
doUpdateMany(db, model, args, simpleUpdateMany) {
|
|
719
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
720
|
-
var _a;
|
|
721
|
-
if (simpleUpdateMany) {
|
|
722
|
-
// do a direct `updateMany`
|
|
723
|
-
args = (0, cross_1.clone)(args);
|
|
724
|
-
yield this.injectUpdateHierarchy(db, model, args);
|
|
725
|
-
if (this.options.logPrismaQuery) {
|
|
726
|
-
this.logger.info(`[delegate] \`updateMany\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
|
|
727
|
-
}
|
|
728
|
-
return db[model].updateMany(args);
|
|
729
|
-
}
|
|
730
|
-
else {
|
|
731
|
-
// translate to plain `update` for nested write into base fields
|
|
732
|
-
const findArgs = {
|
|
733
|
-
where: (0, cross_1.clone)((_a = args.where) !== null && _a !== void 0 ? _a : {}),
|
|
734
|
-
select: this.queryUtils.makeIdSelection(model),
|
|
735
|
-
};
|
|
736
|
-
yield this.injectUpdateHierarchy(db, model, findArgs);
|
|
737
|
-
if (this.options.logPrismaQuery) {
|
|
738
|
-
this.logger.info(`[delegate] \`updateMany\` find candidates: ${this.getModelName(model)}: ${(0, utils_1.formatObject)(findArgs)}`);
|
|
739
|
-
}
|
|
740
|
-
const entities = yield db[model].findMany(findArgs);
|
|
741
|
-
const updatePayload = { data: (0, cross_1.clone)(args.data), select: this.queryUtils.makeIdSelection(model) };
|
|
742
|
-
yield this.injectUpdateHierarchy(db, model, updatePayload);
|
|
743
|
-
const result = yield Promise.all(entities.map((entity) => {
|
|
744
|
-
const updateArgs = Object.assign({ where: entity }, updatePayload);
|
|
745
|
-
if (this.options.logPrismaQuery) {
|
|
746
|
-
this.logger.info(`[delegate] \`updateMany\` update: ${this.getModelName(model)}: ${(0, utils_1.formatObject)(updateArgs)}`);
|
|
747
|
-
}
|
|
748
|
-
return db[model].update(updateArgs);
|
|
749
|
-
}));
|
|
750
|
-
return { count: result.length };
|
|
751
|
-
}
|
|
752
|
-
});
|
|
753
|
-
}
|
|
754
|
-
injectUpdateHierarchy(db, model, args) {
|
|
755
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
756
|
-
const visitor = new cross_1.NestedWriteVisitor(this.options.modelMeta, {
|
|
757
|
-
update: (model, args, _context) => {
|
|
758
|
-
this.injectWhereHierarchy(model, args === null || args === void 0 ? void 0 : args.where);
|
|
759
|
-
this.doProcessUpdatePayload(model, args === null || args === void 0 ? void 0 : args.data);
|
|
760
|
-
},
|
|
761
|
-
updateMany: (model, args, context) => __awaiter(this, void 0, void 0, function* () {
|
|
762
|
-
let simpleUpdateMany = Object.keys(args.data).every((key) => {
|
|
763
|
-
// check if the `data` clause involves base fields
|
|
764
|
-
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, key);
|
|
765
|
-
return !(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom);
|
|
766
|
-
});
|
|
767
|
-
// check if there are any `@updatedAt` fields from delegate base models
|
|
768
|
-
if (simpleUpdateMany) {
|
|
769
|
-
if (this.getUpdatedAtFromDelegateBases(model).length > 0) {
|
|
770
|
-
simpleUpdateMany = false;
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
if (simpleUpdateMany) {
|
|
774
|
-
// check if the `where` clause involves base fields
|
|
775
|
-
simpleUpdateMany = Object.keys(args.where || {}).every((key) => {
|
|
776
|
-
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, key);
|
|
777
|
-
return !(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom);
|
|
778
|
-
});
|
|
779
|
-
}
|
|
780
|
-
if (simpleUpdateMany) {
|
|
781
|
-
this.injectWhereHierarchy(model, args === null || args === void 0 ? void 0 : args.where);
|
|
782
|
-
this.doProcessUpdatePayload(model, args === null || args === void 0 ? void 0 : args.data);
|
|
783
|
-
}
|
|
784
|
-
else {
|
|
785
|
-
const where = yield this.queryUtils.buildReversedQuery(db, context, false, false);
|
|
786
|
-
yield this.queryUtils.transaction(db, (tx) => __awaiter(this, void 0, void 0, function* () {
|
|
787
|
-
yield this.doUpdateMany(tx, model, Object.assign(Object.assign({}, args), { where }), simpleUpdateMany);
|
|
788
|
-
}));
|
|
789
|
-
delete context.parent['updateMany'];
|
|
790
|
-
}
|
|
791
|
-
}),
|
|
792
|
-
upsert: (model, args, _context) => {
|
|
793
|
-
this.injectWhereHierarchy(model, args === null || args === void 0 ? void 0 : args.where);
|
|
794
|
-
if (args.create) {
|
|
795
|
-
this.doProcessCreatePayload(model, args === null || args === void 0 ? void 0 : args.create);
|
|
796
|
-
}
|
|
797
|
-
if (args.update) {
|
|
798
|
-
this.doProcessUpdatePayload(model, args === null || args === void 0 ? void 0 : args.update);
|
|
799
|
-
}
|
|
800
|
-
},
|
|
801
|
-
create: (model, args, _context) => {
|
|
802
|
-
if ((0, cross_1.isDelegateModel)(this.options.modelMeta, model)) {
|
|
803
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `Model "${model}" is a delegate and cannot be created directly`);
|
|
804
|
-
}
|
|
805
|
-
this.doProcessCreatePayload(model, args);
|
|
806
|
-
},
|
|
807
|
-
createMany: (model, args, _context) => {
|
|
808
|
-
if (args.skipDuplicates) {
|
|
809
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, '`createMany` with `skipDuplicates` set to true is not supported for delegated models');
|
|
810
|
-
}
|
|
811
|
-
for (const item of (0, cross_1.enumerate)(args === null || args === void 0 ? void 0 : args.data)) {
|
|
812
|
-
this.doProcessCreatePayload(model, item);
|
|
813
|
-
}
|
|
814
|
-
},
|
|
815
|
-
connect: (model, args, _context) => {
|
|
816
|
-
this.injectWhereHierarchy(model, args);
|
|
817
|
-
},
|
|
818
|
-
connectOrCreate: (model, args, _context) => {
|
|
819
|
-
this.injectWhereHierarchy(model, args.where);
|
|
820
|
-
if (args.create) {
|
|
821
|
-
this.doProcessCreatePayload(model, args.create);
|
|
822
|
-
}
|
|
823
|
-
},
|
|
824
|
-
disconnect: (model, args, _context) => {
|
|
825
|
-
this.injectWhereHierarchy(model, args);
|
|
826
|
-
},
|
|
827
|
-
set: (model, args, _context) => {
|
|
828
|
-
this.injectWhereHierarchy(model, args);
|
|
829
|
-
},
|
|
830
|
-
delete: (model, _args, context) => __awaiter(this, void 0, void 0, function* () {
|
|
831
|
-
const where = yield this.queryUtils.buildReversedQuery(db, context, false, false);
|
|
832
|
-
yield this.queryUtils.transaction(db, (tx) => __awaiter(this, void 0, void 0, function* () {
|
|
833
|
-
yield this.doDelete(tx, model, { where });
|
|
834
|
-
}));
|
|
835
|
-
delete context.parent['delete'];
|
|
836
|
-
}),
|
|
837
|
-
deleteMany: (model, _args, context) => __awaiter(this, void 0, void 0, function* () {
|
|
838
|
-
const where = yield this.queryUtils.buildReversedQuery(db, context, false, false);
|
|
839
|
-
yield this.queryUtils.transaction(db, (tx) => __awaiter(this, void 0, void 0, function* () {
|
|
840
|
-
yield this.doDeleteMany(tx, model, where);
|
|
841
|
-
}));
|
|
842
|
-
delete context.parent['deleteMany'];
|
|
843
|
-
}),
|
|
844
|
-
});
|
|
845
|
-
yield visitor.visit(model, 'update', args);
|
|
846
|
-
});
|
|
847
|
-
}
|
|
848
|
-
doProcessUpdatePayload(model, data) {
|
|
849
|
-
if (!data) {
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
for (const [field, value] of Object.entries(data)) {
|
|
853
|
-
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);
|
|
854
|
-
if (fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom) {
|
|
855
|
-
this.injectBaseFieldData(model, fieldInfo, value, data, 'update');
|
|
856
|
-
delete data[field];
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
// if we're updating any field, we need to take care of updating `@updatedAt`
|
|
860
|
-
// fields inherited from delegate base models
|
|
861
|
-
if (Object.keys(data).length > 0) {
|
|
862
|
-
const updatedAtFields = this.getUpdatedAtFromDelegateBases(model);
|
|
863
|
-
for (const fieldInfo of updatedAtFields) {
|
|
864
|
-
this.injectBaseFieldData(model, fieldInfo, new Date(), data, 'update');
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
// #endregion
|
|
869
|
-
// #region delete
|
|
870
|
-
delete(args) {
|
|
871
|
-
if (!args) {
|
|
872
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
|
|
873
|
-
}
|
|
874
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
875
|
-
return super.delete(args);
|
|
876
|
-
}
|
|
877
|
-
return this.queryUtils.transaction(this.prisma, (tx) => __awaiter(this, void 0, void 0, function* () {
|
|
878
|
-
const selectInclude = yield this.buildSelectIncludeHierarchy(this.model, args);
|
|
879
|
-
// make sure id fields are selected
|
|
880
|
-
const idFields = this.getIdFields(this.model);
|
|
881
|
-
for (const idField of idFields) {
|
|
882
|
-
if ((selectInclude === null || selectInclude === void 0 ? void 0 : selectInclude.select) && !(idField.name in selectInclude.select)) {
|
|
883
|
-
selectInclude.select[idField.name] = true;
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
const deleteArgs = Object.assign(Object.assign({}, (0, cross_1.clone)(args)), selectInclude);
|
|
887
|
-
return this.doDelete(tx, this.model, deleteArgs);
|
|
888
|
-
}));
|
|
889
|
-
}
|
|
890
|
-
deleteMany(args) {
|
|
891
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
892
|
-
return super.deleteMany(args);
|
|
893
|
-
}
|
|
894
|
-
return this.queryUtils.transaction(this.prisma, (tx) => this.doDeleteMany(tx, this.model, args === null || args === void 0 ? void 0 : args.where));
|
|
895
|
-
}
|
|
896
|
-
doDeleteMany(db, model, where) {
|
|
897
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
898
|
-
// query existing entities with id
|
|
899
|
-
const idSelection = this.queryUtils.makeIdSelection(model);
|
|
900
|
-
const findArgs = { where: (0, cross_1.clone)(where !== null && where !== void 0 ? where : {}), select: idSelection };
|
|
901
|
-
this.injectWhereHierarchy(model, findArgs.where);
|
|
902
|
-
if (this.options.logPrismaQuery) {
|
|
903
|
-
this.logger.info(`[delegate] \`deleteMany\` find candidates: ${this.getModelName(model)}: ${(0, utils_1.formatObject)(findArgs)}`);
|
|
904
|
-
}
|
|
905
|
-
const entities = yield db[model].findMany(findArgs);
|
|
906
|
-
// recursively delete base entities (they all have the same id values)
|
|
907
|
-
yield Promise.all(entities.map((entity) => {
|
|
908
|
-
let deleteFilter = entity;
|
|
909
|
-
if (Object.keys(deleteFilter).length > 1) {
|
|
910
|
-
// if the model has compound id fields, we need to compose a compound key filter,
|
|
911
|
-
// otherwise calling Prisma's `delete` won't work
|
|
912
|
-
deleteFilter = this.queryUtils.composeCompoundUniqueField(model, deleteFilter);
|
|
913
|
-
}
|
|
914
|
-
return this.doDelete(db, model, { where: deleteFilter });
|
|
915
|
-
}));
|
|
916
|
-
return { count: entities.length };
|
|
917
|
-
});
|
|
918
|
-
}
|
|
919
|
-
deleteBaseRecursively(db, model, idValues) {
|
|
920
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
921
|
-
let base = this.getBaseModel(model);
|
|
922
|
-
while (base) {
|
|
923
|
-
let deleteFilter = idValues;
|
|
924
|
-
if (Object.keys(idValues).length > 1) {
|
|
925
|
-
// if the model has compound id fields, we need to compose a compound key filter,
|
|
926
|
-
// otherwise calling Prisma's `delete` won't work
|
|
927
|
-
deleteFilter = this.queryUtils.composeCompoundUniqueField(base.name, deleteFilter);
|
|
928
|
-
}
|
|
929
|
-
yield db[base.name].delete({ where: deleteFilter });
|
|
930
|
-
base = this.getBaseModel(base.name);
|
|
931
|
-
}
|
|
932
|
-
});
|
|
933
|
-
}
|
|
934
|
-
doDelete(db_1, model_1, args_1) {
|
|
935
|
-
return __awaiter(this, arguments, void 0, function* (db, model, args, readBack = true) {
|
|
936
|
-
this.injectWhereHierarchy(model, args.where);
|
|
937
|
-
yield this.injectSelectIncludeHierarchy(model, args);
|
|
938
|
-
// read relation entities that need to be cascade deleted before deleting the main entity
|
|
939
|
-
const cascadeDeletes = yield this.getRelationDelegateEntitiesForCascadeDelete(db, model, args.where);
|
|
940
|
-
let result = undefined;
|
|
941
|
-
if (cascadeDeletes.length > 0) {
|
|
942
|
-
// we'll need to do cascade deletes of relations, so first
|
|
943
|
-
// read the current entity before anything changes
|
|
944
|
-
if (readBack) {
|
|
945
|
-
result = yield this.doFind(db, model, 'findUnique', args);
|
|
946
|
-
}
|
|
947
|
-
// process cascade deletes of relations, this ensure their delegate base
|
|
948
|
-
// entities are deleted as well
|
|
949
|
-
yield Promise.all(cascadeDeletes.map(({ model, entity }) => this.doDelete(db, model, { where: entity }, false)));
|
|
950
|
-
}
|
|
951
|
-
if (this.options.logPrismaQuery) {
|
|
952
|
-
this.logger.info(`[delegate] \`delete\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
|
|
953
|
-
}
|
|
954
|
-
const deleteResult = yield db[model].delete(args);
|
|
955
|
-
if (!result) {
|
|
956
|
-
result = this.assembleHierarchy(model, deleteResult);
|
|
957
|
-
}
|
|
958
|
-
// recursively delete base entities (they all have the same id values)
|
|
959
|
-
const idValues = this.queryUtils.getEntityIds(model, deleteResult);
|
|
960
|
-
yield this.deleteBaseRecursively(db, model, idValues);
|
|
961
|
-
return result;
|
|
962
|
-
});
|
|
963
|
-
}
|
|
964
|
-
getRelationDelegateEntitiesForCascadeDelete(db, model, where) {
|
|
965
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
966
|
-
if (!where || Object.keys(where).length === 0) {
|
|
967
|
-
throw new Error('where clause is required for cascade delete');
|
|
968
|
-
}
|
|
969
|
-
const cascadeDeletes = [];
|
|
970
|
-
const fields = (0, cross_1.getFields)(this.options.modelMeta, model);
|
|
971
|
-
if (fields) {
|
|
972
|
-
for (const fieldInfo of Object.values(fields)) {
|
|
973
|
-
if (!fieldInfo.isDataModel) {
|
|
974
|
-
continue;
|
|
975
|
-
}
|
|
976
|
-
if (fieldInfo.isRelationOwner) {
|
|
977
|
-
// this side of the relation owns the foreign key,
|
|
978
|
-
// so it won't cause cascade delete to the other side
|
|
979
|
-
continue;
|
|
980
|
-
}
|
|
981
|
-
if (fieldInfo.backLink) {
|
|
982
|
-
// get the opposite side of the relation
|
|
983
|
-
const backLinkField = this.queryUtils.getModelField(fieldInfo.type, fieldInfo.backLink);
|
|
984
|
-
if ((backLinkField === null || backLinkField === void 0 ? void 0 : backLinkField.isRelationOwner) && this.isFieldCascadeDelete(backLinkField)) {
|
|
985
|
-
// if the opposite side of the relation is to be cascade deleted,
|
|
986
|
-
// recursively delete the delegate base entities
|
|
987
|
-
const relationModel = (0, cross_1.getModelInfo)(this.options.modelMeta, fieldInfo.type);
|
|
988
|
-
if ((relationModel === null || relationModel === void 0 ? void 0 : relationModel.baseTypes) && relationModel.baseTypes.length > 0) {
|
|
989
|
-
// the relation model has delegate base, cascade the delete to the base
|
|
990
|
-
const relationEntities = yield db[relationModel.name].findMany({
|
|
991
|
-
where: { [backLinkField.name]: where },
|
|
992
|
-
select: this.queryUtils.makeIdSelection(relationModel.name),
|
|
993
|
-
});
|
|
994
|
-
relationEntities.forEach((entity) => {
|
|
995
|
-
cascadeDeletes.push({ model: fieldInfo.type, entity });
|
|
996
|
-
});
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
return cascadeDeletes;
|
|
1003
|
-
});
|
|
1004
|
-
}
|
|
1005
|
-
isFieldCascadeDelete(fieldInfo) {
|
|
1006
|
-
return fieldInfo.onDeleteAction === 'Cascade';
|
|
1007
|
-
}
|
|
1008
|
-
// #endregion
|
|
1009
|
-
// #region aggregation
|
|
1010
|
-
aggregate(args) {
|
|
1011
|
-
if (!args) {
|
|
1012
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
|
|
1013
|
-
}
|
|
1014
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
1015
|
-
return super.aggregate(args);
|
|
1016
|
-
}
|
|
1017
|
-
// check if any aggregation operator is using fields from base
|
|
1018
|
-
this.checkAggregationArgs('aggregate', args);
|
|
1019
|
-
args = (0, cross_1.clone)(args);
|
|
1020
|
-
if (args.cursor) {
|
|
1021
|
-
this.injectWhereHierarchy(this.model, args.cursor);
|
|
1022
|
-
}
|
|
1023
|
-
if (args.orderBy) {
|
|
1024
|
-
(0, cross_1.enumerate)(args.orderBy).forEach((item) => this.injectWhereHierarchy(this.model, item));
|
|
1025
|
-
}
|
|
1026
|
-
if (args.where) {
|
|
1027
|
-
this.injectWhereHierarchy(this.model, args.where);
|
|
1028
|
-
}
|
|
1029
|
-
if (this.options.logPrismaQuery) {
|
|
1030
|
-
this.logger.info(`[delegate] \`aggregate\` ${this.getModelName(this.model)}: ${(0, utils_1.formatObject)(args)}`);
|
|
1031
|
-
}
|
|
1032
|
-
return super.aggregate(args);
|
|
1033
|
-
}
|
|
1034
|
-
count(args) {
|
|
1035
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
1036
|
-
return super.count(args);
|
|
1037
|
-
}
|
|
1038
|
-
// check if count select is using fields from base
|
|
1039
|
-
this.checkAggregationArgs('count', args);
|
|
1040
|
-
args = (0, cross_1.clone)(args);
|
|
1041
|
-
if (args === null || args === void 0 ? void 0 : args.cursor) {
|
|
1042
|
-
this.injectWhereHierarchy(this.model, args.cursor);
|
|
1043
|
-
}
|
|
1044
|
-
if (args === null || args === void 0 ? void 0 : args.where) {
|
|
1045
|
-
this.injectWhereHierarchy(this.model, args.where);
|
|
1046
|
-
}
|
|
1047
|
-
if (this.options.logPrismaQuery) {
|
|
1048
|
-
this.logger.info(`[delegate] \`count\` ${this.getModelName(this.model)}: ${(0, utils_1.formatObject)(args)}`);
|
|
1049
|
-
}
|
|
1050
|
-
return super.count(args);
|
|
1051
|
-
}
|
|
1052
|
-
groupBy(args) {
|
|
1053
|
-
if (!args) {
|
|
1054
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, 'query argument is required');
|
|
1055
|
-
}
|
|
1056
|
-
if (!this.involvesDelegateModel(this.model)) {
|
|
1057
|
-
return super.groupBy(args);
|
|
1058
|
-
}
|
|
1059
|
-
// check if count select is using fields from base
|
|
1060
|
-
this.checkAggregationArgs('groupBy', args);
|
|
1061
|
-
if (args.by) {
|
|
1062
|
-
for (const by of (0, cross_1.enumerate)(args.by)) {
|
|
1063
|
-
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, this.model, by);
|
|
1064
|
-
if (fieldInfo && fieldInfo.inheritedFrom) {
|
|
1065
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `groupBy with fields from base type is not supported yet: "${by}"`);
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
args = (0, cross_1.clone)(args);
|
|
1070
|
-
if (args.where) {
|
|
1071
|
-
this.injectWhereHierarchy(this.model, args.where);
|
|
1072
|
-
}
|
|
1073
|
-
if (this.options.logPrismaQuery) {
|
|
1074
|
-
this.logger.info(`[delegate] \`groupBy\` ${this.getModelName(this.model)}: ${(0, utils_1.formatObject)(args)}`);
|
|
1075
|
-
}
|
|
1076
|
-
return super.groupBy(args);
|
|
1077
|
-
}
|
|
1078
|
-
checkAggregationArgs(operation, args) {
|
|
1079
|
-
if (!args) {
|
|
1080
|
-
return;
|
|
1081
|
-
}
|
|
1082
|
-
for (const op of ['_count', '_sum', '_avg', '_min', '_max', 'select', 'having']) {
|
|
1083
|
-
if (args[op] && typeof args[op] === 'object') {
|
|
1084
|
-
for (const field of Object.keys(args[op])) {
|
|
1085
|
-
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, this.model, field);
|
|
1086
|
-
if (fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom) {
|
|
1087
|
-
throw (0, utils_1.prismaClientValidationError)(this.prisma, this.options.prismaModule, `${operation} with fields from base type is not supported yet: "${field}"`);
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
// #endregion
|
|
1094
|
-
// #region utils
|
|
1095
|
-
extractSelectInclude(args) {
|
|
1096
|
-
if (!args) {
|
|
1097
|
-
return undefined;
|
|
1098
|
-
}
|
|
1099
|
-
args = (0, cross_1.clone)(args);
|
|
1100
|
-
return 'select' in args
|
|
1101
|
-
? { select: args['select'] }
|
|
1102
|
-
: 'include' in args
|
|
1103
|
-
? { include: args['include'] }
|
|
1104
|
-
: undefined;
|
|
1105
|
-
}
|
|
1106
|
-
makeAuxRelationName(model) {
|
|
1107
|
-
var _a;
|
|
1108
|
-
const name = `${constants_1.DELEGATE_AUX_RELATION_PREFIX}_${(0, local_helpers_1.lowerCaseFirst)(model.name)}`;
|
|
1109
|
-
// make sure we look up into short name map to see if it's truncated
|
|
1110
|
-
const shortName = (_a = this.options.modelMeta.shortNameMap) === null || _a === void 0 ? void 0 : _a[name];
|
|
1111
|
-
return shortName !== null && shortName !== void 0 ? shortName : name;
|
|
1112
|
-
}
|
|
1113
|
-
getModelName(model) {
|
|
1114
|
-
const info = (0, cross_1.getModelInfo)(this.options.modelMeta, model, true);
|
|
1115
|
-
return info.name;
|
|
1116
|
-
}
|
|
1117
|
-
getIdFields(model) {
|
|
1118
|
-
const idFields = (0, cross_1.getIdFields)(this.options.modelMeta, model);
|
|
1119
|
-
if (idFields && idFields.length > 0) {
|
|
1120
|
-
return idFields;
|
|
1121
|
-
}
|
|
1122
|
-
const base = this.getBaseModel(model);
|
|
1123
|
-
return base ? this.getIdFields(base.name) : [];
|
|
1124
|
-
}
|
|
1125
|
-
getModelInfo(model) {
|
|
1126
|
-
return (0, cross_1.getModelInfo)(this.options.modelMeta, model, true);
|
|
1127
|
-
}
|
|
1128
|
-
getBaseModel(model) {
|
|
1129
|
-
const baseNames = (0, cross_1.getModelInfo)(this.options.modelMeta, model, true).baseTypes;
|
|
1130
|
-
if (!baseNames) {
|
|
1131
|
-
return undefined;
|
|
1132
|
-
}
|
|
1133
|
-
if (baseNames.length > 1) {
|
|
1134
|
-
throw new Error('Multi-inheritance is not supported');
|
|
1135
|
-
}
|
|
1136
|
-
return this.options.modelMeta.models[(0, local_helpers_1.lowerCaseFirst)(baseNames[0])];
|
|
1137
|
-
}
|
|
1138
|
-
involvesDelegateModel(model, visited) {
|
|
1139
|
-
if (this.isDelegateOrDescendantOfDelegate(model)) {
|
|
1140
|
-
return true;
|
|
1141
|
-
}
|
|
1142
|
-
visited = visited !== null && visited !== void 0 ? visited : new Set();
|
|
1143
|
-
if (visited.has(model)) {
|
|
1144
|
-
return false;
|
|
1145
|
-
}
|
|
1146
|
-
visited.add(model);
|
|
1147
|
-
const modelInfo = (0, cross_1.getModelInfo)(this.options.modelMeta, model, true);
|
|
1148
|
-
return Object.values(modelInfo.fields).some((field) => field.isDataModel && this.involvesDelegateModel(field.type, visited));
|
|
1149
|
-
}
|
|
1150
|
-
isDelegateOrDescendantOfDelegate(model) {
|
|
1151
|
-
var _a;
|
|
1152
|
-
if ((0, cross_1.isDelegateModel)(this.options.modelMeta, model)) {
|
|
1153
|
-
return true;
|
|
1154
|
-
}
|
|
1155
|
-
const baseTypes = (_a = (0, cross_1.getModelInfo)(this.options.modelMeta, model)) === null || _a === void 0 ? void 0 : _a.baseTypes;
|
|
1156
|
-
return !!(baseTypes &&
|
|
1157
|
-
baseTypes.length > 0 &&
|
|
1158
|
-
baseTypes.some((base) => this.isDelegateOrDescendantOfDelegate(base)));
|
|
1159
|
-
}
|
|
1160
|
-
assembleHierarchy(model, entity) {
|
|
1161
|
-
if (!entity || typeof entity !== 'object') {
|
|
1162
|
-
return entity;
|
|
1163
|
-
}
|
|
1164
|
-
const upMerged = this.assembleUp(model, entity);
|
|
1165
|
-
const downMerged = this.assembleDown(model, entity);
|
|
1166
|
-
// https://www.npmjs.com/package/deepmerge#arraymerge-example-combine-arrays
|
|
1167
|
-
const combineMerge = (target, source, options) => {
|
|
1168
|
-
const destination = target.slice();
|
|
1169
|
-
source.forEach((item, index) => {
|
|
1170
|
-
if (typeof destination[index] === 'undefined') {
|
|
1171
|
-
destination[index] = options.cloneUnlessOtherwiseSpecified(item, options);
|
|
1172
|
-
}
|
|
1173
|
-
else if (options.isMergeableObject(item)) {
|
|
1174
|
-
destination[index] = (0, deepmerge_1.default)(target[index], item, options);
|
|
1175
|
-
}
|
|
1176
|
-
else if (target.indexOf(item) === -1) {
|
|
1177
|
-
destination.push(item);
|
|
1178
|
-
}
|
|
1179
|
-
});
|
|
1180
|
-
return destination;
|
|
1181
|
-
};
|
|
1182
|
-
const result = (0, deepmerge_1.default)(upMerged, downMerged, {
|
|
1183
|
-
arrayMerge: combineMerge,
|
|
1184
|
-
isMergeableObject: (v) => (0, local_helpers_1.isPlainObject)(v) || Array.isArray(v), // avoid messing with Decimal, Date, etc.
|
|
1185
|
-
});
|
|
1186
|
-
return result;
|
|
1187
|
-
}
|
|
1188
|
-
assembleUp(model, entity) {
|
|
1189
|
-
if (!entity) {
|
|
1190
|
-
return entity;
|
|
1191
|
-
}
|
|
1192
|
-
const result = {};
|
|
1193
|
-
const base = this.getBaseModel(model);
|
|
1194
|
-
if (base) {
|
|
1195
|
-
// fully merge base fields
|
|
1196
|
-
const baseRelationName = this.makeAuxRelationName(base);
|
|
1197
|
-
const baseData = entity[baseRelationName];
|
|
1198
|
-
if (baseData && typeof baseData === 'object') {
|
|
1199
|
-
const baseAssembled = this.assembleHierarchy(base.name, baseData);
|
|
1200
|
-
Object.assign(result, baseAssembled);
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
|
-
const modelInfo = (0, cross_1.getModelInfo)(this.options.modelMeta, model, true);
|
|
1204
|
-
for (const [key, value] of Object.entries(entity)) {
|
|
1205
|
-
if (key.startsWith(constants_1.DELEGATE_AUX_RELATION_PREFIX)) {
|
|
1206
|
-
continue;
|
|
1207
|
-
}
|
|
1208
|
-
const field = modelInfo.fields[key];
|
|
1209
|
-
if (!field) {
|
|
1210
|
-
// not a field, could be `_count`, `_sum`, etc.
|
|
1211
|
-
result[key] = value;
|
|
1212
|
-
continue;
|
|
1213
|
-
}
|
|
1214
|
-
if (field.inheritedFrom) {
|
|
1215
|
-
// already merged from base
|
|
1216
|
-
continue;
|
|
1217
|
-
}
|
|
1218
|
-
if (field.isDataModel) {
|
|
1219
|
-
if (Array.isArray(value)) {
|
|
1220
|
-
result[field.name] = value.map((item) => this.assembleUp(field.type, item));
|
|
1221
|
-
}
|
|
1222
|
-
else {
|
|
1223
|
-
result[field.name] = this.assembleUp(field.type, value);
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
else {
|
|
1227
|
-
result[field.name] = value;
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
return result;
|
|
1231
|
-
}
|
|
1232
|
-
assembleDown(model, entity) {
|
|
1233
|
-
if (!entity) {
|
|
1234
|
-
return entity;
|
|
1235
|
-
}
|
|
1236
|
-
const result = {};
|
|
1237
|
-
const modelInfo = (0, cross_1.getModelInfo)(this.options.modelMeta, model, true);
|
|
1238
|
-
if (modelInfo.discriminator) {
|
|
1239
|
-
// model is a delegate, fully merge concrete model fields
|
|
1240
|
-
const subModelName = entity[modelInfo.discriminator];
|
|
1241
|
-
if (subModelName) {
|
|
1242
|
-
const subModel = (0, cross_1.getModelInfo)(this.options.modelMeta, subModelName, true);
|
|
1243
|
-
const subRelationName = this.makeAuxRelationName(subModel);
|
|
1244
|
-
const subData = entity[subRelationName];
|
|
1245
|
-
if (subData && typeof subData === 'object') {
|
|
1246
|
-
const subAssembled = this.assembleHierarchy(subModel.name, subData);
|
|
1247
|
-
Object.assign(result, subAssembled);
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
}
|
|
1251
|
-
for (const [key, value] of Object.entries(entity)) {
|
|
1252
|
-
if (key.startsWith(constants_1.DELEGATE_AUX_RELATION_PREFIX)) {
|
|
1253
|
-
continue;
|
|
1254
|
-
}
|
|
1255
|
-
const field = modelInfo.fields[key];
|
|
1256
|
-
if (!field) {
|
|
1257
|
-
// not a field, could be `_count`, `_sum`, etc.
|
|
1258
|
-
result[key] = value;
|
|
1259
|
-
continue;
|
|
1260
|
-
}
|
|
1261
|
-
if (field.isDataModel) {
|
|
1262
|
-
if (Array.isArray(value)) {
|
|
1263
|
-
result[field.name] = value.map((item) => this.assembleDown(field.type, item));
|
|
1264
|
-
}
|
|
1265
|
-
else {
|
|
1266
|
-
result[field.name] = this.assembleDown(field.type, value);
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
else {
|
|
1270
|
-
result[field.name] = value;
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
return result;
|
|
1274
|
-
}
|
|
1275
|
-
getUpdatedAtFromDelegateBases(model) {
|
|
1276
|
-
var _a;
|
|
1277
|
-
const result = [];
|
|
1278
|
-
const modelFields = (0, cross_1.getFields)(this.options.modelMeta, model);
|
|
1279
|
-
if (!modelFields) {
|
|
1280
|
-
return result;
|
|
1281
|
-
}
|
|
1282
|
-
for (const fieldInfo of Object.values(modelFields)) {
|
|
1283
|
-
if (((_a = fieldInfo.attributes) === null || _a === void 0 ? void 0 : _a.some((attr) => attr.name === '@updatedAt')) &&
|
|
1284
|
-
fieldInfo.inheritedFrom &&
|
|
1285
|
-
(0, cross_1.isDelegateModel)(this.options.modelMeta, fieldInfo.inheritedFrom)) {
|
|
1286
|
-
result.push(fieldInfo);
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
return result;
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
exports.DelegateProxyHandler = DelegateProxyHandler;
|
|
1293
|
-
//# sourceMappingURL=delegate.js.map
|