arkormx 2.10.0 → 2.10.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
@@ -1,4 +1,4 @@
1
- import { $ as applyOperationsToPersistedColumnMappingsState, $t as resolvePrismaType, A as getRuntimePrismaClient, An as writeAppliedMigrationsStateToStore, At as buildInverseRelationLine, B as getRegisteredModels, Bt as deriveRelationFieldName, C as getActiveTransactionClient, Cn as markMigrationRun, Ct as applyMigrationRollbackToPrismaSchema, D as getRuntimeDebugHandler, Dn as resolveMigrationStateFilePath, Dt as buildEnumBlock, E as getRuntimeClient, En as removeAppliedMigration, Et as applyOperationsToPrismaSchema, F as loadArkormConfig, Fn as RelationResolutionException, Ft as buildUniqueConstraintLine, G as loadModelsFrom, Gt as formatDefaultValue, H as getRegisteredSeeders, Ht as escapeRegex, I as resetArkormRuntimeForTests, In as ArkormCollection, It as createMigrationTimestamp, J as registerMigrations, Jt as generateMigrationFile, K as loadSeedersFrom, Kt as formatEnumDefaultValue, L as runArkormTransaction, Ln as ArkormException, Lt as deriveCollectionFieldName, M as isDelegateLike, Mn as UnsupportedAdapterFeatureException, Mt as buildModelBlock, N as isQuerySchemaLike, Nn as SetBasedEagerLoader, Nt as buildPrimaryKeyLine, O as getRuntimePaginationCurrentPageResolver, On as supportsDatabaseMigrationState, Ot as buildFieldLine, P as isTransactionCapableClient, Pt as buildRelationLine, Q as resetRuntimeRegistryForTests, Qt as resolveMigrationClassName, R as getRegisteredFactories, Rt as deriveInverseRelationAlias, S as getActiveTransactionAdapter, Sn as markMigrationApplied, St as applyMigrationRollbackToDatabase, T as getRuntimeAdapter, Tn as readAppliedMigrationsStateFromStore, Tt as applyMigrationToPrismaSchema, U as loadFactoriesFrom, Ut as findEnumBlock, V as getRegisteredPaths, Vt as deriveSingularFieldName, W as loadMigrationsFrom, Wt as findModelBlock, X as registerPaths, Xt as pad, Y as registerModels, Yt as getMigrationPlan, Z as registerSeeders, Zt as resolveEnumName, _ as bindAdapterToModels, _n as deleteAppliedMigrationsStateFromStore, _t as PRISMA_ENUM_REGEX, a as HasOneThroughRelation, an as supportsDatabaseReset, at as getPersistedPrimaryKeyGeneration, b as emitRuntimeDebugEvent, bn as getLatestAppliedMigrations, bt as applyCreateTableOperation, c as HasManyRelation, cn as SchemaBuilder, ct as readPersistedColumnMappingsState, d as BelongsToManyRelation, dn as PrimaryKeyGenerationPlanner, dt as resolveColumnMappingsFilePath, en as runMigrationWithPrisma, et as createEmptyPersistedColumnMappingsState, f as Relation, fn as ForeignKeyBuilder, ft as resolvePersistedMetadataFeatures, g as awaitConfiguredModelsRegistration, gn as createEmptyAppliedMigrationsState, gt as PRISMA_ENUM_MEMBER_REGEX, h as URLDriver, hn as computeMigrationChecksum, ht as writePersistedColumnMappingsState, i as MorphManyRelation, in as supportsDatabaseMigrationExecution, it as getPersistedEnumTsType, j as getUserConfig, jn as RuntimeModuleLoader, jt as buildMigrationSource, k as getRuntimePaginationURLDriverFactory, kn as writeAppliedMigrationsState, kt as buildIndexLine, l as BelongsToRelation, ln as EnumBuilder, lt as rebuildPersistedColumnMappingsState, m as Paginator, mn as buildMigrationRunId, mt as validatePersistedMetadataFeaturesForMigrations, n as MorphToManyRelation, nn as stripPrismaSchemaModelsAndEnums, nt as getPersistedColumnMap, o as HasOneRelation, on as toMigrationFileSlug, ot as getPersistedTableMetadata, p as LengthAwarePaginator, pn as buildMigrationIdentity, pt as syncPersistedColumnMappingsFromState, q as registerFactories, qt as formatRelationAction, r as MorphOneRelation, rn as supportsDatabaseCreation, rt as getPersistedEnumMap, s as HasManyThroughRelation, sn as toModelName, st as getPersistedTimestampColumns, t as MorphToRelation, tn as runPrismaCommand, tt as deletePersistedColumnMappingsState, un as TableBuilder, ut as resetPersistedColumnMappingsCache, v as configureArkormRuntime, vn as findAppliedMigration, vt as PRISMA_MODEL_REGEX, w as getDefaultStubsPath, wn as readAppliedMigrationsState, wt as applyMigrationToDatabase, x as ensureArkormConfigLoading, xn as isMigrationApplied, xt as applyDropTableOperation, y as defineConfig, yn as getLastMigrationRun, yt as applyAlterTableOperation, z as getRegisteredMigrations, zt as deriveRelationAlias } from "./relationship-CmhzOlEo.mjs";
1
+ import { $ as applyOperationsToPersistedColumnMappingsState, $t as resolvePrismaType, A as getRuntimePrismaClient, An as writeAppliedMigrationsStateToStore, At as buildInverseRelationLine, B as getRegisteredModels, Bt as deriveRelationFieldName, C as getActiveTransactionClient, Cn as markMigrationRun, Ct as applyMigrationRollbackToPrismaSchema, D as getRuntimeDebugHandler, Dn as resolveMigrationStateFilePath, Dt as buildEnumBlock, E as getRuntimeClient, En as removeAppliedMigration, Et as applyOperationsToPrismaSchema, F as loadArkormConfig, Fn as RelationResolutionException, Ft as buildUniqueConstraintLine, G as loadModelsFrom, Gt as formatDefaultValue, H as getRegisteredSeeders, Ht as escapeRegex, I as resetArkormRuntimeForTests, In as ArkormCollection, It as createMigrationTimestamp, J as registerMigrations, Jt as generateMigrationFile, K as loadSeedersFrom, Kt as formatEnumDefaultValue, L as runArkormTransaction, Ln as ArkormException, Lt as deriveCollectionFieldName, M as isDelegateLike, Mn as UnsupportedAdapterFeatureException, Mt as buildModelBlock, N as isQuerySchemaLike, Nn as SetBasedEagerLoader, Nt as buildPrimaryKeyLine, O as getRuntimePaginationCurrentPageResolver, On as supportsDatabaseMigrationState, Ot as buildFieldLine, P as isTransactionCapableClient, Pt as buildRelationLine, Q as resetRuntimeRegistryForTests, Qt as resolveMigrationClassName, R as getRegisteredFactories, Rt as deriveInverseRelationAlias, S as getActiveTransactionAdapter, Sn as markMigrationApplied, St as applyMigrationRollbackToDatabase, T as getRuntimeAdapter, Tn as readAppliedMigrationsStateFromStore, Tt as applyMigrationToPrismaSchema, U as loadFactoriesFrom, Ut as findEnumBlock, V as getRegisteredPaths, Vt as deriveSingularFieldName, W as loadMigrationsFrom, Wt as findModelBlock, X as registerPaths, Xt as pad, Y as registerModels, Yt as getMigrationPlan, Z as registerSeeders, Zt as resolveEnumName, _ as bindAdapterToModels, _n as deleteAppliedMigrationsStateFromStore, _t as PRISMA_ENUM_REGEX, a as HasOneThroughRelation, an as supportsDatabaseReset, at as getPersistedPrimaryKeyGeneration, b as emitRuntimeDebugEvent, bn as getLatestAppliedMigrations, bt as applyCreateTableOperation, c as HasManyRelation, cn as SchemaBuilder, ct as readPersistedColumnMappingsState, d as BelongsToManyRelation, dn as PrimaryKeyGenerationPlanner, dt as resolveColumnMappingsFilePath, en as runMigrationWithPrisma, et as createEmptyPersistedColumnMappingsState, f as Relation, fn as ForeignKeyBuilder, ft as resolvePersistedMetadataFeatures, g as awaitConfiguredModelsRegistration, gn as createEmptyAppliedMigrationsState, gt as PRISMA_ENUM_MEMBER_REGEX, h as URLDriver, hn as computeMigrationChecksum, ht as writePersistedColumnMappingsState, i as MorphManyRelation, in as supportsDatabaseMigrationExecution, it as getPersistedEnumTsType, j as getUserConfig, jn as RuntimeModuleLoader, jt as buildMigrationSource, k as getRuntimePaginationURLDriverFactory, kn as writeAppliedMigrationsState, kt as buildIndexLine, l as BelongsToRelation, ln as EnumBuilder, lt as rebuildPersistedColumnMappingsState, m as Paginator, mn as buildMigrationRunId, mt as validatePersistedMetadataFeaturesForMigrations, n as MorphToManyRelation, nn as stripPrismaSchemaModelsAndEnums, nt as getPersistedColumnMap, o as HasOneRelation, on as toMigrationFileSlug, ot as getPersistedTableMetadata, p as LengthAwarePaginator, pn as buildMigrationIdentity, pt as syncPersistedColumnMappingsFromState, q as registerFactories, qt as formatRelationAction, r as MorphOneRelation, rn as supportsDatabaseCreation, rt as getPersistedEnumMap, s as HasManyThroughRelation, sn as toModelName, st as getPersistedTimestampColumns, t as MorphToRelation, tn as runPrismaCommand, tt as deletePersistedColumnMappingsState, un as TableBuilder, ut as resetPersistedColumnMappingsCache, v as configureArkormRuntime, vn as findAppliedMigration, vt as PRISMA_MODEL_REGEX, w as getDefaultStubsPath, wn as readAppliedMigrationsState, wt as applyMigrationToDatabase, x as ensureArkormConfigLoading, xn as isMigrationApplied, xt as applyDropTableOperation, y as defineConfig, yn as getLastMigrationRun, yt as applyAlterTableOperation, z as getRegisteredMigrations, zt as deriveRelationAlias } from "./relationship-SFhKrphd.mjs";
2
2
  import { Pool } from "pg";
