metal-orm 1.0.66 → 1.0.68

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
@@ -658,10 +658,10 @@ var isWindowFunctionNode = (node) => isOperandNode(node) && node.type === "Windo
658
658
  var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isCastExpressionNode(node) || isWindowFunctionNode(node);
659
659
 
660
660
  // src/core/ast/expression-builders.ts
661
- var isLiteralValue = (value) => value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
661
+ var isLiteralValue = (value) => value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value instanceof Date;
662
662
  var toLiteralNode = (value) => ({
663
663
  type: "Literal",
664
- value
664
+ value: value instanceof Date ? value.toISOString() : value
665
665
  });
666
666
  var columnRefToNode = (col2) => {
667
667
  if (!col2.table) {
@@ -11724,14 +11724,28 @@ var runInTransaction = async (executor, action) => {
11724
11724
  // src/orm/save-graph.ts
11725
11725
  var toKey8 = (value) => value === null || value === void 0 ? "" : String(value);
11726
11726
  var coerceColumnValue = (table, columnName, value, options) => {
11727
- if (options.coerce !== "json") return value;
11728
11727
  if (value === null || value === void 0) return value;
11729
11728
  const column = table.columns[columnName];
11730
11729
  if (!column) return value;
11731
11730
  const normalized = normalizeColumnType(column.type);
11732
11731
  const isDateLikeColumn = normalized === "date" || normalized === "datetime" || normalized === "timestamp" || normalized === "timestamptz";
11733
- if (isDateLikeColumn && value instanceof Date) {
11734
- return value.toISOString();
11732
+ if (!isDateLikeColumn) return value;
11733
+ if (options.coerce === "json") {
11734
+ if (value instanceof Date) {
11735
+ return value.toISOString();
11736
+ }
11737
+ return value;
11738
+ }
11739
+ if (options.coerce === "json-in") {
11740
+ if (value instanceof Date) return value;
11741
+ if (typeof value === "string" || typeof value === "number") {
11742
+ const date = new Date(value);
11743
+ if (Number.isNaN(date.getTime())) {
11744
+ throw new Error(`Invalid date value for column "${columnName}"`);
11745
+ }
11746
+ return date;
11747
+ }
11748
+ return value;
11735
11749
  }
11736
11750
  return value;
11737
11751
  };
@@ -11928,6 +11942,7 @@ var OrmSession = class {
11928
11942
  /** The relation change processor */
11929
11943
  relationChanges;
11930
11944
  interceptors;
11945
+ saveGraphDefaults;
11931
11946
  /**
11932
11947
  * Creates a new OrmSession instance.
11933
11948
  * @param opts - Session options
@@ -12058,6 +12073,15 @@ var OrmSession = class {
12058
12073
  registerDomainEventHandler(type, handler) {
12059
12074
  this.domainEvents.on(type, handler);
12060
12075
  }
12076
+ /**
12077
+ * Sets default options applied to all saveGraph calls for this session.
12078
+ * Per-call options override these defaults.
12079
+ * @param defaults - Default saveGraph options for the session
12080
+ */
12081
+ withSaveGraphDefaults(defaults) {
12082
+ this.saveGraphDefaults = { ...defaults };
12083
+ return this;
12084
+ }
12061
12085
  /**
12062
12086
  * Finds an entity by its primary key.
12063
12087
  * @template TCtor - The entity constructor type
@@ -12105,10 +12129,60 @@ var OrmSession = class {
12105
12129
  return executeHydrated(this, qb);
12106
12130
  }
12107
12131
  async saveGraph(entityClass, payload, options) {
12108
- const { transactional = true, ...graphOptions } = options ?? {};
12132
+ const resolved = this.resolveSaveGraphOptions(options);
12133
+ const { transactional = true, flush = false, ...graphOptions } = resolved;
12109
12134
  const execute = () => saveGraphInternal(this, entityClass, payload, graphOptions);
12110
12135
  if (!transactional) {
12111
- return execute();
12136
+ const result = await execute();
12137
+ if (flush) {
12138
+ await this.flush();
12139
+ }
12140
+ return result;
12141
+ }
12142
+ return this.transaction(() => execute());
12143
+ }
12144
+ /**
12145
+ * Saves an entity graph and flushes immediately (defaults to transactional: false).
12146
+ * @param entityClass - Root entity constructor
12147
+ * @param payload - DTO payload containing column values and nested relations
12148
+ * @param options - Graph save options
12149
+ * @returns The root entity instance
12150
+ */
12151
+ async saveGraphAndFlush(entityClass, payload, options) {
12152
+ const merged = { ...options ?? {}, flush: true, transactional: options?.transactional ?? false };
12153
+ return this.saveGraph(entityClass, payload, merged);
12154
+ }
12155
+ /**
12156
+ * Updates an existing entity graph (requires a primary key in the payload).
12157
+ * @param entityClass - Root entity constructor
12158
+ * @param payload - DTO payload containing column values and nested relations
12159
+ * @param options - Graph save options
12160
+ * @returns The root entity instance or null if not found
12161
+ */
12162
+ async updateGraph(entityClass, payload, options) {
12163
+ const table = getTableDefFromEntity(entityClass);
12164
+ if (!table) {
12165
+ throw new Error("Entity metadata has not been bootstrapped");
12166
+ }
12167
+ const primaryKey = findPrimaryKey(table);
12168
+ const pkValue = payload[primaryKey];
12169
+ if (pkValue === void 0 || pkValue === null) {
12170
+ throw new Error(`updateGraph requires a primary key value for "${primaryKey}"`);
12171
+ }
12172
+ const resolved = this.resolveSaveGraphOptions(options);
12173
+ const { transactional = true, flush = false, ...graphOptions } = resolved;
12174
+ const execute = async () => {
12175
+ const tracked = this.getEntity(table, pkValue);
12176
+ const existing = tracked ?? await this.find(entityClass, pkValue);
12177
+ if (!existing) return null;
12178
+ return saveGraphInternal(this, entityClass, payload, graphOptions);
12179
+ };
12180
+ if (!transactional) {
12181
+ const result = await execute();
12182
+ if (result && flush) {
12183
+ await this.flush();
12184
+ }
12185
+ return result;
12112
12186
  }
12113
12187
  return this.transaction(() => execute());
12114
12188
  }
@@ -12228,6 +12302,14 @@ var OrmSession = class {
12228
12302
  entityContext: this
12229
12303
  };
12230
12304
  }
12305
+ /**
12306
+ * Merges session defaults with per-call saveGraph options.
12307
+ * @param options - Per-call saveGraph options
12308
+ * @returns Combined options with per-call values taking precedence
12309
+ */
12310
+ resolveSaveGraphOptions(options) {
12311
+ return { ...this.saveGraphDefaults ?? {}, ...options ?? {} };
12312
+ }
12231
12313
  };
12232
12314
  var buildRelationChangeEntry = (root, relationKey, rootTable, relationName, relation, change) => ({
12233
12315
  root,