@danielhritcu/zenstack-orm 3.5.14 → 3.5.16

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/dist/index.js CHANGED
@@ -3202,6 +3202,8 @@ var BaseOperationHandler = class {
3202
3202
  if (vr.kind === "filtered") {
3203
3203
  const sourceField = vr.relation;
3204
3204
  const isSelfReferencing = field === sourceField;
3205
+ const { value: rewrittenValue, plan: nestedPlan } = this.rewriteNestedVirtualRelationArgs(vr.targetModel, value, virtualRelations);
3206
+ const discriminatorTarget = vr.where ? this.resolveFilteredRelationDiscriminatorTarget(model, vr.targetModel, vr.where) : void 0;
3205
3207
  if (isSelfReferencing) {
3206
3208
  plans.push({
3207
3209
  kind: "filtered",
@@ -3210,11 +3212,13 @@ var BaseOperationHandler = class {
3210
3212
  sourceModel: vr.targetModel,
3211
3213
  single: vr.single,
3212
3214
  discriminatorWhere: vr.where,
3213
- introducedSourceField: false
3215
+ discriminatorTarget,
3216
+ introducedSourceField: false,
3217
+ nestedPlan
3214
3218
  });
3215
3219
  } else {
3216
- const nestedArgs = value === true ? {} : {
3217
- ...value
3220
+ const nestedArgs = rewrittenValue === true ? {} : {
3221
+ ...rewrittenValue
3218
3222
  };
3219
3223
  const where = nestedArgs.where ? {
3220
3224
  ...nestedArgs.where,
@@ -3235,15 +3239,18 @@ var BaseOperationHandler = class {
3235
3239
  sourceField,
3236
3240
  sourceModel: vr.targetModel,
3237
3241
  single: vr.single,
3238
- introducedSourceField: selection[sourceField] === void 0
3242
+ introducedSourceField: selection[sourceField] === void 0,
3243
+ discriminatorTarget,
3244
+ nestedPlan
3239
3245
  });
3240
3246
  }
3241
3247
  } else if (vr.kind === "through") {
3242
3248
  const path = vr.path;
3243
3249
  const [sourceField, ...restPath] = path;
3244
3250
  if (!sourceField) continue;
3245
- let throughValue = value === true ? true : {
3246
- ...value
3251
+ const { value: rewrittenValue, plan: nestedPlan } = this.rewriteNestedVirtualRelationArgs(vr.targetModel, value, virtualRelations);
3252
+ let throughValue = rewrittenValue === true ? true : {
3253
+ ...rewrittenValue
3247
3254
  };
3248
3255
  for (let i = restPath.length - 1; i >= 0; i--) {
3249
3256
  throughValue = {
@@ -3260,7 +3267,27 @@ var BaseOperationHandler = class {
3260
3267
  sourceField,
3261
3268
  sourceModel: vr.targetModel,
3262
3269
  path: restPath,
3263
- introducedSourceField: selection[sourceField] === void 0
3270
+ introducedSourceField: selection[sourceField] === void 0,
3271
+ nestedPlan
3272
+ });
3273
+ }
3274
+ }
3275
+ for (const [field, value] of Object.entries(nextSelection)) {
3276
+ const fieldDef = getField(this.schema, model, field);
3277
+ if (!fieldDef?.relation || value === true || !value || typeof value !== "object") {
3278
+ continue;
3279
+ }
3280
+ const { value: rewrittenValue, plan: nestedPlan } = this.rewriteNestedVirtualRelationArgs(fieldDef.type, value, virtualRelations);
3281
+ if (rewrittenValue !== value) {
3282
+ nextSelection[field] = rewrittenValue;
3283
+ }
3284
+ if (nestedPlan) {
3285
+ plans.push({
3286
+ kind: "actual",
3287
+ field,
3288
+ sourceField: field,
3289
+ sourceModel: fieldDef.type,
3290
+ nestedPlan
3264
3291
  });
3265
3292
  }
3266
3293
  }
@@ -3271,6 +3298,64 @@ var BaseOperationHandler = class {
3271
3298
  } : void 0
3272
3299
  };
3273
3300
  }
3301
+ rewriteNestedVirtualRelationArgs(model, value, virtualRelations) {
3302
+ if (value === true || !value || typeof value !== "object" || Array.isArray(value)) {
3303
+ return {
3304
+ value
3305
+ };
3306
+ }
3307
+ let changed = false;
3308
+ const nextValue = {
3309
+ ...value
3310
+ };
3311
+ let combinedPlan;
3312
+ const mergePlan = /* @__PURE__ */ __name((plan) => {
3313
+ if (!plan) return;
3314
+ if (!combinedPlan) {
3315
+ combinedPlan = {
3316
+ selections: [
3317
+ ...plan.selections
3318
+ ]
3319
+ };
3320
+ } else {
3321
+ combinedPlan.selections.push(...plan.selections);
3322
+ }
3323
+ }, "mergePlan");
3324
+ if (nextValue["select"] && typeof nextValue["select"] === "object") {
3325
+ const { selection, plan } = this.rewriteSelectionMap(model, nextValue["select"], virtualRelations);
3326
+ nextValue["select"] = selection;
3327
+ changed = true;
3328
+ mergePlan(plan);
3329
+ }
3330
+ if (nextValue["include"] && typeof nextValue["include"] === "object") {
3331
+ const { selection, plan } = this.rewriteSelectionMap(model, nextValue["include"], virtualRelations);
3332
+ nextValue["include"] = selection;
3333
+ changed = true;
3334
+ mergePlan(plan);
3335
+ }
3336
+ return {
3337
+ value: changed ? nextValue : value,
3338
+ plan: combinedPlan
3339
+ };
3340
+ }
3341
+ resolveFilteredRelationDiscriminatorTarget(parentModel, relationModel, where) {
3342
+ const keys = Object.keys(where);
3343
+ const parentMatches = keys.every((key) => {
3344
+ const field = getField(this.schema, parentModel, key);
3345
+ return !!field && !field.relation;
3346
+ });
3347
+ if (parentMatches) {
3348
+ return "parent";
3349
+ }
3350
+ const relationMatches = keys.every((key) => {
3351
+ const field = getField(this.schema, relationModel, key);
3352
+ return !!field && !field.relation;
3353
+ });
3354
+ if (relationMatches) {
3355
+ return "relation";
3356
+ }
3357
+ return "parent";
3358
+ }
3274
3359
  applyVirtualRelationPlan(data, plan) {
3275
3360
  if (!plan || data == null) return data;
3276
3361
  if (Array.isArray(data)) return data.map((item) => this.applyVirtualRelationPlan(item, plan));
@@ -3280,15 +3365,30 @@ var BaseOperationHandler = class {
3280
3365
  };
3281
3366
  for (const sel of plan.selections) {
3282
3367
  const sourceValue = this.normalizeVirtualRelationValue(result[sel.sourceField]);
3283
- if (sel.kind === "filtered") {
3284
- let value = sel.single ? Array.isArray(sourceValue) ? sourceValue[0] ?? null : sourceValue ?? null : sourceValue;
3368
+ if (sel.kind === "actual") {
3369
+ result[sel.field] = sel.nestedPlan ? this.applyVirtualRelationPlan(sourceValue, sel.nestedPlan) : sourceValue;
3370
+ } else if (sel.kind === "filtered") {
3371
+ let value = sourceValue;
3285
3372
  if (sel.discriminatorWhere && value != null) {
3286
- const matches = Object.entries(sel.discriminatorWhere).every(([key, val]) => result[key] === val);
3287
- if (!matches) value = null;
3373
+ if (sel.discriminatorTarget === "relation") {
3374
+ const matchesRelation = /* @__PURE__ */ __name((item) => item != null && typeof item === "object" && Object.entries(sel.discriminatorWhere).every(([key, expected]) => item[key] === expected), "matchesRelation");
3375
+ value = Array.isArray(value) ? value.filter(matchesRelation) : matchesRelation(value) ? value : null;
3376
+ } else {
3377
+ const matches = Object.entries(sel.discriminatorWhere).every(([key, val]) => result[key] === val);
3378
+ if (!matches) value = null;
3379
+ }
3380
+ }
3381
+ value = sel.single ? Array.isArray(value) ? value[0] ?? null : value ?? null : value;
3382
+ if (sel.nestedPlan) {
3383
+ value = this.applyVirtualRelationPlan(value, sel.nestedPlan);
3288
3384
  }
3289
3385
  result[sel.field] = value;
3290
3386
  } else if (sel.kind === "through") {
3291
- result[sel.field] = this.extractThroughValue(sourceValue, sel.path ?? []);
3387
+ let value = this.extractThroughValue(sourceValue, sel.path ?? []);
3388
+ if (sel.nestedPlan) {
3389
+ value = this.applyVirtualRelationPlan(value, sel.nestedPlan);
3390
+ }
3391
+ result[sel.field] = value;
3292
3392
  }
3293
3393
  if (sel.introducedSourceField) {
3294
3394
  delete result[sel.sourceField];