Skip to content

Commit 8a0fab4

Browse files
chore: wip
1 parent bbd3ac7 commit 8a0fab4

File tree

16 files changed

+114
-41
lines changed

16 files changed

+114
-41
lines changed

app/Models/AccessToken.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export default {
6666
string: '`abilities` must be string of either `read`, `write`, `admin`, `read|write`, `read|admin`, `write|admin`, or `read|write|admin`',
6767
},
6868
},
69-
factory: faker =>
69+
factory: () =>
7070
collect(['read', 'write', 'admin', 'read|write', 'read|admin', 'write|admin', 'read|write|admin']).random().first(),
7171
},
7272

@@ -134,7 +134,7 @@ export default {
134134
boolean: 'isSingleUse must be a boolean',
135135
},
136136
},
137-
factory: faker => false,
137+
factory: () => false,
138138
},
139139
},
140140
} satisfies Model

app/Models/Deployment.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default {
7070
},
7171
},
7272

73-
factory: faker => collect(['pending', 'success', 'failure']).random().first(),
73+
factory: () => collect(['pending', 'success', 'failure']).random().first(),
7474
},
7575

7676
executionTime: {

app/Models/Project.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export default {
6666
},
6767
},
6868

69-
factory: faker => collect(['active', 'inactive']).random().first(),
69+
factory: () => collect(['active', 'inactive']).random().first(),
7070
},
7171
},
7272
} satisfies Model

app/Models/Team.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export default {
8383
},
8484
},
8585

86-
factory: faker => collect(['deployed', 'inactive']).random().first(),
86+
factory: () => collect(['deployed', 'inactive']).random().first(),
8787
},
8888

8989
description: {

storage/framework/core/orm/src/utils.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
Model,
88
ModelElement,
99
ModelNames,
10+
MorphOne,
1011
Relation,
1112
RelationConfig,
1213
TableNames,
@@ -95,6 +96,10 @@ export async function getRelations(model: Model, modelName: string): Promise<Rel
9596
}
9697
}
9798

99+
if (model.morphOne) {
100+
relationships.push(await processMorphOne(model.morphOne, model, modelName, 'belongsToMany'))
101+
}
102+
98103
return relationships
99104
}
100105

@@ -211,6 +216,66 @@ async function processBelongsToMany(relationInstance: ModelNames | BaseBelongsTo
211216
return relationshipData
212217
}
213218

