arkormx 2.10.1 → 2.11.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/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_relationship = require('./relationship-DGOpcWA0.cjs');
2
+ const require_relationship = require('./relationship-IC-TAFyG.cjs');
3
3
  let pg = require("pg");
4
4
  let node_path = require("node:path");
5
5
  let module$1 = require("module");
@@ -65,7 +65,8 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
65
65
  rawWhere: true,
66
66
  distinct: true,
67
67
  groupBy: true,
68
- joins: true
68
+ joins: true,
69
+ expressions: true
69
70
  };
70
71
  }
71
72
  resolveConfiguredDatabaseName(connectionString) {
@@ -386,6 +387,13 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
386
387
  }
387
388
  buildSchemaColumnDefinition(table, column) {
388
389
  const parts = [this.quoteIdentifier(column.map ?? column.name), this.resolveSchemaColumnType(table, column)];
390
+ if (column.generatedExpression) {
391
+ const storage = column.generatedStored === false ? "" : " stored";
392
+ parts.push(`generated always as (${column.generatedExpression})${storage}`);
393
+ if (column.unique) parts.push("unique");
394
+ if (!column.nullable && !column.primary) parts.push("not null");
395
+ return parts.join(" ");
396
+ }
389
397
  if (this.shouldUseIdentity(column)) parts.push("generated by default as identity");
390
398
  const defaultValue = this.resolveSchemaColumnDefault(column);
391
399
  if (defaultValue && !this.shouldUseIdentity(column)) parts.push(`default ${defaultValue}`);
@@ -451,12 +459,60 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
451
459
  const table = this.resolveMappedTable(operation.table);
452
460
  await this.ensureEnumTypes(table, operation.addColumns, executor);
453
461
  for (const column of operation.addColumns) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add column if not exists ${this.buildSchemaColumnDefinition(table, column)}`, executor);
462
+ for (const column of operation.changeColumns ?? []) await this.executeChangeColumn(table, column, executor);
454
463
  for (const column of operation.dropColumns) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} drop column if exists ${this.quoteIdentifier(column)}`, executor);
455
464
  for (const foreignKey of operation.addForeignKeys ?? []) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add ${this.buildSchemaForeignKeyConstraint(table, foreignKey, operation.addColumns)}`, executor);
456
465
  if (operation.addPrimaryKey) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add ${this.buildSchemaPrimaryKeyConstraint(table, operation.addPrimaryKey, operation.addColumns)}`, executor);
