arkormx 0.2.2 → 0.2.3

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
@@ -117,6 +117,79 @@ var ArkormException = class extends Error {
117
117
  }
118
118
  };
119
119
 
120
+ //#endregion
121
+ //#region src/database/ForeignKeyBuilder.ts
122
+ /**
123
+ * The ForeignKeyBuilder class provides a fluent interface for defining
124
+ * foreign key constraints in a migration. It allows you to specify
125
+ * the referenced table and column, as well as actions to take on
126
+ * delete and aliases for the relation.
127
+ *
128
+ * @author Legacy (3m1n3nc3)
129
+ * @since 0.2.2
130
+ */
131
+ var ForeignKeyBuilder = class {
132
+ foreignKey;
133
+ constructor(foreignKey) {
134
+ this.foreignKey = foreignKey;
135
+ }
136
+ /**
137
+ * Defines the referenced table and column for this foreign key constraint.
138
+ *
139
+ * @param table
140
+ * @param column
141
+ * @returns
142
+ */
143
+ references(table, column) {
144
+ this.foreignKey.referencesTable = table;
145
+ this.foreignKey.referencesColumn = column;
146
+ return this;
147
+ }
148
+ /**
149
+ * Defines the action to take when a referenced record is deleted, such
150
+ * as "CASCADE", "SET NULL", or "RESTRICT".
151
+ *
152
+ * @param action
153
+ * @returns
154
+ */
155
+ onDelete(action) {
156
+ this.foreignKey.onDelete = action;
157
+ return this;
158
+ }
159
+ /**
160
+ * Defines an alias for the relation represented by this foreign key, which
161
+ * can be used in the ORM for more intuitive access to related models.
162
+ *
163
+ * @param name
164
+ * @returns
165
+ */
166
+ alias(name) {
167
+ this.foreignKey.relationAlias = name;
168
+ return this;
169
+ }
170
+ /**
171
+ * Defines an alias for the inverse relation represented by this foreign key.
172
+ *
173
+ * @param name
174
+ * @returns
175
+ */
176
+ inverseAlias(name) {
177
+ this.foreignKey.inverseRelationAlias = name;
178
+ return this;
179
+ }
180
+ /**
181
+ * Defines an alias for the foreign key field itself, which can be
182
+ * used in the ORM for more intuitive access to the foreign key value.
183
+ *
184
+ * @param fieldName
185
+ * @returns
186
+ */
187
+ as(fieldName) {
188
+ this.foreignKey.fieldAlias = fieldName;
189
+ return this;
190
+ }
191
+ };
192
+
120
193
  //#endregion
121
194
  //#region src/database/TableBuilder.ts
