Skip to content

Commit

Permalink
feat: allow sets to continue to be native javascript arrays
Browse files Browse the repository at this point in the history
This should help with users migrating to Dyngoose v3

Fixes #667
  • Loading branch information
benhutchins committed Sep 13, 2023
1 parent e1599c7 commit c137a74
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 11 deletions.
2 changes: 2 additions & 0 deletions src/decorator/attribute-types/binary-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export class BinarySetAttributeType extends AttributeType<BinarySetValue, Metada
// returning an empty array means there was a value from DynamoDB with a Set containing no items
if (value.BS == null) {
return null
} else if (this.metadata?.array === true) {
return value.BS
} else {
const binarySet: BinarySetValue = new Set()
value.BS.forEach((item) => {
Expand Down
14 changes: 9 additions & 5 deletions src/decorator/attribute-types/number-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ export class NumberSetAttributeType extends AttributeType<NumberSetValue, Metada
}

fromJSON(values: Array<string | number>): 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
}
}
}
39 changes: 39 additions & 0 deletions src/decorator/attribute-types/string-set.spec.ts
Original file line number Diff line number Diff line change
@@ -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<string>(['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<string>(['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)
})
})
})
2 changes: 2 additions & 0 deletions src/decorator/attribute-types/string-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export class StringSetAttributeType extends AttributeType<StringSetValue, Metada
// returning an empty array means there was a value from DynamoDB with a Set containing no items
if (value.SS == null) {
return null
} else if (this.metadata?.array === true) {
return value.SS
} else {
const stringSet: StringSetValue = new Set()
value.SS.forEach((item) => {
Expand Down
6 changes: 5 additions & 1 deletion src/metadata/attribute-types/binary-set.metadata.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { type AttributeMetadata } from '../attribute'

export type BinarySetValue = Set<Uint8Array>
export type BinarySetValue = Set<Uint8Array> | Uint8Array[]

export interface BinarySetAttributeMetadata extends AttributeMetadata<BinarySetValue> {
/**
* Return a native JavaScript array, rather than a Set.
*/
array?: boolean
}
6 changes: 5 additions & 1 deletion src/metadata/attribute-types/number-set.metadata.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { type AttributeMetadata } from '../attribute'
import { type NumberValue } from './number.metadata'

export type NumberSetValue = Set<NumberValue>
export type NumberSetValue = Set<NumberValue> | number[]

export interface NumberSetAttributeMetadata extends AttributeMetadata<NumberSetValue> {
/**
* Return a native JavaScript array, rather than a Set.
*/
array?: boolean
}
9 changes: 5 additions & 4 deletions src/metadata/attribute-types/string-set.metadata.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { type AttributeMetadata } from '../attribute'

export type StringSetValue = Set<string>
export type StringSetValue = Set<string> | string[]

export interface StringSetAttributeMetadata extends AttributeMetadata<StringSetValue> {
trim?: boolean
lowercase?: boolean
uppercase?: boolean
/**
* Return a native JavaScript array, rather than a Set.
*/
array?: boolean
}
3 changes: 3 additions & 0 deletions src/setup-tests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ export class TestableTable extends Dyngoose.Table {
@Dyngoose.Attribute.StringSet()
public testStringSet: Set<string>

@Dyngoose.Attribute.StringSet({ array: true })
public testStringSetArray: string[]

@Dyngoose.Attribute.String({ lowercase: true })
public lowercaseString: string

Expand Down

0 comments on commit c137a74

Please sign in to comment.