From 0e9b2296d2704a1f7991db9f0b58f390d680fefd Mon Sep 17 00:00:00 2001 From: Luciano Fantone Date: Thu, 21 Jan 2021 15:01:57 +0100 Subject: [PATCH 1/2] chore: bump typescript version to latest --- package-lock.json | 213 +++++++++++++++++++++++----------------------- package.json | 4 +- 2 files changed, 108 insertions(+), 109 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9fce305..c66d757 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,60 +5,29 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "@babel/highlight": "^7.0.0" + "@babel/highlight": "^7.10.4" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { + "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@types/aws-sdk": { @@ -178,6 +147,15 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, "ansi-wrap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", @@ -646,6 +624,17 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, "chokidar": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz", @@ -1091,9 +1080,9 @@ "dev": true }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, "duplexify": { @@ -1626,7 +1615,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1647,12 +1637,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1667,17 +1659,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1794,7 +1789,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1806,6 +1802,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1820,6 +1817,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1827,12 +1825,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1851,6 +1851,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1931,7 +1932,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1943,6 +1945,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2028,7 +2031,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2064,6 +2068,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2083,6 +2088,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2126,12 +2132,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -4755,6 +4763,23 @@ "is-utf8": "^0.2.0" } }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + } + } + }, "sver-compat": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", @@ -4903,71 +4928,45 @@ } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "tslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz", - "integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", "chalk": "^2.3.0", "commander": "^2.12.1", - "diff": "^3.2.0", + "diff": "^4.0.1", "glob": "^7.1.1", - "js-yaml": "^3.13.0", + "js-yaml": "^3.13.1", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", + "mkdirp": "^0.5.3", "resolve": "^1.3.2", "semver": "^5.3.0", - "tslib": "^1.8.0", + "tslib": "^1.13.0", "tsutils": "^2.29.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "minimist": "^1.2.5" } } } @@ -5012,9 +5011,9 @@ "dev": true }, "typescript": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", - "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", + "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", "dev": true }, "uglify-js": { diff --git a/package.json b/package.json index 10858cc..2c9ddbe 100644 --- a/package.json +++ b/package.json @@ -58,8 +58,8 @@ "gulp-tslint": "8.1.4", "gulp-typescript": "5.0.1", "jasmine-console-reporter": "3.1.0", - "tslint": "5.16.0", - "typescript": "3.4.5" + "tslint": "6.1.3", + "typescript": "4.1.3" }, "peerDependencies": { "aws-sdk": "2.x" From cb5b73c39fbd19c6686a3407888b2fa7238b7fb0 Mon Sep 17 00:00:00 2001 From: Luciano Fantone Date: Thu, 21 Jan 2021 15:02:28 +0100 Subject: [PATCH 2/2] feat: allow optional pagination of query & scan responses --- lib/dynamodb-wrapper.d.ts | 3 +++ lib/dynamodb-wrapper.spec.ts | 19 +++++++++++++++++-- lib/dynamodb-wrapper.ts | 30 ++++++++++++++++++++---------- lib/utils.ts | 2 +- test/mock-dynamodb.ts | 2 +- 5 files changed, 42 insertions(+), 14 deletions(-) diff --git a/lib/dynamodb-wrapper.d.ts b/lib/dynamodb-wrapper.d.ts index a00c464..eb06a12 100644 --- a/lib/dynamodb-wrapper.d.ts +++ b/lib/dynamodb-wrapper.d.ts @@ -1,4 +1,5 @@ declare interface IDynamoDBWrapperOptions { + autoPagination?: boolean; tableNamePrefix?: string; groupDelayMs?: number; maxRetries?: number; @@ -21,10 +22,12 @@ declare interface IBatchWriteItemOption { declare interface IQueryOptions { groupDelayMs?: number; + autoPagination?: boolean; } declare interface IScanOptions { groupDelayMs?: number; + autoPagination?: boolean; } declare type TDictionary = { [key: string] : T; }; diff --git a/lib/dynamodb-wrapper.spec.ts b/lib/dynamodb-wrapper.spec.ts index 9bf8f66..87c3e84 100644 --- a/lib/dynamodb-wrapper.spec.ts +++ b/lib/dynamodb-wrapper.spec.ts @@ -4,7 +4,7 @@ import { DynamoDBWrapper } from './dynamodb-wrapper'; describe('lib/dynamodb-wrapper', () => { - function _setupDynamoDBWrapper(options?: IMockDynamoDBOptions) { + function _setupDynamoDBWrapper(options?: IMockDynamoDBOptions, wrapperOptions?: IDynamoDBWrapperOptions) { options = options || {}; let mockDynamoDB = new MockDynamoDB(options); return { @@ -15,7 +15,8 @@ describe('lib/dynamodb-wrapper', () => { maxRetries: 2, retryDelayOptions: { base: 0 - } + }, + ...wrapperOptions }) }; } @@ -279,6 +280,20 @@ describe('lib/dynamodb-wrapper', () => { expect(response.ConsumedCapacity).not.toBeDefined(); }); + it('should query only once when auto pagination is disabled', async () => { + let params = _setupQueryParams(); + let mock = _setupDynamoDBWrapper(null, { autoPagination: false }); + let dynamoDB = mock.dynamoDB; + let dynamoDBWrapper = mock.dynamoDBWrapper; + + spyOn(dynamoDB, 'query').and.callThrough(); + let response = await dynamoDBWrapper.query(params); + + expect(dynamoDB.query).toHaveBeenCalledTimes(1); + + expect(response.LastEvaluatedKey).toEqual({ id: { S: 'foo' } }); + }); + it('should aggregate consumed capacity (TOTAL) from multiple responses', async () => { let params = _setupQueryParams('TOTAL'); let mock = _setupDynamoDBWrapper(); diff --git a/lib/dynamodb-wrapper.ts b/lib/dynamodb-wrapper.ts index 1028f28..976c686 100644 --- a/lib/dynamodb-wrapper.ts +++ b/lib/dynamodb-wrapper.ts @@ -15,6 +15,7 @@ export class DynamoDBWrapper { public groupDelayMs: number; public maxRetries: number; public retryDelayOptions: any; + public autoPagination: boolean; constructor(dynamoDB: any, options?: IDynamoDBWrapperOptions) { this.dynamoDB = dynamoDB; @@ -24,6 +25,8 @@ export class DynamoDBWrapper { options.retryDelayOptions = options.retryDelayOptions || {}; this.tableNamePrefix = typeof options.tableNamePrefix === 'string' ? options.tableNamePrefix : ''; this.groupDelayMs = getNonNegativeInteger([options.groupDelayMs, 100]); + this.autoPagination = options.autoPagination ?? true; + this.maxRetries = getNonNegativeInteger([options.maxRetries, 10]); this.retryDelayOptions = {}; this.retryDelayOptions.base = getNonNegativeInteger([options.retryDelayOptions.base, 100]); @@ -147,8 +150,9 @@ export class DynamoDBWrapper { // set default options options = options || {}; options.groupDelayMs = getNonNegativeInteger([options.groupDelayMs, this.groupDelayMs]); + options.autoPagination = options.autoPagination ?? this.autoPagination; - let responses = await this._queryOrScanHelper('query', params, options.groupDelayMs); + let responses = await this._queryOrScanHelper('query', params, options); return _makeQueryOrScanResponse(responses); } @@ -168,8 +172,9 @@ export class DynamoDBWrapper { // set default options options = options || {}; options.groupDelayMs = getNonNegativeInteger([options.groupDelayMs, this.groupDelayMs]); + options.autoPagination = options.autoPagination ?? this.autoPagination; - let responses = await this._queryOrScanHelper('scan', params, options.groupDelayMs); + let responses = await this._queryOrScanHelper('scan', params, options); return _makeQueryOrScanResponse(responses); } @@ -215,19 +220,21 @@ export class DynamoDBWrapper { return _makeBatchWriteItemResponse(tableNames, responsesPerTable, totalRequestItems); } - private async _queryOrScanHelper(method: string, params: any, groupDelayMs: number): Promise { + private async _queryOrScanHelper(method: string, params: any, { groupDelayMs, autoPagination }: IQueryOptions ): Promise { let list = []; // first page of data let res = await this._callDynamoDB(method, params); list.push(res); - // make subsequent requests to get remaining pages of data - while (res.LastEvaluatedKey) { - await wait(groupDelayMs); - params.ExclusiveStartKey = res.LastEvaluatedKey; - res = await this._callDynamoDB(method, params); - list.push(res); + if (autoPagination) { + // make subsequent requests to get remaining pages of data + while (res.LastEvaluatedKey) { + await wait(groupDelayMs); + params.ExclusiveStartKey = res.LastEvaluatedKey; + res = await this._callDynamoDB(method, params); + list.push(res); + } } return list; @@ -406,17 +413,20 @@ function _makeQueryOrScanResponse(responses: any): any { let count = 0; let scannedCount = 0; let items = []; + let lastEvaluatedKey = null; for (let res of responses) { count += res.Count; scannedCount += res.ScannedCount; + lastEvaluatedKey = res.LastEvaluatedKey; appendArray(items, res.Items); } let result: any = { Count: count, ScannedCount: scannedCount, - Items: items + Items: items, + LastEvaluatedKey: lastEvaluatedKey }; if (responses[0].ConsumedCapacity) { diff --git a/lib/utils.ts b/lib/utils.ts index 3dfefb9..86e11e7 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -24,7 +24,7 @@ export function appendArray(array1: any[], array2: any[]) { } } -export function wait(ms: number): Promise { +export function wait(ms: number): Promise { return new Promise(resolve => { setTimeout(() => { resolve(); diff --git a/test/mock-dynamodb.ts b/test/mock-dynamodb.ts index cb3efcf..d2396f7 100644 --- a/test/mock-dynamodb.ts +++ b/test/mock-dynamodb.ts @@ -197,7 +197,7 @@ export class MockDynamoDB { } if (this._countRequests < 3) { - response['LastEvaluatedKey'] = 'foo'; + response['LastEvaluatedKey'] = { id: { S: 'foo' } }; } resolve(response);