122
195
  /**
@@ -130,6 +203,7 @@ var TableBuilder = class {
130
203
  columns = [];
131
204
  dropColumnNames = [];
132
205
  indexes = [];
206
+ foreignKeys = [];
133
207
  latestColumnName;
134
208
  /**
135
209
  * Defines a primary key column in the table.
@@ -372,6 +446,32 @@ var TableBuilder = class {
372
446
  return this;
373
447
  }
374
448
  /**
449
+ * Defines a foreign key relation for an existing column.
450
+ *
451
+ * @param column The local foreign key column name.
452
+ * @returns A fluent foreign key builder.
453
+ */
454
+ foreignKey(column) {
455
+ const entry = {
456
+ column,
457
+ referencesTable: "",
458
+ referencesColumn: "id"
459
+ };
460
+ this.foreignKeys.push(entry);
461
+ return new ForeignKeyBuilder(entry);
462
+ }
463
+ /**
464
+ * Defines a foreign key relation for a column, using a
465
+ * conventional naming pattern.
466
+ *
467
+ * @param column
468
+ * @returns
469
+ */
470
+ foreign(column) {
471
+ const columnName = this.resolveColumn(column).name;
472
+ return this.foreignKey(columnName + (column ? "" : "Id"));
473
+ }
474
+ /**
375
475
  * Returns a deep copy of the defined columns for the table.
376
476
  *
377
477
  * @returns
@@ -399,6 +499,14 @@ var TableBuilder = class {
399
499
  }));
400
500
  }
401
501
  /**
502
+ * Returns a deep copy of the defined foreign keys for the table.
503
+ *
504
+ * @returns
505
+ */
506
+ getForeignKeys() {
507
+ return this.foreignKeys.map((foreignKey) => ({ ...foreignKey }));
508
+ }
509
+ /**
402
510
  * Defines a column in the table with the given name.
403
511
  *
404
512
  * @param name The name of the column.
@@ -461,7 +569,8 @@ var SchemaBuilder = class {
461
569
  type: "createTable",
462
570
  table,
463
571
  columns: builder.getColumns(),
464
- indexes: builder.getIndexes()
572
+ indexes: builder.getIndexes(),
573
+ foreignKeys: builder.getForeignKeys()
465
574
  });
466
575
  return this;
467
576
  }
@@ -480,7 +589,8 @@ var SchemaBuilder = class {
480
589
  table,
481
590
  addColumns: builder.getColumns(),
482
591
  dropColumns: builder.getDropColumns(),
483
- addIndexes: builder.getIndexes()
592
+ addIndexes: builder.getIndexes(),
593
+ addForeignKeys: builder.getForeignKeys()
484
594
  });
485
595
  return this;
486
596
  }
@@ -510,7 +620,8 @@ var SchemaBuilder = class {
510
620
  indexes: operation.indexes.map((index) => ({
511
621
  ...index,
512
622
  columns: [...index.columns]
513
- }))
623
+ })),
624
+ foreignKeys: operation.foreignKeys.map((foreignKey) => ({ ...foreignKey }))
514
625
  };
515
626
  if (operation.type === "alterTable") return {
516
627
  ...operation,
@@ -519,7 +630,8 @@ var SchemaBuilder = class {
519
630
  addIndexes: operation.addIndexes.map((index) => ({
520
631
  ...index,
521
632
  columns: [...index.columns]
522
- }))
633
+ })),
634
+ addForeignKeys: operation.addForeignKeys.map((foreignKey) => ({ ...foreignKey }))
523
635
  };
524
636
  return { ...operation };
525
637
  });
@@ -604,13 +716,139 @@ const buildFieldLine = (column) => {
604
716
  /**
605
717
  * Build a Prisma model-level @@index definition line.
606
718
  *
607
- * @param index
719
+ * @param index The schema index definition to convert to a Prisma \@\@index line.
608
720
  * @returns
609
721
  */
610
722
  const buildIndexLine = (index) => {
611
723
  return ` @@index([${index.columns.join(", ")}]${typeof index.name === "string" && index.name.trim().length > 0 ? `, name: "${index.name.replace(/"/g, "\\\"")}"` : ""})`;
612
724
  };
