dyno-table 0.1.6 → 0.1.8

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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -17
  3. package/dist/builders/condition-check-builder.cjs +394 -0
  4. package/dist/builders/condition-check-builder.cjs.map +1 -0
  5. package/dist/builders/condition-check-builder.js +392 -0
  6. package/dist/builders/condition-check-builder.js.map +1 -0
  7. package/dist/builders/delete-builder.cjs +422 -0
  8. package/dist/builders/delete-builder.cjs.map +1 -0
  9. package/dist/builders/delete-builder.js +420 -0
  10. package/dist/builders/delete-builder.js.map +1 -0
  11. package/dist/builders/paginator.cjs +199 -0
  12. package/dist/builders/paginator.cjs.map +1 -0
  13. package/dist/builders/paginator.js +197 -0
  14. package/dist/builders/paginator.js.map +1 -0
  15. package/dist/builders/put-builder.cjs +468 -0
  16. package/dist/builders/put-builder.cjs.map +1 -0
  17. package/dist/builders/put-builder.js +466 -0
  18. package/dist/builders/put-builder.js.map +1 -0
  19. package/dist/builders/query-builder.cjs +674 -0
  20. package/dist/builders/query-builder.cjs.map +1 -0
  21. package/dist/builders/query-builder.js +672 -0
  22. package/dist/builders/query-builder.js.map +1 -0
  23. package/dist/builders/transaction-builder.cjs +876 -0
  24. package/dist/builders/transaction-builder.cjs.map +1 -0
  25. package/dist/builders/transaction-builder.js +874 -0
  26. package/dist/builders/transaction-builder.js.map +1 -0
  27. package/dist/builders/update-builder.cjs +662 -0
  28. package/dist/builders/update-builder.cjs.map +1 -0
  29. package/dist/builders/update-builder.js +660 -0
  30. package/dist/builders/update-builder.js.map +1 -0
  31. package/dist/conditions.cjs +59 -0
  32. package/dist/conditions.cjs.map +1 -0
  33. package/dist/conditions.js +43 -0
  34. package/dist/conditions.js.map +1 -0
  35. package/dist/entity.cjs +169 -0
  36. package/dist/entity.cjs.map +1 -0
  37. package/dist/entity.js +165 -0
  38. package/dist/entity.js.map +1 -0
  39. package/dist/index.cjs +3333 -0
  40. package/dist/index.d.cts +2971 -0
  41. package/dist/index.d.ts +1504 -1383
  42. package/dist/index.js +391 -375
  43. package/dist/standard-schema.cjs +4 -0
  44. package/dist/standard-schema.cjs.map +1 -0
  45. package/dist/standard-schema.js +3 -0
  46. package/dist/standard-schema.js.map +1 -0
  47. package/dist/table.cjs +3265 -0
  48. package/dist/table.cjs.map +1 -0
  49. package/dist/table.js +3263 -0
  50. package/dist/table.js.map +1 -0
  51. package/dist/types.cjs +4 -0
  52. package/dist/types.cjs.map +1 -0
  53. package/dist/types.js +3 -0
  54. package/dist/types.js.map +1 -0
  55. package/dist/utils/key-template.cjs +19 -0
  56. package/dist/utils/key-template.cjs.map +1 -0
  57. package/dist/utils/key-template.js +17 -0
  58. package/dist/utils/key-template.js.map +1 -0
  59. package/dist/utils/sort-key-template.cjs +19 -0
  60. package/dist/utils/sort-key-template.cjs.map +1 -0
  61. package/dist/utils/sort-key-template.js +17 -0
  62. package/dist/utils/sort-key-template.js.map +1 -0
  63. package/package.json +12 -7
package/dist/index.d.ts CHANGED
@@ -108,6 +108,26 @@ interface Condition {
108
108
  /** Single condition for the 'not' operator */
109
109
  condition?: Condition;
110
110
  }
111
+ /**
112
+ * Parameters used to build DynamoDB expression strings.
113
+ * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html Expression Attribute Names}
114
+ * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeValues.html Expression Attribute Values}
115
+ */
116
+ interface ExpressionParams {
117
+ /** Map of attribute name placeholders to actual attribute names */
118
+ expressionAttributeNames: Record<string, string>;
119
+ /** Map of value placeholders to actual values */
120
+ expressionAttributeValues: Record<string, unknown>;
121
+ /** Counter for generating unique value placeholders */
122
+ valueCounter: {
123
+ count: number;
124
+ };
125
+ }
126
+ /**
127
+ * Creates a comparison condition builder function for the specified operator.
128
+ * @internal
129
+ */
130
+ declare const createComparisonCondition: (type: ComparisonOperator) => (attr: string, value: unknown) => Condition;
111
131
  /**
112
132
  * Creates an equals (=) condition
113
133
  * @example
@@ -331,6 +351,105 @@ type PrimaryKeyWithoutExpression = {
331
351
  sk?: string;
332
352
  };
333
353
 
354
+ /**
355
+ * Interface for DynamoDB command objects that can contain expressions
356
+ */
357
+ interface DynamoCommandWithExpressions {
358
+ conditionExpression?: string;
359
+ updateExpression?: string;
360
+ filterExpression?: string;
361
+ keyConditionExpression?: string;
362
+ projectionExpression?: string;
363
+ expressionAttributeNames?: Record<string, string>;
364
+ expressionAttributeValues?: Record<string, unknown>;
365
+ [key: string]: unknown;
366
+ }
367
+
368
+ interface DeleteCommandParams extends DynamoCommandWithExpressions {
369
+ tableName: string;
370
+ key: PrimaryKeyWithoutExpression;
371
+ conditionExpression?: string;
372
+ expressionAttributeNames?: Record<string, string>;
373
+ expressionAttributeValues?: Record<string, unknown>;
374
+ returnValues?: "ALL_OLD";
375
+ }
376
+ /**
377
+ * Parameters for the DynamoDB put command.
378
+ *
379
+ * These parameters are used when executing the operation against DynamoDB.
380
+ *
381
+ * The `returnValues` property can be:
382
+ * - `"ALL_OLD"`: Return the attributes of the item as they were before the operation
383
+ * - `"NONE"`: Return nothing
384
+ * - `"CONSISTENT"`: Triggers a GET operation after the put to retrieve the updated item state
385
+ */
386
+ interface PutCommandParams extends DynamoCommandWithExpressions {
387
+ tableName: string;
388
+ item: Record<string, unknown>;
389
+ conditionExpression?: string;
390
+ expressionAttributeNames?: Record<string, string>;
391
+ expressionAttributeValues?: Record<string, unknown>;
392
+ returnValues?: "ALL_OLD" | "NONE" | "CONSISTENT";
393
+ }
394
+ /**
395
+ * Parameters for the DynamoDB update command.
396
+ * These parameters are used when executing the operation against DynamoDB.
397
+ */
398
+ interface UpdateCommandParams extends DynamoCommandWithExpressions {
399
+ /** The name of the DynamoDB table */
400
+ tableName: string;
401
+ /** The primary key of the item to update */
402
+ key: PrimaryKeyWithoutExpression;
403
+ /** The update expression (SET, REMOVE, ADD, DELETE clauses) */
404
+ updateExpression: string;
405
+ /** Optional condition expression that must be satisfied */
406
+ conditionExpression?: string;
407
+ /** Map of expression attribute name placeholders to actual names */
408
+ expressionAttributeNames?: Record<string, string>;
409
+ /** Map of expression attribute value placeholders to actual values */
410
+ expressionAttributeValues?: Record<string, unknown>;
411
+ /** Which item attributes to include in the response */
412
+ returnValues?: "ALL_NEW" | "UPDATED_NEW" | "ALL_OLD" | "UPDATED_OLD" | "NONE";
413
+ }
414
+ interface ConditionCheckCommandParams extends DynamoCommandWithExpressions {
415
+ tableName: string;
416
+ key: PrimaryKeyWithoutExpression;
417
+ conditionExpression: string;
418
+ expressionAttributeNames?: Record<string, string>;
419
+ expressionAttributeValues?: Record<string, unknown>;
420
+ }
421
+ /**
422
+ * Base interface for all builder classes that support pagination
423
+ * to be used by Paginator without creating circular dependencies.
424
+ */
425
+ interface BaseBuilderInterface<T extends Record<string, unknown>, TConfig extends TableConfig = TableConfig, B = unknown> {
426
+ clone(): B;
427
+ limit(limit: number): B;
428
+ getLimit(): number | undefined;
429
+ startFrom(lastEvaluatedKey: Record<string, unknown>): B;
430
+ execute(): Promise<{
431
+ items: T[];
432
+ lastEvaluatedKey?: Record<string, unknown>;
433
+ }>;
434
+ }
435
+ /**
436
+ * Interface for the QueryBuilder class to be used by Paginator
437
+ * without creating a circular dependency.
438
+ */
439
+ interface QueryBuilderInterface<T extends Record<string, unknown>, TConfig extends TableConfig = TableConfig> extends BaseBuilderInterface<T, TConfig, QueryBuilderInterface<T, TConfig>> {
440
+ }
441
+ /**
442
+ * Interface for the ScanBuilder class to be used by Paginator
443
+ * without creating a circular dependency.
444
+ */
445
+ interface ScanBuilderInterface<T extends Record<string, unknown>, TConfig extends TableConfig = TableConfig> extends BaseBuilderInterface<T, TConfig, ScanBuilderInterface<T, TConfig>> {
446
+ }
447
+ /**
448
+ * Interface for the FilterBuilder class to be used by Paginator
449
+ * without creating a circular dependency.
450
+ */
451
+ interface FilterBuilderInterface<T extends Record<string, unknown>, TConfig extends TableConfig = TableConfig> extends BaseBuilderInterface<T, TConfig, FilterBuilderInterface<T, TConfig>> {
452
+ }
334
453
  /**
335
454
  * Represents the result of a single page query operation.
336
455
  * This interface provides all necessary information about the current page
@@ -346,6 +465,7 @@ interface PaginationResult<T> {
346
465
  /** The current page number (1-indexed) */
347
466
  page: number;
348
467
  }
468
+
349
469
  /**
350
470
  * A utility class for handling DynamoDB pagination.
351
471
  * Use this class when you need to:
@@ -388,7 +508,7 @@ declare class Paginator<T extends Record<string, unknown>, TConfig extends Table
388
508
  private hasMorePages;
389
509
  private totalItemsRetrieved;
390
510
  private readonly overallLimit?;
391
- constructor(queryBuilder: QueryBuilder<T, TConfig>, pageSize: number);
511
+ constructor(queryBuilder: QueryBuilderInterface<T, TConfig>, pageSize: number);
392
512
  /**
393
513
  * Gets the current page number (1-indexed).
394
514
  * Use this method when you need to:
@@ -521,140 +641,54 @@ declare class Paginator<T extends Record<string, unknown>, TConfig extends Table
521
641
  }
522
642
 
523
643
  /**
524
- * Configuration options for DynamoDB query operations.
644
+ * Configuration options for DynamoDB filter operations.
645
+ * These are common options shared between query and scan operations.
525
646
  */
