Repository: jeremydaly/dynamodb-toolbox
Pull request #600 (2023-10-06 21:10:47)

chore(deps): bump postcss from 8.4.14 to 8.4.31 in /docs
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.14 to 8.4.31.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/postcss/postcss/releases">postcss's releases</a>.</em></p>
<blockquote>
<h2>8.4.31</h2>
<ul>
<li>Fixed <code>\r</code> parsing to fix CVE-2023-44270.</li>
</ul>
<h2>8.4.30</h2>
<ul>
<li>Improved source map performance (by <a href="https://github.com/romainmenke"><code>@​romainmenke</code></a>).</li>
</ul>
<h2>8.4.29</h2>
<ul>
<li>Fixed <code>Node#source.offset</code> (by <a href="https://github.com/idoros"><code>@​idoros</code></a>).</li>
<li>Fixed docs (by <a href="https://github.com/coliff"><code>@​coliff</code></a>).</li>
</ul>
<h2>8.4.28</h2>
<ul>
<li>Fixed <code>Root.source.end</code> for better source map (by <a href="https://github.com/romainmenke"><code>@​romainmenke</code></a>).</li>
<li>Fixed <code>Result.root</code> types when <code>process()</code> has no parser.</li>
</ul>
<h2>8.4.27</h2>
<ul>
<li>Fixed <code>Container</code> clone methods types.</li>
</ul>
<h2>8.4.26</h2>
<ul>
<li>Fixed clone methods types.</li>
</ul>
<h2>8.4.25</h2>
<ul>
<li>Improve stringify performance (by <a href="https://github.com/romainmenke"><code>@​romainmenke</code></a>).</li>
<li>Fixed docs (by <a href="https://github.com/vikaskaliramna07"><code>@​vikaskaliramna07</code></a>).</li>
</ul>
<h2>8.4.24</h2>
<ul>
<li>Fixed <code>Plugin</code> types.</li>
</ul>
<h2>8.4.23</h2>
<ul>
<li>Fixed warnings in TypeDoc.</li>
</ul>
<h2>8.4.22</h2>
<ul>
<li>Fixed TypeScript support with <code>node16</code> (by <a href="https://github.com/remcohaszing"><code>@​remcohaszing</code></a>).</li>
</ul>
<h2>8.4.21</h2>
<ul>
<li>Fixed <code>Input#error</code> types (by <a href="https://github.com/hudochenkov"><code>@​hudochenkov</code></a>).</li>
</ul>
<h2>8.4.20</h2>
<ul>
<li>Fixed source map generation for childless at-rules like <code>@layer</code>.</li>
</ul>
<h2>8.4.19</h2>
<ul>
<li>Fixed whitespace preserving after AST transformations (by <a href="https://github.com/romainmenke"><code>@​romainmenke</code></a>).</li>
</ul>
<h2>8.4.18</h2>
<ul>
<li>Fixed an error on <code>absolute: true</code> with empty <code>sourceContent</code> (by <a href="https://github.com/KingSora"><code>@​KingSora</code></a>).</li>
</ul>
<h2>8.4.17</h2>
<ul>
<li>Fixed <code>Node.before()</code> unexpected behavior (by <a href="https://github.com/romainmenke"><code>@​romainmenke</code></a>).</li>
<li>Added TOC to docs (by <a href="https://github.com/muddv"><code>@​muddv</code></a>).</li>
</ul>
<h2>8.4.16</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/postcss/postcss/blob/main/CHANGELOG.md">postcss's changelog</a>.</em></p>
<blockquote>
<h2>8.4.31</h2>
<ul>
<li>Fixed <code>\r</code> parsing to fix CVE-2023-44270.</li>
</ul>
<h2>8.4.30</h2>
<ul>
<li>Improved source map performance (by Romain Menke).</li>
</ul>
<h2>8.4.29</h2>
<ul>
<li>Fixed <code>Node#source.offset</code> (by Ido Rosenthal).</li>
<li>Fixed docs (by Christian Oliff).</li>
</ul>
<h2>8.4.28</h2>
<ul>
<li>Fixed <code>Root.source.end</code> for better source map (by Romain Menke).</li>
<li>Fixed <code>Result.root</code> types when <code>process()</code> has no parser.</li>
</ul>
<h2>8.4.27</h2>
<ul>
<li>Fixed <code>Container</code> clone methods types.</li>
</ul>
<h2>8.4.26</h2>
<ul>
<li>Fixed clone methods types.</li>
</ul>
<h2>8.4.25</h2>
<ul>
<li>Improve stringify performance (by Romain Menke).</li>
<li>Fixed docs (by <a href="https://github.com/vikaskaliramna07"><code>@​vikaskaliramna07</code></a>).</li>
</ul>
<h2>8.4.24</h2>
<ul>
<li>Fixed <code>Plugin</code> types.</li>
</ul>
<h2>8.4.23</h2>
<ul>
<li>Fixed warnings in TypeDoc.</li>
</ul>
<h2>8.4.22</h2>
<ul>
<li>Fixed TypeScript support with <code>node16</code> (by Remco Haszing).</li>
</ul>
<h2>8.4.21</h2>
<ul>
<li>Fixed <code>Input#error</code> types (by Aleks Hudochenkov).</li>
</ul>
<h2>8.4.20</h2>
<ul>
<li>Fixed source map generation for childless at-rules like <code>@layer</code>.</li>
</ul>
<h2>8.4.19</h2>
<ul>
<li>Fixed whitespace preserving after AST transformations (by Romain Menke).</li>
</ul>
<h2>8.4.18</h2>
<ul>
<li>Fixed an error on <code>absolute: true</code> with empty <code>sourceContent</code> (by Rene Haas).</li>
</ul>
<h2>8.4.17</h2>
<ul>
<li>Fixed <code>Node.before()</code> unexpected behavior (by Romain Menke).</li>
<li>Added TOC to docs (by Mikhail Dedov).</li>
</ul>
<h2>8.4.16</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/postcss/postcss/commit/90208de8805dd762596c0028b8637ffbed23e371"><code>90208de</code></a> Release 8.4.31 version</li>
<li><a href="https://github.com/postcss/postcss/commit/58cc860b4c1707510c9cd1bc1fa30b423a9ad6c5"><code>58cc860</code></a> Fix carrier return parsing</li>
<li><a href="https://github.com/postcss/postcss/commit/4fff8e4cdc237619df1d73a444c0a8329701c1e2"><code>4fff8e4</code></a> Improve pnpm test output</li>
<li><a href="https://github.com/postcss/postcss/commit/cd43ed123274a92ebc13a1e8cccf1d65b8198f84"><code>cd43ed1</code></a> Update dependencies</li>
<li><a href="https://github.com/postcss/postcss/commit/caa916bdcbf66c51321574e2dde112ab13e8b306"><code>caa916b</code></a> Update dependencies</li>
<li><a href="https://github.com/postcss/postcss/commit/8972f76923e921a3c9655822382039b31b1c8e1a"><code>8972f76</code></a> Typo</li>
<li><a href="https://github.com/postcss/postcss/commit/11a5286f781d2a637f2c545c5e9cd661055acaab"><code>11a5286</code></a> Typo</li>
<li><a href="https://github.com/postcss/postcss/commit/45c55017776fc61f7815d1ea8e92d5291ca5d6c8"><code>45c5501</code></a> Release 8.4.30 version</li>
<li><a href="https://github.com/postcss/postcss/commit/bc3c341f589f9c15f1b56838a33d908374e537e0"><code>bc3c341</code></a> Update linter</li>
<li><a href="https://github.com/postcss/postcss/commit/b2be58a2eb788d12474ee1335f8ecdb9fa6225aa"><code>b2be58a</code></a> Merge pull request <a href="https://redirect.github.com/postcss/postcss/issues/1881">#1881</a> from romainmenke/improve-sourcemap-performance--phil...</li>
<li>Additional commits viewable in <a href="https://github.com/postcss/postcss/compare/8.4.14...8.4.31">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=postcss&package-manager=npm_and_yarn&previous-version=8.4.14&new-version=8.4.31)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/jeremydaly/dynamodb-toolbox/network/alerts).

