arkormx 2.7.0 → 2.8.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.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-BuwKUTOb.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--l8RA_yy.mjs";
2
2
  import { Pool } from "pg";
3
3
  import { join, resolve } from "node:path";
4
4
  import { createRequire } from "module";
@@ -5634,6 +5634,56 @@ var QueryBuilder = class QueryBuilder {
5634
5634
  if (!model) throw new ModelNotFoundException(this.model.name, "Record not found.");
5635
5635
  return model;
5636
5636
  }
5637
+ /**
5638
+ * Returns the first record matching the given attributes or instantiates a
5639
+ * new, unpersisted model populated with the merged attributes and values.
5640
+ *
5641
+ * @param attributes
5642
+ * @param values
5643
+ * @returns
5644
+ */
5645
+ async firstOrNew(attributes, values = {}) {
5646
+ const existing = await this.clone().where(attributes).first();
5647
+ if (existing) return existing;
5648
+ const ModelConstructor = this.model;
5649
+ return new ModelConstructor({
5650
+ ...attributes,
5651
+ ...values
5652
+ });
5653
+ }
5654
+ /**
5655
+ * Returns the first record matching the given attributes or creates and
5656
+ * persists a new record populated with the merged attributes and values.
5657
+ *
5658
+ * @param attributes
5659
+ * @param values
5660
+ * @returns
5661
+ */
5662
+ async firstOrCreate(attributes, values = {}) {
5663
+ const existing = await this.clone().where(attributes).first();
5664
+ if (existing) return existing;
5665
+ return await this.create({
5666
+ ...attributes,
5667
+ ...values
5668
+ });
5669
+ }
5670
+ async firstOr(columnsOrCallback, maybeCallback) {
5671
+ const callback = typeof columnsOrCallback === "function" ? columnsOrCallback : maybeCallback;
5672
+ if (!callback) throw new QueryConstraintException("firstOr requires a fallback callback.", {
5673
+ operation: "firstOr",
5674
+ model: this.model.name
5675
+ });
5676
+ if (Array.isArray(columnsOrCallback) && columnsOrCallback.length > 0) {
5677
+ const select = columnsOrCallback.reduce((all, column) => {
5678
+ all[column] = true;
5679
+ return all;
5680
+ }, {});
5681
+ this.select(select);
5682
+ }
5683
+ const found = await this.first();
5684
+ if (found) return found;
5685
+ return callback();
5686
+ }
5637
5687
  async find(value, key) {
5638
5688
  const resolvedKey = key ?? this.model.getPrimaryKey();
5639
5689
  return this.where({ [resolvedKey]: value }).first();
@@ -5843,6 +5893,23 @@ var QueryBuilder = class QueryBuilder {
5843
5893
  }
5844
5894
  return await this.clone().where(attributes).update(resolvedValues) != null;
5845
5895
  }
