dyno-table 1.6.0 → 1.8.0-next.1
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/README.md +53 -140
- package/dist/batch-builder-BOBwOIUE.d.ts +398 -0
- package/dist/batch-builder-CKYnMRyz.d.cts +398 -0
- package/dist/{builder-types-DlaUSc-b.d.cts → builder-types-BTVhQSHI.d.cts} +55 -5
- package/dist/{builder-types-B_tCpn9F.d.ts → builder-types-CzuLR4Th.d.ts} +55 -5
- package/dist/builders/condition-check-builder.cjs +0 -13
- package/dist/builders/condition-check-builder.cjs.map +1 -1
- package/dist/builders/condition-check-builder.d.cts +1 -14
- package/dist/builders/condition-check-builder.d.ts +1 -14
- package/dist/builders/condition-check-builder.js +0 -13
- package/dist/builders/condition-check-builder.js.map +1 -1
- package/dist/builders/delete-builder.cjs +38 -0
- package/dist/builders/delete-builder.cjs.map +1 -1
- package/dist/builders/delete-builder.d.cts +37 -1
- package/dist/builders/delete-builder.d.ts +37 -1
- package/dist/builders/delete-builder.js +38 -0
- package/dist/builders/delete-builder.js.map +1 -1
- package/dist/builders/paginator.cjs +21 -27
- package/dist/builders/paginator.cjs.map +1 -1
- package/dist/builders/paginator.d.cts +3 -27
- package/dist/builders/paginator.d.ts +3 -27
- package/dist/builders/paginator.js +21 -27
- package/dist/builders/paginator.js.map +1 -1
- package/dist/builders/put-builder.cjs +39 -8
- package/dist/builders/put-builder.cjs.map +1 -1
- package/dist/builders/put-builder.d.cts +38 -9
- package/dist/builders/put-builder.d.ts +38 -9
- package/dist/builders/put-builder.js +39 -8
- package/dist/builders/put-builder.js.map +1 -1
- package/dist/builders/query-builder.cjs +115 -75
- package/dist/builders/query-builder.cjs.map +1 -1
- package/dist/builders/query-builder.d.cts +2 -2
- package/dist/builders/query-builder.d.ts +2 -2
- package/dist/builders/query-builder.js +115 -75
- package/dist/builders/query-builder.js.map +1 -1
- package/dist/builders/transaction-builder.cjs +0 -47
- package/dist/builders/transaction-builder.cjs.map +1 -1
- package/dist/builders/transaction-builder.d.cts +1 -48
- package/dist/builders/transaction-builder.d.ts +1 -48
- package/dist/builders/transaction-builder.js +0 -47
- package/dist/builders/transaction-builder.js.map +1 -1
- package/dist/builders/update-builder.cjs +2 -2
- package/dist/builders/update-builder.cjs.map +1 -1
- package/dist/builders/update-builder.d.cts +3 -3
- package/dist/builders/update-builder.d.ts +3 -3
- package/dist/builders/update-builder.js +2 -2
- package/dist/builders/update-builder.js.map +1 -1
- package/dist/conditions.cjs.map +1 -1
- package/dist/conditions.js.map +1 -1
- package/dist/entity.cjs +69 -37
- package/dist/entity.cjs.map +1 -1
- package/dist/entity.d.cts +30 -10
- package/dist/entity.d.ts +30 -10
- package/dist/entity.js +69 -37
- package/dist/entity.js.map +1 -1
- package/dist/index.cjs +661 -218
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +660 -219
- package/dist/index.js.map +1 -1
- package/dist/{query-builder-BhrR31oO.d.ts → query-builder-CaHzZmDf.d.ts} +31 -63
- package/dist/{query-builder-CbHvimBk.d.cts → query-builder-DFkxojBM.d.cts} +31 -63
- package/dist/{table-CY9byPEg.d.cts → table-CHitMHXE.d.cts} +55 -169
- package/dist/{table-Des8C2od.d.ts → table-m7DQk5dK.d.ts} +55 -169
- package/dist/table.cjs +590 -181
- package/dist/table.cjs.map +1 -1
- package/dist/table.d.cts +4 -3
- package/dist/table.d.ts +4 -3
- package/dist/table.js +590 -181
- package/dist/table.js.map +1 -1
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
package/dist/table.js
CHANGED
|
@@ -208,10 +208,6 @@ var Paginator = class {
|
|
|
208
208
|
}
|
|
209
209
|
/**
|
|
210
210
|
* Gets the current page number (1-indexed).
|
|
211
|
-
* Use this method when you need to:
|
|
212
|
-
* - Track progress through dinosaur lists
|
|
213
|
-
* - Display habitat inspection status
|
|
214
|
-
* - Monitor security sweep progress
|
|
215
211
|
*
|
|
216
212
|
* @example
|
|
217
213
|
* ```ts
|
|
@@ -229,11 +225,6 @@ var Paginator = class {
|
|
|
229
225
|
}
|
|
230
226
|
/**
|
|
231
227
|
* Checks if there are more pages of dinosaurs or habitats to process.
|
|
232
|
-
* Use this method when you need to:
|
|
233
|
-
* - Check for more dinosaurs to review
|
|
234
|
-
* - Continue habitat inspections
|
|
235
|
-
* - Process security incidents
|
|
236
|
-
* - Complete feeding schedules
|
|
237
228
|
*
|
|
238
229
|
* This method takes into account both:
|
|
239
230
|
* - DynamoDB's lastEvaluatedKey mechanism
|
|
@@ -265,11 +256,6 @@ var Paginator = class {
|
|
|
265
256
|
}
|
|
266
257
|
/**
|
|
267
258
|
* Retrieves the next page of dinosaurs or habitats from DynamoDB.
|
|
268
|
-
* Use this method when you need to:
|
|
269
|
-
* - Process dinosaur groups systematically
|
|
270
|
-
* - Review habitat inspections in batches
|
|
271
|
-
* - Monitor security incidents in sequence
|
|
272
|
-
* - Schedule feeding rotations
|
|
273
259
|
*
|
|
274
260
|
* This method handles:
|
|
275
261
|
* - Automatic continuation between groups
|
|
@@ -321,13 +307,31 @@ var Paginator = class {
|
|
|
321
307
|
page: this.currentPage
|
|
322
308
|
};
|
|
323
309
|
}
|
|
324
|
-
|
|
310
|
+
if (effectivePageSize !== void 0) {
|
|
311
|
+
effectivePageSize = Math.min(effectivePageSize, remainingItems);
|
|
312
|
+
} else {
|
|
313
|
+
effectivePageSize = remainingItems;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
const query = this.queryBuilder.clone();
|
|
317
|
+
if (effectivePageSize !== void 0) {
|
|
318
|
+
query.limit(effectivePageSize);
|
|
325
319
|
}
|
|
326
|
-
const query = this.queryBuilder.clone().limit(effectivePageSize);
|
|
327
320
|
if (this.lastEvaluatedKey) {
|
|
328
321
|
query.startFrom(this.lastEvaluatedKey);
|
|
329
322
|
}
|
|
330
|
-
const
|
|
323
|
+
const generator = await query.execute();
|
|
324
|
+
const items = [];
|
|
325
|
+
let itemCount = 0;
|
|
326
|
+
for await (const item of generator) {
|
|
327
|
+
if (effectivePageSize !== void 0 && itemCount >= effectivePageSize) {
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
items.push(item);
|
|
331
|
+
itemCount++;
|
|
332
|
+
}
|
|
333
|
+
const lastEvaluatedKey = generator.getLastEvaluatedKey();
|
|
334
|
+
const result = { items, lastEvaluatedKey };
|
|
331
335
|
this.currentPage += 1;
|
|
332
336
|
this.lastEvaluatedKey = result.lastEvaluatedKey;
|
|
333
337
|
this.totalItemsRetrieved += result.items.length;
|
|
@@ -341,16 +345,6 @@ var Paginator = class {
|
|
|
341
345
|
}
|
|
342
346
|
/**
|
|
343
347
|
* Gets all remaining dinosaurs or habitats and combines them into a single array.
|
|
344
|
-
* Use this method when you need to:
|
|
345
|
-
* - Generate complete park inventory
|
|
346
|
-
* - Perform full security audit
|
|
347
|
-
* - Create comprehensive feeding schedule
|
|
348
|
-
* - Run park-wide health checks
|
|
349
|
-
*
|
|
350
|
-
* Note: Use with caution! This method:
|
|
351
|
-
* - Could overwhelm systems with large dinosaur populations
|
|
352
|
-
* - Makes multiple database requests
|
|
353
|
-
* - May cause system strain during peak hours
|
|
354
348
|
*
|
|
355
349
|
* @example
|
|
356
350
|
* ```ts
|
|
@@ -392,10 +386,6 @@ var FilterBuilder = class {
|
|
|
392
386
|
selectedFields = /* @__PURE__ */ new Set();
|
|
393
387
|
/**
|
|
394
388
|
* Sets the maximum number of items to return.
|
|
395
|
-
* Use this method when you need to:
|
|
396
|
-
* - Limit the number of dinosaurs returned
|
|
397
|
-
* - Control the size of habitat reports
|
|
398
|
-
* - Implement manual pagination of security logs
|
|
399
389
|
*
|
|
400
390
|
* Note: This limit applies to the items that match the key condition
|
|
401
391
|
* before any filter expressions are applied.
|
|
@@ -426,11 +416,6 @@ var FilterBuilder = class {
|
|
|
426
416
|
}
|
|
427
417
|
/**
|
|
428
418
|
* Specifies a Global Secondary Index (GSI) to use for the operation.
|
|
429
|
-
* Use this method when you need to:
|
|
430
|
-
* - Find dinosaurs by species or status
|
|
431
|
-
* - Search habitats by security level
|
|
432
|
-
* - Find incidents by date
|
|
433
|
-
* - List feeding schedules by time
|
|
434
419
|
*
|
|
435
420
|
* @example
|
|
436
421
|
* ```typescript
|
|
@@ -459,11 +444,6 @@ var FilterBuilder = class {
|
|
|
459
444
|
}
|
|
460
445
|
/**
|
|
461
446
|
* Sets whether to use strongly consistent reads for the operation.
|
|
462
|
-
* Use this method when you need to:
|
|
463
|
-
* - Get real-time dinosaur status updates
|
|
464
|
-
* - Monitor critical security systems
|
|
465
|
-
* - Track immediate habitat changes
|
|
466
|
-
* - Verify containment protocols
|
|
467
447
|
*
|
|
468
448
|
* Note:
|
|
469
449
|
* - Consistent reads are not available on GSIs
|
|
@@ -494,11 +474,6 @@ var FilterBuilder = class {
|
|
|
494
474
|
}
|
|
495
475
|
/**
|
|
496
476
|
* Adds a filter expression to refine the operation results.
|
|
497
|
-
* Use this method when you need to:
|
|
498
|
-
* - Filter dinosaurs by behavior patterns
|
|
499
|
-
* - Find habitats with specific conditions
|
|
500
|
-
* - Search for security incidents
|
|
501
|
-
* - Monitor feeding patterns
|
|
502
477
|
*
|
|
503
478
|
* @example
|
|
504
479
|
* ```typescript
|
|
@@ -551,11 +526,6 @@ var FilterBuilder = class {
|
|
|
551
526
|
}
|
|
552
527
|
/**
|
|
553
528
|
* Specifies which attributes to return in the results.
|
|
554
|
-
* Use this method when you need to:
|
|
555
|
-
* - Get specific dinosaur attributes
|
|
556
|
-
* - Retrieve habitat statistics
|
|
557
|
-
* - Monitor security metrics
|
|
558
|
-
* - Optimize response size
|
|
559
529
|
*
|
|
560
530
|
* @example
|
|
561
531
|
* ```typescript
|
|
@@ -600,11 +570,16 @@ var FilterBuilder = class {
|
|
|
600
570
|
*
|
|
601
571
|
* @example
|
|
602
572
|
* ```typescript
|
|
603
|
-
* // Create a paginator for dinosaur records
|
|
573
|
+
* // Create a paginator for dinosaur records with specific page size
|
|
604
574
|
* const paginator = builder
|
|
605
575
|
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
606
576
|
* .paginate(10);
|
|
607
577
|
*
|
|
578
|
+
* // Create a paginator with automatic DynamoDB paging (no page size limit)
|
|
579
|
+
* const autoPaginator = builder
|
|
580
|
+
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
581
|
+
* .paginate();
|
|
582
|
+
*
|
|
608
583
|
* // Process pages of dinosaur results
|
|
609
584
|
* while (paginator.hasNextPage()) {
|
|
610
585
|
* const page = await paginator.getNextPage();
|
|
@@ -613,7 +588,7 @@ var FilterBuilder = class {
|
|
|
613
588
|
* }
|
|
614
589
|
* ```
|
|
615
590
|
*
|
|
616
|
-
* @param pageSize - The number of items to return per page
|
|
591
|
+
* @param pageSize - The number of items to return per page. If not provided, DynamoDB will automatically determine page sizes.
|
|
617
592
|
* @returns A Paginator instance that manages the pagination state
|
|
618
593
|
* @see Paginator for more pagination control options
|
|
619
594
|
*/
|
|
@@ -622,11 +597,6 @@ var FilterBuilder = class {
|
|
|
622
597
|
}
|
|
623
598
|
/**
|
|
624
599
|
* Sets the starting point using a previous lastEvaluatedKey.
|
|
625
|
-
* Use this method when you need to:
|
|
626
|
-
* - Implement manual dinosaur list pagination
|
|
627
|
-
* - Resume habitat inspection reviews
|
|
628
|
-
* - Continue security incident analysis
|
|
629
|
-
* - Store operation position between sessions
|
|
630
600
|
*
|
|
631
601
|
* Note: This method is typically used for manual pagination.
|
|
632
602
|
* For automatic pagination, use the paginate() method instead.
|
|
@@ -639,15 +609,17 @@ var FilterBuilder = class {
|
|
|
639
609
|
* .limit(5)
|
|
640
610
|
* .execute();
|
|
641
611
|
*
|
|
642
|
-
*
|
|
612
|
+
* const lastKey = result1.getLastEvaluatedKey();
|
|
613
|
+
* if (lastKey) {
|
|
643
614
|
* // Continue listing dinosaurs
|
|
644
615
|
* const result2 = await builder
|
|
645
616
|
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
646
|
-
* .startFrom(
|
|
617
|
+
* .startFrom(lastKey)
|
|
647
618
|
* .limit(5)
|
|
648
619
|
* .execute();
|
|
649
620
|
*
|
|
650
|
-
*
|
|
621
|
+
* const items = await result2.toArray();
|
|
622
|
+
* console.log('Additional dinosaurs:', items);
|
|
651
623
|
* }
|
|
652
624
|
* ```
|
|
653
625
|
*
|
|
@@ -660,6 +632,72 @@ var FilterBuilder = class {
|
|
|
660
632
|
}
|
|
661
633
|
};
|
|
662
634
|
|
|
635
|
+
// src/builders/result-iterator.ts
|
|
636
|
+
var ResultIterator = class {
|
|
637
|
+
constructor(queryBuilder, directExecutor) {
|
|
638
|
+
this.queryBuilder = queryBuilder;
|
|
639
|
+
this.directExecutor = directExecutor;
|
|
640
|
+
this.overallLimit = queryBuilder.getLimit();
|
|
641
|
+
}
|
|
642
|
+
lastEvaluatedKey;
|
|
643
|
+
itemsYielded = 0;
|
|
644
|
+
overallLimit;
|
|
645
|
+
/**
|
|
646
|
+
* Async iterator with automatic pagination
|
|
647
|
+
*/
|
|
648
|
+
async *[Symbol.asyncIterator]() {
|
|
649
|
+
let hasMorePages = true;
|
|
650
|
+
while (hasMorePages) {
|
|
651
|
+
const result = await this.directExecutor();
|
|
652
|
+
for (const item of result.items) {
|
|
653
|
+
if (this.overallLimit !== void 0 && this.itemsYielded >= this.overallLimit) {
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
yield item;
|
|
657
|
+
this.itemsYielded++;
|
|
658
|
+
}
|
|
659
|
+
if (result.lastEvaluatedKey !== null && result.lastEvaluatedKey !== void 0) {
|
|
660
|
+
this.lastEvaluatedKey = result.lastEvaluatedKey;
|
|
661
|
+
this.queryBuilder.startFrom(result.lastEvaluatedKey);
|
|
662
|
+
} else if (result.lastEvaluatedKey === null) {
|
|
663
|
+
if (this.lastEvaluatedKey === void 0) {
|
|
664
|
+
this.lastEvaluatedKey = null;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
hasMorePages = !!result.lastEvaluatedKey && (this.overallLimit === void 0 || this.itemsYielded < this.overallLimit);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Convert to array (loads all pages).
|
|
672
|
+
*
|
|
673
|
+
* ```ts
|
|
674
|
+
* const result = await table.query({ pk: "foo" }).execute();
|
|
675
|
+
* const allItemsFromDynamo = await result.toArray();
|
|
676
|
+
* ```
|
|
677
|
+
*
|
|
678
|
+
* Note: This will load all pages into memory. For large datasets, consider using async iteration instead.
|
|
679
|
+
*```ts
|
|
680
|
+
* const result = await table.query({ pk: "foo" }).execute();
|
|
681
|
+
* for await (const item of result) {
|
|
682
|
+
* // Process each item
|
|
683
|
+
* }
|
|
684
|
+
* ```
|
|
685
|
+
*/
|
|
686
|
+
async toArray() {
|
|
687
|
+
const items = [];
|
|
688
|
+
for await (const item of this) {
|
|
689
|
+
items.push(item);
|
|
690
|
+
}
|
|
691
|
+
return items;
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Get the last evaluated key
|
|
695
|
+
*/
|
|
696
|
+
getLastEvaluatedKey() {
|
|
697
|
+
return this.lastEvaluatedKey === null ? void 0 : this.lastEvaluatedKey;
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
|
|
663
701
|
// src/builders/query-builder.ts
|
|
664
702
|
var QueryBuilder = class _QueryBuilder extends FilterBuilder {
|
|
665
703
|
keyCondition;
|
|
@@ -781,16 +819,16 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
|
|
|
781
819
|
return clone;
|
|
782
820
|
}
|
|
783
821
|
/**
|
|
784
|
-
* Executes the query against DynamoDB.
|
|
822
|
+
* Executes the query against DynamoDB and returns a generator that behaves like an array.
|
|
785
823
|
*
|
|
786
|
-
* The
|
|
787
|
-
*
|
|
824
|
+
* The generator automatically handles pagination and provides array-like methods
|
|
825
|
+
* for processing results efficiently without loading everything into memory at once.
|
|
788
826
|
*
|
|
789
827
|
* @example
|
|
790
828
|
* ```typescript
|
|
791
829
|
* try {
|
|
792
|
-
* // Find active carnivores
|
|
793
|
-
* const
|
|
830
|
+
* // Find active carnivores with automatic pagination
|
|
831
|
+
* const results = await new QueryBuilder(executor, eq('habitatId', 'PADDOCK-A'))
|
|
794
832
|
* .useIndex('species-status-index')
|
|
795
833
|
* .filter(op =>
|
|
796
834
|
* op.and([
|
|
@@ -800,25 +838,27 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
|
|
|
800
838
|
* ])
|
|
801
839
|
* )
|
|
802
840
|
* .sortDescending()
|
|
803
|
-
* .limit(5)
|
|
804
841
|
* .execute();
|
|
805
842
|
*
|
|
806
|
-
*
|
|
807
|
-
*
|
|
808
|
-
*
|
|
809
|
-
* console.log('Additional threats detected');
|
|
843
|
+
* // Use like an array with automatic pagination
|
|
844
|
+
* for await (const dinosaur of results) {
|
|
845
|
+
* console.log(`Processing ${dinosaur.name}`);
|
|
810
846
|
* }
|
|
847
|
+
*
|
|
848
|
+
* // Or convert to array and use array methods
|
|
849
|
+
* const allItems = await results.toArray();
|
|
850
|
+
* const dangerousOnes = allItems.filter(dino => dino.aggressionLevel > 9);
|
|
851
|
+
* const totalCount = allItems.length;
|
|
811
852
|
* } catch (error) {
|
|
812
853
|
* console.error('Security scan failed:', error);
|
|
813
854
|
* }
|
|
814
855
|
* ```
|
|
815
856
|
*
|
|
816
|
-
* @returns A promise that resolves to an
|
|
817
|
-
* - items: Array of items matching the query
|
|
818
|
-
* - lastEvaluatedKey: Token for continuing the query, if more items exist
|
|
857
|
+
* @returns A promise that resolves to a ResultGenerator that behaves like an array
|
|
819
858
|
*/
|
|
820
859
|
async execute() {
|
|
821
|
-
|
|
860
|
+
const directExecutor = () => this.executor(this.keyCondition, this.options);
|
|
861
|
+
return new ResultIterator(this, directExecutor);
|
|
822
862
|
}
|
|
823
863
|
};
|
|
824
864
|
|
|
@@ -893,10 +933,6 @@ var PutBuilder = class {
|
|
|
893
933
|
}
|
|
894
934
|
/**
|
|
895
935
|
* Adds a condition that must be satisfied for the put operation to succeed.
|
|
896
|
-
* Use this method when you need to:
|
|
897
|
-
* - Prevent overwriting existing items (optimistic locking)
|
|
898
|
-
* - Ensure items meet certain criteria before replacement
|
|
899
|
-
* - Implement complex business rules for item updates
|
|
900
936
|
*
|
|
901
937
|
* @example
|
|
902
938
|
* ```ts
|
|
@@ -1029,10 +1065,6 @@ var PutBuilder = class {
|
|
|
1029
1065
|
}
|
|
1030
1066
|
/**
|
|
1031
1067
|
* Adds this put operation to a transaction.
|
|
1032
|
-
* Use this method when you need to:
|
|
1033
|
-
* - Transfer dinosaurs between habitats
|
|
1034
|
-
* - Initialize new breeding programs
|
|
1035
|
-
* - Update multiple facility records
|
|
1036
1068
|
*
|
|
1037
1069
|
* @example
|
|
1038
1070
|
* ```ts
|
|
@@ -1065,6 +1097,45 @@ var PutBuilder = class {
|
|
|
1065
1097
|
transaction.putWithCommand(command);
|
|
1066
1098
|
return this;
|
|
1067
1099
|
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Adds this put operation to a batch with optional entity type information.
|
|
1102
|
+
*
|
|
1103
|
+
* @example Basic Usage
|
|
1104
|
+
* ```ts
|
|
1105
|
+
* const batch = table.batchBuilder();
|
|
1106
|
+
*
|
|
1107
|
+
* // Add multiple dinosaurs to batch
|
|
1108
|
+
* dinosaurRepo.create(newDino1).withBatch(batch);
|
|
1109
|
+
* dinosaurRepo.create(newDino2).withBatch(batch);
|
|
1110
|
+
* dinosaurRepo.create(newDino3).withBatch(batch);
|
|
1111
|
+
*
|
|
1112
|
+
* // Execute all operations efficiently
|
|
1113
|
+
* await batch.execute();
|
|
1114
|
+
* ```
|
|
1115
|
+
*
|
|
1116
|
+
* @example Typed Usage
|
|
1117
|
+
* ```ts
|
|
1118
|
+
* const batch = table.batchBuilder<{
|
|
1119
|
+
* User: UserEntity;
|
|
1120
|
+
* Order: OrderEntity;
|
|
1121
|
+
* }>();
|
|
1122
|
+
*
|
|
1123
|
+
* // Add operations with type information
|
|
1124
|
+
* userRepo.create(newUser).withBatch(batch, 'User');
|
|
1125
|
+
* orderRepo.create(newOrder).withBatch(batch, 'Order');
|
|
1126
|
+
*
|
|
1127
|
+
* // Execute and get typed results
|
|
1128
|
+
* const result = await batch.execute();
|
|
1129
|
+
* const users: UserEntity[] = result.reads.itemsByType.User;
|
|
1130
|
+
* ```
|
|
1131
|
+
*
|
|
1132
|
+
* @param batch - The batch builder to add this operation to
|
|
1133
|
+
* @param entityType - Optional entity type key for type tracking
|
|
1134
|
+
*/
|
|
1135
|
+
withBatch(batch, entityType) {
|
|
1136
|
+
const command = this.toDynamoCommand();
|
|
1137
|
+
batch.putWithCommand(command, entityType);
|
|
1138
|
+
}
|
|
1068
1139
|
/**
|
|
1069
1140
|
* Executes the put operation against DynamoDB.
|
|
1070
1141
|
*
|
|
@@ -1259,6 +1330,44 @@ var DeleteBuilder = class {
|
|
|
1259
1330
|
const command = this.toDynamoCommand();
|
|
1260
1331
|
transaction.deleteWithCommand(command);
|
|
1261
1332
|
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Adds this delete operation to a batch with optional entity type information.
|
|
1335
|
+
*
|
|
1336
|
+
* @example Basic Usage
|
|
1337
|
+
* ```ts
|
|
1338
|
+
* const batch = table.batchBuilder();
|
|
1339
|
+
*
|
|
1340
|
+
* // Remove multiple dinosaurs in batch
|
|
1341
|
+
* dinosaurRepo.delete({ id: 'old-dino-1' }).withBatch(batch);
|
|
1342
|
+
* dinosaurRepo.delete({ id: 'old-dino-2' }).withBatch(batch);
|
|
1343
|
+
* dinosaurRepo.delete({ id: 'old-dino-3' }).withBatch(batch);
|
|
1344
|
+
*
|
|
1345
|
+
* // Execute all deletions efficiently
|
|
1346
|
+
* await batch.execute();
|
|
1347
|
+
* ```
|
|
1348
|
+
*
|
|
1349
|
+
* @example Typed Usage
|
|
1350
|
+
* ```ts
|
|
1351
|
+
* const batch = table.batchBuilder<{
|
|
1352
|
+
* User: UserEntity;
|
|
1353
|
+
* Order: OrderEntity;
|
|
1354
|
+
* }>();
|
|
1355
|
+
*
|
|
1356
|
+
* // Add operations with type information
|
|
1357
|
+
* userRepo.delete({ id: 'user-1' }).withBatch(batch, 'User');
|
|
1358
|
+
* orderRepo.delete({ id: 'order-1' }).withBatch(batch, 'Order');
|
|
1359
|
+
*
|
|
1360
|
+
* // Execute batch operations
|
|
1361
|
+
* await batch.execute();
|
|
1362
|
+
* ```
|
|
1363
|
+
*
|
|
1364
|
+
* @param batch - The batch builder to add this operation to
|
|
1365
|
+
* @param entityType - Optional entity type key for type tracking
|
|
1366
|
+
*/
|
|
1367
|
+
withBatch(batch, entityType) {
|
|
1368
|
+
const command = this.toDynamoCommand();
|
|
1369
|
+
batch.deleteWithCommand(command, entityType);
|
|
1370
|
+
}
|
|
1262
1371
|
/**
|
|
1263
1372
|
* Executes the delete operation against DynamoDB.
|
|
1264
1373
|
*
|
|
@@ -1501,11 +1610,11 @@ var UpdateBuilder = class {
|
|
|
1501
1610
|
* Sets which item attributes to include in the response.
|
|
1502
1611
|
*
|
|
1503
1612
|
* Available options:
|
|
1504
|
-
* - ALL_NEW: All attributes after the update
|
|
1613
|
+
* - ALL_NEW: All attributes after the update (default)
|
|
1505
1614
|
* - UPDATED_NEW: Only updated attributes, new values
|
|
1506
1615
|
* - ALL_OLD: All attributes before the update
|
|
1507
1616
|
* - UPDATED_OLD: Only updated attributes, old values
|
|
1508
|
-
* - NONE: No attributes returned
|
|
1617
|
+
* - NONE: No attributes returned
|
|
1509
1618
|
*
|
|
1510
1619
|
* @example
|
|
1511
1620
|
* ```typescript
|
|
@@ -1824,10 +1933,6 @@ var TransactionBuilder = class {
|
|
|
1824
1933
|
}
|
|
1825
1934
|
/**
|
|
1826
1935
|
* Adds a put operation to the transaction.
|
|
1827
|
-
* Use this method when you need to:
|
|
1828
|
-
* - Insert new items as part of a transaction
|
|
1829
|
-
* - Replace existing items atomically
|
|
1830
|
-
* - Ensure items meet certain conditions before insertion
|
|
1831
1936
|
*
|
|
1832
1937
|
* The method automatically checks for duplicate items within the transaction
|
|
1833
1938
|
* to prevent multiple operations on the same item.
|
|
@@ -1885,10 +1990,6 @@ var TransactionBuilder = class {
|
|
|
1885
1990
|
}
|
|
1886
1991
|
/**
|
|
1887
1992
|
* Adds a pre-configured put operation to the transaction.
|
|
1888
|
-
* Use this method when you need to:
|
|
1889
|
-
* - Reuse put commands from PutBuilder
|
|
1890
|
-
* - Add complex put operations with pre-configured parameters
|
|
1891
|
-
* - Integrate with existing put command configurations
|
|
1892
1993
|
*
|
|
1893
1994
|
* This method is particularly useful when working with PutBuilder
|
|
1894
1995
|
* to maintain consistency in put operations across your application.
|
|
@@ -1920,10 +2021,6 @@ var TransactionBuilder = class {
|
|
|
1920
2021
|
}
|
|
1921
2022
|
/**
|
|
1922
2023
|
* Adds a delete operation to the transaction.
|
|
1923
|
-
* Use this method when you need to:
|
|
1924
|
-
* - Remove items as part of a transaction
|
|
1925
|
-
* - Conditionally delete items
|
|
1926
|
-
* - Ensure items exist before deletion
|
|
1927
2024
|
*
|
|
1928
2025
|
* The method automatically checks for duplicate items within the transaction
|
|
1929
2026
|
* to prevent multiple operations on the same item.
|
|
@@ -1981,10 +2078,6 @@ var TransactionBuilder = class {
|
|
|
1981
2078
|
}
|
|
1982
2079
|
/**
|
|
1983
2080
|
* Adds a pre-configured delete operation to the transaction.
|
|
1984
|
-
* Use this method when you need to:
|
|
1985
|
-
* - Reuse delete commands from DeleteBuilder
|
|
1986
|
-
* - Add complex delete operations with pre-configured parameters
|
|
1987
|
-
* - Integrate with existing delete command configurations
|
|
1988
2081
|
*
|
|
1989
2082
|
* This method is particularly useful when working with DeleteBuilder
|
|
1990
2083
|
* to maintain consistency in delete operations across your application.
|
|
@@ -2031,11 +2124,6 @@ var TransactionBuilder = class {
|
|
|
2031
2124
|
}
|
|
2032
2125
|
/**
|
|
2033
2126
|
* Adds an update operation to the transaction.
|
|
2034
|
-
* Use this method when you need to:
|
|
2035
|
-
* - Modify existing items as part of a transaction
|
|
2036
|
-
* - Update multiple attributes atomically
|
|
2037
|
-
* - Apply conditional updates
|
|
2038
|
-
* - Perform complex attribute manipulations
|
|
2039
2127
|
*
|
|
2040
2128
|
* The method supports all DynamoDB update expressions:
|
|
2041
2129
|
* - SET: Modify or add attributes
|
|
@@ -2113,10 +2201,6 @@ var TransactionBuilder = class {
|
|
|
2113
2201
|
}
|
|
2114
2202
|
/**
|
|
2115
2203
|
* Adds a pre-configured update operation to the transaction.
|
|
2116
|
-
* Use this method when you need to:
|
|
2117
|
-
* - Reuse update commands from UpdateBuilder
|
|
2118
|
-
* - Add complex update operations with pre-configured parameters
|
|
2119
|
-
* - Integrate with existing update command configurations
|
|
2120
2204
|
*
|
|
2121
2205
|
* This method is particularly useful when working with UpdateBuilder
|
|
2122
2206
|
* to maintain consistency in update operations across your application.
|
|
@@ -2166,11 +2250,6 @@ var TransactionBuilder = class {
|
|
|
2166
2250
|
}
|
|
2167
2251
|
/**
|
|
2168
2252
|
* Adds a condition check operation to the transaction.
|
|
2169
|
-
* Use this method when you need to:
|
|
2170
|
-
* - Validate item state without modifying it
|
|
2171
|
-
* - Ensure data consistency across tables
|
|
2172
|
-
* - Implement complex business rules
|
|
2173
|
-
* - Verify preconditions for other operations
|
|
2174
2253
|
*
|
|
2175
2254
|
* Condition checks are particularly useful for:
|
|
2176
2255
|
* - Implementing optimistic locking
|
|
@@ -2237,10 +2316,6 @@ var TransactionBuilder = class {
|
|
|
2237
2316
|
}
|
|
2238
2317
|
/**
|
|
2239
2318
|
* Adds a pre-configured condition check operation to the transaction.
|
|
2240
|
-
* Use this method when you need to:
|
|
2241
|
-
* - Reuse condition checks from ConditionCheckBuilder
|
|
2242
|
-
* - Add complex condition checks with pre-configured parameters
|
|
2243
|
-
* - Integrate with existing condition check configurations
|
|
2244
2319
|
*
|
|
2245
2320
|
* This method is particularly useful when working with ConditionCheckBuilder
|
|
2246
2321
|
* to maintain consistency in condition checks across your application.
|
|
@@ -2288,10 +2363,6 @@ var TransactionBuilder = class {
|
|
|
2288
2363
|
}
|
|
2289
2364
|
/**
|
|
2290
2365
|
* Sets options for the transaction execution.
|
|
2291
|
-
* Use this method when you need to:
|
|
2292
|
-
* - Enable idempotent transactions
|
|
2293
|
-
* - Track consumed capacity
|
|
2294
|
-
* - Monitor item collection metrics
|
|
2295
2366
|
*
|
|
2296
2367
|
* @example
|
|
2297
2368
|
* ```typescript
|
|
@@ -2319,11 +2390,6 @@ var TransactionBuilder = class {
|
|
|
2319
2390
|
}
|
|
2320
2391
|
/**
|
|
2321
2392
|
* Gets a human-readable representation of the transaction items.
|
|
2322
|
-
* Use this method when you need to:
|
|
2323
|
-
* - Debug complex transactions
|
|
2324
|
-
* - Verify operation parameters
|
|
2325
|
-
* - Log transaction details
|
|
2326
|
-
* - Troubleshoot condition expressions
|
|
2327
2393
|
*
|
|
2328
2394
|
* The method resolves all expression placeholders with their actual values,
|
|
2329
2395
|
* making it easier to understand the transaction's operations.
|
|
@@ -2352,10 +2418,6 @@ var TransactionBuilder = class {
|
|
|
2352
2418
|
}
|
|
2353
2419
|
/**
|
|
2354
2420
|
* Executes all operations in the transaction atomically.
|
|
2355
|
-
* Use this method when you need to:
|
|
2356
|
-
* - Perform multiple operations atomically
|
|
2357
|
-
* - Ensure all-or-nothing execution
|
|
2358
|
-
* - Maintain data consistency across operations
|
|
2359
2421
|
*
|
|
2360
2422
|
* The transaction will only succeed if all operations succeed.
|
|
2361
2423
|
* If any operation fails, the entire transaction is rolled back.
|
|
@@ -2479,10 +2541,6 @@ var ConditionCheckBuilder = class {
|
|
|
2479
2541
|
}
|
|
2480
2542
|
/**
|
|
2481
2543
|
* Adds a condition that must be satisfied for the check to succeed.
|
|
2482
|
-
* Use this method when you need to:
|
|
2483
|
-
* - Validate complex item states
|
|
2484
|
-
* - Check multiple attributes together
|
|
2485
|
-
* - Ensure safety conditions are met
|
|
2486
2544
|
*
|
|
2487
2545
|
* @example
|
|
2488
2546
|
* ```typescript
|
|
@@ -2578,10 +2636,6 @@ var ConditionCheckBuilder = class {
|
|
|
2578
2636
|
}
|
|
2579
2637
|
/**
|
|
2580
2638
|
* Adds this condition check operation to a transaction.
|
|
2581
|
-
* Use this method when you need to:
|
|
2582
|
-
* - Verify habitat safety before transfers
|
|
2583
|
-
* - Ensure proper feeding conditions
|
|
2584
|
-
* - Validate security protocols
|
|
2585
2639
|
*
|
|
2586
2640
|
* @example
|
|
2587
2641
|
* ```ts
|
|
@@ -2611,11 +2665,6 @@ var ConditionCheckBuilder = class {
|
|
|
2611
2665
|
/**
|
|
2612
2666
|
* Gets a human-readable representation of the condition check command
|
|
2613
2667
|
* with all expression placeholders replaced by their actual values.
|
|
2614
|
-
* Use this method when you need to:
|
|
2615
|
-
* - Debug complex condition expressions
|
|
2616
|
-
* - Verify condition parameters
|
|
2617
|
-
* - Log safety checks
|
|
2618
|
-
* - Troubleshoot condition failures
|
|
2619
2668
|
*
|
|
2620
2669
|
* @example
|
|
2621
2670
|
* ```ts
|
|
@@ -2638,6 +2687,283 @@ var ConditionCheckBuilder = class {
|
|
|
2638
2687
|
}
|
|
2639
2688
|
};
|
|
2640
2689
|
|
|
2690
|
+
// src/builders/batch-builder.ts
|
|
2691
|
+
var BatchError = class extends Error {
|
|
2692
|
+
operation;
|
|
2693
|
+
cause;
|
|
2694
|
+
constructor(message, operation, cause) {
|
|
2695
|
+
super(message);
|
|
2696
|
+
this.name = "BatchError";
|
|
2697
|
+
this.operation = operation;
|
|
2698
|
+
this.cause = cause;
|
|
2699
|
+
}
|
|
2700
|
+
};
|
|
2701
|
+
var BatchBuilder = class {
|
|
2702
|
+
constructor(batchWriteExecutor, batchGetExecutor, config) {
|
|
2703
|
+
this.batchWriteExecutor = batchWriteExecutor;
|
|
2704
|
+
this.batchGetExecutor = batchGetExecutor;
|
|
2705
|
+
this.config = config;
|
|
2706
|
+
}
|
|
2707
|
+
writeItems = [];
|
|
2708
|
+
getItems = [];
|
|
2709
|
+
/**
|
|
2710
|
+
* Checks if the batch is empty (contains no operations)
|
|
2711
|
+
*
|
|
2712
|
+
* @returns true if the batch contains no operations
|
|
2713
|
+
*/
|
|
2714
|
+
isEmpty() {
|
|
2715
|
+
return this.writeItems.length === 0 && this.getItems.length === 0;
|
|
2716
|
+
}
|
|
2717
|
+
/**
|
|
2718
|
+
* Gets the count of operations in the batch
|
|
2719
|
+
*
|
|
2720
|
+
* @returns Object containing the count of write and read operations
|
|
2721
|
+
*/
|
|
2722
|
+
getOperationCount() {
|
|
2723
|
+
return {
|
|
2724
|
+
writes: this.writeItems.length,
|
|
2725
|
+
reads: this.getItems.length
|
|
2726
|
+
};
|
|
2727
|
+
}
|
|
2728
|
+
/**
|
|
2729
|
+
* Validates that the batch is not empty before execution
|
|
2730
|
+
*
|
|
2731
|
+
* @throws {BatchError} If the batch is empty
|
|
2732
|
+
*/
|
|
2733
|
+
validateNotEmpty() {
|
|
2734
|
+
if (this.isEmpty()) {
|
|
2735
|
+
throw new BatchError(
|
|
2736
|
+
"Cannot execute empty batch. Add operations using entity builders with .withBatch()",
|
|
2737
|
+
"write"
|
|
2738
|
+
);
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2741
|
+
/**
|
|
2742
|
+
* Adds a put operation to the batch with entity type information.
|
|
2743
|
+
* This method is used internally by entity builders.
|
|
2744
|
+
*
|
|
2745
|
+
* @param command - The complete put command configuration
|
|
2746
|
+
* @param entityType - The entity type name for type tracking
|
|
2747
|
+
* @returns The batch builder for method chaining
|
|
2748
|
+
* @internal
|
|
2749
|
+
*/
|
|
2750
|
+
putWithCommand(command, entityType) {
|
|
2751
|
+
const batchItem = {
|
|
2752
|
+
type: "Put",
|
|
2753
|
+
params: command,
|
|
2754
|
+
entityType
|
|
2755
|
+
};
|
|
2756
|
+
this.writeItems.push(batchItem);
|
|
2757
|
+
return this;
|
|
2758
|
+
}
|
|
2759
|
+
/**
|
|
2760
|
+
* Adds a delete operation to the batch with entity type information.
|
|
2761
|
+
* This method is used internally by entity builders.
|
|
2762
|
+
*
|
|
2763
|
+
* @param command - The complete delete command configuration
|
|
2764
|
+
* @param entityType - The entity type name for type tracking
|
|
2765
|
+
* @returns The batch builder for method chaining
|
|
2766
|
+
* @internal
|
|
2767
|
+
*/
|
|
2768
|
+
deleteWithCommand(command, entityType) {
|
|
2769
|
+
const batchItem = {
|
|
2770
|
+
type: "Delete",
|
|
2771
|
+
params: command,
|
|
2772
|
+
entityType
|
|
2773
|
+
};
|
|
2774
|
+
this.writeItems.push(batchItem);
|
|
2775
|
+
return this;
|
|
2776
|
+
}
|
|
2777
|
+
/**
|
|
2778
|
+
* Adds a get operation to the batch with entity type information.
|
|
2779
|
+
* This method is used internally by entity builders.
|
|
2780
|
+
*
|
|
2781
|
+
* @param command - The complete get command configuration
|
|
2782
|
+
* @param entityType - The entity type name for type tracking
|
|
2783
|
+
* @returns The batch builder for method chaining
|
|
2784
|
+
* @internal
|
|
2785
|
+
*/
|
|
2786
|
+
getWithCommand(command, entityType) {
|
|
2787
|
+
const batchItem = {
|
|
2788
|
+
type: "Get",
|
|
2789
|
+
params: command,
|
|
2790
|
+
entityType
|
|
2791
|
+
};
|
|
2792
|
+
this.getItems.push(batchItem);
|
|
2793
|
+
return this;
|
|
2794
|
+
}
|
|
2795
|
+
/**
|
|
2796
|
+
* Executes all write operations in the batch.
|
|
2797
|
+
*
|
|
2798
|
+
* @returns A promise that resolves to any unprocessed operations
|
|
2799
|
+
* @private
|
|
2800
|
+
*/
|
|
2801
|
+
async executeWrites() {
|
|
2802
|
+
if (this.writeItems.length === 0) {
|
|
2803
|
+
return { unprocessedItems: [] };
|
|
2804
|
+
}
|
|
2805
|
+
try {
|
|
2806
|
+
const operations = this.writeItems.map((item) => {
|
|
2807
|
+
if (item.type === "Put") {
|
|
2808
|
+
return {
|
|
2809
|
+
type: "put",
|
|
2810
|
+
item: item.params.item
|
|
2811
|
+
};
|
|
2812
|
+
}
|
|
2813
|
+
if (item.type === "Delete") {
|
|
2814
|
+
let key;
|
|
2815
|
+
if (typeof item.params.key === "object" && item.params.key !== null && "pk" in item.params.key) {
|
|
2816
|
+
key = item.params.key;
|
|
2817
|
+
} else {
|
|
2818
|
+
const tableKey = item.params.key;
|
|
2819
|
+
key = {
|
|
2820
|
+
pk: tableKey[this.config.partitionKey],
|
|
2821
|
+
sk: this.config.sortKey ? tableKey[this.config.sortKey] : void 0
|
|
2822
|
+
};
|
|
2823
|
+
}
|
|
2824
|
+
return {
|
|
2825
|
+
type: "delete",
|
|
2826
|
+
key
|
|
2827
|
+
};
|
|
2828
|
+
}
|
|
2829
|
+
throw new BatchError(`Unsupported batch item type for write operation: ${item.type}`, "write");
|
|
2830
|
+
});
|
|
2831
|
+
return await this.batchWriteExecutor(operations);
|
|
2832
|
+
} catch (error) {
|
|
2833
|
+
throw new BatchError(
|
|
2834
|
+
`Failed to execute batch write operations: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
2835
|
+
"write",
|
|
2836
|
+
error instanceof Error ? error : void 0
|
|
2837
|
+
);
|
|
2838
|
+
}
|
|
2839
|
+
}
|
|
2840
|
+
/**
|
|
2841
|
+
* Executes all get operations in the batch.
|
|
2842
|
+
*
|
|
2843
|
+
* @returns A promise that resolves to the retrieved items
|
|
2844
|
+
* @private
|
|
2845
|
+
*/
|
|
2846
|
+
async executeGets() {
|
|
2847
|
+
if (this.getItems.length === 0) {
|
|
2848
|
+
return { items: [], unprocessedKeys: [] };
|
|
2849
|
+
}
|
|
2850
|
+
try {
|
|
2851
|
+
const keys = this.getItems.map((item) => {
|
|
2852
|
+
if (item.type === "Get") {
|
|
2853
|
+
if (typeof item.params.key === "object" && item.params.key !== null && "pk" in item.params.key) {
|
|
2854
|
+
return item.params.key;
|
|
2855
|
+
}
|
|
2856
|
+
const tableKey = item.params.key;
|
|
2857
|
+
return {
|
|
2858
|
+
pk: tableKey[this.config.partitionKey],
|
|
2859
|
+
sk: this.config.sortKey ? tableKey[this.config.sortKey] : void 0
|
|
2860
|
+
};
|
|
2861
|
+
}
|
|
2862
|
+
throw new BatchError(`Unsupported batch item type for get operation: ${item.type}`, "read");
|
|
2863
|
+
});
|
|
2864
|
+
return await this.batchGetExecutor(keys);
|
|
2865
|
+
} catch (error) {
|
|
2866
|
+
throw new BatchError(
|
|
2867
|
+
`Failed to execute batch get operations: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
2868
|
+
"read",
|
|
2869
|
+
error instanceof Error ? error : void 0
|
|
2870
|
+
);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
/**
|
|
2874
|
+
* Groups retrieved items by their entity type.
|
|
2875
|
+
* @private
|
|
2876
|
+
*/
|
|
2877
|
+
groupItemsByType(items) {
|
|
2878
|
+
const grouped = {};
|
|
2879
|
+
for (const item of this.getItems) {
|
|
2880
|
+
if (item.entityType) {
|
|
2881
|
+
const entityType = item.entityType;
|
|
2882
|
+
if (!grouped[entityType]) {
|
|
2883
|
+
grouped[entityType] = [];
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
for (const item of items) {
|
|
2888
|
+
const entityType = item.entityType;
|
|
2889
|
+
if (entityType && grouped[entityType]) {
|
|
2890
|
+
grouped[entityType].push(item);
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
return grouped;
|
|
2894
|
+
}
|
|
2895
|
+
/**
|
|
2896
|
+
* Executes all operations in the batch with typed results.
|
|
2897
|
+
* Performs write operations first, then get operations.
|
|
2898
|
+
*
|
|
2899
|
+
* @returns A promise that resolves to a TypedBatchResult with entity type information
|
|
2900
|
+
* @throws {BatchError} If the batch is empty or if operations fail
|
|
2901
|
+
*/
|
|
2902
|
+
async execute() {
|
|
2903
|
+
this.validateNotEmpty();
|
|
2904
|
+
const errors = [];
|
|
2905
|
+
let writeResults = { unprocessedItems: [] };
|
|
2906
|
+
let getResults = {
|
|
2907
|
+
items: [],
|
|
2908
|
+
unprocessedKeys: []
|
|
2909
|
+
};
|
|
2910
|
+
if (this.writeItems.length > 0) {
|
|
2911
|
+
try {
|
|
2912
|
+
writeResults = await this.executeWrites();
|
|
2913
|
+
} catch (error) {
|
|
2914
|
+
if (error instanceof BatchError) {
|
|
2915
|
+
errors.push(error);
|
|
2916
|
+
} else {
|
|
2917
|
+
errors.push(
|
|
2918
|
+
new BatchError(
|
|
2919
|
+
"Unexpected error during write operations",
|
|
2920
|
+
"write",
|
|
2921
|
+
error instanceof Error ? error : void 0
|
|
2922
|
+
)
|
|
2923
|
+
);
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
if (this.getItems.length > 0) {
|
|
2928
|
+
try {
|
|
2929
|
+
getResults = await this.executeGets();
|
|
2930
|
+
} catch (error) {
|
|
2931
|
+
if (error instanceof BatchError) {
|
|
2932
|
+
errors.push(error);
|
|
2933
|
+
} else {
|
|
2934
|
+
errors.push(
|
|
2935
|
+
new BatchError(
|
|
2936
|
+
"Unexpected error during read operations",
|
|
2937
|
+
"read",
|
|
2938
|
+
error instanceof Error ? error : void 0
|
|
2939
|
+
)
|
|
2940
|
+
);
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
if (errors.length > 0 && (writeResults.unprocessedItems.length === this.writeItems.length || getResults.unprocessedKeys.length === this.getItems.length)) {
|
|
2945
|
+
throw errors[0];
|
|
2946
|
+
}
|
|
2947
|
+
const totalOperations = this.writeItems.length + this.getItems.length;
|
|
2948
|
+
const success = errors.length === 0 && writeResults.unprocessedItems.length === 0 && getResults.unprocessedKeys.length === 0;
|
|
2949
|
+
return {
|
|
2950
|
+
success,
|
|
2951
|
+
writes: {
|
|
2952
|
+
processed: this.writeItems.length - writeResults.unprocessedItems.length,
|
|
2953
|
+
unprocessed: writeResults.unprocessedItems
|
|
2954
|
+
},
|
|
2955
|
+
reads: {
|
|
2956
|
+
itemsByType: this.groupItemsByType(getResults.items),
|
|
2957
|
+
items: getResults.items,
|
|
2958
|
+
found: getResults.items.length,
|
|
2959
|
+
unprocessed: getResults.unprocessedKeys
|
|
2960
|
+
},
|
|
2961
|
+
totalOperations,
|
|
2962
|
+
errors: errors.length > 0 ? errors : void 0
|
|
2963
|
+
};
|
|
2964
|
+
}
|
|
2965
|
+
};
|
|
2966
|
+
|
|
2641
2967
|
// src/builders/get-builder.ts
|
|
2642
2968
|
var GetBuilder = class {
|
|
2643
2969
|
/**
|
|
@@ -2659,10 +2985,6 @@ var GetBuilder = class {
|
|
|
2659
2985
|
selectedFields = /* @__PURE__ */ new Set();
|
|
2660
2986
|
/**
|
|
2661
2987
|
* Specifies which attributes to return in the get results.
|
|
2662
|
-
* Use this method when you need to:
|
|
2663
|
-
* - Reduce data transfer by selecting specific dinosaur attributes
|
|
2664
|
-
* - Optimize response size for dinosaur records
|
|
2665
|
-
* - Focus on relevant dinosaur characteristics only
|
|
2666
2988
|
*
|
|
2667
2989
|
* @example
|
|
2668
2990
|
* ```typescript
|
|
@@ -2716,6 +3038,60 @@ var GetBuilder = class {
|
|
|
2716
3038
|
this.params.consistentRead = consistentRead;
|
|
2717
3039
|
return this;
|
|
2718
3040
|
}
|
|
3041
|
+
/**
|
|
3042
|
+
* Adds this get operation to a batch with optional entity type information.
|
|
3043
|
+
*
|
|
3044
|
+
* @example Basic Usage
|
|
3045
|
+
* ```ts
|
|
3046
|
+
* const batch = table.batchBuilder();
|
|
3047
|
+
*
|
|
3048
|
+
* // Add multiple get operations to batch
|
|
3049
|
+
* dinosaurRepo.get({ id: 'dino-1' }).withBatch(batch);
|
|
3050
|
+
* dinosaurRepo.get({ id: 'dino-2' }).withBatch(batch);
|
|
3051
|
+
* dinosaurRepo.get({ id: 'dino-3' }).withBatch(batch);
|
|
3052
|
+
*
|
|
3053
|
+
* // Execute all gets efficiently
|
|
3054
|
+
* const results = await batch.execute();
|
|
3055
|
+
* ```
|
|
3056
|
+
*
|
|
3057
|
+
* @example Typed Usage
|
|
3058
|
+
* ```ts
|
|
3059
|
+
* const batch = table.batchBuilder<{
|
|
3060
|
+
* User: UserEntity;
|
|
3061
|
+
* Order: OrderEntity;
|
|
3062
|
+
* }>();
|
|
3063
|
+
*
|
|
3064
|
+
* // Add operations with type information
|
|
3065
|
+
* userRepo.get({ id: 'user-1' }).withBatch(batch, 'User');
|
|
3066
|
+
* orderRepo.get({ id: 'order-1' }).withBatch(batch, 'Order');
|
|
3067
|
+
*
|
|
3068
|
+
* // Execute and get typed results
|
|
3069
|
+
* const result = await batch.execute();
|
|
3070
|
+
* const users: UserEntity[] = result.reads.itemsByType.User;
|
|
3071
|
+
* const orders: OrderEntity[] = result.reads.itemsByType.Order;
|
|
3072
|
+
* ```
|
|
3073
|
+
*
|
|
3074
|
+
* @param batch - The batch builder to add this operation to
|
|
3075
|
+
* @param entityType - Optional entity type key for type tracking
|
|
3076
|
+
*/
|
|
3077
|
+
withBatch(batch, entityType) {
|
|
3078
|
+
const command = this.toDynamoCommand();
|
|
3079
|
+
batch.getWithCommand(command, entityType);
|
|
3080
|
+
}
|
|
3081
|
+
/**
|
|
3082
|
+
* Converts the builder configuration to a DynamoDB command
|
|
3083
|
+
*/
|
|
3084
|
+
toDynamoCommand() {
|
|
3085
|
+
const expressionParams = {
|
|
3086
|
+
expressionAttributeNames: {}};
|
|
3087
|
+
const projectionExpression = Array.from(this.selectedFields).map((p) => generateAttributeName(expressionParams, p)).join(", ");
|
|
3088
|
+
const { expressionAttributeNames } = expressionParams;
|
|
3089
|
+
return {
|
|
3090
|
+
...this.params,
|
|
3091
|
+
projectionExpression: projectionExpression.length > 0 ? projectionExpression : void 0,
|
|
3092
|
+
expressionAttributeNames: Object.keys(expressionAttributeNames).length > 0 ? expressionAttributeNames : void 0
|
|
3093
|
+
};
|
|
3094
|
+
}
|
|
2719
3095
|
/**
|
|
2720
3096
|
* Executes the get operation against DynamoDB.
|
|
2721
3097
|
*
|
|
@@ -2741,15 +3117,8 @@ var GetBuilder = class {
|
|
|
2741
3117
|
* - item: The retrieved dinosaur or undefined if not found
|
|
2742
3118
|
*/
|
|
2743
3119
|
async execute() {
|
|
2744
|
-
const
|
|
2745
|
-
|
|
2746
|
-
const projectionExpression = Array.from(this.selectedFields).map((p) => generateAttributeName(expressionParams, p)).join(", ");
|
|
2747
|
-
const { expressionAttributeNames } = expressionParams;
|
|
2748
|
-
return this.executor({
|
|
2749
|
-
...this.params,
|
|
2750
|
-
projectionExpression: projectionExpression.length > 0 ? projectionExpression : void 0,
|
|
2751
|
-
expressionAttributeNames: Object.keys(expressionAttributeNames).length > 0 ? expressionAttributeNames : void 0
|
|
2752
|
-
});
|
|
3120
|
+
const command = this.toDynamoCommand();
|
|
3121
|
+
return this.executor(command);
|
|
2753
3122
|
}
|
|
2754
3123
|
};
|
|
2755
3124
|
|
|
@@ -2762,10 +3131,6 @@ var ScanBuilder = class _ScanBuilder extends FilterBuilder {
|
|
|
2762
3131
|
}
|
|
2763
3132
|
/**
|
|
2764
3133
|
* Creates a deep clone of this ScanBuilder instance.
|
|
2765
|
-
* Use this method when you need to:
|
|
2766
|
-
* - Create scan templates
|
|
2767
|
-
* - Run multiple variations of a scan
|
|
2768
|
-
* - Implement pagination (used internally by paginate())
|
|
2769
3134
|
*
|
|
2770
3135
|
* @returns A new ScanBuilder instance with the same configuration
|
|
2771
3136
|
*/
|
|
@@ -2776,46 +3141,43 @@ var ScanBuilder = class _ScanBuilder extends FilterBuilder {
|
|
|
2776
3141
|
return clone;
|
|
2777
3142
|
}
|
|
2778
3143
|
/**
|
|
2779
|
-
* Executes the scan against DynamoDB.
|
|
2780
|
-
* Use this method when you need to:
|
|
2781
|
-
* - Search across the entire table
|
|
2782
|
-
* - Find items matching specific criteria
|
|
2783
|
-
* - Perform full table analysis
|
|
2784
|
-
* - Generate reports across all data
|
|
3144
|
+
* Executes the scan against DynamoDB and returns a generator that behaves like an array.
|
|
2785
3145
|
*
|
|
2786
|
-
* The
|
|
2787
|
-
*
|
|
3146
|
+
* The generator automatically handles pagination and provides array-like methods
|
|
3147
|
+
* for processing results efficiently without loading everything into memory at once.
|
|
2788
3148
|
*
|
|
2789
3149
|
* @example
|
|
2790
3150
|
* ```typescript
|
|
2791
3151
|
* try {
|
|
2792
|
-
* // Find all dinosaurs with high aggression levels
|
|
2793
|
-
* const
|
|
3152
|
+
* // Find all dinosaurs with high aggression levels with automatic pagination
|
|
3153
|
+
* const results = await new ScanBuilder(executor)
|
|
2794
3154
|
* .filter(op =>
|
|
2795
3155
|
* op.and([
|
|
2796
3156
|
* op.eq('status', 'ACTIVE'),
|
|
2797
3157
|
* op.gt('aggressionLevel', 7)
|
|
2798
3158
|
* ])
|
|
2799
3159
|
* )
|
|
2800
|
-
* .limit(20)
|
|
2801
3160
|
* .execute();
|
|
2802
3161
|
*
|
|
2803
|
-
*
|
|
2804
|
-
*
|
|
2805
|
-
*
|
|
2806
|
-
* console.log('More results available');
|
|
3162
|
+
* // Use like an array with automatic pagination
|
|
3163
|
+
* for await (const dinosaur of results) {
|
|
3164
|
+
* console.log(`Processing dangerous dinosaur: ${dinosaur.name}`);
|
|
2807
3165
|
* }
|
|
3166
|
+
*
|
|
3167
|
+
* // Or convert to array and use array methods
|
|
3168
|
+
* const allItems = await results.toArray();
|
|
3169
|
+
* const criticalThreats = allItems.filter(dino => dino.aggressionLevel > 9);
|
|
3170
|
+
* const totalCount = allItems.length;
|
|
2808
3171
|
* } catch (error) {
|
|
2809
3172
|
* console.error('Security scan failed:', error);
|
|
2810
3173
|
* }
|
|
2811
3174
|
* ```
|
|
2812
3175
|
*
|
|
2813
|
-
* @returns A promise that resolves to an
|
|
2814
|
-
* - items: Array of items matching the scan criteria
|
|
2815
|
-
* - lastEvaluatedKey: Token for continuing the scan, if more items exist
|
|
3176
|
+
* @returns A promise that resolves to a ResultGenerator that behaves like an array
|
|
2816
3177
|
*/
|
|
2817
3178
|
async execute() {
|
|
2818
|
-
|
|
3179
|
+
const directExecutor = () => this.executor(this.options);
|
|
3180
|
+
return new ResultIterator(this, directExecutor);
|
|
2819
3181
|
}
|
|
2820
3182
|
};
|
|
2821
3183
|
|
|
@@ -3176,6 +3538,53 @@ var Table = class {
|
|
|
3176
3538
|
sortKey: this.sortKey
|
|
3177
3539
|
});
|
|
3178
3540
|
}
|
|
3541
|
+
/**
|
|
3542
|
+
* Creates a batch builder for performing multiple operations efficiently with optional type inference
|
|
3543
|
+
*
|
|
3544
|
+
* @example Basic Usage
|
|
3545
|
+
* ```typescript
|
|
3546
|
+
* const batch = table.batchBuilder();
|
|
3547
|
+
*
|
|
3548
|
+
* // Add operations
|
|
3549
|
+
* userRepo.create(newUser).withBatch(batch);
|
|
3550
|
+
* orderRepo.get({ id: 'order-1' }).withBatch(batch);
|
|
3551
|
+
*
|
|
3552
|
+
* // Execute operations
|
|
3553
|
+
* const result = await batch.execute();
|
|
3554
|
+
* ```
|
|
3555
|
+
*
|
|
3556
|
+
* @example Typed Usage
|
|
3557
|
+
* ```typescript
|
|
3558
|
+
* // Define entity types for the batch
|
|
3559
|
+
* const batch = table.batchBuilder<{
|
|
3560
|
+
* User: UserEntity;
|
|
3561
|
+
* Order: OrderEntity;
|
|
3562
|
+
* Product: ProductEntity;
|
|
3563
|
+
* }>();
|
|
3564
|
+
*
|
|
3565
|
+
* // Add operations with type information
|
|
3566
|
+
* userRepo.create(newUser).withBatch(batch, 'User');
|
|
3567
|
+
* orderRepo.get({ id: 'order-1' }).withBatch(batch, 'Order');
|
|
3568
|
+
* productRepo.delete({ id: 'old-product' }).withBatch(batch, 'Product');
|
|
3569
|
+
*
|
|
3570
|
+
* // Execute and get typed results
|
|
3571
|
+
* const result = await batch.execute();
|
|
3572
|
+
* const users: UserEntity[] = result.reads.itemsByType.User;
|
|
3573
|
+
* const orders: OrderEntity[] = result.reads.itemsByType.Order;
|
|
3574
|
+
* ```
|
|
3575
|
+
*/
|
|
3576
|
+
batchBuilder() {
|
|
3577
|
+
const batchWriteExecutor = async (operations) => {
|
|
3578
|
+
return this.batchWrite(operations);
|
|
3579
|
+
};
|
|
3580
|
+
const batchGetExecutor = async (keys) => {
|
|
3581
|
+
return this.batchGet(keys);
|
|
3582
|
+
};
|
|
3583
|
+
return new BatchBuilder(batchWriteExecutor, batchGetExecutor, {
|
|
3584
|
+
partitionKey: this.partitionKey,
|
|
3585
|
+
sortKey: this.sortKey
|
|
3586
|
+
});
|
|
3587
|
+
}
|
|
3179
3588
|
/**
|
|
3180
3589
|
* Executes a transaction using a callback function
|
|
3181
3590
|
*
|