From c137a74879e370be13ae7c4970381c4a1b2d4d20 Mon Sep 17 00:00:00 2001 From: Benjamin Hutchins Date: Wed, 13 Sep 2023 17:26:28 -0400 Subject: [PATCH] feat: allow sets to continue to be native javascript arrays This should help with users migrating to Dyngoose v3 Fixes #667 --- src/decorator/attribute-types/binary-set.ts | 2 + src/decorator/attribute-types/number-set.ts | 14 ++++--- .../attribute-types/string-set.spec.ts | 39 +++++++++++++++++++ src/decorator/attribute-types/string-set.ts | 2 + .../attribute-types/binary-set.metadata.ts | 6 ++- .../attribute-types/number-set.metadata.ts | 6 ++- .../attribute-types/string-set.metadata.ts | 9 +++-- src/setup-tests.spec.ts | 3 ++ 8 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 src/decorator/attribute-types/string-set.spec.ts diff --git a/src/decorator/attribute-types/binary-set.ts b/src/decorator/attribute-types/binary-set.ts index b53a988a..633b73d0 100644 --- a/src/decorator/attribute-types/binary-set.ts +++ b/src/decorator/attribute-types/binary-set.ts @@ -26,6 +26,8 @@ export class BinarySetAttributeType extends AttributeType { diff --git a/src/decorator/attribute-types/number-set.ts b/src/decorator/attribute-types/number-set.ts index 2c12af10..194285b5 100644 --- a/src/decorator/attribute-types/number-set.ts +++ b/src/decorator/attribute-types/number-set.ts @@ -42,10 +42,14 @@ export class NumberSetAttributeType extends AttributeType): NumberSetValue { - const numberSet: NumberSetValue = new Set() - values.forEach((item) => { - numberSet.add(stringToNumber(item)) - }) - return numberSet + if (this.metadata?.array === true) { + return values.map((item) => stringToNumber(item)) + } else { + const numberSet: NumberSetValue = new Set() + values.forEach((item) => { + numberSet.add(stringToNumber(item)) + }) + return numberSet + } } } diff --git a/src/decorator/attribute-types/string-set.spec.ts b/src/decorator/attribute-types/string-set.spec.ts new file mode 100644 index 00000000..3dcabc1f --- /dev/null +++ b/src/decorator/attribute-types/string-set.spec.ts @@ -0,0 +1,39 @@ +import { expect } from 'chai' +import { TestableTable } from '../../setup-tests.spec' +import { isArray, toArray } from 'lodash' + +describe('AttributeType/StringSet', () => { + let record: TestableTable + + beforeEach(() => { + record = TestableTable.new() + }) + + describe('setting', () => { + it('should allow values to be a Set', () => { + expect(record.testStringSet).eq(null) + record.testStringSet = new Set(['some value']) + expect(toArray(record.testStringSet)).deep.eq(['some value']) + }) + + it('should allow values to be an Array', () => { + expect(record.testStringSet).eq(null) + record.testStringSet = ['some value'] as any + expect(toArray(record.testStringSet)).deep.eq(['some value']) + }) + }) + + describe('getting', () => { + it('should allow values to read as a Set', () => { + expect(record.testStringSet).eq(null) + record.testStringSet = new Set(['some value']) + expect(record.testStringSet).to.be.instanceOf(Set) + }) + + it('should allow values to be an Array', () => { + expect(record.testStringSetArray).eq(null) + record.testStringSetArray = ['some value'] + expect(isArray(record.testStringSetArray)).eq(true) + }) + }) +}) diff --git a/src/decorator/attribute-types/string-set.ts b/src/decorator/attribute-types/string-set.ts index 87488a08..8d43e54a 100644 --- a/src/decorator/attribute-types/string-set.ts +++ b/src/decorator/attribute-types/string-set.ts @@ -30,6 +30,8 @@ export class StringSetAttributeType extends AttributeType { diff --git a/src/metadata/attribute-types/binary-set.metadata.ts b/src/metadata/attribute-types/binary-set.metadata.ts index 92e21288..77be62e2 100644 --- a/src/metadata/attribute-types/binary-set.metadata.ts +++ b/src/metadata/attribute-types/binary-set.metadata.ts @@ -1,6 +1,10 @@ import { type AttributeMetadata } from '../attribute' -export type BinarySetValue = Set +export type BinarySetValue = Set | Uint8Array[] export interface BinarySetAttributeMetadata extends AttributeMetadata { + /** + * Return a native JavaScript array, rather than a Set. + */ + array?: boolean } diff --git a/src/metadata/attribute-types/number-set.metadata.ts b/src/metadata/attribute-types/number-set.metadata.ts index cb45fafb..40dd135d 100644 --- a/src/metadata/attribute-types/number-set.metadata.ts +++ b/src/metadata/attribute-types/number-set.metadata.ts @@ -1,7 +1,11 @@ import { type AttributeMetadata } from '../attribute' import { type NumberValue } from './number.metadata' -export type NumberSetValue = Set +export type NumberSetValue = Set | number[] export interface NumberSetAttributeMetadata extends AttributeMetadata { + /** + * Return a native JavaScript array, rather than a Set. + */ + array?: boolean } diff --git a/src/metadata/attribute-types/string-set.metadata.ts b/src/metadata/attribute-types/string-set.metadata.ts index 4e4c9c5e..6d1f94b4 100644 --- a/src/metadata/attribute-types/string-set.metadata.ts +++ b/src/metadata/attribute-types/string-set.metadata.ts @@ -1,9 +1,10 @@ import { type AttributeMetadata } from '../attribute' -export type StringSetValue = Set +export type StringSetValue = Set | string[] export interface StringSetAttributeMetadata extends AttributeMetadata { - trim?: boolean - lowercase?: boolean - uppercase?: boolean + /** + * Return a native JavaScript array, rather than a Set. + */ + array?: boolean } diff --git a/src/setup-tests.spec.ts b/src/setup-tests.spec.ts index ccdd9ee2..a8900910 100644 --- a/src/setup-tests.spec.ts +++ b/src/setup-tests.spec.ts @@ -53,6 +53,9 @@ export class TestableTable extends Dyngoose.Table { @Dyngoose.Attribute.StringSet() public testStringSet: Set + @Dyngoose.Attribute.StringSet({ array: true }) + public testStringSetArray: string[] + @Dyngoose.Attribute.String({ lowercase: true }) public lowercaseString: string