betterddb 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/src/betterddb.d.ts +137 -0
  2. package/dist/src/betterddb.d.ts.map +1 -0
  3. package/dist/src/betterddb.js +165 -0
  4. package/dist/src/betterddb.js.map +1 -0
  5. package/dist/src/builders/batch-get-builder.d.ts +16 -0
  6. package/dist/src/builders/batch-get-builder.d.ts.map +1 -0
  7. package/dist/src/builders/batch-get-builder.js +54 -0
  8. package/dist/src/builders/batch-get-builder.js.map +1 -0
  9. package/dist/src/builders/create-builder.d.ts +12 -0
  10. package/dist/src/builders/create-builder.d.ts.map +1 -0
  11. package/dist/src/builders/create-builder.js +84 -0
  12. package/dist/src/builders/create-builder.js.map +1 -0
  13. package/dist/src/builders/delete-builder.d.ts +18 -0
  14. package/dist/src/builders/delete-builder.d.ts.map +1 -0
  15. package/dist/src/builders/delete-builder.js +75 -0
  16. package/dist/src/builders/delete-builder.js.map +1 -0
  17. package/dist/src/builders/get-builder.d.ts +18 -0
  18. package/dist/src/builders/get-builder.d.ts.map +1 -0
  19. package/dist/src/builders/get-builder.js +76 -0
  20. package/dist/src/builders/get-builder.js.map +1 -0
  21. package/dist/src/builders/index.d.ts +8 -0
  22. package/dist/src/builders/index.d.ts.map +1 -0
  23. package/{src/builders/index.ts → dist/src/builders/index.js} +1 -0
  24. package/dist/src/builders/index.js.map +1 -0
  25. package/dist/src/builders/query-builder.d.ts +29 -0
  26. package/dist/src/builders/query-builder.d.ts.map +1 -0
  27. package/dist/src/builders/query-builder.js +171 -0
  28. package/dist/src/builders/query-builder.js.map +1 -0
  29. package/dist/src/builders/scan-builder.d.ts +21 -0
  30. package/dist/src/builders/scan-builder.d.ts.map +1 -0
  31. package/dist/src/builders/scan-builder.js +76 -0
  32. package/dist/src/builders/scan-builder.js.map +1 -0
  33. package/dist/src/builders/update-builder.d.ts +37 -0
  34. package/dist/src/builders/update-builder.d.ts.map +1 -0
  35. package/dist/src/builders/update-builder.js +301 -0
  36. package/dist/src/builders/update-builder.js.map +1 -0
  37. package/dist/src/index.d.ts +5 -0
  38. package/dist/src/index.d.ts.map +1 -0
  39. package/{src/index.ts → dist/src/index.js} +1 -0
  40. package/dist/src/index.js.map +1 -0
  41. package/dist/src/operator.d.ts +3 -0
  42. package/dist/src/operator.d.ts.map +1 -0
  43. package/dist/src/operator.js +28 -0
  44. package/dist/src/operator.js.map +1 -0
  45. package/dist/src/types/index.d.ts +2 -0
  46. package/dist/src/types/index.d.ts.map +1 -0
  47. package/{src/types/index.ts → dist/src/types/index.js} +1 -0
  48. package/dist/src/types/index.js.map +1 -0
  49. package/dist/src/types/paginated-result.d.ts +6 -0
  50. package/dist/src/types/paginated-result.d.ts.map +1 -0
  51. package/dist/src/types/paginated-result.js +2 -0
  52. package/dist/src/types/paginated-result.js.map +1 -0
  53. package/dist/tsconfig.tsbuildinfo +1 -0
  54. package/package.json +9 -8
  55. package/.github/workflows/npm-publish.yml +0 -33
  56. package/.github/workflows/test.yml +0 -42
  57. package/CONTRIBUTING.md +0 -225
  58. package/LICENCSE +0 -21
  59. package/babel.config.cjs +0 -6
  60. package/docker-compose.yml +0 -16
  61. package/eslint.config.mjs +0 -29
  62. package/jest.config.cjs +0 -17
  63. package/prettier.config.js +0 -6
  64. package/src/betterddb.ts +0 -267
  65. package/src/builders/batch-get-builder.ts +0 -56
  66. package/src/builders/create-builder.ts +0 -97
  67. package/src/builders/delete-builder.ts +0 -87
  68. package/src/builders/get-builder.ts +0 -78
  69. package/src/builders/query-builder.ts +0 -242
  70. package/src/builders/scan-builder.ts +0 -98
  71. package/src/builders/update-builder.ts +0 -363
  72. package/src/operator.ts +0 -43
  73. package/src/types/paginated-result.ts +0 -6
  74. package/test/batch-get.test.ts +0 -122
  75. package/test/create.test.ts +0 -121
  76. package/test/delete.test.ts +0 -93
  77. package/test/get.test.ts +0 -98
  78. package/test/query.test.ts +0 -206
  79. package/test/scan.test.ts +0 -130
  80. package/test/update.test.ts +0 -355
  81. package/test/utils/table-setup.ts +0 -62
  82. package/tsconfig.json +0 -23
