dyno-table 2.5.2 → 2.6.0

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 (58) hide show
  1. package/dist/builders/batch-builder.d.ts +249 -0
  2. package/dist/builders/builder-types.d.ts +123 -0
  3. package/dist/builders/condition-check-builder.d.ts +149 -0
  4. package/dist/builders/delete-builder.d.ts +208 -0
  5. package/dist/builders/entity-aware-builders.d.ts +127 -0
  6. package/dist/builders/filter-builder.d.ts +294 -0
  7. package/dist/builders/get-builder.d.ts +191 -0
  8. package/dist/builders/index.d.ts +14 -0
  9. package/dist/builders/paginator.d.ts +151 -0
  10. package/dist/builders/put-builder.d.ts +317 -0
  11. package/dist/builders/query-builder.d.ts +218 -0
  12. package/dist/builders/result-iterator.d.ts +55 -0
  13. package/dist/builders/scan-builder.d.ts +109 -0
  14. package/dist/builders/transaction-builder.d.ts +462 -0
  15. package/dist/builders/types.d.ts +25 -0
  16. package/dist/builders/update-builder.d.ts +372 -0
  17. package/dist/builders.d.ts +1 -4
  18. package/dist/conditions.d.ts +705 -3
  19. package/dist/entity/ddb-indexing.d.ts +45 -0
  20. package/dist/entity/entity.d.ts +188 -0
  21. package/dist/entity/index-utils.d.ts +24 -0
  22. package/dist/entity.cjs +4 -4
  23. package/dist/entity.d.ts +1 -261
  24. package/dist/entity.js +1 -1
  25. package/dist/errors.d.ts +212 -0
  26. package/dist/expression.d.ts +9 -0
  27. package/dist/index-definition.d.ts +10 -0
  28. package/dist/index.cjs +25 -25
  29. package/dist/index.d.ts +16 -273
  30. package/dist/index.js +1 -1
  31. package/dist/operation-types.d.ts +8 -0
  32. package/dist/standard-schema.d.ts +2 -4
  33. package/dist/table.d.ts +13 -8
  34. package/dist/types.d.ts +6 -9
  35. package/dist/utils/chunk-array.d.ts +9 -0
  36. package/dist/utils/debug-expression.d.ts +32 -0
  37. package/dist/utils/debug-transaction.d.ts +17 -0
  38. package/dist/utils/error-factory.d.ts +162 -0
  39. package/dist/utils/error-utils.d.ts +170 -0
  40. package/dist/utils/index.d.ts +7 -0
  41. package/dist/utils/partition-key-template.d.ts +30 -0
  42. package/dist/utils/sort-key-template.d.ts +33 -0
  43. package/dist/utils.d.ts +1 -66
  44. package/package.json +12 -10
  45. package/dist/builders.d.cts +0 -4
  46. package/dist/conditions-BSAcZswY.d.ts +0 -731
  47. package/dist/conditions-C8bM__Pn.d.cts +0 -731
  48. package/dist/conditions.d.cts +0 -3
  49. package/dist/entity.d.cts +0 -261
  50. package/dist/index-Bc-ra0im.d.ts +0 -3042
  51. package/dist/index-CPCmWsEv.d.cts +0 -3042
  52. package/dist/index.d.cts +0 -273
  53. package/dist/standard-schema.d.cts +0 -57
  54. package/dist/table.d.cts +0 -165
  55. package/dist/types.d.cts +0 -29
  56. package/dist/utils.d.cts +0 -66
  57. package/dist/{chunk-RNX2DAHA.js → chunk-JZB6TYST.js} +130 -130
  58. package/dist/{chunk-G5ERTQFX.cjs → chunk-Z334X72N.cjs} +130 -130