</details>


Patch:
diff --git a/docs/package-lock.json b/docs/package-lock.json
index 95e6e763..a783ac4f 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -7823,9 +7823,15 @@
       }
     },
     "node_modules/nanoid": {
-      "version": "3.3.4",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
-      "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
       "bin": {
         "nanoid": "bin/nanoid.cjs"
       },
@@ -8390,9 +8396,9 @@
       }
     },
     "node_modules/postcss": {
-      "version": "8.4.14",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
-      "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
+      "version": "8.4.31",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
       "funding": [
         {
           "type": "opencollective",
@@ -8401,10 +8407,14 @@
         {
           "type": "tidelift",
           "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
         }
       ],
       "dependencies": {
-        "nanoid": "^3.3.4",
+        "nanoid": "^3.3.6",
         "picocolors": "^1.0.0",
         "source-map-js": "^1.0.2"
       },
@@ -18016,9 +18026,9 @@
       }
     },
     "nanoid": {
-      "version": "3.3.4",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
-      "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA=="
     },
     "negotiator": {
       "version": "0.6.3",
@@ -18418,11 +18428,11 @@
       }
     },
     "postcss": {
-      "version": "8.4.14",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
-      "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
+      "version": "8.4.31",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
       "requires": {
-        "nanoid": "^3.3.4",
+        "nanoid": "^3.3.6",
         "picocolors": "^1.0.0",
         "source-map-js": "^1.0.2"
       }
diff --git a/jest.config.js b/jest.config.cjs
similarity index 56%
rename from jest.config.js
rename to jest.config.cjs
index 60488ca9..dfb1558b 100644
--- a/jest.config.js
+++ b/jest.config.cjs
@@ -3,7 +3,16 @@ module.exports = {
   testMatch: ['**/?(*.)+(unit.test).+(ts|tsx|js)'],
   testPathIgnorePatterns: ['/__tests__/entities/*', '/__tests__/tables/*'],
   coveragePathIgnorePatterns: ['/__tests__/*'],
+  extensionsToTreatAsEsm: ['.ts'],
+  moduleNameMapper: {
+    '^(\\.{1,2}/.*)\\.js$': '$1',
+  },
   transform: {
-    '^.+\\.(ts|tsx)$': 'ts-jest'
-  }
+    '^.+\\.[tj]sx?$': [
+      'ts-jest',
+      {
+        useESM: true,
+      },
+    ],
+  },
 }
diff --git a/package.json b/package.json
index 7bce2e3a..a3dbddce 100644
--- a/package.json
+++ b/package.json
@@ -2,8 +2,21 @@
   "name": "dynamodb-toolbox",
   "description": "A simple set of tools for working with Amazon DynamoDB and the DocumentClient.",
   "author": "Jeremy Daly <jeremy@jeremydaly.com>",
-  "main": "dist/index.js",
-  "types": "dist/index.d.ts",
+  "main": "dist/cjs/index.js",
+  "types": "dist/cjs/index.d.ts",
+  "exports": {
+    ".": {
+      "import": {
+        "default": "./dist/esm/index.js",
+        "types": "./dist/esm/index.d.ts"
+      },
+      "require": {
+        "default": "./dist/cjs/index.js",
+        "types": "./dist/cjs/index.d.ts"
+      }
+    }
+  },
+  "type": "module",
   "scripts": {
     "test": "jest unit",
     "test-cov": "jest unit --coverage",
@@ -11,7 +24,10 @@
     "test-types": "tsd",
     "check-types": "tsc --noEmit",
     "lint": "eslint .",
-    "build": "rm -rf dist && tsc -p tsconfig.build.json",
+    "build:cjs": "tsc -p tsconfig.cjs.json && echo '{ \"type\": \"commonjs\" }' > dist/cjs/package.json",
+    "build:esm": "tsc -p tsconfig.esm.json && echo '{ \"type\": \"module\" }' > dist/esm/package.json",
+    "build": "npm run build:cjs & npm run build:esm",
+    "prebuild": "rm -rf dist",
     "prepublishOnly": "npm test && npm run lint && npm run test-types",
     "changelog": "git log $(git describe --tags --abbrev=0)..HEAD --oneline"
   },
@@ -62,9 +78,13 @@
     "typescript": "^4.1.3"
   },
   "files": [
-    "dist/index.*",
-    "dist/constants.*",
-    "dist/classes/",
-    "dist/lib/"
+    "dist/cjs/index.*",
+    "dist/cjs/constants.*",
+    "dist/cjs/classes/",
+    "dist/cjs/lib/",
+    "dist/esm/index.*",
+    "dist/esm/constants.*",
+    "dist/esm/classes/",
+    "dist/esm/lib/"
   ]
 }
diff --git a/src/classes/Entity/Entity.ts b/src/classes/Entity/Entity.ts
index a083a614..ef7c7d00 100644
--- a/src/classes/Entity/Entity.ts
+++ b/src/classes/Entity/Entity.ts
@@ -19,22 +19,23 @@ import type {
   ScanInput,
   TransactGetItem
 } from '@aws-sdk/client-dynamodb'
-import cloneDeep from 'deep-copy'
+import * as cloneDeep from 'deep-copy'
+
 import type { A, B, O } from 'ts-toolbelt'
 
