arkormx 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -629,7 +629,7 @@ var TableBuilder = class {
629
629
  */
630
630
  foreign(column) {
631
631
  const columnName = this.resolveColumn(column).name;
632
- return this.foreignKey(columnName + (column ? "" : "Id"));
632
+ return this.foreignKey(column ?? columnName);
633
633
  }
634
634
  /**
635
635
  * Returns a deep copy of the defined columns for the table.
@@ -1047,24 +1047,24 @@ const deriveRelationFieldName = (columnName) => {
1047
1047
  if (trimmed.endsWith("_id") && trimmed.length > 3) return trimmed.slice(0, -3).replace(/_([a-zA-Z0-9])/g, (_, letter) => letter.toUpperCase());
1048
1048
  return `${trimmed.charAt(0).toLowerCase()}${trimmed.slice(1)}`;
1049
1049
  };
1050
- const pascalWords = (value) => {
1051
- return value.match(/[A-Z][a-z0-9]*/g) ?? [value];
1052
- };
1053
1050
  /**
1054
- * Derive a relation name for the inverse side of a relation based on the
1051
+ * Derive a relation name for both sides of a relation based on the
1055
1052
  * source and target model names, using an explicit alias if provided or a
1056
- * convention of combining the target model name with the last segment of
1057
- * the source model name.
1053
+ * convention of combining the full source model name with the target model name.
1058
1054
  *
1059
1055
  * @param sourceModelName The name of the source model in the relation.
1060
1056
  * @param targetModelName The name of the target model in the relation.
1061
- * @param explicitAlias An optional explicit alias for the inverse relation.
1062
- * @returns The derived or explicit inverse relation alias.
1057
+ * @param explicitAlias An optional explicit alias for the relation.
1058
+ * @returns The derived or explicit relation alias.
1063
1059
  */
