arkormx 2.11.12 → 2.12.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,10 +1,12 @@
1
- import { $ as registerSeeders, $n as supportsDatabaseMigrationState, $t as resolveEnumName, A as getRuntimePaginationCurrentPageResolver, An as min, At as buildFieldLine, B as getRegisteredFactories, Bn as createEmptyAppliedMigrationsState, Bt as deriveInverseRelationAlias, C as ensureArkormConfigLoading, Cn as col, Ct as applyDropTableOperation, D as getRuntimeAdapter, Dn as fromExpressionNode, Dt as applyMigrationToPrismaSchema, E as getDefaultStubsPath, En as fn, Et as applyMigrationToDatabase, F as isQuerySchemaLike, Fn as PrimaryKeyGenerationPlanner, Ft as buildPrimaryKeyLine, G as loadFactoriesFrom, Gn as getLatestAppliedMigrations, Gt as findEnumBlock, H as getRegisteredModels, Hn as findAppliedMigration, Ht as deriveRelationFieldName, I as isTransactionCapableClient, In as ForeignKeyBuilder, It as buildRelationLine, J as loadSeedersFrom, Jn as markMigrationRun, Jt as formatEnumDefaultValue, K as loadMigrationsFrom, Kn as isMigrationApplied, Kt as findModelBlock, L as loadArkormConfig, Ln as buildMigrationIdentity, Lt as buildUniqueConstraintLine, M as getRuntimePrismaClient, Mn as sum, Mt as buildInverseRelationLine, N as getUserConfig, Nn as val, Nt as buildMigrationSource, O as getRuntimeClient, On as json, Ot as applyOperationsToPrismaSchema, P as isDelegateLike, Pn as where, Pt as buildModelBlock, Q as registerPaths, Qn as resolveMigrationStateFilePath, Qt as pad, R as resetArkormRuntimeForTests, Rn as buildMigrationRunId, Rt as createMigrationTimestamp, S as emitRuntimeDebugEvent, Sn as coalesce, St as applyCreateTableOperation, T as getActiveTransactionClient, Tn as expressionBuilder, Tt as applyMigrationRollbackToPrismaSchema, U as getRegisteredPaths, Un as getLastBatchMigrations, Ut as deriveSingularFieldName, V as getRegisteredMigrations, Vn as deleteAppliedMigrationsStateFromStore, Vt as deriveRelationAlias, W as getRegisteredSeeders, Wn as getLastMigrationRun, Wt as escapeRegex, X as registerMigrations, Xn as readAppliedMigrationsStateFromStore, Xt as generateMigrationFile, Y as registerFactories, Yn as readAppliedMigrationsState, Yt as formatRelationAction, Z as registerModels, Zn as removeAppliedMigration, Zt as getMigrationPlan, _ as awaitConfiguredModelsRegistration, _n as CaseExpression, _t as writePersistedColumnMappingsState, a as MorphedByManyRelation, an as supportsDatabaseCreation, at as getPersistedEnumMap, b as defineConfig, bn as avg, bt as PRISMA_MODEL_REGEX, c as HasManyThroughRelation, cn as toMigrationFileSlug, cr as ArkormException, ct as getPersistedTableMetadata, dn as runInMigrationPlanning, dt as rebuildPersistedColumnMappingsState, en as resolveMigrationClassName, er as writeAppliedMigrationsState, et as resetRuntimeRegistryForTests, f as BelongsToManyRelation, fn as SchemaBuilder, ft as resetPersistedColumnMappingsCache, g as URLDriver, gn as AggregateExpression, gt as validatePersistedMetadataFeaturesForMigrations, h as Paginator, hn as resolveGeneratedExpression, ht as syncPersistedColumnMappingsFromState, i as MorphManyRelation, in as stripPrismaSchemaModelsAndEnums, ir as SetBasedEagerLoader, it as getPersistedColumnMap, j as getRuntimePaginationURLDriverFactory, jn as raw, jt as buildIndexLine, k as getRuntimeDebugHandler, kn as max, kt as buildEnumBlock, l as HasManyRelation, ln as toModelName, lt as getPersistedTimestampColumns, m as LengthAwarePaginator, mn as TableBuilder, mt as resolvePersistedMetadataFeatures, n as MorphToManyRelation, nn as runMigrationWithPrisma, nr as RuntimeModuleLoader, nt as createEmptyPersistedColumnMappingsState, o as HasOneThroughRelation, on as supportsDatabaseMigrationExecution, or as RelationResolutionException, ot as getPersistedEnumTsType, p as Relation, pn as EnumBuilder, pt as resolveColumnMappingsFilePath, q as loadModelsFrom, qn as markMigrationApplied, qt as formatDefaultValue, r as MorphOneRelation, rn as runPrismaCommand, rr as UnsupportedAdapterFeatureException, rt as deletePersistedColumnMappingsState, s as HasOneRelation, sn as supportsDatabaseReset, sr as ArkormCollection, st as getPersistedPrimaryKeyGeneration, t as MorphToRelation, tn as resolvePrismaType, tr as writeAppliedMigrationsStateToStore, tt as applyOperationsToPersistedColumnMappingsState, u as BelongsToRelation, un as isMigrationPlanningActive, ut as readPersistedColumnMappingsState, v as bindAdapterToModels, vn as Expression, vt as PRISMA_ENUM_MEMBER_REGEX, w as getActiveTransactionAdapter, wn as count, wt as applyMigrationRollbackToDatabase, x as disposeArkormRuntime, xn as caseWhen, xt as applyAlterTableOperation, y as configureArkormRuntime, yn as JsonExpression, yt as PRISMA_ENUM_REGEX, z as runArkormTransaction, zn as computeMigrationChecksum, zt as deriveCollectionFieldName } from "./relationship-BqPWUfxk.mjs";
1
+ import { $ as buildPrimaryKeyLine, $n as markMigrationRun, $t as awaitConfiguredModelsRegistration, A as resetPersistedColumnMappingsCache, An as loadSeedersFrom, At as SchemaBuilder, B as applyCreateTableOperation, Bn as PrimaryKeyGenerationPlanner, Bt as coalesce, C as getPersistedEnumMap, Cn as getRegisteredMigrations, Ct as supportsDatabaseCreation, D as getPersistedTimestampColumns, Dn as loadFactoriesFrom, Dt as toModelName, E as getPersistedTableMetadata, En as getRegisteredSeeders, Et as toMigrationFileSlug, F as writePersistedColumnMappingsState, Fn as registerSeeders, Ft as CaseExpression, G as applyMigrationToPrismaSchema, Gn as createEmptyAppliedMigrationsState, Gt as fromExpressionNode, H as applyMigrationRollbackToDatabase, Hn as buildMigrationIdentity, Ht as count, I as PRISMA_ENUM_MEMBER_REGEX, In as resetRuntimeRegistryForTests, It as Expression, J as buildFieldLine, Jn as getLastBatchMigrations, Jt as min, K as applyOperationsToPrismaSchema, Kn as deleteAppliedMigrationsStateFromStore, Kt as json, L as PRISMA_ENUM_REGEX, Ln as resolveRegisteredModel, Lt as JsonExpression, M as resolvePersistedMetadataFeatures, Mn as registerMigrations, Mt as TableBuilder, N as syncPersistedColumnMappingsFromState, Nn as registerModels, Nt as resolveGeneratedExpression, O as readPersistedColumnMappingsState, On as loadMigrationsFrom, Ot as isMigrationPlanningActive, P as validatePersistedMetadataFeaturesForMigrations, Pn as registerPaths, Pt as AggregateExpression, Q as buildModelBlock, Qn as markMigrationApplied, Qt as where, R as PRISMA_MODEL_REGEX, Rn as UnsupportedAdapterFeatureException, Rt as avg, S as getPersistedColumnMap, Sn as getRegisteredFactories, St as stripPrismaSchemaModelsAndEnums, T as getPersistedPrimaryKeyGeneration, Tn as getRegisteredPaths, Tt as supportsDatabaseReset, U as applyMigrationRollbackToPrismaSchema, Un as buildMigrationRunId, Ut as expressionBuilder, V as applyDropTableOperation, Vn as ForeignKeyBuilder, Vt as col, W as applyMigrationToDatabase, Wn as computeMigrationChecksum, Wt as fn, X as buildInverseRelationLine, Xn as getLatestAppliedMigrations, Xt as sum, Y as buildIndexLine, Yn as getLastMigrationRun, Yt as raw, Z as buildMigrationSource, Zn as isMigrationApplied, Zt as val, _ as SetBasedEagerLoader, _n as isQuerySchemaLike, _t as resolveEnumName, a as MorphedByManyRelation, an as ensureArkormConfigLoading, ar as writeAppliedMigrationsState, at as deriveRelationAlias, b as createEmptyPersistedColumnMappingsState, bn as resetArkormRuntimeForTests, bt as runMigrationWithPrisma, c as HasManyThroughRelation, cn as getDefaultStubsPath, cr as ArkormCollection, ct as escapeRegex, dn as getRuntimeDebugHandler, dt as formatDefaultValue, en as bindAdapterToModels, er as readAppliedMigrationsState, et as buildRelationLine, f as BelongsToManyRelation, fn as getRuntimePaginationCurrentPageResolver, ft as formatEnumDefaultValue, g as URLDriver, gn as isDelegateLike, gt as pad, h as Paginator, hn as getUserConfig, ht as getMigrationPlan, i as MorphManyRelation, in as emitRuntimeDebugEvent, ir as supportsDatabaseMigrationState, it as deriveInverseRelationAlias, j as resolveColumnMappingsFilePath, jn as registerFactories, jt as EnumBuilder, k as rebuildPersistedColumnMappingsState, kn as loadModelsFrom, kt as runInMigrationPlanning, l as HasManyRelation, ln as getRuntimeAdapter, lr as ArkormException, lt as findEnumBlock, m as LengthAwarePaginator, mn as getRuntimePrismaClient, mt as generateMigrationFile, n as MorphToManyRelation, nn as defineConfig, nr as removeAppliedMigration, nt as createMigrationTimestamp, o as HasOneThroughRelation, on as getActiveTransactionAdapter, or as writeAppliedMigrationsStateToStore, ot as deriveRelationFieldName, p as Relation, pn as getRuntimePaginationURLDriverFactory, pt as formatRelationAction, q as buildEnumBlock, qn as findAppliedMigration, qt as max, r as MorphOneRelation, rn as disposeArkormRuntime, rr as resolveMigrationStateFilePath, rt as deriveCollectionFieldName, s as HasOneRelation, sn as getActiveTransactionClient, sr as RelationResolutionException, st as deriveSingularFieldName, t as MorphToRelation, tn as configureArkormRuntime, tr as readAppliedMigrationsStateFromStore, tt as buildUniqueConstraintLine, u as BelongsToRelation, un as getRuntimeClient, ut as findModelBlock, vn as isTransactionCapableClient, vt as resolveMigrationClassName, w as getPersistedEnumTsType, wn as getRegisteredModels, wt as supportsDatabaseMigrationExecution, x as deletePersistedColumnMappingsState, xn as runArkormTransaction, xt as runPrismaCommand, y as applyOperationsToPersistedColumnMappingsState, yn as loadArkormConfig, yt as resolvePrismaType, z as applyAlterTableOperation, zn as RuntimeModuleLoader, zt as caseWhen } from "./relationship-2jzLUHCB.mjs";
2
2
  import { Pool } from "pg";
