dyno-table 2.3.3 → 2.5.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.
@@ -0,0 +1,543 @@
1
+ // src/errors.ts
2
+ var DynoTableError = class extends Error {
3
+ /**
4
+ * Machine-readable error code for programmatic error handling
5
+ * @example "KEY_GENERATION_FAILED", "VALIDATION_ERROR", etc.
6
+ */
7
+ code;
8
+ /**
9
+ * Additional context about the error
10
+ * Contains operation-specific details like entity names, table names,
11
+ * expressions, conditions, and other relevant debugging information
12
+ */
13
+ context;
14
+ /**
15
+ * The original error that caused this error (if wrapping another error)
16
+ * Useful for preserving AWS SDK errors or other underlying errors
17
+ */
18
+ cause;
19
+ constructor(message, code, context = {}, cause) {
20
+ super(message);
21
+ this.name = "DynoTableError";
22
+ this.code = code;
23
+ this.context = context;
24
+ this.cause = cause;
25
+ if (Error.captureStackTrace) {
26
+ Error.captureStackTrace(this, this.constructor);
27
+ }
28
+ }
29
+ };
30
+ var ValidationError = class extends DynoTableError {
31
+ constructor(message, code, context = {}, cause) {
32
+ super(message, code, context, cause);
33
+ this.name = "ValidationError";
34
+ }
35
+ };
36
+ var OperationError = class extends DynoTableError {
37
+ constructor(message, code, context = {}, cause) {
38
+ super(message, code, context, cause);
39
+ this.name = "OperationError";
40
+ }
41
+ };
42
+ var TransactionError = class extends DynoTableError {
43
+ constructor(message, code, context = {}, cause) {
44
+ super(message, code, context, cause);
45
+ this.name = "TransactionError";
46
+ }
47
+ };
48
+ var BatchError = class extends DynoTableError {
49
+ /**
50
+ * The type of batch operation that failed
51
+ */
52
+ operation;
53
+ /**
54
+ * The items that were not processed during the batch operation
55
+ */
56
+ unprocessedItems;
57
+ constructor(message, code, operation, unprocessedItems = [], context = {}, cause) {
58
+ super(message, code, context, cause);
59
+ this.name = "BatchError";
60
+ this.operation = operation;
61
+ this.unprocessedItems = unprocessedItems;
62
+ }
63
+ };
64
+ var ExpressionError = class extends DynoTableError {
65
+ constructor(message, code, context = {}, cause) {
66
+ super(message, code, context, cause);
67
+ this.name = "ExpressionError";
68
+ }
69
+ };
70
+ var ConfigurationError = class extends DynoTableError {
71
+ constructor(message, code, context = {}, cause) {
72
+ super(message, code, context, cause);
73
+ this.name = "ConfigurationError";
74
+ }
75
+ };
76
+ var EntityError = class extends DynoTableError {
77
+ constructor(message, code, context = {}, cause) {
78
+ super(message, code, context, cause);
79
+ this.name = "EntityError";
80
+ }
81
+ };
82
+ var KeyGenerationError = class extends EntityError {
83
+ constructor(message, code, context = {}, cause) {
84
+ super(message, code, context, cause);
85
+ this.name = "KeyGenerationError";
86
+ }
87
+ };
88
+ var IndexGenerationError = class extends EntityError {
89
+ constructor(message, code, context = {}, cause) {
90
+ super(message, code, context, cause);
91
+ this.name = "IndexGenerationError";
92
+ }
93
+ };
94
+ var EntityValidationError = class extends ValidationError {
95
+ constructor(message, code, context = {}, cause) {
96
+ super(message, code, context, cause);
97
+ this.name = "EntityValidationError";
98
+ }
99
+ };
100
+ var ErrorCodes = {
101
+ // Key Generation Errors
102
+ KEY_GENERATION_FAILED: "KEY_GENERATION_FAILED",
103
+ KEY_MISSING_ATTRIBUTES: "KEY_MISSING_ATTRIBUTES",
104
+ KEY_INVALID_FORMAT: "KEY_INVALID_FORMAT",
105
+ // Index Errors
106
+ INDEX_GENERATION_FAILED: "INDEX_GENERATION_FAILED",
107
+ INDEX_MISSING_ATTRIBUTES: "INDEX_MISSING_ATTRIBUTES",
108
+ INDEX_NOT_FOUND: "INDEX_NOT_FOUND",
109
+ INDEX_READONLY_UPDATE_FAILED: "INDEX_READONLY_UPDATE_FAILED",
110
+ INDEX_UNDEFINED_VALUES: "INDEX_UNDEFINED_VALUES",
111
+ // Validation Errors
112
+ ENTITY_VALIDATION_FAILED: "ENTITY_VALIDATION_FAILED",
113
+ ASYNC_VALIDATION_NOT_SUPPORTED: "ASYNC_VALIDATION_NOT_SUPPORTED",
114
+ QUERY_INPUT_VALIDATION_FAILED: "QUERY_INPUT_VALIDATION_FAILED",
115
+ VALIDATION_ERROR: "VALIDATION_ERROR",
116
+ VALIDATION_FAILED: "VALIDATION_FAILED",
117
+ SCHEMA_VALIDATION_FAILED: "SCHEMA_VALIDATION_FAILED",
118
+ INVALID_PARAMETER: "INVALID_PARAMETER",
119
+ MISSING_REQUIRED_FIELD: "MISSING_REQUIRED_FIELD",
120
+ UNDEFINED_VALUE: "UNDEFINED_VALUE",
121
+ // Expression Errors
122
+ EXPRESSION_MISSING_ATTRIBUTE: "EXPRESSION_MISSING_ATTRIBUTE",
123
+ EXPRESSION_MISSING_VALUE: "EXPRESSION_MISSING_VALUE",
124
+ EXPRESSION_INVALID_CONDITION: "EXPRESSION_INVALID_CONDITION",
125
+ EXPRESSION_EMPTY_ARRAY: "EXPRESSION_EMPTY_ARRAY",
126
+ EXPRESSION_UNKNOWN_TYPE: "EXPRESSION_UNKNOWN_TYPE",
127
+ EXPRESSION_INVALID: "EXPRESSION_INVALID",
128
+ EXPRESSION_INVALID_OPERATOR: "EXPRESSION_INVALID_OPERATOR",
129
+ // Operation Errors
130
+ QUERY_FAILED: "QUERY_FAILED",
131
+ SCAN_FAILED: "SCAN_FAILED",
132
+ GET_FAILED: "GET_FAILED",
133
+ PUT_FAILED: "PUT_FAILED",
134
+ DELETE_FAILED: "DELETE_FAILED",
135
+ UPDATE_FAILED: "UPDATE_FAILED",
136
+ BATCH_GET_FAILED: "BATCH_GET_FAILED",
137
+ BATCH_WRITE_FAILED: "BATCH_WRITE_FAILED",
138
+ NO_UPDATE_ACTIONS: "NO_UPDATE_ACTIONS",
139
+ CONDITIONAL_CHECK_FAILED: "CONDITIONAL_CHECK_FAILED",
140
+ // Transaction Errors
141
+ TRANSACTION_FAILED: "TRANSACTION_FAILED",
142
+ TRANSACTION_DUPLICATE_ITEM: "TRANSACTION_DUPLICATE_ITEM",
143
+ TRANSACTION_EMPTY: "TRANSACTION_EMPTY",
144
+ TRANSACTION_UNSUPPORTED_TYPE: "TRANSACTION_UNSUPPORTED_TYPE",
145
+ TRANSACTION_ITEM_LIMIT: "TRANSACTION_ITEM_LIMIT",
146
+ TRANSACTION_CANCELLED: "TRANSACTION_CANCELLED",
147
+ // Batch Errors
148
+ BATCH_EMPTY: "BATCH_EMPTY",
149
+ BATCH_UNSUPPORTED_TYPE: "BATCH_UNSUPPORTED_TYPE",
150
+ BATCH_UNPROCESSED_ITEMS: "BATCH_UNPROCESSED_ITEMS",
151
+ BATCH_SIZE_EXCEEDED: "BATCH_SIZE_EXCEEDED",
152
+ // Configuration Errors
153
+ GSI_NOT_FOUND: "GSI_NOT_FOUND",
154
+ SORT_KEY_REQUIRED: "SORT_KEY_REQUIRED",
155
+ SORT_KEY_NOT_DEFINED: "SORT_KEY_NOT_DEFINED",
156
+ PRIMARY_KEY_MISSING: "PRIMARY_KEY_MISSING",
157
+ INVALID_CHUNK_SIZE: "INVALID_CHUNK_SIZE",
158
+ CONDITION_REQUIRED: "CONDITION_REQUIRED",
159
+ CONDITION_GENERATION_FAILED: "CONDITION_GENERATION_FAILED",
160
+ PK_EXTRACTION_FAILED: "PK_EXTRACTION_FAILED",
161
+ CONFIGURATION_INVALID: "CONFIGURATION_INVALID",
162
+ CONFIGURATION_MISSING_SORT_KEY: "CONFIGURATION_MISSING_SORT_KEY",
163
+ CONFIGURATION_INVALID_GSI: "CONFIGURATION_INVALID_GSI"
164
+ };
165
+
166
+ // src/utils/error-factory.ts
167
+ var ExpressionErrors = {
168
+ missingAttribute: (conditionType, condition) => new ExpressionError(
169
+ `Attribute is required for ${conditionType} condition`,
170
+ ErrorCodes.EXPRESSION_MISSING_ATTRIBUTE,
171
+ {
172
+ conditionType,
173
+ condition,
174
+ suggestion: "Ensure the condition includes an attribute name"
175
+ }
176
+ ),
177
+ missingValue: (conditionType, condition) => new ExpressionError(`Value is required for ${conditionType} condition`, ErrorCodes.EXPRESSION_MISSING_VALUE, {
178
+ conditionType,
179
+ condition,
180
+ suggestion: "Provide a value for the condition"
181
+ }),
182
+ invalidCondition: (conditionType, condition, suggestion) => new ExpressionError(`Invalid condition for ${conditionType}`, ErrorCodes.EXPRESSION_INVALID_CONDITION, {
183
+ conditionType,
184
+ condition,
185
+ suggestion: suggestion || "Check that the condition is properly formed"
186
+ }),
187
+ emptyArray: (conditionType, providedValue) => new ExpressionError(
188
+ `${conditionType} condition requires a non-empty array of values`,
189
+ ErrorCodes.EXPRESSION_EMPTY_ARRAY,
190
+ {
191
+ conditionType,
192
+ providedValue,
193
+ suggestion: "Provide at least one value in the array"
194
+ }
195
+ ),
196
+ unknownType: (conditionType, condition) => new ExpressionError(`Unknown condition type: ${conditionType}`, ErrorCodes.EXPRESSION_UNKNOWN_TYPE, {
197
+ conditionType,
198
+ condition,
199
+ suggestion: "Use a supported condition type from the query builder"
200
+ })
201
+ };
202
+ var ValidationErrors = {
203
+ indexSchemaValidationFailed: (validationIssues, keyType) => {
204
+ const keyLabel = keyType === "partition" ? "partition key" : keyType === "sort" ? "sort key" : "partition/sort key";
205
+ return new ValidationError(
206
+ `Index validation failed while generating ${keyLabel}: missing required attribute(s) or invalid values.`,
207
+ ErrorCodes.SCHEMA_VALIDATION_FAILED,
208
+ {
209
+ keyType,
210
+ validationIssues,
211
+ suggestion: `Provide the required attributes to construct the index ${keyLabel}`
212
+ }
213
+ );
214
+ },
215
+ noUpdateActions: (tableName, key) => new ValidationError("No update actions specified", ErrorCodes.NO_UPDATE_ACTIONS, {
216
+ tableName,
217
+ key,
218
+ suggestion: "Use set(), remove(), add(), or delete() to specify update actions"
219
+ }),
220
+ conditionRequired: (tableName, key) => new ValidationError("Condition is required for condition check operations", ErrorCodes.CONDITION_REQUIRED, {
221
+ tableName,
222
+ key,
223
+ suggestion: "Use the condition() method to specify a condition"
224
+ }),
225
+ queryInputValidationFailed: (entityName, queryName, validationIssues, providedInput) => new ValidationError(
226
+ `Query input validation failed for "${queryName}" on entity "${entityName}"`,
227
+ ErrorCodes.QUERY_INPUT_VALIDATION_FAILED,
228
+ {
229
+ entityName,
230
+ queryName,
231
+ validationIssues,
232
+ providedInput,
233
+ suggestion: "Ensure the query input matches the expected schema"
234
+ }
235
+ ),
236
+ undefinedValue: (path, tableName, key) => new ValidationError(`Cannot set undefined value for attribute "${path}"`, ErrorCodes.UNDEFINED_VALUE, {
237
+ path,
238
+ tableName,
239
+ key,
240
+ suggestion: "DynamoDB does not support undefined values. Use remove() to delete an attribute, or provide a valid value (null, string, number, etc.)"
241
+ })
242
+ };
243
+ var ConfigurationErrors = {
244
+ invalidChunkSize: (size) => new ConfigurationError("Chunk size must be greater than 0", ErrorCodes.INVALID_CHUNK_SIZE, {
245
+ size,
246
+ suggestion: "Provide a chunk size greater than 0"
247
+ }),
248
+ sortKeyRequired: (tableName, partitionKey, sortKey) => new ConfigurationError("Sort key is required for this operation", ErrorCodes.SORT_KEY_REQUIRED, {
249
+ tableName,
250
+ partitionKey,
251
+ sortKey,
252
+ suggestion: "Provide a sort key value or use a table with only a partition key"
253
+ }),
254
+ sortKeyNotDefined: (tableName, partitionKey, indexName) => new ConfigurationError("Sort key is not defined for this table/index", ErrorCodes.SORT_KEY_NOT_DEFINED, {
255
+ tableName,
256
+ partitionKey,
257
+ indexName,
258
+ suggestion: "This operation requires a table/index with a sort key defined"
259
+ }),
260
+ gsiNotFound: (indexName, tableName, availableIndexes) => new ConfigurationError(`GSI "${indexName}" not found in table configuration`, ErrorCodes.GSI_NOT_FOUND, {
261
+ indexName,
262
+ tableName,
263
+ availableIndexes,
264
+ suggestion: `Use one of the available indexes: ${availableIndexes.join(", ")}`
265
+ }),
266
+ primaryKeyMissing: (tableName, partitionKeyName, providedItem) => new ConfigurationError(`Primary key value for '${partitionKeyName}' is missing`, ErrorCodes.PRIMARY_KEY_MISSING, {
267
+ tableName,
268
+ partitionKeyName,
269
+ providedItem,
270
+ suggestion: `Ensure the item includes a value for '${partitionKeyName}'`
271
+ }),
272
+ pkExtractionFailed: (tableName, indexName, item, cause) => new ConfigurationError(
273
+ `Failed to extract partition key from item for index "${indexName}"`,
274
+ ErrorCodes.PK_EXTRACTION_FAILED,
275
+ {
276
+ tableName,
277
+ indexName,
278
+ item,
279
+ suggestion: "Ensure the item has the required partition key attribute"
280
+ },
281
+ cause
282
+ ),
283
+ conditionGenerationFailed: (condition, suggestion) => new ExpressionError("Failed to generate condition expression", ErrorCodes.CONDITION_GENERATION_FAILED, {
284
+ condition,
285
+ suggestion: suggestion || "Check that the condition is properly formed"
286
+ })
287
+ };
288
+ var OperationErrors = {
289
+ queryFailed: (tableName, context, cause) => new OperationError(
290
+ `Query operation failed on table "${tableName}"`,
291
+ ErrorCodes.QUERY_FAILED,
292
+ {
293
+ tableName,
294
+ operation: "query",
295
+ ...context
296
+ },
297
+ cause
298
+ ),
299
+ scanFailed: (tableName, context, cause) => new OperationError(
300
+ `Scan operation failed on table "${tableName}"`,
301
+ ErrorCodes.SCAN_FAILED,
302
+ {
303
+ tableName,
304
+ operation: "scan",
305
+ ...context
306
+ },
307
+ cause
308
+ ),
309
+ getFailed: (tableName, key, cause) => new OperationError(
310
+ `Get operation failed on table "${tableName}"`,
311
+ ErrorCodes.GET_FAILED,
312
+ {
313
+ tableName,
314
+ operation: "get",
315
+ key
316
+ },
317
+ cause
318
+ ),
319
+ putFailed: (tableName, item, cause) => new OperationError(
320
+ `Put operation failed on table "${tableName}"`,
321
+ ErrorCodes.PUT_FAILED,
322
+ {
323
+ tableName,
324
+ operation: "put",
325
+ item
326
+ },
327
+ cause
328
+ ),
329
+ updateFailed: (tableName, key, cause) => new OperationError(
330
+ `Update operation failed on table "${tableName}"`,
331
+ ErrorCodes.UPDATE_FAILED,
332
+ {
333
+ tableName,
334
+ operation: "update",
335
+ key
336
+ },
337
+ cause
338
+ ),
339
+ deleteFailed: (tableName, key, cause) => new OperationError(
340
+ `Delete operation failed on table "${tableName}"`,
341
+ ErrorCodes.DELETE_FAILED,
342
+ {
343
+ tableName,
344
+ operation: "delete",
345
+ key
346
+ },
347
+ cause
348
+ ),
349
+ batchGetFailed: (tableName, context, cause) => new OperationError(
350
+ `Batch get operation failed on table "${tableName}"`,
351
+ ErrorCodes.BATCH_GET_FAILED,
352
+ {
353
+ tableName,
354
+ operation: "batchGet",
355
+ ...context
356
+ },
357
+ cause
358
+ ),
359
+ batchWriteFailed: (tableName, context, cause) => new OperationError(
360
+ `Batch write operation failed on table "${tableName}"`,
361
+ ErrorCodes.BATCH_WRITE_FAILED,
362
+ {
363
+ tableName,
364
+ operation: "batchWrite",
365
+ ...context
366
+ },
367
+ cause
368
+ )
369
+ };
370
+ var TransactionErrors = {
371
+ transactionFailed: (itemCount, context, cause) => new TransactionError(
372
+ `Transaction failed with ${itemCount} item(s)`,
373
+ ErrorCodes.TRANSACTION_FAILED,
374
+ {
375
+ itemCount,
376
+ ...context
377
+ },
378
+ cause
379
+ ),
380
+ duplicateItem: (tableName, partitionKey, sortKey) => new TransactionError("Duplicate item detected in transaction", ErrorCodes.TRANSACTION_DUPLICATE_ITEM, {
381
+ tableName,
382
+ partitionKey,
383
+ sortKey,
384
+ suggestion: "Each item in a transaction must be unique. Check for duplicate keys in your transaction items."
385
+ }),
386
+ transactionEmpty: () => new TransactionError("No transaction items specified", ErrorCodes.TRANSACTION_EMPTY, {
387
+ suggestion: "Add at least one operation using put(), delete(), update(), or conditionCheck()"
388
+ }),
389
+ unsupportedType: (item) => new TransactionError("Unsupported transaction item type", ErrorCodes.TRANSACTION_UNSUPPORTED_TYPE, {
390
+ item,
391
+ suggestion: "Transaction items must be created using put(), delete(), update(), or conditionCheck()"
392
+ })
393
+ };
394
+ var BatchErrors = {
395
+ batchEmpty: (operation) => new BatchError(`No items specified for batch ${operation} operation`, ErrorCodes.BATCH_EMPTY, operation, [], {
396
+ suggestion: operation === "write" ? "Use put() or delete() to add items to the batch" : "Use get() to add keys to the batch"
397
+ }),
398
+ unsupportedType: (operation, item) => new BatchError(`Unsupported batch ${operation} item type`, ErrorCodes.BATCH_UNSUPPORTED_TYPE, operation, [], {
399
+ item,
400
+ suggestion: operation === "write" ? "Batch items must be put or delete operations" : "Batch items must be get operations"
401
+ }),
402
+ batchWriteFailed: (unprocessedItems, context, cause) => new BatchError(
403
+ `Batch write failed with ${unprocessedItems.length} unprocessed item(s)`,
404
+ ErrorCodes.BATCH_WRITE_FAILED,
405
+ "write",
406
+ unprocessedItems,
407
+ context,
408
+ cause
409
+ ),
410
+ batchGetFailed: (unprocessedItems, context, cause) => new BatchError(
411
+ `Batch get failed with ${unprocessedItems.length} unprocessed item(s)`,
412
+ ErrorCodes.BATCH_GET_FAILED,
413
+ "read",
414
+ unprocessedItems,
415
+ context,
416
+ cause
417
+ )
418
+ };
419
+ var EntityErrors = {
420
+ validationFailed: (entityName, operation, validationIssues, providedData) => new EntityValidationError(
421
+ `Validation failed for entity "${entityName}" during ${operation} operation`,
422
+ ErrorCodes.ENTITY_VALIDATION_FAILED,
423
+ {
424
+ entityName,
425
+ operation,
426
+ validationIssues,
427
+ providedData,
428
+ suggestion: "Check that all required fields are provided and match the schema"
429
+ }
430
+ ),
431
+ queryInputValidationFailed: (entityName, queryName, validationIssues, providedInput) => new EntityValidationError(
432
+ `Query input validation failed for "${queryName}" on entity "${entityName}"`,
433
+ ErrorCodes.QUERY_INPUT_VALIDATION_FAILED,
434
+ {
435
+ entityName,
436
+ queryName,
437
+ validationIssues,
438
+ providedInput,
439
+ suggestion: "Ensure the query input matches the expected schema"
440
+ }
441
+ ),
442
+ asyncValidationNotSupported: (entityName, operation) => new EntityValidationError(
443
+ `Entity "${entityName}" uses async validation which is not supported in transactions/batches`,
444
+ ErrorCodes.ASYNC_VALIDATION_NOT_SUPPORTED,
445
+ {
446
+ entityName,
447
+ operation,
448
+ suggestion: "Use .execute() for async validation or switch to synchronous schema validation"
449
+ }
450
+ ),
451
+ keyGenerationFailed: (entityName, operation, providedData, requiredAttributes, cause) => new KeyGenerationError(
452
+ `Failed to generate primary key for entity "${entityName}"`,
453
+ ErrorCodes.KEY_GENERATION_FAILED,
454
+ {
455
+ entityName,
456
+ operation,
457
+ providedData,
458
+ requiredAttributes,
459
+ suggestion: requiredAttributes ? `Ensure these attributes are provided: ${requiredAttributes.join(", ")}` : "Check that all required attributes for key generation are provided"
460
+ },
461
+ cause
462
+ ),
463
+ keyInvalidFormat: (entityName, operation, providedData, generatedKey) => new KeyGenerationError(
464
+ `Primary key generation for entity "${entityName}" produced undefined/null partition key`,
465
+ ErrorCodes.KEY_INVALID_FORMAT,
466
+ {
467
+ entityName,
468
+ operation,
469
+ providedData,
470
+ generatedKey,
471
+ suggestion: "Ensure the key generation function returns valid pk (and sk if applicable) values"
472
+ }
473
+ ),
474
+ keyMissingAttributes: (entityName, operation, missingAttributes, providedData) => new KeyGenerationError(
475
+ `Missing required attributes for key generation in entity "${entityName}": ${missingAttributes.join(", ")}`,
476
+ ErrorCodes.KEY_MISSING_ATTRIBUTES,
477
+ {
478
+ entityName,
479
+ operation,
480
+ missingAttributes,
481
+ providedData,
482
+ suggestion: `Provide the following attributes: ${missingAttributes.join(", ")}`
483
+ }
484
+ )
485
+ };
486
+ var IndexErrors = {
487
+ generationFailed: (indexName, operation, providedItem, partitionKeyAttribute, sortKeyAttribute, cause) => new IndexGenerationError(
488
+ `Failed to generate key for index "${indexName}"`,
489
+ ErrorCodes.INDEX_GENERATION_FAILED,
490
+ {
491
+ indexName,
492
+ operation,
493
+ providedItem,
494
+ partitionKeyAttribute,
495
+ sortKeyAttribute,
496
+ suggestion: "Ensure all attributes required by the index are present in the item"
497
+ },
498
+ cause
499
+ ),
500
+ missingAttributes: (indexName, operation, missingAttributes, providedData, isReadOnly) => new IndexGenerationError(
501
+ `Cannot regenerate readonly index "${indexName}" - missing required attributes: ${missingAttributes.join(", ")}`,
502
+ ErrorCodes.INDEX_MISSING_ATTRIBUTES,
503
+ {
504
+ indexName,
505
+ operation,
506
+ missingAttributes,
507
+ providedData,
508
+ isReadOnly,
509
+ suggestion: isReadOnly ? "For readonly indexes, provide all attributes or use forceIndexRebuild() with complete data" : `Provide the following attributes: ${missingAttributes.join(", ")}`
510
+ }
511
+ ),
512
+ undefinedValues: (indexName, operation, generatedKey, providedItem) => new IndexGenerationError(`Index "${indexName}" generated undefined values`, ErrorCodes.INDEX_UNDEFINED_VALUES, {
513
+ indexName,
514
+ operation,
515
+ generatedKey,
516
+ providedItem,
517
+ suggestion: "Ensure all attributes required by the index are present in the item"
518
+ }),
519
+ notFound: (requestedIndexes, availableIndexes, entityName, tableName) => new IndexGenerationError(
520
+ `Requested indexes not found: ${requestedIndexes.join(", ")}`,
521
+ ErrorCodes.INDEX_NOT_FOUND,
522
+ {
523
+ requestedIndexes,
524
+ availableIndexes,
525
+ entityName,
526
+ tableName,
527
+ suggestion: `Available indexes are: ${availableIndexes.join(", ")}`
528
+ }
529
+ ),
530
+ readonlyUpdateFailed: (indexName, operation, providedData) => new IndexGenerationError(
531
+ `Cannot update readonly index "${indexName}" without forcing rebuild`,
532
+ ErrorCodes.INDEX_READONLY_UPDATE_FAILED,
533
+ {
534
+ indexName,
535
+ operation,
536
+ providedData,
537
+ isReadOnly: true,
538
+ suggestion: "Use forceIndexRebuild() to update readonly indexes, or provide all required attributes"
539
+ }
540
+ )
541
+ };
542
+
543
+ export { BatchError, BatchErrors, ConfigurationError, ConfigurationErrors, DynoTableError, EntityError, EntityErrors, EntityValidationError, ErrorCodes, ExpressionError, ExpressionErrors, IndexErrors, IndexGenerationError, KeyGenerationError, OperationError, OperationErrors, TransactionError, TransactionErrors, ValidationError, ValidationErrors };