1064
- const deriveInverseRelationAlias = (sourceModelName, targetModelName, explicitAlias) => {
1060
+ const deriveRelationAlias = (sourceModelName, targetModelName, explicitAlias) => {
1065
1061
  if (explicitAlias && explicitAlias.trim().length > 0) return explicitAlias.trim();
1066
- const sourceWords = pascalWords(sourceModelName);
1067
- return `${sourceWords[sourceWords.length - 1] ?? sourceModelName}${targetModelName}`;
1062
+ return [sourceModelName, targetModelName].sort((left, right) => left.localeCompare(right)).join("");
1063
+ };
1064
+ const deriveInverseRelationAlias = deriveRelationAlias;
1065
+ const deriveSingularFieldName = (modelName) => {
1066
+ if (!modelName) return "item";
1067
+ return `${modelName.charAt(0).toLowerCase()}${modelName.slice(1)}`;
1068
1068
  };
1069
1069
  const deriveCollectionFieldName = (modelName) => {
1070
1070
  if (!modelName) return "items";
@@ -1072,6 +1072,12 @@ const deriveCollectionFieldName = (modelName) => {
1072
1072
  if (camel.endsWith("s")) return `${camel}es`;
1073
1073
  return `${camel}s`;
1074
1074
  };
1075
+ const resolveForeignKeyColumn = (columns, foreignKey) => {
1076
+ return columns.find((column) => column.name === foreignKey.column);
1077
+ };
1078
+ const isOneToOneForeignKey = (column) => {
1079
+ return Boolean(column?.unique || column?.primary);
1080
+ };
1075
1081
  /**
1076
1082
  * Format a SchemaForeignKeyAction value as a Prisma onDelete action string.
1077
1083
  *
@@ -1092,15 +1098,16 @@ const formatRelationAction = (action) => {
1092
1098
  * @param foreignKey The foreign key definition to convert to a relation line.
1093
1099
  * @returns The corresponding Prisma schema line for the relation field.
1094
1100
  */
1095
- const buildRelationLine = (foreignKey) => {
1101
+ const buildRelationLine = (sourceModelName, foreignKey, columns = []) => {
1096
1102
  if (!foreignKey.referencesTable.trim()) throw new ArkormException(`Foreign key [${foreignKey.column}] must define a referenced table.`);
1097
1103
  if (!foreignKey.referencesColumn.trim()) throw new ArkormException(`Foreign key [${foreignKey.column}] must define a referenced column.`);
1104
+ const sourceColumn = resolveForeignKeyColumn(columns, foreignKey);
1098
1105
  const fieldName = foreignKey.fieldAlias?.trim() || deriveRelationFieldName(foreignKey.column);
1099
1106
  const targetModel = toModelName(foreignKey.referencesTable);
1100
- const relationName = foreignKey.relationAlias?.trim();
1101
- const relationPrefix = relationName ? `@relation("${relationName.replace(/"/g, "\\\"")}", ` : "@relation(";
1107
+ const relationName = deriveRelationAlias(sourceModelName, targetModel, foreignKey.relationAlias?.trim());
1108
+ const optional = sourceColumn?.nullable ? "?" : "";
1102
1109
  const onDelete = foreignKey.onDelete ? `, onDelete: ${formatRelationAction(foreignKey.onDelete)}` : "";
1103
- return ` ${fieldName} ${targetModel} ${relationPrefix}fields: [${foreignKey.column}], references: [${foreignKey.referencesColumn}]${onDelete})`;
1110
+ return ` ${fieldName} ${targetModel}${optional} @relation("${relationName.replace(/"/g, "\\\"")}", fields: [${foreignKey.column}], references: [${foreignKey.referencesColumn}]${onDelete})`;
1104
1111
  };
1105
1112
  /**
1106
1113
  * Build a Prisma relation field line for the inverse side of a relation, based
@@ -1112,8 +1119,11 @@ const buildRelationLine = (foreignKey) => {
1112
1119
  * @param foreignKey The foreign key definition for the relation.
1113
1120
  * @returns The Prisma schema line for the inverse relation field.
1114
1121
  */
1115
- const buildInverseRelationLine = (sourceModelName, targetModelName, foreignKey) => {
1116
- return ` ${deriveCollectionFieldName(sourceModelName)} ${sourceModelName}[] @relation("${deriveInverseRelationAlias(sourceModelName, targetModelName, foreignKey.inverseRelationAlias).replace(/"/g, "\\\"")}")`;
1122
+ const buildInverseRelationLine = (sourceModelName, targetModelName, foreignKey, columns = []) => {
1123
+ const sourceColumn = resolveForeignKeyColumn(columns, foreignKey);
1124
+ const fieldName = isOneToOneForeignKey(sourceColumn) ? deriveSingularFieldName(sourceModelName) : deriveCollectionFieldName(sourceModelName);
1125
+ const relationName = deriveRelationAlias(sourceModelName, targetModelName, foreignKey.relationAlias?.trim());
1126
+ return ` ${fieldName} ${isOneToOneForeignKey(sourceColumn) ? `${sourceModelName}?` : `${sourceModelName}[]`} @relation("${relationName.replace(/"/g, "\\\"")}")`;
1117
1127
  };
1118
1128
  /**
1119
1129
  * Inject a line into the body of a Prisma model block if it does not already
@@ -1141,14 +1151,15 @@ const injectLineIntoModelBody = (bodyLines, line, exists) => {
1141
1151
  * @param foreignKeys An array of foreign key definitions to process.
1142
1152
  * @returns The updated Prisma schema string with inverse relations applied.
1143
1153
  */
1144
- const applyInverseRelations = (schema, sourceModelName, foreignKeys) => {
1154
+ const applyInverseRelations = (schema, sourceModelName, foreignKeys, columns = []) => {
1145
1155
  let nextSchema = schema;
1146
1156
  for (const foreignKey of foreignKeys) {
1147
1157
  const targetModel = findModelBlock(nextSchema, foreignKey.referencesTable);
1148
1158
  if (!targetModel) continue;
1149
- const inverseLine = buildInverseRelationLine(sourceModelName, targetModel.modelName, foreignKey);
1159
+ const sourceColumn = resolveForeignKeyColumn(columns, foreignKey);
1160
+ const inverseLine = buildInverseRelationLine(sourceModelName, targetModel.modelName, foreignKey, columns);
1150
1161
  const targetBodyLines = targetModel.block.split("\n");
1151
- const fieldName = deriveCollectionFieldName(sourceModelName);
1162
+ const fieldName = isOneToOneForeignKey(sourceColumn) ? deriveSingularFieldName(sourceModelName) : deriveCollectionFieldName(sourceModelName);
1152
1163
  const fieldRegex = new RegExp(`^\\s*${escapeRegex(fieldName)}\\s+`);
1153
1164
  injectLineIntoModelBody(targetBodyLines, inverseLine, (line) => fieldRegex.test(line));
1154
1165
  const updatedTarget = targetBodyLines.join("\n");
@@ -1167,7 +1178,7 @@ const buildModelBlock = (operation) => {
1167
1178
  const modelName = toModelName(operation.table);
1168
1179
  const mapped = operation.table !== modelName.toLowerCase();
1169
1180
  const fields = operation.columns.map(buildFieldLine);
1170
- const relations = (operation.foreignKeys ?? []).map(buildRelationLine);
1181
+ const relations = (operation.foreignKeys ?? []).map((foreignKey) => buildRelationLine(modelName, foreignKey, operation.columns));
1171
1182
  const metadata = [...(operation.indexes ?? []).map(buildIndexLine), ...mapped ? [` @@map("${str(operation.table).snake()}")`] : []];
1172
1183
  return `model ${modelName} {\n${(metadata.length > 0 ? [
1173
1184
  ...fields,
@@ -1225,7 +1236,7 @@ const applyCreateTableOperation = (schema, operation) => {
1225
1236
  if (findModelBlock(schema, operation.table)) throw new ArkormException(`Prisma model for table [${operation.table}] already exists.`);
1226
1237
  const schemaWithEnums = ensureEnumBlocks(schema, operation.columns);
1227
1238
  const block = buildModelBlock(operation);
1228
- return applyInverseRelations(`${schemaWithEnums.trimEnd()}\n\n${block}\n`, toModelName(operation.table), operation.foreignKeys ?? []);
1239
+ return applyInverseRelations(`${schemaWithEnums.trimEnd()}\n\n${block}\n`, toModelName(operation.table), operation.foreignKeys ?? [], operation.columns);
1229
1240
  };
1230
1241
  /**
1231
1242
  * Apply an alter table operation to a Prisma schema string, modifying the model
@@ -1266,12 +1277,12 @@ const applyAlterTableOperation = (schema, operation) => {
1266
1277
  bodyLines.splice(insertIndex, 0, indexLine);
1267
1278
  });
1268
1279
  for (const foreignKey of operation.addForeignKeys ?? []) {
1269
- const relationLine = buildRelationLine(foreignKey);
1280
+ const relationLine = buildRelationLine(model.modelName, foreignKey, operation.addColumns);
1270
1281
  const relationRegex = new RegExp(`^\\s*${escapeRegex(foreignKey.fieldAlias?.trim() || deriveRelationFieldName(foreignKey.column))}\\s+`);
1271
1282
  injectLineIntoModelBody(bodyLines, relationLine, (line) => relationRegex.test(line));
1272
1283
  }
1273
1284
  block = bodyLines.join("\n");
1274
- return applyInverseRelations(`${schemaWithEnums.slice(0, refreshedModel.start)}${block}${schemaWithEnums.slice(refreshedModel.end)}`, model.modelName, operation.addForeignKeys ?? []);
1285
+ return applyInverseRelations(`${schemaWithEnums.slice(0, refreshedModel.start)}${block}${schemaWithEnums.slice(refreshedModel.end)}`, model.modelName, operation.addForeignKeys ?? [], operation.addColumns);
1275
1286
  };
1276
1287
  /**
1277
1288
  * Apply a drop table operation to a Prisma schema string, removing the model block
@@ -3409,6 +3420,30 @@ var Relation = class {
3409
3420
  if (results instanceof ArkormCollection) return results.all()[0] ?? null;
3410
3421
  return results;
3411
3422
  }
3423
+ /**
3424
+ * Count records that match the relationship query.
3425
+ *
3426
+ * @returns
3427
+ */
3428
+ async count() {
3429
+ return (await this.getQuery()).count();
3430
+ }
3431
+ /**
3432
+ * Determine whether the relationship query has any matching records.
3433
+ *
3434
+ * @returns
3435
+ */
3436
+ async exists() {
3437
+ return (await this.getQuery()).exists();
3438
+ }
3439
+ /**
3440
+ * Determine whether the relationship query has no matching records.
3441
+ *
3442
+ * @returns
3443
+ */
3444
+ async doesntExist() {
3445
+ return !await this.exists();
3446
+ }
3412
3447
  };
3413
3448
 
3414
3449
  //#endregion
@@ -3431,15 +3466,55 @@ var BelongsToManyRelation = class extends Relation {
3431
3466
  this.relatedKey = relatedKey;
3432
3467
  }
3433
3468
  /**
3469
+ * Build the relationship query.
3470
+ *
3471
+ * @returns
3472
+ */
3473
+ async getQuery() {
3474
+ const parentValue = this.parent.getAttribute(this.parentKey);
3475
+ const ids = (await this.related.getDelegate(this.throughDelegate).findMany({ where: { [this.foreignPivotKey]: parentValue } })).map((row) => row[this.relatedPivotKey]);
3476
+ return this.applyConstraint(this.related.query().where({ [this.relatedKey]: { in: ids } }));
3477
+ }
3478
+ /**
3434
3479
  * Fetches the related models for this relationship.
3435
3480
  *
3436
3481
  * @returns
3437
3482
  */
3438
3483
  async getResults() {
3439
- const parentValue = this.parent.getAttribute(this.parentKey);
3440
- const ids = (await this.related.getDelegate(this.throughDelegate).findMany({ where: { [this.foreignPivotKey]: parentValue } })).map((row) => row[this.relatedPivotKey]);
3441
- if (ids.length === 0) return new ArkormCollection([]);
3442
- return this.applyConstraint(this.related.query().where({ [this.relatedKey]: { in: ids } })).get();
3484
+ return (await this.getQuery()).get();
3485
+ }
3486
+ };
3487
+
3488
+ //#endregion
3489
+ //#region src/relationship/SingleResultRelation.ts
3490
+ /**
3491
+ * Base class for relationships that resolve to a single related model.
3492
+ *
3493
+ * @author Legacy (3m1n3nc3)
3494
+ * @since 1.3.0
3495
+ */
3496
+ var SingleResultRelation = class extends Relation {
3497
+ defaultValue;
3498
+ constructor(parent, related) {
3499
+ super();
3500
+ this.parent = parent;
3501
+ this.related = related;
3502
+ }
3503
+ /**
3504
+ * Defines a default value to return when the relationship does not find a related model.
3505
+ *
3506
+ * @param value The default value or a callback that returns the default value.
3507
+ * @returns The current instance for method chaining.
3508
+ */
3509
+ withDefault(value = {}) {
3510
+ this.defaultValue = value;
3511
+ return this;
3512
+ }
3513
+ resolveDefaultResult() {
3514
+ if (typeof this.defaultValue === "undefined") return null;
3515
+ const resolved = typeof this.defaultValue === "function" ? this.defaultValue(this.parent) : this.defaultValue;
3516
+ if (resolved instanceof this.related) return resolved;
3517
+ return this.related.hydrate(resolved);
3443
3518
  }
3444
3519
  };
3445
3520
 
@@ -3451,22 +3526,28 @@ var BelongsToManyRelation = class extends Relation {
3451
3526
  * @author Legacy (3m1n3nc3)
3452
3527
  * @since 0.1.0
3453
3528
  */
3454
- var BelongsToRelation = class extends Relation {
3529
+ var BelongsToRelation = class extends SingleResultRelation {
3455
3530
  constructor(parent, related, foreignKey, ownerKey) {
3456
- super();
3457
- this.parent = parent;
3458
- this.related = related;
3531
+ super(parent, related);
3459
3532
  this.foreignKey = foreignKey;
3460
3533
  this.ownerKey = ownerKey;
3461
3534
  }
3462
3535
  /**
3536
+ * Build the relationship query.
3537
+ *
3538
+ * @returns
3539
+ */
3540
+ async getQuery() {
3541
+ const foreignValue = this.parent.getAttribute(this.foreignKey);
3542
+ return this.applyConstraint(this.related.query().where({ [this.ownerKey]: foreignValue }));
3543
+ }
3544
+ /**
3463
3545
  * Fetches the related models for this relationship.
3464
3546
  *
3465
3547
  * @returns
3466
3548
  */
3467
3549
  async getResults() {
3468
- const foreignValue = this.parent.getAttribute(this.foreignKey);
3469
- return this.applyConstraint(this.related.query().where({ [this.ownerKey]: foreignValue })).first();
3550
+ return await (await this.getQuery()).first() ?? this.resolveDefaultResult();
3470
3551
  }
3471
3552
  };
3472
3553
 
@@ -3487,13 +3568,21 @@ var HasManyRelation = class extends Relation {
3487
3568
  this.localKey = localKey;
3488
3569
  }
3489
3570
  /**
3571
+ * Build the relationship query.
3572
+ *
3573
+ * @returns
3574
+ */
3575
+ async getQuery() {
3576
+ const localValue = this.parent.getAttribute(this.localKey);
3577
+ return this.applyConstraint(this.related.query().where({ [this.foreignKey]: localValue }));
3578
+ }
3579
+ /**
3490
3580
  * Fetches the related models for this relationship.
3491
3581
  *
3492
3582
  * @returns
3493
3583
  */
3494
3584
  async getResults() {
3495
- const localValue = this.parent.getAttribute(this.localKey);
3496
- return this.applyConstraint(this.related.query().where({ [this.foreignKey]: localValue })).get();
3585
+ return (await this.getQuery()).get();
3497
3586
  }
3498
3587
  };
3499
3588
 
@@ -3518,15 +3607,22 @@ var HasManyThroughRelation = class extends Relation {
3518
3607
  this.secondLocalKey = secondLocalKey;
3519
3608
  }
3520
3609
  /**
3610
+ * Build the relationship query.
3611
+ *
3612
+ * @returns
3613
+ */
3614
+ async getQuery() {
3615
+ const localValue = this.parent.getAttribute(this.localKey);
3616
+ const keys = (await this.related.getDelegate(this.throughDelegate).findMany({ where: { [this.firstKey]: localValue } })).map((row) => row[this.secondLocalKey]);
3617
+ return this.applyConstraint(this.related.query().where({ [this.secondKey]: { in: keys } }));
3618
+ }
3619
+ /**
3521
3620
  * Fetches the related models for this relationship.
3522
3621
  *
3523
3622
  * @returns
3524
3623
  */
3525
3624
  async getResults() {
3526
- const localValue = this.parent.getAttribute(this.localKey);
3527
- const keys = (await this.related.getDelegate(this.throughDelegate).findMany({ where: { [this.firstKey]: localValue } })).map((row) => row[this.secondLocalKey]);
3528
- if (keys.length === 0) return new ArkormCollection([]);
3529
- return this.applyConstraint(this.related.query().where({ [this.secondKey]: { in: keys } })).get();
3625
+ return (await this.getQuery()).get();
3530
3626
  }
3531
3627
  };
3532
3628
 
@@ -3538,22 +3634,28 @@ var HasManyThroughRelation = class extends Relation {
3538
3634
  * @author Legacy (3m1n3nc3)
3539
3635
  * @since 0.1.0
3540
3636
  */
3541
- var HasOneRelation = class extends Relation {
3637
+ var HasOneRelation = class extends SingleResultRelation {
3542
3638
  constructor(parent, related, foreignKey, localKey) {
3543
- super();
3544
- this.parent = parent;
3545
- this.related = related;
3639
+ super(parent, related);
3546
3640
  this.foreignKey = foreignKey;
3547
3641
  this.localKey = localKey;
3548
3642
  }
3549
3643
  /**
3644
+ * Build the relationship query.
3645
+ *
3646
+ * @returns
3647
+ */
3648
+ async getQuery() {
3649
+ const localValue = this.parent.getAttribute(this.localKey);
3650
+ return this.applyConstraint(this.related.query().where({ [this.foreignKey]: localValue }));
3651
+ }
3652
+ /**
3550
3653
  * Fetches the related models for this relationship.
3551
3654
  *
3552
3655
  * @returns
3553
3656
  */
3554
3657
  async getResults() {
3555
- const localValue = this.parent.getAttribute(this.localKey);
3556
- return this.applyConstraint(this.related.query().where({ [this.foreignKey]: localValue })).first();
3658
+ return await (await this.getQuery()).first() ?? this.resolveDefaultResult();
3557
3659
  }
3558
3660
  };
3559
3661
 
@@ -3566,11 +3668,9 @@ var HasOneRelation = class extends Relation {
3566
3668
  * @author Legacy (3m1n3nc3)
3567
3669
  * @since 0.1.0
3568
3670
  */
3569
- var HasOneThroughRelation = class extends Relation {
3671
+ var HasOneThroughRelation = class extends SingleResultRelation {
3570
3672
  constructor(parent, related, throughDelegate, firstKey, secondKey, localKey, secondLocalKey) {
3571
- super();
3572
- this.parent = parent;
3573
- this.related = related;
3673
+ super(parent, related);
3574
3674
  this.throughDelegate = throughDelegate;
3575
3675
  this.firstKey = firstKey;
3576
3676
  this.secondKey = secondKey;
@@ -3578,15 +3678,23 @@ var HasOneThroughRelation = class extends Relation {
3578
3678
  this.secondLocalKey = secondLocalKey;
3579
3679
  }
3580
3680
  /**
3681
+ * Build the relationship query.
3682
+ *
3683
+ * @returns
3684
+ */
3685
+ async getQuery() {
3686
+ const localValue = this.parent.getAttribute(this.localKey);
3687
+ const intermediate = await this.related.getDelegate(this.throughDelegate).findFirst({ where: { [this.firstKey]: localValue } });
3688
+ if (!intermediate) return this.applyConstraint(this.related.query().where({ [this.secondKey]: { in: [] } }));
3689
+ return this.applyConstraint(this.related.query().where({ [this.secondKey]: intermediate[this.secondLocalKey] }));
3690
+ }
3691
+ /**
3581
3692
  * Fetches the related models for this relationship.
3582
3693
  *
3583
3694
  * @returns
3584
3695
  */
3585
3696
  async getResults() {
3586
- const localValue = this.parent.getAttribute(this.localKey);
3587
- const intermediate = await this.related.getDelegate(this.throughDelegate).findFirst({ where: { [this.firstKey]: localValue } });
3588
- if (!intermediate) return null;
3589
- return this.applyConstraint(this.related.query().where({ [this.secondKey]: intermediate[this.secondLocalKey] })).first();
3697
+ return await (await this.getQuery()).first() ?? this.resolveDefaultResult();
3590
3698
  }
3591
3699
  };
3592
3700
 
@@ -3607,17 +3715,25 @@ var MorphManyRelation = class extends Relation {
3607
3715
  this.localKey = localKey;
3608
3716
  }
3609
3717
  /**
3610
- * Fetches the related models for this relationship.
3611
- *
3612
- * @returns
3718
+ * Build the relationship query.
3719
+ *
3720
+ * @returns
3613
3721
  */
3614
- async getResults() {
3722
+ async getQuery() {
3615
3723
  const id = this.parent.getAttribute(this.localKey);
3616
3724
  const type = this.parent.constructor.name;
3617
3725
  return this.applyConstraint(this.related.query().where({
3618
3726
  [`${this.morphName}Id`]: id,
3619
3727
  [`${this.morphName}Type`]: type
3620
- })).get();
3728
+ }));
3729
+ }
3730
+ /**
3731
+ * Fetches the related models for this relationship.
3732
+ *
3733
+ * @returns
3734
+ */
3735
+ async getResults() {
3736
+ return (await this.getQuery()).get();
3621
3737
  }
3622
3738
  };
3623
3739
 
@@ -3629,26 +3745,32 @@ var MorphManyRelation = class extends Relation {
3629
3745
  * @author Legacy (3m1n3nc3)
3630
3746
  * @since 0.1.0
3631
3747
  */
3632
- var MorphOneRelation = class extends Relation {
3748
+ var MorphOneRelation = class extends SingleResultRelation {
3633
3749
  constructor(parent, related, morphName, localKey) {
3634
- super();
3635
- this.parent = parent;
3636
- this.related = related;
3750
+ super(parent, related);
3637
3751
  this.morphName = morphName;
3638
3752
  this.localKey = localKey;
3639
3753
  }
3640
3754
  /**
3641
- * Fetches the related models for this relationship.
3642
- *
3643
- * @returns
3755
+ * Build the relationship query.
3756
+ *
3757
+ * @returns
3644
3758
  */
3645
- async getResults() {
3759
+ async getQuery() {
3646
3760
  const id = this.parent.getAttribute(this.localKey);
3647
3761
  const type = this.parent.constructor.name;
3648
3762
  return this.applyConstraint(this.related.query().where({
3649
3763
  [`${this.morphName}Id`]: id,
3650
3764
  [`${this.morphName}Type`]: type
3651
- })).first();
3765
+ }));
3766
+ }
3767
+ /**
3768
+ * Fetches the related models for this relationship.
3769
+ *
3770
+ * @returns
3771
+ */
3772
+ async getResults() {
3773
+ return await (await this.getQuery()).first() ?? this.resolveDefaultResult();
3652
3774
  }
3653
3775
  };
3654
3776
 
@@ -3672,19 +3794,26 @@ var MorphToManyRelation = class extends Relation {
3672
3794
  this.relatedKey = relatedKey;
3673
3795
  }
3674
3796
  /**
3675
- * Fetches the related models for this relationship.
3676
- *
3677
- * @returns
3797
+ * Build the relationship query.
3798
+ *
3799
+ * @returns
3678
3800
  */
3679
- async getResults() {
3801
+ async getQuery() {
3680
3802
  const parentValue = this.parent.getAttribute(this.parentKey);
3681
3803
  const morphType = this.parent.constructor.name;
3682
3804
  const ids = (await this.related.getDelegate(this.throughDelegate).findMany({ where: {
3683
3805
  [`${this.morphName}Id`]: parentValue,
3684
3806
  [`${this.morphName}Type`]: morphType
3685
3807
  } })).map((row) => row[this.relatedPivotKey]);
3686
- if (ids.length === 0) return new ArkormCollection([]);
3687
- return this.applyConstraint(this.related.query().where({ [this.relatedKey]: { in: ids } })).get();
3808
+ return this.applyConstraint(this.related.query().where({ [this.relatedKey]: { in: ids } }));
3809
+ }
3810
+ /**
3811
+ * Fetches the related models for this relationship.
3812
+ *
3813
+ * @returns
3814
+ */
3815
+ async getResults() {
3816
+ return (await this.getQuery()).get();
3688
3817
  }
3689
3818
  };
3690
3819
 
@@ -6376,4 +6505,4 @@ var Model = class Model {
6376
6505
  };
6377
6506
 
6378
6507
  //#endregion
6379
- export { ArkormCollection, ArkormException, Attribute, CliApp, EnumBuilder, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, MissingDelegateException, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_ENUM_MEMBER_REGEX, PRISMA_ENUM_REGEX, PRISMA_MODEL_REGEX, Paginator, QueryBuilder, QueryConstraintException, RelationResolutionException, SEEDER_BRAND, SchemaBuilder, ScopeNotDefinedException, SeedCommand, Seeder, TableBuilder, URLDriver, UniqueConstraintResolutionException, UnsupportedAdapterFeatureException, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToPrismaSchema, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildEnumBlock, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildRelationLine, computeMigrationChecksum, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationFieldName, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findEnumBlock, findModelBlock, formatDefaultValue, formatEnumDefaultValue, formatRelationAction, generateMigrationFile, getActiveTransactionClient, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getRuntimePaginationCurrentPageResolver, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, isTransactionCapableClient, loadArkormConfig, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, removeAppliedMigration, resetArkormRuntimeForTests, resolveCast, resolveEnumName, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePrismaType, runArkormTransaction, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName, writeAppliedMigrationsState };
6508
+ export { ArkormCollection, ArkormException, Attribute, CliApp, EnumBuilder, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, MissingDelegateException, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_ENUM_MEMBER_REGEX, PRISMA_ENUM_REGEX, PRISMA_MODEL_REGEX, Paginator, QueryBuilder, QueryConstraintException, RelationResolutionException, SEEDER_BRAND, SchemaBuilder, ScopeNotDefinedException, SeedCommand, Seeder, TableBuilder, URLDriver, UniqueConstraintResolutionException, UnsupportedAdapterFeatureException, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToPrismaSchema, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildEnumBlock, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildRelationLine, computeMigrationChecksum, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationAlias, deriveRelationFieldName, deriveSingularFieldName, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findEnumBlock, findModelBlock, formatDefaultValue, formatEnumDefaultValue, formatRelationAction, generateMigrationFile, getActiveTransactionClient, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getRuntimePaginationCurrentPageResolver, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, isTransactionCapableClient, loadArkormConfig, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, removeAppliedMigration, resetArkormRuntimeForTests, resolveCast, resolveEnumName, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePrismaType, runArkormTransaction, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName, writeAppliedMigrationsState };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkormx",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Modern TypeScript-first ORM for Node.js.",
5
5
  "keywords": [
6
6
  "orm",