Skip to content

Commit 42ad609

Browse files
**Fix**: autoGen was not respecting values already present on create/update values
1 parent 25b62c7 commit 42ad609

File tree

16 files changed

+69
-41
lines changed

16 files changed

+69
-41
lines changed

changelog.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# DynamoDB Provider Changelog
22

3+
## v1.1.6
4+
5+
- **Fix**: `autoGen` was not respecting values already present on create/update values
6+
37
## v1.1.5
48

59
- **Feature**: `getEntityByType` helper added to the `singleTable.schema` to facilitate dynamic entity extractions

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"homepage": "https://github.com/fabiosenracorrea/dynamodb-provider",
33
"author": "fabiosenracorrea",
44
"name": "dynamodb-provider",
5-
"version": "1.1.5",
5+
"version": "1.1.6",
66
"description": "A dynamodb Provider that simplifies the native api. It packs with a Single Table adaptor/pseudo ORM for single table design",
77
"main": "./lib/cjs/index.js",
88
"module": "./lib/esm/index.js",

src/provider/utils/crud/get.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { StringKey } from 'types';
22

3-
import { removeUndefinedProps } from 'utils/object';
3+
import { omitUndefined } from 'utils/object';
44

55
import { getProjectExpressionParams } from '../projection';
66

@@ -41,7 +41,7 @@ export class ItemGetter extends DynamodbExecutor {
4141
propertiesToRetrieve,
4242
}: GetItemParams<Entity, PKs>): Promise<Entity | undefined> {
4343
const { Item } = await this._getItem<Entity>(
44-
removeUndefinedProps({
44+
omitUndefined({
4545
TableName: table,
4646

4747
Key: key,

src/provider/utils/crud/update/updater.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { StringKey } from 'types';
44

5-
import { removeUndefinedProps } from 'utils/object';
5+
import { omitUndefined } from 'utils/object';
66

77
import { DBUpdateItemParams, DynamodbExecutor } from '../../dynamoDB';
88

@@ -57,10 +57,10 @@ export class ItemUpdater extends DynamodbExecutor {
5757
const { key, table, remove, returnUpdatedProperties } = params;
5858

5959
const atomic = params.atomicOperations || [];
60-
const values = removeUndefinedProps(params.values || {});
60+
const values = omitUndefined(params.values || {});
6161
const conditions = params.conditions || [];
6262

63-
return removeUndefinedProps({
63+
return omitUndefined({
6464
TableName: table,
6565

6666
Key: key,

src/provider/utils/listing/list.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
import { AnyObject } from 'types';
33

4-
import { removeUndefinedProps } from 'utils/object';
4+
import { omitUndefined } from 'utils/object';
55

66
import { DBScanParams, DynamodbExecutor } from '../dynamoDB';
77

@@ -112,7 +112,7 @@ export class ItemLister extends DynamodbExecutor {
112112

113113
const isPaginated = _internalStartKey || paginationToken;
114114

115-
return removeUndefinedProps({
115+
return omitUndefined({
116116
TableName: table,
117117

118118
ConsistentRead: consistentRead,
@@ -153,7 +153,7 @@ export class ItemLister extends DynamodbExecutor {
153153
}),
154154
);
155155

156-
return removeUndefinedProps({
156+
return omitUndefined({
157157
items: Items,
158158
paginationToken: lastKey ? toPaginationToken(lastKey) : undefined,
159159
});

src/singleTable/adaptor/definitions/operations/crud/delete.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { DeleteItemParams } from 'provider';
22

33
import { AnyObject } from 'types';
4-
import { removeUndefinedProps } from 'utils/object';
4+
import { omitUndefined } from 'utils/object';
55
import { BaseSingleTableOperator } from '../../executor';
66
import { getPrimaryKey, SingleTableKeyReference } from '../../key';
77

@@ -16,7 +16,7 @@ export class SingleTableRemover extends BaseSingleTableOperator {
1616

1717
conditions,
1818
}: SingleTableDeleteParams<AnyObject>): DeleteItemParams<SingleTableKeyReference> {
19-
return removeUndefinedProps({
19+
return omitUndefined({
2020
conditions,
2121

2222
table: this.config.table,

src/singleTable/adaptor/definitions/operations/crud/get.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { GetItemParams } from 'provider/utils';
22

3-
import { removeUndefinedProps } from 'utils/object';
3+
import { omitUndefined } from 'utils/object';
44
import { BaseSingleTableOperator } from '../../executor';
55
import { getPrimaryKey, SingleTableKeyReference } from '../../key';
66
import { resolveProps } from '../../parsers';
@@ -17,7 +17,7 @@ export class SingleTableGetter extends BaseSingleTableOperator {
1717
propertiesToRetrieve,
1818
}: SingleTableGetParams<Entity>): Promise<Entity | undefined> {
1919
const item = await this.db.get<Entity>(
20-
removeUndefinedProps({
20+
omitUndefined({
2121
consistentRead,
2222
propertiesToRetrieve,
2323

src/singleTable/adaptor/definitions/operations/crud/update.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import { AnyObject, StringKey } from 'types';
55

6-
import { removeUndefinedProps } from 'utils/object';
6+
import { omitUndefined } from 'utils/object';
77
import { toTruthyList } from 'utils/array';
88

99
import { UpdateParams } from 'provider';
@@ -122,7 +122,7 @@ export class SingleTableUpdater extends BaseSingleTableOperator {
122122
(params.expiresAt && this.config.expiresAt)
123123
);
124124

125-
return removeUndefinedProps({
125+
return omitUndefined({
126126
table: this.config.table,
127127

128128
key: getPrimaryKey(params, this.config),

src/singleTable/adaptor/definitions/operations/query/query.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
QueryResult,
88
} from 'provider/utils';
99

10-
import { removeUndefinedProps } from 'utils/object';
10+
import { omitUndefined } from 'utils/object';
1111

1212
import { convertKey, KeyValue } from '../../key';
1313
import { SingleTableConfig } from '../../config';
@@ -80,7 +80,7 @@ export class SingleTableQueryBuilder extends BaseSingleTableOperator {
8080
},
8181

8282
rangeKey: range
83-
? removeUndefinedProps({
83+
? omitUndefined({
8484
...range,
8585

8686
high: range.operation === 'between' ? this.convertKey(range.high) : undefined,

src/singleTable/adaptor/definitions/tableIndex/tableIndex.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ensureArray } from 'utils/array';
22
import { isNonNullable } from 'utils/checkers';
3-
import { removeUndefinedProps } from 'utils/object';
3+
import { omitUndefined } from 'utils/object';
44

55
import { SingleTableConfig } from '../config';
66
import { convertKey, KeyValue, SingleTableKeyReference } from '../key';
@@ -46,7 +46,7 @@ function getIndexRecord({
4646
return convertKey(key!, config);
4747
});
4848

49-
return removeUndefinedProps({
49+
return omitUndefined({
5050
[hashName]: hashValue,
5151

5252
[rangeName]: rangeValue,

src/singleTable/model/definitions/entity/autoGen.spec.ts

+33-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
import { getId } from '../../../../utils/id';
3-
import { removeUndefinedProps } from '../../../../utils/object';
3+
import { omitUndefined } from '../../../../utils/object';
44

55
import { addAutoGenParams } from './autoGen';
66

@@ -9,7 +9,9 @@ jest.mock('../../../../utils/id', () => ({
99
}));
1010

1111
jest.mock('../../../../utils/object', () => ({
12-
removeUndefinedProps: jest.fn((obj) => obj),
12+
omitUndefined: jest.fn((obj) =>
13+
Object.fromEntries(Object.entries(obj).filter(([_, value]) => value !== undefined)),
14+
),
1315
}));
1416

1517
describe('single table model: addAutoGenParams', () => {
@@ -30,7 +32,7 @@ describe('single table model: addAutoGenParams', () => {
3032
});
3133

3234
it('should correctly generate values using UUID generator', () => {
33-
const values = { id: '123', name: 'John Doe' };
35+
const values = { name: 'John Doe' };
3436
const genConfig = { id: 'UUID' } as const;
3537

3638
(getId as jest.Mock).mockReturnValue('mocked-uuid');
@@ -42,7 +44,7 @@ describe('single table model: addAutoGenParams', () => {
4244
});
4345

4446
it('should correctly generate values using KSUID generator', () => {
45-
const values = { id: '123', name: 'John Doe' };
47+
const values = { name: 'John Doe' };
4648
const genConfig = { id: 'KSUID' } as const;
4749

4850
(getId as jest.Mock).mockReturnValue('mocked-ksuid');
@@ -54,7 +56,7 @@ describe('single table model: addAutoGenParams', () => {
5456
});
5557

5658
it('should correctly generate values using timestamp generator', () => {
57-
const values = { id: '123', name: 'John Doe', createdAt: '' };
59+
const values = { id: '123', name: 'John Doe' };
5860
const genConfig = { createdAt: 'timestamp' } as const;
5961

6062
const mockTimestamp = '2024-01-01T00:00:00.000Z';
@@ -69,7 +71,7 @@ describe('single table model: addAutoGenParams', () => {
6971
});
7072

7173
it('should correctly generate values using count generator', () => {
72-
const values = { id: '123', name: 'John Doe', counter: 5 };
74+
const values = { id: '123', name: 'John Doe' };
7375
const genConfig = { counter: 'count' } as const;
7476

7577
const result = addAutoGenParams(values, genConfig);
@@ -78,20 +80,42 @@ describe('single table model: addAutoGenParams', () => {
7880
});
7981

8082
it('should handle custom function generators', () => {
81-
const values = { id: '123', name: 'John Doe', custom: 'initial' };
83+
const values = { id: '123', name: 'John Doe' };
8284
const genConfig = { custom: () => 'custom-generated-value' } as const;
8385

8486
const result = addAutoGenParams(values, genConfig);
8587

8688
expect(result).toEqual({ id: '123', name: 'John Doe', custom: 'custom-generated-value' });
8789
});
8890

89-
it('should remove undefined properties using removeUndefinedProps', () => {
91+
it('should remove undefined properties using omitUndefined', () => {
9092
const values = { name: 'John Doe', some: undefined };
9193
const genConfig = { age: 'count' } as const;
9294

9395
addAutoGenParams(values, genConfig);
9496

95-
expect(removeUndefinedProps).toHaveBeenCalledWith({ name: 'John Doe', age: 0 });
97+
expect(omitUndefined).toHaveBeenCalledWith({ name: 'John Doe', age: 0 });
98+
});
99+
100+
it('should not autogenerate if value is present', () => {
101+
const values = { id: '123', name: 'John Doe' };
102+
const genConfig = { id: 'UUID' } as const;
103+
104+
(getId as jest.Mock).mockReturnValueOnce('mocked-uuid');
105+
106+
const result = addAutoGenParams(values, genConfig);
107+
108+
expect(result).toEqual({ id: '123', name: 'John Doe' });
109+
});
110+
111+
it('should autogenerate if value is present only as undefined', () => {
112+
const values = { id: undefined, name: 'John Doe' };
113+
const genConfig = { id: 'UUID' } as const;
114+
115+
(getId as jest.Mock).mockReturnValueOnce('mocked-uuid');
116+
117+
const result = addAutoGenParams(values, genConfig);
118+
119+
expect(result).toEqual({ id: 'mocked-uuid', name: 'John Doe' });
96120
});
97121
});

src/singleTable/model/definitions/entity/autoGen.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { AnyObject, AtLeastOne } from 'types';
44

55
import { getId } from 'utils/id';
6-
import { removeUndefinedProps } from 'utils/object';
6+
import { omitUndefined } from 'utils/object';
77

88
type LifeCycleParams = AtLeastOne<{
99
onUpdate?: boolean;
@@ -97,9 +97,9 @@ export function addAutoGenParams<Values extends AnyObject>(
9797
typeof genRef === 'function' ? genRef() : generators[genRef!]?.(),
9898
]);
9999

100-
return removeUndefinedProps({
101-
...values,
102-
100+
return omitUndefined({
103101
...Object.fromEntries(generated),
102+
103+
...omitUndefined(values),
104104
});
105105
}

src/singleTable/model/definitions/entity/crud.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { SingleTableConfig } from 'singleTable/adaptor';
1111

1212
import { AnyObject, MakePartial } from 'types';
1313

14-
import { removeUndefinedProps } from 'utils/object';
14+
import { omitUndefined } from 'utils/object';
1515
import { EntityKeyParams, KeyResolvers } from '../key';
1616

1717
import { addAutoGenParams, AutoGenParams } from './autoGen';
@@ -156,7 +156,7 @@ export function getCRUDParamGetters<
156156

157157
const resolvedValues = addAutoGenParams(values ?? {}, autoGen?.onUpdate);
158158

159-
return removeUndefinedProps({
159+
return omitUndefined({
160160
atomicOperations,
161161
conditions,
162162
remove,

src/singleTable/model/definitions/entity/indexParams.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { SingleTableConfig } from 'singleTable/adaptor';
66
import { ensureArray } from 'utils/array';
77
import { isNonNullable } from 'utils/checkers';
88

9-
import { removeUndefinedProps } from 'utils/object';
9+
import { omitUndefined } from 'utils/object';
1010
import { IndexMapping, IndexParams, SingleTableConfigWithIndex } from '../indexes';
1111
import { KeyResolvers, resolveKeys } from '../key';
1212
import { getRangeQueriesParams, RangeQueryResultProps } from '../range';
@@ -122,7 +122,7 @@ export function getEntityIndexParams<
122122
return [
123123
index,
124124

125-
removeUndefinedProps({
125+
omitUndefined({
126126
partitionKey,
127127
rangeKey,
128128
}),
@@ -143,7 +143,7 @@ export function getEntityIndexParams<
143143

144144
return [
145145
index,
146-
removeUndefinedProps({
146+
omitUndefined({
147147
partitionKey,
148148
rangeKey,
149149
}),

src/utils/object.spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { omit, pick, removeUndefinedProps } from './object';
1+
import { omit, pick, omitUndefined } from './object';
22

33
describe('object utils', () => {
44
describe('pick', () => {
@@ -40,7 +40,7 @@ describe('object utils', () => {
4040
});
4141
});
4242

43-
describe('removeUndefinedProps', () => {
43+
describe('omitUndefined', () => {
4444
it('should remove all undefined properties', () => {
4545
const obj = {
4646
some: '22',
@@ -51,7 +51,7 @@ describe('object utils', () => {
5151
hello: undefined,
5252
};
5353

54-
const result = removeUndefinedProps(obj);
54+
const result = omitUndefined(obj);
5555

5656
expect(result).toStrictEqual({
5757
some: '22',

src/utils/object.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export function omit<Obj extends AnyObject, Key extends keyof Obj>(
2222
return curated as Omit<Obj, Key>;
2323
}
2424

25-
export function removeUndefinedProps<Obj extends AnyObject>(object: Obj): Obj {
25+
export function omitUndefined<Obj extends AnyObject>(object: Obj): Obj {
2626
const curated = Object.fromEntries(
2727
Object.entries(object).filter(([_, value]) => value !== undefined),
2828
);

0 commit comments

Comments
 (0)