diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4768bbc5..6a24474e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,7 +7,6 @@ on: push: branches: [ main ] pull_request: - branches: [ main ] jobs: build: @@ -16,7 +15,7 @@ jobs: strategy: matrix: - node-version: [20.x] + node-version: [20.x, 22.x, 24.x] steps: - uses: actions/checkout@v4 @@ -31,7 +30,5 @@ jobs: - run: npm ci - run: npm run build --if-present - run: npm run lint --if-present - - name: DynamoDB Client v2 Tests - run: npm run test:v2 - - name: DynamoDB Client v3 Tests - run: npm run test:v3 + - name: DynamoDB Tests + run: npm test diff --git a/README.md b/README.md index bdc7c8d0..a601f05d 100644 --- a/README.md +++ b/README.md @@ -71,13 +71,6 @@ const client = new DynamoDBClient({ }) ``` -If you are using the legacy AWS SDK V2, import the AWS `DynamoDB` class and create a `DocumentClient` instance. - -```javascript -import DynamoDB from 'aws-sdk/clients/dynamodb' -const client = new DynamoDB.DocumentClient(params) -``` - Note: you can use the Table.setClient API to defer setting the client or replace the client at any time. Initialize your OneTable `Table` instance and define your models via a schema. diff --git a/jest.config.js b/jest.config.js index 58f5a0b6..78be1f98 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,7 +1,6 @@ /* Jest configuration */ -process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE = '1'; module.exports = { coveragePathIgnorePatterns: ['node_modules', 'test/utils'], coverageDirectory: 'coverage', diff --git a/package-lock.json b/package-lock.json index 612dfcac..b14bc16e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,6 @@ "@types/aws-lambda": "^8.10.146", "@types/jest": "^29.5.14", "@types/node": "^22.10.2", - "aws-sdk": "^2.1692.0", "dataloader": "^2.2.3", "dynamo-db-local": "^7.0.0", "eslint": "^9.17.0", @@ -2685,52 +2684,6 @@ "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", "dev": true }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sdk": { - "version": "2.1692.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1692.0.tgz", - "integrity": "sha512-x511uiJ/57FIsbgUe5csJ13k3uzu25uWQE+XqfBis/sB0SFoiElJWXRkgEAUh0U6n40eT3ay5Ue4oPkRMu1LYw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.6.2" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aws-sdk/node_modules/uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -2844,26 +2797,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/bowser": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", @@ -2944,42 +2877,12 @@ "node-int64": "^0.4.0" } }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3229,23 +3132,6 @@ "node": ">=0.10.0" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -3321,27 +3207,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -3522,15 +3387,6 @@ "node": ">=0.10.0" } }, - "node_modules/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -3716,15 +3572,6 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3772,25 +3619,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -3856,18 +3684,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -3883,57 +3699,6 @@ "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -3961,12 +3726,6 @@ "node": ">=10.17.0" } }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -4036,40 +3795,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", @@ -4109,21 +3840,6 @@ "node": ">=6" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -4157,27 +3873,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4847,15 +4542,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5378,15 +5064,6 @@ "node": ">=8" } }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5460,16 +5137,6 @@ } ] }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -5541,12 +5208,6 @@ "node": ">=10" } }, - "node_modules/sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==", - "dev": true - }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -5556,23 +5217,6 @@ "semver": "bin/semver.js" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -5956,35 +5600,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", - "dev": true, - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, "node_modules/utility-types": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", @@ -6061,25 +5676,6 @@ "node": ">= 8" } }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -6125,28 +5721,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/xml2js": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", - "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", - "dev": true, - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 7378d599..7259a423 100644 --- a/package.json +++ b/package.json @@ -29,11 +29,7 @@ "prepare": "npm run build", "_prepublishOnly": "npm test && npm run lint", "test": "jest", - "test:v2": "DDB_CLIENT_VERSION=v2 jest", - "test:v3": "DDB_CLIENT_VERSION=v3 jest", - "test-cov": "jest --coverage", - "test-cov:v2": "npm run test:v2 -- --coverage", - "test-cov:v3": "npm run test:v3 -- --coverage" + "test-cov": "jest --coverage" }, "repository": { "type": "git", @@ -52,7 +48,6 @@ "@types/aws-lambda": "^8.10.146", "@types/jest": "^29.5.14", "@types/node": "^22.10.2", - "aws-sdk": "^2.1692.0", "dataloader": "^2.2.3", "dynamo-db-local": "^7.0.0", "eslint": "^9.17.0", @@ -67,7 +62,7 @@ "Dynamo" ], "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" + "node": ">=20.0.0", + "npm": ">=10.0.0" } } diff --git a/samples/sensedeep/src/index.js b/samples/sensedeep/src/index.js index e4d973c8..688f8d76 100644 --- a/samples/sensedeep/src/index.js +++ b/samples/sensedeep/src/index.js @@ -2,13 +2,16 @@ SenseDeep logging database access */ -import DynamoDB from 'aws-sdk/clients/dynamodb.js' +import {DynamoDBClient} from '@aws-sdk/client-dynamodb' import {Table} from 'dynamodb-onetable' +import {Dynamo} from 'dynamodb-onetable/Dynamo' import Schema from './schema.js' -const client = new DynamoDB.DocumentClient({ - // Configure your credentials here or define AWS_PROFILE. - region: 'us-east-1', +const client = new Dynamo({ + client: new DynamoDBClient({ + // Configure your credentials here or define AWS_PROFILE. + region: 'us-east-1', + }), }) /* diff --git a/src/Table.js b/src/Table.js index 5fba3fa5..d60d4b7d 100644 --- a/src/Table.js +++ b/src/Table.js @@ -14,22 +14,6 @@ import {Schema} from './Schema.js' import {Metrics} from './Metrics.js' import {OneTableArgError, OneTableError} from './Error.js' -/* - AWS V2 DocumentClient methods - */ -const DocumentClientMethods = { - delete: 'delete', - get: 'get', - find: 'query', - put: 'put', - scan: 'scan', - update: 'update', - batchGet: 'batchGet', - batchWrite: 'batchWrite', - transactGet: 'transactGet', - transactWrite: 'transactWrite', -} - /* Safety string required on API to delete a table */ @@ -116,12 +100,11 @@ export class Table { setClient(client) { if (client.send && !client.V3) { - // V3 SDK and not yet wrapped by Dynamo + // Not yet wrapped by Dynamo client = new Dynamo({client}) } this.client = client - this.V3 = client.V3 - this.service = this.V3 ? this.client : this.client.service + this.service = this.client } setParams(params) { @@ -332,11 +315,7 @@ export class Table { let result this.log.trace(`OneTable createTable for "${this.name}"`, {def}) - if (this.V3) { - result = await this.service.createTable(def) - } else { - result = await this.service.createTable(def).promise() - } + result = await this.service.createTable(def) /* Wait for table to become active. Must do if setting a TTL attribute @@ -367,11 +346,7 @@ export class Table { TableName: this.name, TimeToLiveSpecification: params.TimeToLiveSpecification, } - if (this.V3) { - await this.service.updateTimeToLive(def) - } else { - await this.service.updateTimeToLive(def).promise() - } + await this.service.updateTimeToLive(def) } return result } @@ -392,11 +367,7 @@ export class Table { async deleteTable(confirmation) { if (confirmation == ConfirmRemoveTable) { this.log.trace(`OneTable deleteTable for "${this.name}"`) - if (this.V3) { - await this.service.deleteTable({TableName: this.name}) - } else { - await this.service.deleteTable({TableName: this.name}).promise() - } + await this.service.deleteTable({TableName: this.name}) } else { throw new OneTableArgError(`Missing required confirmation "${ConfirmRemoveTable}"`) } @@ -477,29 +448,17 @@ export class Table { TableName: params.TableName, TimeToLiveSpecification: params.TimeToLiveSpecification, } - if (this.V3) { - await this.service.updateTimeToLive(def) - } else { - await this.service.updateTimeToLive(def).promise() - } + await this.service.updateTimeToLive(def) } this.log.trace(`OneTable updateTable for "${this.name}"`, {def}) - if (this.V3) { - return await this.service.updateTable(def) - } else { - return await this.service.updateTable(def).promise() - } + return await this.service.updateTable(def) } /* Return the raw AWS table description */ async describeTable() { - if (this.V3) { - return await this.service.describeTable({TableName: this.name}) - } else { - return await this.service.describeTable({TableName: this.name}).promise() - } + return await this.service.describeTable({TableName: this.name}) } /* @@ -514,12 +473,7 @@ export class Table { Return a list of tables in the AWS region described by the Table instance */ async listTables() { - let results - if (this.V3) { - results = await this.service.listTables({}) - } else { - results = await this.service.listTables({}).promise() - } + let results = await this.service.listTables({}) return results.TableNames } @@ -642,11 +596,7 @@ export class Table { cmd.ReturnItemCollectionMetrics = 'SIZE' } this.log[params.log ? 'info' : 'trace'](`OneTable "${op}" "${model}"`, {trace}) - if (this.V3) { - result = await client[op](cmd) - } else { - result = await client[DocumentClientMethods[op]](cmd).promise() - } + result = await client[op](cmd) } catch (err) { // V3 stores the error in 'name' (Ugh!) let code = err.code || err.name @@ -915,16 +865,12 @@ export class Table { // convert each of the get requests into a single RequestItem with unique Keys const requestItems = Object.keys(groupedByTableName).reduce((requestItems, tableName) => { // batch get does not support duplicate Keys, so we need to make them unique - // it's complex because we have the unmarshalled values on the Keys when it's V3 const allKeys = groupedByTableName[tableName].map((each) => each.Key) const uniqueKeys = allKeys.filter((key1, index1, self) => { const index2 = self.findIndex((key2) => { return Object.keys(key2).every((prop) => { - if (this.V3) { - const type = Object.keys(key1[prop])[0] // { S: "XX" } => type is S - return key2[prop][type] === key1[prop][type] - } - return key2[prop] === key1[prop] + const type = Object.keys(key1[prop])[0] // { S: "XX" } => type is S + return key2[prop][type] === key1[prop][type] }) }) return index2 === index1 @@ -940,22 +886,17 @@ export class Table { return commands.map((command, index) => { const {model, params} = expressions[index] - // each key is { pk: { S: "XX" } } when V3 or { pk: "XX" } when V2 - // on map function, key will be pk and unmarshalled will be { S: "XX" }, OR "XXX" + // each key is { pk: { S: "XX" } } in marshalled format const criteria = Object.entries(command.Key).map(([key, unmarshalled]) => { - if (this.V3) { - const type = Object.keys(unmarshalled)[0] // the type will be S - return [[key, type], unmarshalled[type]] // return [[pk, S], "XX"] - } - return [[key], unmarshalled] + const type = Object.keys(unmarshalled)[0] // the type will be S + return [[key, type], unmarshalled[type]] // return [[pk, S], "XX"] }) // finds the matching object in the unmarshalled Responses array with criteria Key above const findByKeyUnmarshalled = (items = []) => items.find((item) => { return criteria.every(([[prop, type], value]) => { - if (type) return item[prop][type] === value // if it has a type it means it is V3 - return item[prop] === value + return item[prop][type] === value }) }) @@ -1060,23 +1001,13 @@ export class Table { */ marshall(item, params) { let client = params.client || this.client - if (client.V3) { - let options = client.params.marshall - if (Array.isArray(item)) { - for (let i = 0; i < item.length; i++) { - item[i] = client.marshall(item[i], options) - } - } else { - item = client.marshall(item, options) + let options = client.params.marshall + if (Array.isArray(item)) { + for (let i = 0; i < item.length; i++) { + item[i] = client.marshall(item[i], options) } } else { - if (Array.isArray(item)) { - for (let i = 0; i < item.length; i++) { - item = this.marshallv2(item, params) - } - } else { - item = this.marshallv2(item, params) - } + item = client.marshall(item, options) } return item } @@ -1085,53 +1016,14 @@ export class Table { Marshall data out of DynamoDB format */ unmarshall(item, params) { - if (this.V3) { - let client = params.client ? params.client : this.client - let options = client.params.unmarshall - if (Array.isArray(item)) { - for (let i = 0; i < item.length; i++) { - item[i] = client.unmarshall(item[i], options) - } - } else { - item = client.unmarshall(item, options) - } - } else { - if (Array.isArray(item)) { - for (let i = 0; i < item.length; i++) { - item[i] = this.unmarshallv2(item[i]) - } - } else { - item = this.unmarshallv2(item) - } - } - return item - } - - marshallv2(item, params) { let client = params.client ? params.client : this.client - for (let [key, value] of Object.entries(item)) { - if (value instanceof Set) { - item[key] = client.createSet(Array.from(value)) - } - } - return item - } - - unmarshallv2(item) { - for (let [key, value] of Object.entries(item)) { - if ( - value != null && - typeof value == 'object' && - value.wrapperName == 'Set' && - Array.isArray(value.values) - ) { - let list = value.values - if (value.type == 'Binary') { - // Match AWS SDK V3 behavior - list = list.map((v) => new Uint8Array(v)) - } - item[key] = new Set(list) + let options = client.params.unmarshall + if (Array.isArray(item)) { + for (let i = 0; i < item.length; i++) { + item[i] = client.unmarshall(item[i], options) } + } else { + item = client.unmarshall(item, options) } return item } diff --git a/test/basic.ts b/test/basic.ts index e3bd0d5e..b189003f 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -1,7 +1,7 @@ /* basic.ts - Basic create / get */ -import {AWS, Client, Table, print, dump} from './utils/init' +import {Client, Table, print, dump} from './utils/init' // jest.setTimeout(7200 * 1000) diff --git a/test/batch.ts b/test/batch.ts index 99332f22..0a98c838 100644 --- a/test/batch.ts +++ b/test/batch.ts @@ -3,7 +3,7 @@ */ import {DefaultSchema} from './schemas' -import {Client, isV2, isV3, Table} from './utils/init' +import {Client, Table} from './utils/init' // jest.setTimeout(7200 * 1000) diff --git a/test/context.ts b/test/context.ts index edd7f80f..70617311 100644 --- a/test/context.ts +++ b/test/context.ts @@ -1,7 +1,7 @@ /* context.ts - Test context APIs */ -import {AWS, Client, Match, Table, print, dump} from './utils/init' +import {Client, Match, Table, print, dump} from './utils/init' import {TenantSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/create-destroy-table.ts b/test/create-destroy-table.ts index 8092b78f..92872bfd 100644 --- a/test/create-destroy-table.ts +++ b/test/create-destroy-table.ts @@ -1,7 +1,7 @@ /* create-destroy-table.ts */ -import {AWS, Client, Table, print, dump, delay} from './utils/init' +import {Client, Table, print, dump, delay} from './utils/init' import {FullSchema} from './schemas' const TableName = 'CreateDestroyTable' diff --git a/test/crypto.ts b/test/crypto.ts index bbe2589f..7fa07797 100644 --- a/test/crypto.ts +++ b/test/crypto.ts @@ -1,7 +1,7 @@ /* crypto.ts - CRUD with crypto */ -import {AWS, Client, Match, Table, print, dump, delay, isV3, isV2} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {CryptoSchema} from './schemas' const Crypto = { @@ -51,18 +51,10 @@ test('Get', async () => { test('Get raw ', async () => { user = await User.get({id: user.id}, {hidden: true, parse: false}) - if (isV3()) { - expect(user.pk.S).toMatch(/^User#/) - expect(user.email.S).toBeDefined() - expect(user.email.S).not.toMatch('peter@example.com') - expect(user.email.S).toMatch(/^primary/) - } - if (isV2()) { - expect(user.pk).toMatch(/^User#/) - expect(user.email).toBeDefined() - expect(user.email).not.toMatch('peter@example.com') - expect(user.email).toMatch(/^primary/) - } + expect(user.pk.S).toMatch(/^User#/) + expect(user.email.S).toBeDefined() + expect(user.email.S).not.toMatch('peter@example.com') + expect(user.email.S).toMatch(/^primary/) }) test('Destroy Table', async () => { diff --git a/test/custom-generate.ts b/test/custom-generate.ts index a080b8da..0a72ed62 100644 --- a/test/custom-generate.ts +++ b/test/custom-generate.ts @@ -1,7 +1,7 @@ /* crypto.ts - CRUD with crypto */ -import {AWS, Client, Match, Table, print, dump, delay, isV3, isV2} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {CustomGenerateSchema} from './schemas' const table = new Table({ @@ -41,12 +41,7 @@ test('Get', async () => { test('Get raw ', async () => { user = await User.get({id: user.id}, {hidden: true, parse: false}) - if (isV3()) { - expect(user.pk.S).toMatch(/^User#/) - } - if (isV2()) { - expect(user.pk).toMatch(/^User#/) - } + expect(user.pk.S).toMatch(/^User#/) }) test('Destroy Table', async () => { diff --git a/test/data.ts b/test/data.ts index 3ce4b7ca..82e7cf07 100644 --- a/test/data.ts +++ b/test/data.ts @@ -1,29 +1,14 @@ /* data.ts - Test various data types */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {DataTypesSchema} from './schemas' -// V2 -import DynamoDB from 'aws-sdk/clients/dynamodb' - // jest.setTimeout(7200 * 1000) -const PORT = parseInt(process?.env?.DYNAMODB_PORT || '4567') - -const v2Client = new DynamoDB.DocumentClient({ - endpoint: `http://localhost:${PORT}`, - region: 'local', - credentials: new AWS.Credentials({ - accessKeyId: 'test', - secretAccessKey: 'test', - }), -}) - const table = new Table({ name: 'DataTestTable', - client: v2Client, - // client: Client, + client: Client, partial: false, schema: DataTypesSchema, logger: true, diff --git a/test/debug.ts b/test/debug.ts index 69148cd7..7ecc63ef 100644 --- a/test/debug.ts +++ b/test/debug.ts @@ -5,7 +5,7 @@ Or run VS Code in the top level directory and just run. */ -import {AWS, Client, Entity, Match, Model, Table, print, dump, delay} from './utils/init' +import {Client, Entity, Match, Model, Table, print, dump, delay} from './utils/init' import {OneSchema} from '../src/index.js' jest.setTimeout(7200 * 1000) diff --git a/test/default.ts b/test/default.ts index 20d4d36b..89ef23a4 100644 --- a/test/default.ts +++ b/test/default.ts @@ -1,7 +1,7 @@ /* default.ts - Basic create, read, update delete */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' const table = new Table({ diff --git a/test/encode.ts b/test/encode.ts index 288332bc..e1fb3803 100644 --- a/test/encode.ts +++ b/test/encode.ts @@ -1,7 +1,7 @@ /* basic.ts - Basic create / get */ -import {AWS, Client, Table, print, dump} from './utils/init' +import {Client, Table, print, dump} from './utils/init' jest.setTimeout(7200 * 1000) diff --git a/test/fallback.ts b/test/fallback.ts index fd423a30..c07a3506 100644 --- a/test/fallback.ts +++ b/test/fallback.ts @@ -1,7 +1,7 @@ /* fallback.ts - Enhanced get/remove via fallback */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {TenantSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/high-level-table-api.ts b/test/high-level-table-api.ts index 7a32aba9..8ffdcc40 100644 --- a/test/high-level-table-api.ts +++ b/test/high-level-table-api.ts @@ -1,7 +1,7 @@ /* table-high-level.ts - Test CRUD on table high level API */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' const table = new Table({ diff --git a/test/hooks.ts b/test/hooks.ts index fd3de450..dda7ed81 100644 --- a/test/hooks.ts +++ b/test/hooks.ts @@ -1,7 +1,7 @@ /* hooks.ts - Test table and model callback hooks */ -import {AWS, Client, Entity, Match, Model, Table, print, dump, delay} from './utils/init' +import {Client, Entity, Match, Model, Table, print, dump, delay} from './utils/init' // jest.setTimeout(7200 * 1000) diff --git a/test/inline-model-typescript.ts b/test/inline-model-typescript.ts index 9b96a1a6..59e44947 100644 --- a/test/inline-model-typescript.ts +++ b/test/inline-model-typescript.ts @@ -7,7 +7,7 @@ Table constructor. A centralized, declarative schema stored in-table is the preferred pattern so that that table can be self-describing for tooling. */ -import {AWS, Client, Entity, Model, Table, dump, print} from './utils/init' +import {Client, Entity, Model, Table, dump, print} from './utils/init' // send any schema because it gets modified const table = new Table({ diff --git a/test/legacy.ts b/test/legacy.ts index 1c192281..9fc72f98 100644 --- a/test/legacy.ts +++ b/test/legacy.ts @@ -1,7 +1,7 @@ /* legacy-data.ts - Access non-onetable data in legacy tables */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' // jest.setTimeout(7200 * 1000) diff --git a/test/list.ts b/test/list.ts index aaa08d31..1580b24a 100644 --- a/test/list.ts +++ b/test/list.ts @@ -1,7 +1,7 @@ /* list.ts - List manipulation */ -import {AWS, Client, Entity, Match, Model, Table, print, dump, delay} from './utils/init' +import {Client, Entity, Match, Model, Table, print, dump, delay} from './utils/init' // jest.setTimeout(7200 * 1000) diff --git a/test/loader.ts b/test/loader.ts index 7a491d53..ef27487d 100644 --- a/test/loader.ts +++ b/test/loader.ts @@ -5,7 +5,7 @@ // @ts-ignore import DataLoader from 'dataloader' import {DefaultSchema} from './schemas' -import {Client, dynamoExecutedCommandsTracer, isV2, isV3, Table} from './utils/init' +import {Client, dynamoExecutedCommandsTracer, Table} from './utils/init' const table = new Table({ name: 'LoaderTest', @@ -24,16 +24,11 @@ let data = [ ] const assertBatchGetWasUsed = () => { - if (isV3()) { - expect(dynamoExecutedCommandsTracer).toHaveBeenCalledWith( - expect.objectContaining({ - commandName: expect.stringMatching('BatchGetItemCommand'), - }) - ) - } - if (isV2()) { - expect(dynamoExecutedCommandsTracer).toHaveBeenCalledWith(expect.stringMatching('batchGetItem')) - } + expect(dynamoExecutedCommandsTracer).toHaveBeenCalledWith( + expect.objectContaining({ + commandName: expect.stringMatching('BatchGetItemCommand'), + }) + ) } describe('Loader', () => { diff --git a/test/local.ts b/test/local.ts index 5509b565..53b3938c 100644 --- a/test/local.ts +++ b/test/local.ts @@ -1,7 +1,7 @@ /* Local.ts - Test LSIs */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {LocalSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/low-level-table-api.ts b/test/low-level-table-api.ts index 696827f4..3769f707 100644 --- a/test/low-level-table-api.ts +++ b/test/low-level-table-api.ts @@ -1,7 +1,7 @@ /* low-level-table-api.ts - */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' const table = new Table({ diff --git a/test/mapping-and-packing.ts b/test/mapping-and-packing.ts index b5d602f5..2761dd62 100644 --- a/test/mapping-and-packing.ts +++ b/test/mapping-and-packing.ts @@ -4,7 +4,7 @@ This tests simple mapping of properties to an abbreviated attribute and packing properties into a single attribute */ -import {AWS, Client, Match, Table, print, dump, delay, isV3, isV2} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {MappedSchema} from './schemas' // jest.setTimeout(7200 * 1000) @@ -72,22 +72,12 @@ test('Get including hidden', async () => { test('Get without parse', async () => { // Returns attributes without parsing including hidden (pk, sk) let u = await User.get({id: user.id}, {hidden: true, parse: false}) - if (isV3()) { - expect(u.id.S).toMatch(Match.ulid) - expect(u.em.S).toEqual('peter@example.com') - expect(u.pk.S).toEqual(`us#${u.id.S}`) - expect(u.sk.S).toEqual(`us#`) - expect(u.pk1.S).toEqual(`ty#us`) - expect(u.sk1.S).toEqual(`us#${user.email}`) - } - if (isV2()) { - expect(u.id).toMatch(Match.ulid) - expect(u.em).toEqual('peter@example.com') - expect(u.pk).toEqual(`us#${u.id}`) - expect(u.sk).toEqual(`us#`) - expect(u.pk1).toEqual(`ty#us`) - expect(u.sk1).toEqual(`us#${user.email}`) - } + expect(u.id.S).toMatch(Match.ulid) + expect(u.em.S).toEqual('peter@example.com') + expect(u.pk.S).toEqual(`us#${u.id.S}`) + expect(u.sk.S).toEqual(`us#`) + expect(u.pk1.S).toEqual(`ty#us`) + expect(u.sk1.S).toEqual(`us#${user.email}`) }) test('Get via GSI', async () => { diff --git a/test/marshall.ts b/test/marshall.ts index 0503073b..759074c2 100644 --- a/test/marshall.ts +++ b/test/marshall.ts @@ -4,7 +4,7 @@ // jest.setTimeout(7200 * 1000) -import {AWS, Client, Table, print, dump, delay, Model, isV2} from './utils/init' +import {Client, Table, print, dump, delay, Model} from './utils/init' const table = new Table({ name: 'MarshallTestTable', @@ -48,14 +48,6 @@ const jsonV3 = { }, } as const -const jsonV2 = { - name: 'alice', - registered: '2022-01-01Z', - profile: { - dob: '2000-01-01Z', - }, -} as const - const unmarshallModel = (model: Model, item: any): T => { const json = (table as any).unmarshall(item, {}) const obj = (model as any).transformReadItem('get', json, {}, {}) @@ -63,7 +55,7 @@ const unmarshallModel = (model: Model, item: any): T => { } test('Unmarshall model', async () => { - let json = isV2() ? jsonV2 : jsonV3 + let json = jsonV3 const obj = unmarshallModel(User, json) expect(obj).toEqual( expect.objectContaining({ @@ -74,7 +66,7 @@ test('Unmarshall model', async () => { }) test('Unmarshall nested model', async () => { - let json = isV2() ? jsonV2 : jsonV3 + let json = jsonV3 const obj = unmarshallModel(User, json) expect(obj).toEqual( expect.objectContaining({ diff --git a/test/misc.ts b/test/misc.ts index 0626ede5..2aa5807e 100644 --- a/test/misc.ts +++ b/test/misc.ts @@ -1,7 +1,7 @@ /* misc.ts - Miscellaneous tests */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' import Dynamo from '../src/Dynamo.js' diff --git a/test/mock.ts b/test/mock.ts index 99e970e6..716ba2c5 100644 --- a/test/mock.ts +++ b/test/mock.ts @@ -1,7 +1,7 @@ /* mock.ts - Used to mock scenarios */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/nested.ts b/test/nested.ts index 191dafae..0ab95eb7 100644 --- a/test/nested.ts +++ b/test/nested.ts @@ -1,7 +1,7 @@ /* nested.ts - Test nested schema */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {NestedSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/packed-attribute-with-follow.ts b/test/packed-attribute-with-follow.ts index 39c55441..fdcd2bf1 100644 --- a/test/packed-attribute-with-follow.ts +++ b/test/packed-attribute-with-follow.ts @@ -1,7 +1,7 @@ /* packed-attribute-with-follow.ts -- test GSI */ -import {AWS, Client, Table, print, dump, delay} from './utils/init' +import {Client, Table, print, dump, delay} from './utils/init' import {FullSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/pagination.ts b/test/pagination.ts index 9168d12f..61289e13 100644 --- a/test/pagination.ts +++ b/test/pagination.ts @@ -1,7 +1,7 @@ /* pagination.ts - Test find with pagination */ -import {AWS, Client, Entity, Match, Table, print, dump, delay} from './utils/init' +import {Client, Entity, Match, Table, print, dump, delay} from './utils/init' import {PagedSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/parallel-scan.ts b/test/parallel-scan.ts index f9753f18..495d7c45 100644 --- a/test/parallel-scan.ts +++ b/test/parallel-scan.ts @@ -2,7 +2,7 @@ Stub for creating a new test file */ -import {AWS, Client, Table, print, dump, delay} from './utils/init' +import {Client, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' const MaxUsers = 100 diff --git a/test/params.ts b/test/params.ts index b1a2dcc3..6eca3a5a 100644 --- a/test/params.ts +++ b/test/params.ts @@ -3,7 +3,7 @@ Initially just doing add/delete/remove/set */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {NestedSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/partial-nested.ts b/test/partial-nested.ts index e69238a2..cd777702 100644 --- a/test/partial-nested.ts +++ b/test/partial-nested.ts @@ -1,7 +1,7 @@ /* partial-nested.ts - Basic create / get */ -import {AWS, Client, Entity, Match, Model, Table, print, dump, delay} from './utils/init' +import {Client, Entity, Match, Model, Table, print, dump, delay} from './utils/init' import {OneSchema} from '../src/index.js' // jest.setTimeout(7200 * 1000) diff --git a/test/regress/low-level-query-with-gsi.ts b/test/regress/low-level-query-with-gsi.ts index f285aed3..06c2fef6 100644 --- a/test/regress/low-level-query-with-gsi.ts +++ b/test/regress/low-level-query-with-gsi.ts @@ -1,7 +1,7 @@ /* low-level-query-with-gsi.ts - Regression scenario */ -import {AWS, Client, Match, Table, print, dump, delay} from '../utils/init' +import {Client, Match, Table, print, dump, delay} from '../utils/init' // jest.setTimeout(7200 * 1000) diff --git a/test/regress/pagination-without-sort-key.ts b/test/regress/pagination-without-sort-key.ts index 1dfa5bc3..ee3ef97b 100644 --- a/test/regress/pagination-without-sort-key.ts +++ b/test/regress/pagination-without-sort-key.ts @@ -1,7 +1,7 @@ /* pagination-without-sort-key.ts - Test pagination without a primary sort key */ -import {AWS, Client, Entity, Match, Table, print, dump, delay} from '../utils/init' +import {Client, Entity, Match, Table, print, dump, delay} from '../utils/init' // jest.setTimeout(7200 * 1000) diff --git a/test/regress/update-gsi-keys.ts b/test/regress/update-gsi-keys.ts index 22f789f5..ddae723a 100644 --- a/test/regress/update-gsi-keys.ts +++ b/test/regress/update-gsi-keys.ts @@ -1,7 +1,7 @@ /* update-gsi-keys.ts - Test updating GSI keys */ -import {AWS, Client, Entity, Model, Table, print, dump, delay} from '../utils/init' +import {Client, Entity, Model, Table, print, dump, delay} from '../utils/init' const schema = { format: 'onetable:1.1.0', diff --git a/test/scan.ts b/test/scan.ts index 49da11af..c16640ba 100644 --- a/test/scan.ts +++ b/test/scan.ts @@ -1,7 +1,7 @@ /* find-and-scan.ts - Basic find and scan options */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' const table = new Table({ diff --git a/test/single-key.ts b/test/single-key.ts index d65f5c14..01fd1af3 100644 --- a/test/single-key.ts +++ b/test/single-key.ts @@ -1,7 +1,7 @@ /* single-key.ts - Test table with a single primary key */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {SingleKeySchema} from './schemas' const table = new Table({ diff --git a/test/stats.ts b/test/stats.ts index 3044c1bf..d0a5cd5a 100644 --- a/test/stats.ts +++ b/test/stats.ts @@ -1,7 +1,7 @@ /* stats.ts - */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {TenantSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/stub.ts b/test/stub.ts index 21a3b82d..6e2dd55b 100644 --- a/test/stub.ts +++ b/test/stub.ts @@ -2,7 +2,7 @@ Stub for creating a new test file */ -import {AWS, Client, Table, print, dump, delay} from './utils/init' +import {Client, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' const table = new Table({ diff --git a/test/table-constructor.ts b/test/table-constructor.ts index fa6db9c9..24c440dd 100644 --- a/test/table-constructor.ts +++ b/test/table-constructor.ts @@ -1,7 +1,7 @@ /* table-constructor.ts - */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/transact.ts b/test/transact.ts index e2a1dc7d..6e39320e 100644 --- a/test/transact.ts +++ b/test/transact.ts @@ -2,7 +2,7 @@ Transactions */ -import {AWS, Client, Table, print, dump, delay} from './utils/init' +import {Client, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/typescript-count.ts b/test/typescript-count.ts index a526f7bb..cb12f6b3 100644 --- a/test/typescript-count.ts +++ b/test/typescript-count.ts @@ -1,7 +1,7 @@ /* typescript-count.ts - Test *count methods */ -import {AWS, Client, Entity, Match, Table, print, dump, delay} from './utils/init' +import {Client, Entity, Match, Table, print, dump, delay} from './utils/init' import {TenantSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/typescript-extras.ts b/test/typescript-extras.ts index d1e6dfb0..1d2b6a32 100644 --- a/test/typescript-extras.ts +++ b/test/typescript-extras.ts @@ -1,7 +1,7 @@ /* typescript-extras.ts - */ -import {AWS, Client, Entity, Match, Table, print, dump, delay} from './utils/init' +import {Client, Entity, Match, Table, print, dump, delay} from './utils/init' import {TenantSchema} from './schemas' // Test these are exported from index diff --git a/test/typescript-tenant.ts b/test/typescript-tenant.ts index a9ee5c94..39706fdd 100644 --- a/test/typescript-tenant.ts +++ b/test/typescript-tenant.ts @@ -1,7 +1,7 @@ /* typescript-tenant.ts - */ -import {AWS, Client, Entity, Match, Table, print, dump, delay} from './utils/init' +import {Client, Entity, Match, Table, print, dump, delay} from './utils/init' import {TenantSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/unique.ts b/test/unique.ts index 0949b31b..c4e30fcb 100644 --- a/test/unique.ts +++ b/test/unique.ts @@ -2,7 +2,7 @@ unique.ts - Test unique crud */ import {UniqueSchema} from './schemas' -import {Client, Entity, isV2, isV3, Model, Table} from './utils/init' +import {Client, Entity, Model, Table} from './utils/init' import {OneTableError} from '../src' // jest.setTimeout(7200 * 1000) diff --git a/test/update.ts b/test/update.ts index 91d0072c..918e604e 100644 --- a/test/update.ts +++ b/test/update.ts @@ -1,7 +1,7 @@ /* update.ts - Basic updates */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {DefaultSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/utils/init.ts b/test/utils/init.ts index 02f8f274..7895759d 100644 --- a/test/utils/init.ts +++ b/test/utils/init.ts @@ -1,31 +1,18 @@ import {DynamoDBClient} from '@aws-sdk/client-dynamodb' -import AWS, {DynamoDB} from 'aws-sdk' import {Entity, Model, Table} from '../../src/index.js' const PORT = parseInt(process.env.DYNAMODB_PORT || '4567') +const HOST = process.env.DYNAMODB_HOST || 'localhost' const dynamoExecutedCommandsTracer = jest.fn() -const ClientV2 = new DynamoDB.DocumentClient({ - endpoint: `http://localhost:${PORT}`, +const Client = new DynamoDBClient({ + endpoint: `http://${HOST}:${PORT}`, region: 'local', - sslEnabled: false, - credentials: new AWS.Credentials({ + credentials: { accessKeyId: 'test', secretAccessKey: 'test', - }), - logger: { - log: dynamoExecutedCommandsTracer, }, -}) - -const ClientV3 = new DynamoDBClient({ - endpoint: `http://localhost:${PORT}`, - region: 'local', - credentials: new AWS.Credentials({ - accessKeyId: 'test', - secretAccessKey: 'test', - }), logger: { debug: dynamoExecutedCommandsTracer, info: dynamoExecutedCommandsTracer, @@ -34,11 +21,6 @@ const ClientV3 = new DynamoDBClient({ }, }) -const isV2 = () => process.env.DDB_CLIENT_VERSION === 'v2' -const isV3 = () => !isV2() - -const Client = isV2() ? ClientV2 : ClientV3 - const dump = (...args) => { let s: string[] = [] for (let item of args) { @@ -82,4 +64,4 @@ const Match = { phone: /^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$/, } -export {AWS, Client, Entity, Match, Model, Table, delay, dump, print, dynamoExecutedCommandsTracer, isV2, isV3} +export {Client, Entity, Match, Model, Table, delay, dump, print, dynamoExecutedCommandsTracer} diff --git a/test/v2.ts b/test/v2.ts deleted file mode 100644 index 65155742..00000000 --- a/test/v2.ts +++ /dev/null @@ -1,271 +0,0 @@ -/* - v2.ts - AWS V2 SDK test - */ -import {AWS, Match, Table, print, dump, delay} from './utils/init' -import {DefaultSchema} from './schemas' -import DynamoDB from 'aws-sdk/clients/dynamodb' - -// jest.setTimeout(7200 * 1000) - -const PORT = parseInt(process.env.DYNAMODB_PORT || '') - -let data = [ - {name: 'Peter Smith', email: 'peter@example.com', status: 'active'}, - {name: "Patty O'Furniture", email: 'patty@example.com', status: 'active'}, - {name: 'Cu Later', email: 'cu@example.com', status: 'inactive'}, -] - -const client = new DynamoDB.DocumentClient({ - endpoint: `http://localhost:${PORT}`, - region: 'local', - credentials: new AWS.Credentials({ - accessKeyId: 'test', - secretAccessKey: 'test', - }), -}) - -const table = new Table({ - name: 'V2TestTable', - client: client, - partial: false, - schema: DefaultSchema, - logger: (level, message, context) => { - if (level == 'trace' || level == 'data') return - console.log(`${new Date().toLocaleString()}: ${level}: ${message}`) - console.log(JSON.stringify(context, null, 4) + '\n') - }, -}) - -let User -let user: any -let users: any[] - -test('Create Table', async () => { - if (!(await table.exists())) { - await table.createTable() - expect(await table.exists()).toBe(true) - } -}) - -test('Set Client', async () => { - table.setClient(client) -}) - -test('Get Schema', () => { - let schema: any = table.getCurrentSchema() - expect(schema.models).toBeDefined() - expect(schema.indexes).toBeDefined() - expect(schema.params).toBeDefined() - expect(schema.models.User).toBeDefined() - expect(schema.models.User.pk).toBeDefined() -}) - -test('List tables', async () => { - let tables = await table.listTables() - expect(tables.length).toBeGreaterThan(0) - expect(tables).toContain('V2TestTable') -}) - -test('Describe Table', async () => { - let info: any = await table.describeTable() - expect(info.Table).toBeDefined() - expect(info.Table.TableName).toBe('V2TestTable') -}) - -test('List Models', async () => { - let models = table.listModels() - expect(models.length).toBeGreaterThan(0) - expect(models).toContain('User') -}) - -test('Validate User model', () => { - User = table.getModel('User') - expect(User).toMatchObject({ - name: 'User', - hash: 'pk', - sort: 'sk', - }) -}) - -test('Create', async () => { - user = await User.create({name: 'Peter Smith', status: 'active'}) - expect(user).toMatchObject({ - name: 'Peter Smith', - status: 'active', - }) -}) - -test('Get', async () => { - user = await User.get({id: user.id}) - expect(user).toMatchObject({ - name: 'Peter Smith', - status: 'active', - }) - expect(user.id).toMatch(Match.ulid) -}) - -test('Get including hidden', async () => { - user = await User.get({id: user.id}, {hidden: true}) - expect(user).toMatchObject({ - name: 'Peter Smith', - status: 'active', - sk: 'User#', - gs1pk: 'User#Peter Smith', - gs1sk: 'User#', - }) - expect(user.id).toMatch(Match.ulid) - expect(user.pk).toMatch(/^User#/) -}) - -test('Get raw', async () => { - let data = await User.get({id: user.id}, {parse: false, hidden: true}) - // ISO dates 2021-06-30T01:27:19.986Z - expect(data.created).toMatch(/2.*Z/) - expect(data.updated).toMatch(/2.*Z/) -}) - -test('Find by ID', async () => { - users = await User.find({id: user.id}) - expect(users.length).toBe(1) - user = users[0] - expect(user).toMatchObject({ - name: 'Peter Smith', - status: 'active', - }) -}) - -test('Find by name on GSI', async () => { - users = await User.find({name: user.name}, {index: 'gs1'}) - expect(users.length).toBe(1) - user = users[0] - expect(user).toMatchObject({ - name: 'Peter Smith', - status: 'active', - }) -}) - -test('Update', async () => { - user = await User.update({id: user.id, status: 'inactive'}) - expect(user).toMatchObject({ - name: 'Peter Smith', - status: 'inactive', - }) - expect(user.id).toMatch(Match.ulid) -}) - -test('Remove attribute', async () => { - // Remove attribute by setting to null, but status has a default value of 'idle' - user = await User.update({id: user.id, status: null}) - expect(user.status).toBe('idle') -}) - -test('Remove attribute 2', async () => { - // Update and remove attributes using {remove} - user = await User.update({id: user.id, status: 'active'}, {remove: ['gs1pk', 'gs1sk'], hidden: true}) - expect(user).toMatchObject({ - name: 'Peter Smith', - status: 'active', - sk: 'User#', - }) - expect(user.gs1pk).toBeUndefined() - expect(user.gs1sk).toBeUndefined() - expect(user.id).toMatch(Match.ulid) -}) - -test('Remove item', async () => { - await User.remove({id: user.id}) - user = await User.get({id: user.id}) - expect(user).toBeUndefined() -}) - -test('Scan', async () => { - user = await User.create({name: 'Sky Blue', status: 'active'}) - users = await User.scan({}) - expect(users.length).toBe(1) - user = users[0] - expect(user).toMatchObject({ - name: 'Sky Blue', - status: 'active', - }) -}) - -test('Remove all users', async () => { - users = await User.scan({}) - expect(users.length).toBe(1) - - for (let user of users) { - await User.remove({id: user.id}) - } - users = await User.scan({}) - expect(users.length).toBe(0) -}) - -test('Batch put', async () => { - let batch = {} - for (let item of data) { - table.create('User', item, {batch}) - } - await table.batchWrite(batch) - users = await table.scan('User') - expect(users.length).toBe(data.length) -}) - -test('Batch get', async () => { - let batch = {} - for (let user of users) { - table.get('User', {id: user.id}, {batch}) - } - let items: any = await table.batchGet(batch, {parse: true, hidden: false}) - expect(items.length).toBe(data.length) - - for (let item of items) { - let datum = data.find((i) => i.name == item.name) - expect(datum).toBeDefined() - if (datum) { - expect(item).toMatchObject(datum) - } - } - // Cleanup - users = await User.scan({}) - for (let user of users) { - await User.remove({id: user.id}) - } -}) - -test('Transaction create', async () => { - let transaction = {} - try { - for (let item of data) { - await table.create('User', item, {transaction}) - } - await table.transact('write', transaction, {parse: true, hidden: false}) - } catch (err) { - // Never - expect(false).toBe(true) - } - - users = await table.scan('User') - expect(users.length).toBe(data.length) -}) - -test('Transaction get', async () => { - let transaction = {} - for (let user of users) { - await table.get('User', {id: user.id}, {transaction}) - } - let items: any = await table.transact('get', transaction, {parse: true, hidden: false}) - expect(items.length).toBe(data.length) - - for (let item of items) { - let datum = data.find((i) => i.name == item.name) - expect(datum).toBeDefined() - if (datum) { - expect(item).toMatchObject(datum) - } - } -}) - -test('Destroy Table', async () => { - await table.deleteTable('DeleteTableForever') - expect(await table.exists()).toBe(false) -}) diff --git a/test/validate.ts b/test/validate.ts index ee0eb7b7..b5b6c80d 100644 --- a/test/validate.ts +++ b/test/validate.ts @@ -1,7 +1,7 @@ /* validation.ts - Crud with validation */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' import {ValidationSchema} from './schemas' // jest.setTimeout(7200 * 1000) diff --git a/test/value-template.ts b/test/value-template.ts index ad69b4e6..55ae5fe5 100644 --- a/test/value-template.ts +++ b/test/value-template.ts @@ -1,7 +1,7 @@ /* value-function.ts - */ -import {AWS, Client, Match, Table, print, dump, delay} from './utils/init' +import {Client, Match, Table, print, dump, delay} from './utils/init' const table = new Table({ name: 'ValueFunctionTestTable',