Skip to content

Commit 438b617

Browse files
feat: add support for mixed type
1 parent dfff5ac commit 438b617

File tree

7 files changed

+60
-36
lines changed

7 files changed

+60
-36
lines changed

example-app/src/entity/Car.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ export class Car extends BaseEntity {
1010
@Column()
1111
name: string;
1212

13+
@Column({
14+
type: 'jsonb',
15+
nullable: true,
16+
})
17+
meta: any;
18+
1319
@ManyToOne((type) => User, (user) => user.cars)
1420
owner: User;
1521

example-app/src/index.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,19 @@ const run = async () => {
2525
},
2626
},
2727
},
28-
}, Car, Seller],
28+
}, {
29+
resource: Car,
30+
options: {
31+
properties: {
32+
'meta.title': {
33+
type: 'string',
34+
},
35+
'meta.description': {
36+
type: 'string',
37+
},
38+
},
39+
},
40+
}, Seller],
2941
})
3042
const router = buildRouter(admin)
3143

spec/Property.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,12 @@ describe('Property', () => {
108108
])
109109
})
110110
})
111+
112+
describe('#type', () => {
113+
it('returns mixed type for an jsonb property', () => {
114+
const column = columns.find((c) => c.propertyName === 'meta') as ColumnMetadata
115+
116+
expect(new Property(column).type()).to.equal('mixed')
117+
})
118+
})
111119
})

spec/Resource.spec.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ describe('Resource', () => {
1717
streetNumber: 'something',
1818
age: 4,
1919
stringAge: '4',
20+
'meta.title': 'Hyundai',
21+
'meta.description': 'Hyundai Tucson',
2022
}
2123

2224
before(async () => {
@@ -66,12 +68,12 @@ describe('Resource', () => {
6668

6769
describe('#properties', () => {
6870
it('returns all the properties', () => {
69-
expect(resource.properties()).to.have.lengthOf(11)
71+
expect(resource.properties()).to.have.lengthOf(12)
7072
})
7173

7274
it('returns all properties with the correct position', () => {
7375
expect(resource.properties().map((property) => property.position())).to.deep.equal([
74-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
76+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
7577
])
7678
})
7779
})
@@ -126,6 +128,16 @@ describe('Resource', () => {
126128
expect(storedRecord.stringAge).to.equal(4)
127129
})
128130

131+
it('stores mixed type properties', async () => {
132+
const params = await resource.create(data)
133+
const storedRecord = await Car.findOne(params.id) as Car
134+
135+
expect(storedRecord.meta).to.deep.equal({
136+
title: data['meta.title'],
137+
description: data['meta.description'],
138+
})
139+
})
140+
129141
it('throws ValidationError for defined validations', async () => {
130142
Resource.validate = validate
131143
try {

spec/entities/Car.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ export class Car extends BaseEntity {
4444
})
4545
public carType: CarType;
4646

47+
@Column({
48+
type: 'jsonb',
49+
nullable: true,
50+
})
51+
public meta;
52+
4753
@ManyToOne(() => CarDealer, (carDealer) => carDealer.cars)
4854
public carDealer: CarDealer;
4955

src/Resource.ts

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable no-param-reassign */
2-
import { BaseEntity, In } from 'typeorm'
3-
import { BaseResource, ValidationError, Filter, BaseRecord } from 'admin-bro'
2+
import { BaseEntity } from 'typeorm'
3+
import { BaseResource, ValidationError, Filter, BaseRecord, flat } from 'admin-bro'
44

55
import { Property } from './Property'
66
import { convertFilter } from './utils/convertFilter'
@@ -51,29 +51,6 @@ export class Resource extends BaseResource {
5151
}))
5252
}
5353

54-
public async populate(
55-
baseRecords: Array<BaseRecord>,
56-
property: Property,
57-
): Promise<Array<BaseRecord>> {
58-
const fks: Array<any> = baseRecords.map((baseRecord) => baseRecord.params[property.name()])
59-
60-
const instances = await this.model.findByIds(fks)
61-
const instancesRecord: Record<string, BaseEntity> = {}
62-
instances.forEach((instance) => {
63-
if (instance.hasId()) {
64-
instancesRecord[(instance as any).id] = instance
65-
}
66-
})
67-
68-
baseRecords.forEach((baseRecord) => {
69-
const fk = baseRecord.params[property.name()]
70-
const instance = instancesRecord[fk]
71-
// eslint-disable-next-line no-param-reassign
72-
if (instance) { baseRecord.populated[property.name()] = new BaseRecord(instance, this) }
73-
})
74-
return baseRecords
75-
}
76-
7754
public async find(
7855
filter: Filter,
7956
params,
@@ -100,7 +77,7 @@ export class Resource extends BaseResource {
10077
}
10178

10279
public async findMany(ids: Array<string | number>): Promise<Array<BaseRecord>> {
103-
const instances = await this.model.find({ where: { id: In(ids) } })
80+
const instances = await this.model.findByIds(ids)
10481
return instances.map((instance) => new BaseRecord(instance, this))
10582
}
10683

@@ -154,17 +131,17 @@ export class Resource extends BaseResource {
154131
private prepareParams(params: Record<string, any>): Record<string, any> {
155132
const preparedParams: Record<string, any> = { ...params }
156133

157-
for (const key in params) {
158-
const param = params[key]
159-
const property = this.property(key)
134+
this.properties().forEach((property) => {
135+
const param = flat.get(preparedParams, property.path())
136+
const key = property.path()
160137

161138
// eslint-disable-next-line no-continue
162-
if (!(property && param !== undefined)) continue
139+
if (param === undefined) { return }
163140

164141
const type = property.type()
165142

166143
if (type === 'mixed') {
167-
preparedParams[key] = JSON.parse(param)
144+
preparedParams[key] = param
168145
}
169146

170147
if (type === 'number') {
@@ -184,7 +161,7 @@ export class Resource extends BaseResource {
184161
preparedParams[property.column.propertyName] = { id }
185162
}
186163
}
187-
}
164+
})
188165
return preparedParams
189166
}
190167

src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
/**
22
* @module @admin-bro/typeorm
3-
* @description
3+
* @subcategory Adapters
4+
* @section modules
5+
*
6+
* @classdesc
47
* Database adapter which integrates [TypeORM](https://typeorm.io/) into admin-bro
58
*
69
* ## installation

0 commit comments

Comments
 (0)