-import parseEntity from '../../lib/parseEntity'
-import validateTypes from '../../lib/validateTypes'
-import normalizeData from '../../lib/normalizeData'
-import formatItem from '../../lib/formatItem'
-import getKey from '../../lib/getKey'
-import parseConditions from '../../lib/expressionBuilder'
-import parseProjections from '../../lib/projectionBuilder'
-import { error, transformAttr, isEmpty, If, FirstDefined, Compute } from '../../lib/utils'
+import parseEntity from '../../lib/parseEntity.js'
+import validateTypes from '../../lib/validateTypes.js'
+import normalizeData from '../../lib/normalizeData.js'
+import formatItem from '../../lib/formatItem.js'
+import getKey from '../../lib/getKey.js'
+import parseConditions from '../../lib/expressionBuilder.js'
+import parseProjections from '../../lib/projectionBuilder.js'
+import { error, transformAttr, isEmpty, If, FirstDefined, Compute } from '../../lib/utils.js'
 import {
   ATTRIBUTE_VALUES_LIST_DEFAULT_KEY,
   ATTRIBUTE_VALUES_LIST_DEFAULT_VALUE,
-} from '../../constants'
-import type { ScanOptions, TableDef } from '../Table'
+} from '../../constants.js'
+import type { ScanOptions, TableDef } from '../Table/types.js'
 import type {
   $GetOptions,
   $PutOptions,
@@ -61,7 +62,7 @@ import type {
   Writable,
   Readonly,
   $PutBatchOptions, AttributeMap,
-} from './types'
+} from './types.js'
 
 class Entity<Name extends string = string,
   // Name is used to detect Entity instances (new Entity(...)) vs Entity type (const e: Entity = ...)
@@ -149,7 +150,7 @@ class Entity<Name extends string = string,
     // we want to prevent mutation of the original entity configuration input but still be able
     // to mutate the original table instance
     entity = {
-      ...cloneDeep(entitySchemaWithoutTable),
+      ...cloneDeep.default(entitySchemaWithoutTable),
       ...(table ? { table } : {}),
     }
 
diff --git a/src/classes/Entity/deep-copy.d.ts b/src/classes/Entity/deep-copy.d.ts
new file mode 100644
index 00000000..17a3a310
--- /dev/null
+++ b/src/classes/Entity/deep-copy.d.ts
@@ -0,0 +1,4 @@
+declare module 'deep-copy' {
+    declare function dcopy<T>(arg: T): T
+    export default dcopy
+}
diff --git a/src/classes/Entity/index.ts b/src/classes/Entity/index.ts
index ea370d22..134001a2 100644
--- a/src/classes/Entity/index.ts
+++ b/src/classes/Entity/index.ts
@@ -1,3 +1,3 @@
-export { default as default } from './Entity'
-export * from './Entity'
-export * from './types'
+export { default as default } from './Entity.js'
+export * from './Entity.js'
+export * from './types.js'
diff --git a/src/classes/Entity/types.ts b/src/classes/Entity/types.ts
index 5caf9d56..feffcdba 100644
--- a/src/classes/Entity/types.ts
+++ b/src/classes/Entity/types.ts
@@ -2,9 +2,9 @@ import type { A, B, O, F } from 'ts-toolbelt'
 import { NativeAttributeValue } from '@aws-sdk/util-dynamodb'
 import { ReturnConsumedCapacity, ReturnItemCollectionMetrics } from '@aws-sdk/client-dynamodb'
 
-import type { Compute, FirstDefined, If } from '../../lib/utils'
-import type { DynamoDBKeyTypes, DynamoDBTypes, $QueryOptions, TableDef } from '../Table'
-import Entity from './Entity'
+import type { Compute, FirstDefined, If } from '../../lib/utils.js'
+import type { DynamoDBKeyTypes, DynamoDBTypes, $QueryOptions, TableDef } from '../Table/types.js'
+import Entity from './Entity.js'
 import { UpdateCommandInput } from '@aws-sdk/lib-dynamodb'
 
 export interface EntityConstructor<
diff --git a/src/classes/Table/Table.ts b/src/classes/Table/Table.ts
index 37218e66..3734f20e 100644
--- a/src/classes/Table/Table.ts
+++ b/src/classes/Table/Table.ts
@@ -1,15 +1,16 @@
 import type { A, O } from 'ts-toolbelt'
 
-import { parseTable, ParsedTable } from '../../lib/parseTable'
-import parseFilters from '../../lib/expressionBuilder'
-import validateTypes from '../../lib/validateTypes'
-import Entity, { AttributeMap } from '../Entity'
+import { parseTable, ParsedTable } from '../../lib/parseTable.js'
+import parseFilters from '../../lib/expressionBuilder.js'
+import validateTypes from '../../lib/validateTypes.js'
+import Entity from '../Entity/Entity.js'
+import { AttributeMap } from '../Entity/types.js'
 import {
   default as parseProjections,
   ProjectionAttributes,
   ProjectionAttributesTable,
-} from '../../lib/projectionBuilder'
-import type { ParsedEntity } from '../../lib/parseEntity'
+} from '../../lib/projectionBuilder.js'
+import type { ParsedEntity } from '../../lib/parseEntity.js'
 import type {
   BatchGetOptions,
   BatchGetParamsMeta,
@@ -23,9 +24,9 @@ import type {
   transactGetParamsOptions,
   TransactWriteOptions,
   transactWriteParamsOptions,
-} from './types'
+} from './types.js'
 
