{"id":20020603,"url":"https://github.com/sleavely/dynamo-plus","last_synced_at":"2025-05-05T01:30:41.566Z","repository":{"id":34984034,"uuid":"189011688","full_name":"Sleavely/dynamo-plus","owner":"Sleavely","description":"🏋 Supercharged 📡 DynamoDB DocumentClient.","archived":false,"fork":false,"pushed_at":"2025-01-22T06:19:34.000Z","size":730,"stargazers_count":11,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-08T14:41:21.110Z","etag":null,"topics":["aws","aws-sdk","dynamodb","nodejs"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sleavely.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-05-28T11:04:09.000Z","updated_at":"2024-09-25T08:21:02.000Z","dependencies_parsed_at":"2024-03-09T00:27:31.289Z","dependency_job_id":"ae1aaf49-f5d8-4528-a3a9-4dd87935ebd3","html_url":"https://github.com/Sleavely/dynamo-plus","commit_stats":{"total_commits":127,"total_committers":4,"mean_commits":31.75,"dds":0.5275590551181102,"last_synced_commit":"d1658393cb76bd7aabd3343f889ba944d154cd53"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleavely%2Fdynamo-plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleavely%2Fdynamo-plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleavely%2Fdynamo-plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleavely%2Fdynamo-plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sleavely","download_url":"https://codeload.github.com/Sleavely/dynamo-plus/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252422921,"owners_count":21745515,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","aws-sdk","dynamodb","nodejs"],"created_at":"2024-11-13T08:33:12.646Z","updated_at":"2025-05-05T01:30:41.123Z","avatar_url":"https://github.com/Sleavely.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ![Dynamo Plus](logo.svg)\n\n[ ![npm version](https://img.shields.io/npm/v/dynamo-plus.svg?style=flat) ](https://npmjs.org/package/dynamo-plus \"View this project on npm\") [![Types, Tests and Linting](https://github.com/Sleavely/dynamo-plus/actions/workflows/test.yml/badge.svg)](https://github.com/Sleavely/dynamo-plus/actions/workflows/test.yml) [ ![Issues](https://img.shields.io/github/issues/Sleavely/dynamo-plus.svg) ](https://github.com/Sleavely/dynamo-plus/issues)\n\n\u003e Extend and supercharge your DynamoDB DocumentClient with infinite batching.\n\n# Installation\n\n```shell\nnpm i dynamo-plus\n```\n\n```js\nimport { DynamoPlus } from 'dynamo-plus'\nconst dynamo = new DynamoPlus({\n  region: 'eu-west-1',\n})\n\nconst regularDynamoParams = {\n  TableName: 'myTable',\n  Key: {\n    myKey: '1337'\n  }\n}\nconst data = await dynamo.get(regularDynamoParams)\n```\n\n# Features\n\n- Simplified stack traces that dont bury errors in AWS SDK internals\n- Optionally define the expected return type of items when using Typescript\n- `get()` returns the document or `undefined`\n- New methods for batching unlimited amounts of data\n  - [getAll(params)](#methods-getall)\n  - [deleteAll(params)](#methods-deleteall)\n  - [putAll(params)](#methods-putall)\n  - [queryAll(params)](#methods-queryall)\n  - [queryIterator(params[, pageSize])](#methods-queryiterator)\n  - [scanAll(params)](#methods-scanall)\n  - [scanIterator(params[, pageSize[, parallelScans]])](#methods-scaniterator)\n\n## Optional return types\n\nOn methods that return documents you can have them explicitly typed from the get-go:\n\n```typescript\ninterface User {\n  id: string\n  name: string\n  age: number\n}\nconst user = await dynamo.get\u003cUser\u003e({\n  TableName: 'users',\n  Key: { id: 'agent47' },\n})\n// user is now either User or undefined\n\nconst users = await dynamo.getAll\u003cUser\u003e({\n  TableName: 'users',\n  Keys: [\n    { id: 'eagle-1' },\n    { id: 'pelican-1' }\n  ],\n})\n// users is now Array\u003cUser\u003e\n\nconst moreUsers = await dynamo.scanAll\u003cUser\u003e({ TableName: 'users' })\n// Array\u003cUser\u003e\n```\n\n## New method for performing batchGet requests in chunks\n\nThe built-in _batchRead_ method can be used for fetching multiple documents by their primary keys, but it requires you to handle chunking and unprocessed items yourself. DynamoPlus adds a _getAll_ method that does the heavy lifting for you.\n\n\u003ca name=\"methods-getall\"\u003e\u003c/a\u003e\n### getAll(params)\n\nIt's like _batchGet_, but with the simple syntax of _get_.\n\n- **params** `Object`\n  - **TableName**\n  - **Keys** - An array of key objects equivalent to `Key` in _get()_.\n  - **BatchSize** - Optional custom batch size. Defaults to 100 which the maximum permitted value by DynamoDB.\n\n_getAll()_ returns\n\n```js\nconst params = {\n  TableName: 'users',\n  Keys: [{ userId: '1' }, { userId: '2' }, /* ... */ { userId: '999' }]\n}\n\nconst response = await dynamo.getAll(params)\n// response now contains ALL documents, not just the first 100\n```\n\n## New methods for performing batchWrite requests in chunks\n\nbatchWrite is neat for inserting multiple documents at once, but it requires you to handle chunking and unprocessed items yourself, while also using it's own somewhat unique syntax. We've added deleteAll() and putAll() to do the heavy lifting for you.\n\n\u003ca name=\"methods-deleteall\"\u003e\u003c/a\u003e\n### deleteAll(params)\n\n_batchWrite_ deletions, but with the simple syntax of _delete_.\n\n- **params** `Object`\n  - **TableName**\n  - **Keys** - An array of key objects equivalent to `Key` in _delete()_.\n  - **BatchSize** - Optional custom batch size. Defaults to 25 which the maximum permitted value by DynamoDB.\n\n_deleteAll()_ does not return any data once it resolves.\n\n```js\nconst params = {\n  TableName: 'Woop woop!',\n  Keys: [{ userId: '123' }, { userId: 'abc' }]\n}\nawait dynamo.deleteAll(params)\n```\n\n---\n\n\u003ca name=\"methods-putall\"\u003e\u003c/a\u003e\n### putAll(params)\n\n_batchWrite_ upserts, but with the simple syntax of _put_.\n\n- **params** `Object`\n  - **TableName**\n  - **Items** - An array of documents equivalent to `Item` in _put()_.\n  - **BatchSize** - Optional custom batch size. Defaults to 25 which the maximum permitted value by DynamoDB.\n\n_putAll()_ does not return any data once it resolves.\n\n```js\nconst params = {\n  TableName: 'Woop woop!',\n  Items: [{ a: 'b' }, { c: 'd' }]\n}\nawait dynamo.putAll(params)\n```\n\n---\n\n## New methods for query()\n\nQuery has new sibling methods that automatically paginate through resultsets for you.\n\n\u003ca name=\"methods-queryall\"\u003e\u003c/a\u003e\n### queryAll(params[, pageSize])\n\nResolves with the entire array of matching items.\n\n- **params** - [AWS.DynamoDB.DocumentClient.query() parameters](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#query-property)\n\n\n```js\nconst params = {\n  TableName : 'items',\n  IndexName: 'articleNo-index',\n  KeyConditionExpression: 'articleNo = :val',\n  ExpressionAttributeValues: { ':val': articleNo }\n}\nconst response = await dynamo.queryAll(params)\n// response now contains ALL items with the articleNo, not just the first 1MB\n```\n\n---\n\n\u003ca name=\"methods-queryiterator\"\u003e\u003c/a\u003e\n### queryIterator(params[, pageSize])\n\n- **params** - [AWS.DynamoDB.DocumentClient.query() parameters](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#query-property)\n\nLike [scanIterator](#methods-scaniterator), but for queries.\n\n---\n\n## New methods for scan()\n\nWe've supercharged _scan()_ for those times when you want to recurse through entire tables.\n\n\u003ca name=\"methods-scanall\"\u003e\u003c/a\u003e\n### scanAll(params[, pageSize])\n\nResolves with the entire array of matching items.\n\n- **params** - [AWS.DynamoDB.DocumentClient.scan() parameters](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#scan-property)\n\n```js\nconst params = {\n  TableName : 'MyTable',\n  FilterExpression : 'Year = :this_year',\n  ExpressionAttributeValues : {':this_year' : 2015}\n}\nconst response = await documentClient.scanAll(params)\n// response now contains ALL documents from 2015, not just the first 1MB\n```\n\n---\n\n\u003ca name=\"methods-scaniterator\"\u003e\u003c/a\u003e\n### scanIterator(params[, pageSize[, parallelScanSegments]])\n\nAn async generator-driven approach to recursing your tables. This is a powerful tool when you have datasets that are too large to keep in memory all at once.\n\nTo spread out the workload across your table partitions you can define a number of `parallelScanSegments`. DynamoPlus will launch concurrent scans and yield results on the fly.\n\n- **params** - [AWS.DynamoDB.DocumentClient.scan() parameters](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#scan-property)\n- **pageSize** - _integer_ (_Default: 100_) How many items to retrieve per API call. (DynamoPlus automatically fetches all the pages regardless)\n- **parallelScans** - _integer_ (_Default: 1_) Amount of segments to split the scan operation into. It also accepts an array of individual segment options such as LastEvaluatedKey, the length of the array then decides the amount of segments.\n\n```js\nconst usersIterator = dynamoPlus.scanIterator({ TableName: 'users' })\nfor await (const user of usersIterator) {\n  await sendNewsletter(user.email)\n}\n```\n\n---\n\n# FAQ\n\n### Can I interact with the DocumentClient directly?\n\nYes, its accessible via `.client`:\n\n```js\nimport { DescribeTableCommand } from '@aws-sdk/client-dynamodb'\nimport { DynamoPlus } from 'dynamo-plus'\nconst dynamo = new DynamoPlus()\n\nconst command = new DescribeTableCommand({ TableName: 'my-table' })\ndynamo.client.send(command)\n```\n\n### How do I upgrade from v1 to v2?\n\nDynamoPlus 2.0.0 introduces a significant rewrite. Changes include:\n\n* Rewritten from the ground up using modern tools and syntax, natively producing correct type definitions\n\n* `aws-sdk` v2 has been replaced with `@aws-sdk/*` v3 and are now explicit dependencies\n\n* `DynamoPlus` is now a class that you instantiate with `new`, similar to the AWS clients\n  ```ts\n  const dynamo = new DynamoPlus({ region: 'eu-west-1' })\n  ```\n\n* `queryStream` and `queryStreamSync` have been replaced with `queryIterator`\n  ```js\n  const params = {\n    TableName: 'users',\n    IndexName: 'orgs-index',\n    KeyConditionExpression: \"organisationId = :val\",\n    ExpressionAttributeValues: { \":val\": organisationId },\n  }\n  const queryResults = dynamo.queryIterator(params)\n  for await (const user of queryResults) {\n    console.log(user)\n  }\n  ```\n\n* `scanStream` and `scanStreamSync` have been replaced with `scanIterator`\n  ```js\n  const params = {\n    TableName: 'users',\n  }\n  const scanResults = dynamo.scanIterator(params)\n  for await (const user of scanResults) {\n    console.log(user)\n  }\n  ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleavely%2Fdynamo-plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsleavely%2Fdynamo-plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleavely%2Fdynamo-plus/lists"}