diff --git a/packages/pinia-orm/src/model/attributes/types/Attr.ts b/packages/pinia-orm/src/model/attributes/types/Attr.ts index a5dfe1ece..1de085d63 100644 --- a/packages/pinia-orm/src/model/attributes/types/Attr.ts +++ b/packages/pinia-orm/src/model/attributes/types/Attr.ts @@ -5,6 +5,6 @@ export class Attr extends Type { * Make the value for the attribute. */ make (value: any): any { - return value === undefined ? this.value : value + return value === undefined ? this.defaultValue : value } } diff --git a/packages/pinia-orm/src/model/attributes/types/Type.ts b/packages/pinia-orm/src/model/attributes/types/Type.ts index ad1c1a962..9060b17b8 100644 --- a/packages/pinia-orm/src/model/attributes/types/Type.ts +++ b/packages/pinia-orm/src/model/attributes/types/Type.ts @@ -5,9 +5,9 @@ export type TypeDefault = T | null | (() => T | null) export abstract class Type extends Attribute { /** - * The default value for the attribute. + * The raw default value for the attribute (can be a function). */ - value: any + rawDefaultValue: any /** * Whether the attribute accepts `null` value or not. @@ -17,9 +17,16 @@ export abstract class Type extends Attribute { /** * Create a new Type attribute instance. */ - constructor (model: Model, value: TypeDefault = null) { + constructor (model: Model, defaultValue: TypeDefault = null) { super(model) - this.value = typeof value === 'function' ? value() : value + this.rawDefaultValue = defaultValue + } + + /** + * The computed default value of the attribute. + */ + get defaultValue (): any { + return typeof this.rawDefaultValue === 'function' ? this.rawDefaultValue() : this.rawDefaultValue } /** @@ -31,7 +38,7 @@ export abstract class Type extends Attribute { } protected makeReturn (type: 'boolean' | 'number' | 'string', value: any): T { - if (value === undefined) { return this.value } + if (value === undefined) { return this.defaultValue } if (value === null) { if (!this.isNullable) { this.throwWarning(['is set as non nullable!']) } diff --git a/packages/pinia-orm/src/query/Query.ts b/packages/pinia-orm/src/query/Query.ts index 08f8e8e2a..b0de04f03 100644 --- a/packages/pinia-orm/src/query/Query.ts +++ b/packages/pinia-orm/src/query/Query.ts @@ -803,7 +803,7 @@ export class Query { records.forEach((record: Element) => { const recordType = (modelTypesKeys.includes(`${record[this.model.$typeKey()]}`) || isChildEntity) - ? record[this.model.$typeKey()] ?? (this.model.$fields()[this.model.$typeKey()] as Type).value + ? record[this.model.$typeKey()] ?? (this.model.$fields()[this.model.$typeKey()] as Type).defaultValue : modelTypesKeys[0] if (!recordsByTypes[recordType]) { recordsByTypes[recordType] = [] } recordsByTypes[recordType].push(record) diff --git a/packages/pinia-orm/tests/feature/models/default_attr.spec.ts b/packages/pinia-orm/tests/feature/models/default_attr.spec.ts new file mode 100644 index 000000000..53dec605b --- /dev/null +++ b/packages/pinia-orm/tests/feature/models/default_attr.spec.ts @@ -0,0 +1,55 @@ +import { describe, expect, it } from 'vitest' + +import { Model } from '../../../src' + +describe('feature/model/default_attr', () => { + it('should not modify default value by reference', () => { + class User extends Model { + static entity = 'users' + + static fields () { + return { + id: this.attr(null), + str: this.string(''), + num: this.number(0), + bool: this.boolean(false), + parameters: this.attr(() => ({})), + } + } + + id!: any + str!: string + num!: number + bool!: boolean + parameters!: any + } + + console.log('New User 1') + const user = new User({ + str: 'string', + num: 1, + bool: true, + }) + + // Modify the default value by reference + user.parameters.a = 1 + + expect(user.id).toBe(null) + expect(user.str).toBe('string') + expect(user.num).toBe(1) + expect(user.bool).toBe(true) + expect(user.parameters).toEqual({ a: 1 }) + + const user2 = new User({ + str: 'string', + num: 1, + bool: true, + }) + + expect(user2.id).toBe(null) + expect(user2.str).toBe('string') + expect(user2.num).toBe(1) + expect(user2.bool).toBe(true) + expect(user2.parameters).toEqual({}) + }) +})