613
725
  /**
726
+ * Derive a relation field name from a foreign key column name by applying
727
+ * common conventions, such as removing "Id" suffixes and converting to camelCase.
728
+ *
729
+ * @param columnName The name of the foreign key column.
730
+ * @returns The derived relation field name.
731
+ */
732
+ const deriveRelationFieldName = (columnName) => {
733
+ const trimmed = columnName.trim();
734
+ if (!trimmed) return "relation";
735
+ if (trimmed.endsWith("Id") && trimmed.length > 2) {
736
+ const root = trimmed.slice(0, -2);
737
+ return `${root.charAt(0).toLowerCase()}${root.slice(1)}`;
738
+ }
739
+ if (trimmed.endsWith("_id") && trimmed.length > 3) return trimmed.slice(0, -3).replace(/_([a-zA-Z0-9])/g, (_, letter) => letter.toUpperCase());
740
+ return `${trimmed.charAt(0).toLowerCase()}${trimmed.slice(1)}`;
741
+ };
742
+ const pascalWords = (value) => {
743
+ return value.match(/[A-Z][a-z0-9]*/g) ?? [value];
744
+ };
745
+ /**
746
+ * Derive a relation name for the inverse side of a relation based on the
747
+ * source and target model names, using an explicit alias if provided or a
748
+ * convention of combining the target model name with the last segment of
749
+ * the source model name.
750
+ *
751
+ * @param sourceModelName The name of the source model in the relation.
752
+ * @param targetModelName The name of the target model in the relation.
753
+ * @param explicitAlias An optional explicit alias for the inverse relation.
754
+ * @returns The derived or explicit inverse relation alias.
755
+ */
756
+ const deriveInverseRelationAlias = (sourceModelName, targetModelName, explicitAlias) => {
757
+ if (explicitAlias && explicitAlias.trim().length > 0) return explicitAlias.trim();
758
+ const sourceWords = pascalWords(sourceModelName);
759
+ return `${sourceWords[sourceWords.length - 1] ?? sourceModelName}${targetModelName}`;
760
+ };
761
+ const deriveCollectionFieldName = (modelName) => {
762
+ if (!modelName) return "items";
763
+ const camel = `${modelName.charAt(0).toLowerCase()}${modelName.slice(1)}`;
764
+ if (camel.endsWith("s")) return `${camel}es`;
765
+ return `${camel}s`;
766
+ };
767
+ /**
768
+ * Format a SchemaForeignKeyAction value as a Prisma onDelete action string.
769
+ *
770
+ * @param action The foreign key action to format.
771
+ * @returns The corresponding Prisma onDelete action string.
772
+ */
773
+ const formatRelationAction = (action) => {
774
+ if (action === "cascade") return "Cascade";
775
+ if (action === "restrict") return "Restrict";
776
+ if (action === "setNull") return "SetNull";
777
+ if (action === "setDefault") return "SetDefault";
778
+ return "NoAction";
779
+ };
780
+ /**
781
+ * Build a Prisma relation field line based on a SchemaForeignKey
782
+ * definition, including relation name and onDelete action.
783
+ *
784
+ * @param foreignKey The foreign key definition to convert to a relation line.
785
+ * @returns The corresponding Prisma schema line for the relation field.
786
+ */
787
+ const buildRelationLine = (foreignKey) => {
788
+ if (!foreignKey.referencesTable.trim()) throw new ArkormException(`Foreign key [${foreignKey.column}] must define a referenced table.`);
789
+ if (!foreignKey.referencesColumn.trim()) throw new ArkormException(`Foreign key [${foreignKey.column}] must define a referenced column.`);
790
+ const fieldName = foreignKey.fieldAlias?.trim() || deriveRelationFieldName(foreignKey.column);
791
+ const targetModel = toModelName(foreignKey.referencesTable);
792
+ const relationName = foreignKey.relationAlias?.trim();
793
+ const relationPrefix = relationName ? `@relation("${relationName.replace(/"/g, "\\\"")}", ` : "@relation(";
794
+ const onDelete = foreignKey.onDelete ? `, onDelete: ${formatRelationAction(foreignKey.onDelete)}` : "";
795
+ return ` ${fieldName} ${targetModel} ${relationPrefix}fields: [${foreignKey.column}], references: [${foreignKey.referencesColumn}]${onDelete})`;
796
+ };
797
+ /**
798
+ * Build a Prisma relation field line for the inverse side of a relation, based
799
+ * on the source and target model names and the foreign key definition, using
800
+ * naming conventions and any explicit inverse alias provided.
801
+ *
802
+ * @param sourceModelName The name of the source model in the relation.
803
+ * @param targetModelName The name of the target model in the relation.
804
+ * @param foreignKey The foreign key definition for the relation.
805
+ * @returns The Prisma schema line for the inverse relation field.
806
+ */
807
+ const buildInverseRelationLine = (sourceModelName, targetModelName, foreignKey) => {
808
+ return ` ${deriveCollectionFieldName(sourceModelName)} ${sourceModelName}[] @relation("${deriveInverseRelationAlias(sourceModelName, targetModelName, foreignKey.inverseRelationAlias).replace(/"/g, "\\\"")}")`;
809
+ };
810
+ /**
811
+ * Inject a line into the body of a Prisma model block if it does not already
812
+ * exist, using a provided existence check function to determine if the line
813
+ * is already present.
814
+ *
815
+ * @param bodyLines The lines of the model block body to modify.
816
+ * @param line The line to inject if it does not already exist.
817
+ * @param exists A function that checks if a given line already exists in the body.
818
+ * @returns
819
+ */
820
+ const injectLineIntoModelBody = (bodyLines, line, exists) => {
821
+ if (bodyLines.some(exists)) return bodyLines;
822
+ const insertIndex = Math.max(1, bodyLines.length - 1);
823
+ bodyLines.splice(insertIndex, 0, line);
824
+ return bodyLines;
825
+ };
826
+ /**
827
+ * Apply inverse relation definitions to a Prisma schema string based on the
828
+ * foreign keys defined in a create or alter table operation, ensuring that
829
+ * related models have corresponding relation fields for bi-directional navigation.
830
+ *
831
+ * @param schema The Prisma schema string to modify.
832
+ * @param sourceModelName The name of the source model in the relation.
833
+ * @param foreignKeys An array of foreign key definitions to process.
834
+ * @returns The updated Prisma schema string with inverse relations applied.
835
+ */
836
+ const applyInverseRelations = (schema, sourceModelName, foreignKeys) => {
837
+ let nextSchema = schema;
838
+ for (const foreignKey of foreignKeys) {
839
+ const targetModel = findModelBlock(nextSchema, foreignKey.referencesTable);
840
+ if (!targetModel) continue;
841
+ const inverseLine = buildInverseRelationLine(sourceModelName, targetModel.modelName, foreignKey);
842
+ const targetBodyLines = targetModel.block.split("\n");
843
+ const fieldName = deriveCollectionFieldName(sourceModelName);
844
+ const fieldRegex = new RegExp(`^\\s*${escapeRegex(fieldName)}\\s+`);
845
+ injectLineIntoModelBody(targetBodyLines, inverseLine, (line) => fieldRegex.test(line));
846
+ const updatedTarget = targetBodyLines.join("\n");
847
+ nextSchema = `${nextSchema.slice(0, targetModel.start)}${updatedTarget}${nextSchema.slice(targetModel.end)}`;
848
+ }
849
+ return nextSchema;
850
+ };
851
+ /**
614
852
  * Build a Prisma model block string based on a SchemaTableCreateOperation, including
615
853
  * all fields and any necessary mapping.
616
854
  *
@@ -621,12 +859,14 @@ const buildModelBlock = (operation) => {
621
859
  const modelName = toModelName(operation.table);
622
860
  const mapped = operation.table !== modelName.toLowerCase();
623
861
  const fields = operation.columns.map(buildFieldLine);
862
+ const relations = (operation.foreignKeys ?? []).map(buildRelationLine);
624
863
  const metadata = [...(operation.indexes ?? []).map(buildIndexLine), ...mapped ? [` @@map("${(0, _h3ravel_support.str)(operation.table).snake()}")`] : []];
625
864
  return `model ${modelName} {\n${(metadata.length > 0 ? [
626
865
  ...fields,
866
+ ...relations,
627
867
  "",
628
868
  ...metadata
629
- ] : fields).join("\n")}\n}`;
869
+ ] : [...fields, ...relations]).join("\n")}\n}`;
630
870
  };
631
871
  /**
632
872
  * Find the Prisma model block in a schema string that corresponds to a given
@@ -676,7 +916,7 @@ const findModelBlock = (schema, table) => {
676
916
  const applyCreateTableOperation = (schema, operation) => {
677
917
  if (findModelBlock(schema, operation.table)) throw new ArkormException(`Prisma model for table [${operation.table}] already exists.`);
678
918
  const block = buildModelBlock(operation);
679
- return `${schema.trimEnd()}\n\n${block}\n`;
919
+ return applyInverseRelations(`${schema.trimEnd()}\n\n${block}\n`, toModelName(operation.table), operation.foreignKeys ?? []);
680
920
  };
681
921
  /**
682
922
  * Apply an alter table operation to a Prisma schema string, modifying the model
@@ -713,8 +953,13 @@ const applyAlterTableOperation = (schema, operation) => {
713
953
  const insertIndex = Math.max(1, bodyLines.length - 1);
714
954
  bodyLines.splice(insertIndex, 0, indexLine);
715
955
  });
956
+ for (const foreignKey of operation.addForeignKeys ?? []) {
957
+ const relationLine = buildRelationLine(foreignKey);
958
+ const relationRegex = new RegExp(`^\\s*${escapeRegex(foreignKey.fieldAlias?.trim() || deriveRelationFieldName(foreignKey.column))}\\s+`);
959
+ injectLineIntoModelBody(bodyLines, relationLine, (line) => relationRegex.test(line));
960
+ }
716
961
  block = bodyLines.join("\n");
717
- return `${schema.slice(0, model.start)}${block}${schema.slice(model.end)}`;
962
+ return applyInverseRelations(`${schema.slice(0, model.start)}${block}${schema.slice(model.end)}`, model.modelName, operation.addForeignKeys ?? []);
718
963
  };
719
964
  /**
720
965
  * Apply a drop table operation to a Prisma schema string, removing the model block
@@ -4874,6 +5119,7 @@ var Model = class Model {
4874
5119
  exports.ArkormCollection = ArkormCollection;
4875
5120
  exports.ArkormException = ArkormException;
4876
5121
  exports.CliApp = CliApp;
5122
+ exports.ForeignKeyBuilder = ForeignKeyBuilder;
4877
5123
  exports.InitCommand = InitCommand;
4878
5124
  exports.InlineFactory = InlineFactory;
4879
5125
  exports.LengthAwarePaginator = LengthAwarePaginator;
@@ -4904,18 +5150,24 @@ exports.applyMigrationToPrismaSchema = applyMigrationToPrismaSchema;
4904
5150
  exports.applyOperationsToPrismaSchema = applyOperationsToPrismaSchema;
4905
5151
  exports.buildFieldLine = buildFieldLine;
4906
5152
  exports.buildIndexLine = buildIndexLine;
5153
+ exports.buildInverseRelationLine = buildInverseRelationLine;
4907
5154
  exports.buildMigrationSource = buildMigrationSource;
4908
5155
  exports.buildModelBlock = buildModelBlock;
5156
+ exports.buildRelationLine = buildRelationLine;
4909
5157
  exports.configureArkormRuntime = configureArkormRuntime;
4910
5158
  exports.createMigrationTimestamp = createMigrationTimestamp;
4911
5159
  exports.createPrismaAdapter = createPrismaAdapter;
4912
5160
  exports.createPrismaDelegateMap = createPrismaDelegateMap;
4913
5161
  exports.defineConfig = defineConfig;
4914
5162
  exports.defineFactory = defineFactory;
5163
+ exports.deriveCollectionFieldName = deriveCollectionFieldName;
5164
+ exports.deriveInverseRelationAlias = deriveInverseRelationAlias;
5165
+ exports.deriveRelationFieldName = deriveRelationFieldName;
4915
5166
  exports.ensureArkormConfigLoading = ensureArkormConfigLoading;
4916
5167
  exports.escapeRegex = escapeRegex;
4917
5168
  exports.findModelBlock = findModelBlock;
4918
5169
  exports.formatDefaultValue = formatDefaultValue;
5170
+ exports.formatRelationAction = formatRelationAction;
4919
5171
  exports.generateMigrationFile = generateMigrationFile;
4920
5172
  exports.getDefaultStubsPath = getDefaultStubsPath;
4921
5173
  exports.getMigrationPlan = getMigrationPlan;
package/dist/index.d.cts CHANGED
@@ -27,11 +27,22 @@ interface SchemaIndex {
27
27
  columns: string[];
28
28
  name?: string;
29
29
  }
30
+ type SchemaForeignKeyAction = 'cascade' | 'restrict' | 'setNull' | 'noAction' | 'setDefault';
31
+ interface SchemaForeignKey {
32
+ column: string;
33
+ referencesTable: string;
34
+ referencesColumn: string;
35
+ onDelete?: SchemaForeignKeyAction;
36
+ relationAlias?: string;
37
+ inverseRelationAlias?: string;
38
+ fieldAlias?: string;
39
+ }
30
40
  interface SchemaTableCreateOperation {
31
41
  type: 'createTable';
32
42
  table: string;
33
43
  columns: SchemaColumn[];
34
44
  indexes: SchemaIndex[];
45
+ foreignKeys: SchemaForeignKey[];
35
46
  }
36
47
  interface SchemaTableAlterOperation {
37
48
  type: 'alterTable';
@@ -39,6 +50,7 @@ interface SchemaTableAlterOperation {
39
50
  addColumns: SchemaColumn[];
40
51
  dropColumns: string[];
41
52
  addIndexes: SchemaIndex[];
53
+ addForeignKeys: SchemaForeignKey[];
42
54
  }
43
55
  interface SchemaTableDropOperation {
44
56
  type: 'dropTable';
@@ -2286,6 +2298,60 @@ declare class SeedCommand extends Command<CliApp> {
2286
2298
  private loadSeederClassesFromFile;
2287
2299
  }
2288
2300
  //#endregion
2301
+ //#region src/database/ForeignKeyBuilder.d.ts
2302
+ /**
2303
+ * The ForeignKeyBuilder class provides a fluent interface for defining
2304
+ * foreign key constraints in a migration. It allows you to specify
2305
+ * the referenced table and column, as well as actions to take on
2306
+ * delete and aliases for the relation.
2307
+ *
2308
+ * @author Legacy (3m1n3nc3)
2309
+ * @since 0.2.2
2310
+ */
2311
+ declare class ForeignKeyBuilder {
2312
+ private readonly foreignKey;
2313
+ constructor(foreignKey: SchemaForeignKey);
2314
+ /**
2315
+ * Defines the referenced table and column for this foreign key constraint.
2316
+ *
2317
+ * @param table
2318
+ * @param column
2319
+ * @returns
2320
+ */
2321
+ references(table: string, column: string): this;
2322
+ /**
2323
+ * Defines the action to take when a referenced record is deleted, such
2324
+ * as "CASCADE", "SET NULL", or "RESTRICT".
2325
+ *
2326
+ * @param action
2327
+ * @returns
2328
+ */
2329
+ onDelete(action: SchemaForeignKeyAction): this;
2330
+ /**
2331
+ * Defines an alias for the relation represented by this foreign key, which
2332
+ * can be used in the ORM for more intuitive access to related models.
2333
+ *
2334
+ * @param name
2335
+ * @returns
2336
+ */
2337
+ alias(name: string): this;
2338
+ /**
2339
+ * Defines an alias for the inverse relation represented by this foreign key.
2340
+ *
2341
+ * @param name
2342
+ * @returns
2343
+ */
2344
+ inverseAlias(name: string): this;
2345
+ /**
2346
+ * Defines an alias for the foreign key field itself, which can be
2347
+ * used in the ORM for more intuitive access to the foreign key value.
2348
+ *
2349
+ * @param fieldName
2350
+ * @returns
2351
+ */
2352
+ as(fieldName: string): this;
2353
+ }
2354
+ //#endregion
2289
2355
  //#region src/database/TableBuilder.d.ts
