diff --git a/packages/pinia-orm/src/model/Model.ts b/packages/pinia-orm/src/model/Model.ts index b17124e22..d7a45b67b 100644 --- a/packages/pinia-orm/src/model/Model.ts +++ b/packages/pinia-orm/src/model/Model.ts @@ -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 = {} /** - * The casts for the model. + * The casts for the model, keyed by entity. */ - protected static fieldCasts: Record = {} + protected static fieldCasts: Record = {} /** * The array of booted models. @@ -247,7 +247,8 @@ export class Model { key: string, mutator: MutatorFunctions, ): M { - this.fieldMutators[key] = mutator + this.fieldMutators[this.modelEntity()] = this.fieldMutators[this.modelEntity()] ?? {} + this.fieldMutators[this.modelEntity()][key] = mutator return this } @@ -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 } @@ -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 @@ -781,7 +784,7 @@ export class Model { $casts (): Casts { return { ...this.$getCasts(), - ...this.$self().fieldCasts, + ...this.$self().fieldCasts[this.$modelEntity()], } } @@ -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) { diff --git a/packages/pinia-orm/tests/unit/model/Model_Casts_Custom.spec.ts b/packages/pinia-orm/tests/unit/model/Model_Casts_Custom.spec.ts index 78fa246b5..d11363d59 100644 --- a/packages/pinia-orm/tests/unit/model/Model_Casts_Custom.spec.ts +++ b/packages/pinia-orm/tests/unit/model/Model_Casts_Custom.spec.ts @@ -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 = { diff --git a/packages/pinia-orm/tests/unit/model/Model_Hidden_Field.spec.ts b/packages/pinia-orm/tests/unit/model/Model_Hidden_Field.spec.ts index 9748819ee..7a9e518df 100644 --- a/packages/pinia-orm/tests/unit/model/Model_Hidden_Field.spec.ts +++ b/packages/pinia-orm/tests/unit/model/Model_Hidden_Field.spec.ts @@ -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' diff --git a/packages/pinia-orm/tests/unit/model/Model_Mutators.spec.ts b/packages/pinia-orm/tests/unit/model/Model_Mutators.spec.ts index 987a93f44..ebc15e743 100644 --- a/packages/pinia-orm/tests/unit/model/Model_Mutators.spec.ts +++ b/packages/pinia-orm/tests/unit/model/Model_Mutators.spec.ts @@ -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'