dyno-table 2.2.1 → 2.3.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.
- package/README.md +200 -1860
- package/dist/builders.cjs +55 -0
- package/dist/builders.d.cts +4 -0
- package/dist/builders.d.ts +4 -0
- package/dist/builders.js +2 -0
- package/dist/chunk-2EWNZOUK.js +618 -0
- package/dist/chunk-2WIBY7PZ.js +46 -0
- package/dist/chunk-7UJJ7JXM.cjs +63 -0
- package/dist/chunk-DTFJJASK.js +3200 -0
- package/dist/chunk-EODPMYPE.js +558 -0
- package/dist/chunk-KA3VPIPS.cjs +560 -0
- package/dist/chunk-NTA6GDPP.cjs +622 -0
- package/dist/chunk-PB7BBCZO.cjs +32 -0
- package/dist/chunk-QVRMYGC4.js +29 -0
- package/dist/chunk-XYL43FDX.cjs +3217 -0
- package/dist/conditions.cjs +67 -62
- package/dist/conditions.js +1 -48
- package/dist/entity.cjs +14 -625
- package/dist/entity.d.cts +2 -10
- package/dist/entity.d.ts +2 -10
- package/dist/entity.js +2 -626
- package/dist/index-2cbm07Bi.d.ts +2797 -0
- package/dist/index-DlN8G9hd.d.cts +2797 -0
- package/dist/index.cjs +111 -4460
- package/dist/index.d.cts +2 -10
- package/dist/index.d.ts +2 -10
- package/dist/index.js +5 -4442
- package/dist/standard-schema.cjs +0 -2
- package/dist/standard-schema.js +0 -2
- package/dist/table.cjs +7 -3796
- package/dist/table.d.cts +163 -12
- package/dist/table.d.ts +163 -12
- package/dist/table.js +3 -3799
- package/dist/types.cjs +0 -2
- package/dist/types.js +0 -2
- package/dist/utils.cjs +10 -30
- package/dist/utils.js +1 -31
- package/package.json +6 -66
- package/dist/batch-builder-BiQDIZ7p.d.cts +0 -398
- package/dist/batch-builder-CNsLS6sR.d.ts +0 -398
- package/dist/builder-types-BTVhQSHI.d.cts +0 -169
- package/dist/builder-types-CzuLR4Th.d.ts +0 -169
- package/dist/builders/condition-check-builder.cjs +0 -422
- package/dist/builders/condition-check-builder.cjs.map +0 -1
- package/dist/builders/condition-check-builder.d.cts +0 -153
- package/dist/builders/condition-check-builder.d.ts +0 -153
- package/dist/builders/condition-check-builder.js +0 -420
- package/dist/builders/condition-check-builder.js.map +0 -1
- package/dist/builders/delete-builder.cjs +0 -484
- package/dist/builders/delete-builder.cjs.map +0 -1
- package/dist/builders/delete-builder.d.cts +0 -211
- package/dist/builders/delete-builder.d.ts +0 -211
- package/dist/builders/delete-builder.js +0 -482
- package/dist/builders/delete-builder.js.map +0 -1
- package/dist/builders/paginator.cjs +0 -193
- package/dist/builders/paginator.cjs.map +0 -1
- package/dist/builders/paginator.d.cts +0 -155
- package/dist/builders/paginator.d.ts +0 -155
- package/dist/builders/paginator.js +0 -191
- package/dist/builders/paginator.js.map +0 -1
- package/dist/builders/put-builder.cjs +0 -554
- package/dist/builders/put-builder.cjs.map +0 -1
- package/dist/builders/put-builder.d.cts +0 -319
- package/dist/builders/put-builder.d.ts +0 -319
- package/dist/builders/put-builder.js +0 -552
- package/dist/builders/put-builder.js.map +0 -1
- package/dist/builders/query-builder.cjs +0 -757
- package/dist/builders/query-builder.cjs.map +0 -1
- package/dist/builders/query-builder.d.cts +0 -6
- package/dist/builders/query-builder.d.ts +0 -6
- package/dist/builders/query-builder.js +0 -755
- package/dist/builders/query-builder.js.map +0 -1
- package/dist/builders/transaction-builder.cjs +0 -906
- package/dist/builders/transaction-builder.cjs.map +0 -1
- package/dist/builders/transaction-builder.d.cts +0 -464
- package/dist/builders/transaction-builder.d.ts +0 -464
- package/dist/builders/transaction-builder.js +0 -904
- package/dist/builders/transaction-builder.js.map +0 -1
- package/dist/builders/update-builder.cjs +0 -668
- package/dist/builders/update-builder.cjs.map +0 -1
- package/dist/builders/update-builder.d.cts +0 -374
- package/dist/builders/update-builder.d.ts +0 -374
- package/dist/builders/update-builder.js +0 -666
- package/dist/builders/update-builder.js.map +0 -1
- package/dist/conditions.cjs.map +0 -1
- package/dist/conditions.js.map +0 -1
- package/dist/entity.cjs.map +0 -1
- package/dist/entity.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/query-builder-D3URwK9k.d.cts +0 -477
- package/dist/query-builder-cfEkU0_w.d.ts +0 -477
- package/dist/standard-schema.cjs.map +0 -1
- package/dist/standard-schema.js.map +0 -1
- package/dist/table-ClST8nkR.d.cts +0 -276
- package/dist/table-vE3cGoDy.d.ts +0 -276
- package/dist/table.cjs.map +0 -1
- package/dist/table.js.map +0 -1
- package/dist/types.cjs.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils.cjs.map +0 -1
- package/dist/utils.js.map +0 -1
|
@@ -1,755 +0,0 @@
|
|
|
1
|
-
// src/conditions.ts
|
|
2
|
-
var createComparisonCondition = (type) => (attr, value) => ({
|
|
3
|
-
type,
|
|
4
|
-
attr,
|
|
5
|
-
value
|
|
6
|
-
});
|
|
7
|
-
var eq = createComparisonCondition("eq");
|
|
8
|
-
var ne = createComparisonCondition("ne");
|
|
9
|
-
var lt = createComparisonCondition("lt");
|
|
10
|
-
var lte = createComparisonCondition("lte");
|
|
11
|
-
var gt = createComparisonCondition("gt");
|
|
12
|
-
var gte = createComparisonCondition("gte");
|
|
13
|
-
var between = (attr, lower, upper) => ({
|
|
14
|
-
type: "between",
|
|
15
|
-
attr,
|
|
16
|
-
value: [lower, upper]
|
|
17
|
-
});
|
|
18
|
-
var inArray = (attr, values) => ({
|
|
19
|
-
type: "in",
|
|
20
|
-
attr,
|
|
21
|
-
value: values
|
|
22
|
-
});
|
|
23
|
-
var beginsWith = createComparisonCondition("beginsWith");
|
|
24
|
-
var contains = createComparisonCondition("contains");
|
|
25
|
-
var attributeExists = (attr) => ({
|
|
26
|
-
type: "attributeExists",
|
|
27
|
-
attr
|
|
28
|
-
});
|
|
29
|
-
var attributeNotExists = (attr) => ({
|
|
30
|
-
type: "attributeNotExists",
|
|
31
|
-
attr
|
|
32
|
-
});
|
|
33
|
-
var and = (...conditions) => ({
|
|
34
|
-
type: "and",
|
|
35
|
-
conditions
|
|
36
|
-
});
|
|
37
|
-
var or = (...conditions) => ({
|
|
38
|
-
type: "or",
|
|
39
|
-
conditions
|
|
40
|
-
});
|
|
41
|
-
var not = (condition) => ({
|
|
42
|
-
type: "not",
|
|
43
|
-
condition
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
// src/builders/paginator.ts
|
|
47
|
-
var Paginator = class {
|
|
48
|
-
queryBuilder;
|
|
49
|
-
pageSize;
|
|
50
|
-
currentPage = 0;
|
|
51
|
-
lastEvaluatedKey;
|
|
52
|
-
hasMorePages = true;
|
|
53
|
-
totalItemsRetrieved = 0;
|
|
54
|
-
overallLimit;
|
|
55
|
-
constructor(queryBuilder, pageSize) {
|
|
56
|
-
this.queryBuilder = queryBuilder;
|
|
57
|
-
this.pageSize = pageSize;
|
|
58
|
-
this.overallLimit = queryBuilder.getLimit();
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Gets the current page number (1-indexed).
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* ```ts
|
|
65
|
-
* const paginator = new QueryBuilder(executor, eq('species', 'Tyrannosaurus'))
|
|
66
|
-
* .paginate(5);
|
|
67
|
-
*
|
|
68
|
-
* await paginator.getNextPage();
|
|
69
|
-
* console.log(`Reviewing T-Rex group ${paginator.getCurrentPage()}`);
|
|
70
|
-
* ```
|
|
71
|
-
*
|
|
72
|
-
* @returns The current page number, starting from 1
|
|
73
|
-
*/
|
|
74
|
-
getCurrentPage() {
|
|
75
|
-
return this.currentPage;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Checks if there are more pages of dinosaurs or habitats to process.
|
|
79
|
-
*
|
|
80
|
-
* This method takes into account both:
|
|
81
|
-
* - DynamoDB's lastEvaluatedKey mechanism
|
|
82
|
-
* - Any overall limit set on the query
|
|
83
|
-
*
|
|
84
|
-
* @example
|
|
85
|
-
* ```ts
|
|
86
|
-
* // Process all security incidents
|
|
87
|
-
* const paginator = new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
|
|
88
|
-
* .sortDescending()
|
|
89
|
-
* .paginate(10);
|
|
90
|
-
*
|
|
91
|
-
* while (paginator.hasNextPage()) {
|
|
92
|
-
* const page = await paginator.getNextPage();
|
|
93
|
-
* for (const incident of page.items) {
|
|
94
|
-
* await processSecurityBreach(incident);
|
|
95
|
-
* }
|
|
96
|
-
* console.log(`Processed incidents page ${page.page}`);
|
|
97
|
-
* }
|
|
98
|
-
* ```
|
|
99
|
-
*
|
|
100
|
-
* @returns true if there are more pages available, false otherwise
|
|
101
|
-
*/
|
|
102
|
-
hasNextPage() {
|
|
103
|
-
if (this.overallLimit !== void 0 && this.totalItemsRetrieved >= this.overallLimit) {
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
return this.hasMorePages;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Retrieves the next page of dinosaurs or habitats from DynamoDB.
|
|
110
|
-
*
|
|
111
|
-
* This method handles:
|
|
112
|
-
* - Automatic continuation between groups
|
|
113
|
-
* - Respect for park capacity limits
|
|
114
|
-
* - Group size adjustments for safety
|
|
115
|
-
*
|
|
116
|
-
* @example
|
|
117
|
-
* ```ts
|
|
118
|
-
* const paginator = new QueryBuilder(executor, eq('species', 'Velociraptor'))
|
|
119
|
-
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
120
|
-
* .paginate(5);
|
|
121
|
-
*
|
|
122
|
-
* // Check first raptor group
|
|
123
|
-
* const page1 = await paginator.getNextPage();
|
|
124
|
-
* console.log(`Found ${page1.items.length} active raptors`);
|
|
125
|
-
*
|
|
126
|
-
* // Continue inspection if more groups exist
|
|
127
|
-
* if (page1.hasNextPage) {
|
|
128
|
-
* const page2 = await paginator.getNextPage();
|
|
129
|
-
* console.log(`Inspecting raptor group ${page2.page}`);
|
|
130
|
-
*
|
|
131
|
-
* for (const raptor of page2.items) {
|
|
132
|
-
* await performHealthCheck(raptor);
|
|
133
|
-
* }
|
|
134
|
-
* }
|
|
135
|
-
* ```
|
|
136
|
-
*
|
|
137
|
-
* @returns A promise that resolves to a PaginationResult containing:
|
|
138
|
-
* - items: The dinosaurs/habitats for this page
|
|
139
|
-
* - hasNextPage: Whether more groups exist
|
|
140
|
-
* - page: The current group number
|
|
141
|
-
* - lastEvaluatedKey: DynamoDB's continuation token
|
|
142
|
-
*/
|
|
143
|
-
async getNextPage() {
|
|
144
|
-
if (!this.hasNextPage()) {
|
|
145
|
-
return {
|
|
146
|
-
items: [],
|
|
147
|
-
hasNextPage: false,
|
|
148
|
-
page: this.currentPage
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
let effectivePageSize = this.pageSize;
|
|
152
|
-
if (this.overallLimit !== void 0) {
|
|
153
|
-
const remainingItems = this.overallLimit - this.totalItemsRetrieved;
|
|
154
|
-
if (remainingItems <= 0) {
|
|
155
|
-
return {
|
|
156
|
-
items: [],
|
|
157
|
-
hasNextPage: false,
|
|
158
|
-
page: this.currentPage
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
if (effectivePageSize !== void 0) {
|
|
162
|
-
effectivePageSize = Math.min(effectivePageSize, remainingItems);
|
|
163
|
-
} else {
|
|
164
|
-
effectivePageSize = remainingItems;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
const query = this.queryBuilder.clone();
|
|
168
|
-
if (effectivePageSize !== void 0) {
|
|
169
|
-
query.limit(effectivePageSize);
|
|
170
|
-
}
|
|
171
|
-
if (this.lastEvaluatedKey) {
|
|
172
|
-
query.startFrom(this.lastEvaluatedKey);
|
|
173
|
-
}
|
|
174
|
-
const generator = await query.execute();
|
|
175
|
-
const items = [];
|
|
176
|
-
let itemCount = 0;
|
|
177
|
-
for await (const item of generator) {
|
|
178
|
-
if (effectivePageSize !== void 0 && itemCount >= effectivePageSize) {
|
|
179
|
-
break;
|
|
180
|
-
}
|
|
181
|
-
items.push(item);
|
|
182
|
-
itemCount++;
|
|
183
|
-
}
|
|
184
|
-
const lastEvaluatedKey = generator.getLastEvaluatedKey();
|
|
185
|
-
const result = { items, lastEvaluatedKey };
|
|
186
|
-
this.currentPage += 1;
|
|
187
|
-
this.lastEvaluatedKey = result.lastEvaluatedKey;
|
|
188
|
-
this.totalItemsRetrieved += result.items.length;
|
|
189
|
-
this.hasMorePages = !!result.lastEvaluatedKey && (this.overallLimit === void 0 || this.totalItemsRetrieved < this.overallLimit);
|
|
190
|
-
return {
|
|
191
|
-
items: result.items,
|
|
192
|
-
lastEvaluatedKey: result.lastEvaluatedKey,
|
|
193
|
-
hasNextPage: this.hasNextPage(),
|
|
194
|
-
page: this.currentPage
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Gets all remaining dinosaurs or habitats and combines them into a single array.
|
|
199
|
-
*
|
|
200
|
-
* @example
|
|
201
|
-
* ```ts
|
|
202
|
-
* // Get complete carnivore inventory
|
|
203
|
-
* const paginator = new QueryBuilder(executor, eq('diet', 'CARNIVORE'))
|
|
204
|
-
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
205
|
-
* .paginate(10);
|
|
206
|
-
*
|
|
207
|
-
* try {
|
|
208
|
-
* const allCarnivores = await paginator.getAllPages();
|
|
209
|
-
* console.log(`Park contains ${allCarnivores.length} active carnivores`);
|
|
210
|
-
*
|
|
211
|
-
* // Calculate total threat level
|
|
212
|
-
* const totalThreat = allCarnivores.reduce(
|
|
213
|
-
* (sum, dino) => sum + dino.stats.threatLevel,
|
|
214
|
-
* 0
|
|
215
|
-
* );
|
|
216
|
-
* console.log(`Total threat level: ${totalThreat}`);
|
|
217
|
-
* } catch (error) {
|
|
218
|
-
* console.error('Failed to complete carnivore census:', error);
|
|
219
|
-
* }
|
|
220
|
-
* ```
|
|
221
|
-
*
|
|
222
|
-
* @returns A promise that resolves to an array containing all remaining items
|
|
223
|
-
*/
|
|
224
|
-
async getAllPages() {
|
|
225
|
-
const allItems = [];
|
|
226
|
-
while (this.hasNextPage()) {
|
|
227
|
-
const result = await this.getNextPage();
|
|
228
|
-
allItems.push(...result.items);
|
|
229
|
-
}
|
|
230
|
-
return allItems;
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
// src/builders/filter-builder.ts
|
|
235
|
-
var FilterBuilder = class {
|
|
236
|
-
options = {};
|
|
237
|
-
selectedFields = /* @__PURE__ */ new Set();
|
|
238
|
-
/**
|
|
239
|
-
* Sets the maximum number of items to return.
|
|
240
|
-
*
|
|
241
|
-
* Note: This limit applies to the items that match the key condition
|
|
242
|
-
* before any filter expressions are applied.
|
|
243
|
-
*
|
|
244
|
-
* @example
|
|
245
|
-
* ```typescript
|
|
246
|
-
* // Get first 10 dinosaurs
|
|
247
|
-
* const result = await builder
|
|
248
|
-
* .limit(10)
|
|
249
|
-
* .execute();
|
|
250
|
-
* ```
|
|
251
|
-
*
|
|
252
|
-
* @param limit - Maximum number of items to return
|
|
253
|
-
* @returns The builder instance for method chaining
|
|
254
|
-
*/
|
|
255
|
-
limit(limit) {
|
|
256
|
-
this.options.limit = limit;
|
|
257
|
-
return this;
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Gets the current limit set on the operation.
|
|
261
|
-
* This is used internally by the paginator to manage result sets.
|
|
262
|
-
*
|
|
263
|
-
* @returns The current limit or undefined if no limit is set
|
|
264
|
-
*/
|
|
265
|
-
getLimit() {
|
|
266
|
-
return this.options.limit;
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Specifies a Global Secondary Index (GSI) to use for the operation.
|
|
270
|
-
*
|
|
271
|
-
* @example
|
|
272
|
-
* ```typescript
|
|
273
|
-
* // Find all dinosaurs of a specific species
|
|
274
|
-
* builder
|
|
275
|
-
* .useIndex('species-status-index')
|
|
276
|
-
* .filter(op => op.eq('status', 'ACTIVE'));
|
|
277
|
-
*
|
|
278
|
-
* // Search high-security habitats
|
|
279
|
-
* builder
|
|
280
|
-
* .useIndex('security-level-index')
|
|
281
|
-
* .filter(op =>
|
|
282
|
-
* op.and([
|
|
283
|
-
* op.gt('securityLevel', 8),
|
|
284
|
-
* op.eq('status', 'OPERATIONAL')
|
|
285
|
-
* ])
|
|
286
|
-
* );
|
|
287
|
-
* ```
|
|
288
|
-
*
|
|
289
|
-
* @param indexName - The name of the GSI to use (type-safe based on table configuration)
|
|
290
|
-
* @returns The builder instance for method chaining
|
|
291
|
-
*/
|
|
292
|
-
useIndex(indexName) {
|
|
293
|
-
this.options.indexName = indexName;
|
|
294
|
-
return this;
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Sets whether to use strongly consistent reads for the operation.
|
|
298
|
-
*
|
|
299
|
-
* Note:
|
|
300
|
-
* - Consistent reads are not available on GSIs
|
|
301
|
-
* - Consistent reads consume twice the throughput
|
|
302
|
-
* - Default is eventually consistent reads
|
|
303
|
-
*
|
|
304
|
-
* @example
|
|
305
|
-
* ```typescript
|
|
306
|
-
* // Check immediate dinosaur status
|
|
307
|
-
* const result = await builder
|
|
308
|
-
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
309
|
-
* .consistentRead()
|
|
310
|
-
* .execute();
|
|
311
|
-
*
|
|
312
|
-
* // Monitor security breaches
|
|
313
|
-
* const result = await builder
|
|
314
|
-
* .useIndex('primary-index')
|
|
315
|
-
* .consistentRead(isEmergencyMode)
|
|
316
|
-
* .execute();
|
|
317
|
-
* ```
|
|
318
|
-
*
|
|
319
|
-
* @param consistentRead - Whether to use consistent reads (defaults to true)
|
|
320
|
-
* @returns The builder instance for method chaining
|
|
321
|
-
*/
|
|
322
|
-
consistentRead(consistentRead = true) {
|
|
323
|
-
this.options.consistentRead = consistentRead;
|
|
324
|
-
return this;
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Adds a filter expression to refine the operation results.
|
|
328
|
-
*
|
|
329
|
-
* @example
|
|
330
|
-
* ```typescript
|
|
331
|
-
* // Find aggressive carnivores
|
|
332
|
-
* builder.filter(op =>
|
|
333
|
-
* op.and([
|
|
334
|
-
* op.eq('diet', 'CARNIVORE'),
|
|
335
|
-
* op.gt('aggressionLevel', 7),
|
|
336
|
-
* op.eq('status', 'ACTIVE')
|
|
337
|
-
* ])
|
|
338
|
-
* );
|
|
339
|
-
*
|
|
340
|
-
* // Search suitable breeding habitats
|
|
341
|
-
* builder.filter(op =>
|
|
342
|
-
* op.and([
|
|
343
|
-
* op.between('temperature', 25, 30),
|
|
344
|
-
* op.lt('currentOccupants', 3),
|
|
345
|
-
* op.eq('quarantineStatus', 'CLEAR')
|
|
346
|
-
* ])
|
|
347
|
-
* );
|
|
348
|
-
* ```
|
|
349
|
-
*
|
|
350
|
-
* @param condition - Either a Condition object or a callback function that builds the condition
|
|
351
|
-
* @returns The builder instance for method chaining
|
|
352
|
-
*/
|
|
353
|
-
filter(condition) {
|
|
354
|
-
const newCondition = typeof condition === "function" ? condition(this.getConditionOperator()) : condition;
|
|
355
|
-
if (this.options.filter) {
|
|
356
|
-
if (this.options.filter.type === "and" && this.options.filter.conditions) {
|
|
357
|
-
if (newCondition.type === "and" && newCondition.conditions) {
|
|
358
|
-
this.options.filter = {
|
|
359
|
-
type: "and",
|
|
360
|
-
conditions: [...this.options.filter.conditions, ...newCondition.conditions]
|
|
361
|
-
};
|
|
362
|
-
} else {
|
|
363
|
-
this.options.filter = {
|
|
364
|
-
type: "and",
|
|
365
|
-
conditions: [...this.options.filter.conditions, newCondition]
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
} else {
|
|
369
|
-
if (newCondition.type === "and" && newCondition.conditions) {
|
|
370
|
-
this.options.filter = {
|
|
371
|
-
type: "and",
|
|
372
|
-
conditions: [this.options.filter, ...newCondition.conditions]
|
|
373
|
-
};
|
|
374
|
-
} else {
|
|
375
|
-
this.options.filter = and(this.options.filter, newCondition);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
} else {
|
|
379
|
-
this.options.filter = newCondition;
|
|
380
|
-
}
|
|
381
|
-
return this;
|
|
382
|
-
}
|
|
383
|
-
getConditionOperator() {
|
|
384
|
-
return {
|
|
385
|
-
eq,
|
|
386
|
-
ne,
|
|
387
|
-
lt,
|
|
388
|
-
lte,
|
|
389
|
-
gt,
|
|
390
|
-
gte,
|
|
391
|
-
between,
|
|
392
|
-
inArray,
|
|
393
|
-
beginsWith,
|
|
394
|
-
contains,
|
|
395
|
-
attributeExists,
|
|
396
|
-
attributeNotExists,
|
|
397
|
-
and,
|
|
398
|
-
or,
|
|
399
|
-
not
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Specifies which attributes to return in the results.
|
|
404
|
-
*
|
|
405
|
-
* @example
|
|
406
|
-
* ```typescript
|
|
407
|
-
* // Get basic dinosaur info
|
|
408
|
-
* builder.select([
|
|
409
|
-
* 'species',
|
|
410
|
-
* 'status',
|
|
411
|
-
* 'stats.health',
|
|
412
|
-
* 'stats.aggressionLevel'
|
|
413
|
-
* ]);
|
|
414
|
-
*
|
|
415
|
-
* // Monitor habitat conditions
|
|
416
|
-
* builder
|
|
417
|
-
* .select('securityStatus')
|
|
418
|
-
* .select([
|
|
419
|
-
* 'currentOccupants',
|
|
420
|
-
* 'temperature',
|
|
421
|
-
* 'lastInspectionDate'
|
|
422
|
-
* ]);
|
|
423
|
-
* ```
|
|
424
|
-
*
|
|
425
|
-
* @param fields - A single field name or an array of field names to return
|
|
426
|
-
* @returns The builder instance for method chaining
|
|
427
|
-
*/
|
|
428
|
-
select(fields) {
|
|
429
|
-
if (typeof fields === "string") {
|
|
430
|
-
this.selectedFields.add(fields);
|
|
431
|
-
} else if (Array.isArray(fields)) {
|
|
432
|
-
for (const field of fields) {
|
|
433
|
-
this.selectedFields.add(field);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
this.options.projection = Array.from(this.selectedFields);
|
|
437
|
-
return this;
|
|
438
|
-
}
|
|
439
|
-
/**
|
|
440
|
-
* Creates a paginator that handles DynamoDB pagination automatically.
|
|
441
|
-
* The paginator handles:
|
|
442
|
-
* - Tracking the last evaluated key
|
|
443
|
-
* - Managing page boundaries
|
|
444
|
-
* - Respecting overall query limits
|
|
445
|
-
*
|
|
446
|
-
* @example
|
|
447
|
-
* ```typescript
|
|
448
|
-
* // Create a paginator for dinosaur records with specific page size
|
|
449
|
-
* const paginator = builder
|
|
450
|
-
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
451
|
-
* .paginate(10);
|
|
452
|
-
*
|
|
453
|
-
* // Create a paginator with automatic DynamoDB paging (no page size limit)
|
|
454
|
-
* const autoPaginator = builder
|
|
455
|
-
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
456
|
-
* .paginate();
|
|
457
|
-
*
|
|
458
|
-
* // Process pages of dinosaur results
|
|
459
|
-
* while (paginator.hasNextPage()) {
|
|
460
|
-
* const page = await paginator.getNextPage();
|
|
461
|
-
* console.log(`Processing page ${page.page}, count: ${page.items.length}`);
|
|
462
|
-
* // Process dinosaur data
|
|
463
|
-
* }
|
|
464
|
-
* ```
|
|
465
|
-
*
|
|
466
|
-
* @param pageSize - The number of items to return per page. If not provided, DynamoDB will automatically determine page sizes.
|
|
467
|
-
* @returns A Paginator instance that manages the pagination state
|
|
468
|
-
* @see Paginator for more pagination control options
|
|
469
|
-
*/
|
|
470
|
-
paginate(pageSize) {
|
|
471
|
-
return new Paginator(this, pageSize);
|
|
472
|
-
}
|
|
473
|
-
/**
|
|
474
|
-
* Sets the starting point using a previous lastEvaluatedKey.
|
|
475
|
-
*
|
|
476
|
-
* Note: This method is typically used for manual pagination.
|
|
477
|
-
* For automatic pagination, use the paginate() method instead.
|
|
478
|
-
*
|
|
479
|
-
* @example
|
|
480
|
-
* ```typescript
|
|
481
|
-
* // First batch of dinosaurs
|
|
482
|
-
* const result1 = await builder
|
|
483
|
-
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
484
|
-
* .limit(5)
|
|
485
|
-
* .execute();
|
|
486
|
-
*
|
|
487
|
-
* const lastKey = result1.getLastEvaluatedKey();
|
|
488
|
-
* if (lastKey) {
|
|
489
|
-
* // Continue listing dinosaurs
|
|
490
|
-
* const result2 = await builder
|
|
491
|
-
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
492
|
-
* .startFrom(lastKey)
|
|
493
|
-
* .limit(5)
|
|
494
|
-
* .execute();
|
|
495
|
-
*
|
|
496
|
-
* const items = await result2.toArray();
|
|
497
|
-
* console.log('Additional dinosaurs:', 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/result-iterator.ts
|
|
511
|
-
var ResultIterator = class {
|
|
512
|
-
constructor(queryBuilder, directExecutor) {
|
|
513
|
-
this.queryBuilder = queryBuilder;
|
|
514
|
-
this.directExecutor = directExecutor;
|
|
515
|
-
this.overallLimit = queryBuilder.getLimit();
|
|
516
|
-
}
|
|
517
|
-
lastEvaluatedKey;
|
|
518
|
-
itemsYielded = 0;
|
|
519
|
-
overallLimit;
|
|
520
|
-
/**
|
|
521
|
-
* Async iterator with automatic pagination
|
|
522
|
-
*/
|
|
523
|
-
async *[Symbol.asyncIterator]() {
|
|
524
|
-
let hasMorePages = true;
|
|
525
|
-
while (hasMorePages) {
|
|
526
|
-
const result = await this.directExecutor();
|
|
527
|
-
for (const item of result.items) {
|
|
528
|
-
if (this.overallLimit !== void 0 && this.itemsYielded >= this.overallLimit) {
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
yield item;
|
|
532
|
-
this.itemsYielded++;
|
|
533
|
-
}
|
|
534
|
-
if (result.lastEvaluatedKey !== null && result.lastEvaluatedKey !== void 0) {
|
|
535
|
-
this.lastEvaluatedKey = result.lastEvaluatedKey;
|
|
536
|
-
this.queryBuilder.startFrom(result.lastEvaluatedKey);
|
|
537
|
-
} else if (result.lastEvaluatedKey === null) {
|
|
538
|
-
if (this.lastEvaluatedKey === void 0) {
|
|
539
|
-
this.lastEvaluatedKey = null;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
hasMorePages = !!result.lastEvaluatedKey && (this.overallLimit === void 0 || this.itemsYielded < this.overallLimit);
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Convert to array (loads all pages).
|
|
547
|
-
*
|
|
548
|
-
* ```ts
|
|
549
|
-
* const result = await table.query({ pk: "foo" }).execute();
|
|
550
|
-
* const allItemsFromDynamo = await result.toArray();
|
|
551
|
-
* ```
|
|
552
|
-
*
|
|
553
|
-
* Note: This will load all pages into memory. For large datasets, consider using async iteration instead.
|
|
554
|
-
*```ts
|
|
555
|
-
* const result = await table.query({ pk: "foo" }).execute();
|
|
556
|
-
* for await (const item of result) {
|
|
557
|
-
* // Process each item
|
|
558
|
-
* }
|
|
559
|
-
* ```
|
|
560
|
-
*/
|
|
561
|
-
async toArray() {
|
|
562
|
-
const items = [];
|
|
563
|
-
for await (const item of this) {
|
|
564
|
-
items.push(item);
|
|
565
|
-
}
|
|
566
|
-
return items;
|
|
567
|
-
}
|
|
568
|
-
/**
|
|
569
|
-
* Get the last evaluated key
|
|
570
|
-
*/
|
|
571
|
-
getLastEvaluatedKey() {
|
|
572
|
-
return this.lastEvaluatedKey === null ? void 0 : this.lastEvaluatedKey;
|
|
573
|
-
}
|
|
574
|
-
};
|
|
575
|
-
|
|
576
|
-
// src/builders/query-builder.ts
|
|
577
|
-
var QueryBuilder = class _QueryBuilder extends FilterBuilder {
|
|
578
|
-
keyCondition;
|
|
579
|
-
options = {};
|
|
580
|
-
executor;
|
|
581
|
-
constructor(executor, keyCondition) {
|
|
582
|
-
super();
|
|
583
|
-
this.executor = executor;
|
|
584
|
-
this.keyCondition = keyCondition;
|
|
585
|
-
}
|
|
586
|
-
/**
|
|
587
|
-
* Sets the maximum number of items to return from the query.
|
|
588
|
-
*
|
|
589
|
-
* Note: This is the default behavior if no sort order is specified.
|
|
590
|
-
*
|
|
591
|
-
* @example
|
|
592
|
-
* ```typescript
|
|
593
|
-
* // Get orders in chronological order
|
|
594
|
-
* const result = await new QueryBuilder(executor, eq('userId', '123'))
|
|
595
|
-
* .sortAscending()
|
|
596
|
-
* .execute();
|
|
597
|
-
*
|
|
598
|
-
* // Get events from oldest to newest
|
|
599
|
-
* const result = await new QueryBuilder(executor, eq('entityId', 'order-123'))
|
|
600
|
-
* .useIndex('entity-timestamp-index')
|
|
601
|
-
* .sortAscending()
|
|
602
|
-
* .execute();
|
|
603
|
-
* ```
|
|
604
|
-
*
|
|
605
|
-
* @returns The builder instance for method chaining
|
|
606
|
-
*/
|
|
607
|
-
/**
|
|
608
|
-
* Sets the query to return items in ascending order by sort key.
|
|
609
|
-
*
|
|
610
|
-
* @example
|
|
611
|
-
* ```typescript
|
|
612
|
-
* // List dinosaurs by age
|
|
613
|
-
* const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
|
|
614
|
-
* .useIndex('age-index')
|
|
615
|
-
* .sortAscending()
|
|
616
|
-
* .execute();
|
|
617
|
-
*
|
|
618
|
-
* // View incidents chronologically
|
|
619
|
-
* const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
|
|
620
|
-
* .useIndex('date-index')
|
|
621
|
-
* .sortAscending()
|
|
622
|
-
* .execute();
|
|
623
|
-
* ```
|
|
624
|
-
*
|
|
625
|
-
* @returns The builder instance for method chaining
|
|
626
|
-
*/
|
|
627
|
-
sortAscending() {
|
|
628
|
-
this.options.scanIndexForward = true;
|
|
629
|
-
return this;
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Sets the query to return items in descending order by sort key.
|
|
633
|
-
*
|
|
634
|
-
* @example
|
|
635
|
-
* ```typescript
|
|
636
|
-
* // Get most recent security incidents
|
|
637
|
-
* const result = await new QueryBuilder(executor, eq('type', 'SECURITY_BREACH'))
|
|
638
|
-
* .useIndex('date-index')
|
|
639
|
-
* .sortDescending()
|
|
640
|
-
* .limit(10)
|
|
641
|
-
* .execute();
|
|
642
|
-
*
|
|
643
|
-
* // Check latest dinosaur activities
|
|
644
|
-
* const result = await new QueryBuilder(executor, eq('species', 'Velociraptor'))
|
|
645
|
-
* .useIndex('activity-time-index')
|
|
646
|
-
* .filter(op => op.eq('status', 'ACTIVE'))
|
|
647
|
-
* .sortDescending()
|
|
648
|
-
* .execute();
|
|
649
|
-
* ```
|
|
650
|
-
*
|
|
651
|
-
* @returns The builder instance for method chaining
|
|
652
|
-
*/
|
|
653
|
-
sortDescending() {
|
|
654
|
-
this.options.scanIndexForward = false;
|
|
655
|
-
return this;
|
|
656
|
-
}
|
|
657
|
-
/**
|
|
658
|
-
* Creates a deep clone of this QueryBuilder instance.
|
|
659
|
-
*
|
|
660
|
-
* This is particularly useful when:
|
|
661
|
-
* - Implementing pagination (used internally by paginate())
|
|
662
|
-
* - Creating query templates
|
|
663
|
-
* - Running multiple variations of a query
|
|
664
|
-
*
|
|
665
|
-
* @example
|
|
666
|
-
* ```typescript
|
|
667
|
-
* // Create base dinosaur query
|
|
668
|
-
* const baseQuery = new QueryBuilder(executor, eq('species', 'Velociraptor'))
|
|
669
|
-
* .useIndex('status-index')
|
|
670
|
-
* .select(['id', 'status', 'location']);
|
|
671
|
-
*
|
|
672
|
-
* // Check active dinosaurs
|
|
673
|
-
* const activeRaptors = baseQuery.clone()
|
|
674
|
-
* .filter(op => op.eq('status', 'HUNTING'))
|
|
675
|
-
* .execute();
|
|
676
|
-
*
|
|
677
|
-
* // Check contained dinosaurs
|
|
678
|
-
* const containedRaptors = baseQuery.clone()
|
|
679
|
-
* .filter(op => op.eq('status', 'CONTAINED'))
|
|
680
|
-
* .execute();
|
|
681
|
-
*
|
|
682
|
-
* // Check sedated dinosaurs
|
|
683
|
-
* const sedatedRaptors = baseQuery.clone()
|
|
684
|
-
* .filter(op => op.eq('status', 'SEDATED'))
|
|
685
|
-
* .execute();
|
|
686
|
-
* ```
|
|
687
|
-
*
|
|
688
|
-
* @returns A new QueryBuilder instance with the same configuration
|
|
689
|
-
*/
|
|
690
|
-
clone() {
|
|
691
|
-
const clone = new _QueryBuilder(this.executor, this.keyCondition);
|
|
692
|
-
clone.options = {
|
|
693
|
-
...this.options,
|
|
694
|
-
filter: this.deepCloneFilter(this.options.filter)
|
|
695
|
-
};
|
|
696
|
-
clone.selectedFields = new Set(this.selectedFields);
|
|
697
|
-
return clone;
|
|
698
|
-
}
|
|
699
|
-
deepCloneFilter(filter) {
|
|
700
|
-
if (!filter) return filter;
|
|
701
|
-
if (filter.type === "and" || filter.type === "or") {
|
|
702
|
-
return {
|
|
703
|
-
...filter,
|
|
704
|
-
conditions: filter.conditions?.map((condition) => this.deepCloneFilter(condition)).filter((c) => c !== void 0)
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
return { ...filter };
|
|
708
|
-
}
|
|
709
|
-
/**
|
|
710
|
-
* Executes the query against DynamoDB and returns a generator that behaves like an array.
|
|
711
|
-
*
|
|
712
|
-
* The generator automatically handles pagination and provides array-like methods
|
|
713
|
-
* for processing results efficiently without loading everything into memory at once.
|
|
714
|
-
*
|
|
715
|
-
* @example
|
|
716
|
-
* ```typescript
|
|
717
|
-
* try {
|
|
718
|
-
* // Find active carnivores with automatic pagination
|
|
719
|
-
* const results = await new QueryBuilder(executor, eq('habitatId', 'PADDOCK-A'))
|
|
720
|
-
* .useIndex('species-status-index')
|
|
721
|
-
* .filter(op =>
|
|
722
|
-
* op.and([
|
|
723
|
-
* op.eq('diet', 'CARNIVORE'),
|
|
724
|
-
* op.eq('status', 'ACTIVE'),
|
|
725
|
-
* op.gt('aggressionLevel', 7)
|
|
726
|
-
* ])
|
|
727
|
-
* )
|
|
728
|
-
* .sortDescending()
|
|
729
|
-
* .execute();
|
|
730
|
-
*
|
|
731
|
-
* // Use like an array with automatic pagination
|
|
732
|
-
* for await (const dinosaur of results) {
|
|
733
|
-
* console.log(`Processing ${dinosaur.name}`);
|
|
734
|
-
* }
|
|
735
|
-
*
|
|
736
|
-
* // Or convert to array and use array methods
|
|
737
|
-
* const allItems = await results.toArray();
|
|
738
|
-
* const dangerousOnes = allItems.filter(dino => dino.aggressionLevel > 9);
|
|
739
|
-
* const totalCount = allItems.length;
|
|
740
|
-
* } catch (error) {
|
|
741
|
-
* console.error('Security scan failed:', error);
|
|
742
|
-
* }
|
|
743
|
-
* ```
|
|
744
|
-
*
|
|
745
|
-
* @returns A promise that resolves to a ResultGenerator that behaves like an array
|
|
746
|
-
*/
|
|
747
|
-
async execute() {
|
|
748
|
-
const directExecutor = () => this.executor(this.keyCondition, this.options);
|
|
749
|
-
return new ResultIterator(this, directExecutor);
|
|
750
|
-
}
|
|
751
|
-
};
|
|
752
|
-
|
|
753
|
-
export { QueryBuilder };
|
|
754
|
-
//# sourceMappingURL=query-builder.js.map
|
|
755
|
-
//# sourceMappingURL=query-builder.js.map
|