3
- import { join, resolve } from "node:path";
3
+ import { extname, isAbsolute, join, relative, resolve } from "node:path";
4
+ import { existsSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
5
+ import { createJiti } from "jiti";
6
+ import { pathToFileURL } from "node:url";
4
7
  import { createRequire } from "module";
5
- import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs";
6
- import { dirname as dirname$1, extname as extname$1, join as join$1, relative } from "path";
7
- import { existsSync as existsSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, rmSync as rmSync$1, writeFileSync as writeFileSync$1 } from "node:fs";
8
+ import { copyFileSync, existsSync as existsSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, realpathSync, rmSync as rmSync$1, writeFileSync as writeFileSync$1 } from "fs";
9
+ import { dirname as dirname$1, extname as extname$1, join as join$1, relative as relative$1 } from "path";
8
10
  import { DateTime, str } from "@h3ravel/support";
9
11
  import { AsyncLocalStorage } from "node:async_hooks";
10
12
  import { sql } from "kysely";
@@ -634,6 +636,15 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
634
636
  mapColumn(target, column) {
635
637
  return target.columns?.[column] ?? column;
636
638
  }
639
+ buildIdentifierReference(target, reference) {
640
+ const segments = reference.split(".");
641
+ if (segments.length === 1) return sql.ref(this.mapColumn(target, reference));
642
+ const column = segments.pop();
643
+ const table = segments.join(".");
644
+ const mappedTable = this.mapping[table] ?? table;
645
+ const mappedColumn = mappedTable === (target.table ? this.mapping[target.table] ?? target.table : void 0) ? this.mapColumn(target, column) : column;
646
+ return this.buildColumnReference(mappedTable, mappedColumn);
647
+ }
637
648
  reverseColumnMap(target) {
638
649
  return Object.entries(target.columns ?? {}).reduce((all, [attribute, column]) => {
639
650
  all[column] = attribute;
@@ -657,29 +668,31 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
657
668
  return mapped;
658
669
  }, {});
659
670
  }
660
- buildSelectList(target, columns) {
661
- if (!columns || columns.length === 0) return sql.raw("*");
671
+ buildSelectList(target, columns, qualifyColumns = false) {
672
+ const table = this.resolveTable(target);
673
+ if (!columns || columns.length === 0) return qualifyColumns ? sql`${sql.table(table)}.*` : sql.raw("*");
662
674
  return sql.join(columns.map(({ column, alias, raw, wildcard, expression }) => {
663
- if (wildcard) return sql.raw("*");
675
+ if (wildcard) return qualifyColumns ? sql`${sql.table(table)}.*` : sql.raw("*");
664
676
  if (expression) {
665
677
  const compiled = this.buildExpression(target, expression);
666
678
  const resultAlias = alias ?? column;
667
679
  return resultAlias ? sql`${compiled} as ${sql.id(resultAlias)}` : compiled;
668
680
  }
669
681
  if (raw) {
670
- const rawExpression = sql.raw(column);
682
+ const rawExpression = /^[A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)+$/.test(column) ? this.buildIdentifierReference(target, column) : sql.raw(column);
671
683
  return alias ? sql`${rawExpression} as ${sql.id(alias)}` : rawExpression;
672
684
  }
673
685
  const mappedColumn = this.mapColumn(target, column);
674
686
  const resultAlias = alias ?? column;
675
- if (mappedColumn === resultAlias) return sql.ref(mappedColumn);
676
- return sql`${sql.ref(mappedColumn)} as ${sql.id(resultAlias)}`;
687
+ const reference = qualifyColumns ? this.buildColumnReference(table, mappedColumn) : sql.ref(mappedColumn);
688
+ if (mappedColumn === resultAlias) return reference;
689
+ return sql`${reference} as ${sql.id(resultAlias)}`;
677
690
  }));
678
691
  }
679
- buildOrderBy(target, orderBy) {
692
+ buildOrderBy(target, orderBy, qualifyColumns = false) {
680
693
  if (!orderBy || orderBy.length === 0) return sql``;
681
694
  return sql` order by ${sql.join(orderBy.map(({ column, direction, expression }) => {
682
- return sql`${expression ? this.buildExpression(target, expression) : sql.ref(this.mapColumn(target, column))} ${sql.raw(direction === "desc" ? "desc" : "asc")}`;
695
+ return sql`${expression ? this.buildExpression(target, expression) : qualifyColumns ? this.buildColumnReference(this.resolveTable(target), this.mapColumn(target, column)) : sql.ref(this.mapColumn(target, column))} ${sql.raw(direction === "desc" ? "desc" : "asc")}`;
683
696
  }), sql`, `)}`;
684
697
  }
685
698
  buildGroupBy(target, groupBy) {
@@ -734,7 +747,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
734
747
  return sql`${sql.join(parts, sql``)}`;
735
748
  }
736
749
  buildJoinConstraint(target, constraint) {
737
- if (constraint.type === "column") return sql`${sql.ref(constraint.first)} ${sql.raw(constraint.operator)} ${sql.ref(constraint.second)}`;
750
+ if (constraint.type === "column") return sql`${this.buildIdentifierReference(target, constraint.first)} ${sql.raw(constraint.operator)} ${this.buildIdentifierReference(target, constraint.second)}`;
738
751
  if (constraint.type === "null") return constraint.not ? sql`${sql.ref(constraint.column)} is not null` : sql`${sql.ref(constraint.column)} is null`;
739
752
  if (constraint.type === "raw") return this.buildRawWhereCondition({
740
753
  type: "raw",
@@ -742,7 +755,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
742
755
  bindings: constraint.bindings
743
756
  });
744
757
  if (constraint.type === "nested") return sql`(${this.buildJoinConstraints(target, constraint.constraints)})`;
745
- const column = sql.ref(constraint.column);
758
+ const column = this.buildIdentifierReference(target, constraint.column);
746
759
  const operator = constraint.operator;
747
760
  if (operator === "is-null") return sql`${column} is null`;
748
761
  if (operator === "is-not-null") return sql`${column} is not null`;
@@ -764,7 +777,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
764
777
  return typeof value === "undefined" ? [] : [value];
765
778
  }
766
779
  buildComparisonCondition(target, condition) {
767
- const column = sql.ref(this.mapColumn(target, condition.column));
780
+ const column = this.buildIdentifierReference(target, condition.column);
768
781
  if (condition.operator === "is-null") return sql`${column} is null`;
769
782
  if (condition.operator === "is-not-null") return sql`${column} is not null`;
770
783
  if (condition.operator === "in") {
@@ -1197,6 +1210,30 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
1197
1210
  ${this.buildOrderBy(spec.target, spec.orderBy)}
1198
1211
  ${this.buildPaginationClause(spec)}
1199
1212
  `;
1213
+ }
1214
+ buildPartitionedSelectStatement(spec) {
1215
+ const table = this.resolveTable(spec.target);
1216
+ const rankedAlias = "__arkorm_partitioned";
1217
+ const rowAlias = "__arkorm_partition_row";
1218
+ const offset = Math.max(0, spec.perPartitionOffset ?? 0);
1219
+ const upperBound = offset + Math.max(0, spec.perPartitionLimit);
1220
+ const partitionColumns = spec.partitionBy.map((column) => this.buildIdentifierReference(spec.target, column));
1221
+ const orderBy = spec.orderBy && spec.orderBy.length > 0 ? this.buildOrderBy(spec.target, spec.orderBy, true) : sql` order by ${this.buildColumnReference(table, this.resolvePrimaryKey(spec.target))} asc`;
1222
+ return sql`
1223
+ select *
1224
+ from (
1225
+ select ${spec.distinct ? sql`distinct ` : sql``}${this.buildSelectList(spec.target, spec.columns, true)}
1226
+ ${this.buildRelationAggregateSelectList(spec.target, spec.relationAggregates)},
1227
+ row_number() over (
1228
+ partition by ${sql.join(partitionColumns, sql`, `)}${orderBy}
1229
+ ) as ${sql.id(rowAlias)}
1230
+ from ${sql.table(table)}
1231
+ ${this.buildJoinClause(spec.target, spec.joins)}
1232
+ ${this.buildCombinedWhereClause(spec.target, spec.where, spec.relationFilters)}
1233
+ ) as ${sql.table(rankedAlias)}
1234
+ where ${sql.ref(rowAlias)} > ${offset} and ${sql.ref(rowAlias)} <= ${upperBound}
1235
+ order by ${sql.ref(rowAlias)} asc
1236
+ `;
1200
1237
  }
1201
1238
  buildCountStatement(spec) {
1202
1239
  return sql`
@@ -1298,6 +1335,20 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
1298
1335
  offset: spec.offset
1299
1336
  });
1300
1337
  }
1338
+ async selectPerPartition(spec) {
1339
+ if (spec.partitionBy.length === 0) return await this.select(spec);
1340
+ return await this.executeWithDebug("select", spec.target, this.buildPartitionedSelectStatement(spec), (rows) => this.mapRows(spec.target, rows.map((row) => {
1341
+ const { __arkorm_partition_row: _partitionRow, ...attributes } = row;
1342
+ return attributes;
1343
+ })), {
1344
+ where: spec.where,
1345
+ relationFilters: spec.relationFilters,
1346
+ orderBy: spec.orderBy,
1347
+ partitionBy: spec.partitionBy,
1348
+ perPartitionLimit: spec.perPartitionLimit,
1349
+ perPartitionOffset: spec.perPartitionOffset
1350
+ });
1351
+ }
1301
1352
  /**
1302
1353
  * Selects a single record from the database matching the specified criteria and returns it as
1303
1354
  * a database row. If multiple records match the criteria, only the first one is returned.
@@ -2330,6 +2381,92 @@ const createPrismaDatabaseAdapter = (prisma, mapping = {}) => {
2330
2381
  */
2331
2382
  const createPrismaCompatibilityAdapter = createPrismaDatabaseAdapter;
2332
2383
 
2384
+ //#endregion
2385
+ //#region src/helpers/model-resolver.ts
2386
+ const modelExtensions = [
2387
+ ".ts",
2388
+ ".tsx",
2389
+ ".mts",
2390
+ ".cts",
2391
+ ".js",
2392
+ ".mjs",
2393
+ ".cjs"
2394
+ ];
2395
+ const isModelModule = (value) => typeof value === "object" && value !== null;
2396
+ const isModelConstructor = (value) => {
2397
+ if (typeof value !== "function") return false;
2398
+ const candidate = value;
2399
+ return typeof candidate.query === "function" && typeof candidate.hydrate === "function" && typeof candidate.getTable === "function" && typeof candidate.getPrimaryKey === "function";
2400
+ };
2401
+ const resolveModelExport = (module, modelName) => {
2402
+ if (!isModelModule(module)) return module;
2403
+ return module.default ?? module[modelName] ?? module;
2404
+ };
2405
+ const resolveRuntimeDirectory = (directory) => {
2406
+ if (existsSync(directory)) return directory;
2407
+ const buildOutput = getUserConfig("paths")?.buildOutput;
2408
+ if (typeof buildOutput !== "string" || buildOutput.trim().length === 0) return directory;
2409
+ const relativeSource = relative(process.cwd(), directory);
2410
+ if (!relativeSource || relativeSource.startsWith("..")) return directory;
2411
+ const mappedDirectory = join(buildOutput, relativeSource);
2412
+ return existsSync(mappedDirectory) ? mappedDirectory : directory;
2413
+ };
2414
+ const resolveRuntimeModelPath = (sourcePath) => {
2415
+ const extension = extname(sourcePath).toLowerCase();
2416
+ const candidates = [];
2417
+ if (modelExtensions.includes(extension)) candidates.push(sourcePath);
2418
+ else candidates.push(...modelExtensions.map((modelExtension) => `${sourcePath}${modelExtension}`));
2419
+ const buildOutput = getUserConfig("paths")?.buildOutput;
2420
+ if (typeof buildOutput === "string" && buildOutput.trim().length > 0) candidates.slice().forEach((candidate) => {
2421
+ const relativeSource = relative(process.cwd(), candidate);
2422
+ if (!relativeSource || relativeSource.startsWith("..")) return;
2423
+ const mappedFile = join(buildOutput, relativeSource);
2424
+ const mappedExtension = extname(mappedFile).toLowerCase();
2425
+ if ([
2426
+ ".ts",
2427
+ ".tsx",
2428
+ ".mts",
2429
+ ".cts"
2430
+ ].includes(mappedExtension)) {
2431
+ const base = mappedFile.slice(0, -mappedExtension.length);
2432
+ candidates.push(`${base}.js`, `${base}.mjs`, `${base}.cjs`);
2433
+ return;
2434
+ }
2435
+ candidates.push(mappedFile);
2436
+ });
2437
+ return candidates.find((candidate) => existsSync(candidate)) ?? sourcePath;
2438
+ };
2439
+ const getModelDirectories = () => {
2440
+ const configured = getUserConfig("paths")?.models;
2441
+ const registered = getRegisteredPaths("models");
2442
+ return [...typeof configured === "string" ? [configured] : [], ...registered].map((directory) => resolveRuntimeDirectory(isAbsolute(directory) ? directory : resolve(directory))).filter((directory, index, all) => all.indexOf(directory) === index);
2443
+ };
2444
+ const loadModel = (modelName, exportName) => {
2445
+ const jiti = createJiti(`${pathToFileURL(resolve(".")).href}/`, {
2446
+ interopDefault: false,
2447
+ tsconfigPaths: true,
2448
+ sourceMaps: true
2449
+ });
2450
+ for (const directory of getModelDirectories()) {
2451
+ const modulePath = resolveRuntimeModelPath(join(directory, modelName));
2452
+ if (!existsSync(modulePath)) continue;
2453
+ const model = resolveModelExport(jiti(modulePath), exportName);
2454
+ if (!isModelConstructor(model)) continue;
2455
+ registerModels(model);
2456
+ return model;
2457
+ }
2458
+ };
2459
+ function getModel(modelName) {
2460
+ const normalized = modelName.trim();
2461
+ const exportName = normalized.replace(/\\/g, "/").split("/").pop()?.replace(/\.[^.]+$/, "");
2462
+ if (!normalized || !exportName) throw new Error("Model name is required.");
2463
+ const registeredModel = getRegisteredModels().find((model) => model.name === exportName);
2464
+ if (registeredModel) return registeredModel;
2465
+ const model = loadModel(normalized, exportName);
2466
+ if (model) return model;
2467
+ throw new Error(`Model "${modelName}" not found.`);
2468
+ }
2469
+
2333
2470
  //#endregion
2334
2471
  //#region src/Arkorm.ts
2335
2472
  var Arkorm = class Arkorm {
@@ -2349,6 +2486,7 @@ var Arkorm = class Arkorm {
2349
2486
  this.getRegisteredMigrations = Arkorm.getRegisteredMigrations;
2350
2487
  this.getRegisteredSeeders = Arkorm.getRegisteredSeeders;
2351
2488
  this.getRegisteredModels = Arkorm.getRegisteredModels;
2489
+ this.getModel = Arkorm.getModel;
2352
2490
  this.getRegisteredFactories = Arkorm.getRegisteredFactories;
2353
2491
  }
2354
2492
  /**
@@ -2476,6 +2614,9 @@ var Arkorm = class Arkorm {
2476
2614
  static getRegisteredModels() {
2477
2615
  return getRegisteredModels();
2478
2616
  }
2617
+ static {
2618
+ this.getModel = getModel;
2619
+ }
2479
2620
  /**
2480
2621
  * Get registered factory constructors or instances.
2481
2622
  *
@@ -2603,7 +2744,7 @@ var CliApp = class {
2603
2744
  */
2604
2745
  ensureDirectory(filePath) {
2605
2746
  const dir = dirname$1(filePath);
2606
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
2747
+ if (!existsSync$1(dir)) mkdirSync$1(dir, { recursive: true });
2607
2748
  }
2608
2749
  /**
2609
2750
  * Convert absolute paths under current working directory into relative display paths.
@@ -2612,7 +2753,7 @@ var CliApp = class {
2612
2753
  * @returns
2613
2754
  */
2614
2755
  formatPathForLog(filePath) {
2615
- const relPath = relative(process.cwd(), filePath);
2756
+ const relPath = relative$1(process.cwd(), filePath);
2616
2757
  if (!relPath) return ".";
2617
2758
  if (relPath.startsWith("..")) return filePath;
2618
2759
  return relPath;
@@ -2652,13 +2793,13 @@ var CliApp = class {
2652
2793
  * @returns
2653
2794
  */
2654
2795
  resolveRuntimeDirectoryPath(directoryPath) {
2655
- if (existsSync(directoryPath)) return directoryPath;
2796
+ if (existsSync$1(directoryPath)) return directoryPath;
2656
2797
  const { buildOutput } = this.getConfig("paths") || {};
2657
2798
  if (typeof buildOutput !== "string" || buildOutput.trim().length === 0) return directoryPath;
2658
- const relativeSource = relative(process.cwd(), directoryPath);
2799
+ const relativeSource = relative$1(process.cwd(), directoryPath);
2659
2800
  if (!relativeSource || relativeSource.startsWith("..")) return directoryPath;
2660
2801
  const mappedDirectory = join$1(buildOutput, relativeSource);
2661
- return existsSync(mappedDirectory) ? mappedDirectory : directoryPath;
2802
+ return existsSync$1(mappedDirectory) ? mappedDirectory : directoryPath;
2662
2803
  }
2663
2804
  /**
2664
2805
  * Resolve a script file path for runtime execution.
@@ -2678,7 +2819,7 @@ var CliApp = class {
2678
2819
  }
2679
2820
  const { buildOutput } = this.getConfig("paths") ?? {};
2680
2821
  if (typeof buildOutput === "string" && buildOutput.trim().length > 0) {
2681
- const relativeSource = relative(process.cwd(), filePath);
2822
+ const relativeSource = relative$1(process.cwd(), filePath);
2682
2823
  if (relativeSource && !relativeSource.startsWith("..")) {
2683
2824
  const mappedFile = join$1(buildOutput, relativeSource);
2684
2825
  const mappedExtension = extname$1(mappedFile).toLowerCase();
@@ -2688,7 +2829,7 @@ var CliApp = class {
2688
2829
  } else candidates.push(mappedFile);
2689
2830
  }
2690
2831
  }
2691
- const runtimeMatch = candidates.find((path) => existsSync(path));
2832
+ const runtimeMatch = candidates.find((path) => existsSync$1(path));
2692
2833
  if (runtimeMatch) return runtimeMatch;
2693
2834
  return filePath;
2694
2835
  }
@@ -2700,14 +2841,14 @@ var CliApp = class {
2700
2841
  * @param replacements
2701
2842
  */
2702
2843
  generateFile(stubPath, outputPath, replacements, options) {
2703
- if (existsSync(outputPath) && !options?.force) {
2844
+ if (existsSync$1(outputPath) && !options?.force) {
2704
2845
  this.command.error(`Error: ${this.formatPathForLog(outputPath)} already exists.`);
2705
2846
  process.exit(1);
2706
- } else if (existsSync(outputPath) && options?.force) rmSync(outputPath);
2707
- let content = readFileSync(stubPath, "utf-8");
2847
+ } else if (existsSync$1(outputPath) && options?.force) rmSync$1(outputPath);
2848
+ let content = readFileSync$1(stubPath, "utf-8");
2708
2849
  for (const [key, value] of Object.entries(replacements)) content = content.replace(new RegExp(`{{${key}}}`, "g"), value);
2709
2850
  this.ensureDirectory(outputPath);
2710
- writeFileSync(outputPath, content);
2851
+ writeFileSync$1(outputPath, content);
2711
2852
  return outputPath;
2712
2853
  }
2713
2854
  /**
@@ -2745,7 +2886,7 @@ var CliApp = class {
2745
2886
  const outputExt = this.resolveOutputExt();
2746
2887
  const outputPath = join$1(this.resolveConfigPath("factories", join$1(process.cwd(), "database", "factories")), `${factoryName}.${outputExt}`);
2747
2888
  const modelPath = join$1(this.resolveConfigPath("models", join$1(process.cwd(), "src", "models")), `${modelName}.${outputExt}`);
2748
- const relativeImport = options.modelImportPath ?? `./${this.stripKnownSourceExtension(relative(dirname$1(outputPath), modelPath).replace(/\\/g, "/"))}${outputExt === "js" ? ".js" : ""}`;
2889
+ const relativeImport = options.modelImportPath ?? `./${this.stripKnownSourceExtension(relative$1(dirname$1(outputPath), modelPath).replace(/\\/g, "/"))}${outputExt === "js" ? ".js" : ""}`;
2749
2890
  const stubPath = this.resolveStubPath(outputExt === "js" ? "factory.js.stub" : "factory.stub");
2750
2891
  return {
2751
2892
  name: factoryName,
@@ -2807,7 +2948,7 @@ var CliApp = class {
2807
2948
  const shouldBuildMigration = options.all || options.migration;
2808
2949
  const factoryName = `${baseName}Factory`;
2809
2950
  const factoryPath = join$1(this.resolveConfigPath("factories", join$1(process.cwd(), "database", "factories")), `${factoryName}.${outputExt}`);
2810
- const factoryImportPath = `./${relative(dirname$1(outputPath), factoryPath).replace(/\\/g, "/").replace(/\.(ts|tsx|mts|cts|js|mjs|cjs)$/i, "")}${outputExt === "js" ? ".js" : ""}`;
2951
+ const factoryImportPath = `./${relative$1(dirname$1(outputPath), factoryPath).replace(/\\/g, "/").replace(/\.(ts|tsx|mts|cts|js|mjs|cjs)$/i, "")}${outputExt === "js" ? ".js" : ""}`;
2811
2952
  let stubPath;
2812
2953
  if (options.pivot) stubPath = this.resolveStubPath("pivot-model.stub");
2813
2954
  else stubPath = this.resolveStubPath(outputExt === "js" ? "model.js.stub" : "model.stub");
@@ -2831,7 +2972,7 @@ var CliApp = class {
2831
2972
  if (shouldBuildFactory) created.factory = this.makeFactory(baseName, {
2832
2973
  force: options.force,
2833
2974
  modelName,
2834
- modelImportPath: `./${relative(dirname$1(factoryPath), outputPath).replace(/\\/g, "/").replace(/\.(ts|tsx|mts|cts|js|mjs|cjs)$/i, "")}${outputExt === "js" ? ".js" : ""}`
2975
+ modelImportPath: `./${relative$1(dirname$1(factoryPath), outputPath).replace(/\\/g, "/").replace(/\.(ts|tsx|mts|cts|js|mjs|cjs)$/i, "")}${outputExt === "js" ? ".js" : ""}`
2835
2976
  });
2836
2977
  if (shouldBuildSeeder) created.seeder = this.makeSeeder(baseName, { force: options.force });
2837
2978
  if (shouldBuildMigration) created.migration = this.makeMigration(`create ${tableName} table`);
@@ -2847,15 +2988,15 @@ var CliApp = class {
2847
2988
  */
2848
2989
  ensurePrismaModelEntry(modelName, tableName) {
2849
2990
  const schemaPath = join$1(process.cwd(), "prisma", "schema.prisma");
2850
- if (!existsSync(schemaPath)) return void 0;
2851
- const source = readFileSync(schemaPath, "utf-8");
2991
+ if (!existsSync$1(schemaPath)) return void 0;
2992
+ const source = readFileSync$1(schemaPath, "utf-8");
2852
2993
  const existingByTable = findModelBlock(source, tableName);
2853
2994
  const existingByName = new RegExp(`model\\s+${modelName}\\s*\\{`, "m").test(source);
2854
2995
  if (existingByTable || existingByName) return {
2855
2996
  path: schemaPath,
2856
2997
  updated: false
2857
2998
  };
2858
- writeFileSync(schemaPath, applyCreateTableOperation(source, {
2999
+ writeFileSync$1(schemaPath, applyCreateTableOperation(source, {
2859
3000
  type: "createTable",
2860
3001
  table: tableName,
2861
3002
  columns: [{
@@ -3087,7 +3228,7 @@ var CliApp = class {
3087
3228
  const updated = [];
3088
3229
  const skipped = [];
3089
3230
  modelFiles.forEach((filePath) => {
3090
- const source = readFileSync(filePath, "utf-8");
3231
+ const source = readFileSync$1(filePath, "utf-8");
3091
3232
  const structure = resolveStructure(filePath, source);
3092
3233
  if (!structure || structure.fields.length === 0) {
3093
3234
  skipped.push(filePath);
@@ -3098,7 +3239,7 @@ var CliApp = class {
3098
3239
  skipped.push(filePath);
3099
3240
  return;
3100
3241
  }
3101
- writeFileSync(filePath, synced.content);
3242
+ writeFileSync$1(filePath, synced.content);
3102
3243
  updated.push(filePath);
3103
3244
  });
3104
3245
  return {
@@ -3106,6 +3247,58 @@ var CliApp = class {
3106
3247
  skipped
3107
3248
  };
3108
3249
  }
3250
+ resolveModelFiles(modelsDir) {
3251
+ if (!existsSync$1(modelsDir)) throw new Error(`Models directory not found: ${modelsDir}`);
3252
+ return readdirSync$1(modelsDir).filter((file) => file.endsWith(".ts")).map((file) => join$1(modelsDir, file));
3253
+ }
3254
+ syncModelRegistryTypes(modelFiles) {
3255
+ const registryDir = join$1(realpathSync(process.cwd()), ".arkormx");
3256
+ const registryPath = join$1(registryDir, "models.d.ts");
3257
+ const models = modelFiles.map((filePath) => {
3258
+ const parsed = this.parseModelSyncSource(readFileSync$1(filePath, "utf-8"));
3259
+ if (!parsed) return null;
3260
+ return {
3261
+ className: parsed.className,
3262
+ importPath: this.resolveModelRegistryImportPath(registryPath, filePath)
3263
+ };
3264
+ }).filter((model) => model !== null).sort((left, right) => left.className.localeCompare(right.className));
3265
+ const importLines = models.map((model) => {
3266
+ return `import type { ${model.className} } from '${model.importPath}'`;
3267
+ });
3268
+ const registryLines = models.map((model) => {
3269
+ return ` ${model.className}: typeof ${model.className}`;
3270
+ });
3271
+ const content = [
3272
+ "/* eslint-disable */",
3273
+ "// This file is generated by `arkorm models:sync`.",
3274
+ ...importLines,
3275
+ "",
3276
+ "declare module 'arkormx' {",
3277
+ " interface ArkormModelRegistry {",
3278
+ ...registryLines,
3279
+ " }",
3280
+ "}",
3281
+ "",
3282
+ "export {}",
3283
+ ""
3284
+ ].join("\n");
3285
+ if ((existsSync$1(registryPath) ? readFileSync$1(registryPath, "utf-8") : null) === content) return {
3286
+ path: registryPath,
3287
+ updated: false
3288
+ };
3289
+ mkdirSync$1(registryDir, { recursive: true });
3290
+ writeFileSync$1(registryPath, content);
3291
+ return {
3292
+ path: registryPath,
3293
+ updated: true
3294
+ };
3295
+ }
3296
+ resolveModelRegistryImportPath(registryPath, modelPath) {
3297
+ const realModelPath = realpathSync(modelPath);
3298
+ const withoutExtension = realModelPath.slice(0, -extname$1(realModelPath).length);
3299
+ const relativePath = relative$1(dirname$1(registryPath), withoutExtension).replace(/\\/g, "/");
3300
+ return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
3301
+ }
3109
3302
  applyPersistedFieldMetadata(structure) {
3110
3303
  const persistedMetadata = getPersistedTableMetadata(structure.table, {
3111
3304
  features: resolvePersistedMetadataFeatures(this.getConfig("features")),
@@ -3283,12 +3476,11 @@ var CliApp = class {
3283
3476
  }
3284
3477
  async syncModels(options = {}) {
3285
3478
  const modelsDir = options.modelsDir ?? this.resolveConfigPath("models", join$1(process.cwd(), "src", "models"));
3286
- if (!existsSync(modelsDir)) throw new Error(`Models directory not found: ${modelsDir}`);
3287
- const modelFiles = readdirSync(modelsDir).filter((file) => file.endsWith(".ts")).map((file) => join$1(modelsDir, file));
3479
+ const modelFiles = this.resolveModelFiles(modelsDir);
3288
3480
  const adapter = this.getConfig("adapter");
3289
3481
  if (adapter && typeof adapter.introspectModels === "function") {
3290
3482
  const sources = modelFiles.reduce((all, filePath) => {
3291
- const parsed = this.parseModelSyncSource(readFileSync(filePath, "utf-8"));
3483
+ const parsed = this.parseModelSyncSource(readFileSync$1(filePath, "utf-8"));
3292
3484
  if (parsed) all.set(filePath, parsed);
3293
3485
  return all;
3294
3486
  }, /* @__PURE__ */ new Map());
@@ -3301,11 +3493,13 @@ var CliApp = class {
3301
3493
  const parsed = sources.get(filePath);
3302
3494
  return parsed ? structuresByTable.get(parsed.table) : void 0;
3303
3495
  }, /* @__PURE__ */ new Map());
3496
+ const modelTypes = this.syncModelRegistryTypes(modelFiles);
3304
3497
  return {
3305
3498
  source: "adapter",
3306
3499
  modelsDir,
3500
+ modelTypesPath: modelTypes.path,
3307
3501
  total: modelFiles.length,
3308
- updated: result.updated,
3502
+ updated: modelTypes.updated ? [...result.updated, modelTypes.path] : result.updated,
3309
3503
  skipped: result.skipped
3310
3504
  };
3311
3505
  }
@@ -3314,6 +3508,19 @@ var CliApp = class {
3314
3508
  ...this.syncModelsFromPrisma(options)
3315
3509
  };
3316
3510
  }
3511
+ syncModelRegistry(options = {}) {
3512
+ const modelsDir = options.modelsDir ?? this.resolveConfigPath("models", join$1(process.cwd(), "src", "models"));
3513
+ const modelFiles = this.resolveModelFiles(modelsDir);
3514
+ const modelTypes = this.syncModelRegistryTypes(modelFiles);
3515
+ return {
3516
+ source: "registry",
3517
+ modelsDir,
3518
+ modelTypesPath: modelTypes.path,
3519
+ total: modelFiles.length,
3520
+ updated: modelTypes.updated ? [modelTypes.path] : [],
3521
+ skipped: []
3522
+ };
3523
+ }
3317
3524
  /**
3318
3525
  * Sync model attribute declarations in model files based on the Prisma schema.
3319
3526
  * This method reads the Prisma schema to extract model definitions and their
@@ -3328,22 +3535,23 @@ var CliApp = class {
3328
3535
  syncModelsFromPrisma(options = {}) {
3329
3536
  const schemaPath = options.schemaPath ?? join$1(process.cwd(), "prisma", "schema.prisma");
3330
3537
  const modelsDir = options.modelsDir ?? this.resolveConfigPath("models", join$1(process.cwd(), "src", "models"));
3331
- if (!existsSync(schemaPath)) throw new Error(`Prisma schema file not found: ${schemaPath}`);
3332
- if (!existsSync(modelsDir)) throw new Error(`Models directory not found: ${modelsDir}`);
3333
- const schema = readFileSync(schemaPath, "utf-8");
3538
+ if (!existsSync$1(schemaPath)) throw new Error(`Prisma schema file not found: ${schemaPath}`);
3539
+ const schema = readFileSync$1(schemaPath, "utf-8");
3334
3540
  const prismaEnums = this.parsePrismaEnums(schema);
3335
3541
  const prismaModels = this.parsePrismaModels(schema);
3336
- const modelFiles = readdirSync(modelsDir).filter((file) => file.endsWith(".ts")).map((file) => join$1(modelsDir, file));
3542
+ const modelFiles = this.resolveModelFiles(modelsDir);
3337
3543
  const result = this.syncModelFiles(modelFiles, (filePath, source) => {
3338
3544
  const parsed = this.parseModelSyncSource(source);
3339
3545
  if (!parsed) return void 0;
3340
3546
  return prismaModels.find((model) => model.table === parsed.table) ?? prismaModels.find((model) => model.name === parsed.className);
3341
3547
  }, prismaEnums);
3548
+ const modelTypes = this.syncModelRegistryTypes(modelFiles);
3342
3549
  return {
3343
3550
  schemaPath,
3344
3551
  modelsDir,
3552
+ modelTypesPath: modelTypes.path,
3345
3553
  total: modelFiles.length,
3346
- updated: result.updated,
3554
+ updated: modelTypes.updated ? [...result.updated, modelTypes.path] : result.updated,
3347
3555
  skipped: result.skipped
3348
3556
  };
3349
3557
  }
@@ -3453,11 +3661,11 @@ var DbCommand = class extends Command {
3453
3661
  const filePath = this.option("file") ? String(this.option("file")) : void 0;
3454
3662
  if (filePath) {
3455
3663
  const resolved = resolve(filePath);
3456
- if (!existsSync$1(resolved)) {
3664
+ if (!existsSync(resolved)) {
3457
3665
  this.error(`Error: SQL file not found: ${this.app.formatPathForLog(resolved)}`);
3458
3666
  return null;
3459
3667
  }
3460
- return readFileSync$1(resolved, "utf-8");
3668
+ return readFileSync(resolved, "utf-8");
3461
3669
  }
3462
3670
  return await this.multiline("Query", "Enter the SQL to execute");
3463
3671
  }
@@ -3543,18 +3751,18 @@ var InitCommand = class extends Command {
3543
3751
  const stubsDir = typeof stubs === "string" && stubs.trim().length > 0 ? stubs : getDefaultStubsPath();
3544
3752
  const preferredStubPath = join(stubsDir, "arkormx.config.stub");
3545
3753
  const legacyStubPath = join(stubsDir, "arkorm.config.stub");
3546
- const stubPath = existsSync(preferredStubPath) ? preferredStubPath : legacyStubPath;
3547
- if (existsSync(outputDir) && !this.option("force")) {
3754
+ const stubPath = existsSync$1(preferredStubPath) ? preferredStubPath : legacyStubPath;
3755
+ if (existsSync$1(outputDir) && !this.option("force")) {
3548
3756
  this.error("Error: Arkormˣ has already been initialized. Use --force to reinitialize.");
3549
3757
  process.exit(1);
3550
3758
  }
3551
3759
  this.app.ensureDirectory(outputDir);
3552
- if (existsSync(outputDir) && this.option("force")) copyFileSync(outputDir, outputDir.replace(/\.js$/, `.backup.${Date.now()}.js`));
3553
- if (!existsSync(stubPath)) {
3760
+ if (existsSync$1(outputDir) && this.option("force")) copyFileSync(outputDir, outputDir.replace(/\.js$/, `.backup.${Date.now()}.js`));
3761
+ if (!existsSync$1(stubPath)) {
3554
3762
  this.error(`Error: Missing config stub at ${preferredStubPath} (or ${legacyStubPath})`);
3555
3763
  process.exit(1);
3556
3764
  }
3557
- writeFileSync(outputDir, readFileSync(stubPath, "utf-8"));
3765
+ writeFileSync$1(outputDir, readFileSync$1(stubPath, "utf-8"));
3558
3766
  this.success("Arkormˣ initialized successfully!");
3559
3767
  }
3560
3768
  };
@@ -3736,6 +3944,7 @@ var MigrateCommand = class extends Command {
3736
3944
  {--deploy : Use prisma migrate deploy instead of migrate dev (Prisma compatibility driver only)}
3737
3945
  {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
3738
3946
  {--skip-migrate : Skip prisma migrate command}
3947
+ {--r|registry : Sync the generated model registry type augmentation after a successful migration}
3739
3948
  {--state-file= : Path to applied migration state file}
3740
3949
  {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
3741
3950
  {--migration-name= : Name for prisma migrate dev (Prisma compatibility driver only)}
@@ -3792,6 +4001,7 @@ var MigrateCommand = class extends Command {
3792
4001
  this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
3793
4002
  return;
3794
4003
  }
4004
+ if (!this.syncModelRegistryIfRequested()) return;
3795
4005
  this.success("No pending migration classes to apply.");
3796
4006
  return;
3797
4007
  }
@@ -3850,6 +4060,18 @@ var MigrateCommand = class extends Command {
3850
4060
  ], process.cwd());
3851
4061
  this.success(`Applied ${pending.length} migration(s).`);
3852
4062
  pending.forEach(([_, file]) => this.success(this.app.splitLogger("Migrated", file)));
4063
+ this.syncModelRegistryIfRequested();
4064
+ }
4065
+ syncModelRegistryIfRequested() {
4066
+ if (!this.option("registry") && !this.option("r")) return true;
4067
+ try {
4068
+ const result = this.app.syncModelRegistry();
4069
+ this.success(this.app.splitLogger("Model Types", result.modelTypesPath ?? "none"));
4070
+ return true;
4071
+ } catch (error) {
4072
+ this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
4073
+ return false;
4074
+ }
3853
4075
  }
3854
4076
  /**
3855
4077
  * Load all migration classes from the specified directory.
@@ -3857,10 +4079,10 @@ var MigrateCommand = class extends Command {
3857
4079
  * @param migrationsDir The directory to load migration classes from.
3858
4080
  */
3859
4081
  resolveMigrationDirectories(configuredMigrationsDir) {
3860
- return [this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir), ...getRegisteredPaths("migrations").map((directory) => this.app.resolveRuntimeDirectoryPath(directory))].filter((directory, index, all) => existsSync$1(directory) && all.indexOf(directory) === index);
4082
+ return [this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir), ...getRegisteredPaths("migrations").map((directory) => this.app.resolveRuntimeDirectoryPath(directory))].filter((directory, index, all) => existsSync(directory) && all.indexOf(directory) === index);
3861
4083
  }
3862
4084
  async loadAllMigrations(migrationsDirs) {
3863
- const files = migrationsDirs.flatMap((migrationsDir) => readdirSync$1(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file))));
4085
+ const files = migrationsDirs.flatMap((migrationsDir) => readdirSync(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file))));
3864
4086
  return [...(await Promise.all(files.map(async (file) => (await this.loadMigrationClassesFromFile(file)).map((cls) => [cls, file])))).flat(), ...getRegisteredMigrations().map((cls) => [cls, `registered:${cls.name}`])];
3865
4087
  }
3866
4088
  /**
@@ -3884,7 +4106,7 @@ var MigrateCommand = class extends Command {
3884
4106
  `${base}Migration.js`,
3885
4107
  `${base}Migration.mjs`,
3886
4108
  `${base}Migration.cjs`
3887
- ].map((file) => join(migrationsDir, file))).find((file) => existsSync$1(file));
4109
+ ].map((file) => join(migrationsDir, file))).find((file) => existsSync(file));
3888
4110
  if (!target) return [[void 0, name]];
3889
4111
  const runtimeTarget = this.app.resolveRuntimeScriptPath(target);
3890
4112
  return (await this.loadMigrationClassesFromFile(runtimeTarget)).map((cls) => [cls, runtimeTarget]);
@@ -3991,8 +4213,8 @@ var MigrateFreshCommand = class extends Command {
3991
4213
  }
3992
4214
  if (!(await this.runWithDatabaseCreationRetry(adapter, () => adapter.resetDatabase())).ok) return;
3993
4215
  } else {
3994
- if (!existsSync$1(schemaPath)) return void this.error(`Error: Prisma schema file not found: ${this.app.formatPathForLog(schemaPath)}`);
3995
- writeFileSync$1(schemaPath, stripPrismaSchemaModelsAndEnums(readFileSync$1(schemaPath, "utf-8")));
4216
+ if (!existsSync(schemaPath)) return void this.error(`Error: Prisma schema file not found: ${this.app.formatPathForLog(schemaPath)}`);
4217
+ writeFileSync(schemaPath, stripPrismaSchemaModelsAndEnums(readFileSync(schemaPath, "utf-8")));
3996
4218
  }
3997
4219
  let appliedState = createEmptyAppliedMigrationsState();
3998
4220
  if (!(await this.runWithDatabaseCreationRetry(adapter, () => writeAppliedMigrationsStateToStore(adapter, stateFilePath, appliedState))).ok) return;
@@ -4039,10 +4261,10 @@ var MigrateFreshCommand = class extends Command {
4039
4261
  migrations.forEach(([_, file]) => this.success(this.app.splitLogger("Migrated", file)));
4040
4262
  }
4041
4263
  resolveMigrationDirectories(configuredMigrationsDir) {
4042
- return [this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir), ...getRegisteredPaths("migrations").map((directory) => this.app.resolveRuntimeDirectoryPath(directory))].filter((directory, index, all) => existsSync$1(directory) && all.indexOf(directory) === index);
4264
+ return [this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir), ...getRegisteredPaths("migrations").map((directory) => this.app.resolveRuntimeDirectoryPath(directory))].filter((directory, index, all) => existsSync(directory) && all.indexOf(directory) === index);
4043
4265
  }
4044
4266
  async loadAllMigrations(migrationsDirs) {
4045
- const files = migrationsDirs.flatMap((migrationsDir) => readdirSync$1(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file))));
4267
+ const files = migrationsDirs.flatMap((migrationsDir) => readdirSync(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file))));
4046
4268
  return [...(await Promise.all(files.map(async (file) => (await this.loadMigrationClassesFromFile(file)).map((cls) => [cls, file])))).flat(), ...getRegisteredMigrations().map((cls) => [cls, `registered:${cls.name}`])];
4047
4269
  }
4048
4270
  async loadMigrationClassesFromFile(filePath) {
@@ -4187,10 +4409,10 @@ var MigrateRollbackCommand = class extends Command {
4187
4409
  rollbackClasses.forEach(([_, file]) => this.success(this.app.splitLogger("RolledBack", file)));
4188
4410
  }
4189
4411
  resolveMigrationDirectories(configuredMigrationsDir) {
4190
- return [this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir), ...getRegisteredPaths("migrations").map((directory) => this.app.resolveRuntimeDirectoryPath(directory))].filter((directory, index, all) => existsSync$1(directory) && all.indexOf(directory) === index);
4412
+ return [this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir), ...getRegisteredPaths("migrations").map((directory) => this.app.resolveRuntimeDirectoryPath(directory))].filter((directory, index, all) => existsSync(directory) && all.indexOf(directory) === index);
4191
4413
  }
4192
4414
  async loadAllMigrations(migrationsDirs) {
4193
- const files = migrationsDirs.flatMap((migrationsDir) => readdirSync$1(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file))));
4415
+ const files = migrationsDirs.flatMap((migrationsDir) => readdirSync(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file))));
4194
4416
  return [...(await Promise.all(files.map(async (file) => (await this.loadMigrationClassesFromFile(file)).map((cls) => [cls, file])))).flat(), ...getRegisteredMigrations().map((cls) => [cls, `registered:${cls.name}`])];
4195
4417
  }
4196
4418
  async loadMigrationClassesFromFile(filePath) {
@@ -4236,11 +4458,11 @@ var MigrationHistoryCommand = class extends Command {
4236
4458
  this.success("Deleted tracked migration state from database.");
4237
4459
  return;
4238
4460
  }
4239
- if (!existsSync$1(stateFilePath)) {
4461
+ if (!existsSync(stateFilePath)) {
4240
4462
  this.success(`No migration state file found at ${this.app.formatPathForLog(stateFilePath)}`);
4241
4463
  return;
4242
4464
  }
4243
- rmSync$1(stateFilePath);
4465
+ rmSync(stateFilePath);
4244
4466
  deletePersistedColumnMappingsState(resolveColumnMappingsFilePath(process.cwd()));
4245
4467
  this.success(`Deleted migration state file: ${this.app.formatPathForLog(stateFilePath)}`);
4246
4468
  return;
@@ -4279,6 +4501,7 @@ var ModelsSyncCommand = class extends Command {
4279
4501
  this.signature = `models:sync
4280
4502
  {--schema= : Path to prisma schema file used when adapter introspection is unavailable}
4281
4503
  {--models= : Path to models directory}
4504
+ {--r|registry-only : Only sync the generated model registry type augmentation}
4282
4505
  `;
4283
4506
  this.description = "Sync model declare attributes from the active adapter when supported";
4284
4507
  }
@@ -4287,10 +4510,11 @@ var ModelsSyncCommand = class extends Command {
4287
4510
  await loadArkormConfig();
4288
4511
  let result;
4289
4512
  try {
4290
- result = await this.app.syncModels({
4513
+ const options = {
4291
4514
  schemaPath: this.option("schema") ? resolve(String(this.option("schema"))) : void 0,
4292
4515
  modelsDir: this.option("models") ? resolve(String(this.option("models"))) : void 0
4293
- });
4516
+ };
4517
+ result = this.option("registryOnly") || this.option("registry-only") || this.option("r") ? this.app.syncModelRegistry({ modelsDir: options.modelsDir }) : await this.app.syncModels(options);
4294
4518
  } catch (error) {
4295
4519
  this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
4296
4520
  return;
@@ -4298,9 +4522,10 @@ var ModelsSyncCommand = class extends Command {
4298
4522
  const updatedLines = result.updated.length === 0 ? [this.app.splitLogger("Updated", "none")] : result.updated.map((path) => this.app.splitLogger("Updated", path));
4299
4523
  this.success("SUCCESS: Model sync completed with the following results:");
4300
4524
  [
4301
- this.app.splitLogger("Source", result.source === "adapter" ? "adapter introspection" : "prisma schema"),
4525
+ this.app.splitLogger("Source", result.source === "adapter" ? "adapter introspection" : result.source === "registry" ? "model registry" : "prisma schema"),
4302
4526
  ...result.schemaPath ? [this.app.splitLogger("Schema", result.schemaPath)] : [],
4303
4527
  this.app.splitLogger("Models", result.modelsDir),
4528
+ ...result.modelTypesPath ? [this.app.splitLogger("Model Types", result.modelTypesPath)] : [],
4304
4529
  this.app.splitLogger("Processed", String(result.total)),
4305
4530
  ...updatedLines,
4306
4531
  this.app.splitLogger("Skipped", String(result.skipped.length))
@@ -4420,10 +4645,10 @@ var SeedCommand = class extends Command {
4420
4645
  * @returns
4421
4646
  */
4422
4647
  resolveSeederDirectories(configuredSeedersDir) {
4423
- return [this.app.resolveRuntimeDirectoryPath(configuredSeedersDir), ...getRegisteredPaths("seeders").map((directory) => this.app.resolveRuntimeDirectoryPath(directory))].filter((directory, index, all) => existsSync$1(directory) && all.indexOf(directory) === index);
4648
+ return [this.app.resolveRuntimeDirectoryPath(configuredSeedersDir), ...getRegisteredPaths("seeders").map((directory) => this.app.resolveRuntimeDirectoryPath(directory))].filter((directory, index, all) => existsSync(directory) && all.indexOf(directory) === index);
4424
4649
  }
4425
4650
  async loadAllSeeders(seedersDirs) {
4426
- const files = seedersDirs.flatMap((seedersDir) => readdirSync$1(seedersDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).map((file) => this.app.resolveRuntimeScriptPath(join(seedersDir, file))));
4651
+ const files = seedersDirs.flatMap((seedersDir) => readdirSync(seedersDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).map((file) => this.app.resolveRuntimeScriptPath(join(seedersDir, file))));
4427
4652
  return [...(await Promise.all(files.map(async (file) => await this.loadSeederClassesFromFile(file)))).flat(), ...getRegisteredSeeders()];
4428
4653
  }
4429
4654
  /**
@@ -4446,7 +4671,7 @@ var SeedCommand = class extends Command {
4446
4671
  `${base}Seeder.js`,
4447
4672
  `${base}Seeder.mjs`,
4448
4673
  `${base}Seeder.cjs`
4449
- ].map((file) => join(seedersDir, file))).find((file) => existsSync$1(file));
4674
+ ].map((file) => join(seedersDir, file))).find((file) => existsSync(file));
4450
4675
  if (!target) return [];
4451
4676
  const runtimeTarget = this.app.resolveRuntimeScriptPath(target);
4452
4677
  return await this.loadSeederClassesFromFile(runtimeTarget);
@@ -6465,6 +6690,26 @@ var QueryBuilder = class QueryBuilder {
6465
6690
  });
6466
6691
  }
6467
6692
  /**
6693
+ * Compiles the current query into SQL without executing it. Values remain represented by the
6694
+ * adapter's parameter placeholders; use {@link inspect} when the corresponding bindings are
6695
+ * also required.
6696
+ *
6697
+ * @param operation
6698
+ * @returns
6699
+ */
6700
+ toSql(operation = "select") {
6701
+ const inspection = this.inspect(operation);
6702
+ if (inspection?.sql) return inspection.sql;
6703
+ throw new UnsupportedAdapterFeatureException("The active database adapter cannot compile this query to SQL.", {
6704
+ operation: "query.toSql",
6705
+ model: this.model.name,
6706
+ meta: {
6707
+ feature: "inspectQuery",
6708
+ requestedOperation: operation
6709
+ }
6710
+ });
6711
+ }
6712
+ /**
6468
6713
  * Sets offset/limit for a 1-based page.
6469
6714
  *
6470
6715
  * @param page
@@ -6500,6 +6745,50 @@ var QueryBuilder = class QueryBuilder {
6500
6745
  return new ArkormCollection(filteredModels);
6501
6746
  }
6502
6747
  /**
6748
+ * Executes a bounded eager-load query independently for each partition while retaining a
6749
+ * single set-based database query. Returns null when the active adapter cannot represent the
6750
+ * query so the relationship loader can use its correctness fallback.
6751
+ *
6752
+ * @internal
6753
+ *
6754
+ * @param partitionBy
6755
+ * @returns
6756
+ */
6757
+ async getForEagerLoad(partitionBy) {
6758
+ if (this.limitValue === void 0 && this.offsetValue === void 0) return await this.get();
6759
+ const rows = await this.getRowsForEagerLoad(partitionBy);
6760
+ if (!rows) return null;
6761
+ const models = await this.model.hydrateManyRetrieved(rows);
6762
+ await this.eagerLoadModels(models);
6763
+ return new ArkormCollection(models);
6764
+ }
6765
+ /** @internal */
6766
+ async getRowsForEagerLoad(partitionBy) {
6767
+ if (this.limitValue === void 0 && this.offsetValue === void 0) return await this.executeReadRows();
6768
+ const adapter = this.requireAdapter();
6769
+ if (partitionBy.length === 0 || typeof adapter.selectPerPartition !== "function" || this.randomOrderEnabled || this.queryDistinct || this.queryGroupBy !== void 0 || this.queryHaving !== void 0 || !this.canExecuteRelationFeaturesInAdapter()) return null;
6770
+ const spec = this.tryBuildSelectSpec(this.buildWhere());
6771
+ if (!spec) return null;
6772
+ return await adapter.selectPerPartition({
6773
+ ...spec,
6774
+ limit: void 0,
6775
+ offset: void 0,
6776
+ partitionBy,
6777
+ perPartitionLimit: this.limitValue ?? Number.MAX_SAFE_INTEGER,
6778
+ perPartitionOffset: this.offsetValue
6779
+ });
6780
+ }
6781
+ /** Removes limit and offset clauses from a cloned relationship query. @internal */
6782
+ withoutPagination() {
6783
+ this.limitValue = void 0;
6784
+ this.offsetValue = void 0;
6785
+ return this;
6786
+ }
6787
+ /** @internal */
6788
+ hasEagerLoadPagination() {
6789
+ return this.limitValue !== void 0 || this.offsetValue !== void 0;
6790
+ }
6791
+ /**
6503
6792
  * Processes the query results in chunks, invoking the callback with each chunk
6504
6793
  * as a collection. Return `false` from the callback to stop early. Resolves to
6505
6794
  * `false` when stopped early, otherwise `true`.
@@ -7594,6 +7883,7 @@ var QueryBuilder = class QueryBuilder {
7594
7883
  const normalizedQuery = constrained instanceof QueryBuilder ? constrained : relatedQuery;
7595
7884
  if (constrained && !(constrained instanceof QueryBuilder) && constrained !== relatedQuery) return null;
7596
7885
  if (normalizedQuery.randomOrderEnabled) return null;
7886
+ if (normalizedQuery.hasRelationAggregates()) return null;
7597
7887
  const callbackRelationLoads = normalizedQuery.tryBuildAdapterRelationLoadPlans();
7598
7888
  const childRelationLoads = node.children.size > 0 ? toPlans(relatedModel, node.children) : [];
7599
7889
  if (callbackRelationLoads === null || childRelationLoads === null) return null;
@@ -9550,115 +9840,50 @@ var Model = class Model {
9550
9840
  isNotSame(model) {
9551
9841
  return !this.isSame(model);
9552
9842
  }
9553
- /**
9554
- * Define a has one relationship.
9555
- *
9556
- * @param related
9557
- * @param foreignKey
9558
- * @param localKey
9559
- * @returns
9560
- */
9561
9843
  hasOne(related, foreignKey, localKey) {
9562
9844
  const constructor = this.constructor;
9563
- return new HasOneRelation(this, related, foreignKey, localKey ?? constructor.getPrimaryKey());
9845
+ const relatedModel = this.resolveRelationshipModel(related, "hasOne");
9846
+ const resolvedLocalKey = localKey ?? constructor.getPrimaryKey();
9847
+ return new HasOneRelation(this, relatedModel, foreignKey ?? this.resolveDefaultHasForeignKey(constructor, resolvedLocalKey), resolvedLocalKey);
9564
9848
  }
9565
- /**
9566
- * Define a has many relationship.
9567
- *
9568
- * @param related
9569
- * @param foreignKey
9570
- * @param localKey
9571
- * @returns
9572
- */
9573
9849
  hasMany(related, foreignKey, localKey) {
9574
9850
  const constructor = this.constructor;
9575
- return new HasManyRelation(this, related, foreignKey, localKey ?? constructor.getPrimaryKey());
9851
+ const relatedModel = this.resolveRelationshipModel(related, "hasMany");
9852
+ const resolvedLocalKey = localKey ?? constructor.getPrimaryKey();
9853
+ return new HasManyRelation(this, relatedModel, foreignKey ?? this.resolveDefaultHasForeignKey(constructor, resolvedLocalKey), resolvedLocalKey);
9576
9854
  }
9577
- /**
9578
- * Define a belongs to relationship.
9579
- *
9580
- * @param related
9581
- * @param foreignKey
9582
- * @param ownerKey
9583
- * @returns
9584
- */
9585
9855
  belongsTo(related, foreignKey, ownerKey) {
9586
- return new BelongsToRelation(this, related, foreignKey, ownerKey ?? related.getPrimaryKey());
9856
+ const relatedModel = this.resolveRelationshipModel(related, "belongsTo");
9857
+ const resolvedOwnerKey = ownerKey ?? relatedModel.getPrimaryKey();
9858
+ return new BelongsToRelation(this, relatedModel, foreignKey ?? this.resolveDefaultBelongsToForeignKey(relatedModel, resolvedOwnerKey), resolvedOwnerKey);
9587
9859
  }
9588
- /**
9589
- * Define a belongs to many relationship.
9590
- *
9591
- * @param related
9592
- * @param throughTable
9593
- * @param foreignPivotKey
9594
- * @param relatedPivotKey
9595
- * @param parentKey
9596
- * @param relatedKey
9597
- * @returns
9598
- */
9599
9860
  belongsToMany(related, throughTable, foreignPivotKey, relatedPivotKey, parentKey, relatedKey) {
9600
9861
  const constructor = this.constructor;
9601
- return new BelongsToManyRelation(this, related, throughTable, foreignPivotKey, relatedPivotKey, parentKey ?? constructor.getPrimaryKey(), relatedKey ?? related.getPrimaryKey());
9862
+ const relatedModel = this.resolveRelationshipModel(related, "belongsToMany");
9863
+ const resolvedRelatedKey = relatedKey ?? relatedModel.getPrimaryKey();
9864
+ return new BelongsToManyRelation(this, relatedModel, throughTable, foreignPivotKey, relatedPivotKey, parentKey ?? constructor.getPrimaryKey(), resolvedRelatedKey);
9602
9865
  }
9603
- /**
9604
- * Define a has one through relationship.
9605
- *
9606
- * @param related
9607
- * @param throughTable
9608
- * @param firstKey
9609
- * @param secondKey
9610
- * @param localKey
9611
- * @param secondLocalKey
9612
- * @returns
9613
- */
9614
- hasOneThrough(related, throughTable, firstKey, secondKey, localKey, secondLocalKey = "id") {
9866
+ hasOneThrough(related, throughTable, firstKey, secondKey, localKey, secondLocalKey) {
9615
9867
  const constructor = this.constructor;
9616
- return new HasOneThroughRelation(this, related, throughTable, firstKey, secondKey, localKey ?? constructor.getPrimaryKey(), secondLocalKey);
9868
+ const relatedModel = this.resolveRelationshipModel(related, "hasOneThrough");
9869
+ return new HasOneThroughRelation(this, relatedModel, throughTable, firstKey, secondKey, localKey ?? constructor.getPrimaryKey(), secondLocalKey ?? "id");
9617
9870
  }
9618
- /**
9619
- * Define a has many through relationship.
9620
- *
9621
- * @param related
9622
- * @param throughTable
9623
- * @param firstKey
9624
- * @param secondKey
9625
- * @param localKey
9626
- * @param secondLocalKey
9627
- * @returns
9628
- */
9629
9871
  hasManyThrough(related, throughTable, firstKey, secondKey, localKey, secondLocalKey = "id") {
9630
9872
  const constructor = this.constructor;
9631
- return new HasManyThroughRelation(this, related, throughTable, firstKey, secondKey, localKey ?? constructor.getPrimaryKey(), secondLocalKey);
9873
+ const relatedModel = this.resolveRelationshipModel(related, "hasManyThrough");
9874
+ return new HasManyThroughRelation(this, relatedModel, throughTable, firstKey, secondKey, localKey ?? constructor.getPrimaryKey(), secondLocalKey);
9632
9875
  }
9633
- /**
9634
- * Define a polymorphic one to one relationship.
9635
- *
9636
- * @param related
9637
- * @param morphName
9638
- * @param idColumn
9639
- * @param typeColumn
9640
- * @param localKey
9641
- * @returns
9642
- */
9643
9876
  morphOne(related, morphName, idColumn, typeColumn, localKey) {
9644
9877
  const constructor = this.constructor;
9878
+ const relatedModel = this.resolveRelationshipModel(related, "morphOne");
9645
9879
  const columns = this.resolveMorphColumns(morphName, idColumn, typeColumn);
9646
- return new MorphOneRelation(this, related, morphName, columns.idColumn, columns.typeColumn, localKey ?? constructor.getPrimaryKey());
9880
+ return new MorphOneRelation(this, relatedModel, morphName, columns.idColumn, columns.typeColumn, localKey ?? constructor.getPrimaryKey());
9647
9881
  }
9648
- /**
9649
- * Define a polymorphic one to many relationship.
9650
- *
9651
- * @param related
9652
- * @param morphName
9653
- * @param idColumn
9654
- * @param typeColumn
9655
- * @param localKey
9656
- * @returns
9657
- */
9658
9882
  morphMany(related, morphName, idColumn, typeColumn, localKey) {
9659
9883
  const constructor = this.constructor;
9884
+ const relatedModel = this.resolveRelationshipModel(related, "morphMany");
9660
9885
  const columns = this.resolveMorphColumns(morphName, idColumn, typeColumn);
9661
- return new MorphManyRelation(this, related, morphName, columns.idColumn, columns.typeColumn, localKey ?? constructor.getPrimaryKey());
9886
+ return new MorphManyRelation(this, relatedModel, morphName, columns.idColumn, columns.typeColumn, localKey ?? constructor.getPrimaryKey());
9662
9887
  }
9663
9888
  morphTo(morphName, typeColumnOrRelated, idColumn, ownerKey) {
9664
9889
  const related = typeof typeColumnOrRelated === "function" ? typeColumnOrRelated : void 0;
@@ -9666,51 +9891,37 @@ var Model = class Model {
9666
9891
  const columns = this.resolveMorphColumns(morphName, idColumn, typeColumn);
9667
9892
  return new MorphToRelation(this, morphName, columns.typeColumn, columns.idColumn, ownerKey, related);
9668
9893
  }
9669
- /**
9670
- * Define a polymorphic many to many relationship.
9671
- *
9672
- * @param related
9673
- * @param morphName
9674
- * @param throughTable
9675
- * @param foreignPivotKey
9676
- * @param morphTypeColumn
9677
- * @param relatedPivotKey
9678
- * @param parentKey
9679
- * @param relatedKey
9680
- * @returns
9681
- */
9682
9894
  morphToMany(related, morphName, throughTable, foreignPivotKey, morphTypeColumn, relatedPivotKey, parentKey, relatedKey) {
9683
9895
  const constructor = this.constructor;
9684
9896
  const namingCase = Model.getNamingCase();
9685
- const resolvedRelatedKey = relatedKey ?? related.getPrimaryKey();
9897
+ const relatedModel = this.resolveRelationshipModel(related, "morphToMany");
9898
+ const resolvedRelatedKey = relatedKey ?? relatedModel.getPrimaryKey();
9686
9899
  const resolvedTable = throughTable ?? this.formatConventionName(`${str(morphName).plural()}`, namingCase);
9687
- const resolvedRelatedPivotKey = relatedPivotKey ?? this.formatConventionName(`${str(related.getTable()).singular()}_${resolvedRelatedKey}`, namingCase);
9900
+ const resolvedRelatedPivotKey = relatedPivotKey ?? this.formatConventionName(`${str(relatedModel.getTable()).singular()}_${resolvedRelatedKey}`, namingCase);
9688
9901
  const morphIdColumn = foreignPivotKey ?? this.formatConventionName(`${morphName}_id`, namingCase);
9689
9902
  const resolvedMorphTypeColumn = morphTypeColumn ?? this.formatConventionName(`${morphName}_type`, namingCase);
9690
- return new MorphToManyRelation(this, related, resolvedTable, morphName, morphIdColumn, resolvedMorphTypeColumn, resolvedRelatedPivotKey, parentKey ?? constructor.getPrimaryKey(), resolvedRelatedKey);
9903
+ return new MorphToManyRelation(this, relatedModel, resolvedTable, morphName, morphIdColumn, resolvedMorphTypeColumn, resolvedRelatedPivotKey, parentKey ?? constructor.getPrimaryKey(), resolvedRelatedKey);
9691
9904
  }
9692
- /**
9693
- * Define the inverse side of a polymorphic many-to-many relationship.
9694
- *
9695
- * @param related
9696
- * @param morphName
9697
- * @param throughTable
9698
- * @param foreignPivotKey
9699
- * @param morphTypeColumn
9700
- * @param relatedPivotKey
9701
- * @param parentKey
9702
- * @param relatedKey
9703
- * @returns
9704
- */
9705
9905
  morphedByMany(related, morphName, throughTable, foreignPivotKey, morphTypeColumn, relatedPivotKey, parentKey, relatedKey) {
9706
9906
  const constructor = this.constructor;
9707
9907
  const namingCase = Model.getNamingCase();
9708
- const resolvedRelatedKey = relatedKey ?? related.getPrimaryKey();
9908
+ const relatedModel = this.resolveRelationshipModel(related, "morphedByMany");
9909
+ const resolvedRelatedKey = relatedKey ?? relatedModel.getPrimaryKey();
9709
9910
  const resolvedTable = throughTable ?? this.formatConventionName(`${str(morphName).plural()}`, namingCase);
9710
9911
  const resolvedForeignPivotKey = foreignPivotKey ?? this.formatConventionName(`${str(constructor.getTable()).singular()}_${parentKey ?? constructor.getPrimaryKey()}`, namingCase);
9711
9912
  const resolvedMorphTypeColumn = morphTypeColumn ?? this.formatConventionName(`${morphName}_type`, namingCase);
9712
9913
  const resolvedRelatedPivotKey = relatedPivotKey ?? this.formatConventionName(`${morphName}_id`, namingCase);
9713
- return new MorphedByManyRelation(this, related, resolvedTable, morphName, resolvedForeignPivotKey, resolvedMorphTypeColumn, resolvedRelatedPivotKey, parentKey ?? constructor.getPrimaryKey(), resolvedRelatedKey);
9914
+ return new MorphedByManyRelation(this, relatedModel, resolvedTable, morphName, resolvedForeignPivotKey, resolvedMorphTypeColumn, resolvedRelatedPivotKey, parentKey ?? constructor.getPrimaryKey(), resolvedRelatedKey);
9915
+ }
9916
+ resolveRelationshipModel(related, operation) {
9917
+ if (typeof related === "function") return related;
9918
+ return resolveRegisteredModel(related, { operation });
9919
+ }
9920
+ resolveDefaultHasForeignKey(parent, localKey) {
9921
+ return this.formatConventionName(`${str(parent.getTable()).singular()}_${localKey}`, Model.getNamingCase());
9922
+ }
9923
+ resolveDefaultBelongsToForeignKey(related, ownerKey) {
9924
+ return this.formatConventionName(`${str(related.getTable()).singular()}_${ownerKey}`, Model.getNamingCase());
9714
9925
  }
9715
9926
  resolveMorphColumns(morphName, idColumn, typeColumn) {
9716
9927
  const namingCase = Model.getNamingCase();
@@ -10660,4 +10871,4 @@ var PivotModel = class extends Model {
10660
10871
  };
10661
10872
 
10662
10873
  //#endregion
10663
- export { AggregateExpression, Arkorm, ArkormCollection, ArkormException, Arkormx, Attribute, CaseExpression, CliApp, DB, DbCommand, EnumBuilder, Expression, ForeignKeyBuilder, InitCommand, InlineFactory, JoinClause, JsonExpression, KyselyDatabaseAdapter, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateFreshCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, MissingDelegateException, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_ENUM_MEMBER_REGEX, PRISMA_ENUM_REGEX, PRISMA_MODEL_REGEX, Paginator, PivotModel, PrimaryKeyGenerationPlanner, PrismaDatabaseAdapter, QueryBuilder, QueryConstraintException, QueryExecutionException, RelationResolutionException, RuntimeModuleLoader, SEEDER_BRAND, SchemaBuilder, ScopeNotDefinedException, SeedCommand, Seeder, TableBuilder, URLDriver, UniqueConstraintResolutionException, UnsupportedAdapterFeatureException, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToDatabase, applyMigrationRollbackToPrismaSchema, applyMigrationToDatabase, applyMigrationToPrismaSchema, applyOperationsToPersistedColumnMappingsState, applyOperationsToPrismaSchema, avg, awaitConfiguredModelsRegistration, bindAdapterToModels, buildEnumBlock, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildPrimaryKeyLine, buildRelationLine, buildUniqueConstraintLine, caseWhen, coalesce, col, computeMigrationChecksum, configureArkormRuntime, count, createEmptyAppliedMigrationsState, createEmptyPersistedColumnMappingsState, createKyselyAdapter, createMigrationTimestamp, createPrismaAdapter, createPrismaCompatibilityAdapter, createPrismaDatabaseAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deleteAppliedMigrationsStateFromStore, deletePersistedColumnMappingsState, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationAlias, deriveRelationFieldName, deriveSingularFieldName, disposeArkormRuntime, emitRuntimeDebugEvent, ensureArkormConfigLoading, escapeRegex, expressionBuilder, findAppliedMigration, findEnumBlock, findModelBlock, fn, formatDefaultValue, formatEnumDefaultValue, formatRelationAction, fromExpressionNode, generateMigrationFile, getActiveTransactionAdapter, getActiveTransactionClient, getDefaultStubsPath, getLastBatchMigrations, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getPersistedColumnMap, getPersistedEnumMap, getPersistedEnumTsType, getPersistedPrimaryKeyGeneration, getPersistedTableMetadata, getPersistedTimestampColumns, getRegisteredFactories, getRegisteredMigrations, getRegisteredModels, getRegisteredPaths, getRegisteredSeeders, getRuntimeAdapter, getRuntimeClient, getRuntimeCompatibilityAdapter, getRuntimeDebugHandler, getRuntimePaginationCurrentPageResolver, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, isMigrationPlanningActive, isQuerySchemaLike, isTransactionCapableClient, json, loadArkormConfig, loadFactoriesFrom, loadMigrationsFrom, loadModelsFrom, loadSeedersFrom, markMigrationApplied, markMigrationRun, max, min, pad, raw, readAppliedMigrationsState, readAppliedMigrationsStateFromStore, readPersistedColumnMappingsState, rebuildPersistedColumnMappingsState, registerFactories, registerMigrations, registerModels, registerPaths, registerSeeders, removeAppliedMigration, resetArkormRuntimeForTests, resetPersistedColumnMappingsCache, resetRuntimeRegistryForTests, resolveCast, resolveColumnMappingsFilePath, resolveEnumName, resolveGeneratedExpression, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePersistedMetadataFeatures, resolvePrismaType, resolveRuntimeCompatibilityQuerySchema, resolveRuntimeCompatibilityQuerySchemaOrThrow, runArkormTransaction, runInMigrationPlanning, runMigrationWithPrisma, runPrismaCommand, stripPrismaSchemaModelsAndEnums, sum, supportsDatabaseCreation, supportsDatabaseMigrationExecution, supportsDatabaseMigrationState, supportsDatabaseReset, syncPersistedColumnMappingsFromState, toMigrationFileSlug, toModelName, val, validatePersistedMetadataFeaturesForMigrations, where, writeAppliedMigrationsState, writeAppliedMigrationsStateToStore, writePersistedColumnMappingsState };
10874
+ export { AggregateExpression, Arkorm, ArkormCollection, ArkormException, Arkormx, Attribute, CaseExpression, CliApp, DB, DbCommand, EnumBuilder, Expression, ForeignKeyBuilder, InitCommand, InlineFactory, JoinClause, JsonExpression, KyselyDatabaseAdapter, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateFreshCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, MissingDelegateException, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_ENUM_MEMBER_REGEX, PRISMA_ENUM_REGEX, PRISMA_MODEL_REGEX, Paginator, PivotModel, PrimaryKeyGenerationPlanner, PrismaDatabaseAdapter, QueryBuilder, QueryConstraintException, QueryExecutionException, RelationResolutionException, RuntimeModuleLoader, SEEDER_BRAND, SchemaBuilder, ScopeNotDefinedException, SeedCommand, Seeder, TableBuilder, URLDriver, UniqueConstraintResolutionException, UnsupportedAdapterFeatureException, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToDatabase, applyMigrationRollbackToPrismaSchema, applyMigrationToDatabase, applyMigrationToPrismaSchema, applyOperationsToPersistedColumnMappingsState, applyOperationsToPrismaSchema, avg, awaitConfiguredModelsRegistration, bindAdapterToModels, buildEnumBlock, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildPrimaryKeyLine, buildRelationLine, buildUniqueConstraintLine, caseWhen, coalesce, col, computeMigrationChecksum, configureArkormRuntime, count, createEmptyAppliedMigrationsState, createEmptyPersistedColumnMappingsState, createKyselyAdapter, createMigrationTimestamp, createPrismaAdapter, createPrismaCompatibilityAdapter, createPrismaDatabaseAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deleteAppliedMigrationsStateFromStore, deletePersistedColumnMappingsState, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationAlias, deriveRelationFieldName, deriveSingularFieldName, disposeArkormRuntime, emitRuntimeDebugEvent, ensureArkormConfigLoading, escapeRegex, expressionBuilder, findAppliedMigration, findEnumBlock, findModelBlock, fn, formatDefaultValue, formatEnumDefaultValue, formatRelationAction, fromExpressionNode, generateMigrationFile, getActiveTransactionAdapter, getActiveTransactionClient, getDefaultStubsPath, getLastBatchMigrations, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getModel, getPersistedColumnMap, getPersistedEnumMap, getPersistedEnumTsType, getPersistedPrimaryKeyGeneration, getPersistedTableMetadata, getPersistedTimestampColumns, getRegisteredFactories, getRegisteredMigrations, getRegisteredModels, getRegisteredPaths, getRegisteredSeeders, getRuntimeAdapter, getRuntimeClient, getRuntimeCompatibilityAdapter, getRuntimeDebugHandler, getRuntimePaginationCurrentPageResolver, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, isMigrationPlanningActive, isQuerySchemaLike, isTransactionCapableClient, json, loadArkormConfig, loadFactoriesFrom, loadMigrationsFrom, loadModelsFrom, loadSeedersFrom, markMigrationApplied, markMigrationRun, max, min, pad, raw, readAppliedMigrationsState, readAppliedMigrationsStateFromStore, readPersistedColumnMappingsState, rebuildPersistedColumnMappingsState, registerFactories, registerMigrations, registerModels, registerPaths, registerSeeders, removeAppliedMigration, resetArkormRuntimeForTests, resetPersistedColumnMappingsCache, resetRuntimeRegistryForTests, resolveCast, resolveColumnMappingsFilePath, resolveEnumName, resolveGeneratedExpression, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePersistedMetadataFeatures, resolvePrismaType, resolveRegisteredModel, resolveRuntimeCompatibilityQuerySchema, resolveRuntimeCompatibilityQuerySchemaOrThrow, runArkormTransaction, runInMigrationPlanning, runMigrationWithPrisma, runPrismaCommand, stripPrismaSchemaModelsAndEnums, sum, supportsDatabaseCreation, supportsDatabaseMigrationExecution, supportsDatabaseMigrationState, supportsDatabaseReset, syncPersistedColumnMappingsFromState, toMigrationFileSlug, toModelName, val, validatePersistedMetadataFeaturesForMigrations, where, writeAppliedMigrationsState, writeAppliedMigrationsStateToStore, writePersistedColumnMappingsState };