219+
async function processMorphOne(relationInstance: ModelNames | MorphOne<ModelNames>, model: Model, modelName: string, relation: string): Promise<RelationConfig> {
220+
let relationModel = ''
221+
let morphName = ''
222+
let typeColumn = ''
223+
let idColumn = ''
224+
225+
// Determine if it's a simple string or a configuration object
226+
if (isString(relationInstance)) {
227+
relationModel = relationInstance
228+
// Convert model name to "able" format (e.g. "Post" -> "postable")
229+
morphName = `${snakeCase(modelName)}able`
230+
}
231+
else {
232+
relationModel = relationInstance.model
233+
// Use provided morphName or generate default "-able" suffix
234+
morphName = relationInstance.morphName || `${snakeCase(modelName)}able`
235+
typeColumn = relationInstance.type || `${morphName}_type`
236+
idColumn = relationInstance.id || `${morphName}_id`
237+
}
238+
239+
// Load the related model
240+
const modelRelationPath = path.userModelsPath(`${relationModel}.ts`)
241+
const userModelPath = path.userModelsPath(`${modelName}.ts`)
242+
const coreModelPath = path.storagePath(`framework/defaults/models/${modelName}.ts`)
243+
const coreModelRelationPath = path.storagePath(`framework/defaults/models/${relationModel}.ts`)
244+
245+
let modelRelation: Model
246+
if (fs.existsSync(modelRelationPath)) {
247+
modelRelation = (await import(modelRelationPath)).default as Model
248+
}
249+
else {
250+
modelRelation = (await import(coreModelRelationPath)).default as Model
251+
}
252+
253+
const modelPath = fs.existsSync(userModelPath) ? userModelPath : coreModelPath
254+
255+
// Get table names
256+
const modelRelationTable = getTableName(modelRelation, modelRelationPath)
257+
const table = getTableName(model, modelPath)
258+
259+
// Create relationship config
260+
const relationshipData: RelationConfig = {
261+
relationship: relation,
262+
model: relationModel,
263+
table: modelRelationTable as TableNames,
264+
relationTable: table as TableNames,
265+
foreignKey: idColumn || `${morphName}_id`,
266+
modelKey: typeColumn || `${morphName}_type`,
267+
relationName: morphName,
268+
relationModel: modelName,
269+
throughModel: '',
270+
throughForeignKey: '',
271+
pivotForeign: '',
272+
pivotKey: '',
273+
pivotTable: table as TableNames,
274+
}
275+
276+
return relationshipData
277+
}
278+
214279
async function processHasOneAndMany(relationInstance: ModelNames | Relation<ModelNames>, model: Model, modelName: string, relation: string) {
215280
let relationModel = ''
216281
let modelRelation: Model
@@ -271,6 +336,7 @@ export function getRelationType(relation: string): string {
271336
const belongToType = /belongs/
272337
const hasType = /has/
273338
const throughType = /Through/
339+
const morphType = /morph/
274340

275341
if (throughType.test(relation))
276342
return 'throughType'
@@ -281,6 +347,9 @@ export function getRelationType(relation: string): string {
281347
if (hasType.test(relation))
282348
return 'hasType'
283349

350+
if (morphType.test(relation))
351+
return 'morphType'
352+
284353
return ''
285354
}
286355

storage/framework/core/types/src/model.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@ export interface Relation<T = string> extends BaseRelation {
1717

1818
export interface HasOne<T = string> extends Array<Relation<T>> {}
1919

20-
export interface MorphTo<T = string> {
20+
export interface MorphTo {
21+
name: string
22+
}
23+
24+
export interface MorphOne<T = string> extends BaseRelation {
2125
model: T
22-
name?: string
26+
morphName?: string
2327
type?: string
2428
id?: string
2529
}
@@ -174,7 +178,9 @@ export interface ModelOptions extends Base {
174178

175179
hasOneThrough?: HasOneThrough<ModelNames> | ModelNames[]
176180

177-
morphTo?: MorphTo<ModelNames> | ModelNames[]
181+
morphOne?: MorphOne<ModelNames> | ModelNames
182+
183+
morphTo?: MorphTo
178184

179185
scopes?: {
180186
[key: string]: (value: any) => any

storage/framework/defaults/components/Docs/demo/plugins/highlight.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,4 @@ const plugin: Plugin & { component: typeof component } = {
103103
}
104104

105105
export default plugin
106-
export { component as Highlight }
106+
export { component as Highlight }

storage/framework/defaults/models/FailedJob.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default {
2222
string: 'Connection must be a string',
2323
},
2424
},
25-
factory: faker => 'default',
25+
factory: () => 'default',
2626
},
2727

2828
queue: {
@@ -34,7 +34,7 @@ export default {
3434
maxLength: 'Queue must have a maximum of 255 characters',
3535
},
3636
},
37-
factory: faker => 'default',
37+
factory: () => 'default',
3838
},
3939

4040
payload: {
@@ -60,7 +60,7 @@ export default {
6060
validation: {
6161
rule: schema.date(),
6262
},
63-
factory: faker => '2024-12-23 13:32:19',
63+
factory: () => '2024-12-23 13:32:19',
6464
},
6565
},
6666
} satisfies Model

storage/framework/defaults/models/Job.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default {
2121
maxLength: 'Queue must have a maximum of 255 characters',
2222
},
2323
},
24-
factory: faker => 'default',
24+
factory: () => 'default',
2525
},
2626

2727
payload: {
@@ -56,7 +56,7 @@ export default {
5656
validation: {
5757
rule: schema.date(),
5858
},
59-
factory: faker => '2024-12-23 13:32:19',
59+
factory: () => '2024-12-23 13:32:19',
6060
},
6161
},
6262
} satisfies Model

storage/framework/defaults/models/PaymentMethod.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default {
2828
maxLength: 'type must have a maximum of 512 characters',
2929
},
3030
},
31-
factory: faker => 'card',
31+
factory: () => 'card',
3232
},
3333

3434
lastFour: {
@@ -54,7 +54,7 @@ export default {
5454
required: 'brand is required',
5555
},
5656
},
57-
factory: faker => collect(['visa', 'mastercard', 'amex', 'jcb']).random().first(),
57+
factory: () => collect(['visa', 'mastercard', 'amex', 'jcb']).random().first(),
5858
},
5959

6060
expMonth: {

0 commit comments

Comments
 (0)