526
- interface QueryOptions {
527
- /** Condition for the sort key in the table or index */
528
- sortKeyCondition?: Condition;
529
- /** Additional filter conditions applied after the key condition */
647
+ interface FilterOptions {
648
+ /** Filter conditions applied to results */
530
649
  filter?: Condition;
531
650
  /** Maximum number of items to return */
532
651
  limit?: number;
533
- /** Name of the Global Secondary Index to query */
652
+ /** Name of the Global Secondary Index to use */
534
653
  indexName?: string;
535
654
  /** Whether to use strongly consistent reads */
536
655
  consistentRead?: boolean;
537
- /** Direction of sort key traversal (true for ascending, false for descending) */
538
- scanIndexForward?: boolean;
539
656
  /** List of attributes to return in the result */
540
657
  projection?: string[];
541
- /** Number of items to fetch per page when using pagination */
542
- paginationSize?: number;
543
- /** Token for starting the query from a specific point */
658
+ /** Token for starting the operation from a specific point */
544
659
  lastEvaluatedKey?: Record<string, unknown>;
545
660
  }
546
661
  /**
547
- * Function type for executing DynamoDB query operations.
548
- * @typeParam T - The type of items being queried
549
- */
550
- type QueryExecutor<T extends Record<string, unknown>> = (keyCondition: Condition, options: QueryOptions) => Promise<{
551
- items: T[];
552
- lastEvaluatedKey?: Record<string, unknown>;
553
- }>;
554
- /**
555
- * Builder for creating DynamoDB query operations.
556
- * Use this builder when you need to:
557
- * - Query items using partition key (and optionally sort key)
558
- * - Filter results based on non-key attributes
559
- * - Use Global Secondary Indexes (GSIs)
560
- * - Implement pagination
561
- * - Control result ordering
562
- * - Project specific attributes
662
+ * Abstract base builder for creating DynamoDB filter operations.
663
+ * This class provides common functionality for both Query and Scan operations.
563
664
  *
564
665
  * The builder supports:
565
666
  * - Type-safe GSI selection
566
667
  * - Complex filter conditions
567
- * - Automatic pagination handling
668
+ * - Pagination
568
669
  * - Consistent reads
569
- * - Forward and reverse sorting
570
- *
571
- * @example
572
- * ```ts
573
- * // Simple query
574
- * const result = await new QueryBuilder(executor, eq('userId', '123'))
575
- * .execute();
576
- *
577
- * // Complex query with GSI and filtering
578
- * const result = await new QueryBuilder(executor, eq('status', 'ACTIVE'))
579
- * .useIndex('status-index')
580
- * .filter(op => op.beginsWith('name', 'John'))
581
- * .select(['id', 'name', 'email'])
582
- * .sortDescending()
583
- * .limit(10)
584
- * .execute();
585
- *
586
- * // Query with pagination
587
- * const paginator = new QueryBuilder(executor, eq('type', 'order'))
588
- * .paginate(25);
589
- *
590
- * while (paginator.hasNextPage()) {
591
- * const page = await paginator.getNextPage();
592
- * // Process page.items
593
- * }
594
- * ```
595
- *
596
- * @typeParam T - The type of items being queried
597
- * @typeParam TConfig - The table configuration type for type-safe GSI selection
598
- */
599
- /**
600
- * Builder for creating DynamoDB query operations.
601
- * Use this builder when you need to:
602
- * - Find dinosaurs by species or status
603
- * - Search habitats by type or region
604
- * - List incidents by date range
605
- * - Retrieve feeding schedules
606
- *
607
- * The builder supports:
608
- * - Complex filtering conditions
609
- * - Sorting and pagination
610
- * - Global Secondary Indexes
611
670
  * - Attribute projection
612
671
  *
613
- * @example
614
- * ```typescript
615
- * // Find active carnivores
616
- * const result = await new QueryBuilder(executor, eq('species', 'Tyrannosaurus'))
617
- * .filter(op => op.eq('status', 'ACTIVE'))
618
- * .execute();
619
- *
620
- * // Search habitats by security level
621
- * const result = await new QueryBuilder(executor, eq('type', 'CARNIVORE'))
622
- * .useIndex('security-level-index')
623
- * .filter(op => op.gt('securityLevel', 8))
624
- * .select(['id', 'capacity', 'currentOccupants'])
625
- * .sortDescending()
626
- * .execute();
627
- *
628
- * // List recent incidents
629
- * const result = await new QueryBuilder(executor, eq('type', 'INCIDENT'))
630
- * .useIndex('date-index')
631
- * .filter(op => op.gt('severityLevel', 5))
632
- * .paginate(10);
633
- * ```
634
- *
635
- * @typeParam T - The type of items being queried
672
+ * @typeParam T - The type of items being filtered
636
673
  * @typeParam TConfig - The table configuration type for type-safe GSI selection
637
674
  */
638
- declare class QueryBuilder<T extends Record<string, unknown>, TConfig extends TableConfig = TableConfig> {
639
- private readonly keyCondition;
640
- private options;
641
- private selectedFields;
642
- private readonly executor;
643
- constructor(executor: QueryExecutor<T>, keyCondition: Condition);
675
+ declare abstract class FilterBuilder<T extends Record<string, unknown>, TConfig extends TableConfig = TableConfig> implements FilterBuilderInterface<T, TConfig> {
676
+ protected options: FilterOptions;
677
+ protected selectedFields: Set<string>;
644
678
  /**
645
- * Sets the maximum number of items to return from the query.
679
+ * Sets the maximum number of items to return.
646
680
  * Use this method when you need to:
647
- * - Limit the result set size
648
- * - Implement manual pagination
649
- * - Control data transfer size
681
+ * - Limit the number of dinosaurs returned
682
+ * - Control the size of habitat reports
683
+ * - Implement manual pagination of security logs
650
684
  *
651
685
  * Note: This limit applies to the items that match the key condition
652
686
  * before any filter expressions are applied.
653
687
  *
654
688
  * @example
655
- * ```ts
656
- * // Get first 10 orders for a user
657
- * const result = await new QueryBuilder(executor, eq('userId', '123'))
689
+ * ```typescript
690
+ * // Get first 10 dinosaurs
691
+ * const result = await builder
658
692
  * .limit(10)
659
693
  * .execute();
660
694
  * ```
@@ -662,50 +696,18 @@ declare class QueryBuilder<T extends Record<string, unknown>, TConfig extends Ta
662
696
  * @param limit - Maximum number of items to return
663
697
  * @returns The builder instance for method chaining
664
698
  */
665
- limit(limit: number): QueryBuilder<T>;
699
+ limit(limit: number): this;
666
700
  /**
667
- * Gets the current limit set on the query.
701
+ * Gets the current limit set on the operation.
668
702
  * This is used internally by the paginator to manage result sets.
669
703
  *
670
704
  * @returns The current limit or undefined if no limit is set
671
705
  */
672
706
  getLimit(): number | undefined;
673
707
  /**
674
- * Specifies a Global Secondary Index (GSI) to use for the query.
675
- * Use this method when you need to:
676
- * - Query data using non-primary key attributes
677
- * - Access data through alternate access patterns
678
- * - Optimize query performance for specific access patterns
679
- *
680
- * This method provides type safety by only allowing valid GSI names
681
- * defined in your table configuration.
682
- *
683
- * @example
684
- * ```ts
685
- * // Query by status using a GSI
686
- * const result = await new QueryBuilder(executor, eq('status', 'ACTIVE'))
687
- * .useIndex('status-index')
688
- * .execute();
689
- *
690
- * // Query by category and date range
691
- * const result = await new QueryBuilder(executor, eq('category', 'books'))
692
- * .useIndex('category-date-index')
693
- * .filter(op => op.between('date', startDate, endDate))
694
- * .execute();
695
- * ```
696
- *
697
- * Note: Be aware that GSIs:
698
- * - May have different projected attributes
699
- * - Have eventually consistent reads only
700
- * - May have different provisioned throughput
701
- *
702
- * @param indexName - The name of the GSI to use (type-safe based on table configuration)
703
- * @returns The builder instance for method chaining
704
- */
705
- /**
706
- * Specifies a Global Secondary Index (GSI) to use for the query.
708
+ * Specifies a Global Secondary Index (GSI) to use for the operation.
707
709
  * Use this method when you need to:
708
- * - Query dinosaurs by species or status
710
+ * - Find dinosaurs by species or status
709
711
  * - Search habitats by security level
710
712
  * - Find incidents by date
711
713
  * - List feeding schedules by time
@@ -731,9 +733,9 @@ declare class QueryBuilder<T extends Record<string, unknown>, TConfig extends Ta
731
733
  * @param indexName - The name of the GSI to use (type-safe based on table configuration)
732
734
  * @returns The builder instance for method chaining
733
735
  */
734
- useIndex<I extends GSINames<TConfig>>(indexName: I): QueryBuilder<T, TConfig>;
736
+ useIndex<I extends GSINames<TConfig>>(indexName: I): this;
735
737
  /**
736
- * Sets whether to use strongly consistent reads for the query.
738
+ * Sets whether to use strongly consistent reads for the operation.
737
739
  * Use this method when you need to:
738
740
  * - Get real-time dinosaur status updates
739
741
  * - Monitor critical security systems
@@ -746,15 +748,15 @@ declare class QueryBuilder<T extends Record<string, unknown>, TConfig extends Ta
746
748
  * - Default is eventually consistent reads
747
749
  *
748
750
  * @example
749
- * ```ts
751
+ * ```typescript
750
752
  * // Check immediate dinosaur status
751
- * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
753
+ * const result = await builder
752
754
  * .filter(op => op.eq('status', 'ACTIVE'))
753
755
  * .consistentRead()
754
756
  * .execute();
755
757
  *
756
758
  * // Monitor security breaches
757
- * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_ALERT'))
759
+ * const result = await builder
758
760
  * .useIndex('primary-index')
759
761
  * .consistentRead(isEmergencyMode)
760
762
  * .execute();
@@ -763,37 +765,9 @@ declare class QueryBuilder<T extends Record<string, unknown>, TConfig extends Ta
763
765
  * @param consistentRead - Whether to use consistent reads (defaults to true)
764
766
  * @returns The builder instance for method chaining
765
767
  */
766
- consistentRead(consistentRead?: boolean): QueryBuilder<T>;
767
- /**
768
- * Adds a filter expression to the query.
769
- * Use this method when you need to:
770
- * - Filter results based on non-key attributes
771
- * - Apply complex filtering conditions
772
- * - Combine multiple filter conditions
773
- *
774
- * Note: Filter expressions are applied after the key condition,
775
- * so they don't reduce the amount of data read from DynamoDB.
776
- *
777
- * @example
778
- * ```ts
779
- * // Simple filter
780
- * builder.filter(op => op.eq('status', 'ACTIVE'))
781
- *
782
- * // Complex filter with multiple conditions
783
- * builder.filter(op =>
784
- * op.and([
785
- * op.gt('amount', 1000),
786
- * op.beginsWith('category', 'ELECTRONICS'),
787
- * op.attributeExists('reviewDate')
788
- * ])
789
- * )
790
- * ```
791
- *
792
- * @param condition - Either a Condition object or a callback function that builds the condition
793
- * @returns The builder instance for method chaining
794
- */
768
+ consistentRead(consistentRead?: boolean): this;
795
769
  /**
796
- * Adds a filter expression to refine the query results.
770
+ * Adds a filter expression to refine the operation results.
797
771
  * Use this method when you need to:
798
772
  * - Filter dinosaurs by behavior patterns
799
773
  * - Find habitats with specific conditions
@@ -824,36 +798,9 @@ declare class QueryBuilder<T extends Record<string, unknown>, TConfig extends Ta
824
798
  * @param condition - Either a Condition object or a callback function that builds the condition
825
799
  * @returns The builder instance for method chaining
826
800
  */
827
- filter(condition: Condition | ((op: ConditionOperator<T>) => Condition)): QueryBuilder<T>;
828
- /**
829
- * Specifies which attributes to return in the query results.
830
- * Use this method when you need to:
831
- * - Reduce data transfer by selecting specific attributes
832
- * - Optimize response size
833
- * - Focus on relevant attributes only
834
- *
835
- * Note: Using projection can significantly reduce the amount
836
- * of data returned and lower your costs.
837
- *
838
- * @example
839
- * ```ts
840
- * // Select single attribute
841
- * builder.select('email')
842
- *
843
- * // Select multiple attributes
844
- * builder.select(['id', 'name', 'email'])
845
- *
846
- * // Chain multiple select calls
847
- * builder
848
- * .select('id')
849
- * .select(['name', 'email'])
850
- * ```
851
- *
852
- * @param fields - A single field name or an array of field names to return
853
- * @returns The builder instance for method chaining
854
- */
801
+ filter(condition: Condition | ((op: ConditionOperator<T>) => Condition)): this;
855
802
  /**
856
- * Specifies which attributes to return in the query results.
803
+ * Specifies which attributes to return in the results.
857
804
  * Use this method when you need to:
858
805
  * - Get specific dinosaur attributes
859
806
  * - Retrieve habitat statistics
@@ -883,167 +830,242 @@ declare class QueryBuilder<T extends Record<string, unknown>, TConfig extends Ta
883
830
  * @param fields - A single field name or an array of field names to return
884
831
  * @returns The builder instance for method chaining
885
832
  */
886
- select(fields: string | string[]): QueryBuilder<T>;
833
+ select(fields: string | string[]): this;
887
834
  /**
888
- * Sets the query to return items in ascending order by sort key.
889
- * Use this method when you need to:
890
- * - Retrieve items in natural order (e.g., timestamps, versions)
891
- * - Implement chronological ordering
892
- * - Get oldest items first
893
- *
894
- * Note: This is the default behavior if no sort order is specified.
835
+ * Creates a paginator that handles DynamoDB pagination automatically.
836
+ * The paginator handles:
837
+ * - Tracking the last evaluated key
838
+ * - Managing page boundaries
839
+ * - Respecting overall query limits
895
840
  *
896
841
  * @example
897
842
  * ```typescript
898
- * // Get orders in chronological order
899
- * const result = await new QueryBuilder(executor, eq('userId', '123'))
900
- * .sortAscending()
901
- * .execute();
843
+ * // Create a paginator for dinosaur records
844
+ * const paginator = builder
845
+ * .filter(op => op.eq('status', 'ACTIVE'))
846
+ * .paginate(10);
902
847
  *
903
- * // Get events from oldest to newest
904
- * const result = await new QueryBuilder(executor, eq('entityId', 'order-123'))
905
- * .useIndex('entity-timestamp-index')
906
- * .sortAscending()
907
- * .execute();
848
+ * // Process pages of dinosaur results
849
+ * while (paginator.hasNextPage()) {
850
+ * const page = await paginator.getNextPage();
851
+ * console.log(`Processing page ${page.page}, count: ${page.items.length}`);
852
+ * // Process dinosaur data
853
+ * }
908
854
  * ```
909
855
  *
910
- * @returns The builder instance for method chaining
856
+ * @param pageSize - The number of items to return per page
857
+ * @returns A Paginator instance that manages the pagination state
858
+ * @see Paginator for more pagination control options
911
859
  */
860
+ paginate(pageSize: number): Paginator<T, TConfig>;
912
861
  /**
913
- * Sets the query to return items in ascending order by sort key.
862
+ * Sets the starting point using a previous lastEvaluatedKey.
914
863
  * Use this method when you need to:
915
- * - List dinosaurs by age (youngest first)
916
- * - View incidents chronologically
917
- * - Track feeding schedule progression
918
- * - Monitor habitat inspections
864
+ * - Implement manual dinosaur list pagination
865
+ * - Resume habitat inspection reviews
866
+ * - Continue security incident analysis
867
+ * - Store operation position between sessions
868
+ *
869
+ * Note: This method is typically used for manual pagination.
870
+ * For automatic pagination, use the paginate() method instead.
919
871
  *
920
872
  * @example
921
873
  * ```typescript
922
- * // List dinosaurs by age
923
- * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
924
- * .useIndex('age-index')
925
- * .sortAscending()
874
+ * // First batch of dinosaurs
875
+ * const result1 = await builder
876
+ * .filter(op => op.eq('status', 'ACTIVE'))
877
+ * .limit(5)
926
878
  * .execute();
927
879
  *
928
- * // View incidents chronologically
929
- * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
930
- * .useIndex('date-index')
931
- * .sortAscending()
932
- * .execute();
880
+ * if (result1.lastEvaluatedKey) {
881
+ * // Continue listing dinosaurs
882
+ * const result2 = await builder
883
+ * .filter(op => op.eq('status', 'ACTIVE'))
884
+ * .startFrom(result1.lastEvaluatedKey)
885
+ * .limit(5)
886
+ * .execute();
887
+ *
888
+ * console.log('Additional dinosaurs:', result2.items);
889
+ * }
933
890
  * ```
934
891
  *
892
+ * @param lastEvaluatedKey - The exclusive start key from a previous result
935
893
  * @returns The builder instance for method chaining
936
894
  */
937
- sortAscending(): QueryBuilder<T>;
895
+ startFrom(lastEvaluatedKey: Record<string, unknown>): this;
938
896
  /**
939
- * Sets the query to return items in descending order by sort key.
897
+ * Creates a deep clone of this builder instance.
940
898
  * Use this method when you need to:
941
- * - Get most recent security breaches
942
- * - Find oldest dinosaurs first
943
- * - Check latest habitat modifications
944
- * - Monitor recent feeding events
899
+ * - Query different dinosaur statuses
900
+ * - Check multiple habitat conditions
901
+ * - Monitor various security levels
902
+ * - Create report templates
903
+ *
904
+ * This is particularly useful when:
905
+ * - Implementing pagination (used internally by paginate())
906
+ * - Creating operation templates
907
+ * - Running multiple variations of an operation
945
908
  *
946
909
  * @example
947
910
  * ```typescript
948
- * // Get most recent security incidents
949
- * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
950
- * .useIndex('date-index')
951
- * .sortDescending()
952
- * .limit(10)
911
+ * // Create base dinosaur query
912
+ * const baseBuilder = builder
913
+ * .useIndex('status-index')
914
+ * .select(['id', 'status', 'location']);
915
+ *
916
+ * // Check active dinosaurs
917
+ * const activeRaptors = baseBuilder.clone()
918
+ * .filter(op => op.eq('status', 'HUNTING'))
953
919
  * .execute();
954
920
  *
955
- * // Check latest dinosaur activities
956
- * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
957
- * .useIndex('activity-time-index')
958
- * .filter(op => op.eq('status', 'ACTIVE'))
959
- * .sortDescending()
921
+ * // Check contained dinosaurs
922
+ * const containedRaptors = baseBuilder.clone()
923
+ * .filter(op => op.eq('status', 'CONTAINED'))
960
924
  * .execute();
961
925
  * ```
962
926
  *
963
- * @returns The builder instance for method chaining
927
+ * @returns A new builder instance with the same configuration
964
928
  */
965
- sortDescending(): QueryBuilder<T>;
929
+ abstract clone(): FilterBuilderInterface<T, TConfig>;
966
930
  /**
967
- * Creates a paginator that handles DynamoDB pagination automatically.
968
- * Use this method when you need to:
969
- * - Browse large dinosaur collections
970
- * - View habitat inspection history
971
- * - Monitor security incidents
972
- * - Track feeding patterns
931
+ * Executes the operation against DynamoDB.
932
+ * This method must be implemented by subclasses to handle
933
+ * their specific execution logic.
934
+ */
935
+ abstract execute(): Promise<{
936
+ items: T[];
937
+ lastEvaluatedKey?: Record<string, unknown>;
938
+ }>;
939
+ }
940
+
941
+ /**
942
+ * Configuration options for DynamoDB query operations.
943
+ * Extends the base FilterOptions with query-specific options.
944
+ */
945
+ interface QueryOptions extends FilterOptions {
946
+ /** Condition for the sort key in the table or index */
947
+ sortKeyCondition?: Condition;
948
+ /** Direction of sort key traversal (true for ascending, false for descending) */
949
+ scanIndexForward?: boolean;
950
+ }
951
+ /**
952
+ * Function type for executing DynamoDB query operations.
953
+ * @typeParam T - The type of items being queried
954
+ */
955
+ type QueryExecutor<T extends Record<string, unknown>> = (keyCondition: Condition, options: QueryOptions) => Promise<{
956
+ items: T[];
957
+ lastEvaluatedKey?: Record<string, unknown>;
958
+ }>;
959
+ /**
960
+ * Builder for creating DynamoDB query operations.
961
+ *
962
+ * The builder supports:
963
+ * - Type-safe GSI selection
964
+ * - Complex filter conditions
965
+ * - Automatic pagination handling
966
+ * - Consistent reads
967
+ * - Forward and reverse sorting
968
+ *
969
+ * @example
970
+ * ```typescript
971
+ * // Simple query
972
+ * const result = await new QueryBuilder(executor, eq('userId', '123'))
973
+ * .execute();
974
+ *
975
+ * // Complex query with GSI and filtering
976
+ * const result = await new QueryBuilder(executor, eq('status', 'ACTIVE'))
977
+ * .useIndex('status-index')
978
+ * .filter(op => op.beginsWith('name', 'John'))
979
+ * .select(['id', 'name', 'email'])
980
+ * .sortDescending()
981
+ * .limit(10)
982
+ * .execute();
983
+ *
984
+ * // Query with pagination
985
+ * const paginator = new QueryBuilder(executor, eq('type', 'order'))
986
+ * .paginate(25);
987
+ *
988
+ * while (paginator.hasNextPage()) {
989
+ * const page = await paginator.getNextPage();
990
+ * // Process page.items
991
+ * }
992
+ * ```
993
+ *
994
+ * @typeParam T - The type of items being queried
995
+ * @typeParam TConfig - The table configuration type for type-safe GSI selection
996
+ */
997
+ declare class QueryBuilder<T extends Record<string, unknown>, TConfig extends TableConfig = TableConfig> extends FilterBuilder<T, TConfig> implements QueryBuilderInterface<T, TConfig> {
998
+ private readonly keyCondition;
999
+ protected options: QueryOptions;
1000
+ protected readonly executor: QueryExecutor<T>;
1001
+ constructor(executor: QueryExecutor<T>, keyCondition: Condition);
1002
+ /**
1003
+ * Sets the maximum number of items to return from the query.
973
1004
  *
974
- * The paginator handles:
975
- * - Tracking the last evaluated key
976
- * - Managing page boundaries
977
- * - Respecting overall query limits
1005
+ * Note: This is the default behavior if no sort order is specified.
978
1006
  *
979
1007
  * @example
980
1008
  * ```typescript
981
- * // List dinosaurs by species
982
- * const paginator = new QueryBuilder(executor, eq('species', 'Velociraptor'))
983
- * .filter(op => op.eq('status', 'ACTIVE'))
984
- * .useIndex('species-index')
985
- * .paginate(10);
986
- *
987
- * // Process pages of security incidents
988
- * const paginator = new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
989
- * .filter(op => op.gt('severityLevel', 7))
990
- * .sortDescending()
991
- * .paginate(25);
1009
+ * // Get orders in chronological order
1010
+ * const result = await new QueryBuilder(executor, eq('userId', '123'))
1011
+ * .sortAscending()
1012
+ * .execute();
992
1013
  *
993
- * while (paginator.hasNextPage()) {
994
- * const page = await paginator.getNextPage();
995
- * console.log(`Processing incidents page ${page.page}, count: ${page.items.length}`);
996
- * // Handle security incidents
997
- * }
1014
+ * // Get events from oldest to newest
1015
+ * const result = await new QueryBuilder(executor, eq('entityId', 'order-123'))
1016
+ * .useIndex('entity-timestamp-index')
1017
+ * .sortAscending()
1018
+ * .execute();
998
1019
  * ```
999
1020
  *
1000
- * @param pageSize - The number of items to return per page
1001
- * @returns A Paginator instance that manages the pagination state
1002
- * @see Paginator for more pagination control options
1021
+ * @returns The builder instance for method chaining
1003
1022
  */
1004
- paginate(pageSize: number): Paginator<T, TConfig>;
1005
1023
  /**
1006
- * Sets the starting point for the query using a previous lastEvaluatedKey.
1007
- * Use this method when you need to:
1008
- * - Implement manual dinosaur list pagination
1009
- * - Resume habitat inspection reviews
1010
- * - Continue security incident analysis
1011
- * - Store query position between sessions
1012
- *
1013
- * Note: This method is typically used for manual pagination.
1014
- * For automatic pagination, use the paginate() method instead.
1024
+ * Sets the query to return items in ascending order by sort key.
1015
1025
  *
1016
1026
  * @example
1017
1027
  * ```typescript
1018
- * // First batch of dinosaurs
1019
- * const result1 = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
1020
- * .filter(op => op.eq('status', 'ACTIVE'))
1021
- * .limit(5)
1028
+ * // List dinosaurs by age
1029
+ * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
1030
+ * .useIndex('age-index')
1031
+ * .sortAscending()
1022
1032
  * .execute();
1023
1033
  *
1024
- * if (result1.lastEvaluatedKey) {
1025
- * // Continue listing dinosaurs
1026
- * const result2 = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
1027
- * .filter(op => op.eq('status', 'ACTIVE'))
1028
- * .startFrom(result1.lastEvaluatedKey)
1029
- * .limit(5)
1030
- * .execute();
1034
+ * // View incidents chronologically
1035
+ * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
1036
+ * .useIndex('date-index')
1037
+ * .sortAscending()
1038
+ * .execute();
1039
+ * ```
1031
1040
  *
1032
- * console.log('Additional dinosaurs:', result2.items);
1033
- * }
1041
+ * @returns The builder instance for method chaining
1042
+ */
1043
+ sortAscending(): QueryBuilder<T>;
1044
+ /**
1045
+ * Sets the query to return items in descending order by sort key.
1046
+ *
1047
+ * @example
1048
+ * ```typescript
1049
+ * // Get most recent security incidents
1050
+ * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
1051
+ * .useIndex('date-index')
1052
+ * .sortDescending()
1053
+ * .limit(10)
1054
+ * .execute();
1055
+ *
1056
+ * // Check latest dinosaur activities
1057
+ * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
1058
+ * .useIndex('activity-time-index')
1059
+ * .filter(op => op.eq('status', 'ACTIVE'))
1060
+ * .sortDescending()
1061
+ * .execute();
1034
1062
  * ```
1035
1063
  *
1036
- * @param lastEvaluatedKey - The exclusive start key from a previous query result
1037
1064
  * @returns The builder instance for method chaining
1038
1065
  */
1039
- startFrom(lastEvaluatedKey: Record<string, unknown>): QueryBuilder<T>;
1066
+ sortDescending(): QueryBuilder<T>;
1040
1067
  /**
1041
1068
  * Creates a deep clone of this QueryBuilder instance.
1042
- * Use this method when you need to:
1043
- * - Query different dinosaur statuses
1044
- * - Check multiple habitat conditions
1045
- * - Monitor various security levels
1046
- * - Create report templates
1047
1069
  *
1048
1070
  * This is particularly useful when:
1049
1071
  * - Implementing pagination (used internally by paginate())
@@ -1078,11 +1100,6 @@ declare class QueryBuilder<T extends Record<string, unknown>, TConfig extends Ta
1078
1100
  clone(): QueryBuilder<T, TConfig>;
1079
1101
  /**
1080
1102
  * Executes the query against DynamoDB.
1081
- * Use this method when you need to:
1082
- * - Find specific dinosaur groups
1083
- * - Check habitat conditions
1084
- * - Monitor security incidents
1085
- * - Track feeding patterns
1086
1103
  *
1087
1104
  * The method returns both the matched items and, if there are more results,
1088
1105
  * a lastEvaluatedKey that can be used with startFrom() to continue the query.
@@ -1125,489 +1142,609 @@ declare class QueryBuilder<T extends Record<string, unknown>, TConfig extends Ta
1125
1142
  }
1126
1143
 
1127
1144
  /**
1128
- * Interface for DynamoDB command objects that can contain expressions
1145
+ * Configuration options for DynamoDB transactions.
1129
1146
  */
1130
- interface DynamoCommandWithExpressions {
1131
- conditionExpression?: string;
1132
- updateExpression?: string;
1133
- filterExpression?: string;
1134
- keyConditionExpression?: string;
1135
- projectionExpression?: string;
1136
- expressionAttributeNames?: Record<string, string>;
1137
- expressionAttributeValues?: Record<string, unknown>;
1138
- [key: string]: unknown;
1147
+ interface TransactionOptions {
1148
+ /** Unique identifier for the transaction request (idempotency token) */
1149
+ clientRequestToken?: string;
1150
+ /** Level of consumed capacity details to return */
1151
+ returnConsumedCapacity?: "INDEXES" | "TOTAL" | "NONE";
1152
+ /** Whether to return item collection metrics */
1153
+ returnItemCollectionMetrics?: "SIZE" | "NONE";
1139
1154
  }
1140
-
1141
1155
  /**
1142
- * Parameters for the DynamoDB update command.
1143
- * These parameters are used when executing the operation against DynamoDB.
1156
+ * Configuration for table indexes used in duplicate detection.
1157
+ * Defines the key structure for checking uniqueness constraints.
1144
1158
  */
1145
- interface UpdateCommandParams extends DynamoCommandWithExpressions {
1146
- /** The name of the DynamoDB table */
1147
- tableName: string;
1148
- /** The primary key of the item to update */
1149
- key: PrimaryKeyWithoutExpression;
1150
- /** The update expression (SET, REMOVE, ADD, DELETE clauses) */
1151
- updateExpression: string;
1152
- /** Optional condition expression that must be satisfied */
1153
- conditionExpression?: string;
1154
- /** Map of expression attribute name placeholders to actual names */
1155
- expressionAttributeNames?: Record<string, string>;
1156
- /** Map of expression attribute value placeholders to actual values */
1157
- expressionAttributeValues?: Record<string, unknown>;
1158
- /** Which item attributes to include in the response */
1159
- returnValues?: "ALL_NEW" | "UPDATED_NEW" | "ALL_OLD" | "UPDATED_OLD" | "NONE";
1159
+ interface IndexConfig {
1160
+ /** The partition key attribute name */
1161
+ partitionKey: string;
1162
+ /** Optional sort key attribute name */
1163
+ sortKey?: string;
1160
1164
  }
1161
1165
  /**
1162
- * Function type for executing DynamoDB update operations.
1163
- * @typeParam T - The type of the item being updated
1166
+ * Function type for executing DynamoDB transaction operations.
1167
+ * @param params - The complete transaction command input
1168
+ * @returns A promise that resolves when the transaction completes
1164
1169
  */
1165
- type UpdateExecutor<T extends Record<string, unknown>> = (params: UpdateCommandParams) => Promise<{
1166
- item?: T;
1167
- }>;
1170
+ type TransactionExecutor = (params: TransactWriteCommandInput) => Promise<void>;
1168
1171
  /**
1169
- * Type utility to get the element type of a set.
1170
- * Extracts the element type from either a Set or Array type.
1171
- * @typeParam T - The set or array type
1172
- */
1173
- type SetElementType<T> = T extends Set<infer U> ? U : T extends Array<infer U> ? U : never;
1174
- /**
1175
- * Type utility to get the element type from a path that points to a set.
1176
- * Combines PathType and SetElementType to get the element type at a specific path.
1177
- * @typeParam T - The type of the item
1178
- * @typeParam K - The path within the item
1179
- */
1180
- type PathSetElementType<T, K extends Path<T>> = SetElementType<PathType<T, K>>;
1181
- /**
1182
- * Builder for creating DynamoDB update operations.
1172
+ * Builder for creating and executing DynamoDB transactions.
1183
1173
  * Use this builder when you need to:
1184
- * - Modify existing items in DynamoDB
1185
- * - Update multiple attributes atomically
1186
- * - Perform conditional updates
1187
- * - Work with nested attributes
1188
- * - Update sets and lists
1174
+ * - Perform multiple operations atomically
1175
+ * - Ensure data consistency across operations
1176
+ * - Implement complex business logic that requires atomic updates
1177
+ * - Prevent duplicate items across tables
1189
1178
  *
1190
- * The builder supports all DynamoDB update operations:
1191
- * - SET: Modify or add attributes
1192
- * - REMOVE: Delete attributes
1193
- * - ADD: Update numbers and sets
1194
- * - DELETE: Remove elements from a set
1179
+ * The builder supports:
1180
+ * - Put operations (insert/replace items)
1181
+ * - Delete operations
1182
+ * - Update operations
1183
+ * - Condition checks
1184
+ * - Duplicate detection
1185
+ * - Transaction-wide options
1195
1186
  *
1196
1187
  * @example
1197
1188
  * ```typescript
1198
- * // Simple update
1199
- * const result = await new UpdateBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
1200
- * .set('status', 'HUNTING')
1201
- * .set('lastFed', new Date().toISOString())
1202
- * .execute();
1189
+ * // Create a transaction with multiple operations
1190
+ * const transaction = new TransactionBuilder(executor, {
1191
+ * partitionKey: 'id',
1192
+ * sortKey: 'type'
1193
+ * });
1203
1194
  *
1204
- * // Complex update with multiple operations
1205
- * const result = await new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
1206
- * .set({
1207
- * status: 'OCCUPIED',
1208
- * occupants: 3,
1209
- * 'metadata.lastInspection': new Date().toISOString()
1210
- * })
1211
- * .add('securityBreaches', 1)
1212
- * .deleteElementsFromSet('suitableDinosaurs', ['VELOCIRAPTOR'])
1213
- * .condition(op => op.gt('securityLevel', 8))
1214
- * .returnValues('ALL_NEW')
1215
- * .execute();
1195
+ * // Add a new order
1196
+ * transaction.put('orders', {
1197
+ * orderId: '123',
1198
+ * status: 'PENDING'
1199
+ * });
1200
+ *
1201
+ * // Update inventory with condition
1202
+ * transaction.update(
1203
+ * 'inventory',
1204
+ * { productId: 'ABC' },
1205
+ * 'set quantity = quantity - :amount',
1206
+ * { ':amount': 1 },
1207
+ * op => op.gte('quantity', 1)
1208
+ * );
1209
+ *
1210
+ * // Execute the transaction atomically
1211
+ * await transaction.execute();
1216
1212
  * ```
1217
1213
  *
1218
- * @typeParam T - The type of item being updated
1214
+ * Note: DynamoDB transactions have some limitations:
1215
+ * - Maximum 25 operations per transaction
1216
+ * - All operations must be in the same AWS region
1217
+ * - Cannot include table scans or queries
1219
1218
  */
1220
- declare class UpdateBuilder<T extends Record<string, unknown>> {
1221
- private updates;
1219
+ declare class TransactionBuilder {
1220
+ private items;
1222
1221
  private options;
1222
+ private indexConfig;
1223
1223
  private readonly executor;
1224
- private readonly tableName;
1225
- private readonly key;
1226
- constructor(executor: UpdateExecutor<T>, tableName: string, key: PrimaryKeyWithoutExpression);
1224
+ constructor(executor: TransactionExecutor, indexConfig: IndexConfig);
1227
1225
  /**
1228
- * Sets multiple attributes of an item using an object.
1226
+ * Checks if an item with the same primary key already exists in the transaction
1227
+ * @private
1228
+ */
1229
+ private checkForDuplicateItem;
1230
+ /**
1231
+ * Adds a put operation to the transaction.
1229
1232
  * Use this method when you need to:
1230
- * - Update multiple attributes at once
1231
- * - Set nested attribute values
1232
- * - Modify complex data structures
1233
+ * - Insert new items as part of a transaction
1234
+ * - Replace existing items atomically
1235
+ * - Ensure items meet certain conditions before insertion
1236
+ *
1237
+ * The method automatically checks for duplicate items within the transaction
1238
+ * to prevent multiple operations on the same item.
1233
1239
  *
1234
1240
  * @example
1235
1241
  * ```typescript
1236
- * // Update multiple attributes
1237
- * builder.set({
1238
- * species: 'Tyrannosaurus Rex',
1239
- * height: 20,
1240
- * diet: 'CARNIVORE',
1241
- * 'stats.threatLevel': 10
1242
+ * // Simple put operation
1243
+ * transaction.put('orders', {
1244
+ * orderId: '123',
1245
+ * status: 'PENDING',
1246
+ * amount: 100
1242
1247
  * });
1248
+ *
1249
+ * // Conditional put operation
1250
+ * transaction.put(
1251
+ * 'inventory',
1252
+ * { productId: 'ABC', quantity: 50 },
1253
+ * op => op.attributeNotExists('productId')
1254
+ * );
1255
+ *
1256
+ * // Put with complex condition
1257
+ * transaction.put(
1258
+ * 'users',
1259
+ * { userId: '123', status: 'ACTIVE' },
1260
+ * op => op.and([
1261
+ * op.attributeNotExists('userId'),
1262
+ * op.beginsWith('status', 'ACTIVE')
1263
+ * ])
1264
+ * );
1243
1265
  * ```
1266
+ *
1267
+ * @param tableName - The name of the DynamoDB table
1268
+ * @param item - The item to put into the table
1269
+ * @param condition - Optional condition that must be satisfied
1270
+ * @returns The transaction builder for method chaining
1271
+ * @throws {Error} If a duplicate item is detected in the transaction
1244
1272
  */
1245
- set(values: Partial<T>): UpdateBuilder<T>;
1273
+ put<T extends Record<string, unknown>>(tableName: string, item: T, condition?: Condition): TransactionBuilder;
1246
1274
  /**
1247
- * Sets a single attribute to a specific value.
1275
+ * Adds a pre-configured put operation to the transaction.
1248
1276
  * Use this method when you need to:
1249
- * - Update one attribute at a time
1250
- * - Set values with type safety
1251
- * - Update nested attributes
1277
+ * - Reuse put commands from PutBuilder
1278
+ * - Add complex put operations with pre-configured parameters
1279
+ * - Integrate with existing put command configurations
1280
+ *
1281
+ * This method is particularly useful when working with PutBuilder
1282
+ * to maintain consistency in put operations across your application.
1252
1283
  *
1253
1284
  * @example
1254
1285
  * ```typescript
1255
- * // Set simple attributes
1256
- * builder
1257
- * .set('status', 'SLEEPING')
1258
- * .set('lastFeeding', new Date().toISOString());
1286
+ * // Create a put command with PutBuilder
1287
+ * const putCommand = new PutBuilder(executor, newItem, 'users')
1288
+ * .condition(op => op.attributeNotExists('userId'))
1289
+ * .toDynamoCommand();
1259
1290
  *
1260
- * // Set nested attributes
1261
- * builder
1262
- * .set('location.zone', 'RESTRICTED')
1263
- * .set('stats.health', 100);
1291
+ * // Add the command to the transaction
1292
+ * transaction.putWithCommand(putCommand);
1264
1293
  * ```
1294
+ *
1295
+ * @param command - The complete put command configuration
1296
+ * @returns The transaction builder for method chaining
1297
+ * @throws {Error} If a duplicate item is detected in the transaction
1298
+ * @see PutBuilder for creating put commands
1265
1299
  */
1266
- set<K extends Path<T>>(path: K, value: PathType<T, K>): UpdateBuilder<T>;
1300
+ putWithCommand(command: PutCommandParams): TransactionBuilder;
1267
1301
  /**
1268
- * Removes an attribute from the item.
1302
+ * Adds a delete operation to the transaction.
1269
1303
  * Use this method when you need to:
1270
- * - Delete attributes completely
1271
- * - Remove nested attributes
1272
- * - Clean up deprecated fields
1304
+ * - Remove items as part of a transaction
1305
+ * - Conditionally delete items
1306
+ * - Ensure items exist before deletion
1307
+ *
1308
+ * The method automatically checks for duplicate items within the transaction
1309
+ * to prevent multiple operations on the same item.
1273
1310
  *
1274
1311
  * @example
1275
1312
  * ```typescript
1276
- * // Remove simple attributes
1277
- * builder
1278
- * .remove('temporaryTag')
1279
- * .remove('previousLocation');
1313
+ * // Simple delete operation
1314
+ * transaction.delete('orders', {
1315
+ * pk: 'ORDER#123',
1316
+ * sk: 'METADATA'
1317
+ * });
1280
1318
  *
1281
- * // Remove nested attributes
1282
- * builder
1283
- * .remove('metadata.testData')
1284
- * .remove('stats.experimentalMetrics');
1319
+ * // Conditional delete operation
1320
+ * transaction.delete(
1321
+ * 'users',
1322
+ * { pk: 'USER#123' },
1323
+ * op => op.eq('status', 'INACTIVE')
1324
+ * );
1325
+ *
1326
+ * // Delete with complex condition
1327
+ * transaction.delete(
1328
+ * 'products',
1329
+ * { pk: 'PROD#ABC' },
1330
+ * op => op.and([
1331
+ * op.eq('status', 'DRAFT'),
1332
+ * op.lt('version', 5)
1333
+ * ])
1334
+ * );
1285
1335
  * ```
1286
1336
  *
1287
- * @param path - The path to the attribute to remove
1288
- * @returns The builder instance for method chaining
1337
+ * @param tableName - The name of the DynamoDB table
1338
+ * @param key - The primary key of the item to delete
1339
+ * @param condition - Optional condition that must be satisfied
1340
+ * @returns The transaction builder for method chaining
1341
+ * @throws {Error} If a duplicate item is detected in the transaction
1289
1342
  */
1290
- remove<K extends Path<T>>(path: K): UpdateBuilder<T>;
1343
+ delete(tableName: string, key: PrimaryKeyWithoutExpression, condition?: Condition): TransactionBuilder;
1291
1344
  /**
1292
- * Adds a value to a number attribute or adds elements to a set.
1345
+ * Adds a pre-configured delete operation to the transaction.
1293
1346
  * Use this method when you need to:
1294
- * - Increment counters
1295
- * - Add elements to a set atomically
1296
- * - Update numerical statistics
1347
+ * - Reuse delete commands from DeleteBuilder
1348
+ * - Add complex delete operations with pre-configured parameters
1349
+ * - Integrate with existing delete command configurations
1350
+ *
1351
+ * This method is particularly useful when working with DeleteBuilder
1352
+ * to maintain consistency in delete operations across your application.
1297
1353
  *
1298
1354
  * @example
1299
1355
  * ```typescript
1300
- * // Increment counters
1301
- * builder
1302
- * .add('escapeAttempts', 1)
1303
- * .add('feedingCount', 1);
1356
+ * // Create a delete command with DeleteBuilder
1357
+ * const deleteCommand = new DeleteBuilder(executor, 'users', { pk: 'USER#123' })
1358
+ * .condition(op => op.and([
1359
+ * op.attributeExists('pk'),
1360
+ * op.eq('status', 'INACTIVE')
1361
+ * ]))
1362
+ * .toDynamoCommand();
1304
1363
  *
1305
- * // Add to sets
1306
- * builder
1307
- * .add('knownBehaviors', new Set(['PACK_HUNTING', 'AMBUSH_TACTICS']))
1308
- * .add('visitedZones', new Set(['ZONE_A', 'ZONE_B']));
1364
+ * // Add the command to the transaction
1365
+ * transaction.deleteWithCommand(deleteCommand);
1309
1366
  * ```
1310
1367
  *
1311
- * @param path - The path to the attribute to update
1312
- * @param value - The value to add (number or set)
1313
- * @returns The builder instance for method chaining
1368
+ * @param command - The complete delete command configuration
1369
+ * @returns The transaction builder for method chaining
1370
+ * @throws {Error} If a duplicate item is detected in the transaction
1371
+ * @see DeleteBuilder for creating delete commands
1314
1372
  */
1315
- add<K extends Path<T>>(path: K, value: PathType<T, K>): UpdateBuilder<T>;
1373
+ deleteWithCommand(command: DeleteCommandParams): TransactionBuilder;
1316
1374
  /**
1317
- * Removes elements from a set attribute.
1375
+ * Adds an update operation to the transaction.
1318
1376
  * Use this method when you need to:
1319
- * - Remove specific elements from a set
1320
- * - Update set-based attributes atomically
1321
- * - Maintain set membership
1377
+ * - Modify existing items as part of a transaction
1378
+ * - Update multiple attributes atomically
1379
+ * - Apply conditional updates
1380
+ * - Perform complex attribute manipulations
1381
+ *
1382
+ * The method supports all DynamoDB update expressions:
1383
+ * - SET: Modify or add attributes
1384
+ * - REMOVE: Delete attributes
1385
+ * - ADD: Update numbers and sets
1386
+ * - DELETE: Remove elements from a set
1322
1387
  *
1323
1388
  * @example
1324
1389
  * ```typescript
1325
- * // Remove from sets using arrays
1326
- * builder.deleteElementsFromSet(
1327
- * 'allowedHabitats',
1328
- * ['JUNGLE', 'COASTAL']
1390
+ * // Simple update
1391
+ * transaction.update(
1392
+ * 'orders',
1393
+ * { pk: 'ORDER#123' },
1394
+ * 'SET #status = :status',
1395
+ * { '#status': 'status' },
1396
+ * { ':status': 'PROCESSING' }
1329
1397
  * );
1330
1398
  *
1331
- * // Remove from sets using Set objects
1332
- * builder.deleteElementsFromSet(
1333
- * 'knownBehaviors',
1334
- * new Set(['NOCTURNAL', 'TERRITORIAL'])
1399
+ * // Complex update with multiple operations
1400
+ * transaction.update(
1401
+ * 'products',
1402
+ * { pk: 'PROD#ABC' },
1403
+ * 'SET #qty = #qty - :amount, #status = :status REMOVE #oldAttr',
1404
+ * { '#qty': 'quantity', '#status': 'status', '#oldAttr': 'deprecated_field' },
1405
+ * { ':amount': 1, ':status': 'LOW_STOCK' }
1335
1406
  * );
1336
1407
  *
1337
- * // Remove from nested sets
1338
- * builder.deleteElementsFromSet(
1339
- * 'stats.compatibleSpecies',
1340
- * ['VELOCIRAPTOR', 'DILOPHOSAURUS']
1408
+ * // Conditional update
1409
+ * transaction.update(
1410
+ * 'users',
1411
+ * { pk: 'USER#123' },
1412
+ * 'SET #lastLogin = :now',
1413
+ * { '#lastLogin': 'lastLoginDate' },
1414
+ * { ':now': new Date().toISOString() },
1415
+ * op => op.attributeExists('pk')
1341
1416
  * );
1342
1417
  * ```
1343
1418
  *
1344
- * @param path - The path to the set attribute
1345
- * @param value - Elements to remove (array or Set)
1346
- * @returns The builder instance for method chaining
1419
+ * @param tableName - The name of the DynamoDB table
1420
+ * @param key - The primary key of the item to update
1421
+ * @param updateExpression - The update expression (SET, REMOVE, ADD, DELETE)
1422
+ * @param expressionAttributeNames - Map of attribute name placeholders to actual names
1423
+ * @param expressionAttributeValues - Map of value placeholders to actual values
1424
+ * @param condition - Optional condition that must be satisfied
1425
+ * @returns The transaction builder for method chaining
1426
+ * @throws {Error} If a duplicate item is detected in the transaction
1347
1427
  */
1348
- deleteElementsFromSet<K extends Path<T>>(path: K, value: PathSetElementType<T, K>[] | Set<PathSetElementType<T, K>>): UpdateBuilder<T>;
1428
+ update<T extends Record<string, unknown>>(tableName: string, key: PrimaryKeyWithoutExpression, updateExpression: string, expressionAttributeNames?: Record<string, string>, expressionAttributeValues?: Record<string, unknown>, condition?: Condition): TransactionBuilder;
1349
1429
  /**
1350
- * Adds a condition that must be satisfied for the update to succeed.
1430
+ * Adds a pre-configured update operation to the transaction.
1351
1431
  * Use this method when you need to:
1352
- * - Implement optimistic locking
1353
- * - Ensure item state before update
1354
- * - Validate business rules
1355
- * - Prevent concurrent modifications
1432
+ * - Reuse update commands from UpdateBuilder
1433
+ * - Add complex update operations with pre-configured parameters
1434
+ * - Integrate with existing update command configurations
1435
+ *
1436
+ * This method is particularly useful when working with UpdateBuilder
1437
+ * to maintain consistency in update operations across your application.
1356
1438
  *
1357
1439
  * @example
1358
1440
  * ```typescript
1359
- * // Simple condition
1360
- * builder.condition(op =>
1361
- * op.eq('status', 'ACTIVE')
1362
- * );
1441
+ * // Create an update command with UpdateBuilder
1442
+ * const updateCommand = new UpdateBuilder(executor, 'inventory', { pk: 'PROD#ABC' })
1443
+ * .set('quantity', ':qty')
1444
+ * .set('lastUpdated', ':now')
1445
+ * .values({
1446
+ * ':qty': 100,
1447
+ * ':now': new Date().toISOString()
1448
+ * })
1449
+ * .condition(op => op.gt('quantity', 0))
1450
+ * .toDynamoCommand();
1363
1451
  *
1364
- * // Health check condition
1365
- * builder.condition(op =>
1366
- * op.and([
1367
- * op.gt('health', 50),
1368
- * op.eq('status', 'HUNTING')
1369
- * ])
1452
+ * // Add the command to the transaction
1453
+ * transaction.updateWithCommand(updateCommand);
1454
+ * ```
1455
+ *
1456
+ * @param command - The complete update command configuration
1457
+ * @returns The transaction builder for method chaining
1458
+ * @throws {Error} If a duplicate item is detected in the transaction
1459
+ * @see UpdateBuilder for creating update commands
1460
+ */
1461
+ updateWithCommand(command: UpdateCommandParams): TransactionBuilder;
1462
+ /**
1463
+ * Adds a condition check operation to the transaction.
1464
+ * Use this method when you need to:
1465
+ * - Validate item state without modifying it
1466
+ * - Ensure data consistency across tables
1467
+ * - Implement complex business rules
1468
+ * - Verify preconditions for other operations
1469
+ *
1470
+ * Condition checks are particularly useful for:
1471
+ * - Implementing optimistic locking
1472
+ * - Ensuring referential integrity
1473
+ * - Validating business rules atomically
1474
+ *
1475
+ * @example
1476
+ * ```typescript
1477
+ * // Check if order is in correct state
1478
+ * transaction.conditionCheck(
1479
+ * 'orders',
1480
+ * { pk: 'ORDER#123' },
1481
+ * op => op.eq('status', 'PENDING')
1370
1482
  * );
1371
1483
  *
1372
- * // Complex security condition
1373
- * builder.condition(op =>
1374
- * op.and([
1375
- * op.attributeExists('securitySystem'),
1376
- * op.eq('containmentStatus', 'SECURE'),
1377
- * op.lt('aggressionLevel', 8)
1484
+ * // Complex condition check
1485
+ * transaction.conditionCheck(
1486
+ * 'inventory',
1487
+ * { pk: 'PROD#ABC' },
1488
+ * op => op.and([
1489
+ * op.gt('quantity', 0),
1490
+ * op.eq('status', 'ACTIVE'),
1491
+ * op.attributeExists('lastRestockDate')
1378
1492
  * ])
1379
1493
  * );
1380
1494
  *
1381
- * // Version check (optimistic locking)
1382
- * builder.condition(op =>
1383
- * op.eq('version', currentVersion)
1495
+ * // Check with multiple attributes
1496
+ * transaction.conditionCheck(
1497
+ * 'users',
1498
+ * { pk: 'USER#123' },
1499
+ * op => op.or([
1500
+ * op.eq('status', 'PREMIUM'),
1501
+ * op.gte('credits', 100)
1502
+ * ])
1384
1503
  * );
1385
1504
  * ```
1386
1505
  *
1387
- * @param condition - Either a Condition object or a callback function that builds the condition
1388
- * @returns The builder instance for method chaining
1506
+ * @param tableName - The name of the DynamoDB table
1507
+ * @param key - The primary key of the item to check
1508
+ * @param condition - The condition that must be satisfied
1509
+ * @returns The transaction builder for method chaining
1510
+ * @throws {Error} If a duplicate item is detected in the transaction
1511
+ * @throws {Error} If condition expression generation fails
1389
1512
  */
1390
- condition(condition: Condition | ((op: ConditionOperator<T>) => Condition)): UpdateBuilder<T>;
1513
+ conditionCheck(tableName: string, key: PrimaryKeyWithoutExpression, condition: Condition): TransactionBuilder;
1391
1514
  /**
1392
- * Sets which item attributes to include in the response.
1515
+ * Adds a pre-configured condition check operation to the transaction.
1393
1516
  * Use this method when you need to:
1394
- * - Get the complete updated item
1395
- * - Track changes to specific attributes
1396
- * - Compare old and new values
1397
- * - Monitor attribute modifications
1517
+ * - Reuse condition checks from ConditionCheckBuilder
1518
+ * - Add complex condition checks with pre-configured parameters
1519
+ * - Integrate with existing condition check configurations
1398
1520
  *
1399
- * Available options:
1400
- * - ALL_NEW: All attributes after the update
1401
- * - UPDATED_NEW: Only updated attributes, new values
1402
- * - ALL_OLD: All attributes before the update
1403
- * - UPDATED_OLD: Only updated attributes, old values
1404
- * - NONE: No attributes returned (default)
1521
+ * This method is particularly useful when working with ConditionCheckBuilder
1522
+ * to maintain consistency in condition checks across your application.
1405
1523
  *
1406
1524
  * @example
1407
1525
  * ```typescript
1408
- * // Get complete updated dinosaur
1409
- * const result = await builder
1410
- * .set('status', 'SLEEPING')
1411
- * .returnValues('ALL_NEW')
1412
- * .execute();
1413
- *
1414
- * // Track specific attribute changes
1415
- * const result = await builder
1416
- * .set({
1417
- * 'stats.health': 100,
1418
- * 'stats.energy': 95
1419
- * })
1420
- * .returnValues('UPDATED_OLD')
1421
- * .execute();
1526
+ * // Create a condition check with ConditionCheckBuilder
1527
+ * const checkCommand = new ConditionCheckBuilder('inventory', { pk: 'PROD#ABC' })
1528
+ * .condition(op => op.and([
1529
+ * op.between('quantity', 10, 100),
1530
+ * op.beginsWith('category', 'ELECTRONICS'),
1531
+ * op.attributeExists('lastAuditDate')
1532
+ * ]))
1533
+ * .toDynamoCommand();
1422
1534
  *
1423
- * if (result.item) {
1424
- * console.log('Previous health:', result.item.stats?.health);
1425
- * }
1535
+ * // Add the command to the transaction
1536
+ * transaction.conditionCheckWithCommand(checkCommand);
1426
1537
  * ```
1427
1538
  *
1428
- * @param returnValues - Which attributes to return in the response
1429
- * @returns The builder instance for method chaining
1430
- */
1431
- returnValues(returnValues: "ALL_NEW" | "UPDATED_NEW" | "ALL_OLD" | "UPDATED_OLD" | "NONE"): UpdateBuilder<T>;
1432
- /**
1433
- * Generate the DynamoDB command parameters
1539
+ * @param command - The complete condition check command configuration
1540
+ * @returns The transaction builder for method chaining
1541
+ * @throws {Error} If a duplicate item is detected in the transaction
1542
+ * @see ConditionCheckBuilder for creating condition check commands
1434
1543
  */
1435
- toDynamoCommand(): UpdateCommandParams;
1544
+ conditionCheckWithCommand(command: ConditionCheckCommandParams): TransactionBuilder;
1436
1545
  /**
1437
- * Adds this update operation to a transaction.
1546
+ * Sets options for the transaction execution.
1438
1547
  * Use this method when you need to:
1439
- * - Update items as part of a larger transaction
1440
- * - Ensure multiple updates are atomic
1441
- * - Coordinate updates across multiple items
1548
+ * - Enable idempotent transactions
1549
+ * - Track consumed capacity
1550
+ * - Monitor item collection metrics
1442
1551
  *
1443
1552
  * @example
1444
1553
  * ```typescript
1445
- * const transaction = new TransactionBuilder(executor);
1446
- *
1447
- * // Update dinosaur status and habitat occupancy atomically
1448
- * new UpdateBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
1449
- * .set('location', 'PADDOCK_A')
1450
- * .set('status', 'CONTAINED')
1451
- * .withTransaction(transaction);
1452
- *
1453
- * new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
1454
- * .add('occupants', 1)
1455
- * .set('lastOccupied', new Date().toISOString())
1456
- * .withTransaction(transaction);
1554
+ * // Enable idempotency and capacity tracking
1555
+ * transaction.withOptions({
1556
+ * clientRequestToken: 'unique-request-id-123',
1557
+ * returnConsumedCapacity: 'TOTAL'
1558
+ * });
1457
1559
  *
1458
- * // Execute all operations atomically
1459
- * await transaction.execute();
1560
+ * // Track item collection metrics
1561
+ * transaction.withOptions({
1562
+ * returnItemCollectionMetrics: 'SIZE'
1563
+ * });
1460
1564
  * ```
1461
1565
  *
1462
- * @param transaction - The transaction builder to add this operation to
1463
- * @returns The builder instance for method chaining
1566
+ * Note: ClientRequestToken can be used to make transactions idempotent,
1567
+ * ensuring the same transaction is not executed multiple times.
1568
+ *
1569
+ * @param options - Configuration options for the transaction
1570
+ * @returns The transaction builder for method chaining
1464
1571
  */
1465
- withTransaction(transaction: TransactionBuilder): void;
1572
+ withOptions(options: TransactionOptions): TransactionBuilder;
1466
1573
  /**
1467
- * Gets a human-readable representation of the update command.
1574
+ * Gets a human-readable representation of the transaction items.
1468
1575
  * Use this method when you need to:
1469
- * - Debug complex update expressions
1470
- * - Verify attribute names and values
1471
- * - Log update operations
1576
+ * - Debug complex transactions
1577
+ * - Verify operation parameters
1578
+ * - Log transaction details
1472
1579
  * - Troubleshoot condition expressions
1473
1580
  *
1581
+ * The method resolves all expression placeholders with their actual values,
1582
+ * making it easier to understand the transaction's operations.
1583
+ *
1474
1584
  * @example
1475
1585
  * ```typescript
1476
- * // Create complex update
1477
- * const builder = new UpdateBuilder(executor, 'dinosaurs', { id: 'RAPTOR-001' })
1478
- * .set({
1479
- * status: 'HUNTING',
1480
- * 'stats.health': 95,
1481
- * 'behavior.lastObserved': new Date().toISOString()
1482
- * })
1483
- * .add('huntingSuccesses', 1)
1484
- * .condition(op => op.gt('health', 50));
1586
+ * // Add multiple operations
1587
+ * transaction
1588
+ * .put('orders', { orderId: '123', status: 'PENDING' })
1589
+ * .update('inventory',
1590
+ * { productId: 'ABC' },
1591
+ * 'SET quantity = quantity - :amount',
1592
+ * undefined,
1593
+ * { ':amount': 1 }
1594
+ * );
1485
1595
  *
1486
- * // Debug the update
1487
- * const debugInfo = builder.debug();
1488
- * console.log('Update operation:', debugInfo);
1596
+ * // Debug the transaction
1597
+ * const debugInfo = transaction.debug();
1598
+ * console.log('Transaction operations:', debugInfo);
1489
1599
  * ```
1490
1600
  *
1491
- * @returns A readable representation of the update command with resolved expressions
1601
+ * @returns An array of readable representations of the transaction items
1492
1602
  */
1493
- debug(): Record<string, unknown>;
1603
+ debug(): Record<string, unknown>[];
1494
1604
  /**
1495
- * Executes the update operation against DynamoDB.
1605
+ * Executes all operations in the transaction atomically.
1496
1606
  * Use this method when you need to:
1497
- * - Apply updates immediately
1498
- * - Get the updated item values
1499
- * - Handle conditional update failures
1607
+ * - Perform multiple operations atomically
1608
+ * - Ensure all-or-nothing execution
1609
+ * - Maintain data consistency across operations
1610
+ *
1611
+ * The transaction will only succeed if all operations succeed.
1612
+ * If any operation fails, the entire transaction is rolled back.
1500
1613
  *
1501
1614
  * @example
1502
1615
  * ```typescript
1503
1616
  * try {
1504
- * // Update dinosaur status with conditions
1505
- * const result = await new UpdateBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
1506
- * .set({
1507
- * status: 'FEEDING',
1508
- * lastMeal: new Date().toISOString(),
1509
- * 'stats.hunger': 0
1510
- * })
1511
- * .add('feedingCount', 1)
1512
- * .condition(op =>
1513
- * op.and([
1514
- * op.gt('stats.hunger', 80),
1515
- * op.eq('status', 'HUNTING')
1516
- * ])
1617
+ * // Build and execute transaction
1618
+ * await transaction
1619
+ * .put('orders', newOrder)
1620
+ * .update('inventory',
1621
+ * { productId: 'ABC' },
1622
+ * 'SET quantity = quantity - :qty',
1623
+ * undefined,
1624
+ * { ':qty': 1 }
1625
+ * )
1626
+ * .conditionCheck('products',
1627
+ * { productId: 'ABC' },
1628
+ * op => op.eq('status', 'ACTIVE')
1517
1629
  * )
1518
- * .returnValues('ALL_NEW')
1519
1630
  * .execute();
1520
1631
  *
1521
- * if (result.item) {
1522
- * console.log('Updated dinosaur:', result.item);
1523
- * }
1632
+ * console.log('Transaction completed successfully');
1524
1633
  * } catch (error) {
1525
- * // Handle condition check failure
1526
- * console.error('Failed to update dinosaur:', error);
1527
- * // Check if dinosaur wasn't hungry enough
1528
- * if (error.name === 'ConditionalCheckFailedException') {
1529
- * console.log('Dinosaur not ready for feeding');
1530
- * }
1634
+ * // Handle transaction failure
1635
+ * console.error('Transaction failed:', error);
1531
1636
  * }
1532
1637
  * ```
1533
1638
  *
1534
- * @returns A promise that resolves to an object containing the updated item (if returnValues is set)
1535
- * @throws {ConditionalCheckFailedException} If the condition check fails
1536
- * @throws {Error} If the update operation fails for other reasons
1639
+ * @throws {Error} If no transaction items are specified
1640
+ * @throws {Error} If any operation in the transaction fails
1641
+ * @returns A promise that resolves when the transaction completes
1537
1642
  */
1538
- execute(): Promise<{
1539
- item?: T;
1540
- }>;
1643
+ execute(): Promise<void>;
1541
1644
  }
1542
1645
 
1543
- interface DeleteCommandParams extends DynamoCommandWithExpressions {
1544
- tableName: string;
1545
- key: PrimaryKeyWithoutExpression;
1546
- conditionExpression?: string;
1547
- expressionAttributeNames?: Record<string, string>;
1548
- expressionAttributeValues?: Record<string, unknown>;
1549
- returnValues?: "ALL_OLD";
1646
+ /**
1647
+ * Configuration options for DynamoDB put operations.
1648
+ */
1649
+ interface PutOptions {
1650
+ /** Optional condition that must be satisfied for the put operation to succeed */
1651
+ condition?: Condition;
1652
+ /** Determines how to handle the return value of the put operation
1653
+ * @options
1654
+ * - NONE: No return value
1655
+ * - ALL_OLD: Returns the item's previous state if it existed
1656
+ * - CONSISTENT: (default) Performs a GET operation after the put to retrieve the item's new state
1657
+ */
1658
+ returnValues?: "ALL_OLD" | "NONE" | "CONSISTENT";
1550
1659
  }
1551
- type DeleteExecutor = (params: DeleteCommandParams) => Promise<{
1552
- item?: Record<string, unknown>;
1553
- }>;
1660
+ type PutExecutor<T extends Record<string, unknown>> = (params: PutCommandParams) => Promise<T>;
1554
1661
  /**
1555
- * Builder for creating DynamoDB delete operations.
1556
- * Use this builder when you need to:
1557
- * - Remove dinosaurs from the registry
1558
- * - Clean up abandoned habitats
1559
- * - Delete historical tracking data
1560
- * - Remove deprecated classifications
1662
+ * Builder for creating DynamoDB put operations.
1561
1663
  *
1562
1664
  * @example
1563
1665
  * ```typescript
1564
- * // Simple delete
1565
- * const result = await new DeleteBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
1566
- * .execute();
1666
+ * // Add new dinosaur
1667
+ * const result = await new PutBuilder(executor, {
1668
+ * id: 'RAPTOR-001',
1669
+ * species: 'Velociraptor',
1670
+ * status: 'ACTIVE',
1671
+ * stats: {
1672
+ * health: 100,
1673
+ * age: 5,
1674
+ * threatLevel: 8
1675
+ * }
1676
+ * }, 'dinosaurs').execute();
1567
1677
  *
1568
- * // Conditional delete with old value retrieval
1569
- * const result = await new DeleteBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
1570
- * .condition(op =>
1571
- * op.and([
1572
- * op.eq('status', 'DECOMMISSIONED'),
1573
- * op.eq('occupants', 0),
1574
- * op.lt('securityIncidents', 1)
1575
- * ])
1576
- * )
1577
- * .returnValues('ALL_OLD')
1678
+ * // Create new habitat with conditions
1679
+ * const result = await new PutBuilder(executor, {
1680
+ * id: 'PADDOCK-C',
1681
+ * type: 'CARNIVORE',
1682
+ * securityLevel: 'MAXIMUM',
1683
+ * capacity: 3,
1684
+ * environmentType: 'TROPICAL'
1685
+ * }, 'habitats')
1686
+ * .condition(op => op.attributeNotExists('id'))
1578
1687
  * .execute();
1579
1688
  * ```
1689
+ *
1690
+ * @typeParam T - The type of item being put into the table
1580
1691
  */
1581
- declare class DeleteBuilder {
1692
+ declare class PutBuilder<T extends Record<string, unknown>> {
1693
+ private readonly item;
1582
1694
  private options;
1583
1695
  private readonly executor;
1584
1696
  private readonly tableName;
1585
- private readonly key;
1586
- constructor(executor: DeleteExecutor, tableName: string, key: PrimaryKeyWithoutExpression);
1697
+ constructor(executor: PutExecutor<T>, item: T, tableName: string);
1587
1698
  /**
1588
- * Adds a condition that must be satisfied for the delete operation to succeed.
1699
+ * Adds a condition that must be satisfied for the put operation to succeed.
1589
1700
  * Use this method when you need to:
1590
- * - Ensure safe removal conditions
1591
- * - Verify habitat status before deletion
1592
- * - Implement safety protocols
1701
+ * - Prevent overwriting existing items (optimistic locking)
1702
+ * - Ensure items meet certain criteria before replacement
1703
+ * - Implement complex business rules for item updates
1704
+ *
1705
+ * @example
1706
+ * ```ts
1707
+ * // Ensure item doesn't exist (insert only)
1708
+ * builder.condition(op => op.attributeNotExists('id'))
1709
+ *
1710
+ * // Complex condition with version check
1711
+ * builder.condition(op =>
1712
+ * op.and([
1713
+ * op.attributeExists('id'),
1714
+ * op.eq('version', currentVersion),
1715
+ * op.eq('status', 'ACTIVE')
1716
+ * ])
1717
+ * )
1718
+ * ```
1719
+ *
1720
+ * @param condition - Either a Condition object or a callback function that builds the condition
1721
+ * @returns The builder instance for method chaining
1722
+ */
1723
+ /**
1724
+ * Adds a condition that must be satisfied for the put operation to succeed.
1593
1725
  *
1594
1726
  * @example
1595
1727
  * ```typescript
1596
- * // Ensure dinosaur can be safely removed
1728
+ * // Ensure unique dinosaur ID
1729
+ * builder.condition(op =>
1730
+ * op.attributeNotExists('id')
1731
+ * );
1732
+ *
1733
+ * // Verify habitat requirements
1597
1734
  * builder.condition(op =>
1598
1735
  * op.and([
1599
- * op.eq('status', 'SEDATED'),
1600
- * op.eq('location', 'MEDICAL_BAY'),
1601
- * op.attributeExists('lastCheckup')
1736
+ * op.eq('securityStatus', 'READY'),
1737
+ * op.attributeExists('lastInspection'),
1738
+ * op.gt('securityLevel', 5)
1602
1739
  * ])
1603
1740
  * );
1604
1741
  *
1605
- * // Verify habitat is empty
1742
+ * // Check breeding facility conditions
1606
1743
  * builder.condition(op =>
1607
1744
  * op.and([
1608
- * op.eq('occupants', 0),
1609
- * op.eq('maintenanceStatus', 'COMPLETE'),
1610
- * op.not(op.attributeExists('activeAlerts'))
1745
+ * op.between('temperature', 25, 30),
1746
+ * op.between('humidity', 60, 80),
1747
+ * op.eq('quarantineStatus', 'CLEAR')
1611
1748
  * ])
1612
1749
  * );
1613
1750
  * ```
@@ -1615,57 +1752,66 @@ declare class DeleteBuilder {
1615
1752
  * @param condition - Either a Condition object or a callback function that builds the condition
1616
1753
  * @returns The builder instance for method chaining
1617
1754
  */
1618
- condition<T extends Record<string, unknown>>(condition: Condition | ((op: ConditionOperator<T>) => Condition)): DeleteBuilder;
1755
+ condition(condition: Condition | ((op: ConditionOperator<T>) => Condition)): this;
1619
1756
  /**
1620
- * Sets whether to return the item's attribute values before deletion.
1621
- * Use this method when you need to:
1622
- * - Archive removed dinosaur data
1623
- * - Track habitat decommissioning history
1624
- * - Maintain removal audit logs
1757
+ * Sets whether to return the item's previous values (if it existed).
1758
+ *
1759
+ * @options
1760
+ * - NONE: No return value
1761
+ * - ALL_OLD: Returns the item's previous state if it existed, no read capacity units are consumed
1762
+ * - CONSISTENT: (default) Performs a GET operation after the put to retrieve the item's new state
1625
1763
  *
1626
1764
  * @example
1627
1765
  * ```ts
1628
- * // Archive dinosaur data before removal
1766
+ * // Get previous dinosaur state
1629
1767
  * const result = await builder
1630
1768
  * .returnValues('ALL_OLD')
1631
1769
  * .execute();
1632
1770
  *
1633
- * if (result.item) {
1634
- * console.log('Removed dinosaur data:', {
1635
- * species: result.item.species,
1636
- * age: result.item.age,
1637
- * lastLocation: result.item.location
1771
+ * if (result) {
1772
+ * console.log('Previous profile:', {
1773
+ * species: result.species,
1774
+ * status: result.status,
1775
+ * stats: {
1776
+ * health: result.stats.health,
1777
+ * threatLevel: result.stats.threatLevel
1778
+ * }
1638
1779
  * });
1639
1780
  * }
1640
1781
  * ```
1641
1782
  *
1642
- * @param returnValues - Use 'ALL_OLD' to return all attributes of the deleted item
1783
+ * @param returnValues - Use 'ALL_OLD' to return previous values if the item was overwritten, or 'NONE' (default).
1643
1784
  * @returns The builder instance for method chaining
1644
1785
  */
1645
- returnValues(returnValues: "ALL_OLD"): DeleteBuilder;
1786
+ returnValues(returnValues: "ALL_OLD" | "NONE" | "CONSISTENT"): this;
1646
1787
  /**
1647
1788
  * Generate the DynamoDB command parameters
1648
1789
  */
1649
1790
  private toDynamoCommand;
1650
1791
  /**
1651
- * Adds this delete operation to a transaction.
1792
+ * Adds this put operation to a transaction.
1652
1793
  * Use this method when you need to:
1653
- * - Coordinate dinosaur transfers
1654
- * - Manage habitat decommissioning
1655
- * - Handle species relocations
1794
+ * - Transfer dinosaurs between habitats
1795
+ * - Initialize new breeding programs
1796
+ * - Update multiple facility records
1656
1797
  *
1657
1798
  * @example
1658
1799
  * ```ts
1659
1800
  * const transaction = new TransactionBuilder();
1660
1801
  *
1661
- * // Remove dinosaur from old habitat
1662
- * new DeleteBuilder(executor, 'dinosaurs', { id: 'RAPTOR-001' })
1663
- * .condition(op => op.eq('status', 'SEDATED'))
1664
- * .withTransaction(transaction);
1665
- *
1666
- * // Update old habitat occupancy
1667
- * new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
1668
- * .add('occupants', -1)
1802
+ * // Add dinosaur to new habitat
1803
+ * new PutBuilder(executor, {
1804
+ * id: 'TREX-002',
1805
+ * location: 'PADDOCK-B',
1806
+ * status: 'ACTIVE',
1807
+ * transferDate: new Date().toISOString()
1808
+ * }, 'dinosaurs')
1809
+ * .withTransaction(transaction);
1810
+ *
1811
+ * // Update habitat records
1812
+ * new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-B' })
1813
+ * .add('occupants', 1)
1814
+ * .set('lastTransfer', new Date().toISOString())
1669
1815
  * .withTransaction(transaction);
1670
1816
  *
1671
1817
  * // Execute transfer atomically
@@ -1673,136 +1819,129 @@ declare class DeleteBuilder {
1673
1819
  * ```
1674
1820
  *
1675
1821
  * @param transaction - The transaction builder to add this operation to
1822
+ * @returns The builder instance for method chaining
1676
1823
  */
1677
- withTransaction(transaction: TransactionBuilder): void;
1824
+ withTransaction(transaction: TransactionBuilder): this;
1678
1825
  /**
1679
- * Executes the delete operation against DynamoDB.
1826
+ * Executes the put operation against DynamoDB.
1680
1827
  *
1681
1828
  * @example
1682
1829
  * ```ts
1683
- * // Delete with condition and retrieve old values
1684
- * const result = await new DeleteBuilder(executor, 'myTable', { id: '123' })
1685
- * .condition(op => op.eq('status', 'INACTIVE'))
1686
- * .returnValues('ALL_OLD')
1687
- * .execute();
1830
+ * try {
1831
+ * // Put with condition and return old values
1832
+ * const result = await new PutBuilder(executor, newItem, 'myTable')
1833
+ * .condition(op => op.eq('version', 1))
1834
+ * .returnValues('ALL_OLD')
1835
+ * .execute();
1688
1836
  *
1689
- * if (result.item) {
1690
- * console.log('Deleted item:', result.item);
1837
+ * console.log('Put successful, old item:', result);
1838
+ * } catch (error) {
1839
+ * // Handle condition check failure or other errors
1840
+ * console.error('Put failed:', error);
1691
1841
  * }
1692
1842
  * ```
1693
1843
  *
1694
- * @returns A promise that resolves to an object containing the deleted item's attributes (if returnValues is 'ALL_OLD')
1844
+ * @returns A promise that resolves to the operation result (type depends on returnValues setting)
1845
+ * @throws Will throw an error if the condition check fails or other DynamoDB errors occur
1695
1846
  */
1696
- execute(): Promise<{
1697
- item?: Record<string, unknown>;
1698
- }>;
1847
+ execute(): Promise<T | undefined>;
1699
1848
  /**
1700
- * Gets a human-readable representation of the delete command
1849
+ * Gets a human-readable representation of the put command
1701
1850
  * with all expression placeholders replaced by their actual values.
1702
- * Use this method when you need to:
1703
- * - Debug complex deletion conditions
1704
- * - Verify safety checks
1705
- * - Log removal operations
1706
- * - Troubleshoot failed deletions
1707
1851
  *
1708
1852
  * @example
1709
1853
  * ```ts
1710
- * const debugInfo = new DeleteBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
1711
- * .condition(op => op.and([
1712
- * op.eq('status', 'SEDATED'),
1713
- * op.eq('location', 'MEDICAL_BAY'),
1714
- * op.gt('sedationLevel', 8)
1715
- * op.eq('version', 1),
1716
- * op.attributeExists('status')
1717
- * ]))
1854
+ * const debugInfo = new PutBuilder(executor, {
1855
+ * id: 'RAPTOR-003',
1856
+ * species: 'Velociraptor',
1857
+ * status: 'QUARANTINE',
1858
+ * stats: {
1859
+ * health: 100,
1860
+ * aggressionLevel: 7,
1861
+ * age: 2
1862
+ * }
1863
+ * }, 'dinosaurs')
1864
+ * .condition(op =>
1865
+ * op.and([
1866
+ * op.attributeNotExists('id'),
1867
+ * op.eq('quarantineStatus', 'READY'),
1868
+ * op.gt('securityLevel', 8)
1869
+ * ])
1870
+ * )
1718
1871
  * .debug();
1719
1872
  *
1720
- * console.log('Delete command:', debugInfo);
1873
+ * console.log('Dinosaur transfer command:', debugInfo);
1721
1874
  * ```
1722
1875
  *
1723
- * @returns A readable representation of the delete command with resolved expressions
1876
+ * @returns A readable representation of the put command with resolved expressions
1724
1877
  */
1725
1878
  debug(): Record<string, unknown>;
1726
1879
  }
1727
1880
 
1728
- interface ConditionCheckCommandParams extends DynamoCommandWithExpressions {
1729
- tableName: string;
1730
- key: PrimaryKeyWithoutExpression;
1731
- conditionExpression: string;
1732
- expressionAttributeNames?: Record<string, string>;
1733
- expressionAttributeValues?: Record<string, unknown>;
1881
+ interface DeleteOptions {
1882
+ condition?: Condition;
1883
+ returnValues?: "ALL_OLD";
1734
1884
  }
1885
+ type DeleteExecutor = (params: DeleteCommandParams) => Promise<{
1886
+ item?: Record<string, unknown>;
1887
+ }>;
1735
1888
  /**
1736
- * Builder for creating DynamoDB condition check operations.
1889
+ * Builder for creating DynamoDB delete operations.
1737
1890
  * Use this builder when you need to:
1738
- * - Verify item state without modifying it
1739
- * - Ensure preconditions in transactions
1740
- * - Implement optimistic locking patterns
1741
- * - Validate business rules
1891
+ * - Remove dinosaurs from the registry
1892
+ * - Clean up abandoned habitats
1893
+ * - Delete historical tracking data
1894
+ * - Remove deprecated classifications
1742
1895
  *
1743
1896
  * @example
1744
1897
  * ```typescript
1745
- * // Check if dinosaur is ready for feeding
1746
- * const check = new ConditionCheckBuilder('dinosaurs', { id: 'TREX-001' })
1747
- * .condition(op =>
1748
- * op.and([
1749
- * op.eq('status', 'HUNTING'),
1750
- * op.gt('stats.hunger', 80),
1751
- * op.lt('stats.health', 100)
1752
- * ])
1753
- * )
1754
- * .toDynamoCommand();
1898
+ * // Simple delete
1899
+ * const result = await new DeleteBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
1900
+ * .execute();
1755
1901
  *
1756
- * // Check habitat security status
1757
- * const securityCheck = new ConditionCheckBuilder('habitats', { id: 'PADDOCK-A' })
1902
+ * // Conditional delete with old value retrieval
1903
+ * const result = await new DeleteBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
1758
1904
  * .condition(op =>
1759
1905
  * op.and([
1760
- * op.eq('securityStatus', 'ACTIVE'),
1761
- * op.attributeExists('lastInspection'),
1762
- * op.lt('threatLevel', 5)
1906
+ * op.eq('status', 'DECOMMISSIONED'),
1907
+ * op.eq('occupants', 0),
1908
+ * op.lt('securityIncidents', 1)
1763
1909
  * ])
1764
1910
  * )
1765
- * .toDynamoCommand();
1911
+ * .returnValues('ALL_OLD')
1912
+ * .execute();
1766
1913
  * ```
1767
1914
  */
1768
- declare class ConditionCheckBuilder {
1769
- private readonly key;
1915
+ declare class DeleteBuilder {
1916
+ private options;
1917
+ private readonly executor;
1770
1918
  private readonly tableName;
1771
- private conditionExpression?;
1772
- constructor(tableName: string, key: PrimaryKeyWithoutExpression);
1919
+ private readonly key;
1920
+ constructor(executor: DeleteExecutor, tableName: string, key: PrimaryKeyWithoutExpression);
1773
1921
  /**
1774
- * Adds a condition that must be satisfied for the check to succeed.
1922
+ * Adds a condition that must be satisfied for the delete operation to succeed.
1775
1923
  * Use this method when you need to:
1776
- * - Validate complex item states
1777
- * - Check multiple attributes together
1778
- * - Ensure safety conditions are met
1924
+ * - Ensure safe removal conditions
1925
+ * - Verify habitat status before deletion
1926
+ * - Implement safety protocols
1779
1927
  *
1780
1928
  * @example
1781
1929
  * ```typescript
1782
- * // Check dinosaur health and behavior
1783
- * builder.condition(op =>
1784
- * op.and([
1785
- * op.gt('stats.health', 50),
1786
- * op.not(op.eq('status', 'SEDATED')),
1787
- * op.lt('aggressionLevel', 8)
1788
- * ])
1789
- * );
1790
- *
1791
- * // Verify habitat conditions
1930
+ * // Ensure dinosaur can be safely removed
1792
1931
  * builder.condition(op =>
1793
1932
  * op.and([
1794
- * op.eq('powerStatus', 'ONLINE'),
1795
- * op.between('temperature', 20, 30),
1796
- * op.attributeExists('lastMaintenance')
1933
+ * op.eq('status', 'SEDATED'),
1934
+ * op.eq('location', 'MEDICAL_BAY'),
1935
+ * op.attributeExists('lastCheckup')
1797
1936
  * ])
1798
1937
  * );
1799
1938
  *
1800
- * // Check breeding conditions
1939
+ * // Verify habitat is empty
1801
1940
  * builder.condition(op =>
1802
1941
  * op.and([
1803
- * op.eq('species', 'VELOCIRAPTOR'),
1804
- * op.gte('age', 3),
1805
- * op.eq('geneticPurity', 100)
1942
+ * op.eq('occupants', 0),
1943
+ * op.eq('maintenanceStatus', 'COMPLETE'),
1944
+ * op.not(op.attributeExists('activeAlerts'))
1806
1945
  * ])
1807
1946
  * );
1808
1947
  * ```
@@ -1810,689 +1949,602 @@ declare class ConditionCheckBuilder {
1810
1949
  * @param condition - Either a Condition object or a callback function that builds the condition
1811
1950
  * @returns The builder instance for method chaining
1812
1951
  */
1813
- condition<T extends Record<string, unknown>>(condition: Condition | ((op: ConditionOperator<T>) => Condition)): ConditionCheckBuilder;
1952
+ condition<T extends Record<string, unknown>>(condition: Condition | ((op: ConditionOperator<T>) => Condition)): DeleteBuilder;
1814
1953
  /**
1815
- * Generates the DynamoDB command parameters for direct execution.
1816
- * Use this method when you want to:
1817
- * - Execute the condition check as a standalone operation
1818
- * - Get the raw DynamoDB command for custom execution
1819
- * - Inspect the generated command parameters
1954
+ * Sets whether to return the item's attribute values before deletion.
1955
+ * Use this method when you need to:
1956
+ * - Archive removed dinosaur data
1957
+ * - Track habitat decommissioning history
1958
+ * - Maintain removal audit logs
1820
1959
  *
1821
1960
  * @example
1822
1961
  * ```ts
1823
- * const command = new ConditionCheckBuilder('myTable', { id: '123' })
1824
- * .condition(op => op.attributeExists('status'))
1825
- * .toDynamoCommand();
1826
- * // Use command with DynamoDB client
1962
+ * // Archive dinosaur data before removal
1963
+ * const result = await builder
1964
+ * .returnValues('ALL_OLD')
1965
+ * .execute();
1966
+ *
1967
+ * if (result.item) {
1968
+ * console.log('Removed dinosaur data:', {
1969
+ * species: result.item.species,
1970
+ * age: result.item.age,
1971
+ * lastLocation: result.item.location
1972
+ * });
1973
+ * }
1827
1974
  * ```
1828
1975
  *
1829
- * @throws {Error} If no condition has been set
1830
- * @returns The DynamoDB command parameters
1976
+ * @param returnValues - Use 'ALL_OLD' to return all attributes of the deleted item
1977
+ * @returns The builder instance for method chaining
1978
+ */
1979
+ returnValues(returnValues: "ALL_OLD"): DeleteBuilder;
1980
+ /**
1981
+ * Generate the DynamoDB command parameters
1831
1982
  */
1832
1983
  private toDynamoCommand;
1833
1984
  /**
1834
- * Adds this condition check operation to a transaction.
1985
+ * Adds this delete operation to a transaction.
1835
1986
  * Use this method when you need to:
1836
- * - Verify habitat safety before transfers
1837
- * - Ensure proper feeding conditions
1838
- * - Validate security protocols
1987
+ * - Coordinate dinosaur transfers
1988
+ * - Manage habitat decommissioning
1989
+ * - Handle species relocations
1839
1990
  *
1840
1991
  * @example
1841
1992
  * ```ts
1842
1993
  * const transaction = new TransactionBuilder();
1843
- * new ConditionCheckBuilder('habitats', { id: 'PADDOCK-B' })
1844
- * .condition(op => op.and([
1845
- * op.eq('securityStatus', 'ACTIVE'),
1846
- * op.lt('currentOccupants', 3),
1847
- * op.eq('habitatType', 'CARNIVORE')
1848
- * ]))
1994
+ *
1995
+ * // Remove dinosaur from old habitat
1996
+ * new DeleteBuilder(executor, 'dinosaurs', { id: 'RAPTOR-001' })
1997
+ * .condition(op => op.eq('status', 'SEDATED'))
1849
1998
  * .withTransaction(transaction);
1850
- * // Add dinosaur transfer operations
1999
+ *
2000
+ * // Update old habitat occupancy
2001
+ * new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
2002
+ * .add('occupants', -1)
2003
+ * .withTransaction(transaction);
2004
+ *
2005
+ * // Execute transfer atomically
2006
+ * await transaction.execute();
1851
2007
  * ```
1852
2008
  *
1853
2009
  * @param transaction - The transaction builder to add this operation to
1854
- * @throws {Error} If no condition has been set
1855
- * @returns The builder instance for method chaining
1856
2010
  */
1857
- withTransaction(transaction: TransactionBuilder): ConditionCheckBuilder;
2011
+ withTransaction(transaction: TransactionBuilder): void;
1858
2012
  /**
1859
- * Gets a human-readable representation of the condition check command
1860
- * with all expression placeholders replaced by their actual values.
1861
- * Use this method when you need to:
1862
- * - Debug complex condition expressions
1863
- * - Verify condition parameters
1864
- * - Log safety checks
1865
- * - Troubleshoot condition failures
2013
+ * Executes the delete operation against DynamoDB.
1866
2014
  *
1867
2015
  * @example
1868
2016
  * ```ts
1869
- * const debugInfo = new ConditionCheckBuilder('dinosaurs', { id: 'TREX-001' })
1870
- * .condition(op => op.and([
1871
- * op.between('stats.health', 50, 100),
1872
- * op.not(op.eq('status', 'SEDATED')),
1873
- * op.attributeExists('lastFeedingTime')
1874
- * op.eq('version', 1)
1875
- * ]))
1876
- * .debug();
1877
- * console.log(debugInfo);
2017
+ * // Delete with condition and retrieve old values
2018
+ * const result = await new DeleteBuilder(executor, 'myTable', { id: '123' })
2019
+ * .condition(op => op.eq('status', 'INACTIVE'))
2020
+ * .returnValues('ALL_OLD')
2021
+ * .execute();
2022
+ *
2023
+ * if (result.item) {
2024
+ * console.log('Deleted item:', result.item);
2025
+ * }
1878
2026
  * ```
1879
2027
  *
1880
- * @returns A readable representation of the condition check command with resolved expressions
2028
+ * @returns A promise that resolves to an object containing the deleted item's attributes (if returnValues is 'ALL_OLD')
1881
2029
  */
1882
- debug(): Record<string, unknown>;
1883
- }
1884
-
2030
+ execute(): Promise<{
2031
+ item?: Record<string, unknown>;
2032
+ }>;
2033
+ /**
2034
+ * Gets a human-readable representation of the delete command
2035
+ * with all expression placeholders replaced by their actual values.
2036
+ * Use this method when you need to:
2037
+ * - Debug complex deletion conditions
2038
+ * - Verify safety checks
2039
+ * - Log removal operations
2040
+ * - Troubleshoot failed deletions
2041
+ *
2042
+ * @example
2043
+ * ```ts
2044
+ * const debugInfo = new DeleteBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
2045
+ * .condition(op => op.and([
2046
+ * op.eq('status', 'SEDATED'),
2047
+ * op.eq('location', 'MEDICAL_BAY'),
2048
+ * op.gt('sedationLevel', 8)
2049
+ * op.eq('version', 1),
2050
+ * op.attributeExists('status')
2051
+ * ]))
2052
+ * .debug();
2053
+ *
2054
+ * console.log('Delete command:', debugInfo);
2055
+ * ```
2056
+ *
2057
+ * @returns A readable representation of the delete command with resolved expressions
2058
+ */
2059
+ debug(): Record<string, unknown>;
2060
+ }
2061
+
1885
2062
  /**
1886
- * Configuration options for DynamoDB transactions.
2063
+ * Configuration options for DynamoDB update operations.
1887
2064
  */
1888
- interface TransactionOptions {
1889
- /** Unique identifier for the transaction request (idempotency token) */
1890
- clientRequestToken?: string;
1891
- /** Level of consumed capacity details to return */
1892
- returnConsumedCapacity?: "INDEXES" | "TOTAL" | "NONE";
1893
- /** Whether to return item collection metrics */
1894
- returnItemCollectionMetrics?: "SIZE" | "NONE";
2065
+ interface UpdateOptions {
2066
+ /** Optional condition that must be satisfied for the update to succeed */
2067
+ condition?: Condition;
2068
+ /** Determines which item attributes to include in the response */
2069
+ returnValues?: "ALL_NEW" | "UPDATED_NEW" | "ALL_OLD" | "UPDATED_OLD" | "NONE";
1895
2070
  }
1896
2071
  /**
1897
- * Configuration for table indexes used in duplicate detection.
1898
- * Defines the key structure for checking uniqueness constraints.
2072
+ * Function type for executing DynamoDB update operations.
2073
+ * @typeParam T - The type of the item being updated
1899
2074
  */
1900
- interface IndexConfig {
1901
- /** The partition key attribute name */
1902
- partitionKey: string;
1903
- /** Optional sort key attribute name */
1904
- sortKey?: string;
1905
- }
2075
+ type UpdateExecutor<T extends Record<string, unknown>> = (params: UpdateCommandParams) => Promise<{
2076
+ item?: T;
2077
+ }>;
1906
2078
  /**
1907
- * Function type for executing DynamoDB transaction operations.
1908
- * @param params - The complete transaction command input
1909
- * @returns A promise that resolves when the transaction completes
2079
+ * Represents a single update action within an update operation.
2080
+ * Each action modifies the item in a specific way:
2081
+ * - SET: Modify or add attributes
2082
+ * - REMOVE: Delete attributes
2083
+ * - ADD: Update numbers and sets
2084
+ * - DELETE: Remove elements from a set
1910
2085
  */
1911
- type TransactionExecutor = (params: TransactWriteCommandInput) => Promise<void>;
2086
+ type UpdateAction = {
2087
+ /** The type of update action */
2088
+ type: "SET" | "REMOVE" | "ADD" | "DELETE";
2089
+ /** The attribute path to update */
2090
+ path: string;
2091
+ /** The value to use in the update (not used for REMOVE actions) */
2092
+ value?: unknown;
2093
+ };
1912
2094
  /**
1913
- * Builder for creating and executing DynamoDB transactions.
2095
+ * Type utility to get the element type of a set.
2096
+ * Extracts the element type from either a Set or Array type.
2097
+ * @typeParam T - The set or array type
2098
+ */
2099
+ type SetElementType<T> = T extends Set<infer U> ? U : T extends Array<infer U> ? U : never;
2100
+ /**
2101
+ * Type utility to get the element type from a path that points to a set.
2102
+ * Combines PathType and SetElementType to get the element type at a specific path.
2103
+ * @typeParam T - The type of the item
2104
+ * @typeParam K - The path within the item
2105
+ */
2106
+ type PathSetElementType<T, K extends Path<T>> = SetElementType<PathType<T, K>>;
2107
+ /**
2108
+ * Builder for creating DynamoDB update operations.
1914
2109
  * Use this builder when you need to:
1915
- * - Perform multiple operations atomically
1916
- * - Ensure data consistency across operations
1917
- * - Implement complex business logic that requires atomic updates
1918
- * - Prevent duplicate items across tables
2110
+ * - Modify existing items in DynamoDB
2111
+ * - Update multiple attributes atomically
2112
+ * - Perform conditional updates
2113
+ * - Work with nested attributes
2114
+ * - Update sets and lists
1919
2115
  *
1920
- * The builder supports:
1921
- * - Put operations (insert/replace items)
1922
- * - Delete operations
1923
- * - Update operations
1924
- * - Condition checks
1925
- * - Duplicate detection
1926
- * - Transaction-wide options
2116
+ * The builder supports all DynamoDB update operations:
2117
+ * - SET: Modify or add attributes
2118
+ * - REMOVE: Delete attributes
2119
+ * - ADD: Update numbers and sets
2120
+ * - DELETE: Remove elements from a set
1927
2121
  *
1928
2122
  * @example
1929
2123
  * ```typescript
1930
- * // Create a transaction with multiple operations
1931
- * const transaction = new TransactionBuilder(executor, {
1932
- * partitionKey: 'id',
1933
- * sortKey: 'type'
1934
- * });
1935
- *
1936
- * // Add a new order
1937
- * transaction.put('orders', {
1938
- * orderId: '123',
1939
- * status: 'PENDING'
1940
- * });
1941
- *
1942
- * // Update inventory with condition
1943
- * transaction.update(
1944
- * 'inventory',
1945
- * { productId: 'ABC' },
1946
- * 'set quantity = quantity - :amount',
1947
- * { ':amount': 1 },
1948
- * op => op.gte('quantity', 1)
1949
- * );
2124
+ * // Simple update
2125
+ * const result = await new UpdateBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
2126
+ * .set('status', 'HUNTING')
2127
+ * .set('lastFed', new Date().toISOString())
2128
+ * .execute();
1950
2129
  *
1951
- * // Execute the transaction atomically
1952
- * await transaction.execute();
2130
+ * // Complex update with multiple operations
2131
+ * const result = await new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
2132
+ * .set({
2133
+ * status: 'OCCUPIED',
2134
+ * occupants: 3,
2135
+ * 'metadata.lastInspection': new Date().toISOString()
2136
+ * })
2137
+ * .add('securityBreaches', 1)
2138
+ * .deleteElementsFromSet('suitableDinosaurs', ['VELOCIRAPTOR'])
2139
+ * .condition(op => op.gt('securityLevel', 8))
2140
+ * .returnValues('ALL_NEW')
2141
+ * .execute();
1953
2142
  * ```
1954
2143
  *
1955
- * Note: DynamoDB transactions have some limitations:
1956
- * - Maximum 25 operations per transaction
1957
- * - All operations must be in the same AWS region
1958
- * - Cannot include table scans or queries
2144
+ * @typeParam T - The type of item being updated
1959
2145
  */
1960
- declare class TransactionBuilder {
1961
- private items;
2146
+ declare class UpdateBuilder<T extends Record<string, unknown>> {
2147
+ private updates;
1962
2148
  private options;
1963
- private indexConfig;
1964
2149
  private readonly executor;
1965
- constructor(executor: TransactionExecutor, indexConfig: IndexConfig);
1966
- /**
1967
- * Checks if an item with the same primary key already exists in the transaction
1968
- * @private
1969
- */
1970
- private checkForDuplicateItem;
2150
+ private readonly tableName;
2151
+ private readonly key;
2152
+ constructor(executor: UpdateExecutor<T>, tableName: string, key: PrimaryKeyWithoutExpression);
1971
2153
  /**
1972
- * Adds a put operation to the transaction.
2154
+ * Sets multiple attributes of an item using an object.
1973
2155
  * Use this method when you need to:
1974
- * - Insert new items as part of a transaction
1975
- * - Replace existing items atomically
1976
- * - Ensure items meet certain conditions before insertion
1977
- *
1978
- * The method automatically checks for duplicate items within the transaction
1979
- * to prevent multiple operations on the same item.
2156
+ * - Update multiple attributes at once
2157
+ * - Set nested attribute values
2158
+ * - Modify complex data structures
1980
2159
  *
1981
2160
  * @example
1982
2161
  * ```typescript
1983
- * // Simple put operation
1984
- * transaction.put('orders', {
1985
- * orderId: '123',
1986
- * status: 'PENDING',
1987
- * amount: 100
2162
+ * // Update multiple attributes
2163
+ * builder.set({
2164
+ * species: 'Tyrannosaurus Rex',
2165
+ * height: 20,
2166
+ * diet: 'CARNIVORE',
2167
+ * 'stats.threatLevel': 10
1988
2168
  * });
1989
- *
1990
- * // Conditional put operation
1991
- * transaction.put(
1992
- * 'inventory',
1993
- * { productId: 'ABC', quantity: 50 },
1994
- * op => op.attributeNotExists('productId')
1995
- * );
1996
- *
1997
- * // Put with complex condition
1998
- * transaction.put(
1999
- * 'users',
2000
- * { userId: '123', status: 'ACTIVE' },
2001
- * op => op.and([
2002
- * op.attributeNotExists('userId'),
2003
- * op.beginsWith('status', 'ACTIVE')
2004
- * ])
2005
- * );
2006
- * ```
2007
- *
2008
- * @param tableName - The name of the DynamoDB table
2009
- * @param item - The item to put into the table
2010
- * @param condition - Optional condition that must be satisfied
2011
- * @returns The transaction builder for method chaining
2012
- * @throws {Error} If a duplicate item is detected in the transaction
2013
- */
2014
- put<T extends Record<string, unknown>>(tableName: string, item: T, condition?: Condition): TransactionBuilder;
2015
- /**
2016
- * Adds a pre-configured put operation to the transaction.
2017
- * Use this method when you need to:
2018
- * - Reuse put commands from PutBuilder
2019
- * - Add complex put operations with pre-configured parameters
2020
- * - Integrate with existing put command configurations
2021
- *
2022
- * This method is particularly useful when working with PutBuilder
2023
- * to maintain consistency in put operations across your application.
2024
- *
2025
- * @example
2026
- * ```typescript
2027
- * // Create a put command with PutBuilder
2028
- * const putCommand = new PutBuilder(executor, newItem, 'users')
2029
- * .condition(op => op.attributeNotExists('userId'))
2030
- * .toDynamoCommand();
2031
- *
2032
- * // Add the command to the transaction
2033
- * transaction.putWithCommand(putCommand);
2034
2169
  * ```
2035
- *
2036
- * @param command - The complete put command configuration
2037
- * @returns The transaction builder for method chaining
2038
- * @throws {Error} If a duplicate item is detected in the transaction
2039
- * @see PutBuilder for creating put commands
2040
2170
  */
2041
- putWithCommand(command: PutCommandParams): TransactionBuilder;
2171
+ set(values: Partial<T>): UpdateBuilder<T>;
2042
2172
  /**
2043
- * Adds a delete operation to the transaction.
2173
+ * Sets a single attribute to a specific value.
2044
2174
  * Use this method when you need to:
2045
- * - Remove items as part of a transaction
2046
- * - Conditionally delete items
2047
- * - Ensure items exist before deletion
2048
- *
2049
- * The method automatically checks for duplicate items within the transaction
2050
- * to prevent multiple operations on the same item.
2175
+ * - Update one attribute at a time
2176
+ * - Set values with type safety
2177
+ * - Update nested attributes
2051
2178
  *
2052
2179
  * @example
2053
2180
  * ```typescript
2054
- * // Simple delete operation
2055
- * transaction.delete('orders', {
2056
- * pk: 'ORDER#123',
2057
- * sk: 'METADATA'
2058
- * });
2059
- *
2060
- * // Conditional delete operation
2061
- * transaction.delete(
2062
- * 'users',
2063
- * { pk: 'USER#123' },
2064
- * op => op.eq('status', 'INACTIVE')
2065
- * );
2066
- *
2067
- * // Delete with complex condition
2068
- * transaction.delete(
2069
- * 'products',
2070
- * { pk: 'PROD#ABC' },
2071
- * op => op.and([
2072
- * op.eq('status', 'DRAFT'),
2073
- * op.lt('version', 5)
2074
- * ])
2075
- * );
2076
- * ```
2181
+ * // Set simple attributes
2182
+ * builder
2183
+ * .set('status', 'SLEEPING')
2184
+ * .set('lastFeeding', new Date().toISOString());
2077
2185
  *
2078
- * @param tableName - The name of the DynamoDB table
2079
- * @param key - The primary key of the item to delete
2080
- * @param condition - Optional condition that must be satisfied
2081
- * @returns The transaction builder for method chaining
2082
- * @throws {Error} If a duplicate item is detected in the transaction
2186
+ * // Set nested attributes
2187
+ * builder
2188
+ * .set('location.zone', 'RESTRICTED')
2189
+ * .set('stats.health', 100);
2190
+ * ```
2083
2191
  */
2084
- delete(tableName: string, key: PrimaryKeyWithoutExpression, condition?: Condition): TransactionBuilder;
2192
+ set<K extends Path<T>>(path: K, value: PathType<T, K>): UpdateBuilder<T>;
2085
2193
  /**
2086
- * Adds a pre-configured delete operation to the transaction.
2194
+ * Removes an attribute from the item.
2087
2195
  * Use this method when you need to:
2088
- * - Reuse delete commands from DeleteBuilder
2089
- * - Add complex delete operations with pre-configured parameters
2090
- * - Integrate with existing delete command configurations
2091
- *
2092
- * This method is particularly useful when working with DeleteBuilder
2093
- * to maintain consistency in delete operations across your application.
2196
+ * - Delete attributes completely
2197
+ * - Remove nested attributes
2198
+ * - Clean up deprecated fields
2094
2199
  *
2095
2200
  * @example
2096
2201
  * ```typescript
2097
- * // Create a delete command with DeleteBuilder
2098
- * const deleteCommand = new DeleteBuilder(executor, 'users', { pk: 'USER#123' })
2099
- * .condition(op => op.and([
2100
- * op.attributeExists('pk'),
2101
- * op.eq('status', 'INACTIVE')
2102
- * ]))
2103
- * .toDynamoCommand();
2202
+ * // Remove simple attributes
2203
+ * builder
2204
+ * .remove('temporaryTag')
2205
+ * .remove('previousLocation');
2104
2206
  *
2105
- * // Add the command to the transaction
2106
- * transaction.deleteWithCommand(deleteCommand);
2207
+ * // Remove nested attributes
2208
+ * builder
2209
+ * .remove('metadata.testData')
2210
+ * .remove('stats.experimentalMetrics');
2107
2211
  * ```
2108
2212
  *
2109
- * @param command - The complete delete command configuration
2110
- * @returns The transaction builder for method chaining
2111
- * @throws {Error} If a duplicate item is detected in the transaction
2112
- * @see DeleteBuilder for creating delete commands
2213
+ * @param path - The path to the attribute to remove
2214
+ * @returns The builder instance for method chaining
2113
2215
  */
2114
- deleteWithCommand(command: DeleteCommandParams): TransactionBuilder;
2216
+ remove<K extends Path<T>>(path: K): UpdateBuilder<T>;
2115
2217
  /**
2116
- * Adds an update operation to the transaction.
2218
+ * Adds a value to a number attribute or adds elements to a set.
2117
2219
  * Use this method when you need to:
2118
- * - Modify existing items as part of a transaction
2119
- * - Update multiple attributes atomically
2120
- * - Apply conditional updates
2121
- * - Perform complex attribute manipulations
2122
- *
2123
- * The method supports all DynamoDB update expressions:
2124
- * - SET: Modify or add attributes
2125
- * - REMOVE: Delete attributes
2126
- * - ADD: Update numbers and sets
2127
- * - DELETE: Remove elements from a set
2220
+ * - Increment counters
2221
+ * - Add elements to a set atomically
2222
+ * - Update numerical statistics
2128
2223
  *
2129
2224
  * @example
2130
2225
  * ```typescript
2131
- * // Simple update
2132
- * transaction.update(
2133
- * 'orders',
2134
- * { pk: 'ORDER#123' },
2135
- * 'SET #status = :status',
2136
- * { '#status': 'status' },
2137
- * { ':status': 'PROCESSING' }
2138
- * );
2139
- *
2140
- * // Complex update with multiple operations
2141
- * transaction.update(
2142
- * 'products',
2143
- * { pk: 'PROD#ABC' },
2144
- * 'SET #qty = #qty - :amount, #status = :status REMOVE #oldAttr',
2145
- * { '#qty': 'quantity', '#status': 'status', '#oldAttr': 'deprecated_field' },
2146
- * { ':amount': 1, ':status': 'LOW_STOCK' }
2147
- * );
2226
+ * // Increment counters
2227
+ * builder
2228
+ * .add('escapeAttempts', 1)
2229
+ * .add('feedingCount', 1);
2148
2230
  *
2149
- * // Conditional update
2150
- * transaction.update(
2151
- * 'users',
2152
- * { pk: 'USER#123' },
2153
- * 'SET #lastLogin = :now',
2154
- * { '#lastLogin': 'lastLoginDate' },
2155
- * { ':now': new Date().toISOString() },
2156
- * op => op.attributeExists('pk')
2157
- * );
2231
+ * // Add to sets
2232
+ * builder
2233
+ * .add('knownBehaviors', new Set(['PACK_HUNTING', 'AMBUSH_TACTICS']))
2234
+ * .add('visitedZones', new Set(['ZONE_A', 'ZONE_B']));
2158
2235
  * ```
2159
2236
  *
2160
- * @param tableName - The name of the DynamoDB table
2161
- * @param key - The primary key of the item to update
2162
- * @param updateExpression - The update expression (SET, REMOVE, ADD, DELETE)
2163
- * @param expressionAttributeNames - Map of attribute name placeholders to actual names
2164
- * @param expressionAttributeValues - Map of value placeholders to actual values
2165
- * @param condition - Optional condition that must be satisfied
2166
- * @returns The transaction builder for method chaining
2167
- * @throws {Error} If a duplicate item is detected in the transaction
2237
+ * @param path - The path to the attribute to update
2238
+ * @param value - The value to add (number or set)
2239
+ * @returns The builder instance for method chaining
2168
2240
  */
2169
- update<T extends Record<string, unknown>>(tableName: string, key: PrimaryKeyWithoutExpression, updateExpression: string, expressionAttributeNames?: Record<string, string>, expressionAttributeValues?: Record<string, unknown>, condition?: Condition): TransactionBuilder;
2241
+ add<K extends Path<T>>(path: K, value: PathType<T, K>): UpdateBuilder<T>;
2170
2242
  /**
2171
- * Adds a pre-configured update operation to the transaction.
2243
+ * Removes elements from a set attribute.
2172
2244
  * Use this method when you need to:
2173
- * - Reuse update commands from UpdateBuilder
2174
- * - Add complex update operations with pre-configured parameters
2175
- * - Integrate with existing update command configurations
2176
- *
2177
- * This method is particularly useful when working with UpdateBuilder
2178
- * to maintain consistency in update operations across your application.
2245
+ * - Remove specific elements from a set
2246
+ * - Update set-based attributes atomically
2247
+ * - Maintain set membership
2179
2248
  *
2180
2249
  * @example
2181
2250
  * ```typescript
2182
- * // Create an update command with UpdateBuilder
2183
- * const updateCommand = new UpdateBuilder(executor, 'inventory', { pk: 'PROD#ABC' })
2184
- * .set('quantity', ':qty')
2185
- * .set('lastUpdated', ':now')
2186
- * .values({
2187
- * ':qty': 100,
2188
- * ':now': new Date().toISOString()
2189
- * })
2190
- * .condition(op => op.gt('quantity', 0))
2191
- * .toDynamoCommand();
2251
+ * // Remove from sets using arrays
2252
+ * builder.deleteElementsFromSet(
2253
+ * 'allowedHabitats',
2254
+ * ['JUNGLE', 'COASTAL']
2255
+ * );
2192
2256
  *
2193
- * // Add the command to the transaction
2194
- * transaction.updateWithCommand(updateCommand);
2257
+ * // Remove from sets using Set objects
2258
+ * builder.deleteElementsFromSet(
2259
+ * 'knownBehaviors',
2260
+ * new Set(['NOCTURNAL', 'TERRITORIAL'])
2261
+ * );
2262
+ *
2263
+ * // Remove from nested sets
2264
+ * builder.deleteElementsFromSet(
2265
+ * 'stats.compatibleSpecies',
2266
+ * ['VELOCIRAPTOR', 'DILOPHOSAURUS']
2267
+ * );
2195
2268
  * ```
2196
2269
  *
2197
- * @param command - The complete update command configuration
2198
- * @returns The transaction builder for method chaining
2199
- * @throws {Error} If a duplicate item is detected in the transaction
2200
- * @see UpdateBuilder for creating update commands
2270
+ * @param path - The path to the set attribute
2271
+ * @param value - Elements to remove (array or Set)
2272
+ * @returns The builder instance for method chaining
2201
2273
  */
2202
- updateWithCommand(command: UpdateCommandParams): TransactionBuilder;
2274
+ deleteElementsFromSet<K extends Path<T>>(path: K, value: PathSetElementType<T, K>[] | Set<PathSetElementType<T, K>>): UpdateBuilder<T>;
2203
2275
  /**
2204
- * Adds a condition check operation to the transaction.
2276
+ * Adds a condition that must be satisfied for the update to succeed.
2205
2277
  * Use this method when you need to:
2206
- * - Validate item state without modifying it
2207
- * - Ensure data consistency across tables
2208
- * - Implement complex business rules
2209
- * - Verify preconditions for other operations
2210
- *
2211
- * Condition checks are particularly useful for:
2212
- * - Implementing optimistic locking
2213
- * - Ensuring referential integrity
2214
- * - Validating business rules atomically
2278
+ * - Implement optimistic locking
2279
+ * - Ensure item state before update
2280
+ * - Validate business rules
2281
+ * - Prevent concurrent modifications
2215
2282
  *
2216
2283
  * @example
2217
2284
  * ```typescript
2218
- * // Check if order is in correct state
2219
- * transaction.conditionCheck(
2220
- * 'orders',
2221
- * { pk: 'ORDER#123' },
2222
- * op => op.eq('status', 'PENDING')
2285
+ * // Simple condition
2286
+ * builder.condition(op =>
2287
+ * op.eq('status', 'ACTIVE')
2223
2288
  * );
2224
2289
  *
2225
- * // Complex condition check
2226
- * transaction.conditionCheck(
2227
- * 'inventory',
2228
- * { pk: 'PROD#ABC' },
2229
- * op => op.and([
2230
- * op.gt('quantity', 0),
2231
- * op.eq('status', 'ACTIVE'),
2232
- * op.attributeExists('lastRestockDate')
2290
+ * // Health check condition
2291
+ * builder.condition(op =>
2292
+ * op.and([
2293
+ * op.gt('health', 50),
2294
+ * op.eq('status', 'HUNTING')
2233
2295
  * ])
2234
2296
  * );
2235
2297
  *
2236
- * // Check with multiple attributes
2237
- * transaction.conditionCheck(
2238
- * 'users',
2239
- * { pk: 'USER#123' },
2240
- * op => op.or([
2241
- * op.eq('status', 'PREMIUM'),
2242
- * op.gte('credits', 100)
2298
+ * // Complex security condition
2299
+ * builder.condition(op =>
2300
+ * op.and([
2301
+ * op.attributeExists('securitySystem'),
2302
+ * op.eq('containmentStatus', 'SECURE'),
2303
+ * op.lt('aggressionLevel', 8)
2243
2304
  * ])
2244
2305
  * );
2306
+ *
2307
+ * // Version check (optimistic locking)
2308
+ * builder.condition(op =>
2309
+ * op.eq('version', currentVersion)
2310
+ * );
2245
2311
  * ```
2246
2312
  *
2247
- * @param tableName - The name of the DynamoDB table
2248
- * @param key - The primary key of the item to check
2249
- * @param condition - The condition that must be satisfied
2250
- * @returns The transaction builder for method chaining
2251
- * @throws {Error} If a duplicate item is detected in the transaction
2252
- * @throws {Error} If condition expression generation fails
2313
+ * @param condition - Either a Condition object or a callback function that builds the condition
2314
+ * @returns The builder instance for method chaining
2253
2315
  */
2254
- conditionCheck(tableName: string, key: PrimaryKeyWithoutExpression, condition: Condition): TransactionBuilder;
2316
+ condition(condition: Condition | ((op: ConditionOperator<T>) => Condition)): UpdateBuilder<T>;
2255
2317
  /**
2256
- * Adds a pre-configured condition check operation to the transaction.
2318
+ * Sets which item attributes to include in the response.
2257
2319
  * Use this method when you need to:
2258
- * - Reuse condition checks from ConditionCheckBuilder
2259
- * - Add complex condition checks with pre-configured parameters
2260
- * - Integrate with existing condition check configurations
2320
+ * - Get the complete updated item
2321
+ * - Track changes to specific attributes
2322
+ * - Compare old and new values
2323
+ * - Monitor attribute modifications
2261
2324
  *
2262
- * This method is particularly useful when working with ConditionCheckBuilder
2263
- * to maintain consistency in condition checks across your application.
2325
+ * Available options:
2326
+ * - ALL_NEW: All attributes after the update
2327
+ * - UPDATED_NEW: Only updated attributes, new values
2328
+ * - ALL_OLD: All attributes before the update
2329
+ * - UPDATED_OLD: Only updated attributes, old values
2330
+ * - NONE: No attributes returned (default)
2264
2331
  *
2265
2332
  * @example
2266
2333
  * ```typescript
2267
- * // Create a condition check with ConditionCheckBuilder
2268
- * const checkCommand = new ConditionCheckBuilder('inventory', { pk: 'PROD#ABC' })
2269
- * .condition(op => op.and([
2270
- * op.between('quantity', 10, 100),
2271
- * op.beginsWith('category', 'ELECTRONICS'),
2272
- * op.attributeExists('lastAuditDate')
2273
- * ]))
2274
- * .toDynamoCommand();
2334
+ * // Get complete updated dinosaur
2335
+ * const result = await builder
2336
+ * .set('status', 'SLEEPING')
2337
+ * .returnValues('ALL_NEW')
2338
+ * .execute();
2339
+ *
2340
+ * // Track specific attribute changes
2341
+ * const result = await builder
2342
+ * .set({
2343
+ * 'stats.health': 100,
2344
+ * 'stats.energy': 95
2345
+ * })
2346
+ * .returnValues('UPDATED_OLD')
2347
+ * .execute();
2275
2348
  *
2276
- * // Add the command to the transaction
2277
- * transaction.conditionCheckWithCommand(checkCommand);
2349
+ * if (result.item) {
2350
+ * console.log('Previous health:', result.item.stats?.health);
2351
+ * }
2278
2352
  * ```
2279
2353
  *
2280
- * @param command - The complete condition check command configuration
2281
- * @returns The transaction builder for method chaining
2282
- * @throws {Error} If a duplicate item is detected in the transaction
2283
- * @see ConditionCheckBuilder for creating condition check commands
2354
+ * @param returnValues - Which attributes to return in the response
2355
+ * @returns The builder instance for method chaining
2284
2356
  */
2285
- conditionCheckWithCommand(command: ConditionCheckCommandParams): TransactionBuilder;
2357
+ returnValues(returnValues: "ALL_NEW" | "UPDATED_NEW" | "ALL_OLD" | "UPDATED_OLD" | "NONE"): UpdateBuilder<T>;
2286
2358
  /**
2287
- * Sets options for the transaction execution.
2359
+ * Generate the DynamoDB command parameters
2360
+ */
2361
+ toDynamoCommand(): UpdateCommandParams;
2362
+ /**
2363
+ * Adds this update operation to a transaction.
2288
2364
  * Use this method when you need to:
2289
- * - Enable idempotent transactions
2290
- * - Track consumed capacity
2291
- * - Monitor item collection metrics
2365
+ * - Update items as part of a larger transaction
2366
+ * - Ensure multiple updates are atomic
2367
+ * - Coordinate updates across multiple items
2292
2368
  *
2293
2369
  * @example
2294
2370
  * ```typescript
2295
- * // Enable idempotency and capacity tracking
2296
- * transaction.withOptions({
2297
- * clientRequestToken: 'unique-request-id-123',
2298
- * returnConsumedCapacity: 'TOTAL'
2299
- * });
2371
+ * const transaction = new TransactionBuilder(executor);
2300
2372
  *
2301
- * // Track item collection metrics
2302
- * transaction.withOptions({
2303
- * returnItemCollectionMetrics: 'SIZE'
2304
- * });
2305
- * ```
2373
+ * // Update dinosaur status and habitat occupancy atomically
2374
+ * new UpdateBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
2375
+ * .set('location', 'PADDOCK_A')
2376
+ * .set('status', 'CONTAINED')
2377
+ * .withTransaction(transaction);
2306
2378
  *
2307
- * Note: ClientRequestToken can be used to make transactions idempotent,
2308
- * ensuring the same transaction is not executed multiple times.
2379
+ * new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
2380
+ * .add('occupants', 1)
2381
+ * .set('lastOccupied', new Date().toISOString())
2382
+ * .withTransaction(transaction);
2309
2383
  *
2310
- * @param options - Configuration options for the transaction
2311
- * @returns The transaction builder for method chaining
2384
+ * // Execute all operations atomically
2385
+ * await transaction.execute();
2386
+ * ```
2387
+ *
2388
+ * @param transaction - The transaction builder to add this operation to
2389
+ * @returns The builder instance for method chaining
2312
2390
  */
2313
- withOptions(options: TransactionOptions): TransactionBuilder;
2391
+ withTransaction(transaction: TransactionBuilder): void;
2314
2392
  /**
2315
- * Gets a human-readable representation of the transaction items.
2393
+ * Gets a human-readable representation of the update command.
2316
2394
  * Use this method when you need to:
2317
- * - Debug complex transactions
2318
- * - Verify operation parameters
2319
- * - Log transaction details
2395
+ * - Debug complex update expressions
2396
+ * - Verify attribute names and values
2397
+ * - Log update operations
2320
2398
  * - Troubleshoot condition expressions
2321
2399
  *
2322
- * The method resolves all expression placeholders with their actual values,
2323
- * making it easier to understand the transaction's operations.
2324
- *
2325
2400
  * @example
2326
2401
  * ```typescript
2327
- * // Add multiple operations
2328
- * transaction
2329
- * .put('orders', { orderId: '123', status: 'PENDING' })
2330
- * .update('inventory',
2331
- * { productId: 'ABC' },
2332
- * 'SET quantity = quantity - :amount',
2333
- * undefined,
2334
- * { ':amount': 1 }
2335
- * );
2402
+ * // Create complex update
2403
+ * const builder = new UpdateBuilder(executor, 'dinosaurs', { id: 'RAPTOR-001' })
2404
+ * .set({
2405
+ * status: 'HUNTING',
2406
+ * 'stats.health': 95,
2407
+ * 'behavior.lastObserved': new Date().toISOString()
2408
+ * })
2409
+ * .add('huntingSuccesses', 1)
2410
+ * .condition(op => op.gt('health', 50));
2336
2411
  *
2337
- * // Debug the transaction
2338
- * const debugInfo = transaction.debug();
2339
- * console.log('Transaction operations:', debugInfo);
2412
+ * // Debug the update
2413
+ * const debugInfo = builder.debug();
2414
+ * console.log('Update operation:', debugInfo);
2340
2415
  * ```
2341
2416
  *
2342
- * @returns An array of readable representations of the transaction items
2417
+ * @returns A readable representation of the update command with resolved expressions
2343
2418
  */
2344
- debug(): Record<string, unknown>[];
2419
+ debug(): Record<string, unknown>;
2345
2420
  /**
2346
- * Executes all operations in the transaction atomically.
2421
+ * Executes the update operation against DynamoDB.
2347
2422
  * Use this method when you need to:
2348
- * - Perform multiple operations atomically
2349
- * - Ensure all-or-nothing execution
2350
- * - Maintain data consistency across operations
2351
- *
2352
- * The transaction will only succeed if all operations succeed.
2353
- * If any operation fails, the entire transaction is rolled back.
2423
+ * - Apply updates immediately
2424
+ * - Get the updated item values
2425
+ * - Handle conditional update failures
2354
2426
  *
2355
2427
  * @example
2356
2428
  * ```typescript
2357
2429
  * try {
2358
- * // Build and execute transaction
2359
- * await transaction
2360
- * .put('orders', newOrder)
2361
- * .update('inventory',
2362
- * { productId: 'ABC' },
2363
- * 'SET quantity = quantity - :qty',
2364
- * undefined,
2365
- * { ':qty': 1 }
2366
- * )
2367
- * .conditionCheck('products',
2368
- * { productId: 'ABC' },
2369
- * op => op.eq('status', 'ACTIVE')
2430
+ * // Update dinosaur status with conditions
2431
+ * const result = await new UpdateBuilder(executor, 'dinosaurs', { id: 'TREX-001' })
2432
+ * .set({
2433
+ * status: 'FEEDING',
2434
+ * lastMeal: new Date().toISOString(),
2435
+ * 'stats.hunger': 0
2436
+ * })
2437
+ * .add('feedingCount', 1)
2438
+ * .condition(op =>
2439
+ * op.and([
2440
+ * op.gt('stats.hunger', 80),
2441
+ * op.eq('status', 'HUNTING')
2442
+ * ])
2370
2443
  * )
2444
+ * .returnValues('ALL_NEW')
2371
2445
  * .execute();
2372
2446
  *
2373
- * console.log('Transaction completed successfully');
2447
+ * if (result.item) {
2448
+ * console.log('Updated dinosaur:', result.item);
2449
+ * }
2374
2450
  * } catch (error) {
2375
- * // Handle transaction failure
2376
- * console.error('Transaction failed:', error);
2451
+ * // Handle condition check failure
2452
+ * console.error('Failed to update dinosaur:', error);
2453
+ * // Check if dinosaur wasn't hungry enough
2454
+ * if (error.name === 'ConditionalCheckFailedException') {
2455
+ * console.log('Dinosaur not ready for feeding');
2456
+ * }
2377
2457
  * }
2378
2458
  * ```
2379
2459
  *
2380
- * @throws {Error} If no transaction items are specified
2381
- * @throws {Error} If any operation in the transaction fails
2382
- * @returns A promise that resolves when the transaction completes
2460
+ * @returns A promise that resolves to an object containing the updated item (if returnValues is set)
2461
+ * @throws {ConditionalCheckFailedException} If the condition check fails
2462
+ * @throws {Error} If the update operation fails for other reasons
2383
2463
  */
2384
- execute(): Promise<void>;
2464
+ execute(): Promise<{
2465
+ item?: T;
2466
+ }>;
2385
2467
  }
2386
2468
 
2469
+ type BatchWriteOperation<T extends Record<string, unknown>> = {
2470
+ type: "put";
2471
+ item: T;
2472
+ } | {
2473
+ type: "delete";
2474
+ key: PrimaryKeyWithoutExpression;
2475
+ };
2476
+
2387
2477
  /**
2388
- * Parameters for the DynamoDB put command.
2389
- * These parameters are used when executing the operation against DynamoDB.
2390
- */
2391
- interface PutCommandParams extends DynamoCommandWithExpressions {
2392
- tableName: string;
2393
- item: Record<string, unknown>;
2394
- conditionExpression?: string;
2395
- expressionAttributeNames?: Record<string, string>;
2396
- expressionAttributeValues?: Record<string, unknown>;
2397
- returnValues?: "ALL_OLD" | "NONE";
2398
- }
2399
- type PutExecutor<T extends Record<string, unknown>> = (params: PutCommandParams) => Promise<T>;
2400
- /**
2401
- * Builder for creating DynamoDB put operations.
2478
+ * Builder for creating DynamoDB condition check operations.
2402
2479
  * Use this builder when you need to:
2403
- * - Add new dinosaurs to the registry
2404
- * - Create new habitats
2405
- * - Update dinosaur profiles completely
2406
- * - Initialize tracking records
2480
+ * - Verify item state without modifying it
2481
+ * - Ensure preconditions in transactions
2482
+ * - Implement optimistic locking patterns
2483
+ * - Validate business rules
2407
2484
  *
2408
2485
  * @example
2409
2486
  * ```typescript
2410
- * // Add new dinosaur
2411
- * const result = await new PutBuilder(executor, {
2412
- * id: 'RAPTOR-001',
2413
- * species: 'Velociraptor',
2414
- * status: 'ACTIVE',
2415
- * stats: {
2416
- * health: 100,
2417
- * age: 5,
2418
- * threatLevel: 8
2419
- * }
2420
- * }, 'dinosaurs').execute();
2421
- *
2422
- * // Create new habitat with conditions
2423
- * const result = await new PutBuilder(executor, {
2424
- * id: 'PADDOCK-C',
2425
- * type: 'CARNIVORE',
2426
- * securityLevel: 'MAXIMUM',
2427
- * capacity: 3,
2428
- * environmentType: 'TROPICAL'
2429
- * }, 'habitats')
2430
- * .condition(op => op.attributeNotExists('id'))
2431
- * .execute();
2432
- * ```
2487
+ * // Check if dinosaur is ready for feeding
2488
+ * const check = new ConditionCheckBuilder('dinosaurs', { id: 'TREX-001' })
2489
+ * .condition(op =>
2490
+ * op.and([
2491
+ * op.eq('status', 'HUNTING'),
2492
+ * op.gt('stats.hunger', 80),
2493
+ * op.lt('stats.health', 100)
2494
+ * ])
2495
+ * )
2496
+ * .toDynamoCommand();
2433
2497
  *
2434
- * @typeParam T - The type of item being put into the table
2435
- */
2436
- declare class PutBuilder<T extends Record<string, unknown>> {
2437
- private readonly item;
2438
- private options;
2439
- private readonly executor;
2440
- private readonly tableName;
2441
- constructor(executor: PutExecutor<T>, item: T, tableName: string);
2442
- /**
2443
- * Adds a condition that must be satisfied for the put operation to succeed.
2444
- * Use this method when you need to:
2445
- * - Prevent overwriting existing items (optimistic locking)
2446
- * - Ensure items meet certain criteria before replacement
2447
- * - Implement complex business rules for item updates
2448
- *
2449
- * @example
2450
- * ```ts
2451
- * // Ensure item doesn't exist (insert only)
2452
- * builder.condition(op => op.attributeNotExists('id'))
2453
- *
2454
- * // Complex condition with version check
2455
- * builder.condition(op =>
2456
- * op.and([
2457
- * op.attributeExists('id'),
2458
- * op.eq('version', currentVersion),
2459
- * op.eq('status', 'ACTIVE')
2460
- * ])
2461
- * )
2462
- * ```
2463
- *
2464
- * @param condition - Either a Condition object or a callback function that builds the condition
2465
- * @returns The builder instance for method chaining
2466
- */
2498
+ * // Check habitat security status
2499
+ * const securityCheck = new ConditionCheckBuilder('habitats', { id: 'PADDOCK-A' })
2500
+ * .condition(op =>
2501
+ * op.and([
2502
+ * op.eq('securityStatus', 'ACTIVE'),
2503
+ * op.attributeExists('lastInspection'),
2504
+ * op.lt('threatLevel', 5)
2505
+ * ])
2506
+ * )
2507
+ * .toDynamoCommand();
2508
+ * ```
2509
+ */
2510
+ declare class ConditionCheckBuilder {
2511
+ private readonly key;
2512
+ private readonly tableName;
2513
+ private conditionExpression?;
2514
+ constructor(tableName: string, key: PrimaryKeyWithoutExpression);
2467
2515
  /**
2468
- * Adds a condition that must be satisfied for the put operation to succeed.
2516
+ * Adds a condition that must be satisfied for the check to succeed.
2469
2517
  * Use this method when you need to:
2470
- * - Prevent duplicate dinosaur entries
2471
- * - Ensure habitat requirements
2472
- * - Validate security protocols
2518
+ * - Validate complex item states
2519
+ * - Check multiple attributes together
2520
+ * - Ensure safety conditions are met
2473
2521
  *
2474
2522
  * @example
2475
2523
  * ```typescript
2476
- * // Ensure unique dinosaur ID
2524
+ * // Check dinosaur health and behavior
2477
2525
  * builder.condition(op =>
2478
- * op.attributeNotExists('id')
2526
+ * op.and([
2527
+ * op.gt('stats.health', 50),
2528
+ * op.not(op.eq('status', 'SEDATED')),
2529
+ * op.lt('aggressionLevel', 8)
2530
+ * ])
2479
2531
  * );
2480
2532
  *
2481
- * // Verify habitat requirements
2533
+ * // Verify habitat conditions
2482
2534
  * builder.condition(op =>
2483
2535
  * op.and([
2484
- * op.eq('securityStatus', 'READY'),
2485
- * op.attributeExists('lastInspection'),
2486
- * op.gt('securityLevel', 5)
2536
+ * op.eq('powerStatus', 'ONLINE'),
2537
+ * op.between('temperature', 20, 30),
2538
+ * op.attributeExists('lastMaintenance')
2487
2539
  * ])
2488
2540
  * );
2489
2541
  *
2490
- * // Check breeding facility conditions
2542
+ * // Check breeding conditions
2491
2543
  * builder.condition(op =>
2492
2544
  * op.and([
2493
- * op.between('temperature', 25, 30),
2494
- * op.between('humidity', 60, 80),
2495
- * op.eq('quarantineStatus', 'CLEAR')
2545
+ * op.eq('species', 'VELOCIRAPTOR'),
2546
+ * op.gte('age', 3),
2547
+ * op.eq('geneticPurity', 100)
2496
2548
  * ])
2497
2549
  * );
2498
2550
  * ```
@@ -2500,144 +2552,78 @@ declare class PutBuilder<T extends Record<string, unknown>> {
2500
2552
  * @param condition - Either a Condition object or a callback function that builds the condition
2501
2553
  * @returns The builder instance for method chaining
2502
2554
  */
2503
- condition(condition: Condition | ((op: ConditionOperator<T>) => Condition)): PutBuilder<T>;
2555
+ condition<T extends Record<string, unknown>>(condition: Condition | ((op: ConditionOperator<T>) => Condition)): ConditionCheckBuilder;
2504
2556
  /**
2505
- * Sets whether to return the item's previous values (if it existed).
2506
- * Use this method when you need to:
2507
- * - Track dinosaur profile updates
2508
- * - Monitor habitat modifications
2509
- * - Maintain change history
2557
+ * Generates the DynamoDB command parameters for direct execution.
2558
+ * Use this method when you want to:
2559
+ * - Execute the condition check as a standalone operation
2560
+ * - Get the raw DynamoDB command for custom execution
2561
+ * - Inspect the generated command parameters
2510
2562
  *
2511
2563
  * @example
2512
2564
  * ```ts
2513
- * // Get previous dinosaur state
2514
- * const result = await builder
2515
- * .returnValues('ALL_OLD')
2516
- * .execute();
2517
- *
2518
- * if (result) {
2519
- * console.log('Previous profile:', {
2520
- * species: result.species,
2521
- * status: result.status,
2522
- * stats: {
2523
- * health: result.stats.health,
2524
- * threatLevel: result.stats.threatLevel
2525
- * }
2526
- * });
2527
- * }
2565
+ * const command = new ConditionCheckBuilder('myTable', { id: '123' })
2566
+ * .condition(op => op.attributeExists('status'))
2567
+ * .toDynamoCommand();
2568
+ * // Use command with DynamoDB client
2528
2569
  * ```
2529
2570
  *
2530
- * @param returnValues - Use 'ALL_OLD' to return previous values, or 'NONE' (default)
2531
- * @returns The builder instance for method chaining
2532
- */
2533
- returnValues(returnValues: "ALL_OLD" | "NONE"): PutBuilder<T>;
2534
- /**
2535
- * Generate the DynamoDB command parameters
2571
+ * @throws {Error} If no condition has been set
2572
+ * @returns The DynamoDB command parameters
2536
2573
  */
2537
2574
  private toDynamoCommand;
2538
2575
  /**
2539
- * Adds this put operation to a transaction.
2576
+ * Adds this condition check operation to a transaction.
2540
2577
  * Use this method when you need to:
2541
- * - Transfer dinosaurs between habitats
2542
- * - Initialize new breeding programs
2543
- * - Update multiple facility records
2578
+ * - Verify habitat safety before transfers
2579
+ * - Ensure proper feeding conditions
2580
+ * - Validate security protocols
2544
2581
  *
2545
2582
  * @example
2546
2583
  * ```ts
2547
2584
  * const transaction = new TransactionBuilder();
2548
- *
2549
- * // Add dinosaur to new habitat
2550
- * new PutBuilder(executor, {
2551
- * id: 'TREX-002',
2552
- * location: 'PADDOCK-B',
2553
- * status: 'ACTIVE',
2554
- * transferDate: new Date().toISOString()
2555
- * }, 'dinosaurs')
2556
- * .withTransaction(transaction);
2557
- *
2558
- * // Update habitat records
2559
- * new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-B' })
2560
- * .add('occupants', 1)
2561
- * .set('lastTransfer', new Date().toISOString())
2585
+ * new ConditionCheckBuilder('habitats', { id: 'PADDOCK-B' })
2586
+ * .condition(op => op.and([
2587
+ * op.eq('securityStatus', 'ACTIVE'),
2588
+ * op.lt('currentOccupants', 3),
2589
+ * op.eq('habitatType', 'CARNIVORE')
2590
+ * ]))
2562
2591
  * .withTransaction(transaction);
2563
- *
2564
- * // Execute transfer atomically
2565
- * await transaction.execute();
2592
+ * // Add dinosaur transfer operations
2566
2593
  * ```
2567
2594
  *
2568
2595
  * @param transaction - The transaction builder to add this operation to
2596
+ * @throws {Error} If no condition has been set
2569
2597
  * @returns The builder instance for method chaining
2570
2598
  */
2571
- withTransaction(transaction: TransactionBuilder): PutBuilder<T>;
2572
- /**
2573
- * Executes the put operation against DynamoDB.
2574
- *
2575
- * @example
2576
- * ```ts
2577
- * try {
2578
- * // Put with condition and return old values
2579
- * const result = await new PutBuilder(executor, newItem, 'myTable')
2580
- * .condition(op => op.eq('version', 1))
2581
- * .returnValues('ALL_OLD')
2582
- * .execute();
2583
- *
2584
- * console.log('Put successful, old item:', result);
2585
- * } catch (error) {
2586
- * // Handle condition check failure or other errors
2587
- * console.error('Put failed:', error);
2588
- * }
2589
- * ```
2590
- *
2591
- * @returns A promise that resolves to the operation result (type depends on returnValues setting)
2592
- * @throws Will throw an error if the condition check fails or other DynamoDB errors occur
2593
- */
2594
- execute(): Promise<T>;
2599
+ withTransaction(transaction: TransactionBuilder): ConditionCheckBuilder;
2595
2600
  /**
2596
- * Gets a human-readable representation of the put command
2601
+ * Gets a human-readable representation of the condition check command
2597
2602
  * with all expression placeholders replaced by their actual values.
2598
2603
  * Use this method when you need to:
2599
- * - Debug complex dinosaur transfers
2600
- * - Verify habitat assignments
2601
- * - Log security protocols
2602
- * - Troubleshoot breeding program conditions
2604
+ * - Debug complex condition expressions
2605
+ * - Verify condition parameters
2606
+ * - Log safety checks
2607
+ * - Troubleshoot condition failures
2603
2608
  *
2604
2609
  * @example
2605
2610
  * ```ts
2606
- * const debugInfo = new PutBuilder(executor, {
2607
- * id: 'RAPTOR-003',
2608
- * species: 'Velociraptor',
2609
- * status: 'QUARANTINE',
2610
- * stats: {
2611
- * health: 100,
2612
- * aggressionLevel: 7,
2613
- * age: 2
2614
- * }
2615
- * }, 'dinosaurs')
2616
- * .condition(op =>
2617
- * op.and([
2618
- * op.attributeNotExists('id'),
2619
- * op.eq('quarantineStatus', 'READY'),
2620
- * op.gt('securityLevel', 8)
2621
- * ])
2622
- * )
2611
+ * const debugInfo = new ConditionCheckBuilder('dinosaurs', { id: 'TREX-001' })
2612
+ * .condition(op => op.and([
2613
+ * op.between('stats.health', 50, 100),
2614
+ * op.not(op.eq('status', 'SEDATED')),
2615
+ * op.attributeExists('lastFeedingTime')
2616
+ * op.eq('version', 1)
2617
+ * ]))
2623
2618
  * .debug();
2624
- *
2625
- * console.log('Dinosaur transfer command:', debugInfo);
2619
+ * console.log(debugInfo);
2626
2620
  * ```
2627
2621
  *
2628
- * @returns A readable representation of the put command with resolved expressions
2622
+ * @returns A readable representation of the condition check command with resolved expressions
2629
2623
  */
2630
2624
  debug(): Record<string, unknown>;
2631
2625
  }
2632
2626
 
2633
- type BatchWriteOperation<T extends Record<string, unknown>> = {
2634
- type: "put";
2635
- item: T;
2636
- } | {
2637
- type: "delete";
2638
- key: PrimaryKeyWithoutExpression;
2639
- };
2640
-
2641
2627
  /**
2642
2628
  * Parameters for the DynamoDB get command.
2643
2629
  */
@@ -2770,11 +2756,136 @@ declare class GetBuilder<T extends Record<string, unknown>> {
2770
2756
  }>;
2771
2757
  }
2772
2758
 
2759
+ /**
2760
+ * Configuration options for DynamoDB scan operations.
2761
+ * Extends the base FilterOptions.
2762
+ */
2763
+ type ScanOptions = FilterOptions;
2764
+ /**
2765
+ * Function type for executing DynamoDB filter operations.
2766
+ * @typeParam T - The type of items being filtered
2767
+ */
2768
+ type ScanExecutor<T extends Record<string, unknown>> = (options: ScanOptions) => Promise<{
2769
+ items: T[];
2770
+ lastEvaluatedKey?: Record<string, unknown>;
2771
+ }>;
2772
+ /**
2773
+ * Builder for creating DynamoDB scan operations.
2774
+ * Use this builder when you need to:
2775
+ * - Scan all items in a table
2776
+ * - Filter results based on non-key attributes
2777
+ * - Scan items on a Secondary Index (GSI)
2778
+ * - Implement pagination
2779
+ * - Project specific attributes
2780
+ *
2781
+ * The builder supports:
2782
+ * - Type-safe GSI selection
2783
+ * - Complex filter conditions
2784
+ * - Automatic pagination handling
2785
+ * - Consistent reads
2786
+ * - Attribute projection
2787
+ *
2788
+ * @example
2789
+ * ```typescript
2790
+ * // Simple scan with filtering
2791
+ * const result = await new ScanBuilder(executor)
2792
+ * .filter(op => op.eq('status', 'ACTIVE'))
2793
+ * .execute();
2794
+ *
2795
+ * // Scan with GSI and filtering
2796
+ * const result = await new ScanBuilder(executor)
2797
+ * .useIndex('status-index')
2798
+ * .filter(op => op.gt('securityLevel', 8))
2799
+ * .select(['id', 'capacity', 'currentOccupants'])
2800
+ * .limit(10)
2801
+ * .execute();
2802
+ *
2803
+ * // Scan with pagination
2804
+ * const paginator = new ScanBuilder(executor)
2805
+ * .filter(op => op.eq('type', 'INCIDENT'))
2806
+ * .paginate(25);
2807
+ *
2808
+ * while (paginator.hasNextPage()) {
2809
+ * const page = await paginator.getNextPage();
2810
+ * // Process page.items
2811
+ * }
2812
+ * ```
2813
+ *
2814
+ * @typeParam T - The type of items being scanned
2815
+ * @typeParam TConfig - The table configuration type for type-safe GSI selection
2816
+ */
2817
+ declare class ScanBuilder<T extends Record<string, unknown>, TConfig extends TableConfig = TableConfig> extends FilterBuilder<T, TConfig> implements ScanBuilderInterface<T, TConfig> {
2818
+ protected readonly executor: ScanExecutor<T>;
2819
+ constructor(executor: ScanExecutor<T>);
2820
+ /**
2821
+ * Creates a deep clone of this ScanBuilder instance.
2822
+ * Use this method when you need to:
2823
+ * - Create scan templates
2824
+ * - Run multiple variations of a scan
2825
+ * - Implement pagination (used internally by paginate())
2826
+ *
2827
+ * @returns A new ScanBuilder instance with the same configuration
2828
+ */
2829
+ clone(): ScanBuilder<T, TConfig>;
2830
+ /**
2831
+ * Executes the scan against DynamoDB.
2832
+ * Use this method when you need to:
2833
+ * - Search across the entire table
2834
+ * - Find items matching specific criteria
2835
+ * - Perform full table analysis
2836
+ * - Generate reports across all data
2837
+ *
2838
+ * The method returns both the matched items and, if there are more results,
2839
+ * a lastEvaluatedKey that can be used with startFrom() to continue the scan.
2840
+ *
2841
+ * @example
2842
+ * ```typescript
2843
+ * try {
2844
+ * // Find all dinosaurs with high aggression levels
2845
+ * const result = await new ScanBuilder(executor)
2846
+ * .filter(op =>
2847
+ * op.and([
2848
+ * op.eq('status', 'ACTIVE'),
2849
+ * op.gt('aggressionLevel', 7)
2850
+ * ])
2851
+ * )
2852
+ * .limit(20)
2853
+ * .execute();
2854
+ *
2855
+ * console.log(`Found ${result.items.length} potentially dangerous dinosaurs`);
2856
+ *
2857
+ * if (result.lastEvaluatedKey) {
2858
+ * console.log('More results available');
2859
+ * }
2860
+ * } catch (error) {
2861
+ * console.error('Security scan failed:', error);
2862
+ * }
2863
+ * ```
2864
+ *
2865
+ * @returns A promise that resolves to an object containing:
2866
+ * - items: Array of items matching the scan criteria
2867
+ * - lastEvaluatedKey: Token for continuing the scan, if more items exist
2868
+ */
2869
+ execute(): Promise<{
2870
+ items: T[];
2871
+ lastEvaluatedKey?: Record<string, unknown>;
2872
+ }>;
2873
+ }
2874
+
2773
2875
  declare class Table<TConfig extends TableConfig = TableConfig> {
2774
- private dynamoClient;
2876
+ private readonly dynamoClient;
2775
2877
  readonly tableName: string;
2878
+ /**
2879
+ * The column name of the partitionKey for the Table
2880
+ */
2776
2881
  readonly partitionKey: string;
2882
+ /**
2883
+ * The column name of the sortKey for the Table
2884
+ */
2777
2885
  readonly sortKey?: string;
2886
+ /**
2887
+ * The Global Secondary Indexes that are configured on this table
2888
+ */
2778
2889
  readonly gsis: Record<string, Index>;
2779
2890
  constructor(config: TConfig);
2780
2891
  /**
@@ -2797,6 +2908,16 @@ declare class Table<TConfig extends TableConfig = TableConfig> {
2797
2908
  * If useIndex is called on the returned QueryBuilder, it will use the GSI configuration
2798
2909
  */
2799
2910
  query<T extends Record<string, unknown>>(keyCondition: PrimaryKey): QueryBuilder<T, TConfig>;
2911
+ /**
2912
+ * Creates a scan builder for scanning the entire table
2913
+ * Use this when you need to:
2914
+ * - Process all items in a table
2915
+ * - Apply filters to a large dataset
2916
+ * - Use a GSI for scanning
2917
+ *
2918
+ * @returns A ScanBuilder instance for chaining operations
2919
+ */
2920
+ scan<T extends Record<string, unknown>>(): ScanBuilder<T, TConfig>;
2800
2921
  delete(keyCondition: PrimaryKeyWithoutExpression): DeleteBuilder;
2801
2922
  /**
2802
2923
  * Updates an item in the table
@@ -2847,4 +2968,4 @@ declare class Table<TConfig extends TableConfig = TableConfig> {
2847
2968
  }>;
2848
2969
  }
2849
2970
 
2850
- export { type Condition, ConditionCheckBuilder, type ConditionOperator, DeleteBuilder, type EntityConfig, type GSINames, type Index, type PaginationResult, Paginator, PutBuilder, QueryBuilder, Table, type TableConfig, TransactionBuilder, UpdateBuilder, and, attributeExists, attributeNotExists, beginsWith, between, contains, eq, gt, gte, lt, lte, ne, not, or };
2971
+ export { type ComparisonOperator, type Condition, ConditionCheckBuilder, type ConditionOperator, DeleteBuilder, type DeleteOptions, type EntityConfig, type ExpressionParams, type GSINames, type Index, type KeyConditionOperator, type LogicalOperator, Paginator, type PrimaryKey, type PrimaryKeyWithoutExpression, PutBuilder, type PutOptions, QueryBuilder, type QueryOptions, Table, type TableConfig, TransactionBuilder, type TransactionExecutor, type TransactionOptions, type UpdateAction, UpdateBuilder, type UpdateOptions, and, attributeExists, attributeNotExists, beginsWith, between, contains, createComparisonCondition, eq, gt, gte, lt, lte, ne, not, or };