@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.cjs CHANGED
@@ -3251,6 +3251,8 @@ var BaseOperationHandler = class {
3251
3251
  if (vr.kind === "filtered") {
3252
3252
  const sourceField = vr.relation;
3253
3253
  const isSelfReferencing = field === sourceField;
3254
+ const { value: rewrittenValue, plan: nestedPlan } = this.rewriteNestedVirtualRelationArgs(vr.targetModel, value, virtualRelations);
3255
+ const discriminatorTarget = vr.where ? this.resolveFilteredRelationDiscriminatorTarget(model, vr.targetModel, vr.where) : void 0;
3254
3256
  if (isSelfReferencing) {
3255
3257
  plans.push({
3256
3258
  kind: "filtered",
@@ -3259,11 +3261,13 @@ var BaseOperationHandler = class {
3259
3261
  sourceModel: vr.targetModel,
3260
3262
  single: vr.single,
3261
3263
  discriminatorWhere: vr.where,
3262
- introducedSourceField: false
3264
+ discriminatorTarget,
3265
+ introducedSourceField: false,
3266
+ nestedPlan
3263
3267
  });
3264
3268
  } else {
3265
- const nestedArgs = value === true ? {} : {
3266
- ...value
3269
+ const nestedArgs = rewrittenValue === true ? {} : {
3270
+ ...rewrittenValue
3267
3271
  };
3268
3272
  const where = nestedArgs.where ? {
3269
3273
  ...nestedArgs.where,
@@ -3284,15 +3288,18 @@ var BaseOperationHandler = class {
3284
3288
  sourceField,
3285
3289
  sourceModel: vr.targetModel,
3286
3290
  single: vr.single,
3287
- introducedSourceField: selection[sourceField] === void 0
3291
+ introducedSourceField: selection[sourceField] === void 0,
3292
+ discriminatorTarget,
3293
+ nestedPlan
3288
3294
  });
3289
3295
  }
3290
3296
  } else if (vr.kind === "through") {
3291
3297
  const path = vr.path;
3292
3298
  const [sourceField, ...restPath] = path;
3293
3299
  if (!sourceField) continue;
3294
- let throughValue = value === true ? true : {
3295
- ...value
3300
+ const { value: rewrittenValue, plan: nestedPlan } = this.rewriteNestedVirtualRelationArgs(vr.targetModel, value, virtualRelations);
3301
+ let throughValue = rewrittenValue === true ? true : {
3302
+ ...rewrittenValue
3296
3303
  };
3297
3304
  for (let i = restPath.length - 1; i >= 0; i--) {
3298
3305
  throughValue = {
@@ -3309,7 +3316,27 @@ var BaseOperationHandler = class {
3309
3316
  sourceField,
3310
3317
  sourceModel: vr.targetModel,
3311
3318
  path: restPath,
3312
- introducedSourceField: selection[sourceField] === void 0
3319
+ introducedSourceField: selection[sourceField] === void 0,
3320
+ nestedPlan
3321
+ });
3322
+ }
3323
+ }
3324
+ for (const [field, value] of Object.entries(nextSelection)) {
3325
+ const fieldDef = getField(this.schema, model, field);
3326
+ if (!fieldDef?.relation || value === true || !value || typeof value !== "object") {
3327
+ continue;
3328
+ }
3329
+ const { value: rewrittenValue, plan: nestedPlan } = this.rewriteNestedVirtualRelationArgs(fieldDef.type, value, virtualRelations);
3330
+ if (rewrittenValue !== value) {
3331
+ nextSelection[field] = rewrittenValue;
3332
+ }
3333
+ if (nestedPlan) {
3334
+ plans.push({
3335
+ kind: "actual",
3336
+ field,
3337
+ sourceField: field,
3338
+ sourceModel: fieldDef.type,
3339
+ nestedPlan
3313
3340
  });
3314
3341
  }
3315
3342
  }
@@ -3320,6 +3347,64 @@ var BaseOperationHandler = class {
3320
3347
  } : void 0
3321
3348
  };
3322
3349
  }
3350
+ rewriteNestedVirtualRelationArgs(model, value, virtualRelations) {
3351
+ if (value === true || !value || typeof value !== "object" || Array.isArray(value)) {
3352
+ return {
3353
+ value
3354
+ };
3355
+ }
3356
+ let changed = false;
3357
+ const nextValue = {
3358
+ ...value
3359
+ };
3360
+ let combinedPlan;
3361
+ const mergePlan = /* @__PURE__ */ __name((plan) => {
3362
+ if (!plan) return;
3363
+ if (!combinedPlan) {
3364
+ combinedPlan = {
3365
+ selections: [
3366
+ ...plan.selections
3367
+ ]
3368
+ };
3369
+ } else {
3370
+ combinedPlan.selections.push(...plan.selections);
3371
+ }
3372
+ }, "mergePlan");
3373
+ if (nextValue["select"] && typeof nextValue["select"] === "object") {
3374
+ const { selection, plan } = this.rewriteSelectionMap(model, nextValue["select"], virtualRelations);
3375
+ nextValue["select"] = selection;
3376
+ changed = true;
3377
+ mergePlan(plan);
3378
+ }
3379
+ if (nextValue["include"] && typeof nextValue["include"] === "object") {
3380
+ const { selection, plan } = this.rewriteSelectionMap(model, nextValue["include"], virtualRelations);
3381
+ nextValue["include"] = selection;
3382
+ changed = true;
3383
+ mergePlan(plan);
3384
+ }
3385
+ return {
3386
+ value: changed ? nextValue : value,
3387
+ plan: combinedPlan
3388
+ };
3389
+ }
3390
+ resolveFilteredRelationDiscriminatorTarget(parentModel, relationModel, where) {
3391
+ const keys = Object.keys(where);
3392
+ const parentMatches = keys.every((key) => {
3393
+ const field = getField(this.schema, parentModel, key);
3394
+ return !!field && !field.relation;
3395
+ });
3396
+ if (parentMatches) {
3397
+ return "parent";
3398
+ }
3399
+ const relationMatches = keys.every((key) => {
3400
+ const field = getField(this.schema, relationModel, key);
3401
+ return !!field && !field.relation;
3402
+ });
3403
+ if (relationMatches) {
3404
+ return "relation";
3405
+ }
3406
+ return "parent";
3407
+ }
3323
3408
  applyVirtualRelationPlan(data, plan) {
3324
3409
  if (!plan || data == null) return data;
3325
3410
  if (Array.isArray(data)) return data.map((item) => this.applyVirtualRelationPlan(item, plan));
@@ -3329,15 +3414,30 @@ var BaseOperationHandler = class {
3329
3414
  };
3330
3415
  for (const sel of plan.selections) {
3331
3416
  const sourceValue = this.normalizeVirtualRelationValue(result[sel.sourceField]);
3332
- if (sel.kind === "filtered") {
3333
- let value = sel.single ? Array.isArray(sourceValue) ? sourceValue[0] ?? null : sourceValue ?? null : sourceValue;
3417
+ if (sel.kind === "actual") {
3418
+ result[sel.field] = sel.nestedPlan ? this.applyVirtualRelationPlan(sourceValue, sel.nestedPlan) : sourceValue;
3419
+ } else if (sel.kind === "filtered") {
3420
+ let value = sourceValue;
3334
3421
  if (sel.discriminatorWhere && value != null) {
3335
- const matches = Object.entries(sel.discriminatorWhere).every(([key, val]) => result[key] === val);
3336
- if (!matches) value = null;
3422
+ if (sel.discriminatorTarget === "relation") {
3423
+ const matchesRelation = /* @__PURE__ */ __name((item) => item != null && typeof item === "object" && Object.entries(sel.discriminatorWhere).every(([key, expected]) => item[key] === expected), "matchesRelation");
3424
+ value = Array.isArray(value) ? value.filter(matchesRelation) : matchesRelation(value) ? value : null;
3425
+ } else {
3426
+ const matches = Object.entries(sel.discriminatorWhere).every(([key, val]) => result[key] === val);
3427
+ if (!matches) value = null;
3428
+ }
3429
+ }
3430
+ value = sel.single ? Array.isArray(value) ? value[0] ?? null : value ?? null : value;
3431
+ if (sel.nestedPlan) {
3432
+ value = this.applyVirtualRelationPlan(value, sel.nestedPlan);
3337
3433
  }
3338
3434
  result[sel.field] = value;
3339
3435
  } else if (sel.kind === "through") {
3340
- result[sel.field] = this.extractThroughValue(sourceValue, sel.path ?? []);
3436
+ let value = this.extractThroughValue(sourceValue, sel.path ?? []);
3437
+ if (sel.nestedPlan) {
3438
+ value = this.applyVirtualRelationPlan(value, sel.nestedPlan);
3439
+ }
3440
+ result[sel.field] = value;
3341
3441
  }
3342
3442
  if (sel.introducedSourceField) {
3343
3443
  delete result[sel.sourceField];