457
466
  for (const constraint of operation.addUniqueConstraints ?? []) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add ${this.buildSchemaUniqueConstraint(table, constraint, operation.addColumns)}`, executor);
458
467
  for (const index of operation.addIndexes ?? []) await this.executeRawStatement(this.buildSchemaIndexStatement(table, index, operation.addColumns), executor);
459
468
  }
469
+ async enumTypeExists(enumName, executor) {
470
+ const result = await kysely.sql`
471
+ select exists(select 1 from pg_type where typname = ${enumName}) as exists
472
+ `.execute(executor);
473
+ return Boolean(result.rows[0]?.exists);
474
+ }
475
+ /**
476
+ * Redefine an existing column in place using ALTER COLUMN statements: the
477
+ * column type (recreating the enum type when enum values change), nullability,
478
+ * default, and a conventionally-named unique constraint.
479
+ *
480
+ * @param table
481
+ * @param column
482
+ * @param executor
483
+ */
484
+ async executeChangeColumn(table, column, executor) {
485
+ const quotedTable = this.quoteIdentifier(table);
486
+ const physicalName = column.map ?? column.name;
487
+ const physical = this.quoteIdentifier(physicalName);
488
+ if (column.type === "enum") {
489
+ const enumName = this.resolveSchemaEnumName(table, column);
490
+ const values = column.enumValues ?? [];
491
+ if (values.length === 0) throw new require_relationship.ArkormException(`Enum column [${column.name}] requires enum values to change its definition.`);
492
+ const quotedEnum = this.quoteIdentifier(enumName);
493
+ const enumLiterals = values.map((value) => this.quoteLiteral(value)).join(", ");
494
+ if (await this.enumTypeExists(enumName, executor)) {
495
+ const tempEnum = this.quoteIdentifier(`${enumName}__arkorm_change`);
496
+ await this.executeRawStatement(`drop type if exists ${tempEnum}`, executor);
497
+ await this.executeRawStatement(`alter type ${quotedEnum} rename to ${tempEnum}`, executor);
498
+ await this.executeRawStatement(`create type ${quotedEnum} as enum (${enumLiterals})`, executor);
499
+ await this.executeRawStatement(`alter table ${quotedTable} alter column ${physical} type ${quotedEnum} using ${physical}::text::${quotedEnum}`, executor);
500
+ await this.executeRawStatement(`drop type ${tempEnum}`, executor);
501
+ } else {
502
+ await this.executeRawStatement(`create type ${quotedEnum} as enum (${enumLiterals})`, executor);
503
+ await this.executeRawStatement(`alter table ${quotedTable} alter column ${physical} type ${quotedEnum} using ${physical}::text::${quotedEnum}`, executor);
504
+ }
505
+ } else {
506
+ const targetType = this.resolveSchemaColumnType(table, column);
507
+ await this.executeRawStatement(`alter table ${quotedTable} alter column ${physical} type ${targetType} using ${physical}::${targetType}`, executor);
508
+ }
509
+ await this.executeRawStatement(column.nullable ? `alter table ${quotedTable} alter column ${physical} drop not null` : `alter table ${quotedTable} alter column ${physical} set not null`, executor);
510
+ const defaultValue = this.resolveSchemaColumnDefault(column);
511
+ await this.executeRawStatement(defaultValue ? `alter table ${quotedTable} alter column ${physical} set default ${defaultValue}` : `alter table ${quotedTable} alter column ${physical} drop default`, executor);
512
+ const constraint = this.quoteIdentifier(`${table}_${physicalName}_key`);
513
+ await this.executeRawStatement(`alter table ${quotedTable} drop constraint if exists ${constraint}`, executor);
514
+ if (column.unique) await this.executeRawStatement(`alter table ${quotedTable} add constraint ${constraint} unique (${physical})`, executor);
515
+ }
460
516
  async executeDropTableOperation(operation, executor) {
461
517
  const table = this.resolveMappedTable(operation.table);
462
518
  await this.executeRawStatement(`drop table if exists ${this.quoteIdentifier(table)} cascade`, executor);
@@ -595,11 +651,16 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
595
651
  }
596
652
  buildSelectList(target, columns) {
597
653
  if (!columns || columns.length === 0) return kysely.sql.raw("*");
598
- return kysely.sql.join(columns.map(({ column, alias, raw, wildcard }) => {
654
+ return kysely.sql.join(columns.map(({ column, alias, raw, wildcard, expression }) => {
599
655
  if (wildcard) return kysely.sql.raw("*");
656
+ if (expression) {
657
+ const compiled = this.buildExpression(target, expression);
658
+ const resultAlias = alias ?? column;
659
+ return resultAlias ? kysely.sql`${compiled} as ${kysely.sql.id(resultAlias)}` : compiled;
660
+ }
600
661
  if (raw) {
601
- const expression = kysely.sql.raw(column);
602
- return alias ? kysely.sql`${expression} as ${kysely.sql.id(alias)}` : expression;
662
+ const rawExpression = kysely.sql.raw(column);
663
+ return alias ? kysely.sql`${rawExpression} as ${kysely.sql.id(alias)}` : rawExpression;
603
664
  }
604
665
  const mappedColumn = this.mapColumn(target, column);
605
666
  const resultAlias = alias ?? column;
@@ -609,13 +670,18 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
609
670
  }
610
671
  buildOrderBy(target, orderBy) {
611
672
  if (!orderBy || orderBy.length === 0) return kysely.sql``;
612
- return kysely.sql` order by ${kysely.sql.join(orderBy.map(({ column, direction }) => {
613
- return kysely.sql`${kysely.sql.ref(this.mapColumn(target, column))} ${kysely.sql.raw(direction === "desc" ? "desc" : "asc")}`;
673
+ return kysely.sql` order by ${kysely.sql.join(orderBy.map(({ column, direction, expression }) => {
674
+ return kysely.sql`${expression ? this.buildExpression(target, expression) : kysely.sql.ref(this.mapColumn(target, column))} ${kysely.sql.raw(direction === "desc" ? "desc" : "asc")}`;
614
675
  }), kysely.sql`, `)}`;
615
676
  }
616
677
  buildGroupBy(target, groupBy) {
617
678
  if (!groupBy || groupBy.length === 0) return kysely.sql``;
618
- return kysely.sql` group by ${kysely.sql.join(groupBy.map((column) => kysely.sql.ref(this.mapColumn(target, column))), kysely.sql`, `)}`;
679
+ return kysely.sql` group by ${kysely.sql.join(groupBy.map((item) => {
680
+ if (typeof item === "string") return kysely.sql.ref(this.mapColumn(target, item));
681
+ if ("alias" in item) return kysely.sql.ref(item.alias);
682
+ if ("expression" in item) return this.buildExpression(target, item.expression);
683
+ return this.buildRawExpressionFragment(item.raw.sql, item.raw.bindings ?? []);
684
+ }), kysely.sql`, `)}`;
619
685
  }
620
686
  buildHavingClause(target, having) {
621
687
  if (!having) return kysely.sql``;
@@ -764,6 +830,96 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
764
830
  const contains = kysely.sql`${accessor} @> ${jsonValue}::jsonb`;
765
831
  return condition.not ? kysely.sql`not (${contains})` : contains;
766
832
  }
833
+ /**
834
+ * Compiles a serialized {@link ExpressionNode} into a parameterized SQL fragment.
835
+ * Shared by expression-backed select columns, `group by`, `order by`, and any
836
+ * boolean expression used as a `where`/`having` predicate.
837
+ *
838
+ * @param target
839
+ * @param node
840
+ * @returns
841
+ */
842
+ buildExpression(target, node) {
843
+ switch (node.kind) {
844
+ case "column": return this.buildExpressionColumn(target, node.name);
845
+ case "value": return kysely.sql`${node.value}`;
846
+ case "raw": return this.buildRawExpressionFragment(node.sql, node.bindings);
847
+ case "json": return this.buildJsonValueExpression(target, node);
848
+ case "function": {
849
+ const args = node.args.map((arg) => this.buildExpression(target, arg));
850
+ return kysely.sql`${kysely.sql.raw(this.sanitizeFunctionName(node.name))}(${kysely.sql.join(args, kysely.sql`, `)})`;
851
+ }
852
+ case "case": {
853
+ const branches = node.cases.map((branch) => kysely.sql`when ${this.buildExpression(target, branch.when)} then ${this.buildExpression(target, branch.then)}`);
854
+ const elseClause = node.else ? kysely.sql` else ${this.buildExpression(target, node.else)}` : kysely.sql``;
855
+ return kysely.sql`case ${kysely.sql.join(branches, kysely.sql` `)}${elseClause} end`;
856
+ }
857
+ case "binary": return this.buildBinaryExpression(target, node);
858
+ case "in": {
859
+ const operand = this.buildExpression(target, node.operand);
860
+ const values = node.values.map((value) => this.buildExpression(target, value));
861
+ const list = values.length > 0 ? kysely.sql.join(values, kysely.sql`, `) : kysely.sql`null`;
862
+ return node.not ? kysely.sql`(${operand} not in (${list}))` : kysely.sql`(${operand} in (${list}))`;
863
+ }
864
+ case "null-check": {
865
+ const operand = this.buildExpression(target, node.operand);
866
+ return node.not ? kysely.sql`(${operand} is not null)` : kysely.sql`(${operand} is null)`;
867
+ }
868
+ case "aggregate": return this.buildAggregateExpression(target, node);
869
+ default: throw new require_relationship.ArkormException(`Unsupported expression node [${node.kind}].`);
870
+ }
871
+ }
872
+ buildExpressionColumn(target, name) {
873
+ if (name.includes(".")) return kysely.sql.ref(name);
874
+ return kysely.sql.ref(this.mapColumn(target, name));
875
+ }
876
+ buildBinaryExpression(target, node) {
877
+ const left = this.buildExpression(target, node.left);
878
+ const right = this.buildExpression(target, node.right);
879
+ switch (node.operator) {
880
+ case "like": return kysely.sql`(${left} like ${right})`;
881
+ case "ilike": return kysely.sql`(${left} ilike ${right})`;
882
+ case "not-like": return kysely.sql`(${left} not like ${right})`;
883
+ case "not-ilike": return kysely.sql`(${left} not ilike ${right})`;
884
+ case "and": return kysely.sql`(${left} and ${right})`;
885
+ case "or": return kysely.sql`(${left} or ${right})`;
886
+ default: return kysely.sql`(${left} ${kysely.sql.raw(node.operator)} ${right})`;
887
+ }
888
+ }
889
+ buildAggregateExpression(target, node) {
890
+ const argument = node.arg ? this.buildExpression(target, node.arg) : kysely.sql.raw("*");
891
+ const distinctKeyword = node.distinct ? kysely.sql`distinct ` : kysely.sql``;
892
+ let call = kysely.sql`${kysely.sql.raw(node.fn)}(${distinctKeyword}${argument})`;
893
+ if (node.filter) call = kysely.sql`${call} filter (where ${this.buildExpression(target, node.filter)})`;
894
+ if (node.fn === "sum" || node.fn === "avg") return kysely.sql`(${call})::double precision`;
895
+ if (node.fn === "count") return kysely.sql`(${call})::bigint`;
896
+ return call;
897
+ }
898
+ buildJsonValueExpression(target, node) {
899
+ const base = kysely.sql`${kysely.sql.ref(this.mapColumn(target, node.column))}::jsonb`;
900
+ let accessor;
901
+ if (node.path.length === 0) accessor = base;
902
+ else if (node.path.length === 1) accessor = kysely.sql`(${base} ->> ${node.path[0]})`;
903
+ else accessor = kysely.sql`(${base} #>> ${`{${node.path.join(",")}}`}::text[])`;
904
+ if (node.cast === "number") return kysely.sql`(${accessor})::numeric`;
905
+ if (node.cast === "boolean") return kysely.sql`(${accessor})::boolean`;
906
+ return accessor;
907
+ }
908
+ buildRawExpressionFragment(rawSql, bindings) {
909
+ const segments = rawSql.split("?");
910
+ if (segments.length !== bindings.length + 1) throw new require_relationship.ArkormException("Raw expression bindings do not match the number of placeholders.");
911
+ const parts = [];
912
+ segments.forEach((segment, index) => {
913
+ if (segment.length > 0) parts.push(kysely.sql.raw(this.quoteCamelCaseIdentifiers(segment)));
914
+ if (index < bindings.length) parts.push(kysely.sql`${bindings[index]}`);
915
+ });
916
+ if (parts.length === 0) return kysely.sql``;
917
+ return kysely.sql`${kysely.sql.join(parts, kysely.sql``)}`;
918
+ }
919
+ sanitizeFunctionName(name) {
920
+ if (!/^[a-zA-Z_][a-zA-Z0-9_.]*$/.test(name)) throw new require_relationship.ArkormException(`Unsupported SQL function name [${name}].`);
921
+ return name;
922
+ }
767
923
  buildWhereCondition(target, condition) {
768
924
  if (!condition) return kysely.sql`1 = 1`;
769
925
  if (condition.type === "comparison") return this.buildComparisonCondition(target, condition);
@@ -773,6 +929,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
773
929
  if (condition.type === "exists") return this.buildExistsCondition(condition);
774
930
  if (condition.type === "full-text") return this.buildFullTextCondition(target, condition);
775
931
  if (condition.type === "json") return this.buildJsonCondition(target, condition);
932
+ if (condition.type === "expression") return kysely.sql`${this.buildExpression(target, condition.expression)}`;
776
933
  if (condition.type === "group") {
777
934
  const group = condition;
778
935
  const conditions = group.conditions.map((entry) => {
@@ -1645,6 +1802,7 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
1645
1802
  rawWhere: false,
1646
1803
  distinct: false,
1647
1804
  groupBy: false,
1805
+ expressions: false,
1648
1806
  returning: false
1649
1807
  };
1650
1808
  }
@@ -1680,6 +1838,14 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
1680
1838
  }
1681
1839
  toQuerySelect(columns) {
1682
1840
  if (!columns || columns.length === 0) return void 0;
1841
+ const expressionColumn = columns.find((column) => column.expression);
1842
+ if (expressionColumn) throw new require_relationship.UnsupportedAdapterFeatureException("Expression select columns are not supported by the Prisma compatibility adapter; use a SQL-backed adapter.", {
1843
+ operation: "adapter.select",
1844
+ meta: {
1845
+ feature: "expressions",
1846
+ alias: expressionColumn.alias
1847
+ }
1848
+ });
1683
1849
  const rawColumn = columns.find((column) => column.raw);
1684
1850
  if (rawColumn) throw new require_relationship.UnsupportedAdapterFeatureException("Raw select expressions are not supported by the Prisma compatibility adapter; use a SQL-backed adapter or DB.raw().", {
1685
1851
  operation: "adapter.select",
@@ -1697,6 +1863,10 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
1697
1863
  }
1698
1864
  toQueryOrderBy(orderBy) {
1699
1865
  if (!orderBy || orderBy.length === 0) return void 0;
1866
+ if (orderBy.some((entry) => entry.expression)) throw new require_relationship.UnsupportedAdapterFeatureException("Order-by expressions are not supported by the Prisma compatibility adapter; use a SQL-backed adapter.", {
1867
+ operation: "adapter.select",
1868
+ meta: { feature: "expressions" }
1869
+ });
1700
1870
  return orderBy.map((entry) => ({ [entry.column]: entry.direction }));
1701
1871
  }
1702
1872
  toComparisonWhere(condition) {
@@ -3326,13 +3496,22 @@ var Migration = class {
3326
3496
  static {
3327
3497
  this[MIGRATION_BRAND] = true;
3328
3498
  }
3499
+ /**
3500
+ * Optional lifecycle hook invoked after the migration's schema operations
3501
+ * have been applied to the database, for either direction. Override it to run
3502
+ * extra logic such as seeding or data backfills once the schema is in place.
3503
+ *
3504
+ * @param direction The direction that just ran (`'up'` or `'down'`).
3505
+ */
3506
+ done(_direction) {}
3329
3507
  };
3330
3508
 
3331
3509
  //#endregion
3332
3510
  //#region src/cli/commands/MigrateCommand.ts
3333
3511
  /**
3334
3512
  * The MigrateCommand class implements the CLI command for applying migration
3335
- * classes to the Prisma schema and running the Prisma workflow.
3513
+ * classes to the database or Prisma schema and running the Prisma workflow when
3514
+ * using the Prisma compatibility driver.
3336
3515
  *
3337
3516
  * @author Legacy (3m1n3nc3)
3338
3517
  * @since 0.1.0
@@ -3343,22 +3522,22 @@ var MigrateCommand = class extends _h3ravel_musket.Command {
3343
3522
  this.signature = `migrate
3344
3523
  {name? : Migration class or file name}
3345
3524
  {--all : Run all migrations from the configured migrations directory}
3346
- {--deploy : Use prisma migrate deploy instead of migrate dev}
3347
- {--skip-generate : Skip prisma generate}
3525
+ {--deploy : Use prisma migrate deploy instead of migrate dev (Prisma compatibility driver only)}
3526
+ {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
3348
3527
  {--skip-migrate : Skip prisma migrate command}
3349
3528
  {--state-file= : Path to applied migration state file}
3350
- {--schema= : Explicit prisma schema path}
3351
- {--migration-name= : Name for prisma migrate dev}
3529
+ {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
3530
+ {--migration-name= : Name for prisma migrate dev (Prisma compatibility driver only)}
3352
3531
  {--create-database : Create the configured database without prompting}
3353
3532
  `;
3354
- this.description = "Apply migration classes to schema.prisma and run Prisma workflow";
3533
+ this.description = "Apply migration classes to the database or schema.prisma and run Prisma workflow when using the Prisma compatibility driver";
3355
3534
  }
3356
3535
  /**
3357
3536
  * Command handler for the migrate command.
3358
3537
  * This method is responsible for orchestrating the migration
3359
3538
  * process, including loading migration classes, applying them to
3360
- * the Prisma schema, and running the appropriate Prisma commands
3361
- * based on the provided options.
3539
+ * the the database or Prisma schema, and running the appropriate Prisma commands
3540
+ * when using the Prisma compatibility driver based on the provided options.
3362
3541
  *
3363
3542
  * @returns
3364
3543
  */
@@ -3567,10 +3746,10 @@ var MigrateFreshCommand = class extends _h3ravel_musket.Command {
3567
3746
  constructor(..._args) {
3568
3747
  super(..._args);
3569
3748
  this.signature = `migrate:fresh
3570
- {--skip-generate : Skip prisma generate}
3571
- {--skip-migrate : Skip prisma database sync}
3749
+ {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
3750
+ {--skip-migrate : Skip prisma database sync (Prisma compatibility driver only)}
3572
3751
  {--state-file= : Path to applied migration state file}
3573
- {--schema= : Explicit prisma schema path}
3752
+ {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
3574
3753
  {--create-database : Create the configured database without prompting}
3575
3754
  `;
3576
3755
  this.description = "Reset the database and rerun all migration classes";
@@ -3725,12 +3904,12 @@ var MigrateRollbackCommand = class extends _h3ravel_musket.Command {
3725
3904
  this.signature = `migrate:rollback
3726
3905
  {--step= : Number of latest applied migration classes to rollback}
3727
3906
  {--dry-run : Preview rollback targets without applying changes}
3728
- {--deploy : Use prisma migrate deploy instead of migrate dev}
3729
- {--skip-generate : Skip prisma generate}
3730
- {--skip-migrate : Skip prisma migrate command}
3907
+ {--deploy : Use prisma migrate deploy instead of migrate dev (Prisma compatibility driver only)}
3908
+ {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
3909
+ {--skip-migrate : Skip prisma migrate command (Prisma compatibility driver only)}
3731
3910
  {--state-file= : Path to applied migration state file}
3732
- {--schema= : Explicit prisma schema path}
3733
- {--migration-name= : Name for prisma migrate dev}
3911
+ {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
3912
+ {--migration-name= : Name for prisma migrate dev (Prisma compatibility driver only)}
3734
3913
  `;
3735
3914
  this.description = "Rollback migration classes from schema.prisma and run Prisma workflow";
3736
3915
  }
@@ -3745,7 +3924,7 @@ var MigrateRollbackCommand = class extends _h3ravel_musket.Command {
3745
3924
  const useDatabaseMigrations = require_relationship.supportsDatabaseMigrationExecution(adapter);
3746
3925
  const persistedFeatures = require_relationship.resolvePersistedMetadataFeatures(this.app.getConfig("features"));
3747
3926
  let appliedState = await require_relationship.readAppliedMigrationsStateFromStore(adapter, stateFilePath);
3748
- const stepOption = this.option("step");
3927
+ const stepOption = this.option("step", 1);
3749
3928
  const stepCount = stepOption == null ? void 0 : Number(stepOption);
3750
3929
  if (stepCount != null && (!Number.isFinite(stepCount) || stepCount <= 0 || !Number.isInteger(stepCount))) return void this.error("Error: --step must be a positive integer.");
3751
3930
  const targets = stepCount ? require_relationship.getLatestAppliedMigrations(appliedState, stepCount) : (() => {
@@ -4420,14 +4599,34 @@ var QueryBuilder = class QueryBuilder {
4420
4599
  return Math.max(1, resolvedPage);
4421
4600
  }
4422
4601
  where(whereOrCallback) {
4602
+ if (whereOrCallback instanceof require_relationship.Expression) return this.appendExpressionCondition("AND", whereOrCallback);
4423
4603
  if (typeof whereOrCallback === "function") return this.appendNestedWhere("AND", whereOrCallback);
4424
4604
  return this.addLogicalWhere("AND", whereOrCallback);
4425
4605
  }
4426
4606
  orWhere(whereOrCallback) {
4607
+ if (whereOrCallback instanceof require_relationship.Expression) return this.appendExpressionCondition("OR", whereOrCallback);
4427
4608
  if (typeof whereOrCallback === "function") return this.appendNestedWhere("OR", whereOrCallback);
4428
4609
  return this.addLogicalWhere("OR", whereOrCallback);
4429
4610
  }
4430
4611
  /**
4612
+ * Appends a boolean {@link Expression} as a where predicate. When the query is
4613
+ * using the Prisma-like legacy where representation, the expression is merged in
4614
+ * as a structured condition alongside it.
4615
+ */
4616
+ appendExpressionCondition(boolean, expression) {
4617
+ const condition = {
4618
+ type: "expression",
4619
+ expression: expression.toExpressionNode()
4620
+ };
4621
+ if (this.legacyWhere) {
4622
+ const existing = this.tryBuildQueryCondition(this.legacyWhere);
4623
+ this.legacyWhere = void 0;
4624
+ if (existing) this.queryWhere = existing;
4625
+ }
4626
+ this.appendQueryCondition(boolean, condition);
4627
+ return this;
4628
+ }
4629
+ /**
4431
4630
  * Resolve a callback into a parenthesized group condition and append it.
4432
4631
  */
4433
4632
  appendNestedWhere(boolean, callback) {
@@ -5077,15 +5276,17 @@ var QueryBuilder = class QueryBuilder {
5077
5276
  whereIn(key, values) {
5078
5277
  return this.where({ [key]: { in: values } });
5079
5278
  }
5080
- /**
5081
- * Adds an orderBy clause to the query. This will overwrite any existing orderBy clause.
5082
- *
5083
- * @param orderBy
5084
- * @returns
5085
- */
5086
- orderBy(orderBy) {
5279
+ orderBy(orderByOrExpression, direction = "asc") {
5087
5280
  this.randomOrderEnabled = false;
5088
- const normalized = this.normalizeQueryOrderBy(orderBy);
5281
+ if (orderByOrExpression instanceof require_relationship.Expression) {
5282
+ this.queryOrderBy = [...this.queryOrderBy ?? [], {
5283
+ column: "",
5284
+ direction,
5285
+ expression: orderByOrExpression.toExpressionNode()
5286
+ }];
5287
+ return this;
5288
+ }
5289
+ const normalized = this.normalizeQueryOrderBy(orderByOrExpression);
5089
5290
  if (!normalized) throw new require_relationship.UnsupportedAdapterFeatureException("Order clauses must use Arkorm-normalizable column directions.", {
5090
5291
  operation: "orderBy",
5091
5292
  model: this.model.name
@@ -5094,6 +5295,28 @@ var QueryBuilder = class QueryBuilder {
5094
5295
  return this;
5095
5296
  }
5096
5297
  /**
5298
+ * Appends a raw SQL `order by` fragment (with positional `?` bindings), useful
5299
+ * for ordering by a computed expression the builder does not model directly.
5300
+ *
5301
+ * @param sql
5302
+ * @param bindings
5303
+ * @param direction
5304
+ * @returns
5305
+ */
5306
+ orderByRaw(sql, bindings = [], direction = "asc") {
5307
+ this.randomOrderEnabled = false;
5308
+ this.queryOrderBy = [...this.queryOrderBy ?? [], {
5309
+ column: "",
5310
+ direction,
5311
+ expression: {
5312
+ kind: "raw",
5313
+ sql,
5314
+ bindings
5315
+ }
5316
+ }];
5317
+ return this;
5318
+ }
5319
+ /**
5097
5320
  * Puts the query results in random order.
5098
5321
  *
5099
5322
  * @returns
@@ -5459,12 +5682,6 @@ var QueryBuilder = class QueryBuilder {
5459
5682
  pipe(callback) {
5460
5683
  return callback(this);
5461
5684
  }
5462
- /**
5463
- * Adds a select clause to the query. This will overwrite any existing select clause.
5464
- *
5465
- * @param select
5466
- * @returns
5467
- */
5468
5685
  select(select) {
5469
5686
  const normalized = this.normalizeQuerySelect(select);
5470
5687
  if (normalized === null) throw new require_relationship.UnsupportedAdapterFeatureException("Select clauses must use Arkorm-normalizable column projections.", {
@@ -5474,12 +5691,6 @@ var QueryBuilder = class QueryBuilder {
5474
5691
  this.querySelect = normalized;
5475
5692
  return this;
5476
5693
  }
5477
- /**
5478
- * Appends columns or expressions to the existing select clause.
5479
- *
5480
- * @param select
5481
- * @returns
5482
- */
5483
5694
  addSelect(select) {
5484
5695
  const normalized = this.normalizeQuerySelect(select);
5485
5696
  if (normalized === null) throw new require_relationship.UnsupportedAdapterFeatureException("Select clauses must use Arkorm-normalizable column projections.", {
@@ -5503,6 +5714,8 @@ var QueryBuilder = class QueryBuilder {
5503
5714
  return this;
5504
5715
  }
5505
5716
  groupBy(...columns) {
5717
+ const first = columns[0];
5718
+ if (columns.length === 1 && this.isGroupByAggregateSpec(first)) return this.executeGroupByAggregate(first);
5506
5719
  const normalized = Array.isArray(columns[0]) ? columns[0] : columns;
5507
5720
  if (normalized.length === 0) throw new QueryConstraintException("groupBy requires at least one column.", {
5508
5721
  operation: "groupBy",
@@ -5511,6 +5724,109 @@ var QueryBuilder = class QueryBuilder {
5511
5724
  this.queryGroupBy = [...normalized];
5512
5725
  return this;
5513
5726
  }
5727
+ /**
5728
+ * Appends a raw SQL `group by` fragment (with positional `?` bindings), mirroring
5729
+ * `whereRaw`/`havingRaw`. Combines with any columns/expressions already grouped.
5730
+ *
5731
+ * @param sql
5732
+ * @param bindings
5733
+ * @returns
5734
+ */
5735
+ groupByRaw(sql, bindings = []) {
5736
+ this.queryGroupBy = [...this.queryGroupBy ?? [], { raw: {
5737
+ sql,
5738
+ bindings
5739
+ } }];
5740
+ return this;
5741
+ }
5742
+ /**
5743
+ * Resolves the recorded group-by sources into adapter {@link QueryGroupByItem}s.
5744
+ * A bare string that matches a select-column alias is expanded to that column's
5745
+ * underlying expression (group-by-alias); otherwise it is treated as a column.
5746
+ */
5747
+ buildGroupByItems(selectColumns) {
5748
+ if (!this.queryGroupBy || this.queryGroupBy.length === 0) return void 0;
5749
+ const expressionAliases = /* @__PURE__ */ new Map();
5750
+ selectColumns?.forEach((column) => {
5751
+ if (column.expression && column.alias) expressionAliases.set(JSON.stringify(column.expression), column.alias);
5752
+ });
5753
+ const aliasNames = new Set(expressionAliases.values());
5754
+ return this.queryGroupBy.map((source) => {
5755
+ if (source instanceof require_relationship.Expression) {
5756
+ const node = source.toExpressionNode();
5757
+ const alias = expressionAliases.get(JSON.stringify(node));
5758
+ return alias ? { alias } : { expression: node };
5759
+ }
5760
+ if (typeof source === "object") return { raw: source.raw };
5761
+ return aliasNames.has(source) ? { alias: source } : source;
5762
+ });
5763
+ }
5764
+ isGroupByAggregateSpec(value) {
5765
+ return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof require_relationship.Expression) && Array.isArray(value.by);
5766
+ }
5767
+ /**
5768
+ * Executes the query and returns plain, un-hydrated rows keyed by their select
5769
+ * alias — the natural shape for `select` + `groupBy` aggregate reports. Pass a
5770
+ * row type to describe the projection.
5771
+ *
5772
+ * @returns
5773
+ */
5774
+ async getRows() {
5775
+ return await this.executeReadRows();
5776
+ }
5777
+ /**
5778
+ * Runs a Prisma-style grouped aggregate and returns typed rows shaped as
5779
+ * `{ <by columns>, _sum, _avg, _min, _max, _count }`.
5780
+ */
5781
+ async executeGroupByAggregate(spec) {
5782
+ const selectMap = {};
5783
+ spec.by.forEach((column) => {
5784
+ selectMap[column] = true;
5785
+ });
5786
+ const aggregates = [];
5787
+ const register = (group, factory, map, numeric) => {
5788
+ Object.keys(map).forEach((column) => {
5789
+ if (!map[column]) return;
5790
+ const alias = `${group}_${column}`;
5791
+ selectMap[alias] = factory(column);
5792
+ aggregates.push({
5793
+ group,
5794
+ column,
5795
+ alias,
5796
+ numeric
5797
+ });
5798
+ });
5799
+ };
5800
+ if (spec._sum) register("_sum", (column) => require_relationship.sum(column), spec._sum, true);
5801
+ if (spec._avg) register("_avg", (column) => require_relationship.avg(column), spec._avg, true);
5802
+ if (spec._min) register("_min", (column) => require_relationship.min(column), spec._min, false);
5803
+ if (spec._max) register("_max", (column) => require_relationship.max(column), spec._max, false);
5804
+ let countAllAlias;
5805
+ if (spec._count === true) {
5806
+ countAllAlias = "_count_all";
5807
+ selectMap[countAllAlias] = require_relationship.count();
5808
+ } else if (spec._count) register("_count", (column) => require_relationship.count(column), spec._count, true);
5809
+ this.select(selectMap);
5810
+ this.groupBy(spec.by);
5811
+ return (await this.getRows()).map((row) => {
5812
+ const result = {};
5813
+ spec.by.forEach((column) => {
5814
+ result[column] = row[column];
5815
+ });
5816
+ const grouped = {};
5817
+ aggregates.forEach(({ group, column, alias, numeric }) => {
5818
+ grouped[group] ??= {};
5819
+ grouped[group][column] = numeric ? this.coerceNumeric(row[alias]) : row[alias];
5820
+ });
5821
+ Object.assign(result, grouped);
5822
+ if (countAllAlias) result._count = this.coerceNumeric(row[countAllAlias]);
5823
+ return result;
5824
+ });
5825
+ }
5826
+ coerceNumeric(value) {
5827
+ if (value === null || value === void 0) return null;
5828
+ return Number(value);
5829
+ }
5514
5830
  appendHavingCondition(boolean, condition) {
5515
5831
  if (!this.queryHaving) {
5516
5832
  this.queryHaving = condition;
@@ -5531,12 +5847,35 @@ var QueryBuilder = class QueryBuilder {
5531
5847
  value: hasOperator ? maybeValue : operatorOrValue
5532
5848
  };
5533
5849
  }
5534
- having(column, operatorOrValue, maybeValue) {
5535
- this.appendHavingCondition("AND", this.buildHavingComparison(operatorOrValue, maybeValue, column));
5850
+ /**
5851
+ * Resolves the three `having` call shapes into a condition: `having(column, )`,
5852
+ * `having(expression)` (a boolean expression predicate), and
5853
+ * `having(expression, operator, value)` (compare an aggregate to a value).
5854
+ */
5855
+ buildHavingCondition(columnOrExpression, operatorOrValue, maybeValue) {
5856
+ if (columnOrExpression instanceof require_relationship.Expression) return {
5857
+ type: "expression",
5858
+ expression: (operatorOrValue === void 0 ? columnOrExpression : this.compareExpression(columnOrExpression, operatorOrValue, maybeValue)).toExpressionNode()
5859
+ };
5860
+ return this.buildHavingComparison(operatorOrValue, maybeValue, columnOrExpression);
5861
+ }
5862
+ compareExpression(expression, operator, value) {
5863
+ switch (operator) {
5864
+ case "=": return expression.eq(value);
5865
+ case "!=": return expression.ne(value);
5866
+ case ">": return expression.gt(value);
5867
+ case ">=": return expression.gte(value);
5868
+ case "<": return expression.lt(value);
5869
+ case "<=": return expression.lte(value);
5870
+ default: return expression.eq(value);
5871
+ }
5872
+ }
5873
+ having(columnOrExpression, operatorOrValue, maybeValue) {
5874
+ this.appendHavingCondition("AND", this.buildHavingCondition(columnOrExpression, operatorOrValue, maybeValue));
5536
5875
  return this;
5537
5876
  }
5538
- orHaving(column, operatorOrValue, maybeValue) {
5539
- this.appendHavingCondition("OR", this.buildHavingComparison(operatorOrValue, maybeValue, column));
5877
+ orHaving(columnOrExpression, operatorOrValue, maybeValue) {
5878
+ this.appendHavingCondition("OR", this.buildHavingCondition(columnOrExpression, operatorOrValue, maybeValue));
5540
5879
  return this;
5541
5880
  }
5542
5881
  /**
@@ -6694,12 +7033,19 @@ var QueryBuilder = class QueryBuilder {
6694
7033
  }
6695
7034
  if (typeof select !== "object" || !select) return null;
6696
7035
  const entries = Object.entries(select);
6697
- if (entries.some(([, value]) => value !== true && value !== false && value !== void 0 && typeof value !== "string")) return null;
6698
- const columns = entries.filter(([, value]) => value === true || typeof value === "string").map(([column, value]) => typeof value === "string" ? {
6699
- column,
6700
- alias: value,
6701
- raw: true
6702
- } : { column });
7036
+ if (entries.some(([, value]) => value !== true && value !== false && value !== void 0 && typeof value !== "string" && !(value instanceof require_relationship.Expression))) return null;
7037
+ const columns = entries.filter(([, value]) => value === true || typeof value === "string" || value instanceof require_relationship.Expression).map(([column, value]) => {
7038
+ if (value instanceof require_relationship.Expression) return {
7039
+ column,
7040
+ alias: column,
7041
+ expression: value.toExpressionNode()
7042
+ };
7043
+ return typeof value === "string" ? {
7044
+ column,
7045
+ alias: value,
7046
+ raw: true
7047
+ } : { column };
7048
+ });
6703
7049
  return columns.length > 0 ? columns : [];
6704
7050
  }
6705
7051
  normalizeQueryOrderBy(orderBy) {
@@ -6857,7 +7203,7 @@ var QueryBuilder = class QueryBuilder {
6857
7203
  offset: normalizedQuery.offsetValue,
6858
7204
  columns: normalizedQuery.querySelect ? [...normalizedQuery.querySelect] : void 0,
6859
7205
  distinct: normalizedQuery.queryDistinct || void 0,
6860
- groupBy: normalizedQuery.queryGroupBy ? [...normalizedQuery.queryGroupBy] : void 0,
7206
+ groupBy: normalizedQuery.queryGroupBy ? normalizedQuery.queryGroupBy.filter((source) => typeof source === "string") : void 0,
6861
7207
  relationLoads: this.mergeRelationLoadPlans(normalizedQuery.queryRelationLoads ? this.cloneRelationLoads(normalizedQuery.queryRelationLoads) : void 0, this.mergeRelationLoadPlans(callbackRelationLoads, childRelationLoads))
6862
7208
  });
6863
7209
  }
@@ -7121,11 +7467,11 @@ var QueryBuilder = class QueryBuilder {
7121
7467
  if (columns === null || orderBy === null || condition === null) return null;
7122
7468
  if (this.hasRelationFilters() && this.canExecuteRelationFiltersInAdapter() && relationFilters === null) return null;
7123
7469
  if (this.hasRelationAggregates() && this.canExecuteRelationAggregatesInAdapter() && relationAggregates === null) return null;
7124
- return {
7470
+ return this.expandComputedAttributes({
7125
7471
  target: this.buildQueryTarget(),
7126
7472
  columns,
7127
7473
  distinct: this.queryDistinct || void 0,
7128
- groupBy: this.queryGroupBy ? [...this.queryGroupBy] : void 0,
7474
+ groupBy: this.buildGroupByItems(columns ?? void 0),
7129
7475
  having: this.queryHaving,
7130
7476
  joins: this.queryJoins ? [...this.queryJoins] : void 0,
7131
7477
  where: condition,
@@ -7135,8 +7481,87 @@ var QueryBuilder = class QueryBuilder {
7135
7481
  relationLoads: this.queryRelationLoads,
7136
7482
  relationFilters: this.canExecuteRelationFiltersInAdapter() ? relationFilters ?? void 0 : void 0,
7137
7483
  relationAggregates: this.canExecuteRelationAggregatesInAdapter() ? relationAggregates ?? void 0 : void 0
7484
+ });
7485
+ }
7486
+ /** Reads and caches the model's resolved `static computed` expression map. */
7487
+ computedAttributes() {
7488
+ const model = this.model;
7489
+ return typeof model.getComputed === "function" ? model.getComputed() : {};
7490
+ }
7491
+ /**
7492
+ * Expands references to `static computed` attribute names into their backing
7493
+ * expressions across a select spec's columns, group by, order by, where, and
7494
+ * having clauses. A no-op when the model declares no computed attributes.
7495
+ */
7496
+ expandComputedAttributes(spec) {
7497
+ const computed = this.computedAttributes();
7498
+ if (Object.keys(computed).length === 0) return spec;
7499
+ const columns = spec.columns?.map((column) => {
7500
+ if (column.expression || column.raw || column.wildcard) return column;
7501
+ const expression = computed[column.column];
7502
+ return expression ? {
7503
+ ...column,
7504
+ expression,
7505
+ alias: column.alias ?? column.column
7506
+ } : column;
7507
+ });
7508
+ const selectedComputedAliases = new Set(columns?.filter((column) => column.expression && column.alias).map((column) => column.alias));
7509
+ return {
7510
+ ...spec,
7511
+ columns,
7512
+ groupBy: spec.groupBy?.map((item) => {
7513
+ if (typeof item !== "string") return item;
7514
+ const expression = computed[item];
7515
+ if (!expression) return item;
7516
+ return selectedComputedAliases.has(item) ? { alias: item } : { expression };
7517
+ }),
7518
+ orderBy: spec.orderBy?.map((clause) => {
7519
+ if (clause.expression) return clause;
7520
+ const expression = computed[clause.column];
7521
+ return expression ? {
7522
+ ...clause,
7523
+ expression
7524
+ } : clause;
7525
+ }),
7526
+ where: spec.where ? this.expandComputedCondition(spec.where, computed) : spec.where,
7527
+ having: spec.having ? this.expandComputedCondition(spec.having, computed) : spec.having
7138
7528
  };
7139
7529
  }
7530
+ expandComputedCondition(condition, computed) {
7531
+ if (condition.type === "comparison" && computed[condition.column]) return {
7532
+ type: "expression",
7533
+ expression: this.computedComparison(computed[condition.column], condition.operator, condition.value)
7534
+ };
7535
+ if (condition.type === "group") return {
7536
+ ...condition,
7537
+ conditions: condition.conditions.map((entry) => this.expandComputedCondition(entry, computed))
7538
+ };
7539
+ if (condition.type === "not") return {
7540
+ ...condition,
7541
+ condition: this.expandComputedCondition(condition.condition, computed)
7542
+ };
7543
+ return condition;
7544
+ }
7545
+ /** Converts a where comparison against a computed attribute into an expression. */
7546
+ computedComparison(node, operator, value) {
7547
+ const expression = require_relationship.fromExpressionNode(node);
7548
+ const list = Array.isArray(value) ? value : [];
7549
+ switch (operator) {
7550
+ case "!=": return expression.ne(value).toExpressionNode();
7551
+ case ">": return expression.gt(value).toExpressionNode();
7552
+ case ">=": return expression.gte(value).toExpressionNode();
7553
+ case "<": return expression.lt(value).toExpressionNode();
7554
+ case "<=": return expression.lte(value).toExpressionNode();
7555
+ case "in": return expression.in(list).toExpressionNode();
7556
+ case "not-in": return expression.notIn(list).toExpressionNode();
7557
+ case "is-null": return expression.isNull().toExpressionNode();
7558
+ case "is-not-null": return expression.isNotNull().toExpressionNode();
7559
+ case "contains": return expression.like(`%${String(value)}%`).toExpressionNode();
7560
+ case "starts-with": return expression.like(`${String(value)}%`).toExpressionNode();
7561
+ case "ends-with": return expression.like(`%${String(value)}`).toExpressionNode();
7562
+ default: return expression.eq(value).toExpressionNode();
7563
+ }
7564
+ }
7140
7565
  tryBuildAggregateSpec() {
7141
7566
  const condition = this.buildQueryWhereCondition(false);
7142
7567
  const relationFilters = this.tryBuildRelationFilterSpecs();
@@ -7635,6 +8060,9 @@ var Model = class Model {
7635
8060
  static {
7636
8061
  this.castMapCache = /* @__PURE__ */ new WeakMap();
7637
8062
  }
8063
+ static {
8064
+ this.computedCache = /* @__PURE__ */ new WeakMap();
8065
+ }
7638
8066
  static {
7639
8067
  this.emittedDeprecationWarnings = /* @__PURE__ */ new Set();
7640
8068
  }
@@ -7785,6 +8213,19 @@ var Model = class Model {
7785
8213
  return casts;
7786
8214
  }
7787
8215
  /**
8216
+ * Resolves the model's `static computed` declarations into expression nodes,
8217
+ * cached per class. Returns an empty map when no computed attributes exist.
8218
+ */
8219
+ static getComputed() {
8220
+ const cached = Model.computedCache.get(this);
8221
+ if (cached) return cached;
8222
+ const definitions = this.computed;
8223
+ const resolved = {};
8224
+ if (definitions) for (const [name, factory] of Object.entries(definitions)) resolved[name] = factory(require_relationship.expressionBuilder).toExpressionNode();
8225
+ Model.computedCache.set(this, resolved);
8226
+ return resolved;
8227
+ }
8228
+ /**
7788
8229
  * Apply built-in persistence casts (currently `json` serialisation) to a raw
7789
8230
  * attribute payload, without re-running arbitrary custom setters. Used by
7790
8231
  * both instance `save()` and the query-builder insert/update paths so a JS
@@ -8191,6 +8632,22 @@ var Model = class Model {
8191
8632
  });
8192
8633
  return this;
8193
8634
  }
8635
+ /**
8636
+ * Merge already-stored (database representation) attribute values into the
8637
+ * model without running set mutators or casts. Used to refresh the instance
8638
+ * from a row returned by a write, where the values are already in storage
8639
+ * form and must not be re-cast (re-applying a non-idempotent set-cast such as
8640
+ * a money or array cast would corrupt the value).
8641
+ *
8642
+ * @param attributes
8643
+ * @returns
8644
+ */
8645
+ fillRawAttributes(attributes) {
8646
+ Object.entries(attributes).forEach(([key, value]) => {
8647
+ this.attributes[key] = Model.cloneAttributeValue(value);
8648
+ });
8649
+ return this;
8650
+ }
8194
8651
  async update(attributes) {
8195
8652
  try {
8196
8653
  const primaryKey = this.constructor.getPrimaryKey();
@@ -8246,7 +8703,7 @@ var Model = class Model {
8246
8703
  await Model.dispatchEvent(constructor, "creating", this);
8247
8704
  const payload = this.normalizePersistenceAttributes(this.getRawAttributes());
8248
8705
  const model = await constructor.query().create(payload);
8249
- this.fill(model.getRawAttributes());
8706
+ this.fillRawAttributes(model.getRawAttributes());
8250
8707
  this.syncChanges(previousOriginal);
8251
8708
  this.syncPrevious(previousOriginal);
8252
8709
  this.syncOriginal();
@@ -8263,7 +8720,7 @@ var Model = class Model {
8263
8720
  const payload = this.normalizePersistenceAttributes(this.getDirtyAttributes());
8264
8721
  delete payload[primaryKey];
8265
8722
  const model = await constructor.query().where({ [primaryKey]: identifier }).update(payload);
8266
- this.fill(model.getRawAttributes());
8723
+ this.fillRawAttributes(model.getRawAttributes());
8267
8724
  this.syncChanges(previousOriginal);
8268
8725
  this.syncPrevious(previousOriginal);
8269
8726
  this.syncOriginal();
@@ -8306,7 +8763,7 @@ var Model = class Model {
8306
8763
  const softDeleteConfig = constructor.getSoftDeleteConfig();
8307
8764
  if (softDeleteConfig.enabled) {
8308
8765
  const model = await constructor.query().where({ [primaryKey]: identifier }).update({ [softDeleteConfig.column]: /* @__PURE__ */ new Date() });
8309
- this.fill(model.getRawAttributes());
8766
+ this.fillRawAttributes(model.getRawAttributes());
8310
8767
  this.syncChanges(previousOriginal);
8311
8768
  this.syncOriginal();
8312
8769
  await Model.dispatchEvent(constructor, "deleted", this);
@@ -8381,7 +8838,7 @@ var Model = class Model {
8381
8838
  const previousOriginal = this.getOriginal();
8382
8839
  await Model.dispatchEvent(constructor, "restoring", this);
8383
8840
  const model = await constructor.query().withTrashed().where({ [primaryKey]: identifier }).update({ [softDeleteConfig.column]: null });
8384
- this.fill(model.getRawAttributes());
8841
+ this.fillRawAttributes(model.getRawAttributes());
8385
8842
  this.syncChanges(previousOriginal);
8386
8843
  this.syncOriginal();
8387
8844
  await Model.dispatchEvent(constructor, "restored", this);
@@ -9625,18 +10082,22 @@ var PivotModel = class extends Model {
9625
10082
  };
9626
10083
 
9627
10084
  //#endregion
10085
+ exports.AggregateExpression = require_relationship.AggregateExpression;
9628
10086
  exports.Arkorm = Arkorm;
9629
10087
  exports.ArkormCollection = require_relationship.ArkormCollection;
9630
10088
  exports.ArkormException = require_relationship.ArkormException;
9631
10089
  exports.Arkormx = Arkormx;
9632
10090
  exports.Attribute = Attribute;
10091
+ exports.CaseExpression = require_relationship.CaseExpression;
9633
10092
  exports.CliApp = CliApp;
9634
10093
  exports.DB = DB;
9635
10094
  exports.EnumBuilder = require_relationship.EnumBuilder;
10095
+ exports.Expression = require_relationship.Expression;
9636
10096
  exports.ForeignKeyBuilder = require_relationship.ForeignKeyBuilder;
9637
10097
  exports.InitCommand = InitCommand;
9638
10098
  exports.InlineFactory = InlineFactory;
9639
10099
  exports.JoinClause = JoinClause;
10100
+ exports.JsonExpression = require_relationship.JsonExpression;
9640
10101
  exports.KyselyDatabaseAdapter = KyselyDatabaseAdapter;
9641
10102
  exports.LengthAwarePaginator = require_relationship.LengthAwarePaginator;
9642
10103
  exports.MIGRATION_BRAND = MIGRATION_BRAND;
@@ -9684,6 +10145,7 @@ exports.applyMigrationToDatabase = require_relationship.applyMigrationToDatabase
9684
10145
  exports.applyMigrationToPrismaSchema = require_relationship.applyMigrationToPrismaSchema;
9685
10146
  exports.applyOperationsToPersistedColumnMappingsState = require_relationship.applyOperationsToPersistedColumnMappingsState;
9686
10147
  exports.applyOperationsToPrismaSchema = require_relationship.applyOperationsToPrismaSchema;
10148
+ exports.avg = require_relationship.avg;
9687
10149
  exports.awaitConfiguredModelsRegistration = require_relationship.awaitConfiguredModelsRegistration;
9688
10150
  exports.bindAdapterToModels = require_relationship.bindAdapterToModels;
9689
10151
  exports.buildEnumBlock = require_relationship.buildEnumBlock;
@@ -9697,8 +10159,12 @@ exports.buildModelBlock = require_relationship.buildModelBlock;
9697
10159
  exports.buildPrimaryKeyLine = require_relationship.buildPrimaryKeyLine;
9698
10160
  exports.buildRelationLine = require_relationship.buildRelationLine;
9699
10161
  exports.buildUniqueConstraintLine = require_relationship.buildUniqueConstraintLine;
10162
+ exports.caseWhen = require_relationship.caseWhen;
10163
+ exports.coalesce = require_relationship.coalesce;
10164
+ exports.col = require_relationship.col;
9700
10165
  exports.computeMigrationChecksum = require_relationship.computeMigrationChecksum;
9701
10166
  exports.configureArkormRuntime = require_relationship.configureArkormRuntime;
10167
+ exports.count = require_relationship.count;
9702
10168
  exports.createEmptyAppliedMigrationsState = require_relationship.createEmptyAppliedMigrationsState;
9703
10169
  exports.createEmptyPersistedColumnMappingsState = require_relationship.createEmptyPersistedColumnMappingsState;
9704
10170
  exports.createKyselyAdapter = createKyselyAdapter;
@@ -9719,12 +10185,15 @@ exports.deriveSingularFieldName = require_relationship.deriveSingularFieldName;
9719
10185
  exports.emitRuntimeDebugEvent = require_relationship.emitRuntimeDebugEvent;
9720
10186
  exports.ensureArkormConfigLoading = require_relationship.ensureArkormConfigLoading;
9721
10187
  exports.escapeRegex = require_relationship.escapeRegex;
10188
+ exports.expressionBuilder = require_relationship.expressionBuilder;
9722
10189
  exports.findAppliedMigration = require_relationship.findAppliedMigration;
9723
10190
  exports.findEnumBlock = require_relationship.findEnumBlock;
9724
10191
  exports.findModelBlock = require_relationship.findModelBlock;
10192
+ exports.fn = require_relationship.fn;
9725
10193
  exports.formatDefaultValue = require_relationship.formatDefaultValue;
9726
10194
  exports.formatEnumDefaultValue = require_relationship.formatEnumDefaultValue;
9727
10195
  exports.formatRelationAction = require_relationship.formatRelationAction;
10196
+ exports.fromExpressionNode = require_relationship.fromExpressionNode;
9728
10197
  exports.generateMigrationFile = require_relationship.generateMigrationFile;
9729
10198
  exports.getActiveTransactionAdapter = require_relationship.getActiveTransactionAdapter;
9730
10199
  exports.getActiveTransactionClient = require_relationship.getActiveTransactionClient;
@@ -9756,6 +10225,7 @@ exports.isDelegateLike = require_relationship.isDelegateLike;
9756
10225
  exports.isMigrationApplied = require_relationship.isMigrationApplied;
9757
10226
  exports.isQuerySchemaLike = require_relationship.isQuerySchemaLike;
9758
10227
  exports.isTransactionCapableClient = require_relationship.isTransactionCapableClient;
10228
+ exports.json = require_relationship.json;
9759
10229
  exports.loadArkormConfig = require_relationship.loadArkormConfig;
9760
10230
  exports.loadFactoriesFrom = require_relationship.loadFactoriesFrom;
9761
10231
  exports.loadMigrationsFrom = require_relationship.loadMigrationsFrom;
@@ -9763,7 +10233,10 @@ exports.loadModelsFrom = require_relationship.loadModelsFrom;
9763
10233
  exports.loadSeedersFrom = require_relationship.loadSeedersFrom;
9764
10234
  exports.markMigrationApplied = require_relationship.markMigrationApplied;
9765
10235
  exports.markMigrationRun = require_relationship.markMigrationRun;
10236
+ exports.max = require_relationship.max;
10237
+ exports.min = require_relationship.min;
9766
10238
  exports.pad = require_relationship.pad;
10239
+ exports.raw = require_relationship.raw;
9767
10240
  exports.readAppliedMigrationsState = require_relationship.readAppliedMigrationsState;
9768
10241
  exports.readAppliedMigrationsStateFromStore = require_relationship.readAppliedMigrationsStateFromStore;
9769
10242
  exports.readPersistedColumnMappingsState = require_relationship.readPersistedColumnMappingsState;
@@ -9780,6 +10253,7 @@ exports.resetRuntimeRegistryForTests = require_relationship.resetRuntimeRegistry
9780
10253
  exports.resolveCast = resolveCast;
9781
10254
  exports.resolveColumnMappingsFilePath = require_relationship.resolveColumnMappingsFilePath;
9782
10255
  exports.resolveEnumName = require_relationship.resolveEnumName;
10256
+ exports.resolveGeneratedExpression = require_relationship.resolveGeneratedExpression;
9783
10257
  exports.resolveMigrationClassName = require_relationship.resolveMigrationClassName;
9784
10258
  exports.resolveMigrationStateFilePath = require_relationship.resolveMigrationStateFilePath;
9785
10259
  exports.resolvePersistedMetadataFeatures = require_relationship.resolvePersistedMetadataFeatures;
@@ -9790,6 +10264,7 @@ exports.runArkormTransaction = require_relationship.runArkormTransaction;
9790
10264
  exports.runMigrationWithPrisma = require_relationship.runMigrationWithPrisma;
9791
10265
  exports.runPrismaCommand = require_relationship.runPrismaCommand;
9792
10266
  exports.stripPrismaSchemaModelsAndEnums = require_relationship.stripPrismaSchemaModelsAndEnums;
10267
+ exports.sum = require_relationship.sum;
9793
10268
  exports.supportsDatabaseCreation = require_relationship.supportsDatabaseCreation;
9794
10269
  exports.supportsDatabaseMigrationExecution = require_relationship.supportsDatabaseMigrationExecution;
9795
10270
  exports.supportsDatabaseMigrationState = require_relationship.supportsDatabaseMigrationState;
@@ -9797,7 +10272,9 @@ exports.supportsDatabaseReset = require_relationship.supportsDatabaseReset;
9797
10272
  exports.syncPersistedColumnMappingsFromState = require_relationship.syncPersistedColumnMappingsFromState;
9798
10273
  exports.toMigrationFileSlug = require_relationship.toMigrationFileSlug;
9799
10274
  exports.toModelName = require_relationship.toModelName;
10275
+ exports.val = require_relationship.val;
9800
10276
  exports.validatePersistedMetadataFeaturesForMigrations = require_relationship.validatePersistedMetadataFeaturesForMigrations;
10277
+ exports.where = require_relationship.where;
9801
10278
  exports.writeAppliedMigrationsState = require_relationship.writeAppliedMigrationsState;
9802
10279
  exports.writeAppliedMigrationsStateToStore = require_relationship.writeAppliedMigrationsStateToStore;
9803
10280
  exports.writePersistedColumnMappingsState = require_relationship.writePersistedColumnMappingsState;