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.
- package/LICENSE +21 -0
- package/README.md +115 -17
- package/dist/builders/condition-check-builder.cjs +394 -0
- package/dist/builders/condition-check-builder.cjs.map +1 -0
- package/dist/builders/condition-check-builder.js +392 -0
- package/dist/builders/condition-check-builder.js.map +1 -0
- package/dist/builders/delete-builder.cjs +422 -0
- package/dist/builders/delete-builder.cjs.map +1 -0
- package/dist/builders/delete-builder.js +420 -0
- package/dist/builders/delete-builder.js.map +1 -0
- package/dist/builders/paginator.cjs +199 -0
- package/dist/builders/paginator.cjs.map +1 -0
- package/dist/builders/paginator.js +197 -0
- package/dist/builders/paginator.js.map +1 -0
- package/dist/builders/put-builder.cjs +468 -0
- package/dist/builders/put-builder.cjs.map +1 -0
- package/dist/builders/put-builder.js +466 -0
- package/dist/builders/put-builder.js.map +1 -0
- package/dist/builders/query-builder.cjs +674 -0
- package/dist/builders/query-builder.cjs.map +1 -0
- package/dist/builders/query-builder.js +672 -0
- package/dist/builders/query-builder.js.map +1 -0
- package/dist/builders/transaction-builder.cjs +876 -0
- package/dist/builders/transaction-builder.cjs.map +1 -0
- package/dist/builders/transaction-builder.js +874 -0
- package/dist/builders/transaction-builder.js.map +1 -0
- package/dist/builders/update-builder.cjs +662 -0
- package/dist/builders/update-builder.cjs.map +1 -0
- package/dist/builders/update-builder.js +660 -0
- package/dist/builders/update-builder.js.map +1 -0
- package/dist/conditions.cjs +59 -0
- package/dist/conditions.cjs.map +1 -0
- package/dist/conditions.js +43 -0
- package/dist/conditions.js.map +1 -0
- package/dist/entity.cjs +169 -0
- package/dist/entity.cjs.map +1 -0
- package/dist/entity.js +165 -0
- package/dist/entity.js.map +1 -0
- package/dist/index.cjs +3333 -0
- package/dist/index.d.cts +2971 -0
- package/dist/index.d.ts +1504 -1383
- package/dist/index.js +391 -375
- package/dist/standard-schema.cjs +4 -0
- package/dist/standard-schema.cjs.map +1 -0
- package/dist/standard-schema.js +3 -0
- package/dist/standard-schema.js.map +1 -0
- package/dist/table.cjs +3265 -0
- package/dist/table.cjs.map +1 -0
- package/dist/table.js +3263 -0
- package/dist/table.js.map +1 -0
- package/dist/types.cjs +4 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/key-template.cjs +19 -0
- package/dist/utils/key-template.cjs.map +1 -0
- package/dist/utils/key-template.js +17 -0
- package/dist/utils/key-template.js.map +1 -0
- package/dist/utils/sort-key-template.cjs +19 -0
- package/dist/utils/sort-key-template.cjs.map +1 -0
- package/dist/utils/sort-key-template.js +17 -0
- package/dist/utils/sort-key-template.js.map +1 -0
- 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:
|
|
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
|
|
644
|
+
* Configuration options for DynamoDB filter operations.
|
|
645
|
+
* These are common options shared between query and scan operations.
|
|
525
646
|
*/
|
|
526
|
-
interface
|
|
527
|
-
/**
|
|
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
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
548
|
-
*
|
|
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
|
-
* -
|
|
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
|
-
* @
|
|
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
|
|
639
|
-
|
|
640
|
-
|
|
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
|
|
679
|
+
* Sets the maximum number of items to return.
|
|
646
680
|
* Use this method when you need to:
|
|
647
|
-
* - Limit the
|
|
648
|
-
* -
|
|
649
|
-
* -
|
|
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
|
-
* ```
|
|
656
|
-
* // Get first 10
|
|
657
|
-
* const result = await
|
|
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):
|
|
699
|
+
limit(limit: number): this;
|
|
666
700
|
/**
|
|
667
|
-
* Gets the current limit set on the
|
|
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
|
|
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
|
-
* -
|
|
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):
|
|
736
|
+
useIndex<I extends GSINames<TConfig>>(indexName: I): this;
|
|
735
737
|
/**
|
|
736
|
-
* Sets whether to use strongly consistent reads for the
|
|
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
|
-
* ```
|
|
751
|
+
* ```typescript
|
|
750
752
|
* // Check immediate dinosaur status
|
|
751
|
-
* const result = await
|
|
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
|
|
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):
|
|
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
|
|
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)):
|
|
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
|
|
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[]):
|
|
833
|
+
select(fields: string | string[]): this;
|
|
887
834
|
/**
|
|
888
|
-
*
|
|
889
|
-
*
|
|
890
|
-
* -
|
|
891
|
-
* -
|
|
892
|
-
* -
|
|
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
|
-
* //
|
|
899
|
-
* const
|
|
900
|
-
* .
|
|
901
|
-
* .
|
|
843
|
+
* // Create a paginator for dinosaur records
|
|
844
|
+
* const paginator = builder
|
|
845
|
+
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
846
|
+
* .paginate(10);
|
|
902
847
|
*
|
|
903
|
-
* //
|
|
904
|
-
*
|
|
905
|
-
* .
|
|
906
|
-
* .
|
|
907
|
-
*
|
|
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
|
-
* @
|
|
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
|
|
862
|
+
* Sets the starting point using a previous lastEvaluatedKey.
|
|
914
863
|
* Use this method when you need to:
|
|
915
|
-
* -
|
|
916
|
-
* -
|
|
917
|
-
* -
|
|
918
|
-
* -
|
|
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
|
-
* //
|
|
923
|
-
* const
|
|
924
|
-
* .
|
|
925
|
-
* .
|
|
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
|
-
*
|
|
929
|
-
*
|
|
930
|
-
*
|
|
931
|
-
*
|
|
932
|
-
*
|
|
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
|
-
|
|
895
|
+
startFrom(lastEvaluatedKey: Record<string, unknown>): this;
|
|
938
896
|
/**
|
|
939
|
-
*
|
|
897
|
+
* Creates a deep clone of this builder instance.
|
|
940
898
|
* Use this method when you need to:
|
|
941
|
-
* -
|
|
942
|
-
* -
|
|
943
|
-
* -
|
|
944
|
-
* -
|
|
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
|
-
* //
|
|
949
|
-
* const
|
|
950
|
-
* .useIndex('
|
|
951
|
-
* .
|
|
952
|
-
*
|
|
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
|
|
956
|
-
* const
|
|
957
|
-
* .
|
|
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
|
|
927
|
+
* @returns A new builder instance with the same configuration
|
|
964
928
|
*/
|
|
965
|
-
|
|
929
|
+
abstract clone(): FilterBuilderInterface<T, TConfig>;
|
|
966
930
|
/**
|
|
967
|
-
*
|
|
968
|
-
*
|
|
969
|
-
*
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
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
|
-
*
|
|
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
|
-
* //
|
|
982
|
-
* const
|
|
983
|
-
* .
|
|
984
|
-
* .
|
|
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
|
-
*
|
|
994
|
-
*
|
|
995
|
-
*
|
|
996
|
-
*
|
|
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
|
-
* @
|
|
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
|
|
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
|
-
* //
|
|
1019
|
-
* const
|
|
1020
|
-
* .
|
|
1021
|
-
* .
|
|
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
|
-
*
|
|
1025
|
-
*
|
|
1026
|
-
*
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
1145
|
+
* Configuration options for DynamoDB transactions.
|
|
1129
1146
|
*/
|
|
1130
|
-
interface
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
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
|
-
*
|
|
1143
|
-
*
|
|
1156
|
+
* Configuration for table indexes used in duplicate detection.
|
|
1157
|
+
* Defines the key structure for checking uniqueness constraints.
|
|
1144
1158
|
*/
|
|
1145
|
-
interface
|
|
1146
|
-
/** The
|
|
1147
|
-
|
|
1148
|
-
/**
|
|
1149
|
-
|
|
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
|
|
1163
|
-
* @
|
|
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
|
|
1166
|
-
item?: T;
|
|
1167
|
-
}>;
|
|
1170
|
+
type TransactionExecutor = (params: TransactWriteCommandInput) => Promise<void>;
|
|
1168
1171
|
/**
|
|
1169
|
-
*
|
|
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
|
-
* -
|
|
1185
|
-
* -
|
|
1186
|
-
* -
|
|
1187
|
-
* -
|
|
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
|
|
1191
|
-
* -
|
|
1192
|
-
* -
|
|
1193
|
-
* -
|
|
1194
|
-
* -
|
|
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
|
-
* //
|
|
1199
|
-
* const
|
|
1200
|
-
*
|
|
1201
|
-
*
|
|
1202
|
-
*
|
|
1189
|
+
* // Create a transaction with multiple operations
|
|
1190
|
+
* const transaction = new TransactionBuilder(executor, {
|
|
1191
|
+
* partitionKey: 'id',
|
|
1192
|
+
* sortKey: 'type'
|
|
1193
|
+
* });
|
|
1203
1194
|
*
|
|
1204
|
-
* //
|
|
1205
|
-
*
|
|
1206
|
-
*
|
|
1207
|
-
*
|
|
1208
|
-
*
|
|
1209
|
-
*
|
|
1210
|
-
*
|
|
1211
|
-
*
|
|
1212
|
-
*
|
|
1213
|
-
*
|
|
1214
|
-
*
|
|
1215
|
-
*
|
|
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
|
-
*
|
|
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
|
|
1221
|
-
private
|
|
1219
|
+
declare class TransactionBuilder {
|
|
1220
|
+
private items;
|
|
1222
1221
|
private options;
|
|
1222
|
+
private indexConfig;
|
|
1223
1223
|
private readonly executor;
|
|
1224
|
-
|
|
1225
|
-
private readonly key;
|
|
1226
|
-
constructor(executor: UpdateExecutor<T>, tableName: string, key: PrimaryKeyWithoutExpression);
|
|
1224
|
+
constructor(executor: TransactionExecutor, indexConfig: IndexConfig);
|
|
1227
1225
|
/**
|
|
1228
|
-
*
|
|
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
|
-
* -
|
|
1231
|
-
* -
|
|
1232
|
-
* -
|
|
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
|
-
* //
|
|
1237
|
-
*
|
|
1238
|
-
*
|
|
1239
|
-
*
|
|
1240
|
-
*
|
|
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
|
-
|
|
1273
|
+
put<T extends Record<string, unknown>>(tableName: string, item: T, condition?: Condition): TransactionBuilder;
|
|
1246
1274
|
/**
|
|
1247
|
-
*
|
|
1275
|
+
* Adds a pre-configured put operation to the transaction.
|
|
1248
1276
|
* Use this method when you need to:
|
|
1249
|
-
* -
|
|
1250
|
-
* -
|
|
1251
|
-
* -
|
|
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
|
-
* //
|
|
1256
|
-
*
|
|
1257
|
-
* .
|
|
1258
|
-
* .
|
|
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
|
-
* //
|
|
1261
|
-
*
|
|
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
|
-
|
|
1300
|
+
putWithCommand(command: PutCommandParams): TransactionBuilder;
|
|
1267
1301
|
/**
|
|
1268
|
-
*
|
|
1302
|
+
* Adds a delete operation to the transaction.
|
|
1269
1303
|
* Use this method when you need to:
|
|
1270
|
-
* -
|
|
1271
|
-
* -
|
|
1272
|
-
* -
|
|
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
|
-
* //
|
|
1277
|
-
*
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
1313
|
+
* // Simple delete operation
|
|
1314
|
+
* transaction.delete('orders', {
|
|
1315
|
+
* pk: 'ORDER#123',
|
|
1316
|
+
* sk: 'METADATA'
|
|
1317
|
+
* });
|
|
1280
1318
|
*
|
|
1281
|
-
* //
|
|
1282
|
-
*
|
|
1283
|
-
*
|
|
1284
|
-
*
|
|
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
|
|
1288
|
-
* @
|
|
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
|
-
|
|
1343
|
+
delete(tableName: string, key: PrimaryKeyWithoutExpression, condition?: Condition): TransactionBuilder;
|
|
1291
1344
|
/**
|
|
1292
|
-
* Adds a
|
|
1345
|
+
* Adds a pre-configured delete operation to the transaction.
|
|
1293
1346
|
* Use this method when you need to:
|
|
1294
|
-
* -
|
|
1295
|
-
* - Add
|
|
1296
|
-
* -
|
|
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
|
-
* //
|
|
1301
|
-
*
|
|
1302
|
-
* .
|
|
1303
|
-
*
|
|
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
|
|
1306
|
-
*
|
|
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
|
|
1312
|
-
* @
|
|
1313
|
-
* @
|
|
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
|
-
|
|
1373
|
+
deleteWithCommand(command: DeleteCommandParams): TransactionBuilder;
|
|
1316
1374
|
/**
|
|
1317
|
-
*
|
|
1375
|
+
* Adds an update operation to the transaction.
|
|
1318
1376
|
* Use this method when you need to:
|
|
1319
|
-
* -
|
|
1320
|
-
* - Update
|
|
1321
|
-
* -
|
|
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
|
-
* //
|
|
1326
|
-
*
|
|
1327
|
-
* '
|
|
1328
|
-
*
|
|
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
|
-
* //
|
|
1332
|
-
*
|
|
1333
|
-
* '
|
|
1334
|
-
*
|
|
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
|
-
* //
|
|
1338
|
-
*
|
|
1339
|
-
* '
|
|
1340
|
-
*
|
|
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
|
|
1345
|
-
* @param
|
|
1346
|
-
* @
|
|
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
|
-
|
|
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
|
|
1430
|
+
* Adds a pre-configured update operation to the transaction.
|
|
1351
1431
|
* Use this method when you need to:
|
|
1352
|
-
* -
|
|
1353
|
-
* -
|
|
1354
|
-
* -
|
|
1355
|
-
*
|
|
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
|
-
* //
|
|
1360
|
-
*
|
|
1361
|
-
*
|
|
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
|
-
* //
|
|
1365
|
-
*
|
|
1366
|
-
*
|
|
1367
|
-
*
|
|
1368
|
-
*
|
|
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
|
|
1373
|
-
*
|
|
1374
|
-
*
|
|
1375
|
-
*
|
|
1376
|
-
*
|
|
1377
|
-
* op.
|
|
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
|
-
* //
|
|
1382
|
-
*
|
|
1383
|
-
*
|
|
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
|
|
1388
|
-
* @
|
|
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
|
-
|
|
1513
|
+
conditionCheck(tableName: string, key: PrimaryKeyWithoutExpression, condition: Condition): TransactionBuilder;
|
|
1391
1514
|
/**
|
|
1392
|
-
*
|
|
1515
|
+
* Adds a pre-configured condition check operation to the transaction.
|
|
1393
1516
|
* Use this method when you need to:
|
|
1394
|
-
* -
|
|
1395
|
-
* -
|
|
1396
|
-
* -
|
|
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
|
-
*
|
|
1400
|
-
*
|
|
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
|
-
* //
|
|
1409
|
-
* const
|
|
1410
|
-
* .
|
|
1411
|
-
*
|
|
1412
|
-
*
|
|
1413
|
-
*
|
|
1414
|
-
*
|
|
1415
|
-
*
|
|
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
|
-
*
|
|
1424
|
-
*
|
|
1425
|
-
* }
|
|
1535
|
+
* // Add the command to the transaction
|
|
1536
|
+
* transaction.conditionCheckWithCommand(checkCommand);
|
|
1426
1537
|
* ```
|
|
1427
1538
|
*
|
|
1428
|
-
* @param
|
|
1429
|
-
* @returns The builder
|
|
1430
|
-
|
|
1431
|
-
|
|
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
|
-
|
|
1544
|
+
conditionCheckWithCommand(command: ConditionCheckCommandParams): TransactionBuilder;
|
|
1436
1545
|
/**
|
|
1437
|
-
*
|
|
1546
|
+
* Sets options for the transaction execution.
|
|
1438
1547
|
* Use this method when you need to:
|
|
1439
|
-
* -
|
|
1440
|
-
* -
|
|
1441
|
-
* -
|
|
1548
|
+
* - Enable idempotent transactions
|
|
1549
|
+
* - Track consumed capacity
|
|
1550
|
+
* - Monitor item collection metrics
|
|
1442
1551
|
*
|
|
1443
1552
|
* @example
|
|
1444
1553
|
* ```typescript
|
|
1445
|
-
*
|
|
1446
|
-
*
|
|
1447
|
-
*
|
|
1448
|
-
*
|
|
1449
|
-
*
|
|
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
|
-
* //
|
|
1459
|
-
*
|
|
1560
|
+
* // Track item collection metrics
|
|
1561
|
+
* transaction.withOptions({
|
|
1562
|
+
* returnItemCollectionMetrics: 'SIZE'
|
|
1563
|
+
* });
|
|
1460
1564
|
* ```
|
|
1461
1565
|
*
|
|
1462
|
-
*
|
|
1463
|
-
*
|
|
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
|
-
|
|
1572
|
+
withOptions(options: TransactionOptions): TransactionBuilder;
|
|
1466
1573
|
/**
|
|
1467
|
-
* Gets a human-readable representation of the
|
|
1574
|
+
* Gets a human-readable representation of the transaction items.
|
|
1468
1575
|
* Use this method when you need to:
|
|
1469
|
-
* - Debug complex
|
|
1470
|
-
* - Verify
|
|
1471
|
-
* - Log
|
|
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
|
-
* //
|
|
1477
|
-
*
|
|
1478
|
-
* .
|
|
1479
|
-
*
|
|
1480
|
-
* '
|
|
1481
|
-
* '
|
|
1482
|
-
*
|
|
1483
|
-
*
|
|
1484
|
-
*
|
|
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
|
|
1487
|
-
* const debugInfo =
|
|
1488
|
-
* console.log('
|
|
1596
|
+
* // Debug the transaction
|
|
1597
|
+
* const debugInfo = transaction.debug();
|
|
1598
|
+
* console.log('Transaction operations:', debugInfo);
|
|
1489
1599
|
* ```
|
|
1490
1600
|
*
|
|
1491
|
-
* @returns
|
|
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
|
|
1605
|
+
* Executes all operations in the transaction atomically.
|
|
1496
1606
|
* Use this method when you need to:
|
|
1497
|
-
* -
|
|
1498
|
-
* -
|
|
1499
|
-
* -
|
|
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
|
-
* //
|
|
1505
|
-
*
|
|
1506
|
-
* .
|
|
1507
|
-
*
|
|
1508
|
-
*
|
|
1509
|
-
* '
|
|
1510
|
-
*
|
|
1511
|
-
*
|
|
1512
|
-
*
|
|
1513
|
-
*
|
|
1514
|
-
*
|
|
1515
|
-
*
|
|
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
|
-
*
|
|
1522
|
-
* console.log('Updated dinosaur:', result.item);
|
|
1523
|
-
* }
|
|
1632
|
+
* console.log('Transaction completed successfully');
|
|
1524
1633
|
* } catch (error) {
|
|
1525
|
-
* // Handle
|
|
1526
|
-
* console.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
|
-
* @
|
|
1535
|
-
* @throws {
|
|
1536
|
-
* @
|
|
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
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
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
|
|
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
|
|
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
|
-
* //
|
|
1565
|
-
* const result = await new
|
|
1566
|
-
*
|
|
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
|
-
* //
|
|
1569
|
-
* const result = await new
|
|
1570
|
-
*
|
|
1571
|
-
*
|
|
1572
|
-
*
|
|
1573
|
-
*
|
|
1574
|
-
*
|
|
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
|
|
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
|
-
|
|
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
|
|
1699
|
+
* Adds a condition that must be satisfied for the put operation to succeed.
|
|
1589
1700
|
* Use this method when you need to:
|
|
1590
|
-
* -
|
|
1591
|
-
* -
|
|
1592
|
-
* - Implement
|
|
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
|
|
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('
|
|
1600
|
-
* op.
|
|
1601
|
-
* op.
|
|
1736
|
+
* op.eq('securityStatus', 'READY'),
|
|
1737
|
+
* op.attributeExists('lastInspection'),
|
|
1738
|
+
* op.gt('securityLevel', 5)
|
|
1602
1739
|
* ])
|
|
1603
1740
|
* );
|
|
1604
1741
|
*
|
|
1605
|
-
* //
|
|
1742
|
+
* // Check breeding facility conditions
|
|
1606
1743
|
* builder.condition(op =>
|
|
1607
1744
|
* op.and([
|
|
1608
|
-
* op.
|
|
1609
|
-
* op.
|
|
1610
|
-
* op.
|
|
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
|
|
1755
|
+
condition(condition: Condition | ((op: ConditionOperator<T>) => Condition)): this;
|
|
1619
1756
|
/**
|
|
1620
|
-
* Sets whether to return the item's
|
|
1621
|
-
*
|
|
1622
|
-
*
|
|
1623
|
-
*
|
|
1624
|
-
*
|
|
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
|
-
* //
|
|
1766
|
+
* // Get previous dinosaur state
|
|
1629
1767
|
* const result = await builder
|
|
1630
1768
|
* .returnValues('ALL_OLD')
|
|
1631
1769
|
* .execute();
|
|
1632
1770
|
*
|
|
1633
|
-
* if (result
|
|
1634
|
-
* console.log('
|
|
1635
|
-
* species: result.
|
|
1636
|
-
*
|
|
1637
|
-
*
|
|
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
|
|
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"):
|
|
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
|
|
1792
|
+
* Adds this put operation to a transaction.
|
|
1652
1793
|
* Use this method when you need to:
|
|
1653
|
-
* -
|
|
1654
|
-
* -
|
|
1655
|
-
* -
|
|
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
|
-
* //
|
|
1662
|
-
* new
|
|
1663
|
-
*
|
|
1664
|
-
*
|
|
1665
|
-
*
|
|
1666
|
-
*
|
|
1667
|
-
*
|
|
1668
|
-
* .
|
|
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):
|
|
1824
|
+
withTransaction(transaction: TransactionBuilder): this;
|
|
1678
1825
|
/**
|
|
1679
|
-
* Executes the
|
|
1826
|
+
* Executes the put operation against DynamoDB.
|
|
1680
1827
|
*
|
|
1681
1828
|
* @example
|
|
1682
1829
|
* ```ts
|
|
1683
|
-
*
|
|
1684
|
-
*
|
|
1685
|
-
*
|
|
1686
|
-
*
|
|
1687
|
-
*
|
|
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
|
-
*
|
|
1690
|
-
*
|
|
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
|
|
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
|
|
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
|
|
1711
|
-
*
|
|
1712
|
-
*
|
|
1713
|
-
*
|
|
1714
|
-
*
|
|
1715
|
-
*
|
|
1716
|
-
*
|
|
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('
|
|
1873
|
+
* console.log('Dinosaur transfer command:', debugInfo);
|
|
1721
1874
|
* ```
|
|
1722
1875
|
*
|
|
1723
|
-
* @returns A readable representation of the
|
|
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
|
|
1729
|
-
|
|
1730
|
-
|
|
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
|
|
1889
|
+
* Builder for creating DynamoDB delete operations.
|
|
1737
1890
|
* Use this builder when you need to:
|
|
1738
|
-
* -
|
|
1739
|
-
* -
|
|
1740
|
-
* -
|
|
1741
|
-
* -
|
|
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
|
-
* //
|
|
1746
|
-
* const
|
|
1747
|
-
* .
|
|
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
|
-
* //
|
|
1757
|
-
* const
|
|
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('
|
|
1761
|
-
* op.
|
|
1762
|
-
* op.lt('
|
|
1906
|
+
* op.eq('status', 'DECOMMISSIONED'),
|
|
1907
|
+
* op.eq('occupants', 0),
|
|
1908
|
+
* op.lt('securityIncidents', 1)
|
|
1763
1909
|
* ])
|
|
1764
1910
|
* )
|
|
1765
|
-
* .
|
|
1911
|
+
* .returnValues('ALL_OLD')
|
|
1912
|
+
* .execute();
|
|
1766
1913
|
* ```
|
|
1767
1914
|
*/
|
|
1768
|
-
declare class
|
|
1769
|
-
private
|
|
1915
|
+
declare class DeleteBuilder {
|
|
1916
|
+
private options;
|
|
1917
|
+
private readonly executor;
|
|
1770
1918
|
private readonly tableName;
|
|
1771
|
-
private
|
|
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
|
|
1922
|
+
* Adds a condition that must be satisfied for the delete operation to succeed.
|
|
1775
1923
|
* Use this method when you need to:
|
|
1776
|
-
* -
|
|
1777
|
-
* -
|
|
1778
|
-
* -
|
|
1924
|
+
* - Ensure safe removal conditions
|
|
1925
|
+
* - Verify habitat status before deletion
|
|
1926
|
+
* - Implement safety protocols
|
|
1779
1927
|
*
|
|
1780
1928
|
* @example
|
|
1781
1929
|
* ```typescript
|
|
1782
|
-
* //
|
|
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('
|
|
1795
|
-
* op.
|
|
1796
|
-
* op.attributeExists('
|
|
1933
|
+
* op.eq('status', 'SEDATED'),
|
|
1934
|
+
* op.eq('location', 'MEDICAL_BAY'),
|
|
1935
|
+
* op.attributeExists('lastCheckup')
|
|
1797
1936
|
* ])
|
|
1798
1937
|
* );
|
|
1799
1938
|
*
|
|
1800
|
-
* //
|
|
1939
|
+
* // Verify habitat is empty
|
|
1801
1940
|
* builder.condition(op =>
|
|
1802
1941
|
* op.and([
|
|
1803
|
-
* op.eq('
|
|
1804
|
-
* op.
|
|
1805
|
-
* op.
|
|
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)):
|
|
1952
|
+
condition<T extends Record<string, unknown>>(condition: Condition | ((op: ConditionOperator<T>) => Condition)): DeleteBuilder;
|
|
1814
1953
|
/**
|
|
1815
|
-
*
|
|
1816
|
-
* Use this method when you
|
|
1817
|
-
* -
|
|
1818
|
-
* -
|
|
1819
|
-
* -
|
|
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
|
-
*
|
|
1824
|
-
*
|
|
1825
|
-
* .
|
|
1826
|
-
*
|
|
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
|
-
* @
|
|
1830
|
-
* @returns The
|
|
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
|
|
1985
|
+
* Adds this delete operation to a transaction.
|
|
1835
1986
|
* Use this method when you need to:
|
|
1836
|
-
* -
|
|
1837
|
-
* -
|
|
1838
|
-
* -
|
|
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
|
-
*
|
|
1844
|
-
*
|
|
1845
|
-
*
|
|
1846
|
-
*
|
|
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
|
-
*
|
|
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):
|
|
2011
|
+
withTransaction(transaction: TransactionBuilder): void;
|
|
1858
2012
|
/**
|
|
1859
|
-
*
|
|
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
|
-
*
|
|
1870
|
-
*
|
|
1871
|
-
*
|
|
1872
|
-
*
|
|
1873
|
-
*
|
|
1874
|
-
*
|
|
1875
|
-
*
|
|
1876
|
-
* .
|
|
1877
|
-
*
|
|
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
|
|
2028
|
+
* @returns A promise that resolves to an object containing the deleted item's attributes (if returnValues is 'ALL_OLD')
|
|
1881
2029
|
*/
|
|
1882
|
-
|
|
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
|
|
2063
|
+
* Configuration options for DynamoDB update operations.
|
|
1887
2064
|
*/
|
|
1888
|
-
interface
|
|
1889
|
-
/**
|
|
1890
|
-
|
|
1891
|
-
/**
|
|
1892
|
-
|
|
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
|
-
*
|
|
1898
|
-
*
|
|
2072
|
+
* Function type for executing DynamoDB update operations.
|
|
2073
|
+
* @typeParam T - The type of the item being updated
|
|
1899
2074
|
*/
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
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
|
-
*
|
|
1908
|
-
*
|
|
1909
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
-
* -
|
|
1916
|
-
* -
|
|
1917
|
-
* -
|
|
1918
|
-
* -
|
|
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
|
-
* -
|
|
1922
|
-
* - Delete
|
|
1923
|
-
* - Update
|
|
1924
|
-
* -
|
|
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
|
-
* //
|
|
1931
|
-
* const
|
|
1932
|
-
*
|
|
1933
|
-
*
|
|
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
|
-
* //
|
|
1952
|
-
* await
|
|
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
|
-
*
|
|
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
|
|
1961
|
-
private
|
|
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
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
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
|
-
*
|
|
2154
|
+
* Sets multiple attributes of an item using an object.
|
|
1973
2155
|
* Use this method when you need to:
|
|
1974
|
-
* -
|
|
1975
|
-
* -
|
|
1976
|
-
* -
|
|
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
|
-
* //
|
|
1984
|
-
*
|
|
1985
|
-
*
|
|
1986
|
-
*
|
|
1987
|
-
*
|
|
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
|
-
|
|
2171
|
+
set(values: Partial<T>): UpdateBuilder<T>;
|
|
2042
2172
|
/**
|
|
2043
|
-
*
|
|
2173
|
+
* Sets a single attribute to a specific value.
|
|
2044
2174
|
* Use this method when you need to:
|
|
2045
|
-
* -
|
|
2046
|
-
* -
|
|
2047
|
-
* -
|
|
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
|
-
* //
|
|
2055
|
-
*
|
|
2056
|
-
*
|
|
2057
|
-
*
|
|
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
|
-
*
|
|
2079
|
-
*
|
|
2080
|
-
*
|
|
2081
|
-
*
|
|
2082
|
-
*
|
|
2186
|
+
* // Set nested attributes
|
|
2187
|
+
* builder
|
|
2188
|
+
* .set('location.zone', 'RESTRICTED')
|
|
2189
|
+
* .set('stats.health', 100);
|
|
2190
|
+
* ```
|
|
2083
2191
|
*/
|
|
2084
|
-
|
|
2192
|
+
set<K extends Path<T>>(path: K, value: PathType<T, K>): UpdateBuilder<T>;
|
|
2085
2193
|
/**
|
|
2086
|
-
*
|
|
2194
|
+
* Removes an attribute from the item.
|
|
2087
2195
|
* Use this method when you need to:
|
|
2088
|
-
* -
|
|
2089
|
-
* -
|
|
2090
|
-
* -
|
|
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
|
-
* //
|
|
2098
|
-
*
|
|
2099
|
-
* .
|
|
2100
|
-
*
|
|
2101
|
-
* op.eq('status', 'INACTIVE')
|
|
2102
|
-
* ]))
|
|
2103
|
-
* .toDynamoCommand();
|
|
2202
|
+
* // Remove simple attributes
|
|
2203
|
+
* builder
|
|
2204
|
+
* .remove('temporaryTag')
|
|
2205
|
+
* .remove('previousLocation');
|
|
2104
2206
|
*
|
|
2105
|
-
* //
|
|
2106
|
-
*
|
|
2207
|
+
* // Remove nested attributes
|
|
2208
|
+
* builder
|
|
2209
|
+
* .remove('metadata.testData')
|
|
2210
|
+
* .remove('stats.experimentalMetrics');
|
|
2107
2211
|
* ```
|
|
2108
2212
|
*
|
|
2109
|
-
* @param
|
|
2110
|
-
* @returns The
|
|
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
|
-
|
|
2216
|
+
remove<K extends Path<T>>(path: K): UpdateBuilder<T>;
|
|
2115
2217
|
/**
|
|
2116
|
-
* Adds
|
|
2218
|
+
* Adds a value to a number attribute or adds elements to a set.
|
|
2117
2219
|
* Use this method when you need to:
|
|
2118
|
-
* -
|
|
2119
|
-
* -
|
|
2120
|
-
* -
|
|
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
|
-
* //
|
|
2132
|
-
*
|
|
2133
|
-
* '
|
|
2134
|
-
*
|
|
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
|
-
* //
|
|
2150
|
-
*
|
|
2151
|
-
* '
|
|
2152
|
-
*
|
|
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
|
|
2161
|
-
* @param
|
|
2162
|
-
* @
|
|
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
|
-
|
|
2241
|
+
add<K extends Path<T>>(path: K, value: PathType<T, K>): UpdateBuilder<T>;
|
|
2170
2242
|
/**
|
|
2171
|
-
*
|
|
2243
|
+
* Removes elements from a set attribute.
|
|
2172
2244
|
* Use this method when you need to:
|
|
2173
|
-
* -
|
|
2174
|
-
* -
|
|
2175
|
-
* -
|
|
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
|
-
* //
|
|
2183
|
-
*
|
|
2184
|
-
*
|
|
2185
|
-
*
|
|
2186
|
-
*
|
|
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
|
-
* //
|
|
2194
|
-
*
|
|
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
|
|
2198
|
-
* @
|
|
2199
|
-
* @
|
|
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
|
-
|
|
2274
|
+
deleteElementsFromSet<K extends Path<T>>(path: K, value: PathSetElementType<T, K>[] | Set<PathSetElementType<T, K>>): UpdateBuilder<T>;
|
|
2203
2275
|
/**
|
|
2204
|
-
* Adds a condition
|
|
2276
|
+
* Adds a condition that must be satisfied for the update to succeed.
|
|
2205
2277
|
* Use this method when you need to:
|
|
2206
|
-
* -
|
|
2207
|
-
* - Ensure
|
|
2208
|
-
* -
|
|
2209
|
-
* -
|
|
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
|
-
* //
|
|
2219
|
-
*
|
|
2220
|
-
* '
|
|
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
|
-
* //
|
|
2226
|
-
*
|
|
2227
|
-
*
|
|
2228
|
-
*
|
|
2229
|
-
*
|
|
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
|
-
* //
|
|
2237
|
-
*
|
|
2238
|
-
*
|
|
2239
|
-
*
|
|
2240
|
-
*
|
|
2241
|
-
* op.
|
|
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
|
|
2248
|
-
* @
|
|
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
|
-
|
|
2316
|
+
condition(condition: Condition | ((op: ConditionOperator<T>) => Condition)): UpdateBuilder<T>;
|
|
2255
2317
|
/**
|
|
2256
|
-
*
|
|
2318
|
+
* Sets which item attributes to include in the response.
|
|
2257
2319
|
* Use this method when you need to:
|
|
2258
|
-
* -
|
|
2259
|
-
* -
|
|
2260
|
-
* -
|
|
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
|
-
*
|
|
2263
|
-
*
|
|
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
|
-
* //
|
|
2268
|
-
* const
|
|
2269
|
-
* .
|
|
2270
|
-
*
|
|
2271
|
-
*
|
|
2272
|
-
*
|
|
2273
|
-
*
|
|
2274
|
-
*
|
|
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
|
-
*
|
|
2277
|
-
*
|
|
2349
|
+
* if (result.item) {
|
|
2350
|
+
* console.log('Previous health:', result.item.stats?.health);
|
|
2351
|
+
* }
|
|
2278
2352
|
* ```
|
|
2279
2353
|
*
|
|
2280
|
-
* @param
|
|
2281
|
-
* @returns The
|
|
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
|
-
|
|
2357
|
+
returnValues(returnValues: "ALL_NEW" | "UPDATED_NEW" | "ALL_OLD" | "UPDATED_OLD" | "NONE"): UpdateBuilder<T>;
|
|
2286
2358
|
/**
|
|
2287
|
-
*
|
|
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
|
-
* -
|
|
2290
|
-
* -
|
|
2291
|
-
* -
|
|
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
|
-
*
|
|
2296
|
-
* transaction.withOptions({
|
|
2297
|
-
* clientRequestToken: 'unique-request-id-123',
|
|
2298
|
-
* returnConsumedCapacity: 'TOTAL'
|
|
2299
|
-
* });
|
|
2371
|
+
* const transaction = new TransactionBuilder(executor);
|
|
2300
2372
|
*
|
|
2301
|
-
* //
|
|
2302
|
-
*
|
|
2303
|
-
*
|
|
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
|
-
*
|
|
2308
|
-
*
|
|
2379
|
+
* new UpdateBuilder(executor, 'habitats', { id: 'PADDOCK-A' })
|
|
2380
|
+
* .add('occupants', 1)
|
|
2381
|
+
* .set('lastOccupied', new Date().toISOString())
|
|
2382
|
+
* .withTransaction(transaction);
|
|
2309
2383
|
*
|
|
2310
|
-
*
|
|
2311
|
-
*
|
|
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
|
-
|
|
2391
|
+
withTransaction(transaction: TransactionBuilder): void;
|
|
2314
2392
|
/**
|
|
2315
|
-
* Gets a human-readable representation of the
|
|
2393
|
+
* Gets a human-readable representation of the update command.
|
|
2316
2394
|
* Use this method when you need to:
|
|
2317
|
-
* - Debug complex
|
|
2318
|
-
* - Verify
|
|
2319
|
-
* - Log
|
|
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
|
-
* //
|
|
2328
|
-
*
|
|
2329
|
-
* .
|
|
2330
|
-
*
|
|
2331
|
-
*
|
|
2332
|
-
* '
|
|
2333
|
-
*
|
|
2334
|
-
*
|
|
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
|
|
2338
|
-
* const debugInfo =
|
|
2339
|
-
* console.log('
|
|
2412
|
+
* // Debug the update
|
|
2413
|
+
* const debugInfo = builder.debug();
|
|
2414
|
+
* console.log('Update operation:', debugInfo);
|
|
2340
2415
|
* ```
|
|
2341
2416
|
*
|
|
2342
|
-
* @returns
|
|
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
|
|
2421
|
+
* Executes the update operation against DynamoDB.
|
|
2347
2422
|
* Use this method when you need to:
|
|
2348
|
-
* -
|
|
2349
|
-
* -
|
|
2350
|
-
* -
|
|
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
|
-
* //
|
|
2359
|
-
* await
|
|
2360
|
-
* .
|
|
2361
|
-
*
|
|
2362
|
-
*
|
|
2363
|
-
* '
|
|
2364
|
-
*
|
|
2365
|
-
*
|
|
2366
|
-
*
|
|
2367
|
-
*
|
|
2368
|
-
*
|
|
2369
|
-
*
|
|
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
|
-
*
|
|
2447
|
+
* if (result.item) {
|
|
2448
|
+
* console.log('Updated dinosaur:', result.item);
|
|
2449
|
+
* }
|
|
2374
2450
|
* } catch (error) {
|
|
2375
|
-
* // Handle
|
|
2376
|
-
* console.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
|
-
* @
|
|
2381
|
-
* @throws {
|
|
2382
|
-
* @
|
|
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<
|
|
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
|
-
*
|
|
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
|
-
* -
|
|
2404
|
-
* -
|
|
2405
|
-
* -
|
|
2406
|
-
* -
|
|
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
|
-
* //
|
|
2411
|
-
* const
|
|
2412
|
-
*
|
|
2413
|
-
*
|
|
2414
|
-
*
|
|
2415
|
-
*
|
|
2416
|
-
*
|
|
2417
|
-
*
|
|
2418
|
-
*
|
|
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
|
-
*
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
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
|
|
2516
|
+
* Adds a condition that must be satisfied for the check to succeed.
|
|
2469
2517
|
* Use this method when you need to:
|
|
2470
|
-
* -
|
|
2471
|
-
* -
|
|
2472
|
-
* -
|
|
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
|
-
* //
|
|
2524
|
+
* // Check dinosaur health and behavior
|
|
2477
2525
|
* builder.condition(op =>
|
|
2478
|
-
* op.
|
|
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
|
|
2533
|
+
* // Verify habitat conditions
|
|
2482
2534
|
* builder.condition(op =>
|
|
2483
2535
|
* op.and([
|
|
2484
|
-
* op.eq('
|
|
2485
|
-
* op.
|
|
2486
|
-
* op.
|
|
2536
|
+
* op.eq('powerStatus', 'ONLINE'),
|
|
2537
|
+
* op.between('temperature', 20, 30),
|
|
2538
|
+
* op.attributeExists('lastMaintenance')
|
|
2487
2539
|
* ])
|
|
2488
2540
|
* );
|
|
2489
2541
|
*
|
|
2490
|
-
* // Check breeding
|
|
2542
|
+
* // Check breeding conditions
|
|
2491
2543
|
* builder.condition(op =>
|
|
2492
2544
|
* op.and([
|
|
2493
|
-
* op.
|
|
2494
|
-
* op.
|
|
2495
|
-
* op.eq('
|
|
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)):
|
|
2555
|
+
condition<T extends Record<string, unknown>>(condition: Condition | ((op: ConditionOperator<T>) => Condition)): ConditionCheckBuilder;
|
|
2504
2556
|
/**
|
|
2505
|
-
*
|
|
2506
|
-
* Use this method when you
|
|
2507
|
-
* -
|
|
2508
|
-
* -
|
|
2509
|
-
* -
|
|
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
|
-
*
|
|
2514
|
-
*
|
|
2515
|
-
* .
|
|
2516
|
-
*
|
|
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
|
-
* @
|
|
2531
|
-
* @returns The
|
|
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
|
|
2576
|
+
* Adds this condition check operation to a transaction.
|
|
2540
2577
|
* Use this method when you need to:
|
|
2541
|
-
* -
|
|
2542
|
-
* -
|
|
2543
|
-
* -
|
|
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
|
-
*
|
|
2550
|
-
*
|
|
2551
|
-
*
|
|
2552
|
-
*
|
|
2553
|
-
*
|
|
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):
|
|
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
|
|
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
|
|
2600
|
-
* - Verify
|
|
2601
|
-
* - Log
|
|
2602
|
-
* - Troubleshoot
|
|
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
|
|
2607
|
-
*
|
|
2608
|
-
*
|
|
2609
|
-
*
|
|
2610
|
-
*
|
|
2611
|
-
*
|
|
2612
|
-
*
|
|
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
|
|
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
|
|
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 };
|