@@ -1,3042 +0,0 @@
1
- import { P as PrimaryKeyWithoutExpression, s as Path, b as Condition, c as ConditionOperator, t as PathType } from './conditions-BSAcZswY.js';
2
- import { DynamoItem, TableConfig, GSINames } from './types.js';
3
- import { TransactWriteCommandInput } from '@aws-sdk/lib-dynamodb';
4
-
5
- /**
6
- * Base error class for all dyno-table errors
7
- *
8
- * All custom errors in the library extend this class, allowing consumers
9
- * to catch all library errors with a single catch block if needed.
10
- */
11
- declare class DynoTableError extends Error {
12
- /**
13
- * Machine-readable error code for programmatic error handling
14
- * @example "KEY_GENERATION_FAILED", "VALIDATION_ERROR", etc.
15
- */
16
- readonly code: string;
17
- /**
18
- * Additional context about the error
19
- * Contains operation-specific details like entity names, table names,
20
- * expressions, conditions, and other relevant debugging information
21
- */
22
- readonly context: Record<string, unknown>;
23
- /**
24
- * The original error that caused this error (if wrapping another error)
25
- * Useful for preserving AWS SDK errors or other underlying errors
26
- */
27
- readonly cause?: Error;
28
- constructor(message: string, code: string, context?: Record<string, unknown>, cause?: Error);
29
- }
30
- /**
31
- * Error for schema validation and input validation failures
32
- *
33
- * Thrown when user-provided data doesn't match the expected schema
34
- * or when required fields are missing.
35
- */
36
- declare class ValidationError extends DynoTableError {
37
- constructor(message: string, code: string, context?: Record<string, unknown>, cause?: Error);
38
- }
39
- /**
40
- * Error for DynamoDB operation failures
41
- *
42
- * Wraps AWS SDK errors and adds library-specific context like
43
- * the operation type, table name, and generated expressions.
44
- */
45
- declare class OperationError extends DynoTableError {
46
- constructor(message: string, code: string, context?: Record<string, unknown>, cause?: Error);
47
- }
48
- /**
49
- * Error for transaction-specific failures
50
- *
51
- * Thrown when transaction operations fail, including duplicate item
52
- * detection, transaction cancellation, and other transaction-related issues.
53
- */
54
- declare class TransactionError extends DynoTableError {
55
- constructor(message: string, code: string, context?: Record<string, unknown>, cause?: Error);
56
- }
57
- /**
58
- * Error for batch operation failures
59
- *
60
- * Thrown when batch operations fail or when batch limits are exceeded.
61
- * Includes information about unprocessed items and operation details.
62
- */
63
- declare class BatchError extends DynoTableError {
64
- /**
65
- * The type of batch operation that failed
66
- */
67
- readonly operation: "write" | "read";
68
- /**
69
- * The items that were not processed during the batch operation
70
- */
71
- readonly unprocessedItems: unknown[];
72
- constructor(message: string, code: string, operation: "write" | "read", unprocessedItems?: unknown[], context?: Record<string, unknown>, cause?: Error);
73
- }
74
- /**
75
- * Error for expression building failures
76
- *
77
- * Thrown when building DynamoDB expressions (condition, filter, update, etc.)
78
- * fails due to invalid conditions or missing required fields.
79
- */
80
- declare class ExpressionError extends DynoTableError {
81
- constructor(message: string, code: string, context?: Record<string, unknown>, cause?: Error);
82
- }
83
- /**
84
- * Error for table/index configuration issues
85
- *
86
- * Thrown when there are problems with table configuration,
87
- * such as missing GSIs or invalid index references.
88
- */
89
- declare class ConfigurationError extends DynoTableError {
90
- constructor(message: string, code: string, context?: Record<string, unknown>, cause?: Error);
91
- }
92
- /**
93
- * Base error for all entity-related errors
94
- *
95
- * Parent class for entity-specific errors like key generation
96
- * and index generation failures.
97
- */
98
- declare class EntityError extends DynoTableError {
99
- constructor(message: string, code: string, context?: Record<string, unknown>, cause?: Error);
100
- }
101
- /**
102
- * Error for primary key generation failures
103
- *
104
- * Thrown when generating entity primary keys fails due to missing
105
- * attributes or invalid key formats.
106
- *
107
- * @example
108
- * ```typescript
109
- * try {
110
- * await userRepo.create({ name: "John" }).execute();
111
- * } catch (error) {
112
- * if (error instanceof KeyGenerationError) {
113
- * console.error("Failed to generate key");
114
- * console.error("Entity:", error.context.entityName);
115
- * console.error("Required attributes:", error.context.requiredAttributes);
116
- * }
117
- * }
118
- * ```
119
- */
120
- declare class KeyGenerationError extends EntityError {
121
- constructor(message: string, code: string, context?: Record<string, unknown>, cause?: Error);
122
- }
123
- /**
124
- * Error for index key generation failures
125
- *
126
- * Thrown when generating secondary index keys fails due to missing
127
- * attributes or when trying to update readonly indexes without forcing.
128
- *
129
- * @example
130
- * ```typescript
131
- * try {
132
- * await orderRepo.update({ id: "123" }, { status: "shipped" }).execute();
133
- * } catch (error) {
134
- * if (error instanceof IndexGenerationError) {
135
- * console.error("Index failed:", error.context.indexName);
136
- * console.error("Suggestion:", error.context.suggestion);
137
- * }
138
- * }
139
- * ```
140
- */
141
- declare class IndexGenerationError extends EntityError {
142
- constructor(message: string, code: string, context?: Record<string, unknown>, cause?: Error);
143
- }
144
- /**
145
- * Error for entity schema validation failures
146
- *
147
- * Thrown when entity data doesn't pass schema validation.
148
- * Includes validation issues and the entity context.
149
- */
150
- declare class EntityValidationError extends ValidationError {
151
- constructor(message: string, code: string, context?: Record<string, unknown>, cause?: Error);
152
- }
153
- /**
154
- * Error codes used throughout the library
155
- *
156
- * These codes allow for programmatic error handling and can be used
157
- * to implement retry logic, user-friendly error messages, etc.
158
- */
159
- declare const ErrorCodes: {
160
- readonly KEY_GENERATION_FAILED: "KEY_GENERATION_FAILED";
161
- readonly KEY_MISSING_ATTRIBUTES: "KEY_MISSING_ATTRIBUTES";
162
- readonly KEY_INVALID_FORMAT: "KEY_INVALID_FORMAT";
163
- readonly INDEX_GENERATION_FAILED: "INDEX_GENERATION_FAILED";
164
- readonly INDEX_MISSING_ATTRIBUTES: "INDEX_MISSING_ATTRIBUTES";
165
- readonly INDEX_NOT_FOUND: "INDEX_NOT_FOUND";
166
- readonly INDEX_READONLY_UPDATE_FAILED: "INDEX_READONLY_UPDATE_FAILED";
167
- readonly INDEX_UNDEFINED_VALUES: "INDEX_UNDEFINED_VALUES";
168
- readonly ENTITY_VALIDATION_FAILED: "ENTITY_VALIDATION_FAILED";
169
- readonly ASYNC_VALIDATION_NOT_SUPPORTED: "ASYNC_VALIDATION_NOT_SUPPORTED";
170
- readonly QUERY_INPUT_VALIDATION_FAILED: "QUERY_INPUT_VALIDATION_FAILED";
171
- readonly VALIDATION_ERROR: "VALIDATION_ERROR";
172
- readonly VALIDATION_FAILED: "VALIDATION_FAILED";
173
- readonly SCHEMA_VALIDATION_FAILED: "SCHEMA_VALIDATION_FAILED";
174
- readonly INVALID_PARAMETER: "INVALID_PARAMETER";
175
- readonly MISSING_REQUIRED_FIELD: "MISSING_REQUIRED_FIELD";
176
- readonly UNDEFINED_VALUE: "UNDEFINED_VALUE";
177
- readonly EXPRESSION_MISSING_ATTRIBUTE: "EXPRESSION_MISSING_ATTRIBUTE";
178
- readonly EXPRESSION_MISSING_VALUE: "EXPRESSION_MISSING_VALUE";
179
- readonly EXPRESSION_INVALID_CONDITION: "EXPRESSION_INVALID_CONDITION";
180
- readonly EXPRESSION_EMPTY_ARRAY: "EXPRESSION_EMPTY_ARRAY";
181
- readonly EXPRESSION_UNKNOWN_TYPE: "EXPRESSION_UNKNOWN_TYPE";
182
- readonly EXPRESSION_INVALID: "EXPRESSION_INVALID";
183
- readonly EXPRESSION_INVALID_OPERATOR: "EXPRESSION_INVALID_OPERATOR";
184
- readonly QUERY_FAILED: "QUERY_FAILED";
185
- readonly SCAN_FAILED: "SCAN_FAILED";
186
- readonly GET_FAILED: "GET_FAILED";
187
- readonly PUT_FAILED: "PUT_FAILED";
188
- readonly DELETE_FAILED: "DELETE_FAILED";
189
- readonly UPDATE_FAILED: "UPDATE_FAILED";
190
- readonly BATCH_GET_FAILED: "BATCH_GET_FAILED";
191
- readonly BATCH_WRITE_FAILED: "BATCH_WRITE_FAILED";
192
- readonly NO_UPDATE_ACTIONS: "NO_UPDATE_ACTIONS";
193
- readonly CONDITIONAL_CHECK_FAILED: "CONDITIONAL_CHECK_FAILED";
194
- readonly TRANSACTION_FAILED: "TRANSACTION_FAILED";
195
- readonly TRANSACTION_DUPLICATE_ITEM: "TRANSACTION_DUPLICATE_ITEM";
196
- readonly TRANSACTION_EMPTY: "TRANSACTION_EMPTY";
197
- readonly TRANSACTION_UNSUPPORTED_TYPE: "TRANSACTION_UNSUPPORTED_TYPE";
198
- readonly TRANSACTION_ITEM_LIMIT: "TRANSACTION_ITEM_LIMIT";
199
- readonly TRANSACTION_CANCELLED: "TRANSACTION_CANCELLED";
200
- readonly BATCH_EMPTY: "BATCH_EMPTY";
201
- readonly BATCH_UNSUPPORTED_TYPE: "BATCH_UNSUPPORTED_TYPE";
202
- readonly BATCH_UNPROCESSED_ITEMS: "BATCH_UNPROCESSED_ITEMS";
203
- readonly BATCH_SIZE_EXCEEDED: "BATCH_SIZE_EXCEEDED";
204
- readonly GSI_NOT_FOUND: "GSI_NOT_FOUND";
205
- readonly SORT_KEY_REQUIRED: "SORT_KEY_REQUIRED";
206
- readonly SORT_KEY_NOT_DEFINED: "SORT_KEY_NOT_DEFINED";
207
- readonly PRIMARY_KEY_MISSING: "PRIMARY_KEY_MISSING";
208
- readonly INVALID_CHUNK_SIZE: "INVALID_CHUNK_SIZE";
209
- readonly CONDITION_REQUIRED: "CONDITION_REQUIRED";
210
- readonly CONDITION_GENERATION_FAILED: "CONDITION_GENERATION_FAILED";
211
- readonly PK_EXTRACTION_FAILED: "PK_EXTRACTION_FAILED";
212
- readonly CONFIGURATION_INVALID: "CONFIGURATION_INVALID";
213
- readonly CONFIGURATION_MISSING_SORT_KEY: "CONFIGURATION_MISSING_SORT_KEY";
214
- readonly CONFIGURATION_INVALID_GSI: "CONFIGURATION_INVALID_GSI";
215
- };
216
- type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
217
-
218
- type BatchWriteOperation<T extends Record<string, unknown>> = {
219
- type: "put";
220
- item: T;
221
- } | {
222
- type: "delete";
223
- key: PrimaryKeyWithoutExpression;
224
- };
225
-
226
- /**
227
- * Interface for DynamoDB command objects that can contain expressions
228
- */
229
- interface DynamoCommandWithExpressions {
230
- conditionExpression?: string;
231
- updateExpression?: string;
232
- filterExpression?: string;
233
- keyConditionExpression?: string;
234
- projectionExpression?: string;
235
- expressionAttributeNames?: Record<string, string>;
236
- expressionAttributeValues?: Record<string, unknown>;
237
- [key: string]: unknown;
238
- }
239
-
240
- /**
241
- * Function type for executing DynamoDB operations and returning raw results.
242
- */
243
- type DirectExecutor<T extends DynamoItem> = () => Promise<{
244
- items: T[];
245
- lastEvaluatedKey?: DynamoItem;
246
- }>;
247
- /**
248
- * Minimal result generator that provides async iteration over DynamoDB results with automatic pagination.
249
- *
250
- * @example
251
- * ```typescript
252
- * const results = await queryBuilder.execute();
253
- *
254
- * for await (const item of results) {
255
- * console.log(item);
256
- * }
257
- * ```
258
- */
259
- declare class ResultIterator<T extends DynamoItem, TConfig extends TableConfig = TableConfig> {
260
- private queryBuilder;
261
- private directExecutor;
262
- private lastEvaluatedKey?;
263
- private itemsYielded;
264
- private readonly overallLimit?;
265
- constructor(queryBuilder: QueryBuilderInterface<T, TConfig>, directExecutor: DirectExecutor<T>);
266
- /**
267
- * Async iterator with automatic pagination
268
- */
269
- [Symbol.asyncIterator](): AsyncIterableIterator<T>;
270
- /**
271
- * Convert to array (loads all pages).
272
- *
273
- * ```ts
274
- * const result = await table.query({ pk: "foo" }).execute();
275
- * const allItemsFromDynamo = await result.toArray();
276
- * ```
277
- *
278
- * Note: This will load all pages into memory. For large datasets, consider using async iteration instead.
279
- *```ts
280
- * const result = await table.query({ pk: "foo" }).execute();
281
- * for await (const item of result) {
282
- * // Process each item
283
- * }
284
- * ```
285
- */
286
- toArray(): Promise<T[]>;
287
- /**
288
- * Get the last evaluated key
289
- */
290
- getLastEvaluatedKey(): DynamoItem | undefined;
291
- }
292
-
293
- interface DeleteCommandParams extends DynamoCommandWithExpressions {
294
- tableName: string;
295
- key: Record<string, unknown>;
296
- conditionExpression?: string;
297
- expressionAttributeNames?: Record<string, string>;
298
- expressionAttributeValues?: DynamoItem;
299
- returnValues?: "ALL_OLD";
300
- }
301
- /**
302
- * Parameters for the DynamoDB put command.
303
- *
304
- * These parameters are used when executing the operation against DynamoDB.
305
- *
306
- * The `returnValues` property can be:
307
- * - `"ALL_OLD"`: Return the attributes of the item as they were before the operation
308
- * - `"NONE"`: Return nothing
309
- * - `"CONSISTENT"`: Triggers a GET operation after the put to retrieve the updated item state
310
- * - `"INPUT"`: Return the input values that were passed to the operation (useful for create operations)
311
- */
312
- interface PutCommandParams extends DynamoCommandWithExpressions {
313
- tableName: string;
314
- item: DynamoItem;
315
- conditionExpression?: string;
316
- expressionAttributeNames?: Record<string, string>;
317
- expressionAttributeValues?: Record<string, unknown>;
318
- returnValues?: "ALL_OLD" | "NONE" | "CONSISTENT" | "INPUT";
319
- }
320
- /**
321
- * Parameters for the DynamoDB update command.
322
- * These parameters are used when executing the operation against DynamoDB.
323
- */
324
- interface UpdateCommandParams extends DynamoCommandWithExpressions {
325
- /** The name of the DynamoDB table */
326
- tableName: string;
327
- /** The primary key of the item to update */
328
- key: Record<string, unknown>;
329
- /** The update expression (SET, REMOVE, ADD, DELETE clauses) */
330
- updateExpression: string;
331
- /** Optional condition expression that must be satisfied */
332
- conditionExpression?: string;
333
- /** Map of expression attribute name placeholders to actual names */
334
- expressionAttributeNames?: Record<string, string>;
335
- /** Map of expression attribute value placeholders to actual values */
336
- expressionAttributeValues?: DynamoItem;
337
- /** Which item attributes to include in the response */
338
- returnValues?: "ALL_NEW" | "UPDATED_NEW" | "ALL_OLD" | "UPDATED_OLD" | "NONE";
339
- }
340
- interface ConditionCheckCommandParams extends DynamoCommandWithExpressions {
341
- tableName: string;
342
- key: Record<string, unknown>;
343
- conditionExpression: string;
344
- expressionAttributeNames?: Record<string, string>;
345
- expressionAttributeValues?: DynamoItem;
346
- }
347
- /**
348
- * Base interface for all builder classes that support pagination
349
- * to be used by Paginator without creating circular dependencies.
350
- */
351
- interface BaseBuilderInterface<T extends DynamoItem, TConfig extends TableConfig = TableConfig, B = unknown> {
352
- clone(): B;
353
- limit(limit: number): B;
354
- getLimit(): number | undefined;
355
- startFrom(lastEvaluatedKey: DynamoItem): B;
356
- execute(): Promise<ResultIterator<T, TConfig>>;
357
- findOne(): Promise<T | undefined>;
358
- }
359
- /**
360
- * Interface for the QueryBuilder class to be used by Paginator
361
- * without creating a circular dependency.
362
- */
363
- interface QueryBuilderInterface<T extends DynamoItem, TConfig extends TableConfig = TableConfig> extends BaseBuilderInterface<T, TConfig, QueryBuilderInterface<T, TConfig>> {
364
- }
365
- /**
366
- * Interface for the ScanBuilder class to be used by Paginator
367
- * without creating a circular dependency.
368
- */
369
- interface ScanBuilderInterface<T extends DynamoItem, TConfig extends TableConfig = TableConfig> extends BaseBuilderInterface<T, TConfig, ScanBuilderInterface<T, TConfig>> {
370
- }
371
- /**
372
- * Interface for the FilterBuilder class to be used by Paginator
373
- * without creating a circular dependency.
374
- */
375
- interface FilterBuilderInterface<T extends DynamoItem, TConfig extends TableConfig = TableConfig> extends BaseBuilderInterface<T, TConfig, FilterBuilderInterface<T, TConfig>> {
376
- }
377
- /**
378
- * Represents the result of a single page query operation.
379
- * This interface provides all necessary information about the current page
380
- * and the availability of subsequent pages.
381
- */
382
- interface PaginationResult<T> {
383
- /** The items (dinosaurs, habitats, etc.) retrieved for the current page */
384
- items: T[];
385
- /** DynamoDB's last evaluated key, used internally for pagination */
386
- lastEvaluatedKey?: DynamoItem;
387
- /** Indicates whether there are more pages available */
388
- hasNextPage: boolean;
389
- /** The current page number (1-indexed) */
390
- page: number;
391
- }
392
- /**
393
- * Represents a single operation within a DynamoDB transaction.
394
- * Each operation can be one of:
395
- * - Put: Insert or replace an item
396
- * - Update: Modify an existing item
397
- * - Delete: Remove an item
398
- * - ConditionCheck: Verify item state without modification
399
- */
400
- type TransactionItem = {
401
- type: "Put";
402
- params: PutCommandParams;
403
- } | {
404
- type: "Update";
405
- params: UpdateCommandParams;
406
- } | {
407
- type: "Delete";
408
- params: DeleteCommandParams;
409
- } | {
410
- type: "ConditionCheck";
411
- params: ConditionCheckCommandParams;
412
- };
413
-
414
- /**
415
- * Parameters for the DynamoDB get command.
416
- */
417
- interface GetCommandParams {
418
- /** The name of the DynamoDB table */
419
- tableName: string;
420
- /** The primary key of the item to get */
421
- key: PrimaryKeyWithoutExpression;
422
- /** Comma-separated list of attributes to return */
423
- projectionExpression?: string;
424
- /** Map of expression attribute name placeholders to actual names */
425
- expressionAttributeNames?: Record<string, string>;
426
- /** Whether to use strongly consistent reads */
427
- consistentRead?: boolean;
428
- }
429
- /**
430
- * Function type for executing DynamoDB get operations.
431
- * @typeParam T - The type of item being retrieved
432
- */
433
- type GetExecutor<T extends DynamoItem> = (params: GetCommandParams) => Promise<{
434
- item: T | undefined;
435
- }>;
436
- /**
437
- * Builder for creating DynamoDB get operations.
438
- * Use this builder when you need to:
439
- * - Retrieve a single dinosaur by its primary key
440
- * - Project specific dinosaur attributes
441
- * - Use consistent reads for critical dinosaur data
442
- *
443
- * @example
444
- * ```typescript
445
- * // Simple get
446
- * const result = await new GetBuilder(executor, { pk: 'dinosaur#123', sk: 'profile' })
447
- * .execute();
448
- *
449
- * // Get with projection and consistent read
450
- * const result = await new GetBuilder(executor, { pk: 'dinosaur#123', sk: 'profile' })
451
- * .select(['species', 'name', 'diet'])
452
- * .consistentRead()
453
- * .execute();
454
- * ```
455
- *
456
- * @typeParam T - The type of item being retrieved
457
- */
458
- declare class GetBuilder<T extends DynamoItem> {
459
- private readonly executor;
460
- private readonly params;
461
- private options;
462
- private selectedFields;
463
- private includeIndexAttributes;
464
- private readonly indexAttributeNames;
465
- /**
466
- * Creates a new GetBuilder instance.
467
- *
468
- * @param executor - Function that executes the get operation
469
- * @param key - Primary key of the item to retrieve
470
- * @param tableName - Name of the DynamoDB table
471
- */
472
- constructor(executor: GetExecutor<T>, key: PrimaryKeyWithoutExpression, tableName: string, indexAttributeNames?: string[]);
473
- /**
474
- * Specifies which attributes to return in the get results.
475
- *
476
- * @example
477
- * ```typescript
478
- * // Select single attribute
479
- * builder.select('species')
480
- *
481
- * // Select multiple attributes
482
- * builder.select(['id', 'species', 'diet'])
483
- *
484
- * // Chain multiple select calls
485
- * builder
486
- * .select('id')
487
- * .select(['species', 'diet'])
488
- * ```
489
- *
490
- * @param fields - A single field name or an array of field names to return
491
- * @returns The builder instance for method chaining
492
- */
493
- select<K extends Path<T>>(fields: K | K[]): GetBuilder<T>;
494
- /**
495
- * Ensures index attributes are included in the result.
496
- * By default, index attributes are removed from get responses.
497
- */
498
- includeIndexes(): GetBuilder<T>;
499
- /**
500
- * Sets whether to use strongly consistent reads for the get operation.
501
- * Use this method when you need:
502
- * - The most up-to-date dinosaur data
503
- * - To ensure you're reading the latest dinosaur status
504
- * - Critical safety information about dangerous species
505
- *
506
- * Note: Consistent reads consume twice the throughput
507
- *
508
- * @example
509
- * ```typescript
510
- * // Get the latest T-Rex data
511
- * const result = await new GetBuilder(executor, { pk: 'dinosaur#123', sk: 'profile' })
512
- * .consistentRead()
513
- * .execute();
514
- * ```
515
- *
516
- * @param consistentRead - Whether to use consistent reads (defaults to true)
517
- * @returns The builder instance for method chaining
518
- */
519
- consistentRead(consistentRead?: boolean): GetBuilder<T>;
520
- /**
521
- * Adds this get operation to a batch with optional entity type information.
522
- *
523
- * @example Basic Usage
524
- * ```ts
525
- * const batch = table.batchBuilder();
526
- *
527
- * // Add multiple get operations to batch
528
- * dinosaurRepo.get({ id: 'dino-1' }).withBatch(batch);
529
- * dinosaurRepo.get({ id: 'dino-2' }).withBatch(batch);
530
- * dinosaurRepo.get({ id: 'dino-3' }).withBatch(batch);
531
- *
532
- * // Execute all gets efficiently
533
- * const results = await batch.execute();
534
- * ```
535
- *
536
- * @example Typed Usage
537
- * ```ts
538
- * const batch = table.batchBuilder<{
539
- * User: UserEntity;
540
- * Order: OrderEntity;
541
- * }>();
542
- *
543
- * // Add operations with type information
544
- * userRepo.get({ id: 'user-1' }).withBatch(batch, 'User');
545
- * orderRepo.get({ id: 'order-1' }).withBatch(batch, 'Order');
546
- *
547
- * // Execute and get typed results
548
- * const result = await batch.execute();
549
- * const users: UserEntity[] = result.reads.itemsByType.User;
550
- * const orders: OrderEntity[] = result.reads.itemsByType.Order;
551
- * ```
552
- *
553
- * @param batch - The batch builder to add this operation to
554
- * @param entityType - Optional entity type key for type tracking
555
- */
556
- withBatch<TEntities extends Record<string, DynamoItem> = Record<string, DynamoItem>, K extends keyof TEntities = keyof TEntities>(batch: BatchBuilder<TEntities>, entityType?: K): void;
557
- /**
558
- * Converts the builder configuration to a DynamoDB command
559
- */
560
- private toDynamoCommand;
561
- private addIndexAttributesToSelection;
562
- private omitIndexAttributes;
563
- /**
564
- * Executes the get operation against DynamoDB.
565
- *
566
- * @example
567
- * ```typescript
568
- * try {
569
- * const result = await new GetBuilder(executor, { pk: 'dinosaur#123', sk: 'profile' })
570
- * .select(['species', 'name', 'diet'])
571
- * .consistentRead()
572
- * .execute();
573
- *
574
- * if (result.item) {
575
- * console.log('Dinosaur found:', result.item);
576
- * } else {
577
- * console.log('Dinosaur not found');
578
- * }
579
- * } catch (error) {
580
- * console.error('Error getting dinosaur:', error);
581
- * }
582
- * ```
583
- *
584
- * @returns A promise that resolves to an object containing:
585
- * - item: The retrieved dinosaur or undefined if not found
586
- */
587
- execute(): Promise<{
588
- item: T | undefined;
589
- }>;
590
- }
591
-
592
- /**
593
- * Configuration for batch operations
594
- */
595
- interface BatchConfig {
596
- partitionKey: string;
597
- sortKey?: string;
598
- }
599
- /**
600
- * Executor function for batch write operations
601
- */
602
- type BatchWriteExecutor = (operations: Array<BatchWriteOperation<DynamoItem>>) => Promise<{
603
- unprocessedItems: Array<BatchWriteOperation<DynamoItem>>;
604
- }>;
605
- /**
606
- * Executor function for batch get operations
607
- */
608
- type BatchGetExecutor = (keys: Array<PrimaryKeyWithoutExpression>) => Promise<{
609
- items: DynamoItem[];
610
- unprocessedKeys: PrimaryKeyWithoutExpression[];
611
- }>;
612
- /**
613
- * Result structure for batch operations
614
- */
615
- interface BatchResult {
616
- /** Whether the batch operation completed successfully */
617
- success: boolean;
618
- /** Write operation results */
619
- writes: {
620
- /** Number of write operations processed successfully */
621
- processed: number;
622
- /** Write operations that were not processed and may need retry */
623
- unprocessed: Array<BatchWriteOperation<DynamoItem>>;
624
- };
625
- /** Read operation results */
626
- reads: {
627
- /** Items retrieved from the batch get operations */
628
- items: DynamoItem[];
629
- /** Number of items found and returned */
630
- found: number;
631
- /** Keys that were not processed and may need retry */
632
- unprocessed: PrimaryKeyWithoutExpression[];
633
- };
634
- /** Total number of operations in the batch */
635
- totalOperations: number;
636
- /** Any errors that occurred during batch processing */
637
- errors?: BatchError[];
638
- }
639
- /**
640
- * Typed result structure for batch operations with entity type information
641
- */
642
- interface TypedBatchResult<TEntities extends Record<string, DynamoItem> = Record<string, DynamoItem>> {
643
- /** Whether the batch operation completed successfully */
644
- success: boolean;
645
- /** Write operation results */
646
- writes: {
647
- /** Number of write operations processed successfully */
648
- processed: number;
649
- /** Write operations that were not processed and may need retry */
650
- unprocessed: Array<BatchWriteOperation<DynamoItem>>;
651
- };
652
- /** Read operation results with typed items */
653
- reads: {
654
- /** Items retrieved from the batch get operations, grouped by entity type */
655
- itemsByType: {
656
- [K in keyof TEntities]: TEntities[K][];
657
- };
658
- /** All items retrieved (typed as union of all entity types) */
659
- items: TEntities[keyof TEntities][];
660
- /** Number of items found and returned */
661
- found: number;
662
- /** Keys that were not processed and may need retry */
663
- unprocessed: PrimaryKeyWithoutExpression[];
664
- };
665
- /** Total number of operations in the batch */
666
- totalOperations: number;
667
- /** Any errors that occurred during batch execution */
668
- errors?: BatchError[];
669
- }
670
- /**
671
- * Builder for creating and executing DynamoDB batch operations with full entity support and type inference.
672
- *
673
- * Use BatchBuilder when you need to:
674
- * - Perform multiple operations efficiently (up to 25 writes, 100 reads per batch)
675
- * - Maintain entity validation, key generation, and type safety
676
- * - Mix read and write operations in a single batch
677
- * - Get typed results grouped by entity type
678
- *
679
- * @example Basic Usage
680
- * ```typescript
681
- * // Define entity types for the batch
682
- * const batch = table.batchBuilder<{
683
- * User: UserEntity;
684
- * Order: OrderEntity;
685
- * }>();
686
- *
687
- * // Add operations using entity repositories
688
- * userRepo.create(newUser).withBatch(batch, 'User')
689
- * userRepo.delete({ id: 'old-user' }).withBatch(batch, 'User')
690
- * orderRepo.get({ id: 'existing-order' }).withBatch(batch, 'Order')
691
- *
692
- * // Execute all operations and get typed results
693
- * const result = await batch.execute()
694
- * const users: UserEntity[] = result.reads.itemsByType.User
695
- * const orders: OrderEntity[] = result.reads.itemsByType.Order
696
- * ```
697
- *
698
- * @example Error Handling
699
- * ```typescript
700
- * try {
701
- * const result = await batch.execute()
702
- *
703
- * if (result.writes.unprocessed.length > 0) {
704
- * console.warn('Some writes were not processed:', result.writes.unprocessed)
705
- * }
706
- * } catch (error) {
707
- * if (error instanceof BatchError) {
708
- * console.error('Batch operation failed:', error.message)
709
- * }
710
- * }
711
- * ```
712
- */
713
- declare class BatchBuilder<TEntities extends Record<string, DynamoItem> = Record<string, DynamoItem>> {
714
- private batchWriteExecutor;
715
- private batchGetExecutor;
716
- private config;
717
- private writeItems;
718
- private getItems;
719
- constructor(batchWriteExecutor: BatchWriteExecutor, batchGetExecutor: BatchGetExecutor, config: BatchConfig);
720
- /**
721
- * Checks if the batch is empty (contains no operations)
722
- *
723
- * @returns true if the batch contains no operations
724
- */
725
- isEmpty(): boolean;
726
- /**
727
- * Gets the count of operations in the batch
728
- *
729
- * @returns Object containing the count of write and read operations
730
- */
731
- getOperationCount(): {
732
- writes: number;
733
- reads: number;
734
- };
735
- /**
736
- * Validates that the batch is not empty before execution
737
- *
738
- * @throws {BatchError} If the batch is empty
739
- */
740
- private validateNotEmpty;
741
- /**
742
- * Adds a put operation to the batch with entity type information.
743
- * This method is used internally by entity builders.
744
- *
745
- * @param command - The complete put command configuration
746
- * @param entityType - The entity type name for type tracking
747
- * @returns The batch builder for method chaining
748
- * @internal
749
- */
750
- putWithCommand<K extends keyof TEntities>(command: PutCommandParams, entityType?: K): this;
751
- /**
752
- * Adds a delete operation to the batch with entity type information.
753
- * This method is used internally by entity builders.
754
- *
755
- * @param command - The complete delete command configuration
756
- * @param entityType - The entity type name for type tracking
757
- * @returns The batch builder for method chaining
758
- * @internal
759
- */
760
- deleteWithCommand<K extends keyof TEntities>(command: DeleteCommandParams, entityType?: K): this;
761
- /**
762
- * Adds a get operation to the batch with entity type information.
763
- * This method is used internally by entity builders.
764
- *
765
- * @param command - The complete get command configuration
766
- * @param entityType - The entity type name for type tracking
767
- * @returns The batch builder for method chaining
768
- * @internal
769
- */
770
- getWithCommand<K extends keyof TEntities>(command: GetCommandParams, entityType?: K): this;
771
- /**
772
- * Executes all write operations in the batch.
773
- *
774
- * @returns A promise that resolves to any unprocessed operations
775
- * @private
776
- */
777
- private executeWrites;
778
- /**
779
- * Executes all get operations in the batch.
780
- *
781
- * @returns A promise that resolves to the retrieved items
782
- * @private
783
- */
784
- private executeGets;
785
- /**
786
- * Groups retrieved items by their entity type.
787
- * @private
788
- */
789
- private groupItemsByType;
790
- /**
791
- * Executes all operations in the batch with typed results.
792
- * Performs write operations first, then get operations.
793
- *
794
- * @returns A promise that resolves to a TypedBatchResult with entity type information
795
- * @throws {BatchError} If the batch is empty or if operations fail
796
- */
797
- execute(): Promise<TypedBatchResult<TEntities>>;
798
- }
799
-
800
- /**
801
- * Configuration options for DynamoDB transactions.
802
- */
803
- interface TransactionOptions {
804
- /** Unique identifier for the transaction request (idempotency token) */
805
- clientRequestToken?: string;
806
- /** Level of consumed capacity details to return */
807
- returnConsumedCapacity?: "INDEXES" | "TOTAL" | "NONE";
808
- /** Whether to return item collection metrics */
809
- returnItemCollectionMetrics?: "SIZE" | "NONE";
810
- }
811
- /**
812
- * Configuration for table indexes used in duplicate detection.
813
- * Defines the key structure for checking uniqueness constraints.
814
- */
815
- interface IndexConfig {
816
- /** The partition key attribute name */
817
- partitionKey: string;
818
- /** Optional sort key attribute name */
819
- sortKey?: string;
820
- }
821
- /**
822
- * Function type for executing DynamoDB transaction operations.
823
- * @param params - The complete transaction command input
824
- * @returns A promise that resolves when the transaction completes
825
- */
826
- type TransactionExecutor = (params: TransactWriteCommandInput) => Promise<void>;
827
- /**
828
- * Builder for creating and executing DynamoDB transactions.
829
- * Use this builder when you need to:
830
- * - Perform multiple operations atomically
831
- * - Ensure data consistency across operations
832
- * - Implement complex business logic that requires atomic updates
833
- * - Prevent duplicate items across tables
834
- *
835
- * The builder supports:
836
- * - Put operations (insert/replace items)
837
- * - Delete operations
838
- * - Update operations
839
- * - Condition checks
840
- * - Duplicate detection
841
- * - Transaction-wide options
842
- *
843
- * @example
844
- * ```typescript
845
- * // Create a transaction with multiple operations
846
- * const transaction = new TransactionBuilder(executor, {
847
- * partitionKey: 'id',
848
- * sortKey: 'type'
849
- * });
850
- *
851
- * // Add a new order
852
- * transaction.put('orders', {
853
- * orderId: '123',
854
- * status: 'PENDING'
855
- * });
856
- *
857
- * // Update inventory with condition
858
- * transaction.update(
859
- * 'inventory',
860
- * { productId: 'ABC' },
861
- * 'set quantity = quantity - :amount',
862
- * { ':amount': 1 },
863
- * op => op.gte('quantity', 1)
864
- * );
865
- *
866
- * // Execute the transaction atomically
867
- * await transaction.execute();
868
- * ```
869
- *
870
- * Note: DynamoDB transactions have some limitations:
871
- * - Maximum 25 operations per transaction
872
- * - All operations must be in the same AWS region
873
- * - Cannot include table scans or queries
874
- */
875
- declare class TransactionBuilder {
876
- private items;
877
- private options;
878
- private indexConfig;
879
- private readonly executor;
880
- constructor(executor: TransactionExecutor, indexConfig: IndexConfig);
881
- /**
882
- * Checks if an item with the same primary key already exists in the transaction
883
- * @private
884
- */
885
- private checkForDuplicateItem;
886
- createKeyForPrimaryIndex(key: PrimaryKeyWithoutExpression): {
887
- [x: string]: string;
888
- };
889
- /**
890
- * Adds a put operation to the transaction.
891
- *
892
- * The method automatically checks for duplicate items within the transaction
893
- * to prevent multiple operations on the same item.
894
- *
895
- * @example
896
- * ```typescript
897
- * // Simple put operation
898
- * transaction.put('orders', {
899
- * orderId: '123',
900
- * status: 'PENDING',
901
- * amount: 100
902
- * });
903
- *
904
- * // Conditional put operation
905
- * transaction.put(
906
- * 'inventory',
907
- * { productId: 'ABC', quantity: 50 },
908
- * op => op.attributeNotExists('productId')
909
- * );
910
- *
911
- * // Put with complex condition
912
- * transaction.put(
913
- * 'users',
914
- * { userId: '123', status: 'ACTIVE' },
915
- * op => op.and([
916
- * op.attributeNotExists('userId'),
917
- * op.beginsWith('status', 'ACTIVE')
918
- * ])
919
- * );
920
- * ```
921
- *
922
- * @param tableName - The name of the DynamoDB table
923
- * @param item - The item to put into the table
924
- * @param condition - Optional condition that must be satisfied
925
- * @returns The transaction builder for method chaining
926
- * @throws {Error} If a duplicate item is detected in the transaction
927
- */
928
- put<T extends DynamoItem>(tableName: string, item: T, condition?: Condition): this;
929
- /**
930
- * Adds a pre-configured put operation to the transaction.
931
- *
932
- * This method is particularly useful when working with PutBuilder
933
- * to maintain consistency in put operations across your application.
934
- *
935
- * @example
936
- * ```typescript
937
- * // Create a put command with PutBuilder
938
- * const putCommand = new PutBuilder(executor, newItem, 'users')
939
- * .condition(op => op.attributeNotExists('userId'))
940
- * .toDynamoCommand();
941
- *
942
- * // Add the command to the transaction
943
- * transaction.putWithCommand(putCommand);
944
- * ```
945
- *
946
- * @param command - The complete put command configuration
947
- * @returns The transaction builder for method chaining
948
- * @throws {Error} If a duplicate item is detected in the transaction
949
- * @see PutBuilder for creating put commands
950
- */
951
- putWithCommand(command: PutCommandParams): TransactionBuilder;
952
- /**
953
- * Adds a delete operation to the transaction.
954
- *
955
- * The method automatically checks for duplicate items within the transaction
956
- * to prevent multiple operations on the same item.
957
- *
958
- * @example
959
- * ```typescript
960
- * // Simple delete operation
961
- * transaction.delete('orders', {
962
- * pk: 'ORDER#123',
963
- * sk: 'METADATA'
964
- * });
965
- *
966
- * // Conditional delete operation
967
- * transaction.delete(
968
- * 'users',
969
- * { pk: 'USER#123' },
970
- * op => op.eq('status', 'INACTIVE')
971
- * );
972
- *
973
- * // Delete with complex condition
974
- * transaction.delete(
975
- * 'products',
976
- * { pk: 'PROD#ABC' },
977
- * op => op.and([
978
- * op.eq('status', 'DRAFT'),
979
- * op.lt('version', 5)
980
- * ])
981
- * );
982
- * ```
983
- *
984
- * @param tableName - The name of the DynamoDB table
985
- * @param key - The primary key of the item to delete
986
- * @param condition - Optional condition that must be satisfied
987
- * @returns The transaction builder for method chaining
988
- * @throws {Error} If a duplicate item is detected in the transaction
989
- */
990
- delete(tableName: string, key: PrimaryKeyWithoutExpression, condition?: Condition): TransactionBuilder;
991
- /**
992
- * Adds a pre-configured delete operation to the transaction.
993
- *
994
- * This method is particularly useful when working with DeleteBuilder
995
- * to maintain consistency in delete operations across your application.
996
- *
997
- * @example
998
- * ```typescript
999
- * // Create a delete command with DeleteBuilder
1000
- * const deleteCommand = new DeleteBuilder(executor, 'users', { pk: 'USER#123' })
1001
- * .condition(op => op.and([
1002
- * op.attributeExists('pk'),
1003
- * op.eq('status', 'INACTIVE')
1004
- * ]))
1005
- * .toDynamoCommand();
1006
- *
1007
- * // Add the command to the transaction
1008
- * transaction.deleteWithCommand(deleteCommand);
1009
- * ```
1010
- *
1011
- * @param command - The complete delete command configuration
1012
- * @returns The transaction builder for method chaining
1013
- * @throws {Error} If a duplicate item is detected in the transaction
1014
- * @see DeleteBuilder for creating delete commands
1015
- */
1016
- deleteWithCommand(command: DeleteCommandParams): this;
1017
- /**
1018
- * Adds an update operation to the transaction.
1019
- *
1020
- * The method supports all DynamoDB update expressions:
1021
- * - SET: Modify or add attributes
1022
- * - REMOVE: Delete attributes
1023
- * - ADD: Update numbers and sets
1024
- * - DELETE: Remove elements from a set
1025
- *
1026
- * @example
1027
- * ```typescript
1028
- * // Simple update
1029
- * transaction.update(
1030
- * 'orders',
1031
- * { pk: 'ORDER#123' },
1032
- * 'SET #status = :status',
1033
- * { '#status': 'status' },
1034
- * { ':status': 'PROCESSING' }
1035
- * );
1036
- *
1037
- * // Complex update with multiple operations
1038
- * transaction.update(
1039
- * 'products',
1040
- * { pk: 'PROD#ABC' },
1041
- * 'SET #qty = #qty - :amount, #status = :status REMOVE #oldAttr',
1042
- * { '#qty': 'quantity', '#status': 'status', '#oldAttr': 'deprecated_field' },
1043
- * { ':amount': 1, ':status': 'LOW_STOCK' }
1044
- * );
1045
- *
1046
- * // Conditional update
1047
- * transaction.update(
1048
- * 'users',
1049
- * { pk: 'USER#123' },
1050
- * 'SET #lastLogin = :now',
1051
- * { '#lastLogin': 'lastLoginDate' },
1052
- * { ':now': new Date().toISOString() },
1053
- * op => op.attributeExists('pk')
1054
- * );
1055
- * ```
1056
- *
1057
- * @param tableName - The name of the DynamoDB table
1058
- * @param key - The primary key of the item to update
1059
- * @param updateExpression - The update expression (SET, REMOVE, ADD, DELETE)
1060
- * @param expressionAttributeNames - Map of attribute name placeholders to actual names
1061
- * @param expressionAttributeValues - Map of value placeholders to actual values
1062
- * @param condition - Optional condition that must be satisfied
1063
- * @returns The transaction builder for method chaining
1064
- * @throws {Error} If a duplicate item is detected in the transaction
1065
- */
1066
- update<_T extends DynamoItem>(tableName: string, key: PrimaryKeyWithoutExpression, updateExpression: string, expressionAttributeNames?: Record<string, string>, expressionAttributeValues?: Record<string, unknown>, condition?: Condition): this;
1067
- /**
1068
- * Adds a pre-configured update operation to the transaction.
1069
- *
1070
- * This method is particularly useful when working with UpdateBuilder
1071
- * to maintain consistency in update operations across your application.
1072
- *
1073
- * @example
1074
- * ```typescript
1075
- * // Create an update command with UpdateBuilder
1076
- * const updateCommand = new UpdateBuilder(executor, 'inventory', { pk: 'PROD#ABC' })
1077
- * .set('quantity', ':qty')
1078
- * .set('lastUpdated', ':now')
1079
- * .values({
1080
- * ':qty': 100,
1081
- * ':now': new Date().toISOString()
1082
- * })
1083
- * .condition(op => op.gt('quantity', 0))
1084
- * .toDynamoCommand();
1085
- *
1086
- * // Add the command to the transaction
1087
- * transaction.updateWithCommand(updateCommand);
1088
- * ```
1089
- *
1090
- * @param command - The complete update command configuration
1091
- * @returns The transaction builder for method chaining
1092
- * @throws {Error} If a duplicate item is detected in the transaction
1093
- * @see UpdateBuilder for creating update commands
1094
- */
1095
- updateWithCommand(command: UpdateCommandParams): TransactionBuilder;
1096
- /**
1097
- * Adds a condition check operation to the transaction.
1098
- *
1099
- * Condition checks are particularly useful for:
1100
- * - Implementing optimistic locking
1101
- * - Ensuring referential integrity
1102
- * - Validating business rules atomically
1103
- *
1104
- * @example
1105
- * ```typescript
1106
- * // Check if order is in correct state
1107
- * transaction.conditionCheck(
1108
- * 'orders',
1109
- * { pk: 'ORDER#123' },
1110
- * op => op.eq('status', 'PENDING')
1111
- * );
1112
- *
1113
- * // Complex condition check
1114
- * transaction.conditionCheck(
1115
- * 'inventory',
1116
- * { pk: 'PROD#ABC' },
1117
- * op => op.and([
1118
- * op.gt('quantity', 0),
1119
- * op.eq('status', 'ACTIVE'),
1120
- * op.attributeExists('lastRestockDate')
1121
- * ])
1122
- * );
1123
- *
1124
- * // Check with multiple attributes
1125
- * transaction.conditionCheck(
1126
- * 'users',
1127
- * { pk: 'USER#123' },
1128
- * op => op.or([
1129
- * op.eq('status', 'PREMIUM'),
1130
- * op.gte('credits', 100)
1131
- * ])
1132
- * );
1133
- * ```
1134
- *
1135
- * @param tableName - The name of the DynamoDB table
1136
- * @param key - The primary key of the item to check
1137
- * @param condition - The condition that must be satisfied
1138
- * @returns The transaction builder for method chaining
1139
- * @throws {Error} If a duplicate item is detected in the transaction
1140
- * @throws {Error} If condition expression generation fails
1141
- */
1142
- conditionCheck(tableName: string, key: PrimaryKeyWithoutExpression, condition: Condition): TransactionBuilder;
1143
- /**
1144
- * Adds a pre-configured condition check operation to the transaction.
1145
- *
1146
- * This method is particularly useful when working with ConditionCheckBuilder
1147
- * to maintain consistency in condition checks across your application.
1148
- *
1149
- * @example
1150
- * ```typescript
1151
- * // Create a condition check with ConditionCheckBuilder
1152
- * const checkCommand = new ConditionCheckBuilder('inventory', { pk: 'PROD#ABC' })
1153
- * .condition(op => op.and([
1154
- * op.between('quantity', 10, 100),
1155
- * op.beginsWith('category', 'ELECTRONICS'),
1156
- * op.attributeExists('lastAuditDate')
1157
- * ]))
1158
- * .toDynamoCommand();
1159
- *
1160
- * // Add the command to the transaction
1161
- * transaction.conditionCheckWithCommand(checkCommand);
1162
- * ```
1163
- *
1164
- * @param command - The complete condition check command configuration
1165
- * @returns The transaction builder for method chaining
1166
- * @throws {Error} If a duplicate item is detected in the transaction
1167
- * @see ConditionCheckBuilder for creating condition check commands
1168
- */
1169
- conditionCheckWithCommand(command: ConditionCheckCommandParams): TransactionBuilder;
1170
- /**
1171
- * Sets options for the transaction execution.
1172
- *
1173
- * @example
1174
- * ```typescript
1175
- * // Enable idempotency and capacity tracking
1176
- * transaction.withOptions({
1177
- * clientRequestToken: 'unique-request-id-123',
1178
- * returnConsumedCapacity: 'TOTAL'
1179
- * });
1180
- *
1181
- * // Track item collection metrics
1182
- * transaction.withOptions({
1183
- * returnItemCollectionMetrics: 'SIZE'
1184
- * });
1185
- * ```
1186
- *
1187
- * Note: ClientRequestToken can be used to make transactions idempotent,
1188
- * ensuring the same transaction is not executed multiple times.
1189
- *
1190
- * @param options - Configuration options for the transaction
1191
- * @returns The transaction builder for method chaining
1192
- */
1193
- withOptions(options: TransactionOptions): TransactionBuilder;
1194
- /**
1195
- * Gets a human-readable representation of the transaction items.
1196
- *
1197
- * The method resolves all expression placeholders with their actual values,
1198
- * making it easier to understand the transaction's operations.
1199
- *
1200
- * @example
1201
- * ```typescript
1202
- * // Add multiple operations
1203
- * transaction
1204
- * .put('orders', { orderId: '123', status: 'PENDING' })
1205
- * .update('inventory',
1206
- * { productId: 'ABC' },
1207
- * 'SET quantity = quantity - :amount',
1208
- * undefined,
1209
- * { ':amount': 1 }
1210
- * );
1211
- *
1212
- * // Debug the transaction
1213
- * const debugInfo = transaction.debug();
1214
- * console.log('Transaction operations:', debugInfo);
1215
- * ```
1216
- *
1217
- * @returns An array of readable representations of the transaction items
1218
- */
1219
- debug(): Record<string, unknown>[];
1220
- /**
1221
- * Executes all operations in the transaction atomically.
1222
- *
1223
- * The transaction will only succeed if all operations succeed.
1224
- * If any operation fails, the entire transaction is rolled back.
1225
- *
1226
- * @example
1227
- * ```typescript
1228
- * try {
1229
- * // Build and execute transaction
1230
- * await transaction
1231
- * .put('orders', newOrder)
1232
- * .update('inventory',
1233
- * { productId: 'ABC' },
1234
- * 'SET quantity = quantity - :qty',
1235
- * undefined,
1236
- * { ':qty': 1 }
1237
- * )
1238
- * .conditionCheck('products',
1239
- * { productId: 'ABC' },
1240
- * op => op.eq('status', 'ACTIVE')
1241
- * )
1242
- * .execute();
1243
- *
1244
- * console.log('Transaction completed successfully');
1245
- * } catch (error) {
1246
- * // Handle transaction failure
1247
- * console.error('Transaction failed:', error);
1248
- * }
1249
- * ```
1250
- *
1251
- * @throws {Error} If no transaction items are specified
1252
- * @throws {Error} If any operation in the transaction fails
1253
- * @returns A promise that resolves when the transaction completes
1254
- */
1255
- execute(): Promise<void>;
1256
- }
1257
-
1258
- interface DeleteOptions {
1259
- condition?: Condition;
1260
- returnValues?: "ALL_OLD";
1261
- }
1262
- type DeleteExecutor = (params: DeleteCommandParams) => Promise<{
1263
- item?: DynamoItem;
1264
- }>;
1265
- /**
1266
- * Builder for creating DynamoDB delete operations.
1267
- *
1268
- * @example
1269
- * ```typescript
1270
- * // Simple delete
1271
- * const result = await new DeleteBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
1272
- * .execute();
1273
- *
1274
- * // Conditional delete with old value retrieval
1275
- * const result = await new DeleteBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
1276
- * .condition(op =>
1277
- * op.and([
1278
- * op.eq('status', 'DECOMMISSIONED'),
1279
- * op.eq('occupants', 0),
1280
- * op.lt('securityIncidents', 1)
1281
- * ])
1282
- * )
1283
- * .returnValues('ALL_OLD')
1284
- * .execute();
1285
- * ```
1286
- */
1287
- declare class DeleteBuilder {
1288
- private options;
1289
- private readonly executor;
1290
- private readonly tableName;
1291
- private readonly key;
1292
- constructor(executor: DeleteExecutor, tableName: string, key: PrimaryKeyWithoutExpression);
1293
- /**
1294
- * Adds a condition that must be satisfied for the delete operation to succeed.
1295
- *
1296
- * @example
1297
- * ```typescript
1298
- * // Ensure dinosaur can be safely removed
1299
- * builder.condition(op =>
1300
- * op.and([
1301
- * op.eq('status', 'SEDATED'),
1302
- * op.eq('location', 'MEDICAL_BAY'),
1303
- * op.attributeExists('lastCheckup')
1304
- * ])
1305
- * );
1306
- *
1307
- * // Verify habitat is empty
1308
- * builder.condition(op =>
1309
- * op.and([
1310
- * op.eq('occupants', 0),
1311
- * op.eq('maintenanceStatus', 'COMPLETE'),
1312
- * op.not(op.attributeExists('activeAlerts'))
1313
- * ])
1314
- * );
1315
- * ```
1316
- *
1317
- * @param condition - Either a Condition object or a callback function that builds the condition
1318
- * @returns The builder instance for method chaining
1319
- */
1320
- condition<T extends DynamoItem>(condition: Condition | ((op: ConditionOperator<T>) => Condition)): DeleteBuilder;
1321
- /**
1322
- * Sets whether to return the item's attribute values before deletion.
1323
- *
1324
- * @example
1325
- * ```ts
1326
- * // Archive dinosaur data before removal
1327
- * const result = await builder
1328
- * .returnValues('ALL_OLD')
1329
- * .execute();
1330
- *
1331
- * if (result.item) {
1332
- * console.log('Removed dinosaur data:', {
1333
- * species: result.item.species,
1334
- * age: result.item.age,
1335
- * lastLocation: result.item.location
1336
- * });
1337
- * }
1338
- * ```
1339
- *
1340
- * @param returnValues - Use 'ALL_OLD' to return all attributes of the deleted item
1341
- * @returns The builder instance for method chaining
1342
- */
1343
- returnValues(returnValues: "ALL_OLD"): DeleteBuilder;
1344
- /**
1345
- * Generate the DynamoDB command parameters
1346
- */
1347
- private toDynamoCommand;
1348
- /**
1349
- * Adds this delete operation to a transaction.
1350
- *
1351
- * @example
1352
- * ```ts
1353
- * const transaction = new TransactionBuilder();
1354
- *
1355
- * // Remove dinosaur from old habitat
1356
- * new DeleteBuilder(executor, 'dinosaurs', { id: 'RAPTOR-001' })
1357
- * .condition(op => op.eq('status', 'SEDATED'))
1358
- * .withTransaction(transaction);
1359
- *
1360
- * // Update old habitat occupancy
1361
- * new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
1362
- * .add('occupants', -1)
1363
- * .withTransaction(transaction);
1364
- *
1365
- * // Execute transfer atomically
1366
- * await transaction.execute();
1367
- * ```
1368
- *
1369
- * @param transaction - The transaction builder to add this operation to
1370
- */
1371
- withTransaction(transaction: TransactionBuilder): void;
1372
- /**
1373
- * Adds this delete operation to a batch with optional entity type information.
1374
- *
1375
- * @example Basic Usage
1376
- * ```ts
1377
- * const batch = table.batchBuilder();
1378
- *
1379
- * // Remove multiple dinosaurs in batch
1380
- * dinosaurRepo.delete({ id: 'old-dino-1' }).withBatch(batch);
1381
- * dinosaurRepo.delete({ id: 'old-dino-2' }).withBatch(batch);
1382
- * dinosaurRepo.delete({ id: 'old-dino-3' }).withBatch(batch);
1383
- *
1384
- * // Execute all deletions efficiently
1385
- * await batch.execute();
1386
- * ```
1387
- *
1388
- * @example Typed Usage
1389
- * ```ts
1390
- * const batch = table.batchBuilder<{
1391
- * User: UserEntity;
1392
- * Order: OrderEntity;
1393
- * }>();
1394
- *
1395
- * // Add operations with type information
1396
- * userRepo.delete({ id: 'user-1' }).withBatch(batch, 'User');
1397
- * orderRepo.delete({ id: 'order-1' }).withBatch(batch, 'Order');
1398
- *
1399
- * // Execute batch operations
1400
- * await batch.execute();
1401
- * ```
1402
- *
1403
- * @param batch - The batch builder to add this operation to
1404
- * @param entityType - Optional entity type key for type tracking
1405
- */
1406
- withBatch<TEntities extends Record<string, DynamoItem> = Record<string, DynamoItem>, K extends keyof TEntities = keyof TEntities>(batch: BatchBuilder<TEntities>, entityType?: K): void;
1407
- /**
1408
- * Executes the delete operation against DynamoDB.
1409
- *
1410
- * @example
1411
- * ```ts
1412
- * // Delete with condition and retrieve old values
1413
- * const result = await new DeleteBuilder(executor, 'myTable', { id: '123' })
1414
- * .condition(op => op.eq('status', 'INACTIVE'))
1415
- * .returnValues('ALL_OLD')
1416
- * .execute();
1417
- *
1418
- * if (result.item) {
1419
- * console.log('Deleted item:', result.item);
1420
- * }
1421
- * ```
1422
- *
1423
- * @returns A promise that resolves to an object containing the deleted item's attributes (if returnValues is 'ALL_OLD')
1424
- */
1425
- execute(): Promise<{
1426
- item?: DynamoItem;
1427
- }>;
1428
- /**
1429
- * Gets a human-readable representation of the delete command
1430
- * with all expression placeholders replaced by their actual values.
1431
- *
1432
- * @example
1433
- * ```ts
1434
- * const debugInfo = new DeleteBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
1435
- * .condition(op => op.and([
1436
- * op.eq('status', 'SEDATED'),
1437
- * op.eq('location', 'MEDICAL_BAY'),
1438
- * op.gt('sedationLevel', 8)
1439
- * op.eq('version', 1),
1440
- * op.attributeExists('status')
1441
- * ]))
1442
- * .debug();
1443
- *
1444
- * console.log('Delete command:', debugInfo);
1445
- * ```
1446
- *
1447
- * @returns A readable representation of the delete command with resolved expressions
1448
- */
1449
- debug(): {
1450
- raw: DeleteCommandParams;
1451
- readable: {
1452
- conditionExpression?: string;
1453
- updateExpression?: string;
1454
- filterExpression?: string;
1455
- keyConditionExpression?: string;
1456
- projectionExpression?: string;
1457
- };
1458
- };
1459
- }
1460
-
1461
- /**
1462
- * Configuration options for DynamoDB put operations.
1463
- */
1464
- interface PutOptions {
1465
- /** Optional condition that must be satisfied for the put operation to succeed */
1466
- condition?: Condition;
1467
- /** Determines how to handle the return value of the put operation
1468
- * @options
1469
- * - NONE: No return value
1470
- * - ALL_OLD: Returns the item's previous state if it existed
1471
- * - CONSISTENT: Performs a GET operation after the put to retrieve the item's new state
1472
- * - INPUT: Returns the input values that were passed to the operation
1473
- */
1474
- returnValues?: "ALL_OLD" | "NONE" | "CONSISTENT" | "INPUT";
1475
- }
1476
- type PutExecutor<T extends DynamoItem> = (params: PutCommandParams) => Promise<T>;
1477
- /**
1478
- * Builder for creating DynamoDB put operations.
1479
- *
1480
- * @example
1481
- * ```typescript
1482
- * // Add new dinosaur
1483
- * const result = await new PutBuilder(executor, {
1484
- * id: 'RAPTOR-001',
1485
- * species: 'Velociraptor',
1486
- * status: 'ACTIVE',
1487
- * stats: {
1488
- * health: 100,
1489
- * age: 5,
1490
- * threatLevel: 8
1491
- * }
1492
- * }, 'dinosaurs').execute();
1493
- *
1494
- * // Create new habitat with conditions
1495
- * const result = await new PutBuilder(executor, {
1496
- * id: 'PADDOCK-C',
1497
- * type: 'CARNIVORE',
1498
- * securityLevel: 'MAXIMUM',
1499
- * capacity: 3,
1500
- * environmentType: 'TROPICAL'
1501
- * }, 'habitats')
1502
- * .condition(op => op.attributeNotExists('id'))
1503
- * .execute();
1504
- * ```
1505
- *
1506
- * @typeParam T - The type of item being put into the table
1507
- */
1508
- declare class PutBuilder<T extends DynamoItem> {
1509
- private readonly item;
1510
- private options;
1511
- private readonly executor;
1512
- private readonly tableName;
1513
- constructor(executor: PutExecutor<T>, item: T, tableName: string);
1514
- /**
1515
- * Sets multiple attributes of an item using an DynamoItem.
1516
- *
1517
- * @example
1518
- * ```typescript
1519
- * // Update multiple attributes
1520
- * builder.set({
1521
- * species: 'Tyrannosaurus Rex',
1522
- * height: 20,
1523
- * diet: 'CARNIVORE',
1524
- * 'stats.threatLevel': 10
1525
- * });
1526
- * ```
1527
- */
1528
- set(values: Partial<T>): this;
1529
- /**
1530
- * Sets a single attribute to a specific value.
1531
- *
1532
- * @example
1533
- * ```typescript
1534
- * // Set simple attributes
1535
- * builder
1536
- * .set('status', 'SLEEPING')
1537
- * .set('lastFeeding', new Date().toISOString());
1538
- *
1539
- * // Set nested attributes
1540
- * builder
1541
- * .set('location.zone', 'RESTRICTED')
1542
- * .set('stats.health', 100);
1543
- * ```
1544
- */
1545
- set<K extends Path<T>>(path: K, value: PathType<T, K>): this;
1546
- /**
1547
- * Adds a condition that must be satisfied for the put operation to succeed.
1548
- *
1549
- * @example
1550
- * ```ts
1551
- * // Ensure item doesn't exist (insert only)
1552
- * builder.condition(op => op.attributeNotExists('id'))
1553
- *
1554
- * // Complex condition with version check
1555
- * builder.condition(op =>
1556
- * op.and([
1557
- * op.attributeExists('id'),
1558
- * op.eq('version', currentVersion),
1559
- * op.eq('status', 'ACTIVE')
1560
- * ])
1561
- * )
1562
- * ```
1563
- *
1564
- * @param condition - Either a Condition object or a callback function that builds the condition
1565
- * @returns The builder instance for method chaining
1566
- */
1567
- /**
1568
- * Adds a condition that must be satisfied for the put operation to succeed.
1569
- *
1570
- * @example
1571
- * ```typescript
1572
- * // Ensure unique dinosaur ID
1573
- * builder.condition(op =>
1574
- * op.attributeNotExists('id')
1575
- * );
1576
- *
1577
- * // Verify habitat requirements
1578
- * builder.condition(op =>
1579
- * op.and([
1580
- * op.eq('securityStatus', 'READY'),
1581
- * op.attributeExists('lastInspection'),
1582
- * op.gt('securityLevel', 5)
1583
- * ])
1584
- * );
1585
- *
1586
- * // Check breeding facility conditions
1587
- * builder.condition(op =>
1588
- * op.and([
1589
- * op.between('temperature', 25, 30),
1590
- * op.between('humidity', 60, 80),
1591
- * op.eq('quarantineStatus', 'CLEAR')
1592
- * ])
1593
- * );
1594
- * ```
1595
- *
1596
- * @param condition - Either a Condition object or a callback function that builds the condition
1597
- * @returns The builder instance for method chaining
1598
- */
1599
- condition(condition: Condition | ((op: ConditionOperator<T>) => Condition)): this;
1600
- /**
1601
- * Sets whether to return the item's previous values (if it existed).
1602
- *
1603
- * @options
1604
- * - NONE: No return value
1605
- * - ALL_OLD: Returns the item's previous state if it existed, no read capacity units are consumed
1606
- * - CONSISTENT: Performs a GET operation after the put to retrieve the item's new state
1607
- * - INPUT: Returns the input values that were passed to the operation
1608
- *
1609
- * @example
1610
- * ```ts
1611
- * // Get previous dinosaur state
1612
- * const result = await builder
1613
- * .returnValues('ALL_OLD')
1614
- * .execute();
1615
- *
1616
- * if (result) {
1617
- * console.log('Previous profile:', {
1618
- * species: result.species,
1619
- * status: result.status,
1620
- * stats: {
1621
- * health: result.stats.health,
1622
- * threatLevel: result.stats.threatLevel
1623
- * }
1624
- * });
1625
- * }
1626
- *
1627
- * // Return input values for create operations
1628
- * const createResult = await builder
1629
- * .returnValues('INPUT')
1630
- * .execute();
1631
- * ```
1632
- *
1633
- * @param returnValues - Use 'ALL_OLD' to return previous values, 'INPUT' to return input values, 'CONSISTENT' for fresh data, or 'NONE' (default).
1634
- * @returns The builder instance for method chaining
1635
- */
1636
- returnValues(returnValues: "ALL_OLD" | "NONE" | "CONSISTENT" | "INPUT"): this;
1637
- /**
1638
- * Generate the DynamoDB command parameters
1639
- */
1640
- private toDynamoCommand;
1641
- /**
1642
- * Adds this put operation to a transaction.
1643
- *
1644
- * @example
1645
- * ```ts
1646
- * const transaction = new TransactionBuilder();
1647
- *
1648
- * // Add dinosaur to new habitat
1649
- * new PutBuilder(executor, {
1650
- * id: 'TREX-002',
1651
- * location: 'PADDOCK-B',
1652
- * status: 'ACTIVE',
1653
- * transferDate: new Date().toISOString()
1654
- * }, 'dinosaurs')
1655
- * .withTransaction(transaction);
1656
- *
1657
- * // Update habitat records
1658
- * new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-B' })
1659
- * .add('occupants', 1)
1660
- * .set('lastTransfer', new Date().toISOString())
1661
- * .withTransaction(transaction);
1662
- *
1663
- * // Execute transfer atomically
1664
- * await transaction.execute();
1665
- * ```
1666
- *
1667
- * @param transaction - The transaction builder to add this operation to
1668
- * @returns The builder instance for method chaining
1669
- */
1670
- withTransaction(transaction: TransactionBuilder): this;
1671
- /**
1672
- * Adds this put operation to a batch with optional entity type information.
1673
- *
1674
- * @example Basic Usage
1675
- * ```ts
1676
- * const batch = table.batchBuilder();
1677
- *
1678
- * // Add multiple dinosaurs to batch
1679
- * dinosaurRepo.create(newDino1).withBatch(batch);
1680
- * dinosaurRepo.create(newDino2).withBatch(batch);
1681
- * dinosaurRepo.create(newDino3).withBatch(batch);
1682
- *
1683
- * // Execute all operations efficiently
1684
- * await batch.execute();
1685
- * ```
1686
- *
1687
- * @example Typed Usage
1688
- * ```ts
1689
- * const batch = table.batchBuilder<{
1690
- * User: UserEntity;
1691
- * Order: OrderEntity;
1692
- * }>();
1693
- *
1694
- * // Add operations with type information
1695
- * userRepo.create(newUser).withBatch(batch, 'User');
1696
- * orderRepo.create(newOrder).withBatch(batch, 'Order');
1697
- *
1698
- * // Execute and get typed results
1699
- * const result = await batch.execute();
1700
- * const users: UserEntity[] = result.reads.itemsByType.User;
1701
- * ```
1702
- *
1703
- * @param batch - The batch builder to add this operation to
1704
- * @param entityType - Optional entity type key for type tracking
1705
- */
1706
- withBatch<TEntities extends Record<string, DynamoItem> = Record<string, DynamoItem>, K extends keyof TEntities = keyof TEntities>(batch: BatchBuilder<TEntities>, entityType?: K): void;
1707
- /**
1708
- * Executes the put operation against DynamoDB.
1709
- *
1710
- * @example
1711
- * ```ts
1712
- * try {
1713
- * // Put with condition and return old values
1714
- * const result = await new PutBuilder(executor, newItem, 'myTable')
1715
- * .condition(op => op.eq('version', 1))
1716
- * .returnValues('ALL_OLD')
1717
- * .execute();
1718
- *
1719
- * console.log('Put successful, old item:', result);
1720
- * } catch (error) {
1721
- * // Handle condition check failure or other errors
1722
- * console.error('Put failed:', error);
1723
- * }
1724
- * ```
1725
- *
1726
- * @returns A promise that resolves to the operation result (type depends on returnValues setting)
1727
- * @throws Will throw an error if the condition check fails or other DynamoDB errors occur
1728
- */
1729
- execute(): Promise<T | undefined>;
1730
- /**
1731
- * Gets a human-readable representation of the put command
1732
- * with all expression placeholders replaced by their actual values.
1733
- *
1734
- * @example
1735
- * ```ts
1736
- * const debugInfo = new PutBuilder(executor, {
1737
- * id: 'RAPTOR-003',
1738
- * species: 'Velociraptor',
1739
- * status: 'QUARANTINE',
1740
- * stats: {
1741
- * health: 100,
1742
- * aggressionLevel: 7,
1743
- * age: 2
1744
- * }
1745
- * }, 'dinosaurs')
1746
- * .condition(op =>
1747
- * op.and([
1748
- * op.attributeNotExists('id'),
1749
- * op.eq('quarantineStatus', 'READY'),
1750
- * op.gt('securityLevel', 8)
1751
- * ])
1752
- * )
1753
- * .debug();
1754
- *
1755
- * console.log('Dinosaur transfer command:', debugInfo);
1756
- * ```
1757
- *
1758
- * @returns A readable representation of the put command with resolved expressions
1759
- */
1760
- debug(): {
1761
- raw: PutCommandParams;
1762
- readable: {
1763
- conditionExpression?: string;
1764
- updateExpression?: string;
1765
- filterExpression?: string;
1766
- keyConditionExpression?: string;
1767
- projectionExpression?: string;
1768
- };
1769
- };
1770
- }
1771
-
1772
- /**
1773
- * A utility class for handling DynamoDB pagination.
1774
- * Use this class when you need to:
1775
- * - Browse large collections of dinosaurs
1776
- * - Review extensive security logs
1777
- * - Analyze habitat inspection history
1778
- * - Process feeding schedules
1779
- *
1780
- * The paginator maintains internal state and automatically handles:
1781
- * - Page boundaries
1782
- * - Result set limits
1783
- * - Continuation tokens
1784
- *
1785
- * @example
1786
- * ```typescript
1787
- * // List all velociraptors with pagination
1788
- * const paginator = new QueryBuilder(executor, eq('species', 'Velociraptor'))
1789
- * .filter(op => op.eq('status', 'ACTIVE'))
1790
- * .paginate(10);
1791
- *
1792
- * // Process each page of dinosaurs
1793
- * while (paginator.hasNextPage()) {
1794
- * const page = await paginator.getNextPage();
1795
- * console.log(`Processing page ${page.page} of velociraptors`);
1796
- *
1797
- * for (const raptor of page.items) {
1798
- * console.log(`- ${raptor.id}: Health=${raptor.stats.health}`);
1799
- * }
1800
- * }
1801
- * ```
1802
- *
1803
- * @typeParam T - The type of items being paginated
1804
- * @typeParam TConfig - The table configuration type
1805
- */
1806
- declare class Paginator<T extends DynamoItem, TConfig extends TableConfig = TableConfig> {
1807
- private queryBuilder;
1808
- private readonly pageSize?;
1809
- private currentPage;
1810
- private lastEvaluatedKey?;
1811
- private hasMorePages;
1812
- private totalItemsRetrieved;
1813
- private readonly overallLimit?;
1814
- constructor(queryBuilder: QueryBuilderInterface<T, TConfig>, pageSize?: number);
1815
- /**
1816
- * Gets the current page number (1-indexed).
1817
- *
1818
- * @example
1819
- * ```ts
1820
- * const paginator = new QueryBuilder(executor, eq('species', 'Tyrannosaurus'))
1821
- * .paginate(5);
1822
- *
1823
- * await paginator.getNextPage();
1824
- * console.log(`Reviewing T-Rex group ${paginator.getCurrentPage()}`);
1825
- * ```
1826
- *
1827
- * @returns The current page number, starting from 1
1828
- */
1829
- getCurrentPage(): number;
1830
- /**
1831
- * Checks if there are more pages of dinosaurs or habitats to process.
1832
- *
1833
- * This method takes into account both:
1834
- * - DynamoDB's lastEvaluatedKey mechanism
1835
- * - Any overall limit set on the query
1836
- *
1837
- * @example
1838
- * ```ts
1839
- * // Process all security incidents
1840
- * const paginator = new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
1841
- * .sortDescending()
1842
- * .paginate(10);
1843
- *
1844
- * while (paginator.hasNextPage()) {
1845
- * const page = await paginator.getNextPage();
1846
- * for (const incident of page.items) {
1847
- * await processSecurityBreach(incident);
1848
- * }
1849
- * console.log(`Processed incidents page ${page.page}`);
1850
- * }
1851
- * ```
1852
- *
1853
- * @returns true if there are more pages available, false otherwise
1854
- */
1855
- hasNextPage(): boolean;
1856
- /**
1857
- * Retrieves the next page of dinosaurs or habitats from DynamoDB.
1858
- *
1859
- * This method handles:
1860
- * - Automatic continuation between groups
1861
- * - Respect for park capacity limits
1862
- * - Group size adjustments for safety
1863
- *
1864
- * @example
1865
- * ```ts
1866
- * const paginator = new QueryBuilder(executor, eq('species', 'Velociraptor'))
1867
- * .filter(op => op.eq('status', 'ACTIVE'))
1868
- * .paginate(5);
1869
- *
1870
- * // Check first raptor group
1871
- * const page1 = await paginator.getNextPage();
1872
- * console.log(`Found ${page1.items.length} active raptors`);
1873
- *
1874
- * // Continue inspection if more groups exist
1875
- * if (page1.hasNextPage) {
1876
- * const page2 = await paginator.getNextPage();
1877
- * console.log(`Inspecting raptor group ${page2.page}`);
1878
- *
1879
- * for (const raptor of page2.items) {
1880
- * await performHealthCheck(raptor);
1881
- * }
1882
- * }
1883
- * ```
1884
- *
1885
- * @returns A promise that resolves to a PaginationResult containing:
1886
- * - items: The dinosaurs/habitats for this page
1887
- * - hasNextPage: Whether more groups exist
1888
- * - page: The current group number
1889
- * - lastEvaluatedKey: DynamoDB's continuation token
1890
- */
1891
- getNextPage(): Promise<PaginationResult<T>>;
1892
- /**
1893
- * Gets all remaining dinosaurs or habitats and combines them into a single array.
1894
- *
1895
- * @example
1896
- * ```ts
1897
- * // Get complete carnivore inventory
1898
- * const paginator = new QueryBuilder(executor, eq('diet', 'CARNIVORE'))
1899
- * .filter(op => op.eq('status', 'ACTIVE'))
1900
- * .paginate(10);
1901
- *
1902
- * try {
1903
- * const allCarnivores = await paginator.getAllPages();
1904
- * console.log(`Park contains ${allCarnivores.length} active carnivores`);
1905
- *
1906
- * // Calculate total threat level
1907
- * const totalThreat = allCarnivores.reduce(
1908
- * (sum, dino) => sum + dino.stats.threatLevel,
1909
- * 0
1910
- * );
1911
- * console.log(`Total threat level: ${totalThreat}`);
1912
- * } catch (error) {
1913
- * console.error('Failed to complete carnivore census:', error);
1914
- * }
1915
- * ```
1916
- *
1917
- * @returns A promise that resolves to an array containing all remaining items
1918
- */
1919
- getAllPages(): Promise<T[]>;
1920
- }
1921
-
1922
- /**
1923
- * Configuration options for DynamoDB filter operations.
1924
- * These are common options shared between query and scan operations.
1925
- */
1926
- interface FilterOptions {
1927
- /** Filter conditions applied to results */
1928
- filter?: Condition;
1929
- /** Maximum number of items to return */
1930
- limit?: number;
1931
- /** Name of the Global Secondary Index to use */
1932
- indexName?: string;
1933
- /** Whether to use strongly consistent reads */
1934
- consistentRead?: boolean;
1935
- /** List of attributes to return in the result */
1936
- projection?: string[];
1937
- /** Token for starting the operation from a specific point */
1938
- lastEvaluatedKey?: DynamoItem;
1939
- }
1940
- /**
1941
- * Abstract base builder for creating DynamoDB filter operations.
1942
- * This class provides common functionality for both Query and Scan operations.
1943
- *
1944
- * The builder supports:
1945
- * - Type-safe GSI selection
1946
- * - Complex filter conditions
1947
- * - Pagination
1948
- * - Consistent reads
1949
- * - Attribute projection
1950
- *
1951
- * @typeParam T - The type of items being filtered
1952
- * @typeParam TConfig - The table configuration type for type-safe GSI selection
1953
- */
1954
- declare abstract class FilterBuilder<T extends DynamoItem, TConfig extends TableConfig = TableConfig> implements FilterBuilderInterface<T, TConfig> {
1955
- protected options: FilterOptions;
1956
- protected selectedFields: Set<string>;
1957
- /**
1958
- * Sets the maximum number of items to return.
1959
- *
1960
- * Note: This limit applies to the items that match the key condition
1961
- * before any filter expressions are applied.
1962
- *
1963
- * @example
1964
- * ```typescript
1965
- * // Get first 10 dinosaurs
1966
- * const result = await builder
1967
- * .limit(10)
1968
- * .execute();
1969
- * ```
1970
- *
1971
- * @param limit - Maximum number of items to return
1972
- * @returns The builder instance for method chaining
1973
- */
1974
- limit(limit: number): this;
1975
- /**
1976
- * Gets the current limit set on the operation.
1977
- * This is used internally by the paginator to manage result sets.
1978
- *
1979
- * @returns The current limit or undefined if no limit is set
1980
- */
1981
- getLimit(): number | undefined;
1982
- /**
1983
- * Specifies a Global Secondary Index (GSI) to use for the operation.
1984
- *
1985
- * @example
1986
- * ```typescript
1987
- * // Find all dinosaurs of a specific species
1988
- * builder
1989
- * .useIndex('species-status-index')
1990
- * .filter(op => op.eq('status', 'ACTIVE'));
1991
- *
1992
- * // Search high-security habitats
1993
- * builder
1994
- * .useIndex('security-level-index')
1995
- * .filter(op =>
1996
- * op.and([
1997
- * op.gt('securityLevel', 8),
1998
- * op.eq('status', 'OPERATIONAL')
1999
- * ])
2000
- * );
2001
- * ```
2002
- *
2003
- * @param indexName - The name of the GSI to use (type-safe based on table configuration)
2004
- * @returns The builder instance for method chaining
2005
- */
2006
- useIndex<I extends GSINames<TConfig>>(indexName: I): this;
2007
- /**
2008
- * Sets whether to use strongly consistent reads for the operation.
2009
- *
2010
- * Note:
2011
- * - Consistent reads are not available on GSIs
2012
- * - Consistent reads consume twice the throughput
2013
- * - Default is eventually consistent reads
2014
- *
2015
- * @example
2016
- * ```typescript
2017
- * // Check immediate dinosaur status
2018
- * const result = await builder
2019
- * .filter(op => op.eq('status', 'ACTIVE'))
2020
- * .consistentRead()
2021
- * .execute();
2022
- *
2023
- * // Monitor security breaches
2024
- * const result = await builder
2025
- * .useIndex('primary-index')
2026
- * .consistentRead(isEmergencyMode)
2027
- * .execute();
2028
- * ```
2029
- *
2030
- * @param consistentRead - Whether to use consistent reads (defaults to true)
2031
- * @returns The builder instance for method chaining
2032
- */
2033
- consistentRead(consistentRead?: boolean): this;
2034
- /**
2035
- * Adds a filter expression to refine the operation results.
2036
- *
2037
- * @example
2038
- * ```typescript
2039
- * // Find aggressive carnivores
2040
- * builder.filter(op =>
2041
- * op.and([
2042
- * op.eq('diet', 'CARNIVORE'),
2043
- * op.gt('aggressionLevel', 7),
2044
- * op.eq('status', 'ACTIVE')
2045
- * ])
2046
- * );
2047
- *
2048
- * // Search suitable breeding habitats
2049
- * builder.filter(op =>
2050
- * op.and([
2051
- * op.between('temperature', 25, 30),
2052
- * op.lt('currentOccupants', 3),
2053
- * op.eq('quarantineStatus', 'CLEAR')
2054
- * ])
2055
- * );
2056
- * ```
2057
- *
2058
- * @param condition - Either a Condition object or a callback function that builds the condition
2059
- * @returns The builder instance for method chaining
2060
- */
2061
- filter(condition: Condition | ((op: ConditionOperator<T>) => Condition)): this;
2062
- private getConditionOperator;
2063
- /**
2064
- * Specifies which attributes to return in the results.
2065
- *
2066
- * @example
2067
- * ```typescript
2068
- * // Get basic dinosaur info
2069
- * builder.select([
2070
- * 'species',
2071
- * 'status',
2072
- * 'stats.health',
2073
- * 'stats.aggressionLevel'
2074
- * ]);
2075
- *
2076
- * // Monitor habitat conditions
2077
- * builder
2078
- * .select('securityStatus')
2079
- * .select([
2080
- * 'currentOccupants',
2081
- * 'temperature',
2082
- * 'lastInspectionDate'
2083
- * ]);
2084
- * ```
2085
- *
2086
- * @param fields - A single field name or an array of field names to return
2087
- * @returns The builder instance for method chaining
2088
- */
2089
- select<K extends Path<T>>(fields: K | K[]): this;
2090
- /**
2091
- * Creates a paginator that handles DynamoDB pagination automatically.
2092
- * The paginator handles:
2093
- * - Tracking the last evaluated key
2094
- * - Managing page boundaries
2095
- * - Respecting overall query limits
2096
- *
2097
- * @example
2098
- * ```typescript
2099
- * // Create a paginator for dinosaur records with specific page size
2100
- * const paginator = builder
2101
- * .filter(op => op.eq('status', 'ACTIVE'))
2102
- * .paginate(10);
2103
- *
2104
- * // Create a paginator with automatic DynamoDB paging (no page size limit)
2105
- * const autoPaginator = builder
2106
- * .filter(op => op.eq('status', 'ACTIVE'))
2107
- * .paginate();
2108
- *
2109
- * // Process pages of dinosaur results
2110
- * while (paginator.hasNextPage()) {
2111
- * const page = await paginator.getNextPage();
2112
- * console.log(`Processing page ${page.page}, count: ${page.items.length}`);
2113
- * // Process dinosaur data
2114
- * }
2115
- * ```
2116
- *
2117
- * @param pageSize - The number of items to return per page. If not provided, DynamoDB will automatically determine page sizes.
2118
- * @returns A Paginator instance that manages the pagination state
2119
- * @see Paginator for more pagination control options
2120
- */
2121
- paginate(pageSize?: number): Paginator<T, TConfig>;
2122
- /**
2123
- * Sets the starting point using a previous lastEvaluatedKey.
2124
- *
2125
- * Note: This method is typically used for manual pagination.
2126
- * For automatic pagination, use the paginate() method instead.
2127
- *
2128
- * @example
2129
- * ```typescript
2130
- * // First batch of dinosaurs
2131
- * const result1 = await builder
2132
- * .filter(op => op.eq('status', 'ACTIVE'))
2133
- * .limit(5)
2134
- * .execute();
2135
- *
2136
- * const lastKey = result1.getLastEvaluatedKey();
2137
- * if (lastKey) {
2138
- * // Continue listing dinosaurs
2139
- * const result2 = await builder
2140
- * .filter(op => op.eq('status', 'ACTIVE'))
2141
- * .startFrom(lastKey)
2142
- * .limit(5)
2143
- * .execute();
2144
- *
2145
- * const items = await result2.toArray();
2146
- * console.log('Additional dinosaurs:', items);
2147
- * }
2148
- * ```
2149
- *
2150
- * @param lastEvaluatedKey - The exclusive start key from a previous result
2151
- * @returns The builder instance for method chaining
2152
- */
2153
- startFrom(lastEvaluatedKey: DynamoItem): this;
2154
- /**
2155
- * Creates a deep clone of this builder instance.
2156
- *
2157
- * This is particularly useful when:
2158
- * - Implementing pagination (used internally by paginate())
2159
- * - Creating operation templates
2160
- * - Running multiple variations of an operation
2161
- *
2162
- * @example
2163
- * ```typescript
2164
- * // Create base dinosaur query
2165
- * const baseBuilder = builder
2166
- * .useIndex('status-index')
2167
- * .select(['id', 'status', 'location']);
2168
- *
2169
- * // Check active dinosaurs
2170
- * const activeRaptors = baseBuilder.clone()
2171
- * .filter(op => op.eq('status', 'HUNTING'))
2172
- * .execute();
2173
- *
2174
- * // Check contained dinosaurs
2175
- * const containedRaptors = baseBuilder.clone()
2176
- * .filter(op => op.eq('status', 'CONTAINED'))
2177
- * .execute();
2178
- * ```
2179
- *
2180
- * @returns A new builder instance with the same configuration
2181
- */
2182
- abstract clone(): FilterBuilderInterface<T, TConfig>;
2183
- /**
2184
- * Executes the operation against DynamoDB and returns a generator that behaves like an array.
2185
- * This method must be implemented by subclasses to handle
2186
- * their specific execution logic.
2187
- */
2188
- abstract execute(): Promise<ResultIterator<T, TConfig>>;
2189
- /**
2190
- * Executes the operation and returns the first matching item, if any.
2191
- *
2192
- * This helper:
2193
- * - Applies an internal limit of 1
2194
- * - Streams results until a match is found or there are no more pages
2195
- * - Avoids mutating the current builder by using a clone
2196
- *
2197
- * @example
2198
- * ```typescript
2199
- * const latest = await table
2200
- * .query(eq("moduleId", moduleId))
2201
- * .useIndex("module-version-index")
2202
- * .sortDescending()
2203
- * .findOne();
2204
- * ```
2205
- *
2206
- * @returns The first matching item, or undefined if none found
2207
- */
2208
- findOne(): Promise<T | undefined>;
2209
- }
2210
-
2211
- /**
2212
- * Configuration options for DynamoDB query operations.
2213
- * Extends the base FilterOptions with query-specific options.
2214
- */
2215
- interface QueryOptions extends FilterOptions {
2216
- /** Condition for the sort key in the table or index */
2217
- sortKeyCondition?: Condition;
2218
- /** Direction of sort key traversal (true for ascending, false for descending) */
2219
- scanIndexForward?: boolean;
2220
- }
2221
- /**
2222
- * Function type for executing DynamoDB query operations.
2223
- * @typeParam T - The type of items being queried
2224
- */
2225
- type QueryExecutor<T extends DynamoItem> = (keyCondition: Condition, options: QueryOptions) => Promise<{
2226
- items: T[];
2227
- lastEvaluatedKey?: Record<string, unknown>;
2228
- }>;
2229
- /**
2230
- * Builder for creating DynamoDB query operations.
2231
- *
2232
- * The builder supports:
2233
- * - Type-safe GSI selection
2234
- * - Complex filter conditions
2235
- * - Automatic pagination handling
2236
- * - Consistent reads
2237
- * - Forward and reverse sorting
2238
- *
2239
- * @example
2240
- * ```typescript
2241
- * // Simple query
2242
- * const result = await new QueryBuilder(executor, eq('userId', '123'))
2243
- * .execute();
2244
- *
2245
- * // Complex query with GSI and filtering
2246
- * const result = await new QueryBuilder(executor, eq('status', 'ACTIVE'))
2247
- * .useIndex('status-index')
2248
- * .filter(op => op.beginsWith('name', 'John'))
2249
- * .select(['id', 'name', 'email'])
2250
- * .sortDescending()
2251
- * .limit(10)
2252
- * .execute();
2253
- *
2254
- * // Query with pagination
2255
- * const paginator = new QueryBuilder(executor, eq('type', 'order'))
2256
- * .paginate(25);
2257
- *
2258
- * while (paginator.hasNextPage()) {
2259
- * const page = await paginator.getNextPage();
2260
- * // Process page.items
2261
- * }
2262
- * ```
2263
- *
2264
- * @typeParam T - The type of items being queried
2265
- * @typeParam TConfig - The table configuration type for type-safe GSI selection
2266
- */
2267
- declare class QueryBuilder<T extends DynamoItem, TConfig extends TableConfig = TableConfig> extends FilterBuilder<T, TConfig> implements QueryBuilderInterface<T, TConfig> {
2268
- private readonly keyCondition;
2269
- protected options: QueryOptions;
2270
- protected readonly executor: QueryExecutor<T>;
2271
- private includeIndexAttributes;
2272
- private readonly indexAttributeNames;
2273
- constructor(executor: QueryExecutor<T>, keyCondition: Condition, indexAttributeNames?: string[]);
2274
- /**
2275
- * Sets the maximum number of items to return from the query.
2276
- *
2277
- * Note: This is the default behavior if no sort order is specified.
2278
- *
2279
- * @example
2280
- * ```typescript
2281
- * // Get orders in chronological order
2282
- * const result = await new QueryBuilder(executor, eq('userId', '123'))
2283
- * .sortAscending()
2284
- * .execute();
2285
- *
2286
- * // Get events from oldest to newest
2287
- * const result = await new QueryBuilder(executor, eq('entityId', 'order-123'))
2288
- * .useIndex('entity-timestamp-index')
2289
- * .sortAscending()
2290
- * .execute();
2291
- * ```
2292
- *
2293
- * @returns The builder instance for method chaining
2294
- */
2295
- /**
2296
- * Sets the query to return items in ascending order by sort key.
2297
- *
2298
- * @example
2299
- * ```typescript
2300
- * // List dinosaurs by age
2301
- * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
2302
- * .useIndex('age-index')
2303
- * .sortAscending()
2304
- * .execute();
2305
- *
2306
- * // View incidents chronologically
2307
- * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
2308
- * .useIndex('date-index')
2309
- * .sortAscending()
2310
- * .execute();
2311
- * ```
2312
- *
2313
- * @returns The builder instance for method chaining
2314
- */
2315
- sortAscending(): this;
2316
- /**
2317
- * Sets the query to return items in descending order by sort key.
2318
- *
2319
- * @example
2320
- * ```typescript
2321
- * // Get most recent security incidents
2322
- * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
2323
- * .useIndex('date-index')
2324
- * .sortDescending()
2325
- * .limit(10)
2326
- * .execute();
2327
- *
2328
- * // Check latest dinosaur activities
2329
- * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
2330
- * .useIndex('activity-time-index')
2331
- * .filter(op => op.eq('status', 'ACTIVE'))
2332
- * .sortDescending()
2333
- * .execute();
2334
- * ```
2335
- *
2336
- * @returns The builder instance for method chaining
2337
- */
2338
- sortDescending(): this;
2339
- /**
2340
- * Ensures index attributes are included in the result.
2341
- * By default, index attributes are removed from query responses.
2342
- */
2343
- includeIndexes(): this;
2344
- select<K extends Path<T>>(fields: K | K[]): this;
2345
- /**
2346
- * Creates a deep clone of this QueryBuilder instance.
2347
- *
2348
- * This is particularly useful when:
2349
- * - Implementing pagination (used internally by paginate())
2350
- * - Creating query templates
2351
- * - Running multiple variations of a query
2352
- *
2353
- * @example
2354
- * ```typescript
2355
- * // Create base dinosaur query
2356
- * const baseQuery = new QueryBuilder(executor, eq('species', 'Velociraptor'))
2357
- * .useIndex('status-index')
2358
- * .select(['id', 'status', 'location']);
2359
- *
2360
- * // Check active dinosaurs
2361
- * const activeRaptors = baseQuery.clone()
2362
- * .filter(op => op.eq('status', 'HUNTING'))
2363
- * .execute();
2364
- *
2365
- * // Check contained dinosaurs
2366
- * const containedRaptors = baseQuery.clone()
2367
- * .filter(op => op.eq('status', 'CONTAINED'))
2368
- * .execute();
2369
- *
2370
- * // Check sedated dinosaurs
2371
- * const sedatedRaptors = baseQuery.clone()
2372
- * .filter(op => op.eq('status', 'SEDATED'))
2373
- * .execute();
2374
- * ```
2375
- *
2376
- * @returns A new QueryBuilder instance with the same configuration
2377
- */
2378
- clone(): QueryBuilder<T, TConfig>;
2379
- private deepCloneFilter;
2380
- /**
2381
- * Executes the query against DynamoDB and returns a generator that behaves like an array.
2382
- *
2383
- * The generator automatically handles pagination and provides array-like methods
2384
- * for processing results efficiently without loading everything into memory at once.
2385
- *
2386
- * @example
2387
- * ```typescript
2388
- * try {
2389
- * // Find active carnivores with automatic pagination
2390
- * const results = await new QueryBuilder(executor, eq('habitatId', 'PADDOCK-A'))
2391
- * .useIndex('species-status-index')
2392
- * .filter(op =>
2393
- * op.and([
2394
- * op.eq('diet', 'CARNIVORE'),
2395
- * op.eq('status', 'ACTIVE'),
2396
- * op.gt('aggressionLevel', 7)
2397
- * ])
2398
- * )
2399
- * .sortDescending()
2400
- * .execute();
2401
- *
2402
- * // Use like an array with automatic pagination
2403
- * for await (const dinosaur of results) {
2404
- * console.log(`Processing ${dinosaur.name}`);
2405
- * }
2406
- *
2407
- * // Or convert to array and use array methods
2408
- * const allItems = await results.toArray();
2409
- * const dangerousOnes = allItems.filter(dino => dino.aggressionLevel > 9);
2410
- * const totalCount = allItems.length;
2411
- * } catch (error) {
2412
- * console.error('Security scan failed:', error);
2413
- * }
2414
- * ```
2415
- *
2416
- * @returns A promise that resolves to a ResultGenerator that behaves like an array
2417
- */
2418
- execute(): Promise<ResultIterator<T, TConfig>>;
2419
- private addIndexAttributesToSelection;
2420
- private omitIndexAttributes;
2421
- }
2422
-
2423
- /**
2424
- * Configuration options for DynamoDB update operations.
2425
- */
2426
- interface UpdateOptions {
2427
- /** Optional condition that must be satisfied for the update to succeed */
2428
- condition?: Condition;
2429
- /** Determines which item attributes to include in the response */
2430
- returnValues?: "ALL_NEW" | "UPDATED_NEW" | "ALL_OLD" | "UPDATED_OLD" | "NONE";
2431
- }
2432
- /**
2433
- * Function type for executing DynamoDB update operations.
2434
- * @typeParam T - The type of the item being updated
2435
- */
2436
- type UpdateExecutor<T extends DynamoItem> = (params: UpdateCommandParams) => Promise<{
2437
- item?: T;
2438
- }>;
2439
- /**
2440
- * Represents a single update action within an update operation.
2441
- * Each action modifies the item in a specific way:
2442
- * - SET: Modify or add attributes
2443
- * - REMOVE: Delete attributes
2444
- * - ADD: Update numbers and sets
2445
- * - DELETE: Remove elements from a set
2446
- */
2447
- type UpdateAction = {
2448
- /** The type of update action */
2449
- type: "SET" | "REMOVE" | "ADD" | "DELETE";
2450
- /** The attribute path to update */
2451
- path: string;
2452
- /** The value to use in the update (not used for REMOVE actions) */
2453
- value?: unknown;
2454
- };
2455
- /**
2456
- * Type utility to get the element type of a set.
2457
- * Extracts the element type from either a Set or Array type.
2458
- * @typeParam T - The set or array type
2459
- */
2460
- type SetElementType<T> = T extends Set<infer U> ? U : T extends Array<infer U> ? U : never;
2461
- /**
2462
- * Type utility to get the element type from a path that points to a set.
2463
- * Combines PathType and SetElementType to get the element type at a specific path.
2464
- * @typeParam T - The type of the item
2465
- * @typeParam K - The path within the item
2466
- */
2467
- type PathSetElementType<T, K extends Path<T>> = SetElementType<PathType<T, K>>;
2468
- /**
2469
- * Builder for creating DynamoDB update operations.
2470
- *
2471
- * The builder supports all DynamoDB update operations:
2472
- * - SET: Modify or add attributes
2473
- * - REMOVE: Delete attributes
2474
- * - ADD: Update numbers and sets
2475
- * - DELETE: Remove elements from a set
2476
- *
2477
- * @example
2478
- * ```typescript
2479
- * // Simple update
2480
- * const result = await new UpdateBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
2481
- * .set('status', 'HUNTING')
2482
- * .set('lastFed', new Date().toISOString())
2483
- * .execute();
2484
- *
2485
- * // Complex update with multiple operations
2486
- * const result = await new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
2487
- * .set({
2488
- * status: 'OCCUPIED',
2489
- * occupants: 3,
2490
- * 'metadata.lastInspection': new Date().toISOString()
2491
- * })
2492
- * .add('securityBreaches', 1)
2493
- * .deleteElementsFromSet('suitableDinosaurs', ['VELOCIRAPTOR'])
2494
- * .condition(op => op.gt('securityLevel', 8))
2495
- * .returnValues('ALL_NEW')
2496
- * .execute();
2497
- * ```
2498
- *
2499
- * @typeParam T - The type of item being updated
2500
- */
2501
- declare class UpdateBuilder<T extends DynamoItem> {
2502
- protected updates: UpdateAction[];
2503
- protected options: UpdateOptions;
2504
- protected readonly executor: UpdateExecutor<T>;
2505
- protected readonly tableName: string;
2506
- protected readonly key: PrimaryKeyWithoutExpression;
2507
- constructor(executor: UpdateExecutor<T>, tableName: string, key: PrimaryKeyWithoutExpression);
2508
- /**
2509
- * Sets multiple attributes of an item using an object.
2510
- *
2511
- * @example
2512
- * ```typescript
2513
- * // Update multiple attributes
2514
- * builder.set({
2515
- * species: 'Tyrannosaurus Rex',
2516
- * height: 20,
2517
- * diet: 'CARNIVORE',
2518
- * 'stats.threatLevel': 10
2519
- * });
2520
- * ```
2521
- */
2522
- set(values: Partial<T>): UpdateBuilder<T>;
2523
- /**
2524
- * Sets a single attribute to a specific value.
2525
- *
2526
- * @example
2527
- * ```typescript
2528
- * // Set simple attributes
2529
- * builder
2530
- * .set('status', 'SLEEPING')
2531
- * .set('lastFeeding', new Date().toISOString());
2532
- *
2533
- * // Set nested attributes
2534
- * builder
2535
- * .set('location.zone', 'RESTRICTED')
2536
- * .set('stats.health', 100);
2537
- * ```
2538
- */
2539
- set<K extends Path<T>>(path: K, value: PathType<T, K>): UpdateBuilder<T>;
2540
- /**
2541
- * Removes an attribute from the item.
2542
- *
2543
- * @example
2544
- * ```typescript
2545
- * // Remove simple attributes
2546
- * builder
2547
- * .remove('temporaryTag')
2548
- * .remove('previousLocation');
2549
- *
2550
- * // Remove nested attributes
2551
- * builder
2552
- * .remove('metadata.testData')
2553
- * .remove('stats.experimentalMetrics');
2554
- * ```
2555
- *
2556
- * @param path - The path to the attribute to remove
2557
- * @returns The builder instance for method chaining
2558
- */
2559
- remove<K extends Path<T>>(path: K): this;
2560
- /**
2561
- * Adds a value to a number attribute or adds elements to a set.
2562
- *
2563
- * @example
2564
- * ```typescript
2565
- * // Increment counters
2566
- * builder
2567
- * .add('escapeAttempts', 1)
2568
- * .add('feedingCount', 1);
2569
- *
2570
- * // Add to sets
2571
- * builder
2572
- * .add('knownBehaviors', new Set(['PACK_HUNTING', 'AMBUSH_TACTICS']))
2573
- * .add('visitedZones', new Set(['ZONE_A', 'ZONE_B']));
2574
- * ```
2575
- *
2576
- * @param path - The path to the attribute to update
2577
- * @param value - The value to add (number or set)
2578
- * @returns The builder instance for method chaining
2579
- */
2580
- add<K extends Path<T>>(path: K, value: PathType<T, K>): this;
2581
- /**
2582
- * Removes elements from a set attribute.
2583
- *
2584
- * @example
2585
- * ```typescript
2586
- * // Remove from sets using arrays
2587
- * builder.deleteElementsFromSet(
2588
- * 'allowedHabitats',
2589
- * ['JUNGLE', 'COASTAL']
2590
- * );
2591
- *
2592
- * // Remove from sets using Set DynamoItems
2593
- * builder.deleteElementsFromSet(
2594
- * 'knownBehaviors',
2595
- * new Set(['NOCTURNAL', 'TERRITORIAL'])
2596
- * );
2597
- *
2598
- * // Remove from nested sets
2599
- * builder.deleteElementsFromSet(
2600
- * 'stats.compatibleSpecies',
2601
- * ['VELOCIRAPTOR', 'DILOPHOSAURUS']
2602
- * );
2603
- * ```
2604
- *
2605
- * @param path - The path to the set attribute
2606
- * @param value - Elements to remove (array or Set)
2607
- * @returns The builder instance for method chaining
2608
- */
2609
- deleteElementsFromSet<K extends Path<T>>(path: K, value: PathSetElementType<T, K>[] | Set<PathSetElementType<T, K>>): this;
2610
- /**
2611
- * Adds a condition that must be satisfied for the update to succeed.
2612
- *
2613
- * @example
2614
- * ```typescript
2615
- * // Simple condition
2616
- * builder.condition(op =>
2617
- * op.eq('status', 'ACTIVE')
2618
- * );
2619
- *
2620
- * // Health check condition
2621
- * builder.condition(op =>
2622
- * op.and([
2623
- * op.gt('health', 50),
2624
- * op.eq('status', 'HUNTING')
2625
- * ])
2626
- * );
2627
- *
2628
- * // Complex security condition
2629
- * builder.condition(op =>
2630
- * op.and([
2631
- * op.attributeExists('securitySystem'),
2632
- * op.eq('containmentStatus', 'SECURE'),
2633
- * op.lt('aggressionLevel', 8)
2634
- * ])
2635
- * );
2636
- *
2637
- * // Version check (optimistic locking)
2638
- * builder.condition(op =>
2639
- * op.eq('version', currentVersion)
2640
- * );
2641
- * ```
2642
- *
2643
- * @param condition - Either a Condition DynamoItem or a callback function that builds the condition
2644
- * @returns The builder instance for method chaining
2645
- */
2646
- condition(condition: Condition | ((op: ConditionOperator<T>) => Condition)): this;
2647
- /**
2648
- * Sets which item attributes to include in the response.
2649
- *
2650
- * Available options:
2651
- * - ALL_NEW: All attributes after the update (default)
2652
- * - UPDATED_NEW: Only updated attributes, new values
2653
- * - ALL_OLD: All attributes before the update
2654
- * - UPDATED_OLD: Only updated attributes, old values
2655
- * - NONE: No attributes returned
2656
- *
2657
- * @example
2658
- * ```typescript
2659
- * // Get complete updated dinosaur
2660
- * const result = await builder
2661
- * .set('status', 'SLEEPING')
2662
- * .returnValues('ALL_NEW')
2663
- * .execute();
2664
- *
2665
- * // Track specific attribute changes
2666
- * const result = await builder
2667
- * .set({
2668
- * 'stats.health': 100,
2669
- * 'stats.energy': 95
2670
- * })
2671
- * .returnValues('UPDATED_OLD')
2672
- * .execute();
2673
- *
2674
- * if (result.item) {
2675
- * console.log('Previous health:', result.item.stats?.health);
2676
- * }
2677
- * ```
2678
- *
2679
- * @param returnValues - Which attributes to return in the response
2680
- * @returns The builder instance for method chaining
2681
- */
2682
- returnValues(returnValues: "ALL_NEW" | "UPDATED_NEW" | "ALL_OLD" | "UPDATED_OLD" | "NONE"): this;
2683
- /**
2684
- * Generate the DynamoDB command parameters
2685
- */
2686
- toDynamoCommand(): UpdateCommandParams;
2687
- /**
2688
- * Adds this update operation to a transaction.
2689
- *
2690
- * @example
2691
- * ```typescript
2692
- * const transaction = new TransactionBuilder(executor);
2693
- *
2694
- * // Update dinosaur status and habitat occupancy atomically
2695
- * new UpdateBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
2696
- * .set('location', 'PADDOCK_A')
2697
- * .set('status', 'CONTAINED')
2698
- * .withTransaction(transaction);
2699
- *
2700
- * new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
2701
- * .add('occupants', 1)
2702
- * .set('lastOccupied', new Date().toISOString())
2703
- * .withTransaction(transaction);
2704
- *
2705
- * // Execute all operations atomically
2706
- * await transaction.execute();
2707
- * ```
2708
- *
2709
- * @param transaction - The transaction builder to add this operation to
2710
- * @returns The builder instance for method chaining
2711
- */
2712
- withTransaction(transaction: TransactionBuilder): void;
2713
- /**
2714
- * Gets a human-readable representation of the update command.
2715
- *
2716
- * @example
2717
- * ```typescript
2718
- * // Create complex update
2719
- * const builder = new UpdateBuilder(executor, 'dinosaurs', { id: 'RAPTOR-001' })
2720
- * .set({
2721
- * status: 'HUNTING',
2722
- * 'stats.health': 95,
2723
- * 'behavior.lastObserved': new Date().toISOString()
2724
- * })
2725
- * .add('huntingSuccesses', 1)
2726
- * .condition(op => op.gt('health', 50));
2727
- *
2728
- * // Debug the update
2729
- * const debugInfo = builder.debug();
2730
- * console.log('Update operation:', debugInfo);
2731
- * ```
2732
- *
2733
- * @returns A readable representation of the update command with resolved expressions
2734
- */
2735
- debug(): {
2736
- raw: UpdateCommandParams;
2737
- readable: {
2738
- conditionExpression?: string;
2739
- updateExpression?: string;
2740
- filterExpression?: string;
2741
- keyConditionExpression?: string;
2742
- projectionExpression?: string;
2743
- };
2744
- };
2745
- /**
2746
- * Executes the update operation against DynamoDB.
2747
- *
2748
- * @example
2749
- * ```typescript
2750
- * try {
2751
- * // Update dinosaur status with conditions
2752
- * const result = await new UpdateBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
2753
- * .set({
2754
- * status: 'FEEDING',
2755
- * lastMeal: new Date().toISOString(),
2756
- * 'stats.hunger': 0
2757
- * })
2758
- * .add('feedingCount', 1)
2759
- * .condition(op =>
2760
- * op.and([
2761
- * op.gt('stats.hunger', 80),
2762
- * op.eq('status', 'HUNTING')
2763
- * ])
2764
- * )
2765
- * .returnValues('ALL_NEW')
2766
- * .execute();
2767
- *
2768
- * if (result.item) {
2769
- * console.log('Updated dinosaur:', result.item);
2770
- * }
2771
- * } catch (error) {
2772
- * // Handle condition check failure
2773
- * console.error('Failed to update dinosaur:', error);
2774
- * // Check if dinosaur wasn't hungry enough
2775
- * if (error.name === 'ConditionalCheckFailedException') {
2776
- * console.log('Dinosaur not ready for feeding');
2777
- * }
2778
- * }
2779
- * ```
2780
- *
2781
- * @returns A promise that resolves to an DynamoItem containing the updated item (if returnValues is set)
2782
- * @throws {ConditionalCheckFailedException} If the condition check fails
2783
- * @throws {Error} If the update operation fails for other reasons
2784
- */
2785
- execute(): Promise<{
2786
- item?: T;
2787
- }>;
2788
- }
2789
-
2790
- /**
2791
- * Builder for creating DynamoDB condition check operations.
2792
- * Use this builder when you need to:
2793
- * - Verify item state without modifying it
2794
- * - Ensure preconditions in transactions
2795
- * - Implement optimistic locking patterns
2796
- * - Validate business rules
2797
- *
2798
- * @example
2799
- * ```typescript
2800
- * // Check if dinosaur is ready for feeding
2801
- * const check = new ConditionCheckBuilder('dinosaurs', { id: 'TREX-001' })
2802
- * .condition(op =>
2803
- * op.and([
2804
- * op.eq('status', 'HUNTING'),
2805
- * op.gt('stats.hunger', 80),
2806
- * op.lt('stats.health', 100)
2807
- * ])
2808
- * )
2809
- * .toDynamoCommand();
2810
- *
2811
- * // Check habitat security status
2812
- * const securityCheck = new ConditionCheckBuilder('habitats', { id: 'PADDOCK-A' })
2813
- * .condition(op =>
2814
- * op.and([
2815
- * op.eq('securityStatus', 'ACTIVE'),
2816
- * op.attributeExists('lastInspection'),
2817
- * op.lt('threatLevel', 5)
2818
- * ])
2819
- * )
2820
- * .toDynamoCommand();
2821
- * ```
2822
- */
2823
- declare class ConditionCheckBuilder {
2824
- private readonly key;
2825
- private readonly tableName;
2826
- private conditionExpression?;
2827
- constructor(tableName: string, key: PrimaryKeyWithoutExpression);
2828
- /**
2829
- * Adds a condition that must be satisfied for the check to succeed.
2830
- *
2831
- * @example
2832
- * ```typescript
2833
- * // Check dinosaur health and behavior
2834
- * builder.condition(op =>
2835
- * op.and([
2836
- * op.gt('stats.health', 50),
2837
- * op.not(op.eq('status', 'SEDATED')),
2838
- * op.lt('aggressionLevel', 8)
2839
- * ])
2840
- * );
2841
- *
2842
- * // Verify habitat conditions
2843
- * builder.condition(op =>
2844
- * op.and([
2845
- * op.eq('powerStatus', 'ONLINE'),
2846
- * op.between('temperature', 20, 30),
2847
- * op.attributeExists('lastMaintenance')
2848
- * ])
2849
- * );
2850
- *
2851
- * // Check breeding conditions
2852
- * builder.condition(op =>
2853
- * op.and([
2854
- * op.eq('species', 'VELOCIRAPTOR'),
2855
- * op.gte('age', 3),
2856
- * op.eq('geneticPurity', 100)
2857
- * ])
2858
- * );
2859
- * ```
2860
- *
2861
- * @param condition - Either a Condition DynamoItem or a callback function that builds the condition
2862
- * @returns The builder instance for method chaining
2863
- */
2864
- condition<T extends DynamoItem>(condition: Condition | ((op: ConditionOperator<T>) => Condition)): this;
2865
- /**
2866
- * Generates the DynamoDB command parameters for direct execution.
2867
- * Use this method when you want to:
2868
- * - Execute the condition check as a standalone operation
2869
- * - Get the raw DynamoDB command for custom execution
2870
- * - Inspect the generated command parameters
2871
- *
2872
- * @example
2873
- * ```ts
2874
- * const command = new ConditionCheckBuilder('myTable', { id: '123' })
2875
- * .condition(op => op.attributeExists('status'))
2876
- * .toDynamoCommand();
2877
- * // Use command with DynamoDB client
2878
- * ```
2879
- *
2880
- * @throws {Error} If no condition has been set
2881
- * @returns The DynamoDB command parameters
2882
- */
2883
- private toDynamoCommand;
2884
- /**
2885
- * Adds this condition check operation to a transaction.
2886
- *
2887
- * @example
2888
- * ```ts
2889
- * const transaction = new TransactionBuilder();
2890
- * new ConditionCheckBuilder('habitats', { id: 'PADDOCK-B' })
2891
- * .condition(op => op.and([
2892
- * op.eq('securityStatus', 'ACTIVE'),
2893
- * op.lt('currentOccupants', 3),
2894
- * op.eq('habitatType', 'CARNIVORE')
2895
- * ]))
2896
- * .withTransaction(transaction);
2897
- * // Add dinosaur transfer operations
2898
- * ```
2899
- *
2900
- * @param transaction - The transaction builder to add this operation to
2901
- * @throws {Error} If no condition has been set
2902
- * @returns The builder instance for method chaining
2903
- */
2904
- withTransaction(transaction: TransactionBuilder): this;
2905
- /**
2906
- * Gets a human-readable representation of the condition check command
2907
- * with all expression placeholders replaced by their actual values.
2908
- *
2909
- * @example
2910
- * ```ts
2911
- * const debugInfo = new ConditionCheckBuilder('dinosaurs', { id: 'TREX-001' })
2912
- * .condition(op => op.and([
2913
- * op.between('stats.health', 50, 100),
2914
- * op.not(op.eq('status', 'SEDATED')),
2915
- * op.attributeExists('lastFeedingTime')
2916
- * op.eq('version', 1)
2917
- * ]))
2918
- * .debug();
2919
- * console.log(debugInfo);
2920
- * ```
2921
- *
2922
- * @returns A readable representation of the condition check command with resolved expressions
2923
- */
2924
- debug(): {
2925
- raw: ConditionCheckCommandParams;
2926
- readable: {
2927
- conditionExpression?: string;
2928
- updateExpression?: string;
2929
- filterExpression?: string;
2930
- keyConditionExpression?: string;
2931
- projectionExpression?: string;
2932
- };
2933
- };
2934
- }
2935
-
2936
- /**
2937
- * Configuration options for DynamoDB scan operations.
2938
- * Extends the base FilterOptions.
2939
- */
2940
- type ScanOptions = FilterOptions;
2941
- /**
2942
- * Function type for executing DynamoDB filter operations.
2943
- * @typeParam T - The type of items being filtered
2944
- */
2945
- type ScanExecutor<T extends DynamoItem> = (options: ScanOptions) => Promise<{
2946
- items: T[];
2947
- lastEvaluatedKey?: DynamoItem;
2948
- }>;
2949
- /**
2950
- * Builder for creating DynamoDB scan operations.
2951
- * Use this builder when you need to:
2952
- * - Scan all items in a table
2953
- * - Filter results based on non-key attributes
2954
- * - Scan items on a Secondary Index (GSI)
2955
- * - Implement pagination
2956
- * - Project specific attributes
2957
- *
2958
- * The builder supports:
2959
- * - Type-safe GSI selection
2960
- * - Complex filter conditions
2961
- * - Automatic pagination handling
2962
- * - Consistent reads
2963
- * - Attribute projection
2964
- *
2965
- * @example
2966
- * ```typescript
2967
- * // Simple scan with filtering
2968
- * const result = await new ScanBuilder(executor)
2969
- * .filter(op => op.eq('status', 'ACTIVE'))
2970
- * .execute();
2971
- *
2972
- * // Scan with GSI and filtering
2973
- * const result = await new ScanBuilder(executor)
2974
- * .useIndex('status-index')
2975
- * .filter(op => op.gt('securityLevel', 8))
2976
- * .select(['id', 'capacity', 'currentOccupants'])
2977
- * .limit(10)
2978
- * .execute();
2979
- *
2980
- * // Scan with pagination
2981
- * const paginator = new ScanBuilder(executor)
2982
- * .filter(op => op.eq('type', 'INCIDENT'))
2983
- * .paginate(25);
2984
- *
2985
- * while (paginator.hasNextPage()) {
2986
- * const page = await paginator.getNextPage();
2987
- * // Process page.items
2988
- * }
2989
- * ```
2990
- *
2991
- * @typeParam T - The type of items being scanned
2992
- * @typeParam TConfig - The table configuration type for type-safe GSI selection
2993
- */
2994
- declare class ScanBuilder<T extends DynamoItem, TConfig extends TableConfig = TableConfig> extends FilterBuilder<T, TConfig> implements ScanBuilderInterface<T, TConfig> {
2995
- protected readonly executor: ScanExecutor<T>;
2996
- constructor(executor: ScanExecutor<T>);
2997
- /**
2998
- * Creates a deep clone of this ScanBuilder instance.
2999
- *
3000
- * @returns A new ScanBuilder instance with the same configuration
3001
- */
3002
- clone(): ScanBuilder<T, TConfig>;
3003
- private deepCloneFilter;
3004
- /**
3005
- * Executes the scan against DynamoDB and returns a generator that behaves like an array.
3006
- *
3007
- * The generator automatically handles pagination and provides array-like methods
3008
- * for processing results efficiently without loading everything into memory at once.
3009
- *
3010
- * @example
3011
- * ```typescript
3012
- * try {
3013
- * // Find all dinosaurs with high aggression levels with automatic pagination
3014
- * const results = await new ScanBuilder(executor)
3015
- * .filter(op =>
3016
- * op.and([
3017
- * op.eq('status', 'ACTIVE'),
3018
- * op.gt('aggressionLevel', 7)
3019
- * ])
3020
- * )
3021
- * .execute();
3022
- *
3023
- * // Use like an array with automatic pagination
3024
- * for await (const dinosaur of results) {
3025
- * console.log(`Processing dangerous dinosaur: ${dinosaur.name}`);
3026
- * }
3027
- *
3028
- * // Or convert to array and use array methods
3029
- * const allItems = await results.toArray();
3030
- * const criticalThreats = allItems.filter(dino => dino.aggressionLevel > 9);
3031
- * const totalCount = allItems.length;
3032
- * } catch (error) {
3033
- * console.error('Security scan failed:', error);
3034
- * }
3035
- * ```
3036
- *
3037
- * @returns A promise that resolves to a ResultGenerator that behaves like an array
3038
- */
3039
- execute(): Promise<ResultIterator<T, TConfig>>;
3040
- }
3041
-
3042
- export { BatchBuilder as B, ConditionCheckBuilder as C, DeleteBuilder as D, ExpressionError as E, FilterBuilder as F, GetBuilder as G, IndexGenerationError as I, KeyGenerationError as K, OperationError as O, PutBuilder as P, QueryBuilder as Q, ResultIterator as R, ScanBuilder as S, TransactionBuilder as T, UpdateBuilder as U, ValidationError as V, type TransactionOptions as a, type BatchWriteOperation as b, BatchError as c, ConfigurationError as d, EntityValidationError as e, TransactionError as f, DynoTableError as g, EntityError as h, type BatchResult as i, type DeleteOptions as j, type ErrorCode as k, ErrorCodes as l, type PutOptions as m, type QueryOptions as n, type UpdateOptions as o, type UpdateCommandParams as p, type BaseBuilderInterface as q, type ConditionCheckCommandParams as r, type DeleteCommandParams as s, type FilterBuilderInterface as t, type PaginationResult as u, Paginator as v, type PutCommandParams as w, type QueryBuilderInterface as x, type ScanBuilderInterface as y, type TransactionItem as z };