dyno-table 1.0.0-alpha.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +752 -172
  2. package/dist/builder-types-C_PDZhnP.d.ts +118 -0
  3. package/dist/builder-types-DtwbqMeF.d.cts +118 -0
  4. package/dist/builders/condition-check-builder.cjs +394 -0
  5. package/dist/builders/condition-check-builder.cjs.map +1 -0
  6. package/dist/builders/condition-check-builder.d.cts +157 -0
  7. package/dist/builders/condition-check-builder.d.ts +157 -0
  8. package/dist/builders/condition-check-builder.js +392 -0
  9. package/dist/builders/condition-check-builder.js.map +1 -0
  10. package/dist/builders/delete-builder.cjs +405 -0
  11. package/dist/builders/delete-builder.cjs.map +1 -0
  12. package/dist/builders/delete-builder.d.cts +166 -0
  13. package/dist/builders/delete-builder.d.ts +166 -0
  14. package/dist/builders/delete-builder.js +403 -0
  15. package/dist/builders/delete-builder.js.map +1 -0
  16. package/dist/builders/paginator.cjs +199 -0
  17. package/dist/builders/paginator.cjs.map +1 -0
  18. package/dist/builders/paginator.d.cts +179 -0
  19. package/dist/builders/paginator.d.ts +179 -0
  20. package/dist/builders/paginator.js +197 -0
  21. package/dist/builders/paginator.js.map +1 -0
  22. package/dist/builders/put-builder.cjs +476 -0
  23. package/dist/builders/put-builder.cjs.map +1 -0
  24. package/dist/builders/put-builder.d.cts +274 -0
  25. package/dist/builders/put-builder.d.ts +274 -0
  26. package/dist/builders/put-builder.js +474 -0
  27. package/dist/builders/put-builder.js.map +1 -0
  28. package/dist/builders/query-builder.cjs +674 -0
  29. package/dist/builders/query-builder.cjs.map +1 -0
  30. package/dist/builders/query-builder.d.cts +6 -0
  31. package/dist/builders/query-builder.d.ts +6 -0
  32. package/dist/builders/query-builder.js +672 -0
  33. package/dist/builders/query-builder.js.map +1 -0
  34. package/dist/builders/transaction-builder.cjs +918 -0
  35. package/dist/builders/transaction-builder.cjs.map +1 -0
  36. package/dist/builders/transaction-builder.d.cts +511 -0
  37. package/dist/builders/transaction-builder.d.ts +511 -0
  38. package/dist/builders/transaction-builder.js +916 -0
  39. package/dist/builders/transaction-builder.js.map +1 -0
  40. package/dist/builders/update-builder.cjs +627 -0
  41. package/dist/builders/update-builder.cjs.map +1 -0
  42. package/dist/builders/update-builder.d.cts +365 -0
  43. package/dist/builders/update-builder.d.ts +365 -0
  44. package/dist/builders/update-builder.js +625 -0
  45. package/dist/builders/update-builder.js.map +1 -0
  46. package/dist/conditions--ld9a78i.d.ts +331 -0
  47. package/dist/conditions-ChhQWd6z.d.cts +331 -0
  48. package/dist/conditions.cjs +59 -0
  49. package/dist/conditions.cjs.map +1 -0
  50. package/dist/conditions.d.cts +3 -0
  51. package/dist/conditions.d.ts +3 -0
  52. package/dist/conditions.js +43 -0
  53. package/dist/conditions.js.map +1 -0
  54. package/dist/entity.cjs +211 -0
  55. package/dist/entity.cjs.map +1 -0
  56. package/dist/entity.d.cts +149 -0
  57. package/dist/entity.d.ts +149 -0
  58. package/dist/entity.js +207 -0
  59. package/dist/entity.js.map +1 -0
  60. package/dist/query-builder-Csror9Iu.d.ts +507 -0
  61. package/dist/query-builder-D2FM9rsu.d.cts +507 -0
  62. package/dist/standard-schema.cjs +4 -0
  63. package/dist/standard-schema.cjs.map +1 -0
  64. package/dist/standard-schema.d.cts +57 -0
  65. package/dist/standard-schema.d.ts +57 -0
  66. package/dist/standard-schema.js +3 -0
  67. package/dist/standard-schema.js.map +1 -0
  68. package/dist/table-BEhBPy2G.d.cts +364 -0
  69. package/dist/table-BW3cmUqr.d.ts +364 -0
  70. package/dist/{index.cjs → table.cjs} +108 -175
  71. package/dist/table.cjs.map +1 -0
  72. package/dist/table.d.cts +12 -0
  73. package/dist/table.d.ts +12 -0
  74. package/dist/{index.js → table.js} +107 -127
  75. package/dist/table.js.map +1 -0
  76. package/dist/types.cjs +4 -0
  77. package/dist/types.cjs.map +1 -0
  78. package/dist/types.d.cts +22 -0
  79. package/dist/types.d.ts +22 -0
  80. package/dist/types.js +3 -0
  81. package/dist/types.js.map +1 -0
  82. package/dist/utils/partition-key-template.cjs +19 -0
  83. package/dist/utils/partition-key-template.cjs.map +1 -0
  84. package/dist/utils/partition-key-template.d.cts +32 -0
  85. package/dist/utils/partition-key-template.d.ts +32 -0
  86. package/dist/utils/partition-key-template.js +17 -0
  87. package/dist/utils/partition-key-template.js.map +1 -0
  88. package/dist/utils/sort-key-template.cjs +19 -0
  89. package/dist/utils/sort-key-template.cjs.map +1 -0
  90. package/dist/utils/sort-key-template.d.cts +35 -0
  91. package/dist/utils/sort-key-template.d.ts +35 -0
  92. package/dist/utils/sort-key-template.js +17 -0
  93. package/dist/utils/sort-key-template.js.map +1 -0
  94. package/package.json +77 -7
  95. package/dist/index.d.cts +0 -2971
  96. package/dist/index.d.ts +0 -2971
