1
1
import { italic , log } from '@stacksjs/cli'
2
2
import { db } from '@stacksjs/database'
3
3
import { path } from '@stacksjs/path'
4
- import { fs } from '@stacksjs/storage'
4
+ import { fs , glob } from '@stacksjs/storage'
5
+ import { isString } from '@stacksjs/validation'
5
6
import { snakeCase } from '@stacksjs/strings'
6
- import type { Model } from '@stacksjs/types'
7
+ import type { Model , RelationConfig } from '@stacksjs/types'
7
8
import { generateMigrations , resetDatabase , runDatabaseMigration } from './migrations'
8
9
9
10
async function seedModel ( name : string , model ?: Model ) {
@@ -20,20 +21,99 @@ async function seedModel(name: string, model?: Model) {
20
21
log . info ( `Seeding ${ seedCount } records into ${ italic ( tableName ) } ` )
21
22
const records = [ ]
22
23
24
+ const otherRelations = await fetchOtherModelRelations ( model )
25
+
26
+ console . log ( otherRelations )
27
+
23
28
for ( let i = 0 ; i < seedCount ; i ++ ) {
24
29
const record : any = { }
25
30
for ( const fieldName in model . attributes ) {
26
31
const field = model . attributes [ fieldName ]
27
32
// Use the factory function if available, otherwise leave the field undefined
28
33
record [ fieldName ] = field ?. factory ? field . factory ( ) : undefined
29
34
}
35
+
36
+ if ( otherRelations ?. length ) {
37
+ for ( let j = 0 ; j < otherRelations . length ; j ++ ) {
38
+ const relationElement = otherRelations [ j ] as RelationConfig
39
+
40
+ record [ relationElement ?. foreignKey ] = 1 // TODO: make this dynamic
41
+ }
42
+ }
43
+
30
44
records . push ( record )
31
45
}
32
46
33
47
// @ts -expect-error todo: we can improve this in the future
34
48
await db . insertInto ( tableName ) . values ( records ) . execute ( )
35
49
}
36
50
51
+ export async function getRelations ( model : Model ) : Promise < RelationConfig [ ] > {
52
+ const relationsArray = [ 'hasOne' , 'hasMany' , 'belongsToMany' , 'hasOneThrough' ]
53
+ const relationships = [ ]
54
+
55
+ for ( const relation of relationsArray ) {
56
+ if ( hasRelations ( model , relation ) ) {
57
+ for ( const relationInstance of model [ relation ] ) {
58
+ let relationModel = relationInstance . model
59
+
60
+ if ( isString ( relationInstance ) ) {
61
+ relationModel = relationInstance
62
+ }
63
+
64
+ const modelRelationPath = path . userModelsPath ( `${ relationModel } .ts` )
65
+ const modelRelation = ( await import ( modelRelationPath ) ) . default
66
+ const formattedModelName = model . name . toLowerCase ( )
67
+
68
+ relationships . push ( {
69
+ relationship : relation ,
70
+ model : relationModel ,
71
+ table : modelRelation . table ,
72
+ relationModel : model . name ,
73
+ relationTable : model . table ,
74
+ foreignKey : relationInstance . foreignKey || `${ formattedModelName } _id` ,
75
+ relationName : relationInstance . relationName || '' ,
76
+ throughModel : relationInstance . through || '' ,
77
+ throughForeignKey : relationInstance . throughForeignKey || '' ,
78
+ pivotTable : relationInstance ?. pivotTable || `${ formattedModelName } _${ modelRelation . table } ` ,
79
+ } )
80
+ }
81
+ }
82
+ }
83
+
84
+ return relationships
85
+ }
86
+
87
+ export async function fetchOtherModelRelations ( model : Model ) {
88
+
89
+ const modelFiles = glob . sync ( path . userModelsPath ( '*.ts' ) )
90
+
91
+ const modelRelations = [ ]
92
+
93
+ for ( let i = 0 ; i < modelFiles . length ; i ++ ) {
94
+ const modelFileElement = modelFiles [ i ] as string
95
+
96
+ const modelFile = await import ( modelFileElement )
97
+
98
+ if ( model . name === modelFile . default . name ) continue
99
+
100
+ const relations = await getRelations ( modelFile . default )
101
+
102
+ if ( ! relations . length ) continue
103
+
104
+ const relation = relations . find ( relation => relation . model === model . name )
105
+
106
+ if ( relation )
107
+ modelRelations . push ( relation )
108
+
109
+ return modelRelations
110
+ }
111
+ }
112
+
113
+ function hasRelations ( obj : any , key : string ) : boolean {
114
+ return key in obj
115
+ }
116
+
37
117
export async function seed ( ) {
38
118
// TODO: need to check other databases too
39
119
const dbPath = path . userDatabasePath ( 'stacks.sqlite' )
0 commit comments