3
3
  import { join, resolve } from "node:path";
4
4
  import { createRequire } from "module";
@@ -450,12 +450,60 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
450
450
  const table = this.resolveMappedTable(operation.table);
451
451
  await this.ensureEnumTypes(table, operation.addColumns, executor);
452
452
  for (const column of operation.addColumns) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add column if not exists ${this.buildSchemaColumnDefinition(table, column)}`, executor);
453
+ for (const column of operation.changeColumns ?? []) await this.executeChangeColumn(table, column, executor);
453
454
  for (const column of operation.dropColumns) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} drop column if exists ${this.quoteIdentifier(column)}`, executor);
454
455
  for (const foreignKey of operation.addForeignKeys ?? []) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add ${this.buildSchemaForeignKeyConstraint(table, foreignKey, operation.addColumns)}`, executor);
455
456
  if (operation.addPrimaryKey) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add ${this.buildSchemaPrimaryKeyConstraint(table, operation.addPrimaryKey, operation.addColumns)}`, executor);
456
457
  for (const constraint of operation.addUniqueConstraints ?? []) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add ${this.buildSchemaUniqueConstraint(table, constraint, operation.addColumns)}`, executor);
457
458
  for (const index of operation.addIndexes ?? []) await this.executeRawStatement(this.buildSchemaIndexStatement(table, index, operation.addColumns), executor);
458
459
  }
460
+ async enumTypeExists(enumName, executor) {
461
+ const result = await sql`
462
+ select exists(select 1 from pg_type where typname = ${enumName}) as exists
463
+ `.execute(executor);
464
+ return Boolean(result.rows[0]?.exists);
465
+ }
466
+ /**
467
+ * Redefine an existing column in place using ALTER COLUMN statements: the
468
+ * column type (recreating the enum type when enum values change), nullability,
469
+ * default, and a conventionally-named unique constraint.
470
+ *
471
+ * @param table
472
+ * @param column
473
+ * @param executor
474
+ */
475
+ async executeChangeColumn(table, column, executor) {
476
+ const quotedTable = this.quoteIdentifier(table);
477
+ const physicalName = column.map ?? column.name;
478
+ const physical = this.quoteIdentifier(physicalName);
479
+ if (column.type === "enum") {
480
+ const enumName = this.resolveSchemaEnumName(table, column);
481
+ const values = column.enumValues ?? [];
482
+ if (values.length === 0) throw new ArkormException(`Enum column [${column.name}] requires enum values to change its definition.`);
483
+ const quotedEnum = this.quoteIdentifier(enumName);
484
+ const enumLiterals = values.map((value) => this.quoteLiteral(value)).join(", ");
485
+ if (await this.enumTypeExists(enumName, executor)) {
486
+ const tempEnum = this.quoteIdentifier(`${enumName}__arkorm_change`);
487
+ await this.executeRawStatement(`drop type if exists ${tempEnum}`, executor);
488
+ await this.executeRawStatement(`alter type ${quotedEnum} rename to ${tempEnum}`, executor);
489
+ await this.executeRawStatement(`create type ${quotedEnum} as enum (${enumLiterals})`, executor);
490
+ await this.executeRawStatement(`alter table ${quotedTable} alter column ${physical} type ${quotedEnum} using ${physical}::text::${quotedEnum}`, executor);
491
+ await this.executeRawStatement(`drop type ${tempEnum}`, executor);
492
+ } else {
493
+ await this.executeRawStatement(`create type ${quotedEnum} as enum (${enumLiterals})`, executor);
494
+ await this.executeRawStatement(`alter table ${quotedTable} alter column ${physical} type ${quotedEnum} using ${physical}::text::${quotedEnum}`, executor);
495
+ }
496
+ } else {
497
+ const targetType = this.resolveSchemaColumnType(table, column);
498
+ await this.executeRawStatement(`alter table ${quotedTable} alter column ${physical} type ${targetType} using ${physical}::${targetType}`, executor);
499
+ }
500
+ await this.executeRawStatement(column.nullable ? `alter table ${quotedTable} alter column ${physical} drop not null` : `alter table ${quotedTable} alter column ${physical} set not null`, executor);
501
+ const defaultValue = this.resolveSchemaColumnDefault(column);
502
+ await this.executeRawStatement(defaultValue ? `alter table ${quotedTable} alter column ${physical} set default ${defaultValue}` : `alter table ${quotedTable} alter column ${physical} drop default`, executor);
503
+ const constraint = this.quoteIdentifier(`${table}_${physicalName}_key`);
504
+ await this.executeRawStatement(`alter table ${quotedTable} drop constraint if exists ${constraint}`, executor);
505
+ if (column.unique) await this.executeRawStatement(`alter table ${quotedTable} add constraint ${constraint} unique (${physical})`, executor);
506
+ }
459
507
  async executeDropTableOperation(operation, executor) {
460
508
  const table = this.resolveMappedTable(operation.table);
461
509
  await this.executeRawStatement(`drop table if exists ${this.quoteIdentifier(table)} cascade`, executor);
@@ -3325,6 +3373,14 @@ var Migration = class {
3325
3373
  static {
3326
3374
  this[MIGRATION_BRAND] = true;
3327
3375
  }
3376
+ /**
3377
+ * Optional lifecycle hook invoked after the migration's schema operations
3378
+ * have been applied to the database, for either direction. Override it to run
3379
+ * extra logic such as seeding or data backfills once the schema is in place.
3380
+ *
3381
+ * @param direction The direction that just ran (`'up'` or `'down'`).
3382
+ */
3383
+ done(_direction) {}
3328
3384
  };
3329
3385
 
3330
3386
  //#endregion
@@ -6265,10 +6321,11 @@ var QueryBuilder = class QueryBuilder {
6265
6321
  return affected;
6266
6322
  }
6267
6323
  /**
6268
- * Deletes the first record matching the current query constraints and returns
6269
- * it as a hydrated model instance. Returns null when no record matches.
6324
+ * Deletes every record matching the current query constraints and returns the
6325
+ * number of rows deleted (Laravel parity: `int delete()`). A where clause is
6326
+ * required — guarding against an accidental full-table delete.
6270
6327
  *
6271
- * @returns
6328
+ * @returns the count of deleted rows (0 when nothing matched)
6272
6329
  */
6273
6330
  async delete() {
6274
6331
  const where = this.buildWhere();
@@ -6276,40 +6333,17 @@ var QueryBuilder = class QueryBuilder {
6276
6333
  operation: "delete",
6277
6334
  model: this.model.name
6278
6335
  });
6279
- const directSpec = this.tryBuildDeleteSpec(where);
6280
- const adapter = this.requireAdapter();
6281
- if (!this.isUniqueWhere(where) && directSpec && typeof adapter.deleteFirst === "function") {
6282
- const deleted = await adapter.deleteFirst(directSpec);
6283
- if (!deleted) return null;
6284
- return this.hydrateDeleted(deleted);
6285
- }
6286
- const uniqueWhere = await this.resolveUniqueWhere(where, false);
6287
- if (!uniqueWhere) return null;
6288
- const deleted = await this.executeDeleteRow(uniqueWhere, false);
6289
- if (!deleted) return null;
6290
- return this.hydrateDeleted(deleted);
6336
+ return this.executeDeleteManyRows(where);
6291
6337
  }
6292
6338
  /**
6293
- * Hydrate a row that was just deleted, marking the resulting model as no
6294
- * longer existing in the database.
6339
+ * Deletes every record matching the current query constraints and throws when
6340
+ * none matched.
6295
6341
  *
6296
- * @param attributes
6297
- * @returns
6298
- */
6299
- hydrateDeleted(attributes) {
6300
- const model = this.model.hydrate(attributes);
6301
- model.exists = false;
6302
- return model;
6303
- }
6304
- /**
6305
- * Deletes the first record matching the current query constraints and throws
6306
- * when no record matches.
6307
- *
6308
- * @returns
6342
+ * @returns the count of deleted rows (always >= 1)
6309
6343
  */
6310
6344
  async deleteOrFail() {
6311
6345
  const deleted = await this.delete();
6312
- if (!deleted) throw new ModelNotFoundException(this.model.name, "Record not found for delete operation.", { operation: "delete" });
6346
+ if (deleted === 0) throw new ModelNotFoundException(this.model.name, "Record not found for delete operation.", { operation: "delete" });
6313
6347
  return deleted;
6314
6348
  }
6315
6349
  tryBuildInsertSpec(values) {
@@ -6356,14 +6390,6 @@ var QueryBuilder = class QueryBuilder {
6356
6390
  values
6357
6391
  };
6358
6392
  }
6359
- tryBuildDeleteSpec(where) {
6360
- const condition = this.tryBuildQueryCondition(where);
6361
- if (!condition) return null;
6362
- return {
6363
- target: this.buildQueryTarget(),
6364
- where: condition
6365
- };
6366
- }
6367
6393
  /**
6368
6394
  * Counts the number of records matching the current query constraints.
6369
6395
  *
@@ -7294,17 +7320,31 @@ var QueryBuilder = class QueryBuilder {
7294
7320
  }
7295
7321
  return updated;
7296
7322
  }
7297
- async executeDeleteRow(where, failIfMissing = true) {
7323
+ async executeDeleteManyRows(where) {
7298
7324
  const adapter = this.requireAdapter();
7299
- const spec = this.tryBuildDeleteSpec(where);
7300
- if (!spec) throw new UnsupportedAdapterFeatureException("Delete could not be compiled into an Arkorm delete specification.", {
7325
+ const condition = this.tryBuildQueryCondition(where);
7326
+ if (condition === null) throw new UnsupportedAdapterFeatureException("Delete could not be compiled into an Arkorm delete specification.", {
7301
7327
  operation: "query.delete",
7302
7328
  model: this.model.name
7303
7329
  });
7304
- const deleted = await adapter.delete(spec);
7305
- if (!deleted) return failIfMissing ? (() => {
7306
- throw new ModelNotFoundException(this.model.name, "Record not found for delete operation.", { operation: "delete" });
7307
- })() : null;
7330
+ const spec = {
7331
+ target: this.buildQueryTarget(),
7332
+ where: condition
7333
+ };
7334
+ if (typeof adapter.deleteMany === "function") return await adapter.deleteMany(spec);
7335
+ const rows = await adapter.select({
7336
+ target: spec.target,
7337
+ where: spec.where
7338
+ });
7339
+ let deleted = 0;
7340
+ for (const row of rows) {
7341
+ const rowWhere = this.tryBuildQueryCondition(row);
7342
+ if (!rowWhere) continue;
7343
+ if (await adapter.delete({
7344
+ target: spec.target,
7345
+ where: rowWhere
7346
+ })) deleted += 1;
7347
+ }
7308
7348
  return deleted;
7309
7349
  }
7310
7350
  /**
@@ -8206,6 +8246,22 @@ var Model = class Model {
8206
8246
  });
8207
8247
  return this;
8208
8248
  }
8249
+ /**
8250
+ * Merge already-stored (database representation) attribute values into the
8251
+ * model without running set mutators or casts. Used to refresh the instance
8252
+ * from a row returned by a write, where the values are already in storage
8253
+ * form and must not be re-cast (re-applying a non-idempotent set-cast such as
8254
+ * a money or array cast would corrupt the value).
8255
+ *
8256
+ * @param attributes
8257
+ * @returns
8258
+ */
8259
+ fillRawAttributes(attributes) {
8260
+ Object.entries(attributes).forEach(([key, value]) => {
8261
+ this.attributes[key] = Model.cloneAttributeValue(value);
8262
+ });
8263
+ return this;
8264
+ }
8209
8265
  async update(attributes) {
8210
8266
  try {
8211
8267
  const primaryKey = this.constructor.getPrimaryKey();
@@ -8261,7 +8317,7 @@ var Model = class Model {
8261
8317
  await Model.dispatchEvent(constructor, "creating", this);
8262
8318
  const payload = this.normalizePersistenceAttributes(this.getRawAttributes());
8263
8319
  const model = await constructor.query().create(payload);
8264
- this.fill(model.getRawAttributes());
8320
+ this.fillRawAttributes(model.getRawAttributes());
8265
8321
  this.syncChanges(previousOriginal);
8266
8322
  this.syncPrevious(previousOriginal);
8267
8323
  this.syncOriginal();
@@ -8278,7 +8334,7 @@ var Model = class Model {
8278
8334
  const payload = this.normalizePersistenceAttributes(this.getDirtyAttributes());
8279
8335
  delete payload[primaryKey];
8280
8336
  const model = await constructor.query().where({ [primaryKey]: identifier }).update(payload);
8281
- this.fill(model.getRawAttributes());
8337
+ this.fillRawAttributes(model.getRawAttributes());
8282
8338
  this.syncChanges(previousOriginal);
8283
8339
  this.syncPrevious(previousOriginal);
8284
8340
  this.syncOriginal();
@@ -8321,14 +8377,13 @@ var Model = class Model {
8321
8377
  const softDeleteConfig = constructor.getSoftDeleteConfig();
8322
8378
  if (softDeleteConfig.enabled) {
8323
8379
  const model = await constructor.query().where({ [primaryKey]: identifier }).update({ [softDeleteConfig.column]: /* @__PURE__ */ new Date() });
8324
- this.fill(model.getRawAttributes());
8380
+ this.fillRawAttributes(model.getRawAttributes());
8325
8381
  this.syncChanges(previousOriginal);
8326
8382
  this.syncOriginal();
8327
8383
  await Model.dispatchEvent(constructor, "deleted", this);
8328
8384
  return this;
8329
8385
  }
8330
- const deleted = await constructor.query().where({ [primaryKey]: identifier }).deleteOrFail();
8331
- this.fill(deleted.getRawAttributes());
8386
+ await constructor.query().where({ [primaryKey]: identifier }).deleteOrFail();
8332
8387
  this.syncChanges(previousOriginal);
8333
8388
  this.syncOriginal();
8334
8389
  this.exists = false;
@@ -8366,8 +8421,7 @@ var Model = class Model {
8366
8421
  const previousOriginal = this.getOriginal();
8367
8422
  await Model.dispatchEvent(constructor, "forceDeleting", this);
8368
8423
  await Model.dispatchEvent(constructor, "deleting", this);
8369
- const deleted = await constructor.query().withTrashed().where({ [primaryKey]: identifier }).deleteOrFail();
8370
- this.fill(deleted.getRawAttributes());
8424
+ await constructor.query().withTrashed().where({ [primaryKey]: identifier }).deleteOrFail();
8371
8425
  this.syncChanges(previousOriginal);
8372
8426
  this.syncOriginal();
8373
8427
  this.exists = false;
@@ -8398,7 +8452,7 @@ var Model = class Model {
8398
8452
  const previousOriginal = this.getOriginal();
8399
8453
  await Model.dispatchEvent(constructor, "restoring", this);
8400
8454
  const model = await constructor.query().withTrashed().where({ [primaryKey]: identifier }).update({ [softDeleteConfig.column]: null });
8401
- this.fill(model.getRawAttributes());
8455
+ this.fillRawAttributes(model.getRawAttributes());
8402
8456
  this.syncChanges(previousOriginal);
8403
8457
  this.syncOriginal();
8404
8458
  await Model.dispatchEvent(constructor, "restored", this);
@@ -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-DWtfgLfh.cjs');
3
3
 
4
4
  exports.BelongsToManyRelation = require_relationship.BelongsToManyRelation;
5
5
  exports.BelongsToRelation = require_relationship.BelongsToRelation;
@@ -1,2 +1,2 @@
1
- import { Ao as HasOneRelation, Do as MorphOneRelation, Eo as MorphToManyRelation, Fo as BelongsToManyRelation, Io as Relation, Lo as RelationTableLoader, Mo as HasManyRelation, No as BelongsToRelation, Oo as MorphManyRelation, Po as SingleResultRelation, To as MorphToRelation, jo as HasManyThroughRelation, ko as HasOneThroughRelation, wo as SetBasedEagerLoader } from "../index-CgzhC61F.cjs";
1
+ import { Ao as HasOneRelation, Do as MorphOneRelation, Eo as MorphToManyRelation, Fo as BelongsToManyRelation, Io as Relation, Lo as RelationTableLoader, Mo as HasManyRelation, No as BelongsToRelation, Oo as MorphManyRelation, Po as SingleResultRelation, To as MorphToRelation, jo as HasManyThroughRelation, ko as HasOneThroughRelation, wo as SetBasedEagerLoader } from "../index-CGawfwb8.cjs";
2
2
  export { BelongsToManyRelation, BelongsToRelation, HasManyRelation, HasManyThroughRelation, HasOneRelation, HasOneThroughRelation, MorphManyRelation, MorphOneRelation, MorphToManyRelation, MorphToRelation, Relation, RelationTableLoader, SetBasedEagerLoader, SingleResultRelation };
@@ -1,2 +1,2 @@
1
- import { Ao as HasOneRelation, Do as MorphOneRelation, Eo as MorphToManyRelation, Fo as BelongsToManyRelation, Io as Relation, Lo as RelationTableLoader, Mo as HasManyRelation, No as BelongsToRelation, Oo as MorphManyRelation, Po as SingleResultRelation, To as MorphToRelation, jo as HasManyThroughRelation, ko as HasOneThroughRelation, wo as SetBasedEagerLoader } from "../index-CJ7yJR43.mjs";
1
+ import { Ao as HasOneRelation, Do as MorphOneRelation, Eo as MorphToManyRelation, Fo as BelongsToManyRelation, Io as Relation, Lo as RelationTableLoader, Mo as HasManyRelation, No as BelongsToRelation, Oo as MorphManyRelation, Po as SingleResultRelation, To as MorphToRelation, jo as HasManyThroughRelation, ko as HasOneThroughRelation, wo as SetBasedEagerLoader } from "../index-ClVzjhGq.mjs";
2
2
  export { BelongsToManyRelation, BelongsToRelation, HasManyRelation, HasManyThroughRelation, HasOneRelation, HasOneThroughRelation, MorphManyRelation, MorphOneRelation, MorphToManyRelation, MorphToRelation, Relation, RelationTableLoader, SetBasedEagerLoader, SingleResultRelation };
@@ -1,3 +1,3 @@
1
- import { Nn as SetBasedEagerLoader, Pn as RelationTableLoader, a as HasOneThroughRelation, c as HasManyRelation, d as BelongsToManyRelation, f as Relation, i as MorphManyRelation, l as BelongsToRelation, n as MorphToManyRelation, o as HasOneRelation, r as MorphOneRelation, s as HasManyThroughRelation, t as MorphToRelation, u as SingleResultRelation } from "../relationship-CmhzOlEo.mjs";
1
+ import { Nn as SetBasedEagerLoader, Pn as RelationTableLoader, a as HasOneThroughRelation, c as HasManyRelation, d as BelongsToManyRelation, f as Relation, i as MorphManyRelation, l as BelongsToRelation, n as MorphToManyRelation, o as HasOneRelation, r as MorphOneRelation, s as HasManyThroughRelation, t as MorphToRelation, u as SingleResultRelation } from "../relationship-SFhKrphd.mjs";
2
2
 
3
3
  export { BelongsToManyRelation, BelongsToRelation, HasManyRelation, HasManyThroughRelation, HasOneRelation, HasOneThroughRelation, MorphManyRelation, MorphOneRelation, MorphToManyRelation, MorphToRelation, Relation, RelationTableLoader, SetBasedEagerLoader, SingleResultRelation };
@@ -1218,6 +1218,15 @@ var EnumBuilder = class {
1218
1218
  this.tableBuilder.map(name, this.columnName);
1219
1219
  return this;
1220
1220
  }
1221
+ /**
1222
+ * Marks the enum column as an in-place change to an existing column.
1223
+ *
1224
+ * @returns
1225
+ */
1226
+ change() {
1227
+ this.tableBuilder.change(this.columnName);
1228
+ return this;
1229
+ }
1221
1230
  };
1222
1231
  /**
1223
1232
  * The TableBuilder class provides a fluent interface for defining
@@ -1230,6 +1239,7 @@ var TableBuilder = class {
1230
1239
  constructor() {
1231
1240
  this.columns = [];
1232
1241
  this.dropColumnNames = [];
1242
+ this.changeColumnNames = /* @__PURE__ */ new Set();
1233
1243
  this.indexes = [];
1234
1244
  this.foreignKeys = [];
1235
1245
  this.compositeUniqueConstraints = [];
@@ -1543,6 +1553,24 @@ var TableBuilder = class {
1543
1553
  return this;
1544
1554
  }
1545
1555
  /**
1556
+ * Marks a (re)defined column as a change to an existing column rather than an
1557
+ * addition. Use it at the end of a normal column chain inside `alterTable` to
1558
+ * redefine the column's type, nullability, default, or enum values in place:
1559
+ *
1560
+ * ```ts
1561
+ * table.string('status').default('active').change()
1562
+ * table.enum('role', ['admin', 'user', 'guest']).change()
1563
+ * ```
1564
+ *
1565
+ * @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
1566
+ * @returns The current TableBuilder instance for chaining.
1567
+ */
1568
+ change(columnName) {
1569
+ const column = this.resolveColumn(columnName);
1570
+ this.changeColumnNames.add(column.name);
1571
+ return this;
1572
+ }
1573
+ /**
1546
1574
  * Marks a column as nullable.
1547
1575
  *
1548
1576
  * @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
@@ -1651,7 +1679,18 @@ var TableBuilder = class {
1651
1679
  * @returns
1652
1680
  */
1653
1681
  getColumns() {
1654
- return this.columns.map((column) => ({
1682
+ return this.columns.filter((column) => !this.changeColumnNames.has(column.name)).map((column) => ({
1683
+ ...column,
1684
+ enumValues: column.enumValues ? [...column.enumValues] : void 0
1685
+ }));
1686
+ }
1687
+ /**
1688
+ * Returns a deep copy of the columns flagged for in-place change via `change()`.
1689
+ *
1690
+ * @returns
1691
+ */
1692
+ getChangeColumns() {
1693
+ return this.columns.filter((column) => this.changeColumnNames.has(column.name)).map((column) => ({
1655
1694
  ...column,
1656
1695
  enumValues: column.enumValues ? [...column.enumValues] : void 0
1657
1696
  }));
@@ -1873,6 +1912,7 @@ var SchemaBuilder = class SchemaBuilder {
1873
1912
  type: "alterTable",
1874
1913
  table,
1875
1914
  addColumns: builder.getColumns(),
1915
+ changeColumns: builder.getChangeColumns(),
1876
1916
  dropColumns: builder.getDropColumns(),
1877
1917
  addIndexes: builder.getIndexes(),
1878
1918
  addForeignKeys: builder.getForeignKeys(),
@@ -1927,6 +1967,10 @@ var SchemaBuilder = class SchemaBuilder {
1927
1967
  ...column,
1928
1968
  enumValues: column.enumValues ? [...column.enumValues] : void 0
1929
1969
  })),
1970
+ changeColumns: operation.changeColumns?.map((column) => ({
1971
+ ...column,
1972
+ enumValues: column.enumValues ? [...column.enumValues] : void 0
1973
+ })),
1930
1974
  dropColumns: [...operation.dropColumns],
1931
1975
  addIndexes: operation.addIndexes.map((index) => ({
1932
1976
  ...index,
@@ -2431,11 +2475,18 @@ const applyCreateTableOperation = (schema, operation) => {
2431
2475
  const applyAlterTableOperation = (schema, operation) => {
2432
2476
  const model = findModelBlock(schema, operation.table);
2433
2477
  if (!model) throw new ArkormException(`Prisma model for table [${operation.table}] was not found.`);
2434
- const schemaWithEnums = ensureEnumBlocks(schema, operation.addColumns);
2478
+ const schemaWithEnums = ensureEnumBlocks(schema, [...operation.addColumns, ...operation.changeColumns ?? []]);
2435
2479
  const refreshedModel = findModelBlock(schemaWithEnums, operation.table);
2436
2480
  if (!refreshedModel) throw new ArkormException(`Prisma model for table [${operation.table}] was not found.`);
2437
2481
  let block = refreshedModel.block;
2438
2482
  const bodyLines = block.split("\n");
2483
+ (operation.changeColumns ?? []).forEach((column) => {
2484
+ const fieldLine = buildFieldLine(column);
2485
+ const columnRegex = new RegExp(`^\\s*${escapeRegex(column.name)}\\s+`);
2486
+ const index = bodyLines.findIndex((line) => columnRegex.test(line));
2487
+ if (index >= 0) bodyLines.splice(index, 1, fieldLine);
2488
+ else bodyLines.splice(Math.max(1, bodyLines.length - 1), 0, fieldLine);
2489
+ });
2439
2490
  operation.dropColumns.forEach((column) => {
2440
2491
  const columnRegex = new RegExp(`^\\s*${escapeRegex(column)}\\s+`);
2441
2492
  for (let index = 0; index < bodyLines.length; index += 1) if (columnRegex.test(bodyLines[index])) {
@@ -2660,14 +2711,18 @@ const stripPrismaSchemaModelsAndEnums = (schema) => {
2660
2711
  };
2661
2712
  const applyMigrationToDatabase = async (adapter, migration) => {
2662
2713
  if (!supportsDatabaseMigrationExecution(adapter)) throw new ArkormException("The configured adapter does not support database-backed migration execution.");
2663
- const operations = await getMigrationPlan(migration, "up");
2714
+ const instance = typeof migration === "function" ? new migration() : migration;
2715
+ const operations = await getMigrationPlan(instance, "up");
2664
2716
  await adapter.executeSchemaOperations(operations);
2717
+ await instance.done?.("up");
2665
2718
  return { operations };
2666
2719
  };
2667
2720
  const applyMigrationRollbackToDatabase = async (adapter, migration) => {
2668
2721
  if (!supportsDatabaseMigrationExecution(adapter)) throw new ArkormException("The configured adapter does not support database-backed migration execution.");
2669
- const operations = await getMigrationPlan(migration, "down");
2722
+ const instance = typeof migration === "function" ? new migration() : migration;
2723
+ const operations = await getMigrationPlan(instance, "down");
2670
2724
  await adapter.executeSchemaOperations(operations);
2725
+ await instance.done?.("down");
2671
2726
  return { operations };
2672
2727
  };
2673
2728
  /**
@@ -1190,6 +1190,15 @@ var EnumBuilder = class {
1190
1190
  this.tableBuilder.map(name, this.columnName);
1191
1191
  return this;
1192
1192
  }
1193
+ /**
1194
+ * Marks the enum column as an in-place change to an existing column.
1195
+ *
1196
+ * @returns
1197
+ */
1198
+ change() {
1199
+ this.tableBuilder.change(this.columnName);
1200
+ return this;
1201
+ }
1193
1202
  };
1194
1203
  /**
1195
1204
  * The TableBuilder class provides a fluent interface for defining
@@ -1202,6 +1211,7 @@ var TableBuilder = class {
1202
1211
  constructor() {
1203
1212
  this.columns = [];
1204
1213
  this.dropColumnNames = [];
1214
+ this.changeColumnNames = /* @__PURE__ */ new Set();
1205
1215
  this.indexes = [];
1206
1216
  this.foreignKeys = [];
1207
1217
  this.compositeUniqueConstraints = [];
@@ -1515,6 +1525,24 @@ var TableBuilder = class {
1515
1525
  return this;
1516
1526
  }
1517
1527
  /**
1528
+ * Marks a (re)defined column as a change to an existing column rather than an
1529
+ * addition. Use it at the end of a normal column chain inside `alterTable` to
1530
+ * redefine the column's type, nullability, default, or enum values in place:
1531
+ *
1532
+ * ```ts
1533
+ * table.string('status').default('active').change()
1534
+ * table.enum('role', ['admin', 'user', 'guest']).change()
1535
+ * ```
1536
+ *
1537
+ * @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
1538
+ * @returns The current TableBuilder instance for chaining.
1539
+ */
1540
+ change(columnName) {
1541
+ const column = this.resolveColumn(columnName);
1542
+ this.changeColumnNames.add(column.name);
1543
+ return this;
1544
+ }
1545
+ /**
1518
1546
  * Marks a column as nullable.
1519
1547
  *
1520
1548
  * @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
@@ -1623,7 +1651,18 @@ var TableBuilder = class {
1623
1651
  * @returns
1624
1652
  */
1625
1653
  getColumns() {
1626
- return this.columns.map((column) => ({
1654
+ return this.columns.filter((column) => !this.changeColumnNames.has(column.name)).map((column) => ({
1655
+ ...column,
1656
+ enumValues: column.enumValues ? [...column.enumValues] : void 0
1657
+ }));
1658
+ }
1659
+ /**
1660
+ * Returns a deep copy of the columns flagged for in-place change via `change()`.
1661
+ *
1662
+ * @returns
1663
+ */
1664
+ getChangeColumns() {
1665
+ return this.columns.filter((column) => this.changeColumnNames.has(column.name)).map((column) => ({
1627
1666
  ...column,
1628
1667
  enumValues: column.enumValues ? [...column.enumValues] : void 0
1629
1668
  }));
@@ -1845,6 +1884,7 @@ var SchemaBuilder = class SchemaBuilder {
1845
1884
  type: "alterTable",
1846
1885
  table,
1847
1886
  addColumns: builder.getColumns(),
1887
+ changeColumns: builder.getChangeColumns(),
1848
1888
  dropColumns: builder.getDropColumns(),
1849
1889
  addIndexes: builder.getIndexes(),
1850
1890
  addForeignKeys: builder.getForeignKeys(),
@@ -1899,6 +1939,10 @@ var SchemaBuilder = class SchemaBuilder {
1899
1939
  ...column,
1900
1940
  enumValues: column.enumValues ? [...column.enumValues] : void 0
1901
1941
  })),
1942
+ changeColumns: operation.changeColumns?.map((column) => ({
1943
+ ...column,
1944
+ enumValues: column.enumValues ? [...column.enumValues] : void 0
1945
+ })),
1902
1946
  dropColumns: [...operation.dropColumns],
1903
1947
  addIndexes: operation.addIndexes.map((index) => ({
1904
1948
  ...index,
@@ -2403,11 +2447,18 @@ const applyCreateTableOperation = (schema, operation) => {
2403
2447
  const applyAlterTableOperation = (schema, operation) => {
2404
2448
  const model = findModelBlock(schema, operation.table);
2405
2449
  if (!model) throw new ArkormException(`Prisma model for table [${operation.table}] was not found.`);
2406
- const schemaWithEnums = ensureEnumBlocks(schema, operation.addColumns);
2450
+ const schemaWithEnums = ensureEnumBlocks(schema, [...operation.addColumns, ...operation.changeColumns ?? []]);
2407
2451
  const refreshedModel = findModelBlock(schemaWithEnums, operation.table);
2408
2452
  if (!refreshedModel) throw new ArkormException(`Prisma model for table [${operation.table}] was not found.`);
2409
2453
  let block = refreshedModel.block;
2410
2454
  const bodyLines = block.split("\n");
2455
+ (operation.changeColumns ?? []).forEach((column) => {
2456
+ const fieldLine = buildFieldLine(column);
2457
+ const columnRegex = new RegExp(`^\\s*${escapeRegex(column.name)}\\s+`);
2458
+ const index = bodyLines.findIndex((line) => columnRegex.test(line));
2459
+ if (index >= 0) bodyLines.splice(index, 1, fieldLine);
2460
+ else bodyLines.splice(Math.max(1, bodyLines.length - 1), 0, fieldLine);
2461
+ });
2411
2462
  operation.dropColumns.forEach((column) => {
2412
2463
  const columnRegex = new RegExp(`^\\s*${escapeRegex(column)}\\s+`);
2413
2464
  for (let index = 0; index < bodyLines.length; index += 1) if (columnRegex.test(bodyLines[index])) {
@@ -2632,14 +2683,18 @@ const stripPrismaSchemaModelsAndEnums = (schema) => {
2632
2683
  };
2633
2684
  const applyMigrationToDatabase = async (adapter, migration) => {
2634
2685
  if (!supportsDatabaseMigrationExecution(adapter)) throw new ArkormException("The configured adapter does not support database-backed migration execution.");
2635
- const operations = await getMigrationPlan(migration, "up");
2686
+ const instance = typeof migration === "function" ? new migration() : migration;
2687
+ const operations = await getMigrationPlan(instance, "up");
2636
2688
  await adapter.executeSchemaOperations(operations);
2689
+ await instance.done?.("up");
2637
2690
  return { operations };
2638
2691
  };
2639
2692
  const applyMigrationRollbackToDatabase = async (adapter, migration) => {
2640
2693
  if (!supportsDatabaseMigrationExecution(adapter)) throw new ArkormException("The configured adapter does not support database-backed migration execution.");
2641
- const operations = await getMigrationPlan(migration, "down");
2694
+ const instance = typeof migration === "function" ? new migration() : migration;
2695
+ const operations = await getMigrationPlan(instance, "down");
2642
2696
  await adapter.executeSchemaOperations(operations);
2697
+ await instance.done?.("down");
2643
2698
  return { operations };
2644
2699
  };
2645
2700
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkormx",
3
- "version": "2.10.0",
3
+ "version": "2.10.2",
4
4
  "description": "Modern TypeScript-first ORM for Node.js.",
5
5
  "keywords": [
6
6
  "orm",