2290
2356
  /**
2291
2357
  * The TableBuilder class provides a fluent interface for defining
@@ -2298,6 +2364,7 @@ declare class TableBuilder {
2298
2364
  private readonly columns;
2299
2365
  private readonly dropColumnNames;
2300
2366
  private readonly indexes;
2367
+ private readonly foreignKeys;
2301
2368
  private latestColumnName;
2302
2369
  /**
2303
2370
  * Defines a primary key column in the table.
@@ -2475,6 +2542,21 @@ declare class TableBuilder {
2475
2542
  * @returns The current TableBuilder instance for chaining.
2476
2543
  */
2477
2544
  index(columns?: string | string[], name?: string): this;
2545
+ /**
2546
+ * Defines a foreign key relation for an existing column.
2547
+ *
2548
+ * @param column The local foreign key column name.
2549
+ * @returns A fluent foreign key builder.
2550
+ */
2551
+ foreignKey(column: string): ForeignKeyBuilder;
2552
+ /**
2553
+ * Defines a foreign key relation for a column, using a
2554
+ * conventional naming pattern.
2555
+ *
2556
+ * @param column
2557
+ * @returns
2558
+ */
2559
+ foreign(column?: string): ForeignKeyBuilder;
2478
2560
  /**
2479
2561
  * Returns a deep copy of the defined columns for the table.
2480
2562
  *
@@ -2493,6 +2575,12 @@ declare class TableBuilder {
2493
2575
  * @returns
2494
2576
  */
