Skip to content

Commit a80678a

Browse files
authored
feat: extend sideload (#1099)
1 parent 9893ed1 commit a80678a

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

src/orm/query_builder/index.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,6 @@ export class ModelQueryBuilder
7373
extends Chainable
7474
implements ModelQueryBuilderContract<LucidModel, LucidRow>
7575
{
76-
/**
77-
* Side-loaded attributes that will be passed to the model instances
78-
*/
79-
protected sideloaded: ModelObject = {}
80-
8176
/**
8277
* A copy of defined preloads on the model instance
8378
*/
@@ -134,6 +129,11 @@ export class ModelQueryBuilder
134129
*/
135130
isChildQuery = false
136131

132+
/**
133+
* Side-loaded attributes that will be passed to the model instances
134+
*/
135+
sideloaded: ModelObject = {}
136+
137137
constructor(
138138
builder: Knex.QueryBuilder,
139139
public model: LucidModel,
@@ -448,8 +448,13 @@ export class ModelQueryBuilder
448448
/**
449449
* Set side-loaded properties to be passed to the model instance
450450
*/
451-
sideload(value: ModelObject) {
452-
this.sideloaded = value
451+
sideload(value: ModelObject, merge = false) {
452+
if (merge) {
453+
Object.assign(this.sideloaded, value)
454+
} else {
455+
this.sideloaded = value
456+
}
457+
453458
return this
454459
}
455460

src/types/model.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,12 +402,17 @@ export interface ModelQueryBuilderContract<Model extends LucidModel, Result = In
402402
*/
403403
clone<ClonedResult = Result>(): ModelQueryBuilderContract<Model, ClonedResult>
404404

405+
sideloaded: InstanceType<Model>['$sideloaded']
406+
405407
/**
406408
* A custom set of sideloaded properties defined on the query
407409
* builder, this will be passed to the model instance created
408410
* by the query builder
409411
*/
410-
sideload(value: ModelObject): this
412+
sideload<Sideloaded extends InstanceType<Model>['$sideloaded'], Merge extends boolean = false>(
413+
value: Merge extends true ? Partial<Sideloaded> : Sideloaded,
414+
merge?: Merge
415+
): this
411416

412417
/**
413418
* Execute and get first result

test/orm/model_query_builder.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
getBaseModel,
2323
} from '../../test-helpers/index.js'
2424
import type { HasMany } from '../../src/types/relations.js'
25+
import { ModelQueryBuilderContract } from '../../src/types/model.js'
2526

2627
test.group('Model query builder', (group) => {
2728
group.setup(async () => {
@@ -578,4 +579,28 @@ test.group('Model query builder', (group) => {
578579

579580
assert.lengthOf(posts, 1)
580581
})
582+
583+
test('define custom type for sideloaded', async ({ fs, expectTypeOf }) => {
584+
const app = new AppFactory().create(fs.baseUrl, () => {})
585+
await app.init()
586+
const db = getDb()
587+
const adapter = ormAdapter(db)
588+
const BaseModel = getBaseModel(adapter)
589+
590+
type Sideload = { test: boolean }
591+
592+
class User extends BaseModel {
593+
declare $sideloaded: Sideload
594+
595+
@column({ isPrimary: true })
596+
declare id: number
597+
598+
@column()
599+
declare username: string
600+
}
601+
602+
type Query = ModelQueryBuilderContract<typeof User>
603+
604+
expectTypeOf<Query['sideloaded']>().toEqualTypeOf<Sideload>()
605+
})
581606
})

0 commit comments

Comments
 (0)