package/CONTRIBUTING.md DELETED
@@ -1,225 +0,0 @@
1
- # Contributing to BetterDDB
2
-
3
- First off, thank you for considering contributing to BetterDDB! It's people like you that make BetterDDB such a great tool.
4
-
5
- ## Code of Conduct
6
-
7
- This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold this code.
8
-
9
- ## How Can I Contribute?
10
-
11
- ### Reporting Bugs
12
-
13
- Before creating bug reports, please check the issue list as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible:
14
-
15
- - Use a clear and descriptive title
16
- - Describe the exact steps which reproduce the problem
17
- - Provide specific examples to demonstrate the steps
18
- - Describe the behavior you observed after following the steps
19
- - Explain which behavior you expected to see instead and why
20
- - Include code samples and error messages if applicable
21
-
22
- ### Suggesting Enhancements
23
-
24
- Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, please include:
25
-
26
- - Use a clear and descriptive title
27
- - Provide a step-by-step description of the suggested enhancement
28
- - Provide specific examples to demonstrate the steps
29
- - Describe the current behavior and explain which behavior you expected to see instead
30
- - Explain why this enhancement would be useful
31
-
32
- ### Pull Requests
33
-
34
- - Fork the repo and create your branch from `main`
35
- - If you've added code that should be tested, add tests
36
- - Ensure the test suite passes
37
- - Make sure your code lints
38
- - Update the documentation
39
-
40
- ## Development Setup
41
-
42
- 1. Fork and clone the repo
43
- 2. Run `npm install` to install dependencies
44
- 3. Start LocalStack for DynamoDB testing: `docker-compose up -d`
45
- 4. Run `npm test` to run the tests
46
- 5. Create a branch for your changes
47
-
48
- ### Local Development Environment
49
-
50
- ```bash
51
- # Install dependencies
52
- npm install
53
-
54
- # Start LocalStack (required for tests)
55
- docker-compose up -d
56
-
57
- # Run tests
58
- npm test
59
-
60
- # Run linter
61
- npm run lint
62
-
63
- # Build the project
64
- npm run build
65
- ```
66
-
67
- ## Testing
68
-
69
- We use Jest for testing against a local DynamoDB instance provided by LocalStack. All tests can be found in the `test/` directory.
70
-
71
- ### Test Directory Structure
72
-
73
- ```
74
- test/
75
- ├── create.test.ts # Tests for create operations
76
- ├── get.test.ts # Tests for get operations
77
- ├── update.test.ts # Tests for update operations
78
- ├── delete.test.ts # Tests for delete operations
79
- ├── query.test.ts # Tests for query operations
80
- ├── scan.test.ts # Tests for scan operations
81
- ├── batch-get.test.ts # Tests for batch get operations
82
- └── utils/
83
- └── table-setup.ts # Utilities for setting up test tables
84
- ```
85
-
86
- ### Writing Tests
87
-
88
- Each test file focuses on a specific aspect of the library. Tests should follow this pattern:
89
-
90
- 1. **Setup**: Define schema, table configuration, and BetterDDB instance
91
- 2. **Initialize**: Create the test table in LocalStack before tests run
92
- 3. **Test**: Write test cases for specific functionality
93
- 4. **Cleanup**: Delete the test table after tests complete
94
-
95
- Here's an example of a basic test structure:
96
-
97
- ```typescript
98
- import { z } from "zod";
99
- import { BetterDDB } from "../src/betterddb";
100
- import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
101
- import { DynamoDB } from "@aws-sdk/client-dynamodb";
102
- import { createTestTable, deleteTestTable } from "./utils/table-setup";
103
-
104
- // Constants for test configuration
105
- const TEST_TABLE = "my-test-table";
106
- const ENDPOINT = "http://localhost:4566";
107
- const REGION = "us-east-1";
108
-
109
- // Define schema and key configuration
110
- const MySchema = z.object({
111
- id: z.string(),
112
- name: z.string(),
113
- });
114
-
115
- // Create DynamoDB client
116
- const client = DynamoDBDocumentClient.from(
117
- new DynamoDB({
118
- region: REGION,
119
- endpoint: ENDPOINT,
120
- }),
121
- );
122
-
123
- // Create BetterDDB instance
124
- const myDdb = new BetterDDB({
125
- schema: MySchema,
126
- tableName: TEST_TABLE,
127
- keys: {
128
- primary: {
129
- name: "pk",
130
- definition: { build: (raw) => `ITEM#${raw.id}` },
131
- },
132
- sort: {
133
- name: "sk",
134
- definition: { build: (raw) => `ITEM` },
135
- },
136
- },
137
- client,
138
- timestamps: true,
139
- });
140
-
141
- // Setup and teardown
142
- beforeAll(async () => {
143
- await createTestTable(TEST_TABLE, KEY_SCHEMA, ATTRIBUTE_DEFINITIONS, GSIS);
144
- });
145
-
146
- afterAll(async () => {
147
- await deleteTestTable(TEST_TABLE);
148
- });
149
-
150
- // Test cases
151
- describe("My Feature", () => {
152
- it("should do something specific", async () => {
153
- // Test implementation
154
- const result = await myDdb.create({ id: "123", name: "Test" }).execute();
155
- expect(result.id).toBe("123");
156
- });
157
- });
158
- ```
159
-
160
- ### Testing Utilities
161
-
162
- The `test/utils/table-setup.ts` file provides utilities for creating and deleting DynamoDB tables for testing:
163
-
164
- - **createTestTable**: Creates a DynamoDB table in LocalStack with the specified configuration
165
- - **deleteTestTable**: Deletes a DynamoDB table from LocalStack
166
-
167
- ### Testing Best Practices
168
-
169
- 1. **Isolated Tests**: Each test should be independent and not rely on other tests
170
- 2. **Clean up after tests**: Always delete created resources to avoid interference
171
- 3. **Test error cases**: Include tests for failure scenarios, not just success
172
- 4. **Use constants**: Define table names, key names, etc. as constants
173
- 5. **Test both simple and complex scenarios**: Cover the full range of functionality
174
- 6. **Add tests for new features**: Any new functionality should have corresponding tests
175
-
176
- ### Testing against LocalStack
177
-
178
- Tests run against a LocalStack instance, which provides a local DynamoDB implementation. To use this:
179
-
180
- 1. Ensure Docker is installed and running
181
- 2. Start LocalStack with `docker-compose up -d`
182
- 3. Run tests with `npm test`
183
-
184
- The `docker-compose.yml` file in the repository configures the LocalStack environment.
185
-
186
- ## Style Guide
187
-
188
- - We use ESLint and Prettier for code formatting
189
- - TypeScript is required for all new code
190
- - Follow the existing code style
191
- - Write descriptive commit messages
192
- - Add tests for new features
193
- - Update documentation for changes
194
-
195
- ## Project Structure
196
-
197
- ```
198
- src/
199
- ├── builders/ # Query builders
200
- ├── errors/ # Custom error types
201
- ├── types/ # TypeScript type definitions
202
- ├── betterddb.ts # Main class
203
- └── index.ts # Public API
204
- test/
205
- ├── *.test.ts # Test files
206
- └── utils/ # Test utilities
207
- ```
208
-
209
- ## Documentation
210
-
211
- - Keep README.md updated
212
- - Document new features
213
- - Keep code comments clear and relevant
214
- - Update TypeScript types
215
- - Update API_REFERENCE.md with new functionality
216
-
217
- ## Community
218
-
219
- - Join our [Discussions](https://github.com/ryanrawlingswang/betterddb/discussions)
220
-
221
- ## Questions?
222
-
223
- Feel free to open an issue or join our discussions if you have any questions.
224
-
225
- Thank you for contributing! 🎉
package/LICENCSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Ryan Rawlings Wang
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/babel.config.cjs DELETED
@@ -1,6 +0,0 @@
1
- module.exports = {
2
- presets: [
3
- ['@babel/preset-env', { targets: { node: 'current' } }],
4
- '@babel/preset-typescript',
5
- ],
6
- };
@@ -1,16 +0,0 @@
1
- version: "3.8"
2
- services:
3
- betterddb-localstack:
4
- image: localstack/localstack:latest
5
- container_name: betterddb-localstack
6
- ports:
7
- - "4566:4566" # Main edge port
8
- - "4571:4571"
9
- environment:
10
- - SERVICES=dynamodb
11
- - DEFAULT_REGION=us-east-1
12
- - DATA_DIR=/tmp/localstack_data
13
- - HOST_TMP_FOLDER=${TMPDIR:-/tmp}/localstack
14
- - LOCALSTACK_UI=1
15
- volumes:
16
- - "./localstack-tmp:/tmp/localstack_data"
package/eslint.config.mjs DELETED
@@ -1,29 +0,0 @@
1
- import js from '@eslint/js';
2
- import tseslint from '@typescript-eslint/eslint-plugin';
3
- import tsparser from '@typescript-eslint/parser';
4
- import prettier from 'eslint-plugin-prettier';
5
-
6
- export default [
7
- js.configs.recommended,
8
- {
9
- files: ['**/*.ts'],
10
- languageOptions: {
11
- parser: tsparser,
12
- parserOptions: {
13
- ecmaVersion: 'latest',
14
- sourceType: 'module',
15
- },
16
- },
17
- plugins: {
18
- '@typescript-eslint': tseslint,
19
- prettier: prettier,
20
- },
21
- rules: {
22
- 'prettier/prettier': 'error',
23
- // Basic TypeScript rules
24
- '@typescript-eslint/no-unused-vars': 'warn',
25
- '@typescript-eslint/no-explicit-any': 'warn',
26
- '@typescript-eslint/no-non-null-assertion': 'warn',
27
- },
28
- },
29
- ];
package/jest.config.cjs DELETED
@@ -1,17 +0,0 @@
1
- /** @type {import('jest').Config} */
2
- const config = {
3
- testEnvironment: "node",
4
- roots: ["<rootDir>/test/"],
5
- testMatch: ["**/*.test.ts"],
6
- transform: {
7
- "^.+\\.(ts|tsx|js|jsx)$": "babel-jest"
8
- },
9
- moduleNameMapper: {
10
- "^@/(.*)$": "<rootDir>/src/$1",
11
- "^~/(.*)$": "<rootDir>/src/$1",
12
- "^(\\.{1,2}/.*)\\.js$": "$1"
13
- },
14
- moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"]
15
- };
16
-
17
- module.exports = config;
@@ -1,6 +0,0 @@
1
- /** @type {import('prettier').Config} */
2
- const config = {
3
- tabWidth: 2,
4
- };
5
-
6
- export default config;
package/src/betterddb.ts DELETED
@@ -1,267 +0,0 @@
1
- import { type z } from "zod";
2
- import { QueryBuilder } from "./builders/query-builder";
3
- import { ScanBuilder } from "./builders/scan-builder";
4
- import { UpdateBuilder } from "./builders/update-builder";
5
- import { CreateBuilder } from "./builders/create-builder";
6
- import { GetBuilder } from "./builders/get-builder";
7
- import { DeleteBuilder } from "./builders/delete-builder";
8
- import {
9
- type NativeAttributeValue,
10
- type DynamoDBDocumentClient,
11
- } from "@aws-sdk/lib-dynamodb";
12
- import { BatchGetBuilder } from "./builders/batch-get-builder";
13
- export type PrimaryKeyValue = string | number;
14
-
15
- /**
16
- * A key definition can be either a simple key (a property name)
17
- * or an object containing a build function that computes the value.
18
- * (In this design, the attribute name is provided separately.)
19
- */
20
- export type KeyDefinition<T> =
21
- | keyof T
22
- | {
23
- build: (rawKey: Partial<T>) => string;
24
- };
25
-
26
- /**
27
- * Configuration for a primary (partition) key.
28
- */
29
- export interface PrimaryKeyConfig<T> {
30
- /** The attribute name for the primary key in DynamoDB */
31
- name: string;
32
- /** How to compute the key value; if a keyof T, then the raw value is used;
33
- * if an object, the build function is used.
34
- */
35
- definition: KeyDefinition<T>;
36
- }
37
-
38
- /**
39
- * Configuration for a sort key.
40
- */
41
- export interface SortKeyConfig<T> {
42
- /** The attribute name for the sort key in DynamoDB */
43
- name: string;
44
- /** How to compute the sort key value */
45
- definition: KeyDefinition<T>;
46
- }
47
-
48
- /**
49
- * Configuration for a Global Secondary Index (GSI).
50
- */
51
- export interface GSIConfig<T> {
52
- /** The name of the GSI in DynamoDB */
53
- name: string;
54
- /** The primary key configuration for the GSI */
55
- primary: PrimaryKeyConfig<T>;
56
- /** The sort key configuration for the GSI, if any */
57
- sort?: SortKeyConfig<T>;
58
- }
59
-
60
- /**
61
- * Keys configuration for the table.
62
- */
63
- export interface KeysConfig<T> {
64
- primary: PrimaryKeyConfig<T>;
65
- sort?: SortKeyConfig<T>;
66
- gsis?: Record<string, GSIConfig<T>>;
67
- }
68
-
69
- /**
70
- * Options for initializing BetterDDB.
71
- */
72
- export interface BetterDDBOptions<T> {
73
- schema: z.AnyZodObject;
74
- tableName: string;
75
- entityType?: string;
76
- keys: KeysConfig<T>;
77
- client: DynamoDBDocumentClient;
78
- counter?: boolean;
79
- /**
80
- * If true, automatically inject timestamp fields:
81
- * - On create, sets both `createdAt` and `updatedAt`
82
- * - On update, sets `updatedAt`
83
- *
84
- * (T should include these fields if enabled.)
85
- */
86
- timestamps?: boolean;
87
- }
88
-
89
- /**
90
- * BetterDDB is a definition-based DynamoDB wrapper library.
91
- */
92
- export class BetterDDB<T> {
93
- protected schema: z.AnyZodObject;
94
- protected tableName: string;
95
- protected entityType?: string;
96
- protected client: DynamoDBDocumentClient;
97
- protected keys: KeysConfig<T>;
98
- protected timestamps: boolean;
99
- protected counter: boolean;
100
-
101
- constructor(options: BetterDDBOptions<T>) {
102
- this.schema = options.schema;
103
- this.tableName = options.tableName;
104
- this.entityType = options.entityType?.toUpperCase();
105
- this.keys = options.keys;
106
- this.client = options.client;
107
- this.timestamps = options.timestamps ?? false;
108
- this.counter = options.counter ?? false;
109
- }
110
-
111
- public getCounter(): boolean {
112
- return this.counter;
113
- }
114
-
115
- public getKeys(): KeysConfig<T> {
116
- return this.keys;
117
- }
118
-
119
- public getTableName(): string {
120
- return this.tableName;
121
- }
122
-
123
- public getClient(): DynamoDBDocumentClient {
124
- return this.client;
125
- }
126
-
127
- public getSchema(): z.AnyZodObject {
128
- return this.schema;
129
- }
130
-
131
- public getTimestamps(): boolean {
132
- return this.timestamps;
133
- }
134
-
135
- public getEntityType(): string | undefined {
136
- return this.entityType;
137
- }
138
-
139
- // Helper: Retrieve the key value from a KeyDefinition.
140
- protected getKeyValue(def: KeyDefinition<T>, rawKey: Partial<T>): string {
141
- if (
142
- typeof def === "string" ||
143
- typeof def === "number" ||
144
- typeof def === "symbol"
145
- ) {
146
- return String(rawKey[def]);
147
- } else {
148
- return def.build(rawKey);
149
- }
150
- }
151
-
152
- /**
153
- * Build the primary key from a raw key object.
154
- */
155
- public buildKey(rawKey: Partial<T>): Record<string, NativeAttributeValue> {
156
- const keyObj: Record<string, NativeAttributeValue> = {};
157
-
158
- // For primary (partition) key:
159
- const pkConfig = this.keys.primary;
160
- keyObj[pkConfig.name] =
161
- typeof pkConfig.definition === "string" ||
162
- typeof pkConfig.definition === "number" ||
163
- typeof pkConfig.definition === "symbol"
164
- ? String(rawKey[pkConfig.definition])
165
- : pkConfig.definition.build(rawKey);
166
-
167
- // For sort key, if defined:
168
- if (this.keys.sort) {
169
- const skConfig = this.keys.sort;
170
- keyObj[skConfig.name] =
171
- typeof skConfig.definition === "string" ||
172
- typeof skConfig.definition === "number" ||
173
- typeof skConfig.definition === "symbol"
174
- ? String(rawKey[skConfig.definition])
175
- : skConfig.definition.build(rawKey);
176
- }
177
- return keyObj;
178
- }
179
-
180
- /**
181
- * Build index attributes for each defined GSI.
182
- */
183
- public buildIndexes(
184
- rawItem: Partial<T>,
185
- ): Record<string, NativeAttributeValue> {
186
- const indexAttributes: Record<string, NativeAttributeValue> = {};
187
- if (this.keys.gsis) {
188
- for (const gsiName in this.keys.gsis) {
189
- const gsiConfig = this.keys.gsis[gsiName];
190
- if (!gsiConfig) continue;
191
-
192
- // Compute primary index attribute.
193
- const primaryConfig = gsiConfig.primary;
194
- indexAttributes[primaryConfig.name] =
195
- typeof primaryConfig.definition === "string" ||
196
- typeof primaryConfig.definition === "number" ||
197
- typeof primaryConfig.definition === "symbol"
198
- ? String(rawItem[primaryConfig.definition])
199
- : primaryConfig.definition.build(rawItem);
200
-
201
- // Compute sort index attribute if provided.
202
- if (gsiConfig?.sort) {
203
- const sortConfig = gsiConfig.sort;
204
- indexAttributes[sortConfig.name] =
205
- typeof sortConfig.definition === "string" ||
206
- typeof sortConfig.definition === "number" ||
207
- typeof sortConfig.definition === "symbol"
208
- ? String(rawItem[sortConfig.definition])
209
- : sortConfig.definition.build(rawItem);
210
- }
211
- }
212
- }
213
- return indexAttributes;
214
- }
215
-
216
- /**
217
- * Create an item:
218
- * - Computes primary key and index attributes,
219
- * - Optionally injects timestamps,
220
- * - Validates the item and writes it to DynamoDB.
221
- */
222
- public create(item: T): CreateBuilder<T> {
223
- return new CreateBuilder<T>(this, item);
224
- }
225
-
226
- /**
227
- * Get an item by its primary key.
228
- */
229
- public get(rawKey: Partial<T>): GetBuilder<T> {
230
- return new GetBuilder<T>(this, rawKey);
231
- }
232
-
233
- /**
234
- * Get multiple items by their primary keys.
235
- */
236
- public batchGet(rawKeys: Partial<T>[]): BatchGetBuilder<T> {
237
- return new BatchGetBuilder<T>(this, rawKeys);
238
- }
239
-
240
- /**
241
- * Update an item.
242
- */
243
- public update(key: Partial<T>): UpdateBuilder<T> {
244
- return new UpdateBuilder<T>(this, key);
245
- }
246
-
247
- /**
248
- * Delete an item.
249
- */
250
- public delete(rawKey: Partial<T>): DeleteBuilder<T> {
251
- return new DeleteBuilder<T>(this, rawKey);
252
- }
253
-
254
- /**
255
- * Query items.
256
- */
257
- public query(key: Partial<T>): QueryBuilder<T> {
258
- return new QueryBuilder<T>(this, key);
259
- }
260
-
261
- /**
262
- * Scan for items.
263
- */
264
- public scan(): ScanBuilder<T> {
265
- return new ScanBuilder<T>(this);
266
- }
267
- }
@@ -1,56 +0,0 @@
1
- import { type BetterDDB } from "../betterddb.js";
2
- import { BatchGetCommand } from "@aws-sdk/lib-dynamodb";
3
- import { type BatchGetItemInput } from "@aws-sdk/client-dynamodb";
4
-
5
- export class BatchGetBuilder<T> {
6
- /**
7
- * @param parent - The BetterDDB instance for the table.
8
- * @param keys - An array of partial keys for the items you wish to retrieve.
9
- */
10
- constructor(
11
- private parent: BetterDDB<T>,
12
- private keys: Partial<T>[],
13
- ) {}
14
-
15
- /**
16
- * Executes the batch get operation.
17
- * Returns an array of parsed items of type T.
18
- */
19
- public async execute(): Promise<T[]> {
20
- if (this.keys.length === 0) {
21
- return [];
22
- }
23
-
24
- const seen = new Set();
25
- const deduplicatedKeys = this.keys.filter((key) => {
26
- const keyString = JSON.stringify(key);
27
- if (seen.has(keyString)) {
28
- return false;
29
- }
30
- seen.add(keyString);
31
- return true;
32
- });
33
- const tableName = this.parent.getTableName();
34
- // Build an array of keys using the parent's key builder.
35
- const keysArray = deduplicatedKeys.map((key) => this.parent.buildKey(key));
36
-
37
- // Construct the BatchGet parameters.
38
- const params: BatchGetItemInput = {
39
- RequestItems: {
40
- [tableName]: {
41
- Keys: keysArray,
42
- },
43
- },
44
- };
45
-
46
- const result = await this.parent
47
- .getClient()
48
- .send(new BatchGetCommand(params));
49
- const responses = result.Responses ? result.Responses[tableName] : [];
50
- if (!responses) {
51
- return [];
52
- }
53
-
54
- return this.parent.getSchema().array().parse(responses) as T[];
55
- }
56
- }