-import { error, conditionError, If, Compute } from '../../lib/utils'
+import { error, conditionError, If, Compute } from '../../lib/utils.js'
 import {
   BatchGetCommand,
   BatchGetCommandInput, BatchWriteCommand,
diff --git a/src/classes/Table/index.ts b/src/classes/Table/index.ts
index 788c753c..3170ea6a 100644
--- a/src/classes/Table/index.ts
+++ b/src/classes/Table/index.ts
@@ -1,3 +1,3 @@
-export { default as default } from './Table'
-export * from './Table'
-export * from './types'
+export { default as default } from './Table.js'
+export * from './Table.js'
+export * from './types.js'
diff --git a/src/classes/Table/types.ts b/src/classes/Table/types.ts
index 3a73b97a..bfbf60a3 100644
--- a/src/classes/Table/types.ts
+++ b/src/classes/Table/types.ts
@@ -2,10 +2,10 @@ import { ReturnConsumedCapacity, ReturnItemCollectionMetrics, Select } from '@aw
 import { DynamoDBDocumentClient, ScanCommandInput, TransactGetCommandInput } from '@aws-sdk/lib-dynamodb'
 import type { A, O } from 'ts-toolbelt'
 
-import type { ProjectionAttributes } from '../../lib/projectionBuilder'
-import type { FilterExpressions } from '../../lib/expressionBuilder'
-import type { $ReadOptions, ConditionsOrFilters } from '../Entity'
-import type Table from './Table'
+import type { ProjectionAttributes } from '../../lib/projectionBuilder.js'
+import type { FilterExpressions } from '../../lib/expressionBuilder.js'
+import type { $ReadOptions, ConditionsOrFilters } from '../Entity/types.js'
+import type Table from './Table.js'
 
 export interface TableConstructor<
   Name extends string,
diff --git a/src/index.ts b/src/index.ts
index 7373da0b..b81481f9 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,5 @@
-import Table from './classes/Table'
-import Entity from './classes/Entity'
+import Table from './classes/Table/Table.js'
+import Entity from './classes/Entity/Entity.js'
 import type {
   GetOptions,
   QueryOptions,
@@ -8,7 +8,7 @@ import type {
   UpdateOptions,
   EntityItem,
   InferEntityItem
-} from './classes/Entity'
+} from './classes/Entity/types.js'
 
 export {
   Table,
diff --git a/src/lib/checkAttribute.ts b/src/lib/checkAttribute.ts
index 874d194d..105fd70d 100644
--- a/src/lib/checkAttribute.ts
+++ b/src/lib/checkAttribute.ts
@@ -4,7 +4,7 @@
  * @license MIT
  */
 
-import { error } from './utils'
+import { error } from './utils.js'
 
 // Check attribute against attribute set
 export default (attr: string, attrs: any): string => {
diff --git a/src/lib/expressionBuilder.ts b/src/lib/expressionBuilder.ts
index c0e3fdaf..9613ed9d 100644
--- a/src/lib/expressionBuilder.ts
+++ b/src/lib/expressionBuilder.ts
@@ -9,9 +9,9 @@
 
 import { A } from 'ts-toolbelt'
 
-import checkAttribute from './checkAttribute'
-import { error, toDynamoBigInt } from './utils'
-import { TableDef } from '../classes/Table'
+import checkAttribute from './checkAttribute.js'
+import { error, toDynamoBigInt } from './utils.js'
+import { TableDef } from '../classes/Table/types.js'
 
 interface AttrRef {
   attr: string
diff --git a/src/lib/formatItem.ts b/src/lib/formatItem.ts
index c557be56..ae77678e 100644
--- a/src/lib/formatItem.ts
+++ b/src/lib/formatItem.ts
@@ -5,9 +5,9 @@
  */
 
 import type { NativeAttributeValue, NativeScalarAttributeValue, NumberValue } from '@aws-sdk/util-dynamodb'
-import type { PureAttributeDefinition } from '../classes/Entity'
-import validateTypes from './validateTypes'
-import type { Linked } from './parseEntity'
+import type { PureAttributeDefinition } from '../classes/Entity/types.js'
+import validateTypes from './validateTypes.js'
+import type { Linked } from './parseEntity.js'
 
 // Convert from DocumentClient values, which may be wrapped sets or numbers,
 // into normal TS values.
diff --git a/src/lib/getKey.ts b/src/lib/getKey.ts
index bbe44f41..c505baaa 100644
--- a/src/lib/getKey.ts
+++ b/src/lib/getKey.ts
@@ -4,8 +4,8 @@
  * @license MIT
  */
 
-import validateTypes from './validateTypes'
-import { error, transformAttr } from './utils'
+import validateTypes from './validateTypes.js'
+import { error, transformAttr } from './utils.js'
 
 // Get partitionKey/sortKey
 export default () => (
diff --git a/src/lib/normalizeData.ts b/src/lib/normalizeData.ts
index 23f977f2..243881e7 100644
--- a/src/lib/normalizeData.ts
+++ b/src/lib/normalizeData.ts
@@ -7,8 +7,8 @@
 
 import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb'
 
-import validateTypes from './validateTypes'
-import { error, transformAttr } from './utils'
+import validateTypes from './validateTypes.js'
+import { error, transformAttr } from './utils.js'
 
 // Normalize Data
 export default () => (
diff --git a/src/lib/parseCompositeKey.ts b/src/lib/parseCompositeKey.ts
index 95dda93b..2ec4de61 100644
--- a/src/lib/parseCompositeKey.ts
+++ b/src/lib/parseCompositeKey.ts
@@ -5,14 +5,14 @@
  */
 import { A, O } from 'ts-toolbelt'
 
-import { error } from './utils'
-import parseMapping from './parseMapping'
+import { error } from './utils.js'
+import parseMapping from './parseMapping.js'
 import {
   CompositeAttributeDefinition,
   PureAttributeDefinition,
   AttributeDefinitions
-} from '../classes/Entity'
-import { TrackingInfo } from './parseEntity'
+} from '../classes/Entity/types.js'
+import { TrackingInfo } from './parseEntity.js'
 
 const parseCompositeKey = <
   ReadonlyAttributeDefinitions extends
diff --git a/src/lib/parseEntity.ts b/src/lib/parseEntity.ts
index b6c2160c..72fc050c 100644
--- a/src/lib/parseEntity.ts
+++ b/src/lib/parseEntity.ts
@@ -1,12 +1,12 @@
-import parseEntityAttributes from './parseEntityAttributes'
-import type { TableDef } from '../classes/Table'
+import parseEntityAttributes from './parseEntityAttributes.js'
+import type { TableDef } from '../classes/Table/types.js'
 import type {
   AttributeDefinitions,
   EntityConstructor,
   PureAttributeDefinition,
   Readonly
-} from '../classes/Entity'
-import { error } from './utils'
+} from '../classes/Entity/types.js'
+import { error } from './utils.js'
 
 export interface TrackingInfo {
   fields: string[]
diff --git a/src/lib/parseEntityAttributes.ts b/src/lib/parseEntityAttributes.ts
index 4bf048f7..8406141e 100644
--- a/src/lib/parseEntityAttributes.ts
+++ b/src/lib/parseEntityAttributes.ts
@@ -9,11 +9,11 @@ import {
   AttributeDefinitions,
   PureAttributeDefinition,
   CompositeAttributeDefinition
-} from '../classes/Entity'
-import { TrackingInfo } from './parseEntity'
-import parseMapping from './parseMapping'
-import parseCompositeKey from './parseCompositeKey'
-import { error, typeError, validTypes, isDynamoDbType } from './utils'
+} from '../classes/Entity/types.js'
+import { TrackingInfo } from './parseEntity.js'
+import parseMapping from './parseMapping.js'
+import parseCompositeKey from './parseCompositeKey.js'
+import { error, typeError, validTypes, isDynamoDbType } from './utils.js'
 
 const parseEntityAttributes = <
   ReadonlyAttributeDefinitions extends
diff --git a/src/lib/parseMapping.ts b/src/lib/parseMapping.ts
index 68c0cdaa..441f76c3 100644
--- a/src/lib/parseMapping.ts
+++ b/src/lib/parseMapping.ts
@@ -10,9 +10,9 @@ import {
   SortKeyDefinition,
   GSISortKeyDefinition,
   PureAttributeDefinition
-} from '../classes/Entity'
-import { TrackingInfo } from './parseEntity'
-import { error } from './utils'
+} from '../classes/Entity/types.js'
+import { TrackingInfo } from './parseEntity.js'
+import { error } from './utils.js'
 
 // Parse and validate mapping config
 export default (
diff --git a/src/lib/parseTable.ts b/src/lib/parseTable.ts
index eab4f993..b046742a 100644
--- a/src/lib/parseTable.ts
+++ b/src/lib/parseTable.ts
@@ -1,8 +1,8 @@
 import { A } from 'ts-toolbelt'
 
-import parseAttributes from './parseTableAttributes'
-import { error, hasValue } from './utils'
-import { TableConstructor, TableIndexes } from '../classes/Table'
+import parseAttributes from './parseTableAttributes.js'
+import { error, hasValue } from './utils.js'
+import { TableConstructor, TableIndexes } from '../classes/Table/types.js'
 
 export type ParsedTable = ReturnType<typeof parseTable>
 
diff --git a/src/lib/parseTableAttributes.ts b/src/lib/parseTableAttributes.ts
index bf44dbee..05ce2c04 100644
--- a/src/lib/parseTableAttributes.ts
+++ b/src/lib/parseTableAttributes.ts
@@ -4,8 +4,8 @@
  * @license MIT
  */
 
-import { TableAttributes, TableAttributeConfig, ParsedTableAttribute } from '../classes/Table'
-import { error, typeError, keyTypeError, isDynamoDbType, isDynamoDbKeyType } from './utils'
+import { TableAttributes, TableAttributeConfig, ParsedTableAttribute } from '../classes/Table/types.js'
+import { error, typeError, keyTypeError, isDynamoDbType, isDynamoDbKeyType } from './utils.js'
 
 // Parse the attributes and verify valid types
 export default (attrs: TableAttributes, partitionKey: string, sortKey: string | null) =>
diff --git a/src/lib/projectionBuilder.ts b/src/lib/projectionBuilder.ts
index 221672e9..c6322b2a 100644
--- a/src/lib/projectionBuilder.ts
+++ b/src/lib/projectionBuilder.ts
@@ -8,9 +8,9 @@
 
 import { A } from 'ts-toolbelt'
 
-import { TableDef } from '../classes/Table'
-import { error } from './utils'
-import checkAttribute from './checkAttribute'
+import { TableDef } from '../classes/Table/types.js'
+import { error } from './utils.js'
+import checkAttribute from './checkAttribute.js'
 
 // This should be able to parse an array with values,
 // or an object that uses the name of the entity plus an array of values
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
index b14da818..3572a87c 100644
--- a/src/lib/utils.ts
+++ b/src/lib/utils.ts
@@ -1,7 +1,7 @@
 import { A, L } from 'ts-toolbelt'
 
-import { PureAttributeDefinition } from '../classes/Entity'
-import { DynamoDBTypes, DynamoDBKeyTypes } from '../classes/Table'
+import { PureAttributeDefinition } from '../classes/Entity/types.js'
+import { DynamoDBTypes, DynamoDBKeyTypes } from '../classes/Table/types.js'
 import { unmarshall } from '@aws-sdk/util-dynamodb'
 
 export const validTypes: DynamoDBTypes[] = [
diff --git a/src/lib/validateTypes.ts b/src/lib/validateTypes.ts
index fab69ac4..b22d9fc1 100644
--- a/src/lib/validateTypes.ts
+++ b/src/lib/validateTypes.ts
@@ -4,7 +4,7 @@
  * @license MIT
  */
 
-import { toBool, hasValue, error, toDynamoBigInt, typeOf, isArrayOfSameType } from './utils'
+import { toBool, hasValue, error, toDynamoBigInt, typeOf, isArrayOfSameType } from './utils.js'
 
 // Performs type validation/coercion
 export default () => (mapping: any, field: any, value: any) => {
diff --git a/tsconfig.build.json b/tsconfig.build.json
deleted file mode 100644
index b1cd8e4e..00000000
--- a/tsconfig.build.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "extends": "./tsconfig.json",
-  "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test-d.ts"]
-}
diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json
new file mode 100644
index 00000000..886c7143
--- /dev/null
+++ b/tsconfig.cjs.json
@@ -0,0 +1,9 @@
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "moduleResolution": "node",
+    "module": "commonjs",
+    "outDir": "dist/cjs"
+  },
+  "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test-d.ts"]
+}
diff --git a/tsconfig.esm.json b/tsconfig.esm.json
new file mode 100644
index 00000000..7caf2f6d
--- /dev/null
+++ b/tsconfig.esm.json
@@ -0,0 +1,10 @@
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "module": "NodeNext",
+    "moduleResolution": "NodeNext",
+    "noEmitHelpers": true,
+    "outDir": "dist/esm"
+  },
+  "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test-d.ts"]
+}
diff --git a/tsconfig.json b/tsconfig.json
index b817efa8..47235c73 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,11 +1,10 @@
 {
   "compilerOptions": {
+    "module": "NodeNext",
+    "moduleResolution": "NodeNext",
     "baseUrl": "src",
     "target": "es2019",
-    "outDir": "dist",
     "rootDir": "src",
-    "moduleResolution": "node",
-    "module": "commonjs",
     "declaration": true,
     "inlineSourceMap": false,
     "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,


Test patch:
diff --git a/src/__tests__/checkAttribute.unit.test.ts b/src/__tests__/checkAttribute.unit.test.ts
index 72394a95..3ba564e7 100644
--- a/src/__tests__/checkAttribute.unit.test.ts
+++ b/src/__tests__/checkAttribute.unit.test.ts
@@ -1,8 +1,8 @@
-import checkAttribute from '../lib/checkAttribute'
+import checkAttribute from '../lib/checkAttribute.js'
 
 // Require Table and Entity classes
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
 
 // Create basic table
 const DefaultTable = new Table({
diff --git a/src/__tests__/entity-creation.unit.test.ts b/src/__tests__/entity-creation.unit.test.ts
index e5939e52..d2f9dc9c 100644
--- a/src/__tests__/entity-creation.unit.test.ts
+++ b/src/__tests__/entity-creation.unit.test.ts
@@ -1,6 +1,6 @@
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
-import { DocumentClient, DocumentClientWithWrappedNumbers } from './bootstrap.test'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
+import { DocumentClient, DocumentClientWithWrappedNumbers } from './bootstrap.test.js'
 
 const tableAddEntity = jest.spyOn(Table.prototype, 'addEntity').mockReturnValue()
 
diff --git a/src/__tests__/entity-properties.unit.test.ts b/src/__tests__/entity-properties.unit.test.ts
index a40413ee..3a5e367b 100644
--- a/src/__tests__/entity-properties.unit.test.ts
+++ b/src/__tests__/entity-properties.unit.test.ts
@@ -1,5 +1,5 @@
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
 
 describe('Entity properties', () => {
   describe('table', () => {
diff --git a/src/__tests__/entity.delete.unit.test.ts b/src/__tests__/entity.delete.unit.test.ts
index 42d6d371..6dfa2ba8 100644
--- a/src/__tests__/entity.delete.unit.test.ts
+++ b/src/__tests__/entity.delete.unit.test.ts
@@ -1,5 +1,5 @@
-import { Entity, Table } from '..'
-import { DocumentClient } from './bootstrap.test'
+import { Entity, Table } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/entity.get.int.test.ts b/src/__tests__/entity.get.int.test.ts
index 01572ef8..93557462 100644
--- a/src/__tests__/entity.get.int.test.ts
+++ b/src/__tests__/entity.get.int.test.ts
@@ -1,6 +1,6 @@
 // @ts-nocheck
-import { Table, Entity } from '../index'
-import { DocumentClient } from './bootstrap.test'
+import { Table, Entity } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/entity.get.unit.test.ts b/src/__tests__/entity.get.unit.test.ts
index 44c23c80..49906921 100644
--- a/src/__tests__/entity.get.unit.test.ts
+++ b/src/__tests__/entity.get.unit.test.ts
@@ -1,5 +1,5 @@
-import { Table, Entity } from '..'
-import { DocumentClient } from './bootstrap.test'
+import { Table, Entity } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/entity.parse.unit.test.ts b/src/__tests__/entity.parse.unit.test.ts
index e4aae71f..a8a9af80 100644
--- a/src/__tests__/entity.parse.unit.test.ts
+++ b/src/__tests__/entity.parse.unit.test.ts
@@ -1,7 +1,7 @@
-import { DocumentClientWithWrappedNumbers } from './bootstrap.test'
+import { DocumentClientWithWrappedNumbers } from './bootstrap.test.js'
 
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
 import { unmarshall } from '@aws-sdk/util-dynamodb'
 
 const TestTable = new Table({
diff --git a/src/__tests__/entity.put.unit.test.ts b/src/__tests__/entity.put.unit.test.ts
index 882d6621..2c96755c 100644
--- a/src/__tests__/entity.put.unit.test.ts
+++ b/src/__tests__/entity.put.unit.test.ts
@@ -1,5 +1,5 @@
-import { Table, Entity } from '../index'
-import { DocumentClient } from './bootstrap.test'
+import { Table, Entity } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 import assert from 'assert'
 
 const TestTable = new Table({
diff --git a/src/__tests__/entity.putBatch.unit.test.ts b/src/__tests__/entity.putBatch.unit.test.ts
index c665d7fe..2815747b 100644
--- a/src/__tests__/entity.putBatch.unit.test.ts
+++ b/src/__tests__/entity.putBatch.unit.test.ts
@@ -1,5 +1,5 @@
-import { Table, Entity } from '../index'
-import { DocumentClient } from './bootstrap.test'
+import { Table, Entity } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/entity.transaction.unit.test.ts b/src/__tests__/entity.transaction.unit.test.ts
index 43866795..c2c7c5e5 100644
--- a/src/__tests__/entity.transaction.unit.test.ts
+++ b/src/__tests__/entity.transaction.unit.test.ts
@@ -1,5 +1,5 @@
-import { Table, Entity } from '../index'
-import { DocumentClient } from './bootstrap.test'
+import { Table, Entity } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 import assert from 'assert'
 
 const TestTable = new Table({
diff --git a/src/__tests__/entity.update.unit.test.ts b/src/__tests__/entity.update.unit.test.ts
index d170c22e..0c0cc9d0 100644
--- a/src/__tests__/entity.update.unit.test.ts
+++ b/src/__tests__/entity.update.unit.test.ts
@@ -1,9 +1,9 @@
 import {
   ATTRIBUTE_VALUES_LIST_DEFAULT_KEY,
   ATTRIBUTE_VALUES_LIST_DEFAULT_VALUE
-} from '../constants'
-import { Table, Entity } from '../index'
-import { DocumentClient } from './bootstrap.test'
+} from '../constants.js'
+import { Table, Entity } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 import assert from 'assert'
 
 const TestTable = new Table({
diff --git a/src/__tests__/entity.utils.unit.test.ts b/src/__tests__/entity.utils.unit.test.ts
index f96d397c..7b514e5c 100644
--- a/src/__tests__/entity.utils.unit.test.ts
+++ b/src/__tests__/entity.utils.unit.test.ts
@@ -1,4 +1,4 @@
-import { shouldExecute, shouldParse } from '../classes/Entity'
+import { shouldExecute, shouldParse } from '../classes/Entity/Entity.js'
 
 describe('Entity - utils', () => {
   it('should execute', () => {
diff --git a/src/__tests__/expressionBuilder.unit.test.ts b/src/__tests__/expressionBuilder.unit.test.ts
index 48ca57ac..f83c799f 100644
--- a/src/__tests__/expressionBuilder.unit.test.ts
+++ b/src/__tests__/expressionBuilder.unit.test.ts
@@ -1,9 +1,9 @@
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
 import {
   default as expressionBuilder,
   SUPPORTED_FILTER_EXP_ATTR_REF_OPERATORS
-} from '../lib/expressionBuilder'
+} from '../lib/expressionBuilder.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/format.unit.test.ts b/src/__tests__/format.unit.test.ts
index 9883a90e..4d7a0373 100644
--- a/src/__tests__/format.unit.test.ts
+++ b/src/__tests__/format.unit.test.ts
@@ -1,6 +1,6 @@
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
-import { DocumentClient } from './bootstrap.test'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/formatItem.unit.test.ts b/src/__tests__/formatItem.unit.test.ts
index c7fc75e3..ef79d792 100644
--- a/src/__tests__/formatItem.unit.test.ts
+++ b/src/__tests__/formatItem.unit.test.ts
@@ -1,9 +1,9 @@
-import formatItem from '../lib/formatItem'
+import formatItem from '../lib/formatItem.js'
 
-import { DocumentClient } from './bootstrap.test'
+import { DocumentClient } from './bootstrap.test.js'
 
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
 
 // Create basic table
 const DefaultTable = new Table({
diff --git a/src/__tests__/misc-tests.unit.test.ts b/src/__tests__/misc-tests.unit.test.ts
index b6426a7b..6e0c3264 100644
--- a/src/__tests__/misc-tests.unit.test.ts
+++ b/src/__tests__/misc-tests.unit.test.ts
@@ -1,6 +1,6 @@
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
-import { DocumentClient } from './bootstrap.test'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 describe('Misc Tests (development only)', () => {
   it('uses a numeric pk value', async () => {
diff --git a/src/__tests__/normalizeData.unit.test.ts b/src/__tests__/normalizeData.unit.test.ts
index 252b93ef..f957b56e 100644
--- a/src/__tests__/normalizeData.unit.test.ts
+++ b/src/__tests__/normalizeData.unit.test.ts
@@ -1,9 +1,9 @@
-import normalizeData from '../lib/normalizeData'
+import normalizeData from '../lib/normalizeData.js'
 
-import { DocumentClient } from './bootstrap.test'
+import { DocumentClient } from './bootstrap.test.js'
 
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
 
 const DefaultTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/parse-alias.unit.test.ts b/src/__tests__/parse-alias.unit.test.ts
index 2aaf7266..2eb03d39 100644
--- a/src/__tests__/parse-alias.unit.test.ts
+++ b/src/__tests__/parse-alias.unit.test.ts
@@ -1,6 +1,6 @@
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
-import { DocumentClient } from './bootstrap.test'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-alias',
diff --git a/src/__tests__/parse.unit.test.ts b/src/__tests__/parse.unit.test.ts
index 54204a77..518cd9bf 100644
--- a/src/__tests__/parse.unit.test.ts
+++ b/src/__tests__/parse.unit.test.ts
@@ -1,6 +1,6 @@
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
-import { DocumentClient } from './bootstrap.test'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/parseCompositeKey.unit.test.ts b/src/__tests__/parseCompositeKey.unit.test.ts
index a2853525..d1adcb9a 100644
--- a/src/__tests__/parseCompositeKey.unit.test.ts
+++ b/src/__tests__/parseCompositeKey.unit.test.ts
@@ -1,5 +1,5 @@
-import { TrackingInfo } from '../lib/parseEntity'
-import parseCompositeKey from '../lib/parseCompositeKey'
+import { TrackingInfo } from '../lib/parseEntity.js'
+import parseCompositeKey from '../lib/parseCompositeKey.js'
 
 // Simulate attributes
 const attributes = {
diff --git a/src/__tests__/parseEntity.unit.test.ts b/src/__tests__/parseEntity.unit.test.ts
index f1b45e0d..e56a988d 100644
--- a/src/__tests__/parseEntity.unit.test.ts
+++ b/src/__tests__/parseEntity.unit.test.ts
@@ -1,4 +1,4 @@
-import parseEntity from '../lib/parseEntity'
+import parseEntity from '../lib/parseEntity.js'
 
 // Simulate Entity config
 const entity = {
diff --git a/src/__tests__/parseMapping.unit.test.ts b/src/__tests__/parseMapping.unit.test.ts
index e23eecd9..890c3a66 100644
--- a/src/__tests__/parseMapping.unit.test.ts
+++ b/src/__tests__/parseMapping.unit.test.ts
@@ -1,5 +1,5 @@
-import parseMapping from '../lib/parseMapping'
-import { TrackingInfo } from '../lib/parseEntity'
+import parseMapping from '../lib/parseMapping.js'
+import { TrackingInfo } from '../lib/parseEntity.js'
 
 let track: TrackingInfo = {
   fields: [],
diff --git a/src/__tests__/parseTable.unit.test.ts b/src/__tests__/parseTable.unit.test.ts
index 6fa3c29f..7ae5463a 100644
--- a/src/__tests__/parseTable.unit.test.ts
+++ b/src/__tests__/parseTable.unit.test.ts
@@ -1,7 +1,7 @@
-import parseTable from '../lib/parseTable'
+import parseTable from '../lib/parseTable.js'
 
 // Require Table and Entity classes
-import { TableConstructor } from '../classes/Table'
+import { TableConstructor } from '../classes/Table/types.js'
 
 const table: TableConstructor<'test-table', 'pk', 'sk'> = {
   name: 'test-table',
diff --git a/src/__tests__/parseTableAttributes.unit.test.ts b/src/__tests__/parseTableAttributes.unit.test.ts
index 1c73929c..17a0e673 100644
--- a/src/__tests__/parseTableAttributes.unit.test.ts
+++ b/src/__tests__/parseTableAttributes.unit.test.ts
@@ -1,5 +1,5 @@
-import { TableAttributes } from '../classes/Table'
-import parseTableAttributes from '../lib/parseTableAttributes'
+import { TableAttributes } from '../classes/Table/types.js'
+import parseTableAttributes from '../lib/parseTableAttributes.js'
 
 const attrs: TableAttributes = {
   pk: 'string',
diff --git a/src/__tests__/projectionBuilder.unit.test.ts b/src/__tests__/projectionBuilder.unit.test.ts
index 51338279..d2111368 100644
--- a/src/__tests__/projectionBuilder.unit.test.ts
+++ b/src/__tests__/projectionBuilder.unit.test.ts
@@ -1,7 +1,7 @@
-import projectionBuilder from '../lib/projectionBuilder'
+import projectionBuilder from '../lib/projectionBuilder.js'
 
-import Table from '../classes/Table'
-import Entity from '../classes/Entity'
+import Table from '../classes/Table/Table.js'
+import Entity from '../classes/Entity/Entity.js'
 
 const DefaultTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/table-creation.unit.test.ts b/src/__tests__/table-creation.unit.test.ts
index f999b805..868a82e4 100644
--- a/src/__tests__/table-creation.unit.test.ts
+++ b/src/__tests__/table-creation.unit.test.ts
@@ -1,5 +1,5 @@
-import Table from '../classes/Table'
-import { DocumentClient, DocumentClientWithoutConfig } from './bootstrap.test'
+import Table from '../classes/Table/Table.js'
+import { DocumentClient, DocumentClientWithoutConfig } from './bootstrap.test.js'
 
 describe('Table creation', () => {
   it('creates table w/ minimum options', async () => {
diff --git a/src/__tests__/table.batchGet.unit.test.ts b/src/__tests__/table.batchGet.unit.test.ts
index 37fca087..ab0279f8 100644
--- a/src/__tests__/table.batchGet.unit.test.ts
+++ b/src/__tests__/table.batchGet.unit.test.ts
@@ -1,5 +1,5 @@
-import { Table, Entity } from '../index'
-import { DocumentClient } from './bootstrap.test'
+import { Table, Entity } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/table.batchWrite.unit.test.ts b/src/__tests__/table.batchWrite.unit.test.ts
index a76df783..250a300d 100644
--- a/src/__tests__/table.batchWrite.unit.test.ts
+++ b/src/__tests__/table.batchWrite.unit.test.ts
@@ -1,6 +1,6 @@
 import { BatchWriteCommandInput } from '@aws-sdk/lib-dynamodb'
-import { Entity, Table } from '../index'
-import { DocumentClient as docClient } from './bootstrap.test'
+import { Entity, Table } from '../index.js'
+import { DocumentClient as docClient } from './bootstrap.test.js'
 import assert from 'assert'
 
 const TestTable = new Table({
diff --git a/src/__tests__/table.entities.unit.test.ts b/src/__tests__/table.entities.unit.test.ts
index feff685a..7ff8e1ed 100644
--- a/src/__tests__/table.entities.unit.test.ts
+++ b/src/__tests__/table.entities.unit.test.ts
@@ -1,5 +1,5 @@
-import { Table, Entity } from '../index'
-import { DocumentClient } from './bootstrap.test'
+import { Table, Entity } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 let TestTable: any
 let TestEntity: any
diff --git a/src/__tests__/table.entity-actions.unit.test.ts b/src/__tests__/table.entity-actions.unit.test.ts
index 27eb70bf..c92fddd4 100644
--- a/src/__tests__/table.entity-actions.unit.test.ts
+++ b/src/__tests__/table.entity-actions.unit.test.ts
@@ -1,5 +1,5 @@
-import { Table, Entity } from '../index'
-import { DocumentClient } from './bootstrap.test'
+import { Table, Entity } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/table.query.unit.test.ts b/src/__tests__/table.query.unit.test.ts
index c9a2703d..e88659d3 100644
--- a/src/__tests__/table.query.unit.test.ts
+++ b/src/__tests__/table.query.unit.test.ts
@@ -1,5 +1,5 @@
-import { Entity, Table } from '../index'
-import { DocumentClient } from './bootstrap.test'
+import { Entity, Table } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/table.scan.unit.test.ts b/src/__tests__/table.scan.unit.test.ts
index f41a0ecb..24650e60 100644
--- a/src/__tests__/table.scan.unit.test.ts
+++ b/src/__tests__/table.scan.unit.test.ts
@@ -1,5 +1,5 @@
-import { Entity, Table } from '../index'
-import { DocumentClient } from './bootstrap.test'
+import { Entity, Table } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/table.transactGet.unit.test.ts b/src/__tests__/table.transactGet.unit.test.ts
index edf459a2..2194fba8 100644
--- a/src/__tests__/table.transactGet.unit.test.ts
+++ b/src/__tests__/table.transactGet.unit.test.ts
@@ -1,5 +1,5 @@
-import { Table, Entity } from '../index'
-import { DocumentClient } from './bootstrap.test'
+import { Table, Entity } from '../index.js'
+import { DocumentClient } from './bootstrap.test.js'
 
 const TestTable = new Table({
   name: 'test-table',
diff --git a/src/__tests__/table.transactWrite.unit.test.ts b/src/__tests__/table.transactWrite.unit.test.ts
index e148a247..18d5b20e 100644
--- a/src/__tests__/table.transactWrite.unit.test.ts
+++ b/src/__tests__/table.transactWrite.unit.test.ts
@@ -1,5 +1,5 @@
-import { Table, Entity } from '../index'
-import { DocumentClient as docClient } from './bootstrap.test'
+import { Table, Entity } from '../index.js'
+import { DocumentClient as docClient } from './bootstrap.test.js'
 import assert from 'assert'
 
 const TestTable = new Table({
diff --git a/src/__tests__/type-infering.unit.test.ts b/src/__tests__/type-infering.unit.test.ts
index 57d40570..8b2d1092 100644
--- a/src/__tests__/type-infering.unit.test.ts
+++ b/src/__tests__/type-infering.unit.test.ts
@@ -8,9 +8,9 @@ import {
   DeleteOptions,
   UpdateOptions,
   ConditionsOrFilters, AttributeMap,
-} from 'classes/Entity'
+} from 'classes/Entity/types.js'
 
-import { Table, Entity } from '../index'
+import { Table, Entity } from '../index.js'
 import { ReturnConsumedCapacity, ReturnItemCollectionMetrics, Select } from '@aws-sdk/client-dynamodb'
 import {
   DeleteCommandInput,
@@ -20,7 +20,7 @@ import {
   PutCommandInput, PutCommandOutput, QueryCommandInput, ScanCommandInput,
   UpdateCommandInput, UpdateCommandOutput,
 } from '@aws-sdk/lib-dynamodb'
-import { DocumentClient } from './bootstrap.test'
+import { DocumentClient } from './bootstrap.test.js'
 
 const omit = <O extends Record<string, unknown>, K extends (keyof O)[]>(
   obj: O,
diff --git a/src/__tests__/utils.unit.test.ts b/src/__tests__/utils.unit.test.ts
index 39f991dd..5bf823d4 100644
--- a/src/__tests__/utils.unit.test.ts
+++ b/src/__tests__/utils.unit.test.ts
@@ -1,4 +1,4 @@
-import { toBool, hasValue, error } from '../lib/utils'
+import { toBool, hasValue, error } from '../lib/utils.js'
 
 describe('utility functions', () => {
   test('toBool', () => {
diff --git a/src/__tests__/validateTypes.unit.test.ts b/src/__tests__/validateTypes.unit.test.ts
index 418225c1..2bed760d 100644
--- a/src/__tests__/validateTypes.unit.test.ts
+++ b/src/__tests__/validateTypes.unit.test.ts
@@ -1,5 +1,5 @@
-import { toDynamoBigInt } from '../lib/utils'
-import validateTypes from '../lib/validateTypes'
+import { toDynamoBigInt } from '../lib/utils.js'
+import validateTypes from '../lib/validateTypes.js'
 
 describe('validateTypes', () => {
   it('validates string', async () => {
diff --git a/test-d/index.cjs.test-d.ts b/test-d/index.cjs.test-d.ts
new file mode 100644
index 00000000..3b4ce9b9
--- /dev/null
+++ b/test-d/index.cjs.test-d.ts
@@ -0,0 +1,1 @@
+import type * as types from '../dist/cjs/index.js'
diff --git a/test-d/index.esm.test-d.ts b/test-d/index.esm.test-d.ts
new file mode 100644
index 00000000..e9b41cdb
--- /dev/null
+++ b/test-d/index.esm.test-d.ts
@@ -0,0 +1,1 @@
+import type * as types from '../dist/esm/index.js'
diff --git a/test-d/index.test-d.ts b/test-d/index.test-d.ts
deleted file mode 100644
index b446fd7e..00000000
--- a/test-d/index.test-d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-import type * as types from '../dist'