2495
2577
  getIndexes(): SchemaIndex[];
2578
+ /**
2579
+ * Returns a deep copy of the defined foreign keys for the table.
2580
+ *
2581
+ * @returns
2582
+ */
2583
+ getForeignKeys(): SchemaForeignKey[];
2496
2584
  /**
2497
2585
  * Defines a column in the table with the given name.
2498
2586
  *
@@ -2683,10 +2771,57 @@ declare const buildFieldLine: (column: SchemaColumn) => string;
2683
2771
  /**
2684
2772
  * Build a Prisma model-level @@index definition line.
2685
2773
  *
2686
- * @param index
2774
+ * @param index The schema index definition to convert to a Prisma \@\@index line.
2687
2775
  * @returns
2688
2776
  */
2689
2777
  declare const buildIndexLine: (index: SchemaIndex) => string;
2778
+ /**
2779
+ * Derive a relation field name from a foreign key column name by applying
2780
+ * common conventions, such as removing "Id" suffixes and converting to camelCase.
2781
+ *
2782
+ * @param columnName The name of the foreign key column.
2783
+ * @returns The derived relation field name.
2784
+ */
2785
+ declare const deriveRelationFieldName: (columnName: string) => string;
2786
+ /**
2787
+ * Derive a relation name for the inverse side of a relation based on the
2788
+ * source and target model names, using an explicit alias if provided or a
2789
+ * convention of combining the target model name with the last segment of
2790
+ * the source model name.
2791
+ *
2792
+ * @param sourceModelName The name of the source model in the relation.
2793
+ * @param targetModelName The name of the target model in the relation.
2794
+ * @param explicitAlias An optional explicit alias for the inverse relation.
2795
+ * @returns The derived or explicit inverse relation alias.
2796
+ */
2797
+ declare const deriveInverseRelationAlias: (sourceModelName: string, targetModelName: string, explicitAlias?: string) => string;
2798
+ declare const deriveCollectionFieldName: (modelName: string) => string;
2799
+ /**
2800
+ * Format a SchemaForeignKeyAction value as a Prisma onDelete action string.
2801
+ *
2802
+ * @param action The foreign key action to format.
2803
+ * @returns The corresponding Prisma onDelete action string.
2804
+ */
2805
+ declare const formatRelationAction: (action: SchemaForeignKeyAction) => string;
2806
+ /**
2807
+ * Build a Prisma relation field line based on a SchemaForeignKey
2808
+ * definition, including relation name and onDelete action.
2809
+ *
2810
+ * @param foreignKey The foreign key definition to convert to a relation line.
2811
+ * @returns The corresponding Prisma schema line for the relation field.
2812
+ */
2813
+ declare const buildRelationLine: (foreignKey: SchemaForeignKey) => string;
2814
+ /**
2815
+ * Build a Prisma relation field line for the inverse side of a relation, based
2816
+ * on the source and target model names and the foreign key definition, using
2817
+ * naming conventions and any explicit inverse alias provided.
2818
+ *
2819
+ * @param sourceModelName The name of the source model in the relation.
2820
+ * @param targetModelName The name of the target model in the relation.
2821
+ * @param foreignKey The foreign key definition for the relation.
2822
+ * @returns The Prisma schema line for the inverse relation field.
2823
+ */
2824
+ declare const buildInverseRelationLine: (sourceModelName: string, targetModelName: string, foreignKey: SchemaForeignKey) => string;
2690
2825
  /**
2691
2826
  * Build a Prisma model block string based on a SchemaTableCreateOperation, including
2692
2827
  * all fields and any necessary mapping.
@@ -2945,4 +3080,4 @@ declare class URLDriver {
2945
3080
  url(page: number): string;
2946
3081
  }
2947
3082
  //#endregion
2948
- export { ArkormCollection, ArkormException, CliApp, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, Migration, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, PrismaDelegateMap, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, SeederCallArgument, SeederConstructor, SeederInput, TableBuilder, URLDriver, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildFieldLine, buildIndexLine, buildMigrationSource, buildModelBlock, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, ensureArkormConfigLoading, escapeRegex, findModelBlock, formatDefaultValue, generateMigrationFile, getDefaultStubsPath, getMigrationPlan, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, loadArkormConfig, pad, resetArkormRuntimeForTests, resolveCast, resolveMigrationClassName, resolvePrismaType, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName };
3083
+ export { ArkormCollection, ArkormException, CliApp, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, Migration, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, PrismaDelegateMap, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, SeederCallArgument, SeederConstructor, SeederInput, TableBuilder, URLDriver, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationSource, buildModelBlock, buildRelationLine, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationFieldName, ensureArkormConfigLoading, escapeRegex, findModelBlock, formatDefaultValue, formatRelationAction, generateMigrationFile, getDefaultStubsPath, getMigrationPlan, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, loadArkormConfig, pad, resetArkormRuntimeForTests, resolveCast, resolveMigrationClassName, resolvePrismaType, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName };