Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions packages/pinia-orm/src/model/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,14 @@ export class Model {
protected static piniaExtend = {}

/**
* The mutators for the model.
* The mutators for the model, keyed by entity.
*/
protected static fieldMutators: Mutators = {}
protected static fieldMutators: Record<string, Mutators> = {}

/**
* The casts for the model.
* The casts for the model, keyed by entity.
*/
protected static fieldCasts: Record<string, any> = {}
protected static fieldCasts: Record<string, Casts> = {}

/**
* The array of booted models.
Expand Down Expand Up @@ -247,7 +247,8 @@ export class Model {
key: string,
mutator: MutatorFunctions<any>,
): M {
this.fieldMutators[key] = mutator
this.fieldMutators[this.modelEntity()] = this.fieldMutators[this.modelEntity()] ?? {}
this.fieldMutators[this.modelEntity()][key] = mutator

return this
}
Expand All @@ -260,7 +261,8 @@ export class Model {
key: string,
to: typeof CastAttribute,
): M {
this.fieldCasts[key] = to
this.fieldCasts[this.modelEntity()] = this.fieldCasts[this.modelEntity()] ?? {}
this.fieldCasts[this.modelEntity()][key] = to

return this
}
Expand All @@ -272,6 +274,7 @@ export class Model {
this: M,
key: keyof ModelFields,
): M {
if (!Object.prototype.hasOwnProperty.call(this, 'hidden')) { this.hidden = [...this.hidden] }
this.hidden.push(key)

return this
Expand Down Expand Up @@ -781,7 +784,7 @@ export class Model {
$casts (): Casts {
return {
...this.$getCasts(),
...this.$self().fieldCasts,
...this.$self().fieldCasts[this.$modelEntity()],
}
}

Expand All @@ -802,7 +805,7 @@ export class Model {
const fillRelation = options.relations ?? true
const mutators: Mutators = {
...this.$getMutators(),
...this.$self().fieldMutators,
...this.$self().fieldMutators[this.$modelEntity()],
}

for (const key in fields) {
Expand Down
24 changes: 24 additions & 0 deletions packages/pinia-orm/tests/unit/model/Model_Casts_Custom.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,30 @@ describe('unit/model/Model_Casts_Custom', () => {
expect(new User().name).toBe('string test')
})

it('should keep decorator casts of same named fields separate between entities', () => {
class UpperCast extends CastAttribute {
get (value?: any): any {
return typeof value === 'string' ? value.toUpperCase() : value
}
}

class User extends Model {
static entity = 'users'

@Cast(() => UpperCast)
@Attr('') name!: string
}

class Group extends Model {
static entity = 'groups'

@Attr('') name!: string
}

expect(new User({ name: 'John' }, { operation: 'get' }).name).toBe('JOHN')
expect(new Group({ name: 'John' }, { operation: 'get' }).name).toBe('John')
})

it('should cast with parameter', () => {
class CustomCast extends CastAttribute {
static parameters = {
Expand Down
22 changes: 22 additions & 0 deletions packages/pinia-orm/tests/unit/model/Model_Hidden_Field.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,28 @@ describe('unit/model/Model_Hidden_Field', () => {
expect(user.username).toBe(undefined)
})

it('should only hide the field on the entity using the decorator', () => {
class User extends Model {
static entity = 'users'

@Str('') declare name: string
@Hidden() @Str('') declare username: string
}

class Account extends Model {
static entity = 'accounts'

@Str('') declare name: string
@Str('') declare username: string
}

const user = new User({ name: 'Test', username: 'John' }, { operation: 'get' })
const account = new Account({ name: 'Test', username: 'John' }, { operation: 'get' })

expect(user.username).toBe(undefined)
expect(account.username).toBe('John')
})

it('should hide the field with "visible"', () => {
class User extends Model {
static entity = 'users'
Expand Down
48 changes: 48 additions & 0 deletions packages/pinia-orm/tests/unit/model/Model_Mutators.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,54 @@ describe('unit/model/Model_Mutators', () => {
expect(new User({ name: 'john doe' }, { operation: 'get' }).name).toBe('JOHN DOE')
})

it('should keep decorator mutators of same named fields separate between entities', () => {
class User extends Model {
static entity = 'users'

@Mutate((value: any) => value.toUpperCase())
@Attr('')
firstName!: string
}

class Contact extends Model {
static entity = 'contacts'

@Mutate((value: any) => value.toLowerCase())
@Attr('')
firstName!: string
}

expect(new User({ firstName: 'John' }, { operation: 'get' }).firstName).toBe('JOHN')
expect(new Contact({ firstName: 'John' }, { operation: 'get' }).firstName).toBe('john')
})

it('should only apply mutators added with "setMutator" to the model they were set on', () => {
class User extends Model {
static entity = 'users'

@Attr(0) id!: number
@Attr('') title!: string
}

class Todo extends Model {
static entity = 'todos'

@Attr(0) id!: number
@Attr('') title!: string
}

Todo.setMutator('title', { get: (value: any) => value.toUpperCase() })

const userRepo = useRepo(User)
const todoRepo = useRepo(Todo)

userRepo.save({ id: 1, title: 'user title' })
todoRepo.save({ id: 1, title: 'todo title' })

expect(todoRepo.find(1)?.title).toBe('TODO TITLE')
expect(userRepo.find(1)?.title).toBe('user title')
})

it('should mutate data if mutators with getter are present', () => {
class User extends Model {
static entity = 'users'
Expand Down
Loading