arkormx 0.2.1 → 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/cli.mjs +269 -12
- package/dist/index.cjs +276 -12
- package/dist/index.d.cts +149 -6
- package/dist/index.d.mts +149 -6
- package/dist/index.mjs +270 -13
- package/package.json +1 -1
package/dist/index.d.mts
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.
|
|
@@ -2351,7 +2418,7 @@ declare class TableBuilder {
|
|
|
2351
2418
|
*
|
|
2352
2419
|
* @param name The name of the integer column.
|
|
2353
2420
|
* @param options Additional options for the integer column.
|
|
2354
|
-
* @returns
|
|
2421
|
+
* @returns The current TableBuilder instance for chaining.
|
|
2355
2422
|
*/
|
|
2356
2423
|
integer(name: string, options?: Partial<SchemaColumn>): this;
|
|
2357
2424
|
/**
|
|
@@ -2359,7 +2426,7 @@ declare class TableBuilder {
|
|
|
2359
2426
|
*
|
|
2360
2427
|
* @param name The name of the big integer column.
|
|
2361
2428
|
* @param options Additional options for the big integer column.
|
|
2362
|
-
* @returns
|
|
2429
|
+
* @returns The current TableBuilder instance for chaining.
|
|
2363
2430
|
*/
|
|
2364
2431
|
bigInteger(name: string, options?: Partial<SchemaColumn>): this;
|
|
2365
2432
|
/**
|
|
@@ -2367,15 +2434,23 @@ declare class TableBuilder {
|
|
|
2367
2434
|
*
|
|
2368
2435
|
* @param name The name of the float column.
|
|
2369
2436
|
* @param options Additional options for the float column.
|
|
2370
|
-
* @returns
|
|
2437
|
+
* @returns The current TableBuilder instance for chaining.
|
|
2371
2438
|
*/
|
|
2372
2439
|
float(name: string, options?: Partial<SchemaColumn>): this;
|
|
2440
|
+
/**
|
|
2441
|
+
* Marks a column as unique in the table.
|
|
2442
|
+
*
|
|
2443
|
+
* @param name Optional explicit column name.
|
|
2444
|
+
* When omitted, applies to the latest defined column.
|
|
2445
|
+
* @returns The current TableBuilder instance for chaining.
|
|
2446
|
+
*/
|
|
2447
|
+
unique(name?: string): this;
|
|
2373
2448
|
/**
|
|
2374
2449
|
* Defines a boolean column in the table.
|
|
2375
2450
|
*
|
|
2376
2451
|
* @param name The name of the boolean column.
|
|
2377
2452
|
* @param options Additional options for the boolean column.
|
|
2378
|
-
* @returns
|
|
2453
|
+
* @returns The current TableBuilder instance for chaining.
|
|
2379
2454
|
*/
|
|
2380
2455
|
boolean(name: string, options?: Partial<SchemaColumn>): this;
|
|
2381
2456
|
/**
|
|
@@ -2467,6 +2542,21 @@ declare class TableBuilder {
|
|
|
2467
2542
|
* @returns The current TableBuilder instance for chaining.
|
|
2468
2543
|
*/
|
|
2469
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;
|
|
2470
2560
|
/**
|
|
2471
2561
|
* Returns a deep copy of the defined columns for the table.
|
|
2472
2562
|
*
|
|
@@ -2485,6 +2575,12 @@ declare class TableBuilder {
|
|
|
2485
2575
|
* @returns
|
|
2486
2576
|
*/
|
|
2487
2577
|
getIndexes(): SchemaIndex[];
|
|
2578
|
+
/**
|
|
2579
|
+
* Returns a deep copy of the defined foreign keys for the table.
|
|
2580
|
+
*
|
|
2581
|
+
* @returns
|
|
2582
|
+
*/
|
|
2583
|
+
getForeignKeys(): SchemaForeignKey[];
|
|
2488
2584
|
/**
|
|
2489
2585
|
* Defines a column in the table with the given name.
|
|
2490
2586
|
*
|
|
@@ -2675,10 +2771,57 @@ declare const buildFieldLine: (column: SchemaColumn) => string;
|
|
|
2675
2771
|
/**
|
|
2676
2772
|
* Build a Prisma model-level @@index definition line.
|
|
2677
2773
|
*
|
|
2678
|
-
* @param index
|
|
2774
|
+
* @param index The schema index definition to convert to a Prisma \@\@index line.
|
|
2679
2775
|
* @returns
|
|
2680
2776
|
*/
|
|
2681
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;
|
|
2682
2825
|
/**
|
|
2683
2826
|
* Build a Prisma model block string based on a SchemaTableCreateOperation, including
|
|
2684
2827
|
* all fields and any necessary mapping.
|
|
@@ -2937,4 +3080,4 @@ declare class URLDriver {
|
|
|
2937
3080
|
url(page: number): string;
|
|
2938
3081
|
}
|
|
2939
3082
|
//#endregion
|
|
2940
|
-
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 };
|
package/dist/index.mjs
CHANGED
|
@@ -88,6 +88,79 @@ var ArkormException = class extends Error {
|
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/database/ForeignKeyBuilder.ts
|
|
93
|
+
/**
|
|
94
|
+
* The ForeignKeyBuilder class provides a fluent interface for defining
|
|
95
|
+
* foreign key constraints in a migration. It allows you to specify
|
|
96
|
+
* the referenced table and column, as well as actions to take on
|
|
97
|
+
* delete and aliases for the relation.
|
|
98
|
+
*
|
|
99
|
+
* @author Legacy (3m1n3nc3)
|
|
100
|
+
* @since 0.2.2
|
|
101
|
+
*/
|
|
102
|
+
var ForeignKeyBuilder = class {
|
|
103
|
+
foreignKey;
|
|
104
|
+
constructor(foreignKey) {
|
|
105
|
+
this.foreignKey = foreignKey;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Defines the referenced table and column for this foreign key constraint.
|
|
109
|
+
*
|
|
110
|
+
* @param table
|
|
111
|
+
* @param column
|
|
112
|
+
* @returns
|
|
113
|
+
*/
|
|
114
|
+
references(table, column) {
|
|
115
|
+
this.foreignKey.referencesTable = table;
|
|
116
|
+
this.foreignKey.referencesColumn = column;
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Defines the action to take when a referenced record is deleted, such
|
|
121
|
+
* as "CASCADE", "SET NULL", or "RESTRICT".
|
|
122
|
+
*
|
|
123
|
+
* @param action
|
|
124
|
+
* @returns
|
|
125
|
+
*/
|
|
126
|
+
onDelete(action) {
|
|
127
|
+
this.foreignKey.onDelete = action;
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Defines an alias for the relation represented by this foreign key, which
|
|
132
|
+
* can be used in the ORM for more intuitive access to related models.
|
|
133
|
+
*
|
|
134
|
+
* @param name
|
|
135
|
+
* @returns
|
|
136
|
+
*/
|
|
137
|
+
alias(name) {
|
|
138
|
+
this.foreignKey.relationAlias = name;
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Defines an alias for the inverse relation represented by this foreign key.
|
|
143
|
+
*
|
|
144
|
+
* @param name
|
|
145
|
+
* @returns
|
|
146
|
+
*/
|
|
147
|
+
inverseAlias(name) {
|
|
148
|
+
this.foreignKey.inverseRelationAlias = name;
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Defines an alias for the foreign key field itself, which can be
|
|
153
|
+
* used in the ORM for more intuitive access to the foreign key value.
|
|
154
|
+
*
|
|
155
|
+
* @param fieldName
|
|
156
|
+
* @returns
|
|
157
|
+
*/
|
|
158
|
+
as(fieldName) {
|
|
159
|
+
this.foreignKey.fieldAlias = fieldName;
|
|
160
|
+
return this;
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
91
164
|
//#endregion
|
|
92
165
|
//#region src/database/TableBuilder.ts
|
|
93
166
|
/**
|
|
@@ -101,6 +174,7 @@ var TableBuilder = class {
|
|
|
101
174
|
columns = [];
|
|
102
175
|
dropColumnNames = [];
|
|
103
176
|
indexes = [];
|
|
177
|
+
foreignKeys = [];
|
|
104
178
|
latestColumnName;
|
|
105
179
|
/**
|
|
106
180
|
* Defines a primary key column in the table.
|
|
@@ -165,7 +239,7 @@ var TableBuilder = class {
|
|
|
165
239
|
*
|
|
166
240
|
* @param name The name of the integer column.
|
|
167
241
|
* @param options Additional options for the integer column.
|
|
168
|
-
* @returns
|
|
242
|
+
* @returns The current TableBuilder instance for chaining.
|
|
169
243
|
*/
|
|
170
244
|
integer(name, options = {}) {
|
|
171
245
|
return this.column(name, "integer", options);
|
|
@@ -175,7 +249,7 @@ var TableBuilder = class {
|
|
|
175
249
|
*
|
|
176
250
|
* @param name The name of the big integer column.
|
|
177
251
|
* @param options Additional options for the big integer column.
|
|
178
|
-
* @returns
|
|
252
|
+
* @returns The current TableBuilder instance for chaining.
|
|
179
253
|
*/
|
|
180
254
|
bigInteger(name, options = {}) {
|
|
181
255
|
return this.column(name, "bigInteger", options);
|
|
@@ -185,17 +259,29 @@ var TableBuilder = class {
|
|
|
185
259
|
*
|
|
186
260
|
* @param name The name of the float column.
|
|
187
261
|
* @param options Additional options for the float column.
|
|
188
|
-
* @returns
|
|
262
|
+
* @returns The current TableBuilder instance for chaining.
|
|
189
263
|
*/
|
|
190
264
|
float(name, options = {}) {
|
|
191
265
|
return this.column(name, "float", options);
|
|
192
266
|
}
|
|
193
267
|
/**
|
|
268
|
+
* Marks a column as unique in the table.
|
|
269
|
+
*
|
|
270
|
+
* @param name Optional explicit column name.
|
|
271
|
+
* When omitted, applies to the latest defined column.
|
|
272
|
+
* @returns The current TableBuilder instance for chaining.
|
|
273
|
+
*/
|
|
274
|
+
unique(name) {
|
|
275
|
+
const column = this.resolveColumn(name);
|
|
276
|
+
column.unique = true;
|
|
277
|
+
return this;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
194
280
|
* Defines a boolean column in the table.
|
|
195
281
|
*
|
|
196
282
|
* @param name The name of the boolean column.
|
|
197
283
|
* @param options Additional options for the boolean column.
|
|
198
|
-
* @returns
|
|
284
|
+
* @returns The current TableBuilder instance for chaining.
|
|
199
285
|
*/
|
|
200
286
|
boolean(name, options = {}) {
|
|
201
287
|
return this.column(name, "boolean", options);
|
|
@@ -331,6 +417,32 @@ var TableBuilder = class {
|
|
|
331
417
|
return this;
|
|
332
418
|
}
|
|
333
419
|
/**
|
|
420
|
+
* Defines a foreign key relation for an existing column.
|
|
421
|
+
*
|
|
422
|
+
* @param column The local foreign key column name.
|
|
423
|
+
* @returns A fluent foreign key builder.
|
|
424
|
+
*/
|
|
425
|
+
foreignKey(column) {
|
|
426
|
+
const entry = {
|
|
427
|
+
column,
|
|
428
|
+
referencesTable: "",
|
|
429
|
+
referencesColumn: "id"
|
|
430
|
+
};
|
|
431
|
+
this.foreignKeys.push(entry);
|
|
432
|
+
return new ForeignKeyBuilder(entry);
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Defines a foreign key relation for a column, using a
|
|
436
|
+
* conventional naming pattern.
|
|
437
|
+
*
|
|
438
|
+
* @param column
|
|
439
|
+
* @returns
|
|
440
|
+
*/
|
|
441
|
+
foreign(column) {
|
|
442
|
+
const columnName = this.resolveColumn(column).name;
|
|
443
|
+
return this.foreignKey(columnName + (column ? "" : "Id"));
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
334
446
|
* Returns a deep copy of the defined columns for the table.
|
|
335
447
|
*
|
|
336
448
|
* @returns
|
|
@@ -358,6 +470,14 @@ var TableBuilder = class {
|
|
|
358
470
|
}));
|
|
359
471
|
}
|
|
360
472
|
/**
|
|
473
|
+
* Returns a deep copy of the defined foreign keys for the table.
|
|
474
|
+
*
|
|
475
|
+
* @returns
|
|
476
|
+
*/
|
|
477
|
+
getForeignKeys() {
|
|
478
|
+
return this.foreignKeys.map((foreignKey) => ({ ...foreignKey }));
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
361
481
|
* Defines a column in the table with the given name.
|
|
362
482
|
*
|
|
363
483
|
* @param name The name of the column.
|
|
@@ -420,7 +540,8 @@ var SchemaBuilder = class {
|
|
|
420
540
|
type: "createTable",
|
|
421
541
|
table,
|
|
422
542
|
columns: builder.getColumns(),
|
|
423
|
-
indexes: builder.getIndexes()
|
|
543
|
+
indexes: builder.getIndexes(),
|
|
544
|
+
foreignKeys: builder.getForeignKeys()
|
|
424
545
|
});
|
|
425
546
|
return this;
|
|
426
547
|
}
|
|
@@ -439,7 +560,8 @@ var SchemaBuilder = class {
|
|
|
439
560
|
table,
|
|
440
561
|
addColumns: builder.getColumns(),
|
|
441
562
|
dropColumns: builder.getDropColumns(),
|
|
442
|
-
addIndexes: builder.getIndexes()
|
|
563
|
+
addIndexes: builder.getIndexes(),
|
|
564
|
+
addForeignKeys: builder.getForeignKeys()
|
|
443
565
|
});
|
|
444
566
|
return this;
|
|
445
567
|
}
|
|
@@ -469,7 +591,8 @@ var SchemaBuilder = class {
|
|
|
469
591
|
indexes: operation.indexes.map((index) => ({
|
|
470
592
|
...index,
|
|
471
593
|
columns: [...index.columns]
|
|
472
|
-
}))
|
|
594
|
+
})),
|
|
595
|
+
foreignKeys: operation.foreignKeys.map((foreignKey) => ({ ...foreignKey }))
|
|
473
596
|
};
|
|
474
597
|
if (operation.type === "alterTable") return {
|
|
475
598
|
...operation,
|
|
@@ -478,7 +601,8 @@ var SchemaBuilder = class {
|
|
|
478
601
|
addIndexes: operation.addIndexes.map((index) => ({
|
|
479
602
|
...index,
|
|
480
603
|
columns: [...index.columns]
|
|
481
|
-
}))
|
|
604
|
+
})),
|
|
605
|
+
addForeignKeys: operation.addForeignKeys.map((foreignKey) => ({ ...foreignKey }))
|
|
482
606
|
};
|
|
483
607
|
return { ...operation };
|
|
484
608
|
});
|
|
@@ -563,13 +687,139 @@ const buildFieldLine = (column) => {
|
|
|
563
687
|
/**
|
|
564
688
|
* Build a Prisma model-level @@index definition line.
|
|
565
689
|
*
|
|
566
|
-
* @param index
|
|
690
|
+
* @param index The schema index definition to convert to a Prisma \@\@index line.
|
|
567
691
|
* @returns
|
|
568
692
|
*/
|
|
569
693
|
const buildIndexLine = (index) => {
|
|
570
694
|
return ` @@index([${index.columns.join(", ")}]${typeof index.name === "string" && index.name.trim().length > 0 ? `, name: "${index.name.replace(/"/g, "\\\"")}"` : ""})`;
|
|
571
695
|
};
|
|
572
696
|
/**
|
|
697
|
+
* Derive a relation field name from a foreign key column name by applying
|
|
698
|
+
* common conventions, such as removing "Id" suffixes and converting to camelCase.
|
|
699
|
+
*
|
|
700
|
+
* @param columnName The name of the foreign key column.
|
|
701
|
+
* @returns The derived relation field name.
|
|
702
|
+
*/
|
|
703
|
+
const deriveRelationFieldName = (columnName) => {
|
|
704
|
+
const trimmed = columnName.trim();
|
|
705
|
+
if (!trimmed) return "relation";
|
|
706
|
+
if (trimmed.endsWith("Id") && trimmed.length > 2) {
|
|
707
|
+
const root = trimmed.slice(0, -2);
|
|
708
|
+
return `${root.charAt(0).toLowerCase()}${root.slice(1)}`;
|
|
709
|
+
}
|
|
710
|
+
if (trimmed.endsWith("_id") && trimmed.length > 3) return trimmed.slice(0, -3).replace(/_([a-zA-Z0-9])/g, (_, letter) => letter.toUpperCase());
|
|
711
|
+
return `${trimmed.charAt(0).toLowerCase()}${trimmed.slice(1)}`;
|
|
712
|
+
};
|
|
713
|
+
const pascalWords = (value) => {
|
|
714
|
+
return value.match(/[A-Z][a-z0-9]*/g) ?? [value];
|
|
715
|
+
};
|
|
716
|
+
/**
|
|
717
|
+
* Derive a relation name for the inverse side of a relation based on the
|
|
718
|
+
* source and target model names, using an explicit alias if provided or a
|
|
719
|
+
* convention of combining the target model name with the last segment of
|
|
720
|
+
* the source model name.
|
|
721
|
+
*
|
|
722
|
+
* @param sourceModelName The name of the source model in the relation.
|
|
723
|
+
* @param targetModelName The name of the target model in the relation.
|
|
724
|
+
* @param explicitAlias An optional explicit alias for the inverse relation.
|
|
725
|
+
* @returns The derived or explicit inverse relation alias.
|
|
726
|
+
*/
|
|
727
|
+
const deriveInverseRelationAlias = (sourceModelName, targetModelName, explicitAlias) => {
|
|
728
|
+
if (explicitAlias && explicitAlias.trim().length > 0) return explicitAlias.trim();
|
|
729
|
+
const sourceWords = pascalWords(sourceModelName);
|
|
730
|
+
return `${sourceWords[sourceWords.length - 1] ?? sourceModelName}${targetModelName}`;
|
|
731
|
+
};
|
|
732
|
+
const deriveCollectionFieldName = (modelName) => {
|
|
733
|
+
if (!modelName) return "items";
|
|
734
|
+
const camel = `${modelName.charAt(0).toLowerCase()}${modelName.slice(1)}`;
|
|
735
|
+
if (camel.endsWith("s")) return `${camel}es`;
|
|
736
|
+
return `${camel}s`;
|
|
737
|
+
};
|
|
738
|
+
/**
|
|
739
|
+
* Format a SchemaForeignKeyAction value as a Prisma onDelete action string.
|
|
740
|
+
*
|
|
741
|
+
* @param action The foreign key action to format.
|
|
742
|
+
* @returns The corresponding Prisma onDelete action string.
|
|
743
|
+
*/
|
|
744
|
+
const formatRelationAction = (action) => {
|
|
745
|
+
if (action === "cascade") return "Cascade";
|
|
746
|
+
if (action === "restrict") return "Restrict";
|
|
747
|
+
if (action === "setNull") return "SetNull";
|
|
748
|
+
if (action === "setDefault") return "SetDefault";
|
|
749
|
+
return "NoAction";
|
|
750
|
+
};
|
|
751
|
+
/**
|
|
752
|
+
* Build a Prisma relation field line based on a SchemaForeignKey
|
|
753
|
+
* definition, including relation name and onDelete action.
|
|
754
|
+
*
|
|
755
|
+
* @param foreignKey The foreign key definition to convert to a relation line.
|
|
756
|
+
* @returns The corresponding Prisma schema line for the relation field.
|
|
757
|
+
*/
|
|
758
|
+
const buildRelationLine = (foreignKey) => {
|
|
759
|
+
if (!foreignKey.referencesTable.trim()) throw new ArkormException(`Foreign key [${foreignKey.column}] must define a referenced table.`);
|
|
760
|
+
if (!foreignKey.referencesColumn.trim()) throw new ArkormException(`Foreign key [${foreignKey.column}] must define a referenced column.`);
|
|
761
|
+
const fieldName = foreignKey.fieldAlias?.trim() || deriveRelationFieldName(foreignKey.column);
|
|
762
|
+
const targetModel = toModelName(foreignKey.referencesTable);
|
|
763
|
+
const relationName = foreignKey.relationAlias?.trim();
|
|
764
|
+
const relationPrefix = relationName ? `@relation("${relationName.replace(/"/g, "\\\"")}", ` : "@relation(";
|
|
765
|
+
const onDelete = foreignKey.onDelete ? `, onDelete: ${formatRelationAction(foreignKey.onDelete)}` : "";
|
|
766
|
+
return ` ${fieldName} ${targetModel} ${relationPrefix}fields: [${foreignKey.column}], references: [${foreignKey.referencesColumn}]${onDelete})`;
|
|
767
|
+
};
|
|
768
|
+
/**
|
|
769
|
+
* Build a Prisma relation field line for the inverse side of a relation, based
|
|
770
|
+
* on the source and target model names and the foreign key definition, using
|
|
771
|
+
* naming conventions and any explicit inverse alias provided.
|
|
772
|
+
*
|
|
773
|
+
* @param sourceModelName The name of the source model in the relation.
|
|
774
|
+
* @param targetModelName The name of the target model in the relation.
|
|
775
|
+
* @param foreignKey The foreign key definition for the relation.
|
|
776
|
+
* @returns The Prisma schema line for the inverse relation field.
|
|
777
|
+
*/
|
|
778
|
+
const buildInverseRelationLine = (sourceModelName, targetModelName, foreignKey) => {
|
|
779
|
+
return ` ${deriveCollectionFieldName(sourceModelName)} ${sourceModelName}[] @relation("${deriveInverseRelationAlias(sourceModelName, targetModelName, foreignKey.inverseRelationAlias).replace(/"/g, "\\\"")}")`;
|
|
780
|
+
};
|
|
781
|
+
/**
|
|
782
|
+
* Inject a line into the body of a Prisma model block if it does not already
|
|
783
|
+
* exist, using a provided existence check function to determine if the line
|
|
784
|
+
* is already present.
|
|
785
|
+
*
|
|
786
|
+
* @param bodyLines The lines of the model block body to modify.
|
|
787
|
+
* @param line The line to inject if it does not already exist.
|
|
788
|
+
* @param exists A function that checks if a given line already exists in the body.
|
|
789
|
+
* @returns
|
|
790
|
+
*/
|
|
791
|
+
const injectLineIntoModelBody = (bodyLines, line, exists) => {
|
|
792
|
+
if (bodyLines.some(exists)) return bodyLines;
|
|
793
|
+
const insertIndex = Math.max(1, bodyLines.length - 1);
|
|
794
|
+
bodyLines.splice(insertIndex, 0, line);
|
|
795
|
+
return bodyLines;
|
|
796
|
+
};
|
|
797
|
+
/**
|
|
798
|
+
* Apply inverse relation definitions to a Prisma schema string based on the
|
|
799
|
+
* foreign keys defined in a create or alter table operation, ensuring that
|
|
800
|
+
* related models have corresponding relation fields for bi-directional navigation.
|
|
801
|
+
*
|
|
802
|
+
* @param schema The Prisma schema string to modify.
|
|
803
|
+
* @param sourceModelName The name of the source model in the relation.
|
|
804
|
+
* @param foreignKeys An array of foreign key definitions to process.
|
|
805
|
+
* @returns The updated Prisma schema string with inverse relations applied.
|
|
806
|
+
*/
|
|
807
|
+
const applyInverseRelations = (schema, sourceModelName, foreignKeys) => {
|
|
808
|
+
let nextSchema = schema;
|
|
809
|
+
for (const foreignKey of foreignKeys) {
|
|
810
|
+
const targetModel = findModelBlock(nextSchema, foreignKey.referencesTable);
|
|
811
|
+
if (!targetModel) continue;
|
|
812
|
+
const inverseLine = buildInverseRelationLine(sourceModelName, targetModel.modelName, foreignKey);
|
|
813
|
+
const targetBodyLines = targetModel.block.split("\n");
|
|
814
|
+
const fieldName = deriveCollectionFieldName(sourceModelName);
|
|
815
|
+
const fieldRegex = new RegExp(`^\\s*${escapeRegex(fieldName)}\\s+`);
|
|
816
|
+
injectLineIntoModelBody(targetBodyLines, inverseLine, (line) => fieldRegex.test(line));
|
|
817
|
+
const updatedTarget = targetBodyLines.join("\n");
|
|
818
|
+
nextSchema = `${nextSchema.slice(0, targetModel.start)}${updatedTarget}${nextSchema.slice(targetModel.end)}`;
|
|
819
|
+
}
|
|
820
|
+
return nextSchema;
|
|
821
|
+
};
|
|
822
|
+
/**
|
|
573
823
|
* Build a Prisma model block string based on a SchemaTableCreateOperation, including
|
|
574
824
|
* all fields and any necessary mapping.
|
|
575
825
|
*
|
|
@@ -580,12 +830,14 @@ const buildModelBlock = (operation) => {
|
|
|
580
830
|
const modelName = toModelName(operation.table);
|
|
581
831
|
const mapped = operation.table !== modelName.toLowerCase();
|
|
582
832
|
const fields = operation.columns.map(buildFieldLine);
|
|
833
|
+
const relations = (operation.foreignKeys ?? []).map(buildRelationLine);
|
|
583
834
|
const metadata = [...(operation.indexes ?? []).map(buildIndexLine), ...mapped ? [` @@map("${str(operation.table).snake()}")`] : []];
|
|
584
835
|
return `model ${modelName} {\n${(metadata.length > 0 ? [
|
|
585
836
|
...fields,
|
|
837
|
+
...relations,
|
|
586
838
|
"",
|
|
587
839
|
...metadata
|
|
588
|
-
] : fields).join("\n")}\n}`;
|
|
840
|
+
] : [...fields, ...relations]).join("\n")}\n}`;
|
|
589
841
|
};
|
|
590
842
|
/**
|
|
591
843
|
* Find the Prisma model block in a schema string that corresponds to a given
|
|
@@ -635,7 +887,7 @@ const findModelBlock = (schema, table) => {
|
|
|
635
887
|
const applyCreateTableOperation = (schema, operation) => {
|
|
636
888
|
if (findModelBlock(schema, operation.table)) throw new ArkormException(`Prisma model for table [${operation.table}] already exists.`);
|
|
637
889
|
const block = buildModelBlock(operation);
|
|
638
|
-
return `${schema.trimEnd()}\n\n${block}\n
|
|
890
|
+
return applyInverseRelations(`${schema.trimEnd()}\n\n${block}\n`, toModelName(operation.table), operation.foreignKeys ?? []);
|
|
639
891
|
};
|
|
640
892
|
/**
|
|
641
893
|
* Apply an alter table operation to a Prisma schema string, modifying the model
|
|
@@ -672,8 +924,13 @@ const applyAlterTableOperation = (schema, operation) => {
|
|
|
672
924
|
const insertIndex = Math.max(1, bodyLines.length - 1);
|
|
673
925
|
bodyLines.splice(insertIndex, 0, indexLine);
|
|
674
926
|
});
|
|
927
|
+
for (const foreignKey of operation.addForeignKeys ?? []) {
|
|
928
|
+
const relationLine = buildRelationLine(foreignKey);
|
|
929
|
+
const relationRegex = new RegExp(`^\\s*${escapeRegex(foreignKey.fieldAlias?.trim() || deriveRelationFieldName(foreignKey.column))}\\s+`);
|
|
930
|
+
injectLineIntoModelBody(bodyLines, relationLine, (line) => relationRegex.test(line));
|
|
931
|
+
}
|
|
675
932
|
block = bodyLines.join("\n");
|
|
676
|
-
return `${schema.slice(0, model.start)}${block}${schema.slice(model.end)}
|
|
933
|
+
return applyInverseRelations(`${schema.slice(0, model.start)}${block}${schema.slice(model.end)}`, model.modelName, operation.addForeignKeys ?? []);
|
|
677
934
|
};
|
|
678
935
|
/**
|
|
679
936
|
* Apply a drop table operation to a Prisma schema string, removing the model block
|
|
@@ -4830,4 +5087,4 @@ var Model = class Model {
|
|
|
4830
5087
|
};
|
|
4831
5088
|
|
|
4832
5089
|
//#endregion
|
|
4833
|
-
export { ArkormCollection, ArkormException, CliApp, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, Migration, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, 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 };
|
|
5090
|
+
export { ArkormCollection, ArkormException, CliApp, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, Migration, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, 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 };
|