@@ -0,0 +1,674 @@
1
+ 'use strict';
2
+
3
+ // src/conditions.ts
4
+ var createComparisonCondition = (type) => (attr, value) => ({
5
+ type,
6
+ attr,
7
+ value
8
+ });
9
+ var eq = createComparisonCondition("eq");
10
+ var ne = createComparisonCondition("ne");
11
+ var lt = createComparisonCondition("lt");
12
+ var lte = createComparisonCondition("lte");
13
+ var gt = createComparisonCondition("gt");
14
+ var gte = createComparisonCondition("gte");
15
+ var between = (attr, lower, upper) => ({
16
+ type: "between",
17
+ attr,
18
+ value: [lower, upper]
19
+ });
20
+ var beginsWith = createComparisonCondition("beginsWith");
21
+ var contains = createComparisonCondition("contains");
22
+ var attributeExists = (attr) => ({
23
+ type: "attributeExists",
24
+ attr
25
+ });
26
+ var attributeNotExists = (attr) => ({
27
+ type: "attributeNotExists",
28
+ attr
29
+ });
30
+ var and = (...conditions) => ({
31
+ type: "and",
32
+ conditions
33
+ });
34
+ var or = (...conditions) => ({
35
+ type: "or",
36
+ conditions
37
+ });
38
+ var not = (condition) => ({
39
+ type: "not",
40
+ condition
41
+ });
42
+
43
+ // src/builders/paginator.ts
44
+ var Paginator = class {
45
+ queryBuilder;
46
+ pageSize;
47
+ currentPage = 0;
48
+ lastEvaluatedKey;
49
+ hasMorePages = true;
50
+ totalItemsRetrieved = 0;
51
+ overallLimit;
52
+ constructor(queryBuilder, pageSize) {
53
+ this.queryBuilder = queryBuilder;
54
+ this.pageSize = pageSize;
55
+ this.overallLimit = queryBuilder.getLimit();
56
+ }
57
+ /**
58
+ * Gets the current page number (1-indexed).
59
+ * Use this method when you need to:
60
+ * - Track progress through dinosaur lists
61
+ * - Display habitat inspection status
62
+ * - Monitor security sweep progress
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * const paginator = new QueryBuilder(executor, eq('species', 'Tyrannosaurus'))
67
+ * .paginate(5);
68
+ *
69
+ * await paginator.getNextPage();
70
+ * console.log(`Reviewing T-Rex group ${paginator.getCurrentPage()}`);
71
+ * ```
72
+ *
73
+ * @returns The current page number, starting from 1
74
+ */
75
+ getCurrentPage() {
76
+ return this.currentPage;
77
+ }
78
+ /**
79
+ * Checks if there are more pages of dinosaurs or habitats to process.
80
+ * Use this method when you need to:
81
+ * - Check for more dinosaurs to review
82
+ * - Continue habitat inspections
83
+ * - Process security incidents
84
+ * - Complete feeding schedules
85
+ *
86
+ * This method takes into account both:
87
+ * - DynamoDB's lastEvaluatedKey mechanism
88
+ * - Any overall limit set on the query
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * // Process all security incidents
93
+ * const paginator = new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
94
+ * .sortDescending()
95
+ * .paginate(10);
96
+ *
97
+ * while (paginator.hasNextPage()) {
98
+ * const page = await paginator.getNextPage();
99
+ * for (const incident of page.items) {
100
+ * await processSecurityBreach(incident);
101
+ * }
102
+ * console.log(`Processed incidents page ${page.page}`);
103
+ * }
104
+ * ```
105
+ *
106
+ * @returns true if there are more pages available, false otherwise
107
+ */
108
+ hasNextPage() {
109
+ if (this.overallLimit !== void 0 && this.totalItemsRetrieved >= this.overallLimit) {
110
+ return false;
111
+ }
112
+ return this.hasMorePages;
113
+ }
114
+ /**
115
+ * Retrieves the next page of dinosaurs or habitats from DynamoDB.
116
+ * Use this method when you need to:
117
+ * - Process dinosaur groups systematically
118
+ * - Review habitat inspections in batches
119
+ * - Monitor security incidents in sequence
120
+ * - Schedule feeding rotations
121
+ *
122
+ * This method handles:
123
+ * - Automatic continuation between groups
124
+ * - Respect for park capacity limits
125
+ * - Group size adjustments for safety
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * const paginator = new QueryBuilder(executor, eq('species', 'Velociraptor'))
130
+ * .filter(op => op.eq('status', 'ACTIVE'))
131
+ * .paginate(5);
132
+ *
133
+ * // Check first raptor group
134
+ * const page1 = await paginator.getNextPage();
135
+ * console.log(`Found ${page1.items.length} active raptors`);
136
+ *
137
+ * // Continue inspection if more groups exist
138
+ * if (page1.hasNextPage) {
139
+ * const page2 = await paginator.getNextPage();
140
+ * console.log(`Inspecting raptor group ${page2.page}`);
141
+ *
142
+ * for (const raptor of page2.items) {
143
+ * await performHealthCheck(raptor);
144
+ * }
145
+ * }
146
+ * ```
147
+ *
148
+ * @returns A promise that resolves to a PaginationResult containing:
149
+ * - items: The dinosaurs/habitats for this page
150
+ * - hasNextPage: Whether more groups exist
151
+ * - page: The current group number
152
+ * - lastEvaluatedKey: DynamoDB's continuation token
153
+ */
154
+ async getNextPage() {
155
+ if (!this.hasNextPage()) {
156
+ return {
157
+ items: [],
158
+ hasNextPage: false,
159
+ page: this.currentPage
160
+ };
161
+ }
162
+ let effectivePageSize = this.pageSize;
163
+ if (this.overallLimit !== void 0) {
164
+ const remainingItems = this.overallLimit - this.totalItemsRetrieved;
165
+ if (remainingItems <= 0) {
166
+ return {
167
+ items: [],
168
+ hasNextPage: false,
169
+ page: this.currentPage
170
+ };
171
+ }
172
+ effectivePageSize = Math.min(effectivePageSize, remainingItems);
173
+ }
174
+ const query = this.queryBuilder.clone().limit(effectivePageSize);
175
+ if (this.lastEvaluatedKey) {
176
+ query.startFrom(this.lastEvaluatedKey);
177
+ }
178
+ const result = await query.execute();
179
+ this.currentPage += 1;
180
+ this.lastEvaluatedKey = result.lastEvaluatedKey;
181
+ this.totalItemsRetrieved += result.items.length;
182
+ this.hasMorePages = !!result.lastEvaluatedKey && (this.overallLimit === void 0 || this.totalItemsRetrieved < this.overallLimit);
183
+ return {
184
+ items: result.items,
185
+ lastEvaluatedKey: result.lastEvaluatedKey,
186
+ hasNextPage: this.hasNextPage(),
187
+ page: this.currentPage
188
+ };
189
+ }
190
+ /**
191
+ * Gets all remaining dinosaurs or habitats and combines them into a single array.
192
+ * Use this method when you need to:
193
+ * - Generate complete park inventory
194
+ * - Perform full security audit
195
+ * - Create comprehensive feeding schedule
196
+ * - Run park-wide health checks
197
+ *
198
+ * Note: Use with caution! This method:
199
+ * - Could overwhelm systems with large dinosaur populations
200
+ * - Makes multiple database requests
201
+ * - May cause system strain during peak hours
202
+ *
203
+ * @example
204
+ * ```ts
205
+ * // Get complete carnivore inventory
206
+ * const paginator = new QueryBuilder(executor, eq('diet', 'CARNIVORE'))
207
+ * .filter(op => op.eq('status', 'ACTIVE'))
208
+ * .paginate(10);
209
+ *
210
+ * try {
211
+ * const allCarnivores = await paginator.getAllPages();
212
+ * console.log(`Park contains ${allCarnivores.length} active carnivores`);
213
+ *
214
+ * // Calculate total threat level
215
+ * const totalThreat = allCarnivores.reduce(
216
+ * (sum, dino) => sum + dino.stats.threatLevel,
217
+ * 0
218
+ * );
219
+ * console.log(`Total threat level: ${totalThreat}`);
220
+ * } catch (error) {
221
+ * console.error('Failed to complete carnivore census:', error);
222
+ * }
223
+ * ```
224
+ *
225
+ * @returns A promise that resolves to an array containing all remaining items
226
+ */
227
+ async getAllPages() {
228
+ const allItems = [];
229
+ while (this.hasNextPage()) {
230
+ const result = await this.getNextPage();
231
+ allItems.push(...result.items);
232
+ }
233
+ return allItems;
234
+ }
235
+ };
236
+
237
+ // src/builders/filter-builder.ts
238
+ var FilterBuilder = class {
239
+ options = {};
240
+ selectedFields = /* @__PURE__ */ new Set();
241
+ /**
242
+ * Sets the maximum number of items to return.
243
+ * Use this method when you need to:
244
+ * - Limit the number of dinosaurs returned
245
+ * - Control the size of habitat reports
246
+ * - Implement manual pagination of security logs
247
+ *
248
+ * Note: This limit applies to the items that match the key condition
249
+ * before any filter expressions are applied.
250
+ *
251
+ * @example
252
+ * ```typescript
253
+ * // Get first 10 dinosaurs
254
+ * const result = await builder
255
+ * .limit(10)
256
+ * .execute();
257
+ * ```
258
+ *
259
+ * @param limit - Maximum number of items to return
260
+ * @returns The builder instance for method chaining
261
+ */
262
+ limit(limit) {
263
+ this.options.limit = limit;
264
+ return this;
265
+ }
266
+ /**
267
+ * Gets the current limit set on the operation.
268
+ * This is used internally by the paginator to manage result sets.
269
+ *
270
+ * @returns The current limit or undefined if no limit is set
271
+ */
272
+ getLimit() {
273
+ return this.options.limit;
274
+ }
275
+ /**
276
+ * Specifies a Global Secondary Index (GSI) to use for the operation.
277
+ * Use this method when you need to:
278
+ * - Find dinosaurs by species or status
279
+ * - Search habitats by security level
280
+ * - Find incidents by date
281
+ * - List feeding schedules by time
282
+ *
283
+ * @example
284
+ * ```typescript
285
+ * // Find all dinosaurs of a specific species
286
+ * builder
287
+ * .useIndex('species-status-index')
288
+ * .filter(op => op.eq('status', 'ACTIVE'));
289
+ *
290
+ * // Search high-security habitats
291
+ * builder
292
+ * .useIndex('security-level-index')
293
+ * .filter(op =>
294
+ * op.and([
295
+ * op.gt('securityLevel', 8),
296
+ * op.eq('status', 'OPERATIONAL')
297
+ * ])
298
+ * );
299
+ * ```
300
+ *
301
+ * @param indexName - The name of the GSI to use (type-safe based on table configuration)
302
+ * @returns The builder instance for method chaining
303
+ */
304
+ useIndex(indexName) {
305
+ this.options.indexName = indexName;
306
+ return this;
307
+ }
308
+ /**
309
+ * Sets whether to use strongly consistent reads for the operation.
310
+ * Use this method when you need to:
311
+ * - Get real-time dinosaur status updates
312
+ * - Monitor critical security systems
313
+ * - Track immediate habitat changes
314
+ * - Verify containment protocols
315
+ *
316
+ * Note:
317
+ * - Consistent reads are not available on GSIs
318
+ * - Consistent reads consume twice the throughput
319
+ * - Default is eventually consistent reads
320
+ *
321
+ * @example
322
+ * ```typescript
323
+ * // Check immediate dinosaur status
324
+ * const result = await builder
325
+ * .filter(op => op.eq('status', 'ACTIVE'))
326
+ * .consistentRead()
327
+ * .execute();
328
+ *
329
+ * // Monitor security breaches
330
+ * const result = await builder
331
+ * .useIndex('primary-index')
332
+ * .consistentRead(isEmergencyMode)
333
+ * .execute();
334
+ * ```
335
+ *
336
+ * @param consistentRead - Whether to use consistent reads (defaults to true)
337
+ * @returns The builder instance for method chaining
338
+ */
339
+ consistentRead(consistentRead = true) {
340
+ this.options.consistentRead = consistentRead;
341
+ return this;
342
+ }
343
+ /**
344
+ * Adds a filter expression to refine the operation results.
345
+ * Use this method when you need to:
346
+ * - Filter dinosaurs by behavior patterns
347
+ * - Find habitats with specific conditions
348
+ * - Search for security incidents
349
+ * - Monitor feeding patterns
350
+ *
351
+ * @example
352
+ * ```typescript
353
+ * // Find aggressive carnivores
354
+ * builder.filter(op =>
355
+ * op.and([
356
+ * op.eq('diet', 'CARNIVORE'),
357
+ * op.gt('aggressionLevel', 7),
358
+ * op.eq('status', 'ACTIVE')
359
+ * ])
360
+ * );
361
+ *
362
+ * // Search suitable breeding habitats
363
+ * builder.filter(op =>
364
+ * op.and([
365
+ * op.between('temperature', 25, 30),
366
+ * op.lt('currentOccupants', 3),
367
+ * op.eq('quarantineStatus', 'CLEAR')
368
+ * ])
369
+ * );
370
+ * ```
371
+ *
372
+ * @param condition - Either a Condition object or a callback function that builds the condition
373
+ * @returns The builder instance for method chaining
374
+ */
375
+ filter(condition) {
376
+ if (typeof condition === "function") {
377
+ const conditionOperator = {
378
+ eq,
379
+ ne,
380
+ lt,
381
+ lte,
382
+ gt,
383
+ gte,
384
+ between,
385
+ beginsWith,
386
+ contains,
387
+ attributeExists,
388
+ attributeNotExists,
389
+ and,
390
+ or,
391
+ not
392
+ };
393
+ this.options.filter = condition(conditionOperator);
394
+ } else {
395
+ this.options.filter = condition;
396
+ }
397
+ return this;
398
+ }
399
+ /**
400
+ * Specifies which attributes to return in the results.
401
+ * Use this method when you need to:
402
+ * - Get specific dinosaur attributes
403
+ * - Retrieve habitat statistics
404
+ * - Monitor security metrics
405
+ * - Optimize response size
406
+ *
407
+ * @example
408
+ * ```typescript
409
+ * // Get basic dinosaur info
410
+ * builder.select([
411
+ * 'species',
412
+ * 'status',
413
+ * 'stats.health',
414
+ * 'stats.aggressionLevel'
415
+ * ]);
416
+ *
417
+ * // Monitor habitat conditions
418
+ * builder
419
+ * .select('securityStatus')
420
+ * .select([
421
+ * 'currentOccupants',
422
+ * 'temperature',
423
+ * 'lastInspectionDate'
424
+ * ]);
425
+ * ```
426
+ *
427
+ * @param fields - A single field name or an array of field names to return
428
+ * @returns The builder instance for method chaining
429
+ */
430
+ select(fields) {
431
+ if (typeof fields === "string") {
432
+ this.selectedFields.add(fields);
433
+ } else if (Array.isArray(fields)) {
434
+ for (const field of fields) {
435
+ this.selectedFields.add(field);
436
+ }
437
+ }
438
+ this.options.projection = Array.from(this.selectedFields);
439
+ return this;
440
+ }
441
+ /**
442
+ * Creates a paginator that handles DynamoDB pagination automatically.
443
+ * The paginator handles:
444
+ * - Tracking the last evaluated key
445
+ * - Managing page boundaries
446
+ * - Respecting overall query limits
447
+ *
448
+ * @example
449
+ * ```typescript
450
+ * // Create a paginator for dinosaur records
451
+ * const paginator = builder
452
+ * .filter(op => op.eq('status', 'ACTIVE'))
453
+ * .paginate(10);
454
+ *
455
+ * // Process pages of dinosaur results
456
+ * while (paginator.hasNextPage()) {
457
+ * const page = await paginator.getNextPage();
458
+ * console.log(`Processing page ${page.page}, count: ${page.items.length}`);
459
+ * // Process dinosaur data
460
+ * }
461
+ * ```
462
+ *
463
+ * @param pageSize - The number of items to return per page
464
+ * @returns A Paginator instance that manages the pagination state
465
+ * @see Paginator for more pagination control options
466
+ */
467
+ paginate(pageSize) {
468
+ return new Paginator(this, pageSize);
469
+ }
470
+ /**
471
+ * Sets the starting point using a previous lastEvaluatedKey.
472
+ * Use this method when you need to:
473
+ * - Implement manual dinosaur list pagination
474
+ * - Resume habitat inspection reviews
475
+ * - Continue security incident analysis
476
+ * - Store operation position between sessions
477
+ *
478
+ * Note: This method is typically used for manual pagination.
479
+ * For automatic pagination, use the paginate() method instead.
480
+ *
481
+ * @example
482
+ * ```typescript
483
+ * // First batch of dinosaurs
484
+ * const result1 = await builder
485
+ * .filter(op => op.eq('status', 'ACTIVE'))
486
+ * .limit(5)
487
+ * .execute();
488
+ *
489
+ * if (result1.lastEvaluatedKey) {
490
+ * // Continue listing dinosaurs
491
+ * const result2 = await builder
492
+ * .filter(op => op.eq('status', 'ACTIVE'))
493
+ * .startFrom(result1.lastEvaluatedKey)
494
+ * .limit(5)
495
+ * .execute();
496
+ *
497
+ * console.log('Additional dinosaurs:', result2.items);
498
+ * }
499
+ * ```
500
+ *
501
+ * @param lastEvaluatedKey - The exclusive start key from a previous result
502
+ * @returns The builder instance for method chaining
503
+ */
504
+ startFrom(lastEvaluatedKey) {
505
+ this.options.lastEvaluatedKey = lastEvaluatedKey;
506
+ return this;
507
+ }
508
+ };
509
+
510
+ // src/builders/query-builder.ts
511
+ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
512
+ keyCondition;
513
+ options = {};
514
+ executor;
515
+ constructor(executor, keyCondition) {
516
+ super();
517
+ this.executor = executor;
518
+ this.keyCondition = keyCondition;
519
+ }
520
+ /**
521
+ * Sets the maximum number of items to return from the query.
522
+ *
523
+ * Note: This is the default behavior if no sort order is specified.
524
+ *
525
+ * @example
526
+ * ```typescript
527
+ * // Get orders in chronological order
528
+ * const result = await new QueryBuilder(executor, eq('userId', '123'))
529
+ * .sortAscending()
530
+ * .execute();
531
+ *
532
+ * // Get events from oldest to newest
533
+ * const result = await new QueryBuilder(executor, eq('entityId', 'order-123'))
534
+ * .useIndex('entity-timestamp-index')
535
+ * .sortAscending()
536
+ * .execute();
537
+ * ```
538
+ *
539
+ * @returns The builder instance for method chaining
540
+ */
541
+ /**
542
+ * Sets the query to return items in ascending order by sort key.
543
+ *
544
+ * @example
545
+ * ```typescript
546
+ * // List dinosaurs by age
547
+ * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
548
+ * .useIndex('age-index')
549
+ * .sortAscending()
550
+ * .execute();
551
+ *
552
+ * // View incidents chronologically
553
+ * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
554
+ * .useIndex('date-index')
555
+ * .sortAscending()
556
+ * .execute();
557
+ * ```
558
+ *
559
+ * @returns The builder instance for method chaining
560
+ */
561
+ sortAscending() {
562
+ this.options.scanIndexForward = true;
563
+ return this;
564
+ }
565
+ /**
566
+ * Sets the query to return items in descending order by sort key.
567
+ *
568
+ * @example
569
+ * ```typescript
570
+ * // Get most recent security incidents
571
+ * const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
572
+ * .useIndex('date-index')
573
+ * .sortDescending()
574
+ * .limit(10)
575
+ * .execute();
576
+ *
577
+ * // Check latest dinosaur activities
578
+ * const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
579
+ * .useIndex('activity-time-index')
580
+ * .filter(op => op.eq('status', 'ACTIVE'))
581
+ * .sortDescending()
582
+ * .execute();
583
+ * ```
584
+ *
585
+ * @returns The builder instance for method chaining
586
+ */
587
+ sortDescending() {
588
+ this.options.scanIndexForward = false;
589
+ return this;
590
+ }
591
+ /**
592
+ * Creates a deep clone of this QueryBuilder instance.
593
+ *
594
+ * This is particularly useful when:
595
+ * - Implementing pagination (used internally by paginate())
596
+ * - Creating query templates
597
+ * - Running multiple variations of a query
598
+ *
599
+ * @example
600
+ * ```typescript
601
+ * // Create base dinosaur query
602
+ * const baseQuery = new QueryBuilder(executor, eq('species', 'Velociraptor'))
603
+ * .useIndex('status-index')
604
+ * .select(['id', 'status', 'location']);
605
+ *
606
+ * // Check active dinosaurs
607
+ * const activeRaptors = baseQuery.clone()
608
+ * .filter(op => op.eq('status', 'HUNTING'))
609
+ * .execute();
610
+ *
611
+ * // Check contained dinosaurs
612
+ * const containedRaptors = baseQuery.clone()
613
+ * .filter(op => op.eq('status', 'CONTAINED'))
614
+ * .execute();
615
+ *
616
+ * // Check sedated dinosaurs
617
+ * const sedatedRaptors = baseQuery.clone()
618
+ * .filter(op => op.eq('status', 'SEDATED'))
619
+ * .execute();
620
+ * ```
621
+ *
622
+ * @returns A new QueryBuilder instance with the same configuration
623
+ */
624
+ clone() {
625
+ const clone = new _QueryBuilder(this.executor, this.keyCondition);
626
+ clone.options = { ...this.options };
627
+ clone.selectedFields = new Set(this.selectedFields);
628
+ return clone;
629
+ }
630
+ /**
631
+ * Executes the query against DynamoDB.
632
+ *
633
+ * The method returns both the matched items and, if there are more results,
634
+ * a lastEvaluatedKey that can be used with startFrom() to continue the query.
635
+ *
636
+ * @example
637
+ * ```typescript
638
+ * try {
639
+ * // Find active carnivores in specific habitat
640
+ * const result = await new QueryBuilder(executor, eq('habitatId', 'PADDOCK-A'))
641
+ * .useIndex('species-status-index')
642
+ * .filter(op =>
643
+ * op.and([
644
+ * op.eq('diet', 'CARNIVORE'),
645
+ * op.eq('status', 'ACTIVE'),
646
+ * op.gt('aggressionLevel', 7)
647
+ * ])
648
+ * )
649
+ * .sortDescending()
650
+ * .limit(5)
651
+ * .execute();
652
+ *
653
+ * console.log(`Found ${result.items.length} dangerous dinosaurs`);
654
+ *
655
+ * if (result.lastEvaluatedKey) {
656
+ * console.log('Additional threats detected');
657
+ * }
658
+ * } catch (error) {
659
+ * console.error('Security scan failed:', error);
660
+ * }
661
+ * ```
662
+ *
663
+ * @returns A promise that resolves to an object containing:
664
+ * - items: Array of items matching the query
665
+ * - lastEvaluatedKey: Token for continuing the query, if more items exist
666
+ */
667
+ async execute() {
668
+ return this.executor(this.keyCondition, this.options);
669
+ }
670
+ };
671
+
672
+ exports.QueryBuilder = QueryBuilder;
673
+ //# sourceMappingURL=query-builder.cjs.map
674
+ //# sourceMappingURL=query-builder.cjs.map