{"id":16304761,"url":"https://github.com/moznion/ts-dynamodb-attributes-transformer","last_synced_at":"2025-10-29T11:13:57.208Z","repository":{"id":61562558,"uuid":"552184228","full_name":"moznion/ts-dynamodb-attributes-transformer","owner":"moznion","description":"Code transformer plugin powered by TypeScript Compiler API that transforms TypeScript object from/to Amazon DynamoDB attributes","archived":false,"fork":false,"pushed_at":"2025-10-24T04:00:54.000Z","size":202,"stargazers_count":4,"open_issues_count":12,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-24T06:04:13.100Z","etag":null,"topics":["compiler-api","dynamodb","typescript"],"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/moznion.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-10-16T02:25:10.000Z","updated_at":"2023-03-21T11:05:57.000Z","dependencies_parsed_at":"2023-12-26T23:21:05.113Z","dependency_job_id":"950c7f24-7b46-4111-a9e0-f011c0c6989a","html_url":"https://github.com/moznion/ts-dynamodb-attributes-transformer","commit_stats":{"total_commits":53,"total_committers":2,"mean_commits":26.5,"dds":"0.24528301886792447","last_synced_commit":"02793c0bfc503b6f2493405bf5ceadaedb602099"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/moznion/ts-dynamodb-attributes-transformer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moznion%2Fts-dynamodb-attributes-transformer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moznion%2Fts-dynamodb-attributes-transformer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moznion%2Fts-dynamodb-attributes-transformer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moznion%2Fts-dynamodb-attributes-transformer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moznion","download_url":"https://codeload.github.com/moznion/ts-dynamodb-attributes-transformer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moznion%2Fts-dynamodb-attributes-transformer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281608656,"owners_count":26530388,"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","status":"online","status_checked_at":"2025-10-29T02:00:06.901Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["compiler-api","dynamodb","typescript"],"created_at":"2024-10-10T21:04:44.402Z","updated_at":"2025-10-29T11:13:57.192Z","avatar_url":"https://github.com/moznion.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ts-dynamodb-attributes-transformer [![.github/workflows/check.yml](https://github.com/moznion/ts-dynamodb-attributes-transformer/actions/workflows/check.yml/badge.svg)](https://github.com/moznion/ts-dynamodb-attributes-transformer/actions/workflows/check.yml) [![npm version](https://badge.fury.io/js/@moznion%2Fts-dynamodb-attributes-transformer.svg)](https://badge.fury.io/js/@moznion%2Fts-dynamodb-attributes-transformer)\n\nCode transformer plugin powered by [TypeScript Compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API) that transforms TypeScript object from/to Amazon DynamoDB attributes.\n\n## Description\n\nThis plugin replaces the TypeScript function invocation with the generated object code. In short, this plugin generates the code for every property of type `T`.\n\n\n### `dynamodbRecord\u003cT\u003e(obj: T, shouldLenientTypeCheck?: boolean): Record\u003ckeyof T, AttributeValue\u003e`\n\nThis plugin replaces `dynamodbRecord\u003cT\u003e(obj: T)` invocation with `Record\u003ckeyof T, AttributeValue\u003e` value that is defined in aws-sdk-js-v3 according to the type `T` and the contents of the object.\n\nThis plugin powers the users can do drop-in replacements for the existing `Record\u003ckeyof T, AttributeValue\u003e` value and/or the generator with `dynamodbRecord\u003cT\u003e(obj: T)` function.\n\n### `fromDynamodbRecord\u003cT\u003e(attrs: Record\u003cstring, AttributeValue\u003e, shouldLenientTypeCheck?: boolean): T`\n\nThis replaces `fromDynamodbRecord\u003cT\u003e(attrs: Record\u003cstring, AttributeValue\u003e)` invocation with the object which has type `T`. This method is responsible to translate the DynamoDB attributes to the actual TypeScript object, i.e. unmarshalling.\n\n## Motivations\n\n- To do automatic generation of the [DynamoDB attribute data type](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html) code that is recognizable by [aws-sdk-js-v3](https://github.com/aws/aws-sdk-js-v3), with type safety.\n  - Manual making the translation layer between the object and DynamoDB's Record is no longer needed!\n- Performance. This uses TypeScript Compiler API, so it generates/determine the DynamoDB attribute code at the compiling timing. This means the logic doesn't have to do a reflection on the fly so this contributes to a good performance.\n\n### Benchmark\n\nThe benchmark result between this project and [kayomarz/dynamodb-data-types](https://github.com/kayomarz/dynamodb-data-types) is the following:\n\nmarshalling:\n\n```\nnode version: v16.17.0\ndynamodb-data-types marshalling x 3,845,247 ops/sec ±0.63% (90 runs sampled)\nts-dynamodb-attributes-transformer marshalling x 13,614,974 ops/sec ±0.24% (100 runs sampled)\nFastest is ts-dynamodb-attributes-transformer marshalling\n```\n\nunmarshalling:\n\n```\nnode version: v16.17.0\ndynamodb-data-types unmarshalling x 1,800,718 ops/sec ±0.30% (96 runs sampled)\nts-dynamodb-attributes-transformer unmarshalling x 3,493,272 ops/sec ±0.50% (98 runs sampled)\nFastest is ts-dynamodb-attributes-transformer unmarshalling\n```\n\nPlease see also [benchmark](./examples/benchmark) project.\n\n## Synopsis\n\n### Marshalling into DynamoDB record from the Typescript Object\n\n```ts\nimport { AttributeValue } from '@aws-sdk/client-dynamodb';\nimport { dynamodbRecord } from '@moznion/ts-dynamodb-attributes-transformer';\n\ninterface User {\n  readonly id: number;\n  readonly name: string;\n  readonly tags: Map\u003cstring, string\u003e;\n}\n\nconst record: Record\u003ckeyof User, AttributeValue\u003e = dynamodbRecord\u003cUser\u003e({\n  id: 12345,\n  name: 'John Doe',\n  tags: new Map\u003cstring, string\u003e([\n    ['foo', 'bar'],\n    ['buz', 'qux'],\n  ]),\n});\n\n/*\n * Then you can use this record value on the aws-sdk-js-v3's DynamoDB client; for example,\n *\n *   const dyn = new DynamoDBClient(...);\n *   await dyn.send(new PutItemCommand({\n *     TableName: \"...\",\n *     Item: record, // \u003c= HERE!\n *   }));\n */\n```\n\nThen this plugin transforms the above TypeScript code like the following JavaScript code:\n\n```js\nconst record = (function (arg) {\n  return {\n    id: {\n      N: arg.id.toString()\n    },\n    name: {\n      S: arg.name\n    },\n    tags: {\n      M: (function () {\n        var m;\n        m = {}\n        for (const kv of arg.tags) {\n          m[kv[0]] = { S: kv[1] }\n        }\n        return m;\n      })()\n    }\n  };\n})({\n  id: 12345,\n  name: 'John Doe',\n  tags: new Map([\n    ['foo', 'bar'],\n    ['buz', 'qux'],\n  ]),\n});\n/*\n * This record is equal to the following object:\n *\n *   {\n *     id: { N: \"12345\" },\n *     name: { S: \"John Doe\" },\n *     tags: {\n *       M: {\n *         foo: { S: \"bar\" },\n *         buz: { S: \"qux\" }\n *       }\n *     }\n *   }\n */\n```\n\n### Unmarshalling into TypeScript object from DynamoDB record\n\n```ts\nimport { fromDynamodbRecord } from '@moznion/ts-dynamodb-attributes-transformer';\n\ninterface User {\n  readonly id?: number;\n  readonly name?: string;\n  readonly tags: Map\u003cstring, string\u003e;\n}\n\nconst user: User = fromDynamodbRecord\u003cUser\u003e({\n  id: {\n    N: '12345',\n  },\n  name: {\n    S: 'John Doe',\n  },\n  tags: {\n    M: {\n      foo: {\n        S: 'bar',\n      },\n      buz: {\n        S: 'qux',\n      },\n    },\n  },\n});\n```\n\nThen this plugin transforms the above TypeScript code like the following JavaScript code:\n\n```js\nconst user = (function (arg) {\n  return {\n    id: (function () {\n      const numStr = arg.id.N;\n      return numStr === undefined ? undefined : Number(numStr);\n    })(),\n    name: arg.name.S,\n    tags: (function () {\n      var m, r;\n      m = new Map();\n      r = arg['tags']?.M;\n      for (const k in r) {\n        m.set(k, r[k]?.S);\n      }\n      return m;\n    })(),\n  };\n})({\n  id: {\n    N: '12345',\n  },\n  name: {\n    S: 'John Doe',\n  },\n  tags: {\n    M: {\n      foo: {\n        S: 'bar',\n      },\n      buz: {\n        S: 'qux',\n      },\n    },\n  },\n});\n\n/*\n * This object is equal to the following:\n *\n *   {\n *     id: 12345,\n *     name: \"John Doe\",\n *     tags: {\n *       foo: { S: \"bar\" },\n *       buz: { S: \"qux\" },\n *     }\n *   }\n */\n```\n\n## How to use this transformer\n\nThis plugin exports the functions that have the signature `function dynamodbRecord\u003cT extends object\u003e(item: T, shouldLenientTypeCheck?: boolean): Record\u003ckeyof T, AttributeValue\u003e` and `function fromDynamodbRecord\u003cT extends object\u003e(attrs: Record\u003cstring, AttributeValue\u003e, shouldLenientTypeCheck?: boolean): T`.\n\nThese functions are the markers to indicate to the transformer to replace the function invocation with the generated code. Therefore, there are some restrictions:\n\n- Type parameter `T` is mandatory parameter (i.e. this mustn't be omitted). A transformer analyzes the type of the given `T` to collect the property information.\n- Type `T` must be class or interface. If it needs to do unmarshalling, this type `T` must be a derived type of the **interface**.\n\n### Examples\n\n#### ttypescript\n\n[ttypescript](https://github.com/cevek/ttypescript) is a custom TypeScript compiler that triggers the specified transformers in the tsconfig.json.\n\nPlease refer to the [examples/ttypescript](./examples/ttypescript) project directory and [ttypescript official README](https://github.com/cevek/ttypescript) for more details.\n\nAnyway, the important thing is specifying `compilerOptions.plugins` in tsconfig.json like the following:\n\n```json\n{\n  \"compilerOptions\": {\n    // ...\n    \"plugins\": [\n      { \"transform\": \"@moznion/ts-dynamodb-attributes-transformer/transformer\" }\n    ]\n  },\n  // ...\n}\n```\n\n#### ts-jest\n\nIf you use [ts-jest](https://github.com/kulshekhar/ts-jest) with this transformer, one of the easiest ways is using that with ttypescript toghether.\n\nIt needs ttypescript configuration and additionally the jest configuration in `jest.config.js` like the below:\n\n```js\nmodule.exports = {\n  // ...\n  transform: {\n    '^.+\\\\.tsx?$': [\n      'ts-jest',\n      {\n        compiler: 'ttypescript',\n      },\n    ],\n  },\n  // ...\n};\n\n```\n\n## TypeScript types to DynamoDB types\n\nPlease see also [Supported data types and naming rules in Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html) for more details about the DynamoDB types.\n\n### Scalar Types\n\n| TypeScript     | DynamoDB   |\n|----------------|------------|\n| number, BigInt | N          |\n| string         | S          |\n| Uint8Array     | B          |\n| boolean        | BOOL       |\n| unknown        | NULL       |\n\nNOTE: if the TypeScript property has `unknown` type and the value is `null` then DynamoDB attribute becomes `{ NULL: true }`. Else, that attribute value is `{ NULL: false }`.\n\n### Document Types\n\n| TypeScript                                                     | DynamoDB |\n|----------------------------------------------------------------|----------|\n| `Set\u003cstring\u003e`                                                  | SS       |\n| `Set\u003cnumber\u003e`, `Set\u003cBigInt\u003e`                                   | NS       |\n| `Set\u003cUint8Array\u003e`                                              | BS       |\n| `List\u003c$SCALAR_TYPE\u003e`                                           | L        |\n| `Map\u003cstring, $SCALAR_TYPE\u003e`, `{ [key: string]: $SCALAR_TYPE }` | M        |\n\n## Options\n\n### Lenient type checking (default: `false`)\n\nBy default, if this plugin encounters unsupported types, it raises the error and halts the transformation.\n\nBut if `true` value is given through the second argument of the function, it proceeds the transformation with ignoring the unsupported typed property even if it gets the unsupported types.\n\n## Note\n\nThis transformer plugin referred to the various things from [kimamula/ts-transformer-keys](https://github.com/kimamula/ts-transformer-keys)\n\n## Authors\n\nmoznion (\u003cmoznion@mail.moznion.net\u003e)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoznion%2Fts-dynamodb-attributes-transformer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoznion%2Fts-dynamodb-attributes-transformer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoznion%2Fts-dynamodb-attributes-transformer/lists"}