metal-orm 1.0.50 → 1.0.52

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.d.cts CHANGED
@@ -92,6 +92,10 @@ declare const col: {
92
92
  * @returns ColumnDef with VARCHAR type
93
93
  */
94
94
  varchar: (length: number) => ColumnDef<"VARCHAR">;
95
+ /**
96
+ * Creates a text column definition
97
+ */
98
+ text: () => ColumnDef<"TEXT">;
95
99
  /**
96
100
  * Creates a fixed precision decimal column definition
97
101
  */
@@ -2985,8 +2989,45 @@ interface HydrationContext<E extends DomainEvent = AnyDomainEvent> {
2985
2989
  interface SaveGraphOptions {
2986
2990
  /** Remove existing collection members that are not present in the payload */
2987
2991
  pruneMissing?: boolean;
2992
+ /**
2993
+ * Coerce JSON-friendly input values into DB-friendly primitives.
2994
+ * Currently:
2995
+ * - Date -> ISO string (for DATE/DATETIME/TIMESTAMP/TIMESTAMPTZ columns)
2996
+ */
2997
+ coerce?: 'json';
2988
2998
  }
2989
2999
 
3000
+ type AnyId = number | string;
3001
+ type AnyFn = (...args: unknown[]) => unknown;
3002
+ type RelationWrapper = HasManyCollection<unknown> | HasOneReference<unknown> | BelongsToReference<unknown> | ManyToManyCollection<unknown>;
3003
+ type FunctionKeys<T> = {
3004
+ [K in keyof T & string]-?: T[K] extends AnyFn ? K : never;
3005
+ }[keyof T & string];
3006
+ type RelationKeys<T> = {
3007
+ [K in keyof T & string]-?: NonNullable<T[K]> extends RelationWrapper ? K : never;
3008
+ }[keyof T & string];
3009
+ type ColumnKeys<T> = Exclude<keyof T & string, FunctionKeys<T> | RelationKeys<T>>;
3010
+ type SaveGraphJsonScalar<T> = T extends Date ? string : T;
3011
+ /**
3012
+ * Input scalar type that accepts JSON-friendly values for common runtime types.
3013
+ * Currently:
3014
+ * - Date fields accept `Date | string` (ISO string recommended)
3015
+ */
3016
+ type SaveGraphInputScalar<T> = T extends Date ? Date | string : T;
3017
+ type ColumnInput$1<TEntity> = {
3018
+ [K in ColumnKeys<TEntity>]?: SaveGraphInputScalar<TEntity[K]>;
3019
+ };
3020
+ type RelationInputValue<T> = T extends HasManyCollection<infer C> ? Array<SaveGraphInputPayload<C> | AnyId> : T extends HasOneReference<infer C> ? SaveGraphInputPayload<C> | AnyId | null : T extends BelongsToReference<infer P> ? SaveGraphInputPayload<P> | AnyId | null : T extends ManyToManyCollection<infer Tgt> ? Array<SaveGraphInputPayload<Tgt> | AnyId> : never;
3021
+ type RelationInput<TEntity> = {
3022
+ [K in RelationKeys<TEntity>]?: RelationInputValue<NonNullable<TEntity[K]>>;
3023
+ };
3024
+ /**
3025
+ * Typed payload accepted by `OrmSession.saveGraph`:
3026
+ * - Only entity scalar keys + relation keys are accepted.
3027
+ * - Scalars can use JSON-friendly values (e.g., Date fields accept ISO strings).
3028
+ */
3029
+ type SaveGraphInputPayload<TEntity> = ColumnInput$1<TEntity> & RelationInput<TEntity>;
3030
+
2990
3031
  /**
2991
3032
  * Interface for ORM interceptors that allow hooking into the flush lifecycle.
2992
3033
  */
@@ -3155,7 +3196,7 @@ declare class OrmSession<E extends DomainEvent = OrmDomainEvent> implements Enti
3155
3196
  * @param options - Graph save options
3156
3197
  * @returns The root entity instance
3157
3198
  */
3158
- saveGraph<TCtor extends EntityConstructor<object>>(entityClass: TCtor, payload: Record<string, unknown>, options?: SaveGraphOptions & {
3199
+ saveGraph<TCtor extends EntityConstructor<object>>(entityClass: TCtor, payload: SaveGraphInputPayload<InstanceType<TCtor>>, options?: SaveGraphOptions & {
3159
3200
  transactional?: boolean;
3160
3201
  }): Promise<InstanceType<TCtor>>;
3161
3202
  /**
@@ -5250,6 +5291,21 @@ declare function executeHydrated<TTable extends TableDef>(session: OrmSession, q
5250
5291
  */
5251
5292
  declare function executeHydratedWithContexts<TTable extends TableDef>(_execCtx: ExecutionContext, hydCtx: HydrationContext, qb: SelectQueryBuilder<unknown, TTable>): Promise<EntityInstance<TTable>[]>;
5252
5293
 
5294
+ type JsonifyScalar<T> = T extends Date ? string : T;
5295
+ /**
5296
+ * Shallow JSON-friendly mapping:
5297
+ * - Date -> ISO string
5298
+ * - Everything else unchanged
5299
+ */
5300
+ type Jsonify<T> = {
5301
+ [K in keyof T]: JsonifyScalar<T[K]>;
5302
+ };
5303
+ /**
5304
+ * Creates a shallow, JSON-friendly copy of an object by converting `Date` values to ISO strings.
5305
+ * This intentionally does not deep-walk nested objects/relations.
5306
+ */
5307
+ declare const jsonify: <T extends object>(value: T) => Jsonify<T>;
5308
+
5253
5309
  /**
5254
5310
  * Context object provided by standard decorators in newer TypeScript versions.
5255
5311
  */
@@ -5549,4 +5605,4 @@ type PooledExecutorFactoryOptions<TConn> = {
5549
5605
  */
5550
5606
  declare function createPooledExecutorFactory<TConn>(opts: PooledExecutorFactoryOptions<TConn>): DbExecutorFactory;
5551
5607
 
5552
- export { type AliasRefNode, type AnyDomainEvent, type ArithmeticExpressionNode, type TableRef as AstTableRef, AsyncLocalStorage, BelongsTo, BelongsToMany, type BelongsToManyOptions, type BelongsToManyRelation, type BelongsToOptions, type BelongsToReference, type BelongsToRelation, type BetweenExpressionNode, type BinaryExpressionNode, type CascadeMode, type CaseExpressionNode, type CastExpressionNode, type CheckConstraint, Column, type ColumnDef, type ColumnDiff, type ColumnInput, type ColumnNode, type ColumnOptions, type ColumnRef, type ColumnToTs, type ColumnType, type CreateTediousClientOptions, type DatabaseCheck, type DatabaseColumn, type DatabaseIndex, type DatabaseSchema, type DatabaseTable, type DbExecutor, type DbExecutorFactory, DefaultBelongsToReference, DefaultHasManyCollection, DefaultManyToManyCollection, type DefaultValue, DeleteQueryBuilder, type DialectName, type DomainEvent, DomainEventBus, type DomainEventHandler, Entity, type EntityContext, type EntityInstance, type EntityOptions, EntityStatus, type ExecutionContext, type ExistsExpressionNode, type ExpressionNode, type ExpressionVisitor, type ForeignKeyReference, type FunctionNode, type GroupConcatOptions, type HasDomainEvents, HasMany, type HasManyCollection, type HasManyOptions, type HasManyRelation, HasOne, type HasOneOptions, type HasOneReference, type HasOneRelation, type HydrationContext, type HydrationMetadata, type HydrationPivotPlan, type HydrationPlan, type HydrationRelationPlan, type InExpressionNode, type InExpressionRight, type IndexColumn, type IndexDef, type InferRow, type InitialHandlers, InsertQueryBuilder, type IntrospectOptions, type JsonPathNode, type LiteralNode, type LiteralValue, type LogicalExpressionNode, type ManyToManyCollection, type MssqlClientLike, MySqlDialect, type MysqlClientLike, type NullExpressionNode, type OperandNode, type OperandVisitor, Orm, type OrmDomainEvent, type OrmInterceptor, type OrmOptions, OrmSession, type OrmSessionOptions, Pool, type PoolAdapter, type PoolLease, type PoolOptions, type PooledConnectionAdapter, type PostgresClientLike, PostgresDialect, PrimaryKey, type QueryLogEntry, type QueryLogger, type QueryResult, type RawDefaultValue, type ReferentialAction, type RelationChange, type RelationChangeEntry, type RelationDef, type RelationKey, RelationKinds, type RelationMap, type RelationTargetTable, type RelationType, type RenderColumnOptions, STANDARD_COLUMN_TYPES, type ScalarSubqueryNode, type SchemaChange, type SchemaChangeKind, type SchemaDiffOptions, type SchemaGenerateResult, type SchemaIntrospector, type SchemaPlan, SelectQueryBuilder, type SelectQueryInput, type SimpleQueryRunner, SqlServerDialect, type SqliteClientLike, SqliteDialect, type StandardColumnType, type SynchronizeOptions, type TableDef, type TableHooks, type TableOptions, type TableRef$1 as TableRef, type TediousColumn, type TediousConnectionLike, type TediousModule, type TediousRequest, type TediousRequestCtor, type TediousTypes, type TrackedEntity, TypeScriptGenerator, UpdateQueryBuilder, type ValueOperandInput, type WindowFunctionNode, abs, acos, add, addDomainEvent, aliasRef, and, ascii, asin, atan, atan2, avg, belongsTo, belongsToMany, between, bootstrapEntities, caseWhen, cast, ceil, ceiling, char, charLength, clearExpressionDispatchers, clearOperandDispatchers, col, columnOperand, concat, concatWs, correlateBy, cos, cot, count, createEntityFromRow, createEntityProxy, createExecutorFromQueryRunner, createMssqlExecutor, createMysqlExecutor, createPooledExecutorFactory, createPostgresExecutor, createQueryLoggingExecutor, createSqliteExecutor, createTediousExecutor, createTediousMssqlClient, currentDate, currentTime, dateAdd, dateDiff, dateFormat, dateSub, dateTrunc, day, dayOfWeek, defineTable, degrees, denseRank, diffSchema, div, endOfMonth, entityRef, eq, esel, executeHydrated, executeHydratedWithContexts, exists, exp, extract, firstValue, floor, fromUnixTime, generateCreateTableSql, generateSchemaSql, getColumn, getSchemaIntrospector, getTableDefFromEntity, groupConcat, gt, gte, hasMany, hasOne, hydrateRows, inList, inSubquery, instr, introspectSchema, isCaseExpressionNode, isCastExpressionNode, isExpressionSelectionNode, isFunctionNode, isNotNull, isNull, isOperandNode, isValueOperandInput, isWindowFunctionNode, jsonPath, lag, lastValue, lead, left, length, like, ln, loadBelongsToManyRelation, loadBelongsToRelation, loadHasManyRelation, loadHasOneRelation, locate, log, log10, logBase, lower, lpad, lt, lte, ltrim, max, min, mod, month, mul, neq, normalizeColumnType, notBetween, notExists, notInList, notInSubquery, notLike, now, ntile, or, outerRef, pi, position, pow, power, radians, rand, random, rank, registerExpressionDispatcher, registerOperandDispatcher, registerSchemaIntrospector, renderColumnDefinition, renderTypeWithArgs, repeat, replace, right, round, rowNumber, rowsToQueryResult, rpad, rtrim, sel, selectFromEntity, sign, sin, space, sqrt, sub, substr, sum, synchronizeSchema, tableRef, tan, toColumnRef, toTableRef, trim, trunc, truncate, unixTimestamp, upper, utcNow, valueToOperand, visitExpression, visitOperand, weekOfYear, windowFunction, year };
5608
+ export { type AliasRefNode, type AnyDomainEvent, type ArithmeticExpressionNode, type TableRef as AstTableRef, AsyncLocalStorage, BelongsTo, BelongsToMany, type BelongsToManyOptions, type BelongsToManyRelation, type BelongsToOptions, type BelongsToReference, type BelongsToRelation, type BetweenExpressionNode, type BinaryExpressionNode, type CascadeMode, type CaseExpressionNode, type CastExpressionNode, type CheckConstraint, Column, type ColumnDef, type ColumnDiff, type ColumnInput, type ColumnNode, type ColumnOptions, type ColumnRef, type ColumnToTs, type ColumnType, type CreateTediousClientOptions, type DatabaseCheck, type DatabaseColumn, type DatabaseIndex, type DatabaseSchema, type DatabaseTable, type DbExecutor, type DbExecutorFactory, DefaultBelongsToReference, DefaultHasManyCollection, DefaultManyToManyCollection, type DefaultValue, DeleteQueryBuilder, type DialectName, type DomainEvent, DomainEventBus, type DomainEventHandler, Entity, type EntityContext, type EntityInstance, type EntityOptions, EntityStatus, type ExecutionContext, type ExistsExpressionNode, type ExpressionNode, type ExpressionVisitor, type ForeignKeyReference, type FunctionNode, type GroupConcatOptions, type HasDomainEvents, HasMany, type HasManyCollection, type HasManyOptions, type HasManyRelation, HasOne, type HasOneOptions, type HasOneReference, type HasOneRelation, type HydrationContext, type HydrationMetadata, type HydrationPivotPlan, type HydrationPlan, type HydrationRelationPlan, type InExpressionNode, type InExpressionRight, type IndexColumn, type IndexDef, type InferRow, type InitialHandlers, InsertQueryBuilder, type IntrospectOptions, type JsonPathNode, type Jsonify, type JsonifyScalar, type LiteralNode, type LiteralValue, type LogicalExpressionNode, type ManyToManyCollection, type MssqlClientLike, MySqlDialect, type MysqlClientLike, type NullExpressionNode, type OperandNode, type OperandVisitor, Orm, type OrmDomainEvent, type OrmInterceptor, type OrmOptions, OrmSession, type OrmSessionOptions, Pool, type PoolAdapter, type PoolLease, type PoolOptions, type PooledConnectionAdapter, type PostgresClientLike, PostgresDialect, PrimaryKey, type QueryLogEntry, type QueryLogger, type QueryResult, type RawDefaultValue, type ReferentialAction, type RelationChange, type RelationChangeEntry, type RelationDef, type RelationKey, RelationKinds, type RelationMap, type RelationTargetTable, type RelationType, type RenderColumnOptions, STANDARD_COLUMN_TYPES, type SaveGraphInputPayload, type SaveGraphInputScalar, type SaveGraphJsonScalar, type ScalarSubqueryNode, type SchemaChange, type SchemaChangeKind, type SchemaDiffOptions, type SchemaGenerateResult, type SchemaIntrospector, type SchemaPlan, SelectQueryBuilder, type SelectQueryInput, type SimpleQueryRunner, SqlServerDialect, type SqliteClientLike, SqliteDialect, type StandardColumnType, type SynchronizeOptions, type TableDef, type TableHooks, type TableOptions, type TableRef$1 as TableRef, type TediousColumn, type TediousConnectionLike, type TediousModule, type TediousRequest, type TediousRequestCtor, type TediousTypes, type TrackedEntity, TypeScriptGenerator, UpdateQueryBuilder, type ValueOperandInput, type WindowFunctionNode, abs, acos, add, addDomainEvent, aliasRef, and, ascii, asin, atan, atan2, avg, belongsTo, belongsToMany, between, bootstrapEntities, caseWhen, cast, ceil, ceiling, char, charLength, clearExpressionDispatchers, clearOperandDispatchers, col, columnOperand, concat, concatWs, correlateBy, cos, cot, count, createEntityFromRow, createEntityProxy, createExecutorFromQueryRunner, createMssqlExecutor, createMysqlExecutor, createPooledExecutorFactory, createPostgresExecutor, createQueryLoggingExecutor, createSqliteExecutor, createTediousExecutor, createTediousMssqlClient, currentDate, currentTime, dateAdd, dateDiff, dateFormat, dateSub, dateTrunc, day, dayOfWeek, defineTable, degrees, denseRank, diffSchema, div, endOfMonth, entityRef, eq, esel, executeHydrated, executeHydratedWithContexts, exists, exp, extract, firstValue, floor, fromUnixTime, generateCreateTableSql, generateSchemaSql, getColumn, getSchemaIntrospector, getTableDefFromEntity, groupConcat, gt, gte, hasMany, hasOne, hydrateRows, inList, inSubquery, instr, introspectSchema, isCaseExpressionNode, isCastExpressionNode, isExpressionSelectionNode, isFunctionNode, isNotNull, isNull, isOperandNode, isValueOperandInput, isWindowFunctionNode, jsonPath, jsonify, lag, lastValue, lead, left, length, like, ln, loadBelongsToManyRelation, loadBelongsToRelation, loadHasManyRelation, loadHasOneRelation, locate, log, log10, logBase, lower, lpad, lt, lte, ltrim, max, min, mod, month, mul, neq, normalizeColumnType, notBetween, notExists, notInList, notInSubquery, notLike, now, ntile, or, outerRef, pi, position, pow, power, radians, rand, random, rank, registerExpressionDispatcher, registerOperandDispatcher, registerSchemaIntrospector, renderColumnDefinition, renderTypeWithArgs, repeat, replace, right, round, rowNumber, rowsToQueryResult, rpad, rtrim, sel, selectFromEntity, sign, sin, space, sqrt, sub, substr, sum, synchronizeSchema, tableRef, tan, toColumnRef, toTableRef, trim, trunc, truncate, unixTimestamp, upper, utcNow, valueToOperand, visitExpression, visitOperand, weekOfYear, windowFunction, year };
package/dist/index.d.ts CHANGED
@@ -92,6 +92,10 @@ declare const col: {
92
92
  * @returns ColumnDef with VARCHAR type
93
93
  */
94
94
  varchar: (length: number) => ColumnDef<"VARCHAR">;
95
+ /**
96
+ * Creates a text column definition
97
+ */
98
+ text: () => ColumnDef<"TEXT">;
95
99
  /**
96
100
  * Creates a fixed precision decimal column definition
97
101
  */
@@ -2985,8 +2989,45 @@ interface HydrationContext<E extends DomainEvent = AnyDomainEvent> {
2985
2989
  interface SaveGraphOptions {
2986
2990
  /** Remove existing collection members that are not present in the payload */
2987
2991
  pruneMissing?: boolean;
2992
+ /**
2993
+ * Coerce JSON-friendly input values into DB-friendly primitives.
2994
+ * Currently:
2995
+ * - Date -> ISO string (for DATE/DATETIME/TIMESTAMP/TIMESTAMPTZ columns)
2996
+ */
2997
+ coerce?: 'json';
2988
2998
  }
2989
2999
 
3000
+ type AnyId = number | string;
3001
+ type AnyFn = (...args: unknown[]) => unknown;
3002
+ type RelationWrapper = HasManyCollection<unknown> | HasOneReference<unknown> | BelongsToReference<unknown> | ManyToManyCollection<unknown>;
3003
+ type FunctionKeys<T> = {
3004
+ [K in keyof T & string]-?: T[K] extends AnyFn ? K : never;
3005
+ }[keyof T & string];
3006
+ type RelationKeys<T> = {
3007
+ [K in keyof T & string]-?: NonNullable<T[K]> extends RelationWrapper ? K : never;
3008
+ }[keyof T & string];
3009
+ type ColumnKeys<T> = Exclude<keyof T & string, FunctionKeys<T> | RelationKeys<T>>;
3010
+ type SaveGraphJsonScalar<T> = T extends Date ? string : T;
3011
+ /**
3012
+ * Input scalar type that accepts JSON-friendly values for common runtime types.
3013
+ * Currently:
3014
+ * - Date fields accept `Date | string` (ISO string recommended)
3015
+ */
3016
+ type SaveGraphInputScalar<T> = T extends Date ? Date | string : T;
3017
+ type ColumnInput$1<TEntity> = {
3018
+ [K in ColumnKeys<TEntity>]?: SaveGraphInputScalar<TEntity[K]>;
3019
+ };
3020
+ type RelationInputValue<T> = T extends HasManyCollection<infer C> ? Array<SaveGraphInputPayload<C> | AnyId> : T extends HasOneReference<infer C> ? SaveGraphInputPayload<C> | AnyId | null : T extends BelongsToReference<infer P> ? SaveGraphInputPayload<P> | AnyId | null : T extends ManyToManyCollection<infer Tgt> ? Array<SaveGraphInputPayload<Tgt> | AnyId> : never;
3021
+ type RelationInput<TEntity> = {
3022
+ [K in RelationKeys<TEntity>]?: RelationInputValue<NonNullable<TEntity[K]>>;
3023
+ };
3024
+ /**
3025
+ * Typed payload accepted by `OrmSession.saveGraph`:
3026
+ * - Only entity scalar keys + relation keys are accepted.
3027
+ * - Scalars can use JSON-friendly values (e.g., Date fields accept ISO strings).
3028
+ */
3029
+ type SaveGraphInputPayload<TEntity> = ColumnInput$1<TEntity> & RelationInput<TEntity>;
3030
+
2990
3031
  /**
2991
3032
  * Interface for ORM interceptors that allow hooking into the flush lifecycle.
2992
3033
  */
@@ -3155,7 +3196,7 @@ declare class OrmSession<E extends DomainEvent = OrmDomainEvent> implements Enti
3155
3196
  * @param options - Graph save options
3156
3197
  * @returns The root entity instance
3157
3198
  */
3158
- saveGraph<TCtor extends EntityConstructor<object>>(entityClass: TCtor, payload: Record<string, unknown>, options?: SaveGraphOptions & {
3199
+ saveGraph<TCtor extends EntityConstructor<object>>(entityClass: TCtor, payload: SaveGraphInputPayload<InstanceType<TCtor>>, options?: SaveGraphOptions & {
3159
3200
  transactional?: boolean;
3160
3201
  }): Promise<InstanceType<TCtor>>;
3161
3202
  /**
@@ -5250,6 +5291,21 @@ declare function executeHydrated<TTable extends TableDef>(session: OrmSession, q
5250
5291
  */
5251
5292
  declare function executeHydratedWithContexts<TTable extends TableDef>(_execCtx: ExecutionContext, hydCtx: HydrationContext, qb: SelectQueryBuilder<unknown, TTable>): Promise<EntityInstance<TTable>[]>;
5252
5293
 
5294
+ type JsonifyScalar<T> = T extends Date ? string : T;
5295
+ /**
5296
+ * Shallow JSON-friendly mapping:
5297
+ * - Date -> ISO string
5298
+ * - Everything else unchanged
5299
+ */
5300
+ type Jsonify<T> = {
5301
+ [K in keyof T]: JsonifyScalar<T[K]>;
5302
+ };
5303
+ /**
5304
+ * Creates a shallow, JSON-friendly copy of an object by converting `Date` values to ISO strings.
5305
+ * This intentionally does not deep-walk nested objects/relations.
5306
+ */
5307
+ declare const jsonify: <T extends object>(value: T) => Jsonify<T>;
5308
+
5253
5309
  /**
5254
5310
  * Context object provided by standard decorators in newer TypeScript versions.
5255
5311
  */
@@ -5549,4 +5605,4 @@ type PooledExecutorFactoryOptions<TConn> = {
5549
5605
  */
5550
5606
  declare function createPooledExecutorFactory<TConn>(opts: PooledExecutorFactoryOptions<TConn>): DbExecutorFactory;
5551
5607
 
5552
- export { type AliasRefNode, type AnyDomainEvent, type ArithmeticExpressionNode, type TableRef as AstTableRef, AsyncLocalStorage, BelongsTo, BelongsToMany, type BelongsToManyOptions, type BelongsToManyRelation, type BelongsToOptions, type BelongsToReference, type BelongsToRelation, type BetweenExpressionNode, type BinaryExpressionNode, type CascadeMode, type CaseExpressionNode, type CastExpressionNode, type CheckConstraint, Column, type ColumnDef, type ColumnDiff, type ColumnInput, type ColumnNode, type ColumnOptions, type ColumnRef, type ColumnToTs, type ColumnType, type CreateTediousClientOptions, type DatabaseCheck, type DatabaseColumn, type DatabaseIndex, type DatabaseSchema, type DatabaseTable, type DbExecutor, type DbExecutorFactory, DefaultBelongsToReference, DefaultHasManyCollection, DefaultManyToManyCollection, type DefaultValue, DeleteQueryBuilder, type DialectName, type DomainEvent, DomainEventBus, type DomainEventHandler, Entity, type EntityContext, type EntityInstance, type EntityOptions, EntityStatus, type ExecutionContext, type ExistsExpressionNode, type ExpressionNode, type ExpressionVisitor, type ForeignKeyReference, type FunctionNode, type GroupConcatOptions, type HasDomainEvents, HasMany, type HasManyCollection, type HasManyOptions, type HasManyRelation, HasOne, type HasOneOptions, type HasOneReference, type HasOneRelation, type HydrationContext, type HydrationMetadata, type HydrationPivotPlan, type HydrationPlan, type HydrationRelationPlan, type InExpressionNode, type InExpressionRight, type IndexColumn, type IndexDef, type InferRow, type InitialHandlers, InsertQueryBuilder, type IntrospectOptions, type JsonPathNode, type LiteralNode, type LiteralValue, type LogicalExpressionNode, type ManyToManyCollection, type MssqlClientLike, MySqlDialect, type MysqlClientLike, type NullExpressionNode, type OperandNode, type OperandVisitor, Orm, type OrmDomainEvent, type OrmInterceptor, type OrmOptions, OrmSession, type OrmSessionOptions, Pool, type PoolAdapter, type PoolLease, type PoolOptions, type PooledConnectionAdapter, type PostgresClientLike, PostgresDialect, PrimaryKey, type QueryLogEntry, type QueryLogger, type QueryResult, type RawDefaultValue, type ReferentialAction, type RelationChange, type RelationChangeEntry, type RelationDef, type RelationKey, RelationKinds, type RelationMap, type RelationTargetTable, type RelationType, type RenderColumnOptions, STANDARD_COLUMN_TYPES, type ScalarSubqueryNode, type SchemaChange, type SchemaChangeKind, type SchemaDiffOptions, type SchemaGenerateResult, type SchemaIntrospector, type SchemaPlan, SelectQueryBuilder, type SelectQueryInput, type SimpleQueryRunner, SqlServerDialect, type SqliteClientLike, SqliteDialect, type StandardColumnType, type SynchronizeOptions, type TableDef, type TableHooks, type TableOptions, type TableRef$1 as TableRef, type TediousColumn, type TediousConnectionLike, type TediousModule, type TediousRequest, type TediousRequestCtor, type TediousTypes, type TrackedEntity, TypeScriptGenerator, UpdateQueryBuilder, type ValueOperandInput, type WindowFunctionNode, abs, acos, add, addDomainEvent, aliasRef, and, ascii, asin, atan, atan2, avg, belongsTo, belongsToMany, between, bootstrapEntities, caseWhen, cast, ceil, ceiling, char, charLength, clearExpressionDispatchers, clearOperandDispatchers, col, columnOperand, concat, concatWs, correlateBy, cos, cot, count, createEntityFromRow, createEntityProxy, createExecutorFromQueryRunner, createMssqlExecutor, createMysqlExecutor, createPooledExecutorFactory, createPostgresExecutor, createQueryLoggingExecutor, createSqliteExecutor, createTediousExecutor, createTediousMssqlClient, currentDate, currentTime, dateAdd, dateDiff, dateFormat, dateSub, dateTrunc, day, dayOfWeek, defineTable, degrees, denseRank, diffSchema, div, endOfMonth, entityRef, eq, esel, executeHydrated, executeHydratedWithContexts, exists, exp, extract, firstValue, floor, fromUnixTime, generateCreateTableSql, generateSchemaSql, getColumn, getSchemaIntrospector, getTableDefFromEntity, groupConcat, gt, gte, hasMany, hasOne, hydrateRows, inList, inSubquery, instr, introspectSchema, isCaseExpressionNode, isCastExpressionNode, isExpressionSelectionNode, isFunctionNode, isNotNull, isNull, isOperandNode, isValueOperandInput, isWindowFunctionNode, jsonPath, lag, lastValue, lead, left, length, like, ln, loadBelongsToManyRelation, loadBelongsToRelation, loadHasManyRelation, loadHasOneRelation, locate, log, log10, logBase, lower, lpad, lt, lte, ltrim, max, min, mod, month, mul, neq, normalizeColumnType, notBetween, notExists, notInList, notInSubquery, notLike, now, ntile, or, outerRef, pi, position, pow, power, radians, rand, random, rank, registerExpressionDispatcher, registerOperandDispatcher, registerSchemaIntrospector, renderColumnDefinition, renderTypeWithArgs, repeat, replace, right, round, rowNumber, rowsToQueryResult, rpad, rtrim, sel, selectFromEntity, sign, sin, space, sqrt, sub, substr, sum, synchronizeSchema, tableRef, tan, toColumnRef, toTableRef, trim, trunc, truncate, unixTimestamp, upper, utcNow, valueToOperand, visitExpression, visitOperand, weekOfYear, windowFunction, year };
5608
+ export { type AliasRefNode, type AnyDomainEvent, type ArithmeticExpressionNode, type TableRef as AstTableRef, AsyncLocalStorage, BelongsTo, BelongsToMany, type BelongsToManyOptions, type BelongsToManyRelation, type BelongsToOptions, type BelongsToReference, type BelongsToRelation, type BetweenExpressionNode, type BinaryExpressionNode, type CascadeMode, type CaseExpressionNode, type CastExpressionNode, type CheckConstraint, Column, type ColumnDef, type ColumnDiff, type ColumnInput, type ColumnNode, type ColumnOptions, type ColumnRef, type ColumnToTs, type ColumnType, type CreateTediousClientOptions, type DatabaseCheck, type DatabaseColumn, type DatabaseIndex, type DatabaseSchema, type DatabaseTable, type DbExecutor, type DbExecutorFactory, DefaultBelongsToReference, DefaultHasManyCollection, DefaultManyToManyCollection, type DefaultValue, DeleteQueryBuilder, type DialectName, type DomainEvent, DomainEventBus, type DomainEventHandler, Entity, type EntityContext, type EntityInstance, type EntityOptions, EntityStatus, type ExecutionContext, type ExistsExpressionNode, type ExpressionNode, type ExpressionVisitor, type ForeignKeyReference, type FunctionNode, type GroupConcatOptions, type HasDomainEvents, HasMany, type HasManyCollection, type HasManyOptions, type HasManyRelation, HasOne, type HasOneOptions, type HasOneReference, type HasOneRelation, type HydrationContext, type HydrationMetadata, type HydrationPivotPlan, type HydrationPlan, type HydrationRelationPlan, type InExpressionNode, type InExpressionRight, type IndexColumn, type IndexDef, type InferRow, type InitialHandlers, InsertQueryBuilder, type IntrospectOptions, type JsonPathNode, type Jsonify, type JsonifyScalar, type LiteralNode, type LiteralValue, type LogicalExpressionNode, type ManyToManyCollection, type MssqlClientLike, MySqlDialect, type MysqlClientLike, type NullExpressionNode, type OperandNode, type OperandVisitor, Orm, type OrmDomainEvent, type OrmInterceptor, type OrmOptions, OrmSession, type OrmSessionOptions, Pool, type PoolAdapter, type PoolLease, type PoolOptions, type PooledConnectionAdapter, type PostgresClientLike, PostgresDialect, PrimaryKey, type QueryLogEntry, type QueryLogger, type QueryResult, type RawDefaultValue, type ReferentialAction, type RelationChange, type RelationChangeEntry, type RelationDef, type RelationKey, RelationKinds, type RelationMap, type RelationTargetTable, type RelationType, type RenderColumnOptions, STANDARD_COLUMN_TYPES, type SaveGraphInputPayload, type SaveGraphInputScalar, type SaveGraphJsonScalar, type ScalarSubqueryNode, type SchemaChange, type SchemaChangeKind, type SchemaDiffOptions, type SchemaGenerateResult, type SchemaIntrospector, type SchemaPlan, SelectQueryBuilder, type SelectQueryInput, type SimpleQueryRunner, SqlServerDialect, type SqliteClientLike, SqliteDialect, type StandardColumnType, type SynchronizeOptions, type TableDef, type TableHooks, type TableOptions, type TableRef$1 as TableRef, type TediousColumn, type TediousConnectionLike, type TediousModule, type TediousRequest, type TediousRequestCtor, type TediousTypes, type TrackedEntity, TypeScriptGenerator, UpdateQueryBuilder, type ValueOperandInput, type WindowFunctionNode, abs, acos, add, addDomainEvent, aliasRef, and, ascii, asin, atan, atan2, avg, belongsTo, belongsToMany, between, bootstrapEntities, caseWhen, cast, ceil, ceiling, char, charLength, clearExpressionDispatchers, clearOperandDispatchers, col, columnOperand, concat, concatWs, correlateBy, cos, cot, count, createEntityFromRow, createEntityProxy, createExecutorFromQueryRunner, createMssqlExecutor, createMysqlExecutor, createPooledExecutorFactory, createPostgresExecutor, createQueryLoggingExecutor, createSqliteExecutor, createTediousExecutor, createTediousMssqlClient, currentDate, currentTime, dateAdd, dateDiff, dateFormat, dateSub, dateTrunc, day, dayOfWeek, defineTable, degrees, denseRank, diffSchema, div, endOfMonth, entityRef, eq, esel, executeHydrated, executeHydratedWithContexts, exists, exp, extract, firstValue, floor, fromUnixTime, generateCreateTableSql, generateSchemaSql, getColumn, getSchemaIntrospector, getTableDefFromEntity, groupConcat, gt, gte, hasMany, hasOne, hydrateRows, inList, inSubquery, instr, introspectSchema, isCaseExpressionNode, isCastExpressionNode, isExpressionSelectionNode, isFunctionNode, isNotNull, isNull, isOperandNode, isValueOperandInput, isWindowFunctionNode, jsonPath, jsonify, lag, lastValue, lead, left, length, like, ln, loadBelongsToManyRelation, loadBelongsToRelation, loadHasManyRelation, loadHasOneRelation, locate, log, log10, logBase, lower, lpad, lt, lte, ltrim, max, min, mod, month, mul, neq, normalizeColumnType, notBetween, notExists, notInList, notInSubquery, notLike, now, ntile, or, outerRef, pi, position, pow, power, radians, rand, random, rank, registerExpressionDispatcher, registerOperandDispatcher, registerSchemaIntrospector, renderColumnDefinition, renderTypeWithArgs, repeat, replace, right, round, rowNumber, rowsToQueryResult, rpad, rtrim, sel, selectFromEntity, sign, sin, space, sqrt, sub, substr, sum, synchronizeSchema, tableRef, tan, toColumnRef, toTableRef, trim, trunc, truncate, unixTimestamp, upper, utcNow, valueToOperand, visitExpression, visitOperand, weekOfYear, windowFunction, year };
package/dist/index.js CHANGED
@@ -159,6 +159,10 @@ var col = {
159
159
  * @returns ColumnDef with VARCHAR type
160
160
  */
161
161
  varchar: (length2) => ({ name: "", type: "VARCHAR", args: [length2] }),
162
+ /**
163
+ * Creates a text column definition
164
+ */
165
+ text: () => ({ name: "", type: "TEXT" }),
162
166
  /**
163
167
  * Creates a fixed precision decimal column definition
164
168
  */
@@ -6667,6 +6671,29 @@ var postgresIntrospector = {
6667
6671
  if (!trimmed) return;
6668
6672
  columnComments.set(key, trimmed);
6669
6673
  });
6674
+ const tableCommentRows = await queryRows(
6675
+ ctx.executor,
6676
+ `
6677
+ SELECT
6678
+ ns.nspname AS table_schema,
6679
+ cls.relname AS table_name,
6680
+ pg_catalog.obj_description(cls.oid) AS description
6681
+ FROM pg_catalog.pg_class cls
6682
+ JOIN pg_catalog.pg_namespace ns ON ns.oid = cls.relnamespace
6683
+ WHERE ns.nspname = $1
6684
+ AND cls.relkind IN ('r', 'p')
6685
+ `,
6686
+ [schema]
6687
+ );
6688
+ const tableComments = /* @__PURE__ */ new Map();
6689
+ tableCommentRows.forEach((r) => {
6690
+ if (!shouldIncludeTable(r.table_name, options)) return;
6691
+ if (!r.description) return;
6692
+ const key = `${r.table_schema}.${r.table_name}`;
6693
+ const trimmed = r.description.trim();
6694
+ if (!trimmed) return;
6695
+ tableComments.set(key, trimmed);
6696
+ });
6670
6697
  const qbPk = new SelectQueryBuilder(PgKeyColumnUsage).select({
6671
6698
  table_schema: PgKeyColumnUsage.columns.table_schema,
6672
6699
  table_name: PgKeyColumnUsage.columns.table_name,
@@ -6807,7 +6834,8 @@ var postgresIntrospector = {
6807
6834
  schema: r.table_schema,
6808
6835
  columns: [],
6809
6836
  primaryKey: pkMap.get(key) || [],
6810
- indexes: []
6837
+ indexes: [],
6838
+ comment: tableComments.get(key)
6811
6839
  });
6812
6840
  }
6813
6841
  const cols = tablesByKey.get(key);
@@ -7192,6 +7220,53 @@ var runPragma = async (name, table, alias, columnAliases, ctx) => {
7192
7220
  const query = buildPragmaQuery(name, table, alias, columnAliases);
7193
7221
  return await runSelectNode(query, ctx);
7194
7222
  };
7223
+ var loadSqliteSchemaComments = async (ctx) => {
7224
+ const tableComments = /* @__PURE__ */ new Map();
7225
+ const columnComments = /* @__PURE__ */ new Map();
7226
+ const tableExists = await queryRows(
7227
+ ctx.executor,
7228
+ `SELECT name FROM sqlite_master WHERE type='table' AND name='schema_comments' LIMIT 1`
7229
+ );
7230
+ if (!tableExists.length) {
7231
+ return { tableComments, columnComments };
7232
+ }
7233
+ const commentRows = await queryRows(
7234
+ ctx.executor,
7235
+ `SELECT object_type, schema_name, table_name, column_name, comment FROM schema_comments`
7236
+ );
7237
+ for (const row of commentRows) {
7238
+ const objectType = typeof row.object_type === "string" ? row.object_type.toLowerCase() : "";
7239
+ const tableName = typeof row.table_name === "string" ? row.table_name : "";
7240
+ if (!tableName) continue;
7241
+ const columnName = typeof row.column_name === "string" ? row.column_name : "";
7242
+ const schemaName = typeof row.schema_name === "string" ? row.schema_name : "";
7243
+ const rawComment = row.comment;
7244
+ if (rawComment == null) continue;
7245
+ const commentText = String(rawComment).trim();
7246
+ if (!commentText) continue;
7247
+ const addTableComment = () => {
7248
+ tableComments.set(tableName, commentText);
7249
+ if (schemaName) {
7250
+ tableComments.set(`${schemaName}.${tableName}`, commentText);
7251
+ }
7252
+ };
7253
+ const addColumnComment = () => {
7254
+ columnComments.set(`${tableName}.${columnName}`, commentText);
7255
+ if (schemaName) {
7256
+ columnComments.set(`${schemaName}.${tableName}.${columnName}`, commentText);
7257
+ }
7258
+ };
7259
+ if (objectType === "table") {
7260
+ addTableComment();
7261
+ } else if (objectType === "column" && columnName) {
7262
+ addColumnComment();
7263
+ }
7264
+ }
7265
+ return {
7266
+ tableComments,
7267
+ columnComments
7268
+ };
7269
+ };
7195
7270
  var sqliteIntrospector = {
7196
7271
  async introspect(ctx, options) {
7197
7272
  const alias = "sqlite_master";
@@ -7205,6 +7280,7 @@ var sqliteIntrospector = {
7205
7280
  notLike(columnNode2(alias, "name"), "sqlite_%")
7206
7281
  )
7207
7282
  };
7283
+ const { tableComments, columnComments } = await loadSqliteSchemaComments(ctx);
7208
7284
  const tableRows = await runSelectNode(tablesQuery, ctx);
7209
7285
  const tables = [];
7210
7286
  for (const row of tableRows) {
@@ -7231,15 +7307,26 @@ var sqliteIntrospector = {
7231
7307
  ["seq", "name", "unique"],
7232
7308
  ctx
7233
7309
  );
7234
- const tableEntry = { name: tableName, columns: [], primaryKey: [], indexes: [] };
7310
+ const tableEntry = {
7311
+ name: tableName,
7312
+ columns: [],
7313
+ primaryKey: [],
7314
+ indexes: [],
7315
+ comment: tableComments.get(tableName)
7316
+ };
7235
7317
  tableInfo.forEach((info) => {
7236
- tableEntry.columns.push({
7318
+ const column = {
7237
7319
  name: info.name,
7238
7320
  type: info.type,
7239
7321
  notNull: info.notnull === 1,
7240
7322
  default: info.dflt_value ?? void 0,
7241
7323
  autoIncrement: false
7242
- });
7324
+ };
7325
+ const columnComment = columnComments.get(`${tableName}.${info.name}`);
7326
+ if (columnComment) {
7327
+ column.comment = columnComment;
7328
+ }
7329
+ tableEntry.columns.push(column);
7243
7330
  if (info.pk && info.pk > 0) {
7244
7331
  tableEntry.primaryKey = tableEntry.primaryKey || [];
7245
7332
  tableEntry.primaryKey.push(info.name);
@@ -7511,6 +7598,60 @@ var mssqlIntrospector = {
7511
7598
  async introspect(ctx, options) {
7512
7599
  const schema = options.schema;
7513
7600
  const schemaCondition = schema ? eq(columnNode3("sch", "name"), schema) : void 0;
7601
+ const schemaFilter = schema ? "AND sch.name = @p1" : "";
7602
+ const schemaParams = schema ? [schema] : [];
7603
+ const tableCommentRows = await queryRows(
7604
+ ctx.executor,
7605
+ `
7606
+ SELECT
7607
+ sch.name AS table_schema,
7608
+ t.name AS table_name,
7609
+ CONVERT(nvarchar(4000), ep.value) AS comment
7610
+ FROM sys.extended_properties ep
7611
+ JOIN sys.tables t ON t.object_id = ep.major_id
7612
+ JOIN sys.schemas sch ON sch.schema_id = t.schema_id
7613
+ WHERE ep.class = 1
7614
+ AND ep.minor_id = 0
7615
+ AND ep.name = 'MS_Description'
7616
+ ${schemaFilter}
7617
+ `,
7618
+ schemaParams
7619
+ );
7620
+ const columnCommentRows = await queryRows(
7621
+ ctx.executor,
7622
+ `
7623
+ SELECT
7624
+ sch.name AS table_schema,
7625
+ t.name AS table_name,
7626
+ col.name AS column_name,
7627
+ CONVERT(nvarchar(4000), ep.value) AS comment
7628
+ FROM sys.extended_properties ep
7629
+ JOIN sys.columns col ON col.object_id = ep.major_id AND col.column_id = ep.minor_id
7630
+ JOIN sys.tables t ON t.object_id = col.object_id
7631
+ JOIN sys.schemas sch ON sch.schema_id = t.schema_id
7632
+ WHERE ep.class = 1
7633
+ AND ep.minor_id > 0
7634
+ AND ep.name = 'MS_Description'
7635
+ ${schemaFilter}
7636
+ `,
7637
+ schemaParams
7638
+ );
7639
+ const tableComments = /* @__PURE__ */ new Map();
7640
+ tableCommentRows.forEach((r) => {
7641
+ if (!shouldIncludeTable(r.table_name, options)) return;
7642
+ if (!r.comment) return;
7643
+ const trimmed = r.comment.trim();
7644
+ if (!trimmed) return;
7645
+ tableComments.set(`${r.table_schema}.${r.table_name}`, trimmed);
7646
+ });
7647
+ const columnComments = /* @__PURE__ */ new Map();
7648
+ columnCommentRows.forEach((r) => {
7649
+ if (!shouldIncludeTable(r.table_name, options)) return;
7650
+ if (!r.comment) return;
7651
+ const trimmed = r.comment.trim();
7652
+ if (!trimmed) return;
7653
+ columnComments.set(`${r.table_schema}.${r.table_name}.${r.column_name}`, trimmed);
7654
+ });
7514
7655
  const dataTypeExpression = buildMssqlDataType(
7515
7656
  { table: "ty", name: "name" },
7516
7657
  { table: "c", name: "max_length" },
@@ -7816,7 +7957,8 @@ var mssqlIntrospector = {
7816
7957
  schema: r.table_schema,
7817
7958
  columns: [],
7818
7959
  primaryKey: pkMap.get(key) || [],
7819
- indexes: []
7960
+ indexes: [],
7961
+ comment: tableComments.get(key)
7820
7962
  });
7821
7963
  }
7822
7964
  const table = tablesByKey.get(key);
@@ -7827,6 +7969,10 @@ var mssqlIntrospector = {
7827
7969
  default: r.column_default ?? void 0,
7828
7970
  autoIncrement: !!r.is_identity
7829
7971
  };
7972
+ const columnComment = columnComments.get(`${key}.${r.column_name}`);
7973
+ if (columnComment) {
7974
+ column.comment = columnComment;
7975
+ }
7830
7976
  const fk = fkMap.get(`${key}.${r.column_name}`)?.[0];
7831
7977
  if (fk) {
7832
7978
  column.references = {
@@ -9155,18 +9301,30 @@ var runInTransaction = async (executor, action) => {
9155
9301
 
9156
9302
  // src/orm/save-graph.ts
9157
9303
  var toKey8 = (value) => value === null || value === void 0 ? "" : String(value);
9158
- var pickColumns = (table, payload) => {
9304
+ var coerceColumnValue = (table, columnName, value, options) => {
9305
+ if (options.coerce !== "json") return value;
9306
+ if (value === null || value === void 0) return value;
9307
+ const column = table.columns[columnName];
9308
+ if (!column) return value;
9309
+ const normalized = normalizeColumnType(column.type);
9310
+ const isDateLikeColumn = normalized === "date" || normalized === "datetime" || normalized === "timestamp" || normalized === "timestamptz";
9311
+ if (isDateLikeColumn && value instanceof Date) {
9312
+ return value.toISOString();
9313
+ }
9314
+ return value;
9315
+ };
9316
+ var pickColumns = (table, payload, options) => {
9159
9317
  const columns = {};
9160
9318
  for (const key of Object.keys(table.columns)) {
9161
9319
  if (payload[key] !== void 0) {
9162
- columns[key] = payload[key];
9320
+ columns[key] = coerceColumnValue(table, key, payload[key], options);
9163
9321
  }
9164
9322
  }
9165
9323
  return columns;
9166
9324
  };
9167
- var ensureEntity = (session, table, payload) => {
9325
+ var ensureEntity = (session, table, payload, options) => {
9168
9326
  const pk = findPrimaryKey(table);
9169
- const row = pickColumns(table, payload);
9327
+ const row = pickColumns(table, payload, options);
9170
9328
  const pkValue = payload[pk];
9171
9329
  if (pkValue !== void 0 && pkValue !== null) {
9172
9330
  const tracked = session.getEntity(table, pkValue);
@@ -9179,10 +9337,10 @@ var ensureEntity = (session, table, payload) => {
9179
9337
  }
9180
9338
  return createEntityFromRow(session, table, row);
9181
9339
  };
9182
- var assignColumns = (table, entity, payload) => {
9340
+ var assignColumns = (table, entity, payload, options) => {
9183
9341
  for (const key of Object.keys(table.columns)) {
9184
9342
  if (payload[key] !== void 0) {
9185
- entity[key] = payload[key];
9343
+ entity[key] = coerceColumnValue(table, key, payload[key], options);
9186
9344
  }
9187
9345
  }
9188
9346
  };
@@ -9209,8 +9367,8 @@ var handleHasMany = async (session, root, relationName, relation, payload, optio
9209
9367
  const asObj = typeof item === "object" ? item : { [targetPk]: item };
9210
9368
  const pkValue = asObj[targetPk];
9211
9369
  const current = findInCollectionByPk(existing, targetPk, pkValue) ?? (pkValue !== void 0 && pkValue !== null ? session.getEntity(targetTable, pkValue) : void 0);
9212
- const entity = current ?? ensureEntity(session, targetTable, asObj);
9213
- assignColumns(targetTable, entity, asObj);
9370
+ const entity = current ?? ensureEntity(session, targetTable, asObj, options);
9371
+ assignColumns(targetTable, entity, asObj, options);
9214
9372
  await applyGraphToEntity(session, targetTable, entity, asObj, options);
9215
9373
  if (!isEntityInCollection(collection.getItems(), targetPk, entity)) {
9216
9374
  collection.attach(entity);
@@ -9285,8 +9443,8 @@ var handleBelongsToMany = async (session, root, relationName, relation, payload,
9285
9443
  }
9286
9444
  const asObj = item;
9287
9445
  const pkValue = asObj[targetPk];
9288
- const entity = pkValue !== void 0 && pkValue !== null ? session.getEntity(targetTable, pkValue) ?? ensureEntity(session, targetTable, asObj) : ensureEntity(session, targetTable, asObj);
9289
- assignColumns(targetTable, entity, asObj);
9446
+ const entity = pkValue !== void 0 && pkValue !== null ? session.getEntity(targetTable, pkValue) ?? ensureEntity(session, targetTable, asObj, options) : ensureEntity(session, targetTable, asObj, options);
9447
+ assignColumns(targetTable, entity, asObj, options);
9290
9448
  await applyGraphToEntity(session, targetTable, entity, asObj, options);
9291
9449
  if (!isEntityInCollection(collection.getItems(), targetPk, entity)) {
9292
9450
  collection.attach(entity);
@@ -9317,7 +9475,7 @@ var applyRelation = async (session, table, entity, relationName, relation, paylo
9317
9475
  }
9318
9476
  };
9319
9477
  var applyGraphToEntity = async (session, table, entity, payload, options) => {
9320
- assignColumns(table, entity, payload);
9478
+ assignColumns(table, entity, payload, options);
9321
9479
  for (const [relationName, relation] of Object.entries(table.relations)) {
9322
9480
  if (!(relationName in payload)) continue;
9323
9481
  await applyRelation(session, table, entity, relationName, relation, payload[relationName], options);
@@ -9328,7 +9486,7 @@ var saveGraphInternal = async (session, entityClass, payload, options = {}) => {
9328
9486
  if (!table) {
9329
9487
  throw new Error("Entity metadata has not been bootstrapped");
9330
9488
  }
9331
- const root = ensureEntity(session, table, payload);
9489
+ const root = ensureEntity(session, table, payload, options);
9332
9490
  await applyGraphToEntity(session, table, root, payload, options);
9333
9491
  return root;
9334
9492
  };
@@ -9511,13 +9669,6 @@ var OrmSession = class {
9511
9669
  async findMany(qb) {
9512
9670
  return executeHydrated(this, qb);
9513
9671
  }
9514
- /**
9515
- * Saves an entity graph (root + nested relations) based on a DTO-like payload.
9516
- * @param entityClass - Root entity constructor
9517
- * @param payload - DTO payload containing column values and nested relations
9518
- * @param options - Graph save options
9519
- * @returns The root entity instance
9520
- */
9521
9672
  async saveGraph(entityClass, payload, options) {
9522
9673
  const { transactional = true, ...graphOptions } = options ?? {};
9523
9674
  const execute = () => saveGraphInternal(this, entityClass, payload, graphOptions);
@@ -9718,6 +9869,17 @@ var Orm = class {
9718
9869
  }
9719
9870
  };
9720
9871
 
9872
+ // src/orm/jsonify.ts
9873
+ var jsonify = (value) => {
9874
+ const record = value;
9875
+ const result = {};
9876
+ for (const key of Object.keys(record)) {
9877
+ const entry = record[key];
9878
+ result[key] = entry instanceof Date ? entry.toISOString() : entry;
9879
+ }
9880
+ return result;
9881
+ };
9882
+
9721
9883
  // src/decorators/decorator-metadata.ts
9722
9884
  var METADATA_KEY = "metal-orm:decorators";
9723
9885
  var isStandardDecoratorContext = (value) => {
@@ -10601,6 +10763,7 @@ export {
10601
10763
  isValueOperandInput,
10602
10764
  isWindowFunctionNode,
10603
10765
  jsonPath,
10766
+ jsonify,
10604
10767
  lag,
10605
10768
  lastValue,
10606
10769
  lead,