arkormx 2.11.13 → 2.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,11 +1,13 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_relationship = require('./relationship-CBYK5LE3.cjs');
2
+ const require_relationship = require('./relationship-B7dIK_Vc.cjs');
3
3
  let pg = require("pg");
4
4
  let node_path = require("node:path");
5
+ let node_fs = require("node:fs");
6
+ let jiti = require("jiti");
7
+ let node_url = require("node:url");
5
8
  let module$1 = require("module");
6
9
  let fs = require("fs");
7
10
  let path = require("path");
8
- let node_fs = require("node:fs");
9
11
  let _h3ravel_support = require("@h3ravel/support");
10
12
  let node_async_hooks = require("node:async_hooks");
11
13
  let kysely = require("kysely");
@@ -2380,6 +2382,92 @@ const createPrismaDatabaseAdapter = (prisma, mapping = {}) => {
2380
2382
  */
2381
2383
  const createPrismaCompatibilityAdapter = createPrismaDatabaseAdapter;
2382
2384
 
2385
+ //#endregion
2386
+ //#region src/helpers/model-resolver.ts
2387
+ const modelExtensions = [
2388
+ ".ts",
2389
+ ".tsx",
2390
+ ".mts",
2391
+ ".cts",
2392
+ ".js",
2393
+ ".mjs",
2394
+ ".cjs"
2395
+ ];
2396
+ const isModelModule = (value) => typeof value === "object" && value !== null;
2397
+ const isModelConstructor = (value) => {
2398
+ if (typeof value !== "function") return false;
2399
+ const candidate = value;
2400
+ return typeof candidate.query === "function" && typeof candidate.hydrate === "function" && typeof candidate.getTable === "function" && typeof candidate.getPrimaryKey === "function";
2401
+ };
2402
+ const resolveModelExport = (module, modelName) => {
2403
+ if (!isModelModule(module)) return module;
2404
+ return module.default ?? module[modelName] ?? module;
2405
+ };
2406
+ const resolveRuntimeDirectory = (directory) => {
2407
+ if ((0, node_fs.existsSync)(directory)) return directory;
2408
+ const buildOutput = require_relationship.getUserConfig("paths")?.buildOutput;
2409
+ if (typeof buildOutput !== "string" || buildOutput.trim().length === 0) return directory;
2410
+ const relativeSource = (0, node_path.relative)(process.cwd(), directory);
2411
+ if (!relativeSource || relativeSource.startsWith("..")) return directory;
2412
+ const mappedDirectory = (0, node_path.join)(buildOutput, relativeSource);
2413
+ return (0, node_fs.existsSync)(mappedDirectory) ? mappedDirectory : directory;
2414
+ };
2415
+ const resolveRuntimeModelPath = (sourcePath) => {
2416
+ const extension = (0, node_path.extname)(sourcePath).toLowerCase();
2417
+ const candidates = [];
2418
+ if (modelExtensions.includes(extension)) candidates.push(sourcePath);
2419
+ else candidates.push(...modelExtensions.map((modelExtension) => `${sourcePath}${modelExtension}`));
2420
+ const buildOutput = require_relationship.getUserConfig("paths")?.buildOutput;
2421
+ if (typeof buildOutput === "string" && buildOutput.trim().length > 0) candidates.slice().forEach((candidate) => {
2422
+ const relativeSource = (0, node_path.relative)(process.cwd(), candidate);
2423
+ if (!relativeSource || relativeSource.startsWith("..")) return;
2424
+ const mappedFile = (0, node_path.join)(buildOutput, relativeSource);
2425
+ const mappedExtension = (0, node_path.extname)(mappedFile).toLowerCase();
2426
+ if ([
2427
+ ".ts",
2428
+ ".tsx",
2429
+ ".mts",
2430
+ ".cts"
2431
+ ].includes(mappedExtension)) {
2432
+ const base = mappedFile.slice(0, -mappedExtension.length);
2433
+ candidates.push(`${base}.js`, `${base}.mjs`, `${base}.cjs`);
2434
+ return;
2435
+ }
2436
+ candidates.push(mappedFile);
2437
+ });
2438
+ return candidates.find((candidate) => (0, node_fs.existsSync)(candidate)) ?? sourcePath;
2439
+ };
2440
+ const getModelDirectories = () => {
2441
+ const configured = require_relationship.getUserConfig("paths")?.models;
2442
+ const registered = require_relationship.getRegisteredPaths("models");
2443
+ return [...typeof configured === "string" ? [configured] : [], ...registered].map((directory) => resolveRuntimeDirectory((0, node_path.isAbsolute)(directory) ? directory : (0, node_path.resolve)(directory))).filter((directory, index, all) => all.indexOf(directory) === index);
2444
+ };
2445
+ const loadModel = (modelName, exportName) => {
2446
+ const jiti$1 = (0, jiti.createJiti)(`${(0, node_url.pathToFileURL)((0, node_path.resolve)(".")).href}/`, {
2447
+ interopDefault: false,
2448
+ tsconfigPaths: true,
2449
+ sourceMaps: true
2450
+ });
2451
+ for (const directory of getModelDirectories()) {
2452
+ const modulePath = resolveRuntimeModelPath((0, node_path.join)(directory, modelName));
2453
+ if (!(0, node_fs.existsSync)(modulePath)) continue;
2454
+ const model = resolveModelExport(jiti$1(modulePath), exportName);
2455
+ if (!isModelConstructor(model)) continue;
2456
+ require_relationship.registerModels(model);
2457
+ return model;
2458
+ }
2459
+ };
2460
+ function getModel(modelName) {
2461
+ const normalized = modelName.trim();
2462
+ const exportName = normalized.replace(/\\/g, "/").split("/").pop()?.replace(/\.[^.]+$/, "");
2463
+ if (!normalized || !exportName) throw new Error("Model name is required.");
2464
+ const registeredModel = require_relationship.getRegisteredModels().find((model) => model.name === exportName);
2465
+ if (registeredModel) return registeredModel;
2466
+ const model = loadModel(normalized, exportName);
2467
+ if (model) return model;
2468
+ throw new Error(`Model "${modelName}" not found.`);
2469
+ }
2470
+
2383
2471
  //#endregion
2384
2472
  //#region src/Arkorm.ts
2385
2473
  var Arkorm = class Arkorm {
@@ -2399,6 +2487,7 @@ var Arkorm = class Arkorm {
2399
2487
  this.getRegisteredMigrations = Arkorm.getRegisteredMigrations;
2400
2488
  this.getRegisteredSeeders = Arkorm.getRegisteredSeeders;
2401
2489
  this.getRegisteredModels = Arkorm.getRegisteredModels;
2490
+ this.getModel = Arkorm.getModel;
2402
2491
  this.getRegisteredFactories = Arkorm.getRegisteredFactories;
2403
2492
  }
2404
2493
  /**
@@ -2526,6 +2615,9 @@ var Arkorm = class Arkorm {
2526
2615
  static getRegisteredModels() {
2527
2616
  return require_relationship.getRegisteredModels();
2528
2617
  }
2618
+ static {
2619
+ this.getModel = getModel;
2620
+ }
2529
2621
  /**
2530
2622
  * Get registered factory constructors or instances.
2531
2623
  *
@@ -3123,7 +3215,7 @@ var CliApp = class {
3123
3215
  return lines.join("\n");
3124
3216
  }
3125
3217
  parseModelSyncSource(modelSource) {
3126
- const classMatch = modelSource.match(/export\s+class\s+(\w+)\s+extends\s+Model(?:<[^\n]+>)?\s*\{/);
3218
+ const classMatch = modelSource.match(/export\s+(?:abstract\s+)?class\s+(\w+)\s+extends\s+/);
3127
3219
  if (!classMatch) return null;
3128
3220
  const className = classMatch[1];
3129
3221
  const tableMatch = modelSource.match(/protected\s+static\s+override\s+table\s*=\s*['"]([^'"]+)['"]/) ?? modelSource.match(/static\s+table\s*=\s*['"]([^'"]+)['"]/);
@@ -3156,6 +3248,58 @@ var CliApp = class {
3156
3248
  skipped
3157
3249
  };
3158
3250
  }
3251
+ resolveModelFiles(modelsDir) {
3252
+ if (!(0, fs.existsSync)(modelsDir)) throw new Error(`Models directory not found: ${modelsDir}`);
3253
+ return (0, fs.readdirSync)(modelsDir).filter((file) => file.endsWith(".ts")).map((file) => (0, path.join)(modelsDir, file));
3254
+ }
3255
+ syncModelRegistryTypes(modelFiles) {
3256
+ const registryDir = (0, path.join)((0, fs.realpathSync)(process.cwd()), ".arkormx");
3257
+ const registryPath = (0, path.join)(registryDir, "models.d.ts");
3258
+ const models = modelFiles.map((filePath) => {
3259
+ const parsed = this.parseModelSyncSource((0, fs.readFileSync)(filePath, "utf-8"));
3260
+ if (!parsed) return null;
3261
+ return {
3262
+ className: parsed.className,
3263
+ importPath: this.resolveModelRegistryImportPath(registryPath, filePath)
3264
+ };
3265
+ }).filter((model) => model !== null).sort((left, right) => left.className.localeCompare(right.className));
3266
+ const importLines = models.map((model) => {
3267
+ return `import type { ${model.className} } from '${model.importPath}'`;
3268
+ });
3269
+ const registryLines = models.map((model) => {
3270
+ return ` ${model.className}: typeof ${model.className}`;
3271
+ });
3272
+ const content = [
3273
+ "/* eslint-disable */",
3274
+ "// This file is generated by `arkorm models:sync`.",
3275
+ ...importLines,
3276
+ "",
3277
+ "declare module 'arkormx' {",
3278
+ " interface ArkormModelRegistry {",
3279
+ ...registryLines,
3280
+ " }",
3281
+ "}",
3282
+ "",
3283
+ "export {}",
3284
+ ""
3285
+ ].join("\n");
3286
+ if (((0, fs.existsSync)(registryPath) ? (0, fs.readFileSync)(registryPath, "utf-8") : null) === content) return {
3287
+ path: registryPath,
3288
+ updated: false
3289
+ };
3290
+ (0, fs.mkdirSync)(registryDir, { recursive: true });
3291
+ (0, fs.writeFileSync)(registryPath, content);
3292
+ return {
3293
+ path: registryPath,
3294
+ updated: true
3295
+ };
3296
+ }
3297
+ resolveModelRegistryImportPath(registryPath, modelPath) {
3298
+ const realModelPath = (0, fs.realpathSync)(modelPath);
3299
+ const withoutExtension = realModelPath.slice(0, -(0, path.extname)(realModelPath).length);
3300
+ const relativePath = (0, path.relative)((0, path.dirname)(registryPath), withoutExtension).replace(/\\/g, "/");
3301
+ return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
3302
+ }
3159
3303
  applyPersistedFieldMetadata(structure) {
3160
3304
  const persistedMetadata = require_relationship.getPersistedTableMetadata(structure.table, {
3161
3305
  features: require_relationship.resolvePersistedMetadataFeatures(this.getConfig("features")),
@@ -3333,8 +3477,7 @@ var CliApp = class {
3333
3477
  }
3334
3478
  async syncModels(options = {}) {
3335
3479
  const modelsDir = options.modelsDir ?? this.resolveConfigPath("models", (0, path.join)(process.cwd(), "src", "models"));
3336
- if (!(0, fs.existsSync)(modelsDir)) throw new Error(`Models directory not found: ${modelsDir}`);
3337
- const modelFiles = (0, fs.readdirSync)(modelsDir).filter((file) => file.endsWith(".ts")).map((file) => (0, path.join)(modelsDir, file));
3480
+ const modelFiles = this.resolveModelFiles(modelsDir);
3338
3481
  const adapter = this.getConfig("adapter");
3339
3482
  if (adapter && typeof adapter.introspectModels === "function") {
3340
3483
  const sources = modelFiles.reduce((all, filePath) => {
@@ -3351,11 +3494,13 @@ var CliApp = class {
3351
3494
  const parsed = sources.get(filePath);
3352
3495
  return parsed ? structuresByTable.get(parsed.table) : void 0;
3353
3496
  }, /* @__PURE__ */ new Map());
3497
+ const modelTypes = this.syncModelRegistryTypes(modelFiles);
3354
3498
  return {
3355
3499
  source: "adapter",
3356
3500
  modelsDir,
3501
+ modelTypesPath: modelTypes.path,
3357
3502
  total: modelFiles.length,
3358
- updated: result.updated,
3503
+ updated: modelTypes.updated ? [...result.updated, modelTypes.path] : result.updated,
3359
3504
  skipped: result.skipped
3360
3505
  };
3361
3506
  }
@@ -3364,6 +3509,19 @@ var CliApp = class {
3364
3509
  ...this.syncModelsFromPrisma(options)
3365
3510
  };
3366
3511
  }
3512
+ syncModelRegistry(options = {}) {
3513
+ const modelsDir = options.modelsDir ?? this.resolveConfigPath("models", (0, path.join)(process.cwd(), "src", "models"));
3514
+ const modelFiles = this.resolveModelFiles(modelsDir);
3515
+ const modelTypes = this.syncModelRegistryTypes(modelFiles);
3516
+ return {
3517
+ source: "registry",
3518
+ modelsDir,
3519
+ modelTypesPath: modelTypes.path,
3520
+ total: modelFiles.length,
3521
+ updated: modelTypes.updated ? [modelTypes.path] : [],
3522
+ skipped: []
3523
+ };
3524
+ }
3367
3525
  /**
3368
3526
  * Sync model attribute declarations in model files based on the Prisma schema.
3369
3527
  * This method reads the Prisma schema to extract model definitions and their
@@ -3379,21 +3537,22 @@ var CliApp = class {
3379
3537
  const schemaPath = options.schemaPath ?? (0, path.join)(process.cwd(), "prisma", "schema.prisma");
3380
3538
  const modelsDir = options.modelsDir ?? this.resolveConfigPath("models", (0, path.join)(process.cwd(), "src", "models"));
3381
3539
  if (!(0, fs.existsSync)(schemaPath)) throw new Error(`Prisma schema file not found: ${schemaPath}`);
3382
- if (!(0, fs.existsSync)(modelsDir)) throw new Error(`Models directory not found: ${modelsDir}`);
3383
3540
  const schema = (0, fs.readFileSync)(schemaPath, "utf-8");
3384
3541
  const prismaEnums = this.parsePrismaEnums(schema);
3385
3542
  const prismaModels = this.parsePrismaModels(schema);
3386
- const modelFiles = (0, fs.readdirSync)(modelsDir).filter((file) => file.endsWith(".ts")).map((file) => (0, path.join)(modelsDir, file));
3543
+ const modelFiles = this.resolveModelFiles(modelsDir);
3387
3544
  const result = this.syncModelFiles(modelFiles, (filePath, source) => {
3388
3545
  const parsed = this.parseModelSyncSource(source);
3389
3546
  if (!parsed) return void 0;
3390
3547
  return prismaModels.find((model) => model.table === parsed.table) ?? prismaModels.find((model) => model.name === parsed.className);
3391
3548
  }, prismaEnums);
3549
+ const modelTypes = this.syncModelRegistryTypes(modelFiles);
3392
3550
  return {
3393
3551
  schemaPath,
3394
3552
  modelsDir,
3553
+ modelTypesPath: modelTypes.path,
3395
3554
  total: modelFiles.length,
3396
- updated: result.updated,
3555
+ updated: modelTypes.updated ? [...result.updated, modelTypes.path] : result.updated,
3397
3556
  skipped: result.skipped
3398
3557
  };
3399
3558
  }
@@ -3786,6 +3945,7 @@ var MigrateCommand = class extends _h3ravel_musket.Command {
3786
3945
  {--deploy : Use prisma migrate deploy instead of migrate dev (Prisma compatibility driver only)}
3787
3946
  {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
3788
3947
  {--skip-migrate : Skip prisma migrate command}
3948
+ {--r|registry : Sync the generated model registry type augmentation after a successful migration}
3789
3949
  {--state-file= : Path to applied migration state file}
3790
3950
  {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
3791
3951
  {--migration-name= : Name for prisma migrate dev (Prisma compatibility driver only)}
@@ -3842,6 +4002,7 @@ var MigrateCommand = class extends _h3ravel_musket.Command {
3842
4002
  this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
3843
4003
  return;
3844
4004
  }
4005
+ if (!this.syncModelRegistryIfRequested()) return;
3845
4006
  this.success("No pending migration classes to apply.");
3846
4007
  return;
3847
4008
  }
@@ -3900,6 +4061,18 @@ var MigrateCommand = class extends _h3ravel_musket.Command {
3900
4061
  ], process.cwd());
3901
4062
  this.success(`Applied ${pending.length} migration(s).`);
3902
4063
  pending.forEach(([_, file]) => this.success(this.app.splitLogger("Migrated", file)));
4064
+ this.syncModelRegistryIfRequested();
4065
+ }
4066
+ syncModelRegistryIfRequested() {
4067
+ if (!this.option("registry") && !this.option("r")) return true;
4068
+ try {
4069
+ const result = this.app.syncModelRegistry();
4070
+ this.success(this.app.splitLogger("Model Types", result.modelTypesPath ?? "none"));
4071
+ return true;
4072
+ } catch (error) {
4073
+ this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
4074
+ return false;
4075
+ }
3903
4076
  }
3904
4077
  /**
3905
4078
  * Load all migration classes from the specified directory.
@@ -4329,6 +4502,7 @@ var ModelsSyncCommand = class extends _h3ravel_musket.Command {
4329
4502
  this.signature = `models:sync
4330
4503
  {--schema= : Path to prisma schema file used when adapter introspection is unavailable}
4331
4504
  {--models= : Path to models directory}
4505
+ {--r|registry-only : Only sync the generated model registry type augmentation}
4332
4506
  `;
4333
4507
  this.description = "Sync model declare attributes from the active adapter when supported";
4334
4508
  }
@@ -4337,10 +4511,11 @@ var ModelsSyncCommand = class extends _h3ravel_musket.Command {
4337
4511
  await require_relationship.loadArkormConfig();
4338
4512
  let result;
4339
4513
  try {
4340
- result = await this.app.syncModels({
4514
+ const options = {
4341
4515
  schemaPath: this.option("schema") ? (0, node_path.resolve)(String(this.option("schema"))) : void 0,
4342
4516
  modelsDir: this.option("models") ? (0, node_path.resolve)(String(this.option("models"))) : void 0
4343
- });
4517
+ };
4518
+ result = this.option("registryOnly") || this.option("registry-only") || this.option("r") ? this.app.syncModelRegistry({ modelsDir: options.modelsDir }) : await this.app.syncModels(options);
4344
4519
  } catch (error) {
4345
4520
  this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
4346
4521
  return;
@@ -4348,9 +4523,10 @@ var ModelsSyncCommand = class extends _h3ravel_musket.Command {
4348
4523
  const updatedLines = result.updated.length === 0 ? [this.app.splitLogger("Updated", "none")] : result.updated.map((path) => this.app.splitLogger("Updated", path));
4349
4524
  this.success("SUCCESS: Model sync completed with the following results:");
4350
4525
  [
4351
- this.app.splitLogger("Source", result.source === "adapter" ? "adapter introspection" : "prisma schema"),
4526
+ this.app.splitLogger("Source", result.source === "adapter" ? "adapter introspection" : result.source === "registry" ? "model registry" : "prisma schema"),
4352
4527
  ...result.schemaPath ? [this.app.splitLogger("Schema", result.schemaPath)] : [],
4353
4528
  this.app.splitLogger("Models", result.modelsDir),
4529
+ ...result.modelTypesPath ? [this.app.splitLogger("Model Types", result.modelTypesPath)] : [],
4354
4530
  this.app.splitLogger("Processed", String(result.total)),
4355
4531
  ...updatedLines,
4356
4532
  this.app.splitLogger("Skipped", String(result.skipped.length))
@@ -9665,115 +9841,50 @@ var Model = class Model {
9665
9841
  isNotSame(model) {
9666
9842
  return !this.isSame(model);
9667
9843
  }
9668
- /**
9669
- * Define a has one relationship.
9670
- *
9671
- * @param related
9672
- * @param foreignKey
9673
- * @param localKey
9674
- * @returns
9675
- */
9676
9844
  hasOne(related, foreignKey, localKey) {
9677
9845
  const constructor = this.constructor;
9678
- return new require_relationship.HasOneRelation(this, related, foreignKey, localKey ?? constructor.getPrimaryKey());
9846
+ const relatedModel = this.resolveRelationshipModel(related, "hasOne");
9847
+ const resolvedLocalKey = localKey ?? constructor.getPrimaryKey();
9848
+ return new require_relationship.HasOneRelation(this, relatedModel, foreignKey ?? this.resolveDefaultHasForeignKey(constructor, resolvedLocalKey), resolvedLocalKey);
9679
9849
  }
9680
- /**
9681
- * Define a has many relationship.
9682
- *
9683
- * @param related
9684
- * @param foreignKey
9685
- * @param localKey
9686
- * @returns
9687
- */
9688
9850
  hasMany(related, foreignKey, localKey) {
9689
9851
  const constructor = this.constructor;
9690
- return new require_relationship.HasManyRelation(this, related, foreignKey, localKey ?? constructor.getPrimaryKey());
9852
+ const relatedModel = this.resolveRelationshipModel(related, "hasMany");
9853
+ const resolvedLocalKey = localKey ?? constructor.getPrimaryKey();
9854
+ return new require_relationship.HasManyRelation(this, relatedModel, foreignKey ?? this.resolveDefaultHasForeignKey(constructor, resolvedLocalKey), resolvedLocalKey);
9691
9855
  }
9692
- /**
9693
- * Define a belongs to relationship.
9694
- *
9695
- * @param related
9696
- * @param foreignKey
9697
- * @param ownerKey
9698
- * @returns
9699
- */
9700
9856
  belongsTo(related, foreignKey, ownerKey) {
9701
- return new require_relationship.BelongsToRelation(this, related, foreignKey, ownerKey ?? related.getPrimaryKey());
9857
+ const relatedModel = this.resolveRelationshipModel(related, "belongsTo");
9858
+ const resolvedOwnerKey = ownerKey ?? relatedModel.getPrimaryKey();
9859
+ return new require_relationship.BelongsToRelation(this, relatedModel, foreignKey ?? this.resolveDefaultBelongsToForeignKey(relatedModel, resolvedOwnerKey), resolvedOwnerKey);
9702
9860
  }
9703
- /**
9704
- * Define a belongs to many relationship.
9705
- *
9706
- * @param related
9707
- * @param throughTable
9708
- * @param foreignPivotKey
9709
- * @param relatedPivotKey
9710
- * @param parentKey
9711
- * @param relatedKey
9712
- * @returns
9713
- */
9714
9861
  belongsToMany(related, throughTable, foreignPivotKey, relatedPivotKey, parentKey, relatedKey) {
9715
9862
  const constructor = this.constructor;
9716
- return new require_relationship.BelongsToManyRelation(this, related, throughTable, foreignPivotKey, relatedPivotKey, parentKey ?? constructor.getPrimaryKey(), relatedKey ?? related.getPrimaryKey());
9863
+ const relatedModel = this.resolveRelationshipModel(related, "belongsToMany");
9864
+ const resolvedRelatedKey = relatedKey ?? relatedModel.getPrimaryKey();
9865
+ return new require_relationship.BelongsToManyRelation(this, relatedModel, throughTable, foreignPivotKey, relatedPivotKey, parentKey ?? constructor.getPrimaryKey(), resolvedRelatedKey);
9717
9866
  }
9718
- /**
9719
- * Define a has one through relationship.
9720
- *
9721
- * @param related
9722
- * @param throughTable
9723
- * @param firstKey
9724
- * @param secondKey
9725
- * @param localKey
9726
- * @param secondLocalKey
9727
- * @returns
9728
- */
9729
- hasOneThrough(related, throughTable, firstKey, secondKey, localKey, secondLocalKey = "id") {
9867
+ hasOneThrough(related, throughTable, firstKey, secondKey, localKey, secondLocalKey) {
9730
9868
  const constructor = this.constructor;
9731
- return new require_relationship.HasOneThroughRelation(this, related, throughTable, firstKey, secondKey, localKey ?? constructor.getPrimaryKey(), secondLocalKey);
9869
+ const relatedModel = this.resolveRelationshipModel(related, "hasOneThrough");
9870
+ return new require_relationship.HasOneThroughRelation(this, relatedModel, throughTable, firstKey, secondKey, localKey ?? constructor.getPrimaryKey(), secondLocalKey ?? "id");
9732
9871
  }
9733
- /**
9734
- * Define a has many through relationship.
9735
- *
9736
- * @param related
9737
- * @param throughTable
9738
- * @param firstKey
9739
- * @param secondKey
9740
- * @param localKey
9741
- * @param secondLocalKey
9742
- * @returns
9743
- */
9744
9872
  hasManyThrough(related, throughTable, firstKey, secondKey, localKey, secondLocalKey = "id") {
9745
9873
  const constructor = this.constructor;
9746
- return new require_relationship.HasManyThroughRelation(this, related, throughTable, firstKey, secondKey, localKey ?? constructor.getPrimaryKey(), secondLocalKey);
9874
+ const relatedModel = this.resolveRelationshipModel(related, "hasManyThrough");
9875
+ return new require_relationship.HasManyThroughRelation(this, relatedModel, throughTable, firstKey, secondKey, localKey ?? constructor.getPrimaryKey(), secondLocalKey);
9747
9876
  }
9748
- /**
9749
- * Define a polymorphic one to one relationship.
9750
- *
9751
- * @param related
9752
- * @param morphName
9753
- * @param idColumn
9754
- * @param typeColumn
9755
- * @param localKey
9756
- * @returns
9757
- */
9758
9877
  morphOne(related, morphName, idColumn, typeColumn, localKey) {
9759
9878
  const constructor = this.constructor;
9879
+ const relatedModel = this.resolveRelationshipModel(related, "morphOne");
9760
9880
  const columns = this.resolveMorphColumns(morphName, idColumn, typeColumn);
9761
- return new require_relationship.MorphOneRelation(this, related, morphName, columns.idColumn, columns.typeColumn, localKey ?? constructor.getPrimaryKey());
9881
+ return new require_relationship.MorphOneRelation(this, relatedModel, morphName, columns.idColumn, columns.typeColumn, localKey ?? constructor.getPrimaryKey());
9762
9882
  }
9763
- /**
9764
- * Define a polymorphic one to many relationship.
9765
- *
9766
- * @param related
9767
- * @param morphName
9768
- * @param idColumn
9769
- * @param typeColumn
9770
- * @param localKey
9771
- * @returns
9772
- */
9773
9883
  morphMany(related, morphName, idColumn, typeColumn, localKey) {
9774
9884
  const constructor = this.constructor;
9885
+ const relatedModel = this.resolveRelationshipModel(related, "morphMany");
9775
9886
  const columns = this.resolveMorphColumns(morphName, idColumn, typeColumn);
9776
- return new require_relationship.MorphManyRelation(this, related, morphName, columns.idColumn, columns.typeColumn, localKey ?? constructor.getPrimaryKey());
9887
+ return new require_relationship.MorphManyRelation(this, relatedModel, morphName, columns.idColumn, columns.typeColumn, localKey ?? constructor.getPrimaryKey());
9777
9888
  }
9778
9889
  morphTo(morphName, typeColumnOrRelated, idColumn, ownerKey) {
9779
9890
  const related = typeof typeColumnOrRelated === "function" ? typeColumnOrRelated : void 0;
@@ -9781,51 +9892,37 @@ var Model = class Model {
9781
9892
  const columns = this.resolveMorphColumns(morphName, idColumn, typeColumn);
9782
9893
  return new require_relationship.MorphToRelation(this, morphName, columns.typeColumn, columns.idColumn, ownerKey, related);
9783
9894
  }
9784
- /**
9785
- * Define a polymorphic many to many relationship.
9786
- *
9787
- * @param related
9788
- * @param morphName
9789
- * @param throughTable
9790
- * @param foreignPivotKey
9791
- * @param morphTypeColumn
9792
- * @param relatedPivotKey
9793
- * @param parentKey
9794
- * @param relatedKey
9795
- * @returns
9796
- */
9797
9895
  morphToMany(related, morphName, throughTable, foreignPivotKey, morphTypeColumn, relatedPivotKey, parentKey, relatedKey) {
9798
9896
  const constructor = this.constructor;
9799
9897
  const namingCase = Model.getNamingCase();
9800
- const resolvedRelatedKey = relatedKey ?? related.getPrimaryKey();
9898
+ const relatedModel = this.resolveRelationshipModel(related, "morphToMany");
9899
+ const resolvedRelatedKey = relatedKey ?? relatedModel.getPrimaryKey();
9801
9900
  const resolvedTable = throughTable ?? this.formatConventionName(`${(0, _h3ravel_support.str)(morphName).plural()}`, namingCase);
9802
- const resolvedRelatedPivotKey = relatedPivotKey ?? this.formatConventionName(`${(0, _h3ravel_support.str)(related.getTable()).singular()}_${resolvedRelatedKey}`, namingCase);
9901
+ const resolvedRelatedPivotKey = relatedPivotKey ?? this.formatConventionName(`${(0, _h3ravel_support.str)(relatedModel.getTable()).singular()}_${resolvedRelatedKey}`, namingCase);
9803
9902
  const morphIdColumn = foreignPivotKey ?? this.formatConventionName(`${morphName}_id`, namingCase);
9804
9903
  const resolvedMorphTypeColumn = morphTypeColumn ?? this.formatConventionName(`${morphName}_type`, namingCase);
9805
- return new require_relationship.MorphToManyRelation(this, related, resolvedTable, morphName, morphIdColumn, resolvedMorphTypeColumn, resolvedRelatedPivotKey, parentKey ?? constructor.getPrimaryKey(), resolvedRelatedKey);
9904
+ return new require_relationship.MorphToManyRelation(this, relatedModel, resolvedTable, morphName, morphIdColumn, resolvedMorphTypeColumn, resolvedRelatedPivotKey, parentKey ?? constructor.getPrimaryKey(), resolvedRelatedKey);
9806
9905
  }
9807
- /**
9808
- * Define the inverse side of a polymorphic many-to-many relationship.
9809
- *
9810
- * @param related
9811
- * @param morphName
9812
- * @param throughTable
9813
- * @param foreignPivotKey
9814
- * @param morphTypeColumn
9815
- * @param relatedPivotKey
9816
- * @param parentKey
9817
- * @param relatedKey
9818
- * @returns
9819
- */
9820
9906
  morphedByMany(related, morphName, throughTable, foreignPivotKey, morphTypeColumn, relatedPivotKey, parentKey, relatedKey) {
9821
9907
  const constructor = this.constructor;
9822
9908
  const namingCase = Model.getNamingCase();
9823
- const resolvedRelatedKey = relatedKey ?? related.getPrimaryKey();
9909
+ const relatedModel = this.resolveRelationshipModel(related, "morphedByMany");
9910
+ const resolvedRelatedKey = relatedKey ?? relatedModel.getPrimaryKey();
9824
9911
  const resolvedTable = throughTable ?? this.formatConventionName(`${(0, _h3ravel_support.str)(morphName).plural()}`, namingCase);
9825
9912
  const resolvedForeignPivotKey = foreignPivotKey ?? this.formatConventionName(`${(0, _h3ravel_support.str)(constructor.getTable()).singular()}_${parentKey ?? constructor.getPrimaryKey()}`, namingCase);
9826
9913
  const resolvedMorphTypeColumn = morphTypeColumn ?? this.formatConventionName(`${morphName}_type`, namingCase);
9827
9914
  const resolvedRelatedPivotKey = relatedPivotKey ?? this.formatConventionName(`${morphName}_id`, namingCase);
9828
- return new require_relationship.MorphedByManyRelation(this, related, resolvedTable, morphName, resolvedForeignPivotKey, resolvedMorphTypeColumn, resolvedRelatedPivotKey, parentKey ?? constructor.getPrimaryKey(), resolvedRelatedKey);
9915
+ return new require_relationship.MorphedByManyRelation(this, relatedModel, resolvedTable, morphName, resolvedForeignPivotKey, resolvedMorphTypeColumn, resolvedRelatedPivotKey, parentKey ?? constructor.getPrimaryKey(), resolvedRelatedKey);
9916
+ }
9917
+ resolveRelationshipModel(related, operation) {
9918
+ if (typeof related === "function") return related;
9919
+ return require_relationship.resolveRegisteredModel(related, { operation });
9920
+ }
9921
+ resolveDefaultHasForeignKey(parent, localKey) {
9922
+ return this.formatConventionName(`${(0, _h3ravel_support.str)(parent.getTable()).singular()}_${localKey}`, Model.getNamingCase());
9923
+ }
9924
+ resolveDefaultBelongsToForeignKey(related, ownerKey) {
9925
+ return this.formatConventionName(`${(0, _h3ravel_support.str)(related.getTable()).singular()}_${ownerKey}`, Model.getNamingCase());
9829
9926
  }
9830
9927
  resolveMorphColumns(morphName, idColumn, typeColumn) {
9831
9928
  const namingCase = Model.getNamingCase();
@@ -10897,6 +10994,7 @@ exports.getLastBatchMigrations = require_relationship.getLastBatchMigrations;
10897
10994
  exports.getLastMigrationRun = require_relationship.getLastMigrationRun;
10898
10995
  exports.getLatestAppliedMigrations = require_relationship.getLatestAppliedMigrations;
10899
10996
  exports.getMigrationPlan = require_relationship.getMigrationPlan;
10997
+ exports.getModel = getModel;
10900
10998
  exports.getPersistedColumnMap = require_relationship.getPersistedColumnMap;
10901
10999
  exports.getPersistedEnumMap = require_relationship.getPersistedEnumMap;
10902
11000
  exports.getPersistedEnumTsType = require_relationship.getPersistedEnumTsType;
@@ -10919,7 +11017,6 @@ exports.getUserConfig = require_relationship.getUserConfig;
10919
11017
  exports.inferDelegateName = inferDelegateName;
10920
11018
  exports.isDelegateLike = require_relationship.isDelegateLike;
10921
11019
  exports.isMigrationApplied = require_relationship.isMigrationApplied;
10922
- exports.isMigrationPlanningActive = require_relationship.isMigrationPlanningActive;
10923
11020
  exports.isQuerySchemaLike = require_relationship.isQuerySchemaLike;
10924
11021
  exports.isTransactionCapableClient = require_relationship.isTransactionCapableClient;
10925
11022
  exports.json = require_relationship.json;
@@ -10955,10 +11052,10 @@ exports.resolveMigrationClassName = require_relationship.resolveMigrationClassNa
10955
11052
  exports.resolveMigrationStateFilePath = require_relationship.resolveMigrationStateFilePath;
10956
11053
  exports.resolvePersistedMetadataFeatures = require_relationship.resolvePersistedMetadataFeatures;
10957
11054
  exports.resolvePrismaType = require_relationship.resolvePrismaType;
11055
+ exports.resolveRegisteredModel = require_relationship.resolveRegisteredModel;
10958
11056
  exports.resolveRuntimeCompatibilityQuerySchema = resolveRuntimeCompatibilityQuerySchema;
10959
11057
  exports.resolveRuntimeCompatibilityQuerySchemaOrThrow = resolveRuntimeCompatibilityQuerySchemaOrThrow;
10960
11058
  exports.runArkormTransaction = require_relationship.runArkormTransaction;
10961
- exports.runInMigrationPlanning = require_relationship.runInMigrationPlanning;
10962
11059
  exports.runMigrationWithPrisma = require_relationship.runMigrationWithPrisma;
10963
11060
  exports.runPrismaCommand = require_relationship.runPrismaCommand;
10964
11061
  exports.stripPrismaSchemaModelsAndEnums = require_relationship.stripPrismaSchemaModelsAndEnums;