5896
+ /**
5897
+ * Update the first record matching the given attributes, or create a new
5898
+ * record populated with the merged attributes and values when none exists.
5899
+ *
5900
+ * @param attributes
5901
+ * @param values
5902
+ * @returns
5903
+ */
5904
+ async updateOrCreate(attributes, values = {}) {
5905
+ const existing = await this.clone().where(attributes).first();
5906
+ if (!existing) return await this.create({
5907
+ ...attributes,
5908
+ ...values
5909
+ });
5910
+ if (Object.keys(values).length === 0) return existing;
5911
+ return await this.clone().where(attributes).update(values);
5912
+ }
5846
5913
  shouldFallbackUpdateOrInsertUpsert(error) {
5847
5914
  if (!(error instanceof QueryExecutionException)) return false;
5848
5915
  const cause = error.cause;
@@ -5894,13 +5961,25 @@ var QueryBuilder = class QueryBuilder {
5894
5961
  if (!this.isUniqueWhere(where) && directSpec && typeof adapter.deleteFirst === "function") {
5895
5962
  const deleted = await adapter.deleteFirst(directSpec);
5896
5963
  if (!deleted) return null;
5897
- return this.model.hydrate(deleted);
5964
+ return this.hydrateDeleted(deleted);
5898
5965
  }
5899
5966
  const uniqueWhere = await this.resolveUniqueWhere(where, false);
5900
5967
  if (!uniqueWhere) return null;
5901
5968
  const deleted = await this.executeDeleteRow(uniqueWhere, false);
5902
5969
  if (!deleted) return null;
5903
- return this.model.hydrate(deleted);
5970
+ return this.hydrateDeleted(deleted);
5971
+ }
5972
+ /**
5973
+ * Hydrate a row that was just deleted, marking the resulting model as no
5974
+ * longer existing in the database.
5975
+ *
5976
+ * @param attributes
5977
+ * @returns
5978
+ */
5979
+ hydrateDeleted(attributes) {
5980
+ const model = this.model.hydrate(attributes);
5981
+ model.exists = false;
5982
+ return model;
5904
5983
  }
5905
5984
  /**
5906
5985
  * Deletes the first record matching the current query constraints and throws
@@ -7269,9 +7348,12 @@ var Model = class Model {
7269
7348
  this.hidden = [];
7270
7349
  this.visible = [];
7271
7350
  this.appends = [];
7351
+ this.exists = false;
7352
+ this.wasRecentlyCreated = false;
7272
7353
  this.attributes = {};
7273
7354
  this.original = {};
7274
7355
  this.changes = {};
7356
+ this.previous = {};
7275
7357
  this.touchedAttributes = /* @__PURE__ */ new Set();
7276
7358
  this.fill(attributes);
7277
7359
  return new Proxy(this, {
@@ -7631,6 +7713,68 @@ var Model = class Model {
7631
7713
  return this.query().scope(name, ...args);
7632
7714
  }
7633
7715
  /**
7716
+ * Start a query constrained by the given where clause.
7717
+ *
7718
+ * @param this
7719
+ * @param where
7720
+ * @returns
7721
+ */
7722
+ static where(where) {
7723
+ return this.query().where(where);
7724
+ }
7725
+ /**
7726
+ * Retrieve all records for the model.
7727
+ *
7728
+ * @param this
7729
+ * @returns
7730
+ */
7731
+ static async all() {
7732
+ return await this.query().get();
7733
+ }
7734
+ /**
7735
+ * Create and persist a new record, returning the hydrated model instance.
7736
+ *
7737
+ * @param this
7738
+ * @param data
7739
+ * @returns
7740
+ */
7741
+ static async create(data) {
7742
+ return await this.query().create(data);
7743
+ }
7744
+ /**
7745
+ * Insert new records or update existing records by one or more unique keys.
7746
+ *
7747
+ * @param this
7748
+ * @param values
7749
+ * @param uniqueBy
7750
+ * @param update
7751
+ * @returns
7752
+ */
7753
+ static async upsert(values, uniqueBy, update = null) {
7754
+ return await this.query().upsert(values, uniqueBy, update);
7755
+ }
7756
+ /**
7757
+ * Delete records by their primary key(s), dispatching model events for each
7758
+ * matched record. Returns the number of records deleted.
7759
+ *
7760
+ * @param this
7761
+ * @param ids
7762
+ * @returns
7763
+ */
7764
+ static async destroy(ids) {
7765
+ const constructor = this;
7766
+ const identifiers = (Array.isArray(ids) ? ids : [ids]).filter((identifier, index, all) => all.indexOf(identifier) === index);
7767
+ const primaryKey = constructor.getPrimaryKey();
7768
+ let deleted = 0;
7769
+ for (const identifier of identifiers) {
7770
+ const model = await constructor.query().where({ [primaryKey]: identifier }).first();
7771
+ if (!model) continue;
7772
+ await model.delete();
7773
+ deleted += 1;
7774
+ }
7775
+ return deleted;
7776
+ }
7777
+ /**
7634
7778
  * Get the soft delete configuration for the model, including whether
7635
7779
  * soft deletes are enabled and the name of the deleted at column.
7636
7780
  *
@@ -7653,6 +7797,7 @@ var Model = class Model {
7653
7797
  const model = new this(attributes);
7654
7798
  model.syncOriginal();
7655
7799
  model.syncChanges({});
7800
+ model.exists = true;
7656
7801
  return model;
7657
7802
  }
7658
7803
  /**
@@ -7663,7 +7808,8 @@ var Model = class Model {
7663
7808
  * @returns
7664
7809
  */
7665
7810
  static hydrateMany(attributes) {
7666
- return attributes.map((attribute) => new this(attribute));
7811
+ const constructor = this;
7812
+ return attributes.map((attribute) => constructor.hydrate(attribute));
7667
7813
  }
7668
7814
  /**
7669
7815
  * Hydrate a model instance and dispatch the retrieved lifecycle event.
@@ -7711,6 +7857,11 @@ var Model = class Model {
7711
7857
  return false;
7712
7858
  }
7713
7859
  }
7860
+ async updateOrFail(attributes) {
7861
+ const primaryKey = this.constructor.getPrimaryKey();
7862
+ if (this.getAttribute(primaryKey) == null) throw new ArkormException(primaryKey === "id" ? "Cannot update a model without an id." : `Cannot update a model without a [${primaryKey}] value.`);
7863
+ return await this.fill(attributes).saveOrFail();
7864
+ }
7714
7865
  getAttribute(key) {
7715
7866
  const attributeMutator = this.resolveAttributeMutator(key);
7716
7867
  const mutator = this.resolveGetMutator(key);
@@ -7734,29 +7885,35 @@ var Model = class Model {
7734
7885
  return this;
7735
7886
  }
7736
7887
  /**
7737
- * Save the model to the database.
7738
- * If the model has an identifier (id), it will perform an update.
7739
- * Otherwise, it will perform a create.
7740
- *
7741
- * @returns
7888
+ * Save the model to the database.
7889
+ * If the model already exists in the database it performs an update;
7890
+ * otherwise it performs an insert. Existence is tracked through the
7891
+ * `exists` flag rather than the presence of a primary-key value, so a model
7892
+ * built with an explicit primary key still inserts on its first save.
7893
+ *
7894
+ * @returns
7742
7895
  */
7743
7896
  async save() {
7744
7897
  const constructor = this.constructor;
7745
7898
  const primaryKey = constructor.getPrimaryKey();
7746
- const identifier = this.getAttribute(primaryKey);
7747
7899
  const previousOriginal = this.getOriginal();
7748
- if (identifier == null) {
7900
+ if (!this.exists) {
7749
7901
  await Model.dispatchEvent(constructor, "saving", this);
7750
7902
  await Model.dispatchEvent(constructor, "creating", this);
7751
7903
  const payload = this.normalizePersistenceAttributes(this.getRawAttributes());
7752
7904
  const model = await constructor.query().create(payload);
7753
7905
  this.fill(model.getRawAttributes());
7754
7906
  this.syncChanges(previousOriginal);
7907
+ this.syncPrevious(previousOriginal);
7755
7908
  this.syncOriginal();
7909
+ this.exists = true;
7910
+ this.wasRecentlyCreated = true;
7756
7911
  await Model.dispatchEvent(constructor, "created", this);
7757
7912
  await Model.dispatchEvent(constructor, "saved", this);
7758
7913
  return this;
7759
7914
  }
7915
+ const identifier = this.getAttribute(primaryKey);
7916
+ if (identifier == null) throw new ArkormException(primaryKey === "id" ? "Cannot update an existing model without an id." : `Cannot update an existing model without a [${primaryKey}] value.`);
7760
7917
  await Model.dispatchEvent(constructor, "saving", this);
7761
7918
  await Model.dispatchEvent(constructor, "updating", this);
7762
7919
  const payload = this.normalizePersistenceAttributes(this.getDirtyAttributes());
@@ -7764,6 +7921,7 @@ var Model = class Model {
7764
7921
  const model = await constructor.query().where({ [primaryKey]: identifier }).update(payload);
7765
7922
  this.fill(model.getRawAttributes());
7766
7923
  this.syncChanges(previousOriginal);
7924
+ this.syncPrevious(previousOriginal);
7767
7925
  this.syncOriginal();
7768
7926
  await Model.dispatchEvent(constructor, "updated", this);
7769
7927
  await Model.dispatchEvent(constructor, "saved", this);
@@ -7778,6 +7936,15 @@ var Model = class Model {
7778
7936
  return await Model.withoutEvents(() => this.save());
7779
7937
  }
7780
7938
  /**
7939
+ * Save the model within a transaction, rolling back and rethrowing if the
7940
+ * operation fails. Unlike update(), this never swallows errors.
7941
+ *
7942
+ * @returns
7943
+ */
7944
+ async saveOrFail() {
7945
+ return await this.constructor.transaction(async () => await this.save());
7946
+ }
7947
+ /**
7781
7948
  * Delete the model from the database.
7782
7949
  * If soft deletes are enabled, it will perform a soft delete by
7783
7950
  * setting the deleted at column to the current date.
@@ -7805,6 +7972,7 @@ var Model = class Model {
7805
7972
  this.fill(deleted.getRawAttributes());
7806
7973
  this.syncChanges(previousOriginal);
7807
7974
  this.syncOriginal();
7975
+ this.exists = false;
7808
7976
  await Model.dispatchEvent(constructor, "deleted", this);
7809
7977
  return this;
7810
7978
  }
@@ -7817,6 +7985,15 @@ var Model = class Model {
7817
7985
  return await Model.withoutEvents(() => this.delete());
7818
7986
  }
7819
7987
  /**
7988
+ * Delete the model within a transaction, rolling back and rethrowing if the
7989
+ * operation fails.
7990
+ *
7991
+ * @returns
7992
+ */
7993
+ async deleteOrFail() {
7994
+ return await this.constructor.transaction(async () => await this.delete());
7995
+ }
7996
+ /**
7820
7997
  * Permanently delete the model from the database, regardless of whether soft
7821
7998
  * deletes are enabled.
7822
7999
  *
@@ -7834,6 +8011,7 @@ var Model = class Model {
7834
8011
  this.fill(deleted.getRawAttributes());
7835
8012
  this.syncChanges(previousOriginal);
7836
8013
  this.syncOriginal();
8014
+ this.exists = false;
7837
8015
  await Model.dispatchEvent(constructor, "deleted", this);
7838
8016
  await Model.dispatchEvent(constructor, "forceDeleted", this);
7839
8017
  return this;
@@ -7988,6 +8166,25 @@ var Model = class Model {
7988
8166
  return keyList.some((key) => Object.prototype.hasOwnProperty.call(this.changes, key));
7989
8167
  }
7990
8168
  /**
8169
+ * Get the attributes that were changed during the last successful
8170
+ * persistence operation.
8171
+ *
8172
+ * @returns
8173
+ */
8174
+ getChanges() {
8175
+ return Object.entries(this.changes).reduce((all, [key, value]) => {
8176
+ all[key] = Model.cloneAttributeValue(value);
8177
+ return all;
8178
+ }, {});
8179
+ }
8180
+ getPrevious(key) {
8181
+ if (typeof key === "string") return Model.cloneAttributeValue(this.previous[key]);
8182
+ return Object.entries(this.previous).reduce((all, [previousKey, value]) => {
8183
+ all[previousKey] = Model.cloneAttributeValue(value);
8184
+ return all;
8185
+ }, {});
8186
+ }
8187
+ /**
7991
8188
  * Convert the model instance to a plain object, applying visibility
7992
8189
  * rules, appends, and mutators.
7993
8190
  *
@@ -8404,6 +8601,18 @@ var Model = class Model {
8404
8601
  }, {});
8405
8602
  }
8406
8603
  /**
8604
+ * Capture the attribute snapshot that was persisted before the most recent
8605
+ * save so it can be read back via getPrevious().
8606
+ *
8607
+ * @param previousOriginal
8608
+ */
8609
+ syncPrevious(previousOriginal) {
8610
+ this.previous = Object.entries(previousOriginal).reduce((all, [key, value]) => {
8611
+ all[key] = Model.cloneAttributeValue(value);
8612
+ return all;
8613
+ }, {});
8614
+ }
8615
+ /**
8407
8616
  * Resolve lifecycle state for the provided model class.
8408
8617
  *
8409
8618
  * @param modelClass
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_relationship = require('../relationship-B8FaJYIx.cjs');
2
+ const require_relationship = require('../relationship-WiXlopzY.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 MorphManyRelation, Do as MorphToRelation, Eo as SetBasedEagerLoader, Fo as BelongsToRelation, Io as SingleResultRelation, Lo as BelongsToManyRelation, Mo as HasOneRelation, No as HasManyThroughRelation, Oo as MorphToManyRelation, Po as HasManyRelation, Ro as Relation, jo as HasOneThroughRelation, ko as MorphOneRelation, zo as RelationTableLoader } from "../index-Dnn0lsDy.cjs";
1
+ import { Ao as MorphManyRelation, Do as MorphToRelation, Eo as SetBasedEagerLoader, Fo as BelongsToRelation, Io as SingleResultRelation, Lo as BelongsToManyRelation, Mo as HasOneRelation, No as HasManyThroughRelation, Oo as MorphToManyRelation, Po as HasManyRelation, Ro as Relation, jo as HasOneThroughRelation, ko as MorphOneRelation, zo as RelationTableLoader } from "../index-4mi5sLRA.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 MorphManyRelation, Do as MorphToRelation, Eo as SetBasedEagerLoader, Fo as BelongsToRelation, Io as SingleResultRelation, Lo as BelongsToManyRelation, Mo as HasOneRelation, No as HasManyThroughRelation, Oo as MorphToManyRelation, Po as HasManyRelation, Ro as Relation, jo as HasOneThroughRelation, ko as MorphOneRelation, zo as RelationTableLoader } from "../index-C77nMASp.mjs";
1
+ import { Ao as MorphManyRelation, Do as MorphToRelation, Eo as SetBasedEagerLoader, Fo as BelongsToRelation, Io as SingleResultRelation, Lo as BelongsToManyRelation, Mo as HasOneRelation, No as HasManyThroughRelation, Oo as MorphToManyRelation, Po as HasManyRelation, Ro as Relation, jo as HasOneThroughRelation, ko as MorphOneRelation, zo as RelationTableLoader } from "../index-De8zXqTD.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-BuwKUTOb.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--l8RA_yy.mjs";
2
2
 
3
3
  export { BelongsToManyRelation, BelongsToRelation, HasManyRelation, HasManyThroughRelation, HasOneRelation, HasOneThroughRelation, MorphManyRelation, MorphOneRelation, MorphToManyRelation, MorphToRelation, Relation, RelationTableLoader, SetBasedEagerLoader, SingleResultRelation };
@@ -4343,7 +4343,9 @@ var Relation = class {
4343
4343
  * @returns
4344
4344
  */
4345
4345
  make(attributes = {}) {
4346
- return this.getRelatedModelConstructor().hydrate(this.mergeCreationAttributes(attributes));
4346
+ const model = this.getRelatedModelConstructor().hydrate(this.mergeCreationAttributes(attributes));
4347
+ model.exists = false;
4348
+ return model;
4347
4349
  }
4348
4350
  /**
4349
4351
  * Create new instances of the related model with the given attributes and relationship
@@ -4371,7 +4371,9 @@ var Relation = class {
4371
4371
  * @returns
4372
4372
  */
4373
4373
  make(attributes = {}) {
4374
- return this.getRelatedModelConstructor().hydrate(this.mergeCreationAttributes(attributes));
4374
+ const model = this.getRelatedModelConstructor().hydrate(this.mergeCreationAttributes(attributes));
4375
+ model.exists = false;
4376
+ return model;
4375
4377
  }
4376
4378
  /**
4377
4379
  * Create new instances of the related model with the given attributes and relationship
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkormx",
3
- "version": "2.7.0",
3
+ "version": "2.8.0",
4
4
  "description": "Modern TypeScript-first ORM for Node.js.",
5
5
  "keywords": [
6
6
  "orm",